From b344248e0a5e736c0d21e39dce71e24f8edf3d5a Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Wed, 26 Aug 2020 14:20:04 +0100 Subject: [PATCH] Simplify the Host to DMR Gateway protocol. --- Conf.cpp | 74 +++++++---------- Conf.h | 19 ++--- DMRGateway.cpp | 164 +++++++++++++++++-------------------- DMRGateway.h | 8 +- DMRGateway.ini | 10 +-- DMRGateway.vcxproj | 4 +- DMRGateway.vcxproj.filters | 12 +-- DMRNetwork.cpp | 26 ++++-- DMRNetwork.h | 7 +- GPSD.cpp | 110 +++++++++++++++++++++++++ GPSD.h | 57 +++++++++++++ MMDVMNetwork.cpp | 131 +++++++---------------------- MMDVMNetwork.h | 34 +++----- Makefile | 13 ++- RepeaterProtocol.cpp | 23 ------ RepeaterProtocol.h | 57 ------------- RewriteType.cpp | 4 +- Version.h | 2 +- 18 files changed, 375 insertions(+), 380 deletions(-) create mode 100644 GPSD.cpp create mode 100644 GPSD.h delete mode 100644 RepeaterProtocol.cpp delete mode 100644 RepeaterProtocol.h diff --git a/Conf.cpp b/Conf.cpp index 13d9a62..32d1478 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -38,7 +38,8 @@ enum SECTION { SECTION_DMR_NETWORK_4, SECTION_DMR_NETWORK_5, SECTION_XLX_NETWORK, - SECTION_DYNAMIC_TG_CONTROL + SECTION_DYNAMIC_TG_CONTROL, + SECTION_GPSD, }; CConf::CConf(const std::string& file) : @@ -59,14 +60,9 @@ m_logDisplayLevel(0U), m_logFileLevel(0U), m_logFilePath(), m_logFileRoot(), -m_infoEnabled(false), -m_infoRXFrequency(0U), -m_infoTXFrequency(0U), -m_infoPower(0U), m_infoLatitude(0.0F), m_infoLongitude(0.0F), m_infoHeight(0), -m_infoLocation(), m_infoDescription(), m_infoURL(), m_dmrNetwork1Enabled(false), @@ -175,7 +171,10 @@ m_xlxNetworkDebug(false), m_xlxNetworkUserControl(true), m_xlxNetworkModule(), m_dynamicTGControlEnabled(false), -m_dynamicTGControlPort(3769U) +m_dynamicTGControlPort(3769U), +m_gpsdEnabled(false), +m_gpsdAddress(), +m_gpsdPort() { } @@ -221,6 +220,8 @@ bool CConf::read() section = SECTION_DMR_NETWORK_5; else if (::strncmp(buffer, "[Dynamic TG Control]", 20U) == 0) section = SECTION_DYNAMIC_TG_CONTROL; + else if (::strncmp(buffer, "[GPSD]", 6U) == 0) + section = SECTION_GPSD; else section = SECTION_NONE; @@ -280,22 +281,12 @@ bool CConf::read() else if (::strcmp(key, "Directory") == 0) m_voiceDirectory = value; } else if (section == SECTION_INFO) { - if (::strcmp(key, "Enabled") == 0) - m_infoEnabled = ::atoi(value) == 1; - else if (::strcmp(key, "TXFrequency") == 0) - m_infoTXFrequency = (unsigned int)::atoi(value); - else if (::strcmp(key, "RXFrequency") == 0) - m_infoRXFrequency = (unsigned int)::atoi(value); - else if (::strcmp(key, "Power") == 0) - m_infoPower = (unsigned int)::atoi(value); - else if (::strcmp(key, "Latitude") == 0) + if (::strcmp(key, "Latitude") == 0) m_infoLatitude = float(::atof(value)); else if (::strcmp(key, "Longitude") == 0) m_infoLongitude = float(::atof(value)); else if (::strcmp(key, "Height") == 0) m_infoHeight = ::atoi(value); - else if (::strcmp(key, "Location") == 0) - m_infoLocation = value; else if (::strcmp(key, "Description") == 0) m_infoDescription = value; else if (::strcmp(key, "URL") == 0) @@ -946,6 +937,13 @@ bool CConf::read() m_dynamicTGControlEnabled = ::atoi(value) == 1; else if (::strcmp(key, "Port") == 0) m_dynamicTGControlPort = (unsigned int)::atoi(value); + } else if (section == SECTION_GPSD) { + if (::strcmp(key, "Enable") == 0) + m_gpsdEnabled = ::atoi(value) == 1; + else if (::strcmp(key, "Address") == 0) + m_gpsdAddress = value; + else if (::strcmp(key, "Port") == 0) + m_gpsdPort = value; } } @@ -1034,26 +1032,6 @@ std::string CConf::getVoiceDirectory() const return m_voiceDirectory; } -bool CConf::getInfoEnabled() const -{ - return m_infoEnabled; -} - -unsigned int CConf::getInfoRXFrequency() const -{ - return m_infoRXFrequency; -} - -unsigned int CConf::getInfoTXFrequency() const -{ - return m_infoTXFrequency; -} - -unsigned int CConf::getInfoPower() const -{ - return m_infoPower; -} - float CConf::getInfoLatitude() const { return m_infoLatitude; @@ -1069,11 +1047,6 @@ int CConf::getInfoHeight() const return m_infoHeight; } -std::string CConf::getInfoLocation() const -{ - return m_infoLocation; -} - std::string CConf::getInfoDescription() const { return m_infoDescription; @@ -1631,3 +1604,18 @@ unsigned int CConf::getDynamicTGControlPort() const { return m_dynamicTGControlPort; } + +bool CConf::getGPSDEnabled() const +{ + return m_gpsdEnabled; +} + +std::string CConf::getGPSDAddress() const +{ + return m_gpsdAddress; +} + +std::string CConf::getGPSDPort() const +{ + return m_gpsdPort; +} diff --git a/Conf.h b/Conf.h index b038329..7fc7482 100644 --- a/Conf.h +++ b/Conf.h @@ -100,14 +100,9 @@ public: std::string getVoiceDirectory() const; // The Info section - bool getInfoEnabled() const; - unsigned int getInfoRXFrequency() const; - unsigned int getInfoTXFrequency() const; - unsigned int getInfoPower() const; float getInfoLatitude() const; float getInfoLongitude() const; int getInfoHeight() const; - std::string getInfoLocation() const; std::string getInfoDescription() const; std::string getInfoURL() const; @@ -232,6 +227,11 @@ public: bool getDynamicTGControlEnabled() const; unsigned int getDynamicTGControlPort() const; + // The GPSD section + bool getGPSDEnabled() const; + std::string getGPSDAddress() const; + std::string getGPSDPort() const; + private: std::string m_file; bool m_daemon; @@ -253,14 +253,9 @@ private: std::string m_logFilePath; std::string m_logFileRoot; - bool m_infoEnabled; - unsigned int m_infoRXFrequency; - unsigned int m_infoTXFrequency; - unsigned int m_infoPower; float m_infoLatitude; float m_infoLongitude; int m_infoHeight; - std::string m_infoLocation; std::string m_infoDescription; std::string m_infoURL; @@ -377,6 +372,10 @@ private: bool m_dynamicTGControlEnabled; unsigned int m_dynamicTGControlPort; + + bool m_gpsdEnabled; + std::string m_gpsdAddress; + std::string m_gpsdPort; }; #endif diff --git a/DMRGateway.cpp b/DMRGateway.cpp index 4f961d6..b7f1a81 100644 --- a/DMRGateway.cpp +++ b/DMRGateway.cpp @@ -182,6 +182,9 @@ m_dmr5Passalls(), m_dynVoices(), m_dynRF(), m_socket(NULL) +#if defined(USE_GPSD) +,m_gpsd(NULL) +#endif { m_status = new DMRGW_STATUS[3U]; m_status[1U] = DMRGWS_NONE; @@ -354,7 +357,7 @@ int CDMRGateway::run() LogMessage("Waiting for MMDVM to connect....."); while (!m_killed) { - m_configLen = m_repeater->getConfig(m_config); + m_configLen = m_repeater->getShortConfig(m_config); if (m_configLen > 0U && m_repeater->getId() > 1000U) break; @@ -371,6 +374,26 @@ int CDMRGateway::run() LogMessage("MMDVM has connected"); +#if defined(USE_GPSD) + bool gpsdEnabled = m_conf.getGPSDEnabled(); + if (gpsdEnabled) { + std::string gpsdAddress = m_conf.getGPSDAddress(); + std::string gpsdPort = m_conf.getGPSDPort(); + + LogInfo("GPSD Parameters"); + LogInfo(" Address: %s", gpsdAddress.c_str()); + LogInfo(" Port: %s", gpsdPort.c_str()); + + m_gpsd = new CGPSD(gpsdAddress, gpsdPort, m_dmrNetwork); + + ret = m_gpsd->open(); + if (!ret) { + delete m_gpsd; + m_gpsd = NULL; + } + } +#endif + bool ruleTrace = m_conf.getRuleTrace(); LogInfo("Rule trace: %s", ruleTrace ? "yes" : "no"); @@ -1131,8 +1154,6 @@ int CDMRGateway::run() processTalkerAlias(); - processHomePosition(); - if (xlxVoice != NULL) { ret = xlxVoice->read(data); if (ret) { @@ -1183,6 +1204,11 @@ int CDMRGateway::run() if (xlxVoice != NULL) xlxVoice->clock(ms); +#if defined(USE_GPSD) + if (m_gpsd != NULL) + m_gpsd->clock(ms); +#endif + for (std::vector::iterator it = m_dynVoices.begin(); it != m_dynVoices.end(); ++it) (*it)->clock(ms); @@ -1203,6 +1229,13 @@ int CDMRGateway::run() m_repeater->close(); delete m_repeater; +#if defined(USE_GPSD) + if (m_gpsd != NULL) { + m_gpsd->close(); + delete m_gpsd; + } +#endif + if (m_dmrNetwork1 != NULL) { m_dmrNetwork1->close(); delete m_dmrNetwork1; @@ -1297,11 +1330,9 @@ bool CDMRGateway::createDMRNetwork1() LogInfo(" Local: random"); LogInfo(" Location Data: %s", location ? "yes" : "no"); - m_dmrNetwork1 = new CDMRNetwork(address, port, local, id, password, m_dmr1Name, VERSION, debug); + m_dmrNetwork1 = new CDMRNetwork(address, port, local, id, password, m_dmr1Name, VERSION, location, debug); std::string options = m_conf.getDMRNetwork1Options(); - if (options.empty()) - options = m_repeater->getOptions(); if (!options.empty()) { LogInfo(" Options: %s", options.c_str()); @@ -1310,10 +1341,6 @@ bool CDMRGateway::createDMRNetwork1() unsigned char config[400U]; unsigned int len = getConfig(m_dmr1Name, config); - - if (!location) - ::memcpy(config + 30U, "0.00000000.000000", 17U); - m_dmrNetwork1->setConfig(config, len); bool ret = m_dmrNetwork1->open(); @@ -1323,6 +1350,11 @@ bool CDMRGateway::createDMRNetwork1() return false; } +#if defined(USE_GPSD) + if (location) + m_gpsd->addNetwork(m_dmrNetwork1); +#endif + std::vector tgRewrites = m_conf.getDMRNetwork1TGRewrites(); for (std::vector::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) { if ((*it).m_range == 1) @@ -1465,11 +1497,9 @@ bool CDMRGateway::createDMRNetwork2() LogInfo(" Local: random"); LogInfo(" Location Data: %s", location ? "yes" : "no"); - m_dmrNetwork2 = new CDMRNetwork(address, port, local, id, password, m_dmr2Name, VERSION, debug); + m_dmrNetwork2 = new CDMRNetwork(address, port, local, id, password, m_dmr2Name, VERSION, location, debug); std::string options = m_conf.getDMRNetwork2Options(); - if (options.empty()) - options = m_repeater->getOptions(); if (!options.empty()) { LogInfo(" Options: %s", options.c_str()); @@ -1479,9 +1509,6 @@ bool CDMRGateway::createDMRNetwork2() unsigned char config[400U]; unsigned int len = getConfig(m_dmr2Name, config); - if (!location) - ::memcpy(config + 30U, "0.00000000.000000", 17U); - m_dmrNetwork2->setConfig(config, len); bool ret = m_dmrNetwork2->open(); @@ -1491,6 +1518,11 @@ bool CDMRGateway::createDMRNetwork2() return false; } +#if defined(USE_GPSD) + if (location) + m_gpsd->addNetwork(m_dmrNetwork2); +#endif + std::vector tgRewrites = m_conf.getDMRNetwork2TGRewrites(); for (std::vector::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) { if ((*it).m_range == 1) @@ -1633,11 +1665,9 @@ bool CDMRGateway::createDMRNetwork3() LogInfo(" Local: random"); LogInfo(" Location Data: %s", location ? "yes" : "no"); - m_dmrNetwork3 = new CDMRNetwork(address, port, local, id, password, m_dmr3Name, VERSION, debug); + m_dmrNetwork3 = new CDMRNetwork(address, port, local, id, password, m_dmr3Name, VERSION, location, debug); std::string options = m_conf.getDMRNetwork3Options(); - if (options.empty()) - options = m_repeater->getOptions(); if (!options.empty()) { LogInfo(" Options: %s", options.c_str()); @@ -1646,10 +1676,6 @@ bool CDMRGateway::createDMRNetwork3() 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(); @@ -1659,6 +1685,11 @@ bool CDMRGateway::createDMRNetwork3() return false; } +#if defined(USE_GPSD) + if (location) + m_gpsd->addNetwork(m_dmrNetwork3); +#endif + std::vector tgRewrites = m_conf.getDMRNetwork3TGRewrites(); for (std::vector::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) { if ((*it).m_range == 1) @@ -1801,11 +1832,9 @@ bool CDMRGateway::createDMRNetwork4() LogInfo(" Local: random"); LogInfo(" Location Data: %s", location ? "yes" : "no"); - m_dmrNetwork4 = new CDMRNetwork(address, port, local, id, password, m_dmr4Name, VERSION, debug); + m_dmrNetwork4 = new CDMRNetwork(address, port, local, id, password, m_dmr4Name, VERSION, location, debug); std::string options = m_conf.getDMRNetwork4Options(); - if (options.empty()) - options = m_repeater->getOptions(); if (!options.empty()) { LogInfo(" Options: %s", options.c_str()); @@ -1814,10 +1843,6 @@ bool CDMRGateway::createDMRNetwork4() 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(); @@ -1827,6 +1852,11 @@ bool CDMRGateway::createDMRNetwork4() return false; } +#if defined(USE_GPSD) + if (location) + m_gpsd->addNetwork(m_dmrNetwork4); +#endif + std::vector tgRewrites = m_conf.getDMRNetwork4TGRewrites(); for (std::vector::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) { if ((*it).m_range == 1) @@ -1969,11 +1999,9 @@ bool CDMRGateway::createDMRNetwork5() LogInfo(" Local: random"); LogInfo(" Location Data: %s", location ? "yes" : "no"); - m_dmrNetwork5 = new CDMRNetwork(address, port, local, id, password, m_dmr5Name, VERSION, debug); + m_dmrNetwork5 = new CDMRNetwork(address, port, local, id, password, m_dmr5Name, VERSION, location, debug); std::string options = m_conf.getDMRNetwork5Options(); - if (options.empty()) - options = m_repeater->getOptions(); if (!options.empty()) { LogInfo(" Options: %s", options.c_str()); @@ -1982,10 +2010,6 @@ bool CDMRGateway::createDMRNetwork5() 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(); @@ -1995,6 +2019,11 @@ bool CDMRGateway::createDMRNetwork5() return false; } +#if defined(USE_GPSD) + if (location) + m_gpsd->addNetwork(m_dmrNetwork5); +#endif + std::vector tgRewrites = m_conf.getDMRNetwork5TGRewrites(); for (std::vector::const_iterator it = tgRewrites.begin(); it != tgRewrites.end(); ++it) { if ((*it).m_range == 1) @@ -2213,7 +2242,7 @@ bool CDMRGateway::linkXLX(unsigned int number) m_xlxConnected = false; m_xlxRelink.stop(); - m_xlxNetwork = new CDMRNetwork(reflector->m_address, m_xlxPort, m_xlxLocal, m_xlxId, m_xlxPassword, "XLX", VERSION, m_xlxDebug); + m_xlxNetwork = new CDMRNetwork(reflector->m_address, m_xlxPort, m_xlxLocal, m_xlxId, m_xlxPassword, "XLX", VERSION, false, m_xlxDebug); unsigned char config[400U]; unsigned int len = getConfig("XLX", config); @@ -2319,16 +2348,6 @@ unsigned int CDMRGateway::getConfig(const std::string& name, unsigned char* buff { assert(buffer != NULL); - bool enabled = m_conf.getInfoEnabled(); - - if (!enabled) { - LogInfo("%s: Using original configuration message: %*s", name.c_str(), m_configLen, m_config); - ::memcpy(buffer, m_config, m_configLen); - return m_configLen; - } - - LogInfo("%s: Original configuration message: %*s", name.c_str(), m_configLen, m_config); - char latitude[20U]; float lat = m_conf.getInfoLatitude(); ::sprintf(latitude, "%08f", lat); @@ -2337,25 +2356,18 @@ unsigned int CDMRGateway::getConfig(const std::string& name, unsigned char* buff 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(); + 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); + ::sprintf((char*)buffer, "%30.30s%9.9s%9.9s%03d%-20.20s%-19.19s%c%-124.124s%80.80s", + m_config + 0U, latitude, longitude, height, m_config + 30U, + description.c_str(), m_config[50U], url.c_str(), m_config + 51U); - LogInfo("%s: New configuration message: %s", name.c_str(), buffer); + LogInfo("%s: configuration message: %s", name.c_str(), buffer); return (unsigned int)::strlen((char*)buffer); } @@ -2368,9 +2380,6 @@ void CDMRGateway::processRadioPosition() 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); @@ -2414,33 +2423,6 @@ void CDMRGateway::processTalkerAlias() m_dmrNetwork5->writeTalkerAlias(buffer, length); } -void CDMRGateway::processHomePosition() -{ - unsigned char buffer[50U]; - unsigned int length; - bool ret = m_repeater->readHomePosition(buffer, length); - 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); -} - void CDMRGateway::processDynamicTGControl() { unsigned char buffer[100U]; diff --git a/DMRGateway.h b/DMRGateway.h index 0312e5b..0898cba 100644 --- a/DMRGateway.h +++ b/DMRGateway.h @@ -19,7 +19,6 @@ #if !defined(DMRGateway_H) #define DMRGateway_H -#include "RepeaterProtocol.h" #include "RewriteDynTGNet.h" #include "RewriteDynTGRF.h" #include "MMDVMNetwork.h" @@ -31,6 +30,7 @@ #include "Rewrite.h" #include "Timer.h" #include "Conf.h" +#include "GPSD.h" #include @@ -55,7 +55,7 @@ public: private: CConf m_conf; DMRGW_STATUS* m_status; - IRepeaterProtocol* m_repeater; + CMMDVMNetwork* m_repeater; unsigned char* m_config; unsigned int m_configLen; CDMRNetwork* m_dmrNetwork1; @@ -111,6 +111,9 @@ private: std::vector m_dynVoices; std::vector m_dynRF; CUDPSocket* m_socket; +#if defined(USE_GPSD) + CGPSD* m_gpsd; +#endif bool createMMDVM(); bool createDMRNetwork1(); @@ -131,7 +134,6 @@ private: void processRadioPosition(); void processTalkerAlias(); - void processHomePosition(); void processDynamicTGControl(); }; diff --git a/DMRGateway.ini b/DMRGateway.ini index 675e5f9..4771d57 100644 --- a/DMRGateway.ini +++ b/DMRGateway.ini @@ -23,14 +23,9 @@ Language=en_GB Directory=./Audio [Info] -Enabled=0 -RXFrequency=435000000 -TXFrequency=435000000 -Power=1 Latitude=0.0 Longitude=0.0 Height=0 -Location=Nowhere Description=Multi-Mode Repeater URL=www.google.co.uk @@ -137,6 +132,11 @@ Password=PASSWORD Location=0 Debug=0 +[GPSD] +Enable=0 +Address=127.0.0.1 +Port=2947 + [Dynamic TG Control] Enabled=1 Port=3769 diff --git a/DMRGateway.vcxproj b/DMRGateway.vcxproj index fb7a833..59a1d26 100644 --- a/DMRGateway.vcxproj +++ b/DMRGateway.vcxproj @@ -168,6 +168,7 @@ + @@ -175,7 +176,6 @@ - @@ -213,6 +213,7 @@ + @@ -220,7 +221,6 @@ - diff --git a/DMRGateway.vcxproj.filters b/DMRGateway.vcxproj.filters index 63ad046..2913d8d 100644 --- a/DMRGateway.vcxproj.filters +++ b/DMRGateway.vcxproj.filters @@ -83,9 +83,6 @@ Header Files - - Header Files - Header Files @@ -143,6 +140,9 @@ Header Files + + Header Files + @@ -208,9 +208,6 @@ Source Files - - Source Files - Source Files @@ -268,5 +265,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/DMRNetwork.cpp b/DMRNetwork.cpp index 724c4b4..b3c1a4b 100644 --- a/DMRNetwork.cpp +++ b/DMRNetwork.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -31,13 +31,14 @@ const unsigned int BUFFER_LENGTH = 500U; const unsigned int HOMEBREW_DATA_PACKET_LENGTH = 55U; -CDMRNetwork::CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, const std::string& name, const char* version, bool debug) : +CDMRNetwork::CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, const std::string& name, const char* version, bool location, bool debug) : m_address(), m_port(port), m_id(NULL), m_password(password), m_name(name), m_version(version), +m_location(location), m_debug(debug), m_socket(local), m_status(WAITING_CONNECT), @@ -233,13 +234,16 @@ bool CDMRNetwork::writeRadioPosition(const unsigned char* data, unsigned int len if (m_status != RUNNING) return false; + if (!m_location) + return false; + unsigned char buffer[50U]; ::memcpy(buffer + 0U, "DMRG", 4U); ::memcpy(buffer + 4U, m_id, 4U); - ::memcpy(buffer + 8U, data + 8U, length - 8U); + ::memcpy(buffer + 8U, data + 4U, length - 4U); return write(buffer, length); } @@ -255,25 +259,28 @@ bool CDMRNetwork::writeTalkerAlias(const unsigned char* data, unsigned int lengt ::memcpy(buffer + 4U, m_id, 4U); - ::memcpy(buffer + 8U, data + 8U, length - 8U); + ::memcpy(buffer + 8U, data + 4U, length - 4U); return write(buffer, length); } -bool CDMRNetwork::writeHomePosition(const unsigned char* data, unsigned int length) +bool CDMRNetwork::writeHomePosition(float latitude, float longitude) { if (m_status != RUNNING) return false; - unsigned char buffer[50U]; + if (!m_location) + return false; + + char buffer[50U]; ::memcpy(buffer + 0U, "RPTG", 4U); ::memcpy(buffer + 4U, m_id, 4U); - ::memcpy(buffer + 8U, data + 8U, length - 8U); + ::sprintf(buffer + 8U, "%08f%09f", latitude, longitude); - return write(buffer, length); + return write((unsigned char*)buffer, 25U); } bool CDMRNetwork::isConnected() const @@ -497,6 +504,9 @@ bool CDMRNetwork::writeConfig() ::memset(buffer + 222U, ' ', 40U); ::memcpy(buffer + 222U, software, ::strlen(software)); + if (!m_location) + ::memcpy(buffer + 30U, "0.00000000.000000", 17U); + return write((unsigned char*)buffer, m_configLen + 8U); } diff --git a/DMRNetwork.h b/DMRNetwork.h index 458d8df..4448b71 100644 --- a/DMRNetwork.h +++ b/DMRNetwork.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -30,7 +30,7 @@ class CDMRNetwork { public: - CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, const std::string& name, const char* version, bool debug); + CDMRNetwork(const std::string& address, unsigned int port, unsigned int local, unsigned int id, const std::string& password, const std::string& name, const char* version, bool location, bool debug); ~CDMRNetwork(); void setOptions(const std::string& options); @@ -47,7 +47,7 @@ public: bool writeTalkerAlias(const unsigned char* data, unsigned int length); - bool writeHomePosition(const unsigned char* data, unsigned int length); + bool writeHomePosition(float latitude, float longitude); bool wantsBeacon(); @@ -64,6 +64,7 @@ private: std::string m_password; std::string m_name; const char* m_version; + bool m_location; bool m_debug; CUDPSocket m_socket; diff --git a/GPSD.cpp b/GPSD.cpp new file mode 100644 index 0000000..16acc00 --- /dev/null +++ b/GPSD.cpp @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2018,2020 by Jonathan Naylor G4KLX + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include "GPSD.h" + +#if defined(USE_GPSD) + +#include +#include +#include +#include + +CGPSD::CGPSD(const std::string& address, const std::string& port) : +m_gpsdAddress(address), +m_gpsdPort(port), +m_gpsdData(), +m_idTimer(1000U, 60U), +m_networks() +{ + assert(!address.empty()); + assert(!port.empty()); +} + +CGPSD::~CGPSD() +{ +} + +void CGPSD::addNetwork(CDMRNetwork* network) +{ + assert(network != NULL); + + m_networks.push_back(network); +} + +bool CGPSD::open() +{ + int ret = ::gps_open(m_gpsdAddress.c_str(), m_gpsdPort.c_str(), &m_gpsdData); + if (ret != 0) { + LogError("Error when opening access to gpsd - %d - %s", errno, ::gps_errstr(errno)); + return false; + } + + ::gps_stream(&m_gpsdData, WATCH_ENABLE | WATCH_JSON, NULL); + + LogMessage("Connected to GPSD"); + + m_idTimer.start(); + + return true; +} + +void CGPSD::clock(unsigned int ms) +{ + m_idTimer.clock(ms); + + if (m_idTimer.hasExpired()) { + sendReport(); + m_idTimer.start(); + } +} + +void CGPSD::close() +{ + ::gps_stream(&m_gpsdData, WATCH_DISABLE, NULL); + ::gps_close(&m_gpsdData); +} + +void CGPSD::sendReport() +{ + if (!::gps_waiting(&m_gpsdData, 0)) + return; + +#if GPSD_API_MAJOR_VERSION >= 7 + if (::gps_read(&m_gpsdData, NULL, 0) <= 0) + return; +#else + if (::gps_read(&m_gpsdData) <= 0) + return; +#endif + + if (m_gpsdData.status != STATUS_FIX) + return; + + bool latlonSet = (m_gpsdData.set & LATLON_SET) == LATLON_SET; + if (!latlonSet) + return; + + float latitude = float(m_gpsdData.fix.latitude); + float longitude = float(m_gpsdData.fix.longitude); + + for (std::vector::const_iterator it = m_networks.begin(); it != m_networks.end(); ++it) + (*it)->writeHomePosition(latitude, longitude); +} + +#endif diff --git a/GPSD.h b/GPSD.h new file mode 100644 index 0000000..7be3df8 --- /dev/null +++ b/GPSD.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2018,2020 by Jonathan Naylor G4KLX + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#ifndef GPSD_H +#define GPSD_H + +#if defined(USE_GPSD) + +#include "DMRNetwork.h" +#include "Timer.h" + +#include +#include + +#include + +class CGPSD { +public: + CGPSD(const std::string& address, const std::string& port); + ~CGPSD(); + + void addNetwork(CDMRNetwork* network); + + bool open(); + + void clock(unsigned int ms); + + void close(); + +private: + std::string m_gpsdAddress; + std::string m_gpsdPort; + struct gps_data_t m_gpsdData; + CTimer m_idTimer; + std::vector m_networks; + + void sendReport(); +}; + +#endif + +#endif diff --git a/MMDVMNetwork.cpp b/MMDVMNetwork.cpp index 1bc1d78..571d935 100644 --- a/MMDVMNetwork.cpp +++ b/MMDVMNetwork.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,6 @@ #include "MMDVMNetwork.h" #include "StopWatch.h" -#include "SHA256.h" #include "Utils.h" #include "Log.h" @@ -40,15 +39,12 @@ m_debug(debug), m_socket(localAddress, localPort), m_buffer(NULL), m_rxData(1000U, "MMDVM Network"), -m_options(), m_configData(NULL), m_configLen(0U), m_radioPositionData(NULL), m_radioPositionLen(0U), m_talkerAliasData(NULL), -m_talkerAliasLen(0U), -m_homePositionData(NULL), -m_homePositionLen(0U) +m_talkerAliasLen(0U) { assert(!rptAddress.empty()); assert(rptPort > 0U); @@ -60,7 +56,6 @@ m_homePositionLen(0U) m_radioPositionData = new unsigned char[50U]; m_talkerAliasData = new unsigned char[50U]; - m_homePositionData = new unsigned char[50U]; CStopWatch stopWatch; ::srand(stopWatch.start()); @@ -73,15 +68,9 @@ CMMDVMNetwork::~CMMDVMNetwork() delete[] m_configData; delete[] m_radioPositionData; delete[] m_talkerAliasData; - delete[] m_homePositionData; } -std::string CMMDVMNetwork::getOptions() const -{ - return m_options; -} - -unsigned int CMMDVMNetwork::getConfig(unsigned char* config) const +unsigned int CMMDVMNetwork::getShortConfig(unsigned char* config) const { if (m_configData == 0U) return 0U; @@ -248,39 +237,15 @@ bool CMMDVMNetwork::readTalkerAlias(unsigned char* data, unsigned int& length) return true; } -bool CMMDVMNetwork::readHomePosition(unsigned char* data, unsigned int& length) -{ - if (m_homePositionLen == 0U) - return false; - - ::memcpy(data, m_homePositionData, m_homePositionLen); - length = m_homePositionLen; - - m_homePositionLen = 0U; - - return true; -} - bool CMMDVMNetwork::writeBeacon() { - unsigned char buffer[20U]; - ::memcpy(buffer + 0U, "RPTSBKN", 7U); - ::memcpy(buffer + 7U, m_netId, 4U); - - return m_socket.write(buffer, 11U, m_rptAddress, m_rptPort); + return m_socket.write((unsigned char*)"DMRB", 4U, m_rptAddress, m_rptPort); } void CMMDVMNetwork::close() { - unsigned char buffer[HOMEBREW_DATA_PACKET_LENGTH]; - ::memset(buffer, 0x00U, HOMEBREW_DATA_PACKET_LENGTH); - LogMessage("MMDVM Network, Closing"); - ::memcpy(buffer + 0U, "MSTCL", 5U); - ::memcpy(buffer + 5U, m_netId, 4U); - - m_socket.write(buffer, HOMEBREW_DATA_PACKET_LENGTH, m_rptAddress, m_rptPort); m_socket.close(); } @@ -289,74 +254,36 @@ void CMMDVMNetwork::clock(unsigned int ms) in_addr address; unsigned int port; int length = m_socket.read(m_buffer, BUFFER_LENGTH, address, port); - if (length < 0) { - LogError("MMDVM Network, Socket has failed, reopening"); - close(); - open(); + if (length <= 0) + return; + + if (m_rptAddress.s_addr != address.s_addr || m_rptPort != port) { + LogMessage("Packet received from an invalid source, %08X != %08X and/or %u != %u", m_rptAddress.s_addr, address.s_addr, m_rptPort, port); return; } - // if (m_debug && length > 0) - // CUtils::dump(1U, "Network Received", m_buffer, length); + if (m_debug) + CUtils::dump(1U, "Network Received", m_buffer, length); - if (length > 0 && m_rptAddress.s_addr == address.s_addr && m_rptPort == port) { - if (::memcmp(m_buffer, "DMRD", 4U) == 0) { - if (m_debug) - CUtils::dump(1U, "Network Received", m_buffer, length); + if (::memcmp(m_buffer, "DMRD", 4U) == 0) { + unsigned char len = length; + m_rxData.addData(&len, 1U); + m_rxData.addData(m_buffer, len); + } else if (::memcmp(m_buffer, "DMRG", 4U) == 0) { + ::memcpy(m_radioPositionData, m_buffer, length); + m_radioPositionLen = length; + } else if (::memcmp(m_buffer, "DMRA", 4U) == 0) { + ::memcpy(m_talkerAliasData, m_buffer, length); + m_talkerAliasLen = length; + } else if (::memcmp(m_buffer, "DMRC", 4U) == 0) { + m_id = (m_buffer[4U] << 24) | (m_buffer[5U] << 16) | (m_buffer[6U] << 8) | (m_buffer[7U] << 0); - unsigned char len = length; - m_rxData.addData(&len, 1U); - m_rxData.addData(m_buffer, len); - } else if (::memcmp(m_buffer, "DMRG", 4U) == 0) { - ::memcpy(m_radioPositionData, m_buffer, length); - m_radioPositionLen = length; - } else if (::memcmp(m_buffer, "DMRA", 4U) == 0) { - ::memcpy(m_talkerAliasData, m_buffer, length); - m_talkerAliasLen = length; - } else if (::memcmp(m_buffer, "RPTG", 4U) == 0) { - ::memcpy(m_homePositionData, m_buffer, length); - m_homePositionLen = length; - } else if (::memcmp(m_buffer, "RPTL", 4U) == 0) { - m_id = (m_buffer[4U] << 24) | (m_buffer[5U] << 16) | (m_buffer[6U] << 8) | (m_buffer[7U] << 0); - ::memcpy(m_netId, m_buffer + 4U, 4U); + m_configLen = length - 8U; + m_configData = new unsigned char[m_configLen]; + ::memcpy(m_configData, m_buffer + 8U, m_configLen); - unsigned char ack[10U]; - ::memcpy(ack + 0U, "RPTACK", 6U); - - uint32_t salt = 1U; - ::memcpy(ack + 6U, &salt, sizeof(uint32_t)); - - m_socket.write(ack, 10U, m_rptAddress, m_rptPort); - } else if (::memcmp(m_buffer, "RPTK", 4U) == 0) { - unsigned char ack[10U]; - ::memcpy(ack + 0U, "RPTACK", 6U); - ::memcpy(ack + 6U, m_netId, 4U); - m_socket.write(ack, 10U, m_rptAddress, m_rptPort); - } else if (::memcmp(m_buffer, "RPTCL", 5U) == 0) { - ::LogMessage("MMDVM Network, The connected MMDVM is closing down"); - } else if (::memcmp(m_buffer, "RPTC", 4U) == 0) { - m_configLen = length - 8U; - m_configData = new unsigned char[m_configLen]; - ::memcpy(m_configData, m_buffer + 8U, m_configLen); - - unsigned char ack[10U]; - ::memcpy(ack + 0U, "RPTACK", 6U); - ::memcpy(ack + 6U, m_netId, 4U); - m_socket.write(ack, 10U, m_rptAddress, m_rptPort); - } else if (::memcmp(m_buffer, "RPTO", 4U) == 0) { - m_options = std::string((char*)(m_buffer + 8U), length - 8U); - - unsigned char ack[10U]; - ::memcpy(ack + 0U, "RPTACK", 6U); - ::memcpy(ack + 6U, m_netId, 4U); - m_socket.write(ack, 10U, m_rptAddress, m_rptPort); - } else if (::memcmp(m_buffer, "RPTPING", 7U) == 0) { - unsigned char pong[11U]; - ::memcpy(pong + 0U, "MSTPONG", 7U); - ::memcpy(pong + 7U, m_netId, 4U); - m_socket.write(pong, 11U, m_rptAddress, m_rptPort); - } else { - CUtils::dump("Unknown packet from the master", m_buffer, length); - } + m_socket.write((unsigned char*)"DMRP", 4U, m_rptAddress, m_rptPort); + } else { + CUtils::dump("Unknown packet from the MMDVM", m_buffer, length); } } diff --git a/MMDVMNetwork.h b/MMDVMNetwork.h index 39320c8..e9b1f93 100644 --- a/MMDVMNetwork.h +++ b/MMDVMNetwork.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015,2016,2017,2018 by Jonathan Naylor G4KLX + * Copyright (C) 2015,2016,2017,2018,2020 by Jonathan Naylor G4KLX * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,7 +19,6 @@ #if !defined(MMDVMNetwork_H) #define MMDVMNetwork_H -#include "RepeaterProtocol.h" #include "UDPSocket.h" #include "Timer.h" #include "RingBuffer.h" @@ -28,35 +27,31 @@ #include #include -class CMMDVMNetwork : public IRepeaterProtocol +class CMMDVMNetwork { public: CMMDVMNetwork(const std::string& rptAddress, unsigned int rptPort, const std::string& localAddress, unsigned int localPort, bool debug); - virtual ~CMMDVMNetwork(); + ~CMMDVMNetwork(); - virtual std::string getOptions() const; + unsigned int getShortConfig(unsigned char* config) const; - virtual unsigned int getConfig(unsigned char* config) const; + unsigned int getId() const; - virtual unsigned int getId() const; + bool open(); - virtual bool open(); + bool read(CDMRData& data); - virtual bool read(CDMRData& data); + bool write(const CDMRData& data); - virtual bool write(const CDMRData& data); + bool readRadioPosition(unsigned char* data, unsigned int& length); - virtual bool readRadioPosition(unsigned char* data, unsigned int& length); + bool readTalkerAlias(unsigned char* data, unsigned int& length); - virtual bool readTalkerAlias(unsigned char* data, unsigned int& length); + bool writeBeacon(); - virtual bool readHomePosition(unsigned char* data, unsigned int& length); + void clock(unsigned int ms); - virtual bool writeBeacon(); - - virtual void clock(unsigned int ms); - - virtual void close(); + void close(); private: in_addr m_rptAddress; @@ -67,15 +62,12 @@ private: CUDPSocket m_socket; unsigned char* m_buffer; CRingBuffer m_rxData; - std::string m_options; unsigned char* m_configData; unsigned int m_configLen; unsigned char* m_radioPositionData; unsigned int m_radioPositionLen; unsigned char* m_talkerAliasData; unsigned int m_talkerAliasLen; - unsigned char* m_homePositionData; - unsigned int m_homePositionLen; }; #endif diff --git a/Makefile b/Makefile index 148d8bb..1ff39f3 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,20 @@ CC = gcc CXX = g++ + +# Use the following CFLAGS and LIBS if you don't want to use gpsd. CFLAGS = -g -O3 -Wall -std=c++0x -pthread LIBS = -lpthread + +# Use the following CFLAGS and LIBS if you do want to use gpsd. +#CFLAGS = -g -O3 -Wall -DUSE_GPSD -std=c++0x -pthread +#LIBS = -lpthread -lgps + LDFLAGS = -g OBJECTS = BPTC19696.o Conf.o CRC.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREmbeddedData.o DMREMB.o DMRFullLC.o DMRGateway.o DMRLC.o DMRNetwork.o DMRSlotType.o \ - DynVoice.o Golay2087.o Hamming.o Log.o MMDVMNetwork.o PassAllPC.o PassAllTG.o QR1676.o Reflectors.o RepeaterProtocol.o Rewrite.o RewriteDstId.o \ - RewriteDynTGNet.o RewriteDynTGRF.o RewritePC.o RewriteSrc.o RewriteSrcId.o RewriteTG.o RewriteType.o RS129.o SHA256.o StopWatch.o Sync.o Thread.o \ - Timer.o UDPSocket.o Utils.o XLXVoice.o + DynVoice.o Golay2087.o GPSD.o Hamming.o Log.o MMDVMNetwork.o PassAllPC.o PassAllTG.o QR1676.o Reflectors.o Rewrite.o \ + RewriteDstId.o RewriteDynTGNet.o RewriteDynTGRF.o RewritePC.o RewriteSrc.o RewriteSrcId.o RewriteTG.o RewriteType.o RS129.o SHA256.o StopWatch.o Sync.o \ + Thread.o Timer.o UDPSocket.o Utils.o XLXVoice.o all: DMRGateway diff --git a/RepeaterProtocol.cpp b/RepeaterProtocol.cpp deleted file mode 100644 index d49eb62..0000000 --- a/RepeaterProtocol.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* -* Copyright (C) 2017 by Jonathan Naylor G4KLX -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#include "RepeaterProtocol.h" - -IRepeaterProtocol::~IRepeaterProtocol() -{ -} diff --git a/RepeaterProtocol.h b/RepeaterProtocol.h deleted file mode 100644 index 9e52a40..0000000 --- a/RepeaterProtocol.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -* Copyright (C) 2017,2018 by Jonathan Naylor G4KLX -* -* This program is free software; you can redistribute it and/or modify -* it under the terms of the GNU General Public License as published by -* the Free Software Foundation; either version 2 of the License, or -* (at your option) any later version. -* -* This program is distributed in the hope that it will be useful, -* but WITHOUT ANY WARRANTY; without even the implied warranty of -* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -* GNU General Public License for more details. -* -* You should have received a copy of the GNU General Public License -* along with this program; if not, write to the Free Software -* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*/ - -#if !defined(RepeaterProtocol_H) -#define RepeaterProtocol_H - -#include "DMRData.h" - -#include - -class IRepeaterProtocol { -public: - virtual ~IRepeaterProtocol() = 0; - - virtual std::string getOptions() const = 0; - - virtual unsigned int getConfig(unsigned char* config) const = 0; - - virtual unsigned int getId() const = 0; - - virtual bool open() = 0; - - virtual bool read(CDMRData& data) = 0; - - virtual bool write(const CDMRData& data) = 0; - - virtual bool readRadioPosition(unsigned char* data, unsigned int& length) = 0; - - virtual bool readTalkerAlias(unsigned char* data, unsigned int& length) = 0; - - virtual bool readHomePosition(unsigned char* data, unsigned int& length) = 0; - - virtual void clock(unsigned int ms) = 0; - - virtual bool writeBeacon() = 0; - - virtual void close() = 0; - -private: -}; - -#endif diff --git a/RewriteType.cpp b/RewriteType.cpp index 0ceb1da..f7c7d8a 100644 --- a/RewriteType.cpp +++ b/RewriteType.cpp @@ -75,9 +75,9 @@ PROCESS_RESULT CRewriteType::process(CDMRData& data, bool trace) else LogDebug("Rule Trace,\tRewriteType from \"%s\" Slot=%u Dst=TG%u-%u: not matched", m_name.c_str(), m_fromSlot, m_fromTGStart, m_fromTGEnd); if (m_toIdStart == m_toIdEnd) - LogDebug("Rule Trace,\tRewriteType to \"\%s\" Slot=%u Dst=%u: matched", m_name.c_str(), m_toSlot, m_toIdStart); + LogDebug("Rule Trace,\tRewriteType to \"%s\" Slot=%u Dst=%u: matched", m_name.c_str(), m_toSlot, m_toIdStart); else - LogDebug("Rule Trace,\tRewriteType to \"\%s\" Slot=%u Dst=%u-%u: matched", m_name.c_str(), m_toSlot, m_toIdStart, m_toIdEnd); + LogDebug("Rule Trace,\tRewriteType to \"%s\" Slot=%u Dst=%u-%u: matched", m_name.c_str(), m_toSlot, m_toIdStart, m_toIdEnd); } return RESULT_MATCHED; diff --git a/Version.h b/Version.h index aa4c644..426bd2a 100644 --- a/Version.h +++ b/Version.h @@ -19,6 +19,6 @@ #if !defined(VERSION_H) #define VERSION_H -const char* VERSION = "20200421"; +const char* VERSION = "20200826"; #endif