From: Luiz Augusto von Dentz <luiz.dentz@gmail.com>
To: linux-bluetooth@vger.kernel.org
Subject: [PATCH BlueZ v5 03/11] doc/iso-protocol: Document BT_ISO_QOS
Date: Fri, 6 Nov 2026 13:18:00 -0500 [thread overview]
Message-ID: <20261106181809.3134862-4-luiz.dentz@gmail.com> (raw)
In-Reply-To: <20261106181809.3134862-1-luiz.dentz@gmail.com>
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Document BT_ISO_QOS with struct bt_iso_qos_ext, its version and type
fields and why they exist, the PHY values and the HDT rates, with
examples for unicast and broadcast with the LE HDT PHY and reading the
QoS in use.
---
doc/iso-protocol.rst | 207 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 207 insertions(+)
diff --git a/doc/iso-protocol.rst b/doc/iso-protocol.rst
index 4d315132f911..8d8aebc3af2f 100644
--- a/doc/iso-protocol.rst
+++ b/doc/iso-protocol.rst
@@ -241,6 +241,213 @@ Example:
}
}
+BT_ISO_QOS
+----------
+
+Isochronous channel QoS, used by **connect(2)** and **listen(2)** to set up a
+CIS (unicast) or BIS (broadcast). It is read back with **getsockopt(2)**, which
+reports the parameters in use once the channel is connected. Two forms are
+accepted, told apart by the option length:
+
+- ``struct bt_iso_qos``: the original form, kept for existing applications.
+- ``struct bt_iso_qos_ext``: the extended form, required
+ for the fields added after the original one, such as the HDT rates.
+
+.. code-block::
+
+ struct bt_iso_io_qos_ext {
+ uint32_t interval;
+ uint16_t latency;
+ uint16_t sdu;
+ uint8_t phys;
+ uint8_t rtn;
+ uint16_t rates; /* Version 1 */
+ };
+
+ struct bt_iso_ucast_qos_ext {
+ uint8_t cig;
+ uint8_t cis;
+ uint8_t sca;
+ uint8_t packing;
+ uint8_t framing;
+ struct bt_iso_io_qos_ext in;
+ struct bt_iso_io_qos_ext out;
+ };
+
+ struct bt_iso_bcast_qos_ext {
+ uint8_t big;
+ uint8_t bis;
+ uint8_t sync_factor;
+ uint8_t packing;
+ uint8_t framing;
+ struct bt_iso_io_qos_ext in;
+ struct bt_iso_io_qos_ext out;
+ uint8_t encryption;
+ uint8_t bcode[16];
+ uint8_t options;
+ uint16_t skip;
+ uint16_t sync_timeout;
+ uint8_t sync_cte_type;
+ uint8_t mse;
+ uint16_t timeout;
+ };
+
+ struct bt_iso_qos_ext {
+ uint16_t version;
+ uint16_t type;
+ union { /* Shall be the last member */
+ struct bt_iso_ucast_qos_ext ucast;
+ struct bt_iso_bcast_qos_ext bcast;
+ };
+ };
+
+``struct bt_iso_qos`` has the same fields without ``version``, ``type`` and
+``rates``.
+
+The extended form is meant to grow, by extending it rather than adding new
+socket options or structs, which is what its first two fields are for:
+
+- ``version`` tells which fields are valid. Later versions add fields, while
+ applications built for an earlier version keep working with the fields
+ they know.
+- ``type`` tells which member of the union is in use. The QoS is usually set
+ before **bind(2)** or **connect(2)**, when the socket can't tell unicast
+ from broadcast, so with ``type`` ``ucast`` and ``bcast`` can each grow on
+ their own, by adding fields at their end, without the kernel having to
+ guess which one it was given. That is also why the union is the last
+ member.
+
+version:
+
+.. csv-table::
+ :header: "Value", "Description"
+ :widths: auto
+
+ **BT_ISO_QOS_VERSION_1 (0x0001)**, Adds ``rates`` to each direction
+
+type:
+
+.. csv-table::
+ :header: "Value", "Description"
+ :widths: auto
+
+ **BT_ISO_QOS_ANY (0x0000)**, "Set by **connect(2)** or **listen(2)**,
+ possible with version 1 fields since the unicast ones are a prefix of the
+ broadcast ones"
+ **BT_ISO_QOS_UCAST (0x0001)**, Unicast (CIS) uses ``ucast``
+ **BT_ISO_QOS_BCAST (0x0002)**, Broadcast (BIS) uses ``bcast``
+
+**setsockopt(2)** fails with ``EINVAL`` for an unknown ``version`` or
+``type``, and **connect(2)** or **listen(2)** fail with ``EINVAL`` if
+``type`` doesn't match how the socket is used. A socket that already has a
+connection, such as an accepted one with ``BT_DEFER_SETUP`` or a PA sync,
+knows its type, so there **setsockopt(2)** fails instead. **getsockopt(2)** returns
+``struct bt_iso_qos`` if the buffer is shorter than ``struct bt_iso_qos_ext``,
+otherwise ``struct bt_iso_qos_ext`` with the version and, once known, the type
+in use.
+
+phys, in each direction:
+
+.. csv-table::
+ :header: "Value", "Description"
+ :widths: auto
+
+ **BT_ISO_PHY_1M (0x01)**, LE 1M
+ **BT_ISO_PHY_2M (0x02)**, LE 2M
+ **BT_ISO_PHY_CODED (0x04)**, LE Coded
+ **BT_ISO_PHY_HDT (0x10)**, "LE HDT, if supported by the controller, using
+ ``rates``"
+
+rates, in each direction, used with ``BT_ISO_PHY_HDT``; 0 selects every rate
+the controller supports:
+
+.. csv-table::
+ :header: "Value", "Description"
+ :widths: auto
+
+ **BT_ISO_HDT_RATE_2M (0x0001)**, HDT 2M
+ **BT_ISO_HDT_RATE_3M (0x0002)**, HDT 3M
+ **BT_ISO_HDT_RATE_4M (0x0004)**, HDT 4M
+ **BT_ISO_HDT_RATE_6M (0x0008)**, "HDT 6M, if supported in that direction"
+ **BT_ISO_HDT_RATE_7_5M (0x0010)**, "HDT 7.5M, if supported in that
+ direction"
+
+Example (Unicast with the LE HDT PHY):
+
+.. code-block::
+
+ struct bt_iso_qos_ext qos;
+
+ memset(&qos, 0, sizeof(qos));
+ qos.version = BT_ISO_QOS_VERSION_1;
+ qos.type = BT_ISO_QOS_UCAST;
+ qos.ucast.cig = BT_ISO_QOS_CIG_UNSET;
+ qos.ucast.cis = BT_ISO_QOS_CIS_UNSET;
+
+ qos.ucast.out.interval = 10000;
+ qos.ucast.out.latency = 10;
+ qos.ucast.out.sdu = 40;
+ qos.ucast.out.phys = BT_ISO_PHY_HDT;
+ qos.ucast.out.rtn = 2;
+ qos.ucast.out.rates = BT_ISO_HDT_RATE_4M | BT_ISO_HDT_RATE_6M;
+
+ /* The input direction uses the same settings */
+ qos.ucast.in = qos.ucast.out;
+
+ err = setsockopt(iso_socket, SOL_BLUETOOTH, BT_ISO_QOS, &qos,
+ sizeof(qos));
+ if (err == -1) {
+ perror("setsockopt");
+ return err;
+ }
+
+ /* connect(2) sets up the CIS */
+
+Example (Broadcast with the LE HDT PHY at any supported rate):
+
+.. code-block::
+
+ struct bt_iso_qos_ext qos;
+
+ memset(&qos, 0, sizeof(qos));
+ qos.version = BT_ISO_QOS_VERSION_1;
+ qos.type = BT_ISO_QOS_BCAST;
+ qos.bcast.big = BT_ISO_QOS_BIG_UNSET;
+ qos.bcast.bis = BT_ISO_QOS_BIS_UNSET;
+ qos.bcast.sync_factor = 0x01;
+ qos.bcast.sync_timeout = BT_ISO_SYNC_TIMEOUT;
+ qos.bcast.timeout = BT_ISO_SYNC_TIMEOUT;
+
+ qos.bcast.out.interval = 10000;
+ qos.bcast.out.latency = 10;
+ qos.bcast.out.sdu = 40;
+ qos.bcast.out.phys = BT_ISO_PHY_HDT;
+ qos.bcast.out.rtn = 2;
+ qos.bcast.out.rates = 0; /* Every rate the controller supports */
+
+ err = setsockopt(iso_socket, SOL_BLUETOOTH, BT_ISO_QOS, &qos,
+ sizeof(qos));
+
+Example (Read the QoS in use, including the rates selected):
+
+.. code-block::
+
+ struct bt_iso_qos_ext qos;
+ socklen_t len = sizeof(qos);
+
+ err = getsockopt(iso_socket, SOL_BLUETOOTH, BT_ISO_QOS, &qos, &len);
+ if (err == -1) {
+ perror("getsockopt");
+ return err;
+ }
+
+ if (len < sizeof(qos)) {
+ /* Older kernel, only struct bt_iso_qos was returned */
+ } else if (qos.type == BT_ISO_QOS_UCAST &&
+ qos.ucast.out.phys == BT_ISO_PHY_HDT) {
+ printf("Output HDT rates 0x%4.4x\n", qos.ucast.out.rates);
+ }
+
BT_PKT_STATUS
-------------
--
2.56.0
next prev parent reply other threads:[~2026-11-06 18:18 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-06 18:17 [PATCH BlueZ v5 00/11] Add support for HDT and EKS Luiz Augusto von Dentz
2026-11-06 18:17 ` [PATCH BlueZ v5 01/11] monitor: Use __packed in bt.h and its users Luiz Augusto von Dentz
2026-11-06 23:07 ` Add support for HDT and EKS bluez.test.bot
2026-11-06 18:17 ` [PATCH BlueZ v5 02/11] lib: Add HDT definitions Luiz Augusto von Dentz
2026-11-06 18:18 ` Luiz Augusto von Dentz [this message]
2026-11-06 18:18 ` [PATCH BlueZ v5 04/11] monitor: Add HCI decoding for HDT Luiz Augusto von Dentz
2026-11-06 18:18 ` [PATCH BlueZ v5 05/11] monitor: Add LL " Luiz Augusto von Dentz
2026-11-06 18:18 ` [PATCH BlueZ v5 06/11] emulator: Add HDT support to btdev Luiz Augusto von Dentz
2026-11-06 18:18 ` [PATCH BlueZ v5 07/11] emulator: Add HDT support to bthost Luiz Augusto von Dentz
2026-11-06 18:18 ` [PATCH BlueZ v5 08/11] shared/gatt: Add MIC length permission checks Luiz Augusto von Dentz
2026-11-06 18:18 ` [PATCH BlueZ v5 09/11] main.conf: Add HDT configuration Luiz Augusto von Dentz
2026-11-06 18:18 ` [PATCH BlueZ v5 10/11] l2cap-tester, iso-tester, mgmt-tester: Add HDT tests Luiz Augusto von Dentz
2026-11-06 18:18 ` [PATCH BlueZ v5 11/11] l2test: Add HDT options 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=20261106181809.3134862-4-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