nimble/ll: Move wfr handling to LL context

With this patch we move handling scan cleaning to LL context in case of
wfr timeout. This is in order to avoid races on access to scansm data.
This commit is contained in:
Łukasz Rymanowski
2019-06-17 20:06:36 +09:00
parent ae020dace0
commit b6b6958d77
3 changed files with 39 additions and 32 deletions
@@ -143,6 +143,7 @@ struct ble_ll_scan_sm
struct os_mbuf *scan_req_pdu;
struct ble_npl_event scan_sched_ev;
struct hal_timer scan_timer;
struct ble_npl_event scan_wfr_ev;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
struct hal_timer duration_timer;
+2 -10
View File
@@ -554,18 +554,10 @@ ble_ll_conn_init_wfr_timer_exp(void)
}
ble_ll_conn_reset_pending_aux_conn_rsp();
connsm->inita_identity_used = 0;
scansm = connsm->scansm;
if (scansm && scansm->cur_aux_data) {
if (ble_ll_scan_aux_data_unref(scansm->cur_aux_data)) {
ble_ll_scan_aux_data_unref(scansm->cur_aux_data);
}
scansm->cur_aux_data = NULL;
STATS_INC(ble_ll_stats, aux_missed_adv);
ble_ll_event_send(&scansm->scan_sched_ev);
}
connsm->inita_identity_used = 0;
ble_ll_event_send(&scansm->scan_wfr_ev);
#endif
}
/**
+36 -22
View File
@@ -1501,6 +1501,39 @@ ble_ll_aux_scan_rsp_failed(void)
}
#endif
static void
ble_ll_scan_wfr_event_cb(struct ble_npl_event *ev)
{
struct ble_ll_scan_sm *scansm = ev->ev.ev_arg;
if (!scansm->scan_enabled) {
return;
}
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
if (scansm && scansm->cur_aux_data) {
ble_ll_scan_aux_data_unref(scansm->cur_aux_data);
scansm->cur_aux_data = NULL;
STATS_INC(ble_ll_stats, aux_missed_adv);
}
#endif
/*
* If we timed out waiting for a response, the scan response pending
* flag should be set. Deal with scan backoff. Put device back into rx.
*/
if (scansm->scan_rsp_pending) {
ble_ll_scan_req_backoff(scansm, 0);
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
ble_ll_aux_scan_rsp_failed();
#endif
}
ble_ll_scan_chk_resume();
ble_phy_restart_rx();
}
/**
* Called to process the scanning OS event which was posted to the LL task
*
@@ -2610,29 +2643,8 @@ ble_ll_scan_wfr_timer_exp(void)
{
struct ble_ll_scan_sm *scansm;
/*
* If we timed out waiting for a response, the scan response pending
* flag should be set. Deal with scan backoff. Put device back into rx.
*/
scansm = &g_ble_ll_scan_sm;
if (scansm->scan_rsp_pending) {
ble_ll_scan_req_backoff(scansm, 0);
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
ble_ll_aux_scan_rsp_failed();
ble_ll_scan_chk_resume();
#endif
}
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
if (scansm->cur_aux_data) {
ble_ll_scan_end_adv_evt(scansm->cur_aux_data);
scansm->cur_aux_data = NULL;
STATS_INC(ble_ll_stats, aux_missed_adv);
ble_ll_scan_chk_resume();
}
#endif
ble_phy_restart_rx();
ble_ll_event_send(&scansm->scan_wfr_ev);
}
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
@@ -3795,6 +3807,8 @@ ble_ll_scan_common_init(void)
scansm);
#endif
ble_npl_event_init(&scansm->scan_wfr_ev, ble_ll_scan_wfr_event_cb, scansm);
/* Get a scan request mbuf (packet header) and attach to state machine */
scansm->scan_req_pdu = os_msys_get_pkthdr(BLE_SCAN_LEGACY_MAX_PKT_LEN,
sizeof(struct ble_mbuf_hdr));