diff --git a/configs/config.example.yml b/configs/config.example.yml index 6b57762a..5ced356f 100644 --- a/configs/config.example.yml +++ b/configs/config.example.yml @@ -176,6 +176,9 @@ protocols: # Flag indicating whether or not VOC (voice on control) support is enabled. voiceOnControl: false + # Flag indicating whether or not to ignore voice frames on a control channel + # This comes in handy if you're running non-dedicated with an FNE so the CC doesn't repeat voice traffic + controlOnly: false # Flag indicating whether or not the composite flag in the CC service options is set. # (This is useful to disable for some radios when running in VOC mode.) disableCompositeFlag: false diff --git a/src/p25/Control.cpp b/src/p25/Control.cpp index 9e2cb031..2bbd17a5 100644 --- a/src/p25/Control.cpp +++ b/src/p25/Control.cpp @@ -254,6 +254,7 @@ void Control::setOptions(yaml::Node& conf, bool supervisor, const std::string cw } m_voiceOnControl = p25Protocol["voiceOnControl"].as(false); + m_controlOnly = p25Protocol["controlOnly"].as(false); // if control channel is off for voice on control off if (!m_control) { @@ -535,6 +536,12 @@ bool Control::processFrame(uint8_t* data, uint32_t len) case P25_DUID_HDU: case P25_DUID_LDU1: case P25_DUID_LDU2: + if (m_controlOnly) { + if (m_debug) { + LogDebug(LOG_RF, "CC only mode, ignoring HDU/LDU from RF"); + } + break; + } if (!m_dedicatedControl) ret = m_voice->process(data, len); else { @@ -1126,6 +1133,12 @@ void Control::processNetwork() case P25_DUID_HDU: case P25_DUID_LDU1: case P25_DUID_LDU2: + if (m_controlOnly) { + if (m_debug) { + LogDebug(LOG_NET, "CC only mode, ignoring HDU/LDU from network"); + } + break; + } ret = m_voice->processNetwork(data.get(), frameLength, control, lsd, duid, frameType); break; diff --git a/src/p25/Control.h b/src/p25/Control.h index b63f79a2..b86a1466 100644 --- a/src/p25/Control.h +++ b/src/p25/Control.h @@ -171,6 +171,7 @@ namespace p25 bool m_control; bool m_dedicatedControl; bool m_voiceOnControl; + bool m_controlOnly; bool m_ackTSBKRequests; bool m_disableNetworkHDU; diff --git a/src/p25/packet/Data.cpp b/src/p25/packet/Data.cpp index e93e0db3..6d443f6c 100644 --- a/src/p25/packet/Data.cpp +++ b/src/p25/packet/Data.cpp @@ -162,6 +162,23 @@ bool Data::process(uint8_t* data, uint32_t len) return false; } + // If we're in control only mode, we only want to handle AMBTs. Otherwise return + if (m_p25->m_controlOnly && m_rfDataHeader.getMFId() != PDU_FMT_AMBT) { + if (m_debug) { + LogDebug(LOG_RF, "CC only mode, ignoring non-AMBT PDU from RF"); + } + // Reset the CC halted flag + m_p25->m_ccHalted = false; + // Reset everything else + m_rfDataHeader.reset(); + m_rfSecondHeader.reset(); + m_rfDataBlockCnt = 0U; + m_rfPDUCount = 0U; + m_rfPDUBits = 0U; + m_p25->m_rfState = m_prevRfState; + return false; + } + // only send data blocks across the network, if we're not an AMBT, // an RSP or a registration service if ((m_rfDataHeader.getFormat() != PDU_FMT_AMBT) && @@ -491,6 +508,21 @@ bool Data::processNetwork(uint8_t* data, uint32_t len, uint32_t blockLength) return false; } + // If we're in control only mode, we only want to handle AMBTs. Otherwise return + if (m_p25->m_controlOnly && m_rfDataHeader.getMFId() != PDU_FMT_AMBT) { + if (m_debug) { + LogDebug(LOG_NET, "CC only mode, ignoring non-AMBT PDU from network"); + } + // Reset everything else + m_netDataHeader.reset(); + m_netSecondHeader.reset(); + m_netDataOffset = 0U; + m_netDataBlockCnt = 0U; + m_netPDUCount = 0U; + m_p25->m_netState = RS_NET_IDLE; + return false; + } + m_netPDUCount++; return true; }