Merge branch 'bugfix/fix_blufi_nimble_gatt_pkt_v5.3' into 'release/v5.3'

fix(blufi): Handle flattened ATT write payloads correctly in NimBLE BLUFI host (v5.3)

See merge request espressif/esp-idf!46263
This commit is contained in:
Jiang Jiang Jian
2026-03-06 23:31:36 +08:00
@@ -112,7 +112,9 @@ static size_t write_value(uint16_t conn_handle, uint16_t attr_handle,
void *arg)
{
struct gatt_value *value = (struct gatt_value *)arg;
uint8_t *flat_buf = NULL;
uint16_t len;
uint16_t pkt_len;
int rc;
if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
if (ctxt->chr->flags & BLE_GATT_CHR_F_WRITE_AUTHOR) {
@@ -124,38 +126,45 @@ static size_t write_value(uint16_t conn_handle, uint16_t attr_handle,
}
}
/* Data may come in linked om. So retrieve all data */
if (SLIST_NEXT(ctxt->om, om_next) != NULL) {
uint8_t *fw_buf = (uint8_t *)malloc(517 * sizeof(uint8_t));
memset(fw_buf, 0x0, 517);
memcpy(fw_buf, &ctxt->om->om_data[0], ctxt->om->om_len);
struct os_mbuf *last;
last = ctxt->om;
uint32_t offset = ctxt->om->om_len;
while (SLIST_NEXT(last, om_next) != NULL) {
struct os_mbuf *temp = SLIST_NEXT(last, om_next);
memcpy(fw_buf + offset , &temp->om_data[0], temp->om_len);
offset += temp->om_len;
last = SLIST_NEXT(last, om_next);
temp = NULL;
}
btc_blufi_recv_handler(fw_buf, offset);
free(fw_buf);
}
else {
btc_blufi_recv_handler(&ctxt->om->om_data[0], ctxt->om->om_len);
pkt_len = OS_MBUF_PKTLEN(ctxt->om);
if (pkt_len > MAX_VAL_SIZE) {
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
}
rc = ble_hs_mbuf_to_flat(ctxt->om, value->buf->om_data,
value->buf->om_len, &len);
if (rc != 0) {
flat_buf = malloc(pkt_len);
if (flat_buf == NULL) {
return BLE_ATT_ERR_INSUFFICIENT_RES;
}
rc = ble_hs_mbuf_to_flat(ctxt->om, flat_buf, pkt_len, &len);
if (rc != 0 || len != pkt_len) {
free(flat_buf);
return BLE_ATT_ERR_UNLIKELY;
}
/* Maximum attribute value size is 512 bytes */
assert(value->buf->om_len < MAX_VAL_SIZE);
btc_blufi_recv_handler(flat_buf, pkt_len);
if (value->buf != NULL) {
os_mbuf_free_chain(value->buf);
value->buf = NULL;
}
value->buf = os_msys_get(0, 0);
if (value->buf == NULL) {
free(flat_buf);
return BLE_ATT_ERR_INSUFFICIENT_RES;
}
if (pkt_len > 0) {
if (os_mbuf_append(value->buf, flat_buf, pkt_len) != 0) {
os_mbuf_free_chain(value->buf);
value->buf = NULL;
free(flat_buf);
return BLE_ATT_ERR_INSUFFICIENT_RES;
}
}
free(flat_buf);
return 0;
}