Merge remote-tracking branch 'g4klx/master'

This commit is contained in:
Andy CA6JAU 2017-02-16 08:31:20 -03:00
commit cb004bcae4
42 changed files with 53164 additions and 48783 deletions

View file

@ -104,6 +104,7 @@ m_dmrBeacons(false),
m_dmrId(0U),
m_dmrColorCode(2U),
m_dmrSelfOnly(false),
m_dmrEmbeddedLCOnly(false),
m_dmrPrefixes(),
m_dmrBlackList(),
m_dmrWhiteList(),
@ -370,6 +371,8 @@ bool CConf::read()
m_dmrColorCode = (unsigned int)::atoi(value);
else if (::strcmp(key, "SelfOnly") == 0)
m_dmrSelfOnly = ::atoi(value) == 1;
else if (::strcmp(key, "EmbeddedLCOnly") == 0)
m_dmrEmbeddedLCOnly = ::atoi(value) == 1;
else if (::strcmp(key, "Prefixes") == 0) {
char* p = ::strtok(value, ",\r\n");
while (p != NULL) {
@ -801,6 +804,11 @@ bool CConf::getDMRSelfOnly() const
return m_dmrSelfOnly;
}
bool CConf::getDMREmbeddedLCOnly() const
{
return m_dmrEmbeddedLCOnly;
}
std::vector<unsigned int> CConf::getDMRPrefixes() const
{
return m_dmrPrefixes;

2
Conf.h
View file

@ -96,6 +96,7 @@ public:
bool getDMRBeacons() const;
unsigned int getDMRId() const;
unsigned int getDMRColorCode() const;
bool getDMREmbeddedLCOnly() const;
bool getDMRSelfOnly() const;
std::vector<unsigned int> getDMRPrefixes() const;
std::vector<unsigned int> getDMRBlackList() const;
@ -243,6 +244,7 @@ private:
unsigned int m_dmrId;
unsigned int m_dmrColorCode;
bool m_dmrSelfOnly;
bool m_dmrEmbeddedLCOnly;
std::vector<unsigned int> m_dmrPrefixes;
std::vector<unsigned int> m_dmrBlackList;
std::vector<unsigned int> m_dmrWhiteList;

View file

@ -75,6 +75,10 @@ bool CDMRAccessControl::validateTGId(unsigned int slotNo, bool group, unsigned i
if (!group)
return true;
// TG0 is never valid
if (id == 0U)
return false;
if (slotNo == 1U) {
if (m_slot1TGWhiteList.empty())
return true;

View file

@ -21,7 +21,7 @@
#include <cassert>
#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>& whitelist, const std::vector<unsigned int>& slot1TGWhitelist, const std::vector<unsigned int>& slot2TGWhitelist, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter) :
CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, bool embeddedLCOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blacklist, const std::vector<unsigned int>& whitelist, const std::vector<unsigned int>& slot1TGWhitelist, const std::vector<unsigned int>& slot2TGWhitelist, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter) :
m_id(id),
m_colorCode(colorCode),
m_modem(modem),
@ -39,7 +39,7 @@ m_lookup(lookup)
// Load black and white lists to DMRAccessControl
CDMRAccessControl::init(blacklist, whitelist, slot1TGWhitelist, slot2TGWhitelist, selfOnly, prefixes, id);
CDMRSlot::init(colorCode, callHang, modem, network, display, duplex, m_lookup, rssi, jitter);
CDMRSlot::init(colorCode, embeddedLCOnly, callHang, modem, network, display, duplex, m_lookup, rssi, jitter);
}
CDMRControl::~CDMRControl()

View file

@ -31,7 +31,7 @@
class CDMRControl {
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>& whitelist, const std::vector<unsigned int>& slot1TGWhitelist, const std::vector<unsigned int>& slot2TGWhitelist, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter);
CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, bool embeddedLCOnly, const std::vector<unsigned int>& prefixes, const std::vector<unsigned int>& blacklist, const std::vector<unsigned int>& whitelist, const std::vector<unsigned int>& slot1TGWhitelist, const std::vector<unsigned int>& slot2TGWhitelist, unsigned int timeout, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter);
~CDMRControl();
bool processWakeup(const unsigned char* data);

View file

@ -90,7 +90,7 @@ then
fi
# Generate new file
curl 'http://www.dmr-marc.net/cgi-bin/trbo-database/datadump.cgi?table=users&format=csv&header=0' 2>/dev/null | awk -F"," '{printf "%s\t%s\t%s\n", $1, $2, $4 == "" ? $3 : $4}' | sed -e 's/\(.\) .*/\1/g' > ${DMRIDFILE}
curl 'http://www.dmr-marc.net/cgi-bin/trbo-database/datadump.cgi?table=users&format=csv&header=0' 2>/dev/null | sed -e 's/\t//g' | awk -F"," '/,/{gsub(/ /, "", $2); printf "%s\t%s\t%s\n", $1, $2, $3}' | sed -e 's/\(.\) .*/\1/g' > ${DMRIDFILE}
# Restart MMDVMHost
eval ${RESTARTCOMMAND}

101329
DMRIds.dat

File diff suppressed because it is too large Load diff

View file

@ -31,6 +31,8 @@
unsigned int CDMRSlot::m_colorCode = 0U;
bool CDMRSlot::m_embeddedLCOnly = false;
CModem* CDMRSlot::m_modem = NULL;
CDMRNetwork* CDMRSlot::m_network = NULL;
CDisplay* CDMRSlot::m_display = NULL;
@ -52,6 +54,12 @@ FLCO CDMRSlot::m_flco2;
unsigned char CDMRSlot::m_id2 = 0U;
bool CDMRSlot::m_voice2 = true;
const unsigned char TALKER_ID_NONE = 0x00U;
const unsigned char TALKER_ID_HEADER = 0x01U;
const unsigned char TALKER_ID_BLOCK1 = 0x02U;
const unsigned char TALKER_ID_BLOCK2 = 0x04U;
const unsigned char TALKER_ID_BLOCK3 = 0x08U;
// #define DUMP_DMR
CDMRSlot::CDMRSlot(unsigned int slotNo, unsigned int timeout) :
@ -63,10 +71,12 @@ m_rfEmbeddedLC(),
m_rfEmbeddedData(NULL),
m_rfEmbeddedReadN(0U),
m_rfEmbeddedWriteN(1U),
m_rfTalkerId(TALKER_ID_NONE),
m_netEmbeddedLC(),
m_netEmbeddedData(NULL),
m_netEmbeddedReadN(0U),
m_netEmbeddedWriteN(1U),
m_netTalkerId(TALKER_ID_NONE),
m_rfLC(NULL),
m_netLC(NULL),
m_rfDataHeader(),
@ -220,8 +230,10 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
m_rfSeqNo = 0U;
m_rfBits = 1U;
m_rfErrs = 0U;
m_rfEmbeddedReadN = 0U;
m_rfEmbeddedWriteN = 1U;
m_rfTalkerId = TALKER_ID_NONE;
m_minRSSI = m_rssi;
m_maxRSSI = m_rssi;
@ -450,7 +462,7 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
if (ret) {
trellis.encode(payload, data + 2U);
} else {
LogDebug("DMR Slot %u, unfixable rate 3/4 data", m_slotNo);
LogMessage("DMR Slot %u, unfixable RF rate 3/4 data", m_slotNo);
CUtils::dump(1U, "Data", data + 2U, DMR_FRAME_LENGTH_BYTES);
}
}
@ -483,7 +495,8 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
unsigned char fid = m_rfLC->getFID();
if (fid == FID_ETSI || fid == FID_DMRA) {
errors = m_fec.regenerateDMR(data + 2U);
LogDebug("DMR Slot %u, audio sequence no. 0, errs: %u/141", m_slotNo, errors);
LogDebug("DMR Slot %u, audio sequence no. 0, errs: %u/141 (%.1f%%)", m_slotNo, errors, float(errors) / 1.41F);
m_display->writeDMRBER(m_slotNo, float(errors) / 1.41F);
m_rfErrs += errors;
}
@ -516,7 +529,8 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
unsigned char fid = m_rfLC->getFID();
if (fid == FID_ETSI || fid == FID_DMRA) {
errors = m_fec.regenerateDMR(data + 2U);
LogDebug("DMR Slot %u, audio sequence no. %u, errs: %u/141", m_slotNo, m_rfN, errors);
LogDebug("DMR Slot %u, audio sequence no. %u, errs: %u/141 (%.1f%%)", m_slotNo, m_rfN, errors, float(errors) / 1.41F);
m_display->writeDMRBER(m_slotNo, float(errors) / 1.41F);
m_rfErrs += errors;
}
@ -545,23 +559,35 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
break;
case FLCO_GPS_INFO:
::sprintf(text, "DMR Slot %u, Embedded GPS Info", m_slotNo);
CUtils::dump(1U, text, data, 9U);
CUtils::dump(2U, text, data, 9U);
break;
case FLCO_TALKER_ALIAS_HEADER:
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Header", m_slotNo);
CUtils::dump(1U, text, data, 9U);
if (!(m_rfTalkerId & TALKER_ID_HEADER)) {
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Header", m_slotNo);
CUtils::dump(2U, text, data, 9U);
m_rfTalkerId |= TALKER_ID_HEADER;
}
break;
case FLCO_TALKER_ALIAS_BLOCK1:
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 1", m_slotNo);
CUtils::dump(1U, text, data, 9U);
if (!(m_rfTalkerId & TALKER_ID_BLOCK1)) {
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 1", m_slotNo);
CUtils::dump(2U, text, data, 9U);
m_rfTalkerId |= TALKER_ID_BLOCK1;
}
break;
case FLCO_TALKER_ALIAS_BLOCK2:
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 2", m_slotNo);
CUtils::dump(1U, text, data, 9U);
if (!(m_rfTalkerId & TALKER_ID_BLOCK2)) {
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 2", m_slotNo);
CUtils::dump(2U, text, data, 9U);
m_rfTalkerId |= TALKER_ID_BLOCK2;
}
break;
case FLCO_TALKER_ALIAS_BLOCK3:
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 3", m_slotNo);
CUtils::dump(1U, text, data, 9U);
if (!(m_rfTalkerId & TALKER_ID_BLOCK3)) {
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 3", m_slotNo);
CUtils::dump(2U, text, data, 9U);
m_rfTalkerId |= TALKER_ID_BLOCK3;
}
break;
default:
::sprintf(text, "DMR Slot %u, Unknown Embedded Data", m_slotNo);
@ -584,10 +610,20 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
data[0U] = TAG_DATA;
data[1U] = 0x00U;
writeNetworkRF(data, DT_VOICE, errors);
if (m_embeddedLCOnly) {
// Only send the previously received LC
lcss = m_rfEmbeddedLC.getData(data + 2U, m_rfN);
// Regenerate the EMB
emb.setColorCode(m_colorCode);
emb.setLCSS(lcss);
emb.getData(data + 2U);
}
if (m_duplex)
writeQueueRF(data);
writeNetworkRF(data, DT_VOICE, errors);
} else if (m_rfState == RS_RF_LATE_ENTRY) {
CDMREMB emb;
emb.putData(data + 2U);
@ -645,8 +681,10 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
m_rfSeqNo = 0U;
m_rfBits = 1U;
m_rfErrs = 0U;
m_rfEmbeddedReadN = 0U;
m_rfEmbeddedWriteN = 1U;
m_rfTalkerId = TALKER_ID_NONE;
m_minRSSI = m_rssi;
m_maxRSSI = m_rssi;
@ -674,7 +712,7 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
unsigned char fid = m_rfLC->getFID();
if (fid == FID_ETSI || fid == FID_DMRA) {
errors = m_fec.regenerateDMR(data + 2U);
LogDebug("DMR Slot %u, audio sequence no. %u, errs: %u/141", m_slotNo, m_rfN, errors);
LogDebug("DMR Slot %u, audio sequence no. %u, errs: %u/141 (%.1f%%)", m_slotNo, m_rfN, errors, float(errors) / 1.41F);
m_rfErrs += errors;
}
@ -698,6 +736,7 @@ void CDMRSlot::writeModem(unsigned char *data, unsigned int len)
setShortLC(m_slotNo, dstId, flco, true);
m_display->writeDMR(m_slotNo, src, flco == FLCO_GROUP, dst, "R");
m_display->writeDMRRSSI(m_slotNo, m_rssi);
m_display->writeDMRBER(m_slotNo, float(errors) / 1.41F);
}
LogMessage("DMR Slot %u, received RF late entry from %s to %s%s", m_slotNo, src.c_str(), flco == FLCO_GROUP ? "TG " : "", dst.c_str());
@ -927,8 +966,10 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
m_netLost = 0U;
m_netBits = 1U;
m_netErrs = 0U;
m_netEmbeddedReadN = 0U;
m_netEmbeddedWriteN = 1U;
m_netTalkerId = TALKER_ID_NONE;
if (m_duplex) {
m_queue.clear();
@ -1183,8 +1224,10 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
m_netLost = 0U;
m_netBits = 1U;
m_netErrs = 0U;
m_netEmbeddedReadN = 0U;
m_netEmbeddedWriteN = 1U;
m_netTalkerId = TALKER_ID_NONE;
m_netState = RS_NET_AUDIO;
@ -1272,23 +1315,35 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
break;
case FLCO_GPS_INFO:
::sprintf(text, "DMR Slot %u, Embedded GPS Info", m_slotNo);
CUtils::dump(1U, text, data, 9U);
CUtils::dump(2U, text, data, 9U);
break;
case FLCO_TALKER_ALIAS_HEADER:
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Header", m_slotNo);
CUtils::dump(1U, text, data, 9U);
if (!(m_netTalkerId & TALKER_ID_HEADER)) {
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Header", m_slotNo);
CUtils::dump(2U, text, data, 9U);
m_netTalkerId |= TALKER_ID_HEADER;
}
break;
case FLCO_TALKER_ALIAS_BLOCK1:
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 1", m_slotNo);
CUtils::dump(1U, text, data, 9U);
if (!(m_netTalkerId & TALKER_ID_BLOCK1)) {
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 1", m_slotNo);
CUtils::dump(2U, text, data, 9U);
m_netTalkerId |= TALKER_ID_BLOCK1;
}
break;
case FLCO_TALKER_ALIAS_BLOCK2:
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 2", m_slotNo);
CUtils::dump(1U, text, data, 9U);
if (!(m_netTalkerId & TALKER_ID_BLOCK2)) {
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 2", m_slotNo);
CUtils::dump(2U, text, data, 9U);
m_netTalkerId |= TALKER_ID_BLOCK2;
}
break;
case FLCO_TALKER_ALIAS_BLOCK3:
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 3", m_slotNo);
CUtils::dump(1U, text, data, 9U);
if (!(m_netTalkerId & TALKER_ID_BLOCK3)) {
::sprintf(text, "DMR Slot %u, Embedded Talker Alias Block 3", m_slotNo);
CUtils::dump(2U, text, data, 9U);
m_netTalkerId |= TALKER_ID_BLOCK3;
}
break;
default:
::sprintf(text, "DMR Slot %u, Unknown Embedded Data", m_slotNo);
@ -1297,11 +1352,16 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
}
}
// Regenerate the previous super blocks Embedded Data or substitude the LC for it
if (m_netEmbeddedData[m_netEmbeddedReadN].isValid())
lcss = m_netEmbeddedData[m_netEmbeddedReadN].getData(data + 2U, dmrData.getN());
else
if (m_embeddedLCOnly) {
// Only send the previously received LC
lcss = m_netEmbeddedLC.getData(data + 2U, dmrData.getN());
} else {
// Regenerate the previous super blocks Embedded Data or substitude the LC for it
if (m_netEmbeddedData[m_netEmbeddedReadN].isValid())
lcss = m_netEmbeddedData[m_netEmbeddedReadN].getData(data + 2U, dmrData.getN());
else
lcss = m_netEmbeddedLC.getData(data + 2U, dmrData.getN());
}
// Regenerate the EMB
emb.setColorCode(m_colorCode);
@ -1409,8 +1469,12 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
CDMRTrellis trellis;
unsigned char payload[18U];
bool ret = trellis.decode(data + 2U, payload);
if (ret)
if (ret) {
trellis.encode(payload, data + 2U);
} else {
LogMessage("DMR Slot %u, unfixable network rate 3/4 data", m_slotNo);
CUtils::dump(1U, "Data", data + 2U, DMR_FRAME_LENGTH_BYTES);
}
}
// Regenerate the Slot Type
@ -1571,25 +1635,26 @@ void CDMRSlot::writeQueueNet(const unsigned char *data)
m_queue.addData(data, len);
}
void CDMRSlot::init(unsigned int colorCode, unsigned int callHang, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter)
void CDMRSlot::init(unsigned int colorCode, bool embeddedLCOnly, unsigned int callHang, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter)
{
assert(modem != NULL);
assert(display != NULL);
assert(lookup != NULL);
assert(rssiMapper != NULL);
m_colorCode = colorCode;
m_modem = modem;
m_network = network;
m_display = display;
m_duplex = duplex;
m_lookup = lookup;
m_hangCount = callHang * 17U;
m_colorCode = colorCode;
m_embeddedLCOnly = embeddedLCOnly;
m_modem = modem;
m_network = network;
m_display = display;
m_duplex = duplex;
m_lookup = lookup;
m_hangCount = callHang * 17U;
m_rssiMapper = rssiMapper;
m_rssiMapper = rssiMapper;
m_jitterTime = jitter;
m_jitterSlots = jitter / DMR_SLOT_TIME;
m_jitterTime = jitter;
m_jitterSlots = jitter / DMR_SLOT_TIME;
m_idle = new unsigned char[DMR_FRAME_LENGTH_BYTES + 2U];
::memcpy(m_idle, DMR_IDLE_DATA, DMR_FRAME_LENGTH_BYTES + 2U);

View file

@ -50,7 +50,7 @@ public:
void clock();
static void init(unsigned int colorCode, unsigned int callHang, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter);
static void init(unsigned int colorCode, bool embeddedLCOnly, unsigned int callHang, CModem* modem, CDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter);
private:
unsigned int m_slotNo;
@ -61,10 +61,12 @@ private:
CDMREmbeddedData* m_rfEmbeddedData;
unsigned int m_rfEmbeddedReadN;
unsigned int m_rfEmbeddedWriteN;
unsigned char m_rfTalkerId;
CDMREmbeddedData m_netEmbeddedLC;
CDMREmbeddedData* m_netEmbeddedData;
unsigned int m_netEmbeddedReadN;
unsigned int m_netEmbeddedWriteN;
unsigned char m_netTalkerId;
CDMRLC* m_rfLC;
CDMRLC* m_netLC;
CDMRDataHeader m_rfDataHeader;
@ -98,6 +100,8 @@ private:
static unsigned int m_colorCode;
static bool m_embeddedLCOnly;
static CModem* m_modem;
static CDMRNetwork* m_network;
static CDisplay* m_display;

View file

@ -300,12 +300,14 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
return false;
} else if (m_rfState == RS_RF_AUDIO) {
unsigned int errors = 0U;
if (!m_rfHeader.isDataPacket())
if (!m_rfHeader.isDataPacket()) {
errors = m_fec.regenerateDStar(data + 1U);
m_display->writeDStarBER(float(errors) / 0.48F);
LogDebug("D-Star, audio sequence no. %u, errs: %u/48 (%.1f%%)", m_rfN, errors, float(errors) / 0.48F);
m_rfErrs += errors;
}
m_rfErrs += errors;
m_rfBits += 48U;
m_rfFrames++;
// The sync is regenerated by the modem so can do exact match
@ -318,8 +320,6 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
m_display->writeDStarRSSI(m_rssi);
}
LogDebug("D-Star, audio sequence no. %u, errs: %u/48", m_rfN, errors);
if (m_net)
writeNetworkDataRF(data, errors, false);
@ -428,14 +428,14 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
delete header;
unsigned int errors = 0U;
if (!m_rfHeader.isDataPacket())
if (!m_rfHeader.isDataPacket()) {
errors = m_fec.regenerateDStar(data + 1U);
LogDebug("D-Star, audio sequence no. %u, errs: %u/48 (%.1f%%)", m_rfN, errors, float(errors) / 0.48F);
m_rfErrs += errors;
}
m_rfErrs += errors;
m_rfBits += 48U;
LogDebug("D-Star, audio sequence no. %u, errs: %u/48", m_rfN, errors);
if (m_net)
writeNetworkDataRF(data, errors, false);
@ -451,6 +451,7 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
if (m_netState == RS_NET_IDLE) {
m_display->writeDStar((char*)my1, (char*)my2, (char*)your, "R", " ");
m_display->writeDStarRSSI(m_rssi);
m_display->writeDStarBER(float(errors) / 0.48F);
}
LogMessage("D-Star, received RF late entry from %8.8s/%4.4s to %8.8s", my1, my2, your);
@ -624,8 +625,6 @@ void CDStarControl::writeNetwork()
m_netN = n;
LogDebug("D-Star, audio sequence no. %u, errs: %u/48", m_netN, errors);
// Regenerate the sync
if (n == 0U)
CSync::addDStarSync(data + 2U);

View file

@ -90,6 +90,11 @@ void CDisplay::writeDStarRSSI(unsigned char rssi)
writeDStarRSSIInt(rssi);
}
void CDisplay::writeDStarBER(float ber)
{
writeDStarBERInt(ber);
}
void CDisplay::clearDStar()
{
if (m_timer1.hasExpired()) {
@ -122,6 +127,11 @@ void CDisplay::writeDMRRSSI(unsigned int slotNo, unsigned char rssi)
writeDMRRSSIInt(slotNo, rssi);
}
void CDisplay::writeDMRBER(unsigned int slotNo, float ber)
{
writeDMRBERInt(slotNo, ber);
}
void CDisplay::clearDMR(unsigned int slotNo)
{
if (slotNo == 1U) {
@ -162,6 +172,11 @@ void CDisplay::writeFusionRSSI(unsigned char rssi)
writeFusionRSSIInt(rssi);
}
void CDisplay::writeFusionBER(float ber)
{
writeFusionBERInt(ber);
}
void CDisplay::clearFusion()
{
if (m_timer1.hasExpired()) {
@ -190,6 +205,11 @@ void CDisplay::writeP25RSSI(unsigned char rssi)
writeP25RSSIInt(rssi);
}
void CDisplay::writeP25BER(float ber)
{
writeP25BERInt(ber);
}
void CDisplay::clearP25()
{
if (m_timer1.hasExpired()) {
@ -265,14 +285,30 @@ void CDisplay::writeDStarRSSIInt(unsigned char rssi)
{
}
void CDisplay::writeDStarBERInt(float ber)
{
}
void CDisplay::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi)
{
}
void CDisplay::writeDMRBERInt(unsigned int slotNo, float ber)
{
}
void CDisplay::writeFusionRSSIInt(unsigned char rssi)
{
}
void CDisplay::writeFusionBERInt(float ber)
{
}
void CDisplay::writeP25RSSIInt(unsigned char rssi)
{
}
void CDisplay::writeP25BERInt(float ber)
{
}

View file

@ -37,18 +37,22 @@ public:
void writeDStar(const char* my1, const char* my2, const char* your, const char* type, const char* reflector);
void writeDStarRSSI(unsigned char rssi);
void writeDStarBER(float ber);
void clearDStar();
void writeDMR(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
void writeDMRRSSI(unsigned int slotNo, unsigned char rssi);
void writeDMRBER(unsigned int slotNo, float ber);
void clearDMR(unsigned int slotNo);
void writeFusion(const char* source, const char* dest, const char* type, const char* origin);
void writeFusionRSSI(unsigned char rssi);
void writeFusionBER(float ber);
void clearFusion();
void writeP25(const char* source, bool group, unsigned int dest, const char* type);
void writeP25RSSI(unsigned char rssi);
void writeP25BER(float ber);
void clearP25();
void writeCW();
@ -65,18 +69,22 @@ protected:
virtual void writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector) = 0;
virtual void writeDStarRSSIInt(unsigned char rssi);
virtual void writeDStarBERInt(float ber);
virtual void clearDStarInt() = 0;
virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type) = 0;
virtual void writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi);
virtual void writeDMRBERInt(unsigned int slotNo, float ber);
virtual void clearDMRInt(unsigned int slotNo) = 0;
virtual void writeFusionInt(const char* source, const char* dest, const char* type, const char* origin) = 0;
virtual void writeFusionRSSIInt(unsigned char rssi);
virtual void writeFusionBERInt(float ber);
virtual void clearFusionInt() = 0;
virtual void writeP25Int(const char* source, bool group, unsigned int dest, const char* type) = 0;
virtual void writeP25RSSIInt(unsigned char rssi);
virtual void writeP25BERInt(float ber);
virtual void clearP25Int() = 0;
virtual void writeCWInt() = 0;

View file

@ -69,6 +69,7 @@ Beacons=1
Id=123456
ColorCode=1
SelfOnly=0
EmbeddedLCOnly=0
# Prefixes=234,235
# Slot1TGWhiteList=
# Slot2TGWhiteList=

View file

@ -345,6 +345,7 @@ int CMMDVMHost::run()
unsigned int id = m_conf.getDMRId();
unsigned int colorCode = m_conf.getDMRColorCode();
bool selfOnly = m_conf.getDMRSelfOnly();
bool embeddedLCOnly = m_conf.getDMREmbeddedLCOnly();
std::vector<unsigned int> prefixes = m_conf.getDMRPrefixes();
std::vector<unsigned int> blackList = m_conf.getDMRBlackList();
std::vector<unsigned int> whiteList = m_conf.getDMRWhiteList();
@ -366,6 +367,7 @@ int CMMDVMHost::run()
LogInfo(" Id: %u", id);
LogInfo(" Color Code: %u", colorCode);
LogInfo(" Self Only: %s", selfOnly ? "yes" : "no");
LogInfo(" Embedded LC Only: %s", embeddedLCOnly ? "yes" : "no");
LogInfo(" Prefixes: %u", prefixes.size());
if (blackList.size() > 0U)
@ -380,7 +382,7 @@ int CMMDVMHost::run()
LogInfo(" Call Hang: %us", callHang);
LogInfo(" TX Hang: %us", txHang);
dmr = new CDMRControl(id, colorCode, callHang, selfOnly, prefixes, blackList, whiteList, slot1TGWhiteList, slot2TGWhiteList, m_timeout, m_modem, m_dmrNetwork, m_display, m_duplex, m_lookup, rssi, jitter);
dmr = new CDMRControl(id, colorCode, callHang, selfOnly, embeddedLCOnly, prefixes, blackList, whiteList, slot1TGWhiteList, slot2TGWhiteList, m_timeout, m_modem, m_dmrNetwork, m_display, m_duplex, m_lookup, rssi, jitter);
m_dmrTXTimer.setTimeout(txHang);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2016 by Jonathan Naylor G4KLX
* Copyright (C) 2011-2017 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -71,6 +71,8 @@ const unsigned char MMDVM_NAK = 0x7FU;
const unsigned char MMDVM_SERIAL = 0x80U;
const unsigned char MMDVM_SAMPLES = 0xF0U;
const unsigned char MMDVM_DEBUG1 = 0xF1U;
const unsigned char MMDVM_DEBUG2 = 0xF2U;
const unsigned char MMDVM_DEBUG3 = 0xF3U;
@ -463,6 +465,18 @@ void CModem::clock(unsigned int ms)
LogWarning("Received a NAK from the MMDVM, command = 0x%02X, reason = %u", m_buffer[3U], m_buffer[4U]);
break;
case MMDVM_DEBUG1:
case MMDVM_DEBUG2:
case MMDVM_DEBUG3:
case MMDVM_DEBUG4:
case MMDVM_DEBUG5:
printDebug();
break;
case MMDVM_SAMPLES:
printSamples();
break;
default:
LogMessage("Unknown message, type: %02X", m_buffer[2U]);
CUtils::dump("Buffer dump", m_buffer, m_length);
@ -1110,38 +1124,6 @@ RESP_TYPE_MMDVM CModem::getResponse()
if (ret == 0)
return RTM_TIMEOUT;
switch (m_buffer[2U]) {
case MMDVM_DSTAR_HEADER:
case MMDVM_DSTAR_DATA:
case MMDVM_DSTAR_LOST:
case MMDVM_DSTAR_EOT:
case MMDVM_DMR_DATA1:
case MMDVM_DMR_DATA2:
case MMDVM_DMR_LOST1:
case MMDVM_DMR_LOST2:
case MMDVM_YSF_DATA:
case MMDVM_YSF_LOST:
case MMDVM_P25_HDR:
case MMDVM_P25_LDU:
case MMDVM_P25_LOST:
case MMDVM_GET_STATUS:
case MMDVM_GET_VERSION:
case MMDVM_ACK:
case MMDVM_NAK:
case MMDVM_SERIAL:
case MMDVM_DEBUG1:
case MMDVM_DEBUG2:
case MMDVM_DEBUG3:
case MMDVM_DEBUG4:
case MMDVM_DEBUG5:
break;
default:
LogError("Unknown message, type: %02X", m_buffer[2U]);
m_offset = 0U;
return RTM_ERROR;
}
m_offset = 3U;
}
@ -1164,19 +1146,9 @@ RESP_TYPE_MMDVM CModem::getResponse()
m_offset = 0U;
switch (m_buffer[2U]) {
case MMDVM_DEBUG1:
case MMDVM_DEBUG2:
case MMDVM_DEBUG3:
case MMDVM_DEBUG4:
case MMDVM_DEBUG5:
printDebug();
return RTM_TIMEOUT;
// CUtils::dump(1U, "Received", m_buffer, m_length);
default:
// CUtils::dump(1U, "Received", m_buffer, m_length);
return RTM_OK;
}
return RTM_OK;
}
HW_TYPE CModem::getHWType() const
@ -1304,3 +1276,40 @@ void CModem::printDebug()
LogMessage("Debug: %.*s %d %d %d %d", m_length - 11U, m_buffer + 3U, val1, val2, val3, val4);
}
}
void CModem::printSamples()
{
const char* mode = NULL;
switch (m_buffer[3U]) {
case MODE_DSTAR:
mode = "D-Star";
break;
case MODE_DMR:
mode = "DMR";
break;
case MODE_YSF:
mode = "YSF";
break;
case MODE_P25:
mode = "P25";
break;
default:
mode = "???";
break;
}
char samples[250U];
samples[0U] = '\0';
unsigned char n = (m_buffer[1U] - 4U) / 2U;
for (unsigned char i = 0U; i < n; i++) {
unsigned char index = i * 2U + 4U;
short val = (m_buffer[index + 0U] << 8) | m_buffer[index + 1U];
::sprintf(samples + ::strlen(samples), " %d", val - 2048);
}
LogMessage("Debug: Samples dump: %s:%s", mode, samples);
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2016 by Jonathan Naylor G4KLX
* Copyright (C) 2011-2017 by Jonathan Naylor G4KLX
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -143,6 +143,7 @@ private:
bool setFrequency();
void printDebug();
void printSamples();
RESP_TYPE_MMDVM getResponse();
};

View file

@ -25,10 +25,14 @@
#include <ctime>
#include <clocale>
const unsigned int DSTAR_RSSI_COUNT = 3U; // 3 * 420ms = 1260ms
const unsigned int DMR_RSSI_COUNT = 4U; // 4 * 360ms = 1440ms
const unsigned int DSTAR_RSSI_COUNT = 3U; // 3 * 420ms = 1260ms
const unsigned int DSTAR_BER_COUNT = 63U; // 63 * 20ms = 1260ms
const unsigned int DMR_RSSI_COUNT = 4U; // 4 * 360ms = 1440ms
const unsigned int DMR_BER_COUNT = 24U; // 24 * 60ms = 1440ms
const unsigned int YSF_RSSI_COUNT = 13U; // 13 * 100ms = 1300ms
const unsigned int P25_RSSI_COUNT = 7U; // 7 * 180ms = 1260ms
const unsigned int YSF_BER_COUNT = 13U; // 13 * 100ms = 1300ms
const unsigned int P25_RSSI_COUNT = 7U; // 7 * 180ms = 1260ms
const unsigned int P25_BER_COUNT = 7U; // 7 * 180ms = 1260ms
CNextion::CNextion(const std::string& callsign, unsigned int dmrid, ISerialPort* serial, unsigned int brightness, bool displayClock, bool utc, unsigned int idleBrightness) :
CDisplay(),
@ -41,8 +45,14 @@ m_displayClock(displayClock),
m_utc(utc),
m_idleBrightness(idleBrightness),
m_clockDisplayTimer(1000U, 0U, 400U),
m_rssiAccum1(0U),
m_rssiAccum2(0U),
m_berAccum1(0.0F),
m_berAccum2(0.0F),
m_rssiCount1(0U),
m_rssiCount2(0U)
m_rssiCount2(0U),
m_berCount1(0U),
m_berCount2(0U)
{
assert(serial != NULL);
assert(brightness >= 0U && brightness <= 100U);
@ -150,7 +160,10 @@ void CNextion::writeDStarInt(const char* my1, const char* my2, const char* your,
m_clockDisplayTimer.stop();
m_mode = MODE_DSTAR;
m_rssiAccum1 = 0U;
m_berAccum1 = 0.0F;
m_rssiCount1 = 0U;
m_berCount1 = 0U;
}
void CNextion::writeDStarRSSIInt(unsigned char rssi)
@ -159,11 +172,42 @@ void CNextion::writeDStarRSSIInt(unsigned char rssi)
char text[20U];
::sprintf(text, "t3.txt=\"-%udBm\"", rssi);
sendCommand(text);
m_rssiCount1 = 1U;
return;
}
m_rssiAccum1 += rssi;
m_rssiCount1++;
if (m_rssiCount1 >= DSTAR_RSSI_COUNT)
m_rssiCount1 = 0U;
if (m_rssiCount1 == DSTAR_RSSI_COUNT) {
char text[20U];
::sprintf(text, "t3.txt=\"-%udBm\"", m_rssiAccum1 / DSTAR_RSSI_COUNT);
sendCommand(text);
m_rssiAccum1 = 0U;
m_rssiCount1 = 1U;
}
}
void CNextion::writeDStarBERInt(float ber)
{
if (m_berCount1 == 0U) {
char text[20U];
::sprintf(text, "t4.txt=\"%.1f%%\"", ber);
sendCommand(text);
m_berCount1 = 1U;
return;
}
m_berAccum1 += ber;
m_berCount1++;
if (m_berCount1 == DSTAR_BER_COUNT) {
char text[20U];
::sprintf(text, "t4.txt=\"%.1f%%\"", m_berAccum1 / float(DSTAR_BER_COUNT));
sendCommand(text);
m_berAccum1 = 0.0F;
m_berCount1 = 1U;
}
}
void CNextion::clearDStarInt()
@ -172,6 +216,7 @@ void CNextion::clearDStarInt()
sendCommand("t1.txt=\"\"");
sendCommand("t2.txt=\"\"");
sendCommand("t3.txt=\"\"");
sendCommand("t4.txt=\"\"");
}
void CNextion::writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type)
@ -208,8 +253,14 @@ void CNextion::writeDMRInt(unsigned int slotNo, const std::string& src, bool gro
m_clockDisplayTimer.stop();
m_mode = MODE_DMR;
m_rssiAccum1 = 0U;
m_rssiAccum2 = 0U;
m_berAccum1 = 0.0F;
m_berAccum2 = 0.0F;
m_rssiCount1 = 0U;
m_rssiCount2 = 0U;
m_berCount1 = 0U;
m_berCount2 = 0U;
}
void CNextion::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi)
@ -219,21 +270,82 @@ void CNextion::writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi)
char text[20U];
::sprintf(text, "t4.txt=\"-%udBm\"", rssi);
sendCommand(text);
m_rssiCount1 = 1U;
return;
}
m_rssiAccum1 += rssi;
m_rssiCount1++;
if (m_rssiCount1 >= DMR_RSSI_COUNT)
m_rssiCount1 = 0U;
if (m_rssiCount1 == DMR_RSSI_COUNT) {
char text[20U];
::sprintf(text, "t4.txt=\"-%udBm\"", m_rssiAccum1 / DMR_RSSI_COUNT);
sendCommand(text);
m_rssiAccum1 = 0U;
m_rssiCount1 = 1U;
}
} else {
if (m_rssiCount2 == 0U) {
char text[20U];
::sprintf(text, "t5.txt=\"-%udBm\"", rssi);
sendCommand(text);
m_rssiCount2 = 1U;
return;
}
m_rssiAccum2 += rssi;
m_rssiCount2++;
if (m_rssiCount2 >= DMR_RSSI_COUNT)
m_rssiCount2 = 0U;
if (m_rssiCount2 == DMR_RSSI_COUNT) {
char text[20U];
::sprintf(text, "t5.txt=\"-%udBm\"", m_rssiAccum2 / DMR_RSSI_COUNT);
sendCommand(text);
m_rssiAccum2 = 0U;
m_rssiCount2 = 1U;
}
}
}
void CNextion::writeDMRBERInt(unsigned int slotNo, float ber)
{
if (slotNo == 1U) {
if (m_berCount1 == 0U) {
char text[20U];
::sprintf(text, "t6.txt=\"%.1f%%\"", ber);
sendCommand(text);
m_berCount1 = 1U;
return;
}
m_berAccum1 += ber;
m_berCount1++;
if (m_berCount1 == DMR_BER_COUNT) {
char text[20U];
::sprintf(text, "t6.txt=\"%.1f%%\"", m_berAccum1 / DMR_BER_COUNT);
sendCommand(text);
m_berAccum1 = 0U;
m_berCount1 = 1U;
}
} else {
if (m_berCount2 == 0U) {
char text[20U];
::sprintf(text, "t7.txt=\"%.1f%%\"", ber);
sendCommand(text);
m_berCount2 = 1U;
return;
}
m_berAccum2 += ber;
m_berCount2++;
if (m_berCount2 == DMR_BER_COUNT) {
char text[20U];
::sprintf(text, "t7.txt=\"%.1f%%\"", m_berAccum2 / DMR_BER_COUNT);
sendCommand(text);
m_berAccum2 = 0U;
m_berCount2 = 1U;
}
}
}
@ -243,10 +355,12 @@ void CNextion::clearDMRInt(unsigned int slotNo)
sendCommand("t0.txt=\"1 Listening\"");
sendCommand("t1.txt=\"\"");
sendCommand("t4.txt=\"\"");
sendCommand("t6.txt=\"\"");
} else {
sendCommand("t2.txt=\"2 Listening\"");
sendCommand("t3.txt=\"\"");
sendCommand("t5.txt=\"\"");
sendCommand("t7.txt=\"\"");
}
}
@ -277,7 +391,10 @@ void CNextion::writeFusionInt(const char* source, const char* dest, const char*
m_clockDisplayTimer.stop();
m_mode = MODE_YSF;
m_rssiAccum1 = 0U;
m_berAccum1 = 0.0F;
m_rssiCount1 = 0U;
m_berCount1 = 0U;
}
void CNextion::writeFusionRSSIInt(unsigned char rssi)
@ -286,11 +403,42 @@ void CNextion::writeFusionRSSIInt(unsigned char rssi)
char text[20U];
::sprintf(text, "t3.txt=\"-%udBm\"", rssi);
sendCommand(text);
m_rssiCount1 = 1U;
return;
}
m_rssiAccum1 += rssi;
m_rssiCount1++;
if (m_rssiCount1 >= YSF_RSSI_COUNT)
m_rssiCount1 = 0U;
if (m_rssiCount1 == YSF_RSSI_COUNT) {
char text[20U];
::sprintf(text, "t3.txt=\"-%udBm\"", m_rssiAccum1 / YSF_RSSI_COUNT);
sendCommand(text);
m_rssiAccum1 = 0U;
m_rssiCount1 = 1U;
}
}
void CNextion::writeFusionBERInt(float ber)
{
if (m_berCount1 == 0U) {
char text[20U];
::sprintf(text, "t4.txt=\"%.1f%%\"", ber);
sendCommand(text);
m_berCount1 = 1U;
return;
}
m_berAccum1 += ber;
m_berCount1++;
if (m_berCount1 == YSF_BER_COUNT) {
char text[20U];
::sprintf(text, "t4.txt=\"%.1f%%\"", m_berAccum1 / float(YSF_BER_COUNT));
sendCommand(text);
m_berAccum1 = 0.0F;
m_berCount1 = 1U;
}
}
void CNextion::clearFusionInt()
@ -299,6 +447,7 @@ void CNextion::clearFusionInt()
sendCommand("t1.txt=\"\"");
sendCommand("t2.txt=\"\"");
sendCommand("t3.txt=\"\"");
sendCommand("t4.txt=\"\"");
}
void CNextion::writeP25Int(const char* source, bool group, unsigned int dest, const char* type)
@ -322,7 +471,10 @@ void CNextion::writeP25Int(const char* source, bool group, unsigned int dest, co
m_clockDisplayTimer.stop();
m_mode = MODE_P25;
m_rssiAccum1 = 0U;
m_berAccum1 = 0.0F;
m_rssiCount1 = 0U;
m_berCount1 = 0U;
}
void CNextion::writeP25RSSIInt(unsigned char rssi)
@ -331,11 +483,42 @@ void CNextion::writeP25RSSIInt(unsigned char rssi)
char text[20U];
::sprintf(text, "t2.txt=\"-%udBm\"", rssi);
sendCommand(text);
m_rssiCount1 = 1U;
return;
}
m_rssiAccum1 += rssi;
m_rssiCount1++;
if (m_rssiCount1 >= P25_RSSI_COUNT)
m_rssiCount1 = 0U;
if (m_rssiCount1 == P25_RSSI_COUNT) {
char text[20U];
::sprintf(text, "t2.txt=\"-%udBm\"", m_rssiAccum1 / P25_RSSI_COUNT);
sendCommand(text);
m_rssiAccum1 = 0U;
m_rssiCount1 = 1U;
}
}
void CNextion::writeP25BERInt(float ber)
{
if (m_berCount1 == 0U) {
char text[20U];
::sprintf(text, "t3.txt=\"%.1f%%\"", ber);
sendCommand(text);
m_berCount1 = 1U;
return;
}
m_berAccum1 += ber;
m_berCount1++;
if (m_berCount1 == P25_BER_COUNT) {
char text[20U];
::sprintf(text, "t3.txt=\"%.1f%%\"", m_berAccum1 / float(P25_BER_COUNT));
sendCommand(text);
m_berAccum1 = 0.0F;
m_berCount1 = 1U;
}
}
void CNextion::clearP25Int()
@ -343,6 +526,7 @@ void CNextion::clearP25Int()
sendCommand("t0.txt=\"Listening\"");
sendCommand("t1.txt=\"\"");
sendCommand("t2.txt=\"\"");
sendCommand("t3.txt=\"\"");
}
void CNextion::writeCWInt()

View file

@ -43,18 +43,22 @@ protected:
virtual void writeDStarInt(const char* my1, const char* my2, const char* your, const char* type, const char* reflector);
virtual void writeDStarRSSIInt(unsigned char rssi);
virtual void writeDStarBERInt(float ber);
virtual void clearDStarInt();
virtual void writeDMRInt(unsigned int slotNo, const std::string& src, bool group, const std::string& dst, const char* type);
virtual void writeDMRRSSIInt(unsigned int slotNo, unsigned char rssi);
virtual void writeDMRBERInt(unsigned int slotNo, float ber);
virtual void clearDMRInt(unsigned int slotNo);
virtual void writeFusionInt(const char* source, const char* dest, const char* type, const char* origin);
virtual void writeFusionRSSIInt(unsigned char rssi);
virtual void writeFusionBERInt(float ber);
virtual void clearFusionInt();
virtual void writeP25Int(const char* source, bool group, unsigned int dest, const char* type);
virtual void writeP25RSSIInt(unsigned char rssi);
virtual void writeP25BERInt(float ber);
virtual void clearP25Int();
virtual void writeCWInt();
@ -72,8 +76,14 @@ private:
bool m_utc;
unsigned int m_idleBrightness;
CTimer m_clockDisplayTimer;
unsigned int m_rssiAccum1;
unsigned int m_rssiAccum2;
float m_berAccum1;
float m_berAccum2;
unsigned int m_rssiCount1;
unsigned int m_rssiCount2;
unsigned int m_berCount1;
unsigned int m_berCount2;
void sendCommand(const char* command);
};

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

