All of lore.kernel.org
 help / color / mirror / Atom feed
From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH BlueZ v1 10/12] test: functional: add BAP broadcast tests
Date: Wed,  9 Sep 2026 15:23:06 -0400	[thread overview]
Message-ID: <20260909192308.1306567-11-luiz.dentz@gmail.com> (raw)
In-Reply-To: <20260909192308.1306567-1-luiz.dentz@gmail.com>

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Add tests covering BAP broadcast via bluetoothctl: the Broadcast
Source registers a BCAA endpoint, configures it and starts the
broadcast, while the Broadcast Sink registers a BAA endpoint and scans,
syncing to the periodic advertising on its own, without a Broadcast
Assistant. Run them for a plain broadcast and for a Public Broadcast
Profile one.

test_bap_broadcast_transport_created checks a MediaTransport1 object is
created for each BIS of the BASE, and test_bap_broadcast_transport_acquire
checks selecting the transport with the broadcast code moves it to
broadcasting and acquiring it succeeds.

Assisted-by: opencode:claude-opus-5
---
 doc/functional-bap.rst      | 121 +++++++++++++++++++++++++++++++-----
 test/functional/test_bap.py |  68 ++++++++++++++++++++
 2 files changed, 172 insertions(+), 17 deletions(-)

diff --git a/doc/functional-bap.rst b/doc/functional-bap.rst
index 6b67df541e97..99a3d63eef68 100644
--- a/doc/functional-bap.rst
+++ b/doc/functional-bap.rst
@@ -13,6 +13,23 @@ suite.
 SETUP
 =====
 
+BAP requires the ISO socket support, so all hosts run `bluetoothd`
+with:
+
+.. code-block::
+
+	[General]
+	Experimental = true
+	KernelExperimental = true
+	ControllerMode = le
+
+`bluetoothctl` is started with ``-a auto``, so pairing and service
+authorization are accepted without prompting, and with an endpoint
+registration script from `client/scripts`.
+
+UNICAST
+=======
+
 Two hosts, connected over LE:
 
 .. code-block::
@@ -31,20 +48,6 @@ Two hosts, connected over LE:
 
 	--> connection is initiated by      ==> audio flows towards
 
-BAP requires the ISO socket support, so all hosts run `bluetoothd`
-with:
-
-.. code-block::
-
-	[General]
-	Experimental = true
-	KernelExperimental = true
-	ControllerMode = le
-
-`bluetoothctl` is started with ``-a auto``, so pairing and service
-authorization are accepted without prompting, and with an endpoint
-registration script:
-
 ``client/scripts/bap-source-lc3.bt`` on host0
 	Registers a local PAC Source endpoint
 	(``00002bcb-0000-1000-8000-00805f9b34fb``) with LC3. host0 is the
@@ -55,9 +58,6 @@ registration script:
 	(``00002bc9-0000-1000-8000-00805f9b34fb``) with LC3. host1 is the
 	acceptor, i.e. the device receiving audio.
 
-TEST CASES
-==========
-
 test_bap_unicast_transport_created
 ----------------------------------
 
@@ -107,3 +107,90 @@ test_bap_unicast_transport_acquire
 	The acceptor does not have to acquire its transports for the CIS to
 	be established, as `bluetoothd` sets up the ISO listener on its own
 	when the stream is enabled.
