diff --git a/Conf.cpp b/Conf.cpp index 21ab2e4..13d9a62 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -37,7 +37,8 @@ enum SECTION { SECTION_DMR_NETWORK_3, SECTION_DMR_NETWORK_4, SECTION_DMR_NETWORK_5, - SECTION_XLX_NETWORK + SECTION_XLX_NETWORK, + SECTION_DYNAMIC_TG_CONTROL }; CConf::CConf(const std::string& file) : @@ -172,7 +173,9 @@ m_xlxNetworkStartup(4000U), m_xlxNetworkRelink(0U), m_xlxNetworkDebug(false), m_xlxNetworkUserControl(true), -m_xlxNetworkModule() +m_xlxNetworkModule(), +m_dynamicTGControlEnabled(false), +m_dynamicTGControlPort(3769U) { } @@ -216,6 +219,8 @@ bool CConf::read() section = SECTION_DMR_NETWORK_4; else if (::strncmp(buffer, "[DMR Network 5]", 15U) == 0) section = SECTION_DMR_NETWORK_5; + else if (::strncmp(buffer, "[Dynamic TG Control]", 20U) == 0) + section = SECTION_DYNAMIC_TG_CONTROL; else section = SECTION_NONE; @@ -936,6 +941,11 @@ bool CConf::read() unsigned int slotNo = (unsigned int)::atoi(value); m_dmrNetwork5PassAllTG.push_back(slotNo); } + } else if (section == SECTION_DYNAMIC_TG_CONTROL) { + if (::strcmp(key, "Enabled") == 0) + m_dynamicTGControlEnabled = ::atoi(value) == 1; + else if (::strcmp(key, "Port") == 0) + m_dynamicTGControlPort = (unsigned int)::atoi(value); } } @@ -1611,3 +1621,13 @@ std::vector CConf::getDMRNetwork5PassAllTG() const { return m_dmrNetwork5PassAllTG; } + +bool CConf::getDynamicTGControlEnabled() const +{ + return m_dynamicTGControlEnabled; +} + +unsigned int CConf::getDynamicTGControlPort() const +{ + return m_dynamicTGControlPort; +} diff --git a/Conf.h b/Conf.h index 30c85db..b038329 100644 --- a/Conf.h +++ b/Conf.h @@ -228,6 +228,10 @@ public: bool getXLXNetworkUserControl() const; char getXLXNetworkModule() const; + // The Dynamic TG Control section + bool getDynamicTGControlEnabled() const; + unsigned int getDynamicTGControlPort() const; + private: std::string m_file; bool m_daemon; @@ -370,6 +374,9 @@ private: bool m_xlxNetworkDebug; bool m_xlxNetworkUserControl; char m_xlxNetworkModule; + + bool m_dynamicTGControlEnabled; + unsigned int m_dynamicTGControlPort; }; #endif diff --git a/DMRGateway.cpp b/DMRGateway.cpp index c3621d6..0adb93b 100644 --- a/DMRGateway.cpp +++ b/DMRGateway.cpp @@ -24,8 +24,6 @@ #include "RewritePC.h" #include "RewriteSrcId.h" #include "RewriteDstId.h" -#include "RewriteDynTGNet.h" -#include "RewriteDynTGRF.h" #include "PassAllPC.h" #include "PassAllTG.h" #include "DMRFullLC.h" @@ -181,7 +179,9 @@ m_dmr2Passalls(), m_dmr3Passalls(), m_dmr4Passalls(), m_dmr5Passalls(), -m_dynVoices() +m_dynVoices(), +m_dynRF(), +m_socket(NULL) { m_status = new DMRGW_STATUS[3U]; m_status[1U] = DMRGWS_NONE; @@ -430,6 +430,12 @@ int CDMRGateway::run() return 1; } + if (m_conf.getDynamicTGControlEnabled()) { + bool ret = createDynamicTGControl(); + if (!ret) + return 1; + } + unsigned int rfTimeout = m_conf.getRFTimeout(); unsigned int netTimeout = m_conf.getNetTimeout(); @@ -1133,6 +1139,9 @@ int CDMRGateway::run() m_repeater->write(data); } + if (m_socket != NULL) + processDynamicTGControl(); + unsigned int ms = stopWatch.elapsed(); stopWatch.start(); @@ -1214,6 +1223,11 @@ int CDMRGateway::run() delete m_xlxNetwork; } + if (m_socket != NULL) { + m_socket->close(); + delete m_socket; + } + delete timer[1U]; delete timer[2U]; @@ -1377,6 +1391,7 @@ bool CDMRGateway::createDMRNetwork1() m_dmr1RFRewrites.push_back(rfRewriteDynTG); m_dmr1NetRewrites.push_back(netRewriteDynTG); + m_dynRF.push_back(rfRewriteDynTG); } std::vector idRewrites = m_conf.getDMRNetwork1IdRewrites(); @@ -1544,6 +1559,7 @@ bool CDMRGateway::createDMRNetwork2() m_dmr2RFRewrites.push_back(rfRewriteDynTG); m_dmr2NetRewrites.push_back(netRewriteDynTG); + m_dynRF.push_back(rfRewriteDynTG); } std::vector idRewrites = m_conf.getDMRNetwork2IdRewrites(); @@ -1711,6 +1727,7 @@ bool CDMRGateway::createDMRNetwork3() m_dmr3RFRewrites.push_back(rfRewriteDynTG); m_dmr3NetRewrites.push_back(netRewriteDynTG); + m_dynRF.push_back(rfRewriteDynTG); } std::vector idRewrites = m_conf.getDMRNetwork3IdRewrites(); @@ -1878,6 +1895,7 @@ bool CDMRGateway::createDMRNetwork4() m_dmr4RFRewrites.push_back(rfRewriteDynTG); m_dmr4NetRewrites.push_back(netRewriteDynTG); + m_dynRF.push_back(rfRewriteDynTG); } std::vector idRewrites = m_conf.getDMRNetwork4IdRewrites(); @@ -2045,6 +2063,7 @@ bool CDMRGateway::createDMRNetwork5() m_dmr5RFRewrites.push_back(rfRewriteDynTG); m_dmr5NetRewrites.push_back(netRewriteDynTG); + m_dynRF.push_back(rfRewriteDynTG); } std::vector idRewrites = m_conf.getDMRNetwork5IdRewrites(); @@ -2153,6 +2172,22 @@ bool CDMRGateway::createXLXNetwork() return true; } +bool CDMRGateway::createDynamicTGControl() +{ + unsigned int port = m_conf.getDynamicTGControlPort(); + + m_socket = new CUDPSocket(port); + + bool ret = m_socket->open(); + if (!ret) { + delete m_socket; + m_socket = NULL; + return false; + } + + return true; +} + bool CDMRGateway::linkXLX(unsigned int number) { CReflector* reflector = m_xlxReflectors->find(number); @@ -2395,3 +2430,34 @@ void CDMRGateway::processHomePosition() if (m_dmrNetwork5 != NULL) m_dmrNetwork5->writeHomePosition(buffer, length); } + +void CDMRGateway::processDynamicTGControl() +{ + unsigned char buffer[100U]; + in_addr address; + unsigned int port; + + int len = m_socket->read(buffer, 100U, address, port); + if (len <= 0) + return; + + buffer[len] = '\0'; + + if (::memcmp(buffer + 0U, "DynTG", 5U) == 0) { + char* pSlot = ::strtok((char*)(buffer + 5U), ", \r\n"); + char* pTG = ::strtok(NULL, ", \r\n"); + + if (pSlot == NULL || pTG == NULL) { + LogWarning("Malformed dynamic TG control message"); + return; + } + + unsigned int slot = (unsigned int)::atoi(pSlot); + unsigned int tg = (unsigned int)::atoi(pTG); + + for (std::vector::iterator it = m_dynRF.begin(); it != m_dynRF.end(); ++it) + (*it)->tgChange(slot, tg); + } else { + LogWarning("Unknown dynamic TG control message: %s", buffer); + } +} diff --git a/DMRGateway.h b/DMRGateway.h index fd5c6b3..0312e5b 100644 --- a/DMRGateway.h +++ b/DMRGateway.h @@ -20,9 +20,12 @@ #define DMRGateway_H #include "RepeaterProtocol.h" +#include "RewriteDynTGNet.h" +#include "RewriteDynTGRF.h" #include "MMDVMNetwork.h" #include "DMRNetwork.h" #include "Reflectors.h" +#include "UDPSocket.h" #include "RewriteTG.h" #include "DynVoice.h" #include "Rewrite.h" @@ -106,6 +109,8 @@ private: std::vector m_dmr4Passalls; std::vector m_dmr5Passalls; std::vector m_dynVoices; + std::vector m_dynRF; + CUDPSocket* m_socket; bool createMMDVM(); bool createDMRNetwork1(); @@ -114,6 +119,7 @@ private: bool createDMRNetwork4(); bool createDMRNetwork5(); bool createXLXNetwork(); + bool createDynamicTGControl(); bool linkXLX(unsigned int number); void unlinkXLX(); @@ -126,6 +132,7 @@ private: void processRadioPosition(); void processTalkerAlias(); void processHomePosition(); + void processDynamicTGControl(); }; #endif diff --git a/DMRGateway.ini b/DMRGateway.ini index d9b339d..675e5f9 100644 --- a/DMRGateway.ini +++ b/DMRGateway.ini @@ -136,3 +136,7 @@ TGRewrite=2,11,2,11,1 Password=PASSWORD Location=0 Debug=0 + +[Dynamic TG Control] +Enabled=1 +Port=3769 diff --git a/RewriteDynTGRF.cpp b/RewriteDynTGRF.cpp index 1af6d20..1aa8796 100644 --- a/RewriteDynTGRF.cpp +++ b/RewriteDynTGRF.cpp @@ -143,3 +143,20 @@ PROCESS_RESULT CRewriteDynTGRF::process(CDMRData& data, bool trace) return RESULT_UNMATCHED; } + +void CRewriteDynTGRF::tgChange(unsigned int slot, unsigned int tg) +{ + if (slot == m_slot && tg == m_discPC && m_currentTG != 0U) { + m_currentTG = 0U; + m_rewriteNet->setCurrentTG(0U); + if (m_voice != NULL) + m_voice->unlinked(); + } + + if (slot == m_slot && tg >= m_fromTGStart && tg <= m_fromTGEnd && m_currentTG != tg) { + m_currentTG = tg; + m_rewriteNet->setCurrentTG(tg); + if (m_voice != NULL) + m_voice->linkedTo(tg); + } +} \ No newline at end of file diff --git a/RewriteDynTGRF.h b/RewriteDynTGRF.h index 8e6a8d4..d263e84 100644 --- a/RewriteDynTGRF.h +++ b/RewriteDynTGRF.h @@ -35,6 +35,8 @@ public: virtual PROCESS_RESULT process(CDMRData& data, bool trace); + void tgChange(unsigned int slot, unsigned int tg); + private: std::string m_name; unsigned int m_slot; diff --git a/Version.h b/Version.h index 394903b..1442d4b 100644 --- a/Version.h +++ b/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20200408"; +const char* VERSION = "20200413"; #endif