Bluetooth: audio: pacs: Refactor PAC read handler

This makes use of bt_audio_foreach_capability fuction to
simplify building the PAC attribute value.

Signed-off-by: Mariusz Skamra <mariusz.skamra@codecoup.pl>
This commit is contained in:
Mariusz Skamra 2022-10-18 22:37:32 +02:00 committed by Carles Cufí
commit 43ffe3cad9

View file

@ -58,87 +58,64 @@ static void pac_data_add(struct net_buf_simple *buf, uint8_t num,
} }
} }
static int publish_capability(struct bt_conn *conn, uint8_t dir, struct pac_records_build_data {
uint8_t index, struct bt_codec *codec) struct bt_pacs_read_rsp *rsp;
struct net_buf_simple *buf;
};
static bool build_pac_records(const struct bt_audio_capability *capability, void *user_data)
{ {
struct bt_audio_capability *cap; struct pac_records_build_data *data = user_data;
sys_slist_t *lst; struct net_buf_simple *buf = data->buf;
uint8_t i; struct bt_pac_meta *meta;
struct bt_codec *codec;
struct bt_pac *pac;
if (dir == BT_AUDIO_DIR_SINK) { codec = capability->codec;
lst = &snks;
} else if (dir == BT_AUDIO_DIR_SOURCE) {
lst = &srcs;
} else {
BT_ERR("Invalid endpoint dir: %u", dir);
return -EINVAL;
}
i = 0; pac = net_buf_simple_add(buf, sizeof(*pac));
SYS_SLIST_FOR_EACH_CONTAINER(lst, cap, _node) { pac->codec.id = codec->id;
if (i != index) { pac->codec.cid = sys_cpu_to_le16(codec->cid);
i++; pac->codec.vid = sys_cpu_to_le16(codec->vid);
continue; pac->cc_len = buf->len;
}
(void)memcpy(codec, cap->codec, sizeof(*codec)); BT_DBG("Parsing codec config data");
pac_data_add(buf, codec->data_count, codec->data);
return 0; /* Buffer size shall never be below PAC len since we are just
} * append data.
*/
__ASSERT_NO_MSG(buf->len >= pac->cc_len);
return -ENOENT; pac->cc_len = buf->len - pac->cc_len;
meta = net_buf_simple_add(buf, sizeof(*meta));
meta->len = buf->len;
BT_DBG("Parsing metadata");
pac_data_add(buf, codec->meta_count, codec->meta);
meta->len = buf->len - meta->len;
BT_DBG("pac #%u: codec capability len %u metadata len %u",
data->rsp->num_pac, pac->cc_len, meta->len);
data->rsp->num_pac++;
return true;
} }
static void get_pac_records(struct bt_conn *conn, enum bt_audio_dir dir, static void get_pac_records(struct bt_conn *conn, enum bt_audio_dir dir,
struct net_buf_simple *buf) struct net_buf_simple *buf)
{ {
struct bt_pacs_read_rsp *rsp; struct pac_records_build_data data;
/* Reset if buffer before using */ /* Reset if buffer before using */
net_buf_simple_reset(buf); net_buf_simple_reset(buf);
rsp = net_buf_simple_add(buf, sizeof(*rsp)); data.rsp = net_buf_simple_add(buf, sizeof(*data.rsp));
rsp->num_pac = 0; data.rsp->num_pac = 0;
data.buf = buf;
while (true) { bt_audio_foreach_capability(dir, build_pac_records, &data);
struct bt_pac_meta *meta;
struct bt_codec codec;
struct bt_pac *pac;
int err;
err = publish_capability(conn, dir, rsp->num_pac, &codec);
if (err != 0) {
break;
}
pac = net_buf_simple_add(buf, sizeof(*pac));
pac->codec.id = codec.id;
pac->codec.cid = sys_cpu_to_le16(codec.cid);
pac->codec.vid = sys_cpu_to_le16(codec.vid);
pac->cc_len = buf->len;
BT_DBG("Parsing codec config data");
pac_data_add(buf, codec.data_count, codec.data);
/* Buffer size shall never be below PAC len since we are just
* append data.
*/
__ASSERT_NO_MSG(buf->len >= pac->cc_len);
pac->cc_len = buf->len - pac->cc_len;
meta = net_buf_simple_add(buf, sizeof(*meta));
meta->len = buf->len;
BT_DBG("Parsing metadata");
pac_data_add(buf, codec.meta_count, codec.meta);
meta->len = buf->len - meta->len;
BT_DBG("pac #%u: codec capability len %u metadata len %u",
rsp->num_pac, pac->cc_len, meta->len);
rsp->num_pac++;
}
} }
static void available_context_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value) static void available_context_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value)