From b506b9226e6206ebddc96b66d3df376eb8f68c8f Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Tue, 12 May 2026 09:37:17 +0200 Subject: [PATCH] nimble/host: Refactor GATT Read Multiple Variable Char Value response This reworks ATT_READ_MULTIPLE_VARIABLE_RSP parsing. If response doesn't match request (number of values requested) or LV parsing shows incorrect format we ignore that and report error to app. --- nimble/host/src/ble_gattc.c | 84 ++++++++++++++++++++++--------------- 1 file changed, 50 insertions(+), 34 deletions(-) diff --git a/nimble/host/src/ble_gattc.c b/nimble/host/src/ble_gattc.c index fb5ba9a7a..84722621f 100644 --- a/nimble/host/src/ble_gattc.c +++ b/nimble/host/src/ble_gattc.c @@ -4305,48 +4305,64 @@ ble_gattc_read_mult_cb_var(struct ble_gattc_proc *proc, int status, for (i = 0; i < proc->read_mult.num_handles; i++) { attr[i].handle = proc->read_mult.handles[i]; attr[i].offset = 0; - if (om == NULL || OS_MBUF_PKTLEN(*om) < 2) { - continue; + } + + if (status == 0 && om != NULL) { + for (i = 0; i < proc->read_mult.num_handles; i++) { + if (OS_MBUF_PKTLEN(*om) < 2) { + break; + } + + *om = os_mbuf_pullup(*om, 2); + if (*om == NULL) { + break; + } + + attr_len = get_le16((*om)->om_data); + os_mbuf_adj(*om, 2); + + if (attr_len > BLE_ATT_ATTR_MAX_LEN) { + break; + } + + attr[i].om = os_msys_get_pkthdr(attr_len, 0); + if (!attr[i].om) { + /* this is OOM condition */ + status = BLE_HS_ENOMEM; + break; + } + + rc = os_mbuf_appendfrom(attr[i].om, *om, 0, attr_len); + if (rc) { + break; + } + + os_mbuf_adj(*om, attr_len); } - *om = os_mbuf_pullup(*om, 2); - if (!*om) { - break; + /* failed to correctly parse response, + * cleanup any partial data and set status if not set already + */ + if (i < proc->read_mult.num_handles || OS_MBUF_PKTLEN(*om) != 0) { + for (i = 0; i < proc->read_mult.num_handles; i++) { + os_mbuf_free_chain(attr[i].om); + attr[i].om = NULL; + } + + if (status == 0) { + status = BLE_HS_EBADDATA; + } } - - attr_len = get_le16((*om)->om_data); - - os_mbuf_adj(*om, 2); - - if (attr_len > BLE_ATT_ATTR_MAX_LEN) { - /*TODO Figure out what to do here */ - break; - } - - attr[i].om = os_msys_get_pkthdr(attr_len, 0); - if (!attr[i].om) { - /*TODO Figure out what to do here */ - break; - } - - rc = os_mbuf_appendfrom(attr[i].om, *om, 0, attr_len); - if (rc) { - /*TODO Figure out what to do here */ - break; - } - - os_mbuf_adj(*om, attr_len); + } else if (status == 0) { + status = BLE_HS_EBADDATA; } proc->read_mult.cb_mult(proc->conn_handle, - ble_gattc_error(status, att_handle), &attr[0], - i, - proc->read_mult.cb_arg); + ble_gattc_error(status, att_handle), &attr[0], + proc->read_mult.num_handles, proc->read_mult.cb_arg); for (i = 0; i < proc->read_mult.num_handles; i++) { - if (attr[i].om != NULL) { - os_mbuf_free_chain(attr[i].om); - } + os_mbuf_free_chain(attr[i].om); } return 0;