Skip to content
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

bluetooth: host: Allow concurrent advertising with multiple ids #34848

Merged
Merged
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
3 changes: 0 additions & 3 deletions include/bluetooth/bluetooth.h
Original file line number Diff line number Diff line change
Expand Up @@ -537,9 +537,6 @@ struct bt_le_adv_param {
* enabled or not supported by the controller it is not possible
* to scan and advertise simultaneously using two different
* random addresses.
*
* @note It is not possible to have multiple connectable advertising
* sets advertising simultaneously using different identities.
*/
uint8_t id;

Expand Down
20 changes: 20 additions & 0 deletions subsys/bluetooth/host/adv.c
Original file line number Diff line number Diff line change
Expand Up @@ -1553,6 +1553,26 @@ void bt_hci_le_adv_set_terminated(struct net_buf *buf)
adv = bt_adv_lookup_handle(evt->adv_handle);
conn_handle = sys_le16_to_cpu(evt->conn_handle);

#if (CONFIG_BT_ID_MAX > 1) && (CONFIG_BT_EXT_ADV_MAX_ADV_SET > 1)
bt_dev.adv_conn_id = adv->id;
for (int i = 0; i < ARRAY_SIZE(bt_dev.cached_conn_complete); i++) {
if (bt_dev.cached_conn_complete[i].valid &&
bt_dev.cached_conn_complete[i].evt.handle == evt->conn_handle) {
if (atomic_test_bit(adv->flags, BT_ADV_ENABLED)) {
/* Process the cached connection complete event
* now that the corresponding advertising set is known.
*
* If the advertiser has been stopped before the connection
* complete event has been raised to the application, we
* discard the event.
*/
bt_hci_le_enh_conn_complete(&bt_dev.cached_conn_complete[i].evt);
}
bt_dev.cached_conn_complete[i].valid = false;
Copy link
Collaborator

Choose a reason for hiding this comment

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

It still seems that in case that the application disables the advertising set after the connection complete event is received, but before the adv terminated event, then we don't clean up the cached connection complete event, as there won't be a adv terminated event.

}
}
#endif

BT_DBG("status 0x%02x adv_handle %u conn_handle 0x%02x num %u",
evt->status, evt->adv_handle, conn_handle,
evt->num_completed_ext_adv_evts);
Expand Down
31 changes: 31 additions & 0 deletions subsys/bluetooth/host/hci_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -1042,6 +1042,37 @@ static void le_conn_complete_adv_timeout(void)
}

static void enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt)
{
#if (CONFIG_BT_ID_MAX > 1) && (CONFIG_BT_EXT_ADV_MAX_ADV_SET > 1)
if (IS_ENABLED(CONFIG_BT_PERIPHERAL) &&
evt->role == BT_HCI_ROLE_SLAVE &&
evt->status == BT_HCI_ERR_SUCCESS &&
(IS_ENABLED(CONFIG_BT_EXT_ADV) &&
BT_FEAT_LE_EXT_ADV(bt_dev.le.features))) {

/* Cache the connection complete event. Process it later.
* See bt_dev.cached_conn_complete.
*/
for (int i = 0; i < ARRAY_SIZE(bt_dev.cached_conn_complete); i++) {
if (!bt_dev.cached_conn_complete[i].valid) {
(void)memcpy(&bt_dev.cached_conn_complete[i].evt,
evt,
sizeof(struct bt_hci_evt_le_enh_conn_complete));
bt_dev.cached_conn_complete[i].valid = true;
return;
}
}

__ASSERT(false, "No more cache entries available."
"This should not happen by design");

return;
}
#endif
bt_hci_le_enh_conn_complete(evt);
}
Thalley marked this conversation as resolved.
Show resolved Hide resolved

void bt_hci_le_enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt)
{
uint16_t handle = sys_le16_to_cpu(evt->handle);
bt_addr_le_t peer_addr, id_addr;
Expand Down
19 changes: 19 additions & 0 deletions subsys/bluetooth/host/hci_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,22 @@ struct bt_dev {
#else
/* Pointer to reserved advertising set */
struct bt_le_ext_adv *adv;
#if (CONFIG_BT_ID_MAX > 1) && (CONFIG_BT_EXT_ADV_MAX_ADV_SET > 1)
/* When supporting multiple concurrent connectable advertising sets
* with multiple identities, we need to know the identity of
* the terminating advertising set to identify the connection object.
* The identity of the advertising set is determined by its
* advertising handle, which is part of the
* LE Set Advertising Set Terminated event which is always sent
* _after_ the LE Enhanced Connection complete event.
* Therefore we need cache this event until its identity is known.
*/
struct {
bool valid;
struct bt_hci_evt_le_enh_conn_complete evt;
} cached_conn_complete[MIN(CONFIG_BT_MAX_CONN,
CONFIG_BT_EXT_ADV_MAX_ADV_SET)];
#endif
#endif
/* Current local Random Address */
bt_addr_le_t random_addr;
Expand Down Expand Up @@ -386,6 +402,9 @@ void bt_hci_auth_complete(struct net_buf *buf);
void bt_hci_evt_le_pkey_complete(struct net_buf *buf);
void bt_hci_evt_le_dhkey_complete(struct net_buf *buf);

/* Common HCI event handlers */
void bt_hci_le_enh_conn_complete(struct bt_hci_evt_le_enh_conn_complete *evt);

/* Scan HCI event handlers */
void bt_hci_le_adv_report(struct net_buf *buf);
void bt_hci_le_scan_timeout(struct net_buf *buf);
Expand Down
3 changes: 3 additions & 0 deletions tests/bluetooth/bsim_bt/bsim_test_advx/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,6 @@ CONFIG_BT_PER_ADV_SYNC=y
CONFIG_BT_CTLR_ADV_EXT=y
CONFIG_BT_CTLR_ADV_PERIODIC=y
CONFIG_BT_CTLR_SYNC_PERIODIC=y

CONFIG_BT_ID_MAX=2
CONFIG_BT_EXT_ADV_MAX_ADV_SET=2