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);
|
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 */
|
/* Reset connection event global variables */
|
||||||
lll_conn_prepare_reset();
|
lll_conn_prepare_reset();
|
||||||
|
|
||||||
|
|
|
@ -109,6 +109,20 @@ static int prepare_cb(struct lll_prepare_param *prepare_param)
|
||||||
|
|
||||||
DEBUG_RADIO_START_S(1);
|
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 */
|
/* Reset connection event global variables */
|
||||||
lll_conn_prepare_reset();
|
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)
|
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
|
/* Check if no other procedure with instant is requested and not in
|
||||||
* Encryption setup.
|
* 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 memq_link_t link;
|
||||||
static struct mayfly mfy = {0, 0, &link, NULL, lll_master_prepare};
|
static struct mayfly mfy = {0, 0, &link, NULL, lll_master_prepare};
|
||||||
static struct lll_prepare_param p;
|
static struct lll_prepare_param p;
|
||||||
struct ll_conn *conn = param;
|
struct ll_conn *conn;
|
||||||
uint32_t err;
|
uint32_t err;
|
||||||
uint8_t ref;
|
uint8_t ref;
|
||||||
|
|
||||||
DEBUG_RADIO_PREPARE_M(1);
|
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
|
/* 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.
|
* 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 memq_link_t link;
|
||||||
static struct mayfly mfy = {0, 0, &link, NULL, lll_slave_prepare};
|
static struct mayfly mfy = {0, 0, &link, NULL, lll_slave_prepare};
|
||||||
static struct lll_prepare_param p;
|
static struct lll_prepare_param p;
|
||||||
struct ll_conn *conn = param;
|
struct ll_conn *conn;
|
||||||
uint32_t err;
|
uint32_t err;
|
||||||
uint8_t ref;
|
uint8_t ref;
|
||||||
|
|
||||||
DEBUG_RADIO_PREPARE_S(1);
|
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
|
/* 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.
|
* to know. Will be called with lazy > 0 when scheduled in air.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue