Beispiel #1
0
    def test_discover_opportunistic_scan_result_off_secondary_scan_filter(
            self):
        """Test opportunistic scan result from secondary scan filter.

        Tests opportunistic scan where the secondary scan instance does not find
        an advertisement but the scan instance with scan mode set to
        opportunistic scan will find an advertisement.

        Steps:
        1. Initialize advertiser and start advertisement on dut1 (make sure the
        advertisement is not advertising the device name)
        2. Set scan settings to opportunistic scan on dut0 scan instance
        3. Start scan scan from step 2
        4. Try to find an event, expect none
        5. Start a second scanner on dut0, with any other mode set and set the
        scan filter device name to "opp_test"
        6. Pop onScanResults from the second scanner
        7. Expect no events
        8. Pop onScanResults from the first scanner

        Expected Result:
        Opportunistic scan instance finds an advertisement.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Scanning, Opportunistic Scan
        Priority: 1
        """
        self._setup_generic_advertisement()
        self.scn_ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['opportunistic'])
        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
            self.scn_ad.droid)

        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)
        self.active_scan_callback_list.append(scan_callback)
        if not self._verify_no_events_found(scan_result.format(scan_callback)):
            return False
        self.scn_ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['low_latency'])
        self.scn_ad.droid.bleSetScanFilterDeviceName("opp_test")
        filter_list2, scan_settings2, scan_callback2 = (
            generate_ble_scan_objects(self.scn_ad.droid))
        self.scn_ad.droid.bleBuildScanFilter(filter_list2)
        self.scn_ad.droid.bleStartBleScan(filter_list2, scan_settings2,
                                          scan_callback2)
        self.active_scan_callback_list.append(scan_callback2)
        if not self._verify_no_events_found(
                scan_result.format(scan_callback2)):
            return False
        try:
            self.scn_ad.ed.pop_event(scan_result.format(scan_callback),
                                     self.default_timeout)
        except Empty:
            self.log.error("Opportunistic scan found no scan results.")
            return False
        return True
Beispiel #2
0
    def test_scan_result(self):
        """Test opportunistic scan with an advertisement.

        Tests opportunistic scan where it will only report scan results when
        other registered scanners find results.

        Steps:
        1. Initialize advertiser and start advertisement on dut1
        2. Initialize scanner with scan mode set to opportunistic mode on dut0
        and start scanning
        3. Try to find an event, expect none.
        4. Start a second scanner on dut0, with any other mode set
        5. Pop onScanResults event on the second scanner
        6. Pop onScanResults event on the first scanner

        Expected Result:
        Scan result is found on the opportunistic scan instance.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Scanning, Opportunistic Scan
        Priority: 1
        """
        self._setup_generic_advertisement()
        self.scn_ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['opportunistic'])
        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
            self.scn_ad.droid)

        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)
        self.active_scan_callback_list.append(scan_callback)
        if not self._verify_no_events_found(scan_result.format(scan_callback)):
            return False
        self.scn_ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['low_latency'])
        filter_list2, scan_settings2, scan_callback2 = (
            generate_ble_scan_objects(self.scn_ad.droid))
        self.scn_ad.droid.bleStartBleScan(filter_list2, scan_settings2,
                                          scan_callback2)
        self.active_scan_callback_list.append(scan_callback2)
        try:
            self.scn_ad.ed.pop_event(scan_result.format(scan_callback2),
                                     self.default_timeout)
        except Empty:
            self.log.error("Non-Opportunistic scan found no scan results.")
            return False
        try:
            self.scn_ad.ed.pop_event(scan_result.format(scan_callback),
                                     self.default_timeout)
        except Empty:
            self.log.error("Opportunistic scan found no scan results.")
            return False
        return True
    def test_anonymous_advertising(self):
        """Test anonymous advertising.

        Tests test verify that device is able to receive anonymous advertising
        on 1M PHY when secondary is 2M PHY.

        Steps:
        1. Start anonymous advertising set on dut1
        2. Start scanning on dut0, scan filter set to advertiser's device name
        3. Try to find an event, expect found
        4. Stop advertising

        Expected Result:
        Scan finds a advertisement.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE Advertising Extension, BT5, LE, Advertising, Scanning
        Priority: 1
        """
        adv_callback = self.adv_ad.droid.bleAdvSetGenCallback()
        self.adv_ad.droid.bleAdvSetStartAdvertisingSet({
            "connectable": False,
            "anonymous": True,
            "legacyMode": False,
            "primaryPhy": "PHY_LE_1M",
            "secondaryPhy": "PHY_LE_2M",
            "interval": 320
        }, self.big_adv_data, None, None, None, 0, 0, adv_callback)

        self.scn_ad.droid.bleSetScanSettingsLegacy(False)
        self.scn_ad.droid.bleSetScanSettingsPhy(ble_scan_settings_phys['1m'])

        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
            self.scn_ad.droid)

        adv_device_name = self.adv_ad.droid.bluetoothGetLocalName()
        self.scn_ad.droid.bleSetScanFilterDeviceName(adv_device_name)
        self.scn_ad.droid.bleBuildScanFilter(filter_list)
        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)
        self.active_scan_callback_list.append(scan_callback)

        try:
            evt = self.scn_ad.ed.pop_event(
                scan_result.format(scan_callback), self.default_timeout)
            address = evt['data']['Result']['deviceInfo']['address']
            asserts.assert_true(
                '00:00:00:00:00:00' == address,
                "Anonymous address should be 00:00:00:00:00:00, but was " +
                str(address))
        except Empty:
            self.log.error("Scan result not found")
            self.adv_ad.droid.bleAdvSetStopAdvertisingSet(adv_callback)
            return False

        self.adv_ad.droid.bleAdvSetStopAdvertisingSet(adv_callback)
        return True
Beispiel #4
0
    def test_scan_result_no_advertisement(self):
        """Test opportunistic scan with no advertisement.

        Tests opportunistic scan where there are no advertisements. This should
        not find any onScanResults.

        Steps:
        1. Initialize scanner with scan mode set to opportunistic mode.
        2. Start scanning on dut 0
        3. Pop onScanResults event on the scanner

        Expected Result:
        Find no advertisements with the opportunistic scan instance.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Scanning, Opportunistic Scan
        Priority: 1
        """
        self.scn_ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['opportunistic'])
        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
            self.scn_ad.droid)
        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)
        self.active_scan_callback_list.append(scan_callback)
        if not self._verify_no_events_found(scan_result.format(scan_callback)):
            return False
        self.scn_ad.droid.bleStopBleScan(scan_callback)
        return True
    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.scn_ad.droid.bleSetScanFilterServiceUuid(service_uuid,
                                                      service_mask)
        self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
            ble_advertise_settings_modes['low_latency'])
        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
            self.scn_ad.droid)
        expected_event_name = scan_result.format(scan_callback)
        self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
        self.adv_ad.droid.bleSetAdvertiseDataIncludeTxPowerLevel(True)
        advertise_callback, advertise_data, advertise_settings = (
            generate_ble_advertise_objects(self.adv_ad.droid))
        self.adv_ad.droid.bleStartBleAdvertising(advertise_callback,
                                                 advertise_data,
                                                 advertise_settings)
        self.scn_ad.droid.bleSetScanFilterDeviceName(
            self.adv_ad.droid.bluetoothGetLocalName())
        self.scn_ad.droid.bleBuildScanFilter(filter_list)
        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)
        worker = self.scn_ad.ed.handle_event(
            self.blescan_verify_onscanresult_event_handler,
            expected_event_name, ([1]), self.default_timeout)
        try:
            event_info = self.scn_ad.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_ad.droid.bleStopBleScan(scan_callback)
        self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
        return test_result
Beispiel #6
0
    def test_batch_scan_result_not_expected(self):
        """Test opportunistic batch scan without expecting an event.

        Tests opportunistic scan where it will only report scan results when
        other registered scanners find results. Set the report delay millis such
        that a batch scan is not expected.

        Steps:
        1. Initialize advertiser and start advertisement on dut1
        2. Initialize scanner with scan mode set to opportunistic mode and
        set scan settings report delay seconds such that a batch scan is
        expected.
        3. Start scanning on dut 0
        4. Try to find an event, expect none.
        5. Start a second scanner on dut0, with any other mode set and set scan
        settings report delay millis to 0 such that an onBatchScanResult is not
        expected.
        6. Pop onScanResults event on the second scanner
        7. Pop onBatchScanResult event on the first scanner

        Expected Result:
        Batch scan result is not expected on opportunistic scan instance.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Scanning, Opportunistic Scan, Batch Scanning
        Priority: 1
        """
        self._setup_generic_advertisement()
        self.scn_ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['opportunistic'])
        self.scn_ad.droid.bleSetScanSettingsReportDelayMillis(
            self.report_delay)
        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
            self.scn_ad.droid)
        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)
        self.active_scan_callback_list.append(scan_callback)
        if not self._verify_no_events_found(
                batch_scan_result.format(scan_callback)):

            return False
        self.scn_ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['low_latency'])
        filter_list2, scan_settings2, scan_callback2 = (
            generate_ble_scan_objects(self.scn_ad.droid))
        self.scn_ad.droid.bleStartBleScan(filter_list2, scan_settings2,
                                          scan_callback2)
        self.active_scan_callback_list.append(scan_callback2)
        try:
            self.scn_ad.ed.pop_event(scan_result.format(scan_callback2),
                                     self.default_timeout)
        except Empty:
            self.log.error("Non-Opportunistic scan found no scan results.")
            return False
        return self._verify_no_events_found(
            batch_scan_result.format(scan_callback))
Beispiel #7
0
    def test_legacy_scan_result_raw_length(self):
        """Test that raw scan record data in legacy scan is 62 bytes long.

        This is required for compability with older apps that make this
        assumption.

        Steps:
        1. Start legacy advertising set on dut1
        2. Start scanning on dut0, scan filter set to advertiser's device name
        3. Try to find an event, expect found, verify scan recurd data length
        4. Stop advertising

        Expected Result:
        Scan finds a legacy advertisement of proper size

        Returns:
          Pass if True
          Fail if False

        TAGS: LE Advertising Extension, BT5, LE, Advertising, Scanning
        Priority: 1
        """
        adv_callback = self.adv_ad.droid.bleAdvSetGenCallback()
        self.adv_ad.droid.bleAdvSetStartAdvertisingSet(
            {
                "connectable": True,
                "scannable": True,
                "legacyMode": True,
                "interval": 320
            }, {"includeDeviceName": True}, None, None, None, 0, 0,
            adv_callback)

        self.scn_ad.droid.bleSetScanSettingsLegacy(True)
        self.scn_ad.droid.bleSetScanSettingsPhy(ble_scan_settings_phys['1m'])

        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
            self.scn_ad.droid)

        adv_device_name = self.adv_ad.droid.bluetoothGetLocalName()
        self.scn_ad.droid.bleSetScanFilterDeviceName(adv_device_name)
        self.scn_ad.droid.bleBuildScanFilter(filter_list)
        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)
        self.active_scan_callback_list.append(scan_callback)

        try:
            evt = self.scn_ad.ed.pop_event(scan_result.format(scan_callback),
                                           self.default_timeout)
            rawData = evt['data']['Result']['scanRecord']
            asserts.assert_true(62 == len(rawData.split(",")),
                                "Raw data should be 62 bytes long.")
        except Empty:
            self.log.error("Scan result not found")
            self.adv_ad.droid.bleAdvSetStopAdvertisingSet(adv_callback)
            return False

        self.adv_ad.droid.bleAdvSetStopAdvertisingSet(adv_callback)
        return True
Beispiel #8
0
    def test_background_scan(self):
        """Test generic background scan.

        Tests LE background scan. The goal is to find scan results even though
        Bluetooth is turned off.

        Steps:
        1. Setup an advertisement on dut1
        2. Enable LE on the Bluetooth Adapter on dut0
        3. Toggle BT off on dut1
        4. Start a LE scan on dut0
        5. Find the advertisement from dut1

        Expected Result:
        Find a advertisement from the scan instance.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Scanning, Background Scanning
        Priority: 0
        """
        import time
        self._setup_generic_advertisement()
        self.scn_ad.droid.bluetoothToggleState(False)
        try:
            self.scn_ad.ed.pop_event(bluetooth_off, self.default_timeout)
        except Empty:
            self.log.error("Bluetooth Off event not found. Expected {}".format(
                bluetooth_off))
            return False
        self.scn_ad.droid.bluetoothDisableBLE()
        try:
            self.scn_ad.ed.pop_event(bluetooth_off, self.default_timeout)
        except Empty:
            self.log.error("Bluetooth Off event not found. Expected {}".format(
                bluetooth_off))
            return False
        self.scn_ad.droid.bluetoothEnableBLE()
        try:
            self.scn_ad.ed.pop_event(bluetooth_off, self.default_timeout * 2)
        except Empty:
            self.log.error("Bluetooth On event not found. Expected {}".format(
                bluetooth_on))
            return False
        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
            self.scn_ad.droid)
        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)
        expected_event = scan_result.format(scan_callback)
        try:
            self.scn_ad.ed.pop_event(expected_event, self.default_timeout)
        except Empty:
            self.log.error("Scan Result event not found. Expected {}".format(
                expected_event))
            return False
        return True
Beispiel #9
0
 def _scan_found_results(self):
     try:
         self.scn_ad.ed.pop_event(scan_result.format(self.scan_callback),
                                  bt_default_timeout)
         self.log.info("Found an advertisement.")
     except Empty:
         self.log.info("Did not find an advertisement.")
         return False
     return True
    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_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
        self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
            ble_advertise_settings_modes['low_latency'])
        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
            self.scn_ad.droid)
        expected_event_name = scan_result.format(scan_callback)
        advertise_callback, advertise_data, advertise_settings = (
            generate_ble_advertise_objects(self.adv_ad.droid))
        self.adv_ad.droid.bleStartBleAdvertising(advertise_callback,
                                                 advertise_data,
                                                 advertise_settings)
        self.scn_ad.droid.bleSetScanFilterDeviceName(
            self.adv_ad.droid.bluetoothGetLocalName())
        self.scn_ad.droid.bleBuildScanFilter(filter_list)

        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)
        self.scn_ad.droid.bleFlushPendingScanResults(scan_callback)
        worker = self.scn_ad.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.error("Test failed with Empty error: {}".format(error))
        except concurrent.futures._base.TimeoutError as error:
            test_result = False
            self.log.error("Test failed with TimeoutError: {}".format(error))
        self.scn_ad.droid.bleStopBleScan(scan_callback)
        self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
        return test_result
Beispiel #11
0
    def test_background_scan_ble_disabled(self):
        """Test background LE scanning with LE disabled.

        Tests LE background scan. The goal is to find scan results even though
        Bluetooth is turned off.

        Steps:
        1. Setup an advertisement on dut1
        2. Enable LE on the Bluetooth Adapter on dut0
        3. Toggle BT off on dut1
        4. Start a LE scan on dut0
        5. Find the advertisement from dut1

        Expected Result:
        Find a advertisement from the scan instance.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Scanning, Background Scanning
        Priority: 0
        """
        self._setup_generic_advertisement()
        self.scn_ad.droid.bluetoothEnableBLE()
        self.scn_ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['low_latency'])
        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
            self.scn_ad.droid)
        self.scn_ad.droid.bleSetScanFilterDeviceName(
            self.adv_ad.droid.bluetoothGetLocalName())
        self.scn_ad.droid.bleBuildScanFilter(filter_list)
        self.scn_ad.droid.bluetoothToggleState(False)
        try:
            self.scn_ad.ed.pop_event(bluetooth_off, self.default_timeout)
        except Empty:
            self.log.info(self.scn_ad.droid.bluetoothCheckState())
            self.log.error("Bluetooth Off event not found. Expected {}".format(
                bluetooth_off))
            return False
        try:
            self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                              scan_callback)
            expected_event = scan_result.format(scan_callback)
            try:
                self.scn_ad.ed.pop_event(expected_event, self.default_timeout)
            except Empty:
                self.log.error(
                    "Scan Result event not found. Expected {}".format(
                        expected_event))
                return False
        except Exception:
            self.log.info(
                "Was not able to start a background scan as expected.")
        return True
Beispiel #12
0
    def test_max_opportunistic_scan_instances(self):
        """Test max number of opportunistic scan instances.

        Tests max instances of opportunistic scans. Each instances should
        find an onScanResults event.

        Steps:
        1. Initialize advertiser and start advertisement on dut1
        2. Set scan settings to opportunistic scan on dut0 scan instance
        3. Start scan scan from step 2
        4. Repeat step two and three until there are max_scan_instances-1 scan
        instances
        5. Start a regular ble scan on dut0 with the last available scan
        instance
        6. Pop onScanResults event on all scan instances

        Expected Result:
        Each opportunistic scan instance finds a advertisement.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Scanning, Opportunistic Scan
        Priority: 1
        """
        self._setup_generic_advertisement()
        for _ in range(self.max_scan_instances - 1):
            self.scn_ad.droid.bleSetScanSettingsScanMode(
                ble_scan_settings_modes['opportunistic'])
            filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
                self.scn_ad.droid)
            self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                              scan_callback)
            self.active_scan_callback_list.append(scan_callback)

        self.scn_ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['low_latency'])
        filter_list2, scan_settings2, scan_callback2 = (
            generate_ble_scan_objects(self.scn_ad.droid))
        self.scn_ad.droid.bleStartBleScan(filter_list2, scan_settings2,
                                          scan_callback2)
        self.active_scan_callback_list.append(scan_callback2)

        for callback in self.active_scan_callback_list:
            try:
                self.scn_ad.ed.pop_event(scan_result.format(callback),
                                         self.default_timeout)
            except Empty:
                self.log.error(
                    "No scan results found for callback {}".format(callback))
                return False
        return True
Beispiel #13
0
    def test_duration(self):
        """Test scanning duration

        Tests BT5.0 scanning duration

        Steps:
        1. Start advertising set
        2. Start 5.0 scan
        3. Scan for advertisement event

        Expected Result:
        Scan finds a legacy advertisement of proper size

        Returns:
          Pass if True
          Fail if False

        TAGS: BT5.0, LE, Advertising, Scanning
        Priority: 1
        """
        adv_callback = self.adv_ad.droid.bleAdvSetGenCallback()
        self.adv_ad.droid.bleAdvSetStartAdvertisingSet(
            {
                "connectable": True,
                "legacyMode": False,
                "primaryPhy": "PHY_LE_1M",
                "secondaryPhy": "PHY_LE_2M",
                "interval": 320
            }, self.big_adv_data, None, None, None, 0, 0, adv_callback)

        self.scn_ad.droid.bleSetScanSettingsLegacy(False)
        self.scn_ad.droid.bleSetScanSettingsPhy(ble_scan_settings_phys['1m'])

        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
            self.scn_ad.droid)

        adv_device_name = self.adv_ad.droid.bluetoothGetLocalName()
        self.scn_ad.droid.bleSetScanFilterDeviceName(adv_device_name)
        self.scn_ad.droid.bleBuildScanFilter(filter_list)
        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)
        self.active_scan_callback_list.append(scan_callback)

        try:
            self.scn_ad.ed.pop_event(scan_result.format(scan_callback),
                                     self.default_timeout)
        except Empty:
            self.log.error("Scan result not found")
            self.adv_ad.droid.bleAdvSetStopAdvertisingSet(adv_callback)
            return False

        self.adv_ad.droid.bleAdvSetStopAdvertisingSet(adv_callback)
        return True
    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_ad.droid.bluetoothGetLocalName())
        self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
        self.scn_ad.droid.bleSetScanFilterDeviceName(filter_name)
        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
            self.scn_ad.droid)
        self.scn_ad.droid.bleBuildScanFilter(filter_list)
        expected_event_name = scan_result.format(scan_callback)
        self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
        self.adv_ad.droid.bleSetAdvertiseDataIncludeTxPowerLevel(True)
        advertise_callback, advertise_data, advertise_settings = (
            generate_ble_advertise_objects(self.adv_ad.droid))
        self.adv_ad.droid.bleStartBleAdvertising(advertise_callback,
                                                 advertise_data,
                                                 advertise_settings)
        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)
        try:
            event_info = self.scn_ad.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_ad.droid.bleStopBleScan(scan_callback)
        self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
        return test_result
