mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
fix(ble/bluedroid): cap Read By Type response length at ATT maximum
Read By Type Response Length is one octet (max 255). When MTU was
large enough to return a long characteristic value in one pair, the
server wrote (UINT8)(value_len + 2) and overflowed (e.g. 513 -> 1),
so the client rejected the PDU as GATT_INVALID_PDU (0x04).
Cap server value to 253 bytes per pair, clamp the length byte, and
continue long reads via Read Blob when the capped size is returned.
(cherry picked from commit 97905afccc)
Co-authored-by: zhanghaipeng <zhanghaipeng@espressif.com>
This commit is contained in:
@@ -891,7 +891,11 @@ void gatt_process_read_by_type_rsp (tGATT_TCB *p_tcb, tGATT_CLCB *p_clcb, UINT8
|
||||
/* value_len is the length of current record's value; use it to avoid overread when multiple records present */
|
||||
p_clcb->counter = value_len;
|
||||
p_clcb->s_handle = handle;
|
||||
if ( p_clcb->counter == (p_clcb->p_tcb->payload_size - 4)) {
|
||||
UINT16 max_rbtype_val_len = (p_clcb->p_tcb->payload_size - 4);
|
||||
if (max_rbtype_val_len > GATT_MAX_READ_BY_TYPE_VALUE_LEN) {
|
||||
max_rbtype_val_len = GATT_MAX_READ_BY_TYPE_VALUE_LEN;
|
||||
}
|
||||
if (p_clcb->counter == max_rbtype_val_len) {
|
||||
p_clcb->op_subtype = GATT_READ_BY_HANDLE;
|
||||
if (!p_clcb->p_attr_buf) {
|
||||
p_clcb->p_attr_buf = (UINT8 *)osi_malloc(GATT_MAX_ATTR_LEN);
|
||||
|
||||
@@ -370,7 +370,13 @@ tGATT_STATUS gatts_db_read_attr_value_by_type (tGATT_TCB *p_tcb,
|
||||
|
||||
UINT16_TO_STREAM (p, p_attr->handle);
|
||||
|
||||
status = read_attr_value ((void *)p_attr, 0, &p, FALSE, (UINT16)(*p_len - 2), &len, sec_flag, key_size);
|
||||
{
|
||||
UINT16 max_val_len = (UINT16)(*p_len - 2);
|
||||
if (max_val_len > GATT_MAX_READ_BY_TYPE_VALUE_LEN) {
|
||||
max_val_len = GATT_MAX_READ_BY_TYPE_VALUE_LEN;
|
||||
}
|
||||
status = read_attr_value ((void *)p_attr, 0, &p, FALSE, max_val_len, &len, sec_flag, key_size);
|
||||
}
|
||||
if (status == GATT_PENDING) {
|
||||
|
||||
|
||||
|
||||
@@ -76,6 +76,10 @@ typedef UINT8 tGATT_SEC_ACTION;
|
||||
|
||||
#define GATT_HDR_SIZE 3 /* 1B opcode + 2B handle */
|
||||
|
||||
/* ATT Read By Type Response: Length field is 1 octet (max 255). */
|
||||
#define GATT_MAX_READ_BY_TYPE_PAIR_LEN 255
|
||||
#define GATT_MAX_READ_BY_TYPE_VALUE_LEN (GATT_MAX_READ_BY_TYPE_PAIR_LEN - 2)
|
||||
|
||||
/**
|
||||
* Wait for ATT cmd response timeout value (40 seconds).
|
||||
* The max connection supervision timeout is 32 seconds,
|
||||
|
||||
Reference in New Issue
Block a user