Allow for locking the MMDVM to the callsign or id of the

repeater/hostspot.
This commit is contained in:
Jonathan Naylor 2016-04-04 17:40:05 +01:00
parent 5c6e0ea4c1
commit ea51eee15c
10 changed files with 111 additions and 27 deletions

View file

@ -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;

4
Conf.h
View file

@ -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;

View file

@ -19,9 +19,10 @@
#include <cstdio>
#include <cassert>
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;

View file

@ -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;

View file

@ -26,7 +26,9 @@
#include <cassert>
#include <ctime>
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;

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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

View file

@ -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;