diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index 2386d50235e0f19..0ce3335447d3b55 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -199,7 +199,7 @@ struct bt_audio_codec_data { } /** - * @brief Helper to declare @ref bt_audio_codec_cfg or @ref bt_audio_codec_cap structure + * @brief Helper to declare @ref bt_audio_codec_cfg * * @param _id Codec ID * @param _cid Company ID @@ -207,18 +207,40 @@ struct bt_audio_codec_data { * @param _data Codec Specific Data in LVT format * @param _meta Codec Specific Metadata in LVT format */ -#define BT_AUDIO_CODEC(_id, _cid, _vid, _data, _meta) \ - { \ - /* Use HCI data path as default, can be overwritten by application */ \ - .path_id = BT_ISO_DATA_PATH_HCI, \ - .id = _id, \ - .cid = _cid, \ - .vid = _vid, \ - .data_count = ARRAY_SIZE(((struct bt_audio_codec_data[])_data)), \ - .data = _data, \ - .meta_count = ARRAY_SIZE(((struct bt_audio_codec_data[])_meta)), \ - .meta = _meta, \ - } +#define BT_AUDIO_CODEC_CFG(_id, _cid, _vid, _data, _meta) \ + ((struct bt_audio_codec_cfg){ \ + /* Use HCI data path as default, can be overwritten by application */ \ + .path_id = BT_ISO_DATA_PATH_HCI, \ + .id = _id, \ + .cid = _cid, \ + .vid = _vid, \ + .data_count = ARRAY_SIZE(((struct bt_audio_codec_data[])_data)), \ + .data = _data, \ + .meta_count = ARRAY_SIZE(((struct bt_audio_codec_data[])_meta)), \ + .meta = _meta, \ + }) + +/** + * @brief Helper to declare @ref bt_audio_codec_cap structure + * + * @param _id Codec ID + * @param _cid Company ID + * @param _vid Vendor ID + * @param _data Codec Specific Data in LVT format + * @param _meta Codec Specific Metadata in LVT format + */ +#define BT_AUDIO_CODEC_CAP(_id, _cid, _vid, _data, _meta) \ + ((struct bt_audio_codec_cap){ \ + /* Use HCI data path as default, can be overwritten by application */ \ + .path_id = BT_ISO_DATA_PATH_HCI, \ + .id = (_id), \ + .cid = (_cid), \ + .vid = (_vid), \ + .data_len = sizeof((uint8_t[])_data), \ + .data = _data, \ + .meta_len = sizeof((uint8_t[])_meta), \ + .meta = _meta, \ + }) /** @brief Location values for BT Audio. * @@ -302,18 +324,18 @@ struct bt_audio_codec_cap { uint16_t cid; /** Codec Company Vendor ID */ uint16_t vid; -#if defined(CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_COUNT) +#if CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 /** Codec Specific Capabilities Data count */ - size_t data_count; + size_t data_len; /** Codec Specific Capabilities Data */ - struct bt_audio_codec_data data[CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_COUNT]; -#endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_COUNT */ -#if defined(CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_COUNT) + uint8_t data[CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE]; +#endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 */ +#if defined(CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE) /** Codec Specific Capabilities Metadata count */ - size_t meta_count; + size_t meta_len; /** Codec Specific Capabilities Metadata */ - struct bt_audio_codec_data meta[CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_COUNT]; -#endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_COUNT */ + uint8_t meta[CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE]; +#endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE */ }; /** @brief Codec specific configuration structure. */ diff --git a/include/zephyr/bluetooth/audio/lc3.h b/include/zephyr/bluetooth/audio/lc3.h index cde496df2c49e12..50fb7792e26f1b3 100644 --- a/include/zephyr/bluetooth/audio/lc3.h +++ b/include/zephyr/bluetooth/audio/lc3.h @@ -254,38 +254,46 @@ enum bt_audio_codec_config_type { * If the flags argument is != 1 it will evaluate to the third argument which inserts a LTV * entry for the max_frames_per_sdu value. */ -#define BT_AUDIO_CODEC_LC3_DATA(_freq, _duration, _chan_count, _len_min, _len_max, \ +#define BT_AUDIO_CODEC_CAP_LC3_DATA(_freq, _duration, _chan_count, _len_min, _len_max, \ _max_frames_per_sdu) \ { \ - BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_LC3_FREQ, BT_BYTES_LIST_LE16(_freq)), \ - BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_LC3_DURATION, _duration), \ - BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_LC3_CHAN_COUNT, _chan_count), \ - BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_LC3_FRAME_LEN, \ - BT_BYTES_LIST_LE16(_len_min), \ - BT_BYTES_LIST_LE16(_len_max)) \ + 3, BT_AUDIO_CODEC_LC3_FREQ, BT_BYTES_LIST_LE16(_freq), \ + 2, BT_AUDIO_CODEC_LC3_DURATION, (_duration), \ + 2, BT_AUDIO_CODEC_LC3_CHAN_COUNT, (_chan_count), \ + 5, BT_AUDIO_CODEC_LC3_FRAME_LEN, BT_BYTES_LIST_LE16(_len_min), \ + BT_BYTES_LIST_LE16(_len_max), \ COND_CODE_1(_max_frames_per_sdu, (), \ - (, BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_LC3_FRAME_COUNT, \ - _max_frames_per_sdu))) \ + (2, BT_AUDIO_CODEC_LC3_FRAME_COUNT, (_max_frames_per_sdu))), \ } /** * @brief Helper to declare LC3 codec metadata */ -#define BT_AUDIO_CODEC_LC3_META(_prefer_context) \ +#define BT_AUDIO_CODEC_CAP_LC3_META(_prefer_context) \ { \ - BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PREF_CONTEXT, \ - BT_BYTES_LIST_LE16(_prefer_context)) \ + 3, BT_AUDIO_METADATA_TYPE_PREF_CONTEXT, BT_BYTES_LIST_LE16(_prefer_context) \ } /** - * @brief Helper to declare LC3 codec + * @brief Helper to declare LC3 codec + * + * @param _cid Company ID + * @param _vid Vendor ID + * @param _freq Supported Sampling Frequencies bitfield (see BT_AUDIO_CODEC_LC3_FREQ_*) + * @param _duration Supported Frame Durations bitfield (see BT_AUDIO_CODEC_LC3_DURATION_*) + * @param _chan_count Supported channels (see @ref BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT) + * @param _len_min Minimum number of octets supported per codec frame + * @param _len_max Maximum number of octets supported per codec frame + * @param _max_frames_per_sdu Supported maximum codec frames per SDU + * @param _prefer_context Preferred contexts (@ref bt_audio_context) + * */ -#define BT_AUDIO_CODEC_LC3(_freq, _duration, _chan_count, _len_min, _len_max, _max_frames_per_sdu, \ - _prefer_context) \ - BT_AUDIO_CODEC(BT_AUDIO_CODEC_LC3_ID, 0x0000, 0x0000, \ - BT_AUDIO_CODEC_LC3_DATA(_freq, _duration, _chan_count, _len_min, _len_max, \ - _max_frames_per_sdu), \ - BT_AUDIO_CODEC_LC3_META(_prefer_context)) +#define BT_AUDIO_CODEC_CAP_LC3(_cid, _vid, _freq, _duration, _chan_count, _len_min, _len_max, \ + _max_frames_per_sdu, _prefer_context) \ + BT_AUDIO_CODEC_CAP(BT_AUDIO_CODEC_LC3_ID, _cid, _vid, \ + BT_AUDIO_CODEC_CAP_LC3_DATA(_freq, _duration, _chan_count, _len_min, \ + _len_max, _max_frames_per_sdu), \ + BT_AUDIO_CODEC_CAP_LC3_META(_prefer_context)) /** * @brief Helper to declare LC3 codec data configuration @@ -332,7 +340,7 @@ enum bt_audio_codec_config_type { * @param _stream_context Stream context (BT_AUDIO_CONTEXT_*) */ #define BT_AUDIO_CODEC_LC3_CONFIG(_freq, _duration, _loc, _len, _frames_per_sdu, _stream_context) \ - BT_AUDIO_CODEC( \ + BT_AUDIO_CODEC_CFG( \ BT_AUDIO_CODEC_LC3_ID, 0x0000, 0x0000, \ BT_AUDIO_CODEC_LC3_CONFIG_DATA(_freq, _duration, _loc, _len, _frames_per_sdu), \ BT_AUDIO_CODEC_LC3_CONFIG_META(_stream_context)) diff --git a/samples/bluetooth/broadcast_audio_sink/src/main.c b/samples/bluetooth/broadcast_audio_sink/src/main.c index 4a017b6197d65b4..ea1ceb95c85199e 100644 --- a/samples/bluetooth/broadcast_audio_sink/src/main.c +++ b/samples/bluetooth/broadcast_audio_sink/src/main.c @@ -45,8 +45,10 @@ static struct bt_bap_stream *streams_p[ARRAY_SIZE(streams)]; static struct bt_conn *broadcast_assistant_conn; static struct bt_le_ext_adv *ext_adv; -static struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_LC3_CONFIG_16_2( - BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); +static struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( + 0x0000, 0x0000, BT_AUDIO_CODEC_LC3_FREQ_16KHZ | BT_AUDIO_CODEC_LC3_FREQ_24KHZ, + BT_AUDIO_CODEC_LC3_DURATION_10, BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1), 40u, 60u, 1u, + (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); /* Create a mask for the maximum BIS we can sync to using the number of streams * we have. We add an additional 1 since the bis indexes start from 1 and not diff --git a/samples/bluetooth/hap_ha/src/bap_unicast_sr.c b/samples/bluetooth/hap_ha/src/bap_unicast_sr.c index 2ee7faa40b38b5e..7d8e114ad883836 100644 --- a/samples/bluetooth/hap_ha/src/bap_unicast_sr.c +++ b/samples/bluetooth/hap_ha/src/bap_unicast_sr.c @@ -21,8 +21,8 @@ NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_ASCS_ASE_SRC_COUNT, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); -static struct bt_audio_codec_cap lc3_codec_cap = BT_AUDIO_CODEC_LC3( - BT_AUDIO_CODEC_LC3_FREQ_16KHZ | BT_AUDIO_CODEC_LC3_FREQ_24KHZ, +static struct bt_audio_codec_cap lc3_codec_cap = BT_AUDIO_CODEC_CAP_LC3( + 0x0000, 0x0000, BT_AUDIO_CODEC_LC3_FREQ_16KHZ | BT_AUDIO_CODEC_LC3_FREQ_24KHZ, BT_AUDIO_CODEC_LC3_DURATION_10, BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1), 40u, 60u, 1u, (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); diff --git a/samples/bluetooth/tmap_central/src/cap_initiator.c b/samples/bluetooth/tmap_central/src/cap_initiator.c index bfe97175a04e611..835b95edea3febc 100644 --- a/samples/bluetooth/tmap_central/src/cap_initiator.c +++ b/samples/bluetooth/tmap_central/src/cap_initiator.c @@ -180,32 +180,43 @@ static void print_hex(const uint8_t *ptr, size_t len) } } -static void print_codec_capabilities(const struct bt_audio_codec_cap *codec_cap) +static void print_ltv_elem(const char *str, uint8_t type, uint8_t value_len, const uint8_t *value, + size_t cnt) { - printk("codec_cap 0x%02x cid 0x%04x vid 0x%04x count %u\n", codec_cap->id, codec_cap->cid, - codec_cap->vid, codec_cap->data_count); - - for (size_t i = 0; i < codec_cap->data_count; i++) { - printk("data #%zu: type 0x%02x len %u\n", i, codec_cap->data[i].data.type, - codec_cap->data[i].data.data_len); - print_hex(codec_cap->data[i].data.data, - codec_cap->data[i].data.data_len - sizeof(codec_cap->data[i].data.type)); - printk("\n"); - } + printk("%s #%zu: type 0x%02x value_len %u\n", str, cnt, type, value_len); + print_hex(value, value_len); + printk("\n"); +} - for (size_t i = 0; i < codec_cap->meta_count; i++) { - printk("meta #%zu: type 0x%02x len %u\n", i, codec_cap->meta[i].data.type, - codec_cap->meta[i].data.data_len); - print_hex(codec_cap->meta[i].data.data, - codec_cap->meta[i].data.data_len - sizeof(codec_cap->meta[i].data.type)); - printk("\n"); +static void print_ltv_array(const char *str, const uint8_t *ltv_data, size_t ltv_data_len) +{ + size_t cnt = 0U; + + for (size_t i = 0U; i < ltv_data_len; i++) { + const uint8_t len = ltv_data[i++]; + const uint8_t type = ltv_data[i++]; + const uint8_t *value = <v_data[i]; + const uint8_t value_len = len - sizeof(type); + + print_ltv_elem(str, type, value_len, value, cnt++); + i += value_len; } } static void print_remote_codec(const struct bt_audio_codec_cap *codec_cap, enum bt_audio_dir dir) { - printk("codec_cap %p dir 0x%02x\n", codec_cap, dir); - print_codec_capabilities(codec_cap); + printk("codec id 0x%02x cid 0x%04x vid 0x%04x count %u\n", codec_cap->id, codec_cap->cid, + codec_cap->vid, codec_cap->data_len); + + if (codec_cap->id == BT_AUDIO_CODEC_LC3_ID) { + print_ltv_array("data", codec_cap->data, codec_cap->data_len); + } else { /* If not LC3, we cannot assume it's LTV */ + printk("data: "); + print_hex(codec_cap->data, codec_cap->data_len); + printk("\n"); + } + + print_ltv_array("meta", codec_cap->meta, codec_cap->meta_len); } static void add_remote_sink(struct bt_bap_ep *ep) diff --git a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c index 35707cdbd6c0b16..50a326c3783ea44 100644 --- a/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c +++ b/samples/bluetooth/tmap_peripheral/src/bap_unicast_sr.c @@ -24,11 +24,12 @@ #define AVAILABLE_SOURCE_CONTEXT CONFIG_BT_PACS_SRC_CONTEXT static struct bt_audio_codec_cap lc3_codec_cap = - BT_AUDIO_CODEC_LC3(BT_AUDIO_CODEC_LC3_FREQ_16KHZ | BT_AUDIO_CODEC_LC3_FREQ_32KHZ | - BT_AUDIO_CODEC_LC3_FREQ_48KHZ, - BT_AUDIO_CODEC_LC3_DURATION_7_5 | BT_AUDIO_CODEC_LC3_DURATION_10, - BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(2), 30, 155u, 1u, - (CONFIG_BT_PACS_SNK_CONTEXT | CONFIG_BT_PACS_SRC_CONTEXT)); + BT_AUDIO_CODEC_CAP_LC3(0x0000, 0x0000, + BT_AUDIO_CODEC_LC3_FREQ_16KHZ | BT_AUDIO_CODEC_LC3_FREQ_32KHZ | + BT_AUDIO_CODEC_LC3_FREQ_48KHZ, + BT_AUDIO_CODEC_LC3_DURATION_7_5 | BT_AUDIO_CODEC_LC3_DURATION_10, + BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(2), 30, 155u, 1u, + (CONFIG_BT_PACS_SNK_CONTEXT | CONFIG_BT_PACS_SRC_CONTEXT)); static struct bt_conn *default_conn; static struct bt_bap_stream streams[CONFIG_BT_ASCS_ASE_SNK_COUNT + CONFIG_BT_ASCS_ASE_SRC_COUNT]; diff --git a/samples/bluetooth/unicast_audio_client/src/main.c b/samples/bluetooth/unicast_audio_client/src/main.c index db3cd03efbab6c8..435debdf056a99f 100644 --- a/samples/bluetooth/unicast_audio_client/src/main.c +++ b/samples/bluetooth/unicast_audio_client/src/main.c @@ -353,26 +353,43 @@ static void print_hex(const uint8_t *ptr, size_t len) } } -static void print_codec_cap(const struct bt_audio_codec_cap *codec_cap) +static void print_ltv_elem(const char *str, uint8_t type, uint8_t value_len, const uint8_t *value, + size_t cnt) { - printk("codec 0x%02x cid 0x%04x vid 0x%04x count %u\n", codec_cap->id, codec_cap->cid, - codec_cap->vid, codec_cap->data_count); - - for (size_t i = 0; i < codec_cap->data_count; i++) { - printk("data #%zu: type 0x%02x len %u\n", i, codec_cap->data[i].data.type, - codec_cap->data[i].data.data_len); - print_hex(codec_cap->data[i].data.data, - codec_cap->data[i].data.data_len - sizeof(codec_cap->data[i].data.type)); - printk("\n"); + printk("%s #%zu: type 0x%02x value_len %u\n", str, cnt, type, value_len); + print_hex(value, value_len); + printk("\n"); +} + +static void print_ltv_array(const char *str, const uint8_t *ltv_data, size_t ltv_data_len) +{ + size_t cnt = 0U; + + for (size_t i = 0U; i < ltv_data_len; i++) { + const uint8_t len = ltv_data[i++]; + const uint8_t type = ltv_data[i++]; + const uint8_t *value = <v_data[i]; + const uint8_t value_len = len - sizeof(type); + + print_ltv_elem(str, type, value_len, value, cnt++); + i += value_len; } +} - for (size_t i = 0; i < codec_cap->meta_count; i++) { - printk("meta #%zu: type 0x%02x len %u\n", i, codec_cap->meta[i].data.type, - codec_cap->meta[i].data.data_len); - print_hex(codec_cap->meta[i].data.data, - codec_cap->meta[i].data.data_len - sizeof(codec_cap->meta[i].data.type)); +static void print_codec_cap(const struct bt_audio_codec_cap *codec_cap) +{ + printk("codec id 0x%02x cid 0x%04x vid 0x%04x count %u\n", codec_cap->id, codec_cap->cid, + codec_cap->vid, codec_cap->data_len); + + if (codec_cap->id == BT_AUDIO_CODEC_LC3_ID) { + print_ltv_array("data", codec_cap->data, codec_cap->data_len); + } else { /* If not LC3, we cannot assume it's LTV */ + printk("data: "); + print_hex(codec_cap->data, codec_cap->data_len); printk("\n"); } + + print_ltv_array("meta", codec_cap->meta, codec_cap->meta_len); } static bool check_audio_support_and_connect(struct bt_data *data, diff --git a/samples/bluetooth/unicast_audio_server/src/main.c b/samples/bluetooth/unicast_audio_server/src/main.c index 32268c951784959..2523be31e0eb109 100644 --- a/samples/bluetooth/unicast_audio_server/src/main.c +++ b/samples/bluetooth/unicast_audio_server/src/main.c @@ -33,10 +33,10 @@ NET_BUF_POOL_FIXED_DEFINE(tx_pool, CONFIG_BT_ASCS_ASE_SRC_COUNT, BT_ISO_SDU_BUF_SIZE(CONFIG_BT_ISO_TX_MTU), CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL); -static struct bt_audio_codec_cap lc3_codec_cap = - BT_AUDIO_CODEC_LC3(BT_AUDIO_CODEC_LC3_FREQ_ANY, BT_AUDIO_CODEC_LC3_DURATION_10, - BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1), 40u, 120u, 1u, - (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); +static struct bt_audio_codec_cap lc3_codec_cap = BT_AUDIO_CODEC_CAP_LC3( + 0x0000, 0x0000, BT_AUDIO_CODEC_LC3_FREQ_ANY, BT_AUDIO_CODEC_LC3_DURATION_10, + BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1), 40u, 120u, 1u, + (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); static struct bt_conn *default_conn; static struct k_work_delayable audio_send_work; diff --git a/subsys/bluetooth/audio/Kconfig.bap b/subsys/bluetooth/audio/Kconfig.bap index 4bb2361dc0a5634..845b681a2a94279 100644 --- a/subsys/bluetooth/audio/Kconfig.bap +++ b/subsys/bluetooth/audio/Kconfig.bap @@ -46,14 +46,6 @@ config BT_AUDIO_CODEC_CFG_MAX_DATA_COUNT This option defines the maximum number of LTV entries a codec can store. -config BT_AUDIO_CODEC_CAP_MAX_DATA_COUNT - int "Codec Capabilities Data Count" - default 5 - range 1 128 - help - This option defines the maximum number of LTV entries a codec can - store. - config BT_AUDIO_CODEC_MAX_DATA_LEN int "Codec Capabilities Data Length" default 4 @@ -70,13 +62,19 @@ config BT_AUDIO_CODEC_CFG_MAX_METADATA_COUNT This option defines the maximum number of LTV entries a metadata can store. -config BT_AUDIO_CODEC_CAP_MAX_METADATA_COUNT - int "Codec Capabilities Metadata Count" - default 2 - range 1 128 +config BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE + int "Codec Capabilities Data Size" + default 19 + range 0 255 help - This option defines the maximum number of LTV entries a metadata can - store. + Number of octets to support for Codec Specific Capabilities data. + +config BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE + int "Codec Capabilities Metadata Size" + default 4 + range 0 255 + help + Number of octets to support for Codec Specific Capabilities metadata. if BT_BAP_UNICAST_CLIENT config BT_BAP_UNICAST_CLIENT_GROUP_COUNT diff --git a/subsys/bluetooth/audio/bap_unicast_client.c b/subsys/bluetooth/audio/bap_unicast_client.c index 53b4ca3ef4d49e9..2b8c781e5ce8798 100644 --- a/subsys/bluetooth/audio/bap_unicast_client.c +++ b/subsys/bluetooth/audio/bap_unicast_client.c @@ -1172,27 +1172,10 @@ static bool unicast_client_codec_config_cfg_store(struct bt_data *data, void *us return false; } -static bool unicast_client_codec_config_cap_store(struct bt_data *data, void *user_data) +static bool valid_ltv_cb(struct bt_data *data, void *user_data) { - struct bt_audio_codec_cap *codec_cap = user_data; - struct bt_audio_codec_data *cdata; - - if (codec_cap->data_count >= ARRAY_SIZE(codec_cap->data)) { - LOG_ERR("No slot available for Codec Config"); - return false; - } - - cdata = &codec_cap->data[codec_cap->data_count]; - - LOG_DBG("#%u type 0x%02x len %u", codec_cap->data_count, data->type, data->data_len); - - if (unicast_client_codec_data_store(data, cdata)) { - codec_cap->data_count++; - - return true; - } - - return false; + /* just return true to continue parsing as bt_data_parse will validate for us */ + return true; } static int unicast_client_ep_set_codec_cfg(struct bt_bap_ep *ep, uint8_t id, uint16_t cid, @@ -1242,44 +1225,66 @@ static int unicast_client_ep_set_codec_cfg(struct bt_bap_ep *ep, uint8_t id, uin } static int unicast_client_set_codec_cap(uint8_t id, uint16_t cid, uint16_t vid, void *data, - uint8_t len, struct bt_audio_codec_cap *codec_cap) + uint8_t data_len, void *meta, uint8_t meta_len, + struct bt_audio_codec_cap *codec_cap) { - struct net_buf_simple ad; + struct net_buf_simple buf; if (!codec_cap) { return -EINVAL; } - LOG_DBG("codec id 0x%02x cid 0x%04x vid 0x%04x len %u", id, cid, vid, len); + LOG_DBG("codec id 0x%02x cid 0x%04x vid 0x%04x data_len %u meta_len %u", id, cid, vid, + data_len, meta_len); + + /* Reset current data */ + (void)memset(codec_cap, 0, sizeof(*codec_cap)); codec_cap->id = id; codec_cap->cid = cid; codec_cap->vid = vid; - /* Reset current metadata */ - codec_cap->data_count = 0; - (void)memset(codec_cap->data, 0, sizeof(codec_cap->data)); + if (data_len > 0U) { + if (data_len > sizeof(codec_cap->data)) { + return -ENOMEM; + } - if (!len) { - return 0; + net_buf_simple_init_with_data(&buf, data, data_len); + + /* If codec is LC3, then it shall be LTV encoded - We verify this before storing the + * data For any non-LC3 codecs, we cannot verify anything + */ + if (id == BT_AUDIO_CODEC_LC3_ID) { + bt_data_parse(&buf, valid_ltv_cb, codec_cap); + + /* Check if all entries could be parsed */ + if (buf.len) { + LOG_ERR("Unable to parse Codec capabilities: len %u", buf.len); + return -EINVAL; + } + } + memcpy(codec_cap->data, data, data_len); } - net_buf_simple_init_with_data(&ad, data, len); + if (meta_len > 0U) { + if (meta_len > sizeof(codec_cap->meta)) { + return -ENOMEM; + } - /* Parse LTV entries */ - bt_data_parse(&ad, unicast_client_codec_config_cap_store, codec_cap); + net_buf_simple_init_with_data(&buf, meta, meta_len); - /* Check if all entries could be parsed */ - if (ad.len) { - LOG_ERR("Unable to parse Codec Config: len %u", ad.len); - goto fail; + bt_data_parse(&buf, valid_ltv_cb, codec_cap); + + /* Check if all entries could be parsed */ + if (buf.len) { + LOG_ERR("Unable to parse Codec metadata: len %u", buf.len); + return -EINVAL; + } + + memcpy(codec_cap->meta, meta, meta_len); } return 0; - -fail: - (void)memset(codec_cap, 0, sizeof(*codec_cap)); - return -EINVAL; } static bool unicast_client_codec_cfg_metadata_store(struct bt_data *data, void *user_data) @@ -1355,75 +1360,6 @@ static int unicast_client_ep_set_metadata(struct bt_bap_ep *ep, void *data, uint return err; } -static bool unicast_client_codec_cap_metadata_store(struct bt_data *data, void *user_data) -{ - struct bt_audio_codec_cap *codec_cap = user_data; - struct bt_audio_codec_data *meta; - - if (codec_cap->meta_count >= ARRAY_SIZE(codec_cap->meta)) { - LOG_ERR("No slot available for Codec Config"); - return false; - } - - meta = &codec_cap->meta[codec_cap->meta_count]; - - LOG_DBG("#%u type 0x%02x len %u", codec_cap->meta_count, data->type, data->data_len); - - if (unicast_client_codec_data_store(data, meta)) { - codec_cap->meta_count++; - - return true; - } - - return false; -} - -static int unicast_client_set_codec_cap_metadata(void *data, uint8_t len, - struct bt_audio_codec_cap *codec_cap) -{ - struct net_buf_simple meta; - int err; - - if (!codec_cap) { - return -EINVAL; - } - - LOG_DBG("len %u codec_cap %p", len, codec_cap); - - /* Reset current metadata */ - codec_cap->meta_count = 0; - (void)memset(codec_cap->meta, 0, sizeof(codec_cap->meta)); - - if (!len) { - return 0; - } - - net_buf_simple_init_with_data(&meta, data, len); - - /* Parse LTV entries */ - bt_data_parse(&meta, unicast_client_codec_cap_metadata_store, codec_cap); - - /* Check if all entries could be parsed */ - if (meta.len) { - LOG_ERR("Unable to parse Metadata: len %u", meta.len); - err = -EINVAL; - - if (meta.len > 2) { - /* Value of the Metadata Type field in error */ - err = meta.data[2]; - } - - goto fail; - } - - return 0; - -fail: - codec_cap->meta_count = 0; - (void)memset(codec_cap->meta, 0, sizeof(codec_cap->meta)); - return err; -} - static uint8_t unicast_client_cp_notify(struct bt_conn *conn, struct bt_gatt_subscribe_params *params, const void *data, uint16_t length) @@ -4023,18 +3959,13 @@ static uint8_t unicast_client_read_func(struct bt_conn *conn, uint8_t err, if (unicast_client_set_codec_cap(pac_codec->id, sys_le16_to_cpu(pac_codec->cid), sys_le16_to_cpu(pac_codec->vid), cc_ltv, cc->len, - &codec_cap)) { + meta_ltv, meta->len, &codec_cap)) { LOG_ERR("Unable to parse Codec"); break; } - if (unicast_client_set_codec_cap_metadata(meta_ltv, meta->len, &codec_cap)) { - LOG_ERR("Unable to parse Codec Metadata"); - break; - } - - LOG_DBG("codec 0x%02x config count %u meta count %u ", codec_cap.id, - codec_cap.data_count, codec_cap.meta_count); + LOG_DBG("codec 0x%02x capabilities len %u meta len %u ", codec_cap.id, + codec_cap.data_len, codec_cap.meta_len); pac_record_cb(conn, &codec_cap); } diff --git a/subsys/bluetooth/audio/pacs.c b/subsys/bluetooth/audio/pacs.c index 8b5c664fa99ceed..5a690253bb2a3d1 100644 --- a/subsys/bluetooth/audio/pacs.c +++ b/subsys/bluetooth/audio/pacs.c @@ -75,31 +75,6 @@ static uint16_t src_supported_contexts = BT_AUDIO_CONTEXT_TYPE_PROHIBITED; static K_SEM_DEFINE(read_buf_sem, 1, 1); NET_BUF_SIMPLE_DEFINE_STATIC(read_buf, BT_ATT_MAX_ATTRIBUTE_LEN); -static ssize_t pac_data_add(struct net_buf_simple *buf, size_t count, - struct bt_audio_codec_data *data) -{ - size_t len = 0; - - for (size_t i = 0; i < count; i++) { - struct bt_pac_ltv *ltv; - struct bt_data *d = &data[i].data; - const size_t ltv_len = sizeof(*ltv) + d->data_len; - - if (net_buf_simple_tailroom(buf) < ltv_len) { - return -ENOMEM; - } - - ltv = net_buf_simple_add(buf, sizeof(*ltv)); - ltv->len = d->data_len + sizeof(ltv->type); - ltv->type = d->type; - net_buf_simple_add_mem(buf, d->data, d->data_len); - - len += ltv_len; - } - - return len; -} - struct pac_records_build_data { struct bt_pacs_read_rsp *rsp; struct net_buf_simple *buf; @@ -111,9 +86,7 @@ static bool build_pac_records(const struct bt_pacs_cap *cap, void *user_data) struct bt_audio_codec_cap *codec_cap = cap->codec_cap; struct net_buf_simple *buf = data->buf; struct net_buf_simple_state state; - struct bt_pac_ltv_data *cc, *meta; struct bt_pac_codec *pac_codec; - ssize_t len; net_buf_simple_save(buf, &state); @@ -126,31 +99,19 @@ static bool build_pac_records(const struct bt_pacs_cap *cap, void *user_data) pac_codec->cid = sys_cpu_to_le16(codec_cap->cid); pac_codec->vid = sys_cpu_to_le16(codec_cap->vid); - if (net_buf_simple_tailroom(buf) < sizeof(*cc)) { - goto fail; - } - - cc = net_buf_simple_add(buf, sizeof(*cc)); - - len = pac_data_add(buf, codec_cap->data_count, codec_cap->data); - if (len < 0 || len > UINT8_MAX) { - goto fail; - } - - cc->len = len; - - if (net_buf_simple_tailroom(buf) < sizeof(*meta)) { + if (net_buf_simple_tailroom(buf) < (sizeof(struct bt_pac_ltv_data) + codec_cap->data_len)) { goto fail; } - meta = net_buf_simple_add(buf, sizeof(*meta)); + net_buf_simple_add_u8(buf, codec_cap->data_len); + net_buf_simple_add_mem(buf, codec_cap->data, codec_cap->data_len); - len = pac_data_add(buf, codec_cap->meta_count, codec_cap->meta); - if (len < 0 || len > UINT8_MAX) { + if (net_buf_simple_tailroom(buf) < (sizeof(struct bt_pac_ltv_data) + codec_cap->meta_len)) { goto fail; } - meta->len = len; + net_buf_simple_add_u8(buf, codec_cap->meta_len); + net_buf_simple_add_mem(buf, codec_cap->meta, codec_cap->meta_len); data->rsp->num_pac++; diff --git a/subsys/bluetooth/audio/shell/audio.h b/subsys/bluetooth/audio/shell/audio.h index 4c3842616ed1006..e3c2db35c9ddbb4 100644 --- a/subsys/bluetooth/audio/shell/audio.h +++ b/subsys/bluetooth/audio/shell/audio.h @@ -100,33 +100,46 @@ static inline void print_qos(const struct shell *sh, const struct bt_audio_codec #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE || CONFIG_BT_BAP_UNICAST */ } +static void print_ltv_elem(const struct shell *sh, const char *str, uint8_t type, uint8_t value_len, + const uint8_t *value, size_t cnt) +{ + shell_print(sh, "%s #%zu: type 0x%02x value_len %u", str, cnt, type, value_len); + shell_hexdump(sh, value, value_len); +} + +static void print_ltv_array(const struct shell *sh, const char *str, const uint8_t *ltv_data, + size_t ltv_data_len) +{ + size_t cnt = 0U; + + for (size_t i = 0U; i < ltv_data_len; i++) { + const uint8_t len = ltv_data[i++]; + const uint8_t type = ltv_data[i++]; + const uint8_t *value = <v_data[i]; + const uint8_t value_len = len - sizeof(type); + + print_ltv_elem(sh, str, type, value_len, value, cnt++); + i += value_len; + } +} + static inline void print_codec_cap(const struct shell *sh, const struct bt_audio_codec_cap *codec_cap) { - shell_print(sh, "codec cap id 0x%02x cid 0x%04x vid 0x%04x", codec_cap->id, codec_cap->cid, - codec_cap->vid); - -#if CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_COUNT > 0 - shell_print(sh, "data_count %u", codec_cap->data_count); - for (size_t i = 0U; i < codec_cap->data_count; i++) { - shell_print(sh, "data #%u: type 0x%02x len %u", i, codec_cap->data[i].data.type, - codec_cap->data[i].data.data_len); - shell_hexdump(sh, codec_cap->data[i].data.data, - codec_cap->data[i].data.data_len - - sizeof(codec_cap->data[i].data.type)); + shell_print(sh, "codec id 0x%02x cid 0x%04x vid 0x%04x count %u", codec_cap->id, + codec_cap->cid, codec_cap->vid, codec_cap->data_len); + +#if CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 + if (codec_cap->id == BT_AUDIO_CODEC_LC3_ID) { + print_ltv_array(sh, "data", codec_cap->data, codec_cap->data_len); + } else { /* If not LC3, we cannot assume it's LTV */ + shell_hexdump(sh, codec_cap->data, codec_cap->data_len); } -#endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_COUNT > 0 */ - -#if CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_COUNT > 0 - shell_print(sh, "meta_count %u", codec_cap->data_count); - for (size_t i = 0U; i < codec_cap->meta_count; i++) { - shell_print(sh, "meta #%u: type 0x%02x len %u", i, codec_cap->meta[i].data.type, - codec_cap->meta[i].data.data_len); - shell_hexdump(sh, codec_cap->meta[i].data.data, - codec_cap->meta[i].data.data_len - - sizeof(codec_cap->meta[i].data.type)); - } -#endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_COUNT > 0 */ +#endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 */ + +#if CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 + print_ltv_array(sh, "meta", codec_cap->meta, codec_cap->meta_len); +#endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 */ } static inline void print_codec_cfg(const struct shell *sh, diff --git a/subsys/bluetooth/audio/shell/bap.c b/subsys/bluetooth/audio/shell/bap.c index 4521c8bc0dfc892..7e32373ad4712af 100644 --- a/subsys/bluetooth/audio/shell/bap.c +++ b/subsys/bluetooth/audio/shell/bap.c @@ -579,10 +579,10 @@ static int lc3_release(struct bt_bap_stream *stream, struct bt_bap_ascs_rsp *rsp return 0; } -static struct bt_audio_codec_cap lc3_codec_cap = - BT_AUDIO_CODEC_LC3(BT_AUDIO_CODEC_LC3_FREQ_ANY, BT_AUDIO_CODEC_LC3_DURATION_ANY, - BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1, 2), 30, 240, 2, - (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); +static struct bt_audio_codec_cap lc3_codec_cap = BT_AUDIO_CODEC_CAP_LC3( + 0x0000, 0x0000, BT_AUDIO_CODEC_LC3_FREQ_ANY, BT_AUDIO_CODEC_LC3_DURATION_ANY, + BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1, 2), 30, 240, 2, + (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); static const struct bt_bap_unicast_server_cb unicast_server_cb = { .config = lc3_config, diff --git a/tests/bluetooth/audio/mocks/src/pacs.c b/tests/bluetooth/audio/mocks/src/pacs.c index 11cfd629dbcd524..95b37d6a7ca0df4 100644 --- a/tests/bluetooth/audio/mocks/src/pacs.c +++ b/tests/bluetooth/audio/mocks/src/pacs.c @@ -10,13 +10,12 @@ #include "pacs.h" /* List of fakes used by this unit tester */ -#define PACS_FFF_FAKES_LIST(FAKE) \ - FAKE(bt_pacs_cap_foreach) \ +#define PACS_FFF_FAKES_LIST(FAKE) FAKE(bt_pacs_cap_foreach) -static struct bt_audio_codec_cfg lc3_codec = - BT_AUDIO_CODEC_LC3(BT_AUDIO_CODEC_LC3_FREQ_ANY, BT_AUDIO_CODEC_LC3_DURATION_10, - BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1), 40u, 120u, 1u, - (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); +static struct bt_audio_codec_cap lc3_codec = BT_AUDIO_CODEC_CAP_LC3( + 0x0000, 0x0000, BT_AUDIO_CODEC_LC3_FREQ_ANY, BT_AUDIO_CODEC_LC3_DURATION_10, + BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1), 40u, 120u, 1u, + (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); DEFINE_FAKE_VOID_FUNC(bt_pacs_cap_foreach, enum bt_audio_dir, bt_pacs_cap_foreach_func_t, void *); diff --git a/tests/bluetooth/tester/src/btp_bap.c b/tests/bluetooth/tester/src/btp_bap.c index 425d7aa6f8fa911..39fd995fb69a18e 100644 --- a/tests/bluetooth/tester/src/btp_bap.c +++ b/tests/bluetooth/tester/src/btp_bap.c @@ -40,10 +40,10 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL); #define AVAILABLE_SINK_CONTEXT SUPPORTED_SINK_CONTEXT #define AVAILABLE_SOURCE_CONTEXT SUPPORTED_SOURCE_CONTEXT -static struct bt_audio_codec_cap default_codec_cap = - BT_AUDIO_CODEC_LC3(BT_AUDIO_CODEC_LC3_FREQ_ANY, BT_AUDIO_CODEC_LC3_DURATION_10, - BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1), 40u, 120u, 1u, - (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); +static struct bt_audio_codec_cap default_codec_cap = BT_AUDIO_CODEC_CAP_LC3( + 0x0000, 0x0000, BT_AUDIO_CODEC_LC3_FREQ_ANY, BT_AUDIO_CODEC_LC3_DURATION_10, + BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1), 40u, 120u, 1u, + (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); struct audio_stream { struct bt_bap_stream stream; diff --git a/tests/bsim/bluetooth/audio/prj.conf b/tests/bsim/bluetooth/audio/prj.conf index c70248cd5128118..dfa8a84f5333ec3 100644 --- a/tests/bsim/bluetooth/audio/prj.conf +++ b/tests/bsim/bluetooth/audio/prj.conf @@ -25,6 +25,7 @@ CONFIG_BT_ASCS_ASE_SRC_COUNT=2 CONFIG_BT_BAP_BROADCAST_SOURCE=y CONFIG_BT_BAP_BROADCAST_SINK=y CONFIG_BT_AUDIO_CODEC_MAX_DATA_LEN=128 +CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE=196 CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT=1 CONFIG_BT_BAP_BROADCAST_SRC_SUBGROUP_COUNT=1 CONFIG_BT_BAP_BROADCAST_SNK_SUBGROUP_COUNT=1 diff --git a/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c b/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c index af0e4272f0761e7..fe42c2dc2de36bf 100644 --- a/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_broadcast_sink_test.c @@ -26,8 +26,11 @@ CREATE_FLAG(flag_received); static struct bt_bap_broadcast_sink *g_sink; static struct bt_bap_stream broadcast_sink_streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]; static struct bt_bap_stream *streams[ARRAY_SIZE(broadcast_sink_streams)]; -static struct bt_audio_codec_cap codec_cap_16_2_1 = BT_AUDIO_CODEC_LC3_CONFIG_16_2( - BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); + +static struct bt_audio_codec_cap codec_cap_16_2_1 = BT_AUDIO_CODEC_CAP_LC3( + 0x0000, 0x0000, BT_AUDIO_CODEC_LC3_FREQ_ANY, BT_AUDIO_CODEC_LC3_DURATION_ANY, + BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1, 2), 30, 240, 2, + (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); static K_SEM_DEFINE(sem_started, 0U, ARRAY_SIZE(streams)); static K_SEM_DEFINE(sem_stopped, 0U, ARRAY_SIZE(streams)); diff --git a/tests/bsim/bluetooth/audio/src/bap_unicast_common.c b/tests/bsim/bluetooth/audio/src/bap_unicast_common.c index 8da762058423b68..d29e7bee04f9464 100644 --- a/tests/bsim/bluetooth/audio/src/bap_unicast_common.c +++ b/tests/bsim/bluetooth/audio/src/bap_unicast_common.c @@ -14,26 +14,43 @@ void print_hex(const uint8_t *ptr, size_t len) } } -void print_codec_cap(const struct bt_audio_codec_cap *codec_cap) +static void print_ltv_elem(const char *str, uint8_t type, uint8_t value_len, const uint8_t *value, + size_t cnt) { - printk("codec_cfg ID 0x%02x cid 0x%04x vid 0x%04x count %u\n", codec_cap->id, - codec_cap->cid, codec_cap->vid, codec_cap->data_count); + printk("%s #%zu: type 0x%02x value_len %u\n", str, cnt, type, value_len); + print_hex(value, value_len); + printk("\n"); +} - for (uint8_t i = 0; i < codec_cap->data_count; i++) { - printk("data #%u: type 0x%02x len %u\n", i, codec_cap->data[i].data.type, - codec_cap->data[i].data.data_len); - print_hex(codec_cap->data[i].data.data, - codec_cap->data[i].data.data_len - sizeof(codec_cap->data[i].data.type)); - printk("\n"); +static void print_ltv_array(const char *str, const uint8_t *ltv_data, size_t ltv_data_len) +{ + size_t cnt = 0U; + + for (size_t i = 0U; i < ltv_data_len; i++) { + const uint8_t len = ltv_data[i++]; + const uint8_t type = ltv_data[i++]; + const uint8_t *value = <v_data[i]; + const uint8_t value_len = len - sizeof(type); + + print_ltv_elem(str, type, value_len, value, cnt++); + i += value_len; } +} - for (uint8_t i = 0; i < codec_cap->meta_count; i++) { - printk("meta #%u: type 0x%02x len %u\n", i, codec_cap->meta[i].data.type, - codec_cap->meta[i].data.data_len); - print_hex(codec_cap->meta[i].data.data, - codec_cap->meta[i].data.data_len - sizeof(codec_cap->meta[i].data.type)); +void print_codec_cap(const struct bt_audio_codec_cap *codec_cap) +{ + printk("codec_cap ID 0x%02x cid 0x%04x vid 0x%04x count %u\n", codec_cap->id, + codec_cap->cid, codec_cap->vid, codec_cap->data_len); + + if (codec_cap->id == BT_AUDIO_CODEC_LC3_ID) { + print_ltv_array("data", codec_cap->data, codec_cap->data_len); + } else { /* If not LC3, we cannot assume it's LTV */ + printk("data: "); + print_hex(codec_cap->data, codec_cap->data_len); printk("\n"); } + + print_ltv_array("meta", codec_cap->meta, codec_cap->meta_len); } void print_codec_cfg(const struct bt_audio_codec_cfg *codec_cfg) diff --git a/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c b/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c index b5a4ea32eeb7094..b4cf159986bc1c0 100644 --- a/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c +++ b/tests/bsim/bluetooth/audio/src/bap_unicast_server_test.c @@ -17,45 +17,46 @@ extern enum bst_result_t bst_result; #define CHANNEL_COUNT_1 BIT(0) -#define PREF_CONTEXT \ - (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA) +#define PREF_CONTEXT (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA) + +#define LONG_META 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, \ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, \ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, \ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, \ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, \ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, \ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, \ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, \ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, \ + 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, \ + 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, \ + 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, \ + 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, \ + 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, \ + 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, \ + 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f + +#define LONG_META_LEN (sizeof((uint8_t []){LONG_META}) + 1U) /* Size of data + type */ static struct bt_audio_codec_cap lc3_codec_cap = { .path_id = BT_ISO_DATA_PATH_HCI, .id = BT_AUDIO_CODEC_LC3_ID, .cid = 0x0000U, .vid = 0x0000U, - .data_count = 5U, + .data_len = (3 + 1) + (2 + 1) + (2 + 1) + (5 + 1) + (2 + 1), .data = { - BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_LC3_FREQ, - BT_BYTES_LIST_LE16(BT_AUDIO_CODEC_LC3_FREQ_16KHZ)), - BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_LC3_DURATION, - BT_AUDIO_CODEC_LC3_DURATION_10), - BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_LC3_CHAN_COUNT, CHANNEL_COUNT_1), - BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_LC3_FRAME_LEN, BT_BYTES_LIST_LE32(40U)), - BT_AUDIO_CODEC_DATA(BT_AUDIO_CODEC_LC3_FRAME_COUNT, 1U), + 3, BT_AUDIO_CODEC_LC3_FREQ, + BT_BYTES_LIST_LE16(BT_AUDIO_CODEC_LC3_FREQ_16KHZ), + 2, BT_AUDIO_CODEC_LC3_DURATION, BT_AUDIO_CODEC_LC3_DURATION_10, + 2, BT_AUDIO_CODEC_LC3_CHAN_COUNT, CHANNEL_COUNT_1, + 5, BT_AUDIO_CODEC_LC3_FRAME_LEN, BT_BYTES_LIST_LE16(40U), + BT_BYTES_LIST_LE16(40U), + 2, BT_AUDIO_CODEC_LC3_FRAME_COUNT, 1U, }, - .meta_count = 2, + .meta_len = (5 + 1) + (LONG_META_LEN + 1U), .meta = { - BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PREF_CONTEXT, - BT_BYTES_LIST_LE32(PREF_CONTEXT)), - BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_VENDOR, - 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, - 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, - 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, - 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, - 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, - 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, - 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, - 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, - 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, - 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, - 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, - 0x58, 0x59, 0x5a, 0x5b, 0x5c, 0x5d, 0x5e, 0x5f, - 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, - 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, - 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, - 0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f), + 5, BT_AUDIO_METADATA_TYPE_PREF_CONTEXT, BT_BYTES_LIST_LE32(PREF_CONTEXT), + LONG_META_LEN, BT_AUDIO_METADATA_TYPE_VENDOR, LONG_META, }, }; diff --git a/tests/bsim/bluetooth/audio/src/cap_acceptor_test.c b/tests/bsim/bluetooth/audio/src/cap_acceptor_test.c index 0827a77fdd6ef03..bf5d382391ba8f3 100644 --- a/tests/bsim/bluetooth/audio/src/cap_acceptor_test.c +++ b/tests/bsim/bluetooth/audio/src/cap_acceptor_test.c @@ -29,8 +29,11 @@ CREATE_FLAG(flag_pa_sync_lost); static struct bt_bap_broadcast_sink *g_broadcast_sink; static struct bt_cap_stream broadcast_sink_streams[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT]; -static struct bt_audio_codec_cap codec_cap_16_2_1 = BT_AUDIO_CODEC_LC3_CONFIG_16_2( - BT_AUDIO_LOCATION_FRONT_LEFT, BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED); + +static struct bt_audio_codec_cap codec_cap_16_2_1 = BT_AUDIO_CODEC_CAP_LC3( + 0x0000, 0x0000, BT_AUDIO_CODEC_LC3_FREQ_ANY, BT_AUDIO_CODEC_LC3_DURATION_ANY, + BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(1, 2), 30, 240, 2, + (BT_AUDIO_CONTEXT_TYPE_CONVERSATIONAL | BT_AUDIO_CONTEXT_TYPE_MEDIA)); static const struct bt_audio_codec_qos_pref unicast_qos_pref = BT_AUDIO_CODEC_QOS_PREF(true, BT_GAP_LE_PHY_2M, 0u, 60u, 20000u, 40000u, 20000u, 40000u);