after review, because of how higher-level call handling works, and how ultimately LC metadata corruption from a DFSI source will be hidden, perform similar LC recovery attempts in the ModemV24 class;

pull/126/head
Bryan Biedenkapp 4 months ago
parent 9508ce9404
commit 26f9f3019d

@ -920,6 +920,10 @@ void ModemV24::convertToAirV24(const uint8_t *data, uint32_t length)
lc.setKId(m_rxCall->kId);
lc.setMI(m_rxCall->MI);
m_rxCall->lastLDU1 = lc;
m_rxCall->lastLDU2 = lc;
::memcpy(m_rxCall->lastMI, m_rxCall->MI, MI_LENGTH_BYTES);
// generate Sync
Sync::addP25Sync(buffer + 2U);
@ -1672,13 +1676,54 @@ void ModemV24::convertToAirV24(const uint8_t *data, uint32_t length)
// encode LDU1 if ready
if (duid == DUID::LDU1) {
bool valid = false;
// decode RS (24,12,13) FEC
// bryanb: for now this won't abort the frame if RS fails, but maybe it should in the future, for now
// we'll just log the error
try {
bool ret = m_rs.decode241213(m_rxCall->LDULC);
if (!ret) {
LogError(LOG_MODEM, "V.24/DFSI LDU1, failed to decode RS (24,12,13) FEC");
// ensure our srcId and dstId are sane from the last LDU1
if (m_rxCall->lastLDU1.getDstId() != 0U) {
if (m_rxCall->dstId != m_rxCall->lastLDU1.getDstId()) {
LogWarning(LOG_MODEM, "V.24/DFSI LDU1, dstId = %u doesn't match last LDU1 dstId = %u, fixing",
m_rxCall->dstId, m_rxCall->lastLDU1.getDstId());
m_rxCall->dstId = m_rxCall->lastLDU1.getDstId();
}
}
else {
LogWarning(LOG_MODEM, "V.24/DFSI LDU1, last LDU1 LC has bad data, dstId = 0");
}
if (m_rxCall->lastLDU1.getSrcId() != 0U) {
if (m_rxCall->srcId != m_rxCall->lastLDU1.getSrcId()) {
LogWarning(LOG_MODEM, "V.24/DFSI LDU1, srcId = %u doesn't match last LDU1 srcId = %u, fixing",
m_rxCall->srcId, m_rxCall->lastLDU1.getSrcId());
m_rxCall->srcId = m_rxCall->lastLDU1.getSrcId();
}
}
else {
LogWarning(LOG_MODEM, "V.24/DFSI LDU1, last LDU1 LC has bad data, srcId = 0");
}
// recover LC data using the last known good LDU1
if (m_rxCall->lastLDU1.getSrcId() != 0U && m_rxCall->lastLDU1.getDstId() != 0U) {
m_rxCall->lco = m_rxCall->lastLDU1.getLCO();
m_rxCall->mfId = m_rxCall->lastLDU1.getMFId();
bool emergency = m_rxCall->lastLDU1.getEmergency();
bool encryption = m_rxCall->lastLDU1.getEncrypted();
uint8_t priority = m_rxCall->lastLDU1.getPriority();
m_rxCall->serviceOptions = (emergency ? 0x80U : 0x00U) + // Emergency Flag
(encryption ? 0x40U : 0x00U) + // Encrypted Flag
(priority & 0x07U); // Priority
m_rxCall->srcId = m_rxCall->lastLDU1.getSrcId();
m_rxCall->dstId = m_rxCall->lastLDU1.getDstId();
}
} else {
valid = true;
}
}
catch (...) {
@ -1732,6 +1777,14 @@ void ModemV24::convertToAirV24(const uint8_t *data, uint32_t length)
lc.setEncrypted(encryption);
lc.setPriority(priority);
if (valid)
m_rxCall->lastLDU1 = lc;
if (m_debug) {
LogInfoEx(LOG_MODEM, "V.24/DFSI LDU1, audio, mfId = $%02X srcId = %u, dstId = %u, group = %u, emerg = %u, encrypt = %u, prio = %u, errs = %u/1233 (%.1f%%)",
lc.getMFId(), lc.getSrcId(), lc.getDstId(), lc.getGroup(), lc.getEmergency(), lc.getEncrypted(), lc.getPriority(), m_rxCall->errors, float(m_rxCall->errors) / 12.33F);
}
data::LowSpeedData lsd = data::LowSpeedData();
lsd.setLSD1(m_rxCall->lsd1);
lsd.setLSD2(m_rxCall->lsd2);
@ -1764,20 +1817,42 @@ void ModemV24::convertToAirV24(const uint8_t *data, uint32_t length)
buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x01U;
storeConvertedRx(buffer, P25_LDU_FRAME_LENGTH_BYTES + 2U);
buffer[217U] = (m_rxCall->errors >> 8) & 0xFFU;
buffer[218U] = (m_rxCall->errors >> 0) & 0xFFU;
storeConvertedRx(buffer, P25_LDU_FRAME_LENGTH_BYTES + 4U);
m_rxCall->resetLDU1State();
}
// encode LDU2 if ready
if (duid == DUID::LDU2) {
bool valid = false;
// decode RS (24,16,9) FEC
// bryanb: for now this won't abort the frame if RS fails, but maybe it should in the future, for now
// we'll just log the error
try {
bool ret = m_rs.decode24169(m_rxCall->LDULC);
if (!ret) {
LogError(LOG_MODEM, "V.24/DFSI LDU2, failed to decode RS (24,16,9) FEC");
m_rxCall->algoId = m_rxCall->lastLDU2.getAlgId();
m_rxCall->kId = m_rxCall->lastLDU2.getKId();
// regenerate the MI using LFSR
uint8_t lastMI[MI_LENGTH_BYTES];
::memset(lastMI, 0x00U, MI_LENGTH_BYTES);
uint8_t nextMI[MI_LENGTH_BYTES];
::memset(nextMI, 0x00U, MI_LENGTH_BYTES);
getNextMI(m_rxCall->lastMI, m_rxCall->MI);
if (m_debug) {
Utils::dump(1U, "P25, V.24/LDU2, Previous P25 MI", lastMI, MI_LENGTH_BYTES);
Utils::dump(1U, "P25, V.24/LDU2, Calculated next P25 MI", nextMI, MI_LENGTH_BYTES);
}
} else {
valid = true;
}
}
catch (...) {
@ -1794,6 +1869,26 @@ void ModemV24::convertToAirV24(const uint8_t *data, uint32_t length)
lc.setAlgId(m_rxCall->algoId);
lc.setKId(m_rxCall->kId);
if (valid) {
m_rxCall->lastLDU2 = lc;
::memcpy(m_rxCall->lastMI, m_rxCall->MI, MI_LENGTH_BYTES);
}
if (m_debug) {
LogInfoEx(LOG_MODEM, "V.24/LDU2, audio, algo = $%02X, kid = $%04X, errs = %u/1233 (%.1f%%)",
lc.getAlgId(), lc.getKId(), m_rxCall->errors, float(m_rxCall->errors) / 12.33F);
if (lc.getAlgId() != ALGO_UNENCRYPT) {
uint8_t mi[MI_LENGTH_BYTES];
::memset(mi, 0x00U, MI_LENGTH_BYTES);
lc.getMI(mi);
LogInfoEx(LOG_MODEM, "V.24/LDU2, Enc Sync, MI = %02X %02X %02X %02X %02X %02X %02X %02X %02X",
mi[0U], mi[1U], mi[2U], mi[3U], mi[4U], mi[5U], mi[6U], mi[7U], mi[8U]);
}
}
data::LowSpeedData lsd = data::LowSpeedData();
lsd.setLSD1(m_rxCall->lsd1);
lsd.setLSD2(m_rxCall->lsd2);
@ -1826,7 +1921,11 @@ void ModemV24::convertToAirV24(const uint8_t *data, uint32_t length)
buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x01U;
storeConvertedRx(buffer, P25_LDU_FRAME_LENGTH_BYTES + 2U);
buffer[217U] = (m_rxCall->errors >> 8) & 0xFFU;
buffer[218U] = (m_rxCall->errors >> 0) & 0xFFU;
storeConvertedRx(buffer, P25_LDU_FRAME_LENGTH_BYTES + 4U);
m_rxCall->resetLDU2State();
}
@ -2006,6 +2105,10 @@ void ModemV24::convertToAirTIA(const uint8_t *data, uint32_t length)
lc.setKId(m_rxCall->kId);
lc.setMI(m_rxCall->MI);
m_rxCall->lastLDU1 = lc;
m_rxCall->lastLDU2 = lc;
::memcpy(m_rxCall->lastMI, m_rxCall->MI, MI_LENGTH_BYTES);
// generate Sync
Sync::addP25Sync(buffer + 2U);
@ -2279,13 +2382,54 @@ void ModemV24::convertToAirTIA(const uint8_t *data, uint32_t length)
// encode LDU1 if ready
if (duid == DUID::LDU1) {
bool valid = false;
// decode RS (24,12,13) FEC
// bryanb: for now this won't abort the frame if RS fails, but maybe it should in the future, for now
// we'll just log the error
try {
bool ret = m_rs.decode241213(m_rxCall->LDULC);
if (!ret) {
LogError(LOG_MODEM, "TIA/DFSI LDU1, failed to decode RS (24,12,13) FEC");
// ensure our srcId and dstId are sane from the last LDU1
if (m_rxCall->lastLDU1.getDstId() != 0U) {
if (m_rxCall->dstId != m_rxCall->lastLDU1.getDstId()) {
LogWarning(LOG_MODEM, "TIA/DFSI LDU1, dstId = %u doesn't match last LDU1 dstId = %u, fixing",
m_rxCall->dstId, m_rxCall->lastLDU1.getDstId());
m_rxCall->dstId = m_rxCall->lastLDU1.getDstId();
}
}
else {
LogWarning(LOG_MODEM, "TIA/DFSI LDU1, last LDU1 LC has bad data, dstId = 0");
}
if (m_rxCall->lastLDU1.getSrcId() != 0U) {
if (m_rxCall->srcId != m_rxCall->lastLDU1.getSrcId()) {
LogWarning(LOG_MODEM, "V.24/DFSI LDU1, srcId = %u doesn't match last LDU1 srcId = %u, fixing",
m_rxCall->srcId, m_rxCall->lastLDU1.getSrcId());
m_rxCall->srcId = m_rxCall->lastLDU1.getSrcId();
}
}
else {
LogWarning(LOG_MODEM, "TIA/DFSI LDU1, last LDU1 LC has bad data, srcId = 0");
}
// recover LC data using the last known good LDU1
if (m_rxCall->lastLDU1.getSrcId() != 0U && m_rxCall->lastLDU1.getDstId() != 0U) {
m_rxCall->lco = m_rxCall->lastLDU1.getLCO();
m_rxCall->mfId = m_rxCall->lastLDU1.getMFId();
bool emergency = m_rxCall->lastLDU1.getEmergency();
bool encryption = m_rxCall->lastLDU1.getEncrypted();
uint8_t priority = m_rxCall->lastLDU1.getPriority();
m_rxCall->serviceOptions = (emergency ? 0x80U : 0x00U) + // Emergency Flag
(encryption ? 0x40U : 0x00U) + // Encrypted Flag
(priority & 0x07U); // Priority
m_rxCall->srcId = m_rxCall->lastLDU1.getSrcId();
m_rxCall->dstId = m_rxCall->lastLDU1.getDstId();
}
} else {
valid = true;
}
}
catch (...) {
@ -2339,6 +2483,14 @@ void ModemV24::convertToAirTIA(const uint8_t *data, uint32_t length)
lc.setEncrypted(encryption);
lc.setPriority(priority);
if (valid)
m_rxCall->lastLDU1 = lc;
if (m_debug) {
LogInfoEx(LOG_MODEM, "TIA/DFSI LDU1, audio, mfId = $%02X srcId = %u, dstId = %u, group = %u, emerg = %u, encrypt = %u, prio = %u, errs = %u/1233 (%.1f%%)",
lc.getMFId(), lc.getSrcId(), lc.getDstId(), lc.getGroup(), lc.getEmergency(), lc.getEncrypted(), lc.getPriority(), m_rxCall->errors, float(m_rxCall->errors) / 12.33F);
}
data::LowSpeedData lsd = data::LowSpeedData();
lsd.setLSD1(m_rxCall->lsd1);
lsd.setLSD2(m_rxCall->lsd2);
@ -2371,6 +2523,10 @@ void ModemV24::convertToAirTIA(const uint8_t *data, uint32_t length)
buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x01U;
buffer[217U] = (m_rxCall->errors >> 8) & 0xFFU;
buffer[218U] = (m_rxCall->errors >> 0) & 0xFFU;
storeConvertedRx(buffer, P25_LDU_FRAME_LENGTH_BYTES + 2U);
m_rxCall->resetLDU1State();
@ -2378,13 +2534,31 @@ void ModemV24::convertToAirTIA(const uint8_t *data, uint32_t length)
// encode LDU2 if ready
if (duid == DUID::LDU2) {
bool valid = false;
// decode RS (24,16,9) FEC
// bryanb: for now this won't abort the frame if RS fails, but maybe it should in the future, for now
// we'll just log the error
try {
bool ret = m_rs.decode24169(m_rxCall->LDULC);
if (!ret) {
LogError(LOG_MODEM, "TIA/DFSI LDU2, failed to decode RS (24,16,9) FEC");
m_rxCall->algoId = m_rxCall->lastLDU2.getAlgId();
m_rxCall->kId = m_rxCall->lastLDU2.getKId();
// regenerate the MI using LFSR
uint8_t lastMI[MI_LENGTH_BYTES];
::memset(lastMI, 0x00U, MI_LENGTH_BYTES);
uint8_t nextMI[MI_LENGTH_BYTES];
::memset(nextMI, 0x00U, MI_LENGTH_BYTES);
getNextMI(m_rxCall->lastMI, m_rxCall->MI);
if (m_debug) {
Utils::dump(1U, "P25, TIA/LDU2, Previous P25 MI", lastMI, MI_LENGTH_BYTES);
Utils::dump(1U, "P25, TIA/LDU2, Calculated next P25 MI", nextMI, MI_LENGTH_BYTES);
}
} else {
valid = true;
}
}
catch (...) {
@ -2403,6 +2577,26 @@ void ModemV24::convertToAirTIA(const uint8_t *data, uint32_t length)
lc.setAlgId(m_rxCall->algoId);
lc.setKId(m_rxCall->kId);
if (valid) {
m_rxCall->lastLDU2 = lc;
::memcpy(m_rxCall->lastMI, m_rxCall->MI, MI_LENGTH_BYTES);
}
if (m_debug) {
LogInfoEx(LOG_MODEM, "TIA/LDU2, audio, algo = $%02X, kid = $%04X, errs = %u/1233 (%.1f%%)",
lc.getAlgId(), lc.getKId(), m_rxCall->errors, float(m_rxCall->errors) / 12.33F);
if (lc.getAlgId() != ALGO_UNENCRYPT) {
uint8_t mi[MI_LENGTH_BYTES];
::memset(mi, 0x00U, MI_LENGTH_BYTES);
lc.getMI(mi);
LogInfoEx(LOG_MODEM, "TIA/LDU2, Enc Sync, MI = %02X %02X %02X %02X %02X %02X %02X %02X %02X",
mi[0U], mi[1U], mi[2U], mi[3U], mi[4U], mi[5U], mi[6U], mi[7U], mi[8U]);
}
}
data::LowSpeedData lsd = data::LowSpeedData();
lsd.setLSD1(m_rxCall->lsd1);
lsd.setLSD2(m_rxCall->lsd2);
@ -2435,6 +2629,10 @@ void ModemV24::convertToAirTIA(const uint8_t *data, uint32_t length)
buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x01U;
buffer[217U] = (m_rxCall->errors >> 8) & 0xFFU;
buffer[218U] = (m_rxCall->errors >> 0) & 0xFFU;
storeConvertedRx(buffer, P25_LDU_FRAME_LENGTH_BYTES + 2U);
m_rxCall->resetLDU2State();
@ -3818,3 +4016,27 @@ void ModemV24::convertFromAirTIA(uint8_t* data, uint32_t length, bool imm)
}
}
}
/* Given the last MI, generate the next MI using LFSR. */
void ModemV24::getNextMI(uint8_t lastMI[9U], uint8_t nextMI[9U])
{
uint8_t carry, i;
std::copy(lastMI, lastMI + 9, nextMI);
for (uint8_t cycle = 0; cycle < 64; cycle++) {
// calculate bit 0 for the next cycle
carry = ((nextMI[0] >> 7) ^ (nextMI[0] >> 5) ^ (nextMI[2] >> 5) ^
(nextMI[3] >> 5) ^ (nextMI[4] >> 2) ^ (nextMI[6] >> 6)) &
0x01;
// shift all the list elements, except the last one
for (i = 0; i < 7; i++) {
// grab high bit from the next element and use it as our low bit
nextMI[i] = ((nextMI[i] & 0x7F) << 1) | (nextMI[i + 1] >> 7);
}
// shift last element, then copy the bit 0 we calculated in
nextMI[7] = ((nextMI[i] & 0x7F) << 1) | carry;
}
}

@ -76,11 +76,14 @@ namespace modem
lsd1(0U),
lsd2(0U),
MI(nullptr),
lastMI(nullptr),
algoId(P25DEF::ALGO_UNENCRYPT),
kId(0U),
VHDR1(nullptr),
VHDR2(nullptr),
LDULC(nullptr),
lastLDU1(),
lastLDU2(),
seqNo(0U),
ldu1N(0U),
ldu2N(0U),
@ -96,6 +99,7 @@ namespace modem
errors(0U)
{
MI = new uint8_t[P25DEF::MI_LENGTH_BYTES];
lastMI = new uint8_t[P25DEF::MI_LENGTH_BYTES];
VHDR1 = new uint8_t[P25DFSIDEF::DFSI_MOT_VHDR_1_LEN];
VHDR2 = new uint8_t[P25DFSIDEF::DFSI_MOT_VHDR_2_LEN];
LDULC = new uint8_t[P25DEF::P25_LDU_LC_FEC_LENGTH_BYTES];
@ -120,6 +124,10 @@ namespace modem
delete[] MI;
MI = nullptr;
}
if (lastMI != nullptr) {
delete[] lastMI;
lastMI = nullptr;
}
if (VHDR1 != nullptr) {
delete[] VHDR1;
VHDR1 = nullptr;
@ -167,6 +175,8 @@ namespace modem
if (MI != nullptr)
::memset(MI, 0x00U, P25DEF::MI_LENGTH_BYTES);
if (lastMI != nullptr)
::memset(lastMI, 0x00U, P25DEF::MI_LENGTH_BYTES);
algoId = P25DEF::ALGO_UNENCRYPT;
kId = 0U;
@ -178,6 +188,9 @@ namespace modem
if (LDULC != nullptr)
::memset(LDULC, 0x00U, P25DEF::P25_LDU_LC_FEC_LENGTH_BYTES);
lastLDU1 = p25::lc::LC();
lastLDU2 = p25::lc::LC();
if (netLDU1 != nullptr)
::memset(netLDU1, 0x00U, 9U * 25U);
if (netLDU2 != nullptr)
@ -259,6 +272,10 @@ namespace modem
* @brief Encryption Message Indicator.
*/
uint8_t* MI;
/**
* @brief Last Encryption Message Indicator.
*/
uint8_t* lastMI;
/**
* @brief Encryption Algorithm ID.
*/
@ -281,6 +298,14 @@ namespace modem
* @brief LDU LC.
*/
uint8_t* LDULC;
/**
* @brief Last LDU1 Link Control.
*/
p25::lc::LC lastLDU1;
/**
* @brief Last LDU2 Link Control.
*/
p25::lc::LC lastLDU2;
/**
* @brief Sequence Number.
@ -337,7 +362,7 @@ namespace modem
/**
* @brief Total errors for a given call sequence.
*/
uint32_t errors;
uint16_t errors;
/** @} */
};
@ -752,6 +777,13 @@ namespace modem
* @param imm Flag indicating whether the frame is immediate.
*/
void convertFromAirTIA(uint8_t* data, uint32_t length, bool imm);
/**
* @brief Given the last MI, generate the next MI using LFSR.
* @param lastMI Last MI received.
* @param nextMI Next MI.
*/
void getNextMI(uint8_t lastMI[9U], uint8_t nextMI[9U]);
};
} // namespace modem

@ -656,28 +656,36 @@ bool Control::processFrame(uint8_t* data, uint32_t len)
DUID::E duid = m_nid.getDUID();
// Have we got RSSI bytes on the end of a P25 LDU?
if (len == (P25_LDU_FRAME_LENGTH_BYTES + 4U)) {
uint16_t raw = 0U;
raw |= (data[218U] << 8) & 0xFF00U;
raw |= (data[219U] << 0) & 0x00FFU;
// Convert the raw RSSI to dBm
int rssi = m_rssiMapper->interpolate(raw);
if (m_verbose) {
LogInfoEx(LOG_RF, "P25, raw RSSI = %u, reported RSSI = %d dBm", raw, rssi);
}
// have we got RSSI bytes (or error count for DFSI) on the end of a P25 LDU?
if ((duid == DUID::LDU1 || duid == DUID::LDU2) && len == (P25_LDU_FRAME_LENGTH_BYTES + 4U)) {
if (m_isModemDFSI) {
uint16_t raw = 0U;
raw |= (data[218U] << 8) & 0xFF00U;
raw |= (data[219U] << 0) & 0x00FFU;
m_voice->m_dfsiReportedErrs = raw;
} else {
uint16_t raw = 0U;
raw |= (data[218U] << 8) & 0xFF00U;
raw |= (data[219U] << 0) & 0x00FFU;
// Convert the raw RSSI to dBm
int rssi = m_rssiMapper->interpolate(raw);
if (m_verbose) {
LogInfoEx(LOG_RF, "P25, raw RSSI = %u, reported RSSI = %d dBm", raw, rssi);
}
// RSSI is always reported as positive
m_rssi = (rssi >= 0) ? rssi : -rssi;
// RSSI is always reported as positive
m_rssi = (rssi >= 0) ? rssi : -rssi;
if (m_rssi > m_minRSSI)
m_minRSSI = m_rssi;
if (m_rssi < m_maxRSSI)
m_maxRSSI = m_rssi;
if (m_rssi > m_minRSSI)
m_minRSSI = m_rssi;
if (m_rssi < m_maxRSSI)
m_maxRSSI = m_rssi;
m_aveRSSI += m_rssi;
m_rssiCount++;
m_aveRSSI += m_rssi;
m_rssiCount++;
}
}
if (m_debug) {

@ -57,6 +57,7 @@ void Voice::resetRF()
m_rfFrames = 0U;
m_rfErrs = 0U;
m_dfsiReportedErrs = 0U;
m_rfBits = 1U;
m_rfUndecodableLC = 0U;
m_pktLDU1Count = 0U;
@ -594,6 +595,7 @@ bool Voice::process(uint8_t* data, uint32_t len)
m_rfFrames = 0U;
m_rfErrs = 0U;
m_dfsiReportedErrs = 0U;
m_rfBits = 1U;
m_rfUndecodableLC = 0U;
m_pktLDU1Count = 0U;
@ -646,24 +648,24 @@ bool Voice::process(uint8_t* data, uint32_t len)
// ensure our srcId and dstId are sane from the last LDU1
if (m_rfLastLDU1.getDstId() != 0U) {
if (m_rfLC.getDstId() != m_rfLastLDU1.getDstId()) {
LogWarning(LOG_RF, P25_LDU2_STR ", dstId = %u doesn't match last LDU1 dstId = %u, fixing",
LogWarning(LOG_RF, P25_LDU1_STR ", dstId = %u doesn't match last LDU1 dstId = %u, fixing",
m_rfLC.getDstId(), m_rfLastLDU1.getDstId());
m_rfLC.setDstId(m_rfLastLDU1.getDstId());
}
}
else {
LogWarning(LOG_RF, P25_LDU2_STR ", last LDU1 LC has bad data, dstId = 0");
LogWarning(LOG_RF, P25_LDU1_STR ", last LDU1 LC has bad data, dstId = 0");
}
if (m_rfLastLDU1.getSrcId() != 0U) {
if (m_rfLC.getSrcId() != m_rfLastLDU1.getSrcId()) {
LogWarning(LOG_RF, P25_LDU2_STR ", srcId = %u doesn't match last LDU1 srcId = %u, fixing",
LogWarning(LOG_RF, P25_LDU1_STR ", srcId = %u doesn't match last LDU1 srcId = %u, fixing",
m_rfLC.getSrcId(), m_rfLastLDU1.getSrcId());
m_rfLC.setSrcId(m_rfLastLDU1.getSrcId());
}
}
else {
LogWarning(LOG_RF, P25_LDU2_STR ", last LDU1 LC has bad data, srcId = 0");
LogWarning(LOG_RF, P25_LDU1_STR ", last LDU1 LC has bad data, srcId = 0");
}
m_rfUndecodableLC++;
@ -741,6 +743,11 @@ bool Voice::process(uint8_t* data, uint32_t len)
// regenerate audio
uint32_t errors = m_audio.process(data + 2U);
if (m_p25->m_isModemDFSI) {
errors = m_dfsiReportedErrs; // because the errors will have been "corrected" by the encoders
// within ModemV24 we should use the reported errors from the modem
// and not the audio vectors detected errors
}
// replace audio with silence in cases where the error rate
// has exceeded the configured threshold
@ -858,6 +865,11 @@ bool Voice::process(uint8_t* data, uint32_t len)
// regenerate audio
uint32_t errors = m_audio.process(data + 2U);
if (m_p25->m_isModemDFSI) {
errors = m_dfsiReportedErrs; // because the errors will have been "corrected" by the encoders
// within ModemV24 we should use the reported errors from the modem
// and not the audio vectors detected errors
}
// replace audio with silence in cases where the error rate
// has exceeded the configured threshold
@ -1363,6 +1375,7 @@ Voice::Voice(Control* p25, bool debug, bool verbose) :
m_rfFrames(0U),
m_rfBits(0U),
m_rfErrs(0U),
m_dfsiReportedErrs(0U),
m_rfUndecodableLC(0U),
m_netFrames(0U),
m_netLost(0U),

@ -86,6 +86,7 @@ namespace p25
uint32_t m_rfFrames;
uint32_t m_rfBits;
uint32_t m_rfErrs;
uint16_t m_dfsiReportedErrs;
uint32_t m_rfUndecodableLC;
uint32_t m_netFrames;
uint32_t m_netLost;

Loading…
Cancel
Save

Powered by TurnKey Linux.