1#!/usr/bin/env python3.4 2# 3# Copyright 2018 - The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16 17import binascii 18import queue 19import time 20 21from acts import asserts 22from acts import utils 23from acts.test_decorators import test_tracker_info 24from acts.test_utils.wifi import wifi_constants 25from acts.test_utils.wifi import wifi_test_utils as wutils 26from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest 27from acts.test_utils.wifi.aware import aware_test_utils as autils 28 29class WifiDppTest(WifiBaseTest): 30 """This class tests the DPP API surface. 31 32 Attributes: The tests in this class require one DUT and one helper phone 33 device. 34 The tests in this class do not require a SIM. 35 """ 36 37 DPP_TEST_TIMEOUT = 60 38 DPP_TEST_SSID_PREFIX = "dpp_test_ssid_" 39 DPP_TEST_SECURITY_SAE = "SAE" 40 DPP_TEST_SECURITY_PSK_PASSPHRASE = "PSK_PASSPHRASE" 41 DPP_TEST_SECURITY_PSK = "PSK" 42 43 DPP_TEST_EVENT_DPP_CALLBACK = "onDppCallback" 44 DPP_TEST_EVENT_DATA = "data" 45 DPP_TEST_EVENT_ENROLLEE_SUCCESS = "onEnrolleeSuccess" 46 DPP_TEST_EVENT_CONFIGURATOR_SUCCESS = "onConfiguratorSuccess" 47 DPP_TEST_EVENT_PROGRESS = "onProgress" 48 DPP_TEST_EVENT_FAILURE = "onFailure" 49 DPP_TEST_MESSAGE_TYPE = "Type" 50 DPP_TEST_MESSAGE_STATUS = "Status" 51 DPP_TEST_MESSAGE_NETWORK_ID = "NetworkId" 52 DPP_TEST_MESSAGE_FAILURE_SSID = "onFailureSsid" 53 DPP_TEST_MESSAGE_FAILURE_CHANNEL_LIST = "onFailureChannelList" 54 DPP_TEST_MESSAGE_FAILURE_BAND_LIST = "onFailureBandList" 55 56 DPP_TEST_NETWORK_ROLE_STA = "sta" 57 DPP_TEST_NETWORK_ROLE_AP = "ap" 58 59 DPP_TEST_PARAM_SSID = "SSID" 60 DPP_TEST_PARAM_PASSWORD = "Password" 61 62 WPA_SUPPLICANT_SECURITY_SAE = "sae" 63 WPA_SUPPLICANT_SECURITY_PSK = "psk" 64 65 DPP_EVENT_PROGRESS_AUTHENTICATION_SUCCESS = 0 66 DPP_EVENT_PROGRESS_RESPONSE_PENDING = 1 67 DPP_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE = 2 68 DPP_EVENT_PROGRESS_CONFIGURATION_ACCEPTED = 3 69 70 DPP_EVENT_SUCCESS_CONFIGURATION_SENT = 0 71 DPP_EVENT_SUCCESS_CONFIGURATION_APPLIED = 1 72 73 def setup_class(self): 74 """ Sets up the required dependencies from the config file and configures the device for 75 WifiService API tests. 76 77 Returns: 78 True is successfully configured the requirements for testing. 79 """ 80 81 # Device 0 is under test. Device 1 performs the responder role 82 self.dut = self.android_devices[0] 83 self.helper_dev = self.android_devices[1] 84 85 # Do a simple version of init - mainly just sync the time and enable 86 # verbose logging. We would also like to test with phones in less 87 # constrained states (or add variations where we specifically 88 # constrain). 89 utils.require_sl4a((self.dut,)) 90 utils.sync_device_time(self.dut) 91 92 req_params = ["dpp_r1_test_only"] 93 opt_param = ["wifi_psk_network", "wifi_sae_network"] 94 self.unpack_userparams( 95 req_param_names=req_params, opt_param_names=opt_param) 96 97 self.dut.log.info( 98 "Parsed configs: %s %s" % (self.wifi_psk_network, self.wifi_sae_network)) 99 100 # Set up the networks. This is optional. In case these networks are not initialized, 101 # the script will create random ones. However, a real AP is required to pass DPP R2 test. 102 # Most efficient setup would be to use an AP in WPA2/WPA3 transition mode. 103 if self.DPP_TEST_PARAM_SSID in self.wifi_psk_network: 104 self.psk_network_ssid = self.wifi_psk_network[self.DPP_TEST_PARAM_SSID] 105 else: 106 self.psk_network_ssid = None 107 108 if self.DPP_TEST_PARAM_PASSWORD in self.wifi_psk_network: 109 self.psk_network_password = self.wifi_psk_network[self.DPP_TEST_PARAM_PASSWORD] 110 else: 111 self.psk_network_ssid = None 112 113 if self.DPP_TEST_PARAM_SSID in self.wifi_sae_network: 114 self.sae_network_ssid = self.wifi_sae_network[self.DPP_TEST_PARAM_SSID] 115 else: 116 self.sae_network_ssid = None 117 118 if self.DPP_TEST_PARAM_PASSWORD in self.wifi_sae_network: 119 self.sae_network_password = self.wifi_sae_network[self.DPP_TEST_PARAM_PASSWORD] 120 else: 121 self.sae_network_ssid = None 122 123 if self.dpp_r1_test_only == "False": 124 if not self.wifi_psk_network or not self.wifi_sae_network: 125 asserts.fail("Must specify wifi_psk_network and wifi_sae_network for DPP R2 tests") 126 127 # Enable verbose logging on the dut 128 self.dut.droid.wifiEnableVerboseLogging(1) 129 asserts.assert_true(self.dut.droid.wifiGetVerboseLoggingLevel() == 1, 130 "Failed to enable WiFi verbose logging on the dut.") 131 132 def teardown_class(self): 133 wutils.reset_wifi(self.dut) 134 135 def on_fail(self, test_name, begin_time): 136 self.dut.take_bug_report(test_name, begin_time) 137 self.dut.cat_adb_log(test_name, begin_time) 138 139 def create_and_save_wifi_network_config(self, security, random_network=False, 140 r2_auth_error=False): 141 """ Create a config with random SSID and password. 142 143 Args: 144 security: Security type: PSK or SAE 145 random_network: A boolean that indicates if to create a random network 146 r2_auth_error: A boolean that indicates if to create a network with a bad password 147 148 Returns: 149 A tuple with the config and networkId for the newly created and 150 saved network. 151 """ 152 if security == self.DPP_TEST_SECURITY_PSK: 153 if self.psk_network_ssid is None or self.psk_network_password is None or \ 154 random_network is True: 155 config_ssid = self.DPP_TEST_SSID_PREFIX + utils.rand_ascii_str(8) 156 config_password = utils.rand_ascii_str(8) 157 else: 158 config_ssid = self.psk_network_ssid 159 if r2_auth_error: 160 config_password = utils.rand_ascii_str(8) 161 else: 162 config_password = self.psk_network_password 163 else: 164 if self.sae_network_ssid is None or self.sae_network_password is None or \ 165 random_network is True: 166 config_ssid = self.DPP_TEST_SSID_PREFIX + utils.rand_ascii_str(8) 167 config_password = utils.rand_ascii_str(8) 168 else: 169 config_ssid = self.sae_network_ssid 170 if r2_auth_error: 171 config_password = utils.rand_ascii_str(8) 172 else: 173 config_password = self.sae_network_password 174 175 self.dut.log.info( 176 "creating config: %s %s %s" % (config_ssid, config_password, security)) 177 config = { 178 wutils.WifiEnums.SSID_KEY: config_ssid, 179 wutils.WifiEnums.PWD_KEY: config_password, 180 wutils.WifiEnums.SECURITY: security 181 } 182 183 # Now save the config. 184 network_id = self.dut.droid.wifiAddNetwork(config) 185 self.dut.log.info("saved config: network_id = %d" % network_id) 186 return network_id 187 188 def check_network_config_saved(self, expected_ssid, security, network_id): 189 """ Get the configured networks and check if the provided network ID is present. 190 191 Args: 192 expected_ssid: Expected SSID to match with received configuration. 193 security: Security type to match, PSK or SAE 194 195 Returns: 196 True if the WifiConfig is present. 197 """ 198 networks = self.dut.droid.wifiGetConfiguredNetworks() 199 if not networks: 200 return False 201 202 # Normalize PSK and PSK Passphrase to PSK 203 if security == self.DPP_TEST_SECURITY_PSK_PASSPHRASE: 204 security = self.DPP_TEST_SECURITY_PSK 205 206 # If the device doesn't support SAE, then the test fallbacks to PSK 207 if not self.dut.droid.wifiIsWpa3SaeSupported() and \ 208 security == self.DPP_TEST_SECURITY_SAE: 209 security = self.DPP_TEST_SECURITY_PSK 210 211 for network in networks: 212 if network_id == network['networkId'] and \ 213 security == network[wutils.WifiEnums.SECURITY] and \ 214 expected_ssid == network[wutils.WifiEnums.SSID_KEY]: 215 self.log.info("Found SSID %s" % network[wutils.WifiEnums.SSID_KEY]) 216 return True 217 return False 218 219 def forget_network(self, network_id): 220 """ Simple method to call wifiForgetNetwork and wait for confirmation callback. 221 222 Returns: 223 True if network was successfully deleted. 224 """ 225 self.dut.log.info("Deleting config: networkId = %s" % network_id) 226 self.dut.droid.wifiForgetNetwork(network_id) 227 try: 228 event = self.dut.ed.pop_event(wifi_constants.WIFI_FORGET_NW_SUCCESS, 10) 229 return True 230 except queue.Empty: 231 self.dut.log.error("Failed to forget network") 232 return False 233 234 def gen_uri(self, device, info="DPP_TESTER", chan="81/1", mac=None): 235 """Generate a URI on a device 236 237 Args: 238 device: Device object 239 mac: MAC address to use 240 info: Optional info to be embedded in URI 241 chan: Optional channel info 242 243 Returns: 244 URI ID to be used later 245 """ 246 247 # Clean up any previous URIs 248 self.del_uri(device, "'*'") 249 250 self.log.info("Generating a URI for the Responder") 251 cmd = "wpa_cli DPP_BOOTSTRAP_GEN type=qrcode info=%s" % info 252 253 if mac: 254 cmd += " mac=%s" % mac 255 256 if chan: 257 cmd += " chan=%s" % chan 258 259 result = device.adb.shell(cmd) 260 261 if "FAIL" in result: 262 asserts.fail("gen_uri: Failed to generate a URI. Command used: %s" % cmd) 263 264 if not result.index("\n"): 265 asserts.fail("gen_uri: Helper device not responding correctly, may need to restart it." 266 " Command used: %s" % cmd) 267 268 result = result[result.index("\n") + 1:] 269 device.log.info("Generated URI, id = %s" % result) 270 271 return result 272 273 def get_uri(self, device, uri_id): 274 """Get a previously generated URI from a device 275 276 Args: 277 device: Device object 278 uri_id: URI ID returned by gen_uri method 279 280 Returns: 281 URI string 282 283 """ 284 self.log.info("Reading the contents of the URI of the Responder") 285 cmd = "wpa_cli DPP_BOOTSTRAP_GET_URI %s" % uri_id 286 result = device.adb.shell(cmd) 287 288 if "FAIL" in result: 289 asserts.fail("get_uri: Failed to read URI. Command used: %s" % cmd) 290 291 result = result[result.index("\n") + 1:] 292 device.log.info("URI contents = %s" % result) 293 294 return result 295 296 def del_uri(self, device, uri_id): 297 """Delete a previously generated URI 298 299 Args: 300 device: Device object 301 uri_id: URI ID returned by gen_uri method 302 """ 303 self.log.info("Deleting the Responder URI") 304 cmd = "wpa_cli DPP_BOOTSTRAP_REMOVE %s" % uri_id 305 result = device.adb.shell(cmd) 306 307 # If URI was already flushed, ignore a failure here 308 if "FAIL" not in result: 309 device.log.info("Deleted URI, id = %s" % uri_id) 310 311 def start_responder_configurator(self, 312 device, 313 freq=2412, 314 net_role=DPP_TEST_NETWORK_ROLE_STA, 315 security=DPP_TEST_SECURITY_SAE, 316 invalid_config=False): 317 """Start a responder on helper device 318 319 Args: 320 device: Device object 321 freq: Frequency to listen on 322 net_role: Network role to configure 323 security: Security type: SAE or PSK 324 invalid_config: Send invalid configuration (negative test) 325 326 Returns: 327 ssid: SSID name of the network to be configured 328 329 """ 330 if not net_role or (net_role != self.DPP_TEST_NETWORK_ROLE_STA and 331 net_role != self.DPP_TEST_NETWORK_ROLE_AP): 332 asserts.fail("start_responder: Must specify net_role sta or ap") 333 334 self.log.info("Starting Responder in Configurator mode, frequency %sMHz" % freq) 335 336 conf = "conf=%s-" % net_role 337 338 use_psk = False 339 340 if security == self.DPP_TEST_SECURITY_SAE: 341 if not self.dut.droid.wifiIsWpa3SaeSupported(): 342 self.log.warning("SAE not supported on device! reverting to PSK") 343 security = self.DPP_TEST_SECURITY_PSK_PASSPHRASE 344 345 ssid = self.DPP_TEST_SSID_PREFIX + utils.rand_ascii_str(8) 346 password = utils.rand_ascii_str(8) 347 348 if security == self.DPP_TEST_SECURITY_SAE: 349 conf += self.WPA_SUPPLICANT_SECURITY_SAE 350 if not self.sae_network_ssid is None: 351 ssid = self.sae_network_ssid 352 password = self.sae_network_password 353 elif security == self.DPP_TEST_SECURITY_PSK_PASSPHRASE: 354 conf += self.WPA_SUPPLICANT_SECURITY_PSK 355 if not self.psk_network_ssid is None: 356 ssid = self.psk_network_ssid 357 password = self.psk_network_password 358 else: 359 conf += self.WPA_SUPPLICANT_SECURITY_PSK 360 use_psk = True 361 362 self.log.debug("SSID = %s" % ssid) 363 364 ssid_encoded = binascii.hexlify(ssid.encode()).decode() 365 366 if use_psk: 367 psk = utils.rand_ascii_str(16) 368 if not invalid_config: 369 psk_encoded = binascii.b2a_hex(psk.encode()).decode() 370 else: 371 # Use the psk as is without hex encoding, will make it invalid 372 psk_encoded = psk 373 self.log.debug("PSK = %s" % psk) 374 else: 375 if not invalid_config: 376 password_encoded = binascii.b2a_hex(password.encode()).decode() 377 else: 378 # Use the password as is without hex encoding, will make it invalid 379 password_encoded = password 380 self.log.debug("Password = %s" % password) 381 382 conf += " ssid=%s" % ssid_encoded 383 384 if password: # SAE password or PSK passphrase 385 conf += " pass=%s" % password_encoded 386 else: # PSK 387 conf += " psk=%s" % psk_encoded 388 389 # Stop responder first 390 self.stop_responder(device) 391 392 cmd = "wpa_cli set dpp_configurator_params guard=1 %s" % conf 393 device.log.debug("Command used: %s" % cmd) 394 result = self.helper_dev.adb.shell(cmd) 395 if "FAIL" in result: 396 asserts.fail( 397 "start_responder_configurator: Failure. Command used: %s" % cmd) 398 399 cmd = "wpa_cli DPP_LISTEN %d role=configurator netrole=%s" % (freq, 400 net_role) 401 device.log.debug("Command used: %s" % cmd) 402 result = self.helper_dev.adb.shell(cmd) 403 if "FAIL" in result: 404 asserts.fail( 405 "start_responder_configurator: Failure. Command used: %s" % cmd) 406 407 device.log.info("Started responder in configurator mode") 408 return ssid 409 410 def start_responder_enrollee(self, 411 device, 412 freq=2412, 413 net_role=DPP_TEST_NETWORK_ROLE_STA): 414 """Start a responder-enrollee on helper device 415 416 Args: 417 device: Device object 418 freq: Frequency to listen on 419 net_role: Network role to request 420 421 Returns: 422 ssid: SSID name of the network to be configured 423 424 """ 425 if not net_role or (net_role != self.DPP_TEST_NETWORK_ROLE_STA and 426 net_role != self.DPP_TEST_NETWORK_ROLE_AP): 427 asserts.fail("start_responder: Must specify net_role sta or ap") 428 429 # Stop responder first 430 self.stop_responder(device) 431 self.log.info("Starting Responder in Enrollee mode, frequency %sMHz" % freq) 432 433 cmd = "wpa_cli DPP_LISTEN %d role=enrollee netrole=%s" % (freq, net_role) 434 result = device.adb.shell(cmd) 435 436 if "FAIL" in result: 437 asserts.fail("start_responder_enrollee: Failure. Command used: %s" % cmd) 438 439 device.adb.shell("wpa_cli set dpp_config_processing 2") 440 441 device.log.info("Started responder in enrollee mode") 442 443 def stop_responder(self, device, flush=False): 444 """Stop responder on helper device 445 446 Args: 447 device: Device object 448 """ 449 result = device.adb.shell("wpa_cli DPP_STOP_LISTEN") 450 if "FAIL" in result: 451 asserts.fail("stop_responder: Failed to stop responder") 452 device.adb.shell("wpa_cli set dpp_configurator_params") 453 device.adb.shell("wpa_cli set dpp_config_processing 0") 454 if flush: 455 device.adb.shell("wpa_cli flush") 456 device.log.info("Stopped responder") 457 458 def start_dpp_as_initiator_configurator(self, 459 security, 460 use_mac, 461 responder_chan="81/1", 462 responder_freq=2412, 463 net_role=DPP_TEST_NETWORK_ROLE_STA, 464 cause_timeout=False, 465 fail_authentication=False, 466 invalid_uri=False, 467 r2_no_ap=False, 468 r2_auth_error=False): 469 """ Test Easy Connect (DPP) as initiator configurator. 470 471 1. Enable wifi, if needed 472 2. Create and save a random config. 473 3. Generate a URI using the helper device 474 4. Start DPP as responder-enrollee on helper device 475 5. Start DPP as initiator configurator on dut 476 6. Check if configurator sent successfully 477 7. Delete the URI from helper device 478 8. Remove the config. 479 480 Args: 481 security: Security type, a string "SAE" or "PSK" 482 use_mac: A boolean indicating whether to use the device's MAC 483 address (if True) or use a Broadcast (if False). 484 responder_chan: Responder channel to specify in the URI 485 responder_freq: Frequency that the Responder would actually listen on. 486 Note: To succeed, there must be a correlation between responder_chan, which is what 487 the URI advertises, and responder_freq which is the actual frequency. See: 488 https://en.wikipedia.org/wiki/List_of_WLAN_channels 489 net_role: Network role, a string "sta" or "ap" 490 cause_timeout: Intentionally don't start the responder to cause a 491 timeout 492 fail_authentication: Fail authentication by corrupting the 493 responder's key 494 invalid_uri: Use garbage string instead of a URI 495 r2_no_ap: Indicates if to test DPP R2 no AP failure event 496 r2_auth_error: Indicates if to test DPP R2 authentication failure 497 """ 498 if not self.dut.droid.wifiIsEasyConnectSupported(): 499 self.log.warning("Easy Connect is not supported on device!") 500 return 501 502 wutils.wifi_toggle_state(self.dut, True) 503 test_network_id = self.create_and_save_wifi_network_config(security, random_network=r2_no_ap, 504 r2_auth_error=r2_auth_error) 505 506 if use_mac: 507 mac = autils.get_mac_addr(self.helper_dev, "wlan0") 508 else: 509 mac = None 510 511 if invalid_uri: 512 enrollee_uri = "dskjgnkdjfgnkdsjfgnsDFGDIFGKDSJFGFDbgjdsnbkjdfnkbgsdfgFDSGSDfgesouhgureho" \ 513 "iu3ht98368903434089ut4958763094u0934ujg094j5oifegjfds" 514 else: 515 # Generate a URI with default info and channel 516 uri_id = self.gen_uri(self.helper_dev, chan=responder_chan, mac=mac) 517 518 # Get the URI. This is equal to scanning a QR code 519 enrollee_uri = self.get_uri(self.helper_dev, uri_id) 520 521 # Corrupt the responder key if required 522 if fail_authentication: 523 enrollee_uri = enrollee_uri[:80] + "DeAdBeeF" + enrollee_uri[88:] 524 self.log.info("Corrupted enrollee URI: %s" % enrollee_uri) 525 526 if not cause_timeout: 527 # Start DPP as an enrolle-responder for STA on helper device 528 self.start_responder_enrollee(self.helper_dev, freq=responder_freq, net_role=net_role) 529 else: 530 self.log.info("Not starting DPP responder on purpose") 531 532 self.log.info("Starting DPP in Configurator-Initiator mode") 533 534 # Start DPP as configurator-initiator on dut 535 self.dut.droid.startEasyConnectAsConfiguratorInitiator(enrollee_uri, 536 test_network_id, net_role) 537 538 start_time = time.time() 539 while time.time() < start_time + self.DPP_TEST_TIMEOUT: 540 dut_event = self.dut.ed.pop_event(self.DPP_TEST_EVENT_DPP_CALLBACK, 541 self.DPP_TEST_TIMEOUT) 542 if dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_TYPE] \ 543 == self.DPP_TEST_EVENT_ENROLLEE_SUCCESS: 544 asserts.fail("DPP failure, unexpected result!") 545 break 546 if dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_TYPE] \ 547 == self.DPP_TEST_EVENT_CONFIGURATOR_SUCCESS: 548 if cause_timeout or fail_authentication or invalid_uri or r2_no_ap or r2_auth_error: 549 asserts.fail( 550 "Unexpected DPP success, status code: %s" % 551 dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_STATUS]) 552 else: 553 val = dut_event[self.DPP_TEST_EVENT_DATA][ 554 self.DPP_TEST_MESSAGE_STATUS] 555 if val == self.DPP_EVENT_SUCCESS_CONFIGURATION_SENT: 556 self.dut.log.info("DPP Configuration sent success") 557 if val == self.DPP_EVENT_SUCCESS_CONFIGURATION_APPLIED: 558 self.dut.log.info("DPP Configuration applied by enrollee") 559 break 560 if dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_TYPE] \ 561 == self.DPP_TEST_EVENT_PROGRESS: 562 self.dut.log.info("DPP progress event") 563 val = dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_STATUS] 564 if val == self.DPP_EVENT_PROGRESS_AUTHENTICATION_SUCCESS: 565 self.dut.log.info("DPP Authentication success") 566 elif val == self.DPP_EVENT_PROGRESS_RESPONSE_PENDING: 567 self.dut.log.info("DPP Response pending") 568 elif val == self.DPP_EVENT_PROGRESS_CONFIGURATION_SENT_WAITING_RESPONSE: 569 self.dut.log.info("DPP Configuration sent, waiting response") 570 elif val == self.DPP_EVENT_PROGRESS_CONFIGURATION_ACCEPTED: 571 self.dut.log.info("Configuration accepted") 572 continue 573 if dut_event[self.DPP_TEST_EVENT_DATA][ 574 self.DPP_TEST_MESSAGE_TYPE] == self.DPP_TEST_EVENT_FAILURE: 575 if cause_timeout or fail_authentication or invalid_uri or r2_no_ap or r2_auth_error: 576 self.dut.log.info( 577 "Error %s occurred, as expected" % 578 dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_STATUS]) 579 if r2_no_ap or r2_auth_error: 580 if not dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_FAILURE_SSID]: 581 asserts.fail("Expected SSID value in DPP R2 onFailure event") 582 self.dut.log.info( 583 "Enrollee searched for SSID %s" % 584 dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_FAILURE_SSID]) 585 if r2_no_ap: 586 if not dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_FAILURE_CHANNEL_LIST]: 587 asserts.fail("Expected Channel list value in DPP R2 onFailure event") 588 self.dut.log.info( 589 "Enrollee scanned the following channels: %s" % 590 dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_FAILURE_CHANNEL_LIST]) 591 if r2_no_ap or r2_auth_error: 592 if not dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_FAILURE_BAND_LIST]: 593 asserts.fail("Expected Band Support list value in DPP R2 onFailure event") 594 self.dut.log.info( 595 "Enrollee supports the following bands: %s" % 596 dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_FAILURE_BAND_LIST]) 597 else: 598 asserts.fail( 599 "DPP failure, status code: %s" % 600 dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_STATUS]) 601 break 602 603 # Clear all pending events. 604 self.dut.ed.clear_all_events() 605 606 # Stop responder 607 self.stop_responder(self.helper_dev, flush=True) 608 609 if not invalid_uri: 610 # Delete URI 611 self.del_uri(self.helper_dev, uri_id) 612 613 asserts.assert_true( 614 self.forget_network(test_network_id), 615 "Test network not deleted from configured networks.") 616 617 def start_dpp_as_initiator_enrollee(self, 618 security, 619 use_mac, 620 cause_timeout=False, 621 invalid_config=False): 622 """ Test Easy Connect (DPP) as initiator enrollee. 623 624 1. Enable wifi, if needed 625 2. Start DPP as responder-configurator on helper device 626 3. Start DPP as initiator enrollee on dut 627 4. Check if configuration received successfully 628 5. Delete the URI from helper device 629 6. Remove the config. 630 631 Args: 632 security: Security type, a string "SAE" or "PSK" 633 use_mac: A boolean indicating whether to use the device's MAC 634 address (if True) or use a Broadcast (if False). 635 cause_timeout: Intentionally don't start the responder to cause a 636 timeout 637 invalid_config: Responder to intentionally send malformed 638 configuration 639 """ 640 if not self.dut.droid.wifiIsEasyConnectSupported(): 641 self.log.warning("Easy Connect is not supported on device!") 642 return 643 644 wutils.wifi_toggle_state(self.dut, True) 645 646 if use_mac: 647 mac = autils.get_mac_addr(self.helper_dev, "wlan0") 648 else: 649 mac = None 650 651 # Generate a URI with default info and channel 652 uri_id = self.gen_uri(self.helper_dev, mac=mac) 653 654 # Get the URI. This is equal to scanning a QR code 655 configurator_uri = self.get_uri(self.helper_dev, uri_id) 656 657 if not cause_timeout: 658 # Start DPP as an configurator-responder for STA on helper device 659 ssid = self.start_responder_configurator( 660 self.helper_dev, security=security, invalid_config=invalid_config) 661 else: 662 self.log.info( 663 "Not starting a responder configurator on helper device, on purpose") 664 ssid = self.DPP_TEST_SSID_PREFIX + utils.rand_ascii_str(8) 665 666 self.log.info("Starting DPP in Enrollee-Initiator mode") 667 668 # Start DPP as enrollee-initiator on dut 669 self.dut.droid.startEasyConnectAsEnrolleeInitiator(configurator_uri) 670 671 network_id = 0 672 673 start_time = time.time() 674 while time.time() < start_time + self.DPP_TEST_TIMEOUT: 675 dut_event = self.dut.ed.pop_event(self.DPP_TEST_EVENT_DPP_CALLBACK, 676 self.DPP_TEST_TIMEOUT) 677 if dut_event[self.DPP_TEST_EVENT_DATA][ 678 self.DPP_TEST_MESSAGE_TYPE] == self.DPP_TEST_EVENT_ENROLLEE_SUCCESS: 679 if cause_timeout or invalid_config: 680 asserts.fail( 681 "Unexpected DPP success, status code: %s" % 682 dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_STATUS]) 683 else: 684 self.dut.log.info("DPP Configuration received success") 685 network_id = dut_event[self.DPP_TEST_EVENT_DATA][ 686 self.DPP_TEST_MESSAGE_NETWORK_ID] 687 self.dut.log.info("NetworkID: %d" % network_id) 688 break 689 if dut_event[self.DPP_TEST_EVENT_DATA][ 690 self 691 .DPP_TEST_MESSAGE_TYPE] == self.DPP_TEST_EVENT_CONFIGURATOR_SUCCESS: 692 asserts.fail( 693 "DPP failure, unexpected result: %s" % 694 dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_STATUS]) 695 break 696 if dut_event[self.DPP_TEST_EVENT_DATA][ 697 self.DPP_TEST_MESSAGE_TYPE] == self.DPP_TEST_EVENT_PROGRESS: 698 self.dut.log.info("DPP progress event") 699 val = dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_STATUS] 700 if val == 0: 701 self.dut.log.info("DPP Authentication success") 702 elif val == 1: 703 self.dut.log.info("DPP Response pending") 704 continue 705 if dut_event[self.DPP_TEST_EVENT_DATA][ 706 self.DPP_TEST_MESSAGE_TYPE] == self.DPP_TEST_EVENT_FAILURE: 707 if cause_timeout or invalid_config: 708 self.dut.log.info( 709 "Error %s occurred, as expected" % 710 dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_STATUS]) 711 else: 712 asserts.fail( 713 "DPP failure, status code: %s" % 714 dut_event[self.DPP_TEST_EVENT_DATA][self.DPP_TEST_MESSAGE_STATUS]) 715 break 716 asserts.fail("Unknown message received") 717 718 # Clear all pending events. 719 self.dut.ed.clear_all_events() 720 721 # Stop responder 722 self.stop_responder(self.helper_dev, flush=True) 723 724 # Delete URI 725 self.del_uri(self.helper_dev, uri_id) 726 727 if not (invalid_config or cause_timeout): 728 # Check that the saved network is what we expect 729 asserts.assert_true( 730 self.check_network_config_saved(ssid, security, network_id), 731 "Could not find the expected network: %s" % ssid) 732 733 asserts.assert_true( 734 self.forget_network(network_id), 735 "Test network not deleted from configured networks.") 736 737 """ Tests Begin """ 738 739 @test_tracker_info(uuid="30893d51-2069-4e1c-8917-c8a840f91b59") 740 @WifiBaseTest.wifi_test_wrap 741 def test_dpp_as_initiator_configurator_with_psk_5G(self): 742 asserts.skip_if(not self.dut.droid.wifiIs5GHzBandSupported() or 743 not self.helper_dev.droid.wifiIs5GHzBandSupported(), 744 "5G not supported on at least on test device") 745 self.start_dpp_as_initiator_configurator( 746 security=self.DPP_TEST_SECURITY_PSK, responder_chan="126/149", responder_freq=5745, 747 use_mac=True) 748 749 @test_tracker_info(uuid="54d1d19a-aece-459c-b819-9d4b1ae63f77") 750 @WifiBaseTest.wifi_test_wrap 751 def test_dpp_as_initiator_configurator_with_psk_5G_broadcast(self): 752 asserts.skip_if(not self.dut.droid.wifiIs5GHzBandSupported() or 753 not self.helper_dev.droid.wifiIs5GHzBandSupported(), 754 "5G not supported on at least on test device") 755 self.start_dpp_as_initiator_configurator( 756 security=self.DPP_TEST_SECURITY_PSK, responder_chan="126/149", responder_freq=5745, 757 use_mac=False) 758 759 @test_tracker_info(uuid="18270a69-300c-4f54-87fd-c19073a2854e ") 760 @WifiBaseTest.wifi_test_wrap 761 def test_dpp_as_initiator_configurator_with_psk_no_chan_in_uri_listen_on_5745_broadcast(self): 762 asserts.skip_if(not self.dut.droid.wifiIs5GHzBandSupported() or 763 not self.helper_dev.droid.wifiIs5GHzBandSupported(), 764 "5G not supported on at least on test device") 765 self.start_dpp_as_initiator_configurator( 766 security=self.DPP_TEST_SECURITY_PSK, responder_chan=None, responder_freq=5745, use_mac=False) 767 768 @test_tracker_info(uuid="fbdd687c-954a-400b-9da3-2d17e28b0798") 769 @WifiBaseTest.wifi_test_wrap 770 def test_dpp_as_initiator_configurator_with_psk_no_chan_in_uri_listen_on_5745(self): 771 asserts.skip_if(not self.dut.droid.wifiIs5GHzBandSupported() or 772 not self.helper_dev.droid.wifiIs5GHzBandSupported(), 773 "5G not supported on at least on test device") 774 self.start_dpp_as_initiator_configurator( 775 security=self.DPP_TEST_SECURITY_PSK, responder_chan=None, responder_freq=5745, use_mac=True) 776 777 @test_tracker_info(uuid="570f499f-ab12-4405-af14-c9ed36da2e01") 778 @WifiBaseTest.wifi_test_wrap 779 def test_dpp_as_initiator_configurator_with_psk_no_chan_in_uri_listen_on_2462_broadcast(self): 780 self.start_dpp_as_initiator_configurator( 781 security=self.DPP_TEST_SECURITY_PSK, responder_chan=None, responder_freq=2462, use_mac=False) 782 783 @test_tracker_info(uuid="e1f083e0-0878-4c49-8ac5-d7c6bba24625") 784 @WifiBaseTest.wifi_test_wrap 785 def test_dpp_as_initiator_configurator_with_psk_no_chan_in_uri_listen_on_2462(self): 786 self.start_dpp_as_initiator_configurator( 787 security=self.DPP_TEST_SECURITY_PSK, responder_chan=None, responder_freq=2462, use_mac=True) 788 789 @test_tracker_info(uuid="d2a526f5-4269-493d-bd79-4e6d1b7b00f0") 790 @WifiBaseTest.wifi_test_wrap 791 def test_dpp_as_initiator_configurator_with_psk(self): 792 self.start_dpp_as_initiator_configurator( 793 security=self.DPP_TEST_SECURITY_PSK, use_mac=True) 794 795 @test_tracker_info(uuid="6ead218c-222b-45b8-8aad-fe7d883ed631") 796 @WifiBaseTest.wifi_test_wrap 797 def test_dpp_as_initiator_configurator_with_sae(self): 798 self.start_dpp_as_initiator_configurator( 799 security=self.DPP_TEST_SECURITY_SAE, use_mac=True) 800 801 @test_tracker_info(uuid="1686adb5-1b3c-4e6d-a969-6b007bdd990d") 802 @WifiBaseTest.wifi_test_wrap 803 def test_dpp_as_initiator_configurator_with_psk_passphrase(self): 804 self.start_dpp_as_initiator_configurator( 805 security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, use_mac=True) 806 807 @test_tracker_info(uuid="3958feb5-1a0c-4487-9741-ac06f04c55a2") 808 @WifiBaseTest.wifi_test_wrap 809 def test_dpp_as_initiator_configurator_with_sae_broadcast(self): 810 self.start_dpp_as_initiator_configurator( 811 security=self.DPP_TEST_SECURITY_SAE, use_mac=False) 812 813 @test_tracker_info(uuid="fe6d66f5-73a1-46e9-8f49-73b8f332cc8c") 814 @WifiBaseTest.wifi_test_wrap 815 def test_dpp_as_initiator_configurator_with_psk_passphrase_broadcast(self): 816 self.start_dpp_as_initiator_configurator( 817 security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, use_mac=False) 818 819 @test_tracker_info(uuid="9edd372d-e2f1-4545-8d04-6a1636fcbc4b") 820 @WifiBaseTest.wifi_test_wrap 821 def test_dpp_as_initiator_configurator_with_sae_for_ap(self): 822 self.start_dpp_as_initiator_configurator( 823 security=self.DPP_TEST_SECURITY_SAE, 824 use_mac=True, 825 net_role=self.DPP_TEST_NETWORK_ROLE_AP) 826 827 @test_tracker_info(uuid="e9eec912-d665-4926-beac-859cb13dc17b") 828 @WifiBaseTest.wifi_test_wrap 829 def test_dpp_as_initiator_configurator_with_psk_passphrase_for_ap(self): 830 self.start_dpp_as_initiator_configurator( 831 security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, 832 use_mac=True, 833 net_role=self.DPP_TEST_NETWORK_ROLE_AP) 834 835 @test_tracker_info(uuid="8055694f-606f-41dd-9826-3ea1e9b007f8") 836 @WifiBaseTest.wifi_test_wrap 837 def test_dpp_as_initiator_enrollee_with_sae(self): 838 self.start_dpp_as_initiator_enrollee( 839 security=self.DPP_TEST_SECURITY_SAE, use_mac=True) 840 841 @test_tracker_info(uuid="c1e9f605-b5c0-4e53-8a08-1b0087a667fa") 842 @WifiBaseTest.wifi_test_wrap 843 def test_dpp_as_initiator_enrollee_with_psk_passphrase(self): 844 self.start_dpp_as_initiator_enrollee( 845 security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, use_mac=True) 846 847 @test_tracker_info(uuid="1d7f30ad-2f9a-427a-8059-651dc8827ae2") 848 @WifiBaseTest.wifi_test_wrap 849 def test_dpp_as_initiator_enrollee_with_sae_broadcast(self): 850 self.start_dpp_as_initiator_enrollee( 851 security=self.DPP_TEST_SECURITY_SAE, use_mac=False) 852 853 @test_tracker_info(uuid="0cfc2645-600e-4f2b-ab5c-fcee6d363a9a") 854 @WifiBaseTest.wifi_test_wrap 855 def test_dpp_as_initiator_enrollee_with_psk_passphrase_broadcast(self): 856 self.start_dpp_as_initiator_enrollee( 857 security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, use_mac=False) 858 859 @test_tracker_info(uuid="2e26b248-65dd-41f6-977b-e223d72b2de9") 860 @WifiBaseTest.wifi_test_wrap 861 def test_start_dpp_as_initiator_enrollee_receive_invalid_config(self): 862 self.start_dpp_as_initiator_enrollee( 863 security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, 864 use_mac=True, 865 invalid_config=True) 866 867 @test_tracker_info(uuid="ed189661-d1c1-4626-9f01-3b7bb8a417fe") 868 @WifiBaseTest.wifi_test_wrap 869 def test_dpp_as_initiator_configurator_fail_authentication(self): 870 self.start_dpp_as_initiator_configurator( 871 security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, 872 use_mac=True, 873 fail_authentication=True) 874 875 @test_tracker_info(uuid="5a8c6587-fbb4-4a27-9cba-af6f8935833a") 876 @WifiBaseTest.wifi_test_wrap 877 def test_dpp_as_initiator_configurator_fail_unicast_timeout(self): 878 self.start_dpp_as_initiator_configurator( 879 security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, 880 use_mac=True, 881 cause_timeout=True) 882 883 @test_tracker_info(uuid="b12353ac-1a04-4036-81a4-2d2d0c653dbb") 884 @WifiBaseTest.wifi_test_wrap 885 def test_dpp_as_initiator_configurator_fail_broadcast_timeout(self): 886 self.start_dpp_as_initiator_configurator( 887 security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, 888 use_mac=False, 889 cause_timeout=True) 890 891 @test_tracker_info(uuid="eeff91be-09ce-4a33-8b4f-ece40eb51c76") 892 @WifiBaseTest.wifi_test_wrap 893 def test_dpp_as_initiator_configurator_invalid_uri(self): 894 self.start_dpp_as_initiator_configurator( 895 security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, 896 use_mac=True, 897 invalid_uri=True) 898 899 @test_tracker_info(uuid="1fa25f58-0d0e-40bd-8714-ab78957514d9") 900 @WifiBaseTest.wifi_test_wrap 901 def test_start_dpp_as_initiator_enrollee_fail_timeout(self): 902 self.start_dpp_as_initiator_enrollee( 903 security=self.DPP_TEST_SECURITY_PSK_PASSPHRASE, 904 use_mac=True, 905 cause_timeout=True) 906 907 @test_tracker_info(uuid="23601af8-118e-4ba8-89e3-5da2e37bbd7d") 908 def test_dpp_as_initiator_configurator_fail_r2_no_ap(self): 909 asserts.skip_if(self.dpp_r1_test_only == "True", 910 "DPP R1 test, skipping this test for DPP R2 only") 911 self.start_dpp_as_initiator_configurator( 912 security=self.DPP_TEST_SECURITY_PSK, use_mac=True, r2_no_ap=True) 913 914 @test_tracker_info(uuid="7f9756d3-f28f-498e-8dcf-ac3816303998") 915 def test_dpp_as_initiator_configurator_fail_r2_auth_error(self): 916 asserts.skip_if(self.dpp_r1_test_only == "True", 917 "DPP R1 test, skipping this test for DPP R2 only") 918 self.start_dpp_as_initiator_configurator( 919 security=self.DPP_TEST_SECURITY_PSK, use_mac=True, r2_auth_error=True) 920 921""" Tests End """ 922