diff --git a/p25/Control.cpp b/p25/Control.cpp
index 855c4932..b1667cef 100644
--- a/p25/Control.cpp
+++ b/p25/Control.cpp
@@ -834,23 +834,31 @@ void Control::writeRF_Nulls()
///
/// Helper to write TDU preamble packet burst.
///
-void Control::writeRF_Preamble()
+///
+///
+void Control::writeRF_Preamble(uint32_t preambleCount, bool force)
{
- if (m_modem->hasTX() || m_tduPreambleCount == 0U) {
- return;
+ if (preambleCount == 0) {
+ preambleCount = m_tduPreambleCount;
}
- if (m_ccRunning) {
- return;
+ if (!force) {
+ if (m_modem->hasTX() || m_tduPreambleCount == 0U) {
+ return;
+ }
+
+ if (m_ccRunning) {
+ return;
+ }
}
if (m_tduPreambleCount > MAX_PREAMBLE_TDU_CNT) {
LogWarning(LOG_P25, "oversized TDU preamble count, reducing to maximum %u", MAX_PREAMBLE_TDU_CNT);
- m_tduPreambleCount = MAX_PREAMBLE_TDU_CNT;
+ preambleCount = m_tduPreambleCount = MAX_PREAMBLE_TDU_CNT;
}
// write TDUs if requested
- for (uint8_t i = 0U; i < m_tduPreambleCount; i++) {
+ for (uint8_t i = 0U; i < preambleCount; i++) {
writeRF_TDU(true);
}
}
diff --git a/p25/Control.h b/p25/Control.h
index 8a82a79e..edbb6068 100644
--- a/p25/Control.h
+++ b/p25/Control.h
@@ -189,7 +189,7 @@ namespace p25
/// Helper to write data nulls.
void writeRF_Nulls();
/// Helper to write TDU preamble packet burst.
- void writeRF_Preamble();
+ void writeRF_Preamble(uint32_t preambleCount = 0, bool force = false);
/// Helper to write a P25 TDU packet.
void writeRF_TDU(bool noNetwork);
diff --git a/p25/TrunkPacket.cpp b/p25/TrunkPacket.cpp
index 4ce51a1c..f76d5179 100644
--- a/p25/TrunkPacket.cpp
+++ b/p25/TrunkPacket.cpp
@@ -213,7 +213,7 @@ bool TrunkPacket::process(uint8_t* data, uint32_t len)
LogMessage(LOG_RF, P25_TSDU_STR ", TSBK_IOSP_GRP_VCH (Group Voice Channel Request), srcId = %u, dstId = %u", srcId, dstId);
}
- writeRF_TSDU_Grant(true, false, false);
+ writeRF_TSDU_Grant(true);
break;
case TSBK_IOSP_UU_VCH:
// make sure control data is supported
@@ -236,7 +236,7 @@ bool TrunkPacket::process(uint8_t* data, uint32_t len)
writeRF_TSDU_UU_Ans_Req(srcId, dstId);
}
else {
- writeRF_TSDU_Grant(false, false, false);
+ writeRF_TSDU_Grant(false);
}
break;
case TSBK_IOSP_UU_ANS:
@@ -259,7 +259,7 @@ bool TrunkPacket::process(uint8_t* data, uint32_t len)
writeRF_TSDU_ACK_FNE(dstId, TSBK_IOSP_UU_ANS, false, true);
}
- writeRF_TSDU_Grant(false, false, false);
+ writeRF_TSDU_Grant(false);
}
else if (m_rfTSBK.getResponse() == P25_ANS_RSP_DENY) {
writeRF_TSDU_Deny(P25_DENY_RSN_TGT_UNIT_REFUSED, TSBK_IOSP_UU_ANS);
@@ -1465,7 +1465,8 @@ void TrunkPacket::writeRF_TDULC_ChanRelease(bool grp, uint32_t srcId, uint32_t d
///
///
///
-void TrunkPacket::writeRF_TSDU_SBF(bool noNetwork, bool clearBeforeWrite)
+///
+void TrunkPacket::writeRF_TSDU_SBF(bool noNetwork, bool clearBeforeWrite, bool force)
{
if (!m_p25->m_control)
return;
@@ -1496,19 +1497,21 @@ void TrunkPacket::writeRF_TSDU_SBF(bool noNetwork, bool clearBeforeWrite)
if (!noNetwork)
writeNetworkRF(data + 2U, true);
- if (m_p25->m_dedicatedControl && m_ctrlTSDUMBF) {
- writeRF_TSDU_MBF(clearBeforeWrite);
- return;
- }
+ if (!force) {
+ if (m_p25->m_dedicatedControl && m_ctrlTSDUMBF) {
+ writeRF_TSDU_MBF(clearBeforeWrite);
+ return;
+ }
- if (m_p25->m_ccRunning && m_ctrlTSDUMBF) {
- writeRF_TSDU_MBF(clearBeforeWrite);
- return;
- }
+ if (m_p25->m_ccRunning && m_ctrlTSDUMBF) {
+ writeRF_TSDU_MBF(clearBeforeWrite);
+ return;
+ }
- if (clearBeforeWrite) {
- m_p25->m_modem->clearP25Data();
- m_p25->m_queue.clear();
+ if (clearBeforeWrite) {
+ m_p25->m_modem->clearP25Data();
+ m_p25->m_queue.clear();
+ }
}
if (m_p25->m_duplex) {
@@ -1985,7 +1988,7 @@ bool TrunkPacket::writeRF_TSDU_Grant(bool grp, bool skip, bool net)
// transmit group grant
m_rfTSBK.setLCO(TSBK_IOSP_GRP_VCH);
- writeRF_TSDU_SBF(false, true);
+ writeRF_TSDU_SBF(false, true, net);
}
else {
if (!net) {
@@ -1999,7 +2002,7 @@ bool TrunkPacket::writeRF_TSDU_Grant(bool grp, bool skip, bool net)
// transmit private grant
m_rfTSBK.setLCO(TSBK_IOSP_UU_VCH);
- writeRF_TSDU_SBF(false, true);
+ writeRF_TSDU_SBF(false, true, net);
}
m_rfTSBK.setLCO(lco);
diff --git a/p25/TrunkPacket.h b/p25/TrunkPacket.h
index 5b9a6182..aa8ac381 100644
--- a/p25/TrunkPacket.h
+++ b/p25/TrunkPacket.h
@@ -175,7 +175,7 @@ namespace p25
void writeRF_TDULC_ChanRelease(bool grp, uint32_t srcId, uint32_t dstId);
/// Helper to write a single-block P25 TSDU packet.
- void writeRF_TSDU_SBF(bool noNetwork, bool clearBeforeWrite = false);
+ void writeRF_TSDU_SBF(bool noNetwork, bool clearBeforeWrite = false, bool force = false);
/// Helper to write a multi-block (3-block) P25 TSDU packet.
void writeRF_TSDU_MBF(bool clearBeforeWrite = false);
@@ -183,7 +183,7 @@ namespace p25
void queueRF_TSBK_Ctrl(uint8_t lco);
/// Helper to write a grant packet.
- bool writeRF_TSDU_Grant(bool grp, bool skip, bool net);
+ bool writeRF_TSDU_Grant(bool grp, bool skip = false, bool net = false);
/// Helper to write a unit to unit answer request packet.
void writeRF_TSDU_UU_Ans_Req(uint32_t srcId, uint32_t dstId);
/// Helper to write a acknowledge packet.
diff --git a/p25/VoicePacket.cpp b/p25/VoicePacket.cpp
index 6f806622..507d5d6c 100644
--- a/p25/VoicePacket.cpp
+++ b/p25/VoicePacket.cpp
@@ -343,7 +343,7 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
}
}
- if (!m_p25->m_trunk->writeRF_TSDU_Grant(group, false, false)) {
+ if (!m_p25->m_trunk->writeRF_TSDU_Grant(group)) {
return false;
}
}
@@ -356,7 +356,7 @@ bool VoicePacket::process(uint8_t* data, uint32_t len)
// single-channel trunking or voice on control support?
if (m_p25->m_control && m_p25->m_voiceOnControl) {
m_p25->m_ccRunning = false; // otherwise the grant will be bundled with other packets
- m_p25->m_trunk->writeRF_TSDU_Grant(group, true, false);
+ m_p25->m_trunk->writeRF_TSDU_Grant(group, true);
}
m_hadVoice = true;
@@ -779,6 +779,16 @@ bool VoicePacket::processNetwork(uint8_t* data, uint32_t len, lc::LC& control, d
count += 16U;
if (m_p25->m_netState == RS_NET_IDLE) {
+ // are we interrupting a running CC?
+ if (m_p25->m_ccRunning) {
+ g_interruptP25Control = true;
+ }
+
+ // single-channel trunking or voice on control support?
+ if (m_p25->m_control && m_p25->m_voiceOnControl) {
+ m_p25->m_ccRunning = false; // otherwise the grant will be bundled with other packets
+ }
+
m_p25->m_modem->clearP25Data();
m_p25->m_queue.clear();
@@ -1191,7 +1201,7 @@ void VoicePacket::writeNet_LDU1(const lc::LC& control, const data::LowSpeedData&
// single-channel trunking or voice on control support?
if (m_p25->m_control && m_p25->m_voiceOnControl) {
m_p25->m_ccRunning = false; // otherwise the grant will be bundled with other packets
- if (!m_p25->m_trunk->writeRF_TSDU_Grant(group, true, true)) {
+ if (!m_p25->m_trunk->writeRF_TSDU_Grant(group, false, true)) {
if (m_network != NULL)
m_network->resetP25();
@@ -1213,6 +1223,8 @@ void VoicePacket::writeNet_LDU1(const lc::LC& control, const data::LowSpeedData&
return;
}
+
+ m_p25->writeRF_Preamble(0, true);
}
m_hadVoice = true;