From 2f3804240963ddf9a6452a36a61b22807cce6ae6 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 1 Feb 2018 06:35:16 +0000 Subject: [PATCH 1/9] Simplify the non superblock processing. --- NXDNControl.cpp | 34 ++++++++++++---------------------- 1 file changed, 12 insertions(+), 22 deletions(-) diff --git a/NXDNControl.cpp b/NXDNControl.cpp index 74b2991..fb02259 100644 --- a/NXDNControl.cpp +++ b/NXDNControl.cpp @@ -91,7 +91,7 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len) if (type == TAG_LOST && m_rfState == RS_RF_AUDIO) { if (m_rssi != 0U) - LogMessage("NXDN, transmission lost, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount); + LogMessage("NXDN, transmission lost, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount); else LogMessage("NXDN, transmission lost, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits)); writeEndRF(); @@ -180,19 +180,15 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne if (usc == NXDN_LICH_USC_SACCH_NS) { // The SACCH on a non-superblock frame is usually an idle and not interesting apart from the RAN. - CNXDNFACCH1 facch11; - bool valid1 = facch11.decode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS); + CNXDNFACCH1 facch; + bool 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); - CNXDNFACCH1 facch12; - bool valid2 = facch12.decode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS); + if (valid) { + unsigned char buffer[10U]; + facch.getData(buffer); - unsigned char buffer[10U]; - if (valid1) - facch11.getData(buffer); - else if (valid2) - facch12.getData(buffer); - - if (valid1 || valid2) { CNXDNLayer3 layer3; layer3.decode(buffer, NXDN_FACCH1_LENGTH_BITS); @@ -228,13 +224,8 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne sacch.setData(SACCH_IDLE); sacch.encode(data + 2U); - if (valid1) { - facch11.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS); - facch11.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS); - } else { - facch12.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS); - facch12.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS); - } + facch.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS); + facch.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS); scrambler(data + 2U); @@ -243,7 +234,6 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne #if defined(DUMP_NXDN) writeFile(data + 2U); #endif - if (m_duplex) writeQueueRF(data); @@ -312,8 +302,8 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne break; } - if (m_rfMask != 0x0FU) - return false; + // if (m_rfMask != 0x0FU) + // return false; unsigned char messageType = m_rfLayer3.getMessageType(); if (messageType != NXDN_MESSAGE_TYPE_VCALL) From 43fdb770a9e7818ff3d22bfd40c7305a7d41e267 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 1 Feb 2018 06:59:11 +0000 Subject: [PATCH 2/9] Make the jitter buffer switchable. --- Conf.cpp | 8 ++++++++ Conf.h | 2 ++ DMRNetwork.cpp | 33 +++++++++++++++++---------------- DMRNetwork.h | 3 ++- MMDVM.ini | 1 + MMDVMHost.cpp | 4 +++- 6 files changed, 33 insertions(+), 18 deletions(-) diff --git a/Conf.cpp b/Conf.cpp index 5afec64..f4288ed 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -153,6 +153,7 @@ m_dmrNetworkLocal(0U), m_dmrNetworkPassword(), m_dmrNetworkOptions(), m_dmrNetworkDebug(false), +m_dmrNetworkJitterEnabled(true), m_dmrNetworkJitter(300U), m_dmrNetworkSlot1(true), m_dmrNetworkSlot2(true), @@ -550,6 +551,8 @@ bool CConf::read() m_dmrNetworkOptions = value; else if (::strcmp(key, "Debug") == 0) m_dmrNetworkDebug = ::atoi(value) == 1; + else if (::strcmp(key, "JitterEnabled") == 0) + m_dmrNetworkJitterEnabled = ::atoi(value) == 1; else if (::strcmp(key, "Jitter") == 0) m_dmrNetworkJitter = (unsigned int)::atoi(value); else if (::strcmp(key, "Slot1") == 0) @@ -1161,6 +1164,11 @@ bool CConf::getDMRNetworkDebug() const return m_dmrNetworkDebug; } +bool CConf::getDMRNetworkJitterEnabled() const +{ + return m_dmrNetworkJitterEnabled; +} + unsigned int CConf::getDMRNetworkJitter() const { return m_dmrNetworkJitter; diff --git a/Conf.h b/Conf.h index 2f7304a..5ef5efa 100644 --- a/Conf.h +++ b/Conf.h @@ -154,6 +154,7 @@ public: std::string getDMRNetworkPassword() const; std::string getDMRNetworkOptions() const; bool getDMRNetworkDebug() const; + bool getDMRNetworkJitterEnabled() const; unsigned int getDMRNetworkJitter() const; bool getDMRNetworkSlot1() const; bool getDMRNetworkSlot2() const; @@ -327,6 +328,7 @@ private: std::string m_dmrNetworkPassword; std::string m_dmrNetworkOptions; bool m_dmrNetworkDebug; + bool m_dmrNetworkJitterEnabled; unsigned int m_dmrNetworkJitter; bool m_dmrNetworkSlot1; bool m_dmrNetworkSlot2; diff --git a/DMRNetwork.cpp b/DMRNetwork.cpp index 51843db..c9f251a 100644 --- a/DMRNetwork.cpp +++ b/DMRNetwork.cpp @@ -32,7 +32,7 @@ const unsigned int BUFFER_LENGTH = 500U; const unsigned int HOMEBREW_DATA_PACKET_LENGTH = 55U; -CDMRNetwork::CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, bool duplex, const char* version, bool debug, bool slot1, bool slot2, HW_TYPE hwType, unsigned int jitter) : +CDMRNetwork::CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, bool duplex, const char* version, bool debug, bool slot1, bool slot2, HW_TYPE hwType, bool jitterEnabled, unsigned int jitter) : m_address(), m_port(port), m_id(NULL), @@ -44,6 +44,7 @@ m_socket(local), m_enabled(false), m_slot1(slot1), m_slot2(slot2), +m_jitterEnabled(jitterEnabled), m_jitterBuffers(NULL), m_hwType(hwType), m_status(WAITING_CONNECT), @@ -498,23 +499,23 @@ void CDMRNetwork::receiveData(const unsigned char* data, unsigned int length) if (slotNo == 2U && !m_slot2) return; - m_jitterBuffers[slotNo]->appendData(data, length); - - /* - unsigned char dataType = data[15U] & 0x3FU; - if (dataType == (0x20U | DT_CSBK) || - dataType == (0x20U | DT_DATA_HEADER) || - dataType == (0x20U | DT_RATE_1_DATA) || - dataType == (0x20U | DT_RATE_34_DATA) || - dataType == (0x20U | DT_RATE_12_DATA)) { - // Data & CSBK frames - m_jitterBuffers[slotNo]->appendData(data, length); + if (m_jitterEnabled) { + unsigned char dataType = data[15U] & 0x3FU; + if (dataType == (0x20U | DT_CSBK) || + dataType == (0x20U | DT_DATA_HEADER) || + dataType == (0x20U | DT_RATE_1_DATA) || + dataType == (0x20U | DT_RATE_34_DATA) || + dataType == (0x20U | DT_RATE_12_DATA)) { + // Data & CSBK frames + m_jitterBuffers[slotNo]->appendData(data, length); + } else { + // Voice frames + unsigned char seqNo = data[4U]; + m_jitterBuffers[slotNo]->addData(data, length, seqNo); + } } else { - // Voice frames - unsigned char seqNo = data[4U]; - m_jitterBuffers[slotNo]->addData(data, length, seqNo); + m_jitterBuffers[slotNo]->appendData(data, length); } - */ } bool CDMRNetwork::writeLogin() diff --git a/DMRNetwork.h b/DMRNetwork.h index 53f579e..cfacb77 100644 --- a/DMRNetwork.h +++ b/DMRNetwork.h @@ -31,7 +31,7 @@ class CDMRNetwork { public: - CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, bool duplex, const char* version, bool debug, bool slot1, bool slot2, HW_TYPE hwType, unsigned int jitter); + CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, bool duplex, const char* version, bool debug, bool slot1, bool slot2, HW_TYPE hwType, bool jitterEnabled, unsigned int jitter); ~CDMRNetwork(); void setOptions(const std::string& options); @@ -70,6 +70,7 @@ private: bool m_enabled; bool m_slot1; bool m_slot2; + bool m_jitterEnabled; CJitterBuffer** m_jitterBuffers; HW_TYPE m_hwType; diff --git a/MMDVM.ini b/MMDVM.ini index ac034a0..e92e718 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -119,6 +119,7 @@ Debug=0 Enable=1 Address=44.131.4.1 Port=62031 +JitterEnabled=1 Jitter=500 # Local=62032 Password=PASSWORD diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 00c43e8..754c49f 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -944,6 +944,7 @@ bool CMMDVMHost::createDMRNetwork() unsigned int id = m_conf.getDMRId(); std::string password = m_conf.getDMRNetworkPassword(); bool debug = m_conf.getDMRNetworkDebug(); + bool jitterEnabled = m_conf.getDMRNetworkJitterEnabled(); unsigned int jitter = m_conf.getDMRNetworkJitter(); bool slot1 = m_conf.getDMRNetworkSlot1(); bool slot2 = m_conf.getDMRNetworkSlot2(); @@ -957,12 +958,13 @@ bool CMMDVMHost::createDMRNetwork() LogInfo(" Local: %u", local); else LogInfo(" Local: random"); + LogInfo(" Jitter Buffer: %s", jitterEnabled ? "enabled" : "disabled"); LogInfo(" Jitter: %ums", jitter); LogInfo(" Slot 1: %s", slot1 ? "enabled" : "disabled"); LogInfo(" Slot 2: %s", slot2 ? "enabled" : "disabled"); LogInfo(" Mode Hang: %us", m_dmrNetModeHang); - m_dmrNetwork = new CDMRNetwork(address, port, local, id, password, m_duplex, VERSION, debug, slot1, slot2, hwType, jitter); + m_dmrNetwork = new CDMRNetwork(address, port, local, id, password, m_duplex, VERSION, debug, slot1, slot2, hwType, jitterEnabled, jitter); std::string options = m_conf.getDMRNetworkOptions(); if (!options.empty()) { From 8e2c6f65837eaf19500dbb50133319f813a9820e Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 1 Feb 2018 18:32:23 +0000 Subject: [PATCH 3/9] Fix crash in the SACCH and FACCH1 encoders. --- NXDNControl.cpp | 286 ++++++++++++++++++++++++------------------------ NXDNFACCH1.cpp | 9 +- NXDNLayer3.cpp | 9 ++ NXDNLayer3.h | 1 + NXDNSACCH.cpp | 6 +- NXDNUDCH.cpp | 9 +- 6 files changed, 162 insertions(+), 158 deletions(-) diff --git a/NXDNControl.cpp b/NXDNControl.cpp index fb02259..7b009aa 100644 --- a/NXDNControl.cpp +++ b/NXDNControl.cpp @@ -93,7 +93,7 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len) if (m_rssi != 0U) LogMessage("NXDN, transmission lost, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount); else - LogMessage("NXDN, transmission lost, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits)); + LogMessage("NXDN, transmission lost, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits)); writeEndRF(); return false; } @@ -174,6 +174,8 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne unsigned char ran = sacch.getRAN(); if (ran != m_ran && ran != 0U) return false; + } else if (m_rfState == RS_RF_LISTENING) { + // return false; } // XXX Reconstruct invalid LICH @@ -184,161 +186,159 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne bool 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); - - if (valid) { - unsigned char buffer[10U]; - facch.getData(buffer); - - CNXDNLayer3 layer3; - layer3.decode(buffer, NXDN_FACCH1_LENGTH_BITS); - - unsigned char type = layer3.getMessageType(); - if (type == NXDN_MESSAGE_TYPE_TX_REL) { - if (m_rfState != RS_RF_AUDIO) { - m_rfState = RS_RF_LISTENING; - m_rfMask = 0x00U; - return false; - } - } else { - if (m_selfOnly) { - unsigned short srcId = layer3.getSourceUnitId(); - if (srcId != m_id) { - m_rfState = RS_RF_REJECTED; - return false; - } - } - } - - data[0U] = type == NXDN_MESSAGE_TYPE_TX_REL ? TAG_EOT : TAG_DATA; - data[1U] = 0x00U; - - CSync::addNXDNSync(data + 2U); - - CNXDNLICH lich = m_rfLastLICH; - lich.setDirection(m_remoteGateway ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND); - lich.encode(data + 2U); - - CNXDNSACCH sacch; - sacch.setRAN(m_ran); - sacch.setStructure(NXDN_SR_SINGLE); - sacch.setData(SACCH_IDLE); - sacch.encode(data + 2U); - - facch.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS); - facch.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS); - - scrambler(data + 2U); - - // writeNetwork(data, m_rfFrames, ); - -#if defined(DUMP_NXDN) - writeFile(data + 2U); -#endif - if (m_duplex) - writeQueueRF(data); - - if (type == NXDN_MESSAGE_TYPE_TX_REL) { - m_rfFrames++; - if (m_rssi != 0U) - LogMessage("NXDN, received RF end of transmission, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount); - else - LogMessage("NXDN, received RF end of transmission, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits)); - writeEndRF(); - return true; - } else { - m_rfFrames = 0U; - m_rfErrs = 0U; - m_rfBits = 1U; - m_rfTimeoutTimer.start(); - m_rfState = RS_RF_AUDIO; - - m_minRSSI = m_rssi; - m_maxRSSI = m_rssi; - m_aveRSSI = m_rssi; - m_rssiCount = 1U; -#if defined(DUMP_NXDN) - openFile(); -#endif - m_rfLayer3 = layer3; - - unsigned short srcId = m_rfLayer3.getSourceUnitId(); - unsigned short dstId = m_rfLayer3.getDestinationGroupId(); - bool grp = m_rfLayer3.getIsGroup(); - - std::string source = m_lookup->find(srcId); - LogMessage("NXDN, received RF voice transmission from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId); - m_display->writeNXDN(source.c_str(), grp, dstId, "R"); - - m_rfState = RS_RF_AUDIO; - - return true; - } - } - - return false; - } else { - 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) + // if (!valid) // return false; - unsigned char messageType = m_rfLayer3.getMessageType(); - if (messageType != NXDN_MESSAGE_TYPE_VCALL) - return false; + unsigned char buffer[10U]; + facch.getData(buffer); - unsigned short srcId = m_rfLayer3.getSourceUnitId(); - unsigned short dstId = m_rfLayer3.getDestinationGroupId(); - bool grp = m_rfLayer3.getIsGroup(); + CNXDNLayer3 layer3; + layer3.decode(buffer, NXDN_FACCH1_LENGTH_BITS); - if (m_selfOnly) { - if (srcId != m_id) { - m_rfState = RS_RF_REJECTED; + unsigned char type = layer3.getMessageType(); + if (type == NXDN_MESSAGE_TYPE_TX_REL) { + if (m_rfState != RS_RF_AUDIO) { + m_rfState = RS_RF_LISTENING; + m_rfMask = 0x00U; return false; } + } else { + bool hasInfo = layer3.getHasInfo(); + if (m_rfState == RS_RF_LISTENING && m_selfOnly && hasInfo) { + unsigned short srcId = layer3.getSourceUnitId(); + if (srcId != m_id) { + m_rfState = RS_RF_REJECTED; + return false; + } + } } - m_rfFrames = 0U; - m_rfErrs = 0U; - m_rfBits = 1U; - m_rfTimeoutTimer.start(); - m_rfState = RS_RF_AUDIO; + data[0U] = type == NXDN_MESSAGE_TYPE_TX_REL ? TAG_EOT : TAG_DATA; + data[1U] = 0x00U; + + CSync::addNXDNSync(data + 2U); + + CNXDNLICH lich = m_rfLastLICH; + lich.setDirection(m_remoteGateway ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND); + lich.encode(data + 2U); + + CNXDNSACCH sacch; + sacch.setRAN(m_ran); + sacch.setStructure(NXDN_SR_SINGLE); + sacch.setData(SACCH_IDLE); + sacch.encode(data + 2U); + + facch.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS); + facch.encode(data + 2U, NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS + NXDN_SACCH_LENGTH_BITS + NXDN_FACCH1_LENGTH_BITS); + + scrambler(data + 2U); + + // writeNetwork(data, m_rfFrames, ); - m_minRSSI = m_rssi; - m_maxRSSI = m_rssi; - m_aveRSSI = m_rssi; - m_rssiCount = 1U; #if defined(DUMP_NXDN) - openFile(); + writeFile(data + 2U); #endif - std::string source = m_lookup->find(srcId); - LogMessage("NXDN, received RF voice transmission from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId); - m_display->writeNXDN(source.c_str(), grp, dstId, "R"); + if (m_duplex) + writeQueueRF(data); - m_rfState = RS_RF_AUDIO; + if (type == NXDN_MESSAGE_TYPE_TX_REL) { + m_rfFrames++; + if (m_rssi != 0U) + LogMessage("NXDN, received RF end of transmission, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount); + else + LogMessage("NXDN, received RF end of transmission, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 25.0F, float(m_rfErrs * 100U) / float(m_rfBits)); + writeEndRF(); + } else { + m_rfFrames = 0U; + m_rfErrs = 0U; + m_rfBits = 1U; + m_rfTimeoutTimer.start(); + m_rfState = RS_RF_AUDIO; + m_minRSSI = m_rssi; + m_maxRSSI = m_rssi; + m_aveRSSI = m_rssi; + m_rssiCount = 1U; +#if defined(DUMP_NXDN) + openFile(); +#endif + m_rfLayer3 = layer3; + + unsigned short srcId = m_rfLayer3.getSourceUnitId(); + unsigned short dstId = m_rfLayer3.getDestinationGroupId(); + bool grp = m_rfLayer3.getIsGroup(); + + std::string source = m_lookup->find(srcId); + LogMessage("NXDN, received RF voice transmission from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId); + m_display->writeNXDN(source.c_str(), grp, dstId, "R"); + } + + return true; } + else { + // if (valid) { + 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; + + unsigned char messageType = m_rfLayer3.getMessageType(); + if (messageType != NXDN_MESSAGE_TYPE_VCALL) + return false; + + unsigned short srcId = m_rfLayer3.getSourceUnitId(); + unsigned short dstId = m_rfLayer3.getDestinationGroupId(); + bool grp = m_rfLayer3.getIsGroup(); + + if (m_selfOnly) { + if (srcId != m_id) { + m_rfState = RS_RF_REJECTED; + return false; + } + } + + m_rfFrames = 0U; + m_rfErrs = 0U; + m_rfBits = 1U; + m_rfTimeoutTimer.start(); + m_rfState = RS_RF_AUDIO; + + m_minRSSI = m_rssi; + m_maxRSSI = m_rssi; + m_aveRSSI = m_rssi; + m_rssiCount = 1U; +#if defined(DUMP_NXDN) + openFile(); +#endif + std::string source = m_lookup->find(srcId); + LogMessage("NXDN, received RF voice transmission from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId); + m_display->writeNXDN(source.c_str(), grp, dstId, "R"); + + m_rfState = RS_RF_AUDIO; + } + // } // if (m_rfState == RS_RF_AUDIO) { // Regenerate the sync diff --git a/NXDNFACCH1.cpp b/NXDNFACCH1.cpp index 48f4639..8d3ad45 100644 --- a/NXDNFACCH1.cpp +++ b/NXDNFACCH1.cpp @@ -42,7 +42,8 @@ const unsigned int INTERLEAVE_TABLE[] = { const unsigned int PUNCTURE_LIST[] = { 1U, 5U, 9U, 13U, 17U, 21U, 25U, 29U, 33U, 37U, 41U, 45U, 49U, 53U, 57U, 61U, 65U, 69U, 73U, 77U, 81U, 85U, 89U, 93U, 97U, 101U, 105U, 109U, 113U, 117U, - 121U, 125U, 129U, 133U, 137U, 141U}; + 121U, 125U, 129U, 133U, 137U, 141U, 145U, 149U, 153U, 157U, + 161U, 165U, 169U, 173U, 177U, 181U, 185U, 189U }; const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U }; @@ -121,11 +122,7 @@ void CNXDNFACCH1::encode(unsigned char* data, unsigned int offset) const unsigned char temp1[12U]; ::memset(temp1, 0x00U, 12U); - - for (unsigned int i = 0U; i < 80U; i++) { - bool b = READ_BIT1(m_data, i); - WRITE_BIT1(temp1, i, b); - } + ::memcpy(temp1, data, 10U); CNXDNCRC::encodeCRC12(temp1, 80U); diff --git a/NXDNLayer3.cpp b/NXDNLayer3.cpp index f4da16b..dce3d17 100644 --- a/NXDNLayer3.cpp +++ b/NXDNLayer3.cpp @@ -93,6 +93,15 @@ unsigned char CNXDNLayer3::getCallOptions() const return m_data[2U] & 0x1FU; } +bool CNXDNLayer3::getHasInfo() const +{ + unsigned char type = getMessageType(); + + return type != NXDN_MESSAGE_TYPE_IDLE && + type != NXDN_MESSAGE_TYPE_VCALL_IV && + type != NXDN_MESSAGE_TYPE_SDCALL_IV; +} + CNXDNLayer3& CNXDNLayer3::operator=(const CNXDNLayer3& layer3) { if (&layer3 != this) diff --git a/NXDNLayer3.h b/NXDNLayer3.h index 81aff2b..bd4ba6a 100644 --- a/NXDNLayer3.h +++ b/NXDNLayer3.h @@ -34,6 +34,7 @@ public: unsigned short getDestinationGroupId() const; bool getIsGroup() const; unsigned char getCallOptions() const; + bool getHasInfo() const; CNXDNLayer3& operator=(const CNXDNLayer3& layer3); diff --git a/NXDNSACCH.cpp b/NXDNSACCH.cpp index 304b20d..06d3e26 100755 --- a/NXDNSACCH.cpp +++ b/NXDNSACCH.cpp @@ -123,14 +123,14 @@ void CNXDNSACCH::encode(unsigned char* data) const CNXDNCRC::encodeCRC6(temp1, 26U); - CUtils::dump("NXDN, SACCH encoded with CRC", temp1, 4U); + CUtils::dump("NXDN, SACCH encoded with CRC", temp1, 5U); - unsigned char temp2[8U]; + unsigned char temp2[9U]; CNXDNConvolution conv; conv.encode(temp1, temp2, 36U); - // CUtils::dump("NXDN, SACCH convolved", temp2, 8U); + // CUtils::dump("NXDN, SACCH convolved", temp2, 9U); unsigned char temp3[8U]; diff --git a/NXDNUDCH.cpp b/NXDNUDCH.cpp index e58460e..6385edc 100644 --- a/NXDNUDCH.cpp +++ b/NXDNUDCH.cpp @@ -63,7 +63,8 @@ const unsigned int PUNCTURE_LIST[] = { 3U, 11U, 17U, 25U, 31U, 39U, 45U, 73U, 81U, 87U, 95U, 101U, 109U, 115U, 123U, 129U, 137U, 143U, 151U, 157U, 165U, 171U, 179U, 185U, 193U, 199U, 207U, 213U, 221U, 227U, 235U, 241U, 249U, 255U, 263U, 269U, 277U, - 283U, 291U, 297U, 305U, 311U, 319U, 325U, 333U, 339U, 347U }; + 283U, 291U, 297U, 305U, 311U, 319U, 325U, 333U, 339U, 347U, + 353U, 361U, 367U, 375U, 381U, 389U, 395U, 403U }; const unsigned char BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U }; @@ -142,11 +143,7 @@ void CNXDNUDCH::encode(unsigned char* data) const unsigned char temp1[25U]; ::memset(temp1, 0x00U, 25U); - - for (unsigned int i = 0U; i < 184U; i++) { - bool b = READ_BIT1(m_data, i); - WRITE_BIT1(temp1, i, b); - } + ::memcpy(temp1, data, 23U); CNXDNCRC::encodeCRC15(temp1, 184U); From 83e97aa21833ec7d27f8b409557b43082a9738cc Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 1 Feb 2018 18:49:03 +0000 Subject: [PATCH 4/9] Update the log messages. --- NXDNControl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/NXDNControl.cpp b/NXDNControl.cpp index 7b009aa..b140eb7 100644 --- a/NXDNControl.cpp +++ b/NXDNControl.cpp @@ -268,7 +268,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne bool grp = m_rfLayer3.getIsGroup(); std::string source = m_lookup->find(srcId); - LogMessage("NXDN, received RF voice transmission from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId); + LogMessage("NXDN, received RF header from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId); m_display->writeNXDN(source.c_str(), grp, dstId, "R"); } @@ -333,7 +333,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne openFile(); #endif std::string source = m_lookup->find(srcId); - LogMessage("NXDN, received RF voice transmission from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId); + LogMessage("NXDN, received RF late entry from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId); m_display->writeNXDN(source.c_str(), grp, dstId, "R"); m_rfState = RS_RF_AUDIO; From b69d3d247c9b35c05cbfcc556f714acacc1c450d Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 1 Feb 2018 19:07:55 +0000 Subject: [PATCH 5/9] Work on NXDN CRC routines. --- NXDNCRC.cpp | 89 ++++++++++++++++++++++++----------------------------- 1 file changed, 41 insertions(+), 48 deletions(-) diff --git a/NXDNCRC.cpp b/NXDNCRC.cpp index 0e2ad06..a065759 100644 --- a/NXDNCRC.cpp +++ b/NXDNCRC.cpp @@ -17,6 +17,7 @@ */ #include "NXDNCRC.h" +#include "Log.h" #include #include @@ -28,6 +29,7 @@ const uint16_t BIT_MASK_TABLE2[] = { 0x8000U, 0x4000U, 0x2000U, 0x1000U, 0x0800U #define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE1[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE1[(i)&7]) #define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE1[(i)&7]) +#define WRITE_BIT2(p,i,b) p[(i)>>4] = (b) ? (p[(i)>>4] | BIT_MASK_TABLE2[(i)&15]) : (p[(i)>>3] & ~BIT_MASK_TABLE2[(i)&15]) #define READ_BIT2(p,i) (p[(i)>>4] & BIT_MASK_TABLE2[(i)&15]) bool CNXDNCRC::checkCRC6(const unsigned char* in, unsigned int length) @@ -37,6 +39,16 @@ bool CNXDNCRC::checkCRC6(const unsigned char* in, unsigned int length) uint8_t crc[1U]; crc[0U] = createCRC6(in, length); + uint8_t temp[1U]; + temp[0U] = 0x00U; + unsigned int j = length; + for (unsigned int i = 0U; i < 6U; i++, j++) { + bool b = READ_BIT1(in, j); + WRITE_BIT1(temp, i, b); + } + + LogMessage("NXDN, CRC6: new:%02X old:%02X", crc[0U], temp[0U]); + unsigned int n = length; for (unsigned int i = 0U; i < 6U; i++, n++) { bool b1 = READ_BIT1(crc, i); @@ -69,6 +81,16 @@ bool CNXDNCRC::checkCRC12(const unsigned char* in, unsigned int length) uint16_t crc[1U]; crc[0U] = createCRC12(in, length); + uint16_t temp[1U]; + temp[0U] = 0x00U; + unsigned int j = length; + for (unsigned int i = 0U; i < 12U; i++, j++) { + bool b = READ_BIT1(in, j); + WRITE_BIT2(temp, i, b); + } + + LogMessage("NXDN, CRC12: new:%04X old:%04X", crc[0U], temp[0U]); + unsigned int n = length; for (unsigned int i = 0U; i < 12U; i++, n++) { bool b1 = READ_BIT2(crc, i); @@ -101,6 +123,16 @@ bool CNXDNCRC::checkCRC15(const unsigned char* in, unsigned int length) uint16_t crc[1U]; crc[0U] = createCRC15(in, length); + uint16_t temp[1U]; + temp[0U] = 0x00U; + unsigned int j = length; + for (unsigned int i = 0U; i < 15U; i++, j++) { + bool b = READ_BIT1(in, j); + WRITE_BIT2(temp, i, b); + } + + LogMessage("NXDN, CRC15: new:%04X old:%04X", crc[0U], temp[0U]); + unsigned int n = length; for (unsigned int i = 0U; i < 15U; i++, n++) { bool b1 = READ_BIT2(crc, i); @@ -128,93 +160,54 @@ void CNXDNCRC::encodeCRC15(unsigned char* in, unsigned int length) uint8_t CNXDNCRC::createCRC6(const unsigned char* in, unsigned int length) { - uint8_t crc = 0x3EU; + uint8_t crc = 0x3FU; for (unsigned int i = 0U; i < length; i++) { bool bit1 = READ_BIT1(in, i) != 0x00U; bool bit2 = (crc & 0x20U) == 0x20U; crc <<= 1; - - if (bit1) - crc |= 0x01U; - - if (bit2) - crc ^= 0x27U; - crc &= 0x3FU; - } - for (unsigned int i = 0U; i < 6U; i++) { - bool bit = (crc & 0x20U) == 0x20U; - - crc <<= 1; - - if (bit) + if (bit1 ^ bit2) crc ^= 0x27U; } - return (crc & 0x3FU) << 2U; + return crc & 0x3FU; } uint16_t CNXDNCRC::createCRC12(const unsigned char* in, unsigned int length) { - uint16_t crc = 0x0D9EU; + uint16_t crc = 0x0FFFU; for (unsigned int i = 0U; i < length; i++) { bool bit1 = READ_BIT1(in, i) != 0x00U; bool bit2 = (crc & 0x0800U) == 0x0800U; crc <<= 1; - - if (bit1) - crc |= 0x0001U; - - if (bit2) - crc ^= 0x080FU; - crc &= 0x0FFFU; - } - for (unsigned int i = 0U; i < 12U; i++) { - bool bit = (crc & 0x0800U) == 0x0800U; - - crc <<= 1; - - if (bit) + if (bit1 ^ bit2) crc ^= 0x080FU; } - return (crc & 0x0FFFU) << 4U; + return crc & 0x0FFFU; } uint16_t CNXDNCRC::createCRC15(const unsigned char* in, unsigned int length) { - uint16_t crc = 0x02E4U; + uint16_t crc = 0x7FFFU; for (unsigned int i = 0U; i < length; i++) { bool bit1 = READ_BIT1(in, i) != 0x00U; bool bit2 = (crc & 0x4000U) == 0x4000U; crc <<= 1; - - if (bit1) - crc |= 0x0001U; - - if (bit2) - crc ^= 0x4CC5U; - crc &= 0x7FFFU; - } - for (unsigned int i = 0U; i < 15U; i++) { - bool bit = (crc & 0x4000U) == 0x4000U; - - crc <<= 1; - - if (bit) + if (bit1 ^ bit2) crc ^= 0x4CC5U; } - return (crc & 0x7FFFU) << 1U; + return crc & 0x7FFFU; } From 1386b1dd2071674df1523c501dfecc5ed092bbbd Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 1 Feb 2018 19:19:02 +0000 Subject: [PATCH 6/9] Small changes needed for Windows compilation. --- NXDNConvolution.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/NXDNConvolution.cpp b/NXDNConvolution.cpp index 8db6a05..d5292fc 100755 --- a/NXDNConvolution.cpp +++ b/NXDNConvolution.cpp @@ -21,6 +21,7 @@ #include #include #include +#include const unsigned char BIT_MASK_TABLE[] = {0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U}; @@ -72,7 +73,7 @@ void CNXDNConvolution::decode(uint8_t s0, uint8_t s1) for (uint8_t i = 0U; i < NUM_OF_STATES_D2; i++) { uint8_t j = i * 2U; - uint16_t metric = abs(BRANCH_TABLE1[i] - s0) + abs(BRANCH_TABLE2[i] - s1); + uint16_t metric = ::abs(BRANCH_TABLE1[i] - s0) + ::abs(BRANCH_TABLE2[i] - s1); uint16_t m0 = m_oldMetrics[i] + metric; uint16_t m1 = m_oldMetrics[i + NUM_OF_STATES_D2] + (M - metric); From 536d3d9b971bf7a16aba120e85cece2582a3432b Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 1 Feb 2018 20:42:29 +0000 Subject: [PATCH 7/9] Fixed CRC6 detection. --- NXDNCRC.cpp | 59 +++++++++++++++-------------------------------------- 1 file changed, 16 insertions(+), 43 deletions(-) diff --git a/NXDNCRC.cpp b/NXDNCRC.cpp index a065759..12058a2 100644 --- a/NXDNCRC.cpp +++ b/NXDNCRC.cpp @@ -36,28 +36,19 @@ bool CNXDNCRC::checkCRC6(const unsigned char* in, unsigned int length) { assert(in != NULL); - uint8_t crc[1U]; - crc[0U] = createCRC6(in, length); + uint8_t crc = createCRC6(in, length); uint8_t temp[1U]; temp[0U] = 0x00U; unsigned int j = length; - for (unsigned int i = 0U; i < 6U; i++, j++) { + for (unsigned int i = 2U; i < 8U; i++, j++) { bool b = READ_BIT1(in, j); WRITE_BIT1(temp, i, b); } - LogMessage("NXDN, CRC6: new:%02X old:%02X", crc[0U], temp[0U]); + LogMessage("NXDN, CRC6: new:%02X old:%02X", crc, temp[0U]); - unsigned int n = length; - for (unsigned int i = 0U; i < 6U; i++, n++) { - bool b1 = READ_BIT1(crc, i); - bool b2 = READ_BIT1(in, n); - if (b1 != b2) - return false; - } - - return true; + return crc == temp[0U]; } void CNXDNCRC::encodeCRC6(unsigned char* in, unsigned int length) @@ -78,28 +69,19 @@ bool CNXDNCRC::checkCRC12(const unsigned char* in, unsigned int length) { assert(in != NULL); - uint16_t crc[1U]; - crc[0U] = createCRC12(in, length); + uint16_t crc = createCRC12(in, length); uint16_t temp[1U]; temp[0U] = 0x00U; unsigned int j = length; - for (unsigned int i = 0U; i < 12U; i++, j++) { + for (unsigned int i = 4U; i < 16U; i++, j++) { bool b = READ_BIT1(in, j); WRITE_BIT2(temp, i, b); } - LogMessage("NXDN, CRC12: new:%04X old:%04X", crc[0U], temp[0U]); + LogMessage("NXDN, CRC12: new:%04X old:%04X", crc, temp[0U]); - unsigned int n = length; - for (unsigned int i = 0U; i < 12U; i++, n++) { - bool b1 = READ_BIT2(crc, i); - bool b2 = READ_BIT1(in, n); - if (b1 != b2) - return false; - } - - return true; + return crc == temp[0U]; } void CNXDNCRC::encodeCRC12(unsigned char* in, unsigned int length) @@ -120,28 +102,19 @@ bool CNXDNCRC::checkCRC15(const unsigned char* in, unsigned int length) { assert(in != NULL); - uint16_t crc[1U]; - crc[0U] = createCRC15(in, length); + uint16_t crc = createCRC15(in, length); uint16_t temp[1U]; temp[0U] = 0x00U; unsigned int j = length; - for (unsigned int i = 0U; i < 15U; i++, j++) { + for (unsigned int i = 1U; i < 16U; i++, j++) { bool b = READ_BIT1(in, j); WRITE_BIT2(temp, i, b); } - LogMessage("NXDN, CRC15: new:%04X old:%04X", crc[0U], temp[0U]); + LogMessage("NXDN, CRC15: new:%04X old:%04X", crc, temp[0U]); - unsigned int n = length; - for (unsigned int i = 0U; i < 15U; i++, n++) { - bool b1 = READ_BIT2(crc, i); - bool b2 = READ_BIT1(in, n); - if (b1 != b2) - return false; - } - - return true; + return crc == temp[0U]; } void CNXDNCRC::encodeCRC15(unsigned char* in, unsigned int length) @@ -167,13 +140,13 @@ uint8_t CNXDNCRC::createCRC6(const unsigned char* in, unsigned int length) bool bit2 = (crc & 0x20U) == 0x20U; crc <<= 1; - crc &= 0x3FU; + crc &= 0x3EU; if (bit1 ^ bit2) crc ^= 0x27U; } - return crc & 0x3FU; + return crc; } uint16_t CNXDNCRC::createCRC12(const unsigned char* in, unsigned int length) @@ -185,7 +158,7 @@ uint16_t CNXDNCRC::createCRC12(const unsigned char* in, unsigned int length) bool bit2 = (crc & 0x0800U) == 0x0800U; crc <<= 1; - crc &= 0x0FFFU; + crc &= 0x0FFEU; if (bit1 ^ bit2) crc ^= 0x080FU; @@ -203,7 +176,7 @@ uint16_t CNXDNCRC::createCRC15(const unsigned char* in, unsigned int length) bool bit2 = (crc & 0x4000U) == 0x4000U; crc <<= 1; - crc &= 0x7FFFU; + crc &= 0x7FFEU; if (bit1 ^ bit2) crc ^= 0x4CC5U; From dcc8b04b2cc16c9eb0dfc6bef23a07966f99c464 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 1 Feb 2018 21:28:48 +0000 Subject: [PATCH 8/9] Have the CRC6 and CRC12 working with encoding and decoding, not tested CRC15. --- NXDNCRC.cpp | 65 ++++++++++++++++++++++++++++++------------------- NXDNControl.cpp | 27 +++----------------- NXDNFACCH1.cpp | 4 +-- NXDNSACCH.cpp | 4 +-- NXDNUDCH.cpp | 14 +++++------ 5 files changed, 55 insertions(+), 59 deletions(-) diff --git a/NXDNCRC.cpp b/NXDNCRC.cpp index 12058a2..cccbb84 100644 --- a/NXDNCRC.cpp +++ b/NXDNCRC.cpp @@ -23,15 +23,10 @@ #include const uint8_t BIT_MASK_TABLE1[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U }; -const uint16_t BIT_MASK_TABLE2[] = { 0x8000U, 0x4000U, 0x2000U, 0x1000U, 0x0800U, 0x0400U, 0x0200U, 0x0100U, - 0x0080U, 0x0040U, 0x0020U, 0x0010U, 0x0008U, 0x0004U, 0x0002U, 0x0001U }; #define WRITE_BIT1(p,i,b) p[(i)>>3] = (b) ? (p[(i)>>3] | BIT_MASK_TABLE1[(i)&7]) : (p[(i)>>3] & ~BIT_MASK_TABLE1[(i)&7]) #define READ_BIT1(p,i) (p[(i)>>3] & BIT_MASK_TABLE1[(i)&7]) -#define WRITE_BIT2(p,i,b) p[(i)>>4] = (b) ? (p[(i)>>4] | BIT_MASK_TABLE2[(i)&15]) : (p[(i)>>3] & ~BIT_MASK_TABLE2[(i)&15]) -#define READ_BIT2(p,i) (p[(i)>>4] & BIT_MASK_TABLE2[(i)&15]) - bool CNXDNCRC::checkCRC6(const unsigned char* in, unsigned int length) { assert(in != NULL); @@ -46,7 +41,7 @@ bool CNXDNCRC::checkCRC6(const unsigned char* in, unsigned int length) WRITE_BIT1(temp, i, b); } - LogMessage("NXDN, CRC6: new:%02X old:%02X", crc, temp[0U]); + // LogMessage("NXDN, CRC6: new:%02X old:%02X", crc, temp[0U]); return crc == temp[0U]; } @@ -58,8 +53,10 @@ void CNXDNCRC::encodeCRC6(unsigned char* in, unsigned int length) uint8_t crc[1U]; crc[0U] = createCRC6(in, length); + // LogMessage("NXDN, CRC6: new:%02X", crc[0U]); + unsigned int n = length; - for (unsigned int i = 0U; i < 6U; i++, n++) { + for (unsigned int i = 2U; i < 8U; i++, n++) { bool b = READ_BIT1(crc, i); WRITE_BIT1(in, n, b); } @@ -70,30 +67,39 @@ bool CNXDNCRC::checkCRC12(const unsigned char* in, unsigned int length) assert(in != NULL); uint16_t crc = createCRC12(in, length); + uint8_t temp1[2U]; + temp1[0U] = (crc >> 8) & 0xFFU; + temp1[1U] = (crc >> 0) & 0xFFU; - uint16_t temp[1U]; - temp[0U] = 0x00U; + uint8_t temp2[2U]; + temp2[0U] = 0x00U; + temp2[1U] = 0x00U; unsigned int j = length; for (unsigned int i = 4U; i < 16U; i++, j++) { bool b = READ_BIT1(in, j); - WRITE_BIT2(temp, i, b); + WRITE_BIT1(temp2, i, b); } - LogMessage("NXDN, CRC12: new:%04X old:%04X", crc, temp[0U]); + // LogMessage("NXDN, CRC12: new:%02X%02X old:%02X%02X", temp1[0U], temp1[1U], temp2[0U], temp2[1U]); - return crc == temp[0U]; + return temp1[0U] == temp2[0U] && temp1[1U] == temp2[1U]; } void CNXDNCRC::encodeCRC12(unsigned char* in, unsigned int length) { assert(in != NULL); - uint16_t crc[1U]; - crc[0U] = createCRC12(in, length); + uint16_t crc = createCRC12(in, length); + + uint8_t temp[2U]; + temp[0U] = (crc >> 8) & 0xFFU; + temp[1U] = (crc >> 0) & 0xFFU; + + // LogMessage("NXDN, CRC12: new:%02X%02X", temp[0U], temp[1U]); unsigned int n = length; - for (unsigned int i = 0U; i < 12U; i++, n++) { - bool b = READ_BIT2(crc, i); + for (unsigned int i = 4U; i < 16U; i++, n++) { + bool b = READ_BIT1(temp, i); WRITE_BIT1(in, n, b); } } @@ -103,30 +109,39 @@ bool CNXDNCRC::checkCRC15(const unsigned char* in, unsigned int length) assert(in != NULL); uint16_t crc = createCRC15(in, length); + uint8_t temp1[2U]; + temp1[0U] = (crc >> 8) & 0xFFU; + temp1[1U] = (crc >> 0) & 0xFFU; - uint16_t temp[1U]; - temp[0U] = 0x00U; + uint16_t temp2[2U]; + temp2[0U] = 0x00U; + temp2[1U] = 0x00U; unsigned int j = length; for (unsigned int i = 1U; i < 16U; i++, j++) { bool b = READ_BIT1(in, j); - WRITE_BIT2(temp, i, b); + WRITE_BIT1(temp2, i, b); } - LogMessage("NXDN, CRC15: new:%04X old:%04X", crc, temp[0U]); + // LogMessage("NXDN, CRC15: new:%02X%02X old:%02X%02X", temp1[0U], temp1[1U], temp2[0U], temp2[1U]); - return crc == temp[0U]; + return temp1[0U] == temp2[0U] && temp1[1U] == temp2[1U]; } void CNXDNCRC::encodeCRC15(unsigned char* in, unsigned int length) { assert(in != NULL); - uint16_t crc[1U]; - crc[0U] = createCRC15(in, length); + uint16_t crc = createCRC15(in, length); + + uint8_t temp[2U]; + temp[0U] = (crc >> 8) & 0xFFU; + temp[1U] = (crc >> 0) & 0xFFU; + + // LogMessage("NXDN, CRC15: new:%02X%02X", temp[0U], temp[1U]); unsigned int n = length; - for (unsigned int i = 0U; i < 15U; i++, n++) { - bool b = READ_BIT2(crc, i); + for (unsigned int i = 1U; i < 16U; i++, n++) { + bool b = READ_BIT1(temp, i); WRITE_BIT1(in, n, b); } } diff --git a/NXDNControl.cpp b/NXDNControl.cpp index b140eb7..5f4b626 100644 --- a/NXDNControl.cpp +++ b/NXDNControl.cpp @@ -175,7 +175,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne if (ran != m_ran && ran != 0U) return false; } else if (m_rfState == RS_RF_LISTENING) { - // return false; + return false; } // XXX Reconstruct invalid LICH @@ -186,8 +186,8 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne bool 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); - // if (!valid) - // return false; + if (!valid) + return false; unsigned char buffer[10U]; facch.getData(buffer); @@ -273,8 +273,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne } return true; - } - else { + } else { // if (valid) { unsigned char message[3U]; sacch.getData(message); @@ -451,24 +450,6 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne m_display->writeNXDNRSSI(m_rssi); -#ifdef notdef - // Process end of audio here - if (endofdata) { - if (m_rfState == RS_RF_AUDIO) { - if (m_rssi != 0U) - LogMessage("NXDN, received RF end of transmission, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm", float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount); - else - LogMessage("NXDN, received RF end of transmission, %.1f seconds, BER: %.1f%%", float(m_rfFrames) / 10.0F, float(m_rfErrs * 100U) / float(m_rfBits)); - - writeEndRF(); - } else { - m_rfState = RS_RF_LISTENING; - m_rfMask = 0x00U; - return false; - } - } -#endif - return true; } diff --git a/NXDNFACCH1.cpp b/NXDNFACCH1.cpp index 8080d52..ca2a9fc 100644 --- a/NXDNFACCH1.cpp +++ b/NXDNFACCH1.cpp @@ -115,7 +115,7 @@ bool CNXDNFACCH1::decode(const unsigned char* data, unsigned int offset) conv.chainback(m_data, 96U); - CUtils::dump("NXDN, FACCH1 decoded", m_data, 12U); + // CUtils::dump("NXDN, FACCH1 decoded", m_data, 12U); return CNXDNCRC::checkCRC12(m_data, 80U); } @@ -126,7 +126,7 @@ void CNXDNFACCH1::encode(unsigned char* data, unsigned int offset) const unsigned char temp1[12U]; ::memset(temp1, 0x00U, 12U); - ::memcpy(temp1, data, 10U); + ::memcpy(temp1, m_data, 10U); CNXDNCRC::encodeCRC12(temp1, 80U); diff --git a/NXDNSACCH.cpp b/NXDNSACCH.cpp index 323e48d..b060fa4 100755 --- a/NXDNSACCH.cpp +++ b/NXDNSACCH.cpp @@ -108,7 +108,7 @@ bool CNXDNSACCH::decode(const unsigned char* data) conv.chainback(m_data, 36U); - CUtils::dump("NXDN, SACCH decoded", m_data, 4U); + // CUtils::dump("NXDN, SACCH decoded", m_data, 4U); return CNXDNCRC::checkCRC6(m_data, 26U); } @@ -127,7 +127,7 @@ void CNXDNSACCH::encode(unsigned char* data) const CNXDNCRC::encodeCRC6(temp1, 26U); - CUtils::dump("NXDN, SACCH encoded with CRC", temp1, 5U); + // CUtils::dump("NXDN, SACCH encoded with CRC", temp1, 4U); unsigned char temp2[9U]; diff --git a/NXDNUDCH.cpp b/NXDNUDCH.cpp index 3581474..c4ead27 100644 --- a/NXDNUDCH.cpp +++ b/NXDNUDCH.cpp @@ -93,7 +93,7 @@ bool CNXDNUDCH::decode(const unsigned char* data) { assert(data != NULL); - CUtils::dump("NXDN, UDCH/FACCH2 input", data, 44U); + // CUtils::dump("NXDN, UDCH/FACCH2 input", data, 44U); unsigned char temp1[44U]; @@ -103,7 +103,7 @@ bool CNXDNUDCH::decode(const unsigned char* data) WRITE_BIT1(temp1, i, b); } - CUtils::dump("NXDN, UDCH/FACCH2 de-interleaved", temp1, 44U); + // CUtils::dump("NXDN, UDCH/FACCH2 de-interleaved", temp1, 44U); uint8_t temp2[420U]; @@ -136,7 +136,7 @@ bool CNXDNUDCH::decode(const unsigned char* data) conv.chainback(m_data, 203U); - CUtils::dump("NXDN, UDCH/FACCH2 decoded", m_data, 25U); + // CUtils::dump("NXDN, UDCH/FACCH2 decoded", m_data, 25U); return CNXDNCRC::checkCRC15(m_data, 184U); } @@ -147,18 +147,18 @@ void CNXDNUDCH::encode(unsigned char* data) const unsigned char temp1[25U]; ::memset(temp1, 0x00U, 25U); - ::memcpy(temp1, data, 23U); + ::memcpy(temp1, m_data, 23U); CNXDNCRC::encodeCRC15(temp1, 184U); - CUtils::dump("NXDN, UDCH/FACCH2 encoded with CRC", temp1, 25U); + // CUtils::dump("NXDN, UDCH/FACCH2 encoded with CRC", temp1, 25U); unsigned char temp2[51U]; CNXDNConvolution conv; conv.encode(temp1, temp2, 203U); - CUtils::dump("NXDN, UDCH/FACCH2 convolved", temp2, 51U); + // CUtils::dump("NXDN, UDCH/FACCH2 convolved", temp2, 51U); unsigned char temp3[44U]; @@ -174,7 +174,7 @@ void CNXDNUDCH::encode(unsigned char* data) const } } - CUtils::dump("NXDN, UDCH/FACCH2 punctured", temp3, 44U); + // CUtils::dump("NXDN, UDCH/FACCH2 punctured", temp3, 44U); for (unsigned int i = 0U; i < NXDN_FACCH2_LENGTH_BITS; i++) { unsigned int n = INTERLEAVE_TABLE[i] + NXDN_FSW_LENGTH_BITS + NXDN_LICH_LENGTH_BITS; From 7cc2a042b5090446d1ad8ac5f24fe9f909f65c5a Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 1 Feb 2018 22:05:17 +0000 Subject: [PATCH 9/9] Improve the logic of the repeater, late entry still to finish. --- NXDNCRC.cpp | 13 ------------- NXDNControl.cpp | 15 ++++++++------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/NXDNCRC.cpp b/NXDNCRC.cpp index cccbb84..29da35c 100644 --- a/NXDNCRC.cpp +++ b/NXDNCRC.cpp @@ -17,7 +17,6 @@ */ #include "NXDNCRC.h" -#include "Log.h" #include #include @@ -41,8 +40,6 @@ bool CNXDNCRC::checkCRC6(const unsigned char* in, unsigned int length) WRITE_BIT1(temp, i, b); } - // LogMessage("NXDN, CRC6: new:%02X old:%02X", crc, temp[0U]); - return crc == temp[0U]; } @@ -53,8 +50,6 @@ void CNXDNCRC::encodeCRC6(unsigned char* in, unsigned int length) uint8_t crc[1U]; crc[0U] = createCRC6(in, length); - // LogMessage("NXDN, CRC6: new:%02X", crc[0U]); - unsigned int n = length; for (unsigned int i = 2U; i < 8U; i++, n++) { bool b = READ_BIT1(crc, i); @@ -80,8 +75,6 @@ bool CNXDNCRC::checkCRC12(const unsigned char* in, unsigned int length) WRITE_BIT1(temp2, i, b); } - // LogMessage("NXDN, CRC12: new:%02X%02X old:%02X%02X", temp1[0U], temp1[1U], temp2[0U], temp2[1U]); - return temp1[0U] == temp2[0U] && temp1[1U] == temp2[1U]; } @@ -95,8 +88,6 @@ void CNXDNCRC::encodeCRC12(unsigned char* in, unsigned int length) temp[0U] = (crc >> 8) & 0xFFU; temp[1U] = (crc >> 0) & 0xFFU; - // LogMessage("NXDN, CRC12: new:%02X%02X", temp[0U], temp[1U]); - unsigned int n = length; for (unsigned int i = 4U; i < 16U; i++, n++) { bool b = READ_BIT1(temp, i); @@ -122,8 +113,6 @@ bool CNXDNCRC::checkCRC15(const unsigned char* in, unsigned int length) WRITE_BIT1(temp2, i, b); } - // LogMessage("NXDN, CRC15: new:%02X%02X old:%02X%02X", temp1[0U], temp1[1U], temp2[0U], temp2[1U]); - return temp1[0U] == temp2[0U] && temp1[1U] == temp2[1U]; } @@ -137,8 +126,6 @@ void CNXDNCRC::encodeCRC15(unsigned char* in, unsigned int length) temp[0U] = (crc >> 8) & 0xFFU; temp[1U] = (crc >> 0) & 0xFFU; - // LogMessage("NXDN, CRC15: new:%02X%02X", temp[0U], temp[1U]); - unsigned int n = length; for (unsigned int i = 1U; i < 16U; i++, n++) { bool b = READ_BIT1(temp, i); diff --git a/NXDNControl.cpp b/NXDNControl.cpp index 5f4b626..35973f3 100644 --- a/NXDNControl.cpp +++ b/NXDNControl.cpp @@ -274,7 +274,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne return true; } else { - // if (valid) { + if (m_rfState == RS_RF_LISTENING) { unsigned char message[3U]; sacch.getData(message); @@ -300,11 +300,11 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne break; } - // if (m_rfMask != 0x0FU) - // return false; + if (m_rfMask != 0x0FU) + return false; - unsigned char messageType = m_rfLayer3.getMessageType(); - if (messageType != NXDN_MESSAGE_TYPE_VCALL) + bool hasInfo = m_rfLayer3.getHasInfo(); + if (!hasInfo) return false; unsigned short srcId = m_rfLayer3.getSourceUnitId(); @@ -337,9 +337,9 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne m_rfState = RS_RF_AUDIO; } - // } + } - // if (m_rfState == RS_RF_AUDIO) { + if (m_rfState == RS_RF_AUDIO) { // Regenerate the sync CSync::addNXDNSync(data + 2U); @@ -449,6 +449,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne m_rfFrames++; m_display->writeNXDNRSSI(m_rssi); + } return true; }