experimental alteration to handling modem TAG_LOST during an active call for DMR, P25 and NXDN, instead of immediately dropping the call stream holding the call in progress, this will likely require additional thought and implementation, but the intention is to correct odd behavior for fringe or silghtly weak signals which would cause strange call behavior;

pull/32/head
Bryan Biedenkapp 3 years ago
parent d5aa4c2cd9
commit b99ecefd6a

@ -45,6 +45,12 @@ using namespace dmr::packet;
#include <algorithm>
#include <cmath>
// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------
const uint8_t MAX_LOST_FRAMES = 4U;
// ---------------------------------------------------------------------------
// Static Class Members
// ---------------------------------------------------------------------------
@ -152,6 +158,7 @@ Slot::Slot(uint32_t slotNo, uint32_t timeout, uint32_t tgHang, uint32_t queueSiz
m_aveRSSI(0U),
m_rssiCount(0U),
m_silenceThreshold(DEFAULT_SILENCE_THRESHOLD),
m_frameLossCnt(0U),
m_ccSeq(0U),
m_ccRunning(false),
m_ccPrevRunning(false),
@ -195,7 +202,11 @@ bool Slot::processFrame(uint8_t *data, uint32_t len)
{
assert(data != nullptr);
if (data[0U] == modem::TAG_LOST && m_rfState == RS_RF_AUDIO) {
if (data[0U] == modem::TAG_LOST) {
if (m_frameLossCnt > MAX_LOST_FRAMES) {
m_frameLossCnt = 0U;
if (m_rfState == RS_RF_AUDIO) {
if (m_rssi != 0U) {
::ActivityLog("DMR", true, "Slot %u RF voice transmission lost, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm",
m_slotNo, float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
@ -230,18 +241,37 @@ bool Slot::processFrame(uint8_t *data, uint32_t len)
}
}
if (data[0U] == modem::TAG_LOST && m_rfState == RS_RF_DATA) {
if (m_rfState == RS_RF_DATA) {
::ActivityLog("DMR", true, "Slot %u, RF data transmission lost", m_slotNo);
writeEndRF();
return false;
}
if (data[0U] == modem::TAG_LOST) {
m_rfState = RS_RF_LISTENING;
m_rfLastDstId = 0U;
m_rfTGHang.stop();
return false;
}
else {
// increment the frame loss count by one for audio or data; otherwise drop
// packets
if (m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA) {
++m_frameLossCnt;
}
else {
// drop normally
m_frameLossCnt = 0U;
m_rfState = RS_RF_LISTENING;
m_rfLastDstId = 0U;
m_rfTGHang.stop();
return false;
}
}
}
// Have we got RSSI bytes on the end?
if (len == (DMR_FRAME_LENGTH_BYTES + 4U)) {

@ -194,6 +194,8 @@ namespace dmr
uint32_t m_silenceThreshold;
uint8_t m_frameLossCnt;
uint8_t m_ccSeq;
bool m_ccRunning;
bool m_ccPrevRunning;

@ -58,6 +58,8 @@ using namespace nxdn::packet;
const uint8_t MAX_SYNC_BYTES_ERRS = 0U;
const uint8_t MAX_LOST_FRAMES = 4U;
const uint8_t SCRAMBLER[] = {
0x00U, 0x00U, 0x00U, 0x82U, 0xA0U, 0x88U, 0x8AU, 0x00U, 0xA2U, 0xA8U, 0x82U, 0x8AU, 0x82U, 0x02U,
0x20U, 0x08U, 0x8AU, 0x20U, 0xAAU, 0xA2U, 0x82U, 0x08U, 0x22U, 0x8AU, 0xAAU, 0x08U, 0x28U, 0x88U,
@ -130,6 +132,7 @@ Control::Control(bool authoritative, uint32_t ran, uint32_t callHang, uint32_t q
m_netTimeout(1000U, timeout),
m_networkWatchdog(1000U, 0U, 1500U),
m_ccPacketInterval(1000U, 0U, 80U),
m_frameLossCnt(0U),
m_ccFrameCnt(0U),
m_ccSeq(0U),
m_siteData(),
@ -355,10 +358,13 @@ bool Control::processFrame(uint8_t* data, uint32_t len)
{
assert(data != nullptr);
uint8_t type = data[0U];
bool sync = data[1U] == 0x01U;
if (type == modem::TAG_LOST && m_rfState == RS_RF_AUDIO) {
if (data[0U] == modem::TAG_LOST) {
if (m_frameLossCnt > MAX_LOST_FRAMES) {
m_frameLossCnt = 0U;
if (m_rfState == RS_RF_AUDIO) {
if (m_rssi != 0U) {
::ActivityLog("NXDN", true, "transmission lost, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm",
float(m_voice->m_rfFrames) / 12.5F, float(m_voice->m_rfErrs * 100U) / float(m_voice->m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
@ -380,19 +386,37 @@ bool Control::processFrame(uint8_t* data, uint32_t len)
return false;
}
if (type == modem::TAG_LOST && m_rfState == RS_RF_DATA) {
if (m_rfState == RS_RF_DATA) {
writeEndRF();
return false;
}
if (type == modem::TAG_LOST) {
m_rfState = RS_RF_LISTENING;
m_rfMask = 0x00U;
m_rfLC.reset();
return false;
}
else {
// increment the frame loss count by one for audio or data; otherwise drop
// packets
if (m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA) {
++m_frameLossCnt;
}
else {
m_frameLossCnt = 0U;
m_rfState = RS_RF_LISTENING;
m_rfMask = 0x00U;
m_rfLC.reset();
return false;
}
}
}
// Have we got RSSI bytes on the end?
// have we got RSSI bytes on the end?
if (len == (NXDN_FRAME_LENGTH_BYTES + 4U)) {
uint16_t raw = 0U;
raw |= (data[50U] << 8) & 0xFF00U;

@ -188,6 +188,8 @@ namespace nxdn
Timer m_ccPacketInterval;
uint8_t m_frameLossCnt;
uint8_t m_ccFrameCnt;
uint8_t m_ccSeq;

@ -58,6 +58,8 @@ const uint8_t MAX_SYNC_BYTES_ERRS = 4U;
const uint32_t TSBK_PCH_CCH_CNT = 6U;
const uint32_t MAX_PREAMBLE_TDU_CNT = 64U;
const uint8_t MAX_LOST_FRAMES = 4U;
// ---------------------------------------------------------------------------
// Public Class Members
// ---------------------------------------------------------------------------
@ -130,6 +132,7 @@ Control::Control(bool authoritative, uint32_t nac, uint32_t callHang, uint32_t q
m_ccPacketInterval(1000U, 0U, 10U),
m_hangCount(3U * 8U),
m_tduPreambleCount(8U),
m_frameLossCnt(0U),
m_ccFrameCnt(0U),
m_ccSeq(0U),
m_nid(nac),
@ -440,7 +443,11 @@ bool Control::processFrame(uint8_t* data, uint32_t len)
bool sync = data[1U] == 0x01U;
if (data[0U] == modem::TAG_LOST && m_rfState == RS_RF_AUDIO) {
if (data[0U] == modem::TAG_LOST) {
if (m_frameLossCnt > MAX_LOST_FRAMES) {
m_frameLossCnt = 0U;
if (m_rfState == RS_RF_AUDIO) {
if (m_rssi != 0U) {
::ActivityLog("P25", true, "transmission lost, %.1f seconds, BER: %.1f%%, RSSI: -%u/-%u/-%u dBm",
float(m_voice->m_rfFrames) / 5.56F, float(m_voice->m_rfErrs * 100U) / float(m_voice->m_rfBits), m_minRSSI, m_maxRSSI, m_aveRSSI / m_rssiCount);
@ -478,7 +485,7 @@ bool Control::processFrame(uint8_t* data, uint32_t len)
return false;
}
if (data[0U] == modem::TAG_LOST && m_rfState == RS_RF_DATA) {
if (m_rfState == RS_RF_DATA) {
m_rfState = RS_RF_LISTENING;
m_rfLastDstId = 0U;
m_rfTGHang.stop();
@ -493,7 +500,6 @@ bool Control::processFrame(uint8_t* data, uint32_t len)
return false;
}
if (data[0U] == modem::TAG_LOST) {
m_rfState = RS_RF_LISTENING;
m_voice->resetRF();
@ -501,6 +507,23 @@ bool Control::processFrame(uint8_t* data, uint32_t len)
return false;
}
else {
// increment the frame loss count by one for audio or data; otherwise drop
// packets
if (m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA) {
++m_frameLossCnt;
}
else {
m_frameLossCnt = 0U;
m_rfState = RS_RF_LISTENING;
m_voice->resetRF();
m_data->resetRF();
return false;
}
}
}
if (!sync && m_rfState == RS_RF_LISTENING) {
uint8_t syncBytes[P25_SYNC_LENGTH_BYTES];

@ -206,6 +206,8 @@ namespace p25
uint32_t m_hangCount;
uint32_t m_tduPreambleCount;
uint8_t m_frameLossCnt;
uint8_t m_ccFrameCnt;
uint8_t m_ccSeq;

Loading…
Cancel
Save

Powered by TurnKey Linux.