Bluetooth: BAP: Add common capability check

Instead of having 2 separate and non-equal checks for
capabilities in ASCS and the Broadcast Sink, there is now
a single function in pacs.c that performs the
check.

This reduces code size and makes it easier to maintain.

Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2024-12-19 11:06:22 +01:00 committed by Benjamin Cabé
parent 051a2b6cd0
commit eff93d268a
5 changed files with 79 additions and 58 deletions

View File

@ -1488,32 +1488,12 @@ static void ascs_cp_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)
LOG_DBG("attr %p value 0x%04x", attr, value);
}
struct codec_cap_lookup_id_data {
uint8_t id;
uint16_t cid;
uint16_t vid;
const struct bt_audio_codec_cap *codec_cap;
};
static bool codec_lookup_id(const struct bt_pacs_cap *cap, void *user_data)
{
struct codec_cap_lookup_id_data *data = user_data;
if (cap->codec_cap->id == data->id && cap->codec_cap->cid == data->cid &&
cap->codec_cap->vid == data->vid) {
data->codec_cap = cap->codec_cap;
return false;
}
return true;
}
static int ascs_ep_set_codec(struct bt_bap_ep *ep, uint8_t id, uint16_t cid, uint16_t vid,
uint8_t *cc, uint8_t len, struct bt_bap_ascs_rsp *rsp)
{
const struct bt_audio_codec_cap *codec_cap;
struct bt_audio_codec_cfg *codec_cfg;
struct codec_cap_lookup_id_data lookup_data = {
const struct bt_pac_codec codec_id = {
.id = id,
.cid = cid,
.vid = vid,
@ -1530,11 +1510,11 @@ static int ascs_ep_set_codec(struct bt_bap_ep *ep, uint8_t id, uint16_t cid, uin
LOG_DBG("ep %p dir %s codec id 0x%02x cid 0x%04x vid 0x%04x len %u",
ep, bt_audio_dir_str(ep->dir), id, cid, vid, len);
bt_pacs_cap_foreach(ep->dir, codec_lookup_id, &lookup_data);
if (lookup_data.codec_cap == NULL) {
LOG_DBG("Codec with id %u for dir %s is not supported by our capabilities",
id, bt_audio_dir_str(ep->dir));
codec_cap = bt_pacs_get_codec_cap(ep->dir, &codec_id);
if (codec_cap == NULL) {
LOG_DBG("Codec with id 0x%02x cid 0x%04x and vid 0x%04x for dir %s is not "
"supported by our capabilities",
codec_id.id, codec_id.cid, codec_id.vid, bt_audio_dir_str(ep->dir));
*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_CONF_INVALID,
BT_BAP_ASCS_REASON_CODEC);
@ -1546,7 +1526,7 @@ static int ascs_ep_set_codec(struct bt_bap_ep *ep, uint8_t id, uint16_t cid, uin
codec_cfg->vid = vid;
codec_cfg->data_len = len;
memcpy(codec_cfg->data, cc, len);
codec_cfg->path_id = lookup_data.codec_cap->path_id;
codec_cfg->path_id = codec_cap->path_id;
*rsp = BT_BAP_ASCS_RSP(BT_BAP_ASCS_RSP_CODE_SUCCESS, BT_BAP_ASCS_REASON_NONE);
@ -1728,10 +1708,11 @@ int bt_ascs_config_ase(struct bt_conn *conn, struct bt_bap_stream *stream,
struct bt_audio_codec_cfg *codec_cfg,
const struct bt_bap_qos_cfg_pref *qos_pref)
{
int err;
const struct bt_audio_codec_cap *codec_cap;
struct bt_ascs_ase *ase = NULL;
struct bt_pac_codec codec_id;
struct bt_bap_ep *ep;
struct codec_cap_lookup_id_data lookup_data;
int err;
CHECKIF(conn == NULL || stream == NULL || codec_cfg == NULL || qos_pref == NULL) {
LOG_DBG("NULL value(s) supplied)");
@ -1763,15 +1744,15 @@ int bt_ascs_config_ase(struct bt_conn *conn, struct bt_bap_stream *stream,
return -EINVAL;
}
lookup_data.id = codec_cfg->id;
lookup_data.cid = codec_cfg->cid;
lookup_data.vid = codec_cfg->vid;
codec_id.id = codec_cfg->id;
codec_id.cid = codec_cfg->cid;
codec_id.vid = codec_cfg->vid;
bt_pacs_cap_foreach(ep->dir, codec_lookup_id, &lookup_data);
if (lookup_data.codec_cap == NULL) {
LOG_DBG("Codec with id %u for dir %s is not supported by our capabilities",
codec_cfg->id, bt_audio_dir_str(ep->dir));
codec_cap = bt_pacs_get_codec_cap(ep->dir, &codec_id);
if (codec_cap == NULL) {
LOG_DBG("Codec with id 0x%02x cid 0x%04x and vid 0x%04x for dir %s is not "
"supported by our capabilities",
codec_id.id, codec_id.cid, codec_id.vid, bt_audio_dir_str(ep->dir));
return -ENOENT;
}

View File

@ -43,6 +43,7 @@
#include "audio_internal.h"
#include "bap_iso.h"
#include "bap_endpoint.h"
#include "pacs_internal.h"
LOG_MODULE_REGISTER(bt_bap_broadcast_sink, CONFIG_BT_BAP_BROADCAST_SINK_LOG_LEVEL);
@ -553,19 +554,6 @@ static void update_recv_state_base(const struct bt_bap_broadcast_sink *sink,
}
}
static bool codec_lookup_id(const struct bt_pacs_cap *cap, void *user_data)
{
struct codec_cap_lookup_id_data *data = user_data;
if (cap->codec_cap->id == data->id) {
data->codec_cap = cap->codec_cap;
return false;
}
return true;
}
struct store_base_info_data {
struct bt_bap_broadcast_sink_bis bis[CONFIG_BT_BAP_BROADCAST_SNK_STREAM_COUNT];
struct bt_bap_broadcast_sink_subgroup subgroups[CONFIG_BT_BAP_BROADCAST_SNK_SUBGROUP_COUNT];
@ -662,9 +650,10 @@ static bool base_subgroup_bis_index_cb(const struct bt_bap_base_subgroup_bis *bi
static bool base_subgroup_cb(const struct bt_bap_base_subgroup *subgroup, void *user_data)
{
struct bt_bap_broadcast_sink_subgroup *sink_subgroup;
struct codec_cap_lookup_id_data lookup_data = {0};
struct store_base_info_data *data = user_data;
const struct bt_audio_codec_cap *codec_cap;
struct bt_audio_codec_cfg codec_cfg;
struct bt_pac_codec codec_id;
int ret;
if (data->subgroup_count == ARRAY_SIZE(data->subgroups)) {
@ -682,14 +671,18 @@ static bool base_subgroup_cb(const struct bt_bap_base_subgroup *subgroup, void *
}
/* Lookup and assign path_id based on capabilities */
lookup_data.id = codec_cfg.id;
codec_id.id = codec_cfg.id;
codec_id.cid = codec_cfg.cid;
codec_id.vid = codec_cfg.vid;
bt_pacs_cap_foreach(BT_AUDIO_DIR_SINK, codec_lookup_id, &lookup_data);
if (lookup_data.codec_cap == NULL) {
LOG_DBG("Codec with id %u is not supported by our capabilities", lookup_data.id);
codec_cap = bt_pacs_get_codec_cap(BT_AUDIO_DIR_SINK, &codec_id);
if (codec_cap == NULL) {
LOG_DBG("Codec with id 0x%02x cid 0x%04x and vid 0x%04x is not supported by our "
"capabilities",
codec_id.id, codec_id.cid, codec_id.vid);
} else {
codec_cfg.path_id = lookup_data.codec_cap->path_id;
codec_cfg.ctlr_transcode = lookup_data.codec_cap->ctlr_transcode;
codec_cfg.path_id = codec_cap->path_id;
codec_cfg.ctlr_transcode = codec_cap->ctlr_transcode;
data->subgroup_codec_cfg = &codec_cfg;

View File

@ -1305,3 +1305,36 @@ enum bt_audio_context bt_pacs_get_available_contexts_for_conn(struct bt_conn *co
return pacs_get_available_contexts_for_conn(conn, dir);
}
struct codec_cap_lookup_id_data {
const struct bt_pac_codec *codec_id;
const struct bt_audio_codec_cap *codec_cap;
};
static bool codec_lookup_id(const struct bt_pacs_cap *cap, void *user_data)
{
struct codec_cap_lookup_id_data *data = user_data;
if (cap->codec_cap->id == data->codec_id->id &&
cap->codec_cap->cid == data->codec_id->cid &&
cap->codec_cap->vid == data->codec_id->vid) {
data->codec_cap = cap->codec_cap;
return false;
}
return true;
}
const struct bt_audio_codec_cap *bt_pacs_get_codec_cap(enum bt_audio_dir dir,
const struct bt_pac_codec *codec_id)
{
struct codec_cap_lookup_id_data lookup_data = {
.codec_id = codec_id,
.codec_cap = NULL,
};
bt_pacs_cap_foreach(dir, codec_lookup_id, &lookup_data);
return lookup_data.codec_cap;
}

View File

@ -9,6 +9,7 @@
#include <stdint.h>
#include <zephyr/bluetooth/audio/audio.h>
#include <zephyr/sys/util_macro.h>
#define BT_AUDIO_LOCATION_MASK BIT_MASK(28)
@ -38,3 +39,6 @@ struct bt_pacs_context {
uint16_t snk;
uint16_t src;
} __packed;
const struct bt_audio_codec_cap *bt_pacs_get_codec_cap(enum bt_audio_dir dir,
const struct bt_pac_codec *codec_id);

View File

@ -4,10 +4,12 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr/bluetooth/audio/audio.h>
#include <zephyr/types.h>
#include <zephyr/bluetooth/audio/pacs.h>
#include "pacs.h"
#include "pacs_internal.h"
/* List of fakes used by this unit tester */
#define PACS_FFF_FAKES_LIST(FAKE) \
@ -49,3 +51,11 @@ void mock_bt_pacs_cleanup(void)
{
}
const struct bt_audio_codec_cap *bt_pacs_get_codec_cap(enum bt_audio_dir dir,
const struct bt_pac_codec *codec_id)
{
static struct bt_audio_codec_cap mock_cap;
return &mock_cap;
}