diff --git a/config.yml b/config.yml
index 3518d802..61999d3f 100644
--- a/config.yml
+++ b/config.yml
@@ -46,8 +46,9 @@ protocols:
control:
enable: false
ackRequests: true
- continuous: false
- interval: 60
+ dedicated: false
+ broadcast: true
+ interval: 300
duration: 1
voiceOnControl: false
inhibitIllegal: false
diff --git a/dmr/Control.cpp b/dmr/Control.cpp
index da54ddd7..cbf21c5c 100644
--- a/dmr/Control.cpp
+++ b/dmr/Control.cpp
@@ -256,3 +256,16 @@ void Control::writeRF_Call_Alrt(uint32_t slotNo, uint32_t srcId, uint32_t dstId)
break;
}
}
+
+///
+/// Helper to change the debug and verbose state.
+///
+/// Flag indicating whether DMR debug is enabled.
+/// Flag indicating whether DMR verbose logging is enabled.
+void Control::setDebugVerbose(bool debug, bool verbose)
+{
+ m_debug = debug;
+ m_verbose = verbose;
+ m_slot1->setDebugVerbose(debug, verbose);
+ m_slot2->setDebugVerbose(debug, verbose);
+}
diff --git a/dmr/Control.h b/dmr/Control.h
index 3f433796..d481ec2a 100644
--- a/dmr/Control.h
+++ b/dmr/Control.h
@@ -83,6 +83,9 @@ namespace dmr
/// Helper to write a DMR call alert packet on the RF interface.
void writeRF_Call_Alrt(uint32_t slotNo, uint32_t srcId, uint32_t dstId);
+ /// Helper to change the debug and verbose state.
+ void setDebugVerbose(bool debug, bool verbose);
+
private:
uint32_t m_colorCode;
diff --git a/dmr/Slot.cpp b/dmr/Slot.cpp
index 24546b71..2494b417 100644
--- a/dmr/Slot.cpp
+++ b/dmr/Slot.cpp
@@ -434,6 +434,17 @@ void Slot::init(uint32_t colorCode, bool embeddedLCOnly, bool dumpTAData, uint32
// ---------------------------------------------------------------------------
// Private Class Members
// ---------------------------------------------------------------------------
+///
+/// Helper to change the debug and verbose state.
+///
+/// Flag indicating whether DMR debug is enabled.
+/// Flag indicating whether DMR verbose logging is enabled.
+void Slot::setDebugVerbose(bool debug, bool verbose)
+{
+ m_debug = m_voice->m_debug = m_data->m_debug = debug;
+ m_verbose = m_voice->m_verbose = m_data->m_verbose = verbose;
+}
+
///
/// Write data processed from RF to the data ring buffer.
///
diff --git a/dmr/Slot.h b/dmr/Slot.h
index 002310a4..69de0c68 100644
--- a/dmr/Slot.h
+++ b/dmr/Slot.h
@@ -164,6 +164,9 @@ namespace dmr
static uint8_t m_id2;
static bool m_voice2;
+ /// Helper to change the debug and verbose state.
+ void setDebugVerbose(bool debug, bool verbose);
+
/// Write data processed from RF to the data ring buffer.
void writeQueueRF(const uint8_t* data);
/// Write data processed from the network to the data ring buffer.
diff --git a/host/Host.cpp b/host/Host.cpp
index d37b1aa0..1b719b16 100644
--- a/host/Host.cpp
+++ b/host/Host.cpp
@@ -74,7 +74,7 @@ Host::Host(const std::string& confFile) :
m_cwIdTimer(1000U),
m_dmrEnabled(false),
m_p25Enabled(false),
- m_p25CtrlBcstContinuous(false),
+ m_p25CtrlChannel(false),
m_duplex(false),
m_fixedMode(false),
m_timeout(180U),
@@ -341,7 +341,8 @@ int Host::run()
yaml::Node p25Protocol = protocolConf["p25"];
uint32_t tduPreambleCount = p25Protocol["tduPreambleCount"].as(8U);
m_controlData = p25Protocol["control"]["enable"].as(false);
- bool controlBcstContinuous = p25Protocol["control"]["continuous"].as(false);
+ bool p25CtrlChannel = p25Protocol["control"]["dedicated"].as(false);
+ bool p25CtrlBroadcast = p25Protocol["control"]["broadcast"].as(true);
bool p25DumpDataPacket = p25Protocol["dumpDataPacket"].as(false);
bool p25RepeatDataPacket = p25Protocol["repeatDataPacket"].as(true);
bool p25DumpTsbkData = p25Protocol["dumpTsbkData"].as(false);
@@ -359,27 +360,35 @@ int Host::run()
LogInfo(" Control: %s", m_controlData ? "yes" : "no");
- uint32_t p25ControlBcstInterval = p25Protocol["control"]["interval"].as(60U);
+ uint32_t p25ControlBcstInterval = p25Protocol["control"]["interval"].as(300U);
uint32_t p25ControlBcstDuration = p25Protocol["control"]["duration"].as(1U);
if (m_controlData) {
- LogInfo(" Control Broadcast Continuous: %s", controlBcstContinuous ? "yes" : "no");
- if (controlBcstContinuous) {
+ LogInfo(" Control Broadcast: %s", p25CtrlBroadcast ? "yes" : "no");
+ LogInfo(" Control Channel: %s", p25CtrlChannel ? "yes" : "no");
+ if (p25CtrlChannel) {
p25ControlBcstInterval = 30U;
p25ControlBcstDuration = 120U;
- m_p25CtrlBcstContinuous = controlBcstContinuous;
+ m_p25CtrlChannel = p25CtrlChannel;
}
else {
LogInfo(" Control Broadcast Interval: %us", p25ControlBcstInterval);
LogInfo(" Control Broadcast Duration: %us", p25ControlBcstDuration);
}
+ m_p25CtrlBroadcast = p25CtrlBroadcast;
p25CCIntervalTimer.setTimeout(p25ControlBcstInterval);
p25CCIntervalTimer.start();
p25CCDurationTimer.setTimeout(p25ControlBcstDuration);
- g_fireP25Control = true;
- g_interruptP25Control = false;
+ if (p25CtrlBroadcast) {
+ g_fireP25Control = true;
+ g_interruptP25Control = false;
+ }
+ else {
+ g_fireP25Control = false;
+ g_interruptP25Control = false;
+ }
}
p25 = new p25::Control(m_p25NAC, callHang, p25QueueSize, m_modem, m_network, m_timeout, m_rfTalkgroupHang,
@@ -401,7 +410,7 @@ int Host::run()
g_killed = true;
}
- if (m_dmrEnabled && m_p25CtrlBcstContinuous) {
+ if (m_dmrEnabled && m_p25CtrlChannel) {
::LogError(LOG_HOST, "Cannot have DMR enabled when using dedicated P25 control!");
g_killed = true;
}
@@ -422,7 +431,21 @@ int Host::run()
}
if (!g_killed) {
- setMode(STATE_IDLE);
+ // fixed more or P25 control channel will force a mode change
+ if (m_fixedMode || m_p25CtrlChannel) {
+ if (m_p25CtrlChannel) {
+ m_fixedMode = true;
+ }
+
+ if (dmr != NULL)
+ setMode(STATE_DMR);
+ if (p25 != NULL)
+ setMode(STATE_P25);
+ }
+ else {
+ setMode(STATE_IDLE);
+ }
+
::LogInfoEx(LOG_HOST, "Host is performing late initialization and warmup");
// perform early pumping of the modem clock (this is so the DSP has time to setup its buffers),
@@ -925,73 +948,75 @@ int Host::run()
/** P25 */
if (p25 != NULL) {
- // clock and check P25 CC broadcast interval timer
- p25CCIntervalTimer.clock(ms);
- if ((p25CCIntervalTimer.isRunning() && p25CCIntervalTimer.hasExpired()) || g_fireP25Control) {
- if (hasCw) {
- g_fireP25Control = false;
- p25CCIntervalTimer.start();
- }
- else {
- if ((m_mode == STATE_IDLE || m_mode == STATE_P25) && !m_modem->hasTX()) {
- if (m_modeTimer.isRunning()) {
- m_modeTimer.stop();
- }
+ if (m_p25CtrlBroadcast) {
+ // clock and check P25 CC broadcast interval timer
+ p25CCIntervalTimer.clock(ms);
+ if ((p25CCIntervalTimer.isRunning() && p25CCIntervalTimer.hasExpired()) || g_fireP25Control) {
+ if (hasCw) {
+ g_fireP25Control = false;
+ p25CCIntervalTimer.start();
+ }
+ else {
+ if ((m_mode == STATE_IDLE || m_mode == STATE_P25) && !m_modem->hasTX()) {
+ if (m_modeTimer.isRunning()) {
+ m_modeTimer.stop();
+ }
- if (m_mode != STATE_P25)
- setMode(STATE_P25);
+ if (m_mode != STATE_P25)
+ setMode(STATE_P25);
- if (g_interruptP25Control) {
- g_interruptP25Control = false;
- LogDebug(LOG_HOST, "traffic complete, restart P25 CC broadcast, g_interruptP25Control = %u", g_interruptP25Control);
- }
+ if (g_interruptP25Control) {
+ g_interruptP25Control = false;
+ LogDebug(LOG_HOST, "traffic complete, restart P25 CC broadcast, g_interruptP25Control = %u", g_interruptP25Control);
+ }
- p25->writeAdjSSNetwork();
- p25->setCCRunning(true);
+ p25->writeAdjSSNetwork();
+ p25->setCCRunning(true);
- // hide this message for continuous CC -- otherwise display every time we process
- if (!m_p25CtrlBcstContinuous) {
- LogMessage(LOG_HOST, "P25, start CC broadcast");
- }
+ // hide this message for continuous CC -- otherwise display every time we process
+ if (!m_p25CtrlChannel) {
+ LogMessage(LOG_HOST, "P25, start CC broadcast");
+ }
- g_fireP25Control = false;
- p25CCIntervalTimer.start();
- p25CCDurationTimer.start();
+ g_fireP25Control = false;
+ p25CCIntervalTimer.start();
+ p25CCDurationTimer.start();
- // if the CC is continuous -- clock one cycle into the duration timer
- if (m_p25CtrlBcstContinuous) {
- p25CCDurationTimer.clock(ms);
+ // if the CC is continuous -- clock one cycle into the duration timer
+ if (m_p25CtrlChannel) {
+ p25CCDurationTimer.clock(ms);
+ }
}
}
}
- }
- // if the CC is continuous -- we don't clock the CC duration timer (which results in the CC
- // broadcast running infinitely until stopped)
- if (!m_p25CtrlBcstContinuous) {
- // clock and check P25 CC broadcast duration timer
- p25CCDurationTimer.clock(ms);
- if (p25CCDurationTimer.isRunning() && p25CCDurationTimer.hasExpired()) {
- p25CCDurationTimer.stop();
+ // if the CC is continuous -- we don't clock the CC duration timer (which results in the CC
+ // broadcast running infinitely until stopped)
+ if (!m_p25CtrlChannel) {
+ // clock and check P25 CC broadcast duration timer
+ p25CCDurationTimer.clock(ms);
+ if (p25CCDurationTimer.isRunning() && p25CCDurationTimer.hasExpired()) {
+ p25CCDurationTimer.stop();
- p25->writeControlEndRF();
- p25->setCCRunning(false);
+ p25->writeControlEndRF();
+ p25->setCCRunning(false);
- if (m_mode == STATE_P25 && !m_modeTimer.isRunning()) {
- m_modeTimer.setTimeout(m_rfModeHang);
- m_modeTimer.start();
+ if (m_mode == STATE_P25 && !m_modeTimer.isRunning()) {
+ m_modeTimer.setTimeout(m_rfModeHang);
+ m_modeTimer.start();
+ }
}
- }
- if (p25CCDurationTimer.isPaused()) {
- p25CCDurationTimer.resume();
+ if (p25CCDurationTimer.isPaused()) {
+ p25CCDurationTimer.resume();
+ }
}
}
}
if (g_killed) {
if (p25 != NULL) {
- if (m_p25CtrlBcstContinuous && !hasTxShutdown) {
+ if (m_p25CtrlChannel && !hasTxShutdown) {
m_modem->clearP25Data();
p25->reset();
@@ -1374,9 +1399,9 @@ void Host::setMode(uint8_t mode)
{
assert(m_modem != NULL);
- if (m_mode != mode) {
- LogDebug(LOG_HOST, "setMode, m_mode = %u, mode = %u", m_mode, mode);
- }
+ //if (m_mode != mode) {
+ // LogDebug(LOG_HOST, "setMode, m_mode = %u, mode = %u", m_mode, mode);
+ //}
switch (mode) {
case STATE_DMR:
@@ -1403,7 +1428,7 @@ void Host::setMode(uint8_t mode)
break;
case HOST_STATE_LOCKOUT:
- LogWarning(LOG_HOST, "Mode change, MODE_LOCKOUT");
+ LogWarning(LOG_HOST, "Mode change, HOST_STATE_LOCKOUT");
if (m_network != NULL)
m_network->enable(false);
@@ -1420,7 +1445,7 @@ void Host::setMode(uint8_t mode)
break;
case HOST_STATE_ERROR:
- LogWarning(LOG_HOST, "Mode change, MODE_ERROR");
+ LogWarning(LOG_HOST, "Mode change, HOST_STATE_ERROR");
if (m_network != NULL)
m_network->enable(false);
diff --git a/host/Host.h b/host/Host.h
index fc3858fc..cc0d2140 100644
--- a/host/Host.h
+++ b/host/Host.h
@@ -79,7 +79,8 @@ private:
bool m_dmrEnabled;
bool m_p25Enabled;
- bool m_p25CtrlBcstContinuous;
+ bool m_p25CtrlChannel;
+ bool m_p25CtrlBroadcast;
bool m_duplex;
bool m_fixedMode;
diff --git a/network/RemoteControl.cpp b/network/RemoteControl.cpp
index 2d9ab3b2..085a969f 100644
--- a/network/RemoteControl.cpp
+++ b/network/RemoteControl.cpp
@@ -47,44 +47,51 @@ using namespace modem;
// Constants
// ---------------------------------------------------------------------------
-#define BAD_CMD_STR "Bad or invalid remote command."
-#define INVALID_OPT_STR "Invalid command arguments: "
-#define CMD_FAILED_STR "Remote command failed: "
+#define BAD_CMD_STR "Bad or invalid remote command."
+#define INVALID_OPT_STR "Invalid command arguments: "
+#define CMD_FAILED_STR "Remote command failed: "
-#define RCD_MODE_CMD "mdm-mode"
-#define RCD_MODE_OPT_IDLE "idle"
-#define RCD_MODE_OPT_LCKOUT "lockout"
-#define RCD_MODE_OPT_FDMR "dmr"
-#define RCD_MODE_OPT_FP25 "p25"
+#define RCD_MODE_CMD "mdm-mode"
+#define RCD_MODE_OPT_IDLE "idle"
+#define RCD_MODE_OPT_LCKOUT "lockout"
+#define RCD_MODE_OPT_FDMR "dmr"
+#define RCD_MODE_OPT_FP25 "p25"
-#define RCD_KILL_CMD "mdm-kill"
+#define RCD_KILL_CMD "mdm-kill"
-#define RCD_RID_WLIST_CMD "rid-whitelist"
-#define RCD_RID_BLIST_CMD "rid-blacklist"
+#define RCD_RID_WLIST_CMD "rid-whitelist"
+#define RCD_RID_BLIST_CMD "rid-blacklist"
-#define RCD_DMR_BEACON_CMD "dmr-beacon"
-#define RCD_P25_CC_CMD "p25-cc"
+#define RCD_DMR_BEACON_CMD "dmr-beacon"
+#define RCD_P25_CC_CMD "p25-cc"
-#define RCD_DMRD_MDM_INJ_CMD "dmrd-mdm-inj"
-#define RCD_P25D_MDM_INJ_CMD "p25d-mdm-inj"
+#define RCD_DMRD_MDM_INJ_CMD "dmrd-mdm-inj"
+#define RCD_P25D_MDM_INJ_CMD "p25d-mdm-inj"
-#define RCD_DMR_RID_PAGE_CMD "dmr-rid-page"
-#define RCD_DMR_RID_CHECK_CMD "dmr-rid-check"
-#define RCD_DMR_RID_INHIBIT_CMD "dmr-rid-inhibit"
-#define RCD_DMR_RID_UNINHIBIT_CMD "dmr-rid-uninhibit"
+#define RCD_DMR_RID_PAGE_CMD "dmr-rid-page"
+#define RCD_DMR_RID_CHECK_CMD "dmr-rid-check"
+#define RCD_DMR_RID_INHIBIT_CMD "dmr-rid-inhibit"
+#define RCD_DMR_RID_UNINHIBIT_CMD "dmr-rid-uninhibit"
-#define RCD_P25_SET_MFID_CMD "p25-set-mfid"
-#define RCD_P25_RID_PAGE_CMD "p25-rid-page"
-#define RCD_P25_RID_CHECK_CMD "p25-rid-check"
-#define RCD_P25_RID_INHIBIT_CMD "p25-rid-inhibit"
-#define RCD_P25_RID_UNINHIBIT_CMD "p25-rid-uninhibit"
-#define RCD_P25_RID_GAQ_CMD "p25-rid-gaq"
-#define RCD_P25_RID_UREG_CMD "p25-rid-ureg"
+#define RCD_P25_SET_MFID_CMD "p25-set-mfid"
+#define RCD_P25_RID_PAGE_CMD "p25-rid-page"
+#define RCD_P25_RID_CHECK_CMD "p25-rid-check"
+#define RCD_P25_RID_INHIBIT_CMD "p25-rid-inhibit"
+#define RCD_P25_RID_UNINHIBIT_CMD "p25-rid-uninhibit"
+#define RCD_P25_RID_GAQ_CMD "p25-rid-gaq"
+#define RCD_P25_RID_UREG_CMD "p25-rid-ureg"
-#define RCD_P25_PATCH_CMD "p25-patch"
+#define RCD_P25_PATCH_CMD "p25-patch"
-#define RCD_P25_RELEASE_GRANTS "p25-rel-grnts"
-#define RCD_P25_RELEASE_AFFS "p25-rel-affs"
+#define RCD_P25_RELEASE_GRANTS_CMD "p25-rel-grnts"
+#define RCD_P25_RELEASE_AFFS_CMD "p25-rel-affs"
+
+#define RCD_P25_CC_DEDICATED_CMD "p25-cc-dedicated"
+#define RCD_P25_CC_BCAST_CMD "p25-cc-bcast"
+
+#define RCD_DMR_DEBUG "dmr-debug"
+#define RCD_P25_DEBUG "p25-debug"
+#define RCD_P25_DUMP_TSBK "p25-dump-tsbk"
const uint32_t START_OF_TEXT = 0x02;
const uint32_t REC_SEPARATOR = 0x1E;
@@ -224,15 +231,18 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25)
if (mode == RCD_MODE_OPT_IDLE) {
host->m_fixedMode = false;
host->setMode(STATE_IDLE);
+ LogInfoEx(LOG_RCON, "Dynamic mode, mode %u", host->m_mode);
}
else if (mode == RCD_MODE_OPT_LCKOUT) {
host->m_fixedMode = false;
host->setMode(HOST_STATE_LOCKOUT);
+ LogInfoEx(LOG_RCON, "Lockout mode, mode %u", host->m_mode);
}
else if (mode == RCD_MODE_OPT_FDMR) {
if (dmr != NULL) {
host->m_fixedMode = true;
host->setMode(STATE_DMR);
+ LogInfoEx(LOG_RCON, "Fixed mode, mode %u", host->m_mode);
}
else {
LogError(LOG_RCON, CMD_FAILED_STR "DMR mode is not enabled!");
@@ -242,6 +252,7 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25)
if (p25 != NULL) {
host->m_fixedMode = true;
host->setMode(STATE_P25);
+ LogInfoEx(LOG_RCON, "Fixed mode, mode %u", host->m_mode);
}
else {
LogError(LOG_RCON, CMD_FAILED_STR "P25 mode is not enabled!");
@@ -276,7 +287,12 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25)
else if (rcom == RCD_DMR_BEACON_CMD) {
// Command is in the form of: "dmr-beacon"
if (dmr != NULL) {
- g_fireDMRBeacon = true;
+ if (host->m_dmrBeacons) {
+ g_fireDMRBeacon = true;
+ }
+ else {
+ LogError(LOG_RCON, CMD_FAILED_STR "DMR beacons is not enabled!");
+ }
}
else {
LogError(LOG_RCON, CMD_FAILED_STR "DMR mode is not enabled!");
@@ -285,7 +301,12 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25)
else if (rcom == RCD_P25_CC_CMD) {
// Command is in the form of: "p25-cc"
if (p25 != NULL) {
- g_fireP25Control = true;
+ if (host->m_controlData) {
+ g_fireP25Control = true;
+ }
+ else {
+ LogError(LOG_RCON, CMD_FAILED_STR "P25 control data is not enabled!");
+ }
}
else {
LogError(LOG_RCON, CMD_FAILED_STR "P25 mode is not enabled!");
@@ -626,7 +647,7 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25)
LogError(LOG_RCON, CMD_FAILED_STR "P25 mode is not enabled!");
}
}
- else if (rcom == RCD_P25_RELEASE_GRANTS) {
+ else if (rcom == RCD_P25_RELEASE_GRANTS_CMD) {
// Command is in the form of: "p25-rel-grnts"
if (p25 != NULL) {
p25->trunk()->releaseDstIdGrant(0, true);
@@ -635,7 +656,7 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25)
LogError(LOG_RCON, CMD_FAILED_STR "P25 mode is not enabled!");
}
}
- else if (rcom == RCD_P25_RELEASE_AFFS) {
+ else if (rcom == RCD_P25_RELEASE_AFFS_CMD) {
// Command is in the form of: "p25-rel-affs "
if (p25 != NULL) {
uint32_t grp = getArgUInt32(args, 0U);
@@ -651,6 +672,87 @@ void RemoteControl::process(Host* host, dmr::Control* dmr, p25::Control* p25)
LogError(LOG_RCON, CMD_FAILED_STR "P25 mode is not enabled!");
}
}
+ else if (rcom == RCD_P25_CC_DEDICATED_CMD) {
+ // Command is in the form of: "p25-cc-dedicated"
+ if (p25 != NULL) {
+ if (host->m_controlData) {
+ if (dmr != NULL) {
+ LogError(LOG_RCON, CMD_FAILED_STR "Can't enable P25 control channel while DMR is enabled!");
+ }
+ else {
+ host->m_p25CtrlChannel = !host->m_p25CtrlChannel;
+ host->m_p25CtrlBroadcast = true;
+ g_fireP25Control = true;
+ g_interruptP25Control = false;
+
+ LogInfoEx(LOG_RCON, "P25 CC is %s", host->m_p25CtrlChannel ? "enabled" : "disabled");
+ }
+ }
+ else {
+ LogError(LOG_RCON, CMD_FAILED_STR "P25 control data is not enabled!");
+ }
+ }
+ else {
+ LogError(LOG_RCON, CMD_FAILED_STR "P25 mode is not enabled!");
+ }
+ }
+ else if (rcom == RCD_P25_CC_BCAST_CMD) {
+ // Command is in the form of: "p25-cc-bcast"
+ if (p25 != NULL) {
+ if (host->m_controlData) {
+ host->m_p25CtrlBroadcast = !host->m_p25CtrlBroadcast;
+
+ if (!host->m_p25CtrlBroadcast) {
+ g_fireP25Control = false;
+ g_interruptP25Control = true;
+ }
+ else {
+ g_fireP25Control = true;
+ g_interruptP25Control = false;
+ }
+
+ LogInfoEx(LOG_RCON, "P25 CC broadcast is %s", host->m_p25CtrlBroadcast ? "enabled" : "disabled");
+ }
+ else {
+ LogError(LOG_RCON, CMD_FAILED_STR "P25 control data is not enabled!");
+ }
+ }
+ else {
+ LogError(LOG_RCON, CMD_FAILED_STR "P25 mode is not enabled!");
+ }
+ }
+ else if (rcom == RCD_DMR_DEBUG) {
+ // Command is in the form of: "dmr-debug "
+ uint8_t debug = getArgUInt8(args, 0U);
+ uint8_t verbose = getArgUInt8(args, 1U);
+ if (dmr != NULL) {
+ dmr->setDebugVerbose((debug == 1U) ? true : false, (verbose == 1U) ? true : false);
+ }
+ else {
+ LogError(LOG_RCON, CMD_FAILED_STR "DMR mode is not enabled!");
+ }
+ }
+ else if (rcom == RCD_P25_DEBUG) {
+ // Command is in the form of: "p25-debug "
+ uint8_t debug = getArgUInt8(args, 0U);
+ uint8_t verbose = getArgUInt8(args, 1U);
+ if (p25 != NULL) {
+ p25->setDebugVerbose((debug == 1U) ? true : false, (verbose == 1U) ? true : false);
+ }
+ else {
+ LogError(LOG_RCON, CMD_FAILED_STR "P25 mode is not enabled!");
+ }
+ }
+ else if (rcom == RCD_P25_DUMP_TSBK) {
+ // Command is in the form of: "p25-dump-tsbk 0/1"
+ uint8_t verbose = getArgUInt8(args, 0U);
+ if (p25 != NULL) {
+ p25->trunk()->setTSBKVerbose((verbose == 1U) ? true : false);
+ }
+ else {
+ LogError(LOG_RCON, CMD_FAILED_STR "P25 mode is not enabled!");
+ }
+ }
else {
args.clear();
LogError(LOG_RCON, BAD_CMD_STR " (\"%s\")", rcom.c_str());
diff --git a/p25/Control.cpp b/p25/Control.cpp
index 71529ddf..d297f94a 100644
--- a/p25/Control.cpp
+++ b/p25/Control.cpp
@@ -612,6 +612,17 @@ void Control::clock(uint32_t ms)
m_trunk->clock(ms);
}
+///
+/// Helper to change the debug and verbose state.
+///
+/// Flag indicating whether DMR debug is enabled.
+/// Flag indicating whether DMR verbose logging is enabled.
+void Control::setDebugVerbose(bool debug, bool verbose)
+{
+ m_debug = m_voice->m_debug = m_data->m_debug = m_trunk->m_debug = debug;
+ m_verbose = m_voice->m_verbose = m_data->m_verbose = m_trunk->m_verbose = verbose;
+}
+
// ---------------------------------------------------------------------------
// Private Class Members
// ---------------------------------------------------------------------------
diff --git a/p25/Control.h b/p25/Control.h
index 60d3a578..2465aa13 100644
--- a/p25/Control.h
+++ b/p25/Control.h
@@ -106,6 +106,9 @@ namespace p25
///
TrunkPacket* trunk() { return m_trunk; }
+ /// Helper to change the debug and verbose state.
+ void setDebugVerbose(bool debug, bool verbose);
+
private:
friend class VoicePacket;
VoicePacket* m_voice;
diff --git a/p25/TrunkPacket.cpp b/p25/TrunkPacket.cpp
index e4f67342..326f1686 100644
--- a/p25/TrunkPacket.cpp
+++ b/p25/TrunkPacket.cpp
@@ -1251,6 +1251,19 @@ void TrunkPacket::writeRF_TSDU_Mot_Patch(uint32_t group1, uint32_t group2, uint3
m_rfTSBK.setMFId(P25_MFG_STANDARD);
}
+///
+/// Helper to change the TSBK verbose state.
+///
+/// Flag indicating whether TSBK dumping is enabled.
+void TrunkPacket::setTSBKVerbose(bool verbose)
+{
+ m_rfTSBK.setVerbose(verbose);
+ m_netTSBK.setVerbose(verbose);
+
+ m_rfTDULC.setVerbose(verbose);
+ m_netTDULC.setVerbose(verbose);
+}
+
// ---------------------------------------------------------------------------
// Private Class Members
// ---------------------------------------------------------------------------
diff --git a/p25/TrunkPacket.h b/p25/TrunkPacket.h
index 4b4b59ff..41c5f350 100644
--- a/p25/TrunkPacket.h
+++ b/p25/TrunkPacket.h
@@ -123,6 +123,9 @@ namespace p25
/// Helper to write a Motorola patch packet.
void writeRF_TSDU_Mot_Patch(uint32_t group1, uint32_t group2, uint32_t group3);
+ /// Helper to change the TSBK verbose state.
+ void setTSBKVerbose(bool verbose);
+
private:
friend class VoicePacket;
friend class DataPacket;