From d86b36c2f0699dceb46f3a9eb77874dbde630a2b Mon Sep 17 00:00:00 2001 From: Geoffrey Merck Date: Wed, 28 Dec 2022 19:27:04 +0100 Subject: [PATCH] #29 refactor APRS Handling, prepare for more testable code --- Common/APRSFixedIdFrameProvider.cpp | 10 ++++----- Common/APRSFixedIdFrameProvider.h | 4 ++-- Common/APRSGPSDIdFrameProvider.cpp | 14 ++++++------ Common/APRSGPSDIdFrameProvider.h | 4 ++-- Common/APRSHandler.cpp | 23 +++++-------------- Common/APRSHandler.h | 9 +++----- Common/APRSHandlerThread.h | 4 ++-- Common/APRSIdFrameProvider.cpp | 14 +++++++++--- Common/APRSIdFrameProvider.h | 8 ++++--- Common/IAPRSHandlerThread.h | 35 +++++++++++++++++++++++++++++ DStarGateway/DStarGatewayApp.cpp | 12 +++++----- DStarGateway/DStarGatewayThread.cpp | 2 +- 12 files changed, 86 insertions(+), 53 deletions(-) create mode 100644 Common/IAPRSHandlerThread.h diff --git a/Common/APRSFixedIdFrameProvider.cpp b/Common/APRSFixedIdFrameProvider.cpp index 9434175..b09ae9e 100644 --- a/Common/APRSFixedIdFrameProvider.cpp +++ b/Common/APRSFixedIdFrameProvider.cpp @@ -23,13 +23,13 @@ #include "APRSFixedIdFrameProvider.h" #include "StringUtils.h" -CAPRSFixedIdFrameProvider::CAPRSFixedIdFrameProvider() : -CAPRSIdFrameProvider(20U) // Initial timeout of 20 seconds +CAPRSFixedIdFrameProvider::CAPRSFixedIdFrameProvider(const std::string& gateway) : +CAPRSIdFrameProvider(gateway, 20U) // Initial timeout of 20 seconds { } -bool CAPRSFixedIdFrameProvider::buildAPRSFramesInt(const std::string& gateway, const CAPRSEntry * entry, std::vector& frames) +bool CAPRSFixedIdFrameProvider::buildAPRSFramesInt(const CAPRSEntry * entry, std::vector& frames) { if (entry == nullptr) return false; @@ -114,9 +114,9 @@ bool CAPRSFixedIdFrameProvider::buildAPRSFramesInt(const std::string& gateway, c lon.c_str(), (entry->getLongitude() < 0.0F) ? 'W' : 'E', entry->getRange() * 0.6214, entry->getAGL() * 3.28, band.c_str(), desc.c_str()); - CAPRSFrame * frame = new CAPRSFrame(gateway + "-S", + CAPRSFrame * frame = new CAPRSFrame(m_gateway + "-S", "APD5T1", - { "TCPIP*", "qAC" , gateway + "-GS" }, + { "TCPIP*", "qAC" , m_gateway + "-GS" }, body, APFT_OBJECT); frames.push_back(frame); diff --git a/Common/APRSFixedIdFrameProvider.h b/Common/APRSFixedIdFrameProvider.h index 8fa7032..c073a37 100644 --- a/Common/APRSFixedIdFrameProvider.h +++ b/Common/APRSFixedIdFrameProvider.h @@ -23,8 +23,8 @@ class CAPRSFixedIdFrameProvider : public CAPRSIdFrameProvider { public: - CAPRSFixedIdFrameProvider(); + CAPRSFixedIdFrameProvider(const std::string& gateway); protected: - virtual bool buildAPRSFramesInt(const std::string& gateway, const CAPRSEntry * aprsEntry, std::vector& frames); + virtual bool buildAPRSFramesInt(const CAPRSEntry * aprsEntry, std::vector& frames); }; diff --git a/Common/APRSGPSDIdFrameProvider.cpp b/Common/APRSGPSDIdFrameProvider.cpp index f67f634..7f621be 100644 --- a/Common/APRSGPSDIdFrameProvider.cpp +++ b/Common/APRSGPSDIdFrameProvider.cpp @@ -24,8 +24,8 @@ #include "StringUtils.h" #include "Log.h" -CAPRSGPSDIdFrameProvider::CAPRSGPSDIdFrameProvider(std::string address, std::string port) : -CAPRSIdFrameProvider(20U), +CAPRSGPSDIdFrameProvider::CAPRSGPSDIdFrameProvider(const std::string& gateway, const std::string& address, const std::string& port) : +CAPRSIdFrameProvider(gateway, 20U), m_gpsdAddress(address), m_gpsdPort(port), m_gpsdData(), @@ -56,7 +56,7 @@ void CAPRSGPSDIdFrameProvider::close() } } -bool CAPRSGPSDIdFrameProvider::buildAPRSFramesInt(const std::string& gateway, const CAPRSEntry * entry, std::vector& frames) +bool CAPRSGPSDIdFrameProvider::buildAPRSFramesInt(const CAPRSEntry * entry, std::vector& frames) { if(!m_hasConnection) { this->start(); @@ -182,9 +182,9 @@ bool CAPRSGPSDIdFrameProvider::buildAPRSFramesInt(const std::string& gateway, co body.append(CStringUtils::string_format("RNG%04.0lf %s %s\r\n", entry->getRange() * 0.6214, band.c_str(), desc.c_str())); - CAPRSFrame * frame = new CAPRSFrame(gateway + "-S", + CAPRSFrame * frame = new CAPRSFrame(m_gateway + "-S", "APD5T1", - { "TCPIP*", "qAC" , gateway + "-GS" }, + { "TCPIP*", "qAC" , m_gateway + "-GS" }, body, APFT_OBJECT); @@ -201,9 +201,9 @@ bool CAPRSGPSDIdFrameProvider::buildAPRSFramesInt(const std::string& gateway, co lat.c_str(), (rawLatitude < 0.0) ? 'S' : 'N', lon.c_str(), (rawLongitude < 0.0) ? 'W' : 'E'); - frame = new CAPRSFrame(gateway, + frame = new CAPRSFrame(m_gateway, "APD5T2", - { "TCPIP*", "qAC" , gateway + "-GS" }, + { "TCPIP*", "qAC" , m_gateway + "-GS" }, body, APFT_POSITION); frames.push_back(frame); diff --git a/Common/APRSGPSDIdFrameProvider.h b/Common/APRSGPSDIdFrameProvider.h index e982f9b..eca659e 100644 --- a/Common/APRSGPSDIdFrameProvider.h +++ b/Common/APRSGPSDIdFrameProvider.h @@ -29,13 +29,13 @@ class CAPRSGPSDIdFrameProvider : public CAPRSIdFrameProvider { public: - CAPRSGPSDIdFrameProvider(std::string address, std::string port); + CAPRSGPSDIdFrameProvider(const std::string& gateway, const std::string& address, const std::string& port); virtual void start(); virtual void close(); protected: - virtual bool buildAPRSFramesInt(const std::string& gateway, const CAPRSEntry * aprsEntry, std::vector& frames); + virtual bool buildAPRSFramesInt(const CAPRSEntry * aprsEntry, std::vector& frames); private: std::string m_gpsdAddress; diff --git a/Common/APRSHandler.cpp b/Common/APRSHandler.cpp index 919bb13..50dd130 100644 --- a/Common/APRSHandler.cpp +++ b/Common/APRSHandler.cpp @@ -18,10 +18,10 @@ */ #include -#include #include #include #include + #include "StringUtils.h" #include "Log.h" #include "APRSHandler.h" @@ -33,24 +33,12 @@ #include "APRSFormater.h" #include "APRSUtils.h" -CAPRSHandler::CAPRSHandler(const std::string& hostname, unsigned int port, const std::string& gateway, const std::string& password, const std::string& address) : -m_thread(NULL), -m_gateway(), -m_address(), -m_port(0U), +CAPRSHandler::CAPRSHandler(IAPRSHandlerThread* thread) : +m_thread(thread), m_array(), m_idFrameProvider(nullptr) { - assert(!hostname.empty()); - assert(port > 0U); - assert(!gateway.empty()); - assert(!password.empty()); - - m_thread = new CAPRSHandlerThread(gateway, password, address, hostname, port); - - m_gateway = gateway; - m_gateway = m_gateway.substr(0, LONG_CALLSIGN_LENGTH - 1U); - boost::trim(m_gateway); + assert(thread != nullptr); } CAPRSHandler::~CAPRSHandler() @@ -60,6 +48,7 @@ CAPRSHandler::~CAPRSHandler() } m_array.clear(); + delete m_thread; } void CAPRSHandler::setPort(const std::string& callsign, const std::string& band, double frequency, double offset, double range, double latitude, double longitude, double agl) @@ -210,7 +199,7 @@ void CAPRSHandler::sendIdFrames() { for(auto entry : m_array) { std::vector frames; - if(m_idFrameProvider->buildAPRSFrames(m_gateway, entry.second, frames)) { + if(m_idFrameProvider->buildAPRSFrames(entry.second, frames)) { for(auto frame : frames) { m_thread->write(*frame); delete frame; diff --git a/Common/APRSHandler.h b/Common/APRSHandler.h index 743ad37..0958d0a 100644 --- a/Common/APRSHandler.h +++ b/Common/APRSHandler.h @@ -26,7 +26,6 @@ #include "APRSEntry.h" -#include "APRSHandlerThread.h" #include "UDPReaderWriter.h" #include "APRSCollector.h" #include "DStarDefines.h" @@ -34,10 +33,11 @@ #include "AMBEData.h" #include "Timer.h" #include "APRSIdFrameProvider.h" +#include "IAPRSHandlerThread.h" class CAPRSHandler { public: - CAPRSHandler(const std::string& hostname, unsigned int port, const std::string& gateway, const std::string& password, const std::string& address); + CAPRSHandler(IAPRSHandlerThread * thread); ~CAPRSHandler(); bool open(); @@ -61,10 +61,7 @@ public: void addReadAPRSCallback(IReadAPRSFrameCallback* cb); private: - CAPRSHandlerThread* m_thread; - std::string m_gateway; - in_addr m_address; - unsigned int m_port; + IAPRSHandlerThread* m_thread; std::unordered_map m_array; CAPRSIdFrameProvider * m_idFrameProvider; diff --git a/Common/APRSHandlerThread.h b/Common/APRSHandlerThread.h index 01410de..fdeef68 100644 --- a/Common/APRSHandlerThread.h +++ b/Common/APRSHandlerThread.h @@ -25,11 +25,11 @@ #include "RingBuffer.h" #include "Timer.h" #include "Thread.h" -#include "ReadAPRSFrameCallback.h" +#include "IAPRSHandlerThread.h" #include "APRSFrame.h" -class CAPRSHandlerThread : public CThread { +class CAPRSHandlerThread : public CThread, IAPRSHandlerThread { public: CAPRSHandlerThread(const std::string& callsign, const std::string& password, const std::string& address, const std::string& hostname, unsigned int port); CAPRSHandlerThread(const std::string& callsign, const std::string& password, const std::string& address, const std::string& hostname, unsigned int port, const std::string& filter); diff --git a/Common/APRSIdFrameProvider.cpp b/Common/APRSIdFrameProvider.cpp index 3637f9d..fc8b6e0 100644 --- a/Common/APRSIdFrameProvider.cpp +++ b/Common/APRSIdFrameProvider.cpp @@ -17,13 +17,21 @@ */ #include +#include #include "APRSIdFrameProvider.h" -CAPRSIdFrameProvider::CAPRSIdFrameProvider(unsigned int timeout) : +CAPRSIdFrameProvider::CAPRSIdFrameProvider(const std::string& gateway, unsigned int timeout) : +m_gateway(), m_timer(1000U) { + assert(!gateway.empty()); + m_timer.start(timeout); + + m_gateway = gateway; + m_gateway = m_gateway.substr(0, LONG_CALLSIGN_LENGTH - 1U); + boost::trim(m_gateway); } CAPRSIdFrameProvider::~CAPRSIdFrameProvider() @@ -31,11 +39,11 @@ CAPRSIdFrameProvider::~CAPRSIdFrameProvider() } -bool CAPRSIdFrameProvider::buildAPRSFrames(const std::string& gateway, const CAPRSEntry * entry, std::vector & frames) +bool CAPRSIdFrameProvider::buildAPRSFrames(const CAPRSEntry * entry, std::vector & frames) { assert(entry != nullptr); - return buildAPRSFramesInt(gateway, entry, frames); + return buildAPRSFramesInt(entry, frames); } bool CAPRSIdFrameProvider::wantsToSend() diff --git a/Common/APRSIdFrameProvider.h b/Common/APRSIdFrameProvider.h index 48917ee..f123118 100644 --- a/Common/APRSIdFrameProvider.h +++ b/Common/APRSIdFrameProvider.h @@ -27,23 +27,25 @@ class CAPRSIdFrameProvider { public: - CAPRSIdFrameProvider(unsigned int timeOut); + CAPRSIdFrameProvider(const std::string& gateway, unsigned int timeOut); virtual ~CAPRSIdFrameProvider(); - bool buildAPRSFrames(const std::string& gateway, const CAPRSEntry * aprsEntry, std::vector& frames); + bool buildAPRSFrames(const CAPRSEntry * aprsEntry, std::vector& frames); void clock(unsigned int ms) { m_timer.clock(ms); } bool wantsToSend(); virtual void start() { }; virtual void close() { }; protected: - virtual bool buildAPRSFramesInt(const std::string& gateway, const CAPRSEntry * aprsEntry, std::vector& frames) = 0; + virtual bool buildAPRSFramesInt(const CAPRSEntry * aprsEntry, std::vector& frames) = 0; void setTimeout(unsigned int timeout) { m_timer.start(timeout); } +protected: + std::string m_gateway; private: CTimer m_timer; }; \ No newline at end of file diff --git a/Common/IAPRSHandlerThread.h b/Common/IAPRSHandlerThread.h new file mode 100644 index 0000000..991f8f5 --- /dev/null +++ b/Common/IAPRSHandlerThread.h @@ -0,0 +1,35 @@ +/* + * Copyright (C) 2021, 2022 by Geoffrey Merck F4FXL / KC3FRA + * + * 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 "APRSFrame.h" +#include "ReadAPRSFrameCallback.h" + +class IAPRSHandlerThread +{ +public: + virtual ~IAPRSHandlerThread() { } ; + + virtual bool start() = 0; + virtual bool isConnected() const = 0; + virtual void write(CAPRSFrame& frame) = 0; + virtual void clock(unsigned int ms) = 0; + virtual void stop() = 0; + virtual void addReadAPRSCallback(IReadAPRSFrameCallback* cb) = 0; +}; \ No newline at end of file diff --git a/DStarGateway/DStarGatewayApp.cpp b/DStarGateway/DStarGatewayApp.cpp index 8ce9864..76f9c3b 100644 --- a/DStarGateway/DStarGatewayApp.cpp +++ b/DStarGateway/DStarGatewayApp.cpp @@ -1,6 +1,6 @@ /* * Copyright (C) 2010,2011 by Jonathan Naylor G4KLX - * Copyright (c) 2021-2022 by Geoffrey Merck F4FXL / KC3FRA + * Copyright (c) 2021,2022 by Geoffrey Merck F4FXL / KC3FRA * * 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 @@ -48,6 +48,7 @@ #include "APRSGPSDIdFrameProvider.h" #include "APRSFixedIdFrameProvider.h" #include "Daemon.h" +#include "APRSHandlerThread.h" CDStarGatewayApp * CDStarGatewayApp::g_app = nullptr; const std::string BANNER_1 = CStringUtils::string_format("%s Copyright (C) %s\n", FULL_PRODUCT_NAME.c_str(), VENDOR_NAME.c_str()); @@ -194,13 +195,14 @@ bool CDStarGatewayApp::createThread() m_config->getAPRS(aprsConfig); CAPRSHandler * aprsWriter = NULL; if(aprsConfig.enabled && !aprsConfig.password.empty()) { - aprsWriter = new CAPRSHandler(aprsConfig.hostname, aprsConfig.port, gatewayConfig.callsign, aprsConfig.password, gatewayConfig.address); + CAPRSHandlerThread* thread = new CAPRSHandlerThread(gatewayConfig.callsign, aprsConfig.password, gatewayConfig.address, aprsConfig.hostname, aprsConfig.port); + aprsWriter = new CAPRSHandler((IAPRSHandlerThread *)thread); if(aprsWriter->open()) { #ifdef USE_GPSD - CAPRSIdFrameProvider * idFrameProvider = aprsConfig.m_positionSource == POSSRC_GPSD ? (CAPRSIdFrameProvider *)new CAPRSGPSDIdFrameProvider(gpsdConfig.m_address, gpsdConfig.m_port) - : new CAPRSFixedIdFrameProvider(); + CAPRSIdFrameProvider * idFrameProvider = aprsConfig.m_positionSource == POSSRC_GPSD ? (CAPRSIdFrameProvider *)new CAPRSGPSDIdFrameProvider(gatewayConfig.callsign, gpsdConfig.m_address, gpsdConfig.m_port) + : new CAPRSFixedIdFrameProvider(gatewayConfig.callsign); #else - CAPRSIdFrameProvider * idFrameProvider = new CAPRSFixedIdFrameProvider(); + CAPRSIdFrameProvider * idFrameProvider = new CAPRSFixedIdFrameProvider(gatewayConfig.callsign); #endif idFrameProvider->start(); aprsWriter->setIdFrameProvider(idFrameProvider); diff --git a/DStarGateway/DStarGatewayThread.cpp b/DStarGateway/DStarGatewayThread.cpp index 1d7d074..93b78bf 100644 --- a/DStarGateway/DStarGatewayThread.cpp +++ b/DStarGateway/DStarGatewayThread.cpp @@ -984,7 +984,7 @@ void CDStarGatewayThread::processDExtra() case DE_HEADER: { CHeaderData* header = m_dextraPool->readHeader(); if (header != NULL) { - // CLog::logInfo("DExtra header - My: %s/%s Your: %s Rpt1: %s Rpt2: %s", header->getMyCall1().c_str(), header->getMyCall2().c_str(), header->getYourCall().c_str(), header->getRptCall1().c_str(), header->getRptCall2().c_str()); + CLog::logInfo("DExtra header - My: %s/%s Your: %s Rpt1: %s Rpt2: %s", header->getMyCall1().c_str(), header->getMyCall2().c_str(), header->getYourCall().c_str(), header->getRptCall1().c_str(), header->getRptCall2().c_str()); CDExtraHandler::process(*header); delete header; }