aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndre Guedes <andre.guedes@openbossa.org>2014-02-26 18:21:47 -0500
committerMarcel Holtmann <marcel@holtmann.org>2014-02-26 22:41:34 -0500
commita4790dbd43d1617b09d57e96494fde5a4b01980a (patch)
tree9010c2aeecc9b319d5c1c31b3b5c2677946a2f9b
parent77a77a30ae893a63467c51e45de18d0bdfa612e4 (diff)
Bluetooth: Introduce LE auto connection infrastructure
This patch introduces the LE auto connection infrastructure which will be used to implement the LE auto connection options. In summary, the auto connection mechanism works as follows: Once the first pending LE connection is created, the background scanning is started. When the target device is found in range, the kernel autonomously starts the connection attempt. If connection is established successfully, that pending LE connection is deleted and the background is stopped. To achieve that, this patch introduces the hci_update_background_scan() which controls the background scanning state. This function starts or stops the background scanning based on the hdev->pend_le_conns list. If there is no pending LE connection, the background scanning is stopped. Otherwise, we start the background scanning. Then, every time a pending LE connection is added we call hci_update_ background_scan() so the background scanning is started (in case it is not already running). Likewise, every time a pending LE connection is deleted we call hci_update_background_scan() so the background scanning is stopped (in case this was the last pending LE connection) or it is started again (in case we have more pending LE connections). Finally, we also call hci_update_background_scan() in hci_le_conn_failed() so the background scan is restarted in case the connection establishment fails. This way the background scanning keeps running until all pending LE connection are established. At this point, resolvable addresses are not support by this infrastructure. The proper support is added in upcoming patches. Signed-off-by: Andre Guedes <andre.guedes@openbossa.org> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--include/net/bluetooth/hci_core.h2
-rw-r--r--net/bluetooth/hci_conn.c5
-rw-r--r--net/bluetooth/hci_core.c94
-rw-r--r--net/bluetooth/hci_event.c38
4 files changed, 137 insertions, 2 deletions
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index e08405d02649..617cf495a449 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -806,6 +806,8 @@ void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
806void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type); 806void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type);
807void hci_pend_le_conns_clear(struct hci_dev *hdev); 807void hci_pend_le_conns_clear(struct hci_dev *hdev);
808 808
809void hci_update_background_scan(struct hci_dev *hdev);
810
809void hci_uuids_clear(struct hci_dev *hdev); 811void hci_uuids_clear(struct hci_dev *hdev);
810 812
811void hci_link_keys_clear(struct hci_dev *hdev); 813void hci_link_keys_clear(struct hci_dev *hdev);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 46b27133740f..7d6f05e3cae8 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -527,6 +527,11 @@ void hci_le_conn_failed(struct hci_conn *conn, u8 status)
527 hci_proto_connect_cfm(conn, status); 527 hci_proto_connect_cfm(conn, status);
528 528
529 hci_conn_del(conn); 529 hci_conn_del(conn);
530
531 /* Since we may have temporarily stopped the background scanning in
532 * favor of connection establishment, we should restart it.
533 */
534 hci_update_background_scan(hdev);
530} 535}
531 536
532static void create_le_conn_complete(struct hci_dev *hdev, u8 status) 537static void create_le_conn_complete(struct hci_dev *hdev, u8 status)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 142ecd846ccd..9a08f341f0a4 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -3281,7 +3281,7 @@ void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
3281 3281
3282 entry = hci_pend_le_conn_lookup(hdev, addr, addr_type); 3282 entry = hci_pend_le_conn_lookup(hdev, addr, addr_type);
3283 if (entry) 3283 if (entry)
3284 return; 3284 goto done;
3285 3285
3286 entry = kzalloc(sizeof(*entry), GFP_KERNEL); 3286 entry = kzalloc(sizeof(*entry), GFP_KERNEL);
3287 if (!entry) { 3287 if (!entry) {
@@ -3295,6 +3295,9 @@ void hci_pend_le_conn_add(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
3295 list_add(&entry->list, &hdev->pend_le_conns); 3295 list_add(&entry->list, &hdev->pend_le_conns);
3296 3296
3297 BT_DBG("addr %pMR (type %u)", addr, addr_type); 3297 BT_DBG("addr %pMR (type %u)", addr, addr_type);
3298
3299done:
3300 hci_update_background_scan(hdev);
3298} 3301}
3299 3302
3300/* This function requires the caller holds hdev->lock */ 3303/* This function requires the caller holds hdev->lock */
@@ -3304,12 +3307,15 @@ void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type)
3304 3307
3305 entry = hci_pend_le_conn_lookup(hdev, addr, addr_type); 3308 entry = hci_pend_le_conn_lookup(hdev, addr, addr_type);
3306 if (!entry) 3309 if (!entry)
3307 return; 3310 goto done;
3308 3311
3309 list_del(&entry->list); 3312 list_del(&entry->list);
3310 kfree(entry); 3313 kfree(entry);
3311 3314
3312 BT_DBG("addr %pMR (type %u)", addr, addr_type); 3315 BT_DBG("addr %pMR (type %u)", addr, addr_type);
3316
3317done:
3318 hci_update_background_scan(hdev);
3313} 3319}
3314 3320
3315/* This function requires the caller holds hdev->lock */ 3321/* This function requires the caller holds hdev->lock */
@@ -4946,3 +4952,87 @@ void hci_req_add_le_scan_disable(struct hci_request *req)
4946 cp.enable = LE_SCAN_DISABLE; 4952 cp.enable = LE_SCAN_DISABLE;
4947 hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); 4953 hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp);
4948} 4954}
4955
4956static void update_background_scan_complete(struct hci_dev *hdev, u8 status)
4957{
4958 if (status)
4959 BT_DBG("HCI request failed to update background scanning: "
4960 "status 0x%2.2x", status);
4961}
4962
4963/* This function controls the background scanning based on hdev->pend_le_conns
4964 * list. If there are pending LE connection we start the background scanning,
4965 * otherwise we stop it.
4966 *
4967 * This function requires the caller holds hdev->lock.
4968 */
4969void hci_update_background_scan(struct hci_dev *hdev)
4970{
4971 struct hci_cp_le_set_scan_param param_cp;
4972 struct hci_cp_le_set_scan_enable enable_cp;
4973 struct hci_request req;
4974 struct hci_conn *conn;
4975 int err;
4976
4977 hci_req_init(&req, hdev);
4978
4979 if (list_empty(&hdev->pend_le_conns)) {
4980 /* If there is no pending LE connections, we should stop
4981 * the background scanning.
4982 */
4983
4984 /* If controller is not scanning we are done. */
4985 if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags))
4986 return;
4987
4988 hci_req_add_le_scan_disable(&req);
4989
4990 BT_DBG("%s stopping background scanning", hdev->name);
4991 } else {
4992 u8 own_addr_type;
4993
4994 /* If there is at least one pending LE connection, we should
4995 * keep the background scan running.
4996 */
4997
4998 /* If controller is already scanning we are done. */
4999 if (test_bit(HCI_LE_SCAN, &hdev->dev_flags))
5000 return;
5001
5002 /* If controller is connecting, we should not start scanning
5003 * since some controllers are not able to scan and connect at
5004 * the same time.
5005 */
5006 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
5007 if (conn)
5008 return;
5009
5010 /* Set require_privacy to true to avoid identification from
5011 * unknown peer devices. Since this is passive scanning, no
5012 * SCAN_REQ using the local identity should be sent. Mandating
5013 * privacy is just an extra precaution.
5014 */
5015 if (hci_update_random_address(&req, true, &own_addr_type))
5016 return;
5017
5018 memset(&param_cp, 0, sizeof(param_cp));
5019 param_cp.type = LE_SCAN_PASSIVE;
5020 param_cp.interval = cpu_to_le16(hdev->le_scan_interval);
5021 param_cp.window = cpu_to_le16(hdev->le_scan_window);
5022 param_cp.own_address_type = own_addr_type;
5023 hci_req_add(&req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp),
5024 &param_cp);
5025
5026 memset(&enable_cp, 0, sizeof(enable_cp));
5027 enable_cp.enable = LE_SCAN_ENABLE;
5028 enable_cp.filter_dup = LE_SCAN_FILTER_DUP_DISABLE;
5029 hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp),
5030 &enable_cp);
5031
5032 BT_DBG("%s starting background scanning", hdev->name);
5033 }
5034
5035 err = hci_req_run(&req, update_background_scan_complete);
5036 if (err)
5037 BT_ERR("Failed to run HCI request: err %d", err);
5038}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index eaa69650b1e5..b6631d7e2ddf 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -3677,25 +3677,63 @@ static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3677 3677
3678 hci_proto_connect_cfm(conn, ev->status); 3678 hci_proto_connect_cfm(conn, ev->status);
3679 3679
3680 hci_pend_le_conn_del(hdev, &conn->dst, conn->dst_type);
3681
3680unlock: 3682unlock:
3681 hci_dev_unlock(hdev); 3683 hci_dev_unlock(hdev);
3682} 3684}
3683 3685
3686/* This function requires the caller holds hdev->lock */
3687static void check_pending_le_conn(struct hci_dev *hdev, bdaddr_t *addr,
3688 u8 addr_type)
3689{
3690 struct hci_conn *conn;
3691
3692 if (!hci_pend_le_conn_lookup(hdev, addr, addr_type))
3693 return;
3694
3695 conn = hci_connect_le(hdev, addr, addr_type, BT_SECURITY_LOW,
3696 HCI_AT_NO_BONDING);
3697 if (!IS_ERR(conn))
3698 return;
3699
3700 switch (PTR_ERR(conn)) {
3701 case -EBUSY:
3702 /* If hci_connect() returns -EBUSY it means there is already
3703 * an LE connection attempt going on. Since controllers don't
3704 * support more than one connection attempt at the time, we
3705 * don't consider this an error case.
3706 */
3707 break;
3708 default:
3709 BT_DBG("Failed to connect: err %ld", PTR_ERR(conn));
3710 }
3711}
3712
3684static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) 3713static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
3685{ 3714{
3686 u8 num_reports = skb->data[0]; 3715 u8 num_reports = skb->data[0];
3687 void *ptr = &skb->data[1]; 3716 void *ptr = &skb->data[1];
3688 s8 rssi; 3717 s8 rssi;
3689 3718
3719 hci_dev_lock(hdev);
3720
3690 while (num_reports--) { 3721 while (num_reports--) {
3691 struct hci_ev_le_advertising_info *ev = ptr; 3722 struct hci_ev_le_advertising_info *ev = ptr;
3692 3723
3724 if (ev->evt_type == LE_ADV_IND ||
3725 ev->evt_type == LE_ADV_DIRECT_IND)
3726 check_pending_le_conn(hdev, &ev->bdaddr,
3727 ev->bdaddr_type);
3728
3693 rssi = ev->data[ev->length]; 3729 rssi = ev->data[ev->length];
3694 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type, 3730 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
3695 NULL, rssi, 0, 1, ev->data, ev->length); 3731 NULL, rssi, 0, 1, ev->data, ev->length);
3696 3732
3697 ptr += sizeof(*ev) + ev->length + 1; 3733 ptr += sizeof(*ev) + ev->length + 1;
3698 } 3734 }
3735
3736 hci_dev_unlock(hdev);
3699} 3737}
3700 3738
3701static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) 3739static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)