From 6284f053862edd22e4efc023115be72fec5f20eb Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Thu, 25 Jun 2026 17:01:36 -0400 Subject: [PATCH] make strapping check ICCs system requests so they are always actively sent; remove debug text; refactor how P25 call handler handles verifying TG strapping; --- src/fne/network/TrafficNetwork.cpp | 6 ++-- src/fne/network/callhandler/TagNXDNData.cpp | 4 +-- src/fne/network/callhandler/TagP25Data.cpp | 35 ++++++++++++++++++--- src/fne/network/callhandler/TagP25Data.h | 3 +- src/host/p25/packet/ControlSignaling.cpp | 3 -- 5 files changed, 38 insertions(+), 13 deletions(-) diff --git a/src/fne/network/TrafficNetwork.cpp b/src/fne/network/TrafficNetwork.cpp index f78de2a9..791c268c 100644 --- a/src/fne/network/TrafficNetwork.cpp +++ b/src/fne/network/TrafficNetwork.cpp @@ -3331,7 +3331,7 @@ bool TrafficNetwork::writePeerICC(uint32_t peerId, uint32_t streamId, NET_SUBFUN } if (peer.second->isEnabled()) { - LogInfoEx(LOG_MASTER, "PEER %u In-Call Control Request to Upstream, dstId = %u, slot = %u, ssrc = %u, streamId = %u", peerId, dstId, slotNo, ssrc, streamId); + LogInfoEx(LOG_MASTER, "PEER %u In-Call Control Request to Upstream, command = $%02X, dstId = %u, slot = %u, ssrc = %u, streamId = %u", peerId, command, dstId, slotNo, ssrc, streamId); peer.second->writeMaster({ NET_FUNC::INCALL_CTRL, subFunc }, buffer, 15U, RTP_END_OF_CALL_SEQ, streamId, false, 0U, ssrc); } } @@ -3340,8 +3340,10 @@ bool TrafficNetwork::writePeerICC(uint32_t peerId, uint32_t streamId, NET_SUBFUN return true; } - else + else { + LogInfoEx(LOG_MASTER, "PEER %u In-Call Control Request, command = $%02X, dstId = %u, slot = %u, ssrc = %u, streamId = %u", peerId, command, dstId, slotNo, ssrc, streamId); return writePeer(peerId, ssrc, { NET_FUNC::INCALL_CTRL, subFunc }, buffer, 15U, RTP_END_OF_CALL_SEQ, streamId); + } } /* diff --git a/src/fne/network/callhandler/TagNXDNData.cpp b/src/fne/network/callhandler/TagNXDNData.cpp index e99ace99..a11c895f 100644 --- a/src/fne/network/callhandler/TagNXDNData.cpp +++ b/src/fne/network/callhandler/TagNXDNData.cpp @@ -1107,7 +1107,7 @@ bool TagNXDNData::validate(uint32_t peerId, lc::RTCH& lc, uint8_t messageType, u LogError(LOG_NXDN, INFLUXDB_ERRSTR_ENC_TALKGROUP_CLR ", peer = %u, srcId = %u, dstId = %u", peerId, lc.getSrcId(), lc.getDstId()); // report In-Call Control to the peer sending traffic - m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_NXDN, NET_ICC::REJECT_TRAFFIC, lc.getDstId()); + m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_NXDN, NET_ICC::REJECT_TRAFFIC, lc.getDstId(), 0U, true); return false; } } @@ -1132,7 +1132,7 @@ bool TagNXDNData::validate(uint32_t peerId, lc::RTCH& lc, uint8_t messageType, u LogError(LOG_NXDN, INFLUXDB_ERRSTR_CLR_TALKGROUP_ENC ", peer = %u, srcId = %u, dstId = %u", peerId, lc.getSrcId(), lc.getDstId()); // report In-Call Control to the peer sending traffic - m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_NXDN, NET_ICC::REJECT_TRAFFIC, lc.getDstId()); + m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_NXDN, NET_ICC::REJECT_TRAFFIC, lc.getDstId(), 0U, true); return false; } } diff --git a/src/fne/network/callhandler/TagP25Data.cpp b/src/fne/network/callhandler/TagP25Data.cpp index e0b10b68..def31fd0 100644 --- a/src/fne/network/callhandler/TagP25Data.cpp +++ b/src/fne/network/callhandler/TagP25Data.cpp @@ -169,8 +169,32 @@ bool TagP25Data::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId tsbk = lc::tsbk::TSBKFactory::createTSBK(data); } + // decode true LDU LC from the network frame into a DFSI LC class literal + dfsi::LC dfsiLC = dfsi::LC(control, lsd); + if (duid == DUID::LDU1 || duid == DUID::LDU2) { + uint8_t netLDU[9U * 25U]; + ::memset(netLDU, 0x00U, 9U * 25U); + + uint8_t missing = BaseNetwork::reconstructLDUVectors(buffer + 24U, frameLength, &dfsiLC, duid, netLDU); + if (missing > 0U) { + LogWarning(LOG_NET, (duid == DUID::LDU1) ? P25_LDU1_STR : P25_LDU2_STR ", missing %u LDU voice frames, srcId = %u, dstId = %u", missing, srcId, dstId); + } + + // if its a LDU2 get the crypto state + if (duid == DUID::LDU2) { + control.setAlgId(dfsiLC.control()->getAlgId()); + control.setKId(dfsiLC.control()->getKId()); + + // copy MI data + uint8_t mi[MI_LENGTH_BYTES]; + ::memset(mi, 0x00U, MI_LENGTH_BYTES); + dfsiLC.control()->getMI(mi); + control.setMI(mi); + } + } + // is the stream valid? - if (validate(peerId, control, duid, tsbk.get(), streamId)) { + if (validate(peerId, control, duid, tsbk.get(), frameType, streamId)) { // is this peer ignored? if (!isPeerPermitted(peerId, control, duid, streamId, fromUpstream)) { return false; @@ -1531,7 +1555,7 @@ bool TagP25Data::isPeerPermitted(uint32_t peerId, lc::LC& control, DUID::E duid, /* Helper to validate the P25 call stream. */ -bool TagP25Data::validate(uint32_t peerId, lc::LC& control, DUID::E duid, const p25::lc::TSBK* tsbk, uint32_t streamId) +bool TagP25Data::validate(uint32_t peerId, lc::LC& control, DUID::E duid, const p25::lc::TSBK* tsbk, uint8_t frameType, uint32_t streamId) { // promiscuous hub mode performs no ACL checking and will pass all traffic if (g_promiscuousHub) @@ -1787,9 +1811,10 @@ bool TagP25Data::validate(uint32_t peerId, lc::LC& control, DUID::E duid, const } else { // "selectable" strapping doesn't care about encryption state -- anything else does - if (tg.config().strapping() != lookups::TG_STRAPPING_SELECTABLE) { + if ((tg.config().strapping() != lookups::TG_STRAPPING_SELECTABLE) && (frameType == FrameType::HDU_VALID || duid == DUID::LDU2)) { // is the TG strapped but the LC is reporting unencrypted? if (tg.config().strapping() == lookups::TG_STRAPPING_STRAPPED) { + LogDebugEx(LOG_P25, "TagP25Data::validate()", "tgId = %u, duid = $%02X, strapping = %u, algId = $%02X", control.getDstId(), (uint8_t)duid, tg.config().strapping(), control.getAlgId()); if (control.getAlgId() == P25DEF::ALGO_UNENCRYPT) { // report error event to InfluxDB if (m_network->m_enableInfluxDB) { @@ -1808,7 +1833,7 @@ bool TagP25Data::validate(uint32_t peerId, lc::LC& control, DUID::E duid, const LogError(LOG_P25, INFLUXDB_ERRSTR_ENC_TALKGROUP_CLR ", peer = %u, srcId = %u, dstId = %u", peerId, control.getSrcId(), control.getDstId()); // report In-Call Control to the peer sending traffic - m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_P25, NET_ICC::REJECT_TRAFFIC, control.getDstId()); + m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_P25, NET_ICC::REJECT_TRAFFIC, control.getDstId(), 0U, true); return false; } } @@ -1833,7 +1858,7 @@ bool TagP25Data::validate(uint32_t peerId, lc::LC& control, DUID::E duid, const LogError(LOG_P25, INFLUXDB_ERRSTR_CLR_TALKGROUP_ENC ", peer = %u, srcId = %u, dstId = %u", peerId, control.getSrcId(), control.getDstId()); // report In-Call Control to the peer sending traffic - m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_P25, NET_ICC::REJECT_TRAFFIC, control.getDstId()); + m_network->writePeerICC(peerId, streamId, NET_SUBFUNC::PROTOCOL_SUBFUNC_P25, NET_ICC::REJECT_TRAFFIC, control.getDstId(), 0U, true); return false; } } diff --git a/src/fne/network/callhandler/TagP25Data.h b/src/fne/network/callhandler/TagP25Data.h index c98b3247..64c70dd2 100644 --- a/src/fne/network/callhandler/TagP25Data.h +++ b/src/fne/network/callhandler/TagP25Data.h @@ -333,10 +333,11 @@ namespace network * @param control Instance of p25::lc::LC. * @param duid DUID. * @param[in] tsbk Instance of p25::lc::TSBK. + * @param frameType Frame Type. * @param streamId Stream ID. * @returns bool True, if valid, otherwise false. */ - bool validate(uint32_t peerId, p25::lc::LC& control, P25DEF::DUID::E duid, const p25::lc::TSBK* tsbk, uint32_t streamId); + bool validate(uint32_t peerId, p25::lc::LC& control, P25DEF::DUID::E duid, const p25::lc::TSBK* tsbk, uint8_t frameType, uint32_t streamId); /** * @brief Helper to write a grant packet. diff --git a/src/host/p25/packet/ControlSignaling.cpp b/src/host/p25/packet/ControlSignaling.cpp index fc5372a0..1fa021f5 100644 --- a/src/host/p25/packet/ControlSignaling.cpp +++ b/src/host/p25/packet/ControlSignaling.cpp @@ -2153,9 +2153,6 @@ bool ControlSignaling::writeRF_TSDU_Grant(uint32_t srcId, uint32_t dstId, uint8_ return true; // do not generate grant packets for $FFFF (All Call) TGID } - LogDebugEx(LOG_RF, "ControlSignaling::writeRF_TSDU_Grant()", "srcId = %u, dstId = %u, serviceOptions = $%02X, grp = %u, net = %u, skip = %u, chNo = %u", - srcId, dstId, serviceOptions, grp, net, skip, chNo); - // are network channel grants disabled? if (m_p25->m_disableNetworkGrant) { // don't process RF grant if the network isn't in a idle state and the RF destination is the network destination