add support to enable/disable CC message stream debug when a protocol debug is enabled; correct some bad handling of the MESSAGE_TYPE_REG NXDN command;

pull/85/head
Bryan Biedenkapp 10 months ago
parent 27c852e4c2
commit 8dd504adea

@ -4,7 +4,7 @@
* GPLv2 Open Source. Use is subject to license terms. * GPLv2 Open Source. Use is subject to license terms.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* Copyright (C) 2022,2024 Bryan Biedenkapp, N2PLL * Copyright (C) 2022,2024,2025 Bryan Biedenkapp, N2PLL
* *
*/ */
#include "Defines.h" #include "Defines.h"
@ -38,9 +38,12 @@ void MESSAGE_TYPE_REG::decode(const uint8_t* data, uint32_t length, uint32_t off
RCCH::decode(data, rcch, length, offset); RCCH::decode(data, rcch, length, offset);
m_regOption = rcch[1U] >> 3; // Registration Option m_regOption = rcch[1U] >> 3; // Registration Option
m_locId = (uint16_t)((rcch[2U] << 8) | rcch[3U]) & 0xFFFFU; // Location ID
m_locId = ((rcch[1U] & 0x07U) << 3) + ((rcch[2U] & 0xFFU) << 8U) + // Location ID
(rcch[3U] & 0xFFU); // ...
m_srcId = (uint16_t)((rcch[4U] << 8) | rcch[5U]) & 0xFFFFU; // Source Radio Address m_srcId = (uint16_t)((rcch[4U] << 8) | rcch[5U]) & 0xFFFFU; // Source Radio Address
m_dstId = (uint16_t)((rcch[6U] << 8) | rcch[7U]) & 0xFFFFU; // Target Radio Address m_dstId = (uint16_t)((rcch[6U] << 8) | rcch[7U]) & 0xFFFFU; // Talkgroup Address
// bryanb: maybe process subscriber type? (byte 8 and 9) // bryanb: maybe process subscriber type? (byte 8 and 9)
m_version = rcch[10U]; // Version m_version = rcch[10U]; // Version
} }
@ -53,11 +56,16 @@ void MESSAGE_TYPE_REG::encode(uint8_t* data, uint32_t length, uint32_t offset)
uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
rcch[2U] = (m_siteData.locId() >> 8) & 0xFFU; // ... rcch[1U] = (m_regOption << 3) + // Registration Option
rcch[3U] = (m_siteData.locId() >> 0) & 0xFFU; // ... (m_siteData.locId() >> 22U) & 0x03U; // Location ID
uint16_t systemCode = (m_siteData.locId() >> 12U) << 7U;
rcch[2U] = (systemCode >> 8U) & 0x03U; // ...
rcch[3U] = systemCode & 0xFFU; // ...
rcch[4U] = (m_srcId >> 8U) & 0xFFU; // Source Radio Address rcch[4U] = (m_srcId >> 8U) & 0xFFU; // Source Radio Address
rcch[5U] = (m_srcId >> 0U) & 0xFFU; // ... rcch[5U] = (m_srcId >> 0U) & 0xFFU; // ...
rcch[6U] = (m_dstId >> 8U) & 0xFFU; // Target Radio Address rcch[6U] = (m_dstId >> 8U) & 0xFFU; // Talkgroup Address
rcch[7U] = (m_dstId >> 0U) & 0xFFU; // ... rcch[7U] = (m_dstId >> 0U) & 0xFFU; // ...
rcch[8U] = m_causeRsp; // Cause (MM) rcch[8U] = m_causeRsp; // Cause (MM)

