1#!/usr/bin/env python3 2# 3# Copyright (c) 2022, 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 29from cli import verify 30from cli import verify_within 31import cli 32import time 33 34# ----------------------------------------------------------------------------------------------------------------------- 35# Test description: This test covers behavior of device after trel network is temporarily disabled 36# and rediscovery of trel radio using probe mechanism. 37# 38# r1 ---------- r2 39# (15.4+trel) (15.4+trel) 40# 41# On r2 we disable trel temporarily. 42# 43 44test_name = __file__[:-3] if __file__.endswith('.py') else __file__ 45print('-' * 120) 46print('Starting \'{}\''.format(test_name)) 47 48# ----------------------------------------------------------------------------------------------------------------------- 49# Creating `cli.Node` instances 50 51speedup = 10 52cli.Node.set_time_speedup_factor(speedup) 53 54r1 = cli.Node(cli.RADIO_15_4_TREL) 55r2 = cli.Node(cli.RADIO_15_4_TREL) 56 57# ----------------------------------------------------------------------------------------------------------------------- 58# Build network topology 59 60r1.form("prove-discover") 61r2.join(r1) 62 63verify(r1.get_state() == 'leader') 64verify(r2.get_state() == 'router') 65 66# ----------------------------------------------------------------------------------------------------------------------- 67# Test Implementation 68 69high_preference_threshold = 220 70min_preference_threshold = 0 71 72verify(r1.multiradio_get_radios() == '[15.4, TREL]') 73verify(r2.multiradio_get_radios() == '[15.4, TREL]') 74 75r1_rloc = int(r1.get_rloc16(), 16) 76r2_rloc = int(r2.get_rloc16(), 16) 77 78r1_ml_addr = r1.get_mleid_ip_addr() 79r2_ml_addr = r2.get_mleid_ip_addr() 80 81# Wait till routes are discovered. 82 83 84def check_r1_router_table(): 85 table = r1.get_router_table() 86 verify(len(table) == 2) 87 for entry in table: 88 verify(int(entry['RLOC16'], 0) == r1_rloc or int(entry['Link']) == 1) 89 90 91verify_within(check_r1_router_table, 120) 92 93# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 94# Verify that r1 detected both TREL & 15.4 as supported radios by r2 95 96 97def check_r1_sees_r2_has_two_radio_links(): 98 neighbor_radios = r1.multiradio_get_neighbor_list() 99 verify(len(neighbor_radios) == 1) 100 info = cli.Node.parse_multiradio_neighbor_entry(neighbor_radios[0]) 101 verify(int(info['RLOC16'], 16) == r2_rloc) 102 radios = info['Radios'] 103 verify(len(radios) == 2) 104 verify('15.4' in radios) 105 verify('TREL' in radios) 106 107 108cli.verify_within(check_r1_sees_r2_has_two_radio_links, 10) 109 110# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 111# Ping r2 from r1 and verify that r1 prefers trel radio link for 112# sending to r2. 113 114r1.ping(r2_ml_addr, count=5) 115 116neighbor_radios = r1.multiradio_get_neighbor_list() 117verify(len(neighbor_radios) == 1) 118info = cli.Node.parse_multiradio_neighbor_entry(neighbor_radios[0]) 119radios = info['Radios'] 120verify(radios['TREL'] >= high_preference_threshold) 121 122# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 123# Now temporary filter trel link on r2 and ping again. We expect that 124# r1 to quickly detect that trel is no longer supported by r2 and 125# prefer 15.4 for tx to r2. 126 127r2.cli('trel filter enable') 128verify(r2.cli('trel filter')[0] == 'Enabled') 129 130r1.udp_open() 131for count in range(5): 132 r1.udp_send(r2_ml_addr, 12345, 'hi_r2_from_r1') 133 134 135def check_r1_does_not_prefer_trel_for_r2(): 136 neighbor_radios = r1.multiradio_get_neighbor_list() 137 verify(len(neighbor_radios) == 1) 138 info = cli.Node.parse_multiradio_neighbor_entry(neighbor_radios[0]) 139 radios = info['Radios'] 140 verify(radios['TREL'] <= min_preference_threshold) 141 142 143verify_within(check_r1_does_not_prefer_trel_for_r2, 10) 144 145# Check that we can send between r1 and r2 (now all tx should use 15.4) 146 147r1.ping(r2_ml_addr, count=5, verify_success=False) 148r1.ping(r2_ml_addr, count=5) 149 150neighbor_radios = r1.multiradio_get_neighbor_list() 151verify(len(neighbor_radios) == 1) 152info = cli.Node.parse_multiradio_neighbor_entry(neighbor_radios[0]) 153radios = info['Radios'] 154verify(radios['TREL'] <= min_preference_threshold) 155verify(radios['15.4'] >= high_preference_threshold) 156 157# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 158# Enable trel back on r2, start sending traffic from r1 to r2 159# The probe mechanism should kick and detect that r2 has trel again. 160 161r2.cli('trel filter disable') 162verify(r2.cli('trel filter')[0] == 'Disabled') 163 164r2.udp_open() 165for count in range(80): 166 r2.udp_send(r1_ml_addr, 12345, 'hi_r1_from_r2') 167 168 169def check_r1_again_prefers_trel_for_r2(): 170 neighbor_radios = r1.multiradio_get_neighbor_list() 171 verify(len(neighbor_radios) == 1) 172 info = cli.Node.parse_multiradio_neighbor_entry(neighbor_radios[0]) 173 radios = info['Radios'] 174 verify(radios['TREL'] >= high_preference_threshold) 175 176 177verify_within(check_r1_again_prefers_trel_for_r2, 10) 178 179# ----------------------------------------------------------------------------------------------------------------------- 180# Test finished 181 182cli.Node.finalize_all_nodes() 183 184print('\'{}\' passed.'.format(test_name)) 185