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.
278 lines
9.9 KiB
278 lines
9.9 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) 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 <string>
|
|
#include <unordered_map>
|
|
#include <vector>
|
|
|
|
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<uint16_t>& allowedKIds = std::vector<uint16_t>()) :
|
|
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<uint16_t>& allowedKIds = std::vector<uint16_t>())
|
|
{
|
|
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<uint16_t>, 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<RadioId> {
|
|
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<uint16_t>& allowedKIds = std::vector<uint16_t>());
|
|
/**
|
|
* @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<uint32_t, RadioId> Table.
|
|
*/
|
|
std::unordered_map<uint32_t, RadioId> table() override
|
|
{
|
|
std::lock_guard<std::mutex> 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<uint16_t> 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<uint16_t>& kids);
|
|
};
|
|
} // namespace lookups
|
|
|
|
#endif // __RADIO_ID_LOOKUP_H__
|