@ -112,6 +112,7 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, ::lookups::VoiceChDa
else { else {
dedicatedTSCC = false; dedicatedTSCC = false;
} }
bool ccDebug = control["debug"].as<bool>(false);
Slot::setSiteData(controlChData, netId, siteId, channelId, channelNo, dedicatedTSCC); Slot::setSiteData(controlChData, netId, siteId, channelId, channelNo, dedicatedTSCC);
Slot::setAlohaConfig(nRandWait, backOff); Slot::setAlohaConfig(nRandWait, backOff);
@ -125,11 +126,13 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, ::lookups::VoiceChDa
m_slot1->setTSCC(enableTSCC, dedicatedTSCC); m_slot1->setTSCC(enableTSCC, dedicatedTSCC);
m_slot1->setSupervisor(m_supervisor); m_slot1->setSupervisor(m_supervisor);
m_slot1->setDisableSourceIDGrantCheck(disableGrantSourceIdCheck); m_slot1->setDisableSourceIDGrantCheck(disableGrantSourceIdCheck);
m_slot1->setCCDebug(ccDebug);
break; break;
case 2U: case 2U:
m_slot2->setTSCC(enableTSCC, dedicatedTSCC); m_slot2->setTSCC(enableTSCC, dedicatedTSCC);
m_slot2->setSupervisor(m_supervisor); m_slot2->setSupervisor(m_supervisor);
m_slot2->setDisableSourceIDGrantCheck(disableGrantSourceIdCheck); m_slot2->setDisableSourceIDGrantCheck(disableGrantSourceIdCheck);
m_slot2->setCCDebug(ccDebug);
break; break;
default: default:
LogError(LOG_DMR, "DMR, invalid slot, TSCC disabled, slotNo = %u", m_tsccSlotNo); LogError(LOG_DMR, "DMR, invalid slot, TSCC disabled, slotNo = %u", m_tsccSlotNo);

@ -164,6 +164,7 @@ Slot::Slot(uint32_t slotNo, uint32_t timeout, uint32_t tgHang, uint32_t queueSiz
m_lastLateEntry(0U), m_lastLateEntry(0U),
m_supervisor(false), m_supervisor(false),
m_notifyCC(true), m_notifyCC(true),
m_ccDebug(debug),
m_verbose(verbose), m_verbose(verbose),
m_debug(debug) m_debug(debug)
{ {
@ -1506,6 +1507,11 @@ void Slot::writeRF_ControlData(uint16_t frameCnt, uint8_t n)
if (csbkVerbose) if (csbkVerbose)
lc::CSBK::setVerbose(false); lc::CSBK::setVerbose(false);
// disable debug logging during control data writes (if necessary)
bool controlDebug = m_debug;
if (!m_ccDebug)
m_debug = false;
// don't add any frames if the queue is full // don't add any frames if the queue is full
uint8_t len = DMR_FRAME_LENGTH_BYTES + 2U; uint8_t len = DMR_FRAME_LENGTH_BYTES + 2U;
uint32_t space = m_txQueue.freeSpace(); uint32_t space = m_txQueue.freeSpace();
@ -1615,6 +1621,7 @@ void Slot::writeRF_ControlData(uint16_t frameCnt, uint8_t n)
} while (i <= seqCnt); } while (i <= seqCnt);
lc::CSBK::setVerbose(csbkVerbose); lc::CSBK::setVerbose(csbkVerbose);
m_debug = controlDebug;
} }
/* Clears the flag indicating whether the slot is a TSCC payload slot. */ /* Clears the flag indicating whether the slot is a TSCC payload slot. */

