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 21:38:44 UTC

[GitHub] andrzej-kaczmarek closed pull request #51: Multiple fixes to extended advertising

andrzej-kaczmarek closed pull request #51: Multiple fixes to extended advertising
URL: https://github.com/apache/mynewt-nimble/pull/51
 
 
   

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/src/ble_ll_adv.c b/nimble/controller/src/ble_ll_adv.c
index 7a1c2a5c..c2def946 100644
--- a/nimble/controller/src/ble_ll_adv.c
+++ b/nimble/controller/src/ble_ll_adv.c
@@ -185,6 +185,7 @@ struct ble_ll_adv_sm *g_ble_ll_cur_adv_sm;
 
 static void ble_ll_adv_make_done(struct ble_ll_adv_sm *advsm, struct ble_mbuf_hdr *hdr);
 static void ble_ll_adv_sm_init(struct ble_ll_adv_sm *advsm);
+static void ble_ll_adv_sm_stop_timeout(struct ble_ll_adv_sm *advsm);
 
 #if (MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_PRIVACY) == 1)
 static void
@@ -454,8 +455,11 @@ ble_ll_adv_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte)
     dptr += BLE_LL_EXT_ADV_DATA_INFO_SIZE;
 
     /* AuxPtr */
-    assert(AUX_CURRENT(advsm)->sch.enqueued);
-    offset = AUX_CURRENT(advsm)->start_time - advsm->adv_pdu_start_time;
+    if (AUX_CURRENT(advsm)->sch.enqueued) {
+        offset = AUX_CURRENT(advsm)->start_time - advsm->adv_pdu_start_time;
+    } else {
+        offset = 0;
+    }
     ble_ll_adv_put_aux_ptr(advsm, offset, dptr);
 
     return BLE_LL_EXT_ADV_HDR_LEN + ext_hdr_len;
@@ -523,9 +527,14 @@ ble_ll_adv_aux_pdu_make(uint8_t *dptr, void *pducb_arg, uint8_t *hdr_byte)
     }
 
     if (aux->ext_hdr & (1 << BLE_LL_EXT_ADV_AUX_PTR_BIT)) {
-        assert(AUX_NEXT(advsm)->sch.enqueued);
-
-        if (advsm->rx_ble_hdr) {
+        if (!AUX_NEXT(advsm)->sch.enqueued) {
+            /*
+             * Trim data here in case we do not have next aux scheduled. This
+             * can happen if next aux was outside advertising set period and
+             * was removed from scheduler.
+             */
+            offset = 0;
+        } else if (advsm->rx_ble_hdr) {
             offset = advsm->rx_ble_hdr->rem_usecs +
                      ble_ll_pdu_tx_time_get(12, advsm->sec_phy) + BLE_LL_IFS + 30;
             offset = AUX_NEXT(advsm)->start_time - advsm->rx_ble_hdr->beg_cputime -
@@ -1183,7 +1192,6 @@ ble_ll_adv_aux_schedule_next(struct ble_ll_adv_sm *advsm)
 
     ble_ll_adv_aux_calculate(advsm, aux_next, next_aux_data_offset);
     max_usecs = ble_ll_pdu_tx_time_get(aux_next->payload_len, advsm->sec_phy);
-    max_usecs += XCVR_PROC_DELAY_USECS;
 
     aux_next->start_time = aux->sch.end_time +
                           ble_ll_usecs_to_ticks_round_up(BLE_LL_MAFS);
@@ -1191,8 +1199,18 @@ ble_ll_adv_aux_schedule_next(struct ble_ll_adv_sm *advsm)
     sch = &aux_next->sch;
     sch->start_time = aux_next->start_time - g_ble_ll_sched_offset_ticks;
     sch->remainder = 0;
-    sch->end_time = aux_next->start_time + os_cputime_usecs_to_ticks(max_usecs);
+    sch->end_time = aux_next->start_time +
+                    ble_ll_usecs_to_ticks_round_up(max_usecs);
     ble_ll_sched_adv_new(&aux_next->sch, ble_ll_adv_aux_scheduled, aux_next);
+
+    /*
+     * In case duration is set for advertising set we need to check if newly
+     * scheduled aux will fit inside duration. If not, remove it from scheduler
+     * so advertising will stop after current aux.
+     */
+    if (advsm->duration && (aux_next->sch.end_time > advsm->adv_end_time)) {
+        ble_ll_sched_rmv_elem(&aux_next->sch);
+    }
 }
 
 static void
@@ -1242,16 +1260,10 @@ ble_ll_adv_aux_schedule_first(struct ble_ll_adv_sm *advsm)
         max_usecs = ble_ll_pdu_tx_time_get(aux->payload_len, advsm->sec_phy);
     }
 
-    /*
-     * XXX: For now, just schedule some additional time so we insure we have
-     * enough time to do everything we want.
-     */
-    max_usecs += XCVR_PROC_DELAY_USECS;
-
     sch = &aux->sch;
     sch->start_time = aux->start_time - g_ble_ll_sched_offset_ticks;
     sch->remainder = 0;
-    sch->end_time = aux->start_time + os_cputime_usecs_to_ticks(max_usecs);
+    sch->end_time = aux->start_time + ble_ll_usecs_to_ticks_round_up(max_usecs);
     ble_ll_sched_adv_new(sch, ble_ll_adv_aux_scheduled, aux);
 
 }
@@ -1315,6 +1327,16 @@ ble_ll_adv_aux_schedule(struct ble_ll_adv_sm *advsm)
     ble_ll_adv_aux_set_start_time(advsm);
     ble_ll_adv_aux_schedule_first(advsm);
     ble_ll_adv_aux_schedule_next(advsm);
+
+    /*
+     * In case duration is set for advertising set we need to check if at least
+     * 1st aux will fit inside duration. If not, stop advertising now so we do
+     * not start extended advertising event which we cannot finish in time.
+     */
+    if (advsm->duration &&
+            (AUX_CURRENT(advsm)->sch.end_time > advsm->adv_end_time)) {
+        ble_ll_adv_sm_stop_timeout(advsm);
+    }
 }
 #endif
 
@@ -1545,6 +1567,29 @@ ble_ll_adv_sm_stop(struct ble_ll_adv_sm *advsm)
     }
 }
 
+static void
+ble_ll_adv_sm_stop_timeout(struct ble_ll_adv_sm *advsm)
+{
+#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
+    ble_ll_hci_ev_send_adv_set_terminated(BLE_ERR_DIR_ADV_TMO,
+                                          advsm->adv_instance, 0,
+                                          advsm->events);
+#endif
+
+    /*
+     * For high duty directed advertising we need to send connection
+     * complete event with proper status
+     */
+    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) {
+        ble_ll_conn_comp_event_send(NULL, BLE_ERR_DIR_ADV_TMO,
+                                    advsm->conn_comp_ev, advsm);
+        advsm->conn_comp_ev = NULL;
+    }
+
+    /* Disable advertising */
+    ble_ll_adv_sm_stop(advsm);
+}
+
 static void
 ble_ll_adv_scheduled(struct ble_ll_adv_sm *advsm, uint32_t sch_start, void *arg)
 {
@@ -2866,6 +2911,9 @@ ble_ll_adv_drop_event(struct ble_ll_adv_sm *advsm)
 #if MYNEWT_VAL(BLE_LL_CFG_FEAT_LL_EXT_ADV)
     ble_ll_sched_rmv_elem(&advsm->aux[0].sch);
     ble_ll_sched_rmv_elem(&advsm->aux[1].sch);
+
+    os_eventq_remove(&g_ble_ll_data.ll_evq, &advsm->adv_sec_txdone_ev);
+    advsm->aux_active = 0;
 #endif
 
     advsm->adv_chan = ble_ll_adv_final_chan(advsm);
@@ -3040,37 +3088,16 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm)
          */
         if ((advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_LEGACY) &&
                         (advsm->flags & BLE_LL_ADV_SM_FLAG_ADV_TERMINATE_EVT)) {
-            ble_ll_hci_ev_send_adv_set_terminated(BLE_ERR_DIR_ADV_TMO,
-                                                  advsm->adv_instance, 0, 0);
-
-            /*
-             * For high duty directed advertising we need to send connection
-             * complete event with proper status
-             */
-            if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) {
-                ble_ll_conn_comp_event_send(NULL, BLE_ERR_DIR_ADV_TMO,
-                                            advsm->conn_comp_ev, advsm);
-                advsm->conn_comp_ev = NULL;
-            }
-
-            /* Disable advertising */
-            advsm->adv_enabled = 0;
-            ble_ll_scan_chk_resume();
+            ble_ll_adv_sm_stop_timeout(advsm);
         }
 
         return;
     }
 #else
-    if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) {
-        if (advsm->adv_pdu_start_time >= advsm->adv_end_time) {
-            /* Disable advertising */
-            advsm->adv_enabled = 0;
-            ble_ll_conn_comp_event_send(NULL, BLE_ERR_DIR_ADV_TMO,
-                                        advsm->conn_comp_ev, advsm);
-            advsm->conn_comp_ev = NULL;
-            ble_ll_scan_chk_resume();
-            return;
-        }
+    if ((advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) &&
+            (advsm->adv_pdu_start_time >= advsm->adv_end_time)) {
+        ble_ll_adv_sm_stop_timeout(advsm);
+        return;
     }
 #endif
 
@@ -3086,8 +3113,7 @@ ble_ll_adv_done(struct ble_ll_adv_sm *advsm)
                                                   advsm->events);
 
             /* Disable advertising */
-            advsm->adv_enabled = 0;
-            ble_ll_scan_chk_resume();
+            ble_ll_adv_sm_stop(advsm);
         }
 
         return;
@@ -3142,9 +3168,9 @@ ble_ll_adv_sec_done(struct ble_ll_adv_sm *advsm)
     assert(advsm->aux_active);
 
     aux = AUX_CURRENT(advsm);
+    aux_next = AUX_NEXT(advsm);
 
     if (advsm->aux_not_scanned) {
-        aux_next = AUX_NEXT(advsm);
         ble_ll_sched_rmv_elem(&aux_next->sch);
     }
 
@@ -3159,7 +3185,7 @@ ble_ll_adv_sec_done(struct ble_ll_adv_sm *advsm)
     }
 
     /* If we have next AUX scheduled, try to schedule another one */
-    if (AUX_NEXT(advsm)->sch.enqueued) {
+    if (aux_next->sch.enqueued) {
         advsm->aux_index ^= 1;
         advsm->aux_first_pdu = 0;
         ble_ll_adv_aux_schedule_next(advsm);
@@ -3170,34 +3196,18 @@ ble_ll_adv_sec_done(struct ble_ll_adv_sm *advsm)
     ble_ll_scan_chk_resume();
 
     /* Check if advertising timed out */
-    if ((advsm->duration && aux->start_time >= advsm->adv_end_time) &&
-                    (advsm->flags & BLE_LL_ADV_SM_FLAG_ADV_TERMINATE_EVT)) {
-        ble_ll_hci_ev_send_adv_set_terminated(BLE_ERR_DIR_ADV_TMO,
-                                              advsm->adv_instance, 0, 0);
-
-        /*
-         * For high duty directed advertising we need to send connection
-         * complete event with proper status
-         */
-        if (advsm->props & BLE_HCI_LE_SET_EXT_ADV_PROP_HD_DIRECTED) {
-            ble_ll_conn_comp_event_send(NULL, BLE_ERR_DIR_ADV_TMO,
-                                        advsm->conn_comp_ev, advsm);
-            advsm->conn_comp_ev = NULL;
-        }
-
-        /* Disable advertising */
-        advsm->adv_enabled = 0;
+    if (advsm->duration && (advsm->adv_pdu_start_time >= advsm->adv_end_time)) {
+        ble_ll_adv_sm_stop_timeout(advsm);
         return;
     }
 
-    if ((advsm->events_max && (advsm->events >= advsm->events_max)) &&
-                    (advsm->flags & BLE_LL_ADV_SM_FLAG_ADV_TERMINATE_EVT)) {
+    if (advsm->events_max && (advsm->events >= advsm->events_max)) {
         ble_ll_hci_ev_send_adv_set_terminated(BLE_RR_LIMIT_REACHED,
                                               advsm->adv_instance, 0,
                                               advsm->events);
-         /* Disable advertising */
-         advsm->adv_enabled = 0;
-         return;
+        /* Disable advertising */
+        ble_ll_adv_sm_stop(advsm);
+        return;
     }
 
     advsm->aux_active = 0;
diff --git a/nimble/host/include/host/ble_gap.h b/nimble/host/include/host/ble_gap.h
index 4dbf3c5f..6170f63f 100644
--- a/nimble/host/include/host/ble_gap.h
+++ b/nimble/host/include/host/ble_gap.h
@@ -384,6 +384,14 @@ struct ble_gap_event {
             uint8_t instance;
             /** The handle of the relevant connection - valid if reason=0 */
             uint16_t conn_handle;
+            /**
+             * Number of completed extended advertising events
+             *
+             * This field is only valid if non-zero max_events was passed to
+             * ble_gap_ext_adv_start() and advertising completed due to duration
+             * timeout or max events transmitted.
+             * */
+            uint8_t num_ext_adv_events;
 #endif
         } adv_complete;
 
diff --git a/nimble/host/src/ble_gap.c b/nimble/host/src/ble_gap.c
index 6c79842a..3ce763d7 100644
--- a/nimble/host/src/ble_gap.c
+++ b/nimble/host/src/ble_gap.c
@@ -701,7 +701,8 @@ ble_gap_slave_extract_cb(uint8_t instance,
 }
 
 static void
-ble_gap_adv_finished(uint8_t instance, int reason, uint16_t conn_handle)
+ble_gap_adv_finished(uint8_t instance, int reason, uint16_t conn_handle,
+                     uint8_t num_events)
 {
     struct ble_gap_event event;
     ble_gap_event_fn *cb;
@@ -715,6 +716,7 @@ ble_gap_adv_finished(uint8_t instance, int reason, uint16_t conn_handle)
 #if MYNEWT_VAL(BLE_EXT_ADV)
         event.adv_complete.instance = instance;
         event.adv_complete.conn_handle = conn_handle;
+        event.adv_complete.num_ext_adv_events = num_events;
 #endif
         cb(&event, cb_arg);
     }
@@ -1284,7 +1286,8 @@ ble_gap_rx_adv_set_terminated(struct hci_le_adv_set_terminated *evt)
         conn_handle = evt->conn_handle;
     }
 
-    ble_gap_adv_finished(evt->adv_handle, reason, conn_handle);
+    ble_gap_adv_finished(evt->adv_handle, reason, conn_handle,
+                         evt->completed_events);
 }
 #endif
 
diff --git a/nimble/syscfg.yml b/nimble/syscfg.yml
index 53d5898c..11a5bd52 100644
--- a/nimble/syscfg.yml
+++ b/nimble/syscfg.yml
@@ -56,5 +56,5 @@ syscfg.defs:
         description: >
             This allows to configure maximum size of advertising data and
             scan response data used in LE Advertising Extensions.
-            Valid range 31-238.
+            Valid range 31-1650.
         value: 31


 

----------------------------------------------------------------
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