From 805b1f5bf596d747f28f53191b7a28507efb7797 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Danis?= <frederic.danis@collabora.com>
Date: Thu, 25 Jan 2024 20:08:01 +0100
Subject: [PATCH BlueZ 1/5] shared/gatt: Prevent security level change for PTS
 GATT tests
Content-Type: text/plain; charset="utf-8"
Content-Transfer-Encoding: 8bit

Some PTS GATT tests like GATT/CL/GAR/BI-04-C request to be able to get the
security error and do not try to change the security level.

This commit adds the ability to prevent to change the security level for
an operation.
---
 src/shared/att.c         | 26 ++++++++++++++++++++++++++
 src/shared/att.h         |  1 +
 src/shared/gatt-client.c | 19 +++++++++++++++++++
 src/shared/gatt-client.h |  3 +++
 4 files changed, 49 insertions(+)

diff --git a/src/shared/att.c b/src/shared/att.c
index 85feead77..64544f89b 100644
--- a/src/shared/att.c
+++ b/src/shared/att.c
@@ -2034,3 +2034,29 @@ bool bt_att_has_crypto(struct bt_att *att)
 
 	return att->crypto ? true : false;
 }
+
+bool bt_att_set_retry(struct bt_att *att, unsigned int id, bool retry)
+{
+	struct att_send_op *op;
+
+	if (!id)
+		return false;
+
+	op = queue_find(att->req_queue, match_op_id, UINT_TO_PTR(id));
+	if (op)
+		goto done;
+
+	op = queue_find(att->ind_queue, match_op_id, UINT_TO_PTR(id));
+	if (op)
+		goto done;
+
+	op = queue_find(att->write_queue, match_op_id, UINT_TO_PTR(id));
+
+done:
+	if (!op)
+		return false;
+
+	op->retry = !retry;
+
+	return true;
+}
diff --git a/src/shared/att.h b/src/shared/att.h
index 4aa3de87b..6fd78636e 100644
--- a/src/shared/att.h
+++ b/src/shared/att.h
@@ -110,3 +110,4 @@ bool bt_att_set_local_key(struct bt_att *att, uint8_t sign_key[16],
 bool bt_att_set_remote_key(struct bt_att *att, uint8_t sign_key[16],
 			bt_att_counter_func_t func, void *user_data);
 bool bt_att_has_crypto(struct bt_att *att);
+bool bt_att_set_retry(struct bt_att *att, unsigned int id, bool retry);
diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
index efc013a20..2c16e78be 100644
--- a/src/shared/gatt-client.c
+++ b/src/shared/gatt-client.c
@@ -3817,3 +3817,22 @@ bool bt_gatt_client_idle_unregister(struct bt_gatt_client *client,
 
 	return false;
 }
+
+bool bt_gatt_client_set_retry(struct bt_gatt_client *client,
+					unsigned int id,
+					bool retry)
+{
+	struct request *req;
+
+	if (!client || !id)
+		return false;
+
+	req = queue_find(client->pending_requests, match_req_id,
+							UINT_TO_PTR(id));
+	if (!req)
+		return false;
+
+	bt_att_set_retry(client->att, req->att_id, retry);
+
+	return true;
+}
diff --git a/src/shared/gatt-client.h b/src/shared/gatt-client.h
index bccd04a62..63cf99500 100644
--- a/src/shared/gatt-client.h
+++ b/src/shared/gatt-client.h
@@ -134,3 +134,6 @@ unsigned int bt_gatt_client_idle_register(struct bt_gatt_client *client,
 					bt_gatt_client_destroy_func_t destroy);
 bool bt_gatt_client_idle_unregister(struct bt_gatt_client *client,
 						unsigned int id);
+bool bt_gatt_client_set_retry(struct bt_gatt_client *client,
+					unsigned int id,
+					bool retry);
-- 
2.34.1

