mirror of
https://github.com/espressif/openthread.git
synced 2026-09-07 17:50:09 +00:00
[mac] move CSL period and timeout constants from radio (#13572)
This commit moves `kMinCslPeriod` from `Radio` to `Mac` (`mac_types.hpp`) and `kMaxCslTimeout` to `Mle` (`mle.hpp`), grouping them logically within their respective layers. Key changes: - Adds `Time::MsecToUsec()` helper function. - Tightens constant types to native representations: `uint16_t` for `kMinCslPeriod` (units of 10 symbols) and `uint32_t` for `kMaxCslTimeout` (units of seconds), avoiding narrowing conversions across MAC and MLE call sites. - Bug fix in CSL IE validation: Previously, `Mac::ProcessCsl()` checked `csl->GetPeriod() >= kMinCslIePeriod`, where `kMinCslIePeriod` was defined directly as `OPENTHREAD_CONFIG_MAC_CSL_MIN_PERIOD` (in milliseconds, default 10). Because the CSL IE period field is in units of 10 symbols (160 µs), comparing directly against 10 meant it was mistakenly validating `>= 1.6 ms` instead of `>= 10 ms`. Replacing `kMinCslIePeriod` with `kMinCslPeriod` (which properly converts the configured millisecond period to 10-symbol units) fixes this unit mismatch bug. - Updates `Mle::SetCslTimeout()` to validate the timeout against `kMaxCslTimeout` and return `Error`, simplifying `otLinkSetCslTimeout()`.
This commit is contained in:
@@ -455,7 +455,7 @@ otError otLinkSetCslPeriod(otInstance *aInstance, uint32_t aPeriod)
|
||||
{
|
||||
VerifyOrExit((aPeriod % Radio::kTenSymbolsDuration) == 0, error = kErrorInvalidArgs);
|
||||
periodInTenSymbolsUnit = ClampToUint16(aPeriod / Radio::kTenSymbolsDuration);
|
||||
VerifyOrExit(periodInTenSymbolsUnit >= Radio::kMinCslPeriod, error = kErrorInvalidArgs);
|
||||
VerifyOrExit(periodInTenSymbolsUnit >= Mac::kMinCslPeriod, error = kErrorInvalidArgs);
|
||||
}
|
||||
|
||||
AsCoreType(aInstance).Get<Mac::Mac>().SetCslPeriod(periodInTenSymbolsUnit);
|
||||
@@ -468,13 +468,7 @@ uint32_t otLinkGetCslTimeout(otInstance *aInstance) { return AsCoreType(aInstanc
|
||||
|
||||
otError otLinkSetCslTimeout(otInstance *aInstance, uint32_t aTimeout)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(Radio::kMaxCslTimeout >= aTimeout, error = kErrorInvalidArgs);
|
||||
AsCoreType(aInstance).Get<Mle::Mle>().SetCslTimeout(aTimeout);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
return AsCoreType(aInstance).Get<Mle::Mle>().SetCslTimeout(aTimeout);
|
||||
}
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
|
||||
@@ -247,7 +247,7 @@ public:
|
||||
*
|
||||
* @returns The number of milliseconds.
|
||||
*/
|
||||
static uint32_t constexpr SecToMsec(uint32_t aSeconds) { return aSeconds * 1000u; }
|
||||
static uint32_t constexpr SecToMsec(uint32_t aSeconds) { return aSeconds * kOneSecondInMsec; }
|
||||
|
||||
/**
|
||||
* Converts a given number of milliseconds to seconds.
|
||||
@@ -256,7 +256,16 @@ public:
|
||||
*
|
||||
* @returns The number of seconds.
|
||||
*/
|
||||
static uint32_t constexpr MsecToSec(uint32_t aMilliseconds) { return aMilliseconds / 1000u; }
|
||||
static uint32_t constexpr MsecToSec(uint32_t aMilliseconds) { return aMilliseconds / kOneSecondInMsec; }
|
||||
|
||||
/**
|
||||
* Converts a given number of milliseconds to microseconds.
|
||||
*
|
||||
* @param[in] aMilliseconds The milliseconds value to convert to microseconds.
|
||||
*
|
||||
* @returns The number of microseconds.
|
||||
*/
|
||||
static uint32_t constexpr MsecToUsec(uint32_t aMilliseconds) { return aMilliseconds * kOneMsecInUsec; }
|
||||
|
||||
/**
|
||||
* Converts a given number of microseconds to milliseconds.
|
||||
@@ -265,7 +274,7 @@ public:
|
||||
*
|
||||
* @returns The number of milliseconds.
|
||||
*/
|
||||
static uint32_t constexpr UsecToMsec(uint32_t aMicroseconds) { return aMicroseconds / 1000u; }
|
||||
static uint32_t constexpr UsecToMsec(uint32_t aMicroseconds) { return aMicroseconds / kOneMsecInUsec; }
|
||||
|
||||
private:
|
||||
static constexpr uint32_t kDistantInterval = (1UL << 31) - 1;
|
||||
|
||||
@@ -2568,7 +2568,7 @@ void Mac::ProcessCsl(const RxFrame::ParseInfo &aFrameInfo, const Address &aSrcAd
|
||||
|
||||
VerifyOrExit(neighbor != nullptr);
|
||||
|
||||
VerifyOrExit(csl->GetPeriod() >= kMinCslIePeriod);
|
||||
VerifyOrExit(csl->GetPeriod() >= kMinCslPeriod);
|
||||
|
||||
neighbor->SetCslPeriod(csl->GetPeriod());
|
||||
neighbor->SetCslPhase(csl->GetPhase());
|
||||
|
||||
@@ -699,8 +699,6 @@ private:
|
||||
static constexpr uint8_t kMaxFrameRetriesCsl = 0;
|
||||
static constexpr uint8_t kTxNumBcast = OPENTHREAD_CONFIG_MAC_TX_NUM_BCAST;
|
||||
|
||||
static constexpr uint16_t kMinCslIePeriod = OPENTHREAD_CONFIG_MAC_CSL_MIN_PERIOD;
|
||||
|
||||
static constexpr uint32_t kDefaultWedListenInterval = 1000000;
|
||||
static constexpr uint32_t kDefaultWedListenDuration = 8000;
|
||||
|
||||
|
||||
@@ -48,7 +48,9 @@
|
||||
#include "common/data.hpp"
|
||||
#include "common/equatable.hpp"
|
||||
#include "common/non_copyable.hpp"
|
||||
#include "common/numeric_limits.hpp"
|
||||
#include "common/string.hpp"
|
||||
#include "common/time.hpp"
|
||||
#include "crypto/storage.hpp"
|
||||
#include "radio/radio_types.hpp"
|
||||
|
||||
@@ -868,6 +870,17 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* Minimum CSL period supported in units of 10 symbols.
|
||||
*/
|
||||
constexpr uint16_t kMinCslPeriod =
|
||||
static_cast<uint16_t>(Time::MsecToUsec(OPENTHREAD_CONFIG_MAC_CSL_MIN_PERIOD) / Radio::kTenSymbolsDuration);
|
||||
|
||||
static_assert(kMinCslPeriod > 0, "kMinCslPeriod must be greater than zero");
|
||||
static_assert((Time::MsecToUsec(OPENTHREAD_CONFIG_MAC_CSL_MIN_PERIOD) / Radio::kTenSymbolsDuration) <=
|
||||
NumericLimits<uint16_t>::kMax,
|
||||
"kMinCslPeriod is too large to fit in uint16_t");
|
||||
|
||||
/**
|
||||
* Converts a given CSL period in units of 10 symbols to microseconds.
|
||||
*
|
||||
|
||||
@@ -71,14 +71,6 @@ constexpr uint32_t kHeaderShrDuration = 160; ///< Duration of SHR in us
|
||||
constexpr uint32_t kHeaderPhrDuration = 32; ///< Duration of PHR in us
|
||||
constexpr uint32_t kOctetDuration = 32; ///< Duration of one octet in us
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
/**
|
||||
* Minimum CSL period supported in units of 10 symbols.
|
||||
*/
|
||||
constexpr uint64_t kMinCslPeriod = OPENTHREAD_CONFIG_MAC_CSL_MIN_PERIOD * 1000 / kTenSymbolsDuration;
|
||||
constexpr uint64_t kMaxCslTimeout = OPENTHREAD_CONFIG_MAC_CSL_MAX_TIMEOUT;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_TD_WAKE_LISTENER_ENABLE
|
||||
/**
|
||||
* Minimum wake-up listen duration supported in microseconds.
|
||||
|
||||
+11
-6
@@ -956,10 +956,14 @@ exit:
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
void Mle::SetCslTimeout(uint32_t aTimeout)
|
||||
{
|
||||
VerifyOrExit(mCslTimeout != aTimeout);
|
||||
|
||||
Error Mle::SetCslTimeout(uint32_t aTimeout)
|
||||
{
|
||||
Error error = kErrorNone;
|
||||
|
||||
VerifyOrExit(aTimeout <= kMaxCslTimeout, error = kErrorInvalidArgs);
|
||||
|
||||
VerifyOrExit(mCslTimeout != aTimeout);
|
||||
mCslTimeout = aTimeout;
|
||||
|
||||
Get<DataPollSender>().RecalculatePollPeriod();
|
||||
@@ -970,11 +974,12 @@ void Mle::SetCslTimeout(uint32_t aTimeout)
|
||||
}
|
||||
|
||||
exit:
|
||||
return;
|
||||
return error;
|
||||
}
|
||||
|
||||
bool Mle::IsCslSupported(void) const { return IsChild() && GetParent().IsThreadVersion1p2OrHigher(); }
|
||||
#endif
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
|
||||
void Mle::InitNeighbor(Neighbor &aNeighbor, const RxInfo &aRxInfo)
|
||||
{
|
||||
@@ -3047,7 +3052,7 @@ uint64_t Mle::CalcParentCslMetric(const Mac::CslAccuracy &aCslAccuracy) const
|
||||
|
||||
static constexpr uint64_t usInSecond = 1000000;
|
||||
|
||||
uint64_t cslPeriodUs = Mac::CslPeriodToUsec(Radio::kMinCslPeriod);
|
||||
uint64_t cslPeriodUs = Mac::CslPeriodToUsec(Mac::kMinCslPeriod);
|
||||
uint64_t cslTimeoutUs = GetCslTimeout() * usInSecond;
|
||||
uint64_t k = cslTimeoutUs / cslPeriodUs;
|
||||
|
||||
|
||||
@@ -742,8 +742,11 @@ public:
|
||||
* Sets the CSL timeout.
|
||||
*
|
||||
* @param[in] aTimeout The CSL timeout in seconds.
|
||||
*
|
||||
* @retval kErrorNone Successfully set the CSL timeout.
|
||||
* @retval kErrorInvalidArgs @p aTimeout is larger than the maximum allowed CSL timeout.
|
||||
*/
|
||||
void SetCslTimeout(uint32_t aTimeout);
|
||||
Error SetCslTimeout(uint32_t aTimeout);
|
||||
|
||||
/**
|
||||
* Calculates CSL metric of parent.
|
||||
@@ -1353,6 +1356,9 @@ private:
|
||||
static constexpr uint32_t kDefaultStoreFrameCounterAhead = OPENTHREAD_CONFIG_STORE_FRAME_COUNTER_AHEAD;
|
||||
static constexpr uint32_t kDefaultChildTimeout = OPENTHREAD_CONFIG_MLE_CHILD_TIMEOUT_DEFAULT;
|
||||
static constexpr uint32_t kDefaultCslTimeout = OPENTHREAD_CONFIG_CSL_TIMEOUT;
|
||||
static constexpr uint32_t kMaxCslTimeout = OPENTHREAD_CONFIG_MAC_CSL_MAX_TIMEOUT;
|
||||
|
||||
static_assert(kDefaultCslTimeout <= kMaxCslTimeout, "default CSL timeout exceeds max CSL timeout");
|
||||
|
||||
#if OPENTHREAD_FTD
|
||||
// Advertisement trickle timer constants - all times are in milliseconds.
|
||||
|
||||
@@ -197,7 +197,7 @@ void Test1_2_LP_5_3_2(void)
|
||||
|
||||
// Pre-set CSL parameters on SSED_1 before it joins.
|
||||
ssed1.Get<Mac::Mac>().SetCslPeriod(kCslPeriodInTenSymbols);
|
||||
ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout);
|
||||
SuccessOrQuit(ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout));
|
||||
|
||||
/**
|
||||
* Step 1: All
|
||||
@@ -228,7 +228,7 @@ void Test1_2_LP_5_3_2(void)
|
||||
|
||||
// Override again after Join just in case Join() resets them to defaults.
|
||||
ssed1.Get<Mac::Mac>().SetCslPeriod(kCslPeriodInTenSymbols);
|
||||
ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout);
|
||||
SuccessOrQuit(ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout));
|
||||
|
||||
nexus.AdvanceTime(kAttachAsSsedTime);
|
||||
VerifyOrQuit(ssed1.Get<Mle::Mle>().IsAttached());
|
||||
@@ -241,7 +241,7 @@ void Test1_2_LP_5_3_2(void)
|
||||
Log("Step 2a: SSED_1");
|
||||
|
||||
// Deactivate autosynchronization by setting a very long CSL timeout on SSED_1.
|
||||
ssed1.Get<Mle::Mle>().SetCslTimeout(kDeactivatedCslTimeout);
|
||||
SuccessOrQuit(ssed1.Get<Mle::Mle>().SetCslTimeout(kDeactivatedCslTimeout));
|
||||
|
||||
/**
|
||||
* Step 3: Harness
|
||||
|
||||
@@ -170,7 +170,7 @@ void Test1_2_LP_5_3_3(void)
|
||||
VerifyOrQuit(ssed1.Get<Mle::Mle>().IsAttached());
|
||||
|
||||
ssed1.Get<Mac::Mac>().SetCslPeriod(kCslPeriodMs * 1000 / OT_US_PER_TEN_SYMBOLS);
|
||||
ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout);
|
||||
SuccessOrQuit(ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout));
|
||||
|
||||
nexus.AdvanceTime(kCslSyncTime);
|
||||
VerifyOrQuit(ssed1.Get<Mac::Mac>().GetCslPeriod() > 0);
|
||||
|
||||
@@ -131,7 +131,7 @@ void Test1_2_LP_5_3_4(void)
|
||||
|
||||
ssed1.Join(leader, Node::kAsSed);
|
||||
ssed1.Get<Mac::Mac>().SetCslPeriod(kCslPeriod500ms);
|
||||
ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout20s);
|
||||
SuccessOrQuit(ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout20s));
|
||||
nexus.AdvanceTime(kStabilizationTime);
|
||||
VerifyOrQuit(ssed1.Get<Mle::Mle>().IsAttached());
|
||||
|
||||
|
||||
@@ -196,7 +196,7 @@ void Test1_2_LP_5_3_5(void)
|
||||
{
|
||||
// For SSED_2-6, apply target parameters before joining so they are used in Child ID Request
|
||||
sseds[i]->Get<Mac::Mac>().SetCslPeriod(kCslPeriod500ms);
|
||||
sseds[i]->Get<Mle::Mle>().SetCslTimeout(kCslTimeouts[i]);
|
||||
SuccessOrQuit(sseds[i]->Get<Mle::Mle>().SetCslTimeout(kCslTimeouts[i]));
|
||||
sseds[i]->Get<Mac::Mac>().SetCslChannel(kCslChannels[i]);
|
||||
}
|
||||
|
||||
@@ -229,7 +229,7 @@ void Test1_2_LP_5_3_5(void)
|
||||
|
||||
// Now update SSED_1 to trigger MLE Child Update Request/Response (Criterion 2.2)
|
||||
sseds[0]->Get<Mac::Mac>().SetCslPeriod(kCslPeriod500ms);
|
||||
sseds[0]->Get<Mle::Mle>().SetCslTimeout(kCslTimeouts[0]);
|
||||
SuccessOrQuit(sseds[0]->Get<Mle::Mle>().SetCslTimeout(kCslTimeouts[0]));
|
||||
sseds[0]->Get<Mac::Mac>().SetCslChannel(kCslChannels[0]);
|
||||
|
||||
nexus.AdvanceTime(kStabilizationTime);
|
||||
|
||||
@@ -162,7 +162,7 @@ void Test1_2_LP_5_3_6(void)
|
||||
VerifyOrQuit(ssed1.Get<Mle::Mle>().GetParent().GetExtAddress() == router1.Get<Mac::Mac>().GetExtAddress());
|
||||
|
||||
ssed1.Get<Mac::Mac>().SetCslPeriod(kCslPeriodMs * 1000 / OT_US_PER_TEN_SYMBOLS);
|
||||
ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeoutSec);
|
||||
SuccessOrQuit(ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeoutSec));
|
||||
nexus.AdvanceTime(kStabilizationTime);
|
||||
|
||||
/**
|
||||
|
||||
@@ -159,7 +159,7 @@ void Test1_2_LP_5_3_7(void)
|
||||
ssed1.Join(router1, Node::kAsSed);
|
||||
// Set CSL parameters again to override defaults set by Join()
|
||||
ssed1.Get<Mac::Mac>().SetCslPeriod(kCslPeriod);
|
||||
ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout10s);
|
||||
SuccessOrQuit(ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout10s));
|
||||
ssed1.Get<DataPollSender>().StopPolling();
|
||||
nexus.AdvanceTime(kAttachAsSsedTime);
|
||||
VerifyOrQuit(ssed1.Get<Mle::Mle>().IsAttached());
|
||||
@@ -196,7 +196,7 @@ void Test1_2_LP_5_3_7(void)
|
||||
* Child Update Request.
|
||||
* Pass Criteria: N/A.
|
||||
*/
|
||||
ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout20s);
|
||||
SuccessOrQuit(ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout20s));
|
||||
|
||||
Log("---------------------------------------------------------------------------------------");
|
||||
Log("Step 6: Router_1 (DUT): Automatically responds with MLE Child Update Response.");
|
||||
@@ -244,7 +244,7 @@ void Test1_2_LP_5_3_7(void)
|
||||
* Child Update Request.
|
||||
* Pass Criteria: N/A.
|
||||
*/
|
||||
ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout10s);
|
||||
SuccessOrQuit(ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout10s));
|
||||
|
||||
Log("---------------------------------------------------------------------------------------");
|
||||
Log("Step 10: Router_1 (DUT): Automatically responds with MLE Child Update Response.");
|
||||
|
||||
@@ -162,7 +162,7 @@ void Test5_3_8(void)
|
||||
* - Pass Criteria: N/A.
|
||||
*/
|
||||
|
||||
ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout);
|
||||
SuccessOrQuit(ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout));
|
||||
ssed1.Get<Mac::Mac>().SetCslPeriod(kCslPeriod);
|
||||
|
||||
Log("---------------------------------------------------------------------------------------");
|
||||
|
||||
@@ -190,9 +190,9 @@ void Test1_2_LP_7_2_2(void)
|
||||
SuccessOrQuit(ssed1.Get<DataPollSender>().SetExternalPollPeriod(kPollRate5s));
|
||||
SuccessOrQuit(ssed2.Get<DataPollSender>().SetExternalPollPeriod(kPollRate5s));
|
||||
SuccessOrQuit(ssed3.Get<DataPollSender>().SetExternalPollPeriod(kPollRate5s));
|
||||
ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout);
|
||||
ssed2.Get<Mle::Mle>().SetCslTimeout(kCslTimeout);
|
||||
ssed3.Get<Mle::Mle>().SetCslTimeout(kCslTimeout);
|
||||
SuccessOrQuit(ssed1.Get<Mle::Mle>().SetCslTimeout(kCslTimeout));
|
||||
SuccessOrQuit(ssed2.Get<Mle::Mle>().SetCslTimeout(kCslTimeout));
|
||||
SuccessOrQuit(ssed3.Get<Mle::Mle>().SetCslTimeout(kCslTimeout));
|
||||
|
||||
/**
|
||||
* Step 1: All
|
||||
|
||||
Reference in New Issue
Block a user