diff --git a/Conf.cpp b/Conf.cpp index 4d8e0ab..f74bb40 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -43,7 +43,8 @@ m_rptAddress("127.0.0.1"), m_rptPort(62032U), m_localAddress("127.0.0.1"), m_localPort(62031U), -m_timeout(10U), +m_rfTimeout(10U), +m_netTimeout(10U), m_ruleTrace(false), m_debug(false), m_voiceEnabled(true), @@ -148,7 +149,11 @@ bool CConf::read() if (::strcmp(key, "Daemon") == 0) m_daemon = ::atoi(value) == 1; else if (::strcmp(key, "Timeout") == 0) - m_timeout = (unsigned int)::atoi(value); + m_rfTimeout = m_netTimeout = (unsigned int)::atoi(value); + else if (::strcmp(key, "RFTimeout") == 0) + m_rfTimeout = (unsigned int)::atoi(value); + else if (::strcmp(key, "NetTimeout") == 0) + m_netTimeout = (unsigned int)::atoi(value); else if (::strcmp(key, "RptAddress") == 0) m_rptAddress = value; else if (::strcmp(key, "RptPort") == 0) @@ -403,9 +408,14 @@ unsigned int CConf::getLocalPort() const return m_localPort; } -unsigned int CConf::getTimeout() const +unsigned int CConf::getRFTimeout() const { - return m_timeout; + return m_rfTimeout; +} + +unsigned int CConf::getNetTimeout() const +{ + return m_netTimeout; } bool CConf::getRuleTrace() const diff --git a/Conf.h b/Conf.h index b4c2801..e208b41 100644 --- a/Conf.h +++ b/Conf.h @@ -63,7 +63,8 @@ public: // The General section bool getDaemon() const; - unsigned int getTimeout() const; + unsigned int getRFTimeout() const; + unsigned int getNetTimeout() const; std::string getRptAddress() const; unsigned int getRptPort() const; std::string getLocalAddress() const; @@ -137,7 +138,8 @@ private: unsigned int m_rptPort; std::string m_localAddress; unsigned int m_localPort; - unsigned int m_timeout; + unsigned int m_rfTimeout; + unsigned int m_netTimeout; bool m_ruleTrace; bool m_debug; diff --git a/DMRGateway.cpp b/DMRGateway.cpp index e1ab9ef..53e86e7 100644 --- a/DMRGateway.cpp +++ b/DMRGateway.cpp @@ -312,7 +312,8 @@ int CDMRGateway::run() return 1; } - unsigned int timeout = m_conf.getTimeout(); + unsigned int rfTimeout = m_conf.getRFTimeout(); + unsigned int netTimeout = m_conf.getNetTimeout(); CVoice* voice = NULL; if (m_conf.getVoiceEnabled() && m_xlxNetwork != NULL) { @@ -333,8 +334,8 @@ int CDMRGateway::run() } CTimer* timer[3U]; - timer[1U] = new CTimer(1000U, timeout); - timer[2U] = new CTimer(1000U, timeout); + timer[1U] = new CTimer(1000U); + timer[2U] = new CTimer(1000U); DMRGW_STATUS status[3U]; status[1U] = DMRGWS_NONE; @@ -442,6 +443,7 @@ int CDMRGateway::run() m_xlxRewrite->process(data, false); m_xlxNetwork->write(data); status[slotNo] = DMRGWS_XLXREFLECTOR; + timer[slotNo]->setTimeout(rfTimeout); timer[slotNo]->start(); } else if ((dstId <= (m_xlxBase + 26U) || dstId == (m_xlxBase + 1000U)) && flco == FLCO_USER_USER && slotNo == m_xlxSlot && dstId >= m_xlxBase) { dstId += 4000U; @@ -475,6 +477,7 @@ int CDMRGateway::run() } status[slotNo] = DMRGWS_XLXREFLECTOR; + timer[slotNo]->setTimeout(rfTimeout); timer[slotNo]->start(); if (voice == NULL) { @@ -527,6 +530,7 @@ int CDMRGateway::run() if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_DMRNETWORK1) { m_dmrNetwork1->write(data); status[slotNo] = DMRGWS_DMRNETWORK1; + timer[slotNo]->setTimeout(rfTimeout); timer[slotNo]->start(); } } @@ -547,6 +551,7 @@ int CDMRGateway::run() if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_DMRNETWORK2) { m_dmrNetwork2->write(data); status[slotNo] = DMRGWS_DMRNETWORK2; + timer[slotNo]->setTimeout(rfTimeout); timer[slotNo]->start(); } } @@ -567,6 +572,7 @@ int CDMRGateway::run() if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_DMRNETWORK1) { m_dmrNetwork1->write(data); status[slotNo] = DMRGWS_DMRNETWORK1; + timer[slotNo]->setTimeout(rfTimeout); timer[slotNo]->start(); } } @@ -587,6 +593,7 @@ int CDMRGateway::run() if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_DMRNETWORK2) { m_dmrNetwork2->write(data); status[slotNo] = DMRGWS_DMRNETWORK2; + timer[slotNo]->setTimeout(rfTimeout); timer[slotNo]->start(); } } @@ -606,6 +613,7 @@ int CDMRGateway::run() if (ret) { m_repeater->write(data); status[m_xlxSlot] = DMRGWS_XLXREFLECTOR; + timer[m_xlxSlot]->setTimeout(netTimeout); timer[m_xlxSlot]->start(); } else { unsigned int slotNo = data.getSlotNo(); @@ -646,9 +654,12 @@ int CDMRGateway::run() } if (rewritten) { + // Check that the rewritten slot is free to use. + slotNo = data.getSlotNo(); if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_DMRNETWORK1) { m_repeater->write(data); status[slotNo] = DMRGWS_DMRNETWORK1; + timer[slotNo]->setTimeout(netTimeout); timer[slotNo]->start(); } } @@ -691,9 +702,12 @@ int CDMRGateway::run() } if (rewritten) { + // Check that the rewritten slot is free to use. + slotNo = data.getSlotNo(); if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_DMRNETWORK2) { m_repeater->write(data); status[slotNo] = DMRGWS_DMRNETWORK2; + timer[slotNo]->setTimeout(netTimeout); timer[slotNo]->start(); } } @@ -733,6 +747,7 @@ int CDMRGateway::run() if (ret) { m_repeater->write(data); status[m_xlxSlot] = DMRGWS_XLXREFLECTOR; + timer[m_xlxSlot]->setTimeout(netTimeout); timer[m_xlxSlot]->start(); } } diff --git a/DMRGateway.ini b/DMRGateway.ini index c7506f8..275e780 100644 --- a/DMRGateway.ini +++ b/DMRGateway.ini @@ -1,5 +1,7 @@ [General] Timeout=10 +# RFTimeout=10 +# NetTimeout=7 RptAddress=127.0.0.1 RptPort=62032 LocalAddress=127.0.0.1 diff --git a/README.md b/README.md index 22d66a4..8b77c7f 100644 --- a/README.md +++ b/README.md @@ -6,4 +6,8 @@ For example, the default configuration moves the announcements from BrandMeister The rewrite rules don’t apply to the XLX reflector, where only the slot and the talk group used may be changed. The controls i.e. private calls, for altering the reflector are fixed. -It is hoped to expand the program in future to allow more functionality under the control of the sysop. +The MMDVM .ini file should have the IP address and port number of the client in the [DMR Network] settings. + +They build on 32-bit and 64-bit Linux as well as on Windows using Visual Studio 2017 on x86 and x64. + +This software is licenced under the GPL v2 and is intended for amateur and educational use only. Use of this software for commercial purposes is strictly forbidden.