Repository: zephyrproject-rtos/zephyr (C)

Issue:
LE Audio: Add helper functions for bt_audio_codec_cap and metadata
**Is your enhancement proposal related to a problem? Please describe.**
The `bt_audio_codec_cap` contains an array of codec capabilities and codec capabilities metadata. 

For `bt_audio_codec_cfg` we have the `bt_audio_codec_cfg_get_*` functions to retrieve codec cfg data, and we should have the same for the codec capabilities, for both the capabilities and metadata. 

**Describe the solution you'd like**
Implement helper functions to get the following fields from a LTV encoded `bt_audio_codec_cap.data`:
```c
BT_AUDIO_CODEC_LC3_FREQ
BT_AUDIO_CODEC_LC3_DURATION
BT_AUDIO_CODEC_LC3_CHAN_COUNT
BT_AUDIO_CODEC_LC3_FRAME_LEN
BT_AUDIO_CODEC_LC3_FRAME_COUNT
```

As well as the `meta` for both `codec_cfg` and `codec_cap`:
```c
BT_AUDIO_METADATA_TYPE_PREF_CONTEXT
BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT
BT_AUDIO_METADATA_TYPE_PROGRAM_INFO
BT_AUDIO_METADATA_TYPE_STREAM_LANG
BT_AUDIO_METADATA_TYPE_CCID_LIST
BT_AUDIO_METADATA_TYPE_PARENTAL_RATING
BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI
BT_AUDIO_METADATA_TYPE_AUDIO_STATE
BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE
BT_AUDIO_METADATA_TYPE_EXTENDED
BT_AUDIO_METADATA_TYPE_VENDOR
```

**Describe alternatives you've considered**
N/A

**Additional context**
It may also be useful to have `_set_` functions for the above.
```[tasklist]
### Tasks
- [ ] https://github.com/zephyrproject-rtos/zephyr/pull/62774
- [ ] https://github.com/zephyrproject-rtos/zephyr/pull/62712
- [ ] https://github.com/zephyrproject-rtos/zephyr/pull/63040
- [ ] https://github.com/zephyrproject-rtos/zephyr/pull/63147
- [ ] https://github.com/zephyrproject-rtos/zephyr/pull/63155
- [ ] https://github.com/zephyrproject-rtos/zephyr/pull/63161
- [ ] https://github.com/zephyrproject-rtos/zephyr/pull/63170
- [ ] https://github.com/zephyrproject-rtos/zephyr/pull/63203
- [ ] https://github.com/zephyrproject-rtos/zephyr/pull/63223
- [ ] https://github.com/zephyrproject-rtos/zephyr/pull/63321
- [ ] https://github.com/zephyrproject-rtos/zephyr/pull/63400
- [ ] https://github.com/zephyrproject-rtos/zephyr/pull/63427
- [ ] https://github.com/zephyrproject-rtos/zephyr/pull/63429
```




Fix (patch):
diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h
index 772e93588fa50..e6ad69e58ce56 100644
--- a/include/zephyr/bluetooth/audio/audio.h
+++ b/include/zephyr/bluetooth/audio/audio.h
@@ -802,10 +802,13 @@ int bt_audio_codec_cfg_set_frame_blocks_per_sdu(struct bt_audio_codec_cfg *codec
  *  @param[in] codec_cfg The codec data to search in.
  *  @param[in] type The type id to look for
  *  @param[out] data Pointer to the data-pointer to update when item is found
- *  @return Length of found @p data or 0 if not found
+ *
+ *  @retval Length of found @p data (may be 0)
+ *  @retval -EINVAL if arguments are invalid
+ *  @retval -ENODATA if not found
  */
-uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg,
-				   enum bt_audio_codec_config_type type, const uint8_t **data);
+int bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg,
+			       enum bt_audio_codec_config_type type, const uint8_t **data);
 
 /**
  * @brief Set or add a specific codec configuration value
@@ -1194,10 +1197,12 @@ int bt_audio_codec_cfg_meta_set_vendor(struct bt_audio_codec_cfg *codec_cfg,
  * @param[in]  type The type id to look for
  * @param[out] data Pointer to the data-pointer to update when item is found
  *
- * @return Length of found @p data or 0 if not found
+ *  @retval Length of found @p data (may be 0)
+ *  @retval -EINVAL if arguments are invalid
+ *  @retval -ENODATA if not found
  */
-uint8_t bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap,
-				   enum bt_audio_codec_capability_type type, const uint8_t **data);
+int bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap,
+			       enum bt_audio_codec_capability_type type, const uint8_t **data);
 
 /**
  * @brief Set or add a specific codec capability value
diff --git a/subsys/bluetooth/audio/codec.c b/subsys/bluetooth/audio/codec.c
index 6eec848a9b447..c62a48b95c044 100644
--- a/subsys/bluetooth/audio/codec.c
+++ b/subsys/bluetooth/audio/codec.c
@@ -279,8 +279,8 @@ static void init_net_buf_simple_from_codec_cfg(struct net_buf_simple *buf,
 	buf->len = codec_cfg->data_len;
 }
 
-uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg,
-				   enum bt_audio_codec_config_type type, const uint8_t **data)
+int bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg,
+			       enum bt_audio_codec_config_type type, const uint8_t **data)
 {
 	struct search_type_param param = {
 		.found = false,
@@ -292,12 +292,12 @@ uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg,
 
 	CHECKIF(codec_cfg == NULL) {
 		LOG_DBG("codec is NULL");
-		return 0;
+		return -EINVAL;
 	}
 
 	CHECKIF(data == NULL) {
 		LOG_DBG("data is NULL");
-		return 0;
+		return -EINVAL;
 	}
 
 	*data = NULL;
@@ -305,12 +305,12 @@ uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg,
 	err = bt_audio_data_parse(codec_cfg->data, codec_cfg->data_len, parse_cb, &param);
 	if (err != 0 && err != -ECANCELED) {
 		LOG_DBG("Could not parse the data: %d", err);
-		return 0;
+		return err;
 	}
 
-	if (param.data == NULL) {
+	if (!param.found) {
 		LOG_DBG("Could not find the type %u", type);
-		return 0;
+		return -ENODATA;
 	}
 
 	return param.data_len;
@@ -591,12 +591,12 @@ static void init_net_buf_simple_from_meta(struct net_buf_simple *buf, uint8_t me
 	buf->len = meta_len;
 }
 
-static int codec_meta_get_val(const uint8_t meta[], size_t meta_len, uint8_t type,
-			      const uint8_t **data)
+static int codec_meta_get_val(const uint8_t meta[], size_t meta_len,
+			      enum bt_audio_metadata_type type, const uint8_t **data)
 {
 	struct search_type_param param = {
 		.found = false,
-		.type = type,
+		.type = (uint8_t)type,
 		.data_len = 0,
 		.data = data,
 	};
@@ -1793,8 +1793,8 @@ static void init_net_buf_simple_from_codec_cap(struct net_buf_simple *buf,
 	buf->len = codec_cap->data_len;
 }
 
-uint8_t bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap,
-				   enum bt_audio_codec_capability_type type, const uint8_t **data)
+int bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap,
+			       enum bt_audio_codec_capability_type type, const uint8_t **data)
 {
 	struct search_type_param param = {
 		.found = false,
@@ -1806,12 +1806,12 @@ uint8_t bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap,
 
 	CHECKIF(codec_cap == NULL) {
 		LOG_DBG("codec_cap is NULL");
-		return 0;
+		return -EINVAL;
 	}
 
 	CHECKIF(data == NULL) {
 		LOG_DBG("data is NULL");
-		return 0;
+		return -EINVAL;
 	}
 
 	*data = NULL;
@@ -1819,12 +1819,12 @@ uint8_t bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap,
 	err = bt_audio_data_parse(codec_cap->data, codec_cap->data_len, parse_cb, &param);
 	if (err != 0 && err != -ECANCELED) {
 		LOG_DBG("Could not parse the data: %d", err);
-		return 0;
+		return err;
 	}
 
-	if (param.data == NULL) {
+	if (!param.found) {
 		LOG_DBG("Could not find the type %u", type);
-		return 0;
+		return -ENODATA;
 	}
 
 	return param.data_len;