Bluetooth: CAP: Make unicast update more similar to unicast start
Modify the parameters for bt_cap_initiator_unicast_audio_update so that they are more similar to bt_cap_initiator_unicast_audio_start. Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
parent
f35e9871d5
commit
ec549cebd5
5 changed files with 186 additions and 101 deletions
|
@ -227,8 +227,9 @@ struct bt_cap_unicast_audio_start_param {
|
|||
struct bt_cap_unicast_audio_start_stream_param *stream_params;
|
||||
};
|
||||
|
||||
struct bt_cap_unicast_audio_update_param {
|
||||
/** @brief Stream for the @p member */
|
||||
/** Stream specific parameters for the bt_cap_initiator_unicast_audio_update() function */
|
||||
struct bt_cap_unicast_audio_update_stream_param {
|
||||
/** Stream to update */
|
||||
struct bt_cap_stream *stream;
|
||||
|
||||
/** The length of @p meta. */
|
||||
|
@ -242,6 +243,18 @@ struct bt_cap_unicast_audio_update_param {
|
|||
uint8_t *meta;
|
||||
};
|
||||
|
||||
/** Parameters for the bt_cap_initiator_unicast_audio_update() function */
|
||||
struct bt_cap_unicast_audio_update_param {
|
||||
/** The type of the set. */
|
||||
enum bt_cap_set_type type;
|
||||
|
||||
/** The number of parameters in @p stream_params */
|
||||
size_t count;
|
||||
|
||||
/** Array of stream parameters */
|
||||
struct bt_cap_unicast_audio_update_stream_param *stream_params;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Register Common Audio Profile Initiator callbacks
|
||||
*
|
||||
|
@ -277,13 +290,11 @@ int bt_cap_initiator_unicast_audio_start(const struct bt_cap_unicast_audio_start
|
|||
* @kconfig{CONFIG_BT_BAP_UNICAST_CLIENT} must be enabled for this function
|
||||
* to be enabled.
|
||||
*
|
||||
* @param params Array of update parameters.
|
||||
* @param count The number of entries in @p params.
|
||||
* @param param Update parameters.
|
||||
*
|
||||
* @return 0 on success or negative error value on failure.
|
||||
*/
|
||||
int bt_cap_initiator_unicast_audio_update(const struct bt_cap_unicast_audio_update_param params[],
|
||||
size_t count);
|
||||
int bt_cap_initiator_unicast_audio_update(const struct bt_cap_unicast_audio_update_param *param);
|
||||
|
||||
/**
|
||||
* @brief Stop unicast audio streams for a unicast group.
|
||||
|
|
|
@ -891,8 +891,104 @@ static bool can_update_metadata(const struct bt_bap_stream *bap_stream)
|
|||
ep_info.state == BT_BAP_EP_STATE_STREAMING;
|
||||
}
|
||||
|
||||
int bt_cap_initiator_unicast_audio_update(const struct bt_cap_unicast_audio_update_param params[],
|
||||
size_t count)
|
||||
static bool valid_unicast_audio_update_param(const struct bt_cap_unicast_audio_update_param *param)
|
||||
{
|
||||
struct bt_bap_unicast_group *unicast_group = NULL;
|
||||
|
||||
CHECKIF(param == NULL) {
|
||||
LOG_DBG("param is NULL");
|
||||
return false;
|
||||
}
|
||||
|
||||
CHECKIF(param->count == 0) {
|
||||
LOG_DBG("Invalid param->count: %u", param->count);
|
||||
return false;
|
||||
}
|
||||
|
||||
CHECKIF(param->stream_params == NULL) {
|
||||
LOG_DBG("param->stream_params is NULL");
|
||||
return false;
|
||||
}
|
||||
|
||||
CHECKIF(param->count > CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT) {
|
||||
LOG_DBG("param->count (%zu) is larger than "
|
||||
"CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT (%d)",
|
||||
param->count, CONFIG_BT_BAP_UNICAST_CLIENT_GROUP_STREAM_COUNT);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0U; i < param->count; i++) {
|
||||
const struct bt_cap_unicast_audio_update_stream_param *stream_param =
|
||||
¶m->stream_params[i];
|
||||
const struct bt_cap_stream *cap_stream = stream_param->stream;
|
||||
const struct bt_bap_stream *bap_stream;
|
||||
struct bt_cap_common_client *client;
|
||||
struct bt_conn *conn;
|
||||
|
||||
CHECKIF(cap_stream == NULL) {
|
||||
LOG_DBG("param->stream_params[%zu] is NULL", i);
|
||||
return false;
|
||||
}
|
||||
|
||||
bap_stream = &cap_stream->bap_stream;
|
||||
conn = bap_stream->conn;
|
||||
CHECKIF(conn == NULL) {
|
||||
LOG_DBG("param->stream_params[%zu].stream->bap_stream.conn is NULL", i);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
client = bt_cap_common_get_client_by_acl(conn);
|
||||
if (!client->cas_found) {
|
||||
LOG_DBG("CAS was not found for param->stream_params[%zu].stream", i);
|
||||
return false;
|
||||
}
|
||||
|
||||
CHECKIF(bap_stream->group == NULL) {
|
||||
LOG_DBG("param->stream_params[%zu] is not in a unicast group", i);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Use the group of the first stream for comparison */
|
||||
if (unicast_group == NULL) {
|
||||
unicast_group = bap_stream->group;
|
||||
} else {
|
||||
CHECKIF(bap_stream->group != unicast_group) {
|
||||
LOG_DBG("param->stream_params[%zu] is not in this group %p", i,
|
||||
unicast_group);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!can_update_metadata(bap_stream)) {
|
||||
LOG_DBG("param->stream_params[%zu].stream is not in right state to be "
|
||||
"updated",
|
||||
i);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!cap_initiator_valid_metadata(stream_param->meta, stream_param->meta_len)) {
|
||||
LOG_DBG("param->stream_params[%zu] invalid metadata", i);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t j = 0U; j < i; j++) {
|
||||
if (param->stream_params[j].stream == cap_stream) {
|
||||
LOG_DBG("param->stream_params[%zu] (%p) is "
|
||||
"duplicated by "
|
||||
"param->stream_params[%zu] (%p)",
|
||||
j, param->stream_params[j].stream, i, cap_stream);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int bt_cap_initiator_unicast_audio_update(const struct bt_cap_unicast_audio_update_param *param)
|
||||
{
|
||||
struct bt_cap_common_proc *active_proc = bt_cap_common_get_active_proc();
|
||||
struct bt_cap_initiator_proc_param *proc_param;
|
||||
|
@ -901,67 +997,28 @@ int bt_cap_initiator_unicast_audio_update(const struct bt_cap_unicast_audio_upda
|
|||
size_t meta_len;
|
||||
int err;
|
||||
|
||||
CHECKIF(params == NULL) {
|
||||
LOG_DBG("params is NULL");
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
CHECKIF(count == 0) {
|
||||
LOG_DBG("count is 0");
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (bt_cap_common_proc_is_active()) {
|
||||
LOG_DBG("A CAP procedure is already in progress");
|
||||
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
for (size_t i = 0U; i < count; i++) {
|
||||
struct bt_cap_stream *cap_stream = params[i].stream;
|
||||
|
||||
CHECKIF(cap_stream == NULL) {
|
||||
LOG_DBG("params[%zu].stream is NULL", i);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
CHECKIF(cap_stream->bap_stream.conn == NULL) {
|
||||
LOG_DBG("params[%zu].stream->bap_stream.conn is NULL", i);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
CHECKIF(!cap_initiator_valid_metadata(params[i].meta,
|
||||
params[i].meta_len)) {
|
||||
LOG_DBG("params[%zu].meta is invalid", i);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
for (size_t j = 0U; j < i; j++) {
|
||||
if (params[j].stream == cap_stream) {
|
||||
LOG_DBG("param.streams[%zu] is duplicated by param.streams[%zu]",
|
||||
j, i);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!can_update_metadata(&cap_stream->bap_stream)) {
|
||||
LOG_DBG("params[%zu].stream is not in right state to be updated", i);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
active_proc->proc_param.initiator[i].stream = cap_stream;
|
||||
active_proc->proc_param.initiator[i].meta_update.meta_len = params[i].meta_len;
|
||||
memcpy(&active_proc->proc_param.initiator[i].meta_update.meta, params[i].meta,
|
||||
params[i].meta_len);
|
||||
if (!valid_unicast_audio_update_param(param)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bt_cap_common_start_proc(BT_CAP_COMMON_PROC_TYPE_UPDATE, count);
|
||||
for (size_t i = 0U; i < param->count; i++) {
|
||||
const struct bt_cap_unicast_audio_update_stream_param *stream_param =
|
||||
¶m->stream_params[i];
|
||||
struct bt_cap_stream *cap_stream = stream_param->stream;
|
||||
|
||||
active_proc->proc_param.initiator[i].stream = cap_stream;
|
||||
active_proc->proc_param.initiator[i].meta_update.meta_len = stream_param->meta_len;
|
||||
memcpy(&active_proc->proc_param.initiator[i].meta_update.meta, stream_param->meta,
|
||||
stream_param->meta_len);
|
||||
}
|
||||
|
||||
bt_cap_common_start_proc(BT_CAP_COMMON_PROC_TYPE_UPDATE, param->count);
|
||||
bt_cap_common_set_subproc(BT_CAP_COMMON_SUBPROC_TYPE_META_UPDATE);
|
||||
|
||||
proc_param = &active_proc->proc_param.initiator[0];
|
||||
|
|
|
@ -337,8 +337,9 @@ static int cmd_cap_initiator_unicast_list(const struct shell *sh, size_t argc,
|
|||
static int cmd_cap_initiator_unicast_update(const struct shell *sh, size_t argc,
|
||||
char *argv[])
|
||||
{
|
||||
struct bt_cap_unicast_audio_update_param params[CAP_UNICAST_CLIENT_STREAM_COUNT];
|
||||
size_t count;
|
||||
struct bt_cap_unicast_audio_update_stream_param
|
||||
stream_params[CAP_UNICAST_CLIENT_STREAM_COUNT] = {0};
|
||||
struct bt_cap_unicast_audio_update_param param = {0};
|
||||
int err = 0;
|
||||
|
||||
if (default_conn == NULL) {
|
||||
|
@ -346,8 +347,6 @@ static int cmd_cap_initiator_unicast_update(const struct shell *sh, size_t argc,
|
|||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
|
||||
if (argc == 2 && strcmp(argv[1], "all") == 0) {
|
||||
for (size_t i = 0U; i < ARRAY_SIZE(unicast_streams); i++) {
|
||||
struct bt_cap_stream *stream = &unicast_streams[i].stream;
|
||||
|
@ -366,8 +365,7 @@ static int cmd_cap_initiator_unicast_update(const struct shell *sh, size_t argc,
|
|||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
params[count].stream = stream;
|
||||
|
||||
stream_params[param.count].stream = stream;
|
||||
|
||||
if (ep_info.dir == BT_AUDIO_DIR_SINK) {
|
||||
copy_unicast_stream_preset(uni_stream, default_sink_preset);
|
||||
|
@ -375,10 +373,10 @@ static int cmd_cap_initiator_unicast_update(const struct shell *sh, size_t argc,
|
|||
copy_unicast_stream_preset(uni_stream, default_source_preset);
|
||||
}
|
||||
|
||||
params[count].meta = uni_stream->codec_cfg.meta;
|
||||
params[count].meta_len = uni_stream->codec_cfg.meta_len;
|
||||
stream_params[param.count].meta = uni_stream->codec_cfg.meta;
|
||||
stream_params[param.count].meta_len = uni_stream->codec_cfg.meta_len;
|
||||
|
||||
count++;
|
||||
param.count++;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
@ -409,7 +407,7 @@ static int cmd_cap_initiator_unicast_update(const struct shell *sh, size_t argc,
|
|||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
params[count].stream = stream;
|
||||
stream_params[param.count].stream = stream;
|
||||
|
||||
if (ep_info.dir == BT_AUDIO_DIR_SINK) {
|
||||
copy_unicast_stream_preset(uni_stream, default_sink_preset);
|
||||
|
@ -417,22 +415,25 @@ static int cmd_cap_initiator_unicast_update(const struct shell *sh, size_t argc,
|
|||
copy_unicast_stream_preset(uni_stream, default_source_preset);
|
||||
}
|
||||
|
||||
params[count].meta = uni_stream->codec_cfg.meta;
|
||||
params[count].meta_len = uni_stream->codec_cfg.meta_len;
|
||||
stream_params[param.count].meta = uni_stream->codec_cfg.meta;
|
||||
stream_params[param.count].meta_len = uni_stream->codec_cfg.meta_len;
|
||||
|
||||
count++;
|
||||
param.count++;
|
||||
}
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
if (param.count == 0) {
|
||||
shell_error(sh, "No streams to update");
|
||||
|
||||
return -ENOEXEC;
|
||||
}
|
||||
|
||||
shell_print(sh, "Updating %zu streams", count);
|
||||
param.stream_params = stream_params;
|
||||
param.type = BT_CAP_SET_TYPE_AD_HOC;
|
||||
|
||||
err = bt_cap_initiator_unicast_audio_update(params, count);
|
||||
shell_print(sh, "Updating %zu streams", param.count);
|
||||
|
||||
err = bt_cap_initiator_unicast_audio_update(¶m);
|
||||
if (err != 0) {
|
||||
shell_print(sh, "Failed to update unicast audio: %d", err);
|
||||
}
|
||||
|
|
|
@ -341,8 +341,9 @@ static uint8_t btp_cap_unicast_audio_update(const void *cmd, uint16_t cmd_len,
|
|||
int err;
|
||||
const uint8_t *data_ptr;
|
||||
const struct btp_cap_unicast_audio_update_cmd *cp = cmd;
|
||||
struct bt_cap_unicast_audio_update_param stream_params[
|
||||
ARRAY_SIZE(btp_csip_set_members) * BTP_BAP_UNICAST_MAX_STREAMS_COUNT];
|
||||
struct bt_cap_unicast_audio_update_stream_param
|
||||
stream_params[ARRAY_SIZE(btp_csip_set_members) * BTP_BAP_UNICAST_MAX_STREAMS_COUNT];
|
||||
struct bt_cap_unicast_audio_update_param param = {0};
|
||||
|
||||
LOG_DBG("");
|
||||
|
||||
|
@ -357,7 +358,7 @@ static uint8_t btp_cap_unicast_audio_update(const void *cmd, uint16_t cmd_len,
|
|||
struct bt_conn *conn;
|
||||
struct btp_cap_unicast_audio_update_data *update_data =
|
||||
(struct btp_cap_unicast_audio_update_data *)data_ptr;
|
||||
struct bt_cap_unicast_audio_update_param *param = &stream_params[i];
|
||||
struct bt_cap_unicast_audio_update_stream_param *stream_param = &stream_params[i];
|
||||
|
||||
conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, &update_data->address);
|
||||
if (!conn) {
|
||||
|
@ -379,15 +380,19 @@ static uint8_t btp_cap_unicast_audio_update(const void *cmd, uint16_t cmd_len,
|
|||
return BTP_STATUS_FAILED;
|
||||
}
|
||||
|
||||
param->stream = &u_stream->audio_stream.cap_stream;
|
||||
param->meta_len = update_data->metadata_ltvs_len;
|
||||
param->meta = update_data->metadata_ltvs;
|
||||
stream_param->stream = &u_stream->audio_stream.cap_stream;
|
||||
stream_param->meta_len = update_data->metadata_ltvs_len;
|
||||
stream_param->meta = update_data->metadata_ltvs;
|
||||
|
||||
data_ptr = ((uint8_t *)update_data) + param->meta_len +
|
||||
data_ptr = ((uint8_t *)update_data) + stream_param->meta_len +
|
||||
sizeof(struct btp_cap_unicast_audio_update_data);
|
||||
}
|
||||
|
||||
err = bt_cap_initiator_unicast_audio_update(stream_params, cp->stream_count);
|
||||
param.count = cp->stream_count;
|
||||
param.stream_params = stream_params;
|
||||
param.type = BT_CAP_SET_TYPE_AD_HOC;
|
||||
|
||||
err = bt_cap_initiator_unicast_audio_update(¶m);
|
||||
if (err != 0) {
|
||||
LOG_ERR("Failed to start unicast audio: %d", err);
|
||||
|
||||
|
|
|
@ -663,30 +663,36 @@ static void unicast_audio_update_inval(void)
|
|||
{
|
||||
struct bt_audio_codec_cfg invalid_codec = BT_AUDIO_CODEC_LC3_CONFIG_16_2(
|
||||
BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_MEDIA);
|
||||
struct bt_cap_unicast_audio_update_param param;
|
||||
struct bt_cap_unicast_audio_update_stream_param stream_params[1] = {0};
|
||||
struct bt_cap_unicast_audio_update_param param = {0};
|
||||
int err;
|
||||
|
||||
param.stream = &unicast_client_sink_streams[0];
|
||||
param.meta = unicast_preset_16_2_1.codec_cfg.meta;
|
||||
param.meta_len = unicast_preset_16_2_1.codec_cfg.meta_len;
|
||||
stream_params[0].stream = &unicast_client_sink_streams[0];
|
||||
stream_params[0].meta = unicast_preset_16_2_1.codec_cfg.meta;
|
||||
stream_params[0].meta_len = unicast_preset_16_2_1.codec_cfg.meta_len;
|
||||
param.count = ARRAY_SIZE(stream_params);
|
||||
param.stream_params = stream_params;
|
||||
param.type = BT_CAP_SET_TYPE_AD_HOC;
|
||||
|
||||
err = bt_cap_initiator_unicast_audio_update(NULL, 1);
|
||||
err = bt_cap_initiator_unicast_audio_update(NULL);
|
||||
if (err == 0) {
|
||||
FAIL("bt_cap_initiator_unicast_audio_update with NULL params did not fail\n");
|
||||
return;
|
||||
}
|
||||
|
||||
err = bt_cap_initiator_unicast_audio_update(¶m, 0);
|
||||
param.count = 0U;
|
||||
err = bt_cap_initiator_unicast_audio_update(¶m);
|
||||
if (err == 0) {
|
||||
FAIL("bt_cap_initiator_unicast_audio_update with 0 param count did not fail\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* Clear metadata so that it does not contain the mandatory stream context */
|
||||
param.count = ARRAY_SIZE(stream_params);
|
||||
memset(&invalid_codec.meta, 0, sizeof(invalid_codec.meta));
|
||||
param.meta = invalid_codec.meta;
|
||||
stream_params[0].meta = invalid_codec.meta;
|
||||
|
||||
err = bt_cap_initiator_unicast_audio_update(¶m, 1);
|
||||
err = bt_cap_initiator_unicast_audio_update(¶m);
|
||||
if (err == 0) {
|
||||
FAIL("bt_cap_initiator_unicast_audio_update with invalid Codec metadata did not "
|
||||
"fail\n");
|
||||
|
@ -696,7 +702,8 @@ static void unicast_audio_update_inval(void)
|
|||
|
||||
static void unicast_audio_update(void)
|
||||
{
|
||||
struct bt_cap_unicast_audio_update_param param[2];
|
||||
struct bt_cap_unicast_audio_update_stream_param stream_params[2] = {0};
|
||||
struct bt_cap_unicast_audio_update_param param = {0};
|
||||
uint8_t new_meta[] = {
|
||||
3,
|
||||
BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT,
|
||||
|
@ -707,17 +714,21 @@ static void unicast_audio_update(void)
|
|||
};
|
||||
int err;
|
||||
|
||||
param[0].stream = &unicast_client_sink_streams[0];
|
||||
param[0].meta = new_meta;
|
||||
param[0].meta_len = ARRAY_SIZE(new_meta);
|
||||
stream_params[0].stream = &unicast_client_sink_streams[0];
|
||||
stream_params[0].meta = new_meta;
|
||||
stream_params[0].meta_len = ARRAY_SIZE(new_meta);
|
||||
|
||||
param[1].stream = &unicast_client_source_streams[0];
|
||||
param[1].meta = new_meta;
|
||||
param[1].meta_len = ARRAY_SIZE(new_meta);
|
||||
stream_params[1].stream = &unicast_client_source_streams[0];
|
||||
stream_params[1].meta = new_meta;
|
||||
stream_params[1].meta_len = ARRAY_SIZE(new_meta);
|
||||
|
||||
param.count = ARRAY_SIZE(stream_params);
|
||||
param.stream_params = stream_params;
|
||||
param.type = BT_CAP_SET_TYPE_AD_HOC;
|
||||
|
||||
UNSET_FLAG(flag_updated);
|
||||
|
||||
err = bt_cap_initiator_unicast_audio_update(param, ARRAY_SIZE(param));
|
||||
err = bt_cap_initiator_unicast_audio_update(¶m);
|
||||
if (err != 0) {
|
||||
FAIL("Failed to update unicast audio: %d\n", err);
|
||||
return;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue