Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH BlueZ 0/5] Add LE connection parameters to org.bluez.Bearer.LE1
@ 2026-11-03  7:27 Kevin Dewald
  2026-11-03  7:27 ` [PATCH BlueZ 1/5] doc/mgmt: Document Connection Subrate for LE connections and updates Kevin Dewald
                   ` (5 more replies)
  0 siblings, 6 replies; 8+ messages in thread
From: Kevin Dewald @ 2026-11-03  7:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Luiz Augusto von Dentz, Kevin Dewald

Applications have no way to know the parameters of an LE connection:
the interval, peripheral latency and supervision timeout. They decide
how fast data can move and how quickly a lost link is noticed, so
applications that need them end up reading them from HCI traffic.

This adds Interval, Latency, SupervisionTimeout and Subrate properties
to org.bluez.Bearer.LE1, filled from the MGMT Connection Subrate event,
which bluetoothd already registers but only logs. With "Bluetooth: MGMT:
Send Connection Subrate on LE connection and update", now in
bluetooth-next, the kernel sends that event when an LE connection is
established and after each LE Connection Update, not only on LE
Connection Rate Change.

The properties are only present while connected over LE. Interval is in
microseconds, as with Shorter Connection Intervals it is no longer a
multiple of 1.25 ms, and SupervisionTimeout is in milliseconds. They are
not marked experimental, since the tests come with them, but I can mark
them so if you prefer. There is no command to read the parameters, so
when bluetoothd starts while a device is already connected over LE, the
properties only appear once the parameters change.

The two new functional tests check that both hosts report the
parameters once connected, follow a connection update the peripheral
asks for, and drop them on disconnection. On bluetooth-next the bearer
tests pass in 3 of 3 runs; without the kernel patch the new tests fail.
make check and the functional tests using HoG, btmgmt, bluetoothctl or
the agent pass.

Kevin Dewald (5):
  doc/mgmt: Document Connection Subrate for LE connections and updates
  org.bluez.Bearer: Add connection parameter properties
  bearer: Add connection parameter properties
  client: Print LE connection parameters in info
  test: functional: add bearer connection parameter tests

 client/main.c                  |   5 ++
 doc/functional-bearer.rst      |  43 ++++++++++++
 doc/mgmt-protocol.rst          |   8 ++-
 doc/org.bluez.Bearer.LE.rst    |  38 ++++++++++
 src/adapter.c                  |  12 ++++
 src/bearer.c                   | 122 +++++++++++++++++++++++++++++++++
 src/bearer.h                   |   3 +
 src/device.c                   |   8 +++
 src/device.h                   |   3 +
 test/functional/test_bearer.py |  78 +++++++++++++++++++++
 10 files changed, 319 insertions(+), 1 deletion(-)


base-commit: 14bd6ab65f4a647302edbd6df27f6faa91bee8a8
-- 
2.54.0 (Apple Git-157)


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

* [PATCH BlueZ 1/5] doc/mgmt: Document Connection Subrate for LE connections and updates
  2026-11-03  7:27 [PATCH BlueZ 0/5] Add LE connection parameters to org.bluez.Bearer.LE1 Kevin Dewald
@ 2026-11-03  7:27 ` Kevin Dewald
  2026-11-03  8:56   ` Add LE connection parameters to org.bluez.Bearer.LE1 bluez.test.bot
  2026-11-03  7:27 ` [PATCH BlueZ 2/5] org.bluez.Bearer: Add connection parameter properties Kevin Dewald
                   ` (4 subsequent siblings)
  5 siblings, 1 reply; 8+ messages in thread
From: Kevin Dewald @ 2026-11-03  7:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Luiz Augusto von Dentz, Kevin Dewald

With "Bluetooth: MGMT: Send Connection Subrate on LE connection and
update", now in bluetooth-next, the kernel also sends the Connection
Subrate event when an LE connection is established and after each LE
Connection Update, so the connection parameters are known on
controllers without the Shorter Connection Interval feature, and a
failed connection rate change reports the current parameters. Document
this, and the Subrate and Continuation_Number values these events
carry.

Assisted-by: Claude:claude-opus-5.5
---
 doc/mgmt-protocol.rst | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/doc/mgmt-protocol.rst b/doc/mgmt-protocol.rst
index ed2bd3349..bf6a3b200 100644
--- a/doc/mgmt-protocol.rst
+++ b/doc/mgmt-protocol.rst
@@ -5520,6 +5520,11 @@ This event indicates that the connection rate has changed for a device. This
 can be a result of a successful LE Connection Rate Request or a change
 initiated by the remote device.
 
+It is also sent when an LE connection is established and after each LE
+Connection Update, which do not report subrating: the Subrate and
+Continuation_Number parameters then keep the values of the last connection
+rate change, or 1 and 0 if there was none.
+
 Possible values for the Address_Type parameter:
 
 .. csv-table::
@@ -5529,7 +5534,8 @@ Possible values for the Address_Type parameter:
 	0x01, LE Public
 	0x02, LE Random
 
-The Status indicates whether the connection rate change was successful.
+The Status indicates whether the connection rate change was successful. When it
+was not, the other parameters are the current ones of the connection.
 
 The Interval parameter specifies the new connection interval in units of
 0.125 ms.
-- 
2.54.0 (Apple Git-157)


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

* [PATCH BlueZ 2/5] org.bluez.Bearer: Add connection parameter properties
  2026-11-03  7:27 [PATCH BlueZ 0/5] Add LE connection parameters to org.bluez.Bearer.LE1 Kevin Dewald
  2026-11-03  7:27 ` [PATCH BlueZ 1/5] doc/mgmt: Document Connection Subrate for LE connections and updates Kevin Dewald
@ 2026-11-03  7:27 ` Kevin Dewald
  2026-11-03  7:27 ` [PATCH BlueZ 3/5] bearer: " Kevin Dewald
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Kevin Dewald @ 2026-11-03  7:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Luiz Augusto von Dentz, Kevin Dewald

This adds Interval, Latency, SupervisionTimeout and Subrate properties
to org.bluez.Bearer.LE1 with the parameters of the current LE
connection, so applications can see the connection parameters in use,
e.g. to estimate throughput and latency, without reading HCI traffic.

Assisted-by: Claude:claude-opus-5.5
---
 doc/org.bluez.Bearer.LE.rst | 38 +++++++++++++++++++++++++++++++++++++
 1 file changed, 38 insertions(+)

diff --git a/doc/org.bluez.Bearer.LE.rst b/doc/org.bluez.Bearer.LE.rst
index 6d3df3fcf..3db5237b4 100644
--- a/doc/org.bluez.Bearer.LE.rst
+++ b/doc/org.bluez.Bearer.LE.rst
@@ -177,3 +177,41 @@ Possible values:
 	peripheral.
 
 A PropertiesChanged signal indicate changes to this status.
+
+uint32 Interval [readonly, optional]
+````````````````````````````````````
+
+Indicates the connection interval of the current connection on LE bearer, in
+microseconds. It is only present while the remote device is connected over LE
+bearer.
+
+A PropertiesChanged signal indicate changes to this status.
+
+uint16 Latency [readonly, optional]
+```````````````````````````````````
+
+Indicates the peripheral latency of the current connection on LE bearer, the
+number of consecutive connection events the peripheral may skip. When the
+connection is subrated, it counts subrated connection events. It is only present
+while the remote device is connected over LE bearer.
+
+A PropertiesChanged signal indicate changes to this status.
+
+uint16 SupervisionTimeout [readonly, optional]
+``````````````````````````````````````````````
+
+Indicates the supervision timeout of the current connection on LE bearer, in
+milliseconds. It is only present while the remote device is connected over LE
+bearer.
+
+A PropertiesChanged signal indicate changes to this status.
+
+uint16 Subrate [readonly, optional]
+```````````````````````````````````
+
+Indicates the subrate factor of the current connection on LE bearer: only one of
+every Subrate connection events is used. It is 1 when the connection is not
+subrated. It is only present while the remote device is connected over LE
+bearer.
+
+A PropertiesChanged signal indicate changes to this status.
-- 
2.54.0 (Apple Git-157)


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

* [PATCH BlueZ 3/5] bearer: Add connection parameter properties
  2026-11-03  7:27 [PATCH BlueZ 0/5] Add LE connection parameters to org.bluez.Bearer.LE1 Kevin Dewald
  2026-11-03  7:27 ` [PATCH BlueZ 1/5] doc/mgmt: Document Connection Subrate for LE connections and updates Kevin Dewald
  2026-11-03  7:27 ` [PATCH BlueZ 2/5] org.bluez.Bearer: Add connection parameter properties Kevin Dewald
@ 2026-11-03  7:27 ` Kevin Dewald
  2026-11-03  7:27 ` [PATCH BlueZ 4/5] client: Print LE connection parameters in info Kevin Dewald
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 8+ messages in thread
From: Kevin Dewald @ 2026-11-03  7:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Luiz Augusto von Dentz, Kevin Dewald

This implements the Interval, Latency, SupervisionTimeout and Subrate
properties of org.bluez.Bearer.LE1 with the values of the MGMT
Connection Subrate event, which the kernel sends when an LE connection
is established and whenever its parameters change.

Assisted-by: Claude:claude-opus-5.5
---
 src/adapter.c |  12 +++++
 src/bearer.c  | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++
 src/bearer.h  |   3 ++
 src/device.c  |   8 ++++
 src/device.h  |   3 ++
 5 files changed, 148 insertions(+)

diff --git a/src/adapter.c b/src/adapter.c
index edd2fdaf4..5ecb3c784 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -9506,6 +9506,7 @@ static void conn_subrate_evt(uint16_t index, uint16_t length,
 	const struct mgmt_ev_conn_subrate *ev = param;
 	struct btd_adapter *adapter = user_data;
 	uint16_t interval, subrate, latency, cont_num, supv_timeout;
+	struct btd_device *device;
 	char dst[18];
 
 	if (length < sizeof(*ev)) {
@@ -9532,6 +9533,17 @@ static void conn_subrate_evt(uint16_t index, uint16_t length,
 		"cont_num 0x%04x timeout 0x%04x", adapter->dev_id, dst,
 		ev->addr.type, interval, subrate, latency, cont_num,
 		supv_timeout);
+
+	device = btd_adapter_find_device(adapter, &ev->addr.bdaddr,
+							ev->addr.type);
+	if (!device)
+		return;
+
+	/* The interval is in units of 0.125 ms and the supervision timeout
+	 * in units of 10 ms.
+	 */
+	device_set_le_conn_params(device, interval * 125, latency,
+					supv_timeout * 10, subrate);
 }
 
 int adapter_set_io_capability(struct btd_adapter *adapter,
diff --git a/src/bearer.c b/src/bearer.c
index 51dd789f1..5285e0274 100644
--- a/src/bearer.c
+++ b/src/bearer.c
@@ -56,6 +56,13 @@ struct btd_bearer {
 	 * additional connect messages.
 	 */
 	DBusMessage *connect; /* connect message */
+
+	/* LE connection parameters, only valid while connected */
+	bool conn_params;
+	uint32_t interval; /* in microseconds */
+	uint16_t latency;
+	uint16_t supv_timeout; /* in milliseconds */
+	uint16_t subrate;
 };
 
 static void bearer_free_dbus_message(void *data)
@@ -304,6 +311,58 @@ static gboolean bearer_role_exists(const GDBusPropertyTable *property,
 	return btd_device_bdaddr_type_connected(bearer->device, bearer->type);
 }
 
+static gboolean bearer_get_interval(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct btd_bearer *bearer = data;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32,
+							&bearer->interval);
+
+	return TRUE;
+}
+
+static gboolean bearer_get_latency(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct btd_bearer *bearer = data;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16,
+							&bearer->latency);
+
+	return TRUE;
+}
+
+static gboolean bearer_get_supv_timeout(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct btd_bearer *bearer = data;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16,
+							&bearer->supv_timeout);
+
+	return TRUE;
+}
+
+static gboolean bearer_get_subrate(const GDBusPropertyTable *property,
+					DBusMessageIter *iter, void *data)
+{
+	struct btd_bearer *bearer = data;
+
+	dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16,
+							&bearer->subrate);
+
+	return TRUE;
+}
+
+static gboolean bearer_conn_params_exists(const GDBusPropertyTable *property,
+								void *data)
+{
+	struct btd_bearer *bearer = data;
+
+	return bearer->conn_params;
+}
+
 static const GDBusSignalTable bearer_signals[] = {
 	{ GDBUS_SIGNAL("Disconnected",
 			GDBUS_ARGS({ "name", "s" }, { "message", "s" })) },
@@ -318,6 +377,14 @@ static const GDBusPropertyTable bearer_properties[] = {
 	{ "Connectable", "b", bearer_get_connectable, NULL,
 					bearer_connectable_exists },
 	{ "Role", "s", bearer_get_role, NULL, bearer_role_exists },
+	{ "Interval", "u", bearer_get_interval, NULL,
+					bearer_conn_params_exists },
+	{ "Latency", "q", bearer_get_latency, NULL,
+					bearer_conn_params_exists },
+	{ "SupervisionTimeout", "q", bearer_get_supv_timeout, NULL,
+					bearer_conn_params_exists },
+	{ "Subrate", "q", bearer_get_subrate, NULL,
+					bearer_conn_params_exists },
 	{}
 };
 
@@ -418,6 +485,59 @@ void btd_bearer_connectable(struct btd_bearer *bearer)
 					"Connectable");
 }
 
+static void bearer_conn_param_changed(struct btd_bearer *bearer,
+							const char *name)
+{
+	g_dbus_emit_property_changed(btd_get_dbus_connection(), bearer->path,
+					bearer_interface(bearer->type), name);
+}
+
+void btd_bearer_conn_params(struct btd_bearer *bearer, uint32_t interval,
+				uint16_t latency, uint16_t supv_timeout,
+				uint16_t subrate)
+{
+	bool added;
+
+	if (!bearer || !bearer->path)
+		return;
+
+	added = !bearer->conn_params;
+	bearer->conn_params = true;
+
+	if (added || bearer->interval != interval) {
+		bearer->interval = interval;
+		bearer_conn_param_changed(bearer, "Interval");
+	}
+
+	if (added || bearer->latency != latency) {
+		bearer->latency = latency;
+		bearer_conn_param_changed(bearer, "Latency");
+	}
+
+	if (added || bearer->supv_timeout != supv_timeout) {
+		bearer->supv_timeout = supv_timeout;
+		bearer_conn_param_changed(bearer, "SupervisionTimeout");
+	}
+
+	if (added || bearer->subrate != subrate) {
+		bearer->subrate = subrate;
+		bearer_conn_param_changed(bearer, "Subrate");
+	}
+}
+
+static void bearer_clear_conn_params(struct btd_bearer *bearer)
+{
+	if (!bearer->conn_params)
+		return;
+
+	bearer->conn_params = false;
+
+	bearer_conn_param_changed(bearer, "Interval");
+	bearer_conn_param_changed(bearer, "Latency");
+	bearer_conn_param_changed(bearer, "SupervisionTimeout");
+	bearer_conn_param_changed(bearer, "Subrate");
+}
+
 void btd_bearer_connected(struct btd_bearer *bearer, int err)
 {
 	DBusMessage *reply;
@@ -488,6 +608,8 @@ void btd_bearer_disconnected(struct btd_bearer *bearer, uint8_t reason)
 					bearer_interface(bearer->type),
 					"Role");
 
+	bearer_clear_conn_params(bearer);
+
 	switch (reason) {
 	case MGMT_DEV_DISCONN_UNKNOWN:
 		name = "org.bluez.Reason.Unknown";
diff --git a/src/bearer.h b/src/bearer.h
index 238d0a17c..26530c11a 100644
--- a/src/bearer.h
+++ b/src/bearer.h
@@ -19,5 +19,8 @@ void btd_bearer_destroy(struct btd_bearer *bearer);
 void btd_bearer_paired(struct btd_bearer *bearer);
 void btd_bearer_bonded(struct btd_bearer *bearer);
 void btd_bearer_connectable(struct btd_bearer *bearer);
+void btd_bearer_conn_params(struct btd_bearer *bearer, uint32_t interval,
+				uint16_t latency, uint16_t supv_timeout,
+				uint16_t subrate);
 void btd_bearer_connected(struct btd_bearer *bearer, int err);
 void btd_bearer_disconnected(struct btd_bearer *bearer, uint8_t reason);
diff --git a/src/device.c b/src/device.c
index 4567188d6..137970637 100644
--- a/src/device.c
+++ b/src/device.c
@@ -8523,6 +8523,14 @@ void btd_device_set_conn_param(struct btd_device *device, uint16_t min_interval,
 					timeout);
 }
 
+void device_set_le_conn_params(struct btd_device *device, uint32_t interval,
+				uint16_t latency, uint16_t supv_timeout,
+				uint16_t subrate)
+{
+	btd_bearer_conn_params(device->le, interval, latency, supv_timeout,
+								subrate);
+}
+
 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 5ead73958..6756cb3ab 100644
--- a/src/device.h
+++ b/src/device.h
@@ -249,6 +249,9 @@ 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 device_set_le_conn_params(struct btd_device *device, uint32_t interval,
+				uint16_t latency, uint16_t supv_timeout,
+				uint16_t subrate);
 void btd_device_foreach_service_data(struct btd_device *dev,
 					bt_device_ad_func_t func,
 					void *data);
-- 
2.54.0 (Apple Git-157)


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

* [PATCH BlueZ 4/5] client: Print LE connection parameters in info
  2026-11-03  7:27 [PATCH BlueZ 0/5] Add LE connection parameters to org.bluez.Bearer.LE1 Kevin Dewald
                   ` (2 preceding siblings ...)
  2026-11-03  7:27 ` [PATCH BlueZ 3/5] bearer: " Kevin Dewald
@ 2026-11-03  7:27 ` Kevin Dewald
  2026-11-03  7:27 ` [PATCH BlueZ 5/5] test: functional: add bearer connection parameter tests Kevin Dewald
  2026-11-03 16:30 ` [PATCH BlueZ 0/5] Add LE connection parameters to org.bluez.Bearer.LE1 patchwork-bot+bluetooth
  5 siblings, 0 replies; 8+ messages in thread
From: Kevin Dewald @ 2026-11-03  7:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Luiz Augusto von Dentz, Kevin Dewald

This prints the connection parameter properties of the LE bearer with
the likes of info command:

bluetoothctl> info <addr>
...
        LE.Role: central
        LE.Interval: 0x00007530 (30000)
        LE.Latency: 0x0000 (0)
        LE.SupervisionTimeout: 0x07d0 (2000)
        LE.Subrate: 0x0001 (1)

Assisted-by: Claude:claude-opus-5.5
---
 client/main.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/client/main.c b/client/main.c
index 01ed00073..1131c2ae3 100644
--- a/client/main.c
+++ b/client/main.c
@@ -2098,6 +2098,11 @@ static void cmd_info(int argc, char *argv[])
 		print_property_with_label(bearer, "Connectable",
 							"LE.Connectable");
 		print_property_with_label(bearer, "Role", "LE.Role");
+		print_property_with_label(bearer, "Interval", "LE.Interval");
+		print_property_with_label(bearer, "Latency", "LE.Latency");
+		print_property_with_label(bearer, "SupervisionTimeout",
+						"LE.SupervisionTimeout");
+		print_property_with_label(bearer, "Subrate", "LE.Subrate");
 	}
 
 	return bt_shell_noninteractive_quit(EXIT_SUCCESS);
