From 93f6d619ef9fa0fde78cc97485e9c22d5f4871f4 Mon Sep 17 00:00:00 2001 From: Yakun Xu Date: Tue, 7 Jan 2025 01:34:08 +0800 Subject: [PATCH] [wake-up] fix time wrap for wake-up frames (#11028) This commit fixes the potential issue that mTxDelay becomes 0 around the 32-bit time wrapping. --- src/core/mac/sub_mac.cpp | 2 +- src/core/mac/wakeup_tx_scheduler.cpp | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/core/mac/sub_mac.cpp b/src/core/mac/sub_mac.cpp index b13a6aaaf..a7b5620fa 100644 --- a/src/core/mac/sub_mac.cpp +++ b/src/core/mac/sub_mac.cpp @@ -413,7 +413,7 @@ void SubMac::StartCsmaBackoff(void) uint8_t backoffExponent = kCsmaMinBe + mCsmaBackoffs; #if !OPENTHREAD_MTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE - if (mTransmitFrame.mInfo.mTxInfo.mTxDelay != 0) + if (mTransmitFrame.mInfo.mTxInfo.mTxDelay != 0 || mTransmitFrame.mInfo.mTxInfo.mTxDelayBaseTime != 0) { SetState(kStateCslTransmit); diff --git a/src/core/mac/wakeup_tx_scheduler.cpp b/src/core/mac/wakeup_tx_scheduler.cpp index f1fab249f..fe774ab17 100644 --- a/src/core/mac/wakeup_tx_scheduler.cpp +++ b/src/core/mac/wakeup_tx_scheduler.cpp @@ -80,15 +80,17 @@ Mac::TxFrame *WakeupTxScheduler::PrepareWakeupFrame(Mac::TxFrames &aTxFrames) Mac::TxFrame *frame = nullptr; Mac::Address target; Mac::Address source; - uint32_t radioTxUs; + uint32_t radioTxDelay; uint32_t rendezvousTimeUs; + TimeMicro nowUs = TimerMicro::GetNow(); Mac::ConnectionIe *connectionIe; VerifyOrExit(mIsRunning); target.SetExtended(mWedAddress); source.SetExtended(Get().GetExtAddress()); - radioTxUs = static_cast(Get().GetNow()) + (mTxTimeUs - TimerMicro::GetNow()); + VerifyOrExit(mTxTimeUs >= nowUs); + radioTxDelay = mTxTimeUs - nowUs; #if OPENTHREAD_CONFIG_MULTI_RADIO frame = &aTxFrames.GetTxFrame(Mac::kRadioTypeIeee802154); @@ -97,8 +99,8 @@ Mac::TxFrame *WakeupTxScheduler::PrepareWakeupFrame(Mac::TxFrames &aTxFrames) #endif VerifyOrExit(frame->GenerateWakeupFrame(Get().GetPanId(), target, source) == kErrorNone, frame = nullptr); - frame->SetTxDelayBaseTime(0); - frame->SetTxDelay(radioTxUs); + frame->SetTxDelayBaseTime(static_cast(Get().GetNow())); + frame->SetTxDelay(radioTxDelay); frame->SetCsmaCaEnabled(false); frame->SetMaxCsmaBackoffs(0); frame->SetMaxFrameRetries(0);