Hello world!
Given some suitable byte sequences b1, b2 and a Bluetooth Low Energy device that provides two GATT characteristics c1 and c2, can I call CBPeripheral.writeValue(b1, c1)
and then CBPeripheral.writeValue(b2, b2)
without waiting for the callback of the corresponding CBPeripheralDelegate
to occur for the first write operation to c1 and without causing one of both operations to fail due to iOS's BLE implementation? Is there any official documentation or specification that states what would or could happen in such scenario?
The background of this question is that on Android, you usually can only perform one GATT operation on a single BluetoothGatt
instance at a time. Consecutive operations, even for different characteristics, that do not await the callback invocations of previously requested GATT operations, usually just fail. However, experimenting with CBPeripheral
, I can see that such accesses seem to be working on iOS. Now, is that undefined behavior and I am just observing a forgiving implementation or this actually specified behavior?
I would be glad about any hints or comments on this matter that have foundation in the official Apple developer documentation or any official Bluetooth specification. Since I already tried my luck with search engines, I would assume that this is just undefined behavior. Thank you!
Regards, Luis.
This is not a matter of iOS or Android's implementation, but how write-with-response works with BLE. As you imply you are receiving a callback after the write, I will assume you are using write-with-response.
When you are using write-with response, the whole operation requires at least 2 connection intervals to finish. Your write will take 1 connection interval. Then in the second interval you will receive the acknowledgement, and the consecutive callback to your app.
A second write to the same peripheral cannot go through until the first one is completed.
Now, this doesn't necessarily mean that you absolutely cannot call writeValue() again before the callback for the first one, but the success of the second write will depend on a lot of factors that are not under your control, or have knowledge of.
iOS has a very limited queue to buffer write requests. The success of the second write will depend on many factors like the connection parameters, response time of the accessory, etc. and there is no way for your app to know these factors.
If you send a second write before the first one is acknowledged to be complete, and it cannot go through, the write will fail without any errors, and the app will have no way to know if the write went through or not.
In any case, writing this way does not provide any benefit to the throughput of your writes, if that's what you are after. And with the risk of your second write failing intermittently without the app being aware will do more harm than good.
So, our recommendation is to wait for the callback before a second write when using write-with-response.
Argun Tekant / WWDR Engineering / Core Technologies