| # python3.4 |
| # Copyright (C) 2014 The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| # use this file except in compliance with the License. You may obtain a copy of |
| # the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| # License for the specific language governing permissions and limitations under |
| # the License. |
| |
| """ |
| This test script exercises different filters and outcomes not exercised in |
| FilteringTest. |
| """ |
| |
| import concurrent |
| import pprint |
| import time |
| |
| from queue import Empty |
| from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest |
| from acts.test_utils.bt.BleEnum import AdvertiseSettingsAdvertiseMode |
| from acts.test_utils.bt.BleEnum import ScanSettingsScanMode |
| from acts.test_utils.bt.bt_test_utils import generate_ble_advertise_objects |
| from acts.test_utils.bt.bt_test_utils import generate_ble_scan_objects |
| from acts.test_utils.bt.bt_test_utils import get_advanced_droid_list |
| from acts.test_utils.bt.bt_test_utils import batch_scan_result |
| from acts.test_utils.bt.bt_test_utils import scan_result |
| |
| |
| class UniqueFilteringTest(BluetoothBaseTest): |
| tests = None |
| default_timeout = 10 |
| |
| def __init__(self, controllers): |
| BluetoothBaseTest.__init__(self, controllers) |
| self.droid_list = get_advanced_droid_list(self.droids, self.eds) |
| self.scn_droid, self.scn_ed = self.droids[0], self.eds[0] |
| self.adv_droid, self.adv_ed = self.droids[1], self.eds[1] |
| if self.droid_list[1]['max_advertisements'] == 0: |
| self.tests = () |
| return |
| self.tests = ( |
| "test_scan_flush_pending_scan_results", |
| "test_scan_non_existent_name_filter", |
| "test_scan_advertisement_with_device_service_uuid_filter_expect_no_events", |
| "test_scan_filter_device_address", |
| ) |
| if self.droid_list[1]['max_advertisements'] > 1: |
| self.tests = self.tests + \ |
| ("test_scan_filtering_multiple_advertisements_manufacturer_data", |
| ) |
| if self.droid_list[0]['batch_scan_supported']: |
| self.tests = self.tests + ( |
| "test_scan_flush_results_without_on_batch_scan_results_triggered", |
| "test_scan_trigger_on_batch_scan_results",) |
| |
| def blescan_verify_onfailure_event_handler(self, event): |
| self.log.debug("Verifying onFailure event") |
| self.log.debug(pprint.pformat(event)) |
| return event |
| |
| def blescan_verify_onscanresult_event_handler(self, event, |
| expected_callbacktype=None, |
| system_time_nanos=None): |
| test_result = True |
| self.log.debug("Verifying onScanResult event") |
| self.log.debug(pprint.pformat(event)) |
| callbacktype = event['data']['CallbackType'] |
| if callbacktype != expected_callbacktype: |
| self.log.debug("Expected callback type: {}, Found callback type: {}".format( |
| expected_callbacktype, callbacktype)) |
| test_result = False |
| return test_result |
| |
| def blescan_get_mac_address_event_handler(self, event): |
| return event['data']['Result']['deviceInfo']['address'] |
| |
| def blescan_verify_onbatchscanresult_event_handler(self, event, |
| system_time_nanos=None, |
| report_delay_nanos=None): |
| test_result = True |
| self.log.debug("Verifying onBatchScanResult event") |
| self.log.debug(pprint.pformat(event)) |
| for result in event['data']['Results']: |
| timestamp_nanos = result['timestampNanos'] |
| length_of_time = timestamp_nanos - system_time_nanos |
| self.log.debug("Difference in time in between scan start and " |
| "onBatchScanResult: {}".format(length_of_time)) |
| buffer = 1000000000 # 1 second |
| if length_of_time > (report_delay_nanos + buffer): |
| self.log.debug( |
| "Difference was greater than the allowable difference.") |
| test_result = False |
| return test_result |
| |
| @BluetoothBaseTest.bt_test_wrap |
| def test_scan_flush_pending_scan_results(self): |
| """Test LE scan api flush pending results. |
| |
| Test that flush pending scan results doesn't affect onScanResults from |
| triggering. |
| |
| Steps: |
| 1. Setup the scanning android device. |
| 2. Setup the advertiser android devices. |
| 3. Trigger bluetoothFlushPendingScanResults on the scanning droid. |
| 4. Verify that only one onScanResults callback was triggered. |
| |
| Expected Result: |
| After flushing pending scan results, make sure only one onScanResult |
| callback was triggered. |
| |
| Returns: |
| Pass if True |
| Fail if False |
| |
| TAGS: LE, Advertising, Filtering, Scanning |
| Priority: 1 |
| """ |
| test_result = True |
| self.adv_droid.bleSetAdvertiseSettingsAdvertiseMode( |
| AdvertiseSettingsAdvertiseMode.ADVERTISE_MODE_LOW_LATENCY.value) |
| filter_list, scan_settings, scan_callback = generate_ble_scan_objects( |
| self.scn_droid) |
| expected_event_name = scan_result.format(scan_callback) |
| advertise_callback, advertise_data, advertise_settings = ( |
| generate_ble_advertise_objects(self.adv_droid)) |
| self.adv_droid.bleStartBleAdvertising( |
| advertise_callback, advertise_data, advertise_settings) |
| self.scn_droid.bleStartBleScan( |
| filter_list, scan_settings, scan_callback) |
| self.scn_droid.bleFlushPendingScanResults(scan_callback) |
| worker = self.scn_ed.handle_event( |
| self.blescan_verify_onscanresult_event_handler, |
| expected_event_name, ([1]), self.default_timeout) |
| try: |
| self.log.debug(worker.result(self.default_timeout)) |
| except Empty as error: |
| test_result = False |
| self.log.debug("Test failed with Empty error: {}".format(error)) |
| except concurrent.futures._base.TimeoutError as error: |
| test_result = False |
| self.log.debug("Test failed with TimeoutError: {}".format(error)) |
| self.scn_droid.bleStopBleScan(scan_callback) |
| self.adv_droid.bleStopBleAdvertising(advertise_callback) |
| return test_result |
| |
| @BluetoothBaseTest.bt_test_wrap |
| def test_scan_trigger_on_batch_scan_results(self): |
| """Test triggering batch scan results. |
| |
| Test that triggers onBatchScanResults and verifies the time to trigger |
| within one second leeway. |
| |
| Steps: |
| 1. Setup the scanning android device with report delay seconds set to |
| 5000. |
| 2. Setup the advertiser android devices. |
| 3. Verify that only one onBatchScanResult callback was triggered. |
| 4. Compare the system time that the scan was started with the elapsed |
| time that is in the callback. |
| |
| Expected Result: |
| The scan event dispatcher should find an onBatchScanResult event. |
| |
| Returns: |
| Pass if True |
| Fail if False |
| |
| TAGS: LE, Advertising, Filtering, Scanning, Batch Scanning |
| Priority: 2 |
| """ |
| test_result = True |
| self.scn_droid.bleSetScanSettingsReportDelayMillis(5000) |
| filter_list, scan_settings, scan_callback = generate_ble_scan_objects( |
| self.scn_droid) |
| expected_event_name = batch_scan_result.format(scan_callback) |
| self.adv_droid.bleSetAdvertiseDataIncludeDeviceName(True) |
| self.adv_droid.bleSetAdvertiseDataIncludeTxPowerLevel(True) |
| advertise_callback, advertise_data, advertise_settings = ( |
| generate_ble_advertise_objects(self.adv_droid)) |
| self.adv_droid.bleStartBleAdvertising( |
| advertise_callback, advertise_data, advertise_settings) |
| self.scn_droid.bleStartBleScan( |
| filter_list, scan_settings, scan_callback) |
| system_time_nanos = self.scn_droid.getSystemElapsedRealtimeNanos() |
| self.log.debug("Current system time: {}".format(system_time_nanos)) |
| worker = self.scn_ed.handle_event( |
| self.blescan_verify_onbatchscanresult_event_handler, |
| expected_event_name, ([system_time_nanos, 5000000000]), |
| self.default_timeout) |
| try: |
| self.log.debug(worker.result(self.default_timeout)) |
| except Empty as error: |
| test_result = False |
| self.log.debug("Test failed with: {}".format(error)) |
| except concurrent.futures._base.TimeoutError as error: |
| test_result = False |
| self.log.debug("Test failed with: {}".format(error)) |
| self.scn_droid.bleStopBleScan(scan_callback) |
| self.adv_droid.bleStopBleAdvertising(advertise_callback) |
| return test_result |
| |
| @BluetoothBaseTest.bt_test_wrap |
| def test_scan_flush_results_without_on_batch_scan_results_triggered(self): |
| """Test that doesn't expect a batch scan result. |
| |
| Test flush pending scan results with a report delay seconds set to 0. |
| No onBatchScanResults callback should be triggered. |
| |
| Steps: |
| 1. Setup the scanning android device with report delay seconds set to 0 |
| (or just use default). |
| 2. Setup the advertiser android devices. |
| |
| Expected Result: |
| Verify that no onBatchScanResults were triggered. |
| |
| Returns: |
| Pass if True |
| Fail if False |
| |
| TAGS: LE, Advertising, Filtering, Scanning, Batch Scanning |
| Priority: 2 |
| """ |
| test_result = True |
| filter_list, scan_settings, scan_callback = generate_ble_scan_objects( |
| self.scn_droid) |
| expected_event_name = batch_scan_result.format(scan_callback) |
| advertise_callback, advertise_data, advertise_settings =( |
| generate_ble_advertise_objects(self.adv_droid)) |
| self.adv_droid.bleStartBleAdvertising( |
| advertise_callback, advertise_data, advertise_settings) |
| self.scn_droid.bleStartBleScan( |
| filter_list, scan_settings, scan_callback) |
| worker = self.scn_ed.handle_event( |
| self.blescan_verify_onbatchscanresult_event_handler, |
| expected_event_name, ([]), self.default_timeout) |
| self.scn_droid.bleFlushPendingScanResults(scan_callback) |
| try: |
| event_info = self.scn_ed.pop_event(expected_event_name, |
| 10) |
| self.log.debug( |
| "Unexpectedly found an advertiser: {}".format(event_info)) |
| test_result = False |
| except Empty: |
| self.log.debug("No {} events were found as expected.".format( |
| batch_scan_result)) |
| self.scn_droid.bleStopBleScan(scan_callback) |
| self.adv_droid.bleStopBleAdvertising(advertise_callback) |
| return test_result |
| |
| @BluetoothBaseTest.bt_test_wrap |
| def test_scan_non_existent_name_filter(self): |
| """Test non-existent name filter. |
| |
| Test scan filter on non-existent device name. |
| |
| Steps: |
| 1. Setup the scanning android device with scan filter for device name |
| set to an unexpected value. |
| 2. Setup the advertiser android devices. |
| 3. Verify that no onScanResults were triggered. |
| |
| Expected Result: |
| No advertisements were found. |
| |
| Returns: |
| Pass if True |
| Fail if False |
| |
| TAGS: LE, Advertising, Filtering, Scanning |
| Priority: 2 |
| """ |
| test_result = True |
| filter_name = "{}_probably_wont_find".format( |
| self.adv_droid.bluetoothGetLocalName()) |
| self.adv_droid.bleSetAdvertiseDataIncludeDeviceName(True) |
| self.scn_droid.bleSetScanFilterDeviceName(filter_name) |
| filter_list, scan_settings, scan_callback = generate_ble_scan_objects( |
| self.scn_droid) |
| self.scn_droid.bleBuildScanFilter(filter_list) |
| expected_event_name = scan_result.format(scan_callback) |
| self.adv_droid.bleSetAdvertiseDataIncludeDeviceName(True) |
| self.adv_droid.bleSetAdvertiseDataIncludeTxPowerLevel(True) |
| advertise_callback, advertise_data, advertise_settings = ( |
| generate_ble_advertise_objects(self.adv_droid)) |
| self.adv_droid.bleStartBleAdvertising( |
| advertise_callback, advertise_data, advertise_settings) |
| self.scn_droid.bleStartBleScan( |
| filter_list, scan_settings, scan_callback) |
| try: |
| event_info = self.scn_ed.pop_event( |
| expected_event_name, self.default_timeout) |
| self.log.error( |
| "Unexpectedly found an advertiser: {}".format(event_info)) |
| test_result = False |
| except Empty: |
| self.log.debug("No events were found as expected.") |
| self.scn_droid.bleStopBleScan(scan_callback) |
| self.adv_droid.bleStopBleAdvertising(advertise_callback) |
| return test_result |
| |
| @BluetoothBaseTest.bt_test_wrap |
| def test_scan_advertisement_with_device_service_uuid_filter_expect_no_events( |
| self): |
| """Test scan filtering against an advertisement with no data. |
| |
| Test that exercises a service uuid filter on the scanner but no server |
| uuid added to the advertisement. |
| |
| Steps: |
| 1. Setup the scanning android device with scan filter including a |
| service uuid and mask. |
| 2. Setup the advertiser android devices. |
| 3. Verify that no onScanResults were triggered. |
| |
| Expected Result: |
| Verify no advertisements found. |
| |
| Returns: |
| Pass if True |
| Fail if False |
| |
| TAGS: LE, Advertising, Filtering, Scanning |
| Priority: 1 |
| """ |
| test_result = True |
| service_uuid = "00000000-0000-1000-8000-00805F9B34FB" |
| service_mask = "00000000-0000-1000-8000-00805F9B34FA" |
| self.adv_droid.bleSetAdvertiseDataIncludeDeviceName(True) |
| self.scn_droid.bleSetScanFilterServiceUuid(service_uuid, service_mask) |
| self.adv_droid.bleSetAdvertiseSettingsAdvertiseMode( |
| AdvertiseSettingsAdvertiseMode.ADVERTISE_MODE_LOW_LATENCY.value) |
| filter_list, scan_settings, scan_callback = generate_ble_scan_objects( |
| self.scn_droid) |
| self.scn_droid.bleBuildScanFilter(filter_list) |
| expected_event_name = scan_result.format(scan_callback) |
| self.adv_droid.bleSetAdvertiseDataIncludeDeviceName(True) |
| self.adv_droid.bleSetAdvertiseDataIncludeTxPowerLevel(True) |
| advertise_callback, advertise_data, advertise_settings = ( |
| generate_ble_advertise_objects(self.adv_droid)) |
| self.adv_droid.bleStartBleAdvertising( |
| advertise_callback, advertise_data, advertise_settings) |
| self.scn_droid.bleStartBleScan( |
| filter_list, scan_settings, scan_callback) |
| worker = self.scn_ed.handle_event( |
| self.blescan_verify_onscanresult_event_handler, |
| expected_event_name, ([1]), self.default_timeout) |
| try: |
| event_info = self.scn_ed.pop_event(expected_event_name, |
| self.default_timeout) |
| self.log.error( |
| "Unexpectedly found an advertiser:".format(event_info)) |
| test_result = False |
| except Empty as error: |
| self.log.debug("No events were found as expected.") |
| self.scn_droid.bleStopBleScan(scan_callback) |
| self.adv_droid.bleStopBleAdvertising(advertise_callback) |
| return test_result |
| |
| @BluetoothBaseTest.bt_test_wrap |
| def test_scan_filtering_multiple_advertisements_manufacturer_data(self): |
| """Test scan filtering against multiple varying advertisements. |
| |
| Test scan filtering against multiple varying advertisements. The first |
| advertisement will have partial manufacturer data that matches the |
| the full manufacturer data in the second advertisement. |
| |
| Steps: |
| 1. Setup up an advertisement with manufacturer data "1,2,3". |
| 2. Setup a second advertisement with manufacturer data |
| "1,2,3,4,5,6,7,8". |
| 3. Start advertising on each advertisement. |
| 4. Create a scan filter that includes manufacturer data "1,2,3". |
| |
| Expected Result: |
| TBD. Right now Shamu finds only the first advertisement with |
| manufacturer data "1,2,3". |
| |
| Returns: |
| Pass if True |
| Fail if False |
| |
| TAGS: LE, Advertising, Filtering, Scanning |
| Priority: 2 |
| """ |
| # TODO: (tturney) waiting on input from team on how we handle this |
| # situation. |
| test_result = True |
| self.adv_droid.bleSetAdvertiseSettingsAdvertiseMode( |
| AdvertiseSettingsAdvertiseMode.ADVERTISE_MODE_LOW_LATENCY.value) |
| self.adv_droid.bleAddAdvertiseDataManufacturerId(117, "1,2,3") |
| advertise_callback, advertise_data, advertise_settings = ( |
| generate_ble_advertise_objects(self.adv_droid)) |
| self.adv_droid.bleSetAdvertiseSettingsAdvertiseMode( |
| AdvertiseSettingsAdvertiseMode.ADVERTISE_MODE_LOW_LATENCY.value) |
| self.adv_droid.bleAddAdvertiseDataManufacturerId( |
| 117, "1,2,3,4,5,6,7,8") |
| advertise_callback1, advertise_data1, advertise_settings1 = ( |
| generate_ble_advertise_objects(self.adv_droid)) |
| self.adv_droid.bleStartBleAdvertising( |
| advertise_callback, advertise_data, advertise_settings) |
| self.adv_droid.bleStartBleAdvertising( |
| advertise_callback1, advertise_data1, |
| advertise_settings1) |
| |
| filter_list = self.scn_droid.bleGenFilterList() |
| self.scn_droid.bleSetScanSettingsScanMode( |
| ScanSettingsScanMode.SCAN_MODE_LOW_LATENCY.value) |
| scan_settings = self.scn_droid.bleBuildScanSetting() |
| scan_callback = self.scn_droid.bleGenScanCallback() |
| self.scn_droid.bleSetScanFilterManufacturerData( |
| 117, "1,2,3", "127,127,127") |
| self.scn_droid.bleBuildScanFilter(filter_list) |
| self.scn_droid.bleStartBleScan( |
| filter_list, scan_settings, scan_callback) |
| return test_result |
| |
| @BluetoothBaseTest.bt_test_wrap |
| def test_scan_filter_device_address(self): |
| """Test scan filtering of a device address. |
| |
| This test will have to create two scanning instances. The first will |
| have no filters and will find the generic advertisement's mac address. |
| The second will have a filter of the found mac address. |
| |
| Steps: |
| 1. Start a generic advertisement. |
| 2. Start a generic scanner. |
| 3. Find the advertisement and extract the mac address. |
| 4. Stop the first scanner. |
| 5. Create a new scanner with scan filter with a mac address filter of |
| what was found in step 3. |
| 6. Start the scanner. |
| |
| Expected Result: |
| Verify that the advertisement was found in the second scan instance. |
| |
| Returns: |
| Pass if True |
| Fail if False |
| |
| TAGS: LE, Advertising, Filtering, Scanning |
| Priority: 1 |
| """ |
| test_result = True |
| self.scn_droid.bleSetScanSettingsScanMode( |
| ScanSettingsScanMode.SCAN_MODE_LOW_LATENCY.value) |
| filter_list, scan_settings, scan_callback = generate_ble_scan_objects( |
| self.scn_droid) |
| expected_event_name = scan_result.format(scan_callback) |
| self.adv_droid.bleSetAdvertiseSettingsAdvertiseMode( |
| AdvertiseSettingsAdvertiseMode.ADVERTISE_MODE_LOW_LATENCY.value) |
| advertise_callback, advertise_data, advertise_settings = ( |
| generate_ble_advertise_objects(self.adv_droid)) |
| self.adv_droid.bleStartBleAdvertising( |
| advertise_callback, advertise_data, advertise_settings) |
| self.scn_droid.bleStartBleScan( |
| filter_list, scan_settings, scan_callback) |
| event_info = self.scn_ed.pop_event( |
| expected_event_name, self.default_timeout) |
| mac_address = event_info['data']['Result']['deviceInfo']['address'] |
| self.log.info( |
| "Filter advertisement with address {}".format(mac_address)) |
| self.scn_droid.bleStopBleScan(scan_callback) |
| self.scn_droid.bleSetScanSettingsScanMode( |
| ScanSettingsScanMode.SCAN_MODE_LOW_LATENCY.value) |
| self.scn_droid.bleSetScanFilterDeviceAddress(mac_address) |
| filter_list2, scan_settings2, scan_callback2 = ( |
| generate_ble_scan_objects(self.scn_droid)) |
| |
| self.scn_droid.bleBuildScanFilter(filter_list2) |
| self.scn_droid.bleStartBleScan( |
| filter_list2, scan_settings2, scan_callback2) |
| expected_event_name = scan_result.format(scan_callback2) |
| found_event = self.scn_ed.pop_event( |
| expected_event_name, self.default_timeout) |
| if (found_event['data']['Result']['deviceInfo']['address'] != |
| mac_address): |
| test_result = False |
| self.scn_droid.bleStopBleScan(scan_callback2) |
| self.adv_droid.bleStopBleAdvertising(advertise_callback) |
| return test_result |