refactor status bit handling slightly;

pull/79/head
Bryan Biedenkapp 1 year ago
parent 1528894099
commit 1b4ea4d8c7

@ -31,13 +31,37 @@ void P25Utils::setStatusBits(uint8_t* data, uint32_t ssOffset, bool b1, bool b2)
WRITE_BIT(data, ssOffset + 1U, b2);
}
/* Helper to set the starting status bits on P25 frame data to 1,1 for idle. */
void P25Utils::setStatusBitsStartIdle(uint8_t* data)
{
assert(data != nullptr);
// set "1,1" (Start of Inbound Slot/Idle) status bits [TIA-102.BAAA]
P25Utils::setStatusBits(data, P25_SS0_START, true, true);
}
/* Helper to set all status bits on a P25 frame data to 1,1 for idle. */
void P25Utils::setStatusBitsAllIdle(uint8_t* data, uint32_t length)
{
assert(data != nullptr);
// set "1,1" (Idle) status bits [TIA-102.BAAA]
for (uint32_t ss0Pos = P25_SS0_START; ss0Pos < length; ss0Pos += P25_SS_INCREMENT) {
uint32_t ss1Pos = ss0Pos + 1U;
WRITE_BIT(data, ss0Pos, true); // 1
WRITE_BIT(data, ss1Pos, true); // 1
}
}
/* Helper to add the status bits on P25 frame data. */
void P25Utils::addStatusBits(uint8_t* data, uint32_t length, bool inbound, bool control)
void P25Utils::addStatusBits(uint8_t* data, uint32_t length, bool busy, bool unknown)
{
assert(data != nullptr);
// insert the "10" (Unknown, use for inbound or outbound) status bits
// set "1,0" (Unknown) status bits [TIA-102.BAAA]
for (uint32_t ss0Pos = P25_SS0_START; ss0Pos < length; ss0Pos += P25_SS_INCREMENT) {
uint32_t ss1Pos = ss0Pos + 1U;
WRITE_BIT(data, ss0Pos, true); // 1
@ -47,14 +71,17 @@ void P25Utils::addStatusBits(uint8_t* data, uint32_t length, bool inbound, bool
// interleave the requested status bits (every other)
for (uint32_t ss0Pos = P25_SS0_START; ss0Pos < length; ss0Pos += (P25_SS_INCREMENT * 2U)) {
uint32_t ss1Pos = ss0Pos + 1U;
if (inbound) {
if (busy) {
// set "0,1" (Busy) status bits [TIA-102.BAAA]
WRITE_BIT(data, ss0Pos, false); // 0
WRITE_BIT(data, ss1Pos, true); // 1
} else {
if (control) {
if (unknown) {
// set "1,0" (Unknown) status bits [TIA-102.BAAA]
WRITE_BIT(data, ss0Pos, true); // 1
WRITE_BIT(data, ss1Pos, false); // 0
} else {
// set "1,1" (Start of Inbound Slot/Idle) status bits [TIA-102.BAAA]
WRITE_BIT(data, ss0Pos, true); // 1
WRITE_BIT(data, ss1Pos, true); // 1
}
@ -62,27 +89,35 @@ void P25Utils::addStatusBits(uint8_t* data, uint32_t length, bool inbound, bool
}
}
/* Helper to add the idle status bits on P25 frame data. */
/* Helper to add the unknown (1,0) status bits on P25 frame data. */
void P25Utils::addIdleStatusBits(uint8_t* data, uint32_t length)
void P25Utils::addUnknownStatusBits(uint8_t* data, uint32_t length, uint8_t interval)
{
assert(data != nullptr);
for (uint32_t ss0Pos = P25_SS0_START; ss0Pos < length; ss0Pos += (P25_SS_INCREMENT * 5U)) {
if (interval == 0U)
interval = 1U;
for (uint32_t ss0Pos = P25_SS0_START; ss0Pos < length; ss0Pos += (P25_SS_INCREMENT * interval)) {
uint32_t ss1Pos = ss0Pos + 1U;
// set "1,0" (Unknown) status bits [TIA-102.BAAA]
WRITE_BIT(data, ss0Pos, true); // 1
WRITE_BIT(data, ss1Pos, false); // 0
}
}
/* Helper to add the trunk start slot status bits on P25 frame data. */
/* Helper to add the idle (1,1) status bits on P25 frame data. */
void P25Utils::addTrunkSlotStatusBits(uint8_t* data, uint32_t length)
void P25Utils::addIdleStatusBits(uint8_t* data, uint32_t length, uint8_t interval)
{
assert(data != nullptr);
for (uint32_t ss0Pos = P25_SS0_START; ss0Pos < length; ss0Pos += (P25_SS_INCREMENT * 5U)) {
if (interval == 0U)
interval = 1U;
for (uint32_t ss0Pos = P25_SS0_START; ss0Pos < length; ss0Pos += (P25_SS_INCREMENT * interval)) {
uint32_t ss1Pos = ss0Pos + 1U;
// set "1,1" (Start of Inbound Slot/Idle) status bits [TIA-102.BAAA]
WRITE_BIT(data, ss0Pos, true); // 1
WRITE_BIT(data, ss1Pos, true); // 1
}

@ -120,35 +120,48 @@ namespace p25
/**
* @brief Helper to set the status bits on P25 frame data.
* @param data P25 frame data buffer.
* @param ssOffset
* @param ssOffset Status symbol offset (bit offset).
* @param b1 Status Bit 1
* @param b2 Status Bit 2
*/
static void setStatusBits(uint8_t* data, uint32_t ssOffset, bool b1, bool b2);
/**
* @brief Helper to set the starting status bits on P25 frame data to 1,1 for idle.
* @param data P25 frame data buffer.
*/
static void setStatusBitsStartIdle(uint8_t* data);
/**
* @brief Helper to set all status bits on a P25 frame data to 1,1 for idle.
* @param data P25 frame data buffer.
* @param length Lenght of P25 frame in bits.
*/
static void setStatusBitsAllIdle(uint8_t* data, uint32_t length);
/**
* @brief Helper to add the status bits on P25 frame data.
* This appropriately sets the status bits for the P25 frame, starting with 1,0 and then
* properly setting 0,1 for inbound traffic, or 1,1 for idle (or 1,0 for control channels).
* properly setting 0,1 for inbound traffic, or 1,1 for idle (or 1,0 for unknown).
* @param data P25 frame data buffer.
* @param length
* @param inbound Flag indicating inbound channel is busy.
* @param control Flag indicating the channel is a control channel.
* @param length Lenght of P25 frame in bits.
* @param busy Flag indicating inbound channel is busy.
* @param unknown Flag indicating unknown slot state.
*/
static void addStatusBits(uint8_t *data, uint32_t length, bool inbound, bool control = false);
static void addStatusBits(uint8_t *data, uint32_t length, bool busy, bool unknown);
/**
* @brief Helper to add the idle status bits on P25 frame data.
* This sets the status bits to 1,0 interleaved every 5th status bit pair.
* @brief Helper to add the unknown (1,0) status bits on P25 frame data.
* This sets the status bits to 1,0 interleaved every variable status bit pair.
* @param data P25 frame data buffer.
* @param length
* @param length Lenght of P25 frame in bits.
* @param interval Status bit pair interval.
*/
static void addIdleStatusBits(uint8_t* data, uint32_t length);
static void addUnknownStatusBits(uint8_t* data, uint32_t length, uint8_t interval = 5U);
/**
* @brief Helper to add the trunk start slot status bits on P25 frame data.
* This sets the status bits to 1,1 interleaved every 5th status bit pair.
* @brief Helper to add the idle (1,1) status bits on P25 frame data.
* This sets the status bits to 1,1 interleaved every variable status bit pair.
* @param data P25 frame data buffer.
* @param length
* @param length Lenght of P25 frame in bits.
* @param interval Status bit pair interval.
*/
static void addTrunkSlotStatusBits(uint8_t* data, uint32_t length);
static void addIdleStatusBits(uint8_t* data, uint32_t length, uint8_t interval = 5U);
/**
* @brief Decode bit interleaving.

@ -1247,20 +1247,18 @@ void TagP25Data::write_TSDU(uint32_t peerId, lc::TSBK* tsbk)
uint8_t data[P25_TSDU_FRAME_LENGTH_BYTES];
::memset(data, 0x00U, P25_TSDU_FRAME_LENGTH_BYTES);
// Generate Sync
// generate Sync
Sync::addP25Sync(data);
// network bursts have no NID
// Generate TSBK block
// generate TSBK block
tsbk->setLastBlock(true); // always set last block -- this a Single Block TSDU
tsbk->encode(data);
// Add busy bits
P25Utils::addStatusBits(data, P25_TSDU_FRAME_LENGTH_BYTES, false);
// Set first busy bits to 1,1
P25Utils::setStatusBits(data, P25_SS0_START, true, true);
// add status bits
P25Utils::addStatusBits(data, P25_TSDU_FRAME_LENGTH_BYTES, false, true);
P25Utils::setStatusBitsStartIdle(data);
if (m_debug) {
LogDebug(LOG_RF, P25_TSDU_STR ", lco = $%02X, mfId = $%02X, lastBlock = %u, AIV = %u, EX = %u, srcId = %u, dstId = %u, sysId = $%03X, netId = $%05X",

@ -542,14 +542,14 @@ void ModemV24::create_TDU(uint8_t* buffer)
uint8_t data[P25_TDU_FRAME_LENGTH_BYTES + 2U];
::memset(data + 2U, 0x00U, P25_TDU_FRAME_LENGTH_BYTES);
// Generate Sync
// generate Sync
Sync::addP25Sync(data + 2U);
// Generate NID
// generate NID
m_nid->encode(data + 2U, DUID::TDU);
// Add busy bits
P25Utils::addStatusBits(data + 2U, P25_TDU_FRAME_LENGTH_BITS, false);
// add status bits
P25Utils::addStatusBits(data + 2U, P25_TDU_FRAME_LENGTH_BITS, false, false);
buffer[0U] = modem::TAG_EOT;
buffer[1U] = 0x01U;
@ -672,17 +672,17 @@ void ModemV24::convertToAir(const uint8_t *data, uint32_t length)
lc.setKId(m_rxCall->kId);
lc.setMI(m_rxCall->MI);
// Generate Sync
// generate Sync
Sync::addP25Sync(buffer + 2U);
// Generate NID
// generate NID
m_nid->encode(buffer + 2U, DUID::HDU);
// Generate HDU
// generate HDU
lc.encodeHDU(buffer + 2U);
// Add busy bits
P25Utils::addStatusBits(buffer + 2U, P25_HDU_FRAME_LENGTH_BITS, true);
// add status bits
P25Utils::addStatusBits(buffer + 2U, P25_HDU_FRAME_LENGTH_BITS, true, false);
buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x01U;
@ -753,24 +753,22 @@ void ModemV24::convertToAir(const uint8_t *data, uint32_t length)
uint8_t buffer[P25_PDU_FRAME_LENGTH_BYTES + 2U];
::memset(buffer, 0x00U, P25_PDU_FRAME_LENGTH_BYTES + 2U);
// Add the data
// add the data
uint32_t newBitLength = P25Utils::encode(data, buffer + 2U, bitLength);
uint32_t newByteLength = newBitLength / 8U;
if ((newBitLength % 8U) > 0U)
newByteLength++;
// Regenerate Sync
// regenerate Sync
Sync::addP25Sync(buffer + 2U);
// Regenerate NID
// regenerate NID
m_nid->encode(buffer + 2U, DUID::PDU);
// Add status bits
P25Utils::addStatusBits(buffer + 2U, newBitLength, false);
// add status bits
P25Utils::addStatusBits(buffer + 2U, newBitLength, false, false);
P25Utils::addIdleStatusBits(buffer + 2U, newBitLength);
// Set first busy bits to 1,1
P25Utils::setStatusBits(buffer + 2U, P25_SS0_START, true, true);
P25Utils::setStatusBitsStartIdle(buffer + 2U);
storeConvertedRx(buffer, P25_PDU_FRAME_LENGTH_BYTES + 2U);
}
@ -790,22 +788,20 @@ void ModemV24::convertToAir(const uint8_t *data, uint32_t length)
buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x00U;
// Generate Sync
// generate Sync
Sync::addP25Sync(buffer + 2U);
// Generate NID
// generate NID
m_nid->encode(buffer + 2U, DUID::TSDU);
// Regenerate TSDU Data
// regenerate TSDU Data
tsbk.setLastBlock(true); // always set last block -- this a Single Block TSDU
tsbk.encode(buffer + 2U);
// Add busy bits
// add status bits
P25Utils::addStatusBits(buffer + 2U, P25_TSDU_FRAME_LENGTH_BYTES, false, true);
P25Utils::addTrunkSlotStatusBits(buffer + 2U, P25_TSDU_FRAME_LENGTH_BYTES);
// Set first busy bits to 1,1
P25Utils::setStatusBits(buffer + 2U, P25_SS0_START, true, true);
P25Utils::addIdleStatusBits(buffer + 2U, P25_TSDU_FRAME_LENGTH_BYTES);
P25Utils::setStatusBitsStartIdle(buffer + 2U);
storeConvertedRx(buffer, P25_TSDU_FRAME_LENGTH_BYTES + 2U);
}
@ -1028,8 +1024,8 @@ void ModemV24::convertToAir(const uint8_t *data, uint32_t length)
m_audio.encode(buffer + 2U, m_rxCall->netLDU1 + 180U, 7U);
m_audio.encode(buffer + 2U, m_rxCall->netLDU1 + 204U, 8U);
// add busy bits
P25Utils::addStatusBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, true);
// add status bits
P25Utils::addStatusBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, true, false);
buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x01U;
@ -1070,8 +1066,8 @@ void ModemV24::convertToAir(const uint8_t *data, uint32_t length)
m_audio.encode(buffer + 2U, m_rxCall->netLDU2 + 180U, 7U);
m_audio.encode(buffer + 2U, m_rxCall->netLDU2 + 204U, 8U);
// add busy bits
P25Utils::addStatusBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, true);
// add status bits
P25Utils::addStatusBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, true, false);
buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x01U;

@ -1725,14 +1725,14 @@ void Control::writeRF_TDU(bool noNetwork, bool imm)
uint8_t data[P25_TDU_FRAME_LENGTH_BYTES + 2U];
::memset(data + 2U, 0x00U, P25_TDU_FRAME_LENGTH_BYTES);
// Generate Sync
// generate Sync
Sync::addP25Sync(data + 2U);
// Generate NID
// generate NID
m_nid.encode(data + 2U, DUID::TDU);
// Add busy bits
P25Utils::addStatusBits(data + 2U, P25_TDU_FRAME_LENGTH_BITS, false);
// add status bits
P25Utils::setStatusBitsAllIdle(data + 2U, P25_TDU_FRAME_LENGTH_BITS);
if (!noNetwork)
m_voice->writeNetwork(data + 2U, DUID::TDU);

@ -1357,17 +1357,17 @@ void ControlSignaling::writeRF_TDULC(lc::TDULC* lc, bool noNetwork)
uint8_t data[P25_TDULC_FRAME_LENGTH_BYTES + 2U];
::memset(data + 2U, 0x00U, P25_TDULC_FRAME_LENGTH_BYTES);
// Generate Sync
// generate Sync
Sync::addP25Sync(data + 2U);
// Generate NID
// generate NID
m_p25->m_nid.encode(data + 2U, DUID::TDULC);
// Generate TDULC Data
// generate TDULC Data
lc->encode(data + 2U);
// Add busy bits
P25Utils::addStatusBits(data + 2U, P25_TDULC_FRAME_LENGTH_BITS, false);
// add status bits
P25Utils::addStatusBits(data + 2U, P25_TDULC_FRAME_LENGTH_BITS, false, false);
m_p25->m_rfTimeout.stop();
@ -1396,17 +1396,17 @@ void ControlSignaling::writeNet_TDULC(lc::TDULC* lc)
buffer[0U] = modem::TAG_EOT;
buffer[1U] = 0x00U;
// Generate Sync
// generate Sync
Sync::addP25Sync(buffer + 2U);
// Generate NID
// generate NID
m_p25->m_nid.encode(buffer + 2U, DUID::TDULC);
// Regenerate TDULC Data
// regenerate TDULC Data
lc->encode(buffer + 2U);
// Add busy bits
P25Utils::addStatusBits(buffer + 2U, P25_TDULC_FRAME_LENGTH_BITS, false);
// add status bits
P25Utils::addStatusBits(buffer + 2U, P25_TDULC_FRAME_LENGTH_BITS, false, false);
m_p25->addFrame(buffer, P25_TDULC_FRAME_LENGTH_BYTES + 2U, true);
@ -1443,13 +1443,13 @@ void ControlSignaling::writeRF_TSDU_SBF(lc::TSBK* tsbk, bool noNetwork, bool for
uint8_t data[P25_TSDU_FRAME_LENGTH_BYTES + 2U];
::memset(data + 2U, 0x00U, P25_TSDU_FRAME_LENGTH_BYTES);
// Generate Sync
// generate Sync
Sync::addP25Sync(data + 2U);
// Generate NID
// generate NID
m_p25->m_nid.encode(data + 2U, DUID::TSDU);
// Generate TSBK block
// generate TSBK block
tsbk->setLastBlock(true); // always set last block -- this a Single Block TSDU
tsbk->encode(data + 2U);
@ -1461,12 +1461,10 @@ void ControlSignaling::writeRF_TSDU_SBF(lc::TSBK* tsbk, bool noNetwork, bool for
Utils::dump(1U, "!!! *TSDU (SBF) TSBK Block Data", data + P25_PREAMBLE_LENGTH_BYTES + 2U, P25_TSBK_FEC_LENGTH_BYTES);
}
// Add busy bits
// add status bits
P25Utils::addStatusBits(data + 2U, P25_TSDU_FRAME_LENGTH_BITS, m_inbound, true);
P25Utils::addTrunkSlotStatusBits(data + 2U, P25_TSDU_FRAME_LENGTH_BITS);
// Set first busy bits to 1,1
P25Utils::setStatusBits(data + 2U, P25_SS0_START, true, true);
P25Utils::addIdleStatusBits(data + 2U, P25_TSDU_FRAME_LENGTH_BITS);
P25Utils::setStatusBitsStartIdle(data + 2U);
if (!noNetwork)
writeNetworkRF(tsbk, data + 2U, true);
@ -1513,22 +1511,20 @@ void ControlSignaling::writeNet_TSDU(lc::TSBK* tsbk)
buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x00U;
// Generate Sync
// generate Sync
Sync::addP25Sync(buffer + 2U);
// Generate NID
// generate NID
m_p25->m_nid.encode(buffer + 2U, DUID::TSDU);
// Regenerate TSDU Data
// regenerate TSDU Data
tsbk->setLastBlock(true); // always set last block -- this a Single Block TSDU
tsbk->encode(buffer + 2U);
// Add busy bits
// add status bits
P25Utils::addStatusBits(buffer + 2U, P25_TSDU_FRAME_LENGTH_BYTES, false, true);
P25Utils::addTrunkSlotStatusBits(buffer + 2U, P25_TSDU_FRAME_LENGTH_BYTES);
// Set first busy bits to 1,1
P25Utils::setStatusBits(buffer + 2U, P25_SS0_START, true, true);
P25Utils::addIdleStatusBits(buffer + 2U, P25_TSDU_FRAME_LENGTH_BYTES);
P25Utils::setStatusBitsStartIdle(buffer + 2U);
m_p25->addFrame(buffer, P25_TSDU_FRAME_LENGTH_BYTES + 2U, true);
@ -1566,7 +1562,7 @@ void ControlSignaling::writeRF_TSDU_MBF(lc::TSBK* tsbk)
// trigger encoding of last block and write to queue
if (m_mbfCnt + 1U == TSBK_MBF_CNT) {
// Generate TSBK block
// generate TSBK block
tsbk->setLastBlock(true); // set last block
tsbk->encode(frame, true);
@ -1580,7 +1576,7 @@ void ControlSignaling::writeRF_TSDU_MBF(lc::TSBK* tsbk)
Utils::setBitRange(frame, m_rfMBF, (m_mbfCnt * P25_TSBK_FEC_LENGTH_BITS), P25_TSBK_FEC_LENGTH_BITS);
// Generate TSDU frame
// generate TSDU frame
uint8_t tsdu[P25_TSDU_TRIPLE_FRAME_LENGTH_BYTES];
::memset(tsdu, 0x00U, P25_TSDU_TRIPLE_FRAME_LENGTH_BYTES);
@ -1597,7 +1593,7 @@ void ControlSignaling::writeRF_TSDU_MBF(lc::TSBK* tsbk)
Utils::dump(1U, "!!! *TSDU (MBF) TSBK Block", frame, P25_TSBK_FEC_LENGTH_BYTES);
}
// Add TSBK data
// add TSBK data
Utils::setBitRange(frame, tsdu, offset, P25_TSBK_FEC_LENGTH_BITS);
offset += P25_TSBK_FEC_LENGTH_BITS;
@ -1608,18 +1604,18 @@ void ControlSignaling::writeRF_TSDU_MBF(lc::TSBK* tsbk)
uint8_t data[P25_TSDU_TRIPLE_FRAME_LENGTH_BYTES + 2U];
::memset(data + 2U, 0x00U, P25_TSDU_TRIPLE_FRAME_LENGTH_BYTES);
// Generate Sync
// generate Sync
Sync::addP25Sync(data + 2U);
// Generate NID
// generate NID
m_p25->m_nid.encode(data + 2U, DUID::TSDU);
// interleave
P25Utils::encode(tsdu, data + 2U, 114U, 720U);
// Add busy bits
// add busy bits
P25Utils::addStatusBits(data + 2U, P25_TSDU_TRIPLE_FRAME_LENGTH_BITS, m_inbound, true);
P25Utils::addTrunkSlotStatusBits(data + 2U, P25_TSDU_TRIPLE_FRAME_LENGTH_BITS);
P25Utils::addIdleStatusBits(data + 2U, P25_TSDU_TRIPLE_FRAME_LENGTH_BITS);
data[0U] = modem::TAG_DATA;
data[1U] = 0x00U;
@ -1631,7 +1627,7 @@ void ControlSignaling::writeRF_TSDU_MBF(lc::TSBK* tsbk)
return;
}
// Generate TSBK block
// generate TSBK block
tsbk->setLastBlock(false); // clear last block
tsbk->encode(frame, true);
@ -2938,21 +2934,19 @@ void ControlSignaling::writeNet_TSDU_From_RF(lc::TSBK* tsbk, uint8_t* data)
::memset(data, 0x00U, P25_TSDU_FRAME_LENGTH_BYTES);
// Generate Sync
// generate Sync
Sync::addP25Sync(data);
// Generate NID
// generate NID
m_p25->m_nid.encode(data, DUID::TSDU);
// Regenerate TSDU Data
// regenerate TSDU Data
tsbk->setLastBlock(true); // always set last block -- this a Single Block TSDU
tsbk->encode(data);
// Add busy bits
P25Utils::addStatusBits(data, P25_TSDU_FRAME_LENGTH_BYTES, false);
// Set first busy bits to 1,1
P25Utils::setStatusBits(data, P25_SS0_START, true, true);
// add status bits
P25Utils::addStatusBits(data, P25_TSDU_FRAME_LENGTH_BYTES, false, false);
P25Utils::setStatusBitsStartIdle(data);
}
/* Helper to automatically inhibit a source ID on a denial. */

@ -368,7 +368,7 @@ bool Data::process(uint8_t* data, uint32_t len)
if (m_retryPDUData != nullptr && m_retryPDUBitLength > 0U) {
if (m_retryCount < MAX_PDU_RETRY_CNT) {
m_p25->writeRF_Preamble();
writeRF_PDU(m_retryPDUData, m_retryPDUBitLength, false, false, true);
writeRF_PDU(m_retryPDUData, m_retryPDUBitLength, false, true);
m_retryCount++;
}
else {
@ -610,6 +610,7 @@ bool Data::processNetwork(uint8_t* data, uint32_t len, uint32_t blockLength)
}
if (m_p25->m_netState == RS_NET_DATA) {
m_inbound = false; // forcibly set inbound to false
::memcpy(m_netPDU + m_netDataOffset, data + 24U, blockLength);
m_netDataOffset += blockLength;
m_netPDUCount++;
@ -898,7 +899,7 @@ void Data::writeRF_PDU_User(data::DataHeader& dataHeader, bool extendedAddress,
}
}
writeRF_PDU(data, bitLength, false, imm);
writeRF_PDU(data, bitLength, imm);
}
/* Updates the processor by the passed number of milliseconds. */
@ -1386,7 +1387,7 @@ void Data::writeNetwork(const uint8_t currentBlock, const uint8_t *data, uint32_
/* Helper to write a P25 PDU packet. */
void Data::writeRF_PDU(const uint8_t* pdu, uint32_t bitLength, bool noNulls, bool imm, bool ackRetry)
void Data::writeRF_PDU(const uint8_t* pdu, uint32_t bitLength, bool imm, bool ackRetry)
{
assert(pdu != nullptr);
assert(bitLength > 0U);
@ -1414,24 +1415,21 @@ void Data::writeRF_PDU(const uint8_t* pdu, uint32_t bitLength, bool noNulls, boo
uint8_t data[P25_PDU_FRAME_LENGTH_BYTES + 2U];
::memset(data, 0x00U, P25_PDU_FRAME_LENGTH_BYTES + 2U);
// Add the data
// add the data
uint32_t newBitLength = P25Utils::encode(pdu, data + 2U, bitLength);
uint32_t newByteLength = newBitLength / 8U;
if ((newBitLength % 8U) > 0U)
newByteLength++;
// Regenerate Sync
// regenerate Sync
Sync::addP25Sync(data + 2U);
// Regenerate NID
// regenerate NID
m_p25->m_nid.encode(data + 2U, DUID::PDU);
// Add status bits
P25Utils::addStatusBits(data + 2U, newBitLength, false);
P25Utils::addTrunkSlotStatusBits(data + 2U, newBitLength);
// Set first busy bits to 1,1
P25Utils::setStatusBits(data + 2U, P25_SS0_START, true, true);
// add status bits
P25Utils::addStatusBits(data + 2U, newBitLength, m_inbound, true);
P25Utils::setStatusBitsStartIdle(data + 2U);
if (m_p25->m_duplex) {
data[0U] = modem::TAG_DATA;
@ -1440,10 +1438,7 @@ void Data::writeRF_PDU(const uint8_t* pdu, uint32_t bitLength, bool noNulls, boo
m_p25->addFrame(data, newByteLength + 2U, false, imm);
}
// add trailing null pad; only if control data isn't being transmitted
if (!m_p25->m_ccRunning && !noNulls) {
m_p25->writeRF_Nulls();
}
m_p25->writeRF_TDU(true, imm);
}
/* Helper to write a network P25 PDU packet. */
@ -1663,7 +1658,7 @@ void Data::writeRF_PDU_Reg_Response(uint8_t regType, uint32_t llId, uint32_t ipA
/* Helper to write a PDU acknowledge response. */
void Data::writeRF_PDU_Ack_Response(uint8_t ackClass, uint8_t ackType, uint8_t ackStatus, uint32_t llId, uint32_t srcLlId, bool noNulls)
void Data::writeRF_PDU_Ack_Response(uint8_t ackClass, uint8_t ackType, uint8_t ackStatus, uint32_t llId, uint32_t srcLlId)
{
if (ackClass == PDUAckClass::ACK && ackType != PDUAckType::ACK)
return;
@ -1702,5 +1697,5 @@ void Data::writeRF_PDU_Ack_Response(uint8_t ackClass, uint8_t ackType, uint8_t a
rspHeader.getResponseClass(), rspHeader.getResponseType(), rspHeader.getResponseStatus(), rspHeader.getLLId(), rspHeader.getSrcLLId());
}
writeRF_PDU(data, bitLength, noNulls);
writeRF_PDU(data, bitLength);
}

@ -202,11 +202,10 @@ namespace p25
* @brief Helper to write a P25 PDU packet.
* @param[in] pdu Constructed PDU to transmit.
* @param bitlength Length of PDU in bits.
* @param noNulls Flag indicating no trailing nulls should be transmitted.
* @param imm Flag indicating the PDU should be written to the immediate queue.
* @param ackRetry Flag indicating the PDU is being sent as an acknowledged retry.
*/
void writeRF_PDU(const uint8_t* pdu, uint32_t bitLength, bool noNulls = false, bool imm = false, bool ackRetry = false);
void writeRF_PDU(const uint8_t* pdu, uint32_t bitLength, bool imm = false, bool ackRetry = false);
/**
* @brief Helper to write a network P25 PDU packet.
* This will take buffered network PDU data and repeat it over the air.
@ -231,9 +230,8 @@ namespace p25
* @param ackStatus
* @param llId Logical Link ID.
* @param srcLlId Source Logical Link ID.
* @param noNulls Flag indicating no trailing nulls should be transmitted.
*/
void writeRF_PDU_Ack_Response(uint8_t ackClass, uint8_t ackType, uint8_t ackStatus, uint32_t llId, uint32_t srcLlId = 0U, bool noNulls = false);
void writeRF_PDU_Ack_Response(uint8_t ackClass, uint8_t ackType, uint8_t ackStatus, uint32_t llId, uint32_t srcLlId = 0U);
};
} // namespace packet
} // namespace p25

@ -508,17 +508,17 @@ bool Voice::process(uint8_t* data, uint32_t len)
uint8_t buffer[P25_HDU_FRAME_LENGTH_BYTES + 2U];
::memset(buffer, 0x00U, P25_HDU_FRAME_LENGTH_BYTES + 2U);
// Generate Sync
// generate Sync
Sync::addP25Sync(buffer + 2U);
// Generate NID
// generate NID
m_p25->m_nid.encode(buffer + 2U, DUID::HDU);
// Generate HDU
// generate HDU
m_rfLC.encodeHDU(buffer + 2U);
// Add busy bits
P25Utils::addStatusBits(buffer + 2U, P25_HDU_FRAME_LENGTH_BITS, m_inbound);
// add status bits
P25Utils::addStatusBits(buffer + 2U, P25_HDU_FRAME_LENGTH_BITS, m_inbound, false);
writeNetwork(buffer, DUID::HDU);
@ -740,8 +740,8 @@ bool Voice::process(uint8_t* data, uint32_t len)
m_rfErrs += errors;
m_rfFrames++;
// add busy bits
P25Utils::addStatusBits(data + 2U, P25_LDU_FRAME_LENGTH_BITS, m_inbound);
// add status bits
P25Utils::addStatusBits(data + 2U, P25_LDU_FRAME_LENGTH_BITS, m_inbound, false);
writeNetwork(data + 2U, DUID::LDU1, frameType);
@ -857,8 +857,8 @@ bool Voice::process(uint8_t* data, uint32_t len)
m_rfErrs += errors;
m_rfFrames++;
// add busy bits
P25Utils::addStatusBits(data + 2U, P25_LDU_FRAME_LENGTH_BITS, m_inbound);
// add status bits
P25Utils::addStatusBits(data + 2U, P25_LDU_FRAME_LENGTH_BITS, m_inbound, false);
writeNetwork(data + 2U, DUID::LDU2);
@ -937,17 +937,17 @@ bool Voice::process(uint8_t* data, uint32_t len)
uint8_t buffer[P25_HDU_FRAME_LENGTH_BYTES + 2U];
::memset(buffer, 0x00U, P25_HDU_FRAME_LENGTH_BYTES + 2U);
// Generate Sync
// generate Sync
Sync::addP25Sync(buffer + 2U);
// Generate NID
// generate NID
m_p25->m_nid.encode(buffer + 2U, DUID::HDU);
// Generate HDU
// generate HDU
m_rfLC.encodeHDU(buffer + 2U);
// Add busy bits
P25Utils::addStatusBits(buffer + 2U, P25_HDU_FRAME_LENGTH_BITS, m_inbound);
// add status bits
P25Utils::addStatusBits(buffer + 2U, P25_HDU_FRAME_LENGTH_BITS, m_inbound, false);
writeNetwork(buffer, DUID::HDU);
@ -989,8 +989,8 @@ bool Voice::process(uint8_t* data, uint32_t len)
// generate NID
m_p25->m_nid.encode(data + 2U, DUID::VSELP1);
// add busy bits
P25Utils::addStatusBits(data + 2U, P25_LDU_FRAME_LENGTH_BITS, m_inbound);
// add status bits
P25Utils::addStatusBits(data + 2U, P25_LDU_FRAME_LENGTH_BITS, m_inbound, false);
writeNetwork(data + 2U, DUID::VSELP1);
@ -1031,8 +1031,8 @@ bool Voice::process(uint8_t* data, uint32_t len)
// generate NID
m_p25->m_nid.encode(data + 2U, DUID::VSELP2);
// add busy bits
P25Utils::addStatusBits(data + 2U, P25_LDU_FRAME_LENGTH_BITS, m_inbound);
// add status bits
P25Utils::addStatusBits(data + 2U, P25_LDU_FRAME_LENGTH_BITS, m_inbound, false);
writeNetwork(data + 2U, DUID::VSELP2);
@ -1507,14 +1507,14 @@ void Voice::writeNet_TDU()
buffer[0U] = modem::TAG_EOT;
buffer[1U] = 0x00U;
// Generate Sync
// generate Sync
Sync::addP25Sync(buffer + 2U);
// Generate NID
// generate NID
m_p25->m_nid.encode(buffer + 2U, DUID::TDU);
// Add busy bits
P25Utils::addStatusBits(buffer + 2U, P25_TDU_FRAME_LENGTH_BITS, false);
// add status bits
P25Utils::addStatusBits(buffer + 2U, P25_TDU_FRAME_LENGTH_BITS, false, false);
m_p25->addFrame(buffer, P25_TDU_FRAME_LENGTH_BYTES + 2U, true);
@ -1776,17 +1776,17 @@ void Voice::writeNet_LDU1()
uint8_t buffer[P25_HDU_FRAME_LENGTH_BYTES + 2U];
::memset(buffer, 0x00U, P25_HDU_FRAME_LENGTH_BYTES + 2U);
// Generate Sync
// generate Sync
Sync::addP25Sync(buffer + 2U);
// Generate NID
// generate NID
m_p25->m_nid.encode(buffer + 2U, DUID::HDU);
// Generate header
// generate HDU
m_netLC.encodeHDU(buffer + 2U);
// Add busy bits
P25Utils::addStatusBits(buffer + 2U, P25_HDU_FRAME_LENGTH_BITS, false);
// add status bits
P25Utils::addStatusBits(buffer + 2U, P25_HDU_FRAME_LENGTH_BITS, false, false);
buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x00U;
@ -1864,13 +1864,13 @@ void Voice::writeNet_LDU1()
uint8_t buffer[P25_LDU_FRAME_LENGTH_BYTES + 2U];
::memset(buffer, 0x00U, P25_LDU_FRAME_LENGTH_BYTES + 2U);
// Generate Sync
// generate Sync
Sync::addP25Sync(buffer + 2U);
// Generate NID
// generate NID
m_p25->m_nid.encode(buffer + 2U, DUID::LDU1);
// Generate LDU1 data
// generate LDU1 data
if (!m_netLC.isStandardMFId()) {
if (m_debug) {
LogDebug(LOG_NET, "P25, LDU1 LC, non-standard payload, lco = $%02X, mfId = $%02X", m_netLC.getLCO(), m_netLC.getMFId());
@ -1880,7 +1880,7 @@ void Voice::writeNet_LDU1()
m_netLC.encodeLDU1(buffer + 2U);
// Add the Audio
// add the Audio
m_audio.encode(buffer + 2U, m_netLDU1 + 10U, 0U);
m_audio.encode(buffer + 2U, m_netLDU1 + 26U, 1U);
m_audio.encode(buffer + 2U, m_netLDU1 + 55U, 2U);
@ -1891,13 +1891,13 @@ void Voice::writeNet_LDU1()
m_audio.encode(buffer + 2U, m_netLDU1 + 180U, 7U);
m_audio.encode(buffer + 2U, m_netLDU1 + 204U, 8U);
// Add the Low Speed Data
// add the Low Speed Data
m_netLSD.setLSD1(lsd.getLSD1());
m_netLSD.setLSD2(lsd.getLSD2());
m_netLSD.encode(buffer + 2U);
// Add busy bits
P25Utils::addStatusBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, false);
// add status bits
P25Utils::addStatusBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, false, false);
buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x00U;
@ -1962,16 +1962,16 @@ void Voice::writeNet_LDU2()
uint8_t buffer[P25_LDU_FRAME_LENGTH_BYTES + 2U];
::memset(buffer, 0x00U, P25_LDU_FRAME_LENGTH_BYTES + 2U);
// Generate Sync
// generate Sync
Sync::addP25Sync(buffer + 2U);
// Generate NID
// generate NID
m_p25->m_nid.encode(buffer + 2U, DUID::LDU2);
// Generate LDU2 data
// generate LDU2 data
m_netLC.encodeLDU2(buffer + 2U);
// Add the Audio
// add the Audio
m_audio.encode(buffer + 2U, m_netLDU2 + 10U, 0U);
m_audio.encode(buffer + 2U, m_netLDU2 + 26U, 1U);
m_audio.encode(buffer + 2U, m_netLDU2 + 55U, 2U);
@ -1982,13 +1982,13 @@ void Voice::writeNet_LDU2()
m_audio.encode(buffer + 2U, m_netLDU2 + 180U, 7U);
m_audio.encode(buffer + 2U, m_netLDU2 + 204U, 8U);
// Add the Low Speed Data
// add the Low Speed Data
m_netLSD.setLSD1(lsd.getLSD1());
m_netLSD.setLSD2(lsd.getLSD2());
m_netLSD.encode(buffer + 2U);
// Add busy bits
P25Utils::addStatusBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, false);
// add status bits
P25Utils::addStatusBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, false, false);
buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x00U;

@ -193,15 +193,15 @@ protected:
uint8_t data[P25_TDU_FRAME_LENGTH_BYTES + 2U];
::memset(data + 2U, 0x00U, P25_TDU_FRAME_LENGTH_BYTES);
// Generate Sync
// generate Sync
p25::Sync::addP25Sync(data + 2U);
// Generate NID
// generate NID
std::unique_ptr<p25::NID> nid = std::make_unique<p25::NID>(1U);
nid->encode(data + 2U, DUID::TDU);
// Add busy bits
p25::P25Utils::addStatusBits(data + 2U, P25_TDU_FRAME_LENGTH_BITS, false);
// add status bits
p25::P25Utils::addStatusBits(data + 2U, P25_TDU_FRAME_LENGTH_BITS, false, false);
data[0U] = modem::TAG_EOT;
data[1U] = 0x00U;

@ -338,20 +338,18 @@ protected:
uint8_t data[P25_TSDU_FRAME_LENGTH_BYTES];
::memset(data, 0x00U, P25_TSDU_FRAME_LENGTH_BYTES);
// Generate Sync
// generate Sync
Sync::addP25Sync(data);
// network bursts have no NID
// Generate TSBK block
// generate TSBK block
tsbk->setLastBlock(true); // always set last block -- this a Single Block TSDU
tsbk->encode(data);
// Add busy bits
P25Utils::addStatusBits(data, P25_TSDU_FRAME_LENGTH_BYTES, false);
// Set first busy bits to 1,1
P25Utils::setStatusBits(data, P25_SS0_START, true, true);
// add status bits
P25Utils::addStatusBits(data, P25_TSDU_FRAME_LENGTH_BYTES, false, true);
P25Utils::setStatusBitsStartIdle(data);
if (g_debug) {
LogDebug(LOG_RF, P25_TSDU_STR ", lco = $%02X, mfId = $%02X, lastBlock = %u, AIV = %u, EX = %u, srcId = %u, dstId = %u, sysId = $%03X, netId = $%05X",

Loading…
Cancel
Save

Powered by TurnKey Linux.