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 <emil.gydesen@nordicsemi.no>
This commit is contained in:
Emil Gydesen 2022-07-11 14:07:08 +02:00 committed by Carles Cufí
parent bd64be452c
commit c699ae5850
5 changed files with 54 additions and 20 deletions

View file

@ -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

View file

@ -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);

View file

@ -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)

View file

@ -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);

View file

@ -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);