From b6b6958d77f53310b0ad90cd16b13ddd76f37db2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=81ukasz=20Rymanowski?= Date: Wed, 5 Jun 2019 14:52:04 +0200 Subject: [PATCH] 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. --- .../include/controller/ble_ll_scan.h | 1 + nimble/controller/src/ble_ll_conn.c | 12 +--- nimble/controller/src/ble_ll_scan.c | 58 ++++++++++++------- 3 files changed, 39 insertions(+), 32 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h index 746963c90..45a8ec2d5 100644 --- a/nimble/controller/include/controller/ble_ll_scan.h +++ b/nimble/controller/include/controller/ble_ll_scan.h @@ -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; diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c index 809797c41..d37b7ad3c 100644 --- a/nimble/controller/src/ble_ll_conn.c +++ b/nimble/controller/src/ble_ll_conn.c @@ -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 } /** diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index c57dd3217..78cb1f3c8 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -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));