DMRGateway/DMRGateway.cpp

790 lines
20 KiB
C++
Raw Normal View History

2017-04-20 21:51:30 +02:00
/*
* Copyright (C) 2015,2016,2017 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 "DMRGateway.h"
#include "Version.h"
#include "StopWatch.h"
#include "Thread.h"
2017-05-01 15:46:43 +02:00
#include "Voice.h"
2017-04-20 21:51:30 +02:00
#include "Log.h"
#include <cstdio>
#include <vector>
#if !defined(_WIN32) && !defined(_WIN64)
#include <sys/types.h>
#include <unistd.h>
#include <signal.h>
#include <fcntl.h>
#include <pwd.h>
#endif
#if defined(_WIN32) || defined(_WIN64)
const char* DEFAULT_INI_FILE = "DMRGateway.ini";
#else
const char* DEFAULT_INI_FILE = "/etc/DMRGateway.ini";
#endif
2017-04-23 21:17:25 +02:00
const unsigned int XLX_SLOT = 2U;
const unsigned int XLX_TG = 9U;
2017-04-20 21:51:30 +02:00
static bool m_killed = false;
static int m_signal = 0;
#if !defined(_WIN32) && !defined(_WIN64)
static void sigHandler(int signum)
{
m_killed = true;
m_signal = signum;
}
#endif
enum DMRGW_STATUS {
DMRGWS_NONE,
DMRGWS_NETWORK1,
DMRGWS_NETWORK2,
2017-04-20 21:51:30 +02:00
DMRGWS_REFLECTOR
};
const char* HEADER1 = "This software is for use on amateur radio networks only,";
const char* HEADER2 = "it is to be used for educational purposes only. Its use on";
const char* HEADER3 = "commercial networks is strictly prohibited.";
2017-05-01 15:46:43 +02:00
const char* HEADER4 = "Copyright(C) 2017 by Jonathan Naylor, G4KLX and others";
2017-04-20 21:51:30 +02:00
int main(int argc, char** argv)
{
const char* iniFile = DEFAULT_INI_FILE;
if (argc > 1) {
for (int currentArg = 1; currentArg < argc; ++currentArg) {
std::string arg = argv[currentArg];
if ((arg == "-v") || (arg == "--version")) {
::fprintf(stdout, "DMRGateway version %s\n", VERSION);
return 0;
} else if (arg.substr(0,1) == "-") {
::fprintf(stderr, "Usage: DMRGateway [-v|--version] [filename]\n");
return 1;
} else {
iniFile = argv[currentArg];
}
}
}
2017-04-20 21:51:30 +02:00
#if !defined(_WIN32) && !defined(_WIN64)
::signal(SIGTERM, sigHandler);
::signal(SIGHUP, sigHandler);
2017-04-20 21:51:30 +02:00
#endif
int ret = 0;
2017-04-20 21:51:30 +02:00
do {
m_signal = 0;
2017-04-20 21:51:30 +02:00
CDMRGateway* host = new CDMRGateway(std::string(iniFile));
ret = host->run();
2017-04-20 21:51:30 +02:00
delete host;
2017-04-20 21:51:30 +02:00
if (m_signal == 15)
::LogInfo("Caught SIGTERM, exiting");
2017-04-20 21:51:30 +02:00
if (m_signal == 1)
::LogInfo("Caught SIGHUP, restarting");
} while (m_signal == 1);
2017-04-20 21:51:30 +02:00
::LogFinalise();
2017-04-20 21:51:30 +02:00
return ret;
2017-04-20 21:51:30 +02:00
}
CDMRGateway::CDMRGateway(const std::string& confFile) :
m_conf(confFile),
m_repeater(NULL),
m_dmrNetwork1(NULL),
m_dmrNetwork2(NULL),
2017-04-20 21:51:30 +02:00
m_xlxNetwork(NULL),
m_reflector(4000U),
m_xlxSlot(0U),
m_xlxTG(0U),
2017-05-06 18:17:34 +02:00
m_rptRewrite(NULL),
m_xlxRewrite(NULL),
m_dmr1NetRewrites(),
m_dmr1RFRewrites(),
m_dmr2NetRewrites(),
m_dmr2RFRewrites(),
m_dmr1PrivateSlot1(false),
m_dmr1PrivateSlot2(false),
m_dmr2PrivateSlot1(false),
m_dmr2PrivateSlot2(false)
2017-04-20 21:51:30 +02:00
{
}
CDMRGateway::~CDMRGateway()
{
for (std::vector<CRewrite*>::iterator it = m_dmr1NetRewrites.begin(); it != m_dmr1NetRewrites.end(); ++it)
delete *it;
for (std::vector<CRewrite*>::iterator it = m_dmr1RFRewrites.begin(); it != m_dmr1RFRewrites.end(); ++it)
delete *it;
for (std::vector<CRewrite*>::iterator it = m_dmr2NetRewrites.begin(); it != m_dmr2NetRewrites.end(); ++it)
delete *it;
for (std::vector<CRewrite*>::iterator it = m_dmr2RFRewrites.begin(); it != m_dmr2RFRewrites.end(); ++it)
delete *it;
2017-04-20 21:51:30 +02:00
}
int CDMRGateway::run()
{
bool ret = m_conf.read();
if (!ret) {
::fprintf(stderr, "DMRGateway: cannot read the .ini file\n");
return 1;
}
ret = ::LogInitialise(m_conf.getLogFilePath(), m_conf.getLogFileRoot(), m_conf.getLogFileLevel(), m_conf.getLogDisplayLevel());
if (!ret) {
::fprintf(stderr, "DMRGateway: unable to open the log file\n");
return 1;
}
#if !defined(_WIN32) && !defined(_WIN64)
bool m_daemon = m_conf.getDaemon();
if (m_daemon) {
// Create new process
pid_t pid = ::fork();
if (pid == -1) {
::LogWarning("Couldn't fork() , exiting");
return -1;
} else if (pid != 0) {
2017-04-20 21:51:30 +02:00
exit(EXIT_SUCCESS);
}
2017-04-20 21:51:30 +02:00
// Create new session and process group
if (::setsid() == -1){
::LogWarning("Couldn't setsid(), exiting");
return -1;
}
2017-04-20 21:51:30 +02:00
// Set the working directory to the root directory
if (::chdir("/") == -1){
::LogWarning("Couldn't cd /, exiting");
return -1;
}
2017-04-20 21:51:30 +02:00
::close(STDIN_FILENO);
::close(STDOUT_FILENO);
::close(STDERR_FILENO);
2017-04-20 21:51:30 +02:00
//If we are currently root...
if (getuid() == 0) {
struct passwd* user = ::getpwnam("mmdvm");
if (user == NULL) {
::LogError("Could not get the mmdvm user, exiting");
return -1;
}
uid_t mmdvm_uid = user->pw_uid;
gid_t mmdvm_gid = user->pw_gid;
//Set user and group ID's to mmdvm:mmdvm
if (setgid(mmdvm_gid) != 0) {
::LogWarning("Could not set mmdvm GID, exiting");
return -1;
}
if (setuid(mmdvm_uid) != 0) {
::LogWarning("Could not set mmdvm UID, exiting");
return -1;
}
//Double check it worked (AKA Paranoia)
if (setuid(0) != -1){
::LogWarning("It's possible to regain root - something is wrong!, exiting");
return -1;
}
}
}
#endif
LogInfo(HEADER1);
LogInfo(HEADER2);
LogInfo(HEADER3);
LogInfo(HEADER4);
LogMessage("DMRGateway-%s is starting", VERSION);
ret = createMMDVM();
if (!ret)
return 1;
LogMessage("Waiting for MMDVM to connect.....");
for (;;) {
unsigned char config[400U];
unsigned int len = m_repeater->getConfig(config);
2017-04-20 21:51:30 +02:00
if (len > 0U)
break;
2017-04-27 21:39:46 +02:00
m_repeater->clock(10U);
2017-04-27 21:39:46 +02:00
CThread::sleep(10U);
2017-04-20 21:51:30 +02:00
}
LogMessage("MMDVM has connected");
if (m_conf.getDMRNetwork1Enabled()) {
ret = createDMRNetwork1();
if (!ret)
return 1;
}
2017-04-20 21:51:30 +02:00
if (m_conf.getDMRNetwork2Enabled()) {
ret = createDMRNetwork2();
if (!ret)
return 1;
}
2017-05-06 18:17:34 +02:00
if (m_conf.getXLXNetworkEnabled()) {
ret = createXLXNetwork();
if (!ret)
return 1;
}
2017-04-20 21:51:30 +02:00
2017-05-06 10:57:17 +02:00
unsigned int timeout = m_conf.getTimeout();
2017-05-01 15:46:43 +02:00
CVoice* voice = NULL;
if (m_conf.getVoiceEnabled() && m_xlxNetwork != NULL) {
2017-05-01 21:05:41 +02:00
std::string language = m_conf.getVoiceLanguage();
std::string directory = m_conf.getVoiceDirectory();
2017-05-01 15:46:43 +02:00
LogInfo("Voice Parameters");
LogInfo(" Enabled: yes");
LogInfo(" Language: %s", language.c_str());
2017-05-01 21:05:41 +02:00
LogInfo(" Directory: %s", directory.c_str());
2017-05-01 15:46:43 +02:00
voice = new CVoice(directory, language, m_repeater->getId(), m_xlxSlot, m_xlxTG);
2017-05-01 15:46:43 +02:00
bool ret = voice->open();
if (!ret) {
delete voice;
voice = NULL;
}
}
CTimer* timer[3U];
timer[1U] = new CTimer(1000U, timeout);
timer[2U] = new CTimer(1000U, timeout);
2017-04-20 21:51:30 +02:00
DMRGW_STATUS status[3U];
status[1U] = DMRGWS_NONE;
status[2U] = DMRGWS_NONE;
2017-04-20 21:51:30 +02:00
CStopWatch stopWatch;
stopWatch.start();
LogMessage("DMRGateway-%s is running", VERSION);
2017-05-01 15:46:43 +02:00
bool changed = false;
2017-04-20 21:51:30 +02:00
while (!m_killed) {
CDMRData data;
bool ret = m_repeater->read(data);
2017-04-20 21:51:30 +02:00
if (ret) {
unsigned int slotNo = data.getSlotNo();
unsigned int dstId = data.getDstId();
FLCO flco = data.getFLCO();
if (flco == FLCO_GROUP && slotNo == m_xlxSlot && dstId == m_xlxTG) {
2017-05-06 18:17:34 +02:00
m_xlxRewrite->process(data);
m_xlxNetwork->write(data);
status[slotNo] = DMRGWS_REFLECTOR;
timer[slotNo]->start();
} else if (flco == FLCO_USER_USER && slotNo == m_xlxSlot && dstId >= 4000U && dstId <= 4026U) {
if (dstId != m_reflector) {
if (dstId == 4000U)
LogMessage("Unlinking");
else
LogMessage("Linking to reflector %u", dstId);
m_reflector = dstId;
changed = true;
}
data.setSlotNo(XLX_SLOT);
m_xlxNetwork->write(data);
status[slotNo] = DMRGWS_REFLECTOR;
timer[slotNo]->start();
if (voice != NULL) {
unsigned char type = data.getDataType();
if (type == DT_TERMINATOR_WITH_LC) {
if (changed) {
if (m_reflector == 4000U)
voice->unlinked();
2017-04-30 12:01:54 +02:00
else
voice->linkedTo(m_reflector);
changed = false;
}
}
}
2017-05-06 18:17:34 +02:00
} else if (flco == FLCO_USER_USER) {
if (m_dmrNetwork1 != NULL && slotNo == 1U && m_dmr1PrivateSlot1) {
m_dmrNetwork1->write(data);
status[slotNo] = DMRGWS_NETWORK1;
timer[slotNo]->start();
} else if (m_dmrNetwork1 != NULL && slotNo == 2U && m_dmr1PrivateSlot2) {
m_dmrNetwork1->write(data);
status[slotNo] = DMRGWS_NETWORK1;
timer[slotNo]->start();
} else if (m_dmrNetwork2 != NULL && slotNo == 1U && m_dmr2PrivateSlot1) {
m_dmrNetwork2->write(data);
status[slotNo] = DMRGWS_NETWORK2;
timer[slotNo]->start();
} else if (m_dmrNetwork2 != NULL && slotNo == 2U && m_dmr2PrivateSlot2) {
m_dmrNetwork2->write(data);
status[slotNo] = DMRGWS_NETWORK2;
timer[slotNo]->start();
}
} else {
2017-05-06 10:57:17 +02:00
bool rewritten = false;
if (m_dmrNetwork1 != NULL) {
// Rewrite the slot and/or TG or neither
for (std::vector<CRewrite*>::iterator it = m_dmr1RFRewrites.begin(); it != m_dmr1RFRewrites.end(); ++it) {
bool ret = (*it)->process(data);
if (ret) {
rewritten = true;
break;
}
}
2017-04-30 12:01:54 +02:00
if (rewritten) {
unsigned int slotNo = data.getSlotNo();
if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_NETWORK1) {
m_dmrNetwork1->write(data);
status[slotNo] = DMRGWS_NETWORK1;
timer[slotNo]->start();
2017-04-30 12:01:54 +02:00
}
}
}
2017-04-30 12:01:54 +02:00
2017-05-06 10:57:17 +02:00
if (!rewritten) {
if (m_dmrNetwork2 != NULL) {
// Rewrite the slot and/or TG or neither
for (std::vector<CRewrite*>::iterator it = m_dmr2RFRewrites.begin(); it != m_dmr2RFRewrites.end(); ++it) {
bool ret = (*it)->process(data);
if (ret) {
rewritten = true;
break;
}
}
2017-05-06 10:57:17 +02:00
if (rewritten) {
unsigned int slotNo = data.getSlotNo();
if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_NETWORK2) {
m_dmrNetwork2->write(data);
status[slotNo] = DMRGWS_NETWORK2;
timer[slotNo]->start();
}
2017-05-01 15:46:43 +02:00
}
2017-04-20 21:51:30 +02:00
}
}
}
}
if (m_xlxNetwork != NULL) {
ret = m_xlxNetwork->read(data);
if (ret) {
if (status[m_xlxSlot] == DMRGWS_NONE || status[m_xlxSlot] == DMRGWS_REFLECTOR) {
2017-05-08 19:34:41 +02:00
bool ret = m_rptRewrite->process(data);
if (ret) {
m_repeater->write(data);
status[m_xlxSlot] = DMRGWS_REFLECTOR;
timer[m_xlxSlot]->start();
2017-05-12 18:19:39 +02:00
} else {
unsigned int slotNo = data.getSlotNo();
unsigned int dstId = data.getDstId();
FLCO flco = data.getFLCO();
LogWarning("XLX, Unexpected data from slot %u %s%u", slotNo, flco == FLCO_GROUP ? "TG" : "", dstId);
}
2017-04-20 21:51:30 +02:00
}
}
}
if (m_dmrNetwork1 != NULL) {
ret = m_dmrNetwork1->read(data);
if (ret) {
2017-04-20 21:51:30 +02:00
FLCO flco = data.getFLCO();
if (flco == FLCO_USER_USER) {
unsigned int slotNo = data.getSlotNo();
if (slotNo == 1U && m_dmr1PrivateSlot1) {
m_repeater->write(data);
status[slotNo] = DMRGWS_NETWORK1;
timer[slotNo]->start();
} else if (slotNo == 2U && m_dmr1PrivateSlot2) {
m_repeater->write(data);
status[slotNo] = DMRGWS_NETWORK1;
timer[slotNo]->start();
}
} else {
// Rewrite the slot and/or TG or neither
bool rewritten = false;
for (std::vector<CRewrite*>::iterator it = m_dmr1NetRewrites.begin(); it != m_dmr1NetRewrites.end(); ++it) {
bool ret = (*it)->process(data);
if (ret) {
rewritten = true;
break;
}
}
if (rewritten) {
unsigned int slotNo = data.getSlotNo();
unsigned int dstId = data.getDstId();
// Stop the DMR network from using the same TG as XLX after rewriting
if (slotNo != m_xlxSlot || dstId != m_xlxTG) {
if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_NETWORK1) {
m_repeater->write(data);
status[slotNo] = DMRGWS_NETWORK1;
timer[slotNo]->start();
}
}
}
}
}
}
if (m_dmrNetwork2 != NULL) {
ret = m_dmrNetwork2->read(data);
if (ret) {
FLCO flco = data.getFLCO();
if (flco == FLCO_USER_USER) {
unsigned int slotNo = data.getSlotNo();
if (slotNo == 1U && m_dmr2PrivateSlot1) {
m_repeater->write(data);
status[slotNo] = DMRGWS_NETWORK2;
timer[slotNo]->start();
} else if (slotNo == 2U && m_dmr2PrivateSlot2) {
m_repeater->write(data);
status[slotNo] = DMRGWS_NETWORK2;
timer[slotNo]->start();
}
} else {
// Rewrite the slot and/or TG or neither
bool rewritten = false;
for (std::vector<CRewrite*>::iterator it = m_dmr2NetRewrites.begin(); it != m_dmr2NetRewrites.end(); ++it) {
bool ret = (*it)->process(data);
if (ret) {
rewritten = true;
break;
}
}
if (rewritten) {
unsigned int slotNo = data.getSlotNo();
unsigned int dstId = data.getDstId();
// Stop the DMR network from using the same TG as XLX after rewriting
if (slotNo != m_xlxSlot || dstId != m_xlxTG) {
if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_NETWORK2) {
m_repeater->write(data);
status[slotNo] = DMRGWS_NETWORK2;
timer[slotNo]->start();
}
}
2017-04-20 21:51:30 +02:00
}
}
}
}
2017-05-01 15:46:43 +02:00
if (voice != NULL) {
ret = voice->read(data);
if (ret) {
m_repeater->write(data);
status[m_xlxSlot] = DMRGWS_REFLECTOR;
timer[m_xlxSlot]->start();
2017-05-01 15:46:43 +02:00
}
}
2017-04-20 21:51:30 +02:00
unsigned int ms = stopWatch.elapsed();
stopWatch.start();
m_repeater->clock(ms);
if (m_dmrNetwork1 != NULL)
m_dmrNetwork1->clock(ms);
if (m_dmrNetwork2 != NULL)
m_dmrNetwork2->clock(ms);
if (m_xlxNetwork != NULL)
m_xlxNetwork->clock(ms);
2017-04-20 21:51:30 +02:00
2017-05-01 15:46:43 +02:00
if (voice != NULL)
voice->clock(ms);
for (unsigned int i = 1U; i < 3U; i++) {
timer[i]->clock(ms);
if (timer[i]->isRunning() && timer[i]->hasExpired()) {
status[i] = DMRGWS_NONE;
timer[i]->stop();
}
2017-04-20 21:51:30 +02:00
}
if (ms < 10U)
CThread::sleep(10U);
}
LogMessage("DMRGateway-%s is exiting on receipt of SIGHUP1", VERSION);
2017-05-01 15:46:43 +02:00
delete voice;
m_repeater->close();
delete m_repeater;
2017-04-20 21:51:30 +02:00
if (m_dmrNetwork1 != NULL) {
m_dmrNetwork1->close();
delete m_dmrNetwork1;
}
if (m_dmrNetwork2 != NULL) {
m_dmrNetwork2->close();
delete m_dmrNetwork2;
}
2017-04-20 21:51:30 +02:00
if (m_xlxNetwork != NULL) {
m_xlxNetwork->close();
delete m_xlxNetwork;
}
2017-04-20 21:51:30 +02:00
2017-05-06 18:17:34 +02:00
delete m_rptRewrite;
delete m_xlxRewrite;
2017-05-06 10:57:17 +02:00
delete timer[1U];
delete timer[2U];
2017-04-20 21:51:30 +02:00
return 0;
}
bool CDMRGateway::createMMDVM()
{
2017-04-23 21:17:25 +02:00
std::string rptAddress = m_conf.getRptAddress();
unsigned int rptPort = m_conf.getRptPort();
std::string localAddress = m_conf.getLocalAddress();
unsigned int localPort = m_conf.getLocalPort();
bool debug = m_conf.getDebug();
2017-04-20 21:51:30 +02:00
LogInfo("MMDVM Network Parameters");
2017-04-23 21:17:25 +02:00
LogInfo(" Rpt Address: %s", rptAddress.c_str());
LogInfo(" Rpt Port: %u", rptPort);
LogInfo(" Local Address: %s", localAddress.c_str());
LogInfo(" Local Port: %u", localPort);
m_repeater = new CMMDVMNetwork(rptAddress, rptPort, localAddress, localPort, debug);
2017-04-20 21:51:30 +02:00
bool ret = m_repeater->open();
2017-04-20 21:51:30 +02:00
if (!ret) {
delete m_repeater;
m_repeater = NULL;
2017-04-20 21:51:30 +02:00
return false;
}
return true;
}
bool CDMRGateway::createDMRNetwork1()
2017-04-20 21:51:30 +02:00
{
std::string address = m_conf.getDMRNetwork1Address();
unsigned int port = m_conf.getDMRNetwork1Port();
unsigned int local = m_conf.getDMRNetwork1Local();
2017-05-06 10:57:17 +02:00
unsigned int id = m_conf.getDMRNetwork1Id();
std::string password = m_conf.getDMRNetwork1Password();
bool debug = m_conf.getDMRNetwork1Debug();
2017-04-20 21:51:30 +02:00
2017-05-06 10:57:17 +02:00
if (id == 0U)
id = m_repeater->getId();
LogInfo("DMR Network 1 Parameters");
2017-05-06 10:57:17 +02:00
LogInfo(" Id: %u", id);
2017-04-20 21:51:30 +02:00
LogInfo(" Address: %s", address.c_str());
LogInfo(" Port: %u", port);
if (local > 0U)
LogInfo(" Local: %u", local);
else
LogInfo(" Local: random");
2017-05-07 09:45:17 +02:00
m_dmrNetwork1 = new CDMRNetwork(address, port, local, id, password, "DMR-1", debug);
2017-04-20 21:51:30 +02:00
std::string options = m_repeater->getOptions();
2017-04-20 21:51:30 +02:00
if (!options.empty()) {
LogInfo(" Options: %s", options.c_str());
m_dmrNetwork1->setOptions(options);
2017-04-20 21:51:30 +02:00
}
unsigned char config[400U];
unsigned int len = m_repeater->getConfig(config);
2017-04-20 21:51:30 +02:00
m_dmrNetwork1->setConfig(config, len);
2017-04-20 21:51:30 +02:00
bool ret = m_dmrNetwork1->open();
2017-04-20 21:51:30 +02:00
if (!ret) {
delete m_dmrNetwork1;
m_dmrNetwork1 = NULL;
2017-04-20 21:51:30 +02:00
return false;
}
std::vector<CRewriteStruct> rewrites = m_conf.getDMRNetwork1Rewrites();
for (std::vector<CRewriteStruct>::const_iterator it = rewrites.begin(); it != rewrites.end(); ++it) {
LogInfo(" Rewrite: %u:%u -> %u:%u", (*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toTG);
CRewrite* netRewrite = new CRewrite((*it).m_toSlot, (*it).m_toTG, (*it).m_fromSlot, (*it).m_fromTG);
CRewrite* rfRewrite = new CRewrite((*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toTG);
m_dmr1NetRewrites.push_back(netRewrite);
m_dmr1RFRewrites.push_back(rfRewrite);
}
m_dmr1PrivateSlot1 = m_conf.getDMRNetwork1PrivateSlot1();
m_dmr1PrivateSlot2 = m_conf.getDMRNetwork1PrivateSlot2();
LogInfo(" Private slot 1: %s", m_dmr1PrivateSlot1 ? "yes" : "no");
LogInfo(" Private slot 2: %s", m_dmr1PrivateSlot2 ? "yes" : "no");
return true;
}
bool CDMRGateway::createDMRNetwork2()
{
std::string address = m_conf.getDMRNetwork2Address();
unsigned int port = m_conf.getDMRNetwork2Port();
unsigned int local = m_conf.getDMRNetwork2Local();
2017-05-06 10:57:17 +02:00
unsigned int id = m_conf.getDMRNetwork2Id();
std::string password = m_conf.getDMRNetwork2Password();
bool debug = m_conf.getDMRNetwork2Debug();
2017-05-06 10:57:17 +02:00
if (id == 0U)
id = m_repeater->getId();
LogInfo("DMR Network 2 Parameters");
2017-05-06 10:57:17 +02:00
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");
2017-05-07 09:45:17 +02:00
m_dmrNetwork2 = new CDMRNetwork(address, port, local, id, password, "DMR-2", debug);
std::string options = m_repeater->getOptions();
if (!options.empty()) {
LogInfo(" Options: %s", options.c_str());
m_dmrNetwork2->setOptions(options);
}
unsigned char config[400U];
unsigned int len = m_repeater->getConfig(config);
m_dmrNetwork2->setConfig(config, len);
bool ret = m_dmrNetwork2->open();
if (!ret) {
delete m_dmrNetwork2;
m_dmrNetwork2 = NULL;
return false;
}
std::vector<CRewriteStruct> rewrites = m_conf.getDMRNetwork2Rewrites();
for (std::vector<CRewriteStruct>::const_iterator it = rewrites.begin(); it != rewrites.end(); ++it) {
LogInfo(" Rewrite: %u:%u -> %u:%u", (*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toTG);
CRewrite* netRewrite = new CRewrite((*it).m_toSlot, (*it).m_toTG, (*it).m_fromSlot, (*it).m_fromTG);
CRewrite* rfRewrite = new CRewrite((*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toTG);
m_dmr2NetRewrites.push_back(netRewrite);
m_dmr2RFRewrites.push_back(rfRewrite);
}
m_dmr2PrivateSlot1 = m_conf.getDMRNetwork2PrivateSlot1();
m_dmr2PrivateSlot2 = m_conf.getDMRNetwork2PrivateSlot2();
LogInfo(" Private slot 1: %s", m_dmr2PrivateSlot1 ? "yes" : "no");
LogInfo(" Private slot 2: %s", m_dmr2PrivateSlot2 ? "yes" : "no");
2017-04-20 21:51:30 +02:00
return true;
}
bool CDMRGateway::createXLXNetwork()
{
std::string address = m_conf.getXLXNetworkAddress();
unsigned int port = m_conf.getXLXNetworkPort();
unsigned int local = m_conf.getXLXNetworkLocal();
2017-05-06 10:57:17 +02:00
unsigned int id = m_conf.getXLXNetworkId();
2017-04-20 21:51:30 +02:00
std::string password = m_conf.getXLXNetworkPassword();
std::string options = m_conf.getXLXNetworkOptions();
bool debug = m_conf.getXLXNetworkDebug();
2017-05-06 10:57:17 +02:00
if (id == 0U)
id = m_repeater->getId();
2017-04-20 21:51:30 +02:00
LogInfo("XLX Network Parameters");
2017-05-06 10:57:17 +02:00
LogInfo(" Id: %u", id);
2017-04-20 21:51:30 +02:00
LogInfo(" Address: %s", address.c_str());
LogInfo(" Port: %u", port);
if (local > 0U)
LogInfo(" Local: %u", local);
else
LogInfo(" Local: random");
2017-04-27 21:39:46 +02:00
m_xlxNetwork = new CDMRNetwork(address, port, local, id, password, "XLX", debug);
2017-04-20 21:51:30 +02:00
if (!options.empty()) {
LogInfo(" Options: %s", options.c_str());
m_xlxNetwork->setOptions(options);
}
unsigned char config[400U];
unsigned int len = m_repeater->getConfig(config);
2017-04-20 21:51:30 +02:00
m_xlxNetwork->setConfig(config, len);
bool ret = m_xlxNetwork->open();
if (!ret) {
delete m_xlxNetwork;
m_xlxNetwork = NULL;
return false;
}
m_xlxSlot = m_conf.getXLXNetworkSlot();
m_xlxTG = m_conf.getXLXNetworkTG();
LogInfo(" Slot: %u", m_xlxSlot);
LogInfo(" TG: %u", m_xlxTG);
2017-05-06 18:17:34 +02:00
m_rptRewrite = new CRewrite(XLX_SLOT, XLX_TG, m_xlxSlot, m_xlxTG);
m_xlxRewrite = new CRewrite(m_xlxSlot, m_xlxTG, XLX_SLOT, XLX_TG);
2017-04-20 21:51:30 +02:00
return true;
}