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 <andrzej.kaczma...@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;