add support for C++ peers to trigger a radio alias sync request;

pull/134/head
Bryan Biedenkapp 2 weeks ago
parent 9e25bb8fbf
commit cfc036ca38

@ -218,6 +218,19 @@ bool BaseNetwork::writeUKEKReq(const uint32_t rsi)
return writeMaster({ NET_FUNC::KEY_KEK_REQ, NET_SUBFUNC::NOP }, buffer, modifyKeyCmd.fullLength() + 11U, RTP_END_OF_CALL_SEQ, 0U);
}
/* Requests the current radio alias table from the upstream master. */
bool BaseNetwork::writeRadioAliasSyncRequest()
{
using namespace p25::defines;
if (m_status != NET_STAT_RUNNING && m_status != NET_STAT_MST_RUNNING)
return false;
uint8_t buffer[1U] = { 0U };
return writeMaster({ NET_FUNC::RADIO_ALIAS_SYNC, NET_SUBFUNC::NOP }, buffer, 1U, RTP_END_OF_CALL_SEQ, 0U, true);
}
/* Writes the local activity log to the network. */
bool BaseNetwork::writeActLog(const char* message)

@ -484,6 +484,12 @@ namespace network
*/
bool writeUKEKReq(const uint32_t rsi);
/**
* @brief Requests the current radio alias table from the upstream master.
* @returns bool True, if the request was sent, otherwise false.
*/
bool writeRadioAliasSyncRequest();
/**
* @brief Writes the local activity log to the network.
* \code{.unparsed}

@ -49,6 +49,9 @@ Network::Network(const std::string& address, uint16_t port, uint16_t localPort,
m_saveLookup(saveLookup),
m_ridLookup(nullptr),
m_tidLookup(nullptr),
m_ridAliasLookup(nullptr),
m_radioAliasSyncPkt(true, "Radio Alias Sync"),
m_radioAliasSyncStreamId(0U),
m_salt(nullptr),
m_kmfPresharedKey(nullptr),
m_retryTimer(1000U, DEFAULT_RETRY_TIME),
@ -188,6 +191,13 @@ void Network::setLookups(lookups::RadioIdLookup* ridLookup, lookups::TalkgroupRu
m_tidLookup = tidLookup;
}
/* Sets the instance of the Radio Alias lookup table. */
void Network::setRadioAliasLookups(lookups::RadioAliasLookup* ridAliasLookup)
{
m_ridAliasLookup = ridAliasLookup;
}
/* Sets metadata configuration settings from the modem. */
void Network::setMetadata(const std::string& identity, uint32_t rxFrequency, uint32_t txFrequency, float txOffsetMhz, float chBandwidthKhz,
@ -344,6 +354,8 @@ void Network::clock(uint32_t ms)
{ NET_FUNC::MASTER, &Network::PacketHandler::master },
{ NET_FUNC::RADIO_ALIAS_SYNC, &Network::PacketHandler::radioAliasSync },
{ NET_FUNC::INCALL_CTRL, &Network::PacketHandler::inCallControl },
{ NET_FUNC::NAK, &Network::PacketHandler::nak },
@ -466,6 +478,9 @@ void Network::close()
writeMaster({ NET_FUNC::RPT_DISC, NET_SUBFUNC::NOP }, buffer, 1U, pktSeq(true), createStreamId());
}
m_radioAliasSyncPkt.clear();
m_radioAliasSyncStreamId = 0U;
m_socket->close();
m_retryTimer.stop();

