Home | History | Annotate | Download | only in gatt
      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 Test suite for GATT over BR/EDR.
     18 """
     19 
     20 import time
     21 
     22 from acts.test_utils.bt.BluetoothBaseTest import BluetoothBaseTest
     23 from acts.test_utils.bt.bt_test_utils import reset_bluetooth
     24 from acts.test_utils.bt.GattEnum import GattCharacteristic
     25 from acts.test_utils.bt.GattEnum import GattDescriptor
     26 from acts.test_utils.bt.GattEnum import GattService
     27 from acts.test_utils.bt.GattEnum import MtuSize
     28 from acts.test_utils.bt.GattEnum import GattCbStrings
     29 from acts.test_utils.bt.bt_gatt_utils import disconnect_gatt_connection
     30 from acts.test_utils.bt.bt_gatt_utils import orchestrate_gatt_connection
     31 from acts.test_utils.bt.bt_gatt_utils import setup_gatt_characteristics
     32 from acts.test_utils.bt.bt_gatt_utils import setup_gatt_connection
     33 from acts.test_utils.bt.bt_gatt_utils import setup_gatt_descriptors
     34 from acts.test_utils.bt.bt_test_utils import get_advanced_droid_list
     35 from acts.test_utils.bt.bt_test_utils import log_energy_info
     36 from acts.test_utils.bt.bt_test_utils import setup_multiple_devices_for_bt_test
     37 from acts.test_utils.bt.bt_test_utils import take_btsnoop_logs
     38 
     39 
     40 class GattOverBrEdrTest(BluetoothBaseTest):
     41     default_timeout = 10
     42     default_discovery_timeout = 3
     43     droid_list = ()
     44     per_droid_mac_address = None
     45 
     46     def __init__(self, controllers):
     47         BluetoothBaseTest.__init__(self, controllers)
     48         self.droid_list = get_advanced_droid_list(self.android_devices)
     49         self.cen_ad = self.android_devices[0]
     50         self.per_ad = self.android_devices[1]
     51 
     52     def setup_class(self):
     53         self.log.info("Setting up devices for bluetooth testing.")
     54         if not setup_multiple_devices_for_bt_test(self.android_devices):
     55             return False
     56         self.per_droid_mac_address = self.per_ad.droid.bluetoothGetLocalAddress(
     57         )
     58         if not self.per_droid_mac_address:
     59             return False
     60         return True
     61 
     62     def on_fail(self, test_name, begin_time):
     63         take_btsnoop_logs(self.android_devices, self, test_name)
     64         reset_bluetooth(self.android_devices)
     65 
     66     def _setup_characteristics_and_descriptors(self, droid):
     67         characteristic_input = [
     68             {
     69                 'uuid': "aa7edd5a-4d1d-4f0e-883a-d145616a1630",
     70                 'property': GattCharacteristic.PROPERTY_WRITE.value
     71                 | GattCharacteristic.PROPERTY_WRITE_NO_RESPONSE.value,
     72                 'permission': GattCharacteristic.PROPERTY_WRITE.value
     73             },
     74             {
     75                 'uuid': "21c0a0bf-ad51-4a2d-8124-b74003e4e8c8",
     76                 'property': GattCharacteristic.PROPERTY_NOTIFY.value
     77                 | GattCharacteristic.PROPERTY_READ.value,
     78                 'permission': GattCharacteristic.PERMISSION_READ.value
     79             },
     80             {
     81                 'uuid': "6774191f-6ec3-4aa2-b8a8-cf830e41fda6",
     82                 'property': GattCharacteristic.PROPERTY_NOTIFY.value
     83                 | GattCharacteristic.PROPERTY_READ.value,
     84                 'permission': GattCharacteristic.PERMISSION_READ.value
     85             },
     86         ]
     87         descriptor_input = [
     88             {
     89                 'uuid': "aa7edd5a-4d1d-4f0e-883a-d145616a1630",
     90                 'property': GattDescriptor.PERMISSION_READ.value
     91                 | GattDescriptor.PERMISSION_WRITE.value,
     92             }, {
     93                 'uuid': "76d5ed92-ca81-4edb-bb6b-9f019665fb32",
     94                 'property': GattDescriptor.PERMISSION_READ.value
     95                 | GattCharacteristic.PERMISSION_WRITE.value,
     96             }
     97         ]
     98         characteristic_list = setup_gatt_characteristics(droid,
     99                                                          characteristic_input)
    100         descriptor_list = setup_gatt_descriptors(droid, descriptor_input)
    101         return characteristic_list, descriptor_list
    102 
    103     def _orchestrate_gatt_disconnection(self, bluetooth_gatt, gatt_callback):
    104         self.log.info("Disconnecting from peripheral device.")
    105         test_result = disconnect_gatt_connection(self.cen_ad, bluetooth_gatt,
    106                                                  gatt_callback)
    107         if not test_result:
    108             self.log.info("Failed to disconnect from peripheral device.")
    109             return False
    110         return True
    111 
    112     def _iterate_attributes(self, discovered_services_index):
    113         services_count = self.cen_ad.droid.gattClientGetDiscoveredServicesCount(
    114             discovered_services_index)
    115         for i in range(services_count):
    116             service = self.cen_ad.droid.gattClientGetDiscoveredServiceUuid(
    117                 discovered_services_index, i)
    118             self.log.info("Discovered service uuid {}".format(service))
    119             characteristic_uuids = (
    120                 self.cen_ad.droid.gattClientGetDiscoveredCharacteristicUuids(
    121                     discovered_services_index, i))
    122             for characteristic in characteristic_uuids:
    123                 self.log.info("Discovered characteristic uuid {}".format(
    124                     characteristic))
    125                 descriptor_uuids = (
    126                     self.cen_ad.droid.gattClientGetDiscoveredDescriptorUuids(
    127                         discovered_services_index, i, characteristic))
    128                 for descriptor in descriptor_uuids:
    129                     self.log.info("Discovered descriptor uuid {}".format(
    130                         descriptor))
    131 
    132     def _find_service_added_event(self, gatt_server_callback, uuid):
    133         event = self.per_ad.ed.pop_event(
    134             GattCbStrings.SERV_ADDED.value.format(gatt_server_callback),
    135             self.default_timeout)
    136         if event['data']['serviceUuid'].lower() != uuid.lower():
    137             self.log.info("Uuid mismatch. Found: {}, Expected {}.".format(
    138                 event['data']['serviceUuid'], uuid))
    139             return False
    140         return True
    141 
    142     def _setup_multiple_services(self):
    143         gatt_server_callback = (
    144             self.per_ad.droid.gattServerCreateGattServerCallback())
    145         gatt_server = self.per_ad.droid.gattServerOpenGattServer(
    146             gatt_server_callback)
    147         characteristic_list, descriptor_list = (
    148             self._setup_characteristics_and_descriptors(self.per_ad.droid))
    149         self.per_ad.droid.gattServerCharacteristicAddDescriptor(
    150             characteristic_list[1], descriptor_list[0])
    151         self.per_ad.droid.gattServerCharacteristicAddDescriptor(
    152             characteristic_list[2], descriptor_list[1])
    153         gatt_service = self.per_ad.droid.gattServerCreateService(
    154             "00000000-0000-1000-8000-00805f9b34fb",
    155             GattService.SERVICE_TYPE_PRIMARY.value)
    156         gatt_service2 = self.per_ad.droid.gattServerCreateService(
    157             "FFFFFFFF-0000-1000-8000-00805f9b34fb",
    158             GattService.SERVICE_TYPE_PRIMARY.value)
    159         gatt_service3 = self.per_ad.droid.gattServerCreateService(
    160             "3846D7A0-69C8-11E4-BA00-0002A5D5C51B",
    161             GattService.SERVICE_TYPE_PRIMARY.value)
    162         for characteristic in characteristic_list:
    163             self.per_ad.droid.gattServerAddCharacteristicToService(
    164                 gatt_service, characteristic)
    165         self.per_ad.droid.gattServerAddService(gatt_server, gatt_service)
    166         result = self._find_service_added_event(
    167             gatt_server_callback, "00000000-0000-1000-8000-00805f9b34fb")
    168         if not result:
    169             return False
    170         for characteristic in characteristic_list:
    171             self.per_ad.droid.gattServerAddCharacteristicToService(
    172                 gatt_service2, characteristic)
    173         self.per_ad.droid.gattServerAddService(gatt_server, gatt_service2)
    174         result = self._find_service_added_event(
    175             gatt_server_callback, "FFFFFFFF-0000-1000-8000-00805f9b34fb")
    176         if not result:
    177             return False
    178         for characteristic in characteristic_list:
    179             self.per_ad.droid.gattServerAddCharacteristicToService(
    180                 gatt_service3, characteristic)
    181         self.per_ad.droid.gattServerAddService(gatt_server, gatt_service3)
    182         result = self._find_service_added_event(
    183             gatt_server_callback, "3846D7A0-69C8-11E4-BA00-0002A5D5C51B")
    184         if not result:
    185             return False, False
    186         return gatt_server_callback, gatt_server
    187 
    188     @BluetoothBaseTest.bt_test_wrap
    189     def test_gatt_bredr_connect(self):
    190         """Test GATT connection over BR/EDR.
    191 
    192         Test establishing a gatt connection between a GATT server and GATT
    193         client.
    194 
    195         Steps:
    196         1. Start a generic advertisement.
    197         2. Start a generic scanner.
    198         3. Find the advertisement and extract the mac address.
    199         4. Stop the first scanner.
    200         5. Create a GATT connection between the scanner and advertiser.
    201         6. Disconnect the GATT connection.
    202 
    203         Expected Result:
    204         Verify that a connection was established and then disconnected
    205         successfully.
    206 
    207         Returns:
    208           Pass if True
    209           Fail if False
    210 
    211         TAGS: BR/EDR, Filtering, GATT, Scanning
    212         Priority: 0
    213         """
    214         bluetooth_gatt, gatt_callback, adv_callback = (
    215             orchestrate_gatt_connection(self.cen_ad, self.per_ad, False,
    216                                         self.per_droid_mac_address))
    217         return self._orchestrate_gatt_disconnection(bluetooth_gatt,
    218                                                     gatt_callback)
    219 
    220     @BluetoothBaseTest.bt_test_wrap
    221     def test_gatt_bredr_request_min_mtu(self):
    222         """Test GATT connection over BR/EDR and exercise MTU sizes.
    223 
    224         Test establishing a gatt connection between a GATT server and GATT
    225         client. Request an MTU size that matches the correct minimum size.
    226 
    227         Steps:
    228         1. Start a generic advertisement.
    229         2. Start a generic scanner.
    230         3. Find the advertisement and extract the mac address.
    231         4. Stop the first scanner.
    232         5. Create a GATT connection between the scanner and advertiser.
    233         6. From the scanner (client) request MTU size change to the
    234         minimum value.
    235         7. Find the MTU changed event on the client.
    236         8. Disconnect the GATT connection.
    237 
    238         Expected Result:
    239         Verify that a connection was established and the MTU value found
    240         matches the expected MTU value.
    241 
    242         Returns:
    243           Pass if True
    244           Fail if False
    245 
    246         TAGS: LE, Advertising, Filtering, Scanning, GATT, MTU
    247         Priority: 0
    248         """
    249         bluetooth_gatt, gatt_callback, adv_callback = (
    250             orchestrate_gatt_connection(self.cen_ad, self.per_ad, False,
    251                                         self.per_droid_mac_address))
    252         self.cen_ad.droid.gattClientRequestMtu(bluetooth_gatt,
    253                                                MtuSize.MIN.value)
    254         mtu_event = self.cen_ad.ed.pop_event(
    255             GattCbStrings.MTU_CHANGED.value.format(
    256                 bluetooth_gatt), self.default_timeout)
    257         if mtu_event['data']['MTU'] != MtuSize.MIN.value:
    258             return False
    259         return self._orchestrate_gatt_disconnection(bluetooth_gatt,
    260                                                     gatt_callback)
    261 
    262     @BluetoothBaseTest.bt_test_wrap
    263     def test_gatt_bredr_request_max_mtu(self):
    264         """Test GATT connection over BR/EDR and exercise MTU sizes.
    265 
    266         Test establishing a gatt connection between a GATT server and GATT
    267         client. Request an MTU size that matches the correct maximum size.
    268 
    269         Steps:
    270         1. Start a generic advertisement.
    271         2. Start a generic scanner.
    272         3. Find the advertisement and extract the mac address.
    273         4. Stop the first scanner.
    274         5. Create a GATT connection between the scanner and advertiser.
    275         6. From the scanner (client) request MTU size change to the
    276         maximum value.
    277         7. Find the MTU changed event on the client.
    278         8. Disconnect the GATT connection.
    279 
    280         Expected Result:
    281         Verify that a connection was established and the MTU value found
    282         matches the expected MTU value.
    283 
    284         Returns:
    285           Pass if True
    286           Fail if False
    287 
    288         TAGS: LE, Advertising, Filtering, Scanning, GATT, MTU
    289         Priority: 0
    290         """
    291         bluetooth_gatt, gatt_callback, adv_callback = (
    292             orchestrate_gatt_connection(self.cen_ad, self.per_ad, False,
    293                                         self.per_droid_mac_address))
    294         self.cen_ad.droid.gattClientRequestMtu(bluetooth_gatt,
    295                                                MtuSize.MAX.value)
    296         mtu_event = self.cen_ad.ed.pop_event(
    297             GattCbStrings.MTU_CHANGED.value.format(
    298                 bluetooth_gatt), self.default_timeout)
    299         if mtu_event['data']['MTU'] != MtuSize.MAX.value:
    300             return False
    301         return self._orchestrate_gatt_disconnection(bluetooth_gatt,
    302                                                     gatt_callback)
    303 
    304     @BluetoothBaseTest.bt_test_wrap
    305     def test_gatt_bredr_request_out_of_bounds_mtu(self):
    306         """Test GATT connection over BR/EDR and exercise an out of bound MTU size.
    307 
    308         Test establishing a gatt connection between a GATT server and GATT
    309         client. Request an MTU size that is the MIN value minus 1.
    310 
    311         Steps:
    312         1. Start a generic advertisement.
    313         2. Start a generic scanner.
    314         3. Find the advertisement and extract the mac address.
    315         4. Stop the first scanner.
    316         5. Create a GATT connection between the scanner and advertiser.
    317         6. From the scanner (client) request MTU size change to the
    318         minimum value minus one.
    319         7. Find the MTU changed event on the client.
    320         8. Disconnect the GATT connection.
    321 
    322         Expected Result:
    323         Verify that an MTU changed event was not discovered and that
    324         it didn't cause an exception when requesting an out of bounds
    325         MTU.
    326 
    327         Returns:
    328           Pass if True
    329           Fail if False
    330 
    331         TAGS: LE, Advertising, Filtering, Scanning, GATT, MTU
    332         Priority: 0
    333         """
    334         bluetooth_gatt, gatt_callback, adv_callback = (
    335             orchestrate_gatt_connection(self.cen_ad, self.per_ad, False,
    336                                         self.per_droid_mac_address))
    337         self.cen_ad.droid.gattClientRequestMtu(bluetooth_gatt,
    338                                                MtuSize.MIN.value - 1)
    339         try:
    340             self.cen_ad.ed.pop_event(
    341                 GattCbStrings.MTU_CHANGED.value.format(bluetooth_gatt),
    342                 self.default_timeout)
    343             self.log.error("Found {} event when it wasn't expected".format(
    344                 GattCbStrings.MTU_CHANGED.format(bluetooth_gatt)))
    345             return False
    346         except Exception:
    347             self.log.debug("Successfully didn't find {} event".format(
    348                 GattCbStrings.MTU_CHANGED.value.format(bluetooth_gatt)))
    349         return self._orchestrate_gatt_disconnection(bluetooth_gatt,
    350                                                     gatt_callback)
    351 
    352     @BluetoothBaseTest.bt_test_wrap
    353     def test_gatt_bredr_connect_trigger_on_read_rssi(self):
    354         """Test GATT connection over BR/EDR read RSSI.
    355 
    356         Test establishing a gatt connection between a GATT server and GATT
    357         client then read the RSSI.
    358 
    359         Steps:
    360         1. Start a generic advertisement.
    361         2. Start a generic scanner.
    362         3. Find the advertisement and extract the mac address.
    363         4. Stop the first scanner.
    364         5. Create a GATT connection between the scanner and advertiser.
    365         6. From the scanner, request to read the RSSI of the advertiser.
    366         7. Disconnect the GATT connection.
    367 
    368         Expected Result:
    369         Verify that a connection was established and then disconnected
    370         successfully. Verify that the RSSI was ready correctly.
    371 
    372         Returns:
    373           Pass if True
    374           Fail if False
    375 
    376         TAGS: BR/EDR, Scanning, GATT, RSSI
    377         Priority: 1
    378         """
    379         bluetooth_gatt, gatt_callback, adv_callback = (
    380             orchestrate_gatt_connection(self.cen_ad, self.per_ad, False,
    381                                         self.per_droid_mac_address))
    382         if self.cen_ad.droid.gattClientReadRSSI(bluetooth_gatt):
    383             self.cen_ad.ed.pop_event(
    384                 GattCbStrings.RD_REMOTE_RSSI.value.format(
    385                     gatt_callback), self.default_timeout)
    386         return self._orchestrate_gatt_disconnection(bluetooth_gatt,
    387                                                     gatt_callback)
    388 
    389     @BluetoothBaseTest.bt_test_wrap
    390     def test_gatt_bredr_connect_trigger_on_services_discovered(self):
    391         """Test GATT connection and discover services of peripheral.
    392 
    393         Test establishing a gatt connection between a GATT server and GATT
    394         client the discover all services from the connected device.
    395 
    396         Steps:
    397         1. Start a generic advertisement.
    398         2. Start a generic scanner.
    399         3. Find the advertisement and extract the mac address.
    400         4. Stop the first scanner.
    401         5. Create a GATT connection between the scanner and advertiser.
    402         6. From the scanner (central device), discover services.
    403         7. Disconnect the GATT connection.
    404 
    405         Expected Result:
    406         Verify that a connection was established and then disconnected
    407         successfully. Verify that the service were discovered.
    408 
    409         Returns:
    410           Pass if True
    411           Fail if False
    412 
    413         TAGS: BR/EDR, Scanning, GATT, Services
    414         Priority: 1
    415         """
    416         bluetooth_gatt, gatt_callback, adv_callback = (
    417             orchestrate_gatt_connection(self.cen_ad, self.per_ad, False,
    418                                         self.per_droid_mac_address))
    419         discovered_services_index = -1
    420         if self.cen_ad.droid.gattClientDiscoverServices(bluetooth_gatt):
    421             event = self.cen_ad.ed.pop_event(
    422                 GattCbStrings.GATT_SERV_DISC.value.format(gatt_callback),
    423                 self.default_timeout)
    424             discovered_services_index = event['data']['ServicesIndex']
    425         return self._orchestrate_gatt_disconnection(bluetooth_gatt,
    426                                                     gatt_callback)
    427 
    428     @BluetoothBaseTest.bt_test_wrap
    429     def test_gatt_bredr_connect_trigger_on_services_discovered_iterate_attributes(
    430             self):
    431         """Test GATT connection and iterate peripherals attributes.
    432 
    433         Test establishing a gatt connection between a GATT server and GATT
    434         client and iterate over all the characteristics and descriptors of the
    435         discovered services.
    436 
    437         Steps:
    438         1. Start a generic advertisement.
    439         2. Start a generic scanner.
    440         3. Find the advertisement and extract the mac address.
    441         4. Stop the first scanner.
    442         5. Create a GATT connection between the scanner and advertiser.
    443         6. From the scanner (central device), discover services.
    444         7. Iterate over all the characteristics and descriptors of the
    445         discovered features.
    446         8. Disconnect the GATT connection.
    447 
    448         Expected Result:
    449         Verify that a connection was established and then disconnected
    450         successfully. Verify that the services, characteristics, and descriptors
    451         were discovered.
    452 
    453         Returns:
    454           Pass if True
    455           Fail if False
    456 
    457         TAGS: BR/EDR, Scanning, GATT, Services
    458         Characteristics, Descriptors
    459         Priority: 1
    460         """
    461         bluetooth_gatt, gatt_callback, adv_callback = (
    462             orchestrate_gatt_connection(self.cen_ad, self.per_ad, False,
    463                                         self.per_droid_mac_address))
    464         discovered_services_index = -1
    465         if self.cen_ad.droid.gattClientDiscoverServices(bluetooth_gatt):
    466             event = self.cen_ad.ed.pop_event(
    467                 GattCbStrings.GATT_SERV_DISC.value.format(gatt_callback),
    468                 self.default_timeout)
    469             discovered_services_index = event['data']['ServicesIndex']
    470             self._iterate_attributes(discovered_services_index)
    471         return self._orchestrate_gatt_disconnection(bluetooth_gatt,
    472                                                     gatt_callback)
    473 
    474     @BluetoothBaseTest.bt_test_wrap
    475     def test_gatt_bredr_connect_with_service_uuid_variations(self):
    476         """Test GATT connection with multiple service uuids.
    477 
    478         Test establishing a gatt connection between a GATT server and GATT
    479         client with multiple service uuid variations.
    480 
    481         Steps:
    482         1. Start a generic advertisement.
    483         2. Start a generic scanner.
    484         3. Find the advertisement and extract the mac address.
    485         4. Stop the first scanner.
    486         5. Create a GATT connection between the scanner and advertiser.
    487         6. From the scanner (central device), discover services.
    488         7. Verify that all the service uuid variations are found.
    489         8. Disconnect the GATT connection.
    490 
    491         Expected Result:
    492         Verify that a connection was established and then disconnected
    493         successfully. Verify that the service uuid variations are found.
    494 
    495         Returns:
    496           Pass if True
    497           Fail if False
    498 
    499         TAGS: BR/EDR, Scanning, GATT, Services
    500         Priority: 2
    501         """
    502         gatt_server_callback, gatt_server = self._setup_multiple_services()
    503         if not gatt_server_callback or not gatt_server:
    504             return False
    505         bluetooth_gatt, gatt_callback, adv_callback = (
    506             orchestrate_gatt_connection(self.cen_ad, self.per_ad, False,
    507                                         self.per_droid_mac_address))
    508         discovered_services_index = -1
    509         if self.cen_ad.droid.gattClientDiscoverServices(bluetooth_gatt):
    510             event = self.cen_ad.ed.pop_event(
    511                 GattCbStrings.GATT_SERV_DISC.value.format(gatt_callback),
    512                 self.default_timeout)
    513             discovered_services_index = event['data']['ServicesIndex']
    514             self._iterate_attributes(discovered_services_index)
    515         return self._orchestrate_gatt_disconnection(bluetooth_gatt,
    516                                                     gatt_callback)
    517 
    518     @BluetoothBaseTest.bt_test_wrap
    519     def test_gatt_bredr_connect_multiple_iterations(self):
    520         """Test GATT connections multiple times.
    521 
    522         Test establishing a gatt connection between a GATT server and GATT
    523         client with multiple iterations.
    524 
    525         Steps:
    526         1. Start a generic advertisement.
    527         2. Start a generic scanner.
    528         3. Find the advertisement and extract the mac address.
    529         4. Stop the first scanner.
    530         5. Create a GATT connection between the scanner and advertiser.
    531         6. Disconnect the GATT connection.
    532         7. Repeat steps 5 and 6 twenty times.
    533 
    534         Expected Result:
    535         Verify that a connection was established and then disconnected
    536         successfully twenty times.
    537 
    538         Returns:
    539           Pass if True
    540           Fail if False
    541 
    542         TAGS: BR/EDR, Scanning, GATT, Stress
    543         Priority: 1
    544         """
    545         autoconnect = False
    546         mac_address = self.per_ad.droid.bluetoothGetLocalAddress()
    547         for i in range(20):
    548             bluetooth_gatt, gatt_callback, adv_callback = (
    549                 orchestrate_gatt_connection(self.cen_ad, self.per_ad, False,
    550                                             self.per_droid_mac_address))
    551             self.log.info("Disconnecting from peripheral device.")
    552             test_result = self._orchestrate_gatt_disconnection(bluetooth_gatt,
    553                                                                gatt_callback)
    554             if not test_result:
    555                 self.log.info("Failed to disconnect from peripheral device.")
    556                 return False
    557         return True
    558 
    559     @BluetoothBaseTest.bt_test_wrap
    560     def test_bredr_write_descriptor_stress(self):
    561         """Test GATT connection writing and reading descriptors.
    562 
    563         Test establishing a gatt connection between a GATT server and GATT
    564         client with multiple service uuid variations.
    565 
    566         Steps:
    567         1. Start a generic advertisement.
    568         2. Start a generic scanner.
    569         3. Find the advertisement and extract the mac address.
    570         4. Stop the first scanner.
    571         5. Create a GATT connection between the scanner and advertiser.
    572         6. Discover services.
    573         7. Write data to the descriptors of each characteristic 100 times.
    574         8. Read the data sent to the descriptors.
    575         9. Disconnect the GATT connection.
    576 
    577         Expected Result:
    578         Each descriptor in each characteristic is written and read 100 times.
    579 
    580         Returns:
    581           Pass if True
    582           Fail if False
    583 
    584         TAGS: BR/EDR, Scanning, GATT, Stress, Characteristics, Descriptors
    585         Priority: 1
    586         """
    587         gatt_server_callback, gatt_server = self._setup_multiple_services()
    588         if not gatt_server_callback or not gatt_server:
    589             return False
    590         bluetooth_gatt, gatt_callback, adv_callback = (
    591             orchestrate_gatt_connection(self.cen_ad, self.per_ad, False,
    592                                         self.per_droid_mac_address))
    593         if self.cen_ad.droid.gattClientDiscoverServices(bluetooth_gatt):
    594             event = self.cen_ad.ed.pop_event(
    595                 GattCbStrings.GATT_SERV_DISC.value.format(gatt_callback),
    596                 self.default_timeout)
    597             discovered_services_index = event['data']['ServicesIndex']
    598         else:
    599             self.log.info("Failed to discover services.")
    600             return False
    601         services_count = self.cen_ad.droid.gattClientGetDiscoveredServicesCount(
    602             discovered_services_index)
    603 
    604         connected_device_list = self.per_ad.droid.gattServerGetConnectedDevices(
    605             gatt_server)
    606         if len(connected_device_list) == 0:
    607             self.log.info("No devices connected from peripheral.")
    608             return False
    609         bt_device_id = 0
    610         status = 1
    611         offset = 1
    612         test_value = [1,2,3,4,5,6,7]
    613         test_value_return = [1,2,3]
    614         for i in range(services_count):
    615             characteristic_uuids = (
    616                 self.cen_ad.droid.gattClientGetDiscoveredCharacteristicUuids(
    617                     discovered_services_index, i))
    618             for characteristic in characteristic_uuids:
    619                 descriptor_uuids = (
    620                     self.cen_ad.droid.gattClientGetDiscoveredDescriptorUuids(
    621                         discovered_services_index, i, characteristic))
    622                 for _ in range(100):
    623                     for descriptor in descriptor_uuids:
    624                         self.cen_ad.droid.gattClientDescriptorSetValue(
    625                             bluetooth_gatt, discovered_services_index, i,
    626                             characteristic, descriptor, test_value)
    627                         self.cen_ad.droid.gattClientWriteDescriptor(
    628                             bluetooth_gatt, discovered_services_index, i,
    629                             characteristic, descriptor)
    630                         event = self.per_ad.ed.pop_event(
    631                             GattCbStrings.DESC_WRITE_REQ.value.format(
    632                                 gatt_callback), self.default_timeout)
    633                         self.log.info(
    634                             "onDescriptorWriteRequest event found: {}".format(
    635                                 event))
    636                         request_id = event['data']['requestId']
    637                         found_value = event['data']['value']
    638                         if found_value != test_value:
    639                             self.log.info("Values didn't match. Found: {}, "
    640                                           "Expected: {}".format(found_value,
    641                                                                 test_value))
    642                             return False
    643                         self.per_ad.droid.gattServerSendResponse(
    644                             gatt_server, bt_device_id, request_id, status,
    645                             offset, test_value_return)
    646                         self.log.info(
    647                             "onDescriptorWrite event found: {}".format(
    648                                 self.cen_ad.ed.pop_event(
    649                                     GattCbStrings.DESC_WRITE.value.format(
    650                                         bluetooth_gatt),
    651                                     self.default_timeout)))
    652         return True
    653 
    654     @BluetoothBaseTest.bt_test_wrap
    655     def test_gatt_bredr_connect_mitm_attack(self):
    656         """Test GATT connection with permission write encrypted mitm.
    657 
    658         Test establishing a gatt connection between a GATT server and GATT
    659         client while the GATT server's characteristic includes the property
    660         write value and the permission write encrypted mitm value. This will
    661         prompt LE pairing and then the devices will create a bond.
    662 
    663         Steps:
    664         1. Create a GATT server and server callback on the peripheral device.
    665         2. Create a unique service and characteristic uuid on the peripheral.
    666         3. Create a characteristic on the peripheral with these properties:
    667             GattCharacteristic.PROPERTY_WRITE.value,
    668             GattCharacteristic.PERMISSION_WRITE_ENCRYPTED_MITM.value
    669         4. Create a GATT service on the peripheral.
    670         5. Add the characteristic to the GATT service.
    671         6. Create a GATT connection between your central and peripheral device.
    672         7. From the central device, discover the peripheral's services.
    673         8. Iterate the services found until you find the unique characteristic
    674             created in step 3.
    675         9. Once found, write a random but valid value to the characteristic.
    676         10. Start pairing helpers on both devices immediately after attempting
    677             to write to the characteristic.
    678         11. Within 10 seconds of writing the characteristic, there should be
    679             a prompt to bond the device from the peripheral. The helpers will
    680             handle the UI interaction automatically. (see
    681             BluetoothConnectionFacade.java bluetoothStartPairingHelper).
    682         12. Verify that the two devices are bonded.
    683 
    684         Expected Result:
    685         Verify that a connection was established and the devices are bonded.
    686 
    687         Returns:
    688           Pass if True
    689           Fail if False
    690 
    691         TAGS: LE, Advertising, Filtering, Scanning, GATT, Characteristic, MITM
    692         Priority: 1
    693         """
    694         gatt_server_callback = (
    695             self.per_ad.droid.gattServerCreateGattServerCallback())
    696         gatt_server = self.per_ad.droid.gattServerOpenGattServer(
    697             gatt_server_callback)
    698         service_uuid = "3846D7A0-69C8-11E4-BA00-0002A5D5C51B"
    699         test_uuid = "aa7edd5a-4d1d-4f0e-883a-d145616a1630"
    700         bonded = False
    701         characteristic = self.per_ad.droid.gattServerCreateBluetoothGattCharacteristic(
    702             test_uuid, GattCharacteristic.PROPERTY_WRITE.value,
    703             GattCharacteristic.PERMISSION_WRITE_ENCRYPTED_MITM.value)
    704         gatt_service = self.per_ad.droid.gattServerCreateService(
    705             service_uuid, GattService.SERVICE_TYPE_PRIMARY.value)
    706         self.per_ad.droid.gattServerAddCharacteristicToService(gatt_service,
    707                                                                characteristic)
    708         self.per_ad.droid.gattServerAddService(gatt_server, gatt_service)
    709         result = self._find_service_added_event(gatt_server_callback,
    710                                                 service_uuid)
    711         if not result:
    712             return False
    713         bluetooth_gatt, gatt_callback, adv_callback = (
    714             orchestrate_gatt_connection(self.cen_ad, self.per_ad, False,
    715                                         self.per_droid_mac_address))
    716         if bluetooth_gatt is False:
    717             return False
    718         if self.cen_ad.droid.gattClientDiscoverServices(bluetooth_gatt):
    719             event = self.cen_ad.ed.pop_event(
    720                 GattCbStrings.GATT_SERV_DISC.value.format(gatt_callback),
    721                 self.default_timeout)
    722             discovered_services_index = event['data']['ServicesIndex']
    723         else:
    724             self.log.info("Failed to discover services.")
    725             return False
    726         test_value = [1,2,3,4,5,6,7]
    727         services_count = self.cen_ad.droid.gattClientGetDiscoveredServicesCount(
    728             discovered_services_index)
    729         for i in range(services_count):
    730             characteristic_uuids = (
    731                 self.cen_ad.droid.gattClientGetDiscoveredCharacteristicUuids(
    732                     discovered_services_index, i))
    733             for characteristic_uuid in characteristic_uuids:
    734                 if characteristic_uuid == test_uuid:
    735                     self.cen_ad.droid.bluetoothStartPairingHelper()
    736                     self.per_ad.droid.bluetoothStartPairingHelper()
    737                     self.cen_ad.droid.gattClientCharacteristicSetValue(
    738                         bluetooth_gatt, discovered_services_index, i,
    739                         characteristic_uuid, test_value)
    740                     self.cen_ad.droid.gattClientWriteCharacteristic(
    741                         bluetooth_gatt, discovered_services_index, i,
    742                         characteristic_uuid)
    743                     start_time = time.time() + self.default_timeout
    744                     target_name = self.per_ad.droid.bluetoothGetLocalName()
    745                     while time.time() < start_time and bonded == False:
    746                         bonded_devices = self.cen_ad.droid.bluetoothGetBondedDevices(
    747                         )
    748                         for device in bonded_devices:
    749                             if 'name' in device.keys() and device[
    750                                     'name'] == target_name:
    751                                 bonded = True
    752                                 break
    753         return True
    754