diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index efe9e593b2c..6b64959f173 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -3394,6 +3394,7 @@ void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo) RxChallenge challenge; TlvList requestedTlvList; TlvList tlvList; + uint8_t linkMarginOut; SuccessOrExit(error = Tlv::Find(aRxInfo.mMessage, sourceAddress)); @@ -3436,6 +3437,17 @@ void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo) SuccessOrExit(error = HandleLeaderData(aRxInfo)); + switch (Tlv::Find(aRxInfo.mMessage, linkMarginOut)) + { + case kErrorNone: + mParent.SetLinkQualityOut(LinkQualityForLinkMargin(linkMarginOut)); + break; + case kErrorNotFound: + break; + default: + ExitNow(error = kErrorParse); + } + #if OPENTHREAD_CONFIG_MAC_CSL_RECEIVER_ENABLE { Mac::CslAccuracy cslAccuracy; @@ -3494,6 +3506,7 @@ void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo) uint32_t mleFrameCounter; uint16_t sourceAddress; uint32_t timeout; + uint8_t linkMarginOut; Log(kMessageReceive, kTypeChildUpdateResponseAsChild, aRxInfo.mMessageInfo.GetPeerAddr()); @@ -3616,6 +3629,17 @@ void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo) OT_ASSERT(false); } + switch (Tlv::Find(aRxInfo.mMessage, linkMarginOut)) + { + case kErrorNone: + mParent.SetLinkQualityOut(LinkQualityForLinkMargin(linkMarginOut)); + break; + case kErrorNotFound: + break; + default: + ExitNow(error = kErrorParse); + } + aRxInfo.mClass = response.IsEmpty() ? RxInfo::kPeerMessage : RxInfo::kAuthoritativeMessage; exit: diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index fcb4595de75..087be21bc80 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -2211,6 +2211,7 @@ void MleRouter::HandleChildUpdateRequest(RxInfo &aRxInfo) child->SetDeviceMode(mode); tlvList.Add(Tlv::kMode); + tlvList.Add(Tlv::kLinkMargin); // Parent MUST include Leader Data TLV in Child Update Response tlvList.Add(Tlv::kLeaderData); @@ -2921,7 +2922,11 @@ Error MleRouter::SendChildUpdateRequest(Child &aChild) SuccessOrExit(error = message->AppendNetworkDataTlv(aChild.GetNetworkDataType())); SuccessOrExit(error = message->AppendActiveAndPendingTimestampTlvs()); - if (!aChild.IsStateValid()) + if (aChild.IsStateValid()) + { + SuccessOrExit(error = message->AppendLinkMarginTlv(aChild.GetLinkInfo().GetLinkMargin())); + } + else { SuccessOrExit(error = message->AppendTlvRequestTlv(kTlvs)); @@ -3029,6 +3034,10 @@ void MleRouter::SendChildUpdateResponse(Child *aChild, SuccessOrExit(error = message->AppendTimeoutTlv(aChild->GetTimeout())); break; + case Tlv::kLinkMargin: + SuccessOrExit(error = message->AppendLinkMarginTlv(aChild->GetLinkInfo().GetLinkMargin())); + break; + case Tlv::kSupervisionInterval: SuccessOrExit(error = message->AppendSupervisionIntervalTlv(aChild->GetSupervisionInterval())); break;