5

I am developing an Android app that connects to a custom Bluetooth device. A number of posts have been very helpful (such as this and this), but I am experiencing an issue not solved by any if those suggestions.

After a successful Bluetooth connection, I call BluetoothGatt.discoverServices, which on most devices performs correctly. On the Nexus 5 and Samsung Note 3, I never receive any response (onServicesDiscovered), either successful or otherwise. This occurs on the very first connection attempt and no combination of disconnect() or close() seems to fix it.

I have anecdotal evidence for this being an Android OS bug; only our Nexus 5 that was still on 4.4.2 experienced this problem, and upgrading to 4.4.3 seems to have fixed it. This isn't yet an option for the Samsung however and I'd like to find a workaround if possible. I know we've connected to Nexus 5 without these problems in the past; while I'm trying to track down what might have changed I'd appreciate any thoughts.

Samsung Note 3 Logs:

07-02 17:29:54.891 I/PeripheralManager( 8282): Connect has been called on HFEC161332B90C15C29E DF:5F:C8:DF:04:35 -43 , shouldPair = true
07-02 17:29:54.891 I/PeripheralManager( 8282): BTSTATE acquiring new gatt and connecting...
07-02 17:29:54.891 D/BluetoothGatt( 8282): connect() - device: DF:5F:C8:DF:04:35, auto: false
07-02 17:29:54.891 D/BluetoothGatt( 8282): registerApp()
07-02 17:29:54.896 D/BluetoothGatt( 8282): registerApp() - UUID=2fc3ce73-c50c-4cda-8b82-1532a5dccb14
07-02 17:29:54.896 D/BtGatt.GattService( 3434): registerClient() - UUID=2fc3ce73-c50c-4cda-8b82-1532a5dccb14
07-02 17:29:54.896 D/BtGatt.btif( 3434): btif_gattc_register_app
07-02 17:29:54.896 D/BtGatt.btif( 3434): btgattc_handle_event: Event 1000
07-02 17:29:54.896 D/BtGatt.btif( 3434): btif_gattc_upstreams_evt: Event 0
07-02 17:29:54.901 D/BtGatt.GattService( 3434): onClientRegistered() - UUID=2fc3ce73-c50c-4cda-8b82-1532a5dccb14, clientIf=5
07-02 17:29:54.901 I/BluetoothGatt( 8282): Client registered, waiting for callback
07-02 17:29:54.901 D/BluetoothGatt( 8282): onClientRegistered() - status=0 clientIf=5
07-02 17:29:54.901 D/BtGatt.GattService( 3434): clientConnect() - address=DF:5F:C8:DF:04:35, isDirect=true
07-02 17:29:54.901 D/BtGatt.btif( 3434): btif_gattc_open
07-02 17:29:54.901 D/BluetoothAdapter( 8282): stopLeScan()
07-02 17:29:54.906 D/BtGatt.btif( 3434): btgattc_handle_event: Event 1004
07-02 17:29:54.906 D/BtGatt.btif( 3434): btif_get_device_type: Device [df:5f:c8:df:04:35] type 2, addr. type 1
07-02 17:29:54.906 D/BtGatt.btif( 3434): btif_gattc_upstreams_evt: Event 2
07-02 17:29:54.906 D/BtGatt.GattService( 3434): onConnected() - clientIf=5, connId=5, address=DF:5F:C8:DF:04:35
07-02 17:29:54.906 D/BluetoothGatt( 8282): onClientConnectionState() - status=0 clientIf=5 device=DF:5F:C8:DF:04:35
07-02 17:29:54.906 I/PeripheralManager( 8282): Gatt State Connected
07-02 17:29:54.906 D/BluetoothGatt( 8282): discoverServices() - device: DF:5F:C8:DF:04:35
07-02 17:29:54.911 D/BtGatt.GattService( 3434): discoverServices() - address=DF:5F:C8:DF:04:35, connId=5
07-02 17:29:54.911 D/BtGatt.btif( 3434): btif_gattc_search_service
07-02 17:29:54.911 I/PeripheralManager( 8282): Gatt Service Discovery Started
07-02 17:29:54.911 D/BtGatt.btif( 3434): btgattc_handle_event: Event 1006
…
07-02 17:30:24.901 W/PeripheralManager( 8282): Connection time out hard
07-02 17:30:24.921 I/PeripheralManager( 8282): canceling connection

Connect Code:

public void connect(final Peripheral peripheral, boolean pair) {
    Log.i(TAG,  "Connect has been called on " + peripheral.toString() + ", shouldPair = " + pair);
    this.shouldPair = pair;
    bluetoothHandler.post(new Runnable() {
         @Override
         public void run() {
            if(isConnected) {
                Log.w(TAG, "Connecting when already connected!");
                return;
            }
            if (mBluetoothAdapter == null || peripheral == null || peripheral.getAddress() == null) {
                Log.e(TAG, "BluetoothAdapter not initialized or unspecified address.");
                return;
            }
            final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(peripheral.getAddress());
            if (device == null) {
                Log.e(TAG, "Device not found.  Unable to connect.");
                return;
            }
            if(mBluetoothGatt != null) { // use existing gatt if present and not closed
                Log.i(TAG, "connecting to existing gatt...");
                mBluetoothGatt.connect();
            } else {
                Log.i(TAG, "acquiring new gatt and connecting...");
                mBluetoothGatt = device.connectGatt(context, false, mGattCallback);
            }
         }
    });

    lastConnectedPeripheral = peripheral;
}

Discovering Services:

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
    @Override
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
        if (status == BluetoothGatt.GATT_SUCCESS) {
            if (newState == BluetoothGatt.STATE_CONNECTED) {
                Log.i(TAG,"Gatt State Connected");
                isBluetoothConnected = true;
                tryDiscoveringServices();
                ...

Please let me know what additional information might shed light on this. Thanks!

EDIT: After a change in our firmware, the problem has lessened: instead of never connecting, it takes just over one minute to connect. This indicates the problem is at least partially due to our particular bluetooth device in addition to whatever Android OS changes. I will update if I discover how to solve this related problem.

Community
  • 1
  • 1
Tbadams
  • 424
  • 1
  • 5
  • 20
  • I think the bluetooth device is actually NOT connected to you android device. Try to use another device / iOS device to verify this. – reTs Jul 04 '14 at 02:12
  • There is a bug that android will receive CONNECTED even if it is not connected. Maybe a cache issue. – reTs Jul 04 '14 at 02:13
  • Our packet sniffer reports that after the initial BLE connection request, the android device never sends any more packets. So yes, not being connected seems reasonable to me. However, the issue isn't transient; failing the connection and trying again always seems to have the same result as before. Any ideas on how to get that initial connection for real? – Tbadams Jul 07 '14 at 17:44
  • For me, this is always solved by restarting the bluetooth. Pretty sure that's not going to work for you, though. I have never seen this behaviour for the first connection attempt. – reTs Jul 08 '14 at 01:49
  • When/where do you call the `BluetoothGatt.discoverServices` method? I have a Samsung Note 3 and I have never seen this issue – KikiTheMonk Jul 15 '14 at 05:29
  • @Kyriakos I've posted the code where the call is made, thanks for your response. Also read my edit, it looks like our device firmware was contributing to the problem. Not sure exactly what did, possibly lowering the broadcast interval. – Tbadams Jul 18 '14 at 02:02

0 Answers0