NordicSemiconductor / Android-BLE-Library

A library that makes working with Bluetooth LE on Android a pleasure. Seriously.
BSD 3-Clause "New" or "Revised" License
1.99k stars 414 forks source link

ConnectionObserver.onDeviceDisconnected() can never report REASON_TERMINATE_PEER_USER #284

Closed rickymohk closed 3 years ago

rickymohk commented 3 years ago

ConnectionObserver.onDeviceDisconnected() always reports REASON_LINK_LOSS even if the peripheral initiate disconnection with BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION. Expected to report REASON_TERMINATE_PEER_USER in that case.

philips77 commented 3 years ago

REASON_LINK_LOSS is reported when you connect with autoConnect = true and when the device disconnects without you explicitly calling disconnect().enqueue(). Have a look at: https://github.com/NordicSemiconductor/Android-BLE-Library/blob/1b836ad846ef86fed35fc93807ff8e1056afd57f/ble/src/main/java/no/nordicsemi/android/ble/BleManagerHandler.java#L1518-L1534 The userDisconnected flag is set to true in here: https://github.com/NordicSemiconductor/Android-BLE-Library/blob/1b836ad846ef86fed35fc93807ff8e1056afd57f/ble/src/main/java/no/nordicsemi/android/ble/BleManagerHandler.java#L587-L588 When autoConnect flag is false, this is always set to true.

rickymohk commented 3 years ago

The case I am talking about is when the peripheral side initiates disconnection. In that case, REASON_LINK_LOSS is still reported in the central app. There is currently no way to differentiate a connection lost due to bad signal or due to the peripheral explicitly terminating the connection. REASON_TERMINATE_PEER_USER instead of REASON_LINK_LOSS should be reported when the peripheral explicitly terminates the connection so that the central can determine which case it is.

philips77 commented 3 years ago

What would be expected behavior from the phone side then? Remember, that the connection was initiated with autoConnect = true, so the phone will try to reconnect to the device which has disconnected a moment ago.

The reason why you always get link loss in this situation, is that the autoConnect flag, in my opinion, should be used for use cases when the connection should be open for as long as possible, and only loosing a signal could in fact cause disconnection. Otherwise, there is no clear behavior what should happen when the remote initiates disconnection: should the library stop reconnecting, should it continue to try to establish connection, or... a user setting?

rickymohk commented 3 years ago

The behavior could keep the same, but at least give a way for developer to differentiate whether the connection is initiated by the peripheral, in case that information is necessary for the App to determine what to do. In my case, I want to auto reconnect my peripheral if it is disconnected due to let say out of range, but stop auto reconnect if the peripheral explicitly initiates disconnection (e.g. there could be an unpair button or a factory reset button on the peripheral) . Even if the phone keeps auto reconnecting, at least I can write my own code to explicitly call disconnect().enqueue() if I know the disconnection was intentionally initiated by the peripheral.

philips77 commented 3 years ago

Let it be.

cocomeneau commented 2 years ago

The problem describe by @rickymohk still exist on some devices (with Android-BLE-Library v2.3.1). I'm using a Redmi note 7 (Android 10) I got no problems but with a Samsung Galaxy S20 (Android 12) I always have REASON_LINK_LOSS when my BLE device perform a disconnection. I also tried with the last version of the Android-BLE-Library (v2.5.1) and it's the same.