You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
dvmhost/src/common/network/Network.h

343 lines
13 KiB

// 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) 2017-2025 Bryan Biedenkapp, N2PLL
*
*/
/**
* @file Network.h
* @ingroup network_core
* @file Network.cpp
* @ingroup network_core
*/
#if !defined(__NETWORK_H__)
#define __NETWORK_H__
#include "common/Defines.h"
#include "common/network/BaseNetwork.h"
#include "common/lookups/RadioIdLookup.h"
#include "common/lookups/TalkgroupRulesLookup.h"
#include "common/p25/kmm/KeysetItem.h"
#include <string>
#include <cstdint>
#include <functional>
namespace network
{
// ---------------------------------------------------------------------------
// Structure Declaration
// ---------------------------------------------------------------------------
/**
* @brief This structure represents a peer metadata.
* @ingroup network_core
*/
struct PeerMetadata {
/** @name Identity and Frequency */
std::string identity; //! Peer Identity
uint32_t rxFrequency; //! Peer Rx Frequency
uint32_t txFrequency; //! Peer Tx Frequency
/** @} */
/** @name System Info */
uint32_t power; //! Peer Tx Power (W)
float latitude; //! Location Latitude (decmial notation)
float longitude; //! Location Longitude (decmial notation)
int height; //! Height (M)
std::string location; //! Textual Location
/** @} */
/** @name Channel Data */
float txOffsetMhz; //! Tx Offset (MHz)
float chBandwidthKhz; //! Channel Bandwidth (kHz)
uint8_t channelId; //! Channel ID
uint32_t channelNo; //! Channel Number
/** @} */
/** @name RCON */
std::string restApiPassword; //! REST API Password
uint16_t restApiPort; //! REST API Port
/** @} */
/** @name Flags */
bool isConventional; //! Flag indicating peer is a conventional peer.
/** @} */
};
// ---------------------------------------------------------------------------
// Class Declaration
// ---------------------------------------------------------------------------
/**
* @brief Implements the core peer networking logic.
* @ingroup network_core
*/
class HOST_SW_API Network : public BaseNetwork {
public:
/**
* @brief Initializes a new instance of the Network class.
* @param address Network Hostname/IP address to connect to.
* @param port Network port number.
* @param localPort
* @param peerId Unique ID on the network.
* @param password Network authentication password.
* @param duplex Flag indicating full-duplex operation.
* @param debug Flag indicating whether network debug is enabled.
* @param dmr Flag indicating whether DMR is enabled.
* @param p25 Flag indicating whether P25 is enabled.
* @param nxdn Flag indicating whether NXDN is enabled.
* @param slot1 Flag indicating whether DMR slot 1 is enabled for network traffic.
* @param slot2 Flag indicating whether DMR slot 2 is enabled for network traffic.
* @param allowActivityTransfer Flag indicating that the system activity logs will be sent to the network.
* @param allowDiagnosticTransfer Flag indicating that the system diagnostic logs will be sent to the network.
* @param updateLookup Flag indicating that the system will accept radio ID and talkgroup ID lookups from the network.
*/
Network(const std::string& address, uint16_t port, uint16_t localPort, uint32_t peerId, const std::string& password,
bool duplex, bool debug, bool dmr, bool p25, bool nxdn, bool slot1, bool slot2, bool allowActivityTransfer, bool allowDiagnosticTransfer, bool updateLookup, bool saveLookup);
/**
* @brief Finalizes a instance of the Network class.
*/
~Network() override;
/**
* @brief Resets the DMR ring buffer for the given slot.
* @param slotNo DMR slot ring buffer to reset.
*/
void resetDMR(uint32_t slotNo) override;
/**
* @brief Resets the P25 ring buffer.
*/
void resetP25() override;
/**
* @brief Resets the NXDN ring buffer.
*/
void resetNXDN() override;
/**
* @brief Sets the instances of the Radio ID and Talkgroup ID lookup tables.
* @param ridLookup Radio ID Lookup Table Instance
* @param tidLookup Talkgroup Rules Lookup Table Instance
*/
void setLookups(lookups::RadioIdLookup* ridLookup, lookups::TalkgroupRulesLookup* tidLookup);
/**
* @brief Sets metadata configuration settings from the modem.
* @param identity Peer Identity.
* @param rxFrequency Rx Frequency (Informational Only).
* @param txFrequency Tx Frequency (Informational Only).
* @param txOffsetMhz Tx Offset in MHz (Informational Only).
* @param chBandwidthKhz Channel Bandwidth in kHz (Informational Only).
* @param channelId Channel ID (Informational Only).
* @param channelNo Channel Number (Informational Only).
* @param power RF Power Level (Informational Only).
* @param latitude Geographic Latitude (Informational Only).
* @param longitude Geographic Longitude (Informational Only).
* @param height Station Height in Meters (Informational Only).
* @param location Textual Location (Informational Only).
*/
void setMetadata(const std::string& identity, uint32_t rxFrequency, uint32_t txFrequency, float txOffsetMhz, float chBandwidthKhz,
uint8_t channelId, uint32_t channelNo, uint32_t power, float latitude, float longitude, int height, const std::string& location);
/**
* @brief Sets REST API configuration settings from the modem.
* @param password REST API Password.
* @param port REST API Port.
*/
void setRESTAPIData(const std::string& password, uint16_t port);
/**
* @brief Sets a flag indicating whether the conventional option is sent to the FNE.
* @param conv Flag indicating conventional operation.
*/
void setConventional(bool conv) { m_metadata->isConventional = conv; }
/**
* @brief Sets endpoint preshared encryption key.
* @param presharedKey Encryption preshared key for networking.
*/
void setPresharedKey(const uint8_t* presharedKey);
/**
* @brief Updates the timer by the passed number of milliseconds.
* @param ms Number of milliseconds.
*/
void clock(uint32_t ms) override;
/**
* @brief Opens connection to the network.
* @returns bool True, if networking has started, otherwise false.
*/
bool open() override;
/**
* @brief Closes connection to the network.
*/
void close() override;
/**
* @brief Flag indicating if this network connection enabled.
* @returns bool Flag indicating if this network connection enabled.
*/
bool isEnabled() const { return m_enabled; }
/**
* @brief Sets flag enabling network communication.
* @param enabled Flag indicating if this network connection enabled.
*/
void enable(bool enabled);
/**
* @brief Helper to set the peer connected callback.
* @param callback
*/
void setPeerConnectedCallback(std::function<void()>&& callback) { m_peerConnectedCallback = callback; }
/**
* @brief Helper to set the peer disconnected callback.
* @param callback
*/
void setPeerDisconnectedCallback(std::function<void()>&& callback) { m_peerDisconnectedCallback = callback; }
/**
* @brief Helper to set the DMR In-Call Control callback.
* @param callback
*/
void setDMRICCCallback(std::function<void(NET_ICC::ENUM, uint32_t, uint8_t)>&& callback) { m_dmrInCallCallback = callback; }
/**
* @brief Helper to set the P25 In-Call Control callback.
* @param callback
*/
void setP25ICCCallback(std::function<void(NET_ICC::ENUM, uint32_t)>&& callback) { m_p25InCallCallback = callback; }
/**
* @brief Helper to set the NXDN In-Call Control callback.
* @param callback
*/
void setNXDNICCCallback(std::function<void(NET_ICC::ENUM, uint32_t)>&& callback) { m_nxdnInCallCallback = callback; }
/**
* @brief Helper to set the enc. key response callback.
* @param callback
*/
void setKeyResponseCallback(std::function<void(p25::kmm::KeyItem, uint8_t, uint8_t)>&& callback) { m_keyRespCallback = callback; }
public:
/**
* @brief Last received RTP sequence number.
*/
__READONLY_PROPERTY_PLAIN(uint16_t, pktLastSeq);
protected:
std::string m_address;
uint16_t m_port;
std::string m_password;
bool m_enabled;
bool m_dmrEnabled;
bool m_p25Enabled;
bool m_nxdnEnabled;
bool m_updateLookup;
bool m_saveLookup;
lookups::RadioIdLookup* m_ridLookup;
lookups::TalkgroupRulesLookup* m_tidLookup;
uint8_t* m_salt;
Timer m_retryTimer;
Timer m_timeoutTimer;
uint32_t* m_rxDMRStreamId;
uint32_t m_rxP25StreamId;
uint32_t m_rxNXDNStreamId;
uint16_t m_pktSeq;
uint32_t m_loginStreamId;
PeerMetadata* m_metadata;
uint32_t m_remotePeerId;
/**
* @brief Flag indicating this peer will not perform peer ID checking and will process most incoming packets.
*/
bool m_promiscuousPeer;
/**
* @brief Flag indicating this peer will not handle protocol processing internally, and will forward processing
* to the defined user packet handler.
*/
bool m_userHandleProtocol;
/**
* @brief Flag indicating this peer will not disable networking services on a master ACL NAK.
*/
bool m_neverDisableOnACLNAK;
/**
* @brief Peer Connected Function Callback.
* (This is called once this peer connects (or reconnects) to an upstream master.)
*/
std::function<void()> m_peerConnectedCallback;
/**
* @brief Peer Disconnected Function Callback.
* (This is called once this peer disconnects from an upstream master.)
*/
std::function<void()> m_peerDisconnectedCallback;
/**
* @brief DMR In-Call Control Function Callback.
* (This is called when the master sends a In-Call Control request.)
*/
std::function<void(NET_ICC::ENUM command, uint32_t dstId, uint8_t slotNo)> m_dmrInCallCallback;
/**
* @brief P25 In-Call Control Function Callback.
* (This is called once the master sends a In-Call Control request.)
*/
std::function<void(NET_ICC::ENUM command, uint32_t dstId)> m_p25InCallCallback;
/**
* @brief NXDN In-Call Control Function Callback.
* (This is called once the master sends a In-Call Control request.)
*/
std::function<void(NET_ICC::ENUM command, uint32_t dstId)> m_nxdnInCallCallback;
/**
* @brief Encryption Key Response Function Callback.
* (This is called once the master responds to a key request.)
*/
std::function<void(p25::kmm::KeyItem ki, uint8_t algId, uint8_t keyLength)> m_keyRespCallback;
/**
* @brief User overrideable handler that allows user code to process network packets not handled by this class.
* @param peerId Peer ID.
* @param opcode FNE network opcode pair.
* @param[in] data Buffer containing message to send to peer.
* @param length Length of buffer.
* @param streamId Stream ID.
*/
virtual void userPacketHandler(uint32_t peerId, FrameQueue::OpcodePair opcode, const uint8_t* data = nullptr, uint32_t length = 0U,
uint32_t streamId = 0U);
/**
* @brief Writes login request to the network.
* @returns bool True, if login request was sent, otherwise false.
*/
bool writeLogin();
/**
* @brief Writes network authentication challenge.
* @returns bool True, if authorization response was sent, otherwise false.
*/
bool writeAuthorisation();
/**
* @brief Writes modem configuration to the network.
* @returns bool True, if configuration response was sent, otherwise false.
*/
virtual bool writeConfig();
/**
* @brief Writes a network stay-alive ping.
* @returns bool True, if stay-alive ping was sent, otherwise false.
*/
bool writePing();
};
} // namespace network
#endif // __NETWORK_H__

Powered by TurnKey Linux.