BLE Audio course PACS — Exposing Context Types & Availability

BLE Audio course PACS — Exposing Context Types & Availability
Telling devices WHAT a stream is for — and WHETHER to accept it
12
Context Types
2-octet
Bitfield
PACS
Exposes Availability

In Classic Bluetooth, when a Central wants audio it just says “I want an audio connection” — no further detail. BLE Audio changes this completely. Context Types let devices describe what kind of audio they are sending or willing to receive, enabling smart stream management across complex multi-device scenarios.

1. Why Context Types Are Needed

Classic Audio vs BLE Audio — The Connection Dialog
Stream Setup Dialog Comparison
Classic Audio (A2DP / HFP)
📱 Phone: “I want an audio connection”
🎧 Headset: “OK, connecting…”
No context. Works OK for single-purpose profiles (A2DP = music, HFP = calls). Breaks when mixed use cases appear.
BLE Audio (BAP + Context Types)
📱 Phone: “I want a Conversational stream (incoming call)”
🎧 Hearing Aid: “Ringtone is currently UNAVAILABLE — I’m in a private meeting”
Stream request rejected silently before any Isochronous Stream is set up. User’s current audio is undisturbed.

2. All 12 Context Types (2-octet bitfield)

Each bit = one Context Type. Multiple can be set simultaneously.
Context Type Bitfield — Generic Audio Assigned Numbers
Bit Context Type Description & Use Case
0 Unspecified Catch-all for any use case not explicitly listed. Every Acceptor must support this. When set Available = Acceptor accepts anything not explicitly blocked. Gives phone full control (like A2DP/HFP).
1 Conversational Human-to-human conversation: cellular calls, VoIP, landline, PTT. Bidirectional stream expected (microphone + speaker).
2 Media Audio content — radio, TV, music playback. Typically one-way. Equivalent to A2DP’s content type.
3 Game Gaming audio — mix of effects, music, in-game voice. Low latency is critical. Often combined with Conversational for voice chat.
4 Instructional Satnav directions, announcements, user guidance. Often higher priority than other types — may interrupt music.
5 Voice Assistants Man-machine voice recognition (Alexa, Google Assistant, Siri). Bidirectional speech. Distinct from Instructional.
6 Live Live audio where Bluetooth stream and ambient sound are heard together (e.g., live concert, hearing aid pass-through). Strict low-latency requirement — Presentation Delay ≤ 20ms.
7 Sound Effects UI sounds: keyboard clicks, touch feedback, app-specific sounds.
8 Notifications Attention-seeking sounds: new message arrival, app alerts.
9 Ringtone Only for INBAND ringtones (custom ringtone audio streamed from phone). Out-of-band ringtones (locally generated in earbud) use CCP/TBS signalling — no audio stream needed.
10 Alerts Machine-generated event alerts: battery critical, doorbell, kitchen appliance complete, stopwatch alarm.
11 Emergency Alarm Highest priority. Smoke detector, fire alarm — cannot be blocked by other context settings.
12–15 RFU Reserved for future use.

⚠️ Ringtone vs Conversational — A Common Confusion:

Supporting Ringtone does NOT imply supporting Conversational. An extension bell for a deaf user only needs Ringtone to alert about an incoming call — no bidirectional voice stream required. Context Types are fully independent.

3. How Context Types Control Stream Setup

Stream Setup Flow with Context Type Check
Context Type Negotiation — Before Any Isochronous Stream Is Established
📱
Initiator
(Phone / Laptop)
1. ASCS Write on ACL link
“Stream type: Conversational (bit 1)”
→→→→→→→→→→→→
ACL (existing connection) — no ISO stream yet
←←←←←←←←←←←←
2a. REJECT: Context unavailable
— OR —
2b. ACCEPT: proceed to CIS setup
🦻
Acceptor
(Hearing Aid)
Available_Audio_Contexts
= Media | Conversational
(Ringtone = BLOCKED)
Key insight: The Context Type check happens over the existing ACL link before any Isochronous Stream is set up. This means it doesn’t disturb any currently playing audio — whether unicast or broadcast.

4. Availability — Where Context Types Are Exposed

