• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.assertTrue(client.srp_client_get_autostart())
410        client.wait(3)
411        self.assertTrue(client.srp_client_get_state())
412        self.assertNotEqual(('::', 0), client.srp_client_get_server())
413
414        self.assertEqual('', client.srp_client_get_host_name())
415        client.srp_client_set_host_name('host1')
416        self.assertEqual('host1', client.srp_client_get_host_name())
417
418        self.assertEqual([], client.srp_client_get_host_addresses())
419        client.srp_client_set_host_addresses('2001::1')
420        self.assertEqual(['2001::1'], client.srp_client_get_host_addresses())
421        client.srp_client_set_host_addresses('2001::1', '2001::2')
422        self.assertEqual(['2001::1', '2001::2'], client.srp_client_get_host_addresses())
423        srp_client_host = client.srp_client_get_host()
424        self.assertEqual('host1', srp_client_host['host'])
425        self.assertEqual('ToAdd', srp_client_host['state'])
426        self.assertEqual(
427            {ipaddress.IPv6Address('2001::1'), ipaddress.IPv6Address('2001::2')}, set(srp_client_host['addresses']))
428
429        self.assertEqual([], client.srp_client_get_services())
430        client.srp_client_add_service('ins1',
431                                      '_ipps._tcp',
432                                      1000,
433                                      1,
434                                      1,
435                                      txt={
436                                          'txt11': 'val11',
437                                          'txt12': b'val12',
438                                          'txt13': True
439                                      })
440        client.srp_client_add_service('ins2',
441                                      '_meshcop._udp',
442                                      2000,
443                                      2,
444                                      2,
445                                      txt={
446                                          'txt21': 'val21',
447                                          'txt22': b'val22',
448                                          'txt23': True
449                                      })
450        self.assertEqual(2, len(client.srp_client_get_services()))
451        self.assertIn(
452            {
453                'instance': 'ins1',
454                'service': '_ipps._tcp',
455                'state': 'ToAdd',
456                'port': 1000,
457                'priority': 1,
458                'weight': 1,
459            }, client.srp_client_get_services())
460        self.assertIn(
461            {
462                'instance': 'ins2',
463                'service': '_meshcop._udp',
464                'state': 'ToAdd',
465                'port': 2000,
466                'priority': 2,
467                'weight': 2,
468            }, client.srp_client_get_services())
469
470        client.wait(3)
471
472        self.assertEqual('Registered', client.srp_client_get_host()['state'])
473
474        srp_server_hosts = server.srp_server_get_hosts()
475        logging.info('srp_server_hosts %r', srp_server_hosts)
476        self.assertEqual(1, len(srp_server_hosts))
477        self.assertEqual('host1.default.service.arpa.', srp_server_hosts[0]['host'])
478        self.assertEqual(False, srp_server_hosts[0]['deleted'])
479        self.assertEqual(
480            {ipaddress.IPv6Address('2001::1'), ipaddress.IPv6Address('2001::2')},
481            set(srp_server_hosts[0]['addresses']))
482
483        srp_server_services = server.srp_server_get_services()
484        logging.info('srp_server_services %r', srp_server_services)
485        self.assertEqual(2, len(srp_server_services))
486        for service in srp_server_services:
487            if service['instance'] == 'ins1._ipps._tcp.default.service.arpa.':
488                self.assertEqual(False, service['deleted'])
489                self.assertEqual(1000, service['port'])
490                self.assertEqual(1, service['priority'])
491                self.assertEqual(1, service['weight'])
492                self.assertEqual('host1.default.service.arpa.', service['host'])
493                self.assertEqual({ipaddress.IPv6Address('2001::1'),
494                                  ipaddress.IPv6Address('2001::2')}, set(service['addresses']))
495                self.assertEqual({'txt11': b'val11', 'txt12': b'val12', 'txt13': True}, service['txt'])
496            elif service['instance'] == 'ins2._meshcop._udp.default.service.arpa.':
497                self.assertEqual(False, service['deleted'])
498                self.assertEqual(2000, service['port'])
499                self.assertEqual(2, service['priority'])
500                self.assertEqual(2, service['weight'])
501                self.assertEqual('host1.default.service.arpa.', service['host'])
502                self.assertEqual({ipaddress.IPv6Address('2001::1'),
503                                  ipaddress.IPv6Address('2001::2')}, set(service['addresses']))
504                self.assertEqual({'txt21': b'val21', 'txt22': b'val22', 'txt23': True}, service['txt'])
505            else:
506                self.fail(service)
507
508    def _test_otci_srp_remove(self, client: OTCI, server: OTCI):
509        client.srp_client_remove_host(remove_key_lease=True)
510        client.wait(3)
511        self.assertEqual([], client.srp_client_get_services())
512        self.assertEqual('Removed', client.srp_client_get_host()['state'])
513        self.assertEqual([], server.srp_server_get_hosts())
514        self.assertEqual([], server.srp_server_get_services())
515
516    def _test_otci_example(self, node1, node2):
517        node1.dataset_init_buffer()
518        node1.dataset_set_buffer(network_name='test',
519                                 network_key='00112233445566778899aabbccddeeff',
520                                 panid=0xface,
521                                 channel=11)
522        node1.dataset_commit_buffer('active')
523
524        node1.ifconfig_up()
525        node1.thread_start()
526        node1.wait(10)
527        assert node1.get_state() == "leader"
528
529        node1.commissioner_start()
530        node1.wait(3)
531
532        node1.commissioner_add_joiner("TEST123", eui64='*')
533
534        node2.ifconfig_up()
535        node2.set_router_selection_jitter(1)
536
537        node2.joiner_start("TEST123")
538        node2.wait(10, expect_line="Join success")
539        node2.thread_start()
540        node2.wait(10)
541        assert node2.get_state() == "router"
542
543    def _test_otci_multi_nodes(self, leader, commissioner, child1, child2):
544        self.assertFalse(leader.get_ifconfig_state())
545
546        # ifconfig up
547        leader.ifconfig_up()
548        self.assertTrue(leader.get_ifconfig_state())
549
550        logging.info('leader eui64 = %r', leader.get_eui64())
551        logging.info('leader extpanid = %r', leader.get_extpanid())
552        logging.info('leader networkkey = %r', leader.get_network_key())
553
554        extaddr = leader.get_extaddr()
555        self.assertEqual(16, len(extaddr))
556        int(extaddr, 16)
557        new_extaddr = 'aabbccddeeff0011'
558        leader.set_extaddr(new_extaddr)
559        self.assertEqual(new_extaddr, leader.get_extaddr())
560
561        _setup_default_network(leader)
562
563        self.assertEqual(TEST_CHANNEL, leader.get_channel())
564        self.assertEqual(TEST_NETWORK_KEY, leader.get_network_key())
565        self.assertEqual(TEST_NETWORK_NAME, leader.get_network_name())
566        self.assertEqual(TEST_PANID, leader.get_panid())
567
568        self.assertEqual('rdn', leader.get_mode())
569
570        leader.thread_start()
571        leader.wait(10)
572        self.assertEqual('leader', leader.get_state())
573        logging.info('leader key sequence counter = %d', leader.get_key_sequence_counter())
574
575        rloc16 = leader.get_rloc16()
576        leader_id = leader.get_router_id()
577        self.assertEqual(rloc16, leader_id << 10)
578
579        commissioner.dataset_clear_buffer()
580        commissioner.dataset_set_buffer(
581            channel=TEST_CHANNEL,
582            network_key=TEST_NETWORK_KEY,
583            panid=TEST_PANID,
584        )
585        commissioner.dataset_commit_buffer('active')
586        commissioner.set_router_selection_jitter(1)
587        commissioner.ifconfig_up()
588        commissioner.thread_start()
589
590        commissioner.wait(10)
591
592        self.assertEqual('router', commissioner.get_state())
593
594        for dst_ip in leader.get_ipaddrs():
595            statistics = commissioner.ping(dst_ip, size=10, count=10, interval=2, hoplimit=3)
596            self.assertEqual(statistics['transmitted_packets'], 10)
597            self.assertEqual(statistics['received_packets'], 10)
598            self.assertAlmostEqual(statistics['packet_loss'], 0.0, delta=1e-9)
599            rtt = statistics['round_trip_time']
600            self.assertTrue(rtt['min'] - 1e-9 <= rtt['avg'] <= rtt['max'] + 1e-9)
601            commissioner.wait(1)
602
603        self.assertEqual('disabled', commissioner.get_commissioiner_state())
604        commissioner.commissioner_start()
605        commissioner.wait(5)
606        self.assertEqual('active', commissioner.get_commissioiner_state())
607
608        logging.info('commissioner.get_network_id_timeout() = %d', commissioner.get_network_id_timeout())
609        commissioner.set_network_id_timeout(60)
610        self.assertEqual(60, commissioner.get_network_id_timeout())
611
612        commissioner.commissioner_add_joiner('TEST123', eui64='*')
613        commissioner.wait(3)
614
615        child1.ifconfig_up()
616
617        logging.info("child1 discover: %r", child1.discover())
618        logging.info("child1 scan: %r", child1.scan())
619        logging.info("child1 scan energy: %r", child1.scan_energy())
620
621        child1.set_mode('rn')
622        child1.set_router_selection_jitter(1)
623
624        child1.joiner_start('TEST123')
625        logging.info('joiner id = %r', child1.get_joiner_id())
626        child1.wait(10, expect_line="Join success")
627
628        child1.enable_allowlist()
629        child1.disable_allowlist()
630        child1.add_allowlist(commissioner.get_extaddr())
631        child1.remove_allowlist(commissioner.get_extaddr())
632        child1.set_allowlist([commissioner.get_extaddr()])
633
634        child1.thread_start()
635        child1.wait(3)
636        self.assertEqual('child', child1.get_state())
637
638        child1.thread_stop()
639
640        child1.set_mode('n')
641        child1.set_poll_period(1000)
642        self.assertEqual(1000, child1.get_poll_period())
643
644        child1.thread_start()
645        child1.wait(3)
646        self.assertEqual('child', child1.get_state())
647
648        child2.ifconfig_up()
649        child2.set_mode('rn')
650        child2.set_router_selection_jitter(1)
651
652        child2.joiner_start('TEST123')
653        logging.info('joiner id = %r', child2.get_joiner_id())
654        child2.wait(10, expect_line="Join success")
655
656        child2.enable_allowlist()
657        child2.disable_allowlist()
658        child2.add_allowlist(commissioner.get_extaddr())
659        child2.remove_allowlist(commissioner.get_extaddr())
660        child2.set_allowlist([commissioner.get_extaddr()])
661
662        child2.thread_start()
663        child2.wait(3)
664        self.assertEqual('child', child2.get_state())
665
666        child_table = commissioner.get_child_table()
667        logging.info('commissioiner child table: \n%s\n', json.dumps(child_table, indent=True))
668        child_list = commissioner.get_child_list()
669        logging.info('commissioiner child list: %r', child_list)
670        for child_id in child_list:
671            logging.info('child %s info: %r', child_id, commissioner.get_child_info(child_id))
672
673        logging.info('child1 info: %r', commissioner.get_child_info(child1.get_rloc16()))
674        logging.info('child2 info: %r', commissioner.get_child_info(child2.get_rloc16()))
675
676        self.assertEqual(set(commissioner.get_child_list()), set(commissioner.get_child_table().keys()))
677
678        child1.add_ipmaddr('ff04::1')
679        child1.del_ipmaddr('ff04::1')
680        child1.add_ipmaddr('ff04::2')
681        logging.info('child1 ipmaddrs: %r', child1.get_ipmaddrs())
682        self.assertFalse(child1.has_ipmaddr('ff04::1'))
683        self.assertTrue(child1.has_ipmaddr('ff04::2'))
684
685        child1.add_ipaddr('2001::1')
686        child1.del_ipaddr('2001::1')
687        child1.add_ipaddr('2001::2')
688        logging.info('child1 ipaddrs: %r', child1.get_ipaddrs())
689        self.assertFalse(child1.has_ipaddr('2001::1'))
690        self.assertTrue(child1.has_ipaddr('2001::2'))
691
692        logging.info('child ipaddrs: %r', commissioner.get_child_ipaddrs())
693
694        logging.info("EID-to-RLOC cache: %r", leader.get_eidcache())
695
696        logging.info("leader neighbor list: %r", leader.get_neighbor_list())
697        logging.info("leader neighbor table: %r", leader.get_neighbor_table())
698        logging.info("prefixes: %r", commissioner.get_local_prefixes())
699        commissioner.add_prefix('2001::/64')
700        commissioner.register_network_data()
701        commissioner.wait(1)
702        logging.info("prefixes: %r", commissioner.get_local_prefixes())
703
704        self.assertEqual(2, len(leader.get_router_list()))
705        self.assertEqual(2, len(leader.get_router_table()))
706        logging.info('leader router table: %r', leader.get_router_table())
707        self.assertEqual({False, True},
708                         set(router.is_link_established for router in leader.get_router_table().values()))
709
710        self.assertFalse(leader.is_singleton())
711
712        statistics = commissioner.ping("ff02::1", size=1, count=10, interval=1, hoplimit=255)
713        self.assertEqual(statistics['transmitted_packets'], 10)
714        self.assertEqual(statistics['received_packets'], 20)
715        rtt = statistics['round_trip_time']
716        self.assertTrue(rtt['min'] - 1e-9 <= rtt['avg'] <= rtt['max'] + 1e-9)
717
718        # Shutdown
719        leader.thread_stop()
720        logging.info("node state: %s", leader.get_state())
721        leader.ifconfig_down()
722        self.assertFalse(leader.get_ifconfig_state())
723
724        leader.close()
725
726
727def _setup_default_network(node):
728    node.dataset_clear_buffer()
729    node.dataset_set_buffer(
730        active_timestamp=1,
731        channel=TEST_CHANNEL,
732        channel_mask=TEST_CHANNEL_MASK,
733        extpanid=TEST_EXTENDED_PANID,
734        mesh_local_prefix=TEST_MESH_LOCAL_PREFIX,
735        network_key=TEST_NETWORK_KEY,
736        network_name=TEST_NETWORK_NAME,
737        panid=TEST_PANID,
738        pskc=TEST_PSKC,
739        security_policy=TEST_SECURITY_POLICY,
740    )
741    node.dataset_commit_buffer('active')
742
743
744if __name__ == '__main__':
745    unittest.main()
746