diff --git a/Conf.cpp b/Conf.cpp index 7936599..883519a 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -91,8 +91,7 @@ m_modemDMRTXLevel(50U), m_modemYSFTXLevel(50U), m_modemP25TXLevel(50U), m_modemOscOffset(0), -m_modemRSSIMultiplier(0), -m_modemRSSIOffset(0), +m_modemRSSIMappingFile(), m_modemDebug(false), m_umpEnabled(false), m_umpPort(), @@ -105,20 +104,9 @@ m_dmrBeacons(false), m_dmrId(0U), m_dmrColorCode(2U), m_dmrSelfOnly(false), -m_dmrTGRewriteSlot1(false), -m_dmrTGRewriteSlot2(false), -m_dmrBMAutoRewrite(false), -m_dmrBMRewriteReflectorVoicePrompts(false), m_dmrPrefixes(), m_dmrBlackList(), -m_dmrDstIdBlacklistSlot1RF(), -m_dmrDstIdBlacklistSlot2RF(), -m_dmrDstIdWhitelistSlot1RF(), -m_dmrDstIdWhitelistSlot2RF(), -m_dmrDstIdBlacklistSlot1NET(), -m_dmrDstIdBlacklistSlot2NET(), -m_dmrDstIdWhitelistSlot1NET(), -m_dmrDstIdWhitelistSlot2NET(), +m_dmrWhiteList(), m_dmrCallHang(3U), m_dmrTXHang(4U), m_fusionEnabled(false), @@ -338,10 +326,8 @@ bool CConf::read() m_modemP25TXLevel = (unsigned int)::atoi(value); else if (::strcmp(key, "OscOffset") == 0) m_modemOscOffset = ::atoi(value); - else if (::strcmp(key, "RSSIMultiplier") == 0) - m_modemRSSIMultiplier = ::atoi(value); - else if (::strcmp(key, "RSSIOffset") == 0) - m_modemRSSIOffset = ::atoi(value); + else if (::strcmp(key, "RSSIMappingFile") == 0) + m_modemRSSIMappingFile = value; else if (::strcmp(key, "Debug") == 0) m_modemDebug = ::atoi(value) == 1; } else if (section == SECTION_UMP) { @@ -399,82 +385,18 @@ bool CConf::read() m_dmrBlackList.push_back(id); p = ::strtok(NULL, ",\r\n"); } - } else if (::strcmp(key, "DstIdBlackListSlot1RF") == 0) { + } else if (::strcmp(key, "WhiteList") == 0) { char* p = ::strtok(value, ",\r\n"); while (p != NULL) { unsigned int id = (unsigned int)::atoi(p); if (id > 0U) - m_dmrDstIdBlacklistSlot1RF.push_back(id); - p = ::strtok(NULL, ",\r\n"); - } - } else if (::strcmp(key, "DstIdBlackListSlot2RF") == 0) { - char* p = ::strtok(value, ",\r\n"); - while (p != NULL) { - unsigned int id = (unsigned int)::atoi(p); - if (id > 0U) - m_dmrDstIdBlacklistSlot2RF.push_back(id); - p = ::strtok(NULL, ",\r\n"); - } - } else if (::strcmp(key, "DstIdWhiteListSlot1RF") == 0) { - char* p = ::strtok(value, ",\r\n"); - while (p != NULL) { - unsigned int id = (unsigned int)::atoi(p); - if (id > 0U) - m_dmrDstIdWhitelistSlot1RF.push_back(id); - p = ::strtok(NULL, ",\r\n"); - } - } else if (::strcmp(key, "DstIdWhiteListSlot2RF") == 0) { - char* p = ::strtok(value, ",\r\n"); - while (p != NULL) { - unsigned int id = (unsigned int)::atoi(p); - if (id > 0U) - m_dmrDstIdWhitelistSlot2RF.push_back(id); - p = ::strtok(NULL, ",\r\n"); - } - } else if (::strcmp(key, "DstIdBlackListSlot1NET") == 0) { - char* p = ::strtok(value, ",\r\n"); - while (p != NULL) { - unsigned int id = (unsigned int)::atoi(p); - if (id > 0U) - m_dmrDstIdBlacklistSlot1NET.push_back(id); - p = ::strtok(NULL, ",\r\n"); - } - } else if (::strcmp(key, "DstIdBlackListSlot2NET") == 0) { - char* p = ::strtok(value, ",\r\n"); - while (p != NULL) { - unsigned int id = (unsigned int)::atoi(p); - if (id > 0U) - m_dmrDstIdBlacklistSlot2NET.push_back(id); - p = ::strtok(NULL, ",\r\n"); - } - } else if (::strcmp(key, "DstIdWhiteListSlot1NET") == 0) { - char* p = ::strtok(value, ",\r\n"); - while (p != NULL) { - unsigned int id = (unsigned int)::atoi(p); - if (id > 0U) - m_dmrDstIdWhitelistSlot1NET.push_back(id); - p = ::strtok(NULL, ",\r\n"); - } - } else if (::strcmp(key, "DstIdWhiteListSlot2NET") == 0) { - char* p = ::strtok(value, ",\r\n"); - while (p != NULL) { - unsigned int id = (unsigned int)::atoi(p); - if (id > 0U) - m_dmrDstIdWhitelistSlot2NET.push_back(id); + m_dmrWhiteList.push_back(id); p = ::strtok(NULL, ",\r\n"); } } else if (::strcmp(key, "TXHang") == 0) m_dmrTXHang = (unsigned int)::atoi(value); else if (::strcmp(key, "CallHang") == 0) m_dmrCallHang = (unsigned int)::atoi(value); - else if (::strcmp(key, "TGRewriteSlot1") == 0) - m_dmrTGRewriteSlot1 = ::atoi(value) == 1; - else if (::strcmp(key, "TGRewriteSlot2") == 0) - m_dmrTGRewriteSlot2 = ::atoi(value) == 1; - else if (::strcmp(key, "BMAutoRewrite") == 0) - m_dmrBMAutoRewrite = ::atoi(value) == 1; - else if (::strcmp(key, "BMRewriteReflectorVoicePrompts") == 0) - m_dmrBMRewriteReflectorVoicePrompts = ::atoi(value) == 1; } else if (section == SECTION_FUSION) { if (::strcmp(key, "Enable") == 0) m_fusionEnabled = ::atoi(value) == 1; @@ -799,14 +721,9 @@ int CConf::getModemOscOffset() const return m_modemOscOffset; } -int CConf::getModemRSSIMultiplier () const +std::string CConf::getModemRSSIMappingFile () const { - return m_modemRSSIMultiplier; -} - -int CConf::getModemRSSIOffset() const -{ - return m_modemRSSIOffset; + return m_modemRSSIMappingFile; } bool CConf::getModemDebug() const @@ -869,26 +786,6 @@ bool CConf::getDMRSelfOnly() const return m_dmrSelfOnly; } -bool CConf::getDMRTGRewriteSlot1() const -{ - return m_dmrTGRewriteSlot1; -} - -bool CConf::getDMRTGRewriteSlot2() const -{ - return m_dmrTGRewriteSlot2; -} - -bool CConf::getDMRBMAutoRewrite() const -{ - return m_dmrBMAutoRewrite; -} - -bool CConf::getDMRBMRewriteReflectorVoicePrompts() const -{ - return m_dmrBMRewriteReflectorVoicePrompts; -} - std::vector CConf::getDMRPrefixes() const { return m_dmrPrefixes; @@ -899,44 +796,9 @@ std::vector CConf::getDMRBlackList() const return m_dmrBlackList; } -std::vector CConf::getDMRDstIdBlacklistSlot1RF() const +std::vector CConf::getDMRWhiteList() 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 -{ - 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 -{ - return m_dmrDstIdWhitelistSlot2NET; + return m_dmrWhiteList; } unsigned int CConf::getDMRCallHang() const diff --git a/Conf.h b/Conf.h index ed25810..a92ca1a 100644 --- a/Conf.h +++ b/Conf.h @@ -78,8 +78,7 @@ public: unsigned int getModemYSFTXLevel() const; unsigned int getModemP25TXLevel() const; int getModemOscOffset() const; - int getModemRSSIMultiplier() const; - int getModemRSSIOffset() const; + std::string getModemRSSIMappingFile() const; bool getModemDebug() const; // The UMP section @@ -98,20 +97,9 @@ public: unsigned int getDMRId() const; unsigned int getDMRColorCode() const; bool getDMRSelfOnly() const; - bool getDMRTGRewriteSlot1() const; - bool getDMRTGRewriteSlot2() const; - bool getDMRBMAutoRewrite() const; - bool getDMRBMRewriteReflectorVoicePrompts() const; std::vector getDMRPrefixes() const; std::vector getDMRBlackList() const; - std::vector getDMRDstIdBlacklistSlot1RF() const; - std::vector getDMRDstIdBlacklistSlot2RF() const; - std::vector getDMRDstIdWhitelistSlot1RF() const; - std::vector getDMRDstIdWhitelistSlot2RF() const; - std::vector getDMRDstIdBlacklistSlot1NET() const; - std::vector getDMRDstIdBlacklistSlot2NET() const; - std::vector getDMRDstIdWhitelistSlot1NET() const; - std::vector getDMRDstIdWhitelistSlot2NET() const; + std::vector getDMRWhiteList() const; unsigned int getDMRCallHang() const; unsigned int getDMRTXHang() const; @@ -238,8 +226,7 @@ private: unsigned int m_modemYSFTXLevel; unsigned int m_modemP25TXLevel; int m_modemOscOffset; - int m_modemRSSIMultiplier; - int m_modemRSSIOffset; + std::string m_modemRSSIMappingFile; bool m_modemDebug; bool m_umpEnabled; @@ -255,20 +242,9 @@ private: unsigned int m_dmrId; unsigned int m_dmrColorCode; bool m_dmrSelfOnly; - bool m_dmrTGRewriteSlot1; - bool m_dmrTGRewriteSlot2; - bool m_dmrBMAutoRewrite; - bool m_dmrBMRewriteReflectorVoicePrompts; std::vector m_dmrPrefixes; std::vector m_dmrBlackList; - std::vector m_dmrDstIdBlacklistSlot1RF; - std::vector m_dmrDstIdBlacklistSlot2RF; - std::vector m_dmrDstIdWhitelistSlot1RF; - std::vector m_dmrDstIdWhitelistSlot2RF; - std::vector m_dmrDstIdBlacklistSlot1NET; - std::vector m_dmrDstIdBlacklistSlot2NET; - std::vector m_dmrDstIdWhitelistSlot1NET; - std::vector m_dmrDstIdWhitelistSlot2NET; + std::vector m_dmrWhiteList; unsigned int m_dmrCallHang; unsigned int m_dmrTXHang; diff --git a/DMRAccessControl.cpp b/DMRAccessControl.cpp index 4fbd37b..ecda020 100644 --- a/DMRAccessControl.cpp +++ b/DMRAccessControl.cpp @@ -1,4 +1,7 @@ /* + * Copyright (C) 2016 by Simon Rune G7RZU + * Copyright (C) 2016 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 @@ -20,18 +23,8 @@ #include #include - -std::vector CDMRAccessControl::m_dstBlackListSlot1RF; -std::vector CDMRAccessControl::m_dstBlackListSlot2RF; -std::vector CDMRAccessControl::m_dstWhiteListSlot1RF; -std::vector CDMRAccessControl::m_dstWhiteListSlot2RF; - -std::vector CDMRAccessControl::m_dstBlackListSlot1NET; -std::vector CDMRAccessControl::m_dstBlackListSlot2NET; -std::vector CDMRAccessControl::m_dstWhiteListSlot1NET; -std::vector CDMRAccessControl::m_dstWhiteListSlot2NET; - -std::vector CDMRAccessControl::m_srcIdBlacklist; +std::vector CDMRAccessControl::m_blackList; +std::vector CDMRAccessControl::m_whiteList; std::vector CDMRAccessControl::m_prefixes; @@ -39,228 +32,35 @@ bool CDMRAccessControl::m_selfOnly = false; unsigned int CDMRAccessControl::m_id = 0U; -unsigned int CDMRAccessControl::m_dstRewriteID[2]; -unsigned int CDMRAccessControl::m_srcID[2]; - -time_t CDMRAccessControl::m_time[2]; - -int CDMRAccessControl::m_callHang; - -bool CDMRAccessControl::m_tgRewriteSlot1; -bool CDMRAccessControl::m_tgRewriteSlot2; -bool CDMRAccessControl::m_bmAutoRewrite; -bool CDMRAccessControl::m_bmRewriteReflectorVoicePrompts; - -void CDMRAccessControl::init(const std::vector& dstIdBlacklistSlot1RF, const std::vector& dstIdWhitelistSlot1RF, const std::vector& dstIdBlacklistSlot2RF, const std::vector& dstIdWhitelistSlot2RF, const std::vector& dstIdBlacklistSlot1NET, const std::vector& dstIdWhitelistSlot1NET, const std::vector& dstIdBlacklistSlot2NET, const std::vector& dstIdWhitelistSlot2NET, const std::vector& srcIdBlacklist, bool selfOnly, const std::vector& prefixes, unsigned int id, unsigned int callHang, bool tgRewriteSlot1, bool tgRewriteSlot2, bool bmAutoRewrite, bool bmRewriteReflectorVoicePrompts) +void CDMRAccessControl::init(const std::vector& blacklist, const std::vector& whitelist, bool selfOnly, const std::vector& prefixes, unsigned int id) { - m_dstBlackListSlot1RF = dstIdBlacklistSlot1RF; - m_dstWhiteListSlot1RF = dstIdWhitelistSlot1RF; - m_dstBlackListSlot2RF = dstIdBlacklistSlot2RF; - m_dstWhiteListSlot2RF = dstIdWhitelistSlot2RF; - m_dstBlackListSlot1NET = dstIdBlacklistSlot1NET; - m_dstWhiteListSlot1NET = dstIdWhitelistSlot1NET; - m_dstBlackListSlot2NET = dstIdBlacklistSlot2NET; - m_dstWhiteListSlot2NET = dstIdWhitelistSlot2NET; - m_callHang = callHang; - m_tgRewriteSlot1 = tgRewriteSlot1; - m_tgRewriteSlot2 = tgRewriteSlot2; - m_bmAutoRewrite = bmAutoRewrite; - m_bmRewriteReflectorVoicePrompts = bmRewriteReflectorVoicePrompts; + m_blackList = blacklist; + m_whiteList = whitelist; + m_selfOnly = selfOnly; + m_prefixes = prefixes; + m_id = id; } -bool CDMRAccessControl::dstIdBlacklist(unsigned int did, unsigned int slot, bool network) +bool CDMRAccessControl::validateId(unsigned int id) { - static std::vector blacklist; - - if (slot == 1U) { - if (network) - blacklist = m_dstBlackListSlot1NET; - else - blacklist = m_dstBlackListSlot1RF; - } else { - if (network) - blacklist = m_dstBlackListSlot2NET; - else - blacklist = m_dstBlackListSlot2RF; - } - - return std::find(blacklist.begin(), blacklist.end(), did) != blacklist.end(); -} - -bool CDMRAccessControl::dstIdWhitelist(unsigned int did, unsigned int slot, bool gt4k, bool network) -{ - if (network) { - if (slot == 1U) { - if (m_dstWhiteListSlot1NET.size() == 0U) - return true; - - // No reflectors on slot1, so we only allow all IDs over 99999 unless specifically whitelisted. - // Allow traffic to TG0 as I think this is a special case - need to confirm - if (gt4k) { - if (std::find(m_dstWhiteListSlot1NET.begin(), m_dstWhiteListSlot1NET.end(), did) != m_dstWhiteListSlot1NET.end() || did >= 99999U || did == 0) - return true; - } else { - if (std::find(m_dstWhiteListSlot1NET.begin(), m_dstWhiteListSlot1NET.end(), did) != m_dstWhiteListSlot1NET.end() || did == 0) - return true; - } - } else { - if (m_dstWhiteListSlot2NET.size() == 0U) - return true; - - // On slot2 we allow reflector control IDs, but not secondary TG IDs unless specifically listed. Also allow echo. - if (gt4k) { - if (std::find(m_dstWhiteListSlot2NET.begin(), m_dstWhiteListSlot2NET.end(), did) != m_dstWhiteListSlot2NET.end() || did == 0) - return true; - // If dstId in secondary TG range or whitelist - else if (did >= 4000) { - if (did > 5000U && did < 10000U) - return false; - else - return true; - } - } else { - if (std::find(m_dstWhiteListSlot2NET.begin(), m_dstWhiteListSlot2NET.end(), did) != m_dstWhiteListSlot2NET.end()) - return true; - } - } - - return false; - } else { - if (slot == 1U) { - if (m_dstWhiteListSlot1RF.size() == 0U) - return true; - - // No reflectors on slot1, so we only allow all IDs over 99999 unless specifically whitelisted. - // Allow traffic to TG0 as I think this is a special case - need to confirm - if (gt4k) { - if (std::find(m_dstWhiteListSlot1RF.begin(), m_dstWhiteListSlot1RF.end(), did) != m_dstWhiteListSlot1RF.end() || did >= 99999U || did == 0) - return true; - } else { - if (std::find(m_dstWhiteListSlot1RF.begin(), m_dstWhiteListSlot1RF.end(), did) != m_dstWhiteListSlot1RF.end() || did == 0) - return true; - } - } else { - if (m_dstWhiteListSlot2RF.size() == 0U) - return true; - - // On slot2 we allow reflector control IDs, but not secondary TG IDs unless specifically listed. Also allow echo. - if (gt4k) { - if (std::find(m_dstWhiteListSlot2RF.begin(), m_dstWhiteListSlot2RF.end(), did) != m_dstWhiteListSlot2RF.end() || did == 0) - return true; - // If dstId in secondary TG range or whitelist - else if (did >= 4000U) { - if (did > 5000U && did < 10000U) - return false; - else - return true; - } - } else { - if (std::find(m_dstWhiteListSlot2RF.begin(), m_dstWhiteListSlot2RF.end(), did) != m_dstWhiteListSlot2RF.end()) - return true; - } - } - - return false; - } -} - -bool CDMRAccessControl::validateSrcId(unsigned int id) -{ - if (m_selfOnly) { + if (m_selfOnly) return id == m_id; - } else { - if (std::find(m_srcIdBlacklist.begin(), m_srcIdBlacklist.end(), id) != m_srcIdBlacklist.end()) + + if (std::find(m_blackList.begin(), m_blackList.end(), id) != m_blackList.end()) + return false; + + unsigned int prefix = id / 10000U; + if (prefix == 0U || prefix > 999U) + return false; + + if (!m_prefixes.empty()) { + bool ret = std::find(m_prefixes.begin(), m_prefixes.end(), prefix) == m_prefixes.end(); + if (ret) return false; - - unsigned int prefix = id / 10000U; - if (prefix == 0U || prefix > 999U) - return false; - - if (m_prefixes.size() == 0U) - return true; - - return std::find(m_prefixes.begin(), m_prefixes.end(), prefix) != m_prefixes.end(); } -} - -bool CDMRAccessControl::validateAccess(unsigned int src_id, unsigned int dst_id, unsigned int slot, bool network) -{ - // source ID validation is only applied to RF traffic - if (!network && !CDMRAccessControl::validateSrcId(src_id)) { - LogMessage("DMR Slot %u, invalid access attempt from %u (blacklisted)", slot, src_id); - return false; - } else if (CDMRAccessControl::dstIdBlacklist(dst_id, slot, network)) { - LogMessage("DMR Slot %u, invalid access attempt to TG%u (TG blacklisted)", slot, dst_id); - return false; - } else if (!CDMRAccessControl::dstIdWhitelist(dst_id, slot, true, network)) { - LogMessage("DMR Slot %u, invalid access attempt to TG%u (TG not in whitelist)", slot, dst_id); - return false; - } else { - return true; - } -} - -unsigned int CDMRAccessControl::dstIdRewrite(unsigned int did, unsigned int sid, unsigned int slot, bool network, CDMRLC* dmrLC) -{ - if (slot == 1U && !m_tgRewriteSlot1) - return 0U; - - if (slot == 2U && !m_tgRewriteSlot2) - return 0U; - - time_t currenttime = ::time(NULL); - - if (network) { - m_dstRewriteID[slot - 1U] = did; - m_srcID[slot - 1U] = sid; - - //deal with values of did we should never rewrite for - if(did == 0U || did == 9U) { - return 0U; - }; - - - if (m_bmAutoRewrite && (did < 4000U || did > 5000U) && dmrLC->getFLCO() == FLCO_GROUP) { - LogMessage("DMR Slot %u, Rewrite DST ID (TG) of of inbound network traffic from %u to 9", slot, did); - return 9U; - // Rewrite incoming BM voice prompts to TG 9 - } else if (m_bmRewriteReflectorVoicePrompts && (sid >= 4000U && sid <= 5000U) && dmrLC->getFLCO() == FLCO_USER_USER) { - dmrLC->setFLCO(FLCO_GROUP); - LogMessage("DMR Slot %u, Rewrite inbound private call to %u to Group Call on TG 9 (BM reflector voice prompt)", slot, did); - return 9U; - } else { - return 0U; - } - } else { - - //deal with values of did we should never rewrite for - switch(did) { - case 0U : - return 0U; - break; - case 9990U : - LogMessage("DMR Slot %u, Outbound call to Echo on 9990 by %u", slot, sid); - return 0U; - break; - } - - if (m_bmAutoRewrite && did == 9U && m_dstRewriteID[slot - 1U] != 9U && m_dstRewriteID[slot - 1U] != 0U && (m_time[slot - 1U] + m_callHang) > currenttime && dmrLC->getFLCO() == FLCO_GROUP) { - LogMessage("DMR Slot %u, Rewrite DST ID (TG) of outbound network traffic from %u to %u (return traffic during CallHang)", slot, did, m_dstRewriteID[slot - 1U]); - return m_dstRewriteID[slot - 1U]; - } else if (m_bmAutoRewrite && (did < 4000U || did > 5000U) && did != 9U && did < 999999U && dmrLC->getFLCO() == FLCO_USER_USER) { - m_dstRewriteID[slot - 1U] = did; - dmrLC->setFLCO(FLCO_GROUP); - LogMessage("DMR Slot %u, Rewrite outbound private call to %u Group Call (Connect talkgroup by private call)", slot, did); - return did; - } else if (m_bmAutoRewrite && (did < 4000U || did > 5000U) && did != 9U && did > 999999U) { - m_dstRewriteID[slot - 1U] = did; - } - - return 0U; - } -} - -void CDMRAccessControl::setOverEndTime(unsigned int slot) -{ - m_time[slot - 1U] = ::time(NULL); + + if (!m_whiteList.empty()) + return std::find(m_whiteList.begin(), m_whiteList.end(), id) != m_whiteList.end(); + + return true; } diff --git a/DMRAccessControl.h b/DMRAccessControl.h index cd044ee..ccb7c69 100644 --- a/DMRAccessControl.h +++ b/DMRAccessControl.h @@ -1,4 +1,7 @@ /* + * Copyright (C) 2016 by Simon Rune G7RZU + * Copyright (C) 2016 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 @@ -16,56 +19,23 @@ #define DMRAccessControl_H #include -#include #include "DMRLC.h" class CDMRAccessControl { public: - static bool validateAccess(unsigned int srcId, unsigned int dstId, unsigned int slot, bool network); + static bool validateId(unsigned int id); - static bool validateSrcId(unsigned int id); - - static void init(const std::vector& dstIdBlacklistSlot1RF, const std::vector& dstIdWhitelistSlot1RF, const std::vector& dstIdBlacklistSlot2RF, const std::vector& dstIdWhitelistSlot2RF, const std::vector& dstIdBlacklistSlot1NET, const std::vector& dstIdWhitelistSlot1NET, const std::vector& dstIdBlacklistSlot2NET, const std::vector& dstIdWhitelistSlot2NET, const std::vector& srcIdBlacklist, bool selfOnly, const std::vector& prefixes,unsigned int id,unsigned int callHang, bool tgRewrteSlot1, bool tgRewrteSlot2, bool m_bmAutoRewrite, bool m_bmRewriteReflectorVoicePrompts); + static void init(const std::vector& blacklist, const std::vector& whitelist, bool selfOnly, const std::vector& prefixes, unsigned int id); - static unsigned int dstIdRewrite(unsigned int id, unsigned int sid, unsigned int slot, bool network, CDMRLC* dmrLC); - - static void setOverEndTime(unsigned int slot); - private: - static std::vector m_dstBlackListSlot1RF; - static std::vector m_dstBlackListSlot2RF; - static std::vector m_dstWhiteListSlot1RF; - static std::vector m_dstWhiteListSlot2RF; - - static std::vector m_dstBlackListSlot1NET; - static std::vector m_dstBlackListSlot2NET; - static std::vector m_dstWhiteListSlot1NET; - static std::vector m_dstWhiteListSlot2NET; - - static std::vector m_srcIdBlacklist; + static std::vector m_blackList; + static std::vector m_whiteList; static std::vector m_prefixes; - static int m_callHang; - static bool m_selfOnly; static unsigned int m_id; - - static bool dstIdBlacklist(unsigned int did, unsigned int slot, bool network); - static bool dstIdWhitelist(unsigned int did, unsigned int slot, bool gt4k, bool network); - - static time_t m_time[2]; - - static unsigned int m_dstRewriteID[2]; - static unsigned int m_srcID[2]; - - static bool m_tgRewriteSlot1; - static bool m_tgRewriteSlot2; - static bool m_bmAutoRewrite; - static bool m_bmRewriteReflectorVoicePrompts; - - static CDMRLC* m_lastdmrLC; }; #endif diff --git a/DMRControl.cpp b/DMRControl.cpp index 13eb89c..4f749b9 100644 --- a/DMRControl.cpp +++ b/DMRControl.cpp @@ -21,7 +21,7 @@ #include #include -CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& blacklist, const std::vector& dstIdBlacklistSlot1RF, const std::vector& dstIdWhitelistSlot1RF, const std::vector& dstIdBlacklistSlot2RF, const std::vector& dstIdWhitelistSlot2RF, const std::vector& dstIdBlacklistSlot1NET, const std::vector& dstIdWhitelistSlot1NET, const std::vector& dstIdBlacklistSlot2NET, const std::vector& dstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter, bool tgRewriteSlot1, bool tgRewriteSlot2, bool bmAutoRewrite, bool bmRewriteReflectorVoicePrompts) : +CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& blacklist, const std::vector& whitelist, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter) : m_id(id), m_colorCode(colorCode), m_modem(modem), @@ -34,11 +34,12 @@ m_lookup(lookup) assert(modem != NULL); assert(display != NULL); assert(lookup != NULL); + assert(rssi != NULL); // Load black and white lists to DMRAccessControl - CDMRAccessControl::init(dstIdBlacklistSlot1RF, dstIdWhitelistSlot1RF, dstIdBlacklistSlot2RF, dstIdWhitelistSlot2RF, dstIdBlacklistSlot1NET, dstIdWhitelistSlot1NET, dstIdBlacklistSlot2NET, dstIdWhitelistSlot2NET, blacklist, selfOnly, prefixes, id, callHang, tgRewriteSlot1, tgRewriteSlot2, bmAutoRewrite, bmRewriteReflectorVoicePrompts); + CDMRAccessControl::init(blacklist, whitelist, selfOnly, prefixes, id); - CDMRSlot::init(colorCode, callHang, modem, network, display, duplex, m_lookup, rssiMultiplier, rssiOffset, jitter); + CDMRSlot::init(colorCode, callHang, modem, network, display, duplex, m_lookup, rssi, jitter); } CDMRControl::~CDMRControl() @@ -67,7 +68,7 @@ bool CDMRControl::processWakeup(const unsigned char* data) std::string src = m_lookup->find(srcId); - bool ret = CDMRAccessControl::validateSrcId(srcId); + bool ret = CDMRAccessControl::validateId(srcId); if (!ret) { LogMessage("Invalid CSBK BS_Dwn_Act received from %s", src.c_str()); return false; diff --git a/DMRControl.h b/DMRControl.h index bad4850..d631047 100644 --- a/DMRControl.h +++ b/DMRControl.h @@ -19,6 +19,7 @@ #if !defined(DMRControl_H) #define DMRControl_H +#include "RSSIInterpolator.h" #include "DMRNetwork.h" #include "DMRLookup.h" #include "Display.h" @@ -30,7 +31,7 @@ class CDMRControl { public: - CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& blacklist, const std::vector& dstIdBlacklistSlot1RF, const std::vector& dstIdWhitelistSlot1RF, const std::vector& dstIdBlacklistSlot2RF, const std::vector& dstIdWhitelistSlot2RF,const std::vector& dstIdBlacklistSlot1NET, const std::vector& dstIdWhitelistSlot1NET, const std::vector& dstIdBlacklistSlot2NET, const std::vector& dstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter, bool tgRewriteSlot1, bool tgRewriteSlot2, bool bmAutoRewrite, bool bmRewriteReflectorVoicePrompts); + CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector& prefixes, const std::vector& blacklist, const std::vector& whitelist, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter); ~CDMRControl(); bool processWakeup(const unsigned char* data); diff --git a/DMRSlot.cpp b/DMRSlot.cpp index 0905d28..3afa497 100644 --- a/DMRSlot.cpp +++ b/DMRSlot.cpp @@ -37,8 +37,7 @@ bool CDMRSlot::m_duplex = true; CDMRLookup* CDMRSlot::m_lookup = NULL; unsigned int CDMRSlot::m_hangCount = 3U * 17U; -int CDMRSlot::m_rssiMultiplier = 0; -int CDMRSlot::m_rssiOffset = 0; +CRSSIInterpolator* CDMRSlot::m_rssiMapper = NULL; unsigned int CDMRSlot::m_jitterTime = 300U; unsigned int CDMRSlot::m_jitterSlots = 5U; @@ -120,11 +119,11 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len) } // Have we got RSSI bytes on the end? - if (len == (DMR_FRAME_LENGTH_BYTES + 4U) && m_rssiMultiplier != 0) { + if (len == (DMR_FRAME_LENGTH_BYTES + 4U)) { uint16_t raw = 0U; raw |= (data[35U] << 8) & 0xFF00U; raw |= (data[36U] << 0) & 0x00FFU; - int rssi = (raw - m_rssiOffset) / m_rssiMultiplier; + int rssi = m_rssiMapper->interpolate(raw); m_rssi = (rssi >= 0) ? rssi : -rssi; LogDebug("DMR Slot %u, raw RSSI: %u, reported RSSI: -%u dBm", m_slotNo, raw, m_rssi); } @@ -133,10 +132,12 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len) bool audioSync = (data[1U] & DMR_SYNC_AUDIO) == DMR_SYNC_AUDIO; if (dataSync) { - CDMRSlotType slotType; - slotType.putData(data + 2U); + // Get the type from the packet metadata + unsigned char dataType = data[1U] & 0x0FU; - unsigned char dataType = slotType.getDataType(); + CDMRSlotType slotType; + slotType.setColorCode(m_colorCode); + slotType.setDataType(dataType); if (dataType == DT_VOICE_LC_HEADER) { if (m_rfState == RS_RF_AUDIO) @@ -150,17 +151,12 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len) unsigned int srcId = lc->getSrcId(); unsigned int dstId = lc->getDstId(); - if (!CDMRAccessControl::validateAccess(srcId, dstId, m_slotNo, false)) { + if (!CDMRAccessControl::validateId(srcId)) { + LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId); delete lc; return; } - unsigned int rewriteId = CDMRAccessControl::dstIdRewrite(dstId, srcId, m_slotNo, false, lc); - if (rewriteId != 0U) { - lc->setDstId(rewriteId); - dstId = rewriteId; - } - m_rfLC = lc; // Regenerate the LC data @@ -255,7 +251,6 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len) LogMessage("DMR Slot %u, received RF end of voice transmission, %.1f seconds, BER: %.1f%%", m_slotNo, float(m_rfFrames) / 16.667F, float(m_rfErrs * 100U) / float(m_rfBits)); writeEndRF(); - CDMRAccessControl::setOverEndTime(m_slotNo); } else if (dataType == DT_DATA_HEADER) { if (m_rfState == RS_RF_DATA) return; @@ -269,8 +264,10 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len) unsigned int srcId = dataHeader.getSrcId(); unsigned int dstId = dataHeader.getDstId(); - if (!CDMRAccessControl::validateAccess(srcId, dstId, m_slotNo, false)) - return; + if (!CDMRAccessControl::validateId(srcId)) { + LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId); + return; + } m_rfFrames = dataHeader.getBlocks(); @@ -326,8 +323,10 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len) unsigned int dstId = csbk.getDstId(); if (srcId != 0U || dstId != 0U) { - if (!CDMRAccessControl::validateAccess(srcId, dstId, m_slotNo, false)) + if (!CDMRAccessControl::validateId(srcId)) { + LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId); return; + } } // Regenerate the CSBK data @@ -480,17 +479,12 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len) unsigned int srcId = lc->getSrcId(); unsigned int dstId = lc->getDstId(); - if (!CDMRAccessControl::validateAccess(srcId, dstId, m_slotNo, false)) { - delete lc; + if (!CDMRAccessControl::validateId(srcId)) { + LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId); + delete lc; return; } - unsigned int rewriteId = CDMRAccessControl::dstIdRewrite(dstId, srcId, m_slotNo, false, lc); - if (rewriteId != 0U) { - lc->setDstId(rewriteId); - dstId = rewriteId; - } - m_rfLC = lc; // Create a dummy start frame to replace the received frame @@ -760,20 +754,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) unsigned int dstId = lc->getDstId(); unsigned int srcId = lc->getSrcId(); - if (!CDMRAccessControl::validateAccess(srcId, dstId, m_slotNo, true)) { - delete lc; - return; - } - m_netLC = lc; - // Test dst rewrite - unsigned int rewriteId = CDMRAccessControl::dstIdRewrite(dstId, srcId, m_slotNo, true, m_netLC); - if (rewriteId != 0U) { - m_netLC->setDstId(rewriteId); - dstId = rewriteId; - } - // Regenerate the LC data fullLC.encode(*m_netLC, data + 2U, DT_VOICE_LC_HEADER); @@ -832,20 +814,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) unsigned int dstId = lc->getDstId(); unsigned int srcId = lc->getSrcId(); - if (!CDMRAccessControl::validateAccess(srcId, dstId, m_slotNo, true)) { - delete lc; - return; - } - m_netLC = lc; - // Test dst rewrite - unsigned int rewriteId = CDMRAccessControl::dstIdRewrite(dstId, srcId, m_slotNo, true, m_netLC); - if (rewriteId != 0U) { - m_netLC->setDstId(rewriteId); - dstId = rewriteId; - } - m_lastFrameValid = false; m_netTimeoutTimer.start(); @@ -958,7 +928,6 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) LogMessage("DMR Slot %u, received network end of voice transmission, %.1f seconds, %u%% packet loss, BER: %.1f%%", m_slotNo, float(m_netFrames) / 16.667F, (m_netLost * 100U) / m_netFrames, float(m_netErrs * 100U) / float(m_netBits)); writeEndNet(); - CDMRAccessControl::setOverEndTime(m_slotNo); } else if (dataType == DT_DATA_HEADER) { if (m_netState == RS_NET_DATA) return; @@ -976,9 +945,6 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) unsigned int srcId = dataHeader.getSrcId(); unsigned int dstId = dataHeader.getDstId(); - if (!CDMRAccessControl::validateAccess(srcId, dstId, m_slotNo, true)) - return; - m_netFrames = dataHeader.getBlocks(); // Regenerate the data header @@ -1022,20 +988,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) unsigned int dstId = lc->getDstId(); unsigned int srcId = lc->getSrcId(); - if (!CDMRAccessControl::validateAccess(srcId, dstId, m_slotNo, true)) { - delete lc; - return; - } - m_netLC = lc; - // Test dst rewrite - unsigned int rewriteId = CDMRAccessControl::dstIdRewrite(dstId, srcId, m_slotNo, true, m_netLC); - if (rewriteId != 0U) { - m_netLC->setDstId(rewriteId); - dstId = rewriteId; - } - m_lastFrameValid = false; m_netTimeoutTimer.start(); @@ -1184,11 +1138,6 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData) unsigned int srcId = csbk.getSrcId(); unsigned int dstId = csbk.getDstId(); - if (srcId != 0U || dstId != 0U) { - if (!CDMRAccessControl::validateAccess(srcId, dstId, m_slotNo, true)) - return; - } - // Regenerate the CSBK data csbk.get(data + 2U); @@ -1408,11 +1357,12 @@ void CDMRSlot::writeQueueNet(const unsigned char *data) m_queue.addData(data, len); } -void CDMRSlot::init(unsigned int colorCode, unsigned int callHang, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter) +void CDMRSlot::init(unsigned int colorCode, unsigned int callHang, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter) { assert(modem != NULL); assert(display != NULL); assert(lookup != NULL); + assert(rssiMapper != NULL); m_colorCode = colorCode; m_modem = modem; @@ -1422,8 +1372,7 @@ void CDMRSlot::init(unsigned int colorCode, unsigned int callHang, CModem* modem m_lookup = lookup; m_hangCount = callHang * 17U; - m_rssiMultiplier = rssiMultiplier; - m_rssiOffset = rssiOffset; + m_rssiMapper = rssiMapper; m_jitterTime = jitter; m_jitterSlots = jitter / DMR_SLOT_TIME; diff --git a/DMRSlot.h b/DMRSlot.h index 667b5c8..42e1734 100644 --- a/DMRSlot.h +++ b/DMRSlot.h @@ -19,6 +19,7 @@ #if !defined(DMRSlot_H) #define DMRSlot_H +#include "RSSIInterpolator.h" #include "DMREmbeddedLC.h" #include "DMRDataHeader.h" #include "DMRNetwork.h" @@ -50,7 +51,7 @@ public: void clock(); - static void init(unsigned int colorCode, unsigned int callHang, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter); + static void init(unsigned int colorCode, unsigned int callHang, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter); private: unsigned int m_slotNo; @@ -95,8 +96,7 @@ private: static CDMRLookup* m_lookup; static unsigned int m_hangCount; - static int m_rssiMultiplier; - static int m_rssiOffset; + static CRSSIInterpolator* m_rssiMapper; static unsigned int m_jitterTime; static unsigned int m_jitterSlots; diff --git a/MMDVM.ini b/MMDVM.ini index fb50054..acb3f57 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -50,8 +50,7 @@ TXLevel=50 # YSFTXLevel=50 # P25TXLevel=50 OscOffset=0 -RSSIMultiplier=1 -RSSIOffset=10 +RSSIMappingFile=RSSI.dat Debug=0 [UMP] @@ -73,19 +72,6 @@ SelfOnly=0 # Prefixes=234,235 CallHang=3 TXHang=4 -#Blacklist= -#DstIdBlackListSlot1RF= -#DstIdBlackListSlot2RF= -#DstIdWhiteListSlot1RF= -#DstIdWhiteListSlot2RF= -#DstIdBlackListSlot1NET= -#DstIdBlackListSlot2NET= -#DstIdWhiteListSlot1NET= -#DstIdWhiteListSlot2NET= -TGRewriteSlot1=0 -TGRewriteSlot2=0 -BMAutoRewrite=0 -BMRewriteReflectorVoicePrompts=0 [System Fusion] Enable=1 diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 6b495db..ad976af 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -17,6 +17,7 @@ */ #include "MMDVMHost.h" +#include "RSSIInterpolator.h" #include "SerialController.h" #include "ModemSerialPort.h" #include "Version.h" @@ -331,28 +332,16 @@ int CMMDVMHost::run() CDMRControl* dmr = NULL; if (m_dmrEnabled) { - unsigned int id = m_conf.getDMRId(); - unsigned int colorCode = m_conf.getDMRColorCode(); - bool selfOnly = m_conf.getDMRSelfOnly(); - bool tgRewriteSlot1 = m_conf.getDMRTGRewriteSlot1(); - bool tgRewriteSlot2 = m_conf.getDMRTGRewriteSlot2(); - bool bmAutoRewrite = m_conf.getDMRBMAutoRewrite(); - bool bmRewriteReflectorVoicePrompts = m_conf.getDMRBMRewriteReflectorVoicePrompts(); + unsigned int id = m_conf.getDMRId(); + unsigned int colorCode = m_conf.getDMRColorCode(); + bool selfOnly = m_conf.getDMRSelfOnly(); std::vector prefixes = m_conf.getDMRPrefixes(); std::vector blackList = m_conf.getDMRBlackList(); - std::vector dstIDBlackListSlot1RF = m_conf.getDMRDstIdBlacklistSlot1RF(); - std::vector dstIDBlackListSlot2RF = m_conf.getDMRDstIdBlacklistSlot2RF(); - std::vector dstIDWhiteListSlot1RF = m_conf.getDMRDstIdWhitelistSlot1RF(); - std::vector dstIDWhiteListSlot2RF = m_conf.getDMRDstIdWhitelistSlot2RF(); - std::vector dstIDBlackListSlot1NET = m_conf.getDMRDstIdBlacklistSlot1NET(); - std::vector dstIDBlackListSlot2NET = m_conf.getDMRDstIdBlacklistSlot2NET(); - std::vector dstIDWhiteListSlot1NET = m_conf.getDMRDstIdWhitelistSlot1NET(); - std::vector dstIDWhiteListSlot2NET = m_conf.getDMRDstIdWhitelistSlot2NET(); - unsigned int callHang = m_conf.getDMRCallHang(); - unsigned int txHang = m_conf.getDMRTXHang(); - int rssiMultiplier = m_conf.getModemRSSIMultiplier(); - int rssiOffset = m_conf.getModemRSSIOffset(); - unsigned int jitter = m_conf.getDMRNetworkJitter(); + std::vector whiteList = m_conf.getDMRWhiteList(); + unsigned int callHang = m_conf.getDMRCallHang(); + unsigned int txHang = m_conf.getDMRTXHang(); + std::string rssiMappingFile = m_conf.getModemRSSIMappingFile(); + unsigned int jitter = m_conf.getDMRNetworkJitter(); if (txHang > m_rfModeHang) txHang = m_rfModeHang; @@ -370,41 +359,19 @@ int CMMDVMHost::run() if (blackList.size() > 0U) LogInfo(" Source ID Black List: %u", blackList.size()); - if (dstIDBlackListSlot1RF.size() > 0U) - LogInfo(" Slot 1 RF Destination ID Black List: %u entries", dstIDBlackListSlot1RF.size()); - if (dstIDBlackListSlot2RF.size() > 0U) - LogInfo(" Slot 2 RF Destination ID Black List: %u entries", dstIDBlackListSlot2RF.size()); - if (dstIDWhiteListSlot1RF.size() > 0U) - LogInfo(" Slot 1 RF Destination ID White List: %u entries", dstIDWhiteListSlot1RF.size()); - if (dstIDWhiteListSlot2RF.size() > 0U) - LogInfo(" Slot 2 RF Destination ID White List: %u entries", dstIDWhiteListSlot2RF.size()); - if (dstIDBlackListSlot1NET.size() > 0U) - LogInfo(" Slot 1 NET Destination ID Black List: %u entries", dstIDBlackListSlot1NET.size()); - if (dstIDBlackListSlot2NET.size() > 0U) - LogInfo(" Slot 2 NET Destination ID Black List: %u entries", dstIDBlackListSlot2NET.size()); - if (dstIDWhiteListSlot1NET.size() > 0U) - LogInfo(" Slot 1 NET Destination ID White List: %u entries", dstIDWhiteListSlot1NET.size()); - if (dstIDWhiteListSlot2NET.size() > 0U) - LogInfo(" Slot 2 NET Destination ID White List: %u entries", dstIDWhiteListSlot2NET.size()); - + if (whiteList.size() > 0U) + LogInfo(" Source ID White List: %u", whiteList.size()); + LogInfo(" Call Hang: %us", callHang); LogInfo(" TX Hang: %us", txHang); - if (rssiMultiplier != 0) { - LogInfo(" RSSI Multiplier: %d", rssiMultiplier); - LogInfo(" RSSI Offset: %d", rssiOffset); + CRSSIInterpolator* rssi = new CRSSIInterpolator; + if (!rssiMappingFile.empty()) { + LogInfo(" RSSI Mapping File: %s", rssiMappingFile.c_str()); + rssi->load(rssiMappingFile); } - - if (tgRewriteSlot1) - LogInfo(" TG Rewrite Slot 1 enabled"); - if (tgRewriteSlot2) - LogInfo(" TG Rewrite Slot 2 enabled"); - if (bmAutoRewrite) - LogInfo(" BrandMeister Auto Rewrite enabled"); - 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, m_lookup, rssiMultiplier, rssiOffset, jitter, tgRewriteSlot1, tgRewriteSlot2, bmAutoRewrite, bmRewriteReflectorVoicePrompts); + + dmr = new CDMRControl(id, colorCode, callHang, selfOnly, prefixes, blackList, whiteList, m_timeout, m_modem, m_dmrNetwork, m_display, m_duplex, m_lookup, rssi, jitter); m_dmrTXTimer.setTimeout(txHang); } diff --git a/MMDVMHost.vcxproj b/MMDVMHost.vcxproj index 1a43994..017e29c 100644 --- a/MMDVMHost.vcxproj +++ b/MMDVMHost.vcxproj @@ -197,6 +197,7 @@ + @@ -263,6 +264,7 @@ + diff --git a/MMDVMHost.vcxproj.filters b/MMDVMHost.vcxproj.filters index 476c322..814effb 100644 --- a/MMDVMHost.vcxproj.filters +++ b/MMDVMHost.vcxproj.filters @@ -218,6 +218,9 @@ Header Files + + Header Files + @@ -406,5 +409,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/Makefile b/Makefile index f41527f..9f5cb50 100644 --- a/Makefile +++ b/Makefile @@ -10,8 +10,8 @@ OBJECTS = \ AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \ DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ Golay24128.o Hamming.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \ - P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o \ - UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \ + Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi b/Makefile.Pi index 771e62c..8c8db64 100644 --- a/Makefile.Pi +++ b/Makefile.Pi @@ -10,8 +10,8 @@ OBJECTS = \ AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \ DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ Golay24128.o Hamming.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \ - P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o \ - UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \ + Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.Adafruit b/Makefile.Pi.Adafruit index cbab68a..92becf2 100644 --- a/Makefile.Pi.Adafruit +++ b/Makefile.Pi.Adafruit @@ -10,8 +10,8 @@ OBJECTS = \ AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \ DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ Golay24128.o Hamming.o HD44780.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o \ - P25LowSpeedData.o P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \ - Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + P25LowSpeedData.o P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o \ + TFTSerial.o Thread.o Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.HD44780 b/Makefile.Pi.HD44780 index d52cf36..90e359b 100644 --- a/Makefile.Pi.HD44780 +++ b/Makefile.Pi.HD44780 @@ -10,8 +10,8 @@ OBJECTS = \ AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \ DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ Golay24128.o Hamming.o HD44780.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \ - P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o \ - UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \ + Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.OLED b/Makefile.Pi.OLED index 0c3fc9b..dd51474 100644 --- a/Makefile.Pi.OLED +++ b/Makefile.Pi.OLED @@ -10,8 +10,8 @@ OBJECTS = \ AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \ DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ Golay24128.o Hamming.o OLED.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \ - P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o \ - UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \ + Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Pi.PCF8574 b/Makefile.Pi.PCF8574 index 6d432c7..b9607bf 100644 --- a/Makefile.Pi.PCF8574 +++ b/Makefile.Pi.PCF8574 @@ -10,8 +10,8 @@ OBJECTS = \ AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \ DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ Golay24128.o Hamming.o HD44780.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \ - P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o \ - UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \ + Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/Makefile.Solaris b/Makefile.Solaris index d64df30..7e5b5d0 100644 --- a/Makefile.Solaris +++ b/Makefile.Solaris @@ -10,8 +10,8 @@ OBJECTS = \ AMBEFEC.o BCH.o BPTC19696.o Conf.o CRC.o Display.o DMRControl.o DMRCSBK.o DMRData.o DMRDataHeader.o DMREMB.o DMREmbeddedLC.o DMRFullLC.o DMRLookup.o DMRLC.o \ DMRNetwork.o DMRShortLC.o DMRSlot.o DMRSlotType.o DMRAccessControl.o DMRTrellis.o DStarControl.o DStarHeader.o DStarNetwork.o DStarSlowData.o Golay2087.o \ Golay24128.o Hamming.o LCDproc.o Log.o MMDVMHost.o Modem.o ModemSerialPort.o Mutex.o Nextion.o NullDisplay.o P25Audio.o P25Control.o P25Data.o P25LowSpeedData.o \ - P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o Timer.o UDPSocket.o \ - UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o + P25Network.o P25NID.o P25Utils.o QR1676.o RS129.o RS241213.o RSSIInterpolator.o SerialController.o SerialPort.o SHA256.o StopWatch.o Sync.o TFTSerial.o Thread.o \ + Timer.o UDPSocket.o UMP.o Utils.o YSFControl.o YSFConvolution.o YSFFICH.o YSFNetwork.o YSFPayload.o all: MMDVMHost diff --git a/RSSI.dat b/RSSI.dat new file mode 100644 index 0000000..096ae87 --- /dev/null +++ b/RSSI.dat @@ -0,0 +1,11 @@ +# This file maps the raw RSSI values to dBm values to send to the DMR network. A number of data +# points should be entered and the software will use those to work out the in-between values. +# +# The format of the file is: +# Raw RSSI Value dBm Value +# +# For example +# 1134 -90 +# 1123 -100 +# 1000 -109 +# diff --git a/RSSIInterpolator.cpp b/RSSIInterpolator.cpp new file mode 100644 index 0000000..3d6eb06 --- /dev/null +++ b/RSSIInterpolator.cpp @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2016 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 "RSSIInterpolator.h" + +#include "Log.h" + +#include +#include +#include +#include + +CRSSIInterpolator::CRSSIInterpolator() : +m_map() +{ +} + +CRSSIInterpolator::~CRSSIInterpolator() +{ + m_map.clear(); +} + +bool CRSSIInterpolator::load(const std::string& filename) +{ + FILE* fp = ::fopen(filename.c_str(), "rt"); + if (fp == NULL) { + LogWarning("Cannot open the RSSI data file - %s", filename.c_str()); + return false; + } + + char buffer[100U]; + while (::fgets(buffer, 100, 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) { + uint16_t raw = uint16_t(::atoi(p1)); + int rssi = ::atoi(p2); + m_map.insert(std::pair(raw, rssi)); + } + } + + ::fclose(fp); + + LogInfo("Loaded %u RSSI data mapping points from %s", m_map.size(), filename.c_str()); + + return true; +} + +int CRSSIInterpolator::interpolate(uint16_t val) const +{ + if (m_map.empty()) + return 0; + + std::map::const_iterator it = m_map.lower_bound(val); + + if (it == m_map.end()) + return m_map.rbegin()->second; + + if (it == m_map.begin()) + return it->second; + + unsigned int x2 = it->first; + int y2 = it->second; + + --it; + unsigned int x1 = it->first; + int y1 = it->second; + + float p = float(val - x1) / float(x2 - x1); + + return int((1.0F - p) * float(y1) + p * float(y2)); +} diff --git a/RSSIInterpolator.h b/RSSIInterpolator.h new file mode 100644 index 0000000..ac1d4ad --- /dev/null +++ b/RSSIInterpolator.h @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2016 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(RSSIINTERPOLATOR_H) +#define RSSIINTERPOLATOR_H + +#include +#include +#include + +class CRSSIInterpolator { +public: + CRSSIInterpolator(); + ~CRSSIInterpolator(); + + bool load(const std::string& filename); + + int interpolate(uint16_t raw) const; + +private: + std::map m_map; +}; + +#endif