Bluetooth: Controller: Fix DLE HCI params parsing

LE Write Suggested Default Data Length and LE Set Data Length commands
are suggestions from host and should be validated only as per HCI
specification regarding internal setting of LLCP.

LLCP is allowed to use other values if needed.

Signed-off-by: Szymon Janc <szymon.janc@codecoup.pl>
This commit is contained in:
Szymon Janc 2022-05-24 17:41:09 +02:00 committed by Carles Cufí
commit 6673cb1f60
2 changed files with 46 additions and 4 deletions

View file

@ -684,14 +684,30 @@ uint8_t ll_version_ind_send(uint16_t handle)
} }
#if defined(CONFIG_BT_CTLR_DATA_LENGTH) #if defined(CONFIG_BT_CTLR_DATA_LENGTH)
static bool ll_len_validate(uint16_t tx_octets, uint16_t tx_time)
{
/* validate if within HCI allowed range */
if (!IN_RANGE(tx_octets, PDU_DC_PAYLOAD_SIZE_MIN,
PDU_DC_PAYLOAD_SIZE_MAX)) {
return false;
}
/* validate if within HCI allowed range */
if (!IN_RANGE(tx_time, PDU_DC_PAYLOAD_TIME_MIN,
PDU_DC_PAYLOAD_TIME_MAX_CODED)) {
return false;
}
return true;
}
uint32_t ll_length_req_send(uint16_t handle, uint16_t tx_octets, uint32_t ll_length_req_send(uint16_t handle, uint16_t tx_octets,
uint16_t tx_time) uint16_t tx_time)
{ {
struct ll_conn *conn; struct ll_conn *conn;
if (IS_ENABLED(CONFIG_BT_CTLR_PARAM_CHECK) && if (IS_ENABLED(CONFIG_BT_CTLR_PARAM_CHECK) &&
((tx_octets > LL_LENGTH_OCTETS_TX_MAX) || !ll_len_validate(tx_octets, tx_time)) {
(tx_time > PDU_DC_PAYLOAD_TIME_MAX_CODED))) {
return BT_HCI_ERR_INVALID_PARAM; return BT_HCI_ERR_INVALID_PARAM;
} }
@ -778,7 +794,10 @@ void ll_length_default_get(uint16_t *max_tx_octets, uint16_t *max_tx_time)
uint32_t ll_length_default_set(uint16_t max_tx_octets, uint16_t max_tx_time) uint32_t ll_length_default_set(uint16_t max_tx_octets, uint16_t max_tx_time)
{ {
/* TODO: parameter check (for BT 5.0 compliance) */ if (IS_ENABLED(CONFIG_BT_CTLR_PARAM_CHECK) &&
!ll_len_validate(max_tx_octets, max_tx_time)) {
return BT_HCI_ERR_INVALID_PARAM;
}
default_tx_octets = max_tx_octets; default_tx_octets = max_tx_octets;
default_tx_time = max_tx_time; default_tx_time = max_tx_time;
@ -8156,8 +8175,31 @@ uint8_t ull_dle_update_eff(struct ll_conn *conn)
return dle_changed; return dle_changed;
} }
static void ull_len_data_length_trim(uint16_t *tx_octets, uint16_t *tx_time)
{
#if defined(CONFIG_BT_CTLR_PHY_CODED)
uint16_t tx_time_max =
PDU_DC_MAX_US(LL_LENGTH_OCTETS_TX_MAX, PHY_CODED);
#else /* !CONFIG_BT_CTLR_PHY_CODED */
uint16_t tx_time_max =
PDU_DC_MAX_US(LL_LENGTH_OCTETS_TX_MAX, PHY_1M);
#endif /* !CONFIG_BT_CTLR_PHY_CODED */
/* trim to supported values */
if (*tx_octets > LL_LENGTH_OCTETS_TX_MAX) {
*tx_octets = LL_LENGTH_OCTETS_TX_MAX;
}
if (*tx_time > tx_time_max) {
*tx_time = tx_time_max;
}
}
void ull_dle_local_tx_update(struct ll_conn *conn, uint16_t tx_octets, uint16_t tx_time) void ull_dle_local_tx_update(struct ll_conn *conn, uint16_t tx_octets, uint16_t tx_time)
{ {
/* Trim to supported values */
ull_len_data_length_trim(&tx_octets, &tx_time);
conn->lll.dle.default_tx_octets = tx_octets; conn->lll.dle.default_tx_octets = tx_octets;
#if defined(CONFIG_BT_CTLR_PHY) #if defined(CONFIG_BT_CTLR_PHY)

View file

@ -176,6 +176,6 @@
#define CONFIG_BT_CTLR_SUBVERSION_NUMBER 0x5678 #define CONFIG_BT_CTLR_SUBVERSION_NUMBER 0x5678
#define CONFIG_BT_CTLR_ASSERT_HANDLER y #define CONFIG_BT_CTLR_ASSERT_HANDLER y
#define CONFIG_BT_BUF_ACL_TX_COUNT 7 #define CONFIG_BT_BUF_ACL_TX_COUNT 7
#define CONFIG_BT_BUF_ACL_TX_SIZE 27 #define CONFIG_BT_BUF_ACL_TX_SIZE 251
#define CONFIG_BT_CTLR_RX_BUFFERS 7 #define CONFIG_BT_CTLR_RX_BUFFERS 7
#define CONFIG_NET_BUF_USER_DATA_SIZE 8 #define CONFIG_NET_BUF_USER_DATA_SIZE 8