[PATCH 1/4] android/gatt: Handle Androids read/write responses in response queue

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is needed for reads like "read by type" to support Android
responses, callback reads and direct db reads in a single request.
---
 android/gatt.c | 88 ++++++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 58 insertions(+), 30 deletions(-)

diff --git a/android/gatt.c b/android/gatt.c
index 9bbcc48..20850af 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -3610,6 +3610,37 @@ static void send_dev_pending_response(struct gatt_device *device,
 
 		break;
 	}
+	case ATT_OP_EXEC_WRITE_REQ:
+		val = queue_pop_head(device->pending_requests);
+		if (!val) {
+			error = ATT_ECODE_ATTR_NOT_FOUND;
+			break;
+		}
+
+		len = enc_exec_write_resp(rsp);
+		destroy_pending_request(val);
+		break;
+	case ATT_OP_WRITE_REQ:
+		val = queue_pop_head(device->pending_requests);
+		if (!val) {
+			error = ATT_ECODE_ATTR_NOT_FOUND;
+			break;
+		}
+
+		len = enc_write_resp(rsp);
+		destroy_pending_request(val);
+		break;
+	case ATT_OP_PREP_WRITE_REQ:
+		val = queue_pop_head(device->pending_requests);
+		if (!val) {
+			error = ATT_ECODE_ATTR_NOT_FOUND;
+			break;
+		}
+
+		len = enc_prep_write_resp(val->handle, val->offset, val->value,
+						val->length, rsp, sizeof(rsp));
+		destroy_pending_request(val);
+		break;
 	default:
 		break;
 	}
@@ -3698,48 +3729,45 @@ static void send_gatt_response(uint8_t opcode, uint16_t handle,
 					bdaddr_t *bdaddr)
 {
 	struct gatt_device *dev;
-	uint16_t length;
-	uint8_t pdu[ATT_DEFAULT_LE_MTU];
-
-	DBG("");
+	struct pending_request *entry;
 
 	dev = find_device_by_addr(bdaddr);
 	if (!dev) {
 		error("gatt: send_gatt_response, could not find dev");
-		return;
+		goto done;
 	}
 
-	if (!status) {
-		length = enc_error_resp(opcode, handle, status, pdu,
-								sizeof(pdu));
+	if (status)
 		goto done;
-	}
 
-	switch (opcode) {
-	case ATT_OP_EXEC_WRITE_REQ:
-		length = enc_exec_write_resp(pdu);
-		break;
-	case ATT_OP_WRITE_REQ:
-		length = enc_write_resp(pdu);
-		break;
-	case ATT_OP_PREP_WRITE_REQ:
-		length = enc_prep_write_resp(handle, offset, data, len, pdu,
-								sizeof(pdu));
-		break;
-	case ATT_OP_READ_BLOB_REQ:
-		length = enc_read_blob_resp((uint8_t *)data, len, offset, pdu,
-								sizeof(pdu));
-		break;
-	case ATT_OP_READ_REQ:
-		length = enc_read_resp((uint8_t *)data, len, pdu, sizeof(pdu));
-		break;
-	default:
-		error("gatt: Unexpected opcode");
+	entry = queue_find(dev->pending_requests, match_dev_request_by_handle,
+							UINT_TO_PTR(handle));
+	if (!entry) {
+		DBG("No pending response found! Bogus android response?");
 		return;
 	}
 
+	entry->handle = handle;
+	entry->offset = offset;
+	entry->length = len;
+
+	if (!len)
+		goto done;
+
+	entry->value = malloc0(len);
+	if (!entry->value) {
+		/* send_dev_pending_request on empty queue sends error resp. */
+		queue_remove(dev->pending_requests, entry);
+		destroy_pending_request(entry);
+
+		goto done;
+	}
+
+	memcpy(entry->value, data, len);
+
 done:
-	g_attrib_send(dev->attrib, 0, pdu, length, NULL, NULL, NULL);
+	if (!queue_find(dev->pending_requests, match_pending_dev_request, NULL))
+		send_dev_pending_response(dev, opcode);
 }
 
 static void set_trans_id(struct gatt_app *app, unsigned int id, int8_t opcode)
-- 
1.9.3

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux