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);

pull/86/head
Bryan Biedenkapp 11 months ago
parent 3dd7871ee6
commit 1e8c266d8a

@ -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 <cassert>
@ -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<KMMFrame> 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<KMMHello*>(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<uint8_t[]>(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)

@ -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.

@ -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) {

Loading…
Cancel
Save

Powered by TurnKey Linux.