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