Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH BlueZ] shared/gatt-client: always send ATT confirmations
@ 2023-08-26 19:24 Javier de San Pedro
  2023-08-26 21:29 ` [BlueZ] " bluez.test.bot
  2023-08-27 21:07 ` [PATCH BlueZ] " Luiz Augusto von Dentz
  0 siblings, 2 replies; 3+ messages in thread
From: Javier de San Pedro @ 2023-08-26 19:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: luiz.von.dentz, Javier de San Pedro

I noticed after upgrading 5.66->5.68 that Bluez was no longer sending
confirmations (ATT opcode 0x1E) in response to indication opcodes (0x1D).

Commit fde32ff9c9c0 ("shared/gatt-client: Allow registering with NULL
callback") added an early return to the notify_cb function when the
current client's notify_list is empty. However, in this case, we will
also not send the confirmation back. This breaks protocol.

The devices I have generally respond to this by stopping
any new indications until ~15sec timeout or disconnection.

As far as I can see, when using D-Bus API all notify handlers are always
added on client clones, never on the 'root' client itself (the one
with !client->parent), so for the root client the notify_list is always
empty, making this issue very easy to trigger using D-Bus GATT API.

Ensure that we always send the confirmation, even if notify_list is empty.

Fixes: fde32ff9c9c0 ("shared/gatt-client: Allow registering with NULL callback")
---
 src/shared/gatt-client.c | 57 ++++++++++++++++++++--------------------
 1 file changed, 29 insertions(+), 28 deletions(-)

diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
index efc013a20..56ecc6a8f 100644
--- a/src/shared/gatt-client.c
+++ b/src/shared/gatt-client.c
@@ -2230,45 +2230,46 @@ static void notify_cb(struct bt_att_chan *chan, uint8_t opcode,
 					void *user_data)
 {
 	struct bt_gatt_client *client = user_data;
-	struct value_data data;
-
-	if (queue_isempty(client->notify_list))
-		return;
 
 	bt_gatt_client_ref(client);
 
-	memset(&data, 0, sizeof(data));
+	if (!queue_isempty(client->notify_list)) {
+		struct value_data data;
 
-	if (opcode == BT_ATT_OP_HANDLE_NFY_MULT) {
-		while (length >= 4) {
-			data.handle = get_le16(pdu);
-			length -= 2;
-			pdu += 2;
+		memset(&data, 0, sizeof(data));
 
-			data.len = get_le16(pdu);
-			length -= 2;
-			pdu += 2;
+		if (opcode == BT_ATT_OP_HANDLE_NFY_MULT) {
+			while (length >= 4) {
+				data.handle = get_le16(pdu);
+				length -= 2;
+				pdu += 2;
 
-			if (data.len > length)
-				data.len = length;
+				data.len = get_le16(pdu);
+				length -= 2;
+				pdu += 2;
 
-			data.data = pdu;
+				if (data.len > length)
+					data.len = length;
 
-			queue_foreach(client->notify_list, notify_handler,
-								&data);
+				data.data = pdu;
 
-			length -= data.len;
-			pdu += data.len;
-		}
-	} else {
-		data.handle = get_le16(pdu);
-		length -= 2;
-		pdu += 2;
+				queue_foreach(client->notify_list,
+					      notify_handler, &data);
 
-		data.len = length;
-		data.data = pdu;
+				length -= data.len;
+				pdu += data.len;
+			}
+		} else {
+			data.handle = get_le16(pdu);
+			length -= 2;
+			pdu += 2;
+
+			data.len = length;
+			data.data = pdu;
 
-		queue_foreach(client->notify_list, notify_handler, &data);
+			queue_foreach(client->notify_list,
+				      notify_handler, &data);
+		}
 	}
 
 	if (opcode == BT_ATT_OP_HANDLE_IND && !client->parent)
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2023-08-27 21:08 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-08-26 19:24 [PATCH BlueZ] shared/gatt-client: always send ATT confirmations Javier de San Pedro
2023-08-26 21:29 ` [BlueZ] " bluez.test.bot
2023-08-27 21:07 ` [PATCH BlueZ] " Luiz Augusto von Dentz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox