Linux bluetooth development
 help / color / mirror / Atom feed
* RE: input: avoid NSP1 disconnects caused by Sniff/Exit Sniff churn
  2026-08-26 16:41 [PATCH BlueZ 1/2] btio: add BT_IO_OPT_FORCE_ACTIVE support for L2CAP sockets Frédéric Danis
@ 2026-08-26 19:13 ` bluez.test.bot
  0 siblings, 0 replies; 5+ messages in thread
From: bluez.test.bot @ 2026-08-26 19:13 UTC (permalink / raw)
  To: linux-bluetooth, frederic.danis

[-- Attachment #1: Type: text/plain, Size: 990 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1152198

---Test result---

Test Summary:
CheckPatch                    PASS      0.63 seconds
GitLint                       PASS      0.40 seconds
BuildEll                      PASS      20.36 seconds
BluezMake                     PASS      597.60 seconds
MakeCheck                     PASS      19.56 seconds
MakeDistcheck                 PASS      159.04 seconds
CheckValgrind                 PASS      229.06 seconds
CheckSmatch                   PASS      312.41 seconds
bluezmakeextell               PASS      103.17 seconds
IncrementalBuild              PASS      601.76 seconds
ScanBuild                     PASS      1014.94 seconds



https://github.com/bluez/bluez/pull/2438

---
Regards,
Linux Bluetooth


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

* [PATCH BlueZ v2 0/2] input: avoid NSP1 disconnects caused by Sniff/Exit Sniff churn
@ 2026-09-03 11:48 Frédéric Danis
  2026-09-03 11:48 ` [PATCH BlueZ v2 1/2] btio: add BT_IO_OPT_FORCE_ACTIVE support for L2CAP sockets Frédéric Danis
  2026-09-03 11:48 ` [PATCH BlueZ v2 2/2] profiles/input: disable force-active for Nintendo Switch Pro v1 Frédéric Danis
  0 siblings, 2 replies; 5+ messages in thread
From: Frédéric Danis @ 2026-09-03 11:48 UTC (permalink / raw)
  To: linux-bluetooth

We received reports of Bluetooth instability with Nintendo Switch Pro v1
(NSP1), including unexpected disconnects during use. HCI traces indicate
the controller repeatedly requests Sniff mode while BlueZ keeps forcing
Active mode, creating frequent Sniff/Exit Sniff transitions and increasing
the chance of LMP Sniff Response failures.

This series adds generic btio support to control force-active behavior for
L2CAP sockets, then uses it in the input profile for NSP1 by disabling
force-active on the HID interrupt channel. With that, BlueZ stops
repeatedly issuing Exit Sniff requests for this device, improving
connection stability.

v1->v2: Add missing Co-developed-by tag

Frédéric Danis (2):
  btio: add BT_IO_OPT_FORCE_ACTIVE support for L2CAP sockets
  profiles/input: disable force-active for Nintendo Switch Pro v1

 btio/btio.c             | 35 +++++++++++++++++++++++++++++++----
 btio/btio.h             |  1 +
 profiles/input/device.c | 16 ++++++++++++++++
 3 files changed, 48 insertions(+), 4 deletions(-)

-- 
2.43.0


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

* [PATCH BlueZ v2 1/2] btio: add BT_IO_OPT_FORCE_ACTIVE support for L2CAP sockets
  2026-09-03 11:48 [PATCH BlueZ v2 0/2] input: avoid NSP1 disconnects caused by Sniff/Exit Sniff churn Frédéric Danis
@ 2026-09-03 11:48 ` Frédéric Danis
  2026-09-03 15:48   ` input: avoid NSP1 disconnects caused by Sniff/Exit Sniff churn bluez.test.bot
  2026-09-03 11:48 ` [PATCH BlueZ v2 2/2] profiles/input: disable force-active for Nintendo Switch Pro v1 Frédéric Danis
  1 sibling, 1 reply; 5+ messages in thread
From: Frédéric Danis @ 2026-09-03 11:48 UTC (permalink / raw)
  To: linux-bluetooth

Introduce BT_IO_OPT_FORCE_ACTIVE in btio and plumb it through option
parsing and L2CAP setup.

When set, btio now programs BT_POWER on the underlying socket, allowing
callers to explicitly control force-active behavior.

Co-developed-by: Zhongjun.Yu@quectel.com
Signed-off-by: Zhongjun.Yu@quectel.com
---
v1->v2: Add missing Co-developed-by tag

 btio/btio.c | 35 +++++++++++++++++++++++++++++++----
 btio/btio.h |  1 +
 2 files changed, 32 insertions(+), 4 deletions(-)

diff --git a/btio/btio.c b/btio/btio.c
index 4c69d6035..016035dff 100644
--- a/btio/btio.c
+++ b/btio/btio.c
@@ -68,6 +68,7 @@ struct set_opts {
 	int central;
 	uint8_t mode;
 	int flushable;
+	int force_active;
 	uint32_t priority;
 	uint16_t voice;
 	struct bt_iso_qos qos;
@@ -601,6 +602,17 @@ static int l2cap_set_flushable(int sock, gboolean flushable)
 	return 0;
 }
 
+static int l2cap_set_bt_power(int sock, int force_active)
+{
+	struct bt_power pwr = {0};
+
+	pwr.force_active = force_active;
+	if (setsockopt(sock, SOL_BLUETOOTH, BT_POWER, &pwr, sizeof(pwr)) < 0)
+		return -errno;
+
+	return 0;
+}
+
 static int set_priority(int sock, uint32_t prio)
 {
 	if (setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio)) < 0)
@@ -696,8 +708,8 @@ static gboolean set_le_mode(int sock, uint8_t mode, GError **err)
 
 static gboolean l2cap_set(int sock, uint8_t src_type, int sec_level,
 				int imtu, uint16_t omtu, uint8_t mode,
-				int central, int flushable, uint32_t priority,
-				GError **err)
+				int central, int flushable, int force_active,
+				uint32_t priority, GError **err)
 {
 	if (imtu != -1 || omtu || mode) {
 		gboolean ret = FALSE;
@@ -736,6 +748,11 @@ static gboolean l2cap_set(int sock, uint8_t src_type, int sec_level,
 		return FALSE;
 	}
 
+	if (force_active >= 0 && l2cap_set_bt_power(sock, force_active) < 0) {
+		ERROR_FAILED(err, "l2cap_set_bt_power", errno);
+		return FALSE;
+	}
+
 	if (priority > 0 && set_priority(sock, priority) < 0) {
 		ERROR_FAILED(err, "set_priority", errno);
 		return FALSE;
@@ -968,6 +985,7 @@ static gboolean parse_set_opts(struct set_opts *opts, GError **err,
 	opts->central = -1;
 	opts->mode = L2CAP_MODE_BASIC;
 	opts->flushable = -1;
+	opts->force_active = -1;
 	opts->priority = 0;
 	opts->src_type = BDADDR_BREDR;
 	opts->dst_type = BDADDR_BREDR;
@@ -1043,6 +1061,9 @@ static gboolean parse_set_opts(struct set_opts *opts, GError **err,
 		case BT_IO_OPT_FLUSHABLE:
 			opts->flushable = va_arg(args, gboolean);
 			break;
+		case BT_IO_OPT_FORCE_ACTIVE:
+			opts->force_active = va_arg(args, int);
+			break;
 		case BT_IO_OPT_PRIORITY:
 			opts->priority = va_arg(args, int);
 			break;
@@ -1387,6 +1408,7 @@ parse_opts:
 		case BT_IO_OPT_SOURCE_CHANNEL:
 		case BT_IO_OPT_DEST_CHANNEL:
 		case BT_IO_OPT_MTU:
+		case BT_IO_OPT_FORCE_ACTIVE:
 		case BT_IO_OPT_VOICE:
 		case BT_IO_OPT_QOS:
 		case BT_IO_OPT_BASE:
@@ -1544,6 +1566,7 @@ static gboolean rfcomm_get(int sock, GError **err, BtIOOption opt1,
 		case BT_IO_OPT_IMTU:
 		case BT_IO_OPT_MODE:
 		case BT_IO_OPT_FLUSHABLE:
+		case BT_IO_OPT_FORCE_ACTIVE:
 		case BT_IO_OPT_PRIORITY:
 		case BT_IO_OPT_VOICE:
 		case BT_IO_OPT_QOS:
@@ -1658,6 +1681,7 @@ static gboolean sco_get(int sock, GError **err, BtIOOption opt1, va_list args)
 		case BT_IO_OPT_CENTRAL:
 		case BT_IO_OPT_MODE:
 		case BT_IO_OPT_FLUSHABLE:
+		case BT_IO_OPT_FORCE_ACTIVE:
 		case BT_IO_OPT_PRIORITY:
 		case BT_IO_OPT_VOICE:
 		case BT_IO_OPT_QOS:
@@ -1795,6 +1819,7 @@ static gboolean iso_get(int sock, GError **err, BtIOOption opt1, va_list args)
 		case BT_IO_OPT_CENTRAL:
 		case BT_IO_OPT_MODE:
 		case BT_IO_OPT_FLUSHABLE:
+		case BT_IO_OPT_FORCE_ACTIVE:
 		case BT_IO_OPT_PRIORITY:
 		case BT_IO_OPT_VOICE:
 		case BT_IO_OPT_ISO_BC_NUM_BIS:
@@ -1963,7 +1988,8 @@ gboolean bt_io_set(GIOChannel *io, GError **err, BtIOOption opt1, ...)
 	case BT_IO_L2CAP:
 		return l2cap_set(sock, opts.src_type, opts.sec_level, opts.imtu,
 					opts.omtu, opts.mode, opts.central,
-					opts.flushable, opts.priority, err);
+					opts.flushable, opts.force_active,
+					opts.priority, err);
 	case BT_IO_RFCOMM:
 		return rfcomm_set(sock, opts.sec_level, opts.central, err);
 	case BT_IO_SCO:
@@ -2014,7 +2040,8 @@ static GIOChannel *create_io(gboolean server, struct set_opts *opts,
 			goto failed;
 		if (!l2cap_set(sock, opts->src_type, opts->sec_level,
 				opts->imtu, opts->omtu, opts->mode,
-				opts->central, opts->flushable, opts->priority,
+				opts->central, opts->flushable,
+				opts->force_active, opts->priority,
 				err))
 			goto failed;
 		break;
diff --git a/btio/btio.h b/btio/btio.h
index 3e69092b1..f088c3cd4 100644
--- a/btio/btio.h
+++ b/btio/btio.h
@@ -42,6 +42,7 @@ typedef enum {
 	BT_IO_OPT_CLASS,
 	BT_IO_OPT_MODE,
 	BT_IO_OPT_FLUSHABLE,
+	BT_IO_OPT_FORCE_ACTIVE,
 	BT_IO_OPT_PRIORITY,
 	BT_IO_OPT_VOICE,
 	BT_IO_OPT_PHY,
-- 
2.43.0


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

* [PATCH BlueZ v2 2/2] profiles/input: disable force-active for Nintendo Switch Pro v1
  2026-09-03 11:48 [PATCH BlueZ v2 0/2] input: avoid NSP1 disconnects caused by Sniff/Exit Sniff churn Frédéric Danis
  2026-09-03 11:48 ` [PATCH BlueZ v2 1/2] btio: add BT_IO_OPT_FORCE_ACTIVE support for L2CAP sockets Frédéric Danis
@ 2026-09-03 11:48 ` Frédéric Danis
  1 sibling, 0 replies; 5+ messages in thread
From: Frédéric Danis @ 2026-09-03 11:48 UTC (permalink / raw)
  To: linux-bluetooth

For Nintendo Switch Pro v1 controllers (VID:PID 057e:2009), set
BT_IO_OPT_FORCE_ACTIVE to BT_POWER_FORCE_ACTIVE_OFF on the HID interrupt
channel during connection setup.

This avoids repeated host-triggered Exit Sniff requests and reduces
Sniff/Exit Sniff churn linked to unexpected disconnects.

Co-developed-by: Zhongjun.Yu@quectel.com
Signed-off-by: Zhongjun.Yu@quectel.com
---
v1->v2: Add missing Co-developed-by tag

 profiles/input/device.c | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/profiles/input/device.c b/profiles/input/device.c
index 5b1be2b16..c2abe2451 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -1065,6 +1065,9 @@ static gboolean encrypt_notify(GIOChannel *io, GIOCondition condition,
 	return FALSE;
 }
 
+#define NINTENDO_VENDOR_ID 0x057e
+#define NINTENDO_PRO_CONTROLLER_PID 0x2009
+
 static int hidp_add_connection(struct input_device *idev)
 {
 	struct hidp_connadd_req *req;
@@ -1101,6 +1104,19 @@ static int hidp_add_connection(struct input_device *idev)
 		goto cleanup;
 	}
 
+	if ((req->vendor == NINTENDO_VENDOR_ID) &&
+		(req->product == NINTENDO_PRO_CONTROLLER_PID)) {
+		if (!bt_io_set(idev->intr_io, &gerr,
+					BT_IO_OPT_FORCE_ACTIVE,
+					BT_POWER_FORCE_ACTIVE_OFF,
+					BT_IO_OPT_INVALID)) {
+			error("btio: %s", gerr->message);
+			g_error_free(gerr);
+			err = -EFAULT;
+			goto cleanup;
+		}
+	}
+
 	/* Encryption is mandatory for keyboards */
 	/* Some platforms may choose to require encryption for all devices */
 	/* Note that this only matters for pre 2.1 devices as otherwise the */
-- 
2.43.0


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

* RE: input: avoid NSP1 disconnects caused by Sniff/Exit Sniff churn
  2026-09-03 11:48 ` [PATCH BlueZ v2 1/2] btio: add BT_IO_OPT_FORCE_ACTIVE support for L2CAP sockets Frédéric Danis
@ 2026-09-03 15:48   ` bluez.test.bot
  0 siblings, 0 replies; 5+ messages in thread
From: bluez.test.bot @ 2026-09-03 15:48 UTC (permalink / raw)
  To: linux-bluetooth, frederic.danis

[-- Attachment #1: Type: text/plain, Size: 988 bytes --]

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=1157040

---Test result---

Test Summary:
CheckPatch                    PASS      0.99 seconds
GitLint                       PASS      0.66 seconds
BuildEll                      PASS      20.29 seconds
BluezMake                     PASS      568.29 seconds
MakeCheck                     PASS      19.38 seconds
MakeDistcheck                 PASS      156.52 seconds
CheckValgrind                 PASS      224.54 seconds
CheckSmatch                   PASS      298.24 seconds
bluezmakeextell               PASS      96.20 seconds
IncrementalBuild              PASS      572.67 seconds
ScanBuild                     PASS      900.81 seconds



https://github.com/bluez/bluez/pull/2480

---
Regards,
Linux Bluetooth


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

end of thread, other threads:[~2026-09-03 15:48 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-03 11:48 [PATCH BlueZ v2 0/2] input: avoid NSP1 disconnects caused by Sniff/Exit Sniff churn Frédéric Danis
2026-09-03 11:48 ` [PATCH BlueZ v2 1/2] btio: add BT_IO_OPT_FORCE_ACTIVE support for L2CAP sockets Frédéric Danis
2026-09-03 15:48   ` input: avoid NSP1 disconnects caused by Sniff/Exit Sniff churn bluez.test.bot
2026-09-03 11:48 ` [PATCH BlueZ v2 2/2] profiles/input: disable force-active for Nintendo Switch Pro v1 Frédéric Danis
  -- strict thread matches above, loose matches on Subject: below --
2026-08-26 16:41 [PATCH BlueZ 1/2] btio: add BT_IO_OPT_FORCE_ACTIVE support for L2CAP sockets Frédéric Danis
2026-08-26 19:13 ` input: avoid NSP1 disconnects caused by Sniff/Exit Sniff churn bluez.test.bot

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