xref: /aosp_15_r20/external/openthread/tests/toranj/ncp/test-601-channel-manager-channel-change.py (revision cfb92d1480a9e65faed56933e9c12405f45898b4)
1*cfb92d14SAndroid Build Coastguard Worker#!/usr/bin/env python3
2*cfb92d14SAndroid Build Coastguard Worker#
3*cfb92d14SAndroid Build Coastguard Worker#  Copyright (c) 2018, The OpenThread Authors.
4*cfb92d14SAndroid Build Coastguard Worker#  All rights reserved.
5*cfb92d14SAndroid Build Coastguard Worker#
6*cfb92d14SAndroid Build Coastguard Worker#  Redistribution and use in source and binary forms, with or without
7*cfb92d14SAndroid Build Coastguard Worker#  modification, are permitted provided that the following conditions are met:
8*cfb92d14SAndroid Build Coastguard Worker#  1. Redistributions of source code must retain the above copyright
9*cfb92d14SAndroid Build Coastguard Worker#     notice, this list of conditions and the following disclaimer.
10*cfb92d14SAndroid Build Coastguard Worker#  2. Redistributions in binary form must reproduce the above copyright
11*cfb92d14SAndroid Build Coastguard Worker#     notice, this list of conditions and the following disclaimer in the
12*cfb92d14SAndroid Build Coastguard Worker#     documentation and/or other materials provided with the distribution.
13*cfb92d14SAndroid Build Coastguard Worker#  3. Neither the name of the copyright holder nor the
14*cfb92d14SAndroid Build Coastguard Worker#     names of its contributors may be used to endorse or promote products
15*cfb92d14SAndroid Build Coastguard Worker#     derived from this software without specific prior written permission.
16*cfb92d14SAndroid Build Coastguard Worker#
17*cfb92d14SAndroid Build Coastguard Worker#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18*cfb92d14SAndroid Build Coastguard Worker#  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19*cfb92d14SAndroid Build Coastguard Worker#  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20*cfb92d14SAndroid Build Coastguard Worker#  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21*cfb92d14SAndroid Build Coastguard Worker#  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22*cfb92d14SAndroid Build Coastguard Worker#  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23*cfb92d14SAndroid Build Coastguard Worker#  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24*cfb92d14SAndroid Build Coastguard Worker#  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25*cfb92d14SAndroid Build Coastguard Worker#  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26*cfb92d14SAndroid Build Coastguard Worker#  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27*cfb92d14SAndroid Build Coastguard Worker#  POSSIBILITY OF SUCH DAMAGE.
28*cfb92d14SAndroid Build Coastguard Worker
29*cfb92d14SAndroid Build Coastguard Workerimport time
30*cfb92d14SAndroid Build Coastguard Workerimport wpan
31*cfb92d14SAndroid Build Coastguard Workerfrom wpan import verify
32*cfb92d14SAndroid Build Coastguard Worker
33*cfb92d14SAndroid Build Coastguard Worker# -----------------------------------------------------------------------------------------------------------------------
34*cfb92d14SAndroid Build Coastguard Worker# Test description: verifies `ChannelManager` channel change process
35*cfb92d14SAndroid Build Coastguard Worker
36*cfb92d14SAndroid Build Coastguard Workertest_name = __file__[:-3] if __file__.endswith('.py') else __file__
37*cfb92d14SAndroid Build Coastguard Workerprint('-' * 120)
38*cfb92d14SAndroid Build Coastguard Workerprint('Starting \'{}\''.format(test_name))
39*cfb92d14SAndroid Build Coastguard Worker
40*cfb92d14SAndroid Build Coastguard Worker
41*cfb92d14SAndroid Build Coastguard Workerdef verify_channel(nodes, new_channel, wait_time=20):
42*cfb92d14SAndroid Build Coastguard Worker    """
43*cfb92d14SAndroid Build Coastguard Worker    This function checks the channel on a given list of `nodes` and verifies that all nodes
44*cfb92d14SAndroid Build Coastguard Worker    switch to a given `new_channel` (as int) within certain `wait_time` (int and in seconds)
45*cfb92d14SAndroid Build Coastguard Worker    """
46*cfb92d14SAndroid Build Coastguard Worker    start_time = time.time()
47*cfb92d14SAndroid Build Coastguard Worker
48*cfb92d14SAndroid Build Coastguard Worker    while not all([(new_channel == int(node.get(wpan.WPAN_CHANNEL), 0)) for node in nodes]):
49*cfb92d14SAndroid Build Coastguard Worker        if time.time() - start_time > wait_time:
50*cfb92d14SAndroid Build Coastguard Worker            print('Took too long to switch to channel {} ({}>{} sec)'.format(new_channel,
51*cfb92d14SAndroid Build Coastguard Worker                                                                             time.time() - start_time, wait_time))
52*cfb92d14SAndroid Build Coastguard Worker            exit(1)
53*cfb92d14SAndroid Build Coastguard Worker        time.sleep(0.1)
54*cfb92d14SAndroid Build Coastguard Worker
55*cfb92d14SAndroid Build Coastguard Worker
56*cfb92d14SAndroid Build Coastguard Worker# -----------------------------------------------------------------------------------------------------------------------
57*cfb92d14SAndroid Build Coastguard Worker# Creating `wpan.Nodes` instances
58*cfb92d14SAndroid Build Coastguard Worker
59*cfb92d14SAndroid Build Coastguard Workerspeedup = 4
60*cfb92d14SAndroid Build Coastguard Workerwpan.Node.set_time_speedup_factor(speedup)
61*cfb92d14SAndroid Build Coastguard Worker
62*cfb92d14SAndroid Build Coastguard Workerr1 = wpan.Node()
63*cfb92d14SAndroid Build Coastguard Workerr2 = wpan.Node()
64*cfb92d14SAndroid Build Coastguard Workerr3 = wpan.Node()
65*cfb92d14SAndroid Build Coastguard Workersc1 = wpan.Node()
66*cfb92d14SAndroid Build Coastguard Workerec1 = wpan.Node()
67*cfb92d14SAndroid Build Coastguard Workersc2 = wpan.Node()
68*cfb92d14SAndroid Build Coastguard Workersc3 = wpan.Node()
69*cfb92d14SAndroid Build Coastguard Worker
70*cfb92d14SAndroid Build Coastguard Workerall_nodes = [r1, r2, r3, sc1, ec1, sc2, sc3]
71*cfb92d14SAndroid Build Coastguard Worker
72*cfb92d14SAndroid Build Coastguard Worker# -----------------------------------------------------------------------------------------------------------------------
73*cfb92d14SAndroid Build Coastguard Worker# Init all nodes
74*cfb92d14SAndroid Build Coastguard Worker
75*cfb92d14SAndroid Build Coastguard Workerwpan.Node.init_all_nodes()
76*cfb92d14SAndroid Build Coastguard Worker
77*cfb92d14SAndroid Build Coastguard Worker# -----------------------------------------------------------------------------------------------------------------------
78*cfb92d14SAndroid Build Coastguard Worker# Build network topology
79*cfb92d14SAndroid Build Coastguard Worker
80*cfb92d14SAndroid Build Coastguard Workerfor node in all_nodes:
81*cfb92d14SAndroid Build Coastguard Worker    node.set(wpan.WPAN_OT_LOG_LEVEL, '0')
82*cfb92d14SAndroid Build Coastguard Worker
83*cfb92d14SAndroid Build Coastguard Workerr1.allowlist_node(r2)
84*cfb92d14SAndroid Build Coastguard Workerr2.allowlist_node(r1)
85*cfb92d14SAndroid Build Coastguard Workerr1.allowlist_node(r3)
86*cfb92d14SAndroid Build Coastguard Workerr3.allowlist_node(r1)
87*cfb92d14SAndroid Build Coastguard Worker
88*cfb92d14SAndroid Build Coastguard Workerr1.allowlist_node(sc1)
89*cfb92d14SAndroid Build Coastguard Workerr1.allowlist_node(ec1)
90*cfb92d14SAndroid Build Coastguard Workerr2.allowlist_node(sc2)
91*cfb92d14SAndroid Build Coastguard Workerr3.allowlist_node(sc3)
92*cfb92d14SAndroid Build Coastguard Worker
93*cfb92d14SAndroid Build Coastguard Workerr1.form('channel-manager', channel=12)
94*cfb92d14SAndroid Build Coastguard Workerr2.join_node(r1, node_type=wpan.JOIN_TYPE_ROUTER)
95*cfb92d14SAndroid Build Coastguard Workerr3.join_node(r1, node_type=wpan.JOIN_TYPE_ROUTER)
96*cfb92d14SAndroid Build Coastguard Workersc1.join_node(r1, node_type=wpan.JOIN_TYPE_SLEEPY_END_DEVICE)
97*cfb92d14SAndroid Build Coastguard Workerec1.join_node(r1, node_type=wpan.JOIN_TYPE_END_DEVICE)
98*cfb92d14SAndroid Build Coastguard Workersc2.join_node(r2, node_type=wpan.JOIN_TYPE_SLEEPY_END_DEVICE)
99*cfb92d14SAndroid Build Coastguard Workersc3.join_node(r3, node_type=wpan.JOIN_TYPE_SLEEPY_END_DEVICE)
100*cfb92d14SAndroid Build Coastguard Worker
101*cfb92d14SAndroid Build Coastguard Workersc1.set(wpan.WPAN_POLL_INTERVAL, '500')
102*cfb92d14SAndroid Build Coastguard Workersc2.set(wpan.WPAN_POLL_INTERVAL, '500')
103*cfb92d14SAndroid Build Coastguard Workersc3.set(wpan.WPAN_POLL_INTERVAL, '500')
104*cfb92d14SAndroid Build Coastguard Worker
105*cfb92d14SAndroid Build Coastguard Worker# -----------------------------------------------------------------------------------------------------------------------
106*cfb92d14SAndroid Build Coastguard Worker# Test implementation
107*cfb92d14SAndroid Build Coastguard Worker
108*cfb92d14SAndroid Build Coastguard Worker# The channel manager delay is set from "openthread-core-toranj-config.h".
109*cfb92d14SAndroid Build Coastguard Worker# Verify that it is 2 seconds.
110*cfb92d14SAndroid Build Coastguard Worker
111*cfb92d14SAndroid Build Coastguard Workerverify(int(r1.get(wpan.WPAN_CHANNEL_MANAGER_DELAY), 0) == 2)
112*cfb92d14SAndroid Build Coastguard Worker
113*cfb92d14SAndroid Build Coastguard Workerverify_channel(all_nodes, 12)
114*cfb92d14SAndroid Build Coastguard Worker
115*cfb92d14SAndroid Build Coastguard Worker# Request a channel change to channel 13 from router r1
116*cfb92d14SAndroid Build Coastguard Worker
117*cfb92d14SAndroid Build Coastguard Workerr1.set(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL, '13')
118*cfb92d14SAndroid Build Coastguard Workerverify(int(r1.get(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL), 0) == 13)
119*cfb92d14SAndroid Build Coastguard Workerverify_channel(all_nodes, 13)
120*cfb92d14SAndroid Build Coastguard Worker
121*cfb92d14SAndroid Build Coastguard Worker# Request same channel change on multiple routers at the same time
122*cfb92d14SAndroid Build Coastguard Worker
123*cfb92d14SAndroid Build Coastguard Workerr1.set(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL, '14')
124*cfb92d14SAndroid Build Coastguard Workerr2.set(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL, '14')
125*cfb92d14SAndroid Build Coastguard Workerr3.set(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL, '14')
126*cfb92d14SAndroid Build Coastguard Workerverify_channel(all_nodes, 14)
127*cfb92d14SAndroid Build Coastguard Worker
128*cfb92d14SAndroid Build Coastguard Worker# Request different channel changes from same router (router r1).
129*cfb92d14SAndroid Build Coastguard Worker
130*cfb92d14SAndroid Build Coastguard Workerr1.set(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL, '15')
131*cfb92d14SAndroid Build Coastguard Workerverify_channel(all_nodes, 14)
132*cfb92d14SAndroid Build Coastguard Workerr1.set(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL, '16')
133*cfb92d14SAndroid Build Coastguard Workerverify_channel(all_nodes, 16)
134*cfb92d14SAndroid Build Coastguard Worker
135*cfb92d14SAndroid Build Coastguard Worker# Request different channels from two routers (r1 and r2)
136*cfb92d14SAndroid Build Coastguard Worker
137*cfb92d14SAndroid Build Coastguard Workerr1.set(wpan.WPAN_CHANNEL_MANAGER_DELAY, '20')  # increase the time to ensure r1 change is in process
138*cfb92d14SAndroid Build Coastguard Workerr1.set(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL, '17')
139*cfb92d14SAndroid Build Coastguard Workertime.sleep(10.5 / speedup)
140*cfb92d14SAndroid Build Coastguard Workerverify_channel(all_nodes, 16)
141*cfb92d14SAndroid Build Coastguard Workerr2.set(wpan.WPAN_CHANNEL_MANAGER_NEW_CHANNEL, '18')
142*cfb92d14SAndroid Build Coastguard Workerverify_channel(all_nodes, 18)
143*cfb92d14SAndroid Build Coastguard Worker
144*cfb92d14SAndroid Build Coastguard Worker# -----------------------------------------------------------------------------------------------------------------------
145*cfb92d14SAndroid Build Coastguard Worker# Test finished
146*cfb92d14SAndroid Build Coastguard Worker
147*cfb92d14SAndroid Build Coastguard Workerwpan.Node.finalize_all_nodes()
148*cfb92d14SAndroid Build Coastguard Worker
149*cfb92d14SAndroid Build Coastguard Workerprint('\'{}\' passed.'.format(test_name))
150