Add extern dynamic TG control via UDP.

This commit is contained in:
Jonathan Naylor
2020-04-13 14:15:21 +01:00
parent 55af548e6d
commit 42afea8527
8 changed files with 129 additions and 6 deletions

View File

@@ -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<unsigned int> CConf::getDMRNetwork5PassAllTG() const
{
return m_dmrNetwork5PassAllTG;
}
bool CConf::getDynamicTGControlEnabled() const
{
return m_dynamicTGControlEnabled;
}
unsigned int CConf::getDynamicTGControlPort() const
{
return m_dynamicTGControlPort;
}

7
Conf.h
View File

@@ -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

View File

@@ -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<CIdRewriteStruct> 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<CIdRewriteStruct> 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<CIdRewriteStruct> 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<CIdRewriteStruct> 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<CIdRewriteStruct> 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<CRewriteDynTGRF*>::iterator it = m_dynRF.begin(); it != m_dynRF.end(); ++it)
(*it)->tgChange(slot, tg);
} else {
LogWarning("Unknown dynamic TG control message: %s", buffer);
}
}

View File

@@ -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<CRewrite*> m_dmr4Passalls;
std::vector<CRewrite*> m_dmr5Passalls;
std::vector<CDynVoice*> m_dynVoices;
std::vector<CRewriteDynTGRF*> 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

View File

@@ -136,3 +136,7 @@ TGRewrite=2,11,2,11,1
Password=PASSWORD
Location=0
Debug=0
[Dynamic TG Control]
Enabled=1
Port=3769

View File

@@ -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);
}
}

View File

@@ -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;

View File

@@ -19,6 +19,6 @@
#if !defined(VERSION_H)
#define VERSION_H
const char* VERSION = "20200408";
const char* VERSION = "20200413";
#endif