implement missing rfLossWatchdog on DMR and NXDN (this fixes edge case issues where end of call single frame loss could cause a call to not terminate properly);

3.5-maint
Bryan Biedenkapp 2 years ago
parent 481ee51229
commit 19190ce69d

@ -133,6 +133,7 @@ Slot::Slot(uint32_t slotNo, uint32_t timeout, uint32_t tgHang, uint32_t queueSiz
m_networkWatchdog(1000U, 0U, 1500U),
m_rfTimeoutTimer(1000U, timeout),
m_rfTGHang(1000U, tgHang),
m_rfLossWatchdog(1000U, 0U, 1500U),
m_netTimeoutTimer(1000U, timeout),
m_netTGHang(1000U, 2U),
m_packetTimer(1000U, 0U, 50U),
@ -212,6 +213,7 @@ bool Slot::processFrame(uint8_t *data, uint32_t len)
// 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_rfLossWatchdog.start();
++m_frameLossCnt;
}
else {
@ -228,6 +230,12 @@ bool Slot::processFrame(uint8_t *data, uint32_t len)
}
}
if (m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA) {
if (m_rfLossWatchdog.isRunning()) {
m_rfLossWatchdog.start();
}
}
// Have we got RSSI bytes on the end?
if (len == (DMR_FRAME_LENGTH_BYTES + 4U)) {
uint16_t raw = 0U;
@ -495,7 +503,10 @@ void Slot::clock()
}
}
// handle timeouts and hang timers
m_rfTimeoutTimer.clock(ms);
m_netTimeoutTimer.clock(ms);
if (m_rfTimeoutTimer.isRunning() && m_rfTimeoutTimer.hasExpired()) {
if (!m_rfTimeout) {
LogMessage(LOG_RF, "DMR Slot %u, user has timed out", m_slotNo);
@ -503,11 +514,15 @@ void Slot::clock()
}
}
m_netTimeoutTimer.clock(ms);
if (m_netTimeoutTimer.isRunning() && m_netTimeoutTimer.hasExpired()) {
if (!m_netTimeout) {
LogMessage(LOG_NET, "DMR Slot %u, user has timed out", m_slotNo);
m_netTimeout = true;
if (m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA) {
if (m_rfLossWatchdog.isRunning()) {
m_rfLossWatchdog.clock(ms);
if (m_rfLossWatchdog.hasExpired()) {
m_rfLossWatchdog.stop();
processFrameLoss();
}
}
}
@ -529,6 +544,13 @@ void Slot::clock()
}
}
if (m_netTimeoutTimer.isRunning() && m_netTimeoutTimer.hasExpired()) {
if (!m_netTimeout) {
LogMessage(LOG_NET, "DMR Slot %u, user has timed out", m_slotNo);
m_netTimeout = true;
}
}
if (m_authoritative) {
if (m_netTGHang.isRunning()) {
m_netTGHang.clock(ms);
@ -1008,6 +1030,8 @@ void Slot::processFrameLoss()
}
}
clearTSCCActivated();
if (!m_tscc->m_enableTSCC) {
notifyCC_ReleaseGrant(m_rfLC->getDstId());
}

@ -175,6 +175,7 @@ namespace dmr
Timer m_networkWatchdog;
Timer m_rfTimeoutTimer;
Timer m_rfTGHang;
Timer m_rfLossWatchdog;
Timer m_netTimeoutTimer;
Timer m_netTGHang;
Timer m_packetTimer;

@ -130,6 +130,7 @@ Control::Control(bool authoritative, uint32_t ran, uint32_t callHang, uint32_t q
m_ccHalted(false),
m_rfTimeout(1000U, timeout),
m_rfTGHang(1000U, tgHang),
m_rfLossWatchdog(1000U, 0U, 1500U),
m_netTimeout(1000U, timeout),
m_netTGHang(1000U, 2U),
m_networkWatchdog(1000U, 0U, 1500U),
@ -394,6 +395,7 @@ bool Control::processFrame(uint8_t* data, uint32_t len)
// 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_rfLossWatchdog.start();
++m_frameLossCnt;
}
else {
@ -408,6 +410,12 @@ bool Control::processFrame(uint8_t* data, uint32_t len)
}
}
if (m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA) {
if (m_rfLossWatchdog.isRunning()) {
m_rfLossWatchdog.start();
}
}
// have we got RSSI bytes on the end?
if (len == (NXDN_FRAME_LENGTH_BYTES + 4U)) {
uint16_t raw = 0U;
@ -621,6 +629,18 @@ void Control::clock(uint32_t ms)
}
}
}
if (m_rfState == RS_RF_AUDIO || m_rfState == RS_RF_DATA) {
if (m_rfLossWatchdog.isRunning()) {
m_rfLossWatchdog.clock(ms);
if (m_rfLossWatchdog.hasExpired()) {
m_rfLossWatchdog.stop();
processFrameLoss();
}
}
}
if (m_authoritative) {
if (m_netTGHang.isRunning()) {

@ -191,6 +191,7 @@ namespace nxdn
Timer m_rfTimeout;
Timer m_rfTGHang;
Timer m_rfLossWatchdog;
Timer m_netTimeout;
Timer m_netTGHang;
Timer m_networkWatchdog;

Loading…
Cancel
Save

Powered by TurnKey Linux.