Giter VIP home page Giter VIP logo

Comments (60)

philips77 avatar philips77 commented on August 16, 2024 1

Hi, error 133 that happens 30 sec after connectGatt is a timeout. The phone didn't receive any advertising packet from this device during that time and thrown an error.
Make sure that the device is advertising, that the address you try to connect is correct, that you scanned the device you want to connect to or it has a public device type, and you didn't reach any limits of connected devices, etc. I don't know what else may cause a timeout. Does it happens 100% of times?

from android-ble-library.

eliotstock avatar eliotstock commented on August 16, 2024 1

Thanks Maciek, this is super helpful. No, I haven't had time to try the background service yet. Regarding "list of bonded devices seems to be a trigger": I also list all the bonded devices in my app, with bluetoothAdapter.getBondedDevices(). One of us might get some mileage out of stepping through the Android BLE stack sources.

The Java layer of it is here (but you probably already have the sources in the Android SDK inside Android Studio): https://android.googlesource.com/platform/packages/apps/Bluetooth/. It's 80K lines of Java but you should be able to just step into methods from a breakpoint in your own code. Eventually you'll hit some JNI calls and won't be able to step down any further. So far I haven't seen any code that would behave differently based on whether the caller is a service or an activity.

Below that it's this code: https://android.googlesource.com/platform/system/bt/, which is 200K lines of C++. You might be able to use gdb to set a breakpoint in there if you can find the function that the JNI methods in the Java layer map to and have a userdebug Android phone. I haven't tried yet.

from android-ble-library.

mtomczynski avatar mtomczynski commented on August 16, 2024 1

In my case the problem was in the connection not scanning. Manage to fix it by forcing such config:

bluetoothDevice.connectGatt(
                context,
                false,
                connectCallback,
                BluetoothDevice.TRANSPORT_AUTO,
                BluetoothDevice.PHY_LE_CODED
            )

Problem exist only on Android 10 when bonded to more than one device and only this particular config solves it. But this still is a bit flaky solution. After connecting to device with different settings, it breaks all future connections even for this config.

Not going to reopen this as let's say it's fixed. But maybe someone have any idea or wild guesses why this particular config works and others don't?

from android-ble-library.

eliotstock avatar eliotstock commented on August 16, 2024 1

No idea, sorry, but it does sound like we should reopen the issue.

from android-ble-library.

philips77 avatar philips77 commented on August 16, 2024 1

Hi,
I did some tests and can confirm the issue. After disconnecting from a bonded device using Pixel 4 with Android 10, and trying to reconnect I was getting error 8 (timeout) (not 133) very often. By using autoConnect=true it finally manage to connect after few tries after which the connection seemed stabled. On next disconnection situation repeated.

There is #232 open, which should improve the behavior on bonded devices, as the first connection attempt would switch to one using autoConnect automatically.

from android-ble-library.

philips77 avatar philips77 commented on August 16, 2024

I'll gladly look into this on Monday. To be honest, I have no idea what's may be wrong. I have an old Samsung S3 which sometimes requires factory reset to be able to connect again, but then there nRF Connect doesn't work as well (actually nothing really works), so that can't be that.

Did you try refreshing cache in nRF Connect after connecting?

from android-ble-library.

eliotstock avatar eliotstock commented on August 16, 2024

Thanks. I added your Github user to both repos (Android app and device firmware), in case it helps. Nope, I didn't try refreshing cache in nRF Connect. Will try that (also Monday though, probably).

from android-ble-library.

eliotstock avatar eliotstock commented on August 16, 2024

Whether or not I see this timeout seems to depend on what code I execute immediately after the call to .enqueue(). If I do nothing at all, I get a connection OK. If I attempt to go off to Firebase and get some data, I get the timeout.

I'm not yet conscious of which threads everything is happening on here. I also presumed from the logging from the Android BLE stack that the connection had already been started. Are there any rules about which threads things should be happening on that I need to observe? I'm calling enqueue() in a callback from an earlier Firebase operation.

from android-ble-library.

philips77 avatar philips77 commented on August 16, 2024

The BLE Library is using the main thread for all operations and callbacks. The requests, internally on Android, are processed on some other thread, depending on the system, but I call all gatt methods on UI thread. This is because it used to be more stable like this on many phones.
I'm planning to allow to specify a Handler for callbacks, but I'll still be calling methods on UI.
If you find a solution to your timeout please share. If there is that could improve the behavior on library side, we should have it.

from android-ble-library.

eliotstock avatar eliotstock commented on August 16, 2024

OK, thanks. I'll keep tinkering and update here if I find anything conclusive, for the benefit of anyone else seeing something similar. Closing this for now.

from android-ble-library.

eliotstock avatar eliotstock commented on August 16, 2024

Hiya. Re-opening this, sorry!

I've just repro'ed this on 2.1.0 in a situation where I'm not really doing anything in my Android code right after calling enqueue(). The nRF Connect app is able to connect to the same device running the same firmware. From Wireshark captures (attached below), I can see the CONNECT_REQ from the phone when use nRF Connect, but I never see it when I use my own app. I'm calling enqueue() from an onItemClick() handler set on a view, much like the nRF Blinky app does, so this is happening on the main/UI thread. I could try doing this in a handler instead, but as you say, you use the main/UI thread for the operation anyway.

