[csl] update CSL parameters only when necessary (#11312)

The current MLE and MAC layers will trigger a call to "SubMac::UpdateCsl()"
when the CSL state or CSL parameters change. This will bring a lot of
unnecessary interface call overhead when we make RCP support CSL receiver
in the future.

This PR refactors the code so that the MLE and MAC layers only trigger a
call to `UpdateCsl` when a valid state or parameter change occurs.
This commit is contained in:
Zhanglong Xia
2025-03-12 22:27:49 -07:00
committed by GitHub
parent 68543b0faf
commit 1f37da29e5
9 changed files with 126 additions and 81 deletions
+1 -1
View File
@@ -421,7 +421,7 @@ uint16_t otLinkGetCcaFailureRate(otInstance *aInstance)
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
bool otLinkIsCslEnabled(otInstance *aInstance) { return AsCoreType(aInstance).Get<Mac::Mac>().IsCslEnabled(); }
bool otLinkIsCslSupported(otInstance *aInstance) { return AsCoreType(aInstance).Get<Mac::Mac>().IsCslSupported(); }
bool otLinkIsCslSupported(otInstance *aInstance) { return AsCoreType(aInstance).Get<Mle::Mle>().IsCslSupported(); }
uint8_t otLinkGetCslChannel(otInstance *aInstance) { return AsCoreType(aInstance).Get<Mac::Mac>().GetCslChannel(); }
+88 -31
View File
@@ -83,6 +83,8 @@ Mac::Mac(Instance &aInstance)
#endif
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
, mIsCslEnabled(false)
, mIsCslCapable(false)
, mCslChannel(0)
, mCslPeriod(0)
#endif
@@ -423,6 +425,9 @@ exit:
Error Mac::SetPanChannel(uint8_t aChannel)
{
Error error = kErrorNone;
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
bool isPanChannelChanged = (mPanChannel != aChannel);
#endif
VerifyOrExit(mSupportedChannelMask.ContainsChannel(aChannel), error = kErrorInvalidArgs);
@@ -435,7 +440,10 @@ Error Mac::SetPanChannel(uint8_t aChannel)
mRadioChannel = mPanChannel;
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
UpdateCsl();
if ((mCslChannel == 0) && isPanChannelChanged)
{
UpdateCslParameters();
}
#endif
UpdateIdleMode();
@@ -2423,36 +2431,32 @@ exit:
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
void Mac::UpdateCsl(void)
void Mac::SetCslCapable(bool aIsCslCapable)
{
uint16_t period = IsCslEnabled() ? GetCslPeriod() : 0;
uint8_t channel = GetCslChannel() ? GetCslChannel() : mPanChannel;
VerifyOrExit(mIsCslCapable != aIsCslCapable);
mIsCslCapable = aIsCslCapable;
UpdateCslState();
if (mLinks.UpdateCsl(period, channel, Get<Mle::Mle>().GetParent().GetRloc16(),
Get<Mle::Mle>().GetParent().GetExtAddress()))
{
if (Get<Mle::Mle>().IsChild())
{
Get<DataPollSender>().RecalculatePollPeriod();
if (period != 0)
{
Get<Mle::Mle>().ScheduleChildUpdateRequest();
}
}
UpdateIdleMode();
}
exit:
return;
}
void Mac::SetCslChannel(uint8_t aChannel)
{
VerifyOrExit(mCslChannel != aChannel);
mCslChannel = aChannel;
UpdateCsl();
UpdateCslParameters();
exit:
return;
}
void Mac::SetCslPeriod(uint16_t aPeriod)
{
bool shouldUpdateCslState;
VerifyOrExit(mCslPeriod != aPeriod);
#if OPENTHREAD_CONFIG_WAKEUP_END_DEVICE_ENABLE
if (IsWakeupListenEnabled() && aPeriod != 0)
{
@@ -2461,8 +2465,70 @@ void Mac::SetCslPeriod(uint16_t aPeriod)
}
#endif
mCslPeriod = aPeriod;
UpdateCsl();
// A CSL period value of 0 means that the CSL is disabled.
shouldUpdateCslState = ((mCslPeriod == 0) != (aPeriod == 0));
mCslPeriod = aPeriod;
if (shouldUpdateCslState)
{
UpdateCslState();
}
else
{
UpdateCslParameters();
}
exit:
return;
}
void Mac::UpdateCslState(void)
{
// This method will enable/disable CSL when the CSL state (enabled/disabled) is changed. Otherwise, nothing to do.
bool isCslEnabled = mIsCslCapable && (mCslPeriod > 0);
VerifyOrExit(mIsCslEnabled != isCslEnabled);
mIsCslEnabled = isCslEnabled;
if (mIsCslEnabled)
{
UpdateCslParameters();
// Request the Mac to enter sleep state.
UpdateIdleMode();
}
else
{
// The platform API `otPlatRadioEnableCsl()` description says that disable CSL by setting the CSL period to 0.
// However, this description does not say whether the parameter `aExtAddr` can be set to nullptr or how to set
// the `aExtAddr` when the CSL is disabled. Here, an empty ExtAddress is set to meet the API requirement.
ExtAddress extAddress;
extAddress.Fill(0);
mLinks.SetCslParams(0, 0, kShortAddrInvalid, extAddress);
}
LogInfo("CSL receiver is %s", mIsCslEnabled ? "enabled" : "disabled");
exit:
return;
}
void Mac::UpdateCslParameters(void)
{
// This method will set all CSL parameters when the CSL is enabled. Otherwise, nothing to do.
uint8_t cslChannel;
VerifyOrExit(mIsCslEnabled);
cslChannel = GetCslChannel() ? GetCslChannel() : mPanChannel;
mLinks.SetCslParams(GetCslPeriod(), cslChannel, Get<Mle::Mle>().GetParent().GetRloc16(),
Get<Mle::Mle>().GetParent().GetExtAddress());
Get<DataPollSender>().RecalculatePollPeriod();
Get<Mle::Mle>().ScheduleChildUpdateRequest();
exit:
return;
}
uint32_t Mac::GetCslPeriodInMsec(void) const
@@ -2474,15 +2540,6 @@ uint32_t Mac::CslPeriodToUsec(uint16_t aPeriodInTenSymbols)
{
return static_cast<uint32_t>(aPeriodInTenSymbols) * kUsPerTenSymbols;
}
bool Mac::IsCslEnabled(void) const { return !Get<Mle::Mle>().IsRxOnWhenIdle() && IsCslCapable(); }
bool Mac::IsCslCapable(void) const { return (GetCslPeriod() > 0) && IsCslSupported(); }
bool Mac::IsCslSupported(void) const
{
return Get<Mle::MleRouter>().IsChild() && Get<Mle::Mle>().GetParent().IsEnhancedKeepAliveSupported();
}
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
+12 -19
View File
@@ -581,9 +581,12 @@ public:
void SetCslChannel(uint8_t aChannel);
/**
* Centralizes CSL state switching conditions evaluating, configuring SubMac accordingly.
* Sets whether the MLE layer is capable of starting CSL.
*
* @retval TRUE If MLE layer is capable of starting CSL.
* @retval FALSE If MLE layer is not capable of starting CSL.
*/
void UpdateCsl(void);
void SetCslCapable(bool aIsCslCapable);
/**
* Gets the CSL period.
@@ -624,23 +627,7 @@ public:
* @retval TRUE If CSL is enabled.
* @retval FALSE If CSL is not enabled.
*/
bool IsCslEnabled(void) const;
/**
* Indicates whether Link is capable of starting CSL.
*
* @retval TRUE If Link is capable of starting CSL.
* @retval FALSE If link is not capable of starting CSL.
*/
bool IsCslCapable(void) const;
/**
* 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;
bool IsCslEnabled(void) const { return mIsCslEnabled; }
/**
* Returns parent CSL accuracy (clock accuracy and uncertainty).
@@ -870,6 +857,10 @@ private:
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
void ProcessCsl(const RxFrame &aFrame, const Address &aSrcAddr);
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
void UpdateCslParameters(void);
void UpdateCslState(void);
#endif
#if OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE
void ProcessEnhAckProbing(const RxFrame &aFrame, const Neighbor &aNeighbor);
#endif
@@ -917,6 +908,8 @@ private:
TimeMilli mCslTxFireTime;
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
bool mIsCslEnabled : 1;
bool mIsCslCapable : 1;
// When Mac::mCslChannel is 0, it indicates that CSL channel has not been specified by the upper layer.
uint8_t mCslChannel;
uint16_t mCslPeriod;
+3 -9
View File
@@ -461,28 +461,22 @@ public:
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
/**
* Configures CSL parameters in all radios.
* Sets CSL parameters in all radios.
*
* @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.
*/
bool UpdateCsl(uint16_t aPeriod, uint8_t aChannel, ShortAddress aShortAddr, const ExtAddress &aExtAddr)
void SetCslParams(uint16_t aPeriod, uint8_t aChannel, ShortAddress aShortAddr, const ExtAddress &aExtAddr)
{
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
retval = mSubMac.UpdateCsl(aPeriod, aChannel, aShortAddr, aExtAddr);
mSubMac.SetCslParams(aPeriod, aChannel, aShortAddr, aExtAddr);
#endif
return retval;
}
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
+7 -8
View File
@@ -295,9 +295,11 @@ public:
Error Disable(void);
/**
* Transitions the radio to Sleep.
* Request radio to transition to sleep state.
*
* @retval kErrorNone Successfully transitioned to Sleep.
* The `SubMac` layer may enter `Receive()` state when the CSL receiver is enabled.
*
* @retval kErrorNone Successfully transitioned to Sleep or the radio is handled by the CSL receiver.
* @retval kErrorBusy The radio was transmitting.
* @retval kErrorInvalidState The radio was disabled.
*/
@@ -376,17 +378,14 @@ public:
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
/**
* Configures CSL parameters in 'SubMac'.
* Sets CSL parameters in 'SubMac'.
*
* @param[in] aPeriod The CSL period (in unit of 10 symbols).
* @param[in] aPeriod The CSL period (in unit of 10 symbols), 0 for disabling CSL receiver.
* @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.
*/
bool UpdateCsl(uint16_t aPeriod, uint8_t aChannel, ShortAddress aShortAddr, const ExtAddress &aExtAddr);
void SetCslParams(uint16_t aPeriod, uint8_t aChannel, ShortAddress aShortAddr, const ExtAddress &aExtAddr);
/**
* Returns parent CSL accuracy (clock accuracy and uncertainty).
+2 -2
View File
@@ -108,7 +108,7 @@ exit:
return;
}
bool SubMac::UpdateCsl(uint16_t aPeriod, uint8_t aChannel, ShortAddress aShortAddr, const ExtAddress &aExtAddr)
void SubMac::SetCslParams(uint16_t aPeriod, uint8_t aChannel, ShortAddress aShortAddr, const ExtAddress &aExtAddr)
{
bool diffPeriod = aPeriod != mCslPeriod;
bool diffChannel = aChannel != mCslChannel;
@@ -133,7 +133,7 @@ bool SubMac::UpdateCsl(uint16_t aPeriod, uint8_t aChannel, ShortAddress aShortAd
}
exit:
return retval;
return;
}
void SubMac::HandleCslTimer(Timer &aTimer) { aTimer.Get<SubMac>().HandleCslTimer(); }
+6 -7
View File
@@ -349,6 +349,10 @@ void Mle::SetRole(DeviceRole aRole)
mInitiallyAttachedAsSleepy = !GetDeviceMode().IsRxOnWhenIdle();
}
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
Get<Mac::Mac>().SetCslCapable(IsCslSupported() && !IsRxOnWhenIdle());
#endif
exit:
return;
}
@@ -721,9 +725,6 @@ void Mle::SetStateDetached(void)
Get<MleRouter>().ClearAlternateRloc16();
Get<MleRouter>().HandleDetachStart();
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
Get<Mac::Mac>().UpdateCsl();
#endif
}
void Mle::SetStateChild(uint16_t aRloc16)
@@ -769,10 +770,6 @@ void Mle::SetStateChild(uint16_t aRloc16)
}
mPreviousParentRloc = mParent.GetRloc16();
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
Get<Mac::Mac>().UpdateCsl();
#endif
}
void Mle::InformPreviousChannel(void)
@@ -1098,6 +1095,8 @@ void Mle::SetCslTimeout(uint32_t aTimeout)
exit:
return;
}
bool Mle::IsCslSupported(void) const { return IsChild() && GetParent().IsThreadVersion1p2OrHigher(); }
#endif
void Mle::InitNeighbor(Neighbor &aNeighbor, const RxInfo &aRxInfo)
+7
View File
@@ -730,6 +730,13 @@ public:
*/
uint64_t CalcParentCslMetric(const Mac::CslAccuracy &aCslAccuracy) const;
/**
* 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;
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
#if OPENTHREAD_CONFIG_WAKEUP_COORDINATOR_ENABLE
-4
View File
@@ -470,10 +470,6 @@ void MleRouter::SetStateRouterOrLeader(DeviceRole aRole, uint16_t aRloc16, Leade
}
}
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
Get<Mac::Mac>().UpdateCsl();
#endif
LogNote("Partition ID 0x%lx", ToUlong(mLeaderData.GetPartitionId()));
}