From 1c45e41db8014d6fe358eeb980014ed0b166b800 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Thu, 13 Oct 2016 19:04:36 +0100 Subject: [PATCH] Update the reflector to accomodate the new YSF protocol. --- YSFReflector/Network.cpp | 21 +++---- YSFReflector/YSFReflector.cpp | 105 +++++++++++++++++++++------------- YSFReflector/YSFReflector.h | 1 + 3 files changed, 74 insertions(+), 53 deletions(-) diff --git a/YSFReflector/Network.cpp b/YSFReflector/Network.cpp index e30f828..b1b1dff 100644 --- a/YSFReflector/Network.cpp +++ b/YSFReflector/Network.cpp @@ -115,19 +115,13 @@ void CNetwork::clock(unsigned int ms) return; } - // Invalid packet type? - if (::memcmp(buffer, "YSFD", 4U) != 0) - return; - - // Simulate a poll with the data - m_callsign = std::string((char*)(buffer + 4U), YSF_CALLSIGN_LENGTH); - m_address = address; - m_port = port; - 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::readData(unsigned char* data) @@ -137,9 +131,12 @@ unsigned int CNetwork::readData(unsigned char* data) if (m_buffer.isEmpty()) return 0U; - m_buffer.getData(data, 155U); + unsigned char len = 0U; + m_buffer.getData(&len, 1U); - return 155U; + m_buffer.getData(data, len); + + return len; } bool CNetwork::readPoll(std::string& callsign, in_addr& address, unsigned int& port) diff --git a/YSFReflector/YSFReflector.cpp b/YSFReflector/YSFReflector.cpp index bc9b74a..0a9859e 100644 --- a/YSFReflector/YSFReflector.cpp +++ b/YSFReflector/YSFReflector.cpp @@ -42,6 +42,7 @@ const char* DEFAULT_INI_FILE = "YSFReflector.ini"; const char* DEFAULT_INI_FILE = "/etc/YSFReflector.ini"; #endif +#include #include #include #include @@ -186,7 +187,7 @@ void CYSFReflector::run() for (;;) { unsigned char buffer[200U]; - // Refresh/add repeaters based on their polls/simulated polls + // Refresh/add repeaters based on their polls in_addr address; unsigned int port; std::string callsign; @@ -212,51 +213,63 @@ void CYSFReflector::run() unsigned int len = network.readData(buffer); if (len > 0U) { - if (!watchdogTimer.isRunning()) { - ::memcpy(tag, buffer + 4U, YSF_CALLSIGN_LENGTH); + if (::memcmp(buffer + 0U, "YSFU", 4U) == 0) { + std::string callsign = std::string((char*)(buffer + 4U), 10U); + CYSFRepeater* rpt = findRepeater(callsign); + if (rpt != NULL) { + LogMessage("Removing %s (unlinked)", callsign.c_str()); + std::vector::iterator it = std::find(m_repeaters.begin(), m_repeaters.end(), rpt); + if (it != m_repeaters.end()) + m_repeaters.erase(it); + network.setCount(m_repeaters.size()); + } + } else if (::memcmp(buffer + 0U, "YSFD", 4U) == 0) { + if (!watchdogTimer.isRunning()) { + ::memcpy(tag, buffer + 4U, YSF_CALLSIGN_LENGTH); - if (::memcmp(buffer + 14U, " ", YSF_CALLSIGN_LENGTH) != 0) - ::memcpy(src, buffer + 14U, YSF_CALLSIGN_LENGTH); - else - ::memcpy(src, "??????????", YSF_CALLSIGN_LENGTH); - - if (::memcmp(buffer + 24U, " ", YSF_CALLSIGN_LENGTH) != 0) - ::memcpy(dst, buffer + 24U, YSF_CALLSIGN_LENGTH); - else - ::memcpy(dst, "??????????", YSF_CALLSIGN_LENGTH); - - LogMessage("Received data from %10.10s to %10.10s at %10.10s", src, dst, buffer + 4U); - } else { - if (::memcmp(tag, buffer + 4U, YSF_CALLSIGN_LENGTH) == 0) { - bool changed = false; - - if (::memcmp(buffer + 14U, " ", YSF_CALLSIGN_LENGTH) != 0 && ::memcmp(src, "??????????", YSF_CALLSIGN_LENGTH) == 0) { + if (::memcmp(buffer + 14U, " ", YSF_CALLSIGN_LENGTH) != 0) ::memcpy(src, buffer + 14U, YSF_CALLSIGN_LENGTH); - changed = true; - } + else + ::memcpy(src, "??????????", YSF_CALLSIGN_LENGTH); - if (::memcmp(buffer + 24U, " ", YSF_CALLSIGN_LENGTH) != 0 && ::memcmp(dst, "??????????", YSF_CALLSIGN_LENGTH) == 0) { + if (::memcmp(buffer + 24U, " ", YSF_CALLSIGN_LENGTH) != 0) ::memcpy(dst, buffer + 24U, YSF_CALLSIGN_LENGTH); - changed = true; + else + ::memcpy(dst, "??????????", YSF_CALLSIGN_LENGTH); + + LogMessage("Received data from %10.10s to %10.10s at %10.10s", src, dst, buffer + 4U); + } else { + if (::memcmp(tag, buffer + 4U, YSF_CALLSIGN_LENGTH) == 0) { + bool changed = false; + + if (::memcmp(buffer + 14U, " ", YSF_CALLSIGN_LENGTH) != 0 && ::memcmp(src, "??????????", YSF_CALLSIGN_LENGTH) == 0) { + ::memcpy(src, buffer + 14U, YSF_CALLSIGN_LENGTH); + changed = true; + } + + if (::memcmp(buffer + 24U, " ", YSF_CALLSIGN_LENGTH) != 0 && ::memcmp(dst, "??????????", YSF_CALLSIGN_LENGTH) == 0) { + ::memcpy(dst, buffer + 24U, YSF_CALLSIGN_LENGTH); + changed = true; + } + + if (changed) + LogMessage("Received data from %10.10s to %10.10s at %10.10s", src, dst, buffer + 4U); + } + } + + // Only accept transmission from an already accepted repeater + if (::memcmp(tag, buffer + 4U, YSF_CALLSIGN_LENGTH) == 0) { + watchdogTimer.start(); + + for (std::vector::const_iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) { + if ((*it)->m_callsign != callsign) + network.writeData(buffer, (*it)->m_address, (*it)->m_port); } - if (changed) - LogMessage("Received data from %10.10s to %10.10s at %10.10s", src, dst, buffer + 4U); - } - } - - // Only accept transmission from an already accepted repeater - if (::memcmp(tag, buffer + 4U, YSF_CALLSIGN_LENGTH) == 0) { - watchdogTimer.start(); - - for (std::vector::const_iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) { - if ((*it)->m_callsign != callsign) - network.writeData(buffer, (*it)->m_address, (*it)->m_port); - } - - if ((buffer[34U] & 0x01U) == 0x01U) { - LogMessage("Received end of transmission"); - watchdogTimer.stop(); + if ((buffer[34U] & 0x01U) == 0x01U) { + LogMessage("Received end of transmission"); + watchdogTimer.stop(); + } } } } @@ -279,7 +292,7 @@ void CYSFReflector::run() for (std::vector::iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) { if ((*it)->m_timer.hasExpired()) { - LogMessage("Removing %s", (*it)->m_callsign.c_str()); + LogMessage("Removing %s (polls lost)", (*it)->m_callsign.c_str()); m_repeaters.erase(it); network.setCount(m_repeaters.size()); break; @@ -322,6 +335,16 @@ CYSFRepeater* CYSFReflector::findRepeater(const std::string& callsign, const in_ return NULL; } +CYSFRepeater* CYSFReflector::findRepeater(const std::string& callsign) const +{ + for (std::vector::const_iterator it = m_repeaters.begin(); it != m_repeaters.end(); ++it) { + if ((*it)->m_callsign == callsign) + return *it; + } + + return NULL; +} + void CYSFReflector::dumpRepeaters() const { if (m_repeaters.size() == 0U) { diff --git a/YSFReflector/YSFReflector.h b/YSFReflector/YSFReflector.h index 6013818..3dbe765 100644 --- a/YSFReflector/YSFReflector.h +++ b/YSFReflector/YSFReflector.h @@ -67,6 +67,7 @@ private: std::vector m_repeaters; CYSFRepeater* findRepeater(const std::string& callsign, const in_addr& address, unsigned int port) const; + CYSFRepeater* findRepeater(const std::string& callsign) const; void dumpRepeaters() const; };