From 87be717ad6d1fbac671e0f3348934f1a582ed581 Mon Sep 17 00:00:00 2001 From: Shu Chen Date: Thu, 13 Oct 2016 00:21:28 +0800 Subject: [PATCH] Include timestamp tlv in Child ID Response only when it is necessary (#794) --- src/core/thread/mle.cpp | 35 ++++++++++++++-------------------- src/core/thread/mle_router.cpp | 12 ++++++++++-- src/core/thread/topology.hpp | 2 +- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 38d25f86c..e59f783aa 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -936,12 +936,15 @@ exit: ThreadError Mle::AppendActiveTimestamp(Message &aMessage) { + ThreadError error; ActiveTimestampTlv timestampTlv; const MeshCoP::Timestamp *timestamp(mNetif.GetActiveDataset().GetNetwork().GetTimestamp()); + VerifyOrExit(timestamp || mDeviceState == kDeviceStateLeader, error = kThreadError_None); + timestampTlv.Init(); - // set active timestamp to 0 if there is no valid active operational dataset + // only for Leader: set active timestamp to 0 if it is not initialized if (timestamp == NULL) { timestampTlv.SetSeconds(0); @@ -952,7 +955,10 @@ ThreadError Mle::AppendActiveTimestamp(Message &aMessage) *static_cast(×tampTlv) = *timestamp; } - return aMessage.Append(×tampTlv, sizeof(timestampTlv)); + error = aMessage.Append(×tampTlv, sizeof(timestampTlv)); + +exit: + return error; } ThreadError Mle::AppendPendingTimestamp(Message &aMessage) @@ -1807,13 +1813,11 @@ ThreadError Mle::HandleDataResponse(const Message &aMessage, const Ip6::MessageI VerifyOrExit(networkData.IsValid(), error = kThreadError_Parse); // Active Timestamp - SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kActiveTimestamp, sizeof(activeTimestamp), activeTimestamp)); - VerifyOrExit(activeTimestamp.IsValid(), error = kThreadError_Parse); - - if (activeTimestamp.GetSeconds() != 0) + if (Tlv::GetTlv(aMessage, Tlv::kActiveTimestamp, sizeof(activeTimestamp), activeTimestamp) == kThreadError_None) { const MeshCoP::Timestamp *timestamp; + VerifyOrExit(activeTimestamp.IsValid(), error = kThreadError_Parse); timestamp = mNetif.GetActiveDataset().GetNetwork().GetTimestamp(); // if received timestamp does not match the local value and message does not contain the dataset, @@ -2112,18 +2116,11 @@ ThreadError Mle::HandleChildIdResponse(const Message &aMessage, const Ip6::Messa { VerifyOrExit(activeTimestamp.IsValid(), error = kThreadError_Parse); - if (activeTimestamp.GetSeconds() != 0) + // Active Dataset + if (Tlv::GetOffset(aMessage, Tlv::kActiveDataset, offset) == kThreadError_None) { - // Active Dataset - if (Tlv::GetOffset(aMessage, Tlv::kActiveDataset, offset) == kThreadError_None) - { - aMessage.Read(offset, sizeof(tlv), &tlv); - mNetif.GetActiveDataset().Set(activeTimestamp, aMessage, offset + sizeof(tlv), tlv.GetLength()); - } - } - else - { - mNetif.GetActiveDataset().Clear(); + aMessage.Read(offset, sizeof(tlv), &tlv); + mNetif.GetActiveDataset().Set(activeTimestamp, aMessage, offset + sizeof(tlv), tlv.GetLength()); } } @@ -2139,10 +2136,6 @@ ThreadError Mle::HandleChildIdResponse(const Message &aMessage, const Ip6::Messa mNetif.GetPendingDataset().Set(pendingTimestamp, aMessage, offset + sizeof(tlv), tlv.GetLength()); } } - else - { - mNetif.GetPendingDataset().Clear(); - } // Parent Attach Success mParentRequestTimer.Stop(); diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index 026981647..096a0c1b4 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -2093,6 +2093,7 @@ ThreadError MleRouter::HandleChildIdRequest(const Message &aMessage, const Ip6:: mNetif.GetActiveDataset().GetNetwork().GetTimestamp()->Compare(activeTimestamp) != 0) { child->mRequestTlvs[numTlvs++] = Tlv::kActiveDataset; + child->mRequestTlvs[numTlvs++] = Tlv::kActiveTimestamp; } if (pendingTimestamp.GetLength() == 0 || @@ -2100,6 +2101,7 @@ ThreadError MleRouter::HandleChildIdRequest(const Message &aMessage, const Ip6:: mNetif.GetPendingDataset().GetNetwork().GetTimestamp()->Compare(pendingTimestamp) != 0) { child->mRequestTlvs[numTlvs++] = Tlv::kPendingDataset; + child->mRequestTlvs[numTlvs++] = Tlv::kPendingTimestamp; } switch (GetDeviceState()) @@ -2307,8 +2309,6 @@ ThreadError MleRouter::SendChildIdResponse(Child *aChild) SuccessOrExit(error = AppendHeader(*message, Header::kCommandChildIdResponse)); SuccessOrExit(error = AppendSourceAddress(*message)); SuccessOrExit(error = AppendLeaderData(*message)); - SuccessOrExit(error = AppendActiveTimestamp(*message)); - SuccessOrExit(error = AppendPendingTimestamp(*message)); // pick next Child ID that is not being used do @@ -2346,6 +2346,14 @@ ThreadError MleRouter::SendChildIdResponse(Child *aChild) case Tlv::kPendingDataset: SuccessOrExit(error = AppendPendingDataset(*message)); break; + + case Tlv::kActiveTimestamp: + SuccessOrExit(error = AppendActiveTimestamp(*message)); + break; + + case Tlv::kPendingTimestamp: + SuccessOrExit(error = AppendPendingTimestamp(*message)); + break; } } diff --git a/src/core/thread/topology.hpp b/src/core/thread/topology.hpp index 60f97d4b2..1d9beb9b6 100644 --- a/src/core/thread/topology.hpp +++ b/src/core/thread/topology.hpp @@ -105,7 +105,7 @@ public: Ip6::Address mIp6Address[kMaxIp6AddressPerChild]; ///< Registered IPv6 addresses uint32_t mTimeout; ///< Child timeout uint16_t mFragmentOffset; ///< 6LoWPAN fragment offset - uint8_t mRequestTlvs[5]; ///< Requested MLE TLVs + uint8_t mRequestTlvs[7]; ///< Requested MLE TLVs uint8_t mNetworkDataVersion; ///< Current Network Data version uint16_t mQueuedIndirectMessageCnt; ///< Count of queued messages bool mAddSrcMatchEntryShort; ///< Indicates whether or not to force add short address