[mle] implement CSL accuracy rules from latest Thread spec (#7119)

Apply all CSL accuracy rules from latest spec draft:

- If the Mode TLV in the Parent Request had the 'R' flag set to zero
  AND the Version TLV indicates that the version of the attaching
  device is Thread 1.2 or greater, the Parent SHOULD include the CSL
  Accuracy TLV in the Parent Response.

- A Parent that receives a Child Update Request which includes the CSL
  Synchronized Timeout TLV MUST include the CSL Accuracy TLV in the
  response.

- A Child that receives a Child Update Request which includes the CSL
  Accuracy TLV MUST include the CSL Synchronized Timeout TLV in the
  response if the Child is currently acting as a CSL receiver.
This commit is contained in:
Suvesh Pratapa
2021-11-01 11:26:08 -07:00
committed by GitHub
parent 5e8265f455
commit 3dcf0ba544
3 changed files with 58 additions and 1 deletions
+30
View File
@@ -2466,6 +2466,15 @@ Error Mle::SendChildUpdateResponse(const uint8_t *aTlvs, uint8_t aNumTlvs, const
case Tlv::kMleFrameCounter:
SuccessOrExit(error = AppendMleFrameCounter(*message));
break;
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
case Tlv::kCslTimeout:
if (Get<Mac::Mac>().IsCslEnabled())
{
SuccessOrExit(error = AppendCslTimeout(*message));
}
break;
#endif
}
}
@@ -3777,6 +3786,15 @@ void Mle::HandleChildUpdateRequest(const Message &aMessage, const Ip6::MessageIn
// Leader Data, Network Data, Active Timestamp, Pending Timestamp
SuccessOrExit(error = HandleLeaderData(aMessage, aMessageInfo));
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
CslClockAccuracyTlv cslClockAccuracyTlv;
if (Tlv::FindTlv(aMessage, cslClockAccuracyTlv) == kErrorNone)
{
// MUST include CSL timeout TLV when request includes CSL accuracy
tlvs[numTlvs++] = Tlv::kCslTimeout;
}
#endif
}
else
{
@@ -3830,6 +3848,9 @@ void Mle::HandleChildUpdateResponse(const Message & aMessage,
uint32_t mleFrameCounter;
uint16_t sourceAddress;
uint32_t timeout;
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
CslClockAccuracyTlv clockAccuracy;
#endif
Log(kMessageReceive, kTypeChildUpdateResponseOfParent, aMessageInfo.GetPeerAddr());
@@ -3901,6 +3922,15 @@ void Mle::HandleChildUpdateResponse(const Message & aMessage,
ExitNow(error = kErrorParse);
}
#if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE
// CSL Accuracy
if (Tlv::FindTlv(aMessage, clockAccuracy) != kErrorNone)
{
Get<Mac::Mac>().SetCslParentClockAccuracy(clockAccuracy.GetCslClockAccuracy());
Get<Mac::Mac>().SetCslParentUncertainty(clockAccuracy.GetCslUncertainty());
}
#endif
if (!IsRxOnWhenIdle())
{
Get<DataPollSender>().SetAttachMode(false);
+20 -1
View File
@@ -1593,6 +1593,8 @@ void MleRouter::HandleParentRequest(const Message &aMessage, const Ip6::MessageI
Challenge challenge;
Router * leader;
Child * child;
uint8_t modeBitmask;
DeviceMode mode;
Log(kMessageReceive, kTypeParentRequest, aMessageInfo.GetPeerAddr());
@@ -1669,6 +1671,12 @@ void MleRouter::HandleParentRequest(const Message &aMessage, const Ip6::MessageI
#if OPENTHREAD_CONFIG_TIME_SYNC_ENABLE
child->SetTimeSyncEnabled(Tlv::Find<TimeRequestTlv>(aMessage, nullptr, 0) == kErrorNone);
#endif
if (Tlv::Find<ModeTlv>(aMessage, modeBitmask) == kErrorNone)
{
mode.Set(modeBitmask);
child->SetDeviceMode(mode);
child->SetVersion(static_cast<uint8_t>(version));
}
}
else if (TimerMilli::GetNow() - child->GetLastHeard() < kParentRequestRouterTimeout - kParentRequestDuplicateMargin)
{
@@ -1944,7 +1952,7 @@ void MleRouter::SendParentResponse(Child *aChild, const Challenge &aChallenge, b
}
#endif
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
if (!aChild->IsRxOnWhenIdle())
if (aChild->IsThreadVersionCslCapable())
{
SuccessOrExit(error = AppendCslClockAccuracy(*message));
}
@@ -2512,6 +2520,8 @@ void MleRouter::HandleChildUpdateRequest(const Message &aMessage, const Ip6::Mes
if (Tlv::Find<CslTimeoutTlv>(aMessage, cslTimeout) == kErrorNone)
{
child->SetCslTimeout(cslTimeout);
// MUST include CSL accuracy TLV when request includes CSL timeout
tlvs[tlvslength++] = Tlv::kCslClockAccuracy;
}
if (Tlv::FindTlv(aMessage, cslChannel) == kErrorNone)
@@ -3252,6 +3262,15 @@ void MleRouter::SendChildUpdateResponse(Child * aChild,
case Tlv::kLinkFrameCounter:
SuccessOrExit(error = AppendLinkFrameCounter(*message));
break;
#if OPENTHREAD_CONFIG_MAC_CSL_TRANSMITTER_ENABLE
case Tlv::kCslClockAccuracy:
if (!aChild->IsRxOnWhenIdle())
{
SuccessOrExit(error = AppendCslClockAccuracy(*message));
}
break;
#endif
}
}
+8
View File
@@ -564,6 +564,14 @@ public:
*/
bool IsThreadVersion1p2(void) const { return mState != kStateInvalid && mVersion == OT_THREAD_VERSION_1_2; }
/**
* This method indicates whether Thread version supports CSL.
*
* @returns TRUE if CSL is supported, FALSE otherwise.
*
*/
bool IsThreadVersionCslCapable(void) const { return IsThreadVersion1p2() && !IsRxOnWhenIdle(); }
/**
* This method indicates whether Enhanced Keep-Alive is supported or not.
*