Bluetooth Low energy Attribute Protocol (ATT)

 

Chapter 12 — Attribute Protocol (ATT)

Part 1 of 4 · Introduction · Attribute Structure · UUID · Permissions · PDU Format · Sequential Transactions

CID 0x0004Fixed L2CAP channel
4 fieldsPer attribute
6 PDU typesRequest to Confirm
30sTransaction timeout
SEO Keywords:

BLE Attribute Protocol ATT introduction BLE attribute structure handle type value permissions BLE UUID 128-bit 16-bit Bluetooth_Base_UUID BLE attribute permissions access encryption authentication authorization BLE ATT six PDU types request response notification indication BLE 30 second transaction timeout sequential BlueZ GATT attribute protocol

12.1 — Introduction

What ATT Does and Where It Sits

The Attribute Protocol gives one BLE device a way to discover what data another device exposes, then read or write that data. It runs directly above L2CAP and uses CID 0x0004 — a fixed channel that needs no setup handshake before use.

ATT feeds directly into the Generic Attribute Profile (GATT), which organises ATT attributes into the services and characteristics that applications actually work with. Think of ATT as the raw data transport and GATT as the filing system on top of it.

Figure 12.1 — ATT Position in the LE Stack
GATT-Based Profiles
Generic Access Profile (GAP)
Generic Attribute Profile (GATT)
Attribute Protocol (ATT) ← This chapter
Security Manager (SM)
L2CAP (CID 0x0004)
Link Layer / HCI / Radio

Client-server model: The server holds attributes and exposes them. The client discovers, reads, and writes them. A device can be both client and server simultaneously — a heart rate monitor, for example, is a server for heart rate data but might also be a client when reading time from a paired phone. Only one server can be active on a device at any time.

12.2 — What Is an Attribute?

Any Piece of Data a Device Wants to Share

An attribute is an addressable piece of data. It can represent anything: a temperature reading, a device name, battery level, a control command, or the timestamp of last measurement. The ATT protocol is designed to push or pull any such data to or from a remote device, and to alert remote devices when that data changes.

Examples of attributes:

  • Temperature value from a thermometer
  • Temperature unit (Celsius / Fahrenheit)
  • Device name string
  • Manufacturer name and model number
  • Heart rate measurement
  • Battery level percentage
What ATT lets you do:

  • Discover what attributes exist on a server
  • Read the value of any attribute
  • Write a value to a writable attribute
  • Subscribe to notifications when a value changes
  • Receive reliable indications with confirmation

Attribute Structure — Four Fields

Every attribute on a server is described by exactly four fields. These four fields together form the complete identity of that piece of data.

Figure 12.2 — Attribute Structure
Attribute Handle 2 octets — unique address, 0x0001 to 0xFFFF
Attribute Type (UUID) 2 octets (16-bit UUID) or 16 octets (128-bit UUID)
Attribute Value Fixed (1/2/4 octets) or variable length
Attribute Permissions Defined by GATT profile or implementation

12.2.1 — Attribute Type (UUID)

The type field tells a client what this attribute means. Without the type, a handle is just a number pointing to an unknown blob of bytes. The type gives it semantic meaning — “this is a temperature”, “this is a heart rate”, “this is a service boundary”.

All types are identified by a UUID — a Universally Unique Identifier. Two forms are used:

16-bit UUID (short form)

Assigned by the Bluetooth SIG. Published in the Bluetooth Assigned Numbers specification. Used for all standard BLE characteristics and services. Much more compact — only 2 bytes instead of 16.

Example: 0x2A37 = Heart Rate Measurement
Example: 0x180D = Heart Rate Service
Example: 0x2A29 = Manufacturer Name String
128-bit UUID (full form)

Used for custom vendor-specific services and characteristics. Any developer can generate a 128-bit UUID and use it without registration. Derived from 16-bit SIG UUIDs by substituting into the base formula.

128-bit UUID = 16-bit × 2^96 + Bluetooth_Base_UUID
Base UUID: 0000xxxx-0000-1000-8000-00805F9B34FB
Replace xxxx with the 16-bit UUID hex value

12.2.2 — Attribute Handle

Every attribute on a server has a unique numeric handle — a 16-bit value the client uses in every read, write, and discovery operation. Think of it as an address in memory: once you know the handle for “heart rate measurement”, you can read it directly without rediscovering it every connection.

Handle 0x0000 is reserved — never assigned to any attribute.
Handle 0xFFFF is the maximum handle, used as the “end of range” in discovery requests.
Handles are ordered in ascending sequence. Clients iterate through attributes in handle order.
Once assigned, a handle never changes — clients can cache it safely across connections.

If an attribute is deleted, its handle number is retired — the server must not reuse that handle number for any future attribute, even if it adds a new attribute at the same logical position. This guarantees that cached handles on clients remain unique and valid.

12.2.3 — Attribute Permissions

Permissions control who can access an attribute and what they must prove first. They are set by the GATT profile or the application — ATT just enforces them by returning error codes when the requirements are not met.

1. Access Permissions — Can this attribute be read, written, or both? This is the most basic gate — even before encryption or authentication are checked, ATT verifies that the requested operation type is allowed at all.
2. Encryption Permissions — Must the link be encrypted before this attribute can be accessed? A medical device might require link encryption before exposing health measurements, even if the connection itself is allowed without authentication.
3. Authentication Permissions — Must the client have completed an authenticated pairing (one that included MITM protection) before accessing this attribute? Authentication proves the client’s identity, not just that the link is encrypted.
4. Authorization Permissions — Must the client have been explicitly authorized by the user or application before accessing this attribute? This is an application-level gate, separate from authentication. A health app might require authorization even after the device is paired.
Permission Error Codes Returned When Access Is Denied
Error Code Meaning
Read Not Permitted Attribute type does not support reading
Write Not Permitted Attribute type does not support writing
Insufficient Authentication Authenticated pairing required — re-pair with MITM
Insufficient Authorization Application-level authorization needed
Insufficient Encryption Key Size Current encryption key is too short
Insufficient Encryption Link must be encrypted first

12.2.4 — Attribute Value

The value is the actual payload — the byte array that contains the data. Lengths are either fixed (1, 2, or 4 octets for simple types) or variable (strings, variable-length records). ATT sends only one attribute value per PDU. If the value is too large for a single PDU, it gets split across multiple read operations using Read Blob requests.

12.2.5 — Control Point Attributes

Some attributes exist to receive commands, not to expose data. These are write-only — they cannot be read. A good example is the Alert Level characteristic in the Immediate Alert Service: a remote device writes “No Alert”, “Mid Alert”, or “High Alert” to it, which triggers an action like flashing an LED or sounding a buzzer. Reading back the alert level makes no sense — the attribute only processes incoming writes.

12.2.6 — Grouping of Attribute Handles

ATT allows attributes to be grouped together with a specific attribute placed at the beginning of the group. GATT defines three group types: Primary Service, Secondary Service, and Characteristic. Grouping enables range-based operations — a client can ask “give me all attributes in the handle range of this Primary Service group” and get the entire service definition in one transaction.

12.2.7 — Atomic Operations

When multiple clients are connected to one server, each client’s operation is treated atomically — it completes without interference from other clients. If Client A is doing a multi-step Prepare Write sequence, Client B starting a different write on the same server does not corrupt A’s queued data. Each client has its own separate write queue on the server.

12.3 — The Six PDU Method Types

Every ATT Packet Falls Into One of Six Categories

The ATT protocol uses six types of PDU, distinguished by who sends them and whether a response is expected:

Figure 12.3 — ATT Client and Server Message Types
Client Server
Request
Server must reply with a Response (or Error Response)
Response
Sent by server in reply to a Request
Command
Client fires and forgets — no response expected
Notification
Server pushes data unprompted — no response from client
Indication
Server pushes data — client must send Confirmation
Confirmation
Client acknowledges receipt of an Indication

12.3.1 — PDU Format

Every ATT packet starts with a 1-byte Opcode field followed by variable-length parameters, and optionally an authentication signature at the end.

Figure 12.4 — Attribute Protocol PDU Format
Opcode
1 octet
Method
6 bits
CMD
1b
AUTH
1b
Attribute Parameters
Variable length — method-specific data
Auth Sig
Optional
12 octets
CMD flag = 1 → this is a Command (no ACK from server) | AUTH flag = 1 → 12-byte signature appended for data signing on unencrypted links

The Authentication Signature is for the scenario where the link is not encrypted but data integrity is still required. The CSRK (Connection Signature Resolving Key distributed in SM Phase 3) generates this 12-byte signature. The server verifies it before processing the write. This is different from link encryption — it is message-level integrity only.

12.3.2 — Sequential Transactions and the 30-Second Timeout

ATT is a sequential protocol. The client sends one Request and must wait for the Response before sending the next Request. The server sends one Indication and must wait for the Confirmation before sending the next Indication. This keeps things simple and provides implicit flow control.

Request/Response — client sends Request, waits for Response. Next Request only after Response arrives.
Indication/Confirmation — server sends Indication, waits for Confirmation. Next Indication only after Confirmation arrives.
Commands and Notifications — these are fire-and-forget. No waiting, no flow control. If the receiver cannot process them, they are silently discarded. This makes them unreliable — use Indication if delivery confirmation matters.

30-second timeout: If a Request is sent and no Response arrives within 30 seconds, the transaction has timed out. The client notifies the higher layer (GATT, application) of the failure. Both sides must disconnect and reconnect to clear the failed state before trying again.

Interesting sequence possibilities: Because Notifications have no flow control, a sequence like Request → Notification → Response is perfectly valid. The server can send a Notification in the middle of a pending Request/Response pair without violating the protocol.

/* Discovering all services with gatttool (BlueZ)            */
gatttool -b AA:BB:CC:DD:EE:FF -I

/* Inside the interactive session:                           */
[AA:BB:CC:DD:EE:FF][LE]> connect
[AA:BB:CC:DD:EE:FF][LE]> primary

/* This sends a sequence of Read By Group Type Requests      */
/* on CID 0x0004 — waits for each Response before sending   */
/* the next Request (sequential transactions enforced)       */

/* Output:                                                   */
/* attr handle: 0x0001, end grp handle: 0x0007 uuid: 1800   */
/* attr handle: 0x0016, end grp handle: 0x0019 uuid: 1801   */
/* attr handle: 0x0080, end grp handle: 0x0082 uuid: 1803   */

/* Using bluetoothctl (newer BlueZ):                         */
bluetoothctl
[bluetooth]# connect AA:BB:CC:DD:EE:FF
[AA:BB:CC:DD:EE:FF]# list-attributes
/* Lists all GATT services and characteristics via ATT      */

Chapter 12 ATT Series

Next — ATT Read Methods

Part 2 covers all the Request/Response read operations: Exchange MTU, Find Information, Find By Type Value, Read By Type, Read, Read Blob, Read Multiple, and Read By Group Type.

Next: Part 2 Read Methods →

Leave a Reply

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