I can step through your code and see that BleManager.nextRequest() is really being called and ConnectRequest code is executing. And from the logcat, I'm still seeing the call to connect() on BluetoothGatt, but the attempt to connect doesn't actually happen on the air.

2019-02-16 15:28:00.872 7105-7105/cc.biketracker.android I/ProvisioningActivity: Device C7:56:60:F0:56:58 clicked.
2019-02-16 15:28:00.899 7105-7105/cc.biketracker.android I/ProvisioningActivity: Connecting to C7:56:60:F0:56:58
2019-02-16 15:28:00.913 7105-7105/cc.biketracker.android D/BikeTrackerManager: onDeviceConnecting()
2019-02-16 15:28:00.914 7105-7105/cc.biketracker.android D/BluetoothGatt: connect() - device: C7:56:60:F0:56:58, auto: false
2019-02-16 15:28:00.915 7105-7105/cc.biketracker.android D/BluetoothGatt: registerApp()
2019-02-16 15:28:00.916 7105-7105/cc.biketracker.android D/BluetoothGatt: registerApp() - UUID=9c32a9c9-141d-400e-92b5-a48afda38b6e
2019-02-16 15:28:00.918 1407-1871/com.android.bluetooth I/bt_stack: [INFO:gatt_api.cc(948)] GATT_Register e3669297-761c-b2ed-1f02-2621fc89da38
2019-02-16 15:28:00.918 1407-1871/com.android.bluetooth I/bt_stack: [INFO:gatt_api.cc(968)] allocated gatt_if=8
2019-02-16 15:28:00.919 7105-7383/cc.biketracker.android D/BluetoothGatt: onClientRegistered() - status=0 clientIf=8
2019-02-16 15:28:00.920 1407-1871/com.android.bluetooth I/bt_stack: [INFO:gatt_api.cc(1109)] GATT_Connectgatt_if=8 c7:56:60:f0:56:58
2019-02-16 15:28:03.197 1407-1407/com.android.bluetooth D/BtGatt.ScanManager: awakened up at time 272598
2019-02-16 15:28:03.387 7105-7105/cc.biketracker.android I/chatty: uid=10146(cc.biketracker.android) identical 2 lines
2019-02-16 15:28:05.159 1407-1407/com.android.bluetooth D/BtGatt.ScanManager: awakened up at time 274560
2019-02-16 15:28:08.334 895-2499/system_process D/WificondControl: Scan result ready event
2019-02-16 15:28:08.347 1407-1407/com.android.bluetooth D/BtGatt.ScanManager: awakened up at time 277748
2019-02-16 15:28:13.425 1407-1407/com.android.bluetooth D/BtGatt.ScanManager: awakened up at time 282826
2019-02-16 15:28:18.489 1407-1407/com.android.bluetooth D/BtGatt.ScanManager: awakened up at time 287890
2019-02-16 15:28:19.519 654-654/? I//vendor/bin/hw/[email protected]: SRAM data: 2838000
2019-02-16 15:28:23.556 1407-1407/com.android.bluetooth D/BtGatt.ScanManager: awakened up at time 292957
2019-02-16 15:28:27.047 2744-2865/com.android.vending I/Finsky: [27] com.google.android.finsky.bs.m.run(6): Stats for Executor: BlockingExecutor com.google.android.finsky.bs.aw@a2bcdef[Running, pool size = 0, active threads = 0, queued tasks = 0, completed tasks = 19]
2019-02-16 15:28:27.084 2744-2865/com.android.vending I/Finsky: [27] com.google.android.finsky.bs.m.run(6): Stats for Executor: LightweightExecutor com.google.android.finsky.bs.aw@33fb0fc[Running, pool size = 3, active threads = 0, queued tasks = 0, completed tasks = 58]
2019-02-16 15:28:28.198 2744-2865/com.android.vending I/Finsky: [27] com.google.android.finsky.bs.m.run(6): Stats for Executor: bgExecutor com.google.android.finsky.bs.aw@8f35385[Running, pool size = 4, active threads = 0, queued tasks = 0, completed tasks = 47]
2019-02-16 15:28:28.637 1407-1407/com.android.bluetooth D/BtGatt.ScanManager: awakened up at time 298038
2019-02-16 15:28:30.923 1407-1871/com.android.bluetooth W/bt_stack: [WARNING:bta_gattc_act.cc(1040)] bta_gattc_conn_cback: cif=3 connected=0 conn_id=0x0003 reason=0x0100
2019-02-16 15:28:30.923 1407-1871/com.android.bluetooth W/bt_stack: [WARNING:bta_gattc_act.cc(1040)] bta_gattc_conn_cback: cif=4 connected=0 conn_id=0x0004 reason=0x0100
2019-02-16 15:28:30.923 1407-1871/com.android.bluetooth W/bt_stack: [WARNING:bta_gattc_act.cc(1040)] bta_gattc_conn_cback: cif=6 connected=0 conn_id=0x0006 reason=0x0100
2019-02-16 15:28:30.924 1407-1871/com.android.bluetooth W/bt_stack: [WARNING:bta_gattc_act.cc(1040)] bta_gattc_conn_cback: cif=7 connected=0 conn_id=0x0007 reason=0x0100
2019-02-16 15:28:30.924 1407-1871/com.android.bluetooth W/bt_stack: [WARNING:bta_gattc_act.cc(1040)] bta_gattc_conn_cback: cif=8 connected=0 conn_id=0x0008 reason=0x0100
2019-02-16 15:28:30.924 1407-1871/com.android.bluetooth W/bt_stack: [WARNING:bta_gattc_act.cc(339)] bta_gattc_open_fail: Cannot establish Connection. conn_id=0. Return GATT_ERROR(133)
2019-02-16 15:28:30.931 2012-3328/com.google.android.gms.persistent D/BluetoothGattServer: onServerConnectionState() - status=0 serverIf=5 device=C7:56:60:F0:56:58
2019-02-16 15:28:30.936 7105-7383/cc.biketracker.android D/BluetoothGatt: onClientConnectionState() - status=133 clientIf=8 device=C7:56:60:F0:56:58
2019-02-16 15:28:30.958 7105-7105/cc.biketracker.android D/BluetoothGatt: close()
2019-02-16 15:28:30.959 7105-7105/cc.biketracker.android D/BluetoothGatt: unregisterApp() - mClientIf=8
2019-02-16 15:28:30.962 7105-7105/cc.biketracker.android D/BikeTrackerManager: onDeviceDisconnected()
2019-02-16 15:28:30.962 7105-7105/cc.biketracker.android D/ProvisioningActivity: Disconnected. Presenting alert dialog.
2019-02-16 15:28:31.070 7105-7105/cc.biketracker.android D/BikeTrackerManager: onDeviceDisconnected()
2019-02-16 15:28:31.109 7105-7105/cc.biketracker.android W/AudioTrack: Use of stream types is deprecated for operations other than volume control
2019-02-16 15:28:31.109 7105-7105/cc.biketracker.android W/AudioTrack: See the documentation of AudioTrack() for what to use instead with android.media.AudioAttributes to qualify your playback use case
2019-02-16 15:28:31.111 1407-1893/com.android.bluetooth E/bt_btif: register_notification_rsp: Avrcp device is not connected, handle: 0x0
2019-02-16 15:28:31.111 1407-1893/com.android.bluetooth I/chatty: uid=1002(bluetooth) BluetoothAvrcpH identical 4 lines
2019-02-16 15:28:31.111 1407-1893/com.android.bluetooth E/bt_btif: register_notification_rsp: Avrcp device is not connected, handle: 0x0
2019-02-16 15:28:31.112 640-640/? W/AshmemAllocator: ashmem_create_region(7680) returning hidl_memory(0x7274e2c100, 7680)
2019-02-16 15:28:31.113 640-640/? W/AshmemAllocator: ashmem_create_region(7680) returning hidl_memory(0x7274e2c100, 7680)
2019-02-16 15:28:31.121 643-1384/? E/volume_listener: check_and_set_gain_dep_cal: Failed to set gain dep cal level
2019-02-16 15:28:31.364 643-1005/? E/volume_listener: check_and_set_gain_dep_cal: Failed to set gain dep cal level
2019-02-16 15:28:31.365 643-1384/? E/volume_listener: check_and_set_gain_dep_cal: Failed to set gain dep cal level
2019-02-16 15:28:31.381 643-7728/? E/audio_hw_primary: Unable to get Power service
2019-02-16 15:28:31.382 643-7728/? D/audio_hw_primary: select_devices: changing use case low-latency-playback output device from(0: none, acdb -1) to (2: speaker, acdb 15)
2019-02-16 15:28:31.383 2007-2017/? E/ANDR-PERF-OPTSHANDLER: Warning: Resource [2, 0] not supported for core 1. Instead use resource for core 0
2019-02-16 15:28:31.383 2007-2017/? E/ANDR-PERF-RESOURCEQS: Failed to apply optimization [2, 2, 0]
2019-02-16 15:28:31.383 643-7728/? I/ACDB-LOADER: ACDB AFE returned = -19
2019-02-16 15:28:31.383 643-7728/? D/hardware_info: hw_info_append_hw_type : device_name = speaker
2019-02-16 15:28:31.383 643-7728/? D/audio_hw_primary: enable_snd_device: snd_device(2: speaker)
2019-02-16 15:28:31.383 643-7728/? D/audio_route: Apply path: speaker
2019-02-16 15:28:31.383 643-7728/? D/audio_hw_primary: enable_audio_route: usecase(1) apply and update mixer path: low-latency-playback speaker
2019-02-16 15:28:31.383 643-7728/? D/audio_route: Apply path: low-latency-playback speaker
2019-02-16 15:28:31.419 643-7728/? D/audio_hw_primary: out_write: retry previous failed cal level set
2019-02-16 15:28:31.427 7105-7105/cc.biketracker.android W/AudioTrack: Use of stream types is deprecated for operations other than volume control
2019-02-16 15:28:31.427 7105-7105/cc.biketracker.android W/AudioTrack: See the documentation of AudioTrack() for what to use instead with android.media.AudioAttributes to qualify your playback use case
2019-02-16 15:28:31.430 640-640/? W/AshmemAllocator: ashmem_create_region(7680) returning hidl_memory(0x7274e2c100, 7680)
2019-02-16 15:28:31.433 640-640/? W/AshmemAllocator: ashmem_create_region(7680) returning hidl_memory(0x7274e2c100, 7680)
2019-02-16 15:28:31.632 7105-7105/cc.biketracker.android D/BleBackgroundScanner: Bonded peripherals:
2019-02-16 15:28:31.643 7105-7105/cc.biketracker.android D/BleBackgroundScanner: No Bike Tracker devices bonded to this phone. Not scanning.
2019-02-16 15:28:31.644 7105-7105/cc.biketracker.android D/BikeTrackerManager: onError()
2019-02-16 15:28:31.644 7105-7105/cc.biketracker.android E/ProvisioningActivity: BLE error: 133: Error on connection state change

fail_cant_connect_from_bike_tracker_app.pcapng.zip

pass_can_connect_from_nrf_connect_app.pcapng.zip

from android-ble-library.

eliotstock avatar eliotstock commented on August 16, 2024

I see. My device does stop advertising a while after any motion stops. You're suggesting the only reason nRF Connect was able to connect was that the device happened to still be advertising when I tested with nRF Connect, whereas it happened to have already stopped when I tested with my app?

That would make sense. My scanning activity is based on nRF Blinky and it doesn't remove a device from the UI once it stops advertising (logged a bug there for that). So it's easy to tap a device on the UI that's no longer advertising, and therefore no longer connectable. I'll test again and pay more attention to the advertising timeout.

from android-ble-library.

eliotstock avatar eliotstock commented on August 16, 2024

Nope. The device is still advertising. I can see the packets in Wireshark. I can also see from my firmware logging when it stops advertising.

The address I'm connecting to is straight from the scan result. (See "Connecting to C7:56:60:F0:56:58" in logcat above). And although my device uses a RANDOM_STATIC address I definitely scanned right beforehand. The phone is almost fresh from a factory reset, so it's not connected to any other devices. I can repro this 5 out of 5 times so far.

What could the nRF Connect app be doing differently? Is it now using this library?

from android-ble-library.

