aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2014-02-28 10:45:46 -0500
committerMarcel Holtmann <marcel@holtmann.org>2014-02-28 10:56:42 -0500
commit9489eca4ab2fd5d9bbf3bab992168cc8107fc3e9 (patch)
treece538aec7505fcf547a3ad7aad3607e99a0db3d1
parenta7139edd28215623e80c998edd34b3f750c5efc6 (diff)
Bluetooth: Add timeout for LE connection attempts
LE connection attempts do not have a controller side timeout in the same way as BR/EDR has (in form of the page timeout). Since we always do scanning before initiating connections the attempts are always expected to succeed in some reasonable time. This patch adds a timer which forces a cancellation of the connection attempt within 20 seconds if it has not been successful by then. This way we e.g. ensure that mgmt_pair_device times out eventually and gives an error response. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--include/net/bluetooth/hci.h1
-rw-r--r--include/net/bluetooth/hci_core.h1
-rw-r--r--net/bluetooth/hci_conn.c13
-rw-r--r--net/bluetooth/hci_event.c12
4 files changed, 27 insertions, 0 deletions
diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 439b4ebf9644..0409f0119d2b 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -183,6 +183,7 @@ enum {
183#define HCI_ACL_TX_TIMEOUT msecs_to_jiffies(45000) /* 45 seconds */ 183#define HCI_ACL_TX_TIMEOUT msecs_to_jiffies(45000) /* 45 seconds */
184#define HCI_AUTO_OFF_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */ 184#define HCI_AUTO_OFF_TIMEOUT msecs_to_jiffies(2000) /* 2 seconds */
185#define HCI_POWER_OFF_TIMEOUT msecs_to_jiffies(5000) /* 5 seconds */ 185#define HCI_POWER_OFF_TIMEOUT msecs_to_jiffies(5000) /* 5 seconds */
186#define HCI_LE_CONN_TIMEOUT msecs_to_jiffies(20000) /* 20 seconds */
186 187
187/* HCI data types */ 188/* HCI data types */
188#define HCI_COMMAND_PKT 0x01 189#define HCI_COMMAND_PKT 0x01
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index edf194679b7d..dbb788e4f265 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -375,6 +375,7 @@ struct hci_conn {
375 struct delayed_work disc_work; 375 struct delayed_work disc_work;
376 struct delayed_work auto_accept_work; 376 struct delayed_work auto_accept_work;
377 struct delayed_work idle_work; 377 struct delayed_work idle_work;
378 struct delayed_work le_conn_timeout;
378 379
379 struct device dev; 380 struct device dev;
380 381
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 818330c1b2a2..7e47e4240c95 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -363,6 +363,16 @@ static void hci_conn_auto_accept(struct work_struct *work)
363 &conn->dst); 363 &conn->dst);
364} 364}
365 365
366static void le_conn_timeout(struct work_struct *work)
367{
368 struct hci_conn *conn = container_of(work, struct hci_conn,
369 le_conn_timeout.work);
370
371 BT_DBG("");
372
373 hci_le_create_connection_cancel(conn);
374}
375
366struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) 376struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
367{ 377{
368 struct hci_conn *conn; 378 struct hci_conn *conn;
@@ -410,6 +420,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
410 INIT_DELAYED_WORK(&conn->disc_work, hci_conn_timeout); 420 INIT_DELAYED_WORK(&conn->disc_work, hci_conn_timeout);
411 INIT_DELAYED_WORK(&conn->auto_accept_work, hci_conn_auto_accept); 421 INIT_DELAYED_WORK(&conn->auto_accept_work, hci_conn_auto_accept);
412 INIT_DELAYED_WORK(&conn->idle_work, hci_conn_idle); 422 INIT_DELAYED_WORK(&conn->idle_work, hci_conn_idle);
423 INIT_DELAYED_WORK(&conn->le_conn_timeout, le_conn_timeout);
413 424
414 atomic_set(&conn->refcnt, 0); 425 atomic_set(&conn->refcnt, 0);
415 426
@@ -442,6 +453,8 @@ int hci_conn_del(struct hci_conn *conn)
442 /* Unacked frames */ 453 /* Unacked frames */
443 hdev->acl_cnt += conn->sent; 454 hdev->acl_cnt += conn->sent;
444 } else if (conn->type == LE_LINK) { 455 } else if (conn->type == LE_LINK) {
456 cancel_delayed_work_sync(&conn->le_conn_timeout);
457
445 if (hdev->le_pkts) 458 if (hdev->le_pkts)
446 hdev->le_cnt += conn->sent; 459 hdev->le_cnt += conn->sent;
447 else 460 else
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 3ae8ae1a029c..a1075c713a9d 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1678,6 +1678,16 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, u8 status)
1678 conn->resp_addr_type = cp->peer_addr_type; 1678 conn->resp_addr_type = cp->peer_addr_type;
1679 bacpy(&conn->resp_addr, &cp->peer_addr); 1679 bacpy(&conn->resp_addr, &cp->peer_addr);
1680 1680
1681 /* We don't want the connection attempt to stick around
1682 * indefinitely since LE doesn't have a page timeout concept
1683 * like BR/EDR. Set a timer for any connection that doesn't use
1684 * the white list for connecting.
1685 */
1686 if (cp->filter_policy == HCI_LE_USE_PEER_ADDR)
1687 queue_delayed_work(conn->hdev->workqueue,
1688 &conn->le_conn_timeout,
1689 HCI_LE_CONN_TIMEOUT);
1690
1681unlock: 1691unlock:
1682 hci_dev_unlock(hdev); 1692 hci_dev_unlock(hdev);
1683} 1693}
@@ -3794,6 +3804,8 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3794 conn->init_addr_type = ev->bdaddr_type; 3804 conn->init_addr_type = ev->bdaddr_type;
3795 bacpy(&conn->init_addr, &ev->bdaddr); 3805 bacpy(&conn->init_addr, &ev->bdaddr);
3796 } 3806 }
3807 } else {
3808 cancel_delayed_work(&conn->le_conn_timeout);
3797 } 3809 }
3798 3810
3799 /* Ensure that the hci_conn contains the identity address type 3811 /* Ensure that the hci_conn contains the identity address type