+
+BROADCAST
+=========
+
+Two hosts, with no connection between them:
+
+.. code-block::
+
+	+------------------------+                 +------------------------+
+	| host0                  |    extended +   | host1                  |
+	| Broadcast Source       |    periodic     | Broadcast Sink         |
+	| bluetoothctl -a auto   |   advertising   | bluetoothctl -a auto   |
+	| broadcast-source.bt    | --------------> | broadcast-sink.bt      |
+	| or -pbp variant        |                 |                        |
+	| BCAA endpoint (0x1852) |   BIS 0 (LC3)   | BAA endpoint (0x1851)  |
+	|                        | ==============> |                        |
+	+------------------------+                 +------------------------+
+
+	no ACL is established: the sink syncs to the periodic advertising,
+	reads the BASE from it and then syncs to the BIG
+
+	--> advertising is scanned by       ==> audio flows towards
+
+``client/scripts/broadcast-source.bt`` on host0
+	Registers a Broadcast Source endpoint
+	(``00001852-0000-1000-8000-00805f9b34fb``) with LC3, configures it
+	with the 16_2_1 preset and acquires the transport, which starts
+	the broadcast. The stream is encrypted with the broadcast code
+	`bluetoothctl` uses by default.
+
+``client/scripts/broadcast-source-pbp.bt`` on host0
+	As above, but adds the Public Broadcast Announcement service
+	(``0x1856``) to the extended advertising first, so the broadcast
+	is a Public Broadcast Profile one.
+
+``client/scripts/broadcast-sink.bt`` on host1
+	Registers a Broadcast Sink endpoint
+	(``00001851-0000-1000-8000-00805f9b34fb``) with LC3 and scans.
+
+Both test cases run for each source, i.e. with the ``lc3`` parameter
+for a plain broadcast and with ``pbp`` for a Public Broadcast Profile
+one.
+
+test_bap_broadcast_transport_created[lc3|pbp]
+---------------------------------------------
+
+:Setup: As above.
+
+:Steps:
+	1. Start `bluetoothctl` with the source script on host0.
+	2. Start `bluetoothctl` with the sink script on host1.
+	3. Sink: ``transport.show <transport>``.
+
+:Expected:
+	1. ``Endpoint /local/endpoint/ep0 registered``, then
+	   ``Acquire successful: fd <fd> MTU <read>:<write>`` on the
+	   source, i.e. it is broadcasting.
+	2. The sink syncs to the periodic advertising on its own and
+	   creates a transport per BIS described by the BASE, under
+	   ``/org/bluez/hci0/dev_XX/sidN/bisM/fdK``.
+	3. The transport reports ``Codec: 0x06`` for LC3 and
+	   ``State: idle``.
+
+:Notes: The sink does not need a Broadcast Assistant here: it scans,
+	finds the Broadcast Source and syncs by itself.
+
+test_bap_broadcast_transport_acquire[lc3|pbp]
+---------------------------------------------
+
+:Setup: As above, with the transport already created.
+
+:Steps:
+	1. Sink: ``transport.select <transport>``.
+	2. Answer ``Enter bcode[value/no]:`` with the broadcast code the
+	   source used.
+
+:Expected:
+	1. The transport moves to ``State: broadcasting``, i.e. the sink
+	   synced to the BIG.
+	2. ``Acquire successful: fd <fd> MTU <read>:<write>`` and the
+	   transport moves to ``State: active``.
+
+:Notes: Selecting the transport is what moves it out of idle, and
+	`bluetoothctl` starts acquiring it right after, so the test does
+	not issue ``transport.acquire`` itself. The broadcast code has to
+	match the one the source encrypted the BIG with, otherwise the
+	sink cannot decrypt the stream.
diff --git a/test/functional/test_bap.py b/test/functional/test_bap.py
index 69430d7a6699..6b62338ac676 100644
--- a/test/functional/test_bap.py
+++ b/test/functional/test_bap.py
@@ -167,3 +167,71 @@ def test_bap_unicast_transport_acquire(unicast_hosts):
             f"Transport {right} State: active",
         ],
     )
+
+
+# Broadcast code used by the broadcast scripts, see BCAST_CODE in
+# client/player.c
+BCAST_CODE = (
+    "0x01 0x02 0x68 0x05 0x53 0xf1 0x41 0x5a " "0xa2 0x65 0xbb 0xaf 0xc6 0xea 0x03 0xb8"
+)
+
+BCAST_SOURCES = ["broadcast-source.bt", "broadcast-source-pbp.bt"]
+BCAST_IDS = ["lc3", "pbp"]
+
+broadcast_host_config = host_config(
+    [Bluetoothd(conf=BAP_CONF), Pexpect()],
+    [Bluetoothd(conf=BAP_CONF), Pexpect()],
+)
+
+
+def start_broadcast(hosts, source_script):
+    """
+    Source broadcasting with the given script, and sink scanning for it.
+    """
+    source_host, sink_host = hosts
+
+    source = start_bluetoothctl(source_host, source_script)
+    source.expect(r"Acquire successful: fd \d+ MTU \d+:\d+")
+
+    sink = start_bluetoothctl(sink_host, "broadcast-sink.bt")
+
+    return source, sink
+
+
+@broadcast_host_config
+@pytest.mark.parametrize("source_script", BCAST_SOURCES, ids=BCAST_IDS)
+def test_bap_broadcast_transport_created(hosts, source_script):
+    source, sink = start_broadcast(hosts, source_script)
+
+    # Sink syncs to the periodic advertising and creates a transport
+    # for each BIS described by the BASE
+    _, m = sink.expect(TRANSPORT_RE)
+    transport = m[0].decode("utf-8")
+
+    sink.send(f"transport.show {transport}\n")
+    sink.expect(f"Transport {transport}")
+    sink.expect(r"Codec: 0x06")
+    sink.expect("State: idle")
+
+
+@broadcast_host_config
+@pytest.mark.parametrize("source_script", BCAST_SOURCES, ids=BCAST_IDS)
+def test_bap_broadcast_transport_acquire(hosts, source_script):
+    source, sink = start_broadcast(hosts, source_script)
+
+    _, m = sink.expect(TRANSPORT_RE)
+    transport = m[0].decode("utf-8")
+
+    # Selecting the transport syncs to the BIG and starts acquiring it
+    sink.send(f"transport.select {transport}\n")
+    sink.expect(r"Enter bcode\[value/no\]:")
+    sink.send(f"{BCAST_CODE}\n")
+
+    expect_all(
+        sink,
+        [
+            f"Transport {transport} State: broadcasting",
+            r"Acquire successful: fd \d+ MTU \d+:\d+",
+            f"Transport {transport} State: active",
+        ],
+    )
-- 
2.55.0


  parent reply	other threads:[~2026-09-09 19:23 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-09 19:22 [PATCH BlueZ v1 00/12] Add functional tests for A2DP and BAP Luiz Augusto von Dentz
2026-09-09 19:22 ` [PATCH BlueZ v1 01/12] build: add doc/test-functional.rst to EXTRA_DIST Luiz Augusto von Dentz
2026-09-10 18:28   ` Add functional tests for A2DP and BAP bluez.test.bot
2026-09-09 19:22 ` [PATCH BlueZ v1 02/12] doc: describe the functional test cases Luiz Augusto von Dentz
2026-09-09 19:22 ` [PATCH BlueZ v1 03/12] client: do not prompt for LE Audio settings on A2DP endpoints Luiz Augusto von Dentz
2026-09-09 19:23 ` [PATCH BlueZ v1 04/12] client: add A2DP endpoint registration scripts Luiz Augusto von Dentz
2026-09-09 19:23 ` [PATCH BlueZ v1 05/12] test: functional: add A2DP tests Luiz Augusto von Dentz
2026-09-09 19:23 ` [PATCH BlueZ v1 06/12] client: rename media endpoint scripts to include the codec Luiz Augusto von Dentz
2026-09-09 19:23 ` [PATCH BlueZ v1 07/12] client: add BAP endpoint registration scripts Luiz Augusto von Dentz
2026-09-09 19:23 ` [PATCH BlueZ v1 08/12] doc: bluetoothctl: document init script option and scripts Luiz Augusto von Dentz
2026-09-09 19:23 ` [PATCH BlueZ v1 09/12] test: functional: add BAP unicast tests Luiz Augusto von Dentz
2026-09-09 19:23 ` Luiz Augusto von Dentz [this message]
2026-09-09 19:23 ` [PATCH BlueZ v1 11/12] test: functional: add BAP broadcast assistant test Luiz Augusto von Dentz
2026-09-09 19:23 ` [PATCH BlueZ v1 12/12] bap: reuse the PA sync established to discover a Broadcast Source Luiz Augusto von Dentz
2026-09-10 20:50 ` [PATCH BlueZ v1 00/12] Add functional tests for A2DP and BAP patchwork-bot+bluetooth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260909192308.1306567-11-luiz.dentz@gmail.com \
    --to=luiz.dentz@gmail.com \
    --cc=linux-bluetooth@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.