[PATCH BlueZ 1/4] shared/att: Add bt_att_resend

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

 



From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx>

This adds bt_att_resend which can be used with procedures that needs to
send multiple PDUs to complete (e.g. Read Long, Write Long, etc.) so
they are pushed to the head instead of the tail of the queue so one can
retain its position on the queue.
---
 src/shared/att.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++
 src/shared/att.h |  5 ++++
 2 files changed, 64 insertions(+)

diff --git a/src/shared/att.c b/src/shared/att.c
index 2387fe4c3..169f726e4 100644
--- a/src/shared/att.c
+++ b/src/shared/att.c
@@ -1615,6 +1615,65 @@ unsigned int bt_att_send(struct bt_att *att, uint8_t opcode,
 	return op->id;
 }
 
+int bt_att_resend(struct bt_att *att, unsigned int id, uint8_t opcode,
+				const void *pdu, uint16_t length,
+				bt_att_response_func_t callback,
+				void *user_data,
+				bt_att_destroy_func_t destroy)
+{
+	const struct queue_entry *entry;
+	struct att_send_op *op;
+	bool result;
+
+	if (!att || !id)
+		return -EINVAL;
+
+	/* Lookup request on each channel */
+	for (entry = queue_get_entries(att->chans); entry;
+						entry = entry->next) {
+		struct bt_att_chan *chan = entry->data;
+
+		if (chan->pending_req && chan->pending_req->id == id)
+			break;
+	}
+
+	if (!entry)
+		return -ENOENT;
+
+	/* Only allow requests to be resend */
+	if (get_op_type(opcode) != ATT_OP_TYPE_REQ)
+		return -EOPNOTSUPP;
+
+	op = create_att_send_op(att, opcode, pdu, length, callback, user_data,
+								destroy);
+	if (!op)
+		return -ENOMEM;
+
+	op->id = id;
+
+	switch (opcode) {
+	/* Only prepend requests that could be a continuation */
+	case BT_ATT_OP_READ_BLOB_REQ:
+	case BT_ATT_OP_PREP_WRITE_REQ:
+	case BT_ATT_OP_EXEC_WRITE_REQ:
+		result = queue_push_head(att->req_queue, op);
+		break;
+	default:
+		result = queue_push_tail(att->req_queue, op);
+		break;
+	}
+
+	if (!result) {
+		free(op->pdu);
+		free(op);
+		return -ENOMEM;
+	}
+
+	wakeup_writer(att);
+
+	return 0;
+}
+
 unsigned int bt_att_chan_send(struct bt_att_chan *chan, uint8_t opcode,
 				const void *pdu, uint16_t len,
 				bt_att_response_func_t callback,
diff --git a/src/shared/att.h b/src/shared/att.h
index de136a066..4aa3de87b 100644
--- a/src/shared/att.h
+++ b/src/shared/att.h
@@ -63,6 +63,11 @@ unsigned int bt_att_send(struct bt_att *att, uint8_t opcode,
 					bt_att_response_func_t callback,
 					void *user_data,
 					bt_att_destroy_func_t destroy);
+int bt_att_resend(struct bt_att *att, unsigned int id, uint8_t opcode,
+					const void *pdu, uint16_t length,
+					bt_att_response_func_t callback,
+					void *user_data,
+					bt_att_destroy_func_t destroy);
 unsigned int bt_att_chan_send(struct bt_att_chan *chan, uint8_t opcode,
 					const void *pdu, uint16_t len,
 					bt_att_response_func_t callback,
-- 
2.31.1




[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