chipweinberger / flutter_blue_plus

Flutter plugin for connecting and communicationg with Bluetooth Low Energy devices, on Android, iOS, macOS
Other
787 stars 475 forks source link

[Help]: removeBond() fails saying "Device is disconnected" #1018

Closed Wes1324 closed 1 month ago

Wes1324 commented 1 month ago

Requirements

Have you checked this problem on the example app?

Yes

FlutterBluePlus Version

1.32.12. Also tried with 1.33.4

Flutter Version

3.19.3

What OS?

Android

OS Version

Android 12

Bluetooth Module

Unsure

What is your problem?

When removeBond() is invoked, a FlutterBluePlusException saying "Device is disconnected" is thrown.

I've debugged the code and the changed variable on this line is true, which makes me think the Android java code has completed successfully.

However, I can see that the listener that is set up here receives an event that the device is disconnected before the parent future completes.

What could be causing the device to become disconnected before the call to removeBond() completes?

There is no call to removeBond() in the example app so I couldn't try reproducing this in the example app.

Logs

Performing hot restart...
Syncing files to device SM A125F...
Restarted application in 5,864ms.
I/ViewRootImpl@a04a2c1[MainActivity]( 7299): ViewPostIme pointer 0
I/ViewRootImpl@a04a2c1[MainActivity]( 7299): ViewPostIme pointer 1
D/[FBP-Android]( 7299): [FBP] onMethodCall: flutterRestart
I/BluetoothAdapter( 7299): STATE_ON
D/[FBP-Android]( 7299): [FBP] disconnectAllDevices(flutterRestart)
D/[FBP-Android]( 7299): [FBP] connectedPeripherals: 0
D/[FBP-Android]( 7299): [FBP] onMethodCall: getAdapterState
I/ViewRootImpl@a04a2c1[MainActivity]( 7299): ViewPostIme pointer 0
I/ViewRootImpl@a04a2c1[MainActivity]( 7299): ViewPostIme pointer 1
I/ViewRootImpl@a04a2c1[MainActivity]( 7299): ViewPostIme pointer 0
I/ViewRootImpl@a04a2c1[MainActivity]( 7299): ViewPostIme pointer 1
D/[FBP-Android]( 7299): [FBP] onMethodCall: startScan
I/BluetoothAdapter( 7299): STATE_ON
I/BluetoothAdapter( 7299): STATE_ON
I/BluetoothAdapter( 7299): STATE_ON
I/BluetoothAdapter( 7299): STATE_ON
D/BluetoothLeScanner( 7299): Start Scan with callback
D/BluetoothLeScanner( 7299): onScannerRegistered() - status=0 scannerId=10 mScannerId=0
D/[FBP-Android]( 7299): [FBP] onMethodCall: stopScan
I/BluetoothAdapter( 7299): STATE_ON
I/BluetoothAdapter( 7299): STATE_ON
D/BluetoothLeScanner( 7299): Stop Scan with callback
D/[FBP-Android]( 7299): [FBP] onMethodCall: connect
I/BluetoothAdapter( 7299): STATE_ON
D/BluetoothGatt( 7299): connect() - device: C3:94:FC:8F:5B:81, auto: false
I/BluetoothAdapter( 7299): isSecureModeEnabled
D/BluetoothGatt( 7299): registerApp()
D/BluetoothGatt( 7299): registerApp() - UUID=17e636a2-8022-4dfe-b449-223ef0bf5e93
D/BluetoothGatt( 7299): onClientRegistered() - status=0 clientIf=10
D/BluetoothGatt( 7299): onClientConnectionState() - status=0 clientIf=10 device=C3:94:FC:8F:5B:81
D/[FBP-Android]( 7299): [FBP] onConnectionStateChange:connected
D/[FBP-Android]( 7299): [FBP]   status: SUCCESS
D/BluetoothGatt( 7299): onConnectionUpdated() - Device=C3:94:FC:8F:5B:81 interval=6 latency=0 timeout=500 status=0
D/BluetoothGatt( 7299): onConnectionUpdated() - Device=C3:94:FC:8F:5B:81 interval=39 latency=0 timeout=500 status=0
D/[FBP-Android]( 7299): [FBP] onMethodCall: requestMtu
D/BluetoothGatt( 7299): configureMTU() - device: C3:94:FC:8F:5B:81 mtu: 512
D/BluetoothGatt( 7299): onConfigureMTU() - Device=C3:94:FC:8F:5B:81 mtu=23 status=0
D/[FBP-Android]( 7299): [FBP] onMtuChanged:
D/[FBP-Android]( 7299): [FBP]   mtu: 23
D/[FBP-Android]( 7299): [FBP]   status: GATT_SUCCESS (0)
D/[FBP-Android]( 7299): [FBP] onMethodCall: discoverServices
D/BluetoothGatt( 7299): discoverServices() - device: C3:94:FC:8F:5B:81
D/BluetoothGatt( 7299): onSearchComplete() = Device=C3:94:FC:8F:5B:81 Status=0
D/[FBP-Android]( 7299): [FBP] onServicesDiscovered:
D/[FBP-Android]( 7299): [FBP]   count: 8
D/[FBP-Android]( 7299): [FBP]   status: 0GATT_SUCCESS
D/[FBP-Android]( 7299): [FBP] onMethodCall: setNotifyValue
D/BluetoothGatt( 7299): setCharacteristicNotification() - uuid: 00002a05-0000-1000-8000-00805f9b34fb enable: true
D/[FBP-Android]( 7299): [FBP] onDescriptorWrite:
D/[FBP-Android]( 7299): [FBP]   chr: 2a05
D/[FBP-Android]( 7299): [FBP]   desc: 2902
D/[FBP-Android]( 7299): [FBP]   status: GATT_SUCCESS (0)
D/[FBP-Android]( 7299): [FBP] onMethodCall: writeCharacteristic
D/[FBP-Android]( 7299): [FBP] OnBondStateChanged: bonding prev: bond-none
I/ViewRootImpl@a04a2c1[MainActivity]( 7299): MSG_WINDOW_FOCUS_CHANGED 0 1
I/ViewRootImpl@a04a2c1[MainActivity]( 7299): MSG_WINDOW_FOCUS_CHANGED 1 1
D/InputMethodManager( 7299): startInputInner - Id : 0
I/InputMethodManager( 7299): startInputInner - mService.startInputOrWindowGainedFocus
I/ViewRootImpl@a04a2c1[MainActivity]( 7299): stopped(false) old=false
I/DecorView( 7299): notifyKeepScreenOnChanged: keepScreenOn=false
I/ViewRootImpl@a04a2c1[MainActivity]( 7299): Relayout returned: old=(0,0,720,1600) new=(0,0,720,1600) req=(720,1600)0 dur=7 res=0x1 s={true -5476376635469570048} ch=false fn=4
I/ViewRootImpl@a04a2c1[MainActivity]( 7299): mWNT: t = android.view.SurfaceControl$Transaction@10105e8 fN = 4 android.view.ViewRootImpl.prepareSurfaces:2778 android.view.ViewRootImpl.performTraversals:4024 android.view.ViewRootImpl.doTraversal:2919 
I/ViewRootImpl@a04a2c1[MainActivity]( 7299): mWNT: merge t to BBQ
D/[FBP-Android]( 7299): [FBP] onCharacteristicWrite:
D/[FBP-Android]( 7299): [FBP]   chr: be34b890-fcf7-11e6-bb3b-fcaa142b0bea
D/[FBP-Android]( 7299): [FBP]   status: GATT_SUCCESS (0)
D/[FBP-Android]( 7299): [FBP] OnBondStateChanged: bonded prev: bonding
I/ViewRootImpl@a04a2c1[MainActivity]( 7299): ViewPostIme pointer 0
I/ViewRootImpl@a04a2c1[MainActivity]( 7299): ViewPostIme pointer 1
D/[FBP-Android]( 7299): [FBP] onMethodCall: discoverServices
D/BluetoothGatt( 7299): discoverServices() - device: C3:94:FC:8F:5B:81
D/BluetoothGatt( 7299): onSearchComplete() = Device=C3:94:FC:8F:5B:81 Status=0
D/[FBP-Android]( 7299): [FBP] onServicesDiscovered:
D/[FBP-Android]( 7299): [FBP]   count: 8
D/[FBP-Android]( 7299): [FBP]   status: 0GATT_SUCCESS
D/[FBP-Android]( 7299): [FBP] onMethodCall: writeCharacteristic
D/[FBP-Android]( 7299): [FBP] onCharacteristicWrite:
D/[FBP-Android]( 7299): [FBP]   chr: be34b890-fcf7-11e6-bb3b-fcaa142b0bea
D/[FBP-Android]( 7299): [FBP]   status: GATT_SUCCESS (0)
I/ViewRootImpl@a04a2c1[MainActivity]( 7299): ViewPostIme pointer 0
I/ViewRootImpl@a04a2c1[MainActivity]( 7299): ViewPostIme pointer 1
D/[FBP-Android]( 7299): [FBP] onMethodCall: removeBond
I/BluetoothDevice( 7299): removeBond() for device C394FC_1 called by pid: 7299 tid: 7299
W/flutter.stagin( 7299): Reducing the number of considered missed Gc histogram windows from 117 to 100
D/InputTransport( 7299): Input channel destroyed: 'ClientS', fd=175
D/InputTransport( 7299): Input channel destroyed: 'ClientS', fd=180
D/BluetoothGatt( 7299): onClientConnectionState() - status=0 clientIf=10 device=C3:94:FC:8F:5B:81
D/[FBP-Android]( 7299): [FBP] onConnectionStateChange:disconnected
D/[FBP-Android]( 7299): [FBP]   status: SUCCESS
D/BluetoothGatt( 7299): close()
D/BluetoothGatt( 7299): unregisterApp() - mClientIf=10
D/[FBP-Android]( 7299): [FBP] OnBondStateChanged: bond-none prev: bonded
[log] FlutterBluePlusException | removeBond | fbp-code: 6 | Device is disconnected <--- My catch block log showing exception
Wes1324 commented 1 month ago

