This article will consider ATT_MTU equal to 23. See Part 1 for more details.
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.
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:
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.