def test_gatt_bredr_connect(self): """Test GATT connection over BR/EDR. Test establishing a gatt connection between a GATT server and GATT client. 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 GATT connection between the scanner and advertiser. 6. Disconnect the GATT connection. Expected Result: Verify that a connection was established and then disconnected successfully. Returns: Pass if True Fail if False TAGS: BR/EDR, Filtering, GATT, Scanning Priority: 0 """ gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback() gatt_server = self.per_ad.droid.gattServerOpenGattServer( gatt_server_cb) self.gatt_server_list.append(gatt_server) try: bluetooth_gatt, gatt_callback, adv_callback = ( orchestrate_gatt_connection(self.cen_ad, self.per_ad, GattTransport.TRANSPORT_BREDR, self.per_droid_mac_address)) self.bluetooth_gatt_list.append(bluetooth_gatt) except GattTestUtilsError as err: self.log.error(err) return False return self._orchestrate_gatt_disconnection(bluetooth_gatt, gatt_callback)
def setup_test(self): super(GattConnectedBaseTest, self).setup_test() self.gatt_server_callback, self.gatt_server = self._setup_multiple_services( ) if not self.gatt_server_callback or not self.gatt_server: raise AssertionError('Service setup failed') self.bluetooth_gatt, self.gatt_callback, self.adv_callback = ( orchestrate_gatt_connection(self.cen_ad, self.per_ad)) self.per_ad.droid.bleStopBleAdvertising(self.adv_callback) self.mtu = gatt_mtu_size['min'] if self.cen_ad.droid.gattClientDiscoverServices(self.bluetooth_gatt): event = self._client_wait(gatt_event['gatt_serv_disc']) self.discovered_services_index = event['data']['ServicesIndex'] services_count = self.cen_ad.droid.gattClientGetDiscoveredServicesCount( self.discovered_services_index) self.test_service_index = None for i in range(services_count): disc_service_uuid = ( self.cen_ad.droid.gattClientGetDiscoveredServiceUuid( self.discovered_services_index, i).upper()) if disc_service_uuid == self.TEST_SERVICE_UUID: self.test_service_index = i break if not self.test_service_index: print("Service not found") return False connected_device_list = self.per_ad.droid.gattServerGetConnectedDevices( self.gatt_server) if len(connected_device_list) == 0: self.log.info("No devices connected from peripheral.") return False return True
def test_gatt_connect_mitm_attack(self): """Test GATT connection with permission write encrypted mitm. Test establishing a gatt connection between a GATT server and GATT client while the GATT server's characteristic includes the property write value and the permission write encrypted mitm value. This will prompt LE pairing and then the devices will create a bond. Steps: 1. Create a GATT server and server callback on the peripheral device. 2. Create a unique service and characteristic uuid on the peripheral. 3. Create a characteristic on the peripheral with these properties: GattCharacteristic.PROPERTY_WRITE.value, GattCharacteristic.PERMISSION_WRITE_ENCRYPTED_MITM.value 4. Create a GATT service on the peripheral. 5. Add the characteristic to the GATT service. 6. Create a GATT connection between your central and peripheral device. 7. From the central device, discover the peripheral's services. 8. Iterate the services found until you find the unique characteristic created in step 3. 9. Once found, write a random but valid value to the characteristic. 10. Start pairing helpers on both devices immediately after attempting to write to the characteristic. 11. Within 10 seconds of writing the characteristic, there should be a prompt to bond the device from the peripheral. The helpers will handle the UI interaction automatically. (see BluetoothConnectionFacade.java bluetoothStartPairingHelper). 12. Verify that the two devices are bonded. Expected Result: Verify that a connection was established and the devices are bonded. Returns: Pass if True Fail if False TAGS: LE, Advertising, Filtering, Scanning, GATT, Characteristic, MITM Priority: 1 """ gatt_server_cb = self.per_ad.droid.gattServerCreateGattServerCallback() gatt_server = self.per_ad.droid.gattServerOpenGattServer( gatt_server_cb) self.gatt_server_list.append(gatt_server) service_uuid = "3846D7A0-69C8-11E4-BA00-0002A5D5C51B" test_uuid = "aa7edd5a-4d1d-4f0e-883a-d145616a1630" bonded = False characteristic = self.per_ad.droid.gattServerCreateBluetoothGattCharacteristic( test_uuid, GattCharacteristic.PROPERTY_WRITE.value, GattCharacteristic.PERMISSION_WRITE_ENCRYPTED_MITM.value) gatt_service = self.per_ad.droid.gattServerCreateService( service_uuid, GattService.SERVICE_TYPE_PRIMARY.value) self.per_ad.droid.gattServerAddCharacteristicToService(gatt_service, characteristic) self.per_ad.droid.gattServerAddService(gatt_server, gatt_service) result = self._find_service_added_event(gatt_server_cb, service_uuid) if not result: return False bluetooth_gatt, gatt_callback, adv_callback = ( orchestrate_gatt_connection(self.cen_ad, self.per_ad)) self.bluetooth_gatt_list.append(bluetooth_gatt) self.adv_instances.append(adv_callback) if self.cen_ad.droid.gattClientDiscoverServices(bluetooth_gatt): expected_event = GattCbStrings.GATT_SERV_DISC.value.format( gatt_callback) try: event = self.cen_ad.ed.pop_event(expected_event, self.default_timeout) except Empty: self.log.error( GattCbErr.GATT_SERV_DISC_ERR.value.format(expected_event)) return False discovered_services_index = event['data']['ServicesIndex'] else: self.log.info("Failed to discover services.") return False test_value = [1, 2, 3, 4, 5, 6, 7] services_count = self.cen_ad.droid.gattClientGetDiscoveredServicesCount( discovered_services_index) for i in range(services_count): characteristic_uuids = ( self.cen_ad.droid.gattClientGetDiscoveredCharacteristicUuids( discovered_services_index, i)) for characteristic_uuid in characteristic_uuids: if characteristic_uuid == test_uuid: self.cen_ad.droid.bluetoothStartPairingHelper() self.per_ad.droid.bluetoothStartPairingHelper() self.cen_ad.droid.gattClientCharacteristicSetValue( bluetooth_gatt, discovered_services_index, i, characteristic_uuid, test_value) self.cen_ad.droid.gattClientWriteCharacteristic( bluetooth_gatt, discovered_services_index, i, characteristic_uuid) start_time = time.time() + self.default_timeout target_name = self.per_ad.droid.bluetoothGetLocalName() while time.time() < start_time and bonded == False: bonded_devices = self.cen_ad.droid.bluetoothGetBondedDevices( ) for device in bonded_devices: if ('name' in device.keys() and device['name'] == target_name): bonded = True break return self._orchestrate_gatt_disconnection(bluetooth_gatt, gatt_callback)
def test_bredr_write_descriptor_stress(self): """Test GATT connection writing and reading descriptors. Test establishing a gatt connection between a GATT server and GATT client with multiple service uuid variations. 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 GATT connection between the scanner and advertiser. 6. Discover services. 7. Write data to the descriptors of each characteristic 100 times. 8. Read the data sent to the descriptors. 9. Disconnect the GATT connection. Expected Result: Each descriptor in each characteristic is written and read 100 times. Returns: Pass if True Fail if False TAGS: BR/EDR, Scanning, GATT, Stress, Characteristics, Descriptors Priority: 1 """ try: gatt_server_callback, gatt_server = setup_multiple_services( self.per_ad) self.gatt_server_list.append(gatt_server) except GattTestUtilsError as err: self.log.error(err) return False try: bluetooth_gatt, gatt_callback, adv_callback = ( orchestrate_gatt_connection(self.cen_ad, self.per_ad, gatt_transport['bredr'], self.per_droid_mac_address)) self.bluetooth_gatt_list.append(bluetooth_gatt) except GattTestUtilsError as err: self.log.error(err) return False if self.cen_ad.droid.gattClientDiscoverServices(bluetooth_gatt): try: event = self.cen_ad.ed.pop_event( gatt_cb_strings['gatt_serv_disc'].format(gatt_callback), self.default_timeout) except Empty as err: self.log.error("Event not found: {}".format(err)) return False discovered_services_index = event['data']['ServicesIndex'] else: self.log.info("Failed to discover services.") return False services_count = self.cen_ad.droid.gattClientGetDiscoveredServicesCount( discovered_services_index) connected_device_list = self.per_ad.droid.gattServerGetConnectedDevices( gatt_server) if len(connected_device_list) == 0: self.log.info("No devices connected from peripheral.") return False bt_device_id = 0 status = 1 offset = 1 test_value = [1, 2, 3, 4, 5, 6, 7] test_value_return = [1, 2, 3] for i in range(services_count): characteristic_uuids = ( self.cen_ad.droid.gattClientGetDiscoveredCharacteristicUuids( discovered_services_index, i)) for characteristic in characteristic_uuids: descriptor_uuids = ( self.cen_ad.droid.gattClientGetDiscoveredDescriptorUuids( discovered_services_index, i, characteristic)) for _ in range(100): for descriptor in descriptor_uuids: self.cen_ad.droid.gattClientDescriptorSetValue( bluetooth_gatt, discovered_services_index, i, characteristic, descriptor, test_value) self.cen_ad.droid.gattClientWriteDescriptor( bluetooth_gatt, discovered_services_index, i, characteristic, descriptor) event = self.per_ad.ed.pop_event(gatt_cb_strings[ 'desc_write_req'].format(gatt_server_callback), self.default_timeout) self.log.info( "onDescriptorWriteRequest event found: {}".format( event)) request_id = event['data']['requestId'] found_value = event['data']['value'] if found_value != test_value: self.log.info("Values didn't match. Found: {}, " "Expected: {}".format(found_value, test_value)) return False self.per_ad.droid.gattServerSendResponse( gatt_server, bt_device_id, request_id, status, offset, test_value_return) self.log.info( "onDescriptorWrite event found: {}".format( self.cen_ad.ed.pop_event(gatt_cb_strings[ 'desc_write'].format( gatt_callback), self.default_timeout))) return True