From 051fa78ba46b8ac19bfa9ceac2052ce14f47d757 Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Sat, 1 Oct 2022 14:00:52 -0400 Subject: [PATCH] refactor CSBK handling; cleanup argument names for some function calls; cleanup some misleading commenting with more descriptive comments; --- dmr/DMRDefines.h | 26 +- dmr/data/DataHeader.cpp | 18 +- dmr/data/DataHeader.h | 4 +- dmr/lc/CSBK.cpp | 607 ++++++++++++++------------------ dmr/lc/CSBK.h | 55 +-- dmr/lc/LC.cpp | 56 +-- dmr/lc/LC.h | 4 +- dmr/lc/PrivacyLC.cpp | 50 +-- dmr/lc/PrivacyLC.h | 4 +- dmr/packet/ControlSignaling.cpp | 30 +- p25/lc/LC.cpp | 6 +- p25/lc/TDULC.cpp | 4 +- p25/lc/TSBK.cpp | 6 +- 13 files changed, 407 insertions(+), 463 deletions(-) diff --git a/dmr/DMRDefines.h b/dmr/DMRDefines.h index 52dd8d71..e0f8ba79 100644 --- a/dmr/DMRDefines.h +++ b/dmr/DMRDefines.h @@ -69,6 +69,7 @@ namespace dmr const uint32_t DMR_AMBE_LENGTH_BYTES = 27U; const uint32_t DMR_LC_HEADER_LENGTH_BYTES = 12U; + const uint32_t DMR_CSBK_LENGTH_BYTES = 12U; const uint8_t BS_SOURCED_AUDIO_SYNC[] = { 0x07U, 0x55U, 0xFDU, 0x7DU, 0xF7U, 0x5FU, 0x70U }; const uint8_t BS_SOURCED_DATA_SYNC[] = { 0x0DU, 0xFFU, 0x57U, 0xD7U, 0x5DU, 0xF5U, 0xD0U }; @@ -212,6 +213,30 @@ namespace dmr const uint8_t SLCO_ACT = 0x01U; const uint8_t SLCO_TSCC = 0x02U; + // Reason Code(s) + const uint8_t TS_ACK_RSN_MSG = 0x60U; // TS - Message Accepted + const uint8_t TS_ACK_RSN_REG = 0x62U; // TS - Registration Accepted + const uint8_t TS_ACK_RSN_AUTH_RESP = 0x64U; // TS - Authentication Challenge Response + const uint8_t TS_ACK_RSN_REG_SUB_ATTACH = 0x65U; // TS - Registration Response with subscription + const uint8_t MS_ACK_RSN_MSG = 0x44U; // MS - Message Accepted + const uint8_t MS_ACK_RSN_AUTH_RESP = 0x48U; // MS - Authentication Challenge Response + + const uint8_t TS_DENY_RSN_SYS_UNSUPPORTED_SVC = 0x20U; + const uint8_t TS_DENY_RSN_PERM_USER_REFUSED = 0x21U; + const uint8_t TS_DENY_RSN_TEMP_USER_REFUSED = 0x22U; + const uint8_t TS_DENY_RSN_TRSN_SYS_REFUSED = 0x23U; + const uint8_t TS_DENY_RSN_TGT_NOT_REG = 0x24U; + const uint8_t TS_DENY_RSN_TGT_UNAVAILABLE = 0x25U; + const uint8_t TS_DENY_RSN_SYS_BUSY = 0x27U; + const uint8_t TS_DENY_RSN_SYS_NOT_READY = 0x28U; + const uint8_t TS_DENY_RSN_CALL_CNCL_REFUSED = 0x29U; + const uint8_t TS_DENY_RSN_REG_REFUSED = 0x2AU; + const uint8_t TS_DENY_RSN_REG_DENIED = 0x2BU; + const uint8_t TS_DENY_RSN_MS_NOT_REG = 0x2DU; + const uint8_t TS_DENY_RSN_TGT_GROUP_NOT_VALID = 0x2FU; + + const uint8_t MS_DENY_RSN_UNSUPPORTED_SVC = 0x00U; + // Broadcast Announcement Type(s) const uint8_t BCAST_ANNC_ANN_WD_TSCC = 0x00U; // Announce-WD TSCC Channel const uint8_t BCAST_ANNC_CALL_TIMER_PARMS = 0x01U; // Specify Call Timer Parameters @@ -238,7 +263,6 @@ namespace dmr const uint8_t CSBKO_CTCSBK = 0x07U; // CT CSBK - Channel Timing CSBK const uint8_t CSBKO_ALOHA = 0x19U; // ALOHA - Aloha PDUs for the random access protocol const uint8_t CSBKO_RAND = 0x1FU; // (ETSI) RAND - Random Access / (DMRA) CALL ALRT - Call Alert - const uint8_t CSBKO_CALL_ALRT = 0x1FU; // (ETSI) RAND - Random Access / (DMRA) CALL ALRT - Call Alert const uint8_t CSBKO_ACK_RSP = 0x20U; // ACK RSP - Acknowledge Response const uint8_t CSBKO_EXT_FNCT = 0x24U; // (DMRA) EXT FNCT - Extended Function const uint8_t CSBKO_NACK_RSP = 0x26U; // NACK RSP - Negative Acknowledgement Response diff --git a/dmr/data/DataHeader.cpp b/dmr/data/DataHeader.cpp index 641a958e..c0b1f57f 100644 --- a/dmr/data/DataHeader.cpp +++ b/dmr/data/DataHeader.cpp @@ -131,15 +131,15 @@ DataHeader& DataHeader::operator=(const DataHeader& header) /// /// Decodes a DMR data header. /// -/// +/// /// True, if DMR data header was decoded, otherwise false. -bool DataHeader::decode(const uint8_t* bytes) +bool DataHeader::decode(const uint8_t* data) { - assert(bytes != NULL); + assert(data != NULL); // decode BPTC (196,96) FEC edac::BPTC19696 bptc; - bptc.decode(bytes, m_data); + bptc.decode(data, m_data); // make sure the CRC-CCITT 16 was actually included (the network tends to zero the CRC) if (m_data[10U] != 0x00U && m_data[11U] != 0x00U) { @@ -250,10 +250,10 @@ bool DataHeader::decode(const uint8_t* bytes) /// /// Encodes a DMR data header. /// -/// -void DataHeader::encode(uint8_t* bytes) const +/// +void DataHeader::encode(uint8_t* data) const { - assert(bytes != NULL); + assert(data != NULL); // perform no processing other then regenerating FEC if (m_DPF == DPF_PROPRIETARY) { @@ -271,7 +271,7 @@ void DataHeader::encode(uint8_t* bytes) const // encode BPTC (196,96) FEC edac::BPTC19696 bptc; - bptc.encode(m_data, bytes); + bptc.encode(m_data, data); return; } else { @@ -383,5 +383,5 @@ void DataHeader::encode(uint8_t* bytes) const // encode BPTC (196,96) FEC edac::BPTC19696 bptc; - bptc.encode(m_data, bytes); + bptc.encode(m_data, data); } diff --git a/dmr/data/DataHeader.h b/dmr/data/DataHeader.h index 3ab1d3ab..6779340d 100644 --- a/dmr/data/DataHeader.h +++ b/dmr/data/DataHeader.h @@ -53,9 +53,9 @@ namespace dmr DataHeader& operator=(const DataHeader& header); /// Decodes a DMR data header. - bool decode(const uint8_t* bytes); + bool decode(const uint8_t* data); /// Encodes a DMR data header. - void encode(uint8_t* bytes) const; + void encode(uint8_t* data) const; public: /// Flag indicating whether the CSBK is group or individual. diff --git a/dmr/lc/CSBK.cpp b/dmr/lc/CSBK.cpp index 46587280..9f3b75ef 100644 --- a/dmr/lc/CSBK.cpp +++ b/dmr/lc/CSBK.cpp @@ -73,128 +73,125 @@ CSBK::CSBK(SiteData siteData, lookups::IdenTable entry, bool verbose) : CSBK(sit /// CSBK::~CSBK() { - delete[] m_data; + /* stub */ } /// /// Decodes a DMR CSBK. /// -/// +/// /// True, if DMR CSBK was decoded, otherwise false. -bool CSBK::decode(const uint8_t* bytes) +bool CSBK::decode(const uint8_t* data) { - assert(bytes != NULL); + assert(data != NULL); + + uint8_t csbk[DMR_CSBK_LENGTH_BYTES]; // decode BPTC (196,96) FEC edac::BPTC19696 bptc; - bptc.decode(bytes, m_data); + bptc.decode(data, csbk); // validate the CRC-CCITT 16 - m_data[10U] ^= CSBK_CRC_MASK[0U]; - m_data[11U] ^= CSBK_CRC_MASK[1U]; + csbk[10U] ^= CSBK_CRC_MASK[0U]; + csbk[11U] ^= CSBK_CRC_MASK[1U]; - bool valid = edac::CRC::checkCCITT162(m_data, DMR_LC_HEADER_LENGTH_BYTES); + bool valid = edac::CRC::checkCCITT162(csbk, DMR_CSBK_LENGTH_BYTES); if (!valid) { LogError(LOG_DMR, "CSBK::decode(), failed CRC CCITT-162 check"); return false; } // restore the checksum - m_data[10U] ^= CSBK_CRC_MASK[0U]; - m_data[11U] ^= CSBK_CRC_MASK[1U]; + csbk[10U] ^= CSBK_CRC_MASK[0U]; + csbk[11U] ^= CSBK_CRC_MASK[1U]; if (m_verbose) { - Utils::dump(2U, "Decoded CSBK", m_data, DMR_LC_HEADER_LENGTH_BYTES); + Utils::dump(2U, "Decoded CSBK", csbk, DMR_CSBK_LENGTH_BYTES); } - m_CSBKO = m_data[0U] & 0x3FU; // CSBKO - m_lastBlock = (m_data[0U] & 0x80U) == 0x80U; // Last Block Marker - m_FID = m_data[1U]; // Feature ID + m_CSBKO = csbk[0U] & 0x3FU; // CSBKO + m_lastBlock = (csbk[0U] & 0x80U) == 0x80U; // Last Block Marker + m_FID = csbk[1U]; // Feature ID + + m_dataContent = false; + m_CBF = 0U; + + ulong64_t csbkValue = 0U; + + // combine bytes into ulong64_t (8 byte) value + csbkValue = csbk[2U]; + csbkValue = (csbkValue << 8) + csbk[3U]; + csbkValue = (csbkValue << 8) + csbk[4U]; + csbkValue = (csbkValue << 8) + csbk[5U]; + csbkValue = (csbkValue << 8) + csbk[6U]; + csbkValue = (csbkValue << 8) + csbk[7U]; + csbkValue = (csbkValue << 8) + csbk[8U]; + csbkValue = (csbkValue << 8) + csbk[9U]; switch (m_CSBKO) { case CSBKO_BSDWNACT: - m_GI = false; - m_bsId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U]; // Base Station ID - m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U]; // Source ID - m_dataContent = false; - m_CBF = 0U; + m_bsId = (uint32_t)((csbkValue >> 24) & 0xFFFFFFU); // Base Station Address + m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address break; - case CSBKO_UU_V_REQ: - m_GI = false; - m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U]; // Destination ID - m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U]; // Source ID - m_dataContent = false; - m_CBF = 0U; + m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Target Radio Address + m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address break; - case CSBKO_UU_ANS_RSP: - m_GI = false; - m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U]; // Destination ID - m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U]; // Source ID - m_dataContent = false; - m_CBF = 0U; + m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Target Radio Address + m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address break; - case CSBKO_PRECCSBK: - m_GI = (m_data[2U] & 0x40U) == 0x40U; - m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U]; // Destination ID - m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U]; // Source ID - m_dataContent = (m_data[2U] & 0x80U) == 0x80U; - m_CBF = m_data[3U]; + m_GI = (((csbkValue >> 56) & 0xFFU) & 0x40U) == 0x40U; // Group/Individual Flag + m_dataContent = (((csbkValue >> 56) & 0xFFU) & 0x80U) == 0x80U; // + m_CBF = (uint8_t)((csbkValue >> 48) & 0xFFU); // Blocks to Follow + m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Target Radio Address + m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address break; - case CSBKO_RAND: // CSBKO_CALL_ALRT when FID == FID_DMRA switch (m_FID) { case FID_DMRA: - m_GI = (m_data[2U] & 0x40U) == 0x40U; // Group or Individual - m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U]; // Destination ID - m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U]; // Source ID - m_dataContent = (m_data[2U] & 0x80U) == 0x80U; // - m_CBF = m_data[3U]; // + m_GI = (((csbkValue >> 56) & 0xFFU) & 0x40U) == 0x40U; // Group/Individual Flag + m_dataContent = (((csbkValue >> 56) & 0xFFU) & 0x80U) == 0x80U; // + m_CBF = (uint8_t)((csbkValue >> 48) & 0xFFU); // Blocks to Follow + m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Target Radio Address + m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address break; - - /* Tier III */ case FID_ETSI: default: - m_serviceOptions = m_data[2U]; // Service Options - m_targetAddress = (m_data[3U] >> 6 & 0x03U); // Target Address - m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U]; // Destination ID - m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U]; // Source ID + m_emergency = (((csbkValue >> 56) & 0xFFU) & 0x80U) == 0x80U; // Emergency Flag + m_privacy = (((csbkValue >> 56) & 0xFFU) & 0x40U) == 0x40U; // Privacy Flag + m_supplementData = (((csbkValue >> 56) & 0xFFU) & 0x20U) == 0x20U; // Supplementary Data Flag + m_broadcast = (((csbkValue >> 56) & 0xFFU) & 0x10U) == 0x10U; // Broadcast Flag + m_priority = (((csbkValue >> 56) & 0xFFU) & 0x03U); // Priority + m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Target Radio Address + m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address break; } - - case CSBKO_ACK_RSP: - m_GI = (m_data[2U] & 0x40U) == 0x40U; - m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U]; // Destination ID - m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U]; // Source ID - m_response = m_data[3U]; // Response - m_dataContent = false; - break; - case CSBKO_EXT_FNCT: - m_GI = false; - m_dstId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U]; // Destination ID - m_srcId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U]; // Source ID - m_dataContent = (m_data[2U] & 0x80U) == 0x80U; // - m_CBF = m_data[3U]; // + m_dataContent = (((csbkValue >> 56) & 0xFFU) & 0x80U) == 0x80U; // + m_CBF = (uint8_t)((csbkValue >> 48) & 0xFFU); // Blocks to Follow + m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Target Radio Address + m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address break; - case CSBKO_NACK_RSP: - m_GI = false; - m_srcId = m_data[4U] << 16 | m_data[5U] << 8 | m_data[6U]; // Source ID - m_dstId = m_data[7U] << 16 | m_data[8U] << 8 | m_data[9U]; // Destination ID - m_response = m_data[3U]; // Response - m_dataContent = false; + m_GI = (((csbkValue >> 56) & 0xFFU) & 0x40U) == 0x40U; // Group/Individual Flag + m_serviceType = (((csbkValue >> 56) & 0xFFU) & 0x3FU); // Service Type + m_reason = (uint8_t)((csbkValue >> 48) & 0xFFU); // Reason Code + m_srcId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Source Radio Address + m_dstId = (uint32_t)(csbkValue & 0xFFFFFFU); // Target Radio Address + break; + + /** Tier 3 */ + case CSBKO_ACK_RSP: + m_GI = (((csbkValue >> 56) & 0xFFU) & 0x40U) == 0x40U; // Group/Individual Flag + m_reason = (uint8_t)((csbkValue >> 33) & 0xFFU); // Reason Code + m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Target Radio Address + m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address break; default: - m_GI = false; - m_srcId = 0U; - m_dstId = 0U; - m_dataContent = false; - m_CBF = 0U; LogError(LOG_DMR, "CSBK::decode(), unknown CSBK type, csbko = $%02X", m_CSBKO); return true; } @@ -205,261 +202,182 @@ bool CSBK::decode(const uint8_t* bytes) /// /// Encodes a DMR CSBK. /// -/// -void CSBK::encode(uint8_t* bytes) +/// +void CSBK::encode(uint8_t* data) { - assert(bytes != NULL); + assert(data != NULL); - m_data[0U] = m_CSBKO; // CSBKO - m_data[0U] |= (m_lastBlock) ? 0x80U : 0x00U; // Last Block Marker + uint8_t csbk[DMR_CSBK_LENGTH_BYTES]; + ::memset(csbk, 0x00U, DMR_CSBK_LENGTH_BYTES); + + ulong64_t csbkValue = 0U; + csbk[0U] = m_CSBKO; // CSBKO + csbk[0U] |= (m_lastBlock) ? 0x80U : 0x00U; // Last Block Marker if (!m_Cdef) { - m_data[1U] = m_FID; // Feature ID + csbk[1U] = m_FID; // Feature ID } else { - m_data[1U] = m_colorCode & 0x0FU; // Cdef uses Color Code + csbk[1U] = m_colorCode & 0x0FU; // Cdef uses Color Code } switch (m_CSBKO) { - case CSBKO_ACK_RSP: - m_data[2U] = (uint8_t)(m_serviceType & 0x3FU); // Service Type - m_data[2U] |= 0x80U; // Additional Information Field (always 1) - if (m_GI) { - m_data[2U] |= 0x40U; // Source Type - } - m_data[3U] = m_response; // Reason Code - - m_data[4U] = (m_srcId >> 16) & 0xFFU; // Source ID - m_data[5U] = (m_srcId >> 8) & 0xFFU; - m_data[6U] = (m_srcId >> 0) & 0xFFU; - - m_data[7U] = (m_dstId >> 16) & 0xFFU; // Destination ID - m_data[8U] = (m_dstId >> 8) & 0xFFU; - m_data[9U] = (m_dstId >> 0) & 0xFFU; - break; - case CSBKO_EXT_FNCT: - if (m_GI) { - m_data[2U] |= 0x40U; // Group or Individual - } - - if (m_dataContent) { - m_data[2U] |= 0x80U; // - } - - m_data[3U] = m_CBF; // - - m_data[4U] = (m_srcId >> 16) & 0xFFU; // Source ID - m_data[5U] = (m_srcId >> 8) & 0xFFU; - m_data[6U] = (m_srcId >> 0) & 0xFFU; - - m_data[7U] = (m_dstId >> 16) & 0xFFU; // Destination ID - m_data[8U] = (m_dstId >> 8) & 0xFFU; - m_data[9U] = (m_dstId >> 0) & 0xFFU; + csbkValue = + (m_GI ? 0x40U : 0x00U) + // Group or Invididual + (m_dataContent ? 0x80U : 0x00U); + csbkValue = (csbkValue << 8) + m_CBF; // Blocks to Follow + csbkValue = (csbkValue << 24) + m_srcId; // Source Radio Address + csbkValue = (csbkValue << 24) + m_dstId; // Target Radio Address break; case CSBKO_NACK_RSP: - m_data[2U] = (uint8_t)(m_serviceType & 0x3FU); // Service Type - m_data[2U] |= 0x80U; // Additional Information Field (always 1) - if (m_GI) { - m_data[2U] |= 0x40U; // Source Type - } - m_data[3U] = m_response; // Reason Code - - m_data[4U] = (m_srcId >> 16) & 0xFFU; // Source ID - m_data[5U] = (m_srcId >> 8) & 0xFFU; - m_data[6U] = (m_srcId >> 0) & 0xFFU; - - m_data[7U] = (m_dstId >> 16) & 0xFFU; // Destination ID - m_data[8U] = (m_dstId >> 8) & 0xFFU; - m_data[9U] = (m_dstId >> 0) & 0xFFU; + csbkValue = 0x80U + // Additional Information Field (always 1) + (m_GI ? 0x40U : 0x00U) + // Source Type + (m_serviceType & 0x3FU); // Service Type + csbkValue = (csbkValue << 8) + m_reason; // Reason Code + csbkValue = (csbkValue << 24) + m_srcId; // Source Radio Address + csbkValue = (csbkValue << 24) + m_dstId; // Target Radio Address break; /* Tier III */ - case CSBKO_ALOHA: - { - ulong64_t csbkValue = 0U; - csbkValue = (csbkValue << 2) + 0U; // Reserved - csbkValue = (csbkValue << 1) + ((m_siteTSSync) ? 1U : 0U); // Site Time Slot Synchronization - csbkValue = (csbkValue << 3) + DMR_ALOHA_VER_151; // DMR Spec. Version (1.5.1) - csbkValue = (csbkValue << 1) + ((m_siteOffsetTiming) ? 1U : 0U); // Site Timing: Aligned or Offset - csbkValue = (csbkValue << 1) + ((m_siteData.netActive()) ? 1U : 0U); // Site Networked - csbkValue = (csbkValue << 5) + (m_alohaMask & 0x1FU); // MS Mask - csbkValue = (csbkValue << 2) + 0U; // Service Function - csbkValue = (csbkValue << 4) + 0U; // - csbkValue = (csbkValue << 1) + ((m_siteData.requireReg()) ? 1U : 0U); // Require Registration - csbkValue = (csbkValue << 4) + (m_backoffNo & 0x0FU); // Backoff Number - csbkValue = (csbkValue << 16) + m_siteData.systemIdentity(); // Site Identity - csbkValue = (csbkValue << 24) + m_srcId; // Source ID - - // split value into bytes - m_data[2U] = (uint8_t)((csbkValue >> 56) & 0xFFU); - m_data[3U] = (uint8_t)((csbkValue >> 48) & 0xFFU); - m_data[4U] = (uint8_t)((csbkValue >> 40) & 0xFFU); - m_data[5U] = (uint8_t)((csbkValue >> 32) & 0xFFU); - m_data[6U] = (uint8_t)((csbkValue >> 24) & 0xFFU); - m_data[7U] = (uint8_t)((csbkValue >> 16) & 0xFFU); - m_data[8U] = (uint8_t)((csbkValue >> 8) & 0xFFU); - m_data[9U] = (uint8_t)((csbkValue >> 0) & 0xFFU); + case CSBKO_ACK_RSP: + if (m_reason == TS_ACK_RSN_REG) { + csbkValue = 0U; + } else { + csbkValue = (m_GI ? 0x40U : 0x00U) + // Source Type + (m_siteData.siteId() & 0x3FU); // Net + Site LSB } + csbkValue = (csbkValue << 7) + (m_reason & 0xFFU); // Reason Code + csbkValue = (csbkValue << 25) + m_dstId; // Target Radio Address + csbkValue = (csbkValue << 24) + m_srcId; // Source Radio Address + break; + + case CSBKO_ALOHA: + csbkValue = 0U; + csbkValue = (csbkValue << 2) + 0U; // Reserved + csbkValue = (csbkValue << 1) + ((m_siteTSSync) ? 1U : 0U); // Site Time Slot Synchronization + csbkValue = (csbkValue << 3) + DMR_ALOHA_VER_151; // DMR Spec. Version (1.5.1) + csbkValue = (csbkValue << 1) + ((m_siteOffsetTiming) ? 1U : 0U); // Site Timing: Aligned or Offset + csbkValue = (csbkValue << 1) + ((m_siteData.netActive()) ? 1U : 0U); // Site Networked + csbkValue = (csbkValue << 5) + (m_alohaMask & 0x1FU); // MS Mask + csbkValue = (csbkValue << 2) + 0U; // Service Function + csbkValue = (csbkValue << 4) + 0U; // + csbkValue = (csbkValue << 1) + ((m_siteData.requireReg()) ? 1U : 0U); // Require Registration + csbkValue = (csbkValue << 4) + (m_backoffNo & 0x0FU); // Backoff Number + csbkValue = (csbkValue << 16) + m_siteData.systemIdentity(); // Site Identity + csbkValue = (csbkValue << 24) + m_srcId; // Source Radio Address break; case CSBKO_PV_GRANT: - { - ulong64_t csbkValue = 0U; - csbkValue = (csbkValue << 12) + (m_logicalCh1 & 0xFFFU); // Logical Physical Channel 1 - csbkValue = (csbkValue << 1) + (m_slotNo & 0x3U); // Logical Slot Number - csbkValue = (csbkValue << 1) + 0U; // Reserved - csbkValue = (csbkValue << 1) + 0U; // Emergency - csbkValue = (csbkValue << 1) + ((m_siteOffsetTiming) ? 1U : 0U); // Site Timing: Aligned or Offset - csbkValue = (csbkValue << 24) + m_dstId; // Talkgroup ID - csbkValue = (csbkValue << 24) + m_srcId; // Source ID - - // split value into bytes - m_data[2U] = (uint8_t)((csbkValue >> 56) & 0xFFU); - m_data[3U] = (uint8_t)((csbkValue >> 48) & 0xFFU); - m_data[4U] = (uint8_t)((csbkValue >> 40) & 0xFFU); - m_data[5U] = (uint8_t)((csbkValue >> 32) & 0xFFU); - m_data[6U] = (uint8_t)((csbkValue >> 24) & 0xFFU); - m_data[7U] = (uint8_t)((csbkValue >> 16) & 0xFFU); - m_data[8U] = (uint8_t)((csbkValue >> 8) & 0xFFU); - m_data[9U] = (uint8_t)((csbkValue >> 0) & 0xFFU); - } + csbkValue = 0U; + csbkValue = (csbkValue << 12) + (m_logicalCh1 & 0xFFFU); // Logical Physical Channel 1 + csbkValue = (csbkValue << 1) + (m_slotNo & 0x3U); // Logical Slot Number + csbkValue = (csbkValue << 1) + 0U; // Reserved + csbkValue = (csbkValue << 1) + 0U; // Emergency + csbkValue = (csbkValue << 1) + ((m_siteOffsetTiming) ? 1U : 0U); // Site Timing: Aligned or Offset + csbkValue = (csbkValue << 24) + m_dstId; // Talkgroup ID + csbkValue = (csbkValue << 24) + m_srcId; // Source Radio Address break; case CSBKO_TV_GRANT: case CSBKO_BTV_GRANT: - { - ulong64_t csbkValue = 0U; - csbkValue = (csbkValue << 12) + (m_logicalCh1 & 0xFFFU); // Logical Physical Channel 1 - csbkValue = (csbkValue << 1) + (m_slotNo & 0x3U); // Logical Slot Number - csbkValue = (csbkValue << 1) + 0U; // Late Entry - csbkValue = (csbkValue << 1) + 0U; // Emergency - csbkValue = (csbkValue << 1) + ((m_siteOffsetTiming) ? 1U : 0U); // Site Timing: Aligned or Offset - csbkValue = (csbkValue << 24) + m_dstId; // Talkgroup ID - csbkValue = (csbkValue << 24) + m_srcId; // Source ID - - // split value into bytes - m_data[2U] = (uint8_t)((csbkValue >> 56) & 0xFFU); - m_data[3U] = (uint8_t)((csbkValue >> 48) & 0xFFU); - m_data[4U] = (uint8_t)((csbkValue >> 40) & 0xFFU); - m_data[5U] = (uint8_t)((csbkValue >> 32) & 0xFFU); - m_data[6U] = (uint8_t)((csbkValue >> 24) & 0xFFU); - m_data[7U] = (uint8_t)((csbkValue >> 16) & 0xFFU); - m_data[8U] = (uint8_t)((csbkValue >> 8) & 0xFFU); - m_data[9U] = (uint8_t)((csbkValue >> 0) & 0xFFU); - } + csbkValue = 0U; + csbkValue = (csbkValue << 12) + (m_logicalCh1 & 0xFFFU); // Logical Physical Channel 1 + csbkValue = (csbkValue << 1) + (m_slotNo & 0x3U); // Logical Slot Number + csbkValue = (csbkValue << 1) + 0U; // Late Entry + csbkValue = (csbkValue << 1) + 0U; // Emergency + csbkValue = (csbkValue << 1) + ((m_siteOffsetTiming) ? 1U : 0U); // Site Timing: Aligned or Offset + csbkValue = (csbkValue << 24) + m_dstId; // Talkgroup ID + csbkValue = (csbkValue << 24) + m_srcId; // Source Radio Address break; case CSBKO_BROADCAST: - { - ulong64_t csbkValue = 0U; - if (!m_Cdef) { - csbkValue = m_anncType; // Announcement Type - } - - switch (m_anncType) - { - case BCAST_ANNC_ANN_WD_TSCC: - { - // Broadcast Parms 1 - csbkValue = (csbkValue << 4) + 0U; // Reserved - csbkValue = (csbkValue << 4) + (m_colorCode & 0x0FU); // Color Code 1 - csbkValue = (csbkValue << 4) + (m_colorCode & 0x0FU); // Color Code 2 - csbkValue = (csbkValue << 1) + ((m_annWdCh1) ? 1U : 0U); // Announce/Withdraw Channel 1 - csbkValue = (csbkValue << 1) + ((m_annWdCh2) ? 1U : 0U); // Announce/Withdraw Channel 2 - - csbkValue = (csbkValue << 1) + ((m_siteData.requireReg()) ? 1U : 0U); // Require Registration - csbkValue = (csbkValue << 4) + (m_backoffNo & 0x0FU); // Backoff Number - csbkValue = (csbkValue << 16) + m_siteData.systemIdentity(); // Site Identity - - // Broadcast Parms 2 - csbkValue = (csbkValue << 12) + (m_logicalCh1 & 0xFFFU); // Logical Channel 1 - csbkValue = (csbkValue << 12) + (m_logicalCh2 & 0xFFFU); // Logical Channel 2 - } - break; - case BCAST_ANNC_CHAN_FREQ: - { - uint32_t calcSpace = (uint32_t)(m_siteIdenEntry.chSpaceKhz() / 0.125); - float calcTxOffset = m_siteIdenEntry.txOffsetMhz() * 1000000; - const uint32_t multiple = 100000; - - // calculate Rx frequency - uint32_t rxFrequency = (uint32_t)((m_siteIdenEntry.baseFrequency() + ((calcSpace * 125) * m_logicalCh1)) + calcTxOffset); - - // generate frequency in mhz - uint32_t rxFreqMhz = rxFrequency + multiple / 2; - rxFreqMhz -= rxFreqMhz % multiple; - rxFreqMhz /= multiple * 10; - - // generate khz offset - uint32_t rxFreqKhz = rxFrequency - (rxFreqMhz * 1000000); - - // calculate Tx Frequency - uint32_t txFrequency = (uint32_t)((m_siteIdenEntry.baseFrequency() + ((calcSpace * 125) * m_logicalCh1))); - - // generate frequency in mhz - uint32_t txFreqMhz = txFrequency + multiple / 2; - txFreqMhz -= txFreqMhz % multiple; - txFreqMhz /= multiple * 10; - - // generate khz offset - uint32_t txFreqKhz = txFrequency - (txFreqMhz * 1000000); - - csbkValue = 0U; // Cdef Type (always 0 for ANN_WD_TSCC) - csbkValue = (csbkValue << 2) + 0U; // Reserved - csbkValue = (csbkValue << 12) + (m_logicalCh1 & 0xFFFU); // Logical Channel - csbkValue = (csbkValue << 10) + (txFreqMhz & 0x7FFU); // Transmit Freq Mhz - csbkValue = (csbkValue << 13) + (txFreqKhz & 0x3FFFU); // Transmit Freq Offset Khz - csbkValue = (csbkValue << 10) + (rxFreqMhz & 0x7FFU); // Receive Freq Mhz - csbkValue = (csbkValue << 13) + (rxFreqKhz & 0x3FFFU); // Receive Freq Khz - } - break; - case BCAST_ANNC_SITE_PARMS: - { - // Broadcast Parms 1 - csbkValue = (csbkValue << 14) + m_siteData.systemIdentity(true); // Site Identity (Broadcast Parms 1) - - csbkValue = (csbkValue << 1) + ((m_siteData.requireReg()) ? 1U : 0U); // Require Registration - csbkValue = (csbkValue << 4) + (m_backoffNo & 0x0FU); // Backoff Number - csbkValue = (csbkValue << 16) + m_siteData.systemIdentity(); // Site Identity - - // Broadcast Parms 2 - csbkValue = (csbkValue << 1) + 0U; // Roaming TG Subscription/Attach - csbkValue = (csbkValue << 1) + ((m_hibernating) ? 1U : 0U); // TSCC Hibernating - csbkValue = (csbkValue << 22) + 0U; // Broadcast Parms 2 (Reserved) - } - } - - // split value into bytes - m_data[2U] = (uint8_t)((csbkValue >> 56) & 0xFFU); - m_data[3U] = (uint8_t)((csbkValue >> 48) & 0xFFU); - m_data[4U] = (uint8_t)((csbkValue >> 40) & 0xFFU); - m_data[5U] = (uint8_t)((csbkValue >> 32) & 0xFFU); - m_data[6U] = (uint8_t)((csbkValue >> 24) & 0xFFU); - m_data[7U] = (uint8_t)((csbkValue >> 16) & 0xFFU); - m_data[8U] = (uint8_t)((csbkValue >> 8) & 0xFFU); - m_data[9U] = (uint8_t)((csbkValue >> 0) & 0xFFU); + { + csbkValue = 0U; + if (!m_Cdef) { + csbkValue = m_anncType; // Announcement Type } - break; - default: - if (m_GI) { - m_data[2U] |= 0x40U; // Group or Individual + switch (m_anncType) + { + case BCAST_ANNC_ANN_WD_TSCC: + // Broadcast Parms 1 + csbkValue = (csbkValue << 4) + 0U; // Reserved + csbkValue = (csbkValue << 4) + (m_colorCode & 0x0FU); // Color Code 1 + csbkValue = (csbkValue << 4) + (m_colorCode & 0x0FU); // Color Code 2 + csbkValue = (csbkValue << 1) + ((m_annWdCh1) ? 1U : 0U); // Announce/Withdraw Channel 1 + csbkValue = (csbkValue << 1) + ((m_annWdCh2) ? 1U : 0U); // Announce/Withdraw Channel 2 + + csbkValue = (csbkValue << 1) + ((m_siteData.requireReg()) ? 1U : 0U); // Require Registration + csbkValue = (csbkValue << 4) + (m_backoffNo & 0x0FU); // Backoff Number + csbkValue = (csbkValue << 16) + m_siteData.systemIdentity(); // Site Identity + + // Broadcast Parms 2 + csbkValue = (csbkValue << 12) + (m_logicalCh1 & 0xFFFU); // Logical Channel 1 + csbkValue = (csbkValue << 12) + (m_logicalCh2 & 0xFFFU); // Logical Channel 2 + break; + case BCAST_ANNC_CHAN_FREQ: + { + uint32_t calcSpace = (uint32_t)(m_siteIdenEntry.chSpaceKhz() / 0.125); + float calcTxOffset = m_siteIdenEntry.txOffsetMhz() * 1000000; + const uint32_t multiple = 100000; + + // calculate Rx frequency + uint32_t rxFrequency = (uint32_t)((m_siteIdenEntry.baseFrequency() + ((calcSpace * 125) * m_logicalCh1)) + calcTxOffset); + + // generate frequency in mhz + uint32_t rxFreqMhz = rxFrequency + multiple / 2; + rxFreqMhz -= rxFreqMhz % multiple; + rxFreqMhz /= multiple * 10; + + // generate khz offset + uint32_t rxFreqKhz = rxFrequency - (rxFreqMhz * 1000000); + + // calculate Tx Frequency + uint32_t txFrequency = (uint32_t)((m_siteIdenEntry.baseFrequency() + ((calcSpace * 125) * m_logicalCh1))); + + // generate frequency in mhz + uint32_t txFreqMhz = txFrequency + multiple / 2; + txFreqMhz -= txFreqMhz % multiple; + txFreqMhz /= multiple * 10; + + // generate khz offset + uint32_t txFreqKhz = txFrequency - (txFreqMhz * 1000000); + + csbkValue = 0U; // Cdef Type (always 0 for ANN_WD_TSCC) + csbkValue = (csbkValue << 2) + 0U; // Reserved + csbkValue = (csbkValue << 12) + (m_logicalCh1 & 0xFFFU); // Logical Channel + csbkValue = (csbkValue << 10) + (txFreqMhz & 0x7FFU); // Transmit Freq Mhz + csbkValue = (csbkValue << 13) + (txFreqKhz & 0x3FFFU); // Transmit Freq Offset Khz + csbkValue = (csbkValue << 10) + (rxFreqMhz & 0x7FFU); // Receive Freq Mhz + csbkValue = (csbkValue << 13) + (rxFreqKhz & 0x3FFFU); // Receive Freq Khz } - - if (m_dataContent) { - m_data[2U] |= 0x80U; // + break; + case BCAST_ANNC_SITE_PARMS: + // Broadcast Parms 1 + csbkValue = (csbkValue << 14) + m_siteData.systemIdentity(true); // Site Identity (Broadcast Parms 1) + + csbkValue = (csbkValue << 1) + ((m_siteData.requireReg()) ? 1U : 0U); // Require Registration + csbkValue = (csbkValue << 4) + (m_backoffNo & 0x0FU); // Backoff Number + csbkValue = (csbkValue << 16) + m_siteData.systemIdentity(); // Site Identity + + // Broadcast Parms 2 + csbkValue = (csbkValue << 1) + 0U; // Roaming TG Subscription/Attach + csbkValue = (csbkValue << 1) + ((m_hibernating) ? 1U : 0U); // TSCC Hibernating + csbkValue = (csbkValue << 22) + 0U; // Broadcast Parms 2 (Reserved) + break; } + } + break; - m_data[3U] = m_CBF; // - - m_data[4U] = (m_dstId >> 16) & 0xFFU; // Destination ID - m_data[5U] = (m_dstId >> 8) & 0xFFU; - m_data[6U] = (m_dstId >> 0) & 0xFFU; + default: + csbkValue = + (m_GI ? 0x40U : 0x00U) + // Group or Invididual + (m_dataContent ? 0x80U : 0x00U); + csbkValue = (csbkValue << 8) + m_CBF; // Blocks to Follow + csbkValue = (csbkValue << 24) + m_srcId; // Source Radio Address + csbkValue = (csbkValue << 24) + m_dstId; // Target Radio Address - m_data[7U] = (m_srcId >> 16) & 0xFFU; // Source ID - m_data[8U] = (m_srcId >> 8) & 0xFFU; - m_data[9U] = (m_srcId >> 0) & 0xFFU; if ((m_FID == FID_ETSI) || (m_FID == FID_DMRA)) { LogError(LOG_DMR, "CSBK::encode(), unknown CSBK type, csbko = $%02X", m_CSBKO); } @@ -470,65 +388,52 @@ void CSBK::encode(uint8_t* bytes) if (m_FID == FID_DVM) { switch (m_CSBKO) { case CSBKO_DVM_GIT_HASH: - { - ulong64_t csbkValue = 0U; - csbkValue = g_gitHashBytes[0]; // ... - csbkValue = (csbkValue << 8) + (g_gitHashBytes[1U]); // ... - csbkValue = (csbkValue << 8) + (g_gitHashBytes[2U]); // ... - csbkValue = (csbkValue << 8) + (g_gitHashBytes[3U]); // ... - csbkValue = (csbkValue << 16) + 0U; - csbkValue = (csbkValue << 4) + m_siteIdenEntry.channelId(); // Channel ID - csbkValue = (csbkValue << 12) + m_logicalCh1; // Channel Number - - // split value into bytes - m_data[2U] = (uint8_t)((csbkValue >> 56) & 0xFFU); - m_data[3U] = (uint8_t)((csbkValue >> 48) & 0xFFU); - m_data[4U] = (uint8_t)((csbkValue >> 40) & 0xFFU); - m_data[5U] = (uint8_t)((csbkValue >> 32) & 0xFFU); - m_data[6U] = (uint8_t)((csbkValue >> 24) & 0xFFU); - m_data[7U] = (uint8_t)((csbkValue >> 16) & 0xFFU); - m_data[8U] = (uint8_t)((csbkValue >> 8) & 0xFFU); - m_data[9U] = (uint8_t)((csbkValue >> 0) & 0xFFU); - } + csbkValue = 0U; + csbkValue = g_gitHashBytes[0]; // ... + csbkValue = (csbkValue << 8) + (g_gitHashBytes[1U]); // ... + csbkValue = (csbkValue << 8) + (g_gitHashBytes[2U]); // ... + csbkValue = (csbkValue << 8) + (g_gitHashBytes[3U]); // ... + csbkValue = (csbkValue << 16) + 0U; + csbkValue = (csbkValue << 4) + m_siteIdenEntry.channelId(); // Channel ID + csbkValue = (csbkValue << 12) + m_logicalCh1; // Channel Number break; default: - if (m_GI) { - m_data[2U] |= 0x40U; // Group or Individual - } - - if (m_dataContent) { - m_data[2U] |= 0x80U; // - } - - m_data[3U] = m_CBF; // - - m_data[4U] = (m_dstId >> 16) & 0xFFU; // Destination ID - m_data[5U] = (m_dstId >> 8) & 0xFFU; - m_data[6U] = (m_dstId >> 0) & 0xFFU; - - m_data[7U] = (m_srcId >> 16) & 0xFFU; // Source ID - m_data[8U] = (m_srcId >> 8) & 0xFFU; - m_data[9U] = (m_srcId >> 0) & 0xFFU; + csbkValue = + (m_GI ? 0x40U : 0x00U) + // Group or Invididual + (m_dataContent ? 0x80U : 0x00U); + csbkValue = (csbkValue << 8) + m_CBF; // Blocks to Follow + csbkValue = (csbkValue << 24) + m_srcId; // Source Radio Address + csbkValue = (csbkValue << 24) + m_dstId; // Target Radio Address LogError(LOG_DMR, "CSBK::encode(), unknown CSBK type, csbko = $%02X", m_CSBKO); break; } } - m_data[10U] ^= CSBK_CRC_MASK[0U]; - m_data[11U] ^= CSBK_CRC_MASK[1U]; + // split ulong64_t (8 byte) value into bytes + csbk[2U] = (uint8_t)((csbkValue >> 56) & 0xFFU); + csbk[3U] = (uint8_t)((csbkValue >> 48) & 0xFFU); + csbk[4U] = (uint8_t)((csbkValue >> 40) & 0xFFU); + csbk[5U] = (uint8_t)((csbkValue >> 32) & 0xFFU); + csbk[6U] = (uint8_t)((csbkValue >> 24) & 0xFFU); + csbk[7U] = (uint8_t)((csbkValue >> 16) & 0xFFU); + csbk[8U] = (uint8_t)((csbkValue >> 8) & 0xFFU); + csbk[9U] = (uint8_t)((csbkValue >> 0) & 0xFFU); + + csbk[10U] ^= CSBK_CRC_MASK[0U]; + csbk[11U] ^= CSBK_CRC_MASK[1U]; - edac::CRC::addCCITT162(m_data, 12U); + edac::CRC::addCCITT162(csbk, 12U); - m_data[10U] ^= CSBK_CRC_MASK[0U]; - m_data[11U] ^= CSBK_CRC_MASK[1U]; + csbk[10U] ^= CSBK_CRC_MASK[0U]; + csbk[11U] ^= CSBK_CRC_MASK[1U]; if (m_verbose) { - Utils::dump(2U, "Encoded CSBK", m_data, DMR_LC_HEADER_LENGTH_BYTES); + Utils::dump(2U, "Encoded CSBK", csbk, DMR_CSBK_LENGTH_BYTES); } // encode BPTC (196,96) FEC edac::BPTC19696 bptc; - bptc.encode(m_data, bytes); + bptc.encode(csbk, data); } // --------------------------------------------------------------------------- @@ -541,22 +446,27 @@ void CSBK::encode(uint8_t* bytes) /// CSBK::CSBK(SiteData siteData) : m_verbose(false), + m_colorCode(0U), + m_lastBlock(true), + m_Cdef(false), m_CSBKO(CSBKO_NONE), m_FID(0x00U), - m_lastBlock(true), - m_bsId(0U), m_GI(false), - m_Cdef(false), + m_bsId(0U), m_srcId(0U), m_dstId(0U), m_dataContent(false), m_CBF(0U), - m_colorCode(0U), + m_emergency(false), + m_privacy(false), + m_supplementData(false), + m_priority(0U), + m_broadcast(false), m_backoffNo(1U), m_serviceType(0U), - m_serviceOptions(0U), m_targetAddress(TGT_ADRS_TGID), m_response(0U), + m_reason(0U), m_anncType(BCAST_ANNC_SITE_PARMS), m_hibernating(false), m_annWdCh1(false), @@ -568,8 +478,7 @@ CSBK::CSBK(SiteData siteData) : m_siteOffsetTiming(false), m_alohaMask(0U), m_siteData(siteData), - m_siteIdenEntry(lookups::IdenTable()), - m_data(NULL) + m_siteIdenEntry(lookups::IdenTable()) { - m_data = new uint8_t[12U]; + /* stub */ } diff --git a/dmr/lc/CSBK.h b/dmr/lc/CSBK.h index 7f98ebfe..b5170e3d 100644 --- a/dmr/lc/CSBK.h +++ b/dmr/lc/CSBK.h @@ -55,34 +55,33 @@ namespace dmr ~CSBK(); /// Decodes a DMR CSBK. - bool decode(const uint8_t* bytes); + bool decode(const uint8_t* data); /// Encodes a DMR CSBK. - void encode(uint8_t* bytes); + void encode(uint8_t* data); public: /// Flag indicating verbose log output. __PROPERTY(bool, verbose, Verbose); - // Generic fields - /// CSBK opcode. - __PROPERTY(uint8_t, CSBKO, CSBKO); - /// CSBK feature ID. - __PROPERTY(uint8_t, FID, FID); + /// DMR access color code. + __PROPERTY(uint8_t, colorCode, ColorCode); + /** Common Data */ /// Flag indicating this is the last TSBK in a sequence of TSBKs. __PROPERTY(bool, lastBlock, LastBlock); + /// Flag indicating whether the CSBK is a Cdef block. + __PROPERTY(bool, Cdef, Cdef); - // For BS Dwn Act - __READONLY_PROPERTY(uint32_t, bsId, BSId); + /// CSBK opcode. + __PROPERTY(uint8_t, CSBKO, CSBKO); + /// CSBK feature ID. + __PROPERTY(uint8_t, FID, FID); - // For Pre /// Flag indicating whether the CSBK is group or individual. __PROPERTY(bool, GI, GI); - // For Cdef blocks - /// Flag indicating whether the CSBK is a Cdef block. - __PROPERTY(bool, Cdef, Cdef); - + /// Base Station ID. + __READONLY_PROPERTY(uint32_t, bsId, BSId); /// Source ID. __PROPERTY(uint32_t, srcId, SrcId); /// Destination ID. @@ -91,25 +90,35 @@ namespace dmr /// __READONLY_PROPERTY(bool, dataContent, DataContent); - /// Sets the number of blocks to follow. + /// Number of blocks to follow. __PROPERTY(uint8_t, CBF, CBF); - /// DMR access color code. - __PROPERTY(uint8_t, colorCode, ColorCode); - - // Tier III + /** Service Options */ + /// Flag indicating the emergency bits are set. + __PROPERTY(bool, emergency, Emergency); + /// Flag indicating that privacy is enabled. + __PROPERTY(bool, privacy, Privacy); + /// Flag indicating that supplementary data is required. + __PROPERTY(bool, supplementData, SupplementData); + /// Priority level for the traffic. + __PROPERTY(uint8_t, priority, Priority); + /// Flag indicating a broadcast service. + __PROPERTY(bool, broadcast, Broadcast); + + /** Tier III */ /// Backoff Number. __PROPERTY(uint8_t, backoffNo, BackoffNo); /// Service Type. __PROPERTY(uint8_t, serviceType, serviceType); - /// Service type. - __PROPERTY(uint8_t, serviceOptions, ServiceOptions); + /// Destination/Target address type. __PROPERTY(uint8_t, targetAddress, TargetAddress); - /// Response type. + /// Response information. __PROPERTY(uint8_t, response, Response); + /// Reason type. + __PROPERTY(uint8_t, reason, reason); /// Broadcast Announcment Type. __PROPERTY(uint8_t, anncType, AnncType); @@ -144,8 +153,6 @@ namespace dmr private: /// Initializes a new instance of the CSBK class. CSBK(SiteData siteData); - - uint8_t* m_data; }; } // namespace lc } // namespace dmr diff --git a/dmr/lc/LC.cpp b/dmr/lc/LC.cpp index 67361a66..ca3ce96a 100644 --- a/dmr/lc/LC.cpp +++ b/dmr/lc/LC.cpp @@ -66,8 +66,8 @@ LC::LC(uint8_t flco, uint32_t srcId, uint32_t dstId) : /// /// Initializes a new instance of the LC class. /// -/// -LC::LC(const uint8_t* bytes) : +/// +LC::LC(const uint8_t* data) : m_PF(false), m_FLCO(FLCO_GROUP), m_FID(FID_ETSI), @@ -80,23 +80,23 @@ LC::LC(const uint8_t* bytes) : m_priority(CALL_PRIORITY_2), m_R(false) { - assert(bytes != NULL); + assert(data != NULL); - m_PF = (bytes[0U] & 0x80U) == 0x80U; - m_R = (bytes[0U] & 0x40U) == 0x40U; + m_PF = (data[0U] & 0x80U) == 0x80U; + m_R = (data[0U] & 0x40U) == 0x40U; - m_FLCO = bytes[0U] & 0x3FU; + m_FLCO = data[0U] & 0x3FU; - m_FID = bytes[1U]; + m_FID = data[1U]; - m_emergency = (bytes[2U] & 0x80U) == 0x80U; // Emergency Flag - m_encrypted = (bytes[2U] & 0x40U) == 0x40U; // Encryption Flag - m_broadcast = (bytes[2U] & 0x08U) == 0x08U; // Broadcast Flag - m_ovcm = (bytes[2U] & 0x04U) == 0x04U; // OVCM Flag - m_priority = (bytes[2U] & 0x03U); // Priority + m_emergency = (data[2U] & 0x80U) == 0x80U; // Emergency Flag + m_encrypted = (data[2U] & 0x40U) == 0x40U; // Encryption Flag + m_broadcast = (data[2U] & 0x08U) == 0x08U; // Broadcast Flag + m_ovcm = (data[2U] & 0x04U) == 0x04U; // OVCM Flag + m_priority = (data[2U] & 0x03U); // Priority - m_dstId = bytes[3U] << 16 | bytes[4U] << 8 | bytes[5U]; // Destination Address - m_srcId = bytes[6U] << 16 | bytes[7U] << 8 | bytes[8U]; // Source Address + m_dstId = data[3U] << 16 | data[4U] << 8 | data[5U]; // Destination Address + m_srcId = data[6U] << 16 | data[7U] << 8 | data[8U]; // Source Address } /// /// Initializes a new instance of the LC class. @@ -178,34 +178,34 @@ LC::~LC() /// /// /// -/// -void LC::getData(uint8_t* bytes) const +/// +void LC::getData(uint8_t* data) const { - assert(bytes != NULL); + assert(data != NULL); - bytes[0U] = (uint8_t)m_FLCO; + data[0U] = (uint8_t)m_FLCO; if (m_PF) - bytes[0U] |= 0x80U; + data[0U] |= 0x80U; if (m_R) - bytes[0U] |= 0x40U; + data[0U] |= 0x40U; - bytes[1U] = m_FID; + data[1U] = m_FID; - bytes[2U] = (m_emergency ? 0x80U : 0x00U) + // Emergency Flag + data[2U] = (m_emergency ? 0x80U : 0x00U) + // Emergency Flag (m_encrypted ? 0x40U : 0x00U) + // Encrypted Flag (m_broadcast ? 0x08U : 0x00U) + // Broadcast Flag (m_ovcm ? 0x04U : 0x00U) + // OVCM Flag (m_priority & 0x03U); // Priority - bytes[3U] = m_dstId >> 16; // Destination Address - bytes[4U] = m_dstId >> 8; // .. - bytes[5U] = m_dstId >> 0; // .. + data[3U] = m_dstId >> 16; // Destination Address + data[4U] = m_dstId >> 8; // .. + data[5U] = m_dstId >> 0; // .. - bytes[6U] = m_srcId >> 16; // Source Address - bytes[7U] = m_srcId >> 8; // .. - bytes[8U] = m_srcId >> 0; // .. + data[6U] = m_srcId >> 16; // Source Address + data[7U] = m_srcId >> 8; // .. + data[8U] = m_srcId >> 0; // .. } /// diff --git a/dmr/lc/LC.h b/dmr/lc/LC.h index 7c796e21..f07efefe 100644 --- a/dmr/lc/LC.h +++ b/dmr/lc/LC.h @@ -48,7 +48,7 @@ namespace dmr /// Initializes a new instance of the LC class. LC(uint8_t flco, uint32_t srcId, uint32_t dstId); /// Initializes a new instance of the LC class. - LC(const uint8_t* bytes); + LC(const uint8_t* data); /// Initializes a new instance of the LC class. LC(const bool* bits); /// Initializes a new instance of the LC class. @@ -57,7 +57,7 @@ namespace dmr ~LC(); /// Gets LC data as bytes. - void getData(uint8_t* bytes) const; + void getData(uint8_t* data) const; /// Gets LC data as bits. void getData(bool* bits) const; diff --git a/dmr/lc/PrivacyLC.cpp b/dmr/lc/PrivacyLC.cpp index e9b80d0c..62a9ff1d 100644 --- a/dmr/lc/PrivacyLC.cpp +++ b/dmr/lc/PrivacyLC.cpp @@ -41,8 +41,8 @@ using namespace dmr; /// /// Initializes a new instance of the PrivacyLC class. /// -/// -PrivacyLC::PrivacyLC(const uint8_t* bytes) : +/// +PrivacyLC::PrivacyLC(const uint8_t* data) : m_FID(FID_ETSI), m_dstId(0U), m_group(false), @@ -50,22 +50,22 @@ PrivacyLC::PrivacyLC(const uint8_t* bytes) : m_kId(0U), m_mi(NULL) { - assert(bytes != NULL); + assert(data != NULL); m_mi = new uint8_t[DMR_MI_LENGTH_BYTES]; - m_group = (bytes[0U] & 0x20U) == 0x20U; - m_algId = bytes[0U] & 7; // Algorithm ID + m_group = (data[0U] & 0x20U) == 0x20U; + m_algId = data[0U] & 7; // Algorithm ID - m_FID = bytes[1U]; - m_kId = bytes[2U]; + m_FID = data[1U]; + m_kId = data[2U]; - m_mi[0U] = bytes[3U]; - m_mi[1U] = bytes[4U]; - m_mi[2U] = bytes[5U]; - m_mi[3U] = bytes[6U]; + m_mi[0U] = data[3U]; + m_mi[1U] = data[4U]; + m_mi[2U] = data[5U]; + m_mi[3U] = data[6U]; - m_dstId = bytes[7U] << 16 | bytes[8U] << 8 | bytes[9U]; // Destination Address + m_dstId = data[7U] << 16 | data[8U] << 8 | data[9U]; // Destination Address } /// /// Initializes a new instance of the PrivacyLC class. @@ -138,25 +138,25 @@ PrivacyLC::~PrivacyLC() /// /// /// -/// -void PrivacyLC::getData(uint8_t* bytes) const +/// +void PrivacyLC::getData(uint8_t* data) const { - assert(bytes != NULL); + assert(data != NULL); - bytes[0U] = (m_group ? 0x20U : 0x00U) + + data[0U] = (m_group ? 0x20U : 0x00U) + (m_algId & 0x07U); // Algorithm ID - bytes[1U] = m_FID; - bytes[2U] = m_kId; + data[1U] = m_FID; + data[2U] = m_kId; - bytes[3U] = m_mi[0U]; - bytes[4U] = m_mi[1U]; - bytes[5U] = m_mi[2U]; - bytes[6U] = m_mi[3U]; + data[3U] = m_mi[0U]; + data[4U] = m_mi[1U]; + data[5U] = m_mi[2U]; + data[6U] = m_mi[3U]; - bytes[7U] = m_dstId >> 16; // Destination Address - bytes[8U] = m_dstId >> 8; // .. - bytes[9U] = m_dstId >> 0; // .. + data[7U] = m_dstId >> 16; // Destination Address + data[8U] = m_dstId >> 8; // .. + data[9U] = m_dstId >> 0; // .. } /// diff --git a/dmr/lc/PrivacyLC.h b/dmr/lc/PrivacyLC.h index 6e859da3..fa80a344 100644 --- a/dmr/lc/PrivacyLC.h +++ b/dmr/lc/PrivacyLC.h @@ -42,7 +42,7 @@ namespace dmr class HOST_SW_API PrivacyLC { public: /// Initializes a new instance of the PrivacyLC class. - PrivacyLC(const uint8_t* bytes); + PrivacyLC(const uint8_t* data); /// Initializes a new instance of the PrivacyLC class. PrivacyLC(const bool* bits); /// Initializes a new instance of the PrivacyLC class. @@ -51,7 +51,7 @@ namespace dmr ~PrivacyLC(); /// Gets LC data as bytes. - void getData(uint8_t* bytes) const; + void getData(uint8_t* data) const; /// Gets LC data as bits. void getData(bool* bits) const; diff --git a/dmr/packet/ControlSignaling.cpp b/dmr/packet/ControlSignaling.cpp index 272bb198..dcbf19dc 100644 --- a/dmr/packet/ControlSignaling.cpp +++ b/dmr/packet/ControlSignaling.cpp @@ -162,13 +162,15 @@ bool ControlSignaling::process(uint8_t* data, uint32_t len) m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId); } break; - case CSBKO_CALL_ALRT: - if (m_verbose) { - LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_CALL_ALRT (Call Alert), src = %u, dst = %s%u", - m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId); + case CSBKO_RAND: + if (csbk.getFID() == FID_DMRA) { + if (m_verbose) { + LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_CALL_ALRT (Call Alert), src = %u, dst = %s%u", + m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId); + } + + ::ActivityLog("DMR", true, "Slot %u call alert request from %u to %u", m_slot->m_slotNo, srcId, dstId); } - - ::ActivityLog("DMR", true, "Slot %u call alert request from %u to %u", m_slot->m_slotNo, srcId, dstId); break; case CSBKO_ACK_RSP: if (m_verbose) { @@ -312,13 +314,15 @@ void ControlSignaling::processNetwork(const data::Data & dmrData) m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId); } break; - case CSBKO_CALL_ALRT: - if (m_verbose) { - LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_CALL_ALRT (Call Alert), src = %u, dst = %s%u", - m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId); + case CSBKO_RAND: + if (csbk.getFID() == FID_DMRA) { + if (m_verbose) { + LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_CALL_ALRT (Call Alert), src = %u, dst = %s%u", + m_slot->m_slotNo, srcId, gi ? "TG " : "", dstId); + } + + ::ActivityLog("DMR", false, "Slot %u call alert request from %u to %u", m_slot->m_slotNo, srcId, dstId); } - - ::ActivityLog("DMR", false, "Slot %u call alert request from %u to %u", m_slot->m_slotNo, srcId, dstId); break; case CSBKO_ACK_RSP: if (m_verbose) { @@ -454,7 +458,7 @@ void ControlSignaling::writeRF_Call_Alrt(uint32_t srcId, uint32_t dstId) lc::CSBK csbk = lc::CSBK(m_slot->m_siteData, m_slot->m_idenEntry, m_slot->m_dumpCSBKData); csbk.setVerbose(m_dumpCSBKData); - csbk.setCSBKO(CSBKO_CALL_ALRT); + csbk.setCSBKO(CSBKO_RAND); csbk.setFID(FID_DMRA); csbk.setGI(false); diff --git a/p25/lc/LC.cpp b/p25/lc/LC.cpp index 7283ae48..c0896e28 100644 --- a/p25/lc/LC.cpp +++ b/p25/lc/LC.cpp @@ -185,7 +185,7 @@ bool LC::decodeHDU(const uint8_t* data) ulong64_t rsValue = 0U; - // combine bytes into rs value + // combine bytes into ulong64_t (8 byte) value rsValue = rs[12U]; rsValue = (rsValue << 8) + rs[13U]; rsValue = (rsValue << 8) + rs[14U]; @@ -562,7 +562,7 @@ bool LC::decodeLC(const uint8_t * rs) { ulong64_t rsValue = 0U; - // combine bytes into rs value + // combine bytes into ulong64_t (8 byte) value rsValue = rs[1U]; rsValue = (rsValue << 8) + rs[2U]; rsValue = (rsValue << 8) + rs[3U]; @@ -685,7 +685,7 @@ void LC::encodeLC(uint8_t * rs) break; } - // split rs value into bytes + // split ulong64_t (8 byte) value into bytes rs[1U] = (uint8_t)((rsValue >> 56) & 0xFFU); rs[2U] = (uint8_t)((rsValue >> 48) & 0xFFU); rs[3U] = (uint8_t)((rsValue >> 40) & 0xFFU); diff --git a/p25/lc/TDULC.cpp b/p25/lc/TDULC.cpp index ec13b161..5c074cb9 100644 --- a/p25/lc/TDULC.cpp +++ b/p25/lc/TDULC.cpp @@ -290,7 +290,7 @@ bool TDULC::decodeLC(const uint8_t* rs) { ulong64_t rsValue = 0U; - // combine bytes into rs value + // combine bytes into ulong64_t (8 byte) value rsValue = rs[1U]; rsValue = (rsValue << 8) + rs[2U]; rsValue = (rsValue << 8) + rs[3U]; @@ -508,7 +508,7 @@ void TDULC::encodeLC(uint8_t* rs) break; } - // split rs value into bytes + // split ulong64_t (8 byte) value into bytes rs[1U] = (uint8_t)((rsValue >> 56) & 0xFFU); rs[2U] = (uint8_t)((rsValue >> 48) & 0xFFU); rs[3U] = (uint8_t)((rsValue >> 40) & 0xFFU); diff --git a/p25/lc/TSBK.cpp b/p25/lc/TSBK.cpp index 703ee413..e686de07 100644 --- a/p25/lc/TSBK.cpp +++ b/p25/lc/TSBK.cpp @@ -193,7 +193,7 @@ bool TSBK::decodeMBT(const data::DataHeader dataHeader, const data::DataBlock* b ulong64_t tsbkValue = 0U; - // combine bytes into rs value + // combine bytes into ulong64_t (8 byte) value tsbkValue = dataHeader.getAMBTField8(); tsbkValue = (tsbkValue << 8) + dataHeader.getAMBTField9(); tsbkValue = (tsbkValue << 8) + pduUserData[0U]; @@ -544,7 +544,7 @@ bool TSBK::decode(const uint8_t* data, bool rawTSBK) ulong64_t tsbkValue = 0U; - // combine bytes into rs value + // combine bytes into ulong64_t (8 byte) value tsbkValue = tsbk[2U]; tsbkValue = (tsbkValue << 8) + tsbk[3U]; tsbkValue = (tsbkValue << 8) + tsbk[4U]; @@ -1324,7 +1324,7 @@ void TSBK::encode(uint8_t* data, bool rawTSBK, bool noTrellis) } } - // split rs value into bytes + // split ulong64_t (8 byte) value into bytes tsbk[2U] = (uint8_t)((tsbkValue >> 56) & 0xFFU); tsbk[3U] = (uint8_t)((tsbkValue >> 48) & 0xFFU); tsbk[4U] = (uint8_t)((tsbkValue >> 40) & 0xFFU);