BIN
Nextion/NX4827K043.HMI Normal file

Binary file not shown.

BIN
Nextion/NX4827K043.tft Normal file

Binary file not shown.

BIN
Nextion/NX4827T043.HMI Normal file

Binary file not shown.

BIN
Nextion/NX4827T043.tft Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -207,7 +207,9 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
// Regenerate Audio
unsigned int errors = m_audio.process(data + 2U);
LogDebug("P25, LDU1 audio, errs: %u/1233", errors);
LogDebug("P25, LDU1 audio, errs: %u/1233 (%.1f%%)", errors, float(errors) / 12.33F);
m_display->writeP25BER(float(errors) / 12.33F);
m_rfBits += 1233U;
m_rfErrs += errors;
@ -260,7 +262,9 @@ bool CP25Control::writeModem(unsigned char* data, unsigned int len)
// Regenerate Audio
unsigned int errors = m_audio.process(data + 2U);
LogDebug("P25, LDU2 audio, errs: %u/1233", errors);
LogDebug("P25, LDU2 audio, errs: %u/1233 (%.1f%%)", errors, float(errors) / 12.33F);
m_display->writeP25BER(float(errors) / 12.33F);
m_rfBits += 1233U;
m_rfErrs += errors;

View file

@ -1,32 +0,0 @@
To use DMR Access Control you can add the following fields to your MMDVM.ini:
Blacklist= <comma separated list of source-id's to block on RF>
DstIdBlackListSlot1RF= <comma separated list TGs to block on RF Slot1>
DstIdBlackListSlot2RF= <comma separated list TGs to block on RF Slot2>
DstIdWhiteListSlot1RF= <comma separated list TGs to allow on RF Slot1>
DstIdWhiteListSlot2RF= <comma separated list TGs to allow on RF Slot2>
DstIdBlackListSlot1NET= <comma separated list TGs to block on NET Slot1>
DstIdBlackListSlot2NET= <comma separated list TGs to block on NET Slot2>
DstIdWhiteListSlot1NET= <comma separated list TGs to allow on NET Slot1>
DstIdWhiteListSlot2NET= <comma separated list TGs to allow on NET Slot2>
So, for example:
DstIdBlackListSlot1=91 - block the TG91 net.
DstIdWhiteListSlot1=9.5057,9990 - allows TG9, APRS SMS Gateway and Echo.
If the whitelist is null and commented out, it is disabled.
The whitelist behaves slightly differently on Slot1 than is does on Slot2.
For Slot1, the whitelist will allow all IDs above 99999 and everything in the whitelist.
For Slot2, the whitelist will allow all IDs between 4000 and 5000, IDs above 99999 and everything in the whitelist.
You can use the blacklist with the whitelist if you want to specifically block IDs within the allowed ranges above.
For example, to block users from disconnecting the reflectors, you could block ID 4000.
To block users connecting to reflector 4400 you could add ID 4400 to the network blacklist for that slot.

