From 1e8c266d8adbd7a3a7d0f6894d4a7bfdc64c4e86 Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Tue, 11 Mar 2025 15:38:22 -0400 Subject: [PATCH] implement support to handle KMMs at the FNE; hardcode the host to ignore repeating KMM frames; implement HELLO KMM support and response with a NO_SERVICE (we don't have OTAR implemented at this time); --- .../callhandler/packetdata/P25PacketData.cpp | 64 +++++++++++++++++++ .../callhandler/packetdata/P25PacketData.h | 7 ++ src/host/p25/packet/Data.cpp | 9 +++ 3 files changed, 80 insertions(+) diff --git a/src/fne/network/callhandler/packetdata/P25PacketData.cpp b/src/fne/network/callhandler/packetdata/P25PacketData.cpp index 23f69e74..80666a93 100644 --- a/src/fne/network/callhandler/packetdata/P25PacketData.cpp +++ b/src/fne/network/callhandler/packetdata/P25PacketData.cpp @@ -8,6 +8,7 @@ * */ #include "fne/Defines.h" +#include "common/p25/kmm/KMMFactory.h" #include "common/p25/sndcp/SNDCPFactory.h" #include "common/p25/Sync.h" #include "common/edac/CRC.h" @@ -25,6 +26,7 @@ using namespace network::callhandler; using namespace network::callhandler::packetdata; using namespace p25; using namespace p25::defines; +using namespace p25::kmm; using namespace p25::sndcp; #include @@ -658,6 +660,14 @@ void P25PacketData::dispatch(uint32_t peerId) processSNDCPControl(status); } break; + case PDUSAP::UNENC_KMM: + case PDUSAP::ENC_KMM: + { + LogMessage(LOG_NET, P25_PDU_STR ", KMM (Key Management Message), blocksToFollow = %u", + status->header.getBlocksToFollow()); + + processKMM(status); + } default: break; } @@ -801,6 +811,60 @@ bool P25PacketData::processSNDCPControl(RxStatus* status) return true; } +/* Helper used to process KMM frames from PDU data. */ + +bool P25PacketData::processKMM(RxStatus* status) +{ + std::unique_ptr frame = KMMFactory::create(status->pduUserData); + if (frame == nullptr) { + LogWarning(LOG_NET, P25_PDU_STR ", undecodable KMM packet"); + return false; + } + + uint32_t llId = status->header.getLLId(); + + switch (frame->getMessageId()) { + case KMM_MessageType::HELLO: + { + KMMHello* kmm = static_cast(frame.get()); + LogMessage(LOG_NET, P25_PDU_STR ", KMM Hello, llId = %u, flag = $%02X", llId, + kmm->getFlag()); + + // respond with No-Service + // assemble a P25 PDU frame header for transport... + data::DataHeader dataHeader = data::DataHeader(); + dataHeader.setFormat(PDUFormatType::UNCONFIRMED); + dataHeader.setMFId(MFG_STANDARD); + dataHeader.setAckNeeded(false); + dataHeader.setOutbound(true); + dataHeader.setSAP(PDUSAP::UNENC_KMM); + dataHeader.setLLId(WUID_ALL); + dataHeader.setBlocksToFollow(1U); + + dataHeader.calculateLength(KMM_NO_SERVICE_LENGTH); + uint32_t pduLength = dataHeader.getPDULength(); + + UInt8Array __pduUserData = std::make_unique(pduLength); + uint8_t* pduUserData = __pduUserData.get(); + ::memset(pduUserData, 0x00U, pduLength); + + uint8_t buffer[KMM_NO_SERVICE_LENGTH]; + KMMNoService outKmm = KMMNoService(); + outKmm.encode(buffer); + + ::memcpy(pduUserData, buffer, KMM_NO_SERVICE_LENGTH); + + dispatchUserFrameToFNE(dataHeader, false, pduUserData); + } + break; + + default: + break; + } // switch (packet->getPDUType()) + + return true; +} + /* Helper write ARP request to the network. */ void P25PacketData::write_PDU_ARP(uint32_t addr) diff --git a/src/fne/network/callhandler/packetdata/P25PacketData.h b/src/fne/network/callhandler/packetdata/P25PacketData.h index 190ed778..d57b2ca2 100644 --- a/src/fne/network/callhandler/packetdata/P25PacketData.h +++ b/src/fne/network/callhandler/packetdata/P25PacketData.h @@ -199,6 +199,13 @@ namespace network */ bool processSNDCPControl(RxStatus* status); + /** + * @brief Helper used to process KMM frames from PDU data. + * @param status Instance of the RxStatus class. + * @returns bool True, if KMM data was processed, otherwise false. + */ + bool processKMM(RxStatus* status); + /** * @brief Helper write ARP request to the network. * @param addr IP Address. diff --git a/src/host/p25/packet/Data.cpp b/src/host/p25/packet/Data.cpp index 30071bca..66660bec 100644 --- a/src/host/p25/packet/Data.cpp +++ b/src/host/p25/packet/Data.cpp @@ -445,6 +445,15 @@ bool Data::process(uint8_t* data, uint32_t len) processConvDataReg(m_rfPduUserData); } break; + case PDUSAP::UNENC_KMM: + case PDUSAP::ENC_KMM: + { + if (m_verbose) { + LogMessage(LOG_RF, P25_PDU_STR ", KMM (Key Management Message), blocksToFollow = %u", + m_rfDataHeader.getBlocksToFollow()); + } + } + break; case PDUSAP::TRUNK_CTRL: { if (m_verbose) {