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;

r05a06_dev
Bryan Biedenkapp 1 day ago
parent 054f157096
commit 61638ad740

@ -268,52 +268,15 @@ void HostBridge::processP25Network(uint8_t* buffer, uint32_t length)
} }
int count = 0; int count = 0;
switch (duid) switch (duid) {
{
case DUID::LDU1: 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); dfsi::LC dfsiLC = dfsi::LC(control, lsd);
dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE1); uint8_t missing = BaseNetwork::reconstructLDUVectors(data.get(), frameLength, &dfsiLC, DUID::LDU1, m_netLDU1);
dfsiLC.decodeLDU1(data.get() + count, m_netLDU1 + 10U); if (missing > 0U) {
count += DFSI_LDU1_VOICE1_FRAME_LENGTH_BYTES; LogWarning(LOG_NET, P25_LDU1_STR ", missing %u LDU1 voice frames, srcId = %u, dstId = %u", missing, srcId, dstId);
}
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;
LogInfoEx(LOG_NET, P25_LDU1_STR " audio, srcId = %u, dstId = %u", 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; break;
case DUID::LDU2: 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); dfsi::LC dfsiLC = dfsi::LC(control, lsd);
dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE10); uint8_t missing = BaseNetwork::reconstructLDUVectors(data.get(), frameLength, &dfsiLC, DUID::LDU2, m_netLDU2);
dfsiLC.decodeLDU2(data.get() + count, m_netLDU2 + 10U); if (missing > 0U) {
count += DFSI_LDU2_VOICE10_FRAME_LENGTH_BYTES; LogWarning(LOG_NET, P25_LDU2_STR ", missing %u LDU2 voice frames, srcId = %u, dstId = %u", missing, srcId, dstId);
}
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;
LogInfoEx(LOG_NET, P25_LDU2_STR " audio, algo = $%02X, kid = $%04X", dfsiLC.control()->getAlgId(), dfsiLC.control()->getKId()); LogInfoEx(LOG_NET, P25_LDU2_STR " audio, algo = $%02X, kid = $%04X", dfsiLC.control()->getAlgId(), dfsiLC.control()->getKId());

@ -618,6 +618,145 @@ UInt8Array BaseNetwork::readP25(bool& ret, uint32_t& frameLength)
return buffer; 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. */ /* 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, bool BaseNetwork::writeP25LDU1(const p25::lc::LC& control, const p25::data::LowSpeedData& lsd, const uint8_t* data,

@ -836,6 +836,25 @@ namespace network
* @returns UInt8Array Buffer containing received frame. * @returns UInt8Array Buffer containing received frame.
*/ */
virtual UInt8Array readP25(bool& ret, uint32_t& frameLength); 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. * @brief Writes P25 LDU1 frame data to the network.
* @param[in] control Instance of p25::lc::LC containing link control data. * @param[in] control Instance of p25::lc::LC containing link control data.

@ -524,7 +524,7 @@ void Network::clock(uint32_t ms)
m_rxP25Data.addData(&len, 1U); m_rxP25Data.addData(&len, 1U);
} }
m_rxP25Data.addData(buffer.get(), len); m_rxP25Data.addData(buffer.get(), length);
} }
} }
break; break;

@ -1153,49 +1153,13 @@ bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L
uint32_t count = 0U; uint32_t count = 0U;
switch (duid) { switch (duid) {
case DUID::LDU1: 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 = dfsi::LC(control, lsd);
m_dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE1); uint8_t missing = network::BaseNetwork::reconstructLDUVectors(data, len, &m_dfsiLC, DUID::LDU1, m_netLDU1);
m_dfsiLC.decodeLDU1(data + count, m_netLDU1 + 10U); if (missing > 0U) {
count += DFSI_LDU1_VOICE1_FRAME_LENGTH_BYTES; LogWarning(LOG_NET, P25_LDU1_STR ", missing %u LDU1 voice frames, srcId = %u, dstId = %u", missing, srcId, dstId);
}
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;
m_gotNetLDU1 = true; m_gotNetLDU1 = true;
@ -1248,46 +1212,11 @@ bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L
} }
break; break;
case DUID::LDU2: case DUID::LDU2:
if ((data[0U] == DFSIFrameType::LDU2_VOICE10) && (data[22U] == DFSIFrameType::LDU2_VOICE11) && {
(data[36U] == DFSIFrameType::LDU2_VOICE12) && (data[53U] == DFSIFrameType::LDU2_VOICE13) && uint8_t missing = network::BaseNetwork::reconstructLDUVectors(data, len, &m_dfsiLC, DUID::LDU2, m_netLDU2);
(data[70U] == DFSIFrameType::LDU2_VOICE14) && (data[87U] == DFSIFrameType::LDU2_VOICE15) && if (missing > 0U) {
(data[104U] == DFSIFrameType::LDU2_VOICE16) && (data[121U] == DFSIFrameType::LDU2_VOICE17) && LogWarning(LOG_NET, P25_LDU2_STR ", missing %u LDU2 voice frames, srcId = %u, dstId = %u", missing, srcId, dstId);
(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;
m_gotNetLDU2 = true; m_gotNetLDU2 = true;

@ -1252,49 +1252,13 @@ void HostPatch::processP25Network(uint8_t* buffer, uint32_t length)
switch (duid) switch (duid)
{ {
case DUID::LDU1: 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); dfsi::LC dfsiLC = dfsi::LC(control, lsd);
dfsiLC.setFrameType(DFSIFrameType::LDU1_VOICE1); uint8_t missing = BaseNetwork::reconstructLDUVectors(data.get(), frameLength, &dfsiLC, DUID::LDU1, m_netLDU1);
dfsiLC.decodeLDU1(data.get() + count, netLDU + 10U); if (missing > 0) {
count += DFSI_LDU1_VOICE1_FRAME_LENGTH_BYTES; LogWarning(LOG_NET, P25_LDU1_STR ", missing %u voice frames, srcId = %u, dstId = %u", missing, srcId, dstId);
}
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;
LogInfoEx(LOG_NET, P25_LDU1_STR " audio, srcId = %u, dstId = %u", 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; break;
case DUID::LDU2: 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); dfsi::LC dfsiLC = dfsi::LC(control, lsd);
dfsiLC.setFrameType(DFSIFrameType::LDU2_VOICE10); uint8_t missing = BaseNetwork::reconstructLDUVectors(data.get(), frameLength, &dfsiLC, DUID::LDU2, netLDU);
dfsiLC.decodeLDU2(data.get() + count, netLDU + 10U); if (missing > 0) {
count += DFSI_LDU2_VOICE10_FRAME_LENGTH_BYTES; LogWarning(LOG_NET, P25_LDU2_STR ", missing %u voice frames, srcId = %u, dstId = %u", missing, srcId, dstId);
}
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;
LogInfoEx(LOG_NET, P25_LDU2_STR " audio, algo = $%02X, kid = $%04X", dfsiLC.control()->getAlgId(), dfsiLC.control()->getKId()); LogInfoEx(LOG_NET, P25_LDU2_STR " audio, algo = $%02X, kid = $%04X", dfsiLC.control()->getAlgId(), dfsiLC.control()->getKId());

Loading…
Cancel
Save

Powered by TurnKey Linux.