diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index eeaba81f7..a798bb98a 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -290,13 +290,17 @@ Error Mle::RestorePrevRole(void) Error error = kErrorFailed; + VerifyOrExit(IsDetached()); VerifyOrExit(GetRloc16() != kInvalidRloc16); if (IsRouterRloc16(GetRloc16())) { #if OPENTHREAD_FTD VerifyOrExit(mLastSavedRole == kRoleRouter || mLastSavedRole == kRoleLeader); - error = BecomeRouter(ThreadStatusTlv::kTooFewRouters); + VerifyOrExit(IsRouterEligible()); + Get().SetRxOnWhenIdle(true); + mRouterRoleRestorer.Start(mLastSavedRole); + error = kErrorNone; #endif ExitNow(); } diff --git a/src/core/thread/mle_ftd.cpp b/src/core/thread/mle_ftd.cpp index 3fdbc5e2b..8dec57a3a 100644 --- a/src/core/thread/mle_ftd.cpp +++ b/src/core/thread/mle_ftd.cpp @@ -189,8 +189,21 @@ Error Mle::BecomeRouter(ThreadStatusTlv::Status aStatus) { Error error = kErrorNone; - VerifyOrExit(!IsDisabled(), error = kErrorInvalidState); - VerifyOrExit(!IsRouterOrLeader(), error = kErrorNone); + switch (mRole) + { + case kRoleChild: + break; + + case kRoleDisabled: + case kRoleDetached: + error = kErrorInvalidState; + OT_FALL_THROUGH; + + case kRoleRouter: + case kRoleLeader: + ExitNow(); + } + VerifyOrExit(IsRouterEligible(), error = kErrorNotCapable); LogInfo("Attempt to become router"); @@ -198,19 +211,7 @@ Error Mle::BecomeRouter(ThreadStatusTlv::Status aStatus) Get().SetRxOnWhenIdle(true); mRouterRoleTransition.StopTimeout(); - switch (mRole) - { - case kRoleDetached: - mRouterRoleRestorer.Start(mLastSavedRole); - break; - - case kRoleChild: - SuccessOrExit(error = SendAddressSolicit(aStatus)); - break; - - default: - OT_ASSERT(false); - } + error = SendAddressSolicit(aStatus); exit: return error;