#!/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()