Common Audio Profile (CAP)

EmbeddedPathashala · Bluetooth LE Audio Series

Common Audio Profile (CAP)

The Orchestration Framework for All Bluetooth LE Audio Use Cases

v1.0
Spec Version
Adopted March 2022
3
Defined Roles
Initiator · Acceptor · Commander
BT 5.3+
Core Spec
LE Audio Foundation
GATT
Transport
Over BLE Only

What is the Common Audio Profile?

The Common Audio Profile (CAP) is the top-level orchestration profile introduced with Bluetooth LE Audio. It defines how audio devices discover each other, take on defined roles, and coordinate the setup of audio streams — whether those streams are unicast (one-to-one), broadcast (one-to-many), or coordinated (controlling a pair of earbuds as a unit).

Before LE Audio, Bluetooth had separate profiles for music (A2DP), calls (HFP), remote control (AVRCP), and so on. Each profile worked in isolation. CAP replaces this fragmented world with a single, unified framework built entirely on GATT over BLE. Every LE Audio product — smartphones, earbuds, hearing aids, TVs, laptops — implements CAP as its base.

Key insight: CAP does not define audio codecs or transport parameters by itself. Instead it defines procedures — sequences of GATT operations — that use other services (PACS, ASCS, CSIS, VCP, etc.) to achieve audio goals. Think of CAP as the manager who delegates the actual work to specialist departments.

Why CAP Was Needed

Classic Bluetooth audio had a fundamental problem: every profile was independent. An A2DP headset had no standard way to coordinate with a second earbud. Volume control was handled differently by HFP vs A2DP. Discovering a device’s audio capabilities required proprietary mechanisms.

LE Audio was designed from scratch to fix this. CAP provides:

  • Unified discovery — the CAP Acceptor role (identified by CAS) is the single discovery target for all LE Audio sinks and sources
  • Standardised procedures — a defined sequence of GATT operations to start, update, and stop audio streams
  • Coordinated Set support — native concept of grouped devices (left + right earbud) acting as one logical unit
  • Multi-role flexibility — the same device can be an Initiator in one connection and an Acceptor in another

CAP Roles

CAP defines three roles. A real device may implement one or more of these depending on its function. The roles are not mutually exclusive.

📱 CAP Initiator
Controls the audio session. Discovers Acceptors, reads their capabilities, and triggers audio stream setup.
Real devices:
Smartphone, Tablet, Laptop, Dongle
Mandatory services it uses:
CAS (for Acceptor discovery)
PACS (capability check)
ASCS (stream control)
🎧 CAP Acceptor
Receives and renders audio (speaker/earbud) or captures audio (microphone). Must expose CAS on its GATT server.
Real devices:
Earbuds, Hearing Aids, Headsets, Smart Speakers
Mandatory services exposed:
CAS (identity)
PACS (capabilities)
ASCS (stream control)
🎮 CAP Commander
Optional role. Coordinates multiple Acceptors in a Coordinated Set — for example, managing left and right earbuds as a pair — without being the audio source itself.
Real devices:
Could be part of a smartphone, TV, or dedicated audio controller
Uses:
CSIS (set lock/unlock)
VCP (coordinated volume)
MICP (mic mute)

Role Interaction — How They Connect
Initiator
(e.g. Smartphone)
Discovers via CAS
Controls ASCS / PACS
(Commander role: also manages Coordinated Set lock via CSIS)
Acceptor
(e.g. Earbuds)
Exposes CAS, PACS, ASCS, CSIS

Where CAP Sits in the LE Audio Stack

CAP is a profile-level specification. It sits above the GATT layer and uses multiple services to perform its procedures. Below is the full LE Audio stack from the physical layer up to use-case profiles.

USE CASES  |  Music  ·  Calls  ·  Hearing Aid  ·  Broadcast Audio
TMAP   (Telephony & Media Audio Profile) HAP   (Hearing Access Profile)
⭐  CAP — Common Audio Profile  ⭐
CAS CSIS PACS ASCS VCP/MICP BASS
GATT — Generic Attribute Profile
ATT — Attribute Protocol
L2CAP — Logical Link Control and Adaptation Protocol
ISO — Isochronous Channels (audio data) HCI — Host Controller Interface (control)
LE Controller — Baseband, PHY (1M / 2M / Coded)

ⓘ Audio data flows through ISO channels (CIS/BIS). GATT over L2CAP is used for control/configuration only.

Profiles and Services Used by CAP

CAP orchestrates other services to achieve its procedures. Here is a reference for every service/profile CAP depends on:

Service / Profile Abbreviation Role in CAP Acceptor Required?
Common Audio Service CAS Identifies the device as a CAP Acceptor. No characteristics — presence of the service is the information. Yes (Mandatory)
Coordinated Set Identification Service CSIS Groups devices (e.g. left + right earbud) into a Coordinated Set. Included inside CAS when applicable. Conditional
Published Audio Capabilities Service PACS Exposes what audio codecs and configurations the device supports (e.g. LC3, 48 kHz, stereo). Yes (Mandatory)
Audio Stream Control Service ASCS Controls unicast audio streams — enables/disables ASEs (Audio Stream Endpoints) for CIS connections. Yes (for Unicast)
Broadcast Audio Scan Service BASS Used for broadcast audio — allows a device to instruct a scan delegator to scan for Broadcast Audio Streams. For Broadcast
Volume Control Profile VCP Provides standardised volume control. CAP Commander uses VCP to set volume on all Acceptors in a set simultaneously. Optional
Microphone Control Profile MICP Controls microphone mute state. CAP Commander can mute/unmute all mics in a Coordinated Set together. Optional

CAP Use Cases

🎵 Unicast Audio

A phone (Initiator) streams audio to earbuds (Acceptor) over a CIS (Connected Isochronous Stream). CAP orchestrates capability negotiation via PACS, then sets up the stream via ASCS. The audio data itself travels over the ISO channel — not GATT.

Example: Phone → TWS Earbuds (left + right, coordinated via CSIS)
📺 Broadcast Audio (Auracast)

A broadcaster (e.g. TV, PA system) transmits audio via BIS (Broadcast Isochronous Stream). Any device in range with the right keys can receive it — no pairing needed. CAP defines the scan and sync procedures using BASS.

Example: Airport PA → Multiple hearing aids / earbuds simultaneously
🎧 Coordinated Set Operations

When left and right earbuds are a Coordinated Set (both expose CSIS inside their CAS), the CAP Initiator or Commander treats them as a single logical unit. It can lock the set (prevent other devices from connecting while a stream is active), set the same volume on both, mute both mics at once, and synchronise stream start/stop. This is what makes true stereo TWS headsets possible in LE Audio.

Key detail: The Initiator discovers the Coordinated Set by reading CSIS characteristics found inside CAS on the first earbud, then connects to the second earbud whose SIRK (Set Identity Resolving Key) matches.

CAP vs Classic Bluetooth Audio Profiles

Feature Classic BT (A2DP + HFP) LE Audio with CAP
Audio codec SBC (mandatory), AAC/aptX optional LC3 (mandatory) — lower bitrate, better quality
Unified framework No — A2DP, HFP, AVRCP are separate Yes — CAP covers all audio scenarios
Coordinated earbuds Proprietary / not standardised Standardised via CSIS in CAP
Broadcast audio Not supported Native — Auracast via BASS + BIS
Transport BR/EDR (Classic Bluetooth) BLE + ISO channels
Hearing aid support Proprietary / ASHA (not universal) Native via HAP (built on CAP)
Discovery mechanism SDP-based, per-profile GATT-based, single CAS UUID discovery

BlueZ Support for CAP

Checking BlueZ LE Audio Readiness

BlueZ added LE Audio / CAP support starting from version 5.62 (experimental) and progressively stabilised it in 5.65+. The CAP Acceptor role (CAS service registration) is available in BlueZ 5.65 onward when using the --experimental flag.

# Check your BlueZ version
bluetoothd --version

# Start BlueZ with experimental features (required for LE Audio)
sudo bluetoothd --experimental

# Or edit /etc/bluetooth/main.conf and set:
# [Policy]
# Experimental = true

# Verify LE Audio feature flags via btmgmt
sudo btmgmt info
Scanning for CAP Acceptors in BlueZ

A CAP Initiator discovers Acceptors by scanning for devices that advertise the CAS service UUID (0x1853) in their advertisement or expose it as a Primary GATT Service after connection.

# In bluetoothctl, scan for LE devices
bluetoothctl
[bluetooth]# scan le
[NEW] Device AA:BB:CC:DD:EE:FF LE_Audio_Earbuds

# Connect to the device
[bluetooth]# connect AA:BB:CC:DD:EE:FF
[CHG] Device AA:BB:CC:DD:EE:FF Connected: yes

# Switch to GATT menu and list services
[bluetooth]# menu gatt
[bluetooth]# list-attributes AA:BB:CC:DD:EE:FF

# Look for Primary Service: UUID 0x1853 (Common Audio Service)
# If device is a Coordinated Set member, you will also see
# Included Service: UUID 0x1846 (Coordinated Set Identification Service)
CAP Profile Registration in BlueZ Source Code

In the BlueZ source tree, CAP is implemented in profiles/audio/cap.c. The profile triggers when the remote device exposes the CAS UUID. Below is the pattern used for profile registration:

/* profiles/audio/cap.c — CAP profile registration */

/* CAS UUID is used as the trigger for CAP discovery.
 * When BlueZ sees a remote device exposing CAS (0x1853),
 * it probes the CAP profile. */
#define CAS_UUID    "0000185300001000800000805f9b34fb"

static struct btd_profile cap_profile = {
    .name           = "cap",
    .priority       = BTD_PROFILE_PRIORITY_MEDIUM,

    /* CAP discovery is triggered by finding CAS on the remote device */
    .remote_uuid    = CAS_UUID,

    .device_probe   = cap_probe,    /* Called when CAS is found */
    .device_remove  = cap_remove,   /* Called on disconnect     */

    /* CAP accepts incoming connections from Initiators */
    .accept         = cap_accept,
};

static int cap_probe(struct btd_service *service)
{
    struct btd_device *device = btd_service_get_device(service);

    DBG("CAP Acceptor found: %s", device_get_path(device));

    /* Now read PACS to get audio capabilities,
     * and optionally ASCS to control streams */
    return cap_init(device);
}

/* Register the profile on plugin load */
static int cap_init_plugin(void)
{
    return btd_profile_register(&cap_profile);
}

static void cap_exit_plugin(void)
{
    btd_profile_unregister(&cap_profile);
}

Key Takeaways for This Section

CAP = LE Audio orchestrator
3 roles: Initiator, Acceptor, Commander
Acceptors must expose CAS (0x1853)
CAP uses PACS for codec negotiation
CAP uses ASCS for stream control
Coordinated Sets via CSIS inside CAS
Broadcast audio via BASS + BIS
LC3 codec replaces SBC
BlueZ 5.65+ for LE Audio support
Discovery = find CAS UUID 0x1853

Next: Common Audio Service (CAS) — Deep Dive

Now that you understand CAP and its role in LE Audio, the next article covers CAS (Common Audio Service) — the tiny but critical GATT service that every CAP Acceptor must expose. We look at its GATT structure, why it has no characteristics, and how BlueZ registers it.

Part 2: CAS Introduction →

Leave a Reply

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