[mle] simplify router/leader role restoration upon reset (#10798)

This commit introduces the `RouterRoleRestorer` class, nested within
`MleRouter`, to manage router/leader role restoration after an MLE
operation restart (e.g., a device reboot) by sending multicast Link
Requests. This class simplifies the code and centralizes role
restoration logic.

Specific changes:

- A new member variable `mLastSavedRole` is added to track the last
  attached role (saved in non-volatile memory). This is used by
  `RouterRoleRestorer` to determine the number of Link Request
  attempts. This variable replaces the previous `mWasLeader`, which
  was only updated after a reboot and would not account for role
  changes afterward.
- The `AttachTimer` is now used for role restoration instead of the
  retransmission timer, as role restoration always occurs while the
  device is detached and before any attach attempts.
- The `kLinkRequestTimeout` is used for the last attempt before
  considering restoration failure.
- The `mChallengeTimeout` mechanism is now removed (in earlier Thread
  specification versions, multicast Link Requests could be used while
  the device was attached, but this is no longer used or needed).
- `test-012-reset-recovery.py` is updated to validate the role
  restoration behavior. `test_detach` is also updated and fixed.
This commit is contained in:
Abtin Keshavarzian
2024-10-10 21:47:34 -07:00
committed by GitHub
parent 057b87fdd1
commit 19b2d6bbc4
9 changed files with 182 additions and 84 deletions
@@ -133,8 +133,7 @@ class PublishMeshCopService(thread_cert.TestCase):
br1.stop()
br1.set_active_dataset(updateExisting=True, network_name='ot-br1-1')
br1.start()
self.simulator.go(config.BORDER_ROUTER_STARTUP_DELAY)
self.simulator.go(5) # Needs to wait extra some time to update meshcop service on state changes.
self.simulator.go(config.LEADER_REBOOT_DELAY)
self.check_meshcop_service(br1, host)
# verify that there are two meshcop services
@@ -142,7 +141,7 @@ class PublishMeshCopService(thread_cert.TestCase):
br2.start()
br2.disable_backbone_router()
br2.enable_br()
self.simulator.go(config.BORDER_ROUTER_STARTUP_DELAY)
self.simulator.go(config.LEADER_REBOOT_DELAY)
service_instances = host.browse_mdns_services('_meshcop._udp')
self.assertEqual(len(service_instances), 2)
+1
View File
@@ -138,6 +138,7 @@ SECURITY_POLICY = [672, 'onrc']
LEADER_STARTUP_DELAY = 12
ROUTER_STARTUP_DELAY = 10
LEADER_REBOOT_DELAY = 40
ED_STARTUP_DELAY = 5
BORDER_ROUTER_STARTUP_DELAY = 20
MAX_NEIGHBOR_AGE = 100
+2 -3
View File
@@ -145,10 +145,9 @@ class TestDetach(thread_cert.TestCase):
self.assertEqual(leader.get_state(), 'disabled')
leader.start()
# leader didn't become leader after the last start(), so it re-syncs in a non-critical manner thus taking ROUTER_RESET_DELAY to recover
self.simulator.go(config.ROUTER_RESET_DELAY / 2)
self.simulator.go(config.LEADER_RESET_DELAY / 2)
self.assertEqual(leader.get_state(), 'detached')
self.simulator.go(config.ROUTER_RESET_DELAY / 2)
self.simulator.go(config.LEADER_RESET_DELAY / 2)
self.assertEqual(leader.get_state(), 'leader')
router1.start()
self.simulator.go(config.ROUTER_RESET_DELAY)