Home | History | Annotate | Download | only in filtering
      1 #/usr/bin/env python3.4
      2 #
      3 # Copyright (C) 2016 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License"); you may not
      6 # use this file except in compliance with the License. You may obtain a copy of
      7 # 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, WITHOUT
     13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
     14 # License for the specific language governing permissions and limitations under
     15 # the License.
     16 """
     17 This test script exercises different filters and outcomes not exercised in
     18 FilteringTest.
     19 """
     20 
     21 import concurrent
     22 import pprint
     23 import time
     24 
     25 from queue import Empty
     26 from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
     27 from acts.test_utils.bt.BleEnum import AdvertiseSettingsAdvertiseMode
     28 from acts.test_utils.bt.BleEnum import ScanSettingsScanMode
     29 from acts.test_utils.bt.bt_test_utils import generate_ble_advertise_objects
     30 from acts.test_utils.bt.bt_test_utils import generate_ble_scan_objects
     31 from acts.test_utils.bt.bt_test_utils import get_advanced_droid_list
     32 from acts.test_utils.bt.bt_test_utils import batch_scan_result
     33 from acts.test_utils.bt.bt_test_utils import scan_result
     34 
     35 
     36 class UniqueFilteringTest(BluetoothBaseTest):
     37     default_timeout = 10
     38 
     39     def __init__(self, controllers):
     40         BluetoothBaseTest.__init__(self, controllers)
     41         self.droid_list = get_advanced_droid_list(self.android_devices)
     42         self.scn_ad = self.android_devices[0]
     43         self.adv_ad = self.android_devices[1]
     44         if self.droid_list[1]['max_advertisements'] == 0:
     45             self.tests = ()
     46             return
     47 
     48     def blescan_verify_onfailure_event_handler(self, event):
     49         self.log.debug("Verifying onFailure event")
     50         self.log.debug(pprint.pformat(event))
     51         return event
     52 
     53     def blescan_verify_onscanresult_event_handler(self,
     54                                                   event,
     55                                                   expected_callbacktype=None,
     56                                                   system_time_nanos=None):
     57         test_result = True
     58         self.log.debug("Verifying onScanResult event")
     59         self.log.debug(pprint.pformat(event))
     60         callbacktype = event['data']['CallbackType']
     61         if callbacktype != expected_callbacktype:
     62             self.log.debug(
     63                 "Expected callback type: {}, Found callback type: {}"
     64                 .format(expected_callbacktype, callbacktype))
     65             test_result = False
     66         return test_result
     67 
     68     def blescan_get_mac_address_event_handler(self, event):
     69         return event['data']['Result']['deviceInfo']['address']
     70 
     71     def blescan_verify_onbatchscanresult_event_handler(
     72             self,
     73             event,
     74             system_time_nanos=None,
     75             report_delay_nanos=None):
     76         test_result = True
     77         self.log.debug("Verifying onBatchScanResult event")
     78         self.log.debug(pprint.pformat(event))
     79         for result in event['data']['Results']:
     80             timestamp_nanos = result['timestampNanos']
     81             length_of_time = timestamp_nanos - system_time_nanos
     82             self.log.debug("Difference in time in between scan start and "
     83                            "onBatchScanResult: {}".format(length_of_time))
     84             buffer = 1000000000  # 1 second
     85             if length_of_time > (report_delay_nanos + buffer):
     86                 self.log.debug(
     87                     "Difference was greater than the allowable difference.")
     88                 test_result = False
     89         return test_result
     90 
     91     @BluetoothBaseTest.bt_test_wrap
     92     def test_scan_flush_pending_scan_results(self):
     93         """Test LE scan api flush pending results.
     94 
     95         Test that flush pending scan results doesn't affect onScanResults from
     96         triggering.
     97 
     98         Steps:
     99         1. Setup the scanning android device.
    100         2. Setup the advertiser android devices.
    101         3. Trigger bluetoothFlushPendingScanResults on the scanning droid.
    102         4. Verify that only one onScanResults callback was triggered.
    103 
    104         Expected Result:
    105         After flushing pending scan results, make sure only one onScanResult
    106         callback was triggered.
    107 
    108         Returns:
    109           Pass if True
    110           Fail if False
    111 
    112         TAGS: LE, Advertising, Filtering, Scanning
    113         Priority: 1
    114         """
    115         test_result = True
    116         self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
    117             AdvertiseSettingsAdvertiseMode.ADVERTISE_MODE_LOW_LATENCY.value)
    118         filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
    119             self.scn_ad.droid)
    120         expected_event_name = scan_result.format(scan_callback)
    121         advertise_callback, advertise_data, advertise_settings = (
    122             generate_ble_advertise_objects(self.adv_ad.droid))
    123         self.adv_ad.droid.bleStartBleAdvertising(
    124             advertise_callback, advertise_data, advertise_settings)
    125         self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
    126                                           scan_callback)
    127         self.scn_ad.droid.bleFlushPendingScanResults(scan_callback)
    128         worker = self.scn_ad.ed.handle_event(
    129             self.blescan_verify_onscanresult_event_handler,
    130             expected_event_name, ([1]), self.default_timeout)
    131         try:
    132             self.log.debug(worker.result(self.default_timeout))
    133         except Empty as error:
    134             test_result = False
    135             self.log.debug("Test failed with Empty error: {}".format(error))
    136         except concurrent.futures._base.TimeoutError as error:
    137             test_result = False
    138             self.log.debug("Test failed with TimeoutError: {}".format(error))
    139         self.scn_ad.droid.bleStopBleScan(scan_callback)
    140         self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
    141         return test_result
    142 
    143     @BluetoothBaseTest.bt_test_wrap
    144     def test_scan_trigger_on_batch_scan_results(self):
    145         """Test triggering batch scan results.
    146 
    147         Test that triggers onBatchScanResults and verifies the time to trigger
    148         within one second leeway.
    149 
    150         Steps:
    151         1. Setup the scanning android device with report delay seconds set to
    152         5000.
    153         2. Setup the advertiser android devices.
    154         3. Verify that only one onBatchScanResult callback was triggered.
    155         4. Compare the system time that the scan was started with the elapsed
    156         time that is in the callback.
    157 
    158         Expected Result:
    159         The scan event dispatcher should find an onBatchScanResult event.
    160 
    161         Returns:
    162           Pass if True
    163           Fail if False
    164 
    165         TAGS: LE, Advertising, Filtering, Scanning, Batch Scanning
    166         Priority: 2
    167         """
    168         test_result = True
    169         self.scn_ad.droid.bleSetScanSettingsReportDelayMillis(5000)
    170         filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
    171             self.scn_ad.droid)
    172         expected_event_name = batch_scan_result.format(scan_callback)
    173         self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
    174         self.adv_ad.droid.bleSetAdvertiseDataIncludeTxPowerLevel(True)
    175         advertise_callback, advertise_data, advertise_settings = (
    176             generate_ble_advertise_objects(self.adv_ad.droid))
    177         self.adv_ad.droid.bleStartBleAdvertising(
    178             advertise_callback, advertise_data, advertise_settings)
    179         self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
    180                                           scan_callback)
    181         system_time_nanos = self.scn_ad.droid.getSystemElapsedRealtimeNanos()
    182         self.log.debug("Current system time: {}".format(system_time_nanos))
    183         worker = self.scn_ad.ed.handle_event(
    184             self.blescan_verify_onbatchscanresult_event_handler,
    185             expected_event_name, ([system_time_nanos, 5000000000]),
    186             self.default_timeout)
    187         try:
    188             self.log.debug(worker.result(self.default_timeout))
    189         except Empty as error:
    190             test_result = False
    191             self.log.debug("Test failed with: {}".format(error))
    192         except concurrent.futures._base.TimeoutError as error:
    193             test_result = False
    194             self.log.debug("Test failed with: {}".format(error))
    195         self.scn_ad.droid.bleStopBleScan(scan_callback)
    196         self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
    197         return test_result
    198 
    199     @BluetoothBaseTest.bt_test_wrap
    200     def test_scan_flush_results_without_on_batch_scan_results_triggered(self):
    201         """Test that doesn't expect a batch scan result.
    202 
    203         Test flush pending scan results with a report delay seconds set to 0.
    204         No onBatchScanResults callback should be triggered.
    205 
    206         Steps:
    207         1. Setup the scanning android device with report delay seconds set to 0
    208         (or just use default).
    209         2. Setup the advertiser android devices.
    210 
    211         Expected Result:
    212         Verify that no onBatchScanResults were triggered.
    213 
    214         Returns:
    215           Pass if True
    216           Fail if False
    217 
    218         TAGS: LE, Advertising, Filtering, Scanning, Batch Scanning
    219         Priority: 2
    220         """
    221         test_result = True
    222         filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
    223             self.scn_ad.droid)
    224         expected_event_name = batch_scan_result.format(scan_callback)
    225         advertise_callback, advertise_data, advertise_settings = (
    226             generate_ble_advertise_objects(self.adv_ad.droid))
    227         self.adv_ad.droid.bleStartBleAdvertising(
    228             advertise_callback, advertise_data, advertise_settings)
    229         self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
    230                                           scan_callback)
    231         worker = self.scn_ad.ed.handle_event(
    232             self.blescan_verify_onbatchscanresult_event_handler,
    233             expected_event_name, ([]), self.default_timeout)
    234         self.scn_ad.droid.bleFlushPendingScanResults(scan_callback)
    235         try:
    236             event_info = self.scn_ad.ed.pop_event(expected_event_name, 10)
    237             self.log.debug("Unexpectedly found an advertiser: {}".format(
    238                 event_info))
    239             test_result = False
    240         except Empty:
    241             self.log.debug("No {} events were found as expected.".format(
    242                 batch_scan_result))
    243         self.scn_ad.droid.bleStopBleScan(scan_callback)
    244         self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
    245         return test_result
    246 
    247     @BluetoothBaseTest.bt_test_wrap
    248     def test_scan_non_existent_name_filter(self):
    249         """Test non-existent name filter.
    250 
    251         Test scan filter on non-existent device name.
    252 
    253         Steps:
    254         1. Setup the scanning android device with scan filter for device name
    255         set to an unexpected value.
    256         2. Setup the advertiser android devices.
    257         3. Verify that no onScanResults were triggered.
    258 
    259         Expected Result:
    260         No advertisements were found.
    261 
    262         Returns:
    263           Pass if True
    264           Fail if False
    265 
    266         TAGS: LE, Advertising, Filtering, Scanning
    267         Priority: 2
    268         """
    269         test_result = True
    270         filter_name = "{}_probably_wont_find".format(
    271             self.adv_ad.droid.bluetoothGetLocalName())
    272         self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
    273         self.scn_ad.droid.bleSetScanFilterDeviceName(filter_name)
    274         filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
    275             self.scn_ad.droid)
    276         self.scn_ad.droid.bleBuildScanFilter(filter_list)
    277         expected_event_name = scan_result.format(scan_callback)
    278         self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
    279         self.adv_ad.droid.bleSetAdvertiseDataIncludeTxPowerLevel(True)
    280         advertise_callback, advertise_data, advertise_settings = (
    281             generate_ble_advertise_objects(self.adv_ad.droid))
    282         self.adv_ad.droid.bleStartBleAdvertising(
    283             advertise_callback, advertise_data, advertise_settings)
    284         self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
    285                                           scan_callback)
    286         try:
    287             event_info = self.scn_ad.ed.pop_event(expected_event_name,
    288                                                   self.default_timeout)
    289             self.log.error("Unexpectedly found an advertiser: {}".format(
    290                 event_info))
    291             test_result = False
    292         except Empty:
    293             self.log.debug("No events were found as expected.")
    294         self.scn_ad.droid.bleStopBleScan(scan_callback)
    295         self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
    296         return test_result
    297 
    298     @BluetoothBaseTest.bt_test_wrap
    299     def test_scan_advertisement_with_device_service_uuid_filter_expect_no_events(
    300             self):
    301         """Test scan filtering against an advertisement with no data.
    302 
    303         Test that exercises a service uuid filter on the scanner but no server
    304         uuid added to the advertisement.
    305 
    306         Steps:
    307         1. Setup the scanning android device with scan filter including a
    308         service uuid and mask.
    309         2. Setup the advertiser android devices.
    310         3. Verify that no onScanResults were triggered.
    311 
    312         Expected Result:
    313         Verify no advertisements found.
    314 
    315         Returns:
    316           Pass if True
    317           Fail if False
    318 
    319         TAGS: LE, Advertising, Filtering, Scanning
    320         Priority: 1
    321         """
    322         test_result = True
    323         service_uuid = "00000000-0000-1000-8000-00805F9B34FB"
    324         service_mask = "00000000-0000-1000-8000-00805F9B34FA"
    325         self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
    326         self.scn_ad.droid.bleSetScanFilterServiceUuid(service_uuid,
    327                                                       service_mask)
    328         self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
    329             AdvertiseSettingsAdvertiseMode.ADVERTISE_MODE_LOW_LATENCY.value)
    330         filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
    331             self.scn_ad.droid)
    332         self.scn_ad.droid.bleBuildScanFilter(filter_list)
    333         expected_event_name = scan_result.format(scan_callback)
    334         self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
    335         self.adv_ad.droid.bleSetAdvertiseDataIncludeTxPowerLevel(True)
    336         advertise_callback, advertise_data, advertise_settings = (
    337             generate_ble_advertise_objects(self.adv_ad.droid))
    338         self.adv_ad.droid.bleStartBleAdvertising(
    339             advertise_callback, advertise_data, advertise_settings)
    340         self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
    341                                           scan_callback)
    342         worker = self.scn_ad.ed.handle_event(
    343             self.blescan_verify_onscanresult_event_handler,
    344             expected_event_name, ([1]), self.default_timeout)
    345         try:
    346             event_info = self.scn_ad.ed.pop_event(expected_event_name,
    347                                                   self.default_timeout)
    348             self.log.error("Unexpectedly found an advertiser:".format(
    349                 event_info))
    350             test_result = False
    351         except Empty as error:
    352             self.log.debug("No events were found as expected.")
    353         self.scn_ad.droid.bleStopBleScan(scan_callback)
    354         self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
    355         return test_result
    356 
    357     @BluetoothBaseTest.bt_test_wrap
    358     def test_scan_filtering_multiple_advertisements_manufacturer_data(self):
    359         """Test scan filtering against multiple varying advertisements.
    360 
    361         Test scan filtering against multiple varying advertisements. The first
    362         advertisement will have partial manufacturer data that matches the
    363         the full manufacturer data in the second advertisement.
    364 
    365         Steps:
    366         1. Setup up an advertisement with manufacturer data "1,2,3".
    367         2. Setup a second advertisement with manufacturer data
    368         "1,2,3,4,5,6,7,8".
    369         3. Start advertising on each advertisement.
    370         4. Create a scan filter that includes manufacturer data "1,2,3".
    371 
    372         Expected Result:
    373         TBD. Right now Shamu finds only the first advertisement with
    374         manufacturer data "1,2,3".
    375 
    376         Returns:
    377           Pass if True
    378           Fail if False
    379 
    380         TAGS: LE, Advertising, Filtering, Scanning
    381         Priority: 2
    382         """
    383         test_result = True
    384         self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
    385             AdvertiseSettingsAdvertiseMode.ADVERTISE_MODE_LOW_LATENCY.value)
    386         self.adv_ad.droid.bleAddAdvertiseDataManufacturerId(117, "1,2,3")
    387         advertise_callback, advertise_data, advertise_settings = (
    388             generate_ble_advertise_objects(self.adv_ad.droid))
    389         self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
    390             AdvertiseSettingsAdvertiseMode.ADVERTISE_MODE_LOW_LATENCY.value)
    391         self.adv_ad.droid.bleAddAdvertiseDataManufacturerId(117,
    392                                                             "1,2,3,4,5,6,7,8")
    393         advertise_callback1, advertise_data1, advertise_settings1 = (
    394             generate_ble_advertise_objects(self.adv_ad.droid))
    395         self.adv_ad.droid.bleStartBleAdvertising(
    396             advertise_callback, advertise_data, advertise_settings)
    397         self.adv_ad.droid.bleStartBleAdvertising(
    398             advertise_callback1, advertise_data1, advertise_settings1)
    399 
    400         filter_list = self.scn_ad.droid.bleGenFilterList()
    401         self.scn_ad.droid.bleSetScanSettingsScanMode(
    402             ScanSettingsScanMode.SCAN_MODE_LOW_LATENCY.value)
    403         scan_settings = self.scn_ad.droid.bleBuildScanSetting()
    404         scan_callback = self.scn_ad.droid.bleGenScanCallback()
    405         self.scn_ad.droid.bleSetScanFilterManufacturerData(117, "1,2,3",
    406                                                            "127,127,127")
    407         self.scn_ad.droid.bleBuildScanFilter(filter_list)
    408         self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
    409                                           scan_callback)
    410         return test_result
    411 
    412     @BluetoothBaseTest.bt_test_wrap
    413     def test_scan_filter_device_address(self):
    414         """Test scan filtering of a device address.
    415 
    416         This test will have to create two scanning instances. The first will
    417         have no filters and will find the generic advertisement's mac address.
    418         The second will have a filter of the found mac address.
    419 
    420         Steps:
    421         1. Start a generic advertisement.
    422         2. Start a generic scanner.
    423         3. Find the advertisement and extract the mac address.
    424         4. Stop the first scanner.
    425         5. Create a new scanner with scan filter with a mac address filter of
    426         what was found in step 3.
    427         6. Start the scanner.
    428 
    429         Expected Result:
    430         Verify that the advertisement was found in the second scan instance.
    431 
    432         Returns:
    433           Pass if True
    434           Fail if False
    435 
    436         TAGS: LE, Advertising, Filtering, Scanning
    437         Priority: 1
    438         """
    439         test_result = True
    440         self.scn_ad.droid.bleSetScanSettingsScanMode(
    441             ScanSettingsScanMode.SCAN_MODE_LOW_LATENCY.value)
    442         filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
    443             self.scn_ad.droid)
    444         expected_event_name = scan_result.format(scan_callback)
    445         self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
    446             AdvertiseSettingsAdvertiseMode.ADVERTISE_MODE_LOW_LATENCY.value)
    447         advertise_callback, advertise_data, advertise_settings = (
    448             generate_ble_advertise_objects(self.adv_ad.droid))
    449         self.adv_ad.droid.bleStartBleAdvertising(
    450             advertise_callback, advertise_data, advertise_settings)
    451         self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
    452                                           scan_callback)
    453         event_info = self.scn_ad.ed.pop_event(expected_event_name,
    454                                               self.default_timeout)
    455         mac_address = event_info['data']['Result']['deviceInfo']['address']
    456         self.log.info("Filter advertisement with address {}".format(
    457             mac_address))
    458         self.scn_ad.droid.bleStopBleScan(scan_callback)
    459         self.scn_ad.droid.bleSetScanSettingsScanMode(
    460             ScanSettingsScanMode.SCAN_MODE_LOW_LATENCY.value)
    461         self.scn_ad.droid.bleSetScanFilterDeviceAddress(mac_address)
    462         filter_list2, scan_settings2, scan_callback2 = (
    463             generate_ble_scan_objects(self.scn_ad.droid))
    464 
    465         self.scn_ad.droid.bleBuildScanFilter(filter_list2)
    466         self.scn_ad.droid.bleStartBleScan(filter_list2, scan_settings2,
    467                                           scan_callback2)
    468         expected_event_name = scan_result.format(scan_callback2)
    469         found_event = self.scn_ad.ed.pop_event(expected_event_name,
    470                                                self.default_timeout)
    471         if (found_event['data']['Result']['deviceInfo']['address'] !=
    472                 mac_address):
    473             test_result = False
    474         self.scn_ad.droid.bleStopBleScan(scan_callback2)
    475         self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
    476         return test_result
    477