From 5c28c02e4093dbeff52a39c8420e06582ba5a72d Mon Sep 17 00:00:00 2001 From: Lu Wang Date: Thu, 15 Sep 2016 12:13:43 +0800 Subject: [PATCH] Include timestamp TLV (#564) * Include timestamp TLV * Keep one copy of timestamp --- src/core/meshcop/joiner_router.cpp | 14 +++- src/core/thread/meshcop_dataset.cpp | 84 ++++++++++++++------- src/core/thread/meshcop_dataset.hpp | 16 ++-- src/core/thread/meshcop_dataset_manager.cpp | 45 +++++------ src/core/thread/meshcop_dataset_manager.hpp | 2 +- src/core/thread/meshcop_tlvs.hpp | 8 ++ src/core/thread/mle.cpp | 12 +-- src/core/thread/mle_router.cpp | 12 ++- 8 files changed, 120 insertions(+), 73 deletions(-) diff --git a/src/core/meshcop/joiner_router.cpp b/src/core/meshcop/joiner_router.cpp index 4c7fdf9f8..255705a4f 100644 --- a/src/core/meshcop/joiner_router.cpp +++ b/src/core/meshcop/joiner_router.cpp @@ -320,7 +320,6 @@ ThreadError JoinerRouter::SendJoinerEntrust(const Ip6::MessageInfo &aMessageInfo MeshLocalPrefixTlv meshLocalPrefix; ExtendedPanIdTlv extendedPanId; NetworkNameTlv networkName; - ActiveTimestampTlv activeTimestamp; Tlv *tlv; VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs); @@ -353,9 +352,16 @@ ThreadError JoinerRouter::SendJoinerEntrust(const Ip6::MessageInfo &aMessageInfo networkName.SetNetworkName(mNetif.GetMac().GetNetworkName()); SuccessOrExit(error = message->Append(&networkName, sizeof(Tlv) + networkName.GetLength())); - activeTimestamp.Init(); - *static_cast(&activeTimestamp) = mNetif.GetActiveDataset().GetNetwork().GetTimestamp(); - SuccessOrExit(error = message->Append(&activeTimestamp, sizeof(activeTimestamp))); + if ((tlv = mNetif.GetActiveDataset().GetNetwork().Get(Tlv::kActiveTimestamp)) != NULL) + { + SuccessOrExit(error = message->Append(tlv, sizeof(Tlv) + tlv->GetLength())); + } + else + { + ActiveTimestampTlv activeTimestamp; + activeTimestamp.Init(); + SuccessOrExit(error = message->Append(&activeTimestamp, sizeof(activeTimestamp))); + } if ((tlv = mNetif.GetActiveDataset().GetNetwork().Get(Tlv::kChannelMask)) != NULL) { diff --git a/src/core/thread/meshcop_dataset.cpp b/src/core/thread/meshcop_dataset.cpp index 1379247a8..523f052d0 100644 --- a/src/core/thread/meshcop_dataset.cpp +++ b/src/core/thread/meshcop_dataset.cpp @@ -41,15 +41,14 @@ namespace Thread { namespace MeshCoP { -Dataset::Dataset(void) : +Dataset::Dataset(const Tlv::Type aType) : + mType(aType), mLength(0) { - mTimestamp.Init(); } void Dataset::Clear(void) { - mTimestamp.Init(); mLength = 0; } @@ -110,6 +109,8 @@ void Dataset::Get(otOperationalDataset &aDataset) const ActiveTimestampTlv *tlv = static_cast(cur); aDataset.mActiveTimestamp = tlv->GetSeconds(); aDataset.mIsActiveTimestampSet = true; + + GetTimestamp(); break; } @@ -228,30 +229,36 @@ void Dataset::Get(otOperationalDataset &aDataset) } } -ThreadError Dataset::Set(const otOperationalDataset &aDataset, bool aActive) +ThreadError Dataset::Set(const otOperationalDataset &aDataset) { ThreadError error = kThreadError_None; + MeshCoP::ActiveTimestampTlv activeTimestampTlv; VerifyOrExit(aDataset.mIsActiveTimestampSet, error = kThreadError_InvalidArgs); - if (aActive) + activeTimestampTlv.Init(); + activeTimestampTlv.SetSeconds(aDataset.mActiveTimestamp); + activeTimestampTlv.SetTicks(0); + Set(activeTimestampTlv); + + if (mType == Tlv::kPendingTimestamp) { - mTimestamp.SetSeconds(aDataset.mActiveTimestamp); - mTimestamp.SetTicks(0); - mTimestamp.SetAuthoritative(false); - } - else - { - MeshCoP::ActiveTimestampTlv tlv; + MeshCoP::PendingTimestampTlv pendingTimestampTlv; VerifyOrExit(aDataset.mIsPendingTimestampSet, error = kThreadError_InvalidArgs); - mTimestamp.SetSeconds(aDataset.mPendingTimestamp); - mTimestamp.SetTicks(0); - mTimestamp.SetAuthoritative(false); - tlv.Init(); - tlv.SetSeconds(aDataset.mActiveTimestamp); - Set(tlv); + pendingTimestampTlv.Init(); + pendingTimestampTlv.SetSeconds(aDataset.mPendingTimestamp); + pendingTimestampTlv.SetTicks(0); + Set(pendingTimestampTlv); + + if (aDataset.mIsDelaySet) + { + MeshCoP::DelayTimerTlv tlv; + tlv.Init(); + tlv.SetDelayTimer(aDataset.mDelay); + Set(tlv); + } } if (aDataset.mIsChannelSet) @@ -287,14 +294,6 @@ ThreadError Dataset::Set(const otOperationalDataset &aDataset, bool aActive) Set(channelMask.tlv); } - if (aDataset.mIsDelaySet) - { - MeshCoP::DelayTimerTlv tlv; - tlv.Init(); - tlv.SetDelayTimer(aDataset.mDelay); - Set(tlv); - } - if (aDataset.mIsExtendedPanIdSet) { MeshCoP::ExtendedPanIdTlv tlv; @@ -356,14 +355,41 @@ exit: return error; } -const Timestamp &Dataset::GetTimestamp(void) const +const Timestamp *Dataset::GetTimestamp(void) const { - return mTimestamp; + const Timestamp *timestamp = NULL; + + if (mType == Tlv::kActiveTimestamp) + { + const ActiveTimestampTlv *tlv = static_cast(Get(mType)); + VerifyOrExit(tlv != NULL, ;); + timestamp = static_cast(tlv); + } + else + { + const PendingTimestampTlv *tlv = static_cast(Get(mType)); + VerifyOrExit(tlv != NULL, ;); + timestamp = static_cast(tlv); + } + +exit: + return timestamp; } void Dataset::SetTimestamp(const Timestamp &aTimestamp) { - mTimestamp = aTimestamp; + OT_TOOL_PACKED_BEGIN + struct + { + Tlv tlv; + Timestamp timestamp; + } OT_TOOL_PACKED_END timestampTlv; + + timestampTlv.tlv.SetType(mType); + timestampTlv.tlv.SetLength(sizeof(Timestamp)); + timestampTlv.timestamp = aTimestamp; + + Set(timestampTlv.tlv); } ThreadError Dataset::Set(const Tlv &aTlv) diff --git a/src/core/thread/meshcop_dataset.hpp b/src/core/thread/meshcop_dataset.hpp index 685ca4d6e..693b9c439 100644 --- a/src/core/thread/meshcop_dataset.hpp +++ b/src/core/thread/meshcop_dataset.hpp @@ -52,8 +52,10 @@ public: /** * This constructor initializes the object. * + * @param[in] aType The type of the dataset, active or pending. + * */ - Dataset(void); + Dataset(const Tlv::Type aType); /** * This method clears the Dataset. @@ -102,10 +104,10 @@ public: /** * This method returns a reference to the Timestamp. * - * @returns A reference to the Timestamp. + * @returns A pointer to the Timestamp. * */ - const Timestamp &GetTimestamp(void) const; + const Timestamp *GetTimestamp(void) const; /** * This method sets the Timestamp value. @@ -126,16 +128,16 @@ public: ThreadError Set(const Message &aMessage, uint16_t aOffset, uint8_t aLength); - ThreadError Set(const otOperationalDataset &aDataset, bool aActive); + ThreadError Set(const otOperationalDataset &aDataset); void Remove(Tlv::Type aType); private: void Remove(uint8_t *aStart, uint8_t aLength); - Timestamp mTimestamp; ///< Active or Pending Timestamp - uint8_t mTlvs[kMaxSize]; ///< The Dataset buffer - uint8_t mLength; ///< The number of valid bytes in @var mTlvs + Tlv::Type mType; ///< Active or Pending + uint8_t mTlvs[kMaxSize]; ///< The Dataset buffer + uint8_t mLength; ///< The number of valid bytes in @var mTlvs }; } // namespace MeshCoP diff --git a/src/core/thread/meshcop_dataset_manager.cpp b/src/core/thread/meshcop_dataset_manager.cpp index 124fa12af..ed55c1ecd 100644 --- a/src/core/thread/meshcop_dataset_manager.cpp +++ b/src/core/thread/meshcop_dataset_manager.cpp @@ -49,7 +49,10 @@ namespace Thread { namespace MeshCoP { -DatasetManager::DatasetManager(ThreadNetif &aThreadNetif, const char *aUriSet, const char *aUriGet): +DatasetManager::DatasetManager(ThreadNetif &aThreadNetif, const Tlv::Type aType, const char *aUriSet, + const char *aUriGet): + mLocal(aType), + mNetwork(aType), mMle(aThreadNetif.GetMle()), mNetif(aThreadNetif), mNetworkDataLeader(aThreadNetif.GetNetworkDataLeader()), @@ -71,7 +74,8 @@ ThreadError DatasetManager::Set(const Dataset &aDataset, uint8_t &aFlags) aFlags = 0; - VerifyOrExit(mNetwork.GetTimestamp().Compare(aDataset.GetTimestamp()) > 0, error = kThreadError_InvalidArgs); + VerifyOrExit((mNetwork.GetTimestamp() == NULL) || (aDataset.GetTimestamp() && + mNetwork.GetTimestamp()->Compare(*aDataset.GetTimestamp()) > 0), error = kThreadError_InvalidArgs); mLocal = aDataset; aFlags |= kFlagLocalUpdated; @@ -102,6 +106,7 @@ ThreadError DatasetManager::Set(const Timestamp &aTimestamp, const Message &aMes uint16_t aOffset, uint8_t aLength, uint8_t &aFlags) { ThreadError error = kThreadError_None; + const Timestamp *timestamp; int compare; aFlags = 0; @@ -110,7 +115,8 @@ ThreadError DatasetManager::Set(const Timestamp &aTimestamp, const Message &aMes mNetwork.SetTimestamp(aTimestamp); aFlags |= kFlagNetworkUpdated; - compare = mLocal.GetTimestamp().Compare(aTimestamp); + timestamp = mLocal.GetTimestamp(); + compare = (timestamp == NULL) ? 1 : timestamp->Compare(aTimestamp); if (compare > 0) { @@ -141,7 +147,8 @@ void DatasetManager::HandleTimer(void *aContext) void DatasetManager::HandleTimer(void) { - VerifyOrExit(mMle.IsAttached() && mNetwork.GetTimestamp().Compare(mLocal.GetTimestamp()) > 0, ;); + VerifyOrExit(mMle.IsAttached() && ((mNetwork.GetTimestamp() == NULL) || + (mLocal.GetTimestamp() && mNetwork.GetTimestamp()->Compare(*mLocal.GetTimestamp()) > 0)), ;); VerifyOrExit(mLocal.Get(Tlv::kDelayTimer) != NULL, ;); Register(); @@ -158,7 +165,6 @@ ThreadError DatasetManager::Register(void) Message *message; Ip6::Address leader; Ip6::MessageInfo messageInfo; - ActiveTimestampTlv timestamp; mSocket.Open(&HandleUdpReceive, this); @@ -179,10 +185,6 @@ ThreadError DatasetManager::Register(void) VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs); SuccessOrExit(error = message->Append(header.GetBytes(), header.GetLength())); - - timestamp.Init(); - *static_cast(×tamp) = mLocal.GetTimestamp(); - SuccessOrExit(error = message->Append(×tamp, sizeof(timestamp))); SuccessOrExit(error = message->Append(mLocal.GetBytes(), mLocal.GetSize())); mMle.GetLeaderAddress(leader); @@ -262,7 +264,8 @@ void DatasetManager::HandleSet(Coap::Header &aHeader, Message &aMessage, const I } // verify the request includes a timestamp that is ahead of the locally stored value - VerifyOrExit(offset < aMessage.GetLength() && mLocal.GetTimestamp().Compare(timestamp) > 0, state = StateTlv::kReject); + VerifyOrExit(offset < aMessage.GetLength() && (mLocal.GetTimestamp() == NULL || + mLocal.GetTimestamp()->Compare(timestamp) > 0), state = StateTlv::kReject); mLocal.Set(aMessage, aMessage.GetOffset(), static_cast(aMessage.GetLength() - aMessage.GetOffset())); mNetwork = mLocal; @@ -568,7 +571,7 @@ exit: } ActiveDataset::ActiveDataset(ThreadNetif &aThreadNetif): - DatasetManager(aThreadNetif, OPENTHREAD_URI_ACTIVE_SET, OPENTHREAD_URI_ACTIVE_GET) + DatasetManager(aThreadNetif, Tlv::kActiveTimestamp, OPENTHREAD_URI_ACTIVE_SET, OPENTHREAD_URI_ACTIVE_GET) { } @@ -576,8 +579,6 @@ void ActiveDataset::Get(otOperationalDataset &aDataset) { memset(&aDataset, 0, sizeof(aDataset)); mLocal.Get(aDataset); - aDataset.mActiveTimestamp = mLocal.GetTimestamp().GetSeconds(); - aDataset.mIsActiveTimestampSet = true; } ThreadError ActiveDataset::Set(const Dataset &aDataset) @@ -595,9 +596,9 @@ exit: ThreadError ActiveDataset::Set(const otOperationalDataset &aDataset) { ThreadError error = kThreadError_None; - Dataset dataset; + Dataset dataset(Tlv::kActiveTimestamp); - SuccessOrExit(error = dataset.Set(aDataset, true)); + SuccessOrExit(error = dataset.Set(aDataset)); SuccessOrExit(error = Set(dataset)); exit: @@ -688,7 +689,7 @@ ThreadError ActiveDataset::ApplyConfiguration(void) } PendingDataset::PendingDataset(ThreadNetif &aThreadNetif): - DatasetManager(aThreadNetif, OPENTHREAD_URI_PENDING_SET, OPENTHREAD_URI_PENDING_GET), + DatasetManager(aThreadNetif, Tlv::kPendingTimestamp, OPENTHREAD_URI_PENDING_SET, OPENTHREAD_URI_PENDING_GET), mTimer(aThreadNetif.GetIp6().mTimerScheduler, HandleTimer, this) { } @@ -697,8 +698,6 @@ void PendingDataset::Get(otOperationalDataset &aDataset) { memset(&aDataset, 0, sizeof(aDataset)); mLocal.Get(aDataset); - aDataset.mPendingTimestamp = mLocal.GetTimestamp().GetSeconds(); - aDataset.mIsPendingTimestampSet = true; } ThreadError PendingDataset::Set(const Dataset &aDataset) @@ -716,9 +715,9 @@ exit: ThreadError PendingDataset::Set(const otOperationalDataset &aDataset) { ThreadError error = kThreadError_None; - Dataset dataset; + Dataset dataset(Tlv::kPendingTimestamp); - SuccessOrExit(error = dataset.Set(aDataset, false)); + SuccessOrExit(error = dataset.Set(aDataset)); SuccessOrExit(error = Set(dataset)); exit: @@ -766,7 +765,8 @@ void PendingDataset::ResetDelayTimer(uint8_t aFlags) mNetworkTime = Timer::GetNow(); // if partition is up to date and delay timer already expired - if ((mNetwork.GetTimestamp().Compare(mLocal.GetTimestamp()) == 0) && + if ((mNetwork.GetTimestamp() && mLocal.GetTimestamp() && + (mNetwork.GetTimestamp()->Compare(*mLocal.GetTimestamp())) == 0) && (delayTimer = static_cast(mLocal.Get(Tlv::kDelayTimer))) != NULL && (delayTimer->GetDelayTimer() == 0)) { @@ -828,7 +828,8 @@ void PendingDataset::HandleTimer(void) // update only if one of the following is true // 1) not attached // 2) partition's pending dataset is up to date - VerifyOrExit(!mMle.IsAttached() || mNetwork.GetTimestamp().Compare(mLocal.GetTimestamp()) == 0, ;); + VerifyOrExit((!mMle.IsAttached() || (mNetwork.GetTimestamp() && + (mNetwork.GetTimestamp()->Compare(*mLocal.GetTimestamp()))) == 0), ;); mLocal.Remove(Tlv::kDelayTimer); diff --git a/src/core/thread/meshcop_dataset_manager.hpp b/src/core/thread/meshcop_dataset_manager.hpp index abb96a9e1..28baa7add 100644 --- a/src/core/thread/meshcop_dataset_manager.hpp +++ b/src/core/thread/meshcop_dataset_manager.hpp @@ -69,7 +69,7 @@ protected: kFlagNetworkUpdated = 1 << 1, }; - DatasetManager(ThreadNetif &aThreadNetif, const char *aUriSet, const char *aUriGet); + DatasetManager(ThreadNetif &aThreadNetif, const Tlv::Type aType, const char *aUriSet, const char *aUriGet); ThreadError Set(const Dataset &aDataset, uint8_t &aFlags); diff --git a/src/core/thread/meshcop_tlvs.hpp b/src/core/thread/meshcop_tlvs.hpp index bb6083afd..445792516 100644 --- a/src/core/thread/meshcop_tlvs.hpp +++ b/src/core/thread/meshcop_tlvs.hpp @@ -134,6 +134,14 @@ public: */ uint8_t *GetValue() { return reinterpret_cast(this) + sizeof(Tlv); } + /** + * This method returns a pointer to the Value. + * + * @returns A pointer to the value. + * + */ + const uint8_t *GetValue() const { return reinterpret_cast(this) + sizeof(Tlv); } + /** * This method returns a pointer to the next TLV. * diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 0b6fd5260..c0e337582 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -896,12 +896,12 @@ ThreadError Mle::AppendActiveTimestamp(Message &aMessage) { ThreadError error; ActiveTimestampTlv timestampTlv; - const MeshCoP::Timestamp ×tamp(mNetif.GetActiveDataset().GetNetwork().GetTimestamp()); + const MeshCoP::Timestamp *timestamp(mNetif.GetActiveDataset().GetNetwork().GetTimestamp()); - VerifyOrExit(timestamp.GetSeconds() != 0, error = kThreadError_None); + VerifyOrExit(timestamp && timestamp->GetSeconds() != 0, error = kThreadError_None); timestampTlv.Init(); - *static_cast(×tampTlv) = timestamp; + *static_cast(×tampTlv) = *timestamp; error = aMessage.Append(×tampTlv, sizeof(timestampTlv)); exit: @@ -912,12 +912,12 @@ ThreadError Mle::AppendPendingTimestamp(Message &aMessage) { ThreadError error; PendingTimestampTlv timestampTlv; - const MeshCoP::Timestamp ×tamp(mNetif.GetPendingDataset().GetNetwork().GetTimestamp()); + const MeshCoP::Timestamp *timestamp(mNetif.GetPendingDataset().GetNetwork().GetTimestamp()); - VerifyOrExit(timestamp.GetSeconds() != 0, error = kThreadError_None); + VerifyOrExit(timestamp && timestamp->GetSeconds() != 0, error = kThreadError_None); timestampTlv.Init(); - *static_cast(×tampTlv) = timestamp; + *static_cast(×tampTlv) = *timestamp; error = aMessage.Append(×tampTlv, sizeof(timestampTlv)); exit: diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index 7ff254fa9..b0a47b948 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -1950,13 +1950,15 @@ ThreadError MleRouter::HandleChildIdRequest(const Message &aMessage, const Ip6:: numTlvs = tlvRequest.GetLength(); if (activeTimestamp.GetLength() == 0 || - mNetif.GetActiveDataset().GetNetwork().GetTimestamp().Compare(activeTimestamp) != 0) + mNetif.GetActiveDataset().GetNetwork().GetTimestamp() == NULL || + mNetif.GetActiveDataset().GetNetwork().GetTimestamp()->Compare(activeTimestamp) != 0) { child->mRequestTlvs[numTlvs++] = Tlv::kActiveDataset; } if (pendingTimestamp.GetLength() == 0 || - mNetif.GetPendingDataset().GetNetwork().GetTimestamp().Compare(pendingTimestamp) != 0) + mNetif.GetPendingDataset().GetNetwork().GetTimestamp() == NULL || + mNetif.GetPendingDataset().GetNetwork().GetTimestamp()->Compare(pendingTimestamp) != 0) { child->mRequestTlvs[numTlvs++] = Tlv::kPendingDataset; } @@ -2100,13 +2102,15 @@ ThreadError MleRouter::HandleDataRequest(const Message &aMessage, const Ip6::Mes numTlvs = tlvRequest.GetLength(); if (activeTimestamp.GetLength() == 0 || - mNetif.GetActiveDataset().GetNetwork().GetTimestamp().Compare(activeTimestamp) != 0) + mNetif.GetActiveDataset().GetNetwork().GetTimestamp() == NULL || + mNetif.GetActiveDataset().GetNetwork().GetTimestamp()->Compare(activeTimestamp) != 0) { tlvs[numTlvs++] = Tlv::kActiveDataset; } if (pendingTimestamp.GetLength() == 0 || - mNetif.GetPendingDataset().GetNetwork().GetTimestamp().Compare(pendingTimestamp) != 0) + mNetif.GetPendingDataset().GetNetwork().GetTimestamp() == NULL || + mNetif.GetPendingDataset().GetNetwork().GetTimestamp()->Compare(pendingTimestamp) != 0) { tlvs[numTlvs++] = Tlv::kPendingDataset; }