Skip to content
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

Discovery service fails after bluetooth turn off/on #45

Closed
klemzy opened this issue Jul 13, 2016 · 8 comments
Closed

Discovery service fails after bluetooth turn off/on #45

klemzy opened this issue Jul 13, 2016 · 8 comments
Assignees
Labels
bug Bug that is caused by the library

Comments

@klemzy
Copy link

klemzy commented Jul 13, 2016

Summary

My current situation is that I have connected to device with autoconnect flag set. Which means I am waiting for the device to appear in order to connect. When I turn off/on bluetooth I establish again the connection. When the device becomes visible it connects but it hangs on discover services. I have done some debugging with nrf Connect and discover services returns true. Also I debugged RxAndroidBle and RxBleRadioOperationServicesDiscover operation returns true from bluetoothGatt.discoverServices(). However onServicesDiscovered is never called inside RxBleGattCallback. If I clear the app and open again then it immediatelly connects. I am still looking what might be wrong but no solution so far.

Preconditions

Connect with auto connect flag needs to be established.

Steps to reproduce actual result

  1. Connect with auto connect flag
  2. Turn airplane mode on
  3. Turn airplane mode off
  4. Connect with auto connect flag (make sure device is advertising)

Actual result

Discover services hangs

Expected result

Connection proceeds with onServicesDiscovered callback fired

Do you maybe have any ideas what I might be doing wrong?

Thanks!

@dariuszseweryn
Copy link
Owner

Hello,
Thank you for your report.
I will check tomorrow this scenario. I think that it may be a bug in the library because it is listening for BluetoothAdapter's state changes and maybe when the connection is not yet established it's misbehaving.

@klemzy
Copy link
Author

klemzy commented Jul 14, 2016

I see. Also some more information. The weird thing is that in RxBleGattCallback onConnectionStateChange gets called but not onServicesDiscovered. Also another thing. When I debugged with breakpoints on bluetoothGatt.discoverServices() and onComplete inside RxBleRadioOperation getSubscriber then it worked.

@dariuszseweryn
Copy link
Owner

I have tried to reproduce the issue today on Motorola XT1030 but apparently switching off the BluetoothAdapter while establishConnection(_, true) is making the connection never being established without any exceptions. I have waited for around 10 minutes.

Could you paste the code you are using and which mobile phone model?

Apparently it would be best to make the library fail any connections that are in the process of establishing if the BluetoothAdapter will go off.

@dariuszseweryn dariuszseweryn self-assigned this Jul 14, 2016
@dariuszseweryn dariuszseweryn added the bug Bug that is caused by the library label Jul 14, 2016
@klemzy
Copy link
Author

klemzy commented Jul 15, 2016

I see, but did you try to connect again after turn off/on with device being discoverable? Because my problem is that when Bluetooth turns on I call establishConnection and then it hangs.

I am using Nexus 6P, Android N Preview 4

device.establishConnection(context, true)              
            .flatMap(rxBleConnection ->
                    rxBleConnection.getCharacteristic(CHARACTERISTIC)
                            .flatMap(characteristic -> 
                                    rxBleConnection.writeCharacteristic(setValue(characteristic))
                                            .cache()
                                            .flatMap(characteristic1 -> readData(rxBleConnection))
                            )
            );

This is the code.

@dariuszseweryn
Copy link
Owner

dariuszseweryn commented Jul 15, 2016

I don't see if you're unsubscribing the first connection (started before the off/on switch) and you shouldn't be able to call on the same device .establishConnection() again anyway because it would emit BleAlreadyConnectedException.

It would be great to see the logs from the library (use RxBleLog.setLogLevel(RxBleLog.VERBOSE))

You could also describe when do you unsubscribe from the first connection.

@klemzy
Copy link
Author

klemzy commented Jul 15, 2016

I am calling unsubscribe but I did not include the whole snippet. I am listening to the adapter on/off and unsubscribing appropriately. Also I unsubscribe when I finish reading from the device.

I am using latest code commited in this repository.

When I was debugging (I included library source into my project) the code worked?!?!?, services got discovered.

I also found a way to simulate this by not turning on/off the adapter:

.subscribe(bluetoothGatt -> {
                        try {
                            Method method = bluetoothGatt.getClass().getMethod("refresh");
                            if (method != null) {
                                method.setAccessible(true);
                                boolean result = (boolean) method.invoke(bluetoothGatt);
                                RxBleLog.d("Refresh result " + result);
                            }
                        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
                            e.printStackTrace();
                        }
                        bluetoothGatt.close();
                    },
                    throwable -> onError(throwable),
                    () -> onCompleted()
)

Basically inside RxBleRadioOperationDisconnect I have added refresh function. This clears discovered services cache from the device (which also happens on adapter off). At least what the Google and internet says.

So at the moment I managed to fix this with the folling code inside RxBleRadioOperationServicesDiscover.

Handler handler = new Handler(Looper.myLooper());
handler.postDelayed(() -> {
    final boolean success = bluetoothGatt.discoverServices();
    RxBleLog.d("Discover services " + success);
    if (!success) {
        subscription.unsubscribe();
        subscriber.onError(new BleGattCannotStartException(BleGattOperationType.SERVICE_DISCOVERY));
    }
}, 5000);

Maybe there is a better solution to this problem.

I have attached logs.logs.txt

dariuszseweryn added a commit that referenced this issue Jul 20, 2016
…ect=true` flag and before connection being established the `BluetoothAdapter` switched off.

Summary: Related: #45

Reviewers: michal.zielinski, pawel.urban

Reviewed By: michal.zielinski, pawel.urban

Differential Revision: https://phabricator.polidea.com/D1699
@dariuszseweryn
Copy link
Owner

What do you refer to when saying I am using latest code committed in this repository.? The latest SNAPSHOT or the latest release? Maybe your SNAPSHOT is not up to date. Unfortunately I couldn't reproduce your problem and refreshing the BluetoothGatt is not the best idea to reproduce the behaviour as I think it may not be the cause of the original problem.

@dariuszseweryn
Copy link
Owner

Actually last SNAPSHOT was from May since there was a styling issue which prohibited pushing to the maven repo. There is a new SNAPSHOT available since yesterday now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Bug that is caused by the library
Projects
None yet
Development

No branches or pull requests

2 participants