1#!/usr/bin/env python3 2# 3# Copyright (c) 2020, 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 ipaddress 30import json 31import logging 32import os 33import subprocess 34import unittest 35 36import otci 37from otci import OTCI 38from otci.errors import CommandError 39from otci import NetifIdentifier 40 41logging.basicConfig(level=logging.DEBUG) 42 43TEST_CHANNEL = 22 44TEST_CHANNEL_MASK = 0x07fff800 45TEST_EXTENDED_PANID = '000db80000000000' 46TEST_MESH_LOCAL_PREFIX = 'fd00:db8::' 47TEST_NETWORK_KEY = 'ffeeddccbbaa99887766554433221100' 48TEST_NETWORK_NAME = 'OT CI' 49TEST_PANID = 0xeeee 50TEST_PSKC = 'c23a76e98f1a6483639b1ac1271e2e27' 51TEST_SECURITY_POLICY = (672, 'onrc') 52 53REAL_DEVICE = int(os.getenv('REAL_DEVICE', '0')) 54 55 56class TestOTCI(unittest.TestCase): 57 58 def testCliRealDevice(self): 59 if not REAL_DEVICE: 60 self.skipTest('not for virtual device') 61 62 if os.getenv('OTBR_SSH'): 63 node = otci.connect_otbr_ssh(os.getenv('OTBR_SSH')) 64 elif os.getenv('OT_CLI_SERIAL'): 65 node = otci.connect_cli_serial(os.getenv('OT_CLI_SERIAL')) 66 else: 67 self.fail("Please set OT_CLI_SERIAL or OTBR_SSH to test the real device.") 68 69 node.factory_reset() 70 71 self._test_otci_single_node(node) 72 73 def testCliSimRealTime(self): 74 if REAL_DEVICE: 75 self.skipTest('not for real device') 76 77 subprocess.check_call('rm -rf tmp/', shell=True) 78 VIRTUAL_TIME = int(os.getenv('VIRTUAL_TIME', "1")) 79 80 import simulator 81 82 if VIRTUAL_TIME: 83 sim = simulator.VirtualTime(use_message_factory=False) 84 else: 85 sim = None 86 87 if os.getenv('OT_CLI'): 88 executable = os.getenv('OT_CLI') 89 connector = otci.connect_cli_sim 90 elif os.getenv('OT_NCP'): 91 executable = os.getenv('OT_NCP') 92 connector = otci.connect_ncp_sim 93 else: 94 self.fail("Please set OT_CLI to test virtual device") 95 96 node1 = connector(executable, 1, simulator=sim) 97 self._test_otci_single_node(node1) 98 99 node1.factory_reset() 100 101 node2 = connector(executable, 2, simulator=sim) 102 node3 = connector(executable, 3, simulator=sim) 103 node4 = connector(executable, 4, simulator=sim) 104 105 self._test_otci_example(node1, node2) 106 107 node1.factory_reset() 108 node2.factory_reset() 109 110 self._test_otci_multi_nodes(node1, node2, node3, node4) 111 112 def _test_otci_single_node(self, leader): 113 logging.info('leader version: %r', leader.version) 114 logging.info('leader thread version: %r', leader.thread_version) 115 logging.info('API version: %r', leader.api_version) 116 logging.info('log level: %r', leader.get_log_level()) 117 118 leader.enable_promiscuous() 119 self.assertTrue(leader.get_promiscuous()) 120 leader.disable_promiscuous() 121 self.assertFalse(leader.get_promiscuous()) 122 try: 123 logging.info("RCP version: %r", leader.get_rcp_version()) 124 except CommandError: 125 pass 126 127 self.assertTrue(leader.get_router_eligible()) 128 leader.disable_router_eligible() 129 self.assertFalse(leader.get_router_eligible()) 130 leader.enable_router_eligible() 131 132 self.assertFalse(leader.get_ifconfig_state()) 133 # ifconfig up 134 leader.ifconfig_up() 135 self.assertTrue(leader.get_ifconfig_state()) 136 137 logging.info('leader eui64 = %r', leader.get_eui64()) 138 logging.info('leader extpanid = %r', leader.get_extpanid()) 139 logging.info('leader networkkey = %r', leader.get_network_key()) 140 141 extaddr = leader.get_extaddr() 142 self.assertEqual(16, len(extaddr)) 143 int(extaddr, 16) 144 new_extaddr = 'aabbccddeeff0011' 145 leader.set_extaddr(new_extaddr) 146 self.assertEqual(new_extaddr, leader.get_extaddr()) 147 148 leader.set_network_name(TEST_NETWORK_NAME) 149 150 leader.set_network_key(TEST_NETWORK_KEY) 151 self.assertEqual(TEST_NETWORK_KEY, leader.get_network_key()) 152 153 leader.set_panid(TEST_PANID) 154 self.assertEqual(TEST_PANID, leader.get_panid()) 155 156 leader.set_channel(TEST_CHANNEL) 157 self.assertEqual(TEST_CHANNEL, leader.get_channel()) 158 159 leader.set_network_name(TEST_NETWORK_NAME) 160 self.assertEqual(TEST_NETWORK_NAME, leader.get_network_name()) 161 162 self.assertEqual('rdn', leader.get_mode()) 163 leader.set_mode('-') 164 self.assertEqual('-', leader.get_mode()) 165 leader.set_mode('rdn') 166 self.assertEqual('rdn', leader.get_mode()) 167 168 logging.info('leader weight: %d', leader.get_leader_weight()) 169 leader.set_leader_weight(72) 170 171 logging.info('domain name: %r', leader.get_domain_name()) 172 leader.set_domain_name("DefaultDomain2") 173 self.assertEqual("DefaultDomain2", leader.get_domain_name()) 174 175 self.assertEqual(leader.get_preferred_partition_id(), 0) 176 leader.set_preferred_partition_id(0xabcddead) 177 self.assertEqual(leader.get_preferred_partition_id(), 0xabcddead) 178 179 _setup_default_network(leader) 180 leader.thread_start() 181 leader.wait(10) 182 self.assertEqual('leader', leader.get_state()) 183 self.assertEqual(0xabcddead, leader.get_leader_data()['partition_id']) 184 logging.info('leader key sequence counter = %d', leader.get_key_sequence_counter()) 185 186 rloc16 = leader.get_rloc16() 187 leader_id = leader.get_router_id() 188 self.assertEqual(rloc16, leader_id << 10) 189 190 self.assertFalse(leader.get_child_list()) 191 self.assertEqual({}, leader.get_child_table()) 192 193 leader.enable_allowlist() 194 leader.add_allowlist(leader.get_extaddr()) 195 leader.remove_allowlist(leader.get_extaddr()) 196 leader.set_allowlist([leader.get_extaddr()]) 197 leader.disable_allowlist() 198 199 self.assertEqual([], leader.backbone_router_get_multicast_listeners()) 200 201 leader.add_ipmaddr('ff04::1') 202 leader.del_ipmaddr('ff04::1') 203 leader.add_ipmaddr('ff04::2') 204 logging.info('leader ipmaddrs: %r', leader.get_ipmaddrs()) 205 self.assertFalse(leader.has_ipmaddr('ff04::1')) 206 self.assertTrue(leader.has_ipmaddr('ff04::2')) 207 self.assertTrue(leader.get_ipaddr_rloc()) 208 self.assertTrue(leader.get_ipaddr_linklocal()) 209 self.assertTrue(leader.get_ipaddr_mleid()) 210 self.assertTrue(leader.get_ipmaddr_llatn()) 211 self.assertTrue(leader.get_ipmaddr_rlatn()) 212 213 leader.add_ipaddr('2001::1') 214 leader.del_ipaddr('2001::1') 215 leader.add_ipaddr('2001::2') 216 logging.info('leader ipaddrs: %r', leader.get_ipaddrs()) 217 self.assertFalse(leader.has_ipaddr('2001::1')) 218 self.assertTrue(leader.has_ipaddr('2001::2')) 219 220 logging.info('leader bbr state: %r', leader.get_backbone_router_state()) 221 bbr_config = leader.get_backbone_router_config() 222 logging.info('leader bbr config: %r', bbr_config) 223 logging.info('leader PBBR: %r', leader.get_primary_backbone_router_info()) 224 225 new_bbr_seqno = (bbr_config['seqno'] + 1) % 256 226 leader.set_backbone_router_config(seqno=new_bbr_seqno, delay=10, timeout=301) 227 self.assertEqual({'seqno': new_bbr_seqno, 'delay': 10, 'timeout': 301}, leader.get_backbone_router_config()) 228 229 leader.enable_backbone_router() 230 leader.wait(3) 231 232 logging.info('leader bbr state: %r', leader.get_backbone_router_state()) 233 logging.info('leader bbr config: %r', leader.get_backbone_router_config()) 234 logging.info('leader PBBR: %r', leader.get_primary_backbone_router_info()) 235 236 leader.wait(10) 237 self.assertEqual(1, len(leader.backbone_router_get_multicast_listeners())) 238 self.assertEqual('ff04::2', leader.backbone_router_get_multicast_listeners()[0][0]) 239 240 logging.info('leader bufferinfo: %r', leader.get_message_buffer_info()) 241 242 logging.info('child ipaddrs: %r', leader.get_child_ipaddrs()) 243 logging.info('child ipmax: %r', leader.get_child_ip_max()) 244 leader.set_child_ip_max(2) 245 self.assertEqual(2, leader.get_child_ip_max()) 246 logging.info('childmax: %r', leader.get_max_children()) 247 248 logging.info('counter names: %r', leader.counter_names) 249 for counter_name in leader.counter_names: 250 logging.info('counter %s: %r', counter_name, leader.get_counter(counter_name)) 251 leader.reset_counter(counter_name) 252 self.assertTrue(all(x == 0 for name, x in leader.get_counter(counter_name).items() if "Time" not in name)) 253 254 logging.info("CSL config: %r", leader.get_csl_config()) 255 leader.config_csl(channel=13, period=16000, timeout=200) 256 logging.info("CSL config: %r", leader.get_csl_config()) 257 258 logging.info("EID-to-RLOC cache: %r", leader.get_eidcache()) 259 260 logging.info("ipmaddr promiscuous: %r", leader.get_ipmaddr_promiscuous()) 261 leader.enable_ipmaddr_promiscuous() 262 self.assertTrue(leader.get_ipmaddr_promiscuous()) 263 leader.disable_ipmaddr_promiscuous() 264 self.assertFalse(leader.get_ipmaddr_promiscuous()) 265 266 logging.info("leader data: %r", leader.get_leader_data()) 267 logging.info("leader neighbor list: %r", leader.get_neighbor_list()) 268 logging.info("leader neighbor table: %r", leader.get_neighbor_table()) 269 logging.info("Leader external routes: %r", leader.get_local_routes()) 270 leader.add_route('2002::/64') 271 leader.register_network_data() 272 logging.info("Leader external routes: %r", leader.get_local_routes()) 273 274 self.assertEqual(1, len(leader.get_router_list())) 275 self.assertEqual(1, len(leader.get_router_table())) 276 logging.info("Leader router table: %r", leader.get_router_table()) 277 self.assertFalse(list(leader.get_router_table().values())[0].is_link_established) 278 279 logging.info('discover: %r', leader.discover()) 280 logging.info('scan: %r', leader.scan()) 281 logging.info('scan energy: %r', leader.scan_energy()) 282 283 leader.add_service(44970, '112233', 'aabbcc') 284 leader.register_network_data() 285 leader.add_service(44971, b'\x11\x22\x33', b'\xaa\xbb\xcc\xdd') 286 287 leader.add_prefix("2001::/64") 288 289 logging.info("network data: %r", leader.get_network_data()) 290 logging.info("network data raw: %r", leader.get_network_data_bytes()) 291 self.assertEqual(leader.get_network_data()['prefixes'], leader.get_prefixes()) 292 self.assertEqual(leader.get_network_data()['routes'], leader.get_routes()) 293 self.assertEqual(leader.get_network_data()['services'], leader.get_services()) 294 295 logging.info("local prefixes: %r", leader.get_local_prefixes()) 296 logging.info("local routes: %r", leader.get_local_routes()) 297 298 logging.info('txpower %r', leader.get_txpower()) 299 leader.set_txpower(-10) 300 self.assertEqual(-10, leader.get_txpower()) 301 302 self.assertTrue(leader.is_singleton()) 303 304 leader.coap_start() 305 leader.coap_set_test_resource_path('test') 306 leader.coap_test_set_resource_content('helloworld') 307 leader.coap_get(leader.get_ipaddr_rloc(), 'test') 308 leader.coap_put(leader.get_ipaddr_rloc(), 'test', 'con', 'xxx') 309 leader.coap_post(leader.get_ipaddr_rloc(), 'test', 'con', 'xxx') 310 leader.coap_delete(leader.get_ipaddr_rloc(), 'test', 'con', 'xxx') 311 leader.wait(1) 312 leader.coap_stop() 313 314 for netif in (NetifIdentifier.THERAD, NetifIdentifier.UNSPECIFIED, NetifIdentifier.BACKBONE): 315 leader.udp_open() 316 leader.udp_bind("::", 1234, netif=netif) 317 leader.udp_send(leader.get_ipaddr_rloc(), 1234, text='hello') 318 leader.udp_send(leader.get_ipaddr_rloc(), 1234, random_bytes=3) 319 leader.udp_send(leader.get_ipaddr_rloc(), 1234, hex='112233') 320 leader.wait(1) 321 leader.udp_close() 322 323 logging.info('dataset: %r', leader.get_dataset()) 324 logging.info('dataset active: %r', leader.get_dataset('active')) 325 326 leader.dataset_init_buffer() 327 leader.dataset_commit_buffer('pending') 328 leader.dataset_init_buffer(get_active_dataset=True) 329 leader.dataset_init_buffer(get_pending_dataset=True) 330 331 logging.info('dataset: %r', leader.get_dataset()) 332 logging.info('dataset active: %r', leader.get_dataset('active')) 333 logging.info('dataset pending: %r', leader.get_dataset('pending')) 334 335 logging.info('dataset active -x: %r', leader.get_dataset_bytes('active')) 336 logging.info('dataset pending -x: %r', leader.get_dataset_bytes('pending')) 337 338 # Test SRP server & client 339 self._test_otci_srp(leader, leader) 340 341 # Test DNS client and server 342 self._test_otci_dns(leader, leader) 343 344 self._test_otci_srp_remove(leader, leader) 345 346 def _test_otci_dns(self, client: OTCI, server: OTCI): 347 dns_cfg = client.dns_get_config() 348 self.assertTrue(dns_cfg['server']) 349 self.assertIn('response_timeout', dns_cfg) 350 self.assertIn('max_tx_attempts', dns_cfg) 351 self.assertIn('recursion_desired', dns_cfg) 352 353 client.dns_set_config(server=(server.get_ipaddr_rloc(), 53), 354 response_timeout=10000, 355 max_tx_attempts=4, 356 recursion_desired=False) 357 self.assertEqual( 358 { 359 'server': (server.get_ipaddr_rloc(), 53), 360 'response_timeout': 10000, 361 'max_tx_attempts': 4, 362 'recursion_desired': False 363 }, client.dns_get_config()) 364 365 self.assertTrue(client.dns_get_compression()) 366 client.dns_disable_compression() 367 self.assertFalse(client.dns_get_compression()) 368 client.dns_enable_compression() 369 self.assertTrue(client.dns_get_compression()) 370 371 logging.info('dns browse: %r', client.dns_browse('_ipps._tcp.default.service.arpa.')) 372 logging.info('dns browse: %r', client.dns_browse('_meshcop._udp.default.service.arpa.')) 373 logging.info('dns resolve: %r', client.dns_resolve_service('ins1', '_ipps._tcp.default.service.arpa.')) 374 logging.info('dns resolve: %r', client.dns_resolve('host1.default.service.arpa.')) 375 376 def _test_otci_srp(self, client: OTCI, server: OTCI): 377 self.assertEqual('disabled', server.srp_server_get_state()) 378 self.assertEqual('default.service.arpa.', server.srp_server_get_domain()) 379 server.srp_server_set_domain('example1.com') 380 self.assertEqual('example1.com.', server.srp_server_get_domain()) 381 server.srp_server_set_domain('example2.com.') 382 self.assertEqual('example2.com.', server.srp_server_get_domain()) 383 server.srp_server_set_domain('default.service.arpa.') 384 self.assertEqual('default.service.arpa.', server.srp_server_get_domain()) 385 386 default_leases = server.srp_server_get_lease() 387 self.assertEqual(default_leases, (30, 97200, 30, 680400)) 388 server.srp_server_set_lease(1801, 7201, 86401, 1209601) 389 leases = server.srp_server_get_lease() 390 self.assertEqual(leases, (1801, 7201, 86401, 1209601)) 391 392 self.assertFalse(client.srp_client_get_state()) 393 self.assertEqual('Removed', client.srp_client_get_host_state()) 394 self.assertEqual(('::', 0), client.srp_client_get_server()) 395 396 self.assertFalse(client.srp_client_get_service_key()) 397 client.srp_client_enable_service_key() 398 self.assertTrue(client.srp_client_get_service_key()) 399 client.srp_client_disable_service_key() 400 self.assertFalse(client.srp_client_get_service_key()) 401 402 server.srp_server_disable() 403 client.wait(3) 404 server.srp_server_enable() 405 client.wait(10) 406 self.assertEqual([], server.srp_server_get_hosts()) 407 self.assertEqual('running', server.srp_server_get_state()) 408 409 self.assertFalse(client.srp_client_get_autostart()) 410 client.srp_client_enable_autostart() 411 self.assertTrue(client.srp_client_get_autostart()) 412 client.wait(3) 413 self.assertTrue(client.srp_client_get_state()) 414 self.assertNotEqual(('::', 0), client.srp_client_get_server()) 415 416 self.assertEqual('', client.srp_client_get_host_name()) 417 client.srp_client_set_host_name('host1') 418 self.assertEqual('host1', client.srp_client_get_host_name()) 419 420 self.assertEqual([], client.srp_client_get_host_addresses()) 421 client.srp_client_set_host_addresses('2001::1') 422 self.assertEqual(['2001::1'], client.srp_client_get_host_addresses()) 423 client.srp_client_set_host_addresses('2001::1', '2001::2') 424 self.assertEqual(['2001::1', '2001::2'], client.srp_client_get_host_addresses()) 425 srp_client_host = client.srp_client_get_host() 426 self.assertEqual('host1', srp_client_host['host']) 427 self.assertEqual('ToAdd', srp_client_host['state']) 428 self.assertEqual( 429 {ipaddress.IPv6Address('2001::1'), ipaddress.IPv6Address('2001::2')}, set(srp_client_host['addresses'])) 430 431 self.assertEqual([], client.srp_client_get_services()) 432 client.srp_client_add_service('ins1', 433 '_ipps._tcp', 434 1000, 435 1, 436 1, 437 txt={ 438 'txt11': 'val11', 439 'txt12': b'val12', 440 'txt13': True 441 }) 442 client.srp_client_add_service('ins2', 443 '_meshcop._udp', 444 2000, 445 2, 446 2, 447 txt={ 448 'txt21': 'val21', 449 'txt22': b'val22', 450 'txt23': True 451 }) 452 self.assertEqual(2, len(client.srp_client_get_services())) 453 self.assertIn( 454 { 455 'instance': 'ins1', 456 'service': '_ipps._tcp', 457 'state': 'ToAdd', 458 'port': 1000, 459 'priority': 1, 460 'weight': 1, 461 }, client.srp_client_get_services()) 462 self.assertIn( 463 { 464 'instance': 'ins2', 465 'service': '_meshcop._udp', 466 'state': 'ToAdd', 467 'port': 2000, 468 'priority': 2, 469 'weight': 2, 470 }, client.srp_client_get_services()) 471 472 client.wait(3) 473 474 self.assertEqual('Registered', client.srp_client_get_host()['state']) 475 476 srp_server_hosts = server.srp_server_get_hosts() 477 logging.info('srp_server_hosts %r', srp_server_hosts) 478 self.assertEqual(1, len(srp_server_hosts)) 479 self.assertEqual('host1.default.service.arpa.', srp_server_hosts[0]['host']) 480 self.assertEqual(False, srp_server_hosts[0]['deleted']) 481 self.assertEqual( 482 {ipaddress.IPv6Address('2001::1'), ipaddress.IPv6Address('2001::2')}, 483 set(srp_server_hosts[0]['addresses'])) 484 485 srp_server_services = server.srp_server_get_services() 486 logging.info('srp_server_services %r', srp_server_services) 487 self.assertEqual(2, len(srp_server_services)) 488 for service in srp_server_services: 489 if service['instance'] == 'ins1._ipps._tcp.default.service.arpa.': 490 self.assertEqual(False, service['deleted']) 491 self.assertEqual(1000, service['port']) 492 self.assertEqual(1, service['priority']) 493 self.assertEqual(1, service['weight']) 494 self.assertEqual('host1.default.service.arpa.', service['host']) 495 self.assertEqual({ipaddress.IPv6Address('2001::1'), 496 ipaddress.IPv6Address('2001::2')}, set(service['addresses'])) 497 self.assertEqual({'txt11': b'val11', 'txt12': b'val12', 'txt13': True}, service['txt']) 498 elif service['instance'] == 'ins2._meshcop._udp.default.service.arpa.': 499 self.assertEqual(False, service['deleted']) 500 self.assertEqual(2000, service['port']) 501 self.assertEqual(2, service['priority']) 502 self.assertEqual(2, service['weight']) 503 self.assertEqual('host1.default.service.arpa.', service['host']) 504 self.assertEqual({ipaddress.IPv6Address('2001::1'), 505 ipaddress.IPv6Address('2001::2')}, set(service['addresses'])) 506 self.assertEqual({'txt21': b'val21', 'txt22': b'val22', 'txt23': True}, service['txt']) 507 else: 508 self.fail(service) 509 510 def _test_otci_srp_remove(self, client: OTCI, server: OTCI): 511 client.srp_client_remove_host(remove_key_lease=True) 512 client.wait(3) 513 self.assertEqual([], client.srp_client_get_services()) 514 self.assertEqual('Removed', client.srp_client_get_host()['state']) 515 self.assertEqual([], server.srp_server_get_hosts()) 516 self.assertEqual([], server.srp_server_get_services()) 517 518 def _test_otci_example(self, node1, node2): 519 node1.dataset_init_buffer() 520 node1.dataset_set_buffer(network_name='test', 521 network_key='00112233445566778899aabbccddeeff', 522 panid=0xface, 523 channel=11) 524 node1.dataset_commit_buffer('active') 525 526 node1.ifconfig_up() 527 node1.thread_start() 528 node1.wait(10) 529 assert node1.get_state() == "leader" 530 531 node1.commissioner_start() 532 node1.wait(3) 533 534 node1.commissioner_add_joiner("TEST123", eui64='*') 535 536 node2.ifconfig_up() 537 node2.set_router_selection_jitter(1) 538 539 node2.joiner_start("TEST123") 540 node2.wait(10, expect_line="Join success") 541 node2.thread_start() 542 node2.wait(10) 543 assert node2.get_state() == "router" 544 545 def _test_otci_multi_nodes(self, leader, commissioner, child1, child2): 546 self.assertFalse(leader.get_ifconfig_state()) 547 548 # ifconfig up 549 leader.ifconfig_up() 550 self.assertTrue(leader.get_ifconfig_state()) 551 552 logging.info('leader eui64 = %r', leader.get_eui64()) 553 logging.info('leader extpanid = %r', leader.get_extpanid()) 554 logging.info('leader networkkey = %r', leader.get_network_key()) 555 556 extaddr = leader.get_extaddr() 557 self.assertEqual(16, len(extaddr)) 558 int(extaddr, 16) 559 new_extaddr = 'aabbccddeeff0011' 560 leader.set_extaddr(new_extaddr) 561 self.assertEqual(new_extaddr, leader.get_extaddr()) 562 563 _setup_default_network(leader) 564 565 self.assertEqual(TEST_CHANNEL, leader.get_channel()) 566 self.assertEqual(TEST_NETWORK_KEY, leader.get_network_key()) 567 self.assertEqual(TEST_NETWORK_NAME, leader.get_network_name()) 568 self.assertEqual(TEST_PANID, leader.get_panid()) 569 570 self.assertEqual('rdn', leader.get_mode()) 571 572 leader.thread_start() 573 leader.wait(10) 574 self.assertEqual('leader', leader.get_state()) 575 logging.info('leader key sequence counter = %d', leader.get_key_sequence_counter()) 576 577 rloc16 = leader.get_rloc16() 578 leader_id = leader.get_router_id() 579 self.assertEqual(rloc16, leader_id << 10) 580 581 commissioner.dataset_clear_buffer() 582 commissioner.dataset_set_buffer( 583 channel=TEST_CHANNEL, 584 network_key=TEST_NETWORK_KEY, 585 panid=TEST_PANID, 586 ) 587 commissioner.dataset_commit_buffer('active') 588 commissioner.set_router_selection_jitter(1) 589 commissioner.ifconfig_up() 590 commissioner.thread_start() 591 592 commissioner.wait(10) 593 594 self.assertEqual('router', commissioner.get_state()) 595 596 for dst_ip in leader.get_ipaddrs(): 597 statistics = commissioner.ping(dst_ip, size=10, count=10, interval=2, hoplimit=3) 598 self.assertEqual(statistics['transmitted_packets'], 10) 599 self.assertEqual(statistics['received_packets'], 10) 600 self.assertAlmostEqual(statistics['packet_loss'], 0.0, delta=1e-9) 601 rtt = statistics['round_trip_time'] 602 self.assertTrue(rtt['min'] - 1e-9 <= rtt['avg'] <= rtt['max'] + 1e-9) 603 commissioner.wait(1) 604 605 self.assertEqual('disabled', commissioner.get_commissioiner_state()) 606 commissioner.commissioner_start() 607 commissioner.wait(5) 608 self.assertEqual('active', commissioner.get_commissioiner_state()) 609 610 logging.info('commissioner.get_network_id_timeout() = %d', commissioner.get_network_id_timeout()) 611 commissioner.set_network_id_timeout(60) 612 self.assertEqual(60, commissioner.get_network_id_timeout()) 613 614 commissioner.commissioner_add_joiner('TEST123', eui64='*') 615 commissioner.wait(3) 616 617 child1.ifconfig_up() 618 619 logging.info("child1 discover: %r", child1.discover()) 620 logging.info("child1 scan: %r", child1.scan()) 621 logging.info("child1 scan energy: %r", child1.scan_energy()) 622 623 child1.set_mode('rn') 624 child1.set_router_selection_jitter(1) 625 626 child1.joiner_start('TEST123') 627 logging.info('joiner id = %r', child1.get_joiner_id()) 628 child1.wait(10, expect_line="Join success") 629 630 child1.enable_allowlist() 631 child1.disable_allowlist() 632 child1.add_allowlist(commissioner.get_extaddr()) 633 child1.remove_allowlist(commissioner.get_extaddr()) 634 child1.set_allowlist([commissioner.get_extaddr()]) 635 636 child1.thread_start() 637 child1.wait(3) 638 self.assertEqual('child', child1.get_state()) 639 640 child1.thread_stop() 641 642 child1.set_mode('n') 643 child1.set_poll_period(1000) 644 self.assertEqual(1000, child1.get_poll_period()) 645 646 child1.thread_start() 647 child1.wait(3) 648 self.assertEqual('child', child1.get_state()) 649 650 child2.ifconfig_up() 651 child2.set_mode('rn') 652 child2.set_router_selection_jitter(1) 653 654 child2.joiner_start('TEST123') 655 logging.info('joiner id = %r', child2.get_joiner_id()) 656 child2.wait(10, expect_line="Join success") 657 658 child2.enable_allowlist() 659 child2.disable_allowlist() 660 child2.add_allowlist(commissioner.get_extaddr()) 661 child2.remove_allowlist(commissioner.get_extaddr()) 662 child2.set_allowlist([commissioner.get_extaddr()]) 663 664 child2.thread_start() 665 child2.wait(3) 666 self.assertEqual('child', child2.get_state()) 667 668 child_table = commissioner.get_child_table() 669 logging.info('commissioiner child table: \n%s\n', json.dumps(child_table, indent=True)) 670 child_list = commissioner.get_child_list() 671 logging.info('commissioiner child list: %r', child_list) 672 for child_id in child_list: 673 logging.info('child %s info: %r', child_id, commissioner.get_child_info(child_id)) 674 675 logging.info('child1 info: %r', commissioner.get_child_info(child1.get_rloc16())) 676 logging.info('child2 info: %r', commissioner.get_child_info(child2.get_rloc16())) 677 678 self.assertEqual(set(commissioner.get_child_list()), set(commissioner.get_child_table().keys())) 679 680 child1.add_ipmaddr('ff04::1') 681 child1.del_ipmaddr('ff04::1') 682 child1.add_ipmaddr('ff04::2') 683 logging.info('child1 ipmaddrs: %r', child1.get_ipmaddrs()) 684 self.assertFalse(child1.has_ipmaddr('ff04::1')) 685 self.assertTrue(child1.has_ipmaddr('ff04::2')) 686 687 child1.add_ipaddr('2001::1') 688 child1.del_ipaddr('2001::1') 689 child1.add_ipaddr('2001::2') 690 logging.info('child1 ipaddrs: %r', child1.get_ipaddrs()) 691 self.assertFalse(child1.has_ipaddr('2001::1')) 692 self.assertTrue(child1.has_ipaddr('2001::2')) 693 694 logging.info('child ipaddrs: %r', commissioner.get_child_ipaddrs()) 695 696 logging.info("EID-to-RLOC cache: %r", leader.get_eidcache()) 697 698 logging.info("leader neighbor list: %r", leader.get_neighbor_list()) 699 logging.info("leader neighbor table: %r", leader.get_neighbor_table()) 700 logging.info("prefixes: %r", commissioner.get_local_prefixes()) 701 commissioner.add_prefix('2001::/64') 702 commissioner.register_network_data() 703 commissioner.wait(1) 704 logging.info("prefixes: %r", commissioner.get_local_prefixes()) 705 706 self.assertEqual(2, len(leader.get_router_list())) 707 self.assertEqual(2, len(leader.get_router_table())) 708 logging.info('leader router table: %r', leader.get_router_table()) 709 self.assertEqual({False, True}, 710 set(router.is_link_established for router in leader.get_router_table().values())) 711 712 self.assertFalse(leader.is_singleton()) 713 714 statistics = commissioner.ping("ff02::1", size=1, count=10, interval=1, hoplimit=255) 715 self.assertEqual(statistics['transmitted_packets'], 10) 716 self.assertEqual(statistics['received_packets'], 20) 717 rtt = statistics['round_trip_time'] 718 self.assertTrue(rtt['min'] - 1e-9 <= rtt['avg'] <= rtt['max'] + 1e-9) 719 720 # Shutdown 721 leader.thread_stop() 722 logging.info("node state: %s", leader.get_state()) 723 leader.ifconfig_down() 724 self.assertFalse(leader.get_ifconfig_state()) 725 726 leader.close() 727 728 729def _setup_default_network(node): 730 node.dataset_clear_buffer() 731 node.dataset_set_buffer( 732 active_timestamp=1, 733 channel=TEST_CHANNEL, 734 channel_mask=TEST_CHANNEL_MASK, 735 extpanid=TEST_EXTENDED_PANID, 736 mesh_local_prefix=TEST_MESH_LOCAL_PREFIX, 737 network_key=TEST_NETWORK_KEY, 738 network_name=TEST_NETWORK_NAME, 739 panid=TEST_PANID, 740 pskc=TEST_PSKC, 741 security_policy=TEST_SECURITY_POLICY, 742 ) 743 node.dataset_commit_buffer('active') 744 745 746if __name__ == '__main__': 747 unittest.main() 748