public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
From: Martin BTS <martinbts@gmx.net>
To: linux-bluetooth@vger.kernel.org
Cc: hadess@hadess.net, luiz.dentz@gmail.com, vi@endrift.com,
	Martin BTS <martinbts@gmx.net>
Subject: [PATCH BlueZ v3 1/6] shared/gatt: Add skip_secondary option for GATT client
Date: Fri,  3 Apr 2026 10:55:48 +0200	[thread overview]
Message-ID: <20260403085555.23871-2-martinbts@gmx.net> (raw)
In-Reply-To: <20260403085555.23871-1-martinbts@gmx.net>

Some BLE devices reject or ignore secondary service discovery requests,
causing ATT timeouts that terminate the connection. Add a skip_secondary
parameter to bt_gatt_client_new() that skips the secondary service
discovery step during GATT client initialization. Add
btd_device_set_skip_secondary() so device-specific plugins can enable
this. All existing callers pass false (no behavior change).
---
 peripheral/gatt.c        | 3 ++-
 src/device.c             | 9 ++++++++-
 src/device.h             | 1 +
 src/shared/gatt-client.c | 8 ++++++--
 src/shared/gatt-client.h | 3 ++-
 tools/btgatt-client.c    | 2 +-
 unit/test-bap.c          | 2 +-
 unit/test-gatt.c         | 2 +-
 unit/test-gmap.c         | 2 +-
 unit/test-mcp.c          | 2 +-
 unit/test-micp.c         | 3 ++-
 unit/test-tmap.c         | 2 +-
 12 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/peripheral/gatt.c b/peripheral/gatt.c
index d1ddf0c97..2af67f24a 100644
--- a/peripheral/gatt.c
+++ b/peripheral/gatt.c
@@ -121,7 +121,8 @@ static struct gatt_conn *gatt_conn_new(int fd)
 		return NULL;
 	}
 
