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:05 UTC

[mynewt-nimble] branch master updated (654b7d1 -> 859cb35)

This is an automated email from the ASF dual-hosted git repository.

rymek pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-nimble.git.


    from 654b7d1  ble_ll_dtm.c: Add missing #include
     new 1ecfded  nimble/ll: Check privacy mode on Connect Ind receive
     new 21c809b  nimble/ll: Fix parsing aux_ptr
     new 665f079  nimble/ll: Improve getting advertising and target address
     new e945b59  nimble/ll: Improve getting aux data
     new 549f8ad  nimble/ll: Make sure hci event size
     new e6a63e3  nimble/ll: Remove evt reference from aux_data
     new 23f7091  nimble/ll: Fix possible null pointer dereference
     new 83cc4e5  nimble/ll: Fix handling HCI Le Set Advertising Data command
     new c2a36eb  nimble/ll: Keep connecting in case of error when decoding address
     new 3551e30  nimble/ll: Some additional aux_data stats
     new f709097  nimble/ll: Add return value to ble_ll_sched_rmv_elem
     new 2df0d01  nimble/ll: Extended scanner - add ref count for aux data
     new 859cb35  nimble/ll: Improve handling truncated advertising events

The 13 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 nimble/controller/include/controller/ble_ll.h      |   3 +
 nimble/controller/include/controller/ble_ll_scan.h |  11 +-
 .../controller/include/controller/ble_ll_sched.h   |   2 +-
 .../controller/include/controller/ble_ll_trace.h   |   2 +
 nimble/controller/src/ble_ll.c                     |   3 +
 nimble/controller/src/ble_ll_adv.c                 |  32 +-
 nimble/controller/src/ble_ll_conn.c                |  66 ++-
 nimble/controller/src/ble_ll_hci.c                 |   1 +
 nimble/controller/src/ble_ll_scan.c                | 537 ++++++++++++++-------
 nimble/controller/src/ble_ll_sched.c               |  15 +-
 nimble/controller/src/ble_ll_trace.c               |   2 +
 11 files changed, 470 insertions(+), 204 deletions(-)


[mynewt-nimble] 08/13: nimble/ll: Fix handling HCI Le Set Advertising Data command

Posted by ry...@apache.org.
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 83cc4e5b2f887ba60e4d199b14a16b8f12afe89b
Author: Łukasz Rymanowski <lu...@codecoup.pl>
AuthorDate: Tue Nov 13 09:17:15 2018 +0100

    nimble/ll: Fix handling HCI Le Set Advertising Data command
    
    When extended advertising mode is used, Controller shall send Command
    Status with Error Command Disallowed (0x0c) on HCI Le Set Advertising
    data command.
    
    It fixes HCI/GEV/BV-02-C
---
 nimble/controller/src/ble_ll_hci.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/nimble/controller/src/ble_ll_hci.c b/nimble/controller/src/ble_ll_hci.c
index 07f520b..95dd16e 100644
--- a/nimble/controller/src/ble_ll_hci.c
+++ b/nimble/controller/src/ble_ll_hci.c
@@ -671,6 +671,7 @@ ble_ll_is_valid_adv_mode(uint8_t ocf)
     case BLE_HCI_OCF_LE_CREATE_CONN:
     case BLE_HCI_OCF_LE_SET_ADV_PARAMS:
     case BLE_HCI_OCF_LE_SET_ADV_ENABLE:
+    case BLE_HCI_OCF_LE_SET_ADV_DATA:
     case BLE_HCI_OCF_LE_SET_SCAN_PARAMS:
     case BLE_HCI_OCF_LE_SET_SCAN_ENABLE:
     case BLE_HCI_OCF_LE_SET_SCAN_RSP_DATA:


[mynewt-nimble] 01/13: nimble/ll: Check privacy mode on Connect Ind receive

Posted by ry...@apache.org.
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 1ecfded31250c837936413915b52053258512a9c
Author: Łukasz Rymanowski <lu...@codecoup.pl>
AuthorDate: Thu Oct 18 23:21:09 2018 +0200

    nimble/ll: Check privacy mode on Connect Ind receive
    
    This should fix: LL/SEC/ADV/BV-16-C
---
 nimble/controller/src/ble_ll_adv.c | 32 +++++++++++++++++++++++---------
 1 file changed, 23 insertions(+), 9 deletions(-)

diff --git a/nimble/controller/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c
index e0307bd..bae72cc 100644
--- a/nimble/controller/src/ble_ll_adv.c
+++ b/nimble/controller/src/ble_ll_adv.c
@@ -2628,6 +2628,9 @@ ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu)
 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
     struct aux_conn_rsp_data rsp_data;
 #endif
+#if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
+    struct ble_ll_resolv_entry *rl;
+#endif
 
     /* See if adva in the request (scan or connect) matches what we sent */
     advsm = g_ble_ll_cur_adv_sm;
@@ -2657,17 +2660,28 @@ ble_ll_adv_rx_req(uint8_t pdu_type, struct os_mbuf *rxpdu)
     resolved = 0;
 
 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
-    if (ble_ll_is_rpa(peer, txadd) && ble_ll_resolv_enabled()) {
-        advsm->adv_rpa_index = ble_hw_resolv_list_match();
-        if (advsm->adv_rpa_index >= 0) {
-            ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_RESOLVED;
-            if (chk_wl) {
-                peer = g_ble_ll_resolv_list[advsm->adv_rpa_index].rl_identity_addr;
-                peer_addr_type = g_ble_ll_resolv_list[advsm->adv_rpa_index].rl_addr_type;
-                resolved = 1;
+    rl = NULL;
+    if (ble_ll_resolv_enabled()) {
+        if (ble_ll_is_rpa(peer, txadd)) {
+            advsm->adv_rpa_index = ble_hw_resolv_list_match();
+            if (advsm->adv_rpa_index >= 0) {
+                ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_RESOLVED;
+                rl = &g_ble_ll_resolv_list[advsm->adv_rpa_index];
+                if (chk_wl) {
+                    peer = rl->rl_identity_addr;
+                    peer_addr_type = rl->rl_addr_type;
+                    resolved = 1;
+                }
+            } else {
+                if (chk_wl) {
+                    return -1;
+                }
             }
         } else {
-            if (chk_wl) {
+            /* Verify privacy mode */
+            rl = ble_ll_resolv_list_find(peer, peer_addr_type);
+            if (rl && (rl->rl_priv_mode == BLE_HCI_PRIVACY_NETWORK) &&
+                                ble_ll_resolv_irk_nonzero(rl->rl_peer_irk)) {
                 return -1;
             }
         }


[mynewt-nimble] 12/13: nimble/ll: Extended scanner - add ref count for aux data

Posted by ry...@apache.org.
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


[mynewt-nimble] 02/13: nimble/ll: Fix parsing aux_ptr

Posted by ry...@apache.org.
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 21c809bc7407a80a7038c1c165c14e3f06cd4faf
Author: Łukasz Rymanowski <lu...@codecoup.pl>
AuthorDate: Mon Nov 5 15:30:49 2018 +0100

    nimble/ll: Fix parsing aux_ptr
    
    With this patch we make sure that when parsing aux ptr we store
    advertiser and target address.
---
 nimble/controller/src/ble_ll_scan.c | 59 ++++++++++++++++++++++++-------------
 1 file changed, 39 insertions(+), 20 deletions(-)

diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c
index 7823478..2dd9caa 100644
--- a/nimble/controller/src/ble_ll_scan.c
+++ b/nimble/controller/src/ble_ll_scan.c
@@ -1640,6 +1640,7 @@ ble_ll_scan_get_aux_data(struct ble_ll_scan_sm *scansm,
     uint8_t has_adi = 0;
     int i;
     struct ble_ll_aux_data tmp_aux_data = { 0 };
+    int rc;
 
     pdu_len = rxbuf[1];
     if (pdu_len == 0) {
@@ -1706,6 +1707,7 @@ ble_ll_scan_get_aux_data(struct ble_ll_scan_sm *scansm,
             (*aux_data)->flags |= BLE_LL_AUX_CHAIN_BIT;
             (*aux_data)->flags |= BLE_LL_AUX_INCOMPLETE_BIT;
         } else if (ble_ll_scan_ext_adv_init(aux_data) < 0) {
+            /* Out of memory */
             return -1;
         }
 
@@ -1719,34 +1721,51 @@ ble_ll_scan_get_aux_data(struct ble_ll_scan_sm *scansm,
             scansm->cur_aux_data = NULL;
         }
 
-        if (has_adi) {
-            (*aux_data)->adi = tmp_aux_data.adi;
-        }
-
         (*aux_data)->chan = tmp_aux_data.chan;
         (*aux_data)->offset = tmp_aux_data.offset;
         (*aux_data)->mode = tmp_aux_data.mode;
-        if (has_addr) {
-            memcpy((*aux_data)->addr, tmp_aux_data.addr, 6);
-            (*aux_data)->addr_type = tmp_aux_data.addr_type;
-            (*aux_data)->flags |= BLE_LL_AUX_HAS_ADDRA;
-        }
-        if (has_dir_addr) {
-            memcpy((*aux_data)->dir_addr, tmp_aux_data.dir_addr, 6);
-            (*aux_data)->dir_addr_type = tmp_aux_data.dir_addr_type;
-            (*aux_data)->flags |= BLE_LL_AUX_HAS_DIR_ADDRA;
+
+        /* New aux_data or chaining */
+        rc = 0;
+    } else {
+
+        /* So ext packet does not have aux ptr. It can be because
+         * a) it is empty beacon (no aux ptr at all)
+         * b) there is no chaining or chaining has just stopped. In this case we do hava aux_data */
+
+        if (!scansm->cur_aux_data) {
+            (*aux_data) = NULL;
+            return 1;
         }
-        return 0;
+
+        /*If there is no new aux ptr, just get current one */
+        (*aux_data) = scansm->cur_aux_data;
+        scansm->cur_aux_data = NULL;
+
+        /* Clear incomplete flag */
+        (*aux_data)->flags &= ~BLE_LL_AUX_INCOMPLETE_BIT;
+
+        /* Current processing aux_ptr */
+        rc = 1;
     }
 
-    /*If there is no new aux ptr, just get current one */
-    (*aux_data) = scansm->cur_aux_data;
-    scansm->cur_aux_data = NULL;
+    if (has_adi) {
+         (*aux_data)->adi = tmp_aux_data.adi;
+    }
 
-    /* Clear incomplete flag */
-    (*aux_data)->flags &= ~BLE_LL_AUX_INCOMPLETE_BIT;
+    if (has_addr) {
+        memcpy((*aux_data)->addr, tmp_aux_data.addr, 6);
+        (*aux_data)->addr_type = tmp_aux_data.addr_type;
+        (*aux_data)->flags |= BLE_LL_AUX_HAS_ADDRA;
+    }
 
-    return 1;
+    if (has_dir_addr) {
+        memcpy((*aux_data)->dir_addr, tmp_aux_data.dir_addr, 6);
+        (*aux_data)->dir_addr_type = tmp_aux_data.dir_addr_type;
+        (*aux_data)->flags |= BLE_LL_AUX_HAS_DIR_ADDRA;
+    }
+
+    return rc;
 }
 /**
  * Called when a receive ADV_EXT PDU has ended.


[mynewt-nimble] 06/13: nimble/ll: Remove evt reference from aux_data

Posted by ry...@apache.org.
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 e6a63e3cefff3e3003ed549ba81240470aa154df
Author: Łukasz Rymanowski <lu...@codecoup.pl>
AuthorDate: Fri Nov 9 10:32:08 2018 +0100

    nimble/ll: Remove evt reference from aux_data
    
    Once aux_data->evt is taken, remove reference to it from aux_data as it
    is not needed.
---
 nimble/controller/src/ble_ll_scan.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c
index 402dbd8..8b9d270 100644
--- a/nimble/controller/src/ble_ll_scan.c
+++ b/nimble/controller/src/ble_ll_scan.c
@@ -2370,6 +2370,7 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, uint8_t *adva, uint8_t adva_type,
      */
     if (aux_data && aux_data->evt) {
         evt = aux_data->evt;
+        aux_data->evt = NULL;
     } else {
         evt = ble_ll_scan_init_ext_adv_report(NULL);
         if (!evt) {


[mynewt-nimble] 04/13: nimble/ll: Improve getting aux data

Posted by ry...@apache.org.
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 e945b59b8457bcc44042ace8e2d3032415115a80
Author: Łukasz Rymanowski <lu...@codecoup.pl>
AuthorDate: Sun Nov 4 01:06:37 2018 +0100

    nimble/ll: Improve getting aux data
    
    This patch simplify getting aux data so it is easier to follow the code.
    Also, in this patch aux_data is attached to ble_hdr of the received
    packet at the very beginning of isr_end and removed from global scan
    machine.
---
 nimble/controller/include/controller/ble_ll_scan.h |  4 +-
 nimble/controller/src/ble_ll_conn.c                | 11 +--
 nimble/controller/src/ble_ll_scan.c                | 87 ++++++++++------------
 3 files changed, 46 insertions(+), 56 deletions(-)

diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h
index 5aa5234..98246fb 100644
--- a/nimble/controller/include/controller/ble_ll_scan.h
+++ b/nimble/controller/include/controller/ble_ll_scan.h
@@ -230,9 +230,7 @@ int ble_ll_scan_adv_decode_addr(uint8_t pdu_type, uint8_t *rxbuf,
 
 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
 /* Get aux ptr from ext advertising */
-int ble_ll_scan_get_aux_data(struct ble_ll_scan_sm *scansm,
-                             struct ble_mbuf_hdr *ble_hdr, uint8_t *rxbuf,
-                             struct ble_ll_aux_data **aux_data);
+int ble_ll_scan_get_aux_data(struct ble_mbuf_hdr *ble_hdr, uint8_t *rxbuf);
 
 /* Initialize the extended scanner when we start initiating */
 struct hci_ext_create_conn;
diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c
index 26090e5..cdeff55 100644
--- a/nimble/controller/src/ble_ll_conn.c
+++ b/nimble/controller/src/ble_ll_conn.c
@@ -3170,7 +3170,6 @@ ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok,
 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
     struct ble_ll_scan_sm *scansm;
     uint8_t phy;
-    struct ble_ll_aux_data *aux_data = NULL;
 #endif
     int ext_adv_mode = -1;
 
@@ -3180,6 +3179,7 @@ ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok,
 #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;
@@ -3190,7 +3190,6 @@ ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok,
 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
         /* Invalid packet - make sure we do not wait for AUX_CONNECT_RSP */
         ble_ll_conn_reset_pending_aux_conn_rsp();
-        scansm->cur_aux_data = NULL;
 #endif
 
         /* Ignore this packet */
@@ -3221,16 +3220,14 @@ ble_ll_init_rx_isr_end(uint8_t *rxbuf, uint8_t crcok,
             goto init_rx_isr_exit;
         }
 
-        rc = ble_ll_scan_get_aux_data(scansm, ble_hdr, rxbuf, &aux_data);
+        rc = ble_ll_scan_get_aux_data(ble_hdr, rxbuf);
         if (rc < 0) {
             /* No memory or broken packet */
             ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_AUX_INVALID;
-            ble_ll_scan_aux_data_free(scansm->cur_aux_data);
-            scansm->cur_aux_data = NULL;
+            ble_ll_scan_aux_data_free(ble_hdr->rxinfo.user_data);
+            ble_hdr->rxinfo.user_data = NULL;
             goto init_rx_isr_exit;
         }
-
-        ble_hdr->rxinfo.user_data = aux_data;
     }
 #endif
 
diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c
index ebef10b..2eeba78 100644
--- a/nimble/controller/src/ble_ll_scan.c
+++ b/nimble/controller/src/ble_ll_scan.c
@@ -1565,8 +1565,7 @@ ble_ll_ext_adv_phy_mode_to_local_phy(uint8_t adv_phy_mode)
 }
 
 static int
-ble_ll_ext_scan_parse_aux_ptr(struct ble_ll_scan_sm *scansm,
-                              struct ble_ll_aux_data *aux_data, uint8_t *buf)
+ble_ll_ext_scan_parse_aux_ptr(struct ble_ll_aux_data *aux_data, uint8_t *buf)
 {
     uint32_t aux_ptr_field = get_le32(buf) & 0x00FFFFFF;
 
@@ -1612,7 +1611,7 @@ ble_ll_ext_scan_parse_adv_info(struct ble_ll_scan_sm *scansm,
  * ble_ll_scan_get_aux_data
  *
  * Get aux data pointer. It is new allocated data for beacon or currently
- * processing aux data pointer
+ * processing aux data pointer. Aux data pointer will be attached to ble_hdr.rxinfo.user_data
  *
  * Context: Interrupt
  *
@@ -1627,9 +1626,7 @@ ble_ll_ext_scan_parse_adv_info(struct ble_ll_scan_sm *scansm,
  * -1: error
  */
 int
-ble_ll_scan_get_aux_data(struct ble_ll_scan_sm *scansm,
-                         struct ble_mbuf_hdr *ble_hdr, uint8_t *rxbuf,
-                         struct ble_ll_aux_data **aux_data)
+ble_ll_scan_get_aux_data(struct ble_mbuf_hdr *ble_hdr, uint8_t *rxbuf)
 {
     uint8_t ext_hdr_len;
     uint8_t pdu_len;
@@ -1639,6 +1636,8 @@ ble_ll_scan_get_aux_data(struct ble_ll_scan_sm *scansm,
     uint8_t has_dir_addr = 0;
     uint8_t has_adi = 0;
     int i;
+    struct ble_ll_aux_data *current_aux = ble_hdr->rxinfo.user_data;
+    struct ble_ll_aux_data *new_aux = NULL;
     struct ble_ll_aux_data tmp_aux_data = { 0 };
     int rc;
 
@@ -1650,7 +1649,7 @@ ble_ll_scan_get_aux_data(struct ble_ll_scan_sm *scansm,
     tmp_aux_data.mode = rxbuf[2] >> 6;
 
     ext_hdr_len = rxbuf[2] & 0x3F;
-    if (ext_hdr_len < BLE_LL_EXT_ADV_AUX_PTR_SIZE && !scansm->cur_aux_data) {
+    if (ext_hdr_len < BLE_LL_EXT_ADV_AUX_PTR_SIZE && !ble_hdr->rxinfo.user_data) {
         return -1;
     }
 
@@ -1687,43 +1686,42 @@ ble_ll_scan_get_aux_data(struct ble_ll_scan_sm *scansm,
 
     if (ext_hdr_flags & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) {
 
-        if (ble_ll_ext_scan_parse_aux_ptr(scansm, &tmp_aux_data, ext_hdr + i) < 0) {
+        if (ble_ll_ext_scan_parse_aux_ptr(&tmp_aux_data, ext_hdr + i) < 0) {
             return -1;
         }
 
-        if (scansm->cur_aux_data) {
+        if (current_aux) {
             /* If we are here that means there is chain advertising. */
 
             /* Lets reuse old aux_data */
-            *aux_data = scansm->cur_aux_data;
+            new_aux = current_aux;
 
             /* TODO Collision; Do smth smart when did does not match */
-            if (!((*aux_data)->evt_type & (BLE_HCI_ADV_SCAN_MASK))
-                            && (tmp_aux_data.adi != (*aux_data)->adi)) {
+            if (!(new_aux->evt_type & (BLE_HCI_ADV_SCAN_MASK))
+                            && (tmp_aux_data.adi != new_aux->adi)) {
                 STATS_INC(ble_ll_stats, aux_chain_err);
-                (*aux_data)->flags |= BLE_LL_AUX_INCOMPLETE_ERR_BIT;
+                new_aux->flags |= BLE_LL_AUX_INCOMPLETE_ERR_BIT;
             }
 
-            (*aux_data)->flags |= BLE_LL_AUX_CHAIN_BIT;
-            (*aux_data)->flags |= BLE_LL_AUX_INCOMPLETE_BIT;
-        } else if (ble_ll_scan_ext_adv_init(aux_data) < 0) {
+            new_aux->flags |= BLE_LL_AUX_CHAIN_BIT;
+            new_aux->flags |= BLE_LL_AUX_INCOMPLETE_BIT;
+        } else {
+            if (ble_ll_scan_ext_adv_init(&new_aux) < 0) {
             /* Out of memory */
             return -1;
+            }
         }
 
-        (*aux_data)->aux_phy = tmp_aux_data.aux_phy;
+        new_aux->aux_phy = tmp_aux_data.aux_phy;
 
-        if (!scansm->cur_aux_data) {
+        if (!current_aux) {
             /* Only for first ext adv we want to keep primary phy.*/
-            (*aux_data)->aux_primary_phy = ble_hdr->rxinfo.phy;
-        } else {
-            /* We are ok to clear cur_aux_data now. */
-            scansm->cur_aux_data = NULL;
+            new_aux->aux_primary_phy = ble_hdr->rxinfo.phy;
         }
 
-        (*aux_data)->chan = tmp_aux_data.chan;
-        (*aux_data)->offset = tmp_aux_data.offset;
-        (*aux_data)->mode = tmp_aux_data.mode;
+        new_aux->chan = tmp_aux_data.chan;
+        new_aux->offset = tmp_aux_data.offset;
+        new_aux->mode = tmp_aux_data.mode;
 
         /* New aux_data or chaining */
         rc = 0;
@@ -1733,38 +1731,39 @@ ble_ll_scan_get_aux_data(struct ble_ll_scan_sm *scansm,
          * a) it is empty beacon (no aux ptr at all)
          * b) there is no chaining or chaining has just stopped. In this case we do hava aux_data */
 
-        if (!scansm->cur_aux_data) {
-            (*aux_data) = NULL;
+        if (!current_aux) {
+            new_aux = NULL;
             return 1;
         }
 
         /*If there is no new aux ptr, just get current one */
-        (*aux_data) = scansm->cur_aux_data;
-        scansm->cur_aux_data = NULL;
+        new_aux = ble_hdr->rxinfo.user_data;
 
         /* Clear incomplete flag */
-        (*aux_data)->flags &= ~BLE_LL_AUX_INCOMPLETE_BIT;
+        new_aux->flags &= ~BLE_LL_AUX_INCOMPLETE_BIT;
 
         /* Current processing aux_ptr */
         rc = 1;
     }
 
     if (has_adi) {
-         (*aux_data)->adi = tmp_aux_data.adi;
+        new_aux->adi = tmp_aux_data.adi;
     }
 
     if (has_addr) {
-        memcpy((*aux_data)->addr, tmp_aux_data.addr, 6);
-        (*aux_data)->addr_type = tmp_aux_data.addr_type;
-        (*aux_data)->flags |= BLE_LL_AUX_HAS_ADDRA;
+        memcpy(new_aux->addr, tmp_aux_data.addr, 6);
+        new_aux->addr_type = tmp_aux_data.addr_type;
+        new_aux->flags |= BLE_LL_AUX_HAS_ADDRA;
     }
 
     if (has_dir_addr) {
-        memcpy((*aux_data)->dir_addr, tmp_aux_data.dir_addr, 6);
-        (*aux_data)->dir_addr_type = tmp_aux_data.dir_addr_type;
-        (*aux_data)->flags |= BLE_LL_AUX_HAS_DIR_ADDRA;
+        memcpy(new_aux->dir_addr, tmp_aux_data.dir_addr, 6);
+        new_aux->dir_addr_type = tmp_aux_data.dir_addr_type;
+        new_aux->flags |= BLE_LL_AUX_HAS_DIR_ADDRA;
     }
 
+    ble_hdr->rxinfo.user_data = new_aux;
+
     return rc;
 }
 /**
@@ -2048,7 +2047,6 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
     struct ble_ll_scan_params *scanphy;
     int ext_adv_mode = -1;
 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
-    struct ble_ll_aux_data *aux_data = NULL;
     uint8_t phy_mode;
 #endif
 
@@ -2077,12 +2075,14 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
 
 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
     ble_hdr->rxinfo.user_data = scansm->cur_aux_data;
+    scansm->cur_aux_data = NULL;
 #endif
 
     /* Just leave if the CRC is not OK. */
     rc = -1;
     if (!crcok) {
-        scansm->cur_aux_data = NULL;
+        ble_ll_scan_aux_data_free(ble_hdr->rxinfo.user_data);
+        ble_hdr->rxinfo.user_data = NULL;
         goto scan_rx_isr_exit;
     }
 
@@ -2096,13 +2096,10 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
             goto scan_rx_isr_exit;
         }
         /* Create new aux data for beacon or get current processing aux ptr */
-        rc = ble_ll_scan_get_aux_data(scansm, ble_hdr, rxbuf, &aux_data);
+        rc = ble_ll_scan_get_aux_data(ble_hdr, rxbuf);
         if (rc < 0) {
             /* No memory or broken packet */
             ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_AUX_INVALID;
-            /* cur_aux_data is already in the ble_hdr->rxinfo.user_data and
-             * will be taken care by LL task */
-            scansm->cur_aux_data = NULL;
 
             goto scan_rx_isr_exit;
         }
@@ -2115,7 +2112,6 @@ ble_ll_scan_rx_isr_end(struct os_mbuf *rxpdu, uint8_t crcok)
          * and aux_data contains correct data
          */
         BLE_LL_ASSERT(scansm->cur_aux_data == NULL);
-        ble_hdr->rxinfo.user_data = aux_data;
         rc = -1;
     }
 #endif
@@ -2484,7 +2480,7 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd
     struct ble_mbuf_hdr *ble_hdr;
     int ext_adv_mode = -1;
 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
-    struct ble_ll_aux_data *aux_data;
+    struct ble_ll_aux_data *aux_data = hdr->rxinfo.user_data;
     int rc;
 #endif
 
@@ -2588,7 +2584,6 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd
             goto scan_continue;
         }
 
-        aux_data = hdr->rxinfo.user_data;
 
         if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_IGNORE_BIT)) {
             goto scan_continue;


[mynewt-nimble] 10/13: nimble/ll: Some additional aux_data stats

Posted by ry...@apache.org.
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 3551e30949dcb598b7fbec69bce86d38fd9c8c5a
Author: Łukasz Rymanowski <lu...@codecoup.pl>
AuthorDate: Fri Nov 16 16:15:00 2018 +0100

    nimble/ll: Some additional aux_data stats
---
 nimble/controller/include/controller/ble_ll.h | 3 +++
 nimble/controller/src/ble_ll.c                | 3 +++
 nimble/controller/src/ble_ll_scan.c           | 4 ++++
 3 files changed, 10 insertions(+)

diff --git a/nimble/controller/include/controller/ble_ll.h b/nimble/controller/include/controller/ble_ll.h
index 6d86e37..36685fd 100644
--- a/nimble/controller/include/controller/ble_ll.h
+++ b/nimble/controller/include/controller/ble_ll.h
@@ -189,6 +189,9 @@ STATS_SECT_START(ble_ll_stats)
     STATS_SECT_ENTRY(aux_scheduled)
     STATS_SECT_ENTRY(aux_received)
     STATS_SECT_ENTRY(aux_fired_for_read)
+    STATS_SECT_ENTRY(aux_allocated)
+    STATS_SECT_ENTRY(aux_freed)
+    STATS_SECT_ENTRY(aux_sched_cb)
     STATS_SECT_ENTRY(aux_conn_req_tx)
     STATS_SECT_ENTRY(aux_conn_rsp_tx)
     STATS_SECT_ENTRY(aux_conn_rsp_err)
diff --git a/nimble/controller/src/ble_ll.c b/nimble/controller/src/ble_ll.c
index 50e1749..a2b59ef 100644
--- a/nimble/controller/src/ble_ll.c
+++ b/nimble/controller/src/ble_ll.c
@@ -194,6 +194,9 @@ STATS_NAME_START(ble_ll_stats)
     STATS_NAME(ble_ll_stats, aux_scheduled)
     STATS_NAME(ble_ll_stats, aux_received)
     STATS_NAME(ble_ll_stats, aux_fired_for_read)
+    STATS_NAME(ble_ll_stats, aux_allocated)
+    STATS_NAME(ble_ll_stats, aux_freed)
+    STATS_NAME(ble_ll_stats, aux_sched_cb)
     STATS_NAME(ble_ll_stats, aux_conn_req_tx)
     STATS_NAME(ble_ll_stats, aux_conn_rsp_tx)
     STATS_NAME(ble_ll_stats, aux_conn_rsp_err)
diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c
index f2d6069..64e0152 100644
--- a/nimble/controller/src/ble_ll_scan.c
+++ b/nimble/controller/src/ble_ll_scan.c
@@ -162,6 +162,8 @@ ble_ll_aux_scan_cb(struct ble_ll_sched_item *sch)
     uint8_t lls = ble_ll_state_get();
     uint32_t wfr_usec;
 
+    STATS_INC(ble_ll_stats, aux_sched_cb);
+
     /* In case scan has been disabled or there is other aux ptr in progress
      * just drop the scheduled item
      */
@@ -226,6 +228,7 @@ ble_ll_scan_ext_adv_init(struct ble_ll_aux_data **aux_data)
     e->sch.sched_type = BLE_LL_SCHED_TYPE_AUX_SCAN;
 
     *aux_data = e;
+    STATS_INC(ble_ll_stats, aux_allocated);
 
     return 0;
 }
@@ -2334,6 +2337,7 @@ ble_ll_scan_aux_data_free(struct ble_ll_aux_data *aux_scan)
             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);
     }
 }
 


[mynewt-nimble] 05/13: nimble/ll: Make sure hci event size

Posted by ry...@apache.org.
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 549f8adc738e6d181c0aebf5d06cae03054268d7
Author: Łukasz Rymanowski <lu...@codecoup.pl>
AuthorDate: Thu Nov 8 16:29:06 2018 +0100

    nimble/ll: Make sure hci event size
    
    This patch make sure single HCI event is not bigger than 255
---
 nimble/controller/src/ble_ll_scan.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c
index 2eeba78..402dbd8 100644
--- a/nimble/controller/src/ble_ll_scan.c
+++ b/nimble/controller/src/ble_ll_scan.c
@@ -2357,6 +2357,7 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, uint8_t *adva, uint8_t adva_type,
     int datalen;
     int rc;
     bool need_event;
+    uint8_t max_event_len;
 
     if (!ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_EXT_ADV_RPT)) {
         return -1;
@@ -2384,15 +2385,16 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, uint8_t *adva, uint8_t adva_type,
     }
 
     offset = 0;
+    max_event_len = min(UINT8_MAX, BLE_LL_MAX_EVT_LEN);
 
     do {
         need_event = false;
         next_evt = NULL;
 
-        evt->adv_data_len = min(BLE_LL_MAX_EVT_LEN - sizeof(*evt),
+        evt->adv_data_len = min(max_event_len - sizeof(*evt),
                                 datalen - offset);
-        evt->event_len = (sizeof(*evt) - BLE_HCI_EVENT_HDR_LEN) +
-                         evt->adv_data_len;
+        /* Event len, should not contain event meta code and let itself */
+        evt->event_len = (sizeof(*evt) - BLE_HCI_EVENT_HDR_LEN) + evt->adv_data_len;
         evt->rssi = hdr->rxinfo.rssi;
 
         os_mbuf_copydata(om, offset, evt->adv_data_len, evt->adv_data);


[mynewt-nimble] 09/13: nimble/ll: Keep connecting in case of error when decoding address

Posted by ry...@apache.org.
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 c2a36ebebeb6bbf9e5cdfa3eb591fd292209377e
Author: Łukasz Rymanowski <lu...@codecoup.pl>
AuthorDate: Fri Nov 16 15:05:22 2018 +0100

    nimble/ll: Keep connecting in case of error when decoding address
---
 nimble/controller/src/ble_ll_conn.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c
index cdeff55..f170000 100644
--- a/nimble/controller/src/ble_ll_conn.c
+++ b/nimble/controller/src/ble_ll_conn.c
@@ -2974,7 +2974,8 @@ ble_ll_init_rx_pkt_in(uint8_t pdu_type, uint8_t *rxbuf,
         if (ble_ll_scan_adv_decode_addr(pdu_type, rxbuf, ble_hdr,
                                         &adv_addr, &addr_type,
                                         NULL, NULL, &ext_adv_mode)) {
-            return;
+            /* Something got wrong, keep trying to connect */
+            goto scan_continue;
         }
 
         if (ble_ll_scan_whitelist_enabled()) {


[mynewt-nimble] 13/13: nimble/ll: Improve handling truncated advertising events

Posted by ry...@apache.org.
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 859cb352c6f26d4a9c558f2cf63e36864bd8838e
Author: Łukasz Rymanowski <lu...@codecoup.pl>
AuthorDate: Fri Nov 9 10:26:39 2018 +0100

    nimble/ll: Improve handling truncated advertising events
    
    This patch make sure that each truncated advertising event is corretly
    sent to host
---
 nimble/controller/include/controller/ble_ll_scan.h |   2 +
 nimble/controller/src/ble_ll_scan.c                | 173 ++++++++++++++++-----
 nimble/controller/src/ble_ll_sched.c               |   5 +-
 3 files changed, 136 insertions(+), 44 deletions(-)

diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h
index 5aa34f0..65bff1c 100644
--- a/nimble/controller/include/controller/ble_ll_scan.h
+++ b/nimble/controller/include/controller/ble_ll_scan.h
@@ -94,6 +94,7 @@ struct ble_ll_scan_params
 #define BLE_LL_AUX_HAS_ADDRA            0x08
 #define BLE_LL_AUX_IGNORE_BIT           0x10
 #define BLE_LL_AUX_HAS_DIR_ADDRA        0x20
+#define BLE_LL_AUX_TRUNCATED_SENT       0x40
 
 #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))
@@ -253,6 +254,7 @@ int ble_ll_scan_aux_data_unref(struct ble_ll_aux_data *aux_scan);
 
 /* Called to clean up current aux data */
 void ble_ll_scan_clean_cur_aux_data(void);
+void ble_ll_scan_end_adv_evt(struct ble_ll_aux_data *aux_data);
 
 #ifdef __cplusplus
 }
diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c
index e3996c4..1fd0bf5 100644
--- a/nimble/controller/src/ble_ll_scan.c
+++ b/nimble/controller/src/ble_ll_scan.c
@@ -410,6 +410,112 @@ next_dup_adv:
     return NULL;
 }
 
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+static struct ble_ll_ext_adv_report *
+ble_ll_scan_init_ext_adv_report(struct ble_ll_ext_adv_report *copy_from)
+{
+    struct ble_ll_ext_adv_report *evt;
+
+    evt = (struct ble_ll_ext_adv_report *) ble_hci_trans_buf_alloc(
+                                                    BLE_HCI_TRANS_BUF_EVT_LO);
+    if (!evt) {
+        return NULL;
+    }
+
+    if (copy_from) {
+        memcpy(evt, copy_from, sizeof(*evt));
+    } else {
+        memset(evt, 0, sizeof(*evt));
+
+        evt->event_meta = BLE_HCI_EVCODE_LE_META;
+        evt->subevt = BLE_HCI_LE_SUBEV_EXT_ADV_RPT;
+        /* We support only one report per event now */
+        evt->num_reports = 1;
+        /* Init TX Power with "Not available" which is 127 */
+        evt->tx_power = 127;
+        /* Init RSSI with "Not available" which is 127 */
+        evt->rssi = 127;
+        /* Init SID with "Not available" which is 0xFF */
+        evt->sid = 0xFF;
+        /* Init address type with "anonymous" which is 0xFF */
+        evt->addr_type = 0xFF;
+    }
+
+    return evt;
+}
+
+static void
+ble_ll_scan_send_truncated_if_chained(struct ble_ll_aux_data *aux_data)
+{
+    struct ble_ll_ext_adv_report *evt;
+
+    if (!ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_EXT_ADV_RPT)) {
+        goto done;
+    }
+
+    BLE_LL_ASSERT(aux_data);
+
+    if (!BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_CHAIN_BIT)) {
+        /* if not chained, there is nothing to do here */
+        goto done;
+    }
+
+    if (aux_data->evt) {
+        evt = aux_data->evt;
+        aux_data->evt = NULL;
+    } else {
+        evt = ble_ll_scan_init_ext_adv_report(NULL);
+        if (!evt) {
+            goto done;
+        }
+    }
+
+    evt->event_len = sizeof(*evt);
+    evt->evt_type = aux_data->evt_type;
+    evt->evt_type |= (BLE_HCI_ADV_DATA_STATUS_TRUNCATED);
+    BLE_LL_SET_AUX_FLAG(aux_data, BLE_LL_AUX_TRUNCATED_SENT);
+
+    if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_HAS_ADDRA)) {
+        memcpy(evt->addr, aux_data->addr, 6);
+        evt->addr_type = aux_data->addr_type;
+    }
+
+    if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_HAS_DIR_ADDRA)) {
+        memcpy(evt->dir_addr, aux_data->dir_addr, 6);
+        evt->dir_addr_type = aux_data->dir_addr_type;
+    }
+
+    evt->sid = (aux_data->adi >> 12);
+    ble_ll_hci_event_send((uint8_t *)evt);
+
+done:
+    ble_ll_scan_aux_data_unref(aux_data);
+}
+#endif
+
+void
+ble_ll_scan_end_adv_evt(struct ble_ll_aux_data *aux_data)
+{
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+    /*
+     * Check if tuncated has been sent
+     *
+     * Normally reference counter here should be 2. 1 for outstanding
+     * complete event and one for ongoing scanning. If there is only 1
+     * that means, advertising event is already completed
+     * (truncated was sent to the host) and we just need to drop last reference.
+     * Otherwise we should try to send truncated event to the host.
+     */
+    if (!BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_TRUNCATED_SENT)) {
+        ble_ll_scan_send_truncated_if_chained(aux_data);
+    }
+
+    if (ble_ll_scan_aux_data_unref(aux_data) > 0) {
+        BLE_LL_ASSERT(0);
+    }
+
+#endif
+}
 /**
  * Do scan machine clean up on PHY disabled
  *
@@ -422,7 +528,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_unref(scansm->cur_aux_data);
+        ble_ll_scan_end_adv_evt(scansm->cur_aux_data);
         scansm->cur_aux_data = NULL;
     }
 #endif
@@ -577,40 +683,6 @@ ble_ll_scan_add_scan_rsp_adv(uint8_t *addr, uint8_t txadd)
 }
 
 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
-
-static struct ble_ll_ext_adv_report *
-ble_ll_scan_init_ext_adv_report(struct ble_ll_ext_adv_report *copy_from)
-{
-    struct ble_ll_ext_adv_report *evt;
-
-    evt = (struct ble_ll_ext_adv_report *) ble_hci_trans_buf_alloc(
-                                                    BLE_HCI_TRANS_BUF_EVT_LO);
-    if (!evt) {
-        return NULL;
-    }
-
-    if (copy_from) {
-        memcpy(evt, copy_from, sizeof(*evt));
-    } else {
-        memset(evt, 0, sizeof(*evt));
-
-        evt->event_meta = BLE_HCI_EVCODE_LE_META;
-        evt->subevt = BLE_HCI_LE_SUBEV_EXT_ADV_RPT;
-        /* We support only one report per event now */
-        evt->num_reports = 1;
-        /* Init TX Power with "Not available" which is 127 */
-        evt->tx_power = 127;
-        /* Init RSSI with "Not available" which is 127 */
-        evt->rssi = 127;
-        /* Init SID with "Not available" which is 0xFF */
-        evt->sid = 0xFF;
-        /* Init address type with "anonymous" which is 0xFF */
-        evt->addr_type = 0xFF;
-    }
-
-    return evt;
-}
-
 static int
 ble_ll_hci_send_legacy_ext_adv_report(uint8_t evtype,
                                       uint8_t addr_type, uint8_t *addr,
@@ -2385,8 +2457,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_unref(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();
@@ -2489,6 +2560,7 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, uint8_t *adva, uint8_t adva_type,
                 evt->evt_type |= (BLE_HCI_ADV_DATA_STATUS_INCOMPLETE);
             } else {
                 evt->evt_type |= (BLE_HCI_ADV_DATA_STATUS_TRUNCATED);
+                BLE_LL_SET_AUX_FLAG(aux_data, BLE_LL_AUX_TRUNCATED_SENT);
                 rc = -1;
             }
         } else if (aux_data ) {
@@ -2559,14 +2631,23 @@ 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)
     struct ble_ll_aux_data *aux_data = hdr->rxinfo.user_data;
     int rc;
+    uint8_t evt_possibly_truncated = 0;
 #endif
 
     /* Set scan response check flag */
     scan_rsp_chk = BLE_MBUF_HDR_SCAN_RSP_RCV(hdr);
 
     /* We dont care about scan requests or connect requests */
-    if (!BLE_MBUF_HDR_CRC_OK(hdr) || (ptype == BLE_ADV_PDU_TYPE_SCAN_REQ) ||
-        (ptype == BLE_ADV_PDU_TYPE_CONNECT_REQ)) {
+    if (!BLE_MBUF_HDR_CRC_OK(hdr)) {
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+        if (BLE_MBUF_HDR_AUX_INVALID(hdr)) {
+            evt_possibly_truncated = 1;
+        }
+#endif
+        goto scan_continue;
+    }
+
+    if ((ptype == BLE_ADV_PDU_TYPE_SCAN_REQ) || (ptype == BLE_ADV_PDU_TYPE_CONNECT_REQ)) {
         goto scan_continue;
     }
 
@@ -2574,7 +2655,10 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd
                                     &adv_addr, &txadd,
                                     &init_addr, &init_addr_type,
                                     &ext_adv_mode)) {
-       goto scan_continue;
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+        evt_possibly_truncated = 1;
+#endif
+        goto scan_continue;
     }
 
     ident_addr = adv_addr;
@@ -2667,6 +2751,7 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd
         }
 
         if (BLE_MBUF_HDR_AUX_INVALID(hdr)) {
+            evt_possibly_truncated = 1;
             goto scan_continue;
         }
 
@@ -2754,8 +2839,12 @@ scan_continue:
 
 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
     if (aux_data) {
-        /* This is ref for handover to LL */
-        ble_ll_scan_aux_data_unref(aux_data);
+        if (evt_possibly_truncated) {
+            ble_ll_scan_end_adv_evt(aux_data);
+        } else {
+            /* This is ref for handover to LL */
+            ble_ll_scan_aux_data_unref(aux_data);
+        }
     }
 #endif
     /*
diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c
index 9a22ede..ffdbf8e 100644
--- a/nimble/controller/src/ble_ll_sched.c
+++ b/nimble/controller/src/ble_ll_sched.c
@@ -250,8 +250,9 @@ 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_unref((struct ble_ll_aux_data *)
+                ble_ll_scan_end_adv_evt((struct ble_ll_aux_data *)
                                           entry->cb_arg);
+
                 break;
 #endif
             default:
@@ -1361,7 +1362,7 @@ ble_ll_sched_scan_req_over_aux_ptr(uint32_t chan, uint8_t phy_mode)
             return 1;
         }
 
-        ble_ll_scan_aux_data_unref((struct ble_ll_aux_data *)sch->cb_arg);
+        ble_ll_scan_end_adv_evt((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);


[mynewt-nimble] 07/13: nimble/ll: Fix possible null pointer dereference

Posted by ry...@apache.org.
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 23f7091807e13cea344e485f82312cd9be8c76f6
Author: Łukasz Rymanowski <lu...@codecoup.pl>
AuthorDate: Fri Nov 9 10:43:51 2018 +0100

    nimble/ll: Fix possible null pointer dereference
    
    In case of empty beacon (no AUX_ADV_IND), there will be no aux_data.
    
    This patch also:
    - removes reduntant else as need_event is already reset at
    the beggining of the loop
    
    - fixes incorrect return parameter which could be set to 1 for
    completed chained advertising event
---
 nimble/controller/src/ble_ll_scan.c | 22 ++++++++++++++--------
 1 file changed, 14 insertions(+), 8 deletions(-)

diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c
index 8b9d270..f2d6069 100644
--- a/nimble/controller/src/ble_ll_scan.c
+++ b/nimble/controller/src/ble_ll_scan.c
@@ -2405,13 +2405,11 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, uint8_t *adva, uint8_t adva_type,
         if (offset < datalen) {
             /* Need another event for next fragment of this PDU */
             need_event = true;
-        } else if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_INCOMPLETE_ERR_BIT)) {
+        } else if (aux_data && BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_INCOMPLETE_ERR_BIT)) {
             need_event = false;
-        } else if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_INCOMPLETE_BIT)) {
+        } else if (aux_data && BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_INCOMPLETE_BIT)) {
             /* Need another event for next PDU in chain */
             need_event = true;
-        } else {
-            need_event = false;
         }
 
         /* Assume data status is not "completed" */
@@ -2430,12 +2428,14 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, uint8_t *adva, uint8_t adva_type,
                 evt->evt_type |= (BLE_HCI_ADV_DATA_STATUS_TRUNCATED);
                 rc = -1;
             }
-        } else if (aux_data) { 
+        } else if (aux_data ) {
             if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_INCOMPLETE_ERR_BIT)) {
                 evt->evt_type |= (BLE_HCI_ADV_DATA_STATUS_TRUNCATED);
                 rc = -1;
             } else if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_INCOMPLETE_BIT)) {
                 evt->evt_type |= (BLE_HCI_ADV_DATA_STATUS_INCOMPLETE);
+            } else {
+                rc = 0;
             }
         } else {
             rc = 0;
@@ -2448,8 +2448,13 @@ ble_ll_hci_send_ext_adv_report(uint8_t ptype, uint8_t *adva, uint8_t adva_type,
 
     BLE_LL_ASSERT(offset <= datalen);
 
-    /* Store any event left for later use */
-    aux_data->evt = evt;
+    if (aux_data){
+        /* Store any event left for later use */
+        aux_data->evt = evt;
+    } else {
+        /* If it is empty beacon, evt shall be NULL */
+        BLE_LL_ASSERT(!evt);
+    }
 
     return rc;
 }
@@ -2588,12 +2593,13 @@ ble_ll_scan_rx_pkt_in(uint8_t ptype, struct os_mbuf *om, struct ble_mbuf_hdr *hd
         }
 
 
-        if (BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_IGNORE_BIT)) {
+        if (aux_data && BLE_LL_CHECK_AUX_FLAG(aux_data, BLE_LL_AUX_IGNORE_BIT)) {
             goto scan_continue;
         }
 
         /* Let's see if that packet contains aux ptr*/
         if (BLE_MBUF_HDR_WAIT_AUX(hdr)) {
+           BLE_LL_ASSERT(aux_data);
             if (ble_ll_sched_aux_scan(hdr, scansm, hdr->rxinfo.user_data)) {
                 /* We are here when could not schedule the aux ptr */
                 hdr->rxinfo.flags &= ~BLE_MBUF_HDR_F_AUX_PTR_WAIT;


[mynewt-nimble] 03/13: nimble/ll: Improve getting advertising and target address

Posted by ry...@apache.org.
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 665f0795d91d4b3db129d1773a5cd5fa0bd2d39b
Author: Łukasz Rymanowski <lu...@codecoup.pl>
AuthorDate: Mon Nov 5 15:40:54 2018 +0100

    nimble/ll: Improve getting advertising and target address
    
    aux_data pointer contains valid advertiser and directed address from the
    very beggining if it is available. Later on when getting address let's
    make use of it and do not try to parse packet unless this is empty
    beacon
---
 nimble/controller/src/ble_ll_scan.c | 46 +++++++++++++++++--------------------
 1 file changed, 21 insertions(+), 25 deletions(-)

diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c
index 2dd9caa..ebef10b 100644
--- a/nimble/controller/src/ble_ll_scan.c
+++ b/nimble/controller/src/ble_ll_scan.c
@@ -1922,6 +1922,27 @@ ble_ll_scan_get_addr_from_ext_adv(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr,
         return -1;
     }
 
+    if (aux_data) {
+        /* If address has been provided, we do have it already in aux_data.*/
+        if (aux_data->flags & BLE_LL_AUX_HAS_ADDRA) {
+            *addr = aux_data->addr;
+            *addr_type = aux_data->addr_type;
+        }
+
+        if (!inita) {
+            return 0;
+        }
+
+        if (aux_data->flags & BLE_LL_AUX_HAS_DIR_ADDRA) {
+            *inita = aux_data->dir_addr;
+            *inita_type = aux_data->dir_addr_type;
+        }
+
+        return 0;
+    }
+
+    /* If this is just becon with no aux data, lets get address from the packet */
+
     ext_hdr_len = rxbuf[2] & 0x3F;
 
     ext_hdr_flags = rxbuf[3];
@@ -1937,19 +1958,6 @@ ble_ll_scan_get_addr_from_ext_adv(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr,
         *addr_type =
                 ble_ll_get_addr_type(rxbuf[0] & BLE_ADV_PDU_HDR_TXADD_MASK);
         i += BLE_LL_EXT_ADV_ADVA_SIZE;
-        if (aux_data) {
-            /* Lets copy addr to aux_data. Need it for e.g. chaining */
-            /* XXX add sanity checks */
-            memcpy(aux_data->addr, *addr, 6);
-            aux_data->addr_type = *addr_type;
-            aux_data->flags |= BLE_LL_AUX_HAS_ADDRA;
-        }
-    } else {
-        /* We should have address already in aux_data */
-        if (aux_data->flags & BLE_LL_AUX_HAS_ADDRA) {
-            *addr = aux_data->addr;
-            *addr_type = aux_data->addr_type;
-        }
     }
 
     if (!inita) {
@@ -1961,18 +1969,6 @@ ble_ll_scan_get_addr_from_ext_adv(uint8_t *rxbuf, struct ble_mbuf_hdr *ble_hdr,
         *inita_type =
                 ble_ll_get_addr_type(rxbuf[0] & BLE_ADV_PDU_HDR_RXADD_MASK);
         i += BLE_LL_EXT_ADV_TARGETA_SIZE;
-        if (aux_data) {
-            /* Lets copy addr to aux_data. Need it for e.g. chaining */
-            memcpy(aux_data->dir_addr, *inita, 6);
-            aux_data->dir_addr_type = *inita_type;
-            aux_data->flags |= BLE_LL_AUX_HAS_DIR_ADDRA;
-        }
-    } else {
-        /* We should have address already in aux_data */
-        if (aux_data->flags & BLE_LL_AUX_HAS_DIR_ADDRA) {
-            *inita = aux_data->dir_addr;
-            *inita_type = aux_data->dir_addr_type;
-        }
     }
 
     return 0;


[mynewt-nimble] 11/13: nimble/ll: Add return value to ble_ll_sched_rmv_elem

Posted by ry...@apache.org.
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 f709097a7854abce237b02cebfe46ef8850e871b
Author: Łukasz Rymanowski <lu...@codecoup.pl>
AuthorDate: Fri Nov 16 15:16:42 2018 +0100

    nimble/ll: Add return value to ble_ll_sched_rmv_elem
    
    This will be used be next patches where LL need to know if given element
    has been removed or is already fired. Based on this reference counter of
    aux_data will be dropped or not.
---
 nimble/controller/include/controller/ble_ll_sched.h |  2 +-
 nimble/controller/src/ble_ll_sched.c                | 10 +++++++---
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h
index 6c7d8a0..d41f4c1 100644
--- a/nimble/controller/include/controller/ble_ll_sched.h
+++ b/nimble/controller/include/controller/ble_ll_sched.h
@@ -141,7 +141,7 @@ struct ble_ll_sched_item
 int ble_ll_sched_init(void);
 
 /* Remove item(s) from schedule */
-void ble_ll_sched_rmv_elem(struct ble_ll_sched_item *sch);
+int ble_ll_sched_rmv_elem(struct ble_ll_sched_item *sch);
 
 void ble_ll_sched_rmv_elem_type(uint8_t type, sched_remove_cb_func remove_cb);
 
diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c
index cb00ea0..04e630c 100644
--- a/nimble/controller/src/ble_ll_sched.c
+++ b/nimble/controller/src/ble_ll_sched.c
@@ -1066,16 +1066,17 @@ adv_resched_pdu_fail:
  *
  * @param sched_type
  *
- * @return int
+ * @return int 0 - removed, 1 - not in the list
  */
-void
+int
 ble_ll_sched_rmv_elem(struct ble_ll_sched_item *sch)
 {
     os_sr_t sr;
     struct ble_ll_sched_item *first;
+    int rc = 1;
 
     if (!sch) {
-        return;
+        return rc;
     }
 
     OS_ENTER_CRITICAL(sr);
@@ -1087,6 +1088,7 @@ ble_ll_sched_rmv_elem(struct ble_ll_sched_item *sch)
 
         TAILQ_REMOVE(&g_ble_ll_sched_q, sch, link);
         sch->enqueued = 0;
+        rc = 0;
 
         if (first == sch) {
             first = TAILQ_FIRST(&g_ble_ll_sched_q);
@@ -1096,6 +1098,8 @@ ble_ll_sched_rmv_elem(struct ble_ll_sched_item *sch)
         }
     }
     OS_EXIT_CRITICAL(sr);
+
+    return rc;
 }
 
 void