-
Notifications
You must be signed in to change notification settings - Fork 574
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rapid connect/disconnect sequence fails to properly disconnect from BLE device #483
Comments
Hello, This seems to be an Android BLE stack issue — could you share phone model / OS version? Best Regards |
Phone Model: Google Nexus 6P I'll have code snippet to repro the issue in a few minutes too. |
Here is the code sample that reproduces the issue. You may have to vary the timeout based on how long it takes to establish connection with your BLE device.
|
If timeout is > then amount of time needed to establish connection, everything works properly. Here is the corresponding log output: Cancel Subscription after 3000msApp Log
BLE Device Log
|
If timeout is < connection establishment time, then disconnect event is never received by BLE device Cancel Subscription after 250msApp Log
BLE Device Log
|
The same behavior can also be reproduced with RxJava2 and latest RxAndroidBle 1.7.0. Here is isolated and standalone repro code:
|
Here is application log corresponding to the most recent sample code:
|
@dariuszseweryn I tested this issue on another Android device and was able to reproduce this behavior so the problem does not look to be specific to Phone/Android OS combination. Hardware: Asus Tablet Model P00C |
This may not be related to a specific phone/OS mix but a general Android BLE stack issue. I can recall a similar issue with I think I have found a bug report for this exact case. In this situation calling |
Google's bug report does indeed fit the pattern so at least on my side I will put in a workaround to mitigate this issue. It doesn't seem like Google is eager to fix the issue though based on when the issue was filed. Sigh... Thanks for the clarification and help. |
Feel free to share how did you implemented the workaround and if it helped |
The workaround used is less than ideal but it works for my use case. Before cancelling subscription (forcing disconnect), I added an optional delay of 1-2 seconds if the connection is still being established. Something along the lines of:
|
I am afraid that if the device will get connected after the A valid workarounds without changing the library internals would be:
|
I have the same issue on: |
@digitalstreamio @DariuszAniszewski @AnDrOiD73dd This makes me think about my case #530 . Maybe try adding a step waiting for the connection state to become |
@aptly-io, another case is described here. There is no question of reconnection. But you are right that a delay is required when reconnecting, otherwise we will get a connection error. |
What I see in the code of RxAndroidBle is that only close() is called. That unregisters your callback so you will never receive the disconnected event! This is not an Android bug. If you want to stop a connection attempt or disconnect while connected you must first call disconnect(). Then wait for the disconnected state to come in and then call close(). |
@weliem I have performed tests with also |
@dariuszseweryn , I'll do some tests as well. But assuming you are right, I suspect the issue is related to the asynchronous nature of connectGatt, disconnect and close...if you call them too quickly they will be in the middle of executing and the next call may not work as expected. Android is not queueing them up....so anything might happen! Still wondering though why you'd want to cancel a connection after 0.2 seconds of issuing it....? @digitalstreamio , any comments? |
Ok, I just did a small test:
I managed to get down to 100 ms for issuing a disconnect. So essentially, connectGatt takes around 100 ms to complete on my phone (Nokia 8 Sirocco with Android 9 which is quite fast). After that you can issue a disconnect but if you do it earlier it indeed doesn't work. So when I tried 80ms I did not see 'cancelOpen' in the log and the phone indeed still connected to the device.... |
Here is another test on a Samsung S5 running Android 6
As you can see, there is no major difference in timing. So the bottomline is that connectGatt simply needs to complete before you can cancel the connection by calling disconnect. Seems to be around 80-100 ms. |
Thing is that the fast issued disconnect it is probably easiest to way to reproduce this bug. There is probably a race condition where a connection process with a well timed disconect/close will leave the Java part of the API oblivious to a fact that the BT controller is connected to the peripheral with no way to connect/disconnect. |
@digitalstreamio @dariuszseweryn I faced the issue of the connection not being disposed with a Nexus 6P as well. The only thing different from @digitalstreamio 's case is that I retrieved the device from a scan instead of using its MAC address. In my case, I'm also forcing the bonding before connecting. Don't know enough about Bluetooth to determine if this is relevant but the information may help shed some light. The nasty workaround I found to work is to call |
I am facing this issue due to race condition. I dispose connection before calling establish connection function. But sometimes app crashed so how would I add a delay before establishing connection to dispose connection. I am using establishedConnection (false) |
Summary
Rapid connect/disconnect sequence fails to properly disconnect from BLE device.
When creating subscription to RxBleDevice.establishConnection() and cancelling it prior to connection being established, the physical BLE device remains in connected state (verified through JLink debugger output). This only happens when unsubscribe is called prior to fully establishing connection. If delay is inserted between subscribe/unsubscribe calls, then connect and disconnect sequence works properly.
Library version
implementation "com.polidea.rxandroidble:rxandroidble:1.6.0"
Preconditions
Steps to reproduce actual result
Minimum code snippet reproducing the issue
Logs from the application running with setting
RxBleLog.setLogLevel(RxBleLog.VERBOSE)
Actual result
BLE Device indicates it is still in connected state and never receives DISCONNECTED event.
INFO [main] on_ble_evt: CONNECTED
Expected result
BLE Device receives DISCONNECTED event
INFO [ble] on_ble_evt: DISCONNECTED. Reason: 0x13
[Edit @dariuszseweryn] Notes:
Related bug on Google's Issue Tracker: https://issuetracker.google.com/issues/37121223
The text was updated successfully, but these errors were encountered: