1#!/usr/bin/env python3 2# 3# Copyright (c) 2016, The OpenThread Authors. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 3. Neither the name of the copyright holder nor the 14# names of its contributors may be used to endorse or promote products 15# derived from this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27# POSSIBILITY OF SUCH DAMAGE. 28# 29 30import unittest 31 32import config 33import thread_cert 34from 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 35from pktverify.packet_verifier import PacketVerifier 36from pktverify.null_field import nullField 37 38CHANNEL_INIT = 19 39PANID_INIT = 0xface 40TIMESTAMP_INIT = 10 41CHANNEL_SECOND = 20 42 43CHANNEL_FINAL = 19 44PANID_FINAL = 0xabcd 45 46ROUTER2_ACTIVE_TIMESTAMP = 15 47ROUTER2_PENDING_ACTIVE_TIMESTAMP = 410 48ROUTER2_PENDING_TIMESTAMP = 50 49ROUTER2_DELAY_TIMER = 200000 50ROUTER2_NET_NAME = 'TEST' 51 52COMM_PENDING_ACTIVE_TIMESTAMP = 210 53COMM_PENDING_TIMESTAMP = 30 54COMM_DELAY_TIMER = 1000000 55 56COMMISSIONER = 1 57LEADER = 2 58ROUTER1 = 3 59ROUTER2 = 4 60 61# Test Purpose and Description: 62# ----------------------------- 63# The purpose of this test case is to verify how Pending Operational Datasets 64# are synchronized when two partitions merge. 65# 66# Test Topology: 67# ------------- 68# Commissioner 69# | 70# Leader 71# | 72# Router_1 73# | 74# Router_2 75# 76# Note: Router_1 and Router_2 will be in&out RF shield box 77# 78# DUT Types: 79# ---------- 80# Leader 81# Router 82 83 84class Cert_9_2_09_PendingPartition(thread_cert.TestCase): 85 SUPPORT_NCP = False 86 87 TOPOLOGY = { 88 COMMISSIONER: { 89 'name': 'COMMISSIONER', 90 'active_dataset': { 91 'timestamp': TIMESTAMP_INIT, 92 'panid': PANID_INIT, 93 'channel': CHANNEL_INIT 94 }, 95 'mode': 'rdn', 96 'allowlist': [LEADER] 97 }, 98 LEADER: { 99 'name': 'LEADER', 100 'active_dataset': { 101 'timestamp': TIMESTAMP_INIT, 102 'panid': PANID_INIT, 103 'channel': CHANNEL_INIT 104 }, 105 'mode': 'rdn', 106 'partition_id': 0xffffffff, 107 'allowlist': [COMMISSIONER, ROUTER1] 108 }, 109 ROUTER1: { 110 'name': 'ROUTER_1', 111 'active_dataset': { 112 'timestamp': TIMESTAMP_INIT, 113 'panid': PANID_INIT, 114 'channel': CHANNEL_INIT 115 }, 116 'mode': 'rdn', 117 'allowlist': [LEADER, ROUTER2] 118 }, 119 ROUTER2: { 120 'name': 'ROUTER_2', 121 'active_dataset': { 122 'timestamp': TIMESTAMP_INIT, 123 'panid': PANID_INIT, 124 'channel': CHANNEL_INIT 125 }, 126 'mode': 'rdn', 127 'network_id_timeout': 70, 128 'allowlist': [ROUTER1] 129 }, 130 } 131 132 def test(self): 133 self.nodes[LEADER].start() 134 self.simulator.go(config.LEADER_STARTUP_DELAY) 135 self.assertEqual(self.nodes[LEADER].get_state(), 'leader') 136 137 self.nodes[COMMISSIONER].start() 138 self.simulator.go(config.ROUTER_STARTUP_DELAY) 139 self.assertEqual(self.nodes[COMMISSIONER].get_state(), 'router') 140 self.nodes[COMMISSIONER].commissioner_start() 141 self.simulator.go(3) 142 143 self.nodes[ROUTER1].start() 144 self.simulator.go(config.ROUTER_STARTUP_DELAY) 145 self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') 146 147 self.nodes[ROUTER2].start() 148 self.simulator.go(config.ROUTER_STARTUP_DELAY) 149 self.assertEqual(self.nodes[ROUTER2].get_state(), 'router') 150 151 self.nodes[COMMISSIONER].send_mgmt_pending_set( 152 pending_timestamp=COMM_PENDING_TIMESTAMP, 153 active_timestamp=COMM_PENDING_ACTIVE_TIMESTAMP, 154 delay_timer=COMM_DELAY_TIMER, 155 channel=CHANNEL_SECOND, 156 panid=PANID_INIT, 157 ) 158 self.simulator.go(5) 159 160 self.nodes[LEADER].remove_allowlist(self.nodes[ROUTER1].get_addr64()) 161 self.nodes[ROUTER1].remove_allowlist(self.nodes[LEADER].get_addr64()) 162 self.nodes[ROUTER2].set_preferred_partition_id(1) 163 self.simulator.go(250) 164 165 self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') 166 self.assertEqual(self.nodes[ROUTER2].get_state(), 'leader') 167 168 # Keeping network id timeout at 70 can result in ROUTER2 169 # occasionally creating its own partition. Reset back to 120 170 # here to avoid occasional test failures. 171 self.nodes[ROUTER2].set_network_id_timeout(120) 172 173 self.nodes[ROUTER2].commissioner_start() 174 self.simulator.go(3) 175 self.nodes[ROUTER2].send_mgmt_active_set( 176 active_timestamp=ROUTER2_ACTIVE_TIMESTAMP, 177 network_name=ROUTER2_NET_NAME, 178 ) 179 self.simulator.go(5) 180 181 self.nodes[ROUTER2].send_mgmt_pending_set( 182 pending_timestamp=ROUTER2_PENDING_TIMESTAMP, 183 active_timestamp=ROUTER2_PENDING_ACTIVE_TIMESTAMP, 184 delay_timer=ROUTER2_DELAY_TIMER, 185 channel=CHANNEL_FINAL, 186 panid=PANID_FINAL, 187 ) 188 self.simulator.go(5) 189 190 self.nodes[LEADER].add_allowlist(self.nodes[ROUTER1].get_addr64()) 191 self.nodes[ROUTER1].add_allowlist(self.nodes[LEADER].get_addr64()) 192 self.simulator.go(260) 193 194 self.assertEqual(self.nodes[ROUTER1].get_state(), 'router') 195 self.assertEqual(self.nodes[ROUTER2].get_state(), 'router') 196 197 self.collect_rlocs() 198 self.collect_rloc16s() 199 self.collect_ipaddrs() 200 self.assertEqual(self.nodes[COMMISSIONER].get_panid(), PANID_FINAL) 201 self.assertEqual(self.nodes[LEADER].get_panid(), PANID_FINAL) 202 self.assertEqual(self.nodes[ROUTER1].get_panid(), PANID_FINAL) 203 self.assertEqual(self.nodes[ROUTER2].get_panid(), PANID_FINAL) 204 205 self.assertEqual(self.nodes[COMMISSIONER].get_channel(), CHANNEL_FINAL) 206 self.assertEqual(self.nodes[LEADER].get_channel(), CHANNEL_FINAL) 207 self.assertEqual(self.nodes[ROUTER1].get_channel(), CHANNEL_FINAL) 208 self.assertEqual(self.nodes[ROUTER2].get_channel(), CHANNEL_FINAL) 209 210 leader_addr = self.nodes[LEADER].get_ip6_address(config.ADDRESS_TYPE.ML_EID) 211 router1_addr = self.nodes[ROUTER1].get_ip6_address(config.ADDRESS_TYPE.ML_EID) 212 self.assertTrue(self.nodes[ROUTER2].ping(leader_addr, timeout=10)) 213 self.assertTrue(self.nodes[COMMISSIONER].ping(router1_addr, timeout=10)) 214 215 def verify(self, pv): 216 pkts = pv.pkts 217 pv.summary.show() 218 219 LEADER = pv.vars['LEADER'] 220 LEADER_RLOC = pv.vars['LEADER_RLOC'] 221 LEADER_MLEID = pv.vars['LEADER_MLEID'] 222 COMMISSIONER = pv.vars['COMMISSIONER'] 223 COMMISSIONER_MLEID = pv.vars['COMMISSIONER_MLEID'] 224 COMMISSIONER_RLOC = pv.vars['COMMISSIONER_RLOC'] 225 COMMISSIONER_RLOC16 = pv.vars['COMMISSIONER_RLOC16'] 226 ROUTER_1 = pv.vars['ROUTER_1'] 227 ROUTER_1_RLOC = pv.vars['ROUTER_1_RLOC'] 228 ROUTER_1_MLEID = pv.vars['ROUTER_1_MLEID'] 229 ROUTER_2 = pv.vars['ROUTER_2'] 230 ROUTER_2_RLOC = pv.vars['ROUTER_2_RLOC'] 231 ROUTER_2_MLEID = pv.vars['ROUTER_2_MLEID'] 232 233 # Step 1: Ensure the topology is formed correctly 234 for node in ('COMMISSIONER', 'ROUTER_1'): 235 pv.verify_attached(node, 'LEADER') 236 pv.verify_attached('ROUTER_2', 'ROUTER_1') 237 _pkt = pkts.last() 238 239 # Step 3: Leader sends MGMT_PENDING_SET.rsq to the Commissioner: 240 # CoAP Response Code 241 # 2.04 Changed 242 # CoAP Payload 243 # - State TLV (value = Accept) 244 pkts.filter_coap_ack(MGMT_PENDING_SET_URI).\ 245 filter_wpan_src64(LEADER).\ 246 filter_ipv6_dst(COMMISSIONER_RLOC).\ 247 must_next().\ 248 must_verify(lambda p: p.thread_meshcop.tlv.state == 1) 249 250 # Step 4: Leader MUST multicast MLE Data Response with the new network data, 251 # including the following TLVs: 252 # - Source Address TLV 253 # - Leader Data TLV: 254 # Data Version field incremented 255 # Stable Version field incremented 256 # - Network Data TLV: 257 # - Commissioner Data TLV: 258 # Stable flag set to 0 259 # Border Agent Locator TLV 260 # Commissioner Session ID TLV 261 # - Active Timestamp TLV: 10s 262 # - Pending Timestamp TLV: 30s 263 # 264 # Router_1 MUST send a unicast MLE Data Request to the Leader, including the 265 # following TLVs: 266 # - TLV Request TLV: 267 # - Network Data TLV 268 # - Active Timestamp TLV (10s) 269 pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ 270 filter_wpan_src64(LEADER).\ 271 filter_LLANMA().\ 272 filter(lambda p: p.mle.tlv.active_tstamp == TIMESTAMP_INIT and\ 273 p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and\ 274 (p.mle.tlv.leader_data.data_version - 275 _pkt.mle.tlv.leader_data.data_version) % 256 <= 127 and\ 276 (p.mle.tlv.leader_data.stable_data_version - 277 _pkt.mle.tlv.leader_data.stable_data_version) % 256 <= 127 and\ 278 p.thread_nwd.tlv.stable == [0] and\ 279 NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ 280 NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ 281 NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type 282 ).\ 283 must_next() 284 285 pkts.filter_wpan_src64(ROUTER_1).\ 286 filter_wpan_dst64(LEADER).\ 287 filter_mle_cmd(MLE_DATA_REQUEST).\ 288 filter(lambda p: { 289 TLV_REQUEST_TLV, 290 NETWORK_DATA_TLV, 291 ACTIVE_TIMESTAMP_TLV 292 } <= set(p.mle.tlv.type) and\ 293 p.mle.tlv.active_tstamp == TIMESTAMP_INIT and\ 294 p.thread_meshcop.tlv.type is nullField 295 ).\ 296 must_next() 297 298 # Step 5: Leader sends a MLE Data Response to Router_1 including the following TLVs: 299 # - Source Address TLV 300 # - Leader Data TLV 301 # - Network Data TLV 302 # - Commissioner Data TLV: 303 # Stable flag set to 0 304 # Border Agent Locator TLV 305 # Commissioner Session ID TLV 306 # - Active Timestamp TLV: 10s 307 # - Pending Timestamp TLV: 30s 308 # - Pending Operational Dataset TLV 309 # - Active Timestamp TLV <210s> 310 # - Delay Timer TLV <~ 1000s> 311 # - Channel TLV : ‘Secondary’ 312 # - PAN ID TLV : 0xAFCE 313 _dr_pkt = pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ 314 filter_wpan_src64(LEADER).\ 315 filter_wpan_dst64(ROUTER_1).\ 316 filter(lambda p: { 317 SOURCE_ADDRESS_TLV, 318 LEADER_DATA_TLV, 319 ACTIVE_TIMESTAMP_TLV, 320 PENDING_TIMESTAMP_TLV, 321 PENDING_OPERATION_DATASET_TLV 322 } <= set(p.mle.tlv.type) and\ 323 p.thread_nwd.tlv.stable == [0] and\ 324 NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ 325 NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ 326 NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type and\ 327 p.mle.tlv.active_tstamp == TIMESTAMP_INIT and\ 328 p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and\ 329 p.thread_meshcop.tlv.delay_timer < COMM_DELAY_TIMER and\ 330 p.thread_meshcop.tlv.active_tstamp == COMM_PENDING_ACTIVE_TIMESTAMP and\ 331 p.thread_meshcop.tlv.channel == [CHANNEL_SECOND] and\ 332 p.thread_meshcop.tlv.pan_id == [PANID_INIT] 333 ).\ 334 must_next() 335 336 # Step 6: Router_1 MUST multicast MLE Data Response with the new network data, 337 # including the following TLVs: 338 # - Source Address TLV 339 # - Leader Data TLV: 340 # Data Version field incremented 341 # Stable Version field incremented 342 # - Network Data TLV: 343 # - Commissioner Data TLV: 344 # Stable flag set to 0 345 # Border Agent Locator TLV 346 # Commissioner Session ID TLV 347 # - Active Timestamp TLV: 10s 348 # - Pending Timestamp TLV: 30s 349 with pkts.save_index(): 350 pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ 351 filter_wpan_src64(ROUTER_1).\ 352 filter_LLANMA().\ 353 filter(lambda p: p.mle.tlv.active_tstamp == TIMESTAMP_INIT and\ 354 p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and\ 355 (p.mle.tlv.leader_data.data_version - 356 _pkt.mle.tlv.leader_data.data_version) % 256 <= 127 and\ 357 (p.mle.tlv.leader_data.stable_data_version - 358 _pkt.mle.tlv.leader_data.stable_data_version) % 256 <= 127 and\ 359 p.thread_nwd.tlv.stable == [0] and\ 360 NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ 361 NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ 362 NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type 363 ).\ 364 must_next() 365 366 # Step 8: Router_1 sends a MLE Data Response to Router_2 including the following TLVs: 367 # - Source Address TLV 368 # - Leader Data TLV 369 # - Network Data TLV 370 # - Commissioner Data TLV: 371 # Stable flag set to 0 372 # Border Agent Locator TLV 373 # Commissioner Session ID TLV 374 # - Active Timestamp TLV: 10s 375 # - Pending Timestamp TLV: 30s 376 # - Pending Operational Dataset TLV 377 # - Active Timestamp TLV <210s> 378 # - Delay Timer TLV <~ 1000s> 379 # - Channel TLV : ‘Secondary’ 380 # - PAN ID TLV : 0xAFCE 381 pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ 382 filter_wpan_src64(ROUTER_1).\ 383 filter_wpan_dst64(ROUTER_2).\ 384 filter(lambda p: { 385 SOURCE_ADDRESS_TLV, 386 LEADER_DATA_TLV, 387 ACTIVE_TIMESTAMP_TLV, 388 PENDING_TIMESTAMP_TLV, 389 PENDING_OPERATION_DATASET_TLV 390 } <= set(p.mle.tlv.type) and\ 391 p.thread_nwd.tlv.stable == [0] and\ 392 NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ 393 NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ 394 NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type and\ 395 p.mle.tlv.active_tstamp == TIMESTAMP_INIT and\ 396 p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and\ 397 p.thread_meshcop.tlv.delay_timer < COMM_DELAY_TIMER and\ 398 p.thread_meshcop.tlv.active_tstamp == COMM_PENDING_ACTIVE_TIMESTAMP and\ 399 p.thread_meshcop.tlv.channel == [CHANNEL_SECOND] and\ 400 p.thread_meshcop.tlv.pan_id == [PANID_INIT] 401 ).\ 402 must_next() 403 404 # Step 10: Router_1 MUST attach to the new partition formed by Router_2 405 pv.verify_attached('ROUTER_1', 'ROUTER_2') 406 _pkt = pkts.last() 407 408 # Step 12: Router_1 MUST send a unicast MLE Data Request to the Router_2, including the 409 # following TLVs: 410 # - TLV Request TLV: 411 # - Network Data TLV 412 # - Active Timestamp TLV (10s) 413 # - Pending Timestamp TLV (30s) 414 with pkts.save_index(): 415 pkts.filter_wpan_src64(ROUTER_1).\ 416 filter_wpan_dst64(LEADER).\ 417 filter_mle_cmd(MLE_DATA_REQUEST).\ 418 filter(lambda p: { 419 TLV_REQUEST_TLV, 420 NETWORK_DATA_TLV, 421 ACTIVE_TIMESTAMP_TLV 422 } <= set(p.mle.tlv.type) and\ 423 p.mle.tlv.active_tstamp == TIMESTAMP_INIT and\ 424 p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and\ 425 p.thread_meshcop.tlv.type is nullField 426 ).\ 427 must_next() 428 429 # Step 14: Router_1 MUST multicast MLE Data Response with the new network data, 430 # including the following TLVs: 431 # - Source Address TLV 432 # - Leader Data TLV: 433 # Data Version field incremented 434 # Stable Version field incremented 435 # - Network Data TLV: 436 # - Commissioner Data TLV: 437 # Stable flag set to 0 438 # Border Agent Locator TLV 439 # Commissioner Session ID TLV 440 # - Active Timestamp TLV: 15s 441 # - Pending Timestamp TLV: 30s 442 pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ 443 filter_wpan_src64(ROUTER_1).\ 444 filter_LLANMA().\ 445 filter(lambda p: p.mle.tlv.active_tstamp == ROUTER2_ACTIVE_TIMESTAMP and\ 446 p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and\ 447 (p.mle.tlv.leader_data.data_version - 448 _pkt.mle.tlv.leader_data.data_version) % 256 <= 127 and\ 449 (p.mle.tlv.leader_data.stable_data_version - 450 _pkt.mle.tlv.leader_data.stable_data_version) % 256 <= 127 and\ 451 p.thread_nwd.tlv.stable == [0] and\ 452 NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ 453 NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ 454 NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type 455 ).\ 456 must_next() 457 458 # Step 17: Router_1 MUST send a unicast MLE Data Request to the Router_2, including the 459 # following TLVs: 460 # - TLV Request TLV: 461 # - Network Data TLV 462 # - Active Timestamp TLV (15s) 463 # - Pending Timestamp TLV (30s) 464 pkts.filter_wpan_src64(ROUTER_1).\ 465 filter_wpan_dst64(ROUTER_2).\ 466 filter_mle_cmd(MLE_DATA_REQUEST).\ 467 filter(lambda p: { 468 TLV_REQUEST_TLV, 469 NETWORK_DATA_TLV, 470 ACTIVE_TIMESTAMP_TLV 471 } <= set(p.mle.tlv.type) and\ 472 p.mle.tlv.active_tstamp == ROUTER2_ACTIVE_TIMESTAMP and\ 473 p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and\ 474 p.thread_meshcop.tlv.type is nullField 475 ).\ 476 must_next() 477 478 # Step 19: Router_1 MUST multicast MLE Data Response with the new network data, 479 # including the following TLVs: 480 # - Source Address TLV 481 # - Leader Data TLV: 482 # Data Version field incremented 483 # Stable Version field incremented 484 # - Network Data TLV: 485 # - Commissioner Data TLV: 486 # Stable flag set to 0 487 # Border Agent Locator TLV 488 # Commissioner Session ID TLV 489 # - Active Timestamp TLV: 15s 490 # - Pending Timestamp TLV: 50s 491 pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ 492 filter_wpan_src64(ROUTER_1).\ 493 filter_LLANMA().\ 494 filter(lambda p: p.mle.tlv.active_tstamp == ROUTER2_ACTIVE_TIMESTAMP and\ 495 p.mle.tlv.pending_tstamp == ROUTER2_PENDING_TIMESTAMP and\ 496 (p.mle.tlv.leader_data.data_version - 497 _pkt.mle.tlv.leader_data.data_version) % 256 <= 127 and\ 498 (p.mle.tlv.leader_data.stable_data_version - 499 _pkt.mle.tlv.leader_data.stable_data_version) % 256 <= 127 and\ 500 p.thread_nwd.tlv.stable == [0] and\ 501 NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ 502 NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ 503 NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type 504 ).\ 505 must_next() 506 507 # Step 21: Router_1 MUST go through the attachment process and send MLE Child ID 508 # Request to the Leader, including the following TLV: 509 # - Active Timestamp TLV: 15s 510 pkts.filter_mle_cmd(MLE_CHILD_ID_REQUEST).\ 511 filter_wpan_src64(ROUTER_1).\ 512 filter_wpan_dst64(LEADER).\ 513 filter(lambda p: p.mle.tlv.active_tstamp == ROUTER2_ACTIVE_TIMESTAMP).\ 514 must_next() 515 516 # Step 22: Leader MUST send MLE Child ID Response to Router_1, including its current 517 # active timestamp and active configuration set: 518 # - Active Timestamp TLV: 10s 519 # - Active Operational Dataset TLV: 520 # - Pending Timestamp TLV: 30s 521 # - Pending Operational Dataset TLV: 522 # - Active Timestamp TLV:210s 523 _pkt = pkts.filter_mle_cmd(MLE_CHILD_ID_RESPONSE).\ 524 filter_wpan_src64(LEADER).\ 525 filter_wpan_dst64(ROUTER_1).\ 526 filter(lambda p: 527 p.mle.tlv.active_tstamp == TIMESTAMP_INIT and\ 528 p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and\ 529 p.thread_meshcop.tlv.active_tstamp == COMM_PENDING_ACTIVE_TIMESTAMP 530 ).\ 531 must_next() 532 533 # Step 23: Router_1 MUST send MGMT_ACTIVE_SET.req to the Leader RLOC or Anycast Locator: 534 # CoAP Request URI 535 # coap://[Leader]:MM/c/as 536 # CoAP Payload 537 # - Active Timestamp TLV: 15s 538 # - Network Name TLV: “TEST” 539 # - PAN ID TLV 540 # - Channel TLV 541 with pkts.save_index(): 542 pkts.filter_wpan_src64(ROUTER_1).\ 543 filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ 544 filter_coap_request(MGMT_ACTIVE_SET_URI) .\ 545 filter(lambda p: { 546 NM_ACTIVE_TIMESTAMP_TLV, 547 NM_CHANNEL_TLV, 548 NM_NETWORK_NAME_TLV, 549 NM_PAN_ID_TLV, 550 } <= set(p.thread_meshcop.tlv.type) and\ 551 p.thread_meshcop.tlv.active_tstamp == ROUTER2_ACTIVE_TIMESTAMP and\ 552 p.thread_meshcop.tlv.net_name == [ROUTER2_NET_NAME] 553 ).\ 554 must_next() 555 556 # Step 24: Leader sends MGMT_ACTIVE_SET.rsp to the Router_1: 557 # CoAP Response Code 558 # 2.04 Changed 559 # CoAP Payload 560 # - State TLV (value = Accept) 561 # TODO: this ack can not be parsed by pktverify 562 563 # Step 25: Leader MUST send MGMT_DATASET_CHANGED.ntf to Commissioner: 564 # CoAP Request URI 565 # coap://[ Commissioner]:MM/c/dc 566 # CoAP Payload 567 # <empty> 568 with pkts.save_index(): 569 pkts.filter_wpan_src64(LEADER).\ 570 filter_wpan_dst16(COMMISSIONER_RLOC16).\ 571 filter_coap_request(MGMT_DATASET_CHANGED_URI) .\ 572 filter(lambda p: p.thread_meshcop.tlv.type is nullField).\ 573 must_next() 574 575 # Step 27: Router_1 MUST send MGMT_PENDING_SET.req to the Leader RLOC or Anycast Locator: 576 # CoAP Request URI 577 # coap://[Leader]:MM/c/ps 578 # CoAP Payload 579 # - Delay Timer TLV: ~200s 580 # - Channel TLV : ‘Primary’ 581 # - PAN ID TLV : 0xABCD 582 # - Network Name TLV: ‘TEST’ 583 # - Active Timestamp TLV: 410s 584 # - Pending Timestamp TLV: 50s 585 with pkts.save_index(): 586 pkts.filter_wpan_src64(ROUTER_1).\ 587 filter_ipv6_2dsts(LEADER_ALOC, LEADER_RLOC).\ 588 filter_coap_request(MGMT_PENDING_SET_URI) .\ 589 filter(lambda p: 590 p.thread_meshcop.tlv.delay_timer < ROUTER2_DELAY_TIMER and\ 591 p.thread_meshcop.tlv.channel == [CHANNEL_FINAL] and\ 592 p.thread_meshcop.tlv.pan_id == [PANID_FINAL] and\ 593 p.thread_meshcop.tlv.active_tstamp == ROUTER2_PENDING_ACTIVE_TIMESTAMP and\ 594 p.thread_meshcop.tlv.pending_tstamp == ROUTER2_PENDING_TIMESTAMP and\ 595 p.thread_meshcop.tlv.net_name == [ROUTER2_NET_NAME] 596 ).\ 597 must_next() 598 599 # Step 28: Leader sends MGMT_PENDING_SET.rsq to the Router_1: 600 # CoAP Response Code 601 # 2.04 Changed 602 # CoAP Payload 603 # - State TLV (value = Accept) 604 # TODO: this ack can not be parsed by pktverify 605 606 # Step 29: Leader MUST send MGMT_DATASET_CHANGED.ntf to Commissioner: 607 # CoAP Request URI 608 # coap://[ Commissioner]:MM/c/dc 609 # CoAP Payload 610 # <empty> 611 pkts.filter_wpan_src64(LEADER).\ 612 filter_wpan_dst16(COMMISSIONER_RLOC16).\ 613 filter_coap_request(MGMT_DATASET_CHANGED_URI) .\ 614 filter(lambda p: p.thread_meshcop.tlv.type is nullField).\ 615 must_next() 616 617 # Step 30: Leader MUST multicast MLE Data Response with the new network data, 618 # including the following TLVs: 619 # - Source Address TLV 620 # - Leader Data TLV: 621 # Data Version field incremented 622 # Stable Version field incremented 623 # - Network Data TLV: 624 # - Commissioner Data TLV: 625 # Stable flag set to 0 626 # Border Agent Locator TLV 627 # Commissioner Session ID TLV 628 # - Active Timestamp TLV: 15s 629 # - Pending Timestamp TLV: 50s 630 pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ 631 filter_wpan_src64(LEADER).\ 632 filter_LLANMA().\ 633 filter(lambda p: p.mle.tlv.active_tstamp == ROUTER2_ACTIVE_TIMESTAMP and\ 634 p.mle.tlv.pending_tstamp == ROUTER2_PENDING_TIMESTAMP and\ 635 (p.mle.tlv.leader_data.data_version - 636 _pkt.mle.tlv.leader_data.data_version) % 256 <= 127 and\ 637 (p.mle.tlv.leader_data.stable_data_version - 638 _pkt.mle.tlv.leader_data.stable_data_version) % 256 <= 127 and\ 639 p.thread_nwd.tlv.stable == [0] and\ 640 NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ 641 NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ 642 NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type 643 ).\ 644 must_next() 645 646 # 647 # Disable steps 32, 33, and 34 until a solution is 648 # found. Depending on timing, there may be one MLE Data 649 # Request/Response exchange for both Active and Pending 650 # Operational Datasets or individual MLE Data Request/Response 651 # exchange for each Active and Pending Operational Dataset 652 # separately. 653 # 654 655 # Step 32: Leader sends a MLE Data Response to Commissioner including the following TLVs: 656 # - Source Address TLV 657 # - Leader Data TLV 658 # - Active Timestamp TLV: 15s 659 # - Active Operational Dataset TLV: 660 # - Network Name TLV : ‘TEST’ 661 # - Pending Timestamp TLV: 50s 662 # - Pending Operational Dataset TLV 663 # - Active Timestamp TLV <410s> 664 # - Delay Timer TLV <~ 200s> 665 # - Channel TLV : ‘Primary’ 666 # - PAN ID TLV : 0xABCD 667 # - Network Name TLV : 'TEST' 668 #with pkts.save_index(): 669 # pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ 670 # filter_wpan_src64(LEADER).\ 671 # filter_wpan_dst64(COMMISSIONER).\ 672 # filter(lambda p: { 673 # SOURCE_ADDRESS_TLV, 674 # LEADER_DATA_TLV, 675 # ACTIVE_TIMESTAMP_TLV, 676 # PENDING_TIMESTAMP_TLV, 677 # PENDING_OPERATION_DATASET_TLV 678 # } <= set(p.mle.tlv.type) and\ 679 # p.thread_nwd.tlv.stable == [0] and\ 680 # NWD_COMMISSIONING_DATA_TLV in p.thread_nwd.tlv.type and\ 681 # NM_COMMISSIONER_SESSION_ID_TLV in p.thread_meshcop.tlv.type and\ 682 # NM_BORDER_AGENT_LOCATOR_TLV in p.thread_meshcop.tlv.type and\ 683 # p.mle.tlv.active_tstamp == ROUTER2_ACTIVE_TIMESTAMP and\ 684 # p.mle.tlv.pending_tstamp == ROUTER2_PENDING_TIMESTAMP and\ 685 # p.thread_meshcop.tlv.net_name == [ROUTER2_NET_NAME, ROUTER2_NET_NAME] and\ 686 # p.thread_meshcop.tlv.delay_timer < ROUTER2_DELAY_TIMER and\ 687 # p.thread_meshcop.tlv.active_tstamp == ROUTER2_PENDING_ACTIVE_TIMESTAMP and\ 688 # p.thread_meshcop.tlv.channel == [CHANNEL_INIT, CHANNEL_FINAL] and\ 689 # p.thread_meshcop.tlv.pan_id == [PANID_INIT, PANID_FINAL] 690 # ).\ 691 # must_next() 692 693 # Step 33: Router_1 MUST send a unicast MLE Data Request to the Leader, including the 694 # following TLVs: 695 # - TLV Request TLV: 696 # - Network Data TLV 697 # - Active Timestamp TLV (10s) 698 # - Pending Timestamp TLV (30s) 699 #pkts.filter_wpan_src64(ROUTER_1).\ 700 # filter_wpan_dst64(LEADER).\ 701 # filter_mle_cmd(MLE_DATA_REQUEST).\ 702 # filter(lambda p: { 703 # TLV_REQUEST_TLV, 704 # NETWORK_DATA_TLV, 705 # ACTIVE_TIMESTAMP_TLV 706 # } <= set(p.mle.tlv.type) and\ 707 # p.mle.tlv.active_tstamp == TIMESTAMP_INIT and\ 708 # p.mle.tlv.pending_tstamp == COMM_PENDING_TIMESTAMP and\ 709 # p.thread_meshcop.tlv.type is nullField 710 # ).\ 711 # must_next() 712 713 # Step 34: Leader sends a MLE Data Response to Router_1 including the following TLVs: 714 # - Source Address TLV 715 # - Leader Data TLV 716 # - Active Timestamp TLV: 15s 717 # - Active Operational Dataset TLV: 718 # - Network Name TLV : ‘TEST’ 719 # - Pending Timestamp TLV: 50s 720 # - Pending Operational Dataset TLV 721 # - Active Timestamp TLV <410s> 722 # - Delay Timer TLV <~ 200s> 723 # - Channel TLV : ‘Primary’ 724 # - PAN ID TLV : 0xABCD 725 #pkts.filter_mle_cmd(MLE_DATA_RESPONSE).\ 726 # filter_wpan_src64(LEADER).\ 727 # filter_wpan_dst64(ROUTER_1).\ 728 # filter(lambda p: { 729 # SOURCE_ADDRESS_TLV, 730 # LEADER_DATA_TLV, 731 # ACTIVE_TIMESTAMP_TLV, 732 # PENDING_TIMESTAMP_TLV, 733 # PENDING_OPERATION_DATASET_TLV 734 # } <= set(p.mle.tlv.type) and\ 735 # p.mle.tlv.active_tstamp == ROUTER2_ACTIVE_TIMESTAMP and\ 736 # p.mle.tlv.pending_tstamp == ROUTER2_PENDING_TIMESTAMP and\ 737 # p.thread_meshcop.tlv.delay_timer < ROUTER2_DELAY_TIMER and\ 738 # p.thread_meshcop.tlv.active_tstamp == ROUTER2_PENDING_ACTIVE_TIMESTAMP and\ 739 # p.thread_meshcop.tlv.channel == [CHANNEL_INIT, CHANNEL_FINAL] and\ 740 # p.thread_meshcop.tlv.pan_id == [PANID_INIT, PANID_FINAL] 741 # ).\ 742 # must_next() 743 744 # Step 36: The DUT MUST respond with an ICMPv6 Echo Reply 745 _pkt = pkts.filter_ping_request().\ 746 filter_ipv6_src_dst(ROUTER_2_MLEID, LEADER_MLEID).\ 747 filter_ipv6_dst(LEADER_MLEID).\ 748 must_next() 749 pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ 750 filter_ipv6_src_dst(LEADER_MLEID, ROUTER_2_MLEID).\ 751 must_next() 752 753 _pkt = pkts.filter_ping_request().\ 754 filter_ipv6_src_dst(COMMISSIONER_MLEID, ROUTER_1_MLEID).\ 755 must_next() 756 pkts.filter_ping_reply(identifier=_pkt.icmpv6.echo.identifier).\ 757 filter_ipv6_src_dst(ROUTER_1_MLEID, COMMISSIONER_MLEID).\ 758 must_next() 759 760 761if __name__ == '__main__': 762 unittest.main() 763