diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index c3899b060..71f894831 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -69,6 +69,7 @@ Mle::Mle(otInstance &aInstance) : mReattachState(kReattachStop), mParentRequestTimer(aInstance, &Mle::HandleParentRequestTimer, this), mDelayedResponseTimer(aInstance, &Mle::HandleDelayedResponseTimer, this), + mChildUpdateRequestTimer(aInstance, &Mle::HandleChildUpdateRequestTimer, this), mLastPartitionId(0), mLastPartitionRouterIdSequence(0), mLastPartitionIdTimeout(0), @@ -597,6 +598,7 @@ otError Mle::SetStateDetached(void) mRole = OT_DEVICE_ROLE_DETACHED; mParentRequestState = kParentIdle; mParentRequestTimer.Stop(); + mChildUpdateRequestTimer.Stop(); netif.GetMeshForwarder().SetRxOff(); netif.GetMac().SetBeaconEnabled(false); netif.GetMle().HandleDetachStart(); @@ -629,8 +631,9 @@ otError Mle::SetStateChild(uint16_t aRloc16) if ((mDeviceMode & ModeTlv::kModeRxOnWhenIdle) != 0) { - mParentRequestTimer.Start(TimerMilli::SecToMsec(mTimeout) - - static_cast(kUnicastRetransmissionDelay) * kMaxChildKeepAliveAttempts); + mChildUpdateRequestTimer.Start(TimerMilli::SecToMsec(mTimeout) - + static_cast(kUnicastRetransmissionDelay) * + kMaxChildKeepAliveAttempts); } if ((mDeviceMode & ModeTlv::kModeFFD) != 0) @@ -1406,15 +1409,7 @@ void Mle::HandleParentRequestTimer(void) switch (mParentRequestState) { case kParentIdle: - if (mParent.GetState() == Neighbor::kStateValid) - { - SendChildUpdateRequest(); - } - else - { - BecomeDetached(); - } - + assert(false); break; case kParentSynchronize: @@ -1513,12 +1508,6 @@ void Mle::HandleParentRequestTimer(void) break; case kAttachBetter: - if (mRole == OT_DEVICE_ROLE_CHILD) - { - // Restart keep-alive timer as it was disturbed by attachment procedure. - mParentRequestTimer.Start(0); - } - break; } } @@ -1758,6 +1747,16 @@ void Mle::HandleSendChildUpdateRequest(void) } } +void Mle::HandleChildUpdateRequestTimer(Timer &aTimer) +{ + GetOwner(aTimer).HandleChildUpdateRequestTimer(); +} + +void Mle::HandleChildUpdateRequestTimer(void) +{ + SendChildUpdateRequest(); +} + otError Mle::SendChildUpdateRequest(void) { ThreadNetif &netif = GetNetif(); @@ -1772,7 +1771,9 @@ otError Mle::SendChildUpdateRequest(void) ExitNow(); } - mParentRequestTimer.Start(kUnicastRetransmissionDelay); + VerifyOrExit(mParent.IsStateValidOrRestoring(), error = OT_ERROR_INVALID_STATE); + + mChildUpdateRequestTimer.Start(kUnicastRetransmissionDelay); mChildUpdateAttempts++; VerifyOrExit((message = NewMleMessage()) != NULL, error = OT_ERROR_NO_BUFS); @@ -3083,12 +3084,13 @@ otError Mle::HandleChildUpdateResponse(const Message &aMessage, const Ip6::Messa { netif.GetMeshForwarder().GetDataPollManager().SetAttachMode(false); netif.GetMeshForwarder().SetRxOnWhenIdle(false); - mParentRequestTimer.Stop(); + mChildUpdateRequestTimer.Stop(); } else { - mParentRequestTimer.Start(TimerMilli::SecToMsec(mTimeout) - - static_cast(kUnicastRetransmissionDelay) * kMaxChildKeepAliveAttempts); + mChildUpdateRequestTimer.Start(TimerMilli::SecToMsec(mTimeout) - + static_cast(kUnicastRetransmissionDelay) * + kMaxChildKeepAliveAttempts); netif.GetMeshForwarder().SetRxOnWhenIdle(true); } diff --git a/src/core/thread/mle.hpp b/src/core/thread/mle.hpp index e440978fd..5a8e851f2 100644 --- a/src/core/thread/mle.hpp +++ b/src/core/thread/mle.hpp @@ -1380,6 +1380,7 @@ protected: TimerMilli mParentRequestTimer; ///< The timer for driving the Parent Request process. TimerMilli mDelayedResponseTimer; ///< The timer to delay MLE responses. + TimerMilli mChildUpdateRequestTimer; ///< The timer for sending MLE Child Update Request messages. uint32_t mLastPartitionId; ///< The partition ID of the previous Thread partition uint8_t mLastPartitionRouterIdSequence; ///< The router ID sequence from the previous Thread partition uint8_t mLastPartitionIdTimeout; ///< The time remaining to avoid the previous Thread partition @@ -1402,6 +1403,8 @@ private: void HandleParentRequestTimer(void); static void HandleDelayedResponseTimer(Timer &aTimer); void HandleDelayedResponseTimer(void); + static void HandleChildUpdateRequestTimer(Timer &aTimer); + void HandleChildUpdateRequestTimer(void); static void HandleUdpReceive(void *aContext, otMessage *aMessage, const otMessageInfo *aMessageInfo); void HandleUdpReceive(Message &aMessage, const Ip6::MessageInfo &aMessageInfo); static void HandleSendChildUpdateRequest(Tasklet &aTasklet); diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index 79d2366e9..a39d72d5d 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -434,6 +434,7 @@ otError MleRouter::SetStateRouter(uint16_t aRloc16) mRole = OT_DEVICE_ROLE_ROUTER; mParentRequestState = kParentIdle; mParentRequestTimer.Stop(); + mChildUpdateRequestTimer.Stop(); ResetAdvertiseInterval(); netif.SubscribeAllRoutersMulticast(); @@ -471,6 +472,7 @@ otError MleRouter::SetStateLeader(uint16_t aRloc16) mRole = OT_DEVICE_ROLE_LEADER; mParentRequestState = kParentIdle; mParentRequestTimer.Stop(); + mChildUpdateRequestTimer.Stop(); ResetAdvertiseInterval(); AddLeaderAloc();