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
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;
}
@ -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_netLastDstId != 0U && dmrData.getDstId() != 0U && m_netState != RS_NET_IDLE) {
if (m_netLastDstId != dmrData.getDstId() && (m_netTGHang.isRunning() && !m_netTGHang.hasExpired())) {
return;
}
if (m_authoritative) {
// don't process network frames if the destination ID's don't match and the network TG hang timer is running
if (m_netLastDstId != 0U && dmrData.getDstId() != 0U && m_netState != RS_NET_IDLE) {
if (m_netLastDstId != dmrData.getDstId() && (m_netTGHang.isRunning() && !m_netTGHang.hasExpired())) {
return;
}
if (m_netLastDstId == dmrData.getDstId() && (m_netTGHang.isRunning() && !m_netTGHang.hasExpired())) {
m_netTGHang.start();
if (m_netLastDstId == dmrData.getDstId() && (m_netTGHang.isRunning() && !m_netTGHang.hasExpired())) {
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();
uint8_t dataType = dmrData.getDataType();
@ -526,18 +534,23 @@ void Slot::clock()
}
}
if (m_netTGHang.isRunning()) {
m_netTGHang.clock(ms);
if (m_authoritative) {
if (m_netTGHang.isRunning()) {
m_netTGHang.clock(ms);
if (m_netTGHang.hasExpired()) {
m_netTGHang.stop();
if (m_verbose) {
LogMessage(LOG_NET, "Slot %u, talkgroup hang has expired, lastDstId = %u", m_slotNo, m_netLastDstId);
if (m_netTGHang.hasExpired()) {
m_netTGHang.stop();
if (m_verbose) {
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) {
m_networkWatchdog.clock(ms);

@ -604,18 +604,23 @@ void Control::clock(uint32_t ms)
}
}
if (m_netTGHang.isRunning()) {
m_netTGHang.clock(ms);
if (m_authoritative) {
if (m_netTGHang.isRunning()) {
m_netTGHang.clock(ms);
if (m_netTGHang.hasExpired()) {
m_netTGHang.stop();
if (m_verbose) {
LogMessage(LOG_NET, "talkgroup hang has expired, lastDstId = %u", m_netLastDstId);
if (m_netTGHang.hasExpired()) {
m_netTGHang.stop();
if (m_verbose) {
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_networkWatchdog.clock(ms);

@ -94,33 +94,43 @@ using namespace nxdn::packet;
} \
} \
\
if (m_nxdn->m_netLastDstId != 0U) { \
if (m_nxdn->m_netLastDstId != _DST_ID && (m_nxdn->m_netTGHang.isRunning() && !m_nxdn->m_netTGHang.hasExpired())) { \
return false; \
if (m_nxdn->m_authoritative) { \
if (m_nxdn->m_netLastDstId != 0U) { \
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())) { \
m_nxdn->m_netTGHang.start(); \
if (m_nxdn->m_rfState != RS_RF_LISTENING) { \
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 (_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_authoritative && m_nxdn->m_permittedDstId != dstId) { \
LogWarning(LOG_NET, "[NON-AUTHORITATIVE] Ignoring network traffic, destination not permitted!"); \
resetNet(); \
if (m_network != nullptr) \
m_network->resetNXDN(); \
return false; \
}
// Validate the source RID

@ -764,18 +764,23 @@ void Control::clock(uint32_t ms)
}
}
if (m_netTGHang.isRunning()) {
m_netTGHang.clock(ms);
if (m_authoritative) {
if (m_netTGHang.isRunning()) {
m_netTGHang.clock(ms);
if (m_netTGHang.hasExpired()) {
m_netTGHang.stop();
if (m_verbose) {
LogMessage(LOG_NET, "talkgroup hang has expired, lastDstId = %u", m_netLastDstId);
if (m_netTGHang.hasExpired()) {
m_netTGHang.stop();
if (m_verbose) {
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) {
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
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;
// perform authoritative network TG hangtimer and traffic preemption
if (m_p25->m_authoritative) {
// don't process network frames if the destination ID's don't match and the network TG hang timer is running
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())) {
m_p25->m_netTGHang.start();
// don't process network frames if the RF modem isn't in a listening state
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
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 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();
if (m_network != nullptr)
m_network->resetP25();
return false;
}
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) {
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(),

Loading…
Cancel
Save

Powered by TurnKey Linux.