diff --git a/reflector/Clients.cpp b/reflector/Clients.cpp index 4e0bca4..74e7b66 100644 --- a/reflector/Clients.cpp +++ b/reflector/Clients.cpp @@ -63,8 +63,6 @@ void CClients::AddClient(std::shared_ptr client) std::cout << " on module " << client->GetReflectorModule(); } std::cout << std::endl; - // notify - g_Reflector.OnClientsChanged(); } void CClients::RemoveClient(std::shared_ptr client) @@ -87,8 +85,6 @@ void CClients::RemoveClient(std::shared_ptr client) } std::cout << std::endl; m_Clients.erase(it); - // notify - g_Reflector.OnClientsChanged(); break; } } diff --git a/reflector/Peers.cpp b/reflector/Peers.cpp index 9be9c04..4404158 100644 --- a/reflector/Peers.cpp +++ b/reflector/Peers.cpp @@ -64,9 +64,6 @@ void CPeers::AddPeer(std::shared_ptr peer) clients->AddClient(*cit); } g_Reflector.ReleaseClients(); - - // notify - g_Reflector.OnPeersChanged(); } void CPeers::RemovePeer(std::shared_ptr peer) @@ -92,8 +89,6 @@ void CPeers::RemovePeer(std::shared_ptr peer) // remove it std::cout << "Peer " << (*pit)->GetCallsign() << " at " << (*pit)->GetIp() << " removed" << std::endl; pit = m_Peers.erase(pit); - // notify - g_Reflector.OnPeersChanged(); } else { diff --git a/reflector/Reflector.cpp b/reflector/Reflector.cpp index 433ab15..4861ae8 100644 --- a/reflector/Reflector.cpp +++ b/reflector/Reflector.cpp @@ -21,12 +21,7 @@ #include "Global.h" -CReflector::CReflector() -{ -#ifndef NO_DHT - peers_put_count = clients_put_count = users_put_count = 0; -#endif -} +CReflector::CReflector() {} CReflector::~CReflector() { @@ -340,9 +335,6 @@ void CReflector::RouterThread(const char ThisModule) void CReflector::MaintenanceThread() { std::string xmlpath, jsonpath; -#ifndef NO_DHT - peers_changed = clients_changed = users_changed = true; -#endif if (g_Configure.Contains(g_Keys.files.xml)) xmlpath.assign(g_Configure.GetString(g_Keys.files.xml)); if (g_Configure.Contains(g_Keys.files.json)) @@ -387,24 +379,6 @@ void CReflector::MaintenanceThread() } } -#ifndef NO_DHT - // update the dht data, if needed - if (peers_changed) - { - PutDHTPeers(); - peers_changed = false; - } - if (clients_changed) - { - PutDHTClients(); - clients_changed = false; - } - if (users_changed) - { - PutDHTUsers(); - users_changed = false; - } -#endif // and wait a bit and do something useful at the same time for (int i=0; i< XML_UPDATE_PERIOD*10 && keep_running; i++) @@ -422,29 +396,6 @@ void CReflector::MaintenanceThread() } } -// notifications - -void CReflector::OnPeersChanged(void) -{ -#ifndef NO_DHT - peers_changed = true; -#endif -} - -void CReflector::OnClientsChanged(void) -{ -#ifndef NO_DHT - clients_changed = true; -#endif -} - -void CReflector::OnUsersChanged(void) -{ -#ifndef NO_DHT - users_changed = true; -#endif -} - //////////////////////////////////////////////////////////////////////////////////////// // modules & queues @@ -563,94 +514,6 @@ void CReflector::WriteXmlFile(std::ofstream &xmlFile) #ifndef NO_DHT // DHT put() and get() -void CReflector::PutDHTPeers() -{ - const std::string cs(g_Configure.GetString(g_Keys.names.callsign)); - // load it up - SUrfdPeers1 p; - time(&p.timestamp); - p.sequence = peers_put_count++; - auto peers = GetPeers(); - for (auto pit=peers->cbegin(); pit!=peers->cend(); pit++) - { - p.list.emplace_back((*pit)->GetCallsign().GetCS(), (*pit)->GetReflectorModules(), (*pit)->GetConnectTime()); - } - ReleasePeers(); - - auto nv = std::make_shared(p); - nv->user_type.assign(URFD_PEERS_1); - nv->id = toUType(EUrfdValueID::Peers); - - node.putSigned( - refhash, - nv, -#ifdef DEBUG - [](bool success){ std::cout << "PutDHTPeers() " << (success ? "successful" : "unsuccessful") << std::endl; }, -#else - [](bool success){ if (! success) std::cout << "PutDHTPeers() unsuccessful" << std::endl; }, -#endif - true // permanent! - ); -} - -void CReflector::PutDHTClients() -{ - const std::string cs(g_Configure.GetString(g_Keys.names.callsign)); - SUrfdClients1 c; - time(&c.timestamp); - c.sequence = clients_put_count++; - auto clients = GetClients(); - for (auto cit=clients->cbegin(); cit!=clients->cend(); cit++) - { - c.list.emplace_back((*cit)->GetCallsign().GetCS(), std::string((*cit)->GetIp().GetAddress()), (*cit)->GetReflectorModule(), (*cit)->GetConnectTime(), (*cit)->GetLastHeardTime()); - } - ReleaseClients(); - - auto nv = std::make_shared(c); - nv->user_type.assign(URFD_CLIENTS_1); - nv->id = toUType(EUrfdValueID::Clients); - - node.putSigned( - refhash, - nv, -#ifdef DEBUG - [](bool success){ std::cout << "PutDHTClients() " << (success ? "successful" : "unsuccessful") << std::endl; }, -#else - [](bool success){ if (! success) std::cout << "PutDHTClients() unsuccessful" << std::endl; }, -#endif - false // not permanent! - ); -} - -void CReflector::PutDHTUsers() -{ - const std::string cs(g_Configure.GetString(g_Keys.names.callsign)); - SUrfdUsers1 u; - time(&u.timestamp); - u.sequence = users_put_count++; - auto users = GetUsers(); - for (auto uit=users->cbegin(); uit!=users->cend(); uit++) - { - u.list.emplace_back((*uit).GetCallsign(), std::string((*uit).GetViaNode()), (*uit).GetOnModule(), (*uit).GetViaPeer(), (*uit).GetLastHeardTime()); - } - ReleaseUsers(); - - auto nv = std::make_shared(u); - nv->user_type.assign(URFD_USERS_1); - nv->id = toUType(EUrfdValueID::Users); - - node.putSigned( - refhash, - nv, -#ifdef DEBUG - [](bool success){ std::cout << "PutDHTUsers() " << (success ? "successful" : "unsuccessful") << std::endl; }, -#else - [](bool success){ if (! success) std::cout << "PutDHTUsers() unsuccessful" << std::endl; }, -#endif - false // not permanent - ); -} - void CReflector::PutDHTConfig() { const std::string cs(g_Configure.GetString(g_Keys.names.callsign)); diff --git a/reflector/Reflector.h b/reflector/Reflector.h index 9b71b1e..dd260f3 100644 --- a/reflector/Reflector.h +++ b/reflector/Reflector.h @@ -76,9 +76,6 @@ public: // notifications - void OnPeersChanged(void); - void OnClientsChanged(void); - void OnUsersChanged(void); #ifndef NO_DHT void GetDHTConfig(const std::string &cs); #endif @@ -87,9 +84,6 @@ protected: #ifndef NO_DHT // Publish DHT void PutDHTConfig(); - void PutDHTPeers(); - void PutDHTClients(); - void PutDHTUsers(); #endif // threads @@ -127,7 +121,5 @@ protected: // Distributed Hash Table dht::DhtRunner node; dht::InfoHash refhash; - unsigned int peers_put_count, clients_put_count, users_put_count; - std::atomic peers_changed, clients_changed, users_changed; #endif }; diff --git a/reflector/Users.cpp b/reflector/Users.cpp index ac7d774..31f4591 100644 --- a/reflector/Users.cpp +++ b/reflector/Users.cpp @@ -39,9 +39,6 @@ void CUsers::AddUser(const CUser &user) { m_Users.resize(m_Users.size()-1); } - - // notify - g_Reflector.OnUsersChanged(); } //////////////////////////////////////////////////////////////////////////////////////// diff --git a/reflector/dht-values.h b/reflector/dht-values.h index f0fed6f..b6ff056 100644 --- a/reflector/dht-values.h +++ b/reflector/dht-values.h @@ -1,28 +1,32 @@ -// Copyright © 2022 Thomas A. Early, N7TAE -// -// ---------------------------------------------------------------------------- -// This is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// with this software. If not, see . -// ---------------------------------------------------------------------------- +/* + * Copyright (c) 2022-2024 by Thomas A. Early N7TAE + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ #pragma once #include -#define USE_MREFD_VALUES +// comment out sections you don't need for your application +//#define USE_MREFD_VALUES #define USE_URFD_VALUES -/* HELPERS */ +// a typesafe way to extract the numeric value from a enum class +// note that this is a constexpr and so can even be used in an +// array declaration or as a tuple index template constexpr auto toUType(E enumerator) noexcept { return static_cast>(enumerator); @@ -30,112 +34,93 @@ template constexpr auto toUType(E enumerator) noexcept #ifdef USE_MREFD_VALUES -// user_type for mrefd values -#define MREFD_USERS_1 "mrefd-users-1" -#define MREFD_PEERS_1 "mrefd-peers-1" +// DHT::value::user_type for mrefd values +// These are the value release version strings in a +// preprocessor definition for your convience +// if your app needs a particular part, then it should handle all versions of that part #define MREFD_CONFIG_1 "mrefd-config-1" -#define MREFD_CLIENTS_1 "mrefd-clients-1" -// dht::Value ids of the different parts of the document +// dht::Value ids of the different parts of the mrefd document // can be assigned any unsigned value except 0 +// more parts can be added, but don't change the value of any existing part +// using toUType, you can set or query a user_type to determine the value part +// this can be done before unpacking the MSGPACK enum class EMrefdValueID : uint64_t { Config=1, Peers=2, Clients=3, Users=4 }; -using MrefdPeerTuple = std::tuple; -enum class EMrefdPeerFields { Callsign, Modules, ConnectTime }; -struct SMrefdPeers1 -{ - std::time_t timestamp; - unsigned int sequence; - std::list list; - - MSGPACK_DEFINE(timestamp, sequence, list) -}; - -using MrefdClientTuple = std::tuple; -enum class EMrefdClientFields { Callsign, Ip, Module, ConnectTime, LastHeardTime }; -struct SMrefdClients1 -{ - std::time_t timestamp; - unsigned int sequence; - std::list list; - - MSGPACK_DEFINE(timestamp, sequence, list) -}; - -using MrefdUserTuple = std::tuple; -enum class EMrefdUserFields { Source, Destination, Reflector, LastHeardTime }; -struct SMrefdUsers1 -{ - std::time_t timestamp; - unsigned int sequence; - std::list list; - - MSGPACK_DEFINE(timestamp, sequence, list) -}; +///////////////// MREFD PART VALUES /////////////// -struct SMrefdConfig1 +// the configuration part +struct SMrefdConfig1 // user_type is MREFD_CONFIG_1 { - std::time_t timestamp; - std::string callsign, ipv4addr, ipv6addr, modules, encryptedmods, url, email, sponsor, country, version; - uint16_t port; - + std::time_t timestamp; // when this value was set + std::string callsign; // the callsign of the mrefd reflector + std::string ipv4addr; // the external IPv4 address + std::string ipv6addr; // the external IPv6 address + std::string modules; // all the configured modules, [A-Z] + std::string encryptedmods; // modules that will pass encrypted streams + std::string url; // the URL of the dashboard + std::string email; // the email of the responsible owner + std::string sponsor; // the organization or individual sponsoring the reflector + std::string country; // the 2-letter country code + std::string version; // the version of the reflector software + uint16_t port; // the connection listening UDP port, usually 17000 + + // the order in which MSGPACK serializes the data MSGPACK_DEFINE(timestamp, callsign, ipv4addr, ipv6addr, modules, encryptedmods, url, email, sponsor, country, version, port) }; -#endif +#endif // USE_MREFD_VALUES #ifdef USE_URFD_VALUES -#define URFD_PEERS_1 "urfd-peers-1" -#define URFD_USERS_1 "urfd-users-1" +// DHT::value::user_type for urfd values +// These are the value release version strings in a +// preprocessor definition for your convience +// if your app needs a particular part, then it should handle all versions of that part #define URFD_CONFIG_1 "urfd-config-1" -#define URFD_CLIENTS_1 "urfd-clients-1" +#define URFD_CONFIG_2 "urfd-config-2" +// dht::Value::id of the different parts of the urfd document +// can be assigned any unsigned value except 0 +// more parts can be added, but don't change the value of any existing part +// using toUType, you can set or query a user_type to determine the value part +// this can be done before unpacking the MSGPACK enum class EUrfdValueID : uint64_t { Config=1, Peers=2, Clients=3, Users=4 }; -using UrfdPeerTuple = std::tuple; -enum class EUrfdPeerFields { Callsign, Modules, ConnectTime }; -struct SUrfdPeers1 -{ - std::time_t timestamp; - unsigned int sequence; - std::list list; - - MSGPACK_DEFINE(timestamp, sequence, list) -}; - -using UrfdClientTuple = std::tuple; -enum class EUrfdClientFields { Callsign, Ip, Module, ConnectTime, LastHeardTime }; -struct SUrfdClients1 +// the following enum classes can be used to reference a particular value in a fixed array +// 'SIZE' has to be last value for these scoped enums as this is used to declare these arrays +// +// all the configurable ports in urfd (G3 and BM are not configurable) +enum class EUrfdPorts : unsigned { dcs, dextra, dmrplus, dplus, m17, mmdvm, nxdn, p25, urf, ysf, SIZE }; +// autolink modules for these protocols +enum class EUrfdAlMod : unsigned { nxdn, p25, ysf, SIZE }; +// default TX/RX values for ysf +enum class EUrfdTxRx : unsigned { rx, tx, SIZE }; +// reflector ID values for these two modes +enum class EUrfdRefId : unsigned { nxdn, p25, SIZE }; + +struct SUrfdConfig1 // user_type is URFD_CONFIG_1 { std::time_t timestamp; - unsigned int sequence; - std::list list; + std::string callsign, ipv4addr, ipv6addr, modules, transcodedmods, url, email, sponsor, country, version; + // transcodedmods are those modules that support full transcoding + std::array port; + std::array almod; + std::array ysffreq; + std::array refid; + std::unordered_map description; + bool g3enabled; - MSGPACK_DEFINE(timestamp, sequence, list) + MSGPACK_DEFINE(timestamp, callsign, ipv4addr, ipv6addr, modules, transcodedmods, url, email, sponsor, country, version, almod, ysffreq, refid, g3enabled, port, description) }; -using UrfdUserTuple = std::tuple; -enum class EUrfdUserFields { Callsign, ViaNode, OnModule, ViaPeer, LastHeardTime }; -struct SUrfdUsers1 -{ - std::time_t timestamp; - unsigned int sequence; - std::list list; - - MSGPACK_DEFINE(timestamp, sequence, list) -}; +enum class EUrfdPorts2 : unsigned { dcs, dextra, dmrplus, dplus, dsd, m17, mmdvm, nxdn, p25, urf, ysf, SIZE }; -// 'SIZE' has to be last value for these scoped enums -enum class EUrfdPorts : unsigned { dcs, dextra, dmrplus, dplus, m17, mmdvm, nxdn, p25, urf, ysf, SIZE }; -enum class EUrfdAlMod : unsigned { nxdn, p25, ysf, SIZE }; -enum class EUrfdTxRx : unsigned { rx, tx, SIZE }; -enum class EUrfdRefId : unsigned { nxdn, p25, SIZE }; -struct SUrfdConfig1 +struct SUrfdConfig2 { std::time_t timestamp; std::string callsign, ipv4addr, ipv6addr, modules, transcodedmods, url, email, sponsor, country, version; - std::array port; + std::array port; std::array almod; std::array ysffreq; std::array refid; @@ -145,4 +130,4 @@ struct SUrfdConfig1 MSGPACK_DEFINE(timestamp, callsign, ipv4addr, ipv6addr, modules, transcodedmods, url, email, sponsor, country, version, almod, ysffreq, refid, g3enabled, port, description) }; -#endif +#endif // USE_URFD_VALUES