@ -257,6 +257,12 @@ namespace dmr
*/ */
void setNotifyCC(bool notifyCC) { m_notifyCC = notifyCC; } void setNotifyCC(bool notifyCC) { m_notifyCC = notifyCC; }
/**
* @brief Sets a flag indicating whether the control message debug is enabled.
* @param enable Flag indicating whether the control message debug is enabled.
*/
void setCCDebug(bool enable) { m_ccDebug = enable; }
/** /**
* @brief Helper to set the voice error silence threshold. * @brief Helper to set the voice error silence threshold.
* @param threshold Voice error silence threshold. * @param threshold Voice error silence threshold.
@ -420,6 +426,7 @@ namespace dmr
bool m_supervisor; bool m_supervisor;
bool m_notifyCC; bool m_notifyCC;
bool m_ccDebug;
bool m_verbose; bool m_verbose;
bool m_debug; bool m_debug;

@ -115,6 +115,7 @@ Control::Control(bool authoritative, uint32_t ran, uint32_t callHang, uint32_t q
m_rssiCount(0U), m_rssiCount(0U),
m_dumpRCCH(dumpRCCHData), m_dumpRCCH(dumpRCCHData),
m_notifyCC(true), m_notifyCC(true),
m_ccDebug(debug),
m_verbose(verbose), m_verbose(verbose),
m_debug(debug) m_debug(debug)
{ {
@ -207,6 +208,7 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw
} }
m_control->m_disableGrantSrcIdCheck = control["disableGrantSourceIdCheck"].as<bool>(false); m_control->m_disableGrantSrcIdCheck = control["disableGrantSourceIdCheck"].as<bool>(false);
m_ccDebug = control["debug"].as<bool>(false);
m_ignoreAffiliationCheck = nxdnProtocol["ignoreAffiliationCheck"].as<bool>(false); m_ignoreAffiliationCheck = nxdnProtocol["ignoreAffiliationCheck"].as<bool>(false);
@ -304,6 +306,7 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw
} }
if (printOptions) { if (printOptions) {
LogInfo(" Site Location ID: $%04X", m_siteData.locId());
LogInfo(" Silence Threshold: %u (%.1f%%)", m_voice->m_silenceThreshold, float(m_voice->m_silenceThreshold) / 12.33F); LogInfo(" Silence Threshold: %u (%.1f%%)", m_voice->m_silenceThreshold, float(m_voice->m_silenceThreshold) / 12.33F);
LogInfo(" Frame Loss Threshold: %u", m_frameLossThreshold); LogInfo(" Frame Loss Threshold: %u", m_frameLossThreshold);
@ -323,6 +326,10 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw
if (disableUnitRegTimeout) { if (disableUnitRegTimeout) {
LogInfo(" Disable Unit Registration Timeout: yes"); LogInfo(" Disable Unit Registration Timeout: yes");
} }
if (m_ccDebug) {
LogInfo(" Control Message Debug: yes");
}
} }
if (m_voice != nullptr) { if (m_voice != nullptr) {

@ -343,6 +343,7 @@ namespace nxdn
bool m_notifyCC; bool m_notifyCC;
bool m_ccDebug;
bool m_verbose; bool m_verbose;
bool m_debug; bool m_debug;

@ -192,11 +192,11 @@ bool ControlSignaling::process(FuncChannelType::E fct, ChOption::E option, uint8
IS_SUPPORT_CONTROL_CHECK(rcch->toString(true), MessageType::RCCH_REG, srcId); IS_SUPPORT_CONTROL_CHECK(rcch->toString(true), MessageType::RCCH_REG, srcId);
if (m_verbose) { if (m_verbose) {
LogMessage(LOG_RF, "NXDN, %s, srcId = %u, locId = %u", LogMessage(LOG_RF, "NXDN, %s, srcId = %u, locId = $%06X, regOption = $%02X",
rcch->toString(true).c_str(), srcId, rcch->getLocId()); rcch->toString(true).c_str(), srcId, rcch->getLocId(), rcch->getRegOption());
} }
writeRF_Message_U_Reg_Rsp(srcId, rcch->getLocId()); writeRF_Message_U_Reg_Rsp(srcId, dstId, rcch->getLocId());
} }
break; break;
case MessageType::RCCH_GRP_REG: case MessageType::RCCH_GRP_REG:
@ -205,7 +205,7 @@ bool ControlSignaling::process(FuncChannelType::E fct, ChOption::E option, uint8
IS_SUPPORT_CONTROL_CHECK(rcch->toString(true), MessageType::RCCH_GRP_REG, srcId); IS_SUPPORT_CONTROL_CHECK(rcch->toString(true), MessageType::RCCH_GRP_REG, srcId);
if (m_verbose) { if (m_verbose) {
LogMessage(LOG_RF, "NXDN, %s, srcId = %u, dstId = %u, locId = %u", LogMessage(LOG_RF, "NXDN, %s, srcId = %u, dstId = %u, locId = $%06X",
rcch->toString(true).c_str(), srcId, dstId, rcch->getLocId()); rcch->toString(true).c_str(), srcId, dstId, rcch->getLocId());
} }
@ -388,6 +388,11 @@ void ControlSignaling::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adj
if (rcchVerbose) if (rcchVerbose)
lc::RCCH::setVerbose(false); lc::RCCH::setVerbose(false);
// disable debug logging during control data writes (if necessary)
bool controlDebug = m_nxdn->m_debug;
if (!m_nxdn->m_ccDebug)
m_nxdn->m_debug = m_debug = false;
// don't add any frames if the queue is full // don't add any frames if the queue is full
uint8_t len = NXDN_FRAME_LENGTH_BYTES + 2U; uint8_t len = NXDN_FRAME_LENGTH_BYTES + 2U;
uint32_t space = m_nxdn->m_txQueue.freeSpace(); uint32_t space = m_nxdn->m_txQueue.freeSpace();
@ -417,6 +422,7 @@ void ControlSignaling::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adj
} while (i <= seqCnt); } while (i <= seqCnt);
lc::RCCH::setVerbose(rcchVerbose); lc::RCCH::setVerbose(rcchVerbose);
m_nxdn->m_debug = m_debug = controlDebug;
} }
/* Helper to write a grant packet. */ /* Helper to write a grant packet. */
@ -661,7 +667,7 @@ bool ControlSignaling::writeRF_Message_Grp_Reg_Rsp(uint32_t srcId, uint32_t dstI
// validate the location ID // validate the location ID
if (locId != m_nxdn->m_siteData.locId()) { if (locId != m_nxdn->m_siteData.locId()) {
LogWarning(LOG_RF, "NXDN, %s denial, LOCID rejection, locId = $%04X", rcch->toString().c_str(), locId); LogWarning(LOG_RF, "NXDN, %s denial, LOCID rejection, locId = $%06X", rcch->toString().c_str(), locId);
::ActivityLog("NXDN", true, "group affiliation request from %u denied", srcId); ::ActivityLog("NXDN", true, "group affiliation request from %u denied", srcId);
rcch->setCauseResponse(CauseResponse::MM_REG_FAILED); rcch->setCauseResponse(CauseResponse::MM_REG_FAILED);
} }
@ -711,14 +717,14 @@ bool ControlSignaling::writeRF_Message_Grp_Reg_Rsp(uint32_t srcId, uint32_t dstI
/* Helper to write a unit registration response packet. */ /* Helper to write a unit registration response packet. */
void ControlSignaling::writeRF_Message_U_Reg_Rsp(uint32_t srcId, uint32_t locId) void ControlSignaling::writeRF_Message_U_Reg_Rsp(uint32_t srcId, uint32_t dstId, uint32_t locId)
{ {
std::unique_ptr<rcch::MESSAGE_TYPE_REG> rcch = std::make_unique<rcch::MESSAGE_TYPE_REG>(); std::unique_ptr<rcch::MESSAGE_TYPE_REG> rcch = std::make_unique<rcch::MESSAGE_TYPE_REG>();
rcch->setCauseResponse(CauseResponse::MM_REG_ACCEPTED); rcch->setCauseResponse(CauseResponse::MM_REG_ACCEPTED);
// validate the location ID // validate the location ID
if (locId != m_nxdn->m_siteData.locId()) { if (locId != ((m_nxdn->m_siteData.locId() >> 12U) << 7U)) {
LogWarning(LOG_RF, "NXDN, %s denial, LOCID rejection, locId = $%04X", rcch->toString().c_str(), locId); LogWarning(LOG_RF, "NXDN, %s denial, LOCID rejection, locId = $%06X", rcch->toString().c_str(), locId);
::ActivityLog("NXDN", true, "unit registration request from %u denied", srcId); ::ActivityLog("NXDN", true, "unit registration request from %u denied", srcId);
rcch->setCauseResponse(CauseResponse::MM_REG_FAILED); rcch->setCauseResponse(CauseResponse::MM_REG_FAILED);
} }
@ -730,9 +736,21 @@ void ControlSignaling::writeRF_Message_U_Reg_Rsp(uint32_t srcId, uint32_t locId)
rcch->setCauseResponse(CauseResponse::MM_REG_FAILED); rcch->setCauseResponse(CauseResponse::MM_REG_FAILED);
} }
// validate the talkgroup ID
if (dstId == 0U) {
LogWarning(LOG_RF, "NXDN, %s, TGID 0, dstId = %u", rcch->toString().c_str(), dstId);
}
else {
if (!acl::AccessControl::validateTGId(dstId)) {
LogWarning(LOG_RF, "NXDN, %s denial, TGID rejection, dstId = %u", rcch->toString().c_str(), dstId);
::ActivityLog("NXDN", true, "unit registration request from %u to %s %u denied", srcId, "TG ", dstId);
rcch->setCauseResponse(CauseResponse::MM_REG_FAILED);
}
}
if (rcch->getCauseResponse() == CauseResponse::MM_REG_ACCEPTED) { if (rcch->getCauseResponse() == CauseResponse::MM_REG_ACCEPTED) {
if (m_verbose) { if (m_verbose) {
LogMessage(LOG_RF, "NXDN, %s, srcId = %u, locId = %u", LogMessage(LOG_RF, "NXDN, %s, srcId = %u, locId = $%06X",
rcch->toString().c_str(), srcId, locId); rcch->toString().c_str(), srcId, locId);
} }
@ -748,7 +766,7 @@ void ControlSignaling::writeRF_Message_U_Reg_Rsp(uint32_t srcId, uint32_t locId)
} }
rcch->setSrcId(srcId); rcch->setSrcId(srcId);
rcch->setDstId(srcId); rcch->setDstId(dstId);
writeRF_Message_Imm(rcch.get(), true); writeRF_Message_Imm(rcch.get(), true);
} }

@ -168,9 +168,10 @@ namespace nxdn
/** /**
* @brief Helper to write a unit registration response packet. * @brief Helper to write a unit registration response packet.
* @param srcId Source Radio ID. * @param srcId Source Radio ID.
* @param dstId Destination ID.
* @param locId Location ID. * @param locId Location ID.
*/ */
void writeRF_Message_U_Reg_Rsp(uint32_t srcId, uint32_t locId); void writeRF_Message_U_Reg_Rsp(uint32_t srcId, uint32_t dstId, uint32_t locId);
/** /**
* @brief Helper to write a CC SITE_INFO broadcast packet on the RF interface. * @brief Helper to write a CC SITE_INFO broadcast packet on the RF interface.

@ -127,6 +127,7 @@ Control::Control(bool authoritative, uint32_t nac, uint32_t callHang, uint32_t q
m_aveRSSI(0U), m_aveRSSI(0U),
m_rssiCount(0U), m_rssiCount(0U),
m_notifyCC(true), m_notifyCC(true),
m_ccDebug(debug),
m_verbose(verbose), m_verbose(verbose),
m_debug(debug) m_debug(debug)
{ {
@ -310,6 +311,7 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw
m_control->m_ctrlTimeDateAnn = control["enableTimeDateAnn"].as<bool>(false); m_control->m_ctrlTimeDateAnn = control["enableTimeDateAnn"].as<bool>(false);
m_control->m_redundantImmediate = control["redundantImmediate"].as<bool>(true); m_control->m_redundantImmediate = control["redundantImmediate"].as<bool>(true);
m_control->m_redundantGrant = control["redundantGrantTransmit"].as<bool>(false); m_control->m_redundantGrant = control["redundantGrantTransmit"].as<bool>(false);
m_ccDebug = control["debug"].as<bool>(false);
m_allowExplicitSourceId = p25Protocol["allowExplicitSourceId"].as<bool>(true); m_allowExplicitSourceId = p25Protocol["allowExplicitSourceId"].as<bool>(true);
m_convNetGrantDemand = p25Protocol["convNetGrantDemand"].as<bool>(false); m_convNetGrantDemand = p25Protocol["convNetGrantDemand"].as<bool>(false);
@ -515,6 +517,10 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw
if (m_control->m_redundantGrant) { if (m_control->m_redundantGrant) {
LogInfo(" Redundant Grant Transmit: yes"); LogInfo(" Redundant Grant Transmit: yes");
} }
if (m_ccDebug) {
LogInfo(" Control Message Debug: yes");
}
} }
// are we overriding the NAC for split NAC operations? // are we overriding the NAC for split NAC operations?

@ -380,6 +380,7 @@ namespace p25
bool m_notifyCC; bool m_notifyCC;
bool m_ccDebug;
bool m_verbose; bool m_verbose;
bool m_debug; bool m_debug;

@ -1759,6 +1759,11 @@ void ControlSignaling::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adj
if (tsbkVerbose) if (tsbkVerbose)
lc::TSBK::setVerbose(false); lc::TSBK::setVerbose(false);
// disable debug logging during control data writes (if necessary)
bool controlDebug = m_p25->m_debug;
if (!m_p25->m_ccDebug)
m_p25->m_debug = m_debug = false;
if (m_convFallback) { if (m_convFallback) {
bool fallbackTx = (frameCnt % 253U) == 0U; bool fallbackTx = (frameCnt % 253U) == 0U;
if (fallbackTx && n == 8U) { if (fallbackTx && n == 8U) {
@ -1901,6 +1906,7 @@ void ControlSignaling::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adj
} }
lc::TSBK::setVerbose(tsbkVerbose); lc::TSBK::setVerbose(tsbkVerbose);
m_p25->m_debug = m_debug = controlDebug;
} }
/* Helper to generate the given control TSBK into the TSDU frame queue. */ /* Helper to generate the given control TSBK into the TSDU frame queue. */

Loading…
Cancel
Save

Powered by TurnKey Linux.