From 2662dbcf19cd3965754733e17c50072a3209ad66 Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Thu, 24 Sep 2026 10:43:05 -0400 Subject: [PATCH] correct some DMR OTA late entry issues; correct missing NXDN packet length checks (should be similar to DMR); --- src/common/dmr/data/NetData.cpp | 6 +++--- src/common/network/packet/Protocol.cpp | 15 ++++++++++++--- src/fne/network/callhandler/TagDMRData.cpp | 6 ++++++ src/fne/network/callhandler/TagNXDNData.cpp | 6 ++++++ src/host/dmr/packet/Voice.cpp | 14 +++++++++++--- 5 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/common/dmr/data/NetData.cpp b/src/common/dmr/data/NetData.cpp index bae110c6..1aebf2a4 100644 --- a/src/common/dmr/data/NetData.cpp +++ b/src/common/dmr/data/NetData.cpp @@ -38,8 +38,8 @@ NetData::NetData(const NetData& data) : m_rssi(data.m_rssi), m_data(nullptr) { - m_data = new uint8_t[2U * DMR_FRAME_LENGTH_BYTES]; - ::memcpy(m_data, data.m_data, 2U * DMR_FRAME_LENGTH_BYTES); + m_data = new uint8_t[DMR_FRAME_LENGTH_BYTES]; + ::memcpy(m_data, data.m_data, DMR_FRAME_LENGTH_BYTES); } /* Initializes a new instance of the NetData class. */ @@ -57,7 +57,7 @@ NetData::NetData() : m_rssi(0U), m_data(nullptr) { - m_data = new uint8_t[2U * DMR_FRAME_LENGTH_BYTES]; + m_data = new uint8_t[DMR_FRAME_LENGTH_BYTES](); } /* Finalizes a instance of the NetData class. */ diff --git a/src/common/network/packet/Protocol.cpp b/src/common/network/packet/Protocol.cpp index d89eb37e..39816481 100644 --- a/src/common/network/packet/Protocol.cpp +++ b/src/common/network/packet/Protocol.cpp @@ -37,6 +37,12 @@ bool Network::PacketHandler::protocol(Network* network, uint32_t peerId, uint32_ case NET_SUBFUNC::PROTOCOL_SUBFUNC_DMR: // Encapsulated DMR data frame { if (network->m_enabled && network->m_dmrEnabled) { + if (buffer == nullptr || length != (int)(DMR_PACKET_LENGTH + PACKET_PAD)) { + LogError(LOG_NET, "DMR frame has invalid length, peer = %u, streamId = %u, len = %d, expected = %u", + peerId, streamId, length, DMR_PACKET_LENGTH + PACKET_PAD); + break; + } + uint32_t slotNo = (buffer[15U] & 0x80U) == 0x80U ? 1U : 0U; // this is the raw index for the stream ID array if (network->m_debug) { @@ -111,9 +117,6 @@ bool Network::PacketHandler::protocol(Network* network, uint32_t peerId, uint32_ if (network->m_packetDump) Utils::dump(1U, "Network::clock(), Network Rx, DMR", buffer, length); - if (length > (int)(DMR_PACKET_LENGTH + PACKET_PAD)) - LogError(LOG_NET, "DMR Stream %u, frame oversized? this shouldn't happen, pktSeq = %u, len = %u", streamId, network->m_pktSeq, length); - uint8_t len = length; network->m_rxDMRData.addData(&len, 1U); network->m_rxDMRData.addData(buffer, len); @@ -306,6 +309,12 @@ bool Network::PacketHandler::protocol(Network* network, uint32_t peerId, uint32_ case NET_SUBFUNC::PROTOCOL_SUBFUNC_NXDN: // Encapsulated NXDN data frame { if (network->m_enabled && network->m_nxdnEnabled) { + if (buffer == nullptr || length != (int)(NXDN_PACKET_LENGTH + PACKET_PAD)) { + LogError(LOG_NET, "NXDN frame has invalid length, peer = %u, streamId = %u, len = %d, expected = %u", + peerId, streamId, length, NXDN_PACKET_LENGTH + PACKET_PAD); + break; + } + if (network->m_debug) { LogDebug(LOG_NET, "NXDN, peer = %u, len = %u, pktSeq = %u, streamId = %u", peerId, length, rtpHeader.getSequence(), streamId); diff --git a/src/fne/network/callhandler/TagDMRData.cpp b/src/fne/network/callhandler/TagDMRData.cpp index d0426032..f87ca78d 100644 --- a/src/fne/network/callhandler/TagDMRData.cpp +++ b/src/fne/network/callhandler/TagDMRData.cpp @@ -67,6 +67,12 @@ TagDMRData::~TagDMRData() bool TagDMRData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId, uint32_t ssrc, uint16_t pktSeq, uint32_t streamId, bool fromUpstream) { + if (data == nullptr || len != (DMR_PACKET_LENGTH + PACKET_PAD)) { + LogError(LOG_NET, "DMR frame has invalid length, peer = %u, ssrc = %u, streamId = %u, len = %u, expected = %u", + peerId, ssrc, streamId, len, DMR_PACKET_LENGTH + PACKET_PAD); + return false; + } + hrc::hrc_t pktTime = hrc::now(); DECLARE_UINT8_ARRAY(buffer, len); diff --git a/src/fne/network/callhandler/TagNXDNData.cpp b/src/fne/network/callhandler/TagNXDNData.cpp index f749d47d..83bd9a7f 100644 --- a/src/fne/network/callhandler/TagNXDNData.cpp +++ b/src/fne/network/callhandler/TagNXDNData.cpp @@ -65,6 +65,12 @@ TagNXDNData::~TagNXDNData() = default; bool TagNXDNData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId, uint32_t ssrc, uint16_t pktSeq, uint32_t streamId, bool fromUpstream) { + if (data == nullptr || len != (NXDN_PACKET_LENGTH + PACKET_PAD)) { + LogError(LOG_NET, "NXDN frame has invalid length, peer = %u, ssrc = %u, streamId = %u, len = %u, expected = %u", + peerId, ssrc, streamId, len, NXDN_PACKET_LENGTH + PACKET_PAD); + return false; + } + hrc::hrc_t pktTime = hrc::now(); DECLARE_UINT8_ARRAY(buffer, len); diff --git a/src/host/dmr/packet/Voice.cpp b/src/host/dmr/packet/Voice.cpp index b93a6efe..02337436 100644 --- a/src/host/dmr/packet/Voice.cpp +++ b/src/host/dmr/packet/Voice.cpp @@ -357,6 +357,14 @@ bool Voice::process(uint8_t* data, uint32_t len) } } else { + // Late entry may begin on any of the B--E bursts carrying embedded LC; + // do not wait for the next voice-sync (A) burst before collecting it. + if (m_slot->m_rfState == RS_RF_LISTENING) { + m_rfEmbeddedLC.reset(); + m_lastRfN = 0xFFU; + m_slot->m_rfState = RS_RF_LATE_ENTRY; + } + if (m_slot->m_rfState == RS_RF_AUDIO) { m_rfN = data[1U] & 0x0FU; @@ -603,7 +611,7 @@ bool Voice::process(uint8_t* data, uint32_t len) m_rfEmbeddedData[1U].setLC(*m_slot->m_rfLC); // Create a dummy start frame to replace the received frame - uint8_t start[DMR_FRAME_LENGTH_BYTES + 2U]; + uint8_t start[DMR_FRAME_LENGTH_BYTES + 2U] = { 0U }; Sync::addDMRDataSync(start + 2U, m_slot->s_duplex); @@ -865,7 +873,7 @@ void Voice::processNetwork(const data::NetData& dmrData) m_slot->addFrame(m_slot->s_idle, true); // Create a dummy start frame - uint8_t start[DMR_FRAME_LENGTH_BYTES + 2U]; + uint8_t start[DMR_FRAME_LENGTH_BYTES + 2U] = { 0U }; Sync::addDMRDataSync(start + 2U, m_slot->s_duplex); @@ -974,7 +982,7 @@ void Voice::processNetwork(const data::NetData& dmrData) m_slot->addFrame(m_slot->s_idle, true); // Create a dummy start frame - uint8_t start[DMR_FRAME_LENGTH_BYTES + 2U]; + uint8_t start[DMR_FRAME_LENGTH_BYTES + 2U] = { 0U }; Sync::addDMRDataSync(start + 2U, m_slot->s_duplex);