This article will consider ATT_MTU equal to 23. See Part 1 for more details.
Notifications and indications of long attributes
Notifications and indications for long attributes are very similar to reading operations (see Part 2). We will discuss notifications only, as indications are the same, except that they also involve a confirmation from the Client.
First, when the Server needs to notify, if the attribute’s value is longer than 20, it will only send the first 20 bytes in the ATT_HANDLE_VALUE_NOTIFICATION packet. The other 3 bytes are reserved for the operation code (1 byte) and the attribute handle (2 bytes).
Upon receiving such a packet with the maximum possible number of data bytes (20), the Client has the responsibility to begin a series of ATT_READ_BLOB_REQUESTS (just like when reading the attributes itself), starting with an offset of 20. All subsequent offsets will add 22 because the responses will be ATT_READ_BLOB_RESPONSE packets, which do not contain the attribute handle. The blob requests should continue until a response with less than 22 data bytes is received.
Concurrent access protection
Remember (Part 3) that whenever we write a long attribute we must use queues to ensure the writing operation is atomic given the possibility that multiple clients may be connected and trying to write the same attribute at the same time.
Unfortunately, the Bluetooth Core 4.1 specification does not provide a standard protection from concurrent access in case of reading long attributes.
There are two ways something may go wrong when reading multiple parts of a long attribute, and let us see two examples for that:
One Client may be in the middle of sending parts of an attribute to be saved in the Prepare Write Queue when a second Client begins reading blobs of the same attribute. Then, while the second Client has just read the first half of the attribute, the first one sends the command to execute the queue, which prompts the Server to atomically modify the entire value of the attribute, leaving the unfortunate second Client with a whole different second half of attribute to read.
After a sensor has modified a value in the database and the ATT Server has sent a notification to the Client, the Client begins reading parts of the attribute with blob requests. Once again, it is possible that, in the middle of the readings, the sensor changes the value once again, so the rest of the readings are seeing a different value of the attribute.
The specification leaves this problem in the hands of the application, so care must be taken if the use-case has the possibility of getting compromised by such concurrency issues.
Probably the best solution is to listen to the recommendations and have as few long attributes as possible on a GATT Server.