nimble/ll/css: Allow to change state in runtime

This allows to control css state in runtime via HCI command. Default is
disabled.
This commit is contained in:
Andrzej Kaczmarek
2022-06-22 15:18:14 +02:00
parent 277fd466b8
commit 42ad7e1c78
7 changed files with 126 additions and 53 deletions
@@ -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);
+20 -7
View File
@@ -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();
+2 -1
View File
@@ -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
+2 -1
View File
@@ -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;
+27 -1
View File
@@ -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:
+60 -41
View File
@@ -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);
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);
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;
}
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;
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--;
}
#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)
{
+7 -2
View File
@@ -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;