From: Kevin Dewald <kevin@simpleble.org>
To: linux-bluetooth@vger.kernel.org
Cc: Luiz Augusto von Dentz <luiz.dentz@gmail.com>,
Kevin Dewald <kevin@simpleble.org>
Subject: [PATCH BlueZ 5/5] test: functional: add bearer connection parameter tests
Date: Mon, 2 Nov 2026 23:27:49 -0800 [thread overview]
Message-ID: <20261103072749.50979-6-kevin@simpleble.org> (raw)
In-Reply-To: <20261103072749.50979-1-kevin@simpleble.org>
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)
next prev parent reply other threads:[~2026-11-03 7:27 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
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 ` Kevin Dewald [this message]
2026-11-03 16:30 ` [PATCH BlueZ 0/5] Add LE connection parameters to org.bluez.Bearer.LE1 patchwork-bot+bluetooth
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=20261103072749.50979-6-kevin@simpleble.org \
--to=kevin@simpleble.org \
--cc=linux-bluetooth@vger.kernel.org \
--cc=luiz.dentz@gmail.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