diff --git a/Conf.cpp b/Conf.cpp index 966adff..a9261e8 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -79,6 +79,7 @@ m_dmrBeacons(false), m_dmrId(0U), m_dmrColorCode(2U), m_dmrSelfOnly(false), +m_dmrPrefixes(), m_fusionEnabled(true), m_fusionParrotEnabled(false), m_dstarNetworkEnabled(true), @@ -238,6 +239,15 @@ bool CConf::read() m_dmrColorCode = (unsigned int)::atoi(value); else if (::strcmp(key, "SelfOnly") == 0) m_dmrSelfOnly = ::atoi(value) == 1; + else if (::strcmp(key, "Prefixes") == 0) { + char* p = ::strtok(value, ",\r\n"); + while (p != NULL) { + unsigned int prefix = (unsigned int)::atoi(p); + if (prefix > 0U && prefix <= 999U) + m_dmrPrefixes.push_back(prefix); + p = ::strtok(NULL, ",\r\n"); + } + } } else if (section == SECTION_FUSION) { if (::strcmp(key, "Enable") == 0) m_fusionEnabled = ::atoi(value) == 1; @@ -478,6 +488,11 @@ bool CConf::getDMRSelfOnly() const return m_dmrSelfOnly; } +std::vector CConf::getDMRPrefixes() const +{ + return m_dmrPrefixes; +} + bool CConf::getFusionEnabled() const { return m_fusionEnabled; diff --git a/Conf.h b/Conf.h index 0cdbfb5..83c5469 100644 --- a/Conf.h +++ b/Conf.h @@ -20,6 +20,7 @@ #define CONF_H #include +#include class CConf { @@ -76,6 +77,7 @@ public: unsigned int getDMRId() const; unsigned int getDMRColorCode() const; bool getDMRSelfOnly() const; + std::vector getDMRPrefixes() const; // The System Fusion section bool getFusionEnabled() const; @@ -155,6 +157,7 @@ private: unsigned int m_dmrId; unsigned int m_dmrColorCode; bool m_dmrSelfOnly; + std::vector m_dmrPrefixes; bool m_fusionEnabled; bool m_fusionParrotEnabled; diff --git a/DMRControl.cpp b/DMRControl.cpp index 48b5ccf..beee854 100644 --- a/DMRControl.cpp +++ b/DMRControl.cpp @@ -19,10 +19,11 @@ #include #include -CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, bool selfOnly, unsigned int timeout, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex) : +CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, unsigned int timeout, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex) : m_id(id), m_colorCode(colorCode), m_selfOnly(selfOnly), +m_prefixes(prefixes), m_modem(modem), m_network(network), m_slot1(1U, timeout), @@ -31,7 +32,7 @@ m_slot2(2U, timeout) assert(modem != NULL); assert(display != NULL); - CDMRSlot::init(id, colorCode, selfOnly, modem, network, display, duplex); + CDMRSlot::init(id, colorCode, selfOnly, prefixes, modem, network, display, duplex); } CDMRControl::~CDMRControl() @@ -58,22 +59,42 @@ bool CDMRControl::processWakeup(const unsigned char* data) unsigned int srcId = csbk.getSrcId(); unsigned int bsId = csbk.getBSId(); + if (m_selfOnly) { + if (srcId != m_id) { + LogMessage("Invalid CSBK BS_Dwn_Act received from %u", srcId); + return false; + } + } else { + unsigned int prefix = srcId / 10000U; + if (prefix == 0U || prefix > 999U) { + LogMessage("Invalid CSBK BS_Dwn_Act received from %u", srcId); + return false; + } + + bool found = false; + + if (m_prefixes.size() == 0U) + found = true; + + for (std::vector::const_iterator it = m_prefixes.begin(); it != m_prefixes.end(); ++it) { + if (prefix == *it) { + found = true; + break; + } + } + + if (!found) { + LogMessage("Invalid CSBK BS_Dwn_Act received from %u", srcId); + return false; + } + } + if (bsId == 0xFFFFFFU) { - if (m_selfOnly && srcId != m_id) { - LogMessage("Invalid CSBK BS_Dwn_Act for ANY received from %u", srcId); - return false; - } else { - LogMessage("CSBK BS_Dwn_Act for ANY received from %u", srcId); - return true; - } + LogMessage("CSBK BS_Dwn_Act for ANY received from %u", srcId); + return true; } else if (bsId == m_id) { - if (m_selfOnly && srcId != m_id) { - LogMessage("Invalid CSBK BS_Dwn_Act for %u received from %u", bsId, srcId); - return false; - } else { - LogMessage("CSBK BS_Dwn_Act for %u received from %u", bsId, srcId); - return true; - } + LogMessage("CSBK BS_Dwn_Act for %u received from %u", bsId, srcId); + return true; } return false; diff --git a/DMRControl.h b/DMRControl.h index d6a0e8d..711aed8 100644 --- a/DMRControl.h +++ b/DMRControl.h @@ -25,10 +25,11 @@ #include "DMRData.h" #include "Modem.h" +#include class CDMRControl { public: - CDMRControl(unsigned int id, unsigned int colorCode, bool selfOnly, unsigned int timeout, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex); + CDMRControl(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, unsigned int timeout, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex); ~CDMRControl(); bool processWakeup(const unsigned char* data); @@ -45,6 +46,7 @@ private: unsigned int m_id; unsigned int m_colorCode; bool m_selfOnly; + std::vector m_prefixes; CModem* m_modem; CDMRIPSC* m_network; CDMRSlot m_slot1; diff --git a/DMRSlot.cpp b/DMRSlot.cpp index 947590b..04783a6 100644 --- a/DMRSlot.cpp +++ b/DMRSlot.cpp @@ -29,6 +29,7 @@ unsigned int CDMRSlot::m_id = 0U; unsigned int CDMRSlot::m_colorCode = 0U; bool CDMRSlot::m_selfOnly = false; +std::vector CDMRSlot::m_prefixes; CModem* CDMRSlot::m_modem = NULL; CDMRIPSC* CDMRSlot::m_network = NULL; IDisplay* CDMRSlot::m_display = NULL; @@ -131,8 +132,7 @@ void CDMRSlot::writeModem(unsigned char *data) } unsigned int id = lc->getSrcId(); - - if (m_selfOnly && id != m_id) { + if (!validateId(id)) { LogMessage("DMR Slot %u, invalid access atemmpt from %u", m_slotNo, id); delete lc; return; @@ -242,7 +242,7 @@ void CDMRSlot::writeModem(unsigned char *data) unsigned int srcId = dataHeader.getSrcId(); unsigned int dstId = dataHeader.getDstId(); - if (m_selfOnly && srcId != m_id) { + if (!validateId(srcId)) { LogMessage("DMR Slot %u, invalid access atemmpt from %u", m_slotNo, srcId); return; } @@ -300,7 +300,7 @@ void CDMRSlot::writeModem(unsigned char *data) unsigned int srcId = csbk.getSrcId(); unsigned int dstId = csbk.getDstId(); - if (m_selfOnly && srcId != m_id) { + if (!validateId(srcId)) { LogMessage("DMR Slot %u, invalid access atemmpt from %u", m_slotNo, srcId); return; } @@ -480,7 +480,7 @@ void CDMRSlot::writeModem(unsigned char *data) CDMRLC* lc = m_rfEmbeddedLC.addData(data + 2U, emb.getLCSS()); if (lc != NULL) { unsigned int id = lc->getSrcId(); - if (m_selfOnly && id != m_id) { + if (!validateId(id)) { LogMessage("DMR Slot %u, invalid access atemmpt from %u", m_slotNo, id); delete lc; return; @@ -1227,7 +1227,7 @@ void CDMRSlot::writeQueueNet(const unsigned char *data) m_queue.addData(data, len); } -void CDMRSlot::init(unsigned int id, unsigned int colorCode, bool selfOnly, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex) +void CDMRSlot::init(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex) { assert(id != 0U); assert(modem != NULL); @@ -1236,6 +1236,7 @@ void CDMRSlot::init(unsigned int id, unsigned int colorCode, bool selfOnly, CMod m_id = id; m_colorCode = colorCode; m_selfOnly = selfOnly; + m_prefixes = prefixes; m_modem = modem; m_network = network; m_display = display; @@ -1252,6 +1253,27 @@ void CDMRSlot::init(unsigned int id, unsigned int colorCode, bool selfOnly, CMod slotType.getData(m_idle + 2U); } +bool CDMRSlot::validateId(unsigned int id) +{ + if (m_selfOnly) { + return id == m_id; + } else { + unsigned int prefix = id / 10000U; + if (prefix == 0U || prefix > 999U) + return false; + + if (m_prefixes.size() == 0U) + return true; + + for (std::vector::const_iterator it = m_prefixes.begin(); it != m_prefixes.end(); ++it) { + if (prefix == *it) + return true; + } + + return false; + } +} + void CDMRSlot::setShortLC(unsigned int slotNo, unsigned int id, FLCO flco, bool voice) { assert(m_modem != NULL); diff --git a/DMRSlot.h b/DMRSlot.h index 83fe63e..9cb2f65 100644 --- a/DMRSlot.h +++ b/DMRSlot.h @@ -34,6 +34,8 @@ #include "Modem.h" #include "DMRLC.h" +#include + class CDMRSlot { public: CDMRSlot(unsigned int slotNo, unsigned int timeout); @@ -47,7 +49,7 @@ public: void clock(); - static void init(unsigned int id, unsigned int colorCode, bool selfOnly, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex); + static void init(unsigned int id, unsigned int colorCode, bool selfOnly, const std::vector& prefixes, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex); private: unsigned int m_slotNo; @@ -85,6 +87,7 @@ private: static unsigned int m_id; static unsigned int m_colorCode; static bool m_selfOnly; + static std::vector m_prefixes; static CModem* m_modem; static CDMRIPSC* m_network; static IDisplay* m_display; @@ -115,6 +118,7 @@ private: void insertSilence(unsigned int count); static void setShortLC(unsigned int slotNo, unsigned int id, FLCO flco = FLCO_GROUP, bool voice = true); + static bool validateId(unsigned int id); }; #endif diff --git a/MMDVM.ini b/MMDVM.ini index c37aeb2..202fd66 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -47,6 +47,7 @@ Beacons=1 Id=123456 ColorCode=1 SelfOnly=0 +Prefixes=234,235 [System Fusion] Enable=1 diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 81e5919..d7d4579 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -32,6 +32,7 @@ #endif #include +#include #if !defined(_WIN32) && !defined(_WIN64) #include @@ -161,15 +162,17 @@ int CMMDVMHost::run() unsigned int id = m_conf.getDMRId(); unsigned int colorCode = m_conf.getDMRColorCode(); bool selfOnly = m_conf.getDMRSelfOnly(); + std::vector prefixes = m_conf.getDMRPrefixes(); unsigned int timeout = m_conf.getTimeout(); LogInfo("DMR Parameters"); LogInfo(" Id: %u", id); LogInfo(" Color Code: %u", colorCode); LogInfo(" Self Only: %s", selfOnly ? "yes" : "no"); + LogInfo(" Prefixes: %u", prefixes.size()); LogInfo(" Timeout: %us", timeout); - dmr = new CDMRControl(id, colorCode, selfOnly, timeout, m_modem, m_dmrNetwork, m_display, m_duplex); + dmr = new CDMRControl(id, colorCode, selfOnly, prefixes, timeout, m_modem, m_dmrNetwork, m_display, m_duplex); } CYSFControl* ysf = NULL;