Skip to content

Commit

Permalink
[mle] include Link Margin TLV in Child Update messages (openthread#10626
Browse files Browse the repository at this point in the history
)

This commit adds code to include the Link Margin TLV in MLE Child
Update Request or Response messages sent by a parent to a child. This
allows the child to learn and update its "link quality out" to its
parent.

The change is designed to be backward compatible. Child devices
running older firmware will simply disregard this additional TLV.
When processing the message, the presence of the Link Margin TLV is
checked (it is optional).
  • Loading branch information
abtink authored Aug 27, 2024
1 parent e3f0a7c commit a30cbda
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 1 deletion.
24 changes: 24 additions & 0 deletions src/core/thread/mle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3394,6 +3394,7 @@ void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo)
RxChallenge challenge;
TlvList requestedTlvList;
TlvList tlvList;
uint8_t linkMarginOut;

SuccessOrExit(error = Tlv::Find<SourceAddressTlv>(aRxInfo.mMessage, sourceAddress));

Expand Down Expand Up @@ -3436,6 +3437,17 @@ void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo)

SuccessOrExit(error = HandleLeaderData(aRxInfo));

switch (Tlv::Find<LinkMarginTlv>(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;
Expand Down Expand Up @@ -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());

Expand Down Expand Up @@ -3616,6 +3629,17 @@ void Mle::HandleChildUpdateResponse(RxInfo &aRxInfo)
OT_ASSERT(false);
}

switch (Tlv::Find<LinkMarginTlv>(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:
Expand Down
11 changes: 10 additions & 1 deletion src/core/thread/mle_router.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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));

Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit a30cbda

Please sign in to comment.