Skip to content

Commit 9b3628d

Browse files
Vudentzholtmann
authored andcommitted
Bluetooth: hci_sync: Cleanup hci_conn if it cannot be aborted
This attempts to cleanup the hci_conn if it cannot be aborted as otherwise it would likely result in having the controller and host stack out of sync with respect to connection handle. Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
1 parent aef2aa4 commit 9b3628d

4 files changed

Lines changed: 39 additions & 19 deletions

File tree

include/net/bluetooth/hci_core.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1156,7 +1156,7 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role);
11561156

11571157
void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active);
11581158

1159-
void hci_le_conn_failed(struct hci_conn *conn, u8 status);
1159+
void hci_conn_failed(struct hci_conn *conn, u8 status);
11601160

11611161
/*
11621162
* hci_conn_get() and hci_conn_put() are used to control the life-time of an

net/bluetooth/hci_conn.c

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -670,7 +670,7 @@ static void le_conn_timeout(struct work_struct *work)
670670
/* Disable LE Advertising */
671671
le_disable_advertising(hdev);
672672
hci_dev_lock(hdev);
673-
hci_le_conn_failed(conn, HCI_ERROR_ADVERTISING_TIMEOUT);
673+
hci_conn_failed(conn, HCI_ERROR_ADVERTISING_TIMEOUT);
674674
hci_dev_unlock(hdev);
675675
return;
676676
}
@@ -873,7 +873,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src, uint8_t src_type)
873873
EXPORT_SYMBOL(hci_get_route);
874874

875875
/* This function requires the caller holds hdev->lock */
876-
void hci_le_conn_failed(struct hci_conn *conn, u8 status)
876+
static void hci_le_conn_failed(struct hci_conn *conn, u8 status)
877877
{
878878
struct hci_dev *hdev = conn->hdev;
879879
struct hci_conn_params *params;
@@ -886,8 +886,6 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status)
886886
params->conn = NULL;
887887
}
888888

889-
conn->state = BT_CLOSED;
890-
891889
/* If the status indicates successful cancellation of
892890
* the attempt (i.e. Unknown Connection Id) there's no point of
893891
* notifying failure since we'll go back to keep trying to
@@ -899,10 +897,6 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status)
899897
mgmt_connect_failed(hdev, &conn->dst, conn->type,
900898
conn->dst_type, status);
901899

902-
hci_connect_cfm(conn, status);
903-
904-
hci_conn_del(conn);
905-
906900
/* Since we may have temporarily stopped the background scanning in
907901
* favor of connection establishment, we should restart it.
908902
*/
@@ -914,6 +908,28 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status)
914908
hci_enable_advertising(hdev);
915909
}
916910

911+
/* This function requires the caller holds hdev->lock */
912+
void hci_conn_failed(struct hci_conn *conn, u8 status)
913+
{
914+
struct hci_dev *hdev = conn->hdev;
915+
916+
bt_dev_dbg(hdev, "status 0x%2.2x", status);
917+
918+
switch (conn->type) {
919+
case LE_LINK:
920+
hci_le_conn_failed(conn, status);
921+
break;
922+
case ACL_LINK:
923+
mgmt_connect_failed(hdev, &conn->dst, conn->type,
924+
conn->dst_type, status);
925+
break;
926+
}
927+
928+
conn->state = BT_CLOSED;
929+
hci_connect_cfm(conn, status);
930+
hci_conn_del(conn);
931+
}
932+
917933
static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err)
918934
{
919935
struct hci_conn *conn = data;

net/bluetooth/hci_event.c

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2834,7 +2834,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
28342834
bt_dev_dbg(hdev, "status 0x%2.2x", status);
28352835

28362836
/* All connection failure handling is taken care of by the
2837-
* hci_le_conn_failed function which is triggered by the HCI
2837+
* hci_conn_failed function which is triggered by the HCI
28382838
* request completion callbacks used for connecting.
28392839
*/
28402840
if (status)
@@ -2859,7 +2859,7 @@ static void hci_cs_le_ext_create_conn(struct hci_dev *hdev, u8 status)
28592859
bt_dev_dbg(hdev, "status 0x%2.2x", status);
28602860

28612861
/* All connection failure handling is taken care of by the
2862-
* hci_le_conn_failed function which is triggered by the HCI
2862+
* hci_conn_failed function which is triggered by the HCI
28632863
* request completion callbacks used for connecting.
28642864
*/
28652865
if (status)
@@ -3179,12 +3179,7 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data,
31793179

31803180
done:
31813181
if (status) {
3182-
conn->state = BT_CLOSED;
3183-
if (conn->type == ACL_LINK)
3184-
mgmt_connect_failed(hdev, &conn->dst, conn->type,
3185-
conn->dst_type, status);
3186-
hci_connect_cfm(conn, status);
3187-
hci_conn_del(conn);
3182+
hci_conn_failed(conn, status);
31883183
} else if (ev->link_type == SCO_LINK) {
31893184
switch (conn->setting & SCO_AIRMODE_MASK) {
31903185
case SCO_AIRMODE_CVSD:
@@ -5623,7 +5618,7 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status,
56235618
}
56245619

56255620
if (status) {
5626-
hci_le_conn_failed(conn, status);
5621+
hci_conn_failed(conn, status);
56275622
goto unlock;
56285623
}
56295624

net/bluetooth/hci_sync.c

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4408,12 +4408,21 @@ static int hci_reject_conn_sync(struct hci_dev *hdev, struct hci_conn *conn,
44084408
static int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn,
44094409
u8 reason)
44104410
{
4411+
int err;
4412+
44114413
switch (conn->state) {
44124414
case BT_CONNECTED:
44134415
case BT_CONFIG:
44144416
return hci_disconnect_sync(hdev, conn, reason);
44154417
case BT_CONNECT:
4416-
return hci_connect_cancel_sync(hdev, conn);
4418+
err = hci_connect_cancel_sync(hdev, conn);
4419+
/* Cleanup hci_conn object if it cannot be cancelled as it
4420+
* likelly means the controller and host stack are out of sync.
4421+
*/
4422+
if (err)
4423+
hci_conn_failed(conn, err);
4424+
4425+
return err;
44174426
case BT_CONNECT2:
44184427
return hci_reject_conn_sync(hdev, conn, reason);
44194428
default:

0 commit comments

Comments
 (0)