View file

@ -19,6 +19,6 @@
#if !defined(VERSION_H)
#define VERSION_H
const char* VERSION = "20161230";
const char* VERSION = "20170206";
#endif

View file

@ -273,6 +273,7 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len)
unsigned int errors = m_rfPayload.processVDMode1Audio(data + 2U);
m_rfErrs += errors;
m_rfBits += 235U;
m_display->writeFusionBER(float(errors) / 2.35F);
LogDebug("YSF, V/D Mode 1, seq %u, AMBE FEC %u/235 (%.1f%%)", m_rfFrames % 128, errors, float(errors) / 2.35F);
}
break;
@ -282,6 +283,7 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len)
unsigned int errors = m_rfPayload.processVDMode2Audio(data + 2U);
m_rfErrs += errors;
m_rfBits += 135U;
m_display->writeFusionBER(float(errors) / 1.35F);
LogDebug("YSF, V/D Mode 2, seq %u, Repetition FEC %u/135 (%.1f%%)", m_rfFrames % 128, errors, float(errors) / 1.35F);
}
break;
@ -297,6 +299,7 @@ bool CYSFControl::writeModem(unsigned char *data, unsigned int len)
unsigned int errors = m_rfPayload.processVoiceFRModeAudio(data + 2U);
m_rfErrs += errors;
m_rfBits += 720U;
m_display->writeFusionBER(float(errors) / 7.2F);
LogDebug("YSF, V Mode 3, seq %u, AMBE FEC %u/720 (%.1f%%)", m_rfFrames % 128, errors, float(errors) / 7.2F);
}
valid = false;
@ -513,8 +516,6 @@ void CYSFControl::writeNetwork()
CYSFFICH fich;
bool valid = fich.decode(data + 35U);
if (valid) {
unsigned char bn = fich.getBN();
unsigned char bt = fich.getBT();
unsigned char dt = fich.getDT();
unsigned char fn = fich.getFN();
unsigned char ft = fich.getFT();
@ -542,7 +543,6 @@ void CYSFControl::writeNetwork()
// if (send) {
m_netErrs += errors;
m_netBits += 235U;
LogDebug("YSF, V/D Mode 1, seq %u, AMBE FEC %u/235 (%.1f%%)", n, errors, float(errors) / 2.35F);
// }
}
break;
@ -554,13 +554,11 @@ void CYSFControl::writeNetwork()
// if (send) {
m_netErrs += errors;
m_netBits += 135U;
LogDebug("YSF, V/D Mode 2, seq %u, Repetition FEC %u/135 (%.1f%%)", n, errors, float(errors) / 1.35F);
// }
}
break;
case YSF_DT_DATA_FR_MODE:
LogDebug("YSF, Network data FICH B=%u/%u F=%u/%u", bn, bt, fn, ft);
m_netPayload.processDataFRModeData(data + 35U, fn, gateway);
break;
@ -572,7 +570,6 @@ void CYSFControl::writeNetwork()
// if (send) {
m_netErrs += errors;
m_netBits += 720U;
LogDebug("YSF, V Mode 3, seq %u, AMBE FEC %u/720 (%.1f%%)", n, errors, float(errors) / 7.2F);
// }
}
break;