NordicSemiconductor / Android-BLE-Library

A library that makes working with Bluetooth LE on Android a pleasure. Seriously.
BSD 3-Clause "New" or "Revised" License
1.99k stars 414 forks source link

Missing notifications #480

Closed archie94 closed 1 year ago

archie94 commented 1 year ago

Our peripheral can send around 280 notifications at a go one after the other.

While on nRF connect there is no issue in receiving all of these notifications our app (lib version 2.6.0) is failing to capture a few. Some notification packets in between are randomly being missed. Is there any special handling we need to do in these scenarios?

There is no drop in connection while receiving these notifications.

We have tried running BleManager on the default handler as well as a background handler but got similar results.

philips77 commented 1 year ago

Perhaps you're collecting the notifications using this method: https://github.com/NordicSemiconductor/Android-BLE-Library/blob/55ac0691cfae60e478c0304fb0c0722f2db6299c/ble-ktx/src/main/java/no/nordicsemi/android/ble/ktx/ValueChangedCallbackExt.kt#L14-L34

As you see, internally it is using callbackFlow, which is using buffer of size 1. That means that if a new notification is received before the previous one was handled, it may override the last value.

A channel with the default buffer size is used.

As the documentation suggests:

Use the buffer operator on the resulting flow to specify a user-defined value and to control what happens when data is produced faster than consumed, i.e. to control the back-pressure behavior.

You may find more about buffering here: https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines.flow/buffer.html

archie94 commented 1 year ago

We are using DataReceivedCallback

setNotificationCallback(dataCharacteristic)
            .with { device, data ->
                parseData(device.address, data)
            }

parseData mainly converts binary data to int and launches a coroutine to save to db.

philips77 commented 1 year ago

Do you receive some other notifications duplicated?

archie94 commented 1 year ago

Debugged this further. It looks like what you suggested, parseData(device.address, data) was compute heavy and we were using Flow underneath with buffer size 1, which was causing some packets un parsed.

I logged the arrival of packets while collecting the flow which further caused this blunder.

Thank you so much for your help. Closing this :)