refactor TG hang to only apply to authoritative voice channels; correct handling of non-authoritative permitted destination IDs for NXDN and DMR; move non-authoratative handling into main processNetwork() for P25;

pull/39/head
Bryan Biedenkapp 3 years ago
parent bed079f68e
commit e94964ea2f

@ -349,7 +349,7 @@ void Slot::processNetwork(const data::Data& dmrData)
{ {
// don't process network frames if the RF modem isn't in a listening state // don't process network frames if the RF modem isn't in a listening state
if (m_rfState != RS_RF_LISTENING) { if (m_rfState != RS_RF_LISTENING) {
LogWarning(LOG_NET, "Traffic collision detect, preempting new network traffic to existing RF traffic!"); LogWarning(LOG_NET, "DMR Slot %u, Traffic collision detect, preempting new network traffic to existing RF traffic!", m_slotNo);
return; return;
} }
@ -364,17 +364,25 @@ void Slot::processNetwork(const data::Data& dmrData)
} }
} }
// don't process network frames if the destination ID's don't match and the network TG hang timer is running if (m_authoritative) {
if (m_netLastDstId != 0U && dmrData.getDstId() != 0U && m_netState != RS_NET_IDLE) { // don't process network frames if the destination ID's don't match and the network TG hang timer is running
if (m_netLastDstId != dmrData.getDstId() && (m_netTGHang.isRunning() && !m_netTGHang.hasExpired())) { if (m_netLastDstId != 0U && dmrData.getDstId() != 0U && m_netState != RS_NET_IDLE) {
return; if (m_netLastDstId != dmrData.getDstId() && (m_netTGHang.isRunning() && !m_netTGHang.hasExpired())) {
} return;
}
if (m_netLastDstId == dmrData.getDstId() && (m_netTGHang.isRunning() && !m_netTGHang.hasExpired())) { if (m_netLastDstId == dmrData.getDstId() && (m_netTGHang.isRunning() && !m_netTGHang.hasExpired())) {
m_netTGHang.start(); m_netTGHang.start();
}
} }
} }
// don't process network frames if this modem isn't authoritative
if (!m_authoritative && m_permittedDstId != dmrData.getDstId()) {
LogWarning(LOG_NET, "DMR Slot %u, [NON-AUTHORITATIVE] Ignoring network traffic, destination not permitted!", m_slotNo);
return;
}
m_networkWatchdog.start(); m_networkWatchdog.start();
uint8_t dataType = dmrData.getDataType(); uint8_t dataType = dmrData.getDataType();
@ -526,18 +534,23 @@ void Slot::clock()
} }
} }
if (m_netTGHang.isRunning()) { if (m_authoritative) {
m_netTGHang.clock(ms); if (m_netTGHang.isRunning()) {
m_netTGHang.clock(ms);
if (m_netTGHang.hasExpired()) { if (m_netTGHang.hasExpired()) {
m_netTGHang.stop(); m_netTGHang.stop();
if (m_verbose) { if (m_verbose) {
LogMessage(LOG_NET, "Slot %u, talkgroup hang has expired, lastDstId = %u", m_slotNo, m_netLastDstId); LogMessage(LOG_NET, "Slot %u, talkgroup hang has expired, lastDstId = %u", m_slotNo, m_netLastDstId);
}
m_netLastDstId = 0U;
m_netLastSrcId = 0U;
} }
m_netLastDstId = 0U;
m_netLastSrcId = 0U;
} }
} }
else {
m_netTGHang.stop();
}
if (m_netState == RS_NET_AUDIO || m_netState == RS_NET_DATA) { if (m_netState == RS_NET_AUDIO || m_netState == RS_NET_DATA) {
m_networkWatchdog.clock(ms); m_networkWatchdog.clock(ms);

@ -604,18 +604,23 @@ void Control::clock(uint32_t ms)
} }
} }
if (m_netTGHang.isRunning()) { if (m_authoritative) {
m_netTGHang.clock(ms); if (m_netTGHang.isRunning()) {
m_netTGHang.clock(ms);
if (m_netTGHang.hasExpired()) { if (m_netTGHang.hasExpired()) {
m_netTGHang.stop(); m_netTGHang.stop();
if (m_verbose) { if (m_verbose) {
LogMessage(LOG_NET, "talkgroup hang has expired, lastDstId = %u", m_netLastDstId); LogMessage(LOG_NET, "talkgroup hang has expired, lastDstId = %u", m_netLastDstId);
}
m_netLastDstId = 0U;
m_netLastSrcId = 0U;
} }
m_netLastDstId = 0U;
m_netLastSrcId = 0U;
} }
} }
else {
m_netTGHang.stop();
}
if (m_netState == RS_NET_AUDIO) { if (m_netState == RS_NET_AUDIO) {
m_networkWatchdog.clock(ms); m_networkWatchdog.clock(ms);

@ -94,33 +94,43 @@ using namespace nxdn::packet;
} \ } \
} \ } \
\ \
if (m_nxdn->m_netLastDstId != 0U) { \ if (m_nxdn->m_authoritative) { \
if (m_nxdn->m_netLastDstId != _DST_ID && (m_nxdn->m_netTGHang.isRunning() && !m_nxdn->m_netTGHang.hasExpired())) { \ if (m_nxdn->m_netLastDstId != 0U) { \
return false; \ if (m_nxdn->m_netLastDstId != _DST_ID && (m_nxdn->m_netTGHang.isRunning() && !m_nxdn->m_netTGHang.hasExpired())) { \
return false; \
} \
\
if (m_nxdn->m_netLastDstId == _DST_ID && (m_nxdn->m_netTGHang.isRunning() && !m_nxdn->m_netTGHang.hasExpired())) { \
m_nxdn->m_netTGHang.start(); \
} \
} \ } \
\ \
if (m_nxdn->m_netLastDstId == _DST_ID && (m_nxdn->m_netTGHang.isRunning() && !m_nxdn->m_netTGHang.hasExpired())) { \ if (m_nxdn->m_rfState != RS_RF_LISTENING) { \
m_nxdn->m_netTGHang.start(); \ if (_LAYER3.getSrcId() == _SRC_ID && _LAYER3.getDstId() == _DST_ID) { \
LogWarning(LOG_RF, "Traffic collision detect, preempting new network traffic to existing RF traffic (Are we in a voting condition?), rfSrcId = %u, rfDstId = %u, netSrcId = %u, netDstId = %u", _LAYER3.getSrcId(), _LAYER3.getDstId(), \
_SRC_ID, _DST_ID); \
resetNet(); \
if (m_network != nullptr) \
m_network->resetNXDN(); \
return false; \
} \
else { \
LogWarning(LOG_RF, "Traffic collision detect, preempting new network traffic to existing RF traffic, rfDstId = %u, netDstId = %u", _LAYER3.getDstId(), \
_DST_ID); \
resetNet(); \
if (m_network != nullptr) \
m_network->resetNXDN(); \
return false; \
} \
} \ } \
} \ } \
\ \
if (m_nxdn->m_rfState != RS_RF_LISTENING) { \ if (!m_nxdn->m_authoritative && m_nxdn->m_permittedDstId != dstId) { \
if (_LAYER3.getSrcId() == _SRC_ID && _LAYER3.getDstId() == _DST_ID) { \ LogWarning(LOG_NET, "[NON-AUTHORITATIVE] Ignoring network traffic, destination not permitted!"); \
LogWarning(LOG_RF, "Traffic collision detect, preempting new network traffic to existing RF traffic (Are we in a voting condition?), rfSrcId = %u, rfDstId = %u, netSrcId = %u, netDstId = %u", _LAYER3.getSrcId(), _LAYER3.getDstId(), \ resetNet(); \
_SRC_ID, _DST_ID); \ if (m_network != nullptr) \
resetNet(); \ m_network->resetNXDN(); \
if (m_network != nullptr) \ return false; \
m_network->resetNXDN(); \
return false; \
} \
else { \
LogWarning(LOG_RF, "Traffic collision detect, preempting new network traffic to existing RF traffic, rfDstId = %u, netDstId = %u", _LAYER3.getDstId(), \
_DST_ID); \
resetNet(); \
if (m_network != nullptr) \
m_network->resetNXDN(); \
return false; \
} \
} }
// Validate the source RID // Validate the source RID

@ -764,18 +764,23 @@ void Control::clock(uint32_t ms)
} }
} }
if (m_netTGHang.isRunning()) { if (m_authoritative) {
m_netTGHang.clock(ms); if (m_netTGHang.isRunning()) {
m_netTGHang.clock(ms);
if (m_netTGHang.hasExpired()) { if (m_netTGHang.hasExpired()) {
m_netTGHang.stop(); m_netTGHang.stop();
if (m_verbose) { if (m_verbose) {
LogMessage(LOG_NET, "talkgroup hang has expired, lastDstId = %u", m_netLastDstId); LogMessage(LOG_NET, "talkgroup hang has expired, lastDstId = %u", m_netLastDstId);
}
m_netLastDstId = 0U;
m_netLastSrcId = 0U;
} }
m_netLastDstId = 0U;
m_netLastSrcId = 0U;
} }
} }
else {
m_netTGHang.stop();
}
if (m_netState == RS_NET_AUDIO || m_netState == RS_NET_DATA) { if (m_netState == RS_NET_AUDIO || m_netState == RS_NET_DATA) {
m_networkWatchdog.clock(ms); m_networkWatchdog.clock(ms);

@ -799,35 +799,47 @@ bool Voice::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, data::L
} }
} }
// don't process network frames if the destination ID's don't match and the network TG hang timer is running // perform authoritative network TG hangtimer and traffic preemption
if (m_p25->m_netLastDstId != 0U && dstId != 0U && (duid == P25_DUID_LDU1 || duid == P25_DUID_LDU2)) { if (m_p25->m_authoritative) {
if (m_p25->m_netLastDstId != dstId && (m_p25->m_netTGHang.isRunning() && !m_p25->m_netTGHang.hasExpired())) { // don't process network frames if the destination ID's don't match and the network TG hang timer is running
return false; if (m_p25->m_netLastDstId != 0U && dstId != 0U && (duid == P25_DUID_LDU1 || duid == P25_DUID_LDU2)) {
if (m_p25->m_netLastDstId != dstId && (m_p25->m_netTGHang.isRunning() && !m_p25->m_netTGHang.hasExpired())) {
return false;
}
if (m_p25->m_netLastDstId == dstId && (m_p25->m_netTGHang.isRunning() && !m_p25->m_netTGHang.hasExpired())) {
m_p25->m_netTGHang.start();
}
} }
if (m_p25->m_netLastDstId == dstId && (m_p25->m_netTGHang.isRunning() && !m_p25->m_netTGHang.hasExpired())) { // don't process network frames if the RF modem isn't in a listening state
m_p25->m_netTGHang.start(); if (m_p25->m_rfState != RS_RF_LISTENING) {
if (m_rfLC.getSrcId() == srcId && m_rfLC.getDstId() == dstId) {
LogWarning(LOG_RF, "Traffic collision detect, preempting new network traffic to existing RF traffic (Are we in a voting condition?), rfSrcId = %u, rfDstId = %u, netSrcId = %u, netDstId = %u", m_rfLC.getSrcId(), m_rfLC.getDstId(),
srcId, dstId);
resetNet();
if (m_network != nullptr)
m_network->resetP25();
return false;
}
else {
LogWarning(LOG_RF, "Traffic collision detect, preempting new network traffic to existing RF traffic, rfDstId = %u, netDstId = %u", m_rfLC.getDstId(),
dstId);
resetNet();
if (m_network != nullptr)
m_network->resetP25();
return false;
}
} }
} }
// don't process network frames if the RF modem isn't in a listening state // don't process network frames if this modem isn't authoritative
if (m_p25->m_rfState != RS_RF_LISTENING) { if (!m_p25->m_authoritative && m_p25->m_permittedDstId != dstId) {
if (m_rfLC.getSrcId() == srcId && m_rfLC.getDstId() == dstId) { LogWarning(LOG_NET, "[NON-AUTHORITATIVE] Ignoring network traffic (LDU1), destination not permitted!");
LogWarning(LOG_RF, "Traffic collision detect, preempting new network traffic to existing RF traffic (Are we in a voting condition?), rfSrcId = %u, rfDstId = %u, netSrcId = %u, netDstId = %u", m_rfLC.getSrcId(), m_rfLC.getDstId(), resetNet();
srcId, dstId); if (m_network != nullptr)
resetNet(); m_network->resetP25();
if (m_network != nullptr) return false;
m_network->resetP25();
return false;
}
else {
LogWarning(LOG_RF, "Traffic collision detect, preempting new network traffic to existing RF traffic, rfDstId = %u, netDstId = %u", m_rfLC.getDstId(),
dstId);
resetNet();
if (m_network != nullptr)
m_network->resetP25();
return false;
}
} }
uint32_t count = 0U; uint32_t count = 0U;
@ -1239,13 +1251,6 @@ void Voice::writeNet_LDU1()
} }
} }
// don't process network frames if this modem isn't authoritative
if (!m_p25->m_authoritative && m_p25->m_permittedDstId != dstId) {
LogWarning(LOG_NET, "[NON-AUTHORITATIVE] Ignoring network traffic (LDU1), destination not permitted!");
resetNet();
return;
}
if (m_debug) { if (m_debug) {
LogMessage(LOG_NET, P25_LDU1_STR " service flags, emerg = %u, encrypt = %u, prio = %u, DFSI emerg = %u, DFSI encrypt = %u, DFSI prio = %u", LogMessage(LOG_NET, P25_LDU1_STR " service flags, emerg = %u, encrypt = %u, prio = %u, DFSI emerg = %u, DFSI encrypt = %u, DFSI prio = %u",
control.getEmergency(), control.getEncrypted(), control.getPriority(), control.getEmergency(), control.getEncrypted(), control.getPriority(),

Loading…
Cancel
Save

Powered by TurnKey Linux.