BLE ATT Practical Examples – BLE ATT layer

 

ATT Practical Examples & Chapter 12 Summary

Chapter 12 Part 4 of 4 · Exchange MTU Capture · Service Discovery Walk-Through · Three-Pass Iteration · Error Response · Summary

MTU 525→23Client requests larger
5 servicesDiscovered in 2 passes
Error RespSignals completion
Chapter 12Complete
SEO Keywords:

BLE ATT Exchange MTU sniffer 525 23 negotiation BLE Read By Group Type service discovery GAP GATT Link Loss Immediate Alert Tx Power BLE ATT three iteration service discovery error response BLE ATT chapter 12 summary sequential transactions BlueZ gatttool primary service sniffer capture

12.5.1 — Exchange MTU Practical Capture

Figure 12.19 — What a Real MTU Negotiation Looks Like

The sniffer capture shows two consecutive frames — Frame #815 (client sends the request) and Frame #817 (server responds). The outcome of this exchange sets the ATT payload size for every subsequent PDU in this connection.

Figure 12.19 — Exchange MTU Sniffer Capture
Frame Role PDU Key Value
815 Master (Client) Exchange MTU Request Client Rx MTU = 525 octets
817 Slave (Server) Exchange MTU Response Server Rx MTU = 23 octets
Final ATT_MTU = min(525, 23) = 23 octets
Both sides will use exactly 23 octets for every ATT PDU for the rest of this connection.
Neither side can negotiate a larger MTU later — the exchange happens only once per connection.

The client (a phone or PC) supports a much larger MTU — it offered 525 bytes. The server (a simple sensor) only supports 23 bytes. Because the minimum of the two values wins, the session runs at 23 bytes. The client’s larger buffer capability goes unused, but the protocol remains correct.

This is a common scenario in BLE IoT deployments. Constrained sensors often cannot allocate large receive buffers, so they advertise the minimum supported MTU in their response.

12.5.2 — Reading Primary Services — Three-Pass Example

The Iterative Service Discovery Pattern

A client cannot fetch all services in one request if there are many of them — the response is limited to ATT_MTU size. Instead, the client uses an iterative pattern: request a range, note the last handle returned, then send a new request starting just above that handle. This repeats until the server responds with an Error Response meaning there are no more services in the requested range.

Figures 12.20–12.25 — Complete Service Discovery Walk-Through
Client (Master) Server (Slave)

Pass 1 — Request from handle 0x0001 (Figure 12.20)
Read By Group Type (Start=0x0001, End=0xFFFF, UUID=Primary Service 0x2800)
Response: Length=6, 3 services (Figure 12.21)
GAP (Generic Access Profile) — handles 0x0001 to 0x0007
GATT (Generic Attribute Profile) — handles 0x0016 to 0x0019
Link Loss Alert — handles 0x0080 to 0x0082
Last handle in response = 0x0082 → next request must start at 0x0083

Pass 2 — Request from handle 0x0083 (Figure 12.22)
Read By Group Type (Start=0x0083, End=0xFFFF, UUID=Primary Service 0x2800)
Response: Length=6, 2 more services (Figure 12.23)
Immediate Alert Service — handles 0x0083 to 0x0085
Tx Power Service — handles 0x0086 to 0x0088
Last handle = 0x0088 → next request must start at 0x0089

Pass 3 — Request from handle 0x0089 (Figures 12.24 & 12.25)
Read By Group Type (Start=0x0089, End=0xFFFF, UUID=Primary Service 0x2800)
Error Response: Read By Group Type, Handle 0x0089, Error Code = Attribute Not Found
Error Response = discovery complete ✓ Client has all 5 primary services

The complete service map discovered:

# Service UUID Start Handle End Handle
1 Generic Access Profile 0x1800 0x0001 0x0007
2 Generic Attribute Profile 0x1801 0x0016 0x0019
3 Link Loss Alert 0x1803 0x0080 0x0082
4 Immediate Alert 0x1802 0x0083 0x0085
5 Tx Power 0x1804 0x0086 0x0088
/* gatttool -- primary does this exact iteration automatically */
gatttool -b AA:BB:CC:DD:EE:FF --primary

/* To see the raw ATT frames: run btmon in parallel          */
sudo btmon &
gatttool -b AA:BB:CC:DD:EE:FF --primary

/* btmon output shows Read By Group Type Requests:           */
/* ATT: Read By Group Type Request (0x10) len 6              */
/*   Handle range: 0x0001-0xffff                             */
/*   Attribute group type: Primary Service (0x2800)          */
/* ATT: Read By Group Type Response (0x11) len 20            */
/*   Attribute data length: 6                                */
/*   Attribute group list: 3 entries                         */
/*   handle: 0x0001, end: 0x0007, uuid: 0x1800              */
/*   handle: 0x0016, end: 0x0019, uuid: 0x1801              */
/*   handle: 0x0080, end: 0x0082, uuid: 0x1803              */
/* (continues with next request at 0x0083...)                */

12.6 — Chapter 12 Summary

ATT — A Simple, Focused Data Exchange Protocol

ATT’s design philosophy is minimalism. It provides exactly what is needed to expose, discover, and transfer data between BLE devices — and nothing more. The complexity of organising that data is left to GATT in the next layer up.

Core design principles

  • Client-server model — clear separation
  • Sequential transactions — simple flow control
  • Fixed CID 0x0004 — no setup needed
  • Default 23-byte MTU, negotiable upward
  • 30-second transaction timeout
All operation types

  • Read (single, blob, multiple, by type, by group)
  • Write (acknowledged request, fire-and-forget command)
  • Long writes (prepare + execute two-phase)
  • Server push (notification, indication)
  • Data signing (signed write command)
Typical data sizes

  • 10–20 bytes typical per LE transaction
  • Fits in one LE ACL data packet
  • Long values: use Read Blob or Prepare Write
  • Service discovery: iterative Group Type reads
  • Completion always signalled by Error Response
Next: Chapter 13 GATT — GATT takes the flat list of ATT attributes and organises them into a hierarchy: profiles contain services, services contain characteristics, characteristics have descriptors. This hierarchy is what makes BLE devices understandable to any client without prior knowledge of the specific device.

Chapter 12 ATT Series

Next — Chapter 13: Generic Attribute Profile (GATT)

GATT builds the Profile → Service → Characteristic hierarchy on top of ATT. Mandatory for all BLE devices.

Next: GATT Introduction → ← Part 3

Leave a Reply

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