Merge branch 'feature/DPRSLog' into develop closes #29

pull/32/head
Geoffrey Merck 3 years ago
commit 687194993e

@ -73,7 +73,25 @@
"typeindex": "cpp",
"variant": "cpp",
"iostream": "cpp",
"fstream": "cpp"
"fstream": "cpp",
"csignal": "cpp",
"cstdarg": "cpp",
"strstream": "cpp",
"codecvt": "cpp",
"numeric": "cpp",
"regex": "cpp",
"cfenv": "cpp",
"cinttypes": "cpp"
},
"files.exclude": {
"**/.DS_Store": true,
"**/.git": true,
"**/.hg": true,
"**/.svn": true,
"**/*.d": true,
"**/*.o": true,
"**/CVS": true,
"**/Thumbs.db": true
},
"editor.tokenColorCustomizations": {
"textMateRules": [

@ -70,7 +70,7 @@ void CUtils::dump(const char* title, const bool* data, unsigned int length)
output += "*'";
CLog::logInfo("%04X: %s\n", offset / 8U, output.c_str());
CLog::logDebug("%04X: %s\n", offset / 8U, output.c_str());
offset += 128U;
}
@ -115,7 +115,7 @@ void CUtils::dumpRev(const char* title, const bool* data, unsigned int length)
output += "*";
CLog::logInfo("%04X: %s\n", offset / 8U, output.c_str());
CLog::logDebug("%04X: %s\n", offset / 8U, output.c_str());
offset += 128U;
}
@ -157,7 +157,7 @@ void CUtils::dump(const char* title, const unsigned char* data, unsigned int len
output += "*";
CLog::logInfo("%04X: %s\n", offset, output.c_str());
CLog::logDebug("%04X: %s\n", offset, output.c_str());
offset += 16U;

@ -51,10 +51,14 @@ CAPRSCollector::~CAPRSCollector()
m_collectors.clear();
}
void CAPRSCollector::writeHeader(const std::string& callsign)
void CAPRSCollector::writeHeader(const CHeaderData& header)
{
std::string mycall1 = header.getMyCall1();
std::string mycall2 = header.getMyCall2();
for(auto collector : m_collectors) {
collector->setMyCall(callsign);
collector->setMyCall1(mycall1);
collector->setMyCall2(mycall2);
}
}
@ -95,12 +99,12 @@ unsigned int CAPRSCollector::getData(unsigned char dataType, unsigned char* data
return 0U;
}
void CAPRSCollector::getData(std::function<void(const std::string&)> dataHandler)
void CAPRSCollector::getData(std::function<void(const std::string&, const std::string&)> dataHandler)
{
for(auto collector : m_collectors) {
std::string data;
if(collector->getData(data)) {
dataHandler(data);
dataHandler(data, collector->getMyCall1().append("/").append(collector->getMyCall2()));
collector->reset();
}
}

@ -24,6 +24,7 @@
#include <functional>
#include "SlowDataCollector.h"
#include "HeaderData.h"
#include "Defs.h"
enum APRS_STATE {
@ -39,7 +40,7 @@ public:
CAPRSCollector();
~CAPRSCollector();
void writeHeader(const std::string& callsign);
void writeHeader(const CHeaderData& callsign);
bool writeData(const unsigned char* data);
@ -49,7 +50,7 @@ public:
unsigned int getData(unsigned char dataType, unsigned char* data, unsigned int length);
void getData(std::function<void(const std::string&)> dataHandler);
void getData(std::function<void(const std::string&, const std::string&)> dataHandler);
void clock(unsigned int ms);

@ -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<CAPRSFrame *>& frames)
bool CAPRSFixedIdFrameProvider::buildAPRSFramesInt(const CAPRSEntry * entry, std::vector<CAPRSFrame *>& 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);

@ -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<CAPRSFrame *>& frames);
virtual bool buildAPRSFramesInt(const CAPRSEntry * aprsEntry, std::vector<CAPRSFrame *>& frames);
};

@ -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<CAPRSFrame *>& frames)
bool CAPRSGPSDIdFrameProvider::buildAPRSFramesInt(const CAPRSEntry * entry, std::vector<CAPRSFrame *>& 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);

@ -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<CAPRSFrame *>& frames);
virtual bool buildAPRSFramesInt(const CAPRSEntry * aprsEntry, std::vector<CAPRSFrame *>& frames);
private:
std::string m_gpsdAddress;

@ -18,7 +18,6 @@
*/
#include <cassert>
#include <boost/algorithm/string.hpp>
#include <cmath>
#include <cassert>
#include <algorithm>
@ -34,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(IAPRSHandlerBackend* thread) :
m_backend(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()
@ -61,6 +48,7 @@ CAPRSHandler::~CAPRSHandler()
}
m_array.clear();
delete m_backend;
}
void CAPRSHandler::setPort(const std::string& callsign, const std::string& band, double frequency, double offset, double range, double latitude, double longitude, double agl)
@ -74,7 +62,7 @@ void CAPRSHandler::setPort(const std::string& callsign, const std::string& band,
bool CAPRSHandler::open()
{
return m_thread->start();
return m_backend->start();
}
void CAPRSHandler::writeHeader(const std::string& callsign, const CHeaderData& header)
@ -89,7 +77,7 @@ void CAPRSHandler::writeHeader(const std::string& callsign, const CHeaderData& h
CAPRSCollector* collector = entry->getCollector();
collector->writeHeader(header.getMyCall1());
collector->writeHeader(header);
}
void CAPRSHandler::writeData(const std::string& callsign, const CAMBEData& data)
@ -117,22 +105,22 @@ void CAPRSHandler::writeData(const std::string& callsign, const CAMBEData& data)
if (!complete)
return;
if (!m_thread->isConnected()) {
if (!m_backend->isConnected()) {
collector->reset();
return;
}
collector->getData([=](const std::string& text)
collector->getData([=](const std::string& rawFrame, const std::string& dstarCall)
{
CAPRSFrame frame;
if(!CAPRSParser::parseFrame(text, frame)) {
CLog::logWarning("Failed to parse DPRS Frame : %s", text.c_str());
if(!CAPRSParser::parseFrame(rawFrame, frame)) {
CLog::logWarning("Failed to parse DPRS Frame : %s", rawFrame.c_str());
return;
}
// If we already have a q-construct, don't send it on
if(std::any_of(frame.getPath().begin(), frame.getPath().end(), [] (std::string s) { return !s.empty() && s[0] == 'q'; })) {
CLog::logWarning("DPRS Frame already has q construct, not forwarding to APRS-IS: %s", text.c_str());
CLog::logWarning("DPRS Frame already has q construct, not forwarding to APRS-IS: %s", rawFrame.c_str());
return;
}
@ -142,7 +130,9 @@ void CAPRSHandler::writeData(const std::string& callsign, const CAMBEData& data)
std::string output ;
CAPRSFormater::frameToString(output, frame);
m_thread->write(frame);
CLog::logInfo("DPRS\t%s\t%s\t%s", dstarCall.c_str(), frame.getSource().c_str(), rawFrame.c_str());
m_backend->write(frame);
});
}
@ -159,7 +149,7 @@ void CAPRSHandler::writeStatus(const std::string& callsign, const std::string st
void CAPRSHandler::clock(unsigned int ms)
{
m_thread->clock(ms);
m_backend->clock(ms);
if(m_idFrameProvider != nullptr) {
m_idFrameProvider->clock(ms);
@ -181,7 +171,7 @@ void CAPRSHandler::sendStatusFrame(CAPRSEntry * entry)
{
assert(entry != nullptr);
if(!m_thread->isConnected())
if(!m_backend->isConnected())
return;
@ -199,19 +189,19 @@ void CAPRSHandler::sendStatusFrame(CAPRSEntry * entry)
body,
APFT_STATUS);
m_thread->write(frame);
m_backend->write(frame);
}
void CAPRSHandler::sendIdFrames()
{
if(m_thread->isConnected())
if(m_backend->isConnected())
{
for(auto entry : m_array) {
std::vector<CAPRSFrame *> 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);
m_backend->write(*frame);
delete frame;
}
}
@ -221,12 +211,12 @@ void CAPRSHandler::sendIdFrames()
bool CAPRSHandler::isConnected() const
{
return m_thread->isConnected();
return m_backend->isConnected();
}
void CAPRSHandler::close()
{
m_thread->stop();
m_backend->stop();
if(m_idFrameProvider != nullptr) {
m_idFrameProvider->close();
@ -237,5 +227,5 @@ void CAPRSHandler::close()
void CAPRSHandler::addReadAPRSCallback(IReadAPRSFrameCallback* cb)
{
m_thread->addReadAPRSCallback(cb);
m_backend->addReadAPRSCallback(cb);
}

@ -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 "IAPRSHandlerBackend.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(IAPRSHandlerBackend * 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;
IAPRSHandlerBackend* m_backend;
std::unordered_map<std::string,CAPRSEntry *> m_array;
CAPRSIdFrameProvider * m_idFrameProvider;

@ -21,7 +21,7 @@
#include <iostream>
#include <boost/algorithm/string.hpp>
#include "APRSHandlerThread.h"
#include "APRSISHandlerThread.h"
#include "DStarDefines.h"
#include "Utils.h"
#include "Defs.h"
@ -36,7 +36,7 @@ const unsigned int APRS_TIMEOUT = 10U;
const unsigned int APRS_READ_TIMEOUT = 1U;
const unsigned int APRS_KEEP_ALIVE_TIMEOUT = 60U;
CAPRSHandlerThread::CAPRSHandlerThread(const std::string& callsign, const std::string& password, const std::string& address, const std::string& hostname, unsigned int port) :
CAPRSISHandlerThread::CAPRSISHandlerThread(const std::string& callsign, const std::string& password, const std::string& address, const std::string& hostname, unsigned int port) :
CThread("APRS"),
m_username(callsign),
m_password(password),
@ -64,7 +64,7 @@ m_clientName(FULL_PRODUCT_NAME)
m_ssid = m_ssid.substr(LONG_CALLSIGN_LENGTH - 1U, 1);
}
CAPRSHandlerThread::CAPRSHandlerThread(const std::string& callsign, const std::string& password, const std::string& address, const std::string& hostname, unsigned int port, const std::string& filter) :
CAPRSISHandlerThread::CAPRSISHandlerThread(const std::string& callsign, const std::string& password, const std::string& address, const std::string& hostname, unsigned int port, const std::string& filter) :
CThread("APRS"),
m_username(callsign),
m_password(password),
@ -92,7 +92,7 @@ m_clientName(FULL_PRODUCT_NAME)
m_ssid = m_ssid.substr(LONG_CALLSIGN_LENGTH - 1U, 1);
}
CAPRSHandlerThread::~CAPRSHandlerThread()
CAPRSISHandlerThread::~CAPRSISHandlerThread()
{
std::vector<IReadAPRSFrameCallback *> callBacksCopy;
callBacksCopy.assign(m_APRSReadCallbacks.begin(), m_APRSReadCallbacks.end());
@ -105,7 +105,7 @@ CAPRSHandlerThread::~CAPRSHandlerThread()
m_password.clear();
}
bool CAPRSHandlerThread::start()
bool CAPRSISHandlerThread::start()
{
Create();
Run();
@ -113,7 +113,7 @@ bool CAPRSHandlerThread::start()
return true;
}
void* CAPRSHandlerThread::Entry()
void* CAPRSISHandlerThread::Entry()
{
CLog::logInfo("Starting the APRS Writer thread");
@ -151,7 +151,7 @@ void* CAPRSHandlerThread::Entry()
if(!m_queue.empty()){
auto frameStr = m_queue.getData();
CLog::logInfo("APRS ==> %s", frameStr.c_str());
CLog::logInfo("APRS Frame sent to IS ==> %s", frameStr.c_str());
bool ret = m_socket.writeLine(frameStr);
if (!ret) {
@ -176,7 +176,7 @@ void* CAPRSHandlerThread::Entry()
}
else if(line.length() > 0 && line[0] != '#') {
m_keepAliveTimer.start();
CLog::logDebug("APRS <== %s", line.c_str());
CLog::logDebug("APRS Frame received from IS <== %s", line.c_str());
CAPRSFrame readFrame;
if(CAPRSParser::parseFrame(line, readFrame)) {
for(auto cb : m_APRSReadCallbacks) {
@ -214,13 +214,13 @@ void* CAPRSHandlerThread::Entry()
return NULL;
}
void CAPRSHandlerThread::addReadAPRSCallback(IReadAPRSFrameCallback * cb)
void CAPRSISHandlerThread::addReadAPRSCallback(IReadAPRSFrameCallback * cb)
{
assert(cb != nullptr);
m_APRSReadCallbacks.push_back(cb);
}
void CAPRSHandlerThread::write(CAPRSFrame& frame)
void CAPRSISHandlerThread::write(CAPRSFrame& frame)
{
if (!m_connected)
return;
@ -235,25 +235,25 @@ void CAPRSHandlerThread::write(CAPRSFrame& frame)
}
}
bool CAPRSHandlerThread::isConnected() const
bool CAPRSISHandlerThread::isConnected() const
{
return m_connected;
}
void CAPRSHandlerThread::stop()
void CAPRSISHandlerThread::stop()
{
m_exit = true;
Wait();
}
void CAPRSHandlerThread::clock(unsigned int ms)
void CAPRSISHandlerThread::clock(unsigned int ms)
{
m_reconnectTimer.clock(ms);
m_keepAliveTimer.clock(ms);
}
bool CAPRSHandlerThread::connect()
bool CAPRSISHandlerThread::connect()
{
m_socket.close();
bool ret = m_socket.open();
@ -304,7 +304,7 @@ bool CAPRSHandlerThread::connect()
return true;
}
void CAPRSHandlerThread::startReconnectionTimer()
void CAPRSISHandlerThread::startReconnectionTimer()
{
// Clamp at a ten minutes reconnect time
m_tries++;

@ -25,15 +25,15 @@
#include "RingBuffer.h"
#include "Timer.h"
#include "Thread.h"
#include "ReadAPRSFrameCallback.h"
#include "IAPRSHandlerBackend.h"
#include "APRSFrame.h"
class CAPRSHandlerThread : public CThread {
class CAPRSISHandlerThread : public CThread, IAPRSHandlerBackend {
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);
virtual ~CAPRSHandlerThread();
CAPRSISHandlerThread(const std::string& callsign, const std::string& password, const std::string& address, const std::string& hostname, unsigned int port);
CAPRSISHandlerThread(const std::string& callsign, const std::string& password, const std::string& address, const std::string& hostname, unsigned int port, const std::string& filter);
virtual ~CAPRSISHandlerThread();
bool start();

@ -17,13 +17,21 @@
*/
#include <cassert>
#include <boost/algorithm/string.hpp>
#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<CAPRSFrame *> & frames)
bool CAPRSIdFrameProvider::buildAPRSFrames(const CAPRSEntry * entry, std::vector<CAPRSFrame *> & frames)
{
assert(entry != nullptr);
return buildAPRSFramesInt(gateway, entry, frames);
return buildAPRSFramesInt(entry, frames);
}
bool CAPRSIdFrameProvider::wantsToSend()

@ -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<CAPRSFrame *>& frames);
bool buildAPRSFrames(const CAPRSEntry * aprsEntry, std::vector<CAPRSFrame *>& 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<CAPRSFrame *>& frames) = 0;
virtual bool buildAPRSFramesInt(const CAPRSEntry * aprsEntry, std::vector<CAPRSFrame *>& frames) = 0;
void setTimeout(unsigned int timeout)
{
m_timer.start(timeout);
}
protected:
std::string m_gateway;
private:
CTimer m_timer;
};

@ -0,0 +1,55 @@
/*
* 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.
*/
#include "DummyAPRSHandlerThread.h"
CDummyAPRSHandlerBackend::CDummyAPRSHandlerBackend()
{
}
CDummyAPRSHandlerBackend::~CDummyAPRSHandlerBackend()
{
}
bool CDummyAPRSHandlerBackend::start()
{
return true;
}
bool CDummyAPRSHandlerBackend::isConnected() const
{
return true;
}
void CDummyAPRSHandlerBackend::write(CAPRSFrame &)
{
}
void CDummyAPRSHandlerBackend::clock(unsigned int)
{
}
void CDummyAPRSHandlerBackend::stop()
{
}
void CDummyAPRSHandlerBackend::addReadAPRSCallback(IReadAPRSFrameCallback *)
{
}

@ -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 "IAPRSHandlerBackend.h"
class CDummyAPRSHandlerBackend : public IAPRSHandlerBackend
{
public:
CDummyAPRSHandlerBackend();
~CDummyAPRSHandlerBackend();
bool start();
bool isConnected() const;
void write(CAPRSFrame& frame);
void clock(unsigned int ms);
void stop();
void addReadAPRSCallback(IReadAPRSFrameCallback* cb);
};

@ -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 IAPRSHandlerBackend
{
public:
virtual ~IAPRSHandlerBackend() { } ;
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;
};

@ -58,7 +58,7 @@ unsigned char CNMEASentenceCollector::calcXOR(const std::string& nmea)
unsigned char res = 0U;
if(!nmea.empty()) {
unsigned int i = nmea[0] == '$' ? 1U : 0U; //skip $ it it is there
unsigned int i = nmea[0] == '$' ? 1U : 0U; //skip $ if it is there
while(i < nmea.length())
{
if(nmea[i] != '*') {
@ -98,14 +98,14 @@ unsigned int CNMEASentenceCollector::getDataInt(unsigned char * data, unsigned i
bool CNMEASentenceCollector::getDataInt(std::string& data)
{
if(getMyCall().empty() || getSentence().empty())
if(getMyCall1().empty() || getSentence().empty())
return false;
data.clear();
auto nmea = getSentence();
fixUpNMEATimeStamp(nmea);
std::string fromCall = getMyCall();
std::string fromCall = getMyCall1();
CAPRSUtils::dstarCallsignToAPRS(fromCall);
std::string aprsFrame(fromCall);
aprsFrame.append("-5>GPS30,DSTAR*:")

@ -59,7 +59,8 @@ bool CRepeaterHandler::m_dtmfEnabled = true;
CHeaderLogger* CRepeaterHandler::m_headerLogger = NULL;
CAPRSHandler* CRepeaterHandler::m_aprsWriter = NULL;
CAPRSHandler* CRepeaterHandler::m_outgoingAprsHandler = NULL; //handles APRS/DPRS frames coming from radio to network
CAPRSHandler* CRepeaterHandler::m_incomingAprsHandler = NULL; //handles APRS/DPRS frames coming from network to radio
CCallsignList* CRepeaterHandler::m_restrictList = NULL;
@ -352,9 +353,10 @@ void CRepeaterHandler::setHeaderLogger(CHeaderLogger* logger)
m_headerLogger = logger;
}
void CRepeaterHandler::setAPRSWriter(CAPRSHandler* writer)
void CRepeaterHandler::setAPRSHandlers(CAPRSHandler* outgoingAprsHandler, CAPRSHandler* incomingAprsHandler)
{
m_aprsWriter = writer;
m_outgoingAprsHandler = outgoingAprsHandler;
m_incomingAprsHandler = incomingAprsHandler;
}
void CRepeaterHandler::setLocalAddress(const std::string& address)
@ -613,8 +615,8 @@ void CRepeaterHandler::processRepeater(CHeaderData& header)
m_text.clear();
// Reset the APRS Writer if it's enabled
if (m_aprsWriter != NULL)
m_aprsWriter->writeHeader(m_rptCallsign, header);
if (m_outgoingAprsHandler != NULL)
m_outgoingAprsHandler->writeHeader(m_rptCallsign, header);
// Write to Header.log if it's enabled
if (m_headerLogger != NULL)
@ -823,8 +825,8 @@ void CRepeaterHandler::processRepeater(CAMBEData& data)
if (m_drats != NULL)
m_drats->writeData(data);
if (m_aprsWriter != NULL)
m_aprsWriter->writeData(m_rptCallsign, data);
if (m_outgoingAprsHandler != NULL)
m_outgoingAprsHandler->writeData(m_rptCallsign, data);
if (m_text.empty() && !data.isEnd()) {
m_textCollector.writeData(data);
@ -1173,6 +1175,9 @@ bool CRepeaterHandler::process(CHeaderData& header, DIRECTION, AUDIO_SOURCE sour
if (source == AS_DUP)
return true;
if(m_incomingAprsHandler != nullptr)
m_incomingAprsHandler->writeHeader(m_rptCallsign, header);
sendToIncoming(header);
#ifdef USE_CCS
@ -1212,6 +1217,9 @@ bool CRepeaterHandler::process(CAMBEData& data, DIRECTION, AUDIO_SOURCE source)
m_repeaterHandler->writeAMBE(data);
if(m_incomingAprsHandler != nullptr)
m_incomingAprsHandler->writeData(m_rptCallsign, data);
sendToIncoming(data);
#ifdef USE_CCS
@ -2413,8 +2421,8 @@ void CRepeaterHandler::startupInt()
m_irc->rptrQTH(callsign, m_latitude, m_longitude, m_description1, m_description2, m_url);
}
if(m_aprsWriter != nullptr) {
m_aprsWriter->addReadAPRSCallback(this);
if(m_outgoingAprsHandler != nullptr) {
m_outgoingAprsHandler->addReadAPRSCallback(this);
}
#ifdef USE_CCS
@ -2564,8 +2572,8 @@ void CRepeaterHandler::writeLinkingTo(const std::string &callsign)
m_infoAudio->setStatus(m_linkStatus, m_linkRepeater, text);
triggerInfo();
if(m_aprsWriter != nullptr)
m_aprsWriter->writeStatus(m_rptCallsign, text);
if(m_outgoingAprsHandler != nullptr)
m_outgoingAprsHandler->writeStatus(m_rptCallsign, text);
#ifdef USE_CCS
m_ccsHandler->setReflector();
@ -2619,8 +2627,8 @@ void CRepeaterHandler::writeLinkedTo(const std::string &callsign)
m_infoAudio->setStatus(m_linkStatus, m_linkRepeater, text);
triggerInfo();
if(m_aprsWriter != nullptr)
m_aprsWriter->writeStatus(m_rptCallsign, text);
if(m_outgoingAprsHandler != nullptr)
m_outgoingAprsHandler->writeStatus(m_rptCallsign, text);
#ifdef USE_CCS
m_ccsHandler->setReflector(callsign);
@ -2674,8 +2682,8 @@ void CRepeaterHandler::writeNotLinked()
m_infoAudio->setStatus(m_linkStatus, m_linkRepeater, text);
triggerInfo();
if(m_aprsWriter != nullptr)
m_aprsWriter->writeStatus(m_rptCallsign, text);
if(m_outgoingAprsHandler != nullptr)
m_outgoingAprsHandler->writeStatus(m_rptCallsign, text);
#ifdef USE_CCS
m_ccsHandler->setReflector();
@ -2745,8 +2753,8 @@ void CRepeaterHandler::writeIsBusy(const std::string& callsign)
m_infoAudio->setTempStatus(m_linkStatus, m_linkRepeater, tempText);
triggerInfo();
if(m_aprsWriter != nullptr)
m_aprsWriter->writeStatus(m_rptCallsign, text);
if(m_outgoingAprsHandler != nullptr)
m_outgoingAprsHandler->writeStatus(m_rptCallsign, text);
#ifdef USE_CCS
m_ccsHandler->setReflector();

@ -74,7 +74,7 @@ public:
static void setDPlusEnabled(bool enabled);
static void setDCSEnabled(bool enabled);
static void setHeaderLogger(CHeaderLogger* logger);
static void setAPRSWriter(CAPRSHandler* writer);
static void setAPRSHandlers(CAPRSHandler* outgoingAprsHandler, CAPRSHandler* incomingAprsHandler);
static void setInfoEnabled(bool enabled);
static void setEchoEnabled(bool enabled);
static void setDTMFEnabled(bool enabled);
@ -169,7 +169,8 @@ private:
static CHeaderLogger* m_headerLogger;
static CAPRSHandler* m_aprsWriter;
static CAPRSHandler* m_outgoingAprsHandler;
static CAPRSHandler* m_incomingAprsHandler;
static CCallsignList* m_whiteList;
static CCallsignList* m_blackList;

@ -27,7 +27,7 @@ const unsigned int SLOW_DATA_BLOCK_LENGTH = 6U;
CSlowDataCollector::CSlowDataCollector(unsigned char slowDataType) :
m_slowDataType(slowDataType),
m_myCall(),
m_myCall1(),
m_state(SS_FIRST)
{
m_buffer = new unsigned char[SLOW_DATA_BLOCK_LENGTH];
@ -39,14 +39,24 @@ CSlowDataCollector::~CSlowDataCollector()
delete[] m_buffer;
}
std::string CSlowDataCollector::getMyCall() const
std::string CSlowDataCollector::getMyCall1() const
{
return m_myCall;
return m_myCall1;
}
void CSlowDataCollector::setMyCall(const std::string& myCall)
void CSlowDataCollector::setMyCall1(const std::string& myCall)
{
m_myCall = myCall;
m_myCall1 = myCall;
}
std::string CSlowDataCollector::getMyCall2() const
{
return m_myCall2;
}
void CSlowDataCollector::setMyCall2(const std::string& myCall)
{
m_myCall2 = myCall;
}
bool CSlowDataCollector::writeData(const unsigned char* data)

@ -29,8 +29,10 @@ class ISlowDataCollector
public:
virtual ~ISlowDataCollector() { } ;
virtual std::string getMyCall() const = 0;
virtual void setMyCall(const std::string& mycall) = 0;
virtual std::string getMyCall1() const = 0;
virtual void setMyCall1(const std::string& mycall) = 0;
virtual std::string getMyCall2() const = 0;
virtual void setMyCall2(const std::string& mycall) = 0;
virtual bool writeData(const unsigned char* data) = 0;
virtual void sync() = 0;
virtual unsigned int getData(unsigned char* data, unsigned int length) = 0;
@ -46,8 +48,10 @@ public:
CSlowDataCollector(unsigned char slowDataType);
virtual ~CSlowDataCollector();
std::string getMyCall() const;
void setMyCall(const std::string& mycall);
std::string getMyCall1() const;
void setMyCall1(const std::string& mycall);
std::string getMyCall2() const;
void setMyCall2(const std::string& mycall);
bool writeData(const unsigned char* data);
void sync();
unsigned int getData(unsigned char* data, unsigned int length);
@ -64,7 +68,8 @@ protected:
private:
unsigned char m_slowDataType;
std::string m_myCall;
std::string m_myCall1;
std::string m_myCall2;
SLOWDATA_STATE m_state;
unsigned char * m_buffer;
};

@ -33,16 +33,27 @@ CSlowDataCollectorThrottle::~CSlowDataCollectorThrottle()
delete m_collector;
}
std::string CSlowDataCollectorThrottle::getMyCall() const
std::string CSlowDataCollectorThrottle::getMyCall1() const
{
return m_collector->getMyCall();
return m_collector->getMyCall1();
}
void CSlowDataCollectorThrottle::setMyCall(const std::string& mycall)
void CSlowDataCollectorThrottle::setMyCall1(const std::string& mycall)
{
m_isFirst = true;
m_collector->setMyCall(mycall);
m_collector->setMyCall1(mycall);
}
std::string CSlowDataCollectorThrottle::getMyCall2() const
{
return m_collector->getMyCall2();
}
void CSlowDataCollectorThrottle::setMyCall2(const std::string& mycall)
{
m_isFirst = true;
m_collector->setMyCall2(mycall);
}
bool CSlowDataCollectorThrottle::writeData(const unsigned char* data)
{
m_isComplete = false;

@ -28,8 +28,10 @@ class CSlowDataCollectorThrottle : public ISlowDataCollector
public:
CSlowDataCollectorThrottle(ISlowDataCollector* collector, unsigned int timeout);
~CSlowDataCollectorThrottle();
std::string getMyCall() const;
void setMyCall(const std::string& mycall);
std::string getMyCall1() const;
void setMyCall1(const std::string& mycall);
std::string getMyCall2() const;
void setMyCall2(const std::string& mycall);
bool writeData(const unsigned char* data);
void sync();
unsigned int getData(unsigned char* data, unsigned int length);

@ -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,8 @@
#include "APRSGPSDIdFrameProvider.h"
#include "APRSFixedIdFrameProvider.h"
#include "Daemon.h"
#include "APRSISHandlerThread.h"
#include "DummyAPRSHandlerThread.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());
@ -192,23 +194,28 @@ bool CDStarGatewayApp::createThread()
// Setup APRS
TAPRS aprsConfig;
m_config->getAPRS(aprsConfig);
CAPRSHandler * aprsWriter = NULL;
CAPRSHandler * outgoingAprsWriter = nullptr;
CAPRSHandler * incomingAprsWriter = nullptr;
if(aprsConfig.enabled && !aprsConfig.password.empty()) {
aprsWriter = new CAPRSHandler(aprsConfig.hostname, aprsConfig.port, gatewayConfig.callsign, aprsConfig.password, gatewayConfig.address);
if(aprsWriter->open()) {
CAPRSISHandlerThread* aprsisthread = new CAPRSISHandlerThread(gatewayConfig.callsign, aprsConfig.password, gatewayConfig.address, aprsConfig.hostname, aprsConfig.port);
outgoingAprsWriter = new CAPRSHandler((IAPRSHandlerBackend *)aprsisthread);
incomingAprsWriter = new CAPRSHandler((IAPRSHandlerBackend *)new CDummyAPRSHandlerBackend());
if(outgoingAprsWriter->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);
m_thread->setAPRSWriter(aprsWriter);
outgoingAprsWriter->setIdFrameProvider(idFrameProvider);
m_thread->setAPRSWriters(outgoingAprsWriter, incomingAprsWriter);
}
else {
delete aprsWriter;
aprsWriter = NULL;
delete outgoingAprsWriter;
outgoingAprsWriter = NULL;
}
}
@ -278,7 +285,10 @@ bool CDStarGatewayApp::createThread()
rptrConfig.band2,
rptrConfig.band3);
aprsWriter->setPort(rptrConfig.callsign, rptrConfig.band, rptrConfig.frequency, rptrConfig.offset, rptrConfig.range, rptrConfig.latitude, rptrConfig.longitude, rptrConfig.agl);
if(outgoingAprsWriter != nullptr)
outgoingAprsWriter->setPort(rptrConfig.callsign, rptrConfig.band, rptrConfig.frequency, rptrConfig.offset, rptrConfig.range, rptrConfig.latitude, rptrConfig.longitude, rptrConfig.agl);
if(incomingAprsWriter != nullptr)
incomingAprsWriter->setPort(rptrConfig.callsign, rptrConfig.band, rptrConfig.frequency, rptrConfig.offset, rptrConfig.range, rptrConfig.latitude, rptrConfig.longitude, rptrConfig.agl);
if(!ddEnabled) ddEnabled = rptrConfig.band.length() > 1U;
}

@ -69,15 +69,16 @@ m_stopped(true),
m_gatewayType(GT_REPEATER),
m_gatewayCallsign(),
m_gatewayAddress(),
m_icomRepeaterHandler(NULL),
m_hbRepeaterHandler(NULL),
m_dummyRepeaterHandler(NULL),
m_dextraPool(NULL),
m_dplusPool(NULL),
m_dcsPool(NULL),
m_g2HandlerPool(NULL),
m_aprsWriter(NULL),
m_irc(NULL),
m_icomRepeaterHandler(nullptr),
m_hbRepeaterHandler(nullptr),
m_dummyRepeaterHandler(nullptr),
m_dextraPool(nullptr),
m_dplusPool(nullptr),
m_dcsPool(nullptr),
m_g2HandlerPool(nullptr),
m_outgoingAprsHandler(nullptr),
m_incomingAprsHandler(nullptr),
m_irc(nullptr),
m_cache(),
m_language(TL_ENGLISH_UK),
m_dextraEnabled(true),
@ -110,9 +111,9 @@ m_status4(),
m_status5(),
m_latitude(0.0),
m_longitude(0.0),
m_whiteList(NULL),
m_blackList(NULL),
m_restrictList(NULL)
m_whiteList(nullptr),
m_blackList(nullptr),
m_restrictList(nullptr)
{
CHeaderData::initialise();
CG2Handler::initialise(MAX_ROUTES);
@ -250,7 +251,7 @@ void* CDStarGatewayThread::Entry()
CRepeaterHandler::setDPlusEnabled(m_dplusEnabled);
CRepeaterHandler::setDCSEnabled(m_dcsEnabled);
CRepeaterHandler::setHeaderLogger(headerLogger);
CRepeaterHandler::setAPRSWriter(m_aprsWriter);
CRepeaterHandler::setAPRSHandlers(m_outgoingAprsHandler, m_incomingAprsHandler);
CRepeaterHandler::setInfoEnabled(m_infoEnabled);
CRepeaterHandler::setEchoEnabled(m_echoEnabled);
CRepeaterHandler::setDTMFEnabled(m_dtmfEnabled);
@ -377,8 +378,8 @@ void* CDStarGatewayThread::Entry()
m_statusFileTimer.start();
}
if (m_aprsWriter != NULL)
m_aprsWriter->clock(ms);
if (m_outgoingAprsHandler != NULL)
m_outgoingAprsHandler->clock(ms);
if (m_logEnabled) {
m_statusTimer1.clock(ms);
@ -469,9 +470,9 @@ void* CDStarGatewayThread::Entry()
delete m_remote;
}
if(m_aprsWriter != nullptr) {
m_aprsWriter->close();
delete m_aprsWriter;
if(m_outgoingAprsHandler != nullptr) {
m_outgoingAprsHandler->close();
delete m_outgoingAprsHandler;
}
if (headerLogger != NULL) {
@ -636,9 +637,10 @@ void CDStarGatewayThread::setLog(bool enabled)
m_logEnabled = enabled;
}
void CDStarGatewayThread::setAPRSWriter(CAPRSHandler* writer)
void CDStarGatewayThread::setAPRSWriters(CAPRSHandler* outgoingWriter, CAPRSHandler* incomingWriter)
{
m_aprsWriter = writer;
m_outgoingAprsHandler = outgoingWriter;
m_incomingAprsHandler = incomingWriter;
}
void CDStarGatewayThread::setInfoEnabled(bool enabled)
@ -1244,8 +1246,8 @@ void CDStarGatewayThread::writeStatus()
CDStarGatewayStatusData* CDStarGatewayThread::getStatus() const
{
bool aprsStatus = false;
if (m_aprsWriter != NULL)
aprsStatus = m_aprsWriter->isConnected();
if (m_outgoingAprsHandler != NULL)
aprsStatus = m_outgoingAprsHandler->isConnected();
CDStarGatewayStatusData* status = new CDStarGatewayStatusData(m_lastStatus, aprsStatus);

@ -66,7 +66,7 @@ public:
virtual void setCCS(bool enabled, const std::string& host);
#endif
virtual void setLog(bool enabled);
virtual void setAPRSWriter(CAPRSHandler* writer);
virtual void setAPRSWriters(CAPRSHandler* outgoingAprsWriter, CAPRSHandler* incomingAPRSHandler);
virtual void setInfoEnabled(bool enabled);
virtual void setEchoEnabled(bool enabled);
virtual void setDTMFEnabled(bool enabled);
@ -100,7 +100,8 @@ private:
CDPlusProtocolHandlerPool* m_dplusPool;
CDCSProtocolHandlerPool* m_dcsPool;
CG2ProtocolHandlerPool* m_g2HandlerPool;
CAPRSHandler* m_aprsWriter;
CAPRSHandler* m_outgoingAprsHandler;
CAPRSHandler* m_incomingAprsHandler;
CIRCDDB* m_irc;
CCacheManager m_cache;
TEXT_LANG m_language;

@ -1,3 +1,4 @@
[![F4FXL](https://circleci.com/gh/F4FXL/DStarGateway.svg?style=svg)](https://app.circleci.com/pipelines/github/F4FXL/DStarGateway?filter=all)
- [1. Introduction](#1-introduction)
- [2. Current State](#2-current-state)
- [2.1. Code sanity](#21-code-sanity)
@ -144,9 +145,10 @@ The testing framwework used is Google Test.
# 5. Version History
## 5.1. Version 0.7
- [**Improvement**] Add/Fix DPRS Object support([#28](https://github.com/F4FXL/DStarGateway/issues/22))
- [**Improvement**] Add/Fix DPRS Object support([#28](https://github.com/F4FXL/DStarGateway/issues/28))
- [**Improvement**] Log incoming DPRS frames so they can be used in e.g. dashboards([#29](https://github.com/F4FXL/DStarGateway/issues/29))
## 5.2. Version 0.6
- [**Improvement**] Add DRats Support ([#22](https://github.com/F4FXL/DStarGateway/issues/22))
- [**Improvement**] Add DRats Support ([#24](https://github.com/F4FXL/DStarGateway/issues/24))
- [**Improvement**] Add call sign lists ([#22](https://github.com/F4FXL/DStarGateway/issues/22))
- [**Improvement**] Add a way to override Slow Data in VoiceTransmit ([#23](https://github.com/F4FXL/DStarGateway/issues/23))
- [**Improvement**] Add time server

Loading…
Cancel
Save

Powered by TurnKey Linux.