philips77 avatar philips77 commented on August 16, 2024

nRF Connect is not using BLE Library. Its implementation was created long time before the lib was started. It has more features in the connection handler (for example handling and recording macros), but it doesn't do anything else than the nRF Blinky. Are you able to check whether you will connect if you change the address type to public? It looks for me as if the phone was waiting for the packet to come, and as your device is constantly advertising, seems like it's waiting for something else...

Did you try on other phones, perhaps from other manufacturers?

from android-ble-library.

eliotstock avatar eliotstock commented on August 16, 2024

I'm not sure how to change the device firmware to use a valid public address and from a quick search in the devzone, it doesn't look trivial. If you can give me some code to do it, I can try.

I was able to repro this on another manufacturer's device (a Huawei Mate 10 running Android 9.0). The logcat is the same:

2019-02-18 20:54:00.567 11624-11624/cc.biketracker.android I/ProvisioningActivity: Device C7:56:60:F0:56:58 clicked.
2019-02-18 20:54:00.575 11624-11624/cc.biketracker.android D/HwAppInnerBoostImpl: asyncReportData cc.biketracker.android,2,1,1,0 interval=91
2019-02-18 20:54:00.603 11624-11624/cc.biketracker.android I/ProvisioningActivity: Connecting to C7:56:60:F0:56:58
2019-02-18 20:54:00.621 11624-11624/cc.biketracker.android D/BikeTrackerManager: onDeviceConnecting()
2019-02-18 20:54:00.623 11624-11624/cc.biketracker.android D/BluetoothGatt: connect() - device: C7:56:60:F0:56:58, auto: false
2019-02-18 20:54:00.623 11624-11624/cc.biketracker.android D/BluetoothGatt: registerApp()
2019-02-18 20:54:00.624 11624-11624/cc.biketracker.android D/BluetoothGatt: registerApp() - UUID=cf1d36eb-aed3-4d6f-8cf4-e8f1bc4f620e
2019-02-18 20:54:00.714 11624-11647/cc.biketracker.android D/BluetoothGatt: onClientRegistered() - status=0 clientIf=9
2019-02-18 20:54:00.772 11624-11624/cc.biketracker.android D/HwAppInnerBoostImpl: asyncReportData cc.biketracker.android,2,2,1,12 interval=289
2019-02-18 20:54:00.773 11624-11624/cc.biketracker.android I/ViewRootImpl: jank_removeInvalidNode all the node in jank list is out of time
2019-02-18 20:54:06.839 11624-11624/cc.biketracker.android I/ViewRootImpl: jank_removeInvalidNode all the node in jank list is out of time
2019-02-18 20:54:11.864 11624-11624/cc.biketracker.android I/ViewRootImpl: jank_removeInvalidNode all the node in jank list is out of time
2019-02-18 20:54:16.886 11624-11624/cc.biketracker.android I/ViewRootImpl: jank_removeInvalidNode all the node in jank list is out of time
2019-02-18 20:54:21.875 11624-11624/cc.biketracker.android I/ViewRootImpl: jank_removeInvalidNode all the node in jank list is out of time
2019-02-18 20:54:26.918 11624-11624/cc.biketracker.android I/ViewRootImpl: jank_removeInvalidNode all the node in jank list is out of time
2019-02-18 20:54:30.737 11624-11647/cc.biketracker.android D/BluetoothGatt: onClientConnectionState() - status=133 clientIf=9 device=C7:56:60:F0:56:58
2019-02-18 20:54:30.744 11624-11624/cc.biketracker.android D/BluetoothGatt: close()
2019-02-18 20:54:30.744 11624-11624/cc.biketracker.android D/BluetoothGatt: unregisterApp() - mClientIf=9
2019-02-18 20:54:30.746 11624-11624/cc.biketracker.android D/BikeTrackerManager: onDeviceDisconnected()
2019-02-18 20:54:30.746 11624-11624/cc.biketracker.android D/ProvisioningActivity: Disconnected. Presenting alert dialog.

