From 345495076b9f552f4c5a6fef8e9665d43ec61401 Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Fri, 2 Feb 2024 11:50:56 -0500 Subject: [PATCH] fix issue with the FNE not properly rewriting TGIDs for configured peers (the original implementation was slighly naive in assumptions, the new implementation techincally allows rewrites to *any* peer *from* any peer not just ISSI peers); perform some minor cleanup of the REST classes; revert change in ClientConnection and ServerConnection initializing the m_buffer class variable (hopefully this may fix some strange issues being seen); --- src/common/lookups/TalkgroupRulesLookup.cpp | 5 +-- src/common/lookups/TalkgroupRulesLookup.h | 3 +- .../network/rest/http/ClientConnection.h | 18 +++++----- src/common/network/rest/http/HTTPClient.h | 9 +++-- .../network/rest/http/HTTPRequestHandler.h | 7 ++-- src/common/network/rest/http/HTTPServer.h | 9 +++-- .../network/rest/http/ServerConnection.h | 14 ++++---- .../rest/http/ServerConnectionManager.h | 9 +++-- src/fne/HostFNE.cpp | 10 +++--- src/fne/network/fne/TagDMRData.cpp | 34 +++++++++++-------- src/fne/network/fne/TagDMRData.h | 4 +-- src/fne/network/fne/TagNXDNData.cpp | 26 ++++++++------ src/fne/network/fne/TagNXDNData.h | 2 +- src/fne/network/fne/TagP25Data.cpp | 32 +++++++++-------- src/fne/network/fne/TagP25Data.h | 2 +- 15 files changed, 95 insertions(+), 89 deletions(-) diff --git a/src/common/lookups/TalkgroupRulesLookup.cpp b/src/common/lookups/TalkgroupRulesLookup.cpp index d627f141..9ad4b4a2 100644 --- a/src/common/lookups/TalkgroupRulesLookup.cpp +++ b/src/common/lookups/TalkgroupRulesLookup.cpp @@ -262,7 +262,8 @@ TalkgroupRuleGroupVoice TalkgroupRulesLookup::findByRewrite(uint32_t peerId, uin if (x.config().rewrite().size() == 0) return false; - auto innerIt = std::find_if(x.config().rewrite().begin(), x.config().rewrite().end(), + std::vector rewrite = x.config().rewrite(); + auto innerIt = std::find_if(rewrite.begin(), rewrite.end(), [&](TalkgroupRuleRewrite y) { if (slot != 0U) { @@ -272,7 +273,7 @@ TalkgroupRuleGroupVoice TalkgroupRulesLookup::findByRewrite(uint32_t peerId, uin return y.peerId() == peerId && y.tgId() == id; }); - if (innerIt != x.config().rewrite().end()) + if (innerIt != rewrite.end()) return true; return false; }); diff --git a/src/common/lookups/TalkgroupRulesLookup.h b/src/common/lookups/TalkgroupRulesLookup.h index 912f6b19..923823ae 100644 --- a/src/common/lookups/TalkgroupRulesLookup.h +++ b/src/common/lookups/TalkgroupRulesLookup.h @@ -85,7 +85,7 @@ namespace lookups TalkgroupRuleRewrite(yaml::Node& node) : TalkgroupRuleRewrite() { - m_peerId = node["peerId"].as(0U); + m_peerId = node["peerid"].as(0U); m_tgId = node["tgid"].as(0U); m_tgSlot = (uint8_t)node["slot"].as(0U); } @@ -169,6 +169,7 @@ namespace lookups m_parrot = data.m_parrot; m_inclusion = data.m_inclusion; m_exclusion = data.m_exclusion; + m_rewrite = data.m_rewrite; } return *this; diff --git a/src/common/network/rest/http/ClientConnection.h b/src/common/network/rest/http/ClientConnection.h index b2e9d99d..8616b431 100644 --- a/src/common/network/rest/http/ClientConnection.h +++ b/src/common/network/rest/http/ClientConnection.h @@ -38,20 +38,18 @@ namespace network template class ClientConnection { public: + auto operator=(ClientConnection&) -> ClientConnection& = delete; + auto operator=(ClientConnection&&) -> ClientConnection& = delete; + ClientConnection(ClientConnection&) = delete; + /// Initializes a new instance of the ClientConnection class. explicit ClientConnection(asio::ip::tcp::socket socket, RequestHandlerType& handler) : m_socket(std::move(socket)), m_requestHandler(handler), - m_buffer(), m_lexer(HTTPLexer(true)) { /* stub */ } - /// Initializes a copy instance of the ClientConnection class. - ClientConnection(const ClientConnection&) = delete; - - /// - ClientConnection& operator=(const ClientConnection&) = delete; /// Start the first asynchronous operation for the connection. void start() { read(); } @@ -81,7 +79,7 @@ namespace network { asio::error_code ec = e.code(); if (ec) { - ::LogError(LOG_REST, "%s, code = %u", ec.message().c_str(), ec.value()); + ::LogError(LOG_REST, "ClientConnection::ensureNoLinger(), %s, code = %u", ec.message().c_str(), ec.value()); } } } @@ -123,7 +121,7 @@ namespace network } else if (ec != asio::error::operation_aborted) { if (ec) { - ::LogError(LOG_REST, "%s, code = %u", ec.message().c_str(), ec.value()); + ::LogError(LOG_REST, "ClientConnection::read(), %s, code = %u", ec.message().c_str(), ec.value()); } stop(); } @@ -150,7 +148,9 @@ namespace network asio::error_code ignored_ec; m_socket.shutdown(asio::ip::tcp::socket::shutdown_both, ignored_ec); } - catch(const std::exception& e) { ::LogError(LOG_REST, "%s", ec.message().c_str()); } + catch(const std::exception& e) { + ::LogError(LOG_REST, "ClientConnection::write(), %s, code = %u", ec.message().c_str(), ec.value()); + } } } } diff --git a/src/common/network/rest/http/HTTPClient.h b/src/common/network/rest/http/HTTPClient.h index 86dee83b..7d544f2a 100644 --- a/src/common/network/rest/http/HTTPClient.h +++ b/src/common/network/rest/http/HTTPClient.h @@ -42,6 +42,10 @@ namespace network template class ConnectionImpl = ClientConnection> class HTTPClient : private Thread { public: + auto operator=(HTTPClient&) -> HTTPClient& = delete; + auto operator=(HTTPClient&&) -> HTTPClient& = delete; + HTTPClient(HTTPClient&) = delete; + /// Initializes a new instance of the HTTPClient class. HTTPClient(const std::string& address, uint16_t port) : m_address(address), @@ -53,8 +57,6 @@ namespace network { /* stub */ } - /// Initializes a copy instance of the HTTPClient class. - HTTPClient(const HTTPClient&) = delete; /// Finalizes a instance of the HTTPClient class. ~HTTPClient() override { @@ -63,9 +65,6 @@ namespace network } } - /// - HTTPClient& operator=(const HTTPClient&) = delete; - /// Helper to set the HTTP request handlers. template void setHandler(Handler&& handler) diff --git a/src/common/network/rest/http/HTTPRequestHandler.h b/src/common/network/rest/http/HTTPRequestHandler.h index 04137ea1..45d26f19 100644 --- a/src/common/network/rest/http/HTTPRequestHandler.h +++ b/src/common/network/rest/http/HTTPRequestHandler.h @@ -39,15 +39,14 @@ namespace network class HTTPRequestHandler { public: + auto operator=(HTTPRequestHandler&) -> HTTPRequestHandler& = delete; + HTTPRequestHandler(HTTPRequestHandler&) = delete; + /// Initializes a new instance of the HTTPRequestHandler class. explicit HTTPRequestHandler(const std::string& docRoot); - /// Initializes a copy instance of the HTTPRequestHandler class. - HTTPRequestHandler(const HTTPRequestHandler&) = delete; /// HTTPRequestHandler(HTTPRequestHandler&&) = default; - /// - HTTPRequestHandler& operator=(const HTTPRequestHandler&) = delete; /// HTTPRequestHandler& operator=(HTTPRequestHandler&&) = default; diff --git a/src/common/network/rest/http/HTTPServer.h b/src/common/network/rest/http/HTTPServer.h index a06b64e0..fccd1bba 100644 --- a/src/common/network/rest/http/HTTPServer.h +++ b/src/common/network/rest/http/HTTPServer.h @@ -43,6 +43,10 @@ namespace network template class ConnectionImpl = ServerConnection> class HTTPServer { public: + auto operator=(HTTPServer&) -> HTTPServer& = delete; + auto operator=(HTTPServer&&) -> HTTPServer& = delete; + HTTPServer(HTTPServer&) = delete; + /// Initializes a new instance of the HTTPServer class. explicit HTTPServer(const std::string& address, uint16_t port) : m_ioService(), @@ -63,11 +67,6 @@ namespace network accept(); } - /// Initializes a copy instance of the HTTPServer class. - HTTPServer(const HTTPServer&) = delete; - - /// - HTTPServer& operator=(const HTTPServer&) = delete; /// Helper to set the HTTP request handlers. template diff --git a/src/common/network/rest/http/ServerConnection.h b/src/common/network/rest/http/ServerConnection.h index fd6ce928..83beeb2d 100644 --- a/src/common/network/rest/http/ServerConnection.h +++ b/src/common/network/rest/http/ServerConnection.h @@ -49,23 +49,21 @@ namespace network typedef std::shared_ptr selfTypePtr; typedef ServerConnectionManager ConnectionManagerType; public: + auto operator=(ServerConnection&) -> ServerConnection& = delete; + auto operator=(ServerConnection&&) -> ServerConnection& = delete; + ServerConnection(ServerConnection&) = delete; + /// Initializes a new instance of the ServerConnection class. explicit ServerConnection(asio::ip::tcp::socket socket, ConnectionManagerType& manager, RequestHandlerType& handler, bool persistent = false) : m_socket(std::move(socket)), m_connectionManager(manager), m_requestHandler(handler), - m_buffer(), m_lexer(HTTPLexer(false)), m_persistent(persistent) { /* stub */ } - /// Initializes a copy instance of the ServerConnection class. - ServerConnection(const ServerConnection&) = delete; - - /// - ServerConnection& operator=(const ServerConnection&) = delete; /// Start the first asynchronous operation for the connection. void start() { read(); } @@ -118,7 +116,7 @@ namespace network } else if (ec != asio::error::operation_aborted) { if (ec) { - ::LogError(LOG_REST, "%s, code = %u", ec.message().c_str(), ec.value()); + ::LogError(LOG_REST, "ServerConnection::read(), %s, code = %u", ec.message().c_str(), ec.value()); } m_connectionManager.stop(this->shared_from_this()); } @@ -157,7 +155,7 @@ namespace network if (ec != asio::error::operation_aborted) { if (ec) { - ::LogError(LOG_REST, "%s, code = %u", ec.message().c_str(), ec.value()); + ::LogError(LOG_REST, "ServerConnection::write(), %s, code = %u", ec.message().c_str(), ec.value()); } m_connectionManager.stop(this->shared_from_this()); } diff --git a/src/common/network/rest/http/ServerConnectionManager.h b/src/common/network/rest/http/ServerConnectionManager.h index 8d43e53b..85e18be4 100644 --- a/src/common/network/rest/http/ServerConnectionManager.h +++ b/src/common/network/rest/http/ServerConnectionManager.h @@ -36,13 +36,12 @@ namespace network template class ServerConnectionManager { public: + auto operator=(ServerConnectionManager&) -> ServerConnectionManager& = delete; + auto operator=(ServerConnectionManager&&) -> ServerConnectionManager& = delete; + ServerConnectionManager(ServerConnectionManager&) = delete; + /// Initializes a new instance of the ServerConnectionManager class. ServerConnectionManager() = default; - /// Initializes a copy instance of the ServerConnectionManager class. - ServerConnectionManager(const ServerConnectionManager&) = delete; - - /// - ServerConnectionManager& operator=(const ServerConnectionManager&) = delete; /// Add the specified connection to the manager and start it. void start(ConnectionPtr c) diff --git a/src/fne/HostFNE.cpp b/src/fne/HostFNE.cpp index 8669b291..8840dbc5 100644 --- a/src/fne/HostFNE.cpp +++ b/src/fne/HostFNE.cpp @@ -491,7 +491,7 @@ bool HostFNE::createPeerNetworks() if (key.size() == 32) { // bryanb: shhhhhhh....dirty nasty hacks key = key.append(key); // since the key is 32 characters (16 hex pairs), double it on itself for 64 characters (32 hex pairs) - LogWarning(LOG_HOST, "Half-length peer network preshared encryption key detected, doubling key on itself."); + LogWarning(LOG_HOST, "Half-length peer %u network preshared encryption key detected, doubling key on itself.", id); } if (key.size() == 64) { @@ -534,7 +534,7 @@ bool HostFNE::createPeerNetworks() network::PeerNetwork* network = new PeerNetwork(masterAddress, masterPort, 0U, id, password, true, debug, m_dmrEnabled, m_p25Enabled, m_nxdnEnabled, true, true, m_allowActivityTransfer, m_allowDiagnosticTransfer, false); network->setMetadata(identity, rxFrequency, txFrequency, 0.0F, 0.0F, 0, 0, 0, latitude, longitude, 0, location); if (encrypted) { - m_network->setPresharedKey(presharedKey); + network->setPresharedKey(presharedKey); } network->enable(enabled); @@ -576,7 +576,7 @@ void HostFNE::processPeer(network::PeerNetwork* peerNetwork) uint32_t slotNo = (data[15U] & 0x80U) == 0x80U ? 2U : 1U; uint32_t streamId = peerNetwork->getDMRStreamId(slotNo); - m_network->dmrTrafficHandler()->processFrame(data.get(), length, peerId, peerNetwork->pktLastSeq(), streamId, true); + m_network->dmrTrafficHandler()->processFrame(data.get(), length, peerId, peerNetwork->pktLastSeq(), streamId); } } @@ -589,7 +589,7 @@ void HostFNE::processPeer(network::PeerNetwork* peerNetwork) uint32_t peerId = peerNetwork->getPeerId(); uint32_t streamId = peerNetwork->getP25StreamId(); - m_network->p25TrafficHandler()->processFrame(data.get(), length, peerId, peerNetwork->pktLastSeq(), streamId, true); + m_network->p25TrafficHandler()->processFrame(data.get(), length, peerId, peerNetwork->pktLastSeq(), streamId); } } @@ -602,7 +602,7 @@ void HostFNE::processPeer(network::PeerNetwork* peerNetwork) uint32_t peerId = peerNetwork->getPeerId(); uint32_t streamId = peerNetwork->getNXDNStreamId(); - m_network->nxdnTrafficHandler()->processFrame(data.get(), length, peerId, peerNetwork->pktLastSeq(), streamId, true); + m_network->nxdnTrafficHandler()->processFrame(data.get(), length, peerId, peerNetwork->pktLastSeq(), streamId); } } } \ No newline at end of file diff --git a/src/fne/network/fne/TagDMRData.cpp b/src/fne/network/fne/TagDMRData.cpp index e4da77c0..4389df27 100644 --- a/src/fne/network/fne/TagDMRData.cpp +++ b/src/fne/network/fne/TagDMRData.cpp @@ -60,9 +60,8 @@ TagDMRData::~TagDMRData() = default; /// Peer ID /// /// Stream ID -/// Flag indicating whether this traffic is from a peer connection or not. /// -bool TagDMRData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId, uint16_t pktSeq, uint32_t streamId, bool fromPeer) +bool TagDMRData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId, uint16_t pktSeq, uint32_t streamId) { hrc::hrc_t pktTime = hrc::now(); @@ -108,11 +107,9 @@ bool TagDMRData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId dmrData.setN(n); } - // is this data from a peer connection? - if (fromPeer) { - // perform TGID route rewrites if configured - routeRewrite(buffer, peerId, dmrData, dataType, dstId, slotNo, false); - } + // perform TGID route rewrites if configured + routeRewrite(buffer, peerId, dmrData, dataType, dstId, slotNo, false); + dstId = __GET_UINT16(buffer, 8U); // is the stream valid? if (validate(peerId, dmrData, streamId)) { @@ -211,7 +208,14 @@ bool TagDMRData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId continue; } - m_network->writePeer(peer.first, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_DMR }, buffer, len, pktSeq, streamId, true); + uint8_t outboundPeerBuffer[len]; + ::memset(outboundPeerBuffer, 0x00U, len); + ::memcpy(outboundPeerBuffer, buffer, len); + + // perform TGID route rewrites if configured + routeRewrite(outboundPeerBuffer, peer.first, dmrData, dataType, dstId, slotNo); + + m_network->writePeer(peer.first, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_DMR }, outboundPeerBuffer, len, pktSeq, streamId, true); if (m_network->m_debug) { LogDebug(LOG_NET, "DMR, srcPeer = %u, dstPeer = %u, seqNo = %u, srcId = %u, dstId = %u, flco = $%02X, slotNo = %u, len = %u, pktSeq = %u, stream = %u", peerId, peer.first, seqNo, srcId, dstId, flco, slotNo, len, pktSeq, streamId); @@ -303,7 +307,7 @@ void TagDMRData::playbackParrot() /// /// /// -void TagDMRData::routeRewrite(uint8_t* buffer, uint32_t peerId, dmr::data::Data dmrData, uint8_t dataType, uint32_t dstId, uint32_t slotNo, bool outbound) +void TagDMRData::routeRewrite(uint8_t* buffer, uint32_t peerId, dmr::data::Data& dmrData, uint8_t dataType, uint32_t dstId, uint32_t slotNo, bool outbound) { uint32_t rewriteDstId = dstId; uint32_t rewriteSlotNo = slotNo; @@ -369,10 +373,10 @@ bool TagDMRData::peerRewrite(uint32_t peerId, uint32_t& dstId, uint32_t& slotNo, { lookups::TalkgroupRuleGroupVoice tg; if (outbound) { - tg = m_network->m_tidLookup->find(dstId, slotNo); + tg = m_network->m_tidLookup->find(dstId); } else { - tg = m_network->m_tidLookup->findByRewrite(peerId, dstId, slotNo); + tg = m_network->m_tidLookup->findByRewrite(peerId, dstId); } std::vector rewrites = tg.config().rewrite(); @@ -382,13 +386,13 @@ bool TagDMRData::peerRewrite(uint32_t peerId, uint32_t& dstId, uint32_t& slotNo, for (auto entry : rewrites) { if (entry.peerId() == peerId) { if (outbound) { - dstId = tg.source().tgId(); - slotNo = tg.source().tgSlot(); - } - else { dstId = entry.tgId(); slotNo = entry.tgSlot(); } + else { + dstId = tg.source().tgId(); + slotNo = tg.source().tgSlot(); + } rewrote = true; break; } diff --git a/src/fne/network/fne/TagDMRData.h b/src/fne/network/fne/TagDMRData.h index 89855ae4..0dc79703 100644 --- a/src/fne/network/fne/TagDMRData.h +++ b/src/fne/network/fne/TagDMRData.h @@ -38,7 +38,7 @@ namespace network ~TagDMRData(); /// 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 fromPeer = false); + bool processFrame(const uint8_t* data, uint32_t len, uint32_t peerId, uint16_t pktSeq, uint32_t streamId); /// Helper to playback a parrot frame to the network. void playbackParrot(); @@ -65,7 +65,7 @@ namespace network bool m_debug; /// Helper to route rewrite the network data buffer. - void routeRewrite(uint8_t* buffer, uint32_t peerId, dmr::data::Data dmrData, uint8_t dataType, uint32_t dstId, uint32_t slotNo, bool outbound = true); + void routeRewrite(uint8_t* buffer, uint32_t peerId, dmr::data::Data& dmrData, uint8_t dataType, uint32_t dstId, uint32_t slotNo, bool outbound = true); /// Helper to route rewrite destination ID and slot. bool peerRewrite(uint32_t peerId, uint32_t& dstId, uint32_t& slotNo, bool outbound = true); diff --git a/src/fne/network/fne/TagNXDNData.cpp b/src/fne/network/fne/TagNXDNData.cpp index 3da4ce40..e53d94b2 100644 --- a/src/fne/network/fne/TagNXDNData.cpp +++ b/src/fne/network/fne/TagNXDNData.cpp @@ -59,9 +59,8 @@ TagNXDNData::~TagNXDNData() = default; /// Peer ID /// /// Stream ID -/// Flag indicating whether this traffic is from a peer connection or not. /// -bool TagNXDNData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId, uint16_t pktSeq, uint32_t streamId, bool fromPeer) +bool TagNXDNData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId, uint16_t pktSeq, uint32_t streamId) { hrc::hrc_t pktTime = hrc::now(); @@ -74,6 +73,10 @@ bool TagNXDNData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerI uint32_t srcId = __GET_UINT16(data, 5U); uint32_t dstId = __GET_UINT16(data, 8U); + // perform TGID route rewrites if configured + routeRewrite(buffer, peerId, messageType, dstId, false); + dstId = __GET_UINT16(buffer, 8U); + lc::RTCH lc; lc.setMessageType(messageType); @@ -83,12 +86,6 @@ bool TagNXDNData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerI bool group = (data[15U] & 0x40U) == 0x40U ? false : true; lc.setGroup(group); - // is this data from a peer connection? - if (fromPeer) { - // perform TGID route rewrites if configured - routeRewrite(buffer, peerId, messageType, dstId, false); - } - // is the stream valid? if (validate(peerId, lc, messageType, streamId)) { // is this peer ignored? @@ -181,7 +178,14 @@ bool TagNXDNData::processFrame(const uint8_t* data, uint32_t len, uint32_t peerI continue; } - m_network->writePeer(peer.first, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_NXDN }, buffer, len, pktSeq, streamId, true); + uint8_t outboundPeerBuffer[len]; + ::memset(outboundPeerBuffer, 0x00U, len); + ::memcpy(outboundPeerBuffer, buffer, len); + + // perform TGID route rewrites if configured + routeRewrite(outboundPeerBuffer, peer.first, messageType, dstId); + + m_network->writePeer(peer.first, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_NXDN }, outboundPeerBuffer, len, pktSeq, streamId, true); if (m_network->m_debug) { LogDebug(LOG_NET, "NXDN, srcPeer = %u, dstPeer = %u, messageType = $%02X, srcId = %u, dstId = %u, len = %u, pktSeq = %u, streamId = %u", peerId, peer.first, messageType, srcId, dstId, len, pktSeq, streamId); @@ -305,10 +309,10 @@ bool TagNXDNData::peerRewrite(uint32_t peerId, uint32_t& dstId, bool outbound) for (auto entry : rewrites) { if (entry.peerId() == peerId) { if (outbound) { - dstId = tg.source().tgId(); + dstId = entry.tgId(); } else { - dstId = entry.tgId(); + dstId = tg.source().tgId(); } rewrote = true; break; diff --git a/src/fne/network/fne/TagNXDNData.h b/src/fne/network/fne/TagNXDNData.h index b8dcdfbb..531c1207 100644 --- a/src/fne/network/fne/TagNXDNData.h +++ b/src/fne/network/fne/TagNXDNData.h @@ -38,7 +38,7 @@ namespace network ~TagNXDNData(); /// 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 fromPeer = false); + bool processFrame(const uint8_t* data, uint32_t len, 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 a439a17a..9eab1249 100644 --- a/src/fne/network/fne/TagP25Data.cpp +++ b/src/fne/network/fne/TagP25Data.cpp @@ -62,9 +62,8 @@ TagP25Data::~TagP25Data() = default; /// Peer ID /// /// Stream ID -/// Flag indicating whether this traffic is from a peer connection or not. /// -bool TagP25Data::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId, uint16_t pktSeq, uint32_t streamId, bool fromPeer) +bool TagP25Data::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId, uint16_t pktSeq, uint32_t streamId) { hrc::hrc_t pktTime = hrc::now(); @@ -85,6 +84,10 @@ bool TagP25Data::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId uint8_t duid = data[22U]; uint8_t frameType = P25_FT_DATA_UNIT; + // perform TGID route rewrites if configured + routeRewrite(buffer, peerId, duid, dstId, false); + dstId = __GET_UINT16(buffer, 8U); + lc::LC control; data::LowSpeedData lsd; @@ -127,12 +130,6 @@ bool TagP25Data::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId lsd.setLSD1(lsd1); lsd.setLSD2(lsd2); - // is this data from a peer connection? - if (fromPeer) { - // perform TGID route rewrites if configured - routeRewrite(buffer, peerId, duid, dstId, false); - } - // is the stream valid? if (validate(peerId, control, duid, streamId)) { // is this peer ignored? @@ -233,7 +230,14 @@ bool TagP25Data::processFrame(const uint8_t* data, uint32_t len, uint32_t peerId continue; } - m_network->writePeer(peer.first, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_P25 }, buffer, len, pktSeq, streamId, true); + uint8_t outboundPeerBuffer[len]; + ::memset(outboundPeerBuffer, 0x00U, len); + ::memcpy(outboundPeerBuffer, buffer, len); + + // perform TGID route rewrites if configured + routeRewrite(outboundPeerBuffer, peer.first, duid, dstId); + + m_network->writePeer(peer.first, { NET_FUNC_PROTOCOL, NET_PROTOCOL_SUBFUNC_P25 }, outboundPeerBuffer, len, pktSeq, streamId, true); if (m_network->m_debug) { LogDebug(LOG_NET, "P25, srcPeer = %u, dstPeer = %u, duid = $%02X, lco = $%02X, MFId = $%02X, srcId = %u, dstId = %u, len = %u, pktSeq = %u, streamId = %u", peerId, peer.first, duid, lco, MFId, srcId, dstId, len, pktSeq, streamId); @@ -429,23 +433,21 @@ bool TagP25Data::peerRewrite(uint32_t peerId, uint32_t& dstId, bool outbound) std::vector rewrites = tg.config().rewrite(); - bool rewrote = false; if (rewrites.size() > 0) { for (auto entry : rewrites) { if (entry.peerId() == peerId) { if (outbound) { - dstId = tg.source().tgId(); + dstId = entry.tgId(); } else { - dstId = entry.tgId(); + dstId = tg.source().tgId(); } - rewrote = true; - break; + return true; } } } - return rewrote; + return false; } /// diff --git a/src/fne/network/fne/TagP25Data.h b/src/fne/network/fne/TagP25Data.h index 92e21296..3cdd9341 100644 --- a/src/fne/network/fne/TagP25Data.h +++ b/src/fne/network/fne/TagP25Data.h @@ -44,7 +44,7 @@ namespace network ~TagP25Data(); /// 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 fromPeer = false); + bool processFrame(const uint8_t* data, uint32_t len, uint32_t peerId, uint16_t pktSeq, uint32_t streamId); /// Helper to playback a parrot frame to the network. void playbackParrot();