CCCD
Client Characteristic Configuration Descriptor -- enables/disables notifications or indications for a characteristic.
What Is the CCCD?
The Client Characteristic Configuration Descriptor (ATT">CCCD) is a 2-byte descriptor attached to a GATT characteristic that controls whether the server sends notifications or indications to a connected client. Without writing to the CCCD, a client will never receive unsolicited updates, even if the characteristic's properties advertise Notify or Indicate support.
Bit Layout
The CCCD value is a 16-bit little-endian field:
| Bit | Value | Meaning |
|---|---|---|
| 0 | 0x0001 | Notifications enabled |
| 1 | 0x0002 | Indications enabled |
| 2-15 | Reserved | Must be zero |
Writing 0x0001 enables notifications. Writing 0x0002 enables indications. Writing 0x0000 disables both. A client should never set both bits simultaneously on the same characteristic because the Bluetooth specification treats this as undefined behavior, though some stacks tolerate it.
Per-Client State
A critical aspect of the CCCD is that it maintains independent state for each bonded client. When Client A enables notifications, Client B's CCCD remains unchanged. This per-client independence means the GATT server must persist CCCD values in non-volatile storage keyed by the client's identity (IRK or address). After a reconnection, the server should restore the saved CCCD state so the client does not need to re-subscribe.
How Subscription Works
The typical flow for subscribing to a sensor characteristic:
- The client discovers the characteristic and its descriptors.
- The client locates the CCCD by its UUID (0x2902) within the characteristic's handle range.
- The client issues an ATT Write Request to the CCCD handle with value 0x0001.
- The server acknowledges the write and begins sending Notification PDUs whenever the characteristic value changes.
On iOS, Android, and most embedded stacks, the subscription API abstracts this process into a single call (e.g., setNotifyValue on iOS), but understanding the underlying CCCD mechanics is essential for debugging interoperability issues.
Common Pitfalls
Firmware developers frequently encounter CCCD-related bugs. Forgetting to include a CCCD attribute in the ATT database while advertising Notify properties causes subscription failures on mobile devices. Not persisting CCCD state across reboots leads to "silent reconnections" where the peripheral stops streaming data until the client manually re-subscribes. Some Android versions cache CCCD state aggressively, requiring a Bluetooth adapter restart to clear stale subscriptions. Testing with multiple bonded devices is essential to verify correct per-client CCCD isolation.
Related Terms
Related Content
BLE GATT Server Implementation Guide
Development…server-initiated data push. The client must write to the CCCD (UUID 0x2902) to enable them. Indication requires client…
Web Bluetooth API: BLE from the Browser
Development…// Enable notifications via CCCD descriptor const cccd = await…
Python BLE with Bleak: Cross-Platform BLE Scripting
Development…client.stop_notify(HR_MEASUREMENT) start_notify writes the CCCD automatically. For indications , Bleak handles the ACK at…
flutter_blue_plus: Read, Write & Notify in Flutter
Development…HR_CHAR)!; await hrChar.setNotifyValue(true); // writes CCCD final sub = hrChar.onValueReceived.listen((data) { final…
GATT UUID & Descriptors (0x2902) Explained — BLE
Protocols & Profiles…(0x2A37) │ ├── Value (Notify) │ └── Descriptor: CCCD (0x2902) └── Characteristic: Body Sensor Location (0x2A38)…
Frequently Asked Questions
Our glossary covers 90+ BLE technical terms organized by category. Each term includes a definition, related terms, and links to relevant chips and guides.