From 8ff3913729cd02622afec710d0e3869ecb6d5964 Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Thu, 5 Mar 2020 06:35:14 +0900 Subject: [PATCH 01/17] add user database storage simply added UserDB* source code and modified Makefile. others are untouched. --- Makefile | 2 +- Makefile.Pi | 2 +- Makefile.Pi.Adafruit | 2 +- Makefile.Pi.HD44780 | 2 +- Makefile.Pi.OLED | 2 +- Makefile.Pi.PCF8574 | 2 +- Makefile.Solaris | 2 +- UserDB.cpp | 184 +++++++++++++++++++++++++++++++++++++++++++ UserDB.h | 43 ++++++++++ UserDBentry.cpp | 54 +++++++++++++ UserDBentry.h | 49 ++++++++++++ 11 files changed, 337 insertions(+), 7 deletions(-) create mode 100644 UserDB.cpp create mode 100644 UserDB.h create mode 100644 UserDBentry.cpp create mode 100644 UserDBentry.h diff --git a/Makefile b/Makefile index 9a24d1a..efdaba6 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ OBJECTS = \ NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNLayer3.o NXDNLICH.o \ NXDNLookup.o NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o \ POCSAGControl.o POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o \ - TFTSurenoo.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + TFTSurenoo.o Thread.o Timer.o UDPSocket.o UMP.o UserDB.o UserDBentry.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost RemoteCommand diff --git a/Makefile.Pi b/Makefile.Pi index fe7da05..640c07f 100644 --- a/Makefile.Pi +++ b/Makefile.Pi @@ -13,7 +13,7 @@ OBJECTS = \ NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o \ NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o POCSAGControl.o \ POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o TFTSurenoo.o Thread.o Timer.o \ - UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + UDPSocket.o UMP.o UserDB.o UserDBentry.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost RemoteCommand diff --git a/Makefile.Pi.Adafruit b/Makefile.Pi.Adafruit index 1849e68..24c2907 100644 --- a/Makefile.Pi.Adafruit +++ b/Makefile.Pi.Adafruit @@ -14,7 +14,7 @@ OBJECTS = \ NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o \ NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o POCSAGControl.o \ POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o TFTSurenoo.o Thread.o \ - Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + Timer.o UDPSocket.o UMP.o UserDB.o UserDBentry.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost RemoteCommand diff --git a/Makefile.Pi.HD44780 b/Makefile.Pi.HD44780 index f7c0c31..c2faad2 100644 --- a/Makefile.Pi.HD44780 +++ b/Makefile.Pi.HD44780 @@ -13,7 +13,7 @@ OBJECTS = \ NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o \ NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o POCSAGControl.o \ POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o TFTSurenoo.o Thread.o \ - Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + Timer.o UDPSocket.o UMP.o UserDB.o UserDBentry.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost RemoteCommand diff --git a/Makefile.Pi.OLED b/Makefile.Pi.OLED index d6acd67..d2db40c 100644 --- a/Makefile.Pi.OLED +++ b/Makefile.Pi.OLED @@ -13,7 +13,7 @@ OBJECTS = \ NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o \ NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o POCSAGControl.o \ POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o TFTSurenoo.o Thread.o \ - Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + Timer.o UDPSocket.o UMP.o UserDB.o UserDBentry.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost RemoteCommand diff --git a/Makefile.Pi.PCF8574 b/Makefile.Pi.PCF8574 index c3441c6..4c5d3a3 100644 --- a/Makefile.Pi.PCF8574 +++ b/Makefile.Pi.PCF8574 @@ -14,7 +14,7 @@ OBJECTS = \ NetworkInfo.o Nextion.o NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o \ NXDNNetwork.o NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o POCSAGControl.o \ POCSAGNetwork.o QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o TFTSurenoo.o Thread.o \ - Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + Timer.o UDPSocket.o UMP.o UserDB.o UserDBentry.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost RemoteCommand diff --git a/Makefile.Solaris b/Makefile.Solaris index 1d94eef..c50d41e 100644 --- a/Makefile.Solaris +++ b/Makefile.Solaris @@ -13,7 +13,7 @@ OBJECTS = \ NullDisplay.o NullModem.o NXDNAudio.o NXDNControl.o NXDNConvolution.o NXDNCRC.o NXDNFACCH1.o NXDNLayer3.o NXDNLICH.o NXDNLookup.o NXDNNetwork.o \ NXDNSACCH.o NXDNUDCH.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o P25Network.o P25NID.o P25Trellis.o P25Utils.o POCSAGControl.o POCSAGNetwork.o \ QR1676.o RemoteControl.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o TFTSurenoo.o Thread.o Timer.o UDPSocket.o \ - UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + UMP.o UserDB.o UserDBebtry.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost RemoteCommand diff --git a/UserDB.cpp b/UserDB.cpp new file mode 100644 index 0000000..2e20fb0 --- /dev/null +++ b/UserDB.cpp @@ -0,0 +1,184 @@ +/* + * Copyright (C) 2020 by SASANO Takayoshi JG1UAA + * + * 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 "UserDB.h" +#include "Log.h" + +#include +#include +#include + +CUserDB::CUserDB() : +m_table(), +m_mutex() +{ +} + +CUserDB::~CUserDB() +{ +} + +bool CUserDB::lookup(unsigned int id, class CUserDBentry *entry) +{ + bool rv; + + m_mutex.lock(); + + try { + if (entry != NULL) + *entry = m_table.at(id); + else + m_table.at(id); + + rv = true; + } catch (...) { + rv = false; + } + + m_mutex.unlock(); + + return rv; +} + +bool CUserDB::load(std::string const& filename) +{ + FILE* fp = ::fopen(filename.c_str(), "r"); + if (fp == NULL) { + LogWarning("Cannot open ID lookup table - %s", filename.c_str()); + return false; + } + + m_mutex.lock(); + + // Remove the old entries; + m_table.clear(); + + // set index for entries + char buffer[256U]; + if (::fgets(buffer, sizeof(buffer), fp) == NULL) { + LogWarning("ID lookup file has no entry - %s", filename.c_str()); + m_mutex.unlock(); + ::fclose(fp); + return false; + } + + // no index - set default + std::unordered_map index; + if (!makeindex(buffer, index)) { + ::strncpy(buffer, "RADIO_ID,CALLSIGN,FIRST_NAME", sizeof(buffer)); + makeindex(buffer, index); + ::rewind(fp); + } + + while (::fgets(buffer, sizeof(buffer), fp) != NULL) { + if (buffer[0U] != '#') + parse(buffer, index); + } + + ::fclose(fp); + + size_t size = m_table.size(); + m_mutex.unlock(); + + LogInfo("Loaded %u IDs to lookup table - %s", size, filename.c_str()); + + return (size != 0U); +} + +bool CUserDB::makeindex(char* buf, std::unordered_map& index) +{ + int i; + char *p1, *p2; + + for (i = 0, p1 = tokenize(buf, &p2); p1 != NULL; + i++, p1 = tokenize(p2, &p2)) { + + // create [column keyword] - [column number] table + if (CUserDBentry::isValidKey(p1)) + index[p1] = i; + } + + try { + index.at(keyRADIO_ID); + index.at(keyCALLSIGN); + return true; + } catch (...) { + return false; + } +} + +void CUserDB::parse(char* buf, std::unordered_map& index) +{ + int i; + char *p1, *p2; + std::unordered_map ptr; + unsigned int id; + + for (i = 0, p1 = tokenize(buf, &p2); p1 != NULL; + i++, p1 = tokenize(p2, &p2)) { + + for (auto it = index.begin(); it != index.end(); it++) { + // first: column keyword, second: column number + if (it->second == i) { + ptr[it->first] = p1; + break; + } + } + } + + try { + ptr.at(keyRADIO_ID); + ptr.at(keyCALLSIGN); + } catch (...) { + return; + } + + id = (unsigned int)::atoi(ptr[keyRADIO_ID]); + toupper_string(ptr[keyCALLSIGN]); + + for (auto it = ptr.begin(); it != ptr.end(); it++) { + // no need to regist radio ID + if (it->first == keyRADIO_ID) + continue; + + m_table[id].set(it->first, std::string(it->second)); + } +} + +void CUserDB::toupper_string(char* str) +{ + while (*str != '\0') { + *str = ::toupper(*str); + str++; + } +} + +char* CUserDB::tokenize(char* str, char** next) +{ + if (*str == '\0') + return NULL; + + char* p = ::strpbrk(str, ",\t\r\n"); + if (p == NULL) { + *next = str + ::strlen(str); + } else { + *p = '\0'; + *next = p + 1; + } + + return str; +} diff --git a/UserDB.h b/UserDB.h new file mode 100644 index 0000000..acae103 --- /dev/null +++ b/UserDB.h @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2020 by SASANO Takayoshi JG1UAA + * + * 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(USERDB_H) +#define USERDB_H + +#include "UserDBentry.h" +#include "Mutex.h" + +class CUserDB { +public: + CUserDB(); + ~CUserDB(); + + bool lookup(unsigned int id, class CUserDBentry *entry); + bool load(std::string const& filename); + +private: + bool makeindex(char* buf, std::unordered_map& index); + void parse(char* buf, std::unordered_map& index); + void toupper_string(char* str); + char* tokenize(char* str, char** next); + + std::unordered_map m_table; + CMutex m_mutex; +}; + +#endif diff --git a/UserDBentry.cpp b/UserDBentry.cpp new file mode 100644 index 0000000..5b66c59 --- /dev/null +++ b/UserDBentry.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2020 by SASANO Takayoshi JG1UAA + * + * 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 "UserDBentry.h" +#include + +CUserDBentry::CUserDBentry() : +m_db() +{ +} + +CUserDBentry::~CUserDBentry() +{ +} + +const std::vector CUserDBentry::keyList { + keyRADIO_ID, keyCALLSIGN, keyFIRST_NAME, keyLAST_NAME, + keyCITY, keySTATE, keyCOUNTRY, +}; + +bool CUserDBentry::isValidKey(const std::string key) +{ + auto it = std::find(keyList.begin(), keyList.end(), key); + return it != keyList.end(); +} + +void CUserDBentry::set(const std::string key, const std::string value) +{ + if (isValidKey(key)) + m_db[key] = value; +} + +std::string CUserDBentry::get(const std::string key) +{ + try { + return m_db.at(key); + } catch (...) { + return ""; + } +} diff --git a/UserDBentry.h b/UserDBentry.h new file mode 100644 index 0000000..d44f451 --- /dev/null +++ b/UserDBentry.h @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2020 by SASANO Takayoshi JG1UAA + * + * 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(USERDBENTRY_H) +#define USERDBENTRY_H + +#include +#include +#include + +#define keyRADIO_ID "RADIO_ID" +#define keyCALLSIGN "CALLSIGN" +#define keyFIRST_NAME "FIRST_NAME" +#define keyLAST_NAME "LAST_NAME" +#define keyCITY "CITY" +#define keySTATE "STATE" +#define keyCOUNTRY "COUNTRY" + +class CUserDBentry { +public: + CUserDBentry(); + ~CUserDBentry(); + + static const std::vector keyList; + static bool isValidKey(const std::string key); + + void set(const std::string key, const std::string value); + std::string get(const std::string key); + +private: + std::unordered_map m_db; +}; + +#endif From 92d9973ace2e52819be141d2dacab1d3bcb23ce0 Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Thu, 5 Mar 2020 19:26:02 +0900 Subject: [PATCH 02/17] revise LogWarning message, and cosmetic changes --- UserDB.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/UserDB.cpp b/UserDB.cpp index 2e20fb0..4463f25 100644 --- a/UserDB.cpp +++ b/UserDB.cpp @@ -58,7 +58,7 @@ bool CUserDB::load(std::string const& filename) { FILE* fp = ::fopen(filename.c_str(), "r"); if (fp == NULL) { - LogWarning("Cannot open ID lookup table - %s", filename.c_str()); + LogWarning("Cannot open ID lookup file - %s", filename.c_str()); return false; } @@ -79,7 +79,7 @@ bool CUserDB::load(std::string const& filename) // no index - set default std::unordered_map index; if (!makeindex(buffer, index)) { - ::strncpy(buffer, "RADIO_ID,CALLSIGN,FIRST_NAME", sizeof(buffer)); + ::strncpy(buffer, keyRADIO_ID "," keyCALLSIGN "," keyFIRST_NAME, sizeof(buffer)); makeindex(buffer, index); ::rewind(fp); } @@ -96,7 +96,7 @@ bool CUserDB::load(std::string const& filename) LogInfo("Loaded %u IDs to lookup table - %s", size, filename.c_str()); - return (size != 0U); + return size != 0U; } bool CUserDB::makeindex(char* buf, std::unordered_map& index) From a2911fa5c348de3be0b293853db13330ba06b90e Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Fri, 6 Mar 2020 21:56:00 +0900 Subject: [PATCH 03/17] avoid registing "" string to reduce memory consumption --- UserDBentry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UserDBentry.cpp b/UserDBentry.cpp index 5b66c59..28c4ca5 100644 --- a/UserDBentry.cpp +++ b/UserDBentry.cpp @@ -40,7 +40,7 @@ bool CUserDBentry::isValidKey(const std::string key) void CUserDBentry::set(const std::string key, const std::string value) { - if (isValidKey(key)) + if (!value.empty() && isValidKey(key)) m_db[key] = value; } From 9b15454f96b522de5a7df1f043c6896c7da56af6 Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Sat, 7 Mar 2020 16:44:50 +0900 Subject: [PATCH 04/17] makeindex() needs clear old result, add index.clear() --- UserDB.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/UserDB.cpp b/UserDB.cpp index 4463f25..9d962d7 100644 --- a/UserDB.cpp +++ b/UserDB.cpp @@ -104,6 +104,9 @@ bool CUserDB::makeindex(char* buf, std::unordered_map& index) int i; char *p1, *p2; + // Remove the old index + index.clear(); + for (i = 0, p1 = tokenize(buf, &p2); p1 != NULL; i++, p1 = tokenize(p2, &p2)) { From b7f5fdd8a25647cc913728847cbe988a86c2e2bd Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Sat, 7 Mar 2020 16:52:11 +0900 Subject: [PATCH 05/17] use class UserDB (user-info storage) --- DMRLookup.cpp | 101 ++++++++------------------------------------------ 1 file changed, 16 insertions(+), 85 deletions(-) diff --git a/DMRLookup.cpp b/DMRLookup.cpp index 8fc67c3..099ade3 100644 --- a/DMRLookup.cpp +++ b/DMRLookup.cpp @@ -30,7 +30,6 @@ CThread(), m_filename(filename), m_reloadTime(reloadTime), m_table(), -m_mutex(), m_stop(false) { } @@ -41,7 +40,7 @@ CDMRLookup::~CDMRLookup() bool CDMRLookup::read() { - bool ret = load(); + bool ret = m_table.load(m_filename); if (m_reloadTime > 0U) run(); @@ -61,7 +60,7 @@ void CDMRLookup::entry() timer.clock(); if (timer.hasExpired()) { - load(); + m_table.load(m_filename); timer.start(); } } @@ -88,20 +87,20 @@ std::string CDMRLookup::findWithName(unsigned int id) if (id == 0xFFFFFFU) return std::string("ALL"); - m_mutex.lock(); + class CUserDBentry entry; + if (m_table.lookup(id, &entry)) { + // callsign is always available + callsign = entry.get(keyCALLSIGN); + if (!entry.get(keyFIRST_NAME).empty()) + callsign += " " + entry.get(keyFIRST_NAME); - try { - callsign = m_table.at(id); LogDebug("FindWithName =%s",callsign.c_str()); - - } catch (...) { + } else { char text[10U]; - ::sprintf(text, "%u", id); + ::snprintf(text, sizeof(text), "%u", id); callsign = std::string(text); } - m_mutex.unlock(); - return callsign; } std::string CDMRLookup::find(unsigned int id) @@ -109,90 +108,22 @@ std::string CDMRLookup::find(unsigned int id) std::string callsign; std::string b; - if (id == 0xFFFFFFU) return std::string("ALL"); - m_mutex.lock(); - - try { - b = m_table.at(id); - size_t n = b.find(" "); - if (n > 0) { - callsign = b.substr(0,n); - - } else { - LogDebug("b=%s",b.c_str()); - callsign = b; - } - - } catch (...) { + class CUserDBentry entry; + if (m_table.lookup(id, &entry)) { + callsign = entry.get(keyCALLSIGN); + } else { char text[10U]; - ::sprintf(text, "%u", id); + ::snprintf(text, sizeof(text), "%u", id); callsign = std::string(text); } - m_mutex.unlock(); - return callsign; } bool CDMRLookup::exists(unsigned int id) { - m_mutex.lock(); - - bool found = m_table.count(id) == 1U; - - m_mutex.unlock(); - - return found; + return m_table.lookup(id, NULL); } - -bool CDMRLookup::load() -{ - FILE* fp = ::fopen(m_filename.c_str(), "rt"); - if (fp == NULL) { - LogWarning("Cannot open the DMR Id lookup file - %s", m_filename.c_str()); - return false; - } - - m_mutex.lock(); - - // Remove the old entries - m_table.clear(); - - char buffer[100U]; - while (::fgets(buffer, 100U, fp) != NULL) { - if (buffer[0U] == '#') - continue; - - char* p1 = ::strtok(buffer, " \t\r\n"); - char* p2 = ::strtok(NULL, " \r\n"); // tokenize to eol to capture name as well - - if (p1 != NULL && p2 != NULL) { - unsigned int id = (unsigned int)::atoi(p1); - for (char* p = p2; *p != 0x00U; p++) { - - if(*p == 0x09U) - *p = 0x20U; - - else - *p = ::toupper(*p); - - } - m_table[id] = std::string(p2); - } - } - - m_mutex.unlock(); - - ::fclose(fp); - - size_t size = m_table.size(); - if (size == 0U) - return false; - - LogInfo("Loaded %u Ids to the DMR callsign lookup table", size); - - return true; -} \ No newline at end of file From abf17e19fce742b0962c0dec648788679f5b49bb Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Sun, 8 Mar 2020 07:55:08 +0900 Subject: [PATCH 06/17] get() goes const, add clear() --- UserDBentry.cpp | 7 ++++++- UserDBentry.h | 3 ++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/UserDBentry.cpp b/UserDBentry.cpp index 28c4ca5..0121544 100644 --- a/UserDBentry.cpp +++ b/UserDBentry.cpp @@ -44,7 +44,7 @@ void CUserDBentry::set(const std::string key, const std::string value) m_db[key] = value; } -std::string CUserDBentry::get(const std::string key) +const std::string CUserDBentry::get(const std::string key) const { try { return m_db.at(key); @@ -52,3 +52,8 @@ std::string CUserDBentry::get(const std::string key) return ""; } } + +void CUserDBentry::clear(void) +{ + m_db.clear(); +} diff --git a/UserDBentry.h b/UserDBentry.h index d44f451..cbca92f 100644 --- a/UserDBentry.h +++ b/UserDBentry.h @@ -40,7 +40,8 @@ public: static bool isValidKey(const std::string key); void set(const std::string key, const std::string value); - std::string get(const std::string key); + const std::string get(const std::string key) const; + void clear(void); private: std::unordered_map m_db; From 4ff77c50d6faef67136d07279dbf9ceb9e30693f Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Sun, 8 Mar 2020 08:06:27 +0900 Subject: [PATCH 07/17] use UserDBentry from findWithName() to writeDMR(), add writeDMREx() --- DMRLookup.cpp | 33 ++++++++++++++++----------------- DMRLookup.h | 16 ++++++---------- DMRSlot.cpp | 9 ++++++--- Display.cpp | 27 +++++++++++++++++++++++++++ Display.h | 3 +++ 5 files changed, 58 insertions(+), 30 deletions(-) diff --git a/DMRLookup.cpp b/DMRLookup.cpp index 099ade3..71ce3d3 100644 --- a/DMRLookup.cpp +++ b/DMRLookup.cpp @@ -80,28 +80,27 @@ void CDMRLookup::stop() wait(); } -std::string CDMRLookup::findWithName(unsigned int id) +void CDMRLookup::findWithName(unsigned int id, class CUserDBentry *entry) { std::string callsign; - if (id == 0xFFFFFFU) - return std::string("ALL"); - - class CUserDBentry entry; - if (m_table.lookup(id, &entry)) { - // callsign is always available - callsign = entry.get(keyCALLSIGN); - if (!entry.get(keyFIRST_NAME).empty()) - callsign += " " + entry.get(keyFIRST_NAME); - - LogDebug("FindWithName =%s",callsign.c_str()); - } else { - char text[10U]; - ::snprintf(text, sizeof(text), "%u", id); - callsign = std::string(text); + if (id == 0xFFFFFFU) { + entry->clear(); + entry->set(keyCALLSIGN, "ALL"); + return; } - return callsign; + if (m_table.lookup(id, entry)) { + LogDebug("FindWithName =%s %s", entry->get(keyCALLSIGN).c_str(), entry->get(keyFIRST_NAME).c_str()); + } else { + entry->clear(); + + char text[10U]; + ::snprintf(text, sizeof(text), "%u", id); + entry->set(keyCALLSIGN, text); + } + + return; } std::string CDMRLookup::find(unsigned int id) { diff --git a/DMRLookup.h b/DMRLookup.h index 1156270..c4e5d90 100644 --- a/DMRLookup.h +++ b/DMRLookup.h @@ -20,10 +20,9 @@ #define DMRLookup_H #include "Thread.h" -#include "Mutex.h" +#include "UserDB.h" #include -#include class CDMRLookup : public CThread { public: @@ -35,20 +34,17 @@ public: virtual void entry(); std::string find(unsigned int id); - std::string findWithName(unsigned int id); + void findWithName(unsigned int id, class CUserDBentry *entry); bool exists(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(); + std::string m_filename; + unsigned int m_reloadTime; + class CUserDB m_table; + bool m_stop; }; #endif diff --git a/DMRSlot.cpp b/DMRSlot.cpp index f42def4..1cfecab 100644 --- a/DMRSlot.cpp +++ b/DMRSlot.cpp @@ -1108,7 +1108,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) setShortLC(m_slotNo, dstId, flco, ACTIVITY_VOICE); std::string src = m_lookup->find(srcId); std::string dst = m_lookup->find(dstId); - std::string cn = m_lookup->findWithName(srcId); + class CUserDBentry cn; + m_lookup->findWithName(srcId, &cn); m_display->writeDMR(m_slotNo, cn, flco == FLCO_GROUP, dst, "N"); #if defined(DUMP_DMR) @@ -1177,7 +1178,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) setShortLC(m_slotNo, dstId, m_netLC->getFLCO(), ACTIVITY_VOICE); std::string src = m_lookup->find(srcId); std::string dst = m_lookup->find(dstId); - std::string cn = m_lookup->findWithName(srcId); + class CUserDBentry cn; + m_lookup->findWithName(srcId, &cn); m_display->writeDMR(m_slotNo, cn, m_netLC->getFLCO() == FLCO_GROUP, dst, "N"); @@ -1373,7 +1375,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) std::string src = m_lookup->find(srcId); std::string dst = m_lookup->find(dstId); - std::string cn = m_lookup->findWithName(srcId); + class CUserDBentry cn; + m_lookup->findWithName(srcId, &cn); m_display->writeDMR(m_slotNo, cn, m_netLC->getFLCO() == FLCO_GROUP, dst, "N"); diff --git a/Display.cpp b/Display.cpp index 84148b7..fcc7f59 100644 --- a/Display.cpp +++ b/Display.cpp @@ -151,6 +151,28 @@ void CDisplay::writeDMR(unsigned int slotNo, const std::string& src, bool group, writeDMRInt(slotNo, src, group, dst, type); } +void CDisplay::writeDMR(unsigned int slotNo, const class CUserDBentry& src, bool group, const std::string& dst, const char* type) +{ + assert(type != NULL); + + if (slotNo == 1U) { + m_timer1.start(); + m_mode1 = MODE_IDLE; + } else { + m_timer2.start(); + m_mode2 = MODE_IDLE; + } + + if (writeDMRIntEx(slotNo, src, group, dst, type) < 0) { + std::string src_str; + + src_str = src.get(keyCALLSIGN); + if (!src.get(keyFIRST_NAME).empty()) + src_str += " " + src.get(keyFIRST_NAME); + writeDMRInt(slotNo, src_str, group, dst, type); + } +} + void CDisplay::writeDMRRSSI(unsigned int slotNo, unsigned char rssi) { if (rssi != 0U) @@ -386,6 +408,11 @@ void CDisplay::writeDStarBERInt(float ber) { } +int CDisplay::writeDMRIntEx(unsigned int slotNo, const class CUserDBentry& src, bool group, const std::string& dst, const char* type) +{ + return -1; // not supported +} + void CDisplay::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi) { } diff --git a/Display.h b/Display.h index 65515be..2690d94 100644 --- a/Display.h +++ b/Display.h @@ -20,6 +20,7 @@ #define DISPLAY_H #include "Timer.h" +#include "UserDBentry.h" #include @@ -48,6 +49,7 @@ public: void clearDStar(); void writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type); + void writeDMR(unsigned int slotNo, const class CUserDBentry& src, bool group, const std::string& dst, const char* type); void writeDMRRSSI(unsigned int slotNo, unsigned char rssi); void writeDMRBER(unsigned int slotNo, float ber); void writeDMRTA(unsigned int slotNo, unsigned char* talkerAlias, const char* type); @@ -91,6 +93,7 @@ protected: virtual void clearDStarInt() = 0; virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) = 0; + virtual int writeDMRIntEx(unsigned int slotNo, const class CUserDBentry& src, bool group, const std::string& dst, const char* type); virtual void writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi); virtual void writeDMRTAInt(unsigned int slotNo, unsigned char* talkerAlias, const char* type); virtual void writeDMRBERInt(unsigned int slotNo, float ber); From 5bd54e97cb6b7644cf758880f19372eeb2ea6b9e Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Sun, 8 Mar 2020 08:43:57 +0900 Subject: [PATCH 08/17] add writeDMRIntEx() to support UserDB display --- TFTSurenoo.cpp | 25 ++++++++++++++++++++++++- TFTSurenoo.h | 2 ++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/TFTSurenoo.cpp b/TFTSurenoo.cpp index 5d15856..41f2d63 100644 --- a/TFTSurenoo.cpp +++ b/TFTSurenoo.cpp @@ -230,6 +230,28 @@ void CTFTSurenoo::writeDMRInt(unsigned int slotNo, const std::string& src, bool m_mode = MODE_DMR; } +int CTFTSurenoo::writeDMRIntEx(unsigned int slotNo, const class CUserDBentry& src, bool group, const std::string& dst, const char* type) +{ + assert(type != NULL); + + // duplex mode is not supported + if (m_duplex) + return -1; + + setModeLine(STR_DMR); + setStatusLine(statusLineNo(0), src.get(keyCALLSIGN).c_str()); + ::snprintf(m_temp, sizeof(m_temp), "TS%d %s%s", slotNo, group ? "TG" : "", dst.c_str()); + setStatusLine(statusLineNo(1), m_temp); + setStatusLine(statusLineNo(2), (src.get(keyFIRST_NAME) + " " + src.get(keyLAST_NAME)).c_str()); + setStatusLine(statusLineNo(3), src.get(keyCITY).c_str()); + setStatusLine(statusLineNo(4), src.get(keySTATE).c_str()); + setStatusLine(statusLineNo(5), src.get(keyCOUNTRY).c_str()); + + m_mode = MODE_DMR; + + return 0; +} + void CTFTSurenoo::clearDMRInt(unsigned int slotNo) { int pos = m_duplex ? (slotNo - 1) : 0; @@ -239,7 +261,8 @@ void CTFTSurenoo::clearDMRInt(unsigned int slotNo) ::snprintf(m_temp, sizeof(m_temp), "TS%d", slotNo); setStatusLine(statusLineNo(pos * 2 + 1), m_temp); } else { - setStatusLine(statusLineNo(1), ""); + for (int i = 1; i < STATUS_LINES; i++) + setStatusLine(statusLineNo(i), ""); } } diff --git a/TFTSurenoo.h b/TFTSurenoo.h index 20a743a..9058c5b 100644 --- a/TFTSurenoo.h +++ b/TFTSurenoo.h @@ -23,6 +23,7 @@ #include "Display.h" #include "Defines.h" #include "SerialPort.h" +#include "UserDBentry.h" #include @@ -46,6 +47,7 @@ protected: virtual void clearDStarInt(); virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type); + virtual int writeDMRIntEx(unsigned int slotNo, const class CUserDBentry& src, bool group, const std::string& dst, const char* type); virtual void clearDMRInt(unsigned int slotNo); virtual void writeFusionInt(const char* source, const char* dest, const char* type, const char* origin); From 92a34411168b92294aa0a06b218692e2b4a4f8d4 Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Sun, 8 Mar 2020 20:47:48 +0900 Subject: [PATCH 09/17] code cleanup: remove unneeded std::string() --- UserDB.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UserDB.cpp b/UserDB.cpp index 9d962d7..9984d63 100644 --- a/UserDB.cpp +++ b/UserDB.cpp @@ -158,7 +158,7 @@ void CUserDB::parse(char* buf, std::unordered_map& index) if (it->first == keyRADIO_ID) continue; - m_table[id].set(it->first, std::string(it->second)); + m_table[id].set(it->first, it->second); } } From 6febd661f6a769653dc344c0e8d417723301e421 Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Mon, 9 Mar 2020 20:48:14 +0900 Subject: [PATCH 10/17] add return value description of writeDMRIntEx() --- Display.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Display.cpp b/Display.cpp index fcc7f59..dc28fe2 100644 --- a/Display.cpp +++ b/Display.cpp @@ -410,6 +410,13 @@ void CDisplay::writeDStarBERInt(float ber) int CDisplay::writeDMRIntEx(unsigned int slotNo, const class CUserDBentry& src, bool group, const std::string& dst, const char* type) { + /* + * return value: + * < 0 error condition (i.e. not supported) + * -> call writeDMRInt() to display + * = 0 no error, writeDMRIntEx() displayed whole status + * > 0 reserved for future use + */ return -1; // not supported } From 136a14848081597e94490163bdabea13c45d5bd3 Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Mon, 9 Mar 2020 22:16:21 +0900 Subject: [PATCH 11/17] delete unused variable --- DMRLookup.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/DMRLookup.cpp b/DMRLookup.cpp index 71ce3d3..2549e24 100644 --- a/DMRLookup.cpp +++ b/DMRLookup.cpp @@ -82,8 +82,6 @@ void CDMRLookup::stop() void CDMRLookup::findWithName(unsigned int id, class CUserDBentry *entry) { - std::string callsign; - if (id == 0xFFFFFFU) { entry->clear(); entry->set(keyCALLSIGN, "ALL"); @@ -105,8 +103,7 @@ void CDMRLookup::findWithName(unsigned int id, class CUserDBentry *entry) std::string CDMRLookup::find(unsigned int id) { std::string callsign; - std::string b; - + if (id == 0xFFFFFFU) return std::string("ALL"); From f6b50366518ef462e07d757ba80c6b76d12b1d35 Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Mon, 9 Mar 2020 22:23:55 +0900 Subject: [PATCH 12/17] NXDNLookup now use UserDB --- NXDNLookup.cpp | 92 ++++++++++++++++---------------------------------- NXDNLookup.h | 15 ++++---- 2 files changed, 35 insertions(+), 72 deletions(-) diff --git a/NXDNLookup.cpp b/NXDNLookup.cpp index 2c621b6..c12ed27 100644 --- a/NXDNLookup.cpp +++ b/NXDNLookup.cpp @@ -30,7 +30,6 @@ CThread(), m_filename(filename), m_reloadTime(reloadTime), m_table(), -m_mutex(), m_stop(false) { } @@ -41,7 +40,7 @@ CNXDNLookup::~CNXDNLookup() bool CNXDNLookup::read() { - bool ret = load(); + bool ret = m_table.load(m_filename); if (m_reloadTime > 0U) run(); @@ -61,7 +60,7 @@ void CNXDNLookup::entry() timer.clock(); if (timer.hasExpired()) { - load(); + m_table.load(m_filename); timer.start(); } } @@ -81,6 +80,27 @@ void CNXDNLookup::stop() wait(); } +void CNXDNLookup::findWithName(unsigned int id, class CUserDBentry *entry) +{ + if (id == 0xFFFFU) { + entry->clear(); + entry->set(keyCALLSIGN, "ALL"); + return; + } + + if (m_table.lookup(id, entry)) { + LogDebug("FindWithName =%s %s", entry->get(keyCALLSIGN).c_str(), entry->get(keyFIRST_NAME).c_str()); + } else { + entry->clear(); + + char text[10U]; + ::snprintf(text, sizeof(text), "%u", id); + entry->set(keyCALLSIGN, text); + } + + return; +} + std::string CNXDNLookup::find(unsigned int id) { std::string callsign; @@ -88,73 +108,19 @@ std::string CNXDNLookup::find(unsigned int id) if (id == 0xFFFFU) return std::string("ALL"); - m_mutex.lock(); - - try { - callsign = m_table.at(id); - } catch (...) { + class CUserDBentry entry; + if (m_table.lookup(id, &entry)) { + callsign = entry.get(keyCALLSIGN); + } else { char text[10U]; - ::sprintf(text, "%u", id); + ::snprintf(text, sizeof(text), "%u", id); callsign = std::string(text); } - m_mutex.unlock(); - return callsign; } bool CNXDNLookup::exists(unsigned int id) { - m_mutex.lock(); - - bool found = m_table.count(id) == 1U; - - m_mutex.unlock(); - - return found; + return m_table.lookup(id, NULL); } - -bool CNXDNLookup::load() -{ - FILE* fp = ::fopen(m_filename.c_str(), "rt"); - if (fp == NULL) { - LogWarning("Cannot open the NXDN Id lookup file - %s", m_filename.c_str()); - return false; - } - - m_mutex.lock(); - - // Remove the old entries - m_table.clear(); - - char buffer[100U]; - while (::fgets(buffer, 100U, fp) != NULL) { - if (buffer[0U] == '#') - continue; - - char* p1 = ::strtok(buffer, ",\t\r\n"); - char* p2 = ::strtok(NULL, ",\t\r\n"); - - if (p1 != NULL && p2 != NULL) { - unsigned int id = (unsigned int)::atoi(p1); - if (id > 0U) { - for (char* p = p2; *p != 0x00U; p++) - *p = ::toupper(*p); - - m_table[id] = std::string(p2); - } - } - } - - m_mutex.unlock(); - - ::fclose(fp); - - size_t size = m_table.size(); - if (size == 0U) - return false; - - LogInfo("Loaded %u Ids to the NXDN callsign lookup table", size); - - return true; -} \ No newline at end of file diff --git a/NXDNLookup.h b/NXDNLookup.h index d7b0486..c53a927 100644 --- a/NXDNLookup.h +++ b/NXDNLookup.h @@ -20,10 +20,9 @@ #define NXDNLookup_H #include "Thread.h" -#include "Mutex.h" +#include "UserDB.h" #include -#include class CNXDNLookup : public CThread { public: @@ -35,19 +34,17 @@ public: virtual void entry(); std::string find(unsigned int id); + void findWithName(unsigned int id, class CUserDBentry *entry); bool exists(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(); + std::string m_filename; + unsigned int m_reloadTime; + class CUserDB m_table; + bool m_stop; }; #endif From d2751897fb1979c85f718fabe72945617a03a0c4 Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Tue, 10 Mar 2020 05:26:45 +0900 Subject: [PATCH 13/17] cosme --- DMRLookup.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/DMRLookup.cpp b/DMRLookup.cpp index 2549e24..b959950 100644 --- a/DMRLookup.cpp +++ b/DMRLookup.cpp @@ -100,6 +100,7 @@ void CDMRLookup::findWithName(unsigned int id, class CUserDBentry *entry) return; } + std::string CDMRLookup::find(unsigned int id) { std::string callsign; From 36414acc6a61eb8ec64ee4f40b9820fc05813951 Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Tue, 10 Mar 2020 05:46:24 +0900 Subject: [PATCH 14/17] add UserDB-based NXDN display interface --- Display.cpp | 37 +++++++++++++++++++++++++++++-------- Display.h | 2 ++ 2 files changed, 31 insertions(+), 8 deletions(-) diff --git a/Display.cpp b/Display.cpp index dc28fe2..5a74747 100644 --- a/Display.cpp +++ b/Display.cpp @@ -163,12 +163,13 @@ void CDisplay::writeDMR(unsigned int slotNo, const class CUserDBentry& src, bool m_mode2 = MODE_IDLE; } - if (writeDMRIntEx(slotNo, src, group, dst, type) < 0) { - std::string src_str; - - src_str = src.get(keyCALLSIGN); - if (!src.get(keyFIRST_NAME).empty()) + if (int err = writeDMRIntEx(slotNo, src, group, dst, type)) { + std::string src_str = src.get(keyCALLSIGN); + if (err < 0 && !src.get(keyFIRST_NAME).empty()) { + // emulate the result of old CDMRLookup::findWithName() + // (it returned callsign and firstname) src_str += " " + src.get(keyFIRST_NAME); + } writeDMRInt(slotNo, src_str, group, dst, type); } } @@ -289,6 +290,17 @@ void CDisplay::writeNXDN(const char* source, bool group, unsigned int dest, cons writeNXDNInt(source, group, dest, type); } +void CDisplay::writeNXDN(const class CUserDBentry& source, bool group, unsigned int dest, const char* type) +{ + assert(type != NULL); + + m_timer1.start(); + m_mode1 = MODE_IDLE; + + if (writeNXDNIntEx(source, group, dest, type)) + writeNXDNInt(source.get(keyCALLSIGN).c_str(), group, dest, type); +} + void CDisplay::writeNXDNRSSI(unsigned char rssi) { if (rssi != 0U) @@ -413,9 +425,11 @@ int CDisplay::writeDMRIntEx(unsigned int slotNo, const class CUserDBentry& src, /* * return value: * < 0 error condition (i.e. not supported) - * -> call writeDMRInt() to display - * = 0 no error, writeDMRIntEx() displayed whole status - * > 0 reserved for future use + * -> call writeXXXXInt() to display + * = 0 no error, writeXXXXIntEx() displayed whole status + * = 1 no error, writeXXXXIntEx() displayed partial status + * -> call writeXXXXInt() to display remain part + * > 1 reserved for future use */ return -1; // not supported } @@ -455,6 +469,13 @@ void CDisplay::writeNXDNRSSIInt(unsigned char rssi) void CDisplay::writeNXDNBERInt(float ber) { } + +int CDisplay::writeNXDNIntEx(const class CUserDBentry& source, bool group, unsigned int dest, const char* type) +{ + /* return value definition is same as writeDMRIntEx() */ + return -1; // not supported +} + /* Factory method extracted from MMDVMHost.cpp - BG5HHP */ CDisplay* CDisplay::createDisplay(const CConf& conf, CUMP* ump, CModem* modem) diff --git a/Display.h b/Display.h index 2690d94..74fa25b 100644 --- a/Display.h +++ b/Display.h @@ -66,6 +66,7 @@ public: void clearP25(); void writeNXDN(const char* source, bool group, unsigned int dest, const char* type); + void writeNXDN(const class CUserDBentry& source, bool group, unsigned int dest, const char* type); void writeNXDNRSSI(unsigned char rssi); void writeNXDNBER(float ber); void clearNXDN(); @@ -110,6 +111,7 @@ protected: virtual void clearP25Int() = 0; virtual void writeNXDNInt(const char* source, bool group, unsigned int dest, const char* type) = 0; + virtual int writeNXDNIntEx(const class CUserDBentry& source, bool group, unsigned int dest, const char* type); virtual void writeNXDNRSSIInt(unsigned char rssi); virtual void writeNXDNBERInt(float ber); virtual void clearNXDNInt() = 0; From cc62fb62b71420fb389a79b37bc28ac179a84903 Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Tue, 10 Mar 2020 06:14:17 +0900 Subject: [PATCH 15/17] add NXDN user data display --- TFTSurenoo.cpp | 27 ++++++++++++++++++++------- TFTSurenoo.h | 1 + 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/TFTSurenoo.cpp b/TFTSurenoo.cpp index 41f2d63..cb3f6f3 100644 --- a/TFTSurenoo.cpp +++ b/TFTSurenoo.cpp @@ -202,8 +202,8 @@ void CTFTSurenoo::writeDStarInt(const char* my1, const char* my2, const char* yo void CTFTSurenoo::clearDStarInt() { setStatusLine(statusLineNo(0), "Listening"); - setStatusLine(statusLineNo(1), ""); - setStatusLine(statusLineNo(2), ""); + for (int i = 1; i < STATUS_LINES; i++) + setStatusLine(statusLineNo(i), ""); } void CTFTSurenoo::writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) @@ -239,9 +239,6 @@ int CTFTSurenoo::writeDMRIntEx(unsigned int slotNo, const class CUserDBentry& sr return -1; setModeLine(STR_DMR); - setStatusLine(statusLineNo(0), src.get(keyCALLSIGN).c_str()); - ::snprintf(m_temp, sizeof(m_temp), "TS%d %s%s", slotNo, group ? "TG" : "", dst.c_str()); - setStatusLine(statusLineNo(1), m_temp); setStatusLine(statusLineNo(2), (src.get(keyFIRST_NAME) + " " + src.get(keyLAST_NAME)).c_str()); setStatusLine(statusLineNo(3), src.get(keyCITY).c_str()); setStatusLine(statusLineNo(4), src.get(keySTATE).c_str()); @@ -249,7 +246,7 @@ int CTFTSurenoo::writeDMRIntEx(unsigned int slotNo, const class CUserDBentry& sr m_mode = MODE_DMR; - return 0; + return 1; } void CTFTSurenoo::clearDMRInt(unsigned int slotNo) @@ -321,7 +318,8 @@ void CTFTSurenoo::writeNXDNInt(const char* source, bool group, unsigned int dest assert(source != NULL); assert(type != NULL); - setModeLine(STR_NXDN); + if (m_mode != MODE_NXDN) + setModeLine(STR_NXDN); ::snprintf(m_temp, sizeof(m_temp), "%s %.10s", type, source); setStatusLine(statusLineNo(0), m_temp); @@ -332,6 +330,21 @@ void CTFTSurenoo::writeNXDNInt(const char* source, bool group, unsigned int dest m_mode = MODE_NXDN; } +int CTFTSurenoo::writeNXDNIntEx(const class CUserDBentry& source, bool group, unsigned int dest, const char* type) +{ + assert(type != NULL); + + setModeLine(STR_NXDN); + setStatusLine(statusLineNo(2), (source.get(keyFIRST_NAME) + " " + source.get(keyLAST_NAME)).c_str()); + setStatusLine(statusLineNo(3), source.get(keyCITY).c_str()); + setStatusLine(statusLineNo(4), source.get(keySTATE).c_str()); + setStatusLine(statusLineNo(5), source.get(keyCOUNTRY).c_str()); + + m_mode = MODE_NXDN; + + return 1; +} + void CTFTSurenoo::clearNXDNInt() { clearDStarInt(); diff --git a/TFTSurenoo.h b/TFTSurenoo.h index 9058c5b..d058c3e 100644 --- a/TFTSurenoo.h +++ b/TFTSurenoo.h @@ -57,6 +57,7 @@ protected: virtual void clearP25Int(); virtual void writeNXDNInt(const char* source, bool group, unsigned int dest, const char* type); + virtual int writeNXDNIntEx(const class CUserDBentry& source, bool group, unsigned int dest, const char* type); virtual void clearNXDNInt(); virtual void writePOCSAGInt(uint32_t ric, const std::string& message); From e036ac8be317d0cdaea5f1c31e90eaa8da93163a Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Thu, 12 Mar 2020 21:48:21 +0900 Subject: [PATCH 16/17] revise snprintf() format string to simplify display layout (all modes) --- TFTSurenoo.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/TFTSurenoo.cpp b/TFTSurenoo.cpp index cb3f6f3..a2eba9e 100644 --- a/TFTSurenoo.cpp +++ b/TFTSurenoo.cpp @@ -135,7 +135,7 @@ void CTFTSurenoo::setIdleInt() { setModeLine(STR_MMDVM); - ::snprintf(m_temp, sizeof(m_temp), "%-6s / %u", m_callsign.c_str(), m_dmrid); + ::snprintf(m_temp, sizeof(m_temp), "%s / %u", m_callsign.c_str(), m_dmrid); setStatusLine(statusLineNo(0), m_temp); setStatusLine(statusLineNo(1), "IDLE"); @@ -184,14 +184,14 @@ void CTFTSurenoo::writeDStarInt(const char* my1, const char* my2, const char* yo setModeLine(STR_MMDVM); - ::snprintf(m_temp, sizeof(m_temp), "%s %.8s/%4.4s", type, my1, my2); + ::snprintf(m_temp, sizeof(m_temp), "%s %s/%s", type, my1, my2); setStatusLine(statusLineNo(0), m_temp); - ::snprintf(m_temp, sizeof(m_temp), "%.8s", your); + ::snprintf(m_temp, sizeof(m_temp), "%s", your); setStatusLine(statusLineNo(1), m_temp); if (::strcmp(reflector, " ") != 0) - ::snprintf(m_temp, sizeof(m_temp), "via %.8s", reflector); + ::snprintf(m_temp, sizeof(m_temp), "via %s", reflector); else ::strcpy(m_temp, ""); setStatusLine(statusLineNo(2), m_temp); @@ -272,14 +272,14 @@ void CTFTSurenoo::writeFusionInt(const char* source, const char* dest, const cha setModeLine(STR_YSF); - ::snprintf(m_temp, sizeof(m_temp), "%s %.10s", type, source); + ::snprintf(m_temp, sizeof(m_temp), "%s %s", type, source); setStatusLine(statusLineNo(0), m_temp); - ::snprintf(m_temp, sizeof(m_temp), " %.10s", dest); + ::snprintf(m_temp, sizeof(m_temp), "%s", dest); setStatusLine(statusLineNo(1), m_temp); if (::strcmp(origin, " ") != 0) - ::snprintf(m_temp, sizeof(m_temp), "at %.10s", origin); + ::snprintf(m_temp, sizeof(m_temp), "at %s", origin); else ::strcpy(m_temp, ""); setStatusLine(statusLineNo(2), m_temp); @@ -299,10 +299,10 @@ void CTFTSurenoo::writeP25Int(const char* source, bool group, unsigned int dest, setModeLine(STR_P25); - ::snprintf(m_temp, sizeof(m_temp), "%s %.10s", type, source); + ::snprintf(m_temp, sizeof(m_temp), "%s %s", type, source); setStatusLine(statusLineNo(0), m_temp); - ::snprintf(m_temp, sizeof(m_temp), " %s%u", group ? "TG" : "", dest); + ::snprintf(m_temp, sizeof(m_temp), "%s%u", group ? "TG" : "", dest); setStatusLine(statusLineNo(1), m_temp); m_mode = MODE_P25; @@ -321,10 +321,10 @@ void CTFTSurenoo::writeNXDNInt(const char* source, bool group, unsigned int dest if (m_mode != MODE_NXDN) setModeLine(STR_NXDN); - ::snprintf(m_temp, sizeof(m_temp), "%s %.10s", type, source); + ::snprintf(m_temp, sizeof(m_temp), "%s %s", type, source); setStatusLine(statusLineNo(0), m_temp); - ::snprintf(m_temp, sizeof(m_temp), " %s%u", group ? "TG" : "", dest); + ::snprintf(m_temp, sizeof(m_temp), "%s%u", group ? "TG" : "", dest); setStatusLine(statusLineNo(1), m_temp); m_mode = MODE_NXDN; From d7d83ff4d07ea0ad09d7cac3a8b8f1990bfe0a51 Mon Sep 17 00:00:00 2001 From: SASANO Takayoshi Date: Sun, 15 Mar 2020 10:36:57 +0900 Subject: [PATCH 17/17] use findWithName() to display user information when netork voice transmission --- NXDNControl.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/NXDNControl.cpp b/NXDNControl.cpp index f36d7d0..1f3fa4c 100644 --- a/NXDNControl.cpp +++ b/NXDNControl.cpp @@ -835,15 +835,16 @@ void CNXDNControl::writeNetwork() unsigned short dstId = m_netLayer3.getDestinationGroupId(); bool grp = m_netLayer3.getIsGroup(); - std::string source = m_lookup->find(m_netLayer3.getSourceUnitId()); + class CUserDBentry source; + m_lookup->findWithName(m_netLayer3.getSourceUnitId(), &source); if (type == NXDN_MESSAGE_TYPE_TX_REL) { m_netFrames++; - LogMessage("NXDN, received network end of transmission from %s to %s%u, %.1f seconds", source.c_str(), grp ? "TG " : "", dstId, float(m_netFrames) / 12.5F); + LogMessage("NXDN, received network end of transmission from %s to %s%u, %.1f seconds", source.get(keyCALLSIGN).c_str(), grp ? "TG " : "", dstId, float(m_netFrames) / 12.5F); writeEndNet(); } else if (type == NXDN_MESSAGE_TYPE_VCALL) { - LogMessage("NXDN, received network transmission from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId); - m_display->writeNXDN(source.c_str(), grp, dstId, "N"); + LogMessage("NXDN, received network transmission from %s to %s%u", source.get(keyCALLSIGN).c_str(), grp ? "TG " : "", dstId); + m_display->writeNXDN(source, grp, dstId, "N"); m_netTimeoutTimer.start(); m_packetTimer.start(); @@ -892,9 +893,10 @@ void CNXDNControl::writeNetwork() unsigned short dstId = m_netLayer3.getDestinationGroupId(); bool grp = m_netLayer3.getIsGroup(); - std::string source = m_lookup->find(srcId); - LogMessage("NXDN, received network transmission from %s to %s%u", source.c_str(), grp ? "TG " : "", dstId); - m_display->writeNXDN(source.c_str(), grp, dstId, "N"); + class CUserDBentry source; + m_lookup->findWithName(srcId, &source); + LogMessage("NXDN, received network transmission from %s to %s%u", source.get(keyCALLSIGN).c_str(), grp ? "TG " : "", dstId); + m_display->writeNXDN(source, grp, dstId, "N"); m_netTimeoutTimer.start(); m_packetTimer.start();