What This Part Fixes
After a full section-by-section audit of all 148 pages, eight substantive topics were confirmed missing. The most critical is the Broadcast QoS table (Table 6.4) — broadcast uses completely different QoS parameters from unicast, including a Framing field and a 40 ms rendering deadline that does not exist in unicast. The others are equally practical: multi-server group constraints, Presentation_Delay from the source perspective, Broadcast Assistant GATT obligations, and several important LTV default rules that affect every implementation.
Key Terms
Gap 1 — Broadcast QoS Settings (Table 6.4) — The Biggest Miss
Part 2 covered unicast QoS thoroughly but broadcast QoS was never shown. They are not the same. Broadcast has three key differences:
Most broadcast streams are
unframed. But 44.1 kHz streams must be framed because their actual SDU interval (8.163 ms or 10.884 ms) does not match the standard 7.5 ms / 10 ms values the LL uses — so the controller needs framing to find packet boundaries.In broadcast, RTN values in Table 6.4 are recommendations to the controller. The controller may use different values to match desired robustness. The Host must still be capable of requesting the listed values.
A Broadcast Sink must be capable of rendering audio no later than 40 ms after the SDU Synchronization Reference. This 40 ms ceiling is the Presentation_Delay constraint for all broadcast sinks and explains why the Presentation_Delay column in Table 6.4 is always 40,000 µs.
Broadcast QoS Settings — Low Latency (_1) and High Reliability (_2)
Selected rows from Table 6.4. Only mandatory and most commonly used settings shown. The full table has 32 rows (16 codec settings × 2 QoS sets).
| Set Name | Codec | SDU Interval (µs) | Framing | Max SDU (octets) | RTN (rec.) | Max Transport Latency (ms) | Presentation Delay (µs) | Requirement (Source / Sink) |
|---|---|---|---|---|---|---|---|---|
| 16_2_1 | 16_2 | 10,000 | unframed | 40 | 2 | 10 | 40,000 | M / M |
| 16_2_2 | 16_2 | 10,000 | unframed | 40 | 4 | 60 | 40,000 | M / M |
| 24_2_1 | 24_2 | 10,000 | unframed | 60 | 2 | 10 | 40,000 | C.2 / M |
| 24_2_2 | 24_2 | 10,000 | unframed | 60 | 4 | 60 | 40,000 | C.2 / M |
| 48_2_1 | 48_2 | 10,000 | unframed | 100 | 4 | 20 | 40,000 | O / O |
| 48_2_2 | 48_2 | 10,000 | unframed | 100 | 4 | 65 | 40,000 | O / O |
| 441_1_1 | 441_1 | 8,163 µs eff. | framed | 97 | 4 | 24 | 40,000 | O / O |
| 441_2_2 | 441_2 | 10,884 µs eff. | framed | 130 | 4 | 60 | 40,000 | O / O |
| Parameter | Unicast 16_2_2 | Broadcast 16_2_2 | Why Different |
|---|---|---|---|
| Max_Transport_Latency | 95 ms | 60 ms | Broadcast has a 40 ms render deadline constraint, leaving less headroom |
| RTN | 13 (hard requirement) | 4 (recommendation) | Broadcast controller decides actual retransmit count based on BIG constraints |
| Framing | Not a parameter (unframed implied) | Explicit field: unframed or framed | 44.1 kHz requires framed because SDU interval doesn’t match standard LL slot boundaries |
| Presentation_Delay | Negotiated per CIG (server exposes range) | Fixed at 40,000 µs for all sinks | No per-sink negotiation possible in connectionless broadcast |
LL Parameter Recommendations for Broadcast (Table 6.5)
For 48_2_2 (the most common high-quality broadcast config), the spec provides three recommended LL-level parameter sets depending on the optimization target:
| Optimized For | ISO_Interval | BN | NSE | IRC | PTO | Num_BIS | Actual RTN |
|---|---|---|---|---|---|---|---|
| Wi-Fi coexistence + 7.5ms schedules | 30 ms | 3 | 9 | 2 | 1 | 1 or 2 | 2 |
| Maximum link reliability | 10 ms | 1 | 5 | 1 | 1 | 1 or 2 | 4 |
| Balanced (reliability + coexistence) | 20 ms | 2 | 8 | 2 | 1 | 1 or 2 | 3 |
BN = Burst Number (packets per interval), NSE = Number of Sub-Events, IRC = Immediate Repetition Count, PTO = Pre-Transmission Offset. These are controller parameters that the Host sets via HCI LE Create BIG. Increasing NSE or IRC improves reliability at the cost of more airtime.Gap 2 — Presentation_Delay: Sink vs Source Perspectives
Presentation_Delay means different things depending on whether the server is an Audio Sink (receiving audio) or an Audio Source (sending audio). This is section 7.1.1 vs 7.1.2.
| SDU Sync Reference |
→ Presentation_Delay → |
Speaker output |
The time between when the controller signals the SDU reference point and when the audio physically comes out of the speaker. The Sink must buffer the decoded audio for this duration to allow synchronized playback across multiple devices.
| Microphone capture starts |
→ Presentation_Delay → |
SDU Sync Reference |
The time between when the microphone starts acquiring a frame of audio and when the SDU sync reference occurs for that frame. The Source uses this to align its capture timestamp with the reference clock of the CIS.
Gap 3 — Multi-Server Group Rules (Sections 7.1.3 and 7.2.1)
When a Unicast Client manages a CIG that spans two Unicast Servers (e.g. left and right earbuds), it must select a single Presentation_Delay and a single Max_Transport_Latency value for the whole group. The rules are symmetric in structure but opposite in direction:
| Lower bound | ≥ greatest Presentation_Delay_Min across all servers |
| Upper bound | ≤ lowest Presentation_Delay_Max across all servers |
| Rule | Must not exceed the lowest Max_Transport_Latency exposed by any server in the group |
| Device | Presentation_Delay_Min | Presentation_Delay_Max | Max_Transport_Latency (exposed) |
| Left earbud | 20,000 µs | 60,000 µs | 10 ms |
| Right earbud | 30,000 µs | 50,000 µs | 20 ms |
| Client must choose | ≥ 30,000 µs | ≤ 50,000 µs | ≤ 10 ms |
Valid choice: Presentation_Delay = 40,000 µs (fits both), Max_Transport_Latency = 10 ms (capped by left earbud).
Gap 4 — Broadcast Assistant GATT Requirements (Section 3.10)
Part 3 described what a Broadcast Assistant does but never showed its GATT-level obligations. These are distinct from the Unicast Client’s GATT requirements:
Same as all other BAP roles. Must exchange MTU immediately after connecting to the Scan Delegator.
The Broadcast Assistant must discover the BASS Control Point characteristic on the Scan Delegator. This is how it writes Add/Modify/Remove Source and Set Broadcast_Code operations.
The Broadcast Assistant must discover all instances of the Broadcast Receive State characteristic and subscribe to notifications on every one. This is how it tracks which broadcast streams the Scan Delegator is synchronized to.
The Broadcast Assistant may optionally discover the Scan Delegator’s PACS (Sink PAC, Sink Audio Locations) to understand its audio capabilities before selecting a broadcast source on its behalf.
| GATT Sub-Procedure | Requirement (Table 3.20) |
|---|---|
| Exchange MTU | Mandatory |
| Discover All Primary Services | C.1 (one of) |
| Discover Primary Services by UUID | C.1 (one of) |
| Discover All Characteristics of a Service | C.2 (one of) |
| Discover All Characteristic Descriptors | Mandatory |
| Read Characteristic Value | Mandatory |
| Write Characteristic Value | Mandatory |
| Notifications | Mandatory |
| Write Characteristic Descriptors | Mandatory |
Gap 5 — Scan Delegator Solicitation AD Format (Table 3.19)
When a Broadcast Sink with a co-located Scan Delegator wants to attract a Broadcast Assistant, it transmits Extended Advertising PDUs with a specific Service Data AD structure. This is simpler than the Unicast Server announcement (Table 3.7) — it carries no extra data beyond the BASS Service UUID itself.
| Field | Size | Value / Description |
|---|---|---|
| Length | 0x01 | Length of Type + Value |
| Type | 0x01 | «Service Data – 16-bit UUID» |
| BASS Service UUID | 2 bytes | 0x184F — that’s it. No Announcement Type, no Available Contexts, no Metadata. |
Gap 6 — Broadcast Source Address Rules (Section 6.1.3)
When a Broadcast Sink or Broadcast Assistant re-synchronizes to a Broadcast Source after losing the PA sync, it uses the advertising address (AdvA) to find the right advertising set. If the AdvA changes during the BIG lifetime, the Sink must re-scan from scratch, causing audio dropouts. The spec gives three explicit rules:
Gap 7 — LTV Absence Defaults — Four Rules That Must Be Known
When certain optional LTV structures are absent from a PAC record or Config Codec, the spec defines a default interpretation. These four rules are critical for parsing capabilities and configurations correctly:
| LTV Structure | Where It Appears | If Absent, Interpret As |
|---|---|---|
| Supported_Audio_Channel_Counts | Codec_Specific_Capabilities (PAC record) | 0x01 — supports exactly 1 audio channel. No multiplexing possible. |
| Supported_Max_Codec_Frames_Per_SDU | Codec_Specific_Capabilities (PAC record) | 0x01 — max 1 codec frame per audio channel per SDU. |
| Audio_Channel_Allocation | Codec_Specific_Configuration (Config Codec / BASE) | Single channel, no specified Audio Location. Not assigned to FL, FR, or any named position. |
| Codec_Frame_Blocks_Per_SDU | Codec_Specific_Configuration (Config Codec / BASE) | 0x01 — one block of codec frames per SDU. Standard single-period per packet. |
| Streaming_Audio_Contexts | Metadata (Enable / Update Metadata / BASE config) | Equivalent to Streaming_Audio_Contexts = Unspecified (bit 1 set, all others 0). |
/* Parsing PAC record Codec_Specific_Capabilities with LTV absence defaults */ typedef struct { uint16_t supported_sampling_freqs; /* bitmask, MUST be present */ uint8_t supported_frame_durations; /* bitmask, MUST be present */ uint8_t supported_channel_counts; /* default = 0x01 if LTV absent */ uint16_t octets_per_frame_min; /* MUST be present */ uint16_t octets_per_frame_max; /* MUST be present */ uint8_t max_frames_per_sdu; /* default = 0x01 if LTV absent */ } pac_capabilities_t; void parse_codec_specific_capabilities(const uint8_t *ltv, uint8_t len, pac_capabilities_t *out) { /* Set mandatory defaults for optional LTVs */ out->supported_channel_counts = 0x01; /* Section 4.3.1: absent = 1 channel */ out->max_frames_per_sdu = 0x01; /* Section 4.3.1: absent = 1 frame */ uint8_t i = 0; while (i < len) { uint8_t ltv_len = ltv[i]; uint8_t ltv_type = ltv[i + 1]; const uint8_t *v = <v[i + 2]; switch (ltv_type) { case 0x01: /* Supported_Sampling_Frequencies */ out->supported_sampling_freqs = v[0] | (v[1] << 8); break; case 0x02: /* Supported_Frame_Durations */ out->supported_frame_durations = v[0]; break; case 0x03: /* Supported_Audio_Channel_Counts — optional, default 0x01 */ out->supported_channel_counts = v[0]; break; case 0x04: /* Supported_Octets_Per_Codec_Frame */ out->octets_per_frame_min = v[0] | (v[1] << 8); out->octets_per_frame_max = v[2] | (v[3] << 8); break; case 0x05: /* Supported_Max_Codec_Frames_Per_SDU — optional, default 0x01 */ out->max_frames_per_sdu = v[0]; break; } i += (1 + ltv_len); /* advance: 1 byte for Length field + ltv_len bytes */ } }
Gap 8 — BASE Complete Byte Example (Table 3.16 — TV with 4 BIS)
The spec provides a complete worked byte example of the BASE structure for a TV broadcasting two languages (Spanish, English) each in stereo (FL + FR) = 4 BIS total in one BIG. This is the most concrete reference in the entire spec and was never shown in the tutorial.
| Level | Parameter | Size (bytes) | Value |
|---|---|---|---|
| AD | Total AD Length | 1 | 0x5D = 93 octets follow |
| AD | AD Type | 1 | 0x16 = Service Data 16-bit UUID |
| AD | Basic Audio Announcement Service UUID | 2 | 0x1853 |
| L1 | Presentation_Delay | 3 | 40 ms (0x009C40) |
| L1 | Num_Subgroups | 1 | 0x02 (2 subgroups) |
| L2[0] | Num_BIS[0] | 1 | 0x02 (2 BIS in subgroup 0) |
| L2[0] | Codec_ID[0] | 5 | 0x06 0x00 0x00 0x00 0x00 (LC3, standard) |
| L2[0] | Codec_Specific_Configuration_Length[0] | 1 | 0x0A (10 bytes) |
| L2[0] | Codec_Specific_Configuration[0] | 10 | LTV 1: Sampling_Freq = 48 kHz | LTV 2: Frame_Duration = 10 ms | LTV 3: Octets_Per_Frame = 100 |
| L2[0] | Metadata_Length[0] | 1 | 0x09 (9 bytes) |
| L2[0] | Metadata[0] | 9 | LTV 1: Streaming_Audio_Contexts = Media | LTV 2: Language = Spanish |
| L3[0][0] | BIS_index[0][0] | 1 | 0x01 |
| L3[0][0] | Codec_Specific_Configuration_Length[0][0] | 1 | 0x06 |
| L3[0][0] | Codec_Specific_Configuration[0][0] | 6 | Audio_Channel_Allocation = Front Left |
| L3[0][1] | BIS_index[0][1] | 1 | 0x02 |
| L3[0][1] | Codec_Specific_Configuration[0][1] | 6 | Audio_Channel_Allocation = Front Right |
| L2[1] | Num_BIS[1] | 1 | 0x02 (2 BIS in subgroup 1) |
| L2[1] | Codec_ID[1] + Codec_Specific_Configuration[1] | 17 | Same codec settings as Subgroup[0]: 48 kHz, 10 ms, 100 octets/frame |
| L2[1] | Metadata[1] | 9 | LTV 1: Streaming_Audio_Contexts = Media | LTV 2: Language = English |
| L3[1][0] | BIS_index[1][0] | 1 | 0x03 → Audio_Channel_Allocation = Front Left |
| L3[1][1] | BIS_index[1][1] | 1 | 0x04 → Audio_Channel_Allocation = Front Right |
A Broadcast Sink that wants Spanish audio subscribes to BIS indices 0x01 (FL) and 0x02 (FR) from Subgroup[0]. A mono device wanting English can subscribe only to BIS index 0x03. Because the codec parameters (48 kHz, 10 ms, 100 octets/frame) are defined at Level 2 and inherited by all BISes in that subgroup, the Level 3 entries only need to carry the Audio_Channel_Allocation — everything else comes from Level 2.
Complete 6-Part Series — Final Coverage Summary
| Part | Title | Spec Sections |
|---|---|---|
| Part 1 | Architecture, Roles, CIS vs BIS, Role-Service mapping | Ch1 terminology, 2.1–2.6, 3.1–3.3 |
| Part 2 | LC3 codec, LTV format, Codec settings, Unicast QoS, Presentation_Delay, stereo | 4.1–4.3, unicast QoS tables, 7.1–7.2 overview |
| Part 3 | ASE state machine, unicast stream setup steps, broadcast state machine, BASE, Broadcast Assistant/Sink flow | 5.1–5.6, 6.1–6.6 |
| Part 4 | All 14 audio configurations, GAP parameters, Security requirements | 4.4–4.5, Ch8, Ch9 |
| Part 5 | Context Types, Targeted/General Announcements, PAC Record structure, LL feature table, ASE count rules, ATT_MTU + GATT sub-procedures | 3.4–3.6, 3.5.2.1, 3.5.3, Table 3.7–3.10 |
| Part 6 | Broadcast QoS (Table 6.4), LL BIG parameters, Presentation_Delay Sink vs Source, Multi-server group rules, Broadcast Assistant GATT, Scan Delegator AD, Address rules, LTV defaults, BASE byte example | Table 6.4–6.5, 7.1.1–7.2.1, 3.9.2, 3.10, 6.1.3, 4.3.1–4.3.3 |
BAP Tutorial Series — Complete
6 parts, 148 pages fully mapped. Next logical step: PACS (the Published Audio Capabilities Service spec) and ASCS (the Audio Stream Control Service spec) — the two GATT services that BAP depends on most heavily.
