diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2014-02-28 10:45:46 -0500 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2014-02-28 10:56:42 -0500 |
commit | 9489eca4ab2fd5d9bbf3bab992168cc8107fc3e9 (patch) | |
tree | ce538aec7505fcf547a3ad7aad3607e99a0db3d1 | |
parent | a7139edd28215623e80c998edd34b3f750c5efc6 (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.h | 1 | ||||
-rw-r--r-- | include/net/bluetooth/hci_core.h | 1 | ||||
-rw-r--r-- | net/bluetooth/hci_conn.c | 13 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 12 |
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 | ||
366 | static 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 | |||
366 | struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst) | 376 | struct 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 | |||
1681 | unlock: | 1691 | unlock: |
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 |