uint8_t att_ecode;
bool success;
- if (opcode != BT_ATT_OP_READ_MULT_RSP || (!pdu && length)) {
+ if ((opcode != BT_ATT_OP_READ_MULT_RSP &&
+ opcode != BT_ATT_OP_READ_MULT_VL_RSP) ||
+ (!pdu && length)) {
success = false;
if (opcode == BT_ATT_OP_ERROR_RSP)
att_ecode = 0;
}
- if (op->callback)
+ if (!op->callback)
+ return;
+
+ if (opcode == BT_ATT_OP_READ_MULT_RSP || att_ecode) {
op->callback(success, att_ecode, pdu, length, op->user_data);
+ return;
+ }
+
+ if (length < 2) {
+ op->callback(success, att_ecode, pdu, length, op->user_data);
+ return;
+ }
+
+ /* Parse response */
+ while (length >= 2) {
+ uint16_t len;
+
+ len = get_le16(pdu);
+ length -= 2;
+ pdu += 2;
+
+ /* The Length Value Tuple List may be truncated within the
+ * first two octets of a tuple due to the size limits of the
+ * current ATT_MTU.
+ */
+ if (len > length)
+ length = len;
+
+ op->callback(success, att_ecode, pdu, len, op->user_data);
+ }
}
unsigned int bt_gatt_client_read_multiple(struct bt_gatt_client *client,
uint8_t pdu[num_handles * 2];
struct request *req;
struct read_op *op;
+ uint8_t opcode;
int i;
if (!client)
for (i = 0; i < num_handles; i++)
put_le16(handles[i], pdu + (2 * i));
- req->att_id = bt_att_send(client->att, BT_ATT_OP_READ_MULT_REQ,
- pdu, sizeof(pdu),
+ opcode = bt_gatt_client_get_features(client) &
+ BT_GATT_CHRC_CLI_FEAT_EATT ? BT_ATT_OP_READ_MULT_VL_REQ :
+ BT_ATT_OP_READ_MULT_REQ;
+
+ req->att_id = bt_att_send(client->att, opcode, pdu, sizeof(pdu),
read_multiple_cb, req,
request_unref);
if (!req->att_id) {