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:
Vinayak Kariappa Chettimada 2020-09-29 15:14:08 +05:30 committed by Ioannis Glaropoulos
commit b6fb074d6e
5 changed files with 48 additions and 4 deletions

View file

@ -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();

View file

@ -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();

View file

@ -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.
*/

View file

@ -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.
*/

View file

@ -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.
*/