blob: a89cf1f24e47697d14f009900ac8a3ee8fe0e549 [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 <linux/module.h>
28
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/slab.h>
33#include <linux/poll.h>
34#include <linux/fcntl.h>
35#include <linux/init.h>
36#include <linux/skbuff.h>
37#include <linux/interrupt.h>
38#include <linux/notifier.h>
39#include <net/sock.h>
40
41#include <asm/system.h>
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020042#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <asm/unaligned.h>
44
45#include <net/bluetooth/bluetooth.h>
46#include <net/bluetooth/hci_core.h>
47
Andre Guedese6100a22011-06-30 19:20:54 -030048static int enable_le;
49
Linus Torvalds1da177e2005-04-16 15:20:36 -070050/* Handle HCI Event packets */
51
Marcel Holtmanna9de9242007-10-20 13:33:56 +020052static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070053{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020054 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
Marcel Holtmanna9de9242007-10-20 13:33:56 +020056 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070057
Marcel Holtmanna9de9242007-10-20 13:33:56 +020058 if (status)
59 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070060
Andre Guedes89352e72011-11-04 14:16:53 -030061 clear_bit(HCI_INQUIRY, &hdev->flags);
62
Johan Hedberg56e5cb82011-11-08 20:40:16 +020063 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +020064 mgmt_discovering(hdev, 0);
Johan Hedberg56e5cb82011-11-08 20:40:16 +020065 hci_dev_unlock(hdev);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010066
Johan Hedberg23bb5762010-12-21 23:01:27 +020067 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010068
Marcel Holtmanna9de9242007-10-20 13:33:56 +020069 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070070}
71
Marcel Holtmanna9de9242007-10-20 13:33:56 +020072static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070073{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020074 __u8 status = *((__u8 *) skb->data);
75
76 BT_DBG("%s status 0x%x", hdev->name, status);
77
78 if (status)
79 return;
80
Marcel Holtmanna9de9242007-10-20 13:33:56 +020081 hci_conn_check_pending(hdev);
82}
83
84static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
85{
86 BT_DBG("%s", hdev->name);
87}
88
89static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
90{
91 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070092 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070093
Marcel Holtmanna9de9242007-10-20 13:33:56 +020094 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070095
Marcel Holtmanna9de9242007-10-20 13:33:56 +020096 if (rp->status)
97 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070098
Marcel Holtmanna9de9242007-10-20 13:33:56 +020099 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200101 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
102 if (conn) {
103 if (rp->role)
104 conn->link_mode &= ~HCI_LM_MASTER;
105 else
106 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200108
109 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110}
111
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200112static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
113{
114 struct hci_rp_read_link_policy *rp = (void *) skb->data;
115 struct hci_conn *conn;
116
117 BT_DBG("%s status 0x%x", hdev->name, rp->status);
118
119 if (rp->status)
120 return;
121
122 hci_dev_lock(hdev);
123
124 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
125 if (conn)
126 conn->link_policy = __le16_to_cpu(rp->policy);
127
128 hci_dev_unlock(hdev);
129}
130
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200131static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700132{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200133 struct hci_rp_write_link_policy *rp = (void *) skb->data;
134 struct hci_conn *conn;
135 void *sent;
136
137 BT_DBG("%s status 0x%x", hdev->name, rp->status);
138
139 if (rp->status)
140 return;
141
142 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
143 if (!sent)
144 return;
145
146 hci_dev_lock(hdev);
147
148 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200149 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700150 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200151
152 hci_dev_unlock(hdev);
153}
154
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200155static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
156{
157 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
158
159 BT_DBG("%s status 0x%x", hdev->name, rp->status);
160
161 if (rp->status)
162 return;
163
164 hdev->link_policy = __le16_to_cpu(rp->policy);
165}
166
167static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
168{
169 __u8 status = *((__u8 *) skb->data);
170 void *sent;
171
172 BT_DBG("%s status 0x%x", hdev->name, status);
173
174 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
175 if (!sent)
176 return;
177
178 if (!status)
179 hdev->link_policy = get_unaligned_le16(sent);
180
Johan Hedberg23bb5762010-12-21 23:01:27 +0200181 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200182}
183
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200184static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
185{
186 __u8 status = *((__u8 *) skb->data);
187
188 BT_DBG("%s status 0x%x", hdev->name, status);
189
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300190 clear_bit(HCI_RESET, &hdev->flags);
191
Johan Hedberg23bb5762010-12-21 23:01:27 +0200192 hci_req_complete(hdev, HCI_OP_RESET, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200193}
194
195static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
196{
197 __u8 status = *((__u8 *) skb->data);
198 void *sent;
199
200 BT_DBG("%s status 0x%x", hdev->name, status);
201
202 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
203 if (!sent)
204 return;
205
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200206 hci_dev_lock(hdev);
207
Johan Hedbergb312b1612011-03-16 14:29:37 +0200208 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200209 mgmt_set_local_name_complete(hdev, sent, status);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200210
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200211 if (status == 0)
212 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Johan Hedbergb312b1612011-03-16 14:29:37 +0200213
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200214 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200215}
216
217static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
218{
219 struct hci_rp_read_local_name *rp = (void *) skb->data;
220
221 BT_DBG("%s status 0x%x", hdev->name, rp->status);
222
223 if (rp->status)
224 return;
225
Johan Hedberg1f6c6372011-03-16 14:29:35 +0200226 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200227}
228
229static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
230{
231 __u8 status = *((__u8 *) skb->data);
232 void *sent;
233
234 BT_DBG("%s status 0x%x", hdev->name, status);
235
236 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
237 if (!sent)
238 return;
239
240 if (!status) {
241 __u8 param = *((__u8 *) sent);
242
243 if (param == AUTH_ENABLED)
244 set_bit(HCI_AUTH, &hdev->flags);
245 else
246 clear_bit(HCI_AUTH, &hdev->flags);
247 }
248
Johan Hedberg23bb5762010-12-21 23:01:27 +0200249 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200250}
251
252static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
253{
254 __u8 status = *((__u8 *) skb->data);
255 void *sent;
256
257 BT_DBG("%s status 0x%x", hdev->name, status);
258
259 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
260 if (!sent)
261 return;
262
263 if (!status) {
264 __u8 param = *((__u8 *) sent);
265
266 if (param)
267 set_bit(HCI_ENCRYPT, &hdev->flags);
268 else
269 clear_bit(HCI_ENCRYPT, &hdev->flags);
270 }
271
Johan Hedberg23bb5762010-12-21 23:01:27 +0200272 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200273}
274
275static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
276{
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200277 __u8 param, status = *((__u8 *) skb->data);
278 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200279 void *sent;
280
281 BT_DBG("%s status 0x%x", hdev->name, status);
282
283 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
284 if (!sent)
285 return;
286
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200287 param = *((__u8 *) sent);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200288
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200289 hci_dev_lock(hdev);
290
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200291 if (status != 0) {
Johan Hedberg744cf192011-11-08 20:40:14 +0200292 mgmt_write_scan_failed(hdev, param, status);
Johan Hedberg2d7cee52011-11-07 22:16:03 +0200293 hdev->discov_timeout = 0;
294 goto done;
295 }
296
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200297 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
298 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200299
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200300 if (param & SCAN_INQUIRY) {
301 set_bit(HCI_ISCAN, &hdev->flags);
302 if (!old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200303 mgmt_discoverable(hdev, 1);
Johan Hedberg16ab91a2011-11-07 22:16:02 +0200304 if (hdev->discov_timeout > 0) {
305 int to = msecs_to_jiffies(hdev->discov_timeout * 1000);
306 queue_delayed_work(hdev->workqueue, &hdev->discov_off,
307 to);
308 }
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200309 } else if (old_iscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200310 mgmt_discoverable(hdev, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200311
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200312 if (param & SCAN_PAGE) {
313 set_bit(HCI_PSCAN, &hdev->flags);
314 if (!old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200315 mgmt_connectable(hdev, 1);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200316 } else if (old_pscan)
Johan Hedberg744cf192011-11-08 20:40:14 +0200317 mgmt_connectable(hdev, 0);
Johan Hedberg36f7fc72011-11-04 00:17:45 +0200318
319done:
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200320 hci_dev_unlock(hdev);
Johan Hedberg23bb5762010-12-21 23:01:27 +0200321 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200322}
323
324static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
325{
326 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
327
328 BT_DBG("%s status 0x%x", hdev->name, rp->status);
329
330 if (rp->status)
331 return;
332
333 memcpy(hdev->dev_class, rp->dev_class, 3);
334
335 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
336 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
337}
338
339static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
340{
341 __u8 status = *((__u8 *) skb->data);
342 void *sent;
343
344 BT_DBG("%s status 0x%x", hdev->name, status);
345
Marcel Holtmannf383f272008-07-14 20:13:47 +0200346 if (status)
347 return;
348
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200349 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
350 if (!sent)
351 return;
352
Marcel Holtmannf383f272008-07-14 20:13:47 +0200353 memcpy(hdev->dev_class, sent, 3);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200354}
355
356static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
357{
358 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200360
361 BT_DBG("%s status 0x%x", hdev->name, rp->status);
362
363 if (rp->status)
364 return;
365
366 setting = __le16_to_cpu(rp->voice_setting);
367
Marcel Holtmannf383f272008-07-14 20:13:47 +0200368 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200369 return;
370
371 hdev->voice_setting = setting;
372
373 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
374
375 if (hdev->notify) {
376 tasklet_disable(&hdev->tx_task);
377 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
378 tasklet_enable(&hdev->tx_task);
379 }
380}
381
382static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
383{
384 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200385 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 void *sent;
387
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200388 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700389
Marcel Holtmannf383f272008-07-14 20:13:47 +0200390 if (status)
391 return;
392
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200393 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
394 if (!sent)
395 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396
Marcel Holtmannf383f272008-07-14 20:13:47 +0200397 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398
Marcel Holtmannf383f272008-07-14 20:13:47 +0200399 if (hdev->voice_setting == setting)
400 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700401
Marcel Holtmannf383f272008-07-14 20:13:47 +0200402 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700403
Marcel Holtmannf383f272008-07-14 20:13:47 +0200404 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
405
406 if (hdev->notify) {
407 tasklet_disable(&hdev->tx_task);
408 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
409 tasklet_enable(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700410 }
411}
412
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200413static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700414{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200415 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200417 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700418
Johan Hedberg23bb5762010-12-21 23:01:27 +0200419 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420}
421
Marcel Holtmann333140b2008-07-14 20:13:48 +0200422static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
423{
424 struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
425
426 BT_DBG("%s status 0x%x", hdev->name, rp->status);
427
428 if (rp->status)
429 return;
430
431 hdev->ssp_mode = rp->mode;
432}
433
434static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
435{
436 __u8 status = *((__u8 *) skb->data);
437 void *sent;
438
439 BT_DBG("%s status 0x%x", hdev->name, status);
440
441 if (status)
442 return;
443
444 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
445 if (!sent)
446 return;
447
448 hdev->ssp_mode = *((__u8 *) sent);
449}
450
Johan Hedbergd5859e22011-01-25 01:19:58 +0200451static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
452{
453 if (hdev->features[6] & LMP_EXT_INQ)
454 return 2;
455
456 if (hdev->features[3] & LMP_RSSI_INQ)
457 return 1;
458
459 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
460 hdev->lmp_subver == 0x0757)
461 return 1;
462
463 if (hdev->manufacturer == 15) {
464 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
465 return 1;
466 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
467 return 1;
468 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
469 return 1;
470 }
471
472 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
473 hdev->lmp_subver == 0x1805)
474 return 1;
475
476 return 0;
477}
478
479static void hci_setup_inquiry_mode(struct hci_dev *hdev)
480{
481 u8 mode;
482
483 mode = hci_get_inquiry_mode(hdev);
484
485 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
486}
487
488static void hci_setup_event_mask(struct hci_dev *hdev)
489{
490 /* The second byte is 0xff instead of 0x9f (two reserved bits
491 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
492 * command otherwise */
493 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
494
Ville Tervo6de6c182011-05-27 11:16:21 +0300495 /* CSR 1.1 dongles does not accept any bitfield so don't try to set
496 * any event mask for pre 1.2 devices */
497 if (hdev->lmp_ver <= 1)
498 return;
499
500 events[4] |= 0x01; /* Flow Specification Complete */
501 events[4] |= 0x02; /* Inquiry Result with RSSI */
502 events[4] |= 0x04; /* Read Remote Extended Features Complete */
503 events[5] |= 0x08; /* Synchronous Connection Complete */
504 events[5] |= 0x10; /* Synchronous Connection Changed */
Johan Hedbergd5859e22011-01-25 01:19:58 +0200505
506 if (hdev->features[3] & LMP_RSSI_INQ)
507 events[4] |= 0x04; /* Inquiry Result with RSSI */
508
509 if (hdev->features[5] & LMP_SNIFF_SUBR)
510 events[5] |= 0x20; /* Sniff Subrating */
511
512 if (hdev->features[5] & LMP_PAUSE_ENC)
513 events[5] |= 0x80; /* Encryption Key Refresh Complete */
514
515 if (hdev->features[6] & LMP_EXT_INQ)
516 events[5] |= 0x40; /* Extended Inquiry Result */
517
518 if (hdev->features[6] & LMP_NO_FLUSH)
519 events[7] |= 0x01; /* Enhanced Flush Complete */
520
521 if (hdev->features[7] & LMP_LSTO)
522 events[6] |= 0x80; /* Link Supervision Timeout Changed */
523
524 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
525 events[6] |= 0x01; /* IO Capability Request */
526 events[6] |= 0x02; /* IO Capability Response */
527 events[6] |= 0x04; /* User Confirmation Request */
528 events[6] |= 0x08; /* User Passkey Request */
529 events[6] |= 0x10; /* Remote OOB Data Request */
530 events[6] |= 0x20; /* Simple Pairing Complete */
531 events[7] |= 0x04; /* User Passkey Notification */
532 events[7] |= 0x08; /* Keypress Notification */
533 events[7] |= 0x10; /* Remote Host Supported
534 * Features Notification */
535 }
536
537 if (hdev->features[4] & LMP_LE)
538 events[7] |= 0x20; /* LE Meta-Event */
539
540 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
541}
542
Andre Guedese6100a22011-06-30 19:20:54 -0300543static void hci_set_le_support(struct hci_dev *hdev)
544{
545 struct hci_cp_write_le_host_supported cp;
546
547 memset(&cp, 0, sizeof(cp));
548
549 if (enable_le) {
550 cp.le = 1;
551 cp.simul = !!(hdev->features[6] & LMP_SIMUL_LE_BR);
552 }
553
554 hci_send_cmd(hdev, HCI_OP_WRITE_LE_HOST_SUPPORTED, sizeof(cp), &cp);
555}
556
Johan Hedbergd5859e22011-01-25 01:19:58 +0200557static void hci_setup(struct hci_dev *hdev)
558{
559 hci_setup_event_mask(hdev);
560
561 if (hdev->lmp_ver > 1)
562 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
563
564 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
565 u8 mode = 0x01;
566 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
567 }
568
569 if (hdev->features[3] & LMP_RSSI_INQ)
570 hci_setup_inquiry_mode(hdev);
571
572 if (hdev->features[7] & LMP_INQ_TX_PWR)
573 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
Andre Guedes971e3a42011-06-30 19:20:52 -0300574
575 if (hdev->features[7] & LMP_EXTFEATURES) {
576 struct hci_cp_read_local_ext_features cp;
577
578 cp.page = 0x01;
579 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES,
580 sizeof(cp), &cp);
581 }
Andre Guedese6100a22011-06-30 19:20:54 -0300582
583 if (hdev->features[4] & LMP_LE)
584 hci_set_le_support(hdev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200585}
586
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200587static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
588{
589 struct hci_rp_read_local_version *rp = (void *) skb->data;
590
591 BT_DBG("%s status 0x%x", hdev->name, rp->status);
592
593 if (rp->status)
594 return;
595
596 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200597 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200598 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200599 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200600 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200601
602 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
603 hdev->manufacturer,
604 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200605
606 if (test_bit(HCI_INIT, &hdev->flags))
607 hci_setup(hdev);
608}
609
610static void hci_setup_link_policy(struct hci_dev *hdev)
611{
612 u16 link_policy = 0;
613
614 if (hdev->features[0] & LMP_RSWITCH)
615 link_policy |= HCI_LP_RSWITCH;
616 if (hdev->features[0] & LMP_HOLD)
617 link_policy |= HCI_LP_HOLD;
618 if (hdev->features[0] & LMP_SNIFF)
619 link_policy |= HCI_LP_SNIFF;
620 if (hdev->features[1] & LMP_PARK)
621 link_policy |= HCI_LP_PARK;
622
623 link_policy = cpu_to_le16(link_policy);
624 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
625 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200626}
627
628static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
629{
630 struct hci_rp_read_local_commands *rp = (void *) skb->data;
631
632 BT_DBG("%s status 0x%x", hdev->name, rp->status);
633
634 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200635 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200636
637 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200638
639 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
640 hci_setup_link_policy(hdev);
641
642done:
643 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200644}
645
646static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
647{
648 struct hci_rp_read_local_features *rp = (void *) skb->data;
649
650 BT_DBG("%s status 0x%x", hdev->name, rp->status);
651
652 if (rp->status)
653 return;
654
655 memcpy(hdev->features, rp->features, 8);
656
657 /* Adjust default settings according to features
658 * supported by device. */
659
660 if (hdev->features[0] & LMP_3SLOT)
661 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
662
663 if (hdev->features[0] & LMP_5SLOT)
664 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
665
666 if (hdev->features[1] & LMP_HV2) {
667 hdev->pkt_type |= (HCI_HV2);
668 hdev->esco_type |= (ESCO_HV2);
669 }
670
671 if (hdev->features[1] & LMP_HV3) {
672 hdev->pkt_type |= (HCI_HV3);
673 hdev->esco_type |= (ESCO_HV3);
674 }
675
676 if (hdev->features[3] & LMP_ESCO)
677 hdev->esco_type |= (ESCO_EV3);
678
679 if (hdev->features[4] & LMP_EV4)
680 hdev->esco_type |= (ESCO_EV4);
681
682 if (hdev->features[4] & LMP_EV5)
683 hdev->esco_type |= (ESCO_EV5);
684
Marcel Holtmannefc76882009-02-06 09:13:37 +0100685 if (hdev->features[5] & LMP_EDR_ESCO_2M)
686 hdev->esco_type |= (ESCO_2EV3);
687
688 if (hdev->features[5] & LMP_EDR_ESCO_3M)
689 hdev->esco_type |= (ESCO_3EV3);
690
691 if (hdev->features[5] & LMP_EDR_3S_ESCO)
692 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
693
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200694 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
695 hdev->features[0], hdev->features[1],
696 hdev->features[2], hdev->features[3],
697 hdev->features[4], hdev->features[5],
698 hdev->features[6], hdev->features[7]);
699}
700
Andre Guedes971e3a42011-06-30 19:20:52 -0300701static void hci_cc_read_local_ext_features(struct hci_dev *hdev,
702 struct sk_buff *skb)
703{
704 struct hci_rp_read_local_ext_features *rp = (void *) skb->data;
705
706 BT_DBG("%s status 0x%x", hdev->name, rp->status);
707
708 if (rp->status)
709 return;
710
711 memcpy(hdev->extfeatures, rp->features, 8);
712
713 hci_req_complete(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, rp->status);
714}
715
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200716static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
717{
718 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
719
720 BT_DBG("%s status 0x%x", hdev->name, rp->status);
721
722 if (rp->status)
723 return;
724
725 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
726 hdev->sco_mtu = rp->sco_mtu;
727 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
728 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
729
730 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
731 hdev->sco_mtu = 64;
732 hdev->sco_pkts = 8;
733 }
734
735 hdev->acl_cnt = hdev->acl_pkts;
736 hdev->sco_cnt = hdev->sco_pkts;
737
738 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
739 hdev->acl_mtu, hdev->acl_pkts,
740 hdev->sco_mtu, hdev->sco_pkts);
741}
742
743static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
744{
745 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
746
747 BT_DBG("%s status 0x%x", hdev->name, rp->status);
748
749 if (!rp->status)
750 bacpy(&hdev->bdaddr, &rp->bdaddr);
751
Johan Hedberg23bb5762010-12-21 23:01:27 +0200752 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
753}
754
755static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
756{
757 __u8 status = *((__u8 *) skb->data);
758
759 BT_DBG("%s status 0x%x", hdev->name, status);
760
761 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200762}
763
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +0300764static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
765 struct sk_buff *skb)
766{
767 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
768
769 BT_DBG("%s status 0x%x", hdev->name, rp->status);
770
771 if (rp->status)
772 return;
773
774 hdev->amp_status = rp->amp_status;
775 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
776 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
777 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
778 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
779 hdev->amp_type = rp->amp_type;
780 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
781 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
782 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
783 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
784
785 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
786}
787
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200788static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
789 struct sk_buff *skb)
790{
791 __u8 status = *((__u8 *) skb->data);
792
793 BT_DBG("%s status 0x%x", hdev->name, status);
794
795 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
796}
797
Johan Hedbergd5859e22011-01-25 01:19:58 +0200798static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
799{
800 __u8 status = *((__u8 *) skb->data);
801
802 BT_DBG("%s status 0x%x", hdev->name, status);
803
804 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
805}
806
807static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
808 struct sk_buff *skb)
809{
810 __u8 status = *((__u8 *) skb->data);
811
812 BT_DBG("%s status 0x%x", hdev->name, status);
813
814 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
815}
816
817static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
818 struct sk_buff *skb)
819{
820 __u8 status = *((__u8 *) skb->data);
821
822 BT_DBG("%s status 0x%x", hdev->name, status);
823
824 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
825}
826
827static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
828{
829 __u8 status = *((__u8 *) skb->data);
830
831 BT_DBG("%s status 0x%x", hdev->name, status);
832
833 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
834}
835
Johan Hedberg980e1a52011-01-22 06:10:07 +0200836static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
837{
838 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
839 struct hci_cp_pin_code_reply *cp;
840 struct hci_conn *conn;
841
842 BT_DBG("%s status 0x%x", hdev->name, rp->status);
843
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200844 hci_dev_lock(hdev);
845
Johan Hedberg980e1a52011-01-22 06:10:07 +0200846 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200847 mgmt_pin_code_reply_complete(hdev, &rp->bdaddr, rp->status);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200848
849 if (rp->status != 0)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200850 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200851
852 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
853 if (!cp)
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200854 goto unlock;
Johan Hedberg980e1a52011-01-22 06:10:07 +0200855
856 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
857 if (conn)
858 conn->pin_length = cp->pin_len;
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200859
860unlock:
861 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200862}
863
864static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
865{
866 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
867
868 BT_DBG("%s status 0x%x", hdev->name, rp->status);
869
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200870 hci_dev_lock(hdev);
871
Johan Hedberg980e1a52011-01-22 06:10:07 +0200872 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200873 mgmt_pin_code_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberg980e1a52011-01-22 06:10:07 +0200874 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200875
876 hci_dev_unlock(hdev);
Johan Hedberg980e1a52011-01-22 06:10:07 +0200877}
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200878
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300879static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
880 struct sk_buff *skb)
881{
882 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
883
884 BT_DBG("%s status 0x%x", hdev->name, rp->status);
885
886 if (rp->status)
887 return;
888
889 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
890 hdev->le_pkts = rp->le_max_pkt;
891
892 hdev->le_cnt = hdev->le_pkts;
893
894 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
895
896 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
897}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200898
Johan Hedberga5c29682011-02-19 12:05:57 -0300899static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
900{
901 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
902
903 BT_DBG("%s status 0x%x", hdev->name, rp->status);
904
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200905 hci_dev_lock(hdev);
906
Johan Hedberga5c29682011-02-19 12:05:57 -0300907 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200908 mgmt_user_confirm_reply_complete(hdev, &rp->bdaddr,
Johan Hedberga5c29682011-02-19 12:05:57 -0300909 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200910
911 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300912}
913
914static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
915 struct sk_buff *skb)
916{
917 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
918
919 BT_DBG("%s status 0x%x", hdev->name, rp->status);
920
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200921 hci_dev_lock(hdev);
922
Johan Hedberga5c29682011-02-19 12:05:57 -0300923 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +0200924 mgmt_user_confirm_neg_reply_complete(hdev, &rp->bdaddr,
Johan Hedberga5c29682011-02-19 12:05:57 -0300925 rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200926
927 hci_dev_unlock(hdev);
Johan Hedberga5c29682011-02-19 12:05:57 -0300928}
929
Szymon Jancc35938b2011-03-22 13:12:21 +0100930static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
931 struct sk_buff *skb)
932{
933 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
934
935 BT_DBG("%s status 0x%x", hdev->name, rp->status);
936
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200937 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +0200938 mgmt_read_local_oob_data_reply_complete(hdev, rp->hash,
Szymon Jancc35938b2011-03-22 13:12:21 +0100939 rp->randomizer, rp->status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +0200940 hci_dev_unlock(hdev);
Szymon Jancc35938b2011-03-22 13:12:21 +0100941}
942
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300943static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
944 struct sk_buff *skb)
945{
946 struct hci_cp_le_set_scan_enable *cp;
947 __u8 status = *((__u8 *) skb->data);
948
949 BT_DBG("%s status 0x%x", hdev->name, status);
950
951 if (status)
952 return;
953
954 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
955 if (!cp)
956 return;
957
Andre Guedes35815082011-05-26 16:23:53 -0300958 if (cp->enable == 0x01) {
959 del_timer(&hdev->adv_timer);
Andre Guedesa8f13c82011-09-09 18:56:24 -0300960
961 hci_dev_lock(hdev);
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300962 hci_adv_entries_clear(hdev);
Andre Guedesa8f13c82011-09-09 18:56:24 -0300963 hci_dev_unlock(hdev);
Andre Guedes35815082011-05-26 16:23:53 -0300964 } else if (cp->enable == 0x00) {
965 mod_timer(&hdev->adv_timer, jiffies + ADV_CLEAR_TIMEOUT);
966 }
Andre Guedeseb9d91f2011-05-26 16:23:52 -0300967}
968
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -0300969static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
970{
971 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
972
973 BT_DBG("%s status 0x%x", hdev->name, rp->status);
974
975 if (rp->status)
976 return;
977
978 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
979}
980
981static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
982{
983 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
984
985 BT_DBG("%s status 0x%x", hdev->name, rp->status);
986
987 if (rp->status)
988 return;
989
990 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
991}
992
Andre Guedesf9b49302011-06-30 19:20:53 -0300993static inline void hci_cc_write_le_host_supported(struct hci_dev *hdev,
994 struct sk_buff *skb)
995{
996 struct hci_cp_read_local_ext_features cp;
997 __u8 status = *((__u8 *) skb->data);
998
999 BT_DBG("%s status 0x%x", hdev->name, status);
1000
1001 if (status)
1002 return;
1003
1004 cp.page = 0x01;
1005 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_EXT_FEATURES, sizeof(cp), &cp);
1006}
1007
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001008static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
1009{
1010 BT_DBG("%s status 0x%x", hdev->name, status);
1011
1012 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +02001013 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001014 hci_conn_check_pending(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001015 hci_dev_lock(hdev);
Johan Hedberg164a6e72011-11-01 17:06:44 +02001016 if (test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +02001017 mgmt_inquiry_failed(hdev, status);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001018 hci_dev_unlock(hdev);
Johan Hedberg314b2382011-04-27 10:29:57 -04001019 return;
1020 }
1021
Andre Guedes89352e72011-11-04 14:16:53 -03001022 set_bit(HCI_INQUIRY, &hdev->flags);
1023
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001024 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001025 mgmt_discovering(hdev, 1);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001026 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001027}
1028
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
1030{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001031 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001034 BT_DBG("%s status 0x%x", hdev->name, status);
1035
1036 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001037 if (!cp)
1038 return;
1039
1040 hci_dev_lock(hdev);
1041
1042 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1043
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001044 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045
1046 if (status) {
1047 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001048 if (status != 0x0c || conn->attempt > 2) {
1049 conn->state = BT_CLOSED;
1050 hci_proto_connect_cfm(conn, status);
1051 hci_conn_del(conn);
1052 } else
1053 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 }
1055 } else {
1056 if (!conn) {
1057 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
1058 if (conn) {
1059 conn->out = 1;
1060 conn->link_mode |= HCI_LM_MASTER;
1061 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001062 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001063 }
1064 }
1065
1066 hci_dev_unlock(hdev);
1067}
1068
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001069static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001071 struct hci_cp_add_sco *cp;
1072 struct hci_conn *acl, *sco;
1073 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001075 BT_DBG("%s status 0x%x", hdev->name, status);
1076
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001077 if (!status)
1078 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001079
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001080 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1081 if (!cp)
1082 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001083
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001084 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001085
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001086 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001087
1088 hci_dev_lock(hdev);
1089
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001090 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001091 if (acl) {
1092 sco = acl->link;
1093 if (sco) {
1094 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001095
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001096 hci_proto_connect_cfm(sco, status);
1097 hci_conn_del(sco);
1098 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001099 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001100
1101 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001102}
1103
Marcel Holtmannf8558552008-07-14 20:13:49 +02001104static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1105{
1106 struct hci_cp_auth_requested *cp;
1107 struct hci_conn *conn;
1108
1109 BT_DBG("%s status 0x%x", hdev->name, status);
1110
1111 if (!status)
1112 return;
1113
1114 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1115 if (!cp)
1116 return;
1117
1118 hci_dev_lock(hdev);
1119
1120 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1121 if (conn) {
1122 if (conn->state == BT_CONFIG) {
1123 hci_proto_connect_cfm(conn, status);
1124 hci_conn_put(conn);
1125 }
1126 }
1127
1128 hci_dev_unlock(hdev);
1129}
1130
1131static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1132{
1133 struct hci_cp_set_conn_encrypt *cp;
1134 struct hci_conn *conn;
1135
1136 BT_DBG("%s status 0x%x", hdev->name, status);
1137
1138 if (!status)
1139 return;
1140
1141 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1142 if (!cp)
1143 return;
1144
1145 hci_dev_lock(hdev);
1146
1147 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1148 if (conn) {
1149 if (conn->state == BT_CONFIG) {
1150 hci_proto_connect_cfm(conn, status);
1151 hci_conn_put(conn);
1152 }
1153 }
1154
1155 hci_dev_unlock(hdev);
1156}
1157
Johan Hedberg127178d2010-11-18 22:22:29 +02001158static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001159 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001160{
Johan Hedberg392599b2010-11-18 22:22:28 +02001161 if (conn->state != BT_CONFIG || !conn->out)
1162 return 0;
1163
Johan Hedberg765c2a92011-01-19 12:06:52 +05301164 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001165 return 0;
1166
1167 /* Only request authentication for SSP connections or non-SSP
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001168 * devices with sec_level HIGH or if MITM protection is requested */
Johan Hedberg392599b2010-11-18 22:22:28 +02001169 if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
Vinicius Costa Gomese9bf2bf2011-09-02 14:51:20 -03001170 conn->pending_sec_level != BT_SECURITY_HIGH &&
1171 !(conn->auth_type & 0x01))
Johan Hedberg392599b2010-11-18 22:22:28 +02001172 return 0;
1173
Johan Hedberg392599b2010-11-18 22:22:28 +02001174 return 1;
1175}
1176
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001177static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1178{
Johan Hedberg127178d2010-11-18 22:22:29 +02001179 struct hci_cp_remote_name_req *cp;
1180 struct hci_conn *conn;
1181
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001182 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001183
1184 /* If successful wait for the name req complete event before
1185 * checking for the need to do authentication */
1186 if (!status)
1187 return;
1188
1189 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1190 if (!cp)
1191 return;
1192
1193 hci_dev_lock(hdev);
1194
1195 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Johan Hedberg79c6c702011-04-28 11:28:55 -07001196 if (!conn)
1197 goto unlock;
1198
1199 if (!hci_outgoing_auth_needed(hdev, conn))
1200 goto unlock;
1201
1202 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001203 struct hci_cp_auth_requested cp;
1204 cp.handle = __cpu_to_le16(conn->handle);
1205 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1206 }
1207
Johan Hedberg79c6c702011-04-28 11:28:55 -07001208unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001209 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001210}
1211
Marcel Holtmann769be972008-07-14 20:13:49 +02001212static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1213{
1214 struct hci_cp_read_remote_features *cp;
1215 struct hci_conn *conn;
1216
1217 BT_DBG("%s status 0x%x", hdev->name, status);
1218
1219 if (!status)
1220 return;
1221
1222 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1223 if (!cp)
1224 return;
1225
1226 hci_dev_lock(hdev);
1227
1228 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1229 if (conn) {
1230 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001231 hci_proto_connect_cfm(conn, status);
1232 hci_conn_put(conn);
1233 }
1234 }
1235
1236 hci_dev_unlock(hdev);
1237}
1238
1239static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1240{
1241 struct hci_cp_read_remote_ext_features *cp;
1242 struct hci_conn *conn;
1243
1244 BT_DBG("%s status 0x%x", hdev->name, status);
1245
1246 if (!status)
1247 return;
1248
1249 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1250 if (!cp)
1251 return;
1252
1253 hci_dev_lock(hdev);
1254
1255 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1256 if (conn) {
1257 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001258 hci_proto_connect_cfm(conn, status);
1259 hci_conn_put(conn);
1260 }
1261 }
1262
1263 hci_dev_unlock(hdev);
1264}
1265
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001266static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1267{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001268 struct hci_cp_setup_sync_conn *cp;
1269 struct hci_conn *acl, *sco;
1270 __u16 handle;
1271
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001272 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001273
1274 if (!status)
1275 return;
1276
1277 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1278 if (!cp)
1279 return;
1280
1281 handle = __le16_to_cpu(cp->handle);
1282
1283 BT_DBG("%s handle %d", hdev->name, handle);
1284
1285 hci_dev_lock(hdev);
1286
1287 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001288 if (acl) {
1289 sco = acl->link;
1290 if (sco) {
1291 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001292
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001293 hci_proto_connect_cfm(sco, status);
1294 hci_conn_del(sco);
1295 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001296 }
1297
1298 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001299}
1300
1301static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1302{
1303 struct hci_cp_sniff_mode *cp;
1304 struct hci_conn *conn;
1305
1306 BT_DBG("%s status 0x%x", hdev->name, status);
1307
1308 if (!status)
1309 return;
1310
1311 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1312 if (!cp)
1313 return;
1314
1315 hci_dev_lock(hdev);
1316
1317 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001318 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001319 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1320
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001321 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1322 hci_sco_setup(conn, status);
1323 }
1324
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001325 hci_dev_unlock(hdev);
1326}
1327
1328static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1329{
1330 struct hci_cp_exit_sniff_mode *cp;
1331 struct hci_conn *conn;
1332
1333 BT_DBG("%s status 0x%x", hdev->name, status);
1334
1335 if (!status)
1336 return;
1337
1338 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1339 if (!cp)
1340 return;
1341
1342 hci_dev_lock(hdev);
1343
1344 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001345 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001346 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1347
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001348 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1349 hci_sco_setup(conn, status);
1350 }
1351
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001352 hci_dev_unlock(hdev);
1353}
1354
Ville Tervofcd89c02011-02-10 22:38:47 -03001355static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1356{
1357 struct hci_cp_le_create_conn *cp;
1358 struct hci_conn *conn;
1359
1360 BT_DBG("%s status 0x%x", hdev->name, status);
1361
1362 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1363 if (!cp)
1364 return;
1365
1366 hci_dev_lock(hdev);
1367
1368 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1369
1370 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1371 conn);
1372
1373 if (status) {
1374 if (conn && conn->state == BT_CONNECT) {
1375 conn->state = BT_CLOSED;
1376 hci_proto_connect_cfm(conn, status);
1377 hci_conn_del(conn);
1378 }
1379 } else {
1380 if (!conn) {
1381 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
Andre Guedes29b79882011-05-31 14:20:54 -03001382 if (conn) {
1383 conn->dst_type = cp->peer_addr_type;
Ville Tervofcd89c02011-02-10 22:38:47 -03001384 conn->out = 1;
Andre Guedes29b79882011-05-31 14:20:54 -03001385 } else {
Ville Tervofcd89c02011-02-10 22:38:47 -03001386 BT_ERR("No memory for new connection");
Andre Guedes29b79882011-05-31 14:20:54 -03001387 }
Ville Tervofcd89c02011-02-10 22:38:47 -03001388 }
1389 }
1390
1391 hci_dev_unlock(hdev);
1392}
1393
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03001394static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1395{
1396 BT_DBG("%s status 0x%x", hdev->name, status);
1397}
1398
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001399static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1400{
1401 __u8 status = *((__u8 *) skb->data);
1402
1403 BT_DBG("%s status %d", hdev->name, status);
1404
Johan Hedberg23bb5762010-12-21 23:01:27 +02001405 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001406
1407 hci_conn_check_pending(hdev);
Andre Guedes89352e72011-11-04 14:16:53 -03001408
1409 if (!test_and_clear_bit(HCI_INQUIRY, &hdev->flags))
1410 return;
1411
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001412 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001413 mgmt_discovering(hdev, 0);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001414 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001415}
1416
Linus Torvalds1da177e2005-04-16 15:20:36 -07001417static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1418{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001419 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001420 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421 int num_rsp = *((__u8 *) skb->data);
1422
1423 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1424
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001425 if (!num_rsp)
1426 return;
1427
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001429
Johan Hedberge17acd42011-03-30 23:57:16 +03001430 for (; num_rsp; num_rsp--, info++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001431 bacpy(&data.bdaddr, &info->bdaddr);
1432 data.pscan_rep_mode = info->pscan_rep_mode;
1433 data.pscan_period_mode = info->pscan_period_mode;
1434 data.pscan_mode = info->pscan_mode;
1435 memcpy(data.dev_class, info->dev_class, 3);
1436 data.clock_offset = info->clock_offset;
1437 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001438 data.ssp_mode = 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001439 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg744cf192011-11-08 20:40:14 +02001440 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK,
Johan Hedberg4c659c32011-11-07 23:13:39 +02001441 info->dev_class, 0, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001442 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001443
Linus Torvalds1da177e2005-04-16 15:20:36 -07001444 hci_dev_unlock(hdev);
1445}
1446
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001447static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001448{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001449 struct hci_ev_conn_complete *ev = (void *) skb->data;
1450 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001451
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001452 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001453
Linus Torvalds1da177e2005-04-16 15:20:36 -07001454 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001455
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001456 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001457 if (!conn) {
1458 if (ev->link_type != SCO_LINK)
1459 goto unlock;
1460
1461 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1462 if (!conn)
1463 goto unlock;
1464
1465 conn->type = SCO_LINK;
1466 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001467
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001468 if (!ev->status) {
1469 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001470
1471 if (conn->type == ACL_LINK) {
1472 conn->state = BT_CONFIG;
1473 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001474 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg744cf192011-11-08 20:40:14 +02001475 mgmt_connected(hdev, &ev->bdaddr, conn->type);
Marcel Holtmann769be972008-07-14 20:13:49 +02001476 } else
1477 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001478
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001479 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001480 hci_conn_add_sysfs(conn);
1481
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001482 if (test_bit(HCI_AUTH, &hdev->flags))
1483 conn->link_mode |= HCI_LM_AUTH;
1484
1485 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1486 conn->link_mode |= HCI_LM_ENCRYPT;
1487
1488 /* Get remote features */
1489 if (conn->type == ACL_LINK) {
1490 struct hci_cp_read_remote_features cp;
1491 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001492 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1493 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001494 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001495
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001496 /* Set packet type for incoming connection */
Marcel Holtmanna8746412008-07-14 20:13:46 +02001497 if (!conn->out && hdev->hci_ver < 3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001498 struct hci_cp_change_conn_ptype cp;
1499 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001500 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1501 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1502 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001503 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001504 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001505 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001506 if (conn->type == ACL_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001507 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type,
Johan Hedberg4c659c32011-11-07 23:13:39 +02001508 ev->status);
Johan Hedberg17d5c042011-01-22 06:09:08 +02001509 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001510
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001511 if (conn->type == ACL_LINK)
1512 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001513
Marcel Holtmann769be972008-07-14 20:13:49 +02001514 if (ev->status) {
1515 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001516 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001517 } else if (ev->link_type != ACL_LINK)
1518 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001519
1520unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001521 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001522
1523 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524}
1525
Linus Torvalds1da177e2005-04-16 15:20:36 -07001526static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1527{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001528 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529 int mask = hdev->link_mode;
1530
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001531 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1532 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533
1534 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1535
Szymon Janc138d22e2011-02-17 16:44:23 +01001536 if ((mask & HCI_LM_ACCEPT) &&
1537 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001539 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001540 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541
1542 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001543
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001544 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1545 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001546 memcpy(ie->data.dev_class, ev->dev_class, 3);
1547
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1549 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001550 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1551 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001552 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553 hci_dev_unlock(hdev);
1554 return;
1555 }
1556 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001557
Linus Torvalds1da177e2005-04-16 15:20:36 -07001558 memcpy(conn->dev_class, ev->dev_class, 3);
1559 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001560
Linus Torvalds1da177e2005-04-16 15:20:36 -07001561 hci_dev_unlock(hdev);
1562
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001563 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1564 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001565
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001566 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001568 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1569 cp.role = 0x00; /* Become master */
1570 else
1571 cp.role = 0x01; /* Remain slave */
1572
1573 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1574 sizeof(cp), &cp);
1575 } else {
1576 struct hci_cp_accept_sync_conn_req cp;
1577
1578 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001579 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001580
1581 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1582 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1583 cp.max_latency = cpu_to_le16(0xffff);
1584 cp.content_format = cpu_to_le16(hdev->voice_setting);
1585 cp.retrans_effort = 0xff;
1586
1587 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1588 sizeof(cp), &cp);
1589 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001590 } else {
1591 /* Connection rejected */
1592 struct hci_cp_reject_conn_req cp;
1593
1594 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02001595 cp.reason = HCI_ERROR_REJ_BAD_ADDR;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001596 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001597 }
1598}
1599
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1601{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001602 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001603 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604
1605 BT_DBG("%s status %d", hdev->name, ev->status);
1606
Johan Hedberg8962ee72011-01-20 12:40:27 +02001607 if (ev->status) {
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001608 hci_dev_lock(hdev);
Johan Hedberg744cf192011-11-08 20:40:14 +02001609 mgmt_disconnect_failed(hdev);
Johan Hedberg56e5cb82011-11-08 20:40:16 +02001610 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611 return;
Johan Hedberg8962ee72011-01-20 12:40:27 +02001612 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613
1614 hci_dev_lock(hdev);
1615
Marcel Holtmann04837f62006-07-03 10:02:33 +02001616 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001617 if (!conn)
1618 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001619
Johan Hedbergf7520542011-01-20 12:34:39 +02001620 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001621
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03001622 if (conn->type == ACL_LINK || conn->type == LE_LINK)
Johan Hedberg744cf192011-11-08 20:40:14 +02001623 mgmt_disconnected(hdev, &conn->dst, conn->type);
Johan Hedbergf7520542011-01-20 12:34:39 +02001624
1625 hci_proto_disconn_cfm(conn, ev->reason);
1626 hci_conn_del(conn);
1627
1628unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 hci_dev_unlock(hdev);
1630}
1631
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001632static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1633{
1634 struct hci_ev_auth_complete *ev = (void *) skb->data;
1635 struct hci_conn *conn;
1636
1637 BT_DBG("%s status %d", hdev->name, ev->status);
1638
1639 hci_dev_lock(hdev);
1640
1641 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001642 if (!conn)
1643 goto unlock;
1644
1645 if (!ev->status) {
1646 if (!(conn->ssp_mode > 0 && hdev->ssp_mode > 0) &&
1647 test_bit(HCI_CONN_REAUTH_PEND, &conn->pend)) {
1648 BT_INFO("re-auth of legacy device is not possible.");
Johan Hedberg2a611692011-02-19 12:06:00 -03001649 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001650 conn->link_mode |= HCI_LM_AUTH;
1651 conn->sec_level = conn->pending_sec_level;
Johan Hedberg2a611692011-02-19 12:06:00 -03001652 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001653 } else {
Johan Hedberg744cf192011-11-08 20:40:14 +02001654 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001655 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001656
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001657 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1658 clear_bit(HCI_CONN_REAUTH_PEND, &conn->pend);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001659
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001660 if (conn->state == BT_CONFIG) {
1661 if (!ev->status && hdev->ssp_mode > 0 && conn->ssp_mode > 0) {
1662 struct hci_cp_set_conn_encrypt cp;
1663 cp.handle = ev->handle;
1664 cp.encrypt = 0x01;
1665 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1666 &cp);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001667 } else {
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001668 conn->state = BT_CONNECTED;
1669 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001670 hci_conn_put(conn);
1671 }
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001672 } else {
1673 hci_auth_cfm(conn, ev->status);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001674
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001675 hci_conn_hold(conn);
1676 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1677 hci_conn_put(conn);
1678 }
1679
1680 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1681 if (!ev->status) {
1682 struct hci_cp_set_conn_encrypt cp;
1683 cp.handle = ev->handle;
1684 cp.encrypt = 0x01;
1685 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp),
1686 &cp);
1687 } else {
1688 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1689 hci_encrypt_cfm(conn, ev->status, 0x00);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001690 }
1691 }
1692
Waldemar Rymarkiewiczd7556e22011-05-31 15:49:26 +02001693unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001694 hci_dev_unlock(hdev);
1695}
1696
1697static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1698{
Johan Hedberg127178d2010-11-18 22:22:29 +02001699 struct hci_ev_remote_name *ev = (void *) skb->data;
1700 struct hci_conn *conn;
1701
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001702 BT_DBG("%s", hdev->name);
1703
1704 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001705
1706 hci_dev_lock(hdev);
1707
Johan Hedberga88a9652011-03-30 13:18:12 +03001708 if (ev->status == 0 && test_bit(HCI_MGMT, &hdev->flags))
Johan Hedberg744cf192011-11-08 20:40:14 +02001709 mgmt_remote_name(hdev, &ev->bdaddr, ev->name);
Johan Hedberga88a9652011-03-30 13:18:12 +03001710
Johan Hedberg127178d2010-11-18 22:22:29 +02001711 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg79c6c702011-04-28 11:28:55 -07001712 if (!conn)
1713 goto unlock;
1714
1715 if (!hci_outgoing_auth_needed(hdev, conn))
1716 goto unlock;
1717
1718 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001719 struct hci_cp_auth_requested cp;
1720 cp.handle = __cpu_to_le16(conn->handle);
1721 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1722 }
1723
Johan Hedberg79c6c702011-04-28 11:28:55 -07001724unlock:
Johan Hedberg127178d2010-11-18 22:22:29 +02001725 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001726}
1727
1728static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1729{
1730 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1731 struct hci_conn *conn;
1732
1733 BT_DBG("%s status %d", hdev->name, ev->status);
1734
1735 hci_dev_lock(hdev);
1736
1737 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1738 if (conn) {
1739 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001740 if (ev->encrypt) {
1741 /* Encryption implies authentication */
1742 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001743 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomesda85e5e2011-06-09 18:50:53 -03001744 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001745 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001746 conn->link_mode &= ~HCI_LM_ENCRYPT;
1747 }
1748
1749 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1750
Marcel Holtmannf8558552008-07-14 20:13:49 +02001751 if (conn->state == BT_CONFIG) {
1752 if (!ev->status)
1753 conn->state = BT_CONNECTED;
1754
1755 hci_proto_connect_cfm(conn, ev->status);
1756 hci_conn_put(conn);
1757 } else
1758 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001759 }
1760
1761 hci_dev_unlock(hdev);
1762}
1763
1764static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1765{
1766 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1767 struct hci_conn *conn;
1768
1769 BT_DBG("%s status %d", hdev->name, ev->status);
1770
1771 hci_dev_lock(hdev);
1772
1773 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1774 if (conn) {
1775 if (!ev->status)
1776 conn->link_mode |= HCI_LM_SECURE;
1777
1778 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1779
1780 hci_key_change_cfm(conn, ev->status);
1781 }
1782
1783 hci_dev_unlock(hdev);
1784}
1785
1786static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1787{
1788 struct hci_ev_remote_features *ev = (void *) skb->data;
1789 struct hci_conn *conn;
1790
1791 BT_DBG("%s status %d", hdev->name, ev->status);
1792
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001793 hci_dev_lock(hdev);
1794
1795 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001796 if (!conn)
1797 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001798
Johan Hedbergccd556f2010-11-10 17:11:51 +02001799 if (!ev->status)
1800 memcpy(conn->features, ev->features, 8);
1801
1802 if (conn->state != BT_CONFIG)
1803 goto unlock;
1804
1805 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1806 struct hci_cp_read_remote_ext_features cp;
1807 cp.handle = ev->handle;
1808 cp.page = 0x01;
1809 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001810 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001811 goto unlock;
1812 }
1813
Johan Hedberg127178d2010-11-18 22:22:29 +02001814 if (!ev->status) {
1815 struct hci_cp_remote_name_req cp;
1816 memset(&cp, 0, sizeof(cp));
1817 bacpy(&cp.bdaddr, &conn->dst);
1818 cp.pscan_rep_mode = 0x02;
1819 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1820 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001821
Johan Hedberg127178d2010-11-18 22:22:29 +02001822 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001823 conn->state = BT_CONNECTED;
1824 hci_proto_connect_cfm(conn, ev->status);
1825 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001826 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001827
Johan Hedbergccd556f2010-11-10 17:11:51 +02001828unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001829 hci_dev_unlock(hdev);
1830}
1831
1832static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
1833{
1834 BT_DBG("%s", hdev->name);
1835}
1836
1837static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1838{
1839 BT_DBG("%s", hdev->name);
1840}
1841
1842static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1843{
1844 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1845 __u16 opcode;
1846
1847 skb_pull(skb, sizeof(*ev));
1848
1849 opcode = __le16_to_cpu(ev->opcode);
1850
1851 switch (opcode) {
1852 case HCI_OP_INQUIRY_CANCEL:
1853 hci_cc_inquiry_cancel(hdev, skb);
1854 break;
1855
1856 case HCI_OP_EXIT_PERIODIC_INQ:
1857 hci_cc_exit_periodic_inq(hdev, skb);
1858 break;
1859
1860 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1861 hci_cc_remote_name_req_cancel(hdev, skb);
1862 break;
1863
1864 case HCI_OP_ROLE_DISCOVERY:
1865 hci_cc_role_discovery(hdev, skb);
1866 break;
1867
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001868 case HCI_OP_READ_LINK_POLICY:
1869 hci_cc_read_link_policy(hdev, skb);
1870 break;
1871
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001872 case HCI_OP_WRITE_LINK_POLICY:
1873 hci_cc_write_link_policy(hdev, skb);
1874 break;
1875
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001876 case HCI_OP_READ_DEF_LINK_POLICY:
1877 hci_cc_read_def_link_policy(hdev, skb);
1878 break;
1879
1880 case HCI_OP_WRITE_DEF_LINK_POLICY:
1881 hci_cc_write_def_link_policy(hdev, skb);
1882 break;
1883
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001884 case HCI_OP_RESET:
1885 hci_cc_reset(hdev, skb);
1886 break;
1887
1888 case HCI_OP_WRITE_LOCAL_NAME:
1889 hci_cc_write_local_name(hdev, skb);
1890 break;
1891
1892 case HCI_OP_READ_LOCAL_NAME:
1893 hci_cc_read_local_name(hdev, skb);
1894 break;
1895
1896 case HCI_OP_WRITE_AUTH_ENABLE:
1897 hci_cc_write_auth_enable(hdev, skb);
1898 break;
1899
1900 case HCI_OP_WRITE_ENCRYPT_MODE:
1901 hci_cc_write_encrypt_mode(hdev, skb);
1902 break;
1903
1904 case HCI_OP_WRITE_SCAN_ENABLE:
1905 hci_cc_write_scan_enable(hdev, skb);
1906 break;
1907
1908 case HCI_OP_READ_CLASS_OF_DEV:
1909 hci_cc_read_class_of_dev(hdev, skb);
1910 break;
1911
1912 case HCI_OP_WRITE_CLASS_OF_DEV:
1913 hci_cc_write_class_of_dev(hdev, skb);
1914 break;
1915
1916 case HCI_OP_READ_VOICE_SETTING:
1917 hci_cc_read_voice_setting(hdev, skb);
1918 break;
1919
1920 case HCI_OP_WRITE_VOICE_SETTING:
1921 hci_cc_write_voice_setting(hdev, skb);
1922 break;
1923
1924 case HCI_OP_HOST_BUFFER_SIZE:
1925 hci_cc_host_buffer_size(hdev, skb);
1926 break;
1927
Marcel Holtmann333140b2008-07-14 20:13:48 +02001928 case HCI_OP_READ_SSP_MODE:
1929 hci_cc_read_ssp_mode(hdev, skb);
1930 break;
1931
1932 case HCI_OP_WRITE_SSP_MODE:
1933 hci_cc_write_ssp_mode(hdev, skb);
1934 break;
1935
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001936 case HCI_OP_READ_LOCAL_VERSION:
1937 hci_cc_read_local_version(hdev, skb);
1938 break;
1939
1940 case HCI_OP_READ_LOCAL_COMMANDS:
1941 hci_cc_read_local_commands(hdev, skb);
1942 break;
1943
1944 case HCI_OP_READ_LOCAL_FEATURES:
1945 hci_cc_read_local_features(hdev, skb);
1946 break;
1947
Andre Guedes971e3a42011-06-30 19:20:52 -03001948 case HCI_OP_READ_LOCAL_EXT_FEATURES:
1949 hci_cc_read_local_ext_features(hdev, skb);
1950 break;
1951
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001952 case HCI_OP_READ_BUFFER_SIZE:
1953 hci_cc_read_buffer_size(hdev, skb);
1954 break;
1955
1956 case HCI_OP_READ_BD_ADDR:
1957 hci_cc_read_bd_addr(hdev, skb);
1958 break;
1959
Johan Hedberg23bb5762010-12-21 23:01:27 +02001960 case HCI_OP_WRITE_CA_TIMEOUT:
1961 hci_cc_write_ca_timeout(hdev, skb);
1962 break;
1963
Andrei Emeltchenko928abaa2011-10-12 10:53:57 +03001964 case HCI_OP_READ_LOCAL_AMP_INFO:
1965 hci_cc_read_local_amp_info(hdev, skb);
1966 break;
1967
Johan Hedbergb0916ea2011-01-10 13:44:55 +02001968 case HCI_OP_DELETE_STORED_LINK_KEY:
1969 hci_cc_delete_stored_link_key(hdev, skb);
1970 break;
1971
Johan Hedbergd5859e22011-01-25 01:19:58 +02001972 case HCI_OP_SET_EVENT_MASK:
1973 hci_cc_set_event_mask(hdev, skb);
1974 break;
1975
1976 case HCI_OP_WRITE_INQUIRY_MODE:
1977 hci_cc_write_inquiry_mode(hdev, skb);
1978 break;
1979
1980 case HCI_OP_READ_INQ_RSP_TX_POWER:
1981 hci_cc_read_inq_rsp_tx_power(hdev, skb);
1982 break;
1983
1984 case HCI_OP_SET_EVENT_FLT:
1985 hci_cc_set_event_flt(hdev, skb);
1986 break;
1987
Johan Hedberg980e1a52011-01-22 06:10:07 +02001988 case HCI_OP_PIN_CODE_REPLY:
1989 hci_cc_pin_code_reply(hdev, skb);
1990 break;
1991
1992 case HCI_OP_PIN_CODE_NEG_REPLY:
1993 hci_cc_pin_code_neg_reply(hdev, skb);
1994 break;
1995
Szymon Jancc35938b2011-03-22 13:12:21 +01001996 case HCI_OP_READ_LOCAL_OOB_DATA:
1997 hci_cc_read_local_oob_data_reply(hdev, skb);
1998 break;
1999
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002000 case HCI_OP_LE_READ_BUFFER_SIZE:
2001 hci_cc_le_read_buffer_size(hdev, skb);
2002 break;
2003
Johan Hedberga5c29682011-02-19 12:05:57 -03002004 case HCI_OP_USER_CONFIRM_REPLY:
2005 hci_cc_user_confirm_reply(hdev, skb);
2006 break;
2007
2008 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2009 hci_cc_user_confirm_neg_reply(hdev, skb);
2010 break;
2011
Andre Guedeseb9d91f2011-05-26 16:23:52 -03002012 case HCI_OP_LE_SET_SCAN_ENABLE:
2013 hci_cc_le_set_scan_enable(hdev, skb);
2014 break;
2015
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002016 case HCI_OP_LE_LTK_REPLY:
2017 hci_cc_le_ltk_reply(hdev, skb);
2018 break;
2019
2020 case HCI_OP_LE_LTK_NEG_REPLY:
2021 hci_cc_le_ltk_neg_reply(hdev, skb);
2022 break;
2023
Andre Guedesf9b49302011-06-30 19:20:53 -03002024 case HCI_OP_WRITE_LE_HOST_SUPPORTED:
2025 hci_cc_write_le_host_supported(hdev, skb);
2026 break;
2027
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002028 default:
2029 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2030 break;
2031 }
2032
Ville Tervo6bd32322011-02-16 16:32:41 +02002033 if (ev->opcode != HCI_OP_NOP)
2034 del_timer(&hdev->cmd_timer);
2035
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002036 if (ev->ncmd) {
2037 atomic_set(&hdev->cmd_cnt, 1);
2038 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01002039 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002040 }
2041}
2042
2043static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2044{
2045 struct hci_ev_cmd_status *ev = (void *) skb->data;
2046 __u16 opcode;
2047
2048 skb_pull(skb, sizeof(*ev));
2049
2050 opcode = __le16_to_cpu(ev->opcode);
2051
2052 switch (opcode) {
2053 case HCI_OP_INQUIRY:
2054 hci_cs_inquiry(hdev, ev->status);
2055 break;
2056
2057 case HCI_OP_CREATE_CONN:
2058 hci_cs_create_conn(hdev, ev->status);
2059 break;
2060
2061 case HCI_OP_ADD_SCO:
2062 hci_cs_add_sco(hdev, ev->status);
2063 break;
2064
Marcel Holtmannf8558552008-07-14 20:13:49 +02002065 case HCI_OP_AUTH_REQUESTED:
2066 hci_cs_auth_requested(hdev, ev->status);
2067 break;
2068
2069 case HCI_OP_SET_CONN_ENCRYPT:
2070 hci_cs_set_conn_encrypt(hdev, ev->status);
2071 break;
2072
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002073 case HCI_OP_REMOTE_NAME_REQ:
2074 hci_cs_remote_name_req(hdev, ev->status);
2075 break;
2076
Marcel Holtmann769be972008-07-14 20:13:49 +02002077 case HCI_OP_READ_REMOTE_FEATURES:
2078 hci_cs_read_remote_features(hdev, ev->status);
2079 break;
2080
2081 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2082 hci_cs_read_remote_ext_features(hdev, ev->status);
2083 break;
2084
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002085 case HCI_OP_SETUP_SYNC_CONN:
2086 hci_cs_setup_sync_conn(hdev, ev->status);
2087 break;
2088
2089 case HCI_OP_SNIFF_MODE:
2090 hci_cs_sniff_mode(hdev, ev->status);
2091 break;
2092
2093 case HCI_OP_EXIT_SNIFF_MODE:
2094 hci_cs_exit_sniff_mode(hdev, ev->status);
2095 break;
2096
Johan Hedberg8962ee72011-01-20 12:40:27 +02002097 case HCI_OP_DISCONNECT:
2098 if (ev->status != 0)
Johan Hedberg744cf192011-11-08 20:40:14 +02002099 mgmt_disconnect_failed(hdev);
Johan Hedberg8962ee72011-01-20 12:40:27 +02002100 break;
2101
Ville Tervofcd89c02011-02-10 22:38:47 -03002102 case HCI_OP_LE_CREATE_CONN:
2103 hci_cs_le_create_conn(hdev, ev->status);
2104 break;
2105
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002106 case HCI_OP_LE_START_ENC:
2107 hci_cs_le_start_enc(hdev, ev->status);
2108 break;
2109
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002110 default:
2111 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2112 break;
2113 }
2114
Ville Tervo6bd32322011-02-16 16:32:41 +02002115 if (ev->opcode != HCI_OP_NOP)
2116 del_timer(&hdev->cmd_timer);
2117
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002118 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002119 atomic_set(&hdev->cmd_cnt, 1);
2120 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01002121 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002122 }
2123}
2124
2125static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2126{
2127 struct hci_ev_role_change *ev = (void *) skb->data;
2128 struct hci_conn *conn;
2129
2130 BT_DBG("%s status %d", hdev->name, ev->status);
2131
2132 hci_dev_lock(hdev);
2133
2134 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2135 if (conn) {
2136 if (!ev->status) {
2137 if (ev->role)
2138 conn->link_mode &= ~HCI_LM_MASTER;
2139 else
2140 conn->link_mode |= HCI_LM_MASTER;
2141 }
2142
2143 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
2144
2145 hci_role_switch_cfm(conn, ev->status, ev->role);
2146 }
2147
2148 hci_dev_unlock(hdev);
2149}
2150
Linus Torvalds1da177e2005-04-16 15:20:36 -07002151static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2152{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002153 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08002154 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155 int i;
2156
2157 skb_pull(skb, sizeof(*ev));
2158
2159 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2160
2161 if (skb->len < ev->num_hndl * 4) {
2162 BT_DBG("%s bad parameters", hdev->name);
2163 return;
2164 }
2165
2166 tasklet_disable(&hdev->tx_task);
2167
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08002168 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002169 struct hci_conn *conn;
2170 __u16 handle, count;
2171
Harvey Harrison83985312008-05-02 16:25:46 -07002172 handle = get_unaligned_le16(ptr++);
2173 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002174
2175 conn = hci_conn_hash_lookup_handle(hdev, handle);
2176 if (conn) {
2177 conn->sent -= count;
2178
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002179 if (conn->type == ACL_LINK) {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002180 hdev->acl_cnt += count;
2181 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002182 hdev->acl_cnt = hdev->acl_pkts;
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002183 } else if (conn->type == LE_LINK) {
2184 if (hdev->le_pkts) {
2185 hdev->le_cnt += count;
2186 if (hdev->le_cnt > hdev->le_pkts)
2187 hdev->le_cnt = hdev->le_pkts;
2188 } else {
2189 hdev->acl_cnt += count;
2190 if (hdev->acl_cnt > hdev->acl_pkts)
2191 hdev->acl_cnt = hdev->acl_pkts;
2192 }
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002193 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002194 hdev->sco_cnt += count;
2195 if (hdev->sco_cnt > hdev->sco_pkts)
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002196 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002197 }
2198 }
2199 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002200
Marcel Holtmannc78ae282009-11-18 01:02:54 +01002201 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002202
2203 tasklet_enable(&hdev->tx_task);
2204}
2205
Marcel Holtmann04837f62006-07-03 10:02:33 +02002206static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002207{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002208 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002209 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002210
2211 BT_DBG("%s status %d", hdev->name, ev->status);
2212
2213 hci_dev_lock(hdev);
2214
Marcel Holtmann04837f62006-07-03 10:02:33 +02002215 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2216 if (conn) {
2217 conn->mode = ev->mode;
2218 conn->interval = __le16_to_cpu(ev->interval);
2219
2220 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
2221 if (conn->mode == HCI_CM_ACTIVE)
2222 conn->power_save = 1;
2223 else
2224 conn->power_save = 0;
2225 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002226
2227 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
2228 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002229 }
2230
2231 hci_dev_unlock(hdev);
2232}
2233
Linus Torvalds1da177e2005-04-16 15:20:36 -07002234static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2235{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002236 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2237 struct hci_conn *conn;
2238
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002239 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002240
2241 hci_dev_lock(hdev);
2242
2243 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002244 if (!conn)
2245 goto unlock;
2246
2247 if (conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002248 hci_conn_hold(conn);
2249 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2250 hci_conn_put(conn);
2251 }
2252
Johan Hedberg03b555e2011-01-04 15:40:05 +02002253 if (!test_bit(HCI_PAIRABLE, &hdev->flags))
2254 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2255 sizeof(ev->bdaddr), &ev->bdaddr);
Johan Hedberg582fbe92011-04-28 11:28:58 -07002256 else if (test_bit(HCI_MGMT, &hdev->flags)) {
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002257 u8 secure;
2258
2259 if (conn->pending_sec_level == BT_SECURITY_HIGH)
2260 secure = 1;
2261 else
2262 secure = 0;
2263
Johan Hedberg744cf192011-11-08 20:40:14 +02002264 mgmt_pin_code_request(hdev, &ev->bdaddr, secure);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002265 }
Johan Hedberg980e1a52011-01-22 06:10:07 +02002266
Waldemar Rymarkiewiczb6f98042011-09-23 10:01:30 +02002267unlock:
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002268 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002269}
2270
Linus Torvalds1da177e2005-04-16 15:20:36 -07002271static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2272{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002273 struct hci_ev_link_key_req *ev = (void *) skb->data;
2274 struct hci_cp_link_key_reply cp;
2275 struct hci_conn *conn;
2276 struct link_key *key;
2277
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002278 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002279
2280 if (!test_bit(HCI_LINK_KEYS, &hdev->flags))
2281 return;
2282
2283 hci_dev_lock(hdev);
2284
2285 key = hci_find_link_key(hdev, &ev->bdaddr);
2286 if (!key) {
2287 BT_DBG("%s link key not found for %s", hdev->name,
2288 batostr(&ev->bdaddr));
2289 goto not_found;
2290 }
2291
2292 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2293 batostr(&ev->bdaddr));
2294
Waldemar Rymarkiewiczb6020ba2011-04-28 12:07:53 +02002295 if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) &&
2296 key->type == HCI_LK_DEBUG_COMBINATION) {
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002297 BT_DBG("%s ignoring debug key", hdev->name);
2298 goto not_found;
2299 }
2300
2301 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002302 if (conn) {
2303 if (key->type == HCI_LK_UNAUTH_COMBINATION &&
2304 conn->auth_type != 0xff &&
2305 (conn->auth_type & 0x01)) {
2306 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2307 goto not_found;
2308 }
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002309
Waldemar Rymarkiewicz60b83f52011-04-28 12:07:56 +02002310 if (key->type == HCI_LK_COMBINATION && key->pin_len < 16 &&
2311 conn->pending_sec_level == BT_SECURITY_HIGH) {
2312 BT_DBG("%s ignoring key unauthenticated for high \
2313 security", hdev->name);
2314 goto not_found;
2315 }
2316
2317 conn->key_type = key->type;
2318 conn->pin_length = key->pin_len;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002319 }
2320
2321 bacpy(&cp.bdaddr, &ev->bdaddr);
2322 memcpy(cp.link_key, key->val, 16);
2323
2324 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2325
2326 hci_dev_unlock(hdev);
2327
2328 return;
2329
2330not_found:
2331 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2332 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002333}
2334
Linus Torvalds1da177e2005-04-16 15:20:36 -07002335static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2336{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002337 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2338 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002339 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002340
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002341 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002342
2343 hci_dev_lock(hdev);
2344
2345 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2346 if (conn) {
2347 hci_conn_hold(conn);
2348 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002349 pin_len = conn->pin_length;
Waldemar Rymarkiewicz13d39312011-04-28 12:07:55 +02002350
2351 if (ev->key_type != HCI_LK_CHANGED_COMBINATION)
2352 conn->key_type = ev->key_type;
2353
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002354 hci_conn_put(conn);
2355 }
2356
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002357 if (test_bit(HCI_LINK_KEYS, &hdev->flags))
Johan Hedbergd25e28a2011-04-28 11:28:59 -07002358 hci_add_link_key(hdev, conn, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002359 ev->key_type, pin_len);
2360
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002361 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002362}
2363
Marcel Holtmann04837f62006-07-03 10:02:33 +02002364static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2365{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002366 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002367 struct hci_conn *conn;
2368
2369 BT_DBG("%s status %d", hdev->name, ev->status);
2370
2371 hci_dev_lock(hdev);
2372
2373 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002374 if (conn && !ev->status) {
2375 struct inquiry_entry *ie;
2376
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002377 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2378 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002379 ie->data.clock_offset = ev->clock_offset;
2380 ie->timestamp = jiffies;
2381 }
2382 }
2383
2384 hci_dev_unlock(hdev);
2385}
2386
Marcel Holtmanna8746412008-07-14 20:13:46 +02002387static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2388{
2389 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2390 struct hci_conn *conn;
2391
2392 BT_DBG("%s status %d", hdev->name, ev->status);
2393
2394 hci_dev_lock(hdev);
2395
2396 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2397 if (conn && !ev->status)
2398 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2399
2400 hci_dev_unlock(hdev);
2401}
2402
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002403static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2404{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002405 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002406 struct inquiry_entry *ie;
2407
2408 BT_DBG("%s", hdev->name);
2409
2410 hci_dev_lock(hdev);
2411
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002412 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2413 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002414 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2415 ie->timestamp = jiffies;
2416 }
2417
2418 hci_dev_unlock(hdev);
2419}
2420
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002421static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2422{
2423 struct inquiry_data data;
2424 int num_rsp = *((__u8 *) skb->data);
2425
2426 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2427
2428 if (!num_rsp)
2429 return;
2430
2431 hci_dev_lock(hdev);
2432
2433 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002434 struct inquiry_info_with_rssi_and_pscan_mode *info;
2435 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002436
Johan Hedberge17acd42011-03-30 23:57:16 +03002437 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002438 bacpy(&data.bdaddr, &info->bdaddr);
2439 data.pscan_rep_mode = info->pscan_rep_mode;
2440 data.pscan_period_mode = info->pscan_period_mode;
2441 data.pscan_mode = info->pscan_mode;
2442 memcpy(data.dev_class, info->dev_class, 3);
2443 data.clock_offset = info->clock_offset;
2444 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002445 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002446 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg744cf192011-11-08 20:40:14 +02002447 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK,
Johan Hedberge17acd42011-03-30 23:57:16 +03002448 info->dev_class, info->rssi,
2449 NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002450 }
2451 } else {
2452 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2453
Johan Hedberge17acd42011-03-30 23:57:16 +03002454 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002455 bacpy(&data.bdaddr, &info->bdaddr);
2456 data.pscan_rep_mode = info->pscan_rep_mode;
2457 data.pscan_period_mode = info->pscan_period_mode;
2458 data.pscan_mode = 0x00;
2459 memcpy(data.dev_class, info->dev_class, 3);
2460 data.clock_offset = info->clock_offset;
2461 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002462 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002463 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg744cf192011-11-08 20:40:14 +02002464 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK,
Johan Hedberge17acd42011-03-30 23:57:16 +03002465 info->dev_class, info->rssi,
2466 NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002467 }
2468 }
2469
2470 hci_dev_unlock(hdev);
2471}
2472
2473static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2474{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002475 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2476 struct hci_conn *conn;
2477
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002478 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002479
Marcel Holtmann41a96212008-07-14 20:13:48 +02002480 hci_dev_lock(hdev);
2481
2482 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002483 if (!conn)
2484 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002485
Johan Hedbergccd556f2010-11-10 17:11:51 +02002486 if (!ev->status && ev->page == 0x01) {
2487 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002488
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002489 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2490 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002491 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002492
Johan Hedbergccd556f2010-11-10 17:11:51 +02002493 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002494 }
2495
Johan Hedbergccd556f2010-11-10 17:11:51 +02002496 if (conn->state != BT_CONFIG)
2497 goto unlock;
2498
Johan Hedberg127178d2010-11-18 22:22:29 +02002499 if (!ev->status) {
2500 struct hci_cp_remote_name_req cp;
2501 memset(&cp, 0, sizeof(cp));
2502 bacpy(&cp.bdaddr, &conn->dst);
2503 cp.pscan_rep_mode = 0x02;
2504 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
2505 }
Johan Hedberg392599b2010-11-18 22:22:28 +02002506
Johan Hedberg127178d2010-11-18 22:22:29 +02002507 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002508 conn->state = BT_CONNECTED;
2509 hci_proto_connect_cfm(conn, ev->status);
2510 hci_conn_put(conn);
2511 }
2512
2513unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002514 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002515}
2516
2517static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2518{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002519 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2520 struct hci_conn *conn;
2521
2522 BT_DBG("%s status %d", hdev->name, ev->status);
2523
2524 hci_dev_lock(hdev);
2525
2526 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002527 if (!conn) {
2528 if (ev->link_type == ESCO_LINK)
2529 goto unlock;
2530
2531 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2532 if (!conn)
2533 goto unlock;
2534
2535 conn->type = SCO_LINK;
2536 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002537
Marcel Holtmann732547f2009-04-19 19:14:14 +02002538 switch (ev->status) {
2539 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002540 conn->handle = __le16_to_cpu(ev->handle);
2541 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002542
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002543 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002544 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002545 break;
2546
Stephen Coe705e5712010-02-16 11:29:44 -05002547 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002548 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002549 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002550 case 0x1f: /* Unspecified error */
2551 if (conn->out && conn->attempt < 2) {
2552 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2553 (hdev->esco_type & EDR_ESCO_MASK);
2554 hci_setup_sync(conn, conn->link->handle);
2555 goto unlock;
2556 }
2557 /* fall through */
2558
2559 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002560 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002561 break;
2562 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002563
2564 hci_proto_connect_cfm(conn, ev->status);
2565 if (ev->status)
2566 hci_conn_del(conn);
2567
2568unlock:
2569 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002570}
2571
2572static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2573{
2574 BT_DBG("%s", hdev->name);
2575}
2576
Marcel Holtmann04837f62006-07-03 10:02:33 +02002577static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2578{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002579 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002580
2581 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002582}
2583
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002584static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2585{
2586 struct inquiry_data data;
2587 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2588 int num_rsp = *((__u8 *) skb->data);
2589
2590 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2591
2592 if (!num_rsp)
2593 return;
2594
2595 hci_dev_lock(hdev);
2596
Johan Hedberge17acd42011-03-30 23:57:16 +03002597 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002598 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002599 data.pscan_rep_mode = info->pscan_rep_mode;
2600 data.pscan_period_mode = info->pscan_period_mode;
2601 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002602 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002603 data.clock_offset = info->clock_offset;
2604 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002605 data.ssp_mode = 0x01;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002606 hci_inquiry_cache_update(hdev, &data);
Johan Hedberg744cf192011-11-08 20:40:14 +02002607 mgmt_device_found(hdev, &info->bdaddr, ACL_LINK,
Johan Hedberg4c659c32011-11-07 23:13:39 +02002608 info->dev_class, info->rssi, info->data);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002609 }
2610
2611 hci_dev_unlock(hdev);
2612}
2613
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002614static inline u8 hci_get_auth_req(struct hci_conn *conn)
2615{
2616 /* If remote requests dedicated bonding follow that lead */
2617 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2618 /* If both remote and local IO capabilities allow MITM
2619 * protection then require it, otherwise don't */
2620 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2621 return 0x02;
2622 else
2623 return 0x03;
2624 }
2625
2626 /* If remote requests no-bonding follow that lead */
2627 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Waldemar Rymarkiewicz58797bf2011-04-28 12:07:58 +02002628 return conn->remote_auth | (conn->auth_type & 0x01);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002629
2630 return conn->auth_type;
2631}
2632
Marcel Holtmann04936842008-07-14 20:13:48 +02002633static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2634{
2635 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2636 struct hci_conn *conn;
2637
2638 BT_DBG("%s", hdev->name);
2639
2640 hci_dev_lock(hdev);
2641
2642 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002643 if (!conn)
2644 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002645
Johan Hedberg03b555e2011-01-04 15:40:05 +02002646 hci_conn_hold(conn);
2647
2648 if (!test_bit(HCI_MGMT, &hdev->flags))
2649 goto unlock;
2650
2651 if (test_bit(HCI_PAIRABLE, &hdev->flags) ||
2652 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002653 struct hci_cp_io_capability_reply cp;
2654
2655 bacpy(&cp.bdaddr, &ev->bdaddr);
2656 cp.capability = conn->io_capability;
Johan Hedberg7cbc9bd2011-04-28 11:29:04 -07002657 conn->auth_type = hci_get_auth_req(conn);
2658 cp.authentication = conn->auth_type;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002659
Szymon Jancce85ee12011-03-22 13:12:23 +01002660 if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
2661 hci_find_remote_oob_data(hdev, &conn->dst))
2662 cp.oob_data = 0x01;
2663 else
2664 cp.oob_data = 0x00;
2665
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002666 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
2667 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002668 } else {
2669 struct hci_cp_io_capability_neg_reply cp;
2670
2671 bacpy(&cp.bdaddr, &ev->bdaddr);
Andrei Emeltchenko9f5a0d72011-11-07 14:20:25 +02002672 cp.reason = HCI_ERROR_PAIRING_NOT_ALLOWED;
Johan Hedberg03b555e2011-01-04 15:40:05 +02002673
2674 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
2675 sizeof(cp), &cp);
2676 }
2677
2678unlock:
2679 hci_dev_unlock(hdev);
2680}
2681
2682static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
2683{
2684 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
2685 struct hci_conn *conn;
2686
2687 BT_DBG("%s", hdev->name);
2688
2689 hci_dev_lock(hdev);
2690
2691 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2692 if (!conn)
2693 goto unlock;
2694
Johan Hedberg03b555e2011-01-04 15:40:05 +02002695 conn->remote_cap = ev->capability;
2696 conn->remote_oob = ev->oob_data;
2697 conn->remote_auth = ev->authentication;
2698
2699unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002700 hci_dev_unlock(hdev);
2701}
2702
Johan Hedberga5c29682011-02-19 12:05:57 -03002703static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
2704 struct sk_buff *skb)
2705{
2706 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002707 int loc_mitm, rem_mitm, confirm_hint = 0;
Johan Hedberg7a828902011-04-28 11:28:53 -07002708 struct hci_conn *conn;
Johan Hedberga5c29682011-02-19 12:05:57 -03002709
2710 BT_DBG("%s", hdev->name);
2711
2712 hci_dev_lock(hdev);
2713
Johan Hedberg7a828902011-04-28 11:28:53 -07002714 if (!test_bit(HCI_MGMT, &hdev->flags))
2715 goto unlock;
Johan Hedberga5c29682011-02-19 12:05:57 -03002716
Johan Hedberg7a828902011-04-28 11:28:53 -07002717 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2718 if (!conn)
2719 goto unlock;
2720
2721 loc_mitm = (conn->auth_type & 0x01);
2722 rem_mitm = (conn->remote_auth & 0x01);
2723
2724 /* If we require MITM but the remote device can't provide that
2725 * (it has NoInputNoOutput) then reject the confirmation
2726 * request. The only exception is when we're dedicated bonding
2727 * initiators (connect_cfm_cb set) since then we always have the MITM
2728 * bit set. */
2729 if (!conn->connect_cfm_cb && loc_mitm && conn->remote_cap == 0x03) {
2730 BT_DBG("Rejecting request: remote device can't provide MITM");
2731 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_NEG_REPLY,
2732 sizeof(ev->bdaddr), &ev->bdaddr);
2733 goto unlock;
2734 }
2735
2736 /* If no side requires MITM protection; auto-accept */
2737 if ((!loc_mitm || conn->remote_cap == 0x03) &&
2738 (!rem_mitm || conn->io_capability == 0x03)) {
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002739
2740 /* If we're not the initiators request authorization to
2741 * proceed from user space (mgmt_user_confirm with
2742 * confirm_hint set to 1). */
2743 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
2744 BT_DBG("Confirming auto-accept as acceptor");
2745 confirm_hint = 1;
2746 goto confirm;
2747 }
2748
Johan Hedberg9f616562011-04-28 11:28:54 -07002749 BT_DBG("Auto-accept of user confirmation with %ums delay",
2750 hdev->auto_accept_delay);
2751
2752 if (hdev->auto_accept_delay > 0) {
2753 int delay = msecs_to_jiffies(hdev->auto_accept_delay);
2754 mod_timer(&conn->auto_accept_timer, jiffies + delay);
2755 goto unlock;
2756 }
2757
Johan Hedberg7a828902011-04-28 11:28:53 -07002758 hci_send_cmd(hdev, HCI_OP_USER_CONFIRM_REPLY,
2759 sizeof(ev->bdaddr), &ev->bdaddr);
2760 goto unlock;
2761 }
2762
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002763confirm:
Johan Hedberg744cf192011-11-08 20:40:14 +02002764 mgmt_user_confirm_request(hdev, &ev->bdaddr, ev->passkey,
Johan Hedberg55bc1a32011-04-28 11:28:56 -07002765 confirm_hint);
Johan Hedberg7a828902011-04-28 11:28:53 -07002766
2767unlock:
Johan Hedberga5c29682011-02-19 12:05:57 -03002768 hci_dev_unlock(hdev);
2769}
2770
Marcel Holtmann04936842008-07-14 20:13:48 +02002771static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2772{
2773 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
2774 struct hci_conn *conn;
2775
2776 BT_DBG("%s", hdev->name);
2777
2778 hci_dev_lock(hdev);
2779
2780 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03002781 if (!conn)
2782 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002783
Johan Hedberg2a611692011-02-19 12:06:00 -03002784 /* To avoid duplicate auth_failed events to user space we check
2785 * the HCI_CONN_AUTH_PEND flag which will be set if we
2786 * initiated the authentication. A traditional auth_complete
2787 * event gets always produced as initiator and is also mapped to
2788 * the mgmt_auth_failed event */
2789 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0)
Johan Hedberg744cf192011-11-08 20:40:14 +02002790 mgmt_auth_failed(hdev, &conn->dst, ev->status);
Johan Hedberg2a611692011-02-19 12:06:00 -03002791
2792 hci_conn_put(conn);
2793
2794unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002795 hci_dev_unlock(hdev);
2796}
2797
Marcel Holtmann41a96212008-07-14 20:13:48 +02002798static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2799{
2800 struct hci_ev_remote_host_features *ev = (void *) skb->data;
2801 struct inquiry_entry *ie;
2802
2803 BT_DBG("%s", hdev->name);
2804
2805 hci_dev_lock(hdev);
2806
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002807 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2808 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02002809 ie->data.ssp_mode = (ev->features[0] & 0x01);
2810
2811 hci_dev_unlock(hdev);
2812}
2813
Szymon Janc2763eda2011-03-22 13:12:22 +01002814static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
2815 struct sk_buff *skb)
2816{
2817 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
2818 struct oob_data *data;
2819
2820 BT_DBG("%s", hdev->name);
2821
2822 hci_dev_lock(hdev);
2823
Szymon Jance1ba1f12011-04-06 13:01:59 +02002824 if (!test_bit(HCI_MGMT, &hdev->flags))
2825 goto unlock;
2826
Szymon Janc2763eda2011-03-22 13:12:22 +01002827 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
2828 if (data) {
2829 struct hci_cp_remote_oob_data_reply cp;
2830
2831 bacpy(&cp.bdaddr, &ev->bdaddr);
2832 memcpy(cp.hash, data->hash, sizeof(cp.hash));
2833 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
2834
2835 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
2836 &cp);
2837 } else {
2838 struct hci_cp_remote_oob_data_neg_reply cp;
2839
2840 bacpy(&cp.bdaddr, &ev->bdaddr);
2841 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
2842 &cp);
2843 }
2844
Szymon Jance1ba1f12011-04-06 13:01:59 +02002845unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01002846 hci_dev_unlock(hdev);
2847}
2848
Ville Tervofcd89c02011-02-10 22:38:47 -03002849static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2850{
2851 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
2852 struct hci_conn *conn;
2853
2854 BT_DBG("%s status %d", hdev->name, ev->status);
2855
2856 hci_dev_lock(hdev);
2857
2858 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03002859 if (!conn) {
2860 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
2861 if (!conn) {
2862 BT_ERR("No memory for new connection");
2863 hci_dev_unlock(hdev);
2864 return;
2865 }
Andre Guedes29b79882011-05-31 14:20:54 -03002866
2867 conn->dst_type = ev->bdaddr_type;
Ville Tervob62f3282011-02-10 22:38:50 -03002868 }
Ville Tervofcd89c02011-02-10 22:38:47 -03002869
2870 if (ev->status) {
Johan Hedberg744cf192011-11-08 20:40:14 +02002871 mgmt_connect_failed(hdev, &ev->bdaddr, conn->type, ev->status);
Ville Tervofcd89c02011-02-10 22:38:47 -03002872 hci_proto_connect_cfm(conn, ev->status);
2873 conn->state = BT_CLOSED;
2874 hci_conn_del(conn);
2875 goto unlock;
2876 }
2877
Johan Hedberg744cf192011-11-08 20:40:14 +02002878 mgmt_connected(hdev, &ev->bdaddr, conn->type);
Vinicius Costa Gomes83bc71b2011-05-06 18:41:43 -03002879
Vinicius Costa Gomes7b5c0d52011-06-09 18:50:50 -03002880 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03002881 conn->handle = __le16_to_cpu(ev->handle);
2882 conn->state = BT_CONNECTED;
2883
2884 hci_conn_hold_device(conn);
2885 hci_conn_add_sysfs(conn);
2886
2887 hci_proto_connect_cfm(conn, ev->status);
2888
2889unlock:
2890 hci_dev_unlock(hdev);
2891}
2892
Andre Guedes9aa04c92011-05-26 16:23:51 -03002893static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
2894 struct sk_buff *skb)
2895{
Andre Guedese95beb42011-09-26 20:48:35 -03002896 u8 num_reports = skb->data[0];
2897 void *ptr = &skb->data[1];
Andre Guedes9aa04c92011-05-26 16:23:51 -03002898
2899 hci_dev_lock(hdev);
2900
Andre Guedese95beb42011-09-26 20:48:35 -03002901 while (num_reports--) {
2902 struct hci_ev_le_advertising_info *ev = ptr;
Andre Guedes9aa04c92011-05-26 16:23:51 -03002903
Andre Guedes9aa04c92011-05-26 16:23:51 -03002904 hci_add_adv_entry(hdev, ev);
Andre Guedese95beb42011-09-26 20:48:35 -03002905
2906 ptr += sizeof(*ev) + ev->length + 1;
Andre Guedes9aa04c92011-05-26 16:23:51 -03002907 }
2908
2909 hci_dev_unlock(hdev);
2910}
2911
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002912static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
2913 struct sk_buff *skb)
2914{
2915 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
2916 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03002917 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002918 struct hci_conn *conn;
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03002919 struct link_key *ltk;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002920
2921 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
2922
2923 hci_dev_lock(hdev);
2924
2925 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03002926 if (conn == NULL)
2927 goto not_found;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002928
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03002929 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
2930 if (ltk == NULL)
2931 goto not_found;
2932
2933 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002934 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomes726b4ff2011-07-08 18:31:45 -03002935 conn->pin_length = ltk->pin_len;
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002936
2937 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
2938
2939 hci_dev_unlock(hdev);
Vinicius Costa Gomesbea710f2011-07-07 18:59:37 -03002940
2941 return;
2942
2943not_found:
2944 neg.handle = ev->handle;
2945 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
2946 hci_dev_unlock(hdev);
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002947}
2948
Ville Tervofcd89c02011-02-10 22:38:47 -03002949static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
2950{
2951 struct hci_ev_le_meta *le_ev = (void *) skb->data;
2952
2953 skb_pull(skb, sizeof(*le_ev));
2954
2955 switch (le_ev->subevent) {
2956 case HCI_EV_LE_CONN_COMPLETE:
2957 hci_le_conn_complete_evt(hdev, skb);
2958 break;
2959
Andre Guedes9aa04c92011-05-26 16:23:51 -03002960 case HCI_EV_LE_ADVERTISING_REPORT:
2961 hci_le_adv_report_evt(hdev, skb);
2962 break;
2963
Vinicius Costa Gomesa7a595f2011-06-09 18:50:47 -03002964 case HCI_EV_LE_LTK_REQ:
2965 hci_le_ltk_request_evt(hdev, skb);
2966 break;
2967
Ville Tervofcd89c02011-02-10 22:38:47 -03002968 default:
2969 break;
2970 }
2971}
2972
Linus Torvalds1da177e2005-04-16 15:20:36 -07002973void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
2974{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002975 struct hci_event_hdr *hdr = (void *) skb->data;
2976 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002977
2978 skb_pull(skb, HCI_EVENT_HDR_SIZE);
2979
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002980 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002981 case HCI_EV_INQUIRY_COMPLETE:
2982 hci_inquiry_complete_evt(hdev, skb);
2983 break;
2984
2985 case HCI_EV_INQUIRY_RESULT:
2986 hci_inquiry_result_evt(hdev, skb);
2987 break;
2988
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002989 case HCI_EV_CONN_COMPLETE:
2990 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02002991 break;
2992
Linus Torvalds1da177e2005-04-16 15:20:36 -07002993 case HCI_EV_CONN_REQUEST:
2994 hci_conn_request_evt(hdev, skb);
2995 break;
2996
Linus Torvalds1da177e2005-04-16 15:20:36 -07002997 case HCI_EV_DISCONN_COMPLETE:
2998 hci_disconn_complete_evt(hdev, skb);
2999 break;
3000
Linus Torvalds1da177e2005-04-16 15:20:36 -07003001 case HCI_EV_AUTH_COMPLETE:
3002 hci_auth_complete_evt(hdev, skb);
3003 break;
3004
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003005 case HCI_EV_REMOTE_NAME:
3006 hci_remote_name_evt(hdev, skb);
3007 break;
3008
Linus Torvalds1da177e2005-04-16 15:20:36 -07003009 case HCI_EV_ENCRYPT_CHANGE:
3010 hci_encrypt_change_evt(hdev, skb);
3011 break;
3012
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003013 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3014 hci_change_link_key_complete_evt(hdev, skb);
3015 break;
3016
3017 case HCI_EV_REMOTE_FEATURES:
3018 hci_remote_features_evt(hdev, skb);
3019 break;
3020
3021 case HCI_EV_REMOTE_VERSION:
3022 hci_remote_version_evt(hdev, skb);
3023 break;
3024
3025 case HCI_EV_QOS_SETUP_COMPLETE:
3026 hci_qos_setup_complete_evt(hdev, skb);
3027 break;
3028
3029 case HCI_EV_CMD_COMPLETE:
3030 hci_cmd_complete_evt(hdev, skb);
3031 break;
3032
3033 case HCI_EV_CMD_STATUS:
3034 hci_cmd_status_evt(hdev, skb);
3035 break;
3036
3037 case HCI_EV_ROLE_CHANGE:
3038 hci_role_change_evt(hdev, skb);
3039 break;
3040
3041 case HCI_EV_NUM_COMP_PKTS:
3042 hci_num_comp_pkts_evt(hdev, skb);
3043 break;
3044
3045 case HCI_EV_MODE_CHANGE:
3046 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003047 break;
3048
3049 case HCI_EV_PIN_CODE_REQ:
3050 hci_pin_code_request_evt(hdev, skb);
3051 break;
3052
3053 case HCI_EV_LINK_KEY_REQ:
3054 hci_link_key_request_evt(hdev, skb);
3055 break;
3056
3057 case HCI_EV_LINK_KEY_NOTIFY:
3058 hci_link_key_notify_evt(hdev, skb);
3059 break;
3060
3061 case HCI_EV_CLOCK_OFFSET:
3062 hci_clock_offset_evt(hdev, skb);
3063 break;
3064
Marcel Holtmanna8746412008-07-14 20:13:46 +02003065 case HCI_EV_PKT_TYPE_CHANGE:
3066 hci_pkt_type_change_evt(hdev, skb);
3067 break;
3068
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003069 case HCI_EV_PSCAN_REP_MODE:
3070 hci_pscan_rep_mode_evt(hdev, skb);
3071 break;
3072
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003073 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3074 hci_inquiry_result_with_rssi_evt(hdev, skb);
3075 break;
3076
3077 case HCI_EV_REMOTE_EXT_FEATURES:
3078 hci_remote_ext_features_evt(hdev, skb);
3079 break;
3080
3081 case HCI_EV_SYNC_CONN_COMPLETE:
3082 hci_sync_conn_complete_evt(hdev, skb);
3083 break;
3084
3085 case HCI_EV_SYNC_CONN_CHANGED:
3086 hci_sync_conn_changed_evt(hdev, skb);
3087 break;
3088
Marcel Holtmann04837f62006-07-03 10:02:33 +02003089 case HCI_EV_SNIFF_SUBRATE:
3090 hci_sniff_subrate_evt(hdev, skb);
3091 break;
3092
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003093 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3094 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003095 break;
3096
Marcel Holtmann04936842008-07-14 20:13:48 +02003097 case HCI_EV_IO_CAPA_REQUEST:
3098 hci_io_capa_request_evt(hdev, skb);
3099 break;
3100
Johan Hedberg03b555e2011-01-04 15:40:05 +02003101 case HCI_EV_IO_CAPA_REPLY:
3102 hci_io_capa_reply_evt(hdev, skb);
3103 break;
3104
Johan Hedberga5c29682011-02-19 12:05:57 -03003105 case HCI_EV_USER_CONFIRM_REQUEST:
3106 hci_user_confirm_request_evt(hdev, skb);
3107 break;
3108
Marcel Holtmann04936842008-07-14 20:13:48 +02003109 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3110 hci_simple_pair_complete_evt(hdev, skb);
3111 break;
3112
Marcel Holtmann41a96212008-07-14 20:13:48 +02003113 case HCI_EV_REMOTE_HOST_FEATURES:
3114 hci_remote_host_features_evt(hdev, skb);
3115 break;
3116
Ville Tervofcd89c02011-02-10 22:38:47 -03003117 case HCI_EV_LE_META:
3118 hci_le_meta_evt(hdev, skb);
3119 break;
3120
Szymon Janc2763eda2011-03-22 13:12:22 +01003121 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3122 hci_remote_oob_data_request_evt(hdev, skb);
3123 break;
3124
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003125 default:
3126 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003127 break;
3128 }
3129
3130 kfree_skb(skb);
3131 hdev->stat.evt_rx++;
3132}
3133
3134/* Generate internal stack event */
3135void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
3136{
3137 struct hci_event_hdr *hdr;
3138 struct hci_ev_stack_internal *ev;
3139 struct sk_buff *skb;
3140
3141 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
3142 if (!skb)
3143 return;
3144
3145 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
3146 hdr->evt = HCI_EV_STACK_INTERNAL;
3147 hdr->plen = sizeof(*ev) + dlen;
3148
3149 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
3150 ev->type = type;
3151 memcpy(ev->data, data, dlen);
3152
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003153 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07003154 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003155
Marcel Holtmann0d48d932005-08-09 20:30:28 -07003156 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003157 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02003158 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003159 kfree_skb(skb);
3160}
Andre Guedese6100a22011-06-30 19:20:54 -03003161
Gustavo F. Padovan669bb392011-10-11 15:57:01 -03003162module_param(enable_le, bool, 0644);
Andre Guedese6100a22011-06-30 19:20:54 -03003163MODULE_PARM_DESC(enable_le, "Enable LE support");