mirror of
https://github.com/g4klx/MMDVMHost
synced 2025-12-21 06:55:52 +08:00
Add new processing for D-Star Fast Data which doesn't clobber normal
D-Star audio.
This commit is contained in:
9
Conf.cpp
9
Conf.cpp
@@ -161,6 +161,7 @@ m_dmrCallHang(10U),
|
|||||||
m_dmrTXHang(4U),
|
m_dmrTXHang(4U),
|
||||||
m_dmrModeHang(10U),
|
m_dmrModeHang(10U),
|
||||||
m_dmrOVCM(DMR_OVCM_OFF),
|
m_dmrOVCM(DMR_OVCM_OFF),
|
||||||
|
m_dmrProtect(false),
|
||||||
m_fusionEnabled(false),
|
m_fusionEnabled(false),
|
||||||
m_fusionLowDeviation(false),
|
m_fusionLowDeviation(false),
|
||||||
m_fusionRemoteGateway(false),
|
m_fusionRemoteGateway(false),
|
||||||
@@ -753,7 +754,8 @@ bool CConf::read()
|
|||||||
m_dmrOVCM = DMR_OVCM_OFF;
|
m_dmrOVCM = DMR_OVCM_OFF;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else if (::strcmp(key, "Protect") == 0)
|
||||||
|
m_dmrProtect = ::atoi(value) == 1;
|
||||||
} 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;
|
||||||
@@ -1643,6 +1645,11 @@ DMR_OVCM_TYPES CConf::getDMROVCM() const
|
|||||||
return m_dmrOVCM;
|
return m_dmrOVCM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool CConf::getDMRProtect() const
|
||||||
|
{
|
||||||
|
return m_dmrProtect;
|
||||||
|
}
|
||||||
|
|
||||||
bool CConf::getFusionEnabled() const
|
bool CConf::getFusionEnabled() const
|
||||||
{
|
{
|
||||||
return m_fusionEnabled;
|
return m_fusionEnabled;
|
||||||
|
|||||||
2
Conf.h
2
Conf.h
@@ -144,6 +144,7 @@ public:
|
|||||||
unsigned int getDMRTXHang() const;
|
unsigned int getDMRTXHang() const;
|
||||||
unsigned int getDMRModeHang() const;
|
unsigned int getDMRModeHang() const;
|
||||||
DMR_OVCM_TYPES getDMROVCM() const;
|
DMR_OVCM_TYPES getDMROVCM() const;
|
||||||
|
bool getDMRProtect() const;
|
||||||
|
|
||||||
// The System Fusion section
|
// The System Fusion section
|
||||||
bool getFusionEnabled() const;
|
bool getFusionEnabled() const;
|
||||||
@@ -481,6 +482,7 @@ private:
|
|||||||
unsigned int m_dmrTXHang;
|
unsigned int m_dmrTXHang;
|
||||||
unsigned int m_dmrModeHang;
|
unsigned int m_dmrModeHang;
|
||||||
DMR_OVCM_TYPES m_dmrOVCM;
|
DMR_OVCM_TYPES m_dmrOVCM;
|
||||||
|
bool m_dmrProtect;
|
||||||
|
|
||||||
bool m_fusionEnabled;
|
bool m_fusionEnabled;
|
||||||
bool m_fusionLowDeviation;
|
bool m_fusionLowDeviation;
|
||||||
|
|||||||
@@ -21,7 +21,7 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, bool embeddedLCOnly, bool dumpTAData, 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, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter, DMR_OVCM_TYPES ovcm) :
|
CDMRControl::CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, bool embeddedLCOnly, bool dumpTAData, 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, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter, DMR_OVCM_TYPES ovcm, bool protect) :
|
||||||
m_colorCode(colorCode),
|
m_colorCode(colorCode),
|
||||||
m_modem(modem),
|
m_modem(modem),
|
||||||
m_network(network),
|
m_network(network),
|
||||||
@@ -38,7 +38,7 @@ m_lookup(lookup)
|
|||||||
// Load black and white lists to DMRAccessControl
|
// Load black and white lists to DMRAccessControl
|
||||||
CDMRAccessControl::init(blacklist, whitelist, slot1TGWhitelist, slot2TGWhitelist, selfOnly, prefixes, id);
|
CDMRAccessControl::init(blacklist, whitelist, slot1TGWhitelist, slot2TGWhitelist, selfOnly, prefixes, id);
|
||||||
|
|
||||||
CDMRSlot::init(colorCode, embeddedLCOnly, dumpTAData, callHang, modem, network, display, duplex, m_lookup, rssi, jitter, ovcm);
|
CDMRSlot::init(colorCode, embeddedLCOnly, dumpTAData, callHang, modem, network, display, duplex, m_lookup, rssi, jitter, ovcm, protect);
|
||||||
}
|
}
|
||||||
|
|
||||||
CDMRControl::~CDMRControl()
|
CDMRControl::~CDMRControl()
|
||||||
|
|||||||
@@ -31,7 +31,7 @@
|
|||||||
|
|
||||||
class CDMRControl {
|
class CDMRControl {
|
||||||
public:
|
public:
|
||||||
CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, bool embeddedLCOnly, bool dumpTAData, 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, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter, DMR_OVCM_TYPES ovcm);
|
CDMRControl(unsigned int id, unsigned int colorCode, unsigned int callHang, bool selfOnly, bool embeddedLCOnly, bool dumpTAData, 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, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssi, unsigned int jitter, DMR_OVCM_TYPES ovcm, bool protect);
|
||||||
~CDMRControl();
|
~CDMRControl();
|
||||||
|
|
||||||
bool processWakeup(const unsigned char* data);
|
bool processWakeup(const unsigned char* data);
|
||||||
|
|||||||
33
DMRSlot.cpp
33
DMRSlot.cpp
@@ -44,6 +44,7 @@ bool CDMRSlot::m_duplex = true;
|
|||||||
CDMRLookup* CDMRSlot::m_lookup = NULL;
|
CDMRLookup* CDMRSlot::m_lookup = NULL;
|
||||||
unsigned int CDMRSlot::m_hangCount = 3U * 17U;
|
unsigned int CDMRSlot::m_hangCount = 3U * 17U;
|
||||||
DMR_OVCM_TYPES CDMRSlot::m_ovcm = DMR_OVCM_OFF;
|
DMR_OVCM_TYPES CDMRSlot::m_ovcm = DMR_OVCM_OFF;
|
||||||
|
bool CDMRSlot::m_protect = false;
|
||||||
|
|
||||||
CRSSIInterpolator* CDMRSlot::m_rssiMapper = NULL;
|
CRSSIInterpolator* CDMRSlot::m_rssiMapper = NULL;
|
||||||
|
|
||||||
@@ -222,6 +223,15 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||||||
unsigned int dstId = lc->getDstId();
|
unsigned int dstId = lc->getDstId();
|
||||||
FLCO flco = lc->getFLCO();
|
FLCO flco = lc->getFLCO();
|
||||||
|
|
||||||
|
if (!m_protect) {
|
||||||
|
if (lc->getPF()) {
|
||||||
|
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
||||||
|
delete lc;
|
||||||
|
m_rfState = RS_RF_LISTENING;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
||||||
delete lc;
|
delete lc;
|
||||||
@@ -320,10 +330,12 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||||||
data[0U] = TAG_DATA;
|
data[0U] = TAG_DATA;
|
||||||
data[1U] = 0x00U;
|
data[1U] = 0x00U;
|
||||||
|
|
||||||
if (m_duplex)
|
if (m_protect) {
|
||||||
writeQueueRF(data);
|
if (m_duplex)
|
||||||
|
writeQueueRF(data);
|
||||||
|
|
||||||
writeNetworkRF(data, DT_VOICE_PI_HEADER);
|
writeNetworkRF(data, DT_VOICE_PI_HEADER);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} else if (dataType == DT_TERMINATOR_WITH_LC) {
|
} else if (dataType == DT_TERMINATOR_WITH_LC) {
|
||||||
@@ -810,6 +822,15 @@ bool CDMRSlot::writeModem(unsigned char *data, unsigned int len)
|
|||||||
unsigned int dstId = lc->getDstId();
|
unsigned int dstId = lc->getDstId();
|
||||||
FLCO flco = lc->getFLCO();
|
FLCO flco = lc->getFLCO();
|
||||||
|
|
||||||
|
if (!m_protect) {
|
||||||
|
if (lc->getPF()) {
|
||||||
|
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
||||||
|
delete lc;
|
||||||
|
m_rfState = RS_RF_LISTENING;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
if (!CDMRAccessControl::validateSrcId(srcId)) {
|
||||||
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
LogMessage("DMR Slot %u, RF user %u rejected", m_slotNo, srcId);
|
||||||
delete lc;
|
delete lc;
|
||||||
@@ -1246,7 +1267,8 @@ void CDMRSlot::writeNetwork(const CDMRData& dmrData)
|
|||||||
data[0U] = TAG_DATA;
|
data[0U] = TAG_DATA;
|
||||||
data[1U] = 0x00U;
|
data[1U] = 0x00U;
|
||||||
|
|
||||||
writeQueueNet(data);
|
if (m_protect)
|
||||||
|
writeQueueNet(data);
|
||||||
|
|
||||||
#if defined(DUMP_DMR)
|
#if defined(DUMP_DMR)
|
||||||
writeFile(data);
|
writeFile(data);
|
||||||
@@ -1957,7 +1979,7 @@ void CDMRSlot::writeQueueNet(const unsigned char *data)
|
|||||||
m_queue.addData(data, len);
|
m_queue.addData(data, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDMRSlot::init(unsigned int colorCode, bool embeddedLCOnly, bool dumpTAData, unsigned int callHang, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter, DMR_OVCM_TYPES ovcm)
|
void CDMRSlot::init(unsigned int colorCode, bool embeddedLCOnly, bool dumpTAData, unsigned int callHang, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter, DMR_OVCM_TYPES ovcm, bool protect)
|
||||||
{
|
{
|
||||||
assert(modem != NULL);
|
assert(modem != NULL);
|
||||||
assert(display != NULL);
|
assert(display != NULL);
|
||||||
@@ -1974,6 +1996,7 @@ void CDMRSlot::init(unsigned int colorCode, bool embeddedLCOnly, bool dumpTAData
|
|||||||
m_lookup = lookup;
|
m_lookup = lookup;
|
||||||
m_hangCount = callHang * 17U;
|
m_hangCount = callHang * 17U;
|
||||||
m_ovcm = ovcm;
|
m_ovcm = ovcm;
|
||||||
|
m_protect = protect;
|
||||||
|
|
||||||
m_rssiMapper = rssiMapper;
|
m_rssiMapper = rssiMapper;
|
||||||
|
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public:
|
|||||||
|
|
||||||
void enable(bool enabled);
|
void enable(bool enabled);
|
||||||
|
|
||||||
static void init(unsigned int colorCode, bool embeddedLCOnly, bool dumpTAData, unsigned int callHang, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter, DMR_OVCM_TYPES ovcm);
|
static void init(unsigned int colorCode, bool embeddedLCOnly, bool dumpTAData, unsigned int callHang, CModem* modem, IDMRNetwork* network, CDisplay* display, bool duplex, CDMRLookup* lookup, CRSSIInterpolator* rssiMapper, unsigned int jitter, DMR_OVCM_TYPES ovcm, bool protect);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned int m_slotNo;
|
unsigned int m_slotNo;
|
||||||
@@ -125,6 +125,7 @@ private:
|
|||||||
static CDMRLookup* m_lookup;
|
static CDMRLookup* m_lookup;
|
||||||
static unsigned int m_hangCount;
|
static unsigned int m_hangCount;
|
||||||
static DMR_OVCM_TYPES m_ovcm;
|
static DMR_OVCM_TYPES m_ovcm;
|
||||||
|
static bool m_protect;
|
||||||
|
|
||||||
static CRSSIInterpolator* m_rssiMapper;
|
static CRSSIInterpolator* m_rssiMapper;
|
||||||
|
|
||||||
|
|||||||
210
DStarControl.cpp
210
DStarControl.cpp
@@ -129,7 +129,7 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
|||||||
|
|
||||||
unsigned char type = data[0U];
|
unsigned char type = data[0U];
|
||||||
|
|
||||||
if (type == TAG_LOST && m_rfState == RS_RF_AUDIO) {
|
if (type == TAG_LOST && ((m_rfState == RS_RF_AUDIO) || (m_rfState == RS_RF_DATA))) {
|
||||||
unsigned char my1[DSTAR_LONG_CALLSIGN_LENGTH];
|
unsigned char my1[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||||
unsigned char my2[DSTAR_SHORT_CALLSIGN_LENGTH];
|
unsigned char my2[DSTAR_SHORT_CALLSIGN_LENGTH];
|
||||||
unsigned char your[DSTAR_LONG_CALLSIGN_LENGTH];
|
unsigned char your[DSTAR_LONG_CALLSIGN_LENGTH];
|
||||||
@@ -320,7 +320,7 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} else if (m_rfState == RS_RF_AUDIO) {
|
} else if ((m_rfState == RS_RF_AUDIO) || (m_rfState == RS_RF_DATA)) {
|
||||||
if (m_net)
|
if (m_net)
|
||||||
writeNetworkDataRF(DSTAR_END_PATTERN_BYTES, 0U, true);
|
writeNetworkDataRF(DSTAR_END_PATTERN_BYTES, 0U, true);
|
||||||
|
|
||||||
@@ -354,37 +354,75 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
|||||||
// The sync is regenerated by the modem so can do exact match
|
// The sync is regenerated by the modem so can do exact match
|
||||||
if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) {
|
if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) {
|
||||||
m_rfSlowData.start();
|
m_rfSlowData.start();
|
||||||
|
m_rfN = 0U;
|
||||||
m_rfState = RS_RF_LATE_ENTRY;
|
m_rfState = RS_RF_LATE_ENTRY;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_rfState == RS_RF_AUDIO) {
|
if ((m_rfState == RS_RF_AUDIO) || (m_rfState == RS_RF_DATA)) {
|
||||||
// The sync is regenerated by the modem so can do exact match
|
// The sync is regenerated by the modem so can do exact match
|
||||||
if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) {
|
if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) {
|
||||||
m_rfSlowData.start();
|
m_rfSlowData.start();
|
||||||
m_rfN = 0U;
|
m_rfN = 0U;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Regenerate the sync and send the RSSI data to the display
|
if (m_rfState == RS_RF_AUDIO) {
|
||||||
if (m_rfN == 0U) {
|
m_rfSlowData.peakSlowData(data + 1U, m_rfN);
|
||||||
CSync::addDStarSync(data + 1U);
|
unsigned char type = m_rfSlowData.getType();
|
||||||
m_display->writeDStarRSSI(m_rssi);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int errors = 0U;
|
if (type == DSTAR_SLOW_DATA_TYPE_FASTDATA_BEGIN) {
|
||||||
if (!m_rfHeader.isDataPacket()) {
|
LogMessage("D-Star, starting fast data mode");
|
||||||
errors = m_fec.regenerateDStar(data + 1U);
|
m_rfState = RS_RF_DATA;
|
||||||
m_display->writeDStarBER(float(errors) / 0.48F);
|
|
||||||
m_rfErrs += errors;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_rfState == RS_RF_DATA) {
|
||||||
|
LogDebug("D-Star, fast data sequence no. %u", m_rfN);
|
||||||
|
|
||||||
m_rfBits += 48U;
|
m_rfBits += 48U;
|
||||||
m_rfFrames++;
|
m_rfFrames++;
|
||||||
|
|
||||||
|
if (m_net)
|
||||||
|
writeNetworkDataRF(data, 0U, false);
|
||||||
|
|
||||||
|
if (m_duplex)
|
||||||
|
writeQueueDataRF(data);
|
||||||
|
|
||||||
|
m_rfSlowData.peakSlowData(data + 1U, m_rfN);
|
||||||
|
bool complete = m_rfSlowData.isComplete();
|
||||||
|
|
||||||
|
if (complete) {
|
||||||
|
unsigned char type = m_rfSlowData.getType();
|
||||||
|
if (type == DSTAR_SLOW_DATA_TYPE_FASTDATA_END) {
|
||||||
|
LogMessage("D-Star, leaving fast data mode");
|
||||||
|
m_rfState = RS_RF_AUDIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_rfN = (m_rfN + 1U) % 21U;
|
||||||
|
} else if (m_rfState == RS_RF_AUDIO) {
|
||||||
|
// Send the RSSI data to the display
|
||||||
|
if (m_rfN == 0U)
|
||||||
|
m_display->writeDStarRSSI(m_rssi);
|
||||||
|
|
||||||
|
unsigned int errors = 0U;
|
||||||
|
if (::memcmp(data + 1U, DSTAR_NULL_AMBE_DATA_BYTES_SCRAMBLED, DSTAR_VOICE_FRAME_LENGTH_BYTES) == 0) {
|
||||||
|
LogDebug("D-Star, audio sequence no. %u, null audio", m_rfN);
|
||||||
|
} else {
|
||||||
|
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_display->writeDStarBER(float(errors) / 0.48F);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_rfErrs += errors;
|
||||||
|
m_rfBits += 48U;
|
||||||
|
m_rfFrames++;
|
||||||
|
|
||||||
if (m_rfN != 0U) {
|
if (m_rfN != 0U) {
|
||||||
const unsigned char* text = m_rfSlowData.addText(data + 1U);
|
const unsigned char* text = m_rfSlowData.addText(data + 1U, m_rfN);
|
||||||
if (text != NULL)
|
if (text != NULL)
|
||||||
LogMessage("D-Star, RF slow data text = \"%s\"", text);
|
LogMessage("D-Star, RF slow data text = \"%s\"", text);
|
||||||
}
|
}
|
||||||
@@ -398,15 +436,20 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_rfN = (m_rfN + 1U) % 21U;
|
m_rfN = (m_rfN + 1U) % 21U;
|
||||||
} else if (m_rfState == RS_RF_LATE_ENTRY) {
|
}
|
||||||
|
|
||||||
|
if (m_rfState == RS_RF_LATE_ENTRY) {
|
||||||
// The sync is regenerated by the modem so can do exact match
|
// The sync is regenerated by the modem so can do exact match
|
||||||
if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) {
|
if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) {
|
||||||
m_rfSlowData.reset();
|
m_rfSlowData.reset();
|
||||||
|
m_rfN = 0U;
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
CDStarHeader* header = m_rfSlowData.addHeader(data + 1U);
|
CDStarHeader* header = m_rfSlowData.addHeader(data + 1U, m_rfN);
|
||||||
if (header == NULL)
|
if (header == NULL) {
|
||||||
|
m_rfN = (m_rfN + 1U) % 21U;
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
m_rfHeader = *header;
|
m_rfHeader = *header;
|
||||||
delete header;
|
delete header;
|
||||||
@@ -503,12 +546,14 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned int errors = 0U;
|
unsigned int errors = 0U;
|
||||||
if (!m_rfHeader.isDataPacket()) {
|
if (::memcmp(data + 1U, DSTAR_NULL_AMBE_DATA_BYTES_SCRAMBLED, DSTAR_VOICE_FRAME_LENGTH_BYTES) == 0) {
|
||||||
|
LogDebug("D-Star, audio sequence no. %u, null audio", m_rfN);
|
||||||
|
} else {
|
||||||
errors = m_fec.regenerateDStar(data + 1U);
|
errors = m_fec.regenerateDStar(data + 1U);
|
||||||
LogDebug("D-Star, audio sequence no. %u, errs: %u/48 (%.1f%%)", m_rfN, errors, 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_rfBits += 48U;
|
||||||
|
|
||||||
if (m_net)
|
if (m_net)
|
||||||
@@ -521,8 +566,6 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
|||||||
|
|
||||||
m_rfState = RS_RF_AUDIO;
|
m_rfState = RS_RF_AUDIO;
|
||||||
|
|
||||||
m_rfN = (m_rfN + 1U) % 21U;
|
|
||||||
|
|
||||||
if (m_netState == RS_NET_IDLE) {
|
if (m_netState == RS_NET_IDLE) {
|
||||||
m_display->writeDStar((char*)my1, (char*)my2, (char*)your, "R", " ");
|
m_display->writeDStar((char*)my1, (char*)my2, (char*)your, "R", " ");
|
||||||
m_display->writeDStarRSSI(m_rssi);
|
m_display->writeDStarRSSI(m_rssi);
|
||||||
@@ -530,6 +573,8 @@ bool CDStarControl::writeModem(unsigned char *data, unsigned int len)
|
|||||||
}
|
}
|
||||||
|
|
||||||
LogMessage("D-Star, received RF late entry from %8.8s/%4.4s to %8.8s", my1, my2, your);
|
LogMessage("D-Star, received RF late entry from %8.8s/%4.4s to %8.8s", my1, my2, your);
|
||||||
|
|
||||||
|
m_rfN = (m_rfN + 1U) % 21U;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
CUtils::dump("D-Star, unknown data from modem", data, DSTAR_FRAME_LENGTH_BYTES + 1U);
|
CUtils::dump("D-Star, unknown data from modem", data, DSTAR_FRAME_LENGTH_BYTES + 1U);
|
||||||
@@ -601,7 +646,7 @@ void CDStarControl::writeNetwork()
|
|||||||
if (!m_enabled)
|
if (!m_enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (m_rfState == RS_RF_AUDIO && m_netState == RS_NET_IDLE)
|
if (((m_rfState == RS_RF_AUDIO) || (m_rfState == RS_RF_DATA)) && (m_netState == RS_NET_IDLE))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
m_networkWatchdog.start();
|
m_networkWatchdog.start();
|
||||||
@@ -666,12 +711,9 @@ void CDStarControl::writeNetwork()
|
|||||||
LogMessage("D-Star, received network header from %8.8s/%4.4s to %8.8s", my1, my2, your);
|
LogMessage("D-Star, received network header from %8.8s/%4.4s to %8.8s", my1, my2, your);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Something just above here introduces a large delay forcing erroneous(?) insertion of silence packets.
|
|
||||||
// Starting the elapsed timer here instead of the commented out position above solves that.
|
|
||||||
m_elapsed.start();
|
m_elapsed.start();
|
||||||
|
|
||||||
} else if (type == TAG_EOT) {
|
} else if (type == TAG_EOT) {
|
||||||
if (m_netState != RS_NET_AUDIO)
|
if ((m_netState != RS_NET_AUDIO) && (m_netState != RS_NET_DATA))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
writeQueueEOTNet();
|
writeQueueEOTNet();
|
||||||
@@ -695,48 +737,96 @@ void CDStarControl::writeNetwork()
|
|||||||
|
|
||||||
writeEndNet();
|
writeEndNet();
|
||||||
} else if (type == TAG_DATA) {
|
} else if (type == TAG_DATA) {
|
||||||
if (m_netState != RS_NET_AUDIO)
|
if ((m_netState == RS_NET_AUDIO) || (m_netState == RS_NET_DATA)) {
|
||||||
return;
|
unsigned char n = data[1U];
|
||||||
|
|
||||||
unsigned int errors = 0U;
|
// The sync is regenerated by the modem so can do exact match
|
||||||
unsigned char n = data[1U];
|
if (::memcmp(data + 1U + DSTAR_VOICE_FRAME_LENGTH_BYTES, DSTAR_SYNC_BYTES, DSTAR_DATA_FRAME_LENGTH_BYTES) == 0) {
|
||||||
|
m_netSlowData.start();
|
||||||
|
} else {
|
||||||
|
m_netSlowData.peakSlowData(data + 1U, n);
|
||||||
|
|
||||||
if (!m_netHeader.isDataPacket())
|
if (m_netState == RS_NET_AUDIO) {
|
||||||
errors = m_fec.regenerateDStar(data + 2U);
|
unsigned char type = m_netSlowData.getType();
|
||||||
|
if (type == DSTAR_SLOW_DATA_TYPE_FASTDATA_BEGIN) {
|
||||||
blankDTMF(data + 2U);
|
LogMessage("D-Star, starting fast data mode");
|
||||||
|
m_netState = RS_NET_DATA;
|
||||||
data[1U] = TAG_DATA;
|
}
|
||||||
|
}
|
||||||
// Insert silence and reject if in the past
|
}
|
||||||
bool ret = insertSilence(data + 1U, n);
|
|
||||||
if (!ret)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_netErrs += errors;
|
|
||||||
m_netBits += 48U;
|
|
||||||
|
|
||||||
m_netN = n;
|
|
||||||
|
|
||||||
// Regenerate the sync
|
|
||||||
if (n == 0U) {
|
|
||||||
CSync::addDStarSync(data + 2U);
|
|
||||||
m_netSlowData.start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (n != 0U) {
|
if (m_netState == RS_NET_AUDIO) {
|
||||||
const unsigned char* text = m_netSlowData.addText(data + 2U);
|
unsigned char n = data[1U];
|
||||||
if (text != NULL)
|
|
||||||
LogMessage("D-Star, network slow data text = \"%s\"", text);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_packetTimer.start();
|
unsigned int errors = 0U;
|
||||||
m_netFrames++;
|
if (::memcmp(data + 2U, DSTAR_NULL_AMBE_DATA_BYTES_SCRAMBLED, DSTAR_VOICE_FRAME_LENGTH_BYTES) != 0) {
|
||||||
|
errors = m_fec.regenerateDStar(data + 2U);
|
||||||
|
blankDTMF(data + 2U);
|
||||||
|
}
|
||||||
|
|
||||||
|
data[1U] = TAG_DATA;
|
||||||
|
|
||||||
|
// Insert silence and reject if in the past
|
||||||
|
bool ret = insertSilence(data + 1U, n);
|
||||||
|
if (!ret)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_netErrs += errors;
|
||||||
|
m_netBits += 48U;
|
||||||
|
|
||||||
|
m_netN = n;
|
||||||
|
|
||||||
|
// Regenerate the sync
|
||||||
|
if (m_netN == 0U) {
|
||||||
|
CSync::addDStarSync(data + 2U);
|
||||||
|
m_netSlowData.start();
|
||||||
|
} else {
|
||||||
|
const unsigned char* text = m_netSlowData.addText(data + 2U, m_netN);
|
||||||
|
if (text != NULL)
|
||||||
|
LogMessage("D-Star, network slow data text = \"%s\"", text);
|
||||||
|
}
|
||||||
|
|
||||||
|
m_packetTimer.start();
|
||||||
|
m_netFrames++;
|
||||||
|
|
||||||
#if defined(DUMP_DSTAR)
|
#if defined(DUMP_DSTAR)
|
||||||
writeFile(data + 1U, length - 1U);
|
writeFile(data + 1U, length - 1U);
|
||||||
#endif
|
#endif
|
||||||
writeQueueDataNet(data + 1U);
|
writeQueueDataNet(data + 1U);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_netState == RS_NET_DATA) {
|
||||||
|
m_netN = data[1U];
|
||||||
|
|
||||||
|
data[1U] = TAG_DATA;
|
||||||
|
|
||||||
|
m_netBits += 48U;
|
||||||
|
|
||||||
|
// Regenerate the sync
|
||||||
|
if (m_netN == 0U) {
|
||||||
|
CSync::addDStarSync(data + 2U);
|
||||||
|
m_netSlowData.start();
|
||||||
|
} else {
|
||||||
|
m_netSlowData.peakSlowData(data + 2U, m_netN);
|
||||||
|
bool complete = m_netSlowData.isComplete();
|
||||||
|
if (complete) {
|
||||||
|
unsigned char type = m_netSlowData.getType();
|
||||||
|
if (type == DSTAR_SLOW_DATA_TYPE_FASTDATA_END) {
|
||||||
|
LogMessage("D-Star, leaving fast data mode");
|
||||||
|
m_netState = RS_NET_AUDIO;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_packetTimer.start();
|
||||||
|
m_netFrames++;
|
||||||
|
|
||||||
|
#if defined(DUMP_DSTAR)
|
||||||
|
writeFile(data + 1U, length - 1U);
|
||||||
|
#endif
|
||||||
|
writeQueueDataNet(data + 1U);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
CUtils::dump("D-Star, unknown data from network", data, DSTAR_FRAME_LENGTH_BYTES + 1U);
|
CUtils::dump("D-Star, unknown data from network", data, DSTAR_FRAME_LENGTH_BYTES + 1U);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,14 +44,14 @@ const unsigned int DSTAR_DATA_FRAME_LENGTH_BYTES = 3U;
|
|||||||
const unsigned int DSTAR_LONG_CALLSIGN_LENGTH = 8U;
|
const unsigned int DSTAR_LONG_CALLSIGN_LENGTH = 8U;
|
||||||
const unsigned int DSTAR_SHORT_CALLSIGN_LENGTH = 4U;
|
const unsigned int DSTAR_SHORT_CALLSIGN_LENGTH = 4U;
|
||||||
|
|
||||||
const unsigned char DSTAR_SLOW_DATA_TYPE_MASK = 0xF0U;
|
const unsigned char DSTAR_SLOW_DATA_TYPE_MASK = 0xF0U;
|
||||||
const unsigned char DSTAR_SLOW_DATA_TYPE_GPSDATA = 0x30U;
|
const unsigned char DSTAR_SLOW_DATA_TYPE_GPSDATA = 0x30U;
|
||||||
const unsigned char DSTAR_SLOW_DATA_TYPE_TEXT = 0x40U;
|
const unsigned char DSTAR_SLOW_DATA_TYPE_TEXT = 0x40U;
|
||||||
const unsigned char DSTAR_SLOW_DATA_TYPE_HEADER = 0x50U;
|
const unsigned char DSTAR_SLOW_DATA_TYPE_HEADER = 0x50U;
|
||||||
const unsigned char DSTAR_SLOW_DATA_TYPE_FASTDATA01 = 0x80U;
|
const unsigned char DSTAR_SLOW_DATA_TYPE_FASTDATA_END = 0x80U;
|
||||||
const unsigned char DSTAR_SLOW_DATA_TYPE_FASTDATA16 = 0x90U;
|
const unsigned char DSTAR_SLOW_DATA_TYPE_FASTDATA_BEGIN = 0x90U;
|
||||||
const unsigned char DSTAR_SLOW_DATA_TYPE_SQUELCH = 0xC0U;
|
const unsigned char DSTAR_SLOW_DATA_TYPE_SQUELCH = 0xC0U;
|
||||||
const unsigned char DSTAR_SLOW_DATA_LENGTH_MASK = 0x0FU;
|
const unsigned char DSTAR_SLOW_DATA_LENGTH_MASK = 0x0FU;
|
||||||
|
|
||||||
// Data Frames are always scrambled using the first three bytes of
|
// Data Frames are always scrambled using the first three bytes of
|
||||||
// DSTAR_SCRAMBLER_BYTES, and Voice Frames are scrambled with all nine
|
// DSTAR_SCRAMBLER_BYTES, and Voice Frames are scrambled with all nine
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2023 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2023,2025 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -33,7 +33,8 @@ m_buffer(NULL),
|
|||||||
m_text(NULL),
|
m_text(NULL),
|
||||||
m_textPtr(0U),
|
m_textPtr(0U),
|
||||||
m_textBits(0x00U),
|
m_textBits(0x00U),
|
||||||
m_state(SDD_FIRST)
|
m_type(0x00U),
|
||||||
|
m_complete(false)
|
||||||
{
|
{
|
||||||
m_header = new unsigned char[50U]; // DSTAR_HEADER_LENGTH_BYTES
|
m_header = new unsigned char[50U]; // DSTAR_HEADER_LENGTH_BYTES
|
||||||
m_buffer = new unsigned char[DSTAR_DATA_FRAME_LENGTH_BYTES * 2U];
|
m_buffer = new unsigned char[DSTAR_DATA_FRAME_LENGTH_BYTES * 2U];
|
||||||
@@ -47,24 +48,33 @@ CDStarSlowData::~CDStarSlowData()
|
|||||||
delete[] m_text;
|
delete[] m_text;
|
||||||
}
|
}
|
||||||
|
|
||||||
CDStarHeader* CDStarSlowData::addHeader(const unsigned char* data)
|
void CDStarSlowData::peakSlowData(const unsigned char* data, unsigned int n)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
switch (m_state) {
|
if ((n % 2U) == 0U) {
|
||||||
case SDD_FIRST:
|
m_type = data[9U] ^ DSTAR_SCRAMBLER_BYTES[0U];
|
||||||
|
m_complete = false;
|
||||||
|
} else {
|
||||||
|
m_complete = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CDStarHeader* CDStarSlowData::addHeader(const unsigned char* data, unsigned int n)
|
||||||
|
{
|
||||||
|
assert(data != NULL);
|
||||||
|
|
||||||
|
if ((n % 2U) == 0U) {
|
||||||
|
m_type = data[9U] ^ DSTAR_SCRAMBLER_BYTES[0U];
|
||||||
m_buffer[0U] = data[9U] ^ DSTAR_SCRAMBLER_BYTES[0U];
|
m_buffer[0U] = data[9U] ^ DSTAR_SCRAMBLER_BYTES[0U];
|
||||||
m_buffer[1U] = data[10U] ^ DSTAR_SCRAMBLER_BYTES[1U];
|
m_buffer[1U] = data[10U] ^ DSTAR_SCRAMBLER_BYTES[1U];
|
||||||
m_buffer[2U] = data[11U] ^ DSTAR_SCRAMBLER_BYTES[2U];
|
m_buffer[2U] = data[11U] ^ DSTAR_SCRAMBLER_BYTES[2U];
|
||||||
m_state = SDD_SECOND;
|
m_complete = false;
|
||||||
return NULL;
|
} else {
|
||||||
|
|
||||||
case SDD_SECOND:
|
|
||||||
m_buffer[3U] = data[9U] ^ DSTAR_SCRAMBLER_BYTES[0U];
|
m_buffer[3U] = data[9U] ^ DSTAR_SCRAMBLER_BYTES[0U];
|
||||||
m_buffer[4U] = data[10U] ^ DSTAR_SCRAMBLER_BYTES[1U];
|
m_buffer[4U] = data[10U] ^ DSTAR_SCRAMBLER_BYTES[1U];
|
||||||
m_buffer[5U] = data[11U] ^ DSTAR_SCRAMBLER_BYTES[2U];
|
m_buffer[5U] = data[11U] ^ DSTAR_SCRAMBLER_BYTES[2U];
|
||||||
m_state = SDD_FIRST;
|
m_complete = true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((m_buffer[0U] & DSTAR_SLOW_DATA_TYPE_MASK) != DSTAR_SLOW_DATA_TYPE_HEADER)
|
if ((m_buffer[0U] & DSTAR_SLOW_DATA_TYPE_MASK) != DSTAR_SLOW_DATA_TYPE_HEADER)
|
||||||
@@ -95,24 +105,21 @@ CDStarHeader* CDStarSlowData::addHeader(const unsigned char* data)
|
|||||||
return new CDStarHeader(m_header);
|
return new CDStarHeader(m_header);
|
||||||
}
|
}
|
||||||
|
|
||||||
const unsigned char* CDStarSlowData::addText(const unsigned char* data)
|
const unsigned char* CDStarSlowData::addText(const unsigned char* data, unsigned int n)
|
||||||
{
|
{
|
||||||
assert(data != NULL);
|
assert(data != NULL);
|
||||||
|
|
||||||
switch (m_state) {
|
if ((n % 2U) == 0U) {
|
||||||
case SDD_FIRST:
|
m_type = data[9U] ^ DSTAR_SCRAMBLER_BYTES[0U];
|
||||||
m_buffer[0U] = data[9U] ^ DSTAR_SCRAMBLER_BYTES[0U];
|
m_buffer[0U] = data[9U] ^ DSTAR_SCRAMBLER_BYTES[0U];
|
||||||
m_buffer[1U] = data[10U] ^ DSTAR_SCRAMBLER_BYTES[1U];
|
m_buffer[1U] = data[10U] ^ DSTAR_SCRAMBLER_BYTES[1U];
|
||||||
m_buffer[2U] = data[11U] ^ DSTAR_SCRAMBLER_BYTES[2U];
|
m_buffer[2U] = data[11U] ^ DSTAR_SCRAMBLER_BYTES[2U];
|
||||||
m_state = SDD_SECOND;
|
m_complete = false;
|
||||||
return NULL;
|
} else {
|
||||||
|
|
||||||
case SDD_SECOND:
|
|
||||||
m_buffer[3U] = data[9U] ^ DSTAR_SCRAMBLER_BYTES[0U];
|
m_buffer[3U] = data[9U] ^ DSTAR_SCRAMBLER_BYTES[0U];
|
||||||
m_buffer[4U] = data[10U] ^ DSTAR_SCRAMBLER_BYTES[1U];
|
m_buffer[4U] = data[10U] ^ DSTAR_SCRAMBLER_BYTES[1U];
|
||||||
m_buffer[5U] = data[11U] ^ DSTAR_SCRAMBLER_BYTES[2U];
|
m_buffer[5U] = data[11U] ^ DSTAR_SCRAMBLER_BYTES[2U];
|
||||||
m_state = SDD_FIRST;
|
m_complete = true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (m_buffer[0U]) {
|
switch (m_buffer[0U]) {
|
||||||
@@ -160,7 +167,7 @@ const unsigned char* CDStarSlowData::addText(const unsigned char* data)
|
|||||||
if (m_textBits != 0x0FU)
|
if (m_textBits != 0x0FU)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
CUtils::dump(1U, "D-STar slow data text", m_text, 20U);
|
CUtils::dump(1U, "D-Star slow data text", m_text, 20U);
|
||||||
|
|
||||||
m_textBits = 0x00U;
|
m_textBits = 0x00U;
|
||||||
|
|
||||||
@@ -172,14 +179,16 @@ void CDStarSlowData::start()
|
|||||||
::memset(m_header, 0x00U, DSTAR_HEADER_LENGTH_BYTES);
|
::memset(m_header, 0x00U, DSTAR_HEADER_LENGTH_BYTES);
|
||||||
|
|
||||||
m_ptr = 0U;
|
m_ptr = 0U;
|
||||||
m_state = SDD_FIRST;
|
m_type = 0x00U;
|
||||||
|
m_complete = false;
|
||||||
m_textBits = 0x00U;
|
m_textBits = 0x00U;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CDStarSlowData::reset()
|
void CDStarSlowData::reset()
|
||||||
{
|
{
|
||||||
m_ptr = 0U;
|
m_ptr = 0U;
|
||||||
m_state = SDD_FIRST;
|
m_type = 0x00U;
|
||||||
|
m_complete = false;
|
||||||
m_textBits = 0x00U;
|
m_textBits = 0x00U;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,3 +242,13 @@ void CDStarSlowData::getSlowData(unsigned char* data)
|
|||||||
data[2U] = 'f' ^ DSTAR_SCRAMBLER_BYTES[2U];
|
data[2U] = 'f' ^ DSTAR_SCRAMBLER_BYTES[2U];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char CDStarSlowData::getType() const
|
||||||
|
{
|
||||||
|
return m_type & DSTAR_SLOW_DATA_TYPE_MASK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CDStarSlowData::isComplete() const
|
||||||
|
{
|
||||||
|
return m_complete;
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2016,2023 by Jonathan Naylor G4KLX
|
* Copyright (C) 2016,2023,2025 by Jonathan Naylor G4KLX
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -26,9 +26,14 @@ public:
|
|||||||
CDStarSlowData();
|
CDStarSlowData();
|
||||||
~CDStarSlowData();
|
~CDStarSlowData();
|
||||||
|
|
||||||
CDStarHeader* addHeader(const unsigned char* data);
|
void peakSlowData(const unsigned char* data, unsigned int n);
|
||||||
|
|
||||||
const unsigned char* addText(const unsigned char* data);
|
CDStarHeader* addHeader(const unsigned char* data, unsigned int n);
|
||||||
|
|
||||||
|
const unsigned char* addText(const unsigned char* data, unsigned int n);
|
||||||
|
|
||||||
|
unsigned char getType() const;
|
||||||
|
bool isComplete() const;
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
void reset();
|
void reset();
|
||||||
@@ -43,13 +48,8 @@ private:
|
|||||||
unsigned char* m_text;
|
unsigned char* m_text;
|
||||||
unsigned int m_textPtr;
|
unsigned int m_textPtr;
|
||||||
unsigned char m_textBits;
|
unsigned char m_textBits;
|
||||||
|
unsigned char m_type;
|
||||||
enum SDD_STATE {
|
bool m_complete;
|
||||||
SDD_FIRST,
|
|
||||||
SDD_SECOND
|
|
||||||
};
|
|
||||||
|
|
||||||
SDD_STATE m_state;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -541,6 +541,7 @@ int CMMDVMHost::run()
|
|||||||
m_dmrRFModeHang = m_conf.getDMRModeHang();
|
m_dmrRFModeHang = m_conf.getDMRModeHang();
|
||||||
dmrBeacons = m_conf.getDMRBeacons();
|
dmrBeacons = m_conf.getDMRBeacons();
|
||||||
DMR_OVCM_TYPES ovcm = m_conf.getDMROVCM();
|
DMR_OVCM_TYPES ovcm = m_conf.getDMROVCM();
|
||||||
|
bool protect = m_conf.getDMRProtect();
|
||||||
|
|
||||||
if (txHang > m_dmrRFModeHang)
|
if (txHang > m_dmrRFModeHang)
|
||||||
txHang = m_dmrRFModeHang;
|
txHang = m_dmrRFModeHang;
|
||||||
@@ -584,6 +585,9 @@ int CMMDVMHost::run()
|
|||||||
else if (ovcm == DMR_OVCM_FORCE_OFF)
|
else if (ovcm == DMR_OVCM_FORCE_OFF)
|
||||||
LogInfo(" OVCM: off (forced)");
|
LogInfo(" OVCM: off (forced)");
|
||||||
|
|
||||||
|
if (protect)
|
||||||
|
LogInfo(" Protect: yes");
|
||||||
|
|
||||||
switch (dmrBeacons) {
|
switch (dmrBeacons) {
|
||||||
case DMR_BEACONS_NETWORK: {
|
case DMR_BEACONS_NETWORK: {
|
||||||
unsigned int dmrBeaconDuration = m_conf.getDMRBeaconDuration();
|
unsigned int dmrBeaconDuration = m_conf.getDMRBeaconDuration();
|
||||||
@@ -613,7 +617,7 @@ int CMMDVMHost::run()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_dmr = new CDMRControl(id, colorCode, callHang, selfOnly, embeddedLCOnly, dumpTAData, prefixes, blackList, whiteList, slot1TGWhiteList, slot2TGWhiteList, m_timeout, m_modem, m_dmrNetwork, m_display, m_duplex, m_dmrLookup, rssi, jitter, ovcm);
|
m_dmr = new CDMRControl(id, colorCode, callHang, selfOnly, embeddedLCOnly, dumpTAData, prefixes, blackList, whiteList, slot1TGWhiteList, slot2TGWhiteList, m_timeout, m_modem, m_dmrNetwork, m_display, m_duplex, m_dmrLookup, rssi, jitter, ovcm, protect);
|
||||||
|
|
||||||
m_dmrTXTimer.setTimeout(txHang);
|
m_dmrTXTimer.setTimeout(txHang);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user