History

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.

Luiz Augusto von Dentz committed 4 years ago

Commit 9b3628d1 parent aef2aa44 files · +39 −19Browse files

Unified · Split

4 files
  1. include/net/bluetooth/hci_core.h +1 −1
  2. net/bluetooth/hci_conn.c +24 −8
  3. net/bluetooth/hci_event.c +4 −9
  4. net/bluetooth/hci_sync.c +10 −1
include/net/bluetooth/hci_core.h+1−1
@@ -1156,7 +1156,7 @@ int hci_conn_switch_role(struct hci_conn *conn, __u8 role); · 1155 unmodified lines
1156 1156
1157void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active);1157void hci_conn_enter_active_mode(struct hci_conn *conn, __u8 force_active);
1158 1158
1159void hci_le_conn_failed(struct hci_conn *conn, u8 status);1159void hci_conn_failed(struct hci_conn *conn, u8 status);
1160 1160
1161/*1161/*
1162 * hci_conn_get() and hci_conn_put() are used to control the life-time of an1162 * hci_conn_get() and hci_conn_put() are used to control the life-time of an
net/bluetooth/hci_conn.c+24−8
@@ -670,7 +670,7 @@ static void le_conn_timeout(struct work_struct *work) · 669 unmodified lines
670 /* Disable LE Advertising */670 /* Disable LE Advertising */
671 le_disable_advertising(hdev);671 le_disable_advertising(hdev);
672 hci_dev_lock(hdev);672 hci_dev_lock(hdev);
673 hci_le_conn_failed(conn, HCI_ERROR_ADVERTISING_TIMEOUT);673 hci_conn_failed(conn, HCI_ERROR_ADVERTISING_TIMEOUT);
674 hci_dev_unlock(hdev);674 hci_dev_unlock(hdev);
675 return;675 return;
676 }676 }
@@ -873,7 +873,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src, uint8_t src_type) · 196 unmodified lines
873EXPORT_SYMBOL(hci_get_route);873EXPORT_SYMBOL(hci_get_route);
874 874
875/* This function requires the caller holds hdev->lock */875/* This function requires the caller holds hdev->lock */
876void hci_le_conn_failed(struct hci_conn *conn, u8 status)876static void hci_le_conn_failed(struct hci_conn *conn, u8 status)
877{877{
878 struct hci_dev *hdev = conn->hdev;878 struct hci_dev *hdev = conn->hdev;
879 struct hci_conn_params *params;879 struct hci_conn_params *params;
@@ -886,8 +886,6 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status) · 6 unmodified lines
886 params->conn = NULL;886 params->conn = NULL;
887 }887 }
888 888
889 conn->state = BT_CLOSED;
890
891 /* If the status indicates successful cancellation of889 /* If the status indicates successful cancellation of
892 * the attempt (i.e. Unknown Connection Id) there's no point of890 * the attempt (i.e. Unknown Connection Id) there's no point of
893 * notifying failure since we'll go back to keep trying to891 * 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) · 5 unmodified lines
899 mgmt_connect_failed(hdev, &conn->dst, conn->type,897 mgmt_connect_failed(hdev, &conn->dst, conn->type,
900 conn->dst_type, status);898 conn->dst_type, status);
901 899
902 hci_connect_cfm(conn, status);
903
904 hci_conn_del(conn);
905
906 /* Since we may have temporarily stopped the background scanning in900 /* Since we may have temporarily stopped the background scanning in
907 * favor of connection establishment, we should restart it.901 * favor of connection establishment, we should restart it.
908 */902 */
@@ -914,6 +908,28 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status) · 5 unmodified lines
914 hci_enable_advertising(hdev);908 hci_enable_advertising(hdev);
915}909}
916 910
911/* This function requires the caller holds hdev->lock */
912void 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
917static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err)933static void create_le_conn_complete(struct hci_dev *hdev, void *data, int err)
918{934{
919 struct hci_conn *conn = data;935 struct hci_conn *conn = data;
net/bluetooth/hci_event.c+4−9
@@ -2834,7 +2834,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status) · 2833 unmodified lines
2834 bt_dev_dbg(hdev, "status 0x%2.2x", status);2834 bt_dev_dbg(hdev, "status 0x%2.2x", status);
2835 2835
2836 /* All connection failure handling is taken care of by the2836 /* All connection failure handling is taken care of by the
2837 * hci_le_conn_failed function which is triggered by the HCI2837 * hci_conn_failed function which is triggered by the HCI
2838 * request completion callbacks used for connecting.2838 * request completion callbacks used for connecting.
2839 */2839 */
2840 if (status)2840 if (status)
@@ -2859,7 +2859,7 @@ static void hci_cs_le_ext_create_conn(struct hci_dev *hdev, u8 status) · 18 unmodified lines
2859 bt_dev_dbg(hdev, "status 0x%2.2x", status);2859 bt_dev_dbg(hdev, "status 0x%2.2x", status);
2860 2860
2861 /* All connection failure handling is taken care of by the2861 /* All connection failure handling is taken care of by the
2862 * hci_le_conn_failed function which is triggered by the HCI2862 * hci_conn_failed function which is triggered by the HCI
2863 * request completion callbacks used for connecting.2863 * request completion callbacks used for connecting.
2864 */2864 */
2865 if (status)2865 if (status)
@@ -3179,12 +3179,7 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, void *data, · 313 unmodified lines
3179 3179
3180done:3180done:
3181 if (status) {3181 if (status) {
3182 conn->state = BT_CLOSED;3182 hci_conn_failed(conn, status);
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);
3188 } else if (ev->link_type == SCO_LINK) {3183 } else if (ev->link_type == SCO_LINK) {
3189 switch (conn->setting & SCO_AIRMODE_MASK) {3184 switch (conn->setting & SCO_AIRMODE_MASK) {
3190 case SCO_AIRMODE_CVSD:3185 case SCO_AIRMODE_CVSD:
@@ -5623,7 +5618,7 @@ static void le_conn_complete_evt(struct hci_dev *hdev, u8 status, · 2432 unmodified lines
5623 }5618 }
5624 5619
5625 if (status) {5620 if (status) {
5626 hci_le_conn_failed(conn, status);5621 hci_conn_failed(conn, status);
5627 goto unlock;5622 goto unlock;
5628 }5623 }
5629 5624
net/bluetooth/hci_sync.c+10−1
@@ -4408,12 +4408,21 @@ static int hci_reject_conn_sync(struct hci_dev *hdev, struct hci_conn *conn, · 4407 unmodified lines
4408static int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn,4408static int hci_abort_conn_sync(struct hci_dev *hdev, struct hci_conn *conn,
4409 u8 reason)4409 u8 reason)
4410{4410{
4411 int err;
4412
4411 switch (conn->state) {4413 switch (conn->state) {
4412 case BT_CONNECTED:4414 case BT_CONNECTED:
4413 case BT_CONFIG:4415 case BT_CONFIG:
4414 return hci_disconnect_sync(hdev, conn, reason);4416 return hci_disconnect_sync(hdev, conn, reason);
4415 case BT_CONNECT:4417 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;
4417 case BT_CONNECT2:4426 case BT_CONNECT2:
4418 return hci_reject_conn_sync(hdev, conn, reason);4427 return hci_reject_conn_sync(hdev, conn, reason);
4419 default:4428 default:

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t