From 4f9f30b678951b687e1ddb24b820adb35fa27606 Mon Sep 17 00:00:00 2001 From: Daniel Caujolle-Bert Date: Thu, 17 Feb 2022 09:36:23 +0000 Subject: [PATCH] Fix: XLX ID as 3 characters string instead of a number. * Since some XLX reflectors are using characters instead of numbers (like USA,JPN,etc...), it's not possible to use them as startup reflector. * Of course, it's still not possible to switch to that kind of reflector using the xlxBase + 4000 trick. Update Copyright year. --- Conf.cpp | 17 +++++++++++++---- Conf.h | 4 ++-- DMRGateway.cpp | 52 +++++++++++++++++++++++++++----------------------- DMRGateway.h | 6 +++--- Reflectors.cpp | 6 +++--- Reflectors.h | 10 +++++----- XLXVoice.cpp | 11 ++++------- XLXVoice.h | 2 +- 8 files changed, 59 insertions(+), 49 deletions(-) diff --git a/Conf.cpp b/Conf.cpp index 57b177e..5bb71e8 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -169,7 +169,7 @@ m_xlxNetworkLocal(0U), m_xlxNetworkSlot(1U), m_xlxNetworkTG(8U), m_xlxNetworkBase(84000U), -m_xlxNetworkStartup(4000U), +m_xlxNetworkStartup("4000"), m_xlxNetworkRelink(0U), m_xlxNetworkDebug(false), m_xlxNetworkUserControl(true), @@ -342,8 +342,17 @@ bool CConf::read() m_xlxNetworkTG = (unsigned int)::atoi(value); else if (::strcmp(key, "Base") == 0) m_xlxNetworkBase = (unsigned int)::atoi(value); - else if (::strcmp(key, "Startup") == 0) - m_xlxNetworkStartup = (unsigned int)::atoi(value); + else if (::strcmp(key, "Startup") == 0) { + char buffer[16]; + char *p = buffer; + + // Right align, then pads with zeros, as XLX IDs are 3 characters length + snprintf(buffer, sizeof(buffer), "%3s", value); + while ((*p != '\0') && (*p == ' ')) + *p++ = '0'; + + m_xlxNetworkStartup = std::string(buffer); + } else if (::strcmp(key, "Relink") == 0) m_xlxNetworkRelink = (unsigned int)::atoi(value); else if (::strcmp(key, "Debug") == 0) @@ -1165,7 +1174,7 @@ unsigned int CConf::getXLXNetworkBase() const return m_xlxNetworkBase; } -unsigned int CConf::getXLXNetworkStartup() const +std::string CConf::getXLXNetworkStartup() const { return m_xlxNetworkStartup; } diff --git a/Conf.h b/Conf.h index 40d403e..388fe4b 100644 --- a/Conf.h +++ b/Conf.h @@ -219,7 +219,7 @@ public: unsigned int getXLXNetworkSlot() const; unsigned int getXLXNetworkTG() const; unsigned int getXLXNetworkBase() const; - unsigned int getXLXNetworkStartup() const; + std::string getXLXNetworkStartup() const; unsigned int getXLXNetworkRelink() const; bool getXLXNetworkDebug() const; bool getXLXNetworkUserControl() const; @@ -380,7 +380,7 @@ private: unsigned int m_xlxNetworkSlot; unsigned int m_xlxNetworkTG; unsigned int m_xlxNetworkBase; - unsigned int m_xlxNetworkStartup; + std::string m_xlxNetworkStartup; unsigned int m_xlxNetworkRelink; bool m_xlxNetworkDebug; bool m_xlxNetworkUserControl; diff --git a/DMRGateway.cpp b/DMRGateway.cpp index a1813fc..c516c98 100644 --- a/DMRGateway.cpp +++ b/DMRGateway.cpp @@ -70,7 +70,7 @@ static void sigHandler(int signum) 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."; -const char* HEADER4 = "Copyright(C) 2017-2020 by Jonathan Naylor, G4KLX and others"; +const char* HEADER4 = "Copyright(C) 2017-2022 by Jonathan Naylor, G4KLX and others"; int main(int argc, char** argv) { @@ -141,7 +141,7 @@ m_dmr5Name(), m_xlxReflectors(NULL), m_xlxNetwork(NULL), m_xlxId(0U), -m_xlxNumber(0U), +m_xlxNumber("000"), m_xlxReflector(4000U), m_xlxSlot(0U), m_xlxTG(0U), @@ -149,7 +149,7 @@ m_xlxBase(0U), m_xlxLocal(0U), m_xlxPort(62030U), m_xlxPassword("passw0rd"), -m_xlxStartup(950U), +m_xlxStartup("950"), m_xlxRoom(4000U), m_xlxRelink(1000U), m_xlxConnected(false), @@ -548,13 +548,13 @@ int CDMRGateway::run() if (m_xlxReflector >= 4001U && m_xlxReflector <= 4026U) { writeXLXLink(m_xlxId, m_xlxReflector, m_xlxNetwork); char c = ('A' + (m_xlxReflector % 100U)) - 1U; - LogMessage("XLX, Linking to reflector XLX%03u %c", m_xlxNumber, c); + LogMessage("XLX, Linking to reflector XLX%s %c", m_xlxNumber.c_str(), c); if (m_xlxVoice != NULL) m_xlxVoice->linkedTo(m_xlxNumber, m_xlxReflector); } else if (m_xlxRoom >= 4001U && m_xlxRoom <= 4026U) { writeXLXLink(m_xlxId, m_xlxRoom, m_xlxNetwork); char c = ('A' + (m_xlxRoom % 100U)) - 1U; - LogMessage("XLX, Linking to reflector XLX%03u %c", m_xlxNumber, c); + LogMessage("XLX, Linking to reflector XLX%s %c", m_xlxNumber.c_str(), c); if (m_xlxVoice != NULL) m_xlxVoice->linkedTo(m_xlxNumber, m_xlxRoom); m_xlxReflector = m_xlxRoom; @@ -570,7 +570,7 @@ int CDMRGateway::run() else m_xlxRelink.start(); } else if (!connected && m_xlxConnected) { - LogMessage("XLX, Unlinking from XLX%03u due to loss of connection", m_xlxNumber); + LogMessage("XLX, Unlinking from XLX%s due to loss of connection", m_xlxNumber.c_str()); if (m_xlxVoice != NULL) m_xlxVoice->unlinked(); @@ -581,13 +581,13 @@ int CDMRGateway::run() m_xlxRelink.stop(); if (m_xlxNumber != m_xlxStartup) { - if (m_xlxStartup > 0U) { + if (m_xlxStartup != "4000") { m_xlxReflector = 4000U; 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); + LogMessage("XLX, Re-linking to startup reflector XLX%s %c due to RF inactivity timeout", m_xlxNumber.c_str(), c); linkXLX(m_xlxStartup); } else { - LogMessage("XLX, Unlinking from XLX%03u due to RF inactivity timeout", m_xlxNumber); + LogMessage("XLX, Unlinking from XLX%s due to RF inactivity timeout", m_xlxNumber.c_str()); unlinkXLX(); } } else { @@ -597,10 +597,10 @@ int CDMRGateway::run() if (m_xlxRoom >= 4001U && m_xlxRoom <= 4026U) { writeXLXLink(m_xlxId, m_xlxRoom, m_xlxNetwork); 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); + LogMessage("XLX, Re-linking to startup reflector XLX%s %c due to RF inactivity timeout", m_xlxNumber.c_str(), c); } else if (m_xlxReflector >= 4001U && m_xlxReflector <= 4026U) { char c = ('A' + (m_xlxReflector % 100U)) - 1U; - LogMessage("XLX, Unlinking from reflector XLX%03u %c due to RF inactivity timeout", m_xlxNumber, c); + LogMessage("XLX, Unlinking from reflector XLX%s %c due to RF inactivity timeout", m_xlxNumber.c_str(), c); } m_xlxReflector = m_xlxRoom; @@ -643,14 +643,14 @@ int CDMRGateway::run() writeXLXLink(srcId, 4000U, m_xlxNetwork); m_xlxReflector = 4000U; char c = ('A' + (m_xlxRoom % 100U)) - 1U; - LogMessage("XLX, Unlinking from reflector XLX%03u %c", m_xlxNumber, c); + LogMessage("XLX, Unlinking from reflector XLX%s %c", m_xlxNumber.c_str(), c); } else if (dstId != 5000U) { if (m_xlxReflector != 4000U) writeXLXLink(srcId, 4000U, m_xlxNetwork); writeXLXLink(srcId, dstId, m_xlxNetwork); m_xlxReflector = dstId; char c = ('A' + (dstId % 100U)) - 1U; - LogMessage("XLX, Linking to reflector XLX%03u %c", m_xlxNumber, c); + LogMessage("XLX, Linking to reflector XLX%s %c", m_xlxNumber.c_str(), c); } if (m_xlxReflector != m_xlxRoom) @@ -677,11 +677,15 @@ int CDMRGateway::run() } } } else if (dstId >= (m_xlxBase + 4000U) && dstId < (m_xlxBase + 5000U) && flco == FLCO_USER_USER && slotNo == m_xlxSlot && m_xlxUserControl) { + char dstIdBuf[16]; + dstId -= 4000U; dstId -= m_xlxBase; - if (dstId != m_xlxNumber) - linkXLX(dstId); + // it's all 3 characters IDS, and not digits. + snprintf(dstIdBuf, sizeof(dstIdBuf), "%03u", dstId); + if (std::string(dstIdBuf) != m_xlxNumber) + linkXLX(dstIdBuf); } else { unsigned int slotNo = data.getSlotNo(); unsigned int srcId = data.getSrcId(); @@ -942,7 +946,7 @@ int CDMRGateway::run() unsigned int slotNo = data.getSlotNo(); unsigned int dstId = data.getDstId(); FLCO flco = data.getFLCO(); - LogWarning("XLX%03u, Unexpected data from slot %u %s%u", m_xlxNumber, slotNo, flco == FLCO_GROUP ? "TG" : "", dstId); + LogWarning("XLX%s, Unexpected data from slot %u %s%u", m_xlxNumber.c_str(), slotNo, flco == FLCO_GROUP ? "TG" : "", dstId); } } } @@ -2257,8 +2261,8 @@ bool CDMRGateway::createXLXNetwork() LogInfo(" TG: %u", m_xlxTG); LogInfo(" Base: %u", m_xlxBase); - if (m_xlxStartup > 0U) - LogInfo(" Startup: XLX%03u", m_xlxStartup); + if (m_xlxStartup != "4000") + LogInfo(" Startup: XLX%s", m_xlxStartup.c_str()); if (xlxRelink > 0U) { m_xlxRelink.setTimeout(xlxRelink * 60U); @@ -2273,9 +2277,9 @@ bool CDMRGateway::createXLXNetwork() LogInfo(" User Control: disabled"); if (m_xlxModule != 0U) - LogInfo(" Module: %c", m_xlxModule); + LogInfo(" Module: %c", m_xlxModule); - if (m_xlxStartup > 0U) + if (m_xlxStartup != "4000") linkXLX(m_xlxStartup); m_rptRewrite = new CRewriteTG("XLX", XLX_SLOT, XLX_TG, m_xlxSlot, m_xlxTG, 1U); @@ -2300,14 +2304,14 @@ bool CDMRGateway::createDynamicTGControl() return true; } -bool CDMRGateway::linkXLX(unsigned int number) +bool CDMRGateway::linkXLX(const std::string &number) { CReflector* reflector = m_xlxReflectors->find(number); if (reflector == NULL) return false; if (m_xlxNetwork != NULL) { - LogMessage("XLX, Disconnecting from XLX%03u", m_xlxNumber); + LogMessage("XLX, Disconnecting from XLX%s", m_xlxNumber.c_str()); m_xlxNetwork->close(true); delete m_xlxNetwork; } @@ -2335,7 +2339,7 @@ bool CDMRGateway::linkXLX(unsigned int number) m_xlxRoom = reflector->m_startup; m_xlxReflector = 4000U; - LogMessage("XLX, Connecting to XLX%03u", m_xlxNumber); + LogMessage("XLX, Connecting to XLX%s", m_xlxNumber.c_str()); m_xlxNetwork->enable(m_networkXlxEnabled); @@ -2678,7 +2682,7 @@ void CDMRGateway::buildNetworkHostNetworkString(std::string &str, const std::str { if (network && (network == m_xlxNetwork)) { std::string module = ((m_xlxReflector >= 4001U && m_xlxReflector <= 4026U) ? ("_" + std::string(1, (('A' + (m_xlxReflector % 100U)) - 1U))) : ""); - str += name + ":\"XLX" + std::to_string(m_xlxNumber) + module + "\""; + str += name + ":\"XLX" + m_xlxNumber + module + "\""; } else { std::string host = ((network == NULL) ? "NONE" : network->getName()); str += name + ":\""+ ((network == NULL) ? "NONE" : ((host.length() > 0) ? host : "NONE")) + "\""; diff --git a/DMRGateway.h b/DMRGateway.h index 9fbce2f..93bd330 100644 --- a/DMRGateway.h +++ b/DMRGateway.h @@ -77,7 +77,7 @@ private: CReflectors* m_xlxReflectors; CDMRNetwork* m_xlxNetwork; unsigned int m_xlxId; - unsigned int m_xlxNumber; + std::string m_xlxNumber; unsigned int m_xlxReflector; unsigned int m_xlxSlot; unsigned int m_xlxTG; @@ -85,7 +85,7 @@ private: unsigned short m_xlxLocal; unsigned short m_xlxPort; std::string m_xlxPassword; - unsigned int m_xlxStartup; + std::string m_xlxStartup; unsigned int m_xlxRoom; CTimer m_xlxRelink; bool m_xlxConnected; @@ -142,7 +142,7 @@ private: bool createXLXNetwork(); bool createDynamicTGControl(); - bool linkXLX(unsigned int number); + bool linkXLX(const std::string &number); void unlinkXLX(); void writeXLXLink(unsigned int srcId, unsigned int dstId, CDMRNetwork* network); diff --git a/Reflectors.cpp b/Reflectors.cpp index 308ccf5..065de97 100644 --- a/Reflectors.cpp +++ b/Reflectors.cpp @@ -63,7 +63,7 @@ bool CReflectors::load() if (p1 != NULL && p2 != NULL && p3 != NULL) { CReflector* refl = new CReflector; - refl->m_id = (unsigned int)::atoi(p1); + refl->m_id = std::string(p1); refl->m_address = std::string(p2); refl->m_startup = (unsigned int)::atoi(p3); m_reflectors.push_back(refl); @@ -83,14 +83,14 @@ bool CReflectors::load() return true; } -CReflector* CReflectors::find(unsigned int id) +CReflector* CReflectors::find(const std::string &id) { for (std::vector::iterator it = m_reflectors.begin(); it != m_reflectors.end(); ++it) { if (id == (*it)->m_id) return *it; } - LogMessage("Trying to find non existent XLX reflector with an id of %u", id); + LogMessage("Trying to find non existent XLX reflector with an id of %s", id.c_str()); return NULL; } diff --git a/Reflectors.h b/Reflectors.h index fbf4614..ea1cc71 100644 --- a/Reflectors.h +++ b/Reflectors.h @@ -27,13 +27,13 @@ class CReflector { public: CReflector() : - m_id(0U), + m_id("0"), m_address(), m_startup(0U) { } - unsigned int m_id; + std::string m_id; std::string m_address; unsigned int m_startup; }; @@ -45,14 +45,14 @@ public: bool load(); - CReflector* find(unsigned int id); + CReflector* find(const std::string &id); - void clock(unsigned int ms); + void clock(unsigned int ms); private: std::string m_hostsFile; std::vector m_reflectors; - CTimer m_timer; + CTimer m_timer; }; #endif diff --git a/XLXVoice.cpp b/XLXVoice.cpp index 4f1506c..d719d37 100644 --- a/XLXVoice.cpp +++ b/XLXVoice.cpp @@ -130,11 +130,8 @@ bool CXLXVoice::open() return true; } -void CXLXVoice::linkedTo(unsigned int number, unsigned int room) +void CXLXVoice::linkedTo(const std::string &number, unsigned int room) { - char letters[10U]; - ::sprintf(letters, "%03u", number); - std::vector words; if (m_positions.count("linkedto") == 0U) { words.push_back("linked"); @@ -145,9 +142,9 @@ void CXLXVoice::linkedTo(unsigned int number, unsigned int room) words.push_back("X"); words.push_back("L"); words.push_back("X"); - words.push_back(std::string(1U, letters[0U])); - words.push_back(std::string(1U, letters[1U])); - words.push_back(std::string(1U, letters[2U])); + words.push_back(number.substr(0U, 1U)); + words.push_back(number.substr(1U, 1U)); + words.push_back(number.substr(2U, 1U)); // 4001 => 1 => A, 4002 => 2 => B, etc. room %= 100U; diff --git a/XLXVoice.h b/XLXVoice.h index 0a896e5..49e978b 100644 --- a/XLXVoice.h +++ b/XLXVoice.h @@ -47,7 +47,7 @@ public: bool open(); - void linkedTo(unsigned int number, unsigned int room); + void linkedTo(const std::string &number, unsigned int room); void unlinked(); void reset();