This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Observing stuck thread in Android BLE Library while registering characteristics

Hello,

We are leveraging the Android BLE Library from Nordic available on GitHub (release v2.1.1). 

In a scenario where there are repeated requests to connect as a result of being on the edge of the link budget, we've observed that the thread responsible for executing SimpleRequest.await() can get blocked and prevent us from making subsequent attempts to register characteristics in a retry loop. The following is a thread dump when we are able to reproduce the scenario:

"Whoop Strap HandlerThread@17034" prio=5 tid=0x3c95 nid=NA waiting
java.lang.Thread.State: WAITING
blocks Whoop Strap HandlerThread@17034
at java.lang.Object.wait(Object.java:-1)
at java.lang.Object.wait(Object.java:442)
at java.lang.Object.wait(Object.java:568)
at android.os.ConditionVariable.block(ConditionVariable.java:97)
- locked <0x42e2> (a android.os.ConditionVariable)
at no.nordicsemi.android.ble.SimpleRequest.await(SimpleRequest.java:88)
at com.whoop.service.rearchitect.ble.impls.nordic.NordicBleHandlerImpl.registerCharacteristicNotificationsSynchronously(NordicBleHandlerImpl.kt:364)
at com.whoop.service.rearchitect.gatt.WhoopStrapGatt.registerCharsForNotification(WhoopStrapGatt.kt:232)
at com.whoop.service.rearchitect.gatt.WhoopStrapGatt.access$registerCharsForNotification(WhoopStrapGatt.kt:28)
at com.whoop.service.rearchitect.gatt.WhoopStrapGatt$onDeviceReady$1.run(WhoopStrapGatt.kt:560)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:237)
at android.os.HandlerThread.run(HandlerThread.java:67)

For reference, these are the versions on the embedded side:

HW Version: n52840_0DAA
Softdevice: s140_nrf52_6.1.1_softdevice
SDK: nRF5_SDK_15.3.0_59ac345

  • Hello,

    All non-timeoutable requests are waiting for the system callback. In general a new request could not be performed when a previous one still didn't get a callback. But of course we know how it is.

    To cancel current task and all queued, call

     

    cancelQueue()

    in the manager. This will cancel the current one with REASON_CANCELLED. The state of the device is undefined at that moment, so you may need to disconnect and reconnect, etc. I have never tried this. Of course, as you're using synchronous calls, call this method from another thread, as that one is hanging.

Related