Diff between b353ae3cf21825bdf4be33d2e9386e629b3a12a0 and 6024de858943249f431a6a909bdca221c3d6a4eb

Changed Files

File Additions Deletions Status
src/shared/att.c +59 -0 modified
src/shared/att.h +5 -0 modified

Full Patch

diff --git a/src/shared/att.c b/src/shared/att.c
index 2387fe4..169f726 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 de136a0..4aa3de8 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,