From a7c051f07a99358e27063853eaa3e5c08b6976aa Mon Sep 17 00:00:00 2001 From: Jonathan Hui Date: Thu, 26 Feb 2026 13:13:31 -0600 Subject: [PATCH] [tests] remove migrated thread-cert scripts (#12566) This commit removes the certification test scripts in tests/scripts/thread-cert/ that have been successfully migrated to the Nexus test framework. The following tests were migrated and are now available as Nexus tests under tests/nexus/: - 5.8.2, 5.8.3, 5.8.4 - 9.2.1 through 9.2.19 Migrating these tests to Nexus provides faster execution, better reliability, and easier debugging compared to the old simulation-based scripts. --- .../thread-cert/Cert_5_8_02_KeyIncrement.py | 131 --- .../Cert_5_8_03_KeyIncrementRollOver.py | 134 --- .../Cert_5_8_04_SecurityPolicyTLV.py | 415 --------- .../Cert_9_2_01_MGMTCommissionerGet.py | 279 ------ .../Cert_9_2_02_MGMTCommissionerSet.py | 385 -------- .../Cert_9_2_03_ActiveDatasetGet.py | 265 ------ .../thread-cert/Cert_9_2_04_ActiveDataset.py | 319 ------- .../thread-cert/Cert_9_2_05_ActiveDataset.py | 369 -------- .../Cert_9_2_06_DatasetDissemination.py | 872 ------------------ .../thread-cert/Cert_9_2_07_DelayTimer.py | 228 ----- .../Cert_9_2_08_PersistentDatasets.py | 353 ------- .../Cert_9_2_09_PendingPartition.py | 762 --------------- .../Cert_9_2_10_PendingPartition.py | 242 ----- .../thread-cert/Cert_9_2_11_NetworkKey.py | 390 -------- .../thread-cert/Cert_9_2_12_Announce.py | 174 ---- .../thread-cert/Cert_9_2_13_EnergyScan.py | 162 ---- .../thread-cert/Cert_9_2_14_PanIdQuery.py | 141 --- .../Cert_9_2_15_PendingPartition.py | 198 ---- .../Cert_9_2_16_ActivePendingPartition.py | 208 ----- .../scripts/thread-cert/Cert_9_2_17_Orphan.py | 147 --- .../Cert_9_2_18_RollBackActiveTimestamp.py | 258 ------ .../Cert_9_2_19_PendingDatasetGet.py | 293 ------ 22 files changed, 6725 deletions(-) delete mode 100755 tests/scripts/thread-cert/Cert_5_8_02_KeyIncrement.py delete mode 100755 tests/scripts/thread-cert/Cert_5_8_03_KeyIncrementRollOver.py delete mode 100755 tests/scripts/thread-cert/Cert_5_8_04_SecurityPolicyTLV.py delete mode 100755 tests/scripts/thread-cert/Cert_9_2_01_MGMTCommissionerGet.py delete mode 100755 tests/scripts/thread-cert/Cert_9_2_02_MGMTCommissionerSet.py delete mode 100755 tests/scripts/thread-cert/Cert_9_2_03_ActiveDatasetGet.py delete mode 100755 tests/scripts/thread-cert/Cert_9_2_04_ActiveDataset.py delete mode 100755 tests/scripts/thread-cert/Cert_9_2_05_ActiveDataset.py delete mode 100755 tests/scripts/thread-cert/Cert_9_2_06_DatasetDissemination.py delete mode 100755 tests/scripts/thread-cert/Cert_9_2_07_DelayTimer.py delete mode 100755 tests/scripts/thread-cert/Cert_9_2_08_PersistentDatasets.py delete mode 100755 tests/scripts/thread-cert/Cert_9_2_09_PendingPartition.py delete mode 100755 tests/scripts/thread-cert/Cert_9_2_10_PendingPartition.py delete mode 100755 tests/scripts/thread-cert/Cert_9_2_11_NetworkKey.py delete mode 100755 tests/scripts/thread-cert/Cert_9_2_12_Announce.py delete mode 100755 tests/scripts/thread-cert/Cert_9_2_13_EnergyScan.py delete mode 100755 tests/scripts/thread-cert/Cert_9_2_14_PanIdQuery.py delete mode 100755 tests/scripts/thread-cert/Cert_9_2_15_PendingPartition.py delete mode 100755 tests/scripts/thread-cert/Cert_9_2_16_ActivePendingPartition.py delete mode 100755 tests/scripts/thread-cert/Cert_9_2_17_Orphan.py delete mode 100755 tests/scripts/thread-cert/Cert_9_2_18_RollBackActiveTimestamp.py delete mode 100755 tests/scripts/thread-cert/Cert_9_2_19_PendingDatasetGet.py diff --git a/tests/scripts/thread-cert/Cert_5_8_02_KeyIncrement.py b/tests/scripts/thread-cert/Cert_5_8_02_KeyIncrement.py deleted file mode 100755 index 230b3163d..000000000 --- a/tests/scripts/thread-cert/Cert_5_8_02_KeyIncrement.py +++ /dev/null @@ -1,131 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import thread_cert -from pktverify.consts import MLE_ADVERTISEMENT, MLE_CHILD_ID_RESPONSE -from pktverify.packet_verifier import PacketVerifier - -LEADER = 1 -ROUTER = 2 - - -class Cert_5_8_2_KeyIncrement(thread_cert.TestCase): - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [ROUTER] - }, - ROUTER: { - 'name': 'ROUTER', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), "leader") - - self.nodes[ROUTER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER].get_state(), "router") - - self.collect_ipaddrs() - addrs = self.nodes[ROUTER].get_addrs() - for addr in addrs: - if addr[0:4] != 'fe80': - self.assertTrue(self.nodes[LEADER].ping(addr)) - - key_sequence_counter = self.nodes[LEADER].get_key_sequence_counter() - self.nodes[LEADER].set_key_sequence_counter(key_sequence_counter + 1) - - addrs = self.nodes[ROUTER].get_addrs() - for addr in addrs: - if addr[0:4] != 'fe80': - self.assertTrue(self.nodes[LEADER].ping(addr)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - ROUTER = pv.vars['ROUTER'] - leader_pkts = pkts.filter_wpan_src64(LEADER) - router_pkts = pkts.filter_wpan_src64(ROUTER) - - # Step 1: The DUT must start the network using - # thrKeySequenceCounter = 0 - leader_pkts.filter_mle_cmd(MLE_ADVERTISEMENT).must_next().must_verify(lambda p: p.wpan.aux_sec.key_source == 0) - - # Step 2: Verify that the topology described above is created. - # MLE Auxiliary security header shall contain Key Source = 0, - # KeyIndex = 1, KeyID Mode = 2 - leader_pkts.filter_mle_cmd(MLE_CHILD_ID_RESPONSE).must_next() - _lpkts = leader_pkts.copy() - _rpkts = router_pkts.range(leader_pkts.index) - - _rpkts.filter_mle_cmd( - MLE_ADVERTISEMENT).must_next().must_verify(lambda p: p.wpan.aux_sec.key_index == 1 and p.wpan.aux_sec. - key_id_mode == 2 and p.wpan.aux_sec.key_source == 0) - - # Step 3: Leader send an ICMPv6 Echo Request to Router_1. - # The MAC Auxiliary security header must contain - # KeyIndex = 1, KeyID Mode = 1 - leader_mleid = pv.vars['LEADER_MLEID'] - router_mleid = pv.vars['ROUTER_MLEID'] - _lpkts.filter(lambda p: p.ipv6.dst == router_mleid).filter_ping_request().must_next().must_verify( - lambda p: p.wpan.aux_sec.key_index == 1 and p.wpan.aux_sec.key_id_mode == 1) - - # Step 4: Router_1 send an ICMPv6 Echo Reply to Leader. - # The MAC Auxiliary security header must contain - # KeyIndex = 1, KeyID Mode = 1 - _rpkts.filter(lambda p: p.ipv6.dst == leader_mleid).filter_ping_reply().must_next().must_verify( - lambda p: p.wpan.aux_sec.key_index == 1 and p.wpan.aux_sec.key_id_mode == 1) - - # Step 5: The DUT MUST set incoming frame counters to 0 for all existing devices. - # Step 6: Leader Send an ICMPv6 Echo Request to Router_1. - # The MAC Auxiliary security header must contain - # KeyIndex = 2, KeyID Mode = 1 - _lpkts.filter(lambda p: p.ipv6.dst == router_mleid).filter_ping_request().must_next().must_verify( - lambda p: p.wpan.aux_sec.key_index == 2 and p.wpan.aux_sec.key_id_mode == 1) - - # Step 7: Router_1 send an ICMPv6 Echo Reply to Leader. - # The MAC Auxiliary security header must contain - # KeyIndex = 2, KeyID Mode = 1 - _rpkts.filter(lambda p: p.ipv6.dst == leader_mleid).filter_ping_reply().must_next().must_verify( - lambda p: p.wpan.aux_sec.key_index == 2 and p.wpan.aux_sec.key_id_mode == 1) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_8_03_KeyIncrementRollOver.py b/tests/scripts/thread-cert/Cert_5_8_03_KeyIncrementRollOver.py deleted file mode 100755 index 68a2bd7a4..000000000 --- a/tests/scripts/thread-cert/Cert_5_8_03_KeyIncrementRollOver.py +++ /dev/null @@ -1,134 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import thread_cert -from pktverify.consts import MLE_ADVERTISEMENT, MLE_CHILD_ID_RESPONSE -from pktverify.packet_verifier import PacketVerifier - -LEADER = 1 -ROUTER = 2 - - -class Cert_5_8_3_KeyIncrementRollOver(thread_cert.TestCase): - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'key_sequence_counter': 127, - 'mode': 'rdn', - 'allowlist': [ROUTER] - }, - ROUTER: { - 'name': 'ROUTER', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[ROUTER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER].get_state(), 'router') - - self.collect_ipaddrs() - addrs = self.nodes[ROUTER].get_addrs() - for addr in addrs: - if addr[0:4] != 'fe80': - self.assertTrue(self.nodes[LEADER].ping(addr)) - - key_sequence_counter = self.nodes[LEADER].get_key_sequence_counter() - self.nodes[LEADER].set_key_sequence_counter(key_sequence_counter + 1) - - addrs = self.nodes[ROUTER].get_addrs() - for addr in addrs: - if addr[0:4] != 'fe80': - self.assertTrue(self.nodes[LEADER].ping(addr)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - ROUTER = pv.vars['ROUTER'] - leader_pkts = pkts.filter_wpan_src64(LEADER) - router_pkts = pkts.filter_wpan_src64(ROUTER) - - # Step 1: The DUT must start the network using - # thrKeySequenceCounter = 127 - _lpkts = leader_pkts.filter_mle_cmd(MLE_ADVERTISEMENT).must_next() - self.assertTrue(_lpkts.wpan.aux_sec.key_source == 127) - - # Step 2: Verify that the topology described above is created. - # MLE Auxiliary security header shall contain Key Source = 127, - # KeyIndex = 128, KeyID Mode = 2 - leader_pkts.filter_mle_cmd(MLE_CHILD_ID_RESPONSE).must_next() - _lpkts = leader_pkts.copy() - _rpkts = router_pkts.range(leader_pkts.index) - - _rpkts.filter_mle_cmd( - MLE_ADVERTISEMENT).must_next().must_verify(lambda p: p.wpan.aux_sec.key_index == 128 and p.wpan.aux_sec. - key_id_mode == 2 and p.wpan.aux_sec.key_source == 127) - - # Step 3: Leader send an ICMPv6 Echo Request to Router_1. - # The MAC Auxiliary security header must contain - # KeyIndex = 128, KeyID Mode = 1 - leader_mleid = pv.vars['LEADER_MLEID'] - router_mleid = pv.vars['ROUTER_MLEID'] - _lpkts.filter(lambda p: p.ipv6.dst == router_mleid).filter_ping_request().must_next().must_verify( - lambda p: p.wpan.aux_sec.key_index == 128 and p.wpan.aux_sec.key_id_mode == 1) - - # Step 4: Router_1 send an ICMPv6 Echo Reply to Leader. - # The MAC Auxiliary security header must contain - # KeyIndex = 128, KeyID Mode = 1 - _rpkts.filter(lambda p: p.ipv6.dst == leader_mleid).filter_ping_reply().must_next().must_verify( - lambda p: p.wpan.aux_sec.key_index == 128 and p.wpan.aux_sec.key_id_mode == 1) - - # Step 5: The DUT MUST implementation specific means increment - # thrKeySequenceCounter by 1 to force a key switch - # Step 6: Leader Send an ICMPv6 Echo Request to Router_1. - # The MAC Auxiliary security header must contain - # KeyIndex = 1, KeyID Mode = 1 - _lpkts.filter(lambda p: p.ipv6.dst == router_mleid).filter_ping_request().must_next().must_verify( - lambda p: p.wpan.aux_sec.key_index == 1 and p.wpan.aux_sec.key_id_mode == 1) - - # Step 7: Router_1 send an ICMPv6 Echo Reply to Leader. - # The MAC Auxiliary security header must contain - # KeyIndex = 1, KeyID Mode = 1 - _rpkts.filter(lambda p: p.ipv6.dst == leader_mleid).filter_ping_reply().must_next().must_verify( - lambda p: p.wpan.aux_sec.key_index == 1 and p.wpan.aux_sec.key_id_mode == 1) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_5_8_04_SecurityPolicyTLV.py b/tests/scripts/thread-cert/Cert_5_8_04_SecurityPolicyTLV.py deleted file mode 100755 index 328206bb1..000000000 --- a/tests/scripts/thread-cert/Cert_5_8_04_SecurityPolicyTLV.py +++ /dev/null @@ -1,415 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2020, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -from mesh_cop import TlvType -import config -import thread_cert -from pktverify.consts import MLE_DATA_RESPONSE, MGMT_ACTIVE_SET_URI, MGMT_ACTIVE_GET_URI, LEADER_ALOC, NM_COMMISSIONER_SESSION_ID_TLV, NM_ACTIVE_TIMESTAMP_TLV, NM_SECURITY_POLICY_TLV, NM_NETWORK_KEY_TLV, MLE_DISCOVERY_RESPONSE -from pktverify.packet_verifier import PacketVerifier -from pktverify.layer_fields import nullField -from pktverify.bytes import Bytes - -LEADER = 1 -COMMISSIONER_1 = 2 -COMMISSIONER_2 = 3 -THREAD_NODE = 4 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to verify network behavior when Security -# Policy TLV “O”,”N”,”R”,”B” bits are disabled. “C” bit is not tested as it -# requires an External Commissioner which is currently not part of Thread -# Certification. -# -# Notes: Due to the packet parsing compatible issue for supporting Thread 1.2 -# and 1.1, the security policy values can be fetched only in the unknown -# field. -# -# Test Topology: -# ------------- -# Leader ---- Commissioner_2 -# Thread_Node | -# Commissioner_1 -# -# Notes: Commissioner_2 is introduced in Step 10 and powoff -# Thread_Node sends scan beacon -# -# DUT Types: -# ---------- -# Leader - - -class Cert_5_8_04_SecurityPolicyTLV(thread_cert.TestCase): - SUPPORT_NCP = False - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - LEADER: { - 'name': 'LEADER', - 'active_dataset': { - 'timestamp': 1, - 'channel': 19, - 'network_key': '00112233445566778899aabbccddeeff', - 'security_policy': [3600, 'onrc'] - }, - 'mode': 'rdn', - }, - COMMISSIONER_1: { - 'name': 'COMMISSIONER_1', - 'active_dataset': { - 'timestamp': 1, - 'channel': 19, - 'network_key': '00112233445566778899aabbccddeeff', - 'security_policy': [3600, 'onrc'] - }, - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - COMMISSIONER_2: { - 'name': 'COMMISSIONER_2', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - THREAD_NODE: { - 'name': 'THREAD_NODE', - 'active_dataset': { - 'timestamp': 1, - 'channel': 19, - 'network_key': '00112233445566778899aabbccddeeff', - 'security_policy': [3600, 'onrc'] - }, - 'mode': 'rdn', - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[COMMISSIONER_1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[COMMISSIONER_1].get_state(), 'router') - - self.nodes[COMMISSIONER_1].commissioner_start() - self.simulator.go(5) - self.nodes[COMMISSIONER_1].commissioner_add_joiner('*', 'PSKD01') - - self.collect_rlocs() - leader_rloc = self.nodes[LEADER].get_rloc() - - # Step 2 - self.nodes[COMMISSIONER_1].send_mgmt_active_get() - self.simulator.go(5) - - # Step 5 - # Disabling O-Bit security_policy = [3600, 0b01110000] - self.nodes[COMMISSIONER_1].send_mgmt_active_set( - active_timestamp=15, - security_policy=[3600, 'nrc'], - ) - self.simulator.go(5) - - # Step 7 - # Get NetworkKey - self.nodes[COMMISSIONER_1].send_mgmt_active_get(leader_rloc, [TlvType.NETWORK_KEY]) - self.simulator.go(5) - - # Step 9 - # Disabling N-Bit security_policy = [3600, 0b10110000] - self.nodes[COMMISSIONER_1].send_mgmt_active_set( - active_timestamp=20, - security_policy=[3600, 'orc'], - ) - self.simulator.go(5) - - # Step 10 - # Add Native Commissioner - self.nodes[COMMISSIONER_2].interface_up() - self.nodes[COMMISSIONER_2].joiner_start('10DKSP') - self.simulator.go(5) - self.nodes[COMMISSIONER_2].reset() - - # Step 13 - # Disabling B-Bit security_policy = [3600, 0b11110000] - self.nodes[COMMISSIONER_1].send_mgmt_active_set( - active_timestamp=25, - security_policy=[3600, 'onrc'], - ) - self.simulator.go(5) - - # Step 15 - # send beacons - self.nodes[THREAD_NODE].start() - self.simulator.go(2) - self.nodes[THREAD_NODE].scan(result=0) - self.simulator.go(20) - - # Step 17 - # Disabling R-Bit security_policy = [3600, 0b11010000] - self.nodes[COMMISSIONER_1].send_mgmt_active_set( - active_timestamp=30, - security_policy=[3600, 'onc'], - ) - self.simulator.go(5) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_RLOC = pv.vars['LEADER_RLOC'] - COMMISSIONER_1 = pv.vars['COMMISSIONER_1'] - COMMISSIONER_1_RLOC = pv.vars['COMMISSIONER_1_RLOC'] - COMMISSIONER_2 = pv.vars['COMMISSIONER_2'] - - # Step 1: Ensure the topology is formed correctly - pv.verify_attached('COMMISSIONER_1', 'LEADER') - - # Step 2: Commissioner_1 sends MGMT_ACTIVE_GET.req to Leader - # CoAP Request URI - # coap://[]:MM/c/ag - # CoAP Payload - # - pkts.filter_wpan_src64(COMMISSIONER_1).\ - filter_ipv6_2dsts(LEADER_RLOC, LEADER_ALOC).\ - filter_coap_request(MGMT_ACTIVE_GET_URI).\ - filter(lambda p: p.thread_meshcop.tlv.type is nullField).\ - must_next() - - # Step 3: Leader MUST send MGMT_ACTIVE_GET.rsp to the Commissioner_1 - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # Security Policy TLV - # Bits “O”,”N”,”R”,”C” should be set to 1 - pkts.filter_wpan_src64(LEADER).\ - filter_ipv6_dst(COMMISSIONER_1_RLOC).\ - filter_coap_ack(MGMT_ACTIVE_GET_URI).\ - filter(lambda p: (p.thread_meshcop.tlv.sec_policy_rot == 3600 and - p.thread_meshcop.tlv.sec_policy_o == 1 and - p.thread_meshcop.tlv.sec_policy_n == 1 and - p.thread_meshcop.tlv.sec_policy_r == 1 and - p.thread_meshcop.tlv.sec_policy_c == 1) or - (p.thread_meshcop.tlv.unknown == '0e10f7')).\ - must_next() - - # Step 5: Commissioner_1 sends MGMT_ACTIVE_SET.req to Leader - # CoAP Request URI - # coap://[]:MM/c/as - # CoAP Payload - # Commissioner Session ID TLV - # Active Timestamp TLV > stored value in step 4 - # Security Policy TLV with “O” bit disabled - pkts.filter_wpan_src64(COMMISSIONER_1). \ - filter_ipv6_2dsts(LEADER_RLOC, LEADER_ALOC). \ - filter_coap_request(MGMT_ACTIVE_SET_URI). \ - filter(lambda p: { - NM_COMMISSIONER_SESSION_ID_TLV, - NM_ACTIVE_TIMESTAMP_TLV, - NM_SECURITY_POLICY_TLV - } <= set(p.thread_meshcop.tlv.type) and\ - p.thread_meshcop.tlv.active_tstamp == 15 and\ - (p.thread_meshcop.tlv.sec_policy_o == 0 or - p.thread_meshcop.tlv.unknown == '0e1077')).\ - must_next() - - # Step 6: Leader MUST send MGMT_ACTIVE_SET.rsp to the Commissioner_1 - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # State TLV (value = Accept (0x01)) - pkts.filter_wpan_src64(LEADER).\ - filter_ipv6_dst(COMMISSIONER_1_RLOC).\ - filter_coap_ack(MGMT_ACTIVE_SET_URI).\ - filter(lambda p: p.thread_meshcop.tlv.state == 1).\ - must_next() - - # Step 7: Commissioner_1 sends MGMT_ACTIVE_GET.req to Leader - # CoAP Request URI - # coap://[]:MM/c/ag - # CoAP Payload - # Network Key TLV - pkts.filter_wpan_src64(COMMISSIONER_1).\ - filter_ipv6_2dsts(LEADER_RLOC, LEADER_ALOC).\ - filter_coap_request(MGMT_ACTIVE_GET_URI).\ - filter(lambda p: NM_NETWORK_KEY_TLV in p.thread_meshcop.tlv.type).\ - must_next() - - # Step 8: Leader MUST send MGMT_ACTIVE_GET.rsp to the Commissioner_1 - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # Network Key TLV MUST NOT be included - pkts.filter_wpan_src64(LEADER).\ - filter_ipv6_dst(COMMISSIONER_1_RLOC).\ - filter_coap_ack(MGMT_ACTIVE_GET_URI).\ - filter(lambda p: p.thread_meshcop.tlv.type is nullField).\ - must_next() - - # Step 9: Commissioner_1 sends MGMT_ACTIVE_SET.req to Leader - # CoAP Request URI - # coap://[]:MM/c/as - # CoAP Payload - # Commissioner Session ID TLV - # Active Timestamp TLV > stored value in step 5 - # Security Policy TLV with “N” bit disabled - pkts.filter_wpan_src64(COMMISSIONER_1). \ - filter_ipv6_2dsts(LEADER_RLOC, LEADER_ALOC). \ - filter_coap_request(MGMT_ACTIVE_SET_URI). \ - filter(lambda p: { - NM_COMMISSIONER_SESSION_ID_TLV, - NM_ACTIVE_TIMESTAMP_TLV, - NM_SECURITY_POLICY_TLV - } <= set(p.thread_meshcop.tlv.type) and\ - p.thread_meshcop.tlv.active_tstamp == 20 and\ - (p.thread_meshcop.tlv.sec_policy_n == 0 or - p.thread_meshcop.tlv.unknown == '0e10b7')).\ - must_next() - - # Step 10: Leader MUST send MGMT_ACTIVE_SET.rsp to the Commissioner_1 - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # State TLV (value = Accept (0x01)) - pkts.filter_wpan_src64(LEADER).\ - filter_ipv6_dst(COMMISSIONER_1_RLOC).\ - filter_coap_ack(MGMT_ACTIVE_SET_URI).\ - filter(lambda p: p.thread_meshcop.tlv.state == 1).\ - must_next() - - # Step 12: Leader MUST send a Discovery Response with Native Commissioning - # bit set to “Not Allowed” - pkts.filter_wpan_src64(LEADER).\ - filter_mle_cmd(MLE_DISCOVERY_RESPONSE).\ - filter(lambda p: p.thread_meshcop.tlv.discovery_rsp_n == 0).\ - must_next() - - # Step 13: Commissioner_1 sends MGMT_ACTIVE_SET.req to Leader - # CoAP Request URI - # coap://[]:MM/c/as - # CoAP Payload - # Commissioner Session ID TLV - # Active Timestamp TLV > stored value in step 9 - # Security Policy TLV with “B” bit disabled - pkts.filter_wpan_src64(COMMISSIONER_1). \ - filter_ipv6_2dsts(LEADER_RLOC, LEADER_ALOC). \ - filter_coap_request(MGMT_ACTIVE_SET_URI). \ - filter(lambda p: { - NM_COMMISSIONER_SESSION_ID_TLV, - NM_ACTIVE_TIMESTAMP_TLV, - NM_SECURITY_POLICY_TLV - } <= set(p.thread_meshcop.tlv.type) and\ - p.thread_meshcop.tlv.active_tstamp == 25 and\ - (p.thread_meshcop.tlv.sec_policy_b == 0 or - p.thread_meshcop.tlv.unknown == '0e10f7')).\ - must_next() - - # Step 14: Leader MUST send MGMT_ACTIVE_SET.rsp to the Commissioner_1 - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # State TLV (value = Accept (0x01)) - pkts.filter_wpan_src64(LEADER).\ - filter_ipv6_dst(COMMISSIONER_1_RLOC).\ - filter_coap_ack(MGMT_ACTIVE_SET_URI).\ - filter(lambda p: p.thread_meshcop.tlv.state == 1).\ - must_next() - - # Step 16: The DUT MUST send beacon response frames.The beacon payload MUST - # either be empty OR the payload format MUST be different from the - # Thread Beacon payload The Protocol ID and Version field values - # MUST be different from the values specified for the Thread beacon - # (Protocol ID= 3, Version = 2) - pkts.filter_wpan_src64(LEADER).\ - filter_wpan_beacon().\ - filter(lambda p: - (p.thread_bcn.protocol is nullField or\ - p.thread_bcn.protocol != 3) and\ - (p.thread_bcn.version is nullField or\ - p.thread_bcn.version != 2) - ).\ - must_next() - - # Step 17: Commissioner_1 sends MGMT_ACTIVE_SET.req to Leader - # CoAP Request URI - # coap://[]:MM/c/as - # CoAP Payload - # Commissioner Session ID TLV - # Active Timestamp TLV > stored value in step 9 - # Security Policy TLV with “R” bit disabled - pkts.filter_wpan_src64(COMMISSIONER_1). \ - filter_ipv6_2dsts(LEADER_RLOC, LEADER_ALOC). \ - filter_coap_request(MGMT_ACTIVE_SET_URI). \ - filter(lambda p: { - NM_COMMISSIONER_SESSION_ID_TLV, - NM_ACTIVE_TIMESTAMP_TLV, - NM_SECURITY_POLICY_TLV - } <= set(p.thread_meshcop.tlv.type) and\ - p.thread_meshcop.tlv.active_tstamp == 30 and\ - (p.thread_meshcop.tlv.sec_policy_r == 0 or - p.thread_meshcop.tlv.unknown == '0e10d7')).\ - must_next() - - # Step 18: Leader MUST send MGMT_ACTIVE_SET.rsp to the Commissioner_1 - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # State TLV (value = Accept (0x01)) - # Leader MUST multicast MLE Data Response to the Link-Local All Nodes - # multicast address (FF02::1) with active timestamp value as set in - # Step 17. - pkts.filter_wpan_src64(LEADER).\ - filter_ipv6_dst(COMMISSIONER_1_RLOC).\ - filter_coap_ack(MGMT_ACTIVE_SET_URI).\ - filter(lambda p: p.thread_meshcop.tlv.state == 1).\ - must_next() - pkts.filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter(lambda p: p.mle.tlv.active_tstamp == 30).\ - must_next() - - # Step 20: The DUT MUST send a unicast MLE Data Response to Commissioner_1. - # The Active Operational Set MUST contain a Security Policy TLV with - # R bit set to 0. - pkts.filter_wpan_src64(LEADER).\ - filter_wpan_dst64(COMMISSIONER_1). \ - filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter(lambda p: - p.mle.tlv.active_tstamp == 30 and\ - (p.thread_meshcop.tlv.sec_policy_r == 0 or - p.thread_meshcop.tlv.unknown == '0e10d7')).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_9_2_01_MGMTCommissionerGet.py b/tests/scripts/thread-cert/Cert_9_2_01_MGMTCommissionerGet.py deleted file mode 100755 index 9a2226a8d..000000000 --- a/tests/scripts/thread-cert/Cert_9_2_01_MGMTCommissionerGet.py +++ /dev/null @@ -1,279 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2020, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import thread_cert -from pktverify.consts import MLE_DATA_RESPONSE, MGMT_COMMISSIONER_GET_URI, NM_CHANNEL_TLV, NM_COMMISSIONER_ID_TLV, NM_COMMISSIONER_SESSION_ID_TLV, NM_STEERING_DATA_TLV, NM_BORDER_AGENT_LOCATOR_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV, SOURCE_ADDRESS_TLV, NWD_COMMISSIONING_DATA_TLV, NM_PAN_ID_TLV, NM_NETWORK_NAME_TLV -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -COMMISSIONER = 1 -LEADER = 2 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to verify Leader's and active Commissioner's behavior via -# MGMT_COMMISSIONER_GET request and response -# -# Test Topology: -# ------------- -# Commissioner -# | -# Leader -# -# DUT Types: -# ---------- -# Leader -# Commissioner - - -class Cert_9_2_01_MGMTCommissionerGet(thread_cert.TestCase): - SUPPORT_NCP = False - USE_MESSAGE_FACTORY = True - - TOPOLOGY = { - COMMISSIONER: { - 'name': 'COMMISSIONER', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [COMMISSIONER] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[COMMISSIONER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'router') - - self.collect_leader_aloc(LEADER) - self.collect_rlocs() - self.collect_rloc16s() - - self.nodes[COMMISSIONER].commissioner_start() - self.simulator.go(3) - - self.nodes[COMMISSIONER].commissioner_mgmtget() - self.simulator.go(5) - - self.nodes[COMMISSIONER].commissioner_mgmtget('0b08') - self.simulator.go(5) - - self.nodes[COMMISSIONER].commissioner_mgmtget('0b01') - self.simulator.go(5) - - self.nodes[COMMISSIONER].commissioner_mgmtget('0903') - self.simulator.go(5) - - leader_rloc = self.nodes[LEADER].get_rloc() - commissioner_rloc = self.nodes[COMMISSIONER].get_rloc() - self.assertTrue(self.nodes[COMMISSIONER].ping(leader_rloc)) - self.simulator.go(1) - self.assertTrue(self.nodes[LEADER].ping(commissioner_rloc)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_ALOC = pv.vars['LEADER_ALOC'] - LEADER_RLOC = pv.vars['LEADER_RLOC'] - COMMISSIONER = pv.vars['COMMISSIONER'] - COMMISSIONER_RLOC = pv.vars['COMMISSIONER_RLOC'] - - # Step 1: Ensure topology is formed correctly - pv.verify_attached('COMMISSIONER', 'LEADER') - - # Step 2: Commissioner sends a MGMT_COMMISSIONER_GET.req to Leader Anycast - # or Routing Locator: - # CoAP Request URI - # CON POST coap://:MM/c/cg - # CoAP Payload - # - get all Commissioner Dataset parameters - _pkt = pkts.filter_wpan_src64(COMMISSIONER).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_COMMISSIONER_GET_URI).\ - filter(lambda p: p.coap.tlv.type is nullField).\ - must_next() - - # Step 3: Leader sends a MGMT_COMMISSIONER_GET.rsp to Commissioner with - # the following format: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # (entire Commissioner Dataset) - # Border Agent Locator TLV - # Commissioner Session ID TLV - # Steering Data TLV - pkts.filter_ipv6_src_dst(_pkt.ipv6.dst, COMMISSIONER_RLOC).\ - filter_coap_ack(MGMT_COMMISSIONER_GET_URI).\ - filter(lambda p: { - NM_COMMISSIONER_SESSION_ID_TLV, - NM_BORDER_AGENT_LOCATOR_TLV, - NM_STEERING_DATA_TLV - } <= set(p.thread_meshcop.tlv.type) and\ - p.thread_meshcop.tlv.ba_locator is not nullField and\ - p.thread_meshcop.tlv.commissioner_sess_id is not nullField and\ - p.thread_meshcop.tlv.steering_data is not nullField - ).\ - must_next() - - # Step 4: Commissioner sends a MGMT_COMMISSIONER_GET.req to Leader Anycast - # or Routing Locator: - # CoAP Request URI - # CON POST coap://:MM/c/cg - # CoAP Payload - # Commissioner Session ID TLV - # Steering Data TLV - _mgmt_get_pkt = pkts.filter_wpan_src64(COMMISSIONER).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_COMMISSIONER_GET_URI).\ - filter(lambda p: { - NM_COMMISSIONER_SESSION_ID_TLV, - NM_STEERING_DATA_TLV - } <= set(p.thread_meshcop.tlv.type) - ).\ - must_next() - - # Step 5: Leader sends a MGMT_COMMISSIONER_GET.rsp to Commissioner with - # the following format: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # Encoded values for the requested Commissioner Dataset parameters - # Commissioner Session ID TLV - # Steering Data TLV - pkts.filter_ipv6_src_dst(_mgmt_get_pkt.ipv6.dst, COMMISSIONER_RLOC).\ - filter_coap_ack(MGMT_COMMISSIONER_GET_URI).\ - filter(lambda p: { - NM_COMMISSIONER_SESSION_ID_TLV, - NM_STEERING_DATA_TLV - } <= set(p.thread_meshcop.tlv.type) and\ - p.thread_meshcop.tlv.commissioner_sess_id is not nullField and\ - p.thread_meshcop.tlv.steering_data is not nullField - ).\ - must_next() - - # Step 6: Commissioner sends a MGMT_COMMISSIONER_GET.req to Leader Anycast - # or Routing Locator: - # CoAP Request URI - # CON POST coap://:MM/c/cg - # CoAP Payload - # Commissioner Session ID TLV - # PAN ID TLV - _mgmt_get_pkt = pkts.filter_wpan_src64(COMMISSIONER).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_COMMISSIONER_GET_URI).\ - filter(lambda p: { - NM_COMMISSIONER_SESSION_ID_TLV, - NM_PAN_ID_TLV - } <= set(p.thread_meshcop.tlv.type) - ).\ - must_next() - - # Step 7: Leader sends a MGMT_COMMISSIONER_GET.rsp to Commissioner with - # the following format: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # Encoded values for the requested Commissioner Dataset parameters - # Commissioner Session ID TLV - # (PAN ID TLV in Get TLV is ignored) - pkts.filter_ipv6_src_dst(_mgmt_get_pkt.ipv6.dst, COMMISSIONER_RLOC).\ - filter_coap_ack(MGMT_COMMISSIONER_GET_URI).\ - filter(lambda p: { - NM_COMMISSIONER_SESSION_ID_TLV - } <= set(p.thread_meshcop.tlv.type) and\ - p.thread_meshcop.tlv.commissioner_sess_id is not nullField and\ - p.thread_meshcop.tlv.pan_id is nullField - ).\ - must_next() - - # Step 8: Commissioner sends a MGMT_COMMISSIONER_GET.req to Leader Anycast - # or Routing Locator: - # CoAP Request URI - # CON POST coap://:MM/c/cg - # CoAP Payload - # Border Agent Locator TLV - # Network Name TLV - _mgmt_get_pkt = pkts.filter_wpan_src64(COMMISSIONER).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_COMMISSIONER_GET_URI).\ - filter(lambda p: { - NM_BORDER_AGENT_LOCATOR_TLV, - NM_NETWORK_NAME_TLV - } <= set(p.thread_meshcop.tlv.type) - ).\ - must_next() - - # Step 9: Leader sends a MGMT_COMMISSIONER_GET.rsp to Commissioner with - # the following format: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # Encoded values for the requested Commissioner Dataset parameters - # Border Agent Locator TLV - # (Network Name TLV in Get TLV is ignored) - pkts.filter_ipv6_src_dst(_mgmt_get_pkt.ipv6.dst, COMMISSIONER_RLOC).\ - filter_coap_ack(MGMT_COMMISSIONER_GET_URI).\ - filter(lambda p: { - NM_BORDER_AGENT_LOCATOR_TLV - } <= set(p.thread_meshcop.tlv.type) and\ - p.thread_meshcop.tlv.ba_locator is not nullField and\ - p.thread_meshcop.tlv.net_name is nullField - ).\ - must_next() - - # Step 10: Verify connectivity by sending an ICMPv6 Echo Request to the DUT mesh local address - _pkt = pkts.filter_ping_request().\ - filter_ipv6_src_dst(COMMISSIONER_RLOC, LEADER_RLOC).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(LEADER_RLOC, COMMISSIONER_RLOC).\ - must_next() - - _pkt = pkts.filter_ping_request().\ - filter_ipv6_src_dst(LEADER_RLOC, COMMISSIONER_RLOC).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(COMMISSIONER_RLOC, LEADER_RLOC).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_9_2_02_MGMTCommissionerSet.py b/tests/scripts/thread-cert/Cert_9_2_02_MGMTCommissionerSet.py deleted file mode 100755 index ea6e4ef36..000000000 --- a/tests/scripts/thread-cert/Cert_9_2_02_MGMTCommissionerSet.py +++ /dev/null @@ -1,385 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2019, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import command -import config -import mesh_cop -import thread_cert -from pktverify.consts import MLE_DATA_RESPONSE, LEAD_PET_URI, LEAD_KA_URI, MGMT_COMMISSIONER_SET_URI, NM_CHANNEL_TLV, NM_COMMISSIONER_ID_TLV, NM_COMMISSIONER_SESSION_ID_TLV, NM_STATE_TLV, NM_STEERING_DATA_TLV, NM_BORDER_AGENT_LOCATOR_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV, SOURCE_ADDRESS_TLV, NWD_COMMISSIONING_DATA_TLV, MESHCOP_ACCEPT, MESHCOP_REJECT, LEADER_ALOC -from pktverify.packet_verifier import PacketVerifier -from pktverify.bytes import Bytes - -COMMISSIONER = 1 -LEADER = 2 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to verify Leader's and active Commissioner's behavior via -# MGMT_COMMISSIONER_SET request and response -# -# Test Topology: -# ------------- -# Commissioner -# | -# Leader -# -# DUT Types: -# ---------- -# Leader -# Commissioner - - -class Cert_9_2_02_MGMTCommissionerSet(thread_cert.TestCase): - SUPPORT_NCP = False - - TOPOLOGY = { - COMMISSIONER: { - 'name': 'COMMISSIONER', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [COMMISSIONER] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[COMMISSIONER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'router') - self.simulator.get_messages_sent_by(LEADER) - - self.collect_rlocs() - self.collect_rloc16s() - - self.nodes[COMMISSIONER].commissioner_start() - self.simulator.go(3) - - leader_messages = self.simulator.get_messages_sent_by(LEADER) - msg = leader_messages.next_coap_message('2.04', assert_enabled=True) - commissioner_session_id_tlv = command.get_sub_tlv(msg.coap.payload, mesh_cop.CommissionerSessionId) - - steering_data_tlv = mesh_cop.SteeringData(bytes([0xff])) - self.nodes[COMMISSIONER].commissioner_mgmtset_with_tlvs([steering_data_tlv]) - self.simulator.go(5) - - self.nodes[COMMISSIONER].commissioner_mgmtset_with_tlvs([steering_data_tlv, commissioner_session_id_tlv]) - self.simulator.go(5) - - border_agent_locator_tlv = mesh_cop.BorderAgentLocator(0x0400) - self.nodes[COMMISSIONER].commissioner_mgmtset_with_tlvs( - [commissioner_session_id_tlv, border_agent_locator_tlv]) - self.simulator.go(5) - - self.nodes[COMMISSIONER].commissioner_mgmtset_with_tlvs([ - steering_data_tlv, - commissioner_session_id_tlv, - border_agent_locator_tlv, - ]) - self.simulator.go(5) - - self.nodes[COMMISSIONER].commissioner_mgmtset_with_tlvs( - [mesh_cop.CommissionerSessionId(0xffff), steering_data_tlv]) - self.simulator.go(5) - - self.nodes[COMMISSIONER].commissioner_mgmtset_with_tlvs([ - commissioner_session_id_tlv, - steering_data_tlv, - mesh_cop.Channel(0x0, 0x0), - ]) - self.simulator.go(5) - - leader_rloc = self.nodes[LEADER].get_rloc() - commissioner_rloc = self.nodes[COMMISSIONER].get_rloc() - self.assertTrue(self.nodes[COMMISSIONER].ping(leader_rloc)) - self.simulator.go(1) - self.assertTrue(self.nodes[LEADER].ping(commissioner_rloc)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_RLOC = pv.vars['LEADER_RLOC'] - LEADER_RLOC16 = pv.vars['LEADER_RLOC16'] - COMMISSIONER = pv.vars['COMMISSIONER'] - COMMISSIONER_RLOC = pv.vars['COMMISSIONER_RLOC'] - - # Step 1: Ensure topology is formed correctly - pv.verify_attached('COMMISSIONER', 'LEADER') - - # Step 2: Commissioner sends a Set Commissioner Dataset Request (MGMT_COMMISSIONER_SET.req) - # to Leader Anycast or Routing Locator: - # CoAP Request URI - # CON POST coap://:MM/c/cs - # CoAP Payload - # (missing Commissioner Session ID TLV) - # Steering Data TLV (0xFF) - _mgmt_set_pkt = pkts.filter_wpan_src64(COMMISSIONER).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_COMMISSIONER_SET_URI).\ - filter(lambda p: - [NM_STEERING_DATA_TLV] == p.coap.tlv.type and\ - p.thread_meshcop.tlv.steering_data == Bytes('ff') - ).\ - must_next() - - # Step 3: Leader sends a Set Commissioner Dataset Response (MGMT_COMMISSIONER_SET.rsp) to - # Commissioner: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # State TLV (value = Reject) - pkts.filter_ipv6_src_dst(_mgmt_set_pkt.ipv6.dst, COMMISSIONER_RLOC).\ - filter_coap_ack(MGMT_COMMISSIONER_SET_URI).\ - filter(lambda p: - [NM_STATE_TLV] == p.coap.tlv.type and\ - p.thread_meshcop.tlv.state == MESHCOP_REJECT - ).\ - must_next() - - # Step 4: Commissioner sends a Set Commissioner Dataset Request (MGMT_COMMISSIONER_SET.req) - # to Leader Anycast or Routing Locator: - # CoAP Request URI - # CON POST coap://:MM/c/cs - # CoAP Payload - # Commissioner Session ID TLV - # Steering Data TLV (0xFF) - _mgmt_set_pkt = pkts.filter_wpan_src64(COMMISSIONER).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_COMMISSIONER_SET_URI).\ - filter(lambda p: { - NM_COMMISSIONER_SESSION_ID_TLV, - NM_STEERING_DATA_TLV - } <= set(p.thread_meshcop.tlv.type) and\ - p.thread_meshcop.tlv.steering_data == Bytes('ff') - ).\ - must_next() - - # Step 5: Leader sends a Set Commissioner Dataset Response (MGMT_COMMISSIONER_SET.rsp) to - # Commissioner: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # State TLV (value = Accept) - pkts.filter_ipv6_src_dst(_mgmt_set_pkt.ipv6.dst, COMMISSIONER_RLOC).\ - filter_coap_ack(MGMT_COMMISSIONER_SET_URI).\ - filter(lambda p: - [NM_STATE_TLV] == p.coap.tlv.type and\ - p.thread_meshcop.tlv.state == MESHCOP_ACCEPT - ).\ - must_next() - - # Step 6: Leader sends a MLE Data Response to the network with the - # following TLVs: - # - Active Timestamp TLV - # - Leader Data TLV - # - Network Data TLV - # - Source Address TLV - pkts.filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter(lambda p: { - NETWORK_DATA_TLV, - SOURCE_ADDRESS_TLV, - ACTIVE_TIMESTAMP_TLV, - LEADER_DATA_TLV - } <= set(p.mle.tlv.type) and\ - { - NWD_COMMISSIONING_DATA_TLV - } <= set(p.thread_nwd.tlv.type) and\ - { - NM_BORDER_AGENT_LOCATOR_TLV, - NM_COMMISSIONER_SESSION_ID_TLV, - NM_STEERING_DATA_TLV - } <= set(p.thread_meshcop.tlv.type) and\ - p.thread_nwd.tlv.stable == [0] - ).\ - must_next() - - # Step 7: Commissioner sends a Set Commissioner Dataset Request (MGMT_COMMISSIONER_SET.req) - # to Leader Anycast or Routing Locator: - # CoAP Request URI - # CON POST coap://:MM/c/cs - # CoAP Payload - # Commissioner Session ID TLV - # Border Agent Locator TLV (0x0400) (not allowed TLV) - _mgmt_set_pkt = pkts.filter_wpan_src64(COMMISSIONER).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_COMMISSIONER_SET_URI).\ - filter(lambda p: { - NM_COMMISSIONER_SESSION_ID_TLV, - NM_BORDER_AGENT_LOCATOR_TLV - } <= set(p.thread_meshcop.tlv.type) and\ - p.thread_meshcop.tlv.ba_locator == 0x0400 - ).\ - must_next() - - # Step 8: Leader sends a Set Commissioner Dataset Response (MGMT_COMMISSIONER_SET.rsp) to - # Commissioner: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # State TLV (value = Reject) - pkts.filter_ipv6_src_dst(_mgmt_set_pkt.ipv6.dst, COMMISSIONER_RLOC).\ - filter_coap_ack(MGMT_COMMISSIONER_SET_URI).\ - filter(lambda p: - [NM_STATE_TLV] == p.coap.tlv.type and\ - p.thread_meshcop.tlv.state == MESHCOP_REJECT - ).\ - must_next() - - # Step 9: Commissioner sends a Set Commissioner Dataset Request (MGMT_COMMISSIONER_SET.req) - # to Leader Anycast or Routing Locator: - # CoAP Request URI - # CON POST coap://:MM/c/cs - # CoAP Payload - # Commissioner Session ID TLV - # Steering Data TLV (0xFF) - # Border Agent Locator TLV (0x0400) (not allowed TLV) - _mgmt_set_pkt = pkts.filter_wpan_src64(COMMISSIONER).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_COMMISSIONER_SET_URI).\ - filter(lambda p: { - NM_COMMISSIONER_SESSION_ID_TLV, - NM_STEERING_DATA_TLV, - NM_BORDER_AGENT_LOCATOR_TLV - } <= set(p.thread_meshcop.tlv.type) and\ - p.thread_meshcop.tlv.ba_locator == 0x0400 and\ - p.thread_meshcop.tlv.steering_data == Bytes('ff') - ).\ - must_next() - - # Step 10: Leader sends a Set Commissioner Dataset Response (MGMT_COMMISSIONER_SET.rsp) to - # Commissioner: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # State TLV (value = Reject) - pkts.filter_ipv6_src_dst(_mgmt_set_pkt.ipv6.dst, COMMISSIONER_RLOC).\ - filter_coap_ack(MGMT_COMMISSIONER_SET_URI).\ - filter(lambda p: - [NM_STATE_TLV] == p.coap.tlv.type and\ - p.thread_meshcop.tlv.state == MESHCOP_REJECT - ).\ - must_next() - - # Step 11: Commissioner sends a Set Commissioner Dataset Request (MGMT_COMMISSIONER_SET.req) - # to Leader Anycast or Routing Locator: - # CoAP Request URI - # CON POST coap://:MM/c/cs - # CoAP Payload - # Commissioner Session ID TLV (0xFFFF) (invalid value) - # Steering Data TLV (0xFF) - _mgmt_set_pkt = pkts.filter_wpan_src64(COMMISSIONER).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_COMMISSIONER_SET_URI).\ - filter(lambda p: { - NM_COMMISSIONER_SESSION_ID_TLV, - NM_STEERING_DATA_TLV - } <= set(p.thread_meshcop.tlv.type) and\ - p.thread_meshcop.tlv.commissioner_sess_id == 0xFFFF and\ - p.thread_meshcop.tlv.steering_data == Bytes('ff') - ).\ - must_next() - - # Step 12: Leader sends a Set Commissioner Dataset Response (MGMT_COMMISSIONER_SET.rsp) to - # Commissioner: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # State TLV (value = Reject) - pkts.filter_ipv6_src_dst(_mgmt_set_pkt.ipv6.dst, COMMISSIONER_RLOC).\ - filter_coap_ack(MGMT_COMMISSIONER_SET_URI).\ - filter(lambda p: - [NM_STATE_TLV] == p.coap.tlv.type and\ - p.thread_meshcop.tlv.state == MESHCOP_REJECT - ).\ - must_next() - - # Step 13: Commissioner sends a Set Commissioner Dataset Request (MGMT_COMMISSIONER_SET.req) - # to Leader Anycast or Routing Locator: - # CoAP Request URI - # CON POST coap://:MM/c/cs - # CoAP Payload - # Commissioner Session ID TLV - # Steering Data TLV (0xFF) - # Channel TLV (not allowed TLV) - _mgmt_set_pkt = pkts.filter_wpan_src64(COMMISSIONER).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_COMMISSIONER_SET_URI).\ - filter(lambda p: { - NM_COMMISSIONER_SESSION_ID_TLV, - NM_STEERING_DATA_TLV, - NM_CHANNEL_TLV - } <= set(p.thread_meshcop.tlv.type) and\ - p.thread_meshcop.tlv.steering_data == Bytes('ff') - ).\ - must_next() - - # Step 14: Leader sends a Set Commissioner Dataset Response (MGMT_COMMISSIONER_SET.rsp) to - # Commissioner: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # State TLV (value = Accept) - pkts.filter_ipv6_src_dst(_mgmt_set_pkt.ipv6.dst, COMMISSIONER_RLOC).\ - filter_coap_ack(MGMT_COMMISSIONER_SET_URI).\ - filter(lambda p: - [NM_STATE_TLV] == p.coap.tlv.type and\ - p.thread_meshcop.tlv.state == MESHCOP_ACCEPT - ).\ - must_next() - - # Step 15: Verify connectivity by sending an ICMPv6 Echo Request to the DUT mesh local address - _pkt = pkts.filter_ping_request().\ - filter_ipv6_src_dst(COMMISSIONER_RLOC, LEADER_RLOC).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(LEADER_RLOC, COMMISSIONER_RLOC).\ - must_next() - - _pkt = pkts.filter_ping_request().\ - filter_ipv6_src_dst(LEADER_RLOC, COMMISSIONER_RLOC).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(COMMISSIONER_RLOC, LEADER_RLOC).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_9_2_03_ActiveDatasetGet.py b/tests/scripts/thread-cert/Cert_9_2_03_ActiveDatasetGet.py deleted file mode 100755 index 59ab1555a..000000000 --- a/tests/scripts/thread-cert/Cert_9_2_03_ActiveDatasetGet.py +++ /dev/null @@ -1,265 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2020, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import mesh_cop -import thread_cert -from pktverify.consts import MLE_DATA_RESPONSE, MGMT_ACTIVE_GET_URI, NM_CHANNEL_TLV, NM_COMMISSIONER_ID_TLV, NM_COMMISSIONER_SESSION_ID_TLV, NM_STEERING_DATA_TLV, NM_BORDER_AGENT_LOCATOR_TLV, NM_PAN_ID_TLV, NM_NETWORK_NAME_TLV, NM_NETWORK_MESH_LOCAL_PREFIX_TLV, NM_PSKC_TLV, NM_SCAN_DURATION, NM_ENERGY_LIST_TLV, NM_ACTIVE_TIMESTAMP_TLV, NM_CHANNEL_MASK_TLV, NM_EXTENDED_PAN_ID_TLV, NM_NETWORK_KEY_TLV, NM_SECURITY_POLICY_TLV, LEADER_ALOC -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -COMMISSIONER = 1 -LEADER = 2 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to verify Leader's and active Commissioner's behavior via -# MGMT_ACTIVE_GET request and response -# -# Test Topology: -# ------------- -# Commissioner -# | -# Leader -# -# DUT Types: -# ---------- -# Leader -# Commissioner - - -class Cert_9_2_03_ActiveDatasetGet(thread_cert.TestCase): - SUPPORT_NCP = False - USE_MESSAGE_FACTORY = False - - TOPOLOGY = { - COMMISSIONER: { - 'name': 'COMMISSIONER', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [COMMISSIONER] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[COMMISSIONER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'router') - - self.collect_rlocs() - self.collect_rloc16s() - - leader_rloc = self.nodes[LEADER].get_rloc() - - self.nodes[COMMISSIONER].commissioner_start() - self.simulator.go(3) - - self.nodes[COMMISSIONER].send_mgmt_active_get() - self.simulator.go(5) - - self.nodes[COMMISSIONER].send_mgmt_active_get( - leader_rloc, - [mesh_cop.TlvType.CHANNEL_MASK, mesh_cop.TlvType.NETWORK_MESH_LOCAL_PREFIX, mesh_cop.TlvType.NETWORK_NAME]) - self.simulator.go(5) - - self.nodes[COMMISSIONER].send_mgmt_active_get(leader_rloc, [ - mesh_cop.TlvType.CHANNEL, mesh_cop.TlvType.NETWORK_MESH_LOCAL_PREFIX, mesh_cop.TlvType.NETWORK_NAME, - mesh_cop.TlvType.SCAN_DURATION, mesh_cop.TlvType.ENERGY_LIST - ]) - self.simulator.go(5) - - commissioner_rloc = self.nodes[COMMISSIONER].get_rloc() - self.assertTrue(self.nodes[COMMISSIONER].ping(leader_rloc)) - self.simulator.go(1) - self.assertTrue(self.nodes[LEADER].ping(commissioner_rloc)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_RLOC = pv.vars['LEADER_RLOC'] - COMMISSIONER = pv.vars['COMMISSIONER'] - COMMISSIONER_RLOC = pv.vars['COMMISSIONER_RLOC'] - - # Step 1: Ensure topology is formed correctly - pv.verify_attached('COMMISSIONER', 'LEADER') - - # Step 2: Commissioner sends a MGMT_ACTIVE_GET.req to Leader Anycast - # or Routing Locator: - # CoAP Request URI - # CON POST coap://:MM/c/ag - # CoAP Payload - # - get all Active Operational Dataset parameters - _pkt = pkts.filter_wpan_src64(COMMISSIONER).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_ACTIVE_GET_URI).\ - filter(lambda p: p.coap.tlv.type is nullField).\ - must_next() - - # Step 3: Leader sends a MGMT_ACTIVE_GET.rsp to Commissioner with - # the following format: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # (entire Active Operational Dataset) - # Active Timestamp TLV - # Channel TLV - # Channel Mask TLV - # Extended PAN ID TLV - # Network Mesh-Local Prefix TLV - # Network Key TLV - # Network Name TLV - # PAN ID TLV - # PSKc TLV - # Security Policy TLV - pkts.filter_ipv6_src_dst(_pkt.ipv6.dst, COMMISSIONER_RLOC).\ - filter_coap_ack(MGMT_ACTIVE_GET_URI).\ - filter(lambda p: { - NM_ACTIVE_TIMESTAMP_TLV, - NM_CHANNEL_TLV, - NM_CHANNEL_MASK_TLV, - NM_EXTENDED_PAN_ID_TLV, - NM_NETWORK_MESH_LOCAL_PREFIX_TLV, - NM_NETWORK_KEY_TLV, - NM_NETWORK_NAME_TLV, - NM_PAN_ID_TLV, - NM_PSKC_TLV, - NM_SECURITY_POLICY_TLV - } <= set(p.thread_meshcop.tlv.type) - ).\ - must_next() - - # Step 4: Commissioner sends a MGMT_ACTIVE_GET.req to Leader Anycast - # or Routing Locator: - # CoAP Request URI - # CON POST coap://:MM/c/ag - # CoAP Payload - # Channel Mask TLV - # Network Mesh-Local Prefix TLV - # Network Name TLV - pkts.filter_wpan_src64(COMMISSIONER).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_ACTIVE_GET_URI).\ - filter(lambda p: { - NM_CHANNEL_MASK_TLV, - NM_NETWORK_MESH_LOCAL_PREFIX_TLV, - NM_NETWORK_NAME_TLV - } <= set(p.thread_meshcop.tlv.type) - ).\ - must_next() - - # Step 5: Leader sends a MGMT_ACTIVE_GET.rsp to Commissioner with - # the following format: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # Channel Mask TLV - # Network Mesh-Local Prefix TLV - # Network Name TLV - pkts.filter_ipv6_src_dst(LEADER_RLOC, COMMISSIONER_RLOC).\ - filter_coap_ack(MGMT_ACTIVE_GET_URI).\ - filter(lambda p: { - NM_CHANNEL_MASK_TLV, - NM_NETWORK_MESH_LOCAL_PREFIX_TLV, - NM_NETWORK_NAME_TLV - } <= set(p.thread_meshcop.tlv.type) - ).\ - must_next() - - # Step 6: Commissioner sends a MGMT_ACTIVE_GET.req to Leader Anycast - # or Routing Locator: - # CoAP Request URI - # CON POST coap://:MM/c/ag - # CoAP Payload - # Channel TLV - # Network Mesh-Local Prefix TLV - # Network Name TLV - # Scan Duration TLV (not allowed TLV) - # Energy List TLV (not allowed TLV) - pkts.filter_wpan_src64(COMMISSIONER).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_ACTIVE_GET_URI).\ - filter(lambda p: { - NM_CHANNEL_TLV, - NM_NETWORK_MESH_LOCAL_PREFIX_TLV, - NM_NETWORK_NAME_TLV, - NM_SCAN_DURATION, - NM_ENERGY_LIST_TLV - } <= set(p.thread_meshcop.tlv.type) - ).\ - must_next() - - # Step 7: Leader sends a MGMT_ACTIVE_GET.rsp to Commissioner with - # the following format: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # Channel TLV - # Network Mesh-Local Prefix TLV - # Network Name TLV - pkts.filter_ipv6_src_dst(LEADER_RLOC, COMMISSIONER_RLOC).\ - filter_coap_ack(MGMT_ACTIVE_GET_URI).\ - filter(lambda p: { - NM_CHANNEL_TLV, - NM_NETWORK_MESH_LOCAL_PREFIX_TLV, - NM_NETWORK_NAME_TLV, - } <= set(p.thread_meshcop.tlv.type) - ).\ - must_next() - - # Step 8: Verify connectivity by sending an ICMPv6 Echo Request to the - # DUT mesh local address - _pkt = pkts.filter_ping_request().\ - filter_ipv6_src_dst(COMMISSIONER_RLOC, LEADER_RLOC).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(LEADER_RLOC, COMMISSIONER_RLOC).\ - must_next() - - _pkt = pkts.filter_ping_request().\ - filter_ipv6_src_dst(LEADER_RLOC, COMMISSIONER_RLOC).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(COMMISSIONER_RLOC, LEADER_RLOC).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_9_2_04_ActiveDataset.py b/tests/scripts/thread-cert/Cert_9_2_04_ActiveDataset.py deleted file mode 100755 index 01f1f2293..000000000 --- a/tests/scripts/thread-cert/Cert_9_2_04_ActiveDataset.py +++ /dev/null @@ -1,319 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import thread_cert -from pktverify.consts import MLE_CHILD_ID_RESPONSE, MGMT_ACTIVE_SET_URI, MGMT_ACTIVE_GET_URI -from pktverify.packet_verifier import PacketVerifier -from pktverify.bytes import Bytes - -COMMISSIONER = 1 -LEADER = 2 - - -class Cert_9_2_04_ActiveDataset(thread_cert.TestCase): - SUPPORT_NCP = False - - TOPOLOGY = { - COMMISSIONER: { - 'name': 'COMMISSIONER', - 'active_dataset': { - 'timestamp': 10, - 'network_key': '00112233445566778899aabbccddeeff' - }, - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - LEADER: { - 'name': 'LEADER', - 'active_dataset': { - 'timestamp': 10, - 'network_key': '00112233445566778899aabbccddeeff' - }, - 'mode': 'rdn', - 'allowlist': [COMMISSIONER] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[COMMISSIONER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'router') - - self.nodes[COMMISSIONER].commissioner_start() - self.simulator.go(5) - - self.collect_rlocs() - self.collect_leader_aloc(LEADER) - # Step 2 - self.nodes[COMMISSIONER].send_mgmt_active_set( - active_timestamp=101, - channel_mask=0x7fff800, - extended_panid='000db70000000000', - network_name='GRL', - ) - self.simulator.go(5) - self.assertEqual(self.nodes[LEADER].get_network_name(), 'GRL') - self.nodes[COMMISSIONER].send_mgmt_active_get() - self.simulator.go(5) - - # Step 6 - # Attempt to set Channel TLV - self.nodes[COMMISSIONER].send_mgmt_active_set( - active_timestamp=102, - channel=18, - channel_mask=0x7fff800, - extended_panid='000db70000000001', - network_name='threadcert', - ) - self.simulator.go(5) - self.assertEqual(self.nodes[LEADER].get_network_name(), 'GRL') - - # Step 8 - # Attempt to set Mesh Local Prefix TLV - self.nodes[COMMISSIONER].send_mgmt_active_set( - active_timestamp=103, - channel_mask=0x7fff800, - extended_panid='000db70000000000', - mesh_local='fd00:0db7::', - network_name='UL', - ) - self.simulator.go(5) - self.assertEqual(self.nodes[LEADER].get_network_name(), 'GRL') - - # Step 10 - # Attempt to set Network Key TLV - self.nodes[COMMISSIONER].send_mgmt_active_set( - active_timestamp=104, - channel_mask=0x7fff800, - extended_panid='000db70000000000', - network_key='ffeeddccbbaa99887766554433221100', - mesh_local='fd00:0db7::', - network_name='GRL', - ) - self.simulator.go(5) - self.assertEqual(self.nodes[LEADER].get_network_name(), 'GRL') - - # Step 12 - # Attempt to set PAN ID TLV - self.nodes[COMMISSIONER].send_mgmt_active_set( - active_timestamp=105, - channel_mask=0x7fff800, - extended_panid='000db70000000000', - network_key='00112233445566778899aabbccddeeff', - mesh_local='fd00:0db7::', - network_name='UL', - panid=0xafce, - ) - self.simulator.go(5) - self.assertEqual(self.nodes[LEADER].get_network_name(), 'GRL') - - # Step 14 - # Invalid Commissioner Session ID - self.nodes[COMMISSIONER].send_mgmt_active_set( - active_timestamp=106, - channel_mask=0x7fff800, - extended_panid='000db70000000000', - network_name='UL', - binary='0b02abcd', - ) - self.simulator.go(5) - self.assertEqual(self.nodes[LEADER].get_network_name(), 'GRL') - - # Step 16 - # Old Active Timestamp - self.nodes[COMMISSIONER].send_mgmt_active_set( - active_timestamp=101, - channel_mask=0x01fff800, - extended_panid='000db70000000000', - network_name='UL', - ) - self.simulator.go(5) - self.assertEqual(self.nodes[LEADER].get_network_name(), 'GRL') - - # Step 18 - # Unexpected Steering Data TLV - self.nodes[COMMISSIONER].send_mgmt_active_set( - active_timestamp=107, - channel_mask=0x7fff800, - extended_panid='000db70000000000', - network_name='UL', - binary='0806113320440000', - ) - self.simulator.go(5) - self.assertEqual(self.nodes[LEADER].get_network_name(), 'UL') - - # Step 20 - # Undefined TLV - self.nodes[COMMISSIONER].send_mgmt_active_set( - active_timestamp=108, - channel_mask=0x7fff800, - extended_panid='000db70000000000', - network_name='GRL', - binary='8202aa55', - ) - self.simulator.go(5) - self.assertEqual(self.nodes[LEADER].get_network_name(), 'GRL') - - ipaddrs = self.nodes[COMMISSIONER].get_addrs() - for ipaddr in ipaddrs: - self.assertTrue(self.nodes[LEADER].ping(ipaddr)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_RLOC = pv.vars['LEADER_RLOC'] - LEADER_ALOC = pv.vars['LEADER_ALOC'] - COMMISSIONER = pv.vars['COMMISSIONER'] - COMMISSIONER_RLOC = pv.vars['COMMISSIONER_RLOC'] - - # Step 1: Ensure the topology is formed correctly - pkts.filter_wpan_src64(LEADER).filter_wpan_dst64(COMMISSIONER).filter_mle_cmd( - MLE_CHILD_ID_RESPONSE).must_next() - - # Step 2: Commissioner sends MGMT_ACTIVE_SET.req to Leader RLOC or Anycast Locator - pkts.filter_wpan_src64(COMMISSIONER).filter_ipv6_2dsts(LEADER_RLOC, LEADER_ALOC).filter_coap_request( - MGMT_ACTIVE_SET_URI).filter(lambda p: p.thread_meshcop.tlv.xpan_id == '000db70000000000' and p. - thread_meshcop.tlv.net_name == ['GRL'] and p.thread_meshcop.tlv.chan_mask_mask - == '001fffe0' and p.thread_meshcop.tlv.active_tstamp == 101).must_next() - - # Step 3: Leader MUST send MGMT_ACTIVE_SET.rsp to the Commissioner - pkts.filter_wpan_src64(LEADER).filter_ipv6_dst(COMMISSIONER_RLOC).filter_coap_ack(MGMT_ACTIVE_SET_URI).filter( - lambda p: p.thread_meshcop.tlv.state == 1).must_next() - - # Step 4: Commissioner sends MGMT_ACTIVE_GET.req to Leader - pkts.filter_wpan_src64(COMMISSIONER).filter_ipv6_2dsts( - LEADER_RLOC, LEADER_ALOC).filter_coap_request(MGMT_ACTIVE_GET_URI).must_next() - - # Step 5: The Leader MUST send MGMT_ACTIVE_GET.rsp to the Commissioner - pkts.filter_wpan_src64(LEADER).filter_ipv6_dst(COMMISSIONER_RLOC).filter_coap_ack( - MGMT_ACTIVE_GET_URI).filter(lambda p: p.thread_meshcop.tlv.active_tstamp == 101 and p.thread_meshcop.tlv. - xpan_id == '000db70000000000' and p.thread_meshcop.tlv.net_name == ['GRL'] and - p.thread_meshcop.tlv.chan_mask_mask == '001fffe0').must_next() - - # Step 6: Commissioner sends MGMT_ACTIVE_SET.req to Leader RLOC or Anycast Locator - pkts.filter_wpan_src64(COMMISSIONER).filter_ipv6_2dsts( - LEADER_RLOC, LEADER_ALOC).filter_coap_request(MGMT_ACTIVE_SET_URI).filter( - lambda p: p.thread_meshcop.tlv.active_tstamp == 102 and p.thread_meshcop.tlv.xpan_id == - '000db70000000001' and p.thread_meshcop.tlv.net_name == ['threadcert'] and p.thread_meshcop.tlv. - chan_mask_mask == '001fffe0' and p.thread_meshcop.tlv.channel == [18]).must_next() - - # Step 7: Leader MUST send MGMT_ACTIVE_SET.rsp to the Commissioner - pkts.filter_wpan_src64(LEADER).filter_ipv6_dst(COMMISSIONER_RLOC).filter_coap_ack(MGMT_ACTIVE_SET_URI).filter( - lambda p: p.thread_meshcop.tlv.state == -1).must_next() - - # Step 8: Commissioner sends MGMT_ACTIVE_SET.req to Leader RLOC or Leader Anycast Locator - pkts.filter_wpan_src64(COMMISSIONER).filter_ipv6_2dsts( - LEADER_RLOC, LEADER_ALOC).filter_coap_request(MGMT_ACTIVE_SET_URI).filter( - lambda p: p.thread_meshcop.tlv.active_tstamp == 103 and p.thread_meshcop.tlv.xpan_id == - '000db70000000000' and p.thread_meshcop.tlv.net_name == ['UL'] and p.thread_meshcop.tlv.chan_mask_mask - == '001fffe0' and p.thread_meshcop.tlv.ml_prefix == 'fd000db700000000').must_next() - - # Step 9: Leader MUST send MGMT_ACTIVE_SET.rsp to the Commissioner - pkts.filter_wpan_src64(LEADER).filter_ipv6_dst(COMMISSIONER_RLOC).filter_coap_ack(MGMT_ACTIVE_SET_URI).filter( - lambda p: p.thread_meshcop.tlv.state == -1).must_next() - - # Step 10: Commissioner sends MGMT_ACTIVE_SET.req to Leader RLOC or Leader Anycast Locator - pkts.filter_wpan_src64(COMMISSIONER).filter_ipv6_2dsts( - LEADER_RLOC, LEADER_ALOC).filter_coap_request(MGMT_ACTIVE_SET_URI).filter( - lambda p: p.thread_meshcop.tlv.active_tstamp == 104 and p.thread_meshcop.tlv.xpan_id == - '000db70000000000' and p.thread_meshcop.tlv.net_name == ['GRL'] and p.thread_meshcop.tlv.master_key == - 'ffeeddccbbaa99887766554433221100' and p.thread_meshcop.tlv.chan_mask_mask == '001fffe0' and p. - thread_meshcop.tlv.ml_prefix == 'fd000db700000000').must_next() - - # Step 11: Leader MUST send MGMT_ACTIVE_SET.rsp to the Commissioner - pkts.filter_wpan_src64(LEADER).filter_ipv6_dst(COMMISSIONER_RLOC).filter_coap_ack(MGMT_ACTIVE_SET_URI).filter( - lambda p: p.thread_meshcop.tlv.state == -1).must_next() - - # Step 12: Commissioner sends MGMT_ACTIVE_SET.req to Leader RLOC or Leader Anycast Locator - pkts.filter_wpan_src64(COMMISSIONER).filter_ipv6_2dsts( - LEADER_RLOC, LEADER_ALOC).filter_coap_request(MGMT_ACTIVE_SET_URI).filter( - lambda p: p.thread_meshcop.tlv.active_tstamp == 105 and p.thread_meshcop.tlv.xpan_id == - '000db70000000000' and p.thread_meshcop.tlv.net_name == ['UL'] and p.thread_meshcop.tlv.master_key == - '00112233445566778899aabbccddeeff' and p.thread_meshcop.tlv.pan_id == [0xafce] and p.thread_meshcop.tlv - .chan_mask_mask == '001fffe0' and p.thread_meshcop.tlv.ml_prefix == 'fd000db700000000').must_next() - - # Step 13: Leader MUST send MGMT_ACTIVE_SET.rsp to the Commissioner - pkts.filter_wpan_src64(LEADER).filter_ipv6_dst(COMMISSIONER_RLOC).filter_coap_ack(MGMT_ACTIVE_SET_URI).filter( - lambda p: p.thread_meshcop.tlv.state == -1).must_next() - - # Step 14: Commissioner sends MGMT_ACTIVE_SET.req to Leader RLOC or Leader Anycast Locator - pkts.filter_wpan_src64(COMMISSIONER).filter_ipv6_2dsts( - LEADER_RLOC, LEADER_ALOC).filter_coap_request(MGMT_ACTIVE_SET_URI).filter( - lambda p: p.thread_meshcop.tlv.active_tstamp == 106 and p.thread_meshcop.tlv.xpan_id == - '000db70000000000' and p.thread_meshcop.tlv.net_name == ['UL'] and p.thread_meshcop.tlv. - commissioner_sess_id == 0xabcd and p.thread_meshcop.tlv.chan_mask_mask == '001fffe0').must_next() - - # Step 15: Leader MUST send MGMT_ACTIVE_SET.rsp to the Commissioner - pkts.filter_wpan_src64(LEADER).filter_ipv6_dst(COMMISSIONER_RLOC).filter_coap_ack(MGMT_ACTIVE_SET_URI).filter( - lambda p: p.thread_meshcop.tlv.state == -1).must_next() - - # Step 16: Commissioner sends MGMT_ACTIVE_SET.req to Leader RLOC or Leader Anycast Locator - pkts.filter_wpan_src64(COMMISSIONER).filter_ipv6_2dsts(LEADER_RLOC, LEADER_ALOC).filter_coap_request( - MGMT_ACTIVE_SET_URI).filter(lambda p: p.thread_meshcop.tlv.active_tstamp == 101 and p.thread_meshcop.tlv. - xpan_id == '000db70000000000' and p.thread_meshcop.tlv.net_name == ['UL'] and p - .thread_meshcop.tlv.chan_mask_mask == '001fff80').must_next() - - # Step 17: Leader MUST send MGMT_ACTIVE_SET.rsp to the Commissioner - pkts.filter_wpan_src64(LEADER).filter_ipv6_dst(COMMISSIONER_RLOC).filter_coap_ack(MGMT_ACTIVE_SET_URI).filter( - lambda p: p.thread_meshcop.tlv.state == -1).must_next() - - # Step 18: Commissioner sends MGMT_ACTIVE_SET.req to Leader RLOC or Leader Anycast Locator - pkts.filter_wpan_src64(COMMISSIONER).filter_ipv6_2dsts( - LEADER_RLOC, LEADER_ALOC).filter_coap_request(MGMT_ACTIVE_SET_URI).filter( - lambda p: p.thread_meshcop.tlv.active_tstamp == 107 and p.thread_meshcop.tlv.xpan_id == - '000db70000000000' and p.thread_meshcop.tlv.net_name == ['UL'] and p.thread_meshcop.tlv.steering_data - == Bytes('113320440000') and p.thread_meshcop.tlv.chan_mask_mask == '001fffe0').must_next() - - # Step 19: Leader MUST send MGMT_ACTIVE_SET.rsp to the Commissioner - pkts.filter_wpan_src64(LEADER).filter_ipv6_dst(COMMISSIONER_RLOC).filter_coap_ack(MGMT_ACTIVE_SET_URI).filter( - lambda p: p.thread_meshcop.tlv.state == 1).must_next() - - # Step 20: Commissioner sends MGMT_ACTIVE_SET.req to Leader RLOC or Leader Anycast Locator - pkts.filter_wpan_src64(COMMISSIONER).filter_ipv6_2dsts( - LEADER_RLOC, LEADER_ALOC).filter_coap_request(MGMT_ACTIVE_SET_URI).filter( - lambda p: p.thread_meshcop.tlv.active_tstamp == 108 and p.thread_meshcop.tlv.xpan_id == - '000db70000000000' and p.thread_meshcop.tlv.net_name == ['GRL'] and p.thread_meshcop.tlv.unknown == - 'aa55' and p.thread_meshcop.tlv.chan_mask_mask == '001fffe0').must_next() - - # Step 21: Leader MUST send MGMT_ACTIVE_SET.rsp to the Commissioner - pkts.filter_wpan_src64(LEADER).filter_ipv6_dst(COMMISSIONER_RLOC).filter_coap_ack(MGMT_ACTIVE_SET_URI).filter( - lambda p: p.thread_meshcop.tlv.state == 1).must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_9_2_05_ActiveDataset.py b/tests/scripts/thread-cert/Cert_9_2_05_ActiveDataset.py deleted file mode 100755 index f495e8203..000000000 --- a/tests/scripts/thread-cert/Cert_9_2_05_ActiveDataset.py +++ /dev/null @@ -1,369 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2020, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import thread_cert -from pktverify.consts import MLE_DATA_RESPONSE, MGMT_ACTIVE_SET_URI, NETWORK_DATA_TLV, SOURCE_ADDRESS_TLV, LEADER_DATA_TLV, ACTIVE_TIMESTAMP_TLV, ACTIVE_OPERATION_DATASET_TLV, NM_CHANNEL_TLV, NM_CHANNEL_MASK_TLV, NM_EXTENDED_PAN_ID_TLV, NM_NETWORK_MESH_LOCAL_PREFIX_TLV, NM_NETWORK_KEY_TLV, NM_NETWORK_NAME_TLV, NM_PAN_ID_TLV, NM_PSKC_TLV, NM_SECURITY_POLICY_TLV -from pktverify.packet_verifier import PacketVerifier - -ROUTER = 1 -LEADER = 2 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to verify the DUT’s behavior when receiving -# MGMT_ACTIVE_SET.req from an active Thread node. -# -# Test Topology: -# ------------- -# Router -# | -# Leader -# -# DUT Types: -# ---------- -# Leader - - -class Cert_9_2_05_ActiveDataset(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - SUPPORT_NCP = False - - TOPOLOGY = { - ROUTER: { - 'name': 'ROUTER', - 'channel': 11, - 'network_key': '00112233445566778899aabbccddeeff', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - LEADER: { - 'name': 'LEADER', - 'channel': 11, - 'network_key': '00112233445566778899aabbccddeeff', - 'mode': 'rdn', - 'allowlist': [ROUTER] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[ROUTER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER].get_state(), 'router') - - self.nodes[ROUTER].commissioner_start() - self.simulator.go(5) - - self.collect_rlocs() - # Step 2: new, valid Timestamp TLV - # all valid Active Operational Dataset parameters, - # with new values in the TLVs that don’t affect connectivity - # binary = new pskc and security policy [3600, 0b11101111] - self.nodes[ROUTER].send_mgmt_active_set( - active_timestamp=100, - channel_mask=0x3fff800, - extended_panid='000db80000000001', - mesh_local='fd00:0db8::', - network_name='TEST_1', - network_key='00112233445566778899aabbccddeeff', - panid=0xface, - channel=11, - binary='0410d2aa9cd8dff7919122d77d37ec3c1b5f0c030e10ef', - ) - self.simulator.go(5) - - # Step 7: old, invalid Active Timestamp TLV - # all valid Active Operational Dataset parameters, with - # new values in the TLVs that don’t affect connectivity - # binary = new pskc and security policy [3600, 0b11111111] - self.nodes[ROUTER].send_mgmt_active_set( - active_timestamp=100, - channel_mask=0x1fff800, - extended_panid='000db80000000002', - mesh_local='fd00:0db8::', - network_name='TEST_2', - network_key='00112233445566778899aabbccddeeff', - panid=0xface, - channel=11, - binary='041017d672be32b0c24a2f8385f2fbaf1d970c030e10ff', - ) - self.simulator.go(5) - - # Step 9: new, valid Active Timestamp TLV - # all of valid Commissioner Dataset parameters plus one bogus TLV, and - # new values in the TLVs that don’t affect connectivity - # binary = new pskc and security policy [3600, 0b11111111] and BogusTLV=0x400 - self.nodes[ROUTER].send_mgmt_active_set( - active_timestamp=101, - channel_mask=0xfff800, - extended_panid='000db80000000003', - mesh_local='fd00:0db8::', - network_name='TEST_3', - network_key='00112233445566778899aabbccddeeff', - panid=0xface, - channel=11, - binary='041008f4e9531e8efa8e852d5f4fb951b13e0c030e10ff8202aa55', - ) - self.simulator.go(5) - - # Step 14: new, valid Active Timestamp TLV - # attempt to set Channel TLV to an unsupported channel + all of other TLVs - # binary = pskc and security policy step 9 - self.nodes[ROUTER].send_mgmt_active_set( - active_timestamp=102, - channel_mask=0x1fff800, - extended_panid='000db80000000003', - mesh_local='fd00:0db8::', - network_name='TEST_3', - network_key='00112233445566778899aabbccddeeff', - panid=0xface, - channel=63, - binary='041008f4e9531e8efa8e852d5f4fb951b13e0c030e10f8', - ) - self.simulator.go(5) - - ipaddr = self.nodes[LEADER].get_rloc() - self.assertTrue(self.nodes[ROUTER].ping(ipaddr)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_RLOC = pv.vars['LEADER_RLOC'] - ROUTER = pv.vars['ROUTER'] - ROUTER_RLOC = pv.vars['ROUTER_RLOC'] - - # Step 1: Ensure the topology is formed correctly - pv.verify_attached('ROUTER', 'LEADER') - _pkt = pkts.last() - - # Step 3: Leader MUST send MGMT_ACTIVE_SET.rsp to the Router with - # with the following format: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # State TLV (value = Accept (01)) - pkts.filter_wpan_src64(LEADER).\ - filter_ipv6_dst(ROUTER_RLOC).\ - filter_coap_ack(MGMT_ACTIVE_SET_URI).\ - filter(lambda p: p.thread_meshcop.tlv.state == 1).\ - must_next() - - # Step 4: Leader MUST send a multicast MLE Data Response, including - # the following TLVs: - # - Source Address TLV - # - Leader Data TLV - # Data version field [incremented] - # Stable Version field [incremented] - # - Network Data TLV - # - Active Timestamp TLV [new value set in Step 9] - _dr_pkt = pkts.filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter(lambda p: { - NETWORK_DATA_TLV, - SOURCE_ADDRESS_TLV, - LEADER_DATA_TLV, - ACTIVE_TIMESTAMP_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.active_tstamp == 100 and\ - (p.mle.tlv.leader_data.data_version - - _pkt.mle.tlv.leader_data.data_version) % 256 <= 127 and\ - (p.mle.tlv.leader_data.stable_data_version - - _pkt.mle.tlv.leader_data.stable_data_version) % 256 <= 127 - ).\ - must_next() - - # Step 6: Leader MUST send a unicast MLE Data Response to Router, including - # the following TLVs: - # - Source Address TLV - # - Leader Data TLV - # - Active Operational Dataset TLV - # - Channel TLV - # - Channel Mask TLV [new value set in Step 2] - # - Extended PAN ID TLV [new value set in Step 2] - # - Network Mesh-Local Prefix TLV - # - Network Key TLV - # - Network Name TLV [new value set in Step 2] - # - PAN ID TLV - # - PSKc TLV [new value set in Step 2] - # - Security Policy TLV [new value set in Step 2] - # - Active Timestamp TLV [new value set in Step 2] - pkts.filter_wpan_src64(LEADER).\ - filter_wpan_dst64(ROUTER).\ - filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter(lambda p: { - NETWORK_DATA_TLV, - SOURCE_ADDRESS_TLV, - LEADER_DATA_TLV, - ACTIVE_OPERATION_DATASET_TLV, - ACTIVE_TIMESTAMP_TLV - } <= set(p.mle.tlv.type) and\ - { - NM_CHANNEL_TLV, - NM_CHANNEL_MASK_TLV, - NM_EXTENDED_PAN_ID_TLV, - NM_NETWORK_MESH_LOCAL_PREFIX_TLV, - NM_NETWORK_KEY_TLV, - NM_NETWORK_NAME_TLV, - NM_PAN_ID_TLV, - NM_PSKC_TLV, - NM_SECURITY_POLICY_TLV - } <= set(p.thread_meshcop.tlv.type) and\ - p.mle.tlv.active_tstamp == 100 and\ - p.thread_meshcop.tlv.chan_mask_mask == '001fffc0' and\ - p.thread_meshcop.tlv.xpan_id == '000db80000000001' and\ - p.thread_meshcop.tlv.net_name == ['TEST_1'] and\ - p.thread_meshcop.tlv.pskc == 'd2aa9cd8dff7919122d77d37ec3c1b5f' - ).\ - must_next() - - # Step 8: Leader MUST send MGMT_ACTIVE_SET.rsp to the Router with - # with the following format: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # State TLV (value = Reject (ff)) - pkts.filter_wpan_src64(LEADER).\ - filter_ipv6_dst(ROUTER_RLOC).\ - filter_coap_ack(MGMT_ACTIVE_SET_URI).\ - filter(lambda p: p.thread_meshcop.tlv.state == -1).\ - must_next() - - # Step 10: Leader MUST send MGMT_ACTIVE_SET.rsp to the Router with - # with the following format: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # State TLV (value = Accept (01)) - pkts.filter_wpan_src64(LEADER).\ - filter_ipv6_dst(ROUTER_RLOC).\ - filter_coap_ack(MGMT_ACTIVE_SET_URI).\ - filter(lambda p: p.thread_meshcop.tlv.state == 1).\ - must_next() - - # Step 11: Leader MUST send a multicast MLE Data Response, including - # the following TLVs: - # - Source Address TLV - # - Leader Data TLV - # Data version field [incremented] - # Stable Version field [incremented] - # - Network Data TLV - # - Active Timestamp TLV [new value set in Step 9] - pkts.filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter(lambda p: { - NETWORK_DATA_TLV, - SOURCE_ADDRESS_TLV, - LEADER_DATA_TLV, - ACTIVE_TIMESTAMP_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.active_tstamp == 101 and\ - (p.mle.tlv.leader_data.data_version - - _dr_pkt.mle.tlv.leader_data.data_version) % 256 <= 127 and\ - (p.mle.tlv.leader_data.stable_data_version - - _dr_pkt.mle.tlv.leader_data.stable_data_version) % 256 <= 127 - ).\ - must_next() - - # Step 13: Leader MUST send a unicast MLE Data Response to Router, including - # the following TLVs: - # - Source Address TLV - # - Leader Data TLV - # - Active Operational Dataset TLV - # - Channel TLV - # - Channel Mask TLV [new value set in Step 9] - # - Extended PAN ID TLV [new value set in Step 9] - # - Network Mesh-Local Prefix TLV - # - Network Key TLV - # - Network Name TLV [new value set in Step 9] - # - PAN ID TLV - # - PSKc TLV [new value set in Step 9] - # - Security Policy TLV [new value set in Step 9] - # - Active Timestamp TLV [new value set in Step 9] - pkts.filter_wpan_src64(LEADER).\ - filter_wpan_dst64(ROUTER).\ - filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter(lambda p: { - NETWORK_DATA_TLV, - SOURCE_ADDRESS_TLV, - LEADER_DATA_TLV, - ACTIVE_OPERATION_DATASET_TLV, - ACTIVE_TIMESTAMP_TLV - } <= set(p.mle.tlv.type) and\ - { - NM_CHANNEL_TLV, - NM_CHANNEL_MASK_TLV, - NM_EXTENDED_PAN_ID_TLV, - NM_NETWORK_MESH_LOCAL_PREFIX_TLV, - NM_NETWORK_KEY_TLV, - NM_NETWORK_NAME_TLV, - NM_PAN_ID_TLV, - NM_PSKC_TLV, - NM_SECURITY_POLICY_TLV - } <= set(p.thread_meshcop.tlv.type) and\ - p.mle.tlv.active_tstamp == 101 and\ - p.thread_meshcop.tlv.chan_mask_mask == '001fff00' and\ - p.thread_meshcop.tlv.xpan_id == '000db80000000003' and\ - p.thread_meshcop.tlv.net_name == ['TEST_3'] and\ - p.thread_meshcop.tlv.pskc == '08f4e9531e8efa8e852d5f4fb951b13e' - ).\ - must_next() - - # Step 15: Leader MUST send MGMT_ACTIVE_SET.rsp to the Router with - # with the following format: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # State TLV (value = Reject (ff))) - pkts.filter_wpan_src64(LEADER).\ - filter_ipv6_dst(ROUTER_RLOC).\ - filter_coap_ack(MGMT_ACTIVE_SET_URI).\ - filter(lambda p: p.thread_meshcop.tlv.state == -1).\ - must_next() - - # Step 16: The DUT must respond with an ICMPv6 Echo Reply - _pkt = pkts.filter_ping_request().\ - filter_ipv6_src_dst(ROUTER_RLOC, LEADER_RLOC).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(LEADER_RLOC, ROUTER_RLOC).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_9_2_06_DatasetDissemination.py b/tests/scripts/thread-cert/Cert_9_2_06_DatasetDissemination.py deleted file mode 100755 index a4ff24b22..000000000 --- a/tests/scripts/thread-cert/Cert_9_2_06_DatasetDissemination.py +++ /dev/null @@ -1,872 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2020, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import command -import config -import mesh_cop -import thread_cert -from pktverify.consts import MLE_CHILD_ID_RESPONSE, MLE_CHILD_UPDATE_REQUEST, MLE_DATA_RESPONSE, MLE_DATA_REQUEST, MGMT_COMMISSIONER_SET_URI, MGMT_ACTIVE_SET_URI, MGMT_PENDING_SET_URI, TLV_REQUEST_TLV, SOURCE_ADDRESS_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV, PENDING_TIMESTAMP_TLV, ACTIVE_OPERATION_DATASET_TLV, PENDING_OPERATION_DATASET_TLV, NM_COMMISSIONER_SESSION_ID_TLV, NM_BORDER_AGENT_LOCATOR_TLV, NM_ACTIVE_TIMESTAMP_TLV, NM_NETWORK_NAME_TLV, NM_NETWORK_KEY_TLV, NM_CHANNEL_TLV, NM_CHANNEL_MASK_TLV, NM_EXTENDED_PAN_ID_TLV, NM_NETWORK_MESH_LOCAL_PREFIX_TLV, NM_PAN_ID_TLV, NM_PSKC_TLV, NM_SECURITY_POLICY_TLV, NM_DELAY_TIMER_TLV, NM_STEERING_DATA_TLV, NWD_COMMISSIONING_DATA_TLV, LEADER_ALOC -from pktverify.packet_verifier import PacketVerifier -from pktverify.layer_fields import nullField - -CHANNEL_INIT = 19 -PANID_INIT = 0xface -TIMESTAMP_INIT = 10 -CHANNEL_SECOND = 21 - -COMM_ACTIVE_TIMESTAMP = 15 -COMM_ACTIVE_NET_NAME = 'Thread' -COMM_ACTIVE_PSKC = '10b95765596ab9d0b86cebdd0fa24da3' - -COMM_PENDING_TIMESTAMP = 30 -COMM_PENDING_ACTIVE_TIMESTAMP = 75 -COMM_DELAY_TIMER = 60000 - -COMMISSIONER = 1 -LEADER = 2 -ROUTER = 3 -MED = 4 -SED = 5 - -# Test Purpose and Description: -# ----------------------------- -# DUT as Leader: -# The purpose of this test case is to verify that the Leader device properly -# collects and disseminates Operational Datasets through a Thread network. -# DUT as Router: -# The purpose of this test case is to show that the Router device correctly -# sets the Commissioning information propagated by the Leader device and sends -# it properly to devices already attached to it. -# DUT as MED/SED: -# MED - requires full network data -# SED - requires only stable network data -# Set on Leader: Active TimeStamp = 10s -# -# Test Topology: -# ------------- -# Commissioner -# | -# Leader -# | -# Router -# / \ -# MED SED -# -# DUT Types: -# ---------- -# Leader -# Router -# MED -# SED - - -class Cert_9_2_06_DatasetDissemination(thread_cert.TestCase): - SUPPORT_NCP = False - - TOPOLOGY = { - COMMISSIONER: { - 'name': 'COMMISSIONER', - 'active_dataset': { - 'timestamp': TIMESTAMP_INIT, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT - }, - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - LEADER: { - 'name': 'LEADER', - 'active_dataset': { - 'timestamp': TIMESTAMP_INIT, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT - }, - 'mode': 'rdn', - 'allowlist': [COMMISSIONER, ROUTER] - }, - ROUTER: { - 'name': 'ROUTER', - 'active_dataset': { - 'timestamp': TIMESTAMP_INIT, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT - }, - 'mode': 'rdn', - 'allowlist': [LEADER, MED, SED] - }, - MED: { - 'name': 'MED', - 'channel': CHANNEL_INIT, - 'is_mtd': True, - 'mode': 'rn', - 'panid': PANID_INIT, - 'allowlist': [ROUTER] - }, - SED: { - 'name': 'SED', - 'channel': CHANNEL_INIT, - 'is_mtd': True, - 'mode': '-', - 'panid': PANID_INIT, - 'timeout': config.DEFAULT_CHILD_TIMEOUT, - 'allowlist': [ROUTER] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[COMMISSIONER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'router') - self.simulator.get_messages_sent_by(LEADER) - self.nodes[COMMISSIONER].commissioner_start() - self.simulator.go(3) - - leader_messages = self.simulator.get_messages_sent_by(LEADER) - msg = leader_messages.next_coap_message('2.04', assert_enabled=True) - self.nodes[ROUTER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER].get_state(), 'router') - - self.nodes[MED].start() - self.simulator.go(5) - self.assertEqual(self.nodes[MED].get_state(), 'child') - - self.nodes[SED].start() - self.simulator.go(5) - self.assertEqual(self.nodes[SED].get_state(), 'child') - - commissioner_session_id_tlv = command.get_sub_tlv(msg.coap.payload, mesh_cop.CommissionerSessionId) - steering_data_tlv = mesh_cop.SteeringData(bytes([0xff])) - # Step 2 - self.nodes[COMMISSIONER].commissioner_mgmtset_with_tlvs([steering_data_tlv, commissioner_session_id_tlv]) - self.simulator.go(10) - - # Step 7 - self.nodes[COMMISSIONER].send_mgmt_active_set( - active_timestamp=COMM_ACTIVE_TIMESTAMP, - network_name=COMM_ACTIVE_NET_NAME, - binary='0410' + COMM_ACTIVE_PSKC, - ) - self.simulator.go(10) - - # Step 18 - self.nodes[COMMISSIONER].send_mgmt_pending_set( - pending_timestamp=COMM_PENDING_TIMESTAMP, - active_timestamp=COMM_PENDING_ACTIVE_TIMESTAMP, - delay_timer=COMM_DELAY_TIMER, - channel=CHANNEL_SECOND, - ) - self.simulator.go(120) - - self.collect_rlocs() - ed_rloc = self.nodes[MED].get_rloc() - sed_rloc = self.nodes[SED].get_rloc() - leader_rloc = self.nodes[LEADER].get_rloc() - router_rloc = self.nodes[ROUTER].get_rloc() - for rloc in (leader_rloc, router_rloc, ed_rloc, sed_rloc): - self.assertTrue(self.nodes[COMMISSIONER].ping(rloc)) - self.simulator.go(10) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - COMMISSIONER = pv.vars['COMMISSIONER'] - ROUTER = pv.vars['ROUTER'] - MED = pv.vars['MED'] - SED = pv.vars['SED'] - LEADER_RLOC = pv.vars['LEADER_RLOC'] - COMMISSIONER_RLOC = pv.vars['COMMISSIONER_RLOC'] - ROUTER_RLOC = pv.vars['ROUTER_RLOC'] - MED_RLOC = pv.vars['MED_RLOC'] - SED_RLOC = pv.vars['SED_RLOC'] - - # Step 1: Ensure the topology is formed correctly - for node in ('COMMISSIONER', 'ROUTER'): - pv.verify_attached(node, 'LEADER') - for node in ('MED', 'SED'): - pv.verify_attached(node, 'ROUTER', 'MTD') - _pkt = pkts.last() - - # Step 3: Leader sends MGMT_COMMISSIONER_SET.rsp to the Commissioner: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # - State TLV (value = Accept) - pkts.filter_coap_ack(MGMT_COMMISSIONER_SET_URI).\ - filter_wpan_src64(LEADER).\ - filter_ipv6_dst(COMMISSIONER_RLOC).\ - must_next().\ - must_verify(lambda p: p.thread_meshcop.tlv.state == 1) - - # Step 4: Leader MUST multicast MLE Data Response to the Link-Local - # All Nodes multicast address (FF02::1) with the new information - # including the following TLVs: - # - Source Address TLV - # - Leader Data TLV: - # Data Version field incremented - # Stable Version field NOT incremented - # - Network Data TLV: - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # Steering Data TLV - # - Active Timestamp TLV - pkts.filter_mle_cmd(MLE_DATA_RESPONSE). \ - filter_wpan_src64(LEADER). \ - filter_LLANMA(). \ - filter(lambda p: p.mle.tlv.active_tstamp == TIMESTAMP_INIT and \ - (p.mle.tlv.leader_data.data_version - - _pkt.mle.tlv.leader_data.data_version) % 256 <= 127 and \ - p.mle.tlv.leader_data.stable_data_version == - _pkt.mle.tlv.leader_data.stable_data_version and \ - p.thread_nwd.tlv.stable == [0] and \ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and \ - NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and \ - NM_STEERING_DATA_TLV in p.thread_meshcop.tlv.type and \ - NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type - ). \ - must_next() - idx_start = pkts.index - - # Step 5: Router MUST multicast MLE Data Response to the Link-Local - # All Nodes multicast address (FF02::1) with the new information - # including the following TLVs: - # - Source Address TLV - # - Leader Data TLV: - # Data Version field incremented - # Stable Version field NOT incremented - # - Network Data TLV: - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # Steering Data TLV - # - Active Timestamp TLV - pkts.filter_mle_cmd(MLE_DATA_RESPONSE). \ - filter_wpan_src64(ROUTER). \ - filter_LLANMA(). \ - filter(lambda p: p.mle.tlv.active_tstamp == TIMESTAMP_INIT and \ - (p.mle.tlv.leader_data.data_version - - _pkt.mle.tlv.leader_data.data_version) % 256 <= 127 and \ - p.mle.tlv.leader_data.stable_data_version == - _pkt.mle.tlv.leader_data.stable_data_version and \ - p.thread_nwd.tlv.stable == [0] and \ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and \ - NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and \ - NM_STEERING_DATA_TLV in p.thread_meshcop.tlv.type and \ - NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type - ). \ - must_next() - - # Step 8: Leader sends MGMT_ACTIVE_SET.rsp to the Commissioner: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # - State TLV (value = Accept) - pkts.filter_coap_ack(MGMT_ACTIVE_SET_URI). \ - filter_wpan_src64(LEADER). \ - filter_ipv6_dst(COMMISSIONER_RLOC). \ - must_next(). \ - must_verify(lambda p: p.thread_meshcop.tlv.state == 1) - idx_end = pkts.index - - # Step 6: Router MUST NOT send a unicast MLE Data Response or MLE Child - # Update Request to SED_1 - pkts.range(idx_start, idx_end).\ - filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter_wpan_src64(ROUTER).\ - filter_wpan_dst64(SED).\ - must_not_next() - - # Step 9: Leader MUST multicast MLE Data Response to the Link-Local - # All Nodes multicast address (FF02::1) with the new information - # including the following TLVs: - # - Source Address TLV - # - Leader Data TLV: - # Data Version field incremented - # Stable Version field incremented - # - Network Data TLV: - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # Steering Data TLV - # - Active Timestamp TLV: 15s - _pkt9 = pkts.filter_mle_cmd(MLE_DATA_RESPONSE). \ - filter_wpan_src64(LEADER). \ - filter_LLANMA(). \ - filter(lambda p: p.mle.tlv.active_tstamp == COMM_ACTIVE_TIMESTAMP and \ - (p.mle.tlv.leader_data.data_version - - _pkt.mle.tlv.leader_data.data_version) % 256 <= 127 and \ - (p.mle.tlv.leader_data.stable_data_version - - _pkt.mle.tlv.leader_data.stable_data_version) % 256 <= 127 and \ - p.thread_nwd.tlv.stable == [0] and \ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and \ - NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and \ - NM_STEERING_DATA_TLV in p.thread_meshcop.tlv.type and \ - NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type - ). \ - must_next() - - # Step 10: Router MUST send a unicast MLE Data Request to the Leader, including the - # following TLVs: - # - TLV Request TLV: - # - Network Data TLV - # - Active Timestamp TLV - pkts.filter_wpan_src64(ROUTER).\ - filter_wpan_dst64(LEADER).\ - filter_mle_cmd(MLE_DATA_REQUEST).\ - filter(lambda p: { - TLV_REQUEST_TLV, - NETWORK_DATA_TLV, - ACTIVE_TIMESTAMP_TLV - } <= set(p.mle.tlv.type) and\ - p.thread_meshcop.tlv.type is nullField - ).\ - must_next() - - # Step 11: Leader sends a MLE Data Response to Router_1 including the following TLVs: - # - Source Address TLV - # - Leader Data TLV - # Data version numbers should be - # the same as the ones sent in the - # multicast data response in step 9 - # - Network Data TLV - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # Steering Data TLV - # - Active Timestamp TLV: - # - Active Operational Dataset TLV - # - Network Name TLV - # - Channel TLV - # - PAN ID TLV - # - PSKc TLV - # MUST NOT contain the Active Timestamp TLV - pkts.filter_mle_cmd(MLE_DATA_RESPONSE). \ - filter_wpan_src64(LEADER). \ - filter_wpan_dst64(ROUTER). \ - filter(lambda p: { - SOURCE_ADDRESS_TLV, - LEADER_DATA_TLV, - ACTIVE_TIMESTAMP_TLV, - ACTIVE_OPERATION_DATASET_TLV - } <= set(p.mle.tlv.type) and \ - { - NM_COMMISSIONER_SESSION_ID_TLV, - NM_BORDER_AGENT_LOCATOR_TLV, - NM_STEERING_DATA_TLV - } <= set(p.thread_meshcop.tlv.type) and \ - p.mle.tlv.leader_data.data_version == - _pkt9.mle.tlv.leader_data.data_version and \ - p.mle.tlv.leader_data.stable_data_version == - _pkt9.mle.tlv.leader_data.stable_data_version and \ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and \ - NM_ACTIVE_TIMESTAMP_TLV not in p.thread_meshcop.tlv.type and \ - p.thread_nwd.tlv.stable == [0] and \ - p.mle.tlv.active_tstamp == COMM_ACTIVE_TIMESTAMP and \ - p.thread_meshcop.tlv.channel == [CHANNEL_INIT] and \ - p.thread_meshcop.tlv.net_name == [COMM_ACTIVE_NET_NAME] and \ - p.thread_meshcop.tlv.pskc == COMM_ACTIVE_PSKC and \ - p.thread_meshcop.tlv.pan_id == [PANID_INIT] - ). \ - must_next() - - # Step 12: Router MUST multicast MLE Data Response to the Link-Local - # All Nodes multicast address (FF02::1) with the new information - # including the following TLVs: - # - Source Address TLV - # - Leader Data TLV: - # Data version numbers should be - # the same as the ones sent in the - # multicast data response in step 9 - # - Network Data TLV: - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # Steering Data TLV - # - Active Timestamp TLV: 15s - with pkts.save_index(): - pkts.filter_mle_cmd(MLE_DATA_RESPONSE). \ - filter_wpan_src64(ROUTER). \ - filter_LLANMA(). \ - filter(lambda p: p.mle.tlv.active_tstamp == COMM_ACTIVE_TIMESTAMP and \ - p.mle.tlv.leader_data.data_version == - _pkt9.mle.tlv.leader_data.data_version and \ - p.mle.tlv.leader_data.stable_data_version == - _pkt9.mle.tlv.leader_data.stable_data_version and \ - p.thread_nwd.tlv.stable == [0] and \ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and \ - NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and \ - NM_STEERING_DATA_TLV in p.thread_meshcop.tlv.type and \ - NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type - ). \ - must_next() - - # Step 13: MED MUST send a unicast MLE Data Request to the Router, including the - # following TLVs: - # - TLV Request TLV: - # - Network Data TLV - # - Active Timestamp TLV - - # Step 14: Router sends a MLE Data Response to MED including the following TLVs: - # - Source Address TLV - # - Leader Data TLV - # Data version numbers should be - # the same as the ones sent in the - # multicast data response in step 9 - # - Network Data TLV - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # Steering Data TLV - # - Active Timestamp TLV: - # - Active Operational Dataset TLV - # - Network Name TLV - # - Channel TLV - # - PAN ID TLV - # MUST NOT contain the Active Timestamp TLV - with pkts.save_index(): - pkts.filter_wpan_src64(MED). \ - filter_wpan_dst64(ROUTER). \ - filter_mle_cmd(MLE_DATA_REQUEST). \ - filter(lambda p: { - TLV_REQUEST_TLV, - NETWORK_DATA_TLV, - ACTIVE_TIMESTAMP_TLV - } <= set(p.mle.tlv.type) and \ - p.thread_meshcop.tlv.type is nullField - ). \ - must_next() - - pkts.filter_mle_cmd(MLE_DATA_RESPONSE). \ - filter_wpan_src64(ROUTER). \ - filter_wpan_dst64(MED). \ - filter(lambda p: { - SOURCE_ADDRESS_TLV, - LEADER_DATA_TLV, - ACTIVE_TIMESTAMP_TLV, - ACTIVE_OPERATION_DATASET_TLV - } <= set(p.mle.tlv.type) and \ - { - NM_COMMISSIONER_SESSION_ID_TLV, - NM_BORDER_AGENT_LOCATOR_TLV, - NM_STEERING_DATA_TLV - } <= set(p.thread_meshcop.tlv.type) and \ - p.mle.tlv.leader_data.data_version == - _pkt9.mle.tlv.leader_data.data_version and \ - p.mle.tlv.leader_data.stable_data_version == - _pkt9.mle.tlv.leader_data.stable_data_version and \ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and \ - NM_ACTIVE_TIMESTAMP_TLV not in p.thread_meshcop.tlv.type and \ - p.thread_nwd.tlv.stable == [0] and \ - p.mle.tlv.active_tstamp == COMM_ACTIVE_TIMESTAMP and \ - p.thread_meshcop.tlv.channel == [CHANNEL_INIT] and \ - p.thread_meshcop.tlv.net_name == [COMM_ACTIVE_NET_NAME] and \ - p.thread_meshcop.tlv.pskc == COMM_ACTIVE_PSKC and \ - p.thread_meshcop.tlv.pan_id == [PANID_INIT] - ). \ - must_next() - - # Step 15: Router MUST send MLE Child Update Request or MLE Data Response - # to SED, including the following TLVs: - # - Source Address TLV - # - Leader Data TLV: - # Data version numbers should be - # the same as the ones sent in the - # multicast data response in step 9 - # - Network Data TLV - # - Active Timestamp TLV: 15s - pkts.filter_wpan_src64(ROUTER). \ - filter_wpan_dst64(SED). \ - filter_mle_cmd2(MLE_CHILD_UPDATE_REQUEST, MLE_DATA_RESPONSE). \ - filter(lambda p: p.mle.tlv.active_tstamp == COMM_ACTIVE_TIMESTAMP and \ - p.mle.tlv.leader_data.data_version == - _pkt9.mle.tlv.leader_data.data_version and \ - p.mle.tlv.leader_data.stable_data_version == - _pkt9.mle.tlv.leader_data.stable_data_version and \ - NETWORK_DATA_TLV in p.mle.tlv.type and\ - SOURCE_ADDRESS_TLV in p.mle.tlv.type - ). \ - must_next() - - # Step 16: SED MUST send a unicast MLE Data Request to the Router, including the - # following TLVs: - # - TLV Request TLV: - # - Network Data TLV - # - Active Timestamp TLV - pkts.filter_wpan_src64(SED). \ - filter_wpan_dst64(ROUTER). \ - filter_mle_cmd(MLE_DATA_REQUEST). \ - filter(lambda p: { - TLV_REQUEST_TLV, - NETWORK_DATA_TLV, - ACTIVE_TIMESTAMP_TLV - } <= set(p.mle.tlv.type) and \ - p.thread_meshcop.tlv.type is nullField - ). \ - must_next() - - # Step 17: Router sends a MLE Data Response to SED including the following TLVs: - # - Source Address TLV - # - Leader Data TLV - # Data version numbers should be - # the same as the ones sent in the - # multicast data response in step 9 - # - Network Data TLV - # - Active Timestamp TLV: <15s> - # - Active Operational Dataset TLV - # - Network Name TLV - # - Channel TLV - # - PAN ID TLV - # MUST NOT contain the Active Timestamp TLV - pkts.filter_mle_cmd(MLE_DATA_RESPONSE). \ - filter_wpan_src64(ROUTER). \ - filter_wpan_dst64(SED). \ - filter(lambda p: { - SOURCE_ADDRESS_TLV, - LEADER_DATA_TLV, - ACTIVE_TIMESTAMP_TLV, - ACTIVE_OPERATION_DATASET_TLV - } <= set(p.mle.tlv.type) and \ - p.mle.tlv.leader_data.data_version == - _pkt9.mle.tlv.leader_data.data_version and \ - p.mle.tlv.leader_data.stable_data_version == - _pkt9.mle.tlv.leader_data.stable_data_version and \ - NM_ACTIVE_TIMESTAMP_TLV not in p.thread_meshcop.tlv.type and \ - p.mle.tlv.active_tstamp == COMM_ACTIVE_TIMESTAMP and \ - p.thread_meshcop.tlv.channel == [CHANNEL_INIT] and \ - p.thread_meshcop.tlv.net_name == [COMM_ACTIVE_NET_NAME] and \ - p.thread_meshcop.tlv.pskc == COMM_ACTIVE_PSKC and \ - p.thread_meshcop.tlv.pan_id == [PANID_INIT] - ). \ - must_next() - - # Step 19: Leader sends MGMT_PENDING_SET.rsp to the Commissioner: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # - State TLV (value = Accept) - pkts.filter_coap_ack(MGMT_PENDING_SET_URI). \ - filter_wpan_src64(LEADER). \ - filter_ipv6_dst(COMMISSIONER_RLOC). \ - must_next(). \ - must_verify(lambda p: p.thread_meshcop.tlv.state == 1) - - # Step 20: Leader MUST multicast MLE Data Response to the Link-Local - # All Nodes multicast address (FF02::1) with the new information - # including the following TLVs: - # - Source Address TLV - # - Leader Data TLV: - # Data Version field incremented - # Stable Version field incremented - # - Network Data TLV: - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # Steering Data TLV - # - Active Timestamp TLV - # - Pending Timestamp TLV - _pkt20 = pkts.filter_mle_cmd(MLE_DATA_RESPONSE). \ - filter_wpan_src64(LEADER). \ - filter_LLANMA(). \ - filter(lambda p: { - SOURCE_ADDRESS_TLV, - LEADER_DATA_TLV, - ACTIVE_TIMESTAMP_TLV, - PENDING_TIMESTAMP_TLV - } <= set(p.mle.tlv.type) and \ - { - NM_COMMISSIONER_SESSION_ID_TLV, - NM_BORDER_AGENT_LOCATOR_TLV, - NM_STEERING_DATA_TLV - } <= set(p.thread_meshcop.tlv.type) and \ - (p.mle.tlv.leader_data.data_version - - _pkt9.mle.tlv.leader_data.data_version) % 256 <= 127 and \ - (p.mle.tlv.leader_data.stable_data_version - - _pkt9.mle.tlv.leader_data.stable_data_version) % 256 <= 127 and \ - p.thread_nwd.tlv.stable == [0] and \ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type - ). \ - must_next() - - # Step 21: Router MUST send a unicast MLE Data Request to the Leader, including the - # following TLVs: - # - TLV Request TLV: - # - Network Data TLV - # - Active Timestamp TLV - pkts.filter_wpan_src64(ROUTER). \ - filter_wpan_dst64(LEADER). \ - filter_mle_cmd(MLE_DATA_REQUEST). \ - filter(lambda p: { - TLV_REQUEST_TLV, - NETWORK_DATA_TLV, - ACTIVE_TIMESTAMP_TLV - } <= set(p.mle.tlv.type) and \ - p.thread_meshcop.tlv.type is nullField - ). \ - must_next() - - # Step 22: Leader sends a MLE Data Response to Router including the following TLVs: - # - Source Address TLV - # - Leader Data TLV - # - Network Data TLV - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # Steering Data TLV - # - Active Timestamp TLV - # - Pending Timestamp TLV - # - Pending Operational Dataset TLV - - pkts.filter_mle_cmd(MLE_DATA_RESPONSE). \ - filter_wpan_src64(LEADER). \ - filter_wpan_dst64(ROUTER). \ - filter(lambda p: { - SOURCE_ADDRESS_TLV, - LEADER_DATA_TLV, - ACTIVE_TIMESTAMP_TLV, - PENDING_TIMESTAMP_TLV, - PENDING_OPERATION_DATASET_TLV - } <= set(p.mle.tlv.type) and \ - { - NM_COMMISSIONER_SESSION_ID_TLV, - NM_BORDER_AGENT_LOCATOR_TLV, - NM_STEERING_DATA_TLV - } <= set(p.thread_meshcop.tlv.type) and \ - p.thread_nwd.tlv.stable == [0] and \ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and \ - p.mle.tlv.active_tstamp == COMM_ACTIVE_TIMESTAMP and \ - p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and \ - p.thread_meshcop.tlv.delay_timer < COMM_DELAY_TIMER and \ - p.thread_meshcop.tlv.active_tstamp == COMM_PENDING_ACTIVE_TIMESTAMP and \ - p.thread_meshcop.tlv.channel == [CHANNEL_SECOND] and \ - p.thread_meshcop.tlv.pan_id == [PANID_INIT] - ). \ - must_next() - - # Step 23: Router MUST multicast MLE Data Response to the Link-Local - # All Nodes multicast address (FF02::1) with the new information - # including the following TLVs: - # - Source Address TLV - # - Leader Data TLV: - # Data version numbers should be - # the same as the ones sent in the - # multicast data response in step 20 - # - Network Data TLV: - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # Steering Data TLV - # - Active Timestamp TLV: 15s - # - Pending Timestamp TLV: 30s - with pkts.save_index(): - pkts.filter_mle_cmd(MLE_DATA_RESPONSE). \ - filter_wpan_src64(ROUTER). \ - filter_LLANMA(). \ - filter(lambda p: { - NM_COMMISSIONER_SESSION_ID_TLV, - NM_BORDER_AGENT_LOCATOR_TLV, - NM_STEERING_DATA_TLV - } <= set(p.thread_meshcop.tlv.type) and \ - p.mle.tlv.active_tstamp == COMM_ACTIVE_TIMESTAMP and \ - p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and \ - p.mle.tlv.leader_data.data_version == - _pkt20.mle.tlv.leader_data.data_version and \ - p.mle.tlv.leader_data.stable_data_version == - _pkt20.mle.tlv.leader_data.stable_data_version and \ - p.thread_nwd.tlv.stable == [0] and \ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and \ - NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and \ - NM_STEERING_DATA_TLV in p.thread_meshcop.tlv.type and \ - NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type - ). \ - must_next() - - # Step 24: MED MUST send a unicast MLE Data Request to the Router, including the - # following TLVs: - # - TLV Request TLV: - # - Network Data TLV - # - Active Timestamp TLV - - # Step 25: Router sends a MLE Data Response to MED including the following TLVs: - # - Source Address TLV - # - Leader Data TLV - # Data version numbers should be - # the same as the ones sent in the - # multicast data response in step 20 - # - Network Data TLV - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # Steering Data TLV - # - Active Timestamp TLV - # - Pending Timestamp TLV - # - Pending Operational Dataset TLV - # - Network Name TLV - # - Channel TLV - # - PAN ID TLV - with pkts.save_index(): - pkts.filter_wpan_src64(MED). \ - filter_wpan_dst64(ROUTER). \ - filter_mle_cmd(MLE_DATA_REQUEST). \ - filter(lambda p: { - TLV_REQUEST_TLV, - NETWORK_DATA_TLV, - ACTIVE_TIMESTAMP_TLV - } <= set(p.mle.tlv.type) and \ - p.thread_meshcop.tlv.type is nullField - ). \ - must_next() - - pkts.filter_mle_cmd(MLE_DATA_RESPONSE). \ - filter_wpan_src64(ROUTER). \ - filter_wpan_dst64(MED). \ - filter(lambda p: { - SOURCE_ADDRESS_TLV, - LEADER_DATA_TLV, - ACTIVE_TIMESTAMP_TLV, - PENDING_TIMESTAMP_TLV, - PENDING_OPERATION_DATASET_TLV - } <= set(p.mle.tlv.type) and \ - { - NM_COMMISSIONER_SESSION_ID_TLV, - NM_BORDER_AGENT_LOCATOR_TLV, - NM_STEERING_DATA_TLV - } <= set(p.thread_meshcop.tlv.type) and \ - p.mle.tlv.leader_data.data_version == - _pkt20.mle.tlv.leader_data.data_version and \ - p.mle.tlv.leader_data.stable_data_version == - _pkt20.mle.tlv.leader_data.stable_data_version and \ - p.thread_nwd.tlv.stable == [0] - ). \ - must_next() - - # Step 26: Router MUST send MLE Child Update Request or MLE Data Response - # to SED, including the following TLVs: - # - Source Address TLV - # - Leader Data TLV: - # Data version numbers should be - # the same as the ones sent in the - # multicast data response in step 20 - # - Network Data TLV - # - Active Timestamp TLV: 15s - # - Pending Timestamp TLV: 30s - pkts.filter_wpan_src64(ROUTER). \ - filter_wpan_dst64(SED). \ - filter_mle_cmd2(MLE_CHILD_UPDATE_REQUEST, MLE_DATA_RESPONSE). \ - filter(lambda p: p.mle.tlv.active_tstamp == - COMM_ACTIVE_TIMESTAMP and \ - p.mle.tlv.pending_tstamp == - COMM_PENDING_TIMESTAMP and \ - p.mle.tlv.leader_data.data_version == - _pkt20.mle.tlv.leader_data.data_version and \ - p.mle.tlv.leader_data.stable_data_version == - _pkt20.mle.tlv.leader_data.stable_data_version and \ - NETWORK_DATA_TLV in p.mle.tlv.type - ). \ - must_next() - - # Step 27: SED MUST send a unicast MLE Data Request to the Router, including the - # following TLVs: - # - TLV Request TLV: - # - Network Data TLV - # - Active Timestamp TLV - pkts.filter_wpan_src64(SED). \ - filter_wpan_dst64(ROUTER). \ - filter_mle_cmd(MLE_DATA_REQUEST). \ - filter(lambda p: { - TLV_REQUEST_TLV, - NETWORK_DATA_TLV, - ACTIVE_TIMESTAMP_TLV - } <= set(p.mle.tlv.type) and \ - p.thread_meshcop.tlv.type is nullField - ). \ - must_next() - - # Step 28: Router sends a MLE Data Response to SED including the following TLVs: - # - Source Address TLV - # - Leader Data TLV - # Data version numbers should be - # the same as the ones sent in the - # multicast data response in step 20 - # - Network Data TLV - # - Active Timestamp TLV: 15s - # - Pending Timestamp TLV: 30s - # - Pending Operational Dataset TLV - # - Network Name TLV - # - Channel TLV - # - PAN ID TLV - pkts.filter_mle_cmd(MLE_DATA_RESPONSE). \ - filter_wpan_src64(ROUTER). \ - filter_wpan_dst64(SED). \ - filter(lambda p: { - SOURCE_ADDRESS_TLV, - LEADER_DATA_TLV, - ACTIVE_TIMESTAMP_TLV, - PENDING_TIMESTAMP_TLV, - PENDING_OPERATION_DATASET_TLV - } <= set(p.mle.tlv.type) and \ - p.mle.tlv.leader_data.data_version == - _pkt20.mle.tlv.leader_data.data_version and \ - p.mle.tlv.leader_data.stable_data_version == - _pkt20.mle.tlv.leader_data.stable_data_version and \ - p.mle.tlv.active_tstamp == COMM_ACTIVE_TIMESTAMP and \ - p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP - ). \ - must_next() - - # Step 30: The DUT MUST respond with an ICMPv6 Echo Reply - for DUT_RLOC in (LEADER_RLOC, ROUTER_RLOC, MED_RLOC, SED_RLOC): - _pkt = pkts.filter_ping_request().\ - filter_ipv6_src_dst(COMMISSIONER_RLOC, DUT_RLOC).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(DUT_RLOC, COMMISSIONER_RLOC).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_9_2_07_DelayTimer.py b/tests/scripts/thread-cert/Cert_9_2_07_DelayTimer.py deleted file mode 100755 index b4c51668f..000000000 --- a/tests/scripts/thread-cert/Cert_9_2_07_DelayTimer.py +++ /dev/null @@ -1,228 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import thread_cert -from pktverify.consts import MLE_CHILD_ID_RESPONSE, MLE_DATA_RESPONSE, MGMT_PENDING_SET_URI, MGMT_ACTIVE_SET_URI, MGMT_DATASET_CHANGED_URI, COAP_CODE_ACK, ACTIVE_OPERATION_DATASET_TLV, ACTIVE_TIMESTAMP_TLV, PENDING_TIMESTAMP_TLV, NM_CHANNEL_TLV, NM_CHANNEL_MASK_TLV, NM_EXTENDED_PAN_ID_TLV, NM_NETWORK_KEY_TLV, NM_NETWORK_MESH_LOCAL_PREFIX_TLV, NM_NETWORK_NAME_TLV, NM_PAN_ID_TLV, NM_PSKC_TLV, NM_SECURITY_POLICY_TLV, SOURCE_ADDRESS_TLV, LEADER_DATA_TLV, ACTIVE_TIMESTAMP_TLV, NETWORK_DATA_TLV, NM_BORDER_AGENT_LOCATOR_TLV, NM_COMMISSIONER_SESSION_ID_TLV, NM_DELAY_TIMER_TLV, PENDING_OPERATION_DATASET_TLV -from pktverify.packet_verifier import PacketVerifier - -PANID_INIT = 0xface - -COMMISSIONER = 1 -LEADER = 2 -ROUTER = 3 - -LEADER_ACTIVE_TIMESTAMP = 10 -ROUTER_ACTIVE_TIMESTAMP = 20 -ROUTER_PENDING_TIMESTAMP = 30 -ROUTER_PENDING_ACTIVE_TIMESTAMP = 25 -ROUTER_DELAY_TIMER = 3600000 - -COMMISSIONER_PENDING_TIMESTAMP = 40 -COMMISSIONER_PENDING_ACTIVE_TIMESTAMP = 80 -COMMISSIONER_DELAY_TIMER = 60000 -COMMISSIONER_PENDING_CHANNEL = 20 -COMMISSIONER_PENDING_PANID = 0xafce - - -class Cert_9_2_7_DelayTimer(thread_cert.TestCase): - SUPPORT_NCP = False - - TOPOLOGY = { - COMMISSIONER: { - 'name': 'COMMISSIONER', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'partition_id': 0xffffffff, - 'allowlist': [COMMISSIONER] - }, - ROUTER: { - 'name': 'ROUTER', - 'mode': 'rdn', - 'partition_id': 1, - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[COMMISSIONER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'router') - self.nodes[COMMISSIONER].commissioner_start() - self.simulator.go(3) - - self.nodes[COMMISSIONER].send_mgmt_active_set(active_timestamp=LEADER_ACTIVE_TIMESTAMP,) - self.simulator.go(5) - - self.nodes[ROUTER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER].get_state(), 'leader') - - self.nodes[LEADER].add_allowlist(self.nodes[ROUTER].get_addr64()) - self.nodes[ROUTER].add_allowlist(self.nodes[LEADER].get_addr64()) - self.simulator.go(35) - self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'router') - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - self.assertEqual(self.nodes[ROUTER].get_state(), 'router') - - self.nodes[ROUTER].commissioner_start() - self.simulator.go(3) - self.nodes[ROUTER].send_mgmt_active_set(active_timestamp=ROUTER_ACTIVE_TIMESTAMP,) - self.simulator.go(30) - - self.nodes[ROUTER].send_mgmt_pending_set( - pending_timestamp=ROUTER_PENDING_TIMESTAMP, - active_timestamp=ROUTER_PENDING_ACTIVE_TIMESTAMP, - delay_timer=ROUTER_DELAY_TIMER, - ) - self.simulator.go(60) - - self.nodes[COMMISSIONER].send_mgmt_pending_set( - pending_timestamp=COMMISSIONER_PENDING_TIMESTAMP, - active_timestamp=COMMISSIONER_PENDING_ACTIVE_TIMESTAMP, - delay_timer=COMMISSIONER_DELAY_TIMER, - channel=COMMISSIONER_PENDING_CHANNEL, - panid=COMMISSIONER_PENDING_PANID, - ) - self.simulator.go(120) - - self.assertEqual(self.nodes[LEADER].get_panid(), COMMISSIONER_PENDING_PANID) - self.assertEqual(self.nodes[COMMISSIONER].get_panid(), COMMISSIONER_PENDING_PANID) - self.assertEqual(self.nodes[ROUTER].get_panid(), COMMISSIONER_PENDING_PANID) - - self.assertEqual(self.nodes[LEADER].get_channel(), COMMISSIONER_PENDING_CHANNEL) - self.assertEqual( - self.nodes[COMMISSIONER].get_channel(), - COMMISSIONER_PENDING_CHANNEL, - ) - self.assertEqual(self.nodes[ROUTER].get_channel(), COMMISSIONER_PENDING_CHANNEL) - - self.collect_rloc16s() - self.collect_rlocs() - ipaddrs = self.nodes[ROUTER].get_addrs() - for ipaddr in ipaddrs: - if ipaddr[0:4] != 'fe80': - break - self.assertTrue(self.nodes[LEADER].ping(ipaddr)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_RLOC16 = pv.vars['LEADER_RLOC16'] - COMMISSIONER = pv.vars['COMMISSIONER'] - COMMISSIONER_RLOC = pv.vars['COMMISSIONER_RLOC'] - ROUTER = pv.vars['ROUTER'] - ROUTER_RLOC = pv.vars['ROUTER_RLOC'] - ROUTER_RLOC16 = pv.vars['ROUTER_RLOC16'] - _lpkts = pkts.filter_wpan_src64(LEADER) - - # Step 1: Ensure the topology is formed correctly - _lpkts.filter_wpan_dst64(COMMISSIONER).filter_mle_cmd(MLE_CHILD_ID_RESPONSE).must_next() - _lpkts_coap = _lpkts.copy() - - # Step 4: Leader MUST send a unicast MLE Child ID Response to the Router - _lpkts.filter_wpan_dst64(ROUTER).filter_mle_cmd(MLE_CHILD_ID_RESPONSE).must_next( - ).must_verify(lambda p: {ACTIVE_OPERATION_DATASET_TLV, ACTIVE_TIMESTAMP_TLV} <= set(p.mle.tlv.type) and { - NM_CHANNEL_TLV, NM_CHANNEL_MASK_TLV, NM_EXTENDED_PAN_ID_TLV, NM_NETWORK_KEY_TLV, - NM_NETWORK_MESH_LOCAL_PREFIX_TLV, NM_NETWORK_NAME_TLV, NM_PAN_ID_TLV, NM_PSKC_TLV, NM_SECURITY_POLICY_TLV - } <= set(p.thread_meshcop.tlv.type) and p.mle.tlv.active_tstamp == LEADER_ACTIVE_TIMESTAMP) - - # Step 6: Leader automatically sends a MGMT_ACTIVE_SET.rsp to the Router - _lpkts.filter_ipv6_dst(ROUTER_RLOC).filter_coap_ack(MGMT_ACTIVE_SET_URI).must_next().must_verify( - lambda p: p.coap.code == COAP_CODE_ACK and p.thread_meshcop.tlv.state == 1) - - # Step 7: Leader multicasts a MLE Data Response with the new information - _lpkts.filter_LLANMA().filter_mle_cmd(MLE_DATA_RESPONSE).must_next().must_verify( - lambda p: {SOURCE_ADDRESS_TLV, LEADER_DATA_TLV, ACTIVE_TIMESTAMP_TLV, NETWORK_DATA_TLV} <= set( - p.mle.tlv.type) and {NM_BORDER_AGENT_LOCATOR_TLV, NM_COMMISSIONER_SESSION_ID_TLV} <= set( - p.thread_meshcop.tlv.type) and p.thread_nwd.tlv.stable == [0] and p.mle.tlv.active_tstamp == - ROUTER_ACTIVE_TIMESTAMP) - - # Step 10: Leader MUST send a unicast MLE Data Response to the Router - _lpkts.filter_wpan_dst64(ROUTER).filter_mle_cmd(MLE_DATA_RESPONSE).must_next( - ).must_verify(lambda p: {ACTIVE_OPERATION_DATASET_TLV, ACTIVE_TIMESTAMP_TLV} <= set(p.mle.tlv.type) and { - NM_CHANNEL_TLV, NM_CHANNEL_MASK_TLV, NM_EXTENDED_PAN_ID_TLV, NM_NETWORK_KEY_TLV, - NM_NETWORK_MESH_LOCAL_PREFIX_TLV, NM_NETWORK_NAME_TLV, NM_PAN_ID_TLV, NM_PSKC_TLV, NM_SECURITY_POLICY_TLV - } <= set(p.thread_meshcop.tlv.type) and p.mle.tlv.active_tstamp == ROUTER_ACTIVE_TIMESTAMP) - - # Step 12: Leader sends a MGMT_PENDING_SET.rsp to the Router with Status = Accept - _lpkts_coap.filter_ipv6_dst(ROUTER_RLOC).filter_coap_ack(MGMT_PENDING_SET_URI).must_next().must_verify( - lambda p: p.coap.code == COAP_CODE_ACK and p.thread_meshcop.tlv.state == 1) - - # Step 13: Leader sends a multicast MLE Data Response - _lpkts.filter_LLANMA().filter_mle_cmd(MLE_DATA_RESPONSE).must_next().must_verify( - lambda p: { - SOURCE_ADDRESS_TLV, LEADER_DATA_TLV, ACTIVE_TIMESTAMP_TLV, PENDING_TIMESTAMP_TLV, NETWORK_DATA_TLV - } <= set(p.mle.tlv.type) and p.thread_nwd.tlv.stable == [0] and p.mle.tlv.active_tstamp == - ROUTER_ACTIVE_TIMESTAMP and p.mle.tlv.pending_tstamp == ROUTER_PENDING_TIMESTAMP) - - # Step 14: The DUT MUST send MGMT_DATASET_CHANGED.ntf to the Router - _lpkts_coap.filter_wpan_dst16(ROUTER_RLOC16).filter_coap_request(MGMT_DATASET_CHANGED_URI).must_next() - - # Step 16: Leader MUST send a unicast MLE Data Response to the Router - _lpkts.filter_wpan_dst64(ROUTER).filter_mle_cmd(MLE_DATA_RESPONSE).must_next().must_verify( - lambda p: {ACTIVE_TIMESTAMP_TLV, PENDING_TIMESTAMP_TLV} <= set(p.mle.tlv.type) and p.mle.tlv.active_tstamp - == ROUTER_ACTIVE_TIMESTAMP and p.mle.tlv.pending_tstamp == ROUTER_PENDING_TIMESTAMP) - - # Step 18: The DUT MUST send MGMT_PENDING_SET.rsp to the Commissioner - _lpkts_coap.filter_ipv6_dst(COMMISSIONER_RLOC).filter_coap_ack(MGMT_PENDING_SET_URI).must_next().must_verify( - lambda p: p.coap.code == COAP_CODE_ACK and p.thread_meshcop.tlv.state == 1) - - # Step 19: Leader MUST send a unicast MLE Data Response to the Router - _lpkts.filter_LLANMA().filter_mle_cmd(MLE_DATA_RESPONSE).must_next().must_verify( - lambda p: { - SOURCE_ADDRESS_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV, PENDING_TIMESTAMP_TLV - } <= set(p.mle.tlv.type) and p.thread_nwd.tlv.stable == [0] and p.mle.tlv.active_tstamp == - ROUTER_ACTIVE_TIMESTAMP and p.mle.tlv.pending_tstamp == COMMISSIONER_PENDING_TIMESTAMP) - - # Step 20: Leader MUST send a unicast MLE Data Response to the Router - _lpkts.filter_wpan_dst64(ROUTER).filter_mle_cmd(MLE_DATA_RESPONSE).must_next( - ).must_verify(lambda p: {ACTIVE_TIMESTAMP_TLV, PENDING_TIMESTAMP_TLV, PENDING_OPERATION_DATASET_TLV} < set( - p.mle.tlv.type) and {NM_CHANNEL_TLV, NM_COMMISSIONER_SESSION_ID_TLV, NM_PAN_ID_TLV, NM_DELAY_TIMER_TLV} <= - set(p.thread_meshcop.tlv.type) and p.mle.tlv.active_tstamp == ROUTER_ACTIVE_TIMESTAMP and p.mle. - tlv.pending_tstamp == COMMISSIONER_PENDING_TIMESTAMP and p.thread_meshcop.tlv.pan_id == - [COMMISSIONER_PENDING_PANID] and p.thread_meshcop.tlv.channel == [COMMISSIONER_PENDING_CHANNEL]) - - # Step 21: Router MUST respond with an ICMPv6 Echo Reply - pkts.filter_wpan_src16_dst16(ROUTER_RLOC16, LEADER_RLOC16).filter_ping_reply().must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_9_2_08_PersistentDatasets.py b/tests/scripts/thread-cert/Cert_9_2_08_PersistentDatasets.py deleted file mode 100755 index a42188169..000000000 --- a/tests/scripts/thread-cert/Cert_9_2_08_PersistentDatasets.py +++ /dev/null @@ -1,353 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest -import copy - -import config -import thread_cert -from pktverify.consts import MLE_PARENT_REQUEST, MLE_DATA_RESPONSE, MLE_DATA_REQUEST, MLE_CHILD_UPDATE_REQUEST, MGMT_PENDING_SET_URI, ACTIVE_OPERATION_DATASET_TLV, ACTIVE_TIMESTAMP_TLV, PENDING_TIMESTAMP_TLV, TLV_REQUEST_TLV, NETWORK_DATA_TLV, NM_BORDER_AGENT_LOCATOR_TLV, NM_COMMISSIONER_SESSION_ID_TLV, NM_DELAY_TIMER_TLV, PENDING_OPERATION_DATASET_TLV, NWD_COMMISSIONING_DATA_TLV, LEADER_ALOC -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -COMMISSIONER = 1 -LEADER = 2 -DUT = 3 - -CHANNEL_INIT = 19 -PANID_INIT = 0xface -LEADER_ACTIVE_TIMESTAMP = 10 - -COMMISSIONER_PENDING_TIMESTAMP = 20 -COMMISSIONER_ACTIVE_TIMESTAMP = 70 -COMMISSIONER_DELAY_TIMER = 60000 -COMMISSIONER_PENDING_CHANNEL = 20 -COMMISSIONER_PENDING_PANID = 0xafce - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to verify that after a reset, the DUT -# reattaches to the test network using parameters set in Active/Pending -# Operational Datasets. -# -# Test Topology: -# ------------- -# Commissioner -# | -# Leader -# | -# DUT -# -# DUT Types: -# ---------- -# Router -# ED -# SED - - -class Cert_9_2_8_PersistentDatasets_Base(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - SUPPORT_NCP = False - - TOPOLOGY = { - COMMISSIONER: { - 'name': 'COMMISSIONER', - 'mode': 'rdn', - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT, - 'allowlist': [LEADER] - }, - LEADER: { - 'name': 'LEADER', - 'active_dataset': { - 'timestamp': LEADER_ACTIVE_TIMESTAMP, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT - }, - 'mode': 'rdn', - 'allowlist': [COMMISSIONER, DUT] - }, - DUT: { - 'name': 'DUT', - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT, - 'allowlist': [LEADER] - }, - } - - def _setUpDUT(self): - self.nodes[DUT].add_allowlist(self.nodes[LEADER].get_addr64()) - self.nodes[DUT].enable_allowlist() - if self.TOPOLOGY[DUT]['mode'] == 'rdn': - self.nodes[DUT].set_router_selection_jitter(1) - else: - self.nodes[DUT].set_timeout(config.DEFAULT_CHILD_TIMEOUT) - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[COMMISSIONER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'router') - - self.nodes[DUT].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - if self.TOPOLOGY[DUT]['mode'] == 'rdn': - self.assertEqual(self.nodes[DUT].get_state(), 'router') - else: - self.assertEqual(self.nodes[DUT].get_state(), 'child') - - self.collect_rlocs() - - self.nodes[COMMISSIONER].commissioner_start() - self.simulator.go(3) - - self.nodes[COMMISSIONER].send_mgmt_pending_set( - pending_timestamp=COMMISSIONER_PENDING_TIMESTAMP, - active_timestamp=COMMISSIONER_ACTIVE_TIMESTAMP, - delay_timer=COMMISSIONER_DELAY_TIMER, - channel=COMMISSIONER_PENDING_CHANNEL, - panid=COMMISSIONER_PENDING_PANID, - ) - self.simulator.go(5) - - # power down the DUT for 60 seconds - self.nodes[DUT].reset() - self.simulator.go(60) - - # the network moves to COMMISSIONER_PENDING_PANID - self.assertEqual(self.nodes[LEADER].get_panid(), COMMISSIONER_PENDING_PANID) - self.assertEqual(self.nodes[COMMISSIONER].get_panid(), COMMISSIONER_PENDING_PANID) - self.assertEqual(self.nodes[LEADER].get_channel(), COMMISSIONER_PENDING_CHANNEL) - self.assertEqual(self.nodes[COMMISSIONER].get_channel(), COMMISSIONER_PENDING_CHANNEL) - - # restart the DUT to attach to COMMISSIONER_PENDING_CHANNEL - self.nodes[DUT].reset() - self._setUpDUT() - self.nodes[DUT].start() - - self.assertEqual(self.nodes[DUT].get_panid(), PANID_INIT) - self.assertEqual(self.nodes[DUT].get_channel(), CHANNEL_INIT) - self.simulator.go(60) - - self.assertEqual(self.nodes[DUT].get_panid(), COMMISSIONER_PENDING_PANID) - self.assertEqual(self.nodes[DUT].get_channel(), COMMISSIONER_PENDING_CHANNEL) - self.collect_ipaddrs() - - ipaddr = self.nodes[DUT].get_ip6_address(config.ADDRESS_TYPE.ML_EID) - self.assertTrue(self.nodes[COMMISSIONER].ping(ipaddr)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_RLOC = pv.vars['LEADER_RLOC'] - COMMISSIONER = pv.vars['COMMISSIONER'] - COMMISSIONER_MLEID = pv.vars['COMMISSIONER_MLEID'] - COMMISSIONER_RLOC = pv.vars['COMMISSIONER_RLOC'] - DUT_EXTADDR = pv.vars['DUT'] - DUT_MLEID = pv.vars['DUT_MLEID'] - - # Step 1: Ensure the topology is formed correctly - pv.verify_attached('COMMISSIONER', 'LEADER') - if self.TOPOLOGY[DUT]['mode'] == 'rdn': - pv.verify_attached('DUT', 'LEADER') - else: - pv.verify_attached('DUT', 'LEADER', 'MTD') - _pkt = pkts.last() - - # Step 2: Commissioner to send MGMT_PENDING_SET.req to the Leader Anycast - # or Routing Locator: - # CoAP Request URI - # coap://[]:MM/c/ps - # CoAP Payload - # - valid Commissioner Session ID TLV - # - Pending Timestamp TLV : 20s - # - Active Timestamp TLV : 70s - # - Delay Timer TLV : 60s - # - Channel TLV : 20 - # - PAN ID TLV: 0xAFCE - pkts.filter_coap_request(MGMT_PENDING_SET_URI).\ - filter_ipv6_2dsts(LEADER_RLOC, LEADER_ALOC).\ - filter(lambda p: p.thread_meshcop.tlv.active_tstamp == - COMMISSIONER_ACTIVE_TIMESTAMP and\ - p.thread_meshcop.tlv.pending_tstamp == - COMMISSIONER_PENDING_TIMESTAMP and\ - p.thread_meshcop.tlv.delay_timer == - COMMISSIONER_DELAY_TIMER and\ - p.thread_meshcop.tlv.channel == - [COMMISSIONER_PENDING_CHANNEL] and\ - p.thread_meshcop.tlv.pan_id == - [COMMISSIONER_PENDING_PANID] and\ - NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type - ).\ - must_next() - - # Step 3: Leader sends MGMT_PENDING_SET.rsq to the Commissioner: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # - State TLV (value = Accept) - pkts.filter_coap_ack(MGMT_PENDING_SET_URI).\ - filter_wpan_src64(LEADER).\ - filter_ipv6_dst(COMMISSIONER_RLOC).\ - must_next().\ - must_verify(lambda p: p.thread_meshcop.tlv.state == 1) - - if self.TOPOLOGY[DUT]['mode'] != '-': - # Step 4: Leader sends a multicast MLE Data Response with the new network data, - # including the following TLVs: - # - Leader Data TLV: - # Data Version field incremented - # Stable Version field incremented - # - Network Data TLV: - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # - Active Timestamp TLV: 70s - # - Pending Timestamp TLV: 20s - pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter(lambda p: p.mle.tlv.active_tstamp == - LEADER_ACTIVE_TIMESTAMP and\ - p.mle.tlv.pending_tstamp == - COMMISSIONER_PENDING_TIMESTAMP and\ - p.mle.tlv.leader_data.data_version != - (_pkt.mle.tlv.leader_data.data_version + 1) % 256 and\ - p.mle.tlv.leader_data.stable_data_version != - (_pkt.mle.tlv.leader_data.stable_data_version + 1) % 256 and\ - p.thread_nwd.tlv.stable == [0] and\ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ - NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ - NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type - ).\ - must_next() - else: - # Step 5: Leader MUST send a MLE Child Update Request or MLE Data - # Response to SED, including the following TLVs: - # - Leader Data TLV: - # Data Version field incremented - # Stable Version field incremented - # - Network Data TLV: - # - Active Timestamp TLV: 70s - # - Pending Timestamp TLV: 20s - pkts.filter_wpan_src64(LEADER).\ - filter_wpan_dst64(DUT_EXTADDR).\ - filter_mle_cmd2(MLE_CHILD_UPDATE_REQUEST, MLE_DATA_RESPONSE).\ - filter(lambda p: p.mle.tlv.active_tstamp == - LEADER_ACTIVE_TIMESTAMP and\ - p.mle.tlv.pending_tstamp == - COMMISSIONER_PENDING_TIMESTAMP and\ - p.mle.tlv.leader_data.data_version != - (_pkt.mle.tlv.leader_data.data_version + 1) % 256 and\ - p.mle.tlv.leader_data.stable_data_version != - (_pkt.mle.tlv.leader_data.stable_data_version + 1) % 256 and\ - NETWORK_DATA_TLV in p.mle.tlv.type - ).\ - must_next() - - # Step 6: The DUT MUST send a MLE Data Request to the Leader and include its current - # Active Timestamp - pkts.filter_mle_cmd(MLE_DATA_REQUEST).\ - filter_wpan_src64(DUT_EXTADDR).\ - filter_wpan_dst64(LEADER).\ - filter(lambda p: { - TLV_REQUEST_TLV, - NETWORK_DATA_TLV - } <= set(p.mle.tlv.type) and\ - p.thread_nwd.tlv.type is nullField and\ - p.mle.tlv.active_tstamp == LEADER_ACTIVE_TIMESTAMP - ).\ - must_next() - - # Step 6: Leader sends a MLE Data Response including the following TLVs: - # - Active Timestamp TLV - # - Pending Timestamp TLV - # - Pending Operational Dataset TLV - pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter_wpan_src64(LEADER).\ - filter_wpan_dst64(DUT_EXTADDR).\ - filter(lambda p: { - ACTIVE_TIMESTAMP_TLV, - PENDING_TIMESTAMP_TLV, - PENDING_OPERATION_DATASET_TLV - } <= set(p.mle.tlv.type) - ).\ - must_next() - - # Step 9: The DUT MUST attempt to reattach by sending Parent Request using the parameters - # from Active Operational Dataset (Channel ='Primary', PANID: 0xFACE) - # The DUT MUST then attach using the parameters from the Pending Operational - # Dataset (Channel = 'Secondary', PANID:0xAFCE) - for pan_id in (PANID_INIT, COMMISSIONER_PENDING_PANID): - pkts.filter_mle_cmd(MLE_PARENT_REQUEST).\ - filter_wpan_src64(DUT_EXTADDR).\ - filter_LLARMA().\ - filter(lambda p: p.wpan.dst_pan == pan_id).\ - must_next() - - # Step 10: The DUT MUST respond with an ICMPv6 Echo Reply - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(COMMISSIONER).\ - filter_ipv6_dst(DUT_MLEID).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(DUT_EXTADDR).\ - filter_ipv6_dst(COMMISSIONER_MLEID).\ - must_next() - - -class Cert_9_2_8_PersistentDatasets_ROUTER(Cert_9_2_8_PersistentDatasets_Base): - TOPOLOGY = copy.deepcopy(Cert_9_2_8_PersistentDatasets_Base.TOPOLOGY) - TOPOLOGY[DUT]['mode'] = 'rdn' - - -class Cert_9_2_8_PersistentDatasets_ED(Cert_9_2_8_PersistentDatasets_Base): - TOPOLOGY = copy.deepcopy(Cert_9_2_8_PersistentDatasets_Base.TOPOLOGY) - TOPOLOGY[DUT]['mode'] = 'rn' - TOPOLOGY[DUT]['is_mtd'] = True - TOPOLOGY[DUT]['timeout'] = config.DEFAULT_CHILD_TIMEOUT - - -class Cert_9_2_8_PersistentDatasets_SED(Cert_9_2_8_PersistentDatasets_Base): - TOPOLOGY = copy.deepcopy(Cert_9_2_8_PersistentDatasets_Base.TOPOLOGY) - TOPOLOGY[DUT]['mode'] = '-' - TOPOLOGY[DUT]['is_mtd'] = True - TOPOLOGY[DUT]['timeout'] = config.DEFAULT_CHILD_TIMEOUT - - -del (Cert_9_2_8_PersistentDatasets_Base) - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_9_2_09_PendingPartition.py b/tests/scripts/thread-cert/Cert_9_2_09_PendingPartition.py deleted file mode 100755 index a56c47db1..000000000 --- a/tests/scripts/thread-cert/Cert_9_2_09_PendingPartition.py +++ /dev/null @@ -1,762 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import thread_cert -from pktverify.consts import MLE_CHILD_ID_REQUEST, MLE_CHILD_ID_RESPONSE, MLE_DATA_RESPONSE, MLE_DATA_REQUEST, MGMT_PENDING_SET_URI, MGMT_ACTIVE_SET_URI, MGMT_DATASET_CHANGED_URI, SOURCE_ADDRESS_TLV, LEADER_DATA_TLV, ACTIVE_OPERATION_DATASET_TLV, ACTIVE_TIMESTAMP_TLV, PENDING_TIMESTAMP_TLV, TLV_REQUEST_TLV, NETWORK_DATA_TLV, NM_BORDER_AGENT_LOCATOR_TLV, NM_COMMISSIONER_SESSION_ID_TLV, NM_DELAY_TIMER_TLV, PENDING_OPERATION_DATASET_TLV, NWD_COMMISSIONING_DATA_TLV, LEADER_ALOC, NM_ACTIVE_TIMESTAMP_TLV, NM_CHANNEL_TLV, NM_CHANNEL_MASK_TLV, NM_EXTENDED_PAN_ID_TLV, NM_NETWORK_MESH_LOCAL_PREFIX_TLV, NM_NETWORK_KEY_TLV, NM_NETWORK_NAME_TLV, NM_PAN_ID_TLV, NM_PSKC_TLV, NM_SECURITY_POLICY_TLV -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -CHANNEL_INIT = 19 -PANID_INIT = 0xface -TIMESTAMP_INIT = 10 -CHANNEL_SECOND = 20 - -CHANNEL_FINAL = 19 -PANID_FINAL = 0xabcd - -ROUTER2_ACTIVE_TIMESTAMP = 15 -ROUTER2_PENDING_ACTIVE_TIMESTAMP = 410 -ROUTER2_PENDING_TIMESTAMP = 50 -ROUTER2_DELAY_TIMER = 200000 -ROUTER2_NET_NAME = 'TEST' - -COMM_PENDING_ACTIVE_TIMESTAMP = 210 -COMM_PENDING_TIMESTAMP = 30 -COMM_DELAY_TIMER = 1000000 - -COMMISSIONER = 1 -LEADER = 2 -ROUTER1 = 3 -ROUTER2 = 4 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to verify how Pending Operational Datasets -# are synchronized when two partitions merge. -# -# Test Topology: -# ------------- -# Commissioner -# | -# Leader -# | -# Router_1 -# | -# Router_2 -# -# Note: Router_1 and Router_2 will be in&out RF shield box -# -# DUT Types: -# ---------- -# Leader -# Router - - -class Cert_9_2_09_PendingPartition(thread_cert.TestCase): - SUPPORT_NCP = False - - TOPOLOGY = { - COMMISSIONER: { - 'name': 'COMMISSIONER', - 'active_dataset': { - 'timestamp': TIMESTAMP_INIT, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT - }, - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - LEADER: { - 'name': 'LEADER', - 'active_dataset': { - 'timestamp': TIMESTAMP_INIT, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT - }, - 'mode': 'rdn', - 'partition_id': 0xffffffff, - 'allowlist': [COMMISSIONER, ROUTER1] - }, - ROUTER1: { - 'name': 'ROUTER_1', - 'active_dataset': { - 'timestamp': TIMESTAMP_INIT, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT - }, - 'mode': 'rdn', - 'allowlist': [LEADER, ROUTER2] - }, - ROUTER2: { - 'name': 'ROUTER_2', - 'active_dataset': { - 'timestamp': TIMESTAMP_INIT, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT - }, - 'mode': 'rdn', - 'network_id_timeout': 70, - 'allowlist': [ROUTER1] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[COMMISSIONER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'router') - self.nodes[COMMISSIONER].commissioner_start() - self.simulator.go(3) - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[ROUTER2].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER2].get_state(), 'router') - - self.nodes[COMMISSIONER].send_mgmt_pending_set( - pending_timestamp=COMM_PENDING_TIMESTAMP, - active_timestamp=COMM_PENDING_ACTIVE_TIMESTAMP, - delay_timer=COMM_DELAY_TIMER, - channel=CHANNEL_SECOND, - panid=PANID_INIT, - ) - self.simulator.go(5) - - self.nodes[LEADER].remove_allowlist(self.nodes[ROUTER1].get_addr64()) - self.nodes[ROUTER1].remove_allowlist(self.nodes[LEADER].get_addr64()) - self.nodes[ROUTER2].set_preferred_partition_id(1) - self.simulator.go(250) - - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - self.assertEqual(self.nodes[ROUTER2].get_state(), 'leader') - - # Keeping network id timeout at 70 can result in ROUTER2 - # occasionally creating its own partition. Reset back to 120 - # here to avoid occasional test failures. - self.nodes[ROUTER2].set_network_id_timeout(120) - - self.nodes[ROUTER2].commissioner_start() - self.simulator.go(3) - self.nodes[ROUTER2].send_mgmt_active_set( - active_timestamp=ROUTER2_ACTIVE_TIMESTAMP, - network_name=ROUTER2_NET_NAME, - ) - self.simulator.go(5) - - self.nodes[ROUTER2].send_mgmt_pending_set( - pending_timestamp=ROUTER2_PENDING_TIMESTAMP, - active_timestamp=ROUTER2_PENDING_ACTIVE_TIMESTAMP, - delay_timer=ROUTER2_DELAY_TIMER, - channel=CHANNEL_FINAL, - panid=PANID_FINAL, - ) - self.simulator.go(5) - - self.nodes[LEADER].add_allowlist(self.nodes[ROUTER1].get_addr64()) - self.nodes[ROUTER1].add_allowlist(self.nodes[LEADER].get_addr64()) - self.simulator.go(260) - - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - self.assertEqual(self.nodes[ROUTER2].get_state(), 'router') - - self.collect_rlocs() - self.collect_rloc16s() - self.collect_ipaddrs() - self.assertEqual(self.nodes[COMMISSIONER].get_panid(), PANID_FINAL) - self.assertEqual(self.nodes[LEADER].get_panid(), PANID_FINAL) - self.assertEqual(self.nodes[ROUTER1].get_panid(), PANID_FINAL) - self.assertEqual(self.nodes[ROUTER2].get_panid(), PANID_FINAL) - - self.assertEqual(self.nodes[COMMISSIONER].get_channel(), CHANNEL_FINAL) - self.assertEqual(self.nodes[LEADER].get_channel(), CHANNEL_FINAL) - self.assertEqual(self.nodes[ROUTER1].get_channel(), CHANNEL_FINAL) - self.assertEqual(self.nodes[ROUTER2].get_channel(), CHANNEL_FINAL) - - leader_addr = self.nodes[LEADER].get_ip6_address(config.ADDRESS_TYPE.ML_EID) - router1_addr = self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.ML_EID) - self.assertTrue(self.nodes[ROUTER2].ping(leader_addr, timeout=10)) - self.assertTrue(self.nodes[COMMISSIONER].ping(router1_addr, timeout=10)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_RLOC = pv.vars['LEADER_RLOC'] - LEADER_MLEID = pv.vars['LEADER_MLEID'] - COMMISSIONER = pv.vars['COMMISSIONER'] - COMMISSIONER_MLEID = pv.vars['COMMISSIONER_MLEID'] - COMMISSIONER_RLOC = pv.vars['COMMISSIONER_RLOC'] - COMMISSIONER_RLOC16 = pv.vars['COMMISSIONER_RLOC16'] - ROUTER_1 = pv.vars['ROUTER_1'] - ROUTER_1_RLOC = pv.vars['ROUTER_1_RLOC'] - ROUTER_1_MLEID = pv.vars['ROUTER_1_MLEID'] - ROUTER_2 = pv.vars['ROUTER_2'] - ROUTER_2_RLOC = pv.vars['ROUTER_2_RLOC'] - ROUTER_2_MLEID = pv.vars['ROUTER_2_MLEID'] - - # Step 1: Ensure the topology is formed correctly - for node in ('COMMISSIONER', 'ROUTER_1'): - pv.verify_attached(node, 'LEADER') - pv.verify_attached('ROUTER_2', 'ROUTER_1') - _pkt = pkts.last() - - # Step 3: Leader sends MGMT_PENDING_SET.rsq to the Commissioner: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # - State TLV (value = Accept) - pkts.filter_coap_ack(MGMT_PENDING_SET_URI).\ - filter_wpan_src64(LEADER).\ - filter_ipv6_dst(COMMISSIONER_RLOC).\ - must_next().\ - must_verify(lambda p: p.thread_meshcop.tlv.state == 1) - - # Step 4: Leader MUST multicast MLE Data Response with the new network data, - # including the following TLVs: - # - Source Address TLV - # - Leader Data TLV: - # Data Version field incremented - # Stable Version field incremented - # - Network Data TLV: - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # - Active Timestamp TLV: 10s - # - Pending Timestamp TLV: 30s - # - # Router_1 MUST send a unicast MLE Data Request to the Leader, including the - # following TLVs: - # - TLV Request TLV: - # - Network Data TLV - # - Active Timestamp TLV (10s) - pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter(lambda p: p.mle.tlv.active_tstamp == TIMESTAMP_INIT and\ - p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and\ - (p.mle.tlv.leader_data.data_version - - _pkt.mle.tlv.leader_data.data_version) % 256 <= 127 and\ - (p.mle.tlv.leader_data.stable_data_version - - _pkt.mle.tlv.leader_data.stable_data_version) % 256 <= 127 and\ - p.thread_nwd.tlv.stable == [0] and\ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ - NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ - NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type - ).\ - must_next() - - pkts.filter_wpan_src64(ROUTER_1).\ - filter_wpan_dst64(LEADER).\ - filter_mle_cmd(MLE_DATA_REQUEST).\ - filter(lambda p: { - TLV_REQUEST_TLV, - NETWORK_DATA_TLV, - ACTIVE_TIMESTAMP_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.active_tstamp == TIMESTAMP_INIT and\ - p.thread_meshcop.tlv.type is nullField - ).\ - must_next() - - # Step 5: Leader sends a MLE Data Response to Router_1 including the following TLVs: - # - Source Address TLV - # - Leader Data TLV - # - Network Data TLV - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # - Active Timestamp TLV: 10s - # - Pending Timestamp TLV: 30s - # - Pending Operational Dataset TLV - # - Active Timestamp TLV <210s> - # - Delay Timer TLV <~ 1000s> - # - Channel TLV : ‘Secondary’ - # - PAN ID TLV : 0xAFCE - _dr_pkt = pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter_wpan_src64(LEADER).\ - filter_wpan_dst64(ROUTER_1).\ - filter(lambda p: { - SOURCE_ADDRESS_TLV, - LEADER_DATA_TLV, - ACTIVE_TIMESTAMP_TLV, - PENDING_TIMESTAMP_TLV, - PENDING_OPERATION_DATASET_TLV - } <= set(p.mle.tlv.type) and\ - p.thread_nwd.tlv.stable == [0] and\ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ - NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ - NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type and\ - p.mle.tlv.active_tstamp == TIMESTAMP_INIT and\ - p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and\ - p.thread_meshcop.tlv.delay_timer < COMM_DELAY_TIMER and\ - p.thread_meshcop.tlv.active_tstamp == COMM_PENDING_ACTIVE_TIMESTAMP and\ - p.thread_meshcop.tlv.channel == [CHANNEL_SECOND] and\ - p.thread_meshcop.tlv.pan_id == [PANID_INIT] - ).\ - must_next() - - # Step 6: Router_1 MUST multicast MLE Data Response with the new network data, - # including the following TLVs: - # - Source Address TLV - # - Leader Data TLV: - # Data Version field incremented - # Stable Version field incremented - # - Network Data TLV: - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # - Active Timestamp TLV: 10s - # - Pending Timestamp TLV: 30s - with pkts.save_index(): - pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter_wpan_src64(ROUTER_1).\ - filter_LLANMA().\ - filter(lambda p: p.mle.tlv.active_tstamp == TIMESTAMP_INIT and\ - p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and\ - (p.mle.tlv.leader_data.data_version - - _pkt.mle.tlv.leader_data.data_version) % 256 <= 127 and\ - (p.mle.tlv.leader_data.stable_data_version - - _pkt.mle.tlv.leader_data.stable_data_version) % 256 <= 127 and\ - p.thread_nwd.tlv.stable == [0] and\ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ - NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ - NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type - ).\ - must_next() - - # Step 8: Router_1 sends a MLE Data Response to Router_2 including the following TLVs: - # - Source Address TLV - # - Leader Data TLV - # - Network Data TLV - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # - Active Timestamp TLV: 10s - # - Pending Timestamp TLV: 30s - # - Pending Operational Dataset TLV - # - Active Timestamp TLV <210s> - # - Delay Timer TLV <~ 1000s> - # - Channel TLV : ‘Secondary’ - # - PAN ID TLV : 0xAFCE - pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter_wpan_src64(ROUTER_1).\ - filter_wpan_dst64(ROUTER_2).\ - filter(lambda p: { - SOURCE_ADDRESS_TLV, - LEADER_DATA_TLV, - ACTIVE_TIMESTAMP_TLV, - PENDING_TIMESTAMP_TLV, - PENDING_OPERATION_DATASET_TLV - } <= set(p.mle.tlv.type) and\ - p.thread_nwd.tlv.stable == [0] and\ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ - NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ - NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type and\ - p.mle.tlv.active_tstamp == TIMESTAMP_INIT and\ - p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and\ - p.thread_meshcop.tlv.delay_timer < COMM_DELAY_TIMER and\ - p.thread_meshcop.tlv.active_tstamp == COMM_PENDING_ACTIVE_TIMESTAMP and\ - p.thread_meshcop.tlv.channel == [CHANNEL_SECOND] and\ - p.thread_meshcop.tlv.pan_id == [PANID_INIT] - ).\ - must_next() - - # Step 10: Router_1 MUST attach to the new partition formed by Router_2 - pv.verify_attached('ROUTER_1', 'ROUTER_2') - _pkt = pkts.last() - - # Step 12: Router_1 MUST send a unicast MLE Data Request to the Router_2, including the - # following TLVs: - # - TLV Request TLV: - # - Network Data TLV - # - Active Timestamp TLV (10s) - # - Pending Timestamp TLV (30s) - with pkts.save_index(): - pkts.filter_wpan_src64(ROUTER_1).\ - filter_wpan_dst64(LEADER).\ - filter_mle_cmd(MLE_DATA_REQUEST).\ - filter(lambda p: { - TLV_REQUEST_TLV, - NETWORK_DATA_TLV, - ACTIVE_TIMESTAMP_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.active_tstamp == TIMESTAMP_INIT and\ - p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and\ - p.thread_meshcop.tlv.type is nullField - ).\ - must_next() - - # Step 14: Router_1 MUST multicast MLE Data Response with the new network data, - # including the following TLVs: - # - Source Address TLV - # - Leader Data TLV: - # Data Version field incremented - # Stable Version field incremented - # - Network Data TLV: - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # - Active Timestamp TLV: 15s - # - Pending Timestamp TLV: 30s - pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter_wpan_src64(ROUTER_1).\ - filter_LLANMA().\ - filter(lambda p: p.mle.tlv.active_tstamp == ROUTER2_ACTIVE_TIMESTAMP and\ - p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and\ - (p.mle.tlv.leader_data.data_version - - _pkt.mle.tlv.leader_data.data_version) % 256 <= 127 and\ - (p.mle.tlv.leader_data.stable_data_version - - _pkt.mle.tlv.leader_data.stable_data_version) % 256 <= 127 and\ - p.thread_nwd.tlv.stable == [0] and\ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ - NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ - NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type - ).\ - must_next() - - # Step 17: Router_1 MUST send a unicast MLE Data Request to the Router_2, including the - # following TLVs: - # - TLV Request TLV: - # - Network Data TLV - # - Active Timestamp TLV (15s) - # - Pending Timestamp TLV (30s) - pkts.filter_wpan_src64(ROUTER_1).\ - filter_wpan_dst64(ROUTER_2).\ - filter_mle_cmd(MLE_DATA_REQUEST).\ - filter(lambda p: { - TLV_REQUEST_TLV, - NETWORK_DATA_TLV, - ACTIVE_TIMESTAMP_TLV - } <= set(p.mle.tlv.type) and\ - p.mle.tlv.active_tstamp == ROUTER2_ACTIVE_TIMESTAMP and\ - p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and\ - p.thread_meshcop.tlv.type is nullField - ).\ - must_next() - - # Step 19: Router_1 MUST multicast MLE Data Response with the new network data, - # including the following TLVs: - # - Source Address TLV - # - Leader Data TLV: - # Data Version field incremented - # Stable Version field incremented - # - Network Data TLV: - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # - Active Timestamp TLV: 15s - # - Pending Timestamp TLV: 50s - pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter_wpan_src64(ROUTER_1).\ - filter_LLANMA().\ - filter(lambda p: p.mle.tlv.active_tstamp == ROUTER2_ACTIVE_TIMESTAMP and\ - p.mle.tlv.pending_tstamp == ROUTER2_PENDING_TIMESTAMP and\ - (p.mle.tlv.leader_data.data_version - - _pkt.mle.tlv.leader_data.data_version) % 256 <= 127 and\ - (p.mle.tlv.leader_data.stable_data_version - - _pkt.mle.tlv.leader_data.stable_data_version) % 256 <= 127 and\ - p.thread_nwd.tlv.stable == [0] and\ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ - NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ - NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type - ).\ - must_next() - - # Step 21: Router_1 MUST go through the attachment process and send MLE Child ID - # Request to the Leader, including the following TLV: - # - Active Timestamp TLV: 15s - pkts.filter_mle_cmd(MLE_CHILD_ID_REQUEST).\ - filter_wpan_src64(ROUTER_1).\ - filter_wpan_dst64(LEADER).\ - filter(lambda p: p.mle.tlv.active_tstamp == ROUTER2_ACTIVE_TIMESTAMP).\ - must_next() - - # Step 22: Leader MUST send MLE Child ID Response to Router_1, including its current - # active timestamp and active configuration set: - # - Active Timestamp TLV: 10s - # - Active Operational Dataset TLV: - # - Pending Timestamp TLV: 30s - # - Pending Operational Dataset TLV: - # - Active Timestamp TLV:210s - _pkt = pkts.filter_mle_cmd(MLE_CHILD_ID_RESPONSE).\ - filter_wpan_src64(LEADER).\ - filter_wpan_dst64(ROUTER_1).\ - filter(lambda p: - p.mle.tlv.active_tstamp == TIMESTAMP_INIT and\ - p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and\ - p.thread_meshcop.tlv.active_tstamp == COMM_PENDING_ACTIVE_TIMESTAMP - ).\ - must_next() - - # Step 23: Router_1 MUST send MGMT_ACTIVE_SET.req to the Leader RLOC or Anycast Locator: - # CoAP Request URI - # coap://[Leader]:MM/c/as - # CoAP Payload - # - Active Timestamp TLV: 15s - # - Network Name TLV: “TEST” - # - PAN ID TLV - # - Channel TLV - with pkts.save_index(): - pkts.filter_wpan_src64(ROUTER_1).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_ACTIVE_SET_URI) .\ - filter(lambda p: { - NM_ACTIVE_TIMESTAMP_TLV, - NM_CHANNEL_TLV, - NM_NETWORK_NAME_TLV, - NM_PAN_ID_TLV, - } <= set(p.thread_meshcop.tlv.type) and\ - p.thread_meshcop.tlv.active_tstamp == ROUTER2_ACTIVE_TIMESTAMP and\ - p.thread_meshcop.tlv.net_name == [ROUTER2_NET_NAME] - ).\ - must_next() - - # Step 24: Leader sends MGMT_ACTIVE_SET.rsp to the Router_1: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # - State TLV (value = Accept) - # TODO: this ack can not be parsed by pktverify - - # Step 25: Leader MUST send MGMT_DATASET_CHANGED.ntf to Commissioner: - # CoAP Request URI - # coap://[ Commissioner]:MM/c/dc - # CoAP Payload - # - with pkts.save_index(): - pkts.filter_wpan_src64(LEADER).\ - filter_wpan_dst16(COMMISSIONER_RLOC16).\ - filter_coap_request(MGMT_DATASET_CHANGED_URI) .\ - filter(lambda p: p.thread_meshcop.tlv.type is nullField).\ - must_next() - - # Step 27: Router_1 MUST send MGMT_PENDING_SET.req to the Leader RLOC or Anycast Locator: - # CoAP Request URI - # coap://[Leader]:MM/c/ps - # CoAP Payload - # - Delay Timer TLV: ~200s - # - Channel TLV : ‘Primary’ - # - PAN ID TLV : 0xABCD - # - Network Name TLV: ‘TEST’ - # - Active Timestamp TLV: 410s - # - Pending Timestamp TLV: 50s - with pkts.save_index(): - pkts.filter_wpan_src64(ROUTER_1).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_PENDING_SET_URI) .\ - filter(lambda p: - p.thread_meshcop.tlv.delay_timer < ROUTER2_DELAY_TIMER and\ - p.thread_meshcop.tlv.channel == [CHANNEL_FINAL] and\ - p.thread_meshcop.tlv.pan_id == [PANID_FINAL] and\ - p.thread_meshcop.tlv.active_tstamp == ROUTER2_PENDING_ACTIVE_TIMESTAMP and\ - p.thread_meshcop.tlv.pending_tstamp == ROUTER2_PENDING_TIMESTAMP and\ - p.thread_meshcop.tlv.net_name == [ROUTER2_NET_NAME] - ).\ - must_next() - - # Step 28: Leader sends MGMT_PENDING_SET.rsq to the Router_1: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # - State TLV (value = Accept) - # TODO: this ack can not be parsed by pktverify - - # Step 29: Leader MUST send MGMT_DATASET_CHANGED.ntf to Commissioner: - # CoAP Request URI - # coap://[ Commissioner]:MM/c/dc - # CoAP Payload - # - pkts.filter_wpan_src64(LEADER).\ - filter_wpan_dst16(COMMISSIONER_RLOC16).\ - filter_coap_request(MGMT_DATASET_CHANGED_URI) .\ - filter(lambda p: p.thread_meshcop.tlv.type is nullField).\ - must_next() - - # Step 30: Leader MUST multicast MLE Data Response with the new network data, - # including the following TLVs: - # - Source Address TLV - # - Leader Data TLV: - # Data Version field incremented - # Stable Version field incremented - # - Network Data TLV: - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # - Active Timestamp TLV: 15s - # - Pending Timestamp TLV: 50s - pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter(lambda p: p.mle.tlv.active_tstamp == ROUTER2_ACTIVE_TIMESTAMP and\ - p.mle.tlv.pending_tstamp == ROUTER2_PENDING_TIMESTAMP and\ - (p.mle.tlv.leader_data.data_version - - _pkt.mle.tlv.leader_data.data_version) % 256 <= 127 and\ - (p.mle.tlv.leader_data.stable_data_version - - _pkt.mle.tlv.leader_data.stable_data_version) % 256 <= 127 and\ - p.thread_nwd.tlv.stable == [0] and\ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ - NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ - NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type - ).\ - must_next() - - # - # Disable steps 32, 33, and 34 until a solution is - # found. Depending on timing, there may be one MLE Data - # Request/Response exchange for both Active and Pending - # Operational Datasets or individual MLE Data Request/Response - # exchange for each Active and Pending Operational Dataset - # separately. - # - - # Step 32: Leader sends a MLE Data Response to Commissioner including the following TLVs: - # - Source Address TLV - # - Leader Data TLV - # - Active Timestamp TLV: 15s - # - Active Operational Dataset TLV: - # - Network Name TLV : ‘TEST’ - # - Pending Timestamp TLV: 50s - # - Pending Operational Dataset TLV - # - Active Timestamp TLV <410s> - # - Delay Timer TLV <~ 200s> - # - Channel TLV : ‘Primary’ - # - PAN ID TLV : 0xABCD - # - Network Name TLV : 'TEST' - #with pkts.save_index(): - # pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ - # filter_wpan_src64(LEADER).\ - # filter_wpan_dst64(COMMISSIONER).\ - # filter(lambda p: { - # SOURCE_ADDRESS_TLV, - # LEADER_DATA_TLV, - # ACTIVE_TIMESTAMP_TLV, - # PENDING_TIMESTAMP_TLV, - # PENDING_OPERATION_DATASET_TLV - # } <= set(p.mle.tlv.type) and\ - # p.thread_nwd.tlv.stable == [0] and\ - # NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ - # NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ - # NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type and\ - # p.mle.tlv.active_tstamp == ROUTER2_ACTIVE_TIMESTAMP and\ - # p.mle.tlv.pending_tstamp == ROUTER2_PENDING_TIMESTAMP and\ - # p.thread_meshcop.tlv.net_name == [ROUTER2_NET_NAME, ROUTER2_NET_NAME] and\ - # p.thread_meshcop.tlv.delay_timer < ROUTER2_DELAY_TIMER and\ - # p.thread_meshcop.tlv.active_tstamp == ROUTER2_PENDING_ACTIVE_TIMESTAMP and\ - # p.thread_meshcop.tlv.channel == [CHANNEL_INIT, CHANNEL_FINAL] and\ - # p.thread_meshcop.tlv.pan_id == [PANID_INIT, PANID_FINAL] - # ).\ - # must_next() - - # Step 33: Router_1 MUST send a unicast MLE Data Request to the Leader, including the - # following TLVs: - # - TLV Request TLV: - # - Network Data TLV - # - Active Timestamp TLV (10s) - # - Pending Timestamp TLV (30s) - #pkts.filter_wpan_src64(ROUTER_1).\ - # filter_wpan_dst64(LEADER).\ - # filter_mle_cmd(MLE_DATA_REQUEST).\ - # filter(lambda p: { - # TLV_REQUEST_TLV, - # NETWORK_DATA_TLV, - # ACTIVE_TIMESTAMP_TLV - # } <= set(p.mle.tlv.type) and\ - # p.mle.tlv.active_tstamp == TIMESTAMP_INIT and\ - # p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and\ - # p.thread_meshcop.tlv.type is nullField - # ).\ - # must_next() - - # Step 34: Leader sends a MLE Data Response to Router_1 including the following TLVs: - # - Source Address TLV - # - Leader Data TLV - # - Active Timestamp TLV: 15s - # - Active Operational Dataset TLV: - # - Network Name TLV : ‘TEST’ - # - Pending Timestamp TLV: 50s - # - Pending Operational Dataset TLV - # - Active Timestamp TLV <410s> - # - Delay Timer TLV <~ 200s> - # - Channel TLV : ‘Primary’ - # - PAN ID TLV : 0xABCD - #pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ - # filter_wpan_src64(LEADER).\ - # filter_wpan_dst64(ROUTER_1).\ - # filter(lambda p: { - # SOURCE_ADDRESS_TLV, - # LEADER_DATA_TLV, - # ACTIVE_TIMESTAMP_TLV, - # PENDING_TIMESTAMP_TLV, - # PENDING_OPERATION_DATASET_TLV - # } <= set(p.mle.tlv.type) and\ - # p.mle.tlv.active_tstamp == ROUTER2_ACTIVE_TIMESTAMP and\ - # p.mle.tlv.pending_tstamp == ROUTER2_PENDING_TIMESTAMP and\ - # p.thread_meshcop.tlv.delay_timer < ROUTER2_DELAY_TIMER and\ - # p.thread_meshcop.tlv.active_tstamp == ROUTER2_PENDING_ACTIVE_TIMESTAMP and\ - # p.thread_meshcop.tlv.channel == [CHANNEL_INIT, CHANNEL_FINAL] and\ - # p.thread_meshcop.tlv.pan_id == [PANID_INIT, PANID_FINAL] - # ).\ - # must_next() - - # Step 36: The DUT MUST respond with an ICMPv6 Echo Reply - _pkt = pkts.filter_ping_request().\ - filter_ipv6_src_dst(ROUTER_2_MLEID, LEADER_MLEID).\ - filter_ipv6_dst(LEADER_MLEID).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(LEADER_MLEID, ROUTER_2_MLEID).\ - must_next() - - _pkt = pkts.filter_ping_request().\ - filter_ipv6_src_dst(COMMISSIONER_MLEID, ROUTER_1_MLEID).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_ipv6_src_dst(ROUTER_1_MLEID, COMMISSIONER_MLEID).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_9_2_10_PendingPartition.py b/tests/scripts/thread-cert/Cert_9_2_10_PendingPartition.py deleted file mode 100755 index c5c634530..000000000 --- a/tests/scripts/thread-cert/Cert_9_2_10_PendingPartition.py +++ /dev/null @@ -1,242 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import thread_cert -from pktverify.consts import MLE_ADVERTISEMENT, MLE_PARENT_REQUEST, MLE_DATA_REQUEST, MLE_DATA_RESPONSE, MLE_CHILD_UPDATE_REQUEST, MLE_CHILD_UPDATE_RESPONSE, MLE_CHILD_ID_REQUEST, MLE_CHILD_ID_RESPONSE, ADDR_SOL_URI, VERSION_TLV, TLV_REQUEST_TLV, SOURCE_ADDRESS_TLV, LEADER_DATA_TLV, CHALLENGE_TLV, LINK_MARGIN_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV, PENDING_TIMESTAMP_TLV, ACTIVE_OPERATION_DATASET_TLV, PENDING_OPERATION_DATASET_TLV, LINK_LOCAL_ALL_NODES_MULTICAST_ADDRESS, LINK_LOCAL_ALL_ROUTERS_MULTICAST_ADDRESS, NM_COMMISSIONER_SESSION_ID_TLV, NM_BORDER_AGENT_LOCATOR_TLV, NM_CHANNEL_TLV, NM_NETWORK_MESH_LOCAL_PREFIX_TLV, NM_PAN_ID_TLV, NM_DELAY_TIMER_TLV, NM_ACTIVE_TIMESTAMP_TLV -from pktverify.packet_verifier import PacketVerifier - -CHANNEL_INIT = 19 -PANID_INIT = 0xface - -CHANNEL_FINAL = 16 -PANID_FINAL = 0xafce - -COMMISSIONER = 1 -LEADER = 2 -ROUTER1 = 3 -ED1 = 4 -SED1 = 5 - -MTDS = [ED1, SED1] - - -class Cert_9_2_10_PendingPartition(thread_cert.TestCase): - SUPPORT_NCP = False - - TOPOLOGY = { - COMMISSIONER: { - 'name': 'COMMISSIONER', - 'active_dataset': { - 'timestamp': 15, - 'channel': 19 - }, - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - LEADER: { - 'name': 'LEADER', - 'active_dataset': { - 'timestamp': 15, - 'channel': 19 - }, - 'mode': 'rdn', - 'partition_id': 0xffffffff, - 'allowlist': [COMMISSIONER, ROUTER1] - }, - ROUTER1: { - 'name': 'ROUTER', - 'active_dataset': { - 'timestamp': 15, - 'channel': 19 - }, - 'mode': 'rdn', - 'allowlist': [LEADER, ED1, SED1] - }, - ED1: { - 'name': 'MED', - 'channel': 19, - 'is_mtd': True, - 'mode': 'rn', - 'allowlist': [ROUTER1] - }, - SED1: { - 'name': 'SED', - 'channel': 19, - 'is_mtd': True, - 'mode': '-', - 'timeout': config.DEFAULT_CHILD_TIMEOUT, - 'allowlist': [ROUTER1] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[COMMISSIONER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'router') - self.nodes[COMMISSIONER].commissioner_start() - self.simulator.go(3) - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[ED1].start() - self.simulator.go(5) - self.assertEqual(self.nodes[ED1].get_state(), 'child') - - self.nodes[SED1].start() - self.simulator.go(5) - self.assertEqual(self.nodes[SED1].get_state(), 'child') - - self.nodes[COMMISSIONER].send_mgmt_pending_set( - pending_timestamp=30, - active_timestamp=165, - delay_timer=250, - channel=CHANNEL_FINAL, - panid=PANID_FINAL, - ) - self.simulator.go(260) - - self.nodes[LEADER].remove_allowlist(self.nodes[ROUTER1].get_addr64()) - self.nodes[ROUTER1].remove_allowlist(self.nodes[LEADER].get_addr64()) - self.simulator.go(300) - - self.assertEqual(self.nodes[ROUTER1].get_state(), 'leader') - self.assertEqual(self.nodes[ED1].get_state(), 'child') - self.assertEqual(self.nodes[SED1].get_state(), 'child') - - self.assertEqual(self.nodes[ROUTER1].get_panid(), PANID_FINAL) - self.assertEqual(self.nodes[ED1].get_panid(), PANID_FINAL) - self.assertEqual(self.nodes[SED1].get_panid(), PANID_FINAL) - - self.assertEqual(self.nodes[ROUTER1].get_channel(), CHANNEL_FINAL) - self.assertEqual(self.nodes[ED1].get_channel(), CHANNEL_FINAL) - self.assertEqual(self.nodes[SED1].get_channel(), CHANNEL_FINAL) - - self.nodes[LEADER].add_allowlist(self.nodes[ROUTER1].get_addr64()) - self.nodes[ROUTER1].add_allowlist(self.nodes[LEADER].get_addr64()) - self.simulator.go(60) - - self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'router') - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - self.assertEqual(self.nodes[ED1].get_state(), 'child') - self.assertEqual(self.nodes[SED1].get_state(), 'child') - - ipaddrs = self.nodes[ED1].get_addrs() - for ipaddr in ipaddrs: - if ipaddr[0:4] != 'fe80': - break - - self.assertTrue(self.nodes[LEADER].ping(ipaddr)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - ROUTER = pv.vars['ROUTER'] - MED = pv.vars['MED'] - SED = pv.vars['SED'] - COMMISSIONER = pv.vars['COMMISSIONER'] - _rpkts = pkts.filter_wpan_src64(ROUTER, cascade=False) - - # Step 1: Ensure the topology is formed correctly - _rpkts.filter_wpan_dst64(SED).filter_mle_cmd(MLE_CHILD_ID_RESPONSE).must_next() - - # Step 5: Router MUST send a unicast MLE Data Request to the Leader - _rpkts.filter_wpan_dst64(LEADER).filter_mle_cmd(MLE_DATA_REQUEST).must_next().must_verify( - lambda p: {TLV_REQUEST_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV} <= set(p.mle.tlv.type)) - _rpkts_med = _rpkts.copy() - - # Step 7: Router MUST multicast a MLE Data Response - _rpkts.filter_ipv6_dst(LINK_LOCAL_ALL_NODES_MULTICAST_ADDRESS).filter_mle_cmd( - MLE_DATA_RESPONSE).must_next().must_verify(lambda p: { - SOURCE_ADDRESS_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV, PENDING_TIMESTAMP_TLV - } <= set(p.mle.tlv.type) and {NM_COMMISSIONER_SESSION_ID_TLV, NM_BORDER_AGENT_LOCATOR_TLV} <= set( - p.thread_meshcop.tlv.type) and p.thread_nwd.tlv.stable == [0]) - - # Step 8: MED MUST send a unicast MLE Data Request to Router_1, - with pkts.save_index(): - pkts.filter_wpan_src64(MED).filter_wpan_dst64(ROUTER).filter_mle_cmd(MLE_DATA_REQUEST).must_next( - ).must_verify(lambda p: {TLV_REQUEST_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV} <= set(p.mle.tlv.type)) - - # Step 9: Router MUST send a unicast MLE Data Response to MED_1 - _rpkts_med.filter_wpan_dst64(MED).filter_mle_cmd(MLE_DATA_RESPONSE).must_next().must_verify(lambda p: { - SOURCE_ADDRESS_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV, PENDING_OPERATION_DATASET_TLV - } <= set(p.mle.tlv.type) and { - NM_CHANNEL_TLV, NM_NETWORK_MESH_LOCAL_PREFIX_TLV, NM_PAN_ID_TLV, NM_DELAY_TIMER_TLV, - NM_ACTIVE_TIMESTAMP_TLV - } <= set(p.thread_meshcop.tlv.type) and p.thread_nwd.tlv.stable == [0]) - - # Step 10: Router MUST send MLE Child Update Request to SED_1 - _rpkts.range(pkts.index).filter_wpan_dst64(SED).filter_mle_cmd( - MLE_CHILD_UPDATE_REQUEST).must_next().must_verify(lambda p: { - SOURCE_ADDRESS_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV, PENDING_TIMESTAMP_TLV - } <= set(p.mle.tlv.type)) - - # Step 11: SED MUST send a unicast MLE Data Request to Router_1 - pkts.filter_wpan_src64(SED).filter_wpan_dst64(ROUTER).filter_mle_cmd(MLE_DATA_REQUEST).must_next().must_verify( - lambda p: {TLV_REQUEST_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV} <= set(p.mle.tlv.type)) - - # Step 12: Router MUST send a unicast MLE Data Response to SED_1 - _pkt = _rpkts.filter_wpan_dst64(SED).filter_mle_cmd(MLE_DATA_RESPONSE).must_next() - _pkt.must_verify(lambda p: { - SOURCE_ADDRESS_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV, PENDING_OPERATION_DATASET_TLV - } <= set(p.mle.tlv.type) and { - NM_CHANNEL_TLV, NM_NETWORK_MESH_LOCAL_PREFIX_TLV, NM_PAN_ID_TLV, NM_DELAY_TIMER_TLV, - NM_ACTIVE_TIMESTAMP_TLV - } <= set(p.thread_meshcop.tlv.type)) - - # Step 14: After NETWORK_ID_TIMEOUT, Router MUST start a new partition - _rpkts.filter_ipv6_dst(LINK_LOCAL_ALL_ROUTERS_MULTICAST_ADDRESS).filter_mle_cmd( - MLE_PARENT_REQUEST).must_next().must_verify(lambda p: p.sniff_timestamp - _pkt.sniff_timestamp > 300) - _rpkts.filter_mle_cmd(MLE_DATA_RESPONSE).filter(lambda p: p.wpan.dst_pan == PANID_FINAL).must_next() - - # Step 16: After the Delay Timer expires, Router MUST move to the Secondary channel - _rpkts.filter_mle_cmd(MLE_ADVERTISEMENT).filter(lambda p: p.wpan.dst_pan == PANID_FINAL).must_next() - - # Step 19: Router MUST reattach to the Leader and the partitions MUST merge - pkts.filter_wpan_src64(LEADER).filter_wpan_dst64(ROUTER).filter_mle_cmd( - MLE_CHILD_ID_RESPONSE).must_next().must_verify(lambda p: p.mle.tlv.leader_data.partition_id == 0xffffffff) - - # Step 20: MED MUST respond with an ICMPv6 Echo Reply - p = pkts.filter_ping_request().filter_wpan_src64(LEADER).must_next() - pkts.filter_ping_reply(identifier=p.icmpv6.echo.identifier).filter_wpan_src64(MED).must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_9_2_11_NetworkKey.py b/tests/scripts/thread-cert/Cert_9_2_11_NetworkKey.py deleted file mode 100755 index f7095948f..000000000 --- a/tests/scripts/thread-cert/Cert_9_2_11_NetworkKey.py +++ /dev/null @@ -1,390 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import thread_cert -from pktverify.consts import MLE_PARENT_REQUEST, MLE_DATA_RESPONSE, MLE_DATA_REQUEST, MGMT_PENDING_SET_URI, SOURCE_ADDRESS_TLV, LEADER_DATA_TLV, ACTIVE_OPERATION_DATASET_TLV, ACTIVE_TIMESTAMP_TLV, PENDING_TIMESTAMP_TLV, TLV_REQUEST_TLV, NETWORK_DATA_TLV, NM_BORDER_AGENT_LOCATOR_TLV, NM_COMMISSIONER_SESSION_ID_TLV, NM_DELAY_TIMER_TLV, PENDING_OPERATION_DATASET_TLV, NWD_COMMISSIONING_DATA_TLV -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -KEY1 = '00112233445566778899aabbccddeeff' -KEY2 = 'ffeeddccbbaa99887766554433221100' - -CHANNEL_INIT = 19 -PANID_INIT = 0xface - -COMMISSIONER = 1 -LEADER = 2 -ROUTER1 = 3 -ED1 = 4 -SED1 = 5 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to confirm the DUT correctly applies -# DELAY_TIMER_DEFAULT when the network key is changed. -# The Commissioner first tries to set a network key update to happen too -# soon (delay of 60s vs DELAY_TIMER_DEFAULT of 300s); the DUT is expected -# to override the short value and communicate an appropriately longer delay -# to the Router. -# The Commissioner then sets a delay time longer than default; the DUT is -# validated to not artificially clamp the longer time back to the -# DELAY_TIMER_DEFAULT value. -# -# Test Topology: -# ------------- -# Commissioner -# | -# Leader -# | -# Router -# / \ -# ED SED -# -# DUT Types: -# ---------- -# Leader - - -class Cert_9_2_11_NetworkKey(thread_cert.TestCase): - USE_MESSAGE_FACTORY = False - SUPPORT_NCP = False - - TOPOLOGY = { - COMMISSIONER: { - 'name': 'COMMISSIONER', - 'active_dataset': { - 'timestamp': 10, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT, - 'network_key': KEY1 - }, - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - LEADER: { - 'name': 'LEADER', - 'active_dataset': { - 'timestamp': 10, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT, - 'network_key': KEY1 - }, - 'mode': 'rdn', - 'allowlist': [COMMISSIONER, ROUTER1] - }, - ROUTER1: { - 'name': 'ROUTER', - 'active_dataset': { - 'timestamp': 10, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT, - 'network_key': KEY1 - }, - 'mode': 'rdn', - 'allowlist': [LEADER, ED1, SED1] - }, - ED1: { - 'name': 'ED', - 'channel': CHANNEL_INIT, - 'is_mtd': True, - 'network_key': KEY1, - 'mode': 'rn', - 'panid': PANID_INIT, - 'allowlist': [ROUTER1] - }, - SED1: { - 'name': 'SED', - 'channel': CHANNEL_INIT, - 'is_mtd': True, - 'network_key': KEY1, - 'mode': '-', - 'panid': PANID_INIT, - 'timeout': config.DEFAULT_CHILD_TIMEOUT, - 'allowlist': [ROUTER1] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[COMMISSIONER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'router') - self.nodes[COMMISSIONER].commissioner_start() - self.simulator.go(3) - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[ED1].start() - self.simulator.go(5) - self.assertEqual(self.nodes[ED1].get_state(), 'child') - - self.nodes[SED1].start() - self.simulator.go(5) - self.assertEqual(self.nodes[SED1].get_state(), 'child') - - self.collect_rlocs() - self.collect_ipaddrs() - - self.nodes[COMMISSIONER].send_mgmt_pending_set( - pending_timestamp=10, - active_timestamp=70, - delay_timer=60000, - network_key=KEY2, - ) - self.simulator.go(310) - - self.assertEqual(self.nodes[COMMISSIONER].get_networkkey(), KEY2) - self.assertEqual(self.nodes[LEADER].get_networkkey(), KEY2) - self.assertEqual(self.nodes[ROUTER1].get_networkkey(), KEY2) - self.assertEqual(self.nodes[ED1].get_networkkey(), KEY2) - self.assertEqual(self.nodes[SED1].get_networkkey(), KEY2) - - ipaddr = self.nodes[LEADER].get_ip6_address(config.ADDRESS_TYPE.ML_EID) - self.assertTrue(self.nodes[ROUTER1].ping(ipaddr)) - - self.nodes[COMMISSIONER].send_mgmt_pending_set( - pending_timestamp=20, - active_timestamp=30, - delay_timer=500000, - network_key=KEY1, - ) - self.simulator.go(510) - - self.assertEqual(self.nodes[COMMISSIONER].get_networkkey(), KEY1) - self.assertEqual(self.nodes[LEADER].get_networkkey(), KEY1) - self.assertEqual(self.nodes[ROUTER1].get_networkkey(), KEY1) - self.assertEqual(self.nodes[ED1].get_networkkey(), KEY1) - self.assertEqual(self.nodes[SED1].get_networkkey(), KEY1) - - ipaddr = self.nodes[LEADER].get_ip6_address(config.ADDRESS_TYPE.ML_EID) - self.assertTrue(self.nodes[ROUTER1].ping(ipaddr)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_MLEID = pv.vars['LEADER_MLEID'] - COMMISSIONER = pv.vars['COMMISSIONER'] - COMMISSIONER_RLOC = pv.vars['COMMISSIONER_RLOC'] - ROUTER = pv.vars['ROUTER'] - ROUTER_MLEID = pv.vars['ROUTER_MLEID'] - ED = pv.vars['ED'] - SED = pv.vars['SED'] - - # Step 1: Ensure the topology is formed correctly - for node in ('COMMISSIONER', 'ROUTER'): - pv.verify_attached(node, 'LEADER') - for node in ('ED', 'SED'): - pv.verify_attached(node, 'ROUTER', 'MTD') - _pkt = pkts.last() - - # Step 3: Leader sends MGMT_PENDING_SET.rsq to the Commissioner: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # - State TLV (value = Accept) - # - # Leader MUST multicast MLE Data Response with the new network data, - # including the following TLVs: - # - Leader Data TLV: - # Data Version field incremented - # Stable Version field incremented - # - Network Data TLV: - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # - Active Timestamp TLV: 10s - # - Pending Timestamp TLV: 20s - pkts.filter_coap_ack(MGMT_PENDING_SET_URI).\ - filter_wpan_src64(LEADER).\ - filter_ipv6_dst(COMMISSIONER_RLOC).\ - must_next().\ - must_verify(lambda p: p.thread_meshcop.tlv.state == 1) - pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter(lambda p: p.mle.tlv.active_tstamp == 10 and\ - p.mle.tlv.pending_tstamp == 10 and\ - (p.mle.tlv.leader_data.data_version - - _pkt.mle.tlv.leader_data.data_version) % 256 <= 127 and\ - (p.mle.tlv.leader_data.stable_data_version - - _pkt.mle.tlv.leader_data.stable_data_version) % 256 <= 127 and\ - p.thread_nwd.tlv.stable == [0] and\ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ - NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ - NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type - ).\ - must_next() - - # Step 5: Leader sends a MLE Data Response to Router including the following TLVs: - # - Source Address TLV - # - Leader Data TLV - # - Network Data TLV - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # - Active Timestamp TLV - # - Pending Timestamp TLV - # - Pending Operational Dataset TLV - # - Delay Timer TLV - # - Network Key TLV: New Network Key - # - Active Timestamp TLV <70s> - _dr_pkt = pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter_wpan_src64(LEADER).\ - filter_wpan_dst64(ROUTER).\ - filter(lambda p: { - SOURCE_ADDRESS_TLV, - LEADER_DATA_TLV, - ACTIVE_TIMESTAMP_TLV, - PENDING_TIMESTAMP_TLV, - PENDING_OPERATION_DATASET_TLV - } <= set(p.mle.tlv.type) and\ - p.thread_nwd.tlv.stable == [0] and\ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ - NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ - NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type and\ - p.thread_meshcop.tlv.delay_timer > 200000 and\ - p.thread_meshcop.tlv.master_key == KEY2 and\ - p.thread_meshcop.tlv.active_tstamp == 70 - ).\ - must_next() - - # Step 8: Verify all devices now use New Network key. - # checked in test() - - # Step 9: Verify new MAC key is generated and used when sending ICMPv6 Echo Reply - # is received. - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(ROUTER).\ - filter_ipv6_dst(LEADER_MLEID).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(LEADER).\ - filter_ipv6_dst(ROUTER_MLEID).\ - must_next() - - # Step 11: Leader sends MGMT_PENDING_SET.rsq to the Commissioner: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # - State TLV (value = Accept) - # - # Leader MUST multicast MLE Data Response with the new network data, - # including the following TLVs: - # - Leader Data TLV: - # Data Version field incremented - # Stable Version field incremented - # - Network Data TLV: - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # - Active Timestamp TLV: 70s - # - Pending Timestamp TLV: 20s - pkts.filter_coap_ack(MGMT_PENDING_SET_URI).\ - filter_wpan_src64(LEADER).\ - filter_ipv6_dst(COMMISSIONER_RLOC).\ - must_next().\ - must_verify(lambda p: p.thread_meshcop.tlv.state == 1) - pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter_wpan_src64(LEADER).\ - filter_LLANMA().\ - filter(lambda p: p.mle.tlv.active_tstamp == 70 and\ - p.mle.tlv.pending_tstamp == 20 and\ - (p.mle.tlv.leader_data.data_version - - _dr_pkt.mle.tlv.leader_data.data_version) % 256 <= 127 and\ - (p.mle.tlv.leader_data.stable_data_version - - _dr_pkt.mle.tlv.leader_data.stable_data_version) % 256 <= 127 and\ - p.thread_nwd.tlv.stable == [0] and\ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ - NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ - NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type - ).\ - must_next() - - # Step 13: Leader sends a MLE Data Response to Router including the following TLVs: - # - Source Address TLV - # - Leader Data TLV - # - Network Data TLV - # - Commissioner Data TLV: - # Stable flag set to 0 - # Border Agent Locator TLV - # Commissioner Session ID TLV - # - Active Timestamp TLV <70s> - # - Pending Timestamp TLV <20s> - # - Pending Operational Dataset TLV - # - Active Timestamp TLV <30s> - # - Delay Timer TLV - # - Network Key TLV: New Network Key - pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ - filter_wpan_src64(LEADER).\ - filter_wpan_dst64(ROUTER).\ - filter(lambda p: { - SOURCE_ADDRESS_TLV, - LEADER_DATA_TLV, - ACTIVE_TIMESTAMP_TLV, - PENDING_TIMESTAMP_TLV, - PENDING_OPERATION_DATASET_TLV - } <= set(p.mle.tlv.type) and\ - p.thread_nwd.tlv.stable == [0] and\ - NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ - NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ - NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type and\ - p.mle.tlv.active_tstamp == 70 and\ - p.mle.tlv.pending_tstamp == 20 and\ - p.thread_meshcop.tlv.delay_timer > 300000 and\ - p.thread_meshcop.tlv.master_key == KEY1 and\ - p.thread_meshcop.tlv.active_tstamp == 30 - ).\ - must_next() - - # Step 17: The DUT MUST send an ICMPv6 Echo Reply using the new Network key - _pkt = pkts.filter_ping_request().\ - filter_wpan_src64(ROUTER).\ - filter_ipv6_dst(LEADER_MLEID).\ - must_next() - pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ - filter_wpan_src64(LEADER).\ - filter_ipv6_dst(ROUTER_MLEID).\ - must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_9_2_12_Announce.py b/tests/scripts/thread-cert/Cert_9_2_12_Announce.py deleted file mode 100755 index f6db932e3..000000000 --- a/tests/scripts/thread-cert/Cert_9_2_12_Announce.py +++ /dev/null @@ -1,174 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import thread_cert -from pktverify.consts import MLE_CHILD_ID_REQUEST, MLE_PARENT_REQUEST, MLE_CHILD_ID_RESPONSE, MLE_ANNOUNCE, CHANNEL_TLV, PAN_ID_TLV, ACTIVE_TIMESTAMP_TLV, LINK_LOCAL_ALL_NODES_MULTICAST_ADDRESS -from pktverify.packet_verifier import PacketVerifier - -LEADER1 = 1 -ROUTER1 = 2 -LEADER2 = 3 -MED = 4 - -DATASET1_TIMESTAMP = 20 -DATASET1_CHANNEL = 11 -DATASET1_PANID = 0xface - -DATASET2_TIMESTAMP = 10 -DATASET2_CHANNEL = 12 -DATASET2_PANID = 0xafce - - -class Cert_9_2_12_Announce(thread_cert.TestCase): - SUPPORT_NCP = False - - TOPOLOGY = { - LEADER1: { - 'name': 'LEADER_1', - 'active_dataset': { - 'timestamp': DATASET1_TIMESTAMP, - 'panid': DATASET1_PANID, - 'channel': DATASET1_CHANNEL - }, - 'mode': 'rdn', - 'allowlist': [ROUTER1] - }, - ROUTER1: { - 'name': 'ROUTER_1', - 'active_dataset': { - 'timestamp': DATASET1_TIMESTAMP, - 'panid': DATASET1_PANID, - 'channel': DATASET1_CHANNEL - }, - 'mode': 'rdn', - 'allowlist': [LEADER1, LEADER2] - }, - LEADER2: { - 'name': 'LEADER_2', - 'active_dataset': { - 'timestamp': DATASET2_TIMESTAMP, - 'panid': DATASET2_PANID, - 'channel': DATASET2_CHANNEL - }, - 'mode': 'rdn', - 'allowlist': [MED, ROUTER1] - }, - MED: { - 'name': 'MED', - 'channel': DATASET2_CHANNEL, - 'is_mtd': True, - 'mode': 'rn', - 'panid': DATASET2_PANID, - 'allowlist': [LEADER2] - }, - } - - def test(self): - self.nodes[LEADER1].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER1].get_state(), 'leader') - self.nodes[LEADER1].commissioner_start() - self.simulator.go(3) - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[LEADER2].start() - self.nodes[LEADER2].set_state('leader') - self.assertEqual(self.nodes[LEADER2].get_state(), 'leader') - - self.nodes[MED].start() - self.simulator.go(5) - self.assertEqual(self.nodes[MED].get_state(), 'child') - - ipaddrs = self.nodes[ROUTER1].get_addrs() - for ipaddr in ipaddrs: - if ipaddr[0:4] != 'fe80': - break - - self.nodes[LEADER1].announce_begin(0x1000, 1, 1000, ipaddr) - self.simulator.go(30) - self.assertEqual(self.nodes[LEADER2].get_state(), 'router') - self.assertEqual(self.nodes[MED].get_state(), 'child') - - self.collect_rlocs() - ipaddrs = self.nodes[MED].get_addrs() - for ipaddr in ipaddrs: - if ipaddr[0:4] != 'fe80': - self.assertTrue(self.nodes[LEADER1].ping(ipaddr)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER_1 = pv.vars['LEADER_1'] - ROUTER_1 = pv.vars['ROUTER_1'] - LEADER_2 = pv.vars['LEADER_2'] - LEADER_1_RLOC = pv.vars['LEADER_1_RLOC'] - MED = pv.vars['MED'] - MED_RLOC = pv.vars['MED_RLOC'] - - # Step 1: Ensure the topology is formed correctly - pkts.filter_wpan_src64(LEADER_1).filter_wpan_dst64(ROUTER_1).filter_mle_cmd( - MLE_CHILD_ID_RESPONSE).must_next().must_verify(lambda p: p.wpan.dst_pan == DATASET1_PANID) - pkts.copy().filter_wpan_src64(LEADER_2).filter_wpan_dst64(MED).filter_mle_cmd( - MLE_CHILD_ID_RESPONSE).must_next().must_verify(lambda p: p.wpan.dst_pan == DATASET2_PANID) - - # Step 4: Leader_2 MUST send a MLE Child ID Request on its new channel to Router_1 - # LEADER_2 MUST send a MLE Announce Message - # The Destination PAN ID (0xFFFF) in the IEEE 802.15.4 MAC and MUST be secured using Key ID Mode 2. - pkts.filter_wpan_src64(LEADER_2).filter_wpan_dst64(ROUTER_1).filter_mle_cmd( - MLE_CHILD_ID_REQUEST).must_next().must_verify(lambda p: p.wpan.dst_pan == DATASET1_PANID) - - pkts.filter_wpan_src64(LEADER_2).filter_ipv6_dst(LINK_LOCAL_ALL_NODES_MULTICAST_ADDRESS).filter_mle_cmd( - MLE_ANNOUNCE).must_next().must_verify( - lambda p: {CHANNEL_TLV, PAN_ID_TLV, ACTIVE_TIMESTAMP_TLV} <= set(p.mle.tlv.type) and p.wpan.dst_pan == - 0xffff and p.wpan.aux_sec.key_id_mode == 0x2 and p.wpan.aux_sec.key_source == 0x00000000ffffffff) - - # Step 5: MED MUST send a MLE Child ID Request on its new channel - # MED MUST send a MLE Announce Message - # The Destination PAN ID (0xFFFF) in the IEEE 802.15.4 MAC and MUST be secured using Key ID Mode 2. - pkts.filter_wpan_src64(MED).filter_wpan_dst64(LEADER_2).filter_mle_cmd( - MLE_CHILD_ID_REQUEST).must_next().must_verify(lambda p: p.wpan.dst_pan == DATASET1_PANID) - - pkts.filter_wpan_src64(MED).filter_ipv6_dst(LINK_LOCAL_ALL_NODES_MULTICAST_ADDRESS).filter_mle_cmd( - MLE_ANNOUNCE).must_next().must_verify( - lambda p: {CHANNEL_TLV, PAN_ID_TLV, ACTIVE_TIMESTAMP_TLV} <= set(p.mle.tlv.type) and p.wpan.dst_pan == - 0xffff and p.wpan.aux_sec.key_id_mode == 0x2 and p.wpan.aux_sec.key_source == 0x00000000ffffffff) - - # Step 6: MED MUST respond with an ICMPv6 Echo Reply - pkts.filter_ping_reply().filter_ipv6_src_dst(MED_RLOC, LEADER_1_RLOC).must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_9_2_13_EnergyScan.py b/tests/scripts/thread-cert/Cert_9_2_13_EnergyScan.py deleted file mode 100755 index 58e28e01a..000000000 --- a/tests/scripts/thread-cert/Cert_9_2_13_EnergyScan.py +++ /dev/null @@ -1,162 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import copy -import unittest - -import config -import thread_cert -from pktverify.consts import MLE_CHILD_ID_RESPONSE, MGMT_ED_SCAN, MGMT_ED_REPORT, NM_CHANNEL_MASK_TLV, NM_ENERGY_LIST_TLV -from pktverify.packet_verifier import PacketVerifier - -COMMISSIONER = 1 -LEADER = 2 -ROUTER1 = 3 -ED = 4 - - -class Cert_9_2_13_EnergyScan_Base(thread_cert.TestCase): - SUPPORT_NCP = False - - TOPOLOGY = { - COMMISSIONER: { - 'name': 'COMMISSIONER', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [COMMISSIONER, ROUTER1] - }, - ROUTER1: { - 'name': 'ROUTER', - 'mode': 'rdn', - 'allowlist': [LEADER, ED] - }, - ED: { - 'allowlist': [ROUTER1] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[COMMISSIONER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'router') - self.nodes[COMMISSIONER].commissioner_start() - self.simulator.go(5) - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[ED].start() - self.simulator.go(5) - self.assertEqual(self.nodes[ED].get_state(), 'child') - self.collect_rlocs() - - if self.TOPOLOGY[ED]['name'] == 'DUT': - ipaddrs = self.nodes[ED].get_addrs() - else: - ipaddrs = self.nodes[ROUTER1].get_addrs() - - for ipaddr in ipaddrs: - if ipaddr[0:4] != 'fe80': - break - - self.nodes[COMMISSIONER].energy_scan(0x50000, 0x02, 0x20, 0xc8, ipaddr) - self.simulator.go(3) - self.nodes[COMMISSIONER].energy_scan(0x50000, 0x02, 0x20, 0xc8, 'ff33:0040:fd00:db8:0:0:0:1') - self.simulator.go(3) - - self.assertTrue(self.nodes[COMMISSIONER].ping(ipaddr)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - DUT = pv.vars['DUT'] - DUT_RLOC = pv.vars['DUT_RLOC'] - COMMISSIONER_RLOC = pv.vars['COMMISSIONER_RLOC'] - _pkts = pkts.filter_wpan_src64(DUT) - - # Step 3: The DUT MUST send MGMT_ED_REPORT.ans to the Commissioner and report energy measurements - _pkts.filter_ipv6_dst(COMMISSIONER_RLOC).filter_coap_request(MGMT_ED_REPORT).must_next().must_verify( - lambda p: {NM_CHANNEL_MASK_TLV, NM_ENERGY_LIST_TLV} <= set(p.thread_meshcop.tlv.type) and p.thread_meshcop. - tlv.chan_mask_mask == '0000a000' and len(p.thread_meshcop.tlv.energy_list) == 2) - - # Step 5: The DUT MUST send MGMT_ED_REPORT.ans to the Commissioner and report energy measurements - _pkts.filter_ipv6_dst(COMMISSIONER_RLOC).filter_coap_request(MGMT_ED_REPORT).must_next().must_verify( - lambda p: {NM_CHANNEL_MASK_TLV, NM_ENERGY_LIST_TLV} <= set(p.thread_meshcop.tlv.type) and p.thread_meshcop. - tlv.chan_mask_mask == '0000a000' and len(p.thread_meshcop.tlv.energy_list) == 2) - - # Step 6: The DUT MUST respond with ICMPv6 Echo Reply - _pkts.filter_ping_reply().filter_ipv6_src_dst(DUT_RLOC, COMMISSIONER_RLOC).must_next() - - -class Cert_9_2_13_EnergyScan_FED(Cert_9_2_13_EnergyScan_Base): - TOPOLOGY = copy.deepcopy(Cert_9_2_13_EnergyScan_Base.TOPOLOGY) - TOPOLOGY[ROUTER1]['name'] = 'ROUTER' - TOPOLOGY[ED]['name'] = 'DUT' - TOPOLOGY[ED]['router_upgrade_threshold'] = 0 - - -class Cert_9_2_13_EnergyScan_MED(Cert_9_2_13_EnergyScan_Base): - TOPOLOGY = copy.deepcopy(Cert_9_2_13_EnergyScan_Base.TOPOLOGY) - TOPOLOGY[ROUTER1]['name'] = 'ROUTER' - TOPOLOGY[ED]['name'] = 'DUT' - TOPOLOGY[ED]['mode'] = 'rn' - TOPOLOGY[ED]['is_mtd'] = True - - -class Cert_9_2_13_EnergyScan_ROUTER(Cert_9_2_13_EnergyScan_Base): - TOPOLOGY = copy.deepcopy(Cert_9_2_13_EnergyScan_Base.TOPOLOGY) - TOPOLOGY[ROUTER1]['name'] = 'DUT' - TOPOLOGY[ED]['name'] = 'ED' - TOPOLOGY[ED]['mode'] = 'rn' - TOPOLOGY[ED]['is_mtd'] = True - - -class Cert_9_2_13_EnergyScan_SED(Cert_9_2_13_EnergyScan_Base): - TOPOLOGY = copy.deepcopy(Cert_9_2_13_EnergyScan_Base.TOPOLOGY) - TOPOLOGY[ROUTER1]['name'] = 'ROUTER' - TOPOLOGY[ED]['name'] = 'DUT' - TOPOLOGY[ED]['mode'] = '-' - TOPOLOGY[ED]['is_mtd'] = True - TOPOLOGY[ED]['timeout'] = config.DEFAULT_CHILD_TIMEOUT - - -del (Cert_9_2_13_EnergyScan_Base) - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_9_2_14_PanIdQuery.py b/tests/scripts/thread-cert/Cert_9_2_14_PanIdQuery.py deleted file mode 100755 index cf702ef91..000000000 --- a/tests/scripts/thread-cert/Cert_9_2_14_PanIdQuery.py +++ /dev/null @@ -1,141 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import thread_cert -from pktverify.consts import MLE_CHILD_ID_REQUEST, MGMT_PANID_QUERY, MGMT_PANID_CONFLICT, MGMT_ED_REPORT, NM_COMMISSIONER_SESSION_ID_TLV, NM_CHANNEL_MASK_TLV, NM_PAN_ID_TLV, REALM_LOCAL_ALL_THREAD_NODES_MULTICAST_ADDRESS -from pktverify.packet_verifier import PacketVerifier - -COMMISSIONER = 1 -LEADER1 = 2 -ROUTER1 = 3 -LEADER2 = 4 - - -class Cert_9_2_14_PanIdQuery(thread_cert.TestCase): - SUPPORT_NCP = False - - TOPOLOGY = { - COMMISSIONER: { - 'name': 'COMMISSIONER', - 'mode': 'rdn', - 'allowlist': [LEADER1] - }, - LEADER1: { - 'name': 'LEADER_1', - 'mode': 'rdn', - 'allowlist': [COMMISSIONER, ROUTER1] - }, - ROUTER1: { - 'name': 'ROUTER', - 'mode': 'rdn', - 'allowlist': [LEADER1, LEADER2] - }, - LEADER2: { - 'name': 'LEADER_2', - 'mode': 'rdn', - 'panid': 0xdead, - 'allowlist': [ROUTER1] - }, - } - - def test(self): - self.nodes[LEADER1].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER1].get_state(), 'leader') - - self.nodes[COMMISSIONER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'router') - self.nodes[COMMISSIONER].commissioner_start() - self.simulator.go(3) - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[LEADER2].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER2].get_state(), 'leader') - - self.collect_rlocs() - ipaddrs = self.nodes[ROUTER1].get_addrs() - for ipaddr in ipaddrs: - if ipaddr[0:4] != 'fe80': - break - - self.nodes[COMMISSIONER].panid_query(0xdead, 0xffffffff, ipaddr) - - self.nodes[COMMISSIONER].panid_query(0xdead, 0xffffffff, 'ff33:0040:fd00:db8:0:0:0:1') - - self.assertTrue(self.nodes[COMMISSIONER].ping(ipaddr)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - ROUTER = pv.vars['ROUTER'] - COMMISSIONER = pv.vars['COMMISSIONER'] - ROUTER_RLOC = pv.vars['ROUTER_RLOC'] - COMMISSIONER_RLOC = pv.vars['COMMISSIONER_RLOC'] - _rpkts = pkts.filter_wpan_src64(ROUTER) - _cpkts = pkts.filter_wpan_src64(COMMISSIONER) - - # Step 1: Ensure the topology is formed correctly - _rpkts.filter_mle_cmd(MLE_CHILD_ID_REQUEST).must_next() - - # Step 2: Commissioner MUST send a unicast MGMT_PANID_QUERY.qry unicast to Router_1 - _cpkts.filter_ipv6_dst(ROUTER_RLOC).filter_coap_request(MGMT_PANID_QUERY).must_next().must_verify( - lambda p: {NM_COMMISSIONER_SESSION_ID_TLV, NM_CHANNEL_MASK_TLV, NM_PAN_ID_TLV} <= set(p.thread_meshcop.tlv. - type)) - - # Step 3: Router MUST send MGMT_ED_REPORT.ans to the Commissioner - _rpkts.range( - _cpkts.index).filter_ipv6_dst(COMMISSIONER_RLOC).filter_coap_request(MGMT_PANID_CONFLICT).must_next( - ).must_verify(lambda p: {NM_CHANNEL_MASK_TLV, NM_PAN_ID_TLV} <= set(p.thread_meshcop.tlv.type)) - - # Step 4: Commissioner MUST send a multicast MGMT_PANID_QUERY.qry - _cpkts.filter_ipv6_dst(REALM_LOCAL_ALL_THREAD_NODES_MULTICAST_ADDRESS).filter_coap_request( - MGMT_PANID_QUERY).must_next().must_verify( - lambda p: {NM_COMMISSIONER_SESSION_ID_TLV, NM_CHANNEL_MASK_TLV, NM_PAN_ID_TLV} <= set(p.thread_meshcop. - tlv.type)) - - # Step 5: Router MUST send MGMT_PANID_CONFLICT.ans to the Commissioner - _rpkts.range( - _cpkts.index).filter_ipv6_dst(COMMISSIONER_RLOC).filter_coap_request(MGMT_PANID_CONFLICT).must_next( - ).must_verify(lambda p: {NM_CHANNEL_MASK_TLV, NM_PAN_ID_TLV} <= set(p.thread_meshcop.tlv.type)) - - # Step 6: Router MUST respond with an ICMPv6 Echo Reply - _rpkts.filter_ipv6_dst(COMMISSIONER_RLOC).filter_ping_reply().must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_9_2_15_PendingPartition.py b/tests/scripts/thread-cert/Cert_9_2_15_PendingPartition.py deleted file mode 100755 index 51326222d..000000000 --- a/tests/scripts/thread-cert/Cert_9_2_15_PendingPartition.py +++ /dev/null @@ -1,198 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import thread_cert -from pktverify.consts import MLE_ADVERTISEMENT, MLE_PARENT_REQUEST, MLE_CHILD_ID_RESPONSE, MLE_CHILD_ID_REQUEST, MGMT_ACTIVE_SET_URI, MGMT_ACTIVE_GET_URI, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, MODE_TLV, TIMEOUT_TLV, VERSION_TLV, TLV_REQUEST_TLV, CHALLENGE_TLV, SCAN_MASK_TLV, ADDRESS_REGISTRATION_TLV -from pktverify.packet_verifier import PacketVerifier - -CHANNEL_INIT = 19 -PANID_INIT = 0xface - -PANID_FINAL = 0xabcd - -COMMISSIONER = 1 -LEADER = 2 -ROUTER1 = 3 -ROUTER2 = 4 - - -class Cert_9_2_15_PendingPartition(thread_cert.TestCase): - SUPPORT_NCP = False - - TOPOLOGY = { - COMMISSIONER: { - 'name': 'COMMISSIONER', - 'active_dataset': { - 'timestamp': 15, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT - }, - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - LEADER: { - 'name': 'LEADER', - 'active_dataset': { - 'timestamp': 15, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT - }, - 'mode': 'rdn', - 'partition_id': 0xffffffff, - 'allowlist': [COMMISSIONER, ROUTER1] - }, - ROUTER1: { - 'name': 'ROUTER_1', - 'active_dataset': { - 'timestamp': 15, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT - }, - 'mode': 'rdn', - 'allowlist': [LEADER, ROUTER2] - }, - ROUTER2: { - 'name': 'ROUTER_2', - 'active_dataset': { - 'timestamp': 15, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT - }, - 'mode': 'rdn', - 'allowlist': [ROUTER1] - }, - } - - def _setUpRouter2(self): - self.nodes[ROUTER2].add_allowlist(self.nodes[ROUTER1].get_addr64()) - self.nodes[ROUTER2].enable_allowlist() - self.nodes[ROUTER2].set_router_selection_jitter(1) - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[COMMISSIONER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'router') - self.nodes[COMMISSIONER].commissioner_start() - self.simulator.go(3) - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[COMMISSIONER].send_mgmt_pending_set( - pending_timestamp=10, - active_timestamp=70, - delay_timer=600000, - mesh_local='fd00:0db9::', - ) - self.simulator.go(5) - - self.nodes[ROUTER2].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER2].get_state(), 'router') - - self.nodes[ROUTER2].reset() - self._setUpRouter2() - self.simulator.go(100) - - self.nodes[COMMISSIONER].send_mgmt_pending_set( - pending_timestamp=20, - active_timestamp=80, - delay_timer=200000, - mesh_local='fd00:0db7::', - panid=PANID_FINAL, - ) - self.simulator.go(100) - - self.nodes[ROUTER2].start() - self.simulator.go(config.ROUTER_RESET_DELAY) - self.assertEqual(self.nodes[ROUTER2].get_state(), 'router') - self.simulator.go(100) - - self.assertEqual(self.nodes[COMMISSIONER].get_panid(), PANID_FINAL) - self.assertEqual(self.nodes[LEADER].get_panid(), PANID_FINAL) - self.assertEqual(self.nodes[ROUTER1].get_panid(), PANID_FINAL) - self.assertEqual(self.nodes[ROUTER2].get_panid(), PANID_FINAL) - - ipaddrs = self.nodes[ROUTER2].get_addrs() - for ipaddr in ipaddrs: - if ipaddr[0:4] != 'fe80': - break - self.assertTrue(self.nodes[LEADER].ping(ipaddr)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - COMMISSIONER = pv.vars['COMMISSIONER'] - ROUTER_1 = pv.vars['ROUTER_1'] - ROUTER_2 = pv.vars['ROUTER_2'] - _router2_pkts = pkts.filter_wpan_src64(ROUTER_2) - - # Step 1: Ensure the topology is formed correctly - # Verify Commissioner, Leader and Router_1 are sending MLE advertisements - pkts.copy().filter_wpan_src64(LEADER).filter_mle_cmd(MLE_ADVERTISEMENT).must_next() - pkts.filter_wpan_dst64(COMMISSIONER).filter_mle_cmd(MLE_CHILD_ID_RESPONSE).must_next() - pkts.copy().filter_wpan_src64(COMMISSIONER).filter_mle_cmd(MLE_ADVERTISEMENT).must_next() - pkts.filter_wpan_dst64(ROUTER_1).filter_mle_cmd(MLE_CHILD_ID_RESPONSE).must_next() - pkts.copy().filter_wpan_src64(ROUTER_1).filter_mle_cmd(MLE_ADVERTISEMENT).must_next() - - # Step 5: Router_2 begins attach process by sending a multicast MLE Parent Request - # The first MLE Parent Request sent MUST NOT be sent to all routers and REEDS - _router2_pkts.range(pkts.index).filter_mle_cmd(MLE_PARENT_REQUEST).must_next().must_verify( - lambda p: {MODE_TLV, CHALLENGE_TLV, SCAN_MASK_TLV, VERSION_TLV} <= set( - p.mle.tlv.type) and p.mle.tlv.scan_mask.r == 1 and p.mle.tlv.scan_mask.e == 0) - - # Step 7: Router_2 MUST send a MLE Child ID Request to Router_1 - _router2_pkts.filter_mle_cmd(MLE_CHILD_ID_REQUEST).must_next().must_verify(lambda p: { - RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, MODE_TLV, TIMEOUT_TLV, VERSION_TLV, TLV_REQUEST_TLV - } <= set(p.mle.tlv.type) and ADDRESS_REGISTRATION_TLV not in p.mle.tlv.type) - - # Step 14: Router_2 begins attach process by sending a multicast MLE Parent Request - # The first MLE Parent Request sent MUST NOT be sent to all routers and REEDS - _router2_pkts.filter_mle_cmd(MLE_PARENT_REQUEST).must_next().must_verify( - lambda p: {MODE_TLV, CHALLENGE_TLV, SCAN_MASK_TLV, VERSION_TLV} <= set( - p.mle.tlv.type) and p.mle.tlv.scan_mask.r == 1 and p.mle.tlv.scan_mask.e == 0) - - # Step 16: Router_2 MUST send a MLE Child ID Request to Router_1 - _router2_pkts.filter_mle_cmd(MLE_CHILD_ID_REQUEST).must_next().must_verify(lambda p: { - RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, MODE_TLV, TIMEOUT_TLV, VERSION_TLV, TLV_REQUEST_TLV - } <= set(p.mle.tlv.type) and ADDRESS_REGISTRATION_TLV not in p.mle.tlv.type) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_9_2_16_ActivePendingPartition.py b/tests/scripts/thread-cert/Cert_9_2_16_ActivePendingPartition.py deleted file mode 100755 index 727eb8be3..000000000 --- a/tests/scripts/thread-cert/Cert_9_2_16_ActivePendingPartition.py +++ /dev/null @@ -1,208 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import thread_cert -from pktverify.consts import MLE_ADVERTISEMENT, MLE_PARENT_REQUEST, MLE_CHILD_ID_RESPONSE, MLE_CHILD_ID_REQUEST, MGMT_ACTIVE_SET_URI, MGMT_ACTIVE_GET_URI, RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, MODE_TLV, TIMEOUT_TLV, VERSION_TLV, TLV_REQUEST_TLV, CHALLENGE_TLV, SCAN_MASK_TLV, ADDRESS_REGISTRATION_TLV -from pktverify.packet_verifier import PacketVerifier - -CHANNEL_INIT = 19 -PANID_INIT = 0xface - -NETWORK_NAME_FINAL = 'threadCert' -PANID_FINAL = 0xabcd - -COMMISSIONER = 1 -LEADER = 2 -ROUTER1 = 3 -ROUTER2 = 4 - - -class Cert_9_2_16_ActivePendingPartition(thread_cert.TestCase): - SUPPORT_NCP = False - - TOPOLOGY = { - COMMISSIONER: { - 'name': 'COMMISSIONER', - 'active_dataset': { - 'timestamp': 1, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT - }, - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - LEADER: { - 'name': 'LEADER', - 'active_dataset': { - 'timestamp': 1, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT - }, - 'mode': 'rdn', - 'partition_id': 0xffffffff, - 'allowlist': [COMMISSIONER, ROUTER1] - }, - ROUTER1: { - 'name': 'ROUTER_1', - 'active_dataset': { - 'timestamp': 1, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT - }, - 'mode': 'rdn', - 'allowlist': [LEADER, ROUTER2] - }, - ROUTER2: { - 'name': 'ROUTER_2', - 'active_dataset': { - 'timestamp': 1, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT - }, - 'mode': 'rdn', - 'allowlist': [ROUTER1] - }, - } - - def _setUpRouter2(self): - self.nodes[ROUTER2].add_allowlist(self.nodes[ROUTER1].get_addr64()) - self.nodes[ROUTER2].enable_allowlist() - self.nodes[ROUTER2].set_router_selection_jitter(1) - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[COMMISSIONER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'router') - self.nodes[COMMISSIONER].commissioner_start() - self.simulator.go(3) - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[COMMISSIONER].send_mgmt_pending_set( - pending_timestamp=10, - active_timestamp=10, - delay_timer=600000, - mesh_local='fd00:0db9::', - ) - self.simulator.go(5) - - self.nodes[ROUTER2].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER2].get_state(), 'router') - - self.nodes[ROUTER2].reset() - self._setUpRouter2() - self.simulator.go(100) - - self.nodes[COMMISSIONER].send_mgmt_pending_set( - pending_timestamp=20, - active_timestamp=20, - delay_timer=200000, - mesh_local='fd00:0db7::', - panid=PANID_FINAL, - ) - self.simulator.go(5) - - self.nodes[COMMISSIONER].send_mgmt_active_set(active_timestamp=15, network_name='threadCert') - self.simulator.go(100) - - self.nodes[ROUTER2].start() - self.simulator.go(config.ROUTER_RESET_DELAY) - self.assertEqual(self.nodes[ROUTER2].get_state(), 'router') - - self.assertEqual(self.nodes[COMMISSIONER].get_network_name(), NETWORK_NAME_FINAL) - self.assertEqual(self.nodes[LEADER].get_network_name(), NETWORK_NAME_FINAL) - self.assertEqual(self.nodes[ROUTER1].get_network_name(), NETWORK_NAME_FINAL) - self.assertEqual(self.nodes[ROUTER2].get_network_name(), NETWORK_NAME_FINAL) - - self.simulator.go(100) - - self.assertEqual(self.nodes[COMMISSIONER].get_panid(), PANID_FINAL) - self.assertEqual(self.nodes[LEADER].get_panid(), PANID_FINAL) - self.assertEqual(self.nodes[ROUTER1].get_panid(), PANID_FINAL) - self.assertEqual(self.nodes[ROUTER2].get_panid(), PANID_FINAL) - - ipaddrs = self.nodes[ROUTER2].get_addrs() - for ipaddr in ipaddrs: - if ipaddr[0:4] != 'fe80': - break - self.assertTrue(self.nodes[LEADER].ping(ipaddr)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - COMMISSIONER = pv.vars['COMMISSIONER'] - ROUTER_1 = pv.vars['ROUTER_1'] - ROUTER_2 = pv.vars['ROUTER_2'] - _router2_pkts = pkts.filter_wpan_src64(ROUTER_2) - - # Step 1: Ensure the topology is formed correctly - # Verify Commissioner, Leader and Router_1 are sending MLE advertisements - pkts.copy().filter_wpan_src64(LEADER).filter_mle_cmd(MLE_ADVERTISEMENT).must_next() - pkts.filter_wpan_dst64(COMMISSIONER).filter_mle_cmd(MLE_CHILD_ID_RESPONSE).must_next() - pkts.copy().filter_wpan_src64(COMMISSIONER).filter_mle_cmd(MLE_ADVERTISEMENT).must_next() - pkts.filter_wpan_dst64(ROUTER_1).filter_mle_cmd(MLE_CHILD_ID_RESPONSE).must_next() - pkts.copy().filter_wpan_src64(ROUTER_1).filter_mle_cmd(MLE_ADVERTISEMENT).must_next() - - # Step 5: Router_2 begins attach process by sending a multicast MLE Parent Request - # The first MLE Parent Request sent MUST NOT be sent to all routers and REEDS - _router2_pkts.range(pkts.index).filter_mle_cmd(MLE_PARENT_REQUEST).must_next().must_verify( - lambda p: {MODE_TLV, CHALLENGE_TLV, SCAN_MASK_TLV, VERSION_TLV} <= set( - p.mle.tlv.type) and p.mle.tlv.scan_mask.r == 1 and p.mle.tlv.scan_mask.e == 0) - - # Step 7: Router_2 MUST send a MLE Child ID Request to Router_1 - _router2_pkts.filter_mle_cmd(MLE_CHILD_ID_REQUEST).must_next().must_verify(lambda p: { - RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, MODE_TLV, TIMEOUT_TLV, VERSION_TLV, TLV_REQUEST_TLV - } <= set(p.mle.tlv.type) and ADDRESS_REGISTRATION_TLV not in p.mle.tlv.type) - - # Step 14: Router_2 begins attach process by sending a multicast MLE Parent Request - # The first MLE Parent Request sent MUST NOT be sent to all routers and REEDS - _router2_pkts.filter_mle_cmd(MLE_PARENT_REQUEST).must_next().must_verify( - lambda p: {MODE_TLV, CHALLENGE_TLV, SCAN_MASK_TLV, VERSION_TLV} <= set( - p.mle.tlv.type) and p.mle.tlv.scan_mask.r == 1 and p.mle.tlv.scan_mask.e == 0) - - # Step 16: Router_2 MUST send a MLE Child ID Request to Router_1 - _router2_pkts.filter_mle_cmd(MLE_CHILD_ID_REQUEST).must_next().must_verify(lambda p: { - RESPONSE_TLV, LINK_LAYER_FRAME_COUNTER_TLV, MODE_TLV, TIMEOUT_TLV, VERSION_TLV, TLV_REQUEST_TLV - } <= set(p.mle.tlv.type) and ADDRESS_REGISTRATION_TLV not in p.mle.tlv.type) - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_9_2_17_Orphan.py b/tests/scripts/thread-cert/Cert_9_2_17_Orphan.py deleted file mode 100755 index 9a641fb1a..000000000 --- a/tests/scripts/thread-cert/Cert_9_2_17_Orphan.py +++ /dev/null @@ -1,147 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import thread_cert -from pktverify.consts import MLE_ADVERTISEMENT, MLE_PARENT_REQUEST, MLE_CHILD_ID_RESPONSE, MLE_ANNOUNCE, CHANNEL_TLV, PAN_ID_TLV, ACTIVE_TIMESTAMP_TLV -from pktverify.packet_verifier import PacketVerifier - -CHANNEL1 = 11 -CHANNEL2 = 18 -CHANNEL_MASK = 1 << 18 -PANID_INIT = 0xface - -LEADER1 = 1 -LEADER2 = 2 -ED1 = 3 - - -class Cert_9_2_17_Orphan(thread_cert.TestCase): - SUPPORT_NCP = False - - TOPOLOGY = { - LEADER1: { - 'name': 'LEADER_1', - 'active_dataset': { - 'timestamp': 10, - 'panid': PANID_INIT, - 'channel': CHANNEL1, - 'channel_mask': CHANNEL_MASK - }, - 'mode': 'rdn', - 'allowlist': [ED1] - }, - LEADER2: { - 'name': 'LEADER_2', - 'active_dataset': { - 'timestamp': 20, - 'panid': PANID_INIT, - 'channel': CHANNEL2, - 'channel_mask': CHANNEL_MASK - }, - 'mode': 'rdn', - }, - ED1: { - 'name': 'ED', - 'channel': CHANNEL1, - 'is_mtd': True, - 'mode': 'rn', - 'panid': PANID_INIT, - 'timeout': config.DEFAULT_CHILD_TIMEOUT, - 'allowlist': [LEADER1] - }, - } - - def test(self): - self.nodes[LEADER1].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER1].get_state(), 'leader') - - self.nodes[LEADER2].start() - self.nodes[LEADER2].set_state('leader') - self.assertEqual(self.nodes[LEADER2].get_state(), 'leader') - - self.nodes[ED1].start() - self.simulator.go(5) - self.assertEqual(self.nodes[ED1].get_state(), 'child') - - self.nodes[LEADER1].stop() - self.nodes[LEADER2].add_allowlist(self.nodes[ED1].get_addr64()) - self.nodes[ED1].add_allowlist(self.nodes[LEADER2].get_addr64()) - self.simulator.go(20) - - self.assertEqual(self.nodes[ED1].get_state(), 'child') - self.assertEqual(self.nodes[ED1].get_channel(), CHANNEL2) - - self.collect_ipaddrs() - ipaddrs = self.nodes[ED1].get_addrs() - for ipaddr in ipaddrs: - self.assertTrue(self.nodes[LEADER2].ping(ipaddr)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER_1 = pv.vars['LEADER_1'] - LEADER_2 = pv.vars['LEADER_2'] - ED = pv.vars['ED'] - - # Step 1: Ensure the topology is formed correctly - # Verify that Leader_1 & Leader_2 are sending MLE Advertisements on separate channels. - pkts.copy().filter_wpan_src64(LEADER_1).filter_mle_cmd(MLE_ADVERTISEMENT).must_next() - pkts.copy().filter_wpan_src64(LEADER_2).filter_mle_cmd(MLE_ADVERTISEMENT).must_next() - pkts.filter_wpan_src64(LEADER_1).filter_mle_cmd(MLE_CHILD_ID_RESPONSE).must_next().must_verify( - lambda p: p.wpan.dst64 == ED and p.thread_meshcop.tlv.channel == [CHANNEL1]) - - # Step 4: powers-down Leader_1 and enables connectivity between the ED and Leader_2 - # ED MUST send a MLE Parent Request - _epkts = pkts.filter_wpan_src64(ED) - _epkts.filter_mle_cmd(MLE_PARENT_REQUEST).must_next() - - # Step 6: ED MUST send a MLE Announce Message - # The Destination PAN ID (0xFFFF) in the IEEE 802.15.4 MAC and MUST be secured using Key ID Mode 2. - _epkts.filter_mle_cmd(MLE_ANNOUNCE).must_next().must_verify( - lambda p: {CHANNEL_TLV, PAN_ID_TLV, ACTIVE_TIMESTAMP_TLV} <= set( - p.mle.tlv.type) and p.wpan.dst_pan == 0xffff and p.wpan.aux_sec.key_id_mode == 0x2) - - # Step 8: ED MUST attempt to attach on the Secondary channel, - # with the new PAN ID it received in the MLE Announce message from Leader_2 - pkts.range(_epkts.index).filter_mle_cmd(MLE_ANNOUNCE).filter_wpan_src64(LEADER_2).filter_wpan_dst64( - ED).must_next().must_verify(lambda p: p.mle.tlv.channel == CHANNEL2) - _epkts.range(pkts.index).filter_mle_cmd(MLE_PARENT_REQUEST).must_next() - - # Step 9: ED MUST respond with an ICMPv6 Echo Reply - _epkts.filter('ipv6.dst == {LEADER_2_MLEID} and ipv6.src == {ED_MLEID}', - **pv.vars).filter_ping_reply().must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_9_2_18_RollBackActiveTimestamp.py b/tests/scripts/thread-cert/Cert_9_2_18_RollBackActiveTimestamp.py deleted file mode 100755 index 78ab43727..000000000 --- a/tests/scripts/thread-cert/Cert_9_2_18_RollBackActiveTimestamp.py +++ /dev/null @@ -1,258 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2016, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import thread_cert -from pktverify.consts import MLE_CHILD_ID_RESPONSE, MLE_CHILD_UPDATE_REQUEST, MLE_DATA_RESPONSE, MLE_DATA_REQUEST, MGMT_ACTIVE_SET_URI, MGMT_PENDING_SET_URI, LINK_LOCAL_ALL_NODES_MULTICAST_ADDRESS, TLV_REQUEST_TLV, SOURCE_ADDRESS_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV, PENDING_TIMESTAMP_TLV, PENDING_OPERATION_DATASET_TLV, NM_COMMISSIONER_SESSION_ID_TLV, NM_BORDER_AGENT_LOCATOR_TLV, NM_ACTIVE_TIMESTAMP_TLV, NM_NETWORK_NAME_TLV, NM_NETWORK_KEY_TLV, NM_CHANNEL_TLV, NM_CHANNEL_MASK_TLV, NM_EXTENDED_PAN_ID_TLV, NM_NETWORK_MESH_LOCAL_PREFIX_TLV, NM_PAN_ID_TLV, NM_PSKC_TLV, NM_SECURITY_POLICY_TLV, NM_DELAY_TIMER_TLV -from pktverify.packet_verifier import PacketVerifier -from pktverify.addrs import Ipv6Addr - -KEY1 = '00112233445566778899aabbccddeeff' -KEY2 = 'ffeeddccbbaa99887766554433221100' - -CHANNEL_INIT = 19 -PANID_INIT = 0xface - -COMMISSIONER = 1 -LEADER = 2 -ROUTER1 = 3 -ED1 = 4 -SED1 = 5 - -MTDS = [ED1, SED1] - - -class Cert_9_2_18_RollBackActiveTimestamp(thread_cert.TestCase): - SUPPORT_NCP = False - - TOPOLOGY = { - COMMISSIONER: { - 'name': 'COMMISSIONER', - 'active_dataset': { - 'timestamp': 1, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT, - 'network_key': KEY1 - }, - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - LEADER: { - 'name': 'LEADER', - 'active_dataset': { - 'timestamp': 1, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT, - 'network_key': KEY1 - }, - 'mode': 'rdn', - 'partition_id': 0xffffffff, - 'allowlist': [COMMISSIONER, ROUTER1] - }, - ROUTER1: { - 'name': 'ROUTER_1', - 'active_dataset': { - 'timestamp': 1, - 'panid': PANID_INIT, - 'channel': CHANNEL_INIT, - 'network_key': KEY1 - }, - 'mode': 'rdn', - 'allowlist': [LEADER, ED1, SED1] - }, - ED1: { - 'name': 'ED', - 'channel': CHANNEL_INIT, - 'is_mtd': True, - 'network_key': KEY1, - 'mode': 'rn', - 'panid': PANID_INIT, - 'allowlist': [ROUTER1] - }, - SED1: { - 'name': 'SED', - 'channel': CHANNEL_INIT, - 'is_mtd': True, - 'network_key': KEY1, - 'mode': '-', - 'panid': PANID_INIT, - 'timeout': config.DEFAULT_CHILD_TIMEOUT, - 'allowlist': [ROUTER1] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[COMMISSIONER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'router') - self.nodes[COMMISSIONER].commissioner_start() - self.simulator.go(3) - - self.nodes[ROUTER1].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') - - self.nodes[ED1].start() - self.simulator.go(5) - self.assertEqual(self.nodes[ED1].get_state(), 'child') - - self.nodes[SED1].start() - self.simulator.go(5) - self.assertEqual(self.nodes[SED1].get_state(), 'child') - - self.nodes[COMMISSIONER].send_mgmt_active_set(active_timestamp=20000, network_name='GRL') - self.simulator.go(5) - - self.nodes[COMMISSIONER].send_mgmt_pending_set( - pending_timestamp=20, - active_timestamp=20, - delay_timer=20, - network_name='Shouldnotbe', - ) - self.simulator.go(30) - - self.nodes[COMMISSIONER].send_mgmt_pending_set( - pending_timestamp=20, - active_timestamp=20, - delay_timer=300, - network_name='MyHouse', - network_key=KEY2, - ) - self.simulator.go(310) - - self.assertEqual(self.nodes[COMMISSIONER].get_networkkey(), KEY2) - self.assertEqual(self.nodes[LEADER].get_networkkey(), KEY2) - self.assertEqual(self.nodes[ROUTER1].get_networkkey(), KEY2) - self.assertEqual(self.nodes[ED1].get_networkkey(), KEY2) - self.assertEqual(self.nodes[SED1].get_networkkey(), KEY2) - - self.collect_rlocs() - ed_rloc = self.nodes[ED1].get_rloc() - sed_rloc = self.nodes[SED1].get_rloc() - self.assertTrue(self.nodes[COMMISSIONER].ping(ed_rloc)) - self.assertTrue(self.nodes[COMMISSIONER].ping(sed_rloc)) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - COMMISSIONER = pv.vars['COMMISSIONER'] - ROUTER_1 = pv.vars['ROUTER_1'] - SED = pv.vars['SED'] - COMMISSIONER_RLOC = pv.vars['COMMISSIONER_RLOC'] - ED_RLOC = pv.vars['ED_RLOC'] - SED_RLOC = pv.vars['SED_RLOC'] - - # Step 1: Ensure the topology is formed correctly - pkts.filter_wpan_src64(ROUTER_1).filter_wpan_dst64(SED).filter_mle_cmd(MLE_CHILD_ID_RESPONSE).must_next() - - # Step 3: Leader MUST send MGMT_ACTIVE_SET.rsp (Accept) to the Commissioner - pkts.filter_wpan_src64(LEADER).filter_ipv6_dst(COMMISSIONER_RLOC).filter_coap_ack( - MGMT_ACTIVE_SET_URI).must_next().must_verify(lambda p: p.thread_meshcop.tlv.state == 1) - - # Step 5: Leader MUST send MGMT_PENDING_SET.rsp (Reject) to the Commissioner - pkts.filter_wpan_src64(LEADER).filter_ipv6_dst(COMMISSIONER_RLOC).filter_coap_ack( - MGMT_PENDING_SET_URI).must_next().must_verify(lambda p: p.thread_meshcop.tlv.state == -1) - - # Step 7: Leader MUST send MGMT_PENDING_SET.rsp (Accept) to Commissioner - pkts.filter_wpan_src64(LEADER).filter_ipv6_dst(COMMISSIONER_RLOC).filter_coap_ack( - MGMT_PENDING_SET_URI).must_next().must_verify(lambda p: p.thread_meshcop.tlv.state == 1) - - # Step 8: Leader MUST multicast a MLE Data Response to the Link-Local All Nodes multicast address - _pkt = pkts.filter_wpan_src64(LEADER).filter_ipv6_dst(LINK_LOCAL_ALL_NODES_MULTICAST_ADDRESS).filter_mle_cmd( - MLE_DATA_RESPONSE).must_next() - _pkt.must_verify(lambda p: { - SOURCE_ADDRESS_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV, PENDING_TIMESTAMP_TLV - } <= set(p.mle.tlv.type) and {NM_COMMISSIONER_SESSION_ID_TLV, NM_BORDER_AGENT_LOCATOR_TLV} <= set( - p.thread_meshcop.tlv.type) and p.thread_nwd.tlv.stable == [0]) - - # Step 9: Router MUST send a unicast MLE Data Request to the Leader - pkts.filter_wpan_src64(ROUTER_1).filter_wpan_dst64(LEADER).filter_mle_cmd(MLE_DATA_REQUEST).must_next( - ).must_verify(lambda p: {TLV_REQUEST_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV} <= set(p.mle.tlv.type)) - - # Step 10: Leader MUST send a unicast MLE Data Response to Router_1 - pkts.filter_wpan_src64(LEADER).filter_wpan_dst64(ROUTER_1).filter_mle_cmd( - MLE_DATA_RESPONSE).must_next().must_verify( - lambda p: { - SOURCE_ADDRESS_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV, PENDING_TIMESTAMP_TLV, - PENDING_OPERATION_DATASET_TLV - } <= set(p.mle.tlv.type) and { - NM_COMMISSIONER_SESSION_ID_TLV, NM_BORDER_AGENT_LOCATOR_TLV, NM_ACTIVE_TIMESTAMP_TLV, - NM_NETWORK_NAME_TLV, NM_NETWORK_KEY_TLV - } <= set(p.thread_meshcop.tlv.type) and p.thread_nwd.tlv.stable == [0]) - - # Copy a pv.pkts here to filter SED related packets for potential sequence packets disorder - _pkts_sed = pkts.copy() - - # Step 11: Router MUST multicast a MLE Data Response with the new information - pkts.filter_wpan_src64(ROUTER_1).filter_ipv6_dst(LINK_LOCAL_ALL_NODES_MULTICAST_ADDRESS).filter_mle_cmd( - MLE_DATA_RESPONSE).must_next().must_verify( - lambda p: { - SOURCE_ADDRESS_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV, PENDING_TIMESTAMP_TLV - } <= set(p.mle.tlv.type) and p.mle.tlv.leader_data.data_version == _pkt.mle.tlv.leader_data. - data_version and p.mle.tlv.leader_data.stable_data_version == _pkt.mle.tlv.leader_data. - stable_data_version and {NM_COMMISSIONER_SESSION_ID_TLV, NM_BORDER_AGENT_LOCATOR_TLV} <= set( - p.thread_meshcop.tlv.type) and p.thread_nwd.tlv.stable == [0]) - - # Step 12: Router MUST send MLE Child Update Request to SED_1 - pkts.filter_wpan_src64(ROUTER_1).filter_wpan_dst64(SED).filter_mle_cmd( - MLE_CHILD_UPDATE_REQUEST).must_next().must_verify(lambda p: { - SOURCE_ADDRESS_TLV, LEADER_DATA_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV, PENDING_TIMESTAMP_TLV - } <= set(p.mle.tlv.type) and p.mle.tlv.leader_data.data_version == _pkt.mle.tlv.leader_data.data_version) - - # Step 13: SED MUST send a unicast MLE Data Request to Router_1 - _pkts_sed.filter_wpan_src64(SED).filter_wpan_dst64(ROUTER_1).filter_mle_cmd(MLE_DATA_REQUEST).must_next( - ).must_verify(lambda p: {TLV_REQUEST_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV} <= set(p.mle.tlv.type)) - - # Step 14: Router MUST send a unicast MLE Data Response to SED_1 - _pkts_sed.filter_wpan_src64(ROUTER_1).filter_wpan_dst64(SED).filter_mle_cmd( - MLE_DATA_RESPONSE).must_next().must_verify( - lambda p: { - SOURCE_ADDRESS_TLV, NETWORK_DATA_TLV, ACTIVE_TIMESTAMP_TLV, PENDING_TIMESTAMP_TLV, - PENDING_OPERATION_DATASET_TLV - } <= set(p.mle.tlv.type) and { - NM_CHANNEL_TLV, NM_NETWORK_MESH_LOCAL_PREFIX_TLV, NM_PAN_ID_TLV, NM_DELAY_TIMER_TLV, - NM_ACTIVE_TIMESTAMP_TLV, NM_NETWORK_NAME_TLV, NM_NETWORK_KEY_TLV - } <= set(p.thread_meshcop.tlv.type) and p.thread_meshcop.tlv.net_name == ["MyHouse"] and p. - thread_meshcop.tlv.master_key == KEY2) - - # Step 17: MED and SED MUST respond with an ICMPv6 Echo Reply - pkts.filter_ipv6_src_dst(ED_RLOC, COMMISSIONER_RLOC).filter_ping_reply().must_next() - pkts.filter_ipv6_src_dst(SED_RLOC, COMMISSIONER_RLOC).filter_ping_reply().must_next() - - -if __name__ == '__main__': - unittest.main() diff --git a/tests/scripts/thread-cert/Cert_9_2_19_PendingDatasetGet.py b/tests/scripts/thread-cert/Cert_9_2_19_PendingDatasetGet.py deleted file mode 100755 index 34079f178..000000000 --- a/tests/scripts/thread-cert/Cert_9_2_19_PendingDatasetGet.py +++ /dev/null @@ -1,293 +0,0 @@ -#!/usr/bin/env python3 -# -# Copyright (c) 2020, The OpenThread Authors. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without -# modification, are permitted provided that the following conditions are met: -# 1. Redistributions of source code must retain the above copyright -# notice, this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright -# notice, this list of conditions and the following disclaimer in the -# documentation and/or other materials provided with the distribution. -# 3. Neither the name of the copyright holder nor the -# names of its contributors may be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -# POSSIBILITY OF SUCH DAMAGE. -# - -import unittest - -import config -import mesh_cop -import thread_cert -from pktverify.consts import MGMT_PENDING_GET_URI, MGMT_PENDING_SET_URI, NM_CHANNEL_TLV, NM_PAN_ID_TLV, NM_NETWORK_NAME_TLV, NM_NETWORK_MESH_LOCAL_PREFIX_TLV, NM_PSKC_TLV, NM_ACTIVE_TIMESTAMP_TLV, NM_CHANNEL_MASK_TLV, NM_EXTENDED_PAN_ID_TLV, NM_NETWORK_KEY_TLV, NM_SECURITY_POLICY_TLV, NM_PENDING_TIMESTAMP_TLV, NM_DELAY_TIMER_TLV, LEADER_ALOC -from pktverify.packet_verifier import PacketVerifier -from pktverify.null_field import nullField - -COMMISSIONER = 1 -LEADER = 2 - -# Test Purpose and Description: -# ----------------------------- -# The purpose of this test case is to verify Leader's and active Commissioner's behavior via -# MGMT_PENDING_GET request and response -# -# Test Topology: -# ------------- -# Commissioner -# | -# Leader -# -# DUT Types: -# ---------- -# Leader -# Commissioner - - -class Cert_9_2_19_PendingDatasetGet(thread_cert.TestCase): - SUPPORT_NCP = False - - TOPOLOGY = { - COMMISSIONER: { - 'name': 'COMMISSIONER', - 'mode': 'rdn', - 'allowlist': [LEADER] - }, - LEADER: { - 'name': 'LEADER', - 'mode': 'rdn', - 'allowlist': [COMMISSIONER] - }, - } - - def test(self): - self.nodes[LEADER].start() - self.simulator.go(config.LEADER_STARTUP_DELAY) - self.assertEqual(self.nodes[LEADER].get_state(), 'leader') - - self.nodes[COMMISSIONER].start() - self.simulator.go(config.ROUTER_STARTUP_DELAY) - self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'router') - self.simulator.get_messages_sent_by(LEADER) - - self.collect_rlocs() - self.collect_rloc16s() - - leader_rloc = self.nodes[LEADER].get_rloc() - - self.nodes[COMMISSIONER].commissioner_start() - self.simulator.go(3) - - self.nodes[COMMISSIONER].send_mgmt_pending_get() - self.simulator.go(2) - - self.nodes[COMMISSIONER].send_mgmt_pending_set( - active_timestamp=60, - delay_timer=60000, - panid=0xAFCE, - pending_timestamp=30, - ) - self.simulator.go(2) - - self.nodes[COMMISSIONER].send_mgmt_pending_get() - self.simulator.go(2) - - self.nodes[COMMISSIONER].send_mgmt_pending_get(leader_rloc, [mesh_cop.TlvType.PAN_ID]) - self.simulator.go(92) - - self.nodes[COMMISSIONER].send_mgmt_pending_get() - self.simulator.go(2) - - def verify(self, pv): - pkts = pv.pkts - pv.summary.show() - - LEADER = pv.vars['LEADER'] - LEADER_RLOC = pv.vars['LEADER_RLOC'] - COMMISSIONER = pv.vars['COMMISSIONER'] - COMMISSIONER_RLOC = pv.vars['COMMISSIONER_RLOC'] - - # Step 1: Ensure topology is formed correctly - pv.verify_attached('COMMISSIONER', 'LEADER') - - # Step 2: Commissioner sends a MGMT_PENDING_GET.req to Leader Anycast - # or Routing Locator: - # CoAP Request URI - # CON POST coap://:MM/c/pg - # CoAP Payload - # - get all Active Operational Dataset parameters - _mgmt_get_pkt = pkts.filter_wpan_src64(COMMISSIONER).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_PENDING_GET_URI).\ - filter(lambda p: p.coap.tlv.type is nullField).\ - must_next() - - # Step 3: Leader sends a MGMT_PENDING_GET.rsp to Commissioner with - # the following format: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # - (no Pending Operational Dataset) - pkts.filter_ipv6_src_dst(_mgmt_get_pkt.ipv6.dst, COMMISSIONER_RLOC).\ - filter_coap_ack(MGMT_PENDING_GET_URI).\ - filter(lambda p: p.coap.tlv.type is nullField).\ - must_next() - - # Step 4: Commissioner sends a MGMT_PENDING_SET.req to Leader Anycast - # or Routing Locator: - # CoAP Request URI - # CON POST coap://:MM/c/ps - # CoAP Payload - # Active Timestamp TLV: 60s - # Commissioner Session ID TLV (valid) - # Delay Timer TLV: 1 minute - # Pending Timestamp TLV: 30s - # PAN ID TLV: 0xAFCE (new value) - _mgmt_pending_set_pkt = pkts.filter_wpan_src64(COMMISSIONER).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_PENDING_SET_URI).\ - filter(lambda p: { - NM_ACTIVE_TIMESTAMP_TLV, - NM_PENDING_TIMESTAMP_TLV, - NM_DELAY_TIMER_TLV, - NM_PAN_ID_TLV - } <= set(p.thread_meshcop.tlv.type) and\ - p.thread_meshcop.tlv.active_tstamp == 60 and\ - p.thread_meshcop.tlv.pan_id == [0xafce] and\ - p.thread_meshcop.tlv.delay_timer == 60000 - ).\ - must_next() - - # Step 5: Leader sends a MGMT_PENDING_SET.rsp to Commissioner with - # the following format: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # State TLV (value = Accept (01)) - pkts.filter_ipv6_src_dst(_mgmt_pending_set_pkt.ipv6.dst, COMMISSIONER_RLOC).\ - filter_coap_ack(MGMT_PENDING_SET_URI).\ - filter(lambda p: - p.thread_meshcop.tlv.state == 1 - ).\ - must_next() - - # Step 6: Commissioner sends a MGMT_PENDING_GET.req to Leader Anycast - # or Routing Locator: - # CoAP Request URI - # CON POST coap://:MM/c/pg - # CoAP Payload - # - get all Active Operational Dataset parameters - _mgmt_pending_get_pkt = pkts.filter_wpan_src64(COMMISSIONER).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_PENDING_GET_URI).\ - filter(lambda p: p.coap.tlv.type is nullField).\ - must_next() - - # Step 7: Leader sends a MGMT_PENDING_GET.rsp to Commissioner with - # the following format: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # (entire Active Operational Dataset) - # Active Timestamp TLV - # Channel TLV - # Channel Mask TLV - # Delay Timer TLV - # Extended PAN ID TLV - # Network Mesh-Local Prefix TLV - # Network Key TLV - # Network Name TLV - # PAN ID TLV - # Pending Timestamp TLV - # PSKc TLV - # Security Policy TLV - pkts.filter_ipv6_src_dst(_mgmt_pending_get_pkt.ipv6.dst, COMMISSIONER_RLOC).\ - filter_coap_ack(MGMT_PENDING_GET_URI).\ - filter(lambda p: { - NM_ACTIVE_TIMESTAMP_TLV, - NM_CHANNEL_TLV, - NM_CHANNEL_MASK_TLV, - NM_DELAY_TIMER_TLV, - NM_EXTENDED_PAN_ID_TLV, - NM_NETWORK_MESH_LOCAL_PREFIX_TLV, - NM_NETWORK_KEY_TLV, - NM_NETWORK_NAME_TLV, - NM_PAN_ID_TLV, - NM_PENDING_TIMESTAMP_TLV, - NM_PSKC_TLV, - NM_SECURITY_POLICY_TLV - } <= set(p.thread_meshcop.tlv.type) - ).\ - must_next() - - # Step 8: Commissioner sends a MGMT_PENDING_GET.req to Leader Anycast - # or Routing Locator: - # CoAP Request URI - # CON POST coap://:MM/c/pg - # CoAP Payload - # PAN ID TLV - _mgmt_pending_get_pkt = pkts.filter_wpan_src64(COMMISSIONER).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_PENDING_GET_URI).\ - filter(lambda p: { - NM_PAN_ID_TLV - } <= set(p.thread_meshcop.tlv.type) - ).\ - must_next() - - # Step 9: Leader sends a MGMT_PENDING_GET.rsp to Commissioner with - # the following format: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # PAN ID TLV - # Delay Timer TLV - pkts.filter_ipv6_src_dst(_mgmt_pending_get_pkt.ipv6.dst, COMMISSIONER_RLOC).\ - filter_coap_ack(MGMT_PENDING_GET_URI).\ - filter(lambda p: { - NM_DELAY_TIMER_TLV, - NM_PAN_ID_TLV - } <= set(p.coap.tlv.type) and\ - p.thread_meshcop.tlv.pan_id == [0xafce] and\ - p.thread_meshcop.tlv.delay_timer < 60000 - ).\ - must_next() - - # Step 11: Commissioner sends a MGMT_PENDING_GET.req to Leader Anycast - # or Routing Locator: - # CoAP Request URI - # CON POST coap://:MM/c/pg - # CoAP Payload - # - get all Active Operational Dataset parameters - _mgmt_pending_get_pkt = pkts.filter_wpan_src64(COMMISSIONER).\ - filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ - filter_coap_request(MGMT_PENDING_GET_URI).\ - filter(lambda p: p.coap.tlv.type is nullField).\ - must_next() - - # Step 12: Leader sends a MGMT_PENDING_GET.rsp to Commissioner with - # the following format: - # CoAP Response Code - # 2.04 Changed - # CoAP Payload - # - (no Pending Operational Dataset) - pkts.filter_ipv6_src_dst(_mgmt_pending_get_pkt.ipv6.dst, COMMISSIONER_RLOC).\ - filter_coap_ack(MGMT_PENDING_GET_URI).\ - filter(lambda p: p.thread_meshcop.tlv.type is nullField).\ - must_next() - - -if __name__ == '__main__': - unittest.main()