Search code examples
androidbluetooth-lowenergyrxandroidble

In RxAndroidBLE, RxBleDevice.establishConnection() method is blocking infinitely when autoConnect=true


I am using RxAndroidBle library for communication with BLE device. The goal is to perform BLE scan, find device and establish connection to it. I am using autoConnect = true to keep connection running in background, however, I noticed that, sometimes, this method is getting blocked (I have 60 seconds timeout) and it times out. Also, when nRF Connect is running in background, it seems the connection succeed. Here is the log when issue occurs:

2020-07-06 13:22:50.579 ***************** D/BluetoothGatt: connect() - device: 06:05:04:50:D0:84, auto: true
2020-07-06 13:22:50.579 ***************** D/BluetoothGatt: registerApp()
2020-07-06 13:22:50.579 ***************** D/BluetoothGatt: registerApp() - UUID=f5c4a5c2-0655-4585-a430-afce97ba1541
2020-07-06 13:22:50.581 ? D/bt_btif: bta_gattc_register: state 2
2020-07-06 13:22:50.582 ? I/bt_stack: [INFO:gatt_api.cc(949)] GATT_Register417325bf-23e7-e29a-197a-cc3215966959
2020-07-06 13:22:50.582 ? I/bt_stack: [INFO:gatt_api.cc(969)] allocated gatt_if=10
2020-07-06 13:22:50.582 ? I/bt_btif: HAL bt_gatt_callbacks->client->register_client_cb
2020-07-06 13:22:50.582 ***************** D/BluetoothGatt: onClientRegistered() - status=0 clientIf=10
2020-07-06 13:22:50.584 ? D/bt_btif_config: btif_get_address_type: Device [06:05:04:50:d0:84] address type 0
2020-07-06 13:22:50.584 ? D/bt_btif_config: btif_get_device_type: Device [06:05:04:50:d0:84] type 2
2020-07-06 13:22:50.584 ? D/bt_btif: btif_gattc_open_impl Transport=2, device type=2, phy=1
2020-07-06 13:22:50.584 ? I/bt_btif: bta_sys_event: Event 0x112
2020-07-06 13:22:50.584 ? I/bt_btif: bta_dm_sm_execute event:0x12
2020-07-06 13:22:50.584 ? D/bt_btm: BTM_SecAddBleDevice: dev_type=0x2
2020-07-06 13:22:50.584 ? D/bt_btm: InqDb  device_type =0x2  addr_type=0x0
2020-07-06 13:22:50.584 ? I/bt_btif: bta_sys_event: Event 0x116
2020-07-06 13:22:50.584 ? I/bt_btif: bta_dm_sm_execute event:0x16
2020-07-06 13:22:50.584 ? I/bt_btm: BTM_BleStartAutoConn
2020-07-06 13:22:50.584 ? I/bt_btif: bta_sys_event: Event 0x1f00
2020-07-06 13:22:50.584 ? I/bt_stack: [INFO:gatt_api.cc(1122)] GATT_Connectgatt_if=10 06:05:04:50:d0:84
2020-07-06 13:22:50.584 ? I/bt_btm: BTM_BleUpdateBgConnDev() add=1
2020-07-06 13:22:50.584 ? I/bt_btm: btm_ble_start_auto_conn start=0
2020-07-06 13:22:50.584 ? D/bt_btm: conn_st = 0, not in auto conn state, cannot stop
2020-07-06 13:22:50.584 ? I/bt_btm: btm_ble_start_auto_conn start=1
2020-07-06 13:22:50.585 ? E/bt_osi_wakelock: wakelock_acquire wakelock acquired
2020-07-06 13:22:50.615 ? I/[email protected]_handler: ProcessIbsCmd: Received IBS_SLEEP_IND: 0xFE
2020-07-06 13:22:50.645 ? W/auditd: type=1400 "libwatcher_bina""file-nr""proc"
2020-07-06 13:22:50.880 ? I/[email protected]_handler: ProcessIbsCmd: Received IBS_WAKE_IND: 0xFD
2020-07-06 13:22:50.880 ? I/[email protected]_handler: ProcessIbsCmd: Writing IBS_WAKE_ACK
2020-07-06 13:22:50.881 ? E/bt_osi_wakelock: wakelock_release wakelock released
2020-07-06 13:22:50.921 ? I/[email protected]_handler: ProcessIbsCmd: Received IBS_SLEEP_IND: 0xFE
2020-07-06 13:22:51.585 ? I/[email protected]_handler: DeviceSleep: TX Awake, Sending SLEEP_IND
2020-07-06 13:22:51.585 ? D/[email protected]_handler: SerialClockVote: vote for UART CLK OFF
2020-07-06 13:22:51.736 ? D/[email protected]_lock: Release wakelock is released 

When I get successful connection, the log looks like this:

2020-07-06 13:13:44.670 ? I/bt_btif: bta_sys_event: Event 0x1f00
2020-07-06 13:13:44.671 ? I/bt_stack: [INFO:gatt_api.cc(1122)] GATT_Connectgatt_if=10 06:05:04:50:d0:84
2020-07-06 13:13:44.671 ? I/bt_btm: BTM_BleUpdateBgConnDev() add=1
2020-07-06 13:13:44.671 ? I/bt_btm: btm_ble_start_auto_conn start=0
2020-07-06 13:13:44.671 ? D/bt_btm: conn_st = 0, not in auto conn state, cannot stop
2020-07-06 13:13:44.671 ? I/bt_btm: btm_ble_start_auto_conn start=1
2020-07-06 13:13:44.822 ? I/[email protected]_handler: ProcessIbsCmd: Received IBS_WAKE_IND: 0xFD
2020-07-06 13:13:44.823 ? I/[email protected]_handler: ProcessIbsCmd: Writing IBS_WAKE_ACK
2020-07-06 13:13:44.873 ? I/[email protected]_handler: ProcessIbsCmd: Received IBS_SLEEP_IND: 0xFE
2020-07-06 13:13:45.566 ? I/[email protected]_handler: ProcessIbsCmd: Received IBS_WAKE_IND: 0xFD
2020-07-06 13:13:45.566 ? I/[email protected]_handler: ProcessIbsCmd: Writing IBS_WAKE_ACK
2020-07-06 13:13:45.607 ? I/[email protected]_handler: ProcessIbsCmd: Received IBS_SLEEP_IND: 0xFE
2020-07-06 13:13:45.834 ? I/[email protected]_handler: DeviceSleep: TX Awake, Sending SLEEP_IND
2020-07-06 13:13:45.834 ? D/[email protected]_handler: SerialClockVote: vote for UART CLK OFF
2020-07-06 13:13:45.985 ? D/[email protected]_lock: Release wakelock is released 
2020-07-06 13:13:46.103 ? V/ActivityManager: Broadcast sticky: Intent { act=android.intent.action.SIG_STR flg=0x10 (has extras) } ordered=false userid=-1 from pid=2635 uid=1001
2020-07-06 13:13:47.144 ? I/[email protected]_handler: ProcessIbsCmd: Received IBS_WAKE_IND: 0xFD
2020-07-06 13:13:47.144 ? D/[email protected]_handler: SerialClockVote: vote for UART CLK ON
2020-07-06 13:13:47.148 ? D/[email protected]_lock: Acquire wakelock is acquired 
2020-07-06 13:13:47.148 ? I/[email protected]_handler: ProcessIbsCmd: Writing IBS_WAKE_ACK
2020-07-06 13:13:47.152 ? I/bt_hci: BLE HCI(id=62) event = 0x0a)
2020-07-06 13:13:47.152 ? I/bt_btm: btm_identity_addr_to_random_pseudo
2020-07-06 13:13:47.152 ? I/bt_btm: btm_ble_connected
2020-07-06 13:13:47.152 ? D/bt_btm: btm_ble_connected sec_flags=0x1080
2020-07-06 13:13:47.153 ? I/bt_btm: btm_find_or_alloc_dev
2020-07-06 13:13:47.153 ? W/bt_btm: btm_acl_created hci_handle=5 link_role=0  transport=2
2020-07-06 13:13:47.153 ? D/bt_btm: btm_bda_to_acl found
2020-07-06 13:13:47.153 ? D/bt_btm: device_type=0x2
2020-07-06 13:13:47.153 ? D/bt_btm: btm_bda_to_acl found
2020-07-06 13:13:47.153 ? I/bt_btm: btm_ble_start_auto_conn start=1
2020-07-06 13:13:47.153 ? D/bt_btm: btm_bda_to_acl found

I tried to analyze the Android Bluetooth source code, trying to figure out where is the problem, but without much success.

So, is there a way to improve the connection parameters from the app side, to make connection more aggressive or something similar? Does nRF Connect do something different than what library does, so it makes app connecting faster to device? Or is there an issue on firmware side, maybe the app is waiting for some event from BLE device itself?


Solution

  • When using autoConnect = true Android uses relaxed initial scan parameters. Depending on how robust your mobile Bluetooth chipset is and what are the advertising parameters of your peripheral the connecting process may take even many minutes.

    So, is there a way to improve the connection parameters from the app side, to make connection more aggressive or something similar?

    Yes, use autoConnect = false. This makes initial (implicit) scanning more aggressive but limits its time to 30 seconds. This is how Android did implement it.

    Does nRF Connect do something different than what library does, so it makes app connecting faster to device?

    If you have nRF Connect opened in the background — be aware that it "steals" BLE connections. I.e.:

    1. Your peripheral is disconnected
    2. Open nRF Connect
    3. Put nRF Connect to background
    4. Open your app
    5. Connect your peripheral
    6. Close your app
    7. Observe that your peripheral is connected to the phone until nRF Connect is not killed or you do not manually disconnect your peripheral from it