From 70f956a0df8443b77a4294f31bbf87e46e9b8d47 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Wed, 19 Aug 2020 17:43:06 +0100 Subject: [PATCH] Add more IMRS support. --- DGIdGateway/DGIdGateway.cpp | 49 ++++++++++++++----- DGIdGateway/FCSNetwork.cpp | 1 - DGIdGateway/IMRSNetwork.cpp | 94 +++++++++++++++++++++++++++++++++++-- DGIdGateway/IMRSNetwork.h | 34 ++++++++++++-- DGIdGateway/YSFNetwork.cpp | 5 +- 5 files changed, 160 insertions(+), 23 deletions(-) diff --git a/DGIdGateway/DGIdGateway.cpp b/DGIdGateway/DGIdGateway.cpp index 0ac6556..0a6019a 100644 --- a/DGIdGateway/DGIdGateway.cpp +++ b/DGIdGateway/DGIdGateway.cpp @@ -193,6 +193,13 @@ int CDGIdGateway::run() CYSFReflectors* reflectors = new CYSFReflectors(fileName); reflectors->load(); + CIMRSNetwork* imrs = new CIMRSNetwork; + ret = imrs->open(); + if (!ret) { + delete imrs; + imrs = NULL; + } + unsigned int currentDGId = 0U; CDGIdNetwork* dgIdNetwork[100U]; @@ -234,20 +241,32 @@ int CDGIdGateway::run() dgIdNetwork[dgid]->m_netHangTime = netHangTime; } } else if (type == "IMRS") { - std::vector destinations = (*it)->m_destinations; + if (imrs != NULL) { + std::vector destinations = (*it)->m_destinations; + std::vector dests; + + for (std::vector::const_iterator it = destinations.begin(); it != destinations.end(); ++it) { + IMRSDest* dest = new IMRSDest; + dest->m_address = CUDPSocket::lookup((*it)->m_address); + dest->m_dgId = (*it)->m_dgId; + dests.push_back(dest); + } - dgIdNetwork[dgid] = new CIMRSNetwork(destinations, debug); - dgIdNetwork[dgid]->m_modes = YSF_DT_VD_MODE1 | YSF_DT_VD_MODE2 | YSF_DT_VOICE_FR_MODE | YSF_DT_DATA_FR_MODE; - dgIdNetwork[dgid]->m_static = statc; - dgIdNetwork[dgid]->m_rfHangTime = rfHangTime; - dgIdNetwork[dgid]->m_netHangTime = netHangTime; + imrs->addDGId(dgid, dests, debug); + + dgIdNetwork[dgid] = imrs; + dgIdNetwork[dgid]->m_modes = YSF_DT_VD_MODE1 | YSF_DT_VD_MODE2 | YSF_DT_VOICE_FR_MODE | YSF_DT_DATA_FR_MODE; + dgIdNetwork[dgid]->m_static = true; + dgIdNetwork[dgid]->m_rfHangTime = rfHangTime; + dgIdNetwork[dgid]->m_netHangTime = netHangTime; + } } else if (type == "Parrot") { in_addr address = CUDPSocket::lookup((*it)->m_address); unsigned int port = (*it)->m_port; unsigned int local = (*it)->m_local; if (address.s_addr != INADDR_NONE) { - dgIdNetwork[dgid] = new CYSFNetwork(local, "PARROT", address, port, m_callsign, debug);; + dgIdNetwork[dgid] = new CYSFNetwork(local, "PARROT", address, port, m_callsign, debug); dgIdNetwork[dgid]->m_modes = YSF_DT_VD_MODE1 | YSF_DT_VD_MODE2 | YSF_DT_VOICE_FR_MODE | YSF_DT_DATA_FR_MODE; dgIdNetwork[dgid]->m_static = statc; dgIdNetwork[dgid]->m_rfHangTime = rfHangTime; @@ -259,7 +278,7 @@ int CDGIdGateway::run() unsigned int local = (*it)->m_local; if (address.s_addr != INADDR_NONE) { - dgIdNetwork[dgid] = new CYSFNetwork(local, "YSF2DMR", address, port, m_callsign, debug);; + dgIdNetwork[dgid] = new CYSFNetwork(local, "YSF2DMR", address, port, m_callsign, debug); dgIdNetwork[dgid]->m_modes = YSF_DT_VD_MODE1 | YSF_DT_VD_MODE2; dgIdNetwork[dgid]->m_static = statc; dgIdNetwork[dgid]->m_rfHangTime = rfHangTime; @@ -271,7 +290,7 @@ int CDGIdGateway::run() unsigned int local = (*it)->m_local; if (address.s_addr != INADDR_NONE) { - dgIdNetwork[dgid] = new CYSFNetwork(local, "YSF2NXDN", address, port, m_callsign, debug);; + dgIdNetwork[dgid] = new CYSFNetwork(local, "YSF2NXDN", address, port, m_callsign, debug); dgIdNetwork[dgid]->m_modes = YSF_DT_VD_MODE1 | YSF_DT_VD_MODE2; dgIdNetwork[dgid]->m_static = statc; dgIdNetwork[dgid]->m_rfHangTime = rfHangTime; @@ -283,7 +302,7 @@ int CDGIdGateway::run() unsigned int local = (*it)->m_local; if (address.s_addr != INADDR_NONE) { - dgIdNetwork[dgid] = new CYSFNetwork(local, "YSF2P25", address, port, m_callsign, debug);; + dgIdNetwork[dgid] = new CYSFNetwork(local, "YSF2P25", address, port, m_callsign, debug); dgIdNetwork[dgid]->m_modes = YSF_DT_VOICE_FR_MODE; dgIdNetwork[dgid]->m_static = statc; dgIdNetwork[dgid]->m_rfHangTime = rfHangTime; @@ -291,8 +310,7 @@ int CDGIdGateway::run() } } - if (dgIdNetwork[dgid] != NULL) { - LogDebug("Loaded DG-ID %u", dgid); + if (dgIdNetwork[dgid] != NULL && dgIdNetwork[dgid] != imrs) { bool ret = dgIdNetwork[dgid]->open(); if (!ret) { delete dgIdNetwork[dgid]; @@ -433,7 +451,7 @@ int CDGIdGateway::run() } for (unsigned int i = 1U; i < 100U; i++) { - if (dgIdNetwork[i] != NULL) { + if (dgIdNetwork[i] != NULL && dgIdNetwork[i] != imrs) { dgIdNetwork[i]->unlink(); dgIdNetwork[i]->unlink(); dgIdNetwork[i]->unlink(); @@ -442,6 +460,11 @@ int CDGIdGateway::run() } } + if (imrs != NULL) { + imrs->close(); + delete imrs; + } + ::LogFinalise(); return 0; diff --git a/DGIdGateway/FCSNetwork.cpp b/DGIdGateway/FCSNetwork.cpp index 0f0ed9f..d48aa54 100644 --- a/DGIdGateway/FCSNetwork.cpp +++ b/DGIdGateway/FCSNetwork.cpp @@ -192,7 +192,6 @@ unsigned int CFCSNetwork::read(unsigned int dgid, unsigned char* data) unsigned char len = 0U; m_buffer.getData(&len, 1U); - // Pass pings up to the gateway to reset the lost timer. if (len != 130U) { m_buffer.getData(data, len); diff --git a/DGIdGateway/IMRSNetwork.cpp b/DGIdGateway/IMRSNetwork.cpp index eb7fee4..bba03f3 100644 --- a/DGIdGateway/IMRSNetwork.cpp +++ b/DGIdGateway/IMRSNetwork.cpp @@ -25,8 +25,12 @@ #include #include +const unsigned int IMRS_PORT = 21110U; -CIMRSNetwork::CIMRSNetwork(const std::vector& destinations, bool debug) + +CIMRSNetwork::CIMRSNetwork() : +m_socket(IMRS_PORT), +m_dgIds() { } @@ -34,16 +38,39 @@ CIMRSNetwork::~CIMRSNetwork() { } +void CIMRSNetwork::addDGId(unsigned int dgId, const std::vector& destinations, bool debug) +{ + IMRSDGId* f = new IMRSDGId; + f->m_dgId = dgId; + f->m_destinations = destinations; + f->m_debug = debug; + + m_dgIds.push_back(f); +} + bool CIMRSNetwork::open() { LogMessage("Opening IMRS network connection"); - return true; + return m_socket.open(); } -void CIMRSNetwork::write(unsigned int dgid, const unsigned char* data) +void CIMRSNetwork::write(unsigned int dgId, const unsigned char* data) { assert(data != NULL); + + IMRSDGId* ptr = find(dgId); + if (ptr == NULL) + return; + + unsigned char buffer[200U]; + + for (std::vector::const_iterator it = ptr->m_destinations.begin(); it != ptr->m_destinations.end(); ++it) { + if (ptr->m_debug) + CUtils::dump(1U, "IMRS Network Data Sent", buffer, 130U); + + m_socket.write(buffer, 130U, (*it)->m_address, IMRS_PORT); + } } void CIMRSNetwork::link() @@ -56,17 +83,74 @@ void CIMRSNetwork::unlink() void CIMRSNetwork::clock(unsigned int ms) { + unsigned char buffer[500U]; + + in_addr address; + unsigned int port; + int length = m_socket.read(buffer, 500U, address, port); + if (length <= 0) + return; + + if (port != IMRS_PORT) + return; + + IMRSDGId* ptr = find(address); + if (ptr == NULL) + return; + + if (ptr->m_debug) + CUtils::dump(1U, "IMRS Network Data Received", buffer, length); + + unsigned char len = length; + ptr->m_buffer.addData(&len, 1U); + ptr->m_buffer.addData(buffer, len); } -unsigned int CIMRSNetwork::read(unsigned int dgid, unsigned char* data) +unsigned int CIMRSNetwork::read(unsigned int dgId, unsigned char* data) { assert(data != NULL); - return 0U; + IMRSDGId* ptr = find(dgId); + if (ptr == NULL) + return 0U; + + if (ptr->m_buffer.isEmpty()) + return 0U; + + unsigned char len = 0U; + ptr->m_buffer.getData(&len, 1U); + + ptr->m_buffer.getData(data, len); + + return len; } void CIMRSNetwork::close() { LogMessage("Closing IMRS network connection"); + + m_socket.close(); +} + +IMRSDGId* CIMRSNetwork::find(in_addr address) const +{ + for (std::vector::const_iterator it1 = m_dgIds.begin(); it1 != m_dgIds.end(); ++it1) { + for (std::vector::const_iterator it2 = (*it1)->m_destinations.begin(); it2 != (*it1)->m_destinations.end(); ++it2) { + if (address.s_addr == (*it2)->m_address.s_addr) + return *it1; + } + } + + return NULL; +} + +IMRSDGId* CIMRSNetwork::find(unsigned int dgId) const +{ + for (std::vector::const_iterator it = m_dgIds.begin(); it != m_dgIds.end(); ++it) { + if (dgId == (*it)->m_dgId) + return *it; + } + + return NULL; } diff --git a/DGIdGateway/IMRSNetwork.h b/DGIdGateway/IMRSNetwork.h index 063d916..f03b7ee 100644 --- a/DGIdGateway/IMRSNetwork.h +++ b/DGIdGateway/IMRSNetwork.h @@ -21,16 +21,39 @@ #include "DGIdNetwork.h" #include "YSFDefines.h" -#include "Conf.h" +#include "UDPSocket.h" +#include "RingBuffer.h" -#include +#include #include +struct IMRSDest { + in_addr m_address; + unsigned int m_dgId; +}; + +class IMRSDGId { +public: + IMRSDGId() : + m_dgId(0U), + m_destinations(), + m_debug(false), + m_buffer(1000U, "IMRS Buffer") + {} + + unsigned int m_dgId; + std::vector m_destinations; + bool m_debug; + CRingBuffer m_buffer; +}; + class CIMRSNetwork : public CDGIdNetwork { public: - CIMRSNetwork(const std::vector& destinations, bool debug); + CIMRSNetwork(); virtual ~CIMRSNetwork(); + void addDGId(unsigned int dgId, const std::vector& destinations, bool debug); + virtual bool open(); virtual void link(); @@ -46,6 +69,11 @@ public: virtual void close(); private: + CUDPSocket m_socket; + std::vector m_dgIds; + + IMRSDGId* find(in_addr address) const; + IMRSDGId* find(unsigned int dgId) const; }; #endif diff --git a/DGIdGateway/YSFNetwork.cpp b/DGIdGateway/YSFNetwork.cpp index 593e79a..23384fc 100644 --- a/DGIdGateway/YSFNetwork.cpp +++ b/DGIdGateway/YSFNetwork.cpp @@ -37,7 +37,7 @@ m_unlink(NULL), m_buffer(1000U, "YSF Network Buffer"), m_pollTimer(1000U, 5U), m_name(name), -m_linked(false) +m_linked(true) { m_poll = new unsigned char[14U]; ::memcpy(m_poll + 0U, "YSFP", 4U); @@ -97,6 +97,9 @@ void CYSFNetwork::write(unsigned int dgid, const unsigned char* data) { assert(data != NULL); + if (!m_linked) + return; + if (m_debug) CUtils::dump(1U, "YSF Network Data Sent", data, 155U);