From 262eb1c76c310d709f8c3be27adabd2b080b1534 Mon Sep 17 00:00:00 2001 From: Bryan Biedenkapp Date: Wed, 13 Dec 2023 12:34:32 -0500 Subject: [PATCH] store srcId from DMR payload channel activation; implement running timer to retry payload activation until either traffic starts or the payload activation is cleared; --- src/dmr/Slot.cpp | 30 ++++++++++++++++++++++++++++- src/dmr/Slot.h | 4 +++- src/dmr/packet/ControlSignaling.cpp | 9 ++++----- src/dmr/packet/ControlSignaling.h | 2 +- src/dmr/packet/Data.cpp | 8 ++++++++ src/dmr/packet/Voice.cpp | 8 ++++++++ 6 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/dmr/Slot.cpp b/src/dmr/Slot.cpp index 84e2aeb1..a497bb00 100644 --- a/src/dmr/Slot.cpp +++ b/src/dmr/Slot.cpp @@ -165,8 +165,10 @@ Slot::Slot(uint32_t slotNo, uint32_t timeout, uint32_t tgHang, uint32_t queueSiz m_enableTSCC(false), m_dedicatedTSCC(false), m_tsccPayloadDstId(0U), + m_tsccPayloadSrcId(0U), m_tsccPayloadGroup(false), m_tsccPayloadVoice(true), + m_tsccPayloadActRetransmit(1000U, 1U), m_disableGrantSrcIdCheck(false), m_lastLateEntry(0U), m_supervisor(false), @@ -493,6 +495,15 @@ void Slot::clock() if (m_dmr->m_tsccPayloadActive) { if (m_rfState == RS_RF_LISTENING && m_netState == RS_NET_IDLE) { if (m_tsccPayloadDstId > 0U) { + if (m_tsccPayloadActRetransmit.isRunning()) { + m_tsccPayloadActRetransmit.clock(ms); + + if (m_tsccPayloadActRetransmit.hasExpired()) { + m_control->writeRF_CSBK_Payload_Activate(m_tsccPayloadDstId, m_tsccPayloadSrcId, m_tsccPayloadGroup, m_tsccPayloadVoice); + m_tsccPayloadActRetransmit.start(); + } + } + if ((m_dmr->m_tsccCnt % 2) > 0) { setShortLC(m_slotNo, m_tsccPayloadDstId, m_tsccPayloadGroup ? FLCO_GROUP : FLCO_PRIVATE, m_tsccPayloadVoice); } @@ -749,6 +760,7 @@ void Slot::setTSCC(bool enable, bool dedicated) void Slot::setTSCCActivated(uint32_t dstId, uint32_t srcId, bool group, bool voice) { m_tsccPayloadDstId = dstId; + m_tsccPayloadSrcId = srcId; m_tsccPayloadGroup = group; m_tsccPayloadVoice = voice; @@ -757,7 +769,10 @@ void Slot::setTSCCActivated(uint32_t dstId, uint32_t srcId, bool group, bool voi m_modem->writeDMRStart(true); } - m_control->writeRF_CSBK_Payload_Activate(dstId, srcId, group, voice); + m_control->writeRF_CSBK_Payload_Activate(dstId, srcId, group, voice, true); + if (m_tsccPayloadDstId != 0U && !m_tsccPayloadActRetransmit.isRunning()) { + m_tsccPayloadActRetransmit.start(); + } } /// @@ -1410,6 +1425,19 @@ void Slot::writeRF_ControlData(uint16_t frameCnt, uint8_t n) lc::CSBK::setVerbose(csbkVerbose); } +/// +/// Clears the flag indicating whether the slot is a TSCC payload slot. +/// +void Slot::clearTSCCActivated() +{ + m_tsccPayloadDstId = 0U; + m_tsccPayloadSrcId = 0U; + m_tsccPayloadGroup = false; + m_tsccPayloadVoice = true; + + m_tsccPayloadActRetransmit.stop(); +} + /// /// /// diff --git a/src/dmr/Slot.h b/src/dmr/Slot.h index 05f2603a..fff70ba4 100644 --- a/src/dmr/Slot.h +++ b/src/dmr/Slot.h @@ -218,8 +218,10 @@ namespace dmr bool m_dedicatedTSCC; uint32_t m_tsccPayloadDstId; + uint32_t m_tsccPayloadSrcId; bool m_tsccPayloadGroup; bool m_tsccPayloadVoice; + Timer m_tsccPayloadActRetransmit; bool m_disableGrantSrcIdCheck; @@ -304,7 +306,7 @@ namespace dmr void writeRF_ControlData(uint16_t frameCnt, uint8_t n); /// Clears the flag indicating whether the slot is a TSCC payload slot. - void clearTSCCActivated() { m_tsccPayloadDstId = 0U; m_tsccPayloadGroup = false; m_tsccPayloadVoice = true; } + void clearTSCCActivated(); /// Helper to set the DMR short LC. static void setShortLC(uint32_t slotNo, uint32_t id, uint8_t flco = FLCO_GROUP, bool voice = true); diff --git a/src/dmr/packet/ControlSignaling.cpp b/src/dmr/packet/ControlSignaling.cpp index 2b2670ad..1793637f 100644 --- a/src/dmr/packet/ControlSignaling.cpp +++ b/src/dmr/packet/ControlSignaling.cpp @@ -1360,7 +1360,8 @@ void ControlSignaling::writeRF_CSBK_Grant_LateEntry(uint32_t dstId, uint32_t src /// /// /// -void ControlSignaling::writeRF_CSBK_Payload_Activate(uint32_t dstId, uint32_t srcId, bool grp, bool voice) +/// +void ControlSignaling::writeRF_CSBK_Payload_Activate(uint32_t dstId, uint32_t srcId, bool grp, bool voice, bool imm) { std::unique_ptr csbk = new_unique(CSBK_P_GRANT); if (voice) { @@ -1394,10 +1395,8 @@ void ControlSignaling::writeRF_CSBK_Payload_Activate(uint32_t dstId, uint32_t sr } m_slot->setShortLC_Payload(m_slot->m_siteData, 1U); - for (int i = 0; i < 2; i++) { - writeRF_CSBK(csbk.get(), false, true); - writeRF_CSBK(csbk.get()); - } + for (uint8_t i = 0; i < 2U; i++) + writeRF_CSBK(csbk.get(), false, imm); } /// diff --git a/src/dmr/packet/ControlSignaling.h b/src/dmr/packet/ControlSignaling.h index 4c88a353..bd9f1bbc 100644 --- a/src/dmr/packet/ControlSignaling.h +++ b/src/dmr/packet/ControlSignaling.h @@ -112,7 +112,7 @@ namespace dmr /// Helper to write a TSCC late entry channel grant packet on the RF interface. void writeRF_CSBK_Grant_LateEntry(uint32_t dstId, uint32_t srcId, bool grp); /// Helper to write a payload random access to a TSCC payload channel on the RF interface. - void writeRF_CSBK_Payload_Activate(uint32_t dstId, uint32_t srcId, bool grp, bool voice); + void writeRF_CSBK_Payload_Activate(uint32_t dstId, uint32_t srcId, bool grp, bool voice, bool imm = false); /// Helper to write a TSCC Aloha broadcast packet on the RF interface. void writeRF_TSCC_Aloha(); diff --git a/src/dmr/packet/Data.cpp b/src/dmr/packet/Data.cpp index 627ff3f6..76796194 100644 --- a/src/dmr/packet/Data.cpp +++ b/src/dmr/packet/Data.cpp @@ -186,6 +186,10 @@ bool Data::process(uint8_t* data, uint32_t len) CHECK_AUTHORITATIVE(dstId); CHECK_TRAFFIC_COLLISION(dstId); + if (m_slot->m_tsccPayloadDstId != 0U && m_slot->m_tsccPayloadActRetransmit.isRunning()) { + m_slot->m_tsccPayloadActRetransmit.stop(); + } + // validate the source RID if (!acl::AccessControl::validateSrcId(srcId)) { LogWarning(LOG_RF, "DMR Slot %u, DT_DATA_HEADER denial, RID rejection, srcId = %u", m_slot->m_slotNo, srcId); @@ -407,6 +411,10 @@ void Data::processNetwork(const data::Data& dmrData) CHECK_NET_AUTHORITATIVE(dstId); CHECK_TG_HANG(dstId); + if (m_slot->m_tsccPayloadDstId != 0U && m_slot->m_tsccPayloadActRetransmit.isRunning()) { + m_slot->m_tsccPayloadActRetransmit.stop(); + } + m_slot->m_netFrames = dataHeader->getBlocks(); m_slot->m_netLC = new_unique(lc::LC, gi ? FLCO_GROUP : FLCO_PRIVATE, srcId, dstId); diff --git a/src/dmr/packet/Voice.cpp b/src/dmr/packet/Voice.cpp index 09b737e2..1c66d334 100644 --- a/src/dmr/packet/Voice.cpp +++ b/src/dmr/packet/Voice.cpp @@ -133,6 +133,10 @@ bool Voice::process(uint8_t* data, uint32_t len) CHECK_AUTHORITATIVE(dstId); CHECK_TRAFFIC_COLLISION(dstId); + if (m_slot->m_tsccPayloadDstId != 0U && m_slot->m_tsccPayloadActRetransmit.isRunning()) { + m_slot->m_tsccPayloadActRetransmit.stop(); + } + // validate source RID if (!acl::AccessControl::validateSrcId(srcId)) { if (m_slot->m_data->m_lastRejectId == 0U || m_slot->m_data->m_lastRejectId == srcId) { @@ -679,6 +683,10 @@ void Voice::processNetwork(const data::Data& dmrData) CHECK_NET_AUTHORITATIVE(dstId); CHECK_NET_TRAFFIC_COLLISION(dstId); + if (m_slot->m_tsccPayloadDstId != 0U && m_slot->m_tsccPayloadActRetransmit.isRunning()) { + m_slot->m_tsccPayloadActRetransmit.stop(); + } + if (dstId != dmrData.getDstId() || srcId != dmrData.getSrcId() || flco != dmrData.getFLCO()) LogWarning(LOG_NET, "DMR Slot %u, DT_VOICE_LC_HEADER, header doesn't match the DMR RF header: %u->%s%u %u->%s%u", m_slot->m_slotNo, dmrData.getSrcId(), dmrData.getFLCO() == FLCO_GROUP ? "TG" : "", dmrData.getDstId(),