From f29de5907721657824d7b6e54efdc9d69a785b3c Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Thu, 24 Aug 2017 14:03:26 -0700 Subject: [PATCH] [mle] process Active and Pending Timestamps in MLE Child Update Request (#2131) This commit adds proper handling of Active and Pending Timestamp TLVs that are included in parent-initiated MLE Child Update Requests. --- src/core/thread/mle.cpp | 50 ++++++++++++----------------------------- 1 file changed, 14 insertions(+), 36 deletions(-) diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 33595f187..fdd1309c3 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -2361,7 +2361,6 @@ otError Mle::HandleLeaderData(const Message &aMessage, const Ip6::MessageInfo &a uint16_t pendingDatasetOffset = 0; bool dataRequest = false; Tlv tlv; - uint16_t delay; // Leader Data SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kLeaderData, sizeof(leaderData), leaderData)); @@ -2479,13 +2478,22 @@ otError Mle::HandleLeaderData(const Message &aMessage, const Ip6::MessageInfo &a exit: - OT_UNUSED_VARIABLE(aMessageInfo); - if (dataRequest) { static const uint8_t tlvs[] = {Tlv::kNetworkData}; + uint16_t delay; - delay = aMessageInfo.GetSockAddr().IsMulticast() ? (otPlatRandomGet() % kMleMaxResponseDelay) : 0; + if (aMessageInfo.GetSockAddr().IsMulticast()) + { + delay = otPlatRandomGet() % kMleMaxResponseDelay; + } + else + { + // This method may have been called from an MLE request + // handler. We add a minimum delay here so that the MLE + // response is enqueued before the MLE Data Request. + delay = 10; + } SendDataRequest(aMessageInfo.GetPeerAddr(), tlvs, sizeof(tlvs), delay); } @@ -2809,14 +2817,12 @@ otError Mle::HandleChildUpdateRequest(const Message &aMessage, const Ip6::Messag { static const uint8_t kMaxResponseTlvs = 5; - ThreadNetif &netif = GetNetif(); otError error = OT_ERROR_NONE; SourceAddressTlv sourceAddress; LeaderDataTlv leaderData; NetworkDataTlv networkData; ChallengeTlv challenge; TlvRequestTlv tlvRequest; - uint8_t dataRequestTlvs[] = {Tlv::kNetworkData}; uint8_t tlvs[kMaxResponseTlvs] = {}; uint8_t numTlvs = 0; @@ -2827,31 +2833,8 @@ otError Mle::HandleChildUpdateRequest(const Message &aMessage, const Ip6::Messag VerifyOrExit(sourceAddress.IsValid(), error = OT_ERROR_PARSE); VerifyOrExit(mParent.GetRloc16() == sourceAddress.GetRloc16(), error = OT_ERROR_DROP); - // Leader Data - if (Tlv::GetTlv(aMessage, Tlv::kLeaderData, sizeof(leaderData), leaderData) == OT_ERROR_NONE) - { - VerifyOrExit(leaderData.IsValid(), error = OT_ERROR_PARSE); - SetLeaderData(leaderData.GetPartitionId(), leaderData.GetWeighting(), leaderData.GetLeaderRouterId()); - - if ((mDeviceMode & ModeTlv::kModeFullNetworkData && - leaderData.GetDataVersion() != netif.GetNetworkDataLeader().GetVersion()) || - ((mDeviceMode & ModeTlv::kModeFullNetworkData) == 0 && - leaderData.GetStableDataVersion() != netif.GetNetworkDataLeader().GetStableVersion())) - { - mRetrieveNewNetworkData = true; - } - - // Network Data - if (Tlv::GetTlv(aMessage, Tlv::kNetworkData, sizeof(networkData), networkData) == OT_ERROR_NONE) - { - VerifyOrExit(networkData.IsValid(), error = OT_ERROR_PARSE); - netif.GetNetworkDataLeader().SetNetworkData(leaderData.GetDataVersion(), - leaderData.GetStableDataVersion(), - (mDeviceMode & ModeTlv::kModeFullNetworkData) == 0, - networkData.GetNetworkData(), - networkData.GetLength()); - } - } + // Leader Data, Network Data, Active Timestamp, Pending Timestamp + SuccessOrExit(error = HandleLeaderData(aMessage, aMessageInfo)); // TLV Request if (Tlv::GetTlv(aMessage, Tlv::kTlvRequest, sizeof(tlvRequest), tlvRequest) == OT_ERROR_NONE) @@ -2873,11 +2856,6 @@ otError Mle::HandleChildUpdateRequest(const Message &aMessage, const Ip6::Messag SuccessOrExit(error = SendChildUpdateResponse(tlvs, numTlvs, challenge)); - if (mRetrieveNewNetworkData) - { - SendDataRequest(aMessageInfo.GetPeerAddr(), dataRequestTlvs, sizeof(dataRequestTlvs), 0); - } - exit: return error; }