Bluetooth: Classic: add change connection packet type support#104981
Bluetooth: Classic: add change connection packet type support#104981chengkai15 wants to merge 1 commit intozephyrproject-rtos:mainfrom
Conversation
506eadb to
9ed898c
Compare
There was a problem hiding this comment.
Pull request overview
Adds Bluetooth Classic (BR/EDR) host support for changing the allowed ACL packet types on an established connection via the HCI Change Connection Packet Type command, enabling runtime throughput/robustness tuning by applications.
Changes:
- Introduces a new public BR/EDR API:
bt_conn_br_change_packet_type(). - Adds the HCI opcode, command parameter struct, and packet-type bitmask defines needed to issue the command.
- Implements the command construction and synchronous send in the Classic connection implementation.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| subsys/bluetooth/host/classic/conn_br.c | Implements bt_conn_br_change_packet_type() and sends the new HCI command. |
| include/zephyr/bluetooth/hci_types.h | Adds the HCI opcode, command parameters struct, and packet-type bit defines. |
| include/zephyr/bluetooth/conn.h | Exposes the new public API and documents its parameters/return value. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| return bt_conn_br_write_link_policy_settings(conn, link_policy_settings); | ||
| } | ||
|
|
||
| int bt_conn_br_change_packet_type(struct bt_conn *conn, uint16_t packet_type) |
There was a problem hiding this comment.
bt_conn_br_change_packet_type() takes a non-const struct bt_conn * even though it only reads from the connection object. For API consistency with other BR/EDR helpers in this file (e.g. bt_conn_br_switch_role, bt_conn_br_set_role_switch_enable), consider making the parameter const struct bt_conn *conn in both the public header and this implementation.
| int bt_conn_br_change_packet_type(struct bt_conn *conn, uint16_t packet_type) | |
| int bt_conn_br_change_packet_type(const struct bt_conn *conn, uint16_t packet_type) |
| cp = net_buf_add(buf, sizeof(*cp)); | ||
| cp->handle = sys_cpu_to_le16(conn->handle); | ||
| cp->packet_type = sys_cpu_to_le16(packet_type); |
There was a problem hiding this comment.
The PR description mentions input validation, but the implementation forwards packet_type directly to the controller without checking for an empty mask or unsupported/reserved bits. Consider validating that at least one BR packet type bit is set and that no bits outside the supported mask are set, returning -EINVAL for invalid values to avoid opaque controller-side failures.
| * @param conn Connection object. | ||
| * @param packet_type Bitmask of allowed packet types | ||
| * (BT_HCI_ACL_PKT_TYPE_*). | ||
| * | ||
| * @return Zero for success, non-zero otherwise. |
There was a problem hiding this comment.
The Doxygen for packet_type describes it as a “bitmask of allowed packet types”, but the newly introduced BT_HCI_ACL_PKT_TYPE_NO_* defines use inverted semantics (bit set = EDR packet type shall not be used). Please clarify the parameter semantics (raw HCI Packet_Type field) and align the return docs with the rest of conn.h (typically “0 on success or negative errno otherwise”, ideally using @retval).
| * @param conn Connection object. | |
| * @param packet_type Bitmask of allowed packet types | |
| * (BT_HCI_ACL_PKT_TYPE_*). | |
| * | |
| * @return Zero for success, non-zero otherwise. | |
| * @param conn Connection object. | |
| * @param packet_type Raw HCI BR/EDR ACL Packet_Type field composed of | |
| * BT_HCI_ACL_PKT_TYPE_* values. For basic rate packet | |
| * type bits, a set bit allows use of that packet type. | |
| * For BT_HCI_ACL_PKT_TYPE_NO_* bits, a set bit means | |
| * the corresponding EDR packet type shall not be used, | |
| * as defined by the Bluetooth specification. | |
| * | |
| * @retval 0 On success. | |
| * @retval -errno On failure. |
| CHECKIF(conn == NULL) { | ||
| LOG_DBG("conn is NULL"); | ||
| return -EINVAL; | ||
| } |
There was a problem hiding this comment.
CHECKIF should not be used.
| } | ||
|
|
||
| buf = bt_hci_cmd_alloc(K_FOREVER); | ||
| if (!buf) { |
There was a problem hiding this comment.
| if (!buf) { | |
| if (buf == NULL) { |
| /** @brief Change BR/EDR connection packet type. | ||
| * | ||
| * Change which packet types can be used for an established BR/EDR | ||
| * connection. This allows dynamically modifying the connection to |
There was a problem hiding this comment.
In this PR, only Classic ACL conn type is supported.
| * connection. This allows dynamically modifying the connection to | |
| * ACL connection. This allows dynamically modifying the connection to |
9ed898c to
2fb2053
Compare
2fb2053 to
9f5aab1
Compare
lylezhu2012
left a comment
There was a problem hiding this comment.
Should the HCI event HCI_Connection_Packet_Type_Changed be handled? Otherwise, how can we determine if the operation was successful?
It is problematic to simply set the connection packet type without considering the result of response.
Thank you for the review comment. You're right — per BT Core Spec v6.0, Vol 4, Part E, Section 7.1.14, the HCI_Change_Connection_Packet_Type command uses Command Status flow, and the actual result is reported I will add the following in the next revision:
|
9f5aab1 to
c2d2e3d
Compare
c2d2e3d to
8ad308f
Compare
8ad308f to
3171782
Compare
| void (*role_changed)(struct bt_conn *conn, uint8_t status); | ||
|
|
||
| /** @brief The packet type of the connection has changed. | ||
| * | ||
| * This callback notifies the application that the connection packet | ||
| * type change procedure has completed. | ||
| * | ||
| * @param conn Connection object. | ||
| * @param status HCI status of the event. | ||
| * @param packet_type New packet type bitmask. | ||
| */ | ||
| void (*packet_type_changed)(struct bt_conn *conn, uint8_t status, | ||
| uint16_t packet_type); |
There was a problem hiding this comment.
I know the role_changed callback is already there, but since these are specific to BR/EDR, I think it'd be good to indicate that in the callback name as well, probably with a br_* prefix. E.g. LE also has roles, but you can't change it after the connection has been created. Thoughts?
There was a problem hiding this comment.
Thanks for the suggestion! I agree that adding a br_ prefix makes the naming clearer and more consistent with br_mode_changed. I've split the role_changed → br_role_changed rename into a separate PR #108022
to keep this PR focused on the packet type change feature.
The packet_type_changed callback in this PR is already named br_packet_type_changed following the same convention.
Add bt_conn_br_change_packet_type() API to dynamically change the allowed packet types for an established BR/EDR connection. This enables throughput optimization by selecting appropriate packet types (DM/DH 1/3/5 slots) based on application requirements. Signed-off-by: Kai Cheng <chengkai@xiaomi.com>
3171782 to
171e455
Compare
|



Bluetooth: Classic: add change connection packet type support
This PR adds support for dynamically changing the allowed ACL packet types on an established BR/EDR connection via the HCI Change Connection Packet Type command.
Changes
Usage
Applications can select specific BR/EDR packet types (DM1/DH1/DM3/DH3/DM5/DH5) and disable EDR packet types (2-DH1/3-DH1/2-DH3/3-DH3/2-DH5/3-DH5) to optimize throughput based on their requirements.
c
/* Example: allow only DM1 and DH1 packets */
bt_conn_br_change_packet_type(conn,
BT_HCI_ACL_PKT_TYPE_DM1 | BT_HCI_ACL_PKT_TYPE_DH1);