From fd06781f93ab880b8ace326a5c8cbb50dd302300 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Tue, 22 Sep 2020 17:23:50 +0100 Subject: [PATCH] Split the YCS network handler off from the YSF protocol handler and code simplification. --- DGIdGateway/DGIdGateway.cpp | 3 +- DGIdGateway/DGIdGateway.vcxproj | 2 + DGIdGateway/DGIdGateway.vcxproj.filters | 6 + DGIdGateway/FCSNetwork.cpp | 25 ++- DGIdGateway/FCSNetwork.h | 1 - DGIdGateway/Makefile | 4 +- DGIdGateway/YCSNetwork.cpp | 254 ++++++++++++++++++++++++ DGIdGateway/YCSNetwork.h | 74 +++++++ DGIdGateway/YSFNetwork.cpp | 120 +---------- DGIdGateway/YSFNetwork.h | 6 - 10 files changed, 360 insertions(+), 135 deletions(-) create mode 100644 DGIdGateway/YCSNetwork.cpp create mode 100644 DGIdGateway/YCSNetwork.h diff --git a/DGIdGateway/DGIdGateway.cpp b/DGIdGateway/DGIdGateway.cpp index 4866ee9..f347a7a 100644 --- a/DGIdGateway/DGIdGateway.cpp +++ b/DGIdGateway/DGIdGateway.cpp @@ -21,6 +21,7 @@ #include "DGIdNetwork.h" #include "IMRSNetwork.h" #include "YSFNetwork.h" +#include "YCSNetwork.h" #include "FCSNetwork.h" #include "UDPSocket.h" #include "StopWatch.h" @@ -271,7 +272,7 @@ int CDGIdGateway::run() CYSFReflector* reflector = reflectors->findByName(name); if (reflector != NULL) { - dgIdNetwork[dgid] = new CYSFNetwork(local, reflector->m_name, reflector->m_addr, reflector->m_addrLen, m_callsign, rxFrequency, txFrequency, locator, description, id, (*it)->m_netDGId, debug); + dgIdNetwork[dgid] = new CYCSNetwork(local, reflector->m_name, reflector->m_addr, reflector->m_addrLen, m_callsign, rxFrequency, txFrequency, locator, description, id, (*it)->m_netDGId, debug); dgIdNetwork[dgid]->m_modes = DT_VD_MODE1 | DT_VD_MODE2 | DT_VOICE_FR_MODE | DT_DATA_FR_MODE; dgIdNetwork[dgid]->m_static = statc; dgIdNetwork[dgid]->m_rfHangTime = rfHangTime; diff --git a/DGIdGateway/DGIdGateway.vcxproj b/DGIdGateway/DGIdGateway.vcxproj index 1864ae7..5c5a89c 100644 --- a/DGIdGateway/DGIdGateway.vcxproj +++ b/DGIdGateway/DGIdGateway.vcxproj @@ -159,6 +159,7 @@ + @@ -184,6 +185,7 @@ + diff --git a/DGIdGateway/DGIdGateway.vcxproj.filters b/DGIdGateway/DGIdGateway.vcxproj.filters index 8c55194..b1929f0 100644 --- a/DGIdGateway/DGIdGateway.vcxproj.filters +++ b/DGIdGateway/DGIdGateway.vcxproj.filters @@ -74,6 +74,9 @@ Source Files + + Source Files + @@ -148,5 +151,8 @@ Header Files + + Header Files + \ No newline at end of file diff --git a/DGIdGateway/FCSNetwork.cpp b/DGIdGateway/FCSNetwork.cpp index 0baa477..09a29a7 100644 --- a/DGIdGateway/FCSNetwork.cpp +++ b/DGIdGateway/FCSNetwork.cpp @@ -188,14 +188,24 @@ void CFCSNetwork::clock(unsigned int ms) if (length == 7) { if (m_state == DS_LINKING) LogMessage("Linked to %s", m_print.c_str()); + m_state = DS_LINKED; - writeInfo(); + + if (m_debug) + CUtils::dump(1U, "FCS Network Data Sent", m_info, 100U); + + m_socket.write(m_info, 100U, m_addr, m_addrLen); } if (length == 10 && m_state == DS_LINKING) { LogMessage("Linked to %s", m_print.c_str()); + m_state = DS_LINKED; - writeInfo(); + + if (m_debug) + CUtils::dump(1U, "FCS Network Data Sent", m_info, 100U); + + m_socket.write(m_info, 100U, m_addr, m_addrLen); } if (length == 7 || length == 10 || length == 130) { @@ -252,17 +262,6 @@ void CFCSNetwork::close() m_state = DS_NOTOPEN; } -void CFCSNetwork::writeInfo() -{ - if (m_state != DS_LINKED) - return; - - if (m_debug) - CUtils::dump(1U, "FCS Network Data Sent", m_info, 100U); - - m_socket.write(m_info, 100U, m_addr, m_addrLen); -} - void CFCSNetwork::writePing() { if (m_state != DS_LINKING && m_state != DS_LINKED) diff --git a/DGIdGateway/FCSNetwork.h b/DGIdGateway/FCSNetwork.h index 5c22635..7913939 100644 --- a/DGIdGateway/FCSNetwork.h +++ b/DGIdGateway/FCSNetwork.h @@ -68,7 +68,6 @@ private: CTimer m_resetTimer; DGID_STATUS m_state; - void writeInfo(); void writePing(); }; diff --git a/DGIdGateway/Makefile b/DGIdGateway/Makefile index 78db036..242d096 100644 --- a/DGIdGateway/Makefile +++ b/DGIdGateway/Makefile @@ -12,8 +12,8 @@ LIBS = -lm -lpthread LDFLAGS = -g OBJECTS = APRSWriter.o Conf.o CRC.o DGIdGateway.o DGIdNetwork.o FCSNetwork.o Golay24128.o GPS.o IMRSNetwork.o \ - Log.o StopWatch.o Sync.o Thread.o Timer.o UDPSocket.o Utils.o YSFConvolution.o YSFFICH.o YSFNetwork.o \ - YSFPayload.o YSFReflectors.o + Log.o StopWatch.o Sync.o Thread.o Timer.o UDPSocket.o Utils.o YCSNetwork.o YSFConvolution.o YSFFICH.o \ + YSFNetwork.o YSFPayload.o YSFReflectors.o all: DGIdGateway diff --git a/DGIdGateway/YCSNetwork.cpp b/DGIdGateway/YCSNetwork.cpp new file mode 100644 index 0000000..801c487 --- /dev/null +++ b/DGIdGateway/YCSNetwork.cpp @@ -0,0 +1,254 @@ +/* + * Copyright (C) 2009-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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "YSFDefines.h" +#include "YCSNetwork.h" +#include "Utils.h" +#include "Log.h" + +#include +#include +#include + +const unsigned int BUFFER_LENGTH = 200U; + +CYCSNetwork::CYCSNetwork(unsigned int localPort, const std::string& name, const sockaddr_storage& addr, unsigned int addrLen, const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, const std::string& locator, const std::string& description, unsigned int id, unsigned int dgId, bool debug) : +m_socket(localPort), +m_debug(debug), +m_addr(addr), +m_addrLen(addrLen), +m_poll(NULL), +m_options(NULL), +m_info(NULL), +m_unlink(NULL), +m_buffer(1000U, "YCS Network Buffer"), +m_pollTimer(1000U, 5U), +m_name(name), +m_state(DS_NOTOPEN), +m_dgId(dgId) +{ + m_poll = new unsigned char[14U]; + ::memcpy(m_poll + 0U, "YSFP", 4U); + + m_unlink = new unsigned char[14U]; + ::memcpy(m_unlink + 0U, "YSFU", 4U); + + m_options = new unsigned char[50U]; + ::memcpy(m_options + 0U, "YSFO", 4U); + + m_info = new unsigned char[80U]; + ::memcpy(m_info + 0U, "YSFI", 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); + m_unlink[i + 4U] = node.at(i); + m_options[i + 4U] = node.at(i); + m_info[i + 4U] = node.at(i); + } + + char text[101U]; + ::sprintf(text, "%u ", dgId); + + for (unsigned int i = 0U; i < (50U - 4U - YSF_CALLSIGN_LENGTH); i++) + m_options[i + 4U + YSF_CALLSIGN_LENGTH] = text[i]; + + std::string desc = description; + desc.resize(20U, ' '); + + sprintf(text, "%9u%9u%.6s%sMMDVM %07u ", rxFrequency, txFrequency, locator.c_str(), desc.c_str(), id); + for (unsigned int i = 0U; i < (80U - 4U - YSF_CALLSIGN_LENGTH); i++) + m_info[i + 4U + YSF_CALLSIGN_LENGTH] = text[i]; +} + +CYCSNetwork::~CYCSNetwork() +{ + delete[] m_poll; + delete[] m_unlink; + delete[] m_options; + delete[] m_info; +} + +std::string CYCSNetwork::getDesc(unsigned int dgId) +{ + return "YCS: " + m_name; +} + +unsigned int CYCSNetwork::getDGId() +{ + return m_dgId; +} + +bool CYCSNetwork::open() +{ + if (m_addrLen == 0U) { + LogError("Unable to resolve the address of the YCS network"); + m_state = DS_NOTOPEN; + return false; + } + + LogMessage("Opening YCS network connection"); + + bool ret = m_socket.open(m_addr); + if (!ret) { + m_state = DS_NOTOPEN; + return false; + } else { + m_state = DS_NOTLINKED; + return true; + } +} + +DGID_STATUS CYCSNetwork::getStatus() +{ + return m_state; +} + +void CYCSNetwork::write(unsigned int dgid, const unsigned char* data) +{ + assert(data != NULL); + + if (m_state != DS_LINKED) + return; + + if (m_debug) + CUtils::dump(1U, "YCS Network Data Sent", data, 155U); + + m_socket.write(data, 155U, m_addr, m_addrLen); +} + +void CYCSNetwork::link() +{ + if (m_state != DS_NOTLINKED) + return; + + m_state = DS_LINKING; + + writePoll(); +} + +void CYCSNetwork::writePoll() +{ + if (m_state != DS_LINKING && m_state != DS_LINKED) + return; + + m_pollTimer.start(); + + if (m_debug) + CUtils::dump(1U, "YCS Network Data Sent", m_poll, 14U); + + m_socket.write(m_poll, 14U, m_addr, m_addrLen); +} + +void CYCSNetwork::unlink() +{ + if (m_state != DS_LINKED) + return; + + m_pollTimer.stop(); + + if (m_debug) + CUtils::dump(1U, "YCS Network Data Sent", m_unlink, 14U); + + m_socket.write(m_unlink, 14U, m_addr, m_addrLen); + + LogMessage("Unlinked from %s", m_name.c_str()); + + m_state = DS_NOTLINKED; +} + +void CYCSNetwork::clock(unsigned int ms) +{ + if (m_state == DS_NOTOPEN) + return; + + m_pollTimer.clock(ms); + if (m_pollTimer.isRunning() && m_pollTimer.hasExpired()) + writePoll(); + + unsigned char buffer[BUFFER_LENGTH]; + sockaddr_storage addr; + unsigned int addrLen; + int length = m_socket.read(buffer, BUFFER_LENGTH, addr, addrLen); + if (length <= 0) + return; + + if (m_addrLen == 0U) + return; + + if (!CUDPSocket::match(addr, m_addr)) + return; + + if (m_debug) + CUtils::dump(1U, "YCS Network Data Received", buffer, length); + + // Throw away any options messages + if (::memcmp(buffer, "YSFO", 4U) == 0) + return; + + // Throw away any info messages + if (::memcmp(buffer, "YSFI", 4U) == 0) + return; + + if (::memcmp(buffer, "YSFP", 4U) == 0 && m_state == DS_LINKING) { + LogMessage("Linked to %s", m_name.c_str()); + + m_state = DS_LINKED; + + if (m_debug) + CUtils::dump(1U, "YCS Network Data Sent", m_options, 50U); + + m_socket.write(m_options, 50U, m_addr, m_addrLen); + + if (m_debug) + CUtils::dump(1U, "YCS Network Data Sent", m_info, 80U); + + m_socket.write(m_info, 80U, m_addr, m_addrLen); + } + + unsigned char len = length; + m_buffer.addData(&len, 1U); + + m_buffer.addData(buffer, length); +} + +unsigned int CYCSNetwork::read(unsigned int dgid, unsigned char* data) +{ + assert(data != NULL); + + if (m_buffer.isEmpty()) + return 0U; + + unsigned char len = 0U; + m_buffer.getData(&len, 1U); + + m_buffer.getData(data, len); + + return len; +} + +void CYCSNetwork::close() +{ + m_socket.close(); + + LogMessage("Closing YCS network connection"); + + m_state = DS_NOTOPEN; +} diff --git a/DGIdGateway/YCSNetwork.h b/DGIdGateway/YCSNetwork.h new file mode 100644 index 0000000..1007ee1 --- /dev/null +++ b/DGIdGateway/YCSNetwork.h @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2009-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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef YCSNetwork_H +#define YCSNetwork_H + +#include "DGIdNetwork.h" +#include "YSFDefines.h" +#include "UDPSocket.h" +#include "RingBuffer.h" +#include "Timer.h" + +#include +#include + +class CYCSNetwork : public CDGIdNetwork { +public: + CYCSNetwork(unsigned int localPort, const std::string& name, const sockaddr_storage& addr, unsigned int addrLen, const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, const std::string& locator, const std::string& description, unsigned int id, unsigned int dgId, bool debug); + virtual ~CYCSNetwork(); + + virtual std::string getDesc(unsigned int dgId); + + virtual unsigned int getDGId(); + + virtual bool open(); + + virtual DGID_STATUS getStatus(); + + virtual void link(); + + virtual void write(unsigned int dgId, const unsigned char* data); + + virtual unsigned int read(unsigned int dgId, unsigned char* data); + + virtual void clock(unsigned int ms); + + virtual void unlink(); + + virtual void close(); + +private: + CUDPSocket m_socket; + bool m_debug; + sockaddr_storage m_addr; + unsigned int m_addrLen; + unsigned char* m_poll; + unsigned char* m_options; + unsigned char* m_info; + unsigned char* m_unlink; + CRingBuffer m_buffer; + CTimer m_pollTimer; + std::string m_name; + DGID_STATUS m_state; + unsigned int m_dgId; + + void writePoll(); +}; + +#endif diff --git a/DGIdGateway/YSFNetwork.cpp b/DGIdGateway/YSFNetwork.cpp index 42c9e99..496fbf6 100644 --- a/DGIdGateway/YSFNetwork.cpp +++ b/DGIdGateway/YSFNetwork.cpp @@ -33,16 +33,11 @@ m_debug(debug), m_addr(addr), m_addrLen(addrLen), m_poll(NULL), -m_options(NULL), -m_info(NULL), m_unlink(NULL), m_buffer(1000U, "YSF Network Buffer"), m_pollTimer(1000U, 5U), m_name(name), -m_state(DS_NOTOPEN), -m_pollCount(0U), -m_ycs(false), -m_dgId(0U) +m_state(DS_NOTOPEN) { m_poll = new unsigned char[14U]; ::memcpy(m_poll + 0U, "YSFP", 4U); @@ -50,20 +45,12 @@ m_dgId(0U) m_unlink = new unsigned char[14U]; ::memcpy(m_unlink + 0U, "YSFU", 4U); - m_options = new unsigned char[50U]; - ::memcpy(m_options + 0U, "YSFO", 4U); - - m_info = new unsigned char[80U]; - ::memcpy(m_info + 0U, "YSFI", 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); m_unlink[i + 4U] = node.at(i); - m_options[i + 4U] = node.at(i); - m_info[i + 4U] = node.at(i); } } @@ -73,16 +60,11 @@ m_debug(debug), m_addr(addr), m_addrLen(addrLen), m_poll(NULL), -m_options(NULL), -m_info(NULL), m_unlink(NULL), m_buffer(1000U, "YSF Network Buffer"), m_pollTimer(1000U, 5U), m_name(name), -m_state(DS_NOTOPEN), -m_pollCount(0U), -m_ycs(false), -m_dgId(0U) +m_state(DS_NOTOPEN) { m_poll = new unsigned char[14U]; ::memcpy(m_poll + 0U, "YSFP", 4U); @@ -90,106 +72,40 @@ m_dgId(0U) m_unlink = new unsigned char[14U]; ::memcpy(m_unlink + 0U, "YSFU", 4U); - m_options = new unsigned char[50U]; - ::memcpy(m_options + 0U, "YSFO", 4U); - - m_info = new unsigned char[80U]; - ::memcpy(m_info + 0U, "YSFI", 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); m_unlink[i + 4U] = node.at(i); - m_options[i + 4U] = node.at(i); - m_info[i + 4U] = node.at(i); } } -CYSFNetwork::CYSFNetwork(unsigned int localPort, const std::string& name, const sockaddr_storage& addr, unsigned int addrLen, const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, const std::string& locator, const std::string& description, unsigned int id, unsigned int dgId, bool debug) : -m_socket(localPort), -m_debug(debug), -m_addr(addr), -m_addrLen(addrLen), -m_poll(NULL), -m_options(NULL), -m_info(NULL), -m_unlink(NULL), -m_buffer(1000U, "YCS Network Buffer"), -m_pollTimer(1000U, 5U), -m_name(name), -m_state(DS_NOTOPEN), -m_pollCount(0U), -m_ycs(true), -m_dgId(dgId) -{ - m_poll = new unsigned char[14U]; - ::memcpy(m_poll + 0U, "YSFP", 4U); - - m_unlink = new unsigned char[14U]; - ::memcpy(m_unlink + 0U, "YSFU", 4U); - - m_options = new unsigned char[50U]; - ::memcpy(m_options + 0U, "YSFO", 4U); - - m_info = new unsigned char[80U]; - ::memcpy(m_info + 0U, "YSFI", 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); - m_unlink[i + 4U] = node.at(i); - m_options[i + 4U] = node.at(i); - m_info[i + 4U] = node.at(i); - } - - char text[101U]; - ::sprintf(text, "%u ", dgId); - - for (unsigned int i = 0U; i < (50U - 4U - YSF_CALLSIGN_LENGTH); i++) - m_options[i + 4U + YSF_CALLSIGN_LENGTH] = text[i]; - - std::string desc = description; - desc.resize(20U, ' '); - - sprintf(text, "%9u%9u%.6s%sMMDVM %07u ", rxFrequency, txFrequency, locator.c_str(), desc.c_str(), id); - for (unsigned int i = 0U; i < (80U - 4U - YSF_CALLSIGN_LENGTH); i++) - m_info[i + 4U + YSF_CALLSIGN_LENGTH] = text[i]; -} - CYSFNetwork::~CYSFNetwork() { delete[] m_poll; delete[] m_unlink; - delete[] m_options; - delete[] m_info; } std::string CYSFNetwork::getDesc(unsigned int dgId) { - if (m_ycs) - return "YCS: " + m_name; - else - return "YSF: " + m_name; + return "YSF: " + m_name; } unsigned int CYSFNetwork::getDGId() { - return m_dgId; + return 0U; } bool CYSFNetwork::open() { if (m_addrLen == 0U) { - LogError("Unable to resolve the address of the YSF/YCS network"); + LogError("Unable to resolve the address of the YSF network"); m_state = DS_NOTOPEN; return false; } - LogMessage("Opening YSF/YCS network connection"); + LogMessage("Opening YSF network connection"); bool ret = m_socket.open(m_addr); if (!ret) { @@ -240,22 +156,6 @@ void CYSFNetwork::writePoll() CUtils::dump(1U, "YSF Network Data Sent", m_poll, 14U); m_socket.write(m_poll, 14U, m_addr, m_addrLen); - - if (m_ycs && m_state == DS_LINKED && m_pollCount == 0U) { - if (m_debug) - CUtils::dump(1U, "YSF Network Data Sent", m_options, 50U); - - m_socket.write(m_options, 50U, m_addr, m_addrLen); - - if (m_debug) - CUtils::dump(1U, "YSF Network Data Sent", m_info, 80U); - - m_socket.write(m_info, 80U, m_addr, m_addrLen); - } - - m_pollCount++; - if (m_pollCount == 100U) - m_pollCount = 0U; } void CYSFNetwork::unlink() @@ -314,11 +214,7 @@ void CYSFNetwork::clock(unsigned int ms) else LogMessage("Linked to %s", m_name.c_str()); - m_state = DS_LINKED; - m_pollCount = 0U; - - if (m_options != NULL) - m_socket.write(m_options, 50U, m_addr, m_addrLen); + m_state = DS_LINKED; } unsigned char len = length; @@ -346,7 +242,7 @@ void CYSFNetwork::close() { m_socket.close(); - LogMessage("Closing YSF/YCS network connection"); + LogMessage("Closing YSF network connection"); m_state = DS_NOTOPEN; } diff --git a/DGIdGateway/YSFNetwork.h b/DGIdGateway/YSFNetwork.h index d8ce3c7..e2ec175 100644 --- a/DGIdGateway/YSFNetwork.h +++ b/DGIdGateway/YSFNetwork.h @@ -31,7 +31,6 @@ class CYSFNetwork : public CDGIdNetwork { public: CYSFNetwork(const std::string& localAddress, unsigned int localPort, const std::string& name, const sockaddr_storage& addr, unsigned int addrLen, const std::string& callsign, bool debug); - CYSFNetwork(unsigned int localPort, const std::string& name, const sockaddr_storage& addr, unsigned int addrLen, const std::string& callsign, unsigned int rxFrequency, unsigned int txFrequency, const std::string& locator, const std::string& description, unsigned int id, unsigned int dgId, bool debug); CYSFNetwork(unsigned int localPort, const std::string& name, const sockaddr_storage& addr, unsigned int addrLen, const std::string& callsign, bool debug); virtual ~CYSFNetwork(); @@ -61,16 +60,11 @@ private: sockaddr_storage m_addr; unsigned int m_addrLen; unsigned char* m_poll; - unsigned char* m_options; - unsigned char* m_info; unsigned char* m_unlink; CRingBuffer m_buffer; CTimer m_pollTimer; std::string m_name; DGID_STATUS m_state; - unsigned int m_pollCount; - bool m_ycs; - unsigned int m_dgId; void writePoll(); };