2024-01-02 18:59:56

by Jonas Dreßler

[permalink] [raw]
Subject: [PATCH 0/5] Bluetooth: Improve retrying of connection attempts

Since commit 4c67bc74f016b0d360b8573e18969c0ff7926974, the kernel supports
trying to connect again in case the bluetooth card is busy and fails
to connect.

The logic that should handle this became a bit spotty over time, and also
cards these days appear to fail with more errors than just "Command
Disallowed".

This series tries to improve the logic for retrying "HCI Create
Connection" and adds support for two more errors that can indicate the
hardware being busy.

Jonas Dreßler (5):
Bluetooth: Remove superfluous call to hci_conn_check_pending()
Bluetooth: hci_event: Use HCI error defines instead of magic values
Bluetooth: hci_event: Remove limit of 2 reconnection attempts
Bluetooth: hci_event: Do sanity checks before retrying to connect
Bluetooth: hci_event: Try reconnecting on more kinds of errors

include/net/bluetooth/hci.h | 3 ++
net/bluetooth/hci_event.c | 57 +++++++++++++++++++++++++++++++------
2 files changed, 51 insertions(+), 9 deletions(-)

--
2.43.0



2024-01-02 19:00:41

by Jonas Dreßler

[permalink] [raw]
Subject: [PATCH 2/5] Bluetooth: hci_event: Use HCI error defines instead of magic values

Signed-off-by: Jonas Dreßler <[email protected]>
---
include/net/bluetooth/hci.h | 2 ++
net/bluetooth/hci_event.c | 8 ++++----
2 files changed, 6 insertions(+), 4 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 111e8f8e5..fef723afd 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -641,6 +641,7 @@ enum {
#define HCI_ERROR_PIN_OR_KEY_MISSING 0x06
#define HCI_ERROR_MEMORY_EXCEEDED 0x07
#define HCI_ERROR_CONNECTION_TIMEOUT 0x08
+#define HCI_ERROR_COMMAND_DISALLOWED 0x0c
#define HCI_ERROR_REJ_LIMITED_RESOURCES 0x0d
#define HCI_ERROR_REJ_BAD_ADDR 0x0f
#define HCI_ERROR_INVALID_PARAMETERS 0x12
@@ -649,6 +650,7 @@ enum {
#define HCI_ERROR_REMOTE_POWER_OFF 0x15
#define HCI_ERROR_LOCAL_HOST_TERM 0x16
#define HCI_ERROR_PAIRING_NOT_ALLOWED 0x18
+#define HCI_ERROR_UNSUPPORTED_REMOTE_FEATURE 0x1e
#define HCI_ERROR_INVALID_LL_PARAMS 0x1e
#define HCI_ERROR_UNSPECIFIED 0x1f
#define HCI_ERROR_ADVERTISING_TIMEOUT 0x3c
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 13396329f..e8b4a0126 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -92,11 +92,11 @@ static u8 hci_cc_inquiry_cancel(struct hci_dev *hdev, void *data,
/* It is possible that we receive Inquiry Complete event right
* before we receive Inquiry Cancel Command Complete event, in
* which case the latter event should have status of Command
- * Disallowed (0x0c). This should not be treated as error, since
+ * Disallowed. This should not be treated as error, since
* we actually achieve what Inquiry Cancel wants to achieve,
* which is to end the last Inquiry session.
*/
- if (rp->status == 0x0c && !test_bit(HCI_INQUIRY, &hdev->flags)) {
+ if (rp->status == HCI_ERROR_COMMAND_DISALLOWED && !test_bit(HCI_INQUIRY, &hdev->flags)) {
bt_dev_warn(hdev, "Ignoring error of Inquiry Cancel command");
rp->status = 0x00;
}
@@ -2323,7 +2323,7 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)

if (status) {
if (conn && conn->state == BT_CONNECT) {
- if (status != 0x0c || conn->attempt > 2) {
+ if (status != HCI_ERROR_COMMAND_DISALLOWED || conn->attempt > 2) {
conn->state = BT_CLOSED;
hci_connect_cfm(conn, status);
hci_conn_del(conn);
@@ -6578,7 +6578,7 @@ static void hci_le_remote_feat_complete_evt(struct hci_dev *hdev, void *data,
* transition into connected state and mark it as
* successful.
*/
- if (!conn->out && ev->status == 0x1a &&
+ if (!conn->out && ev->status == HCI_ERROR_UNSUPPORTED_REMOTE_FEATURE &&
(hdev->le_features[0] & HCI_LE_PERIPHERAL_FEATURES))
status = 0x00;
else
--
2.43.0