From ecfba7ced2a6c7857d9b7b630550fccdb9d9b097 Mon Sep 17 00:00:00 2001 From: Graham Wacey Date: Tue, 21 May 2024 19:19:56 +0100 Subject: [PATCH] applications: nrf5340_audio: Rewrite adv population for broadcast_source While adding the manufacturer ID in the advertisement packet it was noticed that the adv packet for unicast_client and broadcast_source are done in completely different ways. This rewrites both to make them closer and with a view to setting these later with a shell. Signed-off-by: Graham Wacey --- .../nrf5340_audio/broadcast_source/main.c | 150 ++++++++++++- .../src/bluetooth/bt_management/bt_mgmt.c | 19 ++ .../src/bluetooth/bt_management/bt_mgmt.h | 15 ++ .../src/bluetooth/bt_stream/broadcast/Kconfig | 10 + .../bt_stream/broadcast/broadcast_source.c | 201 ++++++++++-------- .../bt_stream/broadcast/broadcast_source.h | 94 ++++++-- .../bt_stream/unicast/unicast_server.c | 51 ++--- .../nrf5340_audio/unicast_server/main.c | 12 +- 8 files changed, 404 insertions(+), 148 deletions(-) diff --git a/applications/nrf5340_audio/broadcast_source/main.c b/applications/nrf5340_audio/broadcast_source/main.c index 2ab7767d2206..1ad94ab112f5 100644 --- a/applications/nrf5340_audio/broadcast_source/main.c +++ b/applications/nrf5340_audio/broadcast_source/main.c @@ -44,6 +44,53 @@ K_THREAD_STACK_DEFINE(le_audio_msg_sub_thread_stack, CONFIG_LE_AUDIO_MSG_SUB_STA static enum stream_state strm_state = STATE_PAUSED; +/* Buffer for the UUIDs. */ +NET_BUF_SIMPLE_DEFINE_STATIC(uuid_data, CONFIG_EXT_ADV_UUID_BUF_MAX); + +/* Buffer for periodic advertising BASE data. */ +NET_BUF_SIMPLE_DEFINE_STATIC(base_data, 128); + +/* Extended advertising buffer. */ +static struct bt_data ext_adv_buf[CONFIG_EXT_ADV_BUF_MAX]; + +/* Periodic advertising buffer. */ +static struct bt_data per_adv_buf; + +#if (CONFIG_AURACAST) +/* Total size of the PBA buffer includes the 16-bit UUID, 8-bit features and the + * meta data size. + */ +#define BROADCAST_SRC_PBA_BUF_SIZE \ + (BROADCAST_SOURCE_PBA_HEADER_SIZE + CONFIG_BT_AUDIO_BROADCAST_PBA_METADATA_SIZE) + +/* Number of metadata items that can be assigned. */ +#define BROADCAST_SOURCE_PBA_METADATA_VACANT \ + (CONFIG_BT_AUDIO_BROADCAST_PBA_METADATA_SIZE / (sizeof(struct bt_data))) + +/* Make sure pba_buf is large enough for a 16bit UUID and meta data + * (any addition to pba_buf requires an increase of this value) + */ +uint8_t pba_data[BROADCAST_SRC_PBA_BUF_SIZE]; + +/** + * @brief Broadcast source static extended advertising data. + */ +static struct broadcast_source_ext_adv_data ext_adv_data = { + .uuid_buf = &uuid_data, + .pba_metadata_vacant_cnt = BROADCAST_SOURCE_PBA_METADATA_VACANT, + .pba_buf = pba_data}; +#else +/** + * @brief Broadcast source static extended advertising data. + */ +static struct broadcast_source_ext_adv_data ext_adv_data = {.uuid_buf = &uuid_data}; +#endif /* (CONFIG_AURACAST) */ + +/** + * @brief Broadcast source static periodic advertising data. + */ +static struct broadcast_source_per_adv_data per_adv_data = {.base_buf = &base_data}; + /* Function for handling all stream state changes */ static void stream_state_set(enum stream_state stream_state_new) { @@ -285,6 +332,92 @@ static int zbus_link_producers_observers(void) return 0; } +/* + * @brief The following configures the data for the extended advertising. + * This includes the Broadcast Audio Announcements [BAP 3.7.2.1] and Broadcast_ID + * [BAP 3.7.2.1.1] in the AUX_ADV_IND Extended Announcements. + * + * @param ext_adv_data Pointer to the extended advertising buffers. + * @param ext_adv_buf Pointer to the bt_data used for extended advertising. + * @param ext_adv_buf_size Size of @p ext_adv_buf. + * @param ext_adv_count Pointer to the number of elements added to @p adv_buf. + * + * @return 0 for success, error otherwise. + */ +static int ext_adv_populate(struct broadcast_source_ext_adv_data *ext_adv_data, + struct bt_data *ext_adv_buf, size_t ext_adv_buf_size, + size_t *ext_adv_count) +{ + int ret; + size_t ext_adv_buf_cnt = 0; + + ext_adv_buf[ext_adv_buf_cnt].type = BT_DATA_UUID16_SOME; + ext_adv_buf[ext_adv_buf_cnt].data = ext_adv_data->uuid_buf->data; + ext_adv_buf_cnt++; + + ret = bt_mgmt_manufacturer_uuid_populate(ext_adv_data->uuid_buf, + CONFIG_BT_DEVICE_MANUFACTURER_ID); + if (ret) { + LOG_ERR("Failed to add adv data with manufacturer ID: %d", ret); + return ret; + } + + ret = broadcast_source_ext_adv_populate(ext_adv_data, &ext_adv_buf[ext_adv_buf_cnt], + ext_adv_buf_size - ext_adv_buf_cnt); + if (ret < 0) { + LOG_ERR("Failed to add ext adv data for broadcast source: %d", ret); + return ret; + } + + ext_adv_buf_cnt += ret; + + /* Add the number of UUIDs */ + ext_adv_buf[0].data_len = ext_adv_data->uuid_buf->len; + + LOG_DBG("Size of adv data: %d, num_elements: %d", sizeof(struct bt_data) * ext_adv_buf_cnt, + ext_adv_buf_cnt); + + *ext_adv_count = ext_adv_buf_cnt; + + return 0; +} + +/* + * @brief The following configures the data for the periodic advertising. + * This includes the Basic Audio Announcement, including the + * BASE [BAP 3.7.2.2] and BIGInfo. + * + * @param pre_adv_data Pointer to the periodic advertising buffers. + * @param per_adv_buf Pointer to the bt_data used for periodic advertising. + * @param per_adv_buf_size Size of @p ext_adv_buf. + * @param per_adv_count Pointer to the number of elements added to @p adv_buf. + * + * @return 0 for success, error otherwise. + */ +static int per_adv_populate(struct broadcast_source_per_adv_data *pre_adv_data, + struct bt_data *per_adv_buf, size_t per_adv_buf_size, + size_t *per_adv_count) +{ + int ret; + size_t per_adv_buf_cnt = 0; + + ret = broadcast_source_per_adv_populate(pre_adv_data, per_adv_buf, + per_adv_buf_size - per_adv_buf_cnt); + if (ret < 0) { + LOG_ERR("Failed to add per adv data for broadcast source: %d", ret); + return ret; + } + + per_adv_buf_cnt += ret; + + LOG_DBG("Size of per adv data: %d, num_elements: %d", + sizeof(struct bt_data) * per_adv_buf_cnt, per_adv_buf_cnt); + + *per_adv_count = per_adv_buf_cnt; + + return 0; +} + uint8_t stream_state_get(void) { return strm_state; @@ -315,20 +448,18 @@ void streamctrl_send(void const *const data, size_t size, uint8_t num_ch) int main(void) { int ret; - static const struct bt_data *ext_adv; - static const struct bt_data *per_adv; LOG_DBG("nRF5340 APP core started"); + size_t ext_adv_buf_cnt = 0; + size_t per_adv_buf_cnt = 0; + ret = nrf5340_audio_dk_init(); ERR_CHK(ret); ret = nrf5340_audio_common_init(); ERR_CHK(ret); - size_t ext_adv_size = 0; - size_t per_adv_size = 0; - ret = zbus_subscribers_create(); ERR_CHK_MSG(ret, "Failed to create zbus subscriber threads"); @@ -343,9 +474,14 @@ int main(void) CONFIG_BT_AUDIO_BITRATE_BROADCAST_SRC, VALUE_NOT_SET); ERR_CHK_MSG(ret, "Failed to set sample- and bitrate"); - broadcast_source_adv_get(&ext_adv, &ext_adv_size, &per_adv, &per_adv_size); + ret = ext_adv_populate(&ext_adv_data, ext_adv_buf, ARRAY_SIZE(ext_adv_buf), + &ext_adv_buf_cnt); + ERR_CHK(ret); + + ret = per_adv_populate(&per_adv_data, &per_adv_buf, 1, &per_adv_buf_cnt); + ERR_CHK(ret); - ret = bt_mgmt_adv_start(ext_adv, ext_adv_size, per_adv, per_adv_size, false); + ret = bt_mgmt_adv_start(ext_adv_buf, ext_adv_buf_cnt, &per_adv_buf, per_adv_buf_cnt, false); ERR_CHK_MSG(ret, "Failed to start advertiser"); return 0; diff --git a/applications/nrf5340_audio/src/bluetooth/bt_management/bt_mgmt.c b/applications/nrf5340_audio/src/bluetooth/bt_management/bt_mgmt.c index 3f486f313cfd..10726e4f8538 100644 --- a/applications/nrf5340_audio/src/bluetooth/bt_management/bt_mgmt.c +++ b/applications/nrf5340_audio/src/bluetooth/bt_management/bt_mgmt.c @@ -327,6 +327,25 @@ static int local_identity_addr_print(void) return 0; } +int bt_mgmt_adv_buffer_put(struct bt_data *const adv_buf, int *index, size_t adv_buf_vacant, + size_t data_len, uint8_t type, void *data) +{ + if (adv_buf == NULL || index == NULL || data_len == 0) { + return -EINVAL; + } + + if ((adv_buf_vacant - *index) <= 0) { + return -ENOMEM; + } + + adv_buf[*index].type = type; + adv_buf[*index].data_len = data_len; + adv_buf[*index].data = data; + (*index)++; + + return 0; +} + int bt_mgmt_bonding_clear(void) { int ret; diff --git a/applications/nrf5340_audio/src/bluetooth/bt_management/bt_mgmt.h b/applications/nrf5340_audio/src/bluetooth/bt_management/bt_mgmt.h index 9611a26d9dfd..9675c2a70013 100644 --- a/applications/nrf5340_audio/src/bluetooth/bt_management/bt_mgmt.h +++ b/applications/nrf5340_audio/src/bluetooth/bt_management/bt_mgmt.h @@ -55,6 +55,21 @@ enum bt_mgmt_scan_type { #define BRDCAST_ID_NOT_USED (BT_AUDIO_BROADCAST_ID_MAX + 1) +/** + * @brief Load advertising data into an advertising buffer. + * + * @param[out] adv_buf Pointer to the advertising buffer to load. + * @param[in/out] index Next free index in the advertising buffer. + * @param[in] adv_buf_vacant Number of free advertising buffers. + * @param[in] type Type of the data. + * @param[in] data_len Length of the data. + * @param[in] data Data to store in the buffer, can be a pointer or value. + * + * @return 0 if success, error otherwise. + */ +int bt_mgmt_adv_buffer_put(struct bt_data *const adv_buf, int *index, size_t adv_buf_vacant, + size_t data_len, uint8_t type, void *data); + /** * @brief Start scanning for advertisements. * diff --git a/applications/nrf5340_audio/src/bluetooth/bt_stream/broadcast/Kconfig b/applications/nrf5340_audio/src/bluetooth/bt_stream/broadcast/Kconfig index 34ac24170991..dcbf120582e5 100644 --- a/applications/nrf5340_audio/src/bluetooth/bt_stream/broadcast/Kconfig +++ b/applications/nrf5340_audio/src/bluetooth/bt_stream/broadcast/Kconfig @@ -147,6 +147,16 @@ config BT_AUDIO_BROADCAST_ID_FIXED Fixed broadcast ID; 3 octets. Will only be used if BT_AUDIO_USE_BROADCAST_ID_RANDOM=n. Only use for debugging. +config BT_AUDIO_BROADCAST_PBA_METADATA_SIZE + hex "Configure PBA meta data buffer size" + depends on TRANSPORT_BIS && AURACAST + default 0x0010 + help + Configure the maximum size of the Public Broadcast Announcement meata data buffer in octets. + This is the number of meta data LVT records, or the number of meta data items multiplied by + the size of the LTV (sizeof(bt_data)). Configurable option that doesn't follow any preset. + Allows for more flexibility. + config BT_AUDIO_BROADCAST_PARENTAL_RATING hex "Parental rating" depends on TRANSPORT_BIS diff --git a/applications/nrf5340_audio/src/bluetooth/bt_stream/broadcast/broadcast_source.c b/applications/nrf5340_audio/src/bluetooth/bt_stream/broadcast/broadcast_source.c index 6908b92a275f..d6a8f6a9ba9b 100644 --- a/applications/nrf5340_audio/src/bluetooth/bt_stream/broadcast/broadcast_source.c +++ b/applications/nrf5340_audio/src/bluetooth/bt_stream/broadcast/broadcast_source.c @@ -17,6 +17,7 @@ /* TODO: Remove when a get_info function is implemented in host */ #include <../subsys/bluetooth/audio/bap_endpoint.h> +#include "bt_mgmt.h" #include "macros_common.h" #include "bt_le_audio_tx.h" #include "le_audio.h" @@ -28,6 +29,18 @@ LOG_MODULE_REGISTER(broadcast_source, CONFIG_BROADCAST_SOURCE_LOG_LEVEL); /* Length-type-value size for channel allocation */ #define LTV_CHAN_ALLOC_SIZE 6 +#if (CONFIG_AURACAST) +/* Index values into the PBA advertising data format. + * + * See Table 4.1 of the Public Broadcast Profile, Bluetooth® Profile Specification, v1.0. + */ +#define PBA_UUID_INDEX (0) +#define PBA_FEATURES_INDEX (2) +#define PBA_METADATA_SIZE_INDEX (3) +#define PBA_METADATA_START_INDEX (4) + +#endif /* CONFIG_AURACAST */ + BUILD_ASSERT(CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT <= 2, "A maximum of two audio streams are currently supported"); @@ -43,18 +56,6 @@ static bool delete_broadcast_src; uint8_t audio_mapping_mask[CONFIG_BT_BAP_BROADCAST_SRC_STREAM_COUNT] = {UINT8_MAX}; -#if (CONFIG_AURACAST) -/* Make sure pba_buf is large enough for a 16bit UUID and meta data - * (any addition to pba_buf requires an increase of this value) - */ -NET_BUF_SIMPLE_DEFINE(pba_buf, BT_UUID_SIZE_16 + 8); -static struct bt_data ext_ad[5]; -#else -static struct bt_data ext_ad[4]; -#endif /* (CONFIG_AURACAST) */ - -static struct bt_data per_ad[1]; - static void le_audio_event_publish(enum le_audio_evt_type event) { int ret; @@ -163,26 +164,39 @@ static void public_broadcast_features_set(uint8_t *features) } #endif /* (CONFIG_AURACAST) */ -static int adv_create(void) +int broadcast_source_ext_adv_populate(struct broadcast_source_ext_adv_data *ext_adv_data, + struct bt_data *ext_adv_buf, size_t ext_adv_buf_vacant) { int ret; uint32_t broadcast_id = 0; + size_t ext_adv_buf_cnt = 0; + size_t brdcst_name_size; + + if (ext_adv_data == NULL || ext_adv_buf == NULL || ext_adv_buf_vacant == 0) { + LOG_ERR("Advertising populate failed."); + return -EINVAL; + } - /* Broadcast Audio Streaming Endpoint advertising data */ - NET_BUF_SIMPLE_DEFINE_STATIC(brdcst_id_buf, BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE); - /* Buffer for Appearance */ - NET_BUF_SIMPLE_DEFINE_STATIC(brdcst_appearance_buf, BT_UUID_SIZE_16); - /* Buffer for manufacturer ID */ - NET_BUF_SIMPLE_DEFINE_STATIC(manufacturer_id_buf, BT_UUID_SIZE_16); - /* Buffer for Public Broadcast Announcement */ - NET_BUF_SIMPLE_DEFINE_STATIC(base_buf, 128); + sys_put_le16(BT_UUID_BROADCAST_AUDIO_VAL, ext_adv_data->brdcst_id_buf); - net_buf_simple_add_le16(&manufacturer_id_buf, CONFIG_BT_DEVICE_MANUFACTURER_ID); + if (IS_ENABLED(CONFIG_BT_AUDIO_USE_BROADCAST_NAME_ALT)) { + brdcst_name_size = sizeof(CONFIG_BT_AUDIO_BROADCAST_NAME_ALT) - 1; + memcpy(ext_adv_data->brdcst_name_buf, CONFIG_BT_AUDIO_BROADCAST_NAME_ALT, + brdcst_name_size); + } else { + brdcst_name_size = sizeof(CONFIG_BT_AUDIO_BROADCAST_NAME) - 1; + memcpy(ext_adv_data->brdcst_name_buf, CONFIG_BT_AUDIO_BROADCAST_NAME, + brdcst_name_size); + } - ext_ad[0].data_len = manufacturer_id_buf.len; - ext_ad[0].type = BT_DATA_UUID16_SOME; - ext_ad[0].data = manufacturer_id_buf.data; + ret = bt_mgmt_adv_buffer_put(ext_adv_buf, &ext_adv_buf_cnt, ext_adv_buf_vacant, + brdcst_name_size, BT_DATA_BROADCAST_NAME, + (void *)ext_adv_data->brdcst_name_buf); + if (ret) { + return ret; + } + /* Setup extended advertising data */ if (IS_ENABLED(CONFIG_BT_AUDIO_USE_BROADCAST_ID_RANDOM)) { ret = bt_cap_initiator_broadcast_get_id(broadcast_source, &broadcast_id); if (ret) { @@ -193,76 +207,95 @@ static int adv_create(void) broadcast_id = CONFIG_BT_AUDIO_BROADCAST_ID_FIXED; } - if (IS_ENABLED(CONFIG_BT_AUDIO_USE_BROADCAST_NAME_ALT)) { - ext_ad[1] = (struct bt_data)BT_DATA(BT_DATA_BROADCAST_NAME, - CONFIG_BT_AUDIO_BROADCAST_NAME_ALT, - sizeof(CONFIG_BT_AUDIO_BROADCAST_NAME_ALT) - 1); - } else { - ext_ad[1] = (struct bt_data)BT_DATA(BT_DATA_BROADCAST_NAME, - CONFIG_BT_AUDIO_BROADCAST_NAME, - sizeof(CONFIG_BT_AUDIO_BROADCAST_NAME) - 1); - } - - /* Setup extended advertising data */ - net_buf_simple_add_le16(&brdcst_id_buf, BT_UUID_BROADCAST_AUDIO_VAL); - net_buf_simple_add_le24(&brdcst_id_buf, broadcast_id); + sys_put_le24(broadcast_id, &ext_adv_data->brdcst_id_buf[BROADCAST_SOURCE_ADV_ID_START]); - ext_ad[2].data_len = brdcst_id_buf.len; - ext_ad[2].type = BT_DATA_SVC_DATA16; - ext_ad[2].data = brdcst_id_buf.data; + ret = bt_mgmt_adv_buffer_put(ext_adv_buf, &ext_adv_buf_cnt, ext_adv_buf_vacant, + sizeof(ext_adv_data->brdcst_id_buf), BT_DATA_SVC_DATA16, + (void *)ext_adv_data->brdcst_id_buf); + if (ret) { + return ret; + } - net_buf_simple_add_le16(&brdcst_appearance_buf, CONFIG_BT_DEVICE_APPEARANCE); + sys_put_le16(CONFIG_BT_DEVICE_APPEARANCE, ext_adv_data->brdcst_appearance_buf); - ext_ad[3].data_len = brdcst_appearance_buf.len; - ext_ad[3].type = BT_DATA_GAP_APPEARANCE; - ext_ad[3].data = brdcst_appearance_buf.data; + ret = bt_mgmt_adv_buffer_put(ext_adv_buf, &ext_adv_buf_cnt, ext_adv_buf_vacant, + sizeof(ext_adv_data->brdcst_appearance_buf), BT_DATA_GAP_APPEARANCE, + (void *)ext_adv_data->brdcst_appearance_buf); + if (ret) { + return ret; + } #if (CONFIG_AURACAST) - uint8_t pba_features = 0; - public_broadcast_features_set(&pba_features); + size_t meta_data_buf_cnt = 0; - net_buf_simple_add_le16(&pba_buf, 0x1856); - net_buf_simple_add_u8(&pba_buf, pba_features); + sys_put_le16(BT_UUID_PBA_VAL, &ext_adv_data->pba_buf[PBA_UUID_INDEX]); + public_broadcast_features_set(&ext_adv_data->pba_buf[PBA_FEATURES_INDEX]); - /* Metadata */ - /* 3 bytes for parental_rating and 3 bytes for active_flag LTVs */ - net_buf_simple_add_u8(&pba_buf, 0x06); - /* Parental rating*/ - /* Length */ - net_buf_simple_add_u8(&pba_buf, 0x02); - /* Type */ - net_buf_simple_add_u8(&pba_buf, BT_AUDIO_METADATA_TYPE_PARENTAL_RATING); - /* Value */ - net_buf_simple_add_u8(&pba_buf, CONFIG_BT_AUDIO_BROADCAST_PARENTAL_RATING); + /* Metadata */ + /* Parental rating */ + ret = bt_mgmt_adv_buffer_put( + (struct bt_data *)&ext_adv_data->pba_buf[PBA_METADATA_START_INDEX], + &meta_data_buf_cnt, ext_adv_data->pba_metadata_vacant_cnt, + sizeof(uint8_t), BT_AUDIO_METADATA_TYPE_PARENTAL_RATING, + (void *)CONFIG_BT_AUDIO_BROADCAST_PARENTAL_RATING); + if (ret) { + return ret; + } /* Active flag */ - /* Length */ - net_buf_simple_add_u8(&pba_buf, 0x02); - /* Type */ - net_buf_simple_add_u8(&pba_buf, BT_AUDIO_METADATA_TYPE_AUDIO_STATE); - /* Value */ - net_buf_simple_add_u8(&pba_buf, BT_AUDIO_ACTIVE_STATE_ENABLED); - - /* If any additional data is to be added, remember to increase NET_BUF size */ - - ext_ad[4].data_len = pba_buf.len; - ext_ad[4].type = BT_DATA_SVC_DATA16; - ext_ad[4].data = pba_buf.data; + ret = bt_mgmt_adv_buffer_put( + (struct bt_data *)&ext_adv_data->pba_buf[PBA_METADATA_START_INDEX], + &meta_data_buf_cnt, ext_adv_data->pba_metadata_vacant_cnt, + sizeof(uint8_t), BT_AUDIO_METADATA_TYPE_AUDIO_STATE, + (void *)BT_AUDIO_ACTIVE_STATE_ENABLED); + if (ret) { + return ret; + } + + /* Metadata size */ + ext_adv_data->pba_buf[PBA_METADATA_SIZE_INDEX] = + meta_data_buf_cnt * sizeof(struct bt_data); + + /* Add PBA buffer to extended advertising data */ + ret = bt_mgmt_adv_buffer_put(ext_adv_buf, &ext_adv_buf_cnt, ext_adv_buf_vacant, + BROADCAST_SOURCE_PBA_HEADER_SIZE + ext_adv_data->pba_buf[PBA_METADATA_SIZE_INDEX], + BT_DATA_SVC_DATA16, (void *)ext_adv_data->pba_buf); + if (ret) { + return ret; + } + #endif /* (CONFIG_AURACAST) */ + return ext_adv_buf_cnt; +} + +int broadcast_source_per_adv_populate(struct broadcast_source_per_adv_data *per_adv_data, + struct bt_data *per_adv_buf, size_t per_adv_buf_vacant) +{ + int ret; + size_t per_adv_buf_cnt = 0; + + if (per_adv_data == NULL || per_adv_buf == NULL || per_adv_buf_vacant == 0) { + LOG_ERR("Periodic advertising populate failed."); + return -EINVAL; + } + /* Setup periodic advertising data */ - ret = bt_cap_initiator_broadcast_get_base(broadcast_source, &base_buf); + ret = bt_cap_initiator_broadcast_get_base(broadcast_source, per_adv_data->base_buf); if (ret) { LOG_ERR("Failed to get encoded BASE: %d", ret); return ret; } - per_ad[0].data_len = base_buf.len; - per_ad[0].type = BT_DATA_SVC_DATA16; - per_ad[0].data = base_buf.data; + ret = bt_mgmt_adv_buffer_put(per_adv_buf, &per_adv_buf_cnt, per_adv_buf_vacant, + per_adv_data->base_buf->len, BT_DATA_SVC_DATA16, + (void *)per_adv_data->base_buf->data); + if (ret) { + return ret; + } - return 0; + return per_adv_buf_cnt; } /** @@ -280,15 +313,6 @@ static void bt_audio_codec_allocation_set(uint8_t *data, uint8_t data_len, sys_put_le32((const uint32_t)loc, &data[2]); } -void broadcast_source_adv_get(const struct bt_data **ext_adv, size_t *ext_adv_size, - const struct bt_data **per_adv, size_t *per_adv_size) -{ - *ext_adv = ext_ad; - *ext_adv_size = ARRAY_SIZE(ext_ad); - *per_adv = per_ad; - *per_adv_size = ARRAY_SIZE(per_ad); -} - int broadcast_source_start(struct bt_le_ext_adv *ext_adv) { int ret; @@ -477,13 +501,6 @@ int broadcast_source_enable(void) return ret; } - /* Create advertising set */ - ret = adv_create(); - if (ret) { - LOG_ERR("Failed to create advertising set"); - return ret; - } - initialized = true; LOG_DBG("Broadcast source enabled"); diff --git a/applications/nrf5340_audio/src/bluetooth/bt_stream/broadcast/broadcast_source.h b/applications/nrf5340_audio/src/bluetooth/bt_stream/broadcast/broadcast_source.h index e2f14ab9f6ef..2dc2cf6a8a23 100644 --- a/applications/nrf5340_audio/src/bluetooth/bt_stream/broadcast/broadcast_source.h +++ b/applications/nrf5340_audio/src/bluetooth/bt_stream/broadcast/broadcast_source.h @@ -77,54 +77,108 @@ #error Unsupported LC3 codec preset for broadcast #endif /* CONFIG_BT_AUDIO_BROADCAST_CONFIGURABLE */ +/* Size of the Public Broadcast Announcement header, 2-octet Service UUID followed by + * an octet for the features and an octet for the length of the meta data feild. + */ +#define BROADCAST_SOURCE_PBA_HEADER_SIZE (BT_UUID_SIZE_16 + (sizeof(uint8_t) * 2)) + +#define BROADCAST_SOURCE_ADV_NAME_MAX (32) +#define BROADCAST_SOURCE_ADV_ID_START (BT_UUID_SIZE_16) + +/** + * @brief Advertising data for broadcast source. + */ +struct broadcast_source_ext_adv_data { + /* Broadcast Audio Streaming UUIDs. */ + struct net_buf_simple *uuid_buf; + + /* Broadcast Audio Streaming Endpoint advertising data. */ + uint8_t brdcst_id_buf[BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE]; + + /* Buffer for Appearance. */ + uint8_t brdcst_appearance_buf[(sizeof(uint8_t) * 2)]; + + /* Broadcast name, must be between 4 and 32 UTF-8 encoded characters in length. */ + uint8_t brdcst_name_buf[BROADCAST_SOURCE_ADV_NAME_MAX]; + +#if (CONFIG_AURACAST) + /* Number of free metadata items */ + uint8_t pba_metadata_vacant_cnt; + + /* Public Broadcast Announcement buffer. */ + uint8_t *pba_buf; +#endif /* (CONFIG_AURACAST) */ +}; + +/** + * @brief Periodic advertising data for broadcast source. + */ +struct broadcast_source_per_adv_data { + /* Buffer for periodic advertising data */ + struct net_buf_simple *base_buf; +}; + +/** + * @brief Populate the extended advertising data buffer. + * + * @param[in] ext_adv_data Pointer to the extended advertising buffers. + * @param[out] ext_adv_buf Pointer to the bt_data used for extended advertising. + * @param[out] ext_adv_buf_vacant Pointer to unused size of @p ext_adv_buf. + * + * @return Negative values for errors or number of elements added to @p ext_adv_buf. + */ +int broadcast_source_ext_adv_populate(struct broadcast_source_ext_adv_data *ext_adv_data, + struct bt_data *ext_adv_buf, size_t ext_adv_buf_vacant); + /** - * @brief Get the data to advertise. + * @brief Populate the periodic advertising data buffer. + * + * @param[in] per_adv_data Pointer to a structure of periodic advertising buffers. + * @param[out] per_adv_buf Pointer to the bt_data used for periodic advertising. + * @param[out] per_adv_buf_vacant Pointer to unused size of @p per_adv_buf. * - * @param[out] ext_adv Pointer to the pointer of bt_data used for extended advertising. - * @param[out] ext_adv_size Pointer to size of @p ext_adv. - * @param[out] per_adv Pointer to the pointer of bt_data used for periodic advertising. - * @param[out] per_adv_size Pointer to size of @p per_adv. + * @return Negative values for errors or number of elements added to @p per_adv_buf. */ -void broadcast_source_adv_get(const struct bt_data **ext_adv, size_t *ext_adv_size, - const struct bt_data **per_adv, size_t *per_adv_size); +int broadcast_source_per_adv_populate(struct broadcast_source_per_adv_data *per_adv_data, + struct bt_data *per_adv_buf, size_t per_adv_buf_vacant); /** - * @brief Start the Bluetooth LE Audio broadcast (BIS) source. + * @brief Start the Bluetooth LE Audio broadcast (BIS) source. * - * @param[in] ext_adv Pointer to the extended advertising set; can be NULL if a stream - * is restarted. + * @param[in] ext_adv Pointer to the extended advertising set; can be NULL if a + * stream is restarted. * - * @return 0 for success, error otherwise. + * @return 0 for success, error otherwise. */ int broadcast_source_start(struct bt_le_ext_adv *ext_adv); /** - * @brief Stop the Bluetooth LE Audio broadcast (BIS) source. + * @brief Stop the Bluetooth LE Audio broadcast (BIS) source. * - * @return 0 for success, error otherwise. + * @return 0 for success, error otherwise. */ int broadcast_source_stop(void); /** - * @brief Broadcast the Bluetooth LE Audio data. + * @brief Broadcast the Bluetooth LE Audio data. * - * @param[in] enc_audio Encoded audio struct. + * @param[in] enc_audio Encoded audio struct. * - * @return 0 for success, error otherwise. + * @return 0 for success, error otherwise. */ int broadcast_source_send(struct le_audio_encoded_audio enc_audio); /** - * @brief Disable the LE Audio broadcast (BIS) source. + * @brief Disable the LE Audio broadcast (BIS) source. * - * @return 0 for success, error otherwise. + * @return 0 for success, error otherwise. */ int broadcast_source_disable(void); /** - * @brief Enable the LE Audio broadcast (BIS) source. + * @brief Enable the LE Audio broadcast (BIS) source. * - * @return 0 for success, error otherwise. + * @return 0 for success, error otherwise. */ int broadcast_source_enable(void); diff --git a/applications/nrf5340_audio/src/bluetooth/bt_stream/unicast/unicast_server.c b/applications/nrf5340_audio/src/bluetooth/bt_stream/unicast/unicast_server.c index 506b470ad73d..3681b0bd39fa 100644 --- a/applications/nrf5340_audio/src/bluetooth/bt_stream/unicast/unicast_server.c +++ b/applications/nrf5340_audio/src/bluetooth/bt_stream/unicast/unicast_server.c @@ -7,6 +7,7 @@ #include "unicast_server.h" #include +#include #include #include #include @@ -17,6 +18,7 @@ #include "macros_common.h" #include "nrf5340_audio_common.h" +#include "bt_mgmt.h" #include "bt_le_audio_tx.h" #include "le_audio.h" @@ -42,9 +44,9 @@ static struct bt_csip_set_member_svc_inst *csip; /* Advertising data for peer connection */ static uint8_t csip_rsi_adv_data[BT_CSIP_RSI_SIZE]; -static uint8_t flags_adv_data[] = {BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR}; +static uint8_t flags_adv_data; -static uint8_t gap_appear_adv_data[] = {BT_BYTES_LIST_LE16(CONFIG_BT_DEVICE_APPEARANCE)}; +static uint8_t gap_appear_adv_data[BT_UUID_SIZE_16]; static const uint8_t cap_adv_data[] = { BT_UUID_16_ENCODE(BT_UUID_CAS_VAL), @@ -446,21 +448,6 @@ static struct bt_bap_stream_ops stream_ops = { .released = stream_released_cb, }; -static int adv_buf_put(struct bt_data *adv_buf, uint8_t adv_buf_vacant, int *index, uint8_t type, - size_t data_len, const uint8_t *data) -{ - if ((adv_buf_vacant - *index) <= 0) { - return -ENOMEM; - } - - adv_buf[*index].type = type; - adv_buf[*index].data_len = data_len; - adv_buf[*index].data = data; - (*index)++; - - return 0; -} - int unicast_server_config_get(struct bt_conn *conn, enum bt_audio_dir dir, uint32_t *bitrate, uint32_t *sampling_rate_hz, uint32_t *pres_delay_us) { @@ -549,7 +536,6 @@ int unicast_server_uuid_populate(struct net_buf_simple *uuid_buf) if (net_buf_simple_tailroom(uuid_buf) >= (BT_UUID_SIZE_16 * 2)) { net_buf_simple_add_le16(uuid_buf, BT_UUID_ASCS_VAL); net_buf_simple_add_le16(uuid_buf, BT_UUID_PACS_VAL); - } else { LOG_ERR("Not enough space for UUIDS"); return -ENOMEM; @@ -563,34 +549,43 @@ int unicast_server_adv_populate(struct bt_data *adv_buf, uint8_t adv_buf_vacant) int ret; int adv_buf_cnt = 0; - ret = adv_buf_put(adv_buf, adv_buf_vacant, &adv_buf_cnt, BT_DATA_SVC_DATA16, - ARRAY_SIZE(unicast_server_adv_data), &unicast_server_adv_data[0]); + ret = bt_mgmt_adv_buffer_put(adv_buf, &adv_buf_cnt, adv_buf_vacant, + sizeof(unicast_server_adv_data), BT_DATA_SVC_DATA16, + unicast_server_adv_data); if (ret) { return ret; } if (IS_ENABLED(CONFIG_BT_CSIP_SET_MEMBER)) { - ret = adv_buf_put(adv_buf, adv_buf_vacant, &adv_buf_cnt, BT_DATA_CSIS_RSI, - ARRAY_SIZE(csip_rsi_adv_data), &csip_rsi_adv_data[0]); + ret = bt_mgmt_adv_buffer_put(adv_buf, + &adv_buf_cnt, adv_buf_vacant, + sizeof(csip_rsi_adv_data), BT_DATA_CSIS_RSI, + (void *)csip_rsi_adv_data); if (ret) { return ret; } } - ret = adv_buf_put(adv_buf, adv_buf_vacant, &adv_buf_cnt, BT_DATA_GAP_APPEARANCE, - ARRAY_SIZE(gap_appear_adv_data), &gap_appear_adv_data[0]); + sys_put_le16(CONFIG_BT_DEVICE_APPEARANCE, &gap_appear_adv_data[0]); + + ret = bt_mgmt_adv_buffer_put(adv_buf, + &adv_buf_cnt, adv_buf_vacant, + sizeof(gap_appear_adv_data), BT_DATA_GAP_APPEARANCE, + (void *)gap_appear_adv_data); if (ret) { return ret; } - ret = adv_buf_put(adv_buf, adv_buf_vacant, &adv_buf_cnt, BT_DATA_FLAGS, - ARRAY_SIZE(flags_adv_data), &flags_adv_data[0]); + flags_adv_data = BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR; + + ret = bt_mgmt_adv_buffer_put(adv_buf, &adv_buf_cnt, adv_buf_vacant, + sizeof(uint8_t), BT_DATA_FLAGS, (void *)&flags_adv_data); if (ret) { return ret; } - ret = adv_buf_put(adv_buf, adv_buf_vacant, &adv_buf_cnt, BT_DATA_SVC_DATA16, - ARRAY_SIZE(cap_adv_data), &cap_adv_data[0]); + ret = bt_mgmt_adv_buffer_put(adv_buf, &adv_buf_cnt, adv_buf_vacant, + ARRAY_SIZE(cap_adv_data), BT_DATA_SVC_DATA16, (void *)cap_adv_data); if (ret) { return ret; } diff --git a/applications/nrf5340_audio/unicast_server/main.c b/applications/nrf5340_audio/unicast_server/main.c index c85e30551bf5..6bbd73817e35 100644 --- a/applications/nrf5340_audio/unicast_server/main.c +++ b/applications/nrf5340_audio/unicast_server/main.c @@ -410,6 +410,17 @@ static int zbus_link_producers_observers(void) return 0; } +/* + * @brief The following configures the data for the extended advertising, as + * described in Volume 6, Part B, Section 2.3.1. + * + * @param ext_adv_buf Pointer to the bt_data used for extended advertising. + * @param ext_adv_buf_size Size of @p ext_adv_buf. + * @param ext_adv_count Pointer to the number of elements added to @p adv_buf. + * + * @return 0 for success, error otherwise. + */ + static int ext_adv_populate(struct bt_data *ext_adv_buf, size_t ext_adv_buf_size, size_t *ext_adv_count) { @@ -419,7 +430,6 @@ static int ext_adv_populate(struct bt_data *ext_adv_buf, size_t ext_adv_buf_size NET_BUF_SIMPLE_DEFINE_STATIC(uuid_buf, CONFIG_EXT_ADV_UUID_BUF_MAX); ext_adv_buf[ext_adv_buf_cnt].type = BT_DATA_UUID16_SOME; - ext_adv_buf[ext_adv_buf_cnt].data_len = 0; ext_adv_buf[ext_adv_buf_cnt].data = uuid_buf.data; ext_adv_buf_cnt++;