Merge pull request #144 from hacknix/master

TalkGroup Rewrite
This commit is contained in:
Jonathan Naylor 2016-09-16 14:57:46 +01:00 committed by GitHub
commit 7a9369bf13
10 changed files with 189 additions and 19 deletions

View file

@ -93,6 +93,8 @@ m_dmrBeacons(false),
m_dmrId(0U), m_dmrId(0U),
m_dmrColorCode(2U), m_dmrColorCode(2U),
m_dmrSelfOnly(false), m_dmrSelfOnly(false),
m_TGRewriteSlot1(false),
m_TGRewriteSlot2(false),
m_dmrPrefixes(), m_dmrPrefixes(),
m_dmrBlackList(), m_dmrBlackList(),
m_dmrDstIdBlacklistSlot1RF(), m_dmrDstIdBlacklistSlot1RF(),
@ -330,6 +332,10 @@ 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, "TGRewriteSlot1") == 0)
m_TGRewriteSlot1 = ::atoi(value) == 1;
else if (::strcmp(key, "TGRewriteSlot2") == 0)
m_TGRewriteSlot2 = ::atoi(value) == 1;
else if (::strcmp(key, "Prefixes") == 0) { else if (::strcmp(key, "Prefixes") == 0) {
char* p = ::strtok(value, ",\r\n"); char* p = ::strtok(value, ",\r\n");
while (p != NULL) { while (p != NULL) {
@ -748,6 +754,16 @@ bool CConf::getDMRSelfOnly() const
return m_dmrSelfOnly; return m_dmrSelfOnly;
} }
bool CConf::getDMRTGRewriteSlot1() const
{
return m_TGRewriteSlot1;
}
bool CConf::getDMRTGRewriteSlot2() const
{
return m_TGRewriteSlot2;
}
std::vector<unsigned int> CConf::getDMRPrefixes() const std::vector<unsigned int> CConf::getDMRPrefixes() const
{ {
return m_dmrPrefixes; return m_dmrPrefixes;

4
Conf.h
View file

@ -88,6 +88,8 @@ public:
unsigned int getDMRId() const; unsigned int getDMRId() const;
unsigned int getDMRColorCode() const; unsigned int getDMRColorCode() const;
bool getDMRSelfOnly() const; bool getDMRSelfOnly() const;
bool getDMRTGRewriteSlot1() const;
bool getDMRTGRewriteSlot2() const;
std::vector<unsigned int> getDMRPrefixes() const; std::vector<unsigned int> getDMRPrefixes() const;
std::vector<unsigned int> getDMRBlackList() const; std::vector<unsigned int> getDMRBlackList() const;
std::vector<unsigned int> getDMRDstIdBlacklistSlot1RF() const; std::vector<unsigned int> getDMRDstIdBlacklistSlot1RF() const;
@ -213,6 +215,8 @@ private:
unsigned int m_dmrId; unsigned int m_dmrId;
unsigned int m_dmrColorCode; unsigned int m_dmrColorCode;
bool m_dmrSelfOnly; bool m_dmrSelfOnly;
bool m_TGRewriteSlot1;
bool m_TGRewriteSlot2;
std::vector<unsigned int> m_dmrPrefixes; std::vector<unsigned int> m_dmrPrefixes;
std::vector<unsigned int> m_dmrBlackList; std::vector<unsigned int> m_dmrBlackList;
std::vector<unsigned int> m_dmrDstIdBlacklistSlot1RF; std::vector<unsigned int> m_dmrDstIdBlacklistSlot1RF;

View file

@ -18,6 +18,7 @@
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
#include <ctime>
std::vector<unsigned int> DMRAccessControl::m_dstBlackListSlot1RF; std::vector<unsigned int> DMRAccessControl::m_dstBlackListSlot1RF;
std::vector<unsigned int> DMRAccessControl::m_dstBlackListSlot2RF; std::vector<unsigned int> DMRAccessControl::m_dstBlackListSlot2RF;
@ -37,7 +38,18 @@ bool DMRAccessControl::m_selfOnly = false;
unsigned int DMRAccessControl::m_id = 0U; unsigned int DMRAccessControl::m_id = 0U;
void DMRAccessControl::init(const std::vector<unsigned int>& DstIdBlacklistSlot1RF, const std::vector<unsigned int>& DstIdWhitelistSlot1RF, const std::vector<unsigned int>& DstIdBlacklistSlot2RF, const std::vector<unsigned int>& DstIdWhitelistSlot2RF, const std::vector<unsigned int>& DstIdBlacklistSlot1NET, const std::vector<unsigned int>& DstIdWhitelistSlot1NET, const std::vector<unsigned int>& DstIdBlacklistSlot2NET, const std::vector<unsigned int>& DstIdWhitelistSlot2NET, const std::vector<unsigned int>& SrcIdBlacklist, bool selfOnly, const std::vector<unsigned int>& prefixes,unsigned int id) unsigned int DMRAccessControl::m_dstRewriteID = 0U;
unsigned int DMRAccessControl::m_SrcID = 0U;
std::time_t DMRAccessControl::m_time;
unsigned int DMRAccessControl::m_callHang;
bool DMRAccessControl::m_TGRewriteSlot1;
bool DMRAccessControl::m_TGRewriteSlot2;
void DMRAccessControl::init(const std::vector<unsigned int>& DstIdBlacklistSlot1RF, const std::vector<unsigned int>& DstIdWhitelistSlot1RF, const std::vector<unsigned int>& DstIdBlacklistSlot2RF, const std::vector<unsigned int>& DstIdWhitelistSlot2RF, const std::vector<unsigned int>& DstIdBlacklistSlot1NET, const std::vector<unsigned int>& DstIdWhitelistSlot1NET, const std::vector<unsigned int>& DstIdBlacklistSlot2NET, const std::vector<unsigned int>& DstIdWhitelistSlot2NET, const std::vector<unsigned int>& SrcIdBlacklist, bool selfOnly, const std::vector<unsigned int>& prefixes,unsigned int id,unsigned int callHang,bool TGRewriteSlot1, bool TGRewriteSlot2)
{ {
m_dstBlackListSlot1RF = DstIdBlacklistSlot1RF; m_dstBlackListSlot1RF = DstIdBlacklistSlot1RF;
m_dstWhiteListSlot1RF = DstIdWhitelistSlot1RF; m_dstWhiteListSlot1RF = DstIdWhitelistSlot1RF;
@ -47,6 +59,9 @@ void DMRAccessControl::init(const std::vector<unsigned int>& DstIdBlacklistSlot1
m_dstWhiteListSlot1NET = DstIdWhitelistSlot1NET; m_dstWhiteListSlot1NET = DstIdWhitelistSlot1NET;
m_dstBlackListSlot2NET = DstIdBlacklistSlot2NET; m_dstBlackListSlot2NET = DstIdBlacklistSlot2NET;
m_dstWhiteListSlot2NET = DstIdWhitelistSlot2NET; m_dstWhiteListSlot2NET = DstIdWhitelistSlot2NET;
m_callHang = callHang;
m_TGRewriteSlot1 = TGRewriteSlot1;
m_TGRewriteSlot2 = TGRewriteSlot2;
} }
bool DMRAccessControl::DstIdBlacklist(unsigned int did, unsigned int slot, bool network) bool DMRAccessControl::DstIdBlacklist(unsigned int did, unsigned int slot, bool network)
@ -180,3 +195,38 @@ bool DMRAccessControl::validateAccess (unsigned int src_id, unsigned int dst_id,
return true; return true;
} }
} }
unsigned int DMRAccessControl::DstIdRewrite (unsigned int did, unsigned int sid, unsigned int slot, bool network)
{
if (slot == 1 && m_TGRewriteSlot1 == false)
return 0;
if (slot == 2 && m_TGRewriteSlot2 == false)
return 0;
std::time_t currenttime = std::time(nullptr);
if (network) {
m_dstRewriteID = did;
m_SrcID = sid;
if (did < 4000 && did > 0 && did != 9) {
LogMessage("DMR Slot %u, Rewrite DST ID (TG) of of inbound network traffic from %u to 9",slot,did);
return 9;
} else {
return 0;
}
} else if (did == 9 && m_dstRewriteID != 9 && m_dstRewriteID != 0 && (m_time + m_callHang) > currenttime) {
LogMessage("DMR Slot %u, Rewrite DST ID (TG) of outbound network traffic from %u to %u (return traffic during CallHang)",slot,did,m_dstRewriteID);
return(m_dstRewriteID);
} else if (did < 4000 && did > 0 && did !=9) {
m_dstRewriteID = did;
}
return 0;
}
void DMRAccessControl::setOverEndTime()
{
m_time = std::time(nullptr);
}

View file

@ -16,12 +16,16 @@
#define DMRAccessControl_H #define DMRAccessControl_H
#include <vector> #include <vector>
#include <ctime>
class DMRAccessControl { class DMRAccessControl {
public: public:
static bool validateAccess (unsigned int src_id, unsigned int dst_id, unsigned int slot, bool network); static bool validateAccess (unsigned int src_id, unsigned int dst_id, unsigned int slot, bool network);
static void init(const std::vector<unsigned int>& DstIdBlacklistSlot1RF, const std::vector<unsigned int>& DstIdWhitelistSlot1RF, const std::vector<unsigned int>& DstIdBlacklistSlot2RF, const std::vector<unsigned int>& DstIdWhitelistSlot2RF, const std::vector<unsigned int>& DstIdBlacklistSlot1NET, const std::vector<unsigned int>& DstIdWhitelistSlot1NET, const std::vector<unsigned int>& DstIdBlacklistSlot2NET, const std::vector<unsigned int>& DstIdWhitelistSlot2NET, const std::vector<unsigned int>& SrcIdBlacklist, bool selfOnly, const std::vector<unsigned int>& prefixes,unsigned int id); static void init(const std::vector<unsigned int>& DstIdBlacklistSlot1RF, const std::vector<unsigned int>& DstIdWhitelistSlot1RF, const std::vector<unsigned int>& DstIdBlacklistSlot2RF, const std::vector<unsigned int>& DstIdWhitelistSlot2RF, const std::vector<unsigned int>& DstIdBlacklistSlot1NET, const std::vector<unsigned int>& DstIdWhitelistSlot1NET, const std::vector<unsigned int>& DstIdBlacklistSlot2NET, const std::vector<unsigned int>& DstIdWhitelistSlot2NET, const std::vector<unsigned int>& SrcIdBlacklist, bool selfOnly, const std::vector<unsigned int>& prefixes,unsigned int id,unsigned int callHang, bool TGRewrteSlot1, bool TGRewrteSlot2);
static unsigned int DstIdRewrite(unsigned int id, unsigned int sid,unsigned int slot, bool network);
static void setOverEndTime();
private: private:
static std::vector<unsigned int> m_dstBlackListSlot1RF; static std::vector<unsigned int> m_dstBlackListSlot1RF;
@ -37,6 +41,8 @@ private:
static std::vector<unsigned int> m_SrcIdBlacklist; static std::vector<unsigned int> m_SrcIdBlacklist;
static std::vector<unsigned int> m_prefixes; static std::vector<unsigned int> m_prefixes;
static unsigned int m_callHang;
static bool m_selfOnly; static bool m_selfOnly;
static unsigned int m_id; static unsigned int m_id;
@ -45,6 +51,17 @@ private:
static bool DstIdWhitelist(unsigned int did,unsigned int slot,bool gt4k, bool network); static bool DstIdWhitelist(unsigned int did,unsigned int slot,bool gt4k, bool network);
static bool validateSrcId(unsigned int id); static bool validateSrcId(unsigned int id);
static std::time_t m_time;
static unsigned int m_dstRewriteID;
static unsigned int m_SrcID;
static bool m_TGRewriteSlot1;
static bool m_TGRewriteSlot2;
}; };
#endif #endif

View file

@ -20,7 +20,7 @@
#include <cassert> #include <cassert>
#include <algorithm> #include <algorithm>
CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blackList, const std::vector<unsigned int>& DstIdBlacklistSlot1RF, const std::vector<unsigned int>& DstIdWhitelistSlot1RF, const std::vector<unsigned int>& DstIdBlacklistSlot2RF, const std::vector<unsigned int>& DstIdWhitelistSlot2RF, const std::vector<unsigned int>& DstIdBlacklistSlot1NET, const std::vector<unsigned int>& DstIdWhitelistSlot1NET, const std::vector<unsigned int>& DstIdBlacklistSlot2NET, const std::vector<unsigned int>& DstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, const std::string& lookupFile, int rssiMultiplier, int rssiOffset, unsigned int jitter) : CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blackList, const std::vector<unsigned int>& DstIdBlacklistSlot1RF, const std::vector<unsigned int>& DstIdWhitelistSlot1RF, const std::vector<unsigned int>& DstIdBlacklistSlot2RF, const std::vector<unsigned int>& DstIdWhitelistSlot2RF, const std::vector<unsigned int>& DstIdBlacklistSlot1NET, const std::vector<unsigned int>& DstIdWhitelistSlot1NET, const std::vector<unsigned int>& DstIdBlacklistSlot2NET, const std::vector<unsigned int>& DstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, const std::string& lookupFile, int rssiMultiplier, int rssiOffset, unsigned int jitter, bool TGRewriteSlot1, bool TGRewriteSlot2) :
m_id(id), m_id(id),
m_colorCode(colorCode), m_colorCode(colorCode),
m_selfOnly(selfOnly), m_selfOnly(selfOnly),
@ -38,7 +38,7 @@ m_lookup(NULL)
m_lookup = new CDMRLookup(lookupFile); m_lookup = new CDMRLookup(lookupFile);
m_lookup->read(); m_lookup->read();
CDMRSlot::init(id, colorCode, callHang, selfOnly, prefixes, blackList, DstIdBlacklistSlot1RF, DstIdWhitelistSlot1RF, DstIdBlacklistSlot2RF, DstIdWhitelistSlot2RF, DstIdBlacklistSlot1NET, DstIdWhitelistSlot1NET, DstIdBlacklistSlot2NET, DstIdWhitelistSlot2NET, modem, network, display, duplex, m_lookup, rssiMultiplier, rssiOffset, jitter); CDMRSlot::init(id, colorCode, callHang, selfOnly, prefixes, blackList, DstIdBlacklistSlot1RF, DstIdWhitelistSlot1RF, DstIdBlacklistSlot2RF, DstIdWhitelistSlot2RF, DstIdBlacklistSlot1NET, DstIdWhitelistSlot1NET, DstIdBlacklistSlot2NET, DstIdWhitelistSlot2NET, modem, network, display, duplex, m_lookup, rssiMultiplier, rssiOffset, jitter, TGRewriteSlot1, TGRewriteSlot2);
} }
CDMRControl::~CDMRControl() CDMRControl::~CDMRControl()

View file

@ -30,7 +30,7 @@
class CDMRControl { class CDMRControl {
public: public:
CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blackList, const std::vector<unsigned int>& DstIdBlacklistSlot1RF, const std::vector<unsigned int>& DstIdWhitelistSlot1RF, const std::vector<unsigned int>& DstIdBlacklistSlot2RF, const std::vector<unsigned int>& DstIdWhitelistSlot2RF,const std::vector<unsigned int>& DstIdBlacklistSlot1NET, const std::vector<unsigned int>& DstIdWhitelistSlot1NET, const std::vector<unsigned int>& DstIdBlacklistSlot2NET, const std::vector<unsigned int>& DstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, const std::string& lookupFile, int rssiMultiplier, int rssiOffset, unsigned int jitter); CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blackList, const std::vector<unsigned int>& DstIdBlacklistSlot1RF, const std::vector<unsigned int>& DstIdWhitelistSlot1RF, const std::vector<unsigned int>& DstIdBlacklistSlot2RF, const std::vector<unsigned int>& DstIdWhitelistSlot2RF,const std::vector<unsigned int>& DstIdBlacklistSlot1NET, const std::vector<unsigned int>& DstIdWhitelistSlot1NET, const std::vector<unsigned int>& DstIdBlacklistSlot2NET, const std::vector<unsigned int>& DstIdWhitelistSlot2NET, unsigned int timeout, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, const std::string& lookupFile, int rssiMultiplier, int rssiOffset, unsigned int jitter, bool TGRewriteSlot1, bool TGRewriteSlot2);
~CDMRControl(); ~CDMRControl();
bool processWakeup(const unsigned char* data); bool processWakeup(const unsigned char* data);

View file

@ -152,13 +152,19 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
if (lc == NULL) if (lc == NULL)
return; return;
unsigned int id = lc->getSrcId(); unsigned int sid = lc->getSrcId();
unsigned int did = lc->getDstId(); unsigned int did = lc->getDstId();
if (!DMRAccessControl::validateAccess(id, did, m_slotNo, false)) { if (!DMRAccessControl::validateAccess(sid, did, m_slotNo, false)) {
delete lc; delete lc;
return; return;
} }
unsigned int rw_id = DMRAccessControl::DstIdRewrite(did,sid,m_slotNo,false);
if (rw_id) {
lc->setDstId(rw_id);
}
m_rfLC = lc; m_rfLC = lc;
// Store the LC for the embedded LC // Store the LC for the embedded LC
@ -196,7 +202,7 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
m_rfState = RS_RF_AUDIO; m_rfState = RS_RF_AUDIO;
std::string src = m_lookup->find(id); std::string src = m_lookup->find(sid);
std::string dst = m_lookup->find(m_rfLC->getDstId()); std::string dst = m_lookup->find(m_rfLC->getDstId());
if (m_netState == RS_NET_IDLE) { if (m_netState == RS_NET_IDLE) {
@ -256,6 +262,7 @@ 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)); 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(); writeEndRF();
DMRAccessControl::setOverEndTime();
} else if (dataType == DT_DATA_HEADER) { } else if (dataType == DT_DATA_HEADER) {
if (m_rfState == RS_RF_DATA) if (m_rfState == RS_RF_DATA)
return; return;
@ -271,6 +278,7 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
if (!DMRAccessControl::validateAccess(srcId, dstId, m_slotNo, false)) if (!DMRAccessControl::validateAccess(srcId, dstId, m_slotNo, false))
return; return;
m_rfFrames = dataHeader.getBlocks(); m_rfFrames = dataHeader.getBlocks();
m_rfDataHeader = dataHeader; m_rfDataHeader = dataHeader;
@ -325,7 +333,7 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
unsigned int dstId = csbk.getDstId(); unsigned int dstId = csbk.getDstId();
if (!DMRAccessControl::validateAccess(srcId, dstId, m_slotNo, false)) if (!DMRAccessControl::validateAccess(srcId, dstId, m_slotNo, false))
return; return;
// Regenerate the CSBK data // Regenerate the CSBK data
csbk.get(data + 2U); csbk.get(data + 2U);
@ -478,12 +486,18 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
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 sid = lc->getSrcId();
unsigned int did = lc->getDstId(); unsigned int did = lc->getDstId();
if (!DMRAccessControl::validateAccess(id,did,m_slotNo,false)) { if (!DMRAccessControl::validateAccess(sid,did,m_slotNo,false)) {
delete lc; delete lc;
return; return;
} }
// Test dst rewrite
unsigned int rw_id = DMRAccessControl::DstIdRewrite(did,sid,m_slotNo,false);
if (rw_id) {
lc->setDstId(rw_id);
}
m_rfLC = lc; m_rfLC = lc;
@ -759,9 +773,16 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
} }
unsigned int did = m_netLC->getDstId(); unsigned int did = m_netLC->getDstId();
unsigned int id = m_netLC->getSrcId(); unsigned int sid = m_netLC->getSrcId();
if (!DMRAccessControl::validateAccess(id, did, m_slotNo, true)) if (!DMRAccessControl::validateAccess(sid, did, m_slotNo, true))
return; return;
// Test dst rewrite
unsigned int rw_id = DMRAccessControl::DstIdRewrite(did, sid,m_slotNo, true);
if (rw_id) {
m_netLC->setDstId(rw_id);
}
// Store the LC for the embedded LC // Store the LC for the embedded LC
m_netEmbeddedLC.setData(*m_netLC); m_netEmbeddedLC.setData(*m_netLC);
@ -822,9 +843,16 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
return; return;
unsigned int did = m_netLC->getDstId(); unsigned int did = m_netLC->getDstId();
unsigned int id = m_netLC->getSrcId(); unsigned int sid = m_netLC->getSrcId();
if (!DMRAccessControl::validateAccess(id, did, m_slotNo, true)) if (!DMRAccessControl::validateAccess(sid, did, m_slotNo, true))
return; return;
// Test dst rewrite
unsigned int rw_id = DMRAccessControl::DstIdRewrite(did,sid,m_slotNo,true);
if (rw_id) {
m_netLC->setDstId(rw_id);
}
// Regenerate the Slot Type // Regenerate the Slot Type
CDMRSlotType slotType; CDMRSlotType slotType;
@ -891,6 +919,7 @@ 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)); 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(); writeEndNet();
DMRAccessControl::setOverEndTime();
} else if (dataType == DT_DATA_HEADER) { } else if (dataType == DT_DATA_HEADER) {
if (m_netState == RS_NET_DATA) if (m_netState == RS_NET_DATA)
return; return;
@ -1333,7 +1362,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, unsigned int callHang, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& SrcIdBlacklist, const std::vector<unsigned int>& DstIdBlacklistSlot1RF, const std::vector<unsigned int>& DstIdWhitelistSlot1RF, const std::vector<unsigned int>& DstIdBlacklistSlot2RF, const std::vector<unsigned int>& DstIdWhitelistSlot2RF, const std::vector<unsigned int>& DstIdBlacklistSlot1NET, const std::vector<unsigned int>& DstIdWhitelistSlot1NET, const std::vector<unsigned int>& DstIdBlacklistSlot2NET, const std::vector<unsigned int>& DstIdWhitelistSlot2NET, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter) void CDMRSlot::init(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& SrcIdBlacklist, const std::vector<unsigned int>& DstIdBlacklistSlot1RF, const std::vector<unsigned int>& DstIdWhitelistSlot1RF, const std::vector<unsigned int>& DstIdBlacklistSlot2RF, const std::vector<unsigned int>& DstIdWhitelistSlot2RF, const std::vector<unsigned int>& DstIdBlacklistSlot1NET, const std::vector<unsigned int>& DstIdWhitelistSlot1NET, const std::vector<unsigned int>& DstIdBlacklistSlot2NET, const std::vector<unsigned int>& DstIdWhitelistSlot2NET, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter, bool TGRewriteSlot1, bool TGRewriteSlot2)
{ {
assert(id != 0U); assert(id != 0U);
assert(modem != NULL); assert(modem != NULL);
@ -1368,7 +1397,7 @@ void CDMRSlot::init(unsigned int id, unsigned int colorCode, unsigned int callHa
slotType.getData(m_idle + 2U); slotType.getData(m_idle + 2U);
//Load black and white lists to DMRAccessControl //Load black and white lists to DMRAccessControl
DMRAccessControl::init(DstIdBlacklistSlot1RF, DstIdWhitelistSlot1RF, DstIdBlacklistSlot2RF, DstIdWhitelistSlot2RF, DstIdBlacklistSlot1NET, DstIdWhitelistSlot1NET, DstIdBlacklistSlot2NET, DstIdWhitelistSlot2NET, SrcIdBlacklist, m_selfOnly, m_prefixes, m_id); DMRAccessControl::init(DstIdBlacklistSlot1RF, DstIdWhitelistSlot1RF, DstIdBlacklistSlot2RF, DstIdWhitelistSlot2RF, DstIdBlacklistSlot1NET, DstIdWhitelistSlot1NET, DstIdBlacklistSlot2NET, DstIdWhitelistSlot2NET, SrcIdBlacklist, m_selfOnly, m_prefixes, m_id,callHang, TGRewriteSlot1, TGRewriteSlot2);
} }

View file

@ -50,7 +50,7 @@ public:
void clock(); void clock();
static void init(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& SrcIdBlackList, const std::vector<unsigned int>& DstIdBlacklistSlot1RF, const std::vector<unsigned int>& DstIdWhitelistSlot1RF, const std::vector<unsigned int>& DstIdBlacklistSlot2RF, const std::vector<unsigned int>& DstIdWhitelistSlot2RF, const std::vector<unsigned int>& DstIdBlacklistSlot1NET, const std::vector<unsigned int>& DstIdWhitelistSlot1NET, const std::vector<unsigned int>& DstIdBlacklistSlot2NET, const std::vector<unsigned int>& DstIdWhitelistSlot2NET, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter); static void init(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& SrcIdBlackList, const std::vector<unsigned int>& DstIdBlacklistSlot1RF, const std::vector<unsigned int>& DstIdWhitelistSlot1RF, const std::vector<unsigned int>& DstIdBlacklistSlot2RF, const std::vector<unsigned int>& DstIdWhitelistSlot2RF, const std::vector<unsigned int>& DstIdBlacklistSlot1NET, const std::vector<unsigned int>& DstIdWhitelistSlot1NET, const std::vector<unsigned int>& DstIdBlacklistSlot2NET, const std::vector<unsigned int>& DstIdWhitelistSlot2NET, CModem* modem, CDMRIPSC* network, CDisplay* display, bool duplex, CDMRLookup* lookup, int rssiMultiplier, int rssiOffset, unsigned int jitter, bool TGRewriteSlot1, bool TGRewriteSlot2);
private: private:
unsigned int m_slotNo; unsigned int m_slotNo;

View file

@ -296,6 +296,8 @@ 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();
bool TGRewriteSlot1 = m_conf.getDMRTGRewriteSlot1();
bool TGRewriteSlot2 = m_conf.getDMRTGRewriteSlot2();
std::vector<unsigned int> prefixes = m_conf.getDMRPrefixes(); std::vector<unsigned int> prefixes = m_conf.getDMRPrefixes();
std::vector<unsigned int> blackList = m_conf.getDMRBlackList(); std::vector<unsigned int> blackList = m_conf.getDMRBlackList();
std::vector<unsigned int> dstIDBlackListSlot1RF = m_conf.getDMRDstIdBlacklistSlot1RF(); std::vector<unsigned int> dstIDBlackListSlot1RF = m_conf.getDMRDstIdBlacklistSlot1RF();
@ -354,8 +356,15 @@ int CMMDVMHost::run()
LogInfo(" RSSI Multiplier: %d", rssiMultiplier); LogInfo(" RSSI Multiplier: %d", rssiMultiplier);
LogInfo(" RSSI Offset: %d", rssiOffset); LogInfo(" RSSI Offset: %d", rssiOffset);
} }
if (TGRewriteSlot1)
LogInfo(" TG Rewrite Slot 1 enabled");
if (TGRewriteSlot2)
LogInfo(" TG Rewrite Slot 2 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, lookupFile, rssiMultiplier, rssiOffset, jitter); 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, lookupFile, rssiMultiplier, rssiOffset, jitter, TGRewriteSlot1, TGRewriteSlot2);
m_dmrTXTimer.setTimeout(txHang); m_dmrTXTimer.setTimeout(txHang);
} }

45
README.TGRewrite Normal file
View file

@ -0,0 +1,45 @@
Talk-Group Rewrite was conceived as a way of making talk-groups behave more
like the reflector system and of attempting to solve the problem of "slot
contention",where the user may be locked out of a slot by traffic on a
talk-group they know nothing about, without knowing why. This is frustrating to
users, both those new to DMR and seasoned DMR users.
TG Rewrite, when enabled for a slot, rewrites the DST ID of incoming talkgroup
traffic to TG9, alowing audio to be heard by any user monitoring TG9 on that
slot. If the user then replies on TG9, as long as they key-up during the
CallHang period, the DST ID (TG) is again rewritten on the outbound traffic,
which transparently maps back to the originating talkgroup. Rewrite is also
enabled if an outbound call is made to a talkgroup and then TG9 is activated
during the CallHang period.
To use a User Activated talk-group, briefly key-up on that talk-group to
activate it, then switch back to TG9 and talk as normal. If the CallHang period
expires, you may need to activate the talk-group again by keying up on that
talkgroup briefly, as before. Alternatively, you can wait for inbound audio to
re-activate the rewrite, then respond during the CallHang period.
Note, proper ettiquette dictates that the user confirms the repeater is free
before activiating this feature. It is best to ensure the slot is keyed from
"cold" when activating a talkgroup for rewrite. Although not strictly
neccesary, it may be advantageous to also disconnect the repeater from the
reflector system first, if using slot 2.
Talk-group rewrite was originally intended to work with User-Activated talk
groups, although it will function with permanent talk-groups too.
It is useful to set the CallHang parameter to a generous amount. I am currently
using seven seconds.
Two boolean configuration options control the TG Rewrite feature:
TGRewriteSlot1=[0|1]
TGRewriteSlot2=[0|1]
ACL's are applied before the rewrite, so still apply to rewritten traffic on
original (non-rewritten) talk-group.
73
Simon (G7RZU)