From 77f55180afa643441a099498972eb4024fb77b8e Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 3 Mar 2020 15:31:59 +0000 Subject: [PATCH] Add a backoff timer for when the connection to aprs.fi fails. --- NXDNGateway/APRSWriter.cpp | 4 ++- NXDNGateway/APRSWriterThread.cpp | 45 +++++++++++++++++++++++++++----- NXDNGateway/APRSWriterThread.h | 8 +++++- 3 files changed, 48 insertions(+), 9 deletions(-) diff --git a/NXDNGateway/APRSWriter.cpp b/NXDNGateway/APRSWriter.cpp index 4c88902..e5eb58e 100644 --- a/NXDNGateway/APRSWriter.cpp +++ b/NXDNGateway/APRSWriter.cpp @@ -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 * it under the terms of the GNU General Public License as published by @@ -112,6 +112,8 @@ void CAPRSWriter::clock(unsigned int ms) { m_idTimer.clock(ms); + m_thread->clock(ms); + if (m_socket != NULL) { if (m_idTimer.hasExpired()) { pollGPS(); diff --git a/NXDNGateway/APRSWriterThread.cpp b/NXDNGateway/APRSWriterThread.cpp index 93e2e48..c388609 100644 --- a/NXDNGateway/APRSWriterThread.cpp +++ b/NXDNGateway/APRSWriterThread.cpp @@ -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 * 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_exit(false), m_connected(false), +m_reconnectTimer(1000U), +m_tries(1U), m_APRSReadCallback(NULL), m_filter(), m_clientName("YSFGateway") @@ -63,6 +65,8 @@ m_socket(address, port), m_queue(20U, "APRS Queue"), m_exit(false), m_connected(false), +m_reconnectTimer(1000U), +m_tries(1U), m_APRSReadCallback(NULL), m_filter(filter), m_clientName(clientName) @@ -94,19 +98,28 @@ void CAPRSWriterThread::entry() LogMessage("Starting the APRS Writer thread"); m_connected = connect(); + if (!m_connected) { + LogError("Connect attempt to the APRS server has failed"); + startReconnectionTimer(); + } try { while (!m_exit) { if (!m_connected) { - m_connected = connect(); + if (m_reconnectTimer.isRunning() && m_reconnectTimer.hasExpired()) { + m_reconnectTimer.stop(); - if (!m_connected){ - LogError("Reconnect attempt to the APRS server has failed"); - sleep(10000UL); // 10 secs + m_connected = connect(); + if (!m_connected) { + LogError("Reconnect attempt to the APRS server has failed"); + startReconnectionTimer(); + } } } if (m_connected) { + m_tries = 0U; + if (!m_queue.isEmpty()){ char* p = NULL; m_queue.getData(&p, 1U); @@ -115,11 +128,12 @@ void CAPRSWriterThread::entry() ::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) { m_connected = false; m_socket.close(); LogError("Connection to the APRS thread has failed"); + startReconnectionTimer(); } delete[] p; @@ -132,6 +146,7 @@ void CAPRSWriterThread::entry() m_connected = false; m_socket.close(); 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 @@ -176,7 +191,7 @@ void CAPRSWriterThread::write(const char* data) if (!m_connected) return; - unsigned int len = ::strlen(data); + unsigned int len = (unsigned int)::strlen(data); char* p = new char[len + 5U]; ::strcpy(p, data); @@ -196,6 +211,11 @@ void CAPRSWriterThread::stop() wait(); } +void CAPRSWriterThread::clock(unsigned int ms) +{ + m_reconnectTimer.clock(ms); +} + bool CAPRSWriterThread::connect() { bool ret = m_socket.open(); @@ -246,3 +266,14 @@ bool CAPRSWriterThread::connect() 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(); +} diff --git a/NXDNGateway/APRSWriterThread.h b/NXDNGateway/APRSWriterThread.h index 42bfd67..c86c23a 100644 --- a/NXDNGateway/APRSWriterThread.h +++ b/NXDNGateway/APRSWriterThread.h @@ -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 * it under the terms of the GNU General Public License as published by @@ -21,6 +21,7 @@ #include "TCPSocket.h" #include "RingBuffer.h" +#include "Timer.h" #include "Thread.h" #include @@ -45,6 +46,8 @@ public: void setReadAPRSCallback(ReadAPRSFrameCallback cb); + void clock(unsigned int ms); + private: std::string m_username; std::string m_password; @@ -52,11 +55,14 @@ private: CRingBuffer m_queue; bool m_exit; bool m_connected; + CTimer m_reconnectTimer; + unsigned int m_tries; ReadAPRSFrameCallback m_APRSReadCallback; std::string m_filter; std::string m_clientName; bool connect(); + void startReconnectionTimer(); }; #endif