From 41a49d5785abd1769e7ed4a7ee7cd18ced85e067 Mon Sep 17 00:00:00 2001 From: Daniel Caujolle-Bert Date: Sat, 20 Mar 2021 13:03:19 +0100 Subject: [PATCH 1/2] Implement remote command support. - Defaut port is 7643 (totally arbitrary) - Using RemoteCommandDMRG, each network can be enabled or disabled (net1 .. net5, xlx): ~ $ RemoteCommandDMRG 7643 disable net2 M: 2021-03-20 11:48:40.494 Command sent: "disable net2" to port: 7643 M: 2021-03-20 11:48:40.545 OK - Using RemoteCommandDMRG, a connection status can be retrieved: ~ $ RemoteCommandDMRG 7643 status M: 2021-03-20 11:49:13.513 Command sent: "status" to port: 7643 M: 2021-03-20 11:49:13.563 xlx:conn net1:conn net2:n/a net3:n/a net4:conn net5:n/a A returned string is expected from the socket connection, this is why I did not reuse the MMDVMHost's RemoteCommand (unless MMDVMHost RemoteControl is modified as well). The exit value can be used in scripting (also 1 if we didn't get any reply). --- Conf.cpp | 32 +++++- Conf.h | 9 ++ DMRGateway.cpp | 260 ++++++++++++++++++++++++++++++++---------- DMRGateway.h | 25 +++- DMRGateway.ini | 5 + DMRNetwork.cpp | 17 ++- DMRNetwork.h | 3 + Makefile | 5 +- RemoteCommandDMRG.cpp | 111 ++++++++++++++++++ RemoteCommandDMRG.h | 36 ++++++ RemoteControl.cpp | 166 +++++++++++++++++++++++++++ RemoteControl.h | 71 ++++++++++++ XLXVoice.cpp | 15 ++- XLXVoice.h | 2 + 14 files changed, 683 insertions(+), 74 deletions(-) create mode 100644 RemoteCommandDMRG.cpp create mode 100644 RemoteCommandDMRG.h create mode 100644 RemoteControl.cpp create mode 100644 RemoteControl.h diff --git a/Conf.cpp b/Conf.cpp index c29ae34..6a899f2 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -40,7 +40,8 @@ enum SECTION { SECTION_XLX_NETWORK, SECTION_GPSD, SECTION_APRS, - SECTION_DYNAMIC_TG_CONTROL + SECTION_DYNAMIC_TG_CONTROL, + SECTION_REMOTE_CONTROL }; CConf::CConf(const std::string& file) : @@ -182,7 +183,10 @@ m_aprsPort(0U), m_aprsSuffix(), m_aprsDescription(), m_dynamicTGControlEnabled(false), -m_dynamicTGControlPort(3769U) +m_dynamicTGControlPort(3769U), +m_remoteControlEnabled(false), +m_remoteControlAddress("127.0.0.1"), +m_remoteControlPort(0U) { } @@ -232,6 +236,8 @@ bool CConf::read() section = SECTION_APRS; else if (::strncmp(buffer, "[Dynamic TG Control]", 20U) == 0) section = SECTION_DYNAMIC_TG_CONTROL; + else if (::strncmp(buffer, "[Remote Control]", 16U) == 0) + section = SECTION_REMOTE_CONTROL; else section = SECTION_NONE; @@ -977,6 +983,13 @@ bool CConf::read() m_dynamicTGControlEnabled = ::atoi(value) == 1; else if (::strcmp(key, "Port") == 0) m_dynamicTGControlPort = (unsigned int)::atoi(value); + } else if (section == SECTION_REMOTE_CONTROL) { + if (::strcmp(key, "Enable") == 0) + m_remoteControlEnabled = ::atoi(value) == 1; + else if (::strcmp(key, "Address") == 0) + m_remoteControlAddress = value; + else if (::strcmp(key, "Port") == 0) + m_remoteControlPort = (unsigned int)::atoi(value); } } @@ -1687,3 +1700,18 @@ unsigned int CConf::getDynamicTGControlPort() const { return m_dynamicTGControlPort; } + +bool CConf::getRemoteControlEnabled() const +{ + return m_remoteControlEnabled; +} + +std::string CConf::getRemoteControlAddress() const +{ + return m_remoteControlAddress; +} + +unsigned int CConf::getRemoteControlPort() const +{ + return m_remoteControlPort; +} diff --git a/Conf.h b/Conf.h index 85e38a6..d3a15fc 100644 --- a/Conf.h +++ b/Conf.h @@ -241,6 +241,11 @@ public: bool getDynamicTGControlEnabled() const; unsigned int getDynamicTGControlPort() const; + // The Remote Control section + bool getRemoteControlEnabled() const; + std::string getRemoteControlAddress() const; + unsigned int getRemoteControlPort() const; + private: std::string m_file; bool m_daemon; @@ -393,6 +398,10 @@ private: bool m_dynamicTGControlEnabled; unsigned int m_dynamicTGControlPort; + + bool m_remoteControlEnabled; + std::string m_remoteControlAddress; + unsigned int m_remoteControlPort; }; #endif diff --git a/DMRGateway.cpp b/DMRGateway.cpp index 0564932..f9a4047 100644 --- a/DMRGateway.cpp +++ b/DMRGateway.cpp @@ -27,7 +27,6 @@ #include "PassAllPC.h" #include "PassAllTG.h" #include "DMRFullLC.h" -#include "XLXVoice.h" #include "Version.h" #include "Thread.h" #include "DMRLC.h" @@ -159,6 +158,7 @@ m_xlxUserControl(true), m_xlxModule(), m_rptRewrite(NULL), m_xlxRewrite(NULL), +m_xlxVoice(NULL), m_dmr1NetRewrites(), m_dmr1RFRewrites(), m_dmr1SrcRewrites(), @@ -185,10 +185,17 @@ m_socket(NULL), m_writer(NULL), m_callsign(), m_txFrequency(0U), -m_rxFrequency(0U) +m_rxFrequency(0U), #if defined(USE_GPSD) -,m_gpsd(NULL) +m_gpsd(NULL), #endif +m_network1Enabled(false), +m_network2Enabled(false), +m_network3Enabled(false), +m_network4Enabled(false), +m_network5Enabled(false), +m_networkXlxEnabled(false), +m_remoteControl(NULL) { CUDPSocket::startup(); @@ -354,6 +361,13 @@ int CDMRGateway::run() } #endif + m_network1Enabled = m_conf.getDMRNetwork1Enabled(); + m_network2Enabled = m_conf.getDMRNetwork2Enabled(); + m_network3Enabled = m_conf.getDMRNetwork3Enabled(); + m_network4Enabled = m_conf.getDMRNetwork4Enabled(); + m_network5Enabled = m_conf.getDMRNetwork5Enabled(); + m_networkXlxEnabled = m_conf.getXLXNetworkEnabled(); + LogInfo(HEADER1); LogInfo(HEADER2); LogInfo(HEADER3); @@ -409,13 +423,12 @@ int CDMRGateway::run() bool ruleTrace = m_conf.getRuleTrace(); LogInfo("Rule trace: %s", ruleTrace ? "yes" : "no"); - if (m_conf.getXLXNetworkEnabled()) { + if (m_networkXlxEnabled && m_conf.getXLXNetworkEnabled()) { ret = createXLXNetwork(); if (!ret) return 1; } - CXLXVoice* xlxVoice = NULL; if (m_conf.getVoiceEnabled()) { std::string language = m_conf.getVoiceLanguage(); std::string directory = m_conf.getVoiceDirectory(); @@ -426,40 +439,59 @@ int CDMRGateway::run() LogInfo(" Directory: %s", directory.c_str()); if (m_xlxNetwork != NULL) { - xlxVoice = new CXLXVoice(directory, language, m_repeater->getId(), m_xlxSlot, m_xlxTG); - bool ret = xlxVoice->open(); + m_xlxVoice = new CXLXVoice(directory, language, m_repeater->getId(), m_xlxSlot, m_xlxTG); + bool ret = m_xlxVoice->open(); if (!ret) { - delete xlxVoice; - xlxVoice = NULL; + delete m_xlxVoice; + m_xlxVoice = NULL; } } } - if (m_conf.getDMRNetwork1Enabled()) { + bool remoteControlEnabled = m_conf.getRemoteControlEnabled(); + if (remoteControlEnabled) { + std::string address = m_conf.getRemoteControlAddress(); + unsigned int port = m_conf.getRemoteControlPort(); + + LogInfo("Remote Control Parameters"); + LogInfo(" Address: %s", address.c_str()); + LogInfo(" Port: %u", port); + + m_remoteControl = new CRemoteControl(this, address, port); + + ret = m_remoteControl->open(); + if (!ret) { + LogInfo("Failed to open Remove Control Socket"); + delete m_remoteControl; + m_remoteControl = NULL; + } + } + + if (m_network1Enabled && m_conf.getDMRNetwork1Enabled()) { ret = createDMRNetwork1(); if (!ret) return 1; } - if (m_conf.getDMRNetwork2Enabled()) { + if (m_network2Enabled && m_conf.getDMRNetwork2Enabled()) { ret = createDMRNetwork2(); if (!ret) return 1; } - if (m_conf.getDMRNetwork3Enabled()) { + if (m_network3Enabled && m_conf.getDMRNetwork3Enabled()) { ret = createDMRNetwork3(); if (!ret) return 1; } - if (m_conf.getDMRNetwork4Enabled()) { + if (m_network4Enabled && m_conf.getDMRNetwork4Enabled()) { ret = createDMRNetwork4(); if (!ret) return 1; } - if (m_conf.getDMRNetwork5Enabled()) { + if (m_network5Enabled && m_conf.getDMRNetwork5Enabled()) { ret = createDMRNetwork5(); if (!ret) return 1; @@ -510,25 +542,25 @@ int CDMRGateway::run() LogMessage("DMRGateway-%s is running", VERSION); while (!m_killed) { - if (m_xlxNetwork != NULL) { + if (m_networkXlxEnabled && (m_xlxNetwork != NULL)) { bool connected = m_xlxNetwork->isConnected(); if (connected && !m_xlxConnected) { if (m_xlxReflector >= 4001U && m_xlxReflector <= 4026U) { writeXLXLink(m_xlxId, m_xlxReflector, m_xlxNetwork); char c = ('A' + (m_xlxReflector % 100U)) - 1U; LogMessage("XLX, Linking to reflector XLX%03u %c", m_xlxNumber, c); - if (xlxVoice != NULL) - xlxVoice->linkedTo(m_xlxNumber, m_xlxReflector); + if (m_xlxVoice != NULL) + m_xlxVoice->linkedTo(m_xlxNumber, m_xlxReflector); } else if (m_xlxRoom >= 4001U && m_xlxRoom <= 4026U) { writeXLXLink(m_xlxId, m_xlxRoom, m_xlxNetwork); char c = ('A' + (m_xlxRoom % 100U)) - 1U; LogMessage("XLX, Linking to reflector XLX%03u %c", m_xlxNumber, c); - if (xlxVoice != NULL) - xlxVoice->linkedTo(m_xlxNumber, m_xlxRoom); + if (m_xlxVoice != NULL) + m_xlxVoice->linkedTo(m_xlxNumber, m_xlxRoom); m_xlxReflector = m_xlxRoom; } else { - if (xlxVoice != NULL) - xlxVoice->linkedTo(m_xlxNumber, 0U); + if (m_xlxVoice != NULL) + m_xlxVoice->linkedTo(m_xlxNumber, 0U); } m_xlxConnected = true; @@ -540,8 +572,8 @@ int CDMRGateway::run() } else if (!connected && m_xlxConnected) { LogMessage("XLX, Unlinking from XLX%03u due to loss of connection", m_xlxNumber); - if (xlxVoice != NULL) - xlxVoice->unlinked(); + if (m_xlxVoice != NULL) + m_xlxVoice->unlinked(); m_xlxConnected = false; m_xlxRelink.stop(); @@ -572,11 +604,11 @@ int CDMRGateway::run() } m_xlxReflector = m_xlxRoom; - if (xlxVoice != NULL) { + if (m_xlxVoice != NULL) { if (m_xlxReflector < 4001U || m_xlxReflector > 4026U) - xlxVoice->linkedTo(m_xlxNumber, 0U); + m_xlxVoice->linkedTo(m_xlxNumber, 0U); else - xlxVoice->linkedTo(m_xlxNumber, m_xlxReflector); + m_xlxVoice->linkedTo(m_xlxNumber, m_xlxReflector); } } } @@ -596,7 +628,9 @@ int CDMRGateway::run() m_xlxRelink.start(); m_xlxRewrite->process(data, false); - m_xlxNetwork->write(data); + if (m_networkXlxEnabled) { + m_xlxNetwork->write(data); + } m_status[slotNo] = DMRGWS_XLXREFLECTOR; timer[slotNo]->setTimeout(rfTimeout); timer[slotNo]->start(); @@ -629,16 +663,16 @@ int CDMRGateway::run() timer[slotNo]->setTimeout(rfTimeout); timer[slotNo]->start(); - if (xlxVoice != NULL) { + if (m_xlxVoice != NULL) { unsigned char type = data.getDataType(); if (type == DT_TERMINATOR_WITH_LC) { if (m_xlxConnected) { if (m_xlxReflector != 4000U) - xlxVoice->linkedTo(m_xlxNumber, m_xlxReflector); + m_xlxVoice->linkedTo(m_xlxNumber, m_xlxReflector); else - xlxVoice->linkedTo(m_xlxNumber, 0U); + m_xlxVoice->linkedTo(m_xlxNumber, 0U); } else { - xlxVoice->unlinked(); + m_xlxVoice->unlinked(); } } } @@ -666,7 +700,7 @@ int CDMRGateway::run() PROCESS_RESULT result = RESULT_UNMATCHED; - if (m_dmrNetwork1 != NULL) { + if (m_network1Enabled && (m_dmrNetwork1 != NULL)) { // Rewrite the slot and/or TG or neither for (std::vector::iterator it = m_dmr1RFRewrites.begin(); it != m_dmr1RFRewrites.end(); ++it) { PROCESS_RESULT res = (*it)->process(data, trace); @@ -688,7 +722,7 @@ int CDMRGateway::run() } if (result == RESULT_UNMATCHED) { - if (m_dmrNetwork2 != NULL) { + if (m_network2Enabled && (m_dmrNetwork2 != NULL)) { // Rewrite the slot and/or TG or neither for (std::vector::iterator it = m_dmr2RFRewrites.begin(); it != m_dmr2RFRewrites.end(); ++it) { PROCESS_RESULT res = (*it)->process(data, trace); @@ -711,7 +745,7 @@ int CDMRGateway::run() } if (result == RESULT_UNMATCHED) { - if (m_dmrNetwork3 != NULL) { + if (m_network3Enabled && (m_dmrNetwork3 != NULL)) { // Rewrite the slot and/or TG or neither for (std::vector::iterator it = m_dmr3RFRewrites.begin(); it != m_dmr3RFRewrites.end(); ++it) { PROCESS_RESULT res = (*it)->process(data, trace); @@ -734,7 +768,7 @@ int CDMRGateway::run() } if (result == RESULT_UNMATCHED) { - if (m_dmrNetwork4 != NULL) { + if (m_network4Enabled && (m_dmrNetwork4 != NULL)) { // Rewrite the slot and/or TG or neither for (std::vector::iterator it = m_dmr4RFRewrites.begin(); it != m_dmr4RFRewrites.end(); ++it) { PROCESS_RESULT res = (*it)->process(data, trace); @@ -757,7 +791,7 @@ int CDMRGateway::run() } if (result == RESULT_UNMATCHED) { - if (m_dmrNetwork5 != NULL) { + if (m_network5Enabled && (m_dmrNetwork5 != NULL)) { // Rewrite the slot and/or TG or neither for (std::vector::iterator it = m_dmr5RFRewrites.begin(); it != m_dmr5RFRewrites.end(); ++it) { PROCESS_RESULT res = (*it)->process(data, trace); @@ -780,7 +814,7 @@ int CDMRGateway::run() } if (result == RESULT_UNMATCHED) { - if (m_dmrNetwork1 != NULL) { + if (m_network1Enabled && (m_dmrNetwork1 != NULL)) { for (std::vector::iterator it = m_dmr1Passalls.begin(); it != m_dmr1Passalls.end(); ++it) { PROCESS_RESULT res = (*it)->process(data, trace); if (res != RESULT_UNMATCHED) { @@ -802,7 +836,7 @@ int CDMRGateway::run() } if (result == RESULT_UNMATCHED) { - if (m_dmrNetwork2 != NULL) { + if (m_network2Enabled && (m_dmrNetwork2 != NULL)) { for (std::vector::iterator it = m_dmr2Passalls.begin(); it != m_dmr2Passalls.end(); ++it) { PROCESS_RESULT res = (*it)->process(data, trace); if (res != RESULT_UNMATCHED) { @@ -824,7 +858,7 @@ int CDMRGateway::run() } if (result == RESULT_UNMATCHED) { - if (m_dmrNetwork3 != NULL) { + if (m_network3Enabled && (m_dmrNetwork3 != NULL)) { for (std::vector::iterator it = m_dmr3Passalls.begin(); it != m_dmr3Passalls.end(); ++it) { PROCESS_RESULT res = (*it)->process(data, trace); if (res != RESULT_UNMATCHED) { @@ -846,7 +880,7 @@ int CDMRGateway::run() } if (result == RESULT_UNMATCHED) { - if (m_dmrNetwork4 != NULL) { + if (m_network4Enabled && (m_dmrNetwork4 != NULL)) { for (std::vector::iterator it = m_dmr4Passalls.begin(); it != m_dmr4Passalls.end(); ++it) { PROCESS_RESULT res = (*it)->process(data, trace); if (res != RESULT_UNMATCHED) { @@ -868,7 +902,7 @@ int CDMRGateway::run() } if (result == RESULT_UNMATCHED) { - if (m_dmrNetwork5 != NULL) { + if (m_network5Enabled && (m_dmrNetwork5 != NULL)) { for (std::vector::iterator it = m_dmr5Passalls.begin(); it != m_dmr5Passalls.end(); ++it) { PROCESS_RESULT res = (*it)->process(data, trace); if (res != RESULT_UNMATCHED) { @@ -894,7 +928,7 @@ int CDMRGateway::run() } } - if (m_xlxNetwork != NULL) { + if (m_networkXlxEnabled && (m_xlxNetwork != NULL)) { ret = m_xlxNetwork->read(data); if (ret) { if (m_status[m_xlxSlot] == DMRGWS_NONE || m_status[m_xlxSlot] == DMRGWS_XLXREFLECTOR) { @@ -914,7 +948,7 @@ int CDMRGateway::run() } } - if (m_dmrNetwork1 != NULL) { + if (m_network1Enabled && (m_dmrNetwork1 != NULL)) { ret = m_dmrNetwork1->read(data); if (ret) { unsigned int slotNo = data.getSlotNo(); @@ -964,7 +998,7 @@ int CDMRGateway::run() m_repeater->writeBeacon(); } - if (m_dmrNetwork2 != NULL) { + if (m_network2Enabled && (m_dmrNetwork2 != NULL)) { ret = m_dmrNetwork2->read(data); if (ret) { unsigned int slotNo = data.getSlotNo(); @@ -1014,7 +1048,7 @@ int CDMRGateway::run() m_repeater->writeBeacon(); } - if (m_dmrNetwork3 != NULL) { + if (m_network3Enabled && (m_dmrNetwork3 != NULL)) { ret = m_dmrNetwork3->read(data); if (ret) { unsigned int slotNo = data.getSlotNo(); @@ -1064,7 +1098,7 @@ int CDMRGateway::run() m_repeater->writeBeacon(); } - if (m_dmrNetwork4 != NULL) { + if (m_network4Enabled && (m_dmrNetwork4 != NULL)) { ret = m_dmrNetwork4->read(data); if (ret) { unsigned int slotNo = data.getSlotNo(); @@ -1114,7 +1148,7 @@ int CDMRGateway::run() m_repeater->writeBeacon(); } - if (m_dmrNetwork5 != NULL) { + if (m_network5Enabled && (m_dmrNetwork5 != NULL)) { ret = m_dmrNetwork5->read(data); if (ret) { unsigned int slotNo = data.getSlotNo(); @@ -1168,8 +1202,8 @@ int CDMRGateway::run() processTalkerAlias(); - if (xlxVoice != NULL) { - ret = xlxVoice->read(data); + if (m_networkXlxEnabled && (m_xlxVoice != NULL)) { + ret = m_xlxVoice->read(data); if (ret) { m_repeater->write(data); m_status[m_xlxSlot] = DMRGWS_XLXREFLECTOR; @@ -1187,6 +1221,8 @@ int CDMRGateway::run() if (m_socket != NULL) processDynamicTGControl(); + remoteControl(); + unsigned int ms = stopWatch.elapsed(); stopWatch.start(); @@ -1215,8 +1251,8 @@ int CDMRGateway::run() if (m_xlxReflectors != NULL) m_xlxReflectors->clock(ms); - if (xlxVoice != NULL) - xlxVoice->clock(ms); + if (m_xlxVoice != NULL) + m_xlxVoice->clock(ms); #if defined(USE_GPSD) if (m_gpsd != NULL) @@ -1241,11 +1277,16 @@ int CDMRGateway::run() CThread::sleep(10U); } - delete xlxVoice; + delete m_xlxVoice; m_repeater->close(); delete m_repeater; + if (m_remoteControl != NULL) { + m_remoteControl->close(); + delete m_remoteControl; + } + #if defined(USE_GPSD) if (m_gpsd != NULL) { m_gpsd->close(); @@ -1491,6 +1532,8 @@ bool CDMRGateway::createDMRNetwork1() m_dmr1NetRewrites.push_back(netPassAllPC); } + m_dmrNetwork1->enable(true); + return true; } @@ -1658,6 +1701,8 @@ bool CDMRGateway::createDMRNetwork2() m_dmr2NetRewrites.push_back(netPassAllPC); } + m_dmrNetwork2->enable(true); + return true; } @@ -1825,6 +1870,8 @@ bool CDMRGateway::createDMRNetwork3() m_dmr3NetRewrites.push_back(netPassAllPC); } + m_dmrNetwork3->enable(true); + return true; } @@ -1992,6 +2039,8 @@ bool CDMRGateway::createDMRNetwork4() m_dmr4NetRewrites.push_back(netPassAllPC); } + m_dmrNetwork4->enable(true); + return true; } @@ -2159,6 +2208,8 @@ bool CDMRGateway::createDMRNetwork5() m_dmr5NetRewrites.push_back(netPassAllPC); } + m_dmrNetwork5->enable(true); + return true; } @@ -2286,6 +2337,8 @@ bool CDMRGateway::linkXLX(unsigned int number) LogMessage("XLX, Connecting to XLX%03u", m_xlxNumber); + m_xlxNetwork->enable(m_networkXlxEnabled); + return true; } @@ -2412,19 +2465,19 @@ void CDMRGateway::processRadioPosition() if (!ret) return; - if (m_dmrNetwork1 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK1 || m_status[2U] == DMRGWS_DMRNETWORK1)) + if (m_network1Enabled && (m_dmrNetwork1 != NULL) && (m_status[1U] == DMRGWS_DMRNETWORK1 || m_status[2U] == DMRGWS_DMRNETWORK1)) m_dmrNetwork1->writeRadioPosition(buffer, length); - if (m_dmrNetwork2 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK2 || m_status[2U] == DMRGWS_DMRNETWORK2)) + if (m_network2Enabled && (m_dmrNetwork2 != NULL) && (m_status[1U] == DMRGWS_DMRNETWORK2 || m_status[2U] == DMRGWS_DMRNETWORK2)) m_dmrNetwork2->writeRadioPosition(buffer, length); - if (m_dmrNetwork3 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK3 || m_status[2U] == DMRGWS_DMRNETWORK3)) + if (m_network3Enabled && (m_dmrNetwork3 != NULL) && (m_status[1U] == DMRGWS_DMRNETWORK3 || m_status[2U] == DMRGWS_DMRNETWORK3)) m_dmrNetwork3->writeRadioPosition(buffer, length); - if (m_dmrNetwork4 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK4 || m_status[2U] == DMRGWS_DMRNETWORK4)) + if (m_network4Enabled && (m_dmrNetwork4 != NULL) && (m_status[1U] == DMRGWS_DMRNETWORK4 || m_status[2U] == DMRGWS_DMRNETWORK4)) m_dmrNetwork4->writeRadioPosition(buffer, length); - if (m_dmrNetwork5 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK5 || m_status[2U] == DMRGWS_DMRNETWORK5)) + if (m_network5Enabled && (m_dmrNetwork5 != NULL) && (m_status[1U] == DMRGWS_DMRNETWORK5 || m_status[2U] == DMRGWS_DMRNETWORK5)) m_dmrNetwork5->writeRadioPosition(buffer, length); } @@ -2436,19 +2489,19 @@ void CDMRGateway::processTalkerAlias() if (!ret) return; - if (m_dmrNetwork1 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK1 || m_status[2U] == DMRGWS_DMRNETWORK1)) + if (m_network1Enabled && (m_dmrNetwork1 != NULL) && (m_status[1U] == DMRGWS_DMRNETWORK1 || m_status[2U] == DMRGWS_DMRNETWORK1)) m_dmrNetwork1->writeTalkerAlias(buffer, length); - if (m_dmrNetwork2 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK2 || m_status[2U] == DMRGWS_DMRNETWORK2)) + if (m_network2Enabled && (m_dmrNetwork2 != NULL) && (m_status[1U] == DMRGWS_DMRNETWORK2 || m_status[2U] == DMRGWS_DMRNETWORK2)) m_dmrNetwork2->writeTalkerAlias(buffer, length); - if (m_dmrNetwork3 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK3 || m_status[2U] == DMRGWS_DMRNETWORK3)) + if (m_network3Enabled && (m_dmrNetwork3 != NULL) && (m_status[1U] == DMRGWS_DMRNETWORK3 || m_status[2U] == DMRGWS_DMRNETWORK3)) m_dmrNetwork3->writeTalkerAlias(buffer, length); - if (m_dmrNetwork4 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK4 || m_status[2U] == DMRGWS_DMRNETWORK4)) + if (m_network4Enabled && (m_dmrNetwork4 != NULL) && (m_status[1U] == DMRGWS_DMRNETWORK4 || m_status[2U] == DMRGWS_DMRNETWORK4)) m_dmrNetwork4->writeTalkerAlias(buffer, length); - if (m_dmrNetwork5 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK5 || m_status[2U] == DMRGWS_DMRNETWORK5)) + if (m_network5Enabled && (m_dmrNetwork5 != NULL) && (m_status[1U] == DMRGWS_DMRNETWORK5 || m_status[2U] == DMRGWS_DMRNETWORK5)) m_dmrNetwork5->writeTalkerAlias(buffer, length); } @@ -2516,3 +2569,86 @@ void CDMRGateway::processDynamicTGControl() LogWarning("Unknown dynamic TG control message: %s", buffer); } } + +void CDMRGateway::remoteControl() +{ + if (m_remoteControl == NULL) + return; + + REMOTE_COMMAND command = m_remoteControl->getCommand(); + switch (command) { + case RCD_ENABLE_NETWORK1: + processEnableCommand(m_dmrNetwork1, "DMR Network 1", m_network1Enabled, true); + break; + case RCD_ENABLE_NETWORK2: + processEnableCommand(m_dmrNetwork2, "DMR Network 2", m_network2Enabled, true); + break; + case RCD_ENABLE_NETWORK3: + processEnableCommand(m_dmrNetwork3, "DMR Network 3", m_network3Enabled, true); + break; + case RCD_ENABLE_NETWORK4: + processEnableCommand(m_dmrNetwork4, "DMR Network 4", m_network4Enabled, true); + break; + case RCD_ENABLE_NETWORK5: + processEnableCommand(m_dmrNetwork5, "DMR Network 5", m_network5Enabled, true); + break; + case RCD_ENABLE_XLX: + if (m_xlxVoice != NULL) { + m_xlxVoice->reset(); + } + processEnableCommand(m_xlxNetwork, "XLX Network", m_networkXlxEnabled, true); + break; + case RCD_DISABLE_NETWORK1: + processEnableCommand(m_dmrNetwork1, "DMR Network 1", m_network1Enabled, false); + break; + case RCD_DISABLE_NETWORK2: + processEnableCommand(m_dmrNetwork2, "DMR Network 2", m_network2Enabled, false); + break; + case RCD_DISABLE_NETWORK3: + processEnableCommand(m_dmrNetwork3, "DMR Network 3", m_network3Enabled, false); + break; + case RCD_DISABLE_NETWORK4: + processEnableCommand(m_dmrNetwork4, "DMR Network 4", m_network4Enabled, false); + break; + case RCD_DISABLE_NETWORK5: + processEnableCommand(m_dmrNetwork5, "DMR Network 5", m_network5Enabled, false); + break; + case RCD_DISABLE_XLX: + processEnableCommand(m_xlxNetwork, "XLX Network", m_networkXlxEnabled, false); + break; + default: + break; + } +} + +void CDMRGateway::processEnableCommand(CDMRNetwork* network, const std::string& name, bool& mode, bool enabled) +{ + LogDebug("Setting '%s' mode current=%s new=%s", name.c_str(), mode ? "true" : "false", enabled ? "true" : "false"); + + if (network != NULL) { + mode = enabled; + network->enable(enabled); + } +} + +void CDMRGateway::buildNetworkStatusString(std::string &str) +{ + str = ""; + buildNetworkStatusNetworkString(str, "xlx", m_xlxNetwork, m_networkXlxEnabled); + str += " "; + buildNetworkStatusNetworkString(str, "net1", m_dmrNetwork1, m_network1Enabled); + str += " "; + buildNetworkStatusNetworkString(str, "net2", m_dmrNetwork2, m_network2Enabled); + str += " "; + buildNetworkStatusNetworkString(str, "net3", m_dmrNetwork3, m_network3Enabled); + str += " "; + buildNetworkStatusNetworkString(str, "net4", m_dmrNetwork4, m_network4Enabled); + str += " "; + buildNetworkStatusNetworkString(str, "net5", m_dmrNetwork5, m_network5Enabled); +} + +void CDMRGateway::buildNetworkStatusNetworkString(std::string &str, const std::string& name, CDMRNetwork* network, bool enabled) +{ + str += name + ":"+ (((network == NULL) || (enabled == false)) ? "n/a" : (network->isConnected() ? "conn" : "disc")); +} + diff --git a/DMRGateway.h b/DMRGateway.h index d872389..9e28d0b 100644 --- a/DMRGateway.h +++ b/DMRGateway.h @@ -19,12 +19,14 @@ #if !defined(DMRGateway_H) #define DMRGateway_H +#include "RemoteControl.h" #include "RewriteDynTGNet.h" #include "RewriteDynTGRF.h" #include "MMDVMNetwork.h" #include "DMRNetwork.h" #include "APRSWriter.h" #include "Reflectors.h" +#include "XLXVoice.h" #include "UDPSocket.h" #include "RewriteTG.h" #include "DynVoice.h" @@ -53,6 +55,8 @@ public: int run(); + void buildNetworkStatusString(std::string &str); + private: CConf m_conf; DMRGW_STATUS* m_status; @@ -78,17 +82,18 @@ private: unsigned int m_xlxTG; unsigned int m_xlxBase; unsigned int m_xlxLocal; - unsigned int m_xlxPort; - std::string m_xlxPassword; + unsigned int m_xlxPort; + std::string m_xlxPassword; unsigned int m_xlxStartup; unsigned int m_xlxRoom; CTimer m_xlxRelink; bool m_xlxConnected; bool m_xlxDebug; - bool m_xlxUserControl; - char m_xlxModule; + bool m_xlxUserControl; + char m_xlxModule; CRewriteTG* m_rptRewrite; CRewriteTG* m_xlxRewrite; + CXLXVoice* m_xlxVoice; std::vector m_dmr1NetRewrites; std::vector m_dmr1RFRewrites; std::vector m_dmr1SrcRewrites; @@ -119,7 +124,14 @@ private: #if defined(USE_GPSD) CGPSD* m_gpsd; #endif - + bool m_network1Enabled; + bool m_network2Enabled; + bool m_network3Enabled; + bool m_network4Enabled; + bool m_network5Enabled; + bool m_networkXlxEnabled; + CRemoteControl* m_remoteControl; + bool createMMDVM(); bool createDMRNetwork1(); bool createDMRNetwork2(); @@ -141,6 +153,9 @@ private: void processTalkerAlias(); void createAPRS(); void processDynamicTGControl(); + void remoteControl(); + void processEnableCommand(CDMRNetwork* network, const std::string& name, bool& mode, bool enabled); + void buildNetworkStatusNetworkString(std::string &str, const std::string& name, CDMRNetwork* network, bool enabled); }; #endif diff --git a/DMRGateway.ini b/DMRGateway.ini index e19faa4..2431434 100644 --- a/DMRGateway.ini +++ b/DMRGateway.ini @@ -153,3 +153,8 @@ Suffix=3 [Dynamic TG Control] Enabled=1 Port=3769 + +[Remote Control] +Enable=0 +Address=127.0.0.1 +Port=7643 diff --git a/DMRNetwork.cpp b/DMRNetwork.cpp index f503441..4411764 100644 --- a/DMRNetwork.cpp +++ b/DMRNetwork.cpp @@ -40,6 +40,7 @@ m_name(name), m_location(location), m_debug(debug), m_socket(local), +m_enabled(false), m_status(WAITING_CONNECT), m_retryTimer(1000U, 10U), m_timeoutTimer(1000U, 60U), @@ -108,6 +109,14 @@ bool CDMRNetwork::open() return true; } +void CDMRNetwork::enable(bool enabled) +{ + if (!enabled && m_enabled) + m_rxData.clear(); + + m_enabled = enabled; +} + bool CDMRNetwork::read(CDMRData& data) { if (m_status != RUNNING) @@ -345,9 +354,11 @@ void CDMRNetwork::clock(unsigned int ms) if (m_debug) CUtils::dump(1U, "Network Received", m_buffer, length); - unsigned char len = length; - m_rxData.addData(&len, 1U); - m_rxData.addData(m_buffer, len); + if (m_enabled) { + unsigned char len = length; + m_rxData.addData(&len, 1U); + m_rxData.addData(m_buffer, len); + } } else if (::memcmp(m_buffer, "MSTNAK", 6U) == 0) { if (m_status == RUNNING) { LogWarning("%s, Login to the master has failed, retrying login ...", m_name.c_str()); diff --git a/DMRNetwork.h b/DMRNetwork.h index e496bee..8e287a5 100644 --- a/DMRNetwork.h +++ b/DMRNetwork.h @@ -39,6 +39,8 @@ public: bool open(); + void enable(bool enabled); + bool read(CDMRData& data); bool write(const CDMRData& data); @@ -66,6 +68,7 @@ private: bool m_location; bool m_debug; CUDPSocket m_socket; + bool m_enabled; enum STATUS { WAITING_CONNECT, diff --git a/Makefile b/Makefile index 06cd120..6542001 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ 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 PassAllPC.o PassAllTG.o \ - QR1676.o Reflectors.o Rewrite.o RewriteDstId.o RewriteDynTGNet.o RewriteDynTGRF.o RewritePC.o RewriteSrc.o RewriteSrcId.o \ + QR1676.o Reflectors.o RemoteControl.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 all: DMRGateway @@ -21,6 +21,9 @@ all: DMRGateway DMRGateway: GitVersion.h $(OBJECTS) $(CXX) $(OBJECTS) $(CFLAGS) $(LIBS) -o DMRGateway +RemoteCommandDMRG: Log.o RemoteCommandDMRG.o UDPSocket.o + $(CXX) Log.o RemoteCommandDMRG.o UDPSocket.o $(CFLAGS) $(LIBS) -o RemoteCommandDMRG + %.o: %.cpp $(CXX) $(CFLAGS) -c -o $@ $< diff --git a/RemoteCommandDMRG.cpp b/RemoteCommandDMRG.cpp new file mode 100644 index 0000000..fbcd39b --- /dev/null +++ b/RemoteCommandDMRG.cpp @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2019,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 "RemoteCommandDMRG.h" + +#include "UDPSocket.h" +#include "Log.h" + +#include +#include +#include + +const unsigned int BUFFER_LENGTH = 100U; + +int main(int argc, char** argv) +{ + if (argc < 3) { + ::fprintf(stderr, "Usage: RemoteCommand \n"); + return 1; + } + + unsigned int port = (unsigned int)::atoi(argv[1]); + std::string cmd = std::string(argv[2]); + + for (int i = 3; i < argc; i++) { + cmd += " "; + cmd += std::string(argv[i]); + } + + if (port == 0U) { + ::fprintf(stderr, "RemoteCommand: invalid port number - %s\n", argv[1]); + return 1; + } + + CRemoteCommandDMRG* command = new CRemoteCommandDMRG(port); + + return command->send(cmd); +} + +CRemoteCommandDMRG::CRemoteCommandDMRG(unsigned int port) : +m_port(port) +{ + CUDPSocket::startup(); + + ::LogInitialise(false, ".", "RemoteCommand", 2U, 2U, false); +} + +CRemoteCommandDMRG::~CRemoteCommandDMRG() +{ + ::LogFinalise(); + + CUDPSocket::shutdown(); +} + +int CRemoteCommandDMRG::send(const std::string& command) +{ + sockaddr_storage addr; + unsigned int addrLen; + char buffer[BUFFER_LENGTH]; + int retStatus = 0; + + if (CUDPSocket::lookup("127.0.0.1", m_port, addr, addrLen) != 0) { + LogError("Unable to resolve the address of the host"); + return 1; + } + + CUDPSocket socket(0U); + + bool ret = socket.open(addr); + if (!ret) + return 1; + + ret = socket.write((unsigned char*)command.c_str(), command.length(), addr, addrLen); + if (!ret) { + socket.close(); + return 1; + } + + LogMessage("Command sent: \"%s\" to port: %u", command.c_str(), m_port); + + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + + int len = socket.read((unsigned char*)&buffer[0], BUFFER_LENGTH, addr, addrLen); + if (len > 0) { + buffer[len] = '\0'; + LogMessage("%s", buffer); + } + else + { + retStatus = 1; + } + + socket.close(); + + return retStatus; +} diff --git a/RemoteCommandDMRG.h b/RemoteCommandDMRG.h new file mode 100644 index 0000000..cc74359 --- /dev/null +++ b/RemoteCommandDMRG.h @@ -0,0 +1,36 @@ +/* + * Copyright (C) 2019 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 RemoteCommandDMRG_H +#define RemoteCommandDMRG_H + +#include + +class CRemoteCommandDMRG +{ +public: + CRemoteCommandDMRG(unsigned int port); + ~CRemoteCommandDMRG(); + + int send(const std::string& command); + +private: + unsigned int m_port; +}; + +#endif diff --git a/RemoteControl.cpp b/RemoteControl.cpp new file mode 100644 index 0000000..0d4ad07 --- /dev/null +++ b/RemoteControl.cpp @@ -0,0 +1,166 @@ +/* + * Copyright (C) 2019,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 "RemoteControl.h" +#include "Log.h" +#include "DMRGateway.h" + +#include +#include +#include +#include + +const unsigned int ENABLE_ARGS = 2U; +const unsigned int DISABLE_ARGS = 2U; + +const unsigned int BUFFER_LENGTH = 100U; + +CRemoteControl::CRemoteControl(CDMRGateway* host, const std::string address, unsigned int port) : +m_host(host), +m_socket(address, port), +m_command(RCD_NONE), +m_args() +{ + assert(port > 0U); +} + +CRemoteControl::~CRemoteControl() +{ +} + +bool CRemoteControl::open() +{ + return m_socket.open(); +} + +REMOTE_COMMAND CRemoteControl::getCommand() +{ + m_command = RCD_NONE; + m_args.clear(); + + char command[BUFFER_LENGTH]; + char buffer[BUFFER_LENGTH * 2]; + std::string replyStr = "OK"; + sockaddr_storage address; + unsigned int addrlen; + int ret = m_socket.read((unsigned char*)buffer, BUFFER_LENGTH, address, addrlen); + if (ret > 0) { + buffer[ret] = '\0'; + + // Make a copy of the original command for logging. + ::strcpy(command, buffer); + + // Parse the original command into a vector of strings. + char* b = buffer; + char* p = NULL; + while ((p = ::strtok(b, " ")) != NULL) { + b = NULL; + m_args.push_back(std::string(p)); + } + if (m_args.at(0U) == "enable" && m_args.size() >= ENABLE_ARGS) { + if (m_args.at(1U) == "net1") + m_command = RCD_ENABLE_NETWORK1; + else if (m_args.at(1U) == "net2") + m_command = RCD_ENABLE_NETWORK2; + else if (m_args.at(1U) == "net3") + m_command = RCD_ENABLE_NETWORK3; + else if (m_args.at(1U) == "net4") + m_command = RCD_ENABLE_NETWORK4; + else if (m_args.at(1U) == "net5") + m_command = RCD_ENABLE_NETWORK5; + else if (m_args.at(1U) == "xlx") + m_command = RCD_ENABLE_XLX; + else + replyStr = "KO"; + } else if (m_args.at(0U) == "disable" && m_args.size() >= DISABLE_ARGS) { + if (m_args.at(1U) == "net1") + m_command = RCD_DISABLE_NETWORK1; + else if (m_args.at(1U) == "net2") + m_command = RCD_DISABLE_NETWORK2; + else if (m_args.at(1U) == "net3") + m_command = RCD_DISABLE_NETWORK3; + else if (m_args.at(1U) == "net4") + m_command = RCD_DISABLE_NETWORK4; + else if (m_args.at(1U) == "net5") + m_command = RCD_DISABLE_NETWORK5; + else if (m_args.at(1U) == "xlx") + m_command = RCD_DISABLE_XLX; + else + replyStr = "KO"; + } else if (m_args.at(0U) == "status") { + if (m_host != NULL) { + m_host->buildNetworkStatusString(replyStr); + } + else { + replyStr = "KO"; + } + + m_command = RCD_CONNECTION_STATUS; + } + else + replyStr = "KO"; + + ::snprintf(buffer, BUFFER_LENGTH * 2, "%s remote command of \"%s\" received", ((m_command == RCD_NONE) ? "Invalid" : "Valid"), command); + if (m_command == RCD_NONE) { + m_args.clear(); + LogWarning(buffer); + } else { + LogMessage(buffer); + } + + m_socket.write((unsigned char*)replyStr.c_str(), replyStr.length(), address, addrlen); + } + + return m_command; +} + +unsigned int CRemoteControl::getArgCount() const +{ + switch (m_command) { + default: + return 0U; + } +} + +std::string CRemoteControl::getArgString(unsigned int n) const +{ + switch (m_command) { + default: + return ""; + } + + if (n >= m_args.size()) + return ""; + + return m_args.at(n); +} + +unsigned int CRemoteControl::getArgUInt(unsigned int n) const +{ + return (unsigned int)::atoi(getArgString(n).c_str()); +} + +int CRemoteControl::getArgInt(unsigned int n) const +{ + return ::atoi(getArgString(n).c_str()); +} + +void CRemoteControl::close() +{ + m_socket.close(); +} diff --git a/RemoteControl.h b/RemoteControl.h new file mode 100644 index 0000000..9a6c646 --- /dev/null +++ b/RemoteControl.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2019,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. + */ + +#ifndef RemoteControl_H +#define RemoteControl_H + +#include "UDPSocket.h" + +#include +#include + +enum REMOTE_COMMAND { + RCD_ENABLE_NETWORK1, + RCD_ENABLE_NETWORK2, + RCD_ENABLE_NETWORK3, + RCD_ENABLE_NETWORK4, + RCD_ENABLE_NETWORK5, + RCD_ENABLE_XLX, + RCD_DISABLE_NETWORK1, + RCD_DISABLE_NETWORK2, + RCD_DISABLE_NETWORK3, + RCD_DISABLE_NETWORK4, + RCD_DISABLE_NETWORK5, + RCD_DISABLE_XLX, + RCD_CONNECTION_STATUS, + RCD_NONE +}; + +class CDMRGateway; +class CDMRNetwork; + +class CRemoteControl { +public: + CRemoteControl(CDMRGateway* host, const std::string address, unsigned int port); + ~CRemoteControl(); + + bool open(); + + REMOTE_COMMAND getCommand(); + + unsigned int getArgCount() const; + + std::string getArgString(unsigned int n) const; + unsigned int getArgUInt(unsigned int n) const; + signed int getArgInt(unsigned int n) const; + + void close(); + +private: + CDMRGateway* m_host; + CUDPSocket m_socket; + REMOTE_COMMAND m_command; + std::vector m_args; +}; + +#endif diff --git a/XLXVoice.cpp b/XLXVoice.cpp index bcc3edb..4f1506c 100644 --- a/XLXVoice.cpp +++ b/XLXVoice.cpp @@ -195,7 +195,7 @@ void CXLXVoice::createVoice(const std::vector& words) for (unsigned int i = 0U; i < ambeLength; i += AMBE_LENGTH) ::memcpy(ambeData + i, SILENCE, AMBE_LENGTH); - // Put offset in for silence at the beginning + // Put offset in for silence at the beginning unsigned int pos = SILENCE_LENGTH * AMBE_LENGTH; for (std::vector::const_iterator it = words.begin(); it != words.end(); ++it) { if (m_positions.count(*it) > 0U) { @@ -273,6 +273,19 @@ void CXLXVoice::createVoice(const std::vector& words) m_timer.start(); } +void CXLXVoice::reset() +{ + for (std::vector::iterator it = m_data.begin(); it != m_data.end(); ++it) + delete *it; + + m_timer.stop(); + m_status = XLXVS_NONE; + m_data.clear(); + m_seqNo = 0U; + m_streamId = 0U; + m_sent = 0U; +} + bool CXLXVoice::read(CDMRData& data) { if (m_status != XLXVS_SENDING) diff --git a/XLXVoice.h b/XLXVoice.h index 186d3f6..0a896e5 100644 --- a/XLXVoice.h +++ b/XLXVoice.h @@ -50,6 +50,8 @@ public: void linkedTo(unsigned int number, unsigned int room); void unlinked(); + void reset(); + bool read(CDMRData& data); void clock(unsigned int ms); From 579db99ae203ada9ee1f618fa499c576bb1f22c1 Mon Sep 17 00:00:00 2001 From: Daniel Caujolle-Bert Date: Mon, 22 Mar 2021 20:16:35 +0100 Subject: [PATCH 2/2] Remove RemoteCommandDMRG, as RemoteCommand from MMDVMHost's PR now works with DMRGatway too. --- Makefile | 3 -- RemoteCommandDMRG.cpp | 111 ------------------------------------------ RemoteCommandDMRG.h | 36 -------------- 3 files changed, 150 deletions(-) delete mode 100644 RemoteCommandDMRG.cpp delete mode 100644 RemoteCommandDMRG.h diff --git a/Makefile b/Makefile index 6542001..f3b7b2c 100644 --- a/Makefile +++ b/Makefile @@ -21,9 +21,6 @@ all: DMRGateway DMRGateway: GitVersion.h $(OBJECTS) $(CXX) $(OBJECTS) $(CFLAGS) $(LIBS) -o DMRGateway -RemoteCommandDMRG: Log.o RemoteCommandDMRG.o UDPSocket.o - $(CXX) Log.o RemoteCommandDMRG.o UDPSocket.o $(CFLAGS) $(LIBS) -o RemoteCommandDMRG - %.o: %.cpp $(CXX) $(CFLAGS) -c -o $@ $< diff --git a/RemoteCommandDMRG.cpp b/RemoteCommandDMRG.cpp deleted file mode 100644 index fbcd39b..0000000 --- a/RemoteCommandDMRG.cpp +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2019,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 "RemoteCommandDMRG.h" - -#include "UDPSocket.h" -#include "Log.h" - -#include -#include -#include - -const unsigned int BUFFER_LENGTH = 100U; - -int main(int argc, char** argv) -{ - if (argc < 3) { - ::fprintf(stderr, "Usage: RemoteCommand \n"); - return 1; - } - - unsigned int port = (unsigned int)::atoi(argv[1]); - std::string cmd = std::string(argv[2]); - - for (int i = 3; i < argc; i++) { - cmd += " "; - cmd += std::string(argv[i]); - } - - if (port == 0U) { - ::fprintf(stderr, "RemoteCommand: invalid port number - %s\n", argv[1]); - return 1; - } - - CRemoteCommandDMRG* command = new CRemoteCommandDMRG(port); - - return command->send(cmd); -} - -CRemoteCommandDMRG::CRemoteCommandDMRG(unsigned int port) : -m_port(port) -{ - CUDPSocket::startup(); - - ::LogInitialise(false, ".", "RemoteCommand", 2U, 2U, false); -} - -CRemoteCommandDMRG::~CRemoteCommandDMRG() -{ - ::LogFinalise(); - - CUDPSocket::shutdown(); -} - -int CRemoteCommandDMRG::send(const std::string& command) -{ - sockaddr_storage addr; - unsigned int addrLen; - char buffer[BUFFER_LENGTH]; - int retStatus = 0; - - if (CUDPSocket::lookup("127.0.0.1", m_port, addr, addrLen) != 0) { - LogError("Unable to resolve the address of the host"); - return 1; - } - - CUDPSocket socket(0U); - - bool ret = socket.open(addr); - if (!ret) - return 1; - - ret = socket.write((unsigned char*)command.c_str(), command.length(), addr, addrLen); - if (!ret) { - socket.close(); - return 1; - } - - LogMessage("Command sent: \"%s\" to port: %u", command.c_str(), m_port); - - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - - int len = socket.read((unsigned char*)&buffer[0], BUFFER_LENGTH, addr, addrLen); - if (len > 0) { - buffer[len] = '\0'; - LogMessage("%s", buffer); - } - else - { - retStatus = 1; - } - - socket.close(); - - return retStatus; -} diff --git a/RemoteCommandDMRG.h b/RemoteCommandDMRG.h deleted file mode 100644 index cc74359..0000000 --- a/RemoteCommandDMRG.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2019 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 RemoteCommandDMRG_H -#define RemoteCommandDMRG_H - -#include - -class CRemoteCommandDMRG -{ -public: - CRemoteCommandDMRG(unsigned int port); - ~CRemoteCommandDMRG(); - - int send(const std::string& command); - -private: - unsigned int m_port; -}; - -#endif