Skip to content

Commit 89689e0

Browse files
cvinayakAnas Nashif
authored andcommitted
Bluetooth: controller: Fix HCI Reset hang
Issuing HCI reset command while having connections sometimes hung the controller. ll_reset supplied invalid stop ticker id to role_disable when trying to stop all connections. Connection role does not utilize stop ticker. The invalid ticker id supplied referenced memory outside the pool of tickers and based on what the content is in RAM there, the controller would hang trying to stop connections. Fixed by not calling the ticker_stop interface with invalid ticker ids. Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent 91f4c38 commit 89689e0

File tree

1 file changed

+21
-13
lines changed
  • subsys/bluetooth/controller/ll_sw

1 file changed

+21
-13
lines changed

subsys/bluetooth/controller/ll_sw/ctrl.c

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9428,29 +9428,37 @@ static inline void role_active_disable(u8_t ticker_id_stop,
94289428
LL_ASSERT(0);
94299429
}
94309430
} else if (ret_cb == TICKER_STATUS_FAILURE) {
9431-
u32_t volatile ret_cb = TICKER_STATUS_BUSY;
9432-
u32_t ret;
9433-
94349431
/* Step 3: Caller inside Event, handle graceful stop of Event
94359432
* (role dependent)
94369433
*/
9434+
94379435
/* Stop ticker "may" be in use for direct adv or scanner,
94389436
* hence stop may fail if ticker not used.
9437+
*
9438+
* Connection instances do not use a stop ticker, hence do not
9439+
* try to stop an invalid ticker id.
94399440
*/
9440-
ret = ticker_stop(RADIO_TICKER_INSTANCE_ID_RADIO,
9441-
RADIO_TICKER_USER_ID_APP, ticker_id_stop,
9442-
ticker_if_done, (void *)&ret_cb);
9441+
if (ticker_id_stop != TICKER_NULL) {
9442+
u32_t volatile ret_cb = TICKER_STATUS_BUSY;
9443+
u32_t ret;
94439444

9444-
if (ret == TICKER_STATUS_BUSY) {
9445-
mayfly_enable(RADIO_TICKER_USER_ID_APP,
9446-
RADIO_TICKER_USER_ID_JOB, 1);
9445+
ret = ticker_stop(RADIO_TICKER_INSTANCE_ID_RADIO,
9446+
RADIO_TICKER_USER_ID_APP,
9447+
ticker_id_stop, ticker_if_done,
9448+
(void *)&ret_cb);
94479449

9448-
LL_ASSERT(ret_cb != TICKER_STATUS_BUSY);
9449-
}
9450+
if (ret == TICKER_STATUS_BUSY) {
9451+
mayfly_enable(RADIO_TICKER_USER_ID_APP,
9452+
RADIO_TICKER_USER_ID_JOB, 1);
94509453

9451-
LL_ASSERT((ret_cb == TICKER_STATUS_SUCCESS) ||
9452-
(ret_cb == TICKER_STATUS_FAILURE));
9454+
LL_ASSERT(ret_cb != TICKER_STATUS_BUSY);
9455+
}
9456+
9457+
LL_ASSERT((ret_cb == TICKER_STATUS_SUCCESS) ||
9458+
(ret_cb == TICKER_STATUS_FAILURE));
9459+
}
94539460

9461+
/* Force Radio ISR execution and wait for role to stop */
94549462
if (_radio.role != ROLE_NONE) {
94559463
static void *s_link[2];
94569464
static struct mayfly s_mfy_radio_stop = {0, 0, s_link,

0 commit comments

Comments
 (0)