diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index 597e49ade9c..17bac991f18 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -788,8 +788,8 @@ int bt_audio_codec_cfg_set_frame_blocks_per_sdu(struct bt_audio_codec_cfg *codec * @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 */ -uint8_t 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, + enum bt_audio_codec_config_type type, const uint8_t **data); /** * @brief Set or add a specific codec configuration value @@ -803,8 +803,9 @@ uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, u * @retval -EINVAL if arguments are invalid * @retval -ENOMEM if the new value could not set or added due to memory */ -int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t type, - const uint8_t *data, size_t data_len); +int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_codec_config_type type, const uint8_t *data, + size_t data_len); /** @brief Lookup a specific metadata value based on type * @@ -820,6 +821,22 @@ int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t typ int bt_audio_codec_cfg_meta_get_val(const struct bt_audio_codec_cfg *codec_cfg, uint8_t type, const uint8_t **data); +/** + * @brief Set or add a specific codec configuration metadata value. + * + * @param codec_cfg The codec configuration to set the value in. + * @param type The type id to set. + * @param data Pointer to the data-pointer to set. + * @param data_len Length of @p data. + * + * @retval The meta_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_val(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_metadata_type type, const uint8_t *data, + size_t data_len); + /** @brief Extract preferred contexts * * See @ref BT_AUDIO_METADATA_TYPE_PREF_CONTEXT for more information about this value. @@ -833,6 +850,19 @@ int bt_audio_codec_cfg_meta_get_val(const struct bt_audio_codec_cfg *codec_cfg, */ int bt_audio_codec_cfg_meta_get_pref_context(const struct bt_audio_codec_cfg *codec_cfg); +/** + * @brief Set the preferred context of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param ctx The preferred context to set. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_pref_context(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_context ctx); + /** @brief Extract stream contexts * * See @ref BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT for more information about this value. @@ -846,6 +876,19 @@ int bt_audio_codec_cfg_meta_get_pref_context(const struct bt_audio_codec_cfg *co */ int bt_audio_codec_cfg_meta_get_stream_context(const struct bt_audio_codec_cfg *codec_cfg); +/** + * @brief Set the stream context of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param ctx The stream context to set. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_stream_context(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_context ctx); + /** @brief Extract program info * * See @ref BT_AUDIO_METADATA_TYPE_PROGRAM_INFO for more information about this value. @@ -860,6 +903,20 @@ int bt_audio_codec_cfg_meta_get_stream_context(const struct bt_audio_codec_cfg * int bt_audio_codec_cfg_meta_get_program_info(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **program_info); +/** + * @brief Set the program info of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param program_info The program info to set. + * @param program_info_len The length of @p program_info. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_program_info(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *program_info, size_t program_info_len); + /** @brief Extract stream language * * See @ref BT_AUDIO_METADATA_TYPE_STREAM_LANG for more information about this value. @@ -873,6 +930,19 @@ int bt_audio_codec_cfg_meta_get_program_info(const struct bt_audio_codec_cfg *co */ int bt_audio_codec_cfg_meta_get_stream_lang(const struct bt_audio_codec_cfg *codec_cfg); +/** + * @brief Set the stream language of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param stream_lang The 24-bit stream language to set. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_stream_lang(struct bt_audio_codec_cfg *codec_cfg, + uint32_t stream_lang); + /** @brief Extract CCID list * * See @ref BT_AUDIO_METADATA_TYPE_CCID_LIST for more information about this value. @@ -887,6 +957,20 @@ int bt_audio_codec_cfg_meta_get_stream_lang(const struct bt_audio_codec_cfg *cod int bt_audio_codec_cfg_meta_get_ccid_list(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **ccid_list); +/** + * @brief Set the CCID list of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param ccid_list The program info to set. + * @param ccid_list_len The length of @p ccid_list. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_ccid_list(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *ccid_list, size_t ccid_list_len); + /** @brief Extract parental rating * * See @ref BT_AUDIO_METADATA_TYPE_PARENTAL_RATING for more information about this value. @@ -900,6 +984,19 @@ int bt_audio_codec_cfg_meta_get_ccid_list(const struct bt_audio_codec_cfg *codec */ int bt_audio_codec_cfg_meta_get_parental_rating(const struct bt_audio_codec_cfg *codec_cfg); +/** + * @brief Set the parental rating of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param parental_rating The parental rating to set. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_parental_rating(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_parental_rating parental_rating); + /** @brief Extract program info URI * * See @ref BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI for more information about this value. @@ -914,6 +1011,21 @@ int bt_audio_codec_cfg_meta_get_parental_rating(const struct bt_audio_codec_cfg int bt_audio_codec_cfg_meta_get_program_info_uri(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **program_info_uri); +/** + * @brief Set the program info URI of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param program_info_uri The program info URI to set. + * @param program_info_uri_len The length of @p program_info_uri. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_program_info_uri(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *program_info_uri, + size_t program_info_uri_len); + /** @brief Extract audio active state * * See @ref BT_AUDIO_METADATA_TYPE_AUDIO_STATE for more information about this value. @@ -927,6 +1039,19 @@ int bt_audio_codec_cfg_meta_get_program_info_uri(const struct bt_audio_codec_cfg */ int bt_audio_codec_cfg_meta_get_audio_active_state(const struct bt_audio_codec_cfg *codec_cfg); +/** + * @brief Set the audio active state of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param state The audio active state to set. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_audio_active_state(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_active_state state); + /** @brief Extract broadcast audio immediate rendering flag * * See @ref BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE for more information about this value. @@ -940,6 +1065,18 @@ int bt_audio_codec_cfg_meta_get_audio_active_state(const struct bt_audio_codec_c int bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag( const struct bt_audio_codec_cfg *codec_cfg); +/** + * @brief Set the broadcast audio immediate rendering flag of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_bcast_audio_immediate_rend_flag( + struct bt_audio_codec_cfg *codec_cfg); + /** @brief Extract extended metadata * * See @ref BT_AUDIO_METADATA_TYPE_EXTENDED for more information about this value. @@ -954,6 +1091,20 @@ int bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag( int bt_audio_codec_cfg_meta_get_extended(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **extended_meta); +/** + * @brief Set the extended metadata of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param extended_meta The extended metadata to set. + * @param extended_meta_len The length of @p extended_meta. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_extended(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *extended_meta, size_t extended_meta_len); + /** @brief Extract vendor specific metadata * * See @ref BT_AUDIO_METADATA_TYPE_VENDOR for more information about this value. @@ -967,6 +1118,20 @@ int bt_audio_codec_cfg_meta_get_extended(const struct bt_audio_codec_cfg *codec_ */ int bt_audio_codec_cfg_meta_get_vendor(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **vendor_meta); + +/** + * @brief Set the vendor specific metadata of a codec configuration metadata. + * + * @param codec_cfg The codec configuration to set data for. + * @param vendor_meta The vendor specific metadata to set. + * @param vendor_meta_len The length of @p vendor_meta. + * + * @retval The data_len of @p codec_cfg on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cfg_meta_set_vendor(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *vendor_meta, size_t vendor_meta_len); /** @} */ /* End of bt_audio_codec_cfg */ /** @@ -982,14 +1147,30 @@ int bt_audio_codec_cfg_meta_get_vendor(const struct bt_audio_codec_cfg *codec_cf /** * @brief Lookup a specific value based on type * - * @param[in] codec_cap The codec data to search in. - * @param[in] type The type id to look for + * @param[in] codec_cap 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 */ -uint8_t bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap, uint8_t type, - const uint8_t **data); +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); + +/** + * @brief Set or add a specific codec capability value + * + * @param codec_cap The codec data to set the value in. + * @param type The type id to set + * @param data Pointer to the data-pointer to set + * @param data_len Length of @p data + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_set_val(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_codec_capability_type type, const uint8_t *data, + size_t data_len); /** * @brief Extract the frequency from a codec capability. @@ -1133,6 +1314,22 @@ int bt_audio_codec_cap_set_max_codec_frames_per_sdu(struct bt_audio_codec_cap *c int bt_audio_codec_cap_meta_get_val(const struct bt_audio_codec_cap *codec_cap, uint8_t type, const uint8_t **data); +/** + * @brief Set or add a specific codec capability metadata value. + * + * @param codec_cap The codec capability to set the value in. + * @param type The type id to set. + * @param data Pointer to the data-pointer to set. + * @param data_len Length of @p data. + * + * @retval The meta_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_val(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_metadata_type type, const uint8_t *data, + size_t data_len); + /** @brief Extract preferred contexts * * See @ref BT_AUDIO_METADATA_TYPE_PREF_CONTEXT for more information about this value. @@ -1146,6 +1343,19 @@ int bt_audio_codec_cap_meta_get_val(const struct bt_audio_codec_cap *codec_cap, */ int bt_audio_codec_cap_meta_get_pref_context(const struct bt_audio_codec_cap *codec_cap); +/** + * @brief Set the preferred context of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param ctx The preferred context to set. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_pref_context(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_context ctx); + /** @brief Extract stream contexts * * See @ref BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT for more information about this value. @@ -1159,6 +1369,19 @@ int bt_audio_codec_cap_meta_get_pref_context(const struct bt_audio_codec_cap *co */ int bt_audio_codec_cap_meta_get_stream_context(const struct bt_audio_codec_cap *codec_cap); +/** + * @brief Set the stream context of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param ctx The stream context to set. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_stream_context(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_context ctx); + /** @brief Extract program info * * See @ref BT_AUDIO_METADATA_TYPE_PROGRAM_INFO for more information about this value. @@ -1173,6 +1396,20 @@ int bt_audio_codec_cap_meta_get_stream_context(const struct bt_audio_codec_cap * int bt_audio_codec_cap_meta_get_program_info(const struct bt_audio_codec_cap *codec_cap, const uint8_t **program_info); +/** + * @brief Set the program info of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param program_info The program info to set. + * @param program_info_len The length of @p program_info. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_program_info(struct bt_audio_codec_cap *codec_cap, + const uint8_t *program_info, size_t program_info_len); + /** @brief Extract stream language * * See @ref BT_AUDIO_METADATA_TYPE_STREAM_LANG for more information about this value. @@ -1186,6 +1423,19 @@ int bt_audio_codec_cap_meta_get_program_info(const struct bt_audio_codec_cap *co */ int bt_audio_codec_cap_meta_get_stream_lang(const struct bt_audio_codec_cap *codec_cap); +/** + * @brief Set the stream language of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param stream_lang The 24-bit stream language to set. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_stream_lang(struct bt_audio_codec_cap *codec_cap, + uint32_t stream_lang); + /** @brief Extract CCID list * * See @ref BT_AUDIO_METADATA_TYPE_CCID_LIST for more information about this value. @@ -1200,6 +1450,20 @@ int bt_audio_codec_cap_meta_get_stream_lang(const struct bt_audio_codec_cap *cod int bt_audio_codec_cap_meta_get_ccid_list(const struct bt_audio_codec_cap *codec_cap, const uint8_t **ccid_list); +/** + * @brief Set the CCID list of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param ccid_list The program info to set. + * @param ccid_list_len The length of @p ccid_list. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_ccid_list(struct bt_audio_codec_cap *codec_cap, + const uint8_t *ccid_list, size_t ccid_list_len); + /** @brief Extract parental rating * * See @ref BT_AUDIO_METADATA_TYPE_PARENTAL_RATING for more information about this value. @@ -1213,6 +1477,19 @@ int bt_audio_codec_cap_meta_get_ccid_list(const struct bt_audio_codec_cap *codec */ int bt_audio_codec_cap_meta_get_parental_rating(const struct bt_audio_codec_cap *codec_cap); +/** + * @brief Set the parental rating of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param parental_rating The parental rating to set. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_parental_rating(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_parental_rating parental_rating); + /** @brief Extract program info URI * * See @ref BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI for more information about this value. @@ -1227,6 +1504,21 @@ int bt_audio_codec_cap_meta_get_parental_rating(const struct bt_audio_codec_cap int bt_audio_codec_cap_meta_get_program_info_uri(const struct bt_audio_codec_cap *codec_cap, const uint8_t **program_info_uri); +/** + * @brief Set the program info URI of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param program_info_uri The program info URI to set. + * @param program_info_uri_len The length of @p program_info_uri. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_program_info_uri(struct bt_audio_codec_cap *codec_cap, + const uint8_t *program_info_uri, + size_t program_info_uri_len); + /** @brief Extract audio active state * * See @ref BT_AUDIO_METADATA_TYPE_AUDIO_STATE for more information about this value. @@ -1240,6 +1532,19 @@ int bt_audio_codec_cap_meta_get_program_info_uri(const struct bt_audio_codec_cap */ int bt_audio_codec_cap_meta_get_audio_active_state(const struct bt_audio_codec_cap *codec_cap); +/** + * @brief Set the audio active state of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param state The audio active state to set. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_audio_active_state(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_active_state state); + /** @brief Extract broadcast audio immediate rendering flag * * See @ref BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE for more information about this value. @@ -1253,6 +1558,18 @@ int bt_audio_codec_cap_meta_get_audio_active_state(const struct bt_audio_codec_c int bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag( const struct bt_audio_codec_cap *codec_cap); +/** + * @brief Set the broadcast audio immediate rendering flag of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_bcast_audio_immediate_rend_flag( + struct bt_audio_codec_cap *codec_cap); + /** @brief Extract extended metadata * * See @ref BT_AUDIO_METADATA_TYPE_EXTENDED for more information about this value. @@ -1267,6 +1584,20 @@ int bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag( int bt_audio_codec_cap_meta_get_extended(const struct bt_audio_codec_cap *codec_cap, const uint8_t **extended_meta); +/** + * @brief Set the extended metadata of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param extended_meta The extended metadata to set. + * @param extended_meta_len The length of @p extended_meta. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_extended(struct bt_audio_codec_cap *codec_cap, + const uint8_t *extended_meta, size_t extended_meta_len); + /** @brief Extract vendor specific metadata * * See @ref BT_AUDIO_METADATA_TYPE_VENDOR for more information about this value. @@ -1281,6 +1612,20 @@ int bt_audio_codec_cap_meta_get_extended(const struct bt_audio_codec_cap *codec_ int bt_audio_codec_cap_meta_get_vendor(const struct bt_audio_codec_cap *codec_cap, const uint8_t **vendor_meta); +/** + * @brief Set the vendor specific metadata of a codec capability metadata. + * + * @param codec_cap The codec capability to set data for. + * @param vendor_meta The vendor specific metadata to set. + * @param vendor_meta_len The length of @p vendor_meta. + * + * @retval The data_len of @p codec_cap on success + * @retval -EINVAL if arguments are invalid + * @retval -ENOMEM if the new value could not set or added due to memory + */ +int bt_audio_codec_cap_meta_set_vendor(struct bt_audio_codec_cap *codec_cap, + const uint8_t *vendor_meta, size_t vendor_meta_len); + /** @} */ /* End of bt_audio_codec_cap */ #ifdef __cplusplus diff --git a/subsys/bluetooth/audio/codec.c b/subsys/bluetooth/audio/codec.c index 382c6f370b0..38b1ef7d22b 100644 --- a/subsys/bluetooth/audio/codec.c +++ b/subsys/bluetooth/audio/codec.c @@ -238,12 +238,12 @@ 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, uint8_t type, - const uint8_t **data) +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) { struct search_type_param param = { .found = false, - .type = type, + .type = (uint8_t)type, .data_len = 0, .data = data, }; @@ -275,8 +275,9 @@ uint8_t bt_audio_codec_cfg_get_val(const struct bt_audio_codec_cfg *codec_cfg, u return param.data_len; } -int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, uint8_t type, - const uint8_t *data, size_t data_len) +int bt_audio_codec_cfg_set_val(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_codec_config_type type, const uint8_t *data, + size_t data_len) { struct net_buf_simple buf; int ret; @@ -519,10 +520,20 @@ int bt_audio_codec_cfg_set_frame_blocks_per_sdu(struct bt_audio_codec_cfg *codec #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 || \ CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 +static void init_net_buf_simple_from_meta(struct net_buf_simple *buf, uint8_t meta[], + size_t meta_len, size_t meta_size) +{ + buf->__buf = meta; + buf->data = meta; + buf->size = meta_size; + 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) { struct search_type_param param = { + .found = false, .type = type, .data_len = 0, .data = data, @@ -555,6 +566,32 @@ static int codec_meta_get_val(const uint8_t meta[], size_t meta_len, uint8_t typ return param.data_len; } +static int codec_meta_set_val(uint8_t meta[], size_t meta_len, size_t meta_size, + enum bt_audio_metadata_type type, const uint8_t *data, + size_t data_len) +{ + struct net_buf_simple buf; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + CHECKIF(data == NULL && data_len != 0) { + LOG_DBG("data is NULL"); + return -EINVAL; + } + + CHECKIF(data_len > UINT8_MAX) { + LOG_DBG("Invalid data_len %zu", data_len); + return -EINVAL; + } + + init_net_buf_simple_from_meta(&buf, meta, meta_len, meta_size); + + return ltv_set_val(&buf, (uint8_t)type, data, data_len); +} + static int codec_meta_get_pref_context(const uint8_t meta[], size_t meta_len) { const uint8_t *data; @@ -577,6 +614,27 @@ static int codec_meta_get_pref_context(const uint8_t meta[], size_t meta_len) return sys_get_le16(data); } +static int codec_meta_set_pref_context(uint8_t meta[], size_t meta_len, size_t meta_size, + enum bt_audio_context ctx) +{ + uint16_t ctx_le16; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + if ((ctx & BT_AUDIO_CONTEXT_TYPE_ANY) != ctx) { + LOG_DBG("Invalid ctx value: %d", ctx); + return -EINVAL; + } + + ctx_le16 = sys_cpu_to_le16((uint16_t)ctx); + + return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_PREF_CONTEXT, + (const uint8_t *)&ctx_le16, sizeof(ctx_le16)); +} + static int codec_meta_get_stream_context(const uint8_t meta[], size_t meta_len) { const uint8_t *data; @@ -599,6 +657,27 @@ static int codec_meta_get_stream_context(const uint8_t meta[], size_t meta_len) return sys_get_le16(data); } +static int codec_meta_set_stream_context(uint8_t meta[], size_t meta_len, size_t meta_size, + enum bt_audio_context ctx) +{ + uint16_t ctx_le16; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + if ((ctx & BT_AUDIO_CONTEXT_TYPE_ANY) != ctx) { + LOG_DBG("Invalid ctx value: %d", ctx); + return -EINVAL; + } + + ctx_le16 = sys_cpu_to_le16((uint16_t)ctx); + + return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT, + (const uint8_t *)&ctx_le16, sizeof(ctx_le16)); +} + static int codec_meta_get_program_info(const uint8_t meta[], size_t meta_len, const uint8_t **program_info) { @@ -625,6 +704,23 @@ static int codec_meta_get_program_info(const uint8_t meta[], size_t meta_len, return ret; } +static int codec_meta_set_program_info(uint8_t meta[], size_t meta_len, size_t meta_size, + const uint8_t *program_info, size_t program_info_len) +{ + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + CHECKIF(program_info == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_PROGRAM_INFO, + program_info, program_info_len); +} + static int codec_meta_get_stream_lang(const uint8_t meta[], size_t meta_len) { const uint8_t *data; @@ -647,6 +743,27 @@ static int codec_meta_get_stream_lang(const uint8_t meta[], size_t meta_len) return sys_get_le24(data); } +static int codec_meta_set_stream_lang(uint8_t meta[], size_t meta_len, size_t meta_size, + uint32_t stream_lang) +{ + uint8_t stream_lang_le[3]; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + if ((stream_lang & 0xFFFFFFU) != stream_lang) { + LOG_DBG("Invalid stream_lang value: %d", stream_lang); + return -EINVAL; + } + + sys_put_le24(stream_lang, stream_lang_le); + + return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_STREAM_LANG, + stream_lang_le, sizeof(stream_lang_le)); +} + static int codec_meta_get_ccid_list(const uint8_t meta[], size_t meta_len, const uint8_t **ccid_list) { @@ -673,6 +790,23 @@ static int codec_meta_get_ccid_list(const uint8_t meta[], size_t meta_len, return ret; } +static int codec_meta_set_ccid_list(uint8_t meta[], size_t meta_len, size_t meta_size, + const uint8_t *ccid_list, size_t ccid_list_len) +{ + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + CHECKIF(ccid_list == NULL) { + LOG_DBG("ccid_list is NULL"); + return -EINVAL; + } + + return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_CCID_LIST, + ccid_list, ccid_list_len); +} + static int codec_meta_get_parental_rating(const uint8_t meta[], size_t meta_len) { const uint8_t *data; @@ -695,6 +829,27 @@ static int codec_meta_get_parental_rating(const uint8_t meta[], size_t meta_len) return data[0]; } +static int codec_meta_set_parental_rating(uint8_t meta[], size_t meta_len, size_t meta_size, + enum bt_audio_parental_rating parental_rating) +{ + uint8_t parental_rating_u8; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + if (parental_rating > BT_AUDIO_PARENTAL_RATING_AGE_18_OR_ABOVE) { + LOG_DBG("Invalid parental_rating value: %d", parental_rating); + return -EINVAL; + } + + parental_rating_u8 = (uint8_t)parental_rating; + + return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_PARENTAL_RATING, + &parental_rating_u8, sizeof(parental_rating_u8)); +} + static int codec_meta_get_program_info_uri(const uint8_t meta[], size_t meta_len, const uint8_t **program_info_uri) { @@ -721,6 +876,25 @@ static int codec_meta_get_program_info_uri(const uint8_t meta[], size_t meta_len return ret; } +static int codec_meta_set_program_info_uri(uint8_t meta[], size_t meta_len, size_t meta_size, + const uint8_t *program_info_uri, + size_t program_info_uri_len) +{ + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + CHECKIF(program_info_uri == NULL) { + LOG_DBG("program_info_uri is NULL"); + return -EINVAL; + } + + return codec_meta_set_val(meta, meta_len, meta_size, + BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI, program_info_uri, + program_info_uri_len); +} + static int codec_meta_get_audio_active_state(const uint8_t meta[], size_t meta_len) { const uint8_t *data; @@ -743,6 +917,27 @@ static int codec_meta_get_audio_active_state(const uint8_t meta[], size_t meta_l return data[0]; } +static int codec_meta_set_audio_active_state(uint8_t meta[], size_t meta_len, size_t meta_size, + enum bt_audio_active_state state) +{ + uint8_t state_u8; + + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + if (state != BT_AUDIO_ACTIVE_STATE_DISABLED && state != BT_AUDIO_ACTIVE_STATE_ENABLED) { + LOG_DBG("Invalid state value: %d", state); + return -EINVAL; + } + + state_u8 = (uint8_t)state; + + return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_AUDIO_STATE, + &state_u8, sizeof(state_u8)); +} + static int codec_meta_get_bcast_audio_immediate_rend_flag(const uint8_t meta[], size_t meta_len) { const uint8_t *data; @@ -756,6 +951,18 @@ static int codec_meta_get_bcast_audio_immediate_rend_flag(const uint8_t meta[], &data); } +static int codec_meta_set_bcast_audio_immediate_rend_flag(uint8_t meta[], size_t meta_len, + size_t meta_size) +{ + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + return codec_meta_set_val(meta, meta_len, meta_size, + BT_AUDIO_METADATA_TYPE_BROADCAST_IMMEDIATE, NULL, 0); +} + static int codec_meta_get_extended(const uint8_t meta[], size_t meta_len, const uint8_t **extended_meta) { @@ -782,6 +989,23 @@ static int codec_meta_get_extended(const uint8_t meta[], size_t meta_len, return ret; } +static int codec_meta_set_extended(uint8_t meta[], size_t meta_len, size_t meta_size, + const uint8_t *extended, size_t extended_len) +{ + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + CHECKIF(extended == NULL) { + LOG_DBG("extended is NULL"); + return -EINVAL; + } + + return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_EXTENDED, + extended, extended_len); +} + static int codec_meta_get_vendor(const uint8_t meta[], size_t meta_len, const uint8_t **vendor_meta) { const uint8_t *data; @@ -807,6 +1031,23 @@ static int codec_meta_get_vendor(const uint8_t meta[], size_t meta_len, const ui return ret; } +static int codec_meta_set_vendor(uint8_t meta[], size_t meta_len, size_t meta_size, + const uint8_t *vendor, size_t vendor_len) +{ + CHECKIF(meta == NULL) { + LOG_DBG("meta is NULL"); + return -EINVAL; + } + + CHECKIF(vendor == NULL) { + LOG_DBG("vendor is NULL"); + return -EINVAL; + } + + return codec_meta_set_val(meta, meta_len, meta_size, BT_AUDIO_METADATA_TYPE_VENDOR, vendor, + vendor_len); +} + #if CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 int bt_audio_codec_cfg_meta_get_val(const struct bt_audio_codec_cfg *codec_cfg, uint8_t type, const uint8_t **data) @@ -819,6 +1060,26 @@ int bt_audio_codec_cfg_meta_get_val(const struct bt_audio_codec_cfg *codec_cfg, return codec_meta_get_val(codec_cfg->meta, codec_cfg->meta_len, type, data); } +int bt_audio_codec_cfg_meta_set_val(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_metadata_type type, const uint8_t *data, + size_t data_len) +{ + int ret; + + CHECKIF(codec_cfg == NULL) { + LOG_DBG("codec_cfg is NULL"); + return -EINVAL; + } + + ret = codec_meta_set_val(codec_cfg->meta, codec_cfg->meta_len, ARRAY_SIZE(codec_cfg->meta), + type, data, data_len); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_pref_context(const struct bt_audio_codec_cfg *codec_cfg) { CHECKIF(codec_cfg == NULL) { @@ -829,6 +1090,20 @@ int bt_audio_codec_cfg_meta_get_pref_context(const struct bt_audio_codec_cfg *co return codec_meta_get_pref_context(codec_cfg->meta, codec_cfg->meta_len); } +int bt_audio_codec_cfg_meta_set_pref_context(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_context ctx) +{ + int ret; + + ret = codec_meta_set_pref_context(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), ctx); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_stream_context(const struct bt_audio_codec_cfg *codec_cfg) { CHECKIF(codec_cfg == NULL) { @@ -839,6 +1114,20 @@ int bt_audio_codec_cfg_meta_get_stream_context(const struct bt_audio_codec_cfg * return codec_meta_get_stream_context(codec_cfg->meta, codec_cfg->meta_len); } +int bt_audio_codec_cfg_meta_set_stream_context(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_context ctx) +{ + int ret; + + ret = codec_meta_set_stream_context(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), ctx); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_program_info(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **program_info) { @@ -850,6 +1139,21 @@ int bt_audio_codec_cfg_meta_get_program_info(const struct bt_audio_codec_cfg *co return codec_meta_get_program_info(codec_cfg->meta, codec_cfg->meta_len, program_info); } +int bt_audio_codec_cfg_meta_set_program_info(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *program_info, size_t program_info_len) +{ + int ret; + + ret = codec_meta_set_program_info(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), program_info, + program_info_len); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_stream_lang(const struct bt_audio_codec_cfg *codec_cfg) { CHECKIF(codec_cfg == NULL) { @@ -860,6 +1164,20 @@ int bt_audio_codec_cfg_meta_get_stream_lang(const struct bt_audio_codec_cfg *cod return codec_meta_get_stream_lang(codec_cfg->meta, codec_cfg->meta_len); } +int bt_audio_codec_cfg_meta_set_stream_lang(struct bt_audio_codec_cfg *codec_cfg, + uint32_t stream_lang) +{ + int ret; + + ret = codec_meta_set_stream_lang(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), stream_lang); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_ccid_list(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **ccid_list) { @@ -871,6 +1189,20 @@ int bt_audio_codec_cfg_meta_get_ccid_list(const struct bt_audio_codec_cfg *codec return codec_meta_get_ccid_list(codec_cfg->meta, codec_cfg->meta_len, ccid_list); } +int bt_audio_codec_cfg_meta_set_ccid_list(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *ccid_list, size_t ccid_list_len) +{ + int ret; + + ret = codec_meta_set_ccid_list(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), ccid_list, ccid_list_len); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_parental_rating(const struct bt_audio_codec_cfg *codec_cfg) { CHECKIF(codec_cfg == NULL) { @@ -881,6 +1213,20 @@ int bt_audio_codec_cfg_meta_get_parental_rating(const struct bt_audio_codec_cfg return codec_meta_get_parental_rating(codec_cfg->meta, codec_cfg->meta_len); } +int bt_audio_codec_cfg_meta_set_parental_rating(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_parental_rating parental_rating) +{ + int ret; + + ret = codec_meta_set_parental_rating(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), parental_rating); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_program_info_uri(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **program_info_uri) { @@ -893,6 +1239,22 @@ int bt_audio_codec_cfg_meta_get_program_info_uri(const struct bt_audio_codec_cfg program_info_uri); } +int bt_audio_codec_cfg_meta_set_program_info_uri(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *program_info_uri, + size_t program_info_uri_len) +{ + int ret; + + ret = codec_meta_set_program_info_uri(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), program_info_uri, + program_info_uri_len); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_audio_active_state(const struct bt_audio_codec_cfg *codec_cfg) { CHECKIF(codec_cfg == NULL) { @@ -903,6 +1265,20 @@ int bt_audio_codec_cfg_meta_get_audio_active_state(const struct bt_audio_codec_c return codec_meta_get_audio_active_state(codec_cfg->meta, codec_cfg->meta_len); } +int bt_audio_codec_cfg_meta_set_audio_active_state(struct bt_audio_codec_cfg *codec_cfg, + enum bt_audio_active_state state) +{ + int ret; + + ret = codec_meta_set_audio_active_state(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), state); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag( const struct bt_audio_codec_cfg *codec_cfg) { @@ -911,11 +1287,23 @@ int bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag( return -EINVAL; } - LOG_ERR("codec_cfg->meta_len %zu", codec_cfg->meta_len); - return codec_meta_get_bcast_audio_immediate_rend_flag(codec_cfg->meta, codec_cfg->meta_len); } +int bt_audio_codec_cfg_meta_set_bcast_audio_immediate_rend_flag( + struct bt_audio_codec_cfg *codec_cfg) +{ + int ret; + + ret = codec_meta_set_bcast_audio_immediate_rend_flag(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta)); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_extended(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **extended_meta) { @@ -927,6 +1315,21 @@ int bt_audio_codec_cfg_meta_get_extended(const struct bt_audio_codec_cfg *codec_ return codec_meta_get_extended(codec_cfg->meta, codec_cfg->meta_len, extended_meta); } +int bt_audio_codec_cfg_meta_set_extended(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *extended_meta, size_t extended_meta_len) +{ + int ret; + + ret = codec_meta_set_extended(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), extended_meta, + extended_meta_len); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cfg_meta_get_vendor(const struct bt_audio_codec_cfg *codec_cfg, const uint8_t **vendor_meta) { @@ -937,6 +1340,20 @@ int bt_audio_codec_cfg_meta_get_vendor(const struct bt_audio_codec_cfg *codec_cf return codec_meta_get_vendor(codec_cfg->meta, codec_cfg->meta_len, vendor_meta); } + +int bt_audio_codec_cfg_meta_set_vendor(struct bt_audio_codec_cfg *codec_cfg, + const uint8_t *vendor_meta, size_t vendor_meta_len) +{ + int ret; + + ret = codec_meta_set_vendor(codec_cfg->meta, codec_cfg->meta_len, + ARRAY_SIZE(codec_cfg->meta), vendor_meta, vendor_meta_len); + if (ret >= 0) { + codec_cfg->meta_len = ret; + } + + return ret; +} #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 */ #if CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 @@ -951,6 +1368,26 @@ int bt_audio_codec_cap_meta_get_val(const struct bt_audio_codec_cap *codec_cap, return codec_meta_get_val(codec_cap->meta, codec_cap->meta_len, type, data); } +int bt_audio_codec_cap_meta_set_val(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_metadata_type type, const uint8_t *data, + size_t data_len) +{ + int ret; + + CHECKIF(codec_cap == NULL) { + LOG_DBG("codec_cap is NULL"); + return -EINVAL; + } + + ret = codec_meta_set_val(codec_cap->meta, codec_cap->meta_len, ARRAY_SIZE(codec_cap->meta), + type, data, data_len); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_pref_context(const struct bt_audio_codec_cap *codec_cap) { CHECKIF(codec_cap == NULL) { @@ -961,6 +1398,20 @@ int bt_audio_codec_cap_meta_get_pref_context(const struct bt_audio_codec_cap *co return codec_meta_get_pref_context(codec_cap->meta, codec_cap->meta_len); } +int bt_audio_codec_cap_meta_set_pref_context(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_context ctx) +{ + int ret; + + ret = codec_meta_set_pref_context(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), ctx); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_stream_context(const struct bt_audio_codec_cap *codec_cap) { CHECKIF(codec_cap == NULL) { @@ -971,6 +1422,20 @@ int bt_audio_codec_cap_meta_get_stream_context(const struct bt_audio_codec_cap * return codec_meta_get_stream_context(codec_cap->meta, codec_cap->meta_len); } +int bt_audio_codec_cap_meta_set_stream_context(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_context ctx) +{ + int ret; + + ret = codec_meta_set_stream_context(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), ctx); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_program_info(const struct bt_audio_codec_cap *codec_cap, const uint8_t **program_info) { @@ -982,6 +1447,21 @@ int bt_audio_codec_cap_meta_get_program_info(const struct bt_audio_codec_cap *co return codec_meta_get_program_info(codec_cap->meta, codec_cap->meta_len, program_info); } +int bt_audio_codec_cap_meta_set_program_info(struct bt_audio_codec_cap *codec_cap, + const uint8_t *program_info, size_t program_info_len) +{ + int ret; + + ret = codec_meta_set_program_info(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), program_info, + program_info_len); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_stream_lang(const struct bt_audio_codec_cap *codec_cap) { CHECKIF(codec_cap == NULL) { @@ -992,6 +1472,20 @@ int bt_audio_codec_cap_meta_get_stream_lang(const struct bt_audio_codec_cap *cod return codec_meta_get_stream_lang(codec_cap->meta, codec_cap->meta_len); } +int bt_audio_codec_cap_meta_set_stream_lang(struct bt_audio_codec_cap *codec_cap, + uint32_t stream_lang) +{ + int ret; + + ret = codec_meta_set_stream_lang(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), stream_lang); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_ccid_list(const struct bt_audio_codec_cap *codec_cap, const uint8_t **ccid_list) { @@ -1003,6 +1497,20 @@ int bt_audio_codec_cap_meta_get_ccid_list(const struct bt_audio_codec_cap *codec return codec_meta_get_ccid_list(codec_cap->meta, codec_cap->meta_len, ccid_list); } +int bt_audio_codec_cap_meta_set_ccid_list(struct bt_audio_codec_cap *codec_cap, + const uint8_t *ccid_list, size_t ccid_list_len) +{ + int ret; + + ret = codec_meta_set_ccid_list(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), ccid_list, ccid_list_len); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_parental_rating(const struct bt_audio_codec_cap *codec_cap) { CHECKIF(codec_cap == NULL) { @@ -1013,6 +1521,20 @@ int bt_audio_codec_cap_meta_get_parental_rating(const struct bt_audio_codec_cap return codec_meta_get_parental_rating(codec_cap->meta, codec_cap->meta_len); } +int bt_audio_codec_cap_meta_set_parental_rating(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_parental_rating parental_rating) +{ + int ret; + + ret = codec_meta_set_parental_rating(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), parental_rating); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_program_info_uri(const struct bt_audio_codec_cap *codec_cap, const uint8_t **program_info_uri) { @@ -1025,6 +1547,22 @@ int bt_audio_codec_cap_meta_get_program_info_uri(const struct bt_audio_codec_cap program_info_uri); } +int bt_audio_codec_cap_meta_set_program_info_uri(struct bt_audio_codec_cap *codec_cap, + const uint8_t *program_info_uri, + size_t program_info_uri_len) +{ + int ret; + + ret = codec_meta_set_program_info_uri(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), program_info_uri, + program_info_uri_len); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_audio_active_state(const struct bt_audio_codec_cap *codec_cap) { CHECKIF(codec_cap == NULL) { @@ -1035,6 +1573,20 @@ int bt_audio_codec_cap_meta_get_audio_active_state(const struct bt_audio_codec_c return codec_meta_get_audio_active_state(codec_cap->meta, codec_cap->meta_len); } +int bt_audio_codec_cap_meta_set_audio_active_state(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_active_state state) +{ + int ret; + + ret = codec_meta_set_audio_active_state(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), state); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag( const struct bt_audio_codec_cap *codec_cap) { @@ -1046,6 +1598,20 @@ int bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag( return codec_meta_get_bcast_audio_immediate_rend_flag(codec_cap->meta, codec_cap->meta_len); } +int bt_audio_codec_cap_meta_set_bcast_audio_immediate_rend_flag( + struct bt_audio_codec_cap *codec_cap) +{ + int ret; + + ret = codec_meta_set_bcast_audio_immediate_rend_flag(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta)); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_extended(const struct bt_audio_codec_cap *codec_cap, const uint8_t **extended_meta) { @@ -1057,6 +1623,21 @@ int bt_audio_codec_cap_meta_get_extended(const struct bt_audio_codec_cap *codec_ return codec_meta_get_extended(codec_cap->meta, codec_cap->meta_len, extended_meta); } +int bt_audio_codec_cap_meta_set_extended(struct bt_audio_codec_cap *codec_cap, + const uint8_t *extended_meta, size_t extended_meta_len) +{ + int ret; + + ret = codec_meta_set_extended(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), extended_meta, + extended_meta_len); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} + int bt_audio_codec_cap_meta_get_vendor(const struct bt_audio_codec_cap *codec_cap, const uint8_t **vendor_meta) { @@ -1067,6 +1648,20 @@ int bt_audio_codec_cap_meta_get_vendor(const struct bt_audio_codec_cap *codec_ca return codec_meta_get_vendor(codec_cap->meta, codec_cap->meta_len, vendor_meta); } + +int bt_audio_codec_cap_meta_set_vendor(struct bt_audio_codec_cap *codec_cap, + const uint8_t *vendor_meta, size_t vendor_meta_len) +{ + int ret; + + ret = codec_meta_set_vendor(codec_cap->meta, codec_cap->meta_len, + ARRAY_SIZE(codec_cap->meta), vendor_meta, vendor_meta_len); + if (ret >= 0) { + codec_cap->meta_len = ret; + } + + return ret; +} #endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 */ #endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 || \ * CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 \ @@ -1083,11 +1678,12 @@ 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, uint8_t type, - const uint8_t **data) +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) { struct search_type_param param = { - .type = type, + .found = false, + .type = (uint8_t)type, .data_len = 0, .data = data, }; @@ -1119,8 +1715,9 @@ uint8_t bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap, u return param.data_len; } -int bt_audio_codec_cap_set_val(struct bt_audio_codec_cap *codec_cap, uint8_t type, - const uint8_t *data, size_t data_len) +int bt_audio_codec_cap_set_val(struct bt_audio_codec_cap *codec_cap, + enum bt_audio_codec_capability_type type, const uint8_t *data, + size_t data_len) { struct net_buf_simple buf; int ret; diff --git a/tests/bluetooth/audio/codec/src/main.c b/tests/bluetooth/audio/codec/src/main.c index 99d5d6f21fd..386ef40e7f7 100644 --- a/tests/bluetooth/audio/codec/src/main.c +++ b/tests/bluetooth/audio/codec/src/main.c @@ -228,6 +228,27 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_pref_context) zassert_equal(ret, 0x0005, "unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_pref_context) +{ + const enum bt_audio_context ctx = + BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | BT_AUDIO_CONTEXT_TYPE_MEDIA; + const enum bt_audio_context new_ctx = BT_AUDIO_CONTEXT_TYPE_NOTIFICATIONS; + struct bt_audio_codec_cfg codec_cfg = + BT_AUDIO_CODEC_CFG(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PREF_CONTEXT, + BT_BYTES_LIST_LE16(ctx))}); + int ret; + + ret = bt_audio_codec_cfg_meta_get_pref_context(&codec_cfg); + zassert_equal(ret, 0x0005, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_set_pref_context(&codec_cfg, new_ctx); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_pref_context(&codec_cfg); + zassert_equal(ret, 0x0100, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_stream_context) { const enum bt_audio_context ctx = @@ -242,6 +263,26 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_stream_context) zassert_equal(ret, 0x0005, "unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_stream_context) +{ + enum bt_audio_context ctx = BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | BT_AUDIO_CONTEXT_TYPE_MEDIA; + struct bt_audio_codec_cfg codec_cfg = + BT_AUDIO_CODEC_CFG(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT, + BT_BYTES_LIST_LE16(ctx))}); + int ret; + + ret = bt_audio_codec_cfg_meta_get_stream_context(&codec_cfg); + zassert_equal(ret, 0x0005, "Unexpected return value %d", ret); + + ctx = BT_AUDIO_CONTEXT_TYPE_NOTIFICATIONS; + ret = bt_audio_codec_cfg_meta_set_stream_context(&codec_cfg, ctx); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_stream_context(&codec_cfg); + zassert_equal(ret, 0x0100, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_program_info) { const uint8_t expected_data[] = {'P', 'r', 'o', 'g', 'r', 'a', 'm', ' ', @@ -259,6 +300,31 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_program_info) zassert_mem_equal(expected_data, program_data, ARRAY_SIZE(expected_data)); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_program_info) +{ + const uint8_t expected_data[] = {'P', 'r', 'o', 'g', 'r', 'a', + 'm', ' ', 'I', 'n', 'f', 'o'}; + const uint8_t new_expected_data[] = {'N', 'e', 'w', ' ', 'i', 'n', 'f', 'o'}; + struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PROGRAM_INFO, 'P', 'r', 'o', 'g', 'r', + 'a', 'm', ' ', 'I', 'n', 'f', 'o')}); + const uint8_t *program_data; + int ret; + + ret = bt_audio_codec_cfg_meta_get_program_info(&codec_cfg, &program_data); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, program_data, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cfg_meta_set_program_info(&codec_cfg, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_program_info(&codec_cfg, &program_data); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, program_data, ARRAY_SIZE(new_expected_data)); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_stream_lang) { const uint32_t expected_data = sys_get_le24((uint8_t[]){'e', 'n', 'g'}); @@ -271,6 +337,26 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_stream_lang) zassert_equal(ret, expected_data, "Unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_stream_lang) +{ + const uint32_t expected_data = sys_get_le24((uint8_t[]){'e', 'n', 'g'}); + const uint32_t new_expected_data = sys_get_le24((uint8_t[]){'d', 'e', 'u'}); + struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_STREAM_LANG, 'e', 'n', 'g')}); + const uint32_t new_stream_lang = sys_le32_to_cpu(new_expected_data); + int ret; + + ret = bt_audio_codec_cfg_meta_get_stream_lang(&codec_cfg); + zassert_equal(ret, expected_data, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_set_stream_lang(&codec_cfg, new_stream_lang); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_stream_lang(&codec_cfg); + zassert_equal(ret, new_expected_data, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_ccid_list) { const uint8_t expected_data[] = {0x05, 0x10, 0x15}; @@ -285,6 +371,29 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_ccid_list) zassert_mem_equal(expected_data, ccid_list, ARRAY_SIZE(expected_data)); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_ccid_list) +{ + const uint8_t expected_data[] = {0x05, 0x10, 0x15}; + const uint8_t new_expected_data[] = {0x25, 0x30}; + struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_CCID_LIST, 0x05, 0x10, 0x15)}); + const uint8_t *ccid_list; + int ret; + + ret = bt_audio_codec_cfg_meta_get_ccid_list(&codec_cfg, &ccid_list); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, ccid_list, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cfg_meta_set_ccid_list(&codec_cfg, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_ccid_list(&codec_cfg, &ccid_list); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, ccid_list, ARRAY_SIZE(new_expected_data)); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_parental_rating) { const struct bt_audio_codec_cfg codec_cfg = @@ -297,6 +406,25 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_parental_rating) zassert_equal(ret, 0x07, "Unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_parental_rating) +{ + struct bt_audio_codec_cfg codec_cfg = + BT_AUDIO_CODEC_CFG(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PARENTAL_RATING, + BT_AUDIO_PARENTAL_RATING_AGE_10_OR_ABOVE)}); + int ret; + + ret = bt_audio_codec_cfg_meta_get_parental_rating(&codec_cfg); + zassert_equal(ret, 0x07, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_set_parental_rating(&codec_cfg, + BT_AUDIO_PARENTAL_RATING_AGE_13_OR_ABOVE); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_parental_rating(&codec_cfg); + zassert_equal(ret, 0x0a, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_program_info_uri) { const uint8_t expected_data[] = {'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'}; @@ -312,6 +440,30 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_program_info_uri) zassert_mem_equal(expected_data, program_info_uri, ARRAY_SIZE(expected_data)); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_program_info_uri) +{ + const uint8_t expected_data[] = {'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'}; + const uint8_t new_expected_data[] = {'n', 'e', 'w', '.', 'c', 'o', 'm'}; + struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI, 'e', 'x', 'a', 'm', + 'p', 'l', 'e', '.', 'c', 'o', 'm')}); + const uint8_t *program_info_uri; + int ret; + + ret = bt_audio_codec_cfg_meta_get_program_info_uri(&codec_cfg, &program_info_uri); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, program_info_uri, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cfg_meta_set_program_info_uri(&codec_cfg, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_program_info_uri(&codec_cfg, &program_info_uri); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, program_info_uri, ARRAY_SIZE(new_expected_data)); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_audio_active_state) { const struct bt_audio_codec_cfg codec_cfg = @@ -324,6 +476,25 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_audio_active_stat zassert_equal(ret, 0x01, "Unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_audio_active_state) +{ + struct bt_audio_codec_cfg codec_cfg = + BT_AUDIO_CODEC_CFG(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_AUDIO_STATE, + BT_AUDIO_ACTIVE_STATE_ENABLED)}); + int ret; + + ret = bt_audio_codec_cfg_meta_get_audio_active_state(&codec_cfg); + zassert_equal(ret, 0x01, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_set_audio_active_state(&codec_cfg, + BT_AUDIO_ACTIVE_STATE_DISABLED); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_audio_active_state(&codec_cfg); + zassert_equal(ret, 0x00, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag) { const struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( @@ -335,6 +506,22 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_bcast_audio_immed zassert_equal(ret, 0, "Unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_bcast_audio_immediate_rend_flag) +{ + struct bt_audio_codec_cfg codec_cfg = + BT_AUDIO_CODEC_CFG(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, {}); + int ret; + + ret = bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag(&codec_cfg); + zassert_equal(ret, -ENODATA, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_set_bcast_audio_immediate_rend_flag(&codec_cfg); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_bcast_audio_immediate_rend_flag(&codec_cfg); + zassert_equal(ret, 0, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_extended) { const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; @@ -349,6 +536,29 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_extended) zassert_mem_equal(expected_data, extended_meta, ARRAY_SIZE(expected_data)); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_extended) +{ + const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; + const uint8_t new_expected_data[] = {0x04, 0x05}; + struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_EXTENDED, 0x00, 0x01, 0x02, 0x03)}); + const uint8_t *extended_meta; + int ret; + + ret = bt_audio_codec_cfg_meta_get_extended(&codec_cfg, &extended_meta); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, extended_meta, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cfg_meta_set_extended(&codec_cfg, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_extended(&codec_cfg, &extended_meta); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, extended_meta, ARRAY_SIZE(new_expected_data)); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_vendor) { const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; @@ -363,6 +573,29 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_get_vendor) zassert_mem_equal(expected_data, vendor_meta, ARRAY_SIZE(expected_data)); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cfg_meta_set_vendor) +{ + const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; + const uint8_t new_expected_data[] = {0x04, 0x05, 0x06, 0x07, 0x08}; + struct bt_audio_codec_cfg codec_cfg = BT_AUDIO_CODEC_CFG( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_VENDOR, 0x00, 0x01, 0x02, 0x03)}); + const uint8_t *extended_meta; + int ret; + + ret = bt_audio_codec_cfg_meta_get_vendor(&codec_cfg, &extended_meta); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, extended_meta, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cfg_meta_set_vendor(&codec_cfg, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cfg_meta_get_vendor(&codec_cfg, &extended_meta); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, extended_meta, ARRAY_SIZE(new_expected_data)); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_get_freq) { const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP_LC3( @@ -553,6 +786,27 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_pref_context) zassert_equal(ret, 0x0005, "unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_pref_context) +{ + const enum bt_audio_context ctx = + BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | BT_AUDIO_CONTEXT_TYPE_MEDIA; + const enum bt_audio_context new_ctx = BT_AUDIO_CONTEXT_TYPE_NOTIFICATIONS; + struct bt_audio_codec_cap codec_cap = + BT_AUDIO_CODEC_CAP(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PREF_CONTEXT, + BT_BYTES_LIST_LE16(ctx))}); + int ret; + + ret = bt_audio_codec_cap_meta_get_pref_context(&codec_cap); + zassert_equal(ret, 0x0005, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_set_pref_context(&codec_cap, new_ctx); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_pref_context(&codec_cap); + zassert_equal(ret, 0x0100, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_stream_context) { const enum bt_audio_context ctx = @@ -567,6 +821,26 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_stream_context) zassert_equal(ret, 0x0005, "unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_stream_context) +{ + enum bt_audio_context ctx = BT_AUDIO_CONTEXT_TYPE_UNSPECIFIED | BT_AUDIO_CONTEXT_TYPE_MEDIA; + struct bt_audio_codec_cap codec_cap = + BT_AUDIO_CODEC_CAP(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_STREAM_CONTEXT, + BT_BYTES_LIST_LE16(ctx))}); + int ret; + + ret = bt_audio_codec_cap_meta_get_stream_context(&codec_cap); + zassert_equal(ret, 0x0005, "Unexpected return value %d", ret); + + ctx = BT_AUDIO_CONTEXT_TYPE_NOTIFICATIONS; + ret = bt_audio_codec_cap_meta_set_stream_context(&codec_cap, ctx); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_stream_context(&codec_cap); + zassert_equal(ret, 0x0100, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_program_info) { const uint8_t expected_data[] = {'P', 'r', 'o', 'g', 'r', 'a', 'm', ' ', @@ -584,6 +858,31 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_program_info) zassert_mem_equal(expected_data, program_data, ARRAY_SIZE(expected_data)); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_program_info) +{ + const uint8_t expected_data[] = {'P', 'r', 'o', 'g', 'r', 'a', + 'm', ' ', 'I', 'n', 'f', 'o'}; + const uint8_t new_expected_data[] = {'N', 'e', 'w', ' ', 'i', 'n', 'f', 'o'}; + struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PROGRAM_INFO, 'P', 'r', 'o', 'g', 'r', + 'a', 'm', ' ', 'I', 'n', 'f', 'o')}); + const uint8_t *program_data; + int ret; + + ret = bt_audio_codec_cap_meta_get_program_info(&codec_cap, &program_data); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, program_data, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cap_meta_set_program_info(&codec_cap, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_program_info(&codec_cap, &program_data); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, program_data, ARRAY_SIZE(new_expected_data)); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_stream_lang) { const uint32_t expected_data = sys_get_le24((uint8_t[]){'e', 'n', 'g'}); @@ -596,6 +895,26 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_stream_lang) zassert_equal(ret, expected_data, "Unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_stream_lang) +{ + const uint32_t expected_data = sys_get_le24((uint8_t[]){'e', 'n', 'g'}); + const uint32_t new_expected_data = sys_get_le24((uint8_t[]){'d', 'e', 'u'}); + struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_STREAM_LANG, 'e', 'n', 'g')}); + const uint32_t new_stream_lang = sys_le32_to_cpu(new_expected_data); + int ret; + + ret = bt_audio_codec_cap_meta_get_stream_lang(&codec_cap); + zassert_equal(ret, expected_data, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_set_stream_lang(&codec_cap, new_stream_lang); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_stream_lang(&codec_cap); + zassert_equal(ret, new_expected_data, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_ccid_list) { const uint8_t expected_data[] = {0x05, 0x10, 0x15}; @@ -610,6 +929,29 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_ccid_list) zassert_mem_equal(expected_data, ccid_list, ARRAY_SIZE(expected_data)); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_ccid_list) +{ + const uint8_t expected_data[] = {0x05, 0x10, 0x15}; + const uint8_t new_expected_data[] = {0x25, 0x30}; + struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_CCID_LIST, 0x05, 0x10, 0x15)}); + const uint8_t *ccid_list; + int ret; + + ret = bt_audio_codec_cap_meta_get_ccid_list(&codec_cap, &ccid_list); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, ccid_list, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cap_meta_set_ccid_list(&codec_cap, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_ccid_list(&codec_cap, &ccid_list); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, ccid_list, ARRAY_SIZE(new_expected_data)); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_parental_rating) { const struct bt_audio_codec_cap codec_cap = @@ -622,6 +964,25 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_parental_rating) zassert_equal(ret, 0x07, "Unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_parental_rating) +{ + struct bt_audio_codec_cap codec_cap = + BT_AUDIO_CODEC_CAP(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PARENTAL_RATING, + BT_AUDIO_PARENTAL_RATING_AGE_10_OR_ABOVE)}); + int ret; + + ret = bt_audio_codec_cap_meta_get_parental_rating(&codec_cap); + zassert_equal(ret, 0x07, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_set_parental_rating(&codec_cap, + BT_AUDIO_PARENTAL_RATING_AGE_13_OR_ABOVE); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_parental_rating(&codec_cap); + zassert_equal(ret, 0x0a, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_program_info_uri) { const uint8_t expected_data[] = {'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'}; @@ -637,6 +998,30 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_program_info_uri) zassert_mem_equal(expected_data, program_info_uri, ARRAY_SIZE(expected_data)); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_program_info_uri) +{ + const uint8_t expected_data[] = {'e', 'x', 'a', 'm', 'p', 'l', 'e', '.', 'c', 'o', 'm'}; + const uint8_t new_expected_data[] = {'n', 'e', 'w', '.', 'c', 'o', 'm'}; + struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_PROGRAM_INFO_URI, 'e', 'x', 'a', 'm', + 'p', 'l', 'e', '.', 'c', 'o', 'm')}); + const uint8_t *program_info_uri; + int ret; + + ret = bt_audio_codec_cap_meta_get_program_info_uri(&codec_cap, &program_info_uri); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, program_info_uri, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cap_meta_set_program_info_uri(&codec_cap, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_program_info_uri(&codec_cap, &program_info_uri); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, program_info_uri, ARRAY_SIZE(new_expected_data)); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_audio_active_state) { const struct bt_audio_codec_cap codec_cap = @@ -649,6 +1034,25 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_audio_active_stat zassert_equal(ret, 0x01, "Unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_audio_active_state) +{ + struct bt_audio_codec_cap codec_cap = + BT_AUDIO_CODEC_CAP(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_AUDIO_STATE, + BT_AUDIO_ACTIVE_STATE_ENABLED)}); + int ret; + + ret = bt_audio_codec_cap_meta_get_audio_active_state(&codec_cap); + zassert_equal(ret, 0x01, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_set_audio_active_state(&codec_cap, + BT_AUDIO_ACTIVE_STATE_DISABLED); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_audio_active_state(&codec_cap); + zassert_equal(ret, 0x00, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag) { const struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( @@ -660,6 +1064,22 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_bcast_audio_immed zassert_equal(ret, 0, "Unexpected return value %d", ret); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_bcast_audio_immediate_rend_flag) +{ + struct bt_audio_codec_cap codec_cap = + BT_AUDIO_CODEC_CAP(BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, {}); + int ret; + + ret = bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag(&codec_cap); + zassert_equal(ret, -ENODATA, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_set_bcast_audio_immediate_rend_flag(&codec_cap); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_bcast_audio_immediate_rend_flag(&codec_cap); + zassert_equal(ret, 0, "Unexpected return value %d", ret); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_extended) { const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; @@ -674,6 +1094,29 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_extended) zassert_mem_equal(expected_data, extended_meta, ARRAY_SIZE(expected_data)); } +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_extended) +{ + const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; + const uint8_t new_expected_data[] = {0x04, 0x05}; + struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_EXTENDED, 0x00, 0x01, 0x02, 0x03)}); + const uint8_t *extended_meta; + int ret; + + ret = bt_audio_codec_cap_meta_get_extended(&codec_cap, &extended_meta); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, extended_meta, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cap_meta_set_extended(&codec_cap, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_extended(&codec_cap, &extended_meta); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, extended_meta, ARRAY_SIZE(new_expected_data)); +} + ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_vendor) { const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; @@ -687,3 +1130,26 @@ ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_get_vendor) zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); zassert_mem_equal(expected_data, vendor_meta, ARRAY_SIZE(expected_data)); } + +ZTEST(audio_codec_test_suite, test_bt_audio_codec_cap_meta_set_vendor) +{ + const uint8_t expected_data[] = {0x00, 0x01, 0x02, 0x03}; + const uint8_t new_expected_data[] = {0x04, 0x05, 0x06, 0x07, 0x08}; + struct bt_audio_codec_cap codec_cap = BT_AUDIO_CODEC_CAP( + BT_HCI_CODING_FORMAT_LC3, 0x0000, 0x0000, {}, + {BT_AUDIO_CODEC_DATA(BT_AUDIO_METADATA_TYPE_VENDOR, 0x00, 0x01, 0x02, 0x03)}); + const uint8_t *extended_meta; + int ret; + + ret = bt_audio_codec_cap_meta_get_vendor(&codec_cap, &extended_meta); + zassert_equal(ret, ARRAY_SIZE(expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(expected_data, extended_meta, ARRAY_SIZE(expected_data)); + + ret = bt_audio_codec_cap_meta_set_vendor(&codec_cap, new_expected_data, + ARRAY_SIZE(new_expected_data)); + zassert_true(ret > 0, "Unexpected return value %d", ret); + + ret = bt_audio_codec_cap_meta_get_vendor(&codec_cap, &extended_meta); + zassert_equal(ret, ARRAY_SIZE(new_expected_data), "Unexpected return value %d", ret); + zassert_mem_equal(new_expected_data, extended_meta, ARRAY_SIZE(new_expected_data)); +}