diff --git a/src/host/dmr/Slot.cpp b/src/host/dmr/Slot.cpp index 0b7662b5..263848ed 100644 --- a/src/host/dmr/Slot.cpp +++ b/src/host/dmr/Slot.cpp @@ -459,7 +459,7 @@ void Slot::processNetwork(const data::NetData& dmrData) bool unitToUnit = (dmrData.getControl() & network::NET_CTRL_U2U) == network::NET_CTRL_U2U; if (grantDemand) { - if (s_network->disallowUnitToUnit() && unitToUnit) { + if (s_network != nullptr && s_network->disallowUnitToUnit() && unitToUnit) { break; } diff --git a/src/host/dmr/packet/Data.cpp b/src/host/dmr/packet/Data.cpp index 1f1cbaa5..074e0fb3 100644 --- a/src/host/dmr/packet/Data.cpp +++ b/src/host/dmr/packet/Data.cpp @@ -441,7 +441,7 @@ void Data::processNetwork(const data::NetData& dmrData) uint32_t srcId = m_netDataHeader.getSrcId(); uint32_t dstId = m_netDataHeader.getDstId(); - if (m_slot->s_network->disallowUnitToUnit() && !gi) { + if (m_slot->s_network != nullptr && m_slot->s_network->disallowUnitToUnit() && !gi) { LogWarning(LOG_NET, "DMR Slot %u, rejecting network individual data call, srcId = %u, dstId = %u", m_slot->m_slotNo, srcId, dstId); return; diff --git a/src/host/dmr/packet/Voice.cpp b/src/host/dmr/packet/Voice.cpp index e218ef94..bb5ae3c9 100644 --- a/src/host/dmr/packet/Voice.cpp +++ b/src/host/dmr/packet/Voice.cpp @@ -781,7 +781,7 @@ void Voice::processNetwork(const data::NetData& dmrData) uint32_t dstId = lc->getDstId(); FLCO::E flco = lc->getFLCO(); - if (m_slot->s_network->disallowUnitToUnit() && flco == FLCO::PRIVATE) { + if (m_slot->s_network != nullptr && m_slot->s_network->disallowUnitToUnit() && flco == FLCO::PRIVATE) { LogWarning(LOG_NET, "DMR Slot %u, rejecting network unit-to-unit voice call, srcId = %u, dstId = %u", m_slot->m_slotNo, srcId, dstId); return; @@ -877,7 +877,7 @@ void Voice::processNetwork(const data::NetData& dmrData) if (m_slot->m_netState != RS_NET_AUDIO) { std::unique_ptr lc = std::make_unique(dmrData.getFLCO(), dmrData.getSrcId(), dmrData.getDstId()); - if (m_slot->s_network->disallowUnitToUnit() && lc->getFLCO() == FLCO::PRIVATE) { + if (m_slot->s_network != nullptr && m_slot->s_network->disallowUnitToUnit() && lc->getFLCO() == FLCO::PRIVATE) { return; } @@ -988,7 +988,7 @@ void Voice::processNetwork(const data::NetData& dmrData) if (m_slot->m_netState == RS_NET_IDLE) { std::unique_ptr lc = std::make_unique(dmrData.getFLCO(), dmrData.getSrcId(), dmrData.getDstId()); - if (m_slot->s_network->disallowUnitToUnit() && lc->getFLCO() == FLCO::PRIVATE) { + if (m_slot->s_network != nullptr && m_slot->s_network->disallowUnitToUnit() && lc->getFLCO() == FLCO::PRIVATE) { return; } diff --git a/src/host/nxdn/packet/ControlSignaling.cpp b/src/host/nxdn/packet/ControlSignaling.cpp index 60e799a3..8f0a8e24 100644 --- a/src/host/nxdn/packet/ControlSignaling.cpp +++ b/src/host/nxdn/packet/ControlSignaling.cpp @@ -289,7 +289,7 @@ bool ControlSignaling::processNetwork(FuncChannelType::E fct, ChOption::E option uint16_t srcId = rcch->getSrcId(); uint16_t dstId = rcch->getDstId(); - if (m_nxdn->m_network->disallowUnitToUnit()) { + if (m_nxdn->m_network != nullptr && m_nxdn->m_network->disallowUnitToUnit()) { switch (rcch->getMessageType()) { case MessageType::RTCH_VCALL: if (!rcch->getGroup()) { diff --git a/src/host/nxdn/packet/Data.cpp b/src/host/nxdn/packet/Data.cpp index 0863d8b7..41d3d55c 100644 --- a/src/host/nxdn/packet/Data.cpp +++ b/src/host/nxdn/packet/Data.cpp @@ -240,7 +240,7 @@ bool Data::processNetwork(ChOption::E option, lc::RTCH& netLC, uint8_t* data, ui uint16_t srcId = lc.getSrcId(); bool group = lc.getGroup(); - if (m_nxdn->m_network->disallowUnitToUnit() && !group) { + if (m_nxdn->m_network != nullptr && m_nxdn->m_network->disallowUnitToUnit() && !group) { LogWarning(LOG_NET, "NXDN, rejecting network individual data call, srcId = %u, dstId = %u", srcId, dstId); return false; diff --git a/src/host/nxdn/packet/Voice.cpp b/src/host/nxdn/packet/Voice.cpp index 0c9be650..f840ae8a 100644 --- a/src/host/nxdn/packet/Voice.cpp +++ b/src/host/nxdn/packet/Voice.cpp @@ -694,7 +694,7 @@ bool Voice::processNetwork(FuncChannelType::E fct, ChOption::E option, lc::RTCH& bool group = lc.getGroup(); bool encrypted = lc.getEncrypted(); - if (m_nxdn->m_network->disallowUnitToUnit() && !group) { + if (m_nxdn->m_network != nullptr && m_nxdn->m_network->disallowUnitToUnit() && !group) { LogWarning(LOG_NET, "NXDN, rejecting network unit-to-unit voice call, srcId = %u, dstId = %u", srcId, dstId); return false; diff --git a/src/host/p25/Control.cpp b/src/host/p25/Control.cpp index 0b26eefc..9aee0a37 100644 --- a/src/host/p25/Control.cpp +++ b/src/host/p25/Control.cpp @@ -1635,7 +1635,7 @@ void Control::processNetwork() control.setNetId(netId); control.setSysId(sysId); - if (m_network->disallowUnitToUnit()) { + if (m_network != nullptr && m_network->disallowUnitToUnit()) { const bool privateCall = lco == LCO::PRIVATE || lco == LCO::PRIVATE_EXT; const bool voiceFrame = duid == DUID::HDU || duid == DUID::LDU1 || duid == DUID::LDU2; const bool callEnd = duid == DUID::TDU || duid == DUID::TDULC; diff --git a/src/host/p25/packet/ControlSignaling.cpp b/src/host/p25/packet/ControlSignaling.cpp index 9c45d1a8..8f74a242 100644 --- a/src/host/p25/packet/ControlSignaling.cpp +++ b/src/host/p25/packet/ControlSignaling.cpp @@ -872,7 +872,7 @@ bool ControlSignaling::processNetwork(uint8_t* data, uint32_t len, lc::LC& contr return false; } - if (m_p25->m_network->disallowUnitToUnit()) { + if (m_p25->m_network != nullptr && m_p25->m_network->disallowUnitToUnit()) { switch (tsbk->getLCO()) { case TSBKO::IOSP_UU_VCH: case TSBKO::IOSP_UU_ANS: @@ -1603,7 +1603,7 @@ void ControlSignaling::writeNetworkRF(lc::TSBK* tsbk, const uint8_t* data, bool if (m_p25->m_network == nullptr) return; - if (m_p25->m_network->disallowUnitToUnit()) { + if (m_p25->m_network != nullptr && m_p25->m_network->disallowUnitToUnit()) { switch (tsbk->getLCO()) { case TSBKO::IOSP_UU_VCH: case TSBKO::IOSP_UU_ANS: @@ -1637,7 +1637,8 @@ void ControlSignaling::writeNetworkRF(lc::TDULC* tduLc, const uint8_t* data, boo if (m_p25->m_network == nullptr) return; - if (m_p25->m_network->disallowUnitToUnit() && (tduLc->getLCO() == LCO::PRIVATE || tduLc->getLCO() == LCO::PRIVATE_EXT)) + if (m_p25->m_network != nullptr && m_p25->m_network->disallowUnitToUnit() && + (tduLc->getLCO() == LCO::PRIVATE || tduLc->getLCO() == LCO::PRIVATE_EXT)) return; if (m_p25->m_rfTimeoutTimer.isRunning() && m_p25->m_rfTimeoutTimer.hasExpired()) diff --git a/src/host/p25/phase2/Control.cpp b/src/host/p25/phase2/Control.cpp index 46aa0e89..3f7692dc 100644 --- a/src/host/p25/phase2/Control.cpp +++ b/src/host/p25/phase2/Control.cpp @@ -292,7 +292,7 @@ bool Control::writeNetwork(Slot* slot, const uint8_t* data, uint32_t length) if (m_network == nullptr || slot == nullptr || data == nullptr) return true; - if (m_network->disallowUnitToUnit() && (slot->m_control.getLCO() == defines::P2_MAC_MCO::PRIVATE || + if (m_network != nullptr && m_network->disallowUnitToUnit() && (slot->m_control.getLCO() == defines::P2_MAC_MCO::PRIVATE || (slot->m_controlByte & network::NET_CTRL_U2U) == network::NET_CTRL_U2U)) return true; diff --git a/src/host/p25/phase2/Slot.cpp b/src/host/p25/phase2/Slot.cpp index 73d5b078..ac09df75 100644 --- a/src/host/p25/phase2/Slot.cpp +++ b/src/host/p25/phase2/Slot.cpp @@ -444,7 +444,8 @@ bool Slot::processNetwork(uint8_t* data, uint32_t length, const lc::LC& control, { CHECK_NET_AUTHORITATIVE(control.getDstId()); - if (s_network->disallowUnitToUnit() && isVoiceDUID(duid) && (controlByte & network::NET_CTRL_U2U) == network::NET_CTRL_U2U) { + if (s_network != nullptr && s_network->disallowUnitToUnit() && isVoiceDUID(duid) && + (controlByte & network::NET_CTRL_U2U) == network::NET_CTRL_U2U) { return false; } @@ -1156,7 +1157,7 @@ bool Slot::processMAC(uint8_t* data, uint32_t length, defines::P2_DUID::E duid, if (net && !m_control.decodeVCH_MACPDU_OEMI(frame, sync)) return false; - if (net && s_network->disallowUnitToUnit() && + if (net && s_network != nullptr && s_network->disallowUnitToUnit() && m_control.getLCO() == defines::P2_MAC_MCO::PRIVATE) { LogWarning(LOG_NET, "P25 Phase 2 Slot %u, rejecting network unit-to-unit MAC PDU, srcId = %u, dstId = %u", m_slotNo + 1U, m_control.getSrcId(), m_control.getDstId()); diff --git a/tests/dmr/HostControl_Tests.cpp b/tests/dmr/HostControl_Tests.cpp index c66d5854..04e59374 100644 --- a/tests/dmr/HostControl_Tests.cpp +++ b/tests/dmr/HostControl_Tests.cpp @@ -421,6 +421,7 @@ public: ~DMRHostHarness() { delete m_control; + HostTestHooks::dmrDetachNetwork(); delete m_network; g_RPC = nullptr; } diff --git a/tests/host/HostTestHooks.cpp b/tests/host/HostTestHooks.cpp index f4e000d0..22cab11c 100644 --- a/tests/host/HostTestHooks.cpp +++ b/tests/host/HostTestHooks.cpp @@ -178,6 +178,13 @@ bool HostTestHooks::dmrStartRFVoiceCall(dmr::Slot& slot, uint32_t srcId, uint32_ return slot.processFrame(frame, sizeof(frame)); } +/* Detaches the shared DMR network pointer during test-fixture teardown. */ + +void HostTestHooks::dmrDetachNetwork() +{ + dmr::Slot::s_network = nullptr; +} + /* Configures a co-located DMR Tier III control channel. */ void HostTestHooks::dmrEnableTier3(dmr::Control& control, uint32_t channelNo, uint8_t tsccSlot) diff --git a/tests/host/HostTestHooks.h b/tests/host/HostTestHooks.h index 019071c9..74983e40 100644 --- a/tests/host/HostTestHooks.h +++ b/tests/host/HostTestHooks.h @@ -128,6 +128,10 @@ public: * @return bool True if frame processing succeeds. */ static bool dmrStartRFVoiceCall(dmr::Slot& slot, uint32_t srcId, uint32_t dstId, bool group = true); + /** + * @brief Detaches the shared DMR network pointer during test-fixture teardown. + */ + static void dmrDetachNetwork(); /** * @brief Configures one slot as a co-located Tier III control channel for tests. */