From 8402a9adc0bc3716ac0751daa18c93d8476e27d9 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Fri, 4 Oct 2019 14:44:52 +0200 Subject: [PATCH] nimble/ll: Fix crash when scanning for AUX packets When dropping scan for AUX packet we need to make sure to send HCI report with data truncated flag set whe needed. Otherwise assert is triggered in ble_ll_scan_aux_data_unref (as this leaves host in undefined state). --- nimble/controller/include/controller/ble_ll.h | 1 + .../include/controller/ble_ll_scan.h | 1 + nimble/controller/src/ble_ll.c | 1 + nimble/controller/src/ble_ll_scan.c | 24 +++++++++++++++++-- 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h index 5fe808410..a854362d5 100644 --- a/nimble/controller/include/controller/ble_ll.h +++ b/nimble/controller/include/controller/ble_ll.h @@ -199,6 +199,7 @@ STATS_SECT_START(ble_ll_stats) STATS_SECT_ENTRY(aux_scan_rsp_err) STATS_SECT_ENTRY(aux_chain_cnt) STATS_SECT_ENTRY(aux_chain_err) + STATS_SECT_ENTRY(aux_scan_drop) STATS_SECT_ENTRY(adv_evt_dropped) STATS_SECT_ENTRY(scan_timer_stopped) STATS_SECT_ENTRY(scan_timer_restarted) diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h index e1f81975f..5f363842b 100644 --- a/nimble/controller/include/controller/ble_ll_scan.h +++ b/nimble/controller/include/controller/ble_ll_scan.h @@ -119,6 +119,7 @@ struct ble_ll_aux_data { uint8_t evt_type; struct ble_ll_sched_item sch; struct ble_ll_ext_adv_report *evt; + struct ble_npl_event ev; }; struct ble_ll_scan_pdu_data { diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c index 35db515aa..4afb1a00e 100644 --- a/nimble/controller/src/ble_ll.c +++ b/nimble/controller/src/ble_ll.c @@ -205,6 +205,7 @@ STATS_NAME_START(ble_ll_stats) STATS_NAME(ble_ll_stats, aux_scan_rsp_err) STATS_NAME(ble_ll_stats, aux_chain_cnt) STATS_NAME(ble_ll_stats, aux_chain_err) + STATS_NAME(ble_ll_stats, aux_scan_drop) STATS_NAME(ble_ll_stats, adv_evt_dropped) STATS_NAME(ble_ll_stats, scan_timer_stopped) STATS_NAME(ble_ll_stats, scan_timer_restarted) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 823cfbe7a..433388130 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -182,6 +182,26 @@ static struct os_mempool ext_scan_aux_pool; static int ble_ll_scan_start(struct ble_ll_scan_sm *scansm, struct ble_ll_sched_item *sch); +static void +ble_ll_aux_scan_drop_event_cb(struct ble_npl_event *ev) +{ + struct ble_ll_aux_data *aux_data = ble_npl_event_get_arg(ev); + + ble_ll_scan_end_adv_evt(aux_data); + ble_ll_scan_aux_data_unref(aux_data); +} + +static void +ble_ll_aux_scan_drop(struct ble_ll_aux_data *aux_data) +{ + BLE_LL_ASSERT(aux_data); + + STATS_INC(ble_ll_stats, aux_scan_drop); + + ble_npl_event_init(&aux_data->ev, ble_ll_aux_scan_drop_event_cb, aux_data); + ble_ll_event_send(&aux_data->ev); +} + static int ble_ll_aux_scan_cb(struct ble_ll_sched_item *sch) { @@ -195,14 +215,14 @@ ble_ll_aux_scan_cb(struct ble_ll_sched_item *sch) * just drop the scheduled item */ if (!scansm->scan_enabled || scansm->cur_aux_data) { - ble_ll_scan_aux_data_unref(sch->cb_arg); + ble_ll_aux_scan_drop(sch->cb_arg); sch->cb_arg = NULL; goto done; } /* Check if there is no aux connect sent. If so drop the sched item */ if (lls == BLE_LL_STATE_INITIATING && ble_ll_conn_init_pending_aux_conn_rsp()) { - ble_ll_scan_aux_data_unref(sch->cb_arg); + ble_ll_aux_scan_drop(sch->cb_arg); sch->cb_arg = NULL; goto done; }