diff options
-rw-r--r-- | include/net/bluetooth/hci_core.h | 2 | ||||
-rw-r--r-- | net/bluetooth/hci_conn.c | 5 | ||||
-rw-r--r-- | net/bluetooth/hci_core.c | 94 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 38 |
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); | |||
806 | void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type); | 806 | void hci_pend_le_conn_del(struct hci_dev *hdev, bdaddr_t *addr, u8 addr_type); |
807 | void hci_pend_le_conns_clear(struct hci_dev *hdev); | 807 | void hci_pend_le_conns_clear(struct hci_dev *hdev); |
808 | 808 | ||
809 | void hci_update_background_scan(struct hci_dev *hdev); | ||
810 | |||
809 | void hci_uuids_clear(struct hci_dev *hdev); | 811 | void hci_uuids_clear(struct hci_dev *hdev); |
810 | 812 | ||
811 | void hci_link_keys_clear(struct hci_dev *hdev); | 813 | void 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 | ||
532 | static void create_le_conn_complete(struct hci_dev *hdev, u8 status) | 537 | static 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 | |||
3299 | done: | ||
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 | |||
3317 | done: | ||
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 | |||
4956 | static 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 | */ | ||
4969 | void 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(¶m_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 | ¶m_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 | |||
3680 | unlock: | 3682 | unlock: |
3681 | hci_dev_unlock(hdev); | 3683 | hci_dev_unlock(hdev); |
3682 | } | 3684 | } |
3683 | 3685 | ||
3686 | /* This function requires the caller holds hdev->lock */ | ||
3687 | static 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 | |||
3684 | static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) | 3713 | static 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 | ||
3701 | static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | 3739 | static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb) |