All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Frédéric Danis" <frederic.danis@collabora.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH BlueZ 1/2] btio: add BT_IO_OPT_FORCE_ACTIVE support for L2CAP sockets
Date: Wed, 26 Aug 2026 18:41:05 +0200	[thread overview]
Message-ID: <20260826164106.293951-2-frederic.danis@collabora.com> (raw)
In-Reply-To: <20260826164106.293951-1-frederic.danis@collabora.com>

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.
---
 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


  reply	other threads:[~2026-08-26 16:41 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-26 16:41 [PATCH BlueZ 0/2] input: avoid NSP1 disconnects caused by Sniff/Exit Sniff churn Frédéric Danis
2026-08-26 16:41 ` Frédéric Danis [this message]
2026-08-26 19:13   ` bluez.test.bot
2026-08-26 16:41 ` [PATCH BlueZ 2/2] profiles/input: disable force-active for Nintendo Switch Pro v1 Frédéric Danis
2026-08-26 16:58 ` [PATCH BlueZ 0/2] input: avoid NSP1 disconnects caused by Sniff/Exit Sniff churn Luiz Augusto von Dentz

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=20260826164106.293951-2-frederic.danis@collabora.com \
    --to=frederic.danis@collabora.com \
    --cc=linux-bluetooth@vger.kernel.org \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.