If I use nRF Connect to make the very first connection to the device and bond with it, I can then make subsequent connections from my own app. It's only the first connection that'd the problem.

from android-ble-library.

eliotstock avatar eliotstock commented on August 16, 2024

Found it!

You mentioned that in order to connect to a device with a non public address the app needs to have been scanning for it previously. In fact, I found that unless I stop that scan before I attempt to connect, this issue happens. If I stop the scan first, I can connect, no problem.

Is this still a bug? Should I be able to connect while scanning?

from android-ble-library.

philips77 avatar philips77 commented on August 16, 2024

In theory you should be able to connect during scanning. After all, some other app may be scanning even if you don't. It looks like a bug, but I think it's more related to threads. You (?) also had an issue, when connecting wasn't working with Firebase connection, or something like that. That may be similar thing.
In all our apps we stop scanning before connecting. A bit accidentally.

from android-ble-library.

eliotstock avatar eliotstock commented on August 16, 2024

Right. We definitely need to understand the threading a bit better. (The Firebase thing is a red herring: I was calling enqueue() from a callback following a network operation, but I can now repro this when none of that network/Firebase stuff is in the picture.)

If you're not seeing this issue anywhere else, it may be that things have changed in the Android BLE stack in Android 9.0. So far, not many devices are running 9.0 yet. Both the ones I tested on (Pixel and Huawei) are though.

from android-ble-library.

philips77 avatar philips77 commented on August 16, 2024

I'm testing mainly on Pixel 2 with Pie.

from android-ble-library.

eliotstock avatar eliotstock commented on August 16, 2024

My comment from 18 Feb was incorrect, sorry: I was just able to repro this even when I had stopped the scan before connecting. I still have no idea what's causing this.

from android-ble-library.

akshayoyo16 avatar akshayoyo16 commented on August 16, 2024

Have you found the solution ?
I am also facing the same issue. And interestingly my code is working on android version less than 9, i have tested on oneplus 3, 3t, Redmi note. But the same code is not working on android 9(pie). I am always getting 133 as the status in the callback.
The bluetooth version of the phones on which it is working is 4.2 or less. Can it be that it is a bluetooth version issue or is it an android pie issue ?
If you have figured out what the issue is, please share that also.

from android-ble-library.

eliotstock avatar eliotstock commented on August 16, 2024

Nope, sorry, I haven't figured it out. It happens intermittently for me on Android 9 on a Pixel 1. It would be useful to spot the difference between the BLE stack calls from nRF Connect and our own apps.

from android-ble-library.

rawatsaurabh avatar rawatsaurabh commented on August 16, 2024

you can try running scan on one thread and gatt on another. I have the same issue on Honor 9N smartphone.On analyzing the HCI logs I noticed when the Gatt 133 occurs , there is No HCI le create connection being sent from Stack to HCI .
So I doubt its most probably some thing on the Android Bluetooth Stack.In this case I get the onConnectionStateChange call back with 133 status after mysterious 30 Seconds. I have added a retry in my app which generally recovers from this after 2-3 re-trials.And yes I am scanning continuously.
Let me know your thoughts on this.

from android-ble-library.

vikramgokhale11health avatar vikramgokhale11health commented on August 16, 2024

I am calling the connection code on the main thread in a service in my app but I am getting 133 timeout after 30 seconds on all versions of android except android 9 (Pie). Can you advice a good resource to verify if I am doing everything okay?

from android-ble-library.

rawatsaurabh avatar rawatsaurabh commented on August 16, 2024

@vikramgokhale11health are you scanning continuously in the background? If not can you please try scanning on other thread (Dont stop the scan during the whole process)

from android-ble-library.

vikramgokhale11health avatar vikramgokhale11health commented on August 16, 2024

@rawatsaurabh I am scanning for a particular period and then I stop the scan before I start connections. Can you explain what you meant by scanning on other thread? Is it suppose to be a separate handler thread? In my experience scanning & connecting at the same time doesn't work on all android versions. Also many sources specified that BluetoothDevice.connectGatt(context, false, mGattCallback) should be called on the main thread. Let me know your thoughts on this.

from android-ble-library.

eliotstock avatar eliotstock commented on August 16, 2024

This issue continues to plague me and is now 100% reproducible.

