Skip to content

Bluetooth: Classic: add change connection packet type support#104981

Open
chengkai15 wants to merge 1 commit intozephyrproject-rtos:mainfrom
chengkai15:dev_change_conn_packet_type
Open

Bluetooth: Classic: add change connection packet type support#104981
chengkai15 wants to merge 1 commit intozephyrproject-rtos:mainfrom
chengkai15:dev_change_conn_packet_type

Conversation

@chengkai15
Copy link
Copy Markdown
Contributor

@chengkai15 chengkai15 commented Mar 5, 2026

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

  • Add bt_conn_br_change_packet_type() public API in conn.h, allowing applications to change packet types on a BR/EDR connection for throughput optimization.
  • Define BT_HCI_OP_CHANGE_CONN_PACKET_TYPE opcode, bt_hci_cp_change_conn_packet_type command struct, and BT_HCI_ACL_PKT_TYPE_* bitmask defines in hci_types.h (per Core Spec v6.0, Vol 4, Part E, Section 7.1.14).
  • Implement the API in conn_br.c with input validation and HCI command construction.
  • Update tests/bluetooth/shell/prj_br.conf with related config options.

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);

jhedberg
jhedberg previously approved these changes Mar 6, 2026
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Comment thread subsys/bluetooth/host/classic/conn_br.c Outdated
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)
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Suggested change
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)

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

Comment on lines +300 to +302
cp = net_buf_add(buf, sizeof(*cp));
cp->handle = sys_cpu_to_le16(conn->handle);
cp->packet_type = sys_cpu_to_le16(packet_type);
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copilot uses AI. Check for mistakes.
Comment thread include/zephyr/bluetooth/conn.h Outdated
Comment on lines +3310 to +3314
* @param conn Connection object.
* @param packet_type Bitmask of allowed packet types
* (BT_HCI_ACL_PKT_TYPE_*).
*
* @return Zero for success, non-zero otherwise.
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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).

Suggested change
* @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.

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

Comment thread subsys/bluetooth/host/classic/conn_br.c Outdated
Comment on lines +285 to +288
CHECKIF(conn == NULL) {
LOG_DBG("conn is NULL");
return -EINVAL;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CHECKIF should not be used.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

Comment thread subsys/bluetooth/host/classic/conn_br.c Outdated
}

buf = bt_hci_cmd_alloc(K_FOREVER);
if (!buf) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if (!buf) {
if (buf == NULL) {

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

Comment thread include/zephyr/bluetooth/conn.h Outdated
/** @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
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this PR, only Classic ACL conn type is supported.

Suggested change
* connection. This allows dynamically modifying the connection to
* ACL connection. This allows dynamically modifying the connection to

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated

Copy link
Copy Markdown
Contributor

@lylezhu2012 lylezhu2012 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@chengkai15
Copy link
Copy Markdown
Contributor Author

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
via the HCI_Connection_Packet_Type_Changed event (event code 0x1D).

I will add the following in the next revision:

  1. Define BT_HCI_EVT_CONN_PKT_TYPE_CHANGED (0x1D) and its event struct in hci_types.h
  2. Register an event handler in hci_core.c to process this event
  3. Add a packet_type_changed callback in bt_conn_cb to notify the application of the result (similar to the role_changed callback pattern used for HCI_Role_Change)
  4. Enable the event via BT_EVT_MASK_CONN_PKT_TYPE_CHANGED in the event mask

@chengkai15 chengkai15 force-pushed the dev_change_conn_packet_type branch from 9f5aab1 to c2d2e3d Compare April 9, 2026 13:29
@chengkai15 chengkai15 requested a review from lylezhu2012 April 9, 2026 13:40
@chengkai15 chengkai15 force-pushed the dev_change_conn_packet_type branch from c2d2e3d to 8ad308f Compare April 9, 2026 13:45
@chengkai15 chengkai15 force-pushed the dev_change_conn_packet_type branch from 8ad308f to 3171782 Compare April 24, 2026 07:07
Comment on lines 2540 to +2552
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);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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>
@sonarqubecloud
Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: Bluetooth Classic Bluetooth Classic (BR/EDR) area: Bluetooth Host Bluetooth Host (excluding BR/EDR) area: Bluetooth

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants