Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Every connection request is being treated as direct connect request + android ble

We are writing a ble application where want to have a persistent connection with the peripheral we want to connect. For the same purpose we want to re-connect with the peripheral whenever we loose a existing connection. So our android application as a central just tries to reconnect by creating new bluetoothgatt object by calling bluetoothdevice.connectgatt with autoconnect as true.

But whenever we try to do that our reconnection gets failed with

12-02 21:47:11.865: D/BluetoothGatt(31963): onClientConnectionState() - status=133 clientIf=6 device=******** callback.

because our connection request is being treated as a direct connection request on nexus 5 lollipop

Here are the logs

12-03 11:46:12.804: D/BluetoothGatt(6902): connect() - device: 58:EB:14:3D:2A:38, auto: true
12-03 11:46:12.804: D/BluetoothGatt(6902): registerApp()
12-03 11:46:12.804: D/BluetoothGatt(6902): registerApp() - UUID=b8f9298b-4a95-41be-80d6-22d82c498c5c
12-03 11:46:12.807: D/BtGatt.GattService(31817): registerClient() - UUID=b8f9298b-4a95-41be-80d6-22d82c498c5c
12-03 11:46:12.808: D/BtGatt.GattService(31817): onClientRegistered() - UUID=b8f9298b-4a95-41be-80d6-22d82c498c5c, clientIf=6
12-03 11:46:12.808: D/BluetoothGatt(6902): onClientRegistered() - status=0 clientIf=6
12-03 11:46:12.808: D/BtGatt.GattService(31817): clientConnect() - address=58:EB:14:3D:2A:38, isDirect=true
12-03 11:46:12.809: D/BtGatt.btif(31817): btif_get_device_type: Device [58:eb:14:3d:2a:38] type 2, addr. type 0
12-03 11:46:12.811: D/BLEManager(6902): Trying to create a new connection.
like image 995
kaps Avatar asked Dec 03 '14 19:12

kaps


2 Answers

The problem is a race condition described here: https://code.google.com/p/android/issues/detail?id=69834

A possible solution until they fix it (will they?) is to use reflection to manually construct a gatt object, set the mAutoConnect flag to true and call connect.

like image 41
Emil Avatar answered Nov 07 '22 05:11

Emil


The problem has been fixed in the master android branch, May 2016. There are mixed reports about whether it has ended up in Nougat or not, possibly device dependent, but it is definitely still a bug in Marshmallow.

The reflection code required to do the workaround quickly becomes complicated because the classes IBluetoothManager and IBluetoothGatt are not available in user code.

Fortunately, someone has already written a very small, clear library which does this exact routine for us.

https://github.com/Polidea/RxAndroidBle/blob/master/rxandroidble/src/main/java/com/polidea/rxandroidble/internal/util/BleConnectionCompat.java

Using this class, one need only call:

mBluetoothGatt = (new BleConnectionCompat(context)).connectGatt(device, autoConnect, callback)

instead of

mBluetoothGatt = device.connectGatt(context, autoConnect, callback);

It is working beautifully for me. I take no credit whatsoever for this, it is entirely the work of uKL

Also, note it is under Apache License 2.0 Copyright 2016 Polidea Sp. z o.o

like image 125
Mark Ch Avatar answered Nov 07 '22 05:11

Mark Ch