Skip to content

Commit 5220e7e

Browse files
committed
nimble/ll: Fix race condition in aux scan
This fixes race condition in aux scan what was observed on Harmony. During extended scan, the HCI Reset called, that stops the active scan and clears the scan state machine. The scan stop itself, if scan response is pending, and calls ble_ll_scan_aux_sched_remove that pokes the active scan backup (from LL via event queue). The problem is that the SM is cleared already when backoff is called, which causes an assert in ble_ll_scan_req_backoff function. This change ensures the ble_ll_scan_req_backoff is called from ble_ll_reset() function context. ble_ll_reset is always called from LL task context.
1 parent 9de025c commit 5220e7e

File tree

2 files changed

+31
-7
lines changed

2 files changed

+31
-7
lines changed

nimble/controller/src/ble_ll_scan_aux.c

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -682,10 +682,8 @@ ble_ll_hci_ev_send_ext_adv_report_for_ext(struct os_mbuf *rxpdu,
682682
}
683683

684684
static void
685-
ble_ll_scan_aux_break_ev(struct ble_npl_event *ev)
685+
scan_aux_break(struct ble_ll_scan_aux_data *aux)
686686
{
687-
struct ble_ll_scan_aux_data *aux = ble_npl_event_get_arg(ev);
688-
689687
BLE_LL_ASSERT(aux);
690688

691689
if (ble_ll_scan_aux_need_truncation(aux)) {
@@ -701,6 +699,21 @@ ble_ll_scan_aux_break_ev(struct ble_npl_event *ev)
701699
ble_ll_scan_chk_resume();
702700
}
703701

702+
static void
703+
scan_aux_break_ev(struct ble_npl_event *ev)
704+
{
705+
struct ble_ll_scan_aux_data *aux = ble_npl_event_get_arg(ev);
706+
707+
scan_aux_break(aux);
708+
}
709+
710+
static void
711+
scan_aux_break_to_ll(struct ble_ll_scan_aux_data *aux)
712+
{
713+
ble_npl_event_init(&aux->break_ev, scan_aux_break_ev, aux);
714+
ble_ll_event_add(&aux->break_ev);
715+
}
716+
704717
void
705718
ble_ll_scan_aux_break(struct ble_ll_scan_aux_data *aux)
706719
{
@@ -710,8 +723,7 @@ ble_ll_scan_aux_break(struct ble_ll_scan_aux_data *aux)
710723
}
711724
#endif
712725

713-
ble_npl_event_init(&aux->break_ev, ble_ll_scan_aux_break_ev, aux);
714-
ble_ll_event_add(&aux->break_ev);
726+
scan_aux_break_to_ll(aux);
715727
}
716728

717729
static int
@@ -1766,7 +1778,19 @@ ble_ll_scan_aux_halt(void)
17661778
void
17671779
ble_ll_scan_aux_sched_remove(struct ble_ll_sched_item *sch)
17681780
{
1769-
ble_ll_scan_aux_break(sch->cb_arg);
1781+
struct ble_ll_scan_aux_data *aux = sch->cb_arg;
1782+
1783+
#if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL)
1784+
if (aux->flags & BLE_LL_SCAN_AUX_F_W4_CONNECT_RSP) {
1785+
ble_ll_conn_send_connect_req_cancel();
1786+
}
1787+
#endif
1788+
1789+
if (ble_npl_event_is_queued(&aux->break_ev)) {
1790+
ble_ll_event_remove(&aux->break_ev);
1791+
}
1792+
1793+
scan_aux_break(aux);
17701794
}
17711795

17721796
void

nimble/controller/src/ble_ll_sched.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -942,8 +942,8 @@ ble_ll_sched_rmv_elem_type(uint8_t type, sched_remove_cb_func remove_cb)
942942
continue;
943943
}
944944
TAILQ_REMOVE(&g_ble_ll_sched_q, entry, link);
945-
remove_cb(entry);
946945
entry->enqueued = 0;
946+
remove_cb(entry);
947947
}
948948

949949
if (first_removed) {

0 commit comments

Comments
 (0)