From b082d965e923bd5a2077776792003a09ef466ad0 Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Fri, 16 Sep 2016 08:43:52 -0700 Subject: [PATCH] Implement DATA_RESUBMIT_DELAY. (#586) --- src/core/thread/mle.cpp | 1 + src/core/thread/network_data.cpp | 25 +++++++++++++++++++++---- src/core/thread/network_data.hpp | 23 ++++++++++++++++++++--- src/core/thread/network_data_leader.cpp | 4 ++-- src/core/thread/network_data_local.cpp | 14 +++++++++++--- 5 files changed, 55 insertions(+), 12 deletions(-) diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index c0e337582..b2cfb1776 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -372,6 +372,7 @@ ThreadError Mle::SetStateChild(uint16_t aRloc16) mMleRouter.HandleChildStart(mParentRequestMode); } + mNetif.GetNetworkDataLocal().ClearResubmitDelayTimer(); mNetif.GetIp6().SetForwardingEnabled(false); otLogInfoMle("Mode -> Child\n"); diff --git a/src/core/thread/network_data.cpp b/src/core/thread/network_data.cpp index 92bdeda9a..31110ef99 100644 --- a/src/core/thread/network_data.cpp +++ b/src/core/thread/network_data.cpp @@ -45,8 +45,11 @@ namespace Thread { namespace NetworkData { -NetworkData::NetworkData(ThreadNetif &aThreadNetif): +NetworkData::NetworkData(ThreadNetif &aThreadNetif, bool aLocal): mMle(aThreadNetif.GetMle()), + mLocal(aLocal), + mLastAttemptWait(false), + mLastAttempt(0), mSocket(aThreadNetif.GetIp6().mUdp) { mLength = 0; @@ -585,13 +588,16 @@ ThreadError NetworkData::Remove(uint8_t *aStart, uint8_t aLength) return kThreadError_None; } -ThreadError NetworkData::SendServerDataNotification(bool aLocal, uint16_t aRloc16) +ThreadError NetworkData::SendServerDataNotification(uint16_t aRloc16) { ThreadError error = kThreadError_None; Coap::Header header; - Message *message; + Message *message = NULL; Ip6::MessageInfo messageInfo; + VerifyOrExit(!mLastAttemptWait || static_cast(Timer::GetNow() - mLastAttempt) < kDataResubmitDelay, + error = kThreadError_Already); + mSocket.Open(&HandleUdpReceive, this); for (size_t i = 0; i < sizeof(mCoapToken); i++) @@ -612,7 +618,7 @@ ThreadError NetworkData::SendServerDataNotification(bool aLocal, uint16_t aRloc1 VerifyOrExit((message = mSocket.NewMessage(0)) != NULL, error = kThreadError_NoBufs); SuccessOrExit(error = message->Append(header.GetBytes(), header.GetLength())); - if (aLocal) + if (mLocal) { ThreadTlv tlv; tlv.SetType(ThreadTlv::kThreadNetworkData); @@ -634,6 +640,12 @@ ThreadError NetworkData::SendServerDataNotification(bool aLocal, uint16_t aRloc1 messageInfo.mPeerPort = kCoapUdpPort; SuccessOrExit(error = mSocket.SendTo(*message, messageInfo)); + if (mLocal) + { + mLastAttempt = Timer::GetNow(); + mLastAttemptWait = true; + } + otLogInfoNetData("Sent server data notification\n"); exit: @@ -646,6 +658,11 @@ exit: return error; } +void NetworkData::ClearResubmitDelayTimer(void) +{ + mLastAttemptWait = false; +} + void NetworkData::HandleUdpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo) { Local *obj = static_cast(aContext); diff --git a/src/core/thread/network_data.hpp b/src/core/thread/network_data.hpp index c1a7fe900..540893628 100644 --- a/src/core/thread/network_data.hpp +++ b/src/core/thread/network_data.hpp @@ -92,8 +92,11 @@ public: /** * This constructor initializes the object. * + * @param[in] aThreadNetif A reference to the Thread network interface. + * @param[in] aLocal TRUE if this represents local network data, FALSE otherwise. + * */ - NetworkData(ThreadNetif &aThreadNetif); + NetworkData(ThreadNetif &aThreadNetif, bool aLocal); /** * This method provides a full or stable copy of the Thread Network Data. @@ -182,6 +185,12 @@ public: */ bool ContainsExternalRoutes(NetworkData &aCompare, uint16_t aRloc16); + /** + * This method cancels the data resubmit delay timer. + * + */ + void ClearResubmitDelayTimer(void); + protected: /** * This method returns a pointer to the Border Router TLV within a given Prefix TLV. @@ -318,14 +327,13 @@ protected: /** * This method sends a Server Data Notification message to the Leader. * - * @param[in] aLocal TRUE if notifying Leader of local network data, FALSE otherwise. * @param[in] aRloc16 The old RLOC16 value that was previously registered. * * @retval kThreadError_None Successfully enqueued the notification message. * @retval kThreadError_NoBufs Insufficient message buffers to generate the notification message. * */ - ThreadError SendServerDataNotification(bool aLocal, uint16_t aRloc16); + ThreadError SendServerDataNotification(uint16_t aRloc16); uint8_t mTlvs[kMaxSize]; ///< The Network Data buffer. uint8_t mLength; ///< The number of valid bytes in @var mTlvs. @@ -333,9 +341,18 @@ protected: Mle::MleRouter &mMle; private: + enum + { + kDataResubmitDelay = 300, ///< DATA_RESUBMIT_DELAY (seconds) + }; + static void HandleUdpReceive(void *aContext, otMessage aMessage, const otMessageInfo *aMessageInfo); void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo); + const bool mLocal; + bool mLastAttemptWait; + uint32_t mLastAttempt; + Ip6::UdpSocket mSocket; uint8_t mCoapToken[2]; uint16_t mCoapMessageId; diff --git a/src/core/thread/network_data_leader.cpp b/src/core/thread/network_data_leader.cpp index 2b03c8f03..677210b7b 100644 --- a/src/core/thread/network_data_leader.cpp +++ b/src/core/thread/network_data_leader.cpp @@ -52,7 +52,7 @@ namespace Thread { namespace NetworkData { Leader::Leader(ThreadNetif &aThreadNetif): - NetworkData(aThreadNetif), + NetworkData(aThreadNetif, false), mTimer(aThreadNetif.GetIp6().mTimerScheduler, &HandleTimer, this), mServerData(OPENTHREAD_URI_SERVER_DATA, &HandleServerData, this), mCoapServer(aThreadNetif.GetCoapServer()), @@ -961,7 +961,7 @@ ThreadError Leader::SendServerDataNotification(uint16_t aRloc16) VerifyOrExit(rlocIn, error = kThreadError_NotFound); - SuccessOrExit(error = NetworkData::SendServerDataNotification(false, aRloc16)); + SuccessOrExit(error = NetworkData::SendServerDataNotification(aRloc16)); exit: return error; diff --git a/src/core/thread/network_data_local.cpp b/src/core/thread/network_data_local.cpp index 18d9f7171..12a4b5d58 100644 --- a/src/core/thread/network_data_local.cpp +++ b/src/core/thread/network_data_local.cpp @@ -42,7 +42,7 @@ namespace Thread { namespace NetworkData { Local::Local(ThreadNetif &aThreadNetif): - NetworkData(aThreadNetif), + NetworkData(aThreadNetif, true), mOldRloc(Mac::kShortAddrInvalid), mLeader(aThreadNetif.GetNetworkDataLeader()) { @@ -75,6 +75,8 @@ ThreadError Local::AddOnMeshPrefix(const uint8_t *aPrefix, uint8_t aPrefixLength brTlv->SetStable(); } + ClearResubmitDelayTimer(); + otDumpDebgNetData("add prefix done", mTlvs, mLength); return kThreadError_None; } @@ -87,6 +89,7 @@ ThreadError Local::RemoveOnMeshPrefix(const uint8_t *aPrefix, uint8_t aPrefixLen VerifyOrExit((tlv = FindPrefix(aPrefix, aPrefixLength)) != NULL, error = kThreadError_Error); VerifyOrExit(FindBorderRouter(*tlv) != NULL, error = kThreadError_Error); Remove(reinterpret_cast(tlv), sizeof(NetworkDataTlv) + tlv->GetLength()); + ClearResubmitDelayTimer(); exit: otDumpDebgNetData("remove done", mTlvs, mLength); @@ -118,6 +121,8 @@ ThreadError Local::AddHasRoutePrefix(const uint8_t *aPrefix, uint8_t aPrefixLeng hasRouteTlv->SetStable(); } + ClearResubmitDelayTimer(); + otDumpDebgNetData("add route done", mTlvs, mLength); return kThreadError_None; } @@ -130,6 +135,7 @@ ThreadError Local::RemoveHasRoutePrefix(const uint8_t *aPrefix, uint8_t aPrefixL VerifyOrExit((tlv = FindPrefix(aPrefix, aPrefixLength)) != NULL, error = kThreadError_Error); VerifyOrExit(FindHasRoute(*tlv) != NULL, error = kThreadError_Error); Remove(reinterpret_cast(tlv), sizeof(NetworkDataTlv) + tlv->GetLength()); + ClearResubmitDelayTimer(); exit: otDumpDebgNetData("remove done", mTlvs, mLength); @@ -154,6 +160,8 @@ ThreadError Local::UpdateRloc(void) } } + ClearResubmitDelayTimer(); + return kThreadError_None; } @@ -221,14 +229,14 @@ ThreadError Local::SendServerDataNotification(void) UpdateRloc(); - VerifyOrExit(!IsOnMeshPrefixConsistent() || !IsExternalRouteConsistent(), error = kThreadError_None); + VerifyOrExit(!IsOnMeshPrefixConsistent() || !IsExternalRouteConsistent(), ClearResubmitDelayTimer()); if (mOldRloc == rloc) { mOldRloc = Mac::kShortAddrInvalid; } - SuccessOrExit(error = NetworkData::SendServerDataNotification(true, mOldRloc)); + SuccessOrExit(error = NetworkData::SendServerDataNotification(mOldRloc)); mOldRloc = rloc; exit: