diff --git a/Defines.h b/Defines.h index 3d2240b3..a8484764 100644 --- a/Defines.h +++ b/Defines.h @@ -118,6 +118,8 @@ typedef unsigned long long ulong64_t; const uint32_t TRAFFIC_DEFAULT_PORT = 62031; const uint32_t RCON_DEFAULT_PORT = 9990; +const uint32_t QUEUE_RESIZE_SIZE = 500; + const uint8_t BIT_MASK_TABLE[] = { 0x80U, 0x40U, 0x20U, 0x10U, 0x08U, 0x04U, 0x02U, 0x01U }; enum HOST_STATE { diff --git a/config.yml b/config.yml index 69be2ef5..66bf89b1 100644 --- a/config.yml +++ b/config.yml @@ -109,6 +109,7 @@ system: # dmrTxLevel: 50 # p25TxLevel: 50 rssiMappingFile: RSSI.dat + packetPlayoutTime: 10 disableOFlowReset: false trace: false debug: false diff --git a/dmr/Slot.cpp b/dmr/Slot.cpp index 0506a793..d108562a 100644 --- a/dmr/Slot.cpp +++ b/dmr/Slot.cpp @@ -449,7 +449,7 @@ void Slot::writeQueueRF(const uint8_t *data) uint32_t space = m_queue.freeSpace(); if (space < (len + 1U)) { uint32_t queueLen = m_queue.length(); - m_queue.resize(queueLen + 2500); + m_queue.resize(queueLen + QUEUE_RESIZE_SIZE); LogError(LOG_DMR, "Slot %u, overflow in the DMR slot RF queue; queue resized was %u is %u", m_slotNo, queueLen, m_queue.length()); return; diff --git a/host/Host.cpp b/host/Host.cpp index ebc1007a..648e75a2 100644 --- a/host/Host.cpp +++ b/host/Host.cpp @@ -1209,10 +1209,15 @@ bool Host::createModem() if (!modemConf["txLevel"].isNone()) { cwIdTXLevel = dmrTXLevel = p25TXLevel = modemConf["txLevel"].as(50.0F); } + uint8_t packetPlayoutTime = (uint8_t)modemConf["packetPlayoutTime"].as(10U); bool disableOFlowReset = modemConf["disableOFlowReset"].as(false); bool trace = modemConf["trace"].as(false); bool debug = modemConf["debug"].as(false); + // make sure playout time is always greater than 1ms + if (packetPlayoutTime < 1U) + packetPlayoutTime = 1U; + LogInfo("Modem Parameters"); LogInfo(" Port: %s", port.c_str()); LogInfo(" RX Invert: %s", rxInvert ? "yes" : "no"); @@ -1228,13 +1233,14 @@ bool Host::createModem() LogInfo(" CW Id TX Level: %.1f%%", cwIdTXLevel); LogInfo(" DMR TX Level: %.1f%%", dmrTXLevel); LogInfo(" P25 TX Level: %.1f%%", p25TXLevel); + LogInfo(" Packet Playout Time: %u ms", packetPlayoutTime); LogInfo(" Disable Overflow Reset: %s", disableOFlowReset ? "yes" : "no"); if (debug) { LogInfo(" Debug: yes"); } - m_modem = Modem::createModem(port, m_duplex, rxInvert, txInvert, pttInvert, dcBlocker, cosLockout, fdmaPreamble, dmrRxDelay, disableOFlowReset, trace, debug); + m_modem = Modem::createModem(port, m_duplex, rxInvert, txInvert, pttInvert, dcBlocker, cosLockout, fdmaPreamble, dmrRxDelay, packetPlayoutTime, disableOFlowReset, trace, debug); m_modem->setModeParams(m_dmrEnabled, m_p25Enabled); m_modem->setLevels(rxLevel, cwIdTXLevel, dmrTXLevel, p25TXLevel); m_modem->setDCOffsetParams(txDCOffset, rxDCOffset); diff --git a/modem/Modem.cpp b/modem/Modem.cpp index e634e9bb..77632e70 100644 --- a/modem/Modem.cpp +++ b/modem/Modem.cpp @@ -67,10 +67,11 @@ using namespace modem; /// Count of FDMA preambles to transmit before data. (P25/DMR DMO) /// Compensate for delay in receiver audio chain in ms. Usually DSP based. /// Flag indicating whether the ADC/DAC overflow reset logic is disabled. +/// Length of time in MS between packets to send to modem. /// Flag indicating whether modem DSP trace is enabled. /// Flag indicating whether modem DSP debug is enabled. Modem::Modem(const std::string& port, bool duplex, bool rxInvert, bool txInvert, bool pttInvert, bool dcBlocker, - bool cosLockout, uint8_t fdmaPreamble, uint8_t dmrRxDelay, bool disableOFlowReset, bool trace, bool debug) : + bool cosLockout, uint8_t fdmaPreamble, uint8_t dmrRxDelay, uint8_t packetPlayoutTime, bool disableOFlowReset, bool trace, bool debug) : m_port(port), m_dmrColorCode(0U), m_duplex(duplex), @@ -106,7 +107,7 @@ Modem::Modem(const std::string& port, bool duplex, bool rxInvert, bool txInvert, m_txP25Data(1000U, "Modem TX P25"), m_statusTimer(1000U, 0U, 250U), m_inactivityTimer(1000U, 4U), - m_playoutTimer(1000U, 0U, 10U), + m_playoutTimer(1000U, 0U, packetPlayoutTime), m_dmrSpace1(0U), m_dmrSpace2(0U), m_p25Space(0U), @@ -1030,17 +1031,18 @@ bool Modem::sendCWId(const std::string& callsign) /// Flag indicating whether the COS signal should be used to lockout the modem. /// Count of FDMA preambles to transmit before data. (P25/DMR DMO) /// Compensate for delay in receiver audio chain in ms. Usually DSP based. +/// Length of time in MS between packets to send to modem. /// Flag indicating whether the ADC/DAC overflow reset logic is disabled. /// Flag indicating whether modem DSP trace is enabled. /// Flag indicating whether modem DSP debug is enabled. Modem* Modem::createModem(const std::string& port, bool duplex, bool rxInvert, bool txInvert, bool pttInvert, bool dcBlocker, - bool cosLockout, uint8_t fdmaPreamble, uint8_t dmrRxDelay, bool disableOFlowReset, bool trace, bool debug) + bool cosLockout, uint8_t fdmaPreamble, uint8_t dmrRxDelay, uint8_t packetPlayoutTime, bool disableOFlowReset, bool trace, bool debug) { if (port == NULL_MODEM) { - return new NullModem(port, duplex, rxInvert, txInvert, pttInvert, dcBlocker, cosLockout, fdmaPreamble, dmrRxDelay, disableOFlowReset, trace, debug); + return new NullModem(port, duplex, rxInvert, txInvert, pttInvert, dcBlocker, cosLockout, fdmaPreamble, dmrRxDelay, packetPlayoutTime, disableOFlowReset, trace, debug); } else { - return new Modem(port, duplex, rxInvert, txInvert, pttInvert, dcBlocker, cosLockout, fdmaPreamble, dmrRxDelay, disableOFlowReset, trace, debug); + return new Modem(port, duplex, rxInvert, txInvert, pttInvert, dcBlocker, cosLockout, fdmaPreamble, dmrRxDelay, packetPlayoutTime, disableOFlowReset, trace, debug); } } diff --git a/modem/Modem.h b/modem/Modem.h index a15f9230..6317a750 100644 --- a/modem/Modem.h +++ b/modem/Modem.h @@ -163,7 +163,7 @@ namespace modem public: /// Initializes a new instance of the Modem class. Modem(const std::string& port, bool duplex, bool rxInvert, bool txInvert, bool pttInvert, bool dcBlocker, - bool cosLockout, uint8_t fdmaPreamble, uint8_t dmrRxDelay, bool disableOFlowReset, bool trace, bool debug); + bool cosLockout, uint8_t fdmaPreamble, uint8_t dmrRxDelay, uint8_t packetPlayoutTime, bool disableOFlowReset, bool trace, bool debug); /// Finalizes a instance of the Modem class. virtual ~Modem(); @@ -247,7 +247,7 @@ namespace modem /// Helper to create an instance of the Modem class. static Modem* createModem(const std::string& port, bool duplex, bool rxInvert, bool txInvert, bool pttInvert, bool dcBlocker, - bool cosLockout, uint8_t fdmaPreamble, uint8_t dmrRxDelay, bool disableOFlowReset, bool trace, bool debug); + bool cosLockout, uint8_t fdmaPreamble, uint8_t dmrRxDelay, uint8_t packetPlayoutTime, bool disableOFlowReset, bool trace, bool debug); private: std::string m_port; diff --git a/modem/NullModem.cpp b/modem/NullModem.cpp index 000a2723..4d5efe63 100644 --- a/modem/NullModem.cpp +++ b/modem/NullModem.cpp @@ -49,12 +49,13 @@ using namespace modem; /// Flag indicating whether the COS signal should be used to lockout the modem. /// Count of FDMA preambles to transmit before data. (P25/DMR DMO) /// Compensate for delay in receiver audio chain in ms. Usually DSP based. +/// Length of time in MS between packets to send to modem. /// Flag indicating whether the ADC/DAC overflow reset logic is disabled. /// Flag indicating whether modem DSP trace is enabled. /// Flag indicating whether modem DSP debug is enabled. NullModem::NullModem(const std::string& port, bool duplex, bool rxInvert, bool txInvert, bool pttInvert, bool dcBlocker, - bool cosLockout, uint8_t fdmaPreamble, uint8_t dmrRxDelay, bool disableOFlowReset, bool trace, bool debug) : - Modem(port, duplex, rxInvert, txInvert, pttInvert, dcBlocker, cosLockout, fdmaPreamble, dmrRxDelay, disableOFlowReset, trace, debug) + bool cosLockout, uint8_t fdmaPreamble, uint8_t dmrRxDelay, uint8_t packetPlayoutTime, bool disableOFlowReset, bool trace, bool debug) : + Modem(port, duplex, rxInvert, txInvert, pttInvert, dcBlocker, cosLockout, fdmaPreamble, dmrRxDelay, packetPlayoutTime, disableOFlowReset, trace, debug) { /* stub */ } diff --git a/modem/NullModem.h b/modem/NullModem.h index 405c8026..960b187b 100644 --- a/modem/NullModem.h +++ b/modem/NullModem.h @@ -45,7 +45,7 @@ namespace modem public: /// Initializes a new instance of the NullModem class. NullModem(const std::string& port, bool duplex, bool rxInvert, bool txInvert, bool pttInvert, bool dcBlocker, - bool cosLockout, uint8_t fdmaPreamble, uint8_t dmrRxDelay, bool disableOFlowReset, bool trace, bool debug); + bool cosLockout, uint8_t fdmaPreamble, uint8_t dmrRxDelay, uint8_t packetPlayoutTime, bool disableOFlowReset, bool trace, bool debug); /// Finalizes a instance of the NullModem class. ~NullModem(); diff --git a/p25/Control.cpp b/p25/Control.cpp index 74dae48f..0d5b7079 100644 --- a/p25/Control.cpp +++ b/p25/Control.cpp @@ -330,16 +330,16 @@ bool Control::processFrame(uint8_t* data, uint32_t len) } if (!sync && m_rfState == RS_RF_LISTENING) { - if (m_verbose) { - uint8_t sync[P25_SYNC_LENGTH_BYTES]; - ::memcpy(sync, data + 2U, P25_SYNC_LENGTH_BYTES); + uint8_t sync[P25_SYNC_LENGTH_BYTES]; + ::memcpy(sync, data + 2U, P25_SYNC_LENGTH_BYTES); - uint8_t errs = 0U; - for (uint8_t i = 0U; i < P25_SYNC_LENGTH_BYTES; i++) - errs += Utils::countBits8(sync[i] ^ P25_SYNC_BYTES[i]); + uint8_t errs = 0U; + for (uint8_t i = 0U; i < P25_SYNC_LENGTH_BYTES; i++) + errs += Utils::countBits8(sync[i] ^ P25_SYNC_BYTES[i]); + + LogWarning(LOG_RF, "P25, possible sync word rejected, errs = %u, sync word = %02X %02X %02X %02X %02X %02X", errs, + sync[0U], sync[1U], sync[2U], sync[3U], sync[4U], sync[5U]); - LogDebug(LOG_RF, "P25, possible sync word rejected, errs = %u", errs); - } return false; } @@ -626,7 +626,7 @@ void Control::writeQueueRF(const uint8_t* data, uint32_t length) uint32_t space = m_queue.freeSpace(); if (space < (length + 1U)) { uint32_t queueLen = m_queue.length(); - m_queue.resize(queueLen + 2500); + m_queue.resize(queueLen + QUEUE_RESIZE_SIZE); LogError(LOG_P25, "overflow in the P25 RF queue; queue resized was %u is %u", queueLen, m_queue.length()); return; diff --git a/p25/VoicePacket.cpp b/p25/VoicePacket.cpp index 50978022..60470fe1 100644 --- a/p25/VoicePacket.cpp +++ b/p25/VoicePacket.cpp @@ -115,13 +115,17 @@ bool VoicePacket::process(uint8_t* data, uint32_t len) m_p25->m_rfTGHang.start(); } + if (duid == P25_DUID_HDU && m_lastDUID == P25_DUID_HDU) { + duid = P25_DUID_LDU1; + } + // handle individual DUIDs if (duid == P25_DUID_HDU) { m_p25->m_trunk->resetStatusCommand(); m_lastDUID = P25_DUID_HDU; - if (m_p25->m_rfState == RS_RF_LISTENING) { + if (m_p25->m_rfState == RS_RF_LISTENING && m_p25->m_ccRunning) { m_p25->m_modem->clearP25Data(); m_p25->m_queue.clear(); resetRF();