nimble/ll: Add vs command to change all data length parameters

This commit is contained in:
Andrzej Kaczmarek
2022-08-04 15:09:55 +02:00
parent 3de15c9615
commit 5ea8badc46
11 changed files with 180 additions and 100 deletions
@@ -596,10 +596,6 @@ int ble_ll_set_host_feat(const uint8_t *cmdbuf, uint8_t len);
/* Read set of states supported by the Link Layer */
uint64_t ble_ll_read_supp_states(void);
/* Check if octets and time are valid. Returns 0 if not valid */
int ble_ll_chk_txrx_octets(uint16_t octets);
int ble_ll_chk_txrx_time(uint16_t time);
/* Random numbers */
int ble_ll_rand_init(void);
void ble_ll_rand_sample(uint8_t rnum);
@@ -230,6 +230,7 @@ struct ble_ll_conn_sm
uint16_t ota_max_rx_time;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
uint16_t host_req_max_tx_time;
uint16_t host_req_max_rx_time;
#endif
#if (BLE_LL_BT5_PHY_SUPPORTED == 1)
@@ -83,6 +83,9 @@ bool ble_ll_hci_adv_mode_ext(void);
/* Get TX power compensation rounded to integer dB */
int8_t ble_ll_get_tx_pwr_compensation(void);
/* Check if max octets/time are within allowed range */
int ble_ll_hci_check_dle(uint16_t max_octets, uint16_t max_time);
#if MYNEWT_VAL(BLE_LL_HCI_VS)
void ble_ll_hci_vs_register(struct ble_ll_hci_vs_cmd *cmds, uint32_t num_cmds);
#endif
-30
View File
@@ -503,36 +503,6 @@ rxpdu_alloc_fail:
return NULL;
}
int
ble_ll_chk_txrx_octets(uint16_t octets)
{
int rc;
if ((octets < BLE_LL_CONN_SUPP_BYTES_MIN) ||
(octets > BLE_LL_CONN_SUPP_BYTES_MAX)) {
rc = 0;
} else {
rc = 1;
}
return rc;
}
int
ble_ll_chk_txrx_time(uint16_t time)
{
int rc;
if ((time < BLE_LL_CONN_SUPP_TIME_MIN) ||
(time > BLE_LL_CONN_SUPP_TIME_MAX)) {
rc = 0;
} else {
rc = 1;
}
return rc;
}
/**
* Checks to see if the address is a resolvable private address.
*
+53
View File
@@ -1798,6 +1798,58 @@ ble_ll_conn_central_init(struct ble_ll_conn_sm *connsm,
}
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT)
int
ble_ll_conn_set_data_len(struct ble_ll_conn_sm *connsm,
uint16_t tx_octets, uint16_t tx_time,
uint16_t rx_octets, uint16_t rx_time)
{
int init_dle = 0;
/* Note: octets/time shall be checked by caller! */
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
/* Keep original values requested by host since we may want to recalculate
* after PHY changes between coded and uncoded.
*/
connsm->host_req_max_tx_time = tx_time;
connsm->host_req_max_rx_time = rx_time;
/* If peer does not support coded, we cannot use value larger than 2120us */
if (!ble_ll_conn_rem_feature_check(connsm, BLE_LL_FEAT_LE_CODED_PHY)) {
tx_time = min(tx_time, BLE_LL_CONN_SUPP_TIME_MAX_UNCODED);
rx_time = min(rx_time, BLE_LL_CONN_SUPP_TIME_MAX_UNCODED);
}
#endif
if (connsm->max_tx_time != tx_time) {
connsm->max_tx_time = tx_time;
init_dle = 1;
}
if (connsm->max_tx_octets != tx_octets) {
connsm->max_tx_octets = tx_octets;
init_dle = 1;
}
if (rx_time && (connsm->max_rx_time != rx_time)) {
connsm->max_rx_time = rx_time;
init_dle = 1;
}
if (rx_octets && (connsm->max_rx_octets != rx_octets)) {
connsm->max_rx_octets = rx_octets;
init_dle = 1;
}
if (init_dle) {
ble_ll_ctrl_initiate_dle(connsm);
}
return 0;
}
#endif
#if (BLE_LL_BT5_PHY_SUPPORTED == 1)
static void
@@ -1988,6 +2040,7 @@ ble_ll_conn_sm_new(struct ble_ll_conn_sm *connsm)
connsm->eff_max_rx_octets = BLE_LL_CONN_SUPP_BYTES_MIN;
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
connsm->host_req_max_tx_time = 0;
connsm->host_req_max_rx_time = 0;
#endif
/* Reset encryption data */
+8 -31
View File
@@ -1475,8 +1475,8 @@ ble_ll_conn_hci_set_data_len(const uint8_t *cmdbuf, uint8_t len,
struct ble_hci_le_set_data_len_rp *rsp = (void *) rspbuf;
int rc;
uint16_t handle;
uint16_t txoctets;
uint16_t txtime;
uint16_t tx_octets;
uint16_t tx_time;
struct ble_ll_conn_sm *connsm;
if (len != sizeof(*cmd)) {
@@ -1491,42 +1491,19 @@ ble_ll_conn_hci_set_data_len(const uint8_t *cmdbuf, uint8_t len,
goto done;
}
txoctets = le16toh(cmd->tx_octets);
txtime = le16toh(cmd->tx_time);
tx_octets = le16toh(cmd->tx_octets);
tx_time = le16toh(cmd->tx_time);
/* Make sure it is valid */
if (!ble_ll_chk_txrx_octets(txoctets) ||
!ble_ll_chk_txrx_time(txtime)) {
rc = BLE_ERR_INV_HCI_CMD_PARMS;
goto done;
if (!ble_ll_hci_check_dle(tx_octets, tx_time)) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_LE_CODED_PHY)
/*
* Keep original value requested by host since we may want to recalculate
* MaxTxTime after PHY changes between coded and uncoded.
*/
connsm->host_req_max_tx_time = txtime;
/* If peer does not support coded, we cannot use value larger than 2120us */
if (!ble_ll_conn_rem_feature_check(connsm, BLE_LL_FEAT_LE_CODED_PHY)) {
txtime = min(txtime, BLE_LL_CONN_SUPP_TIME_MAX_UNCODED);
}
#endif
rc = BLE_ERR_SUCCESS;
if (connsm->max_tx_time != txtime ||
connsm->max_tx_octets != txoctets) {
connsm->max_tx_time = txtime;
connsm->max_tx_octets = txoctets;
ble_ll_ctrl_initiate_dle(connsm);
}
rc = ble_ll_conn_set_data_len(connsm, tx_octets, tx_time, 0, 0);
done:
rsp->conn_handle = htole16(handle);
*rsplen = sizeof(*rsp);
return rc;
}
#endif
+6
View File
@@ -252,6 +252,12 @@ bool ble_ll_conn_cth_flow_enable(bool enabled);
void ble_ll_conn_cth_flow_process_cmd(const uint8_t *cmdbuf);
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT)
int ble_ll_conn_set_data_len(struct ble_ll_conn_sm *connsm,
uint16_t tx_octets, uint16_t tx_time,
uint16_t rx_octets, uint16_t rx_time);
#endif
void ble_ll_conn_itvl_to_ticks(uint32_t itvl,
uint32_t *itvl_ticks, uint8_t *itvl_usecs);
+6 -1
View File
@@ -2124,7 +2124,12 @@ ble_ll_ctrl_update_features(struct ble_ll_conn_sm *connsm, uint8_t *feat)
} else {
connsm->max_tx_time = g_ble_ll_conn_params.conn_init_max_tx_time_coded;
}
connsm->max_rx_time = BLE_LL_CONN_SUPP_TIME_MAX_CODED;
if (connsm->host_req_max_rx_time) {
connsm->max_rx_time = max(connsm->max_rx_time,
connsm->host_req_max_rx_time);
} else {
connsm->max_rx_time = BLE_LL_CONN_SUPP_TIME_MAX_CODED;
}
}
#endif
+39 -34
View File
@@ -435,6 +435,15 @@ ble_ll_hci_le_set_def_phy(const uint8_t *cmdbuf, uint8_t len)
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT)
int
ble_ll_hci_check_dle(uint16_t max_octets, uint16_t max_time)
{
return (max_octets >= BLE_LL_CONN_SUPP_BYTES_MIN) &&
(max_octets <= BLE_LL_CONN_SUPP_BYTES_MAX) &&
(max_time >= BLE_LL_CONN_SUPP_TIME_MIN) &&
(max_time <= BLE_LL_CONN_SUPP_TIME_MAX);
}
/**
* HCI write suggested default data length command.
*
@@ -453,51 +462,47 @@ ble_ll_hci_le_set_def_phy(const uint8_t *cmdbuf, uint8_t len)
static int
ble_ll_hci_le_wr_sugg_data_len(const uint8_t *cmdbuf, uint8_t len)
{
const struct ble_hci_le_wr_sugg_def_data_len_cp *cmd = (const void*) cmdbuf;
uint16_t tx_oct;
const struct ble_hci_le_wr_sugg_def_data_len_cp *cmd = (const void *)cmdbuf;
uint16_t tx_octets;
uint16_t tx_time;
int rc;
if (len != sizeof(*cmd)) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
/* Get suggested octets and time */
tx_oct = le16toh(cmd->max_tx_octets);
tx_octets = le16toh(cmd->max_tx_octets);
tx_time = le16toh(cmd->max_tx_time);
/* If valid, write into suggested and change connection initial times */
if (ble_ll_chk_txrx_octets(tx_oct) && ble_ll_chk_txrx_time(tx_time)) {
g_ble_ll_conn_params.sugg_tx_octets = (uint8_t)tx_oct;
g_ble_ll_conn_params.sugg_tx_time = tx_time;
/*
* We can disregard host suggestion, but we are a nice controller so
* let's use host suggestion, unless they exceed max supported values
* in which case we just use our max.
*/
g_ble_ll_conn_params.conn_init_max_tx_octets =
min(tx_oct, g_ble_ll_conn_params.supp_max_tx_octets);
g_ble_ll_conn_params.conn_init_max_tx_time =
min(tx_time, g_ble_ll_conn_params.supp_max_tx_time);
/*
* Use the same for coded and uncoded defaults. These are used when PHY
* parameters are initialized and we want to use values overridden by
* host. Make sure we do not exceed max supported time on uncoded.
*/
g_ble_ll_conn_params.conn_init_max_tx_time_uncoded =
min(BLE_LL_CONN_SUPP_TIME_MAX_UNCODED,
g_ble_ll_conn_params.conn_init_max_tx_time);
g_ble_ll_conn_params.conn_init_max_tx_time_coded =
g_ble_ll_conn_params.conn_init_max_tx_time;
rc = BLE_ERR_SUCCESS;
} else {
rc = BLE_ERR_INV_HCI_CMD_PARMS;
if (!ble_ll_hci_check_dle(tx_octets, tx_time)) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
return rc;
g_ble_ll_conn_params.sugg_tx_octets = tx_octets;
g_ble_ll_conn_params.sugg_tx_time = tx_time;
/*
* We can disregard host suggestion, but we are a nice controller so
* let's use host suggestion, unless they exceed max supported values
* in which case we just use our max.
*/
g_ble_ll_conn_params.conn_init_max_tx_octets =
min(tx_octets, g_ble_ll_conn_params.supp_max_tx_octets);
g_ble_ll_conn_params.conn_init_max_tx_time =
min(tx_time, g_ble_ll_conn_params.supp_max_tx_time);
/*
* Use the same for coded and uncoded defaults. These are used when PHY
* parameters are initialized and we want to use values overridden by
* host. Make sure we do not exceed max supported time on uncoded.
*/
g_ble_ll_conn_params.conn_init_max_tx_time_uncoded =
min(BLE_LL_CONN_SUPP_TIME_MAX_UNCODED,
g_ble_ll_conn_params.conn_init_max_tx_time);
g_ble_ll_conn_params.conn_init_max_tx_time_coded =
g_ble_ll_conn_params.conn_init_max_tx_time;
return 0;
}
/**
+52
View File
@@ -303,6 +303,54 @@ ble_ll_hci_vs_css_read_conn_slot(uint16_t ocf, const uint8_t *cmdbuf,
}
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT)
static int
ble_ll_hci_vs_set_data_len(uint16_t ocf, const uint8_t *cmdbuf, uint8_t cmdlen,
uint8_t *rspbuf, uint8_t *rsplen)
{
const struct ble_hci_vs_set_data_len_cp *cmd = (const void *) cmdbuf;
struct ble_hci_vs_set_data_len_rp *rsp = (void *) rspbuf;
struct ble_ll_conn_sm *connsm;
uint16_t conn_handle;
uint16_t tx_octets;
uint16_t tx_time;
uint16_t rx_octets;
uint16_t rx_time;
int rc;
if (cmdlen != sizeof(*cmd)) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
conn_handle = le16toh(cmd->conn_handle);
connsm = ble_ll_conn_find_by_handle(conn_handle);
if (!connsm) {
return BLE_ERR_UNK_CONN_ID;
}
tx_octets = le16toh(cmd->tx_octets);
tx_time = le16toh(cmd->tx_time);
rx_octets = le16toh(cmd->rx_octets);
rx_time = le16toh(cmd->rx_time);
if (!ble_ll_hci_check_dle(tx_octets, tx_time) ||
!ble_ll_hci_check_dle(rx_octets, rx_time)) {
return BLE_ERR_INV_HCI_CMD_PARMS;
}
rc = ble_ll_conn_set_data_len(connsm, tx_octets, tx_time, rx_octets,
rx_time);
if (rc) {
return rc;
}
rsp->conn_handle = htole16(conn_handle);
*rsplen = sizeof(*rsp);
return 0;
}
#endif
static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = {
BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_RD_STATIC_ADDR,
ble_ll_hci_vs_rd_static_addr),
@@ -322,6 +370,10 @@ static struct ble_ll_hci_vs_cmd g_ble_ll_hci_vs_cmds[] = {
BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_CSS_READ_CONN_SLOT,
ble_ll_hci_vs_css_read_conn_slot),
#endif
#if MYNEWT_VAL(BLE_LL_CFG_FEAT_DATA_LEN_EXT)
BLE_LL_HCI_VS_CMD(BLE_HCI_OCF_VS_SET_DATA_LEN,
ble_ll_hci_vs_set_data_len),
#endif
};
static struct ble_ll_hci_vs_cmd *
+12
View File
@@ -1168,6 +1168,18 @@ struct ble_hci_vs_css_read_conn_slot_rp {
uint16_t conn_handle;
uint16_t slot_idx;
} __attribute__((packed));
#define BLE_HCI_OCF_VS_SET_DATA_LEN (MYNEWT_VAL(BLE_HCI_VS_OCF_OFFSET) + (0x0004))
struct ble_hci_vs_set_data_len_cp {
uint16_t conn_handle;
uint16_t tx_octets;
uint16_t tx_time;
uint16_t rx_octets;
uint16_t rx_time;
} __attribute__((packed));
struct ble_hci_vs_set_data_len_rp {
uint16_t conn_handle;
} __attribute__((packed));
/* Command Specific Definitions */
/* --- Set controller to host flow control (OGF 0x03, OCF 0x0031) --- */