Beispiel #15
0
    def test_fuchsia_adv_android_scan(self):
        #Initialize advertising on fuchsia device with name and interval
        fuchsia_name = "testADV123"
        adv_data = {
            "name": fuchsia_name,
            "appearance": None,
            "service_data": None,
            "tx_power_level": None,
            "service_uuids": None,
            "manufacturer_data": None,
            "uris": None,
        }
        scan_response = None
        connectable = True
        interval = 1000

        #Start advertising
        self.fd.ble_lib.bleStartBleAdvertising(adv_data, scan_response,
                                               interval, connectable)

        # Initialize scan on android device which scan settings + callback
        filter_list = self.ad.droid.bleGenFilterList()
        self.ad.droid.bleSetScanFilterDeviceName(fuchsia_name)
        self.ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['low_latency'])
        scan_settings = self.ad.droid.bleBuildScanSetting()
        scan_callback = self.ad.droid.bleGenScanCallback()
        self.ad.droid.bleBuildScanFilter(filter_list)
        self.ad.droid.bleStartBleScan(filter_list, scan_settings,
                                      scan_callback)
        event_name = scan_result.format(scan_callback)
        try:
            event = self.ad.ed.pop_event(event_name, self.default_timeout)
            self.log.info("Found scan result: {}".format(
                pprint.pformat(event)))
        except Exception:
            self.log.error("Didn't find any scan results.")
            return False
        finally:
            self.fd.ble_lib.bleStopBleAdvertising()
            self.ad.droid.bleStopBleScan(scan_callback)
        # TODO(): Validate result
        return True
    def _is_peripheral_advertising(self):
        self.cen_ad.droid.bleSetScanFilterDeviceAddress(self.ble_mac_address)
        self.cen_ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['low_latency'])
        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
            self.cen_ad.droid)
        self.cen_ad.droid.bleBuildScanFilter(filter_list)

        self.cen_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)
        expected_event_name = scan_result.format(scan_callback)
        test_result = True
        try:
            self.cen_ad.ed.pop_event(expected_event_name, self.DEFAULT_TIMEOUT)
            self.log.info(
                "Peripheral found with event: {}".format(expected_event_name))
        except Empty:
            self.log.info("Peripheral not advertising or not found: {}".format(
                self.ble_mac_address))
            test_result = False
        self.cen_ad.droid.bleStopBleScan(scan_callback)
        return test_result
    def test_loop_scanning_100_verify_no_hci_timeout(self):
        """Stress start/stop scan instances variant.

        This test will start and stop scan instances with a one second timeout
        in between each iteration. This testcase was added because the specific
        timing combination caused hci timeouts.

        Steps:
        1. Start a scan instance.
        2. Stop the scan instance.
        3. Sleep for 1 second.
        4. Repeat steps 1-3 100 times.

        Expected Result:
        Neither starting or stopping scan instances causes any failures.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Scanning, Stress
        Priority: 1
        """
        for _ in range(self.droid_list[1]['max_advertisements']):
            adv_callback, adv_data, adv_settings = generate_ble_advertise_objects(
                self.adv_ad.droid)
            self.adv_ad.droid.bleStartBleAdvertising(adv_callback, adv_data,
                                                     adv_settings)
        for _ in range(100):
            filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
                self.scn_ad.droid)
            self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                              scan_callback)
            self.log.info(
                self.scn_ad.ed.pop_event(scan_result.format(scan_callback)))
            self.scn_ad.droid.bleStopBleScan(scan_callback)
            time.sleep(1)
        return True
Beispiel #18
0
    def connect_over_le_based_off_name(self, autoconnect, name):
        """Perform GATT connection over LE"""
        self.dut.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['low_latency'])
        filter_list = self.dut.droid.bleGenFilterList()
        scan_settings = self.dut.droid.bleBuildScanSetting()
        scan_callback = self.dut.droid.bleGenScanCallback()
        event_name = scan_result.format(scan_callback)
        self.dut.droid.bleSetScanFilterDeviceName("BLE Rect")
        self.dut.droid.bleBuildScanFilter(filter_list)
        self.dut.droid.bleStartBleScan(filter_list, scan_settings,
                                       scan_callback)

        try:
            event = self.dut.ed.pop_event(event_name, 10)
            self.log.info("Found scan result: {}".format(event))
        except Exception:
            self.log.info("Didn't find any scan results.")
        mac_addr = event['data']['Result']['deviceInfo']['address']
        self.bluetooth_gatt, self.gatt_callback = setup_gatt_connection(
            self.dut, mac_addr, autoconnect, transport=gatt_transport['le'])
        self.dut.droid.bleStopBleScan(scan_callback)
        self.discovered_services_index = None
    def test_start_ble_scan(self):
        """Test to demonstrate how to start an LE scan

        Test that shows the steps to start a new ble scan.

        Steps:
        1. Create a scan filter object.
        2. Create a scan setting object.
        3. Create a scan callback object.
        4. Start an LE scan using the objects created in steps 1-3.
        5. Find an advertisement with the scanner's event dispatcher.

        Expected Result:
        A generic advertisement is found.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Scanning
        Priority: 4
        """
        filter_list = self.scn_droid.bleGenFilterList()
        scan_settings = self.scn_droid.bleBuildScanSetting()
        scan_callback = self.scn_droid.bleGenScanCallback()
        self.scn_droid.bleStartBleScan(filter_list, scan_settings,
                                       scan_callback)
        self.active_scan_callback_list.append(scan_callback)
        event_name = scan_result.format(scan_callback)
        try:
            event = self.scn_ed.pop_event(event_name, self.default_timeout)
            self.log.info("Found scan result: {}".format(
                pprint.pformat(event)))
        except Exception:
            self.log.info("Didn't find any scan results.")
        return True
Beispiel #20
0
def scan_and_verify_n_advertisements(scn_ad, max_advertisements):
    """Verify that input number of advertisements can be found from the scanning
    Android device.

    Args:
        scn_ad: The Android device to start LE scanning on.
        max_advertisements: The number of advertisements the scanner expects to
        find.

    Returns:
        True if successful, false if unsuccessful.
    """
    test_result = False
    address_list = []
    filter_list = scn_ad.droid.bleGenFilterList()
    scn_ad.droid.bleBuildScanFilter(filter_list)
    scan_settings = scn_ad.droid.bleBuildScanSetting()
    scan_callback = scn_ad.droid.bleGenScanCallback()
    scn_ad.droid.bleStartBleScan(filter_list, scan_settings, scan_callback)
    start_time = time.time()
    while (start_time + bt_default_timeout) > time.time():
        event = None
        try:
            event = scn_ad.ed.pop_event(
                scan_result.format(scan_callback), bt_default_timeout)
        except Empty as error:
            raise BtTestUtilsError("Failed to find scan event: {}".format(
                error))
        address = event['data']['Result']['deviceInfo']['address']
        if address not in address_list:
            address_list.append(address)
        if len(address_list) == max_advertisements:
            test_result = True
            break
    scn_ad.droid.bleStopBleScan(scan_callback)
    return test_result
Beispiel #21
0
    def test_max_concurrent_ble_scans_verify_scans_stop_independently(self):
        """Test max LE scans variant.

        Test that a single device can have max scans concurrently scanning.

        Steps:
        1. Initialize scanner
        2. Initialize advertiser
        3. Create max ble scan callbacks
        4. Start ble scan on each callback
        5. Start advertising on the device from step 2
        6. Verify that the first callback triggers
        7. Stop the scan and repeat steps 6 and 7 until all scans stopped

        Expected Result:
        All scanning instances should start without errors and the advertisement
        should be found on each scan instance. All scanning instances should
        stop successfully.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Scanning, Concurrency
        Priority: 1
        """
        self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
        self.scn_ad.droid.bleSetScanSettingsCallbackType(
            ble_scan_settings_callback_types['all_matches'])
        self.scn_ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['low_latency'])
        self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
            ble_advertise_settings_modes['low_latency'])
        advertise_callback, advertise_data, advertise_settings = (
            generate_ble_advertise_objects(self.adv_ad.droid))
        filter_list = self.scn_ad.droid.bleGenFilterList()
        self.scn_ad.droid.bleSetScanFilterDeviceName(
            self.adv_ad.droid.bluetoothGetLocalName())
        self.scn_ad.droid.bleBuildScanFilter(filter_list)
        scan_settings = self.scn_ad.droid.bleBuildScanSetting()
        scan_callback_list = []
        for i in range(self.max_concurrent_scans):
            self.log.debug("Concurrent Ble Scan iteration {}".format(i + 1))
            scan_callback = self.scn_ad.droid.bleGenScanCallback()
            scan_callback_list.append(scan_callback)
            self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                              scan_callback)
        self.adv_ad.droid.bleStartBleAdvertising(advertise_callback,
                                                 advertise_data,
                                                 advertise_settings)
        try:
            self.adv_ad.ed.pop_event(adv_succ.format(advertise_callback),
                                     self.default_timeout)
        except Empty as error:
            self.log.exception(
                "Test failed with Empty error: {}".format(error))
            return False
        except concurrent.futures._base.TimeoutError as error:
            self.log.exception(
                "Test failed, filtering callback onSuccess never"
                " occurred: {}".format(error))
            return False
        i = 0
        for callback in scan_callback_list:
            expected_scan_event_name = scan_result.format(scan_callback)
            try:
                self.scn_ad.ed.pop_event(expected_scan_event_name,
                                         self.default_timeout)
                self.log.info(
                    "Found scan event successfully. Iteration {} successful.".
                    format(i))
                i += 1
            except Exception:
                self.log.info(
                    "Failed to find a scan result for callback {}".format(
                        scan_callback))
                return False
            self.scn_ad.droid.bleStopBleScan(callback)
        self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
        return True
    def test_onlost_onfound_defaults(self):
        """Test generic onlost/onfound defaults.

        Tests basic onFound/onLost functionality.

        Steps:
        1. Setup dut0 scanner and start scan with this setup:
          Scan Mode: SCAN_MODE_LOW_LATENCY
          Callback Type: CALLBACK_TYPE_FOUND_AND_LOST
          Match Mode: AGGRESSIVE
          Num of Matches: MATCH_NUM_ONE_ADVERTISEMENT
          Filter: Device name of dut1
        2. Start an advertisement on dut1, include device name
        3. Find an onFound event
        4. Stop the advertisement on dut1
        5. Find an onLost event

        Expected Result:
        Find an onLost and an onFound event successfully.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Scanning, onLost, onFound
        Priority: 0
        """
        filter_list = self.scn_ad.droid.bleGenFilterList()
        self.scn_ad.droid.bleSetScanFilterDeviceName(
            self.adv_ad.droid.bluetoothGetLocalName())
        self.scn_ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['low_latency'])
        self.scn_ad.droid.bleSetScanSettingsCallbackType(
            ble_scan_settings_callback_types['found_and_lost'])
        self.scn_ad.droid.bleSetScanSettingsMatchMode(
            ble_scan_settings_match_modes['aggresive'])
        self.scn_ad.droid.bleSetScanSettingsNumOfMatches(
            ble_scan_settings_match_nums['one'])
        scan_settings = self.scn_ad.droid.bleBuildScanSetting()
        scan_callback = self.scn_ad.droid.bleGenScanCallback()
        self.scn_ad.droid.bleBuildScanFilter(filter_list)
        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)
        self.active_scan_callback_list.append(scan_callback)
        adv_callback = self._start_generic_advertisement_include_device_name()
        event = self.scn_ad.ed.pop_event(scan_result.format(scan_callback),
                                         self.default_timeout * 3)
        found_callback_type = event['data']['CallbackType']
        if event['data']['CallbackType'] != ble_scan_settings_callback_types[
                'first_match']:
            self.log.info(
                "Found Callbacreset_bluetoothkType:{}, Expected CallbackType:{}"
                .format(found_callback_type,
                        ble_scan_settings_callback_types['first_match']))
            return False
        self.adv_ad.droid.bleStopBleAdvertising(adv_callback)
        event = self.scn_ad.ed.pop_event(scan_result.format(scan_callback),
                                         self.default_timeout * 4)
        found_callback_type = event['data']['CallbackType']
        if found_callback_type != ble_scan_settings_callback_types[
                'match_lost']:
            self.log.info(
                "Found CallbackType:{}, Expected CallbackType:{}".format(
                    found_callback_type,
                    ble_scan_settings_callback_types['match_lost']))
            return False
        return True
Beispiel #23
0
    def test_opportunistic_scan_filter_result_off_secondary_scan_result(self):
        """Test opportunistic scan from a secondary scan result.

        Tests opportunistic scan where the scan filters are the same between the
        first scan instance with opportunistic scan set and the second instance
        with any other mode set.

        Steps:
        1. Initialize advertiser and start advertisement on dut1
        2. On dut0, set the scan settings mode to opportunistic scan and set
        the scan filter device name to the advertiser's device name
        3. Start scan scan from step 2
        4. Try to find an event, expect none
        5. Start a second scanner on dut0, with any other mode set and set the
        scan filter device name to the advertiser's device name
        6. Pop onScanResults from the second scanner
        7. Pop onScanResults from the first scanner

        Expected Result:
        Opportunistic scan instance finds a advertisement.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Scanning, Opportunistic Scan
        Priority: 1
        """
        self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
        self._setup_generic_advertisement()
        adv_device_name = self.adv_ad.droid.bluetoothGetLocalName()
        self.scn_ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['opportunistic'])
        self.scn_ad.droid.bleSetScanFilterDeviceName(adv_device_name)
        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
            self.scn_ad.droid)
        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)
        self.active_scan_callback_list.append(scan_callback)
        if not self._verify_no_events_found(scan_result.format(scan_callback)):
            return False
        self.scn_ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['low_latency'])
        filter_list2, scan_settings2, scan_callback2 = (
            generate_ble_scan_objects(self.scn_ad.droid))
        self.scn_ad.droid.bleSetScanFilterDeviceName(adv_device_name)
        self.scn_ad.droid.bleBuildScanFilter(filter_list2)
        self.scn_ad.droid.bleStartBleScan(filter_list2, scan_settings2,
                                          scan_callback2)
        self.active_scan_callback_list.append(scan_callback2)
        try:
            self.scn_ad.ed.pop_event(scan_result.format(scan_callback2),
                                     self.default_timeout)
        except Empty:
            self.log.error("Opportunistic scan found no scan results.")
            return False
        try:
            self.scn_ad.ed.pop_event(scan_result.format(scan_callback),
                                     self.default_timeout)
        except Empty:
            self.log.error("Non-Opportunistic scan found no scan results.")
            return False
        return True
Beispiel #24
0
    def test_opportunistic_scan_no_filters_screen_off_then_on(self):
        """Test opportunistic scanning does not find results with screen off.

        Test LE scanning is successful with no filters and screen off. No scan
        results should be found.

        Steps:
        1. Setup advertisement
        2. Turn off screen
        3. Start opportunistic scan without filters
        4. Start scan without filters
        5. Verify no scan results are found on either scan instance
        6. Wake up phone
        7. Verify scan results on each scan instance
        8. Teardown advertisement and scanner

        Expected Result:
        No scan results should be found.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Filtering, Scanning, Screen
        Priority: 1
        """
        # Step 1
        if not self._setup_generic_advertisement():
            return False

        # Step 2
        self.scn_ad.droid.goToSleepNow()
        # Give the device time to go to sleep
        time.sleep(2)

        # Step 3
        self.scn_ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['opportunistic'])
        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
            self.scn_ad.droid)
        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)

        # Step 4
        filter_list2, scan_settings2, scan_callback2 = generate_ble_scan_objects(
            self.scn_ad.droid)
        self.scn_ad.droid.bleStartBleScan(filter_list2, scan_settings2,
                                          scan_callback2)

        # Step 5
        try:
            self.scn_ad.ed.pop_event(scan_result.format(scan_callback),
                                     self.shorter_scan_timeout)
            self.log.error("Found an advertisement on opportunistic scan.")
            return False
        except Empty:
            self.log.info("Did not find an advertisement.")
        try:
            self.scn_ad.ed.pop_event(scan_result.format(scan_callback2),
                                     self.shorter_scan_timeout)
            self.log.error("Found an advertisement on scan instance.")
            return False
        except Empty:
            self.log.info("Did not find an advertisement.")

        # Step 6
        self.scn_ad.droid.wakeUpNow()

        # Step 7
        try:
            self.scn_ad.ed.pop_event(scan_result.format(scan_callback),
                                     self.shorter_scan_timeout)
            self.log.info("Found an advertisement on opportunistic scan.")
        except Empty:
            self.log.error(
                "Did not find an advertisement on opportunistic scan.")
            return False
        try:
            self.scn_ad.ed.pop_event(scan_result.format(scan_callback2),
                                     self.shorter_scan_timeout)
            self.log.info("Found an advertisement on scan instance.")
        except Empty:
            self.log.info("Did not find an advertisement.")
            return False

        # Step 8
        self.adv_ad.droid.bleStopBleAdvertising(self.advertise_callback)
        self.scn_ad.droid.bleStopBleScan(scan_callback)
        self.scn_ad.droid.bleStopBleScan(scan_callback2)
        return True
    def test_toggle_advertiser_bt_state(self):
        """Test forcing stopping advertisements.

        Test that a single device resets its callbacks when the bluetooth state is
        reset. There should be no advertisements.

        Steps:
        1. Setup the scanning android device.
        2. Setup the advertiser android device.
        3. Call start ble advertising.
        4. Toggle bluetooth on and off.
        5. Scan for any advertisements.

        Expected Result:
        No advertisements should be found after toggling Bluetooth on the
        advertising device.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Concurrency
        Priority: 2
        """
        test_result = True
        self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
        advertise_callback, advertise_data, advertise_settings = (
            generate_ble_advertise_objects(self.adv_ad.droid))
        self.adv_ad.droid.bleStartBleAdvertising(advertise_callback,
                                                 advertise_data,
                                                 advertise_settings)
        try:
            self.adv_ad.ed.pop_event(adv_succ.format(advertise_callback),
                                     self.default_timeout)
        except Empty as error:
            self.log.error("Test failed with Empty error: {}".format(error))
            return False
        except concurrent.futures._base.TimeoutError as error:
            self.log.error(
                "Test failed, filtering callback onSuccess never occurred: {}".
                format(error))
        self.scn_ad.droid.bleSetScanFilterDeviceName(
            self.adv_ad.droid.bluetoothGetLocalName())
        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
            self.scn_ad.droid)
        self.scn_ad.droid.bleBuildScanFilter(filter_list)
        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)
        try:
            self.scn_ad.ed.pop_event(scan_result.format(scan_callback),
                                     self.default_timeout)
        except Empty as error:
            self.log.error("Test failed with: {}".format(error))
            return False
        self.scn_ad.droid.bleStopBleScan(scan_callback)
        test_result = reset_bluetooth([self.android_devices[1]])
        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)
        if not test_result:
            return False
        try:
            expected_event = scan_result.format(scan_callback)
            event = self.scn_ad.ed.pop_event(expected_event,
                                             self.default_timeout)
            self.log.error("Event {} not expected. Found: {}".format(
                expected_event, event))
            return False
        except Empty as error:
            self.log.debug("Test passed with: {}".format(error))
        self.scn_ad.droid.bleStopBleScan(scan_callback)
        self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
        return True
Beispiel #26
0
    def test_max_scan_no_filters_screen_off_then_turn_on(self):
        """Test start max scans with no filters while screen is off then turn on

        Test that max LE scan without filters will not return results while the
        screen is off but will return results when the screen turns on.

        Steps:
        1. Setup advertisement
        2. Turn off screen
        3. Start scanner without filters and verify no scan results
        4. Turn screen on
        5. Verify scan results are found on each scan callback
        6. Teardown advertisement and all scanner

        Expected Result:
        Scan results should only come in when the screen is on.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Filtering, Scanning, Screen
        Priority: 2
        """
        # Step 1
        if not self._setup_generic_advertisement():
            return False

        # Step 2
        self.scn_ad.droid.goToSleepNow()
        # Give the device time to go to sleep
        time.sleep(2)

        # Step 3
        scan_callback_list = []
        for _ in range(self.max_concurrent_scans):
            filter_list, scan_settings, scan_callback = \
                generate_ble_scan_objects(self.scn_ad.droid)
            self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                              scan_callback)
            scan_callback_list.append(scan_callback)
            try:
                self.scn_ad.ed.pop_event(
                    scan_result.format(self.scan_callback),
                    self.shorter_scan_timeout)
                self.log.info("Found an advertisement.")
                return False
            except Empty:
                self.log.info("Did not find an advertisement.")

        # Step 4
        self.scn_ad.droid.wakeUpNow()

        # Step 5
        for callback in scan_callback_list:
            try:
                self.scn_ad.ed.pop_event(scan_result.format(callback),
                                         self.shorter_scan_timeout)
                self.log.info("Found an advertisement.")
            except Empty:
                self.log.info("Did not find an advertisement.")
                return False

        # Step 7
        self.adv_ad.droid.bleStopBleAdvertising(self.advertise_callback)
        for callback in scan_callback_list:
            self.scn_ad.droid.bleStopBleScan(callback)
        return True
    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_ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['low_latency'])
        filter_list, scan_settings, scan_callback = generate_ble_scan_objects(
            self.scn_ad.droid)
        expected_event_name = scan_result.format(scan_callback)
        self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
            ble_advertise_settings_modes['low_latency'])
        self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
        advertise_callback, advertise_data, advertise_settings = (
            generate_ble_advertise_objects(self.adv_ad.droid))
        self.adv_ad.droid.bleStartBleAdvertising(advertise_callback,
                                                 advertise_data,
                                                 advertise_settings)
        self.scn_ad.droid.bleSetScanFilterDeviceName(
            self.adv_ad.droid.bluetoothGetLocalName())
        self.scn_ad.droid.bleBuildScanFilter(filter_list)
        self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)
        try:
            event_info = self.scn_ad.ed.pop_event(expected_event_name,
                                                  self.default_timeout)
        except Empty as error:
            self.log.error("Could not find initial advertisement.")
            return False
        mac_address = event_info['data']['Result']['deviceInfo']['address']
        self.log.info(
            "Filter advertisement with address {}".format(mac_address))
        self.scn_ad.droid.bleStopBleScan(scan_callback)
        self.scn_ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['low_latency'])
        self.scn_ad.droid.bleSetScanFilterDeviceAddress(mac_address)
        filter_list2, scan_settings2, scan_callback2 = (
            generate_ble_scan_objects(self.scn_ad.droid))

        self.scn_ad.droid.bleBuildScanFilter(filter_list2)
        self.scn_ad.droid.bleStartBleScan(filter_list2, scan_settings2,
                                          scan_callback2)
        expected_event_name = scan_result.format(scan_callback2)
        found_event = self.scn_ad.ed.pop_event(expected_event_name,
                                               self.default_timeout)
        if (found_event['data']['Result']['deviceInfo']['address'] !=
                mac_address):
            test_result = False
        self.scn_ad.droid.bleStopBleScan(scan_callback2)
        self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
        return test_result
    def test_filter_manufacturer_id_bounds(self):
        """Test scan filtering of lower and upper bounds of allowed manu data

        This test will setup one Android device as an advertiser and the
        second as the scanner and test the upper and lower bounds of
        manufacturer data filtering

        Steps:
        1. Start an advertisement with manufacturer id set to 0x004c
        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
        """
        manufacturer_id_list = [0, 1, 65534, 65535]
        for manufacturer_id in manufacturer_id_list:
            self.adv_ad.droid.bleAddAdvertiseDataManufacturerId(
                manufacturer_id, [0x01])
            self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
                ble_advertise_settings_modes['low_latency'])
            advertise_callback, advertise_data, advertise_settings = (
                generate_ble_advertise_objects(self.adv_ad.droid))
            self.adv_ad.droid.bleStartBleAdvertising(advertise_callback,
                                                     advertise_data,
                                                     advertise_settings)
            expected_event = adv_succ.format(advertise_callback)
            try:
                self.adv_ad.ed.pop_event(expected_event)
            except Empty:
                self.log.info("Failed to start advertisement.")
                return False

            self.scn_ad.droid.bleSetScanSettingsScanMode(
                ble_scan_settings_modes['low_latency'])
            self.scn_ad.droid.bleSetScanFilterManufacturerData(
                manufacturer_id, [0x01])
            filter_list = self.scn_ad.droid.bleGenFilterList()
            scan_settings = self.scn_ad.droid.bleBuildScanSetting()
            scan_filter = self.scn_ad.droid.bleBuildScanFilter(filter_list)
            scan_callback = self.scn_ad.droid.bleGenScanCallback()
            self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                              scan_callback)
            expected_event_name = scan_result.format(scan_callback)
            event = None
            try:
                event = self.scn_ad.ed.pop_event(expected_event_name,
                                                 self.default_timeout)
            except Empty:
                self.log.error("Unable to find beacon advertisement.")
                return False
            found_manufacturer_id = json.loads(
                event['data']['Result']['manufacturerIdList'])
            if found_manufacturer_id[0] != manufacturer_id:
                self.log.error(
                    "Manufacturer id mismatch. Found {}, Expected {}".format(
                        found_manufacturer_id, manufacturer_id))
                return False
            self.scn_ad.droid.bleStopBleScan(scan_callback)
            self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
        return True
    def test_gatt_connect_second_adv_after_canceling_first_adv(self):
        """Test GATT connection to peripherals second advertising address.

        The the ability of cancelling GATT connections and trying to reconnect
        to the same device via a different address.

        Steps:
        1. A starts advertising
        2. B starts scanning and finds A's mac address
        3. Stop advertisement from step 1. Start a new advertisement on A and
            find the new new mac address, B knows of both old and new address.
        4. B1 sends connect request to old address of A
        5. B1 cancel connect attempt after 10 seconds
        6. B1 sends connect request to new address of A
        7. Verify B1 establish connection to A in less than 10 seconds

        Expected Result:
        Verify that a connection was established only on the second
            advertisement's mac address.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Advertising, Scanning, GATT
        Priority: 3
        """
        autoconnect = False
        transport = gatt_transport['auto']
        opportunistic = False
        # Setup a basic Gatt server on the peripheral
        gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback()
        gatt_server = self.per_ad.droid.gattServerOpenGattServer(
            gatt_server_cb)

        # Set advertisement settings to include local name in advertisement
        # and set the advertising mode to low_latency.
        self.per_ad.droid.bleSetAdvertiseSettingsIsConnectable(True)
        self.per_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
        self.per_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
            ble_advertise_settings_modes['low_latency'])

        # Setup necessary advertisement objects.
        advertise_data = self.per_ad.droid.bleBuildAdvertiseData()
        advertise_settings = self.per_ad.droid.bleBuildAdvertiseSettings()
        advertise_callback = self.per_ad.droid.bleGenBleAdvertiseCallback()

        # Step 1: Start advertisement
        self.per_ad.droid.bleStartBleAdvertising(advertise_callback,
                                                 advertise_data,
                                                 advertise_settings)

        # Setup scan settings for low_latency scanning and to include the local name
        # of the advertisement started in step 1.
        filter_list = self.cen_ad.droid.bleGenFilterList()
        self.cen_ad.droid.bleSetScanSettingsNumOfMatches(
            ble_scan_settings_match_nums['one'])
        self.cen_ad.droid.bleSetScanFilterDeviceName(
            self.per_ad.droid.bluetoothGetLocalName())
        self.cen_ad.droid.bleBuildScanFilter(filter_list)
        self.cen_ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['low_latency'])

        # Setup necessary scan objects.
        scan_settings = self.cen_ad.droid.bleBuildScanSetting()
        scan_callback = self.cen_ad.droid.bleGenScanCallback()

        # Step 2: Start scanning on central Android device and find peripheral
        # address.
        self.cen_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                          scan_callback)
        expected_event_name = scan_result.format(scan_callback)
        try:
            mac_address_pre_restart = self.cen_ad.ed.pop_event(
                expected_event_name, self.default_timeout
            )['data']['Result']['deviceInfo']['address']
            self.log.info(
                "Peripheral advertisement found with mac address: {}".format(
                    mac_address_pre_restart))
        except Empty:
            self.log.info("Peripheral advertisement not found")
            test_result = False

        # Step 3: Restart peripheral advertising such that a new mac address is
        # created.
        self.per_ad.droid.bleStopBleAdvertising(advertise_callback)
        self.per_ad.droid.bleStartBleAdvertising(advertise_callback,
                                                 advertise_data,
                                                 advertise_settings)

        try:
            mac_address_post_restart = self.cen_ad.ed.pop_event(
                expected_event_name, self.default_timeout
            )['data']['Result']['deviceInfo']['address']
            self.log.info(
                "Peripheral advertisement found with mac address: {}".format(
                    mac_address_post_restart))
        except Empty:
            self.log.info("Peripheral advertisement not found")
            test_result = False

        # Steps 4: Try to connect to the first mac address
        gatt_callback = self.cen_ad.droid.gattCreateGattCallback()
        self.log.info(
            "Gatt Connect to mac address {}.".format(mac_address_pre_restart))
        bluetooth_gatt = self.cen_ad.droid.gattClientConnectGatt(
            gatt_callback, mac_address_pre_restart, autoconnect, transport,
            opportunistic, gatt_phy_mask['1m_mask'])
        self.bluetooth_gatt_list.append(bluetooth_gatt)
        expected_event = gatt_cb_strings['gatt_conn_change'].format(
            gatt_callback)
        try:
            event = self.cen_ad.ed.pop_event(expected_event,
                                             self.default_timeout)
            self.log.error(
                "Connection callback updated unexpectedly: {}".format(event))
            return False
        except Empty:
            self.log.info("No connection update as expected.")

        # Step 5: Cancel connection request.
        self.cen_ad.droid.gattClientDisconnect(bluetooth_gatt)

        # Step 6: Connect to second mac address.
        self.log.info(
            "Gatt Connect to mac address {}.".format(mac_address_post_restart))
        bluetooth_gatt = self.cen_ad.droid.gattClientConnectGatt(
            gatt_callback, mac_address_post_restart, autoconnect, transport,
            opportunistic, gatt_phy_mask['1m_mask'])
        self.bluetooth_gatt_list.append(bluetooth_gatt)
        expected_event = gatt_cb_strings['gatt_conn_change'].format(
            gatt_callback)

        # Step 7: Verify connection was setup successfully.
        try:
            event = self.cen_ad.ed.pop_event(expected_event,
                                             self.default_timeout)
            self.log.info(
                "Connection callback updated successfully: {}".format(event))
            if event['data']['State'] != gatt_connection_state['connected']:
                self.log.error(
                    "Could not establish a connection to the peripheral.")
                return False
        except Empty:
            self.log.error("No connection update was found.")
            return False
        return self.cen_ad.droid.gattClientDisconnect(bluetooth_gatt)
Beispiel #30
0
    def test_max_concurrent_ble_scans(self):
        """Test max LE scans.

        Test that a single device can have max scans concurrently scanning.

        Steps:
        1. Initialize scanner
        2. Initialize advertiser
        3. Start advertising on the device from step 2
        4. Create max ble scan callbacks
        5. Start ble scan on each callback
        6. Verify that each callback triggers
        7. Stop all scans and advertisements

        Expected Result:
        All scanning instances should start without errors and the advertisement
        should be found on each scan instance.

        Returns:
          Pass if True
          Fail if False

        TAGS: LE, Scanning, Concurrency
        Priority: 0
        """
        test_result = True
        self.adv_ad.droid.bleSetAdvertiseDataIncludeDeviceName(True)
        self.scn_ad.droid.bleSetScanSettingsCallbackType(
            ble_scan_settings_callback_types['all_matches'])
        self.scn_ad.droid.bleSetScanSettingsScanMode(
            ble_scan_settings_modes['low_latency'])
        self.adv_ad.droid.bleSetAdvertiseSettingsAdvertiseMode(
            ble_advertise_settings_modes['low_latency'])
        advertise_callback, advertise_data, advertise_settings = (
            generate_ble_advertise_objects(self.adv_ad.droid))
        self.adv_ad.droid.bleSetAdvertiseSettingsIsConnectable(False)
        self.adv_ad.droid.bleStartBleAdvertising(advertise_callback,
                                                 advertise_data,
                                                 advertise_settings)
        try:
            self.adv_ad.ed.pop_event(adv_succ.format(advertise_callback),
                                     self.default_timeout)
        except Empty as error:
            self.log.exception(
                "Test failed with Empty error: {}".format(error))
            test_result = False
        except concurrent.futures._base.TimeoutError as error:
            self.log.exception(
                "Test failed callback onSuccess never occurred: "
                "{}".format(error))
            test_result = False
        if not test_result:
            return test_result
        filter_list = self.scn_ad.droid.bleGenFilterList()
        self.scn_ad.droid.bleSetScanFilterDeviceName(
            self.adv_ad.droid.bluetoothGetLocalName())
        self.scn_ad.droid.bleBuildScanFilter(filter_list)
        scan_settings = self.scn_ad.droid.bleBuildScanSetting()
        scan_callback_list = []
        for i in range(self.max_concurrent_scans):
            self.log.debug("Concurrent Ble Scan iteration {}".format(i + 1))
            scan_callback = self.scn_ad.droid.bleGenScanCallback()
            scan_callback_list.append(scan_callback)
            self.scn_ad.droid.bleStartBleScan(filter_list, scan_settings,
                                              scan_callback)
            try:
                self.scn_ad.ed.pop_event(scan_result.format(scan_callback),
                                         self.default_timeout)
                self.log.info("Found scan event successfully. Iteration {} "
                              "successful.".format(i))
            except Exception:
                self.log.info(
                    "Failed to find a scan result for callback {}".format(
                        scan_callback))
                test_result = False
                break
        for callback in scan_callback_list:
            self.scn_ad.droid.bleStopBleScan(callback)
        self.adv_ad.droid.bleStopBleAdvertising(advertise_callback)
        if not test_result:
            return test_result
        self.log.info("Waiting for scan callbacks to stop completely.")
        # Wait for all scan callbacks to stop. There is no confirmation
        # otherwise.
        time.sleep(10)
        return test_result