From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH BlueZ v6 06/23] doc: Add functional-hog documentation
Date: Mon, 28 Sep 2026 16:00:12 -0400 [thread overview]
Message-ID: <20260928200031.1209311-7-luiz.dentz@gmail.com> (raw)
In-Reply-To: <20260928200031.1209311-1-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Document the HoG functional tests, where bluetoothctl registers a HID
Service with and without Shorter Connection Interval (SCI) support
using client/scripts/hog-device*.bt, and the HID host:
- checks HID Information, HID SCI Mode and HID SCI Information with
gatt.select-attribute/gatt.read
- receives a few Input Reports notified by the HID device
- changes the SCI mode, followed by the connection rate with
mgmt.conn-subrate, and receives the notification from the HID device
confirming the mode has been changed
Assisted-by: OpenCode:claude-opus-5.5
---
Makefile.am | 1 +
doc/functional-hog.rst | 188 +++++++++++++++++++++++++++++++++++++
doc/functional-testing.rst | 1 +
3 files changed, 190 insertions(+)
create mode 100644 doc/functional-hog.rst
diff --git a/Makefile.am b/Makefile.am
index 53a3a15c3f8b..c88e81f937ff 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -501,6 +501,7 @@ EXTRA_DIST += doc/assigned-numbers.rst doc/supported-features.txt \
doc/functional-a2dp.rst \
doc/functional-avrcp.rst \
doc/functional-bap.rst \
+ doc/functional-hog.rst \
doc/functional-mpris-proxy.rst \
doc/functional-obex.rst \
doc/settings-storage.txt
diff --git a/doc/functional-hog.rst b/doc/functional-hog.rst
new file mode 100644
index 000000000000..d748f241a378
--- /dev/null
+++ b/doc/functional-hog.rst
@@ -0,0 +1,188 @@
+==============
+functional-hog
+==============
+
+DESCRIPTION
+===========
+
+HID over GATT (HoG) functional tests, `test/functional/test_hog.py`,
+driven through **bluetoothctl(1)**. See **functional-testing(7)** for
+the conventions used here, and **test-functional(1)** for how to run
+the suite.
+
+SETUP
+=====
+
+Two hosts, connected over LE, both running **bluetoothd(8)** with
+``ControllerMode = le`` and ``ExportClaimedServices = read-write``, as
+the HID Service is claimed by the input plugin of the HID host and
+bluetoothctl has to write HID SCI Mode:
+
+.. code-block::
+
+ +------------------------+ +------------------------+
+ | host0 | LE | host1 |
+ | central | --------------> | peripheral |
+ | bluetoothctl | | bluetoothctl |
+ | HID host | GATT (HIDS) | hog-device[-sci].bt |
+ | | <============== | HID Service |
+ +------------------------+ +------------------------+
+
+ --> connection is initiated by ==> reports flow towards
+
+host1 starts `bluetoothctl` with a script registering a HID Service
+(HIDS, ``00001812-0000-1000-8000-00805f9b34fb``) acting as a keyboard,
+through the ``gatt.register-service``, ``gatt.register-characteristic``
+and ``gatt.register-descriptor`` commands:
+
+``client/scripts/hog-device.bt``
+ HIDS without Shorter Connection Interval (SCI) support:
+
+ - HID Information (0x2A4A): ``11 01 00 02``, i.e. bcdHID 1.11,
+ bCountryCode 0x00 and Flags NormallyConnectable.
+ - Report Map (0x2A4B): keyboard with Report ID 1.
+ - Report (0x2A4D), with a Report Reference descriptor (0x2908)
+ ``01 01``, i.e. Report ID 1, Input Report.
+ - Protocol Mode (0x2A4E): ``01``, i.e. Report Protocol Mode.
+ - HID Control Point (0x2A4C).
+
+``client/scripts/hog-device-sci.bt``
+ Same as above, with SCI support:
+
+ - HID Information (0x2A4A): ``11 01 00 06``, i.e. the SCI
+ Supported flag (0x04) is set as well.
+ - HID SCI Mode (0x2C39): ``00``, i.e. None, with the notify
+ property so the HID device can confirm a mode change.
+ - HID SCI Information (0x2C3A): ``08 01 08 00 50 00 08 00``, i.e.
+ Minimum Supported Connection Interval 1 ms, and one subgroup
+ with Min 1 ms, Max 10 ms and Stride 1 ms (in units of 0.125 ms).
+
+Both scripts set the advertising data to the HIDS UUID and the
+keyboard appearance (0x03C1). The same scripts can be used manually to
+emulate a HoG device:
+
+.. code-block::
+
+ $ bluetoothctl --init-script client/scripts/hog-device-sci.bt
+ [bluetoothctl]> advertise on
+
+host0 runs a plain `bluetoothctl`, and both use
+``-a auto:NoInputNoOutput`` so pairing is Just Works.
+
+TEST CASES
+==========
+
+test_hog[no-sci]
+----------------
+
+:Setup: As above, with ``client/scripts/hog-device.bt`` on host1.
+
+:Steps:
+ 1. host1: start `bluetoothctl` with the script.
+ 2. host0: ``scan on``; host1: ``advertise on``.
+ 3. host0: ``pair <host1 bdaddr>``.
+ 4. host0: ``info <host1 bdaddr>``.
+ 5. host0: ``gatt.select-attribute 2a4a`` and ``gatt.read``.
+ 6. host0: ``gatt.select-attribute 2a4d`` and ``gatt.notify on``.
+ 7. host1: ``gatt.select-attribute local
+ /org/bluez/app/service0/chrc2``, then for each report
+ ``gatt.write "<report>"``: ``00 00 04 00 00 00 00 00`` (a
+ pressed), ``02 00 05 00 00 00 00 00`` (Left Shift + b pressed)
+ and ``00 00 00 00 00 00 00 00`` (released).
+
+:Expected:
+ 1. ``Application registered`` on host1.
+ 2. ``Advertising object registered`` on host1 and the device found
+ on host0.
+ 3. ``Pairing successful`` and ``ServicesResolved: yes``.
+ 4. ``Human Interface Device (00001812-...)`` is listed in the UUIDs.
+ 5. HID Information reads ``11 01 00 02``:
+
+ .. code-block::
+
+ [bluetoothctl]> gatt.select-attribute 2a4a
+ [bluetoothctl]> gatt.read
+ Attempting to read /org/bluez/hci0/dev_XX/service0013/char001e
+ 11 01 00 02 ....
+
+ 6. ``Notify started``, and the Report subscribed on host1
+ (``Notify sock acquired``, as the input plugin already
+ subscribed with AcquireNotify).
+ 7. Each report is notified to host0, in order:
+
+ .. code-block::
+
+ [CHG] Attribute /org/bluez/hci0/dev_XX/service0013/char0018 Value:
+ 00 00 04 00 00 00 00 00 ........
+
+:Notes: The service is checked at the GATT level only, so the test
+ does not depend on the kernel supporting uhid. The HID Service is
+ claimed by the input plugin on host0, but it is still exported
+ read-only over D-Bus by default (see ``ExportClaimedServices`` in
+ **bluetoothd(8)**), so it can be read with bluetoothctl.
+
+test_hog[sci]
+-------------
+
+:Setup: As above, with ``client/scripts/hog-device-sci.bt`` on host1.
+
+:Steps: As for test_hog[no-sci], then:
+
+ 8. host0: ``gatt.select-attribute 2c39`` and ``gatt.read``.
+ 9. host0: ``gatt.select-attribute 2c3a`` and ``gatt.read``.
+ 10. host0: ``gatt.select-attribute 2c39`` and ``gatt.notify on``.
+ 11. host0: ``gatt.write "0x03"``, i.e. SCI Fast Mode.
+ 12. host0: ``mgmt.conn-subrate <host1 bdaddr> 0x0008 0x0010 1 1 0 0
+ 0x01f4``, i.e. interval 1 ms to 2 ms, within the range given in
+ HID SCI Information, no subrating, no latency and 5 s
+ supervision timeout.
+ 13. host1: ``gatt.select-attribute local
+ /org/bluez/app/service0/chrc5`` and ``gatt.write "0x03"``.
+
+:Expected: As for test_hog[no-sci], except HID Information reads
+ ``11 01 00 06``, then:
+
+ 8. HID SCI Mode reads ``00``.
+ 9. HID SCI Information reads ``08 01 08 00 50 00 08 00``.
+ 10. ``Notify started`` and HID SCI Mode subscribed on host1.
+ 11. host1 receives the write:
+
+ .. code-block::
+
+ [/org/bluez/app/service0/chrc5 (HID SCI Mode)] WriteValue: XX offset 0 link LE
+ 03 .
+
+ 12. ``Connection Subrate loaded successfully``, then the MGMT
+ Connection Subrate event with the new interval on both hosts:
+
+ .. code-block::
+
+ hci0 XX type LE Public connection subrate interval 0x0008 subrate 0x0001 latency 0x0000 cont_num 0x0000 timeout 0x01f4
+
+ 13. The new mode is notified to host0, confirming it has been
+ changed:
+
+ .. code-block::
+
+ [CHG] Attribute /org/bluez/hci0/dev_XX/service0015/char0018 Value:
+ 03 .
+
+ .. code-block::
+
+ [bluetoothctl]> gatt.select-attribute 2c39
+ [bluetoothctl]> gatt.read
+ 00 .
+
+ [bluetoothctl]> gatt.select-attribute 2c3a
+ [bluetoothctl]> gatt.read
+ 08 01 08 00 50 00 08 00 ....P...
+
+:Notes: As the SCI Supported flag is set, the input plugin on host0
+ reads HID SCI Mode and HID SCI Information as well, which can be
+ seen in the **bluetoothd(8)** debug output (``SCI Mode:`` and
+ ``SCI Info:``).
+
+ The kernel only issues the LE Connection Rate Request as central,
+ so the connection rate is changed by the HID host. This requires
+ the controllers to support Shorter Connection Intervals, which
+ btvirt emulates as a BR/EDR/LE 6.2 controller.
diff --git a/doc/functional-testing.rst b/doc/functional-testing.rst
index ca7bfa672a76..7b3cad1c66b1 100644
--- a/doc/functional-testing.rst
+++ b/doc/functional-testing.rst
@@ -15,6 +15,7 @@ are documented separately:
- **functional-a2dp(7)**: `test/functional/test_a2dp.py`
- **functional-avrcp(7)**: `test/functional/test_avrcp.py`
- **functional-bap(7)**: `test/functional/test_bap.py`
+- **functional-hog(7)**: `test/functional/test_hog.py`
- **functional-mpris-proxy(7)**: `test/functional/test_mpris_proxy.py`
- **functional-obex(7)**: `test/functional/test_obex.py`
--
2.55.0
next prev parent reply other threads:[~2026-09-28 20:00 UTC|newest]
Thread overview: 26+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-28 20:00 [PATCH BlueZ v6 00/23] Add HoG functional tests and shared/hog Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 01/23] shared/gatt-client: Fix calling destroy after unregistering notify Luiz Augusto von Dentz
2026-09-28 22:26 ` Add HoG functional tests and shared/hog bluez.test.bot
2026-09-28 20:00 ` [PATCH BlueZ v6 02/23] client/gatt: Fix setting descriptor value from scripts Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 03/23] client/mgmt: Print Connection Subrate event Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 04/23] emulator: Default to the latest BR/EDR+LE version Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 05/23] client/scripts: Add HoG device scripts Luiz Augusto von Dentz
2026-09-28 20:00 ` Luiz Augusto von Dentz [this message]
2026-09-28 20:00 ` [PATCH BlueZ v6 07/23] test: functional: add HoG tests Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 08/23] test: functional: limit the workers by the memory available Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 09/23] client/agent: Fix crash on Cancel with no pending request Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 10/23] shared/uhid: Fix size of Get Report reply with a Report ID Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 11/23] shared/uhid: Keep reading when an event is not available Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 12/23] shared/tester: Allow expecting a PDU with no response Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 13/23] shared/gatt-client: Fix calling idle callbacks again while notifying Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 14/23] shared/gatt-client: Add bt_gatt_client_is_idle Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 15/23] shared/hog: Add initial implementation Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 16/23] unit/test-hog: Use shared/hog Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 17/23] test: functional: change the HoG SCI mode with the HID Control Point Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 18/23] input/hog: Use shared/hog Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 19/23] doc: Add CONFIG_HIDRAW to the tester kernel config Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 20/23] unit/test-uhid: Add Get Report tests Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 21/23] device: Use bt_att instead of GAttrib Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 22/23] attrib: Remove GAttrib and gatttool Luiz Augusto von Dentz
2026-09-28 20:00 ` [PATCH BlueZ v6 23/23] attrib: Remove directory Luiz Augusto von Dentz
2026-09-29 20:50 ` [PATCH BlueZ v6 00/23] Add HoG functional tests and shared/hog 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=20260928200031.1209311-7-luiz.dentz@gmail.com \
--to=luiz.dentz@gmail.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox