Skip to content

Commit 49a052a

Browse files
committed
samples: Bluetooth: CAP Handover
Add a CAP Handover sample that uses the CAP handover API as the CAP Initiator and CAP commander. Signed-off-by: Emil Gydesen <[email protected]>
1 parent 0f1f838 commit 49a052a

17 files changed

+1821
-12
lines changed

samples/bluetooth/cap_acceptor/Kconfig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ config SAMPLE_UNICAST
2020

2121
config SAMPLE_BROADCAST
2222
bool "Whether or not to search for CAP acceptors for unicast audio"
23-
default y if !SAMPLE_UNICAST
23+
default y
2424
select BT_BAP_SCAN_DELEGATOR
2525
select BT_OBSERVER
2626
select BT_ISO_SYNC_RECEIVER

samples/bluetooth/cap_acceptor/src/cap_acceptor.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
struct peer_config {
1919
/** Stream for the source endpoint */
2020
struct bt_cap_stream source_stream;
21-
/** Stream for the sink endpoint */
22-
struct bt_cap_stream sink_stream;
21+
/** Streams for the sink endpoint */
22+
struct bt_cap_stream sink_streams[CONFIG_BT_ASCS_MAX_ASE_SNK_COUNT];
2323
/** Semaphore to help wait for a release operation if the source stream is not idle */
2424
struct k_sem source_stream_sem;
2525
/** Semaphore to help wait for a release operation if the sink stream is not idle */

samples/bluetooth/cap_acceptor/src/cap_acceptor_unicast.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -438,7 +438,10 @@ int init_cap_acceptor_unicast(struct peer_config *peer)
438438
}
439439

440440
bt_cap_stream_ops_register(&peer->source_stream, &unicast_stream_ops);
441-
bt_cap_stream_ops_register(&peer->sink_stream, &unicast_stream_ops);
441+
442+
ARRAY_FOR_EACH_PTR(peer->sink_streams, stream) {
443+
bt_cap_stream_ops_register(stream, &unicast_stream_ops);
444+
}
442445

443446
if (IS_ENABLED(CONFIG_BT_ASCS_ASE_SRC)) {
444447
static bool thread_started;

samples/bluetooth/cap_acceptor/src/main.c

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <zephyr/kernel.h>
2727
#include <zephyr/logging/log.h>
2828
#include <zephyr/logging/log_core.h>
29+
#include <zephyr/sys/__assert.h>
2930
#include <zephyr/sys/util.h>
3031
#include <zephyr/sys/util_macro.h>
3132

@@ -140,8 +141,12 @@ static int advertise(void)
140141

141142
struct bt_cap_stream *stream_alloc(enum bt_audio_dir dir)
142143
{
143-
if (dir == BT_AUDIO_DIR_SINK && peer.sink_stream.bap_stream.ep == NULL) {
144-
return &peer.sink_stream;
144+
if (dir == BT_AUDIO_DIR_SINK) {
145+
ARRAY_FOR_EACH_PTR(peer.sink_streams, stream) {
146+
if (stream->bap_stream.ep == NULL) {
147+
return stream;
148+
}
149+
}
145150
} else if (dir == BT_AUDIO_DIR_SOURCE && peer.source_stream.bap_stream.ep == NULL) {
146151
return &peer.source_stream;
147152
}
@@ -153,8 +158,10 @@ void stream_released(const struct bt_cap_stream *cap_stream)
153158
{
154159
if (cap_stream == &peer.source_stream) {
155160
k_sem_give(&peer.source_stream_sem);
156-
} else if (cap_stream == &peer.sink_stream) {
161+
} else if (IS_ARRAY_ELEMENT(peer.sink_streams, cap_stream)) {
157162
k_sem_give(&peer.sink_stream_sem);
163+
} else {
164+
__ASSERT(false, "Invalid stream: %p", cap_stream);
158165
}
159166
}
160167

@@ -201,11 +208,13 @@ static int reset_cap_acceptor(void)
201208
}
202209
}
203210

204-
if (peer.sink_stream.bap_stream.ep != NULL) {
205-
err = k_sem_take(&peer.sink_stream_sem, SEM_TIMEOUT);
206-
if (err != 0) {
207-
LOG_ERR("Timeout on sink_stream_sem: %d", err);
208-
return err;
211+
ARRAY_FOR_EACH_PTR(peer.sink_streams, stream) {
212+
if (stream->bap_stream.ep != NULL) {
213+
err = k_sem_take(&peer.sink_stream_sem, SEM_TIMEOUT);
214+
if (err != 0) {
215+
LOG_ERR("Timeout on sink_stream_sem: %d", err);
216+
return err;
217+
}
209218
}
210219
}
211220

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# SPDX-License-Identifier: Apache-2.0
2+
3+
cmake_minimum_required(VERSION 3.20.0)
4+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
5+
project(cap_handover)
6+
7+
target_sources(app PRIVATE
8+
src/main.c
9+
src/cap_stream_tx.c
10+
)
11+
12+
zephyr_library_include_directories(${ZEPHYR_BASE}/samples/bluetooth)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Copyright (c) 2024 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
mainmenu "Bluetooth: Common Audio Profile initiator sample"
5+
6+
config SAMPLE_STATIC_BROADCAST_ID
7+
bool "Use static broadcast ID"
8+
default y
9+
help
10+
Enabling this option will make the application use static broadcast ID, as opposed to a
11+
randomly generated one.
12+
13+
config SAMPLE_BROADCAST_ID
14+
hex "The static broadcast ID to use"
15+
range 0x000000 0xFFFFFF
16+
depends on STATIC_BROADCAST_ID
17+
default 0x123456
18+
help
19+
This is the 3-octet broadcast ID advertised if static broadcast IDs are enabled.
20+
21+
source "Kconfig.zephyr"
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Copyright 2023 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
source "share/sysbuild/Kconfig"
5+
6+
config NET_CORE_BOARD
7+
string
8+
default "nrf5340dk/nrf5340/cpunet" if "$(BOARD)" = "nrf5340dk"
9+
default "nrf5340_audio_dk/nrf5340/cpunet" if "$(BOARD)" = "nrf5340_audio_dk"
10+
default "nrf5340bsim/nrf5340/cpunet" if $(BOARD_TARGET_STRING) = "NRF5340BSIM_NRF5340_CPUAPP"
11+
12+
config NET_CORE_IMAGE_HCI_IPC
13+
bool "HCI IPC image on network core"
14+
default y
15+
depends on NET_CORE_BOARD != ""
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
.. zephyr:code-sample:: bluetooth_cap_handover
2+
:name: Common Audio Profile (CAP) Handover
3+
:relevant-api: bluetooth bt_bap bt_cap bt_conn
4+
5+
Connects to a CAP acceptor and performs CAP handover procedures
6+
7+
Overview
8+
********
9+
10+
Application demonstrating the CAP handover functionality.
11+
Starts by scanning for a CAP Acceptor then sets up unicast audio, and then switches between unicast
12+
and broadcast using the CAP handover procedures.
13+
14+
This sample can be found under :zephyr_file:`samples/bluetooth/cap_handover` in the Zephyr tree.
15+
16+
Check the :zephyr:code-sample-category:`bluetooth` samples for general information.
17+
18+
Requirements
19+
************
20+
21+
* BlueZ running on the host, or
22+
* A board with Bluetooth Low Energy 5.2 support
23+
24+
Building and Running
25+
********************
26+
27+
When building targeting an nrf52 series board with the Zephyr Bluetooth Controller,
28+
use ``-DEXTRA_CONF_FILE=overlay-bt_ll_sw_split.conf`` to enable the required ISO
29+
feature support.
30+
31+
Building for an nrf5340dk
32+
-------------------------
33+
34+
You can build both the application core image and an appropriate controller image for the network
35+
core with:
36+
37+
.. zephyr-app-commands::
38+
:zephyr-app: samples/bluetooth/cap_handover/
39+
:board: nrf5340dk/nrf5340/cpuapp
40+
:goals: build
41+
:west-args: --sysbuild
42+
43+
If you prefer to only build the application core image, you can do so by doing instead:
44+
45+
.. zephyr-app-commands::
46+
:zephyr-app: samples/bluetooth/cap_handover/
47+
:board: nrf5340dk/nrf5340/cpuapp
48+
:goals: build
49+
50+
In that case you can pair this application core image with the
51+
:zephyr:code-sample:`bluetooth_hci_ipc` sample
52+
:zephyr_file:`samples/bluetooth/hci_ipc/nrf5340_cpunet_iso-bt_ll_sw_split.conf` configuration.
53+
54+
Building for a simulated nrf5340bsim
55+
------------------------------------
56+
57+
Similarly to how you would for real HW, you can do:
58+
59+
.. zephyr-app-commands::
60+
:zephyr-app: samples/bluetooth/cap_handover/
61+
:board: nrf5340bsim/nrf5340/cpuapp
62+
:goals: build
63+
:west-args: --sysbuild
64+
65+
Note this will produce a Linux executable in :file:`./build/zephyr/zephyr.exe`.
66+
For more information, check :ref:`this board documentation <nrf5340bsim>`.
67+
68+
Building for a simulated nrf52_bsim
69+
-----------------------------------
70+
71+
.. zephyr-app-commands::
72+
:zephyr-app: samples/bluetooth/cap_handover/
73+
:board: nrf52_bsim
74+
:goals: build
75+
:gen-args: -DEXTRA_CONF_FILE=overlay-bt_ll_sw_split.conf
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
CONFIG_BT_BUF_EVT_RX_SIZE=255
2+
CONFIG_BT_BUF_ACL_RX_SIZE=255
3+
CONFIG_BT_BUF_ACL_TX_SIZE=251
4+
CONFIG_BT_BUF_CMD_TX_SIZE=255
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
CONFIG_BT_BUF_EVT_RX_SIZE=255
2+
CONFIG_BT_BUF_ACL_RX_SIZE=255
3+
CONFIG_BT_BUF_ACL_TX_SIZE=251
4+
CONFIG_BT_BUF_CMD_TX_SIZE=255

0 commit comments

Comments
 (0)