From 6f1631aeba08f8c19022f01abb9fc861fd80360a Mon Sep 17 00:00:00 2001 From: Abtin Keshavarzian Date: Wed, 7 Dec 2022 11:11:45 -0800 Subject: [PATCH] [mle] re-attach on FTD/MTD mode changes or from rx-on to sleepy (#8484) This commit updates behavior when device mode gets changed so to re-attach on switching between MTD/FTD modes and also on switching from rx-on to sleepy (rx-off) mode (when attached as a child). This commit also updates `test-027-child-mode-change.py` to match the new behavior. --- src/core/thread/mle.cpp | 33 +++++++++---------- tests/scripts/expect/cli-router.exp | 1 + .../toranj/ncp/test-027-child-mode-change.py | 9 ----- 3 files changed, 16 insertions(+), 27 deletions(-) diff --git a/src/core/thread/mle.cpp b/src/core/thread/mle.cpp index 194045c91..4e741f605 100644 --- a/src/core/thread/mle.cpp +++ b/src/core/thread/mle.cpp @@ -815,30 +815,27 @@ Error Mle::SetDeviceMode(DeviceMode aDeviceMode) IgnoreError(Store()); - switch (mRole) - { - case kRoleDisabled: - break; + // We need to re-attach on switching between MTD/FTD modes + // and also on switching from rx-on to sleepy (rx-off) mode. - case kRoleDetached: + if (IsAttached() && ((oldMode.IsFullThreadDevice() != mDeviceMode.IsFullThreadDevice()) || + (oldMode.IsRxOnWhenIdle() && !mDeviceMode.IsRxOnWhenIdle()))) + { + mAttachCounter = 0; + IgnoreError(BecomeDetached()); + ExitNow(); + } + + if (IsDetached()) + { mAttachCounter = 0; SetStateDetached(); Attach(kAnyPartition); - break; - - case kRoleChild: + } + else if (IsChild()) + { SetStateChild(GetRloc16()); IgnoreError(SendChildUpdateRequest()); - break; - - case kRoleRouter: - case kRoleLeader: - if (oldMode.IsFullThreadDevice() && !mDeviceMode.IsFullThreadDevice()) - { - IgnoreError(BecomeDetached()); - } - - break; } exit: diff --git a/tests/scripts/expect/cli-router.exp b/tests/scripts/expect/cli-router.exp index b7f1a56dd..11456af19 100755 --- a/tests/scripts/expect/cli-router.exp +++ b/tests/scripts/expect/cli-router.exp @@ -52,6 +52,7 @@ expect_line "Done" switch_node 2 send "mode rdn\n" expect_line "Done" +sleep 5 send "state router\n" expect_line "Done" wait_for "router list" $router_id diff --git a/tests/toranj/ncp/test-027-child-mode-change.py b/tests/toranj/ncp/test-027-child-mode-change.py index b3c92c6e8..c3326bcb5 100644 --- a/tests/toranj/ncp/test-027-child-mode-change.py +++ b/tests/toranj/ncp/test-027-child-mode-change.py @@ -127,8 +127,6 @@ child2_ml_address = child2.get(wpan.WPAN_IP6_MESH_LOCAL_ADDRESS)[1:-1] sender = parent.prepare_tx(parent_ml_address, child2_ml_address, 800, NUM_MSGS) -child2_rx_ip_counter = int(child2.get(wpan.WPAN_NCP_COUNTER_RX_IP_SEC_TOTAL), 0) - wpan.Node.perform_async_tx_rx() verify(sender.was_successful) @@ -144,13 +142,6 @@ verify(int(child2.get(wpan.WPAN_THREAD_DEVICE_MODE), 0) == DEVICE_MODE_END_DEVIC # Verify that the child table on parent is also updated wpan.verify_within(check_child_table, WAIT_INTERVAL) - -def check_child2_received_msg(): - verify(int(child2.get(wpan.WPAN_NCP_COUNTER_RX_IP_SEC_TOTAL), 0) >= child2_rx_ip_counter + NUM_MSGS) - - -wpan.verify_within(check_child2_received_msg, WAIT_INTERVAL) - # Reset parent and verify all children are recovered parent.reset() wpan.verify_within(check_child_table, WAIT_INTERVAL)