Supported vs Available Audio Contexts
Two PACS Characteristics for Context Type Exposure
Characteristic (PACS) Meaning Changes?
Supported_Audio_Contexts All Context Types the device hardware can ever handle. Set at manufacture. Read-only. No — fixed
Available_Audio_Contexts Context Types currently accepting new streams RIGHT NOW. Can change dynamically. E.g., set Ringtone=unavailable during a private conversation. Yes — runtime

Context Types also appear in Streaming_Audio_Contexts LTV inside codec configuration metadata — this labels an active stream with its current use case and can be updated mid-stream (e.g., when satnav interrupts music, the stream context changes from Media → Instructional without tearing down the stream).

5. BlueZ: PACS — Exposing Context Types

BlueZ Media Endpoint Registration with Context Types (D-Bus / Python)

In BlueZ, the PACS (Published Audio Capabilities Service) is exposed through the org.bluez.Media1 interface. Context types are embedded in the PAC record metadata.

import dbus import dbus.service # Context Type bitmask values (from BT Generic Audio Assigned Numbers) CONTEXT_UNSPECIFIED = 0x0001 CONTEXT_CONVERSATIONAL= 0x0002 CONTEXT_MEDIA = 0x0004 CONTEXT_GAME = 0x0008 CONTEXT_INSTRUCTIONAL = 0x0010 CONTEXT_LIVE = 0x0040 CONTEXT_RINGTONE = 0x0200 # Supported = all context types this device can handle # Available = context types accepting streams RIGHT NOW supported_contexts = CONTEXT_CONVERSATIONAL | CONTEXT_MEDIA | CONTEXT_RINGTONE available_contexts = CONTEXT_CONVERSATIONAL | CONTEXT_MEDIA # Ringtone blocked # Register Media Endpoint (PACS Sink — Acceptor side) bus = dbus.SystemBus() manager = dbus.Interface( bus.get_object(“org.bluez”, “/org/bluez/hci0”), “org.bluez.Media1” ) # LC3 Codec Specific Capabilities LTV structure # Encodes: sampling freq, frame duration, octets-per-frame, audio location # Available_Audio_Contexts embedded here codec_caps = dbus.Array([ # Sampling Freq: 0x01 = 8kHz, 0x08 = 32kHz, 0x20 = 48kHz (bitmask) dbus.Byte(0x02), dbus.Byte(0x01), dbus.Byte(0x24), # 16kHz | 48kHz # Frame Duration: 0x02 = 7.5ms and 10ms supported dbus.Byte(0x02), dbus.Byte(0x02), dbus.Byte(0x02), # Audio Locations: Front Left (0x01) | Front Right (0x02) dbus.Byte(0x05), dbus.Byte(0x03), dbus.Byte(0x03), dbus.Byte(0x00), dbus.Byte(0x00), dbus.Byte(0x00), # Supported octets per codec frame: 40 min, 120 max dbus.Byte(0x05), dbus.Byte(0x04), dbus.Byte(0x28), dbus.Byte(0x00), dbus.Byte(0x78), dbus.Byte(0x00), ], signature=dbus.Signature(‘y’)) properties = { “UUID” : “00001850-0000-1000-8000-00805f9b34fb”, # PACS UUID “Codec” : dbus.Byte(0x06), # LC3 Codec ID “Capabilities”: codec_caps, “Metadata” : dbus.Array([ # Preferred Audio Contexts LTV: Type=0x02, Value = available_contexts dbus.Byte(0x03), dbus.Byte(0x02), dbus.Byte(available_contexts & 0xFF), dbus.Byte((available_contexts >> 8) & 0xFF), ], signature=dbus.Signature(‘y’)), } manager.RegisterEndpoint(“/org/embeddedpathashala/endpoint0”, properties) # To block Ringtone at runtime (e.g., user is in private meeting): available_contexts &= ~CONTEXT_RINGTONE # Update ASCS Available_Audio_Contexts characteristic via BlueZ GattCharacteristic1 # … notifies connected Initiators of the change
Key Takeaways
Context Types = 2-octet bitfield, 12 types defined
Acceptor can block any Context Type at runtime
Check happens on ACL before ISO stream — no audio disruption
Supported = static | Available = dynamic (changes in real time)
Ringtone ≠ Conversational — each Context Type is independent

Leave a Reply

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