-- 
2.54.0 (Apple Git-157)


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

* [PATCH BlueZ 5/5] test: functional: add bearer connection parameter tests
  2026-11-03  7:27 [PATCH BlueZ 0/5] Add LE connection parameters to org.bluez.Bearer.LE1 Kevin Dewald
                   ` (3 preceding siblings ...)
  2026-11-03  7:27 ` [PATCH BlueZ 4/5] client: Print LE connection parameters in info Kevin Dewald
@ 2026-11-03  7:27 ` Kevin Dewald
  2026-11-03 16:30 ` [PATCH BlueZ 0/5] Add LE connection parameters to org.bluez.Bearer.LE1 patchwork-bot+bluetooth
  5 siblings, 0 replies; 8+ messages in thread
From: Kevin Dewald @ 2026-11-03  7:27 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Luiz Augusto von Dentz, Kevin Dewald

This adds test_bearer_le_conn_params, which checks both hosts report the
same connection parameters on the LE bearer while connected and that
they are gone once disconnected, and test_bearer_le_conn_update, which
checks Interval follows a connection update the peripheral asks for,
and documents them in functional-bearer.

Assisted-by: Claude:claude-opus-5.5
---
 doc/functional-bearer.rst      | 43 +++++++++++++++++++
 test/functional/test_bearer.py | 78 ++++++++++++++++++++++++++++++++++
 2 files changed, 121 insertions(+)

diff --git a/doc/functional-bearer.rst b/doc/functional-bearer.rst
index de69b489b..8331a2a6d 100644
--- a/doc/functional-bearer.rst
+++ b/doc/functional-bearer.rst
@@ -62,6 +62,49 @@ test_bearer_le_connect
 	   ``org.bluez.Reason.Remote`` on host1. ``Connected`` is false on
 	   both hosts and ``Role`` is no longer present.
 
+test_bearer_le_conn_params
+--------------------------
+
+:Setup: As above, over LE.
+
+:Steps:
+	1. host0 connects to host1, as in test_bearer_le_connect.
+	2. Both hosts read ``Interval``, ``Latency``, ``SupervisionTimeout``
+	   and ``Subrate`` on the LE bearer.
+	3. host0 calls ``org.bluez.Bearer.LE1.Disconnect``.
+
+:Expected:
+	1. ``Connect`` replies.
+	2. Both hosts report the same values, ``Subrate`` is 1, and the
+	   supervision timeout is longer than twice ``(1 + Latency) *
+	   Interval``, as the Core specification requires, which also
+	   checks the units of the properties.
+	3. ``Disconnect`` replies, and the four properties are no longer
+	   present on either host.
+
+:Notes: The values are not checked against the defaults, as the kernel
+	of host0 may keep connection parameters for host1 from an earlier
+	test on the same VM instance, e.g. after pairing.
+
+test_bearer_le_conn_update
+--------------------------
+
+:Setup: As above, over LE, except host1 runs **bluetoothd(8)** with a
+	connection interval of 100 ms (``MinConnectionInterval`` and
+	``MaxConnectionInterval`` of 80).
+
+:Steps:
+	1. host0 connects to host1, as in test_bearer_le_connect.
+	2. Both hosts read ``Interval`` on the LE bearer.
+
+:Expected:
+	1. ``Connect`` replies.
+	2. ``Interval`` becomes 100000 on both hosts.
+
+:Notes: host0 connects with a shorter interval, which is outside the
+	range of host1, so the kernel of host1 asks host0 to update the
+	connection with an L2CAP Connection Parameter Update Request.
+
 test_bearer_le_connectable
 --------------------------
 
diff --git a/test/functional/test_bearer.py b/test/functional/test_bearer.py
index 69eed15c4..59ce8ef7d 100644
--- a/test/functional/test_bearer.py
+++ b/test/functional/test_bearer.py
@@ -48,6 +48,12 @@ BROADCAST_UUID = "6e2c1d84-7a3b-4f50-9c1e-5b8d2a7f0e13"
 # other host exports, which would need an agent reply in every test
 ARGS = ("-P", "midi")
 
+# host1 wants a 100 ms connection interval (80 units of 1.25 ms), so it asks
+# host0 to update the connection once connected
+UPDATE_CONF = LE_CONF + "[LE]\nMinConnectionInterval = 80\nMaxConnectionInterval = 80\n"
+
+CONN_PARAMS = ("Interval", "Latency", "SupervisionTimeout", "Subrate")
+
 
 class Bearers(HostPlugin, EventPluginMixin):
     """
@@ -188,6 +194,25 @@ def peers(host0, host1):
     return ((host0, host1), (host1, host0))
 
 
+def conn_params(host, remote):
+    """
+    The connection parameters of the LE bearer host has for remote, or
+    None if they are not present.
+    """
+    values = [host.bearers.get(remote.bdaddr, LE_INTERFACE, n) for n in CONN_PARAMS]
+    if None in values:
+        return None
+
+    return dict(zip(CONN_PARAMS, map(int, values)))
+
+
+def connect_le(host0, host1):
+    discover(host0, host1)
+
+    host0.bearers.call(host1.bdaddr, LE_INTERFACE, "Connect")
+    host0.bearers.expect(f"{LE_INTERFACE}.Connect:reply")
+
+
 def disconnect(host0, host1, interface):
     """
     Disconnect the bearer from host0, and check it is reported as
@@ -230,6 +255,59 @@ def test_bearer_le_connect(hosts):
         assert host.bearers.get(remote.bdaddr, LE_INTERFACE, "Role") is None
 
 
