rymanluk closed pull request #883: nimble/ll: Improve extended scan/connect 
when host request both PHYs to be used
URL: https://github.com/apache/mynewt-core/pull/883
 
 
   

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/net/nimble/controller/src/ble_ll_scan.c 
b/net/nimble/controller/src/ble_ll_scan.c
index b20cbfc99..76559ef85 100644
--- a/net/nimble/controller/src/ble_ll_scan.c
+++ b/net/nimble/controller/src/ble_ll_scan.c
@@ -1001,7 +1001,7 @@ ble_ll_scan_start(struct ble_ll_scan_sm *scansm, struct 
ble_ll_sched_item *sch)
         rc = ble_phy_rx_set_start_time(os_cputime_get32() +
                                        g_ble_ll_sched_offset_ticks, 0);
     }
-    if (!rc) {
+    if (!rc || rc == BLE_PHY_ERR_RX_LATE) {
         /* Enable/disable whitelisting */
         if (scanphy->scan_filt_policy & 1) {
             ble_ll_whitelist_enable();
@@ -1244,9 +1244,9 @@ ble_ll_scan_switch_phy(struct ble_ll_scan_sm *scansm)
  *
  * @param arg
  */
-static uint32_t
+static bool
 ble_ll_scan_start_next_phy(struct ble_ll_scan_sm *scansm,
-                                 uint32_t next_event_time)
+                                 uint32_t *next_event_time)
 {
     struct ble_ll_scan_params *cur_phy;
     struct ble_ll_scan_params *next_phy;
@@ -1256,35 +1256,33 @@ ble_ll_scan_start_next_phy(struct ble_ll_scan_sm 
*scansm,
     /* Lets check if we want to switch to other PHY */
     if (scansm->cur_phy == scansm->next_phy ||
             scansm->next_phy == PHY_NOT_CONFIGURED) {
-        return next_event_time;
+        return false;
     }
 
     cur_phy = &scansm->phy_data[scansm->cur_phy];
     next_phy = &scansm->phy_data[scansm->next_phy];
 
-    cur_phy->next_event_start = next_event_time;
+    /* Store next event for current phy */
+    cur_phy->next_event_start = *next_event_time;
 
-    if ((int32_t)(next_phy->next_event_start - next_event_time)<  0) {
-        /* Other PHY already wanted to scan. Allow it */
-        ble_ll_scan_switch_phy(scansm);
-        now = os_cputime_get32();
-        if ((int32_t)(next_phy->next_event_start - now) <= 0) {
-            /* Start with new channel only if PHY was scanning already */
-            if (next_phy->next_event_start != 0) {
-                next_phy->scan_chan =
-                        
ble_ll_scan_get_next_adv_prim_chan(next_phy->scan_chan);
-            }
-            next_phy->scan_win_start_time = now;
-            win = os_cputime_usecs_to_ticks(next_phy->scan_window *
-                                            BLE_HCI_SCAN_ITVL);
+    /* Other PHY already wanted to scan. Allow it */
+    ble_ll_scan_switch_phy(scansm);
 
-            next_phy->next_event_start = now + win;
-            ble_ll_scan_start(scansm, NULL);
-        }
-        next_event_time = next_phy->next_event_start;
+    now = os_cputime_get32();
+
+    /* Start with new channel only if PHY was scanning already */
+    if (next_phy->next_event_start != 0) {
+        next_phy->scan_chan =
+                ble_ll_scan_get_next_adv_prim_chan(next_phy->scan_chan);
     }
+    next_phy->scan_win_start_time = now;
+    win = os_cputime_usecs_to_ticks(next_phy->scan_window *
+                                    BLE_HCI_SCAN_ITVL);
 
-    return next_event_time;
+    next_phy->next_event_start = now + win;
+
+    *next_event_time = next_phy->next_event_start;
+    return true;
 }
 
 static void
@@ -1369,6 +1367,16 @@ ble_ll_scan_event_proc(struct os_event *ev)
         next_event_time = win_start + scan_itvl;
     }
 
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+    if (inside_window == 0  &&
+                        ble_ll_scan_start_next_phy(scansm, &next_event_time)) {
+        /* Check if we should start next phy. If so let's say we are inside
+         * the window
+         */
+        inside_window = 1;
+    }
+#endif
+
     /*
      * If we are not in the standby state it means that the scheduled
      * scanning event was overlapped in the schedule. In this case all we do
@@ -1379,7 +1387,7 @@ ble_ll_scan_event_proc(struct os_event *ev)
     case BLE_LL_STATE_ADV:
     case BLE_LL_STATE_CONNECTION:
          start_scan = 0;
-        break;
+         break;
     case BLE_LL_STATE_INITIATING:
         /* Must disable PHY since we will move to a new channel */
         ble_phy_disable();
@@ -1403,30 +1411,6 @@ ble_ll_scan_event_proc(struct os_event *ev)
         break;
     }
 
-#ifdef BLE_XCVR_RFCLK
-    if (inside_window == 0) {
-        /*
-         * We need to wake up before we need to start scanning in order
-         * to make sure the rfclock is on. If we are close to being on,
-         * enable the rfclock. If not, set wakeup time.
-         */
-        if (dt >= (scan_itvl - g_ble_ll_data.ll_xtal_ticks)) {
-            /* Start the clock if necessary */
-            if (start_scan) {
-                if (ble_ll_xcvr_rfclk_state() == BLE_RFCLK_STATE_OFF) {
-                    ble_ll_xcvr_rfclk_start_now(now);
-                    next_event_time = now + g_ble_ll_data.ll_xtal_ticks;
-                }
-            }
-        } else {
-            next_event_time -= g_ble_ll_data.ll_xtal_ticks;
-            if (start_scan) {
-                ble_ll_scan_rfclk_chk_stop();
-            }
-        }
-    }
-#endif
-
     if (start_scan && inside_window) {
 #ifdef BLE_XCVR_RFCLK
             xtal_state = ble_ll_xcvr_rfclk_state();
@@ -1443,7 +1427,7 @@ ble_ll_scan_event_proc(struct os_event *ev)
              */
             if (win != 0) {
                 if ((win - dt) <= xtal_ticks)  {
-                    goto rfclk_not_settled;
+                    goto done;
                 }
             }
 
@@ -1455,19 +1439,38 @@ ble_ll_scan_event_proc(struct os_event *ev)
                 ble_ll_xcvr_rfclk_start_now(now);
             }
             next_event_time = now + xtal_ticks;
-            goto rfclk_not_settled;
+            goto done;
         }
 #endif
         ble_ll_scan_start(scansm, NULL);
-    } else {
-#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
-      next_event_time = ble_ll_scan_start_next_phy(scansm, next_event_time);
-#endif
+        goto done;
     }
 
 #ifdef BLE_XCVR_RFCLK
-rfclk_not_settled:
+    if (inside_window == 0) {
+        /*
+         * We need to wake up before we need to start scanning in order
+         * to make sure the rfclock is on. If we are close to being on,
+         * enable the rfclock. If not, set wakeup time.
+         */
+        if (dt >= (scan_itvl - g_ble_ll_data.ll_xtal_ticks)) {
+            /* Start the clock if necessary */
+            if (start_scan) {
+                if (ble_ll_xcvr_rfclk_state() == BLE_RFCLK_STATE_OFF) {
+                    ble_ll_xcvr_rfclk_start_now(now);
+                    next_event_time = now + g_ble_ll_data.ll_xtal_ticks;
+                }
+            }
+        } else {
+            next_event_time -= g_ble_ll_data.ll_xtal_ticks;
+            if (start_scan) {
+                ble_ll_scan_rfclk_chk_stop();
+            }
+        }
+    }
 #endif
+
+done:
     OS_EXIT_CRITICAL(sr);
     os_cputime_timer_start(&scansm->scan_timer, next_event_time);
 }
@@ -2688,14 +2691,16 @@ ble_ll_set_ext_scan_params(uint8_t *cmd)
     }
 #endif
 
-    /* For now we don't accept request for continuous scan if 2 PHYs are
-     * requested.
+    /* If host requests continuous scan for 2 PHYs, we double scan interval
+     * and split it for two equal scan windows between 2 PHYs
      */
-    if ((cmd[2] ==
-            (BLE_HCI_LE_PHY_1M_PREF_MASK | BLE_HCI_LE_PHY_CODED_PREF_MASK)) &&
+    if ((coded->configured && uncoded->configured) &&
                 ((uncoded->scan_itvl == uncoded->scan_window) ||
                 (coded->scan_itvl == coded-> scan_window))) {
-            return BLE_ERR_INV_HCI_CMD_PARMS;
+
+                uncoded->scan_itvl *= 2;
+                coded-> scan_itvl = uncoded->scan_itvl;
+                coded->scan_window = uncoded->scan_window;
     }
 
     memcpy(g_ble_ll_scan_params, new_params, sizeof(new_params));
@@ -2869,7 +2874,8 @@ ble_ll_scan_ext_initiator_start(struct 
hci_ext_create_conn *hcc,
                                 struct ble_ll_scan_sm **sm)
 {
     struct ble_ll_scan_sm *scansm;
-    struct ble_ll_scan_params *scanphy;
+    struct ble_ll_scan_params *uncoded;
+    struct ble_ll_scan_params *coded;
     struct hci_ext_conn_params *params;
     int rc;
 
@@ -2881,23 +2887,23 @@ ble_ll_scan_ext_initiator_start(struct 
hci_ext_create_conn *hcc,
 
     if (hcc->init_phy_mask & BLE_PHY_MASK_1M) {
         params = &hcc->params[0];
-        scanphy = &scansm->phy_data[PHY_UNCODED];
+        uncoded = &scansm->phy_data[PHY_UNCODED];
 
-        scanphy->scan_itvl = params->scan_itvl;
-        scanphy->scan_window = params->scan_window;
-        scanphy->scan_type = BLE_SCAN_TYPE_INITIATE;
-        scanphy->scan_filt_policy = hcc->filter_policy;
+        uncoded->scan_itvl = params->scan_itvl;
+        uncoded->scan_window = params->scan_window;
+        uncoded->scan_type = BLE_SCAN_TYPE_INITIATE;
+        uncoded->scan_filt_policy = hcc->filter_policy;
         scansm->cur_phy = PHY_UNCODED;
     }
 
     if (hcc->init_phy_mask & BLE_PHY_MASK_CODED) {
         params = &hcc->params[2];
-        scanphy = &scansm->phy_data[PHY_CODED];
+        coded = &scansm->phy_data[PHY_CODED];
 
-        scanphy->scan_itvl = params->scan_itvl;
-        scanphy->scan_window = params->scan_window;
-        scanphy->scan_type = BLE_SCAN_TYPE_INITIATE;
-        scanphy->scan_filt_policy = hcc->filter_policy;
+        coded->scan_itvl = params->scan_itvl;
+        coded->scan_window = params->scan_window;
+        coded->scan_type = BLE_SCAN_TYPE_INITIATE;
+        coded->scan_filt_policy = hcc->filter_policy;
         if (scansm->cur_phy == PHY_NOT_CONFIGURED) {
             scansm->cur_phy = PHY_CODED;
         } else {
@@ -2905,6 +2911,18 @@ ble_ll_scan_ext_initiator_start(struct 
hci_ext_create_conn *hcc,
         }
     }
 
+    /* If host request for continuous scan if 2 PHYs are requested, we split
+     * time on two
+     */
+    if ((scansm->next_phy != PHY_NOT_CONFIGURED) &&
+                ((uncoded->scan_itvl == uncoded->scan_window) ||
+                (coded->scan_itvl == coded-> scan_window))) {
+
+        uncoded->scan_itvl *= 2;
+        coded-> scan_itvl = uncoded->scan_itvl;
+        coded->scan_window = uncoded->scan_window;
+    }
+
     rc = ble_ll_scan_sm_start(scansm);
     if (sm == NULL) {
         return rc;


 

----------------------------------------------------------------
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:
us...@infra.apache.org


With regards,
Apache Git Services

Reply via email to