From 015b9e2f0ad3832ef57edcbc22121e02a93924ca Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Tue, 3 Oct 2023 16:29:34 -0400 Subject: [PATCH] add support to test TG grant status when determining sloppy-voting overlap; ensure RF states are returned to RS_RF_LISTENING upon failure (don't assume state); --- src/dmr/packet/Data.cpp | 9 ++++++++ src/dmr/packet/Voice.cpp | 9 ++++++++ src/nxdn/packet/Data.cpp | 2 ++ src/nxdn/packet/Voice.cpp | 16 +++++++++++-- src/p25/packet/Voice.cpp | 48 ++++++++++++++++++++++++++++++++++++++- 5 files changed, 81 insertions(+), 3 deletions(-) diff --git a/src/dmr/packet/Data.cpp b/src/dmr/packet/Data.cpp index 90fbce60..d65adc5c 100644 --- a/src/dmr/packet/Data.cpp +++ b/src/dmr/packet/Data.cpp @@ -54,6 +54,7 @@ using namespace dmr::packet; #define CHECK_AUTHORITATIVE(_DST_ID) \ if (!m_slot->m_authoritative && m_slot->m_permittedDstId != dstId) { \ LogWarning(LOG_RF, "[NON-AUTHORITATIVE] Ignoring RF traffic, destination not permitted!"); \ + m_slot->m_rfState = RS_RF_LISTENING; \ return false; \ } @@ -66,7 +67,15 @@ using namespace dmr::packet; #define CHECK_TRAFFIC_COLLISION(_DST_ID) \ if (m_slot->m_netState != RS_NET_IDLE && _DST_ID == m_slot->m_netLastDstId) { \ LogWarning(LOG_RF, "DMR Slot %u, Traffic collision detect, preempting new RF traffic to existing network traffic!", m_slot->m_slotNo); \ + m_slot->m_rfState = RS_RF_LISTENING; \ return false; \ + } \ + if (m_slot->m_enableTSCC && _DST_ID == m_slot->m_netLastDstId) { \ + if (m_slot->m_affiliations->isNetGranted(_DST_ID)) { \ + LogWarning(LOG_RF, "DMR Slot %u, Traffic collision detect, preempting new RF traffic to existing granted network traffic (Are we in a voting condition?)", m_slot->m_slotNo); \ + m_slot->m_rfState = RS_RF_LISTENING; \ + return false; \ + } \ } #define CHECK_TG_HANG(_DST_ID) \ diff --git a/src/dmr/packet/Voice.cpp b/src/dmr/packet/Voice.cpp index 8db5be99..906dae65 100644 --- a/src/dmr/packet/Voice.cpp +++ b/src/dmr/packet/Voice.cpp @@ -56,6 +56,7 @@ using namespace dmr::packet; #define CHECK_AUTHORITATIVE(_DST_ID) \ if (!m_slot->m_authoritative && m_slot->m_permittedDstId != _DST_ID) { \ LogWarning(LOG_RF, "[NON-AUTHORITATIVE] Ignoring RF traffic, destination not permitted, dstId = %u", _DST_ID); \ + m_slot->m_rfState = RS_RF_LISTENING; \ return false; \ } @@ -67,7 +68,15 @@ using namespace dmr::packet; #define CHECK_TRAFFIC_COLLISION(_DST_ID) \ if (m_slot->m_netState != RS_NET_IDLE && _DST_ID == m_slot->m_netLastDstId) { \ LogWarning(LOG_RF, "DMR Slot %u, Traffic collision detect, preempting new RF traffic to existing network traffic!", m_slot->m_slotNo); \ + m_slot->m_rfState = RS_RF_LISTENING; \ return false; \ + } \ + if (m_slot->m_enableTSCC && _DST_ID == m_slot->m_netLastDstId) { \ + if (m_slot->m_affiliations->isNetGranted(_DST_ID)) { \ + LogWarning(LOG_RF, "DMR Slot %u, Traffic collision detect, preempting new RF traffic to existing granted network traffic (Are we in a voting condition?)", m_slot->m_slotNo); \ + m_slot->m_rfState = RS_RF_LISTENING; \ + return false; \ + } \ } // Don't process network frames if the destination ID's don't match and the network TG hang diff --git a/src/nxdn/packet/Data.cpp b/src/nxdn/packet/Data.cpp index a3de0b7a..235935bb 100644 --- a/src/nxdn/packet/Data.cpp +++ b/src/nxdn/packet/Data.cpp @@ -59,6 +59,7 @@ using namespace nxdn::packet; if (m_nxdn->m_netState != RS_NET_IDLE && _DST_ID == m_nxdn->m_netLastDstId) { \ LogWarning(LOG_RF, "Traffic collision detect, preempting new RF traffic to existing network traffic!"); \ resetRF(); \ + m_nxdn->m_rfState = RS_RF_LISTENING; \ return false; \ } \ \ @@ -67,6 +68,7 @@ using namespace nxdn::packet; LogWarning(LOG_RF, "Traffic collision detect, preempting new RF traffic to existing RF traffic (Are we in a voting condition?), rfSrcId = %u, rfDstId = %u, netSrcId = %u, netDstId = %u", srcId, dstId, \ m_nxdn->m_netLC.getSrcId(), m_nxdn->m_netLastDstId); \ resetRF(); \ + m_nxdn->m_rfState = RS_RF_LISTENING; \ return false; \ } \ else { \ diff --git a/src/nxdn/packet/Voice.cpp b/src/nxdn/packet/Voice.cpp index 64bc5305..9da74dfa 100644 --- a/src/nxdn/packet/Voice.cpp +++ b/src/nxdn/packet/Voice.cpp @@ -61,22 +61,34 @@ using namespace nxdn::packet; if (m_nxdn->m_netState != RS_NET_IDLE && _DST_ID == m_nxdn->m_netLastDstId) { \ LogWarning(LOG_RF, "Traffic collision detect, preempting new RF traffic to existing network traffic!"); \ resetRF(); \ + m_nxdn->m_rfState = RS_RF_LISTENING; \ return false; \ } \ \ if (m_nxdn->m_netState != RS_NET_IDLE) { \ if (m_nxdn->m_netLC.getSrcId() == _SRC_ID && m_nxdn->m_netLastDstId == _DST_ID) { \ - LogWarning(LOG_RF, "Traffic collision detect, preempting new RF traffic to existing RF traffic (Are we in a voting condition?), rfSrcId = %u, rfDstId = %u, netSrcId = %u, netDstId = %u", srcId, dstId, \ + LogWarning(LOG_RF, "Traffic collision detect, preempting new RF traffic to existing RF traffic (Are we in a voting condition?), rfSrcId = %u, rfDstId = %u, netSrcId = %u, netDstId = %u", _SRC_ID, _DST_ID, \ m_nxdn->m_netLC.getSrcId(), m_nxdn->m_netLastDstId); \ resetRF(); \ + m_nxdn->m_rfState = RS_RF_LISTENING; \ return false; \ } \ else { \ - LogWarning(LOG_RF, "Traffic collision detect, preempting existing network traffic to new RF traffic, rfDstId = %u, netDstId = %u", dstId, \ + LogWarning(LOG_RF, "Traffic collision detect, preempting existing network traffic to new RF traffic, rfDstId = %u, netDstId = %u", _DST_ID, \ m_nxdn->m_netLastDstId); \ resetNet(); \ if (m_nxdn->m_network != nullptr) \ m_nxdn->m_network->resetNXDN(); \ + } \ + \ + if (m_nxdn->m_enableControl && _DST_ID == m_nxdn->m_netLastDstId) { \ + if (m_nxdn->m_affiliations.isNetGranted(_DST_ID)) { \ + LogWarning(LOG_RF, "Traffic collision detect, preempting new RF traffic to existing granted network traffic (Are we in a voting condition?), rfSrcId = %u, rfDstId = %u, netSrcId = %u, netDstId = %u", _SRC_ID, _DST_ID, \ + m_nxdn->m_netLC.getSrcId(), m_nxdn->m_netLastDstId); \ + resetRF(); \ + m_nxdn->m_rfState = RS_RF_LISTENING; \ + return false; \ + } \ } \ } diff --git a/src/p25/packet/Voice.cpp b/src/p25/packet/Voice.cpp index 9e1a7a44..a0d71dd7 100644 --- a/src/p25/packet/Voice.cpp +++ b/src/p25/packet/Voice.cpp @@ -160,6 +160,7 @@ bool Voice::process(uint8_t* data, uint32_t len) if (!m_p25->m_authoritative && m_p25->m_permittedDstId != lc.getDstId()) { LogWarning(LOG_RF, "[NON-AUTHORITATIVE] Ignoring RF traffic, destination not permitted!"); resetRF(); + m_p25->m_rfState = RS_RF_LISTENING; return false; } @@ -167,6 +168,7 @@ bool Voice::process(uint8_t* data, uint32_t len) if (m_p25->m_netState != RS_NET_IDLE && lc.getDstId() == m_p25->m_netLastDstId) { LogWarning(LOG_RF, "Traffic collision detect, preempting new RF traffic to existing network traffic!"); resetRF(); + m_p25->m_rfState = RS_RF_LISTENING; return false; } @@ -236,6 +238,7 @@ bool Voice::process(uint8_t* data, uint32_t len) if (!m_p25->m_authoritative && m_p25->m_permittedDstId != lc.getDstId()) { LogWarning(LOG_RF, "[NON-AUTHORITATIVE] Ignoring RF traffic, destination not permitted!"); resetRF(); + m_p25->m_rfState = RS_RF_LISTENING; return false; } @@ -243,15 +246,17 @@ bool Voice::process(uint8_t* data, uint32_t len) if (m_p25->m_netState != RS_NET_IDLE && dstId == m_p25->m_netLastDstId) { LogWarning(LOG_RF, "Traffic collision detect, preempting new RF traffic to existing network traffic!"); resetRF(); + m_p25->m_rfState = RS_RF_LISTENING; return false; } // stop network frames from processing -- RF wants to transmit on a different talkgroup if (m_p25->m_netState != RS_NET_IDLE) { if (m_netLC.getSrcId() == srcId && m_p25->m_netLastDstId == dstId) { - LogWarning(LOG_RF, "Traffic collision detect, preempting new RF traffic to existing RF traffic (Are we in a voting condition?), rfSrcId = %u, rfDstId = %u, netSrcId = %u, netDstId = %u", srcId, dstId, + LogWarning(LOG_RF, "Traffic collision detect, preempting new RF traffic to existing network traffic (Are we in a voting condition?), rfSrcId = %u, rfDstId = %u, netSrcId = %u, netDstId = %u", srcId, dstId, m_netLC.getSrcId(), m_p25->m_netLastDstId); resetRF(); + m_p25->m_rfState = RS_RF_LISTENING; return false; } else { @@ -271,6 +276,17 @@ bool Voice::process(uint8_t* data, uint32_t len) m_p25->m_netTGHang.stop(); } + + // is control is enabled, and the group was granted by network already ignore RF traffic + if (m_p25->m_enableControl && dstId == m_p25->m_netLastDstId) { + if (m_p25->m_affiliations.isNetGranted(dstId)) { + LogWarning(LOG_RF, "Traffic collision detect, preempting new RF traffic to existing granted network traffic (Are we in a voting condition?), rfSrcId = %u, rfDstId = %u, netSrcId = %u, netDstId = %u", srcId, dstId, + m_netLC.getSrcId(), m_p25->m_netLastDstId); + resetRF(); + m_p25->m_rfState = RS_RF_LISTENING; + return false; + } + } } // if this is a late entry call, clear states @@ -486,6 +502,36 @@ bool Voice::process(uint8_t* data, uint32_t len) } if (m_p25->m_rfState == RS_RF_AUDIO) { + // don't process RF frames if this modem isn't authoritative + if (!m_p25->m_authoritative && m_p25->m_permittedDstId != m_rfLC.getDstId()) { + LogWarning(LOG_RF, "[NON-AUTHORITATIVE] Ignoring RF traffic, destination not permitted!"); + resetRF(); + m_p25->m_rfState = RS_RF_LISTENING; + return false; + } + + // stop network frames from processing -- RF wants to transmit on a different talkgroup + if (m_p25->m_netState != RS_NET_IDLE) { + if (m_netLC.getSrcId() == m_rfLC.getSrcId() && m_p25->m_netLastDstId == m_rfLC.getDstId()) { + LogWarning(LOG_RF, "Traffic collision detect, preempting new RF traffic to existing network traffic (Are we in a voting condition?), rfSrcId = %u, rfDstId = %u, netSrcId = %u, netDstId = %u", m_rfLC.getSrcId(), m_rfLC.getDstId(), + m_netLC.getSrcId(), m_p25->m_netLastDstId); + resetRF(); + m_p25->m_rfState = RS_RF_LISTENING; + return false; + } + + // is control is enabled, and the group was granted by network already ignore RF traffic + if (m_p25->m_enableControl && m_rfLC.getDstId() == m_p25->m_netLastDstId) { + if (m_p25->m_affiliations.isNetGranted(m_rfLC.getDstId())) { + LogWarning(LOG_RF, "Traffic collision detect, preempting new RF traffic to existing granted network traffic (Are we in a voting condition?), rfSrcId = %u, rfDstId = %u, netSrcId = %u, netDstId = %u", m_rfLC.getSrcId(), m_rfLC.getDstId(), + m_netLC.getSrcId(), m_p25->m_netLastDstId); + resetRF(); + m_p25->m_rfState = RS_RF_LISTENING; + return false; + } + } + } + if (!alreadyDecoded) { bool ret = m_rfLC.decodeLDU1(data + 2U); if (!ret) {