You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by an...@apache.org on 2022/06/22 13:18:30 UTC

[mynewt-nimble] 10/12: nimble/ll/css: Allow to change state in runtime

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

commit 42ad7e1c787f794510865b53bbe01ea620e44b34
Author: Andrzej Kaczmarek <an...@codecoup.pl>
AuthorDate: Tue Jun 14 12:05:37 2022 +0200

    nimble/ll/css: Allow to change state in runtime
    
    This allows to control css state in runtime via HCI command. Default is
    disabled.
---
 .../controller/include/controller/ble_ll_sched.h   |  8 ++
 nimble/controller/src/ble_ll_conn.c                | 27 +++++--
 nimble/controller/src/ble_ll_conn_hci.c            |  3 +-
 nimble/controller/src/ble_ll_ctrl.c                |  3 +-
 nimble/controller/src/ble_ll_hci_vs.c              | 28 ++++++-
 nimble/controller/src/ble_ll_sched.c               | 93 +++++++++++++---------
 nimble/include/nimble/hci_common.h                 |  9 ++-
 7 files changed, 122 insertions(+), 49 deletions(-)

diff --git a/nimble/controller/include/controller/ble_ll_sched.h b/nimble/controller/include/controller/ble_ll_sched.h
index 7dac8495..e50ebc5c 100644
--- a/nimble/controller/include/controller/ble_ll_sched.h
+++ b/nimble/controller/include/controller/ble_ll_sched.h
@@ -179,9 +179,16 @@ int ble_ll_sched_dtm(struct ble_ll_sched_item *sch);
 #if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED)
 void ble_ll_sched_css_set_params(uint32_t slot_us, uint32_t period_slots);
 #endif
+void ble_ll_sched_css_set_enabled(uint8_t enabled);
 void ble_ll_sched_css_update_anchor(struct ble_ll_conn_sm *connsm);
 void ble_ll_sched_css_set_conn_anchor(struct ble_ll_conn_sm *connsm);
 #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED)
+static inline bool
+ble_ll_sched_css_is_enabled(void)
+{
+    return true;
+}
+
 static inline uint32_t
 ble_ll_sched_css_get_slot_us(void)
 {
@@ -201,6 +208,7 @@ ble_ll_sched_css_get_conn_interval_us(void)
            ble_ll_sched_css_get_slot_us() / 1250;
 }
 #else
+bool ble_ll_sched_css_is_enabled(void);
 uint32_t ble_ll_sched_css_get_slot_us(void);
 uint32_t ble_ll_sched_css_get_period_slots(void);
 uint32_t ble_ll_sched_css_get_conn_interval_us(void);
diff --git a/nimble/controller/src/ble_ll_conn.c b/nimble/controller/src/ble_ll_conn.c
index 802429af..d25fca7a 100644
--- a/nimble/controller/src/ble_ll_conn.c
+++ b/nimble/controller/src/ble_ll_conn.c
@@ -1956,7 +1956,8 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm)
 
     /* Add to list of active connections */
 #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED)
-    if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) {
+    if (ble_ll_sched_css_is_enabled() &&
+        connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) {
         /* We will insert sorted by css_slot_idx to make finding free slot
          * easier.
          */
@@ -2355,7 +2356,8 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm)
     connsm->event_cntr = next_event_cntr;
 
 #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED)
-    if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) {
+    if (ble_ll_sched_css_is_enabled() &&
+        connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) {
         connsm->css_period_idx += event_cntr_diff;
 
         /* If this is non-reference connection, we calculate anchor point from
@@ -2414,7 +2416,8 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm)
 #endif
 
 #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED)
-        if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) {
+        if (ble_ll_sched_css_is_enabled() &&
+            connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) {
             BLE_LL_ASSERT(connsm->css_slot_idx_pending !=
                           BLE_LL_CONN_CSS_NO_SLOT);
 
@@ -2557,13 +2560,21 @@ ble_ll_conn_next_event(struct ble_ll_conn_sm *connsm)
      * Calculate ce end time. For a peripheral, we need to add window widening
      * and the transmit window if we still have one.
      */
-    if (MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED) &&
+#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED)
+    /* If css is enabled, use slot duration instead of conn_init_slots for
+     * reservation.
+     */
+    if (ble_ll_sched_css_is_enabled() &&
         connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) {
-        ce_duration = ble_ll_tmr_u2t(BLE_LL_SCHED_USECS_PER_SLOT);
+        ce_duration = ble_ll_tmr_u2t(ble_ll_sched_css_get_slot_us());
     } else {
         ce_duration = ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) *
                                      BLE_LL_SCHED_USECS_PER_SLOT);
     }
+#else
+    ce_duration = ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) *
+                                     BLE_LL_SCHED_USECS_PER_SLOT);
+#endif
 
 #if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL)
     if (connsm->conn_role == BLE_LL_CONN_ROLE_PERIPHERAL) {
@@ -2709,8 +2720,10 @@ ble_ll_conn_created(struct ble_ll_conn_sm *connsm, struct ble_mbuf_hdr *rxhdr)
 #if MYNEWT_VAL(BLE_LL_ROLE_CENTRAL)
         case BLE_LL_CONN_ROLE_CENTRAL:
 #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED)
-            ble_ll_sched_css_update_anchor(connsm);
-            ble_ll_conn_css_set_next_slot(BLE_LL_CONN_CSS_NO_SLOT);
+            if (ble_ll_sched_css_is_enabled()) {
+                ble_ll_sched_css_update_anchor(connsm);
+                ble_ll_conn_css_set_next_slot(BLE_LL_CONN_CSS_NO_SLOT);
+            }
 #endif
 
             evbuf = ble_ll_init_get_conn_comp_ev();
diff --git a/nimble/controller/src/ble_ll_conn_hci.c b/nimble/controller/src/ble_ll_conn_hci.c
index 4617d3a7..625d8d24 100644
--- a/nimble/controller/src/ble_ll_conn_hci.c
+++ b/nimble/controller/src/ble_ll_conn_hci.c
@@ -959,7 +959,8 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len)
     /* Do not allow connection update if css in enabled, we only allow to move
      * anchor point (i.e. change slot) via dedicated HCI command.
      */
-    if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) {
+    if (ble_ll_sched_css_is_enabled() &&
+        connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) {
         return BLE_ERR_CMD_DISALLOWED;
     }
 #endif
diff --git a/nimble/controller/src/ble_ll_ctrl.c b/nimble/controller/src/ble_ll_ctrl.c
index 07f30300..911673be 100644
--- a/nimble/controller/src/ble_ll_ctrl.c
+++ b/nimble/controller/src/ble_ll_ctrl.c
@@ -2246,7 +2246,8 @@ ble_ll_ctrl_rx_conn_param_req(struct ble_ll_conn_sm *connsm, uint8_t *dptr,
 
 #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED)
     /* Reject any attempts to change connection parameters by peripheral */
-    if (connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) {
+    if (ble_ll_sched_css_is_enabled() &&
+        connsm->conn_role == BLE_LL_CONN_ROLE_CENTRAL) {
         rsp_opcode = BLE_LL_CTRL_REJECT_IND_EXT;
         rspbuf[1] = BLE_LL_CTRL_CONN_PARM_REQ;
         rspbuf[2] = BLE_ERR_UNSUPPORTED;
diff --git a/nimble/controller/src/ble_ll_hci_vs.c b/nimble/controller/src/ble_ll_hci_vs.c
index f12657cc..7504f10d 100644
--- a/nimble/controller/src/ble_ll_hci_vs.c
+++ b/nimble/controller/src/ble_ll_hci_vs.c
@@ -149,7 +149,8 @@ ble_ll_hci_vs_css_configure(const uint8_t *cmdbuf, uint8_t cmdlen,
         return BLE_ERR_INV_HCI_CMD_PARMS;
     }
 
-    if (!SLIST_EMPTY(&g_ble_ll_conn_active_list)) {
+    if (ble_ll_sched_css_is_enabled() &&
+        !SLIST_EMPTY(&g_ble_ll_conn_active_list)) {
         return BLE_ERR_CTLR_BUSY;
     }
 
@@ -170,6 +171,29 @@ ble_ll_hci_vs_css_configure(const uint8_t *cmdbuf, uint8_t cmdlen,
 }
 #endif
 
+static int
+ble_ll_hci_vs_css_enable(const uint8_t *cmdbuf, uint8_t cmdlen,
+                         uint8_t *rspbuf, uint8_t *rsplen)
+{
+    const struct ble_hci_vs_css_enable_cp *cmd = (const void *)cmdbuf;
+
+    if (cmdlen != sizeof(*cmd)) {
+        return BLE_ERR_INV_HCI_CMD_PARMS;
+    }
+
+    if (!SLIST_EMPTY(&g_ble_ll_conn_active_list)) {
+        return BLE_ERR_CTLR_BUSY;
+    }
+
+    if (cmd->enable & 0xfe) {
+        return BLE_ERR_INV_HCI_CMD_PARMS;
+    }
+
+    ble_ll_sched_css_set_enabled(cmd->enable);
+
+    return BLE_ERR_SUCCESS;
+}
+
 static int
 ble_ll_hci_vs_css_set_next_slot(const uint8_t *cmdbuf, uint8_t cmdlen,
                                 uint8_t *rspbuf, uint8_t *rsplen)
@@ -257,6 +281,8 @@ ble_ll_hci_vs_css(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen,
     case BLE_HCI_VS_CSS_OP_CONFIGURE:
         return ble_ll_hci_vs_css_configure(cmdbuf, cmdlen, rspbuf, rsplen);
 #endif
+    case BLE_HCI_VS_CSS_OP_ENABLE:
+        return ble_ll_hci_vs_css_enable(cmdbuf, cmdlen, rspbuf, rsplen);
     case BLE_HCI_VS_CSS_OP_SET_NEXT_SLOT:
         return ble_ll_hci_vs_css_set_next_slot(cmdbuf, cmdlen, rspbuf, rsplen);
     case BLE_HCI_VS_CSS_OP_SET_CONN_SLOT:
diff --git a/nimble/controller/src/ble_ll_sched.c b/nimble/controller/src/ble_ll_sched.c
index 14cb954e..036a3518 100644
--- a/nimble/controller/src/ble_ll_sched.c
+++ b/nimble/controller/src/ble_ll_sched.c
@@ -47,6 +47,7 @@ int32_t g_ble_ll_sched_max_early;
 
 #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED)
 struct ble_ll_sched_css {
+    uint8_t enabled;
 #if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED)
     uint32_t slot_us;
     uint32_t period_slots;
@@ -408,15 +409,15 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm,
 {
 #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED)
     struct ble_ll_sched_css *css = &g_ble_ll_sched_css;
+    uint8_t rem_us;
 #endif
     struct ble_ll_sched_item *sch;
     uint32_t orig_start_time;
     uint32_t earliest_start;
-#if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED)
     uint32_t min_win_offset;
-#endif
     uint32_t max_delay;
     uint32_t adv_rxend;
+    bool calc_sch = true;
     os_sr_t sr;
     int rc;
 
@@ -499,51 +500,56 @@ ble_ll_sched_conn_central_new(struct ble_ll_conn_sm *connsm,
     orig_start_time = earliest_start - g_ble_ll_sched_offset_ticks;
 
 #if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED)
-    uint8_t rem_us;
+    if (ble_ll_sched_css_is_enabled()) {
+        OS_ENTER_CRITICAL(sr);
 
-    OS_ENTER_CRITICAL(sr);
+        if (!g_ble_ll_conn_css_ref) {
+            css->period_anchor_ticks = earliest_start;
+            css->period_anchor_rem_us = 0;
+            css->period_anchor_idx = 0;
+            css->period_anchor_slot_idx = connsm->css_slot_idx;
 
-    if (!g_ble_ll_conn_css_ref) {
-        css->period_anchor_ticks = earliest_start;
-        css->period_anchor_rem_us = 0;
-        css->period_anchor_idx = 0;
-        css->period_anchor_slot_idx = connsm->css_slot_idx;
+            connsm->css_period_idx = 0;
+            max_delay = connsm->conn_itvl_ticks;
+        } else {
+            connsm->css_period_idx = css->period_anchor_idx;
+            max_delay = 0;
+        }
 
-        connsm->css_period_idx = 0;
-        max_delay = connsm->conn_itvl_ticks;
-    } else {
-        connsm->css_period_idx = css->period_anchor_idx;
-        max_delay = 0;
-    }
+        ble_ll_sched_css_set_conn_anchor(connsm);
 
-    ble_ll_sched_css_set_conn_anchor(connsm);
+        sch->start_time = connsm->anchor_point - g_ble_ll_sched_offset_ticks;
+        sch->end_time = connsm->anchor_point;
+        sch->remainder = connsm->anchor_point_usecs;
 
-    sch->start_time = connsm->anchor_point - g_ble_ll_sched_offset_ticks;
-    sch->end_time = connsm->anchor_point;
-    sch->remainder = connsm->anchor_point_usecs;
+        OS_EXIT_CRITICAL(sr);
 
-    OS_EXIT_CRITICAL(sr);
+        rem_us = sch->remainder;
+        ble_ll_tmr_add(&sch->end_time, &rem_us, ble_ll_sched_css_get_slot_us());
+        if (rem_us == 0) {
+            sch->end_time--;
+        }
 
-    rem_us = sch->remainder;
-    ble_ll_tmr_add(&sch->end_time, &rem_us, ble_ll_sched_css_get_slot_us());
-    if (rem_us == 0) {
-        sch->end_time--;
+        calc_sch = false;
     }
-#else
-    sch->start_time = earliest_start - g_ble_ll_sched_offset_ticks;
-    sch->end_time = earliest_start +
-                    ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) *
-                                   BLE_LL_SCHED_USECS_PER_SLOT);
-
-    min_win_offset = ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_MIN_WIN_OFFSET) *
-                                    BLE_LL_SCHED_USECS_PER_SLOT);
-    sch->start_time += min_win_offset;
-    sch->end_time += min_win_offset;
-    sch->remainder = 0;
-
-    max_delay = connsm->conn_itvl_ticks - min_win_offset;
 #endif
 
+    if (calc_sch) {
+        sch->start_time = earliest_start - g_ble_ll_sched_offset_ticks;
+        sch->end_time = earliest_start +
+                        ble_ll_tmr_u2t(MYNEWT_VAL(BLE_LL_CONN_INIT_SLOTS) *
+                                       BLE_LL_SCHED_USECS_PER_SLOT);
+
+        min_win_offset = ble_ll_tmr_u2t(
+                MYNEWT_VAL(BLE_LL_CONN_INIT_MIN_WIN_OFFSET) *
+                BLE_LL_SCHED_USECS_PER_SLOT);
+        sch->start_time += min_win_offset;
+        sch->end_time += min_win_offset;
+        sch->remainder = 0;
+
+        max_delay = connsm->conn_itvl_ticks - min_win_offset;
+    }
+
     OS_ENTER_CRITICAL(sr);
 
     rc = ble_ll_sched_insert(sch, max_delay, preempt_none);
@@ -1185,6 +1191,13 @@ ble_ll_sched_css_set_params(uint32_t slot_us, uint32_t period_slots)
     g_ble_ll_sched_css.period_slots = period_slots;
 }
 #endif
+
+void
+ble_ll_sched_css_set_enabled(uint8_t enabled)
+{
+    g_ble_ll_sched_css.enabled = enabled;
+}
+
 void
 ble_ll_sched_css_update_anchor(struct ble_ll_conn_sm *connsm)
 {
@@ -1224,6 +1237,12 @@ ble_ll_sched_css_set_conn_anchor(struct ble_ll_conn_sm *connsm)
 }
 
 #if !MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED_FIXED)
+inline bool
+ble_ll_sched_css_is_enabled(void)
+{
+    return g_ble_ll_sched_css.enabled;
+}
+
 inline uint32_t
 ble_ll_sched_css_get_slot_us(void)
 {
diff --git a/nimble/include/nimble/hci_common.h b/nimble/include/nimble/hci_common.h
index 14225f50..881fe745 100644
--- a/nimble/include/nimble/hci_common.h
+++ b/nimble/include/nimble/hci_common.h
@@ -1110,12 +1110,17 @@ struct ble_hci_vs_css_configure_cp {
     uint32_t slot_us;
     uint32_t period_slots;
 } __attribute__((packed));
-#define BLE_HCI_VS_CSS_OP_SET_NEXT_SLOT                 0x02
+#define BLE_HCI_VS_CSS_OP_ENABLE                        0x02
+struct ble_hci_vs_css_enable_cp {
+    uint8_t opcode;
+    uint8_t enable;
+} __attribute__((packed));
+#define BLE_HCI_VS_CSS_OP_SET_NEXT_SLOT                 0x03
 struct ble_hci_vs_css_set_next_slot_cp {
     uint8_t opcode;
     uint16_t slot_idx;
 } __attribute__((packed));
-#define BLE_HCI_VS_CSS_OP_SET_CONN_SLOT                 0x03
+#define BLE_HCI_VS_CSS_OP_SET_CONN_SLOT                 0x04
 struct ble_hci_vs_css_set_conn_slot_cp {
     uint8_t opcode;
     uint16_t conn_handle;