diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 5cbf3b89f..aed8e01c8 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -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); diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index cc4656d79..24fbb5b94 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -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, diff --git a/src/core/thread/mle_ftd.cpp b/src/core/thread/mle_ftd.cpp index 07568309d..adce6418c 100644 --- a/src/core/thread/mle_ftd.cpp +++ b/src/core/thread/mle_ftd.cpp @@ -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(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: