Skip to content

Commit

Permalink
Bluetooth: BAP: Add a set of suggested intervals to use with BAP
Browse files Browse the repository at this point in the history
Add a selection of interval values that are suitable for BAP,
which will allow better coexistence between ISO and ACL,
for both broadcast and unicast.

Samples and tests have been updated to use these new values.

The shell has also been updated to use the LE Audio (BAP) values
if audio is enabled, and the audio.conf file has disabled automatic
updating of the connection parameters as the peripheral, as we rarely
(if ever) want to do that.

Due to the connection interval change, CI hit an issue
with test_bass_broadcast_code in test_main_client_sync, where
the reading of the long receive state did not finish before we
attempted to do another procedure, so the function was updated to have
a retry.

Signed-off-by: Emil Gydesen <[email protected]>
  • Loading branch information
Thalley committed Nov 9, 2024
1 parent 07a1d18 commit f4f3960
Show file tree
Hide file tree
Showing 25 changed files with 305 additions and 173 deletions.
57 changes: 57 additions & 0 deletions include/zephyr/bluetooth/audio/bap.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,63 @@ extern "C" {
/** An invalid Broadcast ID */
#define BT_BAP_INVALID_BROADCAST_ID 0xFFFFFFFFU

/**
* @name Suggested connection and advertising intervals suited for coexistence with audio
*
* Suggest use is to use this as both the minimum and maximum interval for best results.
* The intervals are suited for both unicast and broadcast.
* @{
*/
/**
* @brief Fast interval suited for coexistence with 10ms SDU intervals
*
* This works well with ISO intervals of 10, 20 and 30 milliseconds for broadcast and unicast
*/
#define BT_BAP_COEX_INT_MS_10_FAST_1 60U
/**
* @brief Fast interval suited for coexistence with 10ms SDU intervals
*
* This works well with ISO intervals of 10, 20, 30 and 40 milliseconds.
*/
#define BT_BAP_COEX_INT_MS_10_FAST_2 120U
/**
* @brief Slow interval suited for coexistence with 10ms SDU intervals
*
* This works well with ISO intervals of 10, 20, 30, 40, 50 and 60 milliseconds
*/
#define BT_BAP_COEX_INT_MS_10_SLOW 600U
/**
* @brief Fast interval suited for coexistence with 7.5ms SDU intervals
*
* This works well with ISO intervals of 7.5, 15 and 22.5 milliseconds
*/
#define BT_BAP_COEX_INT_MS_7_5_FAST_1 45U
/**
* @brief Fast interval suited for coexistence with 7.5ms SDU intervals
*
* This works well with ISO intervals of 7.5, 15, 22.5, 30 and 45 milliseconds
*/
#define BT_BAP_COEX_INT_MS_7_5_FAST_2 90U
/**
* @brief Slow interval suited for coexistence with 7.5ms SDU intervals
*
* This works well with ISO intervals of 7.5, 15, 22.5, 30, 37.5 and 45 milliseconds
*/
#define BT_BAP_COEX_INT_MS_7_5_SLOW 600U
/**
* @brief Fast interval suited for coexistence with 7.5ms and 10ms SDU intervals
*
* This works well with ISO intervals of 7.5, 10, 15, 20 and 30 milliseconds
*/
#define BT_BAP_COEX_INT_MS_7_5_10_FAST 60U
/**
* @brief Slow interval suited for coexistence with 7.5ms and 10ms SDU intervals
*
* This works well with ISO intervals of 7.5, 10, 15, 20, 22.5 and 30 milliseconds.
*/
#define BT_BAP_COEX_INT_MS_7_5_10_SLOW 180U
/** @} */

/**
* @brief Check if a BAP BASS BIS_Sync bitfield is valid
*
Expand Down
11 changes: 9 additions & 2 deletions samples/bluetooth/bap_broadcast_assistant/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -360,6 +360,14 @@ static void scan_recv_cb(const struct bt_le_scan_recv_info *info,
bt_data_parse(ad, device_found, (void *)&sr_info);

if (sr_info.has_bass && sr_info.has_pacs) {
/* We use BT_BAP_COEX_INT_MS_7_5_10_FAST to best support Scan Delegators
* that support both 7.5 and 10ms SDU interval
*/
const struct bt_le_conn_param *conn_param = BT_LE_CONN_PARAM(
BT_GAP_MS_TO_CONN_INT(BT_BAP_COEX_INT_MS_7_5_10_FAST),
BT_GAP_MS_TO_CONN_INT(BT_BAP_COEX_INT_MS_7_5_10_FAST), 0,
BT_GAP_MS_TO_CONN_TIMEOUT(4000));

printk("Broadcast Sink Found:\n");
printk(" BT Name: %s\n", sr_info.bt_name);

Expand All @@ -381,8 +389,7 @@ static void scan_recv_cb(const struct bt_le_scan_recv_info *info,

printk("Connecting to Broadcast Sink: %s\n", sr_info.bt_name);

err = bt_conn_le_create(info->addr, BT_CONN_LE_CREATE_CONN,
BT_LE_CONN_PARAM_DEFAULT,
err = bt_conn_le_create(info->addr, BT_CONN_LE_CREATE_CONN, conn_param,
&broadcast_sink_conn);
if (err != 0) {
printk("Failed creating connection (err=%u)\n", err);
Expand Down
21 changes: 13 additions & 8 deletions samples/bluetooth/bap_broadcast_source/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,11 @@ BUILD_ASSERT(strlen(CONFIG_BROADCAST_CODE) <= BT_ISO_BROADCAST_CODE_SIZE, "Inval
* of the ISO Interval minus 10 ms (max. advertising random delay). This is
* required to place the AUX_ADV_IND PDUs in a non-overlapping interval with the
* Broadcast ISO radio events.
*
* I.e. for a 7.5 ms ISO interval use 90 ms minus 10 ms ==> 80 ms advertising
* interval.
* And, for 10 ms ISO interval, can use 90 ms minus 10 ms ==> 80 ms advertising
* interval.
*/
#define BT_LE_EXT_ADV_CUSTOM \
BT_LE_ADV_PARAM(BT_LE_ADV_OPT_EXT_ADV, BT_GAP_MS_TO_ADV_INT(80), BT_GAP_MS_TO_ADV_INT(80), \
NULL)
BT_LE_ADV_PARAM(BT_LE_ADV_OPT_EXT_ADV, \
BT_GAP_MS_TO_ADV_INT(BT_BAP_COEX_INT_MS_10_FAST_2 - 10), \
BT_GAP_MS_TO_ADV_INT(BT_BAP_COEX_INT_MS_10_FAST_2 - 10), NULL)

/* When BROADCAST_ENQUEUE_COUNT > 1 we can enqueue enough buffers to ensure that
* the controller is never idle
Expand Down Expand Up @@ -491,6 +487,15 @@ int main(void)
#endif /* defined(CONFIG_LIBLC3) */

while (true) {
/* We use BT_BAP_COEX_INT_MS_10_FAST_2 as this sample only supports using 10ms SDU
* interval. BT_BAP_COEX_INT_MS_10_FAST_2 balances well between sync time (lower
* interval is faster) and air time (lower interval require more air time)
*/
const struct bt_le_per_adv_param *per_adv_param =
BT_LE_PER_ADV_PARAM(BT_GAP_MS_TO_PER_ADV_INT(BT_BAP_COEX_INT_MS_10_FAST_2),
BT_GAP_MS_TO_PER_ADV_INT(BT_BAP_COEX_INT_MS_10_FAST_2),
BT_LE_PER_ADV_OPT_NONE);

/* Broadcast Audio Streaming Endpoint advertising data */
NET_BUF_SIMPLE_DEFINE(ad_buf, BT_UUID_SIZE_16 + BT_AUDIO_BROADCAST_ID_SIZE);
NET_BUF_SIMPLE_DEFINE(base_buf, 128);
Expand All @@ -506,7 +511,7 @@ int main(void)
}

/* Set periodic advertising parameters */
err = bt_le_per_adv_set_param(adv, BT_LE_PER_ADV_DEFAULT);
err = bt_le_per_adv_set_param(adv, per_adv_param);
if (err) {
printk("Failed to set periodic advertising parameters (err %d)\n", err);
return 0;
Expand Down
11 changes: 8 additions & 3 deletions samples/bluetooth/bap_unicast_client/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,13 @@ static void print_codec_cap(const struct bt_audio_codec_cap *codec_cap)
static bool check_audio_support_and_connect(struct bt_data *data,
void *user_data)
{
/* We use BT_BAP_COEX_INT_MS_7_5_10_FAST to best support Unicast Servers
* that support both 7.5 and 10ms SDU interval
*/
const struct bt_le_conn_param *conn_param =
BT_LE_CONN_PARAM(BT_GAP_MS_TO_CONN_INT(BT_BAP_COEX_INT_MS_7_5_10_FAST),
BT_GAP_MS_TO_CONN_INT(BT_BAP_COEX_INT_MS_7_5_10_FAST), 0,
BT_GAP_MS_TO_CONN_TIMEOUT(4000));
struct net_buf_simple ascs_svc_data;
bt_addr_le_t *addr = user_data;
uint8_t announcement_type;
Expand Down Expand Up @@ -162,9 +169,7 @@ static bool check_audio_support_and_connect(struct bt_data *data,
printk("Audio server found with type %u, contexts 0x%08x and meta_len %u; connecting\n",
announcement_type, audio_contexts, meta_len);

err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
BT_LE_CONN_PARAM_DEFAULT,
&default_conn);
err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, conn_param, &default_conn);
if (err != 0) {
printk("Create conn to failed (%u)\n", err);
start_scan();
Expand Down
11 changes: 10 additions & 1 deletion samples/bluetooth/cap_acceptor/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

#include <zephyr/bluetooth/addr.h>
#include <zephyr/bluetooth/audio/audio.h>
#include <zephyr/bluetooth/audio/bap.h>
#include <zephyr/bluetooth/audio/cap.h>
#include <zephyr/bluetooth/audio/lc3.h>
#include <zephyr/bluetooth/audio/pacs.h>
Expand Down Expand Up @@ -102,9 +103,17 @@ BT_CONN_CB_DEFINE(conn_callbacks) = {

static int advertise(void)
{
/* Use BT_BAP_COEX_INT_MS_7_5_10_FAST as advertising interval to better support advertising
* connectable, even if we are synced synced to a broadcast source by self-scanning
*/
const struct bt_le_adv_param *adv_param =
BT_LE_ADV_PARAM(BT_LE_ADV_OPT_EXT_ADV | BT_LE_ADV_OPT_CONN,
BT_GAP_MS_TO_ADV_INT(BT_BAP_COEX_INT_MS_7_5_10_FAST),
BT_GAP_MS_TO_ADV_INT(BT_BAP_COEX_INT_MS_7_5_10_FAST), NULL);

int err;

err = bt_le_ext_adv_create(BT_LE_EXT_ADV_CONN, NULL, &adv);
err = bt_le_ext_adv_create(adv_param, NULL, &adv);
if (err) {
LOG_ERR("Failed to create advertising set: %d", err);

Expand Down
22 changes: 18 additions & 4 deletions samples/bluetooth/cap_initiator/src/cap_initiator_broadcast.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,33 @@ static void broadcast_stream_sent_cb(struct bt_bap_stream *stream)

static int setup_extended_adv(struct bt_le_ext_adv **adv)
{
/* Zephyr Controller works best while Extended Advertising interval to be a multiple
* of the ISO Interval minus 10 ms (max. advertising random delay). This is
* required to place the AUX_ADV_IND PDUs in a non-overlapping interval with the
* Broadcast ISO radio events.
*/
const struct bt_le_adv_param *ext_adv_param = BT_LE_ADV_PARAM(
BT_LE_ADV_OPT_EXT_ADV, BT_GAP_MS_TO_ADV_INT(BT_BAP_COEX_INT_MS_10_FAST_2 - 10),
BT_GAP_MS_TO_ADV_INT(BT_BAP_COEX_INT_MS_10_FAST_2 - 10), NULL);

/* We use BT_BAP_COEX_INT_MS_10_FAST_2 as this sample only supports using 10ms SDU
* interval. BT_BAP_COEX_INT_MS_10_FAST_2 balances well between sync time (lower
* interval is faster) and air time (lower interval require more air time)
*/
const struct bt_le_per_adv_param *per_adv_param = BT_LE_PER_ADV_PARAM(
BT_GAP_MS_TO_PER_ADV_INT(BT_BAP_COEX_INT_MS_10_FAST_2),
BT_GAP_MS_TO_PER_ADV_INT(BT_BAP_COEX_INT_MS_10_FAST_2), BT_LE_PER_ADV_OPT_NONE);
int err;

/* Create a non-connectable non-scannable advertising set */
err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN, NULL, adv);
err = bt_le_ext_adv_create(ext_adv_param, NULL, adv);
if (err != 0) {
LOG_ERR("Unable to create extended advertising set: %d", err);
return err;
}

/* Set periodic advertising parameters */
err = bt_le_per_adv_set_param(*adv, BT_LE_PER_ADV_PARAM(BT_GAP_PER_ADV_FAST_INT_MIN_2,
BT_GAP_PER_ADV_FAST_INT_MAX_2,
BT_LE_PER_ADV_OPT_NONE));
err = bt_le_per_adv_set_param(*adv, per_adv_param);
if (err != 0) {
LOG_ERR("Failed to set periodic advertising parameters: %d", err);
return err;
Expand Down
9 changes: 8 additions & 1 deletion samples/bluetooth/cap_initiator/src/cap_initiator_unicast.c
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,13 @@ BT_CONN_CB_DEFINE(conn_callbacks) = {

static bool check_audio_support_and_connect_cb(struct bt_data *data, void *user_data)
{
/* We use BT_BAP_COEX_INT_MS_7_5_10_FAST to best support CAP Acceptors
* that support both 7.5 and 10ms SDU interval
*/
const struct bt_le_conn_param *conn_param =
BT_LE_CONN_PARAM(BT_GAP_MS_TO_CONN_INT(BT_BAP_COEX_INT_MS_7_5_10_FAST),
BT_GAP_MS_TO_CONN_INT(BT_BAP_COEX_INT_MS_7_5_10_FAST), 0,
BT_GAP_MS_TO_CONN_TIMEOUT(4000));
char addr_str[BT_ADDR_LE_STR_LEN];
bt_addr_le_t *addr = user_data;
const struct bt_uuid *uuid;
Expand Down Expand Up @@ -599,7 +606,7 @@ static bool check_audio_support_and_connect_cb(struct bt_data *data, void *user_
return false;
}

err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, BT_LE_CONN_PARAM_DEFAULT, &peer.conn);
err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, conn_param, &peer.conn);
if (err != 0) {
LOG_WRN("Create conn to failed: %d, restarting scan", err);
start_scan();
Expand Down
20 changes: 18 additions & 2 deletions samples/bluetooth/pbp_public_broadcast_source/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,10 +146,26 @@ static struct bt_bap_stream_ops broadcast_stream_ops = {

static int setup_extended_adv(struct bt_le_ext_adv **adv)
{
/* Zephyr Controller works best while Extended Advertising interval to be a multiple
* of the ISO Interval minus 10 ms (max. advertising random delay). This is
* required to place the AUX_ADV_IND PDUs in a non-overlapping interval with the
* Broadcast ISO radio events.
*/
const struct bt_le_adv_param *ext_adv_param = BT_LE_ADV_PARAM(
BT_LE_ADV_OPT_EXT_ADV, BT_GAP_MS_TO_ADV_INT(BT_BAP_COEX_INT_MS_10_FAST_2 - 10),
BT_GAP_MS_TO_ADV_INT(BT_BAP_COEX_INT_MS_10_FAST_2 - 10), NULL);

/* We use BT_BAP_COEX_INT_MS_10_FAST_2 as this sample only supports using 10ms SDU
* interval. BT_BAP_COEX_INT_MS_10_FAST_2 balances well between sync time (lower
* interval is faster) and air time (lower interval require more air time)
*/
const struct bt_le_per_adv_param *per_adv_param = BT_LE_PER_ADV_PARAM(
BT_GAP_MS_TO_PER_ADV_INT(BT_BAP_COEX_INT_MS_10_FAST_2),
BT_GAP_MS_TO_PER_ADV_INT(BT_BAP_COEX_INT_MS_10_FAST_2), BT_LE_PER_ADV_OPT_NONE);
int err;

/* Create a non-connectable advertising set */
err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN, NULL, adv);
err = bt_le_ext_adv_create(ext_adv_param, NULL, adv);
if (err != 0) {
printk("Unable to create extended advertising set: %d\n", err);

Expand All @@ -165,7 +181,7 @@ static int setup_extended_adv(struct bt_le_ext_adv **adv)
}

/* Set periodic advertising parameters */
err = bt_le_per_adv_set_param(*adv, BT_LE_PER_ADV_DEFAULT);
err = bt_le_per_adv_set_param(*adv, per_adv_param);
if (err) {
printk("Failed to set periodic advertising parameters: %d\n", err);

Expand Down
20 changes: 18 additions & 2 deletions samples/bluetooth/tmap_bms/src/cap_initiator.c
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,26 @@ static const struct bt_data ad[] = {

static int setup_extended_adv(struct bt_le_ext_adv **adv)
{
/* Zephyr Controller works best while Extended Advertising interval to be a multiple
* of the ISO Interval minus 10 ms (max. advertising random delay). This is
* required to place the AUX_ADV_IND PDUs in a non-overlapping interval with the
* Broadcast ISO radio events.
*/
const struct bt_le_adv_param *ext_adv_param = BT_LE_ADV_PARAM(
BT_LE_ADV_OPT_EXT_ADV, BT_GAP_MS_TO_ADV_INT(BT_BAP_COEX_INT_MS_10_FAST_2 - 10),
BT_GAP_MS_TO_ADV_INT(BT_BAP_COEX_INT_MS_10_FAST_2 - 10), NULL);

/* We use BT_BAP_COEX_INT_MS_10_FAST_2 as this sample only supports using 10ms SDU
* interval. BT_BAP_COEX_INT_MS_10_FAST_2 balances well between sync time (lower
* interval is faster) and air time (lower interval require more air time)
*/
const struct bt_le_per_adv_param *per_adv_param = BT_LE_PER_ADV_PARAM(
BT_GAP_MS_TO_PER_ADV_INT(BT_BAP_COEX_INT_MS_10_FAST_2),
BT_GAP_MS_TO_PER_ADV_INT(BT_BAP_COEX_INT_MS_10_FAST_2), BT_LE_PER_ADV_OPT_NONE);
int err;

/* Create a non-connectable advertising set */
err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN, NULL, adv);
err = bt_le_ext_adv_create(ext_adv_param, NULL, adv);
if (err != 0) {
printk("Unable to create extended advertising set: %d\n", err);
return err;
Expand All @@ -150,7 +166,7 @@ static int setup_extended_adv(struct bt_le_ext_adv **adv)
}

/* Set periodic advertising parameters */
err = bt_le_per_adv_set_param(*adv, BT_LE_PER_ADV_DEFAULT);
err = bt_le_per_adv_set_param(*adv, per_adv_param);
if (err) {
printk("Failed to set periodic advertising parameters: %d\n",
err);
Expand Down
11 changes: 8 additions & 3 deletions samples/bluetooth/tmap_central/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,13 @@ BT_CONN_CB_DEFINE(conn_callbacks) = {

static bool check_audio_support_and_connect(struct bt_data *data, void *user_data)
{
/* We use BT_BAP_COEX_INT_MS_7_5_10_FAST to best support TMAP peripherals
* that support both 7.5 and 10ms SDU interval
*/
const struct bt_le_conn_param *conn_param =
BT_LE_CONN_PARAM(BT_GAP_MS_TO_CONN_INT(BT_BAP_COEX_INT_MS_7_5_10_FAST),
BT_GAP_MS_TO_CONN_INT(BT_BAP_COEX_INT_MS_7_5_10_FAST), 0,
BT_GAP_MS_TO_CONN_TIMEOUT(4000));
bt_addr_le_t *addr = user_data;
struct net_buf_simple tmas_svc_data;
const struct bt_uuid *uuid;
Expand Down Expand Up @@ -188,9 +195,7 @@ static bool check_audio_support_and_connect(struct bt_data *data, void *user_dat
return false;
}

err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
BT_LE_CONN_PARAM_DEFAULT,
&default_conn);
err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, conn_param, &default_conn);
if (err != 0) {
printk("Create conn to failed (%u)\n", err);
start_scan();
Expand Down
1 change: 1 addition & 0 deletions subsys/bluetooth/audio/bap_broadcast_assistant.c
Original file line number Diff line number Diff line change
Expand Up @@ -784,6 +784,7 @@ static void bap_broadcast_assistant_write_cp_cb(struct bt_conn *conn, uint8_t er
net_buf_simple_reset(&att_buf);

atomic_clear_bit(inst->flags, BAP_BA_FLAG_BUSY);
LOG_ERR("");

SYS_SLIST_FOR_EACH_CONTAINER_SAFE(&broadcast_assistant_cbs, listener, next, _node) {
switch (opcode) {
Expand Down
19 changes: 17 additions & 2 deletions subsys/bluetooth/host/shell/bt.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
*/

#include <errno.h>
#include <zephyr/autoconf.h>
#include <zephyr/bluetooth/audio/bap.h>
#include <zephyr/bluetooth/gap.h>
#include <zephyr/types.h>
#include <ctype.h>
#include <stddef.h>
Expand Down Expand Up @@ -3261,11 +3264,24 @@ static int cmd_subrate_request(const struct shell *sh, size_t argc, char *argv[]
#if defined(CONFIG_BT_CENTRAL)
static int cmd_connect_le(const struct shell *sh, size_t argc, char *argv[])
{
struct bt_le_conn_param conn_param;
int err;
bt_addr_le_t addr;
struct bt_conn *conn;
uint32_t options = 0;

if (IS_ENABLED(CONFIG_BT_BAP_UNICAST) || IS_ENABLED(CONFIG_BT_BAP_BROADCAST_ASSISTANT)) {
/* We use BT_BAP_COEX_INT_MS_7_5_10_FAST to best support peripherals
* that support both 7.5 and 10ms SDU interval
*/
conn_param =
*BT_LE_CONN_PARAM(BT_GAP_MS_TO_CONN_INT(BT_BAP_COEX_INT_MS_7_5_10_FAST),
BT_GAP_MS_TO_CONN_INT(BT_BAP_COEX_INT_MS_7_5_10_FAST), 0,
BT_GAP_MS_TO_CONN_TIMEOUT(4000));
} else {
conn_param = *BT_LE_CONN_PARAM_DEFAULT;
}

/* When no arguments are specified, connect to the last scanned device. */
if (argc == 1) {
if (auto_connect.addr_set) {
Expand Down Expand Up @@ -3304,8 +3320,7 @@ static int cmd_connect_le(const struct shell *sh, size_t argc, char *argv[])
BT_GAP_SCAN_FAST_INTERVAL,
BT_GAP_SCAN_FAST_INTERVAL);

err = bt_conn_le_create(&addr, create_params, BT_LE_CONN_PARAM_DEFAULT,
&conn);
err = bt_conn_le_create(&addr, create_params, &conn_param, &conn);
if (err) {
shell_error(sh, "Connection failed (%d)", err);
return -ENOEXEC;
Expand Down
Loading

0 comments on commit f4f3960

Please sign in to comment.