Home | History | Annotate | Download | only in pts
      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 Ble libraries
     18 """
     19 
     20 from acts.test_utils.bt.bt_constants import ble_advertise_settings_modes
     21 from acts.test_utils.bt.bt_constants import ble_advertise_settings_tx_powers
     22 from acts.test_utils.bt.bt_constants import ble_scan_settings_modes
     23 from acts.test_utils.bt.bt_constants import small_timeout
     24 from acts.test_utils.bt.bt_test_utils import adv_fail
     25 from acts.test_utils.bt.bt_constants import adv_succ
     26 from acts.test_utils.bt.bt_test_utils import advertising_set_on_own_address_read
     27 from acts.test_utils.bt.bt_test_utils import advertising_set_started
     28 from acts.test_utils.bt.bt_test_utils import generate_ble_advertise_objects
     29 
     30 import time
     31 import os
     32 
     33 
     34 class BleLib():
     35     def __init__(self, log, mac_addr, dut):
     36         self.advertisement_list = []
     37         self.dut = dut
     38         self.log = log
     39         self.mac_addr = mac_addr
     40         self.default_timeout = 5
     41         self.set_advertisement_list = []
     42         self.generic_uuid = "0000{}-0000-1000-8000-00805f9b34fb"
     43 
     44     def _verify_ble_adv_started(self, advertise_callback):
     45         """Helper for verifying if an advertisment started or not"""
     46         regex = "({}|{})".format(
     47             adv_succ.format(advertise_callback),
     48             adv_fail.format(advertise_callback))
     49         try:
     50             event = self.dut.ed.pop_events(regex, 5, small_timeout)
     51         except Empty:
     52             self.dut.log.error("Failed to get success or failed event.")
     53             return
     54         if event[0]["name"] == adv_succ.format(advertise_callback):
     55             self.dut.log.info("Advertisement started successfully.")
     56             return True
     57         else:
     58             self.dut.log.info("Advertisement failed to start.")
     59             return False
     60 
     61     def start_generic_connectable_advertisement(self, line):
     62         """Start a connectable LE advertisement"""
     63         scan_response = None
     64         if line:
     65             scan_response = bool(line)
     66         self.dut.droid.bleSetAdvertiseSettingsAdvertiseMode(
     67             ble_advertise_settings_modes['low_latency'])
     68         self.dut.droid.bleSetAdvertiseSettingsIsConnectable(True)
     69         advertise_callback, advertise_data, advertise_settings = (
     70             generate_ble_advertise_objects(self.dut.droid))
     71         if scan_response:
     72             self.dut.droid.bleStartBleAdvertisingWithScanResponse(
     73                 advertise_callback, advertise_data, advertise_settings,
     74                 advertise_data)
     75         else:
     76             self.dut.droid.bleStartBleAdvertising(
     77                 advertise_callback, advertise_data, advertise_settings)
     78         if self._verify_ble_adv_started(advertise_callback):
     79             self.log.info("Tracking Callback ID: {}".format(
     80                 advertise_callback))
     81             self.advertisement_list.append(advertise_callback)
     82             self.log.info(self.advertisement_list)
     83 
     84     def start_connectable_advertisement_set(self, line):
     85         """Start Connectable Advertisement Set"""
     86         adv_callback = self.dut.droid.bleAdvSetGenCallback()
     87         adv_data = {"includeDeviceName": True, }
     88         self.dut.droid.bleAdvSetStartAdvertisingSet({
     89             "connectable": True,
     90             "legacyMode": False,
     91             "primaryPhy": "PHY_LE_1M",
     92             "secondaryPhy": "PHY_LE_1M",
     93             "interval": 320
     94         }, adv_data, None, None, None, 0, 0, adv_callback)
     95         evt = self.dut.ed.pop_event(
     96             advertising_set_started.format(adv_callback), self.default_timeout)
     97         set_id = evt['data']['setId']
     98         self.log.error("did not receive the set started event!")
     99         evt = self.dut.ed.pop_event(
    100             advertising_set_on_own_address_read.format(set_id),
    101             self.default_timeout)
    102         address = evt['data']['address']
    103         self.log.info("Advertiser address is: {}".format(str(address)))
    104         self.set_advertisement_list.append(adv_callback)
    105 
    106     def stop_all_advertisement_set(self, line):
    107         """Stop all Advertisement Sets"""
    108         for adv in self.set_advertisement_list:
    109             try:
    110                 self.dut.droid.bleAdvSetStopAdvertisingSet(adv)
    111             except Exception as err:
    112                 self.log.error("Failed to stop advertisement: {}".format(err))
    113 
    114     def adv_add_service_uuid_list(self, line):
    115         """Add service UUID to the LE advertisement inputs:
    116          [uuid1 uuid2 ... uuidN]"""
    117         uuids = line.split()
    118         uuid_list = []
    119         for uuid in uuids:
    120             if len(uuid) == 4:
    121                 uuid = self.generic_uuid.format(line)
    122             uuid_list.append(uuid)
    123         self.dut.droid.bleSetAdvertiseDataSetServiceUuids(uuid_list)
    124 
    125     def adv_data_include_local_name(self, is_included):
    126         """Include local name in the advertisement. inputs: [true|false]"""
    127         self.dut.droid.bleSetAdvertiseDataIncludeDeviceName(bool(is_included))
    128 
    129     def adv_data_include_tx_power_level(self, is_included):
    130         """Include tx power level in the advertisement. inputs: [true|false]"""
    131         self.dut.droid.bleSetAdvertiseDataIncludeTxPowerLevel(
    132             bool(is_included))
    133 
    134     def adv_data_add_manufacturer_data(self, line):
    135         """Include manufacturer id and data to the advertisment:
    136         [id data1 data2 ... dataN]"""
    137         info = line.split()
    138         manu_id = int(info[0])
    139         manu_data = []
    140         for data in info[1:]:
    141             manu_data.append(int(data))
    142         self.dut.droid.bleAddAdvertiseDataManufacturerId(manu_id, manu_data)
    143 
    144     def start_generic_nonconnectable_advertisement(self, line):
    145         """Start a nonconnectable LE advertisement"""
    146         self.dut.droid.bleSetAdvertiseSettingsAdvertiseMode(
    147             ble_advertise_settings_modes['low_latency'])
    148         self.dut.droid.bleSetAdvertiseSettingsIsConnectable(False)
    149         advertise_callback, advertise_data, advertise_settings = (
    150             generate_ble_advertise_objects(self.dut.droid))
    151         self.dut.droid.bleStartBleAdvertising(
    152             advertise_callback, advertise_data, advertise_settings)
    153         if self._verify_ble_adv_started(advertise_callback):
    154             self.log.info("Tracking Callback ID: {}".format(
    155                 advertise_callback))
    156             self.advertisement_list.append(advertise_callback)
    157             self.log.info(self.advertisement_list)
    158 
    159     def stop_all_advertisements(self, line):
    160         """Stop all LE advertisements"""
    161         for callback_id in self.advertisement_list:
    162             self.log.info("Stopping Advertisement {}".format(callback_id))
    163             self.dut.droid.bleStopBleAdvertising(callback_id)
    164             time.sleep(1)
    165         self.advertisement_list = []
    166 
    167     def ble_stop_advertisement(self, callback_id):
    168         """Stop an LE advertisement"""
    169         if not callback_id:
    170             self.log.info("Need a callback ID")
    171             return
    172         callback_id = int(callback_id)
    173         if callback_id not in self.advertisement_list:
    174             self.log.info("Callback not in list of advertisements.")
    175             return
    176         self.dut.droid.bleStopBleAdvertising(callback_id)
    177         self.advertisement_list.remove(callback_id)
    178