Skip to content

Commit

Permalink
Bluetooth: CAP: Shell: Add proper broadcast commands
Browse files Browse the repository at this point in the history
Adds additional broadcast commands and modifies the existing
ones to use the CAP API.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
  • Loading branch information
Thalley committed Feb 5, 2024
1 parent e90613e commit ccc1aa9
Show file tree
Hide file tree
Showing 4 changed files with 267 additions and 20 deletions.
50 changes: 49 additions & 1 deletion doc/connectivity/bluetooth/api/shell/cap.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ Using the CAP Initiator
=======================

When the Bluetooth stack has been initialized (:code:`bt init`), the Initiator can discover CAS and
the optionally included CSIS instance by calling (:code:`cap_initiator discover`).
the optionally included CSIS instance by calling (:code:`cap_initiator discover`). The CAP initiator
also does broadcast audio.

.. code-block:: console
Expand Down Expand Up @@ -138,6 +139,53 @@ used.
uart:~$ cap_initiator unicast-stop
Unicast stopped for group 0x81e41c0 completed
When doing broadcast
--------------------

To start a broadcast as the CAP initiator there are a few steps to be done:

1. Create and configure an extended advertising set with periodic advertising
2. Create and configure a broadcast source
3. Setup extended and periodic advertising data

The following commands will setup a CAP broadcast source using the 16_2_1 preset (defined by BAP):


.. code-block:: console
bt init
bap init
bt adv-create nconn-nscan ext-adv name
bt per-adv-param
cap_initiator ac_12 16_2_1
bt adv-data discov
bt per-adv-data
cap_initiator broadcast_start
The broadcast source is created by the :code:`cap_initiator ac_12`, :code:`cap_initiator ac_13`,
and :code:`cap_initiator ac_14` commands, configuring the broadcast source for the defined audio
configurations from BAP. The broadcast source can then be stopped with
:code:`cap_initiator broadcast_stop` or deleted with :code:`cap_initiator broadcast_delete`.

The metadata of the broadcast source can be updated at any time, including when it is already
streaming. To update the metadata the :code:`cap_initiator broadcast_update` command can be used.
The command takes an array of data, and the only requirement (besides having valid data) is that the
streaming context shall be set. For example to set the streaming context to media, the command can
be used as

.. code-block:: console
cap_initiator broadcast_update 03020400
CAP Broadcast source updated with new metadata. Update the advertised base via `bt per-adv-data`
bt per-adv-data
The :code:`bt per-adv-data` command should be used afterwards to update the data is the advertised
BASE. The data must be little-endian, so in the above example the metadata :code:`03020400` is
setting the metadata entry with :code:`03` as the length, :code:`02` as the type (streaming context)
and :code:`0400` as the value :code:`BT_AUDIO_CONTEXT_TYPE_MEDIA`
(which has the numeric value of 0x).

CAP Commander
*************

Expand Down
4 changes: 4 additions & 0 deletions subsys/bluetooth/audio/shell/audio.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ ssize_t csis_ad_data_add(struct bt_data *data, const size_t data_size, const boo
size_t cap_acceptor_ad_data_add(struct bt_data data[], size_t data_size, bool discoverable);
size_t gmap_ad_data_add(struct bt_data data[], size_t data_size);
size_t pbp_ad_data_add(struct bt_data data[], size_t data_size);
ssize_t cap_initiator_ad_data_add(struct bt_data *data_array, const size_t data_array_size,
const bool discoverable, const bool connectable);
ssize_t cap_initiator_pa_data_add(struct bt_data *data_array, const size_t data_array_size);

#if defined(CONFIG_BT_AUDIO)
/* Must guard before including audio.h as audio.h uses Kconfigs guarded by
Expand Down Expand Up @@ -99,6 +102,7 @@ struct shell_stream {
};

struct broadcast_source {
bool is_cap;
union {
struct bt_bap_broadcast_source *bap_source;
struct bt_cap_broadcast_source *cap_source;
Expand Down
25 changes: 18 additions & 7 deletions subsys/bluetooth/audio/shell/bap.c
Original file line number Diff line number Diff line change
Expand Up @@ -2115,7 +2115,7 @@ static int cmd_start_broadcast(const struct shell *sh, size_t argc,
return -ENOEXEC;
}

if (default_source.bap_source == NULL) {
if (default_source.bap_source == NULL || default_source.is_cap) {
shell_info(sh, "Broadcast source not created");
return -ENOEXEC;
}
Expand All @@ -2133,7 +2133,7 @@ static int cmd_stop_broadcast(const struct shell *sh, size_t argc, char *argv[])
{
int err;

if (default_source.bap_source == NULL) {
if (default_source.bap_source == NULL || default_source.is_cap) {
shell_info(sh, "Broadcast source not created");
return -ENOEXEC;
}
Expand All @@ -2152,7 +2152,7 @@ static int cmd_delete_broadcast(const struct shell *sh, size_t argc,
{
int err;

if (default_source.bap_source == NULL) {
if (default_source.bap_source == NULL || default_source.is_cap) {
shell_info(sh, "Broadcast source not created");
return -ENOEXEC;
}
Expand Down Expand Up @@ -2996,7 +2996,7 @@ static ssize_t nonconnectable_ad_data_add(struct bt_data *data_array,
}

#if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
if (default_source.bap_source) {
if (default_source.bap_source != NULL && !default_source.is_cap) {
static uint8_t ad_bap_broadcast_announcement[5] = {
BT_UUID_16_ENCODE(BT_UUID_BROADCAST_AUDIO_VAL),
};
Expand Down Expand Up @@ -3036,15 +3036,24 @@ static ssize_t nonconnectable_ad_data_add(struct bt_data *data_array,
ssize_t audio_ad_data_add(struct bt_data *data_array, const size_t data_array_size,
const bool discoverable, const bool connectable)
{
ssize_t ad_len = 0;

if (!discoverable) {
return 0;
}

if (connectable) {
return connectable_ad_data_add(data_array, data_array_size);
ad_len += connectable_ad_data_add(data_array, data_array_size);
} else {
return nonconnectable_ad_data_add(data_array, data_array_size);
ad_len += nonconnectable_ad_data_add(data_array, data_array_size);
}

if (IS_ENABLED(CONFIG_BT_CAP_INITIATOR)) {
ad_len += cap_initiator_ad_data_add(data_array, data_array_size, discoverable,
connectable);
}

return ad_len;
}

ssize_t audio_pa_data_add(struct bt_data *data_array,
Expand All @@ -3053,7 +3062,7 @@ ssize_t audio_pa_data_add(struct bt_data *data_array,
size_t ad_len = 0;

#if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
if (default_source.bap_source) {
if (default_source.bap_source != NULL && !default_source.is_cap) {
/* Required size of the buffer depends on what has been
* configured. We just use the maximum size possible.
*/
Expand All @@ -3071,6 +3080,8 @@ ssize_t audio_pa_data_add(struct bt_data *data_array,
data_array[ad_len].data_len = base_buf.len;
data_array[ad_len].data = base_buf.data;
ad_len++;
} else if (IS_ENABLED(CONFIG_BT_CAP_INITIATOR)) {
return cap_initiator_pa_data_add(data_array, data_array_size);
}
#endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */

Expand Down

0 comments on commit ccc1aa9

Please sign in to comment.