Add DMR prefix checking.

This commit is contained in:
Jonathan Naylor 2016-04-04 19:03:38 +01:00
parent ea51eee15c
commit a2130421a9
8 changed files with 96 additions and 25 deletions

View file

@ -79,6 +79,7 @@ m_dmrBeacons(false),
m_dmrId(0U), m_dmrId(0U),
m_dmrColorCode(2U), m_dmrColorCode(2U),
m_dmrSelfOnly(false), m_dmrSelfOnly(false),
m_dmrPrefixes(),
m_fusionEnabled(true), m_fusionEnabled(true),
m_fusionParrotEnabled(false), m_fusionParrotEnabled(false),
m_dstarNetworkEnabled(true), m_dstarNetworkEnabled(true),
@ -238,6 +239,15 @@ bool CConf::read()
m_dmrColorCode = (unsigned int)::atoi(value); m_dmrColorCode = (unsigned int)::atoi(value);
else if (::strcmp(key, "SelfOnly") == 0) else if (::strcmp(key, "SelfOnly") == 0)
m_dmrSelfOnly = ::atoi(value) == 1; 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) { } else if (section == SECTION_FUSION) {
if (::strcmp(key, "Enable") == 0) if (::strcmp(key, "Enable") == 0)
m_fusionEnabled = ::atoi(value) == 1; m_fusionEnabled = ::atoi(value) == 1;
@ -478,6 +488,11 @@ bool CConf::getDMRSelfOnly() const
return m_dmrSelfOnly; return m_dmrSelfOnly;
} }
std::vector<unsigned int> CConf::getDMRPrefixes() const
{
return m_dmrPrefixes;
}
bool CConf::getFusionEnabled() const bool CConf::getFusionEnabled() const
{ {
return m_fusionEnabled; return m_fusionEnabled;

3
Conf.h
View file

@ -20,6 +20,7 @@
#define CONF_H #define CONF_H
#include <string> #include <string>
#include <vector>
class CConf class CConf
{ {
@ -76,6 +77,7 @@ public:
unsigned int getDMRId() const; unsigned int getDMRId() const;
unsigned int getDMRColorCode() const; unsigned int getDMRColorCode() const;
bool getDMRSelfOnly() const; bool getDMRSelfOnly() const;
std::vector<unsigned int> getDMRPrefixes() const;
// The System Fusion section // The System Fusion section
bool getFusionEnabled() const; bool getFusionEnabled() const;
@ -155,6 +157,7 @@ private:
unsigned int m_dmrId; unsigned int m_dmrId;
unsigned int m_dmrColorCode; unsigned int m_dmrColorCode;
bool m_dmrSelfOnly; bool m_dmrSelfOnly;
std::vector<unsigned int> m_dmrPrefixes;
bool m_fusionEnabled; bool m_fusionEnabled;
bool m_fusionParrotEnabled; bool m_fusionParrotEnabled;

View file

@ -19,10 +19,11 @@
#include <cstdio> #include <cstdio>
#include <cassert> #include <cassert>
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<unsigned int>& prefixes, unsigned int timeout, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex) :
m_id(id), m_id(id),
m_colorCode(colorCode), m_colorCode(colorCode),
m_selfOnly(selfOnly), m_selfOnly(selfOnly),
m_prefixes(prefixes),
m_modem(modem), m_modem(modem),
m_network(network), m_network(network),
m_slot1(1U, timeout), m_slot1(1U, timeout),
@ -31,7 +32,7 @@ m_slot2(2U, timeout)
assert(modem != NULL); assert(modem != NULL);
assert(display != 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() CDMRControl::~CDMRControl()
@ -58,23 +59,43 @@ bool CDMRControl::processWakeup(const unsigned char* data)
unsigned int srcId = csbk.getSrcId(); unsigned int srcId = csbk.getSrcId();
unsigned int bsId = csbk.getBSId(); unsigned int bsId = csbk.getBSId();
if (bsId == 0xFFFFFFU) { if (m_selfOnly) {
if (m_selfOnly && srcId != m_id) { if (srcId != m_id) {
LogMessage("Invalid CSBK BS_Dwn_Act for ANY received from %u", srcId); LogMessage("Invalid CSBK BS_Dwn_Act received from %u", srcId);
return false; return false;
}
} else { } 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<unsigned int>::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) {
LogMessage("CSBK BS_Dwn_Act for ANY received from %u", srcId); LogMessage("CSBK BS_Dwn_Act for ANY received from %u", srcId);
return true; return true;
}
} else if (bsId == m_id) { } 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); LogMessage("CSBK BS_Dwn_Act for %u received from %u", bsId, srcId);
return true; return true;
} }
}
return false; return false;
} }

