diff --git a/Conf.cpp b/Conf.cpp index 8f3ffce..dd65b7b 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -113,7 +113,7 @@ m_dstarErrorReply(true), m_dstarRemoteGateway(false), m_dstarModeHang(10U), m_dmrEnabled(false), -m_dmrBeacons(false), +m_dmrBeacons(0U), m_dmrId(0U), m_dmrColorCode(2U), m_dmrSelfOnly(false), @@ -445,7 +445,7 @@ bool CConf::read() if (::strcmp(key, "Enable") == 0) m_dmrEnabled = ::atoi(value) == 1; else if (::strcmp(key, "Beacons") == 0) - m_dmrBeacons = ::atoi(value) == 1; + m_dmrBeacons = (unsigned int)::atoi(value); else if (::strcmp(key, "Id") == 0) m_dmrId = (unsigned int)::atoi(value); else if (::strcmp(key, "ColorCode") == 0) @@ -983,7 +983,7 @@ bool CConf::getDMREnabled() const return m_dmrEnabled; } -bool CConf::getDMRBeacons() const +unsigned int CConf::getDMRBeacons() const { return m_dmrBeacons; } diff --git a/Conf.h b/Conf.h index 3a48efb..16f2629 100644 --- a/Conf.h +++ b/Conf.h @@ -104,7 +104,7 @@ public: // The DMR section bool getDMREnabled() const; - bool getDMRBeacons() const; + unsigned int getDMRBeacons() const; unsigned int getDMRId() const; unsigned int getDMRColorCode() const; bool getDMREmbeddedLCOnly() const; @@ -297,7 +297,7 @@ private: unsigned int m_dstarModeHang; bool m_dmrEnabled; - bool m_dmrBeacons; + unsigned int m_dmrBeacons; unsigned int m_dmrId; unsigned int m_dmrColorCode; bool m_dmrSelfOnly; diff --git a/DMRNetwork.cpp b/DMRNetwork.cpp index ae9be97..d296b57 100644 --- a/DMRNetwork.cpp +++ b/DMRNetwork.cpp @@ -498,8 +498,19 @@ void CDMRNetwork::receiveData(const unsigned char* data, unsigned int length) if (slotNo == 2U && !m_slot2) return; - unsigned char seqNo = data[4U]; - m_jitterBuffers[slotNo]->addData(data, length, seqNo); + 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); + } } bool CDMRNetwork::writeLogin() diff --git a/JitterBuffer.cpp b/JitterBuffer.cpp index c77068f..25522ec 100644 --- a/JitterBuffer.cpp +++ b/JitterBuffer.cpp @@ -36,6 +36,7 @@ m_stopWatch(), m_running(false), m_buffer(NULL), m_headSequenceNumber(0U), +m_appendSequenceNumber(0U), m_lastData(NULL), m_lastDataLength(0U) { @@ -115,6 +116,52 @@ bool CJitterBuffer::addData(const unsigned char* data, unsigned int length, unsi return true; } +bool CJitterBuffer::appendData(const unsigned char* data, unsigned int length) +{ + assert(data != NULL); + assert(length > 0U); + assert(length <= m_blockSize); + + unsigned int headSequenceNumber = m_headSequenceNumber % m_topSequenceNumber; + unsigned int tailSequenceNumber = (m_headSequenceNumber + m_blockCount) % m_topSequenceNumber; + + // Is the data out of sequence? + if (headSequenceNumber < tailSequenceNumber) { + if (m_appendSequenceNumber < headSequenceNumber || m_appendSequenceNumber >= tailSequenceNumber) { + LogDebug("%s, JitterBuffer: rejecting append frame with seqNo=%u, raw=%u, head=%u, tail=%u", m_name.c_str(), m_appendSequenceNumber, m_headSequenceNumber, headSequenceNumber, tailSequenceNumber); + return false; + } + } else { + if (m_appendSequenceNumber >= tailSequenceNumber && m_appendSequenceNumber < headSequenceNumber) { + LogDebug("%s, JitterBuffer: rejecting append frame with seqNo=%u, raw=%u, head=%u, tail=%u", m_name.c_str(), m_appendSequenceNumber, m_headSequenceNumber, headSequenceNumber, tailSequenceNumber); + return false; + } + } + + unsigned int number; + if (m_appendSequenceNumber >= headSequenceNumber) + number = m_appendSequenceNumber - headSequenceNumber; + else + number = (m_appendSequenceNumber + m_blockCount) - headSequenceNumber;; + + unsigned int index = (m_headSequenceNumber + number) % m_blockCount; + + if (m_debug) + LogDebug("%s, JitterBuffer: appending frame with seqNo=%u, pos=%u, raw=%u, head=%u, tail=%u", m_name.c_str(), m_appendSequenceNumber, index, m_headSequenceNumber, headSequenceNumber, tailSequenceNumber); + + ::memcpy(m_buffer[index].m_data, data, length); + m_buffer[index].m_length = length; + + if (!m_timer.isRunning()) { + LogDebug("%s, JitterBuffer: starting the timer from append", m_name.c_str()); + m_timer.start(); + } + + m_appendSequenceNumber++; + + return true; +} + JB_STATUS CJitterBuffer::getData(unsigned char* data, unsigned int& length) { assert(data != NULL); @@ -168,6 +215,7 @@ void CJitterBuffer::reset() m_buffer[i].m_length = 0U; m_headSequenceNumber = 0U; + m_appendSequenceNumber = 0U; m_lastDataLength = 0U; diff --git a/JitterBuffer.h b/JitterBuffer.h index 7bf664f..46575ee 100644 --- a/JitterBuffer.h +++ b/JitterBuffer.h @@ -36,6 +36,7 @@ public: ~CJitterBuffer(); 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); @@ -63,6 +64,8 @@ private: JitterEntry* m_buffer; unsigned int m_headSequenceNumber; + unsigned int m_appendSequenceNumber; + unsigned char* m_lastData; unsigned int m_lastDataLength; }; diff --git a/MMDVM.ini b/MMDVM.ini index 01c78b1..9abe0ae 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -78,7 +78,7 @@ RemoteGateway=0 [DMR] Enable=1 -Beacons=1 +Beacons=0 ColorCode=1 SelfOnly=0 EmbeddedLCOnly=0 diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 4bdb1f5..1a99c5a 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -148,6 +148,7 @@ m_ysfNetModeHang(3U), m_p25NetModeHang(3U), m_nxdnNetModeHang(3U), m_modeTimer(1000U), +m_dmrBeaconTimer(1000U), m_dmrTXTimer(1000U), m_cwIdTimer(1000U), m_duplex(false), @@ -321,9 +322,6 @@ int CMMDVMHost::run() m_cwIdTimer.start(); } - CTimer dmrBeaconTimer(1000U, 4U); - bool dmrBeaconsEnabled = m_dmrEnabled && m_conf.getDMRBeacons(); - // For all modes we handle RSSI std::string rssiMappingFile = m_conf.getModemRSSIMappingFile(); @@ -392,6 +390,7 @@ int CMMDVMHost::run() unsigned int callHang = m_conf.getDMRCallHang(); unsigned int txHang = m_conf.getDMRTXHang(); m_dmrRFModeHang = m_conf.getDMRModeHang(); + unsigned int dmrBeacons = m_conf.getDMRBeacons(); if (txHang > m_dmrRFModeHang) txHang = m_dmrRFModeHang; @@ -425,6 +424,12 @@ int CMMDVMHost::run() LogInfo(" TX Hang: %us", txHang); LogInfo(" Mode Hang: %us", m_dmrRFModeHang); + if (dmrBeacons > 0U) { + LogInfo(" DMR Roaming Beacons: %u mins", dmrBeacons); + m_dmrBeaconTimer.setTimeout(dmrBeacons * 60U); + m_dmrBeaconTimer.start(); + } + dmr = new CDMRControl(id, colorCode, callHang, selfOnly, embeddedLCOnly, dumpTAData, prefixes, blackList, whiteList, slot1TGWhiteList, slot2TGWhiteList, m_timeout, m_modem, m_dmrNetwork, m_display, m_duplex, m_lookup, rssi); m_dmrTXTimer.setTimeout(txHang); @@ -490,6 +495,8 @@ int CMMDVMHost::run() nxdn = new CNXDNControl(ran, id, selfOnly, m_nxdnNetwork, m_display, m_timeout, m_duplex, remoteGateway, rssi); } + CTimer dmrBeaconTimer(1000U, 4U); + setMode(MODE_IDLE); LogMessage("MMDVMHost-%s is running", VERSION); @@ -785,14 +792,6 @@ int CMMDVMHost::run() } } - if (m_dmrNetwork != NULL) { - bool run = m_dmrNetwork->wantsBeacon(); - if (dmrBeaconsEnabled && run && m_mode == MODE_IDLE && !m_modem->hasTX()) { - setMode(MODE_DMR); - dmrBeaconTimer.start(); - } - } - unsigned int ms = stopWatch.elapsed(); stopWatch.start(); @@ -835,6 +834,15 @@ int CMMDVMHost::run() } } + m_dmrBeaconTimer.clock(ms); + if (m_dmrBeaconTimer.isRunning() && m_dmrBeaconTimer.hasExpired()) { + if (m_mode == MODE_IDLE && !m_modem->hasTX()) { + setMode(MODE_DMR); + m_dmrBeaconTimer.start(); + dmrBeaconTimer.start(); + } + } + dmrBeaconTimer.clock(ms); if (dmrBeaconTimer.isRunning() && dmrBeaconTimer.hasExpired()) { setMode(MODE_IDLE); diff --git a/MMDVMHost.h b/MMDVMHost.h index c0faa1b..21d34a9 100644 --- a/MMDVMHost.h +++ b/MMDVMHost.h @@ -63,6 +63,7 @@ private: unsigned int m_p25NetModeHang; unsigned int m_nxdnNetModeHang; CTimer m_modeTimer; + CTimer m_dmrBeaconTimer; CTimer m_dmrTXTimer; CTimer m_cwIdTimer; bool m_duplex;