diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/hci_core.c | 192 | ||||
-rw-r--r-- | net/bluetooth/hci_event.c | 71 | ||||
-rw-r--r-- | net/bluetooth/hidp/core.c | 14 | ||||
-rw-r--r-- | net/bluetooth/l2cap_core.c | 121 | ||||
-rw-r--r-- | net/bluetooth/l2cap_sock.c | 4 | ||||
-rw-r--r-- | net/bluetooth/mgmt.c | 229 |
6 files changed, 308 insertions, 323 deletions
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c index ace5e55fe5a3..061523eb52a1 100644 --- a/net/bluetooth/hci_core.c +++ b/net/bluetooth/hci_core.c | |||
@@ -597,7 +597,15 @@ static void hci_init3_req(struct hci_request *req, unsigned long opt) | |||
597 | struct hci_dev *hdev = req->hdev; | 597 | struct hci_dev *hdev = req->hdev; |
598 | u8 p; | 598 | u8 p; |
599 | 599 | ||
600 | /* Only send HCI_Delete_Stored_Link_Key if it is supported */ | 600 | /* Some Broadcom based Bluetooth controllers do not support the |
601 | * Delete Stored Link Key command. They are clearly indicating its | ||
602 | * absence in the bit mask of supported commands. | ||
603 | * | ||
604 | * Check the supported commands and only if the the command is marked | ||
605 | * as supported send it. If not supported assume that the controller | ||
606 | * does not have actual support for stored link keys which makes this | ||
607 | * command redundant anyway. | ||
608 | */ | ||
601 | if (hdev->commands[6] & 0x80) { | 609 | if (hdev->commands[6] & 0x80) { |
602 | struct hci_cp_delete_stored_link_key cp; | 610 | struct hci_cp_delete_stored_link_key cp; |
603 | 611 | ||
@@ -751,7 +759,7 @@ void hci_discovery_set_state(struct hci_dev *hdev, int state) | |||
751 | hdev->discovery.state = state; | 759 | hdev->discovery.state = state; |
752 | } | 760 | } |
753 | 761 | ||
754 | static void inquiry_cache_flush(struct hci_dev *hdev) | 762 | void hci_inquiry_cache_flush(struct hci_dev *hdev) |
755 | { | 763 | { |
756 | struct discovery_state *cache = &hdev->discovery; | 764 | struct discovery_state *cache = &hdev->discovery; |
757 | struct inquiry_entry *p, *n; | 765 | struct inquiry_entry *p, *n; |
@@ -964,7 +972,7 @@ int hci_inquiry(void __user *arg) | |||
964 | hci_dev_lock(hdev); | 972 | hci_dev_lock(hdev); |
965 | if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || | 973 | if (inquiry_cache_age(hdev) > INQUIRY_CACHE_AGE_MAX || |
966 | inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { | 974 | inquiry_cache_empty(hdev) || ir.flags & IREQ_CACHE_FLUSH) { |
967 | inquiry_cache_flush(hdev); | 975 | hci_inquiry_cache_flush(hdev); |
968 | do_inquiry = 1; | 976 | do_inquiry = 1; |
969 | } | 977 | } |
970 | hci_dev_unlock(hdev); | 978 | hci_dev_unlock(hdev); |
@@ -1201,8 +1209,6 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
1201 | { | 1209 | { |
1202 | BT_DBG("%s %p", hdev->name, hdev); | 1210 | BT_DBG("%s %p", hdev->name, hdev); |
1203 | 1211 | ||
1204 | cancel_work_sync(&hdev->le_scan); | ||
1205 | |||
1206 | cancel_delayed_work(&hdev->power_off); | 1212 | cancel_delayed_work(&hdev->power_off); |
1207 | 1213 | ||
1208 | hci_req_cancel(hdev, ENODEV); | 1214 | hci_req_cancel(hdev, ENODEV); |
@@ -1230,7 +1236,7 @@ static int hci_dev_do_close(struct hci_dev *hdev) | |||
1230 | cancel_delayed_work_sync(&hdev->le_scan_disable); | 1236 | cancel_delayed_work_sync(&hdev->le_scan_disable); |
1231 | 1237 | ||
1232 | hci_dev_lock(hdev); | 1238 | hci_dev_lock(hdev); |
1233 | inquiry_cache_flush(hdev); | 1239 | hci_inquiry_cache_flush(hdev); |
1234 | hci_conn_hash_flush(hdev); | 1240 | hci_conn_hash_flush(hdev); |
1235 | hci_dev_unlock(hdev); | 1241 | hci_dev_unlock(hdev); |
1236 | 1242 | ||
@@ -1331,7 +1337,7 @@ int hci_dev_reset(__u16 dev) | |||
1331 | skb_queue_purge(&hdev->cmd_q); | 1337 | skb_queue_purge(&hdev->cmd_q); |
1332 | 1338 | ||
1333 | hci_dev_lock(hdev); | 1339 | hci_dev_lock(hdev); |
1334 | inquiry_cache_flush(hdev); | 1340 | hci_inquiry_cache_flush(hdev); |
1335 | hci_conn_hash_flush(hdev); | 1341 | hci_conn_hash_flush(hdev); |
1336 | hci_dev_unlock(hdev); | 1342 | hci_dev_unlock(hdev); |
1337 | 1343 | ||
@@ -1991,80 +1997,59 @@ int hci_blacklist_del(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 type) | |||
1991 | return mgmt_device_unblocked(hdev, bdaddr, type); | 1997 | return mgmt_device_unblocked(hdev, bdaddr, type); |
1992 | } | 1998 | } |
1993 | 1999 | ||
1994 | static void le_scan_param_req(struct hci_request *req, unsigned long opt) | 2000 | static void inquiry_complete(struct hci_dev *hdev, u8 status) |
1995 | { | 2001 | { |
1996 | struct le_scan_params *param = (struct le_scan_params *) opt; | 2002 | if (status) { |
1997 | struct hci_cp_le_set_scan_param cp; | 2003 | BT_ERR("Failed to start inquiry: status %d", status); |
1998 | |||
1999 | memset(&cp, 0, sizeof(cp)); | ||
2000 | cp.type = param->type; | ||
2001 | cp.interval = cpu_to_le16(param->interval); | ||
2002 | cp.window = cpu_to_le16(param->window); | ||
2003 | 2004 | ||
2004 | hci_req_add(req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(cp), &cp); | 2005 | hci_dev_lock(hdev); |
2005 | } | 2006 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); |
2006 | 2007 | hci_dev_unlock(hdev); | |
2007 | static void le_scan_enable_req(struct hci_request *req, unsigned long opt) | 2008 | return; |
2008 | { | 2009 | } |
2009 | struct hci_cp_le_set_scan_enable cp; | ||
2010 | |||
2011 | memset(&cp, 0, sizeof(cp)); | ||
2012 | cp.enable = LE_SCAN_ENABLE; | ||
2013 | cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE; | ||
2014 | |||
2015 | hci_req_add(req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); | ||
2016 | } | 2010 | } |
2017 | 2011 | ||
2018 | static int hci_do_le_scan(struct hci_dev *hdev, u8 type, u16 interval, | 2012 | static void le_scan_disable_work_complete(struct hci_dev *hdev, u8 status) |
2019 | u16 window, int timeout) | ||
2020 | { | 2013 | { |
2021 | long timeo = msecs_to_jiffies(3000); | 2014 | /* General inquiry access code (GIAC) */ |
2022 | struct le_scan_params param; | 2015 | u8 lap[3] = { 0x33, 0x8b, 0x9e }; |
2016 | struct hci_request req; | ||
2017 | struct hci_cp_inquiry cp; | ||
2023 | int err; | 2018 | int err; |
2024 | 2019 | ||
2025 | BT_DBG("%s", hdev->name); | 2020 | if (status) { |
2026 | 2021 | BT_ERR("Failed to disable LE scanning: status %d", status); | |
2027 | if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) | 2022 | return; |
2028 | return -EINPROGRESS; | 2023 | } |
2029 | |||
2030 | param.type = type; | ||
2031 | param.interval = interval; | ||
2032 | param.window = window; | ||
2033 | |||
2034 | hci_req_lock(hdev); | ||
2035 | |||
2036 | err = __hci_req_sync(hdev, le_scan_param_req, (unsigned long) ¶m, | ||
2037 | timeo); | ||
2038 | if (!err) | ||
2039 | err = __hci_req_sync(hdev, le_scan_enable_req, 0, timeo); | ||
2040 | |||
2041 | hci_req_unlock(hdev); | ||
2042 | 2024 | ||
2043 | if (err < 0) | 2025 | switch (hdev->discovery.type) { |
2044 | return err; | 2026 | case DISCOV_TYPE_LE: |
2027 | hci_dev_lock(hdev); | ||
2028 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
2029 | hci_dev_unlock(hdev); | ||
2030 | break; | ||
2045 | 2031 | ||
2046 | queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable, | 2032 | case DISCOV_TYPE_INTERLEAVED: |
2047 | timeout); | 2033 | hci_req_init(&req, hdev); |
2048 | 2034 | ||
2049 | return 0; | 2035 | memset(&cp, 0, sizeof(cp)); |
2050 | } | 2036 | memcpy(&cp.lap, lap, sizeof(cp.lap)); |
2037 | cp.length = DISCOV_INTERLEAVED_INQUIRY_LEN; | ||
2038 | hci_req_add(&req, HCI_OP_INQUIRY, sizeof(cp), &cp); | ||
2051 | 2039 | ||
2052 | int hci_cancel_le_scan(struct hci_dev *hdev) | 2040 | hci_dev_lock(hdev); |
2053 | { | ||
2054 | BT_DBG("%s", hdev->name); | ||
2055 | 2041 | ||
2056 | if (!test_bit(HCI_LE_SCAN, &hdev->dev_flags)) | 2042 | hci_inquiry_cache_flush(hdev); |
2057 | return -EALREADY; | ||
2058 | 2043 | ||
2059 | if (cancel_delayed_work(&hdev->le_scan_disable)) { | 2044 | err = hci_req_run(&req, inquiry_complete); |
2060 | struct hci_cp_le_set_scan_enable cp; | 2045 | if (err) { |
2046 | BT_ERR("Inquiry request failed: err %d", err); | ||
2047 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
2048 | } | ||
2061 | 2049 | ||
2062 | /* Send HCI command to disable LE Scan */ | 2050 | hci_dev_unlock(hdev); |
2063 | memset(&cp, 0, sizeof(cp)); | 2051 | break; |
2064 | hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); | ||
2065 | } | 2052 | } |
2066 | |||
2067 | return 0; | ||
2068 | } | 2053 | } |
2069 | 2054 | ||
2070 | static void le_scan_disable_work(struct work_struct *work) | 2055 | static void le_scan_disable_work(struct work_struct *work) |
@@ -2072,46 +2057,20 @@ static void le_scan_disable_work(struct work_struct *work) | |||
2072 | struct hci_dev *hdev = container_of(work, struct hci_dev, | 2057 | struct hci_dev *hdev = container_of(work, struct hci_dev, |
2073 | le_scan_disable.work); | 2058 | le_scan_disable.work); |
2074 | struct hci_cp_le_set_scan_enable cp; | 2059 | struct hci_cp_le_set_scan_enable cp; |
2060 | struct hci_request req; | ||
2061 | int err; | ||
2075 | 2062 | ||
2076 | BT_DBG("%s", hdev->name); | 2063 | BT_DBG("%s", hdev->name); |
2077 | 2064 | ||
2078 | memset(&cp, 0, sizeof(cp)); | 2065 | hci_req_init(&req, hdev); |
2079 | |||
2080 | hci_send_cmd(hdev, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); | ||
2081 | } | ||
2082 | |||
2083 | static void le_scan_work(struct work_struct *work) | ||
2084 | { | ||
2085 | struct hci_dev *hdev = container_of(work, struct hci_dev, le_scan); | ||
2086 | struct le_scan_params *param = &hdev->le_scan_params; | ||
2087 | 2066 | ||
2088 | BT_DBG("%s", hdev->name); | 2067 | memset(&cp, 0, sizeof(cp)); |
2068 | cp.enable = LE_SCAN_DISABLE; | ||
2069 | hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(cp), &cp); | ||
2089 | 2070 | ||
2090 | hci_do_le_scan(hdev, param->type, param->interval, param->window, | 2071 | err = hci_req_run(&req, le_scan_disable_work_complete); |
2091 | param->timeout); | 2072 | if (err) |
2092 | } | 2073 | BT_ERR("Disable LE scanning request failed: err %d", err); |
2093 | |||
2094 | int hci_le_scan(struct hci_dev *hdev, u8 type, u16 interval, u16 window, | ||
2095 | int timeout) | ||
2096 | { | ||
2097 | struct le_scan_params *param = &hdev->le_scan_params; | ||
2098 | |||
2099 | BT_DBG("%s", hdev->name); | ||
2100 | |||
2101 | if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags)) | ||
2102 | return -ENOTSUPP; | ||
2103 | |||
2104 | if (work_busy(&hdev->le_scan)) | ||
2105 | return -EINPROGRESS; | ||
2106 | |||
2107 | param->type = type; | ||
2108 | param->interval = interval; | ||
2109 | param->window = window; | ||
2110 | param->timeout = timeout; | ||
2111 | |||
2112 | queue_work(system_long_wq, &hdev->le_scan); | ||
2113 | |||
2114 | return 0; | ||
2115 | } | 2074 | } |
2116 | 2075 | ||
2117 | /* Alloc HCI device */ | 2076 | /* Alloc HCI device */ |
@@ -2148,7 +2107,6 @@ struct hci_dev *hci_alloc_dev(void) | |||
2148 | INIT_WORK(&hdev->cmd_work, hci_cmd_work); | 2107 | INIT_WORK(&hdev->cmd_work, hci_cmd_work); |
2149 | INIT_WORK(&hdev->tx_work, hci_tx_work); | 2108 | INIT_WORK(&hdev->tx_work, hci_tx_work); |
2150 | INIT_WORK(&hdev->power_on, hci_power_on); | 2109 | INIT_WORK(&hdev->power_on, hci_power_on); |
2151 | INIT_WORK(&hdev->le_scan, le_scan_work); | ||
2152 | 2110 | ||
2153 | INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); | 2111 | INIT_DELAYED_WORK(&hdev->power_off, hci_power_off); |
2154 | INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); | 2112 | INIT_DELAYED_WORK(&hdev->discov_off, hci_discov_off); |
@@ -3551,36 +3509,6 @@ static void hci_cmd_work(struct work_struct *work) | |||
3551 | } | 3509 | } |
3552 | } | 3510 | } |
3553 | 3511 | ||
3554 | int hci_do_inquiry(struct hci_dev *hdev, u8 length) | ||
3555 | { | ||
3556 | /* General inquiry access code (GIAC) */ | ||
3557 | u8 lap[3] = { 0x33, 0x8b, 0x9e }; | ||
3558 | struct hci_cp_inquiry cp; | ||
3559 | |||
3560 | BT_DBG("%s", hdev->name); | ||
3561 | |||
3562 | if (test_bit(HCI_INQUIRY, &hdev->flags)) | ||
3563 | return -EINPROGRESS; | ||
3564 | |||
3565 | inquiry_cache_flush(hdev); | ||
3566 | |||
3567 | memset(&cp, 0, sizeof(cp)); | ||
3568 | memcpy(&cp.lap, lap, sizeof(cp.lap)); | ||
3569 | cp.length = length; | ||
3570 | |||
3571 | return hci_send_cmd(hdev, HCI_OP_INQUIRY, sizeof(cp), &cp); | ||
3572 | } | ||
3573 | |||
3574 | int hci_cancel_inquiry(struct hci_dev *hdev) | ||
3575 | { | ||
3576 | BT_DBG("%s", hdev->name); | ||
3577 | |||
3578 | if (!test_bit(HCI_INQUIRY, &hdev->flags)) | ||
3579 | return -EALREADY; | ||
3580 | |||
3581 | return hci_send_cmd(hdev, HCI_OP_INQUIRY_CANCEL, 0, NULL); | ||
3582 | } | ||
3583 | |||
3584 | u8 bdaddr_to_le(u8 bdaddr_type) | 3512 | u8 bdaddr_to_le(u8 bdaddr_type) |
3585 | { | 3513 | { |
3586 | switch (bdaddr_type) { | 3514 | switch (bdaddr_type) { |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index b93cd2eb5d58..0437200d92f4 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -40,21 +40,13 @@ static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb) | |||
40 | 40 | ||
41 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | 41 | BT_DBG("%s status 0x%2.2x", hdev->name, status); |
42 | 42 | ||
43 | if (status) { | 43 | if (status) |
44 | hci_dev_lock(hdev); | ||
45 | mgmt_stop_discovery_failed(hdev, status); | ||
46 | hci_dev_unlock(hdev); | ||
47 | return; | 44 | return; |
48 | } | ||
49 | 45 | ||
50 | clear_bit(HCI_INQUIRY, &hdev->flags); | 46 | clear_bit(HCI_INQUIRY, &hdev->flags); |
51 | smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */ | 47 | smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */ |
52 | wake_up_bit(&hdev->flags, HCI_INQUIRY); | 48 | wake_up_bit(&hdev->flags, HCI_INQUIRY); |
53 | 49 | ||
54 | hci_dev_lock(hdev); | ||
55 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
56 | hci_dev_unlock(hdev); | ||
57 | |||
58 | hci_conn_check_pending(hdev); | 50 | hci_conn_check_pending(hdev); |
59 | } | 51 | } |
60 | 52 | ||
@@ -937,20 +929,6 @@ static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb) | |||
937 | hci_dev_unlock(hdev); | 929 | hci_dev_unlock(hdev); |
938 | } | 930 | } |
939 | 931 | ||
940 | static void hci_cc_le_set_scan_param(struct hci_dev *hdev, struct sk_buff *skb) | ||
941 | { | ||
942 | __u8 status = *((__u8 *) skb->data); | ||
943 | |||
944 | BT_DBG("%s status 0x%2.2x", hdev->name, status); | ||
945 | |||
946 | if (status) { | ||
947 | hci_dev_lock(hdev); | ||
948 | mgmt_start_discovery_failed(hdev, status); | ||
949 | hci_dev_unlock(hdev); | ||
950 | return; | ||
951 | } | ||
952 | } | ||
953 | |||
954 | static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, | 932 | static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, |
955 | struct sk_buff *skb) | 933 | struct sk_buff *skb) |
956 | { | 934 | { |
@@ -963,41 +941,16 @@ static void hci_cc_le_set_scan_enable(struct hci_dev *hdev, | |||
963 | if (!cp) | 941 | if (!cp) |
964 | return; | 942 | return; |
965 | 943 | ||
944 | if (status) | ||
945 | return; | ||
946 | |||
966 | switch (cp->enable) { | 947 | switch (cp->enable) { |
967 | case LE_SCAN_ENABLE: | 948 | case LE_SCAN_ENABLE: |
968 | if (status) { | ||
969 | hci_dev_lock(hdev); | ||
970 | mgmt_start_discovery_failed(hdev, status); | ||
971 | hci_dev_unlock(hdev); | ||
972 | return; | ||
973 | } | ||
974 | |||
975 | set_bit(HCI_LE_SCAN, &hdev->dev_flags); | 949 | set_bit(HCI_LE_SCAN, &hdev->dev_flags); |
976 | |||
977 | hci_dev_lock(hdev); | ||
978 | hci_discovery_set_state(hdev, DISCOVERY_FINDING); | ||
979 | hci_dev_unlock(hdev); | ||
980 | break; | 950 | break; |
981 | 951 | ||
982 | case LE_SCAN_DISABLE: | 952 | case LE_SCAN_DISABLE: |
983 | if (status) { | ||
984 | hci_dev_lock(hdev); | ||
985 | mgmt_stop_discovery_failed(hdev, status); | ||
986 | hci_dev_unlock(hdev); | ||
987 | return; | ||
988 | } | ||
989 | |||
990 | clear_bit(HCI_LE_SCAN, &hdev->dev_flags); | 953 | clear_bit(HCI_LE_SCAN, &hdev->dev_flags); |
991 | |||
992 | if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED && | ||
993 | hdev->discovery.state == DISCOVERY_FINDING) { | ||
994 | mgmt_interleaved_discovery(hdev); | ||
995 | } else { | ||
996 | hci_dev_lock(hdev); | ||
997 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
998 | hci_dev_unlock(hdev); | ||
999 | } | ||
1000 | |||
1001 | break; | 954 | break; |
1002 | 955 | ||
1003 | default: | 956 | default: |
@@ -1077,18 +1030,10 @@ static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status) | |||
1077 | 1030 | ||
1078 | if (status) { | 1031 | if (status) { |
1079 | hci_conn_check_pending(hdev); | 1032 | hci_conn_check_pending(hdev); |
1080 | hci_dev_lock(hdev); | ||
1081 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) | ||
1082 | mgmt_start_discovery_failed(hdev, status); | ||
1083 | hci_dev_unlock(hdev); | ||
1084 | return; | 1033 | return; |
1085 | } | 1034 | } |
1086 | 1035 | ||
1087 | set_bit(HCI_INQUIRY, &hdev->flags); | 1036 | set_bit(HCI_INQUIRY, &hdev->flags); |
1088 | |||
1089 | hci_dev_lock(hdev); | ||
1090 | hci_discovery_set_state(hdev, DISCOVERY_FINDING); | ||
1091 | hci_dev_unlock(hdev); | ||
1092 | } | 1037 | } |
1093 | 1038 | ||
1094 | static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) | 1039 | static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status) |
@@ -2298,10 +2243,6 @@ static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2298 | hci_cc_user_passkey_neg_reply(hdev, skb); | 2243 | hci_cc_user_passkey_neg_reply(hdev, skb); |
2299 | break; | 2244 | break; |
2300 | 2245 | ||
2301 | case HCI_OP_LE_SET_SCAN_PARAM: | ||
2302 | hci_cc_le_set_scan_param(hdev, skb); | ||
2303 | break; | ||
2304 | |||
2305 | case HCI_OP_LE_SET_ADV_ENABLE: | 2246 | case HCI_OP_LE_SET_ADV_ENABLE: |
2306 | hci_cc_le_set_adv_enable(hdev, skb); | 2247 | hci_cc_le_set_adv_enable(hdev, skb); |
2307 | break; | 2248 | break; |
@@ -2670,7 +2611,7 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2670 | 2611 | ||
2671 | BT_DBG("%s", hdev->name); | 2612 | BT_DBG("%s", hdev->name); |
2672 | 2613 | ||
2673 | if (!test_bit(HCI_LINK_KEYS, &hdev->dev_flags)) | 2614 | if (!test_bit(HCI_MGMT, &hdev->dev_flags)) |
2674 | return; | 2615 | return; |
2675 | 2616 | ||
2676 | hci_dev_lock(hdev); | 2617 | hci_dev_lock(hdev); |
@@ -2746,7 +2687,7 @@ static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
2746 | hci_conn_drop(conn); | 2687 | hci_conn_drop(conn); |
2747 | } | 2688 | } |
2748 | 2689 | ||
2749 | if (test_bit(HCI_LINK_KEYS, &hdev->dev_flags)) | 2690 | if (test_bit(HCI_MGMT, &hdev->dev_flags)) |
2750 | hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key, | 2691 | hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key, |
2751 | ev->key_type, pin_len); | 2692 | ev->key_type, pin_len); |
2752 | 2693 | ||
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c index 940f5acb6694..f13a8da441a8 100644 --- a/net/bluetooth/hidp/core.c +++ b/net/bluetooth/hidp/core.c | |||
@@ -76,25 +76,19 @@ static void hidp_copy_session(struct hidp_session *session, struct hidp_conninfo | |||
76 | ci->flags = session->flags; | 76 | ci->flags = session->flags; |
77 | ci->state = BT_CONNECTED; | 77 | ci->state = BT_CONNECTED; |
78 | 78 | ||
79 | ci->vendor = 0x0000; | ||
80 | ci->product = 0x0000; | ||
81 | ci->version = 0x0000; | ||
82 | |||
83 | if (session->input) { | 79 | if (session->input) { |
84 | ci->vendor = session->input->id.vendor; | 80 | ci->vendor = session->input->id.vendor; |
85 | ci->product = session->input->id.product; | 81 | ci->product = session->input->id.product; |
86 | ci->version = session->input->id.version; | 82 | ci->version = session->input->id.version; |
87 | if (session->input->name) | 83 | if (session->input->name) |
88 | strncpy(ci->name, session->input->name, 128); | 84 | strlcpy(ci->name, session->input->name, 128); |
89 | else | 85 | else |
90 | strncpy(ci->name, "HID Boot Device", 128); | 86 | strlcpy(ci->name, "HID Boot Device", 128); |
91 | } | 87 | } else if (session->hid) { |
92 | |||
93 | if (session->hid) { | ||
94 | ci->vendor = session->hid->vendor; | 88 | ci->vendor = session->hid->vendor; |
95 | ci->product = session->hid->product; | 89 | ci->product = session->hid->product; |
96 | ci->version = session->hid->version; | 90 | ci->version = session->hid->version; |
97 | strncpy(ci->name, session->hid->name, 128); | 91 | strlcpy(ci->name, session->hid->name, 128); |
98 | } | 92 | } |
99 | } | 93 | } |
100 | 94 | ||
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 4be6a264b475..9af3a76844f7 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -504,8 +504,10 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | |||
504 | if (conn->hcon->type == LE_LINK) { | 504 | if (conn->hcon->type == LE_LINK) { |
505 | /* LE connection */ | 505 | /* LE connection */ |
506 | chan->omtu = L2CAP_DEFAULT_MTU; | 506 | chan->omtu = L2CAP_DEFAULT_MTU; |
507 | chan->scid = L2CAP_CID_LE_DATA; | 507 | if (chan->dcid == L2CAP_CID_ATT) |
508 | chan->dcid = L2CAP_CID_LE_DATA; | 508 | chan->scid = L2CAP_CID_ATT; |
509 | else | ||
510 | chan->scid = l2cap_alloc_cid(conn); | ||
509 | } else { | 511 | } else { |
510 | /* Alloc CID for connection-oriented socket */ | 512 | /* Alloc CID for connection-oriented socket */ |
511 | chan->scid = l2cap_alloc_cid(conn); | 513 | chan->scid = l2cap_alloc_cid(conn); |
@@ -543,6 +545,8 @@ void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan) | |||
543 | 545 | ||
544 | l2cap_chan_hold(chan); | 546 | l2cap_chan_hold(chan); |
545 | 547 | ||
548 | hci_conn_hold(conn->hcon); | ||
549 | |||
546 | list_add(&chan->list, &conn->chan_l); | 550 | list_add(&chan->list, &conn->chan_l); |
547 | } | 551 | } |
548 | 552 | ||
@@ -1338,17 +1342,21 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid, | |||
1338 | 1342 | ||
1339 | static void l2cap_le_conn_ready(struct l2cap_conn *conn) | 1343 | static void l2cap_le_conn_ready(struct l2cap_conn *conn) |
1340 | { | 1344 | { |
1341 | struct sock *parent, *sk; | 1345 | struct sock *parent; |
1342 | struct l2cap_chan *chan, *pchan; | 1346 | struct l2cap_chan *chan, *pchan; |
1343 | 1347 | ||
1344 | BT_DBG(""); | 1348 | BT_DBG(""); |
1345 | 1349 | ||
1346 | /* Check if we have socket listening on cid */ | 1350 | /* Check if we have socket listening on cid */ |
1347 | pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_LE_DATA, | 1351 | pchan = l2cap_global_chan_by_scid(BT_LISTEN, L2CAP_CID_ATT, |
1348 | conn->src, conn->dst); | 1352 | conn->src, conn->dst); |
1349 | if (!pchan) | 1353 | if (!pchan) |
1350 | return; | 1354 | return; |
1351 | 1355 | ||
1356 | /* Client ATT sockets should override the server one */ | ||
1357 | if (__l2cap_get_chan_by_dcid(conn, L2CAP_CID_ATT)) | ||
1358 | return; | ||
1359 | |||
1352 | parent = pchan->sk; | 1360 | parent = pchan->sk; |
1353 | 1361 | ||
1354 | lock_sock(parent); | 1362 | lock_sock(parent); |
@@ -1357,17 +1365,12 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) | |||
1357 | if (!chan) | 1365 | if (!chan) |
1358 | goto clean; | 1366 | goto clean; |
1359 | 1367 | ||
1360 | sk = chan->sk; | 1368 | chan->dcid = L2CAP_CID_ATT; |
1361 | |||
1362 | hci_conn_hold(conn->hcon); | ||
1363 | conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT; | ||
1364 | |||
1365 | bacpy(&bt_sk(sk)->src, conn->src); | ||
1366 | bacpy(&bt_sk(sk)->dst, conn->dst); | ||
1367 | 1369 | ||
1368 | l2cap_chan_add(conn, chan); | 1370 | bacpy(&bt_sk(chan->sk)->src, conn->src); |
1371 | bacpy(&bt_sk(chan->sk)->dst, conn->dst); | ||
1369 | 1372 | ||
1370 | l2cap_chan_ready(chan); | 1373 | __l2cap_chan_add(conn, chan); |
1371 | 1374 | ||
1372 | clean: | 1375 | clean: |
1373 | release_sock(parent); | 1376 | release_sock(parent); |
@@ -1380,14 +1383,17 @@ static void l2cap_conn_ready(struct l2cap_conn *conn) | |||
1380 | 1383 | ||
1381 | BT_DBG("conn %p", conn); | 1384 | BT_DBG("conn %p", conn); |
1382 | 1385 | ||
1383 | if (!hcon->out && hcon->type == LE_LINK) | 1386 | /* For outgoing pairing which doesn't necessarily have an |
1384 | l2cap_le_conn_ready(conn); | 1387 | * associated socket (e.g. mgmt_pair_device). |
1385 | 1388 | */ | |
1386 | if (hcon->out && hcon->type == LE_LINK) | 1389 | if (hcon->out && hcon->type == LE_LINK) |
1387 | smp_conn_security(hcon, hcon->pending_sec_level); | 1390 | smp_conn_security(hcon, hcon->pending_sec_level); |
1388 | 1391 | ||
1389 | mutex_lock(&conn->chan_lock); | 1392 | mutex_lock(&conn->chan_lock); |
1390 | 1393 | ||
1394 | if (hcon->type == LE_LINK) | ||
1395 | l2cap_le_conn_ready(conn); | ||
1396 | |||
1391 | list_for_each_entry(chan, &conn->chan_l, list) { | 1397 | list_for_each_entry(chan, &conn->chan_l, list) { |
1392 | 1398 | ||
1393 | l2cap_chan_lock(chan); | 1399 | l2cap_chan_lock(chan); |
@@ -1792,7 +1798,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, | |||
1792 | 1798 | ||
1793 | auth_type = l2cap_get_auth_type(chan); | 1799 | auth_type = l2cap_get_auth_type(chan); |
1794 | 1800 | ||
1795 | if (chan->dcid == L2CAP_CID_LE_DATA) | 1801 | if (bdaddr_type_is_le(dst_type)) |
1796 | hcon = hci_connect(hdev, LE_LINK, dst, dst_type, | 1802 | hcon = hci_connect(hdev, LE_LINK, dst, dst_type, |
1797 | chan->sec_level, auth_type); | 1803 | chan->sec_level, auth_type); |
1798 | else | 1804 | else |
@@ -1811,16 +1817,10 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, | |||
1811 | goto done; | 1817 | goto done; |
1812 | } | 1818 | } |
1813 | 1819 | ||
1814 | if (hcon->type == LE_LINK) { | 1820 | if (cid && __l2cap_get_chan_by_dcid(conn, cid)) { |
1815 | err = 0; | 1821 | hci_conn_drop(hcon); |
1816 | 1822 | err = -EBUSY; | |
1817 | if (!list_empty(&conn->chan_l)) { | 1823 | goto done; |
1818 | err = -EBUSY; | ||
1819 | hci_conn_drop(hcon); | ||
1820 | } | ||
1821 | |||
1822 | if (err) | ||
1823 | goto done; | ||
1824 | } | 1824 | } |
1825 | 1825 | ||
1826 | /* Update source addr of the socket */ | 1826 | /* Update source addr of the socket */ |
@@ -1830,6 +1830,9 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid, | |||
1830 | l2cap_chan_add(conn, chan); | 1830 | l2cap_chan_add(conn, chan); |
1831 | l2cap_chan_lock(chan); | 1831 | l2cap_chan_lock(chan); |
1832 | 1832 | ||
1833 | /* l2cap_chan_add takes its own ref so we can drop this one */ | ||
1834 | hci_conn_drop(hcon); | ||
1835 | |||
1833 | l2cap_state_change(chan, BT_CONNECT); | 1836 | l2cap_state_change(chan, BT_CONNECT); |
1834 | __set_chan_timer(chan, sk->sk_sndtimeo); | 1837 | __set_chan_timer(chan, sk->sk_sndtimeo); |
1835 | 1838 | ||
@@ -3751,8 +3754,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn, | |||
3751 | 3754 | ||
3752 | sk = chan->sk; | 3755 | sk = chan->sk; |
3753 | 3756 | ||
3754 | hci_conn_hold(conn->hcon); | ||
3755 | |||
3756 | bacpy(&bt_sk(sk)->src, conn->src); | 3757 | bacpy(&bt_sk(sk)->src, conn->src); |
3757 | bacpy(&bt_sk(sk)->dst, conn->dst); | 3758 | bacpy(&bt_sk(sk)->dst, conn->dst); |
3758 | chan->psm = psm; | 3759 | chan->psm = psm; |
@@ -5292,6 +5293,51 @@ static inline int l2cap_le_sig_cmd(struct l2cap_conn *conn, | |||
5292 | } | 5293 | } |
5293 | } | 5294 | } |
5294 | 5295 | ||
5296 | static inline void l2cap_le_sig_channel(struct l2cap_conn *conn, | ||
5297 | struct sk_buff *skb) | ||
5298 | { | ||
5299 | u8 *data = skb->data; | ||
5300 | int len = skb->len; | ||
5301 | struct l2cap_cmd_hdr cmd; | ||
5302 | int err; | ||
5303 | |||
5304 | l2cap_raw_recv(conn, skb); | ||
5305 | |||
5306 | while (len >= L2CAP_CMD_HDR_SIZE) { | ||
5307 | u16 cmd_len; | ||
5308 | memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE); | ||
5309 | data += L2CAP_CMD_HDR_SIZE; | ||
5310 | len -= L2CAP_CMD_HDR_SIZE; | ||
5311 | |||
5312 | cmd_len = le16_to_cpu(cmd.len); | ||
5313 | |||
5314 | BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd_len, | ||
5315 | cmd.ident); | ||
5316 | |||
5317 | if (cmd_len > len || !cmd.ident) { | ||
5318 | BT_DBG("corrupted command"); | ||
5319 | break; | ||
5320 | } | ||
5321 | |||
5322 | err = l2cap_le_sig_cmd(conn, &cmd, data); | ||
5323 | if (err) { | ||
5324 | struct l2cap_cmd_rej_unk rej; | ||
5325 | |||
5326 | BT_ERR("Wrong link type (%d)", err); | ||
5327 | |||
5328 | /* FIXME: Map err to a valid reason */ | ||
5329 | rej.reason = __constant_cpu_to_le16(L2CAP_REJ_NOT_UNDERSTOOD); | ||
5330 | l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, | ||
5331 | sizeof(rej), &rej); | ||
5332 | } | ||
5333 | |||
5334 | data += cmd_len; | ||
5335 | len -= cmd_len; | ||
5336 | } | ||
5337 | |||
5338 | kfree_skb(skb); | ||
5339 | } | ||
5340 | |||
5295 | static inline void l2cap_sig_channel(struct l2cap_conn *conn, | 5341 | static inline void l2cap_sig_channel(struct l2cap_conn *conn, |
5296 | struct sk_buff *skb) | 5342 | struct sk_buff *skb) |
5297 | { | 5343 | { |
@@ -5318,11 +5364,7 @@ static inline void l2cap_sig_channel(struct l2cap_conn *conn, | |||
5318 | break; | 5364 | break; |
5319 | } | 5365 | } |
5320 | 5366 | ||
5321 | if (conn->hcon->type == LE_LINK) | 5367 | err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data); |
5322 | err = l2cap_le_sig_cmd(conn, &cmd, data); | ||
5323 | else | ||
5324 | err = l2cap_bredr_sig_cmd(conn, &cmd, cmd_len, data); | ||
5325 | |||
5326 | if (err) { | 5368 | if (err) { |
5327 | struct l2cap_cmd_rej_unk rej; | 5369 | struct l2cap_cmd_rej_unk rej; |
5328 | 5370 | ||
@@ -6356,16 +6398,13 @@ static void l2cap_att_channel(struct l2cap_conn *conn, | |||
6356 | { | 6398 | { |
6357 | struct l2cap_chan *chan; | 6399 | struct l2cap_chan *chan; |
6358 | 6400 | ||
6359 | chan = l2cap_global_chan_by_scid(0, L2CAP_CID_LE_DATA, | 6401 | chan = l2cap_global_chan_by_scid(BT_CONNECTED, L2CAP_CID_ATT, |
6360 | conn->src, conn->dst); | 6402 | conn->src, conn->dst); |
6361 | if (!chan) | 6403 | if (!chan) |
6362 | goto drop; | 6404 | goto drop; |
6363 | 6405 | ||
6364 | BT_DBG("chan %p, len %d", chan, skb->len); | 6406 | BT_DBG("chan %p, len %d", chan, skb->len); |
6365 | 6407 | ||
6366 | if (chan->state != BT_BOUND && chan->state != BT_CONNECTED) | ||
6367 | goto drop; | ||
6368 | |||
6369 | if (chan->imtu < skb->len) | 6408 | if (chan->imtu < skb->len) |
6370 | goto drop; | 6409 | goto drop; |
6371 | 6410 | ||
@@ -6395,6 +6434,8 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) | |||
6395 | 6434 | ||
6396 | switch (cid) { | 6435 | switch (cid) { |
6397 | case L2CAP_CID_LE_SIGNALING: | 6436 | case L2CAP_CID_LE_SIGNALING: |
6437 | l2cap_le_sig_channel(conn, skb); | ||
6438 | break; | ||
6398 | case L2CAP_CID_SIGNALING: | 6439 | case L2CAP_CID_SIGNALING: |
6399 | l2cap_sig_channel(conn, skb); | 6440 | l2cap_sig_channel(conn, skb); |
6400 | break; | 6441 | break; |
@@ -6405,7 +6446,7 @@ static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb) | |||
6405 | l2cap_conless_channel(conn, psm, skb); | 6446 | l2cap_conless_channel(conn, psm, skb); |
6406 | break; | 6447 | break; |
6407 | 6448 | ||
6408 | case L2CAP_CID_LE_DATA: | 6449 | case L2CAP_CID_ATT: |
6409 | l2cap_att_channel(conn, skb); | 6450 | l2cap_att_channel(conn, skb); |
6410 | break; | 6451 | break; |
6411 | 6452 | ||
@@ -6531,7 +6572,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt) | |||
6531 | continue; | 6572 | continue; |
6532 | } | 6573 | } |
6533 | 6574 | ||
6534 | if (chan->scid == L2CAP_CID_LE_DATA) { | 6575 | if (chan->scid == L2CAP_CID_ATT) { |
6535 | if (!status && encrypt) { | 6576 | if (!status && encrypt) { |
6536 | chan->sec_level = hcon->sec_level; | 6577 | chan->sec_level = hcon->sec_level; |
6537 | l2cap_chan_ready(chan); | 6578 | l2cap_chan_ready(chan); |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 36fed40c162c..0098af80b213 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -466,7 +466,7 @@ static int l2cap_sock_getsockopt(struct socket *sock, int level, int optname, | |||
466 | static bool l2cap_valid_mtu(struct l2cap_chan *chan, u16 mtu) | 466 | static bool l2cap_valid_mtu(struct l2cap_chan *chan, u16 mtu) |
467 | { | 467 | { |
468 | switch (chan->scid) { | 468 | switch (chan->scid) { |
469 | case L2CAP_CID_LE_DATA: | 469 | case L2CAP_CID_ATT: |
470 | if (mtu < L2CAP_LE_MIN_MTU) | 470 | if (mtu < L2CAP_LE_MIN_MTU) |
471 | return false; | 471 | return false; |
472 | break; | 472 | break; |
@@ -630,7 +630,7 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, | |||
630 | conn = chan->conn; | 630 | conn = chan->conn; |
631 | 631 | ||
632 | /*change security for LE channels */ | 632 | /*change security for LE channels */ |
633 | if (chan->scid == L2CAP_CID_LE_DATA) { | 633 | if (chan->scid == L2CAP_CID_ATT) { |
634 | if (!conn->hcon->out) { | 634 | if (!conn->hcon->out) { |
635 | err = -EINVAL; | 635 | err = -EINVAL; |
636 | break; | 636 | break; |
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index f8ecbc70293d..fedc5399d465 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -102,18 +102,6 @@ static const u16 mgmt_events[] = { | |||
102 | MGMT_EV_PASSKEY_NOTIFY, | 102 | MGMT_EV_PASSKEY_NOTIFY, |
103 | }; | 103 | }; |
104 | 104 | ||
105 | /* | ||
106 | * These LE scan and inquiry parameters were chosen according to LE General | ||
107 | * Discovery Procedure specification. | ||
108 | */ | ||
109 | #define LE_SCAN_WIN 0x12 | ||
110 | #define LE_SCAN_INT 0x12 | ||
111 | #define LE_SCAN_TIMEOUT_LE_ONLY msecs_to_jiffies(10240) | ||
112 | #define LE_SCAN_TIMEOUT_BREDR_LE msecs_to_jiffies(5120) | ||
113 | |||
114 | #define INQUIRY_LEN_BREDR 0x08 /* TGAP(100) */ | ||
115 | #define INQUIRY_LEN_BREDR_LE 0x04 /* TGAP(100)/2 */ | ||
116 | |||
117 | #define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000) | 105 | #define CACHE_TIMEOUT msecs_to_jiffies(2 * 1000) |
118 | 106 | ||
119 | #define hdev_is_powered(hdev) (test_bit(HCI_UP, &hdev->flags) && \ | 107 | #define hdev_is_powered(hdev) (test_bit(HCI_UP, &hdev->flags) && \ |
@@ -1748,8 +1736,6 @@ static int load_link_keys(struct sock *sk, struct hci_dev *hdev, void *data, | |||
1748 | 1736 | ||
1749 | hci_link_keys_clear(hdev); | 1737 | hci_link_keys_clear(hdev); |
1750 | 1738 | ||
1751 | set_bit(HCI_LINK_KEYS, &hdev->dev_flags); | ||
1752 | |||
1753 | if (cp->debug_keys) | 1739 | if (cp->debug_keys) |
1754 | set_bit(HCI_DEBUG_KEYS, &hdev->dev_flags); | 1740 | set_bit(HCI_DEBUG_KEYS, &hdev->dev_flags); |
1755 | else | 1741 | else |
@@ -2633,28 +2619,72 @@ static int remove_remote_oob_data(struct sock *sk, struct hci_dev *hdev, | |||
2633 | return err; | 2619 | return err; |
2634 | } | 2620 | } |
2635 | 2621 | ||
2636 | int mgmt_interleaved_discovery(struct hci_dev *hdev) | 2622 | static int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status) |
2637 | { | 2623 | { |
2624 | struct pending_cmd *cmd; | ||
2625 | u8 type; | ||
2638 | int err; | 2626 | int err; |
2639 | 2627 | ||
2640 | BT_DBG("%s", hdev->name); | 2628 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); |
2641 | 2629 | ||
2642 | hci_dev_lock(hdev); | 2630 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev); |
2631 | if (!cmd) | ||
2632 | return -ENOENT; | ||
2643 | 2633 | ||
2644 | err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR_LE); | 2634 | type = hdev->discovery.type; |
2645 | if (err < 0) | ||
2646 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
2647 | 2635 | ||
2648 | hci_dev_unlock(hdev); | 2636 | err = cmd_complete(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status), |
2637 | &type, sizeof(type)); | ||
2638 | mgmt_pending_remove(cmd); | ||
2649 | 2639 | ||
2650 | return err; | 2640 | return err; |
2651 | } | 2641 | } |
2652 | 2642 | ||
2643 | static void start_discovery_complete(struct hci_dev *hdev, u8 status) | ||
2644 | { | ||
2645 | BT_DBG("status %d", status); | ||
2646 | |||
2647 | if (status) { | ||
2648 | hci_dev_lock(hdev); | ||
2649 | mgmt_start_discovery_failed(hdev, status); | ||
2650 | hci_dev_unlock(hdev); | ||
2651 | return; | ||
2652 | } | ||
2653 | |||
2654 | hci_dev_lock(hdev); | ||
2655 | hci_discovery_set_state(hdev, DISCOVERY_FINDING); | ||
2656 | hci_dev_unlock(hdev); | ||
2657 | |||
2658 | switch (hdev->discovery.type) { | ||
2659 | case DISCOV_TYPE_LE: | ||
2660 | queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable, | ||
2661 | DISCOV_LE_TIMEOUT); | ||
2662 | break; | ||
2663 | |||
2664 | case DISCOV_TYPE_INTERLEAVED: | ||
2665 | queue_delayed_work(hdev->workqueue, &hdev->le_scan_disable, | ||
2666 | DISCOV_INTERLEAVED_TIMEOUT); | ||
2667 | break; | ||
2668 | |||
2669 | case DISCOV_TYPE_BREDR: | ||
2670 | break; | ||
2671 | |||
2672 | default: | ||
2673 | BT_ERR("Invalid discovery type %d", hdev->discovery.type); | ||
2674 | } | ||
2675 | } | ||
2676 | |||
2653 | static int start_discovery(struct sock *sk, struct hci_dev *hdev, | 2677 | static int start_discovery(struct sock *sk, struct hci_dev *hdev, |
2654 | void *data, u16 len) | 2678 | void *data, u16 len) |
2655 | { | 2679 | { |
2656 | struct mgmt_cp_start_discovery *cp = data; | 2680 | struct mgmt_cp_start_discovery *cp = data; |
2657 | struct pending_cmd *cmd; | 2681 | struct pending_cmd *cmd; |
2682 | struct hci_cp_le_set_scan_param param_cp; | ||
2683 | struct hci_cp_le_set_scan_enable enable_cp; | ||
2684 | struct hci_cp_inquiry inq_cp; | ||
2685 | struct hci_request req; | ||
2686 | /* General inquiry access code (GIAC) */ | ||
2687 | u8 lap[3] = { 0x33, 0x8b, 0x9e }; | ||
2658 | int err; | 2688 | int err; |
2659 | 2689 | ||
2660 | BT_DBG("%s", hdev->name); | 2690 | BT_DBG("%s", hdev->name); |
@@ -2687,6 +2717,8 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, | |||
2687 | 2717 | ||
2688 | hdev->discovery.type = cp->type; | 2718 | hdev->discovery.type = cp->type; |
2689 | 2719 | ||
2720 | hci_req_init(&req, hdev); | ||
2721 | |||
2690 | switch (hdev->discovery.type) { | 2722 | switch (hdev->discovery.type) { |
2691 | case DISCOV_TYPE_BREDR: | 2723 | case DISCOV_TYPE_BREDR: |
2692 | if (!lmp_bredr_capable(hdev)) { | 2724 | if (!lmp_bredr_capable(hdev)) { |
@@ -2696,10 +2728,23 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, | |||
2696 | goto failed; | 2728 | goto failed; |
2697 | } | 2729 | } |
2698 | 2730 | ||
2699 | err = hci_do_inquiry(hdev, INQUIRY_LEN_BREDR); | 2731 | if (test_bit(HCI_INQUIRY, &hdev->flags)) { |
2732 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, | ||
2733 | MGMT_STATUS_BUSY); | ||
2734 | mgmt_pending_remove(cmd); | ||
2735 | goto failed; | ||
2736 | } | ||
2737 | |||
2738 | hci_inquiry_cache_flush(hdev); | ||
2739 | |||
2740 | memset(&inq_cp, 0, sizeof(inq_cp)); | ||
2741 | memcpy(&inq_cp.lap, lap, sizeof(inq_cp.lap)); | ||
2742 | inq_cp.length = DISCOV_BREDR_INQUIRY_LEN; | ||
2743 | hci_req_add(&req, HCI_OP_INQUIRY, sizeof(inq_cp), &inq_cp); | ||
2700 | break; | 2744 | break; |
2701 | 2745 | ||
2702 | case DISCOV_TYPE_LE: | 2746 | case DISCOV_TYPE_LE: |
2747 | case DISCOV_TYPE_INTERLEAVED: | ||
2703 | if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { | 2748 | if (!test_bit(HCI_LE_ENABLED, &hdev->dev_flags)) { |
2704 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, | 2749 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, |
2705 | MGMT_STATUS_NOT_SUPPORTED); | 2750 | MGMT_STATUS_NOT_SUPPORTED); |
@@ -2707,20 +2752,40 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, | |||
2707 | goto failed; | 2752 | goto failed; |
2708 | } | 2753 | } |
2709 | 2754 | ||
2710 | err = hci_le_scan(hdev, LE_SCAN_ACTIVE, LE_SCAN_INT, | 2755 | if (hdev->discovery.type == DISCOV_TYPE_INTERLEAVED && |
2711 | LE_SCAN_WIN, LE_SCAN_TIMEOUT_LE_ONLY); | 2756 | !lmp_bredr_capable(hdev)) { |
2712 | break; | ||
2713 | |||
2714 | case DISCOV_TYPE_INTERLEAVED: | ||
2715 | if (!lmp_host_le_capable(hdev) || !lmp_bredr_capable(hdev)) { | ||
2716 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, | 2757 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, |
2717 | MGMT_STATUS_NOT_SUPPORTED); | 2758 | MGMT_STATUS_NOT_SUPPORTED); |
2718 | mgmt_pending_remove(cmd); | 2759 | mgmt_pending_remove(cmd); |
2719 | goto failed; | 2760 | goto failed; |
2720 | } | 2761 | } |
2721 | 2762 | ||
2722 | err = hci_le_scan(hdev, LE_SCAN_ACTIVE, LE_SCAN_INT, | 2763 | if (test_bit(HCI_LE_PERIPHERAL, &hdev->dev_flags)) { |
2723 | LE_SCAN_WIN, LE_SCAN_TIMEOUT_BREDR_LE); | 2764 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, |
2765 | MGMT_STATUS_REJECTED); | ||
2766 | mgmt_pending_remove(cmd); | ||
2767 | goto failed; | ||
2768 | } | ||
2769 | |||
2770 | if (test_bit(HCI_LE_SCAN, &hdev->dev_flags)) { | ||
2771 | err = cmd_status(sk, hdev->id, MGMT_OP_START_DISCOVERY, | ||
2772 | MGMT_STATUS_BUSY); | ||
2773 | mgmt_pending_remove(cmd); | ||
2774 | goto failed; | ||
2775 | } | ||
2776 | |||
2777 | memset(¶m_cp, 0, sizeof(param_cp)); | ||
2778 | param_cp.type = LE_SCAN_ACTIVE; | ||
2779 | param_cp.interval = cpu_to_le16(DISCOV_LE_SCAN_INT); | ||
2780 | param_cp.window = cpu_to_le16(DISCOV_LE_SCAN_WIN); | ||
2781 | hci_req_add(&req, HCI_OP_LE_SET_SCAN_PARAM, sizeof(param_cp), | ||
2782 | ¶m_cp); | ||
2783 | |||
2784 | memset(&enable_cp, 0, sizeof(enable_cp)); | ||
2785 | enable_cp.enable = LE_SCAN_ENABLE; | ||
2786 | enable_cp.filter_dup = LE_SCAN_FILTER_DUP_ENABLE; | ||
2787 | hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, sizeof(enable_cp), | ||
2788 | &enable_cp); | ||
2724 | break; | 2789 | break; |
2725 | 2790 | ||
2726 | default: | 2791 | default: |
@@ -2730,6 +2795,7 @@ static int start_discovery(struct sock *sk, struct hci_dev *hdev, | |||
2730 | goto failed; | 2795 | goto failed; |
2731 | } | 2796 | } |
2732 | 2797 | ||
2798 | err = hci_req_run(&req, start_discovery_complete); | ||
2733 | if (err < 0) | 2799 | if (err < 0) |
2734 | mgmt_pending_remove(cmd); | 2800 | mgmt_pending_remove(cmd); |
2735 | else | 2801 | else |
@@ -2740,6 +2806,39 @@ failed: | |||
2740 | return err; | 2806 | return err; |
2741 | } | 2807 | } |
2742 | 2808 | ||
2809 | static int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status) | ||
2810 | { | ||
2811 | struct pending_cmd *cmd; | ||
2812 | int err; | ||
2813 | |||
2814 | cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev); | ||
2815 | if (!cmd) | ||
2816 | return -ENOENT; | ||
2817 | |||
2818 | err = cmd_complete(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status), | ||
2819 | &hdev->discovery.type, sizeof(hdev->discovery.type)); | ||
2820 | mgmt_pending_remove(cmd); | ||
2821 | |||
2822 | return err; | ||
2823 | } | ||
2824 | |||
2825 | static void stop_discovery_complete(struct hci_dev *hdev, u8 status) | ||
2826 | { | ||
2827 | BT_DBG("status %d", status); | ||
2828 | |||
2829 | hci_dev_lock(hdev); | ||
2830 | |||
2831 | if (status) { | ||
2832 | mgmt_stop_discovery_failed(hdev, status); | ||
2833 | goto unlock; | ||
2834 | } | ||
2835 | |||
2836 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
2837 | |||
2838 | unlock: | ||
2839 | hci_dev_unlock(hdev); | ||
2840 | } | ||
2841 | |||
2743 | static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, | 2842 | static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, |
2744 | u16 len) | 2843 | u16 len) |
2745 | { | 2844 | { |
@@ -2747,6 +2846,8 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2747 | struct pending_cmd *cmd; | 2846 | struct pending_cmd *cmd; |
2748 | struct hci_cp_remote_name_req_cancel cp; | 2847 | struct hci_cp_remote_name_req_cancel cp; |
2749 | struct inquiry_entry *e; | 2848 | struct inquiry_entry *e; |
2849 | struct hci_request req; | ||
2850 | struct hci_cp_le_set_scan_enable enable_cp; | ||
2750 | int err; | 2851 | int err; |
2751 | 2852 | ||
2752 | BT_DBG("%s", hdev->name); | 2853 | BT_DBG("%s", hdev->name); |
@@ -2773,12 +2874,20 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2773 | goto unlock; | 2874 | goto unlock; |
2774 | } | 2875 | } |
2775 | 2876 | ||
2877 | hci_req_init(&req, hdev); | ||
2878 | |||
2776 | switch (hdev->discovery.state) { | 2879 | switch (hdev->discovery.state) { |
2777 | case DISCOVERY_FINDING: | 2880 | case DISCOVERY_FINDING: |
2778 | if (test_bit(HCI_INQUIRY, &hdev->flags)) | 2881 | if (test_bit(HCI_INQUIRY, &hdev->flags)) { |
2779 | err = hci_cancel_inquiry(hdev); | 2882 | hci_req_add(&req, HCI_OP_INQUIRY_CANCEL, 0, NULL); |
2780 | else | 2883 | } else { |
2781 | err = hci_cancel_le_scan(hdev); | 2884 | cancel_delayed_work(&hdev->le_scan_disable); |
2885 | |||
2886 | memset(&enable_cp, 0, sizeof(enable_cp)); | ||
2887 | enable_cp.enable = LE_SCAN_DISABLE; | ||
2888 | hci_req_add(&req, HCI_OP_LE_SET_SCAN_ENABLE, | ||
2889 | sizeof(enable_cp), &enable_cp); | ||
2890 | } | ||
2782 | 2891 | ||
2783 | break; | 2892 | break; |
2784 | 2893 | ||
@@ -2796,16 +2905,22 @@ static int stop_discovery(struct sock *sk, struct hci_dev *hdev, void *data, | |||
2796 | } | 2905 | } |
2797 | 2906 | ||
2798 | bacpy(&cp.bdaddr, &e->data.bdaddr); | 2907 | bacpy(&cp.bdaddr, &e->data.bdaddr); |
2799 | err = hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ_CANCEL, | 2908 | hci_req_add(&req, HCI_OP_REMOTE_NAME_REQ_CANCEL, sizeof(cp), |
2800 | sizeof(cp), &cp); | 2909 | &cp); |
2801 | 2910 | ||
2802 | break; | 2911 | break; |
2803 | 2912 | ||
2804 | default: | 2913 | default: |
2805 | BT_DBG("unknown discovery state %u", hdev->discovery.state); | 2914 | BT_DBG("unknown discovery state %u", hdev->discovery.state); |
2806 | err = -EFAULT; | 2915 | |
2916 | mgmt_pending_remove(cmd); | ||
2917 | err = cmd_complete(sk, hdev->id, MGMT_OP_STOP_DISCOVERY, | ||
2918 | MGMT_STATUS_FAILED, &mgmt_cp->type, | ||
2919 | sizeof(mgmt_cp->type)); | ||
2920 | goto unlock; | ||
2807 | } | 2921 | } |
2808 | 2922 | ||
2923 | err = hci_req_run(&req, stop_discovery_complete); | ||
2809 | if (err < 0) | 2924 | if (err < 0) |
2810 | mgmt_pending_remove(cmd); | 2925 | mgmt_pending_remove(cmd); |
2811 | else | 2926 | else |
@@ -4063,6 +4178,9 @@ int mgmt_device_found(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
4063 | struct mgmt_ev_device_found *ev = (void *) buf; | 4178 | struct mgmt_ev_device_found *ev = (void *) buf; |
4064 | size_t ev_size; | 4179 | size_t ev_size; |
4065 | 4180 | ||
4181 | if (!hci_discovery_active(hdev)) | ||
4182 | return -EPERM; | ||
4183 | |||
4066 | /* Leave 5 bytes for a potential CoD field */ | 4184 | /* Leave 5 bytes for a potential CoD field */ |
4067 | if (sizeof(*ev) + eir_len + 5 > sizeof(buf)) | 4185 | if (sizeof(*ev) + eir_len + 5 > sizeof(buf)) |
4068 | return -EINVAL; | 4186 | return -EINVAL; |
@@ -4114,43 +4232,6 @@ int mgmt_remote_name(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type, | |||
4114 | sizeof(*ev) + eir_len, NULL); | 4232 | sizeof(*ev) + eir_len, NULL); |
4115 | } | 4233 | } |
4116 | 4234 | ||
4117 | int mgmt_start_discovery_failed(struct hci_dev *hdev, u8 status) | ||
4118 | { | ||
4119 | struct pending_cmd *cmd; | ||
4120 | u8 type; | ||
4121 | int err; | ||
4122 | |||
4123 | hci_discovery_set_state(hdev, DISCOVERY_STOPPED); | ||
4124 | |||
4125 | cmd = mgmt_pending_find(MGMT_OP_START_DISCOVERY, hdev); | ||
4126 | if (!cmd) | ||
4127 | return -ENOENT; | ||
4128 | |||
4129 | type = hdev->discovery.type; | ||
4130 | |||
4131 | err = cmd_complete(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status), | ||
4132 | &type, sizeof(type)); | ||
4133 | mgmt_pending_remove(cmd); | ||
4134 | |||
4135 | return err; | ||
4136 | } | ||
4137 | |||
4138 | int mgmt_stop_discovery_failed(struct hci_dev *hdev, u8 status) | ||
4139 | { | ||
4140 | struct pending_cmd *cmd; | ||
4141 | int err; | ||
4142 | |||
4143 | cmd = mgmt_pending_find(MGMT_OP_STOP_DISCOVERY, hdev); | ||
4144 | if (!cmd) | ||
4145 | return -ENOENT; | ||
4146 | |||
4147 | err = cmd_complete(cmd->sk, hdev->id, cmd->opcode, mgmt_status(status), | ||
4148 | &hdev->discovery.type, sizeof(hdev->discovery.type)); | ||
4149 | mgmt_pending_remove(cmd); | ||
4150 | |||
4151 | return err; | ||
4152 | } | ||
4153 | |||
4154 | int mgmt_discovering(struct hci_dev *hdev, u8 discovering) | 4235 | int mgmt_discovering(struct hci_dev *hdev, u8 discovering) |
4155 | { | 4236 | { |
4156 | struct mgmt_ev_discovering ev; | 4237 | struct mgmt_ev_discovering ev; |