1#!/usr/bin/env python3 2# 3# Copyright (c) 2020, The OpenThread Authors. 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions are met: 8# 1. Redistributions of source code must retain the above copyright 9# notice, this list of conditions and the following disclaimer. 10# 2. Redistributions in binary form must reproduce the above copyright 11# notice, this list of conditions and the following disclaimer in the 12# documentation and/or other materials provided with the distribution. 13# 3. Neither the name of the copyright holder nor the 14# names of its contributors may be used to endorse or promote products 15# derived from this software without specific prior written permission. 16# 17# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 'AS IS' 18# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 21# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27# POSSIBILITY OF SUCH DAMAGE. 28# 29 30import unittest 31 32from config import ADDRESS_TYPE 33from pktverify import consts 34 35import config 36import thread_cert 37 38LEADER = 1 39SED_1 = 2 40SSED_1 = 3 41 42POLL_PERIOD = 3000 # 3s 43 44 45class LowPower_7_1_01(thread_cert.TestCase): 46 USE_MESSAGE_FACTORY = False 47 TOPOLOGY = { 48 LEADER: { 49 'version': '1.2', 50 'name': 'LEADER', 51 'mode': 'rdn', 52 'allowlist': [SED_1, SSED_1], 53 }, 54 SED_1: { 55 'version': '1.2', 56 'name': 'SED_1', 57 'mode': '-', 58 'allowlist': [LEADER], 59 }, 60 SSED_1: { 61 'version': '1.2', 62 'name': 'SSED_1', 63 'mode': '-', 64 'allowlist': [LEADER], 65 } 66 } 67 """All nodes are created with default configurations""" 68 69 def test(self): 70 self.nodes[LEADER].start() 71 self.simulator.go(config.LEADER_STARTUP_DELAY) 72 self.assertEqual(self.nodes[LEADER].get_state(), 'leader') 73 74 self.nodes[SED_1].set_pollperiod(POLL_PERIOD) 75 self.nodes[SED_1].start() 76 self.simulator.go(5) 77 self.assertEqual(self.nodes[SED_1].get_state(), 'child') 78 79 self.nodes[SSED_1].set_csl_period(consts.CSL_DEFAULT_PERIOD) 80 self.nodes[SSED_1].start() 81 self.simulator.go(5) 82 self.assertEqual(self.nodes[SSED_1].get_state(), 'child') 83 84 leader_addr = self.nodes[LEADER].get_ip6_address(ADDRESS_TYPE.LINK_LOCAL) 85 86 # Step 3 - Verify connectivity by instructing each device to send an ICMPv6 Echo Request to the DUT 87 self.assertTrue(self.nodes[SED_1].ping(leader_addr, timeout=POLL_PERIOD * 2 / 1000)) 88 self.assertTrue(self.nodes[SSED_1].ping(leader_addr)) 89 self.simulator.go(5) 90 91 # Step 4 - SED_1 enables IEEE 802.15.4-2015 Enhanced ACK based Probing by sending a Link Metrics Management 92 # Request to the DUT 93 # MLE Link Metrics Management TLV Payload: 94 # - Enhanced ACK Configuration Sub-TLV 95 # -- Enh-ACK Flags = 1 (register a configuration) 96 # -- Concatenation of Link Metric Type ID Flags = 0x00: 97 # --- Item1: (0)(0)(001)(010) = 0x0a 98 # ---- E = 0 99 # ---- L = 0 100 # ---- Type/Average Enum = 1 (Exponential Moving Avg) 101 # ---- Metrics Enum = 2 (Link Margin) 102 self.nodes[SED_1].link_metrics_config_req_enhanced_ack_based_probing(leader_addr, True, 'm', mode='async') 103 self.simulator.go(5) 104 105 # Step 6 - SSED_1 enables IEEE 802.15.4-2015 Enhanced ACK based Probing by sending a Link Metrics Management 106 # Request to the DUT 107 # MLE Link Metrics Management TLV Payload: 108 # - Enhanced ACK Configuration Sub-TLV 109 # -- Enh-ACK Flags = 1 (register a configuration) 110 # -- Concatenation of Link Metric Type ID Flags = 0x00: 111 # --- Item1: (0)(0)(001)(010) = 0x0a 112 # --- Item2: (0)(0)(001)(011) = 0x0b 113 # ---- E = 0 114 # ---- L = 0 115 # ---- Type/Average Enum = 1 (Exponential Moving Avg) 116 # ---- Metrics Enum = 2 (Link Margin) 117 # ---- Metrics Enum = 3 (RSSI) 118 self.nodes[SSED_1].link_metrics_config_req_enhanced_ack_based_probing(leader_addr, True, 'mr', mode='async') 119 self.simulator.go(5) 120 121 # Step 8 - SSED_1 sends an MLE Data Message with setting Frame Version subfield within the MAC header of the 122 # message to 0b10 123 self.nodes[SSED_1].send_mac_emptydata() 124 self.simulator.go(5) 125 126 # Step 10 - SED_1 sends an MLE Data Message with setting Frame Version subfield within the MAC header of the 127 # message # to 0b10 128 self.nodes[SED_1].send_mac_emptydata() 129 self.simulator.go(5) 130 131 # Step 12 - SSED_1 clears its Enhanced ACK link metrics configuration by # sending a Link Metrics Management 132 # Request to the DUT 133 # Enh-ACK Flags = 0 (clear enhanced ACK link metric config) 134 self.nodes[SSED_1].link_metrics_config_req_enhanced_ack_based_probing(leader_addr, False, '', mode='async') 135 self.simulator.go(5) 136 137 # Step 14 - SSED_1 Sends a MLE Data Message with setting Frame Version subfield within the MAC header of the 138 # message to 0b10 139 self.nodes[SSED_1].send_mac_emptydata() 140 self.simulator.go(5) 141 142 # Step 16 - This step verifies that Enhanced ACKs cannot be enabled while requesting 3 metric types by 143 # instructing the device to send the following Link Metrics Management Request to the DUT 144 # MLE Link Metrics Management TLV Payload: 145 # - Enhanced ACK Configuration Sub-TLV 146 # -- Enh-ACK Flags = 1 (register a configuration) 147 # -- Concatenation of Link Metric Type ID Flags = 0x00: 148 # --- Item1: (0)(0)(001)(001) = 0x09 149 # --- Item2: (0)(0)(001)(010) = 0x0a 150 # --- Item3: (0)(0)(001)(011) = 0x0b 151 # ---- E = 0 152 # ---- L = 0 153 # ---- Type/Average Enum = 1 (Exponential Moving Avg) 154 # ---- Metrics Enum = 1 (Layer 2 LQI) 155 # ---- Metrics Enum = 2 (Link Margin) 156 # ---- Metrics Enum = 3 (RSSI) 157 self.nodes[SSED_1].link_metrics_config_req_enhanced_ack_based_probing(leader_addr, True, 'qmr', mode='async') 158 self.simulator.go(5) 159 160 # Step 18 - This step verifies that Enhanced ACKs cannot be enabled while requesting a reserved Type/Average 161 # enum of value 2 by instructing the device to send the following Link Metrics Management Request to the DUT 162 # MLE Link Metrics Management TLV Payload: 163 # - Enhanced ACK Configuration Sub-TLV 164 # -- Enh-ACK Flags = 1 (register a configuration) 165 # -- Concatenation of Link Metric Type ID Flags = 0x00: 166 # --- Item1: (0)(0)(010)(010) = 0x12 167 # ---- E = 0 168 # ---- L = 0 169 # ---- Type/Average Enum = 2 (Reserved) 170 # ---- Metrics Enum = 2 (Link Margin) 171 self.nodes[SSED_1].link_metrics_config_req_enhanced_ack_based_probing(leader_addr, 172 True, 173 'm', 174 'r', 175 mode='async') 176 self.simulator.go(5) 177 178 def verify(self, pv): 179 pkts = pv.pkts 180 pv.summary.show() 181 LEADER = pv.vars['LEADER'] 182 SED_1 = pv.vars['SED_1'] 183 SSED_1 = pv.vars['SSED_1'] 184 185 # Step 3 - The DUT MUST send ICMPv6 Echo Responses to both SED1 & SSED1 186 pkts.filter_wpan_src64(LEADER) \ 187 .filter_wpan_dst64(SED_1) \ 188 .filter_ping_reply() \ 189 .must_next() 190 pkts.filter_wpan_src64(LEADER) \ 191 .filter_wpan_dst64(SSED_1) \ 192 .filter_ping_reply() \ 193 .must_next() 194 195 # Step 4 - SED_1 enables IEEE 802.15.4-2015 Enhanced ACK based Probing by sending a Link Metrics Management 196 # Request to the DUT 197 # MLE Link Metrics Management TLV Payload: 198 # - Enhanced ACK Configuration Sub-TLV 199 # -- Enh-ACK Flags = 1 (register a configuration) 200 # -- Concatenation of Link Metric Type ID Flags = 0x00: 201 # --- Item1: (0)(0)(001)(010) = 0x0a 202 # ---- E = 0 203 # ---- L = 0 204 # ---- Type/Average Enum = 1 (Exponential Moving Avg) 205 # ---- Metrics Enum = 2 (Link Margin) 206 pkts.filter_wpan_src64(SED_1) \ 207 .filter_wpan_dst64(LEADER) \ 208 .filter_mle_cmd(consts.MLE_LINK_METRICS_MANAGEMENT_REQUEST) \ 209 .filter(lambda p: consts.LM_ENHANCED_ACK_CONFIGURATION_SUB_TLV in p.mle.tlv.link_sub_tlv) \ 210 .filter(lambda p: p.mle.tlv.link_enh_ack_flags == consts.LINK_METRICS_ENH_ACK_PROBING_REGISTER) \ 211 .filter(lambda p: p.mle.tlv.link_requested_type_id_flags == '0a') \ 212 .must_next() 213 214 # Step 5 - The DUT MUST send a Link Metrics Management Response to SED_1 containing the following TLVs: 215 # - MLE LInk Metrics Management TLV 216 # -- Link Metrics Status Sub-TLV = 0 (Success) 217 pkts.filter_wpan_src64(LEADER) \ 218 .filter_wpan_dst64(SED_1) \ 219 .filter_mle_cmd(consts.MLE_LINK_METRICS_MANAGEMENT_RESPONSE) \ 220 .filter(lambda p: p.mle.tlv.link_status_sub_tlv == consts.LINK_METRICS_STATUS_SUCCESS) \ 221 .must_next() 222 223 # Step 6 - SSED_1 enables IEEE 802.15.4-2015 Enhanced ACK based Probing by sending a Link Metrics Management 224 # Request to the DUT 225 # MLE Link Metrics Management TLV Payload: 226 # - Enhanced ACK Configuration Sub-TLV 227 # -- Enh-ACK Flags = 1 (register a configuration) 228 # -- Concatenation of Link Metric Type ID Flags = 0x00: 229 # --- Item1: (0)(0)(001)(010) = 0x0a 230 # --- Item2: (0)(0)(001)(011) = 0x0b 231 # ---- E = 0 232 # ---- L = 0 233 # ---- Type/Average Enum = 1 (Exponential Moving Avg) 234 # ---- Metrics Enum = 2 (Link Margin) 235 # ---- Metrics Enum = 3 (RSSI) 236 pkts.filter_wpan_src64(SSED_1) \ 237 .filter_mle_cmd(consts.MLE_LINK_METRICS_MANAGEMENT_REQUEST) \ 238 .filter(lambda p: consts.LM_ENHANCED_ACK_CONFIGURATION_SUB_TLV in p.mle.tlv.link_sub_tlv) \ 239 .filter(lambda p: p.mle.tlv.link_enh_ack_flags == consts.LINK_METRICS_ENH_ACK_PROBING_REGISTER) \ 240 .filter(lambda p: p.mle.tlv.link_requested_type_id_flags == '0a0b') \ 241 .must_next() 242 243 # Step 7 - The DUT MUST send a Link Metrics Management Response to SSED_1 244 pkts.filter_wpan_src64(LEADER) \ 245 .filter_mle_cmd(consts.MLE_LINK_METRICS_MANAGEMENT_RESPONSE) \ 246 .filter(lambda p: p.mle.tlv.link_status_sub_tlv == consts.LINK_METRICS_STATUS_SUCCESS) \ 247 .must_next() 248 249 # Step 8 - SSED_1 sends an MLE Data Message with setting Frame Version subfield within the MAC header of the 250 # message to 0b10 251 pkt = pkts.filter_wpan_src64(SSED_1) \ 252 .filter_wpan_data() \ 253 .filter_wpan_version(consts.MAC_FRAME_VERSION_2015) \ 254 .must_next() 255 ack_seq_no = pkt.wpan.seq_no 256 257 # Step 9 - The DUT MUST reply to SSED_1 with an Enhanced ACK containing the following: 258 # - Frame Control Field 259 # -- Security Enabled = True 260 # - Header IE 261 # -- Element ID = 0x00 262 # --- Vendor CID = 0xEAB89B (Thread Group) 263 # --- Vendor Specific Information 264 # ---- 1st byte = 0 (Enhanced ACK Link Metrics) 265 # ---- 2nd byte ... Link Margin data 266 # ---- 3rd byte ... RSSI data 267 pkts.filter_wpan_ack() \ 268 .filter_wpan_seq(ack_seq_no) \ 269 .filter(lambda p: p.wpan.payload_ie.vendor.oui == consts.THREAD_IEEE_802154_COMPANY_ID) \ 270 .must_next() 271 272 # Step 10 - SED_1 sends an MLE Data Message with setting Frame Version subfield within the MAC header of the 273 # message to 0b10 274 pkt = pkts.filter_wpan_src64(SED_1) \ 275 .filter_wpan_data() \ 276 .filter_wpan_version(consts.MAC_FRAME_VERSION_2015) \ 277 .must_next() 278 ack_seq_no = pkt.wpan.seq_no 279 280 # Step 11 - The DUT MUST reply to SED_1 with an Enhanced ACK containing the following: 281 # - Frame Control Field 282 # -- Security Enabled = True 283 # - Header IE 284 # -- Element ID = 0x00 285 # --- Vendor CID = 0xEAB89B (Thread Group) 286 # --- Vendor Specific Information 287 # ---- 1st byte = 0 (Enhanced ACK Link Metrics) 288 # ---- 2nd byte ... Link Margin data 289 pkts.filter_wpan_ack() \ 290 .filter_wpan_seq(ack_seq_no) \ 291 .filter(lambda p: p.wpan.payload_ie.vendor.oui == consts.THREAD_IEEE_802154_COMPANY_ID) \ 292 .must_next() 293 294 # Step 12 - SSED_1 clears enhanced ACK link metrics configuration by instructing it to send a Link Metrics 295 # Management Request to the DUT 296 # - MLE Link Metrics Management TLV Payload 297 # -- Enhanced ACK Configuration Sub-TLV 298 # -- Enh-ACK Flags = 0 (clear enhanced ACK link metric config) 299 pkts.filter_wpan_src64(SSED_1) \ 300 .filter_wpan_dst64(LEADER) \ 301 .filter_mle_cmd(consts.MLE_LINK_METRICS_MANAGEMENT_REQUEST) \ 302 .filter(lambda p: consts.LM_ENHANCED_ACK_CONFIGURATION_SUB_TLV in p.mle.tlv.link_sub_tlv) \ 303 .filter(lambda p: p.mle.tlv.link_enh_ack_flags == consts.LINK_METRICS_ENH_ACK_PROBING_CLEAR) \ 304 .must_next() 305 306 # Step 13 - The DUT MUST send Link Metrics Management Response to SSED_1 containing the following: 307 # - MLE Link Metrics Management TLV 308 # -- Link Metrics Status Sub-TLV = 0 (Success) 309 pkts.filter_wpan_src64(LEADER) \ 310 .filter_wpan_dst64(SSED_1) \ 311 .filter_mle_cmd(consts.MLE_LINK_METRICS_MANAGEMENT_RESPONSE) \ 312 .filter(lambda p: p.mle.tlv.link_status_sub_tlv == consts.LINK_METRICS_STATUS_SUCCESS) \ 313 .must_next() 314 315 # Step 14 - SSED_1 sends an MLE Data Message with setting Frame Version subfield within the MAC header of the 316 # message to 0b10 317 pkt = pkts.filter_wpan_src64(SSED_1) \ 318 .filter_wpan_data() \ 319 .filter_wpan_version(consts.MAC_FRAME_VERSION_2015) \ 320 .must_next() 321 ack_seq_no = pkt.wpan.seq_no 322 323 # Step 15 - The DUT MUST NOT include a Link Metrics Report in the ACK 324 pkts.filter_wpan_ack() \ 325 .filter_wpan_seq(ack_seq_no) \ 326 .filter_wpan_ie_not_present() \ 327 .must_next() 328 329 # Step 16 - This step verifies that Enhanced ACKS cannot be enabled while requesting 3 metric types by 330 # instructing the device to send the following Link Metrics Management Request to the DUT: 331 # MLE Link Metrics Management TLV Payload: 332 # - Enhanced ACK Configuration Sub-TLV 333 # -- Enh-ACK Flags = 1 (register a configuration) 334 # -- Concatenation of Link Metric Type ID Flags = 0x00: 335 # --- Item1: (0)(0)(001)(001) = 0x09 336 # --- Item2: (0)(0)(001)(010) = 0x0a 337 # --- Item3: (0)(0)(001)(011) = 0x0b 338 # ---- E = 0 339 # ---- L = 0 340 # ---- Type/Average Enum = 1 (Exponential Moving Avg) 341 # ---- Metrics Enum = 1 (Layer 2 LQI) 342 # ---- Metrics Enum = 2 (Link Margin) 343 # ---- Metrics Enum = 3 (RSSI) 344 pkts.filter_wpan_src64(SSED_1) \ 345 .filter_wpan_dst64(LEADER) \ 346 .filter_mle_cmd(consts.MLE_LINK_METRICS_MANAGEMENT_REQUEST) \ 347 .filter(lambda p: consts.LM_ENHANCED_ACK_CONFIGURATION_SUB_TLV in p.mle.tlv.link_sub_tlv) \ 348 .filter(lambda p: p.mle.tlv.link_enh_ack_flags == consts.LINK_METRICS_ENH_ACK_PROBING_REGISTER) \ 349 .filter(lambda p: p.mle.tlv.link_requested_type_id_flags == '090a0b') \ 350 .must_next() 351 352 # Step 17 - Leader automatically responds to the invalid query from SSED_1 with a failure 353 # The DUT MUST send Link Metrics Management Response to SSED_1containing the following: 354 # - MLE Link Metrics Management TLV 355 # -- Link Metrics Status Sub-TLV = 254 (Failure) 356 pkts.filter_wpan_src64(LEADER) \ 357 .filter_wpan_dst64(SSED_1) \ 358 .filter_mle_cmd(consts.MLE_LINK_METRICS_MANAGEMENT_RESPONSE) \ 359 .filter(lambda p: p.mle.tlv.link_status_sub_tlv == consts.LINK_METRICS_STATUS_OTHER_ERROR) \ 360 .must_next() 361 362 # Step 18 - This step verifies that Enhanced ACKs cannot be enabled while requesting a reserved Type/Average 363 # enum of value 2 by instructing the device to send the following Link Metrics Management Request to the DUT 364 # MLE Link Metrics Management TLV Payload: 365 # - Enhanced ACK Configuration Sub-TLV 366 # -- Enh-ACK Flags = 1 (register a configuration) 367 # -- Concatenation of Link Metric Type ID Flags = 0x00: 368 # --- Item1: (0)(0)(010)(010) = 0x12 369 # ---- E = 0 370 # ---- L = 0 371 # ---- Type/Average Enum = 2 (Reserved) 372 # ---- Metrics Enum = 2 (Link Margin) 373 pkts.filter_wpan_src64(SSED_1) \ 374 .filter_wpan_dst64(LEADER) \ 375 .filter_mle_cmd(consts.MLE_LINK_METRICS_MANAGEMENT_REQUEST) \ 376 .filter(lambda p: consts.LM_ENHANCED_ACK_CONFIGURATION_SUB_TLV in p.mle.tlv.link_sub_tlv) \ 377 .filter(lambda p: p.mle.tlv.link_enh_ack_flags == consts.LINK_METRICS_ENH_ACK_PROBING_REGISTER) \ 378 .filter(lambda p: p.mle.tlv.link_requested_type_id_flags == '12') \ 379 .must_next() 380 381 # Step 19 - Leader automatically responds to the invalid query from SSED_1 with a failure 382 # The DUT MUST send Link Metrics Management Response to SSED_1containing the following: 383 # - MLE Link Metrics Management TLV 384 # -- Link Metrics Status Sub-TLV = 254 (Failure) 385 pkts.filter_wpan_src64(LEADER) \ 386 .filter_wpan_dst64(SSED_1) \ 387 .filter_mle_cmd(consts.MLE_LINK_METRICS_MANAGEMENT_RESPONSE) \ 388 .filter(lambda p: p.mle.tlv.link_status_sub_tlv == consts.LINK_METRICS_STATUS_OTHER_ERROR) \ 389 .must_next() 390 391 392if __name__ == '__main__': 393 unittest.main() 394