From 4e3205d2386bf92884d8dca1bf66d4fa7267783a Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Tue, 20 Dec 2022 15:54:37 +0100 Subject: [PATCH] Bluetooth: Audio: Add packing to unicast group create Add the ISO packing field when creating a unicast group. This refactors the structure of the unicast group create, as it now takes both the packing as a group parameter, as well as an array of stream-specific parameters. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/audio.h | 34 +++++++++---- .../bluetooth/unicast_audio_client/src/main.c | 16 ++++--- subsys/bluetooth/audio/stream.c | 48 +++++++++++-------- subsys/bluetooth/shell/audio.c | 9 +++- .../bsim_test_audio/src/unicast_client_test.c | 15 ++++-- 5 files changed, 79 insertions(+), 43 deletions(-) diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index 575530f3a68..d840d0c4d89 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -1940,14 +1940,14 @@ int bt_audio_stream_send(struct bt_audio_stream *stream, struct net_buf *buf, * Parameter struct for the bt_audio_unicast_group_create() and * bt_audio_unicast_group_add_streams() functions. */ -struct bt_audio_unicast_group_param { +struct bt_audio_unicast_group_stream_param { /** Pointer to a stream object. */ struct bt_audio_stream *stream; - /** The QoS settings for the @ref bt_audio_unicast_group_param.stream. */ + /** The QoS settings for the @ref bt_audio_unicast_group_stream_param.stream. */ struct bt_codec_qos *qos; - /** @brief The direction of the @ref bt_audio_unicast_group_param.stream + /** @brief The direction of the @ref bt_audio_unicast_group_stream_param.stream * * If two streams are being used for the same ACL connection but in * different directions, they may use the same CIS. @@ -1955,21 +1955,35 @@ struct bt_audio_unicast_group_param { enum bt_audio_dir dir; }; +struct bt_audio_unicast_group_param { + /** The number of parameters in @p params */ + size_t params_count; + + /** Array of stream parameters */ + struct bt_audio_unicast_group_stream_param *params; + + /** @brief Unicast Group packing mode. + * + * @ref BT_ISO_PACKING_SEQUENTIAL or @ref BT_ISO_PACKING_INTERLEAVED. + * + * @note This is a recommendation to the controller, which the + * controller may ignore. + */ + uint8_t packing; +}; + /** @brief Create audio unicast group. * * Create a new audio unicast group with one or more audio streams as a * unicast client. Streams in a unicast group shall share the same interval, * framing and latency (see @ref bt_codec_qos). * - * @param[in] params Array of stream parameters being used for - * the group. - * @param[in] num_param Number of parameters in @p params. - * @param[out] unicast_group Pointer to the unicast group created + * @param[in] param The unicast group create parameters. + * @param[out] unicast_group Pointer to the unicast group created. * * @return Zero on success or (negative) error code otherwise. */ -int bt_audio_unicast_group_create(struct bt_audio_unicast_group_param params[], - size_t num_param, +int bt_audio_unicast_group_create(struct bt_audio_unicast_group_param *param, struct bt_audio_unicast_group **unicast_group); /** @brief Add streams to a unicast group as a unicast client @@ -1995,7 +2009,7 @@ int bt_audio_unicast_group_create(struct bt_audio_unicast_group_param params[], * @return 0 in case of success or negative value in case of error. */ int bt_audio_unicast_group_add_streams(struct bt_audio_unicast_group *unicast_group, - struct bt_audio_unicast_group_param params[], + struct bt_audio_unicast_group_stream_param params[], size_t num_param); /** @brief Delete audio unicast group. diff --git a/samples/bluetooth/unicast_audio_client/src/main.c b/samples/bluetooth/unicast_audio_client/src/main.c index 00c91ef5b1c..42acb896866 100644 --- a/samples/bluetooth/unicast_audio_client/src/main.c +++ b/samples/bluetooth/unicast_audio_client/src/main.c @@ -908,17 +908,21 @@ static int configure_streams(void) static int create_group(void) { - struct bt_audio_unicast_group_param params[ARRAY_SIZE(streams)]; + struct bt_audio_unicast_group_stream_param stream_params[ARRAY_SIZE(streams)]; + struct bt_audio_unicast_group_param param; int err; for (size_t i = 0U; i < configured_stream_count; i++) { - params[i].stream = &streams[i]; - params[i].qos = &codec_configuration.qos; - params[i].dir = stream_dir(params[i].stream); + stream_params[i].stream = &streams[i]; + stream_params[i].qos = &codec_configuration.qos; + stream_params[i].dir = stream_dir(stream_params[i].stream); } - err = bt_audio_unicast_group_create(params, configured_stream_count, - &unicast_group); + param.params = stream_params; + param.params_count = configured_stream_count; + param.packing = BT_ISO_PACKING_SEQUENTIAL; + + err = bt_audio_unicast_group_create(¶m, &unicast_group); if (err != 0) { printk("Could not create unicast group (err %d)\n", err); return err; diff --git a/subsys/bluetooth/audio/stream.c b/subsys/bluetooth/audio/stream.c index 9bea7907bda..79f8001e4a2 100644 --- a/subsys/bluetooth/audio/stream.c +++ b/subsys/bluetooth/audio/stream.c @@ -948,8 +948,7 @@ static void unicast_group_free(struct bt_audio_unicast_group *group) group->allocated = false; } -int bt_audio_unicast_group_create(struct bt_audio_unicast_group_param params[], - size_t num_param, +int bt_audio_unicast_group_create(struct bt_audio_unicast_group_param *param, struct bt_audio_unicast_group **out_unicast_group) { struct bt_audio_unicast_group *unicast_group; @@ -963,39 +962,44 @@ int bt_audio_unicast_group_create(struct bt_audio_unicast_group_param params[], /* Set out_unicast_group to NULL until the source has actually been created */ *out_unicast_group = NULL; - CHECKIF(params == NULL) { + CHECKIF(param == NULL) { LOG_DBG("streams is NULL"); return -EINVAL; } - CHECKIF(num_param > UNICAST_GROUP_STREAM_CNT) { - LOG_DBG("Too many streams provided: %u/%u", num_param, UNICAST_GROUP_STREAM_CNT); + CHECKIF(param->params_count > UNICAST_GROUP_STREAM_CNT) { + LOG_DBG("Too many streams provided: %u/%u", + param->params_count, UNICAST_GROUP_STREAM_CNT); return -EINVAL; } - for (size_t i = 0U; i < num_param; i++) { - CHECKIF(params[i].stream == NULL || - params[i].qos == NULL || - (params[i].dir != BT_AUDIO_DIR_SINK && - params[i].dir != BT_AUDIO_DIR_SOURCE)) { + for (size_t i = 0U; i < param->params_count; i++) { + struct bt_audio_unicast_group_stream_param *stream_param = ¶m->params[i]; + + CHECKIF(stream_param->stream == NULL || + stream_param->qos == NULL || + (stream_param->dir != BT_AUDIO_DIR_SINK && + stream_param->dir != BT_AUDIO_DIR_SOURCE)) { LOG_DBG("Invalid params[%zu] values", i); return -EINVAL; } - if (params[i].stream->group != NULL) { - LOG_DBG("params[%zu] stream (%p) already part of group %p", i, - params[i].stream, params[i].stream->group); + if (stream_param->stream->group != NULL) { + LOG_DBG("params[%zu] stream (%p) already part of group %p", + i, stream_param->stream, + stream_param->stream->group); return -EALREADY; } if (group_qos == NULL) { - group_qos = params[i].qos; - } else if (!unicast_group_valid_qos(group_qos, params[i].qos)) { + group_qos = stream_param->qos; + } else if (!unicast_group_valid_qos(group_qos, + stream_param->qos)) { LOG_DBG("Stream[%zu] QoS incompatible with group QoS", i); return -EINVAL; } - CHECKIF(!bt_audio_valid_qos(params[i].qos)) { + CHECKIF(!bt_audio_valid_qos(stream_param->qos)) { LOG_DBG("Invalid QoS"); return -EINVAL; } @@ -1007,9 +1011,13 @@ int bt_audio_unicast_group_create(struct bt_audio_unicast_group_param params[], return -ENOMEM; } - for (size_t i = 0U; i < num_param; i++) { - err = unicast_group_add_stream(unicast_group, params[i].stream, - params[i].qos, params[i].dir); + for (size_t i = 0U; i < param->params_count; i++) { + struct bt_audio_unicast_group_stream_param *stream_param = ¶m->params[i]; + + err = unicast_group_add_stream(unicast_group, + stream_param->stream, + stream_param->qos, + stream_param->dir); if (err < 0) { LOG_DBG("unicast_group_add_stream failed: %d", err); unicast_group_free(unicast_group); @@ -1032,7 +1040,7 @@ int bt_audio_unicast_group_create(struct bt_audio_unicast_group_param params[], } int bt_audio_unicast_group_add_streams(struct bt_audio_unicast_group *unicast_group, - struct bt_audio_unicast_group_param params[], + struct bt_audio_unicast_group_stream_param params[], size_t num_param) { const struct bt_codec_qos *group_qos = unicast_group->qos; diff --git a/subsys/bluetooth/shell/audio.c b/subsys/bluetooth/shell/audio.c index 70f6b42dd82..7154057d2cf 100644 --- a/subsys/bluetooth/shell/audio.c +++ b/subsys/bluetooth/shell/audio.c @@ -1033,13 +1033,18 @@ static int cmd_qos(const struct shell *sh, size_t argc, char *argv[]) } if (default_unicast_group == NULL) { - struct bt_audio_unicast_group_param params = { + struct bt_audio_unicast_group_stream_param stream_param = { .stream = default_stream, .qos = &default_preset->preset.qos, .dir = stream_dir(default_stream) }; + struct bt_audio_unicast_group_param param = { + .packing = BT_ISO_PACKING_SEQUENTIAL, + .params = &stream_param, + .params_count = 1, + }; - err = bt_audio_unicast_group_create(¶ms, 1, &default_unicast_group); + err = bt_audio_unicast_group_create(¶m, &default_unicast_group); if (err != 0) { shell_error(sh, "Unable to create default unicast group: %d", err); return -ENOEXEC; diff --git a/tests/bluetooth/bsim_bt/bsim_test_audio/src/unicast_client_test.c b/tests/bluetooth/bsim_bt/bsim_test_audio/src/unicast_client_test.c index 61f9d6c49ad..f77093dce32 100644 --- a/tests/bluetooth/bsim_bt/bsim_test_audio/src/unicast_client_test.c +++ b/tests/bluetooth/bsim_bt/bsim_test_audio/src/unicast_client_test.c @@ -339,20 +339,25 @@ static size_t release_streams(size_t stream_cnt) static void create_unicast_group(struct bt_audio_unicast_group **unicast_group, size_t stream_cnt) { - struct bt_audio_unicast_group_param params[ARRAY_SIZE(g_streams)]; + struct bt_audio_unicast_group_stream_param stream_params[ARRAY_SIZE(g_streams)]; + struct bt_audio_unicast_group_param param; for (size_t i = 0U; i < stream_cnt; i++) { - params[i].stream = &g_streams[i]; - params[i].qos = &preset_16_2_1.qos; - params[i].dir = BT_AUDIO_DIR_SINK; /* we only configure sinks */ + stream_params[i].stream = &g_streams[i]; + stream_params[i].qos = &preset_16_2_1.qos; + stream_params[i].dir = BT_AUDIO_DIR_SINK; /* we only configure sinks */ } + param.params = stream_params; + param.params_count = stream_cnt; + param.packing = BT_ISO_PACKING_SEQUENTIAL; + #if defined(CONFIG_BT_CTLR_CENTRAL_ISO) int err; /* Require controller support for CIGs */ printk("Creating unicast group\n"); - err = bt_audio_unicast_group_create(¶ms, 1, unicast_group); + err = bt_audio_unicast_group_create(¶m, unicast_group); if (err != 0) { FAIL("Unable to create unicast group: %d", err); return;