From 289bbebb9c305bebecbb5efc67d29b52d6c78e71 Mon Sep 17 00:00:00 2001 From: Eduardo Montoya Date: Wed, 6 Jul 2022 19:58:01 +0200 Subject: [PATCH] [csl] simplify states and scheduling (#7783) After enabling the scheduling of delayed reception slots in #7677 they would be configured even when the device switched to MED mode. This commit introduces some simplifications around the CSL states and scheduling: - Maintain the CSL timer stopped if not in CSL Receiver mode. - Keep the CSL Period and Channel values in the MAC in order to use them as an indication of CSL Receiver mode in the Sub-Mac. - Simplify CSL states with `mIsCslSampling` variable. - Use a simplified interaction between MAC and SubMac: - `SubMac::UpdateCsl` for CSL config or stopping CSL sampling. - `SubMac::CslSample` for start/maintain CSL sampling. --- src/core/mac/mac.cpp | 65 +++++++++++------- src/core/mac/mac.hpp | 24 +++++-- src/core/mac/mac_links.hpp | 38 ++++++++-- src/core/mac/sub_mac.cpp | 137 +++++++++++-------------------------- src/core/mac/sub_mac.hpp | 89 +++++------------------- src/core/thread/mle.cpp | 25 ++----- 6 files changed, 154 insertions(+), 224 deletions(-) diff --git a/src/core/mac/mac.cpp b/src/core/mac/mac.cpp index 6c99c573c..dbe3c974a 100644 --- a/src/core/mac/mac.cpp +++ b/src/core/mac/mac.cpp @@ -92,6 +92,10 @@ Mac::Mac(Instance &aInstance) #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE , mCslTxFireTime(TimeMilli::kMaxDuration) #endif +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + , mCslChannel(0) + , mCslPeriod(0) +#endif #endif , mActiveScanHandler(nullptr) // Initialize `mActiveScanHandler` and `mEnergyScanHandler` union , mScanHandlerContext(nullptr) @@ -413,6 +417,10 @@ Error Mac::SetPanChannel(uint8_t aChannel) mRadioChannel = mPanChannel; +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + UpdateCsl(); +#endif + UpdateIdleMode(); exit: @@ -553,7 +561,7 @@ void Mac::UpdateIdleMode(void) #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE if (IsCslEnabled()) { - mLinks.CslSample(mRadioChannel); + mLinks.CslSample(); ExitNow(); } #endif @@ -2257,52 +2265,57 @@ exit: #endif #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE -void Mac::SetCslChannel(uint8_t aChannel) +void Mac::UpdateCsl(void) { - VerifyOrExit(GetCslChannel() != aChannel); + uint16_t period; + uint8_t channel; - mLinks.GetSubMac().SetCslChannel(aChannel); - mLinks.GetSubMac().SetCslChannelSpecified(aChannel != 0); + VerifyOrExit(IsCslSupported()); - if (IsCslEnabled()) + period = Get().IsRxOnWhenIdle() ? 0 : GetCslPeriod(); + channel = GetCslChannel() ? GetCslChannel() : mRadioChannel; + + if (mLinks.UpdateCsl(period, channel, Get().GetParent().GetRloc16(), + &Get().GetParent().GetExtAddress())) { - Get().ScheduleChildUpdateRequest(); + Get().RecalculatePollPeriod(); + if (period) + { + Get().ScheduleChildUpdateRequest(); + } + UpdateIdleMode(); } + exit: return; } +void Mac::SetCslChannel(uint8_t aChannel) +{ + mCslChannel = aChannel; + UpdateCsl(); +} + void Mac::SetCslPeriod(uint16_t aPeriod) { - mLinks.GetSubMac().SetCslPeriod(aPeriod); - - Get().RecalculatePollPeriod(); - - if ((GetCslPeriod() == 0) || IsCslEnabled()) - { - IgnoreError(Get().EnableCsl(GetCslPeriod(), Get().GetParent().GetRloc16(), - &Get().GetParent().GetExtAddress())); - } - - if (IsCslEnabled()) - { - Get().ScheduleChildUpdateRequest(); - } - - UpdateIdleMode(); + mCslPeriod = aPeriod; + UpdateCsl(); } bool Mac::IsCslEnabled(void) const { - return !GetRxOnWhenIdle() && IsCslCapable(); + return !Get().IsRxOnWhenIdle() && IsCslCapable(); } bool Mac::IsCslCapable(void) const { - return (GetCslPeriod() > 0) && Get().IsChild() && - Get().GetParent().IsEnhancedKeepAliveSupported(); + return (GetCslPeriod() > 0) && IsCslSupported(); } +bool Mac::IsCslSupported(void) const +{ + return Get().IsChild() && Get().GetParent().IsEnhancedKeepAliveSupported(); +} #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE diff --git a/src/core/mac/mac.hpp b/src/core/mac/mac.hpp index 940a458bc..babdbbf35 100644 --- a/src/core/mac/mac.hpp +++ b/src/core/mac/mac.hpp @@ -583,7 +583,7 @@ public: * @returns CSL channel. * */ - uint8_t GetCslChannel(void) const { return mLinks.GetSubMac().GetCslChannel(); } + uint8_t GetCslChannel(void) const { return mCslChannel; } /** * This method sets the CSL channel. @@ -594,12 +594,10 @@ public: void SetCslChannel(uint8_t aChannel); /** - * This method indicates if CSL channel has been explicitly specified by the upper layer. - * - * @returns If CSL channel has been specified. + * This method centralizes CSL state switching conditions evaluating, configuring SubMac accordingly. * */ - bool IsCslChannelSpecified(void) const { return mLinks.GetSubMac().IsCslChannelSpecified(); } + void UpdateCsl(void); /** * This method gets the CSL period. @@ -607,7 +605,7 @@ public: * @returns CSL period in units of 10 symbols. * */ - uint16_t GetCslPeriod(void) const { return mLinks.GetSubMac().GetCslPeriod(); } + uint16_t GetCslPeriod(void) const { return mCslPeriod; } /** * This method sets the CSL period. @@ -635,6 +633,15 @@ public: */ bool IsCslCapable(void) const; + /** + * This method indicates whether the device is connected to a parent which supports CSL. + * + * @retval TRUE If parent supports CSL. + * @retval FALSE If parent does not support CSL. + * + */ + bool IsCslSupported(void) const; + /** * This method returns CSL parent clock accuracy, in ± ppm. * @@ -820,6 +827,11 @@ private: #if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE TimeMilli mCslTxFireTime; #endif +#endif +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + // When Mac::mCslChannel is 0, it indicates that CSL channel has not been specified by the upper layer. + uint8_t mCslChannel; + uint16_t mCslPeriod; #endif union diff --git a/src/core/mac/mac_links.hpp b/src/core/mac/mac_links.hpp index 85aa0e54b..99406f7ad 100644 --- a/src/core/mac/mac_links.hpp +++ b/src/core/mac/mac_links.hpp @@ -457,18 +457,42 @@ public: #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE /** - * This method transitions all radios link to CSL sample state. + * This method configures CSL parameters in all radios. * - * CSL sample state is only applicable and used for 15.4 radio link. Other link are transitioned to sleep state. + * @param[in] aPeriod The CSL period. + * @param[in] aChannel The CSL channel. + * @param[in] aShortAddr The short source address of CSL receiver's peer. + * @param[in] aExtAddr The extended source address of CSL receiver's peer. + * + * @retval TRUE if CSL Period or CSL Channel changed. + * @retval FALSE if CSL Period and CSL Channel did not change. * - * @param[in] aPanChannel The current phy channel used by the device. This param will only take effect when CSL - * channel hasn't been explicitly specified. */ - void CslSample(uint8_t aPanChannel) + bool UpdateCsl(uint16_t aPeriod, uint8_t aChannel, otShortAddress aShortAddr, const otExtAddress *aExtAddr) { - OT_UNUSED_VARIABLE(aPanChannel); + bool retval = false; + + OT_UNUSED_VARIABLE(aPeriod); + OT_UNUSED_VARIABLE(aChannel); + OT_UNUSED_VARIABLE(aShortAddr); + OT_UNUSED_VARIABLE(aExtAddr); #if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE - IgnoreError(mSubMac.CslSample(aPanChannel)); + retval = mSubMac.UpdateCsl(aPeriod, aChannel, aShortAddr, aExtAddr); +#endif + return retval; + } + + /** + * This method transitions all radios link to CSL sample state, given that a non-zero CSL period is configured. + * + * CSL sample state is only applicable and used for 15.4 radio link. Other link are transitioned to sleep state + * when CSL period is non-zero. + * + */ + void CslSample(void) + { +#if OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE + mSubMac.CslSample(); #endif #if OPENTHREAD_CONFIG_RADIO_LINK_TREL_ENABLE mTrel.Sleep(); diff --git a/src/core/mac/sub_mac.cpp b/src/core/mac/sub_mac.cpp index eb7c064db..01243de7a 100644 --- a/src/core/mac/sub_mac.cpp +++ b/src/core/mac/sub_mac.cpp @@ -95,12 +95,11 @@ void SubMac::Init(void) mTimer.Stop(); #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE - mCslPeriod = 0; - mCslChannel = 0; - mIsCslChannelSpecified = false; - mCslSampleTime = TimeMicro{0}; - mCslLastSync = TimeMicro{0}; - mCslState = kCslIdle; + mCslPeriod = 0; + mCslChannel = 0; + mIsCslSampling = false; + mCslSampleTime = TimeMicro{0}; + mCslLastSync = TimeMicro{0}; mCslTimer.Stop(); #endif } @@ -201,6 +200,10 @@ Error SubMac::Disable(void) { Error error; +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + mCslTimer.Stop(); +#endif + mTimer.Stop(); SuccessOrExit(error = Get().Sleep()); SuccessOrExit(error = Get().Disable()); @@ -254,43 +257,26 @@ exit: } #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE -Error SubMac::CslSample(uint8_t aPanChannel) +void SubMac::CslSample(void) { - Error error = kErrorNone; - - if (!IsCslChannelSpecified()) - { - mCslChannel = aPanChannel; - } - #if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE - VerifyOrExit(!mRadioFilterEnabled, error = Get().Sleep()); + VerifyOrExit(!mRadioFilterEnabled, IgnoreError(Get().Sleep())); #endif - switch (mCslState) - { - case kCslSample: - error = Get().Receive(mCslChannel); - break; - case kCslSleep: -#if !OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE - error = Get().Sleep(); // Don't actually sleep for debugging -#endif - break; - case kCslIdle: - ExitNow(error = kErrorInvalidState); - default: - OT_ASSERT(false); - } - SetState(kStateCslSample); -exit: - if (error != kErrorNone) + if (mIsCslSampling && !RadioSupportsReceiveTiming()) { - LogWarn("CslSample() failed, error: %s", ErrorToString(error)); + IgnoreError(Get().Receive(mCslChannel)); + ExitNow(); } - return error; + +#if !OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE + IgnoreError(Get().Sleep()); // Don't actually sleep for debugging +#endif + +exit: + return; } #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE @@ -318,7 +304,7 @@ void SubMac::HandleReceiveDone(RxFrame *aFrame, Error aError) #if OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE // Split the log into two lines for RTT to output LogDebg("Received frame in state (SubMac %s, CSL %s), timestamp %u", StateToString(mState), - CslStateToString(mCslState), static_cast(aFrame->mInfo.mRxInfo.mTimestamp)); + mIsCslSampling ? "CslSample" : "CslSleep", static_cast(aFrame->mInfo.mRxInfo.mTimestamp)); LogDebg("Target sample start time %u, time drift %d", mCslSampleTime.GetValue(), static_cast(aFrame->mInfo.mRxInfo.mTimestamp) - mCslSampleTime.GetValue()); #endif @@ -1055,63 +1041,35 @@ const char *SubMac::StateToString(State aState) return kStateStrings[aState]; } -#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE -const char *SubMac::CslStateToString(CslState aCslState) -{ - static const char *const kCslStateStrings[] = { - "CslIdle", // (0) kCslIdle - "CslSample", // (1) kCslSample - "CslSleep", // (2) kCslSleep - }; - - static_assert(kCslIdle == 0, "kCslIdle value is incorrect"); - static_assert(kCslSample == 1, "kCslSample value is incorrect"); - static_assert(kCslSleep == 2, "kCslSleep value is incorrect"); - - return kCslStateStrings[aCslState]; -} -#endif - // LCOV_EXCL_STOP //--------------------------------------------------------------------------------------------------------------------- // CSL Receiver methods #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE -void SubMac::SetCslChannel(uint8_t aChannel) +bool SubMac::UpdateCsl(uint16_t aPeriod, uint8_t aChannel, otShortAddress aShortAddr, const otExtAddress *aExtAddr) { + bool diffPeriod = aPeriod != mCslPeriod; + bool diffChannel = aChannel != mCslChannel; + bool retval = diffPeriod || diffChannel; + + VerifyOrExit(retval); mCslChannel = aChannel; -} - -void SubMac::SetCslPeriod(uint16_t aPeriod) -{ - VerifyOrExit(mCslPeriod != aPeriod); + VerifyOrExit(diffPeriod); mCslPeriod = aPeriod; + IgnoreError(Get().EnableCsl(aPeriod, aShortAddr, aExtAddr)); mCslTimer.Stop(); - if (mCslPeriod > 0) { mCslSampleTime = TimeMicro(static_cast(otPlatRadioGetNow(&GetInstance()))); - mCslState = kCslSleep; + mIsCslSampling = false; HandleCslTimer(); } - else - { - mCslState = kCslIdle; - - if (mState == kStateCslSample) - { - IgnoreError(Get().Sleep()); - SetState(kStateSleep); - } - } - - LogDebg("CSL Period: %u", mCslPeriod); exit: - return; + return retval; } void SubMac::HandleCslTimer(Timer &aTimer) @@ -1135,11 +1093,9 @@ void SubMac::HandleCslTimer(void) GetCslWindowEdges(timeAhead, timeAfter); - switch (mCslState) + if (mIsCslSampling) { - case kCslSample: - mCslState = kCslSleep; - + mIsCslSampling = false; mCslTimer.FireAt(mCslSampleTime - timeAhead); if (mState == kStateCslSample) { @@ -1148,9 +1104,9 @@ void SubMac::HandleCslTimer(void) #endif LogDebg("CSL sleep %u", mCslTimer.GetNow().GetValue()); } - break; - - case kCslSleep: + } + else + { if (RadioSupportsReceiveTiming()) { mCslSampleTime += periodUs; @@ -1160,33 +1116,22 @@ void SubMac::HandleCslTimer(void) else { mCslTimer.FireAt(mCslSampleTime + timeAfter); - mCslState = kCslSample; + mIsCslSampling = true; mCslSampleTime += periodUs; } Get().UpdateCslSampleTime(mCslSampleTime.GetValue()); - if (RadioSupportsReceiveTiming()) + if (RadioSupportsReceiveTiming() && (mState != kStateDisabled)) { - if (mState != kStateDisabled && mCslChannel) - { - IgnoreError(Get().ReceiveAt(mCslChannel, mCslSampleTime.GetValue() - periodUs - timeAhead, - timeAhead + timeAfter)); - } + IgnoreError(Get().ReceiveAt(mCslChannel, mCslSampleTime.GetValue() - periodUs - timeAhead, + timeAhead + timeAfter)); } else if (mState == kStateCslSample) { IgnoreError(Get().Receive(mCslChannel)); LogDebg("CSL sample %u, duration %u", mCslTimer.GetNow().GetValue(), timeAhead + timeAfter); } - break; - - case kCslIdle: - break; - - default: - OT_ASSERT(false); - break; } } diff --git a/src/core/mac/sub_mac.hpp b/src/core/mac/sub_mac.hpp index da0dbc6ae..0904351e3 100644 --- a/src/core/mac/sub_mac.hpp +++ b/src/core/mac/sub_mac.hpp @@ -395,69 +395,27 @@ public: int8_t GetNoiseFloor(void); #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE - /** - * This method lets `SubMac` start CSL sample. + * This method configures CSL parameters in 'SubMac'. * - * `SubMac` would switch the radio state between `Receive` and `Sleep` according the CSL timer. When CslSample is - * started, `mState` will become `kStateCslSample`. But it could be doing `Sleep` or `Receive` at this moment - * (depending on `mCslState`). + * @param[in] aPeriod The CSL period. + * @param[in] aChannel The CSL channel. + * @param[in] aShortAddr The short source address of CSL receiver's peer. + * @param[in] aExtAddr The extended source address of CSL receiver's peer. * - * @param[in] aPanChannel The current phy channel used by the device. This param will only take effect when CSL - * channel hasn't been explicitly specified. - * - * @retval kErrorNone Successfully entered CSL operation (sleep or receive according to CSL timer). - * @retval kErrorBusy The radio was transmitting. - * @retval kErrorInvalidState The radio was disabled. + * @retval TRUE if CSL Period or CSL Channel changed. + * @retval FALSE if CSL Period and CSL Channel did not change. * */ - Error CslSample(uint8_t aPanChannel); + bool UpdateCsl(uint16_t aPeriod, uint8_t aChannel, otShortAddress aShortAddr, const otExtAddress *aExtAddr); /** - * This method gets the CSL channel. + * This method lets `SubMac` start CSL sample mode given a configured non-zero CSL period. * - * @returns CSL channel. + * `SubMac` would switch the radio state between `Receive` and `Sleep` according the CSL timer. * */ - uint8_t GetCslChannel(void) const { return mCslChannel; } - - /** - * This method sets the CSL channel. - * - * @param[in] aChannel The CSL channel. `0` to set CSL Channel unspecified. - * - */ - void SetCslChannel(uint8_t aChannel); - - /** - * This method indicates if CSL channel has been explicitly specified by the upper layer. - * - * @returns If CSL channel has been specified. - * - */ - bool IsCslChannelSpecified(void) const { return mIsCslChannelSpecified; } - - /** - * This method sets the flag representing if CSL channel has been specified. - * - */ - void SetCslChannelSpecified(bool aIsSpecified) { mIsCslChannelSpecified = aIsSpecified; } - - /** - * This method gets the CSL period. - * - * @returns CSL period. - * - */ - uint16_t GetCslPeriod(void) const { return mCslPeriod; } - - /** - * This method sets the CSL period. - * - * @param[in] aPeriod The CSL period in 10 symbols. - * - */ - void SetCslPeriod(uint16_t aPeriod); + void CslSample(void); /** * This method returns CSL parent clock accuracy, in ± ppm. @@ -623,12 +581,6 @@ private: // CSL receivers would wake up `kCslReceiveTimeAhead` earlier // than expected sample window. The value is in usec. static constexpr uint32_t kCslReceiveTimeAhead = OPENTHREAD_CONFIG_CSL_RECEIVE_TIME_AHEAD; - - enum CslState : uint8_t{ - kCslIdle, // CSL receiver is not started. - kCslSample, // Sampling CSL channel. - kCslSleep, // Radio in sleep. - }; #endif /** @@ -674,9 +626,6 @@ private: void SetState(State aState); static const char *StateToString(State aState); -#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE - static const char *CslStateToString(CslState aCslState); -#endif otRadioCaps mRadioCaps; State mState; @@ -709,14 +658,14 @@ private: #endif #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE - uint16_t mCslPeriod; // The CSL sample period, in units of 10 symbols (160 microseconds). - uint8_t mCslChannel : 7; // The CSL sample channel (only when `mIsCslChannelSpecified` is `true`). - uint8_t mIsCslChannelSpecified : 1; // Whether the CSL channel was explicitly set - TimeMicro mCslSampleTime; // The CSL sample time of the current period. - TimeMicro mCslLastSync; // The timestamp of the last successful CSL synchronization. - uint8_t mCslParentAccuracy; // Drift of timer used for scheduling CSL tx by the parent, in ± ppm. - uint8_t mCslParentUncert; // Uncertainty of the scheduling CSL of tx by the parent, in ±10 us units. - CslState mCslState; + uint16_t mCslPeriod; // The CSL sample period, in units of 10 symbols (160 microseconds). + uint8_t mCslChannel : 7; // The CSL sample channel. + bool mIsCslSampling : 1; // Indicates that the radio is receiving in CSL state for platforms not supporting delayed + // reception. + TimeMicro mCslSampleTime; // The CSL sample time of the current period. + TimeMicro mCslLastSync; // The timestamp of the last successful CSL synchronization. + uint8_t mCslParentAccuracy; // Drift of timer used for scheduling CSL tx by the parent, in ± ppm. + uint8_t mCslParentUncert; // Uncertainty of the scheduling CSL of tx by the parent, in ±10 us units. TimerMicro mCslTimer; #endif }; diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 596729958..500fcafb6 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -641,12 +641,6 @@ bool Mle::IsRouterOrLeader(void) const void Mle::SetStateDetached(void) { -#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE - if (Get().IsCslEnabled()) - { - IgnoreError(Get().EnableCsl(0, GetParent().GetRloc16(), &GetParent().GetExtAddress())); - } -#endif #if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE Get().Reset(); #endif @@ -676,6 +670,9 @@ void Mle::SetStateDetached(void) #if OPENTHREAD_FTD Get().SetTimerExpirations(0); #endif +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + Get().UpdateCsl(); +#endif } void Mle::SetStateChild(uint16_t aRloc16) @@ -726,12 +723,7 @@ void Mle::SetStateChild(uint16_t aRloc16) mPreviousParentRloc = mParent.GetRloc16(); #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE - if (Get().IsCslCapable()) - { - uint32_t period = IsRxOnWhenIdle() ? 0 : Get().GetCslPeriod(); - IgnoreError(Get().EnableCsl(period, GetParent().GetRloc16(), &GetParent().GetExtAddress())); - ScheduleChildUpdateRequest(); - } + Get().UpdateCsl(); #endif } @@ -1834,12 +1826,7 @@ void Mle::ScheduleMessageTransmissionTimer(void) case kChildUpdateRequestActive: #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE - // CSL transmitter may respond in next CSL cycle. - // This condition IsCslCapable() && !IsRxOnWhenIdle() is used instead of - // IsCslEnabled because during transitions SSED -> MED and MED -> SSED - // there is a delay in synchronisation of IsRxOnWhenIdle residing in MAC - // and in MLE, which causes below datapoll interval to be calculated incorrectly. - if (Get().IsCslCapable() && !IsRxOnWhenIdle()) + if (Get().IsCslEnabled()) { ExitNow(interval = Get().GetCslPeriod() * kUsPerTenSymbols / 1000 + static_cast(kUnicastRetransmissionDelay)); @@ -4767,7 +4754,7 @@ Error Mle::TxMessage::AppendCslChannelTlv(void) // in CSL Channel TLV, if CSL channel is not specified, we don't append CSL Channel TLV. // And on transmitter side, it would also set CSL Channel for the child to `0` if it doesn't find a CSL Channel // TLV. - VerifyOrExit(Get().IsCslChannelSpecified()); + VerifyOrExit(Get().GetCslChannel()); cslChannel.Init(); cslChannel.SetChannelPage(0);