I'm trying to write BLE Android app. I found that sometimes when I call BluetoothGatt.writeDescriptor() it returns false.
I have not found in documentation any note of limitation to this function. But ppl on stack overflow says that I need to wait for BluetoothGattCallback.onDescriptorWrite() before I try to write another descriptor.
Here is one reply saying that BLE is busy with writeDescriptor() and can not do other write.
Here is another thread saying that you can not call twice writeCharacteristic().
My questions are
writeDescriptor()
I understand I can not call second time writeDescriptor()
before I receive onDescriptorWrite()
. But do I have to wait for onDescriptorWrite()
when I want to call writeCharacteristic()
? readCharacteristic()
, readDescriptor()
, requestMtu()
...)? BluetoothGattServer.notifyCharacteristicChanged()
shall I wait forBluetoothGattServerCallback.onNotificationSent
before I can call BluetoothGatt.writeDescriptor()
or BluetoothGatt.writeCharacteristic()
? (BTW praise for google documentation onNotificationSent()
is by luck documented properly. Doc says:When multiple notifications are to be sent, an application must wait for this callback to be received before sending additional notifications.
onNotificationSent()
is arleady properly documented. They just need to copy this sentence to other functions. The documentation lacks information. However you can read the source code to find out the rules, which (currently) are the following:
For each BluetoothGatt
object, you can only have one outstanding request at a time, including requestMtu
, readCharacteristic
, writeCharacteristic
, readDescriptor
, writeDescriptor
and executeReliableWrite
. So if you issue a read request you need to wait for the read response before you issue a write request. While they implemented the code that returns false if there is an ongoing operation in BluetoothGatt.java, they forgot to do this for requestMtu
, so if you have multiple requests at a time where requestMtu
is one of them, you will get random errors sooner or later (in the latest versions at the time of this post).
So yes, every developer has to manually serialize the requests. Note that the Bluetooth stack actually has a queue of requests, but it is limited to only one request per client (i.e. BluetoothGatt object). So if two apps on the same phone talk to the same device simultaneously you will never get "busy" errors. The only exception is if you use Write Without Response for which the current data flow implementation is quite buggy (see https://issuetracker.google.com/issues/37121017 which Google seems to have ignored).
You can send notifications at the same time as you write a characteristic, since the server and client roles are separated.
Regarding updating the documentation, you can always try to file an issue at https://issuetracker.google.com (but I get the feeling nobody reads that), or, since Android is open source, send a pull request to https://android-review.googlesource.com/ which updates the Javadoc from which the documentation is generated.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With