From 4435af975df2fc40c87023c5c512c6e8b3090ad1 Mon Sep 17 00:00:00 2001 From: Andy CA6JAU Date: Sat, 3 Feb 2018 11:07:13 -0300 Subject: [PATCH 01/10] =?UTF-8?q?Fix=20bug=20=E2=80=9CDMR=20ghost=20privat?= =?UTF-8?q?e=20calls=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- DMRSlot.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/DMRSlot.cpp b/DMRSlot.cpp index 3b0f2e1..a296574 100644 --- a/DMRSlot.cpp +++ b/DMRSlot.cpp @@ -1540,8 +1540,10 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) m_display->writeDMR(m_slotNo, src, gi, dst, "N"); } } else if (dataType == DT_RATE_12_DATA || dataType == DT_RATE_34_DATA || dataType == DT_RATE_1_DATA) { - if (m_netState != RS_NET_DATA || m_netFrames == 0U) + if (m_netState != RS_NET_DATA || m_netFrames == 0U) { + writeEndNet(); return; + } // Regenerate the rate 1/2 payload if (dataType == DT_RATE_12_DATA) { From a6269c13e523bc7dc797fc81a4ecaea40dc39aba Mon Sep 17 00:00:00 2001 From: "Ralph A. Schmid" Date: Sun, 4 Feb 2018 14:30:23 +0100 Subject: [PATCH 02/10] Create RSSI_FC-302_RptrBldrV2.dat One more RSSI table... --- RSSI/RSSI_FC-302_RptrBldrV2.dat | 41 +++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 RSSI/RSSI_FC-302_RptrBldrV2.dat diff --git a/RSSI/RSSI_FC-302_RptrBldrV2.dat b/RSSI/RSSI_FC-302_RptrBldrV2.dat new file mode 100644 index 0000000..aa1e523 --- /dev/null +++ b/RSSI/RSSI_FC-302_RptrBldrV2.dat @@ -0,0 +1,41 @@ +# This file maps the raw RSSI values to dBm values to send to the DMR network. A number of data +# points should be entered and the software will use those to work out the in-between values. +# +# The format of the file is: +# Raw RSSI Value dBm Value +# +# The following values were taken with a Schlumberger Stabilock 4040 radio tester as transmitter +# Radio is a Friendcom FC-302 UHF, 12.5 KHz BW, RSSI PIN 7 directly connected to board +# Setup is MMDVM on a Pi3 with modem "Repeater-Builder STM32-DVM V2", RSSI POT at maximum +# Ralph, dk5ras, 20180204 + +1626 -46 +1622 -49 +1611 -52 +1591 -55 +1547 -58 +1486 -61 +1409 -64 +1344 -67 +1292 -70 +1235 -73 +1155 -76 +1068 -79 +1000 -82 +950 -85 +895 -88 +847 -91 +783 -94 +715 -97 +660 -100 +600 -103 +525 -106 +438 -109 +363 -112 +305 -115 +246 -118 +188 -121 +135 -124 +100 -127 +77 -130 +64 -133 From a0394afd9159b05e13127f1c189c1f006d020a02 Mon Sep 17 00:00:00 2001 From: Andy CA6JAU Date: Sun, 4 Feb 2018 14:46:09 -0300 Subject: [PATCH 03/10] Discard DMR audio frames with N > 5 (RF side) --- DMRSlot.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/DMRSlot.cpp b/DMRSlot.cpp index a296574..7db9c53 100644 --- a/DMRSlot.cpp +++ b/DMRSlot.cpp @@ -562,6 +562,9 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len) if (m_rfState == RS_RF_AUDIO) { m_rfN = data[1U] & 0x0FU; + if(m_rfN > 5U) + return false; + unsigned int errors = 0U; unsigned char fid = m_rfLC->getFID(); if (fid == FID_ETSI || fid == FID_DMRA) { @@ -802,6 +805,9 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len) m_rfN = data[1U] & 0x0FU; + if(m_rfN > 5U) + return false; + // Regenerate the EMB emb.getData(data + 2U); From 14a06e7182e0457c84ec86675159a6d60ed3ff91 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 5 Feb 2018 19:07:23 +0000 Subject: [PATCH 04/10] Calculate the RSSI and BER correctly on the Nextion. --- Nextion.cpp | 114 ++++++---------------------------------------------- 1 file changed, 13 insertions(+), 101 deletions(-) diff --git a/Nextion.cpp b/Nextion.cpp index d0495ba..cbdc9c1 100644 --- a/Nextion.cpp +++ b/Nextion.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016,2017 by Jonathan Naylor G4KLX + * Copyright (C) 2016,2017,2018 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -205,15 +205,6 @@ void CNextion::writeDStarInt(const char* my1, const char* my2, const char* your, void CNextion::writeDStarRSSIInt(unsigned char rssi) { - if (m_rssiCount1 == 0U) { - char text[20U]; - ::sprintf(text, "t3.txt=\"-%udBm\"", rssi); - sendCommand(text); - sendCommandAction(47U); - m_rssiCount1 = 1U; - return; - } - m_rssiAccum1 += rssi; m_rssiCount1++; @@ -223,21 +214,12 @@ void CNextion::writeDStarRSSIInt(unsigned char rssi) sendCommand(text); sendCommandAction(47U); m_rssiAccum1 = 0U; - m_rssiCount1 = 1U; + m_rssiCount1 = 0U; } } void CNextion::writeDStarBERInt(float ber) { - if (m_berCount1 == 0U) { - char text[20U]; - ::sprintf(text, "t4.txt=\"%.1f%%\"", ber); - sendCommand(text); - sendCommandAction(48U); - m_berCount1 = 1U; - return; - } - m_berAccum1 += ber; m_berCount1++; @@ -247,7 +229,7 @@ void CNextion::writeDStarBERInt(float ber) sendCommand(text); sendCommandAction(48U); m_berAccum1 = 0.0F; - m_berCount1 = 1U; + m_berCount1 = 0U; } } @@ -339,15 +321,6 @@ void CNextion::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro void CNextion::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi) { if (slotNo == 1U) { - if (m_rssiCount1 == 0U) { - char text[20U]; - ::sprintf(text, "t4.txt=\"-%udBm\"", rssi); - sendCommand(text); - sendCommandAction(66U); - m_rssiCount1 = 1U; - return; - } - m_rssiAccum1 += rssi; m_rssiCount1++; @@ -357,18 +330,9 @@ void CNextion::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi) sendCommand(text); sendCommandAction(66U); m_rssiAccum1 = 0U; - m_rssiCount1 = 1U; + m_rssiCount1 = 0U; } } else { - if (m_rssiCount2 == 0U) { - char text[20U]; - ::sprintf(text, "t5.txt=\"-%udBm\"", rssi); - sendCommandAction(74U); - sendCommand(text); - m_rssiCount2 = 1U; - return; - } - m_rssiAccum2 += rssi; m_rssiCount2++; @@ -378,7 +342,7 @@ void CNextion::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi) sendCommand(text); sendCommandAction(74U); m_rssiAccum2 = 0U; - m_rssiCount2 = 1U; + m_rssiCount2 = 0U; } } } @@ -396,6 +360,7 @@ void CNextion::writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, co if (m_screenLayout == 2U) sendCommand("t2.pco=33808"); sendCommandAction(72U); } + return; } @@ -413,6 +378,7 @@ void CNextion::writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, co sendCommand("t0.pco=1024"); } + sendCommand(text); sendCommandAction(63U); } else { @@ -437,15 +403,6 @@ void CNextion::writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, co void CNextion::writeDMRBERInt(unsigned int slotNo, float ber) { if (slotNo == 1U) { - if (m_berCount1 == 0U) { - char text[20U]; - ::sprintf(text, "t6.txt=\"%.1f%%\"", ber); - sendCommand(text); - sendCommandAction(67U); - m_berCount1 = 1U; - return; - } - m_berAccum1 += ber; m_berCount1++; @@ -455,18 +412,9 @@ void CNextion::writeDMRBERInt(unsigned int slotNo, float ber) sendCommand(text); sendCommandAction(67U); m_berAccum1 = 0U; - m_berCount1 = 1U; + m_berCount1 = 0U; } } else { - if (m_berCount2 == 0U) { - char text[20U]; - ::sprintf(text, "t7.txt=\"%.1f%%\"", ber); - sendCommand(text); - sendCommandAction(75U); - m_berCount2 = 1U; - return; - } - m_berAccum2 += ber; m_berCount2++; @@ -476,7 +424,7 @@ void CNextion::writeDMRBERInt(unsigned int slotNo, float ber) sendCommand(text); sendCommandAction(75U); m_berAccum2 = 0U; - m_berCount2 = 1U; + m_berCount2 = 0U; } } } @@ -551,15 +499,6 @@ void CNextion::writeFusionInt(const char* source, const char* dest, const char* void CNextion::writeFusionRSSIInt(unsigned char rssi) { - if (m_rssiCount1 == 0U) { - char text[20U]; - ::sprintf(text, "t3.txt=\"-%udBm\"", rssi); - sendCommand(text); - sendCommandAction(85U); - m_rssiCount1 = 1U; - return; - } - m_rssiAccum1 += rssi; m_rssiCount1++; @@ -569,21 +508,12 @@ void CNextion::writeFusionRSSIInt(unsigned char rssi) sendCommand(text); sendCommandAction(85U); m_rssiAccum1 = 0U; - m_rssiCount1 = 1U; + m_rssiCount1 = 0U; } } void CNextion::writeFusionBERInt(float ber) { - if (m_berCount1 == 0U) { - char text[20U]; - ::sprintf(text, "t4.txt=\"%.1f%%\"", ber); - sendCommand(text); - sendCommandAction(86U); - m_berCount1 = 1U; - return; - } - m_berAccum1 += ber; m_berCount1++; @@ -593,7 +523,7 @@ void CNextion::writeFusionBERInt(float ber) sendCommand(text); sendCommandAction(86U); m_berAccum1 = 0.0F; - m_berCount1 = 1U; + m_berCount1 = 0U; } } @@ -640,15 +570,6 @@ void CNextion::writeP25Int(const char* source, bool group, unsigned int dest, co void CNextion::writeP25RSSIInt(unsigned char rssi) { - if (m_rssiCount1 == 0U) { - char text[20U]; - ::sprintf(text, "t2.txt=\"-%udBm\"", rssi); - sendCommand(text); - sendCommandAction(104U); - m_rssiCount1 = 1U; - return; - } - m_rssiAccum1 += rssi; m_rssiCount1++; @@ -658,21 +579,12 @@ void CNextion::writeP25RSSIInt(unsigned char rssi) sendCommand(text); sendCommandAction(104U); m_rssiAccum1 = 0U; - m_rssiCount1 = 1U; + m_rssiCount1 = 0U; } } void CNextion::writeP25BERInt(float ber) { - if (m_berCount1 == 0U) { - char text[20U]; - ::sprintf(text, "t3.txt=\"%.1f%%\"", ber); - sendCommand(text); - sendCommandAction(105U); - m_berCount1 = 1U; - return; - } - m_berAccum1 += ber; m_berCount1++; @@ -682,7 +594,7 @@ void CNextion::writeP25BERInt(float ber) sendCommand(text); sendCommandAction(105U); m_berAccum1 = 0.0F; - m_berCount1 = 1U; + m_berCount1 = 0U; } } From 4323c02a0aca78d06681e04411c39b7deccb7b64 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 5 Feb 2018 19:46:27 +0000 Subject: [PATCH 05/10] Add a proper bypass for the jitter buffer if wanted. --- DMRNetwork.cpp | 30 +++++++-- DMRNetwork.h | 2 + Defines.h | 8 ++- DelayBuffer.cpp | 137 ++++++++++++++++++++++++++++++++++++++ DelayBuffer.h | 57 ++++++++++++++++ JitterBuffer.cpp | 12 ++-- JitterBuffer.h | 9 +-- MMDVMHost.vcxproj | 2 + MMDVMHost.vcxproj.filters | 6 ++ Makefile | 11 +-- Makefile.Pi | 11 +-- Makefile.Pi.Adafruit | 11 +-- Makefile.Pi.HD44780 | 11 +-- Makefile.Pi.OLED | 11 +-- Makefile.Pi.PCF8574 | 11 +-- Makefile.Solaris | 11 +-- 16 files changed, 287 insertions(+), 53 deletions(-) create mode 100644 DelayBuffer.cpp create mode 100644 DelayBuffer.h diff --git a/DMRNetwork.cpp b/DMRNetwork.cpp index c9f251a..0b1edcf 100644 --- a/DMRNetwork.cpp +++ b/DMRNetwork.cpp @@ -46,6 +46,7 @@ m_slot1(slot1), m_slot2(slot2), m_jitterEnabled(jitterEnabled), m_jitterBuffers(NULL), +m_delayBuffers(NULL), m_hwType(hwType), m_status(WAITING_CONNECT), m_retryTimer(1000U, 10U), @@ -79,11 +80,16 @@ m_beacon(false) m_salt = new unsigned char[sizeof(uint32_t)]; m_id = new uint8_t[4U]; m_streamId = new uint32_t[2U]; + m_jitterBuffers = new CJitterBuffer*[3U]; + m_delayBuffers = new CDelayBuffer*[3U]; m_jitterBuffers[1U] = new CJitterBuffer("DMR Slot 1", 60U, DMR_SLOT_TIME, jitter, 256U, debug); m_jitterBuffers[2U] = new CJitterBuffer("DMR Slot 2", 60U, DMR_SLOT_TIME, jitter, 256U, debug); + m_delayBuffers[1U] = new CDelayBuffer("DMR Slot 1", 60U, DMR_SLOT_TIME, jitter, debug); + m_delayBuffers[2U] = new CDelayBuffer("DMR Slot 2", 60U, DMR_SLOT_TIME, jitter, debug); + m_id[0U] = id >> 24; m_id[1U] = id >> 16; m_id[2U] = id >> 8; @@ -101,11 +107,16 @@ CDMRNetwork::~CDMRNetwork() delete m_jitterBuffers[1U]; delete m_jitterBuffers[2U]; + delete m_delayBuffers[1U]; + delete m_delayBuffers[2U]; + delete[] m_buffer; delete[] m_salt; delete[] m_streamId; delete[] m_id; + delete[] m_jitterBuffers; + delete[] m_delayBuffers; } void CDMRNetwork::setOptions(const std::string& options) @@ -151,8 +162,14 @@ bool CDMRNetwork::read(CDMRData& data) for (unsigned int slotNo = 1U; slotNo <= 2U; slotNo++) { unsigned int length = 0U; - JB_STATUS status = m_jitterBuffers[slotNo]->getData(m_buffer, length); - if (status != JBS_NO_DATA) { + B_STATUS status = BS_NO_DATA; + + if (m_jitterEnabled) + status = m_jitterBuffers[slotNo]->getData(m_buffer, length); + else + status = m_delayBuffers[slotNo]->getData(m_buffer, length); + + if (status != BS_NO_DATA) { unsigned char seqNo = m_buffer[4U]; unsigned int srcId = (m_buffer[5U] << 16) | (m_buffer[6U] << 8) | (m_buffer[7U] << 0); @@ -166,7 +183,7 @@ bool CDMRNetwork::read(CDMRData& data) data.setSrcId(srcId); data.setDstId(dstId); data.setFLCO(flco); - data.setMissing(status == JBS_MISSING); + data.setMissing(status == BS_MISSING); bool dataSync = (m_buffer[15U] & 0x20U) == 0x20U; bool voiceSync = (m_buffer[15U] & 0x10U) == 0x10U; @@ -331,6 +348,9 @@ void CDMRNetwork::clock(unsigned int ms) m_jitterBuffers[1U]->clock(ms); m_jitterBuffers[2U]->clock(ms); + m_delayBuffers[1U]->clock(ms); + m_delayBuffers[2U]->clock(ms); + if (m_status == WAITING_CONNECT) { m_retryTimer.clock(ms); if (m_retryTimer.isRunning() && m_retryTimer.hasExpired()) { @@ -475,9 +495,11 @@ void CDMRNetwork::reset(unsigned int slotNo) if (slotNo == 1U) { m_jitterBuffers[1U]->reset(); + m_delayBuffers[1U]->reset(); m_streamId[0U] = ::rand() + 1U; } else { m_jitterBuffers[2U]->reset(); + m_delayBuffers[2U]->reset(); m_streamId[1U] = ::rand() + 1U; } } @@ -514,7 +536,7 @@ void CDMRNetwork::receiveData(const unsigned char* data, unsigned int length) m_jitterBuffers[slotNo]->addData(data, length, seqNo); } } else { - m_jitterBuffers[slotNo]->appendData(data, length); + m_delayBuffers[slotNo]->addData(data, length); } } diff --git a/DMRNetwork.h b/DMRNetwork.h index cfacb77..799b2bc 100644 --- a/DMRNetwork.h +++ b/DMRNetwork.h @@ -20,6 +20,7 @@ #define DMRNetwork_H #include "JitterBuffer.h" +#include "DelayBuffer.h" #include "UDPSocket.h" #include "Timer.h" #include "DMRData.h" @@ -72,6 +73,7 @@ private: bool m_slot2; bool m_jitterEnabled; CJitterBuffer** m_jitterBuffers; + CDelayBuffer** m_delayBuffers; HW_TYPE m_hwType; enum STATUS { diff --git a/Defines.h b/Defines.h index 9285789..852fd3e 100644 --- a/Defines.h +++ b/Defines.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -57,4 +57,10 @@ enum RPT_NET_STATE { RS_NET_DATA }; +enum B_STATUS { + BS_NO_DATA, + BS_DATA, + BS_MISSING +}; + #endif diff --git a/DelayBuffer.cpp b/DelayBuffer.cpp new file mode 100644 index 0000000..e38125b --- /dev/null +++ b/DelayBuffer.cpp @@ -0,0 +1,137 @@ +/* +* Copyright (C) 2018 by Jonathan Naylor G4KLX +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "DelayBuffer.h" + +#include "Log.h" + +#include +#include +#include + +CDelayBuffer::CDelayBuffer(const std::string& name, unsigned int blockSize, unsigned int blockTime, unsigned int jitterTime, bool debug) : +m_name(name), +m_blockSize(blockSize), +m_blockTime(blockTime), +m_debug(debug), +m_timer(1000U, 0U, jitterTime), +m_stopWatch(), +m_running(false), +m_buffer(1000U, name.c_str()), +m_outputCount(0U), +m_lastData(NULL), +m_lastDataLength(0U) +{ + assert(blockSize > 0U); + assert(blockTime > 0U); + assert(jitterTime > 0U); + + m_lastData = new unsigned char[m_blockSize]; + + reset(); +} + +CDelayBuffer::~CDelayBuffer() +{ + delete[] m_lastData; +} + +bool CDelayBuffer::addData(const unsigned char* data, unsigned int length) +{ + assert(data != NULL); + assert(length > 0U); + assert(length == m_blockSize); + + if (m_debug) + LogDebug("%s, DelayBuffer: appending data", m_name.c_str()); + + m_buffer.addData(data, length); + + if (!m_timer.isRunning()) { + LogDebug("%s, DelayBuffer: starting the timer from append", m_name.c_str()); + m_timer.start(); + } + + return true; +} + +B_STATUS CDelayBuffer::getData(unsigned char* data, unsigned int& length) +{ + assert(data != NULL); + + if (!m_running) + return BS_NO_DATA; + + unsigned int needed = m_stopWatch.elapsed() / m_blockTime + 2U; + if (needed <= m_outputCount) + return BS_NO_DATA; + + if (!m_buffer.isEmpty()) { + if (m_debug) + LogDebug("%s, DelayBuffer: returning data, elapsed=%ums", m_name.c_str(), m_stopWatch.elapsed()); + + length = m_buffer.getData(data, m_blockSize); + + // Save this data in case no more data is available next time + ::memcpy(m_lastData, data, length); + m_lastDataLength = length; + + m_outputCount++; + + return BS_DATA; + } + + LogDebug("%s, DelayBuffer: no data available, elapsed=%ums", m_name.c_str(), m_stopWatch.elapsed()); + + // Return the last data frame if we have it + if (m_lastDataLength > 0U) { + LogDebug("%s, DelayBuffer: returning the last received frame", m_name.c_str()); + ::memcpy(data, m_lastData, m_lastDataLength); + length = m_lastDataLength; + + m_outputCount++; + + return BS_MISSING; + } + + return BS_NO_DATA; +} + +void CDelayBuffer::reset() +{ + m_buffer.clear(); + + m_lastDataLength = 0U; + + m_outputCount = 0U; + + m_timer.stop(); + + m_running = false; +} + +void CDelayBuffer::clock(unsigned int ms) +{ + m_timer.clock(ms); + if (m_timer.isRunning() && m_timer.hasExpired()) { + if (!m_running) { + m_stopWatch.start(); + m_running = true; + } + } +} diff --git a/DelayBuffer.h b/DelayBuffer.h new file mode 100644 index 0000000..d773f26 --- /dev/null +++ b/DelayBuffer.h @@ -0,0 +1,57 @@ +/* +* Copyright (C) 2018 by Jonathan Naylor G4KLX +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#if !defined(DELAYBUFFER_H) +#define DELAYBUFFER_H + +#include "RingBuffer.h" +#include "StopWatch.h" +#include "Defines.h" +#include "Timer.h" + +#include + +class CDelayBuffer { +public: + CDelayBuffer(const std::string& name, unsigned int blockSize, unsigned int blockTime, unsigned int jitterTime, bool debug); + ~CDelayBuffer(); + + bool addData(const unsigned char* data, unsigned int length); + + B_STATUS getData(unsigned char* data, unsigned int& length); + + void reset(); + + void clock(unsigned int ms); + +private: + std::string m_name; + unsigned int m_blockSize; + unsigned int m_blockTime; + bool m_debug; + CTimer m_timer; + CStopWatch m_stopWatch; + bool m_running; + CRingBuffer m_buffer; + unsigned int m_outputCount; + + unsigned char* m_lastData; + unsigned int m_lastDataLength; +}; + +#endif diff --git a/JitterBuffer.cpp b/JitterBuffer.cpp index 25522ec..3af4f48 100644 --- a/JitterBuffer.cpp +++ b/JitterBuffer.cpp @@ -162,16 +162,16 @@ bool CJitterBuffer::appendData(const unsigned char* data, unsigned int length) return true; } -JB_STATUS CJitterBuffer::getData(unsigned char* data, unsigned int& length) +B_STATUS CJitterBuffer::getData(unsigned char* data, unsigned int& length) { assert(data != NULL); if (!m_running) - return JBS_NO_DATA; + return BS_NO_DATA; unsigned int sequenceNumber = m_stopWatch.elapsed() / m_blockTime + 2U; if (m_headSequenceNumber > sequenceNumber) - return JBS_NO_DATA; + return BS_NO_DATA; unsigned int head = m_headSequenceNumber % m_blockCount; @@ -190,7 +190,7 @@ JB_STATUS CJitterBuffer::getData(unsigned char* data, unsigned int& length) m_buffer[head].m_length = 0U; - return JBS_DATA; + return BS_DATA; } m_buffer[head].m_length = 0U; @@ -203,10 +203,10 @@ JB_STATUS CJitterBuffer::getData(unsigned char* data, unsigned int& length) ::memcpy(data, m_lastData, m_lastDataLength); length = m_lastDataLength; - return JBS_MISSING; + return BS_MISSING; } - return JBS_NO_DATA; + return BS_NO_DATA; } void CJitterBuffer::reset() diff --git a/JitterBuffer.h b/JitterBuffer.h index 46575ee..9a9f1fe 100644 --- a/JitterBuffer.h +++ b/JitterBuffer.h @@ -20,16 +20,11 @@ #define JITTERBUFFER_H #include "StopWatch.h" +#include "Defines.h" #include "Timer.h" #include -enum JB_STATUS { - JBS_NO_DATA, - JBS_DATA, - JBS_MISSING -}; - class CJitterBuffer { public: CJitterBuffer(const std::string& name, unsigned int blockSize, unsigned int blockTime, unsigned int jitterTime, unsigned int topSequenceNumber, bool debug); @@ -38,7 +33,7 @@ public: bool addData(const unsigned char* data, unsigned int length, unsigned int sequenceNumber); bool appendData(const unsigned char* data, unsigned int length); - JB_STATUS getData(unsigned char* data, unsigned int& length); + B_STATUS getData(unsigned char* data, unsigned int& length); void reset(); diff --git a/MMDVMHost.vcxproj b/MMDVMHost.vcxproj index 62fd668..b5b8162 100644 --- a/MMDVMHost.vcxproj +++ b/MMDVMHost.vcxproj @@ -158,6 +158,7 @@ + @@ -232,6 +233,7 @@ + diff --git a/MMDVMHost.vcxproj.filters b/MMDVMHost.vcxproj.filters index d6ba4f3..6f28b05 100644 --- a/MMDVMHost.vcxproj.filters +++ b/MMDVMHost.vcxproj.filters @@ -230,6 +230,9 @@ Header Files + + Header Files + @@ -430,5 +433,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/Makefile b/Makefile index 1a45e69..43c1476 100644 --- a/Makefile +++ b/Makefile @@ -7,11 +7,12 @@ LIBS = -lpthread LDFLAGS = -g OBJECTS = \ - AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \ - DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ - Golay24128.o Hamming.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o P25Audio.o P25Control.o \ - P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o \ - StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o DelayBuffer.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \ + DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \ + DStarSlowData.o Golay2087.o Golay24128.o Hamming.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o \ + NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o QR1676.o RS129.o RS241213.o \ + RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o \ + YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi b/Makefile.Pi index f28cda0..22fc628 100644 --- a/Makefile.Pi +++ b/Makefile.Pi @@ -7,11 +7,12 @@ LIBS = -lwiringPi -lwiringPiDev -lpthread LDFLAGS = -g -L/usr/local/lib OBJECTS = \ - AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \ - DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ - Golay24128.o Hamming.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o P25Audio.o P25Control.o \ - P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o \ - StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o DelayBuffer.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \ + DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \ + DStarSlowData.o Golay2087.o Golay24128.o Hamming.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o \ + NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o QR1676.o RS129.o RS241213.o \ + RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o \ + YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.Adafruit b/Makefile.Pi.Adafruit index 9f69fee..390d07d 100644 --- a/Makefile.Pi.Adafruit +++ b/Makefile.Pi.Adafruit @@ -7,11 +7,12 @@ LIBS = -lwiringPi -lwiringPiDev -lpthread LDFLAGS = -g -L/usr/local/lib OBJECTS = \ - AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \ - DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ - Golay24128.o Hamming.o HD44780.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o P25Audio.o \ - P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o \ - SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o DelayBuffer.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \ + DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \ + DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o \ + Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o QR1676.o RS129.o RS241213.o \ + RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o \ + YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.HD44780 b/Makefile.Pi.HD44780 index 4548ee4..ae7266e 100644 --- a/Makefile.Pi.HD44780 +++ b/Makefile.Pi.HD44780 @@ -7,11 +7,12 @@ LIBS = -lwiringPi -lwiringPiDev -lpthread LDFLAGS = -g -L/usr/local/lib OBJECTS = \ - AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \ - DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ - Golay24128.o Hamming.o HD44780.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o P25Audio.o \ - P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o \ - SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o DelayBuffer.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \ + DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \ + DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o \ + Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o QR1676.o RS129.o RS241213.o \ + RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o \ + YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.OLED b/Makefile.Pi.OLED index 4cf1b2e..ff61b18 100644 --- a/Makefile.Pi.OLED +++ b/Makefile.Pi.OLED @@ -7,11 +7,12 @@ LIBS = -lArduiPi_OLED -li2c -lpthread LDFLAGS = -g -L/usr/local/lib OBJECTS = \ - AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \ - DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ - Golay24128.o Hamming.o JitterBuffer.o OLED.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o P25Audio.o \ - P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o \ - SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o DelayBuffer.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \ + DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \ + DStarSlowData.o Golay2087.o Golay24128.o Hamming.o JitterBuffer.o OLED.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o \ + Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o QR1676.o RS129.o RS241213.o \ + RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o \ + YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.PCF8574 b/Makefile.Pi.PCF8574 index d1fa047..5aea72c 100644 --- a/Makefile.Pi.PCF8574 +++ b/Makefile.Pi.PCF8574 @@ -7,11 +7,12 @@ LIBS = -lwiringPi -lwiringPiDev -lpthread LDFLAGS = -g -L/usr/local/lib OBJECTS = \ - AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \ - DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ - Golay24128.o Hamming.o HD44780.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o P25Audio.o \ - P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o \ - SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o DelayBuffer.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \ + DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \ + DStarSlowData.o Golay2087.o Golay24128.o Hamming.o HD44780.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o \ + Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o QR1676.o RS129.o RS241213.o \ + RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o \ + YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Solaris b/Makefile.Solaris index 9e8769f..4c47f85 100644 --- a/Makefile.Solaris +++ b/Makefile.Solaris @@ -7,11 +7,12 @@ LIBS = -lpthread -lsocket LDFLAGS = -g OBJECTS = \ - AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o DMRLookup.o DMRLC.o \ - DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ - Golay24128.o Hamming.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o NullDisplay.o P25Audio.o P25Control.o \ - P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o \ - StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o DelayBuffer.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedData.o DMRFullLC.o \ + DMRLookup.o DMRLC.o DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o \ + DStarSlowData.o Golay2087.o Golay24128.o Hamming.o JitterBuffer.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o NetworkInfo.o Nextion.o \ + NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o QR1676.o RS129.o RS241213.o \ + RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o \ + YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost From 7737659729fb091b7a3f675fb9971bbfd7867210 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 5 Feb 2018 20:42:43 +0000 Subject: [PATCH 06/10] Add code for handling NXDN data calls and remove unused YSF code. --- NXDNControl.cpp | 374 ++++++++++-------------------------------------- NXDNLayer3.cpp | 8 +- NXDNLayer3.h | 2 +- 3 files changed, 77 insertions(+), 307 deletions(-) diff --git a/NXDNControl.cpp b/NXDNControl.cpp index 0ab043c..a612475 100644 --- a/NXDNControl.cpp +++ b/NXDNControl.cpp @@ -200,15 +200,16 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne m_rfLayer3.reset(); return false; } - } else { - bool hasInfo = layer3.getHasInfo(); - if (m_rfState == RS_RF_LISTENING && m_selfOnly && hasInfo) { + } else if (type == NXDN_MESSAGE_TYPE_VCALL) { + if (m_rfState == RS_RF_LISTENING && m_selfOnly) { unsigned short srcId = layer3.getSourceUnitId(); if (srcId != m_id) { m_rfState = RS_RF_REJECTED; return false; } } + } else { + return false; } data[0U] = type == NXDN_MESSAGE_TYPE_TX_REL ? TAG_EOT : TAG_DATA; @@ -299,7 +300,7 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne CNXDNLayer3 layer3; layer3.decode(buffer, NXDN_FACCH1_LENGTH_BITS); - hasInfo = layer3.getHasInfo(); + hasInfo = layer3.getMessageType() == NXDN_MESSAGE_TYPE_VCALL; if (!hasInfo) return false; @@ -335,8 +336,8 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne if (m_rfMask != 0x0FU) return false; - hasInfo = m_rfLayer3.getHasInfo(); - if (!hasInfo) + unsigned char type = m_rfLayer3.getMessageType(); + if (type != NXDN_MESSAGE_TYPE_VCALL) return false; } @@ -531,199 +532,92 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data) { CNXDNUDCH udch; bool valid = udch.decode(data + 2U); + if (m_rfState == RS_RF_LISTENING && !valid) + return false; + if (valid) { unsigned char ran = udch.getRAN(); if (ran != m_ran && ran != 0U) return false; + } - data[0U] = TAG_DATA; - data[1U] = 0x00U; + // The layer3 data will only be correct if valid is true + unsigned char buffer[23U]; + udch.getData(buffer); - CSync::addNXDNSync(data + 2U); + CNXDNLayer3 layer3; + layer3.decode(buffer, 184U); - CNXDNLICH lich; - lich.setRFCT(NXDN_LICH_RFCT_RDCH); - lich.setFCT(NXDN_LICH_USC_UDCH); - lich.setOption(option); - lich.setDirection(m_remoteGateway ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND); - lich.encode(data + 2U); + if (m_rfState == RS_RF_LISTENING) { + unsigned char type = layer3.getMessageType(); + if (type != NXDN_MESSAGE_TYPE_DCALL_HDR) + return false; + unsigned short srcId = layer3.getSourceUnitId(); + unsigned short dstId = layer3.getDestinationGroupId(); + bool grp = layer3.getIsGroup(); + + if (m_selfOnly) { + if (srcId != m_id) + return false; + } + + unsigned char frames = layer3.getDataBlocks(); + + std::string source = m_lookup->find(srcId); + + m_display->writeNXDN(source.c_str(), grp, dstId, "R"); + m_display->writeNXDNRSSI(m_rssi); + + LogMessage("NXDN, received RF data header from %s to %s%u, %u blocks", source.c_str(), grp ? "TG " : "", dstId, frames); + + m_rfState = RS_RF_DATA; + +#if defined(DUMP_NXDN) + openFile(); +#endif + } + + if (m_rfState != RS_RF_DATA) + return false; + + data[0U] = TAG_DATA; + data[1U] = 0x00U; + + CSync::addNXDNSync(data + 2U); + + CNXDNLICH lich; + lich.setRFCT(NXDN_LICH_RFCT_RDCH); + lich.setFCT(NXDN_LICH_USC_UDCH); + lich.setOption(option); + lich.setDirection(m_remoteGateway ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND); + lich.encode(data + 2U); + + if (valid) { udch.setRAN(m_ran); udch.encode(data + 2U); - - scrambler(data + 2U); - - writeQueueNet(data); - - if (m_duplex) - writeQueueRF(data); -#if defined(DUMP_NXDN) - writeFile(data + 2U); -#endif - return true; } -#ifdef notdef - unsigned char fi = m_lastFICH.getFI(); - if (valid && fi == YSF_FI_HEADER) { - if (m_rfState == RS_RF_LISTENING) { - valid = m_rfPayload.processHeaderData(data + 2U); - if (!valid) - return false; + scrambler(data + 2U); - m_rfSource = m_rfPayload.getSource(); + writeQueueNet(data); - if (m_selfOnly) { - bool ret = checkCallsign(m_rfSource); - if (!ret) { - LogMessage("NXDN, invalid access attempt from %10.10s", m_rfSource); - m_rfState = RS_RF_REJECTED; - return false; - } - } - - unsigned char cm = m_lastFICH.getCM(); - if (cm == YSF_CM_GROUP1 || cm == YSF_CM_GROUP2) - m_rfDest = (unsigned char*)"ALL "; - else - m_rfDest = m_rfPayload.getDest(); - - m_rfFrames = 0U; - m_rfState = RS_RF_DATA; - - m_minRSSI = m_rssi; - m_maxRSSI = m_rssi; - m_aveRSSI = m_rssi; - m_rssiCount = 1U; -#if defined(DUMP_NXDN) - openFile(); -#endif - - m_display->writeFusion((char*)m_rfSource, (char*)m_rfDest, "R", " "); - LogMessage("NXDN, received RF header from %10.10s to %10.10s", m_rfSource, m_rfDest); - - CSync::addNXDNSync(data + 2U); - - CYSFFICH fich = m_lastFICH; - - // Remove any DSQ information - fich.setSQL(false); - fich.setSQ(0U); - fich.encode(data + 2U); - - data[0U] = TAG_DATA; - data[1U] = 0x00U; - - writeNetwork(data, m_rfFrames); + if (m_duplex) + writeQueueRF(data); #if defined(DUMP_NXDN) - writeFile(data + 2U); + writeFile(data + 2U); #endif - if (m_duplex) { - fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY); - fich.encode(data + 2U); - writeQueueRF(data); - } - - m_rfFrames++; - - m_display->writeFusionRSSI(m_rssi); - - return true; - } - } else if (valid && fi == YSF_FI_TERMINATOR) { - if (m_rfState == RS_RF_REJECTED) { - m_rfPayload.reset(); - m_rfSource = NULL; - m_rfDest = NULL; - m_rfState = RS_RF_LISTENING; - } else if (m_rfState == RS_RF_DATA) { - m_rfPayload.processHeaderData(data + 2U); - - CSync::addNXDNSync(data + 2U); - - CYSFFICH fich = m_lastFICH; - - // Remove any DSQ information - fich.setSQL(false); - fich.setSQ(0U); - fich.encode(data + 2U); - - data[0U] = TAG_EOT; - data[1U] = 0x00U; - - writeNetwork(data, m_rfFrames); - -#if defined(DUMP_NXDN) - writeFile(data + 2U); -#endif - - if (m_duplex) { - fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY); - fich.encode(data + 2U); - writeQueueRF(data); - } - - m_rfFrames++; - - if (m_rssi != 0U) - LogMessage("NXDN, received RF end of transmission, %.1f seconds, RSSI: -%u/-%u/-%u dBm", float(m_rfFrames) / 10.0F, m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount); - else - LogMessage("NXDN, received RF end of transmission, %.1f seconds", float(m_rfFrames) / 10.0F); - + if (valid) { + unsigned char type = layer3.getMessageType(); + if (type == NXDN_MESSAGE_TYPE_TX_REL) { + LogMessage("NXDN, ended RF data transmission"); writeEndRF(); } - } else { - if (m_rfState == RS_RF_DATA) { - // If valid is false, update the m_lastFICH for this transmission - if (!valid) { - unsigned char ft = m_lastFICH.getFT(); - unsigned char fn = m_lastFICH.getFN() + 1U; - - if (fn > ft) - fn = 0U; - - m_lastFICH.setFN(fn); - } - - CSync::addNXDNSync(data + 2U); - - unsigned char fn = m_lastFICH.getFN(); - - m_rfPayload.processDataFRModeData(data + 2U, fn); - - CYSFFICH fich = m_lastFICH; - - // Remove any DSQ information - fich.setSQL(false); - fich.setSQ(0U); - fich.encode(data + 2U); - - data[0U] = TAG_DATA; - data[1U] = 0x00U; - - writeNetwork(data, m_rfFrames); - - if (m_duplex) { - fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY); - fich.encode(data + 2U); - writeQueueRF(data); - } - -#if defined(DUMP_NXDN) - writeFile(data + 2U); -#endif - - m_rfFrames++; - - m_display->writeFusionRSSI(m_rssi); - - return true; - } } -#endif - return false; + + return true; } unsigned int CNXDNControl::readModem(unsigned char* data) @@ -776,10 +670,9 @@ void CNXDNControl::writeEndNet() m_network->reset(); } -#ifdef notdef - void CNXDNControl::writeNetwork() { +#ifdef notdef unsigned char data[200U]; unsigned int length = m_network->read(data); if (length == 0U) @@ -789,132 +682,13 @@ void CNXDNControl::writeNetwork() return; m_networkWatchdog.start(); - - unsigned char n = (data[5U] & 0xFEU) >> 1; - bool end = (data[5U] & 0x01U) == 0x01U; - - if (!m_netTimeoutTimer.isRunning()) { - if (end) - return; - - m_display->writeFusion((char*)m_netSource, (char*)m_netDest, "N", (char*)(data + 4U)); - LogMessage("NXDN, received network data from %10.10s to %10.10s at %10.10s", m_netSource, m_netDest, data + 4U); - - m_netTimeoutTimer.start(); - m_packetTimer.start(); - m_elapsed.start(); - m_netState = RS_NET_AUDIO; - m_netFrames = 0U; - m_netLost = 0U; - m_netErrs = 0U; - m_netBits = 1U; - m_netN = 0U; - } else { - // Check for duplicate frames, if we can - if (m_netN == n) - return; - - bool changed = false; - - if (::memcmp(data + 14U, " ", YSF_CALLSIGN_LENGTH) != 0 && ::memcmp(m_netSource, "??????????", YSF_CALLSIGN_LENGTH) == 0) { - ::memcpy(m_netSource, data + 14U, YSF_CALLSIGN_LENGTH); - changed = true; - } - - if (::memcmp(data + 24U, " ", YSF_CALLSIGN_LENGTH) != 0 && ::memcmp(m_netDest, "??????????", YSF_CALLSIGN_LENGTH) == 0) { - ::memcpy(m_netDest, data + 24U, YSF_CALLSIGN_LENGTH); - changed = true; - } - - if (changed) { - m_display->writeFusion((char*)m_netSource, (char*)m_netDest, "N", (char*)(data + 4U)); - LogMessage("YSF, received network data from %10.10s to %10.10s at %10.10s", m_netSource, m_netDest, data + 4U); - } - } - - data[33U] = end ? TAG_EOT : TAG_DATA; - data[34U] = 0x00U; - - CYSFFICH fich; - bool valid = fich.decode(data + 35U); - if (valid) { - unsigned char dt = fich.getDT(); - unsigned char fn = fich.getFN(); - unsigned char ft = fich.getFT(); - unsigned char fi = fich.getFI(); - - fich.setVoIP(true); - fich.setMR(m_remoteGateway ? YSF_MR_NOT_BUSY : YSF_MR_BUSY); - fich.encode(data + 35U); - - // Set the downlink callsign - switch (fi) { - case YSF_FI_HEADER: - case YSF_FI_TERMINATOR: - m_netPayload.processHeaderData(data + 35U); - break; - - case YSF_FI_COMMUNICATIONS: - switch (dt) { - case YSF_DT_VD_MODE1: { - m_netPayload.processVDMode1Data(data + 35U, fn, gateway); - unsigned int errors = m_netPayload.processVDMode1Audio(data + 35U); - m_netErrs += errors; - m_netBits += 235U; - } - break; - - case YSF_DT_VD_MODE2: { - m_netPayload.processVDMode2Data(data + 35U, fn, gateway); - unsigned int errors = m_netPayload.processVDMode2Audio(data + 35U); - m_netErrs += errors; - m_netBits += 135U; - } - break; - - case YSF_DT_DATA_FR_MODE: - m_netPayload.processDataFRModeData(data + 35U, fn, gateway); - break; - - case YSF_DT_VOICE_FR_MODE: - if (fn != 0U || ft != 1U) { - // The first packet after the header is odd, don't try and regenerate it - unsigned int errors = m_netPayload.processVoiceFRModeAudio(data + 35U); - m_netErrs += errors; - m_netBits += 720U; - } - break; - - default: - break; - } - break; - - default: - break; - } - } - - writeQueueNet(data + 33U); - - m_packetTimer.start(); - m_netFrames++; - m_netN = n; - - if (end) { - LogMessage("NXDN, received network end of transmission, %.1f seconds, %u%% packet loss, BER: %.1f%%", float(m_netFrames) / 10.0F, (m_netLost * 100U) / m_netFrames, float(m_netErrs * 100U) / float(m_netBits)); - writeEndNet(); - } -} - #endif +} void CNXDNControl::clock(unsigned int ms) { -#ifdef notdef if (m_network != NULL) writeNetwork(); -#endif m_rfTimeoutTimer.clock(ms); m_netTimeoutTimer.clock(ms); diff --git a/NXDNLayer3.cpp b/NXDNLayer3.cpp index cf32008..f1b98f3 100644 --- a/NXDNLayer3.cpp +++ b/NXDNLayer3.cpp @@ -92,13 +92,9 @@ unsigned char CNXDNLayer3::getCallOptions() const return m_data[2U] & 0x1FU; } -bool CNXDNLayer3::getHasInfo() const +unsigned char CNXDNLayer3::getDataBlocks() const { - unsigned char type = getMessageType(); - - return type != NXDN_MESSAGE_TYPE_IDLE && - type != NXDN_MESSAGE_TYPE_VCALL_IV && - type != NXDN_MESSAGE_TYPE_SDCALL_IV; + return m_data[8U] & 0x0FU; } void CNXDNLayer3::getData(unsigned char* data) const diff --git a/NXDNLayer3.h b/NXDNLayer3.h index 827deee..d39a41b 100644 --- a/NXDNLayer3.h +++ b/NXDNLayer3.h @@ -34,7 +34,7 @@ public: unsigned short getDestinationGroupId() const; bool getIsGroup() const; unsigned char getCallOptions() const; - bool getHasInfo() const; + unsigned char getDataBlocks() const; void getData(unsigned char* data) const; From bdc35d02bd5cf8f51fef4e13438459333aea8b35 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 5 Feb 2018 21:07:06 +0000 Subject: [PATCH 07/10] Regenerate more NXDN voice data elements. --- NXDNControl.cpp | 44 ++++++++++++++++++++++++++++++++------------ NXDNControl.h | 2 +- NXDNLayer3.cpp | 4 ++-- NXDNLayer3.h | 2 +- 4 files changed, 36 insertions(+), 16 deletions(-) diff --git a/NXDNControl.cpp b/NXDNControl.cpp index a612475..74627fd 100644 --- a/NXDNControl.cpp +++ b/NXDNControl.cpp @@ -158,16 +158,16 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len) if (usc == NXDN_LICH_USC_UDCH) ret = processData(option, data); else - ret = processVoice(usc, option, data); + ret = processVoice(valid, usc, option, data); return ret; } -bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigned char *data) +bool CNXDNControl::processVoice(bool validLICH, unsigned char usc, unsigned char option, unsigned char *data) { CNXDNSACCH sacch; - bool valid = sacch.decode(data + 2U); - if (valid) { + bool validSACCH = sacch.decode(data + 2U); + if (validSACCH) { unsigned char ran = sacch.getRAN(); if (ran != m_ran && ran != 0U) return false; @@ -175,7 +175,21 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne return false; } - // XXX Reconstruct invalid LICH + // Reconstruct invalid LICH + if (!validLICH) { + if (usc == NXDN_LICH_USC_SACCH_NS) { + option = NXDN_LICH_STEAL_NONE; + usc = NXDN_LICH_USC_SACCH_SS; + } else { + if (option == NXDN_LICH_STEAL_FACCH) + option = NXDN_LICH_STEAL_NONE; + else if (option == NXDN_LICH_STEAL_NONE) + option = NXDN_LICH_STEAL_FACCH; + } + + m_rfLastLICH.setFCT(usc); + m_rfLastLICH.setOption(option); + } 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. @@ -425,10 +439,16 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne lich.setDirection(m_remoteGateway ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND); lich.encode(data + 2U); - // XXX Regenerate SACCH here + // Regenerate SACCH if it's valid + CNXDNSACCH sacch; + bool validSACCH = sacch.decode(data + 2U); + if (validSACCH) { + sacch.setRAN(m_ran); + sacch.encode(data + 2U); + } // Regenerate the audio and interpret the FACCH1 data - unsigned char voiceMode = m_rfLayer3.getCallOptions() & 0x07U; + unsigned char voiceMode = m_rfLayer3.getVoiceMode(); if (option == NXDN_LICH_STEAL_NONE) { CAMBEFEC ambe; @@ -531,11 +551,11 @@ bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigne bool CNXDNControl::processData(unsigned char option, unsigned char *data) { CNXDNUDCH udch; - bool valid = udch.decode(data + 2U); - if (m_rfState == RS_RF_LISTENING && !valid) + bool validUDCH = udch.decode(data + 2U); + if (m_rfState == RS_RF_LISTENING && !validUDCH) return false; - if (valid) { + if (validUDCH) { unsigned char ran = udch.getRAN(); if (ran != m_ran && ran != 0U) return false; @@ -593,7 +613,7 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data) lich.setDirection(m_remoteGateway ? NXDN_LICH_DIRECTION_INBOUND : NXDN_LICH_DIRECTION_OUTBOUND); lich.encode(data + 2U); - if (valid) { + if (validUDCH) { udch.setRAN(m_ran); udch.encode(data + 2U); } @@ -609,7 +629,7 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data) writeFile(data + 2U); #endif - if (valid) { + if (validUDCH) { unsigned char type = layer3.getMessageType(); if (type == NXDN_MESSAGE_TYPE_TX_REL) { LogMessage("NXDN, ended RF data transmission"); diff --git a/NXDNControl.h b/NXDNControl.h index 5f000e7..8dfaedd 100644 --- a/NXDNControl.h +++ b/NXDNControl.h @@ -81,7 +81,7 @@ private: unsigned int m_rssiCount; FILE* m_fp; - bool processVoice(unsigned char usc, unsigned char option, unsigned char *data); + bool processVoice(bool validLICH, unsigned char usc, unsigned char option, unsigned char *data); bool processData(unsigned char option, unsigned char *data); void writeQueueRF(const unsigned char* data); diff --git a/NXDNLayer3.cpp b/NXDNLayer3.cpp index f1b98f3..72b938a 100644 --- a/NXDNLayer3.cpp +++ b/NXDNLayer3.cpp @@ -87,9 +87,9 @@ bool CNXDNLayer3::getIsGroup() const return (m_data[2U] & 0x80U) != 0x80U; } -unsigned char CNXDNLayer3::getCallOptions() const +unsigned char CNXDNLayer3::getVoiceMode() const { - return m_data[2U] & 0x1FU; + return m_data[2U] & 0x07U; } unsigned char CNXDNLayer3::getDataBlocks() const diff --git a/NXDNLayer3.h b/NXDNLayer3.h index d39a41b..b0749a2 100644 --- a/NXDNLayer3.h +++ b/NXDNLayer3.h @@ -33,7 +33,7 @@ public: unsigned short getSourceUnitId() const; unsigned short getDestinationGroupId() const; bool getIsGroup() const; - unsigned char getCallOptions() const; + unsigned char getVoiceMode() const; unsigned char getDataBlocks() const; void getData(unsigned char* data) const; From d2504172f960e30620b0b232181b08021f825700 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 5 Feb 2018 21:21:08 +0000 Subject: [PATCH 08/10] Small optimisation of the CRC calculations. --- NXDNCRC.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/NXDNCRC.cpp b/NXDNCRC.cpp index 29da35c..7ffc456 100644 --- a/NXDNCRC.cpp +++ b/NXDNCRC.cpp @@ -142,13 +142,12 @@ uint8_t CNXDNCRC::createCRC6(const unsigned char* in, unsigned int length) bool bit2 = (crc & 0x20U) == 0x20U; crc <<= 1; - crc &= 0x3EU; if (bit1 ^ bit2) crc ^= 0x27U; } - return crc; + return crc & 0x3FU; } uint16_t CNXDNCRC::createCRC12(const unsigned char* in, unsigned int length) @@ -160,7 +159,6 @@ uint16_t CNXDNCRC::createCRC12(const unsigned char* in, unsigned int length) bool bit2 = (crc & 0x0800U) == 0x0800U; crc <<= 1; - crc &= 0x0FFEU; if (bit1 ^ bit2) crc ^= 0x080FU; @@ -178,7 +176,6 @@ uint16_t CNXDNCRC::createCRC15(const unsigned char* in, unsigned int length) bool bit2 = (crc & 0x4000U) == 0x4000U; crc <<= 1; - crc &= 0x7FFEU; if (bit1 ^ bit2) crc ^= 0x4CC5U; From a5c61daa736f9f6032478676c22b795d6233acce Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 5 Feb 2018 21:33:36 +0000 Subject: [PATCH 09/10] Fix the data tag for the end of NXDN data transmissions. --- NXDNControl.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/NXDNControl.cpp b/NXDNControl.cpp index 74627fd..c1198a4 100644 --- a/NXDNControl.cpp +++ b/NXDNControl.cpp @@ -601,9 +601,6 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data) if (m_rfState != RS_RF_DATA) return false; - data[0U] = TAG_DATA; - data[1U] = 0x00U; - CSync::addNXDNSync(data + 2U); CNXDNLICH lich; @@ -614,8 +611,14 @@ bool CNXDNControl::processData(unsigned char option, unsigned char *data) lich.encode(data + 2U); if (validUDCH) { + unsigned char type = layer3.getMessageType(); + data[0U] = type == NXDN_MESSAGE_TYPE_TX_REL ? TAG_EOT : TAG_DATA; + udch.setRAN(m_ran); udch.encode(data + 2U); + } else { + data[0U] = TAG_DATA; + data[1U] = 0x00U; } scrambler(data + 2U); From ff71383ac78ba0905ff7fb1391b7c0471d40676b Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 5 Feb 2018 21:39:50 +0000 Subject: [PATCH 10/10] Not happy about LICH reconstruction, remove it. --- NXDNControl.cpp | 24 ++++-------------------- NXDNControl.h | 2 +- 2 files changed, 5 insertions(+), 21 deletions(-) diff --git a/NXDNControl.cpp b/NXDNControl.cpp index c1198a4..4eeea24 100644 --- a/NXDNControl.cpp +++ b/NXDNControl.cpp @@ -158,16 +158,16 @@ bool CNXDNControl::writeModem(unsigned char *data, unsigned int len) if (usc == NXDN_LICH_USC_UDCH) ret = processData(option, data); else - ret = processVoice(valid, usc, option, data); + ret = processVoice(usc, option, data); return ret; } -bool CNXDNControl::processVoice(bool validLICH, unsigned char usc, unsigned char option, unsigned char *data) +bool CNXDNControl::processVoice(unsigned char usc, unsigned char option, unsigned char *data) { CNXDNSACCH sacch; - bool validSACCH = sacch.decode(data + 2U); - if (validSACCH) { + bool valid = sacch.decode(data + 2U); + if (valid) { unsigned char ran = sacch.getRAN(); if (ran != m_ran && ran != 0U) return false; @@ -175,22 +175,6 @@ bool CNXDNControl::processVoice(bool validLICH, unsigned char usc, unsigned char return false; } - // Reconstruct invalid LICH - if (!validLICH) { - if (usc == NXDN_LICH_USC_SACCH_NS) { - option = NXDN_LICH_STEAL_NONE; - usc = NXDN_LICH_USC_SACCH_SS; - } else { - if (option == NXDN_LICH_STEAL_FACCH) - option = NXDN_LICH_STEAL_NONE; - else if (option == NXDN_LICH_STEAL_NONE) - option = NXDN_LICH_STEAL_FACCH; - } - - m_rfLastLICH.setFCT(usc); - m_rfLastLICH.setOption(option); - } - 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 facch; diff --git a/NXDNControl.h b/NXDNControl.h index 8dfaedd..5f000e7 100644 --- a/NXDNControl.h +++ b/NXDNControl.h @@ -81,7 +81,7 @@ private: unsigned int m_rssiCount; FILE* m_fp; - bool processVoice(bool validLICH, unsigned char usc, unsigned char option, unsigned char *data); + bool processVoice(unsigned char usc, unsigned char option, unsigned char *data); bool processData(unsigned char option, unsigned char *data); void writeQueueRF(const unsigned char* data);