BLE GATT Layer – GATT Features

 

GATT — All 11 Features & Procedures

Chapter 13 Part 2 of 2 · Table 13.2 Complete · Service Discovery · Characteristic Read/Write · Notify/Indicate · Descriptor Operations · BlueZ Examples

11GATT features
26+Sub-procedures
0x2800Primary Service UUID
0x2902CCCD descriptor

SEO Keywords:

BLE GATT 11 features Table 13.2 BLE primary service discovery all services by UUID BLE Find Included Services relationship discovery BLE Discover All Characteristics service BLE Read Long Characteristic multiple values BLE Write Reliable Writes Signed Write BLE GATT Notifications Indications CCCD 0x2902 BlueZ gatttool GATT procedures

13.5 — Configured Broadcast

📡
Client Configures Server to Broadcast Characteristic Values in Advertising

A client can ask the server to include certain characteristic values inside its BLE advertising packets. This is done by setting the broadcast bit in the Server Characteristic Configuration Descriptor — a descriptor associated with that characteristic. Once set, the server includes that characteristic’s value in its advertising data so nearby devices can read it without even connecting.

Example use case: a thermometer broadcasting current temperature in its advertising packets. Any phone nearby can read the temperature from the advertisement without needing to connect, saving radio time for both devices.

13.6 — GATT Features (Table 13.2)

1
Server Configuration
Exchange MTU

The client negotiates the ATT_MTU size at the start of the connection. Sent only once. Sets the maximum PDU payload for all subsequent ATT operations. Default is 23 octets. See Chapter 12 for the full Exchange MTU walkthrough.

2
Primary Service Discovery
Discover All Primary Services Discover Primary Services By UUID

Discover All: Uses Read By Group Type Request (UUID = 0x2800) iteratively, starting from handle 0x0001 and repeating until an Error Response arrives. Returns all services with their handle ranges.

By UUID: Uses Find By Type Value Request (UUID = 0x2800, value = specific service UUID) to find only instances of one particular service. Useful when the client knows exactly which service it needs without wanting to walk the entire database.

/* Discover all primary services:                           */
gatttool -b AA:BB:CC:DD:EE:FF --primary

/* Discover only Heart Rate Service:                        */
gatttool -b AA:BB:CC:DD:EE:FF --primary --uuid=0x180D

/* With bluetoothctl:                                       */
[AA:BB:CC:DD:EE:FF]# menu gatt
[AA:BB:CC:DD:EE:FF]# list-attributes

3
Relationship Discovery
Find Included Services

A service may reference (include) other services using Include Definitions. This procedure finds those references. The client uses Read By Type Request with UUID = 0x2802 (Include) within the handle range of the service being examined. The response reveals which other services this service depends on.

For example, if the Heart Rate Service includes the Device Information Service, this procedure will reveal that relationship. The client can then read the Device Information Service directly once it has its start/end handles from the Include Declaration.

4
Characteristic Discovery
Discover All Characteristics of a Service Discover Characteristic by UUID

Once the service handle range is known, the client reads all Characteristic Declarations within it using Read By Type Request (UUID = 0x2803). The response gives: the Properties byte (what operations are allowed), the Value Handle (the handle to use when reading/writing the value), and the Characteristic UUID (what type of data it is).

By UUID: Same Read By Type Request but the client looks for a specific characteristic UUID, getting only the matching characteristic declarations.

/* Discover all characteristics in a service:               */
gatttool -b AA:BB:CC:DD:EE:FF \
         --characteristics --start=0x000a --end=0x0019

/* Discover specific characteristic by UUID:                */
gatttool -b AA:BB:CC:DD:EE:FF \
         --characteristics --uuid=0x2A37

/* bluetoothctl shows characteristics automatically         */
/* after list-attributes — type "Characteristic" entries    */

5
Characteristic Descriptor Discovery
Discover All Characteristic Descriptors

Descriptors live between the Characteristic Value Declaration and the next Characteristic Declaration. The client uses Find Information Request to get handle-UUID pairs in the range between the characteristic’s value handle and the next characteristic’s handle. Common descriptors include the CCCD (0x2902 — enables notify/indicate), User Description (0x2901), and Presentation Format (0x2904).

