1
0
Fork 0

Add a reconnection backoff timer for APRS reporting.

ycs232-kbc
Jonathan Naylor 5 years ago
parent f8121777cc
commit b058539a71

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2010-2014,2016,2017,2018 by Jonathan Naylor G4KLX * Copyright (C) 2010-2014,2016,2017,2018,2020 by Jonathan Naylor G4KLX
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -168,6 +168,8 @@ void CAPRSWriter::clock(unsigned int ms)
{ {
m_idTimer.clock(ms); m_idTimer.clock(ms);
m_thread->clock(ms);
if (m_socket != NULL) { if (m_socket != NULL) {
if (m_idTimer.hasExpired()) { if (m_idTimer.hasExpired()) {
pollGPS(); pollGPS();
@ -289,9 +291,9 @@ void CAPRSWriter::sendIdFrameMobile()
if (pLatitude == NULL || pLongitude == NULL || pAltitude == NULL) if (pLatitude == NULL || pLongitude == NULL || pAltitude == NULL)
return; return;
float rawLatitude = ::atof(pLatitude); float rawLatitude = float(::atof(pLatitude));
float rawLongitude = ::atof(pLongitude); float rawLongitude = float(::atof(pLongitude));
float rawAltitude = ::atof(pAltitude); float rawAltitude = float(::atof(pAltitude));
char desc[200U]; char desc[200U];
if (m_txFrequency != 0U) { if (m_txFrequency != 0U) {
@ -345,8 +347,8 @@ void CAPRSWriter::sendIdFrameMobile()
lon, (rawLongitude < 0.0F) ? 'W' : 'E'); lon, (rawLongitude < 0.0F) ? 'W' : 'E');
if (pBearing != NULL && pVelocity != NULL) { if (pBearing != NULL && pVelocity != NULL) {
float rawBearing = ::atof(pBearing); float rawBearing = float(::atof(pBearing));
float rawVelocity = ::atof(pVelocity); float rawVelocity = float(::atof(pVelocity));
::sprintf(output + ::strlen(output), "%03.0f/%03.0f", rawBearing, rawVelocity * 0.539957F); ::sprintf(output + ::strlen(output), "%03.0f/%03.0f", rawBearing, rawVelocity * 0.539957F);
} }

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2010-2014,2016 by Jonathan Naylor G4KLX * Copyright (C) 2010-2014,2016,2020 by Jonathan Naylor G4KLX
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -41,6 +41,8 @@ m_socket(address, port),
m_queue(20U, "APRS Queue"), m_queue(20U, "APRS Queue"),
m_exit(false), m_exit(false),
m_connected(false), m_connected(false),
m_reconnectTimer(1000U),
m_tries(1U),
m_APRSReadCallback(NULL), m_APRSReadCallback(NULL),
m_filter(), m_filter(),
m_clientName("YSFGateway") m_clientName("YSFGateway")
@ -63,6 +65,8 @@ m_socket(address, port),
m_queue(20U, "APRS Queue"), m_queue(20U, "APRS Queue"),
m_exit(false), m_exit(false),
m_connected(false), m_connected(false),
m_reconnectTimer(1000U),
m_tries(1U),
m_APRSReadCallback(NULL), m_APRSReadCallback(NULL),
m_filter(filter), m_filter(filter),
m_clientName(clientName) m_clientName(clientName)
@ -94,19 +98,28 @@ void CAPRSWriterThread::entry()
LogMessage("Starting the APRS Writer thread"); LogMessage("Starting the APRS Writer thread");
m_connected = connect(); m_connected = connect();
if (!m_connected) {
LogError("Connect attempt to the APRS server has failed");
startReconnectionTimer();
}
try { try {
while (!m_exit) { while (!m_exit) {
if (!m_connected) { if (!m_connected) {
m_connected = connect(); if (m_reconnectTimer.isRunning() && m_reconnectTimer.hasExpired()) {
m_reconnectTimer.stop();
if (!m_connected){ m_connected = connect();
LogError("Reconnect attempt to the APRS server has failed"); if (!m_connected) {
sleep(10000UL); // 10 secs LogError("Reconnect attempt to the APRS server has failed");
startReconnectionTimer();
}
} }
} }
if (m_connected) { if (m_connected) {
m_tries = 0U;
if (!m_queue.isEmpty()){ if (!m_queue.isEmpty()){
char* p = NULL; char* p = NULL;
m_queue.getData(&p, 1U); m_queue.getData(&p, 1U);
@ -115,11 +128,12 @@ void CAPRSWriterThread::entry()
::strcat(p, "\r\n"); ::strcat(p, "\r\n");
bool ret = m_socket.write((unsigned char*)p, ::strlen(p)); bool ret = m_socket.write((unsigned char*)p, (unsigned int)::strlen(p));
if (!ret) { if (!ret) {
m_connected = false; m_connected = false;
m_socket.close(); m_socket.close();
LogError("Connection to the APRS thread has failed"); LogError("Connection to the APRS thread has failed");
startReconnectionTimer();
} }
delete[] p; delete[] p;
@ -132,6 +146,7 @@ void CAPRSWriterThread::entry()
m_connected = false; m_connected = false;
m_socket.close(); m_socket.close();
LogError("Error when reading from the APRS server"); LogError("Error when reading from the APRS server");
startReconnectionTimer();
} }
if(length > 0 && line.at(0U) != '#'//check if we have something and if that something is an APRS frame if(length > 0 && line.at(0U) != '#'//check if we have something and if that something is an APRS frame
@ -176,7 +191,7 @@ void CAPRSWriterThread::write(const char* data)
if (!m_connected) if (!m_connected)
return; return;
unsigned int len = ::strlen(data); unsigned int len = (unsigned int)::strlen(data);
char* p = new char[len + 5U]; char* p = new char[len + 5U];
::strcpy(p, data); ::strcpy(p, data);
@ -196,6 +211,11 @@ void CAPRSWriterThread::stop()
wait(); wait();
} }
void CAPRSWriterThread::clock(unsigned int ms)
{
m_reconnectTimer.clock(ms);
}
bool CAPRSWriterThread::connect() bool CAPRSWriterThread::connect()
{ {
bool ret = m_socket.open(); bool ret = m_socket.open();
@ -246,3 +266,14 @@ bool CAPRSWriterThread::connect()
return true; return true;
} }
void CAPRSWriterThread::startReconnectionTimer()
{
// Clamp at a ten minutes reconnect time
m_tries++;
if (m_tries > 10U)
m_tries = 10U;
m_reconnectTimer.setTimeout(m_tries * 60U);
m_reconnectTimer.start();
}

@ -1,5 +1,5 @@
/* /*
* Copyright (C) 2010,2011,2012,2016 by Jonathan Naylor G4KLX * Copyright (C) 2010,2011,2012,2016,2020 by Jonathan Naylor G4KLX
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
@ -21,6 +21,7 @@
#include "TCPSocket.h" #include "TCPSocket.h"
#include "RingBuffer.h" #include "RingBuffer.h"
#include "Timer.h"
#include "Thread.h" #include "Thread.h"
#include <string> #include <string>
@ -45,6 +46,8 @@ public:
void setReadAPRSCallback(ReadAPRSFrameCallback cb); void setReadAPRSCallback(ReadAPRSFrameCallback cb);
void clock(unsigned int ms);
private: private:
std::string m_username; std::string m_username;
std::string m_password; std::string m_password;
@ -52,11 +55,14 @@ private:
CRingBuffer<char*> m_queue; CRingBuffer<char*> m_queue;
bool m_exit; bool m_exit;
bool m_connected; bool m_connected;
CTimer m_reconnectTimer;
unsigned int m_tries;
ReadAPRSFrameCallback m_APRSReadCallback; ReadAPRSFrameCallback m_APRSReadCallback;
std::string m_filter; std::string m_filter;
std::string m_clientName; std::string m_clientName;
bool connect(); bool connect();
void startReconnectionTimer();
}; };
#endif #endif

Loading…
Cancel
Save