Bluetooth: controller: Connection termination race condition
Add checks to abort connection radio event preparation and start, if the connection terminates with a race condition with new radio event being prepared or being in prepare pipeline. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
3e2dc0d706
commit
b6fb074d6e
5 changed files with 48 additions and 4 deletions
|
@ -100,6 +100,20 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
|
|||
|
||||
DEBUG_RADIO_START_M(1);
|
||||
|
||||
/* Check if stopped (on disconnection between prepare and pre-empt)
|
||||
*/
|
||||
if (unlikely(lll->handle == 0xFFFF)) {
|
||||
int err;
|
||||
|
||||
err = lll_hfclock_off();
|
||||
LL_ASSERT(err >= 0);
|
||||
|
||||
lll_done(NULL);
|
||||
|
||||
DEBUG_RADIO_START_M(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Reset connection event global variables */
|
||||
lll_conn_prepare_reset();
|
||||
|
||||
|
|
|
@ -109,6 +109,20 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
|
|||
|
||||
DEBUG_RADIO_START_S(1);
|
||||
|
||||
/* Check if stopped (on disconnection between prepare and pre-empt)
|
||||
*/
|
||||
if (unlikely(lll->handle == 0xFFFF)) {
|
||||
int err;
|
||||
|
||||
err = lll_hfclock_off();
|
||||
LL_ASSERT(err >= 0);
|
||||
|
||||
lll_done(NULL);
|
||||
|
||||
DEBUG_RADIO_START_S(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Reset connection event global variables */
|
||||
lll_conn_prepare_reset();
|
||||
|
||||
|
|
|
@ -815,8 +815,6 @@ 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)
|
||||
{
|
||||
LL_ASSERT(conn->lll.handle != 0xFFFF);
|
||||
|
||||
/* Check if no other procedure with instant is requested and not in
|
||||
* Encryption setup.
|
||||
*/
|
||||
|
|
|
@ -728,12 +728,21 @@ void ull_master_ticker_cb(uint32_t ticks_at_expire, uint32_t remainder, uint16_t
|
|||
static memq_link_t link;
|
||||
static struct mayfly mfy = {0, 0, &link, NULL, lll_master_prepare};
|
||||
static struct lll_prepare_param p;
|
||||
struct ll_conn *conn = param;
|
||||
struct ll_conn *conn;
|
||||
uint32_t err;
|
||||
uint8_t ref;
|
||||
|
||||
DEBUG_RADIO_PREPARE_M(1);
|
||||
|
||||
conn = param;
|
||||
|
||||
/* Check if stopping ticker (on disconnection, race with ticker expiry)
|
||||
*/
|
||||
if (unlikely(conn->lll.handle == 0xFFFF)) {
|
||||
DEBUG_RADIO_PREPARE_M(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If this is a must-expire callback, LLCP state machine does not need
|
||||
* to know. Will be called with lazy > 0 when scheduled in air.
|
||||
*/
|
||||
|
|
|
@ -375,12 +375,21 @@ void ull_slave_ticker_cb(uint32_t ticks_at_expire, uint32_t remainder,
|
|||
static memq_link_t link;
|
||||
static struct mayfly mfy = {0, 0, &link, NULL, lll_slave_prepare};
|
||||
static struct lll_prepare_param p;
|
||||
struct ll_conn *conn = param;
|
||||
struct ll_conn *conn;
|
||||
uint32_t err;
|
||||
uint8_t ref;
|
||||
|
||||
DEBUG_RADIO_PREPARE_S(1);
|
||||
|
||||
conn = param;
|
||||
|
||||
/* Check if stopping ticker (on disconnection, race with ticker expiry)
|
||||
*/
|
||||
if (unlikely(conn->lll.handle == 0xFFFF)) {
|
||||
DEBUG_RADIO_PREPARE_S(0);
|
||||
return;
|
||||
}
|
||||
|
||||
/* If this is a must-expire callback, LLCP state machine does not need
|
||||
* to know. Will be called with lazy > 0 when scheduled in air.
|
||||
*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue