You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by GitBox <gi...@apache.org> on 2018/04/18 11:27:29 UTC

[GitHub] sjanc closed pull request #48: Support for duration and period in extended scan

sjanc closed pull request #48: Support for duration and period in extended scan
URL: https://github.com/apache/mynewt-nimble/pull/48
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/nimble/controller/include/controller/ble_ll_ctrl.h b/nimble/controller/include/controller/ble_ll_ctrl.h
index fa50c98f..7e5d50ba 100644
--- a/nimble/controller/include/controller/ble_ll_ctrl.h
+++ b/nimble/controller/include/controller/ble_ll_ctrl.h
@@ -272,6 +272,7 @@ void ble_ll_hci_ev_databuf_overflow(void);
 void ble_ll_hci_ev_le_csa(struct ble_ll_conn_sm *connsm);
 void ble_ll_hci_ev_send_scan_req_recv(uint8_t adv_handle, const uint8_t *peer,
                                       uint8_t peer_addr_type);
+void ble_ll_hci_ev_send_scan_timeout(void);
 void ble_ll_hci_ev_send_adv_set_terminated(uint8_t status, uint8_t adv_handle,
                                            uint16_t conn_handle, uint8_t events);
 int ble_ll_hci_ev_phy_update(struct ble_ll_conn_sm *connsm, uint8_t status);
diff --git a/nimble/controller/include/controller/ble_ll_scan.h b/nimble/controller/include/controller/ble_ll_scan.h
index 35cbeb44..d01647bf 100644
--- a/nimble/controller/include/controller/ble_ll_scan.h
+++ b/nimble/controller/include/controller/ble_ll_scan.h
@@ -132,12 +132,16 @@ struct ble_ll_scan_sm
     struct os_event scan_sched_ev;
     struct hal_timer scan_timer;
 
-    uint16_t duration;
-    uint16_t period;
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+    struct hal_timer duration_timer;
+    struct hal_timer period_timer;
+    uint32_t duration_ticks;
+    uint32_t period_ticks;
+    uint8_t ext_scanning;
+#endif
 
     uint8_t cur_phy;
     uint8_t next_phy;
-    uint8_t ext_scanning;
     uint8_t restart_timer_needed;
     struct ble_ll_aux_data *cur_aux_data;
     struct ble_ll_scan_params phy_data[BLE_LL_SCAN_PHY_NUMBER];
diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c
index 2ed695f1..d5b0b47e 100644
--- a/nimble/controller/src/ble_ll_conn.c
+++ b/nimble/controller/src/ble_ll_conn.c
@@ -3028,13 +3028,11 @@ int
 ble_ll_init_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *ble_hdr)
 {
     struct ble_ll_conn_sm *connsm;
-    struct ble_ll_scan_sm *scansm;
 
     connsm = g_ble_ll_conn_create_sm;
     if (!connsm) {
         return 0;
     }
-    scansm = connsm->scansm;
 
     if ((pdu_type == BLE_ADV_PDU_TYPE_ADV_IND) ||
         (pdu_type == BLE_ADV_PDU_TYPE_ADV_DIRECT_IND ||
@@ -3042,7 +3040,9 @@ ble_ll_init_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *ble_hdr)
         return 1;
     }
 
-    if (pdu_type == BLE_ADV_PDU_TYPE_ADV_EXT_IND && scansm->ext_scanning) {
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+    if (pdu_type == BLE_ADV_PDU_TYPE_ADV_EXT_IND &&
+                                                connsm->scansm->ext_scanning) {
         if (connsm->scansm->cur_aux_data) {
             STATS_INC(ble_ll_stats, aux_received);
         }
@@ -3050,6 +3050,7 @@ ble_ll_init_rx_isr_start(uint8_t pdu_type, struct ble_mbuf_hdr *ble_hdr)
         ble_hdr->rxinfo.flags |= BLE_MBUF_HDR_F_EXT_ADV;
         return 1;
     }
+#endif
 
     return 0;
 }
diff --git a/nimble/controller/src/ble_ll_hci_ev.c b/nimble/controller/src/ble_ll_hci_ev.c
index 6abfdd6d..815338aa 100644
--- a/nimble/controller/src/ble_ll_hci_ev.c
+++ b/nimble/controller/src/ble_ll_hci_ev.c
@@ -320,6 +320,28 @@ ble_ll_hci_ev_send_scan_req_recv(uint8_t adv_handle, const uint8_t *peer,
 }
 #endif
 
+/**
+ * Sends the  LE Scan Timeout Event
+ *
+ */
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+void
+ble_ll_hci_ev_send_scan_timeout(void)
+{
+    uint8_t *evbuf;
+
+    if (ble_ll_hci_is_le_event_enabled(BLE_HCI_LE_SUBEV_SCAN_TIMEOUT)) {
+        evbuf = ble_hci_trans_buf_alloc(BLE_HCI_TRANS_BUF_EVT_HI);
+        if (evbuf) {
+            evbuf[0] = BLE_HCI_EVCODE_LE_META;
+            evbuf[1] = BLE_HCI_LE_SUBEV_SCAN_TIMEOUT_LEN;
+            evbuf[2] = BLE_HCI_LE_SUBEV_SCAN_TIMEOUT;
+            ble_ll_hci_event_send(evbuf);
+        }
+    }
+}
+#endif
+
 /**
  * Sends the LE Advertising Set Terminated event
  *
diff --git a/nimble/controller/src/ble_ll_scan.c b/nimble/controller/src/ble_ll_scan.c
index 49d5eda2..cbf63f0c 100644
--- a/nimble/controller/src/ble_ll_scan.c
+++ b/nimble/controller/src/ble_ll_scan.c
@@ -1154,7 +1154,9 @@ ble_ll_scan_sm_stop(int chk_disable)
     if (chk_disable) {
         OS_ENTER_CRITICAL(sr);
         lls = ble_ll_state_get();
-        if ((lls == BLE_LL_STATE_SCANNING) || (lls == BLE_LL_STATE_INITIATING)) {
+
+        if ((lls == BLE_LL_STATE_SCANNING) ||
+                        (lls == BLE_LL_STATE_INITIATING && chk_disable == 1)) {
             /* Disable phy */
             ble_phy_disable();
 
@@ -1509,10 +1511,12 @@ ble_ll_scan_rx_isr_start(uint8_t pdu_type, uint16_t *rxflags)
             rc = 1;
         }
 
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
         if ((pdu_type == BLE_ADV_PDU_TYPE_ADV_EXT_IND && scansm->ext_scanning)) {
             *rxflags |= BLE_MBUF_HDR_F_EXT_ADV;
             rc = 1;
         }
+#endif
 
         /*
          * If this is the first PDU after we sent the scan response (as
@@ -2710,6 +2714,57 @@ ble_ll_set_ext_scan_params(uint8_t *cmd)
 
 #endif
 
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+static void
+ble_ll_scan_duration_period_timers_restart(struct ble_ll_scan_sm *scansm)
+{
+    uint32_t now;
+
+    now = os_cputime_get32();
+
+    os_cputime_timer_stop(&scansm->duration_timer);
+    os_cputime_timer_stop(&scansm->period_timer);
+
+    if (scansm->duration_ticks) {
+        os_cputime_timer_start(&scansm->duration_timer,
+                                                now + scansm->duration_ticks);
+
+        if (scansm->period_ticks) {
+            os_cputime_timer_start(&scansm->period_timer,
+                                                    now + scansm->period_ticks);
+        }
+    }
+}
+
+static void
+ble_ll_scan_duration_timer_cb(void *arg)
+{
+    struct ble_ll_scan_sm *scansm;
+
+    scansm = (struct ble_ll_scan_sm *)arg;
+
+    ble_ll_scan_sm_stop(2);
+
+    /* if period is set both timers get started from period cb */
+    if (!scansm->period_ticks) {
+        ble_ll_hci_ev_send_scan_timeout();
+    }
+}
+
+static void
+ble_ll_scan_period_timer_cb(void *arg)
+{
+    struct ble_ll_scan_sm *scansm = arg;
+
+    ble_ll_scan_sm_start(scansm);
+
+    /* always start timer regardless of ble_ll_scan_sm_start result
+     * if it failed will restart in next period
+     */
+    ble_ll_scan_duration_period_timers_restart(scansm);
+}
+#endif
+
 /**
  * ble ll scan set enable
  *
@@ -2730,9 +2785,13 @@ ble_ll_scan_set_enable(uint8_t *cmd, uint8_t ext)
     struct ble_ll_scan_sm *scansm;
     struct ble_ll_scan_params *scanp;
     struct ble_ll_scan_params *scanphy;
-    uint16_t dur;
-    uint16_t period;
     int i;
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+    uint32_t period_ticks = 0;
+    uint32_t dur_ticks = 0;
+    uint16_t period;
+    uint16_t dur;
+#endif
 
     /* Check for valid parameters */
     enable = cmd[0];
@@ -2743,70 +2802,114 @@ ble_ll_scan_set_enable(uint8_t *cmd, uint8_t ext)
 
     scansm = &g_ble_ll_scan_sm;
 
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+    /* we can do that here since value will never change until reset */
     scansm->ext_scanning = ext;
 
     if (ext) {
-        /* TODO: Mark that extended scan is ongoing in order to send
-        * correct advertising report
-        */
-
         dur = get_le16(cmd + 2);
-        period = get_le16(cmd + 4);
 
-        /* TODO Use period and duration */
-        (void) dur;
-        (void) period;
-    }
+        /* Period parameter is ignored when the Duration parameter is zero */
+        if (dur) {
+            period = get_le16(cmd + 4);
+        } else {
+            period = 0;
+        }
 
-    rc = BLE_ERR_SUCCESS;
-    if (enable) {
-        /* If already enabled, do nothing */
-        if (!scansm->scan_enabled) {
+        /* period is in 1.28 sec units
+         * TODO support full range, would require os_cputime milliseconds API
+         */
+        if (period > 3355) {
+            return BLE_ERR_INV_HCI_CMD_PARMS;
+        }
+        period_ticks = os_cputime_usecs_to_ticks(period * 1280000);
 
-            scansm->cur_phy = PHY_NOT_CONFIGURED;
-            scansm->next_phy = PHY_NOT_CONFIGURED;
+        /* duration is in 10ms units */
+        dur_ticks = os_cputime_usecs_to_ticks(dur * 10000);
 
-            for (i = 0; i < BLE_LL_SCAN_PHY_NUMBER; i++) {
-                scanphy = &scansm->phy_data[i];
-                scanp = &g_ble_ll_scan_params[i];
+        if (dur_ticks && period_ticks && (dur_ticks >= period_ticks)) {
+            return BLE_ERR_INV_HCI_CMD_PARMS;
+        }
+    }
+#endif
 
-                if (!scanp->configured) {
-                    continue;
-                }
+    /* disable*/
+    if (!enable) {
+        if (scansm->scan_enabled) {
+            ble_ll_scan_sm_stop(1);
+        }
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+        os_cputime_timer_stop(&scansm->duration_timer);
+        os_cputime_timer_stop(&scansm->period_timer);
+#endif
 
-                scanphy->configured = scanp->configured;
-                scanphy->scan_type = scanp->scan_type;
-                scanphy->scan_itvl = scanp->scan_itvl;
-                scanphy->scan_window = scanp->scan_window;
-                scanphy->scan_filt_policy = scanp->scan_filt_policy;
-                scanphy->own_addr_type = scanp->own_addr_type;
-                scansm->scan_filt_dups = filter_dups;
-
-                if (scansm->cur_phy == PHY_NOT_CONFIGURED) {
-                    scansm->cur_phy = i;
-                } else {
-                    scansm->next_phy = i;
-                }
-            }
+        return BLE_ERR_SUCCESS;
+    }
 
-            rc = ble_ll_scan_sm_start(scansm);
-        } else {
-            /* Controller does not allow initiating and scanning.*/
-            for (i = 0; i < BLE_LL_SCAN_PHY_NUMBER; i++) {
-                scanphy = &scansm->phy_data[i];
-                if (scanphy->configured &&
-                        scanphy->scan_type == BLE_SCAN_TYPE_INITIATE) {
-                        rc = BLE_ERR_CMD_DISALLOWED;
-                        break;
-                }
+    /* if already enable we just need to update parameters */
+    if (scansm->scan_enabled) {
+        /* Controller does not allow initiating and scanning.*/
+        for (i = 0; i < BLE_LL_SCAN_PHY_NUMBER; i++) {
+            scanphy = &scansm->phy_data[i];
+            if (scanphy->configured &&
+                                scanphy->scan_type == BLE_SCAN_TYPE_INITIATE) {
+                return BLE_ERR_CMD_DISALLOWED;
             }
         }
-    } else {
-        if (scansm->scan_enabled) {
-            ble_ll_scan_sm_stop(1);
+
+        /* update filter policy */
+        scansm->scan_filt_dups = filter_dups;
+
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+        /* restart timers according to new settings */
+        scansm->duration_ticks = dur_ticks;
+        scansm->period_ticks = period_ticks;
+        ble_ll_scan_duration_period_timers_restart(scansm);
+#endif
+
+        return BLE_ERR_SUCCESS;
+    }
+
+    /* we can store those upfront regardless of start scan result since scan is
+     * disabled now
+     */
+
+    scansm->scan_filt_dups = filter_dups;
+    scansm->cur_phy = PHY_NOT_CONFIGURED;
+    scansm->next_phy = PHY_NOT_CONFIGURED;
+
+    for (i = 0; i < BLE_LL_SCAN_PHY_NUMBER; i++) {
+        scanphy = &scansm->phy_data[i];
+        scanp = &g_ble_ll_scan_params[i];
+
+        if (!scanp->configured) {
+            continue;
+        }
+
+        scanphy->configured = scanp->configured;
+        scanphy->scan_type = scanp->scan_type;
+        scanphy->scan_itvl = scanp->scan_itvl;
+        scanphy->scan_window = scanp->scan_window;
+        scanphy->scan_filt_policy = scanp->scan_filt_policy;
+        scanphy->own_addr_type = scanp->own_addr_type;
+
+        if (scansm->cur_phy == PHY_NOT_CONFIGURED) {
+            scansm->cur_phy = i;
+        } else {
+            scansm->next_phy = i;
         }
     }
 
+    rc = ble_ll_scan_sm_start(scansm);
+
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+    if (rc == BLE_ERR_SUCCESS) {
+        scansm->duration_ticks = dur_ticks;
+        scansm->period_ticks = period_ticks;
+        ble_ll_scan_duration_period_timers_restart(scansm);
+    }
+#endif
+
     return rc;
 }
 
@@ -2844,7 +2947,9 @@ ble_ll_scan_initiator_start(struct hci_create_conn *hcc,
 
     scansm = &g_ble_ll_scan_sm;
     scansm->own_addr_type = hcc->own_addr_type;
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
     scansm->ext_scanning = 0;
+#endif
     scansm->cur_phy = PHY_UNCODED;
     scansm->next_phy = PHY_NOT_CONFIGURED;
 
@@ -3059,6 +3164,14 @@ ble_ll_scan_common_init(void)
     /* Initialize scanning timer */
     os_cputime_timer_init(&scansm->scan_timer, ble_ll_scan_timer_cb, scansm);
 
+    /* Initialize extended scan timers */
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+    os_cputime_timer_init(&g_ble_ll_scan_sm.duration_timer,
+                            ble_ll_scan_duration_timer_cb, &g_ble_ll_scan_sm);
+    os_cputime_timer_init(&g_ble_ll_scan_sm.period_timer,
+                            ble_ll_scan_period_timer_cb, &g_ble_ll_scan_sm);
+#endif
+
     /* Get a scan request mbuf (packet header) and attach to state machine */
     scansm->scan_req_pdu = os_msys_get_pkthdr(BLE_SCAN_LEGACY_MAX_PKT_LEN,
                                               sizeof(struct ble_mbuf_hdr));
@@ -3076,12 +3189,19 @@ ble_ll_scan_reset(void)
 {
     struct ble_ll_scan_sm *scansm;
 
-    /* If enabled, stop it. */
     scansm = &g_ble_ll_scan_sm;
+
+    /* If enabled, stop it. */
     if (scansm->scan_enabled) {
         ble_ll_scan_sm_stop(0);
     }
 
+    /* stop extended scan timers */
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+    os_cputime_timer_stop(&scansm->duration_timer);
+    os_cputime_timer_stop(&scansm->period_timer);
+#endif
+
     /* Free the scan request pdu */
     os_mbuf_free_chain(scansm->scan_req_pdu);
 
diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c
index 6c79842a..1bfaad06 100644
--- a/nimble/host/src/ble_gap.c
+++ b/nimble/host/src/ble_gap.c
@@ -1257,6 +1257,14 @@ ble_gap_rx_adv_report(struct ble_gap_disc_desc *desc)
     ble_gap_disc_report(desc);
 }
 
+#if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN
+void
+ble_gap_rx_le_scan_timeout(void)
+{
+    ble_gap_disc_complete();
+}
+#endif
+
 #if MYNEWT_VAL(BLE_EXT_ADV)
 void
 ble_gap_rx_ext_adv_report(struct ble_gap_ext_disc_desc *desc)
diff --git a/nimble/host/src/ble_gap_priv.h b/nimble/host/src/ble_gap_priv.h
index 1da9aa7a..a789f397 100644
--- a/nimble/host/src/ble_gap_priv.h
+++ b/nimble/host/src/ble_gap_priv.h
@@ -75,6 +75,10 @@ extern STATS_SECT_DECL(ble_gap_stats) ble_gap_stats;
 #define BLE_GAP_CONN_MODE_MAX               3
 #define BLE_GAP_DISC_MODE_MAX               3
 
+#if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN
+void ble_gap_rx_le_scan_timeout(void);
+#endif
+
 #if MYNEWT_VAL(BLE_EXT_ADV)
 void ble_gap_rx_ext_adv_report(struct ble_gap_ext_disc_desc *desc);
 void ble_gap_rx_adv_set_terminated(struct hci_le_adv_set_terminated *evt);
diff --git a/nimble/host/src/ble_hs_hci_evt.c b/nimble/host/src/ble_hs_hci_evt.c
index b5174e05..61250845 100644
--- a/nimble/host/src/ble_hs_hci_evt.c
+++ b/nimble/host/src/ble_hs_hci_evt.c
@@ -50,6 +50,7 @@ static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_dir_adv_rpt;
 static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_phy_update_complete;
 static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_ext_adv_rpt;
 static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_rd_rem_used_feat_complete;
+static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_scan_timeout;
 static ble_hs_hci_evt_le_fn ble_hs_hci_evt_le_adv_set_terminated;
 
 /* Statistics */
@@ -102,6 +103,8 @@ static const struct ble_hs_hci_evt_le_dispatch_entry
     { BLE_HCI_LE_SUBEV_EXT_ADV_RPT, ble_hs_hci_evt_le_ext_adv_rpt },
     { BLE_HCI_LE_SUBEV_RD_REM_USED_FEAT,
             ble_hs_hci_evt_le_rd_rem_used_feat_complete },
+    { BLE_HCI_LE_SUBEV_SCAN_TIMEOUT,
+            ble_hs_hci_evt_le_scan_timeout },
     { BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED,
             ble_hs_hci_evt_le_adv_set_terminated },
 };
@@ -604,6 +607,15 @@ ble_hs_hci_evt_le_ext_adv_rpt(uint8_t subevent, uint8_t *data, int len)
     return 0;
 }
 
+static int
+ble_hs_hci_evt_le_scan_timeout(uint8_t subevent, uint8_t *data, int len)
+{
+#if MYNEWT_VAL(BLE_EXT_ADV) && NIMBLE_BLE_SCAN
+        ble_gap_rx_le_scan_timeout();
+#endif
+        return 0;
+}
+
 static int
 ble_hs_hci_evt_le_adv_set_terminated(uint8_t subevent, uint8_t *data, int len)
 {
diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h
index e887e21c..4ce941ee 100644
--- a/nimble/include/nimble/hci_common.h
+++ b/nimble/include/nimble/hci_common.h
@@ -775,6 +775,9 @@ extern "C" {
 /* LE PHY update complete event (sub event 0x0C) */
 #define BLE_HCI_LE_PHY_UPD_LEN              (6)
 
+/* LE Scan Timeout Event (sub event 0x11) */
+#define BLE_HCI_LE_SUBEV_SCAN_TIMEOUT_LEN   (1)
+
 /*  LE Advertising Set Terminated Event (sub event 0x12) */
 #define BLE_HCI_LE_SUBEV_ADV_SET_TERMINATED_LEN   (6)
 


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
users@infra.apache.org


With regards,
Apache Git Services