fix(bt_hid): size HID TX buffers to report length

This commit is contained in:
hejiaxin
2026-08-27 15:10:05 +08:00
parent 7648fc84bf
commit 5036f97cb8
2 changed files with 23 additions and 6 deletions

View File

@@ -729,7 +729,8 @@ tHID_STATUS hidd_conn_send_data(uint8_t channel, uint8_t msg_type, uint8_t param
BT_HDR *p_buf;
uint8_t *p_out;
uint16_t cid;
uint16_t buf_size;
uint16_t max_buf_size;
uint32_t payload_size, buf_size;
HIDD_TRACE_VERBOSE("%s: channel(%d), msg_type(%d), len(%d)", __func__, channel, msg_type, len);
@@ -742,20 +743,34 @@ tHID_STATUS hidd_conn_send_data(uint8_t channel, uint8_t msg_type, uint8_t param
case HID_TRANS_HANDSHAKE:
case HID_TRANS_CONTROL:
cid = p_hcon->ctrl_cid;
buf_size = HID_CONTROL_BUF_SIZE;
max_buf_size = HID_CONTROL_BUF_SIZE;
break;
case HID_TRANS_DATA:
if (channel == HID_CHANNEL_CTRL) {
cid = p_hcon->ctrl_cid;
buf_size = HID_CONTROL_BUF_SIZE;
max_buf_size = HID_CONTROL_BUF_SIZE;
} else {
cid = p_hcon->intr_cid;
buf_size = HID_INTERRUPT_BUF_SIZE;
max_buf_size = HID_INTERRUPT_BUF_SIZE;
}
break;
default:
return (HID_ERR_INVALID_PARAM);
}
/* HID header byte, plus an optional report id byte */
payload_size = (uint32_t)len + 2;
buf_size = BT_HDR_SIZE + L2CAP_MIN_OFFSET + payload_size;
if (buf_size > max_buf_size) {
HIDD_TRACE_ERROR("hidd tx: len(%d) too large",len);
return (HID_ERR_INVALID_PARAM);
}
/* rem_mtu_size is only known once the channel has been configured */
if (p_hcon->rem_mtu_size && payload_size > p_hcon->rem_mtu_size) {
HIDD_TRACE_ERROR("hidd tx: len(%d) exceeds peer mtu(%d)",len, p_hcon->rem_mtu_size);
return (HID_ERR_INVALID_PARAM);
}
p_buf = (BT_HDR *)osi_malloc(buf_size);
if (p_buf == NULL)
return (HID_ERR_NO_RESOURCES);

View File

@@ -865,11 +865,9 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
case HID_TRANS_GET_IDLE:
case HID_TRANS_SET_IDLE:
cid = p_hcon->ctrl_cid;
buf_size = HID_CONTROL_BUF_SIZE;
break;
case HID_TRANS_DATA:
cid = p_hcon->intr_cid;
buf_size = HID_INTERRUPT_BUF_SIZE;
break;
default:
rc = HID_ERR_INVALID_PARAM;
@@ -884,6 +882,8 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
do {
if ( buf == NULL || blank_datc ) {
/* HID header byte, an optional report id byte and the inlined data bytes */
buf_size = BT_HDR_SIZE + L2CAP_MIN_OFFSET + 2 + use_data;
if ((p_buf = (BT_HDR *)osi_malloc(buf_size)) == NULL) {
rc = HID_ERR_NO_RESOURCES;
goto error;
@@ -895,6 +895,8 @@ tHID_STATUS hidh_conn_snd_data (UINT8 dhandle, UINT8 trans_type, UINT8 param,
bytes_copied = 0;
blank_datc = FALSE;
} else if ( (buf->len > (p_hcon->rem_mtu_size - 1))) {
/* HID header byte plus a full (rem_mtu_size - 1) payload segment */
buf_size = BT_HDR_SIZE + L2CAP_MIN_OFFSET + p_hcon->rem_mtu_size + use_data;
if ((p_buf = (BT_HDR *)osi_malloc(buf_size)) == NULL) {
rc = HID_ERR_NO_RESOURCES;
goto error;