+@le_config
+def test_bearer_le_conn_params(hosts):
+    host0, host1 = hosts
+
+    connect_le(host0, host1)
+
+    for host, remote in peers(host0, host1):
+        wait_until(lambda: conn_params(host, remote) is not None)
+
+    # The parameters are not known in advance, as the kernel of host0 may
+    # keep connection parameters for host1 from an earlier test, but both
+    # ends of the connection report the same ones
+    params = conn_params(host0, host1)
+    assert conn_params(host1, host0) == params
+    assert params["Subrate"] == 1
+
+    # The supervision timeout is longer than twice the time between the
+    # connection events the peripheral listens to
+    timeout = params["SupervisionTimeout"] * 1000
+    assert timeout > 2 * (1 + params["Latency"]) * params["Interval"]
+
+    disconnect(host0, host1, LE_INTERFACE)
+
+    for host, remote in peers(host0, host1):
+        for name in CONN_PARAMS:
+            assert host.bearers.get(remote.bdaddr, LE_INTERFACE, name) is None
+
+
+@host_config(
+    [
+        Bluetoothd(conf=LE_CONF, args=ARGS),
+        Agent(capability="NoInputNoOutput"),
+        Bearers(),
+    ],
+    [
+        Bluetoothd(conf=UPDATE_CONF, args=ARGS),
+        LeAdvertiser(),
+        Agent(capability="NoInputNoOutput"),
+        Bearers(),
+    ],
+)
+def test_bearer_le_conn_update(hosts):
+    host0, host1 = hosts
+
+    connect_le(host0, host1)
+
+    for host, remote in peers(host0, host1):
+        wait_until(
+            lambda: host.bearers.get(remote.bdaddr, LE_INTERFACE, "Interval")
+            == "100000"
+        )
+
+
 @host_config(
     [Bluetoothd(conf=SCANNER_CONF, args=ARGS), Agent(), Bearers()],
     # A broadcaster, so neither connectable nor discoverable
-- 
2.54.0 (Apple Git-157)


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

* RE: Add LE connection parameters to org.bluez.Bearer.LE1
  2026-11-03  7:27 ` [PATCH BlueZ 1/5] doc/mgmt: Document Connection Subrate for LE connections and updates Kevin Dewald
@ 2026-11-03  8:56   ` bluez.test.bot
  0 siblings, 0 replies; 8+ messages in thread
From: bluez.test.bot @ 2026-11-03  8:56 UTC (permalink / raw)
  To: linux-bluetooth, kevin

[-- Attachment #1: Type: text/plain, Size: 3310 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/series/1199871/

---Test result---

Test Summary:
CheckPatch                    PASS      2.65 seconds
GitLint                       PASS      1.42 seconds
BuildEll                      PASS      18.70 seconds
BluezMake                     PASS      270.41 seconds
MakeCheck                     PASS      13.99 seconds
MakeDistcheck                 PASS      137.94 seconds
CheckValgrind                 PASS      225.99 seconds
CheckSmatch                   PASS      237.40 seconds
bluezmakeextell               PASS      90.37 seconds
TestFunctional                FAIL      1102.51 seconds
IncrementalBuild              PASS      304.24 seconds
ScanBuild                     PASS      944.67 seconds

Details
##############################
Test: TestFunctional - FAIL
Desc: Run test-functional
Output:
FAIL functional.test_bluetoothctl::test_bluetoothctl_pair_bredr[hosts16-vm2]: pytest_bluezenv.rpc.RemoteError: <pexpect.popen_spawn.PopenSpawn object at 0x7f0ba9926510>
    searcher: searcher_re:
        0: re.compile(b'Changing pairable on succeeded')
    <pexpect.popen_spawn.PopenSpawn object at 0x7f0ba9926510>
    searcher: searcher_re:
        0: re.compile(b'Changing pairable on succeeded')
    Remote traceback:
        Traceback (most recent call last):
          File "/usr/local/lib/python3.14/dist-packages/pytest_bluezenv/../pytest_bluezenv/rpc.py", line 102, in server_stream
            result = method(*msg["a"], **msg["kw"])
          File "/usr/local/lib/python3.14/dist-packages/pytest_bluezenv/../pytest_bluezenv/env.py", line 256, in call_plugin
            return getattr(self.plugins[name], method)(*a, **kw)
                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^
          File "/usr/local/lib/python3.14/dist-packages/pytest_bluezenv/../pytest_bluezenv/host_plugins.py", line 502, in expect
            ret = self.ctl.expect(*a, **kw)
          File "/usr/lib/python3/dist-packages/pexpect/spawnbase.py", line 354, in expect
            return self.expect_list(compiled_pattern_list,
                   ~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^
                    timeout, searchwindowsize, async_)
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
          File "/usr/lib/python3/dist-packages/pexpect/spawnbase.py", line 383, in expect_list
            return exp.expect_loop(timeout)
                   ~~~~~~~~~~~~~~~^^^^^^^^^
          File "/usr/lib/python3/dist-packages/pexpect/expect.py", line 181, in expect_loop
            return self.timeout(e)
                   ~~~~~~~~~~~~^^^
          File "/usr/lib/python3/dist-packages/pexpect/expect.py", line 144, in timeout
            raise exc
        pexpect.exceptions.TIMEOUT: <pexpect.popen_spawn.PopenSpawn object at 0x7f0ba9926510>
        searcher: searcher_re:
            0: re.compile(b'Changing pairable on succeeded')
        <pexpect.popen_spawn.PopenSpawn object at 0x7f0ba9926510>
        searcher: searcher_re:
            0: re.compile(b'Changing pairable on succeeded')


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

---
Regards,
Linux Bluetooth


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

* Re: [PATCH BlueZ 0/5] Add LE connection parameters to org.bluez.Bearer.LE1
  2026-11-03  7:27 [PATCH BlueZ 0/5] Add LE connection parameters to org.bluez.Bearer.LE1 Kevin Dewald
                   ` (4 preceding siblings ...)
  2026-11-03  7:27 ` [PATCH BlueZ 5/5] test: functional: add bearer connection parameter tests Kevin Dewald
@ 2026-11-03 16:30 ` patchwork-bot+bluetooth
  5 siblings, 0 replies; 8+ messages in thread
From: patchwork-bot+bluetooth @ 2026-11-03 16:30 UTC (permalink / raw)
  To: Kevin Dewald; +Cc: linux-bluetooth, luiz.dentz

Hello:

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

On Mon,  2 Nov 2026 23:27:44 -0800 you wrote:
> Applications have no way to know the parameters of an LE connection:
> the interval, peripheral latency and supervision timeout. They decide
> how fast data can move and how quickly a lost link is noticed, so
> applications that need them end up reading them from HCI traffic.
> 
> This adds Interval, Latency, SupervisionTimeout and Subrate properties
> to org.bluez.Bearer.LE1, filled from the MGMT Connection Subrate event,
> which bluetoothd already registers but only logs. With "Bluetooth: MGMT:
> Send Connection Subrate on LE connection and update", now in
> bluetooth-next, the kernel sends that event when an LE connection is
> established and after each LE Connection Update, not only on LE
> Connection Rate Change.
> 
> [...]

Here is the summary with links:
  - [BlueZ,1/5] doc/mgmt: Document Connection Subrate for LE connections and updates
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=4382352a3214
  - [BlueZ,2/5] org.bluez.Bearer: Add connection parameter properties
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=65cfa00be28b
  - [BlueZ,3/5] bearer: Add connection parameter properties
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=cbac1283b7d9
  - [BlueZ,4/5] client: Print LE connection parameters in info
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=8e89e98a4b76
  - [BlueZ,5/5] test: functional: add bearer connection parameter tests
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=aaf8f96f42d1

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] 8+ messages in thread

end of thread, other threads:[~2026-11-03 16:30 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-03  7:27 [PATCH BlueZ 0/5] Add LE connection parameters to org.bluez.Bearer.LE1 Kevin Dewald
2026-11-03  7:27 ` [PATCH BlueZ 1/5] doc/mgmt: Document Connection Subrate for LE connections and updates Kevin Dewald
2026-11-03  8:56   ` Add LE connection parameters to org.bluez.Bearer.LE1 bluez.test.bot
2026-11-03  7:27 ` [PATCH BlueZ 2/5] org.bluez.Bearer: Add connection parameter properties Kevin Dewald
2026-11-03  7:27 ` [PATCH BlueZ 3/5] bearer: " Kevin Dewald
2026-11-03  7:27 ` [PATCH BlueZ 4/5] client: Print LE connection parameters in info Kevin Dewald
2026-11-03  7:27 ` [PATCH BlueZ 5/5] test: functional: add bearer connection parameter tests Kevin Dewald
2026-11-03 16:30 ` [PATCH BlueZ 0/5] Add LE connection parameters to org.bluez.Bearer.LE1 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