From 5018c40edbb2c75c23ca54df5b7d907d80450a0a Mon Sep 17 00:00:00 2001 From: Luiz Augusto von Dentz Date: Mon, 16 Jun 2025 09:47:40 -0400 Subject: [PATCH] shared/bap: Fix not using metadata set on stream->meta bt_bap_stream_metadata maybe used before enabling state in which case it will be store in the stream->meta so when processing bt_bap_stream_enable if there is no metadata set use the existing one set in stream->meta. --- src/shared/bap.c | 47 +++++++++++++++++++++++++++++++++++++---------- unit/test-bap.c | 12 ++++++++---- 2 files changed, 45 insertions(+), 14 deletions(-) diff --git a/src/shared/bap.c b/src/shared/bap.c index 1c15a4ecb..625f5bf7d 100644 --- a/src/shared/bap.c +++ b/src/shared/bap.c @@ -1959,6 +1959,17 @@ static unsigned int bap_ucast_qos(struct bt_bap_stream *stream, return req->id; } +static void bap_stream_get_context(size_t i, uint8_t l, uint8_t t, uint8_t *v, + void *user_data) +{ + bool *found = user_data; + + if (!v) + return; + + *found = true; +} + static unsigned int bap_stream_metadata(struct bt_bap_stream *stream, uint8_t op, struct iovec *data, bt_bap_stream_func_t func, @@ -1967,11 +1978,7 @@ static unsigned int bap_stream_metadata(struct bt_bap_stream *stream, struct iovec iov[2]; struct bt_ascs_metadata meta; struct bt_bap_req *req; - struct metadata { - uint8_t len; - uint8_t type; - uint8_t data[2]; - } ctx = LTV(0x02, 0x01, 0x00); /* Context = Unspecified */ + uint16_t value = cpu_to_le16(0x0001); /* Context = Unspecified */ memset(&meta, 0, sizeof(meta)); @@ -1980,13 +1987,33 @@ static unsigned int bap_stream_metadata(struct bt_bap_stream *stream, iov[0].iov_base = &meta; iov[0].iov_len = sizeof(meta); - if (data) - iov[1] = *data; - else { - iov[1].iov_base = &ctx; - iov[1].iov_len = sizeof(ctx); + if (data) { + util_iov_free(stream->meta, 1); + stream->meta = util_iov_dup(data, 1); } + /* Check if metadata contains an Audio Context */ + if (stream->meta) { + uint8_t type = 0x02; + bool found = false; + + util_ltv_foreach(stream->meta->iov_base, + stream->meta->iov_len, &type, + bap_stream_get_context, &found); + if (!found) + util_ltv_push(stream->meta, sizeof(value), type, + &value); + } + + /* If metadata doesn't contain an Audio Context, add one */ + if (!stream->meta) { + stream->meta = new0(struct iovec, 1); + util_ltv_push(stream->meta, sizeof(value), 0x02, &value); + } + + iov[1].iov_base = stream->meta->iov_base; + iov[1].iov_len = stream->meta->iov_len; + meta.len = iov[1].iov_len; req = bap_req_new(stream, op, iov, 2, func, user_data); diff --git a/unit/test-bap.c b/unit/test-bap.c index b32c3e96a..f65df69ef 100644 --- a/unit/test-bap.c +++ b/unit/test-bap.c @@ -3833,10 +3833,12 @@ static struct test_config cfg_snk_metadata = { * Data: 0103000000 */ #define ASE_SNK_METADATA \ - IOV_DATA(0x52, 0x22, 0x00, 0x07, 0x01, 0x01, 0x00), \ + IOV_DATA(0x52, 0x22, 0x00, 0x07, 0x01, 0x01, 0x04, 0x03, 0x02, 0x01, \ + 0x00), \ IOV_DATA(0x1b, 0x22, 0x00, 0x07, 0x01, 0x01, 0x00, 0x00), \ IOV_NULL, \ - IOV_DATA(0x1b, 0x16, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00) + IOV_DATA(0x1b, 0x16, 0x00, 0x01, 0x03, 0x00, 0x00, 0x04, 0x03, 0x02, \ + 0x01, 0x00) #define SCC_SNK_METADATA \ SCC_SNK_ENABLE, \ @@ -3861,10 +3863,12 @@ static struct test_config cfg_src_metadata = { * Data: 0303000000 */ #define ASE_SRC_METADATA(_state) \ - IOV_DATA(0x52, 0x22, 0x00, 0x07, 0x01, 0x03, 0x00), \ + IOV_DATA(0x52, 0x22, 0x00, 0x07, 0x01, 0x03, 0x04, 0x03, 0x02, 0x01, \ + 0x00), \ IOV_DATA(0x1b, 0x22, 0x00, 0x07, 0x01, 0x03, 0x00, 0x00), \ IOV_NULL, \ - IOV_DATA(0x1b, 0x1c, 0x00, 0x03, _state, 0x00, 0x00, 0x00) + IOV_DATA(0x1b, 0x1c, 0x00, 0x03, _state, 0x00, 0x00, 0x04, 0x03, 0x02, \ + 0x01, 0x00) #define SCC_SRC_METADATA \ SCC_SRC_ENABLE, \ ASE_SRC_METADATA(0x03) -- 2.47.3