I tried putting the scan into a new thread but leaving the connection on the main thread. So for my scan, rather than simply:

scanner.startScan(noFilters, settings, scanCallback);

I tried:

new Handler(Looper.getMainLooper()).postDelayed(() -> scanner.startScan(noFilters, settings, scanCallback), 10);

That made no difference. I also tried removing the retries specified in the call to connect():

bleDeviceManager.connect(selectedBluetoothDevice.getDevice())
                    .retry(3, 200)
                    .useAutoConnect(false)
                    .enqueue();

That made no difference either.

I can connect and bond just fine using the nRF Connect app, which doesn't use this library, every time. From my Wireshark captures above, we know that no CONNECT_REQ ever comes from the phone.

Aleksander, would it be possible for you to have a look at the nRF Connect code and see if you can spot any difference in what they're doing and what this library does?

I'll also attach HCI snoop logs for both cases (my app, and nRF Connect) in case that helps. These are viewable in Wireshark.

btsnoop_hci_biketracker_app.log

btsnoop_hci_nrf_connect_app.log

from android-ble-library.

philips77 avatar philips77 commented on August 16, 2024

Hi @eliotstock,
The nRF Connect does everything on the main thread, in a running background service. Only automated tests are performed on a new thread in the IntentService.
Stupid question: did you try restarting Bluetooth on the phone?
I see there are issues with the BLE Library 2.x. There's your issue, where the connection is not initiated, there are #127 and NordicSemiconductor/Android-nRF-Mesh-Library#250 where the data are lost. Also, we found that switching the thread to the main thread before calling each method slows down the connection as a side effect. For example, if you want to sent a lot of Write Without Response packets, they are sent 1-2 per connection interval instead of 6-7.
I have to come back to this library and make necessary improvements.

from android-ble-library.

eliotstock avatar eliotstock commented on August 16, 2024

Thanks, but I'm not sure we can say with much certainty that this is a bug in this library - it could be a bug in the Android BLE stack, but one which would be really nice to be able to work around in this library. It could even be something that only manifests with my peripheral firmware - something in the way I'm advertising for example.

Your mention of the service in nRF Connect is interesting! I used to have a background service in my app that did all the BLE operations and everything worked fine then. It became monolithic and horrible and I refactored it away in the process of moving to using this library. I could bring it back for at least the connection call and see if it makes any difference.

(Yep, tried restarting Bluetooth. Even rebooting the phone.)

from android-ble-library.

mtomczynski avatar mtomczynski commented on August 16, 2024

@eliotstock any progress on going back to background service? I've got exactly same problem, I can't connect to device (133 error timeout), but nRF connect is somehow working just fine

I'll add my 3 cents to the issue, 133 error timeout happens 100% (not from nRF connect) under this conditions:

  • Only happens on Android 10
  • Bonded to TWO devices from the same producer
  • Try to connect to first paired one

Steps to reproduce:

  • Bond to first device - connecting and disconnecting without any problems
  • Bond to second device - connecting and disconnecting without any problems
  • Try to connect to first device - results in 133 error. From this point on can't connect to both devices which results in the same error

Problems disappears after unbonding from one device, so leaving only one bonded device and turning off and on bt. Somehow list of bonded devices seems to be a trigger

from android-ble-library.

eliotstock avatar eliotstock commented on August 16, 2024

OK, I have a working theory on this. It's to do with the scanning code, not the connection code. Also note that I don't use the compat library for scanning (and maybe I should have been). Until now I'd been setting a report delay on my scan settings:

final ScanSettings settings = new ScanSettings.Builder()
                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                .setReportDelay(500)
                .build();

Today I tried removing it:

final ScanSettings settings = new ScanSettings.Builder()
                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                .build();

This meant that results showed up much more quickly on my list of devices. And not by 500ms either - for some reason this delay was causing them to take up to 6s to appear on the UI.

But it also seems to have fixed my issue with connecting. I've been back and forth between using the .setReportDelay() and not using it and over three or four tests, I'm able to connect every time I don't use it and I can repro this timeout and 133 error issue every time I do use it.

Maciek, could this have anything to do with your issue? Do you ever use the reporting delay?

from android-ble-library.

philips77 avatar philips77 commented on August 16, 2024

In my experience, report delay works write 6 reliably when the delay it long enough, around 5000+. With shorter values the report is still delayed longer, like you say. Of course this is not documented anywhere.
I'd use report delay only when scanning in background with low battery mode and is set the delay to many seconds. The main purpose of using this method is to save battery, as it offloads scanning to the controller.

from android-ble-library.

eliotstock avatar eliotstock commented on August 16, 2024

OK let's close this for now. Maciek, if you're still having issues even without the report delay, feel free to reopen it.

from android-ble-library.

CodemenschenAndroid avatar CodemenschenAndroid commented on August 16, 2024

Hi I am working on BLE connection I try to connect ble device using below code

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
FileHelper.saveToFile("Build.VERSION_CODES.O ....");

                mBluetoothGatt = device.connectGatt(this, true, mGattCallback,
                        BluetoothDevice.TRANSPORT_LE, PHY_LE_1M_MASK);
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

                FileHelper.saveToFile("Build.VERSION_CODES.M ....");

                mBluetoothGatt = device.connectGatt(this, true, mGattCallback,
                        BluetoothDevice.TRANSPORT_LE);
            } else {

                FileHelper.saveToFile("below api 23 connection ...");

                mBluetoothGatt = device.connectGatt(this, true, mGattCallback);
            }

getting an issue on android version 10
BluetoothGattCallback onConnectionStateChange i am get status code 257
check below screenshot of app log
Annotation 2020-01-13 093717

I checked developer android about status code 257 that is GATT_FAILURE

I am not able to find a solution, please help me

Thanks

from android-ble-library.

huntc avatar huntc commented on August 16, 2024

This problem appears to remain. I'm using Android 9 and 2.2.4 of the Nordic BLE library.

If my foreground service attempts to re-connect to a previously bonded device I see:

V/au.com.titanclass.xdpservice.GattService$BleEndDeviceClient: Connecting...
D/au.com.titanclass.xdpservice.GattService$BleEndDeviceClient: gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, LE 1M)
D/BluetoothGatt: connect() - device: 84:B8:B8:DD:7E:01, auto: false
    registerApp()
D/BluetoothGatt: registerApp() - UUID=ce1af493-9679-4acd-a3fc-596c23f61cb3
D/BluetoothGatt: onClientRegistered() - status=0 clientIf=5

...and then later:

D/au.com.titanclass.xdpservice.GattService$BleEndDeviceClient: [Callback] Connection state changed with status: 133 and new state: 0 (DISCONNECTED)
W/au.com.titanclass.xdpservice.GattService$BleEndDeviceClient: Error: (0x85): GATT ERROR
W/au.com.titanclass.xdpservice.GattService$BleEndDeviceClient: Connection attempt timed out
D/au.com.titanclass.xdpservice.GattService$BleEndDeviceClient: gatt.close()

Here's how I connect:

endDeviceClient.connect(bluetoothDevice).useAutoConnect(true).enqueue()

I've run a Bluetooth sniffer and don't see any connect requests. nRF Connect on IOs works fine. I'm not scanning and the other device is advertising.

Another comment: given that the device is already bonded on Android, it'll use the private address it knows of from the bonding. My guess is that nRF Connect will use the address from the scan, which is randomised... possible clue?

Any more ideas? Any further thinking on thread usage? Thanks.

from android-ble-library.

huntc avatar huntc commented on August 16, 2024

Thanks for re-opening. Confirming that this also appears to be a problem on Android 8.1.

Totally out of ideas...

from android-ble-library.

huntc avatar huntc commented on August 16, 2024

By using autoConnect=true it finally manage to connect after few tries after which the connection seemed stabled. On next disconnection situation repeated.

Wondering if a connect request actually gets sent out still and whether the required services check the of the Lib will succeed.

from android-ble-library.

huntc avatar huntc commented on August 16, 2024

I've begun developing a sample server using the BLE library, to be followed by a sample client using the BLE library. These can then be used to further investigate the issues here perhaps. It'd be wonderful if we could all collaborate on this, as right now, Android is winning. :-)

Progress so far: #234

from android-ble-library.

huntc avatar huntc commented on August 16, 2024

I've now introduced both a client and a complimentary server using this library. Setting the server up on one device, the client on another, and using settings to pair the two, then reveals the 133 error on the client starting up. I'll shortly try with #232 in place. Any help from the people subscribed to this issue would be greatly appreciated.

Ref: #238

from android-ble-library.

huntc avatar huntc commented on August 16, 2024

I've just tried my client with #232 and, while a welcome change, it doesn't alter the fact that we are unable to connect with a previously bonded device. Here's what I observed (and expected):

D/BluetoothGatt: onClientConnectionState() - status=133 clientIf=5 device=84:B8:B8:DD:7E:01
D/gatt-service: [Callback] Connection state changed with status: 133 and new state: 0 (DISCONNECTED)
W/gatt-service: Error: (0x85): GATT ERROR
D/gatt-service: autoConnect = false called failed; retrying with autoConnect = true
V/gatt-service: Connecting...
D/gatt-service: gatt.connect()

... but then no initialisation code called of the BleGattHandler. I suspect that there's still no connect going out over the air even though Android is claiming this to be so.

I'm really out of ideas... perhaps it is time to raise a bug with Google.

from android-ble-library.

philips77 avatar philips77 commented on August 16, 2024

What device are you trying to connect to? Are you testing client and server on 2 phones? It works with security removed, doesn't it?

from android-ble-library.

huntc avatar huntc commented on August 16, 2024

What device are you trying to connect to?

ble-gatt-client - Android 9 tablet
ble-gatt-server - Android 8.1 tablet

Are you testing client and server on 2 phones?

Two tablets, but yes.

It works with security removed, doesn't it?

I've not tried that with these two specific examples, but past efforts have shown that I'm able to connect unsecured Android tablets.

from android-ble-library.

philips77 avatar philips77 commented on August 16, 2024

Did you try with nRF Connect app running on these devices? In gatt server config you may set permissions for the characteristics and descriptors.

from android-ble-library.

huntc avatar huntc commented on August 16, 2024

Did you try with nRF Connect app running on these devices? In gatt server config you may set permissions for the characteristics and descriptors.

Do you mean setting up nRF Connect as a server? I've not tried that but will do so and report back. However, the fact that I'm not seeing any connection request going out from the Android central device though makes me think that the problem will remain.

from android-ble-library.

huntc avatar huntc commented on August 16, 2024

I'm having difficulty setting up nRF Connect as per the ble-gatt-server. I've created a gist of my ncs file. I'm probably doing something wrong, but I don't even see this device advertised. I'm using an nRF52DK also.

https://gist.github.com/huntc/9436582b85e34e58bca9ed7975b3c70d

from android-ble-library.

huntc avatar huntc commented on August 16, 2024

Actually, from nRF Connect on my iPhone I can connect, but then I get an error (Failed to update physs - NRF_ERROR_INVALID_PARAM):

image

from android-ble-library.

philips77 avatar philips77 commented on August 16, 2024

I was talking about nRF Connect on Android.

from android-ble-library.

huntc avatar huntc commented on August 16, 2024

I was talking about nRF Connect on Android.

I actually don't have Google Play services set up on my devices - anon usage at the moment. Should it make a difference for our experiments though? My understanding of nRF Connect on OS X is that it'll flash my nRF5 DK with a GATT server for the purposes of being able to connect with it. I should then be able to use nRF connect for iOS to connect to that service, right?

from android-ble-library.

philips77 avatar philips77 commented on August 16, 2024

You may get nRF Connect for Android from our GitHub: https://github.com/NordicSemiconductor/Android-nRF-Connect/releases. APKs are included in each release.

from android-ble-library.

philips77 avatar philips77 commented on August 16, 2024

My understanding of nRF Connect on OS X is that it'll flash my nRF5 DK with a GATT server for the purposes of being able to connect with it. I should then be able to use nRF connect for iOS to connect to that service, right?

Yes, but your also want to try it on Android. Does it also fail in other apps, etc.

from android-ble-library.

huntc avatar huntc commented on August 16, 2024

Thanks. I shall try it nRF connect on Android later, although I’m thinking now of having to abandon bonded connections and roll my own encryption.

from android-ble-library.

huntc avatar huntc commented on August 16, 2024

I have now raised an issue with Google having used nRF Connect on Android. The issue contains a video illustrating my method to reproduce the GATT 133 status.

Interestingly, I am able to see bonded devices connect after a while. My current theory is that when the randomised address is changed, the bonded device is able to connect. I shall test this theory further.

Meanwhile, perhaps it is best to close the issue here as I don't believe it to be a BLE library one. Perhaps further commentary can be better placed on the Google issue. Thoughts?

from android-ble-library.

huntc avatar huntc commented on August 16, 2024

An update here, for continuity... it appears that if I disable and then re-enable Bluetooth on the central device then I'm able to perform a bonded connection. There must be some caching of stale info happening somewhere...

However, if I try the BT off-on trick with the ble-gatt-client/ble-gatt-server, it isn't working.

from android-ble-library.

huntc avatar huntc commented on August 16, 2024

Looks as though Android 10 solves the error 133 issue, at least on a Samsung Tab A device.

from android-ble-library.

pablogeek avatar pablogeek commented on August 16, 2024

This is still happening to me even in android 11. Would be nice to see if someone actually can give us some tips :) Thanks

from android-ble-library.

BlackTentDev avatar BlackTentDev commented on August 16, 2024

Hello All! I had a quite long session testing this issue and I think I have the correct steps to reproduce and solution as well.
Issue reproduction:

  • Restart the device
  • Open your app and scan for devices using hardware batching and try to connect then. In my case, I could not establish the connection no matter what
  • If u connect to your remote device with nrf connect e.g. then somehow it clear the issue out and u can connect to your device with mac address e.g.

Guilty: .setUseHardwareBatchingIfSupported(true)

Solution
Simply do not use hardware batching when starting the scan (set it to false)
Example ScanSettings:
ScanSettings = ScanSettings.Builder().setLegacy(false).setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) .setReportDelay(1000).setUseHardwareBatchingIfSupported(false).build()

I have tried lots of ideas mentioned here since 2018... including:

  • Using Android Service instead of keeping BleManager in Activity scope
  • Scanning before connecting
  • Retrying when 133 error appears
  • Switching threads

Hope u guys will find it helpful.
@philips77 Can u confirm this might be the workaround? Maybe u know what is wrong with setUseHardwareBatchingIfSupported(true) enabled?

from android-ble-library.

rawatsaurabh avatar rawatsaurabh commented on August 16, 2024

from android-ble-library.

BlackTentDev avatar BlackTentDev commented on August 16, 2024

@rawatsaurabh by default u use it. See the docs.

from android-ble-library.

philips77 avatar philips77 commented on August 16, 2024

From our treating the native offloaded batching works better with longer delays, like 5+ seconds. When you use setUseHardwareBatchingIfSupported(false) it will scan with delay 0 and will just batch results in the lib. There is no battery benefit, but at least works and for short scanning intervals is a good option.

from android-ble-library.

philips77 avatar philips77 commented on August 16, 2024

I'm closing the issue due to inactivity.

from android-ble-library.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.