You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ry...@apache.org on 2018/12/05 12:24:17 UTC
[mynewt-nimble] 12/13: nimble/ll: Extended scanner - add ref count
for aux data
This is an automated email from the ASF dual-hosted git repository.
rymek pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git
commit 2df0d01fe354ef289d4eb2857e8dbe6b5a1859f4
Author: Ćukasz Rymanowski <lu...@codecoup.pl>
AuthorDate: Thu Nov 8 12:25:00 2018 +0100
nimble/ll: Extended scanner - add ref count for aux data
This patch improves scanner by adding ref counter for outstanding
aux_data. With this we want to make sure aux_data is not freed e.g. when
being handover to LL and in the same time processed in the interrupt in
chaining scenario
General idea is that 1 reference is kept as long as event is not
completed (note: truncated is also completed) and other references are
use when:
- aux is scheduled
- report is sending to the host
- scan request has been sent
- when packet is handover to LL
---
nimble/controller/include/controller/ble_ll_scan.h | 5 +-
.../controller/include/controller/ble_ll_trace.h | 2 +
nimble/controller/src/ble_ll_conn.c | 56 +++++--
nimble/controller/src/ble_ll_scan.c | 179 ++++++++++++++++-----
nimble/controller/src/ble_ll_sched.c | 4 +-
nimble/controller/src/ble_ll_trace.c | 2 +
6 files changed, 189 insertions(+), 59 deletions(-)
diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h
index 98246fb..5aa34f0 100644
--- a/nimble/controller/include/controller/ble_ll_scan.h
+++ b/nimble/controller/include/controller/ble_ll_scan.h
@@ -95,9 +95,11 @@ struct ble_ll_scan_params
#define BLE_LL_AUX_IGNORE_BIT 0x10
#define BLE_LL_AUX_HAS_DIR_ADDRA 0x20
+#define BLE_LL_SET_AUX_FLAG(aux_data, flag) ((aux_data)->flags |= flag)
#define BLE_LL_CHECK_AUX_FLAG(aux_data, flag) (!!((aux_data)->flags & flag))
struct ble_ll_aux_data {
+ uint8_t ref_cnt;
uint8_t chan;
uint8_t aux_phy;
uint8_t aux_primary_phy;
@@ -245,7 +247,8 @@ int ble_ll_scan_parse_ext_hdr(struct os_mbuf *om,
struct ble_mbuf_hdr *ble_hdr,
struct ble_ll_ext_adv_report *parsed_evt);
-void ble_ll_scan_aux_data_free(struct ble_ll_aux_data *aux_scan);
+void ble_ll_scan_aux_data_ref(struct ble_ll_aux_data *aux_scan);
+int ble_ll_scan_aux_data_unref(struct ble_ll_aux_data *aux_scan);
#endif
/* Called to clean up current aux data */
diff --git a/nimble/controller/include/controller/ble_ll_trace.h b/nimble/controller/include/controller/ble_ll_trace.h
index b2556d8..7545b57 100644
--- a/nimble/controller/include/controller/ble_ll_trace.h
+++ b/nimble/controller/include/controller/ble_ll_trace.h
@@ -38,6 +38,8 @@ extern "C" {
#define BLE_LL_TRACE_ID_CONN_RX 9
#define BLE_LL_TRACE_ID_ADV_TXDONE 10
#define BLE_LL_TRACE_ID_ADV_HALT 11
+#define BLE_LL_TRACE_ID_AUX_REF 12
+#define BLE_LL_TRACE_ID_AUX_UNREF 13
#if MYNEWT_VAL(BLE_LL_SYSVIEW)
diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c
index f170000..3c407c5 100644
--- a/nimble/controller/src/ble_ll_conn.c
+++ b/nimble/controller/src/ble_ll_conn.c
@@ -842,7 +842,9 @@ ble_ll_conn_init_wfr_timer_exp(void)
scansm = connsm->scansm;
if (scansm && scansm->cur_aux_data) {
- ble_ll_scan_aux_data_free(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);
@@ -2931,6 +2933,18 @@ ble_ll_init_rx_pkt_in(uint8_t pdu_type, uint8_t *rxbuf,
uint8_t *adv_addr;
struct ble_ll_conn_sm *connsm;
int ext_adv_mode = -1;
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+ struct ble_ll_aux_data *aux_data = ble_hdr->rxinfo.user_data;
+
+ /*
+ * Let's take the reference for handover to LL.
+ * There shall be one more, if not something went very wrong
+ */
+ if (!ble_ll_scan_aux_data_unref(aux_data)) {
+ BLE_LL_ASSERT(0);
+ }
+
+#endif
/* Get the connection state machine we are trying to create */
connsm = g_ble_ll_conn_create_sm;
@@ -2946,13 +2960,14 @@ ble_ll_init_rx_pkt_in(uint8_t pdu_type, uint8_t *rxbuf,
if (BLE_MBUF_HDR_AUX_INVALID(ble_hdr)) {
goto scan_continue;
}
+
if (pdu_type == BLE_ADV_PDU_TYPE_ADV_EXT_IND) {
if (BLE_MBUF_HDR_WAIT_AUX(ble_hdr)) {
/* Just continue scanning. We are waiting for AUX */
- if (!ble_ll_sched_aux_scan(ble_hdr, connsm->scansm,
- ble_hdr->rxinfo.user_data)) {
- /* Wait for aux conn response */
- ble_hdr->rxinfo.user_data = NULL;
+ if (!ble_ll_sched_aux_scan(ble_hdr, connsm->scansm, aux_data)) {
+ ble_ll_scan_aux_data_ref(aux_data);
+ ble_ll_scan_chk_resume();
+ return;
}
goto scan_continue;
}
@@ -2963,7 +2978,6 @@ ble_ll_init_rx_pkt_in(uint8_t pdu_type, uint8_t *rxbuf,
if (pdu_type != BLE_ADV_PDU_TYPE_AUX_CONNECT_RSP) {
return;
}
- ble_ll_scan_aux_data_free(ble_hdr->rxinfo.user_data);
}
#endif
@@ -3028,6 +3042,7 @@ ble_ll_init_rx_pkt_in(uint8_t pdu_type, uint8_t *rxbuf,
/* Lets take last used phy */
ble_ll_conn_init_phy(connsm, ble_hdr->rxinfo.phy);
#endif
+ ble_ll_scan_aux_data_unref(aux_data);
#endif
ble_ll_conn_created(connsm, NULL);
return;
@@ -3035,7 +3050,8 @@ ble_ll_init_rx_pkt_in(uint8_t pdu_type, uint8_t *rxbuf,
scan_continue:
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
- ble_ll_scan_aux_data_free(ble_hdr->rxinfo.user_data);
+ /* Drop last reference and keep continue to connect */
+ ble_ll_scan_aux_data_unref(aux_data);
#endif
ble_ll_scan_chk_resume();
}
@@ -3177,16 +3193,22 @@ ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok,
/* Get connection state machine to use if connection to be established */
connsm = g_ble_ll_conn_create_sm;
-#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
- scansm = connsm->scansm;
- ble_hdr->rxinfo.user_data =scansm->cur_aux_data;
- scansm->cur_aux_data = NULL;
-#endif
-
rc = -1;
pdu_type = rxbuf[0] & BLE_ADV_PDU_HDR_TYPE_MASK;
pyld_len = rxbuf[1];
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+ scansm = connsm->scansm;
+ if (scansm->cur_aux_data) {
+ ble_hdr->rxinfo.user_data = scansm->cur_aux_data;
+ scansm->cur_aux_data = NULL;
+ if (ble_ll_scan_aux_data_unref(ble_hdr->rxinfo.user_data) == 0) {
+ ble_hdr->rxinfo.user_data = 0;
+ goto init_rx_isr_exit;
+ }
+ }
+#endif
+
if (!crcok) {
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
/* Invalid packet - make sure we do not wait for AUX_CONNECT_RSP */
@@ -3225,7 +3247,7 @@ ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok,
if (rc < 0) {
/* No memory or broken packet */
ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_AUX_INVALID;
- ble_ll_scan_aux_data_free(ble_hdr->rxinfo.user_data);
+ ble_ll_scan_aux_data_unref(ble_hdr->rxinfo.user_data);
ble_hdr->rxinfo.user_data = NULL;
goto init_rx_isr_exit;
}
@@ -3434,6 +3456,12 @@ ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok,
STATS_INC(ble_ll_conn_stats, conn_req_txd);
init_rx_isr_exit:
+
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+ if (ble_hdr->rxinfo.user_data) {
+ ble_ll_scan_aux_data_ref(ble_hdr->rxinfo.user_data);
+ }
+#endif
/*
* We have to restart receive if we cant hand up pdu. We return 0 so that
* the phy does not get disabled.
diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c
index 64e0152..e3996c4 100644
--- a/nimble/controller/src/ble_ll_scan.c
+++ b/nimble/controller/src/ble_ll_scan.c
@@ -38,6 +38,7 @@
#include "controller/ble_ll_whitelist.h"
#include "controller/ble_ll_resolv.h"
#include "controller/ble_ll_xcvr.h"
+#include "controller/ble_ll_trace.h"
#include "ble_ll_conn_priv.h"
/*
@@ -168,13 +169,13 @@ 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_free(sch->cb_arg);
+ ble_ll_scan_aux_data_unref(sch->cb_arg);
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_free(sch->cb_arg);
+ ble_ll_scan_aux_data_unref(sch->cb_arg);
goto done;
}
@@ -196,7 +197,7 @@ ble_ll_aux_scan_cb(struct ble_ll_sched_item *sch)
scansm->cur_aux_data->scanning = 1;
if (ble_ll_scan_start(scansm, sch)) {
- ble_ll_scan_aux_data_free(scansm->cur_aux_data);
+ ble_ll_scan_aux_data_unref(scansm->cur_aux_data);
scansm->cur_aux_data = NULL;
ble_ll_scan_chk_resume();
goto done;
@@ -226,6 +227,8 @@ ble_ll_scan_ext_adv_init(struct ble_ll_aux_data **aux_data)
e->sch.sched_cb = ble_ll_aux_scan_cb;
e->sch.cb_arg = e;
e->sch.sched_type = BLE_LL_SCHED_TYPE_AUX_SCAN;
+ e->ref_cnt = 1;
+ ble_ll_trace_u32x2(BLE_LL_TRACE_ID_AUX_REF, (uint32_t)e, e->ref_cnt);
*aux_data = e;
STATS_INC(ble_ll_stats, aux_allocated);
@@ -419,7 +422,7 @@ ble_ll_scan_clean_cur_aux_data(void)
/* If scanner was reading aux ptr, we need to clean it up */
if (scansm && scansm->cur_aux_data) {
- ble_ll_scan_aux_data_free(scansm->cur_aux_data);
+ ble_ll_scan_aux_data_unref(scansm->cur_aux_data);
scansm->cur_aux_data = NULL;
}
#endif
@@ -1114,6 +1117,59 @@ ble_ll_scan_window_chk(struct ble_ll_scan_sm *scansm, uint32_t cputime)
}
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
static void
+ble_ll_scan_aux_data_free(struct ble_ll_aux_data *aux_scan)
+{
+ if (aux_scan) {
+ if (aux_scan->evt) {
+ ble_hci_trans_buf_free((uint8_t *)aux_scan->evt);
+ aux_scan->evt = NULL;
+ }
+ os_memblock_put(&ext_adv_pool, aux_scan);
+ STATS_INC(ble_ll_stats, aux_freed);
+ }
+}
+
+void
+ble_ll_scan_aux_data_ref(struct ble_ll_aux_data *aux_data)
+{
+ os_sr_t sr;
+
+ if (!aux_data) {
+ return;
+ }
+
+ OS_ENTER_CRITICAL(sr);
+ aux_data->ref_cnt++;
+ ble_ll_trace_u32x2(BLE_LL_TRACE_ID_AUX_REF, (uint32_t) aux_data, aux_data->ref_cnt);
+
+ OS_EXIT_CRITICAL(sr);
+}
+
+int
+ble_ll_scan_aux_data_unref(struct ble_ll_aux_data *aux_data)
+{
+ os_sr_t sr;
+ int ret;
+
+ if (!aux_data) {
+ return 0;
+ }
+
+ OS_ENTER_CRITICAL(sr);
+ aux_data->ref_cnt--;
+ ret = aux_data->ref_cnt;
+ ble_ll_trace_u32x2(BLE_LL_TRACE_ID_AUX_UNREF, (uint32_t) aux_data, aux_data->ref_cnt);
+
+ if (aux_data->ref_cnt == 0) {
+ ble_ll_scan_aux_data_free(aux_data);
+ }
+
+ OS_EXIT_CRITICAL(sr);
+
+ return ret;
+}
+
+static void
ble_ll_scan_sched_remove(struct ble_ll_sched_item *sch)
{
ble_ll_scan_aux_data_free(sch->cb_arg);
@@ -2074,18 +2130,27 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
return 0;
}
+ rc = -1;
+
ble_hdr = BLE_MBUF_HDR_PTR(rxpdu);
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
- ble_hdr->rxinfo.user_data = scansm->cur_aux_data;
- scansm->cur_aux_data = NULL;
+ if (scansm->cur_aux_data) {
+ ble_hdr->rxinfo.user_data = scansm->cur_aux_data;
+ scansm->cur_aux_data = NULL;
+ if (ble_ll_scan_aux_data_unref(ble_hdr->rxinfo.user_data) == 0) {
+ ble_hdr->rxinfo.user_data = NULL;
+ ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_AUX_INVALID;
+ goto scan_rx_isr_exit;
+ }
+ }
#endif
/* Just leave if the CRC is not OK. */
- rc = -1;
if (!crcok) {
- ble_ll_scan_aux_data_free(ble_hdr->rxinfo.user_data);
- ble_hdr->rxinfo.user_data = NULL;
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+ ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_AUX_INVALID;
+#endif
goto scan_rx_isr_exit;
}
@@ -2111,10 +2176,6 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_AUX_PTR_WAIT;
}
- /* If the ble_ll_scan_get_aux_data() succeed, scansm->cur_aux_data is NULL
- * and aux_data contains correct data
- */
- BLE_LL_ASSERT(scansm->cur_aux_data == NULL);
rc = -1;
}
#endif
@@ -2227,6 +2288,7 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
if (ble_hdr->rxinfo.channel < BLE_PHY_NUM_DATA_CHANS) {
/* Let's keep the aux ptr as a reference to scan rsp */
scansm->cur_aux_data = ble_hdr->rxinfo.user_data;
+ ble_ll_scan_aux_data_ref(scansm->cur_aux_data);
STATS_INC(ble_ll_stats, aux_scan_req_tx);
}
#endif
@@ -2238,6 +2300,12 @@ scan_rx_isr_exit:
if (rc) {
ble_ll_state_set(BLE_LL_STATE_STANDBY);
}
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+ /* On handover lets increase ref count */
+ if (ble_hdr->rxinfo.user_data) {
+ ble_ll_scan_aux_data_ref(ble_hdr->rxinfo.user_data);
+ }
+#endif
return rc;
}
@@ -2318,7 +2386,7 @@ ble_ll_scan_wfr_timer_exp(void)
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
if (scansm->cur_aux_data) {
/*TODO handle chain incomplete, data truncated */
- ble_ll_scan_aux_data_free(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_scan_chk_resume();
@@ -2329,18 +2397,6 @@ ble_ll_scan_wfr_timer_exp(void)
}
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
-void
-ble_ll_scan_aux_data_free(struct ble_ll_aux_data *aux_scan)
-{
- if (aux_scan) {
- if (aux_scan->evt) {
- ble_hci_trans_buf_free((uint8_t *)aux_scan->evt);
- }
- os_memblock_put(&ext_adv_pool, aux_scan);
- STATS_INC(ble_ll_stats, aux_freed);
- }
-}
-
/*
* Send extended advertising report
*
@@ -2364,7 +2420,8 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, uint8_t *adva, uint8_t adva_type,
uint8_t max_event_len;
if (!ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_EXT_ADV_RPT)) {
- return -1;
+ rc = -1;
+ goto done;
}
/*
@@ -2378,7 +2435,8 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, uint8_t *adva, uint8_t adva_type,
} else {
evt = ble_ll_scan_init_ext_adv_report(NULL);
if (!evt) {
- return -1;
+ rc = -1;
+ goto done;
}
}
@@ -2386,7 +2444,8 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, uint8_t *adva, uint8_t adva_type,
if (datalen < 0) {
/* XXX what should we do here? send some trimmed event? */
ble_hci_trans_buf_free((uint8_t *)evt);
- return -1;
+ rc = -1;
+ goto done;
}
offset = 0;
@@ -2460,6 +2519,12 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, uint8_t *adva, uint8_t adva_type,
BLE_LL_ASSERT(!evt);
}
+done:
+ /* If advertising event is completed or failed, we can drop the reference */
+ if (rc <= 0) {
+ ble_ll_scan_aux_data_unref(aux_data);
+ }
+
return rc;
}
#endif
@@ -2542,6 +2607,9 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd
if (ble_ll_scan_chk_filter_policy(ptype, adv_addr, txadd, init_addr,
init_addr_type,
BLE_MBUF_HDR_DEVMATCH(hdr))) {
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+ ble_ll_scan_aux_data_unref(aux_data);
+#endif
goto scan_continue;
}
@@ -2582,6 +2650,11 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd
/* Filter duplicates */
if (scansm->scan_filt_dups) {
if (ble_ll_scan_is_dup_adv(ptype, ident_addr_type, ident_addr)) {
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+ if (ptype == BLE_ADV_PDU_TYPE_ADV_EXT_IND) {
+ ble_ll_scan_aux_data_unref(aux_data);
+ }
+#endif
goto scan_continue;
}
}
@@ -2589,6 +2662,7 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
if (ptype == BLE_ADV_PDU_TYPE_ADV_EXT_IND) {
if (!scansm->ext_scanning) {
+ ble_ll_scan_aux_data_unref(aux_data);
goto scan_continue;
}
@@ -2596,8 +2670,9 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd
goto scan_continue;
}
-
+ /* If it is ignore it means event is already truncated, just unref aux */
if (aux_data && BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_IGNORE_BIT)) {
+ ble_ll_scan_aux_data_unref(aux_data);
goto scan_continue;
}
@@ -2609,13 +2684,22 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd
hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_AUX_PTR_WAIT;
/* Mark that chain is trimmed */
aux_data->flags |= BLE_LL_AUX_INCOMPLETE_ERR_BIT;
+ /* Note: aux_data unref will be done when truncated is sent to the host or
+ * below if we failed to schedule for the very first aux packet.
+ */
+ } else {
+ /* We are here because successfully scheduled for next aux */
+ ble_ll_scan_aux_data_ref(aux_data);
}
+ /*
+ * If this is ext adv, there is nothing to do here but just leave and wait
+ * for aux packet. However, if we was not able to schedule for first aux packet,
+ * make sure to unref aux_data here
+ */
if (!BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_CHAIN_BIT)) {
- /* This is just beacon. Let's wait for more data */
- if (BLE_MBUF_HDR_WAIT_AUX(hdr)) {
- /* If scheduled for aux let's don't remove aux data */
- hdr->rxinfo.user_data = NULL;
+ if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_INCOMPLETE_ERR_BIT)) {
+ ble_ll_scan_aux_data_unref(aux_data);
}
goto scan_continue;
}
@@ -2623,6 +2707,8 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd
STATS_INC(ble_ll_stats, aux_chain_cnt);
}
+ /* For the time when sending events up, lets increase ref count */
+ ble_ll_scan_aux_data_ref(aux_data);
rc = ble_ll_hci_send_ext_adv_report(ptype, ident_addr, ident_addr_type,
init_addr, init_addr_type, om, hdr);
if (rc < 0) {
@@ -2631,19 +2717,25 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd
* make sure we do not send any more events for this chain, just in
* case we managed to scan something before events were processed.
*/
- ble_ll_sched_rmv_elem(&aux_data->sch);
- hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_AUX_PTR_WAIT;
+ if (BLE_MBUF_HDR_WAIT_AUX(hdr)) {
+ hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_AUX_PTR_WAIT;
+ if (ble_ll_sched_rmv_elem(&aux_data->sch) == 0) {
+ ble_ll_scan_aux_data_unref(aux_data);
+ }
+ }
aux_data->flags |= BLE_LL_AUX_IGNORE_BIT;
}
- ble_ll_scan_switch_phy(scansm);
+ ble_ll_scan_aux_data_unref(aux_data);
- if (BLE_MBUF_HDR_WAIT_AUX(hdr)) {
- /* If scheduled for aux let's don't remove aux data */
- hdr->rxinfo.user_data = NULL;
- }
+ ble_ll_scan_switch_phy(scansm);
if (scansm->scan_rsp_pending) {
if (!scan_rsp_chk) {
+ /* We are here because we sent SCAN_REQ and wait for SCAN_RSP.
+ * We do not drop reference here by purpose, because
+ * it was already dropped in ble_ll_hci_send_ext_adv_report() as
+ * very first advertising report for scannable report is "completed"
+ */
return;
}
@@ -2661,7 +2753,10 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd
scan_continue:
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
- ble_ll_scan_aux_data_free(hdr->rxinfo.user_data);
+ if (aux_data) {
+ /* This is ref for handover to LL */
+ ble_ll_scan_aux_data_unref(aux_data);
+ }
#endif
/*
* If the scan response check bit is set and we are pending a response,
diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c
index 04e630c..9a22ede 100644
--- a/nimble/controller/src/ble_ll_sched.c
+++ b/nimble/controller/src/ble_ll_sched.c
@@ -250,7 +250,7 @@ ble_ll_sched_conn_reschedule(struct ble_ll_conn_sm *connsm)
break;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
case BLE_LL_SCHED_TYPE_AUX_SCAN:
- ble_ll_scan_aux_data_free((struct ble_ll_aux_data *)
+ ble_ll_scan_aux_data_unref((struct ble_ll_aux_data *)
entry->cb_arg);
break;
#endif
@@ -1361,7 +1361,7 @@ ble_ll_sched_scan_req_over_aux_ptr(uint32_t chan, uint8_t phy_mode)
return 1;
}
- ble_ll_scan_aux_data_free((struct ble_ll_aux_data *)sch->cb_arg);
+ ble_ll_scan_aux_data_unref((struct ble_ll_aux_data *)sch->cb_arg);
TAILQ_REMOVE(&g_ble_ll_sched_q, sch, link);
sch->enqueued = 0;
sch = TAILQ_FIRST(&g_ble_ll_sched_q);
diff --git a/nimble/controller/src/ble_ll_trace.c b/nimble/controller/src/ble_ll_trace.c
index bdea2bf..330b3d4 100644
--- a/nimble/controller/src/ble_ll_trace.c
+++ b/nimble/controller/src/ble_ll_trace.c
@@ -41,6 +41,8 @@ ble_ll_trace_module_send_desc(void)
os_trace_module_desc(&g_ble_ll_trace_mod, "9 ll_conn_rx conn_sn=%u pdu_nesn=%u");
os_trace_module_desc(&g_ble_ll_trace_mod, "10 ll_adv_txdone inst=%u chanset=%x");
os_trace_module_desc(&g_ble_ll_trace_mod, "11 ll_adv_halt inst=%u");
+ os_trace_module_desc(&g_ble_ll_trace_mod, "12 ll_aux_ref aux=%p ref=%u");
+ os_trace_module_desc(&g_ble_ll_trace_mod, "13 ll_aux_unref aux=%p ref=%u");
}
void