1# Lint as: python2, python3 2# Copyright 2016 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6"""Server side bluetooth tests on adapter ble advertising. 7 8The Mnemonics describing the test cases: 9 CD: check advertising duration and intervals 10 RA: register advertisements 11 UA: unregister advertisements 12 SI: set advertising intervals 13 RS: reset advertising 14 FRA: fail to register extra advertisements when max ones 15 have been registered. 16 FSI: fail to set advertising intervals beyond legitimate range 17 of [20 ms, 10,240 ms]. 18 PC: power cycle the bluetooth adapter (controller). 19 SR: suspend and resume the DUT (chromebook) 20 21A test represents a component of a test case which comprises a 22sequence of tests. A test case usually requires a tester (user) 23to perform a sequence of actions and make a sequence of 24observations if the test case is performed manually. 25 26A test consists of an optional action such as "register n 27advertisements" and a number of test criteria such as "verifying 28if min advertising interval is set to an expected value" or 29"verifying if advertising is disabled". 30 31""" 32 33from __future__ import absolute_import 34from __future__ import division 35from __future__ import print_function 36 37import copy 38import logging 39import re 40import time 41 42import common 43from autotest_lib.server.cros.bluetooth import advertisements_data 44from autotest_lib.server.cros.bluetooth import bluetooth_adapter_tests 45from six.moves import range 46from six.moves import zip 47 48test_case_log = bluetooth_adapter_tests.test_case_log 49test_retry_and_log = bluetooth_adapter_tests.test_retry_and_log 50 51class bluetooth_AdapterLEAdvertising( 52 bluetooth_adapter_tests.BluetoothAdapterTests): 53 """Server side bluetooth adapter advertising Test. 54 55 This class comprises a number of test cases to verify 56 bluetooth low-energy advertising. 57 58 Refer to BluetoothAdapterTests for the implementation of the tests 59 performed in this autotest test. 60 61 Refer to the design doc for more details: 62 "Test Cases for Bluetooth Low-Energy Advertising". 63 64 """ 65 66 # The software advertising rotation is a default bluez parameter, 2 seconds 67 SOFTWARE_ROTATION_INTERVAL_S = 2 68 69 # If hardware offloading is available, a 'default' discovery time is used, 70 # that will not depend on number of advertisements registered since they are 71 # advertised in parallel. 72 DEFAULT_DISCOVERY_TIME_S = 3 73 74 @staticmethod 75 def get_instance_ids(advertisements): 76 """Get the list of instace IDs starting at 1. 77 78 @param advertisements: a list of advertisements. 79 80 """ 81 return list(range(1, len(advertisements) + 1)) 82 83 84 def register_advertisements(self, advertisements, min_adv_interval_ms, 85 max_adv_interval_ms, instance_ids=None): 86 """Register multiple advertisements continuously. 87 88 @param advertisements: a list of advertisement instances. 89 @param min_adv_interval_ms: min_adv_interval in milliseconds. 90 @param max_adv_interval_ms: max_adv_interval in milliseconds. 91 @param instance_ids: the list of instance IDs to register. 92 """ 93 if instance_ids is None: 94 instance_ids = self.get_instance_ids(advertisements) 95 96 for instance_id, advertisement in zip(instance_ids, advertisements): 97 advertisement['MinInterval'] = min_adv_interval_ms 98 advertisement['MaxInterval'] = max_adv_interval_ms 99 100 self.test_register_advertisement(advertisement, instance_id) 101 102 103 def unregister_advertisements(self, advertisements, instance_ids=None): 104 """Register multiple advertisements. 105 106 @param advertisements: a list of advertisement instances. 107 @param instance_ids: the list of instance IDs to unregister. 108 109 """ 110 if instance_ids is None: 111 instance_ids = self.get_instance_ids(advertisements) 112 113 count = 0 114 number_advs = len(advertisements) 115 for instance_id, advertisement in zip(instance_ids, advertisements): 116 # Advertising is only disabled at the removal of the 117 # last advertisement. 118 count += 1 119 advertising_disabled = count == number_advs 120 self.test_unregister_advertisement(advertisement, 121 instance_id, 122 advertising_disabled) 123 124 125 def check_kernel_version(self): 126 """ Check if test can execute on this kernel version.""" 127 128 logging.info("Checking kernel version {}".format(self.kernel_version)) 129 # 130 # Due to crbug/729648, we cannot set advertising intervals 131 # on kernels that are 3.8.11 and below, so we raise TestNAError. 132 # 3.8.12 used so that version of the form 3.8.11<suffix> fails the check 133 # 134 self.is_supported_kernel_version(self.kernel_version, "3.8.12", 135 'Test cannnot proceed on old kernels') 136 # 137 # Due to crbug/946835, some messages does not reach btmon 138 # causing our tests to fails. This is seen on kernel 3.18 and lower. 139 # Remove this check when the issue is fixed 140 # TODO(crbug/946835) 141 # 142 self.is_supported_kernel_version(self.kernel_version, "3.19", 143 'Test cannnot proceed on this' 144 'kernel due to crbug/946835 ') 145 logging.debug("Test is supported on this kernel version") 146 147 148 # --------------------------------------------------------------- 149 # Definitions of all test cases 150 # --------------------------------------------------------------- 151 152 def _get_uuids_from_advertisement(self, adv, type): 153 """Parses Solicit or Service UUIDs from advertising data 154 155 Data to be parsed has the following structure: 156 16-bit Service UUIDs (complete): 2 entries 157 Heart Rate (0x180d) 158 Battery Service (0x180f) 159 160 @param adv: string advertising data as collected by btmon 161 @param type: Type of UUIDs to parse, either 'Solicit' or 'Service' 162 163 @returns: list of UUIDs as ints 164 """ 165 if not adv: 166 return [] 167 168 lines = adv.split('\n') 169 num_uuids = 0 170 # Find Service UUID section in adv and grab number of entries 171 for idx, line in enumerate(lines): 172 if '{} UUIDs (complete)'.format(type) in line: 173 search_res = re.search('(\d) entr', line) 174 if search_res and search_res.group(1): 175 num_uuids = int(search_res.group(1)) 176 break 177 178 found_uuids = [] 179 # Iterate through each entry and collect UUIDs. UUIDs are saved as ints 180 # to reduce complexity of comparing hex strings, i.e. ab vs AB vs 0xab 181 for lineidx in range(idx+1, idx+num_uuids+1): 182 line = lines[lineidx] 183 search_res = re.search('\((.*?)\)', line) 184 if search_res and search_res.group(1): 185 uuid = search_res.group(1) 186 found_uuids.append(int(uuid, 16)) 187 188 return found_uuids 189 190 191 def _get_company_data_from_advertisement(self, adv): 192 """Parses Company ID and associated company data from advertisement 193 194 Data to be parsed has the following structure: 195 Company: not assigned (65281) 196 Data: 1a1b1c1d1e 197 198 @param adv: string advertising data as collected by btmon 199 200 @returns: dictionary with structure {company uuid: company data} 201 """ 202 203 lines = adv.split('\n') 204 205 for idx, line in enumerate(lines): 206 if 'Company:' in line: 207 search_res = re.search('\((.*?)\)', line) 208 if search_res and search_res.group(1): 209 company_id = int(search_res.group(1)) 210 break 211 212 # Company data is on the line after the header, and is the last block 213 # printed 214 if company_id and idx+1 < len(lines): 215 company_data = lines[idx+1].split(' ')[-1] 216 return {company_id: company_data} 217 218 return {} 219 220 221 def _get_service_data_from_advertisement(self, adv): 222 """Parses Service data from advertisement 223 224 Data to be parsed has the following structure: 225 Service Data (UUID 0x9991): 1112131415 226 227 @param adv: string advertising data as collected by btmon 228 229 @returns: dictionary with structure {company uuid: company data} 230 """ 231 232 lines = adv.split('\n') 233 234 discovered_service_data = {} 235 # Iterate through lines in advertisement, grabbing Service Data entries 236 for line in lines: 237 if 'Service Data' in line: 238 search_res = re.search('\(UUID (.*?)\)', line) 239 if search_res and search_res.group(1): 240 found_uuid = search_res.group(1) 241 found_data = line.split(' ')[-1] 242 243 discovered_service_data[int(found_uuid, 16)] = found_data 244 245 return discovered_service_data 246 247 248 def validate_scan_rsp_reception(self, peer, advertisement, discover_time): 249 """Validate our advertisement's scan response is located by the peer 250 251 If our advertisements are configured with scan response data, we wish 252 to confirm that a scanning peer will be able to discover this content. 253 254 @param peer: Handle to peer device for advertisement collection 255 @param advertisement: Advertisement data that has been enabled on DUT 256 side 257 @param discover_time: Number of seconds we should spend discovering 258 before considering the device undiscoverable 259 260 @returns: True if scan response is discovered and is correct, else False 261 """ 262 263 scan_rsp_data = advertisement.get('ScanResponseData', {}) 264 265 # For now, scan response can only contain service data (ad type 0x16): 266 # It appears in a scan response event with the following format: 267 # 'Service Data (UUID 0xfef3): 010203...' 268 if '0x16' in scan_rsp_data: 269 service_uuid_data = scan_rsp_data['0x16'] 270 271 # First two bytes of data make up 16 bit service UUID 272 uuid = service_uuid_data[1] * 256 + service_uuid_data[0] 273 # Subsequent bytes make up the service data 274 service_data = ''.join( 275 ['{:02x}'.format(data) for data in service_uuid_data[2:]]) 276 277 search_str = 'Service Data (UUID 0x{:4x}): {}'.format( 278 uuid, service_data) 279 logging.debug('Searching btmon for content: {}'.format(search_str)) 280 281 # Locate a scan response with the above entry. Pass if it is found 282 start_time = time.time() 283 found_adv = peer.FindAdvertisementWithAttributes( 284 [search_str, 'SCAN_RSP'], discover_time) 285 286 logging.info('Scan response discovered after %fs', 287 time.time() - start_time) 288 289 return bool(found_adv) 290 291 return True 292 293 def _test_peer_received_correct_adv(self, peer, advertisement, 294 discover_time): 295 """Test that configured advertisements are found by peer 296 297 We need to verify quality of advertising service from the perspective of 298 the client, as this is externally visible in cases like Nearby features. 299 This test ensures advertisements are discovered and are correct, 300 helping to confirm quality provided, especially with multi-advertising 301 302 @param peer: Handle to peer device for advertisement collection 303 @param advertisement: Advertisement data that has been enabled on DUT 304 side 305 @param discover_time: Number of seconds we should spend discovering 306 before considering the device undiscoverable 307 308 @returns: True if advertisement is discovered and is correct, else False 309 """ 310 311 self.results = {} 312 313 # We locate the advertisement by searching for the ServiceData 314 # attribute we configured. 315 data_to_match = list(advertisement['ServiceData'].keys())[0] 316 317 start_time = time.time() 318 found_adv = peer.FindAdvertisementWithAttributes([data_to_match], 319 discover_time) 320 logging.info('Advertisement discovered after %fs', 321 time.time() - start_time) 322 323 if not found_adv: 324 self.results['advertisement_found'] = False 325 326 # Check that our service UUIDs match what we expect 327 found_service_uuids = self._get_uuids_from_advertisement( 328 found_adv, 'Service') 329 330 for UUID in advertisement.get('ServiceUUIDs', []): 331 if int(UUID, 16) not in found_service_uuids: 332 logging.info('Service id %d not found in %s', int(UUID, 16), 333 str(found_service_uuids)) 334 self.results['service_ids_found'] = False 335 return False 336 337 # Check that our solicit UUIDs match what we expect 338 found_solicit_uuids = self._get_uuids_from_advertisement( 339 found_adv, 'Solicit') 340 341 for UUID in advertisement.get('SolicitUUIDs', []): 342 if int(UUID, 16) not in found_solicit_uuids: 343 logging.info('Solicid ID %d not found in %s', int(UUID, 16), 344 str(found_solicit_uuids)) 345 self.results['solicit_ids_found'] = False 346 return False 347 348 # Check that our Manufacturer info is correct 349 company_info = self._get_company_data_from_advertisement(found_adv) 350 351 expected_company_info = advertisement.get('ManufacturerData', {}) 352 for UUID in expected_company_info: 353 if int(UUID, 16) not in company_info: 354 logging.info('Company ID %d not found in advertisement', 355 int(UUID, 16)) 356 self.results['manufacturer_uuid_found'] = False 357 return False 358 359 expected_data = expected_company_info.get(UUID, None) 360 formatted_data = ''.join([format(d, 'x') for d in expected_data]) 361 362 if formatted_data != company_info.get(int(UUID, 16)): 363 logging.info('Manufacturer data %s didn\'t match expected %s', 364 company_info.get(int(UUID, 16)), formatted_data) 365 self.results['manufacturer_data_found'] = False 366 return False 367 368 # Check that our service data is correct 369 service_data = self._get_service_data_from_advertisement(found_adv) 370 371 expected_service_data = advertisement.get('ServiceData', {}) 372 for UUID in expected_service_data: 373 if int(UUID, 16) not in service_data: 374 logging.info('Service UUID %d not found in advertisement', 375 int(UUID, 16)) 376 self.results['service_data_uuid_found'] = False 377 return False 378 379 expected_data = expected_service_data.get(UUID, None) 380 formatted_data = ''.join([format(d, 'x') for d in expected_data]) 381 382 if formatted_data != service_data.get(int(UUID, 16)): 383 logging.info('Service data %s didn\'t match expected %s', 384 service_data.get(int(UUID, 16)), formatted_data) 385 self.results['service_data_found'] = False 386 return False 387 388 # Validate scan response from peer's perspective 389 if not self.validate_scan_rsp_reception(peer, advertisement, 390 discover_time): 391 self.results['scan_rsp_found'] = False 392 return False 393 394 return True 395 396 397 def get_host_discovery_time(self, num_adv): 398 """Estimates how long it will take the peer to discover the host 399 400 The amount of time we wait for the peer to discover the host's 401 advertisement depends on how many advertisements are registered, and 402 whether the host platform is using hardware offloaded multi-advertising 403 or software rotation. 404 405 @param num_adv: Number of advertisements that are active 406 @returns: number of seconds we should wait for discovery 407 """ 408 409 if self.ext_adv_enabled(): 410 return self.DEFAULT_DISCOVERY_TIME_S 411 412 return num_adv * self.SOFTWARE_ROTATION_INTERVAL_S 413 414 @test_retry_and_log(False) 415 def test_peer_received_correct_adv(self, peer, advertisement, 416 discover_time): 417 """Tests that advertisement can be received by the peer""" 418 419 return self._test_peer_received_correct_adv(peer, advertisement, 420 discover_time) 421 422 @test_retry_and_log(False, messages_start=False, messages_stop=False) 423 def test_peer_failed_received_correct_adv(self, peer, advertisement, 424 discover_time): 425 """Tests that advertisement can not be received by the peer""" 426 427 return not self._test_peer_received_correct_adv( 428 peer, advertisement, discover_time) 429 430 def advertising_peer_test(self, peer): 431 """Verifies that advertisements registered on DUT are seen by peer 432 433 @param peer: handle to peer used in test 434 """ 435 436 self.kernel_version = self.host.get_kernel_version() 437 self.check_kernel_version() 438 439 self.bluetooth_le_facade = self.bluetooth_facade 440 441 # Register some advertisements 442 num_adv = 3 443 self.test_reset_advertising() 444 445 for i in range(0, num_adv): 446 self.bluetooth_le_facade.register_advertisement( 447 advertisements_data.ADVERTISEMENTS[i]) 448 449 discover_time = self.get_host_discovery_time(num_adv) 450 451 for i in range(0, num_adv): 452 res = self.test_peer_received_correct_adv( 453 peer, advertisements_data.ADVERTISEMENTS[i], discover_time) 454 455 def advertising_peer_suspend_resume_test(self, peer): 456 """Verify expected advertising behavior around suspend/resume 457 458 For power and usage sake, we expect that when the system suspends, any 459 advertising instances should be paused. When we resume from suspend, 460 they should be re-enabled again. To confirm this behavior, the test 461 performs the following steps: 462 463 - Register some advertisements 464 - Verify that advertisements are discoverable by remote device 465 - Enter suspend 466 - Verify that advertisements are NOT discoverable by remote device 467 - Exit suspend 468 - Verify that advertisements are discoverable by remote device 469 470 @param peer: handle to peer used in test 471 """ 472 473 self.kernel_version = self.host.get_kernel_version() 474 self.check_kernel_version() 475 476 self.bluetooth_le_facade = self.bluetooth_facade 477 478 # Register some advertisements 479 num_adv = 3 480 discover_time = self.get_host_discovery_time(num_adv) 481 self.test_reset_advertising() 482 483 for i in range(0, num_adv): 484 self.bluetooth_le_facade.register_advertisement( 485 advertisements_data.ADVERTISEMENTS[i]) 486 487 # Verify they can all be discovered 488 for i in range(0, num_adv): 489 res = self.test_peer_received_correct_adv( 490 peer, advertisements_data.ADVERTISEMENTS[i], discover_time) 491 492 # Enter suspend long enough to verify none of the registered 493 # advertisements are discoverable. Give a few extra seconds in suspend 494 # to be safe 495 suspend_time = discover_time * num_adv + 10 496 logging.debug( 497 'suspend_time(%d) = discover_time(%d) * num_adv(%d) + 10', 498 suspend_time, discover_time, num_adv) 499 500 # Trigger suspend, asynchronously trigger wake and wait for resume 501 boot_id = self.host.get_boot_id() 502 suspend = self.suspend_async(suspend_time=suspend_time) 503 start_time = self.bluetooth_facade.get_device_utc_time() 504 self.test_suspend_and_wait_for_sleep(suspend, sleep_timeout=5) 505 506 # Verify they can not be discovered 507 for i in range(0, num_adv): 508 res = self.test_peer_failed_received_correct_adv( 509 peer, advertisements_data.ADVERTISEMENTS[i], discover_time) 510 511 # Wait for device to come out of suspend 512 logging.debug('test_wait_for_resume(resume_timeout=%d, start_time=%s)', 513 suspend_time, start_time) 514 self.test_wait_for_resume(boot_id, 515 suspend, 516 resume_timeout=suspend_time, 517 test_start_time=start_time) 518 519 # Verify reception of advertisements again 520 for i in range(0, num_adv): 521 res = self.test_peer_received_correct_adv( 522 peer, advertisements_data.ADVERTISEMENTS[i], discover_time) 523 524 525 @test_case_log 526 def test_case_SI200_RA3_CD_UA3(self): 527 """Test Case: SI(200) - RA(3) - CD - UA(3)""" 528 new_min_adv_interval_ms = 200 529 new_max_adv_interval_ms = 200 530 advertisements = self.three_advertisements 531 532 self.test_reset_advertising() 533 534 self.register_advertisements(advertisements, new_min_adv_interval_ms, 535 new_max_adv_interval_ms) 536 537 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 538 new_max_adv_interval_ms, 539 len(advertisements)) 540 541 self.unregister_advertisements(advertisements) 542 543 544 @test_case_log 545 def test_case_SI200_RA3_CD_RA1_CD_UA1_CD_UA3(self): 546 """Test Case: SI(200) - RA(3) - CD - RA(1) - CD - UA(1) - CD - UA(3)""" 547 new_min_adv_interval_ms = 200 548 new_max_adv_interval_ms = 200 549 # Make a copy of advertisements since we are going to modify it. 550 advertisements = copy.copy(self.three_advertisements) 551 number_advs = len(advertisements) 552 one_more_advertisement = [self.sixth_advertisement] 553 554 self.test_reset_advertising() 555 556 self.register_advertisements(advertisements, new_min_adv_interval_ms, 557 new_max_adv_interval_ms) 558 559 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 560 new_max_adv_interval_ms, 561 number_advs) 562 563 # Register one more advertisement. 564 # The instance ID to register is len(advertisements) + 1 = 4 565 self.register_advertisements(one_more_advertisement, 566 new_min_adv_interval_ms, 567 new_max_adv_interval_ms, 568 instance_ids=[number_advs + 1]) 569 570 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 571 new_max_adv_interval_ms, 572 number_advs + 1) 573 574 # Unregister the 3rd advertisement. 575 # After removing the advertisement, the remaining instance IDs 576 # would be [1, 2, 4] 577 instance_id = 3 578 self.test_unregister_advertisement(advertisements.pop(instance_id - 1), 579 instance_id, 580 advertising_disabled=False) 581 582 if not self.ext_adv_enabled(): 583 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 584 new_max_adv_interval_ms, 585 number_advs) 586 587 # Unregister all existing advertisements which are [1, 2, 4] 588 # since adv 3 was removed in the previous step. 589 self.unregister_advertisements(advertisements + one_more_advertisement, 590 instance_ids=[1, 2, 4]) 591 592 593 @test_case_log 594 def test_case_SI200_RA3_CD_RS(self): 595 """Test Case: SI(200) - RA(3) - CD - RS""" 596 new_min_adv_interval_ms = 200 597 new_max_adv_interval_ms = 200 598 advertisements = self.three_advertisements 599 number_advs = len(advertisements) 600 601 self.test_reset_advertising() 602 603 self.register_advertisements(advertisements, new_min_adv_interval_ms, 604 new_max_adv_interval_ms) 605 606 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 607 new_max_adv_interval_ms, 608 number_advs) 609 610 self.test_reset_advertising(self.get_instance_ids(advertisements)) 611 612 613 @test_case_log 614 def test_case_SI200_RA3_CD_UA1_CD_RS(self): 615 """Test Case: SI(200) - RA(3) - CD - UA(1) - CD - RS""" 616 new_min_adv_interval_ms = 200 617 new_max_adv_interval_ms = 200 618 # Make a copy of advertisements since we are going to modify it. 619 advertisements = copy.copy(self.three_advertisements) 620 621 self.test_reset_advertising() 622 623 self.register_advertisements(advertisements, new_min_adv_interval_ms, 624 new_max_adv_interval_ms) 625 626 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 627 new_max_adv_interval_ms, 628 len(advertisements)) 629 630 # Unregister the 1st advertisement. 631 # After removing the advertisement, the remaining instance IDs 632 # would be [2, 3] 633 instance_id = 1 634 self.test_unregister_advertisement(advertisements.pop(instance_id - 1), 635 instance_id, 636 advertising_disabled=False) 637 638 if not self.ext_adv_enabled(): 639 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 640 new_max_adv_interval_ms, 641 len(advertisements) - 1) 642 643 self.test_reset_advertising([2, 3]) 644 645 646 @test_case_log 647 def test_case_SI200_RA3_CD_UA1_CD_RA2_CD_UA4(self): 648 """Test Case: SI(200) - RA(3) - CD - UA(1) - CD - RA(2) - CD - UA(4)""" 649 new_min_adv_interval_ms = 200 650 new_max_adv_interval_ms = 200 651 # Make a copy of three_advertisements since we are going to modify it. 652 advertisements1 = copy.copy(self.three_advertisements) 653 advertisements2 = self.two_advertisements 654 number_advs1 = len(advertisements1) 655 number_advs2 = len(advertisements2) 656 657 self.test_reset_advertising() 658 659 self.register_advertisements(advertisements1, new_min_adv_interval_ms, 660 new_max_adv_interval_ms) 661 662 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 663 new_max_adv_interval_ms, 664 number_advs1) 665 666 # Unregister the 2nd advertisement. 667 # After removing the 2nd advertisement, the remaining instance IDs 668 # would be [1, 3] 669 instance_id = 2 670 self.test_unregister_advertisement(advertisements1.pop(instance_id - 1), 671 instance_id, 672 advertising_disabled=False) 673 674 if not self.ext_adv_enabled(): 675 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 676 new_max_adv_interval_ms, 677 number_advs1 - 1) 678 679 # Register two more advertisements. 680 # The instance IDs to register would be [2, 4] 681 self.register_advertisements(advertisements2, new_min_adv_interval_ms, 682 new_max_adv_interval_ms, 683 instance_ids=[2, 4]) 684 685 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 686 new_max_adv_interval_ms, 687 number_advs1 + number_advs2 - 1) 688 689 # Unregister all advertisements. 690 # The instance_ids of advertisements1 is [1, 3]. 691 # The instance_ids of advertisements2 is [2, 4]. 692 self.unregister_advertisements(advertisements1 + advertisements2, 693 instance_ids=[1, 3, 2, 4]) 694 695 696 @test_case_log 697 def test_case_SI200_RA5_CD_FRA1_CD_UA5(self): 698 """Test Case: SI(200) - RA(5) - CD - FRA(1) - CD - UA(5)""" 699 new_min_adv_interval_ms = 200 700 new_max_adv_interval_ms = 200 701 advertisements = self.five_advertisements 702 extra_advertisement = self.sixth_advertisement 703 number_advs = len(advertisements) 704 705 self.test_reset_advertising() 706 707 self.register_advertisements(advertisements, new_min_adv_interval_ms, 708 new_max_adv_interval_ms) 709 710 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 711 new_max_adv_interval_ms, 712 number_advs) 713 714 self.test_fail_to_register_advertisement(extra_advertisement, 715 new_min_adv_interval_ms, 716 new_max_adv_interval_ms) 717 718 # If the registration fails and extended advertising is available, 719 # there will be no events in btmon. Therefore, we only run this part of 720 # the test if extended advertising is not available, indicating that 721 # software advertisement rotation is being used. 722 if not self.ext_adv_enabled(): 723 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 724 new_max_adv_interval_ms, 725 number_advs) 726 727 self.unregister_advertisements(advertisements) 728 729 730 @test_case_log 731 def test_case_SI200_RA3_CD_PC_CD_UA3(self): 732 """Test Case: SI(200) - RA(3) - CD - PC - CD - UA(3)""" 733 new_min_adv_interval_ms = 200 734 new_max_adv_interval_ms = 200 735 advertisements = self.three_advertisements 736 737 self.test_reset_advertising() 738 739 self.register_advertisements(advertisements, new_min_adv_interval_ms, 740 new_max_adv_interval_ms) 741 742 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 743 new_max_adv_interval_ms, 744 len(advertisements)) 745 746 # Turn off and then turn on the adapter. 747 self.test_power_off_adapter() 748 time.sleep(1) 749 self.test_power_on_adapter() 750 751 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 752 new_max_adv_interval_ms, 753 len(advertisements)) 754 755 self.unregister_advertisements(advertisements) 756 757 758 @test_case_log 759 def test_case_SI200_RA3_CD_SR_CD_UA3(self): 760 """Test Case: SI(200) - RA(3) - CD - SR - CD - UA(3)""" 761 new_min_adv_interval_ms = 200 762 new_max_adv_interval_ms = 200 763 advertisements = self.three_advertisements 764 765 self.test_reset_advertising() 766 767 self.register_advertisements(advertisements, new_min_adv_interval_ms, 768 new_max_adv_interval_ms) 769 770 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 771 new_max_adv_interval_ms, 772 len(advertisements)) 773 774 # Suspend for a while and resume. 775 self.suspend_resume() 776 777 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 778 new_max_adv_interval_ms, 779 len(advertisements)) 780 781 self.unregister_advertisements(advertisements) 782 783 784 @test_case_log 785 def test_case_RA3_CD_SI200_CD_UA3(self): 786 """Test Case: RA(3) - CD - SI(200) - CD - UA(3)""" 787 orig_min_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 788 orig_max_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 789 new_min_adv_interval_ms = 200 790 new_max_adv_interval_ms = 200 791 advertisements = self.three_advertisements 792 number_advs = len(advertisements) 793 794 self.test_reset_advertising() 795 796 self.register_advertisements(advertisements, orig_min_adv_interval_ms, 797 orig_max_adv_interval_ms) 798 799 self.test_check_duration_and_intervals(orig_min_adv_interval_ms, 800 orig_max_adv_interval_ms, 801 number_advs) 802 803 self.unregister_advertisements(advertisements) 804 self.register_advertisements(advertisements, new_min_adv_interval_ms, 805 new_max_adv_interval_ms) 806 807 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 808 new_max_adv_interval_ms, 809 number_advs) 810 811 self.unregister_advertisements(advertisements) 812 813 814 @test_case_log 815 def test_case_RA3_CD_SI200_CD_RS(self): 816 """Test Case: RA(3) - CD - SI(200) - CD - RS""" 817 orig_min_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 818 orig_max_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 819 new_min_adv_interval_ms = 200 820 new_max_adv_interval_ms = 200 821 advertisements = self.three_advertisements 822 number_advs = len(advertisements) 823 824 self.test_reset_advertising() 825 826 self.register_advertisements(advertisements, orig_min_adv_interval_ms, 827 orig_max_adv_interval_ms) 828 829 self.test_check_duration_and_intervals(orig_min_adv_interval_ms, 830 orig_max_adv_interval_ms, 831 number_advs) 832 833 self.unregister_advertisements(advertisements) 834 self.register_advertisements(advertisements, new_min_adv_interval_ms, 835 new_max_adv_interval_ms) 836 837 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 838 new_max_adv_interval_ms, 839 number_advs) 840 841 self.test_reset_advertising(self.get_instance_ids(advertisements)) 842 843 844 845 @test_case_log 846 def test_case_RA3_CD_SI200_CD_UA1_CD_RS(self): 847 """Test Case: RA(3) - CD - SI(200) - CD - UA(1) - CD - RS""" 848 orig_min_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 849 orig_max_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 850 new_min_adv_interval_ms = 200 851 new_max_adv_interval_ms = 200 852 advertisements = self.three_advertisements 853 number_advs = len(advertisements) 854 855 self.test_reset_advertising() 856 857 self.register_advertisements(advertisements, orig_min_adv_interval_ms, 858 orig_max_adv_interval_ms) 859 860 self.test_check_duration_and_intervals(orig_min_adv_interval_ms, 861 orig_max_adv_interval_ms, 862 number_advs) 863 864 self.unregister_advertisements(advertisements) 865 self.register_advertisements(advertisements, new_min_adv_interval_ms, 866 new_max_adv_interval_ms) 867 868 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 869 new_max_adv_interval_ms, 870 number_advs) 871 872 # Unregister the 2nd advertisement. 873 instance_id = 2 874 self.test_unregister_advertisement(advertisements[instance_id - 1], 875 instance_id, 876 advertising_disabled=False) 877 878 if not self.ext_adv_enabled(): 879 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 880 new_max_adv_interval_ms, 881 number_advs - 1) 882 883 # Test if advertising is reset correctly.Only instances [1, 3] are left. 884 self.test_reset_advertising([1, 3]) 885 886 887 @test_case_log 888 def test_case_RA3_CD_SI200_CD_SI2000_CD_UA3(self): 889 """Test Case: RA(3) - CD - SI(200) - CD - SI(2000) - CD - UA(3)""" 890 orig_min_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 891 orig_max_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 892 new_small_min_adv_interval_ms = 200 893 new_small_max_adv_interval_ms = 200 894 new_large_min_adv_interval_ms = 2000 895 new_large_max_adv_interval_ms = 2000 896 advertisements = self.three_advertisements 897 number_advs = len(advertisements) 898 899 self.test_reset_advertising() 900 901 self.register_advertisements(advertisements, orig_min_adv_interval_ms, 902 orig_max_adv_interval_ms) 903 904 self.test_check_duration_and_intervals(orig_min_adv_interval_ms, 905 orig_max_adv_interval_ms, 906 number_advs) 907 908 self.unregister_advertisements(advertisements) 909 self.register_advertisements(advertisements, 910 new_small_min_adv_interval_ms, 911 new_small_max_adv_interval_ms) 912 913 self.test_check_duration_and_intervals(new_small_min_adv_interval_ms, 914 new_small_max_adv_interval_ms, 915 number_advs) 916 917 self.unregister_advertisements(advertisements) 918 self.register_advertisements(advertisements, 919 new_large_min_adv_interval_ms, 920 new_large_max_adv_interval_ms) 921 922 self.test_check_duration_and_intervals(new_large_min_adv_interval_ms, 923 new_large_max_adv_interval_ms, 924 number_advs) 925 926 self.unregister_advertisements(advertisements) 927 928 929 @test_case_log 930 def test_case_RA5_CD_SI200_CD_FRA1_CD_UA5(self): 931 """Test Case: RA(5) - CD - SI(200) - CD - FRA(1) - CD - UA(5)""" 932 orig_min_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 933 orig_max_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 934 new_min_adv_interval_ms = 200 935 new_max_adv_interval_ms = 200 936 advertisements = self.five_advertisements 937 extra_advertisement = self.sixth_advertisement 938 number_advs = len(advertisements) 939 940 self.test_reset_advertising() 941 942 self.register_advertisements(advertisements, orig_min_adv_interval_ms, 943 orig_max_adv_interval_ms) 944 945 self.test_check_duration_and_intervals(orig_min_adv_interval_ms, 946 orig_max_adv_interval_ms, 947 number_advs) 948 949 self.unregister_advertisements(advertisements) 950 self.register_advertisements(advertisements, new_min_adv_interval_ms, 951 new_max_adv_interval_ms) 952 953 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 954 new_max_adv_interval_ms, 955 number_advs) 956 957 self.test_fail_to_register_advertisement(extra_advertisement, 958 new_min_adv_interval_ms, 959 new_max_adv_interval_ms) 960 961 # If the registration fails and extended advertising is available, 962 # there will be no events in btmon. Therefore, we only run this part of 963 # the test if extended advertising is not available, indicating that 964 # software advertisement rotation is being used. 965 if not self.ext_adv_enabled(): 966 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 967 new_max_adv_interval_ms, 968 number_advs) 969 970 self.unregister_advertisements(advertisements) 971 972 973 @test_case_log 974 def test_case_RA3_CD_SI200_CD_FSI10_CD_FSI20000_CD_UA3(self): 975 """Test Case: RA(3) - CD - SI(200) - CD - FSI(10) - CD - FSI(20000) - CD 976 - UA(3) 977 """ 978 orig_min_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 979 orig_max_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 980 new_min_adv_interval_ms = 200 981 new_max_adv_interval_ms = 200 982 invalid_small_min_adv_interval_ms = 10 983 invalid_small_max_adv_interval_ms = 10 984 invalid_large_min_adv_interval_ms = 20000 985 invalid_large_max_adv_interval_ms = 20000 986 advertisements = self.three_advertisements 987 number_advs = len(advertisements) 988 989 self.test_reset_advertising() 990 991 self.register_advertisements(advertisements, orig_min_adv_interval_ms, 992 orig_max_adv_interval_ms) 993 994 self.test_check_duration_and_intervals(orig_min_adv_interval_ms, 995 orig_max_adv_interval_ms, 996 number_advs) 997 998 self.unregister_advertisements(advertisements) 999 self.register_advertisements(advertisements, new_min_adv_interval_ms, 1000 new_max_adv_interval_ms) 1001 1002 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1003 new_max_adv_interval_ms, 1004 number_advs) 1005 1006 # Fails to set intervals that are too small. Intervals remain the same. 1007 self.test_fail_to_set_advertising_intervals( 1008 invalid_small_min_adv_interval_ms, 1009 invalid_small_max_adv_interval_ms, 1010 new_min_adv_interval_ms, new_max_adv_interval_ms) 1011 1012 if not self.ext_adv_enabled(): 1013 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1014 new_max_adv_interval_ms, 1015 number_advs) 1016 1017 # Fails to set intervals that are too large. Intervals remain the same. 1018 self.test_fail_to_set_advertising_intervals( 1019 invalid_large_min_adv_interval_ms, 1020 invalid_large_max_adv_interval_ms, 1021 new_min_adv_interval_ms, new_max_adv_interval_ms) 1022 1023 if not self.ext_adv_enabled(): 1024 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1025 new_max_adv_interval_ms, 1026 number_advs) 1027 1028 # Unregister all advertisements. 1029 self.unregister_advertisements(advertisements) 1030 1031 1032 @test_case_log 1033 def test_case_RA3_CD_SI200_CD_PC_CD_UA3(self): 1034 """Test Case: RA(3) - CD - SI(200) - CD - PC - CD - UA(3)""" 1035 orig_min_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1036 orig_max_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1037 new_min_adv_interval_ms = 200 1038 new_max_adv_interval_ms = 200 1039 advertisements = self.three_advertisements 1040 number_advs = len(advertisements) 1041 1042 self.test_reset_advertising() 1043 1044 self.register_advertisements(advertisements, orig_min_adv_interval_ms, 1045 orig_max_adv_interval_ms) 1046 1047 self.test_check_duration_and_intervals(orig_min_adv_interval_ms, 1048 orig_max_adv_interval_ms, 1049 number_advs) 1050 1051 self.unregister_advertisements(advertisements) 1052 self.register_advertisements(advertisements, new_min_adv_interval_ms, 1053 new_max_adv_interval_ms) 1054 1055 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1056 new_max_adv_interval_ms, 1057 number_advs) 1058 1059 # Turn off and then turn on the adapter. 1060 self.test_power_off_adapter() 1061 time.sleep(1) 1062 self.test_power_on_adapter() 1063 1064 # Check if the advertising durations remain the same after resume. 1065 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1066 new_max_adv_interval_ms, 1067 number_advs) 1068 1069 # Unregister all advertisements. 1070 self.unregister_advertisements(advertisements) 1071 1072 1073 @test_case_log 1074 def test_case_RA3_CD_SI200_CD_SR_CD_UA3(self): 1075 """Test Case: RA(3) - CD - SI(200) - CD - SR - CD - UA(3)""" 1076 orig_min_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1077 orig_max_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1078 new_min_adv_interval_ms = 200 1079 new_max_adv_interval_ms = 200 1080 advertisements = self.three_advertisements 1081 number_advs = len(advertisements) 1082 1083 self.test_reset_advertising() 1084 1085 self.register_advertisements(advertisements, orig_min_adv_interval_ms, 1086 orig_max_adv_interval_ms) 1087 1088 self.test_check_duration_and_intervals(orig_min_adv_interval_ms, 1089 orig_max_adv_interval_ms, 1090 number_advs) 1091 1092 self.unregister_advertisements(advertisements) 1093 self.register_advertisements(advertisements, new_min_adv_interval_ms, 1094 new_max_adv_interval_ms) 1095 1096 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1097 new_max_adv_interval_ms, 1098 number_advs) 1099 1100 # Suspend for a while and resume. 1101 self.suspend_resume() 1102 1103 # Check if the advertising durations remain the same after resume. 1104 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1105 new_max_adv_interval_ms, 1106 number_advs) 1107 1108 # Unregister all advertisements. 1109 self.unregister_advertisements(advertisements) 1110 1111 # SINGLE TEST CASES 1112 @test_case_log 1113 def test_case_SI200_RA1_CD_UA1(self): 1114 """Test Case: SI(200) - RA(1) - CD - UA(1)""" 1115 new_min_adv_interval_ms = 200 1116 new_max_adv_interval_ms = 200 1117 advertisements = [self.sixth_advertisement] 1118 1119 self.test_reset_advertising() 1120 1121 self.register_advertisements(advertisements, new_min_adv_interval_ms, 1122 new_max_adv_interval_ms) 1123 1124 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1125 new_max_adv_interval_ms, 1126 len(advertisements)) 1127 1128 self.unregister_advertisements(advertisements) 1129 1130 1131 @test_case_log 1132 def test_case_SI200_RA1_CD_RS(self): 1133 """Test Case: SI(200) - RA(1) - CD - RS""" 1134 new_min_adv_interval_ms = 200 1135 new_max_adv_interval_ms = 200 1136 advertisements = [self.first_advertisement] 1137 1138 self.test_reset_advertising() 1139 1140 self.register_advertisements(advertisements, new_min_adv_interval_ms, 1141 new_max_adv_interval_ms) 1142 1143 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1144 new_max_adv_interval_ms, 1145 len(advertisements)) 1146 1147 self.test_reset_advertising() 1148 1149 1150 @test_case_log 1151 def test_case_SI200_RA1_CD_SR_CD_UA1(self): 1152 """Test Case: SI(200) - RA(1) - CD - SR - CD - UA(1)""" 1153 new_min_adv_interval_ms = 200 1154 new_max_adv_interval_ms = 200 1155 advertisements = [self.sixth_advertisement] 1156 1157 self.test_reset_advertising() 1158 1159 self.register_advertisements(advertisements, new_min_adv_interval_ms, 1160 new_max_adv_interval_ms) 1161 1162 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1163 new_max_adv_interval_ms, 1164 len(advertisements)) 1165 1166 self.suspend_resume() 1167 1168 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1169 new_max_adv_interval_ms, 1170 len(advertisements)) 1171 1172 self.unregister_advertisements(advertisements) 1173 1174 1175 @test_case_log 1176 def test_case_RA1_CD_SI200_CD_UA1(self): 1177 """Test Case: RA(1) - CD - SI(200) - CD - UA(1)""" 1178 orig_min_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1179 orig_max_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1180 new_min_adv_interval_ms = 200 1181 new_max_adv_interval_ms = 200 1182 advertisements = [self.first_advertisement] 1183 1184 self.test_reset_advertising() 1185 1186 self.register_advertisements(advertisements, orig_min_adv_interval_ms, 1187 orig_max_adv_interval_ms) 1188 1189 self.test_check_duration_and_intervals(orig_min_adv_interval_ms, 1190 orig_max_adv_interval_ms, 1191 len(advertisements)) 1192 1193 self.unregister_advertisements(advertisements) 1194 self.register_advertisements(advertisements, new_min_adv_interval_ms, 1195 new_max_adv_interval_ms) 1196 1197 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1198 new_max_adv_interval_ms, 1199 len(advertisements)) 1200 1201 self.unregister_advertisements(advertisements) 1202 1203 1204 @test_case_log 1205 def test_case_RA1_CD_SI200_CD_RS(self): 1206 """Test Case: RA(1) - CD - SI(200) - CD - RS""" 1207 orig_min_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1208 orig_max_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1209 new_min_adv_interval_ms = 200 1210 new_max_adv_interval_ms = 200 1211 advertisements = [self.sixth_advertisement] 1212 self.test_reset_advertising() 1213 1214 self.register_advertisements(advertisements, orig_min_adv_interval_ms, 1215 orig_max_adv_interval_ms) 1216 1217 self.test_check_duration_and_intervals(orig_min_adv_interval_ms, 1218 orig_max_adv_interval_ms, 1219 len(advertisements)) 1220 1221 self.unregister_advertisements(advertisements) 1222 self.register_advertisements(advertisements, new_min_adv_interval_ms, 1223 new_max_adv_interval_ms) 1224 1225 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1226 new_max_adv_interval_ms, 1227 len(advertisements)) 1228 self.test_reset_advertising() 1229 1230 1231 @test_case_log 1232 def test_case_RA1_CD_SI200_CD_FSI10_UA1_RA1_CD_UA1(self): 1233 """Test Case: RA(1) - CD - SI(200) - CD - FSI(10) - UA(1) 1234 - RA(1) - CD - UA(1)""" 1235 orig_min_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1236 orig_max_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1237 new_min_adv_interval_ms = 200 1238 new_max_adv_interval_ms = 200 1239 invalid_small_min_adv_interval_ms = 10 1240 invalid_small_max_adv_interval_ms = 10 1241 advertisements = [self.three_advertisements[1]] 1242 new_advertisement = [self.three_advertisements[2]] 1243 1244 self.test_reset_advertising() 1245 1246 self.register_advertisements(advertisements, orig_min_adv_interval_ms, 1247 orig_max_adv_interval_ms) 1248 1249 self.test_check_duration_and_intervals(orig_min_adv_interval_ms, 1250 orig_max_adv_interval_ms, 1251 len(advertisements)) 1252 1253 self.unregister_advertisements(advertisements) 1254 self.register_advertisements(advertisements, new_min_adv_interval_ms, 1255 new_max_adv_interval_ms) 1256 1257 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1258 new_max_adv_interval_ms, 1259 len(advertisements)) 1260 1261 # Fails to set intervals that are too small. Intervals remain the same. 1262 self.test_fail_to_set_advertising_intervals( 1263 invalid_small_min_adv_interval_ms, 1264 invalid_small_max_adv_interval_ms, 1265 new_min_adv_interval_ms, new_max_adv_interval_ms) 1266 1267 self.unregister_advertisements(advertisements) 1268 1269 # Register a new advertisement in order to avoid kernel caching. 1270 self.register_advertisements(new_advertisement, new_min_adv_interval_ms, 1271 new_max_adv_interval_ms) 1272 1273 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1274 new_max_adv_interval_ms, 1275 len(advertisements)) 1276 1277 self.unregister_advertisements(new_advertisement) 1278 1279 1280 @test_case_log 1281 def test_case_RA1_CD_SI200_CD_FSI20000_UA1_RA1_CD_UA1(self): 1282 """Test Case: RA(1) - CD - SI(200) - CD - FSI(20000) - UA(1) 1283 - RA(1) - CD - UA(1)""" 1284 orig_min_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1285 orig_max_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1286 new_min_adv_interval_ms = 200 1287 new_max_adv_interval_ms = 200 1288 invalid_large_min_adv_interval_ms = 20000 1289 invalid_large_max_adv_interval_ms = 20000 1290 advertisements = [self.three_advertisements[1]] 1291 new_advertisement = [self.three_advertisements[2]] 1292 1293 self.test_reset_advertising() 1294 1295 self.register_advertisements(advertisements, orig_min_adv_interval_ms, 1296 orig_max_adv_interval_ms) 1297 1298 self.test_check_duration_and_intervals(orig_min_adv_interval_ms, 1299 orig_max_adv_interval_ms, 1300 len(advertisements)) 1301 1302 self.unregister_advertisements(advertisements) 1303 self.register_advertisements(advertisements, new_min_adv_interval_ms, 1304 new_max_adv_interval_ms) 1305 1306 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1307 new_max_adv_interval_ms, 1308 len(advertisements)) 1309 # Fails to set intervals that are too large. Intervals remain the same. 1310 self.test_fail_to_set_advertising_intervals( 1311 invalid_large_min_adv_interval_ms, 1312 invalid_large_max_adv_interval_ms, 1313 new_min_adv_interval_ms, new_max_adv_interval_ms) 1314 1315 self.unregister_advertisements(advertisements) 1316 1317 # Register a new advertisement in order to avoid kernel caching. 1318 self.register_advertisements(new_advertisement, new_min_adv_interval_ms, 1319 new_max_adv_interval_ms) 1320 1321 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1322 new_max_adv_interval_ms, 1323 len(advertisements)) 1324 1325 self.unregister_advertisements(new_advertisement) 1326 1327 1328 @test_case_log 1329 def test_case_RA1_CD_SI200_CD_PC_CD_UA1(self): 1330 """Test Case: RA(1) - CD - SI(200) - CD - PC - CD - UA(1)""" 1331 orig_min_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1332 orig_max_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1333 new_min_adv_interval_ms = 200 1334 new_max_adv_interval_ms = 200 1335 advertisements = [self.sixth_advertisement] 1336 self.test_reset_advertising() 1337 1338 self.register_advertisements(advertisements, orig_min_adv_interval_ms, 1339 orig_max_adv_interval_ms) 1340 1341 self.test_check_duration_and_intervals(orig_min_adv_interval_ms, 1342 orig_max_adv_interval_ms, 1343 len(advertisements)) 1344 1345 self.unregister_advertisements(advertisements) 1346 self.register_advertisements(advertisements, new_min_adv_interval_ms, 1347 new_max_adv_interval_ms) 1348 1349 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1350 new_max_adv_interval_ms, 1351 len(advertisements)) 1352 1353 # Turn off and then turn on the adapter. 1354 self.test_power_off_adapter() 1355 time.sleep(1) 1356 self.test_power_on_adapter() 1357 1358 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1359 new_max_adv_interval_ms, 1360 len(advertisements)) 1361 1362 self.unregister_advertisements(advertisements) 1363 1364 1365 @test_case_log 1366 def test_case_RA1_CD_SI200_CD_SR_CD_UA1(self): 1367 """Test Case: RA(1) - CD - SI(200) - CD - SR - CD - UA(1)""" 1368 orig_min_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1369 orig_max_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1370 new_min_adv_interval_ms = 200 1371 new_max_adv_interval_ms = 200 1372 advertisements = [self.first_advertisement] 1373 self.test_reset_advertising() 1374 1375 self.register_advertisements(advertisements, orig_min_adv_interval_ms, 1376 orig_max_adv_interval_ms) 1377 1378 self.test_check_duration_and_intervals(orig_min_adv_interval_ms, 1379 orig_max_adv_interval_ms, 1380 len(advertisements)) 1381 1382 self.unregister_advertisements(advertisements) 1383 self.register_advertisements(advertisements, new_min_adv_interval_ms, 1384 new_max_adv_interval_ms) 1385 1386 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1387 new_max_adv_interval_ms, 1388 len(advertisements)) 1389 1390 self.suspend_resume() 1391 1392 self.test_check_duration_and_intervals(new_min_adv_interval_ms, 1393 new_max_adv_interval_ms, 1394 len(advertisements)) 1395 1396 self.unregister_advertisements(advertisements) 1397 1398 @test_case_log 1399 def test_case_nearby_mediums_fast(self): 1400 """Verify minimal test case for nearby sharing""" 1401 orig_min_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1402 orig_max_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1403 1404 # We set a specific advertisement with fields required by Nearby 1405 # sharing service 1406 advertisements = [advertisements_data.NEARBY_MEDIUMS_FAST_ADV] 1407 1408 self.test_reset_advertising() 1409 1410 # Nearby share requires general discoverable advertising flag be set. 1411 # Bluez sets this flag based on the adapter's Discoverable property, 1412 # so we apply this setting here 1413 self.bluetooth_facade.set_discoverable(True) 1414 1415 self.register_advertisements(advertisements, orig_min_adv_interval_ms, 1416 orig_max_adv_interval_ms) 1417 1418 # Ensure that our discoverable flag is advertised 1419 self.test_advertising_flags(['Advertise as Discoverable']) 1420 1421 @test_case_log 1422 def test_case_adv_before_scan(self): 1423 """Verify we can scan after advertising starts 1424 1425 We found that when extended advertising is available, any Set Adv 1426 Disable HCI command would mark the hdev as not advertising, even if 1427 other instances were active at the time. Later attempts to start 1428 discovery would fail, because kernel tries to update the random address 1429 without knowing to pause the advertisements. This test case replicates 1430 this failure condition to validate the fix. 1431 """ 1432 orig_min_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1433 orig_max_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1434 advertisements = self.three_advertisements 1435 1436 self.test_reset_advertising() 1437 1438 # Register several advertisements 1439 self.register_advertisements(advertisements, orig_min_adv_interval_ms, 1440 orig_max_adv_interval_ms) 1441 1442 # Unregister one active advertisement. 1443 instance_id = 2 1444 self.test_unregister_advertisement(advertisements[instance_id - 1], 1445 instance_id, 1446 advertising_disabled=False) 1447 1448 self.test_start_discovery() 1449 1450 # Test if advertising is reset correctly.Only instances [1, 3] are left. 1451 self.test_reset_advertising([1, 3]) 1452 1453 @test_case_log 1454 def test_case_broadcast(self): 1455 """Verify minimal test case for broadcasted advertising""" 1456 orig_min_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1457 orig_max_adv_interval_ms = self.DEFAULT_MIN_ADVERTISEMENT_INTERVAL_MS 1458 1459 # We set a specific advertisement that uses the 'broadcast' mode 1460 advertisements = [advertisements_data.NEARBY_BROADCAST_ADV] 1461 1462 self.test_reset_advertising() 1463 1464 # Verify that registration is successful, and that all configured 1465 # properties are sent to the controller. 1466 self.register_advertisements(advertisements, orig_min_adv_interval_ms, 1467 orig_max_adv_interval_ms) 1468 1469 def run_le_advertising_test(self, host, advertisements, test_type, \ 1470 num_iterations=1): 1471 """Running Bluetooth adapter LE advertising autotest. 1472 1473 @param host: device under test host. 1474 @param advertisements: a list of advertisement instances. 1475 @param test_type: indicating one of three test types: multi-advertising, 1476 single-advertising, reboot (stress only), or 1477 suspend_resume (stress only). 1478 1479 @raises TestNAError: if DUT has low kernel version (<=3.8.11) 1480 1481 """ 1482 self.host = host 1483 self.kernel_version = self.host.get_kernel_version() 1484 self.check_kernel_version() 1485 1486 self.advertisements = advertisements 1487 self.first_advertisement = advertisements[0] 1488 self.two_advertisements = advertisements[3:5] 1489 self.three_advertisements = advertisements[0:3] 1490 self.five_advertisements = advertisements[0:5] 1491 self.sixth_advertisement = advertisements[5] 1492 1493 self.bluetooth_le_facade = self.bluetooth_facade 1494 1495 # Reset the adapter to forget previous stored data and turn it on. 1496 self.test_reset_on_adapter() 1497 1498 if test_type == 'multi_advertising': 1499 # Run all test cases for multiple advertisements. 1500 self.test_case_SI200_RA3_CD_UA3() 1501 self.test_case_SI200_RA3_CD_RA1_CD_UA1_CD_UA3() 1502 self.test_case_SI200_RA3_CD_RS() 1503 self.test_case_SI200_RA3_CD_UA1_CD_RS() 1504 self.test_case_SI200_RA3_CD_UA1_CD_RA2_CD_UA4() 1505 # TODO (b/169603469) this test will fail on platforms supporting 1506 # >5 advertising slots due to new advertising feature, so disable 1507 # until test can be refactored. 1508 # self.test_case_SI200_RA5_CD_FRA1_CD_UA5() 1509 self.test_case_RA3_CD_SI200_CD_UA3() 1510 self.test_case_RA3_CD_SI200_CD_RS() 1511 self.test_case_RA3_CD_SI200_CD_UA1_CD_RS() 1512 self.test_case_RA3_CD_SI200_CD_SI2000_CD_UA3() 1513 # TODO (b/169603469) this test will fail on platforms supporting 1514 # >5 advertising slots due to new advertising feature, so disable 1515 # until test can be refactored. 1516 # self.test_case_RA5_CD_SI200_CD_FRA1_CD_UA5() 1517 self.test_case_RA3_CD_SI200_CD_FSI10_CD_FSI20000_CD_UA3() 1518 self.test_case_SI200_RA3_CD_PC_CD_UA3() 1519 self.test_case_RA3_CD_SI200_CD_PC_CD_UA3() 1520 1521 elif test_type == 'single_advertising': 1522 # Run all test cases for single advertisement. 1523 # Note: it is required to change the advertisement instance 1524 # so that the advertisement data could be monitored by btmon. 1525 # Otherwise, the advertisement data would be just cached and 1526 # reused such that the data would not be visible in btmon. 1527 self.test_case_SI200_RA1_CD_UA1() 1528 self.test_case_SI200_RA1_CD_RS() 1529 self.test_case_RA1_CD_SI200_CD_UA1() 1530 self.test_case_RA1_CD_SI200_CD_RS() 1531 self.test_case_RA1_CD_SI200_CD_FSI10_UA1_RA1_CD_UA1() 1532 self.test_case_RA1_CD_SI200_CD_FSI20000_UA1_RA1_CD_UA1() 1533 self.test_case_RA1_CD_SI200_CD_PC_CD_UA1() 1534 1535 elif test_type == 'suspend_resume': 1536 # Run all test cases for suspend resume stress testing. 1537 for i in range(num_iterations): 1538 logging.info('Starting suspend resume loop #%d', i+1) 1539 self.test_case_SI200_RA3_CD_SR_CD_UA3() 1540 self.test_case_RA3_CD_SI200_CD_SR_CD_UA3() 1541 self.test_case_SI200_RA1_CD_SR_CD_UA1() 1542 self.test_case_RA1_CD_SI200_CD_SR_CD_UA1() 1543 1544 elif test_type == 'reboot': 1545 # Run all test cases for reboot stress testing. 1546 for i in range(num_iterations): 1547 logging.info('Starting reboot loop #%d', i+1) 1548 self.test_case_SI200_RA3_CD_PC_CD_UA3() 1549 self.test_case_RA3_CD_SI200_CD_PC_CD_UA3() 1550 self.test_case_RA1_CD_SI200_CD_PC_CD_UA1() 1551 1552 elif test_type == 'nearby': 1553 self.test_case_nearby_mediums_fast() 1554 self.test_case_adv_before_scan() 1555 1556 elif test_type == 'broadcast': 1557 self.test_case_broadcast() 1558