It's also worth noting that the paired device disappears from the list of paired devices in my phone's settings after this call to removeBond(), despite the exception that is thrown from the library. Further evidence that the OS has actually successfully removed the bond.

shubhamsinghmutualmobile commented 1 month ago

I'm facing the same issue on version 1.33.4, is there a fix?

chipweinberger commented 1 month ago

is your device supposed to disconnect when you remove the bond?

it seems android updates the connectionState stream before the bondState stream

the best solution i can think of is to try to get it to either:

  1. stay connected
  2. update bondState stream first
chipweinberger commented 1 month ago

a simple fix is to just remove the fbpEnsureDeviceIsConnected line

Wes1324 commented 1 month ago

Thanks for the replies @chipweinberger.

is your device supposed to disconnect when you remove the bond?

That was the question I had. I was surprised to see that calling removeBond() disconnects the device too. I guess it kind of makes sense that Android would do this but I wasn't expecting it because I didn't see that behaviour documented anywhere.

it seems android updates the connectionState stream before the bondState stream

Yeh, I agree. That seems to be the root cause here.

a simple fix is to just remove the fbpEnsureDeviceIsConnected line

I think that would fix it (I can test and confirm tomorrow)... but can you foresee any issues in doing that? Do you remember why it was thought to be necessary to continuously monitor the connection state when removing the bond?

chipweinberger commented 1 month ago

it's possible your ble peripheral initiated the disconnection, not android

you should log the disconnectionReason


Do you remember why it was thought to be necessary to continuously monitor the connection state when removing the bond?

I added that line because if the device disconnects, it would (usually) be a waste of time to wait until the full timeout

perhaps just put this change behind a flag. removeBond(ensureConnection:false)

shubhamsinghmutualmobile commented 1 month ago

perhaps just put this change behind a flag. removeBond(ensureConnection:false)

This seems like a good idea!

chipweinberger commented 1 month ago

however, you should confirm why the device is disconnecting.

check your peripheral's firmware logs.

Wes1324 commented 1 month ago

We have decided that we are not going to call removeBond anymore so this is no longer an issue for us. Thanks for your help.