diff options
-rw-r--r-- | include/net/bluetooth/hci.h | 6 | ||||
-rw-r--r-- | include/net/bluetooth/hci_core.h | 9 | ||||
-rw-r--r-- | net/bluetooth/hci_conn.c | 31 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 4 |
4 files changed, 43 insertions, 7 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h index 5f04181b8109..10a3eec191fd 100644 --- a/include/net/bluetooth/hci.h +++ b/include/net/bluetooth/hci.h | |||
@@ -297,6 +297,7 @@ struct hci_cp_host_buffer_size { | |||
297 | 297 | ||
298 | /* Link Control */ | 298 | /* Link Control */ |
299 | #define OGF_LINK_CTL 0x01 | 299 | #define OGF_LINK_CTL 0x01 |
300 | |||
300 | #define OCF_CREATE_CONN 0x0005 | 301 | #define OCF_CREATE_CONN 0x0005 |
301 | struct hci_cp_create_conn { | 302 | struct hci_cp_create_conn { |
302 | bdaddr_t bdaddr; | 303 | bdaddr_t bdaddr; |
@@ -307,6 +308,11 @@ struct hci_cp_create_conn { | |||
307 | __u8 role_switch; | 308 | __u8 role_switch; |
308 | } __attribute__ ((packed)); | 309 | } __attribute__ ((packed)); |
309 | 310 | ||
311 | #define OCF_CREATE_CONN_CANCEL 0x0008 | ||
312 | struct hci_cp_create_conn_cancel { | ||
313 | bdaddr_t bdaddr; | ||
314 | } __attribute__ ((packed)); | ||
315 | |||
310 | #define OCF_ACCEPT_CONN_REQ 0x0009 | 316 | #define OCF_ACCEPT_CONN_REQ 0x0009 |
311 | struct hci_cp_accept_conn_req { | 317 | struct hci_cp_accept_conn_req { |
312 | bdaddr_t bdaddr; | 318 | bdaddr_t bdaddr; |
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h index 7451a9c92d9d..df22efcfcc0b 100644 --- a/include/net/bluetooth/hci_core.h +++ b/include/net/bluetooth/hci_core.h | |||
@@ -316,10 +316,13 @@ static inline void hci_conn_put(struct hci_conn *conn) | |||
316 | if (atomic_dec_and_test(&conn->refcnt)) { | 316 | if (atomic_dec_and_test(&conn->refcnt)) { |
317 | unsigned long timeo; | 317 | unsigned long timeo; |
318 | if (conn->type == ACL_LINK) { | 318 | if (conn->type == ACL_LINK) { |
319 | timeo = msecs_to_jiffies(HCI_DISCONN_TIMEOUT); | ||
320 | if (!conn->out) | ||
321 | timeo *= 2; | ||
322 | del_timer(&conn->idle_timer); | 319 | del_timer(&conn->idle_timer); |
320 | if (conn->state == BT_CONNECTED) { | ||
321 | timeo = msecs_to_jiffies(HCI_DISCONN_TIMEOUT); | ||
322 | if (!conn->out) | ||
323 | timeo *= 2; | ||
324 | } else | ||
325 | timeo = msecs_to_jiffies(10); | ||
323 | } else | 326 | } else |
324 | timeo = msecs_to_jiffies(10); | 327 | timeo = msecs_to_jiffies(10); |
325 | mod_timer(&conn->disc_timer, jiffies + timeo); | 328 | mod_timer(&conn->disc_timer, jiffies + timeo); |
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 | ||