diff --git a/p25/Control.cpp b/p25/Control.cpp index a0ae9750..0b7aefcc 100644 --- a/p25/Control.cpp +++ b/p25/Control.cpp @@ -212,6 +212,7 @@ void Control::setOptions(yaml::Node& conf, const std::string cwCallsign, const s m_voiceOnControl = p25Protocol["voiceOnControl"].as(false); m_ackTSBKRequests = control["ackRequests"].as(true); + m_trunk->m_ctrlTSDUMBF = !control["disableTSDUMBF"].as(false); m_voice->m_silenceThreshold = p25Protocol["silenceThreshold"].as(p25::DEFAULT_SILENCE_THRESHOLD); if (m_voice->m_silenceThreshold > MAX_P25_VOICE_ERRORS) { @@ -259,6 +260,9 @@ void Control::setOptions(yaml::Node& conf, const std::string cwCallsign, const s } LogInfo(" Disable Network HDUs: %s", m_disableNetworkHDU ? "yes" : "no"); + if (!m_trunk->m_ctrlTSDUMBF) { + LogInfo(" Disable Multi-Block TSDUs: yes"); + } LogInfo(" Inhibit Illegal: %s", m_inhibitIllegal ? "yes" : "no"); LogInfo(" Legacy Group Grant: %s", m_legacyGroupGrnt ? "yes" : "no"); @@ -533,7 +537,7 @@ bool Control::writeControlEndRF() if (m_netState == RS_NET_IDLE && m_rfState == RS_RF_LISTENING) { for (uint32_t i = 0; i < TSBK_PCH_CCH_CNT; i++) { - m_trunk->queueRF_TSBK_Ctrl_MBF(TSBK_OSP_MOT_PSH_CCH); + m_trunk->queueRF_TSBK_Ctrl(TSBK_OSP_MOT_PSH_CCH); } writeRF_Nulls(); diff --git a/p25/TrunkPacket.cpp b/p25/TrunkPacket.cpp index 4512ac05..2fc30876 100644 --- a/p25/TrunkPacket.cpp +++ b/p25/TrunkPacket.cpp @@ -1139,6 +1139,7 @@ TrunkPacket::TrunkPacket(Control* p25, network::BaseNetwork* network, bool dumpT m_noMessageAck(true), m_adjSiteUpdateTimer(1000U), m_adjSiteUpdateInterval(ADJ_SITE_TIMER_TIMEOUT), + m_ctrlTSDUMBF(true), m_dumpTSBK(dumpTSBKData), m_verbose(verbose), m_debug(debug) @@ -1217,34 +1218,34 @@ void TrunkPacket::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS) /** required data */ case 0: default: - queueRF_TSBK_Ctrl_MBF(TSBK_OSP_IDEN_UP); + queueRF_TSBK_Ctrl(TSBK_OSP_IDEN_UP); break; case 1: if (alt) - queueRF_TSBK_Ctrl_MBF(TSBK_OSP_RFSS_STS_BCAST); + queueRF_TSBK_Ctrl(TSBK_OSP_RFSS_STS_BCAST); else - queueRF_TSBK_Ctrl_MBF(TSBK_OSP_NET_STS_BCAST); + queueRF_TSBK_Ctrl(TSBK_OSP_NET_STS_BCAST); break; case 2: if (alt) - queueRF_TSBK_Ctrl_MBF(TSBK_OSP_NET_STS_BCAST); + queueRF_TSBK_Ctrl(TSBK_OSP_NET_STS_BCAST); else - queueRF_TSBK_Ctrl_MBF(TSBK_OSP_RFSS_STS_BCAST); + queueRF_TSBK_Ctrl(TSBK_OSP_RFSS_STS_BCAST); break; case 3: if (alt) - queueRF_TSBK_Ctrl_MBF(TSBK_OSP_RFSS_STS_BCAST); + queueRF_TSBK_Ctrl(TSBK_OSP_RFSS_STS_BCAST); else - queueRF_TSBK_Ctrl_MBF(TSBK_OSP_NET_STS_BCAST); + queueRF_TSBK_Ctrl(TSBK_OSP_NET_STS_BCAST); break; /** extra data */ case 4: - queueRF_TSBK_Ctrl_MBF(TSBK_OSP_SNDCP_CH_ANN); + queueRF_TSBK_Ctrl(TSBK_OSP_SNDCP_CH_ANN); break; case 5: // write ADJSS if (adjSS && m_adjSiteTable.size() > 0) { - queueRF_TSBK_Ctrl_MBF(TSBK_OSP_ADJ_STS_BCAST); + queueRF_TSBK_Ctrl(TSBK_OSP_ADJ_STS_BCAST); break; } else { forcePad = true; @@ -1252,7 +1253,7 @@ void TrunkPacket::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS) case 6: // write SCCB if (adjSS && m_sccbTable.size() > 0) { - queueRF_TSBK_Ctrl_MBF(TSBK_OSP_SCCB_EXP); + queueRF_TSBK_Ctrl(TSBK_OSP_SCCB_EXP); break; } } @@ -1260,15 +1261,17 @@ void TrunkPacket::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS) // should we insert the BSI bursts? bool bsi = (frameCnt % 127U) == 0U; if (bsi && n > 3U) { - queueRF_TSBK_Ctrl_MBF(TSBK_OSP_MOT_CC_BSI); + queueRF_TSBK_Ctrl(TSBK_OSP_MOT_CC_BSI); } - // add padding after the 4th sequence - if (n == 6U || forcePad) { + // add padding after the last sequence or if forced; and only + // if we're doing multiblock frames (MBF) + if ((n == 6U || forcePad) && m_ctrlTSDUMBF) + { // pad MBF if we have 1 queued TSDUs if (m_mbfCnt == 1U) { - queueRF_TSBK_Ctrl_MBF(TSBK_OSP_RFSS_STS_BCAST); - queueRF_TSBK_Ctrl_MBF(TSBK_OSP_NET_STS_BCAST); + queueRF_TSBK_Ctrl(TSBK_OSP_RFSS_STS_BCAST); + queueRF_TSBK_Ctrl(TSBK_OSP_NET_STS_BCAST); if (m_debug) { LogDebug(LOG_P25, "writeRF_ControlData, have 1 pad 2, mbfCnt = %u", m_mbfCnt); } @@ -1278,10 +1281,10 @@ void TrunkPacket::writeRF_ControlData(uint8_t frameCnt, uint8_t n, bool adjSS) if (m_mbfCnt == 2U) { std::vector entries = m_p25->m_idenTable->list(); if (entries.size() > 1U) { - queueRF_TSBK_Ctrl_MBF(TSBK_OSP_IDEN_UP); + queueRF_TSBK_Ctrl(TSBK_OSP_IDEN_UP); } else { - queueRF_TSBK_Ctrl_MBF(TSBK_OSP_RFSS_STS_BCAST); + queueRF_TSBK_Ctrl(TSBK_OSP_RFSS_STS_BCAST); } if (m_debug) { @@ -1404,7 +1407,7 @@ void TrunkPacket::writeRF_TSDU_SBF(bool noNetwork, bool clearBeforeWrite) } // Add busy bits - m_p25->addBusyBits(data + 2U, P25_TSDU_FRAME_LENGTH_BITS, false, true); + m_p25->addBusyBits(data + 2U, P25_TSDU_FRAME_LENGTH_BITS, true, false); // Set first busy bits to 1,1 m_p25->setBusyBits(data + 2U, P25_SS0_START, true, true); @@ -1412,12 +1415,12 @@ void TrunkPacket::writeRF_TSDU_SBF(bool noNetwork, bool clearBeforeWrite) if (!noNetwork) writeNetworkRF(data + 2U, true); - if (m_p25->m_dedicatedControl) { + if (m_p25->m_dedicatedControl && m_ctrlTSDUMBF) { writeRF_TSDU_MBF(clearBeforeWrite); return; } - if (m_p25->m_ccRunning) { + if (m_p25->m_ccRunning && m_ctrlTSDUMBF) { writeRF_TSDU_MBF(clearBeforeWrite); return; } @@ -1436,7 +1439,7 @@ void TrunkPacket::writeRF_TSDU_SBF(bool noNetwork, bool clearBeforeWrite) } /// -/// Helper to write a multi-block P25 TSDU packet. +/// Helper to write a multi-block (3-block) P25 TSDU packet. /// /// void TrunkPacket::writeRF_TSDU_MBF(bool clearBeforeWrite) @@ -1509,7 +1512,7 @@ void TrunkPacket::writeRF_TSDU_MBF(bool clearBeforeWrite) P25Utils::encode(tsdu, data + 2U, 114U, 720U); // Add busy bits - m_p25->addBusyBits(data + 2U, P25_TSDU_TRIPLE_FRAME_LENGTH_BITS, false, true); + m_p25->addBusyBits(data + 2U, P25_TSDU_TRIPLE_FRAME_LENGTH_BITS, true, false); // Add idle bits addIdleBits(data + 2U, P25_TSDU_TRIPLE_FRAME_LENGTH_BITS, true, true); @@ -1542,10 +1545,10 @@ void TrunkPacket::writeRF_TSDU_MBF(bool clearBeforeWrite) } /// -/// Helper to queue the given control TSBK into the MBF queue. +/// Helper to generate the given control TSBK into the TSDU frame queue. /// /// -void TrunkPacket::queueRF_TSBK_Ctrl_MBF(uint8_t lco) +void TrunkPacket::queueRF_TSBK_Ctrl(uint8_t lco) { if (!m_p25->m_control) return; @@ -1726,7 +1729,14 @@ void TrunkPacket::queueRF_TSBK_Ctrl_MBF(uint8_t lco) } m_rfTSBK.setLastBlock(true); // always set last block - writeRF_TSDU_MBF(); + + // are we transmitting CC as a multi-block? + if (m_ctrlTSDUMBF) { + writeRF_TSDU_MBF(); + } + else { + writeRF_TSDU_SBF(false); + } } /// @@ -2183,7 +2193,7 @@ void TrunkPacket::writeNet_TSDU_From_RF(uint8_t* data) m_rfTSBK.encode(data, true); // Add busy bits - m_p25->addBusyBits(data, P25_TSDU_FRAME_LENGTH_BYTES, false, true); + m_p25->addBusyBits(data, P25_TSDU_FRAME_LENGTH_BYTES, true, false); // Set first busy bits to 1,1 m_p25->setBusyBits(data, P25_SS0_START, true, true); @@ -2258,7 +2268,7 @@ void TrunkPacket::writeNet_TSDU() m_netTSBK.encode(buffer + 2U, true); // Add busy bits - m_p25->addBusyBits(buffer + 2U, P25_TSDU_FRAME_LENGTH_BYTES, false, true); + m_p25->addBusyBits(buffer + 2U, P25_TSDU_FRAME_LENGTH_BYTES, true, false); // Set first busy bits to 1,1 m_p25->setBusyBits(buffer + 2U, P25_SS0_START, true, true); diff --git a/p25/TrunkPacket.h b/p25/TrunkPacket.h index 9583d4b0..595a7696 100644 --- a/p25/TrunkPacket.h +++ b/p25/TrunkPacket.h @@ -153,6 +153,8 @@ namespace p25 Timer m_adjSiteUpdateTimer; uint32_t m_adjSiteUpdateInterval; + bool m_ctrlTSDUMBF; + bool m_dumpTSBK; bool m_verbose; @@ -176,11 +178,11 @@ namespace p25 /// Helper to write a single-block P25 TSDU packet. void writeRF_TSDU_SBF(bool noNetwork, bool clearBeforeWrite = false); - /// Helper to write a multi-block P25 TSDU packet. + /// Helper to write a multi-block (3-block) P25 TSDU packet. void writeRF_TSDU_MBF(bool clearBeforeWrite = false); - /// Helper to queue the given control TSBK into the MBF queue. - void queueRF_TSBK_Ctrl_MBF(uint8_t lco); + /// Helper to generate the given control TSBK into the TSDU frame queue. + void queueRF_TSBK_Ctrl(uint8_t lco); /// Helper to write a grant packet. bool writeRF_TSDU_Grant(bool grp, bool skip, bool net);