diff mbox series

[BlueZ,3/4] attrib: Make use of bt_att_resend

Message ID 20211006213704.1093265-3-luiz.dentz@gmail.com (mailing list archive)
State Accepted
Delegated to: Luiz Von Dentz
Headers show
Series [BlueZ,1/4] shared/att: Add bt_att_resend | expand

Checks

Context Check Description
tedd_an/checkpatch success Checkpatch PASS
tedd_an/gitlint success Gitlint PASS

Commit Message

Luiz Augusto von Dentz Oct. 6, 2021, 9:37 p.m. UTC
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

If the id != 0 that means that a proceedure that needs multiple PDUs is
in progress so use bt_att_resend with its id that way the bt_att id and
gattrib shall always be the same.
---
 attrib/gattrib.c | 95 +++++++++++-------------------------------------
 1 file changed, 22 insertions(+), 73 deletions(-)
diff mbox series

Patch

diff --git a/attrib/gattrib.c b/attrib/gattrib.c
index bc7d4f22c..270a37ebe 100644
--- a/attrib/gattrib.c
+++ b/attrib/gattrib.c
@@ -41,13 +41,8 @@  struct _GAttrib {
 	struct queue *track_ids;
 };
 
-struct id_pair {
-	unsigned int org_id;
-	unsigned int pend_id;
-};
-
 struct attrib_callbacks {
-	struct id_pair *id;
+	unsigned int id;
 	GAttribResultFunc result_func;
 	GAttribNotifyFunc notify_func;
 	GDestroyNotify destroy_func;
@@ -56,32 +51,6 @@  struct attrib_callbacks {
 	uint16_t notify_handle;
 };
 
-static bool find_with_org_id(const void *data, const void *user_data)
-{
-	const struct id_pair *p = data;
-	unsigned int orig_id = PTR_TO_UINT(user_data);
-
-	return (p->org_id == orig_id);
-}
-
-static struct id_pair *store_id(GAttrib *attrib, unsigned int org_id,
-							unsigned int pend_id)
-{
-	struct id_pair *t;
-
-	t = new0(struct id_pair, 1);
-	if (!t)
-		return NULL;
-
-	t->org_id = org_id;
-	t->pend_id = pend_id;
-
-	if (queue_push_tail(attrib->track_ids, t))
-		return t;
-
-	return NULL;
-}
-
 GAttrib *g_attrib_new(GIOChannel *io, guint16 mtu, bool ext_signed)
 {
 	gint fd;
@@ -150,9 +119,6 @@  static void attrib_callbacks_destroy(void *data)
 	if (cb->destroy_func)
 		cb->destroy_func(cb->user_data);
 
-	if (queue_remove(cb->parent->track_ids, cb->id))
-		free(cb->id);
-
 	free(data);
 }
 
@@ -182,7 +148,7 @@  void g_attrib_unref(GAttrib *attrib)
 	bt_att_unref(attrib->att);
 
 	queue_destroy(attrib->callbacks, attrib_callbacks_destroy);
-	queue_destroy(attrib->track_ids, free);
+	queue_destroy(attrib->track_ids, NULL);
 
 	free(attrib->buf);
 
@@ -295,7 +261,6 @@  guint g_attrib_send(GAttrib *attrib, guint id, const guint8 *pdu, guint16 len,
 	struct attrib_callbacks *cb = NULL;
 	bt_att_response_func_t response_cb = NULL;
 	bt_att_destroy_func_t destroy_cb = NULL;
-	unsigned int pend_id;
 
 	if (!attrib)
 		return 0;
@@ -317,62 +282,47 @@  guint g_attrib_send(GAttrib *attrib, guint id, const guint8 *pdu, guint16 len,
 
 	}
 
-	pend_id = bt_att_send(attrib->att, pdu[0], (void *) pdu + 1, len - 1,
-						response_cb, cb, destroy_cb);
-
-	/*
-	 * We store here pair as it is easier to handle it in response and in
-	 * case where user request us to use specific id request - see below.
-	 */
 	if (id == 0)
-		id = pend_id;
+		id = bt_att_send(attrib->att, pdu[0], (void *) pdu + 1,
+					len - 1, response_cb, cb, destroy_cb);
+	else {
+		int err;
+
+		err = bt_att_resend(attrib->att, id, pdu[0], (void *) pdu + 1,
+					len - 1, response_cb, cb, destroy_cb);
+		if (err)
+			return 0;
+	}
+
+	if (!id)
+		return id;
 
 	/*
 	 * If user what us to use given id, lets keep track on that so we give
 	 * user a possibility to cancel ongoing request.
 	 */
-	if (cb)
-		cb->id = store_id(attrib, id, pend_id);
+	if (cb) {
+		cb->id = id;
+		queue_push_tail(attrib->track_ids, UINT_TO_PTR(id));
+	}
 
 	return id;
 }
 
 gboolean g_attrib_cancel(GAttrib *attrib, guint id)
 {
-	struct id_pair *p;
-
 	if (!attrib)
 		return FALSE;
 
-	/*
-	 * If request belongs to gattrib and is not yet done it has to be on
-	 * the tracking id queue
-	 *
-	 * FIXME: It can happen that on the queue there is id_pair with
-	 * given id which was provided by the user. In the same time it might
-	 * happen that other attrib user got dynamic allocated req_id with same
-	 * value as the one provided by the other user.
-	 * In such case there are two clients having same request id and in
-	 * this point of time we don't know which one calls cancel. For
-	 * now we cancel request in which id was specified by the user.
-	 */
-	p = queue_remove_if(attrib->track_ids, find_with_org_id,
-							UINT_TO_PTR(id));
-	if (!p)
-		return FALSE;
-
-	id = p->pend_id;
-	free(p);
-
 	return bt_att_cancel(attrib->att, id);
 }
 
 static void cancel_request(void *data, void *user_data)
 {
-	struct id_pair *p = data;
+	unsigned int id = PTR_TO_UINT(data);
 	GAttrib *attrib = user_data;
 
-	bt_att_cancel(attrib->att, p->pend_id);
+	bt_att_cancel(attrib->att, id);
 }
 
 gboolean g_attrib_cancel_all(GAttrib *attrib)
@@ -380,9 +330,8 @@  gboolean g_attrib_cancel_all(GAttrib *attrib)
 	if (!attrib)
 		return FALSE;
 
-	/* Cancel only request which belongs to gattrib */
 	queue_foreach(attrib->track_ids, cancel_request, attrib);
-	queue_remove_all(attrib->track_ids, NULL, NULL, free);
+	queue_remove_all(attrib->track_ids, NULL, NULL, NULL);
 
 	return TRUE;
 }