diff --git a/src/async/ChangeLog b/src/async/ChangeLog index d7c79acd..e65c15fc 100644 --- a/src/async/ChangeLog +++ b/src/async/ChangeLog @@ -1,4 +1,4 @@ - 1.7.0 -- ?? ??? 2022 + 1.7.0 -- ?? ??? ???? ---------------------- * ASYNC_AUDIO_ALSA_ZEROFILL is now enabled by default. diff --git a/src/svxlink/ChangeLog b/src/svxlink/ChangeLog index d3e643c5..848aef7a 100644 --- a/src/svxlink/ChangeLog +++ b/src/svxlink/ChangeLog @@ -218,6 +218,10 @@ See man svxlink.conf and the LOGIC_CORE_PATH configuration variable for info on how SvxLink find the plugins. +* Bugfix in SvxReflector: After 65536 client connections the warning "Incoming + UDP datagram from XX.XX.XX.XX:YYYYY has invalid client id ZZZZZ" was logged + for all new client connections. + 1.7.0 -- 01 Sep 2019 diff --git a/src/svxlink/devcal/devcal.cpp b/src/svxlink/devcal/devcal.cpp index 2115593a..652c690a 100644 --- a/src/svxlink/devcal/devcal.cpp +++ b/src/svxlink/devcal/devcal.cpp @@ -6,7 +6,7 @@ \verbatim SvxLink - A Multi Purpose Voice Services System for Ham Radio Use -Copyright (C) 2003-2022 Tobias Blomberg / SM0SVX +Copyright (C) 2003-2023 Tobias Blomberg / SM0SVX 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 @@ -485,7 +485,7 @@ static const unsigned audio_ch = 0; int main(int argc, const char *argv[]) { cout << PROGRAM_NAME " v" DEVCAL_VERSION - " Copyright (C) 2003-2022 Tobias Blomberg / SM0SVX\n\n"; + " Copyright (C) 2003-2023 Tobias Blomberg / SM0SVX\n\n"; cout << PROGRAM_NAME " comes with ABSOLUTELY NO WARRANTY. " "This is free software, and you\n"; cout << "are welcome to redistribute it in accordance with the " diff --git a/src/svxlink/reflector/Reflector.cpp b/src/svxlink/reflector/Reflector.cpp index c11477f5..76b3ae09 100644 --- a/src/svxlink/reflector/Reflector.cpp +++ b/src/svxlink/reflector/Reflector.cpp @@ -6,7 +6,7 @@ \verbatim SvxReflector - An audio reflector for connecting SvxLink Servers -Copyright (C) 2003-2021 Tobias Blomberg / SM0SVX +Copyright (C) 2003-2023 Tobias Blomberg / SM0SVX 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 @@ -140,14 +140,8 @@ Reflector::~Reflector(void) m_udp_sock = 0; delete m_srv; m_srv = 0; - - for (ReflectorClientMap::iterator it = m_client_map.begin(); - it != m_client_map.end(); ++it) - { - delete (*it).second; - } - m_client_map.clear(); - + m_client_con_map.clear(); + ReflectorClient::cleanup(); delete TGHandler::instance(); } /* Reflector::~Reflector */ @@ -239,10 +233,9 @@ bool Reflector::initialize(Async::Config &cfg) void Reflector::nodeList(std::vector& nodes) const { nodes.clear(); - for (ReflectorClientMap::const_iterator it = m_client_map.begin(); - it != m_client_map.end(); ++it) + for (const auto& item : m_client_con_map) { - const std::string& callsign = (*it).second->callsign(); + const std::string& callsign = item.second->callsign(); if (!callsign.empty()) { nodes.push_back(callsign); @@ -254,14 +247,13 @@ void Reflector::nodeList(std::vector& nodes) const void Reflector::broadcastMsg(const ReflectorMsg& msg, const ReflectorClient::Filter& filter) { - ReflectorClientMap::const_iterator it = m_client_map.begin(); - for (; it != m_client_map.end(); ++it) + for (const auto& item : m_client_con_map) { - ReflectorClient *client = (*it).second; + ReflectorClient *client = item.second; if (filter(client) && (client->conState() == ReflectorClient::STATE_CONNECTED)) { - (*it).second->sendMsg(msg); + client->sendMsg(msg); } } } /* Reflector::broadcastMsg */ @@ -278,10 +270,9 @@ bool Reflector::sendUdpDatagram(ReflectorClient *client, const void *buf, void Reflector::broadcastUdpMsg(const ReflectorUdpMsg& msg, const ReflectorClient::Filter& filter) { - for (ReflectorClientMap::iterator it = m_client_map.begin(); - it != m_client_map.end(); ++it) + for (const auto& item : m_client_con_map) { - ReflectorClient *client = (*it).second; + ReflectorClient *client = item.second; if (filter(client) && (client->conState() == ReflectorClient::STATE_CONNECTED)) { @@ -335,9 +326,7 @@ void Reflector::clientConnected(Async::FramedTcpConnection *con) { cout << "Client " << con->remoteHost() << ":" << con->remotePort() << " connected" << endl; - ReflectorClient *rc = new ReflectorClient(this, con, m_cfg); - m_client_map[rc->clientId()] = rc; - m_client_con_map[con] = rc; + m_client_con_map[con] = new ReflectorClient(this, con, m_cfg); } /* Reflector::clientConnected */ @@ -361,7 +350,6 @@ void Reflector::clientDisconnected(Async::FramedTcpConnection *con, cout << "disconnected: " << TcpConnection::disconnectReasonStr(reason) << endl; - m_client_map.erase(client->clientId()); m_client_con_map.erase(it); if (!client->callsign().empty()) @@ -387,14 +375,13 @@ void Reflector::udpDatagramReceived(const IpAddress& addr, uint16_t port, return; } - ReflectorClientMap::iterator it = m_client_map.find(header.clientId()); - if (it == m_client_map.end()) + ReflectorClient *client = ReflectorClient::lookup(header.clientId()); + if (client == nullptr) { cerr << "*** WARNING: Incoming UDP datagram from " << addr << ":" << port << " has invalid client id " << header.clientId() << endl; return; } - ReflectorClient *client = (*it).second; if (addr != client->remoteHost()) { cerr << "*** WARNING[" << client->callsign() @@ -642,10 +629,9 @@ void Reflector::httpRequestReceived(Async::HttpServerConnection *con, Json::Value status; status["nodes"] = Json::Value(Json::objectValue); - ReflectorClientMap::const_iterator client_it; - for (client_it = m_client_map.begin(); client_it != m_client_map.end(); ++client_it) + for (const auto& item : m_client_con_map) { - ReflectorClient* client = client_it->second; + ReflectorClient* client = item.second; Json::Value node(client->nodeInfo()); //node["addr"] = client->remoteHost().toString(); node["protoVer"]["majorVer"] = client->protoVer().majorVer(); diff --git a/src/svxlink/reflector/Reflector.h b/src/svxlink/reflector/Reflector.h index e95f130d..86d90a4e 100644 --- a/src/svxlink/reflector/Reflector.h +++ b/src/svxlink/reflector/Reflector.h @@ -6,7 +6,7 @@ \verbatim SvxReflector - An audio reflector for connecting SvxLink Servers -Copyright (C) 2003-2017 Tobias Blomberg / SM0SVX +Copyright (C) 2003-2023 Tobias Blomberg / SM0SVX 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 @@ -182,14 +182,12 @@ class Reflector : public sigc::trackable void requestQsy(ReflectorClient *client, uint32_t tg); private: - typedef std::map ReflectorClientMap; typedef std::map ReflectorClientConMap; typedef Async::TcpServer FramedTcpServer; FramedTcpServer* m_srv; Async::UdpSocket* m_udp_sock; - ReflectorClientMap m_client_map; ReflectorClientConMap m_client_con_map; Async::Config* m_cfg; uint32_t m_tg_for_v1_clients; diff --git a/src/svxlink/reflector/ReflectorClient.cpp b/src/svxlink/reflector/ReflectorClient.cpp index 80143212..70f86760 100644 --- a/src/svxlink/reflector/ReflectorClient.cpp +++ b/src/svxlink/reflector/ReflectorClient.cpp @@ -6,7 +6,7 @@ \verbatim SvxReflector - An audio reflector for connecting SvxLink Servers -Copyright (C) 2003-2021 Tobias Blomberg / SM0SVX +Copyright (C) 2003-2023 Tobias Blomberg / SM0SVX 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 @@ -111,7 +111,9 @@ using namespace Async; * ****************************************************************************/ -uint32_t ReflectorClient::next_client_id = 0; +ReflectorClient::ClientMap ReflectorClient::client_map; +std::mt19937 ReflectorClient::id_gen(std::random_device{}()); +ReflectorClient::ClientIdRandomDist ReflectorClient::id_dist(0, CLIENT_ID_MAX); /**************************************************************************** @@ -120,6 +122,28 @@ uint32_t ReflectorClient::next_client_id = 0; * ****************************************************************************/ +ReflectorClient* ReflectorClient::lookup(ClientId id) +{ + auto it = client_map.find(id); + if (it == client_map.end()) + { + return nullptr; + } + return it->second; +} /* ReflectorClient::lookup */ + + +void ReflectorClient::cleanup(void) +{ + auto client_map_copy = client_map; + for (const auto& item : client_map_copy) + { + delete item.second; + } + assert(client_map.size() == 0); +} /* ReflectorClient::cleanup */ + + bool ReflectorClient::TgFilter::operator()(ReflectorClient* client) const { //cout << "m_tg=" << m_tg << " client_tg=" @@ -132,7 +156,7 @@ ReflectorClient::ReflectorClient(Reflector *ref, Async::FramedTcpConnection *con Async::Config *cfg) : m_con(con), m_con_state(STATE_EXPECT_PROTO_VER), m_disc_timer(10000, Timer::TYPE_ONESHOT, false), - m_client_id(next_client_id++), m_remote_udp_port(0), m_cfg(cfg), + m_client_id(newClient(this)), m_remote_udp_port(0), m_cfg(cfg), m_next_udp_tx_seq(0), m_next_udp_rx_seq(0), m_heartbeat_timer(1000, Timer::TYPE_PERIODIC), m_heartbeat_tx_cnt(HEARTBEAT_TX_CNT_RESET), @@ -183,6 +207,9 @@ ReflectorClient::ReflectorClient(Reflector *ref, Async::FramedTcpConnection *con ReflectorClient::~ReflectorClient(void) { + auto client_it = client_map.find(m_client_id); + assert(client_it != client_map.end()); + client_map.erase(client_it); TGHandler::instance()->removeClient(this); } /* ReflectorClient::~ReflectorClient */ @@ -260,6 +287,19 @@ void ReflectorClient::setBlock(unsigned blocktime) * ****************************************************************************/ +ReflectorClient::ClientId ReflectorClient::newClient(ReflectorClient* client) +{ + assert(!(client_map.size() > CLIENT_ID_MAX)); + ClientId id = id_dist(id_gen); + while (client_map.count(id) > 0) + { + id = (id < CLIENT_ID_MAX) ? id+1 : 0; + } + client_map[id] = client; + return id; +} /* ReflectorClient::newClient */ + + void ReflectorClient::onFrameReceived(FramedTcpConnection *con, std::vector& data) { diff --git a/src/svxlink/reflector/ReflectorClient.h b/src/svxlink/reflector/ReflectorClient.h index 339c04a1..443c45c1 100644 --- a/src/svxlink/reflector/ReflectorClient.h +++ b/src/svxlink/reflector/ReflectorClient.h @@ -6,7 +6,7 @@ \verbatim SvxReflector - An audio reflector for connecting SvxLink Servers -Copyright (C) 2003-2017 Tobias Blomberg / SM0SVX +Copyright (C) 2003-2023 Tobias Blomberg / SM0SVX 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 @@ -36,6 +36,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #include #include +#include /**************************************************************************** @@ -110,6 +111,8 @@ the client connection. class ReflectorClient { public: + using ClientId = ReflectorUdpMsg::ClientId; + typedef enum { STATE_DISCONNECTED, STATE_EXPECT_PROTO_VER, STATE_EXPECT_AUTH_RESPONSE, @@ -235,6 +238,18 @@ class ReflectorClient return OrFilter(f1, f2); } + /** + * @brief Get the client object associated with the given id + * @param id The id of the client object to find + * @return Return the client object associated with the given id + */ + static ReflectorClient* lookup(ClientId id); + + /** + * @brief Remove all client objects + */ + static void cleanup(void); + /** * @brief Constructor * @param ref The associated Reflector object @@ -257,7 +272,7 @@ class ReflectorClient * It is for example used to associate incoming audio with the correct * client. */ - uint32_t clientId(void) const { return m_client_id; } + ClientId clientId(void) const { return m_client_id; } /** * @brief Return the remote IP address @@ -412,21 +427,29 @@ class ReflectorClient const Json::Value& nodeInfo(void) const { return m_node_info; } private: + using ClientIdRandomDist = std::uniform_int_distribution; + using ClientMap = std::map; + static const uint16_t MIN_MAJOR_VER = 0; static const uint16_t MIN_MINOR_VER = 6; - static uint32_t next_client_id; static const unsigned HEARTBEAT_TX_CNT_RESET = 10; static const unsigned HEARTBEAT_RX_CNT_RESET = 15; static const unsigned UDP_HEARTBEAT_TX_CNT_RESET = 15; static const unsigned UDP_HEARTBEAT_RX_CNT_RESET = 120; + static const ClientId CLIENT_ID_MAX = std::numeric_limits::max(); + + static ClientMap client_map; + static std::mt19937 id_gen; + static ClientIdRandomDist id_dist; + Async::FramedTcpConnection* m_con; unsigned char m_auth_challenge[MsgAuthChallenge::CHALLENGE_LEN]; ConState m_con_state; Async::Timer m_disc_timer; std::string m_callsign; - uint32_t m_client_id; + ClientId m_client_id; uint16_t m_remote_udp_port; Async::Config* m_cfg; uint16_t m_next_udp_tx_seq; @@ -447,6 +470,8 @@ class ReflectorClient TxMap m_tx_map; Json::Value m_node_info; + static ClientId newClient(ReflectorClient* client); + ReflectorClient(const ReflectorClient&); ReflectorClient& operator=(const ReflectorClient&); void onFrameReceived(Async::FramedTcpConnection *con, diff --git a/src/svxlink/reflector/ReflectorMsg.h b/src/svxlink/reflector/ReflectorMsg.h index d544e2ae..2f1442c3 100644 --- a/src/svxlink/reflector/ReflectorMsg.h +++ b/src/svxlink/reflector/ReflectorMsg.h @@ -162,12 +162,14 @@ the argument type for functions that take a UDP message as argument. class ReflectorUdpMsg : public Async::Msg { public: + using ClientId = uint16_t; + /** * @brief Constuctor * @param type The message type * @param client_id The client ID */ - ReflectorUdpMsg(uint16_t type=0, uint16_t client_id=0, uint16_t seq=0) + ReflectorUdpMsg(uint16_t type=0, ClientId client_id=0, uint16_t seq=0) : m_type(type), m_client_id(client_id), m_seq(seq) {} /** @@ -185,7 +187,7 @@ class ReflectorUdpMsg : public Async::Msg * @brief Get the clientId * @return Returns the client ID */ - uint16_t clientId(void) const { return m_client_id; } + ClientId clientId(void) const { return m_client_id; } /** * @brief Get the sequence number @@ -196,9 +198,9 @@ class ReflectorUdpMsg : public Async::Msg ASYNC_MSG_MEMBERS(m_type, m_client_id, m_seq) private: - uint16_t m_type; - uint16_t m_client_id; - uint16_t m_seq; + uint16_t m_type; + ClientId m_client_id; + uint16_t m_seq; }; @@ -475,17 +477,20 @@ connection properties. class MsgServerInfo : public ReflectorMsgBase<100> { public: - MsgServerInfo(uint32_t client_id=0, + using ClientId = ReflectorUdpMsg::ClientId; + + MsgServerInfo(ClientId client_id=0, std::vector codecs=std::vector()) : m_client_id(client_id), m_codecs(codecs) {} - uint32_t clientId(void) const { return m_client_id; } + ClientId clientId(void) const { return m_client_id; } std::vector& nodes(void) { return m_nodes; } std::vector& codecs(void) { return m_codecs; } - ASYNC_MSG_MEMBERS(m_client_id, m_nodes, m_codecs) + ASYNC_MSG_MEMBERS(m_reserved, m_client_id, m_nodes, m_codecs) private: - uint32_t m_client_id; + uint16_t m_reserved = 0; + ClientId m_client_id; std::vector m_nodes; std::vector m_codecs; }; /* MsgServerInfo */ diff --git a/src/svxlink/reflector/svxreflector.cpp b/src/svxlink/reflector/svxreflector.cpp index 3819417a..7ca9b1ca 100644 --- a/src/svxlink/reflector/svxreflector.cpp +++ b/src/svxlink/reflector/svxreflector.cpp @@ -9,7 +9,7 @@ nodes together. \verbatim SvxReflector - An audio reflector for connecting SvxLink Servers -Copyright (C) 2003-2022 Tobias Blomberg / SM0SVX +Copyright (C) 2003-2023 Tobias Blomberg / SM0SVX 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 @@ -412,7 +412,7 @@ int main(int argc, const char *argv[]) cfg.getValue("GLOBAL", "TIMESTAMP_FORMAT", tstamp_format); cout << PROGRAM_NAME " v" SVXREFLECTOR_VERSION - " Copyright (C) 2003-2022 Tobias Blomberg / SM0SVX\n\n"; + " Copyright (C) 2003-2023 Tobias Blomberg / SM0SVX\n\n"; cout << PROGRAM_NAME " comes with ABSOLUTELY NO WARRANTY. " "This is free software, and you are\n"; cout << "welcome to redistribute it in accordance with the " diff --git a/src/svxlink/remotetrx/remotetrx.cpp b/src/svxlink/remotetrx/remotetrx.cpp index 562a5d5b..33e16004 100644 --- a/src/svxlink/remotetrx/remotetrx.cpp +++ b/src/svxlink/remotetrx/remotetrx.cpp @@ -10,7 +10,7 @@ server core (e.g. via a TCP/IP network). \verbatim RemoteTrx - A remote receiver for the SvxLink server -Copyright (C) 2003-2022 Tobias Blomberg / SM0SVX +Copyright (C) 2003-2023 Tobias Blomberg / SM0SVX 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 @@ -474,7 +474,7 @@ int main(int argc, char **argv) cfg.getValue("GLOBAL", "TIMESTAMP_FORMAT", tstamp_format); cout << PROGRAM_NAME " v" REMOTE_TRX_VERSION - " Copyright (C) 2003-2022 Tobias Blomberg / SM0SVX\n\n"; + " Copyright (C) 2003-2023 Tobias Blomberg / SM0SVX\n\n"; cout << PROGRAM_NAME " comes with ABSOLUTELY NO WARRANTY. " "This is free software, and you are\n"; cout << "welcome to redistribute it in accordance with the " diff --git a/src/svxlink/siglevdetcal/siglevdetcal.cpp b/src/svxlink/siglevdetcal/siglevdetcal.cpp index cb4283ba..de17834d 100644 --- a/src/svxlink/siglevdetcal/siglevdetcal.cpp +++ b/src/svxlink/siglevdetcal/siglevdetcal.cpp @@ -1,7 +1,46 @@ +/** +@file siglevdetcal.cpp +@brief Signal level detector calibration utility +@author Tobias Blomberg / SM0SVX +@date 2008-03-30 + +\verbatim +SvxLink - A Multi Purpose Voice Services System for Ham Radio Use +Copyright (C) 2003-2023 Tobias Blomberg / SM0SVX + +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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +\endverbatim +*/ + +/**************************************************************************** + * + * System Includes + * + ****************************************************************************/ + #include #include #include + +/**************************************************************************** + * + * Project Includes + * + ****************************************************************************/ + #include #include #include @@ -10,12 +49,33 @@ #include + +/**************************************************************************** + * + * Local Includes + * + ****************************************************************************/ + #include "version/SIGLEV_DET_CAL.h" + +/**************************************************************************** + * + * Namespaces to use + * + ****************************************************************************/ + using namespace std; using namespace sigc; using namespace Async; + +/**************************************************************************** + * + * Defines & typedefs + * + ****************************************************************************/ + #define PROGRAM_NAME "SigLevDetCal" struct CtcssMeasurement @@ -24,6 +84,13 @@ struct CtcssMeasurement size_t count = 0; }; + +/**************************************************************************** + * + * Local Global Variables + * + ****************************************************************************/ + static const int INTERVAL = 100; static const int ITERATIONS = 150; @@ -38,6 +105,12 @@ static std::map ctcss_open_snr; static std::map ctcss_close_snr; +/**************************************************************************** + * + * Local Functions + * + ****************************************************************************/ + #if 0 void squelchOpen(bool is_open) { @@ -230,12 +303,18 @@ void ctcss_snr_updated(float snr, float fq) } +/**************************************************************************** + * + * MAIN + * + ****************************************************************************/ + int main(int argc, char **argv) { CppApplication app; cout << PROGRAM_NAME " v" SIGLEV_DET_CAL_VERSION - " Copyright (C) 2003-2022 Tobias Blomberg / SM0SVX\n\n"; + " Copyright (C) 2003-2023 Tobias Blomberg / SM0SVX\n\n"; cout << PROGRAM_NAME " comes with ABSOLUTELY NO WARRANTY. " "This is free software, and you\n"; cout << "are welcome to redistribute it in accordance with the " diff --git a/src/svxlink/svxlink/svxlink.cpp b/src/svxlink/svxlink/svxlink.cpp index b26d529a..bffa8325 100644 --- a/src/svxlink/svxlink/svxlink.cpp +++ b/src/svxlink/svxlink/svxlink.cpp @@ -6,7 +6,7 @@ \verbatim SvxLink - A Multi Purpose Voice Services System for Ham Radio Use -Copyright (C) 2003-2022 Tobias Blomberg / SM0SVX +Copyright (C) 2003-2023 Tobias Blomberg / SM0SVX 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 @@ -432,7 +432,7 @@ int main(int argc, char **argv) cfg.getValue("GLOBAL", "TIMESTAMP_FORMAT", tstamp_format); cout << PROGRAM_NAME " v" SVXLINK_VERSION - " Copyright (C) 2003-2022 Tobias Blomberg / SM0SVX\n\n"; + " Copyright (C) 2003-2023 Tobias Blomberg / SM0SVX\n\n"; cout << PROGRAM_NAME " comes with ABSOLUTELY NO WARRANTY. " "This is free software, and you are\n"; cout << "welcome to redistribute it in accordance with the terms " diff --git a/src/template.cpp b/src/template.cpp index ee8decb7..cabd5087 100644 --- a/src/template.cpp +++ b/src/template.cpp @@ -2,13 +2,13 @@ @file MyNamespaceTemplate.cpp @brief A_brief_description_for_this_file @author Tobias Blomberg / SM0SVX -@date 2022- +@date 2023- A_detailed_description_for_this_file \verbatim -Copyright (C) 2003-2022 Tobias Blomberg / SM0SVX +Copyright (C) 2003-2023 Tobias Blomberg / SM0SVX 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 diff --git a/src/template.h b/src/template.h index 027e2837..82970b6a 100644 --- a/src/template.h +++ b/src/template.h @@ -2,13 +2,13 @@ @file MyNamespaceTemplate.h @brief A_brief_description_for_this_file @author Tobias Blomberg / SM0SVX -@date 2022- +@date 2023- A_detailed_description_for_this_file \verbatim -Copyright (C) 2003-2022 Tobias Blomberg / SM0SVX +Copyright (C) 2003-2023 Tobias Blomberg / SM0SVX 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 @@ -109,7 +109,7 @@ namespace MyNamespace /** @brief A_brief_class_description @author Tobias Blomberg / SM0SVX -@date 2022- +@date 2023- A_detailed_class_description diff --git a/src/versions b/src/versions index ce13d7fc..abf609a7 100644 --- a/src/versions +++ b/src/versions @@ -11,7 +11,7 @@ LIBECHOLIB=1.3.3.99.2 LIBASYNC=1.6.99.24 # SvxLink versions -SVXLINK=1.7.99.73 +SVXLINK=1.7.99.75 MODULE_HELP=1.0.0 MODULE_PARROT=1.1.1 MODULE_ECHO_LINK=1.5.99.3 @@ -25,16 +25,16 @@ MODULE_FRN=1.1.0 MODULE_TRX=1.0.0 # Version for the RemoteTrx application -REMOTE_TRX=1.3.99.11 +REMOTE_TRX=1.3.99.12 # Version for the signal level calibration utility -SIGLEV_DET_CAL=1.0.7.99.7 +SIGLEV_DET_CAL=1.0.7.99.8 # Version for the deviation calibration utility -DEVCAL=1.0.2.99.8 +DEVCAL=1.0.2.99.9 # Version for svxserver SVXSERVER=0.0.6 # Version for SvxReflector -SVXREFLECTOR=1.99.15 +SVXREFLECTOR=1.99.16