You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Describe the bug
When peripheral device has a single characteristic for both TX and RX operations, next race condition happens: when writing to the characteristic, onNotificationReceived() event can happen during 'write' operation, replacing content of internal Android buffer, which leads to sending the received buffer (instead of one we want to send). Observing everything on the same thread doesn't help.
The root cause can be that BluetoothGattCharacteristic class shares mValue between read and write operations, though I'm not confident about this. Such race condition also mentioned here.
One possible workaround would be to send data only on new data received. Such a workaround is implemented in class below (see setWriteOnRead()), and it's working for me. But it's of course just a hack. Another way to solve the problem could be to keep two different instances of BluetoothGattCharacteristic class, one for read and one for write. This way we can keep buffers separate, avoiding race condition. Not sure if it's possible to implement something like this, though.
Of course, it's 100% Android bug, not an RxAndroidBle library bug. Frankly, I've stumbled upon this bug first when using Android BLE framework directly, and kinda hoped that this library would help me to avoid that (and other issues).
Here is the class I'm using for connection and data exchange (basically it's modified sample/example4_characteristic):
Peripheral device should send data very fast (the one I use has a rate of 55 packets per second); always send e.g. packet "A"
Single characteristic should be used for TX and RX.
As a code reference -- class above can be used.
Write some uniqe packets (e.g. packet "B") to the characteristic, like 1 time per second
Watch received packets on peripheral device: sometimes it will receive packet "A", which is a bug
Expected behavior
For a test case above: peripheral device should never receive packet "A". In other words, described race condition should never happen on Android device, and packets we write should never be overwritten with received packets.
Smartphone (please complete the following information):
Device: OnePlus 5
OS: Android 9
Library version: 1.11.1
Logs from the application when bug occurs (this will greatly help in quick understanding the problem)
From log one can see that I'm writing [48, 0D, 0A] packet. But because onCharacteristicChanged() happens during write operation, instead of [48, 0D, 0A] I'm observing this packet on peripheral device: [40, 38, 41, 6C, 6E, 2F, 50, 63, 4A, 58, 66, 7A, 76, 43, 56, 7A, 38, 0D, 0A].
The text was updated successfully, but these errors were encountered:
where it shows Scan operation api 21 is finished and no scan result found/return.
Where on Android 9, it's working fine and above situation is limited or few, but recovers after giving break of 5 secs for next try. But on Android 10, it's stuck and doesn't recover after long time.
Describe the bug
When peripheral device has a single characteristic for both TX and RX operations, next race condition happens: when writing to the characteristic,
onNotificationReceived()
event can happen during 'write' operation, replacing content of internal Android buffer, which leads to sending the received buffer (instead of one we want to send). Observing everything on the same thread doesn't help.The root cause can be that BluetoothGattCharacteristic class shares
mValue
between read and write operations, though I'm not confident about this. Such race condition also mentioned here.One possible workaround would be to send data only on new data received. Such a workaround is implemented in class below (see
setWriteOnRead()
), and it's working for me. But it's of course just a hack. Another way to solve the problem could be to keep two different instances of BluetoothGattCharacteristic class, one for read and one for write. This way we can keep buffers separate, avoiding race condition. Not sure if it's possible to implement something like this, though.Of course, it's 100% Android bug, not an RxAndroidBle library bug. Frankly, I've stumbled upon this bug first when using Android BLE framework directly, and kinda hoped that this library would help me to avoid that (and other issues).
Here is the class I'm using for connection and data exchange (basically it's modified
sample/example4_characteristic
):To Reproduce
Steps to reproduce the behavior:
Expected behavior
For a test case above: peripheral device should never receive packet "A". In other words, described race condition should never happen on Android device, and packets we write should never be overwritten with received packets.
Smartphone (please complete the following information):
Logs from the application when bug occurs (this will greatly help in quick understanding the problem)
Additional context
From log one can see that I'm writing
[48, 0D, 0A]
packet. But becauseonCharacteristicChanged()
happens during write operation, instead of[48, 0D, 0A]
I'm observing this packet on peripheral device:[40, 38, 41, 6C, 6E, 2F, 50, 63, 4A, 58, 66, 7A, 76, 43, 56, 7A, 38, 0D, 0A]
.The text was updated successfully, but these errors were encountered: