aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
authorAndrzej Kaczmarek <andrzej.kaczmarek@tieto.com>2012-05-30 09:39:23 -0400
committerJohan Hedberg <johan.hedberg@intel.com>2012-06-04 23:34:15 -0400
commit4f72b3291c9537a3c3c94552e248eaed8e4f8492 (patch)
treedcad0e6f1c084dcf33f48ed789d9b80f39e28a13 /net/bluetooth
parent489dc48e7583d825304b0aff3fc17e706627b3c8 (diff)
Bluetooth: Fix not removing hci_conn for failed LE connection
This patch changes way LE Connection Complete event with error status are handled. BDADDR returned in such event packet do not need to be valid and should not be used to search for existing hci_conn. Instead, any hci_conn with BT_CONNECT state should be matched since there can be only one pending LE outgoing connection at any time. If not handled properly, appriopriate hci_conn will not be removed and subsequent connection to given peer will try to reuse it without making actual connection attempt. 2012-05-07 11:21:39.133378 < HCI Command: LE Create Connection (0x08|0x000d) plen 25 bdaddr 00:22:D0:10:13:EE type 1 2012-05-07 11:21:39.138774 > HCI Event: Command Status (0x0f) plen 4 LE Create Connection (0x08|0x000d) status 0x00 ncmd 1 2012-05-07 11:21:44.752854 < HCI Command: LE Create Connection Cancel (0x08|0x000e) plen 0 2012-05-07 11:21:44.759475 > HCI Event: Command Complete (0x0e) plen 4 LE Create Connection Cancel (0x08|0x000e) ncmd 1 2012-05-07 11:21:44.764479 > HCI Event: LE Meta Event (0x3e) plen 19 LE Connection Complete status 0x02 handle 0, role master bdaddr 00:00:00:00:00:00 (Public) [14898.739425] [6603] hci_connect: hci0 dst 00:22:D0:10:13:EE [14898.739429] [6603] hci_conn_add: hci0 dst 00:22:D0:10:13:EE [14898.739434] [6603] hci_conn_init_sysfs: conn ffff880079f03000 [14898.739440] [6603] hci_send_cmd: hci0 opcode 0x200d plen 25 [14898.739443] [6603] hci_send_cmd: skb len 28 [14898.739487] [6603] hci_chan_create: hci0 conn ffff880079f03000 ... [14938.860231] [55] hci_send_cmd: hci0 opcode 0x200e plen 0 ... [14938.876427] [55] hci_le_conn_complete_evt: hci0 status 2 [14938.876433] [55] hci_conn_add: hci0 dst 00:00:00:00:00:00 [14938.876439] [55] hci_conn_init_sysfs: conn ffff88007aeff800 [14938.876454] [55] hci_send_to_control: len 14 [14938.876470] [55] l2cap_connect_cfm: hcon ffff88007aeff800 bdaddr 00:00:00:00:00:00 status 2 [14938.876474] [55] hci_conn_del: hci0 conn ffff88007aeff800 handle 0 Signed-off-by: Andrzej Kaczmarek <andrzej.kaczmarek@tieto.com> Acked-by: Andre Guedes <andre.guedes@openbossa.org> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_event.c22
1 files changed, 13 insertions, 9 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index ac86b656c7a8..47656beee14c 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3306,6 +3306,19 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3306 3306
3307 hci_dev_lock(hdev); 3307 hci_dev_lock(hdev);
3308 3308
3309 if (ev->status) {
3310 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
3311 if (!conn)
3312 goto unlock;
3313
3314 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3315 conn->dst_type, ev->status);
3316 hci_proto_connect_cfm(conn, ev->status);
3317 conn->state = BT_CLOSED;
3318 hci_conn_del(conn);
3319 goto unlock;
3320 }
3321
3309 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr); 3322 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
3310 if (!conn) { 3323 if (!conn) {
3311 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr); 3324 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
@@ -3318,15 +3331,6 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3318 conn->dst_type = ev->bdaddr_type; 3331 conn->dst_type = ev->bdaddr_type;
3319 } 3332 }
3320 3333
3321 if (ev->status) {
3322 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
3323 conn->dst_type, ev->status);
3324 hci_proto_connect_cfm(conn, ev->status);
3325 conn->state = BT_CLOSED;
3326 hci_conn_del(conn);
3327 goto unlock;
3328 }
3329
3330 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) 3334 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3331 mgmt_device_connected(hdev, &ev->bdaddr, conn->type, 3335 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
3332 conn->dst_type, 0, NULL, 0, NULL); 3336 conn->dst_type, 0, NULL, 0, NULL);