Bluetooth: Audio: Add bt_audio_codec_cap_get helper functions
Add helper function to get specific values from a codec capability struct. Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
parent
b54951b86e
commit
e51ac69156
|
@ -651,12 +651,7 @@ int bt_audio_codec_cfg_get_octets_per_frame(const struct bt_audio_codec_cfg *cod
|
|||
int bt_audio_codec_cfg_get_frame_blocks_per_sdu(const struct bt_audio_codec_cfg *codec_cfg,
|
||||
bool fallback_to_default);
|
||||
|
||||
/** @brief Lookup a specific codec configuration value based on type
|
||||
* *
|
||||
* Typically types used are:
|
||||
* @ref bt_audio_codec_capability_type
|
||||
* @ref bt_audio_codec_config_type
|
||||
* @ref bt_audio_metadata_type
|
||||
/** @brief Lookup a specific codec configuration value
|
||||
*
|
||||
* @param[in] codec_cfg The codec data to search in.
|
||||
* @param[in] type The type id to look for
|
||||
|
@ -853,6 +848,94 @@ int bt_audio_codec_meta_get_vendor(const uint8_t meta[], size_t meta_len,
|
|||
const uint8_t **vendor_meta);
|
||||
|
||||
/** @} */ /* End of bt_audio_codec_meta */
|
||||
|
||||
/**
|
||||
* @brief Audio codec capabilities APIs
|
||||
* @defgroup bt_audio_codec_cap Codec capability parsing APIs
|
||||
*
|
||||
* Functions to parse codec capability data when formatted as LTV wrapped into @ref
|
||||
* bt_audio_codec_cap.
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @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[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);
|
||||
|
||||
/**
|
||||
* @brief Extract the frequency from a codec capability.
|
||||
*
|
||||
* @param codec_cap The codec configuration to extract data from.
|
||||
*
|
||||
* @retval Bitfield of supported frequencies if 0 or positive
|
||||
* @retval -EINVAL if arguments are invalid
|
||||
* @retval -ENODATA if not found
|
||||
* @retval -EBADMSG if found value has invalid size or value
|
||||
*/
|
||||
int bt_audio_codec_cap_get_freq(const struct bt_audio_codec_cap *codec_cap);
|
||||
|
||||
/**
|
||||
* @brief Extract the frequency from a codec capability.
|
||||
*
|
||||
* @param codec_cap The codec configuration to extract data from.
|
||||
*
|
||||
* @retval Bitfield of supported frame durations if 0 or positive
|
||||
* @retval -EINVAL if arguments are invalid
|
||||
* @retval -ENODATA if not found
|
||||
* @retval -EBADMSG if found value has invalid size or value
|
||||
*/
|
||||
int bt_audio_codec_cap_get_frame_duration(const struct bt_audio_codec_cap *codec_cap);
|
||||
|
||||
/**
|
||||
* @brief Extract the frequency from a codec capability.
|
||||
*
|
||||
* @param codec_cap The codec configuration to extract data from.
|
||||
*
|
||||
* @retval Bitfield of supported channel counts if 0 or positive
|
||||
* @retval -EINVAL if arguments are invalid
|
||||
* @retval -ENODATA if not found
|
||||
* @retval -EBADMSG if found value has invalid size or value
|
||||
*/
|
||||
int bt_audio_codec_cap_get_supported_audio_chan_counts(const struct bt_audio_codec_cap *codec_cap);
|
||||
|
||||
/**
|
||||
* @brief Extract the frequency from a codec capability.
|
||||
*
|
||||
* @param[in] codec_cap The codec configuration to extract data from.
|
||||
* @param[out] codec_frame Struct to place the resulting values in
|
||||
*
|
||||
* @retval 0 on success
|
||||
* @retval -EINVAL if arguments are invalid
|
||||
* @retval -ENODATA if not found
|
||||
* @retval -EBADMSG if found value has invalid size or value
|
||||
*/
|
||||
int bt_audio_codec_cap_get_octets_per_frame(
|
||||
const struct bt_audio_codec_cap *codec_cap,
|
||||
struct bt_audio_codec_octets_per_codec_frame *codec_frame);
|
||||
|
||||
/**
|
||||
* @brief Extract the frequency from a codec capability.
|
||||
*
|
||||
* @param codec_cap The codec configuration to extract data from.
|
||||
*
|
||||
* @retval Maximum number of codec frames per SDU supported
|
||||
* @retval -EINVAL if arguments are invalid
|
||||
* @retval -ENODATA if not found
|
||||
* @retval -EBADMSG if found value has invalid size or value
|
||||
*/
|
||||
int bt_audio_codec_cap_get_max_codec_frames_per_sdu(const struct bt_audio_codec_cap *codec_cap);
|
||||
|
||||
/** @} */ /* End of bt_audio_codec_cap */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -26,6 +26,11 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @brief LC3 codec ID
|
||||
*/
|
||||
#define BT_HCI_CODING_FORMAT_LC3 0x06
|
||||
|
||||
/**
|
||||
* @brief Codec capability type id's
|
||||
*
|
||||
|
@ -145,6 +150,18 @@ enum bt_audio_codec_capability_type {
|
|||
#define BT_AUDIO_CODEC_LC3_CHAN_COUNT_SUPPORT(...) \
|
||||
((uint8_t)((FOR_EACH(BIT, (|), __VA_ARGS__)) >> 1))
|
||||
|
||||
struct BT_AUDIO_CODEC_LC3_frame_len {
|
||||
uint16_t min;
|
||||
uint16_t max;
|
||||
};
|
||||
|
||||
struct bt_audio_codec_octets_per_codec_frame {
|
||||
/** Minimum number of octets supported per codec frame */
|
||||
uint16_t min;
|
||||
/** Maximum number of octets supported per codec frame */
|
||||
uint16_t max;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Codec configuration type IDs
|
||||
*
|
||||
|
|
|
@ -545,3 +545,163 @@ int bt_audio_codec_meta_get_vendor(const uint8_t meta[], size_t meta_len,
|
|||
#endif /* CONFIG_BT_AUDIO_CODEC_CFG_MAX_METADATA_SIZE > 0 || \
|
||||
* CONFIG_BT_AUDIO_CODEC_CAP_MAX_METADATA_SIZE > 0 \
|
||||
*/
|
||||
|
||||
#if CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0
|
||||
|
||||
uint8_t bt_audio_codec_cap_get_val(const struct bt_audio_codec_cap *codec_cap, uint8_t type,
|
||||
const uint8_t **data)
|
||||
{
|
||||
struct search_type_param param = {
|
||||
.type = type,
|
||||
.data_len = 0,
|
||||
.data = data,
|
||||
};
|
||||
int err;
|
||||
|
||||
CHECKIF(codec_cap == NULL) {
|
||||
LOG_DBG("codec_cap is NULL");
|
||||
return 0;
|
||||
}
|
||||
|
||||
CHECKIF(data == NULL) {
|
||||
LOG_DBG("data is NULL");
|
||||
return 0;
|
||||
}
|
||||
|
||||
*data = NULL;
|
||||
|
||||
err = bt_audio_data_parse(codec_cap->data, codec_cap->data_len, parse_cb, ¶m);
|
||||
if (err != 0 && err != -ECANCELED) {
|
||||
LOG_DBG("Could not parse the data: %d", err);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (param.data == NULL) {
|
||||
LOG_DBG("Could not find the type %u", type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return param.data_len;
|
||||
}
|
||||
|
||||
int bt_audio_codec_cap_get_freq(const struct bt_audio_codec_cap *codec_cap)
|
||||
{
|
||||
const uint8_t *data;
|
||||
uint8_t data_len;
|
||||
|
||||
CHECKIF(codec_cap == NULL) {
|
||||
LOG_DBG("codec_cap is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data_len = bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_LC3_FREQ, &data);
|
||||
if (data == NULL) {
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
if (data_len != sizeof(uint16_t)) {
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
return sys_get_le16(data);
|
||||
}
|
||||
|
||||
int bt_audio_codec_cap_get_frame_duration(const struct bt_audio_codec_cap *codec_cap)
|
||||
{
|
||||
const uint8_t *data;
|
||||
uint8_t data_len;
|
||||
|
||||
CHECKIF(codec_cap == NULL) {
|
||||
LOG_DBG("codec_cap is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data_len = bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_LC3_DURATION, &data);
|
||||
if (data == NULL) {
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
if (data_len != sizeof(uint8_t)) {
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
return data[0];
|
||||
}
|
||||
|
||||
int bt_audio_codec_cap_get_supported_audio_chan_counts(const struct bt_audio_codec_cap *codec_cap)
|
||||
{
|
||||
const uint8_t *data;
|
||||
uint8_t data_len;
|
||||
|
||||
CHECKIF(codec_cap == NULL) {
|
||||
LOG_DBG("codec_cap is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data_len = bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_LC3_CHAN_COUNT, &data);
|
||||
if (data == NULL) {
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
if (data_len != sizeof(uint8_t)) {
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
return data[0];
|
||||
}
|
||||
|
||||
int bt_audio_codec_cap_get_octets_per_frame(
|
||||
const struct bt_audio_codec_cap *codec_cap,
|
||||
struct bt_audio_codec_octets_per_codec_frame *codec_frame)
|
||||
{
|
||||
const uint8_t *data;
|
||||
uint8_t data_len;
|
||||
|
||||
CHECKIF(codec_cap == NULL) {
|
||||
LOG_DBG("codec_cap is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
CHECKIF(codec_frame == NULL) {
|
||||
LOG_DBG("codec_frame is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data_len = bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_LC3_FRAME_LEN, &data);
|
||||
if (data == NULL) {
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
if (data_len != sizeof(uint32_t)) {
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
codec_frame->min = sys_get_le16(data);
|
||||
codec_frame->max = sys_get_le16(data + sizeof(codec_frame->min));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bt_audio_codec_cap_get_max_codec_frames_per_sdu(const struct bt_audio_codec_cap *codec_cap)
|
||||
{
|
||||
const uint8_t *data;
|
||||
uint8_t data_len;
|
||||
|
||||
CHECKIF(codec_cap == NULL) {
|
||||
LOG_DBG("codec_cap is NULL");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
data_len = bt_audio_codec_cap_get_val(codec_cap, BT_AUDIO_CODEC_LC3_FRAME_COUNT, &data);
|
||||
if (data == NULL) {
|
||||
return -ENODATA;
|
||||
}
|
||||
|
||||
if (data_len != sizeof(uint8_t)) {
|
||||
return -EBADMSG;
|
||||
}
|
||||
|
||||
return data[0];
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BT_AUDIO_CODEC_CAP_MAX_DATA_SIZE > 0 */
|
||||
|
|
Loading…
Reference in a new issue