From 75dbc9e02597cfb1c1b22f6252d33322a7f4b6ad Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Sat, 25 May 2024 12:47:44 -0400 Subject: [PATCH] refactor parrot frame storage; add support to allow parrot responses to go only to the peer for which the parrot call originated; --- configs/fne-config.example.yml | 2 ++ src/fne/network/FNENetwork.cpp | 4 +++ src/fne/network/FNENetwork.h | 1 + src/fne/network/fne/TagDMRData.cpp | 41 +++++++++++++++++++++------- src/fne/network/fne/TagDMRData.h | 16 ++++++++++- src/fne/network/fne/TagNXDNData.cpp | 39 ++++++++++++++++++++------- src/fne/network/fne/TagNXDNData.h | 14 +++++++++- src/fne/network/fne/TagP25Data.cpp | 42 +++++++++++++++++++++-------- src/fne/network/fne/TagP25Data.h | 14 +++++++++- 9 files changed, 141 insertions(+), 32 deletions(-) diff --git a/configs/fne-config.example.yml b/configs/fne-config.example.yml index 19a9cfaa..3e597566 100644 --- a/configs/fne-config.example.yml +++ b/configs/fne-config.example.yml @@ -70,6 +70,8 @@ master: parrotDelay: 2000 # Flag indicating whether or not a parrot TG call will generate a grant demand. parrotGrantDemand: true + # Flag indicating whether or not a parrot TG call will only be sent to the originating peer. + parrotOnlyToOrginiatingPeer: false # Flag indicating whether or not a adjacent site broadcasts will pass to any peers. disallowAdjStsBcast: false diff --git a/src/fne/network/FNENetwork.cpp b/src/fne/network/FNENetwork.cpp index a9a11860..8ac5e97a 100644 --- a/src/fne/network/FNENetwork.cpp +++ b/src/fne/network/FNENetwork.cpp @@ -84,6 +84,7 @@ FNENetwork::FNENetwork(HostFNE* host, const std::string& address, uint16_t port, m_parrotDelay(parrotDelay), m_parrotDelayTimer(1000U, 0U, parrotDelay), m_parrotGrantDemand(parrotGrantDemand), + m_parrotOnlyOriginating(false), m_ridLookup(nullptr), m_tidLookup(nullptr), m_status(NET_STAT_INVALID), @@ -159,6 +160,8 @@ void FNENetwork::setOptions(yaml::Node& conf, bool printOptions) m_influxServer = influxdb::ServerInfo(m_influxServerAddress, m_influxServerPort, m_influxOrg, m_influxServerToken, m_influxBucket); } + m_parrotOnlyOriginating = conf["parrotOnlyToOrginiatingPeer"].as(false); + if (printOptions) { LogInfo(" Maximum Permitted Connections: %u", m_softConnLimit); LogInfo(" Disable adjacent site broadcasts to any peers: %s", m_disallowAdjStsBcast ? "yes" : "no"); @@ -175,6 +178,7 @@ void FNENetwork::setOptions(yaml::Node& conf, bool printOptions) LogInfo(" InfluxDB Bucket: %s", m_influxBucket.c_str()); LogInfo(" InfluxDB Log Raw TSBK/CSBK/RCCH: %s", m_influxLogRawData ? "yes" : "no"); } + LogInfo(" Parrot Repeat to Only Originating Peer: %u", m_parrotOnlyOriginating); } } diff --git a/src/fne/network/FNENetwork.h b/src/fne/network/FNENetwork.h index 20d8c76b..d0168c33 100644 --- a/src/fne/network/FNENetwork.h +++ b/src/fne/network/FNENetwork.h @@ -280,6 +280,7 @@ namespace network uint32_t m_parrotDelay; Timer m_parrotDelayTimer; bool m_parrotGrantDemand; + bool m_parrotOnlyOriginating; lookups::RadioIdLookup* m_ridLookup; lookups::TalkgroupRulesLookup* m_tidLookup; diff --git a/src/fne/network/fne/TagDMRData.cpp b/src/fne/network/fne/TagDMRData.cpp index 28631c30..dca5d21f 100644 --- a/src/fne/network/fne/TagDMRData.cpp +++ b/src/fne/network/fne/TagDMRData.cpp @@ -200,8 +200,8 @@ bool TagDMRData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId m_parrotFramesReady = false; if (m_parrotFrames.size() > 0) { for (auto& pkt : m_parrotFrames) { - if (std::get<0>(pkt) != nullptr) { - delete std::get<0>(pkt); + if (pkt.buffer != nullptr) { + delete pkt.buffer; } } m_parrotFrames.clear(); @@ -228,7 +228,21 @@ bool TagDMRData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId if (tg.config().parrot()) { uint8_t* copy = new uint8_t[len]; ::memcpy(copy, buffer, len); - m_parrotFrames.push_back(std::make_tuple(copy, len, pktSeq, streamId)); + + ParrotFrame parrotFrame = ParrotFrame(); + parrotFrame.buffer = copy; + parrotFrame.bufferLen = len; + + parrotFrame.slotNo = slotNo; + + parrotFrame.pktSeq = pktSeq; + parrotFrame.streamId = streamId; + parrotFrame.peerId = peerId; + + parrotFrame.srcId = srcId; + parrotFrame.dstId = dstId; + + m_parrotFrames.push_back(parrotFrame); } // process CSBK from peer @@ -343,17 +357,26 @@ void TagDMRData::playbackParrot() } auto& pkt = m_parrotFrames[0]; - if (std::get<0>(pkt) != nullptr) { - // repeat traffic to the connected peers - for (auto peer : m_network->m_peers) { - m_network->writePeer(peer.first, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_DMR }, std::get<0>(pkt), std::get<1>(pkt), std::get<2>(pkt), std::get<3>(pkt), false); + if (pkt.buffer != nullptr) { + if (m_network->m_parrotOnlyOriginating) { + m_network->writePeer(pkt.peerId, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_DMR }, pkt.buffer, pkt.bufferLen, pkt.pktSeq, pkt.streamId, false); if (m_network->m_debug) { LogDebug(LOG_NET, "DMR, parrot, dstPeer = %u, len = %u, pktSeq = %u, streamId = %u", - peer.first, std::get<1>(pkt), std::get<2>(pkt), std::get<3>(pkt)); + pkt.peerId, pkt.bufferLen, pkt.pktSeq, pkt.streamId); + } + } + else { + // repeat traffic to the connected peers + for (auto peer : m_network->m_peers) { + m_network->writePeer(peer.first, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_DMR }, pkt.buffer, pkt.bufferLen, pkt.pktSeq, pkt.streamId, false); + if (m_network->m_debug) { + LogDebug(LOG_NET, "DMR, parrot, dstPeer = %u, len = %u, pktSeq = %u, streamId = %u", + peer.first, pkt.bufferLen, pkt.pktSeq, pkt.streamId); + } } } - delete std::get<0>(pkt); + delete pkt.buffer; } Thread::sleep(60); m_parrotFrames.pop_front(); diff --git a/src/fne/network/fne/TagDMRData.h b/src/fne/network/fne/TagDMRData.h index 03333d0a..7bc3678d 100644 --- a/src/fne/network/fne/TagDMRData.h +++ b/src/fne/network/fne/TagDMRData.h @@ -56,7 +56,21 @@ namespace network private: FNENetwork* m_network; - std::deque> m_parrotFrames; + class ParrotFrame { + public: + uint8_t* buffer; + uint32_t bufferLen; + + uint8_t slotNo; + + uint16_t pktSeq; + uint32_t streamId; + uint32_t peerId; + + uint32_t srcId; + uint32_t dstId; + }; + std::deque m_parrotFrames; bool m_parrotFramesReady; class RxStatus { diff --git a/src/fne/network/fne/TagNXDNData.cpp b/src/fne/network/fne/TagNXDNData.cpp index 61a92f1c..73e9840b 100644 --- a/src/fne/network/fne/TagNXDNData.cpp +++ b/src/fne/network/fne/TagNXDNData.cpp @@ -172,8 +172,8 @@ bool TagNXDNData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerI m_parrotFramesReady = false; if (m_parrotFrames.size() > 0) { for (auto& pkt : m_parrotFrames) { - if (std::get<0>(pkt) != nullptr) { - delete std::get<0>(pkt); + if (pkt.buffer != nullptr) { + delete pkt.buffer; } } m_parrotFrames.clear(); @@ -200,7 +200,19 @@ bool TagNXDNData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerI if (tg.config().parrot()) { uint8_t *copy = new uint8_t[len]; ::memcpy(copy, buffer, len); - m_parrotFrames.push_back(std::make_tuple(copy, len, pktSeq, streamId)); + + ParrotFrame parrotFrame = ParrotFrame(); + parrotFrame.buffer = copy; + parrotFrame.bufferLen = len; + + parrotFrame.pktSeq = pktSeq; + parrotFrame.streamId = streamId; + parrotFrame.peerId = peerId; + + parrotFrame.srcId = srcId; + parrotFrame.dstId = dstId; + + m_parrotFrames.push_back(parrotFrame); } // repeat traffic to the connected peers @@ -309,17 +321,26 @@ void TagNXDNData::playbackParrot() } auto& pkt = m_parrotFrames[0]; - if (std::get<0>(pkt) != nullptr) { - // repeat traffic to the connected peers - for (auto peer : m_network->m_peers) { - m_network->writePeer(peer.first, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_NXDN }, std::get<0>(pkt), std::get<1>(pkt), std::get<2>(pkt), std::get<3>(pkt), false); + if (pkt.buffer != nullptr) { + if (m_network->m_parrotOnlyOriginating) { + m_network->writePeer(pkt.peerId, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_NXDN }, pkt.buffer, pkt.bufferLen, pkt.pktSeq, pkt.streamId, false); if (m_network->m_debug) { LogDebug(LOG_NET, "NXDN, parrot, dstPeer = %u, len = %u, pktSeq = %u, streamId = %u", - peer.first, std::get<1>(pkt), std::get<2>(pkt), std::get<3>(pkt)); + pkt.peerId, pkt.bufferLen, pkt.pktSeq, pkt.streamId); + } + } + else { + // repeat traffic to the connected peers + for (auto peer : m_network->m_peers) { + m_network->writePeer(peer.first, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_NXDN }, pkt.buffer, pkt.bufferLen, pkt.pktSeq, pkt.streamId, false); + if (m_network->m_debug) { + LogDebug(LOG_NET, "NXDN, parrot, dstPeer = %u, len = %u, pktSeq = %u, streamId = %u", + peer.first, pkt.bufferLen, pkt.pktSeq, pkt.streamId); + } } } - delete std::get<0>(pkt); + delete pkt.buffer; } Thread::sleep(60); m_parrotFrames.pop_front(); diff --git a/src/fne/network/fne/TagNXDNData.h b/src/fne/network/fne/TagNXDNData.h index 9533484c..5514fcce 100644 --- a/src/fne/network/fne/TagNXDNData.h +++ b/src/fne/network/fne/TagNXDNData.h @@ -51,7 +51,19 @@ namespace network private: FNENetwork* m_network; - std::deque> m_parrotFrames; + class ParrotFrame { + public: + uint8_t* buffer; + uint32_t bufferLen; + + uint16_t pktSeq; + uint32_t streamId; + uint32_t peerId; + + uint32_t srcId; + uint32_t dstId; + }; + std::deque m_parrotFrames; bool m_parrotFramesReady; class RxStatus { diff --git a/src/fne/network/fne/TagP25Data.cpp b/src/fne/network/fne/TagP25Data.cpp index a509b85d..6367a175 100644 --- a/src/fne/network/fne/TagP25Data.cpp +++ b/src/fne/network/fne/TagP25Data.cpp @@ -230,8 +230,8 @@ bool TagP25Data::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId m_parrotFramesReady = false; if (m_parrotFrames.size() > 0) { for (auto& pkt : m_parrotFrames) { - if (std::get<0>(pkt) != nullptr) { - delete std::get<0>(pkt); + if (pkt.buffer != nullptr) { + delete pkt.buffer; } } m_parrotFrames.clear(); @@ -258,7 +258,19 @@ bool TagP25Data::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId if (tg.config().parrot()) { uint8_t *copy = new uint8_t[len]; ::memcpy(copy, buffer, len); - m_parrotFrames.push_back(std::make_tuple(copy, len, pktSeq, streamId, srcId, dstId)); + + ParrotFrame parrotFrame = ParrotFrame(); + parrotFrame.buffer = copy; + parrotFrame.bufferLen = len; + + parrotFrame.pktSeq = pktSeq; + parrotFrame.streamId = streamId; + parrotFrame.peerId = peerId; + + parrotFrame.srcId = srcId; + parrotFrame.dstId = dstId; + + m_parrotFrames.push_back(parrotFrame); } // process TSDU from peer @@ -376,11 +388,11 @@ void TagP25Data::playbackParrot() } auto& pkt = m_parrotFrames[0]; - if (std::get<0>(pkt) != nullptr) { + if (pkt.buffer != nullptr) { if (m_parrotFirstFrame) { if (m_network->m_parrotGrantDemand) { - uint32_t srcId = std::get<4>(pkt); - uint32_t dstId = std::get<5>(pkt); + uint32_t srcId = pkt.srcId; + uint32_t dstId = pkt.dstId; // create control data lc::LC control = lc::LC(); @@ -407,16 +419,24 @@ void TagP25Data::playbackParrot() m_parrotFirstFrame = false; } - // repeat traffic to the connected peers - for (auto peer : m_network->m_peers) { - m_network->writePeer(peer.first, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_P25 }, std::get<0>(pkt), std::get<1>(pkt), std::get<2>(pkt), std::get<3>(pkt), false); + if (m_network->m_parrotOnlyOriginating) { + m_network->writePeer(pkt.peerId, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_P25 }, pkt.buffer, pkt.bufferLen, pkt.pktSeq, pkt.streamId, false); if (m_network->m_debug) { LogDebug(LOG_NET, "P25, parrot, dstPeer = %u, len = %u, pktSeq = %u, streamId = %u", - peer.first, std::get<1>(pkt), std::get<2>(pkt), std::get<3>(pkt)); + pkt.peerId, pkt.bufferLen, pkt.pktSeq, pkt.streamId); + } + } else { + // repeat traffic to the connected peers + for (auto peer : m_network->m_peers) { + m_network->writePeer(peer.first, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_P25 }, pkt.buffer, pkt.bufferLen, pkt.pktSeq, pkt.streamId, false); + if (m_network->m_debug) { + LogDebug(LOG_NET, "P25, parrot, dstPeer = %u, len = %u, pktSeq = %u, streamId = %u", + peer.first, pkt.bufferLen, pkt.pktSeq, pkt.streamId); + } } } - delete std::get<0>(pkt); + delete pkt.buffer; } Thread::sleep(180); m_parrotFrames.pop_front(); diff --git a/src/fne/network/fne/TagP25Data.h b/src/fne/network/fne/TagP25Data.h index 9d302486..d265fd2d 100644 --- a/src/fne/network/fne/TagP25Data.h +++ b/src/fne/network/fne/TagP25Data.h @@ -67,7 +67,19 @@ namespace network private: FNENetwork* m_network; - std::deque> m_parrotFrames; + class ParrotFrame { + public: + uint8_t* buffer; + uint32_t bufferLen; + + uint16_t pktSeq; + uint32_t streamId; + uint32_t peerId; + + uint32_t srcId; + uint32_t dstId; + }; + std::deque m_parrotFrames; bool m_parrotFramesReady; bool m_parrotFirstFrame;