[mle] use ChildUpdateResponseInfo to pass parameters (#12073)

This commit introduces the `ChildUpdateResponseInfo` struct to
encapsulate parameters for sending "Child Update Response" messages.

The new struct holds the list of TLVs to include, the received
challenge, and the destination address.

Related methods such as `SendChildUpdateResponse()` are updated to use
the new struct. This simplifies the method signatures by reducing the
number of arguments and improves code clarity by grouping related
data.
This commit is contained in:
Abtin Keshavarzian
2025-10-28 14:17:01 -07:00
committed by GitHub
parent ca3e4d50fc
commit eede70c0ef
3 changed files with 79 additions and 80 deletions
+32 -33
View File
@@ -1264,28 +1264,26 @@ exit:
return error;
}
Error Mle::SendChildUpdateRejectResponse(const RxChallenge &aChallenge, const Ip6::Address &aDestination)
Error Mle::SendChildUpdateRejectResponse(ChildUpdateResponseInfo &aInfo)
{
// Send a reject response which only includes a Source Address TLV,
// a Status TLV, and a Response TLV when request contained a
// Challenge TLV.
TlvList tlvList;
aInfo.mTlvList.Clear();
tlvList.Add(Tlv::kSourceAddress);
tlvList.Add(Tlv::kStatus);
aInfo.mTlvList.Add(Tlv::kSourceAddress);
aInfo.mTlvList.Add(Tlv::kStatus);
if (!aChallenge.IsEmpty())
if (!aInfo.mChallenge.IsEmpty())
{
tlvList.Add(Tlv::kResponse);
aInfo.mTlvList.Add(Tlv::kResponse);
}
return SendChildUpdateResponse(tlvList, aChallenge, aDestination);
return SendChildUpdateResponse(aInfo);
}
Error Mle::SendChildUpdateResponse(const TlvList &aTlvList,
const RxChallenge &aChallenge,
const Ip6::Address &aDestination)
Error Mle::SendChildUpdateResponse(const ChildUpdateResponseInfo &aInfo)
{
Error error = kErrorNone;
TxMessage *message;
@@ -1293,7 +1291,7 @@ Error Mle::SendChildUpdateResponse(const TlvList &aTlvList,
VerifyOrExit((message = NewMleMessage(kCommandChildUpdateResponse)) != nullptr, error = kErrorNoBufs);
for (uint8_t tlvType : aTlvList)
for (uint8_t tlvType : aInfo.mTlvList)
{
switch (tlvType)
{
@@ -1328,7 +1326,7 @@ Error Mle::SendChildUpdateResponse(const TlvList &aTlvList,
break;
case Tlv::kResponse:
SuccessOrExit(error = message->AppendResponseTlv(aChallenge));
SuccessOrExit(error = message->AppendResponseTlv(aInfo.mChallenge));
break;
case Tlv::kLinkFrameCounter:
@@ -1354,9 +1352,9 @@ Error Mle::SendChildUpdateResponse(const TlvList &aTlvList,
}
}
SuccessOrExit(error = message->SendTo(aDestination));
SuccessOrExit(error = message->SendTo(aInfo.mDestination));
Log(kMessageSend, kTypeChildUpdateResponseAsChild, aDestination);
Log(kMessageSend, kTypeChildUpdateResponseAsChild, aInfo.mDestination);
if (checkAddress && HasUnregisteredAddress())
{
@@ -2232,13 +2230,12 @@ void Mle::HandleChildUpdateRequest(RxInfo &aRxInfo)
void Mle::HandleChildUpdateRequestOnChild(RxInfo &aRxInfo)
{
Error error = kErrorNone;
bool canTrustMessage = aRxInfo.IsNeighborStateValid();
uint16_t sourceAddress;
RxChallenge challenge;
TlvList requestedTlvList;
TlvList tlvList;
uint8_t linkMarginOut;
Error error = kErrorNone;
bool canTrustMessage = aRxInfo.IsNeighborStateValid();
uint8_t linkMarginOut;
uint16_t sourceAddress;
ChildUpdateResponseInfo info;
TlvList requestedTlvList;
if (!IsAttached())
{
@@ -2256,18 +2253,20 @@ void Mle::HandleChildUpdateRequestOnChild(RxInfo &aRxInfo)
Log(kMessageReceive, kTypeChildUpdateRequestAsChild, aRxInfo.mMessageInfo.GetPeerAddr(), sourceAddress);
tlvList.Add(Tlv::kSourceAddress);
tlvList.Add(Tlv::kLeaderData);
info.mDestination = aRxInfo.mMessageInfo.GetPeerAddr();
switch (aRxInfo.mMessage.ReadChallengeTlv(challenge))
info.mTlvList.Add(Tlv::kSourceAddress);
info.mTlvList.Add(Tlv::kLeaderData);
switch (aRxInfo.mMessage.ReadChallengeTlv(info.mChallenge))
{
case kErrorNone:
tlvList.Add(Tlv::kResponse);
tlvList.Add(Tlv::kMleFrameCounter);
tlvList.Add(Tlv::kLinkFrameCounter);
info.mTlvList.Add(Tlv::kResponse);
info.mTlvList.Add(Tlv::kMleFrameCounter);
info.mTlvList.Add(Tlv::kLinkFrameCounter);
break;
case kErrorNotFound:
challenge.Clear();
info.mChallenge.Clear();
break;
default:
ExitNow(error = kErrorParse);
@@ -2318,7 +2317,7 @@ void Mle::HandleChildUpdateRequestOnChild(RxInfo &aRxInfo)
{
// MUST include CSL timeout TLV when request includes
// CSL accuracy
tlvList.Add(Tlv::kCslTimeout);
info.mTlvList.Add(Tlv::kCslTimeout);
}
}
#endif
@@ -2326,7 +2325,7 @@ void Mle::HandleChildUpdateRequestOnChild(RxInfo &aRxInfo)
switch (aRxInfo.mMessage.ReadTlvRequestTlv(requestedTlvList))
{
case kErrorNone:
tlvList.AddElementsFrom(requestedTlvList);
info.mTlvList.AddElementsFrom(requestedTlvList);
break;
case kErrorNotFound:
break;
@@ -2337,7 +2336,7 @@ void Mle::HandleChildUpdateRequestOnChild(RxInfo &aRxInfo)
else
{
// This device is not a child of the Child Update Request source.
error = SendChildUpdateRejectResponse(challenge, aRxInfo.mMessageInfo.GetPeerAddr());
error = SendChildUpdateRejectResponse(info);
ExitNow();
}
@@ -2345,13 +2344,13 @@ void Mle::HandleChildUpdateRequestOnChild(RxInfo &aRxInfo)
ProcessKeySequence(aRxInfo);
#if OPENTHREAD_CONFIG_MULTI_RADIO
if ((aRxInfo.mNeighbor != nullptr) && !challenge.IsEmpty())
if ((aRxInfo.mNeighbor != nullptr) && !info.mChallenge.IsEmpty())
{
aRxInfo.mNeighbor->ClearLastRxFragmentTag();
}
#endif
error = SendChildUpdateResponse(tlvList, challenge, aRxInfo.mMessageInfo.GetPeerAddr());
error = SendChildUpdateResponse(info);
exit:
LogProcessError(kTypeChildUpdateRequestAsChild, error);
+10 -8
View File
@@ -1645,6 +1645,13 @@ private:
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
struct ChildUpdateResponseInfo
{
TlvList mTlvList; // The TLVs to include in the Child Update Response.
RxChallenge mChallenge; // The received challenge from the Child Update Request (can be empty if none).
Ip6::Address mDestination; // The destination address.
};
#if OPENTHREAD_FTD
struct ParentResponseInfo
{
@@ -2262,10 +2269,8 @@ private:
void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo);
void ReestablishLinkWithNeighbor(Neighbor &aNeighbor);
Error SendChildUpdateRequestToParent(ChildUpdateRequestMode aMode);
Error SendChildUpdateRejectResponse(const RxChallenge &aChallenge, const Ip6::Address &aDestination);
Error SendChildUpdateResponse(const TlvList &aTlvList,
const RxChallenge &aChallenge,
const Ip6::Address &aDestination);
Error SendChildUpdateRejectResponse(ChildUpdateResponseInfo &aInfo);
Error SendChildUpdateResponse(const ChildUpdateResponseInfo &aInfo);
void SetRloc16(uint16_t aRloc16);
void SetStateDetached(void);
void SetStateChild(uint16_t aRloc16);
@@ -2388,10 +2393,7 @@ private:
void SendParentResponse(const ParentResponseInfo &aInfo);
Error SendChildIdResponse(Child &aChild);
Error SendChildUpdateRequestToChild(Child &aChild);
void SendChildUpdateResponseToChild(Child *aChild,
const Ip6::MessageInfo &aMessageInfo,
const TlvList &aTlvList,
const RxChallenge &aChallenge);
void SendChildUpdateResponseToChild(Child *aChild, const ChildUpdateResponseInfo &aInfo);
void SendMulticastDataResponse(void);
void SendDataResponse(const Ip6::Address &aDestination,
const TlvList &aTlvList,
+37 -39
View File
@@ -2213,38 +2213,39 @@ exit:
void Mle::HandleChildUpdateRequestOnParent(RxInfo &aRxInfo)
{
Error error = kErrorNone;
Mac::ExtAddress extAddr;
DeviceMode mode;
RxChallenge challenge;
LeaderData leaderData;
uint32_t timeout;
uint16_t supervisionInterval;
Child *child;
DeviceMode oldMode;
TlvList requestedTlvList;
TlvList tlvList;
bool childDidChange = false;
Error error = kErrorNone;
Mac::ExtAddress extAddr;
DeviceMode mode;
LeaderData leaderData;
uint32_t timeout;
uint16_t supervisionInterval;
Child *child;
DeviceMode oldMode;
TlvList requestedTlvList;
ChildUpdateResponseInfo info;
bool childDidChange = false;
Log(kMessageReceive, kTypeChildUpdateRequestOfChild, aRxInfo.mMessageInfo.GetPeerAddr());
VerifyOrExit(!mDetacher.IsDetaching());
info.mDestination = aRxInfo.mMessageInfo.GetPeerAddr();
SuccessOrExit(error = aRxInfo.mMessage.ReadModeTlv(mode));
switch (aRxInfo.mMessage.ReadChallengeTlv(challenge))
switch (aRxInfo.mMessage.ReadChallengeTlv(info.mChallenge))
{
case kErrorNone:
tlvList.Add(Tlv::kResponse);
info.mTlvList.Add(Tlv::kResponse);
break;
case kErrorNotFound:
challenge.Clear();
info.mChallenge.Clear();
break;
default:
ExitNow(error = kErrorParse);
}
tlvList.Add(Tlv::kSourceAddress);
info.mTlvList.Add(Tlv::kSourceAddress);
extAddr.SetFromIid(aRxInfo.mMessageInfo.GetPeerAddr().GetIid());
child = mChildTable.FindChild(extAddr, Child::kInStateAnyExceptInvalid);
@@ -2255,7 +2256,7 @@ void Mle::HandleChildUpdateRequestOnParent(RxInfo &aRxInfo)
// Status TLV (error).
if (mode.IsRxOnWhenIdle())
{
IgnoreError(SendChildUpdateRejectResponse(challenge, aRxInfo.mMessageInfo.GetPeerAddr()));
IgnoreError(SendChildUpdateRejectResponse(info));
}
ExitNow();
@@ -2272,22 +2273,22 @@ void Mle::HandleChildUpdateRequestOnParent(RxInfo &aRxInfo)
oldMode = child->GetDeviceMode();
child->SetDeviceMode(mode);
tlvList.Add(Tlv::kMode);
tlvList.Add(Tlv::kLinkMargin);
info.mTlvList.Add(Tlv::kMode);
info.mTlvList.Add(Tlv::kLinkMargin);
// Parent MUST include Leader Data TLV in Child Update Response
tlvList.Add(Tlv::kLeaderData);
info.mTlvList.Add(Tlv::kLeaderData);
if (!challenge.IsEmpty())
if (!info.mChallenge.IsEmpty())
{
tlvList.Add(Tlv::kMleFrameCounter);
tlvList.Add(Tlv::kLinkFrameCounter);
info.mTlvList.Add(Tlv::kMleFrameCounter);
info.mTlvList.Add(Tlv::kLinkFrameCounter);
}
switch (ProcessAddressRegistrationTlv(aRxInfo, *child))
{
case kErrorNone:
tlvList.Add(Tlv::kAddressRegistration);
info.mTlvList.Add(Tlv::kAddressRegistration);
break;
case kErrorNotFound:
break;
@@ -2315,7 +2316,7 @@ void Mle::HandleChildUpdateRequestOnParent(RxInfo &aRxInfo)
childDidChange = true;
}
tlvList.Add(Tlv::kTimeout);
info.mTlvList.Add(Tlv::kTimeout);
break;
case kErrorNotFound:
@@ -2328,7 +2329,7 @@ void Mle::HandleChildUpdateRequestOnParent(RxInfo &aRxInfo)
switch (Tlv::Find<SupervisionIntervalTlv>(aRxInfo.mMessage, supervisionInterval))
{
case kErrorNone:
tlvList.Add(Tlv::kSupervisionInterval);
info.mTlvList.Add(Tlv::kSupervisionInterval);
break;
case kErrorNotFound:
@@ -2345,7 +2346,7 @@ void Mle::HandleChildUpdateRequestOnParent(RxInfo &aRxInfo)
switch (aRxInfo.mMessage.ReadTlvRequestTlv(requestedTlvList))
{
case kErrorNone:
tlvList.AddElementsFrom(requestedTlvList);
info.mTlvList.AddElementsFrom(requestedTlvList);
break;
case kErrorNotFound:
break;
@@ -2364,7 +2365,7 @@ void Mle::HandleChildUpdateRequestOnParent(RxInfo &aRxInfo)
case kErrorNone:
child->SetCslTimeout(cslTimeout);
// MUST include CSL accuracy TLV when request includes CSL timeout
tlvList.Add(Tlv::kCslClockAccuracy);
info.mTlvList.Add(Tlv::kCslClockAccuracy);
break;
case kErrorNotFound:
break;
@@ -2416,13 +2417,13 @@ void Mle::HandleChildUpdateRequestOnParent(RxInfo &aRxInfo)
// from a detached child trying to restore its link with its
// parent which is indicated by the presence of Challenge TLV in
// the message.
if (!challenge.IsEmpty())
if (!info.mChallenge.IsEmpty())
{
child->ClearLastRxFragmentTag();
}
#endif
SendChildUpdateResponseToChild(child, aRxInfo.mMessageInfo, tlvList, challenge);
SendChildUpdateResponseToChild(child, info);
aRxInfo.mClass = RxInfo::kPeerMessage;
@@ -3011,17 +3012,14 @@ exit:
return error;
}
void Mle::SendChildUpdateResponseToChild(Child *aChild,
const Ip6::MessageInfo &aMessageInfo,
const TlvList &aTlvList,
const RxChallenge &aChallenge)
void Mle::SendChildUpdateResponseToChild(Child *aChild, const ChildUpdateResponseInfo &aInfo)
{
Error error = kErrorNone;
TxMessage *message;
VerifyOrExit((message = NewMleMessage(kCommandChildUpdateResponse)) != nullptr, error = kErrorNoBufs);
for (uint8_t tlvType : aTlvList)
for (uint8_t tlvType : aInfo.mTlvList)
{
// Add all TLV types that do not depend on `child`
@@ -3036,7 +3034,7 @@ void Mle::SendChildUpdateResponseToChild(Child *aChild,
break;
case Tlv::kResponse:
SuccessOrExit(error = message->AppendResponseTlv(aChallenge));
SuccessOrExit(error = message->AppendResponseTlv(aInfo.mChallenge));
break;
case Tlv::kSourceAddress:
@@ -3098,15 +3096,15 @@ void Mle::SendChildUpdateResponseToChild(Child *aChild,
}
}
SuccessOrExit(error = message->SendTo(aMessageInfo.GetPeerAddr()));
SuccessOrExit(error = message->SendTo(aInfo.mDestination));
if (aChild == nullptr)
{
Log(kMessageSend, kTypeChildUpdateResponseOfChild, aMessageInfo.GetPeerAddr());
Log(kMessageSend, kTypeChildUpdateResponseOfChild, aInfo.mDestination);
}
else
{
Log(kMessageSend, kTypeChildUpdateResponseOfChild, aMessageInfo.GetPeerAddr(), aChild->GetRloc16());
Log(kMessageSend, kTypeChildUpdateResponseOfChild, aInfo.mDestination, aChild->GetRloc16());
}
exit: