1#!/usr/bin/env python3 2# 3# Copyright (C) 2018 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"""This script shows simple examples of how to get started with bluetooth 17 low energy testing in acts. 18""" 19 20import pprint 21import random 22import time 23 24from acts.controllers import android_device 25from acts_contrib.test_utils.fuchsia.bt_test_utils import le_scan_for_device_by_name 26from acts_contrib.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest 27from acts_contrib.test_utils.bt.bt_constants import ble_advertise_settings_modes 28from acts_contrib.test_utils.bt.bt_constants import adv_succ 29from acts_contrib.test_utils.bt.bt_constants import ble_scan_settings_modes 30from acts_contrib.test_utils.bt.bt_constants import scan_result 31from acts_contrib.test_utils.bt.bt_test_utils import cleanup_scanners_and_advertisers 32from acts_contrib.test_utils.bt.bt_test_utils import reset_bluetooth 33 34 35class BleFuchsiaAndroidTest(BluetoothBaseTest): 36 default_timeout = 10 37 active_adv_callback_list = [] 38 droid = None 39 40 def setup_class(self): 41 super().setup_class() 42 43 # Android device under test 44 self.ad = self.android_devices[0] 45 # Fuchsia device under test 46 self.fd = self.fuchsia_devices[0] 47 self.log.info("There are: {} fuchsia and {} android devices.".format( 48 len(self.fuchsia_devices), len(self.android_devices))) 49 50 def _start_generic_advertisement_include_device_name(self): 51 self.ad.droid.bleSetAdvertiseDataIncludeDeviceName(True) 52 self.ad.droid.bleSetAdvertiseSettingsAdvertiseMode( 53 ble_advertise_settings_modes['low_latency']) 54 advertise_data = self.ad.droid.bleBuildAdvertiseData() 55 advertise_settings = self.ad.droid.bleBuildAdvertiseSettings() 56 advertise_callback = self.ad.droid.bleGenBleAdvertiseCallback() 57 self.ad.droid.bleStartBleAdvertising(advertise_callback, 58 advertise_data, 59 advertise_settings) 60 self.ad.ed.pop_event(adv_succ.format(advertise_callback), 61 self.default_timeout) 62 self.active_adv_callback_list.append(advertise_callback) 63 return advertise_callback 64 65 # Basic test for android device as advertiser and fuchsia device as scanner 66 # Returns True if scan result has an entry corresponding to sample_android_name 67 @BluetoothBaseTest.bt_test_wrap 68 def test_fuchsia_scan_android_adv(self): 69 sample_android_name = "Pixel1234" 70 self.ad.droid.bluetoothSetLocalName(sample_android_name) 71 adv_callback = self._start_generic_advertisement_include_device_name() 72 droid_name = self.ad.droid.bluetoothGetLocalName() 73 self.log.info("Android device name: {}".format(droid_name)) 74 res = True 75 if not le_scan_for_device_by_name( 76 self.fd, self.log, sample_android_name, self.default_timeout): 77 res = False 78 79 #Print clients to validate results are saved 80 self.fd.print_clients() 81 82 #Stop android advertising 83 self.ad.droid.bleStopBleAdvertising(adv_callback) 84 85 return res 86 87 # Test for fuchsia device attempting to connect to android device (peripheral) 88 # Also tests the list_services and discconect to a peripheral 89 @BluetoothBaseTest.bt_test_wrap 90 def test_fuchsia_connect_android_periph(self): 91 sample_android_name = "Pixel1234" 92 self.ad.droid.bluetoothStartPairingHelper() 93 self.ad.droid.bluetoothSetLocalName(sample_android_name) 94 adv_callback = self._start_generic_advertisement_include_device_name() 95 droid_name = self.ad.droid.bluetoothGetLocalName() 96 self.log.info("Android device name: {}".format(droid_name)) 97 98 scan_result = le_scan_for_device_by_name(self.fd, self.log, 99 sample_android_name, 100 self.default_timeout) 101 if not scan_result: 102 return False 103 104 name, did, connectable = scan_result["name"], scan_result[ 105 "id"], scan_result["connectable"] 106 107 connect = self.fd.gattc_lib.bleConnectToPeripheral(did) 108 self.log.info("Connecting returned status: {}".format(connect)) 109 110 services = self.fd.gattc_lib.listServices(did) 111 self.log.info("Listing services returned: {}".format(services)) 112 113 dconnect = self.fd.gattc_lib.bleDisconnectPeripheral(did) 114 self.log.info("Disconnect status: {}".format(dconnect)) 115 116 #Print clients to validate results are saved 117 self.fd.print_clients() 118 119 #Stop android advertising + cleanup sl4f 120 self.ad.droid.bleStopBleAdvertising(adv_callback) 121 122 return True 123 124 # Currently, this test doesn't work. The android device does not scan 125 # TODO(): Debug android scan 126 @BluetoothBaseTest.bt_test_wrap 127 def test_fuchsia_adv_android_scan(self): 128 #Initialize advertising on fuchsia device with name and interval 129 fuchsia_name = "testADV123" 130 adv_data = { 131 "name": fuchsia_name, 132 "appearance": None, 133 "service_data": None, 134 "tx_power_level": None, 135 "service_uuids": None, 136 "manufacturer_data": None, 137 "uris": None, 138 } 139 scan_response = None 140 connectable = True 141 interval = 1000 142 143 #Start advertising 144 self.fd.ble_lib.bleStartBleAdvertising(adv_data, scan_response, 145 interval, connectable) 146 147 # Initialize scan on android device which scan settings + callback 148 filter_list = self.ad.droid.bleGenFilterList() 149 self.ad.droid.bleSetScanFilterDeviceName(fuchsia_name) 150 self.ad.droid.bleSetScanSettingsScanMode( 151 ble_scan_settings_modes['low_latency']) 152 scan_settings = self.ad.droid.bleBuildScanSetting() 153 scan_callback = self.ad.droid.bleGenScanCallback() 154 self.ad.droid.bleBuildScanFilter(filter_list) 155 self.ad.droid.bleStartBleScan(filter_list, scan_settings, 156 scan_callback) 157 event_name = scan_result.format(scan_callback) 158 try: 159 event = self.ad.ed.pop_event(event_name, self.default_timeout) 160 self.log.info("Found scan result: {}".format( 161 pprint.pformat(event))) 162 except Exception: 163 self.log.error("Didn't find any scan results.") 164 return False 165 finally: 166 self.fd.ble_lib.bleStopBleAdvertising() 167 self.ad.droid.bleStopBleScan(scan_callback) 168 # TODO(): Validate result 169 return True 170