xref: /aosp_15_r20/external/openthread/tests/toranj/ncp/test-012-multi-hop-traffic.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 wpan
30*cfb92d14SAndroid Build Coastguard Workerfrom wpan import verify
31*cfb92d14SAndroid Build Coastguard Worker
32*cfb92d14SAndroid Build Coastguard Worker# -----------------------------------------------------------------------------------------------------------------------
33*cfb92d14SAndroid Build Coastguard Worker# Test description:
34*cfb92d14SAndroid Build Coastguard Worker#
35*cfb92d14SAndroid Build Coastguard Worker# Traffic over multi-hop in a network with chain topology
36*cfb92d14SAndroid Build Coastguard Worker#
37*cfb92d14SAndroid Build Coastguard Worker#       r1 ----- r2 ---- r3 ----- r4
38*cfb92d14SAndroid Build Coastguard Worker#       /\       |       |        /\
39*cfb92d14SAndroid Build Coastguard Worker#      /  \      |       |       /  \
40*cfb92d14SAndroid Build Coastguard Worker#    fed1 sed1  sed2    sed3   sed4 fed4
41*cfb92d14SAndroid Build Coastguard Worker#
42*cfb92d14SAndroid Build Coastguard Worker#
43*cfb92d14SAndroid Build Coastguard Worker# Traffic flow:
44*cfb92d14SAndroid Build Coastguard Worker#  - From first router to last router
45*cfb92d14SAndroid Build Coastguard Worker#  - From SED child of last router to SED child of first router
46*cfb92d14SAndroid Build Coastguard Worker#  - From FED child of first router to FED child of last router
47*cfb92d14SAndroid Build Coastguard Worker#
48*cfb92d14SAndroid Build Coastguard Worker# The test verifies the following:
49*cfb92d14SAndroid Build Coastguard Worker# - Verifies Address Query process to routers and FEDs.
50*cfb92d14SAndroid Build Coastguard Worker# - Verifies Mesh Header frame forwarding over multiple routers.
51*cfb92d14SAndroid Build Coastguard Worker# - Verifies forwarding of large IPv6 messages (1000 bytes) requiring lowpan fragmentation.
52*cfb92d14SAndroid Build Coastguard Worker
53*cfb92d14SAndroid Build Coastguard Workertest_name = __file__[:-3] if __file__.endswith('.py') else __file__
54*cfb92d14SAndroid Build Coastguard Workerprint('-' * 120)
55*cfb92d14SAndroid Build Coastguard Workerprint('Starting \'{}\''.format(test_name))
56*cfb92d14SAndroid Build Coastguard Worker
57*cfb92d14SAndroid Build Coastguard Worker# -----------------------------------------------------------------------------------------------------------------------
58*cfb92d14SAndroid Build Coastguard Worker# Creating `wpan.Nodes` instances
59*cfb92d14SAndroid Build Coastguard Worker
60*cfb92d14SAndroid Build Coastguard Workerspeedup = 4
61*cfb92d14SAndroid Build Coastguard Workerwpan.Node.set_time_speedup_factor(speedup)
62*cfb92d14SAndroid Build Coastguard Worker
63*cfb92d14SAndroid Build Coastguard WorkerNUM_ROUTERS = 4
64*cfb92d14SAndroid Build Coastguard Worker
65*cfb92d14SAndroid Build Coastguard Workerrouters = []
66*cfb92d14SAndroid Build Coastguard Workersed_children = []
67*cfb92d14SAndroid Build Coastguard Workerfed_children = []
68*cfb92d14SAndroid Build Coastguard Worker
69*cfb92d14SAndroid Build Coastguard Workerfor index in range(NUM_ROUTERS):
70*cfb92d14SAndroid Build Coastguard Worker    routers.append(wpan.Node())
71*cfb92d14SAndroid Build Coastguard Worker    sed_children.append(wpan.Node())
72*cfb92d14SAndroid Build Coastguard Worker
73*cfb92d14SAndroid Build Coastguard Workerfed_children.append(wpan.Node())
74*cfb92d14SAndroid Build Coastguard Workerfed_children.append(wpan.Node())
75*cfb92d14SAndroid Build Coastguard Worker
76*cfb92d14SAndroid Build Coastguard Workerall_nodes = routers + sed_children + fed_children
77*cfb92d14SAndroid Build Coastguard Worker
78*cfb92d14SAndroid Build Coastguard Worker# -----------------------------------------------------------------------------------------------------------------------
79*cfb92d14SAndroid Build Coastguard Worker# Init all nodes
80*cfb92d14SAndroid Build Coastguard Worker
81*cfb92d14SAndroid Build Coastguard Workerwpan.Node.init_all_nodes()
82*cfb92d14SAndroid Build Coastguard Worker
83*cfb92d14SAndroid Build Coastguard Worker# -----------------------------------------------------------------------------------------------------------------------
84*cfb92d14SAndroid Build Coastguard Worker# Build network topology
85*cfb92d14SAndroid Build Coastguard Worker#
86*cfb92d14SAndroid Build Coastguard Worker#       r1 ----- r2 ---- r3 ----- r4
87*cfb92d14SAndroid Build Coastguard Worker#       /\       |       |        /\
88*cfb92d14SAndroid Build Coastguard Worker#      /  \      |       |       /  \
89*cfb92d14SAndroid Build Coastguard Worker#    fed1 sed1  sed2    sed3   sed4 fed4
90*cfb92d14SAndroid Build Coastguard Worker
91*cfb92d14SAndroid Build Coastguard Worker# Allowlist routers with their corresponding sleepy children
92*cfb92d14SAndroid Build Coastguard Worker
93*cfb92d14SAndroid Build Coastguard Workerfor index in range(0, NUM_ROUTERS):
94*cfb92d14SAndroid Build Coastguard Worker    routers[index].allowlist_node(sed_children[index])
95*cfb92d14SAndroid Build Coastguard Worker    sed_children[index].allowlist_node(routers[index])
96*cfb92d14SAndroid Build Coastguard Worker
97*cfb92d14SAndroid Build Coastguard Worker# Allowlist a FED child for the first and last routers
98*cfb92d14SAndroid Build Coastguard Worker
99*cfb92d14SAndroid Build Coastguard Workerrouters[0].allowlist_node(fed_children[0])
100*cfb92d14SAndroid Build Coastguard Workerfed_children[0].allowlist_node(routers[0])
101*cfb92d14SAndroid Build Coastguard Worker
102*cfb92d14SAndroid Build Coastguard Workerrouters[-1].allowlist_node(fed_children[-1])
103*cfb92d14SAndroid Build Coastguard Workerfed_children[-1].allowlist_node(routers[-1])
104*cfb92d14SAndroid Build Coastguard Worker
105*cfb92d14SAndroid Build Coastguard Worker# While list routers at [index-1] and [index]
106*cfb92d14SAndroid Build Coastguard Worker
107*cfb92d14SAndroid Build Coastguard Workerfor index in range(1, NUM_ROUTERS):
108*cfb92d14SAndroid Build Coastguard Worker    routers[index - 1].allowlist_node(routers[index])
109*cfb92d14SAndroid Build Coastguard Worker    routers[index].allowlist_node(routers[index - 1])
110*cfb92d14SAndroid Build Coastguard Worker
111*cfb92d14SAndroid Build Coastguard Workerrouters[0].form("multi-hop")
112*cfb92d14SAndroid Build Coastguard Workersed_children[0].join_node(routers[0], wpan.JOIN_TYPE_SLEEPY_END_DEVICE)
113*cfb92d14SAndroid Build Coastguard Workersed_children[0].set(wpan.WPAN_POLL_INTERVAL, '500')
114*cfb92d14SAndroid Build Coastguard Worker
115*cfb92d14SAndroid Build Coastguard Workerfor index in range(1, NUM_ROUTERS):
116*cfb92d14SAndroid Build Coastguard Worker    routers[index].join_node(routers[index - 1], wpan.JOIN_TYPE_ROUTER)
117*cfb92d14SAndroid Build Coastguard Worker    sed_children[index].join_node(routers[index], wpan.JOIN_TYPE_SLEEPY_END_DEVICE)
118*cfb92d14SAndroid Build Coastguard Worker    sed_children[index].set(wpan.WPAN_POLL_INTERVAL, '500')
119*cfb92d14SAndroid Build Coastguard Worker
120*cfb92d14SAndroid Build Coastguard Workerfed_children[0].join_node(routers[0], wpan.JOIN_TYPE_END_DEVICE)
121*cfb92d14SAndroid Build Coastguard Workerfed_children[-1].join_node(routers[-1], wpan.JOIN_TYPE_END_DEVICE)
122*cfb92d14SAndroid Build Coastguard Worker
123*cfb92d14SAndroid Build Coastguard Worker# -----------------------------------------------------------------------------------------------------------------------
124*cfb92d14SAndroid Build Coastguard Worker# Test implementation
125*cfb92d14SAndroid Build Coastguard Worker
126*cfb92d14SAndroid Build Coastguard WorkerNUM_MSGS = 3
127*cfb92d14SAndroid Build Coastguard WorkerMSG_LENS = [40, 100, 400, 800, 1000]
128*cfb92d14SAndroid Build Coastguard Worker
129*cfb92d14SAndroid Build Coastguard Worker# Wait till first router has either established a link or
130*cfb92d14SAndroid Build Coastguard Worker# has a valid "next hop" towards all other routers.
131*cfb92d14SAndroid Build Coastguard Worker
132*cfb92d14SAndroid Build Coastguard WorkerROUTER_TABLE_WAIT_TIME = 60 / speedup + 5
133*cfb92d14SAndroid Build Coastguard WorkerINVALID_ROUTER_ID = 63
134*cfb92d14SAndroid Build Coastguard Worker
135*cfb92d14SAndroid Build Coastguard Workerr1_rloc = int(routers[0].get(wpan.WPAN_THREAD_RLOC16), 16)
136*cfb92d14SAndroid Build Coastguard Worker
137*cfb92d14SAndroid Build Coastguard Worker
138*cfb92d14SAndroid Build Coastguard Workerdef check_r1_router_table():
139*cfb92d14SAndroid Build Coastguard Worker    router_table = wpan.parse_router_table_result(routers[0].get(wpan.WPAN_THREAD_ROUTER_TABLE))
140*cfb92d14SAndroid Build Coastguard Worker    verify(len(router_table) == NUM_ROUTERS)
141*cfb92d14SAndroid Build Coastguard Worker    for entry in router_table:
142*cfb92d14SAndroid Build Coastguard Worker        verify(entry.rloc16 == r1_rloc or entry.is_link_established() or entry.next_hop != INVALID_ROUTER_ID)
143*cfb92d14SAndroid Build Coastguard Worker
144*cfb92d14SAndroid Build Coastguard Worker
145*cfb92d14SAndroid Build Coastguard Workerwpan.verify_within(check_r1_router_table, ROUTER_TABLE_WAIT_TIME)
146*cfb92d14SAndroid Build Coastguard Worker
147*cfb92d14SAndroid Build Coastguard Worker# Send from the first router in the chain to the last one.
148*cfb92d14SAndroid Build Coastguard Worker
149*cfb92d14SAndroid Build Coastguard Workersrc = routers[0].get(wpan.WPAN_IP6_MESH_LOCAL_ADDRESS)[1:-1]
150*cfb92d14SAndroid Build Coastguard Workerdst = routers[-1].get(wpan.WPAN_IP6_MESH_LOCAL_ADDRESS)[1:-1]
151*cfb92d14SAndroid Build Coastguard Worker
152*cfb92d14SAndroid Build Coastguard Workerfor msg_length in MSG_LENS:
153*cfb92d14SAndroid Build Coastguard Worker    sender = routers[0].prepare_tx(src, dst, msg_length, NUM_MSGS)
154*cfb92d14SAndroid Build Coastguard Worker    recver = routers[-1].prepare_rx(sender)
155*cfb92d14SAndroid Build Coastguard Worker    wpan.Node.perform_async_tx_rx()
156*cfb92d14SAndroid Build Coastguard Worker    verify(sender.was_successful)
157*cfb92d14SAndroid Build Coastguard Worker    verify(recver.was_successful)
158*cfb92d14SAndroid Build Coastguard Worker
159*cfb92d14SAndroid Build Coastguard Worker# Send from the SED child of the last router to the SED child of the first
160*cfb92d14SAndroid Build Coastguard Worker# router.
161*cfb92d14SAndroid Build Coastguard Worker
162*cfb92d14SAndroid Build Coastguard Workersrc = sed_children[-1].get(wpan.WPAN_IP6_MESH_LOCAL_ADDRESS)[1:-1]
163*cfb92d14SAndroid Build Coastguard Workerdst = sed_children[0].get(wpan.WPAN_IP6_MESH_LOCAL_ADDRESS)[1:-1]
164*cfb92d14SAndroid Build Coastguard Worker
165*cfb92d14SAndroid Build Coastguard Workerfor msg_length in MSG_LENS:
166*cfb92d14SAndroid Build Coastguard Worker    sender = sed_children[-1].prepare_tx(src, dst, msg_length, NUM_MSGS)
167*cfb92d14SAndroid Build Coastguard Worker    recver = sed_children[0].prepare_rx(sender)
168*cfb92d14SAndroid Build Coastguard Worker    wpan.Node.perform_async_tx_rx()
169*cfb92d14SAndroid Build Coastguard Worker    verify(sender.was_successful)
170*cfb92d14SAndroid Build Coastguard Worker    verify(recver.was_successful)
171*cfb92d14SAndroid Build Coastguard Worker
172*cfb92d14SAndroid Build Coastguard Worker# Send from the FED child of the first router to the FED child of the last
173*cfb92d14SAndroid Build Coastguard Worker# router.
174*cfb92d14SAndroid Build Coastguard Worker
175*cfb92d14SAndroid Build Coastguard Workersrc = fed_children[0].get(wpan.WPAN_IP6_MESH_LOCAL_ADDRESS)[1:-1]
176*cfb92d14SAndroid Build Coastguard Workerdst = fed_children[-1].get(wpan.WPAN_IP6_MESH_LOCAL_ADDRESS)[1:-1]
177*cfb92d14SAndroid Build Coastguard Worker
178*cfb92d14SAndroid Build Coastguard Workerfor msg_length in MSG_LENS:
179*cfb92d14SAndroid Build Coastguard Worker    sender = fed_children[0].prepare_tx(src, dst, msg_length, NUM_MSGS)
180*cfb92d14SAndroid Build Coastguard Worker    recver = fed_children[-1].prepare_rx(sender)
181*cfb92d14SAndroid Build Coastguard Worker    wpan.Node.perform_async_tx_rx()
182*cfb92d14SAndroid Build Coastguard Worker    verify(sender.was_successful)
183*cfb92d14SAndroid Build Coastguard Worker    verify(recver.was_successful)
184*cfb92d14SAndroid Build Coastguard Worker
185*cfb92d14SAndroid Build Coastguard Worker# -----------------------------------------------------------------------------------------------------------------------
186*cfb92d14SAndroid Build Coastguard Worker# Test finished
187*cfb92d14SAndroid Build Coastguard Worker
188*cfb92d14SAndroid Build Coastguard Workerwpan.Node.finalize_all_nodes()
189*cfb92d14SAndroid Build Coastguard Worker
190*cfb92d14SAndroid Build Coastguard Workerprint('\'{}\' passed.'.format(test_name))
191