diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index 16a34bd9891..f78e285ab26 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -662,20 +662,20 @@ int bt_audio_codec_cfg_get_frame_blocks_per_sdu(const struct bt_audio_codec_cfg /** @brief Lookup a specific value based on type * * Depending on context bt_audio_codec_cfg will be either codec capabilities, codec configuration - * or meta data. + * or meta data. * * Typically types used are: * @ref bt_audio_codec_capability_type * @ref bt_audio_codec_config_type * @ref bt_audio_metadata_type * - * @param codec_cfg The codec data to search in. - * @param type The type id to look for - * @param data Pointer to the data-pointer to update when item is found - * @return True if the type is found, false otherwise. + * @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 */ -bool bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, uint8_t type, - const uint8_t **data); +uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, uint8_t type, + const uint8_t **data); /** @} */ /* End of bt_audio_codec_cfg */ diff --git a/subsys/bluetooth/audio/codec.c b/subsys/bluetooth/audio/codec.c index 52dc06d2b1e..9d377a28d25 100644 --- a/subsys/bluetooth/audio/codec.c +++ b/subsys/bluetooth/audio/codec.c @@ -22,14 +22,16 @@ LOG_MODULE_REGISTER(bt_audio_codec, CONFIG_BT_AUDIO_CODEC_LOG_LEVEL); struct search_type_param { uint8_t type; + uint8_t data_len; const uint8_t *data; }; -static bool print_cb(struct bt_data *data, void *user_data) +static bool parse_cb(struct bt_data *data, void *user_data) { struct search_type_param *param = (struct search_type_param *)user_data; if (param->type == data->type) { + param->data_len = data->data_len; param->data = data->data; return false; @@ -38,114 +40,124 @@ static bool print_cb(struct bt_data *data, void *user_data) return true; } -bool bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, uint8_t type, - const uint8_t **data) +uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, uint8_t type, + const uint8_t **data) { struct search_type_param param = { .type = type, - .data = NULL, + .data_len = 0, + .data = *data, }; int err; + *data = NULL; + CHECKIF(codec_cfg == NULL) { LOG_DBG("codec is NULL"); - return false; + return 0; } - err = bt_audio_data_parse(codec_cfg->data, codec_cfg->data_len, print_cb, ¶m); + err = bt_audio_data_parse(codec_cfg->data, codec_cfg->data_len, parse_cb, ¶m); if (err != 0 && err != -ECANCELED) { LOG_DBG("Could not parse the data: %d", err); - - return false; + return 0; } if (param.data == NULL) { LOG_DBG("Could not find the type %u", type); - - return false; + return 0; } - *data = param.data; - - return true; + return param.data_len; } int bt_audio_codec_cfg_get_freq(const struct bt_audio_codec_cfg *codec_cfg) { const uint8_t *data; + uint8_t data_len; CHECKIF(codec_cfg == NULL) { LOG_DBG("codec is NULL"); return BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM; } - if (bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_FREQ, &data)) { - const uint8_t freq = data[0]; - - switch (freq) { - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_8KHZ: - return 8000; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_11KHZ: - return 11025; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_16KHZ: - return 16000; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_22KHZ: - return 22050; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_24KHZ: - return 24000; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_32KHZ: - return 32000; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_44KHZ: - return 44100; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_48KHZ: - return 48000; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_88KHZ: - return 88200; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_96KHZ: - return 96000; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_176KHZ: - return 176400; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_192KHZ: - return 192000; - case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_384KHZ: - return 384000; - default: - return BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND; - } + data_len = bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_FREQ, &data); + if (data == NULL) { + return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND; } - return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND; + if (data_len != sizeof(uint8_t)) { + return BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND; + } + + switch (data[0]) { + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_8KHZ: + return 8000; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_11KHZ: + return 11025; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_16KHZ: + return 16000; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_22KHZ: + return 22050; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_24KHZ: + return 24000; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_32KHZ: + return 32000; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_44KHZ: + return 44100; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_48KHZ: + return 48000; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_88KHZ: + return 88200; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_96KHZ: + return 96000; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_176KHZ: + return 176400; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_192KHZ: + return 192000; + case BT_AUDIO_CODEC_CONFIG_LC3_FREQ_384KHZ: + return 384000; + default: + return BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND; + } } int bt_audio_codec_cfg_get_frame_duration_us(const struct bt_audio_codec_cfg *codec_cfg) { const uint8_t *data; + uint8_t data_len; CHECKIF(codec_cfg == NULL) { LOG_DBG("codec is NULL"); return BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM; } - if (bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_DURATION, &data)) { - const uint8_t duration = data[0]; - - switch (duration) { - case BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5: - return 7500; - case BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10: - return 10000; - default: - return BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND; - } + data_len = bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_DURATION, &data); + if (data == NULL) { + return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND; } - return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND; + if (data_len != sizeof(uint8_t)) { + return BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND; + } + + switch (data[0]) { + case BT_AUDIO_CODEC_CONFIG_LC3_DURATION_7_5: + return 7500; + case BT_AUDIO_CODEC_CONFIG_LC3_DURATION_10: + return 10000; + default: + return BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND; + } } int bt_audio_codec_cfg_get_chan_allocation_val(const struct bt_audio_codec_cfg *codec_cfg, enum bt_audio_location *chan_allocation) { const uint8_t *data; + uint8_t data_len; + + *chan_allocation = 0; CHECKIF(codec_cfg == NULL) { LOG_DBG("codec is NULL"); @@ -156,14 +168,17 @@ int bt_audio_codec_cfg_get_chan_allocation_val(const struct bt_audio_codec_cfg * return BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM; } - if (bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_CHAN_ALLOC, &data)) { - - *chan_allocation = sys_get_le32(data); - - return BT_AUDIO_CODEC_PARSE_ERR_SUCCESS; + data_len = bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_CHAN_ALLOC, + &data); + if (data == NULL) { + return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND; } - *chan_allocation = 0; + if (data_len != sizeof(uint32_t)) { + return BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND; + } + + *chan_allocation = sys_get_le32(data); return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND; } @@ -171,41 +186,51 @@ int bt_audio_codec_cfg_get_chan_allocation_val(const struct bt_audio_codec_cfg * int bt_audio_codec_cfg_get_octets_per_frame(const struct bt_audio_codec_cfg *codec_cfg) { const uint8_t *data; + uint8_t data_len; CHECKIF(codec_cfg == NULL) { LOG_DBG("codec is NULL"); return BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM; } - if (bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_FRAME_LEN, &data)) { - - return sys_get_le16(data); + data_len = bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_FRAME_LEN, + &data); + if (data == NULL) { + return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND; } - return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND; + if (data_len != sizeof(uint16_t)) { + return BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND; + } + + return sys_get_le16(data); } int bt_audio_codec_cfg_get_frame_blocks_per_sdu(const struct bt_audio_codec_cfg *codec_cfg, bool fallback_to_default) { const uint8_t *data; + uint8_t data_len; CHECKIF(codec_cfg == NULL) { LOG_DBG("codec is NULL"); return BT_AUDIO_CODEC_PARSE_ERR_INVALID_PARAM; } - if (bt_audio_codec_cfg_get_val(codec_cfg, BT_AUDIO_CODEC_CONFIG_LC3_FRAME_BLKS_PER_SDU, - &data)) { + data_len = bt_audio_codec_cfg_get_val(codec_cfg, + BT_AUDIO_CODEC_CONFIG_LC3_FRAME_BLKS_PER_SDU, &data); + if (data == NULL) { + if (fallback_to_default) { + return 1; + } - return data[0]; + return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND; } - if (fallback_to_default) { - - return 1; + if (data_len != sizeof(uint8_t)) { + return BT_AUDIO_CODEC_PARSE_ERR_INVALID_VALUE_FOUND; } - return BT_AUDIO_CODEC_PARSE_ERR_TYPE_NOT_FOUND; + return data[0]; } #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_DATA_SIZE > 0 */