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
next prev parent 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