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); 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. */ /* 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); 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) { for (uint32_t ss0Pos = P25_SS0_START; ss0Pos < length; ss0Pos += P25_SS_INCREMENT) {
uint32_t ss1Pos = ss0Pos + 1U; uint32_t ss1Pos = ss0Pos + 1U;
WRITE_BIT(data, ss0Pos, true); // 1 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) // interleave the requested status bits (every other)
for (uint32_t ss0Pos = P25_SS0_START; ss0Pos < length; ss0Pos += (P25_SS_INCREMENT * 2U)) { for (uint32_t ss0Pos = P25_SS0_START; ss0Pos < length; ss0Pos += (P25_SS_INCREMENT * 2U)) {
uint32_t ss1Pos = ss0Pos + 1U; 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, ss0Pos, false); // 0
WRITE_BIT(data, ss1Pos, true); // 1 WRITE_BIT(data, ss1Pos, true); // 1
} else { } else {
if (control) { if (unknown) {
// set "1,0" (Unknown) status bits [TIA-102.BAAA]
WRITE_BIT(data, ss0Pos, true); // 1 WRITE_BIT(data, ss0Pos, true); // 1
WRITE_BIT(data, ss1Pos, false); // 0 WRITE_BIT(data, ss1Pos, false); // 0
} else { } else {
// set "1,1" (Start of Inbound Slot/Idle) status bits [TIA-102.BAAA]
WRITE_BIT(data, ss0Pos, true); // 1 WRITE_BIT(data, ss0Pos, true); // 1
WRITE_BIT(data, ss1Pos, 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); 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; uint32_t ss1Pos = ss0Pos + 1U;
// set "1,0" (Unknown) status bits [TIA-102.BAAA]
WRITE_BIT(data, ss0Pos, true); // 1 WRITE_BIT(data, ss0Pos, true); // 1
WRITE_BIT(data, ss1Pos, false); // 0 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); 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; 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, ss0Pos, true); // 1
WRITE_BIT(data, ss1Pos, 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. * @brief Helper to set the status bits on P25 frame data.
* @param data P25 frame data buffer. * @param data P25 frame data buffer.
* @param ssOffset * @param ssOffset Status symbol offset (bit offset).
* @param b1 Status Bit 1 * @param b1 Status Bit 1
* @param b2 Status Bit 2 * @param b2 Status Bit 2
*/ */
static void setStatusBits(uint8_t* data, uint32_t ssOffset, bool b1, bool b2); 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. * @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 * 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 data P25 frame data buffer.
* @param length * @param length Lenght of P25 frame in bits.
* @param inbound Flag indicating inbound channel is busy. * @param busy Flag indicating inbound channel is busy.
* @param control Flag indicating the channel is a control channel. * @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. * @brief Helper to add the unknown (1,0) status bits on P25 frame data.
* This sets the status bits to 1,0 interleaved every 5th status bit pair. * This sets the status bits to 1,0 interleaved every variable status bit pair.
* @param data P25 frame data buffer. * @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. * @brief Helper to add the idle (1,1) status bits on P25 frame data.
* This sets the status bits to 1,1 interleaved every 5th status bit pair. * This sets the status bits to 1,1 interleaved every variable status bit pair.
* @param data P25 frame data buffer. * @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. * @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]; uint8_t data[P25_TSDU_FRAME_LENGTH_BYTES];
::memset(data, 0x00U, P25_TSDU_FRAME_LENGTH_BYTES); ::memset(data, 0x00U, P25_TSDU_FRAME_LENGTH_BYTES);
// Generate Sync // generate Sync
Sync::addP25Sync(data); Sync::addP25Sync(data);
// network bursts have no NID // network bursts have no NID
// Generate TSBK block // generate TSBK block
tsbk->setLastBlock(true); // always set last block -- this a Single Block TSDU tsbk->setLastBlock(true); // always set last block -- this a Single Block TSDU
tsbk->encode(data); tsbk->encode(data);
// Add busy bits // add status bits
P25Utils::addStatusBits(data, P25_TSDU_FRAME_LENGTH_BYTES, false); P25Utils::addStatusBits(data, P25_TSDU_FRAME_LENGTH_BYTES, false, true);
P25Utils::setStatusBitsStartIdle(data);
// Set first busy bits to 1,1
P25Utils::setStatusBits(data, P25_SS0_START, true, true);
if (m_debug) { 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", 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]; uint8_t data[P25_TDU_FRAME_LENGTH_BYTES + 2U];
::memset(data + 2U, 0x00U, P25_TDU_FRAME_LENGTH_BYTES); ::memset(data + 2U, 0x00U, P25_TDU_FRAME_LENGTH_BYTES);
// Generate Sync // generate Sync
Sync::addP25Sync(data + 2U); Sync::addP25Sync(data + 2U);
// Generate NID // generate NID
m_nid->encode(data + 2U, DUID::TDU); m_nid->encode(data + 2U, DUID::TDU);
// Add busy bits // add status bits
P25Utils::addStatusBits(data + 2U, P25_TDU_FRAME_LENGTH_BITS, false); P25Utils::addStatusBits(data + 2U, P25_TDU_FRAME_LENGTH_BITS, false, false);
buffer[0U] = modem::TAG_EOT; buffer[0U] = modem::TAG_EOT;
buffer[1U] = 0x01U; buffer[1U] = 0x01U;
@ -672,17 +672,17 @@ void ModemV24::convertToAir(const uint8_t *data, uint32_t length)
lc.setKId(m_rxCall->kId); lc.setKId(m_rxCall->kId);
lc.setMI(m_rxCall->MI); lc.setMI(m_rxCall->MI);
// Generate Sync // generate Sync
Sync::addP25Sync(buffer + 2U); Sync::addP25Sync(buffer + 2U);
// Generate NID // generate NID
m_nid->encode(buffer + 2U, DUID::HDU); m_nid->encode(buffer + 2U, DUID::HDU);
// Generate HDU // generate HDU
lc.encodeHDU(buffer + 2U); lc.encodeHDU(buffer + 2U);
// Add busy bits // add status bits
P25Utils::addStatusBits(buffer + 2U, P25_HDU_FRAME_LENGTH_BITS, true); P25Utils::addStatusBits(buffer + 2U, P25_HDU_FRAME_LENGTH_BITS, true, false);
buffer[0U] = modem::TAG_DATA; buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x01U; 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]; uint8_t buffer[P25_PDU_FRAME_LENGTH_BYTES + 2U];
::memset(buffer, 0x00U, 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 newBitLength = P25Utils::encode(data, buffer + 2U, bitLength);
uint32_t newByteLength = newBitLength / 8U; uint32_t newByteLength = newBitLength / 8U;
if ((newBitLength % 8U) > 0U) if ((newBitLength % 8U) > 0U)
newByteLength++; newByteLength++;
// Regenerate Sync // regenerate Sync
Sync::addP25Sync(buffer + 2U); Sync::addP25Sync(buffer + 2U);
// Regenerate NID // regenerate NID
m_nid->encode(buffer + 2U, DUID::PDU); m_nid->encode(buffer + 2U, DUID::PDU);
// Add status bits // add status bits
P25Utils::addStatusBits(buffer + 2U, newBitLength, false); P25Utils::addStatusBits(buffer + 2U, newBitLength, false, false);
P25Utils::addIdleStatusBits(buffer + 2U, newBitLength); P25Utils::addIdleStatusBits(buffer + 2U, newBitLength);
P25Utils::setStatusBitsStartIdle(buffer + 2U);
// Set first busy bits to 1,1
P25Utils::setStatusBits(buffer + 2U, P25_SS0_START, true, true);
storeConvertedRx(buffer, P25_PDU_FRAME_LENGTH_BYTES + 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[0U] = modem::TAG_DATA;
buffer[1U] = 0x00U; buffer[1U] = 0x00U;
// Generate Sync // generate Sync
Sync::addP25Sync(buffer + 2U); Sync::addP25Sync(buffer + 2U);
// Generate NID // generate NID
m_nid->encode(buffer + 2U, DUID::TSDU); 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.setLastBlock(true); // always set last block -- this a Single Block TSDU
tsbk.encode(buffer + 2U); tsbk.encode(buffer + 2U);
// Add busy bits // add status bits
P25Utils::addStatusBits(buffer + 2U, P25_TSDU_FRAME_LENGTH_BYTES, false, true); P25Utils::addStatusBits(buffer + 2U, P25_TSDU_FRAME_LENGTH_BYTES, false, true);
P25Utils::addTrunkSlotStatusBits(buffer + 2U, P25_TSDU_FRAME_LENGTH_BYTES); P25Utils::addIdleStatusBits(buffer + 2U, P25_TSDU_FRAME_LENGTH_BYTES);
P25Utils::setStatusBitsStartIdle(buffer + 2U);
// Set first busy bits to 1,1
P25Utils::setStatusBits(buffer + 2U, P25_SS0_START, true, true);
storeConvertedRx(buffer, P25_TSDU_FRAME_LENGTH_BYTES + 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 + 180U, 7U);
m_audio.encode(buffer + 2U, m_rxCall->netLDU1 + 204U, 8U); m_audio.encode(buffer + 2U, m_rxCall->netLDU1 + 204U, 8U);
// add busy bits // add status bits
P25Utils::addStatusBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, true); P25Utils::addStatusBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, true, false);
buffer[0U] = modem::TAG_DATA; buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x01U; 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 + 180U, 7U);
m_audio.encode(buffer + 2U, m_rxCall->netLDU2 + 204U, 8U); m_audio.encode(buffer + 2U, m_rxCall->netLDU2 + 204U, 8U);
// add busy bits // add status bits
P25Utils::addStatusBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, true); P25Utils::addStatusBits(buffer + 2U, P25_LDU_FRAME_LENGTH_BITS, true, false);
buffer[0U] = modem::TAG_DATA; buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x01U; buffer[1U] = 0x01U;

@ -1725,14 +1725,14 @@ void Control::writeRF_TDU(bool noNetwork, bool imm)
uint8_t data[P25_TDU_FRAME_LENGTH_BYTES + 2U]; uint8_t data[P25_TDU_FRAME_LENGTH_BYTES + 2U];
::memset(data + 2U, 0x00U, P25_TDU_FRAME_LENGTH_BYTES); ::memset(data + 2U, 0x00U, P25_TDU_FRAME_LENGTH_BYTES);
// Generate Sync // generate Sync
Sync::addP25Sync(data + 2U); Sync::addP25Sync(data + 2U);
// Generate NID // generate NID
m_nid.encode(data + 2U, DUID::TDU); m_nid.encode(data + 2U, DUID::TDU);
// Add busy bits // add status bits
P25Utils::addStatusBits(data + 2U, P25_TDU_FRAME_LENGTH_BITS, false); P25Utils::setStatusBitsAllIdle(data + 2U, P25_TDU_FRAME_LENGTH_BITS);
if (!noNetwork) if (!noNetwork)
m_voice->writeNetwork(data + 2U, DUID::TDU); 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]; uint8_t data[P25_TDULC_FRAME_LENGTH_BYTES + 2U];
::memset(data + 2U, 0x00U, P25_TDULC_FRAME_LENGTH_BYTES); ::memset(data + 2U, 0x00U, P25_TDULC_FRAME_LENGTH_BYTES);
// Generate Sync // generate Sync
Sync::addP25Sync(data + 2U); Sync::addP25Sync(data + 2U);
// Generate NID // generate NID
m_p25->m_nid.encode(data + 2U, DUID::TDULC); m_p25->m_nid.encode(data + 2U, DUID::TDULC);
// Generate TDULC Data // generate TDULC Data
lc->encode(data + 2U); lc->encode(data + 2U);
// Add busy bits // add status bits
P25Utils::addStatusBits(data + 2U, P25_TDULC_FRAME_LENGTH_BITS, false); P25Utils::addStatusBits(data + 2U, P25_TDULC_FRAME_LENGTH_BITS, false, false);
m_p25->m_rfTimeout.stop(); m_p25->m_rfTimeout.stop();
@ -1396,17 +1396,17 @@ void ControlSignaling::writeNet_TDULC(lc::TDULC* lc)
buffer[0U] = modem::TAG_EOT; buffer[0U] = modem::TAG_EOT;
buffer[1U] = 0x00U; buffer[1U] = 0x00U;
// Generate Sync // generate Sync
Sync::addP25Sync(buffer + 2U); Sync::addP25Sync(buffer + 2U);
// Generate NID // generate NID
m_p25->m_nid.encode(buffer + 2U, DUID::TDULC); m_p25->m_nid.encode(buffer + 2U, DUID::TDULC);
// Regenerate TDULC Data // regenerate TDULC Data
lc->encode(buffer + 2U); lc->encode(buffer + 2U);
// Add busy bits // add status bits
P25Utils::addStatusBits(buffer + 2U, P25_TDULC_FRAME_LENGTH_BITS, false); P25Utils::addStatusBits(buffer + 2U, P25_TDULC_FRAME_LENGTH_BITS, false, false);
m_p25->addFrame(buffer, P25_TDULC_FRAME_LENGTH_BYTES + 2U, true); 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]; uint8_t data[P25_TSDU_FRAME_LENGTH_BYTES + 2U];
::memset(data + 2U, 0x00U, P25_TSDU_FRAME_LENGTH_BYTES); ::memset(data + 2U, 0x00U, P25_TSDU_FRAME_LENGTH_BYTES);
// Generate Sync // generate Sync
Sync::addP25Sync(data + 2U); Sync::addP25Sync(data + 2U);
// Generate NID // generate NID
m_p25->m_nid.encode(data + 2U, DUID::TSDU); 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->setLastBlock(true); // always set last block -- this a Single Block TSDU
tsbk->encode(data + 2U); 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); 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::addStatusBits(data + 2U, P25_TSDU_FRAME_LENGTH_BITS, m_inbound, true);
P25Utils::addTrunkSlotStatusBits(data + 2U, P25_TSDU_FRAME_LENGTH_BITS); P25Utils::addIdleStatusBits(data + 2U, P25_TSDU_FRAME_LENGTH_BITS);
P25Utils::setStatusBitsStartIdle(data + 2U);
// Set first busy bits to 1,1
P25Utils::setStatusBits(data + 2U, P25_SS0_START, true, true);
if (!noNetwork) if (!noNetwork)
writeNetworkRF(tsbk, data + 2U, true); writeNetworkRF(tsbk, data + 2U, true);
@ -1513,22 +1511,20 @@ void ControlSignaling::writeNet_TSDU(lc::TSBK* tsbk)
buffer[0U] = modem::TAG_DATA; buffer[0U] = modem::TAG_DATA;
buffer[1U] = 0x00U; buffer[1U] = 0x00U;
// Generate Sync // generate Sync
Sync::addP25Sync(buffer + 2U); Sync::addP25Sync(buffer + 2U);
// Generate NID // generate NID
m_p25->m_nid.encode(buffer + 2U, DUID::TSDU); 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->setLastBlock(true); // always set last block -- this a Single Block TSDU
tsbk->encode(buffer + 2U); tsbk->encode(buffer + 2U);
// Add busy bits // add status bits
P25Utils::addStatusBits(buffer + 2U, P25_TSDU_FRAME_LENGTH_BYTES, false, true); P25Utils::addStatusBits(buffer + 2U, P25_TSDU_FRAME_LENGTH_BYTES, false, true);
P25Utils::addTrunkSlotStatusBits(buffer + 2U, P25_TSDU_FRAME_LENGTH_BYTES); P25Utils::addIdleStatusBits(buffer + 2U, P25_TSDU_FRAME_LENGTH_BYTES);
P25Utils::setStatusBitsStartIdle(buffer + 2U);
// Set first busy bits to 1,1
P25Utils::setStatusBits(buffer + 2U, P25_SS0_START, true, true);
m_p25->addFrame(buffer, P25_TSDU_FRAME_LENGTH_BYTES + 2U, true); 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 // trigger encoding of last block and write to queue
if (m_mbfCnt + 1U == TSBK_MBF_CNT) { if (m_mbfCnt + 1U == TSBK_MBF_CNT) {
// Generate TSBK block // generate TSBK block
tsbk->setLastBlock(true); // set last block tsbk->setLastBlock(true); // set last block
tsbk->encode(frame, true); 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); 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]; uint8_t tsdu[P25_TSDU_TRIPLE_FRAME_LENGTH_BYTES];
::memset(tsdu, 0x00U, 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); 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); Utils::setBitRange(frame, tsdu, offset, P25_TSBK_FEC_LENGTH_BITS);
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]; uint8_t data[P25_TSDU_TRIPLE_FRAME_LENGTH_BYTES + 2U];
::memset(data + 2U, 0x00U, P25_TSDU_TRIPLE_FRAME_LENGTH_BYTES); ::memset(data + 2U, 0x00U, P25_TSDU_TRIPLE_FRAME_LENGTH_BYTES);
// Generate Sync // generate Sync
Sync::addP25Sync(data + 2U); Sync::addP25Sync(data + 2U);
// Generate NID // generate NID
m_p25->m_nid.encode(data + 2U, DUID::TSDU); m_p25->m_nid.encode(data + 2U, DUID::TSDU);
// interleave // interleave
P25Utils::encode(tsdu, data + 2U, 114U, 720U); 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::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[0U] = modem::TAG_DATA;
data[1U] = 0x00U; data[1U] = 0x00U;
@ -1631,7 +1627,7 @@ void ControlSignaling::writeRF_TSDU_MBF(lc::TSBK* tsbk)
return; return;
} }
// Generate TSBK block // generate TSBK block
tsbk->setLastBlock(false); // clear last block tsbk->setLastBlock(false); // clear last block
tsbk->encode(frame, true); 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); ::memset(data, 0x00U, P25_TSDU_FRAME_LENGTH_BYTES);
// Generate Sync // generate Sync
Sync::addP25Sync(data); Sync::addP25Sync(data);
// Generate NID // generate NID
m_p25->m_nid.encode(data, DUID::TSDU); 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->setLastBlock(true); // always set last block -- this a Single Block TSDU
tsbk->encode(data); tsbk->encode(data);
// Add busy bits // add status bits
P25Utils::addStatusBits(data, P25_TSDU_FRAME_LENGTH_BYTES, false); P25Utils::addStatusBits(data, P25_TSDU_FRAME_LENGTH_BYTES, false, false);
P25Utils::setStatusBitsStartIdle(data);
// Set first busy bits to 1,1
P25Utils::setStatusBits(data, P25_SS0_START, true, true);
} }
/* Helper to automatically inhibit a source ID on a denial. */ /* 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_retryPDUData != nullptr && m_retryPDUBitLength > 0U) {
if (m_retryCount < MAX_PDU_RETRY_CNT) { if (m_retryCount < MAX_PDU_RETRY_CNT) {
m_p25->writeRF_Preamble(); m_p25->writeRF_Preamble();
writeRF_PDU(m_retryPDUData, m_retryPDUBitLength, false, false, true); writeRF_PDU(m_retryPDUData, m_retryPDUBitLength, false, true);
m_retryCount++; m_retryCount++;
} }
else { 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) { if (m_p25->m_netState == RS_NET_DATA) {
m_inbound = false; // forcibly set inbound to false
::memcpy(m_netPDU + m_netDataOffset, data + 24U, blockLength); ::memcpy(m_netPDU + m_netDataOffset, data + 24U, blockLength);
m_netDataOffset += blockLength; m_netDataOffset += blockLength;
m_netPDUCount++; 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. */ /* 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. */ /* 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(pdu != nullptr);
assert(bitLength > 0U); 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]; uint8_t data[P25_PDU_FRAME_LENGTH_BYTES + 2U];
::memset(data, 0x00U, 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 newBitLength = P25Utils::encode(pdu, data + 2U, bitLength);
uint32_t newByteLength = newBitLength / 8U; uint32_t newByteLength = newBitLength / 8U;
if ((newBitLength % 8U) > 0U) if ((newBitLength % 8U) > 0U)
newByteLength++; newByteLength++;
// Regenerate Sync // regenerate Sync
Sync::addP25Sync(data + 2U); Sync::addP25Sync(data + 2U);
// Regenerate NID // regenerate NID
m_p25->m_nid.encode(data + 2U, DUID::PDU); m_p25->m_nid.encode(data + 2U, DUID::PDU);
// Add status bits // add status bits
P25Utils::addStatusBits(data + 2U, newBitLength, false); P25Utils::addStatusBits(data + 2U, newBitLength, m_inbound, true);
P25Utils::addTrunkSlotStatusBits(data + 2U, newBitLength); P25Utils::setStatusBitsStartIdle(data + 2U);
// Set first busy bits to 1,1
P25Utils::setStatusBits(data + 2U, P25_SS0_START, true, true);
if (m_p25->m_duplex) { if (m_p25->m_duplex) {
data[0U] = modem::TAG_DATA; 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); m_p25->addFrame(data, newByteLength + 2U, false, imm);
} }
// add trailing null pad; only if control data isn't being transmitted m_p25->writeRF_TDU(true, imm);
if (!m_p25->m_ccRunning && !noNulls) {
m_p25->writeRF_Nulls();
}
} }
/* Helper to write a network P25 PDU packet. */ /* 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. */ /* 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) if (ackClass == PDUAckClass::ACK && ackType != PDUAckType::ACK)
return; 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()); 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. * @brief Helper to write a P25 PDU packet.
* @param[in] pdu Constructed PDU to transmit. * @param[in] pdu Constructed PDU to transmit.
* @param bitlength Length of PDU in bits. * @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 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. * @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. * @brief Helper to write a network P25 PDU packet.
* This will take buffered network PDU data and repeat it over the air. * This will take buffered network PDU data and repeat it over the air.
@ -231,9 +230,8 @@ namespace p25
* @param ackStatus * @param ackStatus
* @param llId Logical Link ID. * @param llId Logical Link ID.
* @param srcLlId Source 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 packet
} // namespace p25 } // namespace p25

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

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

@ -338,20 +338,18 @@ protected:
uint8_t data[P25_TSDU_FRAME_LENGTH_BYTES]; uint8_t data[P25_TSDU_FRAME_LENGTH_BYTES];
::memset(data, 0x00U, P25_TSDU_FRAME_LENGTH_BYTES); ::memset(data, 0x00U, P25_TSDU_FRAME_LENGTH_BYTES);
// Generate Sync // generate Sync
Sync::addP25Sync(data); Sync::addP25Sync(data);
// network bursts have no NID // network bursts have no NID
// Generate TSBK block // generate TSBK block
tsbk->setLastBlock(true); // always set last block -- this a Single Block TSDU tsbk->setLastBlock(true); // always set last block -- this a Single Block TSDU
tsbk->encode(data); tsbk->encode(data);
// Add busy bits // add status bits
P25Utils::addStatusBits(data, P25_TSDU_FRAME_LENGTH_BYTES, false); P25Utils::addStatusBits(data, P25_TSDU_FRAME_LENGTH_BYTES, false, true);
P25Utils::setStatusBitsStartIdle(data);
// Set first busy bits to 1,1
P25Utils::setStatusBits(data, P25_SS0_START, true, true);
if (g_debug) { 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", 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.