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("leader data: %r", leader.get_leader_data()) 261 logging.info("leader neighbor list: %r", leader.get_neighbor_list()) 262 logging.info("leader neighbor table: %r", leader.get_neighbor_table()) 263 logging.info("Leader external routes: %r", leader.get_local_routes()) 264 leader.add_route('2002::/64') 265 leader.register_network_data() 266 logging.info("Leader external routes: %r", leader.get_local_routes()) 267 268 self.assertEqual(1, len(leader.get_router_list())) 269 self.assertEqual(1, len(leader.get_router_table())) 270 logging.info("Leader router table: %r", leader.get_router_table()) 271 self.assertFalse(list(leader.get_router_table().values())[0].is_link_established) 272 273 logging.info('discover: %r', leader.discover()) 274 logging.info('scan: %r', leader.scan()) 275 logging.info('scan energy: %r', leader.scan_energy()) 276 277 leader.add_service(44970, '112233', 'aabbcc') 278 leader.register_network_data() 279 leader.add_service(44971, b'\x11\x22\x33', b'\xaa\xbb\xcc\xdd') 280 281 leader.add_prefix("2001::/64") 282 283 logging.info("network data: %r", leader.get_network_data()) 284 logging.info("network data raw: %r", leader.get_network_data_bytes()) 285 self.assertEqual(leader.get_network_data()['prefixes'], leader.get_prefixes()) 286 self.assertEqual(leader.get_network_data()['routes'], leader.get_routes()) 287 self.assertEqual(leader.get_network_data()['services'], leader.get_services()) 288 289 logging.info("local prefixes: %r", leader.get_local_prefixes()) 290 logging.info("local routes: %r", leader.get_local_routes()) 291 292 logging.info('txpower %r', leader.get_txpower()) 293 leader.set_txpower(-10) 294 self.assertEqual(-10, leader.get_txpower()) 295 296 self.assertTrue(leader.is_singleton()) 297 298 leader.coap_start() 299 leader.coap_set_test_resource_path('test') 300 leader.coap_test_set_resource_content('helloworld') 301 leader.coap_get(leader.get_ipaddr_rloc(), 'test') 302 leader.coap_put(leader.get_ipaddr_rloc(), 'test', 'con', 'xxx') 303 leader.coap_post(leader.get_ipaddr_rloc(), 'test', 'con', 'xxx') 304 leader.coap_delete(leader.get_ipaddr_rloc(), 'test', 'con', 'xxx') 305 leader.wait(1) 306 leader.coap_stop() 307 308 for netif in (NetifIdentifier.THERAD, NetifIdentifier.UNSPECIFIED, NetifIdentifier.BACKBONE): 309 leader.udp_open() 310 leader.udp_bind("::", 1234, netif=netif) 311 leader.udp_send(leader.get_ipaddr_rloc(), 1234, text='hello') 312 leader.udp_send(leader.get_ipaddr_rloc(), 1234, random_bytes=3) 313 leader.udp_send(leader.get_ipaddr_rloc(), 1234, hex='112233') 314 leader.wait(1) 315 leader.udp_close() 316 317 logging.info('dataset: %r', leader.get_dataset()) 318 logging.info('dataset active: %r', leader.get_dataset('active')) 319 320 leader.dataset_init_buffer() 321 leader.dataset_commit_buffer('pending') 322 leader.dataset_init_buffer(get_active_dataset=True) 323 leader.dataset_init_buffer(get_pending_dataset=True) 324 325 logging.info('dataset: %r', leader.get_dataset()) 326 logging.info('dataset active: %r', leader.get_dataset('active')) 327 logging.info('dataset pending: %r', leader.get_dataset('pending')) 328 329 logging.info('dataset active -x: %r', leader.get_dataset_bytes('active')) 330 logging.info('dataset pending -x: %r', leader.get_dataset_bytes('pending')) 331 332 # Test SRP server & client 333 self._test_otci_srp(leader, leader) 334 335 # Test DNS client and server 336 self._test_otci_dns(leader, leader) 337 338 self._test_otci_srp_remove(leader, leader) 339 340 def _test_otci_dns(self, client: OTCI, server: OTCI): 341 dns_cfg = client.dns_get_config() 342 self.assertTrue(dns_cfg['server']) 343 self.assertIn('response_timeout', dns_cfg) 344 self.assertIn('max_tx_attempts', dns_cfg) 345 self.assertIn('recursion_desired', dns_cfg) 346 347 client.dns_set_config(server=(server.get_ipaddr_rloc(), 53), 348 response_timeout=10000, 349 max_tx_attempts=4, 350 recursion_desired=False) 351 self.assertEqual( 352 { 353 'server': (server.get_ipaddr_rloc(), 53), 354 'response_timeout': 10000, 355 'max_tx_attempts': 4, 356 'recursion_desired': False 357 }, client.dns_get_config()) 358 359 self.assertTrue(client.dns_get_compression()) 360 client.dns_disable_compression() 361 self.assertFalse(client.dns_get_compression()) 362 client.dns_enable_compression() 363 self.assertTrue(client.dns_get_compression()) 364 365 logging.info('dns browse: %r', client.dns_browse('_ipps._tcp.default.service.arpa.')) 366 logging.info('dns browse: %r', client.dns_browse('_meshcop._udp.default.service.arpa.')) 367 logging.info('dns resolve: %r', client.dns_resolve_service('ins1', '_ipps._tcp.default.service.arpa.')) 368 logging.info('dns resolve: %r', client.dns_resolve('host1.default.service.arpa.')) 369 370 def _test_otci_srp(self, client: OTCI, server: OTCI): 371 self.assertEqual('disabled', server.srp_server_get_state()) 372 self.assertEqual('default.service.arpa.', server.srp_server_get_domain()) 373 server.srp_server_set_domain('example1.com') 374 self.assertEqual('example1.com.', server.srp_server_get_domain()) 375 server.srp_server_set_domain('example2.com.') 376 self.assertEqual('example2.com.', server.srp_server_get_domain()) 377 server.srp_server_set_domain('default.service.arpa.') 378 self.assertEqual('default.service.arpa.', server.srp_server_get_domain()) 379 380 default_leases = server.srp_server_get_lease() 381 self.assertEqual(default_leases, (30, 97200, 30, 680400)) 382 server.srp_server_set_lease(1801, 7201, 86401, 1209601) 383 leases = server.srp_server_get_lease() 384 self.assertEqual(leases, (1801, 7201, 86401, 1209601)) 385 386 self.assertFalse(client.srp_client_get_state()) 387 self.assertEqual('Removed', client.srp_client_get_host_state()) 388 self.assertEqual(('::', 0), client.srp_client_get_server()) 389 390 self.assertFalse(client.srp_client_get_service_key()) 391 client.srp_client_enable_service_key() 392 self.assertTrue(client.srp_client_get_service_key()) 393 client.srp_client_disable_service_key() 394 self.assertFalse(client.srp_client_get_service_key()) 395 396 server.srp_server_disable() 397 client.wait(3) 398 server.srp_server_enable() 399 client.wait(10) 400 self.assertEqual([], server.srp_server_get_hosts()) 401 self.assertEqual('running', server.srp_server_get_state()) 402 403 self.assertTrue(client.srp_client_get_autostart()) 404 client.wait(3) 405 self.assertTrue(client.srp_client_get_state()) 406 self.assertNotEqual(('::', 0), client.srp_client_get_server()) 407 408 self.assertEqual('', client.srp_client_get_host_name()) 409 client.srp_client_set_host_name('host1') 410 self.assertEqual('host1', client.srp_client_get_host_name()) 411 412 self.assertEqual([], client.srp_client_get_host_addresses()) 413 client.srp_client_set_host_addresses('2001::1') 414 self.assertEqual(['2001::1'], client.srp_client_get_host_addresses()) 415 client.srp_client_set_host_addresses('2001::1', '2001::2') 416 self.assertEqual(['2001::1', '2001::2'], client.srp_client_get_host_addresses()) 417 srp_client_host = client.srp_client_get_host() 418 self.assertEqual('host1', srp_client_host['host']) 419 self.assertEqual('ToAdd', srp_client_host['state']) 420 self.assertEqual( 421 {ipaddress.IPv6Address('2001::1'), ipaddress.IPv6Address('2001::2')}, set(srp_client_host['addresses'])) 422 423 self.assertEqual([], client.srp_client_get_services()) 424 client.srp_client_add_service('ins1', 425 '_ipps._tcp', 426 1000, 427 1, 428 1, 429 txt={ 430 'txt11': 'val11', 431 'txt12': b'val12', 432 'txt13': True 433 }) 434 client.srp_client_add_service('ins2', 435 '_meshcop._udp', 436 2000, 437 2, 438 2, 439 txt={ 440 'txt21': 'val21', 441 'txt22': b'val22', 442 'txt23': True 443 }) 444 self.assertEqual(2, len(client.srp_client_get_services())) 445 self.assertIn( 446 { 447 'instance': 'ins1', 448 'service': '_ipps._tcp', 449 'state': 'ToAdd', 450 'port': 1000, 451 'priority': 1, 452 'weight': 1, 453 }, client.srp_client_get_services()) 454 self.assertIn( 455 { 456 'instance': 'ins2', 457 'service': '_meshcop._udp', 458 'state': 'ToAdd', 459 'port': 2000, 460 'priority': 2, 461 'weight': 2, 462 }, client.srp_client_get_services()) 463 464 client.wait(3) 465 466 self.assertEqual('Registered', client.srp_client_get_host()['state']) 467 468 srp_server_hosts = server.srp_server_get_hosts() 469 logging.info('srp_server_hosts %r', srp_server_hosts) 470 self.assertEqual(1, len(srp_server_hosts)) 471 self.assertEqual('host1.default.service.arpa.', srp_server_hosts[0]['host']) 472 self.assertEqual(False, srp_server_hosts[0]['deleted']) 473 self.assertEqual( 474 {ipaddress.IPv6Address('2001::1'), ipaddress.IPv6Address('2001::2')}, 475 set(srp_server_hosts[0]['addresses'])) 476 477 srp_server_services = server.srp_server_get_services() 478 logging.info('srp_server_services %r', srp_server_services) 479 self.assertEqual(2, len(srp_server_services)) 480 for service in srp_server_services: 481 if service['instance'] == 'ins1._ipps._tcp.default.service.arpa.': 482 self.assertEqual(False, service['deleted']) 483 self.assertEqual(1000, service['port']) 484 self.assertEqual(1, service['priority']) 485 self.assertEqual(1, service['weight']) 486 self.assertEqual('host1.default.service.arpa.', service['host']) 487 self.assertEqual({ipaddress.IPv6Address('2001::1'), 488 ipaddress.IPv6Address('2001::2')}, set(service['addresses'])) 489 self.assertEqual({'txt11': b'val11', 'txt12': b'val12', 'txt13': True}, service['txt']) 490 elif service['instance'] == 'ins2._meshcop._udp.default.service.arpa.': 491 self.assertEqual(False, service['deleted']) 492 self.assertEqual(2000, service['port']) 493 self.assertEqual(2, service['priority']) 494 self.assertEqual(2, service['weight']) 495 self.assertEqual('host1.default.service.arpa.', service['host']) 496 self.assertEqual({ipaddress.IPv6Address('2001::1'), 497 ipaddress.IPv6Address('2001::2')}, set(service['addresses'])) 498 self.assertEqual({'txt21': b'val21', 'txt22': b'val22', 'txt23': True}, service['txt']) 499 else: 500 self.fail(service) 501 502 def _test_otci_srp_remove(self, client: OTCI, server: OTCI): 503 client.srp_client_remove_host(remove_key_lease=True) 504 client.wait(3) 505 self.assertEqual([], client.srp_client_get_services()) 506 self.assertEqual('Removed', client.srp_client_get_host()['state']) 507 self.assertEqual([], server.srp_server_get_hosts()) 508 self.assertEqual([], server.srp_server_get_services()) 509 510 def _test_otci_example(self, node1, node2): 511 node1.dataset_init_buffer() 512 node1.dataset_set_buffer(network_name='test', 513 network_key='00112233445566778899aabbccddeeff', 514 panid=0xface, 515 channel=11) 516 node1.dataset_commit_buffer('active') 517 518 node1.ifconfig_up() 519 node1.thread_start() 520 node1.wait(10) 521 assert node1.get_state() == "leader" 522 523 node1.commissioner_start() 524 node1.wait(3) 525 526 node1.commissioner_add_joiner("TEST123", eui64='*') 527 528 node2.ifconfig_up() 529 node2.set_router_selection_jitter(1) 530 531 node2.joiner_start("TEST123") 532 node2.wait(10, expect_line="Join success") 533 node2.thread_start() 534 node2.wait(10) 535 assert node2.get_state() == "router" 536 537 def _test_otci_multi_nodes(self, leader, commissioner, child1, child2): 538 self.assertFalse(leader.get_ifconfig_state()) 539 540 # ifconfig up 541 leader.ifconfig_up() 542 self.assertTrue(leader.get_ifconfig_state()) 543 544 logging.info('leader eui64 = %r', leader.get_eui64()) 545 logging.info('leader extpanid = %r', leader.get_extpanid()) 546 logging.info('leader networkkey = %r', leader.get_network_key()) 547 548 extaddr = leader.get_extaddr() 549 self.assertEqual(16, len(extaddr)) 550 int(extaddr, 16) 551 new_extaddr = 'aabbccddeeff0011' 552 leader.set_extaddr(new_extaddr) 553 self.assertEqual(new_extaddr, leader.get_extaddr()) 554 555 _setup_default_network(leader) 556 557 self.assertEqual(TEST_CHANNEL, leader.get_channel()) 558 self.assertEqual(TEST_NETWORK_KEY, leader.get_network_key()) 559 self.assertEqual(TEST_NETWORK_NAME, leader.get_network_name()) 560 self.assertEqual(TEST_PANID, leader.get_panid()) 561 562 self.assertEqual('rdn', leader.get_mode()) 563 564 leader.thread_start() 565 leader.wait(10) 566 self.assertEqual('leader', leader.get_state()) 567 logging.info('leader key sequence counter = %d', leader.get_key_sequence_counter()) 568 569 rloc16 = leader.get_rloc16() 570 leader_id = leader.get_router_id() 571 self.assertEqual(rloc16, leader_id << 10) 572 573 commissioner.dataset_clear_buffer() 574 commissioner.dataset_set_buffer( 575 channel=TEST_CHANNEL, 576 network_key=TEST_NETWORK_KEY, 577 panid=TEST_PANID, 578 ) 579 commissioner.dataset_commit_buffer('active') 580 commissioner.set_router_selection_jitter(1) 581 commissioner.ifconfig_up() 582 commissioner.thread_start() 583 584 commissioner.wait(10) 585 586 self.assertEqual('router', commissioner.get_state()) 587 588 for dst_ip in leader.get_ipaddrs(): 589 statistics = commissioner.ping(dst_ip, size=10, count=10, interval=2, hoplimit=3) 590 self.assertEqual(statistics['transmitted_packets'], 10) 591 self.assertEqual(statistics['received_packets'], 10) 592 self.assertAlmostEqual(statistics['packet_loss'], 0.0, delta=1e-9) 593 rtt = statistics['round_trip_time'] 594 self.assertTrue(rtt['min'] - 1e-9 <= rtt['avg'] <= rtt['max'] + 1e-9) 595 commissioner.wait(1) 596 597 self.assertEqual('disabled', commissioner.get_commissioiner_state()) 598 commissioner.commissioner_start() 599 commissioner.wait(5) 600 self.assertEqual('active', commissioner.get_commissioiner_state()) 601 602 logging.info('commissioner.get_network_id_timeout() = %d', commissioner.get_network_id_timeout()) 603 commissioner.set_network_id_timeout(60) 604 self.assertEqual(60, commissioner.get_network_id_timeout()) 605 606 commissioner.commissioner_add_joiner('TEST123', eui64='*') 607 commissioner.wait(3) 608 609 child1.ifconfig_up() 610 611 logging.info("child1 discover: %r", child1.discover()) 612 logging.info("child1 scan: %r", child1.scan()) 613 logging.info("child1 scan energy: %r", child1.scan_energy()) 614 615 child1.set_mode('rn') 616 child1.set_router_selection_jitter(1) 617 618 child1.joiner_start('TEST123') 619 logging.info('joiner id = %r', child1.get_joiner_id()) 620 child1.wait(10, expect_line="Join success") 621 622 child1.enable_allowlist() 623 child1.disable_allowlist() 624 child1.add_allowlist(commissioner.get_extaddr()) 625 child1.remove_allowlist(commissioner.get_extaddr()) 626 child1.set_allowlist([commissioner.get_extaddr()]) 627 628 child1.thread_start() 629 child1.wait(3) 630 self.assertEqual('child', child1.get_state()) 631 632 child1.thread_stop() 633 634 child1.set_mode('n') 635 child1.set_poll_period(1000) 636 self.assertEqual(1000, child1.get_poll_period()) 637 638 child1.thread_start() 639 child1.wait(3) 640 self.assertEqual('child', child1.get_state()) 641 642 child2.ifconfig_up() 643 child2.set_mode('rn') 644 child2.set_router_selection_jitter(1) 645 646 child2.joiner_start('TEST123') 647 logging.info('joiner id = %r', child2.get_joiner_id()) 648 child2.wait(10, expect_line="Join success") 649 650 child2.enable_allowlist() 651 child2.disable_allowlist() 652 child2.add_allowlist(commissioner.get_extaddr()) 653 child2.remove_allowlist(commissioner.get_extaddr()) 654 child2.set_allowlist([commissioner.get_extaddr()]) 655 656 child2.thread_start() 657 child2.wait(3) 658 self.assertEqual('child', child2.get_state()) 659 660 child_table = commissioner.get_child_table() 661 logging.info('commissioiner child table: \n%s\n', json.dumps(child_table, indent=True)) 662 child_list = commissioner.get_child_list() 663 logging.info('commissioiner child list: %r', child_list) 664 for child_id in child_list: 665 logging.info('child %s info: %r', child_id, commissioner.get_child_info(child_id)) 666 667 logging.info('child1 info: %r', commissioner.get_child_info(child1.get_rloc16())) 668 logging.info('child2 info: %r', commissioner.get_child_info(child2.get_rloc16())) 669 670 self.assertEqual(set(commissioner.get_child_list()), set(commissioner.get_child_table().keys())) 671 672 child1.add_ipmaddr('ff04::1') 673 child1.del_ipmaddr('ff04::1') 674 child1.add_ipmaddr('ff04::2') 675 logging.info('child1 ipmaddrs: %r', child1.get_ipmaddrs()) 676 self.assertFalse(child1.has_ipmaddr('ff04::1')) 677 self.assertTrue(child1.has_ipmaddr('ff04::2')) 678 679 child1.add_ipaddr('2001::1') 680 child1.del_ipaddr('2001::1') 681 child1.add_ipaddr('2001::2') 682 logging.info('child1 ipaddrs: %r', child1.get_ipaddrs()) 683 self.assertFalse(child1.has_ipaddr('2001::1')) 684 self.assertTrue(child1.has_ipaddr('2001::2')) 685 686 logging.info('child ipaddrs: %r', commissioner.get_child_ipaddrs()) 687 688 logging.info("EID-to-RLOC cache: %r", leader.get_eidcache()) 689 690 logging.info("leader neighbor list: %r", leader.get_neighbor_list()) 691 logging.info("leader neighbor table: %r", leader.get_neighbor_table()) 692 logging.info("prefixes: %r", commissioner.get_local_prefixes()) 693 commissioner.add_prefix('2001::/64') 694 commissioner.register_network_data() 695 commissioner.wait(1) 696 logging.info("prefixes: %r", commissioner.get_local_prefixes()) 697 698 self.assertEqual(2, len(leader.get_router_list())) 699 self.assertEqual(2, len(leader.get_router_table())) 700 logging.info('leader router table: %r', leader.get_router_table()) 701 self.assertEqual({False, True}, 702 set(router.is_link_established for router in leader.get_router_table().values())) 703 704 self.assertFalse(leader.is_singleton()) 705 706 statistics = commissioner.ping("ff02::1", size=1, count=10, interval=1, hoplimit=255) 707 self.assertEqual(statistics['transmitted_packets'], 10) 708 self.assertEqual(statistics['received_packets'], 20) 709 rtt = statistics['round_trip_time'] 710 self.assertTrue(rtt['min'] - 1e-9 <= rtt['avg'] <= rtt['max'] + 1e-9) 711 712 # Shutdown 713 leader.thread_stop() 714 logging.info("node state: %s", leader.get_state()) 715 leader.ifconfig_down() 716 self.assertFalse(leader.get_ifconfig_state()) 717 718 leader.close() 719 720 721def _setup_default_network(node): 722 node.dataset_clear_buffer() 723 node.dataset_set_buffer( 724 active_timestamp=1, 725 channel=TEST_CHANNEL, 726 channel_mask=TEST_CHANNEL_MASK, 727 extpanid=TEST_EXTENDED_PANID, 728 mesh_local_prefix=TEST_MESH_LOCAL_PREFIX, 729 network_key=TEST_NETWORK_KEY, 730 network_name=TEST_NETWORK_NAME, 731 panid=TEST_PANID, 732 pskc=TEST_PSKC, 733 security_policy=TEST_SECURITY_POLICY, 734 ) 735 node.dataset_commit_buffer('active') 736 737 738if __name__ == '__main__': 739 unittest.main() 740