From c40e77e502d4d1daedd648cdf8d0d21c7acc15e2 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Mon, 19 May 2025 23:36:37 +0200 Subject: [PATCH 1/2] Bluetooth: Host: Add advertising state to bt_le_ext_adv_info The bt_le_ext_adv_info struct has been extended to also contain the advertising and periodic advertising states. Additionally, the function verifies the input to avoid NULL pointer access, and the addr field is more properly documented. Signed-off-by: Emil Gydesen --- include/zephyr/bluetooth/bluetooth.h | 42 ++++++++++++++++++++++++++-- subsys/bluetooth/host/adv.c | 35 +++++++++++++++++++++++ subsys/bluetooth/host/shell/bt.c | 6 +++- 3 files changed, 80 insertions(+), 3 deletions(-) diff --git a/include/zephyr/bluetooth/bluetooth.h b/include/zephyr/bluetooth/bluetooth.h index c68327647599..c9c7f8e13bf6 100644 --- a/include/zephyr/bluetooth/bluetooth.h +++ b/include/zephyr/bluetooth/bluetooth.h @@ -1714,6 +1714,31 @@ int bt_le_ext_adv_delete(struct bt_le_ext_adv *adv); */ uint8_t bt_le_ext_adv_get_index(struct bt_le_ext_adv *adv); +enum bt_le_ext_adv_state { + /** No state */ + BT_LE_EXT_ADV_STATE_NONE, + + /** The advertising set has been created but not started */ + BT_LE_EXT_ADV_STATE_CREATED, + + /** The advertising set is started */ + BT_LE_EXT_ADV_STATE_STARTED, + + /** Ther advertising set is temporarily paused */ + BT_LE_EXT_ADV_STATE_PAUSED, +}; + +enum bt_le_per_adv_state { + /** No state */ + BT_LE_PER_ADV_STATE_NONE, + + /** The advertising set has been configured for periodic advertising */ + BT_LE_PER_ADV_STATE_CONFIGURED, + + /** Periodic advertising is started */ + BT_LE_PER_ADV_STATE_STARTED, +}; + /** @brief Advertising set info structure. */ struct bt_le_ext_adv_info { /** Local identity handle. */ @@ -1722,8 +1747,19 @@ struct bt_le_ext_adv_info { /** Currently selected Transmit Power (dBM). */ int8_t tx_power; - /** Current local advertising address used. */ + /** + * @brief Current local advertising address used. + * + * If @ref bt_le_ext_adv_info.ext_adv_state is not BT_LE_EXT_ADV_STATE_STARTED the value + * of this address may change when bt_le_ext_adv_start() is called. + */ const bt_addr_le_t *addr; + + /** Extended advertising state */ + enum bt_le_ext_adv_state ext_adv_state; + + /** Periodic advertising state */ + enum bt_le_per_adv_state per_adv_state; }; /** @@ -1732,7 +1768,9 @@ struct bt_le_ext_adv_info { * @param adv Advertising set object * @param info Advertising set info object * - * @return Zero on success or (negative) error code on failure. + * @retval 0 Success + * @retval -EINVAL @p adv or @p info is NULL + * @retval -ENXIO @p adv is not a created advertising set */ int bt_le_ext_adv_get_info(const struct bt_le_ext_adv *adv, struct bt_le_ext_adv_info *info); diff --git a/subsys/bluetooth/host/adv.c b/subsys/bluetooth/host/adv.c index 0694c2ce54b3..7fdc3ec1a58e 100644 --- a/subsys/bluetooth/host/adv.c +++ b/subsys/bluetooth/host/adv.c @@ -1592,10 +1592,45 @@ void bt_le_adv_resume(void) int bt_le_ext_adv_get_info(const struct bt_le_ext_adv *adv, struct bt_le_ext_adv_info *info) { + if (adv == NULL) { + LOG_DBG("adv is NULL"); + return -EINVAL; + } + + if (info == NULL) { + LOG_DBG("info is NULL"); + return -EINVAL; + } + + if (!atomic_test_bit(adv->flags, BT_ADV_CREATED)) { + LOG_DBG("Advertising set %p is not created", adv); + return -ENXIO; + } + + (void)memset(info, 0, sizeof(*info)); + info->id = adv->id; info->tx_power = adv->tx_power; info->addr = &adv->random_addr; + if (atomic_test_bit(adv->flags, BT_ADV_ENABLED)) { + info->ext_adv_state = BT_LE_EXT_ADV_STATE_STARTED; + } else if (atomic_test_bit(adv->flags, BT_ADV_PAUSED)) { + info->ext_adv_state = BT_LE_EXT_ADV_STATE_PAUSED; + } else { + info->ext_adv_state = BT_LE_EXT_ADV_STATE_CREATED; + } + + if (IS_ENABLED(CONFIG_BT_PER_ADV)) { + if (atomic_test_bit(adv->flags, BT_PER_ADV_PARAMS_SET)) { + info->per_adv_state = BT_LE_PER_ADV_STATE_CONFIGURED; + } else if (atomic_test_bit(adv->flags, BT_PER_ADV_ENABLED)) { + info->per_adv_state = BT_LE_PER_ADV_STATE_STARTED; + } else { + info->per_adv_state = BT_LE_PER_ADV_STATE_NONE; + } + } + return 0; } diff --git a/subsys/bluetooth/host/shell/bt.c b/subsys/bluetooth/host/shell/bt.c index a2ee453b2ea7..3d49d60bf398 100644 --- a/subsys/bluetooth/host/shell/bt.c +++ b/subsys/bluetooth/host/shell/bt.c @@ -2566,7 +2566,11 @@ static int cmd_adv_info(const struct shell *sh, size_t argc, char *argv[]) shell_print(sh, "Advertiser[%d] %p", selected_adv, adv); shell_print(sh, "Id: %d, TX power: %d dBm", info.id, info.tx_power); - print_le_addr("Address", info.addr); + shell_print(sh, "Adv state: %d", info.ext_adv_state); + if (info.ext_adv_state == BT_LE_EXT_ADV_STATE_STARTED) { + print_le_addr("Address", info.addr); + } + shell_print(sh, "Per Adv state: %d", info.per_adv_state); return 0; } From 79a334bdf2d1f119d392dfd05a903d155a560235 Mon Sep 17 00:00:00 2001 From: Emil Gydesen Date: Sat, 24 May 2025 16:19:54 +0200 Subject: [PATCH 2/2] tests: Bluetooth: Audio: Add common start_broadcast_adv Add a common function, start_broadcast_adv, to start broadcast advertisement in the LE Audio BSIM tests. Signed-off-by: Emil Gydesen --- .../audio/src/cap_initiator_broadcast_test.c | 27 ++----------- tests/bsim/bluetooth/audio/src/common.c | 39 +++++++++++++++++++ tests/bsim/bluetooth/audio/src/common.h | 1 + .../bsim/bluetooth/audio/src/gmap_ugg_test.c | 21 +--------- .../src/pbp_public_broadcast_source_test.c | 29 +------------- 5 files changed, 46 insertions(+), 71 deletions(-) diff --git a/tests/bsim/bluetooth/audio/src/cap_initiator_broadcast_test.c b/tests/bsim/bluetooth/audio/src/cap_initiator_broadcast_test.c index 7b149f9dae50..ef7663f7fbd7 100644 --- a/tests/bsim/bluetooth/audio/src/cap_initiator_broadcast_test.c +++ b/tests/bsim/bluetooth/audio/src/cap_initiator_broadcast_test.c @@ -248,25 +248,6 @@ static void setup_extended_adv_data(struct bt_cap_broadcast_source *source, } } -static void start_extended_adv(struct bt_le_ext_adv *adv) -{ - int err; - - /* Start extended advertising */ - err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT); - if (err) { - FAIL("Failed to start extended advertising: %d\n", err); - return; - } - - /* Enable Periodic Advertising */ - err = bt_le_per_adv_start(adv); - if (err) { - FAIL("Failed to enable periodic advertising: %d\n", err); - return; - } -} - static void stop_and_delete_extended_adv(struct bt_le_ext_adv *adv) { int err; @@ -662,7 +643,7 @@ static void test_main_cap_initiator_broadcast(void) setup_extended_adv_data(broadcast_source, adv); - start_extended_adv(adv); + start_broadcast_adv(adv); /* Wait for all to be started */ printk("Waiting for broadcast_streams to be started\n"); @@ -708,7 +689,7 @@ static void test_main_cap_initiator_broadcast_inval(void) setup_extended_adv_data(broadcast_source, adv); - start_extended_adv(adv); + start_broadcast_adv(adv); /* Wait for all to be started */ printk("Waiting for broadcast_streams to be started\n"); @@ -754,7 +735,7 @@ static void test_main_cap_initiator_broadcast_update(void) setup_extended_adv_data(broadcast_source, adv); - start_extended_adv(adv); + start_broadcast_adv(adv); /* Wait for all to be started */ printk("Waiting for broadcast_streams to be started\n"); @@ -848,7 +829,7 @@ static int test_cap_initiator_ac(const struct cap_initiator_ac_param *param) test_broadcast_audio_start(broadcast_source, adv); setup_extended_adv_data(broadcast_source, adv); - start_extended_adv(adv); + start_broadcast_adv(adv); /* Wait for all to be started */ printk("Waiting for broadcast_streams to be started\n"); diff --git a/tests/bsim/bluetooth/audio/src/common.c b/tests/bsim/bluetooth/audio/src/common.c index 2c23a0836241..6896d879b866 100644 --- a/tests/bsim/bluetooth/audio/src/common.c +++ b/tests/bsim/bluetooth/audio/src/common.c @@ -247,6 +247,45 @@ void setup_broadcast_adv(struct bt_le_ext_adv **adv) } } +void start_broadcast_adv(struct bt_le_ext_adv *adv) +{ + char addr_str[BT_ADDR_LE_STR_LEN]; + struct bt_le_ext_adv_info info; + int err; + + err = bt_le_ext_adv_get_info(adv, &info); + if (err != 0) { + FAIL("Failed to get adv info: %d\n", err); + return; + } + + if (info.per_adv_state == BT_LE_PER_ADV_STATE_NONE) { + FAIL("Cannot start periodic advertising for non-periodic advertising set"); + return; + } + + if (info.ext_adv_state == BT_LE_EXT_ADV_STATE_CREATED) { + /* Start extended advertising */ + err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT); + if (err != 0) { + FAIL("Failed to start extended advertising: %d\n", err); + return; + } + } + + if (info.per_adv_state == BT_LE_PER_ADV_STATE_CONFIGURED) { + /* Enable Periodic Advertising */ + err = bt_le_per_adv_start(adv); + if (err != 0) { + FAIL("Failed to enable periodic advertising: %d\n", err); + return; + } + } + + bt_addr_le_to_str(info.addr, addr_str, sizeof(addr_str)); + printk("Started advertising with addr %s\n", addr_str); +} + void test_tick(bs_time_t HW_device_time) { if (bst_result != Passed) { diff --git a/tests/bsim/bluetooth/audio/src/common.h b/tests/bsim/bluetooth/audio/src/common.h index 6ba2106a6c9a..accf7a4ef8fe 100644 --- a/tests/bsim/bluetooth/audio/src/common.h +++ b/tests/bsim/bluetooth/audio/src/common.h @@ -140,6 +140,7 @@ extern uint8_t csip_rsi[BT_CSIP_RSI_SIZE]; void disconnected(struct bt_conn *conn, uint8_t reason); void setup_connectable_adv(struct bt_le_ext_adv **ext_adv); void setup_broadcast_adv(struct bt_le_ext_adv **adv); +void start_broadcast_adv(struct bt_le_ext_adv *adv); void test_tick(bs_time_t HW_device_time); void test_init(void); uint16_t get_dev_cnt(void); diff --git a/tests/bsim/bluetooth/audio/src/gmap_ugg_test.c b/tests/bsim/bluetooth/audio/src/gmap_ugg_test.c index c1d608058712..b5e6f04d3d5d 100644 --- a/tests/bsim/bluetooth/audio/src/gmap_ugg_test.c +++ b/tests/bsim/bluetooth/audio/src/gmap_ugg_test.c @@ -1066,25 +1066,6 @@ static void setup_extended_adv_data(struct bt_cap_broadcast_source *source, } } -static void start_extended_adv(struct bt_le_ext_adv *adv) -{ - int err; - - /* Start extended advertising */ - err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT); - if (err) { - FAIL("Failed to start extended advertising: %d\n", err); - return; - } - - /* Enable Periodic Advertising */ - err = bt_le_per_adv_start(adv); - if (err) { - FAIL("Failed to enable periodic advertising: %d\n", err); - return; - } -} - static void stop_and_delete_extended_adv(struct bt_le_ext_adv *adv) { int err; @@ -1222,7 +1203,7 @@ static int test_gmap_ugg_broadcast_ac(const struct gmap_broadcast_ac_param *para broadcast_audio_start(broadcast_source, adv); setup_extended_adv_data(broadcast_source, adv); - start_extended_adv(adv); + start_broadcast_adv(adv); /* Wait for all to be started */ printk("Waiting for broadcast_streams to be started\n"); diff --git a/tests/bsim/bluetooth/audio/src/pbp_public_broadcast_source_test.c b/tests/bsim/bluetooth/audio/src/pbp_public_broadcast_source_test.c index eb2e789f24a3..2a2221855ba2 100644 --- a/tests/bsim/bluetooth/audio/src/pbp_public_broadcast_source_test.c +++ b/tests/bsim/bluetooth/audio/src/pbp_public_broadcast_source_test.c @@ -175,29 +175,6 @@ static int setup_extended_adv_data(struct bt_cap_broadcast_source *source, return 0; } -static int start_extended_adv(struct bt_le_ext_adv *adv) -{ - int err; - - /* Start extended advertising */ - err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT); - if (err) { - printk("Failed to start extended advertising: %d\n", err); - - return err; - } - - /* Enable Periodic Advertising */ - err = bt_le_per_adv_start(adv); - if (err) { - printk("Failed to enable periodic advertising: %d\n", err); - - return err; - } - - return 0; -} - static int stop_extended_adv(struct bt_le_ext_adv *adv) { int err; @@ -289,11 +266,7 @@ static void test_main(void) FAIL("Public Broadcast source failed\n"); } - err = start_extended_adv(adv); - if (err != 0) { - printk("Unable to start extended advertiser: %d\n", err); - FAIL("Public Broadcast source failed\n"); - } + start_broadcast_adv(adv); k_sem_take(&sem_started, SEM_TIMEOUT);