1#!/usr/bin/env python3.4 2# 3# Copyright 2016 - 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 queue 18import time 19 20from acts import asserts 21from acts import base_test 22from acts import signals 23from acts.test_decorators import test_tracker_info 24from acts_contrib.test_utils.wifi import wifi_test_utils as wutils 25from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest 26 27WifiChannelUS = wutils.WifiChannelUS 28WifiEnums = wutils.WifiEnums 29 30SCAN_EVENT_TAG = "WifiScannerScan" 31 32 33class WifiScanResultEvents(): 34 """This class stores the setting of a scan, parameters generated 35 from starting the scan, and events reported later from the scan 36 for validation. 37 38 Attributes: 39 scan_setting: Setting used to perform the scan. 40 scan_channels: Channels used for scanning. 41 events: A list to store the scan result events. 42 """ 43 44 def __init__(self, scan_setting, scan_channels): 45 self.scan_setting = scan_setting 46 self.scan_channels = scan_channels 47 self.results_events = [] 48 49 def add_results_event(self, event): 50 self.results_events.append(event) 51 52 def check_interval(self, scan_result, scan_result_next): 53 """Verifies that the time gap between two consecutive results is within 54 expected range. 55 56 Right now it is hard coded to be 20 percent of the interval specified 57 by scan settings. This threshold can be imported from the configuration 58 file in the future if necessary later. 59 60 Note the scan result timestamps are in microseconds, but "periodInMs" 61 in scan settings is in milliseconds. 62 63 Args: 64 scan_result: A dictionary representing a scan result for a BSSID. 65 scan_result_next: A dictionary representing a scan result for a 66 BSSID, whose scan happened after scan_result. 67 """ 68 actual_interval = scan_result_next["timestamp"] - scan_result[ 69 "timestamp"] 70 expected_interval = self.scan_setting['periodInMs'] * 1000 71 delta = abs(actual_interval - expected_interval) 72 margin = expected_interval * 0.25 # 25% of the expected_interval 73 asserts.assert_true( 74 delta < margin, "The difference in time between scan %s and " 75 "%s is %dms, which is out of the expected range %sms" % ( 76 scan_result, scan_result_next, delta / 1000, 77 self.scan_setting['periodInMs'])) 78 79 def verify_one_scan_result(self, scan_result): 80 """Verifies the scan result of a single BSSID. 81 82 1. Verifies the frequency of the network is within the range requested 83 in the scan. 84 85 Args: 86 scan_result: A dictionary representing the scan result of a single 87 BSSID. 88 """ 89 freq = scan_result["frequency"] 90 asserts.assert_true( 91 freq in self.scan_channels, 92 "Frequency %d of result entry %s is out of the expected range %s." 93 % (freq, scan_result, self.scan_channels)) 94 # TODO(angli): add RSSI check. 95 96 def verify_one_scan_result_group(self, batch): 97 """Verifies a group of scan results obtained during one scan. 98 99 1. Verifies the number of BSSIDs in the batch is less than the 100 threshold set by scan settings. 101 2. Verifies each scan result for individual BSSID. 102 103 Args: 104 batch: A list of dictionaries, each dictionary represents a scan 105 result. 106 """ 107 scan_results = batch["ScanResults"] 108 actual_num_of_results = len(scan_results) 109 expected_num_of_results = self.scan_setting['numBssidsPerScan'] 110 asserts.assert_true(actual_num_of_results <= expected_num_of_results, 111 "Expected no more than %d BSSIDs, got %d." % 112 (expected_num_of_results, actual_num_of_results)) 113 for scan_result in scan_results: 114 self.verify_one_scan_result(scan_result) 115 116 def have_enough_events(self): 117 """Check if there are enough events to properly validate the scan""" 118 return len(self.results_events) >= 2 119 120 def check_scan_results(self): 121 """Validate the reported scan results against the scan settings. 122 Assert if any error detected in the results. 123 124 1. For each scan setting there should be no less than 2 events received. 125 2. For batch scan, the number of buffered results in each event should 126 be exactly what the scan setting specified. 127 3. Each scan result should contain no more BBSIDs than what scan 128 setting specified. 129 4. The frequency reported by each scan result should comply with its 130 scan setting. 131 5. The time gap between two consecutive scan results should be 132 approximately equal to the scan interval specified by the scan 133 setting. 134 A scan result looks like this: 135 { 136 'data': 137 { 138 'Type': 'onResults', 139 'ResultElapsedRealtime': 4280931, 140 'Index': 10, 141 'Results': [ 142 { 143 'Flags': 0, 144 'Id': 4, 145 'ScanResults':[ 146 { 147 'is80211McRTTResponder': False, 148 'channelWidth': 0, 149 'numUsage': 0, 150 'SSID': '"wh_ap1_2g"', 151 'timestamp': 4280078660, 152 'BSSID': '30:b5:c2:33:f9:05', 153 'frequency': 2412, 154 'distanceSdCm': 0, 155 'distanceCm': 0, 156 'centerFreq1': 0, 157 'centerFreq0': 0, 158 'venueName': '', 159 'seen': 0, 160 'operatorFriendlyName': '', 161 'level': -31, 162 'passpointNetwork': False, 163 'untrusted': False 164 } 165 ] 166 } 167 ] 168 }, 169 'time': 1491744576383, 170 'name': 'WifiScannerScan10onResults' 171 } 172 """ 173 num_of_events = len(self.results_events) 174 asserts.assert_true( 175 num_of_events >= 2, 176 "Expected more than one scan result events, got %d." % 177 num_of_events) 178 for event_idx in range(num_of_events): 179 batches = self.results_events[event_idx]["data"]["Results"] 180 actual_num_of_batches = len(batches) 181 if not actual_num_of_batches: 182 raise signals.TestFailure("Scan returned empty Results list %s " 183 "% batches") 184 # For batch scan results. 185 report_type = self.scan_setting['reportEvents'] 186 if not (report_type & WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN): 187 # Verifies that the number of buffered results matches the 188 # number defined in scan settings. 189 expected_num_of_batches = self.scan_setting['maxScansToCache'] 190 asserts.assert_true( 191 actual_num_of_batches <= expected_num_of_batches, 192 "Expected to get at most %d batches in event No.%d, got %d." 193 % (expected_num_of_batches, event_idx, 194 actual_num_of_batches)) 195 # Check the results within each event of batch scan 196 for batch_idx in range(actual_num_of_batches): 197 if not len(batches[batch_idx]["ScanResults"]): 198 raise signals.TestFailure("Scan event %d returned empty" 199 " scan results in batch %d" % (event_idx, batch_idx)) 200 # Start checking interval from the second batch. 201 if batch_idx >=1: 202 self.check_interval( 203 batches[batch_idx - 1]["ScanResults"][0], 204 batches[batch_idx]["ScanResults"][0]) 205 for batch in batches: 206 self.verify_one_scan_result_group(batch) 207 208 # Check the time gap between the first result of an event and 209 # the last result of its previous event 210 # Skip the very first event. 211 if event_idx >= 1: 212 previous_batches = self.results_events[event_idx - 1]["data"][ 213 "Results"] 214 self.check_interval(previous_batches[-1]["ScanResults"][0], 215 batches[0]["ScanResults"][0]) 216 217 218class WifiScannerMultiScanTest(WifiBaseTest): 219 """This class is the WiFi Scanner Multi-Scan Test suite. 220 It collects a number of test cases, sets up and executes 221 the tests, and validates the scan results. 222 223 Attributes: 224 tests: A collection of tests to excute. 225 leeway: Scan interval drift time (in seconds). 226 stime_channels: Dwell time plus 2ms. 227 dut: Android device(s). 228 wifi_chs: WiFi channels according to the device model. 229 """ 230 231 def __init__(self, configs): 232 super().__init__(configs) 233 self.enable_packet_log = True 234 self.tests = ( 235 'test_wifi_two_scans_at_same_interval', 236 'test_wifi_two_scans_at_different_interval', 237 'test_wifi_scans_24GHz_and_both', 238 'test_wifi_scans_5GHz_and_both', 239 'test_wifi_scans_batch_and_24GHz', 240 'test_wifi_scans_batch_and_5GHz', 241 'test_wifi_scans_24GHz_5GHz_full_result',) 242 243 def setup_class(self): 244 super().setup_class() 245 self.leeway = 5 # seconds, for event wait time computation 246 self.stime_channel = 47 #dwell time plus 2ms 247 self.dut = self.android_devices[0] 248 wutils.wifi_test_device_init(self.dut) 249 asserts.assert_true(self.dut.droid.wifiIsScannerSupported(), 250 "Device %s doesn't support WifiScanner, abort." % 251 self.dut.model) 252 """ Setup the required dependencies and fetch the user params from 253 config file. 254 """ 255 opt_param = ["reference_networks"] 256 self.unpack_userparams(opt_param_names=opt_param) 257 258 if "AccessPoint" in self.user_params: 259 self.legacy_configure_ap_and_start() 260 elif "OpenWrtAP" in self.user_params: 261 self.configure_openwrt_ap_and_start(open_network=True) 262 263 self.wifi_chs = WifiChannelUS(self.dut.model) 264 265 def teardown_class(self): 266 if "AccessPoint" in self.user_params: 267 del self.user_params["reference_networks"] 268 del self.user_params["open_network"] 269 270 """ Helper Functions Begin """ 271 272 def start_scan(self, scan_setting): 273 data = wutils.start_wifi_background_scan(self.dut, scan_setting) 274 idx = data["Index"] 275 # Calculate event wait time from scan setting plus leeway 276 scan_time, scan_channels = wutils.get_scan_time_and_channels( 277 self.wifi_chs, scan_setting, self.stime_channel) 278 scan_period = scan_setting['periodInMs'] 279 report_type = scan_setting['reportEvents'] 280 if report_type & WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN: 281 scan_time += scan_period 282 else: 283 max_scan = scan_setting['maxScansToCache'] 284 scan_time += max_scan * scan_period 285 wait_time = scan_time / 1000 + self.leeway 286 return idx, wait_time, scan_channels 287 288 def validate_scan_results(self, scan_results_dict): 289 # Check to make sure the dict is not empty 290 asserts.assert_true(scan_results_dict, "Scan result dict is empty.") 291 for scan_result_obj in scan_results_dict.values(): 292 # Validate the results received for each scan setting 293 scan_result_obj.check_scan_results() 294 295 def wait_for_scan_events(self, wait_time_list, scan_results_dict): 296 """Poll for WifiScanner events and record them""" 297 298 # Compute the event wait time 299 event_wait_time = min(wait_time_list) 300 301 # Compute the maximum test time that guarantee that even the scan 302 # which requires the most wait time will receive at least two 303 # results. 304 max_wait_time = max(wait_time_list) 305 max_end_time = time.monotonic() + max_wait_time 306 self.log.debug("Event wait time %s seconds", event_wait_time) 307 308 try: 309 # Wait for scan results on all the caller specified bands 310 event_name = SCAN_EVENT_TAG 311 while True: 312 self.log.debug("Waiting for events '%s' for up to %s seconds", 313 event_name, event_wait_time) 314 events = self.dut.ed.pop_events(event_name, event_wait_time) 315 for event in events: 316 self.log.debug("Event received: %s", event) 317 # Event name is the key to the scan results dictionary 318 actual_event_name = event["name"] 319 asserts.assert_true( 320 actual_event_name in scan_results_dict, 321 "Expected one of these event names: %s, got '%s'." % 322 (scan_results_dict.keys(), actual_event_name)) 323 324 # TODO validate full result callbacks also 325 if event["name"].endswith("onResults"): 326 # Append the event 327 scan_results_dict[actual_event_name].add_results_event( 328 event) 329 330 # If we time out then stop waiting for events. 331 if time.monotonic() >= max_end_time: 332 break 333 # If enough scan results have been returned to validate the 334 # results then break early. 335 have_enough_events = True 336 for key in scan_results_dict: 337 if not scan_results_dict[key].have_enough_events(): 338 have_enough_events = False 339 if have_enough_events: 340 break 341 except queue.Empty: 342 asserts.fail("Event did not trigger for {} in {} seconds".format( 343 event_name, event_wait_time)) 344 345 def scan_and_validate_results(self, scan_settings): 346 """Perform WifiScanner scans and check the scan results 347 348 Procedures: 349 * Start scans for each caller specified setting 350 * Wait for at least two results for each scan 351 * Check the results received for each scan 352 """ 353 # Awlays get a clean start 354 self.dut.ed.clear_all_events() 355 356 # Start scanning with the caller specified settings and 357 # compute parameters for receiving events 358 idx_list = [] 359 wait_time_list = [] 360 scan_results_dict = {} 361 362 try: 363 for scan_setting in scan_settings: 364 self.log.debug( 365 "Scan setting: band %s, interval %s, reportEvents " 366 "%s, numBssidsPerScan %s", scan_setting["band"], 367 scan_setting["periodInMs"], scan_setting["reportEvents"], 368 scan_setting["numBssidsPerScan"]) 369 idx, wait_time, scan_chan = self.start_scan(scan_setting) 370 self.log.debug( 371 "Scan started for band %s: idx %s, wait_time %ss, scan_channels %s", 372 scan_setting["band"], idx, wait_time, scan_chan) 373 idx_list.append(idx) 374 wait_time_list.append(wait_time) 375 376 report_type = scan_setting['reportEvents'] 377 scan_results_events = WifiScanResultEvents(scan_setting, 378 scan_chan) 379 scan_results_dict["{}{}onResults".format( 380 SCAN_EVENT_TAG, idx)] = scan_results_events 381 if (scan_setting['reportEvents'] 382 & WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT): 383 scan_results_dict["{}{}onFullResult".format( 384 SCAN_EVENT_TAG, idx)] = scan_results_events 385 386 self.wait_for_scan_events(wait_time_list, scan_results_dict) 387 388 # Validate the scan results 389 self.validate_scan_results(scan_results_dict) 390 391 finally: 392 # Tear down and clean up 393 for idx in idx_list: 394 self.dut.droid.wifiScannerStopBackgroundScan(idx) 395 self.dut.ed.clear_all_events() 396 397 """ Helper Functions End """ 398 """ Tests Begin """ 399 400 @test_tracker_info(uuid="d490b146-5fc3-4fc3-9958-78ba0ad63211") 401 @WifiBaseTest.wifi_test_wrap 402 def test_wifi_two_scans_at_same_interval(self): 403 """Perform two WifiScanner background scans, one at 2.4GHz and the other 404 at 5GHz, the same interval and number of BSSIDs per scan. 405 406 Initial Conditions: 407 * Set multiple APs broadcasting 2.4GHz and 5GHz. 408 409 Expected Results: 410 * DUT reports success for starting both scans 411 * Scan results for each callback contains only the results on the 412 frequency scanned 413 * Wait for at least two scan results and confirm that separation 414 between them approximately equals to the expected interval 415 * Number of BSSIDs doesn't exceed 416 """ 417 scan_settings = [{"band": WifiEnums.WIFI_BAND_24_GHZ, 418 "periodInMs": 10000, # ms 419 "reportEvents": 420 WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, 421 "numBssidsPerScan": 24}, 422 {"band": WifiEnums.WIFI_BAND_5_GHZ, 423 "periodInMs": 10000, # ms 424 "reportEvents": 425 WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, 426 "numBssidsPerScan": 24}] 427 428 self.scan_and_validate_results(scan_settings) 429 430 @test_tracker_info(uuid="0ec9a554-f942-41a9-8096-6b0b400f60b0") 431 @WifiBaseTest.wifi_test_wrap 432 def test_wifi_two_scans_at_different_interval(self): 433 """Perform two WifiScanner background scans, one at 2.4GHz and the other 434 at 5GHz, different interval and number of BSSIDs per scan. 435 436 Initial Conditions: 437 * Set multiple APs broadcasting 2.4GHz and 5GHz. 438 439 Expected Results: 440 * DUT reports success for starting both scans 441 * Scan results for each callback contains only the results on the 442 frequency scanned 443 * Wait for at least two scan results and confirm that separation 444 between them approximately equals to the expected interval 445 * Number of BSSIDs doesn't exceed 446 """ 447 scan_settings = [{"band": WifiEnums.WIFI_BAND_24_GHZ, 448 "periodInMs": 10000, # ms 449 "reportEvents": 450 WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, 451 "numBssidsPerScan": 20}, 452 {"band": WifiEnums.WIFI_BAND_5_GHZ, 453 "periodInMs": 30000, # ms 454 "reportEvents": 455 WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, 456 "numBssidsPerScan": 24}] 457 458 self.scan_and_validate_results(scan_settings) 459 460 @test_tracker_info(uuid="0d616591-0d32-4be6-8fd4-e4a5e9ccdce0") 461 @WifiBaseTest.wifi_test_wrap 462 def test_wifi_scans_24GHz_and_both(self): 463 """Perform two WifiScanner background scans, one at 2.4GHz and 464 the other at both 2.4GHz and 5GHz 465 466 Initial Conditions: 467 * Set multiple APs broadcasting 2.4GHz and 5GHz. 468 469 Expected Results: 470 * DUT reports success for starting both scans 471 * Scan results for each callback contains only the results on the 472 frequency scanned 473 * Wait for at least two scan results and confirm that separation 474 between them approximately equals to the expected interval 475 * Number of BSSIDs doesn't exceed 476 """ 477 scan_settings = [{"band": WifiEnums.WIFI_BAND_BOTH, 478 "periodInMs": 10000, # ms 479 "reportEvents": 480 WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, 481 "numBssidsPerScan": 24}, 482 {"band": WifiEnums.WIFI_BAND_24_GHZ, 483 "periodInMs": 10000, # ms 484 "reportEvents": 485 WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, 486 "numBssidsPerScan": 24}] 487 488 self.scan_and_validate_results(scan_settings) 489 490 @test_tracker_info(uuid="ddcf959e-512a-4e86-b3d3-18cebd0b22a0") 491 @WifiBaseTest.wifi_test_wrap 492 def test_wifi_scans_5GHz_and_both(self): 493 """Perform two WifiScanner scans, one at 5GHz and the other at both 494 2.4GHz and 5GHz 495 496 Initial Conditions: 497 * Set multiple APs broadcasting 2.4GHz and 5GHz. 498 499 Expected Results: 500 * DUT reports success for starting both scans 501 * Scan results for each callback contains only the results on the 502 frequency scanned 503 * Wait for at least two scan results and confirm that separation 504 between them approximately equals to the expected interval 505 * Number of BSSIDs doesn't exceed 506 """ 507 scan_settings = [{"band": WifiEnums.WIFI_BAND_BOTH, 508 "periodInMs": 10000, # ms 509 "reportEvents": 510 WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, 511 "numBssidsPerScan": 24}, 512 {"band": WifiEnums.WIFI_BAND_5_GHZ, 513 "periodInMs": 10000, # ms 514 "reportEvents": 515 WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, 516 "numBssidsPerScan": 24}] 517 518 self.scan_and_validate_results(scan_settings) 519 520 @test_tracker_info(uuid="060469f1-fc6b-4255-ab6e-b1d5b54db53d") 521 @WifiBaseTest.wifi_test_wrap 522 def test_wifi_scans_24GHz_5GHz_and_DFS(self): 523 """Perform three WifiScanner scans, one at 5GHz, one at 2.4GHz and the 524 other at just 5GHz DFS channels 525 526 Initial Conditions: 527 * Set multiple APs broadcasting 2.4GHz and 5GHz. 528 529 Expected Results: 530 * DUT reports success for starting both scans 531 * Scan results for each callback contains only the results on the 532 frequency scanned 533 * Wait for at least two scan results and confirm that separation 534 between them approximately equals to the expected interval 535 * Number of BSSIDs doesn't exceed 536 """ 537 scan_settings = [ 538 {"band": WifiEnums.WIFI_BAND_5_GHZ_DFS_ONLY, 539 "periodInMs": 10000, # ms 540 "reportEvents": WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, 541 "numBssidsPerScan": 24}, 542 {"band": WifiEnums.WIFI_BAND_5_GHZ, 543 "periodInMs": 10000, # ms 544 "reportEvents": WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, 545 "numBssidsPerScan": 24}, 546 {"band": WifiEnums.WIFI_BAND_24_GHZ, 547 "periodInMs": 30000, # ms 548 "reportEvents": WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, 549 "numBssidsPerScan": 24} 550 ] 551 552 self.scan_and_validate_results(scan_settings) 553 554 @test_tracker_info(uuid="14104e98-27a0-43d5-9525-b36b65ac3957") 555 @WifiBaseTest.wifi_test_wrap 556 def test_wifi_scans_batch_and_24GHz(self): 557 """Perform two WifiScanner background scans, one in batch mode for both 558 bands and the other in periodic mode at 2.4GHz 559 560 Initial Conditions: 561 * Set multiple APs broadcasting 2.4GHz and 5GHz. 562 563 Expected Results: 564 * DUT reports success for starting both scans 565 * Scan results for each callback contains only the results on the 566 frequency scanned 567 * Wait for at least two scan results and confirm that separation 568 between them approximately equals to the expected interval 569 * Number of results in batch mode should match the setting 570 * Number of BSSIDs doesn't exceed 571 """ 572 scan_settings = [{"band": WifiEnums.WIFI_BAND_BOTH, 573 "periodInMs": 10000, # ms 574 "reportEvents": 575 WifiEnums.REPORT_EVENT_AFTER_BUFFER_FULL, 576 "numBssidsPerScan": 24, 577 "maxScansToCache": 2}, 578 {"band": WifiEnums.WIFI_BAND_24_GHZ, 579 "periodInMs": 10000, # ms 580 "reportEvents": 581 WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, 582 "numBssidsPerScan": 24}] 583 584 self.scan_and_validate_results(scan_settings) 585 586 @test_tracker_info(uuid="cd6064b5-840b-4334-8cd4-8320a6cda52f") 587 @WifiBaseTest.wifi_test_wrap 588 def test_wifi_scans_batch_and_5GHz(self): 589 """Perform two WifiScanner background scans, one in batch mode for both 590 bands and the other in periodic mode at 5GHz 591 592 Initial Conditions: 593 * Set multiple APs broadcasting 2.4GHz and 5GHz. 594 595 Expected Results: 596 * DUT reports success for starting both scans 597 * Scan results for each callback contains only the results on the 598 frequency scanned 599 * Wait for at least two scan results and confirm that separation 600 between them approximately equals to the expected interval 601 * Number of results in batch mode should match the setting 602 * Number of BSSIDs doesn't exceed 603 """ 604 scan_settings = [{"band": WifiEnums.WIFI_BAND_BOTH, 605 "periodInMs": 10000, # ms 606 "reportEvents": 607 WifiEnums.REPORT_EVENT_AFTER_BUFFER_FULL, 608 "numBssidsPerScan": 24, 609 "maxScansToCache": 2}, 610 {"band": WifiEnums.WIFI_BAND_5_GHZ, 611 "periodInMs": 10000, # ms 612 "reportEvents": 613 WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, 614 "numBssidsPerScan": 24}] 615 616 self.scan_and_validate_results(scan_settings) 617 618 @test_tracker_info(uuid="9f48cb0c-de87-4cd2-9e50-857579d44079") 619 @WifiBaseTest.wifi_test_wrap 620 def test_wifi_scans_24GHz_5GHz_full_result(self): 621 """Perform two WifiScanner background scans, one at 2.4GHz and 622 the other at 5GHz. Report full scan results. 623 624 Initial Conditions: 625 * Set multiple APs broadcasting 2.4GHz and 5GHz. 626 627 Expected Results: 628 * DUT reports success for starting both scans 629 * Scan results for each callback contains only the results on the 630 frequency scanned 631 * Wait for at least two scan results and confirm that separation 632 between them approximately equals to the expected interval 633 * Number of BSSIDs doesn't exceed 634 """ 635 scan_settings = [ 636 {"band": WifiEnums.WIFI_BAND_24_GHZ, 637 "periodInMs": 10000, # ms 638 "reportEvents": WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT 639 | WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, 640 "numBssidsPerScan": 24}, 641 {"band": WifiEnums.WIFI_BAND_5_GHZ, 642 "periodInMs": 10000, # ms 643 "reportEvents": WifiEnums.REPORT_EVENT_FULL_SCAN_RESULT 644 | WifiEnums.REPORT_EVENT_AFTER_EACH_SCAN, 645 "numBssidsPerScan": 24} 646 ] 647 648 self.scan_and_validate_results(scan_settings) 649 650 """ Tests End """ 651