View file

@ -25,10 +25,11 @@
#include "DMRData.h" #include "DMRData.h"
#include "Modem.h" #include "Modem.h"
#include <vector>
class CDMRControl { class CDMRControl {
public: 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<unsigned int>& prefixes, unsigned int timeout, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex);
~CDMRControl(); ~CDMRControl();
bool processWakeup(const unsigned char* data); bool processWakeup(const unsigned char* data);
@ -45,6 +46,7 @@ private:
unsigned int m_id; unsigned int m_id;
unsigned int m_colorCode; unsigned int m_colorCode;
bool m_selfOnly; bool m_selfOnly;
std::vector<unsigned int> m_prefixes;
CModem* m_modem; CModem* m_modem;
CDMRIPSC* m_network; CDMRIPSC* m_network;
CDMRSlot m_slot1; CDMRSlot m_slot1;

View file

@ -29,6 +29,7 @@
unsigned int CDMRSlot::m_id = 0U; unsigned int CDMRSlot::m_id = 0U;
unsigned int CDMRSlot::m_colorCode = 0U; unsigned int CDMRSlot::m_colorCode = 0U;
bool CDMRSlot::m_selfOnly = false; bool CDMRSlot::m_selfOnly = false;
std::vector<unsigned int> CDMRSlot::m_prefixes;
CModem* CDMRSlot::m_modem = NULL; CModem* CDMRSlot::m_modem = NULL;
CDMRIPSC* CDMRSlot::m_network = NULL; CDMRIPSC* CDMRSlot::m_network = NULL;
IDisplay* CDMRSlot::m_display = NULL; IDisplay* CDMRSlot::m_display = NULL;
@ -131,8 +132,7 @@ void CDMRSlot::writeModem(unsigned char *data)
} }
unsigned int id = lc->getSrcId(); unsigned int id = lc->getSrcId();
if (!validateId(id)) {
if (m_selfOnly && id != m_id) {
LogMessage("DMR Slot %u, invalid access atemmpt from %u", m_slotNo, id); LogMessage("DMR Slot %u, invalid access atemmpt from %u", m_slotNo, id);
delete lc; delete lc;
return; return;
@ -242,7 +242,7 @@ void CDMRSlot::writeModem(unsigned char *data)
unsigned int srcId = dataHeader.getSrcId(); unsigned int srcId = dataHeader.getSrcId();
unsigned int dstId = dataHeader.getDstId(); 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); LogMessage("DMR Slot %u, invalid access atemmpt from %u", m_slotNo, srcId);
return; return;
} }
@ -300,7 +300,7 @@ void CDMRSlot::writeModem(unsigned char *data)
unsigned int srcId = csbk.getSrcId(); unsigned int srcId = csbk.getSrcId();
unsigned int dstId = csbk.getDstId(); 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); LogMessage("DMR Slot %u, invalid access atemmpt from %u", m_slotNo, srcId);
return; return;
} }
@ -480,7 +480,7 @@ void CDMRSlot::writeModem(unsigned char *data)
CDMRLC* lc = m_rfEmbeddedLC.addData(data + 2U, emb.getLCSS()); CDMRLC* lc = m_rfEmbeddedLC.addData(data + 2U, emb.getLCSS());
if (lc != NULL) { if (lc != NULL) {
unsigned int id = lc->getSrcId(); 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); LogMessage("DMR Slot %u, invalid access atemmpt from %u", m_slotNo, id);
delete lc; delete lc;
return; return;
@ -1227,7 +1227,7 @@ void CDMRSlot::writeQueueNet(const unsigned char *data)
m_queue.addData(data, len); 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<unsigned int>& prefixes, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex)
{ {
assert(id != 0U); assert(id != 0U);
assert(modem != NULL); assert(modem != NULL);
@ -1236,6 +1236,7 @@ void CDMRSlot::init(unsigned int id, unsigned int colorCode, bool selfOnly, CMod
m_id = id; m_id = id;
m_colorCode = colorCode; m_colorCode = colorCode;
m_selfOnly = selfOnly; m_selfOnly = selfOnly;
m_prefixes = prefixes;
m_modem = modem; m_modem = modem;
m_network = network; m_network = network;
m_display = display; m_display = display;
@ -1252,6 +1253,27 @@ void CDMRSlot::init(unsigned int id, unsigned int colorCode, bool selfOnly, CMod
slotType.getData(m_idle + 2U); 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<unsigned int>::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) void CDMRSlot::setShortLC(unsigned int slotNo, unsigned int id, FLCO flco, bool voice)
{ {
assert(m_modem != NULL); assert(m_modem != NULL);

View file

@ -34,6 +34,8 @@
#include "Modem.h" #include "Modem.h"
#include "DMRLC.h" #include "DMRLC.h"
#include <vector>
class CDMRSlot { class CDMRSlot {
public: public:
CDMRSlot(unsigned int slotNo, unsigned int timeout); CDMRSlot(unsigned int slotNo, unsigned int timeout);
@ -47,7 +49,7 @@ public:
void clock(); 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<unsigned int>& prefixes, CModem* modem, CDMRIPSC* network, IDisplay* display, bool duplex);
private: private:
unsigned int m_slotNo; unsigned int m_slotNo;
@ -85,6 +87,7 @@ private:
static unsigned int m_id; static unsigned int m_id;
static unsigned int m_colorCode; static unsigned int m_colorCode;
static bool m_selfOnly; static bool m_selfOnly;
static std::vector<unsigned int> m_prefixes;
static CModem* m_modem; static CModem* m_modem;
static CDMRIPSC* m_network; static CDMRIPSC* m_network;
static IDisplay* m_display; static IDisplay* m_display;
@ -115,6 +118,7 @@ private:
void insertSilence(unsigned int count); void insertSilence(unsigned int count);
static void setShortLC(unsigned int slotNo, unsigned int id, FLCO flco = FLCO_GROUP, bool voice = true); static void setShortLC(unsigned int slotNo, unsigned int id, FLCO flco = FLCO_GROUP, bool voice = true);
static bool validateId(unsigned int id);
}; };
#endif #endif

View file

@ -47,6 +47,7 @@ Beacons=1
Id=123456 Id=123456
ColorCode=1 ColorCode=1
SelfOnly=0 SelfOnly=0
Prefixes=234,235
[System Fusion] [System Fusion]
Enable=1 Enable=1

View file

@ -32,6 +32,7 @@
#endif #endif
#include <cstdio> #include <cstdio>
#include <vector>
#if !defined(_WIN32) && !defined(_WIN64) #if !defined(_WIN32) && !defined(_WIN64)
#include <unistd.h> #include <unistd.h>
@ -161,15 +162,17 @@ int CMMDVMHost::run()
unsigned int id = m_conf.getDMRId(); unsigned int id = m_conf.getDMRId();
unsigned int colorCode = m_conf.getDMRColorCode(); unsigned int colorCode = m_conf.getDMRColorCode();
bool selfOnly = m_conf.getDMRSelfOnly(); bool selfOnly = m_conf.getDMRSelfOnly();
std::vector<unsigned int> prefixes = m_conf.getDMRPrefixes();
unsigned int timeout = m_conf.getTimeout(); unsigned int timeout = m_conf.getTimeout();
LogInfo("DMR Parameters"); LogInfo("DMR Parameters");
LogInfo(" Id: %u", id); LogInfo(" Id: %u", id);
LogInfo(" Color Code: %u", colorCode); LogInfo(" Color Code: %u", colorCode);
LogInfo(" Self Only: %s", selfOnly ? "yes" : "no"); LogInfo(" Self Only: %s", selfOnly ? "yes" : "no");
LogInfo(" Prefixes: %u", prefixes.size());
LogInfo(" Timeout: %us", timeout); 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; CYSFControl* ysf = NULL;