mirror of
https://github.com/g4klx/MMDVMHost
synced 2025-12-21 06:55:52 +08:00
Load the DMR Id lookup table periodically.
This commit is contained in:
43
Conf.cpp
43
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<unsigned int> CConf::getDMRBlackList() const
|
||||
{
|
||||
return m_dmrBlackList;
|
||||
}
|
||||
|
||||
std::vector<unsigned int> CConf::getDMRDstIdBlacklistSlot1RF() const
|
||||
{
|
||||
return m_dmrDstIdBlacklistSlot1RF;
|
||||
}
|
||||
|
||||
std::vector<unsigned int> CConf::getDMRDstIdBlacklistSlot2RF() const
|
||||
{
|
||||
return m_dmrDstIdBlacklistSlot2RF;
|
||||
}
|
||||
|
||||
std::vector<unsigned int> CConf::getDMRDstIdWhitelistSlot1RF() const
|
||||
{
|
||||
return m_dmrDstIdWhitelistSlot1RF;
|
||||
}std::vector<unsigned int> CConf::getDMRDstIdWhitelistSlot2RF() const
|
||||
}
|
||||
|
||||
std::vector<unsigned int> CConf::getDMRDstIdWhitelistSlot2RF() const
|
||||
{
|
||||
return m_dmrDstIdWhitelistSlot2RF;
|
||||
}
|
||||
|
||||
std::vector<unsigned int> CConf::getDMRDstIdBlacklistSlot1NET() const
|
||||
{
|
||||
return m_dmrDstIdBlacklistSlot1NET;
|
||||
}
|
||||
|
||||
std::vector<unsigned int> CConf::getDMRDstIdBlacklistSlot2NET() const
|
||||
{
|
||||
return m_dmrDstIdBlacklistSlot2NET;
|
||||
}
|
||||
|
||||
std::vector<unsigned int> CConf::getDMRDstIdWhitelistSlot1NET() const
|
||||
{
|
||||
return m_dmrDstIdWhitelistSlot1NET;
|
||||
}std::vector<unsigned int> CConf::getDMRDstIdWhitelistSlot2NET() const
|
||||
}
|
||||
|
||||
std::vector<unsigned int> CConf::getDMRDstIdWhitelistSlot2NET() const
|
||||
{
|
||||
return m_dmrDstIdWhitelistSlot2NET;
|
||||
}
|
||||
std::string CConf::getDMRLookupFile() const
|
||||
{
|
||||
return m_dmrLookupFile;
|
||||
}
|
||||
|
||||
unsigned int CConf::getDMRCallHang() const
|
||||
{
|
||||
|
||||
10
Conf.h
10
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<unsigned int> getDMRDstIdBlacklistSlot2NET() const;
|
||||
std::vector<unsigned int> getDMRDstIdWhitelistSlot1NET() const;
|
||||
std::vector<unsigned int> 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<unsigned int> m_dmrPrefixes;
|
||||
std::vector<unsigned int> m_dmrBlackList;
|
||||
std::vector<unsigned int> m_dmrDstIdBlacklistSlot1RF;
|
||||
@@ -248,7 +253,6 @@ private:
|
||||
std::vector<unsigned int> m_dmrDstIdBlacklistSlot2NET;
|
||||
std::vector<unsigned int> m_dmrDstIdWhitelistSlot1NET;
|
||||
std::vector<unsigned int> m_dmrDstIdWhitelistSlot2NET;
|
||||
std::string m_dmrLookupFile;
|
||||
unsigned int m_dmrCallHang;
|
||||
unsigned int m_dmrTXHang;
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
*/
|
||||
|
||||
#include "DMRLookup.h"
|
||||
#include "Timer.h"
|
||||
#include "Log.h"
|
||||
|
||||
#include <cstdio>
|
||||
@@ -24,8 +25,13 @@
|
||||
#include <cstring>
|
||||
#include <cctype>
|
||||
|
||||
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();
|
||||
@@ -68,21 +145,3 @@ bool CDMRLookup::read()
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
20
DMRLookup.h
20
DMRLookup.h
@@ -19,21 +19,33 @@
|
||||
#ifndef DMRLookup_H
|
||||
#define DMRLookup_H
|
||||
|
||||
#include "Thread.h"
|
||||
#include "Mutex.h"
|
||||
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
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<unsigned int, std::string> m_table;
|
||||
CMutex m_mutex;
|
||||
bool m_stop;
|
||||
|
||||
bool load();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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=
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user