diff --git a/dmr/lc/CSBK.cpp b/dmr/lc/CSBK.cpp index d4aa6e9e..db257321 100644 --- a/dmr/lc/CSBK.cpp +++ b/dmr/lc/CSBK.cpp @@ -134,18 +134,18 @@ bool CSBK::decode(const uint8_t* data) m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address break; case CSBKO_UU_V_REQ: - m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Target Radio Address + m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFFFU); // Target Radio Address m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address break; case CSBKO_UU_ANS_RSP: - m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Target Radio Address + m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFFFU); // Target Radio Address m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address break; case CSBKO_PRECCSBK: 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_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFFFU); // Target Radio Address m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address break; case CSBKO_RAND: // CSBKO_CALL_ALRT when FID == FID_DMRA @@ -153,33 +153,30 @@ bool CSBK::decode(const uint8_t* data) { case FID_DMRA: m_GI = (((csbkValue >> 56) & 0xFFU) & 0x40U) == 0x40U; // Group/Individual Flag - m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Target Radio Address + m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFFFU); // Target Radio Address m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address break; case FID_ETSI: default: - 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_serviceData = (uint8_t)((csbkValue >> 52U) & 0x0FU); // Service Data - m_serviceType = (uint8_t)((csbkValue >> 48U) & 0x0FU); // Service Type - m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Target Radio Address + m_serviceOptions = (uint8_t)((csbkValue >> 57U) & 0x7FU); // Service Options + m_proxy = (((csbkValue >> 56U) & 0xFF) & 0x01U) == 0x01U; // Proxy Flag + m_serviceExtra = (uint8_t)((csbkValue >> 52U) & 0x0FU); // Service Extras (content dependant on service) + m_serviceKind = (uint8_t)((csbkValue >> 48U) & 0x0FU); // Service Kind + m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFFFU); // Target Radio Address m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address break; } case CSBKO_EXT_FNCT: m_dataContent = (((csbkValue >> 56) & 0xFFU) & 0x80U) == 0x80U; // - m_serviceType = (uint8_t)((csbkValue >> 48) & 0xFFU); // Service Type - m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Target Radio Address + m_serviceKind = (uint8_t)((csbkValue >> 48) & 0xFFU); // Service Kind + m_dstId = (uint32_t)((csbkValue >> 24) & 0xFFFFFFU); // Target Radio Address m_srcId = (uint32_t)(csbkValue & 0xFFFFFFU); // Source Radio Address break; case CSBKO_NACK_RSP: m_GI = (((csbkValue >> 56) & 0xFFU) & 0x40U) == 0x40U; // Group/Individual Flag - m_serviceType = (((csbkValue >> 56) & 0xFFU) & 0x3FU); // Service Type + m_serviceKind = (((csbkValue >> 56) & 0xFFU) & 0x3FU); // Service Kind m_reason = (uint8_t)((csbkValue >> 48) & 0xFFU); // Reason Code - m_srcId = (uint32_t)((csbkValue >> 24) & 0xFFFFU); // Source Radio Address + m_srcId = (uint32_t)((csbkValue >> 24) & 0xFFFFFFU); // Source Radio Address m_dstId = (uint32_t)(csbkValue & 0xFFFFFFU); // Target Radio Address break; @@ -225,7 +222,7 @@ void CSBK::encode(uint8_t* data) csbkValue = (m_GI ? 0x40U : 0x00U) + // Group or Invididual (m_dataContent ? 0x80U : 0x00U); - csbkValue = (csbkValue << 8) + m_CBF; // Blocks to Follow + csbkValue = (csbkValue << 8) + m_serviceKind; // Service Kind csbkValue = (csbkValue << 24) + m_srcId; // Source Radio Address csbkValue = (csbkValue << 24) + m_dstId; // Target Radio Address break; @@ -233,7 +230,7 @@ void CSBK::encode(uint8_t* data) case CSBKO_NACK_RSP: csbkValue = 0x80U + // Additional Information Field (always 1) (m_GI ? 0x40U : 0x00U) + // Source Type - (m_serviceType & 0x3FU); // Service Type + (m_serviceKind & 0x3FU); // Service Kind csbkValue = (csbkValue << 8) + m_reason; // Reason Code csbkValue = (csbkValue << 24) + m_srcId; // Source Radio Address csbkValue = (csbkValue << 24) + m_dstId; // Target Radio Address @@ -462,10 +459,12 @@ CSBK::CSBK(SiteData siteData) : m_supplementData(false), m_priority(0U), m_broadcast(false), + m_proxy(false), m_backoffNo(1U), m_nRandWait(DEFAULT_NRAND_WAIT), - m_serviceData(0U), - m_serviceType(0U), + m_serviceOptions(0U), + m_serviceExtra(0U), + m_serviceKind(0U), m_targetAddress(TGT_ADRS_TGID), m_response(0U), m_reason(0U), diff --git a/dmr/lc/CSBK.h b/dmr/lc/CSBK.h index 20a0f953..80afbdc4 100644 --- a/dmr/lc/CSBK.h +++ b/dmr/lc/CSBK.h @@ -104,6 +104,8 @@ namespace dmr __PROPERTY(uint8_t, priority, Priority); /// Flag indicating a broadcast service. __PROPERTY(bool, broadcast, Broadcast); + /// Flag indicating a proxy. + __PROPERTY(bool, proxy, Proxy); /** Tier III */ /// Backoff Number. @@ -111,10 +113,12 @@ namespace dmr /// Random Access Wait Delay. __PROPERTY(uint8_t, nRandWait, NRandWait); - /// Service Data. - __PROPERTY(uint8_t, serviceData, ServiceData); - /// Service Type. - __PROPERTY(uint8_t, serviceType, ServiceType); + /// Service Options. + __PROPERTY(uint8_t, serviceOptions, ServiceOptions); + /// Service Extra Options. + __PROPERTY(uint8_t, serviceExtra, ServiceExtra); + /// Service Kind. + __PROPERTY(uint8_t, serviceKind, ServiceKind); /// Destination/Target address type. __PROPERTY(uint8_t, targetAddress, TargetAddress); diff --git a/dmr/packet/ControlSignaling.cpp b/dmr/packet/ControlSignaling.cpp index f5a1e2f4..b837933f 100644 --- a/dmr/packet/ControlSignaling.cpp +++ b/dmr/packet/ControlSignaling.cpp @@ -189,11 +189,11 @@ bool ControlSignaling::process(uint8_t* data, uint32_t len) handled = true; if (m_verbose) { - LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_RAND (Random Access), emerg = %u, prio = %u, serviceType = %02X, serviceData = %02X, srcId = %u, dstId = %u", - m_slot->m_slotNo, csbk.getEmergency(), csbk.getPriority(), csbk.getServiceType(), csbk.getServiceData(), csbk.getSrcId(), csbk.getDstId()); + LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_RAND (Random Access), emerg = %u, prio = %u, serviceKind = $%02X, serviceOptions = $%02X, serviceExtra = $%02X, srcId = %u, dstId = %u", + m_slot->m_slotNo, csbk.getEmergency(), csbk.getPriority(), csbk.getServiceKind(), csbk.getServiceOptions(), csbk.getServiceExtra(), csbk.getSrcId(), csbk.getDstId()); } - switch (csbk.getServiceType()) { + switch (csbk.getServiceKind()) { case SVC_KIND_IND_VOICE_CALL: // TODO TODO TODO break; @@ -212,10 +212,10 @@ bool ControlSignaling::process(uint8_t* data, uint32_t len) // make sure control data is supported IS_SUPPORT_CONTROL_CHECK("DT_CSBK, CSBKO_RAND (Random Access), SVC_KIND_REG_SVC (Registration Service)", SVC_KIND_REG_SVC, srcId); - writeRF_CSBK_U_Reg_Rsp(srcId); + writeRF_CSBK_U_Reg_Rsp(srcId, csbk.getServiceOptions()); break; default: - LogWarning(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_RAND (Random Access), unhandled service, serviceType = %02X", m_slot->m_slotNo, csbk.getServiceType()); + LogWarning(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_RAND (Random Access), unhandled service, serviceKind = %02X", m_slot->m_slotNo, csbk.getServiceKind()); // should we drop the CSBK and not repeat it? break; } @@ -232,11 +232,11 @@ bool ControlSignaling::process(uint8_t* data, uint32_t len) case CSBKO_EXT_FNCT: if (m_verbose) { LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_EXT_FNCT (Extended Function), op = $%02X, arg = %u, tgt = %u", - m_slot->m_slotNo, csbk.getServiceType(), dstId, srcId); + m_slot->m_slotNo, csbk.getServiceKind(), dstId, srcId); } // generate activity log entry - switch (csbk.getServiceType()) { + switch (csbk.getServiceKind()) { case DMR_EXT_FNCT_CHECK: ::ActivityLog("DMR", true, "Slot %u radio check request from %u to %u", m_slot->m_slotNo, dstId, srcId); break; @@ -256,7 +256,7 @@ bool ControlSignaling::process(uint8_t* data, uint32_t len) ::ActivityLog("DMR", true, "Slot %u radio uninhibit response from %u to %u", m_slot->m_slotNo, dstId, srcId); break; default: - LogWarning(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_EXT_FNCT (Extended Function), unhandled op, op = $%02X", m_slot->m_slotNo, csbk.getServiceType()); + LogWarning(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_EXT_FNCT (Extended Function), unhandled op, op = $%02X", m_slot->m_slotNo, csbk.getServiceKind()); break; } break; @@ -360,8 +360,8 @@ void ControlSignaling::processNetwork(const data::Data & dmrData) ::ActivityLog("DMR", false, "Slot %u call alert request from %u to %u", m_slot->m_slotNo, srcId, dstId); } else { if (m_verbose) { - LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_RAND (Random Access), emerg = %u, prio = %u, serviceType = %02X, serviceData = %02X, srcId = %u, dstId = %u", - m_slot->m_slotNo, csbk.getEmergency(), csbk.getPriority(), csbk.getServiceType(), csbk.getServiceData(), csbk.getSrcId(), csbk.getDstId()); + LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_RAND (Random Access), emerg = %u, prio = %u, serviceKind = $%02X, serviceOptions = $%02X, serviceExtra = $%02X, srcId = %u, dstId = %u", + m_slot->m_slotNo, csbk.getEmergency(), csbk.getPriority(), csbk.getServiceKind(), csbk.getServiceOptions(), csbk.getServiceExtra(), csbk.getSrcId(), csbk.getDstId()); } } break; @@ -376,11 +376,11 @@ void ControlSignaling::processNetwork(const data::Data & dmrData) case CSBKO_EXT_FNCT: if (m_verbose) { LogMessage(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_EXT_FNCT (Extended Function), op = $%02X, arg = %u, tgt = %u", - m_slot->m_slotNo, csbk.getCBF(), dstId, srcId); + m_slot->m_slotNo, csbk.getServiceKind(), dstId, srcId); } // generate activity log entry - switch (csbk.getServiceType()) { + switch (csbk.getServiceKind()) { case DMR_EXT_FNCT_CHECK: ::ActivityLog("DMR", false, "Slot %u radio check request from %u to %u", m_slot->m_slotNo, dstId, srcId); break; @@ -400,7 +400,7 @@ void ControlSignaling::processNetwork(const data::Data & dmrData) ::ActivityLog("DMR", false, "Slot %u radio uninhibit response from %u to %u", m_slot->m_slotNo, dstId, srcId); break; default: - LogWarning(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_EXT_FNCT (Extended Function), unhandled op, op = $%02X", m_slot->m_slotNo, csbk.getServiceType()); + LogWarning(LOG_NET, "DMR Slot %u, DT_CSBK, CSBKO_EXT_FNCT (Extended Function), unhandled op, op = $%02X", m_slot->m_slotNo, csbk.getServiceKind()); break; } break; @@ -635,34 +635,50 @@ void ControlSignaling::writeRF_CSBK_ACK_RSP(uint8_t reason, uint8_t service) /// Helper to write a unit registration response packet. /// /// -void ControlSignaling::writeRF_CSBK_U_Reg_Rsp(uint32_t srcId) +/// +void ControlSignaling::writeRF_CSBK_U_Reg_Rsp(uint32_t srcId, uint8_t serviceOptions) { Slot *m_tscc = m_slot->m_dmr->getTSCCSlot(); + bool dereg = (serviceOptions & 0x01U) == 0x01U; + lc::CSBK csbk = lc::CSBK(m_slot->m_siteData, m_slot->m_idenEntry, m_slot->m_dumpCSBKData); csbk.setVerbose(m_dumpCSBKData); csbk.setCSBKO(CSBKO_ACK_RSP); csbk.setFID(FID_ETSI); - csbk.setReason(TS_ACK_RSN_REG); + if (!dereg) { + if (m_verbose) { + LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_RAND (Random Access), SVC_KIND_REG_SVC (Registration Service), srcId = %u, serviceOptions = $%02X", m_tscc->m_slotNo, srcId, serviceOptions); + } - // validate the source RID - if (!acl::AccessControl::validateSrcId(srcId)) { - LogWarning(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_RAND (Random Access), SVC_KIND_REG_SVC (Registration Service), denial, RID rejection, srcId = %u", m_tscc->m_slotNo, srcId); - ::ActivityLog("DMR", true, "unit registration request from %u denied", srcId); - csbk.setReason(TS_DENY_RSN_REG_DENIED); - } + // remove dynamic unit registration table entry + m_slot->m_affiliations->unitDereg(srcId); - if (csbk.getReason() == TS_ACK_RSN_REG) { - if (m_verbose) { - LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_RAND (Random Access), SVC_KIND_REG_SVC (Registration Service), srcId = %u", m_tscc->m_slotNo, srcId); + csbk.setReason(TS_ACK_RSN_REG); + } + else + { + csbk.setReason(TS_ACK_RSN_REG); + + // validate the source RID + if (!acl::AccessControl::validateSrcId(srcId)) { + LogWarning(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_RAND (Random Access), SVC_KIND_REG_SVC (Registration Service), denial, RID rejection, srcId = %u", m_tscc->m_slotNo, srcId); + ::ActivityLog("DMR", true, "unit registration request from %u denied", srcId); + csbk.setReason(TS_DENY_RSN_REG_DENIED); } - ::ActivityLog("DMR", true, "unit registration request from %u", srcId); + if (csbk.getReason() == TS_ACK_RSN_REG) { + if (m_verbose) { + LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_RAND (Random Access), SVC_KIND_REG_SVC (Registration Service), srcId = %u, serviceOptions = $%02X", m_tscc->m_slotNo, srcId, serviceOptions); + } + + ::ActivityLog("DMR", true, "unit registration request from %u", srcId); - // update dynamic unit registration table - if (!m_slot->m_affiliations->isUnitReg(srcId)) { - m_slot->m_affiliations->unitReg(srcId); + // update dynamic unit registration table + if (!m_slot->m_affiliations->isUnitReg(srcId)) { + m_slot->m_affiliations->unitReg(srcId); + } } } @@ -681,8 +697,7 @@ void ControlSignaling::writeRF_TSCC_Aloha() LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_ALOHA (Aloha)", m_slot->m_slotNo); } - lc::CSBK csbk = lc::CSBK(m_slot->m_siteData, m_slot->m_idenEntry, m_slot->m_dumpCSBKData); - csbk.setVerbose(m_dumpCSBKData); + lc::CSBK csbk = lc::CSBK(m_slot->m_siteData, m_slot->m_idenEntry, false/*m_slot->m_dumpCSBKData*/); csbk.setCSBKO(CSBKO_ALOHA); csbk.setFID(FID_ETSI); @@ -706,9 +721,8 @@ void ControlSignaling::writeRF_TSCC_Bcast_Ann_Wd(uint32_t channelNo, bool annWd) m_slot->m_rfSeqNo = 0U; - lc::CSBK csbk = lc::CSBK(m_slot->m_siteData, m_slot->m_idenEntry, m_slot->m_dumpCSBKData); + lc::CSBK csbk = lc::CSBK(m_slot->m_siteData, m_slot->m_idenEntry, false/*m_slot->m_dumpCSBKData*/); csbk.setCdef(false); - csbk.setVerbose(m_dumpCSBKData); csbk.setCSBKO(CSBKO_BROADCAST); csbk.setFID(FID_ETSI); @@ -728,8 +742,7 @@ void ControlSignaling::writeRF_TSCC_Bcast_Sys_Parm() LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_BROADCAST (Broadcast), BCAST_ANNC_SITE_PARMS (Announce Site Parms)", m_slot->m_slotNo); } - lc::CSBK csbk = lc::CSBK(m_slot->m_siteData, m_slot->m_idenEntry, m_slot->m_dumpCSBKData); - csbk.setVerbose(m_dumpCSBKData); + lc::CSBK csbk = lc::CSBK(m_slot->m_siteData, m_slot->m_idenEntry, false/*m_slot->m_dumpCSBKData*/); csbk.setCSBKO(CSBKO_BROADCAST); csbk.setFID(FID_ETSI); @@ -747,8 +760,7 @@ void ControlSignaling::writeRF_TSCC_Git_Hash() LogMessage(LOG_RF, "DMR Slot %u, DT_CSBK, CSBKO_DVM_GIT_HASH (DVM Git Hash)", m_slot->m_slotNo); } - lc::CSBK csbk = lc::CSBK(m_slot->m_siteData, m_slot->m_idenEntry, m_slot->m_dumpCSBKData); - csbk.setVerbose(m_dumpCSBKData); + lc::CSBK csbk = lc::CSBK(m_slot->m_siteData, m_slot->m_idenEntry, false/*m_slot->m_dumpCSBKData*/); csbk.setCSBKO(CSBKO_DVM_GIT_HASH); csbk.setFID(FID_DVM); diff --git a/dmr/packet/ControlSignaling.h b/dmr/packet/ControlSignaling.h index 44c35d6c..1847342f 100644 --- a/dmr/packet/ControlSignaling.h +++ b/dmr/packet/ControlSignaling.h @@ -93,7 +93,7 @@ namespace dmr /// Helper to write a ACK RSP packet. void writeRF_CSBK_ACK_RSP(uint8_t reason, uint8_t service); /// Helper to write a unit registration response packet. - void writeRF_CSBK_U_Reg_Rsp(uint32_t srcId); + void writeRF_CSBK_U_Reg_Rsp(uint32_t srcId, uint8_t serviceOptions); /// Helper to write a TSCC Aloha broadcast packet on the RF interface. void writeRF_TSCC_Aloha();