2017-04-20 21:51:30 +02:00
|
|
|
/*
|
2020-04-01 23:22:12 +02:00
|
|
|
* Copyright (C) 2015-2020 by Jonathan Naylor G4KLX
|
2017-04-20 21:51:30 +02:00
|
|
|
*
|
|
|
|
|
* 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"
|
2019-05-19 08:56:39 +02:00
|
|
|
#include "RewriteSrcId.h"
|
|
|
|
|
#include "RewriteDstId.h"
|
2020-04-01 23:22:12 +02:00
|
|
|
#include "RewriteDynTGNet.h"
|
|
|
|
|
#include "RewriteDynTGRF.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"
|
2020-04-03 16:25:33 +02:00
|
|
|
#include "XLXVoice.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"
|
|
|
|
|
#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)
|
|
|
|
|
{
|
2017-06-23 10:07:50 +02:00
|
|
|
m_killed = true;
|
|
|
|
|
m_signal = signum;
|
2017-04-20 21:51:30 +02:00
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
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.";
|
2020-04-01 23:22:12 +02:00
|
|
|
const char* HEADER4 = "Copyright(C) 2017-2020 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-06-07 20:34:18 +02:00
|
|
|
::signal(SIGINT, sigHandler);
|
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-06-07 20:34:18 +02:00
|
|
|
if (m_signal == 2)
|
|
|
|
|
::LogInfo("DMRGateway-%s exited on receipt of SIGINT", VERSION);
|
|
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
if (m_signal == 15)
|
2017-06-07 20:34:18 +02:00
|
|
|
::LogInfo("DMRGateway-%s exited on receipt of SIGTERM", VERSION);
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
if (m_signal == 1)
|
2017-06-07 20:34:18 +02:00
|
|
|
::LogInfo("DMRGateway-%s restarted on receipt of SIGHUP", VERSION);
|
2017-05-03 18:48:55 +02:00
|
|
|
} 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),
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status(NULL),
|
2017-04-30 12:13:35 +02:00
|
|
|
m_repeater(NULL),
|
2017-10-08 15:13:52 +02:00
|
|
|
m_config(NULL),
|
|
|
|
|
m_configLen(0U),
|
2017-05-03 18:48:55 +02:00
|
|
|
m_dmrNetwork1(NULL),
|
2017-08-01 22:51:22 +02:00
|
|
|
m_dmr1Name(),
|
2017-05-03 18:48:55 +02:00
|
|
|
m_dmrNetwork2(NULL),
|
2017-08-01 22:51:22 +02:00
|
|
|
m_dmr2Name(),
|
2017-11-21 12:30:13 +01:00
|
|
|
m_dmrNetwork3(NULL),
|
|
|
|
|
m_dmr3Name(),
|
2019-03-16 11:08:32 +01:00
|
|
|
m_dmrNetwork4(NULL),
|
|
|
|
|
m_dmr4Name(),
|
2019-07-17 09:21:52 +02:00
|
|
|
m_dmrNetwork5(NULL),
|
|
|
|
|
m_dmr5Name(),
|
2017-08-20 22:48:49 +02:00
|
|
|
m_xlxReflectors(NULL),
|
|
|
|
|
m_xlxNetwork(NULL),
|
|
|
|
|
m_xlxId(0U),
|
|
|
|
|
m_xlxNumber(0U),
|
|
|
|
|
m_xlxReflector(4000U),
|
|
|
|
|
m_xlxSlot(0U),
|
|
|
|
|
m_xlxTG(0U),
|
|
|
|
|
m_xlxBase(0U),
|
|
|
|
|
m_xlxLocal(0U),
|
2017-09-26 15:58:22 +02:00
|
|
|
m_xlxPort(62030U),
|
|
|
|
|
m_xlxPassword("passw0rd"),
|
2017-08-20 22:48:49 +02:00
|
|
|
m_xlxStartup(950U),
|
|
|
|
|
m_xlxRoom(4000U),
|
|
|
|
|
m_xlxRelink(1000U),
|
|
|
|
|
m_xlxConnected(false),
|
|
|
|
|
m_xlxDebug(false),
|
2018-10-21 11:18:55 +02:00
|
|
|
m_xlxUserControl(true),
|
2018-10-21 16:26:54 +02:00
|
|
|
m_xlxModule(),
|
2017-08-20 22:48:49 +02:00
|
|
|
m_rptRewrite(NULL),
|
|
|
|
|
m_xlxRewrite(NULL),
|
2017-05-03 18:48:55 +02:00
|
|
|
m_dmr1NetRewrites(),
|
|
|
|
|
m_dmr1RFRewrites(),
|
2019-05-19 08:56:39 +02:00
|
|
|
m_dmr1SrcRewrites(),
|
2017-05-03 18:48:55 +02:00
|
|
|
m_dmr2NetRewrites(),
|
2017-06-07 21:40:51 +02:00
|
|
|
m_dmr2RFRewrites(),
|
2019-05-19 08:56:39 +02:00
|
|
|
m_dmr2SrcRewrites(),
|
2017-11-21 12:30:13 +01:00
|
|
|
m_dmr3NetRewrites(),
|
|
|
|
|
m_dmr3RFRewrites(),
|
2019-05-19 08:56:39 +02:00
|
|
|
m_dmr3SrcRewrites(),
|
|
|
|
|
m_dmr4NetRewrites(),
|
|
|
|
|
m_dmr4RFRewrites(),
|
|
|
|
|
m_dmr4SrcRewrites(),
|
2019-07-17 09:21:52 +02:00
|
|
|
m_dmr5NetRewrites(),
|
|
|
|
|
m_dmr5RFRewrites(),
|
|
|
|
|
m_dmr5SrcRewrites(),
|
2017-06-07 21:40:51 +02:00
|
|
|
m_dmr1Passalls(),
|
2017-11-21 12:30:13 +01:00
|
|
|
m_dmr2Passalls(),
|
2019-07-17 09:21:52 +02:00
|
|
|
m_dmr3Passalls(),
|
|
|
|
|
m_dmr4Passalls(),
|
2020-04-08 00:03:27 +02:00
|
|
|
m_dmr5Passalls(),
|
|
|
|
|
m_dynVoices()
|
2017-04-20 21:51:30 +02:00
|
|
|
{
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status = new DMRGW_STATUS[3U];
|
|
|
|
|
m_status[1U] = DMRGWS_NONE;
|
|
|
|
|
m_status[2U] = DMRGWS_NONE;
|
|
|
|
|
|
2017-10-08 15:13:52 +02:00
|
|
|
m_config = new unsigned char[400U];
|
2017-04-20 21:51:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CDMRGateway::~CDMRGateway()
|
|
|
|
|
{
|
2017-08-02 20:30:39 +02:00
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr1NetRewrites.begin(); it != m_dmr1NetRewrites.end(); ++it)
|
2017-05-03 18:48:55 +02:00
|
|
|
delete *it;
|
|
|
|
|
|
2017-08-02 20:30:39 +02:00
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr1RFRewrites.begin(); it != m_dmr1RFRewrites.end(); ++it)
|
2017-05-03 18:48:55 +02:00
|
|
|
delete *it;
|
2017-11-21 12:30:13 +01:00
|
|
|
|
2019-05-19 08:56:39 +02:00
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr1SrcRewrites.begin(); it != m_dmr1SrcRewrites.end(); ++it)
|
|
|
|
|
delete *it;
|
|
|
|
|
|
2017-08-02 20:30:39 +02:00
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr2NetRewrites.begin(); it != m_dmr2NetRewrites.end(); ++it)
|
2020-04-08 00:03:27 +02:00
|
|
|
delete *it;
|
2017-05-03 18:48:55 +02:00
|
|
|
|
2017-08-02 20:30:39 +02:00
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr2RFRewrites.begin(); it != m_dmr2RFRewrites.end(); ++it)
|
2020-04-08 00:03:27 +02:00
|
|
|
delete *it;
|
2017-05-14 19:14:09 +02:00
|
|
|
|
2019-05-19 08:56:39 +02:00
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr2SrcRewrites.begin(); it != m_dmr2SrcRewrites.end(); ++it)
|
|
|
|
|
delete *it;
|
|
|
|
|
|
2017-11-21 12:30:13 +01:00
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr3NetRewrites.begin(); it != m_dmr3NetRewrites.end(); ++it)
|
|
|
|
|
delete *it;
|
|
|
|
|
|
|
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr3RFRewrites.begin(); it != m_dmr3RFRewrites.end(); ++it)
|
|
|
|
|
delete *it;
|
|
|
|
|
|
2019-05-19 08:56:39 +02:00
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr3SrcRewrites.begin(); it != m_dmr3SrcRewrites.end(); ++it)
|
|
|
|
|
delete *it;
|
|
|
|
|
|
|
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr4NetRewrites.begin(); it != m_dmr4NetRewrites.end(); ++it)
|
|
|
|
|
delete *it;
|
|
|
|
|
|
|
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr4RFRewrites.begin(); it != m_dmr4RFRewrites.end(); ++it)
|
|
|
|
|
delete *it;
|
|
|
|
|
|
|
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr4SrcRewrites.begin(); it != m_dmr4SrcRewrites.end(); ++it)
|
|
|
|
|
delete *it;
|
|
|
|
|
|
2019-07-17 09:21:52 +02:00
|
|
|
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;
|
|
|
|
|
|
2017-08-02 20:30:39 +02:00
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr1Passalls.begin(); it != m_dmr1Passalls.end(); ++it)
|
2017-06-07 21:40:51 +02:00
|
|
|
delete *it;
|
|
|
|
|
|
2017-08-02 20:30:39 +02:00
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr2Passalls.begin(); it != m_dmr2Passalls.end(); ++it)
|
2017-06-07 21:40:51 +02:00
|
|
|
delete *it;
|
|
|
|
|
|
2017-11-21 12:30:13 +01:00
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr3Passalls.begin(); it != m_dmr3Passalls.end(); ++it)
|
|
|
|
|
delete *it;
|
|
|
|
|
|
2019-05-19 08:56:39 +02:00
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr4Passalls.begin(); it != m_dmr4Passalls.end(); ++it)
|
|
|
|
|
delete *it;
|
|
|
|
|
|
2019-07-17 09:21:52 +02:00
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr5Passalls.begin(); it != m_dmr5Passalls.end(); ++it)
|
|
|
|
|
delete *it;
|
|
|
|
|
|
2020-04-08 00:03:27 +02:00
|
|
|
for (std::vector<CDynVoice*>::iterator it = m_dynVoices.begin(); it != m_dynVoices.end(); ++it)
|
|
|
|
|
delete* it;
|
|
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
delete m_rptRewrite;
|
|
|
|
|
delete m_xlxRewrite;
|
2017-10-08 15:13:52 +02:00
|
|
|
|
2019-07-17 10:46:41 +02:00
|
|
|
delete[] m_status;
|
2017-10-08 15:13:52 +02:00
|
|
|
delete[] m_config;
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#if !defined(_WIN32) && !defined(_WIN64)
|
|
|
|
|
bool m_daemon = m_conf.getDaemon();
|
|
|
|
|
if (m_daemon) {
|
|
|
|
|
// Create new process
|
|
|
|
|
pid_t pid = ::fork();
|
|
|
|
|
if (pid == -1) {
|
2018-06-18 19:27:35 +02:00
|
|
|
::fprintf(stderr, "Couldn't fork() , exiting\n");
|
2017-05-03 18:48:55 +02:00
|
|
|
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){
|
2018-06-18 19:27:35 +02:00
|
|
|
::fprintf(stderr, "Couldn't setsid(), exiting\n");
|
2017-05-03 18:48:55 +02:00
|
|
|
return -1;
|
|
|
|
|
}
|
2017-04-20 21:51:30 +02:00
|
|
|
|
|
|
|
|
// Set the working directory to the root directory
|
|
|
|
|
if (::chdir("/") == -1){
|
2018-06-18 19:27:35 +02:00
|
|
|
::fprintf(stderr, "Couldn't cd /, exiting\n");
|
2017-05-03 18:48:55 +02:00
|
|
|
return -1;
|
|
|
|
|
}
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-06-23 10:07:50 +02:00
|
|
|
// If we are currently root...
|
2017-04-20 21:51:30 +02:00
|
|
|
if (getuid() == 0) {
|
|
|
|
|
struct passwd* user = ::getpwnam("mmdvm");
|
|
|
|
|
if (user == NULL) {
|
2018-06-18 19:27:35 +02:00
|
|
|
::fprintf(stderr, "Could not get the mmdvm user, exiting\n");
|
2017-04-20 21:51:30 +02:00
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
uid_t mmdvm_uid = user->pw_uid;
|
2017-06-23 10:07:50 +02:00
|
|
|
gid_t mmdvm_gid = user->pw_gid;
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2018-06-18 19:27:35 +02:00
|
|
|
// Set user and group ID's to mmdvm:mmdvm
|
2017-06-23 10:07:50 +02:00
|
|
|
if (setgid(mmdvm_gid) != 0) {
|
2018-06-18 19:27:35 +02:00
|
|
|
::fprintf(stderr, "Could not set mmdvm GID, exiting\n");
|
2017-06-23 10:07:50 +02:00
|
|
|
return -1;
|
|
|
|
|
}
|
2017-04-20 21:51:30 +02:00
|
|
|
|
|
|
|
|
if (setuid(mmdvm_uid) != 0) {
|
2018-06-18 19:27:35 +02:00
|
|
|
::fprintf(stderr, "Could not set mmdvm UID, exiting\n");
|
2017-06-23 10:07:50 +02:00
|
|
|
return -1;
|
|
|
|
|
}
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-06-23 10:07:50 +02:00
|
|
|
// Double check it worked (AKA Paranoia)
|
2018-06-18 19:27:35 +02:00
|
|
|
if (setuid(0) != -1) {
|
|
|
|
|
::fprintf(stderr, "It's possible to regain root - something is wrong!, exiting\n");
|
2017-06-23 10:07:50 +02:00
|
|
|
return -1;
|
|
|
|
|
}
|
2017-04-20 21:51:30 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2018-06-18 19:27:35 +02:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2018-07-26 19:47:55 +02:00
|
|
|
#if !defined(_WIN32) && !defined(_WIN64)
|
|
|
|
|
if (m_daemon) {
|
|
|
|
|
::close(STDIN_FILENO);
|
|
|
|
|
::close(STDOUT_FILENO);
|
|
|
|
|
::close(STDERR_FILENO);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2017-04-20 21:51:30 +02:00
|
|
|
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-10-08 15:13:52 +02:00
|
|
|
m_configLen = m_repeater->getConfig(m_config);
|
|
|
|
|
if (m_configLen > 0U && m_repeater->getId() > 1000U)
|
2017-04-20 21:51:30 +02:00
|
|
|
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) {
|
|
|
|
|
m_repeater->close();
|
|
|
|
|
delete m_repeater;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-20 21:51:30 +02:00
|
|
|
LogMessage("MMDVM has connected");
|
|
|
|
|
|
2017-06-04 20:12:16 +02:00
|
|
|
bool ruleTrace = m_conf.getRuleTrace();
|
|
|
|
|
LogInfo("Rule trace: %s", ruleTrace ? "yes" : "no");
|
|
|
|
|
|
2020-04-03 17:54:35 +02:00
|
|
|
if (m_conf.getXLXNetworkEnabled()) {
|
|
|
|
|
ret = createXLXNetwork();
|
|
|
|
|
if (!ret)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
CXLXVoice* xlxVoice = NULL;
|
|
|
|
|
if (m_conf.getVoiceEnabled()) {
|
|
|
|
|
std::string language = m_conf.getVoiceLanguage();
|
|
|
|
|
std::string directory = m_conf.getVoiceDirectory();
|
|
|
|
|
|
|
|
|
|
LogInfo("Voice Parameters");
|
|
|
|
|
LogInfo(" Enabled: yes");
|
|
|
|
|
LogInfo(" Language: %s", language.c_str());
|
|
|
|
|
LogInfo(" Directory: %s", directory.c_str());
|
|
|
|
|
|
|
|
|
|
if (m_xlxNetwork != NULL) {
|
|
|
|
|
xlxVoice = new CXLXVoice(directory, language, m_repeater->getId(), m_xlxSlot, m_xlxTG);
|
|
|
|
|
bool ret = xlxVoice->open();
|
|
|
|
|
if (!ret) {
|
|
|
|
|
delete xlxVoice;
|
|
|
|
|
xlxVoice = NULL;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
if (m_conf.getDMRNetwork1Enabled()) {
|
2020-04-08 00:03:27 +02:00
|
|
|
ret = createDMRNetwork1();
|
2017-05-03 18:48:55 +02:00
|
|
|
if (!ret)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
if (m_conf.getDMRNetwork2Enabled()) {
|
2020-04-08 00:03:27 +02:00
|
|
|
ret = createDMRNetwork2();
|
2017-05-03 18:48:55 +02:00
|
|
|
if (!ret)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-21 12:30:13 +01:00
|
|
|
if (m_conf.getDMRNetwork3Enabled()) {
|
2020-04-08 00:03:27 +02:00
|
|
|
ret = createDMRNetwork3();
|
2017-11-21 12:30:13 +01:00
|
|
|
if (!ret)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2017-05-06 18:17:34 +02:00
|
|
|
|
2019-03-16 11:08:32 +01:00
|
|
|
if (m_conf.getDMRNetwork4Enabled()) {
|
2020-04-08 00:03:27 +02:00
|
|
|
ret = createDMRNetwork4();
|
2019-03-16 11:08:32 +01:00
|
|
|
if (!ret)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-17 09:21:52 +02:00
|
|
|
if (m_conf.getDMRNetwork5Enabled()) {
|
2020-04-08 00:03:27 +02:00
|
|
|
ret = createDMRNetwork5();
|
2017-05-03 18:48:55 +02:00
|
|
|
if (!ret)
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-09-22 22:03:44 +02:00
|
|
|
unsigned int rfTimeout = m_conf.getRFTimeout();
|
|
|
|
|
unsigned int netTimeout = m_conf.getNetTimeout();
|
2017-05-06 10:57:17 +02:00
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
CTimer* timer[3U];
|
2017-09-22 22:03:44 +02:00
|
|
|
timer[1U] = new CTimer(1000U);
|
|
|
|
|
timer[2U] = new CTimer(1000U);
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-06-09 21:14:26 +02:00
|
|
|
unsigned int rfSrcId[3U];
|
|
|
|
|
unsigned int rfDstId[3U];
|
|
|
|
|
rfSrcId[1U] = rfSrcId[2U] = rfDstId[1U] = rfDstId[2U] = 0U;
|
|
|
|
|
|
|
|
|
|
unsigned int dmr1SrcId[3U];
|
|
|
|
|
unsigned int dmr1DstId[3U];
|
|
|
|
|
dmr1SrcId[1U] = dmr1SrcId[2U] = dmr1DstId[1U] = dmr1DstId[2U] = 0U;
|
|
|
|
|
|
|
|
|
|
unsigned int dmr2SrcId[3U];
|
|
|
|
|
unsigned int dmr2DstId[3U];
|
|
|
|
|
dmr2SrcId[1U] = dmr2SrcId[2U] = dmr2DstId[1U] = dmr2DstId[2U] = 0U;
|
|
|
|
|
|
2017-11-21 12:30:13 +01:00
|
|
|
unsigned int dmr3SrcId[3U];
|
|
|
|
|
unsigned int dmr3DstId[3U];
|
|
|
|
|
dmr3SrcId[1U] = dmr3SrcId[2U] = dmr3DstId[1U] = dmr3DstId[2U] = 0U;
|
|
|
|
|
|
2019-03-16 11:08:32 +01:00
|
|
|
unsigned int dmr4SrcId[3U];
|
|
|
|
|
unsigned int dmr4DstId[3U];
|
|
|
|
|
dmr4SrcId[1U] = dmr4SrcId[2U] = dmr4DstId[1U] = dmr4DstId[2U] = 0U;
|
|
|
|
|
|
2019-07-17 09:21:52 +02:00
|
|
|
unsigned int dmr5SrcId[3U];
|
|
|
|
|
unsigned int dmr5DstId[3U];
|
|
|
|
|
dmr5SrcId[1U] = dmr5SrcId[2U] = dmr5DstId[1U] = dmr5DstId[2U] = 0U;
|
|
|
|
|
|
2017-04-20 21:51:30 +02:00
|
|
|
CStopWatch stopWatch;
|
|
|
|
|
stopWatch.start();
|
|
|
|
|
|
|
|
|
|
LogMessage("DMRGateway-%s is running", VERSION);
|
|
|
|
|
|
|
|
|
|
while (!m_killed) {
|
2017-08-20 22:48:49 +02:00
|
|
|
if (m_xlxNetwork != NULL) {
|
|
|
|
|
bool connected = m_xlxNetwork->isConnected();
|
|
|
|
|
if (connected && !m_xlxConnected) {
|
2017-08-24 09:54:20 +02:00
|
|
|
if (m_xlxReflector >= 4001U && m_xlxReflector <= 4026U) {
|
|
|
|
|
writeXLXLink(m_xlxId, m_xlxReflector, m_xlxNetwork);
|
2017-10-04 17:18:29 +02:00
|
|
|
char c = ('A' + (m_xlxReflector % 100U)) - 1U;
|
|
|
|
|
LogMessage("XLX, Linking to reflector XLX%03u %c", m_xlxNumber, c);
|
2020-04-03 17:54:35 +02:00
|
|
|
if (xlxVoice != NULL)
|
|
|
|
|
xlxVoice->linkedTo(m_xlxNumber, m_xlxReflector);
|
2017-08-24 09:54:20 +02:00
|
|
|
} else if (m_xlxRoom >= 4001U && m_xlxRoom <= 4026U) {
|
2017-08-20 22:48:49 +02:00
|
|
|
writeXLXLink(m_xlxId, m_xlxRoom, m_xlxNetwork);
|
2017-10-04 17:18:29 +02:00
|
|
|
char c = ('A' + (m_xlxRoom % 100U)) - 1U;
|
|
|
|
|
LogMessage("XLX, Linking to reflector XLX%03u %c", m_xlxNumber, c);
|
2020-04-03 17:54:35 +02:00
|
|
|
if (xlxVoice != NULL)
|
|
|
|
|
xlxVoice->linkedTo(m_xlxNumber, m_xlxRoom);
|
2017-08-24 09:54:20 +02:00
|
|
|
m_xlxReflector = m_xlxRoom;
|
2017-09-30 00:09:35 +02:00
|
|
|
} else {
|
2020-04-03 17:54:35 +02:00
|
|
|
if (xlxVoice != NULL)
|
|
|
|
|
xlxVoice->linkedTo(m_xlxNumber, 0U);
|
2017-06-20 14:48:01 +02:00
|
|
|
}
|
2017-05-30 14:42:30 +02:00
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
m_xlxConnected = true;
|
2017-08-21 14:21:43 +02:00
|
|
|
|
2017-08-24 09:54:20 +02:00
|
|
|
if (m_xlxNumber == m_xlxStartup && m_xlxRoom == m_xlxReflector)
|
2017-08-21 14:21:43 +02:00
|
|
|
m_xlxRelink.stop();
|
|
|
|
|
else
|
|
|
|
|
m_xlxRelink.start();
|
2017-08-20 22:48:49 +02:00
|
|
|
} else if (!connected && m_xlxConnected) {
|
2017-09-30 00:09:35 +02:00
|
|
|
LogMessage("XLX, Unlinking from XLX%03u due to loss of connection", m_xlxNumber);
|
|
|
|
|
|
2020-04-03 17:54:35 +02:00
|
|
|
if (xlxVoice != NULL)
|
|
|
|
|
xlxVoice->unlinked();
|
2017-05-30 14:42:30 +02:00
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
m_xlxConnected = false;
|
|
|
|
|
m_xlxRelink.stop();
|
|
|
|
|
} else if (connected && m_xlxRelink.isRunning() && m_xlxRelink.hasExpired()) {
|
|
|
|
|
m_xlxRelink.stop();
|
|
|
|
|
|
|
|
|
|
if (m_xlxNumber != m_xlxStartup) {
|
2017-08-22 10:34:37 +02:00
|
|
|
if (m_xlxStartup > 0U) {
|
2017-08-24 09:54:20 +02:00
|
|
|
m_xlxReflector = 4000U;
|
2017-10-04 17:18:29 +02:00
|
|
|
char c = ('A' + (m_xlxRoom % 100U)) - 1U;
|
|
|
|
|
LogMessage("XLX, Re-linking to startup reflector XLX%03u %c due to RF inactivity timeout", m_xlxNumber, c);
|
2017-08-22 10:34:37 +02:00
|
|
|
linkXLX(m_xlxStartup);
|
|
|
|
|
} else {
|
|
|
|
|
LogMessage("XLX, Unlinking from XLX%03u due to RF inactivity timeout", m_xlxNumber);
|
|
|
|
|
unlinkXLX();
|
|
|
|
|
}
|
2017-08-20 22:48:49 +02:00
|
|
|
} else {
|
2017-08-22 10:34:37 +02:00
|
|
|
if (m_xlxReflector >= 4001U && m_xlxReflector <= 4026U)
|
2017-08-20 22:48:49 +02:00
|
|
|
writeXLXLink(m_xlxId, 4000U, m_xlxNetwork);
|
|
|
|
|
|
2017-08-22 10:34:37 +02:00
|
|
|
if (m_xlxRoom >= 4001U && m_xlxRoom <= 4026U) {
|
|
|
|
|
writeXLXLink(m_xlxId, m_xlxRoom, m_xlxNetwork);
|
2017-10-04 17:18:29 +02:00
|
|
|
char c = ('A' + (m_xlxRoom % 100U)) - 1U;
|
|
|
|
|
LogMessage("XLX, Re-linking to startup reflector XLX%03u %c due to RF inactivity timeout", m_xlxNumber, c);
|
2017-08-22 10:34:37 +02:00
|
|
|
} else if (m_xlxReflector >= 4001U && m_xlxReflector <= 4026U) {
|
2017-10-04 17:18:29 +02:00
|
|
|
char c = ('A' + (m_xlxReflector % 100U)) - 1U;
|
|
|
|
|
LogMessage("XLX, Unlinking from reflector XLX%03u %c due to RF inactivity timeout", m_xlxNumber, c);
|
2017-08-22 10:34:37 +02:00
|
|
|
}
|
|
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
m_xlxReflector = m_xlxRoom;
|
2020-04-03 17:54:35 +02:00
|
|
|
if (xlxVoice != NULL) {
|
2017-08-22 10:34:37 +02:00
|
|
|
if (m_xlxReflector < 4001U || m_xlxReflector > 4026U)
|
2020-04-03 17:54:35 +02:00
|
|
|
xlxVoice->linkedTo(m_xlxNumber, 0U);
|
2017-08-20 22:48:49 +02:00
|
|
|
else
|
2020-04-03 17:54:35 +02:00
|
|
|
xlxVoice->linkedTo(m_xlxNumber, m_xlxReflector);
|
2017-08-20 22:48:49 +02:00
|
|
|
}
|
2017-06-20 14:48:01 +02:00
|
|
|
}
|
2017-06-23 21:57:50 +02:00
|
|
|
}
|
2017-05-30 14:42:30 +02:00
|
|
|
}
|
|
|
|
|
|
2017-04-20 21:51:30 +02:00
|
|
|
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-08-20 22:48:49 +02:00
|
|
|
if (flco == FLCO_GROUP && slotNo == m_xlxSlot && dstId == m_xlxTG) {
|
|
|
|
|
if (m_xlxReflector != m_xlxRoom || m_xlxNumber != m_xlxStartup)
|
|
|
|
|
m_xlxRelink.start();
|
2017-06-23 21:57:50 +02:00
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
m_xlxRewrite->process(data, false);
|
|
|
|
|
m_xlxNetwork->write(data);
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[slotNo] = DMRGWS_XLXREFLECTOR;
|
2017-09-22 22:03:44 +02:00
|
|
|
timer[slotNo]->setTimeout(rfTimeout);
|
2017-05-03 18:48:55 +02:00
|
|
|
timer[slotNo]->start();
|
2018-10-21 11:18:55 +02:00
|
|
|
} else if ((dstId <= (m_xlxBase + 26U) || dstId == (m_xlxBase + 1000U)) && flco == FLCO_USER_USER && slotNo == m_xlxSlot && dstId >= m_xlxBase && m_xlxUserControl) {
|
2017-05-26 14:26:39 +02:00
|
|
|
dstId += 4000U;
|
2017-08-20 22:48:49 +02:00
|
|
|
dstId -= m_xlxBase;
|
2017-05-26 14:26:39 +02:00
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
if (dstId != m_xlxReflector) {
|
2017-05-29 20:24:13 +02:00
|
|
|
if (dstId == 4000U) {
|
2017-09-30 00:09:35 +02:00
|
|
|
writeXLXLink(srcId, 4000U, m_xlxNetwork);
|
|
|
|
|
m_xlxReflector = 4000U;
|
2017-10-04 17:18:29 +02:00
|
|
|
char c = ('A' + (m_xlxRoom % 100U)) - 1U;
|
|
|
|
|
LogMessage("XLX, Unlinking from reflector XLX%03u %c", m_xlxNumber, c);
|
2017-09-30 00:09:35 +02:00
|
|
|
} else if (dstId != 5000U) {
|
2017-08-20 22:48:49 +02:00
|
|
|
if (m_xlxReflector != 4000U)
|
|
|
|
|
writeXLXLink(srcId, 4000U, m_xlxNetwork);
|
|
|
|
|
writeXLXLink(srcId, dstId, m_xlxNetwork);
|
|
|
|
|
m_xlxReflector = dstId;
|
2017-10-04 17:18:29 +02:00
|
|
|
char c = ('A' + (dstId % 100U)) - 1U;
|
|
|
|
|
LogMessage("XLX, Linking to reflector XLX%03u %c", m_xlxNumber, c);
|
2017-06-01 18:34:51 +02:00
|
|
|
}
|
2017-06-23 21:57:50 +02:00
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
if (m_xlxReflector != m_xlxRoom)
|
|
|
|
|
m_xlxRelink.start();
|
2017-06-23 21:57:50 +02:00
|
|
|
else
|
2017-08-20 22:48:49 +02:00
|
|
|
m_xlxRelink.stop();
|
2017-05-26 14:26:39 +02:00
|
|
|
}
|
|
|
|
|
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[slotNo] = DMRGWS_XLXREFLECTOR;
|
2017-09-22 22:03:44 +02:00
|
|
|
timer[slotNo]->setTimeout(rfTimeout);
|
2017-05-26 14:26:39 +02:00
|
|
|
timer[slotNo]->start();
|
|
|
|
|
|
2020-04-03 17:54:35 +02:00
|
|
|
if (xlxVoice != NULL) {
|
2017-05-26 14:26:39 +02:00
|
|
|
unsigned char type = data.getDataType();
|
|
|
|
|
if (type == DT_TERMINATOR_WITH_LC) {
|
2017-09-30 00:09:35 +02:00
|
|
|
if (m_xlxConnected) {
|
|
|
|
|
if (m_xlxReflector != 4000U)
|
2020-04-03 17:54:35 +02:00
|
|
|
xlxVoice->linkedTo(m_xlxNumber, m_xlxReflector);
|
2017-09-30 00:09:35 +02:00
|
|
|
else
|
2020-04-03 17:54:35 +02:00
|
|
|
xlxVoice->linkedTo(m_xlxNumber, 0U);
|
2017-09-30 00:09:35 +02:00
|
|
|
} else {
|
2020-04-03 17:54:35 +02:00
|
|
|
xlxVoice->unlinked();
|
2017-05-03 18:48:55 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-10-21 11:18:55 +02:00
|
|
|
} else if (dstId >= (m_xlxBase + 4000U) && dstId < (m_xlxBase + 5000U) && flco == FLCO_USER_USER && slotNo == m_xlxSlot && m_xlxUserControl) {
|
2017-09-24 10:11:21 +02:00
|
|
|
dstId -= 4000U;
|
2017-08-21 14:17:21 +02:00
|
|
|
dstId -= m_xlxBase;
|
|
|
|
|
|
|
|
|
|
if (dstId != m_xlxNumber)
|
|
|
|
|
linkXLX(dstId);
|
2017-05-03 18:48:55 +02:00
|
|
|
} else {
|
2017-06-04 16:17:43 +02:00
|
|
|
unsigned int slotNo = data.getSlotNo();
|
|
|
|
|
unsigned int srcId = data.getSrcId();
|
|
|
|
|
unsigned int dstId = data.getDstId();
|
|
|
|
|
FLCO flco = data.getFLCO();
|
|
|
|
|
|
2017-06-09 21:14:26 +02:00
|
|
|
bool trace = false;
|
|
|
|
|
if (ruleTrace && (srcId != rfSrcId[slotNo] || dstId != rfDstId[slotNo])) {
|
|
|
|
|
rfSrcId[slotNo] = srcId;
|
|
|
|
|
rfDstId[slotNo] = dstId;
|
|
|
|
|
trace = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (trace)
|
2017-06-04 20:12:16 +02:00
|
|
|
LogDebug("Rule Trace, RF transmission: Slot=%u Src=%u Dst=%s%u", slotNo, srcId, flco == FLCO_GROUP ? "TG" : "", dstId);
|
2017-06-04 16:17:43 +02:00
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
PROCESS_RESULT result = RESULT_UNMATCHED;
|
2017-05-06 10:57:17 +02:00
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
if (m_dmrNetwork1 != NULL) {
|
|
|
|
|
// Rewrite the slot and/or TG or neither
|
2017-08-02 20:30:39 +02:00
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr1RFRewrites.begin(); it != m_dmr1RFRewrites.end(); ++it) {
|
2020-04-03 16:10:41 +02:00
|
|
|
PROCESS_RESULT res = (*it)->process(data, trace);
|
|
|
|
|
if (res != RESULT_UNMATCHED) {
|
|
|
|
|
result = res;
|
2017-05-03 18:48:55 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-04-30 12:01:54 +02:00
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_MATCHED) {
|
2019-07-17 10:46:41 +02:00
|
|
|
if (m_status[slotNo] == DMRGWS_NONE || m_status[slotNo] == DMRGWS_DMRNETWORK1) {
|
2019-05-19 08:56:39 +02:00
|
|
|
rewrite(m_dmr1SrcRewrites, data, trace);
|
2017-05-03 18:48:55 +02:00
|
|
|
m_dmrNetwork1->write(data);
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[slotNo] = DMRGWS_DMRNETWORK1;
|
2017-09-22 22:03:44 +02:00
|
|
|
timer[slotNo]->setTimeout(rfTimeout);
|
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
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_UNMATCHED) {
|
2017-05-06 10:57:17 +02:00
|
|
|
if (m_dmrNetwork2 != NULL) {
|
|
|
|
|
// Rewrite the slot and/or TG or neither
|
2017-08-02 20:30:39 +02:00
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr2RFRewrites.begin(); it != m_dmr2RFRewrites.end(); ++it) {
|
2020-04-03 16:10:41 +02:00
|
|
|
PROCESS_RESULT res = (*it)->process(data, trace);
|
|
|
|
|
if (res != RESULT_UNMATCHED) {
|
|
|
|
|
result = res;
|
2017-05-06 10:57:17 +02:00
|
|
|
break;
|
|
|
|
|
}
|
2017-05-03 18:48:55 +02:00
|
|
|
}
|
|
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_MATCHED) {
|
2019-07-17 10:46:41 +02:00
|
|
|
if (m_status[slotNo] == DMRGWS_NONE || m_status[slotNo] == DMRGWS_DMRNETWORK2) {
|
2019-05-19 08:56:39 +02:00
|
|
|
rewrite(m_dmr2SrcRewrites, data, trace);
|
2017-05-06 10:57:17 +02:00
|
|
|
m_dmrNetwork2->write(data);
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[slotNo] = DMRGWS_DMRNETWORK2;
|
2017-09-22 22:03:44 +02:00
|
|
|
timer[slotNo]->setTimeout(rfTimeout);
|
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
|
|
|
}
|
2019-07-17 09:21:52 +02:00
|
|
|
}
|
2017-11-21 12:30:13 +01:00
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_UNMATCHED) {
|
2019-07-17 09:21:52 +02:00
|
|
|
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) {
|
2020-04-03 16:10:41 +02:00
|
|
|
PROCESS_RESULT res = (*it)->process(data, trace);
|
|
|
|
|
if (res != RESULT_UNMATCHED) {
|
|
|
|
|
result = res;
|
2019-07-17 09:21:52 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_MATCHED) {
|
2019-07-17 10:46:41 +02:00
|
|
|
if (m_status[slotNo] == DMRGWS_NONE || m_status[slotNo] == DMRGWS_DMRNETWORK3) {
|
2019-07-17 09:21:52 +02:00
|
|
|
rewrite(m_dmr3SrcRewrites, data, trace);
|
|
|
|
|
m_dmrNetwork3->write(data);
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[slotNo] = DMRGWS_DMRNETWORK3;
|
2019-07-17 09:21:52 +02:00
|
|
|
timer[slotNo]->setTimeout(rfTimeout);
|
|
|
|
|
timer[slotNo]->start();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_UNMATCHED) {
|
2019-07-17 09:21:52 +02:00
|
|
|
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) {
|
2020-04-03 16:10:41 +02:00
|
|
|
PROCESS_RESULT res = (*it)->process(data, trace);
|
|
|
|
|
if (res != RESULT_UNMATCHED) {
|
|
|
|
|
result = res;
|
2019-07-17 09:21:52 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_MATCHED) {
|
2019-07-17 10:46:41 +02:00
|
|
|
if (m_status[slotNo] == DMRGWS_NONE || m_status[slotNo] == DMRGWS_DMRNETWORK4) {
|
2019-07-17 09:21:52 +02:00
|
|
|
rewrite(m_dmr4SrcRewrites, data, trace);
|
|
|
|
|
m_dmrNetwork4->write(data);
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[slotNo] = DMRGWS_DMRNETWORK4;
|
2019-07-17 09:21:52 +02:00
|
|
|
timer[slotNo]->setTimeout(rfTimeout);
|
|
|
|
|
timer[slotNo]->start();
|
2017-11-21 12:30:13 +01:00
|
|
|
}
|
2019-07-17 09:21:52 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-11-21 12:30:13 +01:00
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_UNMATCHED) {
|
2019-07-17 09:21:52 +02:00
|
|
|
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) {
|
2020-04-03 16:10:41 +02:00
|
|
|
PROCESS_RESULT res = (*it)->process(data, trace);
|
|
|
|
|
if (res != RESULT_UNMATCHED) {
|
|
|
|
|
result = res;
|
2019-07-17 09:21:52 +02:00
|
|
|
break;
|
2017-11-21 12:30:13 +01:00
|
|
|
}
|
|
|
|
|
}
|
2019-03-16 11:08:32 +01:00
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_MATCHED) {
|
2019-07-17 10:46:41 +02:00
|
|
|
if (m_status[slotNo] == DMRGWS_NONE || m_status[slotNo] == DMRGWS_DMRNETWORK5) {
|
2019-07-17 09:21:52 +02:00
|
|
|
rewrite(m_dmr5SrcRewrites, data, trace);
|
|
|
|
|
m_dmrNetwork5->write(data);
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[slotNo] = DMRGWS_DMRNETWORK5;
|
2019-07-17 09:21:52 +02:00
|
|
|
timer[slotNo]->setTimeout(rfTimeout);
|
|
|
|
|
timer[slotNo]->start();
|
2019-03-16 11:08:32 +01:00
|
|
|
}
|
|
|
|
|
}
|
2017-11-21 12:30:13 +01:00
|
|
|
}
|
2017-04-20 21:51:30 +02:00
|
|
|
}
|
2017-06-04 16:17:43 +02:00
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_UNMATCHED) {
|
2017-06-07 21:40:51 +02:00
|
|
|
if (m_dmrNetwork1 != NULL) {
|
2017-08-02 20:30:39 +02:00
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr1Passalls.begin(); it != m_dmr1Passalls.end(); ++it) {
|
2020-04-03 16:10:41 +02:00
|
|
|
PROCESS_RESULT res = (*it)->process(data, trace);
|
|
|
|
|
if (res != RESULT_UNMATCHED) {
|
|
|
|
|
result = res;
|
2017-06-07 21:40:51 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_MATCHED) {
|
2019-07-17 10:46:41 +02:00
|
|
|
if (m_status[slotNo] == DMRGWS_NONE || m_status[slotNo] == DMRGWS_DMRNETWORK1) {
|
2019-05-19 08:56:39 +02:00
|
|
|
rewrite(m_dmr1SrcRewrites, data, trace);
|
2017-06-07 21:40:51 +02:00
|
|
|
m_dmrNetwork1->write(data);
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[slotNo] = DMRGWS_DMRNETWORK1;
|
2017-09-22 22:03:44 +02:00
|
|
|
timer[slotNo]->setTimeout(rfTimeout);
|
2017-06-07 21:40:51 +02:00
|
|
|
timer[slotNo]->start();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_UNMATCHED) {
|
2017-06-07 21:40:51 +02:00
|
|
|
if (m_dmrNetwork2 != NULL) {
|
2017-08-02 20:30:39 +02:00
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr2Passalls.begin(); it != m_dmr2Passalls.end(); ++it) {
|
2020-04-03 16:10:41 +02:00
|
|
|
PROCESS_RESULT res = (*it)->process(data, trace);
|
|
|
|
|
if (res != RESULT_UNMATCHED) {
|
|
|
|
|
result = res;
|
2017-06-07 21:40:51 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_MATCHED) {
|
2019-07-17 10:46:41 +02:00
|
|
|
if (m_status[slotNo] == DMRGWS_NONE || m_status[slotNo] == DMRGWS_DMRNETWORK2) {
|
2019-05-19 08:56:39 +02:00
|
|
|
rewrite(m_dmr2SrcRewrites, data, trace);
|
2017-06-07 21:40:51 +02:00
|
|
|
m_dmrNetwork2->write(data);
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[slotNo] = DMRGWS_DMRNETWORK2;
|
2017-09-22 22:03:44 +02:00
|
|
|
timer[slotNo]->setTimeout(rfTimeout);
|
2017-06-07 21:40:51 +02:00
|
|
|
timer[slotNo]->start();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_UNMATCHED) {
|
2017-11-21 12:30:13 +01:00
|
|
|
if (m_dmrNetwork3 != NULL) {
|
|
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr3Passalls.begin(); it != m_dmr3Passalls.end(); ++it) {
|
2020-04-03 16:10:41 +02:00
|
|
|
PROCESS_RESULT res = (*it)->process(data, trace);
|
|
|
|
|
if (res != RESULT_UNMATCHED) {
|
|
|
|
|
result = res;
|
2017-11-21 12:30:13 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_MATCHED) {
|
2019-07-17 10:46:41 +02:00
|
|
|
if (m_status[slotNo] == DMRGWS_NONE || m_status[slotNo] == DMRGWS_DMRNETWORK3) {
|
2019-05-19 08:56:39 +02:00
|
|
|
rewrite(m_dmr3SrcRewrites, data, trace);
|
2017-11-21 12:30:13 +01:00
|
|
|
m_dmrNetwork3->write(data);
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[slotNo] = DMRGWS_DMRNETWORK3;
|
2017-11-21 12:30:13 +01:00
|
|
|
timer[slotNo]->setTimeout(rfTimeout);
|
|
|
|
|
timer[slotNo]->start();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_UNMATCHED) {
|
2019-03-16 11:08:32 +01:00
|
|
|
if (m_dmrNetwork4 != NULL) {
|
|
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr4Passalls.begin(); it != m_dmr4Passalls.end(); ++it) {
|
2020-04-03 16:10:41 +02:00
|
|
|
PROCESS_RESULT res = (*it)->process(data, trace);
|
|
|
|
|
if (res != RESULT_UNMATCHED) {
|
|
|
|
|
result = res;
|
2019-03-16 11:08:32 +01:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_MATCHED) {
|
2019-07-17 10:46:41 +02:00
|
|
|
if (m_status[slotNo] == DMRGWS_NONE || m_status[slotNo] == DMRGWS_DMRNETWORK4) {
|
2019-05-19 08:56:39 +02:00
|
|
|
rewrite(m_dmr4SrcRewrites, data, trace);
|
2019-03-16 11:08:32 +01:00
|
|
|
m_dmrNetwork4->write(data);
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[slotNo] = DMRGWS_DMRNETWORK4;
|
2019-03-16 11:08:32 +01:00
|
|
|
timer[slotNo]->setTimeout(rfTimeout);
|
|
|
|
|
timer[slotNo]->start();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_UNMATCHED) {
|
2019-07-17 09:21:52 +02:00
|
|
|
if (m_dmrNetwork5 != NULL) {
|
|
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr5Passalls.begin(); it != m_dmr5Passalls.end(); ++it) {
|
2020-04-03 16:10:41 +02:00
|
|
|
PROCESS_RESULT res = (*it)->process(data, trace);
|
|
|
|
|
if (res != RESULT_UNMATCHED) {
|
|
|
|
|
result = res;
|
2019-07-17 09:21:52 +02:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_MATCHED) {
|
2019-07-17 10:46:41 +02:00
|
|
|
if (m_status[slotNo] == DMRGWS_NONE || m_status[slotNo] == DMRGWS_DMRNETWORK5) {
|
2019-07-17 09:21:52 +02:00
|
|
|
rewrite(m_dmr5SrcRewrites, data, trace);
|
|
|
|
|
m_dmrNetwork5->write(data);
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[slotNo] = DMRGWS_DMRNETWORK5;
|
2019-07-17 09:21:52 +02:00
|
|
|
timer[slotNo]->setTimeout(rfTimeout);
|
|
|
|
|
timer[slotNo]->start();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-03 16:10:41 +02:00
|
|
|
if (result == RESULT_UNMATCHED && trace)
|
2017-06-04 16:17:43 +02:00
|
|
|
LogDebug("Rule Trace,\tnot matched so rejected");
|
2017-04-20 21:51:30 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
if (m_xlxNetwork != NULL) {
|
|
|
|
|
ret = m_xlxNetwork->read(data);
|
2017-05-03 18:48:55 +02:00
|
|
|
if (ret) {
|
2019-07-17 10:46:41 +02:00
|
|
|
if (m_status[m_xlxSlot] == DMRGWS_NONE || m_status[m_xlxSlot] == DMRGWS_XLXREFLECTOR) {
|
2017-08-20 22:48:49 +02:00
|
|
|
bool ret = m_rptRewrite->process(data, false);
|
2017-05-08 19:34:41 +02:00
|
|
|
if (ret) {
|
2017-05-03 18:48:55 +02:00
|
|
|
m_repeater->write(data);
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[m_xlxSlot] = DMRGWS_XLXREFLECTOR;
|
2017-09-22 22:10:40 +02:00
|
|
|
timer[m_xlxSlot]->setTimeout(netTimeout);
|
2017-08-20 22:48:49 +02:00
|
|
|
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();
|
2017-08-20 22:48:49 +02:00
|
|
|
LogWarning("XLX%03u, Unexpected data from slot %u %s%u", m_xlxNumber, 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-06-04 16:17:43 +02:00
|
|
|
unsigned int slotNo = data.getSlotNo();
|
|
|
|
|
unsigned int srcId = data.getSrcId();
|
|
|
|
|
unsigned int dstId = data.getDstId();
|
|
|
|
|
FLCO flco = data.getFLCO();
|
|
|
|
|
|
2017-06-09 21:14:26 +02:00
|
|
|
bool trace = false;
|
|
|
|
|
if (ruleTrace && (srcId != dmr1SrcId[slotNo] || dstId != dmr1DstId[slotNo])) {
|
|
|
|
|
dmr1SrcId[slotNo] = srcId;
|
|
|
|
|
dmr1DstId[slotNo] = dstId;
|
|
|
|
|
trace = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (trace)
|
2017-06-04 20:12:16 +02:00
|
|
|
LogDebug("Rule Trace, network 1 transmission: Slot=%u Src=%u Dst=%s%u", slotNo, srcId, flco == FLCO_GROUP ? "TG" : "", dstId);
|
2017-06-04 16:17:43 +02:00
|
|
|
|
2017-05-14 19:14:09 +02:00
|
|
|
// Rewrite the slot and/or TG or neither
|
|
|
|
|
bool rewritten = false;
|
2017-08-02 20:30:39 +02:00
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr1NetRewrites.begin(); it != m_dmr1NetRewrites.end(); ++it) {
|
2017-06-09 21:14:26 +02:00
|
|
|
bool ret = (*it)->process(data, trace);
|
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) {
|
2017-09-22 21:49:12 +02:00
|
|
|
// Check that the rewritten slot is free to use.
|
|
|
|
|
slotNo = data.getSlotNo();
|
2019-07-17 10:46:41 +02:00
|
|
|
if (m_status[slotNo] == DMRGWS_NONE || m_status[slotNo] == DMRGWS_DMRNETWORK1) {
|
2017-05-26 14:26:39 +02:00
|
|
|
m_repeater->write(data);
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[slotNo] = DMRGWS_DMRNETWORK1;
|
2017-09-22 22:03:44 +02:00
|
|
|
timer[slotNo]->setTimeout(netTimeout);
|
2017-05-26 14:26:39 +02:00
|
|
|
timer[slotNo]->start();
|
2017-05-03 18:48:55 +02:00
|
|
|
}
|
|
|
|
|
}
|
2017-06-04 16:17:43 +02:00
|
|
|
|
2017-06-09 21:14:26 +02:00
|
|
|
if (!rewritten && trace)
|
2017-06-04 16:17:43 +02:00
|
|
|
LogDebug("Rule Trace,\tnot matched so rejected");
|
2017-05-03 18:48:55 +02:00
|
|
|
}
|
2017-06-02 17:29:01 +02:00
|
|
|
|
|
|
|
|
ret = m_dmrNetwork1->wantsBeacon();
|
|
|
|
|
if (ret)
|
|
|
|
|
m_repeater->writeBeacon();
|
2017-05-03 18:48:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (m_dmrNetwork2 != NULL) {
|
|
|
|
|
ret = m_dmrNetwork2->read(data);
|
|
|
|
|
if (ret) {
|
2017-06-04 16:17:43 +02:00
|
|
|
unsigned int slotNo = data.getSlotNo();
|
|
|
|
|
unsigned int srcId = data.getSrcId();
|
|
|
|
|
unsigned int dstId = data.getDstId();
|
|
|
|
|
FLCO flco = data.getFLCO();
|
|
|
|
|
|
2017-06-09 21:14:26 +02:00
|
|
|
bool trace = false;
|
|
|
|
|
if (ruleTrace && (srcId != dmr2SrcId[slotNo] || dstId != dmr2DstId[slotNo])) {
|
|
|
|
|
dmr2SrcId[slotNo] = srcId;
|
|
|
|
|
dmr2DstId[slotNo] = dstId;
|
|
|
|
|
trace = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (trace)
|
2017-06-04 20:12:16 +02:00
|
|
|
LogDebug("Rule Trace, network 2 transmission: Slot=%u Src=%u Dst=%s%u", slotNo, srcId, flco == FLCO_GROUP ? "TG" : "", dstId);
|
2017-06-04 16:17:43 +02:00
|
|
|
|
2017-05-14 19:14:09 +02:00
|
|
|
// Rewrite the slot and/or TG or neither
|
|
|
|
|
bool rewritten = false;
|
2017-08-02 20:30:39 +02:00
|
|
|
for (std::vector<CRewrite*>::iterator it = m_dmr2NetRewrites.begin(); it != m_dmr2NetRewrites.end(); ++it) {
|
2017-06-09 21:14:26 +02:00
|
|
|
bool ret = (*it)->process(data, trace);
|
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) {
|
2017-09-22 21:49:12 +02:00
|
|
|
// Check that the rewritten slot is free to use.
|
|
|
|
|
slotNo = data.getSlotNo();
|
2019-07-17 10:46:41 +02:00
|
|
|
if (m_status[slotNo] == DMRGWS_NONE || m_status[slotNo] == DMRGWS_DMRNETWORK2) {
|
2017-05-26 14:26:39 +02:00
|
|
|
m_repeater->write(data);
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[slotNo] = DMRGWS_DMRNETWORK2;
|
2017-09-22 22:03:44 +02:00
|
|
|
timer[slotNo]->setTimeout(netTimeout);
|
2017-05-26 14:26:39 +02:00
|
|
|
timer[slotNo]->start();
|
2017-04-20 21:51:30 +02:00
|
|
|
}
|
|
|
|
|
}
|
2017-06-04 16:17:43 +02:00
|
|
|
|
2017-06-09 21:14:26 +02:00
|
|
|
if (!rewritten && trace)
|
2017-06-04 16:17:43 +02:00
|
|
|
LogDebug("Rule Trace,\tnot matched so rejected");
|
2017-04-20 21:51:30 +02:00
|
|
|
}
|
2017-06-02 17:29:01 +02:00
|
|
|
|
|
|
|
|
ret = m_dmrNetwork2->wantsBeacon();
|
|
|
|
|
if (ret)
|
|
|
|
|
m_repeater->writeBeacon();
|
2017-04-20 21:51:30 +02:00
|
|
|
}
|
|
|
|
|
|
2017-11-21 12:30:13 +01:00
|
|
|
if (m_dmrNetwork3 != NULL) {
|
|
|
|
|
ret = m_dmrNetwork3->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 != dmr3SrcId[slotNo] || dstId != dmr3DstId[slotNo])) {
|
|
|
|
|
dmr3SrcId[slotNo] = srcId;
|
|
|
|
|
dmr3DstId[slotNo] = dstId;
|
|
|
|
|
trace = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (trace)
|
|
|
|
|
LogDebug("Rule Trace, network 3 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_dmr3NetRewrites.begin(); it != m_dmr3NetRewrites.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();
|
2019-07-17 10:46:41 +02:00
|
|
|
if (m_status[slotNo] == DMRGWS_NONE || m_status[slotNo] == DMRGWS_DMRNETWORK3) {
|
2017-11-21 12:30:13 +01:00
|
|
|
m_repeater->write(data);
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[slotNo] = DMRGWS_DMRNETWORK3;
|
2017-11-21 12:30:13 +01:00
|
|
|
timer[slotNo]->setTimeout(netTimeout);
|
|
|
|
|
timer[slotNo]->start();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!rewritten && trace)
|
|
|
|
|
LogDebug("Rule Trace,\tnot matched so rejected");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = m_dmrNetwork3->wantsBeacon();
|
|
|
|
|
if (ret)
|
|
|
|
|
m_repeater->writeBeacon();
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-16 11:08:32 +01:00
|
|
|
if (m_dmrNetwork4 != NULL) {
|
|
|
|
|
ret = m_dmrNetwork4->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 != dmr4SrcId[slotNo] || dstId != dmr4DstId[slotNo])) {
|
|
|
|
|
dmr4SrcId[slotNo] = srcId;
|
|
|
|
|
dmr4DstId[slotNo] = dstId;
|
|
|
|
|
trace = true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (trace)
|
|
|
|
|
LogDebug("Rule Trace, network 4 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_dmr4NetRewrites.begin(); it != m_dmr4NetRewrites.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();
|
2019-07-17 10:46:41 +02:00
|
|
|
if (m_status[slotNo] == DMRGWS_NONE || m_status[slotNo] == DMRGWS_DMRNETWORK4) {
|
2019-03-16 11:08:32 +01:00
|
|
|
m_repeater->write(data);
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[slotNo] = DMRGWS_DMRNETWORK4;
|
2019-03-16 11:08:32 +01:00
|
|
|
timer[slotNo]->setTimeout(netTimeout);
|
|
|
|
|
timer[slotNo]->start();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!rewritten && trace)
|
|
|
|
|
LogDebug("Rule Trace,\tnot matched so rejected");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ret = m_dmrNetwork4->wantsBeacon();
|
|
|
|
|
if (ret)
|
|
|
|
|
m_repeater->writeBeacon();
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-17 09:21:52 +02:00
|
|
|
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();
|
2019-07-17 10:46:41 +02:00
|
|
|
if (m_status[slotNo] == DMRGWS_NONE || m_status[slotNo] == DMRGWS_DMRNETWORK5) {
|
2019-07-17 09:21:52 +02:00
|
|
|
m_repeater->write(data);
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[slotNo] = DMRGWS_DMRNETWORK5;
|
2019-07-17 09:21:52 +02:00
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-17 10:46:41 +02:00
|
|
|
processRadioPosition();
|
|
|
|
|
|
|
|
|
|
processTalkerAlias();
|
|
|
|
|
|
|
|
|
|
processHomePosition();
|
2017-05-17 19:58:46 +02:00
|
|
|
|
2020-04-03 17:54:35 +02:00
|
|
|
if (xlxVoice != NULL) {
|
|
|
|
|
ret = xlxVoice->read(data);
|
2017-05-01 15:46:43 +02:00
|
|
|
if (ret) {
|
|
|
|
|
m_repeater->write(data);
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[m_xlxSlot] = DMRGWS_XLXREFLECTOR;
|
2017-09-22 22:10:40 +02:00
|
|
|
timer[m_xlxSlot]->setTimeout(netTimeout);
|
2017-08-20 22:48:49 +02:00
|
|
|
timer[m_xlxSlot]->start();
|
2017-05-01 15:46:43 +02:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-08 00:03:27 +02:00
|
|
|
for (std::vector<CDynVoice*>::iterator it = m_dynVoices.begin(); it != m_dynVoices.end(); ++it) {
|
|
|
|
|
ret = (*it)->read(data);
|
2020-04-03 17:54:35 +02:00
|
|
|
if (ret)
|
|
|
|
|
m_repeater->write(data);
|
|
|
|
|
}
|
|
|
|
|
|
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
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
m_xlxRelink.clock(ms);
|
2017-06-23 21:57:50 +02:00
|
|
|
|
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-11-21 12:30:13 +01:00
|
|
|
if (m_dmrNetwork3 != NULL)
|
|
|
|
|
m_dmrNetwork3->clock(ms);
|
|
|
|
|
|
2019-03-16 11:08:32 +01:00
|
|
|
if (m_dmrNetwork4 != NULL)
|
|
|
|
|
m_dmrNetwork4->clock(ms);
|
|
|
|
|
|
2019-07-17 09:21:52 +02:00
|
|
|
if (m_dmrNetwork5 != NULL)
|
|
|
|
|
m_dmrNetwork5->clock(ms);
|
|
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
if (m_xlxNetwork != NULL)
|
|
|
|
|
m_xlxNetwork->clock(ms);
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-11-21 12:30:13 +01:00
|
|
|
if (m_xlxReflectors != NULL)
|
|
|
|
|
m_xlxReflectors->clock(ms);
|
2017-09-26 14:08:35 +02:00
|
|
|
|
2020-04-03 17:54:35 +02:00
|
|
|
if (xlxVoice != NULL)
|
|
|
|
|
xlxVoice->clock(ms);
|
|
|
|
|
|
2020-04-08 00:03:27 +02:00
|
|
|
for (std::vector<CDynVoice*>::iterator it = m_dynVoices.begin(); it != m_dynVoices.end(); ++it)
|
|
|
|
|
(*it)->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()) {
|
2019-07-17 10:46:41 +02:00
|
|
|
m_status[i] = DMRGWS_NONE;
|
2017-05-03 18:48:55 +02:00
|
|
|
timer[i]->stop();
|
|
|
|
|
}
|
2017-04-20 21:51:30 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ms < 10U)
|
|
|
|
|
CThread::sleep(10U);
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-03 17:54:35 +02:00
|
|
|
delete xlxVoice;
|
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-11-21 12:30:13 +01:00
|
|
|
if (m_dmrNetwork3 != NULL) {
|
|
|
|
|
m_dmrNetwork3->close();
|
|
|
|
|
delete m_dmrNetwork3;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-16 11:08:32 +01:00
|
|
|
if (m_dmrNetwork4 != NULL) {
|
|
|
|
|
m_dmrNetwork4->close();
|
|
|
|
|
delete m_dmrNetwork4;
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-17 09:21:52 +02:00
|
|
|
if (m_dmrNetwork5 != NULL) {
|
|
|
|
|
m_dmrNetwork5->close();
|
|
|
|
|
delete m_dmrNetwork5;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
if (m_xlxNetwork != NULL) {
|
|
|
|
|
m_xlxNetwork->close();
|
|
|
|
|
delete m_xlxNetwork;
|
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-08-20 22:48:49 +02:00
|
|
|
delete m_xlxReflectors;
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-08 00:03:27 +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();
|
2017-09-16 15:33:04 +02:00
|
|
|
bool location = m_conf.getDMRNetwork1Location();
|
2017-05-03 18:48:55 +02:00
|
|
|
bool debug = m_conf.getDMRNetwork1Debug();
|
2017-08-01 22:51:22 +02:00
|
|
|
m_dmr1Name = m_conf.getDMRNetwork1Name();
|
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-08-01 22:51:22 +02:00
|
|
|
LogInfo(" Name: %s", m_dmr1Name.c_str());
|
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-09-16 15:33:04 +02:00
|
|
|
LogInfo(" Location Data: %s", location ? "yes" : "no");
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2018-06-04 22:56:10 +02:00
|
|
|
m_dmrNetwork1 = new CDMRNetwork(address, port, local, id, password, m_dmr1Name, VERSION, 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-10-09 10:38:13 +02:00
|
|
|
unsigned int len = getConfig(m_dmr1Name, config);
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-09-16 15:33:04 +02:00
|
|
|
if (!location)
|
|
|
|
|
::memcpy(config + 30U, "0.00000000.000000", 17U);
|
|
|
|
|
|
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-07-31 13:45:39 +02:00
|
|
|
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);
|
2017-05-03 18:48:55 +02:00
|
|
|
|
2017-08-01 22:51:22 +02:00
|
|
|
CRewriteTG* rfRewrite = new CRewriteTG(m_dmr1Name, (*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toTG, (*it).m_range);
|
|
|
|
|
CRewriteTG* netRewrite = new CRewriteTG(m_dmr1Name, (*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-07-31 13:45:39 +02:00
|
|
|
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);
|
2017-05-15 22:16:52 +02:00
|
|
|
|
2017-08-01 22:51:22 +02:00
|
|
|
CRewritePC* rewrite = new CRewritePC(m_dmr1Name, (*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-08-01 22:51:22 +02:00
|
|
|
CRewriteType* rewrite = new CRewriteType(m_dmr1Name, (*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-07-31 13:45:39 +02:00
|
|
|
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);
|
2017-05-14 19:14:09 +02:00
|
|
|
|
2017-08-01 22:51:22 +02:00
|
|
|
CRewriteSrc* rewrite = new CRewriteSrc(m_dmr1Name, (*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
|
|
|
|
2020-04-01 23:22:12 +02:00
|
|
|
std::vector<CTGDynRewriteStruct> dynRewrites = m_conf.getDMRNetwork1TGDynRewrites();
|
|
|
|
|
for (std::vector<CTGDynRewriteStruct>::const_iterator it = dynRewrites.begin(); it != dynRewrites.end(); ++it) {
|
2020-04-05 14:43:57 +02:00
|
|
|
LogInfo(" Dyn Rewrite: %u:TG%u-%u:TG%u <-> %u:TG%u (disc %u:%u) (status %u:%u)", (*it).m_slot, (*it).m_fromTG, (*it).m_slot, (*it).m_fromTG + (*it).m_range - 1U, (*it).m_slot, (*it).m_toTG, (*it).m_slot, (*it).m_discPC, (*it).m_slot, (*it).m_statusPC);
|
2020-04-01 23:22:12 +02:00
|
|
|
|
2020-04-08 00:03:27 +02:00
|
|
|
CDynVoice* voice = NULL;
|
|
|
|
|
if (m_conf.getVoiceEnabled()) {
|
|
|
|
|
std::string language = m_conf.getVoiceLanguage();
|
|
|
|
|
std::string directory = m_conf.getVoiceDirectory();
|
|
|
|
|
|
|
|
|
|
voice = new CDynVoice(directory, language, m_repeater->getId(), (*it).m_slot, (*it).m_toTG);
|
|
|
|
|
bool ret = voice->open();
|
|
|
|
|
if (!ret) {
|
|
|
|
|
delete voice;
|
|
|
|
|
voice = NULL;
|
|
|
|
|
} else {
|
|
|
|
|
m_dynVoices.push_back(voice);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-01 23:56:48 +02:00
|
|
|
CRewriteDynTGNet* netRewriteDynTG = new CRewriteDynTGNet(m_dmr1Name, (*it).m_slot, (*it).m_toTG);
|
2020-04-08 00:03:27 +02:00
|
|
|
CRewriteDynTGRF* rfRewriteDynTG = new CRewriteDynTGRF(m_dmr1Name, (*it).m_slot, (*it).m_fromTG, (*it).m_toTG, (*it).m_discPC, (*it).m_statusPC, (*it).m_range, (*it).m_exclTGs, netRewriteDynTG, voice);
|
2020-04-01 23:22:12 +02:00
|
|
|
|
|
|
|
|
m_dmr1RFRewrites.push_back(rfRewriteDynTG);
|
|
|
|
|
m_dmr1NetRewrites.push_back(netRewriteDynTG);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-19 08:56:39 +02:00
|
|
|
std::vector<CIdRewriteStruct> idRewrites = m_conf.getDMRNetwork1IdRewrites();
|
|
|
|
|
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_dmr1Name, (*it).m_rfId, (*it).m_netId);
|
|
|
|
|
CRewriteDstId* rewriteDstId = new CRewriteDstId(m_dmr1Name, (*it).m_netId, (*it).m_rfId);
|
|
|
|
|
|
|
|
|
|
m_dmr1SrcRewrites.push_back(rewriteSrcId);
|
|
|
|
|
m_dmr1NetRewrites.push_back(rewriteDstId);
|
|
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
|
|
2017-08-01 22:51:22 +02:00
|
|
|
CPassAllTG* rfPassAllTG = new CPassAllTG(m_dmr1Name, *it);
|
|
|
|
|
CPassAllTG* netPassAllTG = new CPassAllTG(m_dmr1Name, *it);
|
2017-05-27 17:50:34 +02:00
|
|
|
|
2017-06-07 21:40:51 +02:00
|
|
|
m_dmr1Passalls.push_back(rfPassAllTG);
|
2017-05-27 17:50:34 +02:00
|
|
|
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);
|
|
|
|
|
|
2017-08-01 22:51:22 +02:00
|
|
|
CPassAllPC* rfPassAllPC = new CPassAllPC(m_dmr1Name, *it);
|
|
|
|
|
CPassAllPC* netPassAllPC = new CPassAllPC(m_dmr1Name, *it);
|
2017-05-27 17:50:34 +02:00
|
|
|
|
2017-06-07 21:40:51 +02:00
|
|
|
m_dmr1Passalls.push_back(rfPassAllPC);
|
2017-05-27 17:50:34 +02:00
|
|
|
m_dmr1NetRewrites.push_back(netPassAllPC);
|
|
|
|
|
}
|
|
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-08 00:03:27 +02:00
|
|
|
bool CDMRGateway::createDMRNetwork2()
|
2017-05-03 18:48:55 +02:00
|
|
|
{
|
|
|
|
|
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();
|
2017-09-16 15:33:04 +02:00
|
|
|
bool location = m_conf.getDMRNetwork2Location();
|
2017-05-03 18:48:55 +02:00
|
|
|
bool debug = m_conf.getDMRNetwork2Debug();
|
2017-08-01 22:51:22 +02:00
|
|
|
m_dmr2Name = m_conf.getDMRNetwork2Name();
|
2017-05-03 18:48:55 +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 2 Parameters");
|
2017-08-01 22:51:22 +02:00
|
|
|
LogInfo(" Name: %s", m_dmr2Name.c_str());
|
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-09-16 15:33:04 +02:00
|
|
|
LogInfo(" Location Data: %s", location ? "yes" : "no");
|
2017-05-03 18:48:55 +02:00
|
|
|
|
2018-06-04 22:56:10 +02:00
|
|
|
m_dmrNetwork2 = new CDMRNetwork(address, port, local, id, password, m_dmr2Name, VERSION, 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];
|
2017-10-09 10:38:13 +02:00
|
|
|
unsigned int len = getConfig(m_dmr2Name, config);
|
2017-05-03 18:48:55 +02:00
|
|
|
|
2017-09-16 15:33:04 +02:00
|
|
|
if (!location)
|
|
|
|
|
::memcpy(config + 30U, "0.00000000.000000", 17U);
|
|
|
|
|
|
2017-05-03 18:48:55 +02:00
|
|
|
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-07-31 13:45:39 +02:00
|
|
|
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);
|
2017-05-03 18:48:55 +02:00
|
|
|
|
2017-08-01 22:51:22 +02:00
|
|
|
CRewriteTG* rfRewrite = new CRewriteTG(m_dmr2Name, (*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toTG, (*it).m_range);
|
|
|
|
|
CRewriteTG* netRewrite = new CRewriteTG(m_dmr2Name, (*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-07-31 13:45:39 +02:00
|
|
|
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);
|
2017-05-15 22:16:52 +02:00
|
|
|
|
2017-08-01 22:51:22 +02:00
|
|
|
CRewritePC* rewrite = new CRewritePC(m_dmr2Name, (*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-08-01 22:51:22 +02:00
|
|
|
CRewriteType* rewrite = new CRewriteType(m_dmr2Name, (*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-07-31 13:45:39 +02:00
|
|
|
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);
|
2017-05-14 19:14:09 +02:00
|
|
|
|
2017-08-01 22:51:22 +02:00
|
|
|
CRewriteSrc* rewrite = new CRewriteSrc(m_dmr2Name, (*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
|
|
|
|
2020-04-01 23:22:12 +02:00
|
|
|
std::vector<CTGDynRewriteStruct> dynRewrites = m_conf.getDMRNetwork2TGDynRewrites();
|
|
|
|
|
for (std::vector<CTGDynRewriteStruct>::const_iterator it = dynRewrites.begin(); it != dynRewrites.end(); ++it) {
|
2020-04-05 14:43:57 +02:00
|
|
|
LogInfo(" Dyn Rewrite: %u:TG%u-%u:TG%u <-> %u:TG%u (disc %u:%u) (status %u:%u)", (*it).m_slot, (*it).m_fromTG, (*it).m_slot, (*it).m_fromTG + (*it).m_range - 1U, (*it).m_slot, (*it).m_toTG, (*it).m_slot, (*it).m_discPC, (*it).m_slot, (*it).m_statusPC);
|
2020-04-01 23:22:12 +02:00
|
|
|
|
2020-04-08 00:03:27 +02:00
|
|
|
CDynVoice* voice = NULL;
|
|
|
|
|
if (m_conf.getVoiceEnabled()) {
|
|
|
|
|
std::string language = m_conf.getVoiceLanguage();
|
|
|
|
|
std::string directory = m_conf.getVoiceDirectory();
|
|
|
|
|
|
|
|
|
|
voice = new CDynVoice(directory, language, m_repeater->getId(), (*it).m_slot, (*it).m_toTG);
|
|
|
|
|
bool ret = voice->open();
|
|
|
|
|
if (!ret) {
|
|
|
|
|
delete voice;
|
|
|
|
|
voice = NULL;
|
|
|
|
|
} else {
|
|
|
|
|
m_dynVoices.push_back(voice);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-01 23:56:48 +02:00
|
|
|
CRewriteDynTGNet* netRewriteDynTG = new CRewriteDynTGNet(m_dmr2Name, (*it).m_slot, (*it).m_toTG);
|
2020-04-08 00:03:27 +02:00
|
|
|
CRewriteDynTGRF* rfRewriteDynTG = new CRewriteDynTGRF(m_dmr2Name, (*it).m_slot, (*it).m_fromTG, (*it).m_toTG, (*it).m_discPC, (*it).m_statusPC, (*it).m_range, (*it).m_exclTGs, netRewriteDynTG, voice);
|
2020-04-01 23:22:12 +02:00
|
|
|
|
|
|
|
|
m_dmr2RFRewrites.push_back(rfRewriteDynTG);
|
|
|
|
|
m_dmr2NetRewrites.push_back(netRewriteDynTG);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-19 08:56:39 +02:00
|
|
|
std::vector<CIdRewriteStruct> idRewrites = m_conf.getDMRNetwork2IdRewrites();
|
|
|
|
|
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_dmr2Name, (*it).m_rfId, (*it).m_netId);
|
|
|
|
|
CRewriteDstId* rewriteDstId = new CRewriteDstId(m_dmr2Name, (*it).m_netId, (*it).m_rfId);
|
|
|
|
|
|
|
|
|
|
m_dmr2SrcRewrites.push_back(rewriteSrcId);
|
|
|
|
|
m_dmr2NetRewrites.push_back(rewriteDstId);
|
|
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
|
|
2017-08-01 22:51:22 +02:00
|
|
|
CPassAllTG* rfPassAllTG = new CPassAllTG(m_dmr2Name, *it);
|
|
|
|
|
CPassAllTG* netPassAllTG = new CPassAllTG(m_dmr2Name, *it);
|
2017-05-27 17:50:34 +02:00
|
|
|
|
2017-06-07 21:40:51 +02:00
|
|
|
m_dmr2Passalls.push_back(rfPassAllTG);
|
2017-05-27 17:50:34 +02:00
|
|
|
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);
|
|
|
|
|
|
2017-08-01 22:51:22 +02:00
|
|
|
CPassAllPC* rfPassAllPC = new CPassAllPC(m_dmr2Name, *it);
|
|
|
|
|
CPassAllPC* netPassAllPC = new CPassAllPC(m_dmr2Name, *it);
|
2017-05-27 17:50:34 +02:00
|
|
|
|
2017-06-07 21:40:51 +02:00
|
|
|
m_dmr2Passalls.push_back(rfPassAllPC);
|
2017-05-27 17:50:34 +02:00
|
|
|
m_dmr2NetRewrites.push_back(netPassAllPC);
|
|
|
|
|
}
|
|
|
|
|
|
2017-04-20 21:51:30 +02:00
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-08 00:03:27 +02:00
|
|
|
bool CDMRGateway::createDMRNetwork3()
|
2017-11-21 12:30:13 +01:00
|
|
|
{
|
|
|
|
|
std::string address = m_conf.getDMRNetwork3Address();
|
|
|
|
|
unsigned int port = m_conf.getDMRNetwork3Port();
|
|
|
|
|
unsigned int local = m_conf.getDMRNetwork3Local();
|
|
|
|
|
unsigned int id = m_conf.getDMRNetwork3Id();
|
|
|
|
|
std::string password = m_conf.getDMRNetwork3Password();
|
|
|
|
|
bool location = m_conf.getDMRNetwork3Location();
|
|
|
|
|
bool debug = m_conf.getDMRNetwork3Debug();
|
|
|
|
|
m_dmr3Name = m_conf.getDMRNetwork3Name();
|
|
|
|
|
|
|
|
|
|
if (id == 0U)
|
|
|
|
|
id = m_repeater->getId();
|
|
|
|
|
|
|
|
|
|
LogInfo("DMR Network 3 Parameters");
|
2018-12-24 16:17:28 +01:00
|
|
|
LogInfo(" Name: %s", m_dmr3Name.c_str());
|
2017-11-21 12:30:13 +01: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");
|
|
|
|
|
LogInfo(" Location Data: %s", location ? "yes" : "no");
|
|
|
|
|
|
2018-06-04 22:56:10 +02:00
|
|
|
m_dmrNetwork3 = new CDMRNetwork(address, port, local, id, password, m_dmr3Name, VERSION, debug);
|
2017-11-21 12:30:13 +01:00
|
|
|
|
|
|
|
|
std::string options = m_conf.getDMRNetwork3Options();
|
|
|
|
|
if (options.empty())
|
|
|
|
|
options = m_repeater->getOptions();
|
|
|
|
|
|
|
|
|
|
if (!options.empty()) {
|
|
|
|
|
LogInfo(" Options: %s", options.c_str());
|
|
|
|
|
m_dmrNetwork3->setOptions(options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned char config[400U];
|
|
|
|
|
unsigned int len = getConfig(m_dmr3Name, config);
|
|
|
|
|
|
|
|
|
|
if (!location)
|
|
|
|
|
::memcpy(config + 30U, "0.00000000.000000", 17U);
|
|
|
|
|
|
|
|
|
|
m_dmrNetwork3->setConfig(config, len);
|
|
|
|
|
|
|
|
|
|
bool ret = m_dmrNetwork3->open();
|
|
|
|
|
if (!ret) {
|
|
|
|
|
delete m_dmrNetwork3;
|
|
|
|
|
m_dmrNetwork3 = NULL;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork3TGRewrites();
|
|
|
|
|
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_dmr3Name, (*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toTG, (*it).m_range);
|
|
|
|
|
CRewriteTG* netRewrite = new CRewriteTG(m_dmr3Name, (*it).m_toSlot, (*it).m_toTG, (*it).m_fromSlot, (*it).m_fromTG, (*it).m_range);
|
|
|
|
|
|
|
|
|
|
m_dmr3RFRewrites.push_back(rfRewrite);
|
|
|
|
|
m_dmr3NetRewrites.push_back(netRewrite);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<CPCRewriteStruct> pcRewrites = m_conf.getDMRNetwork3PCRewrites();
|
|
|
|
|
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_dmr3Name, (*it).m_fromSlot, (*it).m_fromId, (*it).m_toSlot, (*it).m_toId, (*it).m_range);
|
|
|
|
|
|
|
|
|
|
m_dmr3RFRewrites.push_back(rewrite);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<CTypeRewriteStruct> typeRewrites = m_conf.getDMRNetwork3TypeRewrites();
|
|
|
|
|
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_dmr3Name, (*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toId);
|
|
|
|
|
|
|
|
|
|
m_dmr3RFRewrites.push_back(rewrite);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<CSrcRewriteStruct> srcRewrites = m_conf.getDMRNetwork3SrcRewrites();
|
|
|
|
|
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_dmr3Name, (*it).m_fromSlot, (*it).m_fromId, (*it).m_toSlot, (*it).m_toTG, (*it).m_range);
|
|
|
|
|
|
|
|
|
|
m_dmr3NetRewrites.push_back(rewrite);
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-01 23:22:12 +02:00
|
|
|
std::vector<CTGDynRewriteStruct> dynRewrites = m_conf.getDMRNetwork3TGDynRewrites();
|
|
|
|
|
for (std::vector<CTGDynRewriteStruct>::const_iterator it = dynRewrites.begin(); it != dynRewrites.end(); ++it) {
|
2020-04-05 14:43:57 +02:00
|
|
|
LogInfo(" Dyn Rewrite: %u:TG%u-%u:TG%u <-> %u:TG%u (disc %u:%u) (status %u:%u)", (*it).m_slot, (*it).m_fromTG, (*it).m_slot, (*it).m_fromTG + (*it).m_range - 1U, (*it).m_slot, (*it).m_toTG, (*it).m_slot, (*it).m_discPC, (*it).m_slot, (*it).m_statusPC);
|
2020-04-01 23:22:12 +02:00
|
|
|
|
2020-04-08 00:03:27 +02:00
|
|
|
CDynVoice* voice = NULL;
|
|
|
|
|
if (m_conf.getVoiceEnabled()) {
|
|
|
|
|
std::string language = m_conf.getVoiceLanguage();
|
|
|
|
|
std::string directory = m_conf.getVoiceDirectory();
|
|
|
|
|
|
|
|
|
|
voice = new CDynVoice(directory, language, m_repeater->getId(), (*it).m_slot, (*it).m_toTG);
|
|
|
|
|
bool ret = voice->open();
|
|
|
|
|
if (!ret) {
|
|
|
|
|
delete voice;
|
|
|
|
|
voice = NULL;
|
|
|
|
|
} else {
|
|
|
|
|
m_dynVoices.push_back(voice);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-01 23:56:48 +02:00
|
|
|
CRewriteDynTGNet* netRewriteDynTG = new CRewriteDynTGNet(m_dmr3Name, (*it).m_slot, (*it).m_toTG);
|
2020-04-08 00:03:27 +02:00
|
|
|
CRewriteDynTGRF* rfRewriteDynTG = new CRewriteDynTGRF(m_dmr3Name, (*it).m_slot, (*it).m_fromTG, (*it).m_toTG, (*it).m_discPC, (*it).m_statusPC, (*it).m_range, (*it).m_exclTGs, netRewriteDynTG, voice);
|
2020-04-01 23:22:12 +02:00
|
|
|
|
|
|
|
|
m_dmr3RFRewrites.push_back(rfRewriteDynTG);
|
|
|
|
|
m_dmr3NetRewrites.push_back(netRewriteDynTG);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-19 08:56:39 +02:00
|
|
|
std::vector<CIdRewriteStruct> idRewrites = m_conf.getDMRNetwork3IdRewrites();
|
|
|
|
|
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_dmr3Name, (*it).m_rfId, (*it).m_netId);
|
|
|
|
|
CRewriteDstId* rewriteDstId = new CRewriteDstId(m_dmr3Name, (*it).m_netId, (*it).m_rfId);
|
|
|
|
|
|
|
|
|
|
m_dmr3SrcRewrites.push_back(rewriteSrcId);
|
|
|
|
|
m_dmr3NetRewrites.push_back(rewriteDstId);
|
|
|
|
|
}
|
|
|
|
|
|
2017-11-21 12:30:13 +01:00
|
|
|
std::vector<unsigned int> tgPassAll = m_conf.getDMRNetwork3PassAllTG();
|
|
|
|
|
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_dmr3Name, *it);
|
|
|
|
|
CPassAllTG* netPassAllTG = new CPassAllTG(m_dmr3Name, *it);
|
|
|
|
|
|
|
|
|
|
m_dmr3Passalls.push_back(rfPassAllTG);
|
|
|
|
|
m_dmr3NetRewrites.push_back(netPassAllTG);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<unsigned int> pcPassAll = m_conf.getDMRNetwork3PassAllPC();
|
|
|
|
|
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_dmr3Name, *it);
|
|
|
|
|
CPassAllPC* netPassAllPC = new CPassAllPC(m_dmr3Name, *it);
|
|
|
|
|
|
|
|
|
|
m_dmr3Passalls.push_back(rfPassAllPC);
|
|
|
|
|
m_dmr3NetRewrites.push_back(netPassAllPC);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-08 00:03:27 +02:00
|
|
|
bool CDMRGateway::createDMRNetwork4()
|
2019-03-16 11:08:32 +01:00
|
|
|
{
|
|
|
|
|
std::string address = m_conf.getDMRNetwork4Address();
|
|
|
|
|
unsigned int port = m_conf.getDMRNetwork4Port();
|
|
|
|
|
unsigned int local = m_conf.getDMRNetwork4Local();
|
|
|
|
|
unsigned int id = m_conf.getDMRNetwork4Id();
|
|
|
|
|
std::string password = m_conf.getDMRNetwork4Password();
|
|
|
|
|
bool location = m_conf.getDMRNetwork4Location();
|
|
|
|
|
bool debug = m_conf.getDMRNetwork4Debug();
|
|
|
|
|
m_dmr4Name = m_conf.getDMRNetwork4Name();
|
|
|
|
|
|
|
|
|
|
if (id == 0U)
|
|
|
|
|
id = m_repeater->getId();
|
|
|
|
|
|
|
|
|
|
LogInfo("DMR Network 4 Parameters");
|
|
|
|
|
LogInfo(" Name: %s", m_dmr4Name.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");
|
|
|
|
|
|
2019-03-16 11:44:55 +01:00
|
|
|
m_dmrNetwork4 = new CDMRNetwork(address, port, local, id, password, m_dmr4Name, VERSION, debug);
|
2019-03-16 11:08:32 +01:00
|
|
|
|
|
|
|
|
std::string options = m_conf.getDMRNetwork4Options();
|
|
|
|
|
if (options.empty())
|
|
|
|
|
options = m_repeater->getOptions();
|
|
|
|
|
|
|
|
|
|
if (!options.empty()) {
|
|
|
|
|
LogInfo(" Options: %s", options.c_str());
|
|
|
|
|
m_dmrNetwork4->setOptions(options);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
unsigned char config[400U];
|
|
|
|
|
unsigned int len = getConfig(m_dmr4Name, config);
|
|
|
|
|
|
|
|
|
|
if (!location)
|
|
|
|
|
::memcpy(config + 30U, "0.00000000.000000", 17U);
|
|
|
|
|
|
|
|
|
|
m_dmrNetwork4->setConfig(config, len);
|
|
|
|
|
|
|
|
|
|
bool ret = m_dmrNetwork4->open();
|
|
|
|
|
if (!ret) {
|
|
|
|
|
delete m_dmrNetwork4;
|
|
|
|
|
m_dmrNetwork4 = NULL;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<CTGRewriteStruct> tgRewrites = m_conf.getDMRNetwork4TGRewrites();
|
|
|
|
|
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);
|
|
|
|
|
|
2019-03-16 11:44:55 +01:00
|
|
|
CRewriteTG* rfRewrite = new CRewriteTG(m_dmr4Name, (*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toTG, (*it).m_range);
|
|
|
|
|
CRewriteTG* netRewrite = new CRewriteTG(m_dmr4Name, (*it).m_toSlot, (*it).m_toTG, (*it).m_fromSlot, (*it).m_fromTG, (*it).m_range);
|
2019-03-16 11:08:32 +01:00
|
|
|
|
|
|
|
|
m_dmr4RFRewrites.push_back(rfRewrite);
|
|
|
|
|
m_dmr4NetRewrites.push_back(netRewrite);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<CPCRewriteStruct> pcRewrites = m_conf.getDMRNetwork4PCRewrites();
|
|
|
|
|
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);
|
|
|
|
|
|
2019-03-16 11:44:55 +01:00
|
|
|
CRewritePC* rewrite = new CRewritePC(m_dmr4Name, (*it).m_fromSlot, (*it).m_fromId, (*it).m_toSlot, (*it).m_toId, (*it).m_range);
|
2019-03-16 11:08:32 +01:00
|
|
|
|
|
|
|
|
m_dmr4RFRewrites.push_back(rewrite);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<CTypeRewriteStruct> typeRewrites = m_conf.getDMRNetwork4TypeRewrites();
|
|
|
|
|
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_dmr4Name, (*it).m_fromSlot, (*it).m_fromTG, (*it).m_toSlot, (*it).m_toId);
|
|
|
|
|
|
|
|
|
|
m_dmr4RFRewrites.push_back(rewrite);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<CSrcRewriteStruct> srcRewrites = m_conf.getDMRNetwork4SrcRewrites();
|
|
|
|
|
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_dmr4Name, (*it).m_fromSlot, (*it).m_fromId, (*it).m_toSlot, (*it).m_toTG, (*it).m_range);
|
|
|
|
|
|
|
|
|
|
m_dmr4NetRewrites.push_back(rewrite);
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-01 23:22:12 +02:00
|
|
|
std::vector<CTGDynRewriteStruct> dynRewrites = m_conf.getDMRNetwork4TGDynRewrites();
|
|
|
|
|
for (std::vector<CTGDynRewriteStruct>::const_iterator it = dynRewrites.begin(); it != dynRewrites.end(); ++it) {
|
2020-04-05 14:43:57 +02:00
|
|
|
LogInfo(" Dyn Rewrite: %u:TG%u-%u:TG%u <-> %u:TG%u (disc %u:%u) (status %u:%u)", (*it).m_slot, (*it).m_fromTG, (*it).m_slot, (*it).m_fromTG + (*it).m_range - 1U, (*it).m_slot, (*it).m_toTG, (*it).m_slot, (*it).m_discPC, (*it).m_slot, (*it).m_statusPC);
|
2020-04-01 23:22:12 +02:00
|
|
|
|
2020-04-08 00:03:27 +02:00
|
|
|
CDynVoice* voice = NULL;
|
|
|
|
|
if (m_conf.getVoiceEnabled()) {
|
|
|
|
|
std::string language = m_conf.getVoiceLanguage();
|
|
|
|
|
std::string directory = m_conf.getVoiceDirectory();
|
|
|
|
|
|
|
|
|
|
voice = new CDynVoice(directory, language, m_repeater->getId(), (*it).m_slot, (*it).m_toTG);
|
|
|
|
|
bool ret = voice->open();
|
|
|
|
|
if (!ret) {
|
|
|
|
|
delete voice;
|
|
|
|
|
voice = NULL;
|
|
|
|
|
} else {
|
|
|
|
|
m_dynVoices.push_back(voice);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-01 23:56:48 +02:00
|
|
|
CRewriteDynTGNet* netRewriteDynTG = new CRewriteDynTGNet(m_dmr4Name, (*it).m_slot, (*it).m_toTG);
|
2020-04-08 00:03:27 +02:00
|
|
|
CRewriteDynTGRF* rfRewriteDynTG = new CRewriteDynTGRF(m_dmr4Name, (*it).m_slot, (*it).m_fromTG, (*it).m_toTG, (*it).m_discPC, (*it).m_statusPC, (*it).m_range, (*it).m_exclTGs, netRewriteDynTG, voice);
|
2020-04-01 23:22:12 +02:00
|
|
|
|
|
|
|
|
m_dmr4RFRewrites.push_back(rfRewriteDynTG);
|
|
|
|
|
m_dmr4NetRewrites.push_back(netRewriteDynTG);
|
|
|
|
|
}
|
|
|
|
|
|
2019-05-19 08:56:39 +02:00
|
|
|
std::vector<CIdRewriteStruct> idRewrites = m_conf.getDMRNetwork4IdRewrites();
|
|
|
|
|
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_dmr4Name, (*it).m_rfId, (*it).m_netId);
|
|
|
|
|
CRewriteDstId* rewriteDstId = new CRewriteDstId(m_dmr4Name, (*it).m_netId, (*it).m_rfId);
|
|
|
|
|
|
|
|
|
|
m_dmr4SrcRewrites.push_back(rewriteSrcId);
|
|
|
|
|
m_dmr4NetRewrites.push_back(rewriteDstId);
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-16 11:08:32 +01:00
|
|
|
std::vector<unsigned int> tgPassAll = m_conf.getDMRNetwork4PassAllTG();
|
|
|
|
|
for (std::vector<unsigned int>::const_iterator it = tgPassAll.begin(); it != tgPassAll.end(); ++it) {
|
|
|
|
|
LogInfo(" Pass All TG: %u", *it);
|
|
|
|
|
|
2019-03-16 11:44:55 +01:00
|
|
|
CPassAllTG* rfPassAllTG = new CPassAllTG(m_dmr4Name, *it);
|
|
|
|
|
CPassAllTG* netPassAllTG = new CPassAllTG(m_dmr4Name, *it);
|
2019-03-16 11:08:32 +01:00
|
|
|
|
|
|
|
|
m_dmr4Passalls.push_back(rfPassAllTG);
|
|
|
|
|
m_dmr4NetRewrites.push_back(netPassAllTG);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
std::vector<unsigned int> pcPassAll = m_conf.getDMRNetwork4PassAllPC();
|
|
|
|
|
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_dmr4Name, *it);
|
|
|
|
|
CPassAllPC* netPassAllPC = new CPassAllPC(m_dmr4Name, *it);
|
|
|
|
|
|
|
|
|
|
m_dmr4Passalls.push_back(rfPassAllPC);
|
|
|
|
|
m_dmr4NetRewrites.push_back(netPassAllPC);
|
2019-07-17 09:21:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-08 00:03:27 +02:00
|
|
|
bool CDMRGateway::createDMRNetwork5()
|
2019-07-17 09:21:52 +02:00
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-01 23:22:12 +02:00
|
|
|
std::vector<CTGDynRewriteStruct> dynRewrites = m_conf.getDMRNetwork5TGDynRewrites();
|
|
|
|
|
for (std::vector<CTGDynRewriteStruct>::const_iterator it = dynRewrites.begin(); it != dynRewrites.end(); ++it) {
|
2020-04-05 14:43:57 +02:00
|
|
|
LogInfo(" Dyn Rewrite: %u:TG%u-%u:TG%u <-> %u:TG%u (disc %u:%u) (status %u:%u)", (*it).m_slot, (*it).m_fromTG, (*it).m_slot, (*it).m_fromTG + (*it).m_range - 1U, (*it).m_slot, (*it).m_toTG, (*it).m_slot, (*it).m_discPC, (*it).m_slot, (*it).m_statusPC);
|
2020-04-01 23:22:12 +02:00
|
|
|
|
2020-04-08 00:03:27 +02:00
|
|
|
CDynVoice* voice = NULL;
|
|
|
|
|
if (m_conf.getVoiceEnabled()) {
|
|
|
|
|
std::string language = m_conf.getVoiceLanguage();
|
|
|
|
|
std::string directory = m_conf.getVoiceDirectory();
|
|
|
|
|
|
|
|
|
|
voice = new CDynVoice(directory, language, m_repeater->getId(), (*it).m_slot, (*it).m_toTG);
|
|
|
|
|
bool ret = voice->open();
|
|
|
|
|
if (!ret) {
|
|
|
|
|
delete voice;
|
|
|
|
|
voice = NULL;
|
|
|
|
|
} else {
|
|
|
|
|
m_dynVoices.push_back(voice);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2020-04-01 23:56:48 +02:00
|
|
|
CRewriteDynTGNet* netRewriteDynTG = new CRewriteDynTGNet(m_dmr5Name, (*it).m_slot, (*it).m_toTG);
|
2020-04-08 00:03:27 +02:00
|
|
|
CRewriteDynTGRF* rfRewriteDynTG = new CRewriteDynTGRF(m_dmr5Name, (*it).m_slot, (*it).m_fromTG, (*it).m_toTG, (*it).m_discPC, (*it).m_statusPC, (*it).m_range, (*it).m_exclTGs, netRewriteDynTG, voice);
|
2020-04-01 23:22:12 +02:00
|
|
|
|
|
|
|
|
m_dmr5RFRewrites.push_back(rfRewriteDynTG);
|
|
|
|
|
m_dmr5NetRewrites.push_back(netRewriteDynTG);
|
|
|
|
|
}
|
|
|
|
|
|
2019-07-17 09:21:52 +02:00
|
|
|
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);
|
2019-03-16 11:08:32 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
bool CDMRGateway::createXLXNetwork()
|
2017-05-26 14:26:39 +02:00
|
|
|
{
|
2017-09-26 14:08:35 +02:00
|
|
|
std::string fileName = m_conf.getXLXNetworkFile();
|
|
|
|
|
unsigned int reloadTime = m_conf.getXLXNetworkReloadTime();
|
2017-05-26 14:26:39 +02:00
|
|
|
|
2017-09-26 14:08:35 +02:00
|
|
|
m_xlxReflectors = new CReflectors(fileName, reloadTime);
|
2017-05-26 14:26:39 +02:00
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
bool ret = m_xlxReflectors->load();
|
2017-05-26 14:26:39 +02:00
|
|
|
if (!ret) {
|
2017-08-20 22:48:49 +02:00
|
|
|
delete m_xlxReflectors;
|
2017-05-26 14:26:39 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2018-10-21 11:18:55 +02:00
|
|
|
m_xlxLocal = m_conf.getXLXNetworkLocal();
|
|
|
|
|
m_xlxPort = m_conf.getXLXNetworkPort();
|
|
|
|
|
m_xlxPassword = m_conf.getXLXNetworkPassword();
|
|
|
|
|
m_xlxId = m_conf.getXLXNetworkId();
|
|
|
|
|
m_xlxDebug = m_conf.getXLXNetworkDebug();
|
|
|
|
|
m_xlxUserControl = m_conf.getXLXNetworkUserControl();
|
2017-06-23 21:57:50 +02:00
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
if (m_xlxId == 0U)
|
|
|
|
|
m_xlxId = m_repeater->getId();
|
2017-05-26 14:26:39 +02:00
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
m_xlxSlot = m_conf.getXLXNetworkSlot();
|
|
|
|
|
m_xlxTG = m_conf.getXLXNetworkTG();
|
|
|
|
|
m_xlxBase = m_conf.getXLXNetworkBase();
|
|
|
|
|
m_xlxStartup = m_conf.getXLXNetworkStartup();
|
2018-10-21 16:26:54 +02:00
|
|
|
m_xlxModule = m_conf.getXLXNetworkModule();
|
2017-06-23 10:07:50 +02:00
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
unsigned int xlxRelink = m_conf.getXLXNetworkRelink();
|
2017-06-23 10:07:50 +02:00
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
LogInfo("XLX Network Parameters");
|
|
|
|
|
LogInfo(" Id: %u", m_xlxId);
|
|
|
|
|
LogInfo(" Hosts file: %s", fileName.c_str());
|
2017-09-26 15:58:22 +02:00
|
|
|
LogInfo(" Reload time: %u minutes", reloadTime);
|
2017-08-20 22:48:49 +02:00
|
|
|
if (m_xlxLocal > 0U)
|
|
|
|
|
LogInfo(" Local: %u", m_xlxLocal);
|
|
|
|
|
else
|
|
|
|
|
LogInfo(" Local: random");
|
2017-09-26 15:58:22 +02:00
|
|
|
LogInfo(" Port: %u", m_xlxPort);
|
2017-08-20 22:48:49 +02:00
|
|
|
LogInfo(" Slot: %u", m_xlxSlot);
|
|
|
|
|
LogInfo(" TG: %u", m_xlxTG);
|
|
|
|
|
LogInfo(" Base: %u", m_xlxBase);
|
|
|
|
|
if (m_xlxStartup > 0U)
|
|
|
|
|
LogInfo(" Startup: XLX%03u", m_xlxStartup);
|
|
|
|
|
if (xlxRelink > 0U) {
|
|
|
|
|
m_xlxRelink.setTimeout(xlxRelink * 60U);
|
|
|
|
|
LogInfo(" Relink: %u minutes", xlxRelink);
|
2017-06-23 21:57:50 +02:00
|
|
|
} else {
|
2017-06-20 16:22:30 +02:00
|
|
|
LogInfo(" Relink: disabled");
|
2017-06-23 21:57:50 +02:00
|
|
|
}
|
2018-10-21 11:18:55 +02:00
|
|
|
if (m_xlxUserControl) {
|
|
|
|
|
LogInfo(" User Control: enabled");
|
|
|
|
|
} else {
|
|
|
|
|
LogInfo(" User Control: disabled");
|
|
|
|
|
}
|
2018-10-21 16:26:54 +02:00
|
|
|
if (m_xlxModule) {
|
|
|
|
|
LogInfo(" Module: %c",m_xlxModule);
|
|
|
|
|
}
|
2018-10-21 11:18:55 +02:00
|
|
|
|
2017-05-26 14:26:39 +02:00
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
if (m_xlxStartup > 0U)
|
|
|
|
|
linkXLX(m_xlxStartup);
|
|
|
|
|
|
|
|
|
|
m_rptRewrite = new CRewriteTG("XLX", XLX_SLOT, XLX_TG, m_xlxSlot, m_xlxTG, 1U);
|
|
|
|
|
m_xlxRewrite = new CRewriteTG("XLX", m_xlxSlot, m_xlxTG, XLX_SLOT, XLX_TG, 1U);
|
2017-05-26 14:26:39 +02:00
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
bool CDMRGateway::linkXLX(unsigned int number)
|
2017-04-20 21:51:30 +02:00
|
|
|
{
|
2017-08-20 22:48:49 +02:00
|
|
|
CReflector* reflector = m_xlxReflectors->find(number);
|
|
|
|
|
if (reflector == NULL)
|
|
|
|
|
return false;
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
if (m_xlxNetwork != NULL) {
|
|
|
|
|
LogMessage("XLX, Disconnecting from XLX%03u", m_xlxNumber);
|
|
|
|
|
m_xlxNetwork->close();
|
|
|
|
|
delete m_xlxNetwork;
|
2017-04-20 21:51:30 +02:00
|
|
|
}
|
|
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
m_xlxConnected = false;
|
2017-08-21 14:17:21 +02:00
|
|
|
m_xlxRelink.stop();
|
2017-08-20 22:48:49 +02:00
|
|
|
|
2018-06-04 22:56:10 +02:00
|
|
|
m_xlxNetwork = new CDMRNetwork(reflector->m_address, m_xlxPort, m_xlxLocal, m_xlxId, m_xlxPassword, "XLX", VERSION, m_xlxDebug);
|
2017-08-20 22:48:49 +02:00
|
|
|
|
2017-04-20 21:51:30 +02:00
|
|
|
unsigned char config[400U];
|
2017-10-09 10:38:13 +02:00
|
|
|
unsigned int len = getConfig("XLX", config);
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
m_xlxNetwork->setConfig(config, len);
|
2017-04-20 21:51:30 +02:00
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
bool ret = m_xlxNetwork->open();
|
2017-04-20 21:51:30 +02:00
|
|
|
if (!ret) {
|
2017-08-20 22:48:49 +02:00
|
|
|
delete m_xlxNetwork;
|
|
|
|
|
m_xlxNetwork = NULL;
|
2017-04-20 21:51:30 +02:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2017-09-26 10:19:55 +02:00
|
|
|
m_xlxNumber = number;
|
2018-10-21 16:26:54 +02:00
|
|
|
if (m_xlxModule) {
|
2018-10-21 16:46:24 +02:00
|
|
|
m_xlxRoom = ((int(m_xlxModule) - 64U) + 4000U);
|
2018-10-21 16:26:54 +02:00
|
|
|
} else {
|
|
|
|
|
m_xlxRoom = reflector->m_startup;
|
|
|
|
|
}
|
2017-10-09 10:38:13 +02:00
|
|
|
m_xlxReflector = 4000U;
|
2017-08-21 14:17:21 +02:00
|
|
|
|
2017-08-20 22:48:49 +02:00
|
|
|
LogMessage("XLX, Connecting to XLX%03u", m_xlxNumber);
|
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
|
|
|
|
2017-08-22 10:34:37 +02:00
|
|
|
void CDMRGateway::unlinkXLX()
|
|
|
|
|
{
|
|
|
|
|
if (m_xlxNetwork != NULL) {
|
|
|
|
|
m_xlxNetwork->close();
|
|
|
|
|
delete m_xlxNetwork;
|
|
|
|
|
m_xlxNetwork = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
m_xlxConnected = false;
|
|
|
|
|
m_xlxRelink.stop();
|
|
|
|
|
}
|
|
|
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
2017-10-08 15:13:52 +02:00
|
|
|
|
2019-05-19 08:56:39 +02:00
|
|
|
bool CDMRGateway::rewrite(std::vector<CRewrite*>& rewrites, CDMRData & data, bool trace)
|
|
|
|
|
{
|
|
|
|
|
for (std::vector<CRewrite*>::iterator it = rewrites.begin(); it != rewrites.end(); ++it)
|
|
|
|
|
if ((*it)->process(data, trace))
|
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-09 10:38:13 +02:00
|
|
|
unsigned int CDMRGateway::getConfig(const std::string& name, unsigned char* buffer)
|
2017-10-08 15:13:52 +02:00
|
|
|
{
|
|
|
|
|
assert(buffer != NULL);
|
|
|
|
|
|
|
|
|
|
bool enabled = m_conf.getInfoEnabled();
|
|
|
|
|
|
|
|
|
|
if (!enabled) {
|
2017-10-09 10:38:13 +02:00
|
|
|
LogInfo("%s: Using original configuration message: %*s", name.c_str(), m_configLen, m_config);
|
2017-10-08 15:13:52 +02:00
|
|
|
::memcpy(buffer, m_config, m_configLen);
|
|
|
|
|
return m_configLen;
|
|
|
|
|
}
|
|
|
|
|
|
2017-10-09 10:38:13 +02:00
|
|
|
LogInfo("%s: Original configuration message: %*s", name.c_str(), m_configLen, m_config);
|
|
|
|
|
|
2017-10-08 15:13:52 +02:00
|
|
|
char latitude[20U];
|
|
|
|
|
float lat = m_conf.getInfoLatitude();
|
|
|
|
|
::sprintf(latitude, "%08f", lat);
|
|
|
|
|
|
|
|
|
|
char longitude[20U];
|
|
|
|
|
float lon = m_conf.getInfoLongitude();
|
|
|
|
|
::sprintf(longitude, "%09f", lon);
|
|
|
|
|
|
|
|
|
|
unsigned int power = m_conf.getInfoPower();
|
|
|
|
|
if (power > 99U)
|
|
|
|
|
power = 99U;
|
|
|
|
|
|
|
|
|
|
int height = m_conf.getInfoHeight();
|
|
|
|
|
if (height > 999)
|
|
|
|
|
height = 999;
|
|
|
|
|
|
|
|
|
|
unsigned int rxFrequency = m_conf.getInfoRXFrequency();
|
|
|
|
|
unsigned int txFrequency = m_conf.getInfoTXFrequency();
|
|
|
|
|
std::string location = m_conf.getInfoLocation();
|
|
|
|
|
std::string description = m_conf.getInfoDescription();
|
|
|
|
|
std::string url = m_conf.getInfoURL();
|
|
|
|
|
|
|
|
|
|
::sprintf((char*)buffer, "%-8.8s%09u%09u%02u%2.2s%8.8s%9.9s%03d%-20.20s%-19.19s%c%-124.124s%-40.40s%-40.40s", m_config + 0U,
|
|
|
|
|
rxFrequency, txFrequency, power, m_config + 28U, latitude, longitude, height, location.c_str(),
|
|
|
|
|
description.c_str(), m_config[89U], url.c_str(), m_config + 214U, m_config + 254U);
|
|
|
|
|
|
2017-10-09 10:38:13 +02:00
|
|
|
LogInfo("%s: New configuration message: %s", name.c_str(), buffer);
|
|
|
|
|
|
2017-10-08 15:13:52 +02:00
|
|
|
return (unsigned int)::strlen((char*)buffer);
|
|
|
|
|
}
|
2019-07-17 10:46:41 +02:00
|
|
|
|
|
|
|
|
void CDMRGateway::processRadioPosition()
|
|
|
|
|
{
|
|
|
|
|
unsigned char buffer[50U];
|
|
|
|
|
unsigned int length;
|
|
|
|
|
bool ret = m_repeater->readRadioPosition(buffer, length);
|
|
|
|
|
if (!ret)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (m_xlxNetwork != NULL && (m_status[1U] == DMRGWS_XLXREFLECTOR || m_status[2U] == DMRGWS_XLXREFLECTOR))
|
|
|
|
|
m_xlxNetwork->writeRadioPosition(buffer, length);
|
|
|
|
|
|
|
|
|
|
if (m_dmrNetwork1 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK1 || m_status[2U] == DMRGWS_DMRNETWORK1))
|
|
|
|
|
m_dmrNetwork1->writeRadioPosition(buffer, length);
|
|
|
|
|
|
|
|
|
|
if (m_dmrNetwork2 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK2 || m_status[2U] == DMRGWS_DMRNETWORK2))
|
|
|
|
|
m_dmrNetwork2->writeRadioPosition(buffer, length);
|
|
|
|
|
|
|
|
|
|
if (m_dmrNetwork3 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK3 || m_status[2U] == DMRGWS_DMRNETWORK3))
|
|
|
|
|
m_dmrNetwork3->writeRadioPosition(buffer, length);
|
|
|
|
|
|
|
|
|
|
if (m_dmrNetwork4 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK4 || m_status[2U] == DMRGWS_DMRNETWORK4))
|
|
|
|
|
m_dmrNetwork4->writeRadioPosition(buffer, length);
|
|
|
|
|
|
|
|
|
|
if (m_dmrNetwork5 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK5 || m_status[2U] == DMRGWS_DMRNETWORK5))
|
|
|
|
|
m_dmrNetwork5->writeRadioPosition(buffer, length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDMRGateway::processTalkerAlias()
|
|
|
|
|
{
|
|
|
|
|
unsigned char buffer[50U];
|
|
|
|
|
unsigned int length;
|
2019-07-17 15:36:00 +02:00
|
|
|
bool ret = m_repeater->readTalkerAlias(buffer, length);
|
2019-07-17 10:46:41 +02:00
|
|
|
if (!ret)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (m_xlxNetwork != NULL && (m_status[1U] == DMRGWS_XLXREFLECTOR || m_status[2U] == DMRGWS_XLXREFLECTOR))
|
|
|
|
|
m_xlxNetwork->writeTalkerAlias(buffer, length);
|
|
|
|
|
|
|
|
|
|
if (m_dmrNetwork1 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK1 || m_status[2U] == DMRGWS_DMRNETWORK1))
|
|
|
|
|
m_dmrNetwork1->writeTalkerAlias(buffer, length);
|
|
|
|
|
|
|
|
|
|
if (m_dmrNetwork2 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK2 || m_status[2U] == DMRGWS_DMRNETWORK2))
|
|
|
|
|
m_dmrNetwork2->writeTalkerAlias(buffer, length);
|
|
|
|
|
|
|
|
|
|
if (m_dmrNetwork3 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK3 || m_status[2U] == DMRGWS_DMRNETWORK3))
|
|
|
|
|
m_dmrNetwork3->writeTalkerAlias(buffer, length);
|
|
|
|
|
|
|
|
|
|
if (m_dmrNetwork4 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK4 || m_status[2U] == DMRGWS_DMRNETWORK4))
|
|
|
|
|
m_dmrNetwork4->writeTalkerAlias(buffer, length);
|
|
|
|
|
|
|
|
|
|
if (m_dmrNetwork5 != NULL && (m_status[1U] == DMRGWS_DMRNETWORK5 || m_status[2U] == DMRGWS_DMRNETWORK5))
|
|
|
|
|
m_dmrNetwork5->writeTalkerAlias(buffer, length);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CDMRGateway::processHomePosition()
|
|
|
|
|
{
|
|
|
|
|
unsigned char buffer[50U];
|
|
|
|
|
unsigned int length;
|
2019-07-17 15:36:00 +02:00
|
|
|
bool ret = m_repeater->readHomePosition(buffer, length);
|
2019-07-17 10:46:41 +02:00
|
|
|
if (!ret)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (m_xlxNetwork != NULL)
|
|
|
|
|
m_xlxNetwork->writeHomePosition(buffer, length);
|
|
|
|
|
|
|
|
|
|
if (m_dmrNetwork1 != NULL)
|
|
|
|
|
m_dmrNetwork1->writeHomePosition(buffer, length);
|
|
|
|
|
|
|
|
|
|
if (m_dmrNetwork2 != NULL)
|
|
|
|
|
m_dmrNetwork2->writeHomePosition(buffer, length);
|
|
|
|
|
|
|
|
|
|
if (m_dmrNetwork3 != NULL)
|
|
|
|
|
m_dmrNetwork3->writeHomePosition(buffer, length);
|
|
|
|
|
|
|
|
|
|
if (m_dmrNetwork4 != NULL)
|
|
|
|
|
m_dmrNetwork4->writeHomePosition(buffer, length);
|
|
|
|
|
|
|
|
|
|
if (m_dmrNetwork5 != NULL)
|
|
|
|
|
m_dmrNetwork5->writeHomePosition(buffer, length);
|
|
|
|
|
}
|