diff options
Diffstat (limited to 'net/bluetooth')
-rw-r--r-- | net/bluetooth/hci_conn.c | 31 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 4 |
2 files changed, 31 insertions, 4 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index 7e9515b41cc0..90e3a285a17e 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -84,6 +84,20 @@ static void hci_acl_connect(struct hci_conn *conn) | |||
84 | hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp); | 84 | hci_send_cmd(hdev, OGF_LINK_CTL, OCF_CREATE_CONN, sizeof(cp), &cp); |
85 | } | 85 | } |
86 | 86 | ||
87 | static void hci_acl_connect_cancel(struct hci_conn *conn) | ||
88 | { | ||
89 | struct hci_cp_create_conn_cancel cp; | ||
90 | |||
91 | BT_DBG("%p", conn); | ||
92 | |||
93 | if (conn->hdev->hci_ver < 2) | ||
94 | return; | ||
95 | |||
96 | bacpy(&cp.bdaddr, &conn->dst); | ||
97 | hci_send_cmd(conn->hdev, OGF_LINK_CTL, | ||
98 | OCF_CREATE_CONN_CANCEL, sizeof(cp), &cp); | ||
99 | } | ||
100 | |||
87 | void hci_acl_disconn(struct hci_conn *conn, __u8 reason) | 101 | void hci_acl_disconn(struct hci_conn *conn, __u8 reason) |
88 | { | 102 | { |
89 | struct hci_cp_disconnect cp; | 103 | struct hci_cp_disconnect cp; |
@@ -94,7 +108,8 @@ void hci_acl_disconn(struct hci_conn *conn, __u8 reason) | |||
94 | 108 | ||
95 | cp.handle = __cpu_to_le16(conn->handle); | 109 | cp.handle = __cpu_to_le16(conn->handle); |
96 | cp.reason = reason; | 110 | cp.reason = reason; |
97 | hci_send_cmd(conn->hdev, OGF_LINK_CTL, OCF_DISCONNECT, sizeof(cp), &cp); | 111 | hci_send_cmd(conn->hdev, OGF_LINK_CTL, |
112 | OCF_DISCONNECT, sizeof(cp), &cp); | ||
98 | } | 113 | } |
99 | 114 | ||
100 | void hci_add_sco(struct hci_conn *conn, __u16 handle) | 115 | void hci_add_sco(struct hci_conn *conn, __u16 handle) |
@@ -124,12 +139,20 @@ static void hci_conn_timeout(unsigned long arg) | |||
124 | return; | 139 | return; |
125 | 140 | ||
126 | hci_dev_lock(hdev); | 141 | hci_dev_lock(hdev); |
127 | if (conn->state == BT_CONNECTED) | 142 | |
143 | switch (conn->state) { | ||
144 | case BT_CONNECT: | ||
145 | hci_acl_connect_cancel(conn); | ||
146 | break; | ||
147 | case BT_CONNECTED: | ||
128 | hci_acl_disconn(conn, 0x13); | 148 | hci_acl_disconn(conn, 0x13); |
129 | else | 149 | break; |
150 | default: | ||
130 | conn->state = BT_CLOSED; | 151 | conn->state = BT_CLOSED; |
152 | break; | ||
153 | } | ||
154 | |||
131 | hci_dev_unlock(hdev); | 155 | hci_dev_unlock(hdev); |
132 | return; | ||
133 | } | 156 | } |
134 | 157 | ||
135 | static void hci_conn_idle(unsigned long arg) | 158 | static void hci_conn_idle(unsigned long arg) |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 7518bdbf34cd..bb25484b8747 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -750,6 +750,8 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
750 | if (test_bit(HCI_ENCRYPT, &hdev->flags)) | 750 | if (test_bit(HCI_ENCRYPT, &hdev->flags)) |
751 | conn->link_mode |= HCI_LM_ENCRYPT; | 751 | conn->link_mode |= HCI_LM_ENCRYPT; |
752 | 752 | ||
753 | hci_conn_hold(conn); | ||
754 | |||
753 | /* Get remote features */ | 755 | /* Get remote features */ |
754 | if (conn->type == ACL_LINK) { | 756 | if (conn->type == ACL_LINK) { |
755 | struct hci_cp_read_remote_features cp; | 757 | struct hci_cp_read_remote_features cp; |
@@ -778,6 +780,8 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
778 | hci_send_cmd(hdev, OGF_LINK_CTL, | 780 | hci_send_cmd(hdev, OGF_LINK_CTL, |
779 | OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp); | 781 | OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp); |
780 | } | 782 | } |
783 | |||
784 | hci_conn_put(conn); | ||
781 | } else | 785 | } else |
782 | conn->state = BT_CLOSED; | 786 | conn->state = BT_CLOSED; |
783 | 787 | ||