From ea51eee15cffc118bbb32f61b6afb2b62e3acf6b Mon Sep 17 00:00:00 2001 From: Jonathan Naylor Date: Mon, 4 Apr 2016 17:40:05 +0100 Subject: [PATCH] Allow for locking the MMDVM to the callsign or id of the repeater/hostspot. --- Conf.cpp | 16 ++++++++++++++ Conf.h | 4 ++++ DMRControl.cpp | 27 +++++++++++++++++------ DMRControl.h | 3 ++- DMRSlot.cpp | 56 ++++++++++++++++++++++++++++++++++++++---------- DMRSlot.h | 4 +++- DStarControl.cpp | 14 ++++++++---- DStarControl.h | 3 ++- MMDVM.ini | 2 ++ MMDVMHost.cpp | 9 ++++++-- 10 files changed, 111 insertions(+), 27 deletions(-) diff --git a/Conf.cpp b/Conf.cpp index ace7a0f..966adff 100644 --- a/Conf.cpp +++ b/Conf.cpp @@ -73,10 +73,12 @@ m_modemOscOffset(0), m_modemDebug(false), m_dstarEnabled(true), m_dstarModule("C"), +m_dstarSelfOnly(false), m_dmrEnabled(true), m_dmrBeacons(false), m_dmrId(0U), m_dmrColorCode(2U), +m_dmrSelfOnly(false), m_fusionEnabled(true), m_fusionParrotEnabled(false), m_dstarNetworkEnabled(true), @@ -223,6 +225,8 @@ bool CConf::read() m_dstarEnabled = ::atoi(value) == 1; else if (::strcmp(key, "Module") == 0) m_dstarModule = value; + else if (::strcmp(key, "SelfOnly") == 0) + m_dstarSelfOnly = ::atoi(value) == 1; } else if (section == SECTION_DMR) { if (::strcmp(key, "Enable") == 0) m_dmrEnabled = ::atoi(value) == 1; @@ -232,6 +236,8 @@ bool CConf::read() m_dmrId = (unsigned int)::atoi(value); else if (::strcmp(key, "ColorCode") == 0) m_dmrColorCode = (unsigned int)::atoi(value); + else if (::strcmp(key, "SelfOnly") == 0) + m_dmrSelfOnly = ::atoi(value) == 1; } else if (section == SECTION_FUSION) { if (::strcmp(key, "Enable") == 0) m_fusionEnabled = ::atoi(value) == 1; @@ -442,6 +448,11 @@ std::string CConf::getDStarModule() const return m_dstarModule; } +bool CConf::getDStarSelfOnly() const +{ + return m_dstarSelfOnly; +} + bool CConf::getDMREnabled() const { return m_dmrEnabled; @@ -462,6 +473,11 @@ unsigned int CConf::getDMRColorCode() const return m_dmrColorCode; } +bool CConf::getDMRSelfOnly() const +{ + return m_dmrSelfOnly; +} + bool CConf::getFusionEnabled() const { return m_fusionEnabled; diff --git a/Conf.h b/Conf.h index c385cb1..0cdbfb5 100644 --- a/Conf.h +++ b/Conf.h @@ -68,12 +68,14 @@ public: // The D-Star section bool getDStarEnabled() const; std::string getDStarModule() const; + bool getDStarSelfOnly() const; // The DMR section bool getDMREnabled() const; bool getDMRBeacons() const; unsigned int getDMRId() const; unsigned int getDMRColorCode() const; + bool getDMRSelfOnly() const; // The System Fusion section bool getFusionEnabled() const; @@ -146,11 +148,13 @@ private: bool m_dstarEnabled; std::string m_dstarModule; + bool m_dstarSelfOnly; bool m_dmrEnabled; bool m_dmrBeacons; unsigned int m_dmrId; unsigned int m_dmrColorCode; + bool m_dmrSelfOnly; bool m_fusionEnabled; bool m_fusionParrotEnabled; diff --git a/DMRControl.cpp b/DMRControl.cpp index 66077c9..48b5ccf 100644 --- a/DMRControl.cpp +++ b/DMRControl.cpp @@ -19,9 +19,10 @@ #include #include -CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int timeout, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex) : +CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, bool selfOnly, unsigned int timeout, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex) : m_id(id), m_colorCode(colorCode), +m_selfOnly(selfOnly), m_modem(modem), m_network(network), m_slot1(1U, timeout), @@ -30,7 +31,7 @@ m_slot2(2U, timeout) assert(modem != NULL); assert(display != NULL); - CDMRSlot::init(colorCode, modem, network, display, duplex); + CDMRSlot::init(id, colorCode, selfOnly, modem, network, display, duplex); } CDMRControl::~CDMRControl() @@ -54,13 +55,25 @@ bool CDMRControl::processWakeup(const unsigned char* data) if (csbko != CSBKO_BSDWNACT) return false; - unsigned int bsId = csbk.getBSId(); + unsigned int srcId = csbk.getSrcId(); + unsigned int bsId = csbk.getBSId(); + if (bsId == 0xFFFFFFU) { - LogMessage("CSBK BS_Dwn_Act for ANY received from %u", csbk.getSrcId()); - return true; + 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; + } } else if (bsId == m_id) { - LogMessage("CSBK BS_Dwn_Act for %u received from %u", bsId, csbk.getSrcId()); - return true; + 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; + } } return false; diff --git a/DMRControl.h b/DMRControl.h index 4a94dbf..d6a0e8d 100644 --- a/DMRControl.h +++ b/DMRControl.h @@ -28,7 +28,7 @@ class CDMRControl { public: - CDMRControl(unsigned int id, unsigned int colorCode, unsigned int timeout, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex); + CDMRControl(unsigned int id, unsigned int colorCode, bool selfOnly, unsigned int timeout, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex); ~CDMRControl(); bool processWakeup(const unsigned char* data); @@ -44,6 +44,7 @@ public: private: unsigned int m_id; unsigned int m_colorCode; + bool m_selfOnly; CModem* m_modem; CDMRIPSC* m_network; CDMRSlot m_slot1; diff --git a/DMRSlot.cpp b/DMRSlot.cpp index 28c4022..947590b 100644 --- a/DMRSlot.cpp +++ b/DMRSlot.cpp @@ -26,7 +26,9 @@ #include #include +unsigned int CDMRSlot::m_id = 0U; unsigned int CDMRSlot::m_colorCode = 0U; +bool CDMRSlot::m_selfOnly = false; CModem* CDMRSlot::m_modem = NULL; CDMRIPSC* CDMRSlot::m_network = NULL; IDisplay* CDMRSlot::m_display = NULL; @@ -122,12 +124,22 @@ void CDMRSlot::writeModem(unsigned char *data) return; CDMRFullLC fullLC; - m_rfLC = fullLC.decode(data + 2U, DT_VOICE_LC_HEADER); - if (m_rfLC == NULL) { + CDMRLC* lc = fullLC.decode(data + 2U, DT_VOICE_LC_HEADER); + if (lc == NULL) { LogMessage("DMR Slot %u, unable to decode the RF LC", m_slotNo); return; } + unsigned int id = lc->getSrcId(); + + if (m_selfOnly && id != m_id) { + LogMessage("DMR Slot %u, invalid access atemmpt from %u", m_slotNo, id); + delete lc; + return; + } + + m_rfLC = lc; + // Store the LC for the embedded LC m_rfEmbeddedLC.setData(*m_rfLC); @@ -161,10 +173,10 @@ void CDMRSlot::writeModem(unsigned char *data) if (m_netState == RS_NET_IDLE) { setShortLC(m_slotNo, m_rfLC->getDstId(), m_rfLC->getFLCO(), true); - m_display->writeDMR(m_slotNo, m_rfLC->getSrcId(), m_rfLC->getFLCO() == FLCO_GROUP, m_rfLC->getDstId(), "R"); + m_display->writeDMR(m_slotNo, id, m_rfLC->getFLCO() == FLCO_GROUP, m_rfLC->getDstId(), "R"); } - LogMessage("DMR Slot %u, received RF voice header from %u to %s%u", m_slotNo, m_rfLC->getSrcId(), m_rfLC->getFLCO() == FLCO_GROUP ? "TG " : "", m_rfLC->getDstId()); + LogMessage("DMR Slot %u, received RF voice header from %u to %s%u", m_slotNo, id, m_rfLC->getFLCO() == FLCO_GROUP ? "TG " : "", m_rfLC->getDstId()); } else if (dataType == DT_VOICE_PI_HEADER) { if (m_rfState != RS_RF_AUDIO) return; @@ -226,6 +238,15 @@ void CDMRSlot::writeModem(unsigned char *data) return; } + bool gi = dataHeader.getGI(); + unsigned int srcId = dataHeader.getSrcId(); + unsigned int dstId = dataHeader.getDstId(); + + if (m_selfOnly && srcId != m_id) { + LogMessage("DMR Slot %u, invalid access atemmpt from %u", m_slotNo, srcId); + return; + } + m_rfFrames = dataHeader.getBlocks(); if (m_rfFrames == 0U) { LogMessage("DMR Slot %u, unknown RF data header type, no block count information found", m_slotNo); @@ -234,10 +255,6 @@ void CDMRSlot::writeModem(unsigned char *data) m_rfDataHeader = dataHeader; - bool gi = dataHeader.getGI(); - unsigned int srcId = dataHeader.getSrcId(); - unsigned int dstId = dataHeader.getDstId(); - m_rfSeqNo = 0U; m_rfLC = new CDMRLC(gi ? FLCO_GROUP : FLCO_USER_USER, srcId, dstId); @@ -283,6 +300,11 @@ void CDMRSlot::writeModem(unsigned char *data) unsigned int srcId = csbk.getSrcId(); unsigned int dstId = csbk.getDstId(); + if (m_selfOnly && srcId != m_id) { + LogMessage("DMR Slot %u, invalid access atemmpt from %u", m_slotNo, srcId); + return; + } + // Regenerate the CSBK data csbk.get(data + 2U); @@ -455,8 +477,17 @@ void CDMRSlot::writeModem(unsigned char *data) if (colorCode != m_colorCode) return; - m_rfLC = m_rfEmbeddedLC.addData(data + 2U, emb.getLCSS()); - if (m_rfLC != NULL) { + CDMRLC* lc = m_rfEmbeddedLC.addData(data + 2U, emb.getLCSS()); + if (lc != NULL) { + unsigned int id = lc->getSrcId(); + if (m_selfOnly && id != m_id) { + LogMessage("DMR Slot %u, invalid access atemmpt from %u", m_slotNo, id); + delete lc; + return; + } + + m_rfLC = lc; + // Store the LC for the embedded LC m_rfEmbeddedLC.setData(*m_rfLC); @@ -1196,12 +1227,15 @@ void CDMRSlot::writeQueueNet(const unsigned char *data) m_queue.addData(data, len); } -void CDMRSlot::init(unsigned int colorCode, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex) +void CDMRSlot::init(unsigned int id, unsigned int colorCode, bool selfOnly, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex) { + assert(id != 0U); assert(modem != NULL); assert(display != NULL); + m_id = id; m_colorCode = colorCode; + m_selfOnly = selfOnly; m_modem = modem; m_network = network; m_display = display; diff --git a/DMRSlot.h b/DMRSlot.h index 23fda24..83fe63e 100644 --- a/DMRSlot.h +++ b/DMRSlot.h @@ -47,7 +47,7 @@ public: void clock(); - static void init(unsigned int colorCode, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex); + static void init(unsigned int id, unsigned int colorCode, bool selfOnly, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex); private: unsigned int m_slotNo; @@ -82,7 +82,9 @@ private: CDMREMB m_lastEMB; FILE* m_fp; + static unsigned int m_id; static unsigned int m_colorCode; + static bool m_selfOnly; static CModem* m_modem; static CDMRIPSC* m_network; static IDisplay* m_display; diff --git a/DStarControl.cpp b/DStarControl.cpp index ae75a1f..ca4fbb7 100644 --- a/DStarControl.cpp +++ b/DStarControl.cpp @@ -24,9 +24,10 @@ const unsigned int MAX_SYNC_BIT_ERRORS = 2U; // #define DUMP_DSTAR -CDStarControl::CDStarControl(const std::string& callsign, const std::string& module, CDStarNetwork* network, IDisplay* display, unsigned int timeout, bool duplex) : +CDStarControl::CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, CDStarNetwork* network, IDisplay* display, unsigned int timeout, bool duplex) : m_callsign(NULL), m_gateway(NULL), +m_selfOnly(selfOnly), m_network(network), m_display(display), m_duplex(duplex), @@ -118,6 +119,14 @@ bool CDStarControl::writeModem(unsigned char *data) return false; } + unsigned char my1[DSTAR_LONG_CALLSIGN_LENGTH]; + header.getMyCall1(my1); + + if (m_selfOnly && ::memcmp(my1, m_callsign, DSTAR_LONG_CALLSIGN_LENGTH - 1U) != 0) { + LogMessage("D-Star, invalid access attempt from %8.8s", my1); + return false; + } + unsigned char callsign[DSTAR_LONG_CALLSIGN_LENGTH]; header.getRPTCall1(callsign); @@ -130,9 +139,6 @@ bool CDStarControl::writeModem(unsigned char *data) unsigned char gateway[DSTAR_LONG_CALLSIGN_LENGTH]; header.getRPTCall2(gateway); - unsigned char my1[DSTAR_LONG_CALLSIGN_LENGTH]; - header.getMyCall1(my1); - unsigned char my2[DSTAR_SHORT_CALLSIGN_LENGTH]; header.getMyCall2(my2); diff --git a/DStarControl.h b/DStarControl.h index 90966d5..3036af0 100644 --- a/DStarControl.h +++ b/DStarControl.h @@ -35,7 +35,7 @@ class CDStarControl { public: - CDStarControl(const std::string& callsign, const std::string& module, CDStarNetwork* network, IDisplay* display, unsigned int timeout, bool duplex); + CDStarControl(const std::string& callsign, const std::string& module, bool selfOnly, CDStarNetwork* network, IDisplay* display, unsigned int timeout, bool duplex); ~CDStarControl(); bool writeModem(unsigned char* data); @@ -47,6 +47,7 @@ public: private: unsigned char* m_callsign; unsigned char* m_gateway; + bool m_selfOnly; CDStarNetwork* m_network; IDisplay* m_display; bool m_duplex; diff --git a/MMDVM.ini b/MMDVM.ini index 40bd15e..c37aeb2 100644 --- a/MMDVM.ini +++ b/MMDVM.ini @@ -39,12 +39,14 @@ Debug=0 [D-Star] Enable=1 Module=C +SelfOnly=0 [DMR] Enable=1 Beacons=1 Id=123456 ColorCode=1 +SelfOnly=0 [System Fusion] Enable=1 diff --git a/MMDVMHost.cpp b/MMDVMHost.cpp index 4fea953..81e5919 100644 --- a/MMDVMHost.cpp +++ b/MMDVMHost.cpp @@ -143,28 +143,33 @@ int CMMDVMHost::run() if (m_dstarEnabled) { std::string callsign = m_conf.getCallsign(); std::string module = m_conf.getDStarModule(); + bool selfOnly = m_conf.getDStarSelfOnly(); unsigned int timeout = m_conf.getTimeout(); LogInfo("D-Star Parameters"); LogInfo(" Callsign: %s", callsign.c_str()); LogInfo(" Module: %s", module.c_str()); + LogInfo(" Self Only: %s", selfOnly ? "yes" : "no"); LogInfo(" Timeout: %us", timeout); - dstar = new CDStarControl(callsign, module, m_dstarNetwork, m_display, timeout, m_duplex); + + dstar = new CDStarControl(callsign, module, selfOnly, m_dstarNetwork, m_display, timeout, m_duplex); } CDMRControl* dmr = NULL; if (m_dmrEnabled) { unsigned int id = m_conf.getDMRId(); unsigned int colorCode = m_conf.getDMRColorCode(); + bool selfOnly = m_conf.getDMRSelfOnly(); 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(" Timeout: %us", timeout); - dmr = new CDMRControl(id, colorCode, timeout, m_modem, m_dmrNetwork, m_display, m_duplex); + dmr = new CDMRControl(id, colorCode, selfOnly, timeout, m_modem, m_dmrNetwork, m_display, m_duplex); } CYSFControl* ysf = NULL;