diff --git a/NXDNControl.cpp b/NXDNControl.cpp index d4e6f0a..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 { @@ -275,37 +273,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 +369,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); } } @@ -673,6 +746,7 @@ void CNXDNControl::writeEndRF() m_rfState = RS_RF_LISTENING; m_rfMask = 0x00U; + m_rfLayer3.reset(); m_rfTimeoutTimer.stop(); 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..cf32008 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); } } @@ -102,6 +101,16 @@ bool CNXDNLayer3::getHasInfo() const type != NXDN_MESSAGE_TYPE_SDCALL_IV; } +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 bd4ba6a..827deee 100644 --- a/NXDNLayer3.h +++ b/NXDNLayer3.h @@ -36,6 +36,10 @@ public: unsigned char getCallOptions() const; bool getHasInfo() const; + void getData(unsigned char* data) const; + + void reset(); + CNXDNLayer3& operator=(const CNXDNLayer3& layer3); private: 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