Commit eff93d26 authored by Emil Gydesen's avatar Emil Gydesen Committed by Benjamin Cabé
Browse files

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: default avatarEmil Gydesen <emil.gydesen@nordicsemi.no>
parent 051a2b6c
Loading
Loading
Loading
Loading
+19 −38
Changes for subsys/bluetooth/audio/ascs.c: 19 added lines, 38 removed lines.
Original line number Diff line number Diff line
@@ -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;

	bt_pacs_cap_foreach(ep->dir, codec_lookup_id, &lookup_data);
	codec_id.id = codec_cfg->id;
	codec_id.cid = codec_cfg->cid;
	codec_id.vid = codec_cfg->vid;

	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;
	}

+14 −21
Changes for subsys/bluetooth/audio/bap_broadcast_sink.c: 14 added lines, 21 removed lines.
Original line number Diff line number Diff line
@@ -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;

	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_id.id = codec_cfg.id;
	codec_id.cid = codec_cfg.cid;
	codec_id.vid = codec_cfg.vid;

	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;

+33 −0
Changes for subsys/bluetooth/audio/pacs.c: 33 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -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;
}
+4 −0
Changes for subsys/bluetooth/audio/pacs_internal.h: 4 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -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);
+10 −0
Changes for tests/bluetooth/audio/mocks/src/pacs.c: 10 added lines, 0 removed lines.
Original line number Diff line number Diff line
@@ -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;
}