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.
|
|
|
|
|
*/
|
|
|
|
|
|
2017-05-15 22:16:52 +02:00
|
|
|
#include "RewriteType.h"
|
2017-05-29 20:24:13 +02:00
|
|
|
#include "DMRSlotType.h"
|
2017-05-15 22:16:52 +02:00
|
|
|
#include "RewriteSrc.h"
|
2017-04-20 21:51:30 +02:00
|
|
|
#include "DMRGateway.h"
|
|
|
|
|
#include "StopWatch.h"
|
2017-05-14 19:14:09 +02:00
|
|
|
#include "RewritePC.h"
|
2017-05-27 17:50:34 +02:00
|
|
|
#include "PassAllPC.h"
|
|
|
|
|
#include "PassAllTG.h"
|
2017-05-29 20:24:13 +02:00
|
|
|
#include "DMRFullLC.h"
|
2017-05-15 22:16:52 +02:00
|
|
|
#include "Version.h"
|
2017-04-20 21:51:30 +02:00
|
|
|
#include "Thread.h"
|
2017-05-29 20:24:13 +02:00
|
|
|
#include "DMRLC.h"
|
2017-05-01 15:46:43 +02:00
|
|
|
#include "Voice.h"
|
2017-05-29 20:24:13 +02:00
|
|
|
#include "Sync.h"
|
2017-04-20 21:51:30 +02:00
|
|
|
#include "Log.h"
|
2017-05-23 10:07:44 +02:00
|
|
|
#include "GitVersion.h"
|
2017-04-20 21:51:30 +02:00
|
|
|
|
|
|
|
|
#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-05-29 20:24:13 +02:00
|
|
|
const unsigned char COLOR_CODE = 3U;
|
|
|
|
|
|
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,
|
2017-05-26 14:26:39 +02:00
|
|
|
DMRGWS_DMRNETWORK1,
|
|
|
|
|
DMRGWS_DMRNETWORK2,
|
|
|
|
|
DMRGWS_XLXREFLECTOR1,
|
|
|
|
|
DMRGWS_XLXREFLECTOR2
|
2017-04-20 21:51:30 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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)
|
|
|
|
|
{
|
2017-05-03 18:48:55 +02:00
|
|
|
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")) {
|
2017-05-23 10:07:44 +02:00
|
|
|
::fprintf(stdout, "DMRGateway version %s git #%.7s\n", VERSION, gitversion);
|
2017-05-03 18:48:55 +02:00
|
|
|
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)
|
2017-05-03 18:48:55 +02:00
|
|
|
::signal(SIGTERM, sigHandler);
|
|
|
|
|
::signal(SIGHUP, sigHandler);
|
2017-04-20 21:51:30 +02:00
|
|
|
#endif
|
|
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
int ret = 0;
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
do {
|
|
|
|
|
m_signal = 0;
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
CDMRGateway* host = new CDMRGateway(std::string(iniFile));
|
|
|
|
|
ret = host->run();
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
delete host;
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
if (m_signal == 15)
|
|
|
|
|
::LogInfo("Caught SIGTERM, exiting");
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
if (m_signal == 1)
|
|
|
|
|
::LogInfo("Caught SIGHUP, restarting");
|
|
|
|
|
} while (m_signal == 1);
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
::LogFinalise();
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
return ret;
|
2017-04-20 21:51:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CDMRGateway::CDMRGateway(const std::string& confFile) :
|
|
|
|
|
m_conf(confFile),
|
2017-04-30 12:13:35 +02:00
|
|
|
m_repeater(NULL),
|
2017-05-03 18:48:55 +02:00
|
|
|
m_dmrNetwork1(NULL),
|
|
|
|
|
m_dmrNetwork2(NULL),
|
2017-05-26 14:26:39 +02:00
|
|
|
m_xlxNetwork1(NULL),
|
|
|
|
|
m_xlxNetwork2(NULL),
|
|
|
|
|
m_xlx1Reflector(4000U),
|
|
|
|
|
m_xlx1Slot(0U),
|
|
|
|
|
m_xlx1TG(0U),
|
|
|
|
|
m_xlx1Base(0U),
|
|
|
|
|
m_rpt1Rewrite(NULL),
|
|
|
|
|
m_xlx1Rewrite(NULL),
|
|
|
|
|
m_xlx2Reflector(4000U),
|
|
|
|
|
m_xlx2Slot(0U),
|
|
|
|
|
m_xlx2TG(0U),
|
|
|
|
|
m_xlx2Base(0U),
|
|
|
|
|
m_rpt2Rewrite(NULL),
|
|
|
|
|
m_xlx2Rewrite(NULL),
|
2017-05-03 18:48:55 +02:00
|
|
|
m_dmr1NetRewrites(),
|
|
|
|
|
m_dmr1RFRewrites(),
|
|
|
|
|
m_dmr2NetRewrites(),
|
2017-05-14 19:14:09 +02:00
|
|
|
m_dmr2RFRewrites()
|
2017-04-20 21:51:30 +02:00
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CDMRGateway::~CDMRGateway()
|
|
|
|
|
{
|
2017-05-14 19:14:09 +02:00
|
|
|
for (std::vector<IRewrite*>::iterator it = m_dmr1NetRewrites.begin(); it != m_dmr1NetRewrites.end(); ++it)
|
2017-05-03 18:48:55 +02:00
|
|
|
delete *it;
|
|
|
|
|
|
2017-05-14 19:14:09 +02:00
|
|
|
for (std::vector<IRewrite*>::iterator it = m_dmr1RFRewrites.begin(); it != m_dmr1RFRewrites.end(); ++it)
|
2017-05-03 18:48:55 +02:00
|
|
|
delete *it;
|
|
|
|
|
|
2017-05-14 19:14:09 +02:00
|
|
|
for (std::vector<IRewrite*>::iterator it = m_dmr2NetRewrites.begin(); it != m_dmr2NetRewrites.end(); ++it)
|
2017-05-03 18:48:55 +02:00
|
|
|
delete *it;
|
|
|
|
|
|
2017-05-14 19:14:09 +02:00
|
|
|
for (std::vector<IRewrite*>::iterator it = m_dmr2RFRewrites.begin(); it != m_dmr2RFRewrites.end(); ++it)
|
2017-05-03 18:48:55 +02:00
|
|
|
delete *it;
|
2017-05-14 19:14:09 +02:00
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
delete m_rpt1Rewrite;
|
|
|
|
|
delete m_xlx1Rewrite;
|
|
|
|
|
delete m_rpt2Rewrite;
|
|
|
|
|
delete m_xlx2Rewrite;
|
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) {
|
2017-05-03 18:48:55 +02:00
|
|
|
::LogWarning("Couldn't fork() , exiting");
|
|
|
|
|
return -1;
|
|
|
|
|
} else if (pid != 0) {
|
2017-04-20 21:51:30 +02:00
|
|
|
exit(EXIT_SUCCESS);
|
2017-05-03 18:48:55 +02:00
|
|
|
}
|
2017-04-20 21:51:30 +02:00
|
|
|
|
|
|
|
|
// Create new session and process group
|
|
|
|
|
if (::setsid() == -1){
|
2017-05-03 18:48:55 +02:00
|
|
|
::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){
|
2017-05-03 18:48:55 +02:00
|
|
|
::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-05-03 18:48:55 +02:00
|
|
|
|
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);
|
2017-05-23 10:07:44 +02:00
|
|
|
LogMessage("Built %s %s (GitID #%.7s)", __TIME__, __DATE__, gitversion);
|
2017-04-20 21:51:30 +02:00
|
|
|
|
|
|
|
|
ret = createMMDVM();
|
|
|
|
|
if (!ret)
|
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
|
|
LogMessage("Waiting for MMDVM to connect.....");
|
|
|
|
|
|
2017-05-29 19:52:36 +02:00
|
|
|
while (!m_killed) {
|
2017-04-20 21:51:30 +02:00
|
|
|
unsigned char config[400U];
|
2017-04-30 12:13:35 +02:00
|
|
|
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
|
|
|
|
2017-04-30 12:13:35 +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
|
|
|
}
|
|
|
|
|
|
2017-05-29 19:52:36 +02:00
|
|
|
if (m_killed) {
|
|
|
|
|
LogMessage("DMRGateway-%s is exiting on receipt of SIGHUP1", VERSION);
|
|
|
|
|
m_repeater->close();
|
|
|
|
|
delete m_repeater;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-20 21:51:30 +02:00
|
|
|
LogMessage("MMDVM has connected");
|
|
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
if (m_conf.getDMRNetwork1Enabled()) {
|
|
|
|
|
ret = createDMRNetwork1();
|
|
|
|
|
if (!ret)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
if (m_conf.getDMRNetwork2Enabled()) {
|
|
|
|
|
ret = createDMRNetwork2();
|
|
|
|
|
if (!ret)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-06 18:17:34 +02:00
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
if (m_conf.getXLXNetwork1Enabled()) {
|
|
|
|
|
ret = createXLXNetwork1();
|
|
|
|
|
if (!ret)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_conf.getXLXNetwork2Enabled()) {
|
|
|
|
|
ret = createXLXNetwork2();
|
2017-05-03 18:48:55 +02:00
|
|
|
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-26 14:26:39 +02:00
|
|
|
CVoice* voice1 = NULL;
|
|
|
|
|
CVoice* voice2 = NULL;
|
|
|
|
|
if (m_conf.getVoiceEnabled() && (m_xlxNetwork1 != NULL || m_xlxNetwork2 != 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
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
if (m_xlxNetwork1 != NULL) {
|
|
|
|
|
voice1 = new CVoice(directory, language, m_repeater->getId(), m_xlx1Slot, m_xlx1TG);
|
|
|
|
|
bool ret = voice1->open();
|
|
|
|
|
if (!ret) {
|
|
|
|
|
delete voice1;
|
|
|
|
|
voice1 = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-05-01 15:46:43 +02:00
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
if (m_xlxNetwork2 != NULL) {
|
|
|
|
|
voice2 = new CVoice(directory, language, m_repeater->getId(), m_xlx2Slot, m_xlx2TG);
|
|
|
|
|
bool ret = voice2->open();
|
|
|
|
|
if (!ret) {
|
|
|
|
|
delete voice2;
|
|
|
|
|
voice2 = NULL;
|
|
|
|
|
}
|
2017-05-01 15:46:43 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
CTimer* timer[3U];
|
|
|
|
|
timer[1U] = new CTimer(1000U, timeout);
|
|
|
|
|
timer[2U] = new CTimer(1000U, timeout);
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-05-03 18:48:55 +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;
|
|
|
|
|
|
2017-04-30 12:13:35 +02:00
|
|
|
bool ret = m_repeater->read(data);
|
2017-04-20 21:51:30 +02:00
|
|
|
if (ret) {
|
|
|
|
|
unsigned int slotNo = data.getSlotNo();
|
2017-05-29 20:24:13 +02:00
|
|
|
unsigned int srcId = data.getSrcId();
|
2017-05-03 18:48:55 +02:00
|
|
|
unsigned int dstId = data.getDstId();
|
|
|
|
|
FLCO flco = data.getFLCO();
|
|
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
if (flco == FLCO_GROUP && slotNo == m_xlx1Slot && dstId == m_xlx1TG) {
|
2017-05-27 17:26:52 +02:00
|
|
|
m_xlx1Rewrite->processRF(data);
|
2017-05-26 14:26:39 +02:00
|
|
|
m_xlxNetwork1->write(data);
|
|
|
|
|
status[slotNo] = DMRGWS_XLXREFLECTOR1;
|
|
|
|
|
timer[slotNo]->start();
|
|
|
|
|
} else if (flco == FLCO_GROUP && slotNo == m_xlx2Slot && dstId == m_xlx2TG) {
|
2017-05-27 17:26:52 +02:00
|
|
|
m_xlx2Rewrite->processRF(data);
|
2017-05-26 14:26:39 +02:00
|
|
|
m_xlxNetwork2->write(data);
|
|
|
|
|
status[slotNo] = DMRGWS_XLXREFLECTOR2;
|
2017-05-03 18:48:55 +02:00
|
|
|
timer[slotNo]->start();
|
2017-05-26 14:26:39 +02:00
|
|
|
} else if (flco == FLCO_USER_USER && slotNo == m_xlx1Slot && dstId >= m_xlx1Base && dstId <= (m_xlx1Base + 26U)) {
|
|
|
|
|
dstId += 4000U;
|
|
|
|
|
dstId -= m_xlx1Base;
|
|
|
|
|
|
|
|
|
|
if (dstId != m_xlx1Reflector) {
|
2017-05-29 20:24:13 +02:00
|
|
|
if (dstId == 4000U) {
|
2017-05-26 14:26:39 +02:00
|
|
|
LogMessage("XLX-1, Unlinking");
|
2017-05-29 20:24:13 +02:00
|
|
|
} else {
|
|
|
|
|
if (m_xlx1Reflector != 4000U)
|
|
|
|
|
writeXLXLink(srcId, 4000U, m_xlxNetwork1);
|
|
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
LogMessage("XLX-1, Linking to reflector %u", dstId);
|
2017-05-29 20:24:13 +02:00
|
|
|
}
|
2017-05-26 14:26:39 +02:00
|
|
|
|
2017-05-29 20:24:13 +02:00
|
|
|
writeXLXLink(srcId, dstId, m_xlxNetwork1);
|
2017-05-26 14:26:39 +02:00
|
|
|
m_xlx1Reflector = dstId;
|
|
|
|
|
changed = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
status[slotNo] = DMRGWS_XLXREFLECTOR1;
|
|
|
|
|
timer[slotNo]->start();
|
|
|
|
|
|
|
|
|
|
if (voice1 != NULL) {
|
|
|
|
|
unsigned char type = data.getDataType();
|
|
|
|
|
if (type == DT_TERMINATOR_WITH_LC) {
|
|
|
|
|
if (changed) {
|
|
|
|
|
if (m_xlx1Reflector == 4000U)
|
|
|
|
|
voice1->unlinked();
|
|
|
|
|
else
|
|
|
|
|
voice1->linkedTo(m_xlx1Reflector);
|
|
|
|
|
changed = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if (flco == FLCO_USER_USER && slotNo == m_xlx2Slot && dstId >= m_xlx2Base && dstId <= (m_xlx2Base + 26U)) {
|
2017-05-25 19:24:05 +02:00
|
|
|
dstId += 4000U;
|
2017-05-26 14:26:39 +02:00
|
|
|
dstId -= m_xlx2Base;
|
2017-05-25 19:24:05 +02:00
|
|
|
|
2017-05-29 20:24:13 +02:00
|
|
|
if (dstId != m_xlx2Reflector) {
|
|
|
|
|
if (dstId == 4000U) {
|
2017-05-26 14:26:39 +02:00
|
|
|
LogMessage("XLX-2, Unlinking");
|
2017-05-29 20:24:13 +02:00
|
|
|
} else {
|
|
|
|
|
if (m_xlx2Reflector != 4000U)
|
|
|
|
|
writeXLXLink(srcId, 4000U, m_xlxNetwork2);
|
|
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
LogMessage("XLX-2, Linking to reflector %u", dstId);
|
2017-05-29 20:24:13 +02:00
|
|
|
}
|
2017-05-03 18:48:55 +02:00
|
|
|
|
2017-05-29 20:24:13 +02:00
|
|
|
writeXLXLink(srcId, dstId, m_xlxNetwork2);
|
2017-05-26 14:26:39 +02:00
|
|
|
m_xlx2Reflector = dstId;
|
2017-05-03 18:48:55 +02:00
|
|
|
changed = true;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
status[slotNo] = DMRGWS_XLXREFLECTOR2;
|
2017-05-03 18:48:55 +02:00
|
|
|
timer[slotNo]->start();
|
|
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
if (voice2 != NULL) {
|
2017-05-03 18:48:55 +02:00
|
|
|
unsigned char type = data.getDataType();
|
|
|
|
|
if (type == DT_TERMINATOR_WITH_LC) {
|
|
|
|
|
if (changed) {
|
2017-05-26 14:26:39 +02:00
|
|
|
if (m_xlx2Reflector == 4000U)
|
|
|
|
|
voice2->unlinked();
|
2017-04-30 12:01:54 +02:00
|
|
|
else
|
2017-05-26 14:26:39 +02:00
|
|
|
voice2->linkedTo(m_xlx2Reflector);
|
2017-05-03 18:48:55 +02:00
|
|
|
changed = false;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2017-05-06 10:57:17 +02:00
|
|
|
bool rewritten = false;
|
|
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
if (m_dmrNetwork1 != NULL) {
|
|
|
|
|
// Rewrite the slot and/or TG or neither
|
2017-05-14 19:14:09 +02:00
|
|
|
for (std::vector<IRewrite*>::iterator it = m_dmr1RFRewrites.begin(); it != m_dmr1RFRewrites.end(); ++it) {
|
2017-05-27 17:26:52 +02:00
|
|
|
bool ret = (*it)->processRF(data);
|
2017-05-03 18:48:55 +02:00
|
|
|
if (ret) {
|
|
|
|
|
rewritten = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-04-30 12:01:54 +02:00
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
if (rewritten) {
|
|
|
|
|
unsigned int slotNo = data.getSlotNo();
|
2017-05-26 14:26:39 +02:00
|
|
|
if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_DMRNETWORK1) {
|
2017-05-03 18:48:55 +02:00
|
|
|
m_dmrNetwork1->write(data);
|
2017-05-26 14:26:39 +02:00
|
|
|
status[slotNo] = DMRGWS_DMRNETWORK1;
|
2017-05-03 18:48:55 +02:00
|
|
|
timer[slotNo]->start();
|
2017-04-30 12:01:54 +02:00
|
|
|
}
|
2017-05-03 18:48:55 +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
|
2017-05-14 19:14:09 +02:00
|
|
|
for (std::vector<IRewrite*>::iterator it = m_dmr2RFRewrites.begin(); it != m_dmr2RFRewrites.end(); ++it) {
|
2017-05-27 17:26:52 +02:00
|
|
|
bool ret = (*it)->processRF(data);
|
2017-05-06 10:57:17 +02:00
|
|
|
if (ret) {
|
|
|
|
|
rewritten = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2017-05-03 18:48:55 +02:00
|
|
|
}
|
|
|
|
|
|
2017-05-06 10:57:17 +02:00
|
|
|
if (rewritten) {
|
|
|
|
|
unsigned int slotNo = data.getSlotNo();
|
2017-05-26 14:26:39 +02:00
|
|
|
if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_DMRNETWORK2) {
|
2017-05-06 10:57:17 +02:00
|
|
|
m_dmrNetwork2->write(data);
|
2017-05-26 14:26:39 +02:00
|
|
|
status[slotNo] = DMRGWS_DMRNETWORK2;
|
2017-05-06 10:57:17 +02:00
|
|
|
timer[slotNo]->start();
|
|
|
|
|
}
|
2017-05-01 15:46:43 +02:00
|
|
|
}
|
2017-04-20 21:51:30 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
if (m_xlxNetwork1 != NULL) {
|
|
|
|
|
ret = m_xlxNetwork1->read(data);
|
2017-05-03 18:48:55 +02:00
|
|
|
if (ret) {
|
2017-05-26 14:26:39 +02:00
|
|
|
if (status[m_xlx1Slot] == DMRGWS_NONE || status[m_xlx1Slot] == DMRGWS_XLXREFLECTOR1) {
|
2017-05-27 17:26:52 +02:00
|
|
|
bool ret = m_rpt1Rewrite->processNet(data);
|
2017-05-08 19:34:41 +02:00
|
|
|
if (ret) {
|
2017-05-03 18:48:55 +02:00
|
|
|
m_repeater->write(data);
|
2017-05-26 14:26:39 +02:00
|
|
|
status[m_xlx1Slot] = DMRGWS_XLXREFLECTOR1;
|
|
|
|
|
timer[m_xlx1Slot]->start();
|
2017-05-12 18:19:39 +02:00
|
|
|
} else {
|
|
|
|
|
unsigned int slotNo = data.getSlotNo();
|
|
|
|
|
unsigned int dstId = data.getDstId();
|
|
|
|
|
FLCO flco = data.getFLCO();
|
2017-05-26 14:26:39 +02:00
|
|
|
LogWarning("XLX-1, Unexpected data from slot %u %s%u", slotNo, flco == FLCO_GROUP ? "TG" : "", dstId);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_xlxNetwork2 != NULL) {
|
|
|
|
|
ret = m_xlxNetwork2->read(data);
|
|
|
|
|
if (ret) {
|
|
|
|
|
if (status[m_xlx2Slot] == DMRGWS_NONE || status[m_xlx2Slot] == DMRGWS_XLXREFLECTOR2) {
|
2017-05-27 17:26:52 +02:00
|
|
|
bool ret = m_rpt2Rewrite->processNet(data);
|
2017-05-26 14:26:39 +02:00
|
|
|
if (ret) {
|
|
|
|
|
m_repeater->write(data);
|
|
|
|
|
status[m_xlx2Slot] = DMRGWS_XLXREFLECTOR2;
|
|
|
|
|
timer[m_xlx2Slot]->start();
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
unsigned int slotNo = data.getSlotNo();
|
|
|
|
|
unsigned int dstId = data.getDstId();
|
|
|
|
|
FLCO flco = data.getFLCO();
|
|
|
|
|
LogWarning("XLX-2, Unexpected data from slot %u %s%u", slotNo, flco == FLCO_GROUP ? "TG" : "", dstId);
|
2017-05-03 18:48:55 +02:00
|
|
|
}
|
2017-04-20 21:51:30 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
if (m_dmrNetwork1 != NULL) {
|
|
|
|
|
ret = m_dmrNetwork1->read(data);
|
|
|
|
|
if (ret) {
|
2017-05-14 19:14:09 +02:00
|
|
|
// Rewrite the slot and/or TG or neither
|
|
|
|
|
bool rewritten = false;
|
|
|
|
|
for (std::vector<IRewrite*>::iterator it = m_dmr1NetRewrites.begin(); it != m_dmr1NetRewrites.end(); ++it) {
|
2017-05-27 17:26:52 +02:00
|
|
|
bool ret = (*it)->processNet(data);
|
2017-05-14 19:14:09 +02:00
|
|
|
if (ret) {
|
|
|
|
|
rewritten = true;
|
|
|
|
|
break;
|
2017-05-03 18:48:55 +02:00
|
|
|
}
|
2017-05-14 19:14:09 +02:00
|
|
|
}
|
2017-05-03 18:48:55 +02:00
|
|
|
|
2017-05-14 19:14:09 +02:00
|
|
|
if (rewritten) {
|
|
|
|
|
unsigned int slotNo = data.getSlotNo();
|
2017-05-26 14:26:39 +02:00
|
|
|
if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_DMRNETWORK1) {
|
|
|
|
|
m_repeater->write(data);
|
|
|
|
|
status[slotNo] = DMRGWS_DMRNETWORK1;
|
|
|
|
|
timer[slotNo]->start();
|
2017-05-03 18:48:55 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_dmrNetwork2 != NULL) {
|
|
|
|
|
ret = m_dmrNetwork2->read(data);
|
|
|
|
|
if (ret) {
|
2017-05-14 19:14:09 +02:00
|
|
|
// Rewrite the slot and/or TG or neither
|
|
|
|
|
bool rewritten = false;
|
|
|
|
|
for (std::vector<IRewrite*>::iterator it = m_dmr2NetRewrites.begin(); it != m_dmr2NetRewrites.end(); ++it) {
|
2017-05-27 17:26:52 +02:00
|
|
|
bool ret = (*it)->processNet(data);
|
2017-05-14 19:14:09 +02:00
|
|
|
if (ret) {
|
|
|
|
|
rewritten = true;
|
|
|
|
|
break;
|
2017-05-03 18:48:55 +02:00
|
|
|
}
|
2017-05-14 19:14:09 +02:00
|
|
|
}
|
2017-05-03 18:48:55 +02:00
|
|
|
|
2017-05-14 19:14:09 +02:00
|
|
|
if (rewritten) {
|
|
|
|
|
unsigned int slotNo = data.getSlotNo();
|
2017-05-26 14:26:39 +02:00
|
|
|
if (status[slotNo] == DMRGWS_NONE || status[slotNo] == DMRGWS_DMRNETWORK2) {
|
|
|
|
|
m_repeater->write(data);
|
|
|
|
|
status[slotNo] = DMRGWS_DMRNETWORK2;
|
|
|
|
|
timer[slotNo]->start();
|
2017-04-20 21:51:30 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-17 19:58:46 +02:00
|
|
|
unsigned char buffer[50U];
|
|
|
|
|
unsigned int length;
|
|
|
|
|
ret = m_repeater->readPosition(buffer, length);
|
|
|
|
|
if (ret) {
|
2017-05-26 14:26:39 +02:00
|
|
|
if (m_xlxNetwork1 != NULL)
|
|
|
|
|
m_xlxNetwork1->writePosition(buffer, length);
|
|
|
|
|
if (m_xlxNetwork2 != NULL)
|
|
|
|
|
m_xlxNetwork2->writePosition(buffer, length);
|
2017-05-17 19:58:46 +02:00
|
|
|
if (m_dmrNetwork1 != NULL)
|
|
|
|
|
m_dmrNetwork1->writePosition(buffer, length);
|
|
|
|
|
if (m_dmrNetwork2 != NULL)
|
|
|
|
|
m_dmrNetwork2->writePosition(buffer, length);
|
|
|
|
|
}
|
|
|
|
|
ret = m_repeater->readTalkerAlias(buffer, length);
|
|
|
|
|
if (ret) {
|
2017-05-26 14:26:39 +02:00
|
|
|
if (m_xlxNetwork1 != NULL)
|
|
|
|
|
m_xlxNetwork1->writeTalkerAlias(buffer, length);
|
|
|
|
|
if (m_xlxNetwork2 != NULL)
|
|
|
|
|
m_xlxNetwork2->writeTalkerAlias(buffer, length);
|
2017-05-17 19:58:46 +02:00
|
|
|
if (m_dmrNetwork1 != NULL)
|
|
|
|
|
m_dmrNetwork1->writeTalkerAlias(buffer, length);
|
|
|
|
|
if (m_dmrNetwork2 != NULL)
|
|
|
|
|
m_dmrNetwork2->writeTalkerAlias(buffer, length);
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
if (voice1 != NULL) {
|
|
|
|
|
ret = voice1->read(data);
|
|
|
|
|
if (ret) {
|
|
|
|
|
m_repeater->write(data);
|
|
|
|
|
status[m_xlx1Slot] = DMRGWS_XLXREFLECTOR1;
|
|
|
|
|
timer[m_xlx1Slot]->start();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (voice2 != NULL) {
|
|
|
|
|
ret = voice2->read(data);
|
2017-05-01 15:46:43 +02:00
|
|
|
if (ret) {
|
|
|
|
|
m_repeater->write(data);
|
2017-05-26 14:26:39 +02:00
|
|
|
status[m_xlx2Slot] = DMRGWS_XLXREFLECTOR2;
|
|
|
|
|
timer[m_xlx2Slot]->start();
|
2017-05-01 15:46:43 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-20 21:51:30 +02:00
|
|
|
unsigned int ms = stopWatch.elapsed();
|
|
|
|
|
stopWatch.start();
|
|
|
|
|
|
2017-04-30 12:13:35 +02:00
|
|
|
m_repeater->clock(ms);
|
2017-05-03 18:48:55 +02:00
|
|
|
|
|
|
|
|
if (m_dmrNetwork1 != NULL)
|
|
|
|
|
m_dmrNetwork1->clock(ms);
|
|
|
|
|
|
|
|
|
|
if (m_dmrNetwork2 != NULL)
|
|
|
|
|
m_dmrNetwork2->clock(ms);
|
|
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
if (m_xlxNetwork1 != NULL)
|
|
|
|
|
m_xlxNetwork1->clock(ms);
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
if (m_xlxNetwork2 != NULL)
|
|
|
|
|
m_xlxNetwork2->clock(ms);
|
|
|
|
|
|
|
|
|
|
if (voice1 != NULL)
|
|
|
|
|
voice1->clock(ms);
|
|
|
|
|
|
|
|
|
|
if (voice2 != NULL)
|
|
|
|
|
voice2->clock(ms);
|
2017-05-01 15:46:43 +02:00
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
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-26 14:26:39 +02:00
|
|
|
delete voice1;
|
|
|
|
|
delete voice2;
|
2017-05-01 15:46:43 +02:00
|
|
|
|
2017-04-30 12:13:35 +02:00
|
|
|
m_repeater->close();
|
|
|
|
|
delete m_repeater;
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-05-03 18:48:55 +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
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
if (m_xlxNetwork1 != NULL) {
|
|
|
|
|
m_xlxNetwork1->close();
|
|
|
|
|
delete m_xlxNetwork1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_xlxNetwork2 != NULL) {
|
|
|
|
|
m_xlxNetwork2->close();
|
|
|
|
|
delete m_xlxNetwork2;
|
2017-05-03 18:48:55 +02:00
|
|
|
}
|
2017-04-20 21:51:30 +02:00
|
|
|
|
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);
|
|
|
|
|
|
2017-04-30 12:13:35 +02:00
|
|
|
m_repeater = new CMMDVMNetwork(rptAddress, rptPort, localAddress, localPort, debug);
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-04-30 12:13:35 +02:00
|
|
|
bool ret = m_repeater->open();
|
2017-04-20 21:51:30 +02:00
|
|
|
if (!ret) {
|
2017-04-30 12:13:35 +02:00
|
|
|
delete m_repeater;
|
|
|
|
|
m_repeater = NULL;
|
2017-04-20 21:51:30 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
bool CDMRGateway::createDMRNetwork1()
|
2017-04-20 21:51:30 +02:00
|
|
|
{
|
2017-05-03 18:48:55 +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();
|
2017-05-03 18:48:55 +02:00
|
|
|
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();
|
|
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
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
|
|
|
|
2017-05-24 18:42:48 +02:00
|
|
|
std::string options = m_conf.getDMRNetwork1Options();
|
|
|
|
|
if (options.empty())
|
|
|
|
|
options = m_repeater->getOptions();
|
|
|
|
|
|
2017-04-20 21:51:30 +02:00
|
|
|
if (!options.empty()) {
|
|
|
|
|
LogInfo(" Options: %s", options.c_str());
|
2017-05-03 18:48:55 +02:00
|
|
|
m_dmrNetwork1->setOptions(options);
|
2017-04-20 21:51:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned char config[400U];
|
2017-04-30 12:13:35 +02:00
|
|
|
unsigned int len = m_repeater->getConfig(config);
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
m_dmrNetwork1->setConfig(config, len);
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
bool ret = m_dmrNetwork1->open();
|
2017-04-20 21:51:30 +02:00
|
|
|
if (!ret) {
|
2017-05-03 18:48:55 +02:00
|
|
|
delete m_dmrNetwork1;
|
|
|
|
|
m_dmrNetwork1 = NULL;
|
2017-04-20 21:51:30 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-14 19:14:09 +02:00
|
|
|
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork1TGRewrites();
|
|
|
|
|
for (std::vector<CTGRewriteStruct>::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) {
|
2017-05-15 22:16:52 +02:00
|
|
|
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);
|
|
|
|
|
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);
|
2017-05-03 18:48:55 +02:00
|
|
|
|
2017-05-15 22:16:52 +02:00
|
|
|
CRewriteTG* rfRewrite = new CRewriteTG("DMR-1", (*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toTG, (*it).m_range);
|
|
|
|
|
CRewriteTG* netRewrite = new CRewriteTG("DMR-1", (*it).m_toSlot, (*it).m_toTG, (*it).m_fromSlot, (*it).m_fromTG, (*it).m_range);
|
2017-05-03 18:48:55 +02:00
|
|
|
|
2017-05-15 22:16:52 +02:00
|
|
|
m_dmr1RFRewrites.push_back(rfRewrite);
|
|
|
|
|
m_dmr1NetRewrites.push_back(netRewrite);
|
2017-05-03 18:48:55 +02:00
|
|
|
}
|
|
|
|
|
|
2017-05-14 19:14:09 +02:00
|
|
|
std::vector<CPCRewriteStruct> pcRewrites = m_conf.getDMRNetwork1PCRewrites();
|
|
|
|
|
for (std::vector<CPCRewriteStruct>::const_iterator it = pcRewrites.begin(); it != pcRewrites.end(); ++it) {
|
2017-05-15 22:16:52 +02:00
|
|
|
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);
|
|
|
|
|
|
2017-05-25 19:19:47 +02:00
|
|
|
CRewritePC* rewrite = new CRewritePC("DMR-1", (*it).m_fromSlot, (*it).m_fromId, (*it).m_toSlot, (*it).m_toId, (*it).m_range);
|
2017-05-15 22:16:52 +02:00
|
|
|
|
2017-05-25 19:19:47 +02:00
|
|
|
m_dmr1RFRewrites.push_back(rewrite);
|
2017-05-15 22:16:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<CTypeRewriteStruct> typeRewrites = m_conf.getDMRNetwork1TypeRewrites();
|
|
|
|
|
for (std::vector<CTypeRewriteStruct>::const_iterator it = typeRewrites.begin(); it != typeRewrites.end(); ++it) {
|
2017-05-24 18:46:07 +02:00
|
|
|
LogInfo(" Rewrite RF: %u:TG%u -> %u:%u", (*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toId);
|
2017-05-15 22:16:52 +02:00
|
|
|
|
2017-05-24 18:46:07 +02:00
|
|
|
CRewriteType* rewrite = new CRewriteType("DMR-1", (*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toId);
|
2017-05-15 22:16:52 +02:00
|
|
|
|
2017-05-24 18:46:07 +02:00
|
|
|
m_dmr1RFRewrites.push_back(rewrite);
|
2017-05-15 22:16:52 +02:00
|
|
|
}
|
2017-05-03 18:48:55 +02:00
|
|
|
|
2017-05-15 22:16:52 +02:00
|
|
|
std::vector<CSrcRewriteStruct> srcRewrites = m_conf.getDMRNetwork1SrcRewrites();
|
|
|
|
|
for (std::vector<CSrcRewriteStruct>::const_iterator it = srcRewrites.begin(); it != srcRewrites.end(); ++it) {
|
2017-05-16 19:42:37 +02:00
|
|
|
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);
|
2017-05-14 19:14:09 +02:00
|
|
|
|
2017-05-16 19:42:37 +02:00
|
|
|
CRewriteSrc* rewrite = new CRewriteSrc("DMR-1", (*it).m_fromSlot, (*it).m_fromId, (*it).m_toSlot, (*it).m_toTG, (*it).m_range);
|
2017-05-15 22:16:52 +02:00
|
|
|
|
|
|
|
|
m_dmr1NetRewrites.push_back(rewrite);
|
2017-05-14 19:14:09 +02:00
|
|
|
}
|
2017-05-03 18:48:55 +02:00
|
|
|
|
2017-05-30 13:13:17 +02:00
|
|
|
std::vector<unsigned int> tgPassAll = m_conf.getDMRNetwork1PassAllTG();
|
2017-05-27 17:50:34 +02:00
|
|
|
for (std::vector<unsigned int>::const_iterator it = tgPassAll.begin(); it != tgPassAll.end(); ++it) {
|
|
|
|
|
LogInfo(" Pass All TG: %u", *it);
|
|
|
|
|
|
|
|
|
|
CPassAllTG* rfPassAllTG = new CPassAllTG("DMR-1", *it);
|
|
|
|
|
CPassAllTG* netPassAllTG = new CPassAllTG("DMR-1", *it);
|
|
|
|
|
|
|
|
|
|
m_dmr1RFRewrites.push_back(rfPassAllTG);
|
|
|
|
|
m_dmr1NetRewrites.push_back(netPassAllTG);
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-30 13:13:17 +02:00
|
|
|
std::vector<unsigned int> pcPassAll = m_conf.getDMRNetwork1PassAllPC();
|
2017-05-27 17:50:34 +02:00
|
|
|
for (std::vector<unsigned int>::const_iterator it = pcPassAll.begin(); it != pcPassAll.end(); ++it) {
|
|
|
|
|
LogInfo(" Pass All PC: %u", *it);
|
|
|
|
|
|
|
|
|
|
CPassAllPC* rfPassAllPC = new CPassAllPC("DMR-1", *it);
|
|
|
|
|
CPassAllPC* netPassAllPC = new CPassAllPC("DMR-1", *it);
|
|
|
|
|
|
|
|
|
|
m_dmr1RFRewrites.push_back(rfPassAllPC);
|
|
|
|
|
m_dmr1NetRewrites.push_back(netPassAllPC);
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
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();
|
2017-05-03 18:48:55 +02:00
|
|
|
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();
|
|
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
LogInfo("DMR Network 2 Parameters");
|
2017-05-06 10:57:17 +02:00
|
|
|
LogInfo(" Id: %u", id);
|
2017-05-03 18:48:55 +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_dmrNetwork2 = new CDMRNetwork(address, port, local, id, password, "DMR-2", debug);
|
2017-05-03 18:48:55 +02:00
|
|
|
|
2017-05-24 18:42:48 +02:00
|
|
|
std::string options = m_conf.getDMRNetwork2Options();
|
|
|
|
|
if (options.empty())
|
|
|
|
|
options = m_repeater->getOptions();
|
|
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-14 19:14:09 +02:00
|
|
|
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork2TGRewrites();
|
|
|
|
|
for (std::vector<CTGRewriteStruct>::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) {
|
2017-05-15 22:16:52 +02:00
|
|
|
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);
|
|
|
|
|
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);
|
2017-05-03 18:48:55 +02:00
|
|
|
|
2017-05-15 22:16:52 +02:00
|
|
|
CRewriteTG* rfRewrite = new CRewriteTG("DMR-2", (*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toTG, (*it).m_range);
|
|
|
|
|
CRewriteTG* netRewrite = new CRewriteTG("DMR-2", (*it).m_toSlot, (*it).m_toTG, (*it).m_fromSlot, (*it).m_fromTG, (*it).m_range);
|
2017-05-03 18:48:55 +02:00
|
|
|
|
2017-05-15 22:16:52 +02:00
|
|
|
m_dmr2RFRewrites.push_back(rfRewrite);
|
|
|
|
|
m_dmr2NetRewrites.push_back(netRewrite);
|
2017-05-03 18:48:55 +02:00
|
|
|
}
|
|
|
|
|
|
2017-05-14 19:14:09 +02:00
|
|
|
std::vector<CPCRewriteStruct> pcRewrites = m_conf.getDMRNetwork2PCRewrites();
|
|
|
|
|
for (std::vector<CPCRewriteStruct>::const_iterator it = pcRewrites.begin(); it != pcRewrites.end(); ++it) {
|
2017-05-15 22:16:52 +02:00
|
|
|
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);
|
|
|
|
|
|
2017-05-25 19:19:47 +02:00
|
|
|
CRewritePC* rewrite = new CRewritePC("DMR-2", (*it).m_fromSlot, (*it).m_fromId, (*it).m_toSlot, (*it).m_toId, (*it).m_range);
|
2017-05-15 22:16:52 +02:00
|
|
|
|
2017-05-25 19:19:47 +02:00
|
|
|
m_dmr2RFRewrites.push_back(rewrite);
|
2017-05-15 22:16:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<CTypeRewriteStruct> typeRewrites = m_conf.getDMRNetwork2TypeRewrites();
|
|
|
|
|
for (std::vector<CTypeRewriteStruct>::const_iterator it = typeRewrites.begin(); it != typeRewrites.end(); ++it) {
|
2017-05-24 18:46:07 +02:00
|
|
|
LogInfo(" Rewrite RF: %u:TG%u -> %u:%u", (*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toId);
|
2017-05-15 22:16:52 +02:00
|
|
|
|
2017-05-24 18:46:07 +02:00
|
|
|
CRewriteType* rewrite = new CRewriteType("DMR-2", (*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toId);
|
2017-05-15 22:16:52 +02:00
|
|
|
|
2017-05-24 18:46:07 +02:00
|
|
|
m_dmr2RFRewrites.push_back(rewrite);
|
2017-05-15 22:16:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<CSrcRewriteStruct> srcRewrites = m_conf.getDMRNetwork2SrcRewrites();
|
|
|
|
|
for (std::vector<CSrcRewriteStruct>::const_iterator it = srcRewrites.begin(); it != srcRewrites.end(); ++it) {
|
2017-05-16 19:42:37 +02:00
|
|
|
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);
|
2017-05-14 19:14:09 +02:00
|
|
|
|
2017-05-16 19:42:37 +02:00
|
|
|
CRewriteSrc* rewrite = new CRewriteSrc("DMR-2", (*it).m_fromSlot, (*it).m_fromId, (*it).m_toSlot, (*it).m_toTG, (*it).m_range);
|
2017-05-03 18:48:55 +02:00
|
|
|
|
2017-05-15 22:16:52 +02:00
|
|
|
m_dmr2NetRewrites.push_back(rewrite);
|
2017-05-14 19:14:09 +02:00
|
|
|
}
|
2017-05-03 18:48:55 +02:00
|
|
|
|
2017-05-27 17:50:34 +02:00
|
|
|
std::vector<unsigned int> tgPassAll = m_conf.getDMRNetwork2PassAllTG();
|
|
|
|
|
for (std::vector<unsigned int>::const_iterator it = tgPassAll.begin(); it != tgPassAll.end(); ++it) {
|
|
|
|
|
LogInfo(" Pass All TG: %u", *it);
|
|
|
|
|
|
|
|
|
|
CPassAllTG* rfPassAllTG = new CPassAllTG("DMR-2", *it);
|
|
|
|
|
CPassAllTG* netPassAllTG = new CPassAllTG("DMR-2", *it);
|
|
|
|
|
|
|
|
|
|
m_dmr2RFRewrites.push_back(rfPassAllTG);
|
|
|
|
|
m_dmr2NetRewrites.push_back(netPassAllTG);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<unsigned int> pcPassAll = m_conf.getDMRNetwork2PassAllPC();
|
|
|
|
|
for (std::vector<unsigned int>::const_iterator it = pcPassAll.begin(); it != pcPassAll.end(); ++it) {
|
|
|
|
|
LogInfo(" Pass All PC: %u", *it);
|
|
|
|
|
|
|
|
|
|
CPassAllPC* rfPassAllPC = new CPassAllPC("DMR-2", *it);
|
|
|
|
|
CPassAllPC* netPassAllPC = new CPassAllPC("DMR-2", *it);
|
|
|
|
|
|
|
|
|
|
m_dmr2RFRewrites.push_back(rfPassAllPC);
|
|
|
|
|
m_dmr2NetRewrites.push_back(netPassAllPC);
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-20 21:51:30 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
bool CDMRGateway::createXLXNetwork1()
|
|
|
|
|
{
|
|
|
|
|
std::string address = m_conf.getXLXNetwork1Address();
|
|
|
|
|
unsigned int port = m_conf.getXLXNetwork1Port();
|
|
|
|
|
unsigned int local = m_conf.getXLXNetwork1Local();
|
|
|
|
|
unsigned int id = m_conf.getXLXNetwork1Id();
|
|
|
|
|
std::string password = m_conf.getXLXNetwork1Password();
|
|
|
|
|
bool debug = m_conf.getXLXNetwork1Debug();
|
|
|
|
|
|
|
|
|
|
if (id == 0U)
|
|
|
|
|
id = m_repeater->getId();
|
|
|
|
|
|
|
|
|
|
LogInfo("XLX Network 1 Parameters");
|
|
|
|
|
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");
|
|
|
|
|
|
|
|
|
|
m_xlxNetwork1 = new CDMRNetwork(address, port, local, id, password, "XLX-1", debug);
|
|
|
|
|
|
|
|
|
|
std::string options = m_conf.getXLXNetwork1Options();
|
|
|
|
|
if (!options.empty()) {
|
|
|
|
|
LogInfo(" Options: %s", options.c_str());
|
|
|
|
|
m_xlxNetwork1->setOptions(options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned char config[400U];
|
|
|
|
|
unsigned int len = m_repeater->getConfig(config);
|
|
|
|
|
|
|
|
|
|
m_xlxNetwork1->setConfig(config, len);
|
|
|
|
|
|
|
|
|
|
bool ret = m_xlxNetwork1->open();
|
|
|
|
|
if (!ret) {
|
|
|
|
|
delete m_xlxNetwork1;
|
|
|
|
|
m_xlxNetwork1 = NULL;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_xlx1Slot = m_conf.getXLXNetwork1Slot();
|
|
|
|
|
m_xlx1TG = m_conf.getXLXNetwork1TG();
|
|
|
|
|
m_xlx1Base = m_conf.getXLXNetwork1Base();
|
|
|
|
|
|
|
|
|
|
LogInfo(" Slot: %u", m_xlx1Slot);
|
|
|
|
|
LogInfo(" TG: %u", m_xlx1TG);
|
|
|
|
|
LogInfo(" Base: %u", m_xlx1Base);
|
|
|
|
|
|
|
|
|
|
m_rpt1Rewrite = new CRewriteTG("XLX-1", XLX_SLOT, XLX_TG, m_xlx1Slot, m_xlx1TG, 1U);
|
|
|
|
|
m_xlx1Rewrite = new CRewriteTG("XLX-1", m_xlx1Slot, m_xlx1TG, XLX_SLOT, XLX_TG, 1U);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool CDMRGateway::createXLXNetwork2()
|
2017-04-20 21:51:30 +02:00
|
|
|
{
|
2017-05-26 14:26:39 +02:00
|
|
|
std::string address = m_conf.getXLXNetwork2Address();
|
|
|
|
|
unsigned int port = m_conf.getXLXNetwork2Port();
|
|
|
|
|
unsigned int local = m_conf.getXLXNetwork2Local();
|
|
|
|
|
unsigned int id = m_conf.getXLXNetwork2Id();
|
|
|
|
|
std::string password = m_conf.getXLXNetwork2Password();
|
|
|
|
|
bool debug = m_conf.getXLXNetwork2Debug();
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-05-06 10:57:17 +02:00
|
|
|
if (id == 0U)
|
|
|
|
|
id = m_repeater->getId();
|
|
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
LogInfo("XLX Network 2 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-26 14:26:39 +02:00
|
|
|
m_xlxNetwork2 = new CDMRNetwork(address, port, local, id, password, "XLX-2", debug);
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
std::string options = m_conf.getXLXNetwork2Options();
|
2017-04-20 21:51:30 +02:00
|
|
|
if (!options.empty()) {
|
|
|
|
|
LogInfo(" Options: %s", options.c_str());
|
2017-05-26 14:26:39 +02:00
|
|
|
m_xlxNetwork2->setOptions(options);
|
2017-04-20 21:51:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned char config[400U];
|
2017-04-30 12:13:35 +02:00
|
|
|
unsigned int len = m_repeater->getConfig(config);
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
m_xlxNetwork2->setConfig(config, len);
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
bool ret = m_xlxNetwork2->open();
|
2017-04-20 21:51:30 +02:00
|
|
|
if (!ret) {
|
2017-05-26 14:26:39 +02:00
|
|
|
delete m_xlxNetwork2;
|
|
|
|
|
m_xlxNetwork2 = NULL;
|
2017-04-20 21:51:30 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
m_xlx2Slot = m_conf.getXLXNetwork2Slot();
|
|
|
|
|
m_xlx2TG = m_conf.getXLXNetwork2TG();
|
|
|
|
|
m_xlx2Base = m_conf.getXLXNetwork2Base();
|
2017-05-03 18:48:55 +02:00
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
LogInfo(" Slot: %u", m_xlx2Slot);
|
|
|
|
|
LogInfo(" TG: %u", m_xlx2TG);
|
|
|
|
|
LogInfo(" Base: %u", m_xlx2Base);
|
2017-05-03 18:48:55 +02:00
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
m_rpt2Rewrite = new CRewriteTG("XLX-2", XLX_SLOT, XLX_TG, m_xlx2Slot, m_xlx2TG, 1U);
|
|
|
|
|
m_xlx2Rewrite = new CRewriteTG("XLX-2", m_xlx2Slot, m_xlx2TG, XLX_SLOT, XLX_TG, 1U);
|
2017-05-06 18:17:34 +02:00
|
|
|
|
2017-04-20 21:51:30 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
2017-05-29 20:24:13 +02:00
|
|
|
|
|
|
|
|
void CDMRGateway::writeXLXLink(unsigned int srcId, unsigned int dstId, CDMRNetwork* network)
|
|
|
|
|
{
|
|
|
|
|
assert(network != NULL);
|
|
|
|
|
|
|
|
|
|
unsigned int streamId = ::rand() + 1U;
|
|
|
|
|
|
|
|
|
|
CDMRData data;
|
|
|
|
|
|
|
|
|
|
data.setSlotNo(XLX_SLOT);
|
|
|
|
|
data.setFLCO(FLCO_USER_USER);
|
|
|
|
|
data.setSrcId(srcId);
|
|
|
|
|
data.setDstId(dstId);
|
|
|
|
|
data.setDataType(DT_VOICE_LC_HEADER);
|
|
|
|
|
data.setN(0U);
|
|
|
|
|
data.setStreamId(streamId);
|
|
|
|
|
|
|
|
|
|
unsigned char buffer[DMR_FRAME_LENGTH_BYTES];
|
|
|
|
|
|
|
|
|
|
CDMRLC lc;
|
|
|
|
|
lc.setSrcId(srcId);
|
|
|
|
|
lc.setDstId(dstId);
|
|
|
|
|
lc.setFLCO(FLCO_USER_USER);
|
|
|
|
|
|
|
|
|
|
CDMRFullLC fullLC;
|
|
|
|
|
fullLC.encode(lc, buffer, DT_VOICE_LC_HEADER);
|
|
|
|
|
|
|
|
|
|
CDMRSlotType slotType;
|
|
|
|
|
slotType.setColorCode(COLOR_CODE);
|
|
|
|
|
slotType.setDataType(DT_VOICE_LC_HEADER);
|
|
|
|
|
slotType.getData(buffer);
|
|
|
|
|
|
|
|
|
|
CSync::addDMRDataSync(buffer, true);
|
|
|
|
|
|
|
|
|
|
data.setData(buffer);
|
|
|
|
|
|
|
|
|
|
for (unsigned int i = 0U; i < 3U; i++) {
|
|
|
|
|
data.setSeqNo(i);
|
|
|
|
|
network->write(data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
data.setDataType(DT_TERMINATOR_WITH_LC);
|
|
|
|
|
|
|
|
|
|
fullLC.encode(lc, buffer, DT_TERMINATOR_WITH_LC);
|
|
|
|
|
|
|
|
|
|
slotType.setDataType(DT_TERMINATOR_WITH_LC);
|
|
|
|
|
slotType.getData(buffer);
|
|
|
|
|
|
|
|
|
|
data.setData(buffer);
|
|
|
|
|
|
|
|
|
|
for (unsigned int i = 0U; i < 2U; i++) {
|
|
|
|
|
data.setSeqNo(i + 3U);
|
|
|
|
|
network->write(data);
|
|
|
|
|
}
|
|
|
|
|
}
|