mirror of
https://github.com/espressif/openthread.git
synced 2026-08-16 07:37:47 +00:00
[csl] add CslAccuracy type (#8024)
The CSL accuracy is represented as two parameters: clock accuracy in ppm, and uncertainty in units of 10 microseconds. These two parameters are often used together. This commit adds a new class `CslAccuracy` encapsulating both. This new type is used in `Mac` and `Mle` methods allowing us to pass both in one object. This commit also adds `Mle::RxMessage::ReadCslClockAccuracyTlv()` to read and parse the CSL Accuracy TLV value from a given received MLE message.
This commit is contained in:
+7
-25
@@ -643,42 +643,24 @@ public:
|
||||
bool IsCslSupported(void) const;
|
||||
|
||||
/**
|
||||
* This method returns CSL parent clock accuracy, in ± ppm.
|
||||
* This method returns parent CSL accuracy (clock accuracy and uncertainty).
|
||||
*
|
||||
* @retval CSL parent clock accuracy, in ± ppm.
|
||||
* @returns The parent CSL accuracy.
|
||||
*
|
||||
*/
|
||||
uint8_t GetCslParentClockAccuracy(void) const { return mLinks.GetSubMac().GetCslParentClockAccuracy(); }
|
||||
const CslAccuracy &GetCslParentAccuracy(void) const { return mLinks.GetSubMac().GetCslParentAccuracy(); }
|
||||
|
||||
/**
|
||||
* This method sets CSL parent clock accuracy, in ± ppm.
|
||||
* This method sets parent CSL accuracy.
|
||||
*
|
||||
* @param[in] aCslParentAccuracy CSL parent clock accuracy, in ± ppm.
|
||||
* @param[in] aCslAccuracy The parent CSL accuracy.
|
||||
*
|
||||
*/
|
||||
void SetCslParentClockAccuracy(uint8_t aCslParentAccuracy)
|
||||
void SetCslParentAccuracy(const CslAccuracy &aCslAccuracy)
|
||||
{
|
||||
mLinks.GetSubMac().SetCslParentClockAccuracy(aCslParentAccuracy);
|
||||
mLinks.GetSubMac().SetCslParentAccuracy(aCslAccuracy);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns CSL parent uncertainty, in ±10 us units.
|
||||
*
|
||||
* @retval CSL parent uncertainty, in ±10 us units.
|
||||
*
|
||||
*/
|
||||
uint8_t GetCslParentUncertainty(void) const { return mLinks.GetSubMac().GetCslParentUncertainty(); }
|
||||
|
||||
/**
|
||||
* This method returns CSL parent uncertainty, in ±10 us units.
|
||||
*
|
||||
* @param[in] aCslParentUncert CSL parent uncertainty, in ±10 us units.
|
||||
*
|
||||
*/
|
||||
void SetCslParentUncertainty(uint8_t aCslParentUncert)
|
||||
{
|
||||
mLinks.GetSubMac().SetCslParentUncertainty(aCslParentUncert);
|
||||
}
|
||||
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_FILTER_ENABLE && OPENTHREAD_CONFIG_RADIO_LINK_IEEE_802_15_4_ENABLE
|
||||
|
||||
@@ -866,6 +866,73 @@ private:
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* This class represents CSL accuracy.
|
||||
*
|
||||
*/
|
||||
class CslAccuracy
|
||||
{
|
||||
public:
|
||||
static constexpr uint8_t kWorstClockAccuracy = 255; ///< Worst possible crystal accuracy, in units of ± ppm.
|
||||
static constexpr uint8_t kWorstUncertainty = 255; ///< Worst possible uncertainty, in units of 10 microseconds.
|
||||
|
||||
/**
|
||||
* This method initializes the CSL accuracy using `kWorstClockAccuracy` and `kWorstUncertainty` values.
|
||||
*
|
||||
*/
|
||||
void Init(void)
|
||||
{
|
||||
mClockAccuracy = kWorstClockAccuracy;
|
||||
mUncertainty = kWorstUncertainty;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the CSL clock accuracy.
|
||||
*
|
||||
* @returns The CSL clock accuracy in ± ppm.
|
||||
*
|
||||
*/
|
||||
uint8_t GetClockAccuracy(void) const { return mClockAccuracy; }
|
||||
|
||||
/**
|
||||
* This method sets the CSL clock accuracy.
|
||||
*
|
||||
* @param[in] aClockAccuracy The CSL clock accuracy in ± ppm.
|
||||
*
|
||||
*/
|
||||
void SetClockAccuracy(uint8_t aClockAccuracy) { mClockAccuracy = aClockAccuracy; }
|
||||
|
||||
/**
|
||||
* This method returns the CSL uncertainty.
|
||||
*
|
||||
* @returns The uncertainty in units 10 microseconds.
|
||||
*
|
||||
*/
|
||||
uint8_t GetUncertainty(void) const { return mUncertainty; }
|
||||
|
||||
/**
|
||||
* This method gets the CLS uncertainty in microseconds.
|
||||
*
|
||||
* @returns the CLS uncertainty in microseconds.
|
||||
*
|
||||
*/
|
||||
uint16_t GetUncertaintyInMicrosec(void) const { return static_cast<uint16_t>(mUncertainty) * kUsPerUncertUnit; }
|
||||
|
||||
/**
|
||||
* This method sets the CSL uncertainty.
|
||||
*
|
||||
* @param[in] aUncertainty The CSL uncertainty in units 10 microseconds.
|
||||
*
|
||||
*/
|
||||
void SetUncertainty(uint8_t aUncertainty) { mUncertainty = aUncertainty; }
|
||||
|
||||
private:
|
||||
static constexpr uint8_t kUsPerUncertUnit = 10;
|
||||
|
||||
uint8_t mClockAccuracy;
|
||||
uint8_t mUncertainty;
|
||||
};
|
||||
|
||||
/**
|
||||
* @}
|
||||
*
|
||||
|
||||
@@ -61,11 +61,13 @@ SubMac::SubMac(Instance &aInstance)
|
||||
, mPcapCallbackContext(nullptr)
|
||||
, mTimer(aInstance, SubMac::HandleTimer)
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
, mCslParentAccuracy(kCslWorstCrystalPpm)
|
||||
, mCslParentUncert(kCslWorstUncertainty)
|
||||
, mCslTimer(aInstance, SubMac::HandleCslTimer)
|
||||
#endif
|
||||
{
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
mCslParentAccuracy.Init();
|
||||
#endif
|
||||
|
||||
Init();
|
||||
}
|
||||
|
||||
@@ -1149,9 +1151,10 @@ void SubMac::GetCslWindowEdges(uint32_t &aAhead, uint32_t &aAfter)
|
||||
|
||||
elapsed = curTime - mCslLastSync.GetValue();
|
||||
|
||||
semiWindow = static_cast<uint32_t>(static_cast<uint64_t>(elapsed) *
|
||||
(Get<Radio>().GetCslAccuracy() + mCslParentAccuracy) / 1000000);
|
||||
semiWindow += mCslParentUncert * kUsPerUncertUnit;
|
||||
semiWindow =
|
||||
static_cast<uint32_t>(static_cast<uint64_t>(elapsed) *
|
||||
(Get<Radio>().GetCslAccuracy() + mCslParentAccuracy.GetClockAccuracy()) / 1000000);
|
||||
semiWindow += mCslParentAccuracy.GetUncertaintyInMicrosec();
|
||||
|
||||
aAhead = (semiWindow + kCslReceiveTimeAhead > semiPeriod) ? semiPeriod : semiWindow + kCslReceiveTimeAhead;
|
||||
aAfter = (semiWindow + kMinCslWindow > semiPeriod) ? semiPeriod : semiWindow + kMinCslWindow;
|
||||
|
||||
+11
-28
@@ -418,36 +418,20 @@ public:
|
||||
void CslSample(void);
|
||||
|
||||
/**
|
||||
* This method returns CSL parent clock accuracy, in ± ppm.
|
||||
* This method returns parent CSL accuracy (clock accuracy and uncertainty).
|
||||
*
|
||||
* @retval CSL parent clock accuracy.
|
||||
* @returns The parent CSL accuracy.
|
||||
*
|
||||
*/
|
||||
uint8_t GetCslParentClockAccuracy(void) const { return mCslParentAccuracy; }
|
||||
const CslAccuracy &GetCslParentAccuracy(void) const { return mCslParentAccuracy; }
|
||||
|
||||
/**
|
||||
* This method sets CSL parent clock accuracy, in ± ppm.
|
||||
* This method sets parent CSL accuracy.
|
||||
*
|
||||
* @param[in] aCslParentAccuracy CSL parent clock accuracy, in ± ppm.
|
||||
* @param[in] aCslAccuracy The parent CSL accuracy.
|
||||
*
|
||||
*/
|
||||
void SetCslParentClockAccuracy(uint8_t aCslParentAccuracy) { mCslParentAccuracy = aCslParentAccuracy; }
|
||||
|
||||
/**
|
||||
* This method sets CSL parent uncertainty, in ±10 us units.
|
||||
*
|
||||
* @retval CSL parent uncertainty, in ±10 us units.
|
||||
*
|
||||
*/
|
||||
uint8_t GetCslParentUncertainty(void) const { return mCslParentUncert; }
|
||||
|
||||
/**
|
||||
* This method returns CSL parent uncertainty, in ±10 us units.
|
||||
*
|
||||
* @param[in] aCslParentUncert CSL parent uncertainty, in ±10 us units.
|
||||
*
|
||||
*/
|
||||
void SetCslParentUncertainty(uint8_t aCslParentUncert) { mCslParentUncert = aCslParentUncert; }
|
||||
void SetCslParentAccuracy(const CslAccuracy &aCslAccuracy) { mCslParentAccuracy = aCslAccuracy; }
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
|
||||
@@ -662,12 +646,11 @@ private:
|
||||
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.
|
||||
uint16_t mCslPeerShort; // The CSL peer short address.
|
||||
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;
|
||||
uint16_t mCslPeerShort; // The CSL peer short address.
|
||||
TimeMicro mCslSampleTime; // The CSL sample time of the current period.
|
||||
TimeMicro mCslLastSync; // The timestamp of the last successful CSL synchronization.
|
||||
CslAccuracy mCslParentAccuracy; // The parent's CSL accuracy (clock accuracy and uncertainty).
|
||||
TimerMicro mCslTimer;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -56,12 +56,6 @@ static constexpr uint64_t kMinCslPeriod = OPENTHREAD_CONFIG_MAC_CSL_MIN_PERIOD
|
||||
static constexpr uint64_t kMaxCslTimeout = OPENTHREAD_CONFIG_MAC_CSL_MAX_TIMEOUT;
|
||||
#endif
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
static constexpr uint8_t kCslWorstCrystalPpm = 255; ///< Worst possible crystal accuracy, in units of ± ppm.
|
||||
static constexpr uint8_t kCslWorstUncertainty = 255; ///< Worst possible scheduling uncertainty, in units of 10 us.
|
||||
static constexpr uint8_t kUsPerUncertUnit = 10; ///< Number of microseconds by uncertainty unit.
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup core-radio
|
||||
*
|
||||
|
||||
+76
-63
@@ -2984,25 +2984,16 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
bool Mle::IsBetterParent(uint16_t aRloc16,
|
||||
LinkQuality aLinkQuality,
|
||||
uint8_t aLinkMargin,
|
||||
const ConnectivityTlv &aConnectivityTlv,
|
||||
uint16_t aVersion,
|
||||
uint8_t aCslClockAccuracy,
|
||||
uint8_t aCslUncertainty)
|
||||
bool Mle::IsBetterParent(uint16_t aRloc16,
|
||||
LinkQuality aLinkQuality,
|
||||
uint8_t aLinkMargin,
|
||||
const ConnectivityTlv & aConnectivityTlv,
|
||||
uint16_t aVersion,
|
||||
const Mac::CslAccuracy &aCslAccuracy)
|
||||
{
|
||||
bool rval = false;
|
||||
|
||||
bool rval = false;
|
||||
LinkQuality candidateLinkQualityIn = mParentCandidate.GetLinkInfo().GetLinkQuality();
|
||||
LinkQuality candidateTwoWayLinkQuality = Min(candidateLinkQualityIn, mParentCandidate.GetLinkQualityOut());
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
uint64_t candidateCslMetric = 0;
|
||||
uint64_t cslMetric = 0;
|
||||
#else
|
||||
OT_UNUSED_VARIABLE(aCslClockAccuracy);
|
||||
OT_UNUSED_VARIABLE(aCslUncertainty);
|
||||
#endif
|
||||
|
||||
// Mesh Impacting Criteria
|
||||
if (aLinkQuality != candidateTwoWayLinkQuality)
|
||||
@@ -3057,14 +3048,16 @@ bool Mle::IsBetterParent(uint16_t aRloc16,
|
||||
// CSL metric
|
||||
if (!IsRxOnWhenIdle())
|
||||
{
|
||||
cslMetric = CalcParentCslMetric(aCslClockAccuracy, aCslUncertainty);
|
||||
candidateCslMetric =
|
||||
CalcParentCslMetric(mParentCandidate.GetCslClockAccuracy(), mParentCandidate.GetCslUncertainty());
|
||||
uint64_t cslMetric = CalcParentCslMetric(aCslAccuracy);
|
||||
uint64_t candidateCslMetric = CalcParentCslMetric(mParentCandidate.GetCslAccuracy());
|
||||
|
||||
if (candidateCslMetric != cslMetric)
|
||||
{
|
||||
ExitNow(rval = (cslMetric < candidateCslMetric));
|
||||
}
|
||||
}
|
||||
#else
|
||||
OT_UNUSED_VARIABLE(aCslAccuracy);
|
||||
#endif
|
||||
|
||||
rval = (aLinkMargin > mParentLinkMargin);
|
||||
@@ -3088,12 +3081,10 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo)
|
||||
uint32_t linkFrameCounter;
|
||||
uint32_t mleFrameCounter;
|
||||
Mac::ExtAddress extAddress;
|
||||
Mac::CslAccuracy cslAccuracy;
|
||||
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
|
||||
TimeParameterTlv timeParameter;
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
CslClockAccuracyTlv clockAccuracy;
|
||||
#endif
|
||||
|
||||
// Source Address
|
||||
SuccessOrExit(error = Tlv::Find<SourceAddressTlv>(aRxInfo.mMessage, sourceAddress));
|
||||
@@ -3136,15 +3127,18 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo)
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
// CSL Accuracy
|
||||
if (Tlv::FindTlv(aRxInfo.mMessage, clockAccuracy) == kErrorNone)
|
||||
switch (aRxInfo.mMessage.ReadCslClockAccuracyTlv(cslAccuracy))
|
||||
{
|
||||
VerifyOrExit(clockAccuracy.IsValid(), error = kErrorParse);
|
||||
}
|
||||
else
|
||||
{
|
||||
clockAccuracy.SetCslClockAccuracy(kCslWorstCrystalPpm);
|
||||
clockAccuracy.SetCslUncertainty(kCslWorstUncertainty);
|
||||
case kErrorNone:
|
||||
break;
|
||||
case kErrorNotFound:
|
||||
cslAccuracy.Init(); // Use worst-case values if TLV is not found
|
||||
break;
|
||||
default:
|
||||
ExitNow(error = kErrorParse);
|
||||
}
|
||||
#else
|
||||
cslAccuracy.Init();
|
||||
#endif
|
||||
|
||||
// Share data with application, if requested.
|
||||
@@ -3221,14 +3215,10 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo)
|
||||
#endif
|
||||
|
||||
// only consider better parents if the partitions are the same
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
VerifyOrExit(compare != 0 ||
|
||||
IsBetterParent(sourceAddress, linkQuality, linkMargin, connectivity, version,
|
||||
clockAccuracy.GetCslClockAccuracy(), clockAccuracy.GetCslUncertainty()));
|
||||
#else
|
||||
VerifyOrExit(compare != 0 ||
|
||||
IsBetterParent(sourceAddress, linkQuality, linkMargin, connectivity, version, 0, 0));
|
||||
#endif
|
||||
if (compare == 0)
|
||||
{
|
||||
VerifyOrExit(IsBetterParent(sourceAddress, linkQuality, linkMargin, connectivity, version, cslAccuracy));
|
||||
}
|
||||
}
|
||||
|
||||
// Link/MLE Frame Counters
|
||||
@@ -3273,8 +3263,7 @@ void Mle::HandleParentResponse(RxInfo &aRxInfo)
|
||||
mParentCandidate.SetState(Neighbor::kStateParentResponse);
|
||||
mParentCandidate.SetKeySequence(aRxInfo.mKeySequence);
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
mParentCandidate.SetCslClockAccuracy(clockAccuracy.GetCslClockAccuracy());
|
||||
mParentCandidate.SetCslUncertainty(clockAccuracy.GetCslUncertainty());
|
||||
mParentCandidate.SetCslAccuracy(cslAccuracy);
|
||||
#endif
|
||||
|
||||
mParentPriority = connectivity.GetParentPriority();
|
||||
@@ -3401,8 +3390,7 @@ void Mle::HandleChildIdResponse(RxInfo &aRxInfo)
|
||||
mParentCandidate.Clear();
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
Get<Mac::Mac>().SetCslParentUncertainty(mParent.GetCslUncertainty());
|
||||
Get<Mac::Mac>().SetCslParentClockAccuracy(mParent.GetCslClockAccuracy());
|
||||
Get<Mac::Mac>().SetCslParentAccuracy(mParent.GetCslAccuracy());
|
||||
#endif
|
||||
|
||||
mParent.SetRloc16(sourceAddress);
|
||||
@@ -3482,11 +3470,14 @@ void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo)
|
||||
SuccessOrExit(error = HandleLeaderData(aRxInfo));
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
CslClockAccuracyTlv cslClockAccuracyTlv;
|
||||
if (Tlv::FindTlv(aRxInfo.mMessage, cslClockAccuracyTlv) == kErrorNone)
|
||||
{
|
||||
// MUST include CSL timeout TLV when request includes CSL accuracy
|
||||
tlvList.Add(Tlv::kCslTimeout);
|
||||
Mac::CslAccuracy cslAccuracy;
|
||||
|
||||
if (aRxInfo.mMessage.ReadCslClockAccuracyTlv(cslAccuracy) == kErrorNone)
|
||||
{
|
||||
// MUST include CSL timeout TLV when request includes CSL accuracy
|
||||
tlvList.Add(Tlv::kCslTimeout);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -3533,9 +3524,6 @@ void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo)
|
||||
uint32_t mleFrameCounter;
|
||||
uint16_t sourceAddress;
|
||||
uint32_t timeout;
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
CslClockAccuracyTlv clockAccuracy;
|
||||
#endif
|
||||
|
||||
Log(kMessageReceive, kTypeChildUpdateResponseOfParent, aRxInfo.mMessageInfo.GetPeerAddr());
|
||||
|
||||
@@ -3625,12 +3613,20 @@ void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo)
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
// CSL Accuracy
|
||||
if (Tlv::FindTlv(aRxInfo.mMessage, clockAccuracy) == kErrorNone)
|
||||
{
|
||||
VerifyOrExit(clockAccuracy.IsValid(), error = kErrorParse);
|
||||
Get<Mac::Mac>().SetCslParentClockAccuracy(clockAccuracy.GetCslClockAccuracy());
|
||||
Get<Mac::Mac>().SetCslParentUncertainty(clockAccuracy.GetCslUncertainty());
|
||||
Mac::CslAccuracy cslAccuracy;
|
||||
|
||||
// CSL Accuracy
|
||||
switch (aRxInfo.mMessage.ReadCslClockAccuracyTlv(cslAccuracy))
|
||||
{
|
||||
case kErrorNone:
|
||||
Get<Mac::Mac>().SetCslParentAccuracy(cslAccuracy);
|
||||
break;
|
||||
case kErrorNotFound:
|
||||
break;
|
||||
default:
|
||||
ExitNow(error = kErrorParse);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -4332,18 +4328,19 @@ void Mle::RegisterParentResponseStatsCallback(otThreadParentResponseCallback aCa
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
uint64_t Mle::CalcParentCslMetric(uint8_t aCslClockAccuracy, uint8_t aCslUncertainty)
|
||||
uint64_t Mle::CalcParentCslMetric(const Mac::CslAccuracy &aCslAccuracy)
|
||||
{
|
||||
/*
|
||||
* This function calculates the overall time that device will operate on battery
|
||||
* by summming sequence of "ON quants" over a period of time.
|
||||
*/
|
||||
const uint64_t usInSecond = 1000000;
|
||||
uint64_t cslPeriodUs = kMinCslPeriod * kUsPerTenSymbols;
|
||||
uint64_t cslTimeoutUs = GetCslTimeout() * usInSecond;
|
||||
uint64_t k = cslTimeoutUs / cslPeriodUs;
|
||||
// This function calculates the overall time that device will operate
|
||||
// on battery by summing sequence of "ON quants" over a period of time.
|
||||
|
||||
return k * (k + 1) * cslPeriodUs / usInSecond * aCslClockAccuracy + aCslUncertainty * k * kUsPerUncertUnit;
|
||||
static constexpr uint64_t usInSecond = 1000000;
|
||||
|
||||
uint64_t cslPeriodUs = kMinCslPeriod * kUsPerTenSymbols;
|
||||
uint64_t cslTimeoutUs = GetCslTimeout() * usInSecond;
|
||||
uint64_t k = cslTimeoutUs / cslPeriodUs;
|
||||
|
||||
return k * (k + 1) * cslPeriodUs / usInSecond * aCslAccuracy.GetClockAccuracy() +
|
||||
aCslAccuracy.GetUncertaintyInMicrosec() * k;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -5091,5 +5088,21 @@ exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
Error Mle::RxMessage::ReadCslClockAccuracyTlv(Mac::CslAccuracy &aCslAccuracy) const
|
||||
{
|
||||
Error error;
|
||||
CslClockAccuracyTlv clockAccuracyTlv;
|
||||
|
||||
SuccessOrExit(error = Tlv::FindTlv(*this, clockAccuracyTlv));
|
||||
VerifyOrExit(clockAccuracyTlv.IsValid(), error = kErrorParse);
|
||||
aCslAccuracy.SetClockAccuracy(clockAccuracyTlv.GetCslClockAccuracy());
|
||||
aCslAccuracy.SetUncertainty(clockAccuracyTlv.GetCslUncertainty());
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace Mle
|
||||
} // namespace ot
|
||||
|
||||
+23
-10
@@ -773,12 +773,12 @@ public:
|
||||
/**
|
||||
* This method calculates CSL metric of parent.
|
||||
*
|
||||
* @param[in] aCslClockAccuracy The CSL Clock Accuracy.
|
||||
* @param[in] aCslUncertainty The CSL Uncertainty.
|
||||
* @param[in] aCslAccuracy The CSL accuracy.
|
||||
*
|
||||
* @returns CSL metric.
|
||||
*
|
||||
*/
|
||||
uint64_t CalcParentCslMetric(uint8_t aCslClockAccuracy, uint8_t aCslUncertainty);
|
||||
uint64_t CalcParentCslMetric(const Mac::CslAccuracy &aCslAccuracy);
|
||||
|
||||
#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
|
||||
@@ -1424,6 +1424,20 @@ protected:
|
||||
*/
|
||||
Error ReadLeaderDataTlv(LeaderData &aLeaderData) const;
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
/**
|
||||
* This method reads CSL Clock Accuracy TLV from a message.
|
||||
*
|
||||
* @param[out] A reference to output the CSL accuracy.
|
||||
*
|
||||
* @retval kErrorNone Successfully read the TLV.
|
||||
* @retval kErrorNotFound TLV was not found in the message.
|
||||
* @retval kErrorParse TLV was found but could not be parsed.
|
||||
*
|
||||
*/
|
||||
Error ReadCslClockAccuracyTlv(Mac::CslAccuracy &aCslAccuracy) const;
|
||||
#endif
|
||||
|
||||
private:
|
||||
Error ReadChallengeOrResponse(uint8_t aTlvType, Challenge &aBuffer) const;
|
||||
};
|
||||
@@ -2009,13 +2023,12 @@ private:
|
||||
bool HasAcceptableParentCandidate(void) const;
|
||||
Error DetermineParentRequestType(ParentRequestType &aType) const;
|
||||
|
||||
bool IsBetterParent(uint16_t aRloc16,
|
||||
LinkQuality aLinkQuality,
|
||||
uint8_t aLinkMargin,
|
||||
const ConnectivityTlv &aConnectivityTlv,
|
||||
uint16_t aVersion,
|
||||
uint8_t aCslClockAccuracy,
|
||||
uint8_t aCslUncertainty);
|
||||
bool IsBetterParent(uint16_t aRloc16,
|
||||
LinkQuality aLinkQuality,
|
||||
uint8_t aLinkMargin,
|
||||
const ConnectivityTlv & aConnectivityTlv,
|
||||
uint16_t aVersion,
|
||||
const Mac::CslAccuracy &aCslAccuracy);
|
||||
bool IsNetworkDataNewer(const LeaderData &aLeaderData);
|
||||
|
||||
Error ProcessMessageSecurity(Crypto::AesCcm::Mode aMode,
|
||||
|
||||
@@ -527,8 +527,8 @@ void Router::Info::SetFrom(const Router &aRouter)
|
||||
mAge = static_cast<uint8_t>(Time::MsecToSec(TimerMilli::GetNow() - aRouter.GetLastHeard()));
|
||||
mVersion = ClampToUint8(aRouter.GetVersion());
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
mCslClockAccuracy = aRouter.GetCslClockAccuracy();
|
||||
mCslUncertainty = aRouter.GetCslUncertainty();
|
||||
mCslClockAccuracy = aRouter.GetCslAccuracy().GetClockAccuracy();
|
||||
mCslUncertainty = aRouter.GetCslAccuracy().GetUncertainty();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -1365,8 +1365,7 @@ public:
|
||||
{
|
||||
Neighbor::Init(aInstance);
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
SetCslClockAccuracy(kCslWorstCrystalPpm);
|
||||
SetCslUncertainty(kCslWorstUncertainty);
|
||||
mCslAccuracy.Init();
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1426,36 +1425,20 @@ public:
|
||||
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
/**
|
||||
* This method get the CSL clock accuracy of this router.
|
||||
* This method gets the CSL accuracy (clock accuracy and uncertainty).
|
||||
*
|
||||
* @returns The CSL clock accuracy of this router.
|
||||
* @returns The CSL accuracy.
|
||||
*
|
||||
*/
|
||||
uint8_t GetCslClockAccuracy(void) const { return mCslClockAccuracy; }
|
||||
const Mac::CslAccuracy &GetCslAccuracy(void) const { return mCslAccuracy; }
|
||||
|
||||
/**
|
||||
* This method sets the CSL clock accuracy of this router.
|
||||
* This method sets CSL accuracy.
|
||||
*
|
||||
* @param[in] aCslClockAccuracy The CSL clock accuracy of this router.
|
||||
* @param[in] aCslAccuracy The CSL accuracy.
|
||||
*
|
||||
*/
|
||||
void SetCslClockAccuracy(uint8_t aCslClockAccuracy) { mCslClockAccuracy = aCslClockAccuracy; }
|
||||
|
||||
/**
|
||||
* This method get the CSL clock uncertainty of this router.
|
||||
*
|
||||
* @returns The CSL clock uncertainty of this router.
|
||||
*
|
||||
*/
|
||||
uint8_t GetCslUncertainty(void) const { return mCslUncertainty; }
|
||||
|
||||
/**
|
||||
* This method sets the CSL clock uncertainty of this router.
|
||||
*
|
||||
* @param[in] aCslUncertainty The CSL clock uncertainty of this router.
|
||||
*
|
||||
*/
|
||||
void SetCslUncertainty(uint8_t aCslUncertainty) { mCslUncertainty = aCslUncertainty; }
|
||||
void SetCslAccuracy(const Mac::CslAccuracy &aCslAccuracy) { mCslAccuracy = aCslAccuracy; }
|
||||
#endif
|
||||
|
||||
private:
|
||||
@@ -1468,8 +1451,7 @@ private:
|
||||
uint8_t mCost : 4; ///< The cost to this router via neighbor router
|
||||
#endif
|
||||
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
|
||||
uint8_t mCslClockAccuracy; ///< Crystal accuracy, in units of ± ppm.
|
||||
uint8_t mCslUncertainty; ///< Scheduling uncertainty, in units of 10 us.
|
||||
Mac::CslAccuracy mCslAccuracy; // CSL accuracy (clock accuracy in ppm and uncertainty).
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user