Android 5.x BLE GATT service not discovered, but device is connected - android

My BLE discovery and connecting is working fine on Android 6.0 and higher. However, on version 5.x devices (both are Samsung - Note 4 and Galaxy Core Prime) I am able to scan, find my peripheral, connect and get the onConnectionStateChange callback. All the connection steps work fine.
After onConnectionStateChange I call gatt.discoverServices() - this returns onServicesDiscovered() and then I call getSupportedGattServices(). getSupportedGattServices() returns successfully but it's missing the specific Service UUID that is on my peripheral. I know the UUID is there because I can see it on the peripheral and my other Android devices can connect to it. I'm logging all the discovered UUIDs and it only sees the Generic Attribute Profile and the Generic Access Profile services.
I checked the ScanResult class returned in LeScanCallback and the service UUID is there. And again, this is only happening on 5.x. 6.0+ Android devices discover the service without issue.
Thanks.

Related

Disconnecting and closing BLE connection stops classic Blutetooth PBAP profile

I have a setup with two Android devices: an android phone and a custom hardware running Android 10. The latter acts as a BLE Server, which is discoverable always with the same static MAC address. Also when that custom HW is paired with the phone it has access to phone's contacts and calls history. That HW can also play media (sound) streamed from the phone.
I use RxAndroidBle 1.11.0 library for BLE communication. As soon as I exchange some data via BLE Characteristic I unsubscribe from the RX observable so the library effectively calls: bluetoothGatt.disconnect() then blutetoohGatt.close()
(all those inside the DisconnectOperation class).
My problem is the fact that based on my observations, calling blutetoohGatt.disconnect() disconnects the classic BT profile (PBAP) as well.
Is it an expected behaviour?
I have investigated the code of generic Android P framework and it looks that calling bluetoothGatt.disconnect() -> bluetoothGatt.close() completely disconnects the device described by the given MAC Address:
BluteoothGatt#disconnect()
BlutetoothGatt#close()
BlutetoothGatt#unregisterApp()
I would risk a statement that I have quite unusual BLE use-case scenario where the phone (Central/Client) and the peripheral (custom Android HW/Server) are connected simultaneously via Classic BT profile and via BLE.
I suspect that disconnecting/closing device using its BT MAC address disconnect both profiles, hence the contacts sharing stops working.
Is it possible to disconnect BLE connection only, but not affect the classic BT (SPP/PBAP) connections between the two devices?
After further investigation described on that Github issue
I realised that my custom hardware is equipped with dual-mode BT adapter so it supports classic BT (BR/EDR) and the BLE one.
As soon as I pair an Android phone with the custom hardware via System Settings, classic BT profiles are bonded, but also my GATT Server advertises relevant services using the same MAC address which is used by the BR/EDR. Disconnecting BLE client connection disconnect BD/EDR as well.
What helps in my case is to not start pairing via System Settings, but let the GATT server advertise and let my BLE client app to connect (and trigger pairing) first. As a result I have a BLE connection with server available under "AA:AA:AA:AA:xx", while the classic BT profiles are connected to "BB:BB:BB:BB:yy" interface on the custom hardware.
Now, disconnecting BLE profile does not disconnect the classic one.
I am looking for a solution which would allow my GATT Server to be advertised with BLE only, but no luck so far.
Here are some interesting links I have found:
connectGatt creates connection over BT Classic instead of BLE
how to force BLE "just works" pairing in Android
BLE Dual-Mode

BLE connectivity not consistent on Samsung devices

We are using Android BLE code for connection to a custom hardware and with most mobile devices, this works perfectly. However, when it comes to Samsung with the Android OS Version 6.0.1, attempt for connection is not successful in most cases.
The problem is happening after trying to connect to a device with bluetoothDevice.connectGatt(context, false, gattCallback);
In onConnectionStateChange callback gatt status code 133 is received and in that case what the app does is to close the current instance of the BluetoothGatt and connect again to the device for a new BluetoothGatt instance. This workaround helps to get a connection after a couple of retries but this is definitely not the way how it should work.
After doing some BLE sniffing, it is clear that the device is not even trying to connect to the peripheral and just gives out the general gatt error (133). What is interesting that this has been a major problem only for the Marshmallow update, more specifically on the Android 6.0.1.
So my question is whether anybody experienced similar connectivity issues with only selected devices, where the mobile device tries to connect to the device and instead receives 133 gatt status code?

connectGatt on Samsung Galaxy S7 creates connection over Bluetooth Classic instead of BLE

I have a dual-mode (BR/EDR + BLE) device running a GATT server. The address is public and same for BLE and BD/EDR.
When I call connectGatt on Galaxy S7 with Android 6.0.1 (API level 23) and set the transport parameter as "TRANSPORT_LE" the phone still tries to establish connection over BD/EDR. It looks like the problem is related to the public address of the BLE because if I set it to private the connection is done over BLE, as expected.
This problem was observed only on Galaxy S7, on other phones (i.e Nexus 6P) the connection is always correctly done over BLE.
Is this an Android bug or am I missing something?
Bluetooth 4.0 specification states that if both devices support Classic and LEW then connection must be done over Classic. And Android stacks tend to follow this. Make you other device non-connectable and not in visible in inquiry and it should work fine
GATT is not transport specific and it is a framework implemented on top of attribute protocol(ATT). Its possible to access GATT over BR/EDR if the peripheral device is a dual mode device and supports GATT over BR/EDR. Bluetooth 4.X core specifications doesn't mandate access of connection bearer over GATT. Some android phones try using GATT over BR/EDR and applications can not control it. I also observed GATT over BR/EDR in Lenovo TAB 2 A8-50F.
An old question, but not answered...
You might have wrong FLAGS on the Advertising packet on the GATT device. Additionally the EIR (Extended Inquiry Response) packet transmitted by the Classic part of your implementation.
There is a flag "BR/EDR NOT SUPPORTED" that might help you in both of these cases.
This problem is common on the CSR chipsets, due to the default setup in the ADK code provided by CSR. Is there any chance you are using a CSR chip? your problem might not be on the android device?

Android BLE disconnects after bonding

I'm developing 2 Android BLE applications. One app will serve as the peripheral role and the other app will serve as the central role. On the peripheral app, there is one encrypted characteristic with PROPERTY_WRITE and PERMISSION_WRITE_ENCRYPTED.
The central app is able to connect to the peripheral and discover its services. The first time that central attempts to write to the encrypted characteristic, the system begins the bonding process and a dialog for entering the PIN appears. After the PIN is entered correctly, the characteristic can be written to successfully. If the central disconnects from the peripheral and then attempts to reconnect, a connection is briefly established but then disconnected. The onConnectionStateChange callback is received on the peripheral with a status of STATE_CONNECTED and then immediately called again with a status of STATE_DISCONNECTED.
Unless I manually unpair the devices (from the Bluetooth settings) and then start the connection process again, the central is unable to connect to the peripheral.
I've tried this solution but it did not work for me.
BLE Device Bonding Remove Automatically in Android
Both apps are running on devices with Android 5.
This issue seems to be resolved in Android 5.1.1. Originally, I was running the peripheral app on a Samsung Galaxy Tab A with Android 5.0.2. I switched to a Nexus 9 running 5.1.1 and 6.0.1 and did not encounter the issue described above.

Cannot establish BLE connection between Android 5 and BLE device

I'm stuck with implementing connection between Android Lollipop smartphone and BLE device (TI experimenter board with BLE module). I use following call to connect:
device.connectGatt(context, true, mGattCallback);
I've managed to establish connection for Android 4.3 and 4.4, but when I use this same code for Android 5, I get following error on BluetoothGattCallback::onConnectionStateChange:
onClientConnectionState() - status=133 clientIf=5 device=D0:36:12:CD:73:49
Error code 133 means GATT_ERROR.
I tried to use my own app, google sample and BLE scanner app from play market, but none of them were able to connect to device. I also tried several Android 5 smartphones with no luck.
However, I have another device (TI wireless connectivity development kit), and I can establish connection between it and Android 5 smartphone. So the issue is related to Android 5 and my particular device. I wonder how it can be solved or at least how can I debug this kind of error to find out the root cause.
P.S.
I also tried the approach proposed by #nayoso here, but it didn't helped either.
You may have hit the maximum connection number, see this:
https://www.youtube.com/watch?feature=player_detailpage&v=qx55Sa8UZAQ#t=1712

Categories

Resources