aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_event.c
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 /net/bluetooth/hci_event.c
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>
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r--net/bluetooth/hci_event.c38
1 files changed, 38 insertions, 0 deletions
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)