Add a fifth DMR network. This has not been tested nor even compiled.

This commit is contained in:
Jonathan Naylor 2019-07-17 08:21:52 +01:00
parent 4204bd1091
commit 82d0b06db1
7 changed files with 593 additions and 58 deletions

205
Conf.cpp
View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2015-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
@ -36,6 +36,7 @@ enum SECTION {
SECTION_DMR_NETWORK_2,
SECTION_DMR_NETWORK_3,
SECTION_DMR_NETWORK_4,
SECTION_DMR_NETWORK_5,
SECTION_XLX_NETWORK
};
@ -135,6 +136,23 @@ m_dmrNetwork4SrcRewrites(),
m_dmrNetwork4IdRewrites(),
m_dmrNetwork4PassAllPC(),
m_dmrNetwork4PassAllTG(),
m_dmrNetwork5Enabled(false),
m_dmrNetwork5Name(),
m_dmrNetwork5Id(0U),
m_dmrNetwork5Address(),
m_dmrNetwork5Port(0U),
m_dmrNetwork5Local(0U),
m_dmrNetwork5Password(),
m_dmrNetwork5Options(),
m_dmrNetwork5Location(true),
m_dmrNetwork5Debug(false),
m_dmrNetwork5TGRewrites(),
m_dmrNetwork5PCRewrites(),
m_dmrNetwork5TypeRewrites(),
m_dmrNetwork5SrcRewrites(),
m_dmrNetwork5IdRewrites(),
m_dmrNetwork5PassAllPC(),
m_dmrNetwork5PassAllTG(),
m_xlxNetworkEnabled(false),
m_xlxNetworkId(0U),
m_xlxNetworkFile(),
@ -191,6 +209,8 @@ bool CConf::read()
section = SECTION_DMR_NETWORK_3;
else if (::strncmp(buffer, "[DMR Network 4]", 15U) == 0)
section = SECTION_DMR_NETWORK_4;
else if (::strncmp(buffer, "[DMR Network 5]", 15U) == 0)
section = SECTION_DMR_NETWORK_5;
else
section = SECTION_NONE;
@ -681,6 +701,101 @@ bool CConf::read()
unsigned int slotNo = (unsigned int)::atoi(value);
m_dmrNetwork4PassAllTG.push_back(slotNo);
}
} else if (section == SECTION_DMR_NETWORK_5) {
if (::strcmp(key, "Enabled") == 0)
m_dmrNetwork5Enabled = ::atoi(value) == 1;
else if (::strcmp(key, "Name") == 0)
m_dmrNetwork5Name = value;
else if (::strcmp(key, "Id") == 0)
m_dmrNetwork5Id = (unsigned int)::atoi(value);
else if (::strcmp(key, "Address") == 0)
m_dmrNetwork5Address = value;
else if (::strcmp(key, "Port") == 0)
m_dmrNetwork5Port = (unsigned int)::atoi(value);
else if (::strcmp(key, "Local") == 0)
m_dmrNetwork5Local = (unsigned int)::atoi(value);
else if (::strcmp(key, "Password") == 0)
m_dmrNetwork5Password = value;
else if (::strcmp(key, "Options") == 0)
m_dmrNetwork5Options = value;
else if (::strcmp(key, "Location") == 0)
m_dmrNetwork5Location = ::atoi(value) == 1;
else if (::strcmp(key, "Debug") == 0)
m_dmrNetwork5Debug = ::atoi(value) == 1;
else if (::strncmp(key, "TGRewrite", 9U) == 0) {
char* p1 = ::strtok(value, ", ");
char* p2 = ::strtok(NULL, ", ");
char* p3 = ::strtok(NULL, ", ");
char* p4 = ::strtok(NULL, ", ");
char* p5 = ::strtok(NULL, " \r\n");
if (p1 != NULL && p2 != NULL && p3 != NULL && p4 != NULL && p5 != NULL) {
CTGRewriteStruct rewrite;
rewrite.m_fromSlot = ::atoi(p1);
rewrite.m_fromTG = ::atoi(p2);
rewrite.m_toSlot = ::atoi(p3);
rewrite.m_toTG = ::atoi(p4);
rewrite.m_range = ::atoi(p5);
m_dmrNetwork5TGRewrites.push_back(rewrite);
}
} else if (::strncmp(key, "PCRewrite", 9U) == 0) {
char* p1 = ::strtok(value, ", ");
char* p2 = ::strtok(NULL, ", ");
char* p3 = ::strtok(NULL, ", ");
char* p4 = ::strtok(NULL, ", ");
char* p5 = ::strtok(NULL, " \r\n");
if (p1 != NULL && p2 != NULL && p3 != NULL && p4 != NULL && p5 != NULL) {
CPCRewriteStruct rewrite;
rewrite.m_fromSlot = ::atoi(p1);
rewrite.m_fromId = ::atoi(p2);
rewrite.m_toSlot = ::atoi(p3);
rewrite.m_toId = ::atoi(p4);
rewrite.m_range = ::atoi(p5);
m_dmrNetwork5PCRewrites.push_back(rewrite);
}
} else if (::strncmp(key, "TypeRewrite", 11U) == 0) {
char* p1 = ::strtok(value, ", ");
char* p2 = ::strtok(NULL, ", ");
char* p3 = ::strtok(NULL, ", ");
char* p4 = ::strtok(NULL, " \r\n");
if (p1 != NULL && p2 != NULL && p3 != NULL && p4 != NULL) {
CTypeRewriteStruct rewrite;
rewrite.m_fromSlot = ::atoi(p1);
rewrite.m_fromTG = ::atoi(p2);
rewrite.m_toSlot = ::atoi(p3);
rewrite.m_toId = ::atoi(p4);
m_dmrNetwork5TypeRewrites.push_back(rewrite);
}
} else if (::strncmp(key, "SrcRewrite", 10U) == 0) {
char* p1 = ::strtok(value, ", ");
char* p2 = ::strtok(NULL, ", ");
char* p3 = ::strtok(NULL, ", ");
char* p4 = ::strtok(NULL, ", ");
char* p5 = ::strtok(NULL, " \r\n");
if (p1 != NULL && p2 != NULL && p3 != NULL && p4 != NULL && p5 != NULL) {
CSrcRewriteStruct rewrite;
rewrite.m_fromSlot = ::atoi(p1);
rewrite.m_fromId = ::atoi(p2);
rewrite.m_toSlot = ::atoi(p3);
rewrite.m_toTG = ::atoi(p4);
rewrite.m_range = ::atoi(p5);
m_dmrNetwork5SrcRewrites.push_back(rewrite);
}
} else if (::strncmp(key, "IdRewrite", 9U) == 0) {
char* rfId = ::strtok(value, ", ");
char* netId = ::strtok(NULL, " \r\n");
if (rfId != NULL && netId != NULL) {
CIdRewriteStruct rewrite;
rewrite.m_rfId = ::atoi(rfId);
rewrite.m_netId = ::atoi(netId);
m_dmrNetwork5IdRewrites.push_back(rewrite);
}
} else if (::strncmp(key, "PassAllPC", 9U) == 0) {
unsigned int slotNo = (unsigned int)::atoi(value);
m_dmrNetwork5PassAllPC.push_back(slotNo);
} else if (::strncmp(key, "PassAllTG", 9U) == 0) {
unsigned int slotNo = (unsigned int)::atoi(value);
m_dmrNetwork5PassAllTG.push_back(slotNo);
}
}
}
@ -1243,3 +1358,91 @@ std::vector<unsigned int> CConf::getDMRNetwork4PassAllTG() const
{
return m_dmrNetwork4PassAllTG;
}
bool CConf::getDMRNetwork5Enabled() const
{
return m_dmrNetwork5Enabled;
}
std::string CConf::getDMRNetwork5Name() const
{
if (m_dmrNetwork5Name.empty())
return "DMR-5";
else
return m_dmrNetwork5Name;
}
unsigned int CConf::getDMRNetwork5Id() const
{
return m_dmrNetwork5Id;
}
std::string CConf::getDMRNetwork5Address() const
{
return m_dmrNetwork5Address;
}
unsigned int CConf::getDMRNetwork5Port() const
{
return m_dmrNetwork5Port;
}
unsigned int CConf::getDMRNetwork5Local() const
{
return m_dmrNetwork5Local;
}
std::string CConf::getDMRNetwork5Password() const
{
return m_dmrNetwork5Password;
}
std::string CConf::getDMRNetwork5Options() const
{
return m_dmrNetwork5Options;
}
bool CConf::getDMRNetwork5Location() const
{
return m_dmrNetwork5Location;
}
bool CConf::getDMRNetwork5Debug() const
{
return m_dmrNetwork5Debug;
}
std::vector<CTGRewriteStruct> CConf::getDMRNetwork5TGRewrites() const
{
return m_dmrNetwork5TGRewrites;
}
std::vector<CPCRewriteStruct> CConf::getDMRNetwork5PCRewrites() const
{
return m_dmrNetwork5PCRewrites;
}
std::vector<CTypeRewriteStruct> CConf::getDMRNetwork5TypeRewrites() const
{
return m_dmrNetwork5TypeRewrites;
}
std::vector<CSrcRewriteStruct> CConf::getDMRNetwork5SrcRewrites() const
{
return m_dmrNetwork5SrcRewrites;
}
std::vector<CIdRewriteStruct> CConf::getDMRNetwork5IdRewrites() const
{
return m_dmrNetwork5IdRewrites;
}
std::vector<unsigned int> CConf::getDMRNetwork5PassAllPC() const
{
return m_dmrNetwork5PassAllPC;
}
std::vector<unsigned int> CConf::getDMRNetwork5PassAllTG() const
{
return m_dmrNetwork5PassAllTG;
}

55
Conf.h
View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,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
@ -115,7 +115,7 @@ public:
std::vector<CPCRewriteStruct> getDMRNetwork1PCRewrites() const;
std::vector<CTypeRewriteStruct> getDMRNetwork1TypeRewrites() const;
std::vector<CSrcRewriteStruct> getDMRNetwork1SrcRewrites() const;
std::vector<CIdRewriteStruct> getDMRNetwork1IdRewrites() const;
std::vector<CIdRewriteStruct> getDMRNetwork1IdRewrites() const;
std::vector<unsigned int> getDMRNetwork1PassAllPC() const;
std::vector<unsigned int> getDMRNetwork1PassAllTG() const;
@ -134,7 +134,7 @@ public:
std::vector<CPCRewriteStruct> getDMRNetwork2PCRewrites() const;
std::vector<CTypeRewriteStruct> getDMRNetwork2TypeRewrites() const;
std::vector<CSrcRewriteStruct> getDMRNetwork2SrcRewrites() const;
std::vector<CIdRewriteStruct> getDMRNetwork2IdRewrites() const;
std::vector<CIdRewriteStruct> getDMRNetwork2IdRewrites() const;
std::vector<unsigned int> getDMRNetwork2PassAllPC() const;
std::vector<unsigned int> getDMRNetwork2PassAllTG() const;
@ -153,7 +153,7 @@ public:
std::vector<CPCRewriteStruct> getDMRNetwork3PCRewrites() const;
std::vector<CTypeRewriteStruct> getDMRNetwork3TypeRewrites() const;
std::vector<CSrcRewriteStruct> getDMRNetwork3SrcRewrites() const;
std::vector<CIdRewriteStruct> getDMRNetwork3IdRewrites() const;
std::vector<CIdRewriteStruct> getDMRNetwork3IdRewrites() const;
std::vector<unsigned int> getDMRNetwork3PassAllPC() const;
std::vector<unsigned int> getDMRNetwork3PassAllTG() const;
@ -172,10 +172,29 @@ public:
std::vector<CPCRewriteStruct> getDMRNetwork4PCRewrites() const;
std::vector<CTypeRewriteStruct> getDMRNetwork4TypeRewrites() const;
std::vector<CSrcRewriteStruct> getDMRNetwork4SrcRewrites() const;
std::vector<CIdRewriteStruct> getDMRNetwork4IdRewrites() const;
std::vector<CIdRewriteStruct> getDMRNetwork4IdRewrites() const;
std::vector<unsigned int> getDMRNetwork4PassAllPC() const;
std::vector<unsigned int> getDMRNetwork4PassAllTG() const;
// The DMR Network 5 section
bool getDMRNetwork5Enabled() const;
std::string getDMRNetwork5Name() const;
unsigned int getDMRNetwork5Id() const;
std::string getDMRNetwork5Address() const;
unsigned int getDMRNetwork5Port() const;
unsigned int getDMRNetwork5Local() const;
std::string getDMRNetwork5Password() const;
std::string getDMRNetwork5Options() const;
bool getDMRNetwork5Location() const;
bool getDMRNetwork5Debug() const;
std::vector<CTGRewriteStruct> getDMRNetwork5TGRewrites() const;
std::vector<CPCRewriteStruct> getDMRNetwork5PCRewrites() const;
std::vector<CTypeRewriteStruct> getDMRNetwork5TypeRewrites() const;
std::vector<CSrcRewriteStruct> getDMRNetwork5SrcRewrites() const;
std::vector<CIdRewriteStruct> getDMRNetwork5IdRewrites() const;
std::vector<unsigned int> getDMRNetwork5PassAllPC() const;
std::vector<unsigned int> getDMRNetwork5PassAllTG() const;
// The XLX Network section
bool getXLXNetworkEnabled() const;
unsigned int getXLXNetworkId() const;
@ -239,7 +258,7 @@ private:
std::vector<CPCRewriteStruct> m_dmrNetwork1PCRewrites;
std::vector<CTypeRewriteStruct> m_dmrNetwork1TypeRewrites;
std::vector<CSrcRewriteStruct> m_dmrNetwork1SrcRewrites;
std::vector<CIdRewriteStruct> m_dmrNetwork1IdRewrites;
std::vector<CIdRewriteStruct> m_dmrNetwork1IdRewrites;
std::vector<unsigned int> m_dmrNetwork1PassAllPC;
std::vector<unsigned int> m_dmrNetwork1PassAllTG;
@ -257,7 +276,7 @@ private:
std::vector<CPCRewriteStruct> m_dmrNetwork2PCRewrites;
std::vector<CTypeRewriteStruct> m_dmrNetwork2TypeRewrites;
std::vector<CSrcRewriteStruct> m_dmrNetwork2SrcRewrites;
std::vector<CIdRewriteStruct> m_dmrNetwork2IdRewrites;
std::vector<CIdRewriteStruct> m_dmrNetwork2IdRewrites;
std::vector<unsigned int> m_dmrNetwork2PassAllPC;
std::vector<unsigned int> m_dmrNetwork2PassAllTG;
@ -275,7 +294,7 @@ private:
std::vector<CPCRewriteStruct> m_dmrNetwork3PCRewrites;
std::vector<CTypeRewriteStruct> m_dmrNetwork3TypeRewrites;
std::vector<CSrcRewriteStruct> m_dmrNetwork3SrcRewrites;
std::vector<CIdRewriteStruct> m_dmrNetwork3IdRewrites;
std::vector<CIdRewriteStruct> m_dmrNetwork3IdRewrites;
std::vector<unsigned int> m_dmrNetwork3PassAllPC;
std::vector<unsigned int> m_dmrNetwork3PassAllTG;
@ -293,10 +312,28 @@ private:
std::vector<CPCRewriteStruct> m_dmrNetwork4PCRewrites;
std::vector<CTypeRewriteStruct> m_dmrNetwork4TypeRewrites;
std::vector<CSrcRewriteStruct> m_dmrNetwork4SrcRewrites;
std::vector<CIdRewriteStruct> m_dmrNetwork4IdRewrites;
std::vector<CIdRewriteStruct> m_dmrNetwork4IdRewrites;
std::vector<unsigned int> m_dmrNetwork4PassAllPC;
std::vector<unsigned int> m_dmrNetwork4PassAllTG;
bool m_dmrNetwork5Enabled;
std::string m_dmrNetwork5Name;
unsigned int m_dmrNetwork5Id;
std::string m_dmrNetwork5Address;
unsigned int m_dmrNetwork5Port;
unsigned int m_dmrNetwork5Local;
std::string m_dmrNetwork5Password;
std::string m_dmrNetwork5Options;
bool m_dmrNetwork5Location;
bool m_dmrNetwork5Debug;
std::vector<CTGRewriteStruct> m_dmrNetwork5TGRewrites;
std::vector<CPCRewriteStruct> m_dmrNetwork5PCRewrites;
std::vector<CTypeRewriteStruct> m_dmrNetwork5TypeRewrites;
std::vector<CSrcRewriteStruct> m_dmrNetwork5SrcRewrites;
std::vector<CIdRewriteStruct> m_dmrNetwork5IdRewrites;
std::vector<unsigned int> m_dmrNetwork5PassAllPC;
std::vector<unsigned int> m_dmrNetwork5PassAllTG;
bool m_xlxNetworkEnabled;
unsigned int m_xlxNetworkId;
std::string m_xlxNetworkFile;

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX
* Copyright (C) 2015-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
@ -74,6 +74,7 @@ enum DMRGW_STATUS {
DMRGWS_DMRNETWORK2,
DMRGWS_DMRNETWORK3,
DMRGWS_DMRNETWORK4,
DMRGWS_DMRNETWORK5,
DMRGWS_XLXREFLECTOR
};
@ -145,6 +146,8 @@ m_dmrNetwork3(NULL),
m_dmr3Name(),
m_dmrNetwork4(NULL),
m_dmr4Name(),
m_dmrNetwork5(NULL),
m_dmr5Name(),
m_xlxReflectors(NULL),
m_xlxNetwork(NULL),
m_xlxId(0U),
@ -177,9 +180,14 @@ m_dmr3SrcRewrites(),
m_dmr4NetRewrites(),
m_dmr4RFRewrites(),
m_dmr4SrcRewrites(),
m_dmr5NetRewrites(),
m_dmr5RFRewrites(),
m_dmr5SrcRewrites(),
m_dmr1Passalls(),
m_dmr2Passalls(),
m_dmr3Passalls()
m_dmr3Passalls(),
m_dmr4Passalls(),
m_dmr5Passalls()
{
m_config = new unsigned char[400U];
}
@ -222,6 +230,15 @@ CDMRGateway::~CDMRGateway()
for (std::vector<CRewrite*>::iterator it = m_dmr4SrcRewrites.begin(); it != m_dmr4SrcRewrites.end(); ++it)
delete *it;
for (std::vector<CRewrite*>::iterator it = m_dmr5NetRewrites.begin(); it != m_dmr5NetRewrites.end(); ++it)
delete *it;
for (std::vector<CRewrite*>::iterator it = m_dmr5RFRewrites.begin(); it != m_dmr5RFRewrites.end(); ++it)
delete *it;
for (std::vector<CRewrite*>::iterator it = m_dmr5SrcRewrites.begin(); it != m_dmr5SrcRewrites.end(); ++it)
delete *it;
for (std::vector<CRewrite*>::iterator it = m_dmr1Passalls.begin(); it != m_dmr1Passalls.end(); ++it)
delete *it;
@ -234,6 +251,9 @@ CDMRGateway::~CDMRGateway()
for (std::vector<CRewrite*>::iterator it = m_dmr4Passalls.begin(); it != m_dmr4Passalls.end(); ++it)
delete *it;
for (std::vector<CRewrite*>::iterator it = m_dmr5Passalls.begin(); it != m_dmr5Passalls.end(); ++it)
delete *it;
delete m_rptRewrite;
delete m_xlxRewrite;
@ -376,6 +396,12 @@ int CDMRGateway::run()
return 1;
}
if (m_conf.getDMRNetwork5Enabled()) {
ret = createDMRNetwork5();
if (!ret)
return 1;
}
if (m_conf.getXLXNetworkEnabled()) {
ret = createXLXNetwork();
if (!ret)
@ -431,6 +457,10 @@ int CDMRGateway::run()
unsigned int dmr4DstId[3U];
dmr4SrcId[1U] = dmr4SrcId[2U] = dmr4DstId[1U] = dmr4DstId[2U] = 0U;
unsigned int dmr5SrcId[3U];
unsigned int dmr5DstId[3U];
dmr5SrcId[1U] = dmr5SrcId[2U] = dmr5DstId[1U] = dmr5DstId[2U] = 0U;
CStopWatch stopWatch;
stopWatch.start();
@ -635,49 +665,72 @@ int CDMRGateway::run()
}
}
}
}
if (!rewritten) {
if (m_dmrNetwork3 != NULL) {
// Rewrite the slot and/or TG or neither
for (std::vector<CRewrite*>::iterator it = m_dmr3RFRewrites.begin(); it != m_dmr3RFRewrites.end(); ++it) {
bool ret = (*it)->process(data, trace);
if (ret) {
rewritten = true;
break;
}
}
if (rewritten) {
if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_DMRNETWORK3) {
rewrite(m_dmr3SrcRewrites, data, trace);
m_dmrNetwork3->write(data);
status[slotNo] = DMRGWS_DMRNETWORK3;
timer[slotNo]->setTimeout(rfTimeout);
timer[slotNo]->start();
}
if (!rewritten) {
if (m_dmrNetwork3 != NULL) {
// Rewrite the slot and/or TG or neither
for (std::vector<CRewrite*>::iterator it = m_dmr3RFRewrites.begin(); it != m_dmr3RFRewrites.end(); ++it) {
bool ret = (*it)->process(data, trace);
if (ret) {
rewritten = true;
break;
}
}
if (!rewritten) {
if (m_dmrNetwork4 != NULL) {
// Rewrite the slot and/or TG or neither
for (std::vector<CRewrite*>::iterator it = m_dmr4RFRewrites.begin(); it != m_dmr4RFRewrites.end(); ++it) {
bool ret = (*it)->process(data, trace);
if (ret) {
rewritten = true;
break;
}
}
if (rewritten) {
if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_DMRNETWORK3) {
rewrite(m_dmr3SrcRewrites, data, trace);
m_dmrNetwork3->write(data);
status[slotNo] = DMRGWS_DMRNETWORK3;
timer[slotNo]->setTimeout(rfTimeout);
timer[slotNo]->start();
}
}
}
}
if (rewritten) {
if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_DMRNETWORK4) {
rewrite(m_dmr4SrcRewrites, data, trace);
m_dmrNetwork4->write(data);
status[slotNo] = DMRGWS_DMRNETWORK4;
timer[slotNo]->setTimeout(rfTimeout);
timer[slotNo]->start();
}
}
if (!rewritten) {
if (m_dmrNetwork4 != NULL) {
// Rewrite the slot and/or TG or neither
for (std::vector<CRewrite*>::iterator it = m_dmr4RFRewrites.begin(); it != m_dmr4RFRewrites.end(); ++it) {
bool ret = (*it)->process(data, trace);
if (ret) {
rewritten = true;
break;
}
}
if (rewritten) {
if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_DMRNETWORK4) {
rewrite(m_dmr4SrcRewrites, data, trace);
m_dmrNetwork4->write(data);
status[slotNo] = DMRGWS_DMRNETWORK4;
timer[slotNo]->setTimeout(rfTimeout);
timer[slotNo]->start();
}
}
}
}
if (!rewritten) {
if (m_dmrNetwork5 != NULL) {
// Rewrite the slot and/or TG or neither
for (std::vector<CRewrite*>::iterator it = m_dmr5RFRewrites.begin(); it != m_dmr5RFRewrites.end(); ++it) {
bool ret = (*it)->process(data, trace);
if (ret) {
rewritten = true;
break;
}
}
if (rewritten) {
if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_DMRNETWORK5) {
rewrite(m_dmr5SrcRewrites, data, trace);
m_dmrNetwork5->write(data);
status[slotNo] = DMRGWS_DMRNETWORK5;
timer[slotNo]->setTimeout(rfTimeout);
timer[slotNo]->start();
}
}
}
@ -771,6 +824,28 @@ int CDMRGateway::run()
}
}
if (!rewritten) {
if (m_dmrNetwork5 != NULL) {
for (std::vector<CRewrite*>::iterator it = m_dmr5Passalls.begin(); it != m_dmr5Passalls.end(); ++it) {
bool ret = (*it)->process(data, trace);
if (ret) {
rewritten = true;
break;
}
}
if (rewritten) {
if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_DMRNETWORK5) {
rewrite(m_dmr5SrcRewrites, data, trace);
m_dmrNetwork5->write(data);
status[slotNo] = DMRGWS_DMRNETWORK5;
timer[slotNo]->setTimeout(rfTimeout);
timer[slotNo]->start();
}
}
}
}
if (!rewritten && trace)
LogDebug("Rule Trace,\tnot matched so rejected");
}
@ -988,6 +1063,54 @@ int CDMRGateway::run()
m_repeater->writeBeacon();
}
if (m_dmrNetwork5 != NULL) {
ret = m_dmrNetwork5->read(data);
if (ret) {
unsigned int slotNo = data.getSlotNo();
unsigned int srcId = data.getSrcId();
unsigned int dstId = data.getDstId();
FLCO flco = data.getFLCO();
bool trace = false;
if (ruleTrace && (srcId != dmr5SrcId[slotNo] || dstId != dmr5DstId[slotNo])) {
dmr5SrcId[slotNo] = srcId;
dmr5DstId[slotNo] = dstId;
trace = true;
}
if (trace)
LogDebug("Rule Trace, network 5 transmission: Slot=%u Src=%u Dst=%s%u", slotNo, srcId, flco == FLCO_GROUP ? "TG" : "", dstId);
// Rewrite the slot and/or TG or neither
bool rewritten = false;
for (std::vector<CRewrite*>::iterator it = m_dmr5NetRewrites.begin(); it != m_dmr5NetRewrites.end(); ++it) {
bool ret = (*it)->process(data, trace);
if (ret) {
rewritten = true;
break;
}
}
if (rewritten) {
// Check that the rewritten slot is free to use.
slotNo = data.getSlotNo();
if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_DMRNETWORK5) {
m_repeater->write(data);
status[slotNo] = DMRGWS_DMRNETWORK5;
timer[slotNo]->setTimeout(netTimeout);
timer[slotNo]->start();
}
}
if (!rewritten && trace)
LogDebug("Rule Trace,\tnot matched so rejected");
}
ret = m_dmrNetwork5->wantsBeacon();
if (ret)
m_repeater->writeBeacon();
}
unsigned char buffer[50U];
unsigned int length;
ret = m_repeater->readRadioPosition(buffer, length);
@ -1002,6 +1125,8 @@ int CDMRGateway::run()
m_dmrNetwork3->writeRadioPosition(buffer, length);
if (m_dmrNetwork4 != NULL)
m_dmrNetwork4->writeRadioPosition(buffer, length);
if (m_dmrNetwork5 != NULL)
m_dmrNetwork5->writeRadioPosition(buffer, length);
}
ret = m_repeater->readTalkerAlias(buffer, length);
if (ret) {
@ -1015,6 +1140,8 @@ int CDMRGateway::run()
m_dmrNetwork3->writeTalkerAlias(buffer, length);
if (m_dmrNetwork4 != NULL)
m_dmrNetwork4->writeTalkerAlias(buffer, length);
if (m_dmrNetwork5 != NULL)
m_dmrNetwork5->writeTalkerAlias(buffer, length);
}
ret = m_repeater->readHomePosition(buffer, length);
if (ret) {
@ -1028,6 +1155,8 @@ int CDMRGateway::run()
m_dmrNetwork3->writeHomePosition(buffer, length);
if (m_dmrNetwork4 != NULL)
m_dmrNetwork4->writeHomePosition(buffer, length);
if (m_dmrNetwork5 != NULL)
m_dmrNetwork5->writeHomePosition(buffer, length);
}
if (voice != NULL) {
@ -1059,6 +1188,9 @@ int CDMRGateway::run()
if (m_dmrNetwork4 != NULL)
m_dmrNetwork4->clock(ms);
if (m_dmrNetwork5 != NULL)
m_dmrNetwork5->clock(ms);
if (m_xlxNetwork != NULL)
m_xlxNetwork->clock(ms);
@ -1105,6 +1237,11 @@ int CDMRGateway::run()
delete m_dmrNetwork4;
}
if (m_dmrNetwork5 != NULL) {
m_dmrNetwork5->close();
delete m_dmrNetwork5;
}
if (m_xlxNetwork != NULL) {
m_xlxNetwork->close();
delete m_xlxNetwork;
@ -1696,6 +1833,144 @@ bool CDMRGateway::createDMRNetwork4()
return true;
}
bool CDMRGateway::createDMRNetwork5()
{
std::string address = m_conf.getDMRNetwork5Address();
unsigned int port = m_conf.getDMRNetwork5Port();
unsigned int local = m_conf.getDMRNetwork5Local();
unsigned int id = m_conf.getDMRNetwork5Id();
std::string password = m_conf.getDMRNetwork5Password();
bool location = m_conf.getDMRNetwork5Location();
bool debug = m_conf.getDMRNetwork5Debug();
m_dmr5Name = m_conf.getDMRNetwork5Name();
if (id == 0U)
id = m_repeater->getId();
LogInfo("DMR Network 5 Parameters");
LogInfo(" Name: %s", m_dmr5Name.c_str());
LogInfo(" Id: %u", id);
LogInfo(" Address: %s", address.c_str());
LogInfo(" Port: %u", port);
if (local > 0U)
LogInfo(" Local: %u", local);
else
LogInfo(" Local: random");
LogInfo(" Location Data: %s", location ? "yes" : "no");
m_dmrNetwork5 = new CDMRNetwork(address, port, local, id, password, m_dmr5Name, VERSION, debug);
std::string options = m_conf.getDMRNetwork5Options();
if (options.empty())
options = m_repeater->getOptions();
if (!options.empty()) {
LogInfo(" Options: %s", options.c_str());
m_dmrNetwork5->setOptions(options);
}
unsigned char config[400U];
unsigned int len = getConfig(m_dmr5Name, config);
if (!location)
::memcpy(config + 30U, "0.00000000.000000", 17U);
m_dmrNetwork5->setConfig(config, len);
bool ret = m_dmrNetwork5->open();
if (!ret) {
delete m_dmrNetwork5;
m_dmrNetwork5 = NULL;
return false;
}
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork5TGRewrites();
for (std::vector<CTGRewriteStruct>::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) {
if ((*it).m_range == 1)
LogInfo(" Rewrite RF: %u:TG%u -> %u:TG%u", (*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toTG);
else
LogInfo(" Rewrite RF: %u:TG%u-TG%u -> %u:TG%u-TG%u", (*it).m_fromSlot, (*it).m_fromTG, (*it).m_fromTG + (*it).m_range - 1U, (*it).m_toSlot, (*it).m_toTG, (*it).m_toTG + (*it).m_range - 1U);
if ((*it).m_range == 1)
LogInfo(" Rewrite Net: %u:TG%u -> %u:TG%u", (*it).m_toSlot, (*it).m_toTG, (*it).m_fromSlot, (*it).m_fromTG);
else
LogInfo(" Rewrite Net: %u:TG%u-TG%u -> %u:TG%u-TG%u", (*it).m_toSlot, (*it).m_toTG, (*it).m_toTG + (*it).m_range - 1U, (*it).m_fromSlot, (*it).m_fromTG, (*it).m_fromTG + (*it).m_range - 1U);
CRewriteTG* rfRewrite = new CRewriteTG(m_dmr5Name, (*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toTG, (*it).m_range);
CRewriteTG* netRewrite = new CRewriteTG(m_dmr5Name, (*it).m_toSlot, (*it).m_toTG, (*it).m_fromSlot, (*it).m_fromTG, (*it).m_range);
m_dmr5RFRewrites.push_back(rfRewrite);
m_dmr5NetRewrites.push_back(netRewrite);
}
std::vector<CPCRewriteStruct> pcRewrites = m_conf.getDMRNetwork5PCRewrites();
for (std::vector<CPCRewriteStruct>::const_iterator it = pcRewrites.begin(); it != pcRewrites.end(); ++it) {
if ((*it).m_range == 1)
LogInfo(" Rewrite RF: %u:%u -> %u:%u", (*it).m_fromSlot, (*it).m_fromId, (*it).m_toSlot, (*it).m_toId);
else
LogInfo(" Rewrite RF: %u:%u-%u -> %u:%u-%u", (*it).m_fromSlot, (*it).m_fromId, (*it).m_fromId + (*it).m_range - 1U, (*it).m_toSlot, (*it).m_toId, (*it).m_toId + (*it).m_range - 1U);
CRewritePC* rewrite = new CRewritePC(m_dmr5Name, (*it).m_fromSlot, (*it).m_fromId, (*it).m_toSlot, (*it).m_toId, (*it).m_range);
m_dmr5RFRewrites.push_back(rewrite);
}
std::vector<CTypeRewriteStruct> typeRewrites = m_conf.getDMRNetwork5TypeRewrites();
for (std::vector<CTypeRewriteStruct>::const_iterator it = typeRewrites.begin(); it != typeRewrites.end(); ++it) {
LogInfo(" Rewrite RF: %u:TG%u -> %u:%u", (*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toId);
CRewriteType* rewrite = new CRewriteType(m_dmr5Name, (*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toId);
m_dmr5RFRewrites.push_back(rewrite);
}
std::vector<CSrcRewriteStruct> srcRewrites = m_conf.getDMRNetwork5SrcRewrites();
for (std::vector<CSrcRewriteStruct>::const_iterator it = srcRewrites.begin(); it != srcRewrites.end(); ++it) {
if ((*it).m_range == 1)
LogInfo(" Rewrite Net: %u:%u -> %u:TG%u", (*it).m_fromSlot, (*it).m_fromId, (*it).m_toSlot, (*it).m_toTG);
else
LogInfo(" Rewrite Net: %u:%u-%u -> %u:TG%u", (*it).m_fromSlot, (*it).m_fromId, (*it).m_fromId + (*it).m_range - 1U, (*it).m_toSlot, (*it).m_toTG);
CRewriteSrc* rewrite = new CRewriteSrc(m_dmr5Name, (*it).m_fromSlot, (*it).m_fromId, (*it).m_toSlot, (*it).m_toTG, (*it).m_range);
m_dmr5NetRewrites.push_back(rewrite);
}
std::vector<CIdRewriteStruct> idRewrites = m_conf.getDMRNetwork5IdRewrites();
for (std::vector<CIdRewriteStruct>::const_iterator it = idRewrites.begin(); it != idRewrites.end(); ++it) {
LogInfo(" Rewrite Id: %u <-> %u", (*it).m_rfId, (*it).m_netId);
CRewriteSrcId* rewriteSrcId = new CRewriteSrcId(m_dmr5Name, (*it).m_rfId, (*it).m_netId);
CRewriteDstId* rewriteDstId = new CRewriteDstId(m_dmr5Name, (*it).m_netId, (*it).m_rfId);
m_dmr5SrcRewrites.push_back(rewriteSrcId);
m_dmr5NetRewrites.push_back(rewriteDstId);
}
std::vector<unsigned int> tgPassAll = m_conf.getDMRNetwork5PassAllTG();
for (std::vector<unsigned int>::const_iterator it = tgPassAll.begin(); it != tgPassAll.end(); ++it) {
LogInfo(" Pass All TG: %u", *it);
CPassAllTG* rfPassAllTG = new CPassAllTG(m_dmr5Name, *it);
CPassAllTG* netPassAllTG = new CPassAllTG(m_dmr5Name, *it);
m_dmr5Passalls.push_back(rfPassAllTG);
m_dmr5NetRewrites.push_back(netPassAllTG);
}
std::vector<unsigned int> pcPassAll = m_conf.getDMRNetwork5PassAllPC();
for (std::vector<unsigned int>::const_iterator it = pcPassAll.begin(); it != pcPassAll.end(); ++it) {
LogInfo(" Pass All PC: %u", *it);
CPassAllPC* rfPassAllPC = new CPassAllPC(m_dmr5Name, *it);
CPassAllPC* netPassAllPC = new CPassAllPC(m_dmr5Name, *it);
m_dmr5Passalls.push_back(rfPassAllPC);
m_dmr5NetRewrites.push_back(netPassAllPC);
}
return true;
}
bool CDMRGateway::createXLXNetwork()
{
std::string fileName = m_conf.getXLXNetworkFile();

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015,2016,2017 by Jonathan Naylor G4KLX
* Copyright (C) 2015,2016,2017,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
@ -51,6 +51,8 @@ private:
std::string m_dmr3Name;
CDMRNetwork* m_dmrNetwork4;
std::string m_dmr4Name;
CDMRNetwork* m_dmrNetwork5;
std::string m_dmr5Name;
CReflectors* m_xlxReflectors;
CDMRNetwork* m_xlxNetwork;
unsigned int m_xlxId;
@ -83,16 +85,21 @@ private:
std::vector<CRewrite*> m_dmr4NetRewrites;
std::vector<CRewrite*> m_dmr4RFRewrites;
std::vector<CRewrite*> m_dmr4SrcRewrites;
std::vector<CRewrite*> m_dmr5NetRewrites;
std::vector<CRewrite*> m_dmr5RFRewrites;
std::vector<CRewrite*> m_dmr5SrcRewrites;
std::vector<CRewrite*> m_dmr1Passalls;
std::vector<CRewrite*> m_dmr2Passalls;
std::vector<CRewrite*> m_dmr3Passalls;
std::vector<CRewrite*> m_dmr4Passalls;
std::vector<CRewrite*> m_dmr5Passalls;
bool createMMDVM();
bool createDMRNetwork1();
bool createDMRNetwork2();
bool createDMRNetwork3();
bool createDMRNetwork4();
bool createDMRNetwork5();
bool createXLXNetwork();
bool linkXLX(unsigned int number);

View file

@ -109,10 +109,10 @@ Port=62031
Location=0
Debug=0
# Local HBLink network
[DMR Network 3]
# Local HBLink 1 network
[DMR Network 4]
Enabled=0
Name=HBLink
Name=HBLink 1
Address=44.131.4.2
Port=55555
# Local=3352
@ -121,3 +121,16 @@ TGRewrite=2,11,2,11,1
Password=PASSWORD
Location=0
Debug=0
# Local HBLink 2 network
[DMR Network 5]
Enabled=0
Name=HBLink 2
Address=44.131.4.3
Port=55555
# Local=3352
# Local area TG on to slot 2 TG11
TGRewrite=2,11,2,11,1
Password=PASSWORD
Location=0
Debug=0

View file

@ -1,4 +1,4 @@
This is the DMR Gateway which allows for the connection of up to four different DMR networks to one MMDVM system. One of the networks is defined as being an XLX reflector, while the other three may be one each of DMR+, BrandMeister, or a local HBLink system.
This is the DMR Gateway which allows for the connection of up to six different DMR networks to one MMDVM system. One of the networks is defined as being an XLX reflector, while the other five may be any combination of DMR+, BrandMeister, TGIF, or local HBLink systems.
This software works by use of powerful rewriting rules which allow for changes in the slot, talk group, the type, and even the destination, of the messages. Without a rewrite rule, even if it does no actual rewriting, traffic will not be passed through from that defined network to the MMDVM and back again.
@ -8,6 +8,6 @@ The rewrite rules don
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 builds on 32-bit and 64-bit Linux systems 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.

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2015-2018 by Jonathan Naylor G4KLX
* Copyright (C) 2015-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
@ -19,6 +19,6 @@
#if !defined(VERSION_H)
#define VERSION_H
const char* VERSION = "20180606";
const char* VERSION = "20190717";
#endif