From 40c086bad8ffe6f1146236cb7be2f0e638549de5 Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 10 Oct 2016 19:15:30 +0100 Subject: [PATCH] Load the DMR Id lookup table periodically. --- Conf.cpp | 43 ++++++++++++++++----- Conf.h | 10 +++-- DMRLookup.cpp | 101 +++++++++++++++++++++++++++++++++++++++----------- DMRLookup.h | 20 ++++++++-- MMDVM.ini | 5 ++- MMDVMHost.cpp | 23 ++++++++---- MMDVMHost.h | 2 + 7 files changed, 157 insertions(+), 47 deletions(-) diff --git a/Conf.cpp b/Conf.cpp index 7a00eae..f79a82b 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -33,6 +33,7 @@ enum SECTION { SECTION_INFO, SECTION_LOG, SECTION_CWID, + SECTION_DMRID_LOOKUP, SECTION_MODEM, SECTION_DSTAR, SECTION_DMR, @@ -73,6 +74,8 @@ m_logFilePath(), m_logFileRoot(), m_cwIdEnabled(false), m_cwIdTime(10U), +m_dmrIdLookupFile(), +m_dmrIdLookupTime(0U), m_modemPort(), m_modemRXInvert(false), m_modemTXInvert(false), @@ -112,7 +115,6 @@ m_dmrDstIdBlacklistSlot1NET(), m_dmrDstIdBlacklistSlot2NET(), m_dmrDstIdWhitelistSlot1NET(), m_dmrDstIdWhitelistSlot2NET(), -m_dmrLookupFile(), m_dmrCallHang(3U), m_dmrTXHang(4U), m_fusionEnabled(false), @@ -196,6 +198,8 @@ bool CConf::read() section = SECTION_LOG; else if (::strncmp(buffer, "[CW Id]", 7U) == 0) section = SECTION_CWID; + else if (::strncmp(buffer, "[DMR Id Lookup]", 15U) == 0) + section = SECTION_DMRID_LOOKUP; else if (::strncmp(buffer, "[Modem]", 7U) == 0) section = SECTION_MODEM; else if (::strncmp(buffer, "[D-Star]", 8U) == 0) @@ -287,6 +291,11 @@ bool CConf::read() m_cwIdEnabled = ::atoi(value) == 1; else if (::strcmp(key, "Time") == 0) m_cwIdTime = (unsigned int)::atoi(value); + } else if (section == SECTION_DMRID_LOOKUP) { + if (::strcmp(key, "File") == 0) + m_dmrIdLookupFile = value; + else if (::strcmp(key, "Time") == 0) + m_dmrIdLookupTime = (unsigned int)::atoi(value); } else if (section == SECTION_MODEM) { if (::strcmp(key, "Port") == 0) m_modemPort = value; @@ -436,9 +445,7 @@ bool CConf::read() m_dmrDstIdWhitelistSlot2NET.push_back(id); p = ::strtok(NULL, ",\r\n"); } - } else if (::strcmp(key, "LookupFile") == 0) - m_dmrLookupFile = value; - else if (::strcmp(key, "TXHang") == 0) + } else if (::strcmp(key, "TXHang") == 0) m_dmrTXHang = (unsigned int)::atoi(value); else if (::strcmp(key, "CallHang") == 0) m_dmrCallHang = (unsigned int)::atoi(value); @@ -686,6 +693,16 @@ unsigned int CConf::getCWIdTime() const return m_cwIdTime; } +std::string CConf::getDMRIdLookupFile() const +{ + return m_dmrIdLookupFile; +} + +unsigned int CConf::getDMRIdLookupTime() const +{ + return m_dmrIdLookupTime; +} + std::string CConf::getModemPort() const { return m_modemPort; @@ -840,40 +857,46 @@ std::vector CConf::getDMRBlackList() const { return m_dmrBlackList; } + std::vector CConf::getDMRDstIdBlacklistSlot1RF() const { return m_dmrDstIdBlacklistSlot1RF; } + std::vector CConf::getDMRDstIdBlacklistSlot2RF() const { return m_dmrDstIdBlacklistSlot2RF; } + std::vector CConf::getDMRDstIdWhitelistSlot1RF() const { return m_dmrDstIdWhitelistSlot1RF; -}std::vector CConf::getDMRDstIdWhitelistSlot2RF() const +} + +std::vector CConf::getDMRDstIdWhitelistSlot2RF() const { return m_dmrDstIdWhitelistSlot2RF; } + std::vector CConf::getDMRDstIdBlacklistSlot1NET() const { return m_dmrDstIdBlacklistSlot1NET; } + std::vector CConf::getDMRDstIdBlacklistSlot2NET() const { return m_dmrDstIdBlacklistSlot2NET; } + std::vector CConf::getDMRDstIdWhitelistSlot1NET() const { return m_dmrDstIdWhitelistSlot1NET; -}std::vector CConf::getDMRDstIdWhitelistSlot2NET() const +} + +std::vector CConf::getDMRDstIdWhitelistSlot2NET() const { return m_dmrDstIdWhitelistSlot2NET; } -std::string CConf::getDMRLookupFile() const -{ - return m_dmrLookupFile; -} unsigned int CConf::getDMRCallHang() const { diff --git a/Conf.h b/Conf.h index e3efdf4..aad2e5b 100644 --- a/Conf.h +++ b/Conf.h @@ -60,6 +60,10 @@ public: bool getCWIdEnabled() const; unsigned int getCWIdTime() const; + // The DMR Id section + std::string getDMRIdLookupFile() const; + unsigned int getDMRIdLookupTime() const; + // The Modem section std::string getModemPort() const; bool getModemRXInvert() const; @@ -104,7 +108,6 @@ public: std::vector getDMRDstIdBlacklistSlot2NET() const; std::vector getDMRDstIdWhitelistSlot1NET() const; std::vector getDMRDstIdWhitelistSlot2NET() const; - std::string getDMRLookupFile() const; unsigned int getDMRCallHang() const; unsigned int getDMRTXHang() const; @@ -206,6 +209,9 @@ private: bool m_cwIdEnabled; unsigned int m_cwIdTime; + std::string m_dmrIdLookupFile; + unsigned int m_dmrIdLookupTime; + std::string m_modemPort; bool m_modemRXInvert; bool m_modemTXInvert; @@ -237,7 +243,6 @@ private: bool m_dmrTGRewriteSlot2; bool m_dmrBMAutoRewrite; bool m_dmrBMRewriteReflectorVoicePrompts; - std::vector m_dmrPrefixes; std::vector m_dmrBlackList; std::vector m_dmrDstIdBlacklistSlot1RF; @@ -248,7 +253,6 @@ private: std::vector m_dmrDstIdBlacklistSlot2NET; std::vector m_dmrDstIdWhitelistSlot1NET; std::vector m_dmrDstIdWhitelistSlot2NET; - std::string m_dmrLookupFile; unsigned int m_dmrCallHang; unsigned int m_dmrTXHang; diff --git a/DMRLookup.cpp b/DMRLookup.cpp index a77b053..418c3e6 100644 --- a/DMRLookup.cpp +++ b/DMRLookup.cpp @@ -17,6 +17,7 @@ */ #include "DMRLookup.h" +#include "Timer.h" #include "Log.h" #include @@ -24,8 +25,13 @@ #include #include -CDMRLookup::CDMRLookup(const std::string& filename) : -m_filename(filename) +CDMRLookup::CDMRLookup(const std::string& filename, unsigned int reloadTime) : +CThread(), +m_filename(filename), +m_reloadTime(reloadTime), +m_table(), +m_mutex(), +m_stop(false) { } @@ -34,6 +40,70 @@ CDMRLookup::~CDMRLookup() } bool CDMRLookup::read() +{ + bool ret = load(); + + if (m_reloadTime > 0U) + run(); + + return ret; +} + +void CDMRLookup::entry() +{ + LogInfo("Started the DMR Id lookup reload thread"); + + CTimer timer(1U, 3600U * m_reloadTime); + timer.start(); + + while (!m_stop) { + sleep(1000U); + + timer.clock(); + if (timer.hasExpired()) { + load(); + timer.start(); + } + } + + LogInfo("Stopped the DMR Id lookup reload thread"); +} + +void CDMRLookup::stop() +{ + if (m_reloadTime == 0U) { + delete this; + return; + } + + m_stop = true; + + wait(); +} + +std::string CDMRLookup::find(unsigned int id) +{ + std::string callsign; + + if (id == 0xFFFFFFU) + return std::string("ALL"); + + m_mutex.lock(); + + try { + callsign = m_table.at(id); + } catch (...) { + char text[10U]; + ::sprintf(text, "%u", id); + callsign = std::string(text); + } + + m_mutex.unlock(); + + return callsign; +} + +bool CDMRLookup::load() { FILE* fp = ::fopen(m_filename.c_str(), "rt"); if (fp == NULL) { @@ -41,6 +111,11 @@ bool CDMRLookup::read() return false; } + m_mutex.lock(); + + // Remove the old entries + m_table.clear(); + char buffer[100U]; while (::fgets(buffer, 100U, fp) != NULL) { if (buffer[0U] == '#') @@ -58,6 +133,8 @@ bool CDMRLookup::read() } } + m_mutex.unlock(); + ::fclose(fp); size_t size = m_table.size(); @@ -67,22 +144,4 @@ bool CDMRLookup::read() LogInfo("Loaded %u Ids to the callsign lookup table", size); return true; -} - -std::string CDMRLookup::find(unsigned int id) const -{ - std::string callsign; - - if (id == 0xFFFFFFU) - return std::string("ALL"); - - try { - callsign = m_table.at(id); - } catch (...) { - char text[10U]; - ::sprintf(text, "%u", id); - callsign = std::string(text); - } - - return callsign; -} +} \ No newline at end of file diff --git a/DMRLookup.h b/DMRLookup.h index 0403154..6cb3cda 100644 --- a/DMRLookup.h +++ b/DMRLookup.h @@ -19,21 +19,33 @@ #ifndef DMRLookup_H #define DMRLookup_H +#include "Thread.h" +#include "Mutex.h" + #include #include -class CDMRLookup { +class CDMRLookup : public CThread { public: - CDMRLookup(const std::string& filename); - ~CDMRLookup(); + CDMRLookup(const std::string& filename, unsigned int reloadTime); + virtual ~CDMRLookup(); bool read(); - std::string find(unsigned int id) const; + virtual void entry(); + + std::string find(unsigned int id); + + void stop(); private: std::string m_filename; + unsigned int m_reloadTime; std::unordered_map m_table; + CMutex m_mutex; + bool m_stop; + + bool load(); }; #endif diff --git a/MMDVM.ini b/MMDVM.ini index af9556e..8b3fe06 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -30,6 +30,10 @@ FileRoot=MMDVM Enable=1 Time=10 +[DMR Id Lookup] +File=DMRIds.dat +Time=24 + [Modem] # Port=/dev/ttyACM0 Port=\\.\COM3 @@ -62,7 +66,6 @@ Id=123456 ColorCode=1 SelfOnly=0 # Prefixes=234,235 -LookupFile=DMRIds.dat CallHang=3 TXHang=4 #Blacklist= diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index cc8afb4..d579a99 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -24,7 +24,6 @@ #include "Defines.h" #include "DStarControl.h" #include "DMRControl.h" -#include "DMRLookup.h" #include "TFTSerial.h" #include "NullDisplay.h" #include "YSFControl.h" @@ -139,6 +138,7 @@ m_dstarEnabled(false), m_dmrEnabled(false), m_ysfEnabled(false), m_p25Enabled(false), +m_lookup(NULL), m_callsign() { } @@ -278,13 +278,17 @@ int CMMDVMHost::run() bool dmrBeaconsEnabled = m_dmrEnabled && m_conf.getDMRBeacons(); // For DMR and P25 we try to map IDs to callsigns - CDMRLookup* lookup = NULL; if (m_dmrEnabled || m_p25Enabled) { - std::string lookupFile = m_conf.getDMRLookupFile(); - LogInfo("ID lookup File: %s", lookupFile.length() > 0U ? lookupFile.c_str() : "None"); + std::string lookupFile = m_conf.getDMRIdLookupFile(); + unsigned int reloadTime = m_conf.getDMRIdLookupTime(); - lookup = new CDMRLookup(lookupFile); - lookup->read(); + LogInfo("DMR Id Lookups"); + LogInfo(" File: %s", lookupFile.length() > 0U ? lookupFile.c_str() : "None"); + if (reloadTime > 0U) + LogInfo(" Reload: %u hours", reloadTime); + + m_lookup = new CDMRLookup(lookupFile, reloadTime); + m_lookup->read(); } CStopWatch stopWatch; @@ -382,7 +386,7 @@ int CMMDVMHost::run() if (BMRewriteReflectorVoicePrompts) LogInfo(" BrandMeister Rewrite Reflector Voice Prompts enabled"); - dmr = new CDMRControl(id, colorCode, callHang, selfOnly, prefixes, blackList,dstIDBlackListSlot1RF,dstIDWhiteListSlot1RF, dstIDBlackListSlot2RF, dstIDWhiteListSlot2RF, dstIDBlackListSlot1NET,dstIDWhiteListSlot1NET, dstIDBlackListSlot2NET, dstIDWhiteListSlot2NET, m_timeout, m_modem, m_dmrNetwork, m_display, m_duplex, lookup, rssiMultiplier, rssiOffset, jitter, TGRewriteSlot1, TGRewriteSlot2, BMAutoRewrite, BMRewriteReflectorVoicePrompts); + dmr = new CDMRControl(id, colorCode, callHang, selfOnly, prefixes, blackList,dstIDBlackListSlot1RF,dstIDWhiteListSlot1RF, dstIDBlackListSlot2RF, dstIDWhiteListSlot2RF, dstIDBlackListSlot1NET,dstIDWhiteListSlot1NET, dstIDBlackListSlot2NET, dstIDWhiteListSlot2NET, m_timeout, m_modem, m_dmrNetwork, m_display, m_duplex, m_lookup, rssiMultiplier, rssiOffset, jitter, TGRewriteSlot1, TGRewriteSlot2, BMAutoRewrite, BMRewriteReflectorVoicePrompts); m_dmrTXTimer.setTimeout(txHang); } @@ -404,7 +408,7 @@ int CMMDVMHost::run() LogInfo("P25 Parameters"); LogInfo(" NAC: $%03X", nac); - p25 = new CP25Control(nac, m_p25Network, m_display, m_timeout, m_duplex, lookup); + p25 = new CP25Control(nac, m_p25Network, m_display, m_timeout, m_duplex, m_lookup); } setMode(MODE_IDLE); @@ -724,6 +728,9 @@ int CMMDVMHost::run() m_display->close(); delete m_display; + if (m_lookup != NULL) + m_lookup->stop(); + if (m_dstarNetwork != NULL) { m_dstarNetwork->close(); delete m_dstarNetwork; diff --git a/MMDVMHost.h b/MMDVMHost.h index db92394..b55f22b 100644 --- a/MMDVMHost.h +++ b/MMDVMHost.h @@ -23,6 +23,7 @@ #include "YSFNetwork.h" #include "P25Network.h" #include "DMRNetwork.h" +#include "DMRLookup.h" #include "Display.h" #include "Timer.h" #include "Modem.h" @@ -58,6 +59,7 @@ private: bool m_dmrEnabled; bool m_ysfEnabled; bool m_p25Enabled; + CDMRLookup* m_lookup; std::string m_callsign; void readParams();