From c9191ae79d70f30e446b6460de3e9544a7b9884b Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Sun, 12 Mar 2017 10:10:47 -0700 Subject: [PATCH] Add retransmission logic to MLE Child Update exchanges from child. (#1457) --- src/core/thread/mle.cpp | 47 +++++++++++++++---------------- src/core/thread/mle.hpp | 2 +- src/core/thread/mle_constants.hpp | 1 + 3 files changed, 25 insertions(+), 25 deletions(-) diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 0dd9c723d..b83bca352 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -236,9 +236,9 @@ ThreadError Mle::Start(bool aEnableReattach) } else { - SendChildUpdateRequest(); mParentRequestState = kParentSynchronize; - mParentRequestTimer.Start(kParentRequestRouterTimeout); + mChildUpdateAttempts = 0; + SendChildUpdateRequest(); } exit: @@ -546,10 +546,10 @@ ThreadError Mle::SetStateChild(uint16_t aRloc16) SetRloc16(aRloc16); mDeviceState = kDeviceStateChild; mParentRequestState = kParentIdle; + mChildUpdateAttempts = 0; if ((mDeviceMode & ModeTlv::kModeRxOnWhenIdle) != 0) { - mKeepAliveAttemptsSent = 0; mParentRequestTimer.Start(Timer::SecToMsec(mTimeout / kMaxChildKeepAliveAttempts)); } @@ -579,6 +579,8 @@ uint32_t Mle::GetTimeout(void) const ThreadError Mle::SetTimeout(uint32_t aTimeout) { + VerifyOrExit(mTimeout != aTimeout, ;); + if (aTimeout < 4) { aTimeout = 4; @@ -589,13 +591,9 @@ ThreadError Mle::SetTimeout(uint32_t aTimeout) if (mDeviceState == kDeviceStateChild) { SendChildUpdateRequest(); - - if ((mDeviceMode & ModeTlv::kModeRxOnWhenIdle) != 0) - { - mParentRequestTimer.Start(Timer::SecToMsec(mTimeout / kMaxChildKeepAliveAttempts)); - } } +exit: return kThreadError_None; } @@ -611,6 +609,7 @@ ThreadError Mle::SetDeviceMode(uint8_t aDeviceMode) VerifyOrExit((aDeviceMode & ModeTlv::kModeFFD) == 0 || (aDeviceMode & ModeTlv::kModeRxOnWhenIdle) != 0, error = kThreadError_InvalidArgs); + VerifyOrExit(mDeviceMode != aDeviceMode, ;); mDeviceMode = aDeviceMode; @@ -1265,20 +1264,7 @@ void Mle::HandleParentRequestTimer(void) case kParentIdle: if (mParent.mState == Neighbor::kStateValid) { - if (mDeviceMode & ModeTlv::kModeRxOnWhenIdle) - { - if (mKeepAliveAttemptsSent >= kMaxChildKeepAliveAttempts) - { - // Reattach when no Child Update Response received for more than kMaxChildKeepAliveAttempts - BecomeDetached(); - } - else - { - SendChildUpdateRequest(); - mKeepAliveAttemptsSent++; - mParentRequestTimer.Start(Timer::SecToMsec(mTimeout / kMaxChildKeepAliveAttempts)); - } - } + SendChildUpdateRequest(); } else { @@ -1651,7 +1637,17 @@ ThreadError Mle::SendChildUpdateRequest(void) { ThreadError error = kThreadError_None; Ip6::Address destination; - Message *message; + Message *message = NULL; + + if (mChildUpdateAttempts >= kMaxChildKeepAliveAttempts) + { + mChildUpdateAttempts = 0; + BecomeDetached(); + ExitNow(); + } + + mParentRequestTimer.Start(kUnicastRetransmissionDelay); + mChildUpdateAttempts++; VerifyOrExit((message = NewMleMessage()) != NULL, ;); SuccessOrExit(error = AppendHeader(*message, Header::kCommandChildUpdateRequest)); @@ -2942,13 +2938,16 @@ ThreadError Mle::HandleChildUpdateResponse(const Message &aMessage, const Ip6::M { mNetif.GetMeshForwarder().SetPollPeriod(Timer::SecToMsec(mTimeout / kMaxChildKeepAliveAttempts)); mNetif.GetMeshForwarder().SetRxOnWhenIdle(false); + mParentRequestTimer.Stop(); } else { - mKeepAliveAttemptsSent = 0; + mParentRequestTimer.Start(Timer::SecToMsec(mTimeout / kMaxChildKeepAliveAttempts)); mNetif.GetMeshForwarder().SetRxOnWhenIdle(true); } + mChildUpdateAttempts = 0; + break; default: diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index c2d425c1b..3d61f9f3b 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -1429,7 +1429,7 @@ private: uint8_t mParentLinkQuality3; uint8_t mParentLinkQuality2; uint8_t mParentLinkQuality1; - uint8_t mKeepAliveAttemptsSent; + uint8_t mChildUpdateAttempts; LeaderDataTlv mParentLeaderData; bool mParentIsSingleton; diff --git a/src/core/thread/mle_constants.hpp b/src/core/thread/mle_constants.hpp index 39fa9a395..663094a56 100644 --- a/src/core/thread/mle_constants.hpp +++ b/src/core/thread/mle_constants.hpp @@ -61,6 +61,7 @@ enum kParentRequestChildTimeout = 1250, ///< End Device Request timeout kParentResponseMaxDelayRouters = 500, ///< Maximum delay for response for Parent Request sent to routers only kParentResponseMaxDelayAll = 1000, ///< Maximum delay for response for Parent Request sent to all devices + kUnicastRetransmissionDelay = 1000, ///< Base delay before retransmitting an MLE unicast. kMaxResponseDelay = 1000, ///< Maximum delay before responding to a multicast request kMaxChildIdRequestTimeout = 5000, ///< Maximum delay for receiving a Child ID Request kChildUpdateRequestPeriod = 100, ///< The period for sending Child Update Request