| Supported Targets | ESP32-H4 | ESP32-S31 |
|---|
BLE CIS Central Example
(See the README.md file in the upper level examples directory for more information about examples.)
Overview
This is a raw BLE Connected Isochronous Stream (CIS) example operating directly at the ISO transport layer. It is not a BAP/CAP (BLE Audio profile) example — it does not implement Unicast Server/Client, ASCS, PACS, or any LC3 codec; it only exercises the underlying CIG/CIS plumbing.
The central scans for a peer advertising the name CIS Peripheral, opens an ACL link, optionally pairs (security level ESP_BLE_ISO_SECURITY_NO_MITM), creates a single-CIS CIG (10 ms SDU interval, 2M PHY, RTN 2, 120-byte SDU, sequential/unframed), connects the CIS, configures the input data path to the HCI in transparent format, and then drives a software TX scheduler that submits one SDU every 10 ms.
The transmitted payload is a dummy buffer filled with the current sequence number byte — there is no real audio data, the example just demonstrates the ISO transport mechanics on top of the NimBLE host with ISO support and the esp_ble_iso_* APIs.
Requirements
- A board with BLE 5.2 and ISO support (e.g. ESP32-H4, ESP32-S31)
- Peer device running the paired example
Configuration
idf.py menuconfig
No build-time options — runtime defaults are baked into source.
Security & Pairing
Just-Works pairing (LE Secure Connections, no MITM, BLE_SM_IO_CAP_NO_IO) with bonding enabled, inherited from the shared host init in ../common_components/example_init/ble_iso_example_init.c. ISO examples do not register any GATT services (gatts_register_cb = NULL).
Build & Flash
idf.py set-target esp32h4
idf.py -p PORT flash monitor
(Exit serial monitor with Ctrl-].)
Example Flow
- Initialize NVS, NimBLE host, and the ISO common layer with a GAP callback.
- Start passive extended scanning for a device whose Complete Local Name is
CIS Peripheral. - Cancel scan and create an ACL connection (interval 80 ms, supervision 5 s) once the target is matched.
- On ACL connect, initiate pairing because the configured security level is
ESP_BLE_ISO_SECURITY_NO_MITM. - After the security change, call
esp_ble_iso_cig_create(one CIS, 10 ms latencies and SDU interval, sequential/unframed, SCA unknown) andesp_ble_iso_chan_connectover the ACL handle. - On CIS connect, set up the input data path (HCI / transparent) and start the periodic TX scheduler.
- The scheduler invokes
esp_ble_iso_chan_sendevery 10 ms with an incrementing sequence number on a 120-byte dummy SDU.
Expected Log
TAG: CIS_CEN
Scan and connection phase:
I CIS_CEN: Scanning for peripheral...
I CIS_CEN: Connected: handle <h> role <r> peer XX:XX:XX:XX:XX:XX
I CIS_CEN: Security: handle <h> level <l> bonded <b>
CIS setup and streaming phase (TX log emitted every LOG_INTERVAL_PACKETS SDUs by the shared utility):
I CIS_CEN: [CIS #0] Connected
I CIS_CEN: [CIS #0] TX: <count> packets
Disconnect path:
I CIS_CEN: [CIS #0] Disconnected, reason 0x<rr>
I CIS_CEN: Disconnected: handle <h> reason 0x<rr>
Peer Pairing
Run cis_peripheral on a second board.
- Flash and run
cis_peripheralfirst; it begins extended advertising asCIS Peripheral. - Flash and run
cis_centralon the second board; it scans and matches that name. - The central creates the ACL connection and initiates pairing.
- After the security change, the central creates the CIG and connects the CIS.
- Both sides set up their data paths (input on central, output on peripheral).
- The central streams 120-byte SDUs every 10 ms; the peripheral reports
RX: <count> packetsperiodically.