From 61638ad740a160a5e92497a6cb65039d6badccc2 Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Wed, 3 Jun 2026 10:01:34 -0400 Subject: [PATCH] simplify how LDU voice vectors are recovered from network packed DFSI frames (this reduces code duplication across the project; correct bad length being used for P25 causing PDU data to be unintentionally truncated; --- src/bridge/HostBridge.P25.cpp | 95 +++----------------- src/common/network/BaseNetwork.cpp | 139 +++++++++++++++++++++++++++++ src/common/network/BaseNetwork.h | 19 ++++ src/common/network/Network.cpp | 2 +- src/host/p25/packet/Voice.cpp | 91 +++---------------- src/patch/HostPatch.cpp | 92 +++---------------- 6 files changed, 190 insertions(+), 248 deletions(-) diff --git a/src/bridge/HostBridge.P25.cpp b/src/bridge/HostBridge.P25.cpp index 93c5d083..4b32eb92 100644 --- a/src/bridge/HostBridge.P25.cpp +++ b/src/bridge/HostBridge.P25.cpp @@ -268,52 +268,15 @@ void HostBridge::processP25Network(uint8_t* buffer, uint32_t length) } int count = 0; - switch (duid) - { + switch (duid) { case DUID::LDU1: - if ((data[0U] == DFSIFrameType::LDU1_VOICE1) && (data[22U] == DFSIFrameType::LDU1_VOICE2) && - (data[36U] == DFSIFrameType::LDU1_VOICE3) && (data[53U] == DFSIFrameType::LDU1_VOICE4) && - (data[70U] == DFSIFrameType::LDU1_VOICE5) && (data[87U] == DFSIFrameType::LDU1_VOICE6) && - (data[104U] == DFSIFrameType::LDU1_VOICE7) && (data[121U] == DFSIFrameType::LDU1_VOICE8) && - (data[138U] == DFSIFrameType::LDU1_VOICE9)) { - + { dfsi::LC dfsiLC = dfsi::LC(control, lsd); - dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE1); - dfsiLC.decodeLDU1(data.get() + count, m_netLDU1 + 10U); - count += DFSI_LDU1_VOICE1_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE2); - dfsiLC.decodeLDU1(data.get() + count, m_netLDU1 + 26U); - count += DFSI_LDU1_VOICE2_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE3); - dfsiLC.decodeLDU1(data.get() + count, m_netLDU1 + 55U); - count += DFSI_LDU1_VOICE3_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE4); - dfsiLC.decodeLDU1(data.get() + count, m_netLDU1 + 80U); - count += DFSI_LDU1_VOICE4_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE5); - dfsiLC.decodeLDU1(data.get() + count, m_netLDU1 + 105U); - count += DFSI_LDU1_VOICE5_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE6); - dfsiLC.decodeLDU1(data.get() + count, m_netLDU1 + 130U); - count += DFSI_LDU1_VOICE6_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE7); - dfsiLC.decodeLDU1(data.get() + count, m_netLDU1 + 155U); - count += DFSI_LDU1_VOICE7_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE8); - dfsiLC.decodeLDU1(data.get() + count, m_netLDU1 + 180U); - count += DFSI_LDU1_VOICE8_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE9); - dfsiLC.decodeLDU1(data.get() + count, m_netLDU1 + 204U); - count += DFSI_LDU1_VOICE9_FRAME_LENGTH_BYTES; + uint8_t missing = BaseNetwork::reconstructLDUVectors(data.get(), frameLength, &dfsiLC, DUID::LDU1, m_netLDU1); + if (missing > 0U) { + LogWarning(LOG_NET, P25_LDU1_STR ", missing %u LDU1 voice frames, srcId = %u, dstId = %u", missing, srcId, dstId); + } LogInfoEx(LOG_NET, P25_LDU1_STR " audio, srcId = %u, dstId = %u", srcId, dstId); @@ -322,49 +285,13 @@ void HostBridge::processP25Network(uint8_t* buffer, uint32_t length) } break; case DUID::LDU2: - if ((data[0U] == DFSIFrameType::LDU2_VOICE10) && (data[22U] == DFSIFrameType::LDU2_VOICE11) && - (data[36U] == DFSIFrameType::LDU2_VOICE12) && (data[53U] == DFSIFrameType::LDU2_VOICE13) && - (data[70U] == DFSIFrameType::LDU2_VOICE14) && (data[87U] == DFSIFrameType::LDU2_VOICE15) && - (data[104U] == DFSIFrameType::LDU2_VOICE16) && (data[121U] == DFSIFrameType::LDU2_VOICE17) && - (data[138U] == DFSIFrameType::LDU2_VOICE18)) { - + { dfsi::LC dfsiLC = dfsi::LC(control, lsd); - dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE10); - dfsiLC.decodeLDU2(data.get() + count, m_netLDU2 + 10U); - count += DFSI_LDU2_VOICE10_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE11); - dfsiLC.decodeLDU2(data.get() + count, m_netLDU2 + 26U); - count += DFSI_LDU2_VOICE11_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE12); - dfsiLC.decodeLDU2(data.get() + count, m_netLDU2 + 55U); - count += DFSI_LDU2_VOICE12_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE13); - dfsiLC.decodeLDU2(data.get() + count, m_netLDU2 + 80U); - count += DFSI_LDU2_VOICE13_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE14); - dfsiLC.decodeLDU2(data.get() + count, m_netLDU2 + 105U); - count += DFSI_LDU2_VOICE14_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE15); - dfsiLC.decodeLDU2(data.get() + count, m_netLDU2 + 130U); - count += DFSI_LDU2_VOICE15_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE16); - dfsiLC.decodeLDU2(data.get() + count, m_netLDU2 + 155U); - count += DFSI_LDU2_VOICE16_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE17); - dfsiLC.decodeLDU2(data.get() + count, m_netLDU2 + 180U); - count += DFSI_LDU2_VOICE17_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE18); - dfsiLC.decodeLDU2(data.get() + count, m_netLDU2 + 204U); - count += DFSI_LDU2_VOICE18_FRAME_LENGTH_BYTES; + uint8_t missing = BaseNetwork::reconstructLDUVectors(data.get(), frameLength, &dfsiLC, DUID::LDU2, m_netLDU2); + if (missing > 0U) { + LogWarning(LOG_NET, P25_LDU2_STR ", missing %u LDU2 voice frames, srcId = %u, dstId = %u", missing, srcId, dstId); + } LogInfoEx(LOG_NET, P25_LDU2_STR " audio, algo = $%02X, kid = $%04X", dfsiLC.control()->getAlgId(), dfsiLC.control()->getKId()); diff --git a/src/common/network/BaseNetwork.cpp b/src/common/network/BaseNetwork.cpp index 0a816168..ed0a92f7 100644 --- a/src/common/network/BaseNetwork.cpp +++ b/src/common/network/BaseNetwork.cpp @@ -618,6 +618,145 @@ UInt8Array BaseNetwork::readP25(bool& ret, uint32_t& frameLength) return buffer; } +/* Helper to test if the given buffer contains a complete set of P25 LDU voice vectors for the given DUID type. */ + +bool BaseNetwork::hasLDUVectors(const uint8_t* data, uint32_t len, P25DEF::DUID::E duid) +{ + switch (duid) { + case P25DEF::DUID::LDU1: + { + if ((data[0U] == P25DFSIDEF::DFSIFrameType::LDU1_VOICE1) && (data[22U] == P25DFSIDEF::DFSIFrameType::LDU1_VOICE2) && + (data[36U] == P25DFSIDEF::DFSIFrameType::LDU1_VOICE3) && (data[53U] == P25DFSIDEF::DFSIFrameType::LDU1_VOICE4) && + (data[70U] == P25DFSIDEF::DFSIFrameType::LDU1_VOICE5) && (data[87U] == P25DFSIDEF::DFSIFrameType::LDU1_VOICE6) && + (data[104U] == P25DFSIDEF::DFSIFrameType::LDU1_VOICE7) && (data[121U] == P25DFSIDEF::DFSIFrameType::LDU1_VOICE8) && + (data[138U] == P25DFSIDEF::DFSIFrameType::LDU1_VOICE9)) { + return true; + } + } + break; + case P25DEF::DUID::LDU2: + { + if ((data[0U] == P25DFSIDEF::DFSIFrameType::LDU2_VOICE10) && (data[22U] == P25DFSIDEF::DFSIFrameType::LDU2_VOICE11) && + (data[36U] == P25DFSIDEF::DFSIFrameType::LDU2_VOICE12) && (data[53U] == P25DFSIDEF::DFSIFrameType::LDU2_VOICE13) && + (data[70U] == P25DFSIDEF::DFSIFrameType::LDU2_VOICE14) && (data[87U] == P25DFSIDEF::DFSIFrameType::LDU2_VOICE15) && + (data[104U] == P25DFSIDEF::DFSIFrameType::LDU2_VOICE16) && (data[121U] == P25DFSIDEF::DFSIFrameType::LDU2_VOICE17) && + (data[138U] == P25DFSIDEF::DFSIFrameType::LDU2_VOICE18)) { + return true; + } + } + break; + + default: + return false; + } + + return false; +} + +/* Helper to reconstruct a P25 LDU voice vectors from the given DFSI data. */ + +uint8_t BaseNetwork::reconstructLDUVectors(const uint8_t* dfsiData, uint32_t len, p25::dfsi::LC* dfsiLC, P25DEF::DUID::E duid, + uint8_t* outLDU) +{ + if (dfsiData == nullptr || outLDU == nullptr) + return 9U; + + constexpr P25DFSIDEF::DFSIFrameType::E LDU1_FRAME_TYPES[] = { + P25DFSIDEF::DFSIFrameType::LDU1_VOICE1, P25DFSIDEF::DFSIFrameType::LDU1_VOICE2, P25DFSIDEF::DFSIFrameType::LDU1_VOICE3, + P25DFSIDEF::DFSIFrameType::LDU1_VOICE4, P25DFSIDEF::DFSIFrameType::LDU1_VOICE5, P25DFSIDEF::DFSIFrameType::LDU1_VOICE6, + P25DFSIDEF::DFSIFrameType::LDU1_VOICE7, P25DFSIDEF::DFSIFrameType::LDU1_VOICE8, P25DFSIDEF::DFSIFrameType::LDU1_VOICE9 + }; + constexpr uint32_t LDU1_FRAME_LENGTH[] = { + P25DFSIDEF::DFSI_LDU1_VOICE1_FRAME_LENGTH_BYTES, P25DFSIDEF::DFSI_LDU1_VOICE2_FRAME_LENGTH_BYTES, P25DFSIDEF::DFSI_LDU1_VOICE3_FRAME_LENGTH_BYTES, + P25DFSIDEF::DFSI_LDU1_VOICE4_FRAME_LENGTH_BYTES, P25DFSIDEF::DFSI_LDU1_VOICE5_FRAME_LENGTH_BYTES, P25DFSIDEF::DFSI_LDU1_VOICE6_FRAME_LENGTH_BYTES, + P25DFSIDEF::DFSI_LDU1_VOICE7_FRAME_LENGTH_BYTES, P25DFSIDEF::DFSI_LDU1_VOICE8_FRAME_LENGTH_BYTES, P25DFSIDEF::DFSI_LDU1_VOICE9_FRAME_LENGTH_BYTES + }; + + constexpr P25DFSIDEF::DFSIFrameType::E LDU2_FRAME_TYPES[] = { + P25DFSIDEF::DFSIFrameType::LDU2_VOICE10, P25DFSIDEF::DFSIFrameType::LDU2_VOICE11, P25DFSIDEF::DFSIFrameType::LDU2_VOICE12, + P25DFSIDEF::DFSIFrameType::LDU2_VOICE13, P25DFSIDEF::DFSIFrameType::LDU2_VOICE14, P25DFSIDEF::DFSIFrameType::LDU2_VOICE15, + P25DFSIDEF::DFSIFrameType::LDU2_VOICE16, P25DFSIDEF::DFSIFrameType::LDU2_VOICE17, P25DFSIDEF::DFSIFrameType::LDU2_VOICE18 + }; + constexpr uint32_t LDU2_FRAME_LENGTH[] = { + P25DFSIDEF::DFSI_LDU2_VOICE10_FRAME_LENGTH_BYTES, P25DFSIDEF::DFSI_LDU2_VOICE11_FRAME_LENGTH_BYTES, P25DFSIDEF::DFSI_LDU2_VOICE12_FRAME_LENGTH_BYTES, + P25DFSIDEF::DFSI_LDU2_VOICE13_FRAME_LENGTH_BYTES, P25DFSIDEF::DFSI_LDU2_VOICE14_FRAME_LENGTH_BYTES, P25DFSIDEF::DFSI_LDU2_VOICE15_FRAME_LENGTH_BYTES, + P25DFSIDEF::DFSI_LDU2_VOICE16_FRAME_LENGTH_BYTES, P25DFSIDEF::DFSI_LDU2_VOICE17_FRAME_LENGTH_BYTES, P25DFSIDEF::DFSI_LDU2_VOICE18_FRAME_LENGTH_BYTES + }; + + constexpr uint8_t FRAME_OFFSETS[] = { 10U, 26U, 55U, 80U, 105U, 130U, 155U, 180U, 204U }; + + uint8_t missing = 0U; + uint32_t packetOffset = 0U; + + // reset outLDU to NULL frames + for (int n = 0; n < 9; n++) { + ::memcpy(outLDU + FRAME_OFFSETS[n], P25DEF::NULL_IMBE, P25DEF::RAW_IMBE_LENGTH_BYTES); + } + + /* + ** bryanb: this centralizes the multiple instances of DFSI unpacking that are done throughout DVM; + ** However, in most cases unless you have packet corruption, you will either have all frames present or + ** all frames missing, so the logic here is a bit misleading because it implies that you could have some frames + ** present and some frames missing, which is not really the case in practice; the only time you would get a false + ** return from decodeLDU1 or decodeLDU2 is if the frame had an unexpected frame type, which would be an indication + ** of packet corruption; in that case, we would want to treat that frame as missing, but we would still want to + ** attempt to decode the other frames in the packet, which is what this logic does. + ** + ** So in practice, you will either get 0 frames missing (if all frames are present) or 9 frames missing (if all + ** frames are missing or if there is packet corruption), but you could also get some intermediate number of frames + ** missing if there is packet corruption that affects some but not all of the frames in the packet. + */ + + if (duid == P25DEF::DUID::LDU1) { + for (int n = 0; n < 9; n++) { + bool haveFrame = (packetOffset + LDU1_FRAME_LENGTH[n]) <= len && dfsiData[packetOffset] == LDU1_FRAME_TYPES[n]; + if (haveFrame) { + dfsiLC->setFrameType(LDU1_FRAME_TYPES[n]); + + // bryanb: this logic is misleading really -- because the only time we would get a false return from + // decodeLDU1 is if the frame had an unexpected frame type + if (!dfsiLC->decodeLDU1(dfsiData + packetOffset, outLDU + FRAME_OFFSETS[n])) { + missing++; + } + } + else { + missing++; + } + + packetOffset += LDU1_FRAME_LENGTH[n]; + } + + if (missing == 9U) { + return 9U; // all frames missing, return the total number of frames that were expected + } + } + else if (duid == P25DEF::DUID::LDU2) { + for (int n = 0; n < 9; n++) { + bool haveFrame = (packetOffset + LDU2_FRAME_LENGTH[n]) <= len && dfsiData[packetOffset] == LDU2_FRAME_TYPES[n]; + if (haveFrame) { + dfsiLC->setFrameType(LDU2_FRAME_TYPES[n]); + + // bryanb: this logic is misleading really -- because the only time we would get a false return from + // decodeLDU2 is if the frame had an unexpected frame type + if (!dfsiLC->decodeLDU2(dfsiData + packetOffset, outLDU + FRAME_OFFSETS[n])) { + missing++; + } + } + else { + missing++; + } + + packetOffset += LDU2_FRAME_LENGTH[n]; + } + + if (missing == 9U) { + return 9U; // all frames missing, return the total number of frames that were expected + } + } + + return missing; +} + /* Writes P25 LDU1 frame data to the network. */ bool BaseNetwork::writeP25LDU1(const p25::lc::LC& control, const p25::data::LowSpeedData& lsd, const uint8_t* data, diff --git a/src/common/network/BaseNetwork.h b/src/common/network/BaseNetwork.h index 21f0fe45..1e2f038d 100644 --- a/src/common/network/BaseNetwork.h +++ b/src/common/network/BaseNetwork.h @@ -836,6 +836,25 @@ namespace network * @returns UInt8Array Buffer containing received frame. */ virtual UInt8Array readP25(bool& ret, uint32_t& frameLength); + /** + * @brief Helper to test if the given buffer contains a complete set of P25 LDU voice vectors for the given DUID type. + * @param[in] data Buffer containing the data to check. + * @param len Length of the data buffer. + * @param[in] duid P25 DUID type. + * @returns bool True, if the buffer contains P25 LDU voice vectors for the given DUID type, otherwise false. + */ + static bool hasLDUVectors(const uint8_t* data, uint32_t len, P25DEF::DUID::E duid); + /** + * @brief Helper to reconstruct P25 LDU voice vectors from the given DFSI data. + * @param[in] dfsiData Buffer containing the DFSI data to reconstruct from. + * @param len Length of the DFSI data buffer. + * @param[in] dfsiLC Instance of p25::dfsi::LC containing the DFSI link control data. + * @param[in] duid P25 DUID type. + * @param[out] outLDU Buffer to write the reconstructed LDU voice vectors to. + * @returns uint8_t Number of missing frames, 9 if reconstruction failed, otherwise the number of missing frames. + */ + static uint8_t reconstructLDUVectors(const uint8_t* dfsiData, uint32_t len, p25::dfsi::LC* dfsiLC, P25DEF::DUID::E duid, + uint8_t* outLDU); /** * @brief Writes P25 LDU1 frame data to the network. * @param[in] control Instance of p25::lc::LC containing link control data. diff --git a/src/common/network/Network.cpp b/src/common/network/Network.cpp index 5a8d618d..821e957b 100644 --- a/src/common/network/Network.cpp +++ b/src/common/network/Network.cpp @@ -524,7 +524,7 @@ void Network::clock(uint32_t ms) m_rxP25Data.addData(&len, 1U); } - m_rxP25Data.addData(buffer.get(), len); + m_rxP25Data.addData(buffer.get(), length); } } break; diff --git a/src/host/p25/packet/Voice.cpp b/src/host/p25/packet/Voice.cpp index 389152fe..f677a716 100644 --- a/src/host/p25/packet/Voice.cpp +++ b/src/host/p25/packet/Voice.cpp @@ -1153,49 +1153,13 @@ bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L uint32_t count = 0U; switch (duid) { case DUID::LDU1: - if ((data[0U] == DFSIFrameType::LDU1_VOICE1) && (data[22U] == DFSIFrameType::LDU1_VOICE2) && - (data[36U] == DFSIFrameType::LDU1_VOICE3) && (data[53U] == DFSIFrameType::LDU1_VOICE4) && - (data[70U] == DFSIFrameType::LDU1_VOICE5) && (data[87U] == DFSIFrameType::LDU1_VOICE6) && - (data[104U] == DFSIFrameType::LDU1_VOICE7) && (data[121U] == DFSIFrameType::LDU1_VOICE8) && - (data[138U] == DFSIFrameType::LDU1_VOICE9)) { - + { m_dfsiLC = dfsi::LC(control, lsd); - m_dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE1); - m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 10U); - count += DFSI_LDU1_VOICE1_FRAME_LENGTH_BYTES; - - m_dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE2); - m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 26U); - count += DFSI_LDU1_VOICE2_FRAME_LENGTH_BYTES; - - m_dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE3); - m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 55U); - count += DFSI_LDU1_VOICE3_FRAME_LENGTH_BYTES; - - m_dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE4); - m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 80U); - count += DFSI_LDU1_VOICE4_FRAME_LENGTH_BYTES; - - m_dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE5); - m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 105U); - count += DFSI_LDU1_VOICE5_FRAME_LENGTH_BYTES; - - m_dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE6); - m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 130U); - count += DFSI_LDU1_VOICE6_FRAME_LENGTH_BYTES; - - m_dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE7); - m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 155U); - count += DFSI_LDU1_VOICE7_FRAME_LENGTH_BYTES; - - m_dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE8); - m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 180U); - count += DFSI_LDU1_VOICE8_FRAME_LENGTH_BYTES; - - m_dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE9); - m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 204U); - count += DFSI_LDU1_VOICE9_FRAME_LENGTH_BYTES; + uint8_t missing = network::BaseNetwork::reconstructLDUVectors(data, len, &m_dfsiLC, DUID::LDU1, m_netLDU1); + if (missing > 0U) { + LogWarning(LOG_NET, P25_LDU1_STR ", missing %u LDU1 voice frames, srcId = %u, dstId = %u", missing, srcId, dstId); + } m_gotNetLDU1 = true; @@ -1248,46 +1212,11 @@ bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L } break; case DUID::LDU2: - if ((data[0U] == DFSIFrameType::LDU2_VOICE10) && (data[22U] == DFSIFrameType::LDU2_VOICE11) && - (data[36U] == DFSIFrameType::LDU2_VOICE12) && (data[53U] == DFSIFrameType::LDU2_VOICE13) && - (data[70U] == DFSIFrameType::LDU2_VOICE14) && (data[87U] == DFSIFrameType::LDU2_VOICE15) && - (data[104U] == DFSIFrameType::LDU2_VOICE16) && (data[121U] == DFSIFrameType::LDU2_VOICE17) && - (data[138U] == DFSIFrameType::LDU2_VOICE18)) { - m_dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE10); - m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 10U); - count += DFSI_LDU2_VOICE10_FRAME_LENGTH_BYTES; - - m_dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE11); - m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 26U); - count += DFSI_LDU2_VOICE11_FRAME_LENGTH_BYTES; - - m_dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE12); - m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 55U); - count += DFSI_LDU2_VOICE12_FRAME_LENGTH_BYTES; - - m_dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE13); - m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 80U); - count += DFSI_LDU2_VOICE13_FRAME_LENGTH_BYTES; - - m_dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE14); - m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 105U); - count += DFSI_LDU2_VOICE14_FRAME_LENGTH_BYTES; - - m_dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE15); - m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 130U); - count += DFSI_LDU2_VOICE15_FRAME_LENGTH_BYTES; - - m_dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE16); - m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 155U); - count += DFSI_LDU2_VOICE16_FRAME_LENGTH_BYTES; - - m_dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE17); - m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 180U); - count += DFSI_LDU2_VOICE17_FRAME_LENGTH_BYTES; - - m_dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE18); - m_dfsiLC.decodeLDU2(data + count, m_netLDU2 + 204U); - count += DFSI_LDU2_VOICE18_FRAME_LENGTH_BYTES; + { + uint8_t missing = network::BaseNetwork::reconstructLDUVectors(data, len, &m_dfsiLC, DUID::LDU2, m_netLDU2); + if (missing > 0U) { + LogWarning(LOG_NET, P25_LDU2_STR ", missing %u LDU2 voice frames, srcId = %u, dstId = %u", missing, srcId, dstId); + } m_gotNetLDU2 = true; diff --git a/src/patch/HostPatch.cpp b/src/patch/HostPatch.cpp index bf68c6b2..2aa457df 100644 --- a/src/patch/HostPatch.cpp +++ b/src/patch/HostPatch.cpp @@ -1252,49 +1252,13 @@ void HostPatch::processP25Network(uint8_t* buffer, uint32_t length) switch (duid) { case DUID::LDU1: - if ((data[0U] == DFSIFrameType::LDU1_VOICE1) && (data[22U] == DFSIFrameType::LDU1_VOICE2) && - (data[36U] == DFSIFrameType::LDU1_VOICE3) && (data[53U] == DFSIFrameType::LDU1_VOICE4) && - (data[70U] == DFSIFrameType::LDU1_VOICE5) && (data[87U] == DFSIFrameType::LDU1_VOICE6) && - (data[104U] == DFSIFrameType::LDU1_VOICE7) && (data[121U] == DFSIFrameType::LDU1_VOICE8) && - (data[138U] == DFSIFrameType::LDU1_VOICE9)) { - + { dfsi::LC dfsiLC = dfsi::LC(control, lsd); - dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE1); - dfsiLC.decodeLDU1(data.get() + count, netLDU + 10U); - count += DFSI_LDU1_VOICE1_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE2); - dfsiLC.decodeLDU1(data.get() + count, netLDU + 26U); - count += DFSI_LDU1_VOICE2_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE3); - dfsiLC.decodeLDU1(data.get() + count, netLDU + 55U); - count += DFSI_LDU1_VOICE3_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE4); - dfsiLC.decodeLDU1(data.get() + count, netLDU + 80U); - count += DFSI_LDU1_VOICE4_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE5); - dfsiLC.decodeLDU1(data.get() + count, netLDU + 105U); - count += DFSI_LDU1_VOICE5_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE6); - dfsiLC.decodeLDU1(data.get() + count, netLDU + 130U); - count += DFSI_LDU1_VOICE6_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE7); - dfsiLC.decodeLDU1(data.get() + count, netLDU + 155U); - count += DFSI_LDU1_VOICE7_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE8); - dfsiLC.decodeLDU1(data.get() + count, netLDU + 180U); - count += DFSI_LDU1_VOICE8_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE9); - dfsiLC.decodeLDU1(data.get() + count, netLDU + 204U); - count += DFSI_LDU1_VOICE9_FRAME_LENGTH_BYTES; + uint8_t missing = BaseNetwork::reconstructLDUVectors(data.get(), frameLength, &dfsiLC, DUID::LDU1, m_netLDU1); + if (missing > 0) { + LogWarning(LOG_NET, P25_LDU1_STR ", missing %u voice frames, srcId = %u, dstId = %u", missing, srcId, dstId); + } LogInfoEx(LOG_NET, P25_LDU1_STR " audio, srcId = %u, dstId = %u", srcId, dstId); @@ -1387,49 +1351,13 @@ void HostPatch::processP25Network(uint8_t* buffer, uint32_t length) } break; case DUID::LDU2: - if ((data[0U] == DFSIFrameType::LDU2_VOICE10) && (data[22U] == DFSIFrameType::LDU2_VOICE11) && - (data[36U] == DFSIFrameType::LDU2_VOICE12) && (data[53U] == DFSIFrameType::LDU2_VOICE13) && - (data[70U] == DFSIFrameType::LDU2_VOICE14) && (data[87U] == DFSIFrameType::LDU2_VOICE15) && - (data[104U] == DFSIFrameType::LDU2_VOICE16) && (data[121U] == DFSIFrameType::LDU2_VOICE17) && - (data[138U] == DFSIFrameType::LDU2_VOICE18)) { - + { dfsi::LC dfsiLC = dfsi::LC(control, lsd); - dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE10); - dfsiLC.decodeLDU2(data.get() + count, netLDU + 10U); - count += DFSI_LDU2_VOICE10_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE11); - dfsiLC.decodeLDU2(data.get() + count, netLDU + 26U); - count += DFSI_LDU2_VOICE11_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE12); - dfsiLC.decodeLDU2(data.get() + count, netLDU + 55U); - count += DFSI_LDU2_VOICE12_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE13); - dfsiLC.decodeLDU2(data.get() + count, netLDU + 80U); - count += DFSI_LDU2_VOICE13_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE14); - dfsiLC.decodeLDU2(data.get() + count, netLDU + 105U); - count += DFSI_LDU2_VOICE14_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE15); - dfsiLC.decodeLDU2(data.get() + count, netLDU + 130U); - count += DFSI_LDU2_VOICE15_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE16); - dfsiLC.decodeLDU2(data.get() + count, netLDU + 155U); - count += DFSI_LDU2_VOICE16_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE17); - dfsiLC.decodeLDU2(data.get() + count, netLDU + 180U); - count += DFSI_LDU2_VOICE17_FRAME_LENGTH_BYTES; - - dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE18); - dfsiLC.decodeLDU2(data.get() + count, netLDU + 204U); - count += DFSI_LDU2_VOICE18_FRAME_LENGTH_BYTES; + uint8_t missing = BaseNetwork::reconstructLDUVectors(data.get(), frameLength, &dfsiLC, DUID::LDU2, netLDU); + if (missing > 0) { + LogWarning(LOG_NET, P25_LDU2_STR ", missing %u voice frames, srcId = %u, dstId = %u", missing, srcId, dstId); + } LogInfoEx(LOG_NET, P25_LDU2_STR " audio, algo = $%02X, kid = $%04X", dfsiLC.control()->getAlgId(), dfsiLC.control()->getKId());