-	conn->client = bt_gatt_client_new(gatt_cache, conn->att, mtu, 0);
+	conn->client = bt_gatt_client_new(gatt_cache, conn->att, mtu, 0,
+								false);
 	if (!conn->gatt) {
 		fprintf(stderr, "Failed to create GATT client\n");
 		bt_gatt_server_unref(conn->gatt);
diff --git a/src/device.c b/src/device.c
index 3ea683667..fbe137db7 100644
--- a/src/device.c
+++ b/src/device.c
@@ -213,6 +213,7 @@ struct btd_device {
 	bool		pending_paired;		/* "Paired" waiting for SDP */
 	bool		svc_refreshed;
 	bool		refresh_discovery;
+	bool		skip_secondary;
 
 	/* Manage whether this device can wake the system from suspend.
 	 * - wake_support: Requires a profile that supports wake (i.e. HID)
@@ -6302,7 +6303,8 @@ static void gatt_client_init(struct btd_device *device)
 	}
 
 	device->client = bt_gatt_client_new(device->db, device->att,
-						device->att_mtu, features);
+						device->att_mtu, features,
+						device->skip_secondary);
 	if (!device->client) {
 		DBG("Failed to initialize");
 		return;
@@ -8254,6 +8256,11 @@ void btd_device_set_conn_param(struct btd_device *device, uint16_t min_interval,
 					timeout);
 }
 
+void btd_device_set_skip_secondary(struct btd_device *device, bool skip)
+{
+	device->skip_secondary = skip;
+}
+
 void btd_device_foreach_service_data(struct btd_device *dev, bt_ad_func_t func,
 							void *data)
 {
diff --git a/src/device.h b/src/device.h
index c7b8b2a16..fe988652d 100644
--- a/src/device.h
+++ b/src/device.h
@@ -231,6 +231,7 @@ void btd_device_foreach_ad(struct btd_device *dev, bt_device_ad_func_t func,
 void btd_device_set_conn_param(struct btd_device *device, uint16_t min_interval,
 					uint16_t max_interval, uint16_t latency,
 					uint16_t timeout);
+void btd_device_set_skip_secondary(struct btd_device *device, bool skip);
 void btd_device_foreach_service_data(struct btd_device *dev,
 					bt_device_ad_func_t func,
 					void *data);
diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
index df1541b88..e1685809f 100644
--- a/src/shared/gatt-client.c
+++ b/src/shared/gatt-client.c
@@ -93,6 +93,7 @@ struct bt_gatt_client {
 	struct queue *notify_chrcs;
 	int next_reg_id;
 	unsigned int disc_id, nfy_id, nfy_mult_id, ind_id;
+	bool skip_secondary;
 
 	/*
 	 * Handles of the GATT Service and the Service Changed characteristic
@@ -1344,7 +1345,7 @@ secondary:
 	 * functionality of a device and is referenced from at least one
 	 * primary service on the device.
 	 */
-	if (queue_isempty(op->pending_svcs))
+	if (queue_isempty(op->pending_svcs) || client->skip_secondary)
 		goto done;
 
 	/* Discover secondary services */
@@ -2550,7 +2551,8 @@ fail:
 struct bt_gatt_client *bt_gatt_client_new(struct gatt_db *db,
 							struct bt_att *att,
 							uint16_t mtu,
-							uint8_t features)
+							uint8_t features,
+							bool skip_secondary)
 {
 	struct bt_gatt_client *client;
 
@@ -2561,6 +2563,8 @@ struct bt_gatt_client *bt_gatt_client_new(struct gatt_db *db,
 	if (!client)
 		return NULL;
 
+	client->skip_secondary = skip_secondary;
+
 	if (!gatt_client_init(client, mtu)) {
 		bt_gatt_client_free(client);
 		return NULL;
diff --git a/src/shared/gatt-client.h b/src/shared/gatt-client.h
index 63cf99500..d9655e6f0 100644
--- a/src/shared/gatt-client.h
+++ b/src/shared/gatt-client.h
@@ -19,7 +19,8 @@ struct bt_gatt_client;
 struct bt_gatt_client *bt_gatt_client_new(struct gatt_db *db,
 							struct bt_att *att,
 							uint16_t mtu,
-							uint8_t features);
+							uint8_t features,
+							bool skip_secondary);
 struct bt_gatt_client *bt_gatt_client_clone(struct bt_gatt_client *client);
 
 struct bt_gatt_client *bt_gatt_client_ref(struct bt_gatt_client *client);
diff --git a/tools/btgatt-client.c b/tools/btgatt-client.c
index 667b3d651..58999011a 100644
--- a/tools/btgatt-client.c
+++ b/tools/btgatt-client.c
@@ -206,7 +206,7 @@ static struct client *client_create(int fd, uint16_t mtu)
 		return NULL;
 	}
 
-	cli->gatt = bt_gatt_client_new(cli->db, cli->att, mtu, 0);
+	cli->gatt = bt_gatt_client_new(cli->db, cli->att, mtu, 0, false);
 	if (!cli->gatt) {
 		fprintf(stderr, "Failed to create GATT client\n");
 		gatt_db_unref(cli->db);
diff --git a/unit/test-bap.c b/unit/test-bap.c
index 3a67e7016..221bbedfb 100644
--- a/unit/test-bap.c
+++ b/unit/test-bap.c
@@ -582,7 +582,7 @@ static void test_setup(const void *user_data)
 	db = gatt_db_new();
 	g_assert(db);
 
-	data->client = bt_gatt_client_new(db, att, 64, 0);
+	data->client = bt_gatt_client_new(db, att, 64, 0, false);
 	g_assert(data->client);
 
 	bt_gatt_client_set_debug(data->client, print_debug, "bt_gatt_client:",
diff --git a/unit/test-gatt.c b/unit/test-gatt.c
index 535baafc6..8780cc4f5 100644
--- a/unit/test-gatt.c
+++ b/unit/test-gatt.c
@@ -684,7 +684,7 @@ static struct context *create_context(uint16_t mtu, gconstpointer data)
 		g_assert(context->client_db);
 
 		context->client = bt_gatt_client_new(context->client_db,
-							context->att, mtu, 0);
+						context->att, mtu, 0, false);
 		g_assert(context->client);
 
 		bt_gatt_client_set_debug(context->client, print_debug,
diff --git a/unit/test-gmap.c b/unit/test-gmap.c
index 8b37efd18..fbf1529a6 100644
--- a/unit/test-gmap.c
+++ b/unit/test-gmap.c
@@ -323,7 +323,7 @@ static void test_setup(const void *user_data)
 	db = gatt_db_new();
 	g_assert(db);
 
-	data->client = bt_gatt_client_new(db, att, 64, 0);
+	data->client = bt_gatt_client_new(db, att, 64, 0, false);
 	g_assert(data->client);
 
 	bt_gatt_client_set_debug(data->client, print_debug, "bt_gatt_client:",
diff --git a/unit/test-mcp.c b/unit/test-mcp.c
index 7d922bb83..3c5cdaad3 100644
--- a/unit/test-mcp.c
+++ b/unit/test-mcp.c
@@ -509,7 +509,7 @@ static void test_setup(const void *user_data)
 	db = gatt_db_new();
 	g_assert(db);
 
-	data->client = bt_gatt_client_new(db, att, 64, 0);
+	data->client = bt_gatt_client_new(db, att, 64, 0, false);
 	g_assert(data->client);
 
 	bt_gatt_client_set_debug(data->client, print_debug, "bt_gatt_client:",
diff --git a/unit/test-micp.c b/unit/test-micp.c
index ff17300d5..64a248a40 100644
--- a/unit/test-micp.c
+++ b/unit/test-micp.c
@@ -500,7 +500,8 @@ static void test_setup(const void *user_data)
 	db = gatt_db_new();
 	g_assert(db);
 
-	data->client = bt_gatt_client_new(db, att, MICP_GATT_CLIENT_MTU, 0);
+	data->client = bt_gatt_client_new(db, att, MICP_GATT_CLIENT_MTU, 0,
+								false);
 	g_assert(data->client);
 
 	bt_gatt_client_set_debug(data->client, print_debug, "bt_gatt_client:",
diff --git a/unit/test-tmap.c b/unit/test-tmap.c
index e75d62119..44465abf5 100644
--- a/unit/test-tmap.c
+++ b/unit/test-tmap.c
@@ -288,7 +288,7 @@ static void test_setup(const void *user_data)
 	db = gatt_db_new();
 	g_assert(db);
 
-	data->client = bt_gatt_client_new(db, att, 64, 0);
+	data->client = bt_gatt_client_new(db, att, 64, 0, false);
 	g_assert(data->client);
 
 	bt_gatt_client_set_debug(data->client, print_debug, "bt_gatt_client:",
-- 
2.47.3


  reply	other threads:[~2026-04-03  8:56 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-03  8:55 [PATCH BlueZ v3 0/6] BLE-HID/Nintendo Switch 2 support Martin BTS
2026-04-03  8:55 ` Martin BTS [this message]
2026-04-03 10:18   ` bluez.test.bot
2026-04-03  8:55 ` [PATCH BlueZ v3 2/6] shared/gatt: Add timeout for secondary service discovery Martin BTS
2026-04-03  8:55 ` [PATCH BlueZ v3 3/6] device: Rename set_alias to btd_device_set_alias() Martin BTS
2026-04-03  8:55 ` [PATCH BlueZ v3 4/6] dbus-common: Add Gaming appearance class (0x2a) Martin BTS
2026-04-03  8:55 ` [PATCH BlueZ v3 5/6] plugins/gatt-uhid: Add generic GATT-to-UHID bridge Martin BTS
2026-04-03  8:55 ` [PATCH BlueZ v3 6/6] plugins/switch2: Add Nintendo Switch 2 Controller plugin Martin BTS
  -- strict thread matches above, loose matches on Subject: below --
2026-03-17 20:26 [PATCH BlueZ v3 0/6] BLE-HID/Nintendo Switch 2 support Martin BTS
2026-03-17 20:26 ` [PATCH BlueZ v3 1/6] shared/gatt: Add skip_secondary option for GATT client Martin BTS

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260403085555.23871-2-martinbts@gmx.net \
    --to=martinbts@gmx.net \
    --cc=hadess@hadess.net \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=luiz.dentz@gmail.com \
    --cc=vi@endrift.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox