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);