diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 38ee74bb5..75361bc21 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -1606,8 +1606,13 @@ void Mle::HandleAttachTimer(void) // to which the device is attached. This ensures that the // new parent candidate is compared with the current parent // and that it is indeed preferred over the current one. + // If we are in kAttachStateParentRequestRouter and cannot + // find a parent with best link quality(3), we will keep + // the candidate and forward to REED stage to find a better + // parent. - if (mParentCandidate.GetState() == Neighbor::kStateParentResponse && + if ((mParentCandidate.GetLinkInfo().GetLinkQuality() == 3 || mAttachState != kAttachStateParentRequestRouter) && + mParentCandidate.GetState() == Neighbor::kStateParentResponse && (mRole != OT_DEVICE_ROLE_CHILD || mReceivedResponseFromParent || mParentRequestMode == kAttachBetter) && SendChildIdRequest() == OT_ERROR_NONE) { @@ -3133,8 +3138,6 @@ otError Mle::HandleParentResponse(const Message &aMessage, const Ip6::MessageInf linkQuality = LinkQualityInfo::ConvertLinkMarginToLinkQuality(linkMargin); - VerifyOrExit(mAttachState != kAttachStateParentRequestRouter || linkQuality == 3); - // Connectivity SuccessOrExit(error = Tlv::GetTlv(aMessage, Tlv::kConnectivity, sizeof(connectivity), connectivity)); VerifyOrExit(connectivity.IsValid(), error = OT_ERROR_PARSE); diff --git a/src/core/thread/mle_constants.hpp b/src/core/thread/mle_constants.hpp index ff658d4a2..c740b0d0e 100644 --- a/src/core/thread/mle_constants.hpp +++ b/src/core/thread/mle_constants.hpp @@ -60,6 +60,7 @@ enum kThreadVersion = 2, ///< Thread Version kUdpPort = 19788, ///< MLE UDP Port kParentRequestRouterTimeout = 750, ///< Router Parent Request timeout + kParentRequestDuplicateMargin = 50, ///< Margin for duplicate parent request kParentRequestReedTimeout = 1250, ///< Router and REEDs Parent Request timeout kAttachStartJitter = 50, ///< Maximum jitter time added to start of attach. kAnnounceProcessTimeout = 250, ///< Timeout after receiving Announcement before channel/pan-id change diff --git a/src/core/thread/mle_router.cpp b/src/core/thread/mle_router.cpp index e872bf534..3c4d755a7 100644 --- a/src/core/thread/mle_router.cpp +++ b/src/core/thread/mle_router.cpp @@ -1649,7 +1649,7 @@ otError MleRouter::HandleParentRequest(const Message &aMessage, const Ip6::Messa } #endif } - else if (TimerMilli::Elapsed(child->GetLastHeard()) < kParentRequestRouterTimeout) + else if (TimerMilli::Elapsed(child->GetLastHeard()) < kParentRequestRouterTimeout - kParentRequestDuplicateMargin) { ExitNow(error = OT_ERROR_DUPLICATED); }