implement logic to encode and transmit AMBTs;

2.0-maint
Bryan Biedenkapp 3 years ago
parent 86316d2f05
commit e005a2af20

@ -334,13 +334,10 @@ bool TSBK::decodeMBT(const data::DataHeader dataHeader, const data::DataBlock* b
/// Encode a alternate trunking signalling block. /// Encode a alternate trunking signalling block.
/// </summary> /// </summary>
/// <param name="dataHeader"></param> /// <param name="dataHeader"></param>
/// <param name="blocks"></param> /// <param name="pduUserData"></param>
void TSBK::encodeMBT(data::DataHeader& dataHeader, data::DataBlock* blocks) void TSBK::encodeMBT(data::DataHeader& dataHeader, uint8_t* pduUserData)
{ {
assert(blocks != NULL); assert(pduUserData != NULL);
uint8_t pduUserData[P25_PDU_UNCONFIRMED_LENGTH_BYTES * 2U];
::memset(pduUserData, 0x00U, P25_PDU_UNCONFIRMED_LENGTH_BYTES * 2U);
dataHeader.setFormat(PDU_FMT_UNCONFIRMED); dataHeader.setFormat(PDU_FMT_UNCONFIRMED);
dataHeader.setMFId(m_mfId); dataHeader.setMFId(m_mfId);
@ -394,15 +391,8 @@ void TSBK::encodeMBT(data::DataHeader& dataHeader, data::DataBlock* blocks)
// generate packet CRC-32 and set data blocks // generate packet CRC-32 and set data blocks
if (dataHeader.getBlocksToFollow() > 1U) { if (dataHeader.getBlocksToFollow() > 1U) {
edac::CRC::addCRC32(pduUserData, P25_PDU_UNCONFIRMED_LENGTH_BYTES * dataHeader.getBlocksToFollow()); edac::CRC::addCRC32(pduUserData, P25_PDU_UNCONFIRMED_LENGTH_BYTES * dataHeader.getBlocksToFollow());
uint8_t offs = 0U;
for (uint8_t i = 0; i < dataHeader.getBlocksToFollow(); i++) {
blocks[i].setData(pduUserData + offs);
offs += P25_PDU_UNCONFIRMED_LENGTH_BYTES;
}
} else { } else {
edac::CRC::addCRC32(pduUserData, P25_PDU_UNCONFIRMED_LENGTH_BYTES); edac::CRC::addCRC32(pduUserData, P25_PDU_UNCONFIRMED_LENGTH_BYTES);
blocks[0U].setData(pduUserData);
} }
} }

@ -84,7 +84,7 @@ namespace p25
/// <summary>Decode a alternate trunking signalling block.</summary> /// <summary>Decode a alternate trunking signalling block.</summary>
bool decodeMBT(const data::DataHeader dataHeader, const data::DataBlock* blocks); bool decodeMBT(const data::DataHeader dataHeader, const data::DataBlock* blocks);
/// <summary>Encode a alternate trunking signalling block.</summary> /// <summary>Encode a alternate trunking signalling block.</summary>
void encodeMBT(data::DataHeader& dataHeader, data::DataBlock* blocks); void encodeMBT(data::DataHeader& dataHeader, uint8_t* pduUserData);
/// <summary>Decode a trunking signalling block.</summary> /// <summary>Decode a trunking signalling block.</summary>
bool decode(const uint8_t* data, bool rawTSBK = false); bool decode(const uint8_t* data, bool rawTSBK = false);

@ -51,6 +51,7 @@ namespace p25
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
class HOST_SW_API Control; class HOST_SW_API Control;
namespace packet { class HOST_SW_API Trunk; }
namespace packet namespace packet
{ {
@ -78,6 +79,7 @@ namespace p25
private: private:
friend class p25::Control; friend class p25::Control;
Control* m_p25; Control* m_p25;
friend class p25::packet::Trunk;
network::BaseNetwork* m_network; network::BaseNetwork* m_network;

@ -1666,6 +1666,67 @@ void Trunk::writeRF_TSDU_MBF(bool clearBeforeWrite)
m_mbfCnt++; m_mbfCnt++;
} }
/// <summary>
/// Helper to write a alternate multi-block trunking PDU packet.
/// </summary>
/// <param name="clearBeforeWrite"></param>
void Trunk::writeRF_PDU_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);
// Generate TSBK block
m_rfTSBK.setLastBlock(true); // always set last block -- this a Single Block TSDU
m_rfTSBK.encodeMBT(rspHeader, rspData);
if (m_debug) {
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());
}
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();
uint8_t offs = 0U;
for (uint8_t i = 0; i < rspHeader.getBlocksToFollow(); i++) {
rspBlock.setFormat(PDU_FMT_UNCONFIRMED);
rspBlock.setSerialNo(0U);
rspBlock.setData(rspData + offs);
::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;
offs += 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);
}
/// <summary> /// <summary>
/// Helper to generate the given control TSBK into the TSDU frame queue. /// Helper to generate the given control TSBK into the TSDU frame queue.
/// </summary> /// </summary>

@ -178,6 +178,8 @@ namespace p25
virtual void writeRF_TSDU_SBF(bool noNetwork, bool clearBeforeWrite = false, bool force = false); virtual void writeRF_TSDU_SBF(bool noNetwork, bool clearBeforeWrite = false, bool force = false);
/// <summary>Helper to write a multi-block (3-block) P25 TSDU packet.</summary> /// <summary>Helper to write a multi-block (3-block) P25 TSDU packet.</summary>
void writeRF_TSDU_MBF(bool clearBeforeWrite = false); void writeRF_TSDU_MBF(bool clearBeforeWrite = false);
/// <summary>Helper to write a alternate multi-block trunking PDU packet.</summary>
void writeRF_PDU_AMBT(bool clearBeforeWrite = false);
/// <summary>Helper to generate the given control TSBK into the TSDU frame queue.</summary> /// <summary>Helper to generate the given control TSBK into the TSDU frame queue.</summary>
void queueRF_TSBK_Ctrl(uint8_t lco); void queueRF_TSBK_Ctrl(uint8_t lco);

Loading…
Cancel
Save

Powered by TurnKey Linux.