Bluetooth: BAP: Refactor bt_bap_base
This removes the fixed size bt_bap_base, which provides 2 improvements: 1) The RAM usage of the broadcast sink has been reduced. For the Broadcast Sink sample it is a reduction of 120 octets, but with much better scaling for supporting more or larger BASEs. 2) The functions to parse BASEs now support arbitrary sized BASEs, where they were previously restricted by our local Kconfig options. This allow us to parse any BASE from a remote device, without encounting memory issues. We are still memory restricted on the devices we actually want to sync to. Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
parent
031c842ecb
commit
c9daed9712
18 changed files with 1330 additions and 681 deletions
|
@ -252,44 +252,71 @@ static struct bt_bap_stream_ops stream_ops = {
|
|||
.recv = stream_recv_cb,
|
||||
};
|
||||
|
||||
static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap_base *base)
|
||||
#if defined(CONFIG_LIBLC3)
|
||||
static bool base_subgroup_cb(const struct bt_bap_base_subgroup *subgroup, void *user_data)
|
||||
{
|
||||
struct bt_audio_codec_cfg *codec_cfg = user_data;
|
||||
struct bt_bap_base_codec_id codec_id;
|
||||
int ret;
|
||||
|
||||
ret = bt_bap_base_get_subgroup_codec_id(subgroup, &codec_id);
|
||||
if (ret < 0) {
|
||||
printk("Could not get codec id for subgroup %p: %d", subgroup, ret);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (codec_id.id != BT_HCI_CODING_FORMAT_LC3) {
|
||||
printk("Unsupported codec for subgroup %p: 0x%02x", subgroup, codec_id.id);
|
||||
return true; /* parse next subgroup */
|
||||
}
|
||||
|
||||
ret = bt_bap_base_subgroup_codec_to_codec_cfg(subgroup, codec_cfg);
|
||||
if (ret < 0) {
|
||||
printk("Could convert subgroup %p to codec_cfg: %d", subgroup, ret);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false; /* We only care about the first subgroup with LC3 */
|
||||
}
|
||||
#endif /* CONFIG_LIBLC3 */
|
||||
|
||||
static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap_base *base,
|
||||
size_t base_size)
|
||||
{
|
||||
uint32_t base_bis_index_bitfield = 0U;
|
||||
int err;
|
||||
|
||||
if (k_sem_count_get(&sem_base_received) != 0U) {
|
||||
return;
|
||||
}
|
||||
|
||||
printk("Received BASE with %u subgroups from broadcast sink %p\n",
|
||||
base->subgroup_count, sink);
|
||||
printk("Received BASE with %d subgroups from broadcast sink %p\n",
|
||||
bt_bap_base_get_subgroup_count(base), sink);
|
||||
|
||||
for (size_t i = 0U; i < base->subgroup_count; i++) {
|
||||
const size_t bis_count = base->subgroups[i].bis_count;
|
||||
|
||||
printk("Subgroup[%zu] has %zu streams\n", i, bis_count);
|
||||
|
||||
for (size_t j = 0U; j < bis_count; j++) {
|
||||
const uint8_t index = base->subgroups[i].bis_data[j].index;
|
||||
|
||||
printk("\tIndex 0x%02x\n", index);
|
||||
|
||||
base_bis_index_bitfield |= BIT(index);
|
||||
}
|
||||
#if defined(CONFIG_LIBLC3)
|
||||
int ret;
|
||||
const struct bt_audio_codec_cfg *codec_cfg = &base->subgroups[i].codec_cfg;
|
||||
struct bt_audio_codec_cfg codec_cfg = {0};
|
||||
|
||||
if (codec_cfg->id != BT_HCI_CODING_FORMAT_LC3) {
|
||||
printk("unsupported codec 0x%02x", codec_cfg->id);
|
||||
return;
|
||||
}
|
||||
err = bt_bap_base_foreach_subgroup(base, base_subgroup_cb, &codec_cfg);
|
||||
if (err != 0 && err != -ECANCELED) {
|
||||
printk("Failed to parse subgroups: %d\n", err);
|
||||
return;
|
||||
} else if (codec_cfg.id != BT_HCI_CODING_FORMAT_LC3) {
|
||||
/* No subgroups with LC3 was found */
|
||||
printk("Did not parse an LC3 codec\n");
|
||||
return;
|
||||
}
|
||||
|
||||
ret = lc3_enable(codec_cfg);
|
||||
if (ret < 0) {
|
||||
printk("Error: cannot enable LC3 codec: %d", ret);
|
||||
return;
|
||||
}
|
||||
#endif /* defined(CONFIG_LIBLC3) */
|
||||
err = lc3_enable(&codec_cfg);
|
||||
if (err < 0) {
|
||||
printk("Error: cannot enable LC3 codec: %d", err);
|
||||
return;
|
||||
}
|
||||
#endif /* CONFIG_LIBLC3 */
|
||||
|
||||
err = bt_bap_base_get_bis_indexes(base, &base_bis_index_bitfield);
|
||||
if (err != 0) {
|
||||
printk("Failed to BIS indexes: %d\n", err);
|
||||
return;
|
||||
}
|
||||
|
||||
bis_index_bitfield = base_bis_index_bitfield & bis_index_mask;
|
||||
|
|
|
@ -215,29 +215,20 @@ static void broadcast_scan_timeout(void)
|
|||
|
||||
static bool pa_decode_base(struct bt_data *data, void *user_data)
|
||||
{
|
||||
const struct bt_bap_base *base = bt_bap_base_get_base_from_ad(data);
|
||||
uint32_t base_bis_index_bitfield = 0U;
|
||||
struct bt_bap_base base = { 0 };
|
||||
int err;
|
||||
|
||||
if (data->type != BT_DATA_SVC_DATA16) {
|
||||
/* Base is NULL if the data does not contain a valid BASE */
|
||||
if (base == NULL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (data->data_len < BT_BAP_BASE_MIN_SIZE) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (bt_bap_decode_base(data, &base) != 0) {
|
||||
err = bt_bap_base_get_bis_indexes(base, &base_bis_index_bitfield);
|
||||
if (err != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0U; i < base.subgroup_count; i++) {
|
||||
for (size_t j = 0U; j < base.subgroups[i].bis_count; j++) {
|
||||
const uint8_t index = base.subgroups[i].bis_data[j].index;
|
||||
|
||||
base_bis_index_bitfield |= BIT(index);
|
||||
}
|
||||
}
|
||||
|
||||
bis_index_bitfield = base_bis_index_bitfield & bis_index_mask;
|
||||
k_sem_give(&sem_base_received);
|
||||
|
||||
|
@ -256,7 +247,8 @@ static void syncable_cb(struct bt_bap_broadcast_sink *sink, bool encrypted)
|
|||
k_sem_give(&sem_syncable);
|
||||
}
|
||||
|
||||
static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap_base *base)
|
||||
static void base_recv_cb(struct bt_bap_broadcast_sink *sink, const struct bt_bap_base *base,
|
||||
size_t base_size)
|
||||
{
|
||||
k_sem_give(&sem_base_received);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue