From c699ae5850297c824f8a7ca2a4f06174a9782fd3 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 11 Jul 2022 14:07:08 +0200 Subject: [PATCH] Bluetooth: Audio: Expose broadcast sink adv data to application In the broadcast sink `scan_recv` which is called when we scan for broadcast source, we now also provide the entire AD struct to the application. The reason for this is that the advertising data may contain other information that is useful for the application like the broadcaster device name or any other vendor/application specific data. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/audio/audio.h | 2 + .../bluetooth/broadcast_audio_sink/src/main.c | 1 + subsys/bluetooth/audio/broadcast_sink.c | 67 +++++++++++++------ subsys/bluetooth/shell/audio.c | 3 +- .../bsim_test_audio/src/broadcast_sink_test.c | 1 + 5 files changed, 54 insertions(+), 20 deletions(-) diff --git a/include/zephyr/bluetooth/audio/audio.h b/include/zephyr/bluetooth/audio/audio.h index d518f88311..917d6abc72 100644 --- a/include/zephyr/bluetooth/audio/audio.h +++ b/include/zephyr/bluetooth/audio/audio.h @@ -1529,12 +1529,14 @@ struct bt_audio_broadcast_sink_cb { * found. * * @param info Advertiser packet information. + * @param ad Buffer containing advertiser data. * @param broadcast_id 24-bit broadcast ID * * @return true to sync to the broadcaster, else false. * Syncing to the broadcaster will stop the current scan. */ bool (*scan_recv)(const struct bt_le_scan_recv_info *info, + struct net_buf_simple *ad, uint32_t broadcast_id); /** @brief Periodic advertising sync callback diff --git a/samples/bluetooth/broadcast_audio_sink/src/main.c b/samples/bluetooth/broadcast_audio_sink/src/main.c index bd83fdc223..1cd345d11a 100644 --- a/samples/bluetooth/broadcast_audio_sink/src/main.c +++ b/samples/bluetooth/broadcast_audio_sink/src/main.c @@ -58,6 +58,7 @@ static struct bt_audio_stream_ops stream_ops = { }; static bool scan_recv_cb(const struct bt_le_scan_recv_info *info, + struct net_buf_simple *ad, uint32_t broadcast_id) { k_sem_give(&sem_broadcaster_found); diff --git a/subsys/bluetooth/audio/broadcast_sink.c b/subsys/bluetooth/audio/broadcast_sink.c index d86c6f14fa..86ab95b80d 100644 --- a/subsys/bluetooth/audio/broadcast_sink.c +++ b/subsys/bluetooth/audio/broadcast_sink.c @@ -30,6 +30,11 @@ #define BASE_BIS_DATA_MIN_SIZE 2 /* index and length */ #define BROADCAST_SYNC_MIN_INDEX (BIT(1)) +/* any value above 0xFFFFFF is invalid, so we can just use 0xFFFFFFFF to denote + * invalid broadcast ID + */ +#define INVALID_BROADCAST_ID 0xFFFFFFFF + static struct bt_audio_iso broadcast_sink_iso [CONFIG_BT_AUDIO_BROADCAST_SNK_COUNT][BROADCAST_SNK_STREAM_CNT]; static struct bt_audio_ep broadcast_sink_eps @@ -700,10 +705,8 @@ static void sync_broadcast_pa(const struct bt_le_scan_recv_info *info, static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data) { - const struct bt_le_scan_recv_info *info = user_data; - struct bt_audio_broadcast_sink_cb *listener; + uint32_t *broadcast_id = user_data; struct bt_uuid_16 adv_uuid; - uint32_t broadcast_id; if (sys_slist_is_empty(&sink_cbs)) { /* Terminate early if we do not have any broadcast sink listeners */ @@ -731,21 +734,7 @@ static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data) return true; } - broadcast_id = sys_get_le24(data->data + BT_UUID_SIZE_16); - - BT_DBG("Found broadcast source with address %s and id 0x%6X", - bt_addr_le_str(info->addr), broadcast_id); - - SYS_SLIST_FOR_EACH_CONTAINER(&sink_cbs, listener, node) { - if (listener->scan_recv != NULL) { - bool sync_pa = listener->scan_recv(info, broadcast_id); - - if (sync_pa) { - sync_broadcast_pa(info, broadcast_id); - break; - } - } - } + *broadcast_id = sys_get_le24(data->data + BT_UUID_SIZE_16); /* Stop parsing */ return false; @@ -754,13 +743,53 @@ static bool scan_check_and_sync_broadcast(struct bt_data *data, void *user_data) static void broadcast_scan_recv(const struct bt_le_scan_recv_info *info, struct net_buf_simple *ad) { + struct bt_audio_broadcast_sink_cb *listener; + struct net_buf_simple_state state; + uint32_t broadcast_id; + /* We are only interested in non-connectable periodic advertisers */ if ((info->adv_props & BT_GAP_ADV_PROP_CONNECTABLE) || info->interval == 0) { return; } - bt_data_parse(ad, scan_check_and_sync_broadcast, (void *)info); + /* As scan_check_and_sync_broadcast modifies the AD data, + * we store the state before parsing it + */ + net_buf_simple_save(ad, &state); + broadcast_id = INVALID_BROADCAST_ID; + bt_data_parse(ad, scan_check_and_sync_broadcast, (void *)&broadcast_id); + net_buf_simple_restore(ad, &state); + + /* We check if `broadcast_id` was modified by `scan_check_and_sync_broadcast`. + * If it was then that means that we found a broadcast source + */ + if (broadcast_id != INVALID_BROADCAST_ID) { + BT_DBG("Found broadcast source with address %s and id 0x%6X", + bt_addr_le_str(info->addr), broadcast_id); + + SYS_SLIST_FOR_EACH_CONTAINER(&sink_cbs, listener, node) { + if (listener->scan_recv != NULL) { + bool sync_pa; + + + /* As the callback receiver may modify the AD + * data, we store the state so that we can + * restore it for each callback + */ + net_buf_simple_save(ad, &state); + + sync_pa = listener->scan_recv(info, ad, broadcast_id); + + if (sync_pa) { + sync_broadcast_pa(info, broadcast_id); + break; + } + + net_buf_simple_restore(ad, &state); + } + } + } } static void broadcast_scan_timeout(void) diff --git a/subsys/bluetooth/shell/audio.c b/subsys/bluetooth/shell/audio.c index 82d9c96e8c..0190329c45 100644 --- a/subsys/bluetooth/shell/audio.c +++ b/subsys/bluetooth/shell/audio.c @@ -985,7 +985,8 @@ static struct bt_audio_base received_base; static bool sink_syncable; static bool scan_recv(const struct bt_le_scan_recv_info *info, - uint32_t broadcast_id) + struct net_buf_simple *ad, + uint32_t broadcast_id) { shell_print(ctx_shell, "Found broadcaster with ID 0x%06X", broadcast_id); diff --git a/tests/bluetooth/bsim_bt/bsim_test_audio/src/broadcast_sink_test.c b/tests/bluetooth/bsim_bt/bsim_test_audio/src/broadcast_sink_test.c index d08cdbaa16..5a99880884 100644 --- a/tests/bluetooth/bsim_bt/bsim_test_audio/src/broadcast_sink_test.c +++ b/tests/bluetooth/bsim_bt/bsim_test_audio/src/broadcast_sink_test.c @@ -38,6 +38,7 @@ static const uint32_t bis_index_mask = BIT_MASK(ARRAY_SIZE(streams) + 1U); static uint32_t bis_index_bitfield; static bool scan_recv_cb(const struct bt_le_scan_recv_info *info, + struct net_buf_simple *ad, uint32_t broadcast_id) { SET_FLAG(broadcaster_found);