From 02d968baa61cf783741da5cb19e7f4e81d36e6d6 Mon Sep 17 00:00:00 2001 From: canisLupus1313 <85344032+canisLupus1313@users.noreply.github.com> Date: Sat, 24 Jul 2021 02:08:05 +0200 Subject: [PATCH] [csl] add TLV for CSL clock accuracy (#6802) --- include/openthread/instance.h | 2 +- include/openthread/platform/radio.h | 10 +++ src/core/config/platform.h | 10 +++ src/core/mac/mac.hpp | 38 ++++++++ src/core/mac/sub_mac.cpp | 4 +- src/core/mac/sub_mac.hpp | 47 +++++++--- src/core/radio/radio.hpp | 39 ++++++++- src/core/radio/radio_platform.cpp | 7 ++ src/core/thread/mle.cpp | 87 ++++++++++++++++++- src/core/thread/mle.hpp | 27 +++++- src/core/thread/mle_router.cpp | 6 ++ src/core/thread/mle_tlvs.hpp | 58 +++++++++++++ src/core/thread/topology.hpp | 48 +++++++++- tests/scripts/thread-cert/config.py | 1 + tests/scripts/thread-cert/mesh_cop.py | 1 + tests/scripts/thread-cert/mle.py | 14 +++ tests/scripts/thread-cert/pktverify/consts.py | 1 + 17 files changed, 380 insertions(+), 20 deletions(-) diff --git a/include/openthread/instance.h b/include/openthread/instance.h index dd46453b3..df5dca641 100644 --- a/include/openthread/instance.h +++ b/include/openthread/instance.h @@ -53,7 +53,7 @@ extern "C" { * @note This number versions both OpenThread platform and user APIs. * */ -#define OPENTHREAD_API_VERSION (140) +#define OPENTHREAD_API_VERSION (141) /** * @addtogroup api-instance diff --git a/include/openthread/platform/radio.h b/include/openthread/platform/radio.h index 8fd87d463..f0b21c378 100644 --- a/include/openthread/platform/radio.h +++ b/include/openthread/platform/radio.h @@ -1018,6 +1018,16 @@ void otPlatRadioUpdateCslSampleTime(otInstance *aInstance, uint32_t aCslSampleTi */ uint8_t otPlatRadioGetCslAccuracy(otInstance *aInstance); +/** + * Get the current uncertainty, in units of 10 us, of the clock used for scheduling CSL operations. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * + * @returns The current CSL Clock Uncertainty in units of 10 us. + * + */ +uint8_t otPlatRadioGetCslClockUncertainty(otInstance *aInstance); + /** * Set the max transmit power for a specific channel. * diff --git a/src/core/config/platform.h b/src/core/config/platform.h index 59539f799..e1c082e84 100644 --- a/src/core/config/platform.h +++ b/src/core/config/platform.h @@ -146,4 +146,14 @@ #endif #endif +/** + * @def OPENTHREAD_CONFIG_PLATFORM_CSL_UNCERT + * + * The Uncertainty of the scheduling CSL of transmission by the parent, in ±10 us units. + * + */ +#ifndef OPENTHREAD_CONFIG_PLATFORM_CSL_UNCERT +#define OPENTHREAD_CONFIG_PLATFORM_CSL_UNCERT UINT8_MAX +#endif + #endif // CONFIG_PLATFORM_H_ diff --git a/src/core/mac/mac.hpp b/src/core/mac/mac.hpp index f8d86f743..a6c022d5d 100644 --- a/src/core/mac/mac.hpp +++ b/src/core/mac/mac.hpp @@ -713,6 +713,44 @@ public: */ bool IsCslEnabled(void) const; + /** + * This method returns CSL parent clock accuracy, in ± ppm. + * + * @retval CSL parent clock accuracy, in ± ppm. + * + */ + uint8_t GetCslParentClockAccuracy(void) const { return mLinks.GetSubMac().GetCslParentClockAccuracy(); } + + /** + * This method sets CSL parent clock accuracy, in ± ppm. + * + * @param[in] aCslParentAccuracy CSL parent clock accuracy, in ± ppm. + * + */ + void SetCslParentClockAccuracy(uint8_t aCslParentAccuracy) + { + mLinks.GetSubMac().SetCslParentClockAccuracy(aCslParentAccuracy); + } + + /** + * This method returns CSL parent uncertanity, in ±10 us units. + * + * @retval CSL parent uncertanity, in ±10 us units. + * + */ + uint8_t GetCslParentUncertanity(void) const { return mLinks.GetSubMac().GetCslParentUncertanity(); } + + /** + * This method returns CSL parent uncertanity, in ±10 us units. + * + * @param[in] aCslParentUncert CSL parent uncertanity, in ±10 us units. + * + */ + void SetCslParentUncertanity(uint8_t aCslParentUncert) + { + mLinks.GetSubMac().SetCslParentUncertanity(aCslParentUncert); + } + #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE private: diff --git a/src/core/mac/sub_mac.cpp b/src/core/mac/sub_mac.cpp index acc9f958f..eeffbe5f5 100644 --- a/src/core/mac/sub_mac.cpp +++ b/src/core/mac/sub_mac.cpp @@ -71,7 +71,7 @@ SubMac::SubMac(Instance &aInstance) , mCslChannel(0) , mIsCslChannelSpecified(false) , mCslLastSync(0) - , mCslParentDrift(kCslWorstCrystalPpm) + , mCslParentAccuracy(kCslWorstCrystalPpm) , mCslParentUncert(kCslWorstUncertainty) , mCslState(kCslIdle) , mCslTimer(aInstance, SubMac::HandleCslTimer) @@ -1070,7 +1070,7 @@ void SubMac::GetCslWindowEdges(uint32_t &ahead, uint32_t &after) elapsed = curTime - mCslLastSync.GetValue(); } - semiWindow = static_cast(elapsed * (Get().GetCslAccuracy() + mCslParentDrift) / 1000000); + semiWindow = static_cast(elapsed * (Get().GetCslAccuracy() + mCslParentAccuracy) / 1000000); semiWindow += mCslParentUncert * kUsPerUncertUnit; ahead = (semiWindow + kCslReceiveTimeAhead > semiPeriod) ? semiPeriod : semiWindow + kCslReceiveTimeAhead; diff --git a/src/core/mac/sub_mac.hpp b/src/core/mac/sub_mac.hpp index b6926a7fd..9ab0c0957 100644 --- a/src/core/mac/sub_mac.hpp +++ b/src/core/mac/sub_mac.hpp @@ -442,6 +442,38 @@ public: */ void SetCslPeriod(uint16_t aPeriod); + /** + * This method returns CSL parent clock accuracy, in ± ppm. + * + * @retval CSL parent clock accuracy. + * + */ + uint8_t GetCslParentClockAccuracy(void) const { return mCslParentAccuracy; } + + /** + * This method sets CSL parent clock accuracy, in ± ppm. + * + * @param[in] aCslParentAccuracy CSL parent clock accuracy, in ± ppm. + * + */ + void SetCslParentClockAccuracy(uint8_t aCslParentAccuracy) { mCslParentAccuracy = aCslParentAccuracy; } + + /** + * This method sets CSL parent uncertanity, in ±10 us units. + * + * @retval CSL parent uncertanity, in ±10 us units. + * + */ + uint8_t GetCslParentUncertanity(void) const { return mCslParentUncert; } + + /** + * This method returns CSL parent uncertanity, in ±10 us units. + * + * @param[in] aCslParentUncert CSL parent uncertanity, in ±10 us units. + * + */ + void SetCslParentUncertanity(uint8_t aCslParentUncert) { mCslParentUncert = aCslParentUncert; } + #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE /** @@ -544,13 +576,6 @@ private: ///< than expected sample window. The time is in unit of ///< microseconds. }; - - enum : uint8_t{ - kCslWorstCrystalPpm = 255, ///< Worst possible crystal accuracy, in units of ± ppm. - kCslWorstUncertainty = 255, ///< Worst possible scheduling uncertainty, in units of 100 us. - kUsPerUncertUnit = 100, ///< Number of microseconds by uncertainty unit. - }; - /** * CSL state, always updated by `mCslTimer`. * @@ -633,10 +658,10 @@ private: uint8_t mIsCslChannelSpecified : 1; ///< Indicates whether or not the CSL channel was explicitly specified by ///< the user. - TimeMicro mCslSampleTime; ///< The CSL sample time of the current period. - TimeMicro mCslLastSync; ///< The timestamp of the last successful CSL syncronization. - uint8_t mCslParentDrift; ///< Drift of timer used for scheduling CSL transmission by the parent, in ± ppm. - uint8_t mCslParentUncert; ///< Uncertainty of the scheduling CSL of transmission by the parent, in ±100 us units. + TimeMicro mCslSampleTime; ///< The CSL sample time of the current period. + TimeMicro mCslLastSync; ///< The timestamp of the last successful CSL syncronization. + uint8_t mCslParentAccuracy; ///< Drift of timer used for scheduling CSL transmission by the parent, in ± ppm. + uint8_t mCslParentUncert; ///< Uncertainty of the scheduling CSL of transmission by the parent, in ±10 us units. CslState mCslState; diff --git a/src/core/radio/radio.hpp b/src/core/radio/radio.hpp index 808380ec3..79d1ddfb2 100644 --- a/src/core/radio/radio.hpp +++ b/src/core/radio/radio.hpp @@ -54,6 +54,15 @@ enum #endif }; +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE +enum : uint8_t +{ + kCslWorstCrystalPpm = 255, ///< Worst possible crystal accuracy, in units of ± ppm. + kCslWorstUncertainty = 255, ///< Worst possible scheduling uncertainty, in units of 10 us. + kUsPerUncertUnit = 10, ///< Number of microseconds by uncertainty unit. +}; +#endif + /** * @addtogroup core-radio * @@ -449,7 +458,9 @@ public: * */ Error EnableCsl(uint32_t aCslPeriod, otShortAddress aShortAddr, const otExtAddress *aExtAddr); +#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE /** * Get the current accuracy, in units of ± ppm, of the clock used for scheduling CSL operations. * @@ -459,7 +470,17 @@ public: * */ uint8_t GetCslAccuracy(void); -#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + + /** + * Get the current uncertainty, in units of 10 us, of the clock used for scheduling CSL operations. + * + * @param[in] aInstance A pointer to an OpenThread instance. + * + * @returns The current CSL Clock Uncertainty in units of 10 us. + * + */ + uint8_t GetCslClockUncertainty(void); +#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE /** * This method gets the radio transmit frame buffer. @@ -775,11 +796,18 @@ inline Error Radio::EnableCsl(uint32_t aCslPeriod, otShortAddress aShortAddr, co { return otPlatRadioEnableCsl(GetInstancePtr(), aCslPeriod, aShortAddr, aExtAddr); } +#endif -inline uint8_t Radio::GetCslAccuracy() +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE +inline uint8_t Radio::GetCslAccuracy(void) { return otPlatRadioGetCslAccuracy(GetInstancePtr()); } + +inline uint8_t Radio::GetCslClockUncertainty(void) +{ + return otPlatRadioGetCslClockUncertainty(GetInstancePtr()); +} #endif inline Mac::TxFrame &Radio::GetTransmitBuffer(void) @@ -933,11 +961,18 @@ inline Error Radio::EnableCsl(uint32_t, otShortAddress aShortAddr, const otExtAd { return kErrorNotImplemented; } +#endif +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE inline uint8_t Radio::GetCslAccuracy(void) { return UINT8_MAX; } + +inline uint8_t Radio::GetCslClockUncertainty(void) +{ + return UINT8_MAX; +} #endif inline Mac::TxFrame &Radio::GetTransmitBuffer(void) diff --git a/src/core/radio/radio_platform.cpp b/src/core/radio/radio_platform.cpp index f80c3041c..048bc638c 100644 --- a/src/core/radio/radio_platform.cpp +++ b/src/core/radio/radio_platform.cpp @@ -249,6 +249,13 @@ OT_TOOL_WEAK uint8_t otPlatRadioGetCslAccuracy(otInstance *aInstance) return UINT8_MAX; } +OT_TOOL_WEAK uint8_t otPlatRadioGetCslClockUncertainty(otInstance *aInstance) +{ + OT_UNUSED_VARIABLE(aInstance); + + return OPENTHREAD_CONFIG_PLATFORM_CSL_UNCERT; +} + OT_TOOL_WEAK Error otPlatRadioGetFemLnaGain(otInstance *aInstance, int8_t *aGain) { OT_UNUSED_VARIABLE(aInstance); diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 296fa974d..fd1a03eeb 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -1493,6 +1493,24 @@ exit: } #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE +#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE +Error Mle::AppendCslClockAccuracy(Message &aMessage) +{ + Error error = kErrorNone; + CslClockAccuracyTlv cslClockAccuracy; + + cslClockAccuracy.Init(); + + cslClockAccuracy.SetCslClockAccuracy(Get().GetCslAccuracy()); + cslClockAccuracy.SetCslUncertainty(Get().GetCslClockUncertainty()); + + SuccessOrExit(error = aMessage.Append(cslClockAccuracy)); + +exit: + return error; +} +#endif + void Mle::HandleNotifierEvents(Events aEvents) { VerifyOrExit(!IsDisabled()); @@ -3211,7 +3229,9 @@ bool Mle::IsBetterParent(uint16_t aRloc16, uint8_t aLinkQuality, uint8_t aLinkMargin, const ConnectivityTlv &aConnectivityTlv, - uint8_t aVersion) + uint8_t aVersion, + uint8_t aCslClockAccuracy, + uint8_t aCslUncertainty) { bool rval = false; @@ -3219,6 +3239,13 @@ bool Mle::IsBetterParent(uint16_t aRloc16, uint8_t candidateTwoWayLinkQuality = (candidateLinkQualityIn < mParentCandidate.GetLinkQualityOut()) ? 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) @@ -3269,6 +3296,20 @@ bool Mle::IsBetterParent(uint16_t aRloc16, ExitNow(rval = (aConnectivityTlv.GetLinkQuality1() > mParentLinkQuality1)); } +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + // CSL metric + if (!IsRxOnWhenIdle()) + { + cslMetric = CalcParentCslMetric(aCslClockAccuracy, aCslUncertainty); + candidateCslMetric = + CalcParentCslMetric(mParentCandidate.GetCslClockAccuracy(), mParentCandidate.GetCslClockUncertianity()); + if (candidateCslMetric != cslMetric) + { + ExitNow(rval = (cslMetric < candidateCslMetric)); + } + } +#endif + rval = (aLinkMargin > mParentLinkMargin); exit: @@ -3293,6 +3334,9 @@ void Mle::HandleParentResponse(const Message &aMessage, const Ip6::MessageInfo & #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(aMessage, sourceAddress)); @@ -3402,9 +3446,23 @@ void Mle::HandleParentResponse(const Message &aMessage, const Ip6::MessageInfo & VerifyOrExit(compare >= 0); #endif +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + if (Tlv::FindTlv(aMessage, clockAccuracy) != kErrorNone) + { + clockAccuracy.SetCslClockAccuracy(kCslWorstCrystalPpm); + clockAccuracy.SetCslUncertainty(kCslWorstUncertainty); + } +#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, static_cast(version), + clockAccuracy.GetCslClockAccuracy(), clockAccuracy.GetCslUncertainty())); +#else VerifyOrExit(compare != 0 || IsBetterParent(sourceAddress, linkQuality, linkMargin, connectivity, - static_cast(version))); + static_cast(version), 0, 0)); +#endif } // Link/MLE Frame Counters @@ -3448,6 +3506,10 @@ void Mle::HandleParentResponse(const Message &aMessage, const Ip6::MessageInfo & mParentCandidate.SetLinkQualityOut(LinkQualityInfo::ConvertLinkMarginToLinkQuality(linkMarginFromTlv)); mParentCandidate.SetState(Neighbor::kStateParentResponse); mParentCandidate.SetKeySequence(aKeySequence); +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + mParentCandidate.SetCslClockAccuracy(clockAccuracy.GetCslClockAccuracy()); + mParentCandidate.SetCslClockUncertianity(clockAccuracy.GetCslUncertainty()); +#endif mParentPriority = connectivity.GetParentPriority(); mParentLinkQuality3 = connectivity.GetLinkQuality3(); @@ -3576,6 +3638,11 @@ void Mle::HandleChildIdResponse(const Message & aMessage, mParent = mParentCandidate; mParentCandidate.Clear(); +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + Get().SetCslParentUncertanity(mParent.GetCslClockUncertianity()); + Get().SetCslParentClockAccuracy(mParent.GetCslClockAccuracy()); +#endif + mParent.SetRloc16(sourceAddress); IgnoreError(Get().SetNetworkData(leaderData.GetDataVersion(), @@ -4438,6 +4505,22 @@ void Mle::RegisterParentResponseStatsCallback(otThreadParentResponseCallback aCa mParentResponseCbContext = aContext; } +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE +uint64_t Mle::CalcParentCslMetric(uint8_t aCslClockAccuracy, uint8_t aCslUncertainty) +{ + /* + * 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; + + return k * (k + 1) * cslPeriodUs / usInSecond * aCslClockAccuracy + aCslUncertainty * k * kUsPerUncertUnit; +} +#endif + void Mle::Challenge::GenerateRandom(void) { mLength = kMaxChallengeSize; diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index 6e1f41fa8..109fb6922 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -745,6 +745,17 @@ public: * */ void SetCslTimeout(uint32_t aTimeout); + + /** + * This method calculates CSL metric of parent. + * + * @param[in] aCslClockAccuracy The CSL Clock Accuracy. + * @param[in] aCslUncertainty The CSL Uncertainty. + * + * @returns CSL metric. + */ + uint64_t CalcParentCslMetric(uint8_t aCslClockAccuracy, uint8_t aCslUncertainty); + #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE protected: @@ -1299,6 +1310,18 @@ protected: Error AppendCslTimeout(Message &aMessage); #endif // (OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE) || OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE + /** + * This method appends a CSL Clock Accuracy TLV to a message. + * + * @param[in] aMessage A reference to the message. + * + * @retval kErrorNone Successfully appended the CSL Accuracy TLV. + * @retval kErrorNoBufs Insufficient buffers available to append the CSL Accuracy TLV. + */ + Error AppendCslClockAccuracy(Message &aMessage); +#endif + /** * This method appends a Active Timestamp TLV to a message. * @@ -1794,7 +1817,9 @@ private: uint8_t aLinkQuality, uint8_t aLinkMargin, const ConnectivityTlv &aConnectivityTlv, - uint8_t aVersion); + uint8_t aVersion, + uint8_t aCslClockAccuracy, + uint8_t aCslUncertainty); bool IsNetworkDataNewer(const LeaderData &aLeaderData); #if OPENTHREAD_CONFIG_TMF_NETDATA_SERVICE_ENABLE diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index e58f0c347..213612cc6 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -1937,6 +1937,12 @@ void MleRouter::SendParentResponse(Child *aChild, const Challenge &aChallenge, b SuccessOrExit(error = AppendTimeParameter(*message)); } #endif +#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE + if (!aChild->IsRxOnWhenIdle()) + { + SuccessOrExit(error = AppendCslClockAccuracy(*message)); + } +#endif aChild->GenerateChallenge(); diff --git a/src/core/thread/mle_tlvs.hpp b/src/core/thread/mle_tlvs.hpp index 4da6c306f..f697bb0a0 100644 --- a/src/core/thread/mle_tlvs.hpp +++ b/src/core/thread/mle_tlvs.hpp @@ -104,6 +104,7 @@ public: kDiscovery = 26, ///< Thread Discovery TLV kCslChannel = 80, ///< CSL Channel TLV kCslTimeout = 85, ///< CSL Timeout TLV + kCslClockAccuracy = 86, ///< CSL Clock Accuracy TLV kLinkMetricsQuery = 87, ///< Link Metrics Query TLV kLinkMetricsManagement = 88, ///< Link Metrics Management TLV kLinkMetricsReport = 89, ///< Link Metrics Report TLV @@ -1332,6 +1333,63 @@ private: #endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || (OPENTHREAD_FTD && OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE) +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE +/** + * This class implements CSL Clock Accuracy TLV generation and parsing. + * + */ +OT_TOOL_PACKED_BEGIN +class CslClockAccuracyTlv : public Tlv, public TlvInfo +{ +public: + /** + * This method initializes the TLV. + * + */ + void Init(void) + { + SetType(kCslClockAccuracy); + SetLength(sizeof(*this) - sizeof(Tlv)); + } + + /** + * This method returns the CSL Clock Accuracy value. + * + * @returns The CSL Clock Accuracy value. + * + */ + uint8_t GetCslClockAccuracy(void) { return mCslClockAccuracy; } + + /** + * This method sets the CSL Clock Accuracy value. + * + * @param[in] aCslClockAccuracy The CSL Clock Accuracy value. + * + */ + void SetCslClockAccuracy(uint8_t aCslClockAccuracy) { mCslClockAccuracy = aCslClockAccuracy; } + + /** + * This method returns the Clock Accuracy value. + * + * @returns The Clock Accuracy value. + * + */ + uint8_t GetCslUncertainty(void) { return mCslUncertainty; } + + /** + * This method sets the CSL Uncertainty value. + * + * @param[in] aCslUncertainty The CSL Uncertainty value. + * + */ + void SetCslUncertainty(uint8_t aCslUncertainty) { mCslUncertainty = aCslUncertainty; } + +private: + uint8_t mCslClockAccuracy; + uint8_t mCslUncertainty; +} OT_TOOL_PACKED_END; + +#endif // OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE || OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE /** * @} * diff --git a/src/core/thread/topology.hpp b/src/core/thread/topology.hpp index bd0ffa29e..3d5ae0184 100644 --- a/src/core/thread/topology.hpp +++ b/src/core/thread/topology.hpp @@ -47,6 +47,7 @@ #include "common/timer.hpp" #include "mac/mac_types.hpp" #include "net/ip6.hpp" +#include "radio/radio.hpp" #include "radio/trel_link.hpp" #include "thread/csl_tx_scheduler.hpp" #include "thread/indirect_sender.hpp" @@ -1341,7 +1342,14 @@ public: * @param[in] aInstance A reference to OpenThread instance. * */ - void Init(Instance &aInstance) { Neighbor::Init(aInstance); } + void Init(Instance &aInstance) + { + Neighbor::Init(aInstance); +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + SetCslClockAccuracy(kCslWorstCrystalPpm); + SetCslClockUncertianity(kCslWorstUncertainty); +#endif + } /** * This method clears the router entry. @@ -1397,6 +1405,40 @@ public: */ void SetCost(uint8_t aCost) { mCost = aCost; } +#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE + /** + * This method get the CSL clock accuracy of this router. + * + * @returns The CSL clock accuracy of this router. + * + */ + uint8_t GetCslClockAccuracy(void) const { return mCslClockAccuracy; } + + /** + * This method sets the CSL clock accuracy of this router. + * + * @param[in] aCost The CSL clock accuracy of this router. + * + */ + void SetCslClockAccuracy(uint8_t aCslClockAccuracy) { mCslClockAccuracy = aCslClockAccuracy; } + + /** + * This method get the CSL clock uncertianity of this router. + * + * @returns The CSL clock uncertianity of this router. + * + */ + uint8_t GetCslClockUncertianity(void) const { return mCslClockUncertianity; } + + /** + * This method sets the CSL clock uncertianity of this router. + * + * @param[in] aCost The CSL clock uncertianity of this router. + * + */ + void SetCslClockUncertianity(uint8_t aCslClockUncertianity) { mCslClockUncertianity = aCslClockUncertianity; } +#endif + private: uint8_t mNextHop; ///< The next hop towards this router uint8_t mLinkQualityOut : 2; ///< The link quality out for this router @@ -1406,6 +1448,10 @@ private: #else 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 mCslClockUncertianity; ///< Scheduling uncertainty, in units of 10 us. +#endif }; } // namespace ot diff --git a/tests/scripts/thread-cert/config.py b/tests/scripts/thread-cert/config.py index ed07b24ff..ed2dd8882 100755 --- a/tests/scripts/thread-cert/config.py +++ b/tests/scripts/thread-cert/config.py @@ -265,6 +265,7 @@ def create_default_mle_tlvs_factories(): mle.TlvType.PENDING_TIMESTAMP: mle.PendingTimestampFactory(), mle.TlvType.CSL_CHANNEL: mle.CslChannelFactory(), mle.TlvType.CSL_SYNCHRONIZED_TIMEOUT: mle.CslSynchronizedTimeoutFactory(), + mle.TlvType.CSL_CLOCK_ACCURACY: mle.CslClockAccuracyFactory(), mle.TlvType.ACTIVE_OPERATIONAL_DATASET: mle.ActiveOperationalDatasetFactory(), mle.TlvType.PENDING_OPERATIONAL_DATASET: mle.PendingOperationalDatasetFactory(), mle.TlvType.TIME_REQUEST: mle.TimeRequestFactory(), diff --git a/tests/scripts/thread-cert/mesh_cop.py b/tests/scripts/thread-cert/mesh_cop.py index c64135318..d55c9b24f 100755 --- a/tests/scripts/thread-cert/mesh_cop.py +++ b/tests/scripts/thread-cert/mesh_cop.py @@ -77,6 +77,7 @@ class TlvType(IntEnum): SCAN_DURATION = 56 ENERGY_LIST = 57 CSL_SYNCHRONIZED_TIMEOUT = 85 + CSL_CLOCK_ACCURACY = 86 DISCOVERY_REQUEST = 128 DISCOVERY_RESPONSE = 129 diff --git a/tests/scripts/thread-cert/mle.py b/tests/scripts/thread-cert/mle.py index 7ced8a078..3c70b7f4d 100755 --- a/tests/scripts/thread-cert/mle.py +++ b/tests/scripts/thread-cert/mle.py @@ -92,6 +92,7 @@ class TlvType(IntEnum): THREAD_DISCOVERY = 26 CSL_CHANNEL = 80 CSL_SYNCHRONIZED_TIMEOUT = 85 + CSL_CLOCK_ACCURACY = 86 LINK_METRICS_QUERY = 87 LINK_METRICS_MANAGEMENT = 88 LINK_METRICS_REPORT = 89 @@ -1092,6 +1093,19 @@ class CslSynchronizedTimeoutFactory: return CslSynchronizedTimeout() +class CslClockAccuracy: + # TODO: Not implemented yet + + def __init__(self): + print("CslClockAccuracy is not implemented yet.") + + +class CslClockAccuracyFactory: + + def parse(self, data, message_info): + return CslClockAccuracy() + + class TimeRequest: # TODO: Not implemented yet diff --git a/tests/scripts/thread-cert/pktverify/consts.py b/tests/scripts/thread-cert/pktverify/consts.py index 1fe11dee9..4266ad9e9 100644 --- a/tests/scripts/thread-cert/pktverify/consts.py +++ b/tests/scripts/thread-cert/pktverify/consts.py @@ -161,6 +161,7 @@ ACTIVE_OPERATION_DATASET_TLV = 24 PENDING_OPERATION_DATASET_TLV = 25 THREAD_DISCOVERY_TLV = 26 CSL_SYNCHRONIZED_TIMEOUT = 85 +CSL_CLOCK_ACCURACY = 86 # Network Layer TLVs NL_TARGET_EID_TLV = 0