Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH BlueZ v2 1/3] emulator: bthost: add function for sending raw L2CAP sig commands
@ 2026-08-30 19:57 Pauli Virtanen
  2026-08-30 19:57 ` [PATCH BlueZ v2 2/3] tools/l2cap-server: add test for invalid Conn Req on Ext-Flowctl server Pauli Virtanen
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Pauli Virtanen @ 2026-08-30 19:57 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pauli Virtanen

Add bthost_l2cap_sig_raw() that tests can use to send raw L2CAP
signaling commands.
---

Notes:
    v2:
    - no changes

 emulator/bthost.c | 13 +++++++++++++
 emulator/bthost.h |  4 ++++
 2 files changed, 17 insertions(+)

diff --git a/emulator/bthost.c b/emulator/bthost.c
index 46c6a52f5..b3d48ffb3 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -811,6 +811,19 @@ static uint8_t l2cap_sig_send(struct bthost *bthost, struct btconn *conn,
 	return ident;
 }
 
+uint8_t bthost_l2cap_sig_raw(struct bthost *bthost, uint16_t handle,
+					uint8_t code, uint8_t ident,
+					const void *data, uint16_t len)
+{
+	struct btconn *conn;
+
+	conn = bthost_find_conn(bthost, handle);
+	if (!conn)
+		return 0;
+
+	return l2cap_sig_send(bthost, conn, code, ident, data, len);
+}
+
 void bthost_add_cid_hook(struct bthost *bthost, uint16_t handle, uint16_t cid,
 				bthost_cid_hook_func_t func, void *user_data)
 {
diff --git a/emulator/bthost.h b/emulator/bthost.h
index e104e68af..ed924eb99 100644
--- a/emulator/bthost.h
+++ b/emulator/bthost.h
@@ -126,6 +126,10 @@ bool bthost_l2cap_req(struct bthost *bthost, uint16_t handle, uint8_t req,
 				const void *data, uint16_t len,
 				bthost_l2cap_rsp_cb cb, void *user_data);
 
+uint8_t bthost_l2cap_sig_raw(struct bthost *bthost, uint16_t handle,
+						uint8_t req, uint8_t ident,
+						const void *data, uint16_t len);
+
 void bthost_write_scan_enable(struct bthost *bthost, uint8_t scan);
 
 void bthost_set_adv_data(struct bthost *bthost, const uint8_t *data,
-- 
2.55.0


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

* [PATCH BlueZ v2 2/3] tools/l2cap-server: add test for invalid Conn Req on Ext-Flowctl server
  2026-08-30 19:57 [PATCH BlueZ v2 1/3] emulator: bthost: add function for sending raw L2CAP sig commands Pauli Virtanen
@ 2026-08-30 19:57 ` Pauli Virtanen
  2026-08-30 19:57 ` [PATCH BlueZ v2 3/3] tools/l2cap-tester: test closing sockets with ECRED defer Pauli Virtanen
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Pauli Virtanen @ 2026-08-30 19:57 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pauli Virtanen

Add test that checks Ext-Flowctl server handles invalid connection
requests with ident collisions. This triggers null-deref crash / hang on
some kernel versions.

L2CAP Ext-Flowctl Server - Nval Conn Req
---

Notes:
    v2:
    - no changes

 tools/l2cap-tester.c | 169 ++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 160 insertions(+), 9 deletions(-)

diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c
index 69c529aa8..efff5c2d8 100644
--- a/tools/l2cap-tester.c
+++ b/tools/l2cap-tester.c
@@ -30,6 +30,7 @@
 
 #include "src/shared/tester.h"
 #include "src/shared/mgmt.h"
+#include "src/shared/queue.h"
 #include "src/shared/util.h"
 
 #include "tester.h"
@@ -51,6 +52,7 @@ struct test_data {
 	int sk2;
 	bool host_disconnected;
 	int step;
+	struct queue *io_channels;
 	struct tx_tstamp_data tx_ts;
 };
 
@@ -267,6 +269,11 @@ static void test_pre_setup(const void *test_data)
 					read_index_list_callback, NULL, NULL);
 }
 
+static void io_channel_unref(void *data)
+{
+	g_io_channel_unref(data);
+}
+
 static void test_post_teardown(const void *test_data)
 {
 	struct test_data *data = tester_get_data();
@@ -281,6 +288,9 @@ static void test_post_teardown(const void *test_data)
 		data->err_io_id = 0;
 	}
 
+	queue_destroy(data->io_channels, io_channel_unref);
+	data->io_channels = NULL;
+
 	hciemu_unref(data->hciemu);
 	data->hciemu = NULL;
 }
@@ -1137,6 +1147,12 @@ static const struct l2cap_data ext_flowctl_server_nval_scid_test = {
 	.expect_cmd_len = sizeof(nval_ecred_connect_rsp),
 };
 
+static const struct l2cap_data ext_flowctl_server_nval_conn_req_test = {
+	.server_psm = 0x0080,
+	.defer = true,
+	.mode = BT_MODE_EXT_FLOWCTL,
+};
+
 static const struct l2cap_data ext_flowctl_server_phy_test = {
 	.server_psm = 0x0080,
 	.send_cmd_code = BT_L2CAP_PDU_ECRED_CONN_REQ,
@@ -2897,6 +2913,8 @@ static gboolean l2cap_accept_cb(GIOChannel *io, GIOCondition cond,
 	const struct l2cap_data *l2data = data->test_data;
 	int sk, err;
 
+	data->io_id = 0;
+
 	sk = g_io_channel_unix_get_fd(io);
 
 	if (!check_mtu(data, sk)) {
@@ -2929,7 +2947,8 @@ static gboolean l2cap_accept_cb(GIOChannel *io, GIOCondition cond,
 	return FALSE;
 }
 
-static bool defer_accept(struct test_data *data, GIOChannel *io)
+static bool defer_accept(struct test_data *data, GIOChannel *io,
+							GIOFunc accept_cb)
 {
 	int sk;
 	char c;
@@ -2953,11 +2972,12 @@ static bool defer_accept(struct test_data *data, GIOChannel *io)
 		}
 	}
 
-	data->io_id = g_io_add_watch(io, G_IO_OUT, l2cap_accept_cb, NULL);
+	if (accept_cb)
+		data->io_id = g_io_add_watch(io, G_IO_OUT, accept_cb, NULL);
 
 	g_io_channel_unref(io);
 
-	tester_print("Accept deferred setup");
+	tester_print("Accept deferred setup sk = %d", sk);
 
 	return true;
 }
@@ -2980,6 +3000,8 @@ static gboolean l2cap_listen_cb(GIOChannel *io, GIOCondition cond,
 		return FALSE;
 	}
 
+	tester_print("Accept sk = %d", new_sk);
+
 	io = g_io_channel_unix_new(new_sk);
 	g_io_channel_set_close_on_unref(io, TRUE);
 
@@ -2989,7 +3011,7 @@ static gboolean l2cap_listen_cb(GIOChannel *io, GIOCondition cond,
 			return FALSE;
 		}
 
-		if (!defer_accept(data, io)) {
+		if (!defer_accept(data, io, l2cap_accept_cb)) {
 			tester_warn("Unable to accept deferred setup");
 			tester_test_failed();
 		}
@@ -3098,7 +3120,8 @@ static void send_req_new_conn(uint16_t handle, void *user_data)
 	}
 }
 
-static void test_server(const void *test_data)
+static void start_test_server(const void *test_data, bthost_new_conn_cb conn_cb,
+							GIOFunc listen_cb)
 {
 	struct test_data *data = tester_get_data();
 	const struct l2cap_data *l2data = data->test_data;
@@ -3128,7 +3151,7 @@ static void test_server(const void *test_data)
 			return;
 		}
 
-		if (listen(sk, 5) < 0) {
+		if (listen(sk, 32) < 0) {
 			tester_warn("listening on socket failed: %s (%u)",
 					strerror(errno), errno);
 			tester_test_failed();
@@ -3139,8 +3162,7 @@ static void test_server(const void *test_data)
 		io = g_io_channel_unix_new(sk);
 		g_io_channel_set_close_on_unref(io, TRUE);
 
-		data->io_id = g_io_add_watch(io, G_IO_IN, l2cap_listen_cb,
-									NULL);
+		data->io_id = g_io_add_watch(io, G_IO_IN, listen_cb, NULL);
 		g_io_channel_unref(io);
 
 		tester_print("Listening for connections");
@@ -3154,7 +3176,7 @@ static void test_server(const void *test_data)
 	}
 
 	bthost = hciemu_client_get_host(data->hciemu);
-	bthost_set_connect_cb(bthost, send_req_new_conn, data);
+	bthost_set_connect_cb(bthost, conn_cb, data);
 
 	if (data->hciemu_type == HCIEMU_TYPE_BREDR)
 		addr_type = BDADDR_BREDR;
@@ -3164,6 +3186,130 @@ static void test_server(const void *test_data)
 	bthost_hci_connect(bthost, central_bdaddr, addr_type);
 }
 
+static void test_server(const void *test_data)
+{
+	start_test_server(test_data, send_req_new_conn, l2cap_listen_cb);
+}
+
+static gboolean ext_flowctl_nval_conn_req_ready_cb(gpointer ptr)
+{
+	struct test_data *data = tester_get_data();
+	const struct queue_entry *entry;
+	GIOFunc cb = l2cap_accept_cb;
+
+	if (data->io_id) {
+		g_source_remove(data->io_id);
+		data->io_id = 0;
+	}
+
+	data->err_io_id = 0;
+	data->step = 0;
+
+	tester_print("Accepting %d deferred", queue_length(data->io_channels));
+
+	entry = queue_get_entries(data->io_channels);
+	for (; entry; entry = entry->next) {
+		GIOChannel *io = entry->data;
+
+		if (!defer_accept(data, g_io_channel_ref(io), cb)) {
+			g_io_channel_unref(io);
+			tester_warn("Unable to accept deferred setup");
+			tester_test_failed();
+			break;
+		}
+
+		/* Require only the first to connect */
+		cb = NULL;
+	}
+
+	return FALSE;
+}
+
+static gboolean ext_flowctl_nval_conn_req_listen_cb(GIOChannel *io,
+					GIOCondition cond, gpointer user_data)
+{
+	struct test_data *data = tester_get_data();
+	int sk, new_sk;
+	GIOChannel *new_io;
+
+	if (!data->step)
+		return FALSE;
+
+	sk = g_io_channel_unix_get_fd(io);
+
+	new_sk = accept(sk, NULL, NULL);
+	if (new_sk < 0) {
+		tester_warn("accept failed: %s (%u)", strerror(errno), errno);
+		tester_test_failed();
+		return FALSE;
+	}
+
+	tester_print("Accept sk = %d", new_sk);
+
+	new_io = g_io_channel_unix_new(new_sk);
+	g_io_channel_set_close_on_unref(new_io, TRUE);
+
+	if (!data->io_channels)
+		data->io_channels = queue_new();
+	queue_push_tail(data->io_channels, new_io);
+
+	if (data->err_io_id) {
+		g_source_remove(data->err_io_id);
+		data->err_io_id = 0;
+	}
+
+	/* Accept all deferred connections at once, or until timeout */
+	data->step--;
+	if (!data->step) {
+		data->io_id = 0;
+		ext_flowctl_nval_conn_req_ready_cb(NULL);
+		return FALSE;
+	}
+
+	data->err_io_id = g_timeout_add(1000,
+				ext_flowctl_nval_conn_req_ready_cb, NULL);
+
+	return TRUE;
+}
+
+static void ext_flowctl_nval_conn_req_conn_cb(uint16_t handle, void *user_data)
+{
+	struct test_data *data = user_data;
+	struct bthost *bthost;
+	int i;
+
+	tester_print("New client connection with handle 0x%04x", handle);
+
+	bthost = hciemu_client_get_host(data->hciemu);
+
+	tester_print("Sending %d L2CAP_LE_CONN_REQ", data->step);
+
+	/* All L2CAP_LE_CONN_REQ (0x14) use the same PSM, same ident, different
+	 * SCID.  Receiver may reject some of these due to ident collision,
+	 * but at least it should not hang/crash.
+	 */
+	for (i = 0; i < data->step; ++i) {
+		uint8_t cmd[] = {
+			/* PSM(2), SCID(2), MTU(2), MPS(2), Crd(2) */
+			0x80, 0x00, 0x40 + i, 0x00,
+			0x40, 0x00, 0x40, 0x00,
+			0x05, 0x00
+		};
+
+		bthost_l2cap_sig_raw(bthost, handle, 0x14, 0x9f,
+							cmd, ARRAY_SIZE(cmd));
+	}
+}
+
+static void test_ext_flowctl_server_nval_conn_req(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+
+	data->step = 32;
+	start_test_server(test_data, ext_flowctl_nval_conn_req_conn_cb,
+					ext_flowctl_nval_conn_req_listen_cb);
+}
+
 static void test_getpeername_not_connected(const void *test_data)
 {
 	struct test_data *data = tester_get_data();
@@ -3550,6 +3696,11 @@ int main(int argc, char *argv[])
 				&ext_flowctl_server_set_phy_coded_test,
 				setup_powered_server, test_server);
 
+	test_l2cap_le_52("L2CAP Ext-Flowctl Server - Nval Conn Req",
+				&ext_flowctl_server_nval_conn_req_test,
+				setup_powered_server,
+				test_ext_flowctl_server_nval_conn_req);
+
 	test_l2cap_le("L2CAP LE ATT Client - Success",
 				&le_att_client_connect_success_test_1,
 				setup_powered_client, test_connect);
-- 
2.55.0


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

* [PATCH BlueZ v2 3/3] tools/l2cap-tester: test closing sockets with ECRED defer
  2026-08-30 19:57 [PATCH BlueZ v2 1/3] emulator: bthost: add function for sending raw L2CAP sig commands Pauli Virtanen
  2026-08-30 19:57 ` [PATCH BlueZ v2 2/3] tools/l2cap-server: add test for invalid Conn Req on Ext-Flowctl server Pauli Virtanen
@ 2026-08-30 19:57 ` Pauli Virtanen
  2026-08-30 21:59 ` [BlueZ,v2,1/3] emulator: bthost: add function for sending raw L2CAP sig commands bluez.test.bot
  2026-08-31 17:30 ` [PATCH BlueZ v2 1/3] " patchwork-bot+bluetooth
  3 siblings, 0 replies; 5+ messages in thread
From: Pauli Virtanen @ 2026-08-30 19:57 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pauli Virtanen

Add test that does defer accept with ECRED with 1 SCIDs, and
accepts + closes the first before accepting the second. This triggers
deadlock on some kernel versions.

L2CAP Ext-Flowctl Server - Accept 2 Close 1
---

Notes:
    v2:
    - new test
    
    Lockdep fails to print a splat for this deadlock, since l2cap_sock.c is
    mixing lock_sock(sk) == lock_sock(sk, 0) and lock_sock_nested, and the
    normal sockets are at nesting level 1...

 tools/l2cap-tester.c | 66 ++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c
index efff5c2d8..3f78fc86b 100644
--- a/tools/l2cap-tester.c
+++ b/tools/l2cap-tester.c
@@ -1153,6 +1153,24 @@ static const struct l2cap_data ext_flowctl_server_nval_conn_req_test = {
 	.mode = BT_MODE_EXT_FLOWCTL,
 };
 
+static const uint8_t ecred_connect_req_2[] = {
+						0x80, 0x00, /* PSM */
+						0x40, 0x00, /* MTU */
+						0x40, 0x00, /* MPS */
+						0x05, 0x00, /* Credits */
+						0x41, 0x00, /* SCID #1 */
+						0x42, 0x00, /* SCID #2 */
+};
+
+static const struct l2cap_data ext_flowctl_server_accept_2_close_1_test = {
+	.server_psm = 0x0080,
+	.defer = true,
+	.mode = BT_MODE_EXT_FLOWCTL,
+	.send_cmd_code = BT_L2CAP_PDU_ECRED_CONN_REQ,
+	.send_cmd = ecred_connect_req_2,
+	.send_cmd_len = ARRAY_SIZE(ecred_connect_req_2)
+};
+
 static const struct l2cap_data ext_flowctl_server_phy_test = {
 	.server_psm = 0x0080,
 	.send_cmd_code = BT_L2CAP_PDU_ECRED_CONN_REQ,
@@ -3191,6 +3209,50 @@ static void test_server(const void *test_data)
 	start_test_server(test_data, send_req_new_conn, l2cap_listen_cb);
 }
 
+static gboolean ext_flowctl_accept_2_close_1_listen_cb(GIOChannel *io,
+					GIOCondition cond, gpointer user_data)
+{
+	struct test_data *data = tester_get_data();
+	int sk, new_sk;
+	int err = 0;
+
+	sk = g_io_channel_unix_get_fd(io);
+
+	new_sk = accept(sk, NULL, NULL);
+	if (err < 0) {
+		tester_warn("accept failed: %s (%u)", strerror(errno), errno);
+		tester_test_failed();
+		return FALSE;
+	}
+
+	if (!defer_accept(data, g_io_channel_unix_new(new_sk), NULL))
+		goto fail;
+
+	close(new_sk);
+
+	if (data->step--)
+		return TRUE;
+
+	tester_test_passed();
+
+	data->io_id = 0;
+	return FALSE;
+
+fail:
+	tester_test_failed();
+	close(new_sk);
+	return FALSE;
+}
+
+static void test_ext_flowctl_server_accept_2_close_1(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+
+	data->step = 1;
+	start_test_server(test_data, send_req_new_conn,
+					ext_flowctl_accept_2_close_1_listen_cb);
+}
+
 static gboolean ext_flowctl_nval_conn_req_ready_cb(gpointer ptr)
 {
 	struct test_data *data = tester_get_data();
@@ -3680,6 +3742,10 @@ int main(int argc, char *argv[])
 	test_l2cap_le("L2CAP Ext-Flowctl Server - Nval SCID",
 				&ext_flowctl_server_nval_scid_test,
 				setup_powered_server, test_server);
+	test_l2cap_le("L2CAP Ext-Flowctl Server - Accept 2 Close 1",
+				&ext_flowctl_server_accept_2_close_1_test,
+				setup_powered_server,
+				test_ext_flowctl_server_accept_2_close_1);
 	test_l2cap_le("L2CAP Ext-Flowctl Server - PHY",
 				&ext_flowctl_server_phy_test,
 				setup_powered_server, test_server);
-- 
2.55.0


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

* RE: [BlueZ,v2,1/3] emulator: bthost: add function for sending raw L2CAP sig commands
  2026-08-30 19:57 [PATCH BlueZ v2 1/3] emulator: bthost: add function for sending raw L2CAP sig commands Pauli Virtanen
  2026-08-30 19:57 ` [PATCH BlueZ v2 2/3] tools/l2cap-server: add test for invalid Conn Req on Ext-Flowctl server Pauli Virtanen
  2026-08-30 19:57 ` [PATCH BlueZ v2 3/3] tools/l2cap-tester: test closing sockets with ECRED defer Pauli Virtanen
@ 2026-08-30 21:59 ` bluez.test.bot
  2026-08-31 17:30 ` [PATCH BlueZ v2 1/3] " patchwork-bot+bluetooth
  3 siblings, 0 replies; 5+ messages in thread
From: bluez.test.bot @ 2026-08-30 21:59 UTC (permalink / raw)
  To: linux-bluetooth, pav

[-- Attachment #1: Type: text/plain, Size: 1673 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=1153985

---Test result---

Test Summary:
CheckPatch                    PASS      1.61 seconds
GitLint                       FAIL      0.97 seconds
BuildEll                      PASS      20.15 seconds
BluezMake                     PASS      593.18 seconds
CheckSmatch                   WARNING   312.74 seconds
bluezmakeextell               PASS      102.11 seconds
IncrementalBuild              PASS      595.19 seconds
ScanBuild                     PASS      972.72 seconds

Details
##############################
Test: GitLint - FAIL
Desc: Run gitlint
Output:
[BlueZ,v2,2/3] tools/l2cap-server: add test for invalid Conn Req on Ext-Flowctl server

1: T1 Title exceeds max length (86>80): "[BlueZ,v2,2/3] tools/l2cap-server: add test for invalid Conn Req on Ext-Flowctl server"
[BlueZ,v2,3/3] tools/l2cap-tester: test closing sockets with ECRED defer

13: B2 Line has trailing whitespace: "    "
##############################
Test: CheckSmatch - WARNING
Desc: Run smatch tool with source
Output:
emulator/bthost.c:703:28: warning: Variable length array is used.emulator/bthost.c:704:32: warning: Variable length array is used.emulator/bthost.c:957:28: warning: Variable length array is used.emulator/bthost.c:991:28: warning: Variable length array is used.emulator/bthost.c:992:32: warning: Variable length array is used.


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

---
Regards,
Linux Bluetooth


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

* Re: [PATCH BlueZ v2 1/3] emulator: bthost: add function for sending raw L2CAP sig commands
  2026-08-30 19:57 [PATCH BlueZ v2 1/3] emulator: bthost: add function for sending raw L2CAP sig commands Pauli Virtanen
                   ` (2 preceding siblings ...)
  2026-08-30 21:59 ` [BlueZ,v2,1/3] emulator: bthost: add function for sending raw L2CAP sig commands bluez.test.bot
@ 2026-08-31 17:30 ` patchwork-bot+bluetooth
  3 siblings, 0 replies; 5+ messages in thread
From: patchwork-bot+bluetooth @ 2026-08-31 17:30 UTC (permalink / raw)
  To: Pauli Virtanen; +Cc: linux-bluetooth

Hello:

This series was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:

On Sun, 30 Aug 2026 22:57:22 +0300 you wrote:
> Add bthost_l2cap_sig_raw() that tests can use to send raw L2CAP
> signaling commands.
> ---
> 
> Notes:
>     v2:
>     - no changes
> 
> [...]

Here is the summary with links:
  - [BlueZ,v2,1/3] emulator: bthost: add function for sending raw L2CAP sig commands
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=d52d9a173a5f
  - [BlueZ,v2,2/3] tools/l2cap-server: add test for invalid Conn Req on Ext-Flowctl server
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=3a2d543c4c21
  - [BlueZ,v2,3/3] tools/l2cap-tester: test closing sockets with ECRED defer
    (no matching commit)

You are awesome, thank you!
-- 
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html



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

end of thread, other threads:[~2026-08-31 17:31 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-30 19:57 [PATCH BlueZ v2 1/3] emulator: bthost: add function for sending raw L2CAP sig commands Pauli Virtanen
2026-08-30 19:57 ` [PATCH BlueZ v2 2/3] tools/l2cap-server: add test for invalid Conn Req on Ext-Flowctl server Pauli Virtanen
2026-08-30 19:57 ` [PATCH BlueZ v2 3/3] tools/l2cap-tester: test closing sockets with ECRED defer Pauli Virtanen
2026-08-30 21:59 ` [BlueZ,v2,1/3] emulator: bthost: add function for sending raw L2CAP sig commands bluez.test.bot
2026-08-31 17:30 ` [PATCH BlueZ v2 1/3] " patchwork-bot+bluetooth

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