BLE: Read Long Characteristics Value using Android / iOS
Asked Answered
E

1

2

With a normal Characteristics Read only the MTU Size (20bytes) of data will be read. My customer will offer a characteristics with a larger size (about 100bytes).

I saw that BLE offers a "Long Read" feature which reads until the size of the characteristics is reached. (https://bluegiga.zendesk.com/entries/25053373--REFERENCE-BLE-master-slave-GATT-client-server-and-data-RX-TX-basics)

attclient_read_long command - Starts a procedure where the client first sends normal read request to the server, and if the server returns an attribute value with a length equal to the BLE MTU (22 bytes), then the client continues to send "read long" requests until rest of the attribute is read. This only applies if you are reading attributes that are longer than 22 bytes. It is often simpler to construct your GATT server such that there are no long attributes, for simplicity. Note that the BLE protocol still requires that data is packetized into max. 22-byte chunks, so using "read long" does not save transmission time.

But how can I use this feature in Android? The BluetoothGatt class only offers a simple "Read()" - same for iOS.

Increasing the MTU is not possible since we need to support devices with AP Level < 21 (increaseMTU was introduced at API 21)

Elkins answered 7/7, 2016 at 9:29 Comment(2)
In iOS, at least, you would need to issue multiple reads, repeating until you get less than 22 bytes. This is the same process described by BlueGiga; you just need to implement it yourself. I suspect the same may be true of AndroidAlessandraalessandria
Hi! Do you have any update on this? I am trying to do this in iOS. I have an ESP32 peripheral which tries to send data which is around 1000 bytes long. When I receive the data in didUpdateValueFor function, after calling the .readValue(for:) function, the data I get is always the same and always only 516 bytes long. And it is the beginning of the data on the peripheral. Have you found out how to perform some kind of a long read on iOS?Canned
T
2

I can confirm for iOS that a read operation as per standard will occur first. Then if the server returns a completely filled PDU, the iOS device will then continue to perform the blob read operation. Tested with iPhone 7 running iOS 11.2.x

You do NOT need to call the peripheral.readValue(characteristic) multiple times for long attributes. CoreBluetooth does all of this under the covers.

Refer to the Bluetooth Spec Core v5.0, specifically Vol 3, Part F. "Long Attribute Values".

Experiment to prove above.

I have an Android Thing acting as the server that I'm making return the maximum length with my iPhone during a read operation. iOS and my RPI3 exchange a MTU of 185. So the read response is (MTU - 1) 184 bytes long. The server (RPI) then receives a new read request with an offset of 184, which you can then return more data. This is continued until the offset is > 512, or the last read response returns less than the MTU - 1 length.

Based upon the fact that the BluetoothGattServer supports long attributes, I'd assume the BluetoothGatt object does as well. Since there is no way via the API to set the offset to be read, I'd assume you can invoke read just once.

Tanh answered 29/3, 2018 at 3:55 Comment(1)
Hi user2121685! Can you clarify how it's done on iOS? I have an ESP32 peripheral which tries to send data which is around 1000 bytes long. When I receive the data in didUpdateValueFor function, after calling the .readValue(for:) function, the data I get is always the same and always only 516 bytes long. And it is the beginning of the data on the peripheral.Canned

© 2022 - 2024 — McMap. All rights reserved.