cleanup and refactor how TSBK, TDULC, CSBK buffers are handled (optimization to buffer sizes); fix use of magic numbers in NXDN RCCH handlers;

3.56-maint
Bryan Biedenkapp 2 years ago
parent e4e677fa2b
commit d40960bba5

@ -109,7 +109,7 @@ typedef unsigned long long ulong64_t;
#define __PROG_NAME__ "Digital Voice Modem (DVM) Host" #define __PROG_NAME__ "Digital Voice Modem (DVM) Host"
#define __NET_NAME__ "DVM_DMR_P25" #define __NET_NAME__ "DVM_DMR_P25"
#define __EXE_NAME__ "dvmhost" #define __EXE_NAME__ "dvmhost"
#define __VER__ "D03.55.00 (" __GIT_VER__ ")" #define __VER__ "D03.56.00 (" __GIT_VER__ ")"
#define __BUILD__ __DATE__ " " __TIME__ #define __BUILD__ __DATE__ " " __TIME__
#define HOST_SW_API #define HOST_SW_API

@ -192,59 +192,62 @@ bool CSBK::regenerate(uint8_t* data, uint8_t dataType)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /// <summary>
/// Internal helper to convert CSBK bytes to a 64-bit long value. /// Internal helper to convert payload bytes to a 64-bit long value.
/// </summary> /// </summary>
/// <param name="tsbk"></param> /// <param name="payload"></param>
/// <returns></returns> /// <returns></returns>
ulong64_t CSBK::toValue(const uint8_t* csbk) ulong64_t CSBK::toValue(const uint8_t* payload)
{ {
ulong64_t csbkValue = 0U; ulong64_t value = 0U;
// combine bytes into ulong64_t (8 byte) value // combine bytes into ulong64_t (8 byte) value
csbkValue = csbk[2U]; value = payload[0U];
csbkValue = (csbkValue << 8) + csbk[3U]; value = (value << 8) + payload[1U];
csbkValue = (csbkValue << 8) + csbk[4U]; value = (value << 8) + payload[2U];
csbkValue = (csbkValue << 8) + csbk[5U]; value = (value << 8) + payload[3U];
csbkValue = (csbkValue << 8) + csbk[6U]; value = (value << 8) + payload[4U];
csbkValue = (csbkValue << 8) + csbk[7U]; value = (value << 8) + payload[5U];
csbkValue = (csbkValue << 8) + csbk[8U]; value = (value << 8) + payload[6U];
csbkValue = (csbkValue << 8) + csbk[9U]; value = (value << 8) + payload[7U];
return csbkValue; return value;
} }
/// <summary> /// <summary>
/// Internal helper to convert a 64-bit long value to CSBK bytes. /// Internal helper to convert a 64-bit long value to payload bytes.
/// </summary> /// </summary>
/// <param name="csbkValue"></param> /// <param name="value"></param>
/// <returns></returns> /// <returns></returns>
UInt8Array CSBK::fromValue(const ulong64_t csbkValue) UInt8Array CSBK::fromValue(const ulong64_t value)
{ {
__UNIQUE_UINT8_ARRAY(csbk, DMR_CSBK_LENGTH_BYTES); __UNIQUE_UINT8_ARRAY(payload, DMR_CSBK_LENGTH_BYTES - 4U);
// split ulong64_t (8 byte) value into bytes // split ulong64_t (8 byte) value into bytes
csbk[2U] = (uint8_t)((csbkValue >> 56) & 0xFFU); payload[0U] = (uint8_t)((value >> 56) & 0xFFU);
csbk[3U] = (uint8_t)((csbkValue >> 48) & 0xFFU); payload[1U] = (uint8_t)((value >> 48) & 0xFFU);
csbk[4U] = (uint8_t)((csbkValue >> 40) & 0xFFU); payload[2U] = (uint8_t)((value >> 40) & 0xFFU);
csbk[5U] = (uint8_t)((csbkValue >> 32) & 0xFFU); payload[3U] = (uint8_t)((value >> 32) & 0xFFU);
csbk[6U] = (uint8_t)((csbkValue >> 24) & 0xFFU); payload[4U] = (uint8_t)((value >> 24) & 0xFFU);
csbk[7U] = (uint8_t)((csbkValue >> 16) & 0xFFU); payload[5U] = (uint8_t)((value >> 16) & 0xFFU);
csbk[8U] = (uint8_t)((csbkValue >> 8) & 0xFFU); payload[6U] = (uint8_t)((value >> 8) & 0xFFU);
csbk[9U] = (uint8_t)((csbkValue >> 0) & 0xFFU); payload[7U] = (uint8_t)((value >> 0) & 0xFFU);
return csbk; return payload;
} }
/// <summary> /// <summary>
/// Internal helper to decode a control signalling block. /// Internal helper to decode a control signalling block.
/// </summary> /// </summary>
/// <param name="data"></param> /// <param name="data"></param>
/// <param name="tsbk"></param> /// <param name="payload"></param>
/// <returns>True, if TSBK was decoded, otherwise false.</returns> /// <returns>True, if CSBK was decoded, otherwise false.</returns>
bool CSBK::decode(const uint8_t* data, uint8_t* csbk) bool CSBK::decode(const uint8_t* data, uint8_t* payload)
{ {
assert(data != nullptr); assert(data != nullptr);
assert(csbk != nullptr); assert(payload != nullptr);
uint8_t csbk[DMR_CSBK_LENGTH_BYTES];
::memset(csbk, 0x00U, DMR_CSBK_LENGTH_BYTES);
// decode BPTC (196,96) FEC // decode BPTC (196,96) FEC
edac::BPTC19696 bptc; edac::BPTC19696 bptc;
@ -291,6 +294,7 @@ bool CSBK::decode(const uint8_t* data, uint8_t* csbk)
m_dataContent = false; m_dataContent = false;
m_CBF = 0U; m_CBF = 0U;
::memcpy(payload, csbk + 2U, DMR_CSBK_LENGTH_BYTES - 4U);
return true; return true;
} }
@ -298,58 +302,56 @@ bool CSBK::decode(const uint8_t* data, uint8_t* csbk)
/// Internal helper to encode a control signalling block. /// Internal helper to encode a control signalling block.
/// </summary> /// </summary>
/// <param name="data"></param> /// <param name="data"></param>
/// <param name="tsbk"></param> /// <param name="payload"></param>
/// <param name="rawTSBK"></param> void CSBK::encode(uint8_t* data, const uint8_t* payload)
/// <param name="noTrellis"></param>
void CSBK::encode(uint8_t* data, const uint8_t* csbk)
{ {
assert(data != nullptr); assert(data != nullptr);
assert(csbk != nullptr); assert(payload != nullptr);
uint8_t outCsbk[DMR_CSBK_LENGTH_BYTES]; uint8_t csbk[DMR_CSBK_LENGTH_BYTES];
::memset(outCsbk, 0x00U, DMR_CSBK_LENGTH_BYTES); ::memset(csbk, 0x00U, DMR_CSBK_LENGTH_BYTES);
::memcpy(outCsbk, csbk, DMR_CSBK_LENGTH_BYTES); ::memcpy(csbk + 2U, payload, DMR_CSBK_LENGTH_BYTES - 4U);
outCsbk[0U] = m_CSBKO; // CSBKO csbk[0U] = m_CSBKO; // CSBKO
outCsbk[0U] |= (m_lastBlock) ? 0x80U : 0x00U; // Last Block Marker csbk[0U] |= (m_lastBlock) ? 0x80U : 0x00U; // Last Block Marker
if (!m_Cdef) { if (!m_Cdef) {
outCsbk[1U] = m_FID; // Feature ID csbk[1U] = m_FID; // Feature ID
} }
else { else {
outCsbk[1U] = m_colorCode & 0x0FU; // Cdef uses Color Code csbk[1U] = m_colorCode & 0x0FU; // Cdef uses Color Code
} }
switch (m_dataType) { switch (m_dataType) {
case DT_CSBK: case DT_CSBK:
outCsbk[10U] ^= CSBK_CRC_MASK[0U]; csbk[10U] ^= CSBK_CRC_MASK[0U];
outCsbk[11U] ^= CSBK_CRC_MASK[1U]; csbk[11U] ^= CSBK_CRC_MASK[1U];
break; break;
case DT_MBC_HEADER: case DT_MBC_HEADER:
outCsbk[10U] ^= CSBK_MBC_CRC_MASK[0U]; csbk[10U] ^= CSBK_MBC_CRC_MASK[0U];
outCsbk[11U] ^= CSBK_MBC_CRC_MASK[1U]; csbk[11U] ^= CSBK_MBC_CRC_MASK[1U];
break; break;
} }
edac::CRC::addCCITT162(outCsbk, 12U); edac::CRC::addCCITT162(csbk, 12U);
switch (m_dataType) { switch (m_dataType) {
case DT_CSBK: case DT_CSBK:
outCsbk[10U] ^= CSBK_CRC_MASK[0U]; csbk[10U] ^= CSBK_CRC_MASK[0U];
outCsbk[11U] ^= CSBK_CRC_MASK[1U]; csbk[11U] ^= CSBK_CRC_MASK[1U];
break; break;
case DT_MBC_HEADER: case DT_MBC_HEADER:
outCsbk[10U] ^= CSBK_MBC_CRC_MASK[0U]; csbk[10U] ^= CSBK_MBC_CRC_MASK[0U];
outCsbk[11U] ^= CSBK_MBC_CRC_MASK[1U]; csbk[11U] ^= CSBK_MBC_CRC_MASK[1U];
break; break;
} }
if (m_verbose) { if (m_verbose) {
Utils::dump(2U, "Encoded CSBK", outCsbk, DMR_CSBK_LENGTH_BYTES); Utils::dump(2U, "Encoded CSBK", csbk, DMR_CSBK_LENGTH_BYTES);
} }
// encode BPTC (196,96) FEC // encode BPTC (196,96) FEC
edac::BPTC19696 bptc; edac::BPTC19696 bptc;
bptc.encode(outCsbk, data); bptc.encode(csbk, data);
} }
/// <summary> /// <summary>

@ -149,15 +149,15 @@ namespace dmr
/** Local Site data */ /** Local Site data */
static SiteData m_siteData; static SiteData m_siteData;
/// <summary>Internal helper to convert CSBK bytes to a 64-bit long value.</summary> /// <summary>Internal helper to convert payload bytes to a 64-bit long value.</summary>
static ulong64_t toValue(const uint8_t* Csbk); static ulong64_t toValue(const uint8_t* payload);
/// <summary>Internal helper to convert a 64-bit long value to CSBK bytes.</summary> /// <summary>Internal helper to convert a 64-bit long value to payload bytes.</summary>
static UInt8Array fromValue(const ulong64_t csbkValue); static UInt8Array fromValue(const ulong64_t value);
/// <summary>Internal helper to decode a control signalling block.</summary> /// <summary>Internal helper to decode a control signalling block.</summary>
bool decode(const uint8_t* data, uint8_t* csbk); bool decode(const uint8_t* data, uint8_t* payload);
/// <summary>Internal helper to encode a control signalling block.</summary> /// <summary>Internal helper to encode a control signalling block.</summary>
void encode(uint8_t* data, const uint8_t* csbk); void encode(uint8_t* data, const uint8_t* payload);
__PROTECTED_COPY(CSBK); __PROTECTED_COPY(CSBK);
}; };

@ -57,7 +57,7 @@ void MESSAGE_TYPE_DCALL_HDR::decode(const uint8_t* data, uint32_t length, uint32
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
RCCH::decode(data, rcch, length, offset); RCCH::decode(data, rcch, length, offset);
@ -81,7 +81,7 @@ void MESSAGE_TYPE_DCALL_HDR::encode(uint8_t* data, uint32_t length, uint32_t off
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
rcch[1U] = (m_emergency ? 0x80U : 0x00U) + // Emergency Flag rcch[1U] = (m_emergency ? 0x80U : 0x00U) + // Emergency Flag

@ -57,7 +57,7 @@ void MESSAGE_TYPE_DST_ID_INFO::decode(const uint8_t* data, uint32_t length, uint
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
RCCH::decode(data, rcch, length, offset); RCCH::decode(data, rcch, length, offset);
@ -73,7 +73,7 @@ void MESSAGE_TYPE_DST_ID_INFO::encode(uint8_t* data, uint32_t length, uint32_t o
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
rcch[1U] = 0xC0U + NXDN_CALLSIGN_LENGTH_BYTES; // Station ID Option - Start / End / Character Count rcch[1U] = 0xC0U + NXDN_CALLSIGN_LENGTH_BYTES; // Station ID Option - Start / End / Character Count

@ -57,7 +57,7 @@ void MESSAGE_TYPE_GRP_REG::decode(const uint8_t* data, uint32_t length, uint32_t
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
RCCH::decode(data, rcch, length, offset); RCCH::decode(data, rcch, length, offset);
@ -77,7 +77,7 @@ void MESSAGE_TYPE_GRP_REG::encode(uint8_t* data, uint32_t length, uint32_t offse
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
rcch[2U] = (m_srcId >> 8U) & 0xFFU; // Source Radio Address rcch[2U] = (m_srcId >> 8U) & 0xFFU; // Source Radio Address

@ -57,7 +57,7 @@ void MESSAGE_TYPE_IDLE::decode(const uint8_t* data, uint32_t length, uint32_t of
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
RCCH::decode(data, rcch, length, offset); RCCH::decode(data, rcch, length, offset);
@ -73,7 +73,7 @@ void MESSAGE_TYPE_IDLE::encode(uint8_t* data, uint32_t length, uint32_t offset)
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
RCCH::encode(data, rcch, length, offset); RCCH::encode(data, rcch, length, offset);

@ -57,7 +57,7 @@ void MESSAGE_TYPE_REG::decode(const uint8_t* data, uint32_t length, uint32_t off
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
RCCH::decode(data, rcch, length, offset); RCCH::decode(data, rcch, length, offset);
@ -80,7 +80,7 @@ void MESSAGE_TYPE_REG::encode(uint8_t* data, uint32_t length, uint32_t offset)
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
rcch[2U] = (m_siteData.locId() >> 8) & 0xFFU; // ... rcch[2U] = (m_siteData.locId() >> 8) & 0xFFU; // ...

@ -57,7 +57,7 @@ void MESSAGE_TYPE_REG_C::decode(const uint8_t* data, uint32_t length, uint32_t o
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
RCCH::decode(data, rcch, length, offset); RCCH::decode(data, rcch, length, offset);
@ -77,7 +77,7 @@ void MESSAGE_TYPE_REG_C::encode(uint8_t* data, uint32_t length, uint32_t offset)
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
rcch[2U] = (m_siteData.locId() >> 8) & 0xFFU; // Location ID rcch[2U] = (m_siteData.locId() >> 8) & 0xFFU; // Location ID

@ -57,7 +57,7 @@ void MESSAGE_TYPE_REG_COMM::decode(const uint8_t* data, uint32_t length, uint32_
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
RCCH::decode(data, rcch, length, offset); RCCH::decode(data, rcch, length, offset);
@ -73,7 +73,7 @@ void MESSAGE_TYPE_REG_COMM::encode(uint8_t* data, uint32_t length, uint32_t offs
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
rcch[2U] = (m_siteData.locId() >> 8) & 0xFFU; // Location ID rcch[2U] = (m_siteData.locId() >> 8) & 0xFFU; // Location ID

@ -62,7 +62,7 @@ void MESSAGE_TYPE_SITE_INFO::decode(const uint8_t* data, uint32_t length, uint32
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
RCCH::decode(data, rcch, length, offset); RCCH::decode(data, rcch, length, offset);
@ -78,7 +78,7 @@ void MESSAGE_TYPE_SITE_INFO::encode(uint8_t* data, uint32_t length, uint32_t off
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
rcch[1U] = (m_siteData.locId() >> 16) & 0xFFU; // Location ID rcch[1U] = (m_siteData.locId() >> 16) & 0xFFU; // Location ID

@ -57,7 +57,7 @@ void MESSAGE_TYPE_SRV_INFO::decode(const uint8_t* data, uint32_t length, uint32_
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
RCCH::decode(data, rcch, length, offset); RCCH::decode(data, rcch, length, offset);
@ -73,7 +73,7 @@ void MESSAGE_TYPE_SRV_INFO::encode(uint8_t* data, uint32_t length, uint32_t offs
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
rcch[1U] = (m_siteData.locId() >> 16) & 0xFFU; // Location ID rcch[1U] = (m_siteData.locId() >> 16) & 0xFFU; // Location ID

@ -57,7 +57,7 @@ void MESSAGE_TYPE_VCALL_ASSGN::decode(const uint8_t* data, uint32_t length, uint
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
RCCH::decode(data, rcch, length, offset); RCCH::decode(data, rcch, length, offset);
@ -73,7 +73,7 @@ void MESSAGE_TYPE_VCALL_ASSGN::encode(uint8_t* data, uint32_t length, uint32_t o
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
rcch[1U] = (m_emergency ? 0x80U : 0x00U) + // Emergency Flag rcch[1U] = (m_emergency ? 0x80U : 0x00U) + // Emergency Flag

@ -57,7 +57,7 @@ void MESSAGE_TYPE_VCALL_CONN::decode(const uint8_t* data, uint32_t length, uint3
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
RCCH::decode(data, rcch, length, offset); RCCH::decode(data, rcch, length, offset);
@ -81,7 +81,7 @@ void MESSAGE_TYPE_VCALL_CONN::encode(uint8_t* data, uint32_t length, uint32_t of
{ {
assert(data != NULL); assert(data != NULL);
uint8_t rcch[22U]; uint8_t rcch[NXDN_RCCH_LC_LENGTH_BYTES + 4U];
::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U); ::memset(rcch, 0x00U, NXDN_RCCH_LC_LENGTH_BYTES + 4U);
rcch[1U] = (m_emergency ? 0x80U : 0x00U) + // Emergency Flag rcch[1U] = (m_emergency ? 0x80U : 0x00U) + // Emergency Flag

@ -78,6 +78,7 @@ namespace p25
const uint32_t P25_TDULC_FEC_LENGTH_BYTES = 36U; const uint32_t P25_TDULC_FEC_LENGTH_BYTES = 36U;
const uint32_t P25_TDULC_LENGTH_BYTES = 18U; const uint32_t P25_TDULC_LENGTH_BYTES = 18U;
const uint32_t P25_TDULC_PAYLOAD_LENGTH_BYTES = 8U;
const uint32_t P25_TSBK_FEC_LENGTH_BYTES = 25U; const uint32_t P25_TSBK_FEC_LENGTH_BYTES = 25U;
const uint32_t P25_TSBK_FEC_LENGTH_BITS = P25_TSBK_FEC_LENGTH_BYTES * 8U - 4U; // Trellis is actually 196 bits const uint32_t P25_TSBK_FEC_LENGTH_BITS = P25_TSBK_FEC_LENGTH_BYTES * 8U - 4U; // Trellis is actually 196 bits

@ -81,9 +81,10 @@ void AMBT::encode(uint8_t* data, bool rawTSBK, bool noTrellis)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /// <summary>
/// Internal helper to convert TSBK bytes to a 64-bit long value. /// Internal helper to convert AMBT bytes to a 64-bit long value.
/// </summary> /// </summary>
/// <param name="tsbk"></param> /// <param name="dataHeader"></param>
/// <param name="pduUserData"></param>
/// <returns></returns> /// <returns></returns>
ulong64_t AMBT::toValue(const data::DataHeader& dataHeader, const uint8_t* pduUserData) ulong64_t AMBT::toValue(const data::DataHeader& dataHeader, const uint8_t* pduUserData)
{ {
@ -125,7 +126,7 @@ bool AMBT::decode(const data::DataHeader& dataHeader, const data::DataBlock* blo
} }
m_lco = dataHeader.getAMBTOpcode(); // LCO m_lco = dataHeader.getAMBTOpcode(); // LCO
m_lastBlock = true; m_lastBlock = true; // Last Block Marker
m_mfId = dataHeader.getMFId(); // Mfg Id. m_mfId = dataHeader.getMFId(); // Mfg Id.
if (dataHeader.getOutbound()) { if (dataHeader.getOutbound()) {
@ -159,7 +160,7 @@ void AMBT::encode(data::DataHeader& dataHeader, uint8_t* pduUserData)
assert(pduUserData != nullptr); assert(pduUserData != nullptr);
dataHeader.setFormat(PDU_FMT_AMBT); dataHeader.setFormat(PDU_FMT_AMBT);
dataHeader.setMFId(m_mfId); dataHeader.setMFId(m_mfId); // Mfg Id.
dataHeader.setAckNeeded(false); dataHeader.setAckNeeded(false);
dataHeader.setOutbound(true); dataHeader.setOutbound(true);
dataHeader.setSAP(PDU_SAP_TRUNK_CTRL); dataHeader.setSAP(PDU_SAP_TRUNK_CTRL);
@ -170,7 +171,7 @@ void AMBT::encode(data::DataHeader& dataHeader, uint8_t* pduUserData)
dataHeader.setBlocksToFollow(1U); dataHeader.setBlocksToFollow(1U);
} }
dataHeader.setAMBTOpcode(m_lco); dataHeader.setAMBTOpcode(m_lco); // LCO
// generate packet CRC-32 and set data blocks // generate packet CRC-32 and set data blocks
if (dataHeader.getBlocksToFollow() > 1U) { if (dataHeader.getBlocksToFollow() > 1U) {

@ -56,7 +56,7 @@ namespace p25
void encode(uint8_t* data, bool rawTSBK = false, bool noTrellis = false); void encode(uint8_t* data, bool rawTSBK = false, bool noTrellis = false);
protected: protected:
/// <summary>Internal helper to convert TSBK bytes to a 64-bit long value.</summary> /// <summary>Internal helper to convert AMBT bytes to a 64-bit long value.</summary>
static ulong64_t toValue(const data::DataHeader& dataHeader, const uint8_t* pduUserData); static ulong64_t toValue(const data::DataHeader& dataHeader, const uint8_t* pduUserData);
/// <summary>Internal helper to decode a trunking signalling block.</summary> /// <summary>Internal helper to decode a trunking signalling block.</summary>

@ -120,59 +120,64 @@ TDULC::~TDULC()
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /// <summary>
/// Internal helper to convert RS bytes to a 64-bit long value. /// Internal helper to convert payload bytes to a 64-bit long value.
/// </summary> /// </summary>
/// <param name="tsbk"></param> /// <param name="tsbk"></param>
/// <returns></returns> /// <returns></returns>
ulong64_t TDULC::toValue(const uint8_t* rs) ulong64_t TDULC::toValue(const uint8_t* payload)
{ {
ulong64_t rsValue = 0U; assert(payload != nullptr);
ulong64_t value = 0U;
// combine bytes into ulong64_t (8 byte) value // combine bytes into ulong64_t (8 byte) value
rsValue = rs[1U]; value = payload[0U];
rsValue = (rsValue << 8) + rs[2U]; value = (value << 8) + payload[1U];
rsValue = (rsValue << 8) + rs[3U]; value = (value << 8) + payload[2U];
rsValue = (rsValue << 8) + rs[4U]; value = (value << 8) + payload[3U];
rsValue = (rsValue << 8) + rs[5U]; value = (value << 8) + payload[4U];
rsValue = (rsValue << 8) + rs[6U]; value = (value << 8) + payload[5U];
rsValue = (rsValue << 8) + rs[7U]; value = (value << 8) + payload[6U];
rsValue = (rsValue << 8) + rs[8U]; value = (value << 8) + payload[7U];
return rsValue; return value;
} }
/// <summary> /// <summary>
/// Internal helper to convert a 64-bit long value to RS bytes. /// Internal helper to convert a 64-bit long value to payload bytes.
/// </summary> /// </summary>
/// <param name="rsValue"></param> /// <param name="rsValue"></param>
/// <returns></returns> /// <returns></returns>
UInt8Array TDULC::fromValue(const ulong64_t rsValue) UInt8Array TDULC::fromValue(const ulong64_t value)
{ {
__UNIQUE_UINT8_ARRAY(rs, P25_TDULC_LENGTH_BYTES); __UNIQUE_UINT8_ARRAY(payload, P25_TDULC_PAYLOAD_LENGTH_BYTES);
// split ulong64_t (8 byte) value into bytes // split ulong64_t (8 byte) value into bytes
rs[1U] = (uint8_t)((rsValue >> 56) & 0xFFU); payload[0U] = (uint8_t)((value >> 56) & 0xFFU);
rs[2U] = (uint8_t)((rsValue >> 48) & 0xFFU); payload[1U] = (uint8_t)((value >> 48) & 0xFFU);
rs[3U] = (uint8_t)((rsValue >> 40) & 0xFFU); payload[2U] = (uint8_t)((value >> 40) & 0xFFU);
rs[4U] = (uint8_t)((rsValue >> 32) & 0xFFU); payload[3U] = (uint8_t)((value >> 32) & 0xFFU);
rs[5U] = (uint8_t)((rsValue >> 24) & 0xFFU); payload[4U] = (uint8_t)((value >> 24) & 0xFFU);
rs[6U] = (uint8_t)((rsValue >> 16) & 0xFFU); payload[5U] = (uint8_t)((value >> 16) & 0xFFU);
rs[7U] = (uint8_t)((rsValue >> 8) & 0xFFU); payload[6U] = (uint8_t)((value >> 8) & 0xFFU);
rs[8U] = (uint8_t)((rsValue >> 0) & 0xFFU); payload[7U] = (uint8_t)((value >> 0) & 0xFFU);
return rs; return payload;
} }
/// <summary> /// <summary>
/// Internal helper to decode a terminator data unit w/ link control. /// Internal helper to decode a terminator data unit w/ link control.
/// </summary> /// </summary>
/// <param name="data"></param> /// <param name="data"></param>
/// <param name="rs"></param> /// <param name="payload"></param>
/// <returns>True, if TDULC was decoded, otherwise false.</returns> /// <returns>True, if TDULC was decoded, otherwise false.</returns>
bool TDULC::decode(const uint8_t* data, uint8_t* rs) bool TDULC::decode(const uint8_t* data, uint8_t* payload)
{ {
assert(data != nullptr); assert(data != nullptr);
assert(rs != nullptr); assert(payload != nullptr);
uint8_t rs[P25_TDULC_LENGTH_BYTES];
::memset(rs, 0x00U, P25_TDULC_LENGTH_BYTES);
// deinterleave // deinterleave
uint8_t raw[P25_TDULC_FEC_LENGTH_BYTES + 1U]; uint8_t raw[P25_TDULC_FEC_LENGTH_BYTES + 1U];
@ -202,6 +207,7 @@ bool TDULC::decode(const uint8_t* data, uint8_t* rs)
Utils::dump(2U, "TDULC::decode(), TDULC Value", rs, P25_TDULC_LENGTH_BYTES); Utils::dump(2U, "TDULC::decode(), TDULC Value", rs, P25_TDULC_LENGTH_BYTES);
} }
::memcpy(payload, rs + 1U, P25_TDULC_PAYLOAD_LENGTH_BYTES);
return true; return true;
} }
@ -209,36 +215,36 @@ bool TDULC::decode(const uint8_t* data, uint8_t* rs)
/// Internal helper to encode a terminator data unit w/ link control. /// Internal helper to encode a terminator data unit w/ link control.
/// </summary> /// </summary>
/// <param name="data"></param> /// <param name="data"></param>
/// <param name="rs"></param> /// <param name="payload"></param>
void TDULC::encode(uint8_t* data, const uint8_t* rs) void TDULC::encode(uint8_t* data, const uint8_t* payload)
{ {
assert(data != nullptr); assert(data != nullptr);
assert(rs != nullptr); assert(payload != nullptr);
uint8_t outRs[P25_TDULC_LENGTH_BYTES]; uint8_t rs[P25_TDULC_LENGTH_BYTES];
::memset(outRs, 0x00U, P25_TDULC_LENGTH_BYTES); ::memset(rs, 0x00U, P25_TDULC_LENGTH_BYTES);
::memcpy(outRs, rs, P25_TDULC_LENGTH_BYTES); ::memcpy(rs + 1U, payload, P25_TDULC_PAYLOAD_LENGTH_BYTES);
outRs[0U] = m_lco; // LCO rs[0U] = m_lco; // LCO
if (m_implicit) if (m_implicit)
outRs[0U] |= 0x40U; // Implicit Operation rs[0U] |= 0x40U; // Implicit Operation
if (m_verbose) { if (m_verbose) {
Utils::dump(2U, "TDULC::encode(), TDULC Value", outRs, P25_TDULC_LENGTH_BYTES); Utils::dump(2U, "TDULC::encode(), TDULC Value", rs, P25_TDULC_LENGTH_BYTES);
} }
// encode RS (24,12,13) FEC // encode RS (24,12,13) FEC
m_rs.encode241213(outRs); m_rs.encode241213(rs);
#if DEBUG_P25_TDULC #if DEBUG_P25_TDULC
Utils::dump(2U, "TDULC::encode(), TDULC RS", outRs, P25_TDULC_LENGTH_BYTES); Utils::dump(2U, "TDULC::encode(), TDULC RS", rs, P25_TDULC_LENGTH_BYTES);
#endif #endif
uint8_t raw[P25_TDULC_FEC_LENGTH_BYTES + 1U]; uint8_t raw[P25_TDULC_FEC_LENGTH_BYTES + 1U];
::memset(raw, 0x00U, P25_TDULC_FEC_LENGTH_BYTES + 1U); ::memset(raw, 0x00U, P25_TDULC_FEC_LENGTH_BYTES + 1U);
// encode Golay (24,12,8) FEC // encode Golay (24,12,8) FEC
edac::Golay24128::encode24128(raw, outRs, P25_TDULC_LENGTH_BYTES); edac::Golay24128::encode24128(raw, rs, P25_TDULC_LENGTH_BYTES);
// interleave // interleave
P25Utils::encode(raw, data, 114U, 410U); P25Utils::encode(raw, data, 114U, 410U);

@ -121,15 +121,15 @@ namespace p25
/** Local Site data */ /** Local Site data */
static SiteData m_siteData; static SiteData m_siteData;
/// <summary>Internal helper to convert RS bytes to a 64-bit long value.</summary> /// <summary>Internal helper to convert payload bytes to a 64-bit long value.</summary>
static ulong64_t toValue(const uint8_t* rs); static ulong64_t toValue(const uint8_t* payload);
/// <summary>Internal helper to convert a 64-bit long value to RS bytes.</summary> /// <summary>Internal helper to convert a 64-bit long value to payload bytes.</summary>
static UInt8Array fromValue(const ulong64_t rsValue); static UInt8Array fromValue(const ulong64_t value);
/// <summary>Internal helper to decode terminator data unit w/ link control.</summary> /// <summary>Internal helper to decode terminator data unit w/ link control.</summary>
bool decode(const uint8_t* data, uint8_t* rs); bool decode(const uint8_t* data, uint8_t* payload);
/// <summary>Internal helper to encode terminator data unit w/ link control.</summary> /// <summary>Internal helper to encode terminator data unit w/ link control.</summary>
void encode(uint8_t* data, const uint8_t* rs); void encode(uint8_t* data, const uint8_t* payload);
__PROTECTED_COPY(TDULC); __PROTECTED_COPY(TDULC);
}; };

@ -47,7 +47,7 @@ bool TSBK::m_warnCRC = true;
bool TSBK::m_warnCRC = false; bool TSBK::m_warnCRC = false;
#endif #endif
uint8_t *TSBK::m_siteCallsign = nullptr; uint8_t* TSBK::m_siteCallsign = nullptr;
SiteData TSBK::m_siteData = SiteData(); SiteData TSBK::m_siteData = SiteData();
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
@ -163,62 +163,67 @@ void TSBK::setCallsign(std::string callsign)
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
/// <summary> /// <summary>
/// Internal helper to convert TSBK bytes to a 64-bit long value. /// Internal helper to convert payload bytes to a 64-bit long value.
/// </summary> /// </summary>
/// <param name="tsbk"></param> /// <param name="tsbk"></param>
/// <returns></returns> /// <returns></returns>
ulong64_t TSBK::toValue(const uint8_t* tsbk) ulong64_t TSBK::toValue(const uint8_t* payload)
{ {
ulong64_t tsbkValue = 0U; assert(payload != nullptr);
ulong64_t value = 0U;
// combine bytes into ulong64_t (8 byte) value // combine bytes into ulong64_t (8 byte) value
tsbkValue = tsbk[2U]; value = payload[0U];
tsbkValue = (tsbkValue << 8) + tsbk[3U]; value = (value << 8) + payload[1U];
tsbkValue = (tsbkValue << 8) + tsbk[4U]; value = (value << 8) + payload[2U];
tsbkValue = (tsbkValue << 8) + tsbk[5U]; value = (value << 8) + payload[3U];
tsbkValue = (tsbkValue << 8) + tsbk[6U]; value = (value << 8) + payload[4U];
tsbkValue = (tsbkValue << 8) + tsbk[7U]; value = (value << 8) + payload[5U];
tsbkValue = (tsbkValue << 8) + tsbk[8U]; value = (value << 8) + payload[6U];
tsbkValue = (tsbkValue << 8) + tsbk[9U]; value = (value << 8) + payload[7U];
return tsbkValue; return value;
} }
/// <summary> /// <summary>
/// Internal helper to convert a 64-bit long value to TSBK bytes. /// Internal helper to convert a 64-bit long value to payload bytes.
/// </summary> /// </summary>
/// <param name="tsbkValue"></param> /// <param name="value"></param>
/// <returns></returns> /// <returns></returns>
UInt8Array TSBK::fromValue(const ulong64_t tsbkValue) UInt8Array TSBK::fromValue(const ulong64_t value)
{ {
__UNIQUE_UINT8_ARRAY(tsbk, P25_TSBK_LENGTH_BYTES); __UNIQUE_UINT8_ARRAY(payload, P25_TSBK_LENGTH_BYTES - 4U);
// split ulong64_t (8 byte) value into bytes // split ulong64_t (8 byte) value into bytes
tsbk[2U] = (uint8_t)((tsbkValue >> 56) & 0xFFU); payload[0U] = (uint8_t)((value >> 56) & 0xFFU);
tsbk[3U] = (uint8_t)((tsbkValue >> 48) & 0xFFU); payload[1U] = (uint8_t)((value >> 48) & 0xFFU);
tsbk[4U] = (uint8_t)((tsbkValue >> 40) & 0xFFU); payload[2U] = (uint8_t)((value >> 40) & 0xFFU);
tsbk[5U] = (uint8_t)((tsbkValue >> 32) & 0xFFU); payload[3U] = (uint8_t)((value >> 32) & 0xFFU);
tsbk[6U] = (uint8_t)((tsbkValue >> 24) & 0xFFU); payload[4U] = (uint8_t)((value >> 24) & 0xFFU);
tsbk[7U] = (uint8_t)((tsbkValue >> 16) & 0xFFU); payload[5U] = (uint8_t)((value >> 16) & 0xFFU);
tsbk[8U] = (uint8_t)((tsbkValue >> 8) & 0xFFU); payload[6U] = (uint8_t)((value >> 8) & 0xFFU);
tsbk[9U] = (uint8_t)((tsbkValue >> 0) & 0xFFU); payload[7U] = (uint8_t)((value >> 0) & 0xFFU);
return tsbk; return payload;
} }
/// <summary> /// <summary>
/// Internal helper to decode a trunking signalling block. /// Internal helper to decode a trunking signalling block.
/// </summary> /// </summary>
/// <param name="data"></param> /// <param name="data"></param>
/// <param name="tsbk"></param> /// <param name="payload"></param>
/// <param name="rawTSBK"></param> /// <param name="rawTSBK"></param>
/// <returns>True, if TSBK was decoded, otherwise false.</returns> /// <returns>True, if TSBK was decoded, otherwise false.</returns>
bool TSBK::decode(const uint8_t* data, uint8_t* tsbk, bool rawTSBK) bool TSBK::decode(const uint8_t* data, uint8_t* payload, bool rawTSBK)
{ {
assert(data != nullptr); assert(data != nullptr);
assert(tsbk != nullptr); assert(payload != nullptr);
if (rawTSBK) { uint8_t tsbk[P25_TSBK_LENGTH_BYTES];
::memset(tsbk, 0x00U, P25_TSBK_LENGTH_BYTES);
if (rawTSBK)
{
::memcpy(tsbk, data, P25_TSBK_LENGTH_BYTES); ::memcpy(tsbk, data, P25_TSBK_LENGTH_BYTES);
bool ret = edac::CRC::checkCCITT162(tsbk, P25_TSBK_LENGTH_BYTES); bool ret = edac::CRC::checkCCITT162(tsbk, P25_TSBK_LENGTH_BYTES);
@ -274,6 +279,7 @@ bool TSBK::decode(const uint8_t* data, uint8_t* tsbk, bool rawTSBK)
m_lastBlock = (tsbk[0U] & 0x80U) == 0x80U; // Last Block Marker m_lastBlock = (tsbk[0U] & 0x80U) == 0x80U; // Last Block Marker
m_mfId = tsbk[1U]; // Mfg Id. m_mfId = tsbk[1U]; // Mfg Id.
::memcpy(payload, tsbk + 2U, P25_TSBK_LENGTH_BYTES - 4U);
return true; return true;
} }
@ -281,40 +287,39 @@ bool TSBK::decode(const uint8_t* data, uint8_t* tsbk, bool rawTSBK)
/// Internal helper to eecode a trunking signalling block. /// Internal helper to eecode a trunking signalling block.
/// </summary> /// </summary>
/// <param name="data"></param> /// <param name="data"></param>
/// <param name="tsbk"></param> /// <param name="payload"></param>
/// <param name="rawTSBK"></param> /// <param name="rawTSBK"></param>
/// <param name="noTrellis"></param> /// <param name="noTrellis"></param>
void TSBK::encode(uint8_t* data, const uint8_t* tsbk, bool rawTSBK, bool noTrellis) void TSBK::encode(uint8_t* data, const uint8_t* payload, bool rawTSBK, bool noTrellis)
{ {
assert(data != nullptr); assert(data != nullptr);
assert(tsbk != nullptr); assert(payload != nullptr);
uint8_t outTsbk[P25_TSBK_LENGTH_BYTES];
::memset(outTsbk, 0x00U, P25_TSBK_LENGTH_BYTES);
::memcpy(outTsbk, tsbk, P25_TSBK_LENGTH_BYTES);
outTsbk[0U] = m_lco; // LCO uint8_t tsbk[P25_TSBK_LENGTH_BYTES];
outTsbk[0U] |= (m_lastBlock) ? 0x80U : 0x00U; // Last Block Marker ::memset(tsbk, 0x00U, P25_TSBK_LENGTH_BYTES);
::memcpy(tsbk + 2U, payload, P25_TSBK_LENGTH_BYTES - 4U);
outTsbk[1U] = m_mfId; tsbk[0U] = m_lco; // LCO
tsbk[0U] |= (m_lastBlock) ? 0x80U : 0x00U; // Last Block Marker
tsbk[1U] = m_mfId; // Mfg Id.
// compute CRC-CCITT 16 // compute CRC-CCITT 16
edac::CRC::addCCITT162(outTsbk, P25_TSBK_LENGTH_BYTES); edac::CRC::addCCITT162(tsbk, P25_TSBK_LENGTH_BYTES);
if (m_verbose) { if (m_verbose) {
Utils::dump(2U, "TSBK::encode(), TSBK Value", outTsbk, P25_TSBK_LENGTH_BYTES); Utils::dump(2U, "TSBK::encode(), TSBK Value", tsbk, P25_TSBK_LENGTH_BYTES);
} }
uint8_t raw[P25_TSBK_FEC_LENGTH_BYTES]; uint8_t raw[P25_TSBK_FEC_LENGTH_BYTES];
::memset(raw, 0x00U, P25_TSBK_FEC_LENGTH_BYTES); ::memset(raw, 0x00U, P25_TSBK_FEC_LENGTH_BYTES);
// encode 1/2 rate Trellis // encode 1/2 rate Trellis
m_trellis.encode12(outTsbk, raw); m_trellis.encode12(tsbk, raw);
// are we encoding a raw TSBK? // are we encoding a raw TSBK?
if (rawTSBK) { if (rawTSBK) {
if (noTrellis) { if (noTrellis) {
::memcpy(data, outTsbk, P25_TSBK_LENGTH_BYTES); ::memcpy(data, tsbk, P25_TSBK_LENGTH_BYTES);
} }
else { else {
::memcpy(data, raw, P25_TSBK_FEC_LENGTH_BYTES); ::memcpy(data, raw, P25_TSBK_FEC_LENGTH_BYTES);

@ -160,15 +160,15 @@ namespace p25
static uint8_t* m_siteCallsign; static uint8_t* m_siteCallsign;
static SiteData m_siteData; static SiteData m_siteData;
/// <summary>Internal helper to convert TSBK bytes to a 64-bit long value.</summary> /// <summary>Internal helper to convert payload bytes to a 64-bit long value.</summary>
static ulong64_t toValue(const uint8_t* tsbk); static ulong64_t toValue(const uint8_t* payload);
/// <summary>Internal helper to convert a 64-bit long value to TSBK bytes.</summary> /// <summary>Internal helper to convert a 64-bit long value to payload bytes.</summary>
static UInt8Array fromValue(const ulong64_t tsbkValue); static UInt8Array fromValue(const ulong64_t value);
/// <summary>Internal helper to decode a trunking signalling block.</summary> /// <summary>Internal helper to decode a trunking signalling block.</summary>
bool decode(const uint8_t* data, uint8_t* tsbk, bool rawTSBK = false); bool decode(const uint8_t* data, uint8_t* payload, bool rawTSBK = false);
/// <summary>Internal helper to encode a trunking signalling block.</summary> /// <summary>Internal helper to encode a trunking signalling block.</summary>
void encode(uint8_t* data, const uint8_t* tsbk, bool rawTSBK = false, bool noTrellis = false); void encode(uint8_t* data, const uint8_t* payload, bool rawTSBK = false, bool noTrellis = false);
__PROTECTED_COPY(TSBK); __PROTECTED_COPY(TSBK);
}; };

Loading…
Cancel
Save

Powered by TurnKey Linux.