From f1c5282833859373da0eeae2322ea77d4602fd33 Mon Sep 17 00:00:00 2001 From: Grzegorz Kolodziejczyk Date: Wed, 18 May 2016 18:28:06 +0200 Subject: [PATCH] Bluetooth: tester: Fix handling execute write error responses This patch fixes returning invalid offset, invalid attribute length error. Error should be set during prepare write and returned in response to execute write request as error response. Change-Id: I78c57abc5f6f2fbd4a2c0fbb1ee6532212679a36 Signed-off-by: Grzegorz Kolodziejczyk --- tests/bluetooth/tester/src/gatt.c | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/tests/bluetooth/tester/src/gatt.c b/tests/bluetooth/tester/src/gatt.c index 0529a72fa1a..ee775422cda 100644 --- a/tests/bluetooth/tester/src/gatt.c +++ b/tests/bluetooth/tester/src/gatt.c @@ -267,9 +267,11 @@ fail: struct gatt_value { uint16_t len; uint8_t *data; + uint16_t prep_data_len; uint8_t *prep_data; uint8_t enc_key_size; uint8_t flags[1]; + uint8_t prep_write_err; }; enum { @@ -311,19 +313,26 @@ static ssize_t write_value(struct bt_conn *conn, return BT_GATT_ERR(BT_ATT_ERR_ENCRYPTION_KEY_SIZE); } + if (value->prep_write_err) { + return len; + } + /* * If the prepare Value Offset is greater than the current length of * the attribute value Error Response shall be sent with the * «Invalid Offset». */ if (offset > value->len) { - return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET); + value->prep_write_err = BT_ATT_ERR_INVALID_OFFSET; + return len; } if (offset + len > value->len) { - return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN); + value->prep_write_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN; + return len; } + value->prep_data_len += len; memcpy(value->prep_data + offset, buf, len); return len; @@ -334,13 +343,29 @@ static ssize_t flush_value(struct bt_conn *conn, { struct gatt_value *value = attr->user_data; + if (!value->prep_data_len && !value->prep_write_err) { + return 0; + } + + if (value->prep_write_err) { + uint8_t err = value->prep_write_err; + + memset(value->prep_data, 0, value->prep_data_len); + value->prep_data_len = 0; + value->prep_write_err = 0; + + return BT_GATT_ERR(err); + } + switch (flags) { case BT_GATT_FLUSH_SYNC: /* Sync buffer to data */ memcpy(value->data, value->prep_data, value->len); + value->len = value->prep_data_len; /* Fallthrough */ case BT_GATT_FLUSH_DISCARD: - memset(value->prep_data, 0, value->len); + memset(value->prep_data, 0, value->prep_data_len); + value->prep_data_len = 0; return 0; }