From cd8462b9006c7b1b500a4b4f5210489052a35178 Mon Sep 17 00:00:00 2001 From: Andrzej Kaczmarek Date: Mon, 22 Feb 2021 16:24:01 +0100 Subject: [PATCH] nimble/ll: Fix assert on aux unref during scan This fixes assert in ble_ll_scan_aux_data_unref() during scan under heavy load. This happens when we scanned an aux with auxptr, but we failed to schedule scan for pointed aux. What happens in above scenario is that scan error is already set due to failed scheduling, but we still send complete received aux. That is ok, but we do not check for error that is already set and do not mark data as truncated which results in an assert: if any data were sent to host, it's expected that we'll have either truncated or completed flag set on last unref. The fix is to set truncated flag properly on last chunk of data from mentioned aux. --- nimble/controller/src/ble_ll_scan.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c index 0cbcb3769..197ec9107 100644 --- a/nimble/controller/src/ble_ll_scan.c +++ b/nimble/controller/src/ble_ll_scan.c @@ -2687,10 +2687,16 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, uint8_t *adva, uint8_t adva_type, /* * We need another event if either there are still some data left to - * send in current PDU or scan is not completed. The only exception is - * when this is a scannable event which is not a scan response. + * send in current PDU or scan is not completed. There are two exceptions + * though: + * - we sent all data from this PDU and there is scan error set already; + * it may be set before entering current function due to failed aux + * scan scheduling + * - this is a scannable event which is not a scan response */ - need_event = ((offset < datalen) || (aux_data && !(aux_data->flags_ll & BLE_LL_AUX_FLAG_SCAN_COMPLETE))) && !is_scannable_aux; + need_event = ((offset < datalen) || (aux_data && !(aux_data->flags_ll & BLE_LL_AUX_FLAG_SCAN_COMPLETE))) && + !((offset == datalen) && (aux_data->flags_ll & BLE_LL_AUX_FLAG_SCAN_ERROR)) && + !is_scannable_aux; if (need_event) { /*