From aa1a3d5ed870a075d1d8a6ec704bf0387404253f Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Wed, 10 Feb 2021 03:43:07 +0000 Subject: [PATCH] enhance available options for P25 control data (enable/disable broadcast, enable/disable dedicated); enhance availablt options for RCON for enabling/disabling P25 CC dedicated and broadcast, as well as some remote debug enable/disable commands; --- config.yml | 5 +- dmr/Control.cpp | 13 +++ dmr/Control.h | 3 + dmr/Slot.cpp | 11 +++ dmr/Slot.h | 3 + host/Host.cpp | 149 +++++++++++++++++++-------------- host/Host.h | 3 +- network/RemoteControl.cpp | 168 ++++++++++++++++++++++++++++++-------- p25/Control.cpp | 11 +++ p25/Control.h | 3 + p25/TrunkPacket.cpp | 13 +++ p25/TrunkPacket.h | 3 + 12 files changed, 287 insertions(+), 98 deletions(-) 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;