diff --git a/p25/dfsi/packet/DFSITrunk.cpp b/p25/dfsi/packet/DFSITrunk.cpp
index 049f78ec..efa84341 100644
--- a/p25/dfsi/packet/DFSITrunk.cpp
+++ b/p25/dfsi/packet/DFSITrunk.cpp
@@ -198,6 +198,18 @@ void DFSITrunk::writeRF_TSDU_SBF(bool noNetwork, bool clearBeforeWrite, bool for
writeRF_DSFI_Stop(P25_DFSI_TYPE_TSBK);
}
+///
+/// Helper to write a alternate multi-block trunking PDU packet.
+///
+///
+void DFSITrunk::writeRF_TSDU_AMBT(bool clearBeforeWrite)
+{
+ if (!m_p25->m_control)
+ return;
+
+ // for now this is ignored...
+}
+
///
/// Helper to write a network single-block P25 TSDU packet.
///
diff --git a/p25/dfsi/packet/DFSITrunk.h b/p25/dfsi/packet/DFSITrunk.h
index 11d3031d..195ebb83 100644
--- a/p25/dfsi/packet/DFSITrunk.h
+++ b/p25/dfsi/packet/DFSITrunk.h
@@ -74,6 +74,8 @@ namespace p25
/// Helper to write a single-block P25 TSDU packet.
virtual void writeRF_TSDU_SBF(bool noNetwork, bool clearBeforeWrite = false, bool force = false);
+ /// Helper to write a alternate multi-block trunking PDU packet.
+ virtual void writeRF_TSDU_AMBT(bool clearBeforeWrite = false);
/// Helper to write a network P25 TDU w/ link control packet.
//virtual void writeNet_TDULC(lc::TDULC lc);
diff --git a/p25/packet/Data.cpp b/p25/packet/Data.cpp
index 666007ca..ddbf5075 100644
--- a/p25/packet/Data.cpp
+++ b/p25/packet/Data.cpp
@@ -505,6 +505,52 @@ bool Data::hasLLIdFNEReg(uint32_t llId) const
}
}
+///
+/// Helper to write user data as a P25 PDU packet.
+///
+///
+///
+///
+void Data::writeRF_PDU_User(data::DataHeader dataHeader, const uint8_t* pduUserData, bool clearBeforeWrite)
+{
+ assert(pduUserData != NULL);
+
+ uint32_t bitLength = ((dataHeader.getBlocksToFollow() + 1U) * P25_PDU_FEC_LENGTH_BITS) + P25_PREAMBLE_LENGTH_BITS;
+ uint32_t offset = P25_PREAMBLE_LENGTH_BITS;
+
+ uint8_t data[bitLength / 8U];
+ ::memset(data, 0x00U, bitLength / 8U);
+ uint8_t block[P25_PDU_FEC_LENGTH_BYTES];
+ ::memset(block, 0x00U, P25_PDU_FEC_LENGTH_BYTES);
+
+ // Generate the PDU header and 1/2 rate Trellis
+ dataHeader.encode(block);
+ Utils::setBitRange(block, data, offset, P25_PDU_FEC_LENGTH_BITS);
+ offset += P25_PDU_FEC_LENGTH_BITS;
+
+ // Generate the PDU data
+ DataBlock rspBlock = DataBlock();
+ uint32_t dataOffset = 0U;
+ for (uint8_t i = 0; i < dataHeader.getBlocksToFollow(); i++) {
+ rspBlock.setFormat(PDU_FMT_UNCONFIRMED);
+ rspBlock.setSerialNo(0U);
+ rspBlock.setData(pduUserData + dataOffset);
+
+ ::memset(block, 0x00U, P25_PDU_FEC_LENGTH_BYTES);
+ rspBlock.encode(block);
+ Utils::setBitRange(block, data, offset, P25_PDU_FEC_LENGTH_BITS);
+ offset += P25_PDU_FEC_LENGTH_BITS;
+ dataOffset += P25_PDU_UNCONFIRMED_LENGTH_BYTES;
+ }
+
+ if (clearBeforeWrite) {
+ m_p25->m_modem->clearP25Data();
+ m_p25->m_queue.clear();
+ }
+
+ writeRF_PDU(data, bitLength);
+}
+
///
/// Updates the processor by the passed number of milliseconds.
///
diff --git a/p25/packet/Data.h b/p25/packet/Data.h
index d959b595..4bdfeeb6 100644
--- a/p25/packet/Data.h
+++ b/p25/packet/Data.h
@@ -73,13 +73,15 @@ namespace p25
/// Helper to check if a logical link ID has registered with data services.
bool hasLLIdFNEReg(uint32_t llId) const;
+ /// Helper to write user data as a P25 PDU packet.
+ void writeRF_PDU_User(data::DataHeader dataHeader, const uint8_t* pduUserData, bool clearBeforeWrite = false);
+
/// Updates the processor by the passed number of milliseconds.
void clock(uint32_t ms);
private:
friend class p25::Control;
Control* m_p25;
- friend class p25::packet::Trunk;
network::BaseNetwork* m_network;
diff --git a/p25/packet/Trunk.cpp b/p25/packet/Trunk.cpp
index 546ab374..9ca8c35c 100644
--- a/p25/packet/Trunk.cpp
+++ b/p25/packet/Trunk.cpp
@@ -1670,61 +1670,32 @@ void Trunk::writeRF_TSDU_MBF(bool clearBeforeWrite)
/// Helper to write a alternate multi-block trunking PDU packet.
///
///
-void Trunk::writeRF_PDU_AMBT(bool clearBeforeWrite)
+void Trunk::writeRF_TSDU_AMBT(bool clearBeforeWrite)
{
if (!m_p25->m_control)
return;
- DataHeader rspHeader = DataHeader();
- uint8_t rspData[P25_PDU_UNCONFIRMED_LENGTH_BYTES * P25_MAX_PDU_COUNT];
- ::memset(rspData, 0x00U, P25_PDU_UNCONFIRMED_LENGTH_BYTES * P25_MAX_PDU_COUNT);
+ DataHeader header = DataHeader();
+ uint8_t pduUserData[P25_PDU_UNCONFIRMED_LENGTH_BYTES * P25_MAX_PDU_COUNT];
+ ::memset(pduUserData, 0x00U, P25_PDU_UNCONFIRMED_LENGTH_BYTES * P25_MAX_PDU_COUNT);
// Generate TSBK block
m_rfTSBK.setLastBlock(true); // always set last block -- this a Single Block TSDU
- m_rfTSBK.encodeMBT(rspHeader, rspData);
+ m_rfTSBK.encodeMBT(header, pduUserData);
if (m_debug) {
+ LogDebug(LOG_RF, P25_PDU_STR ", ack = %u, outbound = %u, fmt = $%02X, sap = $%02X, fullMessage = %u, blocksToFollow = %u, padCount = %u, n = %u, seqNo = %u, hdrOffset = %u",
+ header.getAckNeeded(), header.getOutbound(), header.getFormat(), header.getSAP(), header.getFullMessage(),
+ header.getBlocksToFollow(), header.getPadCount(), header.getNs(), header.getFSN(),
+ header.getHeaderOffset());
LogDebug(LOG_RF, P25_PDU_STR " AMBT, lco = $%02X, mfId = $%02X, lastBlock = %u, AIV = %u, EX = %u, srcId = %u, dstId = %u, sysId = $%03X, netId = $%05X",
m_rfTSBK.getLCO(), m_rfTSBK.getMFId(), m_rfTSBK.getLastBlock(), m_rfTSBK.getAIV(), m_rfTSBK.getEX(), m_rfTSBK.getSrcId(), m_rfTSBK.getDstId(),
m_rfTSBK.getSysId(), m_rfTSBK.getNetId());
- Utils::dump(1U, "!!! *TSDU (AMBT) TSBK Block Data", rspData, P25_PDU_UNCONFIRMED_LENGTH_BYTES * rspHeader.getBlocksToFollow());
+ Utils::dump(1U, "!!! *PDU (AMBT) TSBK Block Data", pduUserData, P25_PDU_UNCONFIRMED_LENGTH_BYTES * header.getBlocksToFollow());
}
- uint32_t bitLength = ((rspHeader.getBlocksToFollow() + 1U) * P25_PDU_FEC_LENGTH_BITS) + P25_PREAMBLE_LENGTH_BITS;
- uint32_t offset = P25_PREAMBLE_LENGTH_BITS;
-
- uint8_t data[bitLength / 8U];
- ::memset(data, 0x00U, bitLength / 8U);
- uint8_t block[P25_PDU_FEC_LENGTH_BYTES];
- ::memset(block, 0x00U, P25_PDU_FEC_LENGTH_BYTES);
-
- // Generate the PDU header and 1/2 rate Trellis
- rspHeader.encode(block);
- Utils::setBitRange(block, data, offset, P25_PDU_FEC_LENGTH_BITS);
- offset += P25_PDU_FEC_LENGTH_BITS;
-
- // Generate the PDU data
- DataBlock rspBlock = DataBlock();
- uint32_t dataOffset = 0U;
- for (uint8_t i = 0; i < rspHeader.getBlocksToFollow(); i++) {
- rspBlock.setFormat(PDU_FMT_UNCONFIRMED);
- rspBlock.setSerialNo(0U);
- rspBlock.setData(rspData + dataOffset);
-
- ::memset(block, 0x00U, P25_PDU_FEC_LENGTH_BYTES);
- rspBlock.encode(block);
- Utils::setBitRange(block, data, offset, P25_PDU_FEC_LENGTH_BITS);
- offset += P25_PDU_FEC_LENGTH_BITS;
- dataOffset += P25_PDU_UNCONFIRMED_LENGTH_BYTES;
- }
-
- if (clearBeforeWrite) {
- m_p25->m_modem->clearP25Data();
- m_p25->m_queue.clear();
- }
-
- m_p25->m_data->writeRF_PDU(data, bitLength);
+ m_p25->m_data->writeRF_PDU_User(header, pduUserData, clearBeforeWrite);
}
///
diff --git a/p25/packet/Trunk.h b/p25/packet/Trunk.h
index 31498fe3..bb12fea3 100644
--- a/p25/packet/Trunk.h
+++ b/p25/packet/Trunk.h
@@ -83,6 +83,7 @@ namespace p25
/// Helper to set the TSBK manufacturer ID.
void setMFId(uint8_t val) { m_rfTSBK.setMFId(val); }
+
/// Helper to write a call alert packet.
void writeRF_TSDU_Call_Alrt(uint32_t srcId, uint32_t dstId);
/// Helper to write a call alert packet.
@@ -179,7 +180,7 @@ namespace p25
/// Helper to write a multi-block (3-block) P25 TSDU packet.
void writeRF_TSDU_MBF(bool clearBeforeWrite = false);
/// Helper to write a alternate multi-block trunking PDU packet.
- void writeRF_PDU_AMBT(bool clearBeforeWrite = false);
+ virtual void writeRF_TSDU_AMBT(bool clearBeforeWrite = false);
/// Helper to generate the given control TSBK into the TSDU frame queue.
void queueRF_TSBK_Ctrl(uint8_t lco);