From 8ff50ce2d31c4e6fa4286a3a4c93757910ed384d Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Fri, 2 Feb 2018 06:34:21 +0000 Subject: [PATCH 1/3] Get half of the late entry working. --- NXDNFACCH1.cpp | 1 - NXDNLayer3.cpp | 5 ++--- NXDNSACCH.cpp | 1 - NXDNUDCH.cpp | 1 - 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/NXDNFACCH1.cpp b/NXDNFACCH1.cpp index ca2a9fc..54aceaa 100644 --- a/NXDNFACCH1.cpp +++ b/NXDNFACCH1.cpp @@ -22,7 +22,6 @@ #include "NXDNDefines.h" #include "NXDNCRC.h" #include "Utils.h" -#include "Log.h" #include #include diff --git a/NXDNLayer3.cpp b/NXDNLayer3.cpp index dce3d17..b8a60e8 100644 --- a/NXDNLayer3.cpp +++ b/NXDNLayer3.cpp @@ -18,7 +18,6 @@ #include "NXDNDefines.h" #include "NXDNLayer3.h" -#include "Log.h" #include #include @@ -53,8 +52,8 @@ void CNXDNLayer3::decode(const unsigned char* bytes, unsigned int length, unsign assert(bytes != NULL); for (unsigned int i = 0U; i < length; i++, offset++) { - bool b = READ_BIT1(bytes, offset); - WRITE_BIT1(m_data, i, b); + bool b = READ_BIT1(bytes, i); + WRITE_BIT1(m_data, offset, b); } } diff --git a/NXDNSACCH.cpp b/NXDNSACCH.cpp index b060fa4..1e490c2 100755 --- a/NXDNSACCH.cpp +++ b/NXDNSACCH.cpp @@ -22,7 +22,6 @@ #include "NXDNDefines.h" #include "NXDNCRC.h" #include "Utils.h" -#include "Log.h" #include #include diff --git a/NXDNUDCH.cpp b/NXDNUDCH.cpp index c4ead27..a0d8dbf 100644 --- a/NXDNUDCH.cpp +++ b/NXDNUDCH.cpp @@ -22,7 +22,6 @@ #include "NXDNDefines.h" #include "NXDNCRC.h" #include "Utils.h" -#include "Log.h" #include #include From 6d0e95fb9baf8b6e9455dd53b99610937dc35deb Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Fri, 2 Feb 2018 07:03:10 +0000 Subject: [PATCH 2/3] Add late entry using FACCH1 and create a dummy start message. --- NXDNControl.cpp | 121 +++++++++++++++++++++++++++++++++++++++--------- NXDNLayer3.cpp | 5 ++ NXDNLayer3.h | 2 + 3 files changed, 105 insertions(+), 23 deletions(-) diff --git a/NXDNControl.cpp b/NXDNControl.cpp index d4e6f0a..12b28d4 100644 --- a/NXDNControl.cpp +++ b/NXDNControl.cpp @@ -275,37 +275,72 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne return true; } else { if (m_rfState == RS_RF_LISTENING) { - unsigned char message[3U]; - sacch.getData(message); - - unsigned char structure = sacch.getStructure(); - switch (structure) { - case NXDN_SR_1_4: - m_rfMask |= 0x01U; - m_rfLayer3.decode(message, 18U, 0U); + CNXDNFACCH1 facch; + bool valid = false; + switch (option) { + case NXDN_LICH_STEAL_FACCH: + valid = facch.decode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS); + if (!valid) + valid = facch.decode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS); break; - case NXDN_SR_2_4: - m_rfMask |= 0x02U; - m_rfLayer3.decode(message, 18U, 18U); + case NXDN_LICH_STEAL_FACCH1_1: + valid = facch.decode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS); break; - case NXDN_SR_3_4: - m_rfMask |= 0x04U; - m_rfLayer3.decode(message, 18U, 36U); - break; - case NXDN_SR_4_4: - m_rfMask |= 0x08U; - m_rfLayer3.decode(message, 18U, 54U); + case NXDN_LICH_STEAL_FACCH1_2: + valid = facch.decode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS); break; default: break; } - if (m_rfMask != 0x0FU) - return false; + bool hasInfo = false; + if (valid) { + unsigned char buffer[10U]; + facch.getData(buffer); - bool hasInfo = m_rfLayer3.getHasInfo(); - if (!hasInfo) - return false; + CNXDNLayer3 layer3; + layer3.decode(buffer, NXDN_FACCH1_LENGTH_BITS); + + hasInfo = layer3.getHasInfo(); + if (!hasInfo) + return false; + + m_rfLayer3 = layer3; + } + + if (!hasInfo) { + unsigned char message[3U]; + sacch.getData(message); + + unsigned char structure = sacch.getStructure(); + switch (structure) { + case NXDN_SR_1_4: + m_rfMask |= 0x01U; + m_rfLayer3.decode(message, 18U, 0U); + break; + case NXDN_SR_2_4: + m_rfMask |= 0x02U; + m_rfLayer3.decode(message, 18U, 18U); + break; + case NXDN_SR_3_4: + m_rfMask |= 0x04U; + m_rfLayer3.decode(message, 18U, 36U); + break; + case NXDN_SR_4_4: + m_rfMask |= 0x08U; + m_rfLayer3.decode(message, 18U, 54U); + break; + default: + break; + } + + if (m_rfMask != 0x0FU) + return false; + + hasInfo = m_rfLayer3.getHasInfo(); + if (!hasInfo) + return false; + } unsigned short srcId = m_rfLayer3.getSourceUnitId(); unsigned short dstId = m_rfLayer3.getDestinationGroupId(); @@ -336,6 +371,46 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne m_display->writeNXDN(source.c_str(), grp, dstId, "R"); m_rfState = RS_RF_AUDIO; + + // Create a dummy start message + unsigned char start[NXDN_FRAME_LENGTH_BYTES + 2U]; + + start[0U] = TAG_DATA; + start[1U] = 0x00U; + + // Generate the sync + CSync::addNXDNSync(start + 2U); + + // Generate the LICH + CNXDNLICH lich; + lich.setRFCT(NXDN_LICH_RFCT_RDCH); + lich.setFCT(NXDN_LICH_USC_SACCH_NS); + lich.setOption(NXDN_LICH_STEAL_FACCH); + lich.setDirection(m_remoteGateway ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND); + lich.encode(start + 2U); + + CNXDNSACCH sacch; + sacch.setRAN(m_ran); + sacch.setStructure(NXDN_SR_SINGLE); + sacch.setData(SACCH_IDLE); + sacch.encode(start + 2U); + + unsigned char message[22U]; + m_rfLayer3.getData(message); + + facch.setData(message); + facch.encode(start + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS); + facch.encode(start + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS); + + scrambler(start + 2U); + + // writeNetwork(start, m_rfFrames, ); + +#if defined(DUMP_NXDN) + writeFile(start + 2U); +#endif + if (m_duplex) + writeQueueRF(start); } } diff --git a/NXDNLayer3.cpp b/NXDNLayer3.cpp index b8a60e8..3fc6e33 100644 --- a/NXDNLayer3.cpp +++ b/NXDNLayer3.cpp @@ -101,6 +101,11 @@ bool CNXDNLayer3::getHasInfo() const type != NXDN_MESSAGE_TYPE_SDCALL_IV; } +void CNXDNLayer3::getData(unsigned char* data) const +{ + ::memcpy(data, m_data, 22U); +} + CNXDNLayer3& CNXDNLayer3::operator=(const CNXDNLayer3& layer3) { if (&layer3 != this) diff --git a/NXDNLayer3.h b/NXDNLayer3.h index bd4ba6a..cb2f499 100644 --- a/NXDNLayer3.h +++ b/NXDNLayer3.h @@ -36,6 +36,8 @@ public: unsigned char getCallOptions() const; bool getHasInfo() const; + void getData(unsigned char* data) const; + CNXDNLayer3& operator=(const CNXDNLayer3& layer3); private: From 0f685095e55c3ce4330fdf3731d31cdb483727e9 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Fri, 2 Feb 2018 07:34:59 +0000 Subject: [PATCH 3/3] Reset the layer3 data accumulator at end of transmissions. --- NXDNControl.cpp | 7 +++---- NXDNLayer3.cpp | 5 +++++ NXDNLayer3.h | 2 ++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/NXDNControl.cpp b/NXDNControl.cpp index 12b28d4..0ab043c 100644 --- a/NXDNControl.cpp +++ b/NXDNControl.cpp @@ -106,6 +106,7 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len) if (type == TAG_LOST) { m_rfState = RS_RF_LISTENING; m_rfMask = 0x00U; + m_rfLayer3.reset(); return false; } @@ -131,12 +132,8 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len) m_rssiCount++; } - // CUtils::dump(2U, "NXDN, raw data", data + 2U, NXDN_FRAME_LENGTH_BYTES); - scrambler(data + 2U); - // CUtils::dump(2U, "NXDN, after descrambling", data + 2U, NXDN_FRAME_LENGTH_BYTES); - CNXDNLICH lich; bool valid = lich.decode(data + 2U); @@ -200,6 +197,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne if (m_rfState != RS_RF_AUDIO) { m_rfState = RS_RF_LISTENING; m_rfMask = 0x00U; + m_rfLayer3.reset(); return false; } } else { @@ -748,6 +746,7 @@ void CNXDNControl::writeEndRF() m_rfState = RS_RF_LISTENING; m_rfMask = 0x00U; + m_rfLayer3.reset(); m_rfTimeoutTimer.stop(); diff --git a/NXDNLayer3.cpp b/NXDNLayer3.cpp index 3fc6e33..cf32008 100644 --- a/NXDNLayer3.cpp +++ b/NXDNLayer3.cpp @@ -106,6 +106,11 @@ void CNXDNLayer3::getData(unsigned char* data) const ::memcpy(data, m_data, 22U); } +void CNXDNLayer3::reset() +{ + ::memset(m_data, 0x00U, 22U); +} + CNXDNLayer3& CNXDNLayer3::operator=(const CNXDNLayer3& layer3) { if (&layer3 != this) diff --git a/NXDNLayer3.h b/NXDNLayer3.h index cb2f499..827deee 100644 --- a/NXDNLayer3.h +++ b/NXDNLayer3.h @@ -38,6 +38,8 @@ public: void getData(unsigned char* data) const; + void reset(); + CNXDNLayer3& operator=(const CNXDNLayer3& layer3); private: