1#!/usr/bin/env python3 2# 3# Copyright (c) 2018, The OpenThread Authors. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 3. Neither the name of the copyright holder nor the 14# names of its contributors may be used to endorse or promote products 15# derived from this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27# POSSIBILITY OF SUCH DAMAGE. 28 29import wpan 30from wpan import verify 31 32# ----------------------------------------------------------------------------------------------------------------------- 33# Test description: Router table 34# 35# Verify router table entries on a network with 4 routers: 36# {r1, r2, r3} forming a loop with r4 connecting to r3. 37# 38 39test_name = __file__[:-3] if __file__.endswith('.py') else __file__ 40print('-' * 120) 41print('Starting \'{}\''.format(test_name)) 42 43# ----------------------------------------------------------------------------------------------------------------------- 44# Creating `wpan.Nodes` instances 45 46speedup = 4 47wpan.Node.set_time_speedup_factor(speedup) 48 49r1 = wpan.Node() 50r2 = wpan.Node() 51r3 = wpan.Node() 52r4 = wpan.Node() 53c4 = wpan.Node() 54 55# ----------------------------------------------------------------------------------------------------------------------- 56# Init all nodes 57 58wpan.Node.init_all_nodes() 59 60# ----------------------------------------------------------------------------------------------------------------------- 61# Build network topology 62# 63# 64# r1 ------ r2 65# \ / 66# \ / 67# \ / 68# r3 _____ r4 69# 70# 71 72r1.form("route-table") 73 74r1.allowlist_node(r2) 75r2.allowlist_node(r1) 76r2.join_node(r1, wpan.JOIN_TYPE_ROUTER) 77 78r2.allowlist_node(r3) 79r3.allowlist_node(r2) 80r3.join_node(r2, wpan.JOIN_TYPE_ROUTER) 81 82r3.allowlist_node(r1) 83r1.allowlist_node(r3) 84 85r3.allowlist_node(r4) 86r4.allowlist_node(r3) 87r4.join_node(r3, wpan.JOIN_TYPE_ROUTER) 88 89# c4 is attached to r4 so that it quickly gets promoted to a router role. 90c4.allowlist_node(r4) 91r4.allowlist_node(c4) 92c4.join_node(r4, wpan.JOIN_TYPE_SLEEPY_END_DEVICE) 93c4.set(wpan.WPAN_POLL_INTERVAL, '2000') 94 95# ----------------------------------------------------------------------------------------------------------------------- 96# Test implementation 97# 98 99verify(r1.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_LEADER) 100verify(r2.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_ROUTER) 101verify(r3.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_ROUTER) 102verify(r4.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_ROUTER) 103 104r1_id = int(r1.get(wpan.WPAN_THREAD_ROUTER_ID), 0) 105r2_id = int(r2.get(wpan.WPAN_THREAD_ROUTER_ID), 0) 106r3_id = int(r3.get(wpan.WPAN_THREAD_ROUTER_ID), 0) 107r4_id = int(r4.get(wpan.WPAN_THREAD_ROUTER_ID), 0) 108 109r1_ext_addr = r1.get(wpan.WPAN_EXT_ADDRESS)[1:-1] 110r2_ext_addr = r2.get(wpan.WPAN_EXT_ADDRESS)[1:-1] 111r3_ext_addr = r3.get(wpan.WPAN_EXT_ADDRESS)[1:-1] 112r4_ext_addr = r4.get(wpan.WPAN_EXT_ADDRESS)[1:-1] 113 114r1_rloc = int(r1.get(wpan.WPAN_THREAD_RLOC16), 16) 115r2_rloc = int(r2.get(wpan.WPAN_THREAD_RLOC16), 16) 116r3_rloc = int(r3.get(wpan.WPAN_THREAD_RLOC16), 16) 117r4_rloc = int(r4.get(wpan.WPAN_THREAD_RLOC16), 16) 118 119WAIT_TIME = 30 / speedup + 5 120 121INVALID_ROUTER_ID = 63 122 123 124def check_r1_router_table(): 125 router_table = wpan.parse_router_table_result(r1.get(wpan.WPAN_THREAD_ROUTER_TABLE)) 126 verify(len(router_table) == 4) 127 for entry in router_table: 128 if entry.rloc16 == r1_rloc: 129 pass 130 elif entry.rloc16 == r2_rloc: 131 # r1 should be directly connected to r2. 132 verify(entry.is_link_established()) 133 verify(entry.ext_address == r2_ext_addr) 134 elif entry.rloc16 == r3_rloc: 135 # r1 should be directly connected to r3. 136 verify(entry.is_link_established()) 137 verify(entry.ext_address == r3_ext_addr) 138 elif entry.rloc16 == r4_rloc: 139 # r1's next hop towards r4 should be through r3. 140 verify(not entry.is_link_established()) 141 verify(entry.next_hop == r3_id) 142 else: 143 raise (wpan.VerifyError("unknown entry in the router table of r1")) 144 145 146wpan.verify_within(check_r1_router_table, WAIT_TIME) 147 148 149def check_r3_router_table(): 150 router_table = wpan.parse_router_table_result(r3.get(wpan.WPAN_THREAD_ROUTER_TABLE)) 151 verify(len(router_table) == 4) 152 for entry in router_table: 153 if entry.rloc16 == r1_rloc: 154 # r3 should be directly connected to r1. 155 verify(entry.is_link_established()) 156 verify(entry.ext_address == r1_ext_addr) 157 elif entry.rloc16 == r2_rloc: 158 # r3 should be directly connected to r2. 159 verify(entry.is_link_established()) 160 verify(entry.ext_address == r2_ext_addr) 161 elif entry.rloc16 == r3_rloc: 162 pass 163 elif entry.rloc16 == r4_rloc: 164 # r3 should be directly connected to r4. 165 verify(entry.is_link_established()) 166 verify(entry.ext_address == r4_ext_addr) 167 else: 168 raise (wpan.VerifyError("unknown entry in the router table of r3")) 169 170 171wpan.verify_within(check_r3_router_table, WAIT_TIME) 172 173 174def check_r4_router_table(): 175 router_table = wpan.parse_router_table_result(r4.get(wpan.WPAN_THREAD_ROUTER_TABLE)) 176 verify(len(router_table) == 4) 177 for entry in router_table: 178 if entry.rloc16 == r1_rloc: 179 # r4's next hop towards r1 should be through r3. 180 verify(not entry.is_link_established()) 181 verify(entry.next_hop == r3_id) 182 elif entry.rloc16 == r2_rloc: 183 # r4's next hop towards r2 should be through r3. 184 verify(not entry.is_link_established()) 185 verify(entry.next_hop == r3_id) 186 elif entry.rloc16 == r3_rloc: 187 # r4 should be directly connected to r3. 188 verify(entry.is_link_established()) 189 verify(entry.ext_address == r3_ext_addr) 190 elif entry.rloc16 == r4_rloc: 191 pass 192 else: 193 raise (wpan.VerifyError("unknown entry in the router table of r4")) 194 195 196wpan.verify_within(check_r4_router_table, WAIT_TIME) 197 198# ----------------------------------------------------------------------------------------------------------------------- 199# Test finished 200 201wpan.Node.finalize_all_nodes() 202 203print('\'{}\' passed.'.format(test_name)) 204