Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

BluetoothGattServer cancelConnection does not cancel the connection

I have Android application which exposes BLE Server. I connect with BluetoothGattServer#connect. It works - my app gets call to BluetoothGattServerCallback#onConnectionStateChange with STATE_CONNECTED. When I'm done with the client I try to disconnect from my app with BluetoothGattServer#cancelConnection.

But I do not get call to BluetoothGattServerCallback#onConnectionStateChange and it seems that the connection is still active as my BLE client does not start to advertise (which it does when nothing is connected to it).

In logcat I see only:

BluetoothGattServer: cancelConnection() - device: XX:XX:XX:XX:XX:XX

The funny part is, my app gets call to BluetoothGattServerCallback#onConnectionStateChange with STATE_DISCONNECTED as soon as I turn off BT completely.

Similar issues in Google's tracker: 63461 and 63464.

like image 472
Marian Paździoch Avatar asked Aug 04 '16 08:08

Marian Paździoch


3 Answers

When newState==BluetoothProfile.STATE_CONNECTED, you have to call BluetoothGattServer.connect();.

@Override
public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {
    super.onConnectionStateChange(device, status, newState);
    if (newState == BluetoothProfile.STATE_CONNECTED){
        mDevice = device;
        mBluetoothGattServer.connect(device, false);
    }else {
        mDevice = null;
    }
}

private void cancelConnection(){
    if (mDevice != null) {
        mBluetoothGattServer.cancelConnection(mDevice);
    }
}
like image 71
yotods Avatar answered Nov 04 '22 17:11

yotods


Encountering same issue when calling disconnect() method.. no disconnect is given in onConnectionStateChange in my BluetoothGattCallback.

Cycling Bluetooth seems the be the only thing that works.

edit: also, after disconnect() and close() method are called, I am still connected according to this code:

public int getConnectedBLEDevices() {
        int i = 0;
        List<BluetoothDevice> devices = mBluetoothManager.getConnectedDevices(BluetoothProfile.GATT);
        for(BluetoothDevice device : devices) {
            if(device.getType() == BluetoothDevice.DEVICE_TYPE_LE) {
                Logs.writeEvent(TAG+".getConnectedBLEDevices()", device.getAddress() + "\n"+ getStateAsString(mBluetoothManager.getConnectionState(device, BluetoothProfile.GATT)));
                i++;
            }
        }
        return i;
    }
like image 2
user1064249 Avatar answered Nov 04 '22 16:11

user1064249


pls see https://issuetracker.google.com/issues/37127644

Status: Won't Fix (Intended Behavior) You must call BluetoothGattServer.connect() to mark connection as used, then BluetoothGattServer.disconnect() to mark it as no longer used. Then after a timeout stack can decide to disconnect from the remote if no one else is using the connection. If BluetoothGattServer.connect() is not called after the connection is established, then the stack is keeping the connection until some gatt client/server app start using this connection.

like image 1
Hard Song Avatar answered Nov 04 '22 17:11

Hard Song