blob: ae483c69ce8001bde4adde300687a91e4e7a68d8 [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
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003 Copyright (c) 2000-2001, 2010-2011, 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
Linus Torvalds1da177e2005-04-16 15:20:36 -070048/* Handle HCI Event packets */
49
Marcel Holtmanna9de9242007-10-20 13:33:56 +020050static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070051{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020052 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070053
Marcel Holtmanna9de9242007-10-20 13:33:56 +020054 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070055
Marcel Holtmanna9de9242007-10-20 13:33:56 +020056 if (status)
57 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070059 clear_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010060
Johan Hedberg23bb5762010-12-21 23:01:27 +020061 hci_req_complete(hdev, HCI_OP_INQUIRY_CANCEL, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010062
Marcel Holtmanna9de9242007-10-20 13:33:56 +020063 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070064}
65
Marcel Holtmanna9de9242007-10-20 13:33:56 +020066static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070067{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020068 __u8 status = *((__u8 *) skb->data);
69
70 BT_DBG("%s status 0x%x", hdev->name, status);
71
72 if (status)
73 return;
74
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070075 clear_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +020076
77 hci_conn_check_pending(hdev);
78}
79
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070080static void hci_cc_link_key_reply(struct hci_dev *hdev, struct sk_buff *skb)
81{
82 struct hci_rp_link_key_reply *rp = (void *) skb->data;
83 struct hci_conn *conn;
84 struct hci_cp_link_key_reply *cp;
85
86 BT_DBG("%s status 0x%x", hdev->name, rp->status);
87 if (rp->status)
88 return;
89
90 cp = hci_sent_cmd_data(hdev, HCI_OP_LINK_KEY_REPLY);
91 if (!cp)
92 return;
93
94 hci_dev_lock(hdev);
95 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
96 if (conn) {
97 hci_conn_hold(conn);
98 memcpy(conn->link_key, cp->link_key, sizeof(conn->link_key));
99 conn->key_type = 5;
100 hci_conn_put(conn);
101 }
102 hci_dev_unlock(hdev);
103}
104
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200105static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
106{
107 BT_DBG("%s", hdev->name);
108}
109
110static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
111{
112 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700113 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700114
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200115 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700116
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200117 if (rp->status)
118 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200120 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700121
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200122 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
123 if (conn) {
124 if (rp->role)
125 conn->link_mode &= ~HCI_LM_MASTER;
126 else
127 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200129
130 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131}
132
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200133static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
134{
135 struct hci_rp_read_link_policy *rp = (void *) skb->data;
136 struct hci_conn *conn;
137
138 BT_DBG("%s status 0x%x", hdev->name, rp->status);
139
140 if (rp->status)
141 return;
142
143 hci_dev_lock(hdev);
144
145 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
146 if (conn)
147 conn->link_policy = __le16_to_cpu(rp->policy);
148
149 hci_dev_unlock(hdev);
150}
151
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200152static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700153{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200154 struct hci_rp_write_link_policy *rp = (void *) skb->data;
155 struct hci_conn *conn;
156 void *sent;
157
158 BT_DBG("%s status 0x%x", hdev->name, rp->status);
159
160 if (rp->status)
161 return;
162
163 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
164 if (!sent)
165 return;
166
167 hci_dev_lock(hdev);
168
169 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200170 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700171 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200172
173 hci_dev_unlock(hdev);
174}
175
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200176static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
177{
178 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
179
180 BT_DBG("%s status 0x%x", hdev->name, rp->status);
181
182 if (rp->status)
183 return;
184
185 hdev->link_policy = __le16_to_cpu(rp->policy);
186}
187
188static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
189{
190 __u8 status = *((__u8 *) skb->data);
191 void *sent;
192
193 BT_DBG("%s status 0x%x", hdev->name, status);
194
195 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
196 if (!sent)
197 return;
198
199 if (!status)
200 hdev->link_policy = get_unaligned_le16(sent);
201
Johan Hedberg23bb5762010-12-21 23:01:27 +0200202 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200203}
204
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200205static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
206{
207 __u8 status = *((__u8 *) skb->data);
208
209 BT_DBG("%s status 0x%x", hdev->name, status);
210
Gustavo F. Padovan10572132011-03-16 15:36:29 -0300211 clear_bit(HCI_RESET, &hdev->flags);
212
Johan Hedberg23bb5762010-12-21 23:01:27 +0200213 hci_req_complete(hdev, HCI_OP_RESET, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200214}
215
216static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
217{
218 __u8 status = *((__u8 *) skb->data);
219 void *sent;
220
221 BT_DBG("%s status 0x%x", hdev->name, status);
222
223 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
224 if (!sent)
225 return;
226
Johan Hedbergb312b1612011-03-16 14:29:37 +0200227 if (test_bit(HCI_MGMT, &hdev->flags))
228 mgmt_set_local_name_complete(hdev->id, sent, status);
229
230 if (status)
231 return;
232
Johan Hedberg1f6c6372011-03-16 14:29:35 +0200233 memcpy(hdev->dev_name, sent, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200234}
235
236static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
237{
238 struct hci_rp_read_local_name *rp = (void *) skb->data;
239
240 BT_DBG("%s status 0x%x", hdev->name, rp->status);
241
242 if (rp->status)
243 return;
244
Johan Hedberg1f6c6372011-03-16 14:29:35 +0200245 memcpy(hdev->dev_name, rp->name, HCI_MAX_NAME_LENGTH);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200246}
247
248static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
249{
250 __u8 status = *((__u8 *) skb->data);
251 void *sent;
252
253 BT_DBG("%s status 0x%x", hdev->name, status);
254
255 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
256 if (!sent)
257 return;
258
259 if (!status) {
260 __u8 param = *((__u8 *) sent);
261
262 if (param == AUTH_ENABLED)
263 set_bit(HCI_AUTH, &hdev->flags);
264 else
265 clear_bit(HCI_AUTH, &hdev->flags);
266 }
267
Johan Hedberg23bb5762010-12-21 23:01:27 +0200268 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200269}
270
271static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
272{
273 __u8 status = *((__u8 *) skb->data);
274 void *sent;
275
276 BT_DBG("%s status 0x%x", hdev->name, status);
277
278 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
279 if (!sent)
280 return;
281
282 if (!status) {
283 __u8 param = *((__u8 *) sent);
284
285 if (param)
286 set_bit(HCI_ENCRYPT, &hdev->flags);
287 else
288 clear_bit(HCI_ENCRYPT, &hdev->flags);
289 }
290
Johan Hedberg23bb5762010-12-21 23:01:27 +0200291 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200292}
293
294static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
295{
296 __u8 status = *((__u8 *) skb->data);
297 void *sent;
298
299 BT_DBG("%s status 0x%x", hdev->name, status);
300
301 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
302 if (!sent)
303 return;
304
305 if (!status) {
306 __u8 param = *((__u8 *) sent);
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200307 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200308
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200309 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
310 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200311
Johan Hedberg73f22f62010-12-29 16:00:25 +0200312 if (param & SCAN_INQUIRY) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200313 set_bit(HCI_ISCAN, &hdev->flags);
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200314 if (!old_iscan)
315 mgmt_discoverable(hdev->id, 1);
316 } else if (old_iscan)
Johan Hedberg73f22f62010-12-29 16:00:25 +0200317 mgmt_discoverable(hdev->id, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200318
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200319 if (param & SCAN_PAGE) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200320 set_bit(HCI_PSCAN, &hdev->flags);
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200321 if (!old_pscan)
322 mgmt_connectable(hdev->id, 1);
323 } else if (old_pscan)
324 mgmt_connectable(hdev->id, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200325 }
326
Johan Hedberg23bb5762010-12-21 23:01:27 +0200327 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200328}
329
330static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
331{
332 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
333
334 BT_DBG("%s status 0x%x", hdev->name, rp->status);
335
336 if (rp->status)
337 return;
338
339 memcpy(hdev->dev_class, rp->dev_class, 3);
340
341 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
342 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
343}
344
345static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
346{
347 __u8 status = *((__u8 *) skb->data);
348 void *sent;
349
350 BT_DBG("%s status 0x%x", hdev->name, status);
351
Marcel Holtmannf383f272008-07-14 20:13:47 +0200352 if (status)
353 return;
354
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200355 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
356 if (!sent)
357 return;
358
Marcel Holtmannf383f272008-07-14 20:13:47 +0200359 memcpy(hdev->dev_class, sent, 3);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200360}
361
362static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
363{
364 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200366
367 BT_DBG("%s status 0x%x", hdev->name, rp->status);
368
369 if (rp->status)
370 return;
371
372 setting = __le16_to_cpu(rp->voice_setting);
373
Marcel Holtmannf383f272008-07-14 20:13:47 +0200374 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200375 return;
376
377 hdev->voice_setting = setting;
378
379 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
380
381 if (hdev->notify) {
382 tasklet_disable(&hdev->tx_task);
383 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
384 tasklet_enable(&hdev->tx_task);
385 }
386}
387
388static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
389{
390 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200391 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392 void *sent;
393
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200394 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700395
Marcel Holtmannf383f272008-07-14 20:13:47 +0200396 if (status)
397 return;
398
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200399 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
400 if (!sent)
401 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700402
Marcel Holtmannf383f272008-07-14 20:13:47 +0200403 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700404
Marcel Holtmannf383f272008-07-14 20:13:47 +0200405 if (hdev->voice_setting == setting)
406 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700407
Marcel Holtmannf383f272008-07-14 20:13:47 +0200408 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700409
Marcel Holtmannf383f272008-07-14 20:13:47 +0200410 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
411
412 if (hdev->notify) {
413 tasklet_disable(&hdev->tx_task);
414 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
415 tasklet_enable(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700416 }
417}
418
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200419static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700420{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200421 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200423 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424
Johan Hedberg23bb5762010-12-21 23:01:27 +0200425 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700426}
427
Marcel Holtmann333140b2008-07-14 20:13:48 +0200428static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
429{
430 struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
431
432 BT_DBG("%s status 0x%x", hdev->name, rp->status);
433
434 if (rp->status)
435 return;
436
437 hdev->ssp_mode = rp->mode;
438}
439
440static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
441{
442 __u8 status = *((__u8 *) skb->data);
443 void *sent;
444
445 BT_DBG("%s status 0x%x", hdev->name, status);
446
447 if (status)
448 return;
449
450 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
451 if (!sent)
452 return;
453
454 hdev->ssp_mode = *((__u8 *) sent);
455}
456
Johan Hedbergd5859e22011-01-25 01:19:58 +0200457static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
458{
459 if (hdev->features[6] & LMP_EXT_INQ)
460 return 2;
461
462 if (hdev->features[3] & LMP_RSSI_INQ)
463 return 1;
464
465 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
466 hdev->lmp_subver == 0x0757)
467 return 1;
468
469 if (hdev->manufacturer == 15) {
470 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
471 return 1;
472 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
473 return 1;
474 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
475 return 1;
476 }
477
478 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
479 hdev->lmp_subver == 0x1805)
480 return 1;
481
482 return 0;
483}
484
485static void hci_setup_inquiry_mode(struct hci_dev *hdev)
486{
487 u8 mode;
488
489 mode = hci_get_inquiry_mode(hdev);
490
491 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
492}
493
494static void hci_setup_event_mask(struct hci_dev *hdev)
495{
496 /* The second byte is 0xff instead of 0x9f (two reserved bits
497 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
498 * command otherwise */
499 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
500
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700501 /* Events for 1.2 and newer controllers */
502 if (hdev->lmp_ver > 1) {
503 events[4] |= 0x01; /* Flow Specification Complete */
504 events[4] |= 0x02; /* Inquiry Result with RSSI */
505 events[4] |= 0x04; /* Read Remote Extended Features Complete */
506 events[5] |= 0x08; /* Synchronous Connection Complete */
507 events[5] |= 0x10; /* Synchronous Connection Changed */
508 }
Johan Hedbergd5859e22011-01-25 01:19:58 +0200509
510 if (hdev->features[3] & LMP_RSSI_INQ)
511 events[4] |= 0x04; /* Inquiry Result with RSSI */
512
513 if (hdev->features[5] & LMP_SNIFF_SUBR)
514 events[5] |= 0x20; /* Sniff Subrating */
515
516 if (hdev->features[5] & LMP_PAUSE_ENC)
517 events[5] |= 0x80; /* Encryption Key Refresh Complete */
518
519 if (hdev->features[6] & LMP_EXT_INQ)
520 events[5] |= 0x40; /* Extended Inquiry Result */
521
522 if (hdev->features[6] & LMP_NO_FLUSH)
523 events[7] |= 0x01; /* Enhanced Flush Complete */
524
525 if (hdev->features[7] & LMP_LSTO)
526 events[6] |= 0x80; /* Link Supervision Timeout Changed */
527
528 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
529 events[6] |= 0x01; /* IO Capability Request */
530 events[6] |= 0x02; /* IO Capability Response */
531 events[6] |= 0x04; /* User Confirmation Request */
532 events[6] |= 0x08; /* User Passkey Request */
533 events[6] |= 0x10; /* Remote OOB Data Request */
534 events[6] |= 0x20; /* Simple Pairing Complete */
535 events[7] |= 0x04; /* User Passkey Notification */
536 events[7] |= 0x08; /* Keypress Notification */
537 events[7] |= 0x10; /* Remote Host Supported
538 * Features Notification */
539 }
540
541 if (hdev->features[4] & LMP_LE)
542 events[7] |= 0x20; /* LE Meta-Event */
543
544 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
545}
546
547static void hci_setup(struct hci_dev *hdev)
548{
549 hci_setup_event_mask(hdev);
550
551 if (hdev->lmp_ver > 1)
552 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
553
554 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
555 u8 mode = 0x01;
556 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
557 }
558
559 if (hdev->features[3] & LMP_RSSI_INQ)
560 hci_setup_inquiry_mode(hdev);
561
562 if (hdev->features[7] & LMP_INQ_TX_PWR)
563 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
564}
565
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200566static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
567{
568 struct hci_rp_read_local_version *rp = (void *) skb->data;
569
570 BT_DBG("%s status 0x%x", hdev->name, rp->status);
571
572 if (rp->status)
573 return;
574
575 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200576 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200577 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200578 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200579 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200580
581 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
582 hdev->manufacturer,
583 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200584
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700585 if (hdev->dev_type == HCI_BREDR && test_bit(HCI_INIT, &hdev->flags))
Johan Hedbergd5859e22011-01-25 01:19:58 +0200586 hci_setup(hdev);
587}
588
589static void hci_setup_link_policy(struct hci_dev *hdev)
590{
591 u16 link_policy = 0;
592
593 if (hdev->features[0] & LMP_RSWITCH)
594 link_policy |= HCI_LP_RSWITCH;
595 if (hdev->features[0] & LMP_HOLD)
596 link_policy |= HCI_LP_HOLD;
597 if (hdev->features[0] & LMP_SNIFF)
598 link_policy |= HCI_LP_SNIFF;
599 if (hdev->features[1] & LMP_PARK)
600 link_policy |= HCI_LP_PARK;
601
602 link_policy = cpu_to_le16(link_policy);
603 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
604 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200605}
606
607static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
608{
609 struct hci_rp_read_local_commands *rp = (void *) skb->data;
610
611 BT_DBG("%s status 0x%x", hdev->name, rp->status);
612
613 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200614 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200615
616 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200617
618 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
619 hci_setup_link_policy(hdev);
620
621done:
622 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200623}
624
625static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
626{
627 struct hci_rp_read_local_features *rp = (void *) skb->data;
628
629 BT_DBG("%s status 0x%x", hdev->name, rp->status);
630
631 if (rp->status)
632 return;
633
634 memcpy(hdev->features, rp->features, 8);
635
636 /* Adjust default settings according to features
637 * supported by device. */
638
639 if (hdev->features[0] & LMP_3SLOT)
640 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
641
642 if (hdev->features[0] & LMP_5SLOT)
643 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
644
645 if (hdev->features[1] & LMP_HV2) {
646 hdev->pkt_type |= (HCI_HV2);
647 hdev->esco_type |= (ESCO_HV2);
648 }
649
650 if (hdev->features[1] & LMP_HV3) {
651 hdev->pkt_type |= (HCI_HV3);
652 hdev->esco_type |= (ESCO_HV3);
653 }
654
655 if (hdev->features[3] & LMP_ESCO)
656 hdev->esco_type |= (ESCO_EV3);
657
658 if (hdev->features[4] & LMP_EV4)
659 hdev->esco_type |= (ESCO_EV4);
660
661 if (hdev->features[4] & LMP_EV5)
662 hdev->esco_type |= (ESCO_EV5);
663
Marcel Holtmannefc76882009-02-06 09:13:37 +0100664 if (hdev->features[5] & LMP_EDR_ESCO_2M)
665 hdev->esco_type |= (ESCO_2EV3);
666
667 if (hdev->features[5] & LMP_EDR_ESCO_3M)
668 hdev->esco_type |= (ESCO_3EV3);
669
670 if (hdev->features[5] & LMP_EDR_3S_ESCO)
671 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
672
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200673 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
674 hdev->features[0], hdev->features[1],
675 hdev->features[2], hdev->features[3],
676 hdev->features[4], hdev->features[5],
677 hdev->features[6], hdev->features[7]);
678}
679
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700680static void hci_cc_read_flow_control_mode(struct hci_dev *hdev,
681 struct sk_buff *skb)
Andre Guedesd5fa5132011-06-30 19:20:52 -0300682{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700683 struct hci_rp_read_flow_control_mode *rp = (void *) skb->data;
Andre Guedesd5fa5132011-06-30 19:20:52 -0300684
685 BT_DBG("%s status 0x%x", hdev->name, rp->status);
686
687 if (rp->status)
688 return;
689
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700690 hdev->flow_ctl_mode = rp->mode;
Andre Guedesd5fa5132011-06-30 19:20:52 -0300691}
692
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200693static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
694{
695 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
696
697 BT_DBG("%s status 0x%x", hdev->name, rp->status);
698
699 if (rp->status)
700 return;
701
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700702 if (hdev->flow_ctl_mode == HCI_PACKET_BASED_FLOW_CTL_MODE) {
703 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
704 hdev->sco_mtu = rp->sco_mtu;
705 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
706 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
707 hdev->acl_cnt = hdev->acl_pkts;
708 hdev->sco_cnt = hdev->sco_pkts;
709 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200710
711 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
712 hdev->sco_mtu = 64;
713 hdev->sco_pkts = 8;
714 }
715
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200716
717 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
718 hdev->acl_mtu, hdev->acl_pkts,
719 hdev->sco_mtu, hdev->sco_pkts);
720}
721
722static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
723{
724 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
725
726 BT_DBG("%s status 0x%x", hdev->name, rp->status);
727
728 if (!rp->status)
729 bacpy(&hdev->bdaddr, &rp->bdaddr);
730
Johan Hedberg23bb5762010-12-21 23:01:27 +0200731 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
732}
733
734static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
735{
736 __u8 status = *((__u8 *) skb->data);
737
738 BT_DBG("%s status 0x%x", hdev->name, status);
739
740 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200741}
742
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700743static void hci_cc_read_data_block_size(struct hci_dev *hdev,
744 struct sk_buff *skb)
745{
746 struct hci_rp_read_data_block_size *rp = (void *) skb->data;
747
748 BT_DBG("%s status 0x%x", hdev->name, rp->status);
749
750 if (rp->status)
751 return;
752
753 if (hdev->flow_ctl_mode == HCI_BLOCK_BASED_FLOW_CTL_MODE) {
754 hdev->acl_mtu = __le16_to_cpu(rp->max_acl_len);
755 hdev->sco_mtu = 0;
756 hdev->data_block_len = __le16_to_cpu(rp->data_block_len);
757 /* acl_pkts indicates the number of blocks */
758 hdev->acl_pkts = __le16_to_cpu(rp->num_blocks);
759 hdev->sco_pkts = 0;
760 hdev->acl_cnt = hdev->acl_pkts;
761 hdev->sco_cnt = 0;
762 }
763
764 BT_DBG("%s acl mtu %d:%d, data block len %d", hdev->name,
765 hdev->acl_mtu, hdev->acl_cnt, hdev->data_block_len);
766}
767
768static void hci_cc_read_local_amp_info(struct hci_dev *hdev,
769 struct sk_buff *skb)
770{
771 struct hci_rp_read_local_amp_info *rp = (void *) skb->data;
772
773 BT_DBG("%s status 0x%x", hdev->name, rp->status);
774
775 if (rp->status)
776 return;
777
778 hdev->amp_status = rp->amp_status;
779 hdev->amp_total_bw = __le32_to_cpu(rp->total_bw);
780 hdev->amp_max_bw = __le32_to_cpu(rp->max_bw);
781 hdev->amp_min_latency = __le32_to_cpu(rp->min_latency);
782 hdev->amp_max_pdu = __le32_to_cpu(rp->max_pdu);
783 hdev->amp_type = rp->amp_type;
784 hdev->amp_pal_cap = __le16_to_cpu(rp->pal_cap);
785 hdev->amp_assoc_size = __le16_to_cpu(rp->max_assoc_size);
786 hdev->amp_be_flush_to = __le32_to_cpu(rp->be_flush_to);
787 hdev->amp_max_flush_to = __le32_to_cpu(rp->max_flush_to);
788
789 hci_req_complete(hdev, HCI_OP_READ_LOCAL_AMP_INFO, rp->status);
790}
791
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200792static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
793 struct sk_buff *skb)
794{
795 __u8 status = *((__u8 *) skb->data);
796
797 BT_DBG("%s status 0x%x", hdev->name, status);
798
799 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
800}
801
Johan Hedbergd5859e22011-01-25 01:19:58 +0200802static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
803{
804 __u8 status = *((__u8 *) skb->data);
805
806 BT_DBG("%s status 0x%x", hdev->name, status);
807
808 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
809}
810
811static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
812 struct sk_buff *skb)
813{
814 __u8 status = *((__u8 *) skb->data);
815
816 BT_DBG("%s status 0x%x", hdev->name, status);
817
818 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
819}
820
821static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
822 struct sk_buff *skb)
823{
824 __u8 status = *((__u8 *) skb->data);
825
826 BT_DBG("%s status 0x%x", hdev->name, status);
827
828 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
829}
830
831static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
832{
833 __u8 status = *((__u8 *) skb->data);
834
835 BT_DBG("%s status 0x%x", hdev->name, status);
836
837 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
838}
839
Johan Hedberg980e1a52011-01-22 06:10:07 +0200840static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
841{
842 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
843 struct hci_cp_pin_code_reply *cp;
844 struct hci_conn *conn;
845
846 BT_DBG("%s status 0x%x", hdev->name, rp->status);
847
848 if (test_bit(HCI_MGMT, &hdev->flags))
849 mgmt_pin_code_reply_complete(hdev->id, &rp->bdaddr, rp->status);
850
851 if (rp->status != 0)
852 return;
853
854 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
855 if (!cp)
856 return;
857
858 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
859 if (conn)
860 conn->pin_length = cp->pin_len;
861}
862
863static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
864{
865 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
866
867 BT_DBG("%s status 0x%x", hdev->name, rp->status);
868
869 if (test_bit(HCI_MGMT, &hdev->flags))
870 mgmt_pin_code_neg_reply_complete(hdev->id, &rp->bdaddr,
871 rp->status);
872}
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300873static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
874 struct sk_buff *skb)
875{
876 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
877
878 BT_DBG("%s status 0x%x", hdev->name, rp->status);
879
880 if (rp->status)
881 return;
882
883 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
884 hdev->le_pkts = rp->le_max_pkt;
885
886 hdev->le_cnt = hdev->le_pkts;
887
888 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
889
890 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
891}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200892
Johan Hedberga5c29682011-02-19 12:05:57 -0300893static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
894{
895 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
896
897 BT_DBG("%s status 0x%x", hdev->name, rp->status);
898
899 if (test_bit(HCI_MGMT, &hdev->flags))
900 mgmt_user_confirm_reply_complete(hdev->id, &rp->bdaddr,
901 rp->status);
902}
903
904static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
905 struct sk_buff *skb)
906{
907 struct hci_rp_user_confirm_reply *rp = (void *) skb->data;
908
909 BT_DBG("%s status 0x%x", hdev->name, rp->status);
910
911 if (test_bit(HCI_MGMT, &hdev->flags))
912 mgmt_user_confirm_neg_reply_complete(hdev->id, &rp->bdaddr,
913 rp->status);
914}
915
Szymon Jancc35938b2011-03-22 13:12:21 +0100916static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
917 struct sk_buff *skb)
918{
919 struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
920
921 BT_DBG("%s status 0x%x", hdev->name, rp->status);
922
923 mgmt_read_local_oob_data_reply_complete(hdev->id, rp->hash,
924 rp->randomizer, rp->status);
925}
926
Vinicius Costa Gomes735038c2011-06-09 18:50:47 -0300927static void hci_cc_le_ltk_reply(struct hci_dev *hdev, struct sk_buff *skb)
928{
929 struct hci_rp_le_ltk_reply *rp = (void *) skb->data;
930
931 BT_DBG("%s status 0x%x", hdev->name, rp->status);
932
933 if (rp->status)
934 return;
935
936 hci_req_complete(hdev, HCI_OP_LE_LTK_REPLY, rp->status);
937}
938
939static void hci_cc_le_ltk_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
940{
941 struct hci_rp_le_ltk_neg_reply *rp = (void *) skb->data;
942
943 BT_DBG("%s status 0x%x", hdev->name, rp->status);
944
945 if (rp->status)
946 return;
947
948 hci_req_complete(hdev, HCI_OP_LE_LTK_NEG_REPLY, rp->status);
949}
950
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700951static void hci_cc_le_set_scan_enable(struct hci_dev *hdev,
952 struct sk_buff *skb)
Andre Guedese326af42011-06-30 19:20:53 -0300953{
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700954 void *sent;
955 __u8 param_scan_enable;
Andre Guedese326af42011-06-30 19:20:53 -0300956 __u8 status = *((__u8 *) skb->data);
957
Andre Guedese326af42011-06-30 19:20:53 -0300958 if (status)
959 return;
960
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700961 sent = hci_sent_cmd_data(hdev, HCI_OP_LE_SET_SCAN_ENABLE);
962 if (!sent)
963 return;
964
965 param_scan_enable = *((__u8 *) sent);
966 if (param_scan_enable == 0x01) {
967 del_timer(&hdev->adv_timer);
968 hci_adv_entries_clear(hdev);
969 } else if (param_scan_enable == 0x00) {
970 mod_timer(&hdev->adv_timer, jiffies + ADV_CLEAR_TIMEOUT);
971 }
Andre Guedese326af42011-06-30 19:20:53 -0300972}
973
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200974static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
975{
976 BT_DBG("%s status 0x%x", hdev->name, status);
977
978 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +0200979 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Johan Hedberg314b2382011-04-27 10:29:57 -0400980
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700981 hci_conn_check_pending(hdev);
982 } else
983 set_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200984}
985
Linus Torvalds1da177e2005-04-16 15:20:36 -0700986static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
987{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200988 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200991 BT_DBG("%s status 0x%x", hdev->name, status);
992
993 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700994 if (!cp)
995 return;
996
997 hci_dev_lock(hdev);
998
999 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
1000
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001001 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002
1003 if (status) {
1004 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +02001005 if (status != 0x0c || conn->attempt > 2) {
1006 conn->state = BT_CLOSED;
1007 hci_proto_connect_cfm(conn, status);
1008 hci_conn_del(conn);
1009 } else
1010 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011 }
1012 } else {
1013 if (!conn) {
Nick Pellybbcda3b2010-02-11 11:54:28 -08001014 conn = hci_conn_add(hdev, ACL_LINK, 0, &cp->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001015 if (conn) {
1016 conn->out = 1;
1017 conn->link_mode |= HCI_LM_MASTER;
1018 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001019 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020 }
1021 }
1022
1023 hci_dev_unlock(hdev);
1024}
1025
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001026static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001027{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001028 struct hci_cp_add_sco *cp;
1029 struct hci_conn *acl, *sco;
1030 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001031
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001032 BT_DBG("%s status 0x%x", hdev->name, status);
1033
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001034 if (!status)
1035 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001037 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
1038 if (!cp)
1039 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001040
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001041 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001043 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001044
1045 hci_dev_lock(hdev);
1046
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001047 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001048 if (acl) {
1049 sco = acl->link;
1050 if (sco) {
1051 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001052
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001053 hci_proto_connect_cfm(sco, status);
1054 hci_conn_del(sco);
1055 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001056 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +01001057
1058 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059}
1060
Marcel Holtmannf8558552008-07-14 20:13:49 +02001061static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
1062{
1063 struct hci_cp_auth_requested *cp;
1064 struct hci_conn *conn;
1065
1066 BT_DBG("%s status 0x%x", hdev->name, status);
1067
1068 if (!status)
1069 return;
1070
1071 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
1072 if (!cp)
1073 return;
1074
1075 hci_dev_lock(hdev);
1076
1077 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1078 if (conn) {
1079 if (conn->state == BT_CONFIG) {
1080 hci_proto_connect_cfm(conn, status);
1081 hci_conn_put(conn);
1082 }
1083 }
1084
1085 hci_dev_unlock(hdev);
1086}
1087
1088static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
1089{
1090 struct hci_cp_set_conn_encrypt *cp;
1091 struct hci_conn *conn;
1092
1093 BT_DBG("%s status 0x%x", hdev->name, status);
1094
1095 if (!status)
1096 return;
1097
1098 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
1099 if (!cp)
1100 return;
1101
1102 hci_dev_lock(hdev);
1103
1104 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1105 if (conn) {
1106 if (conn->state == BT_CONFIG) {
1107 hci_proto_connect_cfm(conn, status);
1108 hci_conn_put(conn);
1109 }
1110 }
1111
1112 hci_dev_unlock(hdev);
1113}
1114
Johan Hedberg127178d2010-11-18 22:22:29 +02001115static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +01001116 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +02001117{
Johan Hedberg392599b2010-11-18 22:22:28 +02001118 if (conn->state != BT_CONFIG || !conn->out)
1119 return 0;
1120
Johan Hedberg765c2a92011-01-19 12:06:52 +05301121 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +02001122 return 0;
1123
1124 /* Only request authentication for SSP connections or non-SSP
Prabhakaran Mc6001a712011-09-06 11:56:25 +05301125 * devices with sec_level >= BT_SECURITY_MEDIUM*/
1126 BT_DBG("Pending sec level is %d", conn->pending_sec_level);
Johan Hedberg392599b2010-11-18 22:22:28 +02001127 if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
Prabhakaran Mc6001a712011-09-06 11:56:25 +05301128 conn->pending_sec_level < BT_SECURITY_MEDIUM)
Johan Hedberg392599b2010-11-18 22:22:28 +02001129 return 0;
1130
Johan Hedberg392599b2010-11-18 22:22:28 +02001131 return 1;
1132}
1133
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001134static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
1135{
Johan Hedberg127178d2010-11-18 22:22:29 +02001136 struct hci_cp_remote_name_req *cp;
1137 struct hci_conn *conn;
1138
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001139 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +02001140
1141 /* If successful wait for the name req complete event before
1142 * checking for the need to do authentication */
1143 if (!status)
1144 return;
1145
1146 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
1147 if (!cp)
1148 return;
1149
1150 hci_dev_lock(hdev);
1151
1152 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001153 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001154 struct hci_cp_auth_requested cp;
1155 cp.handle = __cpu_to_le16(conn->handle);
1156 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1157 }
1158
1159 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001160}
1161
Marcel Holtmann769be972008-07-14 20:13:49 +02001162static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
1163{
1164 struct hci_cp_read_remote_features *cp;
1165 struct hci_conn *conn;
1166
1167 BT_DBG("%s status 0x%x", hdev->name, status);
1168
1169 if (!status)
1170 return;
1171
1172 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
1173 if (!cp)
1174 return;
1175
1176 hci_dev_lock(hdev);
1177
1178 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1179 if (conn) {
1180 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001181 hci_proto_connect_cfm(conn, status);
1182 hci_conn_put(conn);
1183 }
1184 }
1185
1186 hci_dev_unlock(hdev);
1187}
1188
1189static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1190{
1191 struct hci_cp_read_remote_ext_features *cp;
1192 struct hci_conn *conn;
1193
1194 BT_DBG("%s status 0x%x", hdev->name, status);
1195
1196 if (!status)
1197 return;
1198
1199 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1200 if (!cp)
1201 return;
1202
1203 hci_dev_lock(hdev);
1204
1205 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1206 if (conn) {
1207 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001208 hci_proto_connect_cfm(conn, status);
1209 hci_conn_put(conn);
1210 }
1211 }
1212
1213 hci_dev_unlock(hdev);
1214}
1215
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001216static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1217{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001218 struct hci_cp_setup_sync_conn *cp;
1219 struct hci_conn *acl, *sco;
1220 __u16 handle;
1221
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001222 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001223
1224 if (!status)
1225 return;
1226
1227 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1228 if (!cp)
1229 return;
1230
1231 handle = __le16_to_cpu(cp->handle);
1232
1233 BT_DBG("%s handle %d", hdev->name, handle);
1234
1235 hci_dev_lock(hdev);
1236
1237 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001238 if (acl) {
1239 sco = acl->link;
1240 if (sco) {
1241 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001242
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001243 hci_proto_connect_cfm(sco, status);
1244 hci_conn_del(sco);
1245 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001246 }
1247
1248 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001249}
1250
1251static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1252{
1253 struct hci_cp_sniff_mode *cp;
1254 struct hci_conn *conn;
1255
1256 BT_DBG("%s status 0x%x", hdev->name, status);
1257
1258 if (!status)
1259 return;
1260
1261 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1262 if (!cp)
1263 return;
1264
1265 hci_dev_lock(hdev);
1266
1267 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001268 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001269 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1270
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001271 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1272 hci_sco_setup(conn, status);
1273 }
1274
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001275 hci_dev_unlock(hdev);
1276}
1277
1278static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1279{
1280 struct hci_cp_exit_sniff_mode *cp;
1281 struct hci_conn *conn;
1282
1283 BT_DBG("%s status 0x%x", hdev->name, status);
1284
1285 if (!status)
1286 return;
1287
1288 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1289 if (!cp)
1290 return;
1291
1292 hci_dev_lock(hdev);
1293
1294 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001295 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001296 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1297
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001298 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1299 hci_sco_setup(conn, status);
1300 }
1301
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001302 hci_dev_unlock(hdev);
1303}
1304
Ville Tervofcd89c02011-02-10 22:38:47 -03001305static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1306{
1307 struct hci_cp_le_create_conn *cp;
1308 struct hci_conn *conn;
1309
1310 BT_DBG("%s status 0x%x", hdev->name, status);
1311
1312 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1313 if (!cp)
1314 return;
1315
1316 hci_dev_lock(hdev);
1317
1318 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1319
1320 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1321 conn);
1322
1323 if (status) {
1324 if (conn && conn->state == BT_CONNECT) {
1325 conn->state = BT_CLOSED;
1326 hci_proto_connect_cfm(conn, status);
1327 hci_conn_del(conn);
1328 }
1329 } else {
1330 if (!conn) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001331 conn = hci_le_conn_add(hdev, &cp->peer_addr,
1332 cp->peer_addr_type);
1333 if (conn)
Ville Tervofcd89c02011-02-10 22:38:47 -03001334 conn->out = 1;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001335 else
Ville Tervofcd89c02011-02-10 22:38:47 -03001336 BT_ERR("No memory for new connection");
1337 }
1338 }
1339
1340 hci_dev_unlock(hdev);
1341}
1342
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001343static void hci_cs_accept_logical_link(struct hci_dev *hdev, __u8 status)
1344{
1345 struct hci_cp_create_logical_link *ap;
1346 struct hci_chan *chan;
1347
1348 BT_DBG("%s status 0x%x", hdev->name, status);
1349
1350 ap = hci_sent_cmd_data(hdev, HCI_OP_ACCEPT_LOGICAL_LINK);
1351 if (!ap)
1352 return;
1353
1354 hci_dev_lock(hdev);
1355
1356 chan = hci_chan_list_lookup_id(hdev, ap->phy_handle);
1357
1358 BT_DBG("%s chan %p", hdev->name, chan);
1359
1360 if (status) {
1361 if (chan && chan->state == BT_CONNECT) {
1362 chan->state = BT_CLOSED;
1363 hci_proto_create_cfm(chan, status);
1364 hci_chan_del(chan);
1365 }
1366 } else if (chan)
1367 chan->state = BT_CONNECT2;
1368
1369 hci_dev_unlock(hdev);
1370}
1371
1372static void hci_cs_create_logical_link(struct hci_dev *hdev, __u8 status)
1373{
1374 struct hci_cp_create_logical_link *cp;
1375 struct hci_chan *chan;
1376
1377 BT_DBG("%s status 0x%x", hdev->name, status);
1378
1379 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_LOGICAL_LINK);
1380 if (!cp)
1381 return;
1382
1383 hci_dev_lock(hdev);
1384
1385 chan = hci_chan_list_lookup_id(hdev, cp->phy_handle);
1386
1387 BT_DBG("%s chan %p", hdev->name, chan);
1388
1389 if (status) {
1390 if (chan && chan->state == BT_CONNECT) {
1391 chan->state = BT_CLOSED;
1392 hci_proto_create_cfm(chan, status);
1393 hci_chan_del(chan);
1394 }
1395 } else if (chan)
1396 chan->state = BT_CONNECT2;
1397
1398 hci_dev_unlock(hdev);
1399}
1400
1401static void hci_cs_flow_spec_modify(struct hci_dev *hdev, __u8 status)
1402{
1403 struct hci_cp_flow_spec_modify *cp;
1404 struct hci_chan *chan;
1405
1406 BT_DBG("%s status 0x%x", hdev->name, status);
1407
1408 cp = hci_sent_cmd_data(hdev, HCI_OP_FLOW_SPEC_MODIFY);
1409 if (!cp)
1410 return;
1411
1412 hci_dev_lock(hdev);
1413
1414 chan = hci_chan_list_lookup_handle(hdev, cp->log_handle);
1415 if (chan) {
1416 if (status)
1417 hci_proto_modify_cfm(chan, status);
1418 else {
1419 chan->tx_fs = cp->tx_fs;
1420 chan->rx_fs = cp->rx_fs;
1421 }
1422 }
1423
1424 hci_dev_unlock(hdev);
1425}
1426
1427static void hci_cs_disconn_logical_link(struct hci_dev *hdev, __u8 status)
1428{
1429 struct hci_cp_disconn_logical_link *cp;
1430 struct hci_chan *chan;
1431
1432 if (!status)
1433 return;
1434
1435 BT_DBG("%s status 0x%x", hdev->name, status);
1436
1437 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONN_LOGICAL_LINK);
1438 if (!cp)
1439 return;
1440
1441 hci_dev_lock(hdev);
1442
1443 chan = hci_chan_list_lookup_handle(hdev, cp->log_handle);
1444 if (chan)
1445 hci_chan_del(chan);
1446
1447 hci_dev_unlock(hdev);
1448}
1449
1450static void hci_cs_disconn_physical_link(struct hci_dev *hdev, __u8 status)
1451{
1452 struct hci_cp_disconn_phys_link *cp;
1453 struct hci_conn *conn;
1454
1455 if (!status)
1456 return;
1457
1458 BT_DBG("%s status 0x%x", hdev->name, status);
1459
1460 cp = hci_sent_cmd_data(hdev, HCI_OP_DISCONN_PHYS_LINK);
1461 if (!cp)
1462 return;
1463
1464 hci_dev_lock(hdev);
1465
1466 conn = hci_conn_hash_lookup_handle(hdev, cp->phy_handle);
1467 if (conn) {
1468 conn->state = BT_CLOSED;
1469 hci_conn_del(conn);
1470 }
1471
1472 hci_dev_unlock(hdev);
1473}
1474
Vinicius Costa Gomes735038c2011-06-09 18:50:47 -03001475static void hci_cs_le_start_enc(struct hci_dev *hdev, u8 status)
1476{
1477 BT_DBG("%s status 0x%x", hdev->name, status);
1478}
1479
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001480static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1481{
1482 __u8 status = *((__u8 *) skb->data);
1483
1484 BT_DBG("%s status %d", hdev->name, status);
1485
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001486 clear_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001487
Johan Hedberg23bb5762010-12-21 23:01:27 +02001488 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001489
1490 hci_conn_check_pending(hdev);
1491}
1492
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1494{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001495 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001496 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001497 int num_rsp = *((__u8 *) skb->data);
1498
1499 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1500
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001501 if (!num_rsp)
1502 return;
1503
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001505
Johan Hedberge17acd42011-03-30 23:57:16 +03001506 for (; num_rsp; num_rsp--, info++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001507 bacpy(&data.bdaddr, &info->bdaddr);
1508 data.pscan_rep_mode = info->pscan_rep_mode;
1509 data.pscan_period_mode = info->pscan_period_mode;
1510 data.pscan_mode = info->pscan_mode;
1511 memcpy(data.dev_class, info->dev_class, 3);
1512 data.clock_offset = info->clock_offset;
1513 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001514 data.ssp_mode = 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515 hci_inquiry_cache_update(hdev, &data);
Johan Hedberge17acd42011-03-30 23:57:16 +03001516 mgmt_device_found(hdev->id, &info->bdaddr, info->dev_class, 0,
1517 NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001519
Linus Torvalds1da177e2005-04-16 15:20:36 -07001520 hci_dev_unlock(hdev);
1521}
1522
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001523static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001524{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001525 struct hci_ev_conn_complete *ev = (void *) skb->data;
1526 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001528 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001529
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001531
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001532 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001533 if (!conn) {
1534 if (ev->link_type != SCO_LINK)
1535 goto unlock;
1536
1537 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1538 if (!conn)
1539 goto unlock;
1540
1541 conn->type = SCO_LINK;
1542 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001543
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001544 if (!ev->status) {
1545 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001546
1547 if (conn->type == ACL_LINK) {
1548 conn->state = BT_CONFIG;
1549 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001550 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedbergf7520542011-01-20 12:34:39 +02001551 mgmt_connected(hdev->id, &ev->bdaddr);
Marcel Holtmann769be972008-07-14 20:13:49 +02001552 } else
1553 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001554
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001555 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001556 hci_conn_add_sysfs(conn);
1557
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001558 if (test_bit(HCI_AUTH, &hdev->flags))
1559 conn->link_mode |= HCI_LM_AUTH;
1560
1561 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1562 conn->link_mode |= HCI_LM_ENCRYPT;
1563
1564 /* Get remote features */
1565 if (conn->type == ACL_LINK) {
1566 struct hci_cp_read_remote_features cp;
1567 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001568 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1569 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001570 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001571
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001572 /* Set packet type for incoming connection */
Marcel Holtmanna8746412008-07-14 20:13:46 +02001573 if (!conn->out && hdev->hci_ver < 3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001574 struct hci_cp_change_conn_ptype cp;
1575 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001576 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1577 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1578 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001579 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001580 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001581 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001582 if (conn->type == ACL_LINK)
1583 mgmt_connect_failed(hdev->id, &ev->bdaddr, ev->status);
1584 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001585
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001586 if (conn->type == ACL_LINK)
1587 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001588
Marcel Holtmann769be972008-07-14 20:13:49 +02001589 if (ev->status) {
1590 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001591 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001592 } else if (ev->link_type != ACL_LINK)
1593 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001594
1595unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001597
1598 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001599}
1600
Linus Torvalds1da177e2005-04-16 15:20:36 -07001601static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1602{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001603 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001604 int mask = hdev->link_mode;
1605
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001606 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1607 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608
1609 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1610
Szymon Janc138d22e2011-02-17 16:44:23 +01001611 if ((mask & HCI_LM_ACCEPT) &&
1612 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001613 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001614 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001615 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001616
1617 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001618
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001619 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1620 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001621 memcpy(ie->data.dev_class, ev->dev_class, 3);
1622
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1624 if (!conn) {
Nick Pellybbcda3b2010-02-11 11:54:28 -08001625 /* pkt_type not yet used for incoming connections */
1626 conn = hci_conn_add(hdev, ev->link_type, 0, &ev->bdaddr);
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001627 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001628 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001629 hci_dev_unlock(hdev);
1630 return;
1631 }
1632 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001633
Linus Torvalds1da177e2005-04-16 15:20:36 -07001634 memcpy(conn->dev_class, ev->dev_class, 3);
1635 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001636
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637 hci_dev_unlock(hdev);
1638
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001639 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1640 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001642 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001643
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001644 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1645 cp.role = 0x00; /* Become master */
1646 else
1647 cp.role = 0x01; /* Remain slave */
1648
1649 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1650 sizeof(cp), &cp);
1651 } else {
1652 struct hci_cp_accept_sync_conn_req cp;
1653
1654 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001655 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001656
1657 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1658 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001659 cp.max_latency = cpu_to_le16(0x000A);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001660 cp.content_format = cpu_to_le16(hdev->voice_setting);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001661 cp.retrans_effort = 0x01;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001662
1663 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1664 sizeof(cp), &cp);
1665 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001666 } else {
1667 /* Connection rejected */
1668 struct hci_cp_reject_conn_req cp;
1669
1670 bacpy(&cp.bdaddr, &ev->bdaddr);
1671 cp.reason = 0x0f;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001672 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001673 }
1674}
1675
Linus Torvalds1da177e2005-04-16 15:20:36 -07001676static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1677{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001678 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001679 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001680
1681 BT_DBG("%s status %d", hdev->name, ev->status);
1682
Johan Hedberg8962ee72011-01-20 12:40:27 +02001683 if (ev->status) {
1684 mgmt_disconnect_failed(hdev->id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001685 return;
Johan Hedberg8962ee72011-01-20 12:40:27 +02001686 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001687
1688 hci_dev_lock(hdev);
1689
Marcel Holtmann04837f62006-07-03 10:02:33 +02001690 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001691 if (!conn)
1692 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001693
Johan Hedbergf7520542011-01-20 12:34:39 +02001694 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001695
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001696 if (conn->type == ACL_LINK)
Johan Hedbergf7520542011-01-20 12:34:39 +02001697 mgmt_disconnected(hdev->id, &conn->dst);
1698
1699 hci_proto_disconn_cfm(conn, ev->reason);
1700 hci_conn_del(conn);
1701
1702unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001703 hci_dev_unlock(hdev);
1704}
1705
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001706static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1707{
1708 struct hci_ev_auth_complete *ev = (void *) skb->data;
1709 struct hci_conn *conn;
1710
1711 BT_DBG("%s status %d", hdev->name, ev->status);
1712
1713 hci_dev_lock(hdev);
1714
1715 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001716 if (conn) {
1717 if (ev->status == 0x06 && hdev->ssp_mode > 0 &&
1718 conn->ssp_mode > 0) {
1719 struct hci_cp_auth_requested cp;
1720 cp.handle = cpu_to_le16(conn->handle);
1721 hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
1722 sizeof(cp), &cp);
1723 hci_dev_unlock(hdev);
1724 BT_INFO("Pin or key missing");
1725 return;
1726 }
Waldemar Rymarkiewicz54444292011-05-31 15:49:26 +02001727
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001728 if (!ev->status) {
Waldemar Rymarkiewicz54444292011-05-31 15:49:26 +02001729 conn->link_mode |= HCI_LM_AUTH;
1730 conn->sec_level = conn->pending_sec_level;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001731 } else {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001732 mgmt_auth_failed(hdev->id, &conn->dst, ev->status);
1733 conn->sec_level = BT_SECURITY_LOW;
1734 }
1735
1736 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1737
1738 if (conn->state == BT_CONFIG) {
1739 if (!ev->status && hdev->ssp_mode > 0 &&
1740 conn->ssp_mode > 0) {
1741 struct hci_cp_set_conn_encrypt cp;
1742 cp.handle = ev->handle;
1743 cp.encrypt = 0x01;
1744 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1745 sizeof(cp), &cp);
1746 } else {
1747 conn->state = BT_CONNECTED;
1748 hci_proto_connect_cfm(conn, ev->status);
1749 hci_conn_put(conn);
1750 }
1751 } else {
1752 hci_auth_cfm(conn, ev->status);
1753
1754 hci_conn_hold(conn);
1755 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001756 hci_conn_put(conn);
1757 }
1758
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001759 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1760 if (!ev->status) {
1761 struct hci_cp_set_conn_encrypt cp;
1762 cp.handle = ev->handle;
1763 cp.encrypt = 0x01;
1764 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1765 sizeof(cp), &cp);
1766 } else {
1767 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1768 hci_encrypt_cfm(conn, ev->status, 0x00);
1769 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001770 }
1771 }
1772
1773 hci_dev_unlock(hdev);
1774}
1775
1776static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1777{
Johan Hedberg127178d2010-11-18 22:22:29 +02001778 struct hci_ev_remote_name *ev = (void *) skb->data;
1779 struct hci_conn *conn;
1780
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001781 BT_DBG("%s", hdev->name);
1782
1783 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001784
1785 hci_dev_lock(hdev);
1786
Johan Hedberga88a9652011-03-30 13:18:12 +03001787 if (ev->status == 0 && test_bit(HCI_MGMT, &hdev->flags))
1788 mgmt_remote_name(hdev->id, &ev->bdaddr, ev->name);
1789
Johan Hedberg127178d2010-11-18 22:22:29 +02001790 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001791 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedberg127178d2010-11-18 22:22:29 +02001792 struct hci_cp_auth_requested cp;
1793 cp.handle = __cpu_to_le16(conn->handle);
1794 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1795 }
1796
1797 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001798}
1799
1800static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1801{
1802 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1803 struct hci_conn *conn;
1804
1805 BT_DBG("%s status %d", hdev->name, ev->status);
1806
1807 hci_dev_lock(hdev);
1808
1809 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1810 if (conn) {
1811 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001812 if (ev->encrypt) {
1813 /* Encryption implies authentication */
1814 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001815 conn->link_mode |= HCI_LM_ENCRYPT;
Vinicius Costa Gomes64532ec2011-06-09 18:50:53 -03001816 conn->sec_level = conn->pending_sec_level;
Marcel Holtmannae293192008-07-14 20:13:45 +02001817 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001818 conn->link_mode &= ~HCI_LM_ENCRYPT;
1819 }
1820
1821 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1822
Marcel Holtmannf8558552008-07-14 20:13:49 +02001823 if (conn->state == BT_CONFIG) {
1824 if (!ev->status)
1825 conn->state = BT_CONNECTED;
1826
1827 hci_proto_connect_cfm(conn, ev->status);
1828 hci_conn_put(conn);
1829 } else
1830 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001831 }
1832
1833 hci_dev_unlock(hdev);
1834}
1835
1836static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1837{
1838 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1839 struct hci_conn *conn;
1840
1841 BT_DBG("%s status %d", hdev->name, ev->status);
1842
1843 hci_dev_lock(hdev);
1844
1845 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1846 if (conn) {
1847 if (!ev->status)
1848 conn->link_mode |= HCI_LM_SECURE;
1849
1850 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1851
1852 hci_key_change_cfm(conn, ev->status);
1853 }
1854
1855 hci_dev_unlock(hdev);
1856}
1857
1858static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1859{
1860 struct hci_ev_remote_features *ev = (void *) skb->data;
1861 struct hci_conn *conn;
1862
1863 BT_DBG("%s status %d", hdev->name, ev->status);
1864
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001865 hci_dev_lock(hdev);
1866
1867 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001868 if (!conn)
1869 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001870
Johan Hedbergccd556f2010-11-10 17:11:51 +02001871 if (!ev->status)
1872 memcpy(conn->features, ev->features, 8);
1873
1874 if (conn->state != BT_CONFIG)
1875 goto unlock;
1876
1877 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1878 struct hci_cp_read_remote_ext_features cp;
1879 cp.handle = ev->handle;
1880 cp.page = 0x01;
1881 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001882 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001883 goto unlock;
1884 }
1885
Johan Hedberg127178d2010-11-18 22:22:29 +02001886 if (!ev->status) {
1887 struct hci_cp_remote_name_req cp;
1888 memset(&cp, 0, sizeof(cp));
1889 bacpy(&cp.bdaddr, &conn->dst);
1890 cp.pscan_rep_mode = 0x02;
1891 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1892 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001893
Johan Hedberg127178d2010-11-18 22:22:29 +02001894 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001895 conn->state = BT_CONNECTED;
1896 hci_proto_connect_cfm(conn, ev->status);
1897 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001898 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001899
Johan Hedbergccd556f2010-11-10 17:11:51 +02001900unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001901 hci_dev_unlock(hdev);
1902}
1903
1904static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
1905{
1906 BT_DBG("%s", hdev->name);
1907}
1908
1909static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1910{
1911 BT_DBG("%s", hdev->name);
1912}
1913
1914static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1915{
1916 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1917 __u16 opcode;
1918
1919 skb_pull(skb, sizeof(*ev));
1920
1921 opcode = __le16_to_cpu(ev->opcode);
1922
1923 switch (opcode) {
1924 case HCI_OP_INQUIRY_CANCEL:
1925 hci_cc_inquiry_cancel(hdev, skb);
1926 break;
1927
1928 case HCI_OP_EXIT_PERIODIC_INQ:
1929 hci_cc_exit_periodic_inq(hdev, skb);
1930 break;
1931
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001932 case HCI_OP_LINK_KEY_REPLY:
1933 hci_cc_link_key_reply(hdev, skb);
1934 break;
1935
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001936 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1937 hci_cc_remote_name_req_cancel(hdev, skb);
1938 break;
1939
1940 case HCI_OP_ROLE_DISCOVERY:
1941 hci_cc_role_discovery(hdev, skb);
1942 break;
1943
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001944 case HCI_OP_READ_LINK_POLICY:
1945 hci_cc_read_link_policy(hdev, skb);
1946 break;
1947
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001948 case HCI_OP_WRITE_LINK_POLICY:
1949 hci_cc_write_link_policy(hdev, skb);
1950 break;
1951
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001952 case HCI_OP_READ_DEF_LINK_POLICY:
1953 hci_cc_read_def_link_policy(hdev, skb);
1954 break;
1955
1956 case HCI_OP_WRITE_DEF_LINK_POLICY:
1957 hci_cc_write_def_link_policy(hdev, skb);
1958 break;
1959
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001960 case HCI_OP_RESET:
1961 hci_cc_reset(hdev, skb);
1962 break;
1963
1964 case HCI_OP_WRITE_LOCAL_NAME:
1965 hci_cc_write_local_name(hdev, skb);
1966 break;
1967
1968 case HCI_OP_READ_LOCAL_NAME:
1969 hci_cc_read_local_name(hdev, skb);
1970 break;
1971
1972 case HCI_OP_WRITE_AUTH_ENABLE:
1973 hci_cc_write_auth_enable(hdev, skb);
1974 break;
1975
1976 case HCI_OP_WRITE_ENCRYPT_MODE:
1977 hci_cc_write_encrypt_mode(hdev, skb);
1978 break;
1979
1980 case HCI_OP_WRITE_SCAN_ENABLE:
1981 hci_cc_write_scan_enable(hdev, skb);
1982 break;
1983
1984 case HCI_OP_READ_CLASS_OF_DEV:
1985 hci_cc_read_class_of_dev(hdev, skb);
1986 break;
1987
1988 case HCI_OP_WRITE_CLASS_OF_DEV:
1989 hci_cc_write_class_of_dev(hdev, skb);
1990 break;
1991
1992 case HCI_OP_READ_VOICE_SETTING:
1993 hci_cc_read_voice_setting(hdev, skb);
1994 break;
1995
1996 case HCI_OP_WRITE_VOICE_SETTING:
1997 hci_cc_write_voice_setting(hdev, skb);
1998 break;
1999
2000 case HCI_OP_HOST_BUFFER_SIZE:
2001 hci_cc_host_buffer_size(hdev, skb);
2002 break;
2003
Marcel Holtmann333140b2008-07-14 20:13:48 +02002004 case HCI_OP_READ_SSP_MODE:
2005 hci_cc_read_ssp_mode(hdev, skb);
2006 break;
2007
2008 case HCI_OP_WRITE_SSP_MODE:
2009 hci_cc_write_ssp_mode(hdev, skb);
2010 break;
2011
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002012 case HCI_OP_READ_LOCAL_VERSION:
2013 hci_cc_read_local_version(hdev, skb);
2014 break;
2015
2016 case HCI_OP_READ_LOCAL_COMMANDS:
2017 hci_cc_read_local_commands(hdev, skb);
2018 break;
2019
2020 case HCI_OP_READ_LOCAL_FEATURES:
2021 hci_cc_read_local_features(hdev, skb);
2022 break;
2023
2024 case HCI_OP_READ_BUFFER_SIZE:
2025 hci_cc_read_buffer_size(hdev, skb);
2026 break;
2027
2028 case HCI_OP_READ_BD_ADDR:
2029 hci_cc_read_bd_addr(hdev, skb);
2030 break;
2031
Johan Hedberg23bb5762010-12-21 23:01:27 +02002032 case HCI_OP_WRITE_CA_TIMEOUT:
2033 hci_cc_write_ca_timeout(hdev, skb);
2034 break;
2035
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002036 case HCI_OP_READ_FLOW_CONTROL_MODE:
2037 hci_cc_read_flow_control_mode(hdev, skb);
2038 break;
2039
2040 case HCI_OP_READ_DATA_BLOCK_SIZE:
2041 hci_cc_read_data_block_size(hdev, skb);
2042 break;
2043
2044 case HCI_OP_READ_LOCAL_AMP_INFO:
2045 hci_cc_read_local_amp_info(hdev, skb);
2046 break;
2047
2048 case HCI_OP_READ_LOCAL_AMP_ASSOC:
2049 case HCI_OP_WRITE_REMOTE_AMP_ASSOC:
2050 hci_amp_cmd_complete(hdev, opcode, skb);
2051 break;
2052
Johan Hedbergb0916ea2011-01-10 13:44:55 +02002053 case HCI_OP_DELETE_STORED_LINK_KEY:
2054 hci_cc_delete_stored_link_key(hdev, skb);
2055 break;
2056
Johan Hedbergd5859e22011-01-25 01:19:58 +02002057 case HCI_OP_SET_EVENT_MASK:
2058 hci_cc_set_event_mask(hdev, skb);
2059 break;
2060
2061 case HCI_OP_WRITE_INQUIRY_MODE:
2062 hci_cc_write_inquiry_mode(hdev, skb);
2063 break;
2064
2065 case HCI_OP_READ_INQ_RSP_TX_POWER:
2066 hci_cc_read_inq_rsp_tx_power(hdev, skb);
2067 break;
2068
2069 case HCI_OP_SET_EVENT_FLT:
2070 hci_cc_set_event_flt(hdev, skb);
2071 break;
2072
Johan Hedberg980e1a52011-01-22 06:10:07 +02002073 case HCI_OP_PIN_CODE_REPLY:
2074 hci_cc_pin_code_reply(hdev, skb);
2075 break;
2076
2077 case HCI_OP_PIN_CODE_NEG_REPLY:
2078 hci_cc_pin_code_neg_reply(hdev, skb);
2079 break;
2080
Szymon Jancc35938b2011-03-22 13:12:21 +01002081 case HCI_OP_READ_LOCAL_OOB_DATA:
2082 hci_cc_read_local_oob_data_reply(hdev, skb);
2083 break;
2084
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002085 case HCI_OP_LE_READ_BUFFER_SIZE:
2086 hci_cc_le_read_buffer_size(hdev, skb);
2087 break;
2088
Johan Hedberga5c29682011-02-19 12:05:57 -03002089 case HCI_OP_USER_CONFIRM_REPLY:
2090 hci_cc_user_confirm_reply(hdev, skb);
2091 break;
2092
2093 case HCI_OP_USER_CONFIRM_NEG_REPLY:
2094 hci_cc_user_confirm_neg_reply(hdev, skb);
2095 break;
2096
Vinicius Costa Gomes735038c2011-06-09 18:50:47 -03002097 case HCI_OP_LE_LTK_REPLY:
2098 hci_cc_le_ltk_reply(hdev, skb);
2099 break;
2100
2101 case HCI_OP_LE_LTK_NEG_REPLY:
2102 hci_cc_le_ltk_neg_reply(hdev, skb);
2103 break;
2104
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002105 case HCI_OP_LE_SET_SCAN_ENABLE:
2106 hci_cc_le_set_scan_enable(hdev, skb);
Andre Guedese326af42011-06-30 19:20:53 -03002107 break;
2108
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002109 default:
2110 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2111 break;
2112 }
2113
Ville Tervo6bd32322011-02-16 16:32:41 +02002114 if (ev->opcode != HCI_OP_NOP)
2115 del_timer(&hdev->cmd_timer);
2116
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002117 if (ev->ncmd) {
2118 atomic_set(&hdev->cmd_cnt, 1);
2119 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01002120 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002121 }
2122}
2123
2124static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
2125{
2126 struct hci_ev_cmd_status *ev = (void *) skb->data;
2127 __u16 opcode;
2128
2129 skb_pull(skb, sizeof(*ev));
2130
2131 opcode = __le16_to_cpu(ev->opcode);
2132
2133 switch (opcode) {
2134 case HCI_OP_INQUIRY:
2135 hci_cs_inquiry(hdev, ev->status);
2136 break;
2137
2138 case HCI_OP_CREATE_CONN:
2139 hci_cs_create_conn(hdev, ev->status);
2140 break;
2141
2142 case HCI_OP_ADD_SCO:
2143 hci_cs_add_sco(hdev, ev->status);
2144 break;
2145
Marcel Holtmannf8558552008-07-14 20:13:49 +02002146 case HCI_OP_AUTH_REQUESTED:
2147 hci_cs_auth_requested(hdev, ev->status);
2148 break;
2149
2150 case HCI_OP_SET_CONN_ENCRYPT:
2151 hci_cs_set_conn_encrypt(hdev, ev->status);
2152 break;
2153
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002154 case HCI_OP_REMOTE_NAME_REQ:
2155 hci_cs_remote_name_req(hdev, ev->status);
2156 break;
2157
Marcel Holtmann769be972008-07-14 20:13:49 +02002158 case HCI_OP_READ_REMOTE_FEATURES:
2159 hci_cs_read_remote_features(hdev, ev->status);
2160 break;
2161
2162 case HCI_OP_READ_REMOTE_EXT_FEATURES:
2163 hci_cs_read_remote_ext_features(hdev, ev->status);
2164 break;
2165
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002166 case HCI_OP_SETUP_SYNC_CONN:
2167 hci_cs_setup_sync_conn(hdev, ev->status);
2168 break;
2169
2170 case HCI_OP_SNIFF_MODE:
2171 hci_cs_sniff_mode(hdev, ev->status);
2172 break;
2173
2174 case HCI_OP_EXIT_SNIFF_MODE:
2175 hci_cs_exit_sniff_mode(hdev, ev->status);
2176 break;
2177
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002178 case HCI_OP_CREATE_LOGICAL_LINK:
2179 hci_cs_create_logical_link(hdev, ev->status);
2180 break;
2181
2182 case HCI_OP_ACCEPT_LOGICAL_LINK:
2183 hci_cs_accept_logical_link(hdev, ev->status);
2184 break;
2185
2186 case HCI_OP_DISCONN_LOGICAL_LINK:
2187 hci_cs_disconn_logical_link(hdev, ev->status);
2188 break;
2189
2190 case HCI_OP_FLOW_SPEC_MODIFY:
2191 hci_cs_flow_spec_modify(hdev, ev->status);
2192 break;
2193
2194 case HCI_OP_CREATE_PHYS_LINK:
2195 case HCI_OP_ACCEPT_PHYS_LINK:
2196 hci_amp_cmd_status(hdev, opcode, ev->status);
2197 break;
2198
2199 case HCI_OP_DISCONN_PHYS_LINK:
2200 hci_cs_disconn_physical_link(hdev, ev->status);
2201
Johan Hedberg8962ee72011-01-20 12:40:27 +02002202 case HCI_OP_DISCONNECT:
2203 if (ev->status != 0)
2204 mgmt_disconnect_failed(hdev->id);
2205 break;
2206
Ville Tervofcd89c02011-02-10 22:38:47 -03002207 case HCI_OP_LE_CREATE_CONN:
2208 hci_cs_le_create_conn(hdev, ev->status);
2209 break;
2210
Vinicius Costa Gomes735038c2011-06-09 18:50:47 -03002211 case HCI_OP_LE_START_ENC:
2212 hci_cs_le_start_enc(hdev, ev->status);
2213 break;
2214
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002215 default:
2216 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
2217 break;
2218 }
2219
Ville Tervo6bd32322011-02-16 16:32:41 +02002220 if (ev->opcode != HCI_OP_NOP)
2221 del_timer(&hdev->cmd_timer);
2222
Gustavo F. Padovan10572132011-03-16 15:36:29 -03002223 if (ev->ncmd && !test_bit(HCI_RESET, &hdev->flags)) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002224 atomic_set(&hdev->cmd_cnt, 1);
2225 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01002226 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002227 }
2228}
2229
2230static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2231{
2232 struct hci_ev_role_change *ev = (void *) skb->data;
2233 struct hci_conn *conn;
2234
2235 BT_DBG("%s status %d", hdev->name, ev->status);
2236
2237 hci_dev_lock(hdev);
2238
2239 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2240 if (conn) {
2241 if (!ev->status) {
2242 if (ev->role)
2243 conn->link_mode &= ~HCI_LM_MASTER;
2244 else
2245 conn->link_mode |= HCI_LM_MASTER;
2246 }
2247
2248 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
2249
2250 hci_role_switch_cfm(conn, ev->status, ev->role);
2251 }
2252
2253 hci_dev_unlock(hdev);
2254}
2255
Linus Torvalds1da177e2005-04-16 15:20:36 -07002256static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
2257{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002258 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08002259 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002260 int i;
2261
2262 skb_pull(skb, sizeof(*ev));
2263
2264 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
2265
2266 if (skb->len < ev->num_hndl * 4) {
2267 BT_DBG("%s bad parameters", hdev->name);
2268 return;
2269 }
2270
2271 tasklet_disable(&hdev->tx_task);
2272
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08002273 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002274 struct hci_conn *conn = NULL;
2275 struct hci_chan *chan;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002276 __u16 handle, count;
2277
Harvey Harrison83985312008-05-02 16:25:46 -07002278 handle = get_unaligned_le16(ptr++);
2279 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002280
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002281 if (hdev->dev_type == HCI_BREDR)
2282 conn = hci_conn_hash_lookup_handle(hdev, handle);
2283 else {
2284 chan = hci_chan_list_lookup_handle(hdev, handle);
2285 if (chan)
2286 conn = chan->conn;
2287 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002288 if (conn) {
2289 conn->sent -= count;
2290
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002291 if (conn->type == ACL_LINK) {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002292 hdev->acl_cnt += count;
2293 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002294 hdev->acl_cnt = hdev->acl_pkts;
Ville Tervo6ed58ec2011-02-10 22:38:48 -03002295 } else if (conn->type == LE_LINK) {
2296 if (hdev->le_pkts) {
2297 hdev->le_cnt += count;
2298 if (hdev->le_cnt > hdev->le_pkts)
2299 hdev->le_cnt = hdev->le_pkts;
2300 } else {
2301 hdev->acl_cnt += count;
2302 if (hdev->acl_cnt > hdev->acl_pkts)
2303 hdev->acl_cnt = hdev->acl_pkts;
2304 }
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002305 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02002306 hdev->sco_cnt += count;
2307 if (hdev->sco_cnt > hdev->sco_pkts)
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02002308 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002309 }
2310 }
2311 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002312
Marcel Holtmannc78ae282009-11-18 01:02:54 +01002313 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002314
2315 tasklet_enable(&hdev->tx_task);
2316}
2317
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002318static inline void hci_num_comp_blocks_evt(struct hci_dev *hdev,
2319 struct sk_buff *skb)
2320{
2321 struct hci_ev_num_comp_blocks *ev = (void *) skb->data;
2322 __le16 *ptr;
2323 int i;
2324
2325 skb_pull(skb, sizeof(*ev));
2326
2327 BT_DBG("%s total_num_blocks %d num_hndl %d",
2328 hdev->name, ev->total_num_blocks, ev->num_hndl);
2329
2330 if (skb->len < ev->num_hndl * 6) {
2331 BT_DBG("%s bad parameters", hdev->name);
2332 return;
2333 }
2334
2335 tasklet_disable(&hdev->tx_task);
2336
2337 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
2338 struct hci_conn *conn = NULL;
2339 struct hci_chan *chan;
2340 __u16 handle, block_count;
2341
2342 handle = get_unaligned_le16(ptr++);
2343
2344 /* Skip packet count */
2345 ptr++;
2346 block_count = get_unaligned_le16(ptr++);
2347
2348 BT_DBG("%s handle %d count %d", hdev->name, handle,
2349 block_count);
2350
2351 if (hdev->dev_type == HCI_BREDR)
2352 conn = hci_conn_hash_lookup_handle(hdev, handle);
2353 else {
2354 chan = hci_chan_list_lookup_handle(hdev, handle);
2355 if (chan)
2356 conn = chan->conn;
2357 }
2358 if (conn) {
2359 BT_DBG("%s conn %p sent %d", hdev->name,
2360 conn, conn->sent);
2361
2362 conn->sent -= block_count;
2363
2364 if (conn->type == ACL_LINK) {
2365 hdev->acl_cnt += block_count;
2366 if (hdev->acl_cnt > hdev->acl_pkts)
2367 hdev->acl_cnt = hdev->acl_pkts;
2368 } else {
2369 /* We should not find ourselves here */
2370 BT_DBG("Unexpected event for SCO connection");
2371 }
2372 }
2373 }
2374
2375 tasklet_schedule(&hdev->tx_task);
2376
2377 tasklet_enable(&hdev->tx_task);
2378}
2379
Marcel Holtmann04837f62006-07-03 10:02:33 +02002380static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002381{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002382 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002383 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002384
2385 BT_DBG("%s status %d", hdev->name, ev->status);
2386
2387 hci_dev_lock(hdev);
2388
Marcel Holtmann04837f62006-07-03 10:02:33 +02002389 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2390 if (conn) {
2391 conn->mode = ev->mode;
2392 conn->interval = __le16_to_cpu(ev->interval);
2393
2394 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
2395 if (conn->mode == HCI_CM_ACTIVE)
2396 conn->power_save = 1;
2397 else
2398 conn->power_save = 0;
2399 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04002400
2401 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
2402 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002403 }
2404
2405 hci_dev_unlock(hdev);
2406}
2407
Linus Torvalds1da177e2005-04-16 15:20:36 -07002408static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2409{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002410 struct hci_ev_pin_code_req *ev = (void *) skb->data;
2411 struct hci_conn *conn;
2412
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002413 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002414
2415 hci_dev_lock(hdev);
2416
2417 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Marcel Holtmann3d7a9d12009-05-09 12:09:21 -07002418 if (conn && conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002419 hci_conn_hold(conn);
2420 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
2421 hci_conn_put(conn);
2422 }
2423
Johan Hedberg03b555e2011-01-04 15:40:05 +02002424 if (!test_bit(HCI_PAIRABLE, &hdev->flags))
2425 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
2426 sizeof(ev->bdaddr), &ev->bdaddr);
Waldemar Rymarkiewicza770bb52011-04-28 12:07:59 +02002427
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002428 if (test_bit(HCI_MGMT, &hdev->flags))
2429 mgmt_pin_code_request(hdev->id, &ev->bdaddr);
Johan Hedberg980e1a52011-01-22 06:10:07 +02002430
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002431 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002432}
2433
Linus Torvalds1da177e2005-04-16 15:20:36 -07002434static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2435{
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002436 struct hci_ev_link_key_req *ev = (void *) skb->data;
2437 struct hci_cp_link_key_reply cp;
2438 struct hci_conn *conn;
2439 struct link_key *key;
2440
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002441 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002442
2443 if (!test_bit(HCI_LINK_KEYS, &hdev->flags))
2444 return;
2445
2446 hci_dev_lock(hdev);
2447
2448 key = hci_find_link_key(hdev, &ev->bdaddr);
2449 if (!key) {
2450 BT_DBG("%s link key not found for %s", hdev->name,
2451 batostr(&ev->bdaddr));
2452 goto not_found;
2453 }
2454
2455 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
2456 batostr(&ev->bdaddr));
2457
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002458 if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) && key->type == 0x03) {
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002459 BT_DBG("%s ignoring debug key", hdev->name);
2460 goto not_found;
2461 }
2462
2463 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2464
Prabhakaran Mc6001a712011-09-06 11:56:25 +05302465 if (conn) {
2466 BT_DBG("Conn pending sec level is %d, ssp is %d, key len is %d",
2467 conn->pending_sec_level, conn->ssp_mode, key->pin_len);
2468 }
2469 if (conn && (conn->ssp_mode == 0) &&
2470 (conn->pending_sec_level == BT_SECURITY_HIGH) &&
2471 (key->pin_len != 16)) {
2472 BT_DBG("Security is high ignoring this key");
2473 goto not_found;
2474 }
2475
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002476 if (key->type == 0x04 && conn && conn->auth_type != 0xff &&
2477 (conn->auth_type & 0x01)) {
2478 BT_DBG("%s ignoring unauthenticated key", hdev->name);
2479 goto not_found;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002480 }
2481
2482 bacpy(&cp.bdaddr, &ev->bdaddr);
2483 memcpy(cp.link_key, key->val, 16);
2484
2485 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2486
2487 hci_dev_unlock(hdev);
2488
2489 return;
2490
2491not_found:
2492 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2493 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002494}
2495
Linus Torvalds1da177e2005-04-16 15:20:36 -07002496static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2497{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002498 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2499 struct hci_conn *conn;
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002500 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002501
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002502 BT_DBG("%s type %d", hdev->name, ev->key_type);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002503
2504 hci_dev_lock(hdev);
2505
2506 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2507 if (conn) {
2508 hci_conn_hold(conn);
2509 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002510
2511 memcpy(conn->link_key, ev->link_key, 16);
2512 conn->key_type = ev->key_type;
2513 hci_disconnect_amp(conn, 0x06);
2514
Johan Hedberg980e1a52011-01-22 06:10:07 +02002515 pin_len = conn->pin_length;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002516 hci_conn_put(conn);
2517 }
2518
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002519 if (test_bit(HCI_LINK_KEYS, &hdev->flags))
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002520 hci_add_link_key(hdev, 1, &ev->bdaddr, ev->link_key,
Johan Hedberg55ed8ca2011-01-17 14:41:05 +02002521 ev->key_type, pin_len);
2522
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002523 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002524}
2525
Marcel Holtmann04837f62006-07-03 10:02:33 +02002526static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2527{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002528 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002529 struct hci_conn *conn;
2530
2531 BT_DBG("%s status %d", hdev->name, ev->status);
2532
2533 hci_dev_lock(hdev);
2534
2535 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002536 if (conn && !ev->status) {
2537 struct inquiry_entry *ie;
2538
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002539 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2540 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541 ie->data.clock_offset = ev->clock_offset;
2542 ie->timestamp = jiffies;
2543 }
2544 }
2545
2546 hci_dev_unlock(hdev);
2547}
2548
Marcel Holtmanna8746412008-07-14 20:13:46 +02002549static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2550{
2551 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2552 struct hci_conn *conn;
2553
2554 BT_DBG("%s status %d", hdev->name, ev->status);
2555
2556 hci_dev_lock(hdev);
2557
2558 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2559 if (conn && !ev->status)
2560 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2561
2562 hci_dev_unlock(hdev);
2563}
2564
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002565static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2566{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002567 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002568 struct inquiry_entry *ie;
2569
2570 BT_DBG("%s", hdev->name);
2571
2572 hci_dev_lock(hdev);
2573
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002574 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2575 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002576 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2577 ie->timestamp = jiffies;
2578 }
2579
2580 hci_dev_unlock(hdev);
2581}
2582
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002583static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2584{
2585 struct inquiry_data data;
2586 int num_rsp = *((__u8 *) skb->data);
2587
2588 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2589
2590 if (!num_rsp)
2591 return;
2592
2593 hci_dev_lock(hdev);
2594
2595 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002596 struct inquiry_info_with_rssi_and_pscan_mode *info;
2597 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002598
Johan Hedberge17acd42011-03-30 23:57:16 +03002599 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002600 bacpy(&data.bdaddr, &info->bdaddr);
2601 data.pscan_rep_mode = info->pscan_rep_mode;
2602 data.pscan_period_mode = info->pscan_period_mode;
2603 data.pscan_mode = info->pscan_mode;
2604 memcpy(data.dev_class, info->dev_class, 3);
2605 data.clock_offset = info->clock_offset;
2606 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002607 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002608 hci_inquiry_cache_update(hdev, &data);
Johan Hedberge17acd42011-03-30 23:57:16 +03002609 mgmt_device_found(hdev->id, &info->bdaddr,
2610 info->dev_class, info->rssi,
2611 NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002612 }
2613 } else {
2614 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2615
Johan Hedberge17acd42011-03-30 23:57:16 +03002616 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002617 bacpy(&data.bdaddr, &info->bdaddr);
2618 data.pscan_rep_mode = info->pscan_rep_mode;
2619 data.pscan_period_mode = info->pscan_period_mode;
2620 data.pscan_mode = 0x00;
2621 memcpy(data.dev_class, info->dev_class, 3);
2622 data.clock_offset = info->clock_offset;
2623 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002624 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002625 hci_inquiry_cache_update(hdev, &data);
Johan Hedberge17acd42011-03-30 23:57:16 +03002626 mgmt_device_found(hdev->id, &info->bdaddr,
2627 info->dev_class, info->rssi,
2628 NULL);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002629 }
2630 }
2631
2632 hci_dev_unlock(hdev);
2633}
2634
2635static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2636{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002637 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2638 struct hci_conn *conn;
2639
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002640 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002641
Marcel Holtmann41a96212008-07-14 20:13:48 +02002642 hci_dev_lock(hdev);
2643
2644 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002645 if (!conn)
2646 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002647
Johan Hedbergccd556f2010-11-10 17:11:51 +02002648 if (!ev->status && ev->page == 0x01) {
2649 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002650
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002651 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2652 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002653 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002654
Johan Hedbergccd556f2010-11-10 17:11:51 +02002655 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002656 }
2657
Johan Hedbergccd556f2010-11-10 17:11:51 +02002658 if (conn->state != BT_CONFIG)
2659 goto unlock;
2660
Johan Hedberg127178d2010-11-18 22:22:29 +02002661 if (!ev->status) {
2662 struct hci_cp_remote_name_req cp;
2663 memset(&cp, 0, sizeof(cp));
2664 bacpy(&cp.bdaddr, &conn->dst);
2665 cp.pscan_rep_mode = 0x02;
2666 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
2667 }
Johan Hedberg392599b2010-11-18 22:22:28 +02002668
Johan Hedberg127178d2010-11-18 22:22:29 +02002669 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002670 conn->state = BT_CONNECTED;
2671 hci_proto_connect_cfm(conn, ev->status);
2672 hci_conn_put(conn);
2673 }
2674
2675unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002676 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002677}
2678
2679static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2680{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002681 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2682 struct hci_conn *conn;
2683
2684 BT_DBG("%s status %d", hdev->name, ev->status);
2685
2686 hci_dev_lock(hdev);
2687
2688 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002689 if (!conn) {
2690 if (ev->link_type == ESCO_LINK)
2691 goto unlock;
2692
2693 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2694 if (!conn)
2695 goto unlock;
2696
2697 conn->type = SCO_LINK;
2698 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002699
Marcel Holtmann732547f2009-04-19 19:14:14 +02002700 switch (ev->status) {
2701 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002702 conn->handle = __le16_to_cpu(ev->handle);
2703 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002704
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002705 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002706 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002707 break;
2708
Stephen Coe705e5712010-02-16 11:29:44 -05002709 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002710 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002711 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002712 case 0x1f: /* Unspecified error */
2713 if (conn->out && conn->attempt < 2) {
2714 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2715 (hdev->esco_type & EDR_ESCO_MASK);
2716 hci_setup_sync(conn, conn->link->handle);
2717 goto unlock;
2718 }
2719 /* fall through */
2720
2721 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002722 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002723 break;
2724 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002725
2726 hci_proto_connect_cfm(conn, ev->status);
2727 if (ev->status)
2728 hci_conn_del(conn);
2729
2730unlock:
2731 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002732}
2733
2734static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2735{
2736 BT_DBG("%s", hdev->name);
2737}
2738
Marcel Holtmann04837f62006-07-03 10:02:33 +02002739static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2740{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002741 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002742
2743 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002744}
2745
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002746static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2747{
2748 struct inquiry_data data;
2749 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2750 int num_rsp = *((__u8 *) skb->data);
2751
2752 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2753
2754 if (!num_rsp)
2755 return;
2756
2757 hci_dev_lock(hdev);
2758
Johan Hedberge17acd42011-03-30 23:57:16 +03002759 for (; num_rsp; num_rsp--, info++) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002760 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002761 data.pscan_rep_mode = info->pscan_rep_mode;
2762 data.pscan_period_mode = info->pscan_period_mode;
2763 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002764 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002765 data.clock_offset = info->clock_offset;
2766 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002767 data.ssp_mode = 0x01;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002768 hci_inquiry_cache_update(hdev, &data);
Johan Hedberge17acd42011-03-30 23:57:16 +03002769 mgmt_device_found(hdev->id, &info->bdaddr, info->dev_class,
2770 info->rssi, info->data);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002771 }
2772
2773 hci_dev_unlock(hdev);
2774}
2775
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002776static inline u8 hci_get_auth_req(struct hci_conn *conn)
2777{
2778 /* If remote requests dedicated bonding follow that lead */
2779 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2780 /* If both remote and local IO capabilities allow MITM
2781 * protection then require it, otherwise don't */
2782 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2783 return 0x02;
2784 else
2785 return 0x03;
2786 }
2787
2788 /* If remote requests no-bonding follow that lead */
2789 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002790 return 0x00;
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002791
2792 return conn->auth_type;
2793}
2794
Marcel Holtmann04936842008-07-14 20:13:48 +02002795static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2796{
2797 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2798 struct hci_conn *conn;
2799
2800 BT_DBG("%s", hdev->name);
2801
2802 hci_dev_lock(hdev);
2803
2804 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002805 if (!conn)
2806 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002807
Johan Hedberg03b555e2011-01-04 15:40:05 +02002808 hci_conn_hold(conn);
2809
2810 if (!test_bit(HCI_MGMT, &hdev->flags))
2811 goto unlock;
2812
2813 if (test_bit(HCI_PAIRABLE, &hdev->flags) ||
2814 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002815 struct hci_cp_io_capability_reply cp;
2816
2817 bacpy(&cp.bdaddr, &ev->bdaddr);
2818 cp.capability = conn->io_capability;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002819 cp.authentication = hci_get_auth_req(conn);
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002820
Szymon Jancce85ee12011-03-22 13:12:23 +01002821 if ((conn->out == 0x01 || conn->remote_oob == 0x01) &&
2822 hci_find_remote_oob_data(hdev, &conn->dst))
2823 cp.oob_data = 0x01;
2824 else
2825 cp.oob_data = 0x00;
2826
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002827 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
2828 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002829 } else {
2830 struct hci_cp_io_capability_neg_reply cp;
2831
2832 bacpy(&cp.bdaddr, &ev->bdaddr);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002833 cp.reason = 0x16; /* Pairing not allowed */
Johan Hedberg03b555e2011-01-04 15:40:05 +02002834
2835 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
2836 sizeof(cp), &cp);
2837 }
2838
2839unlock:
2840 hci_dev_unlock(hdev);
2841}
2842
2843static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
2844{
2845 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
2846 struct hci_conn *conn;
2847
2848 BT_DBG("%s", hdev->name);
2849
2850 hci_dev_lock(hdev);
2851
2852 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2853 if (!conn)
2854 goto unlock;
2855
Johan Hedberg03b555e2011-01-04 15:40:05 +02002856 conn->remote_cap = ev->capability;
2857 conn->remote_oob = ev->oob_data;
2858 conn->remote_auth = ev->authentication;
2859
2860unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002861 hci_dev_unlock(hdev);
2862}
2863
Johan Hedberga5c29682011-02-19 12:05:57 -03002864static inline void hci_user_confirm_request_evt(struct hci_dev *hdev,
2865 struct sk_buff *skb)
2866{
2867 struct hci_ev_user_confirm_req *ev = (void *) skb->data;
2868
2869 BT_DBG("%s", hdev->name);
2870
2871 hci_dev_lock(hdev);
2872
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002873 if (test_bit(HCI_MGMT, &hdev->flags))
2874 mgmt_user_confirm_request(hdev->id, &ev->bdaddr, ev->passkey);
Johan Hedberga5c29682011-02-19 12:05:57 -03002875
2876 hci_dev_unlock(hdev);
2877}
2878
Marcel Holtmann04936842008-07-14 20:13:48 +02002879static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2880{
2881 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
2882 struct hci_conn *conn;
2883
2884 BT_DBG("%s", hdev->name);
2885
2886 hci_dev_lock(hdev);
2887
2888 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg2a611692011-02-19 12:06:00 -03002889 if (!conn)
2890 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002891
Johan Hedberg2a611692011-02-19 12:06:00 -03002892 /* To avoid duplicate auth_failed events to user space we check
2893 * the HCI_CONN_AUTH_PEND flag which will be set if we
2894 * initiated the authentication. A traditional auth_complete
2895 * event gets always produced as initiator and is also mapped to
2896 * the mgmt_auth_failed event */
2897 if (!test_bit(HCI_CONN_AUTH_PEND, &conn->pend) && ev->status != 0)
2898 mgmt_auth_failed(hdev->id, &conn->dst, ev->status);
2899
2900 hci_conn_put(conn);
2901
2902unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002903 hci_dev_unlock(hdev);
2904}
2905
Marcel Holtmann41a96212008-07-14 20:13:48 +02002906static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2907{
2908 struct hci_ev_remote_host_features *ev = (void *) skb->data;
2909 struct inquiry_entry *ie;
2910
2911 BT_DBG("%s", hdev->name);
2912
2913 hci_dev_lock(hdev);
2914
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002915 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2916 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02002917 ie->data.ssp_mode = (ev->features[0] & 0x01);
2918
2919 hci_dev_unlock(hdev);
2920}
2921
Szymon Janc2763eda2011-03-22 13:12:22 +01002922static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
2923 struct sk_buff *skb)
2924{
2925 struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
2926 struct oob_data *data;
2927
2928 BT_DBG("%s", hdev->name);
2929
2930 hci_dev_lock(hdev);
2931
Szymon Jance1ba1f12011-04-06 13:01:59 +02002932 if (!test_bit(HCI_MGMT, &hdev->flags))
2933 goto unlock;
2934
Szymon Janc2763eda2011-03-22 13:12:22 +01002935 data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
2936 if (data) {
2937 struct hci_cp_remote_oob_data_reply cp;
2938
2939 bacpy(&cp.bdaddr, &ev->bdaddr);
2940 memcpy(cp.hash, data->hash, sizeof(cp.hash));
2941 memcpy(cp.randomizer, data->randomizer, sizeof(cp.randomizer));
2942
2943 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
2944 &cp);
2945 } else {
2946 struct hci_cp_remote_oob_data_neg_reply cp;
2947
2948 bacpy(&cp.bdaddr, &ev->bdaddr);
2949 hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
2950 &cp);
2951 }
2952
Szymon Jance1ba1f12011-04-06 13:01:59 +02002953unlock:
Szymon Janc2763eda2011-03-22 13:12:22 +01002954 hci_dev_unlock(hdev);
2955}
2956
Ville Tervofcd89c02011-02-10 22:38:47 -03002957static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2958{
2959 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
2960 struct hci_conn *conn;
2961
2962 BT_DBG("%s status %d", hdev->name, ev->status);
2963
2964 hci_dev_lock(hdev);
2965
2966 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03002967 if (!conn) {
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07002968 conn = hci_le_conn_add(hdev, &ev->bdaddr, ev->bdaddr_type);
Ville Tervob62f3282011-02-10 22:38:50 -03002969 if (!conn) {
2970 BT_ERR("No memory for new connection");
2971 hci_dev_unlock(hdev);
2972 return;
2973 }
2974 }
Ville Tervofcd89c02011-02-10 22:38:47 -03002975
2976 if (ev->status) {
2977 hci_proto_connect_cfm(conn, ev->status);
2978 conn->state = BT_CLOSED;
2979 hci_conn_del(conn);
2980 goto unlock;
2981 }
2982
Vinicius Costa Gomes403d2c82011-06-09 18:50:50 -03002983 conn->sec_level = BT_SECURITY_LOW;
Ville Tervofcd89c02011-02-10 22:38:47 -03002984 conn->handle = __le16_to_cpu(ev->handle);
2985 conn->state = BT_CONNECTED;
2986
2987 hci_conn_hold_device(conn);
2988 hci_conn_add_sysfs(conn);
2989
2990 hci_proto_connect_cfm(conn, ev->status);
2991
2992unlock:
2993 hci_dev_unlock(hdev);
2994}
2995
Vinicius Costa Gomes735038c2011-06-09 18:50:47 -03002996static inline void hci_le_ltk_request_evt(struct hci_dev *hdev,
2997 struct sk_buff *skb)
2998{
2999 struct hci_ev_le_ltk_req *ev = (void *) skb->data;
3000 struct hci_cp_le_ltk_reply cp;
Vinicius Costa Gomes60e56472011-07-07 18:59:37 -03003001 struct hci_cp_le_ltk_neg_reply neg;
Vinicius Costa Gomes735038c2011-06-09 18:50:47 -03003002 struct hci_conn *conn;
Vinicius Costa Gomes60e56472011-07-07 18:59:37 -03003003 struct link_key *ltk;
Vinicius Costa Gomes735038c2011-06-09 18:50:47 -03003004
3005 BT_DBG("%s handle %d", hdev->name, cpu_to_le16(ev->handle));
3006
3007 hci_dev_lock(hdev);
3008
3009 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Vinicius Costa Gomes60e56472011-07-07 18:59:37 -03003010 if (conn == NULL)
3011 goto not_found;
Vinicius Costa Gomes735038c2011-06-09 18:50:47 -03003012
Vinicius Costa Gomes60e56472011-07-07 18:59:37 -03003013 ltk = hci_find_ltk(hdev, ev->ediv, ev->random);
3014 if (ltk == NULL)
3015 goto not_found;
3016
3017 memcpy(cp.ltk, ltk->val, sizeof(ltk->val));
Vinicius Costa Gomes735038c2011-06-09 18:50:47 -03003018 cp.handle = cpu_to_le16(conn->handle);
Vinicius Costa Gomes1fa2de32011-07-08 18:31:45 -03003019 conn->pin_length = ltk->pin_len;
Vinicius Costa Gomes735038c2011-06-09 18:50:47 -03003020
3021 hci_send_cmd(hdev, HCI_OP_LE_LTK_REPLY, sizeof(cp), &cp);
3022
3023 hci_dev_unlock(hdev);
Vinicius Costa Gomes60e56472011-07-07 18:59:37 -03003024
3025 return;
3026
3027not_found:
3028 neg.handle = ev->handle;
3029 hci_send_cmd(hdev, HCI_OP_LE_LTK_NEG_REPLY, sizeof(neg), &neg);
3030 hci_dev_unlock(hdev);
Vinicius Costa Gomes735038c2011-06-09 18:50:47 -03003031}
3032
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003033static inline void hci_le_adv_report_evt(struct hci_dev *hdev,
3034 struct sk_buff *skb)
3035{
3036 struct hci_ev_le_advertising_info *ev;
3037 u8 num_reports;
3038
3039 num_reports = skb->data[0];
3040 ev = (void *) &skb->data[1];
3041 hci_add_adv_entry(hdev, ev);
3042
3043 while (--num_reports) {
3044 ev = (void *) (ev->data + ev->length + 1);
3045 hci_add_adv_entry(hdev, ev);
3046 }
3047}
3048
Ville Tervofcd89c02011-02-10 22:38:47 -03003049static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
3050{
3051 struct hci_ev_le_meta *le_ev = (void *) skb->data;
3052
3053 skb_pull(skb, sizeof(*le_ev));
3054
3055 switch (le_ev->subevent) {
3056 case HCI_EV_LE_CONN_COMPLETE:
3057 hci_le_conn_complete_evt(hdev, skb);
3058 break;
3059
Vinicius Costa Gomes735038c2011-06-09 18:50:47 -03003060 case HCI_EV_LE_LTK_REQ:
3061 hci_le_ltk_request_evt(hdev, skb);
3062 break;
3063
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003064 case HCI_EV_LE_ADVERTISING_REPORT:
3065 hci_le_adv_report_evt(hdev, skb);
3066 break;
3067
Ville Tervofcd89c02011-02-10 22:38:47 -03003068 default:
3069 break;
3070 }
3071}
3072
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003073static inline void hci_phy_link_complete(struct hci_dev *hdev,
3074 struct sk_buff *skb)
3075{
3076 struct hci_ev_phys_link_complete *ev = (void *) skb->data;
3077 struct hci_conn *conn;
3078
3079 BT_DBG("%s handle %d status %d", hdev->name, ev->phy_handle,
3080 ev->status);
3081
3082 hci_dev_lock(hdev);
3083
3084 if (ev->status == 0) {
3085 conn = hci_conn_add(hdev, ACL_LINK, 0, BDADDR_ANY);
3086 if (conn) {
3087 conn->handle = ev->phy_handle;
3088 conn->state = BT_CONNECTED;
3089
3090 hci_conn_hold(conn);
3091 conn->disc_timeout = HCI_DISCONN_TIMEOUT/2;
3092 hci_conn_put(conn);
3093
3094 hci_conn_hold_device(conn);
3095 hci_conn_add_sysfs(conn);
3096 } else
3097 BT_ERR("No memory for new connection");
3098 }
3099
3100 hci_dev_unlock(hdev);
3101}
3102
3103static inline void hci_log_link_complete(struct hci_dev *hdev,
3104 struct sk_buff *skb)
3105{
3106 struct hci_ev_log_link_complete *ev = (void *) skb->data;
3107 struct hci_chan *chan;
3108
3109 BT_DBG("%s handle %d status %d", hdev->name,
3110 __le16_to_cpu(ev->log_handle), ev->status);
3111
3112 hci_dev_lock(hdev);
3113
3114 chan = hci_chan_list_lookup_id(hdev, ev->phy_handle);
3115
3116 if (ev->status == 0) {
3117 if (chan) {
3118 chan->ll_handle = __le16_to_cpu(ev->log_handle);
3119 chan->state = BT_CONNECTED;
3120 hci_proto_create_cfm(chan, ev->status);
3121 hci_chan_hold(chan);
3122 }
3123 } else {
3124 if (chan) {
3125 chan->state = BT_CLOSED;
3126 hci_proto_create_cfm(chan, ev->status);
3127 hci_chan_del(chan);
3128 }
3129 }
3130
3131 hci_dev_unlock(hdev);
3132}
3133
3134static inline void hci_flow_spec_modify_complete(struct hci_dev *hdev,
3135 struct sk_buff *skb)
3136{
3137 struct hci_ev_flow_spec_modify_complete *ev = (void *) skb->data;
3138 struct hci_chan *chan;
3139
3140 BT_DBG("%s handle %d status %d", hdev->name,
3141 __le16_to_cpu(ev->log_handle), ev->status);
3142
3143 hci_dev_lock(hdev);
3144
3145 chan = hci_chan_list_lookup_handle(hdev, ev->log_handle);
3146 if (chan)
3147 hci_proto_modify_cfm(chan, ev->status);
3148
3149 hci_dev_unlock(hdev);
3150}
3151
3152static inline void hci_disconn_log_link_complete_evt(struct hci_dev *hdev,
3153 struct sk_buff *skb)
3154{
3155 struct hci_ev_disconn_log_link_complete *ev = (void *) skb->data;
3156 struct hci_chan *chan;
3157
3158 BT_DBG("%s handle %d status %d", hdev->name,
3159 __le16_to_cpu(ev->log_handle), ev->status);
3160
3161 if (ev->status)
3162 return;
3163
3164 hci_dev_lock(hdev);
3165
3166 chan = hci_chan_list_lookup_handle(hdev, __le16_to_cpu(ev->log_handle));
3167 if (chan) {
3168 hci_proto_destroy_cfm(chan, ev->reason);
3169 hci_chan_del(chan);
3170 }
3171
3172 hci_dev_unlock(hdev);
3173}
3174
3175static inline void hci_disconn_phy_link_complete_evt(struct hci_dev *hdev,
3176 struct sk_buff *skb)
3177{
3178 struct hci_ev_disconn_phys_link_complete *ev = (void *) skb->data;
3179 struct hci_conn *conn;
3180
3181 BT_DBG("%s status %d", hdev->name, ev->status);
3182
3183 if (ev->status)
3184 return;
3185
3186 hci_dev_lock(hdev);
3187
3188 conn = hci_conn_hash_lookup_handle(hdev, ev->phy_handle);
3189 if (conn) {
3190 conn->state = BT_CLOSED;
3191
3192 hci_proto_disconn_cfm(conn, ev->reason);
3193 hci_conn_del(conn);
3194 }
3195
3196 hci_dev_unlock(hdev);
3197}
3198
Linus Torvalds1da177e2005-04-16 15:20:36 -07003199void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
3200{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003201 struct hci_event_hdr *hdr = (void *) skb->data;
3202 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003203
3204 skb_pull(skb, HCI_EVENT_HDR_SIZE);
3205
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003206 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003207 case HCI_EV_INQUIRY_COMPLETE:
3208 hci_inquiry_complete_evt(hdev, skb);
3209 break;
3210
3211 case HCI_EV_INQUIRY_RESULT:
3212 hci_inquiry_result_evt(hdev, skb);
3213 break;
3214
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003215 case HCI_EV_CONN_COMPLETE:
3216 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02003217 break;
3218
Linus Torvalds1da177e2005-04-16 15:20:36 -07003219 case HCI_EV_CONN_REQUEST:
3220 hci_conn_request_evt(hdev, skb);
3221 break;
3222
Linus Torvalds1da177e2005-04-16 15:20:36 -07003223 case HCI_EV_DISCONN_COMPLETE:
3224 hci_disconn_complete_evt(hdev, skb);
3225 break;
3226
Linus Torvalds1da177e2005-04-16 15:20:36 -07003227 case HCI_EV_AUTH_COMPLETE:
3228 hci_auth_complete_evt(hdev, skb);
3229 break;
3230
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003231 case HCI_EV_REMOTE_NAME:
3232 hci_remote_name_evt(hdev, skb);
3233 break;
3234
Linus Torvalds1da177e2005-04-16 15:20:36 -07003235 case HCI_EV_ENCRYPT_CHANGE:
3236 hci_encrypt_change_evt(hdev, skb);
3237 break;
3238
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003239 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
3240 hci_change_link_key_complete_evt(hdev, skb);
3241 break;
3242
3243 case HCI_EV_REMOTE_FEATURES:
3244 hci_remote_features_evt(hdev, skb);
3245 break;
3246
3247 case HCI_EV_REMOTE_VERSION:
3248 hci_remote_version_evt(hdev, skb);
3249 break;
3250
3251 case HCI_EV_QOS_SETUP_COMPLETE:
3252 hci_qos_setup_complete_evt(hdev, skb);
3253 break;
3254
3255 case HCI_EV_CMD_COMPLETE:
3256 hci_cmd_complete_evt(hdev, skb);
3257 break;
3258
3259 case HCI_EV_CMD_STATUS:
3260 hci_cmd_status_evt(hdev, skb);
3261 break;
3262
3263 case HCI_EV_ROLE_CHANGE:
3264 hci_role_change_evt(hdev, skb);
3265 break;
3266
3267 case HCI_EV_NUM_COMP_PKTS:
3268 hci_num_comp_pkts_evt(hdev, skb);
3269 break;
3270
3271 case HCI_EV_MODE_CHANGE:
3272 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003273 break;
3274
3275 case HCI_EV_PIN_CODE_REQ:
3276 hci_pin_code_request_evt(hdev, skb);
3277 break;
3278
3279 case HCI_EV_LINK_KEY_REQ:
3280 hci_link_key_request_evt(hdev, skb);
3281 break;
3282
3283 case HCI_EV_LINK_KEY_NOTIFY:
3284 hci_link_key_notify_evt(hdev, skb);
3285 break;
3286
3287 case HCI_EV_CLOCK_OFFSET:
3288 hci_clock_offset_evt(hdev, skb);
3289 break;
3290
Marcel Holtmanna8746412008-07-14 20:13:46 +02003291 case HCI_EV_PKT_TYPE_CHANGE:
3292 hci_pkt_type_change_evt(hdev, skb);
3293 break;
3294
Marcel Holtmann85a1e932005-08-09 20:28:02 -07003295 case HCI_EV_PSCAN_REP_MODE:
3296 hci_pscan_rep_mode_evt(hdev, skb);
3297 break;
3298
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003299 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
3300 hci_inquiry_result_with_rssi_evt(hdev, skb);
3301 break;
3302
3303 case HCI_EV_REMOTE_EXT_FEATURES:
3304 hci_remote_ext_features_evt(hdev, skb);
3305 break;
3306
3307 case HCI_EV_SYNC_CONN_COMPLETE:
3308 hci_sync_conn_complete_evt(hdev, skb);
3309 break;
3310
3311 case HCI_EV_SYNC_CONN_CHANGED:
3312 hci_sync_conn_changed_evt(hdev, skb);
3313 break;
3314
Marcel Holtmann04837f62006-07-03 10:02:33 +02003315 case HCI_EV_SNIFF_SUBRATE:
3316 hci_sniff_subrate_evt(hdev, skb);
3317 break;
3318
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003319 case HCI_EV_EXTENDED_INQUIRY_RESULT:
3320 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003321 break;
3322
Marcel Holtmann04936842008-07-14 20:13:48 +02003323 case HCI_EV_IO_CAPA_REQUEST:
3324 hci_io_capa_request_evt(hdev, skb);
3325 break;
3326
Johan Hedberg03b555e2011-01-04 15:40:05 +02003327 case HCI_EV_IO_CAPA_REPLY:
3328 hci_io_capa_reply_evt(hdev, skb);
3329 break;
3330
Johan Hedberga5c29682011-02-19 12:05:57 -03003331 case HCI_EV_USER_CONFIRM_REQUEST:
3332 hci_user_confirm_request_evt(hdev, skb);
3333 break;
3334
Marcel Holtmann04936842008-07-14 20:13:48 +02003335 case HCI_EV_SIMPLE_PAIR_COMPLETE:
3336 hci_simple_pair_complete_evt(hdev, skb);
3337 break;
3338
Marcel Holtmann41a96212008-07-14 20:13:48 +02003339 case HCI_EV_REMOTE_HOST_FEATURES:
3340 hci_remote_host_features_evt(hdev, skb);
3341 break;
3342
Ville Tervofcd89c02011-02-10 22:38:47 -03003343 case HCI_EV_LE_META:
3344 hci_le_meta_evt(hdev, skb);
3345 break;
3346
Szymon Janc2763eda2011-03-22 13:12:22 +01003347 case HCI_EV_REMOTE_OOB_DATA_REQUEST:
3348 hci_remote_oob_data_request_evt(hdev, skb);
3349 break;
3350
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003351 case HCI_EV_PHYS_LINK_COMPLETE:
3352 hci_phy_link_complete(hdev, skb);
3353 hci_amp_event_packet(hdev, event, skb);
3354 break;
3355
3356 case HCI_EV_LOG_LINK_COMPLETE:
3357 hci_log_link_complete(hdev, skb);
3358 break;
3359
3360 case HCI_EV_FLOW_SPEC_MODIFY_COMPLETE:
3361 hci_flow_spec_modify_complete(hdev, skb);
3362 break;
3363
3364 case HCI_EV_DISCONN_LOG_LINK_COMPLETE:
3365 hci_disconn_log_link_complete_evt(hdev, skb);
3366 break;
3367
3368 case HCI_EV_DISCONN_PHYS_LINK_COMPLETE:
3369 hci_disconn_phy_link_complete_evt(hdev, skb);
3370 hci_amp_event_packet(hdev, event, skb);
3371 break;
3372
3373 case HCI_EV_NUM_COMP_BLOCKS:
3374 hci_num_comp_blocks_evt(hdev, skb);
3375 break;
3376
3377 case HCI_EV_CHANNEL_SELECTED:
3378 hci_amp_event_packet(hdev, event, skb);
3379 break;
3380
3381 case HCI_EV_AMP_STATUS_CHANGE:
3382 hci_amp_event_packet(hdev, event, skb);
3383 break;
3384
Marcel Holtmanna9de9242007-10-20 13:33:56 +02003385 default:
3386 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003387 break;
3388 }
3389
3390 kfree_skb(skb);
3391 hdev->stat.evt_rx++;
3392}
3393
3394/* Generate internal stack event */
3395void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
3396{
3397 struct hci_event_hdr *hdr;
3398 struct hci_ev_stack_internal *ev;
3399 struct sk_buff *skb;
3400
3401 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
3402 if (!skb)
3403 return;
3404
3405 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
3406 hdr->evt = HCI_EV_STACK_INTERNAL;
3407 hdr->plen = sizeof(*ev) + dlen;
3408
3409 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
3410 ev->type = type;
3411 memcpy(ev->data, data, dlen);
3412
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003413 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07003414 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02003415
Marcel Holtmann0d48d932005-08-09 20:30:28 -07003416 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003417 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02003418 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003419 kfree_skb(skb);
3420}