mirror of
https://github.com/espressif/esp-nimble.git
synced 2026-06-06 05:14:45 +00:00
nimble/ll: Add vs command to change all data length parameters
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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.
|
||||
*
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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 *
|
||||
|
||||
@@ -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) --- */
|
||||
|
||||
Reference in New Issue
Block a user