diff --git a/YSFGateway/FCSNetwork.cpp b/YSFGateway/FCSNetwork.cpp index 4923205..7746509 100644 --- a/YSFGateway/FCSNetwork.cpp +++ b/YSFGateway/FCSNetwork.cpp @@ -38,7 +38,9 @@ m_ping(NULL), m_info(NULL), m_reflector(), m_buffer(1000U, "FCS Network Buffer"), -m_n(0U) +m_n(0U), +m_pingTimer(1000U, 5U), +m_state(FCS_UNLINKED) { m_info = new unsigned char[100U]; ::sprintf((char*)m_info, "%9u%9u%-6.6s%-12.12s%7u", rxFrequency, txFrequency, locator.c_str(), FCS_VERSION, id); @@ -71,6 +73,10 @@ void CFCSNetwork::clearDestination() { m_address.s_addr = INADDR_NONE; m_port = 0U; + + m_pingTimer.stop(); + + m_state = FCS_UNLINKED; } void CFCSNetwork::write(const unsigned char* data) @@ -80,6 +86,9 @@ void CFCSNetwork::write(const unsigned char* data) if (m_port == 0U) return; + if (m_state != FCS_LINKED) + return; + unsigned char buffer[130U]; ::memset(buffer + 0U, ' ', 130U); ::memcpy(buffer + 0U, data + 35U, 120U); @@ -114,6 +123,10 @@ void CFCSNetwork::writeLink(const std::string& reflector) ::memcpy(m_ping + 10U, m_reflector.c_str(), 8U); writePing(); + + m_pingTimer.start(); + + m_state = FCS_LINKING; } void CFCSNetwork::writeUnlink(unsigned int count) @@ -123,6 +136,10 @@ void CFCSNetwork::writeUnlink(unsigned int count) for (unsigned int i = 0U; i < count; i++) m_socket.write((unsigned char*)"CLOSE ", 11U, m_address, m_port); + + m_pingTimer.stop(); + + m_state = FCS_UNLINKED; } void CFCSNetwork::clock(unsigned int ms) @@ -138,17 +155,33 @@ void CFCSNetwork::clock(unsigned int ms) if (m_port == 0U) return; + m_pingTimer.clock(ms); + if (m_pingTimer.isRunning() && m_pingTimer.hasExpired()) { + writePing(); + m_pingTimer.start(); + } + if (address.s_addr != m_address.s_addr || port != m_port) return; if (m_debug) CUtils::dump(1U, "FCS Network Data Received", buffer, length); - if (length == 7 || length == 10) + if (length == 7) { + m_state = FCS_LINKED; writeInfo(); + } + + if (length == 10 && m_state == FCS_LINKING) { + m_state = FCS_LINKED; + writeInfo(); + } - if (length == 130) - m_buffer.addData(buffer, 130U); + if (length == 10 || length == 130) { + unsigned char len = length; + m_buffer.addData(&len, 1U); + m_buffer.addData(buffer, len); + } } unsigned int CFCSNetwork::read(unsigned char* data) @@ -158,8 +191,17 @@ unsigned int CFCSNetwork::read(unsigned char* data) if (m_buffer.isEmpty()) return 0U; + unsigned char len = 0U; + m_buffer.getData(&len, 1U); + + // Pass pings up to the gateway to reset the lost timer. + if (len == 10U) { + m_buffer.getData(data, len); + return 10U; + } + unsigned char buffer[130U]; - m_buffer.getData(buffer, 130U); + m_buffer.getData(buffer, len); ::memcpy(data + 0U, "YSFDDB0SAT DB0SAT-RPTALL ", 35U); ::memcpy(data + 35U, buffer, 120U); diff --git a/YSFGateway/FCSNetwork.h b/YSFGateway/FCSNetwork.h index a5ce229..de6b1c1 100644 --- a/YSFGateway/FCSNetwork.h +++ b/YSFGateway/FCSNetwork.h @@ -22,11 +22,18 @@ #include "YSFDefines.h" #include "UDPSocket.h" #include "RingBuffer.h" +#include "Timer.h" #include #include #include +enum FCS_STATE { + FCS_UNLINKED, + FCS_LINKING, + FCS_LINKED +}; + class CFCSNetwork { public: CFCSNetwork(unsigned int port, const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, const std::string& locator, unsigned int id, bool debug); @@ -59,6 +66,8 @@ private: CRingBuffer m_buffer; std::map m_addresses; unsigned char m_n; + CTimer m_pingTimer; + FCS_STATE m_state; void writeInfo(); void writePing(); diff --git a/YSFGateway/YSFGateway.cpp b/YSFGateway/YSFGateway.cpp index b1351f3..d1444d1 100644 --- a/YSFGateway/YSFGateway.cpp +++ b/YSFGateway/YSFGateway.cpp @@ -223,37 +223,8 @@ int CYSFGateway::run() m_inactivityTimer.setTimeout(m_conf.getNetworkInactivityTimeout() * 60U); bool revert = m_conf.getNetworkRevert(); - std::string startup = m_conf.getNetworkStartup(); - - if (!startup.empty()) { - if (startup.substr(0U, 3U) == "FCS" && m_fcsNetwork != NULL) { - LogMessage("Automatic connection to %s", startup.c_str()); - - m_fcsNetwork->writeLink(startup); - - if (!revert) - m_inactivityTimer.start(); - - m_lostTimer.start(); - - m_linkType = LINK_FCS; - } else if (m_ysfNetwork != NULL) { - CYSFReflector* reflector = m_wiresX->getReflector(startup); - if (reflector != NULL) { - LogMessage("Automatic connection to %5.5s - \"%s\"", reflector->m_id.c_str(), reflector->m_name.c_str()); - - m_ysfNetwork->setDestination(reflector->m_address, reflector->m_port); - m_ysfNetwork->writePoll(3U); - - if (!revert) - m_inactivityTimer.start(); - - m_lostTimer.start(); - m_linkType = LINK_YSF; - } - } - } + startupLinking(); CStopWatch stopWatch; stopWatch.start(); @@ -347,50 +318,38 @@ int CYSFGateway::run() m_inactivityTimer.clock(ms); if (m_inactivityTimer.isRunning() && m_inactivityTimer.hasExpired()) { if (m_linkType == LINK_YSF) { - CYSFReflector* reflector = NULL; - if (revert && !startup.empty()) - reflector = m_wiresX->getReflector(startup); - - if (reflector != NULL) { - LogMessage("Reverting connection to %5.5s - \"%s\"", reflector->m_id.c_str(), reflector->m_name.c_str()); - - m_wiresX->processConnect(reflector); - - m_ysfNetwork->writeUnlink(3U); - - m_ysfNetwork->setDestination(reflector->m_address, reflector->m_port); - m_ysfNetwork->writePoll(3U); - - m_lostTimer.start(); - } else { - LogMessage("Disconnecting due to inactivity"); - - m_wiresX->processDisconnect(); - - m_ysfNetwork->writeUnlink(3U); - m_ysfNetwork->clearDestination(); - - m_lostTimer.stop(); + LogMessage("Disconnecting due to inactivity"); + m_wiresX->processDisconnect(); + m_ysfNetwork->writeUnlink(3U); + m_ysfNetwork->clearDestination(); + } - m_linkType = LINK_NONE; - } + if (m_linkType == LINK_FCS) { + LogMessage("Disconnecting due to inactivity"); + m_fcsNetwork->writeUnlink(3U); + m_fcsNetwork->clearDestination(); } m_inactivityTimer.stop(); + m_lostTimer.stop(); + + m_linkType = LINK_NONE; + + startupLinking(); } m_lostTimer.clock(ms); if (m_lostTimer.isRunning() && m_lostTimer.hasExpired()) { - LogWarning("Link has failed, polls lost"); - - if (m_linkType == LINK_YSF) + if (m_linkType == LINK_YSF) { + LogWarning("Link has failed, polls lost"); m_wiresX->processDisconnect(); + m_ysfNetwork->clearDestination(); + } - if (m_fcsNetwork != NULL) + if (m_fcsNetwork != NULL) { + LogWarning("Link has failed, polls lost"); m_fcsNetwork->clearDestination(); - - if (m_ysfNetwork != NULL) - m_ysfNetwork->clearDestination(); + } m_inactivityTimer.stop(); m_lostTimer.stop(); @@ -683,3 +642,39 @@ std::string CYSFGateway::calculateLocator() return locator; } + +void CYSFGateway::startupLinking() +{ + std::string startup = m_conf.getNetworkStartup(); + bool revert = m_conf.getNetworkRevert(); + + if (!startup.empty()) { + if (startup.substr(0U, 3U) == "FCS" && m_fcsNetwork != NULL) { + LogMessage("Automatic (re-)connection to %s", startup.c_str()); + + m_fcsNetwork->writeLink(startup); + + if (!revert) + m_inactivityTimer.start(); + + m_lostTimer.start(); + + m_linkType = LINK_FCS; + } else if (m_ysfNetwork != NULL) { + CYSFReflector* reflector = m_wiresX->getReflector(startup); + if (reflector != NULL) { + LogMessage("Automatic (re-)connection to %5.5s - \"%s\"", reflector->m_id.c_str(), reflector->m_name.c_str()); + + m_ysfNetwork->setDestination(reflector->m_address, reflector->m_port); + m_ysfNetwork->writePoll(3U); + + if (!revert) + m_inactivityTimer.start(); + + m_lostTimer.start(); + + m_linkType = LINK_YSF; + } + } + } +} diff --git a/YSFGateway/YSFGateway.h b/YSFGateway/YSFGateway.h index 1f553d0..5e71b75 100644 --- a/YSFGateway/YSFGateway.h +++ b/YSFGateway/YSFGateway.h @@ -57,6 +57,7 @@ private: CTimer m_inactivityTimer; CTimer m_lostTimer; + void startupLinking(); std::string calculateLocator(); void processWiresX(const unsigned char* buffer, unsigned char fi, unsigned char dt, unsigned char fn, unsigned char ft); void processDTMF(const unsigned char* buffer, unsigned char dt); diff --git a/YSFGateway/YSFGateway.ini b/YSFGateway/YSFGateway.ini index 3fd3432..16b41af 100644 --- a/YSFGateway/YSFGateway.ini +++ b/YSFGateway/YSFGateway.ini @@ -35,7 +35,7 @@ Password=9999 Description=APRS Description [Network] -# Startup= +# Startup=FCS00120 InactivityTimeout=10 # Revert=0 Debug=0