From 8ca4ed5a4007e73ca05d8655a6a16feefed6882a Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Fri, 9 Feb 2024 10:51:28 -0500 Subject: [PATCH] implement a few more CFNE NAK types to notify the peer of invalid conditions; take first steps towards FNE-side authoritative grants by implementing some logic plumbing; --- src/common/lookups/RadioIdLookup.cpp | 1 - src/common/network/BaseNetwork.h | 4 ++ src/fne/network/FNENetwork.cpp | 58 +++++++++++++++++++++++++--- src/fne/network/FNENetwork.h | 14 +++++++ src/fne/network/fne/TagDMRData.cpp | 17 ++++++++ src/fne/network/fne/TagDMRData.h | 2 + src/fne/network/fne/TagNXDNData.cpp | 16 ++++++++ src/fne/network/fne/TagNXDNData.h | 2 + src/fne/network/fne/TagP25Data.cpp | 16 ++++++++ src/fne/network/fne/TagP25Data.h | 2 + src/host/network/Network.cpp | 6 +++ 11 files changed, 132 insertions(+), 6 deletions(-) diff --git a/src/common/lookups/RadioIdLookup.cpp b/src/common/lookups/RadioIdLookup.cpp index 672373b7..ba0fb379 100644 --- a/src/common/lookups/RadioIdLookup.cpp +++ b/src/common/lookups/RadioIdLookup.cpp @@ -131,7 +131,6 @@ RadioId RadioIdLookup::find(uint32_t id) /// void RadioIdLookup::commit() { - // bryanb: TODO TODO TODO save(); } diff --git a/src/common/network/BaseNetwork.h b/src/common/network/BaseNetwork.h index c4f2969d..b0a60f90 100644 --- a/src/common/network/BaseNetwork.h +++ b/src/common/network/BaseNetwork.h @@ -50,6 +50,7 @@ #define TAG_REPEATER_PING "RPTP" #define TAG_REPEATER_GRANT "RPTG" +#define TAG_TRANSFER "TRNS" #define TAG_TRANSFER_ACT_LOG "TRNSLOG" #define TAG_TRANSFER_DIAG_LOG "TRNSDIAG" @@ -137,6 +138,9 @@ namespace network enum NET_CONN_NAK_REASON { NET_CONN_NAK_GENERAL_FAILURE, + NET_CONN_NAK_MODE_NOT_ENABLED, + NET_CONN_NAK_ILLEGAL_PACKET, + NET_CONN_NAK_FNE_UNAUTHORIZED, NET_CONN_NAK_BAD_CONN_STATE, NET_CONN_NAK_INVALID_CONFIG_DATA, diff --git a/src/fne/network/FNENetwork.cpp b/src/fne/network/FNENetwork.cpp index 2cfb4fe6..eaba1a4d 100644 --- a/src/fne/network/FNENetwork.cpp +++ b/src/fne/network/FNENetwork.cpp @@ -387,6 +387,8 @@ void* FNENetwork::threadedNetworkRx(void* arg) if (network->m_tagDMR != nullptr) { network->m_tagDMR->processFrame(req->buffer, req->length, peerId, req->rtpHeader.getSequence(), streamId); } + } else { + network->writePeerNAK(peerId, TAG_DMR_DATA, NET_CONN_NAK_MODE_NOT_ENABLED); } } } @@ -408,6 +410,8 @@ void* FNENetwork::threadedNetworkRx(void* arg) if (network->m_tagP25 != nullptr) { network->m_tagP25->processFrame(req->buffer, req->length, peerId, req->rtpHeader.getSequence(), streamId); } + } else { + network->writePeerNAK(peerId, TAG_P25_DATA, NET_CONN_NAK_MODE_NOT_ENABLED); } } } @@ -429,6 +433,8 @@ void* FNENetwork::threadedNetworkRx(void* arg) if (network->m_tagNXDN != nullptr) { network->m_tagNXDN->processFrame(req->buffer, req->length, peerId, req->rtpHeader.getSequence(), streamId); } + } else { + network->writePeerNAK(peerId, TAG_NXDN_DATA, NET_CONN_NAK_MODE_NOT_ENABLED); } } } @@ -708,7 +714,47 @@ void* FNENetwork::threadedNetworkRx(void* arg) // validate peer (simple validation really) if (connection->connected() && connection->address() == ip) { - /* ignored */ + uint32_t srcId = __GET_UINT16(req->buffer, 11U); // Source Address + uint32_t dstId = __GET_UINT16(req->buffer, 15U); // Destination Address + + uint8_t slot = req->buffer[19U]; + + bool unitToUnit = (req->buffer[19U] & 0x80U) == 0x80U; + + DVM_STATE state = (DVM_STATE)req->buffer[20U]; // DVM Mode State + switch (state) { + case STATE_DMR: + if (network->m_dmrEnabled) { + if (network->m_tagDMR != nullptr) { + network->m_tagDMR->processGrantReq(srcId, dstId, slot, unitToUnit, peerId, req->rtpHeader.getSequence(), streamId); + } else { + network->writePeerNAK(peerId, TAG_DMR_DATA, NET_CONN_NAK_MODE_NOT_ENABLED); + } + } + break; + case STATE_P25: + if (network->m_p25Enabled) { + if (network->m_tagP25 != nullptr) { + network->m_tagP25->processGrantReq(srcId, dstId, unitToUnit, peerId, req->rtpHeader.getSequence(), streamId); + } else { + network->writePeerNAK(peerId, TAG_P25_DATA, NET_CONN_NAK_MODE_NOT_ENABLED); + } + } + break; + case STATE_NXDN: + if (network->m_nxdnEnabled) { + if (network->m_tagNXDN != nullptr) { + network->m_tagNXDN->processGrantReq(srcId, dstId, unitToUnit, peerId, req->rtpHeader.getSequence(), streamId); + } else { + network->writePeerNAK(peerId, TAG_NXDN_DATA, NET_CONN_NAK_MODE_NOT_ENABLED); + } + } + break; + default: + network->writePeerNAK(peerId, TAG_REPEATER_GRANT, NET_CONN_NAK_ILLEGAL_PACKET); + Utils::dump("unknown state for grant request from the peer", req->buffer, req->length); + break; + } } else { network->writePeerNAK(peerId, TAG_REPEATER_GRANT, NET_CONN_NAK_FNE_UNAUTHORIZED); @@ -770,6 +816,7 @@ void* FNENetwork::threadedNetworkRx(void* arg) } } else { + network->writePeerNAK(peerId, TAG_TRANSFER, NET_CONN_NAK_ILLEGAL_PACKET); Utils::dump("unknown transfer opcode from the peer", req->buffer, req->length); } } @@ -786,8 +833,8 @@ void* FNENetwork::threadedNetworkRx(void* arg) // validate peer (simple validation really) if (connection->connected() && connection->address() == ip) { - uint32_t srcId = __GET_UINT16(req->buffer, 0U); - uint32_t dstId = __GET_UINT16(req->buffer, 3U); + uint32_t srcId = __GET_UINT16(req->buffer, 0U); // Source Address + uint32_t dstId = __GET_UINT16(req->buffer, 3U); // Destination Address aff->groupUnaff(srcId); aff->groupAff(srcId, dstId); } @@ -806,7 +853,7 @@ void* FNENetwork::threadedNetworkRx(void* arg) // validate peer (simple validation really) if (connection->connected() && connection->address() == ip) { - uint32_t srcId = __GET_UINT16(req->buffer, 0U); + uint32_t srcId = __GET_UINT16(req->buffer, 0U); // Source Address aff->unitReg(srcId); } else { @@ -824,7 +871,7 @@ void* FNENetwork::threadedNetworkRx(void* arg) // validate peer (simple validation really) if (connection->connected() && connection->address() == ip) { - uint32_t srcId = __GET_UINT16(req->buffer, 0U); + uint32_t srcId = __GET_UINT16(req->buffer, 0U); // Source Address aff->unitDereg(srcId); } else { @@ -863,6 +910,7 @@ void* FNENetwork::threadedNetworkRx(void* arg) } } else { + network->writePeerNAK(peerId, TAG_ANNOUNCE, NET_CONN_NAK_ILLEGAL_PACKET); Utils::dump("unknown announcement opcode from the peer", req->buffer, req->length); } } diff --git a/src/fne/network/FNENetwork.h b/src/fne/network/FNENetwork.h index 2e692e57..32869fae 100644 --- a/src/fne/network/FNENetwork.h +++ b/src/fne/network/FNENetwork.h @@ -40,6 +40,20 @@ namespace network { namespace fne { class HOST_SW_API TagNXDNData; } } namespace network { + // --------------------------------------------------------------------------- + // Constants + // --------------------------------------------------------------------------- + + enum DVM_STATE { + STATE_IDLE = 0U, + // DMR + STATE_DMR = 1U, + // Project 25 + STATE_P25 = 2U, + // NXDN + STATE_NXDN = 3U, + }; + // --------------------------------------------------------------------------- // Class Prototypes // --------------------------------------------------------------------------- diff --git a/src/fne/network/fne/TagDMRData.cpp b/src/fne/network/fne/TagDMRData.cpp index 2c6cd261..9cc9ffed 100644 --- a/src/fne/network/fne/TagDMRData.cpp +++ b/src/fne/network/fne/TagDMRData.cpp @@ -289,6 +289,23 @@ bool TagDMRData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId return false; } +/// +/// Process a grant request frame from the network. +/// +/// +/// +/// +/// +/// Peer ID +/// +/// Stream ID +/// +bool TagDMRData::processGrantReq(uint32_t srcId, uint32_t dstId, uint8_t slot, bool unitToUnit, uint32_t peerId, uint16_t pktSeq, uint32_t streamId) +{ + // bryanb: TODO TODO TODO + return false; +} + /// /// Helper to playback a parrot frame to the network. /// diff --git a/src/fne/network/fne/TagDMRData.h b/src/fne/network/fne/TagDMRData.h index 94a17d85..8502c2b8 100644 --- a/src/fne/network/fne/TagDMRData.h +++ b/src/fne/network/fne/TagDMRData.h @@ -39,6 +39,8 @@ namespace network /// Process a data frame from the network. bool processFrame(const uint8_t* data, uint32_t len, uint32_t peerId, uint16_t pktSeq, uint32_t streamId, bool external = false); + /// Process a grant request frame from the network. + bool processGrantReq(uint32_t srcId, uint32_t dstId, uint8_t slot, bool unitToUnit, uint32_t peerId, uint16_t pktSeq, uint32_t streamId); /// Helper to playback a parrot frame to the network. void playbackParrot(); diff --git a/src/fne/network/fne/TagNXDNData.cpp b/src/fne/network/fne/TagNXDNData.cpp index fde01e24..4fcf8fd4 100644 --- a/src/fne/network/fne/TagNXDNData.cpp +++ b/src/fne/network/fne/TagNXDNData.cpp @@ -259,6 +259,22 @@ bool TagNXDNData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerI return false; } +/// +/// Process a grant request frame from the network. +/// +/// +/// +/// +/// Peer ID +/// +/// Stream ID +/// +bool TagNXDNData::processGrantReq(uint32_t srcId, uint32_t dstId, bool unitToUnit, uint32_t peerId, uint16_t pktSeq, uint32_t streamId) +{ + // bryanb: TODO TODO TODO + return false; +} + /// /// Helper to playback a parrot frame to the network. /// diff --git a/src/fne/network/fne/TagNXDNData.h b/src/fne/network/fne/TagNXDNData.h index e678c945..0bd15fd7 100644 --- a/src/fne/network/fne/TagNXDNData.h +++ b/src/fne/network/fne/TagNXDNData.h @@ -39,6 +39,8 @@ namespace network /// Process a data frame from the network. bool processFrame(const uint8_t* data, uint32_t len, uint32_t peerId, uint16_t pktSeq, uint32_t streamId, bool external = false); + /// Process a grant request frame from the network. + bool processGrantReq(uint32_t srcId, uint32_t dstId, bool unitToUnit, uint32_t peerId, uint16_t pktSeq, uint32_t streamId); /// Helper to playback a parrot frame to the network. void playbackParrot(); diff --git a/src/fne/network/fne/TagP25Data.cpp b/src/fne/network/fne/TagP25Data.cpp index 41213224..dc8c6cc1 100644 --- a/src/fne/network/fne/TagP25Data.cpp +++ b/src/fne/network/fne/TagP25Data.cpp @@ -326,6 +326,22 @@ bool TagP25Data::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId return false; } +/// +/// Process a grant request frame from the network. +/// +/// +/// +/// +/// Peer ID +/// +/// Stream ID +/// +bool TagP25Data::processGrantReq(uint32_t srcId, uint32_t dstId, bool unitToUnit, uint32_t peerId, uint16_t pktSeq, uint32_t streamId) +{ + // bryanb: TODO TODO TODO + return false; +} + /// /// Helper to playback a parrot frame to the network. /// diff --git a/src/fne/network/fne/TagP25Data.h b/src/fne/network/fne/TagP25Data.h index c951bf82..c76adc78 100644 --- a/src/fne/network/fne/TagP25Data.h +++ b/src/fne/network/fne/TagP25Data.h @@ -45,6 +45,8 @@ namespace network /// Process a data frame from the network. bool processFrame(const uint8_t* data, uint32_t len, uint32_t peerId, uint16_t pktSeq, uint32_t streamId, bool external = false); + /// Process a grant request frame from the network. + bool processGrantReq(uint32_t srcId, uint32_t dstId, bool unitToUnit, uint32_t peerId, uint16_t pktSeq, uint32_t streamId); /// Helper to playback a parrot frame to the network. void playbackParrot(); diff --git a/src/host/network/Network.cpp b/src/host/network/Network.cpp index 27bc1ed5..a8b2b135 100644 --- a/src/host/network/Network.cpp +++ b/src/host/network/Network.cpp @@ -486,6 +486,12 @@ void Network::clock(uint32_t ms) if (length > 10) { reason = __GET_UINT16B(buffer, 10U); switch (reason) { + case NET_CONN_NAK_MODE_NOT_ENABLED: + LogWarning(LOG_NET, "PEER %u master NAK; digital mode not enabled on FNE, remotePeerId = %u", m_peerId, rtpHeader.getSSRC()); + break; + case NET_CONN_NAK_ILLEGAL_PACKET: + LogWarning(LOG_NET, "PEER %u master NAK; illegal/unknown packet, remotePeerId = %u", m_peerId, rtpHeader.getSSRC()); + break; case NET_CONN_NAK_FNE_UNAUTHORIZED: LogWarning(LOG_NET, "PEER %u master NAK; unauthorized, remotePeerId = %u", m_peerId, rtpHeader.getSSRC()); break;