mirror of
https://github.com/espressif/openthread.git
synced 2026-10-15 12:17:41 +00:00
[mle] enhance role restoration logic in Start() (#11679)
This commit refactors `Mle::Start()` by moving the logic for restoring the previous role into a new method, `RestorePrevRole()`. This change simplifies the startup process and improves robustness by adding more validation checks within `RestorePrevRole()`. The new method ensures that the previously saved state information is consistent before it is applied. For example, it verifies that `mLastSavedRole` matches the saved RLOC16 and that parent information is valid if the saved role was Child. These checks protect against loading invalid settings and allow the device to start more quickly by ignoring inconsistent state.
This commit is contained in:
+46
-18
@@ -225,29 +225,23 @@ Error Mle::Start(StartMode aMode)
|
||||
|
||||
Get<KeyManager>().Start();
|
||||
|
||||
if (aMode == kNormalAttach)
|
||||
switch (aMode)
|
||||
{
|
||||
case kNormalAttach:
|
||||
mReattachState =
|
||||
(Get<MeshCoP::ActiveDatasetManager>().Restore() == kErrorNone) ? kReattachActive : kReattachStop;
|
||||
|
||||
if (RestorePrevRole() == kErrorNone)
|
||||
{
|
||||
ExitNow();
|
||||
}
|
||||
break;
|
||||
|
||||
case kAnnounceAttach:
|
||||
break;
|
||||
}
|
||||
|
||||
if ((aMode == kAnnounceAttach) || (GetRloc16() == kInvalidRloc16))
|
||||
{
|
||||
Attach(kAnyPartition);
|
||||
}
|
||||
#if OPENTHREAD_FTD
|
||||
else if (IsRouterRloc16(GetRloc16()))
|
||||
{
|
||||
if (BecomeRouter(ThreadStatusTlv::kTooFewRouters) != kErrorNone)
|
||||
{
|
||||
Attach(kAnyPartition);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
IgnoreError(SendChildUpdateRequestToParent());
|
||||
}
|
||||
Attach(kAnyPartition);
|
||||
|
||||
exit:
|
||||
return error;
|
||||
@@ -286,6 +280,40 @@ exit:
|
||||
}
|
||||
}
|
||||
|
||||
Error Mle::RestorePrevRole(void)
|
||||
{
|
||||
// Restores the device to its previously saved role after MLE
|
||||
// start.
|
||||
//
|
||||
// Returns `kErrorNone` if the restoration process begins
|
||||
// successfully. An error is returned if:
|
||||
// - No previous role was saved.
|
||||
// - The saved role info is inconsistent (e.g., RLOC16 indicates a
|
||||
// router/leader, but `mLastSavedRole` doesn't match).
|
||||
// - The last role is "Child," but no valid parent is available.
|
||||
|
||||
Error error = kErrorFailed;
|
||||
|
||||
VerifyOrExit(GetRloc16() != kInvalidRloc16);
|
||||
|
||||
if (IsRouterRloc16(GetRloc16()))
|
||||
{
|
||||
#if OPENTHREAD_FTD
|
||||
VerifyOrExit(mLastSavedRole == kRoleRouter || mLastSavedRole == kRoleLeader);
|
||||
error = BecomeRouter(ThreadStatusTlv::kTooFewRouters);
|
||||
#endif
|
||||
ExitNow();
|
||||
}
|
||||
|
||||
VerifyOrExit(mLastSavedRole == kRoleChild);
|
||||
VerifyOrExit(mParent.IsStateValidOrRestoring());
|
||||
IgnoreError(SendChildUpdateRequestToParent());
|
||||
error = kErrorNone;
|
||||
|
||||
exit:
|
||||
return error;
|
||||
}
|
||||
|
||||
const Counters &Mle::GetCounters(void)
|
||||
{
|
||||
UpdateRoleTimeCounters(mRole);
|
||||
|
||||
@@ -1958,6 +1958,7 @@ private:
|
||||
|
||||
Error Start(StartMode aMode);
|
||||
void Stop(StopMode aMode);
|
||||
Error RestorePrevRole(void);
|
||||
TxMessage *NewMleMessage(Command aCommand);
|
||||
void SetRole(DeviceRole aRole);
|
||||
void Attach(AttachMode aMode);
|
||||
|
||||
Reference in New Issue
Block a user