1#!/usr/bin/env python3 2# 3# Copyright (c) 2024, 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 validates the mechanism to discover and update the TREL peer info when processing 36# a received TREL packet from a peer (when peer IPv6 address or port number gets changes). 37# 38 39test_name = __file__[:-3] if __file__.endswith('.py') else __file__ 40print('-' * 120) 41print('Starting \'{}\''.format(test_name)) 42 43# ----------------------------------------------------------------------------------------------------------------------- 44# Creating `cli.Node` instances 45 46speedup = 10 47cli.Node.set_time_speedup_factor(speedup) 48 49r1 = cli.Node(cli.RADIO_15_4_TREL) 50r2 = cli.Node(cli.RADIO_15_4_TREL) 51c1 = cli.Node(cli.RADIO_15_4_TREL) 52 53# ----------------------------------------------------------------------------------------------------------------------- 54# Build network topology 55 56r1.form("trel-peer-disc") 57c1.join(r1, cli.JOIN_TYPE_REED) 58r2.join(r1) 59 60verify(r1.get_state() == 'leader') 61verify(r2.get_state() == 'router') 62verify(c1.get_state() == 'child') 63 64verify(r1.multiradio_get_radios() == '[15.4, TREL]') 65verify(r2.multiradio_get_radios() == '[15.4, TREL]') 66verify(c1.multiradio_get_radios() == '[15.4, TREL]') 67 68# ----------------------------------------------------------------------------------------------------------------------- 69# Test Implementation 70 71 72def check_trel_peers(node, peer_nodes): 73 # Validate that `node` has discovered `peer_nodes` as its TREL peers 74 # and validate that the correct TREL socket address is discovered 75 # and used for each. 76 peers = node.trel_get_peers() 77 verify(len(peers) == len(peer_nodes)) 78 peers_ext_addrs = [nd.get_ext_addr() for nd in peer_nodes] 79 for peer in peers: 80 for peer_node in peer_nodes: 81 if peer['Ext MAC Address'] == peer_node.get_ext_addr(): 82 verify(peer_node.trel_test_get_sock_addr() == peer['IPv6 Socket Address']) 83 break 84 else: 85 verify(False) # Did not find peer in `peer_nodes` 86 87 88# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 89# Check that all nodes see each other as TREL peers with the correct 90# TREL socket address. 91 92check_trel_peers(r1, [r2, c1]) 93check_trel_peers(r2, [r1, c1]) 94check_trel_peers(c1, [r1, r2]) 95 96verify(int(r1.trel_test_get_notify_addr_counter()) == 0) 97verify(int(r2.trel_test_get_notify_addr_counter()) == 0) 98verify(int(c1.trel_test_get_notify_addr_counter()) == 0) 99 100# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 101# Use test CLI command to force `r2` to change its TREL socket 102# address (IPv6 address only). 103 104time.sleep(10 / speedup) 105 106old_sock_addr = r2.trel_test_get_sock_addr() 107r2.trel_test_change_sock_addr() 108verify(r2.trel_test_get_sock_addr() != old_sock_addr) 109 110# Wait for longer than the Link Advertisement interval for `r2` to 111# send an advertisement. Other nodes that receive and process this 112# adv should then update the socket address of `r2` in their TREL 113# peer table. 114 115time.sleep(35 / speedup) 116 117check_trel_peers(r1, [r2, c1]) 118check_trel_peers(r2, [r1, c1]) 119check_trel_peers(c1, [r1, r2]) 120 121# Validate that the platform is notified of the socket address 122# discrepancy on `r1` and `c1`. 123 124verify(int(r1.trel_test_get_notify_addr_counter()) == 1) 125verify(int(r2.trel_test_get_notify_addr_counter()) == 0) 126verify(int(c1.trel_test_get_notify_addr_counter()) == 1) 127 128# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 129# Use test CLI command to force `r2` to change its TREL socket 130# address port. 131 132time.sleep(10 / speedup) 133 134old_sock_addr = r2.trel_test_get_sock_addr() 135r2.trel_test_change_sock_port() 136verify(r2.trel_test_get_sock_addr() != old_sock_addr) 137 138# Wait for longer than the Link Advertisement interval for `r2` to 139# send an advertisement. Other nodes that receive and process this 140# adv should then update the socket address of `r2` in their TREL 141# peer table. 142 143time.sleep(35 / speedup) 144 145check_trel_peers(r1, [r2, c1]) 146check_trel_peers(r2, [r1, c1]) 147check_trel_peers(c1, [r1, r2]) 148 149# Validate that the platform is notified of the socket address 150# discrepancy on `r1` and `c1`. 151 152verify(int(r1.trel_test_get_notify_addr_counter()) == 2) 153verify(int(r2.trel_test_get_notify_addr_counter()) == 0) 154verify(int(c1.trel_test_get_notify_addr_counter()) == 2) 155 156# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 157# Use test CLI command to force `c1` to change its TREL socket 158# address (IPv6 address only). 159 160old_sock_addr = c1.trel_test_get_sock_addr() 161c1.trel_test_change_sock_addr() 162verify(c1.trel_test_get_sock_addr() != old_sock_addr) 163 164# Send a ping from `c1` to `r1` to trigger communication 165# between `r1` and `c1`. The receipt of a secure data frame 166# from `c1` should update the TREL socket address on `r1` 167 168c1.ping(r1.get_rloc_ip_addr()) 169 170check_trel_peers(r1, [r2, c1]) 171verify(int(r1.trel_test_get_notify_addr_counter()) == 3) 172 173# ----------------------------------------------------------------------------------------------------------------------- 174# Test finished 175 176cli.Node.finalize_all_nodes() 177 178print('\'{}\' passed.'.format(test_name)) 179