/* Find descriptors for a characteristic:                   */
gatttool -b AA:BB:CC:DD:EE:FF \
         --char-desc --start=0x000b --end=0x000d

/* Output typically shows:                                  */
/* handle: 0x000b, uuid: 0x2803 (Characteristic Decl)      */
/* handle: 0x000c, uuid: 0x2a37 (Heart Rate Measurement)   */
/* handle: 0x000d, uuid: 0x2902 (Client Char Config = CCCD) */

6
Characteristic Value Read
Read Characteristic Value Read Using Characteristic UUID Read Long Characteristic Values Read Multiple Characteristic Values

Read Characteristic Value: ATT Read Request using the value handle. Returns up to ATT_MTU-1 bytes.

Read Using UUID: ATT Read By Type Request — lets the client read a characteristic value without needing its handle, only its UUID. Useful when the handle is not cached.

Read Long: ATT Read + Read Blob sequence for values larger than ATT_MTU-1 bytes. Client keeps issuing Read Blob with increasing offsets until the response is shorter than ATT_MTU-1.

Read Multiple: ATT Read Multiple Request — fetches several fixed-length characteristic values in one round trip.

/* Read a specific characteristic by handle:                */
gatttool -b AA:BB:CC:DD:EE:FF --char-read --handle=0x000c

/* Read by UUID (no need to know handle):                   */
gatttool -b AA:BB:CC:DD:EE:FF --char-read --uuid=0x2A29
/* Returns Manufacturer Name String value                   */

/* BlueZ Python D-Bus read:                                 */
char_iface.ReadValue({'offset': dbus.UInt16(0)})

7
Characteristic Value Write
Write Without Response Signed Write Without Response Write Characteristic Value Write Long Characteristic Values Characteristic Values Reliable Writes

Write Without Response: ATT Write Command — fire and forget, no acknowledgement. Fastest but unreliable.

Signed Write Without Response: ATT Signed Write Command — includes 12-byte CSRK signature for integrity without link encryption.

Write Characteristic Value: ATT Write Request — acknowledged write. Server confirms success or returns error.

Write Long: ATT Prepare Write + Execute Write sequence for values larger than ATT_MTU-3 bytes. Two-phase commit.

Reliable Writes: Multiple Prepare Write Requests where the client verifies each echoed response before sending the next chunk. If any echo doesn’t match, the client cancels with Execute Write (Flags=0x00) and retries.

/* Acknowledged write:                                      */
gatttool -b AA:BB:CC:DD:EE:FF \
         --char-write-req --handle=0x0025 --value=01

/* Write without response (faster, no ACK):                 */
gatttool -b AA:BB:CC:DD:EE:FF \
         --char-write --handle=0x0025 --value=01

/* BlueZ D-Bus write with options:                          */
char_iface.WriteValue([0x01], {})              # Write Request
char_iface.WriteValue([0x01], {'type':'command'})  # Write Cmd

8
Characteristic Value Notification
Notifications

The client enables notifications by writing 0x0001 to the CCCD descriptor (UUID 0x2902) associated with the characteristic. The server then sends Handle Value Notification PDUs whenever the characteristic value changes. The client never sends a response — unreliable delivery but lowest overhead.

The client must re-enable notifications after every reconnection unless the bonded CCCD value is persistent on the server.

/* Enable notifications — write 0x0001 to CCCD handle:      */
gatttool -b AA:BB:CC:DD:EE:FF --char-write-req \
         --handle=0x000d --value=0100

/* Listen for incoming notifications:                       */
gatttool -b AA:BB:CC:DD:EE:FF --listen

/* bluetoothctl:                                            */
[AA:BB:CC:DD:EE:FF]# select-attribute /org/.../char000b
[AA:BB:CC:DD:EE:FF]# notify on
9
Characteristic Value Indication
Indications

Enable by writing 0x0002 to the CCCD. The server sends Handle Value Indication PDUs. The client must respond with Handle Value Confirmation before the server sends the next indication. Reliable delivery — server knows the client received each value. Higher latency than notification due to confirmation round-trip.

/* Enable indications — write 0x0002 to CCCD handle:        */
gatttool -b AA:BB:CC:DD:EE:FF --char-write-req \
         --handle=0x000d --value=0200

/* BlueZ automatically sends Confirmation for Indications   */
/* The application just sees the value via D-Bus signal     */

10
Characteristic Descriptor Value Read
Read Characteristic Descriptors Read Long Characteristic Descriptors

Reads the current value of a descriptor — for example, reading the CCCD to check whether notifications are currently enabled, or reading the User Description to get a human-readable string for a characteristic. Long descriptors use the Read Blob mechanism just like long characteristic values.

/* Read CCCD value (check if notifications enabled):        */
gatttool -b AA:BB:CC:DD:EE:FF --char-read --handle=0x000d
/* Response 0100 = notifications enabled                    */
/* Response 0000 = disabled                                 */

/* Read User Description descriptor:                        */
gatttool -b AA:BB:CC:DD:EE:FF --char-read --handle=0x000e
/* Returns UTF-8 string e.g. "Heart Rate"                   */
11
Characteristic Descriptor Value Write
Write Characteristic Descriptors Write Long Characteristic Descriptors

Writes to a descriptor using ATT Write Request. The most common use is writing to the CCCD (enabling/disabling notifications or indications). Long descriptors use Prepare Write + Execute Write. Most clients only write to CCCDs, but some application profiles use writable User Description or custom descriptors.

/* Disable notifications (write 0x0000 to CCCD):            */
gatttool -b AA:BB:CC:DD:EE:FF --char-write-req \
         --handle=0x000d --value=0000

/* Summary of CCCD values:                                  */
/* 0x0000 = disable all                                     */
/* 0x0001 = enable notifications                            */
/* 0x0002 = enable indications                              */
/* 0x0003 = enable both (if characteristic supports both)   */

Table 13.2 — GATT Features and Procedures Summary

# Feature Sub-procedures
1 Server Configuration Exchange MTU
2 Primary Service Discovery Discover All · By Service UUID
3 Relationship Discovery Find Included Services
4 Characteristic Discovery Discover All · By UUID
5 Characteristic Descriptor Discovery Discover All Descriptors
6 Characteristic Value Read Read · By UUID · Long · Multiple
7 Characteristic Value Write Write Without Resp · Signed · Write · Long · Reliable
8 Characteristic Value Notification Notifications
9 Characteristic Value Indication Indications
10 Characteristic Descriptor Value Read Read · Read Long
11 Characteristic Descriptor Value Write Write · Write Long

Chapter 13 Summary

GATT is the framework every BLE application rests on. It takes ATT’s flat attribute list and gives it a logical shape — services hold related characteristics, and profiles group services into complete device roles. The 11 GATT features provide a complete toolkit: discover what a device offers, read its current values, write new values, and subscribe to receive updates automatically.

Every BLE device exposes at least two mandatory services — Generic Access (device name, appearance) and Generic Attribute (Service Changed characteristic). Everything else is application-specific and defined by profile specifications that build on the foundation GATT provides.

/* Complete GATT client workflow in BlueZ shell:            */
sudo bluetoothctl
[bluetooth]# scan on
[bluetooth]# connect AA:BB:CC:DD:EE:FF
[AA:BB:CC:DD:EE:FF]# menu gatt

/* Service/characteristic discovery (Feature 2, 4, 5):     */
[AA:BB:CC:DD:EE:FF]# list-attributes

/* Navigate to a characteristic:                            */
[AA:BB:CC:DD:EE:FF]# select-attribute /org/.../char000b

/* Read (Feature 6):                                        */
[AA:BB:CC:DD:EE:FF]# read

/* Write (Feature 7):                                       */
[AA:BB:CC:DD:EE:FF]# write "0x01"

/* Enable notifications (Feature 8):                        */
[AA:BB:CC:DD:EE:FF]# notify on

/* Incoming notifications print automatically:              */
/* [CHG] Attribute .../char000b Value: 0x48 bpm             */

Leave a Reply

Your email address will not be published. Required fields are marked *