From 7da7384bb220ed0765fec39493431fa2c3e9e3a0 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Sun, 31 Jan 2021 12:04:37 +0000 Subject: [PATCH] First version of the split network. --- Conf.cpp | 6 +- Conf.h | 4 +- DMRGateway.cpp | 30 ++++++-- DMRGateway.vcxproj | 2 + DMRGateway.vcxproj.filters | 6 ++ MMDVMNetwork.h | 2 +- MMDVMNetworkNew.cpp | 2 +- MMDVMNetworkNew.h | 2 +- MMDVMNetworkOld.cpp | 47 +++++++------ MMDVMNetworkOld.h | 6 +- Makefile | 3 +- SplitNetwork.cpp | 138 +++++++++++++++++++++++++++++++++++++ SplitNetwork.h | 59 ++++++++++++++++ Version.h | 4 +- 14 files changed, 264 insertions(+), 47 deletions(-) create mode 100644 SplitNetwork.cpp create mode 100644 SplitNetwork.h diff --git a/Conf.cpp b/Conf.cpp index 7e3fd52..9a4d669 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -53,7 +53,7 @@ m_rptPort(62032U), m_localAddress("127.0.0.1"), m_localPort(62031U), m_rptProtocol("New"), -m_split(false), +m_split(0U), m_ruleTrace(false), m_debug(false), m_voiceEnabled(true), @@ -285,7 +285,7 @@ bool CConf::read() else if (::strcmp(key, "RptProtocol") == 0) m_rptProtocol = value; else if (::strcmp(key, "Split") == 0) - m_split = ::atoi(value) == 1; + m_split = (unsigned int)::atoi(value); else if (::strcmp(key, "RuleTrace") == 0) m_ruleTrace = ::atoi(value) == 1; else if (::strcmp(key, "Debug") == 0) @@ -1031,7 +1031,7 @@ std::string CConf::getRptProtocol() const return m_rptProtocol; } -bool CConf::getSplit() const +unsigned int CConf::getSplit() const { return m_split; } diff --git a/Conf.h b/Conf.h index 99c43e5..f40fb65 100644 --- a/Conf.h +++ b/Conf.h @@ -86,7 +86,7 @@ public: std::string getLocalAddress() const; unsigned int getLocalPort() const; std::string getRptProtocol() const; - bool getSplit() const; + unsigned int getSplit() const; bool getRuleTrace() const; bool getDebug() const; @@ -253,7 +253,7 @@ private: std::string m_localAddress; unsigned int m_localPort; std::string m_rptProtocol; - bool m_split; + unsigned int m_split; bool m_ruleTrace; bool m_debug; diff --git a/DMRGateway.cpp b/DMRGateway.cpp index 748e5f9..ecd0371 100644 --- a/DMRGateway.cpp +++ b/DMRGateway.cpp @@ -18,6 +18,7 @@ #include "MMDVMNetworkNew.h" #include "MMDVMNetworkOld.h" +#include "SplitNetwork.h" #include "RewriteType.h" #include "DMRSlotType.h" #include "RewriteSrc.h" @@ -73,7 +74,7 @@ static void sigHandler(int signum) const char* HEADER1 = "This software is for use on amateur radio networks only,"; const char* HEADER2 = "it is to be used for educational purposes only. Its use on"; const char* HEADER3 = "commercial networks is strictly prohibited."; -const char* HEADER4 = "Copyright(C) 2017-2020 by Jonathan Naylor, G4KLX and others"; +const char* HEADER4 = "Copyright(C) 2017-2021 by Jonathan Naylor, G4KLX and others"; int main(int argc, char** argv) { @@ -1310,7 +1311,7 @@ bool CDMRGateway::createMMDVM() std::string localAddress = m_conf.getLocalAddress(); unsigned int localPort = m_conf.getLocalPort(); std::string protocol = m_conf.getRptProtocol(); - bool split = m_conf.getSplit(); + unsigned int split = m_conf.getSplit(); bool debug = m_conf.getDebug(); LogInfo("MMDVM Network Parameters"); @@ -1319,12 +1320,27 @@ bool CDMRGateway::createMMDVM() LogInfo(" Local Address: %s", localAddress.c_str()); LogInfo(" Local Port: %u", localPort); LogInfo(" Protocol: %s", protocol.c_str()); - LogInfo(" Split: %s", split ? "yes" : "no"); + LogInfo(" Split: %u", split); - if (protocol == "old") - m_repeater = new CMMDVMNetworkOld(rptAddress, rptPort, localAddress, localPort, debug); - else - m_repeater = new CMMDVMNetworkNew(rptAddress, rptPort, localAddress, localPort, debug); + if (split > 0U) { + IMMDVMNetwork* network1 = NULL; + IMMDVMNetwork* network2 = NULL; + + if (protocol == "old") { + network1 = new CMMDVMNetworkOld(rptAddress, rptPort + 0U, localAddress, localPort + 0U, debug); + network2 = new CMMDVMNetworkOld(rptAddress, rptPort + 1U, localAddress, localPort + 1U, debug); + } else { + network1 = new CMMDVMNetworkNew(rptAddress, rptPort + 0U, localAddress, localPort + 0U, debug); + network2 = new CMMDVMNetworkNew(rptAddress, rptPort + 1U, localAddress, localPort + 1U, debug); + } + + m_repeater = new CSplitNetwork(network1, network2, split, debug); + } else { + if (protocol == "old") + m_repeater = new CMMDVMNetworkOld(rptAddress, rptPort, localAddress, localPort, debug); + else + m_repeater = new CMMDVMNetworkNew(rptAddress, rptPort, localAddress, localPort, debug); + } bool ret = m_repeater->open(); if (!ret) { diff --git a/DMRGateway.vcxproj b/DMRGateway.vcxproj index 056b770..b40e943 100644 --- a/DMRGateway.vcxproj +++ b/DMRGateway.vcxproj @@ -191,6 +191,7 @@ + @@ -238,6 +239,7 @@ + diff --git a/DMRGateway.vcxproj.filters b/DMRGateway.vcxproj.filters index 6083433..7be09e7 100644 --- a/DMRGateway.vcxproj.filters +++ b/DMRGateway.vcxproj.filters @@ -152,6 +152,9 @@ Header Files + + Header Files + @@ -286,5 +289,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/MMDVMNetwork.h b/MMDVMNetwork.h index ec99790..0ef1485 100644 --- a/MMDVMNetwork.h +++ b/MMDVMNetwork.h @@ -36,7 +36,7 @@ public: virtual bool read(CDMRData& data) = 0; - virtual bool write(const CDMRData& data) = 0; + virtual bool write(CDMRData& data) = 0; virtual bool readRadioPosition(unsigned char* data, unsigned int& length) = 0; diff --git a/MMDVMNetworkNew.cpp b/MMDVMNetworkNew.cpp index 0e837f0..03e0817 100644 --- a/MMDVMNetworkNew.cpp +++ b/MMDVMNetworkNew.cpp @@ -160,7 +160,7 @@ bool CMMDVMNetworkNew::read(CDMRData& data) return true; } -bool CMMDVMNetworkNew::write(const CDMRData& data) +bool CMMDVMNetworkNew::write(CDMRData& data) { unsigned char buffer[HOMEBREW_DATA_PACKET_LENGTH]; ::memset(buffer, 0x00U, HOMEBREW_DATA_PACKET_LENGTH); diff --git a/MMDVMNetworkNew.h b/MMDVMNetworkNew.h index cad3bf3..4a834af 100644 --- a/MMDVMNetworkNew.h +++ b/MMDVMNetworkNew.h @@ -41,7 +41,7 @@ public: virtual bool read(CDMRData& data); - virtual bool write(const CDMRData& data); + virtual bool write(CDMRData& data); virtual bool readRadioPosition(unsigned char* data, unsigned int& length); diff --git a/MMDVMNetworkOld.cpp b/MMDVMNetworkOld.cpp index 50ebbd2..872ca08 100644 --- a/MMDVMNetworkOld.cpp +++ b/MMDVMNetworkOld.cpp @@ -45,9 +45,7 @@ m_configLen(0U), m_radioPositionData(NULL), m_radioPositionLen(0U), m_talkerAliasData(NULL), -m_talkerAliasLen(0U), -m_homePositionData(NULL), -m_homePositionLen(0U) +m_talkerAliasLen(0U) { assert(!rptAddress.empty()); assert(rptPort > 0U); @@ -60,7 +58,6 @@ m_homePositionLen(0U) m_radioPositionData = new unsigned char[50U]; m_talkerAliasData = new unsigned char[50U]; - m_homePositionData = new unsigned char[50U]; CStopWatch stopWatch; ::srand(stopWatch.start()); @@ -73,7 +70,6 @@ CMMDVMNetworkOld::~CMMDVMNetworkOld() delete[] m_configData; delete[] m_radioPositionData; delete[] m_talkerAliasData; - delete[] m_homePositionData; } unsigned int CMMDVMNetworkOld::getShortConfig(unsigned char* config) const @@ -165,7 +161,7 @@ bool CMMDVMNetworkOld::read(CDMRData& data) return true; } -bool CMMDVMNetworkOld::write(const CDMRData& data) +bool CMMDVMNetworkOld::write(CDMRData& data) { unsigned char buffer[HOMEBREW_DATA_PACKET_LENGTH]; ::memset(buffer, 0x00U, HOMEBREW_DATA_PACKET_LENGTH); @@ -248,19 +244,6 @@ bool CMMDVMNetworkOld::readTalkerAlias(unsigned char* data, unsigned int& length return true; } -bool CMMDVMNetworkOld::readHomePosition(unsigned char* data, unsigned int& length) -{ - if (m_homePositionLen == 0U) - return false; - - ::memcpy(data, m_homePositionData, m_homePositionLen); - length = m_homePositionLen; - - m_homePositionLen = 0U; - - return true; -} - bool CMMDVMNetworkOld::writeBeacon() { unsigned char buffer[20U]; @@ -319,8 +302,6 @@ void CMMDVMNetworkOld::clock(unsigned int ms) ::memcpy(m_talkerAliasData, m_buffer, length); m_talkerAliasLen = length; } else if (::memcmp(m_buffer, "RPTG", 4U) == 0) { - ::memcpy(m_homePositionData, m_buffer, length); - m_homePositionLen = length; } else if (::memcmp(m_buffer, "RPTL", 4U) == 0) { m_id = (m_buffer[4U] << 24) | (m_buffer[5U] << 16) | (m_buffer[6U] << 8) | (m_buffer[7U] << 0); ::memcpy(m_netId, m_buffer + 4U, 4U); @@ -340,10 +321,28 @@ void CMMDVMNetworkOld::clock(unsigned int ms) } else if (::memcmp(m_buffer, "RPTCL", 5U) == 0) { ::LogMessage("MMDVM Network, The connected MMDVM is closing down"); } else if (::memcmp(m_buffer, "RPTC", 4U) == 0) { - // XXX FIXME !!! - m_configLen = length - 8U; + m_configLen = 111U; m_configData = new unsigned char[m_configLen]; - ::memcpy(m_configData, m_buffer + 8U, m_configLen); + + // Convert the old style config data to the new style + const unsigned char* p = m_buffer; + + p += 4U + 4U; // Skip the opcode and id fields + + // First the callsign, frequencies, power, and color code. + ::memcpy(m_configData + 0U, p, 8U + 9U + 9U + 2U + 2U); + p += 8U + 9U + 9U + 2U + 2U; + + p += 8U + 9U + 3U + 20U + 19U; // Skip the latutude, longitude, height, location and description. + + // Next the slots. + ::memcpy(m_configData + 30U, p, 1U); + p += 1U; + + p += 124U; // Skip the URL + + // Finally the version and software. + ::memcpy(m_configData + 31U, p, 40U + 40U); unsigned char ack[10U]; ::memcpy(ack + 0U, "RPTACK", 6U); diff --git a/MMDVMNetworkOld.h b/MMDVMNetworkOld.h index 5a91c07..343530f 100644 --- a/MMDVMNetworkOld.h +++ b/MMDVMNetworkOld.h @@ -41,14 +41,12 @@ public: virtual bool read(CDMRData& data); - virtual bool write(const CDMRData& data); + virtual bool write(CDMRData& data); virtual bool readRadioPosition(unsigned char* data, unsigned int& length); virtual bool readTalkerAlias(unsigned char* data, unsigned int& length); - virtual bool readHomePosition(unsigned char* data, unsigned int& length); - virtual bool writeBeacon(); virtual void clock(unsigned int ms); @@ -70,8 +68,6 @@ private: unsigned int m_radioPositionLen; unsigned char* m_talkerAliasData; unsigned int m_talkerAliasLen; - unsigned char* m_homePositionData; - unsigned int m_homePositionLen; }; #endif diff --git a/Makefile b/Makefile index 3f3b12b..da0c2d9 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,8 @@ LDFLAGS = -g OBJECTS = APRSWriter.o BPTC19696.o Conf.o CRC.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREmbeddedData.o DMREMB.o DMRFullLC.o DMRGateway.o \ DMRLC.o DMRNetwork.o DMRSlotType.o DynVoice.o Golay2087.o GPSD.o Hamming.o Log.o MMDVMNetwork.o MMDVMNetworkNew.o MMDVMNetworkOld.o \ PassAllPC.o PassAllTG.o QR1676.o Reflectors.o Rewrite.o RewriteDstId.o RewriteDynTGNet.o RewriteDynTGRF.o RewritePC.o RewriteSrc.o \ - RewriteSrcId.o RewriteTG.o RewriteType.o RS129.o SHA256.o StopWatch.o Sync.o Thread.o Timer.o UDPSocket.o Utils.o XLXVoice.o + RewriteSrcId.o RewriteTG.o RewriteType.o RS129.o SHA256.o SplitNetwork.o StopWatch.o Sync.o Thread.o Timer.o UDPSocket.o Utils.o \ + XLXVoice.o all: DMRGateway diff --git a/SplitNetwork.cpp b/SplitNetwork.cpp new file mode 100644 index 0000000..e636eeb --- /dev/null +++ b/SplitNetwork.cpp @@ -0,0 +1,138 @@ +/* + * Copyright (C) 2021 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 "SplitNetwork.h" + +#include +#include + +CSplitNetwork::CSplitNetwork(IMMDVMNetwork* network1, IMMDVMNetwork* network2, unsigned int slotNo, bool debug) : +m_network1(network1), +m_network2(network2), +m_slotNo(slotNo), +m_debug(debug) +{ + assert(network1 != NULL); + assert(network2 != NULL); + assert(slotNo == 1U || slotNo == 2U); +} + +CSplitNetwork::~CSplitNetwork() +{ + delete m_network1; + delete m_network2; +} + +unsigned int CSplitNetwork::getShortConfig(unsigned char* config) const +{ + assert(config != NULL); + + return m_network1->getShortConfig(config); +} + +unsigned int CSplitNetwork::getId() const +{ + return m_network1->getId(); +} + +bool CSplitNetwork::open() +{ + bool ret = m_network1->open(); + if (!ret) + return false; + + ret = m_network2->open(); + if (!ret) { + m_network1->close(); + return false; + } + + return true; +} + +bool CSplitNetwork::read(CDMRData& data) +{ + bool ret = m_network1->read(data); + if (ret) { + data.setSlotNo(1U); + return true; + } + + ret = m_network2->read(data); + if (ret) { + data.setSlotNo(2U); + return true; + } + + return false; +} + +bool CSplitNetwork::write(CDMRData& data) +{ + unsigned int slot = data.getSlotNo(); + if (slot == 1U) { + data.setSlotNo(m_slotNo); + return m_network1->write(data); + } else { + data.setSlotNo(m_slotNo); + return m_network2->write(data); + } +} + +bool CSplitNetwork::readRadioPosition(unsigned char* data, unsigned int& length) +{ + assert(data != NULL); + + bool ret = m_network1->readRadioPosition(data, length); + if (ret) + return true; + + return m_network2->readRadioPosition(data, length); +} + +bool CSplitNetwork::readTalkerAlias(unsigned char* data, unsigned int& length) +{ + assert(data != NULL); + + bool ret = m_network1->readTalkerAlias(data, length); + if (ret) + return true; + + return m_network2->readTalkerAlias(data, length); +} + +bool CSplitNetwork::writeBeacon() +{ + bool ret = m_network1->writeBeacon(); + if (!ret) + return false; + + return m_network2->writeBeacon(); +} + +void CSplitNetwork::clock(unsigned int ms) +{ + m_network1->clock(ms); + m_network2->clock(ms); +} + +void CSplitNetwork::close() +{ + m_network1->close(); + m_network2->close(); +} diff --git a/SplitNetwork.h b/SplitNetwork.h new file mode 100644 index 0000000..6e0f1f9 --- /dev/null +++ b/SplitNetwork.h @@ -0,0 +1,59 @@ +/* + * Copyright (C) 2021 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. + */ + +#if !defined(SplitNetwork_H) +#define SplitNetwork_H + +#include "MMDVMNetwork.h" + +#include + +class CSplitNetwork : public IMMDVMNetwork +{ +public: + CSplitNetwork(IMMDVMNetwork* network1, IMMDVMNetwork* network2, unsigned int slotNo, bool debug); + virtual ~CSplitNetwork(); + + virtual unsigned int getShortConfig(unsigned char* config) const; + + virtual unsigned int getId() const; + + virtual bool open(); + + virtual bool read(CDMRData& data); + + virtual bool write(CDMRData& data); + + virtual bool readRadioPosition(unsigned char* data, unsigned int& length); + + virtual bool readTalkerAlias(unsigned char* data, unsigned int& length); + + virtual bool writeBeacon(); + + virtual void clock(unsigned int ms); + + virtual void close(); + +private: + IMMDVMNetwork* m_network1; + IMMDVMNetwork* m_network2; + unsigned int m_slotNo; + bool m_debug; +}; + +#endif diff --git a/Version.h b/Version.h index b85724b..dc21127 100644 --- a/Version.h +++ b/Version.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2020 by Jonathan Naylor G4KLX + * Copyright (C) 2015-2021 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 @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20201031"; +const char* VERSION = "20210131"; #endif