Skip to content

samples: Bluetooth: Broadcast multiple legacy and extended advertising #94304

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions samples/bluetooth/broadcaster_multiple/prj.conf
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
CONFIG_BT=y
CONFIG_BT_BROADCASTER=y
CONFIG_BT_DEVICE_NAME="Broadcaster Multiple"
CONFIG_LOG=y

# Require Bluetooth Advertising Extensions Feature
CONFIG_BT_EXT_ADV=y

# Increase to 4 gives one each of legacy, 2M, 1M and Coded PHY advertising sets
CONFIG_BT_EXT_ADV_MAX_ADV_SET=2
CONFIG_BT_DEVICE_NAME="Broadcaster Multiple"

CONFIG_LOG=y
# Enable Coded PHY support in Zephyr Controller, if testing 4 advertising sets
# CONFIG_BT_CTLR_PHY_CODED=y
Comment on lines +12 to +13
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jhedberg Currently, the Controller specific is commented for this sample, do you agree that this be moved to a overlay and sample document/readme updated according to indicate the same, right?


# Zephyr Bluetooth LE Controller will need to use chain PDUs when AD data
# length > 191 bytes
Expand All @@ -20,4 +26,6 @@ CONFIG_LOG=y
# number of chain PDUs per advertising set when using Zephyr Bluetooth LE
# Controller
# CONFIG_BT_CTLR_ADVANCED_FEATURES=y
# CONFIG_BT_CTLR_ADV_DATA_BUF_MAX=2
# CONFIG_BT_CTLR_ADV_RESERVE_MAX=n
# CONFIG_BT_CTLR_ADV_DATA_BUF_MAX=6
# CONFIG_BT_CTLR_ADV_DATA_CHAIN=y
50 changes: 45 additions & 5 deletions samples/bluetooth/broadcaster_multiple/src/broadcaster_multiple.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,18 @@
*/
static uint8_t mfg_data[BT_MFG_DATA_LEN] = { 0xFF, 0xFF, };

static const struct bt_data ad[] = {
static const struct bt_data ad_long[] = {
BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, sizeof(mfg_data)),
#if CONFIG_BT_CTLR_ADV_DATA_LEN_MAX > 255
BT_DATA(BT_DATA_MANUFACTURER_DATA, mfg_data, sizeof(mfg_data)),
#endif
BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1),
};

static const struct bt_data ad_short[] = {
BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1),
};

static struct bt_le_ext_adv *adv[CONFIG_BT_EXT_ADV_MAX_ADV_SET];

int broadcaster_multiple(void)
Expand All @@ -78,20 +82,56 @@ int broadcaster_multiple(void)
int err;

for (int index = 0; index < CONFIG_BT_EXT_ADV_MAX_ADV_SET; index++) {
const struct bt_data *ad;
size_t ad_size;

/* Use advertising set instance index as SID */
adv_param.sid = index;

/* Use Coded PHY */
if ((index % 4) == 3) {
adv_param.options = BT_LE_ADV_OPT_EXT_ADV;
adv_param.options |= BT_LE_ADV_OPT_CODED;
ad = ad_long;
ad_size = ARRAY_SIZE(ad_long);
/* Use 1M auxiliary PDU */
} else if ((index % 4) == 2) {
adv_param.options = BT_LE_ADV_OPT_EXT_ADV;
adv_param.options |= BT_LE_ADV_OPT_NO_2M;
ad = ad_long;
ad_size = ARRAY_SIZE(ad_long);
/* Use 2M auxiliary PDU */
} else if ((index % 4) == 1) {
adv_param.options = BT_LE_ADV_OPT_EXT_ADV;
ad = ad_long;
ad_size = ARRAY_SIZE(ad_long);
/* Use 1M legacy PDU */
} else {
adv_param.options = BT_LE_ADV_OPT_NONE;
ad = ad_short;
ad_size = ARRAY_SIZE(ad_short);
}
Comment on lines +91 to +113
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider moving this into a select function to simplify the loop.

Also consider storing this in an array like

struct {
    uint32_t options;
    const struct bt_data *ad;
    size_t ad_size
} adv_params[4];

So you can do things like (index % sizeof(adv_params) == 2U). Alternatively you can also make it a circular linked list and just get the next entry for each iteration.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using an array is a better implementation, will update the PR.


ext_adv_create_retry:
/* Create a non-connectable advertising set */
err = bt_le_ext_adv_create(&adv_param, NULL, &adv[index]);
if (err) {
printk("Failed to create advertising set %d (err %d)\n",
index, err);
/* Failed creating Coded PHY advertising set? */
if (adv_param.options & BT_LE_ADV_OPT_CODED) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (adv_param.options & BT_LE_ADV_OPT_CODED) {
if ((adv_param.options & BT_LE_ADV_OPT_CODED) != 0) {

printk("Failed to create advertising set %d with Coded PHY "
"(err %d), retry without...\n", index, err);
/* Retry with non-Coded PHY advertising set */
adv_param.options &= ~BT_LE_ADV_OPT_CODED;

goto ext_adv_create_retry;
}

printk("Failed to create advertising set %d (err %d)\n", index, err);
return err;
}

/* Set extended advertising data */
err = bt_le_ext_adv_set_data(adv[index], ad, ARRAY_SIZE(ad),
NULL, 0);
err = bt_le_ext_adv_set_data(adv[index], ad, ad_size, NULL, 0);
if (err) {
printk("Failed to set advertising data for set %d "
"(err %d)\n", index, err);
Expand Down
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the changes to this file also be applied to the other bt_ll_sw_split files in hci_ipc?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two added where the Kconfig defaults already... but made sense to have it here to be similar to one used for hci_uart, the overlay-all-bt_ll_sw_split.conf or the one used in audio bsim tests. Will review other files and make similar changes as required.

Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ CONFIG_BT_CTLR_LOW_LAT_ULL=y

CONFIG_BT_CTLR_ADV_RESERVE_MAX=n
CONFIG_BT_CTLR_ADV_ISO_RESERVE_MAX=y
CONFIG_BT_CTLR_SCAN_AUX_SYNC_RESERVE_MIN=y
CONFIG_BT_CTLR_SYNC_PERIODIC_SKIP_ON_SCAN_AUX=n
CONFIG_BT_CTLR_SYNC_ISO_RESERVE_MAX=n
CONFIG_BT_CTLR_CENTRAL_RESERVE_MAX=n
CONFIG_BT_CTLR_PERIPHERAL_RESERVE_MAX=n
Expand Down Expand Up @@ -155,7 +157,3 @@ CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL=y
CONFIG_MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG=y
CONFIG_MBEDTLS_AES_ROM_TABLES=y
CONFIG_MBEDTLS_PSA_KEY_SLOT_COUNT=3

# Reduce RAM footprint further otherwise the image won't fit in cpu_net.
CONFIG_BT_CTLR_ADV_ISO_SET=1
CONFIG_BT_CTLR_ADV_ISO_STREAM_COUNT=2
14 changes: 14 additions & 0 deletions samples/bluetooth/observer/src/observer.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,13 +99,27 @@ int observer_start(void)
#if defined(CONFIG_BT_EXT_ADV)
bt_le_scan_cb_register(&scan_callbacks);
printk("Registered scan callbacks\n");

scan_param.options |= BT_LE_SCAN_OPT_CODED;
#endif /* CONFIG_BT_EXT_ADV */

scan_start_retry:
err = bt_le_scan_start(&scan_param, device_found);
if (err) {
if (scan_param.options & BT_LE_SCAN_OPT_CODED) {
printk("Failed to start scanning with Coded PHY (err %d), retrying "
"without...\n", err);

scan_param.options &= ~BT_LE_SCAN_OPT_CODED;

goto scan_start_retry;
}

printk("Start scanning failed (err %d)\n", err);

return err;
}

printk("Started scanning...\n");

return 0;
Expand Down
14 changes: 7 additions & 7 deletions subsys/bluetooth/controller/ll_sw/nordic/lll/lll_vendor.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,20 @@
#if defined(CONFIG_BT_CTLR_ADV_EXT)
#if defined(CONFIG_BT_OBSERVER)
#if defined(CONFIG_BT_CTLR_PHY_CODED)
/* Active connection in peripheral role with extended scanning on 1M and Coded
* PHY, scheduling and receiving auxiliary PDUs.
/* Simultaneous 3 extended advertising sets with extended scanning on 1M and Coded PHY, scheduling
* and receiving auxiliary PDUs.
*/
#define EVENT_OVERHEAD_START_US 733 /* 24 RTC ticks */
#define EVENT_OVERHEAD_START_US 580 /* 19 RTC ticks */
#else /* !CONFIG_BT_CTLR_PHY_CODED */
/* Active connection in peripheral role with extended scanning on 1M only,
* scheduling and receiving auxiliary PDUs.
/* Active connection in peripheral role with extended scanning on 1M only, scheduling and receiving
* auxiliary PDUs.
*/
#define EVENT_OVERHEAD_START_US 428 /* 14 RTC ticks */
#endif /* !CONFIG_BT_CTLR_PHY_CODED */
#else /* !CONFIG_BT_OBSERVER */
/* Active connection in peripheral role with legacy scanning on 1M.
/* Simultaneous 3 extended advertising sets calculating aux offsets.
*/
#define EVENT_OVERHEAD_START_US 275 /* 9 RTC ticks */
#define EVENT_OVERHEAD_START_US 367 /* 12 RTC ticks */
#endif /* !CONFIG_BT_OBSERVER */
#else /* !CONFIG_BT_CTLR_ADV_EXT */
/* Active connection in peripheral role with additional advertising state.
Expand Down
7 changes: 4 additions & 3 deletions subsys/bluetooth/controller/ll_sw/ull_adv_aux.c
Original file line number Diff line number Diff line change
Expand Up @@ -3324,9 +3324,10 @@ static void mfy_aux_offset_get(void *param)
/* Assertion check for delayed aux_offset calculations */
ticks_now = ticker_ticks_now_get();
ticks_elapsed = ticker_ticks_diff_get(ticks_now, ticks_current);
ticks_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_XTAL_US) -
HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_PREEMPT_MIN_US);
LL_ASSERT(ticks_elapsed < ticks_to_start);
ticks_to_start = HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US);
LL_ASSERT_MSG((ticks_elapsed < ticks_to_start), "%s overhead = %u (%u) us.",
__func__, HAL_TICKER_TICKS_TO_US(ticks_elapsed),
HAL_TICKER_TICKS_TO_US(ticks_to_start));
}

static void ticker_op_cb(uint32_t status, void *param)
Expand Down
5 changes: 5 additions & 0 deletions tests/bsim/bluetooth/audio/overlay-bt_ll_sw_split.conf
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ CONFIG_BT_CTLR_ADV_DATA_BUF_MAX=6

# Increase the below to receive interleaved advertising chains
CONFIG_BT_CTLR_SCAN_AUX_SET=3
CONFIG_BT_CTLR_LOW_LAT_ULL=y
# CONFIG_BT_CTLR_SCAN_AUX_USE_CHAINS=y
# CONFIG_BT_CTLR_SCAN_AUX_CHAIN_COUNT=1

Expand All @@ -50,6 +51,8 @@ CONFIG_BT_CTLR_ADV_EXT=y
CONFIG_BT_CTLR_ADV_PERIODIC=y
CONFIG_BT_CTLR_SYNC_TRANSFER_SENDER=y
CONFIG_BT_CTLR_ADV_ISO=y
CONFIG_BT_CTLR_ADV_ISO_SEQUENTIAL=y
CONFIG_BT_CTLR_ADV_ISO_INTERLEAVED=y
CONFIG_BT_CTLR_ADV_ISO_SET=1
CONFIG_BT_CTLR_ADV_ISO_STREAM_COUNT=4
CONFIG_BT_CTLR_ADV_ISO_STREAM_MAX=4
Expand All @@ -60,6 +63,8 @@ CONFIG_BT_CTLR_ADV_EXT=y
CONFIG_BT_CTLR_SYNC_PERIODIC=y
CONFIG_BT_CTLR_SYNC_TRANSFER_RECEIVER=y
CONFIG_BT_CTLR_SYNC_ISO=y
CONFIG_BT_CTLR_SYNC_ISO_SEQUENTIAL=y
CONFIG_BT_CTLR_SYNC_ISO_INTERLEAVED=y
CONFIG_BT_CTLR_SCAN_SYNC_ISO_SET=1
CONFIG_BT_CTLR_SYNC_ISO_STREAM_COUNT=4
CONFIG_BT_CTLR_SYNC_ISO_STREAM_MAX=4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_audio_prj_conf \
-v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=1 \
-testid=bap_broadcast_assistant_client_sync -RealEncryption=1 -rs=46 -D=3

Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_audio_prj_conf \
Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_audio_prj_conf \
-v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -d=2 -testid=bass_broadcaster \
-RealEncryption=1 -rs=69 -D=3
-RealEncryption=1 -rs=69 -D=3 -start_offset=2e3

# Simulation time should be larger than the WAIT_TIME in common.h
Execute ./bs_2G4_phy_v1 -v=${VERBOSITY_LEVEL} -s=${SIMULATION_ID} -D=3 \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,6 @@ Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_audio_samples_bap_unicast_client_p
-testid=unicast_client

Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \
-D=2 -sim_length=20e6 $@ -argschannel -at=40
-D=2 -sim_length=21e6 $@ -argschannel -at=40

wait_for_background_jobs #Wait for all programs in background and return != 0 if any fails
29 changes: 24 additions & 5 deletions tests/bsim/bluetooth/host/adv/chain/prj.conf
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
CONFIG_BT=y

# Broadcaster
CONFIG_BT_BROADCASTER=y
CONFIG_BT_OBSERVER=y
CONFIG_BT_EXT_ADV=y
CONFIG_BT_EXT_ADV_MAX_ADV_SET=2
CONFIG_BT_EXT_ADV_MAX_ADV_SET=4
CONFIG_BT_DEVICE_NAME="Broadcaster Multiple"

# Enable Advertising Data chaining in Zephyr Bluetooth LE Controller
CONFIG_BT_CTLR_ADVANCED_FEATURES=y
CONFIG_BT_CTLR_ADV_RESERVE_MAX=n
CONFIG_BT_CTLR_ADV_DATA_CHAIN=y

# Zephyr Bluetooth LE Controller will need to use chain PDUs when AD data
Expand All @@ -24,17 +26,34 @@ CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=1650
# Controller
CONFIG_BT_CTLR_ADV_DATA_BUF_MAX=2

# Enable Coded PHY
CONFIG_BT_CTLR_PHY_CODED=y

# Observer
CONFIG_BT_OBSERVER=y
CONFIG_BT_EXT_ADV=y

# Maximum Extended Scanning buffer size
CONFIG_BT_EXT_SCAN_BUF_SIZE=1650

# Set maximum scan data length for Extended Scanning in Bluetooth LE Controller
CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX=1650

# The Zephyr Controller does not combine all the 1650 bytes before
# fragmenting into 8 HCI reports, if a PDU has 255 bytes,
# it will generate 2 HCI reports and so we need to reserve 16 buffers
CONFIG_BT_BUF_EVT_RX_COUNT=16

# Set maximum scan data length for Extended Scanning in Bluetooth LE Controller
CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX=1650

# Increase Zephyr Bluetooth LE Controller Rx buffer to receive complete chain
# of PDUs
CONFIG_BT_CTLR_RX_BUFFERS=9

# Enable scanning interleaved extended advertising in Zephyr Bluetooth LE
# Controller
CONFIG_BT_CTLR_ADVANCED_FEATURES=y
CONFIG_BT_CTLR_SCAN_AUX_SET=9
CONFIG_BT_CTLR_LOW_LAT_ULL=y
# CONFIG_BT_CTLR_SCAN_AUX_USE_CHAINS=y
# CONFIG_BT_CTLR_SCAN_AUX_CHAIN_COUNT=9
CONFIG_BT_CTLR_SCAN_UNRESERVED=y
# CONFIG_BT_TICKER_EXT_EXPIRE_INFO=y
9 changes: 7 additions & 2 deletions tests/bsim/bluetooth/host/adv/chain/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,11 @@
BT_AD_DATA_MFG_DATA_SIZE + BT_AD_DATA_MFG_DATA_SIZE), \
CONFIG_BT_CTLR_ADV_DATA_LEN_MAX)

/* One less extended advertising set as first one is legacy advertising in the broadcaster_multiple
* sample.
*/
#define BT_EXT_ADV_MAX_ADV_SET (CONFIG_BT_EXT_ADV_MAX_ADV_SET - 1)

static K_SEM_DEFINE(sem_recv, 0, 1);

static void test_adv_main(void)
Expand Down Expand Up @@ -76,7 +81,7 @@ static bool data_cb(struct bt_data *data, void *user_data)
static void scan_recv(const struct bt_le_scan_recv_info *info,
struct net_buf_simple *buf)
{
static uint8_t sid[CONFIG_BT_EXT_ADV_MAX_ADV_SET];
static uint8_t sid[BT_EXT_ADV_MAX_ADV_SET];
static uint8_t sid_count;
char name[NAME_LEN];
uint8_t data_status;
Expand Down Expand Up @@ -110,7 +115,7 @@ static void scan_recv(const struct bt_le_scan_recv_info *info,

sid[sid_count++] = info->sid;

if (sid_count < CONFIG_BT_EXT_ADV_MAX_ADV_SET) {
if (sid_count < BT_EXT_ADV_MAX_ADV_SET) {
printk("Received advertising sets: %d\n", sid_count);
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@ Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_host_adv_chain_prj_conf\
-v=${verbosity_level} -s=${simulation_id} -d=1 -testid=scan

Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \
-D=2 -sim_length=10e6 $@
-D=2 -sim_length=11e6 $@

wait_for_background_jobs