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