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: controller: Fix adv/scan context access post release #35014

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
82 changes: 67 additions & 15 deletions subsys/bluetooth/controller/ll_sw/ull_conn.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ static void ticker_update_conn_op_cb(uint32_t status, void *param);
static void ticker_stop_conn_op_cb(uint32_t status, void *param);
static void ticker_start_conn_op_cb(uint32_t status, void *param);

static void conn_setup_adv_scan_disabled_cb(void *param);
static inline void disable(uint16_t handle);
static void conn_cleanup(struct ll_conn *conn, uint8_t reason);
static void tx_ull_flush(struct ll_conn *conn);
Expand Down Expand Up @@ -817,10 +818,21 @@ bool ull_conn_peer_connected(uint8_t own_addr_type, uint8_t *own_addr,
}
#endif /* CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN */

void ull_conn_setup(memq_link_t *link, struct node_rx_hdr *rx)
void ull_conn_setup(memq_link_t *rx_link, struct node_rx_hdr *rx)
{
static memq_link_t link;
static struct mayfly mfy = {0, 0, &link, NULL, NULL};
struct node_rx_ftr *ftr;
struct lll_conn *lll;
struct ull_hdr *hdr;

/* Pass the node rx as mayfly function parameter */
mfy.param = rx;

/* Store the link in the node rx so that when done event is
* processed it can be used to enqueue node rx towards LL context
*/
rx->link = rx_link;

ftr = &(rx->rx_ftr);

Expand All @@ -829,22 +841,29 @@ void ull_conn_setup(memq_link_t *link, struct node_rx_hdr *rx)
*/
lll = *((struct lll_conn **)((uint8_t *)ftr->param +
sizeof(struct lll_hdr)));
switch (lll->role) {
#if defined(CONFIG_BT_CENTRAL)
case 0:
ull_master_setup(link, rx, ftr, lll);
break;
#endif /* CONFIG_BT_CENTRAL */

#if defined(CONFIG_BT_PERIPHERAL)
case 1:
ull_slave_setup(link, rx, ftr, lll);
break;
#endif /* CONFIG_BT_PERIPHERAL */
/* Check for reference count and decide to setup connection
* here or when done event arrives.
*/
hdr = HDR_LLL2ULL(ftr->param);
if (ull_ref_get(hdr)) {
uint32_t ret;

default:
LL_ASSERT(0);
break;
LL_ASSERT(!hdr->disabled_cb);
hdr->disabled_param = mfy.param;
hdr->disabled_cb = conn_setup_adv_scan_disabled_cb;

mfy.fp = lll_disable;
ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW,
TICKER_USER_ID_LLL, 0, &mfy);
LL_ASSERT(!ret);
} else {
uint32_t ret;

mfy.fp = conn_setup_adv_scan_disabled_cb;
ret = mayfly_enqueue(TICKER_USER_ID_ULL_LOW,
TICKER_USER_ID_ULL_HIGH, 0, &mfy);
LL_ASSERT(!ret);
}
}

Expand Down Expand Up @@ -1873,6 +1892,39 @@ static void ticker_start_conn_op_cb(uint32_t status, void *param)
LL_ASSERT(p == param);
}

static void conn_setup_adv_scan_disabled_cb(void *param)
{
struct node_rx_ftr *ftr;
struct node_rx_hdr *rx;
struct lll_conn *lll;

rx = param;
ftr = &(rx->rx_ftr);

/* NOTE: LLL conn context SHALL be after lll_hdr in
* struct lll_adv and struct lll_scan.
*/
lll = *((struct lll_conn **)((uint8_t *)ftr->param +
sizeof(struct lll_hdr)));
switch (lll->role) {
#if defined(CONFIG_BT_CENTRAL)
case 0:
ull_master_setup(rx, ftr, lll);
break;
#endif /* CONFIG_BT_CENTRAL */

#if defined(CONFIG_BT_PERIPHERAL)
case 1:
ull_slave_setup(rx, ftr, lll);
break;
#endif /* CONFIG_BT_PERIPHERAL */

default:
LL_ASSERT(0);
break;
}
}

static inline void disable(uint16_t handle)
{
struct ll_conn *conn;
Expand Down
2 changes: 1 addition & 1 deletion subsys/bluetooth/controller/ll_sw/ull_conn_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ uint8_t ull_conn_default_phy_tx_get(void);
uint8_t ull_conn_default_phy_rx_get(void);
bool ull_conn_peer_connected(uint8_t own_addr_type, uint8_t *own_addr,
uint8_t peer_addr_type, uint8_t *peer_addr);
void ull_conn_setup(memq_link_t *link, struct node_rx_hdr *rx);
void ull_conn_setup(memq_link_t *rx_link, struct node_rx_hdr *rx);
int ull_conn_rx(memq_link_t *link, struct node_rx_pdu **rx);
int ull_conn_llcp(struct ll_conn *conn, uint32_t ticks_at_expire, uint16_t lazy);
void ull_conn_done(struct node_rx_event_done *done);
Expand Down
10 changes: 8 additions & 2 deletions subsys/bluetooth/controller/ll_sw/ull_master.c
Original file line number Diff line number Diff line change
Expand Up @@ -665,8 +665,8 @@ void ull_master_cleanup(struct node_rx_hdr *rx_free)
#endif /* CONFIG_BT_CTLR_ADV_EXT && CONFIG_BT_CTLR_PHY_CODED */
}

void ull_master_setup(memq_link_t *link, struct node_rx_hdr *rx,
struct node_rx_ftr *ftr, struct lll_conn *lll)
void ull_master_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr,
struct lll_conn *lll)
{
uint32_t conn_offset_us, conn_interval_us;
uint8_t ticker_id_scan, ticker_id_conn;
Expand All @@ -679,6 +679,7 @@ void ull_master_setup(memq_link_t *link, struct node_rx_hdr *rx,
uint32_t ticker_status;
struct node_rx_cc *cc;
struct ll_conn *conn;
memq_link_t *link;
uint8_t chan_sel;

/* Get reference to Tx-ed CONNECT_IND PDU */
Expand Down Expand Up @@ -741,6 +742,11 @@ void ull_master_setup(memq_link_t *link, struct node_rx_hdr *rx,
lll->tx_pwr_lvl = RADIO_TXP_DEFAULT;
#endif /* CONFIG_BT_CTLR_TX_PWR_DYNAMIC_CONTROL */

/* Use the link stored in the node rx to enqueue connection
* complete node rx towards LL context.
*/
link = rx->link;

/* Use Channel Selection Algorithm #2 if peer too supports it */
if (IS_ENABLED(CONFIG_BT_CTLR_CHAN_SEL_2)) {
struct node_rx_pdu *rx_csa;
Expand Down
8 changes: 4 additions & 4 deletions subsys/bluetooth/controller/ll_sw/ull_master_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/

void ull_master_cleanup(struct node_rx_hdr *rx_free);
void ull_master_setup(memq_link_t *link, struct node_rx_hdr *rx,
struct node_rx_ftr *ftr, struct lll_conn *lll);
void ull_master_ticker_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_t lazy,
uint8_t force, void *param);
void ull_master_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr,
struct lll_conn *lll);
void ull_master_ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param);
10 changes: 8 additions & 2 deletions subsys/bluetooth/controller/ll_sw/ull_slave.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ static void ticker_op_cb(uint32_t status, void *param);
static void ticker_update_latency_cancel_op_cb(uint32_t ticker_status,
void *param);

void ull_slave_setup(memq_link_t *link, struct node_rx_hdr *rx,
struct node_rx_ftr *ftr, struct lll_conn *lll)
void ull_slave_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr,
struct lll_conn *lll)
{
uint32_t conn_offset_us, conn_interval_us;
uint8_t ticker_id_adv, ticker_id_conn;
Expand All @@ -72,6 +72,7 @@ void ull_slave_setup(memq_link_t *link, struct node_rx_hdr *rx,
struct node_rx_cc *cc;
struct ll_conn *conn;
uint16_t win_offset;
memq_link_t *link;
uint16_t timeout;
uint8_t chan_sel;

Expand Down Expand Up @@ -99,6 +100,11 @@ void ull_slave_setup(memq_link_t *link, struct node_rx_hdr *rx,
memcpy(peer_id_addr, peer_addr, BDADDR_SIZE);
}

/* Use the link stored in the node rx to enqueue connection
* complete node rx towards LL context.
*/
link = rx->link;

#if defined(CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN)
uint8_t own_addr_type = pdu_adv->rx_addr;
uint8_t *own_addr = adv->own_addr;
Expand Down
4 changes: 2 additions & 2 deletions subsys/bluetooth/controller/ll_sw/ull_slave_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
* SPDX-License-Identifier: Apache-2.0
*/

void ull_slave_setup(memq_link_t *link, struct node_rx_hdr *rx,
struct node_rx_ftr *ftr, struct lll_conn *lll);
void ull_slave_setup(struct node_rx_hdr *rx, struct node_rx_ftr *ftr,
struct lll_conn *lll);
void ull_slave_latency_cancel(struct ll_conn *conn, uint16_t handle);
void ull_slave_ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
uint16_t lazy, uint8_t force, void *param);