@ -20,6 +20,8 @@
#include "common/network/BaseNetwork.h"
#include "common/network/RTPHeader.h"
#include "common/network/RTPFNEHeader.h"
#include "common/network/PacketBuffer.h"
#include "common/lookups/RadioAliasLookup.h"
#include "common/lookups/RadioIdLookup.h"
#include "common/lookups/TalkgroupRulesLookup.h"
#include "common/p25/kmm/KeysetItem.h"
@ -198,6 +200,12 @@ namespace network
* @param tidLookup Talkgroup Rules Lookup Table Instance
*/
void setLookups(lookups::RadioIdLookup* ridLookup, lookups::TalkgroupRulesLookup* tidLookup);
/**
* @brief Sets the instance of the Radio Alias lookup table.
* @param ridAliasLookup Radio Alias Lookup Table Instance.
*/
void setRadioAliasLookups(lookups::RadioAliasLookup* ridAliasLookup);
/**
* @brief Sets metadata configuration settings from the modem.
* @param identity Peer Identity.
@ -348,6 +356,10 @@ namespace network
lookups::RadioIdLookup* m_ridLookup;
lookups::TalkgroupRulesLookup* m_tidLookup;
lookups::RadioAliasLookup* m_ridAliasLookup;
PacketBuffer m_radioAliasSyncPkt;
uint32_t m_radioAliasSyncStreamId;
uint8_t* m_salt;
@ -484,6 +496,21 @@ namespace network
static bool master(Network* network, uint32_t peerId, uint32_t streamId, uint64_t now,
const frame::RTPFNEHeader& fneHeader, const frame::RTPHeader& rtpHeader, const uint8_t* buffer, int length);
/**
* @brief Handles NET_FUNC::RADIO_ALIAS_SYNC packets.
* @param network Instance of the Network class.
* @param peerId Peer ID.
* @param streamId Stream ID.
* @param now Current time in milliseconds.
* @param fneHeader RTP FNE Header.
* @param rtpHeader RTP Header.
* @param buffer Buffer containing the received message.
* @param length Length of buffer.
* @returns bool True, if packet processing should stop, otherwise false.
*/
static bool radioAliasSync(Network* network, uint32_t peerId, uint32_t streamId, uint64_t now,
const frame::RTPFNEHeader& fneHeader, const frame::RTPHeader& rtpHeader, const uint8_t* buffer, int length);
/**
* @brief Handles NET_FUNC::INCALL_CTRL packets.
* @param network Instance of the TrafficNetwork class.

@ -0,0 +1,113 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Digital Voice Modem - Common Library
* GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* Copyright (C) 2026 Bryan Biedenkapp, N2PLL
*
*/
#include "Defines.h"
#include "common/Log.h"
#include "network/Network.h"
using namespace network;
#include <cstdio>
#include <fstream>
#include <random>
#include <sstream>
// ---------------------------------------------------------------------------
// Public Class Members
// ---------------------------------------------------------------------------
/* Handles NET_FUNC::RADIO_ALIAS_SYNC packets. */
bool Network::PacketHandler::radioAliasSync(Network* network, uint32_t peerId, uint32_t streamId, uint64_t now,
const frame::RTPFNEHeader& fneHeader, const frame::RTPHeader& rtpHeader, const uint8_t* buffer, int length)
{
(void)peerId;
(void)now;
(void)rtpHeader;
if (fneHeader.getSubFunction() != NET_SUBFUNC::NOP)
return false;
if (network->m_radioAliasSyncStreamId == 0U || streamId != network->m_radioAliasSyncStreamId) {
LogWarning(LOG_NET, "PEER %u Radio Alias Sync, ignoring unexpected stream %u", network->m_peerId, streamId);
return true;
}
if (length < static_cast<int>(FRAG_SIZE)) {
LogWarning(LOG_NET, "PEER %u Radio Alias Sync, ignoring short fragment, length = %d", network->m_peerId, length);
network->m_radioAliasSyncPkt.clear();
network->m_radioAliasSyncStreamId = 0U;
return true;
}
uint32_t decodedLength = 0U;
uint8_t* decoded = nullptr;
if (!network->m_radioAliasSyncPkt.decode(buffer, &decoded, &decodedLength))
return true;
if (!network->m_enabled || !network->m_updateLookup || network->m_ridAliasLookup == nullptr || decodedLength == 0U) {
LogWarning(LOG_NET, "PEER %u Radio Alias Sync, alias lookup update is unavailable", network->m_peerId);
network->m_radioAliasSyncPkt.clear();
network->m_radioAliasSyncStreamId = 0U;
delete[] decoded;
return true;
}
std::ostringstream name;
std::random_device rd;
std::mt19937 mt(rd());
std::uniform_int_distribution<uint32_t> dist(0x00U, 0xFFFFFFFFU);
name << "/tmp/rid_alias.dat." << dist(mt);
const std::string tempFilename = name.str();
std::ofstream file(tempFilename, std::ios::out | std::ios::binary);
if (file.fail()) {
LogError(LOG_NET, "PEER %u Radio Alias Sync, cannot open temporary lookup file - %s",
network->m_peerId, tempFilename.c_str());
network->m_radioAliasSyncPkt.clear();
network->m_radioAliasSyncStreamId = 0U;
delete[] decoded;
return true;
}
file.write(reinterpret_cast<const char*>(decoded), decodedLength);
const bool writeFailed = file.fail();
file.close();
delete[] decoded;
if (writeFailed) {
LogError(LOG_NET, "PEER %u Radio Alias Sync, failed writing temporary lookup file - %s",
network->m_peerId, tempFilename.c_str());
::remove(tempFilename.c_str());
network->m_radioAliasSyncPkt.clear();
network->m_radioAliasSyncStreamId = 0U;
return true;
}
const std::string lookupFilename = network->m_ridAliasLookup->filename();
network->m_ridAliasLookup->filename(tempFilename);
const bool loaded = network->m_ridAliasLookup->reload();
network->m_ridAliasLookup->filename(lookupFilename);
if (loaded && network->m_saveLookup) {
network->m_ridAliasLookup->commit(true);
}
::remove(tempFilename.c_str());
if (!loaded) {
LogError(LOG_NET, "PEER %u Radio Alias Sync, received lookup table could not be loaded", network->m_peerId);
} else {
LogInfoEx(LOG_NET, "PEER %u Radio Alias Sync, lookup table updated", network->m_peerId);
}
network->m_radioAliasSyncPkt.clear();
network->m_radioAliasSyncStreamId = 0U;
return true;
}

@ -99,6 +99,7 @@ PeerNetwork::~PeerNetwork()
void PeerNetwork::setRadioAliasLookups(lookups::RadioAliasLookup* ridAliasLookup)
{
Network::setRadioAliasLookups(ridAliasLookup);
m_ridAliasLookup = ridAliasLookup;
}

Loading…
Cancel
Save

Powered by TurnKey Linux.