LE Audio BASS Explained: How Broadcast Audio Scan Service Enables Low-Power Broadcast Receivers

BASS is the core GATT service for LE Audio broadcast receivers. It standardizes broadcast source discovery, synchronization control, and key management. It addresses the high power cost of continuous scanning on devices such as earbuds and hearing aids, while also solving the problem of fragmented and difficult-to-maintain state. Keywords: LE Audio, BASS, low-power broadcasting.

The technical specification snapshot defines the core profile surface

Parameter Description
Technical Domain Bluetooth LE Audio
Service Name BASS (Broadcast Audio Scan Service)
Layer GATT Primary Service
Core Protocols ATT / GATT / LE Isochronous / Periodic Advertising
UUID Type Bluetooth SIG 16-bit UUID
Typical Devices Hearing aids, TWS earbuds, Bluetooth speakers
Star Count Not provided in the source
Core Dependencies BAP, PA, PAST, BASE, Broadcast_Code

The BASS service declaration requires it to be unique and identifiable

BASS is not just another collection of characteristics. It is the standard entry point for the broadcast audio receiver control plane. Once a receiver supports delegated broadcast audio scanning, it must expose that capability in a consistent way. Otherwise, clients cannot discover or control it reliably.

Its first constraint is single instantiation. A device can expose only one BASS service because the broadcast source list, synchronization state, broadcast code, and remote scan state are all global resources. If multiple instances existed, clients would face conflicting state, and the server would have to maintain duplicate scanning contexts.

The single-instance constraint is fundamentally a state consistency design

A single instance means the client never has to choose between multiple control planes. For earbuds or hearing aids, this effectively creates one centralized broadcast reception controller, which avoids implementation ambiguity such as adding the same broadcast source multiple times or synchronizing the same BIS from different control paths.

// Pseudocode: register only one BASS service during device initialization
int bass_service_init(void) {
    if (g_bass_registered) {
        return -1; // Prevent duplicate registration and enforce global uniqueness
    }
    gatt_register_primary_service(BASS_UUID_16);
    g_bass_registered = 1; // Mark BASS as created
    return 0;
}

This code snippet shows a typical firmware implementation of the BASS single-instance constraint.

BASS is defined as a primary service to reduce interoperability complexity

BASS must be declared as a Primary Service, not a Secondary Service. The reason is simple: it provides an independent control function and can be discovered and accessed without depending on any other audio service.

This allows clients such as phones and watches to locate broadcast receiver control capabilities directly while traversing the GATT service table, without resolving additional dependencies first. In multi-vendor ecosystems, that is critical for reducing integration cost.

A standard UUID is the minimum requirement for cross-vendor identification

BASS uses a standard 16-bit UUID assigned by the Bluetooth SIG. The value of a unified UUID is not just naming consistency. It makes the discovery flow predictable. As soon as the client recognizes that UUID, it knows the target device supports delegated broadcast audio scanning and broadcast receive state reporting.

AI Visual Insight: This diagram summarizes the three service declaration constraints of BASS in a structured way: single instance, primary service, and standard UUID. Technically, it reflects the modeling boundaries of GATT services and helps developers quickly determine whether an implementation satisfies the most basic interoperability requirements.

The BASS behavior model centers on low power and unified state

The BASS design goal is explicit: reduce scanning work on battery-constrained receivers by shifting power-hungry tasks to clients with stronger battery capacity, while mapping the broadcast reception process into standardized characteristics.

In the traditional model, earbuds scan for broadcast sources themselves, parse advertisements, synchronize to PA, and then start BIS reception, which keeps power consumption consistently high. BASS changes this to a delegated model where the server accepts commands and the client scans on its behalf. As a result, the receiver can disable local scanning in many scenarios.

The server and client split responsibilities clearly

The server typically runs on devices such as earbuds and hearing aids. It stores broadcast sources, manages PA/BIS synchronization, receives the Broadcast_Code, and reports results through state characteristics. The client is usually a phone or watch that scans nearby broadcast sources and sends key information back to the server.

class BassWorkflow:
    def remote_scan_started(self):
        self.local_scan_enabled = False  # Disable local scanning to save power after the client takes over scanning

    def add_source(self, addr, broadcast_id, base):
        self.source = {
            "addr": addr,
            "broadcast_id": broadcast_id,
            "base": base  # Store the broadcast source configuration for later PA/BIS synchronization
        }
        self.sync_pa_and_bis()

This pseudocode captures the core low-power collaboration path in BASS.

Two core characteristics form the closed-loop BASS control plane

BASS mainly relies on two cooperating characteristics: Broadcast Audio Scan Control Point and Broadcast Receive State. The former handles command writes, while the latter exposes state.

The Control Point is the only control entry. The client uses it to send operations such as Remote Scan Started, Add Source, Modify Source, Remove Source, and Set Broadcast_Code. In practice, implementations often require writes over an encrypted connection to reduce the risk of command tampering.

Broadcast Receive State provides the state window

Receive State is the server’s external projection of actual status. It typically includes Source_ID, the broadcast address, PA synchronization state, the BIS synchronization bitmap, and encryption status. A server can expose multiple instances of this characteristic to represent multiple broadcast sources.

Opcode Flow:
Client -> Control Point : Add Source
Server -> Sync Engine   : start PA/BIS sync
Server -> Receive State : notify synced / need code / failed

This flow illustrates the BASS command-execution-feedback loop.

Array field ordering rules directly affect protocol compatibility

The BASS specification imposes strict ordering requirements on array parameters. If ParameterA[i] and ParameterB[i] both exist, the transmission order must be A0, B0, A1, B1 rather than sending all A values first and all B values afterward.

This rule is especially important for fields such as Metadata_Length[i] and Metadata[i]. If the parser assumes the wrong order, it can immediately cause length misalignment, out-of-bounds parsing, and broadcast source configuration failures. This is a frequent issue in cross-vendor interoperability testing.

Related concepts determine whether the implementation is complete

Broadcast_Code is a 16-byte symmetric key used to decrypt encrypted BIS streams. BASE describes the broadcast audio configuration, including subgroup and BIS information. PA is the synchronization entry point for reception, while PAST allows the client to transfer PA synchronization context to the server.

These are not peripheral concepts. They are required pieces of the BASS control chain. Without BASE, the server cannot determine which BIS streams to synchronize. Without Broadcast_Code, it cannot decrypt protected audio streams.

AI Visual Insight: This image functions more like a channel branding or referral graphic than a protocol structure diagram. As a result, its visual information mainly indicates content branding and source attribution rather than any specific BASS data-plane or control-plane detail.

Developers can understand BASS through one implementation path

Start by exposing a single Primary BASS service. Then implement Control Point write handling and Receive State notifications. Next, add delegated remote scanning, BASE parsing, PA/PAST integration, and Broadcast_Code management. Finally, validate array parameter ordering and multi-source state synchronization.

If you think of BASS as a broadcast reception control bus, most specification constraints become intuitive: a single instance ensures one authoritative state source, a primary service enables fast discovery, a standard UUID enables interoperability, and the two-characteristic model separates control from observation.

FAQ provides structured answers to common implementation questions

Why can BASS have only one instance?

Because it manages global broadcast reception state, including scan delegation, synchronization status, and key information. Multiple instances would introduce state conflicts, duplicate synchronization, and client-side ambiguity in control selection.

Why must BASS be a Primary Service?

Because clients need to discover and access it directly as an independent service. If it were exposed only as an auxiliary service, it would increase discovery path length and implementation complexity, making cross-vendor interoperability harder.

How do Control Point and Receive State work together?

The client first writes commands to the Control Point. The server then performs actions such as adding a source, synchronizing, or setting a key, and finally notifies the result through Receive State, such as synchronization success, failure, or a request for a key. That creates a complete closed loop.

Core Summary: This article systematically reconstructs the service declaration rules, role collaboration model, and core characteristics of BASS (Broadcast Audio Scan Service) in LE Audio. It explains why BASS must be a single instance, why it is defined as a primary service, and how delegated remote scanning reduces receiver power consumption while unifying broadcast reception state.