diff --git a/YSFGateway/Network.cpp b/YSFGateway/Network.cpp index 3913d6f..57432d7 100644 --- a/YSFGateway/Network.cpp +++ b/YSFGateway/Network.cpp @@ -33,19 +33,24 @@ m_debug(debug), m_address(), m_port(0U), m_poll(NULL), -m_buffer(1000U, "YSF Network Buffer"), -m_timer(1000U, 5U) +m_unlink(NULL), +m_buffer(1000U, "YSF Network Buffer") { assert(port > 0U); m_poll = new unsigned char[14U]; ::memcpy(m_poll + 0U, "YSFP", 4U); + m_unlink = new unsigned char[14U]; + ::memcpy(m_unlink + 0U, "YSFU", 4U); + std::string node = callsign; node.resize(YSF_CALLSIGN_LENGTH, ' '); - for (unsigned int i = 0U; i < YSF_CALLSIGN_LENGTH; i++) + for (unsigned int i = 0U; i < YSF_CALLSIGN_LENGTH; i++) { m_poll[i + 4U] = node.at(i); + m_unlink[i + 4U] = node.at(i); + } } CNetwork::CNetwork(unsigned int port, const std::string& callsign, bool debug) : @@ -54,19 +59,24 @@ m_debug(debug), m_address(), m_port(0U), m_poll(NULL), -m_buffer(1000U, "YSF Network Buffer"), -m_timer(1000U, 5U) +m_unlink(NULL), +m_buffer(1000U, "YSF Network Buffer") { assert(port > 0U); m_poll = new unsigned char[14U]; ::memcpy(m_poll + 0U, "YSFP", 4U); + m_unlink = new unsigned char[14U]; + ::memcpy(m_unlink + 0U, "YSFU", 4U); + std::string node = callsign; node.resize(YSF_CALLSIGN_LENGTH, ' '); - for (unsigned int i = 0U; i < YSF_CALLSIGN_LENGTH; i++) - m_poll[i + 4U] = node.at(i); + for (unsigned int i = 0U; i < YSF_CALLSIGN_LENGTH; i++) { + m_poll[i + 4U] = node.at(i); + m_unlink[i + 4U] = node.at(i); + } } CNetwork::~CNetwork() @@ -85,16 +95,12 @@ void CNetwork::setDestination(const in_addr& address, unsigned int port) { m_address = address; m_port = port; - - m_timer.start(); } void CNetwork::setDestination() { m_address.s_addr = INADDR_NONE; m_port = 0U; - - m_timer.stop(); } bool CNetwork::write(const unsigned char* data) @@ -118,14 +124,16 @@ bool CNetwork::writePoll() return m_socket.write(m_poll, 14U, m_address, m_port); } -void CNetwork::clock(unsigned int ms) +bool CNetwork::writeUnlink() { - m_timer.clock(ms); - if (m_timer.isRunning() && m_timer.hasExpired()) { - writePoll(); - m_timer.start(); - } + if (m_port == 0U) + return true; + return m_socket.write(m_unlink, 14U, m_address, m_port); +} + +void CNetwork::clock(unsigned int ms) +{ unsigned char buffer[BUFFER_LENGTH]; in_addr address; @@ -137,20 +145,13 @@ void CNetwork::clock(unsigned int ms) if (address.s_addr != m_address.s_addr || port != m_port) return; - // Handle incoming polls - if (::memcmp(buffer, "YSFP", 4U) == 0) { - // How do we handle a loss of polls? - return; - } - - // Invalid packet type? - if (::memcmp(buffer, "YSFD", 4U) != 0) - return; - if (m_debug) CUtils::dump(1U, "YSF Network Data Received", buffer, length); - m_buffer.addData(buffer, 155U); + unsigned char len = length; + m_buffer.addData(&len, 1U); + + m_buffer.addData(buffer, length); } unsigned int CNetwork::read(unsigned char* data) @@ -160,9 +161,12 @@ unsigned int CNetwork::read(unsigned char* data) if (m_buffer.isEmpty()) return 0U; - m_buffer.getData(data, 155U); + unsigned char len = 0U; + m_buffer.getData(&len, 1U); + + m_buffer.getData(data, len); - return 155U; + return len; } void CNetwork::close() diff --git a/YSFGateway/Network.h b/YSFGateway/Network.h index fc3fd96..e5c90be 100644 --- a/YSFGateway/Network.h +++ b/YSFGateway/Network.h @@ -22,7 +22,6 @@ #include "YSFDefines.h" #include "UDPSocket.h" #include "RingBuffer.h" -#include "Timer.h" #include #include @@ -40,6 +39,9 @@ public: bool write(const unsigned char* data); + bool writePoll(); + bool writeUnlink(); + unsigned int read(unsigned char* data); void clock(unsigned int ms); @@ -52,10 +54,8 @@ private: in_addr m_address; unsigned int m_port; unsigned char* m_poll; + unsigned char* m_unlink; CRingBuffer m_buffer; - CTimer m_timer; - - bool writePoll(); }; #endif diff --git a/YSFGateway/YSFGateway.cpp b/YSFGateway/YSFGateway.cpp index d2549fd..03fcc09 100644 --- a/YSFGateway/YSFGateway.cpp +++ b/YSFGateway/YSFGateway.cpp @@ -81,9 +81,7 @@ m_gps(NULL), m_wiresX(NULL), m_netNetwork(NULL), m_linked(false), -m_exclude(false), -m_startupTimer(1000U, 30U), -m_startup() +m_exclude(false) { } @@ -194,6 +192,10 @@ int CYSFGateway::run() return 1; } + CTimer watchdogTimer(1000U, 0U, 500U); + CTimer lostTimer(1000U, 120U); + CTimer pollTimer(1000U, 5U); + bool networkEnabled = m_conf.getNetworkEnabled(); if (networkEnabled) { std::string fileName = m_conf.getNetworkHosts(); @@ -215,9 +217,20 @@ int CYSFGateway::run() m_wiresX->start(); - m_startup = m_conf.getNetworkStartup(); - if (!m_startup.empty()) - m_startupTimer.start(); + std::string startup = m_conf.getNetworkStartup(); + if (!startup.empty()) { + CYSFReflector* reflector = m_wiresX->getReflector(startup); + if (reflector != NULL) { + LogMessage("Automatic connection to %5.5s", reflector->m_id.c_str()); + m_netNetwork->setDestination(reflector->m_address, reflector->m_port); + m_netNetwork->writePoll(); + m_netNetwork->writePoll(); + m_netNetwork->writePoll(); + lostTimer.start(); + pollTimer.start(); + m_linked = true; + } + } } CStopWatch stopWatch; @@ -227,8 +240,6 @@ int CYSFGateway::run() createGPS(); - CTimer watchdogTimer(1000U, 0U, 500U); - for (;;) { unsigned char buffer[200U]; @@ -253,14 +264,22 @@ int CYSFGateway::run() CYSFReflector* reflector = m_wiresX->getReflector(); LogMessage("Connect to %5.5s has been requested by %10.10s", reflector->m_id.c_str(), buffer + 14U); m_netNetwork->setDestination(reflector->m_address, reflector->m_port); - m_startupTimer.stop(); + m_netNetwork->writePoll(); + m_netNetwork->writePoll(); + m_netNetwork->writePoll(); + lostTimer.start(); + pollTimer.start(); m_linked = true; } break; case WXS_DISCONNECT: LogMessage("Disconnect has been requested by %10.10s", buffer + 14U); + m_netNetwork->writeUnlink(); + m_netNetwork->writeUnlink(); + m_netNetwork->writeUnlink(); m_netNetwork->setDestination(); - m_startupTimer.stop(); + lostTimer.stop(); + pollTimer.stop(); m_linked = false; break; default: @@ -284,8 +303,13 @@ int CYSFGateway::run() } while (m_netNetwork->read(buffer) > 0U) { - if (networkEnabled && m_linked) - rptNetwork.write(buffer); + if (networkEnabled && m_linked) { + // Only pass through YSF data packets + if (::memcmp(buffer + 0U, "YSFD", 4U) == 0) + rptNetwork.write(buffer); + + lostTimer.start(); + } } unsigned int ms = stopWatch.elapsed(); @@ -298,6 +322,21 @@ int CYSFGateway::run() if (m_wiresX != NULL) m_wiresX->clock(ms); + lostTimer.clock(ms); + if (lostTimer.isRunning() && lostTimer.hasExpired()) { + LogWarning("Link has failed, polls lost"); + m_netNetwork->setDestination(); + lostTimer.stop(); + pollTimer.stop(); + m_linked = false; + } + + pollTimer.clock(ms); + if (pollTimer.isRunning() && pollTimer.hasExpired()) { + m_netNetwork->writePoll(); + pollTimer.start(); + } + watchdogTimer.clock(ms); if (watchdogTimer.isRunning() && watchdogTimer.hasExpired()) { LogMessage("Network watchdog has expired"); @@ -307,17 +346,6 @@ int CYSFGateway::run() m_exclude = false; } - m_startupTimer.clock(ms); - if (m_startupTimer.isRunning() && m_startupTimer.hasExpired()) { - CYSFReflector* reflector = m_wiresX->getReflector(m_startup); - if (reflector != NULL) { - LogMessage("Automatic connection to %5.5s", reflector->m_id.c_str()); - m_netNetwork->setDestination(reflector->m_address, reflector->m_port); - m_startupTimer.stop(); - m_linked = true; - } - } - if (ms < 5U) CThread::sleep(5U); } diff --git a/YSFGateway/YSFGateway.h b/YSFGateway/YSFGateway.h index 24dc615..9c3f413 100644 --- a/YSFGateway/YSFGateway.h +++ b/YSFGateway/YSFGateway.h @@ -43,8 +43,6 @@ private: CNetwork* m_netNetwork; bool m_linked; bool m_exclude; - CTimer m_startupTimer; - std::string m_startup; void createGPS(); };