blob: 6eaef6ed95223afe867699b3946875f16b011753 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <asm/unaligned.h>
28
29#include <net/bluetooth/bluetooth.h>
30#include <net/bluetooth/hci_core.h>
Mikel Astizf0d6a0e2012-08-09 09:52:30 +020031#include <net/bluetooth/mgmt.h>
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +030032#include <net/bluetooth/a2mp.h>
Andrei Emeltchenko903e4542012-09-27 17:26:09 +030033#include <net/bluetooth/amp.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070034
Linus Torvalds1da177e2005-04-16 15:20:36 -070035/* Handle HCI Event packets */
36
Marcel Holtmanna9de9242007-10-20 13:33:56 +020037static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070038{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020039 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070040
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030041 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070042
Andre Guedes82f47852013-04-30 15:29:34 -030043 if (status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020044 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070045
Andre Guedes89352e72011-11-04 14:16:53 -030046 clear_bit(HCI_INQUIRY, &hdev->flags);
Andre Guedes3e13fa12013-03-27 20:04:56 -030047 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
48 wake_up_bit(&hdev->flags, HCI_INQUIRY);
Andre Guedes89352e72011-11-04 14:16:53 -030049
Marcel Holtmanna9de9242007-10-20 13:33:56 +020050 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070051}
52
Andre Guedes4d934832012-03-21 00:03:35 -030053static void hci_cc_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
54{
55 __u8 status = *((__u8 *) skb->data);
56
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030057 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesae854a72012-03-21 00:03:36 -030058
59 if (status)
60 return;
61
62 set_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
Andre Guedes4d934832012-03-21 00:03:35 -030063}
64
Marcel Holtmanna9de9242007-10-20 13:33:56 +020065static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070066{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020067 __u8 status = *((__u8 *) skb->data);
68
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030069 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020070
71 if (status)
72 return;
73
Andre Guedesae854a72012-03-21 00:03:36 -030074 clear_bit(HCI_PERIODIC_INQ, &hdev->dev_flags);
75
Marcel Holtmanna9de9242007-10-20 13:33:56 +020076 hci_conn_check_pending(hdev);
77}
78
Gustavo Padovan807deac2012-05-17 00:36:24 -030079static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev,
80 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +020081{
82 BT_DBG("%s", hdev->name);
83}
84
85static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
86{
87 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +030090 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
Marcel Holtmanna9de9242007-10-20 13:33:56 +020092 if (rp->status)
93 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
Marcel Holtmanna9de9242007-10-20 13:33:56 +020095 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
Marcel Holtmanna9de9242007-10-20 13:33:56 +020097 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
98 if (conn) {
99 if (rp->role)
100 conn->link_mode &= ~HCI_LM_MASTER;
101 else
102 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200104
105 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106}
107
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200108static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
109{
110 struct hci_rp_read_link_policy *rp = (void *) skb->data;
111 struct hci_conn *conn;
112
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300113 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200114
115 if (rp->status)
116 return;
117
118 hci_dev_lock(hdev);
119
120 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
121 if (conn)
122 conn->link_policy = __le16_to_cpu(rp->policy);
123
124 hci_dev_unlock(hdev);
125}
126
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200127static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200129 struct hci_rp_write_link_policy *rp = (void *) skb->data;
130 struct hci_conn *conn;
131 void *sent;
132
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300133 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200134
135 if (rp->status)
136 return;
137
138 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
139 if (!sent)
140 return;
141
142 hci_dev_lock(hdev);
143
144 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200145 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700146 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200147
148 hci_dev_unlock(hdev);
149}
150
Gustavo Padovan807deac2012-05-17 00:36:24 -0300151static void hci_cc_read_def_link_policy(struct hci_dev *hdev,
152 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200153{
154 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
155
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300156 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200157
158 if (rp->status)
159 return;
160
161 hdev->link_policy = __le16_to_cpu(rp->policy);
162}
163
Gustavo Padovan807deac2012-05-17 00:36:24 -0300164static void hci_cc_write_def_link_policy(struct hci_dev *hdev,
165 struct sk_buff *skb)
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200166{
167 __u8 status = *((__u8 *) skb->data);
168 void *sent;
169
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300170 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200171
172 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
173 if (!sent)
174 return;
175
176 if (!status)
177 hdev->link_policy = get_unaligned_le16(sent);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200178}
179
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200180static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
181{
182 __u8 status = *((__u8 *) skb->data);
183
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300184 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200185
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300186 clear_bit(HCI_RESET, &hdev->flags);
187
Johan Hedberga297e972012-02-21 17:55:47 +0200188 /* Reset all non-persistent flags */
Johan Hedberg2cc6fb02013-03-15 17:06:57 -0500189 hdev->dev_flags &= ~HCI_PERSISTENT_MASK;
Andre Guedes69775ff2012-02-23 16:50:05 +0200190
191 hdev->discovery.state = DISCOVERY_STOPPED;
Johan Hedbergbbaf4442012-11-08 01:22:59 +0100192 hdev->inq_tx_power = HCI_TX_POWER_INVALID;
193 hdev->adv_tx_power = HCI_TX_POWER_INVALID;
Johan Hedberg3f0f5242012-11-08 01:23:00 +0100194
195 memset(hdev->adv_data, 0, sizeof(hdev->adv_data));
196 hdev->adv_data_len = 0;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200197}
198
199static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
200{
201 __u8 status = *((__u8 *) skb->data);
202 void *sent;
203
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300204 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200205
206 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
207 if (!sent)
208 return;
209
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200210 hci_dev_lock(hdev);
211
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200212 if (test_bit(HCI_MGMT, &hdev->dev_flags))
213 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedberg28cc7bd2012-02-22 21:06:55 +0200214 else if (!status)
215 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergf51d5b22012-02-22 18:17:32 +0200216
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200217 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200218}
219
220static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
221{
222 struct hci_rp_read_local_name *rp = (void *) skb->data;
223
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300224 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200225
226 if (rp->status)
227 return;
228
Johan Hedbergdb99b5f2012-02-22 20:14:22 +0200229 if (test_bit(HCI_SETUP, &hdev->dev_flags))
230 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200231}
232
233static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
234{
235 __u8 status = *((__u8 *) skb->data);
236 void *sent;
237
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300238 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200239
240 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
241 if (!sent)
242 return;
243
244 if (!status) {
245 __u8 param = *((__u8 *) sent);
246
247 if (param == AUTH_ENABLED)
248 set_bit(HCI_AUTH, &hdev->flags);
249 else
250 clear_bit(HCI_AUTH, &hdev->flags);
251 }
252
Johan Hedberg33ef95e2012-02-16 23:56:27 +0200253 if (test_bit(HCI_MGMT, &hdev->dev_flags))
254 mgmt_auth_enable_complete(hdev, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200255}
256
257static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
258{
259 __u8 status = *((__u8 *) skb->data);
260 void *sent;
261
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300262 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200263
264 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
265 if (!sent)
266 return;
267
268 if (!status) {
269 __u8 param = *((__u8 *) sent);
270
271 if (param)
272 set_bit(HCI_ENCRYPT, &hdev->flags);
273 else
274 clear_bit(HCI_ENCRYPT, &hdev->flags);
275 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200276}
277
278static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
279{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200280 __u8 param, status = *((__u8 *) skb->data);
281 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200282 void *sent;
283
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300284 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200285
286 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
287 if (!sent)
288 return;
289
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200290 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200291
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200292 hci_dev_lock(hdev);
293
Mikel Astizfa1bd912012-08-09 09:52:29 +0200294 if (status) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200295 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200296 hdev->discov_timeout = 0;
297 goto done;
298 }
299
Johan Hedberg0663ca22013-10-02 13:43:14 +0300300 /* We need to ensure that we set this back on if someone changed
301 * the scan mode through a raw HCI socket.
302 */
303 set_bit(HCI_BREDR_ENABLED, &hdev->dev_flags);
304
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200305 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
306 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200307
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200308 if (param & SCAN_INQUIRY) {
309 set_bit(HCI_ISCAN, &hdev->flags);
310 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200311 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200312 if (hdev->discov_timeout > 0) {
313 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
314 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300315 to);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200316 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200317 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200318 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200319
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200320 if (param & SCAN_PAGE) {
321 set_bit(HCI_PSCAN, &hdev->flags);
322 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200323 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200324 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200325 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200326
327done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200328 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200329}
330
331static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
332{
333 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
334
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300335 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200336
337 if (rp->status)
338 return;
339
340 memcpy(hdev->dev_class, rp->dev_class, 3);
341
342 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300343 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200344}
345
346static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
347{
348 __u8 status = *((__u8 *) skb->data);
349 void *sent;
350
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300351 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200352
353 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
354 if (!sent)
355 return;
356
Marcel Holtmann7f9a9032012-02-22 18:38:01 +0100357 hci_dev_lock(hdev);
358
359 if (status == 0)
360 memcpy(hdev->dev_class, sent, 3);
361
362 if (test_bit(HCI_MGMT, &hdev->dev_flags))
363 mgmt_set_class_of_dev_complete(hdev, sent, status);
364
365 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200366}
367
368static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
369{
370 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200372
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300373 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200374
375 if (rp->status)
376 return;
377
378 setting = __le16_to_cpu(rp->voice_setting);
379
Marcel Holtmannf383f272008-07-14 20:13:47 +0200380 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200381 return;
382
383 hdev->voice_setting = setting;
384
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300385 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200386
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200387 if (hdev->notify)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200388 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200389}
390
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300391static void hci_cc_write_voice_setting(struct hci_dev *hdev,
392 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200393{
394 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200395 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396 void *sent;
397
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300398 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700399
Marcel Holtmannf383f272008-07-14 20:13:47 +0200400 if (status)
401 return;
402
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200403 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
404 if (!sent)
405 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700406
Marcel Holtmannf383f272008-07-14 20:13:47 +0200407 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700408
Marcel Holtmannf383f272008-07-14 20:13:47 +0200409 if (hdev->voice_setting == setting)
410 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411
Marcel Holtmannf383f272008-07-14 20:13:47 +0200412 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300414 BT_DBG("%s voice setting 0x%4.4x", hdev->name, setting);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200415
Gustavo F. Padovan3c547112011-12-14 22:58:44 -0200416 if (hdev->notify)
Marcel Holtmannf383f272008-07-14 20:13:47 +0200417 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418}
419
Marcel Holtmann333140b2008-07-14 20:13:48 +0200420static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
421{
422 __u8 status = *((__u8 *) skb->data);
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300423 struct hci_cp_write_ssp_mode *sent;
Marcel Holtmann333140b2008-07-14 20:13:48 +0200424
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300425 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann333140b2008-07-14 20:13:48 +0200426
Marcel Holtmann333140b2008-07-14 20:13:48 +0200427 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
428 if (!sent)
429 return;
430
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300431 if (!status) {
432 if (sent->mode)
Johan Hedbergcad718e2013-04-17 15:00:51 +0300433 hdev->features[1][0] |= LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300434 else
Johan Hedbergcad718e2013-04-17 15:00:51 +0300435 hdev->features[1][0] &= ~LMP_HOST_SSP;
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300436 }
437
Johan Hedberged2c4ee2012-02-17 00:56:28 +0200438 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300439 mgmt_ssp_enable_complete(hdev, sent->mode, status);
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200440 else if (!status) {
Johan Hedberg5ed8eb22012-10-25 00:09:51 +0300441 if (sent->mode)
Johan Hedbergc0ecddc2012-02-22 12:38:31 +0200442 set_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
443 else
444 clear_bit(HCI_SSP_ENABLED, &hdev->dev_flags);
445 }
Marcel Holtmann333140b2008-07-14 20:13:48 +0200446}
447
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200448static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
449{
450 struct hci_rp_read_local_version *rp = (void *) skb->data;
451
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300452 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200453
454 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200455 return;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200456
457 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200458 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200459 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200460 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200461 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200462
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300463 BT_DBG("%s manufacturer 0x%4.4x hci ver %d:%d", hdev->name,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300464 hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200465}
466
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300467static void hci_cc_read_local_commands(struct hci_dev *hdev,
468 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200469{
470 struct hci_rp_read_local_commands *rp = (void *) skb->data;
471
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300472 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200473
Johan Hedberg2177bab2013-03-05 20:37:43 +0200474 if (!rp->status)
475 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200476}
477
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -0300478static void hci_cc_read_local_features(struct hci_dev *hdev,
479 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200480{
481 struct hci_rp_read_local_features *rp = (void *) skb->data;
482
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300483 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200484
485 if (rp->status)
486 return;
487
488 memcpy(hdev->features, rp->features, 8);
489
490 /* Adjust default settings according to features
491 * supported by device. */
492
Johan Hedbergcad718e2013-04-17 15:00:51 +0300493 if (hdev->features[0][0] & LMP_3SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200494 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
495
Johan Hedbergcad718e2013-04-17 15:00:51 +0300496 if (hdev->features[0][0] & LMP_5SLOT)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200497 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
498
Johan Hedbergcad718e2013-04-17 15:00:51 +0300499 if (hdev->features[0][1] & LMP_HV2) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200500 hdev->pkt_type |= (HCI_HV2);
501 hdev->esco_type |= (ESCO_HV2);
502 }
503
Johan Hedbergcad718e2013-04-17 15:00:51 +0300504 if (hdev->features[0][1] & LMP_HV3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200505 hdev->pkt_type |= (HCI_HV3);
506 hdev->esco_type |= (ESCO_HV3);
507 }
508
Andre Guedes45db810f2012-07-24 15:03:49 -0300509 if (lmp_esco_capable(hdev))
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200510 hdev->esco_type |= (ESCO_EV3);
511
Johan Hedbergcad718e2013-04-17 15:00:51 +0300512 if (hdev->features[0][4] & LMP_EV4)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200513 hdev->esco_type |= (ESCO_EV4);
514
Johan Hedbergcad718e2013-04-17 15:00:51 +0300515 if (hdev->features[0][4] & LMP_EV5)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200516 hdev->esco_type |= (ESCO_EV5);
517
Johan Hedbergcad718e2013-04-17 15:00:51 +0300518 if (hdev->features[0][5] & LMP_EDR_ESCO_2M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100519 hdev->esco_type |= (ESCO_2EV3);
520
Johan Hedbergcad718e2013-04-17 15:00:51 +0300521 if (hdev->features[0][5] & LMP_EDR_ESCO_3M)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100522 hdev->esco_type |= (ESCO_3EV3);
523
Johan Hedbergcad718e2013-04-17 15:00:51 +0300524 if (hdev->features[0][5] & LMP_EDR_3S_ESCO)
Marcel Holtmannefc76882009-02-06 09:13:37 +0100525 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
526
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200527 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
Johan Hedbergcad718e2013-04-17 15:00:51 +0300528 hdev->features[0][0], hdev->features[0][1],
529 hdev->features[0][2], hdev->features[0][3],
530 hdev->features[0][4], hdev->features[0][5],
531 hdev->features[0][6], hdev->features[0][7]);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200532}
533
Andre Guedes971e3a42011-06-30 19:20:52 -0300534static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300535 struct sk_buff *skb)
Andre Guedes971e3a42011-06-30 19:20:52 -0300536{
537 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
538
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300539 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andre Guedes971e3a42011-06-30 19:20:52 -0300540
541 if (rp->status)
Johan Hedberg42c6b122013-03-05 20:37:49 +0200542 return;
Andre Guedes971e3a42011-06-30 19:20:52 -0300543
Johan Hedbergd2c5d772013-04-17 15:00:52 +0300544 hdev->max_page = rp->max_page;
545
Johan Hedbergcad718e2013-04-17 15:00:51 +0300546 if (rp->page < HCI_MAX_PAGES)
547 memcpy(hdev->features[rp->page], rp->features, 8);
Andre Guedes971e3a42011-06-30 19:20:52 -0300548}
549
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200550static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300551 struct sk_buff *skb)
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200552{
553 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
554
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300555 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200556
Johan Hedberg42c6b122013-03-05 20:37:49 +0200557 if (!rp->status)
558 hdev->flow_ctl_mode = rp->mode;
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +0200559}
560
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200561static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
562{
563 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
564
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300565 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200566
567 if (rp->status)
568 return;
569
570 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
571 hdev->sco_mtu = rp->sco_mtu;
572 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
573 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
574
575 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
576 hdev->sco_mtu = 64;
577 hdev->sco_pkts = 8;
578 }
579
580 hdev->acl_cnt = hdev->acl_pkts;
581 hdev->sco_cnt = hdev->sco_pkts;
582
Gustavo Padovan807deac2012-05-17 00:36:24 -0300583 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name, hdev->acl_mtu,
584 hdev->acl_pkts, hdev->sco_mtu, hdev->sco_pkts);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200585}
586
587static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
588{
589 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
590
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300591 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200592
593 if (!rp->status)
594 bacpy(&hdev->bdaddr, &rp->bdaddr);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200595}
596
Johan Hedbergf332ec62013-03-15 17:07:11 -0500597static void hci_cc_read_page_scan_activity(struct hci_dev *hdev,
598 struct sk_buff *skb)
599{
600 struct hci_rp_read_page_scan_activity *rp = (void *) skb->data;
601
602 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
603
604 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status) {
605 hdev->page_scan_interval = __le16_to_cpu(rp->interval);
606 hdev->page_scan_window = __le16_to_cpu(rp->window);
607 }
608}
609
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500610static void hci_cc_write_page_scan_activity(struct hci_dev *hdev,
611 struct sk_buff *skb)
612{
613 u8 status = *((u8 *) skb->data);
614 struct hci_cp_write_page_scan_activity *sent;
615
616 BT_DBG("%s status 0x%2.2x", hdev->name, status);
617
618 if (status)
619 return;
620
621 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_ACTIVITY);
622 if (!sent)
623 return;
624
625 hdev->page_scan_interval = __le16_to_cpu(sent->interval);
626 hdev->page_scan_window = __le16_to_cpu(sent->window);
627}
628
Johan Hedbergf332ec62013-03-15 17:07:11 -0500629static void hci_cc_read_page_scan_type(struct hci_dev *hdev,
630 struct sk_buff *skb)
631{
632 struct hci_rp_read_page_scan_type *rp = (void *) skb->data;
633
634 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
635
636 if (test_bit(HCI_INIT, &hdev->flags) && !rp->status)
637 hdev->page_scan_type = rp->type;
638}
639
Johan Hedberg4a3ee762013-03-15 17:07:12 -0500640static void hci_cc_write_page_scan_type(struct hci_dev *hdev,
641 struct sk_buff *skb)
642{
643 u8 status = *((u8 *) skb->data);
644 u8 *type;
645
646 BT_DBG("%s status 0x%2.2x", hdev->name, status);
647
648 if (status)
649 return;
650
651 type = hci_sent_cmd_data(hdev, HCI_OP_WRITE_PAGE_SCAN_TYPE);
652 if (type)
653 hdev->page_scan_type = *type;
654}
655
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200656static void hci_cc_read_data_block_size(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300657 struct sk_buff *skb)
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200658{
659 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
660
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300661 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200662
663 if (rp->status)
664 return;
665
666 hdev->block_mtu = __le16_to_cpu(rp->max_acl_len);
667 hdev->block_len = __le16_to_cpu(rp->block_len);
668 hdev->num_blocks = __le16_to_cpu(rp->num_blocks);
669
670 hdev->block_cnt = hdev->num_blocks;
671
672 BT_DBG("%s blk mtu %d cnt %d len %d", hdev->name, hdev->block_mtu,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300673 hdev->block_cnt, hdev->block_len);
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +0200674}
675
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300676static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300677 struct sk_buff *skb)
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300678{
679 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
680
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300681 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300682
683 if (rp->status)
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300684 goto a2mp_rsp;
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300685
686 hdev->amp_status = rp->amp_status;
687 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
688 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
689 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
690 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
691 hdev->amp_type = rp->amp_type;
692 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
693 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
694 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
695 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
696
Andrei Emeltchenko8e2a0d92012-09-27 17:26:08 +0300697a2mp_rsp:
698 a2mp_send_getinfo_rsp(hdev);
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300699}
700
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300701static void hci_cc_read_local_amp_assoc(struct hci_dev *hdev,
702 struct sk_buff *skb)
703{
704 struct hci_rp_read_local_amp_assoc *rp = (void *) skb->data;
705 struct amp_assoc *assoc = &hdev->loc_assoc;
706 size_t rem_len, frag_len;
707
708 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
709
710 if (rp->status)
711 goto a2mp_rsp;
712
713 frag_len = skb->len - sizeof(*rp);
714 rem_len = __le16_to_cpu(rp->rem_len);
715
716 if (rem_len > frag_len) {
Andrei Emeltchenko2e430be32012-09-28 14:44:23 +0300717 BT_DBG("frag_len %zu rem_len %zu", frag_len, rem_len);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300718
719 memcpy(assoc->data + assoc->offset, rp->frag, frag_len);
720 assoc->offset += frag_len;
721
722 /* Read other fragments */
723 amp_read_loc_assoc_frag(hdev, rp->phy_handle);
724
725 return;
726 }
727
728 memcpy(assoc->data + assoc->offset, rp->frag, rem_len);
729 assoc->len = assoc->offset + rem_len;
730 assoc->offset = 0;
731
732a2mp_rsp:
733 /* Send A2MP Rsp when all fragments are received */
734 a2mp_send_getampassoc_rsp(hdev, rp->status);
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +0300735 a2mp_send_create_phy_link_req(hdev, rp->status);
Andrei Emeltchenko903e4542012-09-27 17:26:09 +0300736}
737
Johan Hedbergd5859e22011-01-25 01:19:58 +0200738static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300739 struct sk_buff *skb)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200740{
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700741 struct hci_rp_read_inq_rsp_tx_power *rp = (void *) skb->data;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200742
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300743 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200744
Marcel Holtmann91c4e9b2012-03-11 19:27:21 -0700745 if (!rp->status)
746 hdev->inq_tx_power = rp->tx_power;
Johan Hedbergd5859e22011-01-25 01:19:58 +0200747}
748
Johan Hedberg980e1a52011-01-22 06:10:07 +0200749static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
750{
751 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
752 struct hci_cp_pin_code_reply *cp;
753 struct hci_conn *conn;
754
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300755 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200756
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200757 hci_dev_lock(hdev);
758
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200759 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200760 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200761
Mikel Astizfa1bd912012-08-09 09:52:29 +0200762 if (rp->status)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200763 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200764
765 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
766 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200767 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200768
769 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
770 if (conn)
771 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200772
773unlock:
774 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200775}
776
777static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
778{
779 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
780
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300781 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200782
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200783 hci_dev_lock(hdev);
784
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200785 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200786 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300787 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200788
789 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200790}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200791
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300792static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
793 struct sk_buff *skb)
794{
795 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
796
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300797 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300798
799 if (rp->status)
800 return;
801
802 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
803 hdev->le_pkts = rp->le_max_pkt;
804
805 hdev->le_cnt = hdev->le_pkts;
806
807 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300808}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200809
Johan Hedberg60e77322013-01-22 14:01:59 +0200810static void hci_cc_le_read_local_features(struct hci_dev *hdev,
811 struct sk_buff *skb)
812{
813 struct hci_rp_le_read_local_features *rp = (void *) skb->data;
814
815 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
816
817 if (!rp->status)
818 memcpy(hdev->le_features, rp->features, 8);
Johan Hedberg60e77322013-01-22 14:01:59 +0200819}
820
Johan Hedberg8fa19092012-10-19 20:57:49 +0300821static void hci_cc_le_read_adv_tx_power(struct hci_dev *hdev,
822 struct sk_buff *skb)
823{
824 struct hci_rp_le_read_adv_tx_power *rp = (void *) skb->data;
825
826 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
827
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500828 if (!rp->status)
Johan Hedberg8fa19092012-10-19 20:57:49 +0300829 hdev->adv_tx_power = rp->tx_power;
Johan Hedberg8fa19092012-10-19 20:57:49 +0300830}
831
Johan Hedberga5c29682011-02-19 12:05:57 -0300832static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
833{
834 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
835
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300836 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300837
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200838 hci_dev_lock(hdev);
839
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200840 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300841 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr, ACL_LINK, 0,
842 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200843
844 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300845}
846
847static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300848 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -0300849{
850 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
851
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300852 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Johan Hedberga5c29682011-02-19 12:05:57 -0300853
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200854 hci_dev_lock(hdev);
855
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200856 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200857 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300858 ACL_LINK, 0, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200859
860 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300861}
862
Brian Gix1143d452011-11-23 08:28:34 -0800863static void hci_cc_user_passkey_reply(struct hci_dev *hdev, struct sk_buff *skb)
864{
865 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
866
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300867 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800868
869 hci_dev_lock(hdev);
870
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200871 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +0200872 mgmt_user_passkey_reply_complete(hdev, &rp->bdaddr, ACL_LINK,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300873 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800874
875 hci_dev_unlock(hdev);
876}
877
878static void hci_cc_user_passkey_neg_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300879 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -0800880{
881 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
882
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300883 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800884
885 hci_dev_lock(hdev);
886
Johan Hedberga8b2d5c2012-01-08 23:11:15 +0200887 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Brian Gix1143d452011-11-23 08:28:34 -0800888 mgmt_user_passkey_neg_reply_complete(hdev, &rp->bdaddr,
Gustavo F. Padovan04124682012-03-08 01:25:00 -0300889 ACL_LINK, 0, rp->status);
Brian Gix1143d452011-11-23 08:28:34 -0800890
891 hci_dev_unlock(hdev);
892}
893
Szymon Jancc35938b2011-03-22 13:12:21 +0100894static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300895 struct sk_buff *skb)
Szymon Jancc35938b2011-03-22 13:12:21 +0100896{
897 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
898
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300899 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
Szymon Jancc35938b2011-03-22 13:12:21 +0100900
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200901 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +0200902 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +0100903 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200904 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100905}
906
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100907static void hci_cc_le_set_adv_enable(struct hci_dev *hdev, struct sk_buff *skb)
908{
909 __u8 *sent, status = *((__u8 *) skb->data);
910
911 BT_DBG("%s status 0x%2.2x", hdev->name, status);
912
913 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_ADV_ENABLE);
914 if (!sent)
915 return;
916
917 hci_dev_lock(hdev);
918
919 if (!status) {
920 if (*sent)
Johan Hedbergf3d3444a2013-10-05 12:01:04 +0200921 set_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100922 else
Johan Hedbergf3d3444a2013-10-05 12:01:04 +0200923 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100924 }
925
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500926 if (!test_bit(HCI_INIT, &hdev->flags)) {
927 struct hci_request req;
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100928
Johan Hedberg04b4edc2013-03-15 17:07:01 -0500929 hci_req_init(&req, hdev);
930 hci_update_ad(&req);
931 hci_req_run(&req, NULL);
932 }
933
934 hci_dev_unlock(hdev);
Johan Hedbergc1d5dc42012-11-08 01:23:01 +0100935}
936
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300937static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -0300938 struct sk_buff *skb)
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300939{
940 struct hci_cp_le_set_scan_enable *cp;
941 __u8 status = *((__u8 *) skb->data);
942
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300943 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300944
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300945 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
946 if (!cp)
947 return;
948
Andre Guedes3fd319b2013-04-30 15:29:36 -0300949 if (status)
950 return;
951
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200952 switch (cp->enable) {
Andre Guedes76a388b2013-04-04 20:21:02 -0300953 case LE_SCAN_ENABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -0300954 set_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200955 break;
956
Andre Guedes76a388b2013-04-04 20:21:02 -0300957 case LE_SCAN_DISABLE:
Andre Guedesd23264a2011-11-25 20:53:38 -0300958 clear_bit(HCI_LE_SCAN, &hdev->dev_flags);
Andrei Emeltchenko68a8aea2011-12-19 16:14:18 +0200959 break;
960
961 default:
962 BT_ERR("Used reserved LE_Scan_Enable param %d", cp->enable);
963 break;
Andre Guedes35815082011-05-26 16:23:53 -0300964 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300965}
966
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200967static void hci_cc_le_read_white_list_size(struct hci_dev *hdev,
968 struct sk_buff *skb)
969{
970 struct hci_rp_le_read_white_list_size *rp = (void *) skb->data;
971
972 BT_DBG("%s status 0x%2.2x size %u", hdev->name, rp->status, rp->size);
973
974 if (!rp->status)
975 hdev->le_white_list_size = rp->size;
Johan Hedbergcf1d0812013-01-22 14:02:00 +0200976}
977
Johan Hedberg9b008c02013-01-22 14:02:01 +0200978static void hci_cc_le_read_supported_states(struct hci_dev *hdev,
979 struct sk_buff *skb)
980{
981 struct hci_rp_le_read_supported_states *rp = (void *) skb->data;
982
983 BT_DBG("%s status 0x%2.2x", hdev->name, rp->status);
984
985 if (!rp->status)
986 memcpy(hdev->le_states, rp->le_states, 8);
Johan Hedberg9b008c02013-01-22 14:02:01 +0200987}
988
Gustavo Padovan6039aa72012-05-23 04:04:18 -0300989static void hci_cc_write_le_host_supported(struct hci_dev *hdev,
990 struct sk_buff *skb)
Andre Guedesf9b49302011-06-30 19:20:53 -0300991{
Johan Hedberg06199cf2012-02-22 16:37:11 +0200992 struct hci_cp_write_le_host_supported *sent;
Andre Guedesf9b49302011-06-30 19:20:53 -0300993 __u8 status = *((__u8 *) skb->data);
994
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +0300995 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andre Guedesf9b49302011-06-30 19:20:53 -0300996
Johan Hedberg06199cf2012-02-22 16:37:11 +0200997 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED);
Johan Hedberg8f984df2012-02-28 01:07:22 +0200998 if (!sent)
Andre Guedesf9b49302011-06-30 19:20:53 -0300999 return;
1000
Johan Hedberg8f984df2012-02-28 01:07:22 +02001001 if (!status) {
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001002 if (sent->le) {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001003 hdev->features[1][0] |= LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001004 set_bit(HCI_LE_ENABLED, &hdev->dev_flags);
1005 } else {
Johan Hedbergcad718e2013-04-17 15:00:51 +03001006 hdev->features[1][0] &= ~LMP_HOST_LE;
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001007 clear_bit(HCI_LE_ENABLED, &hdev->dev_flags);
Johan Hedbergf3d3444a2013-10-05 12:01:04 +02001008 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
Johan Hedberg416a4ae2013-09-25 13:26:08 +03001009 }
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001010
1011 if (sent->simul)
Johan Hedbergcad718e2013-04-17 15:00:51 +03001012 hdev->features[1][0] |= LMP_HOST_LE_BREDR;
Johan Hedberg53b2caa2012-10-24 21:11:59 +03001013 else
Johan Hedbergcad718e2013-04-17 15:00:51 +03001014 hdev->features[1][0] &= ~LMP_HOST_LE_BREDR;
Johan Hedberg8f984df2012-02-28 01:07:22 +02001015 }
Andre Guedesf9b49302011-06-30 19:20:53 -03001016}
1017
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001018static void hci_cc_write_remote_amp_assoc(struct hci_dev *hdev,
1019 struct sk_buff *skb)
1020{
1021 struct hci_rp_write_remote_amp_assoc *rp = (void *) skb->data;
1022
1023 BT_DBG("%s status 0x%2.2x phy_handle 0x%2.2x",
1024 hdev->name, rp->status, rp->phy_handle);
1025
1026 if (rp->status)
1027 return;
1028
1029 amp_write_rem_assoc_continue(hdev, rp->phy_handle);
1030}
1031
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001032static void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001033{
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001034 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001035
1036 if (status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001037 hci_conn_check_pending(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001038 return;
1039 }
1040
Andre Guedes89352e72011-11-04 14:16:53 -03001041 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001042}
1043
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001044static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001046 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001047 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001048
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001049 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001050
1051 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052 if (!cp)
1053 return;
1054
1055 hci_dev_lock(hdev);
1056
1057 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1058
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001059 BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060
1061 if (status) {
1062 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001063 if (status != 0x0c || conn->attempt > 2) {
1064 conn->state = BT_CLOSED;
1065 hci_proto_connect_cfm(conn, status);
1066 hci_conn_del(conn);
1067 } else
1068 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069 }
1070 } else {
1071 if (!conn) {
1072 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1073 if (conn) {
Johan Hedberga0c808b2012-01-16 09:49:58 +02001074 conn->out = true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 conn->link_mode |= HCI_LM_MASTER;
1076 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001077 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001078 }
1079 }
1080
1081 hci_dev_unlock(hdev);
1082}
1083
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001084static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001086 struct hci_cp_add_sco *cp;
1087 struct hci_conn *acl, *sco;
1088 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001090 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001091
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001092 if (!status)
1093 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001095 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1096 if (!cp)
1097 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001099 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001101 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001102
1103 hci_dev_lock(hdev);
1104
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001105 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001106 if (acl) {
1107 sco = acl->link;
1108 if (sco) {
1109 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001110
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001111 hci_proto_connect_cfm(sco, status);
1112 hci_conn_del(sco);
1113 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001114 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001115
1116 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001117}
1118
Marcel Holtmannf8558552008-07-14 20:13:49 +02001119static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1120{
1121 struct hci_cp_auth_requested *cp;
1122 struct hci_conn *conn;
1123
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001124 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001125
1126 if (!status)
1127 return;
1128
1129 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1130 if (!cp)
1131 return;
1132
1133 hci_dev_lock(hdev);
1134
1135 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1136 if (conn) {
1137 if (conn->state == BT_CONFIG) {
1138 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001139 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001140 }
1141 }
1142
1143 hci_dev_unlock(hdev);
1144}
1145
1146static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1147{
1148 struct hci_cp_set_conn_encrypt *cp;
1149 struct hci_conn *conn;
1150
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001151 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001152
1153 if (!status)
1154 return;
1155
1156 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1157 if (!cp)
1158 return;
1159
1160 hci_dev_lock(hdev);
1161
1162 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1163 if (conn) {
1164 if (conn->state == BT_CONFIG) {
1165 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001166 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02001167 }
1168 }
1169
1170 hci_dev_unlock(hdev);
1171}
1172
Johan Hedberg127178d2010-11-18 22:22:29 +02001173static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001174 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001175{
Johan Hedberg392599b2010-11-18 22:22:28 +02001176 if (conn->state != BT_CONFIG || !conn->out)
1177 return 0;
1178
Johan Hedberg765c2a92011-01-19 12:06:52 +05301179 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001180 return 0;
1181
1182 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001183 * devices with sec_level HIGH or if MITM protection is requested */
Gustavo Padovan807deac2012-05-17 00:36:24 -03001184 if (!hci_conn_ssp_enabled(conn) && !(conn->auth_type & 0x01) &&
1185 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +02001186 return 0;
1187
Johan Hedberg392599b2010-11-18 22:22:28 +02001188 return 1;
1189}
1190
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001191static int hci_resolve_name(struct hci_dev *hdev,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001192 struct inquiry_entry *e)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001193{
1194 struct hci_cp_remote_name_req cp;
1195
1196 memset(&cp, 0, sizeof(cp));
1197
1198 bacpy(&cp.bdaddr, &e->data.bdaddr);
1199 cp.pscan_rep_mode = e->data.pscan_rep_mode;
1200 cp.pscan_mode = e->data.pscan_mode;
1201 cp.clock_offset = e->data.clock_offset;
1202
1203 return hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1204}
1205
Johan Hedbergb644ba32012-01-17 21:48:47 +02001206static bool hci_resolve_next_name(struct hci_dev *hdev)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001207{
1208 struct discovery_state *discov = &hdev->discovery;
1209 struct inquiry_entry *e;
1210
Johan Hedbergb644ba32012-01-17 21:48:47 +02001211 if (list_empty(&discov->resolve))
1212 return false;
1213
1214 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
Ram Malovanyc8100892012-07-19 10:26:09 +03001215 if (!e)
1216 return false;
1217
Johan Hedbergb644ba32012-01-17 21:48:47 +02001218 if (hci_resolve_name(hdev, e) == 0) {
1219 e->name_state = NAME_PENDING;
1220 return true;
1221 }
1222
1223 return false;
1224}
1225
1226static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001227 bdaddr_t *bdaddr, u8 *name, u8 name_len)
Johan Hedbergb644ba32012-01-17 21:48:47 +02001228{
1229 struct discovery_state *discov = &hdev->discovery;
1230 struct inquiry_entry *e;
1231
1232 if (conn && !test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001233 mgmt_device_connected(hdev, bdaddr, ACL_LINK, 0x00, 0, name,
1234 name_len, conn->dev_class);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001235
1236 if (discov->state == DISCOVERY_STOPPED)
1237 return;
1238
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001239 if (discov->state == DISCOVERY_STOPPING)
1240 goto discov_complete;
1241
1242 if (discov->state != DISCOVERY_RESOLVING)
1243 return;
1244
1245 e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING);
Ram Malovany7cc83802012-07-19 10:26:10 +03001246 /* If the device was not found in a list of found devices names of which
1247 * are pending. there is no need to continue resolving a next name as it
1248 * will be done upon receiving another Remote Name Request Complete
1249 * Event */
1250 if (!e)
1251 return;
1252
1253 list_del(&e->list);
1254 if (name) {
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001255 e->name_state = NAME_KNOWN;
Ram Malovany7cc83802012-07-19 10:26:10 +03001256 mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00,
1257 e->data.rssi, name, name_len);
Ram Malovanyc3e7c0d2012-07-19 10:26:11 +03001258 } else {
1259 e->name_state = NAME_NOT_KNOWN;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001260 }
1261
Johan Hedbergb644ba32012-01-17 21:48:47 +02001262 if (hci_resolve_next_name(hdev))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001263 return;
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001264
1265discov_complete:
1266 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1267}
1268
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001269static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1270{
Johan Hedberg127178d2010-11-18 22:22:29 +02001271 struct hci_cp_remote_name_req *cp;
1272 struct hci_conn *conn;
1273
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001274 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001275
1276 /* If successful wait for the name req complete event before
1277 * checking for the need to do authentication */
1278 if (!status)
1279 return;
1280
1281 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1282 if (!cp)
1283 return;
1284
1285 hci_dev_lock(hdev);
1286
1287 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001288
1289 if (test_bit(HCI_MGMT, &hdev->dev_flags))
1290 hci_check_pending_name(hdev, conn, &cp->bdaddr, NULL, 0);
1291
Johan Hedberg79c6c702011-04-28 11:28:55 -07001292 if (!conn)
1293 goto unlock;
1294
1295 if (!hci_outgoing_auth_needed(hdev, conn))
1296 goto unlock;
1297
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001298 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001299 struct hci_cp_auth_requested cp;
1300 cp.handle = __cpu_to_le16(conn->handle);
1301 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1302 }
1303
Johan Hedberg79c6c702011-04-28 11:28:55 -07001304unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001305 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001306}
1307
Marcel Holtmann769be972008-07-14 20:13:49 +02001308static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1309{
1310 struct hci_cp_read_remote_features *cp;
1311 struct hci_conn *conn;
1312
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001313 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001314
1315 if (!status)
1316 return;
1317
1318 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1319 if (!cp)
1320 return;
1321
1322 hci_dev_lock(hdev);
1323
1324 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1325 if (conn) {
1326 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001327 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001328 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001329 }
1330 }
1331
1332 hci_dev_unlock(hdev);
1333}
1334
1335static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1336{
1337 struct hci_cp_read_remote_ext_features *cp;
1338 struct hci_conn *conn;
1339
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001340 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmann769be972008-07-14 20:13:49 +02001341
1342 if (!status)
1343 return;
1344
1345 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1346 if (!cp)
1347 return;
1348
1349 hci_dev_lock(hdev);
1350
1351 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1352 if (conn) {
1353 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001354 hci_proto_connect_cfm(conn, status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001355 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001356 }
1357 }
1358
1359 hci_dev_unlock(hdev);
1360}
1361
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001362static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1363{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001364 struct hci_cp_setup_sync_conn *cp;
1365 struct hci_conn *acl, *sco;
1366 __u16 handle;
1367
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001368 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001369
1370 if (!status)
1371 return;
1372
1373 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1374 if (!cp)
1375 return;
1376
1377 handle = __le16_to_cpu(cp->handle);
1378
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001379 BT_DBG("%s handle 0x%4.4x", hdev->name, handle);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001380
1381 hci_dev_lock(hdev);
1382
1383 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001384 if (acl) {
1385 sco = acl->link;
1386 if (sco) {
1387 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001388
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001389 hci_proto_connect_cfm(sco, status);
1390 hci_conn_del(sco);
1391 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001392 }
1393
1394 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001395}
1396
1397static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1398{
1399 struct hci_cp_sniff_mode *cp;
1400 struct hci_conn *conn;
1401
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001402 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001403
1404 if (!status)
1405 return;
1406
1407 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1408 if (!cp)
1409 return;
1410
1411 hci_dev_lock(hdev);
1412
1413 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001414 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001415 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001416
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001417 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001418 hci_sco_setup(conn, status);
1419 }
1420
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001421 hci_dev_unlock(hdev);
1422}
1423
1424static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1425{
1426 struct hci_cp_exit_sniff_mode *cp;
1427 struct hci_conn *conn;
1428
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001429 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001430
1431 if (!status)
1432 return;
1433
1434 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1435 if (!cp)
1436 return;
1437
1438 hci_dev_lock(hdev);
1439
1440 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001441 if (conn) {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001442 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001443
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001444 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001445 hci_sco_setup(conn, status);
1446 }
1447
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001448 hci_dev_unlock(hdev);
1449}
1450
Johan Hedberg88c3df12012-02-09 14:27:38 +02001451static void hci_cs_disconnect(struct hci_dev *hdev, u8 status)
1452{
1453 struct hci_cp_disconnect *cp;
1454 struct hci_conn *conn;
1455
1456 if (!status)
1457 return;
1458
1459 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONNECT);
1460 if (!cp)
1461 return;
1462
1463 hci_dev_lock(hdev);
1464
1465 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1466 if (conn)
1467 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001468 conn->dst_type, status);
Johan Hedberg88c3df12012-02-09 14:27:38 +02001469
1470 hci_dev_unlock(hdev);
1471}
1472
Ville Tervofcd89c02011-02-10 22:38:47 -03001473static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1474{
Ville Tervofcd89c02011-02-10 22:38:47 -03001475 struct hci_conn *conn;
1476
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001477 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Ville Tervofcd89c02011-02-10 22:38:47 -03001478
Ville Tervofcd89c02011-02-10 22:38:47 -03001479 if (status) {
Andre Guedesf00a06a2012-07-27 15:10:13 -03001480 hci_dev_lock(hdev);
Ville Tervofcd89c02011-02-10 22:38:47 -03001481
Andre Guedes0c95ab72012-07-27 15:10:14 -03001482 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001483 if (!conn) {
1484 hci_dev_unlock(hdev);
1485 return;
1486 }
1487
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001488 BT_DBG("%s bdaddr %pMR conn %p", hdev->name, &conn->dst, conn);
Andre Guedesf00a06a2012-07-27 15:10:13 -03001489
1490 conn->state = BT_CLOSED;
Andre Guedes0c95ab72012-07-27 15:10:14 -03001491 mgmt_connect_failed(hdev, &conn->dst, conn->type,
Andre Guedesf00a06a2012-07-27 15:10:13 -03001492 conn->dst_type, status);
1493 hci_proto_connect_cfm(conn, status);
1494 hci_conn_del(conn);
1495
1496 hci_dev_unlock(hdev);
1497 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001498}
1499
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001500static void hci_cs_create_phylink(struct hci_dev *hdev, u8 status)
1501{
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001502 struct hci_cp_create_phy_link *cp;
1503
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001504 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001505
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03001506 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_PHY_LINK);
1507 if (!cp)
1508 return;
1509
Andrei Emeltchenkoe58917b2012-10-31 15:46:33 +02001510 hci_dev_lock(hdev);
1511
1512 if (status) {
1513 struct hci_conn *hcon;
1514
1515 hcon = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1516 if (hcon)
1517 hci_conn_del(hcon);
1518 } else {
1519 amp_write_remote_assoc(hdev, cp->phy_handle);
1520 }
1521
1522 hci_dev_unlock(hdev);
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03001523}
1524
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03001525static void hci_cs_accept_phylink(struct hci_dev *hdev, u8 status)
1526{
1527 struct hci_cp_accept_phy_link *cp;
1528
1529 BT_DBG("%s status 0x%2.2x", hdev->name, status);
1530
1531 if (status)
1532 return;
1533
1534 cp = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_PHY_LINK);
1535 if (!cp)
1536 return;
1537
1538 amp_write_remote_assoc(hdev, cp->phy_handle);
1539}
1540
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001541static void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001542{
1543 __u8 status = *((__u8 *) skb->data);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001544 struct discovery_state *discov = &hdev->discovery;
1545 struct inquiry_entry *e;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001546
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001547 BT_DBG("%s status 0x%2.2x", hdev->name, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001548
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001549 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001550
1551 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1552 return;
1553
Andre Guedes3e13fa12013-03-27 20:04:56 -03001554 smp_mb__after_clear_bit(); /* wake_up_bit advises about this barrier */
1555 wake_up_bit(&hdev->flags, HCI_INQUIRY);
1556
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02001557 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001558 return;
1559
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001560 hci_dev_lock(hdev);
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001561
Andre Guedes343f9352012-02-17 20:39:37 -03001562 if (discov->state != DISCOVERY_FINDING)
Johan Hedberg30dc78e2012-01-04 15:44:20 +02001563 goto unlock;
1564
1565 if (list_empty(&discov->resolve)) {
1566 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1567 goto unlock;
1568 }
1569
1570 e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED);
1571 if (e && hci_resolve_name(hdev, e) == 0) {
1572 e->name_state = NAME_PENDING;
1573 hci_discovery_set_state(hdev, DISCOVERY_RESOLVING);
1574 } else {
1575 hci_discovery_set_state(hdev, DISCOVERY_STOPPED);
1576 }
1577
1578unlock:
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001579 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001580}
1581
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001582static void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001584 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001585 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586 int num_rsp = *((__u8 *) skb->data);
1587
1588 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1589
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001590 if (!num_rsp)
1591 return;
1592
Andre Guedes1519cc12012-03-21 00:03:38 -03001593 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
1594 return;
1595
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001597
Johan Hedberge17acd42011-03-30 23:57:16 +03001598 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001599 bool name_known, ssp;
Johan Hedberg31754052012-01-04 13:39:52 +02001600
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601 bacpy(&data.bdaddr, &info->bdaddr);
1602 data.pscan_rep_mode = info->pscan_rep_mode;
1603 data.pscan_period_mode = info->pscan_period_mode;
1604 data.pscan_mode = info->pscan_mode;
1605 memcpy(data.dev_class, info->dev_class, 3);
1606 data.clock_offset = info->clock_offset;
1607 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001608 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02001609
Johan Hedberg388fc8f2012-02-23 00:38:59 +02001610 name_known = hci_inquiry_cache_update(hdev, &data, false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02001611 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001612 info->dev_class, 0, !name_known, ssp, NULL,
1613 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001615
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616 hci_dev_unlock(hdev);
1617}
1618
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001619static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001620{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001621 struct hci_ev_conn_complete *ev = (void *) skb->data;
1622 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001624 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001625
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001627
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001628 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001629 if (!conn) {
1630 if (ev->link_type != SCO_LINK)
1631 goto unlock;
1632
1633 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1634 if (!conn)
1635 goto unlock;
1636
1637 conn->type = SCO_LINK;
1638 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001639
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001640 if (!ev->status) {
1641 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001642
1643 if (conn->type == ACL_LINK) {
1644 conn->state = BT_CONFIG;
1645 hci_conn_hold(conn);
Szymon Janca9ea3ed2012-07-19 14:46:08 +02001646
1647 if (!conn->out && !hci_conn_ssp_enabled(conn) &&
1648 !hci_find_link_key(hdev, &ev->bdaddr))
1649 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1650 else
1651 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +02001652 } else
1653 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001654
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001655 hci_conn_add_sysfs(conn);
1656
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001657 if (test_bit(HCI_AUTH, &hdev->flags))
1658 conn->link_mode |= HCI_LM_AUTH;
1659
1660 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1661 conn->link_mode |= HCI_LM_ENCRYPT;
1662
1663 /* Get remote features */
1664 if (conn->type == ACL_LINK) {
1665 struct hci_cp_read_remote_features cp;
1666 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001667 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001668 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001669 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001670
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001671 /* Set packet type for incoming connection */
Andrei Emeltchenkod095c1e2011-12-01 14:33:27 +02001672 if (!conn->out && hdev->hci_ver < BLUETOOTH_VER_2_0) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001673 struct hci_cp_change_conn_ptype cp;
1674 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001675 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001676 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE, sizeof(cp),
1677 &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001678 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001679 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001680 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001681 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001682 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001683 conn->dst_type, ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001684 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001685
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001686 if (conn->type == ACL_LINK)
1687 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001688
Marcel Holtmann769be972008-07-14 20:13:49 +02001689 if (ev->status) {
1690 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001691 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001692 } else if (ev->link_type != ACL_LINK)
1693 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001694
1695unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001696 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001697
1698 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001699}
1700
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001701static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001702{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001703 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 int mask = hdev->link_mode;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001705 __u8 flags = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001706
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03001707 BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001708 ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001710 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type,
1711 &flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001712
Szymon Janc138d22e2011-02-17 16:44:23 +01001713 if ((mask & HCI_LM_ACCEPT) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001714 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001715 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001716 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001717 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001718
1719 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001720
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001721 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1722 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001723 memcpy(ie->data.dev_class, ev->dev_class, 3);
1724
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03001725 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type,
1726 &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001727 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001728 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1729 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001730 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001731 hci_dev_unlock(hdev);
1732 return;
1733 }
1734 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001735
Linus Torvalds1da177e2005-04-16 15:20:36 -07001736 memcpy(conn->dev_class, ev->dev_class, 3);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001737
Linus Torvalds1da177e2005-04-16 15:20:36 -07001738 hci_dev_unlock(hdev);
1739
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001740 if (ev->link_type == ACL_LINK ||
1741 (!(flags & HCI_PROTO_DEFER) && !lmp_esco_capable(hdev))) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001742 struct hci_cp_accept_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001743 conn->state = BT_CONNECT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001744
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001745 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001746
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001747 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1748 cp.role = 0x00; /* Become master */
1749 else
1750 cp.role = 0x01; /* Remain slave */
1751
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001752 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ, sizeof(cp),
1753 &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001754 } else if (!(flags & HCI_PROTO_DEFER)) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001755 struct hci_cp_accept_sync_conn_req cp;
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001756 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001757
1758 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001759 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001760
Andrei Emeltchenko82781e62012-05-25 11:38:27 +03001761 cp.tx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1762 cp.rx_bandwidth = __constant_cpu_to_le32(0x00001f40);
1763 cp.max_latency = __constant_cpu_to_le16(0xffff);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001764 cp.content_format = cpu_to_le16(hdev->voice_setting);
1765 cp.retrans_effort = 0xff;
1766
1767 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001768 sizeof(cp), &cp);
Frédéric Dalleau20714bf2012-11-21 10:51:12 +01001769 } else {
1770 conn->state = BT_CONNECT2;
1771 hci_proto_connect_cfm(conn, 0);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001772 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001773 } else {
1774 /* Connection rejected */
1775 struct hci_cp_reject_conn_req cp;
1776
1777 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001778 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001779 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001780 }
1781}
1782
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001783static u8 hci_to_mgmt_reason(u8 err)
1784{
1785 switch (err) {
1786 case HCI_ERROR_CONNECTION_TIMEOUT:
1787 return MGMT_DEV_DISCONN_TIMEOUT;
1788 case HCI_ERROR_REMOTE_USER_TERM:
1789 case HCI_ERROR_REMOTE_LOW_RESOURCES:
1790 case HCI_ERROR_REMOTE_POWER_OFF:
1791 return MGMT_DEV_DISCONN_REMOTE;
1792 case HCI_ERROR_LOCAL_HOST_TERM:
1793 return MGMT_DEV_DISCONN_LOCAL_HOST;
1794 default:
1795 return MGMT_DEV_DISCONN_UNKNOWN;
1796 }
1797}
1798
Johan Hedberg22102462013-10-05 12:01:06 +02001799static void adv_enable_complete(struct hci_dev *hdev, u8 status)
1800{
1801 BT_DBG("%s status %u", hdev->name, status);
1802
1803 /* Clear the advertising mgmt setting if we failed to re-enable it */
1804 if (status) {
1805 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
1806 mgmt_new_settings(hdev);
1807 }
1808}
1809
1810static void reenable_advertising(struct hci_dev *hdev)
1811{
1812 struct hci_request req;
1813 u8 enable = 0x01;
1814
1815 if (hdev->conn_hash.le_num)
1816 return;
1817
1818 if (!test_bit(HCI_ADVERTISING, &hdev->dev_flags))
1819 return;
1820
1821 hci_req_init(&req, hdev);
1822 hci_req_add(&req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
1823
1824 /* If this fails we have no option but to let user space know
1825 * that we've disabled advertising.
1826 */
1827 if (hci_req_run(&req, adv_enable_complete) < 0) {
1828 clear_bit(HCI_ADVERTISING, &hdev->dev_flags);
1829 mgmt_new_settings(hdev);
1830 }
1831}
1832
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001833static void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001834{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001835 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001836 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001837
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001838 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001839
Linus Torvalds1da177e2005-04-16 15:20:36 -07001840 hci_dev_lock(hdev);
1841
Marcel Holtmann04837f62006-07-03 10:02:33 +02001842 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001843 if (!conn)
1844 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001845
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001846 if (ev->status == 0)
1847 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001848
Johan Hedbergb644ba32012-01-17 21:48:47 +02001849 if (test_and_clear_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001850 (conn->type == ACL_LINK || conn->type == LE_LINK)) {
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001851 if (ev->status) {
Johan Hedberg88c3df12012-02-09 14:27:38 +02001852 mgmt_disconnect_failed(hdev, &conn->dst, conn->type,
Gustavo Padovan807deac2012-05-17 00:36:24 -03001853 conn->dst_type, ev->status);
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001854 } else {
1855 u8 reason = hci_to_mgmt_reason(ev->reason);
1856
Johan Hedbergafc747a2012-01-15 18:11:07 +02001857 mgmt_device_disconnected(hdev, &conn->dst, conn->type,
Mikel Astizf0d6a0e2012-08-09 09:52:30 +02001858 conn->dst_type, reason);
1859 }
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001860 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001861
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001862 if (ev->status == 0) {
Johan Hedberg22102462013-10-05 12:01:06 +02001863 u8 type = conn->type;
1864
1865 if (type == ACL_LINK && conn->flush_key)
Vishal Agarwal6ec5bca2012-04-16 14:44:44 +05301866 hci_remove_link_key(hdev, &conn->dst);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001867 hci_proto_disconn_cfm(conn, ev->reason);
1868 hci_conn_del(conn);
Johan Hedberg22102462013-10-05 12:01:06 +02001869
1870 /* Re-enable advertising if necessary, since it might
1871 * have been disabled by the connection. From the
1872 * HCI_LE_Set_Advertise_Enable command description in
1873 * the core specification (v4.0):
1874 * "The Controller shall continue advertising until the Host
1875 * issues an LE_Set_Advertise_Enable command with
1876 * Advertising_Enable set to 0x00 (Advertising is disabled)
1877 * or until a connection is created or until the Advertising
1878 * is timed out due to Directed Advertising."
1879 */
1880 if (type == LE_LINK)
1881 reenable_advertising(hdev);
Johan Hedberg37d9ef72011-11-10 15:54:39 +02001882 }
Johan Hedbergf7520542011-01-20 12:34:39 +02001883
1884unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001885 hci_dev_unlock(hdev);
1886}
1887
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001888static void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001889{
1890 struct hci_ev_auth_complete *ev = (void *) skb->data;
1891 struct hci_conn *conn;
1892
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001893 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001894
1895 hci_dev_lock(hdev);
1896
1897 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001898 if (!conn)
1899 goto unlock;
1900
1901 if (!ev->status) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001902 if (!hci_conn_ssp_enabled(conn) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03001903 test_bit(HCI_CONN_REAUTH_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001904 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001905 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001906 conn->link_mode |= HCI_LM_AUTH;
1907 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001908 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001909 } else {
Johan Hedbergbab73cb2012-02-09 16:07:29 +02001910 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001911 ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001912 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001913
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001914 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
1915 clear_bit(HCI_CONN_REAUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001916
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001917 if (conn->state == BT_CONFIG) {
Johan Hedbergaa64a8b2012-01-18 21:33:12 +02001918 if (!ev->status && hci_conn_ssp_enabled(conn)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001919 struct hci_cp_set_conn_encrypt cp;
1920 cp.handle = ev->handle;
1921 cp.encrypt = 0x01;
1922 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001923 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001924 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001925 conn->state = BT_CONNECTED;
1926 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02001927 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001928 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001929 } else {
1930 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001931
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001932 hci_conn_hold(conn);
1933 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02001934 hci_conn_drop(conn);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001935 }
1936
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001937 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags)) {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001938 if (!ev->status) {
1939 struct hci_cp_set_conn_encrypt cp;
1940 cp.handle = ev->handle;
1941 cp.encrypt = 0x01;
1942 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03001943 &cp);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001944 } else {
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001945 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001946 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001947 }
1948 }
1949
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001950unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001951 hci_dev_unlock(hdev);
1952}
1953
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001954static void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001955{
Johan Hedberg127178d2010-11-18 22:22:29 +02001956 struct hci_ev_remote_name *ev = (void *) skb->data;
1957 struct hci_conn *conn;
1958
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001959 BT_DBG("%s", hdev->name);
1960
1961 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001962
1963 hci_dev_lock(hdev);
1964
1965 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedbergb644ba32012-01-17 21:48:47 +02001966
1967 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
1968 goto check_auth;
1969
1970 if (ev->status == 0)
1971 hci_check_pending_name(hdev, conn, &ev->bdaddr, ev->name,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03001972 strnlen(ev->name, HCI_MAX_NAME_LENGTH));
Johan Hedbergb644ba32012-01-17 21:48:47 +02001973 else
1974 hci_check_pending_name(hdev, conn, &ev->bdaddr, NULL, 0);
1975
1976check_auth:
Johan Hedberg79c6c702011-04-28 11:28:55 -07001977 if (!conn)
1978 goto unlock;
1979
1980 if (!hci_outgoing_auth_needed(hdev, conn))
1981 goto unlock;
1982
Johan Hedberg51a8efd2012-01-16 06:10:31 +02001983 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001984 struct hci_cp_auth_requested cp;
1985 cp.handle = __cpu_to_le16(conn->handle);
1986 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1987 }
1988
Johan Hedberg79c6c702011-04-28 11:28:55 -07001989unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001990 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001991}
1992
Gustavo Padovan6039aa72012-05-23 04:04:18 -03001993static void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001994{
1995 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1996 struct hci_conn *conn;
1997
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03001998 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001999
2000 hci_dev_lock(hdev);
2001
2002 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2003 if (conn) {
2004 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02002005 if (ev->encrypt) {
2006 /* Encryption implies authentication */
2007 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002008 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03002009 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02002010 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002011 conn->link_mode &= ~HCI_LM_ENCRYPT;
2012 }
2013
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002014 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002015
Gustavo Padovana7d77232012-05-13 03:20:07 -03002016 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03002017 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02002018 hci_conn_drop(conn);
Gustavo Padovana7d77232012-05-13 03:20:07 -03002019 goto unlock;
2020 }
2021
Marcel Holtmannf8558552008-07-14 20:13:49 +02002022 if (conn->state == BT_CONFIG) {
2023 if (!ev->status)
2024 conn->state = BT_CONNECTED;
2025
2026 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002027 hci_conn_drop(conn);
Marcel Holtmannf8558552008-07-14 20:13:49 +02002028 } else
2029 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002030 }
2031
Gustavo Padovana7d77232012-05-13 03:20:07 -03002032unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002033 hci_dev_unlock(hdev);
2034}
2035
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002036static void hci_change_link_key_complete_evt(struct hci_dev *hdev,
2037 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002038{
2039 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
2040 struct hci_conn *conn;
2041
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002042 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002043
2044 hci_dev_lock(hdev);
2045
2046 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2047 if (conn) {
2048 if (!ev->status)
2049 conn->link_mode |= HCI_LM_SECURE;
2050
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002051 clear_bit(HCI_CONN_AUTH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002052
2053 hci_key_change_cfm(conn, ev->status);
2054 }
2055
2056 hci_dev_unlock(hdev);
2057}
2058
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002059static void hci_remote_features_evt(struct hci_dev *hdev,
2060 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002061{
2062 struct hci_ev_remote_features *ev = (void *) skb->data;
2063 struct hci_conn *conn;
2064
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002065 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002066
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002067 hci_dev_lock(hdev);
2068
2069 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002070 if (!conn)
2071 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02002072
Johan Hedbergccd556f2010-11-10 17:11:51 +02002073 if (!ev->status)
Johan Hedbergcad718e2013-04-17 15:00:51 +03002074 memcpy(conn->features[0], ev->features, 8);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002075
2076 if (conn->state != BT_CONFIG)
2077 goto unlock;
2078
2079 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
2080 struct hci_cp_read_remote_ext_features cp;
2081 cp.handle = ev->handle;
2082 cp.page = 0x01;
2083 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002084 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02002085 goto unlock;
2086 }
2087
Johan Hedberg671267b2012-05-12 16:11:50 -03002088 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002089 struct hci_cp_remote_name_req cp;
2090 memset(&cp, 0, sizeof(cp));
2091 bacpy(&cp.bdaddr, &conn->dst);
2092 cp.pscan_rep_mode = 0x02;
2093 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002094 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2095 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002096 conn->dst_type, 0, NULL, 0,
2097 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002098
Johan Hedberg127178d2010-11-18 22:22:29 +02002099 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002100 conn->state = BT_CONNECTED;
2101 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002102 hci_conn_drop(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02002103 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002104
Johan Hedbergccd556f2010-11-10 17:11:51 +02002105unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002106 hci_dev_unlock(hdev);
2107}
2108
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002109static void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002110{
2111 struct hci_ev_cmd_complete *ev = (void *) skb->data;
Johan Hedberg9238f362013-03-05 20:37:48 +02002112 u8 status = skb->data[sizeof(*ev)];
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002113 __u16 opcode;
2114
2115 skb_pull(skb, sizeof(*ev));
2116
2117 opcode = __le16_to_cpu(ev->opcode);
2118
2119 switch (opcode) {
2120 case HCI_OP_INQUIRY_CANCEL:
2121 hci_cc_inquiry_cancel(hdev, skb);
2122 break;
2123
Andre Guedes4d934832012-03-21 00:03:35 -03002124 case HCI_OP_PERIODIC_INQ:
2125 hci_cc_periodic_inq(hdev, skb);
2126 break;
2127
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002128 case HCI_OP_EXIT_PERIODIC_INQ:
2129 hci_cc_exit_periodic_inq(hdev, skb);
2130 break;
2131
2132 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
2133 hci_cc_remote_name_req_cancel(hdev, skb);
2134 break;
2135
2136 case HCI_OP_ROLE_DISCOVERY:
2137 hci_cc_role_discovery(hdev, skb);
2138 break;
2139
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002140 case HCI_OP_READ_LINK_POLICY:
2141 hci_cc_read_link_policy(hdev, skb);
2142 break;
2143
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002144 case HCI_OP_WRITE_LINK_POLICY:
2145 hci_cc_write_link_policy(hdev, skb);
2146 break;
2147
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02002148 case HCI_OP_READ_DEF_LINK_POLICY:
2149 hci_cc_read_def_link_policy(hdev, skb);
2150 break;
2151
2152 case HCI_OP_WRITE_DEF_LINK_POLICY:
2153 hci_cc_write_def_link_policy(hdev, skb);
2154 break;
2155
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002156 case HCI_OP_RESET:
2157 hci_cc_reset(hdev, skb);
2158 break;
2159
2160 case HCI_OP_WRITE_LOCAL_NAME:
2161 hci_cc_write_local_name(hdev, skb);
2162 break;
2163
2164 case HCI_OP_READ_LOCAL_NAME:
2165 hci_cc_read_local_name(hdev, skb);
2166 break;
2167
2168 case HCI_OP_WRITE_AUTH_ENABLE:
2169 hci_cc_write_auth_enable(hdev, skb);
2170 break;
2171
2172 case HCI_OP_WRITE_ENCRYPT_MODE:
2173 hci_cc_write_encrypt_mode(hdev, skb);
2174 break;
2175
2176 case HCI_OP_WRITE_SCAN_ENABLE:
2177 hci_cc_write_scan_enable(hdev, skb);
2178 break;
2179
2180 case HCI_OP_READ_CLASS_OF_DEV:
2181 hci_cc_read_class_of_dev(hdev, skb);
2182 break;
2183
2184 case HCI_OP_WRITE_CLASS_OF_DEV:
2185 hci_cc_write_class_of_dev(hdev, skb);
2186 break;
2187
2188 case HCI_OP_READ_VOICE_SETTING:
2189 hci_cc_read_voice_setting(hdev, skb);
2190 break;
2191
2192 case HCI_OP_WRITE_VOICE_SETTING:
2193 hci_cc_write_voice_setting(hdev, skb);
2194 break;
2195
Marcel Holtmann333140b2008-07-14 20:13:48 +02002196 case HCI_OP_WRITE_SSP_MODE:
2197 hci_cc_write_ssp_mode(hdev, skb);
2198 break;
2199
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002200 case HCI_OP_READ_LOCAL_VERSION:
2201 hci_cc_read_local_version(hdev, skb);
2202 break;
2203
2204 case HCI_OP_READ_LOCAL_COMMANDS:
2205 hci_cc_read_local_commands(hdev, skb);
2206 break;
2207
2208 case HCI_OP_READ_LOCAL_FEATURES:
2209 hci_cc_read_local_features(hdev, skb);
2210 break;
2211
Andre Guedes971e3a42011-06-30 19:20:52 -03002212 case HCI_OP_READ_LOCAL_EXT_FEATURES:
2213 hci_cc_read_local_ext_features(hdev, skb);
2214 break;
2215
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002216 case HCI_OP_READ_BUFFER_SIZE:
2217 hci_cc_read_buffer_size(hdev, skb);
2218 break;
2219
2220 case HCI_OP_READ_BD_ADDR:
2221 hci_cc_read_bd_addr(hdev, skb);
2222 break;
2223
Johan Hedbergf332ec62013-03-15 17:07:11 -05002224 case HCI_OP_READ_PAGE_SCAN_ACTIVITY:
2225 hci_cc_read_page_scan_activity(hdev, skb);
2226 break;
2227
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002228 case HCI_OP_WRITE_PAGE_SCAN_ACTIVITY:
2229 hci_cc_write_page_scan_activity(hdev, skb);
2230 break;
2231
Johan Hedbergf332ec62013-03-15 17:07:11 -05002232 case HCI_OP_READ_PAGE_SCAN_TYPE:
2233 hci_cc_read_page_scan_type(hdev, skb);
2234 break;
2235
Johan Hedberg4a3ee762013-03-15 17:07:12 -05002236 case HCI_OP_WRITE_PAGE_SCAN_TYPE:
2237 hci_cc_write_page_scan_type(hdev, skb);
2238 break;
2239
Andrei Emeltchenko350ee4c2011-12-07 15:56:51 +02002240 case HCI_OP_READ_DATA_BLOCK_SIZE:
2241 hci_cc_read_data_block_size(hdev, skb);
2242 break;
2243
Andrei Emeltchenko1e89cff2011-11-24 14:52:02 +02002244 case HCI_OP_READ_FLOW_CONTROL_MODE:
2245 hci_cc_read_flow_control_mode(hdev, skb);
2246 break;
2247
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03002248 case HCI_OP_READ_LOCAL_AMP_INFO:
2249 hci_cc_read_local_amp_info(hdev, skb);
2250 break;
2251
Andrei Emeltchenko903e4542012-09-27 17:26:09 +03002252 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2253 hci_cc_read_local_amp_assoc(hdev, skb);
2254 break;
2255
Johan Hedbergd5859e22011-01-25 01:19:58 +02002256 case HCI_OP_READ_INQ_RSP_TX_POWER:
2257 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2258 break;
2259
Johan Hedberg980e1a52011-01-22 06:10:07 +02002260 case HCI_OP_PIN_CODE_REPLY:
2261 hci_cc_pin_code_reply(hdev, skb);
2262 break;
2263
2264 case HCI_OP_PIN_CODE_NEG_REPLY:
2265 hci_cc_pin_code_neg_reply(hdev, skb);
2266 break;
2267
Szymon Jancc35938b2011-03-22 13:12:21 +01002268 case HCI_OP_READ_LOCAL_OOB_DATA:
2269 hci_cc_read_local_oob_data_reply(hdev, skb);
2270 break;
2271
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002272 case HCI_OP_LE_READ_BUFFER_SIZE:
2273 hci_cc_le_read_buffer_size(hdev, skb);
2274 break;
2275
Johan Hedberg60e77322013-01-22 14:01:59 +02002276 case HCI_OP_LE_READ_LOCAL_FEATURES:
2277 hci_cc_le_read_local_features(hdev, skb);
2278 break;
2279
Johan Hedberg8fa19092012-10-19 20:57:49 +03002280 case HCI_OP_LE_READ_ADV_TX_POWER:
2281 hci_cc_le_read_adv_tx_power(hdev, skb);
2282 break;
2283
Johan Hedberga5c29682011-02-19 12:05:57 -03002284 case HCI_OP_USER_CONFIRM_REPLY:
2285 hci_cc_user_confirm_reply(hdev, skb);
2286 break;
2287
2288 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2289 hci_cc_user_confirm_neg_reply(hdev, skb);
2290 break;
2291
Brian Gix1143d452011-11-23 08:28:34 -08002292 case HCI_OP_USER_PASSKEY_REPLY:
2293 hci_cc_user_passkey_reply(hdev, skb);
2294 break;
2295
2296 case HCI_OP_USER_PASSKEY_NEG_REPLY:
2297 hci_cc_user_passkey_neg_reply(hdev, skb);
Szymon Janc16cde992012-04-13 12:32:42 +02002298 break;
Andre Guedes07f7fa52011-12-02 21:13:31 +09002299
Johan Hedbergc1d5dc42012-11-08 01:23:01 +01002300 case HCI_OP_LE_SET_ADV_ENABLE:
2301 hci_cc_le_set_adv_enable(hdev, skb);
2302 break;
2303
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002304 case HCI_OP_LE_SET_SCAN_ENABLE:
2305 hci_cc_le_set_scan_enable(hdev, skb);
2306 break;
2307
Johan Hedbergcf1d0812013-01-22 14:02:00 +02002308 case HCI_OP_LE_READ_WHITE_LIST_SIZE:
2309 hci_cc_le_read_white_list_size(hdev, skb);
2310 break;
2311
Johan Hedberg9b008c02013-01-22 14:02:01 +02002312 case HCI_OP_LE_READ_SUPPORTED_STATES:
2313 hci_cc_le_read_supported_states(hdev, skb);
2314 break;
2315
Andre Guedesf9b49302011-06-30 19:20:53 -03002316 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2317 hci_cc_write_le_host_supported(hdev, skb);
2318 break;
2319
Andrei Emeltchenko93c284e2012-09-27 17:26:20 +03002320 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2321 hci_cc_write_remote_amp_assoc(hdev, skb);
2322 break;
2323
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002324 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002325 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002326 break;
2327 }
2328
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002329 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002330 del_timer(&hdev->cmd_timer);
2331
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002332 hci_req_cmd_complete(hdev, opcode, status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002333
Szymon Jancdbccd792012-12-11 08:51:19 +01002334 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002335 atomic_set(&hdev->cmd_cnt, 1);
2336 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002337 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002338 }
2339}
2340
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002341static void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002342{
2343 struct hci_ev_cmd_status *ev = (void *) skb->data;
2344 __u16 opcode;
2345
2346 skb_pull(skb, sizeof(*ev));
2347
2348 opcode = __le16_to_cpu(ev->opcode);
2349
2350 switch (opcode) {
2351 case HCI_OP_INQUIRY:
2352 hci_cs_inquiry(hdev, ev->status);
2353 break;
2354
2355 case HCI_OP_CREATE_CONN:
2356 hci_cs_create_conn(hdev, ev->status);
2357 break;
2358
2359 case HCI_OP_ADD_SCO:
2360 hci_cs_add_sco(hdev, ev->status);
2361 break;
2362
Marcel Holtmannf8558552008-07-14 20:13:49 +02002363 case HCI_OP_AUTH_REQUESTED:
2364 hci_cs_auth_requested(hdev, ev->status);
2365 break;
2366
2367 case HCI_OP_SET_CONN_ENCRYPT:
2368 hci_cs_set_conn_encrypt(hdev, ev->status);
2369 break;
2370
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002371 case HCI_OP_REMOTE_NAME_REQ:
2372 hci_cs_remote_name_req(hdev, ev->status);
2373 break;
2374
Marcel Holtmann769be972008-07-14 20:13:49 +02002375 case HCI_OP_READ_REMOTE_FEATURES:
2376 hci_cs_read_remote_features(hdev, ev->status);
2377 break;
2378
2379 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2380 hci_cs_read_remote_ext_features(hdev, ev->status);
2381 break;
2382
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002383 case HCI_OP_SETUP_SYNC_CONN:
2384 hci_cs_setup_sync_conn(hdev, ev->status);
2385 break;
2386
2387 case HCI_OP_SNIFF_MODE:
2388 hci_cs_sniff_mode(hdev, ev->status);
2389 break;
2390
2391 case HCI_OP_EXIT_SNIFF_MODE:
2392 hci_cs_exit_sniff_mode(hdev, ev->status);
2393 break;
2394
Johan Hedberg8962ee72011-01-20 12:40:27 +02002395 case HCI_OP_DISCONNECT:
Johan Hedberg88c3df12012-02-09 14:27:38 +02002396 hci_cs_disconnect(hdev, ev->status);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002397 break;
2398
Ville Tervofcd89c02011-02-10 22:38:47 -03002399 case HCI_OP_LE_CREATE_CONN:
2400 hci_cs_le_create_conn(hdev, ev->status);
2401 break;
2402
Andrei Emeltchenkoa02226d2012-09-27 17:26:19 +03002403 case HCI_OP_CREATE_PHY_LINK:
2404 hci_cs_create_phylink(hdev, ev->status);
2405 break;
2406
Andrei Emeltchenko0b26ab92012-09-27 17:26:24 +03002407 case HCI_OP_ACCEPT_PHY_LINK:
2408 hci_cs_accept_phylink(hdev, ev->status);
2409 break;
2410
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002411 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002412 BT_DBG("%s opcode 0x%4.4x", hdev->name, opcode);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002413 break;
2414 }
2415
Johan Hedbergad82cdd2013-03-09 09:53:50 +02002416 if (opcode != HCI_OP_NOP)
Ville Tervo6bd32322011-02-16 16:32:41 +02002417 del_timer(&hdev->cmd_timer);
2418
Johan Hedberg02350a72013-04-03 21:50:29 +03002419 if (ev->status ||
2420 (hdev->sent_cmd && !bt_cb(hdev->sent_cmd)->req.event))
2421 hci_req_cmd_complete(hdev, opcode, ev->status);
Johan Hedberg9238f362013-03-05 20:37:48 +02002422
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002423 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002424 atomic_set(&hdev->cmd_cnt, 1);
2425 if (!skb_queue_empty(&hdev->cmd_q))
Gustavo F. Padovanc347b762011-12-14 23:53:47 -02002426 queue_work(hdev->workqueue, &hdev->cmd_work);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002427 }
2428}
2429
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002430static void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002431{
2432 struct hci_ev_role_change *ev = (void *) skb->data;
2433 struct hci_conn *conn;
2434
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002435 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002436
2437 hci_dev_lock(hdev);
2438
2439 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2440 if (conn) {
2441 if (!ev->status) {
2442 if (ev->role)
2443 conn->link_mode &= ~HCI_LM_MASTER;
2444 else
2445 conn->link_mode |= HCI_LM_MASTER;
2446 }
2447
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002448 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002449
2450 hci_role_switch_cfm(conn, ev->status, ev->role);
2451 }
2452
2453 hci_dev_unlock(hdev);
2454}
2455
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002456static void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002457{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002458 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002459 int i;
2460
Andrei Emeltchenko32ac5b92011-12-19 16:31:29 +02002461 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_PACKET_BASED) {
2462 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2463 return;
2464 }
2465
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002466 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002467 ev->num_hndl * sizeof(struct hci_comp_pkts_info)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002468 BT_DBG("%s bad parameters", hdev->name);
2469 return;
2470 }
2471
Andrei Emeltchenkoc5993de2011-12-30 12:07:47 +02002472 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2473
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002474 for (i = 0; i < ev->num_hndl; i++) {
2475 struct hci_comp_pkts_info *info = &ev->handles[i];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002476 struct hci_conn *conn;
2477 __u16 handle, count;
2478
Andrei Emeltchenko613a1c02011-12-19 16:31:30 +02002479 handle = __le16_to_cpu(info->handle);
2480 count = __le16_to_cpu(info->count);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002481
2482 conn = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002483 if (!conn)
2484 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002485
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002486 conn->sent -= count;
2487
2488 switch (conn->type) {
2489 case ACL_LINK:
2490 hdev->acl_cnt += count;
2491 if (hdev->acl_cnt > hdev->acl_pkts)
2492 hdev->acl_cnt = hdev->acl_pkts;
2493 break;
2494
2495 case LE_LINK:
2496 if (hdev->le_pkts) {
2497 hdev->le_cnt += count;
2498 if (hdev->le_cnt > hdev->le_pkts)
2499 hdev->le_cnt = hdev->le_pkts;
2500 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002501 hdev->acl_cnt += count;
2502 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002503 hdev->acl_cnt = hdev->acl_pkts;
2504 }
Andrei Emeltchenkof4280912011-12-07 15:56:52 +02002505 break;
2506
2507 case SCO_LINK:
2508 hdev->sco_cnt += count;
2509 if (hdev->sco_cnt > hdev->sco_pkts)
2510 hdev->sco_cnt = hdev->sco_pkts;
2511 break;
2512
2513 default:
2514 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2515 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002516 }
2517 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002518
Gustavo F. Padovan3eff45e2011-12-15 00:50:02 -02002519 queue_work(hdev->workqueue, &hdev->tx_work);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002520}
2521
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002522static struct hci_conn *__hci_conn_lookup_handle(struct hci_dev *hdev,
2523 __u16 handle)
2524{
2525 struct hci_chan *chan;
2526
2527 switch (hdev->dev_type) {
2528 case HCI_BREDR:
2529 return hci_conn_hash_lookup_handle(hdev, handle);
2530 case HCI_AMP:
2531 chan = hci_chan_lookup_handle(hdev, handle);
2532 if (chan)
2533 return chan->conn;
2534 break;
2535 default:
2536 BT_ERR("%s unknown dev_type %d", hdev->name, hdev->dev_type);
2537 break;
2538 }
2539
2540 return NULL;
2541}
2542
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002543static void hci_num_comp_blocks_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002544{
2545 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2546 int i;
2547
2548 if (hdev->flow_ctl_mode != HCI_FLOW_CTL_MODE_BLOCK_BASED) {
2549 BT_ERR("Wrong event for mode %d", hdev->flow_ctl_mode);
2550 return;
2551 }
2552
2553 if (skb->len < sizeof(*ev) || skb->len < sizeof(*ev) +
Gustavo Padovan807deac2012-05-17 00:36:24 -03002554 ev->num_hndl * sizeof(struct hci_comp_blocks_info)) {
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002555 BT_DBG("%s bad parameters", hdev->name);
2556 return;
2557 }
2558
2559 BT_DBG("%s num_blocks %d num_hndl %d", hdev->name, ev->num_blocks,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002560 ev->num_hndl);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002561
2562 for (i = 0; i < ev->num_hndl; i++) {
2563 struct hci_comp_blocks_info *info = &ev->handles[i];
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002564 struct hci_conn *conn = NULL;
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002565 __u16 handle, block_count;
2566
2567 handle = __le16_to_cpu(info->handle);
2568 block_count = __le16_to_cpu(info->blocks);
2569
Andrei Emeltchenko76ef7cf2012-10-10 17:38:29 +03002570 conn = __hci_conn_lookup_handle(hdev, handle);
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002571 if (!conn)
2572 continue;
2573
2574 conn->sent -= block_count;
2575
2576 switch (conn->type) {
2577 case ACL_LINK:
Andrei Emeltchenkobd1eb662012-10-10 17:38:30 +03002578 case AMP_LINK:
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02002579 hdev->block_cnt += block_count;
2580 if (hdev->block_cnt > hdev->num_blocks)
2581 hdev->block_cnt = hdev->num_blocks;
2582 break;
2583
2584 default:
2585 BT_ERR("Unknown type %d conn %p", conn->type, conn);
2586 break;
2587 }
2588 }
2589
2590 queue_work(hdev->workqueue, &hdev->tx_work);
2591}
2592
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002593static void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002594{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002595 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002596 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002597
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002598 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002599
2600 hci_dev_lock(hdev);
2601
Marcel Holtmann04837f62006-07-03 10:02:33 +02002602 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2603 if (conn) {
2604 conn->mode = ev->mode;
2605 conn->interval = __le16_to_cpu(ev->interval);
2606
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002607 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND,
2608 &conn->flags)) {
Marcel Holtmann04837f62006-07-03 10:02:33 +02002609 if (conn->mode == HCI_CM_ACTIVE)
Johan Hedberg58a681e2012-01-16 06:47:28 +02002610 set_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002611 else
Johan Hedberg58a681e2012-01-16 06:47:28 +02002612 clear_bit(HCI_CONN_POWER_SAVE, &conn->flags);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002613 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002614
Johan Hedberg51a8efd2012-01-16 06:10:31 +02002615 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->flags))
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002616 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002617 }
2618
2619 hci_dev_unlock(hdev);
2620}
2621
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002622static void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002623{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002624 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2625 struct hci_conn *conn;
2626
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002627 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002628
2629 hci_dev_lock(hdev);
2630
2631 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002632 if (!conn)
2633 goto unlock;
2634
2635 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002636 hci_conn_hold(conn);
2637 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02002638 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002639 }
2640
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002641 if (!test_bit(HCI_PAIRABLE, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02002642 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002643 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002644 else if (test_bit(HCI_MGMT, &hdev->dev_flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002645 u8 secure;
2646
2647 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2648 secure = 1;
2649 else
2650 secure = 0;
2651
Johan Hedberg744cf192011-11-08 20:40:14 +02002652 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002653 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002654
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002655unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002656 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002657}
2658
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002659static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002660{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002661 struct hci_ev_link_key_req *ev = (void *) skb->data;
2662 struct hci_cp_link_key_reply cp;
2663 struct hci_conn *conn;
2664 struct link_key *key;
2665
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002666 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002667
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002668 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002669 return;
2670
2671 hci_dev_lock(hdev);
2672
2673 key = hci_find_link_key(hdev, &ev->bdaddr);
2674 if (!key) {
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002675 BT_DBG("%s link key not found for %pMR", hdev->name,
2676 &ev->bdaddr);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002677 goto not_found;
2678 }
2679
Andrei Emeltchenko6ed93dc2012-09-25 12:49:43 +03002680 BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
2681 &ev->bdaddr);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002682
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02002683 if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002684 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002685 BT_DBG("%s ignoring debug key", hdev->name);
2686 goto not_found;
2687 }
2688
2689 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002690 if (conn) {
2691 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002692 conn->auth_type != 0xff && (conn->auth_type & 0x01)) {
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002693 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2694 goto not_found;
2695 }
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002696
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002697 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
Gustavo Padovan807deac2012-05-17 00:36:24 -03002698 conn->pending_sec_level == BT_SECURITY_HIGH) {
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03002699 BT_DBG("%s ignoring key unauthenticated for high security",
2700 hdev->name);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002701 goto not_found;
2702 }
2703
2704 conn->key_type = key->type;
2705 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002706 }
2707
2708 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9b3b4462012-05-23 11:31:20 +03002709 memcpy(cp.link_key, key->val, HCI_LINK_KEY_SIZE);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002710
2711 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2712
2713 hci_dev_unlock(hdev);
2714
2715 return;
2716
2717not_found:
2718 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2719 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002720}
2721
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002722static void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002723{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002724 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2725 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002726 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002727
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002728 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002729
2730 hci_dev_lock(hdev);
2731
2732 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2733 if (conn) {
2734 hci_conn_hold(conn);
2735 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002736 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002737
2738 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2739 conn->key_type = ev->key_type;
2740
David Herrmann76a68ba2013-04-06 20:28:37 +02002741 hci_conn_drop(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002742 }
2743
Andrei Emeltchenko034cbea2013-05-14 11:44:16 +03002744 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002745 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Gustavo Padovan807deac2012-05-17 00:36:24 -03002746 ev->key_type, pin_len);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002747
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002748 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002749}
2750
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002751static void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04837f62006-07-03 10:02:33 +02002752{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002753 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002754 struct hci_conn *conn;
2755
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002756 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002757
2758 hci_dev_lock(hdev);
2759
2760 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002761 if (conn && !ev->status) {
2762 struct inquiry_entry *ie;
2763
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002764 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2765 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002766 ie->data.clock_offset = ev->clock_offset;
2767 ie->timestamp = jiffies;
2768 }
2769 }
2770
2771 hci_dev_unlock(hdev);
2772}
2773
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002774static void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmanna8746412008-07-14 20:13:46 +02002775{
2776 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2777 struct hci_conn *conn;
2778
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002779 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmanna8746412008-07-14 20:13:46 +02002780
2781 hci_dev_lock(hdev);
2782
2783 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2784 if (conn && !ev->status)
2785 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2786
2787 hci_dev_unlock(hdev);
2788}
2789
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002790static void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002791{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002792 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002793 struct inquiry_entry *ie;
2794
2795 BT_DBG("%s", hdev->name);
2796
2797 hci_dev_lock(hdev);
2798
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002799 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2800 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002801 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2802 ie->timestamp = jiffies;
2803 }
2804
2805 hci_dev_unlock(hdev);
2806}
2807
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002808static void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev,
2809 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002810{
2811 struct inquiry_data data;
2812 int num_rsp = *((__u8 *) skb->data);
Johan Hedberg388fc8f2012-02-23 00:38:59 +02002813 bool name_known, ssp;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002814
2815 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2816
2817 if (!num_rsp)
2818 return;
2819
Andre Guedes1519cc12012-03-21 00:03:38 -03002820 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
2821 return;
2822
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002823 hci_dev_lock(hdev);
2824
2825 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002826 struct inquiry_info_with_rssi_and_pscan_mode *info;
2827 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002828
Johan Hedberge17acd42011-03-30 23:57:16 +03002829 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002830 bacpy(&data.bdaddr, &info->bdaddr);
2831 data.pscan_rep_mode = info->pscan_rep_mode;
2832 data.pscan_period_mode = info->pscan_period_mode;
2833 data.pscan_mode = info->pscan_mode;
2834 memcpy(data.dev_class, info->dev_class, 3);
2835 data.clock_offset = info->clock_offset;
2836 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002837 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002838
2839 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002840 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002841 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002842 info->dev_class, info->rssi,
2843 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002844 }
2845 } else {
2846 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2847
Johan Hedberge17acd42011-03-30 23:57:16 +03002848 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002849 bacpy(&data.bdaddr, &info->bdaddr);
2850 data.pscan_rep_mode = info->pscan_rep_mode;
2851 data.pscan_period_mode = info->pscan_period_mode;
2852 data.pscan_mode = 0x00;
2853 memcpy(data.dev_class, info->dev_class, 3);
2854 data.clock_offset = info->clock_offset;
2855 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002856 data.ssp_mode = 0x00;
Johan Hedberg31754052012-01-04 13:39:52 +02002857 name_known = hci_inquiry_cache_update(hdev, &data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002858 false, &ssp);
Johan Hedberg48264f02011-11-09 13:58:58 +02002859 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002860 info->dev_class, info->rssi,
2861 !name_known, ssp, NULL, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002862 }
2863 }
2864
2865 hci_dev_unlock(hdev);
2866}
2867
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002868static void hci_remote_ext_features_evt(struct hci_dev *hdev,
2869 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002870{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002871 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2872 struct hci_conn *conn;
2873
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002874 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002875
Marcel Holtmann41a96212008-07-14 20:13:48 +02002876 hci_dev_lock(hdev);
2877
2878 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002879 if (!conn)
2880 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002881
Johan Hedbergcad718e2013-04-17 15:00:51 +03002882 if (ev->page < HCI_MAX_PAGES)
2883 memcpy(conn->features[ev->page], ev->features, 8);
2884
Johan Hedbergccd556f2010-11-10 17:11:51 +02002885 if (!ev->status && ev->page == 0x01) {
2886 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002887
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002888 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2889 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02002890 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann769be972008-07-14 20:13:49 +02002891
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302892 if (ev->features[0] & LMP_HOST_SSP) {
Johan Hedberg58a681e2012-01-16 06:47:28 +02002893 set_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
Jaganath Kanakkasserybbb0ead2013-04-16 20:16:30 +05302894 } else {
2895 /* It is mandatory by the Bluetooth specification that
2896 * Extended Inquiry Results are only used when Secure
2897 * Simple Pairing is enabled, but some devices violate
2898 * this.
2899 *
2900 * To make these devices work, the internal SSP
2901 * enabled flag needs to be cleared if the remote host
2902 * features do not indicate SSP support */
2903 clear_bit(HCI_CONN_SSP_ENABLED, &conn->flags);
2904 }
Marcel Holtmann41a96212008-07-14 20:13:48 +02002905 }
2906
Johan Hedbergccd556f2010-11-10 17:11:51 +02002907 if (conn->state != BT_CONFIG)
2908 goto unlock;
2909
Johan Hedberg671267b2012-05-12 16:11:50 -03002910 if (!ev->status && !test_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02002911 struct hci_cp_remote_name_req cp;
2912 memset(&cp, 0, sizeof(cp));
2913 bacpy(&cp.bdaddr, &conn->dst);
2914 cp.pscan_rep_mode = 0x02;
2915 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
Johan Hedbergb644ba32012-01-17 21:48:47 +02002916 } else if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
2917 mgmt_device_connected(hdev, &conn->dst, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03002918 conn->dst_type, 0, NULL, 0,
2919 conn->dev_class);
Johan Hedberg392599b2010-11-18 22:22:28 +02002920
Johan Hedberg127178d2010-11-18 22:22:29 +02002921 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002922 conn->state = BT_CONNECTED;
2923 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02002924 hci_conn_drop(conn);
Johan Hedbergccd556f2010-11-10 17:11:51 +02002925 }
2926
2927unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002928 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002929}
2930
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002931static void hci_sync_conn_complete_evt(struct hci_dev *hdev,
2932 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002933{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002934 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2935 struct hci_conn *conn;
2936
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03002937 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002938
2939 hci_dev_lock(hdev);
2940
2941 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002942 if (!conn) {
2943 if (ev->link_type == ESCO_LINK)
2944 goto unlock;
2945
2946 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2947 if (!conn)
2948 goto unlock;
2949
2950 conn->type = SCO_LINK;
2951 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002952
Marcel Holtmann732547f2009-04-19 19:14:14 +02002953 switch (ev->status) {
2954 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002955 conn->handle = __le16_to_cpu(ev->handle);
2956 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002957
2958 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002959 break;
2960
Frédéric Dalleau1a4c9582013-08-19 14:24:02 +02002961 case 0x0d: /* Connection Rejected due to Limited Resources */
Stephen Coe705e5712010-02-16 11:29:44 -05002962 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002963 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002964 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002965 case 0x1f: /* Unspecified error */
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002966 if (conn->out) {
Marcel Holtmann732547f2009-04-19 19:14:14 +02002967 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2968 (hdev->esco_type & EDR_ESCO_MASK);
Frédéric Dalleau2dea6322013-08-19 14:24:03 +02002969 if (hci_setup_sync(conn, conn->link->handle))
2970 goto unlock;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002971 }
2972 /* fall through */
2973
2974 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002975 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002976 break;
2977 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002978
2979 hci_proto_connect_cfm(conn, ev->status);
2980 if (ev->status)
2981 hci_conn_del(conn);
2982
2983unlock:
2984 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002985}
2986
Gustavo Padovan6039aa72012-05-23 04:04:18 -03002987static void hci_extended_inquiry_result_evt(struct hci_dev *hdev,
2988 struct sk_buff *skb)
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002989{
2990 struct inquiry_data data;
2991 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2992 int num_rsp = *((__u8 *) skb->data);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05302993 size_t eir_len;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002994
2995 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2996
2997 if (!num_rsp)
2998 return;
2999
Andre Guedes1519cc12012-03-21 00:03:38 -03003000 if (test_bit(HCI_PERIODIC_INQ, &hdev->dev_flags))
3001 return;
3002
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003003 hci_dev_lock(hdev);
3004
Johan Hedberge17acd42011-03-30 23:57:16 +03003005 for (; num_rsp; num_rsp--, info++) {
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003006 bool name_known, ssp;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003007
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003008 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01003009 data.pscan_rep_mode = info->pscan_rep_mode;
3010 data.pscan_period_mode = info->pscan_period_mode;
3011 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003012 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01003013 data.clock_offset = info->clock_offset;
3014 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003015 data.ssp_mode = 0x01;
Johan Hedberg561aafb2012-01-04 13:31:59 +02003016
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003017 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg4ddb1932012-01-15 20:04:43 +02003018 name_known = eir_has_data_type(info->data,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003019 sizeof(info->data),
3020 EIR_NAME_COMPLETE);
Johan Hedberg561aafb2012-01-04 13:31:59 +02003021 else
3022 name_known = true;
3023
Johan Hedberg388fc8f2012-02-23 00:38:59 +02003024 name_known = hci_inquiry_cache_update(hdev, &data, name_known,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003025 &ssp);
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303026 eir_len = eir_get_length(info->data, sizeof(info->data));
Johan Hedberg48264f02011-11-09 13:58:58 +02003027 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK, 0x00,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003028 info->dev_class, info->rssi, !name_known,
Vishal Agarwal9d939d92012-04-26 19:19:56 +05303029 ssp, info->data, eir_len);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003030 }
3031
3032 hci_dev_unlock(hdev);
3033}
3034
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003035static void hci_key_refresh_complete_evt(struct hci_dev *hdev,
3036 struct sk_buff *skb)
3037{
3038 struct hci_ev_key_refresh_complete *ev = (void *) skb->data;
3039 struct hci_conn *conn;
3040
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003041 BT_DBG("%s status 0x%2.2x handle 0x%4.4x", hdev->name, ev->status,
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003042 __le16_to_cpu(ev->handle));
3043
3044 hci_dev_lock(hdev);
3045
3046 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
3047 if (!conn)
3048 goto unlock;
3049
3050 if (!ev->status)
3051 conn->sec_level = conn->pending_sec_level;
3052
3053 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags);
3054
3055 if (ev->status && conn->state == BT_CONNECTED) {
Andre Guedesbed71742013-01-30 11:50:56 -03003056 hci_disconnect(conn, HCI_ERROR_AUTH_FAILURE);
David Herrmann76a68ba2013-04-06 20:28:37 +02003057 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003058 goto unlock;
3059 }
3060
3061 if (conn->state == BT_CONFIG) {
3062 if (!ev->status)
3063 conn->state = BT_CONNECTED;
3064
3065 hci_proto_connect_cfm(conn, ev->status);
David Herrmann76a68ba2013-04-06 20:28:37 +02003066 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003067 } else {
3068 hci_auth_cfm(conn, ev->status);
3069
3070 hci_conn_hold(conn);
3071 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003072 hci_conn_drop(conn);
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003073 }
3074
3075unlock:
3076 hci_dev_unlock(hdev);
3077}
3078
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003079static u8 hci_get_auth_req(struct hci_conn *conn)
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003080{
3081 /* If remote requests dedicated bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003082 if (conn->remote_auth == HCI_AT_DEDICATED_BONDING ||
3083 conn->remote_auth == HCI_AT_DEDICATED_BONDING_MITM) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003084 /* If both remote and local IO capabilities allow MITM
3085 * protection then require it, otherwise don't */
Mikel Astizacabae92013-06-28 10:56:28 +02003086 if (conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT ||
3087 conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)
3088 return HCI_AT_DEDICATED_BONDING;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003089 else
Mikel Astizacabae92013-06-28 10:56:28 +02003090 return HCI_AT_DEDICATED_BONDING_MITM;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003091 }
3092
3093 /* If remote requests no-bonding follow that lead */
Mikel Astizacabae92013-06-28 10:56:28 +02003094 if (conn->remote_auth == HCI_AT_NO_BONDING ||
3095 conn->remote_auth == HCI_AT_NO_BONDING_MITM)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02003096 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003097
3098 return conn->auth_type;
3099}
3100
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003101static void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003102{
3103 struct hci_ev_io_capa_request *ev = (void *) skb->data;
3104 struct hci_conn *conn;
3105
3106 BT_DBG("%s", hdev->name);
3107
3108 hci_dev_lock(hdev);
3109
3110 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003111 if (!conn)
3112 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003113
Johan Hedberg03b555e2011-01-04 15:40:05 +02003114 hci_conn_hold(conn);
3115
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003116 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg03b555e2011-01-04 15:40:05 +02003117 goto unlock;
3118
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003119 if (test_bit(HCI_PAIRABLE, &hdev->dev_flags) ||
Gustavo Padovan807deac2012-05-17 00:36:24 -03003120 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003121 struct hci_cp_io_capability_reply cp;
3122
3123 bacpy(&cp.bdaddr, &ev->bdaddr);
Hemant Gupta7a7f1e72012-01-16 13:34:29 +05303124 /* Change the IO capability from KeyboardDisplay
3125 * to DisplayYesNo as it is not supported by BT spec. */
3126 cp.capability = (conn->io_capability == 0x04) ?
Mikel Astiza7676312013-06-28 10:56:29 +02003127 HCI_IO_DISPLAY_YESNO : conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07003128 conn->auth_type = hci_get_auth_req(conn);
3129 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003130
Gustavo Padovan8fc9ced2012-05-23 04:04:21 -03003131 if (hci_find_remote_oob_data(hdev, &conn->dst) &&
3132 (conn->out || test_bit(HCI_CONN_REMOTE_OOB, &conn->flags)))
Szymon Jancce85ee12011-03-22 13:12:23 +01003133 cp.oob_data = 0x01;
3134 else
3135 cp.oob_data = 0x00;
3136
Johan Hedberg17fa4b92011-01-25 13:28:33 +02003137 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003138 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003139 } else {
3140 struct hci_cp_io_capability_neg_reply cp;
3141
3142 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02003143 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003144
3145 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003146 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003147 }
3148
3149unlock:
3150 hci_dev_unlock(hdev);
3151}
3152
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003153static void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
Johan Hedberg03b555e2011-01-04 15:40:05 +02003154{
3155 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
3156 struct hci_conn *conn;
3157
3158 BT_DBG("%s", hdev->name);
3159
3160 hci_dev_lock(hdev);
3161
3162 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3163 if (!conn)
3164 goto unlock;
3165
Johan Hedberg03b555e2011-01-04 15:40:05 +02003166 conn->remote_cap = ev->capability;
Johan Hedberg03b555e2011-01-04 15:40:05 +02003167 conn->remote_auth = ev->authentication;
Johan Hedberg58a681e2012-01-16 06:47:28 +02003168 if (ev->oob_data)
3169 set_bit(HCI_CONN_REMOTE_OOB, &conn->flags);
Johan Hedberg03b555e2011-01-04 15:40:05 +02003170
3171unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003172 hci_dev_unlock(hdev);
3173}
3174
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003175static void hci_user_confirm_request_evt(struct hci_dev *hdev,
3176 struct sk_buff *skb)
Johan Hedberga5c29682011-02-19 12:05:57 -03003177{
3178 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003179 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07003180 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03003181
3182 BT_DBG("%s", hdev->name);
3183
3184 hci_dev_lock(hdev);
3185
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003186 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg7a828902011-04-28 11:28:53 -07003187 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03003188
Johan Hedberg7a828902011-04-28 11:28:53 -07003189 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3190 if (!conn)
3191 goto unlock;
3192
3193 loc_mitm = (conn->auth_type & 0x01);
3194 rem_mitm = (conn->remote_auth & 0x01);
3195
3196 /* If we require MITM but the remote device can't provide that
3197 * (it has NoInputNoOutput) then reject the confirmation
3198 * request. The only exception is when we're dedicated bonding
3199 * initiators (connect_cfm_cb set) since then we always have the MITM
3200 * bit set. */
Mikel Astiza7676312013-06-28 10:56:29 +02003201 if (!conn->connect_cfm_cb && loc_mitm &&
3202 conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) {
Johan Hedberg7a828902011-04-28 11:28:53 -07003203 BT_DBG("Rejecting request: remote device can't provide MITM");
3204 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003205 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003206 goto unlock;
3207 }
3208
3209 /* If no side requires MITM protection; auto-accept */
Mikel Astiza7676312013-06-28 10:56:29 +02003210 if ((!loc_mitm || conn->remote_cap == HCI_IO_NO_INPUT_OUTPUT) &&
3211 (!rem_mitm || conn->io_capability == HCI_IO_NO_INPUT_OUTPUT)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003212
3213 /* If we're not the initiators request authorization to
3214 * proceed from user space (mgmt_user_confirm with
3215 * confirm_hint set to 1). */
Johan Hedberg51a8efd2012-01-16 06:10:31 +02003216 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003217 BT_DBG("Confirming auto-accept as acceptor");
3218 confirm_hint = 1;
3219 goto confirm;
3220 }
3221
Johan Hedberg9f616562011-04-28 11:28:54 -07003222 BT_DBG("Auto-accept of user confirmation with %ums delay",
Gustavo Padovan807deac2012-05-17 00:36:24 -03003223 hdev->auto_accept_delay);
Johan Hedberg9f616562011-04-28 11:28:54 -07003224
3225 if (hdev->auto_accept_delay > 0) {
3226 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
3227 mod_timer(&conn->auto_accept_timer, jiffies + delay);
3228 goto unlock;
3229 }
3230
Johan Hedberg7a828902011-04-28 11:28:53 -07003231 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
Gustavo Padovan807deac2012-05-17 00:36:24 -03003232 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg7a828902011-04-28 11:28:53 -07003233 goto unlock;
3234 }
3235
Johan Hedberg55bc1a32011-04-28 11:28:56 -07003236confirm:
Johan Hedberg272d90d2012-02-09 15:26:12 +02003237 mgmt_user_confirm_request(hdev, &ev->bdaddr, ACL_LINK, 0, ev->passkey,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003238 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07003239
3240unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03003241 hci_dev_unlock(hdev);
3242}
3243
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003244static void hci_user_passkey_request_evt(struct hci_dev *hdev,
3245 struct sk_buff *skb)
Brian Gix1143d452011-11-23 08:28:34 -08003246{
3247 struct hci_ev_user_passkey_req *ev = (void *) skb->data;
3248
3249 BT_DBG("%s", hdev->name);
3250
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003251 if (test_bit(HCI_MGMT, &hdev->dev_flags))
Johan Hedberg272d90d2012-02-09 15:26:12 +02003252 mgmt_user_passkey_request(hdev, &ev->bdaddr, ACL_LINK, 0);
Brian Gix1143d452011-11-23 08:28:34 -08003253}
3254
Johan Hedberg92a25252012-09-06 18:39:26 +03003255static void hci_user_passkey_notify_evt(struct hci_dev *hdev,
3256 struct sk_buff *skb)
3257{
3258 struct hci_ev_user_passkey_notify *ev = (void *) skb->data;
3259 struct hci_conn *conn;
3260
3261 BT_DBG("%s", hdev->name);
3262
3263 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3264 if (!conn)
3265 return;
3266
3267 conn->passkey_notify = __le32_to_cpu(ev->passkey);
3268 conn->passkey_entered = 0;
3269
3270 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3271 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3272 conn->dst_type, conn->passkey_notify,
3273 conn->passkey_entered);
3274}
3275
3276static void hci_keypress_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
3277{
3278 struct hci_ev_keypress_notify *ev = (void *) skb->data;
3279 struct hci_conn *conn;
3280
3281 BT_DBG("%s", hdev->name);
3282
3283 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3284 if (!conn)
3285 return;
3286
3287 switch (ev->type) {
3288 case HCI_KEYPRESS_STARTED:
3289 conn->passkey_entered = 0;
3290 return;
3291
3292 case HCI_KEYPRESS_ENTERED:
3293 conn->passkey_entered++;
3294 break;
3295
3296 case HCI_KEYPRESS_ERASED:
3297 conn->passkey_entered--;
3298 break;
3299
3300 case HCI_KEYPRESS_CLEARED:
3301 conn->passkey_entered = 0;
3302 break;
3303
3304 case HCI_KEYPRESS_COMPLETED:
3305 return;
3306 }
3307
3308 if (test_bit(HCI_MGMT, &hdev->dev_flags))
3309 mgmt_user_passkey_notify(hdev, &conn->dst, conn->type,
3310 conn->dst_type, conn->passkey_notify,
3311 conn->passkey_entered);
3312}
3313
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003314static void hci_simple_pair_complete_evt(struct hci_dev *hdev,
3315 struct sk_buff *skb)
Marcel Holtmann04936842008-07-14 20:13:48 +02003316{
3317 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
3318 struct hci_conn *conn;
3319
3320 BT_DBG("%s", hdev->name);
3321
3322 hci_dev_lock(hdev);
3323
3324 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03003325 if (!conn)
3326 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02003327
Johan Hedberg2a611692011-02-19 12:06:00 -03003328 /* To avoid duplicate auth_failed events to user space we check
3329 * the HCI_CONN_AUTH_PEND flag which will be set if we
3330 * initiated the authentication. A traditional auth_complete
3331 * event gets always produced as initiator and is also mapped to
3332 * the mgmt_auth_failed event */
Mikel Astizfa1bd912012-08-09 09:52:29 +02003333 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->flags) && ev->status)
Johan Hedbergbab73cb2012-02-09 16:07:29 +02003334 mgmt_auth_failed(hdev, &conn->dst, conn->type, conn->dst_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003335 ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03003336
David Herrmann76a68ba2013-04-06 20:28:37 +02003337 hci_conn_drop(conn);
Johan Hedberg2a611692011-02-19 12:06:00 -03003338
3339unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02003340 hci_dev_unlock(hdev);
3341}
3342
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003343static void hci_remote_host_features_evt(struct hci_dev *hdev,
3344 struct sk_buff *skb)
Marcel Holtmann41a96212008-07-14 20:13:48 +02003345{
3346 struct hci_ev_remote_host_features *ev = (void *) skb->data;
3347 struct inquiry_entry *ie;
Johan Hedbergcad718e2013-04-17 15:00:51 +03003348 struct hci_conn *conn;
Marcel Holtmann41a96212008-07-14 20:13:48 +02003349
3350 BT_DBG("%s", hdev->name);
3351
3352 hci_dev_lock(hdev);
3353
Johan Hedbergcad718e2013-04-17 15:00:51 +03003354 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
3355 if (conn)
3356 memcpy(conn->features[1], ev->features, 8);
3357
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02003358 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
3359 if (ie)
Johan Hedberg02b7cc62012-02-28 02:28:43 +02003360 ie->data.ssp_mode = (ev->features[0] & LMP_HOST_SSP);
Marcel Holtmann41a96212008-07-14 20:13:48 +02003361
3362 hci_dev_unlock(hdev);
3363}
3364
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003365static void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
3366 struct sk_buff *skb)
Szymon Janc2763eda2011-03-22 13:12:22 +01003367{
3368 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
3369 struct oob_data *data;
3370
3371 BT_DBG("%s", hdev->name);
3372
3373 hci_dev_lock(hdev);
3374
Johan Hedberga8b2d5c2012-01-08 23:11:15 +02003375 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
Szymon Jance1ba1f12011-04-06 13:01:59 +02003376 goto unlock;
3377
Szymon Janc2763eda2011-03-22 13:12:22 +01003378 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
3379 if (data) {
3380 struct hci_cp_remote_oob_data_reply cp;
3381
3382 bacpy(&cp.bdaddr, &ev->bdaddr);
3383 memcpy(cp.hash, data->hash, sizeof(cp.hash));
3384 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
3385
3386 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003387 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003388 } else {
3389 struct hci_cp_remote_oob_data_neg_reply cp;
3390
3391 bacpy(&cp.bdaddr, &ev->bdaddr);
3392 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
Gustavo Padovan807deac2012-05-17 00:36:24 -03003393 &cp);
Szymon Janc2763eda2011-03-22 13:12:22 +01003394 }
3395
Szymon Jance1ba1f12011-04-06 13:01:59 +02003396unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01003397 hci_dev_unlock(hdev);
3398}
3399
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003400static void hci_phy_link_complete_evt(struct hci_dev *hdev,
3401 struct sk_buff *skb)
3402{
3403 struct hci_ev_phy_link_complete *ev = (void *) skb->data;
3404 struct hci_conn *hcon, *bredr_hcon;
3405
3406 BT_DBG("%s handle 0x%2.2x status 0x%2.2x", hdev->name, ev->phy_handle,
3407 ev->status);
3408
3409 hci_dev_lock(hdev);
3410
3411 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3412 if (!hcon) {
3413 hci_dev_unlock(hdev);
3414 return;
3415 }
3416
3417 if (ev->status) {
3418 hci_conn_del(hcon);
3419 hci_dev_unlock(hdev);
3420 return;
3421 }
3422
3423 bredr_hcon = hcon->amp_mgr->l2cap_conn->hcon;
3424
3425 hcon->state = BT_CONNECTED;
3426 bacpy(&hcon->dst, &bredr_hcon->dst);
3427
3428 hci_conn_hold(hcon);
3429 hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
David Herrmann76a68ba2013-04-06 20:28:37 +02003430 hci_conn_drop(hcon);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003431
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003432 hci_conn_add_sysfs(hcon);
3433
Andrei Emeltchenkocf70ff22012-10-31 15:46:36 +02003434 amp_physical_cfm(bredr_hcon, hcon);
3435
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003436 hci_dev_unlock(hdev);
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003437}
3438
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003439static void hci_loglink_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
3440{
3441 struct hci_ev_logical_link_complete *ev = (void *) skb->data;
3442 struct hci_conn *hcon;
3443 struct hci_chan *hchan;
3444 struct amp_mgr *mgr;
3445
3446 BT_DBG("%s log_handle 0x%4.4x phy_handle 0x%2.2x status 0x%2.2x",
3447 hdev->name, le16_to_cpu(ev->handle), ev->phy_handle,
3448 ev->status);
3449
3450 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3451 if (!hcon)
3452 return;
3453
3454 /* Create AMP hchan */
3455 hchan = hci_chan_create(hcon);
3456 if (!hchan)
3457 return;
3458
3459 hchan->handle = le16_to_cpu(ev->handle);
3460
3461 BT_DBG("hcon %p mgr %p hchan %p", hcon, hcon->amp_mgr, hchan);
3462
3463 mgr = hcon->amp_mgr;
3464 if (mgr && mgr->bredr_chan) {
3465 struct l2cap_chan *bredr_chan = mgr->bredr_chan;
3466
3467 l2cap_chan_lock(bredr_chan);
3468
3469 bredr_chan->conn->mtu = hdev->block_mtu;
3470 l2cap_logical_cfm(bredr_chan, hchan, 0);
3471 hci_conn_hold(hcon);
3472
3473 l2cap_chan_unlock(bredr_chan);
3474 }
3475}
3476
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003477static void hci_disconn_loglink_complete_evt(struct hci_dev *hdev,
3478 struct sk_buff *skb)
3479{
3480 struct hci_ev_disconn_logical_link_complete *ev = (void *) skb->data;
3481 struct hci_chan *hchan;
3482
3483 BT_DBG("%s log handle 0x%4.4x status 0x%2.2x", hdev->name,
3484 le16_to_cpu(ev->handle), ev->status);
3485
3486 if (ev->status)
3487 return;
3488
3489 hci_dev_lock(hdev);
3490
3491 hchan = hci_chan_lookup_handle(hdev, le16_to_cpu(ev->handle));
3492 if (!hchan)
3493 goto unlock;
3494
3495 amp_destroy_logical_link(hchan, ev->reason);
3496
3497unlock:
3498 hci_dev_unlock(hdev);
3499}
3500
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003501static void hci_disconn_phylink_complete_evt(struct hci_dev *hdev,
3502 struct sk_buff *skb)
3503{
3504 struct hci_ev_disconn_phy_link_complete *ev = (void *) skb->data;
3505 struct hci_conn *hcon;
3506
3507 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
3508
3509 if (ev->status)
3510 return;
3511
3512 hci_dev_lock(hdev);
3513
3514 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3515 if (hcon) {
3516 hcon->state = BT_CLOSED;
3517 hci_conn_del(hcon);
3518 }
3519
3520 hci_dev_unlock(hdev);
3521}
3522
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003523static void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003524{
3525 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
3526 struct hci_conn *conn;
3527
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003528 BT_DBG("%s status 0x%2.2x", hdev->name, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03003529
3530 hci_dev_lock(hdev);
3531
Andre Guedesb47a09b2012-07-27 15:10:15 -03003532 conn = hci_conn_hash_lookup_state(hdev, LE_LINK, BT_CONNECT);
Ville Tervob62f3282011-02-10 22:38:50 -03003533 if (!conn) {
3534 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
3535 if (!conn) {
3536 BT_ERR("No memory for new connection");
Andre Guedes230fd162012-07-27 15:10:10 -03003537 goto unlock;
Ville Tervob62f3282011-02-10 22:38:50 -03003538 }
Andre Guedes29b79882011-05-31 14:20:54 -03003539
3540 conn->dst_type = ev->bdaddr_type;
Andre Guedesb9b343d2012-07-27 15:10:11 -03003541
3542 if (ev->role == LE_CONN_ROLE_MASTER) {
3543 conn->out = true;
3544 conn->link_mode |= HCI_LM_MASTER;
3545 }
Ville Tervob62f3282011-02-10 22:38:50 -03003546 }
Ville Tervofcd89c02011-02-10 22:38:47 -03003547
Andre Guedescd17dec2012-07-27 15:10:16 -03003548 if (ev->status) {
3549 mgmt_connect_failed(hdev, &conn->dst, conn->type,
3550 conn->dst_type, ev->status);
3551 hci_proto_connect_cfm(conn, ev->status);
3552 conn->state = BT_CLOSED;
3553 hci_conn_del(conn);
3554 goto unlock;
3555 }
3556
Johan Hedbergb644ba32012-01-17 21:48:47 +02003557 if (!test_and_set_bit(HCI_CONN_MGMT_CONNECTED, &conn->flags))
3558 mgmt_device_connected(hdev, &ev->bdaddr, conn->type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003559 conn->dst_type, 0, NULL, 0, NULL);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03003560
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03003561 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03003562 conn->handle = __le16_to_cpu(ev->handle);
3563 conn->state = BT_CONNECTED;
3564
Ville Tervofcd89c02011-02-10 22:38:47 -03003565 hci_conn_add_sysfs(conn);
3566
3567 hci_proto_connect_cfm(conn, ev->status);
3568
3569unlock:
3570 hci_dev_unlock(hdev);
3571}
3572
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003573static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb)
Andre Guedes9aa04c92011-05-26 16:23:51 -03003574{
Andre Guedese95beb42011-09-26 20:48:35 -03003575 u8 num_reports = skb->data[0];
3576 void *ptr = &skb->data[1];
Andre Guedes3c9e9192012-01-10 18:20:50 -03003577 s8 rssi;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003578
Andre Guedese95beb42011-09-26 20:48:35 -03003579 while (num_reports--) {
3580 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003581
Andre Guedes3c9e9192012-01-10 18:20:50 -03003582 rssi = ev->data[ev->length];
3583 mgmt_device_found(hdev, &ev->bdaddr, LE_LINK, ev->bdaddr_type,
Gustavo F. Padovan04124682012-03-08 01:25:00 -03003584 NULL, rssi, 0, 1, ev->data, ev->length);
Andre Guedes3c9e9192012-01-10 18:20:50 -03003585
Andre Guedese95beb42011-09-26 20:48:35 -03003586 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03003587 }
Andre Guedes9aa04c92011-05-26 16:23:51 -03003588}
3589
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003590static void hci_le_ltk_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003591{
3592 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3593 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003594 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003595 struct hci_conn *conn;
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003596 struct smp_ltk *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003597
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003598 BT_DBG("%s handle 0x%4.4x", hdev->name, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003599
3600 hci_dev_lock(hdev);
3601
3602 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003603 if (conn == NULL)
3604 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003605
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003606 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3607 if (ltk == NULL)
3608 goto not_found;
3609
3610 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003611 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003612
3613 if (ltk->authenticated)
Andre Guedesf8776212013-07-31 16:25:28 -03003614 conn->pending_sec_level = BT_SECURITY_HIGH;
3615 else
3616 conn->pending_sec_level = BT_SECURITY_MEDIUM;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003617
Andre Guedes89cbb4d2013-07-31 16:25:29 -03003618 conn->enc_key_size = ltk->enc_size;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003619
3620 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3621
Vinicius Costa Gomesc9839a12012-02-02 21:08:01 -03003622 if (ltk->type & HCI_SMP_STK) {
3623 list_del(&ltk->list);
3624 kfree(ltk);
3625 }
3626
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003627 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03003628
3629 return;
3630
3631not_found:
3632 neg.handle = ev->handle;
3633 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3634 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003635}
3636
Gustavo Padovan6039aa72012-05-23 04:04:18 -03003637static void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
Ville Tervofcd89c02011-02-10 22:38:47 -03003638{
3639 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3640
3641 skb_pull(skb, sizeof(*le_ev));
3642
3643 switch (le_ev->subevent) {
3644 case HCI_EV_LE_CONN_COMPLETE:
3645 hci_le_conn_complete_evt(hdev, skb);
3646 break;
3647
Andre Guedes9aa04c92011-05-26 16:23:51 -03003648 case HCI_EV_LE_ADVERTISING_REPORT:
3649 hci_le_adv_report_evt(hdev, skb);
3650 break;
3651
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03003652 case HCI_EV_LE_LTK_REQ:
3653 hci_le_ltk_request_evt(hdev, skb);
3654 break;
3655
Ville Tervofcd89c02011-02-10 22:38:47 -03003656 default:
3657 break;
3658 }
3659}
3660
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003661static void hci_chan_selected_evt(struct hci_dev *hdev, struct sk_buff *skb)
3662{
3663 struct hci_ev_channel_selected *ev = (void *) skb->data;
3664 struct hci_conn *hcon;
3665
3666 BT_DBG("%s handle 0x%2.2x", hdev->name, ev->phy_handle);
3667
3668 skb_pull(skb, sizeof(*ev));
3669
3670 hcon = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3671 if (!hcon)
3672 return;
3673
3674 amp_read_loc_assoc_final_data(hdev, hcon);
3675}
3676
Linus Torvalds1da177e2005-04-16 15:20:36 -07003677void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3678{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003679 struct hci_event_hdr *hdr = (void *) skb->data;
3680 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003681
Johan Hedbergb6ddb632013-04-02 13:34:31 +03003682 hci_dev_lock(hdev);
3683
3684 /* Received events are (currently) only needed when a request is
3685 * ongoing so avoid unnecessary memory allocation.
3686 */
3687 if (hdev->req_status == HCI_REQ_PEND) {
3688 kfree_skb(hdev->recv_evt);
3689 hdev->recv_evt = skb_clone(skb, GFP_KERNEL);
3690 }
3691
3692 hci_dev_unlock(hdev);
3693
Linus Torvalds1da177e2005-04-16 15:20:36 -07003694 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3695
Johan Hedberg02350a72013-04-03 21:50:29 +03003696 if (hdev->sent_cmd && bt_cb(hdev->sent_cmd)->req.event == event) {
3697 struct hci_command_hdr *hdr = (void *) hdev->sent_cmd->data;
3698 u16 opcode = __le16_to_cpu(hdr->opcode);
3699
3700 hci_req_cmd_complete(hdev, opcode, 0);
3701 }
3702
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003703 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003704 case HCI_EV_INQUIRY_COMPLETE:
3705 hci_inquiry_complete_evt(hdev, skb);
3706 break;
3707
3708 case HCI_EV_INQUIRY_RESULT:
3709 hci_inquiry_result_evt(hdev, skb);
3710 break;
3711
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003712 case HCI_EV_CONN_COMPLETE:
3713 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003714 break;
3715
Linus Torvalds1da177e2005-04-16 15:20:36 -07003716 case HCI_EV_CONN_REQUEST:
3717 hci_conn_request_evt(hdev, skb);
3718 break;
3719
Linus Torvalds1da177e2005-04-16 15:20:36 -07003720 case HCI_EV_DISCONN_COMPLETE:
3721 hci_disconn_complete_evt(hdev, skb);
3722 break;
3723
Linus Torvalds1da177e2005-04-16 15:20:36 -07003724 case HCI_EV_AUTH_COMPLETE:
3725 hci_auth_complete_evt(hdev, skb);
3726 break;
3727
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003728 case HCI_EV_REMOTE_NAME:
3729 hci_remote_name_evt(hdev, skb);
3730 break;
3731
Linus Torvalds1da177e2005-04-16 15:20:36 -07003732 case HCI_EV_ENCRYPT_CHANGE:
3733 hci_encrypt_change_evt(hdev, skb);
3734 break;
3735
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003736 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3737 hci_change_link_key_complete_evt(hdev, skb);
3738 break;
3739
3740 case HCI_EV_REMOTE_FEATURES:
3741 hci_remote_features_evt(hdev, skb);
3742 break;
3743
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003744 case HCI_EV_CMD_COMPLETE:
3745 hci_cmd_complete_evt(hdev, skb);
3746 break;
3747
3748 case HCI_EV_CMD_STATUS:
3749 hci_cmd_status_evt(hdev, skb);
3750 break;
3751
3752 case HCI_EV_ROLE_CHANGE:
3753 hci_role_change_evt(hdev, skb);
3754 break;
3755
3756 case HCI_EV_NUM_COMP_PKTS:
3757 hci_num_comp_pkts_evt(hdev, skb);
3758 break;
3759
3760 case HCI_EV_MODE_CHANGE:
3761 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003762 break;
3763
3764 case HCI_EV_PIN_CODE_REQ:
3765 hci_pin_code_request_evt(hdev, skb);
3766 break;
3767
3768 case HCI_EV_LINK_KEY_REQ:
3769 hci_link_key_request_evt(hdev, skb);
3770 break;
3771
3772 case HCI_EV_LINK_KEY_NOTIFY:
3773 hci_link_key_notify_evt(hdev, skb);
3774 break;
3775
3776 case HCI_EV_CLOCK_OFFSET:
3777 hci_clock_offset_evt(hdev, skb);
3778 break;
3779
Marcel Holtmanna8746412008-07-14 20:13:46 +02003780 case HCI_EV_PKT_TYPE_CHANGE:
3781 hci_pkt_type_change_evt(hdev, skb);
3782 break;
3783
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003784 case HCI_EV_PSCAN_REP_MODE:
3785 hci_pscan_rep_mode_evt(hdev, skb);
3786 break;
3787
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003788 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3789 hci_inquiry_result_with_rssi_evt(hdev, skb);
3790 break;
3791
3792 case HCI_EV_REMOTE_EXT_FEATURES:
3793 hci_remote_ext_features_evt(hdev, skb);
3794 break;
3795
3796 case HCI_EV_SYNC_CONN_COMPLETE:
3797 hci_sync_conn_complete_evt(hdev, skb);
3798 break;
3799
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003800 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3801 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003802 break;
3803
Johan Hedberg1c2e0042012-06-08 23:31:13 +08003804 case HCI_EV_KEY_REFRESH_COMPLETE:
3805 hci_key_refresh_complete_evt(hdev, skb);
3806 break;
3807
Marcel Holtmann04936842008-07-14 20:13:48 +02003808 case HCI_EV_IO_CAPA_REQUEST:
3809 hci_io_capa_request_evt(hdev, skb);
3810 break;
3811
Johan Hedberg03b555e2011-01-04 15:40:05 +02003812 case HCI_EV_IO_CAPA_REPLY:
3813 hci_io_capa_reply_evt(hdev, skb);
3814 break;
3815
Johan Hedberga5c29682011-02-19 12:05:57 -03003816 case HCI_EV_USER_CONFIRM_REQUEST:
3817 hci_user_confirm_request_evt(hdev, skb);
3818 break;
3819
Brian Gix1143d452011-11-23 08:28:34 -08003820 case HCI_EV_USER_PASSKEY_REQUEST:
3821 hci_user_passkey_request_evt(hdev, skb);
3822 break;
3823
Johan Hedberg92a25252012-09-06 18:39:26 +03003824 case HCI_EV_USER_PASSKEY_NOTIFY:
3825 hci_user_passkey_notify_evt(hdev, skb);
3826 break;
3827
3828 case HCI_EV_KEYPRESS_NOTIFY:
3829 hci_keypress_notify_evt(hdev, skb);
3830 break;
3831
Marcel Holtmann04936842008-07-14 20:13:48 +02003832 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3833 hci_simple_pair_complete_evt(hdev, skb);
3834 break;
3835
Marcel Holtmann41a96212008-07-14 20:13:48 +02003836 case HCI_EV_REMOTE_HOST_FEATURES:
3837 hci_remote_host_features_evt(hdev, skb);
3838 break;
3839
Ville Tervofcd89c02011-02-10 22:38:47 -03003840 case HCI_EV_LE_META:
3841 hci_le_meta_evt(hdev, skb);
3842 break;
3843
Andrei Emeltchenko9495b2e2012-09-27 17:26:22 +03003844 case HCI_EV_CHANNEL_SELECTED:
3845 hci_chan_selected_evt(hdev, skb);
3846 break;
3847
Szymon Janc2763eda2011-03-22 13:12:22 +01003848 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3849 hci_remote_oob_data_request_evt(hdev, skb);
3850 break;
3851
Andrei Emeltchenkod5e91192012-10-25 15:20:44 +03003852 case HCI_EV_PHY_LINK_COMPLETE:
3853 hci_phy_link_complete_evt(hdev, skb);
3854 break;
3855
Andrei Emeltchenko27695fb2012-10-25 15:20:45 +03003856 case HCI_EV_LOGICAL_LINK_COMPLETE:
3857 hci_loglink_complete_evt(hdev, skb);
3858 break;
3859
Andrei Emeltchenko606e2a12012-10-31 15:46:31 +02003860 case HCI_EV_DISCONN_LOGICAL_LINK_COMPLETE:
3861 hci_disconn_loglink_complete_evt(hdev, skb);
3862 break;
3863
Andrei Emeltchenko9eef6b32012-10-31 15:46:32 +02003864 case HCI_EV_DISCONN_PHY_LINK_COMPLETE:
3865 hci_disconn_phylink_complete_evt(hdev, skb);
3866 break;
3867
Andrei Emeltchenko25e89e92012-01-04 12:41:58 +02003868 case HCI_EV_NUM_COMP_BLOCKS:
3869 hci_num_comp_blocks_evt(hdev, skb);
3870 break;
3871
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003872 default:
Andrei Emeltchenko9f1db002012-07-11 14:32:43 +03003873 BT_DBG("%s event 0x%2.2x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003874 break;
3875 }
3876
3877 kfree_skb(skb);
3878 hdev->stat.evt_rx++;
3879}