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: Neighbor table 34# 35# - Network with NUM_ROUTERS(= 2) routers, all within range of each other. 36# - The first router has NUM_CHILDREN(= 1) sleepy children attached to it. 37# - The test verifies that all children and routers are observed in the "Thread:NeighborTable" of the first router. 38# 39 40test_name = __file__[:-3] if __file__.endswith('.py') else __file__ 41print('-' * 120) 42print('Starting \'{}\''.format(test_name)) 43 44# ----------------------------------------------------------------------------------------------------------------------- 45# Creating `wpan.Nodes` instances 46 47speedup = 4 48wpan.Node.set_time_speedup_factor(speedup) 49 50NUM_ROUTERS = 2 51NUM_CHILDREN = 1 52 53routers = [] 54for num in range(NUM_ROUTERS): 55 routers.append(wpan.Node()) 56 57children = [] 58for num in range(NUM_CHILDREN): 59 children.append(wpan.Node()) 60 61# end-device per router used for quick promotion to router role 62ed = [0] 63for num in range(1, NUM_ROUTERS): 64 ed.append(wpan.Node()) 65 66all_nodes = routers + children + ed 67 68# ----------------------------------------------------------------------------------------------------------------------- 69# Init all nodes 70 71wpan.Node.init_all_nodes() 72 73# ----------------------------------------------------------------------------------------------------------------------- 74# Build network topology 75# 76 77# allowlist all routers with one another 78for i in range(NUM_ROUTERS): 79 for j in range(NUM_ROUTERS): 80 if i != j: 81 routers[i].allowlist_node(routers[j]) 82 83# All children should attach to routers[0] 84for num in range(NUM_CHILDREN): 85 children[num].allowlist_node(routers[0]) 86 routers[0].allowlist_node(children[num]) 87 88# allowlist the end-device ed with its corresponding router 89for num in range(1, NUM_ROUTERS): 90 ed[num].allowlist_node(routers[num]) 91 routers[num].allowlist_node(ed[num]) 92 93routers[0].form("neigh-table") 94 95for router in routers[1:]: 96 router.join_node(routers[0], wpan.JOIN_TYPE_ROUTER) 97 98for num in range(1, NUM_ROUTERS): 99 ed[num].join_node(routers[num], wpan.JOIN_TYPE_END_DEVICE) 100 101for num in range(NUM_CHILDREN): 102 children[num].join_node(routers[0], wpan.JOIN_TYPE_SLEEPY_END_DEVICE) 103 children[num].set(wpan.WPAN_POLL_INTERVAL, '300') 104 105# ----------------------------------------------------------------------------------------------------------------------- 106# Test implementation 107 108for router in routers[1:]: 109 verify(router.get(wpan.WPAN_NODE_TYPE) == wpan.NODE_TYPE_ROUTER) 110 111# Get and parse the neighbor table on routers[0]. 112neighbor_table = wpan.parse_neighbor_table_result(routers[0].get(wpan.WPAN_THREAD_NEIGHBOR_TABLE)) 113 114verify(len(neighbor_table) == NUM_ROUTERS - 1 + NUM_CHILDREN) 115 116# Verify that all children are seen in the neighbor table 117for child in children: 118 ext_addr = child.get(wpan.WPAN_EXT_ADDRESS)[1:-1] 119 for entry in neighbor_table: 120 if entry.ext_address == ext_addr: 121 break 122 else: 123 raise wpan.VerifyError('Failed to find a child entry for extended address {} in table'.format(ext_addr)) 124 125 verify(int(entry.rloc16, 16) == int(child.get(wpan.WPAN_THREAD_RLOC16), 16)) 126 verify(entry.is_rx_on_when_idle() is False) 127 verify(entry.is_ftd() is False) 128 verify(entry.is_child()) 129 130# Verify that all other routers are seen in the neighbor table 131for router in routers[1:]: 132 ext_addr = router.get(wpan.WPAN_EXT_ADDRESS)[1:-1] 133 for entry in neighbor_table: 134 if entry.ext_address == ext_addr: 135 break 136 else: 137 raise wpan.VerifyError('Failed to find a router entry for extended address {} in table'.format(ext_addr)) 138 139 verify(int(entry.rloc16, 16) == int(router.get(wpan.WPAN_THREAD_RLOC16), 16)) 140 verify(entry.is_rx_on_when_idle()) 141 verify(entry.is_ftd()) 142 verify(entry.is_child() is False) 143 144# ----------------------------------------------------------------------------------------------------------------------- 145# Test finished 146 147wpan.Node.finalize_all_nodes() 148 149print('\'{}\' passed.'.format(test_name)) 150