[PATCH v2] Bluetooth: hci_event: Add HCI_Write_Link_Supervision_Timeout command/event structures
[email protected] Fri, 24 Jul 2026 16:54:06 +0800
| Newsgroups | org.kernel.vger.linux-bluetooth |
|---|---|
| Message-ID | <[email protected]> |
From: Chen Zhang <[email protected]> Some speakers do not actively initiate disconnection when power off. As a result, the center can only wait for a timeout to disconnect, with the default timeout being 20s. In certain scenarios, this can significantly impact user experience. For example, if a speaker is playing music and is then turned off, it takes 20s before the music starts playing from the center. Define HCI_Write_Link_Supervision_Timeout command, event structure, and corresponding event handler function, set the timeout to 5s after ACL link is established. Signed-off-by: Chen Zhang <[email protected]> --- include/net/bluetooth/hci.h | 10 +++++++ include/net/bluetooth/hci_core.h | 1 + net/bluetooth/hci_event.c | 50 ++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+) diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 50f0eef71fb1..18a5a17eb218 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h @@ -1239,6 +1239,16 @@ struct hci_cp_host_buffer_size { __le16 sco_max_pkt; } __packed; +#define HCI_OP_WRITE_LINK_SUPERVISION_TIMEOUT 0x0c37 +struct hci_cp_write_link_supervision_timeout { + __le16 handle; + __le16 timeout; +} __packed; +struct hci_rp_write_link_supervision_timeout { + __u8 status; + __le16 handle; +} __packed; + #define HCI_OP_READ_NUM_SUPPORTED_IAC 0x0c38 struct hci_rp_read_num_supported_iac { __u8 status; diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index e7133ff87fbf..866903a9b5c8 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h @@ -702,6 +702,7 @@ struct hci_conn { __u8 le_features[248]; __u16 pkt_type; __u16 link_policy; + __u16 link_supervision_timeout; __u8 key_type; __u8 auth_type; __u8 sec_level; diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 741d658e9630..653184d0dfc7 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c @@ -606,6 +606,44 @@ static u8 hci_cc_write_voice_setting(struct hci_dev *hdev, void *data, return rp->status; } +static u8 hci_cc_write_link_supervision_timeout(struct hci_dev *hdev, void *data, + struct sk_buff *skb) +{ + struct hci_ev_status *rp = data; + struct hci_cp_write_link_supervision_timeout *sent; + struct hci_conn *conn; + u16 handle; + u8 status = rp->status; + + bt_dev_dbg(hdev, "status 0x%2.2x", status); + + sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_SUPERVISION_TIMEOUT); + if (!sent) + return status; + + handle = le16_to_cpu(sent->handle); + + hci_dev_lock(hdev); + + conn = hci_conn_hash_lookup_handle(hdev, handle); + if (!conn) { + status = 0xFF; + goto done; + } + + if (!status) { + conn->link_supervision_timeout = __le16_to_cpu(sent->timeout); + bt_dev_dbg(hdev, "handle 0x%4.4x timeout set to 0x%4.4x (%u ms)", + handle, conn->link_supervision_timeout, + conn->link_supervision_timeout * 5 / 8); + } + +done: + hci_dev_unlock(hdev); + + return status; +} + static u8 hci_cc_read_num_supported_iac(struct hci_dev *hdev, void *data, struct sk_buff *skb) { @@ -3240,6 +3278,16 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data, hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp), &cp); } + + if (conn->type == ACL_LINK && conn->role == HCI_ROLE_MASTER) { + struct hci_cp_write_link_supervision_timeout cp; + + cp.handle = ev->handle; + cp.timeout = 0x1F40; /* 8000 * 0.625ms = 5000ms */ + hci_send_cmd(hdev, HCI_OP_WRITE_LINK_SUPERVISION_TIMEOUT, + sizeof(cp), &cp); + } + } if (conn->type == ACL_LINK) @@ -4097,6 +4145,8 @@ static const struct hci_cc { HCI_CC_STATUS(HCI_OP_WRITE_CLASS_OF_DEV, hci_cc_write_class_of_dev), HCI_CC(HCI_OP_READ_VOICE_SETTING, hci_cc_read_voice_setting, sizeof(struct hci_rp_read_voice_setting)), + HCI_CC(HCI_OP_WRITE_LINK_SUPERVISION_TIMEOUT, hci_cc_write_link_supervision_timeout, + sizeof(struct hci_rp_write_link_supervision_timeout)), HCI_CC_STATUS(HCI_OP_WRITE_VOICE_SETTING, hci_cc_write_voice_setting), HCI_CC(HCI_OP_READ_NUM_SUPPORTED_IAC, hci_cc_read_num_supported_iac, sizeof(struct hci_rp_read_num_supported_iac)), -- 2.25.1