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.
* 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"
@ -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);
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_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)
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];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
rcch[2U] = (m_siteData.locId() >> 8) & 0xFFU; // ...
rcch[3U] = (m_siteData.locId() >> 0) & 0xFFU; // ...
rcch[1U] = (m_regOption << 3) + // Registration Option
(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[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[8U] = m_causeRsp; // Cause (MM)

@ -112,6 +112,7 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, ::lookups::VoiceChDa
else {
dedicatedTSCC = false;
}
bool ccDebug = control["debug"].as<bool>(false);
Slot::setSiteData(controlChData, netId, siteId, channelId, channelNo, dedicatedTSCC);
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->setSupervisor(m_supervisor);
m_slot1->setDisableSourceIDGrantCheck(disableGrantSourceIdCheck);
m_slot1->setCCDebug(ccDebug);
break;
case 2U:
m_slot2->setTSCC(enableTSCC, dedicatedTSCC);
m_slot2->setSupervisor(m_supervisor);
m_slot2->setDisableSourceIDGrantCheck(disableGrantSourceIdCheck);
m_slot2->setCCDebug(ccDebug);
break;
default:
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_supervisor(false),
m_notifyCC(true),
m_ccDebug(debug),
m_verbose(verbose),
m_debug(debug)
{
@ -1506,6 +1507,11 @@ void Slot::writeRF_ControlData(uint16_t frameCnt, uint8_t n)
if (csbkVerbose)
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
uint8_t len = DMR_FRAME_LENGTH_BYTES + 2U;
uint32_t space = m_txQueue.freeSpace();
@ -1615,6 +1621,7 @@ void Slot::writeRF_ControlData(uint16_t frameCnt, uint8_t n)
} while (i <= seqCnt);
lc::CSBK::setVerbose(csbkVerbose);
m_debug = controlDebug;
}
/* 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; }
/**
* @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.
* @param threshold Voice error silence threshold.
@ -420,6 +426,7 @@ namespace dmr
bool m_supervisor;
bool m_notifyCC;
bool m_ccDebug;
bool m_verbose;
bool m_debug;

@ -115,6 +115,7 @@ Control::Control(bool authoritative, uint32_t ran, uint32_t callHang, uint32_t q
m_rssiCount(0U),
m_dumpRCCH(dumpRCCHData),
m_notifyCC(true),
m_ccDebug(debug),
m_verbose(verbose),
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_ccDebug = control["debug"].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) {
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(" Frame Loss Threshold: %u", m_frameLossThreshold);
@ -323,6 +326,10 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw
if (disableUnitRegTimeout) {
LogInfo(" Disable Unit Registration Timeout: yes");
}
if (m_ccDebug) {
LogInfo(" Control Message Debug: yes");
}
}
if (m_voice != nullptr) {

@ -343,6 +343,7 @@ namespace nxdn
bool m_notifyCC;
bool m_ccDebug;
bool m_verbose;
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);
if (m_verbose) {
LogMessage(LOG_RF, "NXDN, %s, srcId = %u, locId = %u",
rcch->toString(true).c_str(), srcId, rcch->getLocId());
LogMessage(LOG_RF, "NXDN, %s, srcId = %u, locId = $%06X, regOption = $%02X",
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;
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);
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());
}
@ -388,6 +388,11 @@ void ControlSignaling::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adj
if (rcchVerbose)
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
uint8_t len = NXDN_FRAME_LENGTH_BYTES + 2U;
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);
lc::RCCH::setVerbose(rcchVerbose);
m_nxdn->m_debug = m_debug = controlDebug;
}
/* 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
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);
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. */
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>();
rcch->setCauseResponse(CauseResponse::MM_REG_ACCEPTED);
// validate the location ID
if (locId != m_nxdn->m_siteData.locId()) {
LogWarning(LOG_RF, "NXDN, %s denial, LOCID rejection, locId = $%04X", rcch->toString().c_str(), locId);
if (locId != ((m_nxdn->m_siteData.locId() >> 12U) << 7U)) {
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);
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);
}
// 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 (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);
}
@ -748,7 +766,7 @@ void ControlSignaling::writeRF_Message_U_Reg_Rsp(uint32_t srcId, uint32_t locId)
}
rcch->setSrcId(srcId);
rcch->setDstId(srcId);
rcch->setDstId(dstId);
writeRF_Message_Imm(rcch.get(), true);
}

@ -168,9 +168,10 @@ namespace nxdn
/**
* @brief Helper to write a unit registration response packet.
* @param srcId Source Radio ID.
* @param dstId Destination 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.

@ -127,6 +127,7 @@ Control::Control(bool authoritative, uint32_t nac, uint32_t callHang, uint32_t q
m_aveRSSI(0U),
m_rssiCount(0U),
m_notifyCC(true),
m_ccDebug(debug),
m_verbose(verbose),
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_redundantImmediate = control["redundantImmediate"].as<bool>(true);
m_control->m_redundantGrant = control["redundantGrantTransmit"].as<bool>(false);
m_ccDebug = control["debug"].as<bool>(false);
m_allowExplicitSourceId = p25Protocol["allowExplicitSourceId"].as<bool>(true);
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) {
LogInfo(" Redundant Grant Transmit: yes");
}
if (m_ccDebug) {
LogInfo(" Control Message Debug: yes");
}
}
// are we overriding the NAC for split NAC operations?

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

@ -1759,6 +1759,11 @@ void ControlSignaling::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adj
if (tsbkVerbose)
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) {
bool fallbackTx = (frameCnt % 253U) == 0U;
if (fallbackTx && n == 8U) {
@ -1901,6 +1906,7 @@ void ControlSignaling::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adj
}
lc::TSBK::setVerbose(tsbkVerbose);
m_p25->m_debug = m_debug = controlDebug;
}
/* Helper to generate the given control TSBK into the TSDU frame queue. */

Loading…
Cancel
Save

Powered by TurnKey Linux.