mirror of
https://github.com/espressif/openthread.git
synced 2026-06-05 21:14:49 +00:00
[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.
This commit is contained in:
+39
-26
@@ -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<Mle::Mle>().IsRxOnWhenIdle() ? 0 : GetCslPeriod();
|
||||
channel = GetCslChannel() ? GetCslChannel() : mRadioChannel;
|
||||
|
||||
if (mLinks.UpdateCsl(period, channel, Get<Mle::Mle>().GetParent().GetRloc16(),
|
||||
&Get<Mle::Mle>().GetParent().GetExtAddress()))
|
||||
{
|
||||
Get<Mle::Mle>().ScheduleChildUpdateRequest();
|
||||
Get<DataPollSender>().RecalculatePollPeriod();
|
||||
if (period)
|
||||
{
|
||||
Get<Mle::Mle>().ScheduleChildUpdateRequest();
|
||||
}
|
||||
UpdateIdleMode();
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void Mac::SetCslChannel(uint8_t aChannel)
|
||||
{
|
||||
mCslChannel = aChannel;
|
||||
UpdateCsl();
|
||||
}
|
||||
|
||||
void Mac::SetCslPeriod(uint16_t aPeriod)
|
||||
{
|
||||
mLinks.GetSubMac().SetCslPeriod(aPeriod);
|
||||
|
||||
Get<DataPollSender>().RecalculatePollPeriod();
|
||||
|
||||
if ((GetCslPeriod() == 0) || IsCslEnabled())
|
||||
{
|
||||
IgnoreError(Get<Radio>().EnableCsl(GetCslPeriod(), Get<Mle::Mle>().GetParent().GetRloc16(),
|
||||
&Get<Mle::Mle>().GetParent().GetExtAddress()));
|
||||
}
|
||||
|
||||
if (IsCslEnabled())
|
||||
{
|
||||
Get<Mle::Mle>().ScheduleChildUpdateRequest();
|
||||
}
|
||||
|
||||
UpdateIdleMode();
|
||||
mCslPeriod = aPeriod;
|
||||
UpdateCsl();
|
||||
}
|
||||
|
||||
bool Mac::IsCslEnabled(void) const
|
||||
{
|
||||
return !GetRxOnWhenIdle() && IsCslCapable();
|
||||
return !Get<Mle::Mle>().IsRxOnWhenIdle() && IsCslCapable();
|
||||
}
|
||||
|
||||
bool Mac::IsCslCapable(void) const
|
||||
{
|
||||
return (GetCslPeriod() > 0) && Get<Mle::MleRouter>().IsChild() &&
|
||||
Get<Mle::Mle>().GetParent().IsEnhancedKeepAliveSupported();
|
||||
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_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
|
||||
|
||||
+18
-6
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
+41
-96
@@ -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<Radio>().Sleep());
|
||||
SuccessOrExit(error = Get<Radio>().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<Radio>().Sleep());
|
||||
VerifyOrExit(!mRadioFilterEnabled, IgnoreError(Get<Radio>().Sleep()));
|
||||
#endif
|
||||
|
||||
switch (mCslState)
|
||||
{
|
||||
case kCslSample:
|
||||
error = Get<Radio>().Receive(mCslChannel);
|
||||
break;
|
||||
case kCslSleep:
|
||||
#if !OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE
|
||||
error = Get<Radio>().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<Radio>().Receive(mCslChannel));
|
||||
ExitNow();
|
||||
}
|
||||
return error;
|
||||
|
||||
#if !OPENTHREAD_CONFIG_MAC_CSL_DEBUG_ENABLE
|
||||
IgnoreError(Get<Radio>().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<uint32_t>(aFrame->mInfo.mRxInfo.mTimestamp));
|
||||
mIsCslSampling ? "CslSample" : "CslSleep", static_cast<uint32_t>(aFrame->mInfo.mRxInfo.mTimestamp));
|
||||
LogDebg("Target sample start time %u, time drift %d", mCslSampleTime.GetValue(),
|
||||
static_cast<uint32_t>(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<Radio>().EnableCsl(aPeriod, aShortAddr, aExtAddr));
|
||||
|
||||
mCslTimer.Stop();
|
||||
|
||||
if (mCslPeriod > 0)
|
||||
{
|
||||
mCslSampleTime = TimeMicro(static_cast<uint32_t>(otPlatRadioGetNow(&GetInstance())));
|
||||
mCslState = kCslSleep;
|
||||
mIsCslSampling = false;
|
||||
HandleCslTimer();
|
||||
}
|
||||
else
|
||||
{
|
||||
mCslState = kCslIdle;
|
||||
|
||||
if (mState == kStateCslSample)
|
||||
{
|
||||
IgnoreError(Get<Radio>().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<Radio>().UpdateCslSampleTime(mCslSampleTime.GetValue());
|
||||
|
||||
if (RadioSupportsReceiveTiming())
|
||||
if (RadioSupportsReceiveTiming() && (mState != kStateDisabled))
|
||||
{
|
||||
if (mState != kStateDisabled && mCslChannel)
|
||||
{
|
||||
IgnoreError(Get<Radio>().ReceiveAt(mCslChannel, mCslSampleTime.GetValue() - periodUs - timeAhead,
|
||||
timeAhead + timeAfter));
|
||||
}
|
||||
IgnoreError(Get<Radio>().ReceiveAt(mCslChannel, mCslSampleTime.GetValue() - periodUs - timeAhead,
|
||||
timeAhead + timeAfter));
|
||||
}
|
||||
else if (mState == kStateCslSample)
|
||||
{
|
||||
IgnoreError(Get<Radio>().Receive(mCslChannel));
|
||||
LogDebg("CSL sample %u, duration %u", mCslTimer.GetNow().GetValue(), timeAhead + timeAfter);
|
||||
}
|
||||
break;
|
||||
|
||||
case kCslIdle:
|
||||
break;
|
||||
|
||||
default:
|
||||
OT_ASSERT(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+19
-70
@@ -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
|
||||
};
|
||||
|
||||
+6
-19
@@ -641,12 +641,6 @@ bool Mle::IsRouterOrLeader(void) const
|
||||
|
||||
void Mle::SetStateDetached(void)
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
if (Get<Mac::Mac>().IsCslEnabled())
|
||||
{
|
||||
IgnoreError(Get<Radio>().EnableCsl(0, GetParent().GetRloc16(), &GetParent().GetExtAddress()));
|
||||
}
|
||||
#endif
|
||||
#if OPENTHREAD_FTD && OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE
|
||||
Get<BackboneRouter::Local>().Reset();
|
||||
#endif
|
||||
@@ -676,6 +670,9 @@ void Mle::SetStateDetached(void)
|
||||
#if OPENTHREAD_FTD
|
||||
Get<Ip6::Mpl>().SetTimerExpirations(0);
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
Get<Mac::Mac>().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<Mac::Mac>().IsCslCapable())
|
||||
{
|
||||
uint32_t period = IsRxOnWhenIdle() ? 0 : Get<Mac::Mac>().GetCslPeriod();
|
||||
IgnoreError(Get<Radio>().EnableCsl(period, GetParent().GetRloc16(), &GetParent().GetExtAddress()));
|
||||
ScheduleChildUpdateRequest();
|
||||
}
|
||||
Get<Mac::Mac>().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<Mac::Mac>().IsCslCapable() && !IsRxOnWhenIdle())
|
||||
if (Get<Mac::Mac>().IsCslEnabled())
|
||||
{
|
||||
ExitNow(interval = Get<Mac::Mac>().GetCslPeriod() * kUsPerTenSymbols / 1000 +
|
||||
static_cast<uint32_t>(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<Mac::Mac>().IsCslChannelSpecified());
|
||||
VerifyOrExit(Get<Mac::Mac>().GetCslChannel());
|
||||
|
||||
cslChannel.Init();
|
||||
cslChannel.SetChannelPage(0);
|
||||
|
||||
Reference in New Issue
Block a user