Skip to content

Commit

Permalink
nimble/ll: Allow to locally update connection min/max CE length
Browse files Browse the repository at this point in the history
Updating Min/Max CE Length can be done without triggering LL procedure.
We can do that if current connection parameters fits parameters
parameters provided in HCI command. Note that this is also valid
for Connections Strict Scheduling.
  • Loading branch information
sjanc committed Apr 21, 2023
1 parent 357f721 commit e08a13f
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 15 deletions.
2 changes: 1 addition & 1 deletion nimble/controller/include/controller/ble_ll_hci.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ extern "C" {
*/
#define BLE_LL_CFG_NUM_HCI_CMD_PKTS (1)

typedef void (*ble_ll_hci_post_cmd_complete_cb)(void);
typedef void (*ble_ll_hci_post_cmd_complete_cb)(void *user_data);

#if MYNEWT_VAL(BLE_LL_HCI_VS)
typedef int (* ble_ll_hci_vs_cb_t)(uint16_t ocf,
Expand Down
2 changes: 1 addition & 1 deletion nimble/controller/include/controller/ble_ll_sync.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ struct ble_ll_scan_addr_data;
struct ble_ll_sync_sm;

int ble_ll_sync_create(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_sync_cancel(ble_ll_hci_post_cmd_complete_cb *post_cmd_cb);
int ble_ll_sync_cancel(ble_ll_hci_post_cmd_complete_cb *post_cmd_cb, void **cb_user_data);
int ble_ll_sync_terminate(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_sync_list_add(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_sync_list_remove(const uint8_t *cmdbuf, uint8_t len);
Expand Down
58 changes: 55 additions & 3 deletions nimble/controller/src/ble_ll_conn_hci.c
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,34 @@ ble_ll_conn_hci_read_rem_features(const uint8_t *cmdbuf, uint8_t len)
return BLE_ERR_SUCCESS;
}

static bool
ble_ll_conn_params_in_range(struct ble_ll_conn_sm *connsm,
const struct ble_hci_le_conn_update_cp *cmd)
{
if (!IN_RANGE(connsm->conn_itvl, le16toh(cmd->conn_itvl_min),
le16toh(cmd->conn_itvl_max))) {
return false;
}

if (connsm->periph_latency != le16toh(cmd->conn_latency)) {
return false;
}

if (connsm->supervision_tmo != le16toh(cmd->supervision_timeout)) {
return false;
}

return true;
}

static void
ble_ll_conn_hci_update_complete_event(void *user_data)
{
struct ble_ll_conn_sm *connsm = user_data;

ble_ll_hci_ev_conn_update(connsm, BLE_ERR_SUCCESS);
}

/**
* Called to process a connection update command.
*
Expand All @@ -954,14 +982,16 @@ ble_ll_conn_hci_read_rem_features(const uint8_t *cmdbuf, uint8_t len)
* @return int
*/
int
ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len)
ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len,
ble_ll_hci_post_cmd_complete_cb *post_cmd_cb, void **cb_user_data)
{
const struct ble_hci_le_conn_update_cp *cmd = (const void *) cmdbuf;
int rc;
uint8_t ctrl_proc;
uint16_t handle;
struct ble_ll_conn_sm *connsm;
struct hci_conn_update *hcu;
uint16_t max_ce_len;

/*
* XXX: must deal with peripheral not supporting this feature and using
Expand All @@ -979,6 +1009,27 @@ ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len)
return BLE_ERR_UNK_CONN_ID;
}

/* if current connection parameters fit updated values we don't have to
* trigger LL procedure and just update local values (Min/Max CE Length)
*
* Note that this is also allowed for CSS as nothing changes WRT connections
* scheduling.
*/
if (ble_ll_conn_params_in_range(connsm, cmd)) {
max_ce_len = le16toh(cmd->max_ce_len);

if (le16toh(cmd->min_ce_len) > max_ce_len) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}

connsm->max_ce_len_ticks = ble_ll_tmr_u2t_up(max_ce_len * BLE_LL_CONN_CE_USECS);

*post_cmd_cb = ble_ll_conn_hci_update_complete_event;
*cb_user_data = connsm;

return BLE_ERR_SUCCESS;
}

#if MYNEWT_VAL(BLE_LL_CONN_STRICT_SCHED)
/* Do not allow connection update if css in enabled, we only allow to move
* anchor point (i.e. change slot) via dedicated HCI command.
Expand Down Expand Up @@ -1198,7 +1249,7 @@ ble_ll_conn_hci_param_nrr(const uint8_t *cmdbuf, uint8_t len,
* safe to use g_ble_ll_conn_comp_ev
*/
static void
ble_ll_conn_hci_cancel_conn_complete_event(void)
ble_ll_conn_hci_cancel_conn_complete_event(void *user_data)
{
BLE_LL_ASSERT(g_ble_ll_conn_comp_ev);

Expand All @@ -1216,7 +1267,7 @@ ble_ll_conn_hci_cancel_conn_complete_event(void)
* @return int
*/
int
ble_ll_conn_create_cancel(ble_ll_hci_post_cmd_complete_cb *post_cmd_cb)
ble_ll_conn_create_cancel(ble_ll_hci_post_cmd_complete_cb *post_cmd_cb, void **cb_user_data)
{
int rc;
struct ble_ll_conn_sm *connsm;
Expand All @@ -1237,6 +1288,7 @@ ble_ll_conn_create_cancel(ble_ll_hci_post_cmd_complete_cb *post_cmd_cb)
ble_ll_conn_end(connsm, BLE_ERR_UNK_CONN_ID);

*post_cmd_cb = ble_ll_conn_hci_cancel_conn_complete_event;
*cb_user_data = NULL;

rc = BLE_ERR_SUCCESS;
} else {
Expand Down
5 changes: 3 additions & 2 deletions nimble/controller/src/ble_ll_conn_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -198,13 +198,14 @@ void ble_ll_auth_pyld_tmo_event_send(struct ble_ll_conn_sm *connsm);
int ble_ll_conn_hci_disconnect_cmd(const struct ble_hci_lc_disconnect_cp *cmd);
int ble_ll_conn_hci_rd_rem_ver_cmd(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_conn_hci_create(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_conn_hci_update(const uint8_t *cmdbuf, uint8_t len,
ble_ll_hci_post_cmd_complete_cb *post_cmd_cb, void **cb_user_data);
int ble_ll_conn_hci_set_chan_class(const uint8_t *cmdbuf, uint8_t len);
int ble_ll_conn_hci_param_rr(const uint8_t *cmdbuf, uint8_t len,
uint8_t *rspbuf, uint8_t *rsplen);
int ble_ll_conn_hci_param_nrr(const uint8_t *cmdbuf, uint8_t len,
uint8_t *rspbuf, uint8_t *rsplen);
int ble_ll_conn_create_cancel(ble_ll_hci_post_cmd_complete_cb *post_cmd_cb);
int ble_ll_conn_create_cancel(ble_ll_hci_post_cmd_complete_cb *post_cmd_cb, void **cb_user_data);
void ble_ll_conn_num_comp_pkts_event_send(struct ble_ll_conn_sm *connsm);
void ble_ll_conn_comp_event_send(struct ble_ll_conn_sm *connsm, uint8_t status,
uint8_t *evbuf, struct ble_ll_adv_sm *advsm);
Expand Down
14 changes: 8 additions & 6 deletions nimble/controller/src/ble_ll_hci.c
Original file line number Diff line number Diff line change
Expand Up @@ -880,7 +880,8 @@ ble_ll_hci_le_set_host_chan_class(const uint8_t *cmdbuf, uint8_t len)
static int
ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf,
uint8_t *rspbuf, uint8_t *rsplen,
ble_ll_hci_post_cmd_complete_cb *cb)
ble_ll_hci_post_cmd_complete_cb *cb,
void **cb_user_data)
{
int rc;

Expand Down Expand Up @@ -960,7 +961,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf,
break;
case BLE_HCI_OCF_LE_CREATE_CONN_CANCEL:
if (len == 0) {
rc = ble_ll_conn_create_cancel(cb);
rc = ble_ll_conn_create_cancel(cb, cb_user_data);
}
break;
#endif
Expand All @@ -983,7 +984,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf,
break;
#if MYNEWT_VAL(BLE_LL_ROLE_PERIPHERAL) || MYNEWT_VAL(BLE_LL_ROLE_CENTRAL)
case BLE_HCI_OCF_LE_CONN_UPDATE:
rc = ble_ll_conn_hci_update(cmdbuf, len);
rc = ble_ll_conn_hci_update(cmdbuf, len, cb, cb_user_data);
break;
#endif
case BLE_HCI_OCF_LE_SET_HOST_CHAN_CLASS:
Expand Down Expand Up @@ -1187,7 +1188,7 @@ ble_ll_hci_le_cmd_proc(const uint8_t *cmdbuf, uint8_t len, uint16_t ocf,
break;
case BLE_HCI_OCF_LE_PERIODIC_ADV_CREATE_SYNC_CANCEL:
if (len == 0) {
rc = ble_ll_sync_cancel(cb);
rc = ble_ll_sync_cancel(cb, cb_user_data);
}
break;
case BLE_HCI_OCF_LE_PERIODIC_ADV_TERM_SYNC:
Expand Down Expand Up @@ -1751,6 +1752,7 @@ ble_ll_hci_cmd_proc(struct ble_npl_event *ev)
uint16_t opcode;
uint16_t ocf;
ble_ll_hci_post_cmd_complete_cb post_cb = NULL;
void *post_cb_user_data;
struct ble_hci_ev *hci_ev;
struct ble_hci_ev_command_status *cmd_status;
struct ble_hci_ev_command_complete *cmd_complete;
Expand Down Expand Up @@ -1817,7 +1819,7 @@ ble_ll_hci_cmd_proc(struct ble_npl_event *ev)
rc = ble_ll_hci_status_params_cmd_proc(cmd->data, cmd->length, ocf, rspbuf, &rsplen);
break;
case BLE_HCI_OGF_LE:
rc = ble_ll_hci_le_cmd_proc(cmd->data, cmd->length, ocf, rspbuf, &rsplen, &post_cb);
rc = ble_ll_hci_le_cmd_proc(cmd->data, cmd->length, ocf, rspbuf, &rsplen, &post_cb, &post_cb_user_data);
break;
#if MYNEWT_VAL(BLE_LL_HCI_VS)
case BLE_HCI_OGF_VENDOR:
Expand Down Expand Up @@ -1876,7 +1878,7 @@ ble_ll_hci_cmd_proc(struct ble_npl_event *ev)

/* Call post callback if set by command handler */
if (post_cb) {
post_cb();
post_cb(post_cb_user_data);
}

BLE_LL_DEBUG_GPIO(HCI_CMD, 0);
Expand Down
5 changes: 3 additions & 2 deletions nimble/controller/src/ble_ll_sync.c
Original file line number Diff line number Diff line change
Expand Up @@ -1559,13 +1559,13 @@ ble_ll_sync_create(const uint8_t *cmdbuf, uint8_t len)
}

static void
ble_ll_sync_cancel_complete_event(void)
ble_ll_sync_cancel_complete_event(void *user_data)
{
ble_ll_sync_est_event_failed(BLE_ERR_OPERATION_CANCELLED);
}

int
ble_ll_sync_cancel(ble_ll_hci_post_cmd_complete_cb *post_cmd_cb)
ble_ll_sync_cancel(ble_ll_hci_post_cmd_complete_cb *post_cmd_cb, void **cb_user_data)
{
struct ble_ll_sync_sm *sm;
os_sr_t sr;
Expand Down Expand Up @@ -1597,6 +1597,7 @@ ble_ll_sync_cancel(ble_ll_hci_post_cmd_complete_cb *post_cmd_cb)

/* g_ble_ll_sync_create_comp_ev will be cleared by this callback */
*post_cmd_cb = ble_ll_sync_cancel_complete_event;
*cb_user_data = NULL;

return BLE_ERR_SUCCESS;
}
Expand Down

0 comments on commit e08a13f

Please sign in to comment.