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

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


The following commit(s) were added to refs/heads/master by this push:
     new 3eb3f0a0 nimble/ll: Improve scheduling of 1st BIG event
3eb3f0a0 is described below

commit 3eb3f0a0aa61207807e89c63b0dc2e38b3cc5947
Author: Andrzej Kaczmarek <andrzej.kaczma...@codecoup.pl>
AuthorDate: Tue Jan 31 00:53:59 2023 +0100

    nimble/ll: Improve scheduling of 1st BIG event
    
    This improves BIG scheduling in case periodic advertising interval is
    an integer multiple of ISO interval. In such case placing BIG event
    directly before periodic advertising event makes sure both won't overlap
    even if periodic advertising data changes in future.
    
    Note that there may still be conflicts with other instances and this
    patch doesn't resolve that.
---
 nimble/controller/include/controller/ble_ll_adv.h  |  3 ++
 .../controller/include/controller/ble_ll_sched.h   |  2 +-
 nimble/controller/src/ble_ll_adv.c                 | 18 ++++++++++
 nimble/controller/src/ble_ll_iso_big.c             | 38 ++++++++++++++++------
 nimble/controller/src/ble_ll_sched.c               |  4 +--
 5 files changed, 52 insertions(+), 13 deletions(-)

diff --git a/nimble/controller/include/controller/ble_ll_adv.h 
b/nimble/controller/include/controller/ble_ll_adv.h
index ba17ed5e..b861d19d 100644
--- a/nimble/controller/include/controller/ble_ll_adv.h
+++ b/nimble/controller/include/controller/ble_ll_adv.h
@@ -201,6 +201,9 @@ int ble_ll_adv_periodic_set_info_transfer(const uint8_t 
*cmdbuf, uint8_t len,
 
 /* Get advertising instance with periodic advertising configured */
 struct ble_ll_adv_sm *ble_ll_adv_sync_get(uint8_t handle);
+/* Get periodic advertising event scheduled time */
+int ble_ll_adv_sync_sched_get(struct ble_ll_adv_sm *advsm,
+                              uint32_t *start_time, uint32_t *end_time);
 
 #if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
 struct ble_ll_iso_big;
diff --git a/nimble/controller/include/controller/ble_ll_sched.h 
b/nimble/controller/include/controller/ble_ll_sched.h
index cceb96ce..5daa647f 100644
--- a/nimble/controller/include/controller/ble_ll_sched.h
+++ b/nimble/controller/include/controller/ble_ll_sched.h
@@ -219,7 +219,7 @@ uint32_t ble_ll_sched_css_get_conn_interval_us(void);
 #endif
 
 #if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
-int ble_ll_sched_iso_big(struct ble_ll_sched_item *sch, int first);
+int ble_ll_sched_iso_big(struct ble_ll_sched_item *sch, int first, int fixed);
 #endif /* BLE_LL_ISO_BROADCASTER */
 
 #ifdef __cplusplus
diff --git a/nimble/controller/src/ble_ll_adv.c 
b/nimble/controller/src/ble_ll_adv.c
index 7056c8de..db07f896 100644
--- a/nimble/controller/src/ble_ll_adv.c
+++ b/nimble/controller/src/ble_ll_adv.c
@@ -5309,6 +5309,24 @@ ble_ll_adv_sync_get(uint8_t handle)
     return advsm;
 }
 
+int
+ble_ll_adv_sync_sched_get(struct ble_ll_adv_sm *advsm, uint32_t *start_time,
+                          uint32_t *end_time)
+{
+    struct ble_ll_adv_sync *sync;
+
+    if (!advsm || !advsm->periodic_adv_active) {
+        return -EIO;
+    }
+
+    sync = SYNC_CURRENT(advsm);
+
+    *start_time = sync->sch.start_time + g_ble_ll_sched_offset_ticks;
+    *end_time = sync->sch.end_time;
+
+    return 0;
+}
+
 int
 ble_ll_adv_sync_big_add(struct ble_ll_adv_sm *advsm,
                         struct ble_ll_iso_big *big)
diff --git a/nimble/controller/src/ble_ll_iso_big.c 
b/nimble/controller/src/ble_ll_iso_big.c
index 31bcd21f..b836fed0 100644
--- a/nimble/controller/src/ble_ll_iso_big.c
+++ b/nimble/controller/src/ble_ll_iso_big.c
@@ -498,7 +498,7 @@ ble_ll_iso_big_event_done(struct ble_ll_iso_big *big)
         }
 
         /* XXX this should always succeed since we preempt anything for now */
-        rc = ble_ll_sched_iso_big(&big->sch, 0);
+        rc = ble_ll_sched_iso_big(&big->sch, 0, 0);
         assert(rc == 0);
     } while (rc < 0);
 
@@ -1029,18 +1029,36 @@ ble_ll_iso_big_create(uint8_t big_handle, uint8_t 
adv_handle, uint8_t num_bis,
      * not enough for some phys to run scheduler item.
      */
 
-    /* Schedule 1st event a bit in future */
-    /* FIXME schedule 6ms in the future to avoid conflict with periodic
-     *       advertising when both are started at the same time; we should
-     *       select this value in some smart way later...
-     */
-    big->sch.start_time = ble_ll_tmr_get() + ble_ll_tmr_u2t(6000);
+    uint32_t start_time, end_time, big_time;
+    uint32_t sync_delay_ticks = ble_ll_tmr_u2t_up(big->sync_delay);
+    uint32_t iso_interval_ticks = ble_ll_tmr_u2t_up(big->iso_interval * 1250);
+    int big_event_fixed;
+
+    rc = ble_ll_adv_sync_sched_get(big->advsm, &start_time, &end_time);
+    if (rc) {
+        /* Set 1st BIG one interval after "now", this ensures it's always
+         * scheduled in the future.
+         */
+        big_time = ble_ll_tmr_get() + iso_interval_ticks;
+        big_event_fixed = 0;
+    } else {
+        /* Set 1st BIG event directly before periodic advertising event, this
+         * way it will not overlap it even if periodic advertising data 
changes.
+         * Make sure it's in the future.
+         */
+        big_time = start_time - g_ble_ll_sched_offset_ticks - sync_delay_ticks 
- 1;
+        while (big_time - g_ble_ll_sched_offset_ticks < ble_ll_tmr_get()) {
+            big_time += iso_interval_ticks;
+        }
+        big_event_fixed = 1;
+    }
+
+    big->sch.start_time = big_time;
     big->sch.remainder = 0;
-    big->sch.end_time = big->sch.start_time +
-                        ble_ll_tmr_u2t_up(big->sync_delay) + 1;
+    big->sch.end_time = big->sch.start_time + sync_delay_ticks + 1;
     big->sch.start_time -= g_ble_ll_sched_offset_ticks;
 
-    rc = ble_ll_sched_iso_big(&big->sch, 1);
+    rc = ble_ll_sched_iso_big(&big->sch, 1, big_event_fixed);
     if (rc < 0) {
         ble_ll_iso_big_free(big);
         return -EFAULT;
diff --git a/nimble/controller/src/ble_ll_sched.c 
b/nimble/controller/src/ble_ll_sched.c
index 8e8cee18..5cd01e04 100644
--- a/nimble/controller/src/ble_ll_sched.c
+++ b/nimble/controller/src/ble_ll_sched.c
@@ -844,14 +844,14 @@ ble_ll_sched_adv_resched_pdu(struct ble_ll_sched_item 
*sch)
 
 #if MYNEWT_VAL(BLE_LL_ISO_BROADCASTER)
 int
-ble_ll_sched_iso_big(struct ble_ll_sched_item *sch, int first)
+ble_ll_sched_iso_big(struct ble_ll_sched_item *sch, int first, int fixed)
 {
     os_sr_t sr;
     int rc;
 
     OS_ENTER_CRITICAL(sr);
 
-    if (first) {
+    if (first && !fixed) {
         rc = ble_ll_sched_insert(sch, BLE_LL_SCHED_MAX_DELAY_ANY, 
preempt_none);
     } else {
         /* XXX provide better strategy for preemption */

Reply via email to