// 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) 2016 Jonathan Naylor, G4KLX * Copyright (C) 2017-2022,2024,2025-2026 Bryan Biedenkapp, N2PLL * Copyright (c) 2024 Patrick McDonnell, W3AXL * */ /** * @defgroup lookups_rid Radio ID Lookups * @brief Implementation for radio ID lookup tables. * @ingroup lookups * * @file RadioIdLookup.h * @ingroup lookups_rid * @file RadioIdLookup.cpp * @ingroup lookups_rid */ #if !defined(__RADIO_ID_LOOKUP_H__) #define __RADIO_ID_LOOKUP_H__ #include "common/Defines.h" #include "common/lookups/LookupTable.h" #include #include #include namespace lookups { // --------------------------------------------------------------------------- // Class Declaration // --------------------------------------------------------------------------- /** * @brief Represents an individual entry in the radio ID table. * @ingroup lookups_rid */ class HOST_SW_API RadioId { public: /** * @brief Initializes a new instance of the RadioId class. */ RadioId() : m_radioEnabled(false), m_radioDefault(false), m_radioAlias(""), m_radioIPAddress(""), m_canRequestKeys(false), m_canRekey(false), m_allowedKIds() { /* stub */ } /** * @brief Initializes a new instance of the RadioId class. * @param radioEnabled Flag indicating radio is enabled. * @param radioDefault Flag indicating this is a "default" (i.e. undefined) radio. */ RadioId(bool radioEnabled, bool radioDefault) : m_radioEnabled(radioEnabled), m_radioDefault(radioDefault), m_radioAlias(""), m_radioIPAddress(""), m_canRequestKeys(false), m_canRekey(false), m_allowedKIds() { /* stub */ } /** * @brief Initializes a new instance of the RadioId class. * @param radioEnabled Flag indicating radio is enabled. * @param radioDefault Flag indicating this is a "default" (i.e. undefined) radio. * @param radioAlias Textual alias for the radio. * @param ipAddress Textual IP Address for the radio. */ RadioId(bool radioEnabled, bool radioDefault, const std::string& radioAlias, const std::string& ipAddress = "", bool canRequestKeys = false, bool canRekey = false, const std::vector& allowedKIds = std::vector()) : m_radioEnabled(radioEnabled), m_radioDefault(radioDefault), m_radioAlias(radioAlias), m_radioIPAddress(ipAddress), m_canRequestKeys(canRequestKeys), m_canRekey(canRekey), m_allowedKIds(allowedKIds) { /* stub */ } /** * @brief Equals operator. Copies this RadioId to another RadioId. * @param data Instance of RadioId to copy. */ RadioId& operator=(const RadioId& data) { if (this != &data) { m_radioEnabled = data.m_radioEnabled; m_radioDefault = data.m_radioDefault; m_radioAlias = data.m_radioAlias; m_radioIPAddress = data.m_radioIPAddress; m_canRequestKeys = data.m_canRequestKeys; m_canRekey = data.m_canRekey; m_allowedKIds = data.m_allowedKIds; } return *this; } /** * @brief Sets flag values. * @param radioEnabled Flag indicating radio is enabled. * @param radioDefault Flag indicating this is a "default" (i.e. undefined) radio. * @param radioAlias Textual alias for the radio. * @param ipAddress Textual IP Address for the radio. */ void set(bool radioEnabled, bool radioDefault, const std::string& radioAlias, const std::string& ipAddress = "", bool canRequestKeys = false, bool canRekey = false, const std::vector& allowedKIds = std::vector()) { m_radioEnabled = radioEnabled; m_radioDefault = radioDefault; m_radioAlias = radioAlias; m_radioIPAddress = ipAddress; m_canRequestKeys = canRequestKeys; m_canRekey = canRekey; m_allowedKIds = allowedKIds; } public: /** * @brief Flag indicating if the radio is enabled. */ DECLARE_RO_PROPERTY_PLAIN(bool, radioEnabled); /** * @brief Flag indicating if the radio is default. */ DECLARE_RO_PROPERTY_PLAIN(bool, radioDefault); /** * @brief Alias for the radio. */ DECLARE_RO_PROPERTY_PLAIN(std::string, radioAlias); /** * @brief IP Address for the radio. */ DECLARE_RO_PROPERTY_PLAIN(std::string, radioIPAddress); /** * @brief Flag indicating if the radio can request keys from FNE. */ DECLARE_RO_PROPERTY_PLAIN(bool, canRequestKeys); /** * @brief Flag indicating if the radio can receive OTAR rekey command payloads. */ DECLARE_RO_PROPERTY_PLAIN(bool, canRekey); /** * @brief Allowed encryption key IDs for this radio. */ DECLARE_RO_PROPERTY_PLAIN(std::vector, allowedKIds); }; // --------------------------------------------------------------------------- // Class Declaration // --------------------------------------------------------------------------- /** * @brief Implements a threading lookup table class that contains a radio ID * lookup table. * @ingroup lookups_rid */ class HOST_SW_API RadioIdLookup : public LookupTable { public: /** * @brief Initializes a new instance of the RadioIdLookup class. * @param filename Full-path to the radio ID table file. * @param reloadTime Interval of time to reload the radio ID table. * @param ridAcl Flag indicating whether radio ID access control is enabled. * @param verbose Flag indicating if logging should be enabled for this lookup table. */ RadioIdLookup(const std::string& filename, uint32_t reloadTime, bool ridAcl, bool verbose = false); /** * @brief Clears all entries from the lookup table. */ void clear() override; /** * @brief Toggles the specified radio ID enabled or disabled. * @param id Unique ID to toggle. * @param enabled Flag indicating if radio ID is enabled or not. */ void toggleEntry(uint32_t id, bool enabled); /** * @brief Adds a new entry to the lookup table by the specified unique ID, with an alias. * @param id Unique ID to add. * @param enabled Flag indicating if radio ID is enabled or not. * @param alias Alias for the radio ID * @param ipAddress IP Address for Radio */ void addEntry(uint32_t id, bool enabled, const std::string& alias, const std::string& ipAddress = "", bool canRequestKeys = false, bool canRekey = false, const std::vector& allowedKIds = std::vector()); /** * @brief Erases an existing entry from the lookup table by the specified unique ID. * @param id Unique ID to erase. */ void eraseEntry(uint32_t id); /** * @brief Helper to return the lookup table. * @returns std::unordered_map Table. */ std::unordered_map table() override { std::lock_guard lock(s_mutex); return m_table; } /** * @brief Finds a table entry in this lookup table. * @param id Unique identifier for table entry. * @returns RadioId Table entry. */ RadioId find(uint32_t id) override; /** * @brief Saves loaded radio ID lookups. * @param quiet Disable logging during save operation. */ void commit(bool quiet = false); /** * @brief Flag indicating whether radio ID access control is enabled or not. */ bool getACL(); protected: bool m_acl; bool m_verbose; /** * @brief Loads the table from the passed lookup table file. * @return True, if lookup table was loaded, otherwise false. */ bool load() override; /** * @brief Saves the table to the passed lookup table file. * @param quiet Disable logging during save operation. * @return True, if lookup table was saved, otherwise false. */ bool save(bool quiet = false) override; private: static std::mutex s_mutex; //!< Mutex used for change locking. static bool s_locked; //!< Flag used for read locking (prevents find lookups), should be used when atomic operations (add/erase/etc) are being used. /** * @brief Parses a string of KIDs from the lookup file into a vector of uint16_t KIDs. * @param input String representation of KID list from the lookup file. * @returns Vector of KIDs parsed from the input string. */ std::vector parseKIdList(const std::string& input); /** * @brief Serializes a list of KIDs into a string for storage in the lookup file. * @param kids List of KIDs to serialize. * @returns String representation of the KID list. */ std::string serializeKIdList(const std::vector& kids); }; } // namespace lookups #endif // __RADIO_ID_LOOKUP_H__