blob: 98b5764e43156e88d6f4daa725c44d40195dbea9 [file] [log] [blame]
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +09001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002 BlueZ - Bluetooth protocol stack for Linux
Ron Shaffer2d0a0342010-05-28 11:53:46 -04003 Copyright (c) 2000-2001, 2010, Code Aurora Forum. All rights reserved.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004
5 Written 2000,2001 by Maxim Krasnyansky <maxk@qualcomm.com>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation;
10
11 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
12 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.
14 IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) AND AUTHOR(S) BE LIABLE FOR ANY
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090015 CLAIM, OR ANY SPECIAL INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES
16 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +090020 ALL LIABILITY, INCLUDING LIABILITY FOR INFRINGEMENT OF ANY PATENTS,
21 COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS, RELATING TO USE OF THIS
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 SOFTWARE IS DISCLAIMED.
23*/
24
25/* Bluetooth HCI event handling. */
26
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <linux/module.h>
28
29#include <linux/types.h>
30#include <linux/errno.h>
31#include <linux/kernel.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070032#include <linux/slab.h>
33#include <linux/poll.h>
34#include <linux/fcntl.h>
35#include <linux/init.h>
36#include <linux/skbuff.h>
37#include <linux/interrupt.h>
38#include <linux/notifier.h>
39#include <net/sock.h>
40
41#include <asm/system.h>
Andrei Emeltchenko70f230202010-12-01 16:58:25 +020042#include <linux/uaccess.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070043#include <asm/unaligned.h>
44
45#include <net/bluetooth/bluetooth.h>
46#include <net/bluetooth/hci_core.h>
47
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
Marcel Holtmanna9de9242007-10-20 13:33:56 +020059 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
75 clear_bit(HCI_INQUIRY, &hdev->flags);
76
77 hci_conn_check_pending(hdev);
78}
79
80static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
81{
82 BT_DBG("%s", hdev->name);
83}
84
85static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
86{
87 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070088 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070089
Marcel Holtmanna9de9242007-10-20 13:33:56 +020090 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070091
Marcel Holtmanna9de9242007-10-20 13:33:56 +020092 if (rp->status)
93 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
Marcel Holtmanna9de9242007-10-20 13:33:56 +020095 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
Marcel Holtmanna9de9242007-10-20 13:33:56 +020097 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
98 if (conn) {
99 if (rp->role)
100 conn->link_mode &= ~HCI_LM_MASTER;
101 else
102 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200104
105 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106}
107
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200108static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
109{
110 struct hci_rp_read_link_policy *rp = (void *) skb->data;
111 struct hci_conn *conn;
112
113 BT_DBG("%s status 0x%x", hdev->name, rp->status);
114
115 if (rp->status)
116 return;
117
118 hci_dev_lock(hdev);
119
120 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
121 if (conn)
122 conn->link_policy = __le16_to_cpu(rp->policy);
123
124 hci_dev_unlock(hdev);
125}
126
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200127static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200129 struct hci_rp_write_link_policy *rp = (void *) skb->data;
130 struct hci_conn *conn;
131 void *sent;
132
133 BT_DBG("%s status 0x%x", hdev->name, rp->status);
134
135 if (rp->status)
136 return;
137
138 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
139 if (!sent)
140 return;
141
142 hci_dev_lock(hdev);
143
144 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200145 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700146 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200147
148 hci_dev_unlock(hdev);
149}
150
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200151static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
152{
153 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
154
155 BT_DBG("%s status 0x%x", hdev->name, rp->status);
156
157 if (rp->status)
158 return;
159
160 hdev->link_policy = __le16_to_cpu(rp->policy);
161}
162
163static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
164{
165 __u8 status = *((__u8 *) skb->data);
166 void *sent;
167
168 BT_DBG("%s status 0x%x", hdev->name, status);
169
170 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
171 if (!sent)
172 return;
173
174 if (!status)
175 hdev->link_policy = get_unaligned_le16(sent);
176
Johan Hedberg23bb5762010-12-21 23:01:27 +0200177 hci_req_complete(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, status);
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200178}
179
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200180static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
181{
182 __u8 status = *((__u8 *) skb->data);
183
184 BT_DBG("%s status 0x%x", hdev->name, status);
185
Johan Hedberg23bb5762010-12-21 23:01:27 +0200186 hci_req_complete(hdev, HCI_OP_RESET, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200187}
188
189static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
190{
191 __u8 status = *((__u8 *) skb->data);
192 void *sent;
193
194 BT_DBG("%s status 0x%x", hdev->name, status);
195
Marcel Holtmannf383f272008-07-14 20:13:47 +0200196 if (status)
197 return;
198
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200199 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
200 if (!sent)
201 return;
202
Marcel Holtmannf383f272008-07-14 20:13:47 +0200203 memcpy(hdev->dev_name, sent, 248);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200204}
205
206static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
207{
208 struct hci_rp_read_local_name *rp = (void *) skb->data;
209
210 BT_DBG("%s status 0x%x", hdev->name, rp->status);
211
212 if (rp->status)
213 return;
214
215 memcpy(hdev->dev_name, rp->name, 248);
216}
217
218static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
219{
220 __u8 status = *((__u8 *) skb->data);
221 void *sent;
222
223 BT_DBG("%s status 0x%x", hdev->name, status);
224
225 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
226 if (!sent)
227 return;
228
229 if (!status) {
230 __u8 param = *((__u8 *) sent);
231
232 if (param == AUTH_ENABLED)
233 set_bit(HCI_AUTH, &hdev->flags);
234 else
235 clear_bit(HCI_AUTH, &hdev->flags);
236 }
237
Johan Hedberg23bb5762010-12-21 23:01:27 +0200238 hci_req_complete(hdev, HCI_OP_WRITE_AUTH_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200239}
240
241static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
242{
243 __u8 status = *((__u8 *) skb->data);
244 void *sent;
245
246 BT_DBG("%s status 0x%x", hdev->name, status);
247
248 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
249 if (!sent)
250 return;
251
252 if (!status) {
253 __u8 param = *((__u8 *) sent);
254
255 if (param)
256 set_bit(HCI_ENCRYPT, &hdev->flags);
257 else
258 clear_bit(HCI_ENCRYPT, &hdev->flags);
259 }
260
Johan Hedberg23bb5762010-12-21 23:01:27 +0200261 hci_req_complete(hdev, HCI_OP_WRITE_ENCRYPT_MODE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200262}
263
264static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
265{
266 __u8 status = *((__u8 *) skb->data);
267 void *sent;
268
269 BT_DBG("%s status 0x%x", hdev->name, status);
270
271 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
272 if (!sent)
273 return;
274
275 if (!status) {
276 __u8 param = *((__u8 *) sent);
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200277 int old_pscan, old_iscan;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200278
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200279 old_pscan = test_and_clear_bit(HCI_PSCAN, &hdev->flags);
280 old_iscan = test_and_clear_bit(HCI_ISCAN, &hdev->flags);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200281
Johan Hedberg73f22f62010-12-29 16:00:25 +0200282 if (param & SCAN_INQUIRY) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200283 set_bit(HCI_ISCAN, &hdev->flags);
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200284 if (!old_iscan)
285 mgmt_discoverable(hdev->id, 1);
286 } else if (old_iscan)
Johan Hedberg73f22f62010-12-29 16:00:25 +0200287 mgmt_discoverable(hdev->id, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200288
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200289 if (param & SCAN_PAGE) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200290 set_bit(HCI_PSCAN, &hdev->flags);
Johan Hedberg9fbcbb42010-12-30 00:18:33 +0200291 if (!old_pscan)
292 mgmt_connectable(hdev->id, 1);
293 } else if (old_pscan)
294 mgmt_connectable(hdev->id, 0);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200295 }
296
Johan Hedberg23bb5762010-12-21 23:01:27 +0200297 hci_req_complete(hdev, HCI_OP_WRITE_SCAN_ENABLE, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200298}
299
300static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
301{
302 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
303
304 BT_DBG("%s status 0x%x", hdev->name, rp->status);
305
306 if (rp->status)
307 return;
308
309 memcpy(hdev->dev_class, rp->dev_class, 3);
310
311 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
312 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
313}
314
315static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
316{
317 __u8 status = *((__u8 *) skb->data);
318 void *sent;
319
320 BT_DBG("%s status 0x%x", hdev->name, status);
321
Marcel Holtmannf383f272008-07-14 20:13:47 +0200322 if (status)
323 return;
324
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200325 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
326 if (!sent)
327 return;
328
Marcel Holtmannf383f272008-07-14 20:13:47 +0200329 memcpy(hdev->dev_class, sent, 3);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200330}
331
332static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
333{
334 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200336
337 BT_DBG("%s status 0x%x", hdev->name, rp->status);
338
339 if (rp->status)
340 return;
341
342 setting = __le16_to_cpu(rp->voice_setting);
343
Marcel Holtmannf383f272008-07-14 20:13:47 +0200344 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200345 return;
346
347 hdev->voice_setting = setting;
348
349 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
350
351 if (hdev->notify) {
352 tasklet_disable(&hdev->tx_task);
353 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
354 tasklet_enable(&hdev->tx_task);
355 }
356}
357
358static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
359{
360 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200361 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362 void *sent;
363
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200364 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365
Marcel Holtmannf383f272008-07-14 20:13:47 +0200366 if (status)
367 return;
368
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200369 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
370 if (!sent)
371 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700372
Marcel Holtmannf383f272008-07-14 20:13:47 +0200373 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374
Marcel Holtmannf383f272008-07-14 20:13:47 +0200375 if (hdev->voice_setting == setting)
376 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377
Marcel Holtmannf383f272008-07-14 20:13:47 +0200378 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379
Marcel Holtmannf383f272008-07-14 20:13:47 +0200380 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
381
382 if (hdev->notify) {
383 tasklet_disable(&hdev->tx_task);
384 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
385 tasklet_enable(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386 }
387}
388
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200389static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200391 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200393 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700394
Johan Hedberg23bb5762010-12-21 23:01:27 +0200395 hci_req_complete(hdev, HCI_OP_HOST_BUFFER_SIZE, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396}
397
Marcel Holtmann333140b2008-07-14 20:13:48 +0200398static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
399{
400 struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
401
402 BT_DBG("%s status 0x%x", hdev->name, rp->status);
403
404 if (rp->status)
405 return;
406
407 hdev->ssp_mode = rp->mode;
408}
409
410static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
411{
412 __u8 status = *((__u8 *) skb->data);
413 void *sent;
414
415 BT_DBG("%s status 0x%x", hdev->name, status);
416
417 if (status)
418 return;
419
420 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
421 if (!sent)
422 return;
423
424 hdev->ssp_mode = *((__u8 *) sent);
425}
426
Johan Hedbergd5859e22011-01-25 01:19:58 +0200427static u8 hci_get_inquiry_mode(struct hci_dev *hdev)
428{
429 if (hdev->features[6] & LMP_EXT_INQ)
430 return 2;
431
432 if (hdev->features[3] & LMP_RSSI_INQ)
433 return 1;
434
435 if (hdev->manufacturer == 11 && hdev->hci_rev == 0x00 &&
436 hdev->lmp_subver == 0x0757)
437 return 1;
438
439 if (hdev->manufacturer == 15) {
440 if (hdev->hci_rev == 0x03 && hdev->lmp_subver == 0x6963)
441 return 1;
442 if (hdev->hci_rev == 0x09 && hdev->lmp_subver == 0x6963)
443 return 1;
444 if (hdev->hci_rev == 0x00 && hdev->lmp_subver == 0x6965)
445 return 1;
446 }
447
448 if (hdev->manufacturer == 31 && hdev->hci_rev == 0x2005 &&
449 hdev->lmp_subver == 0x1805)
450 return 1;
451
452 return 0;
453}
454
455static void hci_setup_inquiry_mode(struct hci_dev *hdev)
456{
457 u8 mode;
458
459 mode = hci_get_inquiry_mode(hdev);
460
461 hci_send_cmd(hdev, HCI_OP_WRITE_INQUIRY_MODE, 1, &mode);
462}
463
464static void hci_setup_event_mask(struct hci_dev *hdev)
465{
466 /* The second byte is 0xff instead of 0x9f (two reserved bits
467 * disabled) since a Broadcom 1.2 dongle doesn't respond to the
468 * command otherwise */
469 u8 events[8] = { 0xff, 0xff, 0xfb, 0xff, 0x00, 0x00, 0x00, 0x00 };
470
471 /* Events for 1.2 and newer controllers */
472 if (hdev->lmp_ver > 1) {
473 events[4] |= 0x01; /* Flow Specification Complete */
474 events[4] |= 0x02; /* Inquiry Result with RSSI */
475 events[4] |= 0x04; /* Read Remote Extended Features Complete */
476 events[5] |= 0x08; /* Synchronous Connection Complete */
477 events[5] |= 0x10; /* Synchronous Connection Changed */
478 }
479
480 if (hdev->features[3] & LMP_RSSI_INQ)
481 events[4] |= 0x04; /* Inquiry Result with RSSI */
482
483 if (hdev->features[5] & LMP_SNIFF_SUBR)
484 events[5] |= 0x20; /* Sniff Subrating */
485
486 if (hdev->features[5] & LMP_PAUSE_ENC)
487 events[5] |= 0x80; /* Encryption Key Refresh Complete */
488
489 if (hdev->features[6] & LMP_EXT_INQ)
490 events[5] |= 0x40; /* Extended Inquiry Result */
491
492 if (hdev->features[6] & LMP_NO_FLUSH)
493 events[7] |= 0x01; /* Enhanced Flush Complete */
494
495 if (hdev->features[7] & LMP_LSTO)
496 events[6] |= 0x80; /* Link Supervision Timeout Changed */
497
498 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
499 events[6] |= 0x01; /* IO Capability Request */
500 events[6] |= 0x02; /* IO Capability Response */
501 events[6] |= 0x04; /* User Confirmation Request */
502 events[6] |= 0x08; /* User Passkey Request */
503 events[6] |= 0x10; /* Remote OOB Data Request */
504 events[6] |= 0x20; /* Simple Pairing Complete */
505 events[7] |= 0x04; /* User Passkey Notification */
506 events[7] |= 0x08; /* Keypress Notification */
507 events[7] |= 0x10; /* Remote Host Supported
508 * Features Notification */
509 }
510
511 if (hdev->features[4] & LMP_LE)
512 events[7] |= 0x20; /* LE Meta-Event */
513
514 hci_send_cmd(hdev, HCI_OP_SET_EVENT_MASK, sizeof(events), events);
515}
516
517static void hci_setup(struct hci_dev *hdev)
518{
519 hci_setup_event_mask(hdev);
520
521 if (hdev->lmp_ver > 1)
522 hci_send_cmd(hdev, HCI_OP_READ_LOCAL_COMMANDS, 0, NULL);
523
524 if (hdev->features[6] & LMP_SIMPLE_PAIR) {
525 u8 mode = 0x01;
526 hci_send_cmd(hdev, HCI_OP_WRITE_SSP_MODE, sizeof(mode), &mode);
527 }
528
529 if (hdev->features[3] & LMP_RSSI_INQ)
530 hci_setup_inquiry_mode(hdev);
531
532 if (hdev->features[7] & LMP_INQ_TX_PWR)
533 hci_send_cmd(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, 0, NULL);
534}
535
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200536static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
537{
538 struct hci_rp_read_local_version *rp = (void *) skb->data;
539
540 BT_DBG("%s status 0x%x", hdev->name, rp->status);
541
542 if (rp->status)
543 return;
544
545 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200546 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200547 hdev->lmp_ver = rp->lmp_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200548 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200549 hdev->lmp_subver = __le16_to_cpu(rp->lmp_subver);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200550
551 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
552 hdev->manufacturer,
553 hdev->hci_ver, hdev->hci_rev);
Johan Hedbergd5859e22011-01-25 01:19:58 +0200554
555 if (test_bit(HCI_INIT, &hdev->flags))
556 hci_setup(hdev);
557}
558
559static void hci_setup_link_policy(struct hci_dev *hdev)
560{
561 u16 link_policy = 0;
562
563 if (hdev->features[0] & LMP_RSWITCH)
564 link_policy |= HCI_LP_RSWITCH;
565 if (hdev->features[0] & LMP_HOLD)
566 link_policy |= HCI_LP_HOLD;
567 if (hdev->features[0] & LMP_SNIFF)
568 link_policy |= HCI_LP_SNIFF;
569 if (hdev->features[1] & LMP_PARK)
570 link_policy |= HCI_LP_PARK;
571
572 link_policy = cpu_to_le16(link_policy);
573 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY,
574 sizeof(link_policy), &link_policy);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200575}
576
577static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
578{
579 struct hci_rp_read_local_commands *rp = (void *) skb->data;
580
581 BT_DBG("%s status 0x%x", hdev->name, rp->status);
582
583 if (rp->status)
Johan Hedbergd5859e22011-01-25 01:19:58 +0200584 goto done;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200585
586 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
Johan Hedbergd5859e22011-01-25 01:19:58 +0200587
588 if (test_bit(HCI_INIT, &hdev->flags) && (hdev->commands[5] & 0x10))
589 hci_setup_link_policy(hdev);
590
591done:
592 hci_req_complete(hdev, HCI_OP_READ_LOCAL_COMMANDS, rp->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200593}
594
595static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
596{
597 struct hci_rp_read_local_features *rp = (void *) skb->data;
598
599 BT_DBG("%s status 0x%x", hdev->name, rp->status);
600
601 if (rp->status)
602 return;
603
604 memcpy(hdev->features, rp->features, 8);
605
606 /* Adjust default settings according to features
607 * supported by device. */
608
609 if (hdev->features[0] & LMP_3SLOT)
610 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
611
612 if (hdev->features[0] & LMP_5SLOT)
613 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
614
615 if (hdev->features[1] & LMP_HV2) {
616 hdev->pkt_type |= (HCI_HV2);
617 hdev->esco_type |= (ESCO_HV2);
618 }
619
620 if (hdev->features[1] & LMP_HV3) {
621 hdev->pkt_type |= (HCI_HV3);
622 hdev->esco_type |= (ESCO_HV3);
623 }
624
625 if (hdev->features[3] & LMP_ESCO)
626 hdev->esco_type |= (ESCO_EV3);
627
628 if (hdev->features[4] & LMP_EV4)
629 hdev->esco_type |= (ESCO_EV4);
630
631 if (hdev->features[4] & LMP_EV5)
632 hdev->esco_type |= (ESCO_EV5);
633
Marcel Holtmannefc76882009-02-06 09:13:37 +0100634 if (hdev->features[5] & LMP_EDR_ESCO_2M)
635 hdev->esco_type |= (ESCO_2EV3);
636
637 if (hdev->features[5] & LMP_EDR_ESCO_3M)
638 hdev->esco_type |= (ESCO_3EV3);
639
640 if (hdev->features[5] & LMP_EDR_3S_ESCO)
641 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
642
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200643 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
644 hdev->features[0], hdev->features[1],
645 hdev->features[2], hdev->features[3],
646 hdev->features[4], hdev->features[5],
647 hdev->features[6], hdev->features[7]);
648}
649
650static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
651{
652 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
653
654 BT_DBG("%s status 0x%x", hdev->name, rp->status);
655
656 if (rp->status)
657 return;
658
659 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
660 hdev->sco_mtu = rp->sco_mtu;
661 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
662 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
663
664 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
665 hdev->sco_mtu = 64;
666 hdev->sco_pkts = 8;
667 }
668
669 hdev->acl_cnt = hdev->acl_pkts;
670 hdev->sco_cnt = hdev->sco_pkts;
671
672 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
673 hdev->acl_mtu, hdev->acl_pkts,
674 hdev->sco_mtu, hdev->sco_pkts);
675}
676
677static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
678{
679 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
680
681 BT_DBG("%s status 0x%x", hdev->name, rp->status);
682
683 if (!rp->status)
684 bacpy(&hdev->bdaddr, &rp->bdaddr);
685
Johan Hedberg23bb5762010-12-21 23:01:27 +0200686 hci_req_complete(hdev, HCI_OP_READ_BD_ADDR, rp->status);
687}
688
689static void hci_cc_write_ca_timeout(struct hci_dev *hdev, struct sk_buff *skb)
690{
691 __u8 status = *((__u8 *) skb->data);
692
693 BT_DBG("%s status 0x%x", hdev->name, status);
694
695 hci_req_complete(hdev, HCI_OP_WRITE_CA_TIMEOUT, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200696}
697
Johan Hedbergb0916ea2011-01-10 13:44:55 +0200698static void hci_cc_delete_stored_link_key(struct hci_dev *hdev,
699 struct sk_buff *skb)
700{
701 __u8 status = *((__u8 *) skb->data);
702
703 BT_DBG("%s status 0x%x", hdev->name, status);
704
705 hci_req_complete(hdev, HCI_OP_DELETE_STORED_LINK_KEY, status);
706}
707
Johan Hedbergd5859e22011-01-25 01:19:58 +0200708static void hci_cc_set_event_mask(struct hci_dev *hdev, struct sk_buff *skb)
709{
710 __u8 status = *((__u8 *) skb->data);
711
712 BT_DBG("%s status 0x%x", hdev->name, status);
713
714 hci_req_complete(hdev, HCI_OP_SET_EVENT_MASK, status);
715}
716
717static void hci_cc_write_inquiry_mode(struct hci_dev *hdev,
718 struct sk_buff *skb)
719{
720 __u8 status = *((__u8 *) skb->data);
721
722 BT_DBG("%s status 0x%x", hdev->name, status);
723
724 hci_req_complete(hdev, HCI_OP_WRITE_INQUIRY_MODE, status);
725}
726
727static void hci_cc_read_inq_rsp_tx_power(struct hci_dev *hdev,
728 struct sk_buff *skb)
729{
730 __u8 status = *((__u8 *) skb->data);
731
732 BT_DBG("%s status 0x%x", hdev->name, status);
733
734 hci_req_complete(hdev, HCI_OP_READ_INQ_RSP_TX_POWER, status);
735}
736
737static void hci_cc_set_event_flt(struct hci_dev *hdev, struct sk_buff *skb)
738{
739 __u8 status = *((__u8 *) skb->data);
740
741 BT_DBG("%s status 0x%x", hdev->name, status);
742
743 hci_req_complete(hdev, HCI_OP_SET_EVENT_FLT, status);
744}
745
Johan Hedberg980e1a52011-01-22 06:10:07 +0200746static void hci_cc_pin_code_reply(struct hci_dev *hdev, struct sk_buff *skb)
747{
748 struct hci_rp_pin_code_reply *rp = (void *) skb->data;
749 struct hci_cp_pin_code_reply *cp;
750 struct hci_conn *conn;
751
752 BT_DBG("%s status 0x%x", hdev->name, rp->status);
753
754 if (test_bit(HCI_MGMT, &hdev->flags))
755 mgmt_pin_code_reply_complete(hdev->id, &rp->bdaddr, rp->status);
756
757 if (rp->status != 0)
758 return;
759
760 cp = hci_sent_cmd_data(hdev, HCI_OP_PIN_CODE_REPLY);
761 if (!cp)
762 return;
763
764 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
765 if (conn)
766 conn->pin_length = cp->pin_len;
767}
768
769static void hci_cc_pin_code_neg_reply(struct hci_dev *hdev, struct sk_buff *skb)
770{
771 struct hci_rp_pin_code_neg_reply *rp = (void *) skb->data;
772
773 BT_DBG("%s status 0x%x", hdev->name, rp->status);
774
775 if (test_bit(HCI_MGMT, &hdev->flags))
776 mgmt_pin_code_neg_reply_complete(hdev->id, &rp->bdaddr,
777 rp->status);
778}
Ville Tervo6ed58ec2011-02-10 22:38:48 -0300779static void hci_cc_le_read_buffer_size(struct hci_dev *hdev,
780 struct sk_buff *skb)
781{
782 struct hci_rp_le_read_buffer_size *rp = (void *) skb->data;
783
784 BT_DBG("%s status 0x%x", hdev->name, rp->status);
785
786 if (rp->status)
787 return;
788
789 hdev->le_mtu = __le16_to_cpu(rp->le_mtu);
790 hdev->le_pkts = rp->le_max_pkt;
791
792 hdev->le_cnt = hdev->le_pkts;
793
794 BT_DBG("%s le mtu %d:%d", hdev->name, hdev->le_mtu, hdev->le_pkts);
795
796 hci_req_complete(hdev, HCI_OP_LE_READ_BUFFER_SIZE, rp->status);
797}
Johan Hedberg980e1a52011-01-22 06:10:07 +0200798
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200799static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
800{
801 BT_DBG("%s status 0x%x", hdev->name, status);
802
803 if (status) {
Johan Hedberg23bb5762010-12-21 23:01:27 +0200804 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200805
806 hci_conn_check_pending(hdev);
807 } else
808 set_bit(HCI_INQUIRY, &hdev->flags);
809}
810
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
812{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200813 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200816 BT_DBG("%s status 0x%x", hdev->name, status);
817
818 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 if (!cp)
820 return;
821
822 hci_dev_lock(hdev);
823
824 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
825
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200826 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700827
828 if (status) {
829 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +0200830 if (status != 0x0c || conn->attempt > 2) {
831 conn->state = BT_CLOSED;
832 hci_proto_connect_cfm(conn, status);
833 hci_conn_del(conn);
834 } else
835 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836 }
837 } else {
838 if (!conn) {
839 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
840 if (conn) {
841 conn->out = 1;
842 conn->link_mode |= HCI_LM_MASTER;
843 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -0300844 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700845 }
846 }
847
848 hci_dev_unlock(hdev);
849}
850
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200851static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700852{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200853 struct hci_cp_add_sco *cp;
854 struct hci_conn *acl, *sco;
855 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200857 BT_DBG("%s status 0x%x", hdev->name, status);
858
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200859 if (!status)
860 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700861
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200862 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
863 if (!cp)
864 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700865
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200866 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200868 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100869
870 hci_dev_lock(hdev);
871
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200872 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +0200873 if (acl) {
874 sco = acl->link;
875 if (sco) {
876 sco->state = BT_CLOSED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200877
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +0200878 hci_proto_connect_cfm(sco, status);
879 hci_conn_del(sco);
880 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200881 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100882
883 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700884}
885
Marcel Holtmannf8558552008-07-14 20:13:49 +0200886static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
887{
888 struct hci_cp_auth_requested *cp;
889 struct hci_conn *conn;
890
891 BT_DBG("%s status 0x%x", hdev->name, status);
892
893 if (!status)
894 return;
895
896 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
897 if (!cp)
898 return;
899
900 hci_dev_lock(hdev);
901
902 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
903 if (conn) {
904 if (conn->state == BT_CONFIG) {
905 hci_proto_connect_cfm(conn, status);
906 hci_conn_put(conn);
907 }
908 }
909
910 hci_dev_unlock(hdev);
911}
912
913static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
914{
915 struct hci_cp_set_conn_encrypt *cp;
916 struct hci_conn *conn;
917
918 BT_DBG("%s status 0x%x", hdev->name, status);
919
920 if (!status)
921 return;
922
923 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
924 if (!cp)
925 return;
926
927 hci_dev_lock(hdev);
928
929 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
930 if (conn) {
931 if (conn->state == BT_CONFIG) {
932 hci_proto_connect_cfm(conn, status);
933 hci_conn_put(conn);
934 }
935 }
936
937 hci_dev_unlock(hdev);
938}
939
Johan Hedberg127178d2010-11-18 22:22:29 +0200940static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Szymon Janc138d22e2011-02-17 16:44:23 +0100941 struct hci_conn *conn)
Johan Hedberg392599b2010-11-18 22:22:28 +0200942{
Johan Hedberg392599b2010-11-18 22:22:28 +0200943 if (conn->state != BT_CONFIG || !conn->out)
944 return 0;
945
Johan Hedberg765c2a92011-01-19 12:06:52 +0530946 if (conn->pending_sec_level == BT_SECURITY_SDP)
Johan Hedberg392599b2010-11-18 22:22:28 +0200947 return 0;
948
949 /* Only request authentication for SSP connections or non-SSP
950 * devices with sec_level HIGH */
951 if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
Johan Hedberg765c2a92011-01-19 12:06:52 +0530952 conn->pending_sec_level != BT_SECURITY_HIGH)
Johan Hedberg392599b2010-11-18 22:22:28 +0200953 return 0;
954
Johan Hedberg392599b2010-11-18 22:22:28 +0200955 return 1;
956}
957
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200958static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
959{
Johan Hedberg127178d2010-11-18 22:22:29 +0200960 struct hci_cp_remote_name_req *cp;
961 struct hci_conn *conn;
962
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200963 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +0200964
965 /* If successful wait for the name req complete event before
966 * checking for the need to do authentication */
967 if (!status)
968 return;
969
970 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
971 if (!cp)
972 return;
973
974 hci_dev_lock(hdev);
975
976 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
977 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
978 struct hci_cp_auth_requested cp;
979 cp.handle = __cpu_to_le16(conn->handle);
980 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
981 }
982
983 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200984}
985
Marcel Holtmann769be972008-07-14 20:13:49 +0200986static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
987{
988 struct hci_cp_read_remote_features *cp;
989 struct hci_conn *conn;
990
991 BT_DBG("%s status 0x%x", hdev->name, status);
992
993 if (!status)
994 return;
995
996 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
997 if (!cp)
998 return;
999
1000 hci_dev_lock(hdev);
1001
1002 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1003 if (conn) {
1004 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001005 hci_proto_connect_cfm(conn, status);
1006 hci_conn_put(conn);
1007 }
1008 }
1009
1010 hci_dev_unlock(hdev);
1011}
1012
1013static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
1014{
1015 struct hci_cp_read_remote_ext_features *cp;
1016 struct hci_conn *conn;
1017
1018 BT_DBG("%s status 0x%x", hdev->name, status);
1019
1020 if (!status)
1021 return;
1022
1023 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
1024 if (!cp)
1025 return;
1026
1027 hci_dev_lock(hdev);
1028
1029 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
1030 if (conn) {
1031 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +02001032 hci_proto_connect_cfm(conn, status);
1033 hci_conn_put(conn);
1034 }
1035 }
1036
1037 hci_dev_unlock(hdev);
1038}
1039
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001040static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
1041{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001042 struct hci_cp_setup_sync_conn *cp;
1043 struct hci_conn *acl, *sco;
1044 __u16 handle;
1045
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001046 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001047
1048 if (!status)
1049 return;
1050
1051 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
1052 if (!cp)
1053 return;
1054
1055 handle = __le16_to_cpu(cp->handle);
1056
1057 BT_DBG("%s handle %d", hdev->name, handle);
1058
1059 hci_dev_lock(hdev);
1060
1061 acl = hci_conn_hash_lookup_handle(hdev, handle);
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001062 if (acl) {
1063 sco = acl->link;
1064 if (sco) {
1065 sco->state = BT_CLOSED;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001066
Andrei Emeltchenko5a08ecc2011-01-11 17:20:20 +02001067 hci_proto_connect_cfm(sco, status);
1068 hci_conn_del(sco);
1069 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001070 }
1071
1072 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001073}
1074
1075static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
1076{
1077 struct hci_cp_sniff_mode *cp;
1078 struct hci_conn *conn;
1079
1080 BT_DBG("%s status 0x%x", hdev->name, status);
1081
1082 if (!status)
1083 return;
1084
1085 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
1086 if (!cp)
1087 return;
1088
1089 hci_dev_lock(hdev);
1090
1091 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001092 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001093 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1094
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001095 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1096 hci_sco_setup(conn, status);
1097 }
1098
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001099 hci_dev_unlock(hdev);
1100}
1101
1102static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
1103{
1104 struct hci_cp_exit_sniff_mode *cp;
1105 struct hci_conn *conn;
1106
1107 BT_DBG("%s status 0x%x", hdev->name, status);
1108
1109 if (!status)
1110 return;
1111
1112 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
1113 if (!cp)
1114 return;
1115
1116 hci_dev_lock(hdev);
1117
1118 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001119 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001120 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
1121
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001122 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1123 hci_sco_setup(conn, status);
1124 }
1125
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001126 hci_dev_unlock(hdev);
1127}
1128
Ville Tervofcd89c02011-02-10 22:38:47 -03001129static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
1130{
1131 struct hci_cp_le_create_conn *cp;
1132 struct hci_conn *conn;
1133
1134 BT_DBG("%s status 0x%x", hdev->name, status);
1135
1136 cp = hci_sent_cmd_data(hdev, HCI_OP_LE_CREATE_CONN);
1137 if (!cp)
1138 return;
1139
1140 hci_dev_lock(hdev);
1141
1142 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &cp->peer_addr);
1143
1144 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->peer_addr),
1145 conn);
1146
1147 if (status) {
1148 if (conn && conn->state == BT_CONNECT) {
1149 conn->state = BT_CLOSED;
1150 hci_proto_connect_cfm(conn, status);
1151 hci_conn_del(conn);
1152 }
1153 } else {
1154 if (!conn) {
1155 conn = hci_conn_add(hdev, LE_LINK, &cp->peer_addr);
1156 if (conn)
1157 conn->out = 1;
1158 else
1159 BT_ERR("No memory for new connection");
1160 }
1161 }
1162
1163 hci_dev_unlock(hdev);
1164}
1165
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001166static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1167{
1168 __u8 status = *((__u8 *) skb->data);
1169
1170 BT_DBG("%s status %d", hdev->name, status);
1171
1172 clear_bit(HCI_INQUIRY, &hdev->flags);
1173
Johan Hedberg23bb5762010-12-21 23:01:27 +02001174 hci_req_complete(hdev, HCI_OP_INQUIRY, status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001175
1176 hci_conn_check_pending(hdev);
1177}
1178
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1180{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001181 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001182 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183 int num_rsp = *((__u8 *) skb->data);
1184
1185 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1186
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001187 if (!num_rsp)
1188 return;
1189
Linus Torvalds1da177e2005-04-16 15:20:36 -07001190 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001191
Linus Torvalds1da177e2005-04-16 15:20:36 -07001192 for (; num_rsp; num_rsp--) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 bacpy(&data.bdaddr, &info->bdaddr);
1194 data.pscan_rep_mode = info->pscan_rep_mode;
1195 data.pscan_period_mode = info->pscan_period_mode;
1196 data.pscan_mode = info->pscan_mode;
1197 memcpy(data.dev_class, info->dev_class, 3);
1198 data.clock_offset = info->clock_offset;
1199 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001200 data.ssp_mode = 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001201 info++;
1202 hci_inquiry_cache_update(hdev, &data);
1203 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001204
Linus Torvalds1da177e2005-04-16 15:20:36 -07001205 hci_dev_unlock(hdev);
1206}
1207
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001208static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001210 struct hci_ev_conn_complete *ev = (void *) skb->data;
1211 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001213 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001214
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001216
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001217 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +02001218 if (!conn) {
1219 if (ev->link_type != SCO_LINK)
1220 goto unlock;
1221
1222 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1223 if (!conn)
1224 goto unlock;
1225
1226 conn->type = SCO_LINK;
1227 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001228
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001229 if (!ev->status) {
1230 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +02001231
1232 if (conn->type == ACL_LINK) {
1233 conn->state = BT_CONFIG;
1234 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001235 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedbergf7520542011-01-20 12:34:39 +02001236 mgmt_connected(hdev->id, &ev->bdaddr);
Marcel Holtmann769be972008-07-14 20:13:49 +02001237 } else
1238 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001239
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001240 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001241 hci_conn_add_sysfs(conn);
1242
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001243 if (test_bit(HCI_AUTH, &hdev->flags))
1244 conn->link_mode |= HCI_LM_AUTH;
1245
1246 if (test_bit(HCI_ENCRYPT, &hdev->flags))
1247 conn->link_mode |= HCI_LM_ENCRYPT;
1248
1249 /* Get remote features */
1250 if (conn->type == ACL_LINK) {
1251 struct hci_cp_read_remote_features cp;
1252 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +02001253 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
1254 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001255 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001256
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001257 /* Set packet type for incoming connection */
Marcel Holtmanna8746412008-07-14 20:13:46 +02001258 if (!conn->out && hdev->hci_ver < 3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001259 struct hci_cp_change_conn_ptype cp;
1260 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +02001261 cp.pkt_type = cpu_to_le16(conn->pkt_type);
1262 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
1263 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001264 }
Johan Hedberg17d5c042011-01-22 06:09:08 +02001265 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001266 conn->state = BT_CLOSED;
Johan Hedberg17d5c042011-01-22 06:09:08 +02001267 if (conn->type == ACL_LINK)
1268 mgmt_connect_failed(hdev->id, &ev->bdaddr, ev->status);
1269 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001270
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001271 if (conn->type == ACL_LINK)
1272 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -07001273
Marcel Holtmann769be972008-07-14 20:13:49 +02001274 if (ev->status) {
1275 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001276 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +01001277 } else if (ev->link_type != ACL_LINK)
1278 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001279
1280unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001281 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001282
1283 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284}
1285
Linus Torvalds1da177e2005-04-16 15:20:36 -07001286static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1287{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001288 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001289 int mask = hdev->link_mode;
1290
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001291 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
1292 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001293
1294 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
1295
Szymon Janc138d22e2011-02-17 16:44:23 +01001296 if ((mask & HCI_LM_ACCEPT) &&
1297 !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001298 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001299 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001301
1302 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001303
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001304 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1305 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001306 memcpy(ie->data.dev_class, ev->dev_class, 3);
1307
Linus Torvalds1da177e2005-04-16 15:20:36 -07001308 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1309 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001310 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1311 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001312 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001313 hci_dev_unlock(hdev);
1314 return;
1315 }
1316 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001317
Linus Torvalds1da177e2005-04-16 15:20:36 -07001318 memcpy(conn->dev_class, ev->dev_class, 3);
1319 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001320
Linus Torvalds1da177e2005-04-16 15:20:36 -07001321 hci_dev_unlock(hdev);
1322
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001323 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1324 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001326 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001328 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1329 cp.role = 0x00; /* Become master */
1330 else
1331 cp.role = 0x01; /* Remain slave */
1332
1333 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1334 sizeof(cp), &cp);
1335 } else {
1336 struct hci_cp_accept_sync_conn_req cp;
1337
1338 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001339 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001340
1341 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1342 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1343 cp.max_latency = cpu_to_le16(0xffff);
1344 cp.content_format = cpu_to_le16(hdev->voice_setting);
1345 cp.retrans_effort = 0xff;
1346
1347 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1348 sizeof(cp), &cp);
1349 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350 } else {
1351 /* Connection rejected */
1352 struct hci_cp_reject_conn_req cp;
1353
1354 bacpy(&cp.bdaddr, &ev->bdaddr);
1355 cp.reason = 0x0f;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001356 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357 }
1358}
1359
Linus Torvalds1da177e2005-04-16 15:20:36 -07001360static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1361{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001362 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001363 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364
1365 BT_DBG("%s status %d", hdev->name, ev->status);
1366
Johan Hedberg8962ee72011-01-20 12:40:27 +02001367 if (ev->status) {
1368 mgmt_disconnect_failed(hdev->id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369 return;
Johan Hedberg8962ee72011-01-20 12:40:27 +02001370 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001371
1372 hci_dev_lock(hdev);
1373
Marcel Holtmann04837f62006-07-03 10:02:33 +02001374 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001375 if (!conn)
1376 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001377
Johan Hedbergf7520542011-01-20 12:34:39 +02001378 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379
Johan Hedbergf7520542011-01-20 12:34:39 +02001380 if (conn->type == ACL_LINK)
1381 mgmt_disconnected(hdev->id, &conn->dst);
1382
1383 hci_proto_disconn_cfm(conn, ev->reason);
1384 hci_conn_del(conn);
1385
1386unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001387 hci_dev_unlock(hdev);
1388}
1389
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001390static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1391{
1392 struct hci_ev_auth_complete *ev = (void *) skb->data;
1393 struct hci_conn *conn;
1394
1395 BT_DBG("%s status %d", hdev->name, ev->status);
1396
1397 hci_dev_lock(hdev);
1398
1399 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1400 if (conn) {
Johan Hedberg765c2a92011-01-19 12:06:52 +05301401 if (!ev->status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001402 conn->link_mode |= HCI_LM_AUTH;
Johan Hedberg765c2a92011-01-19 12:06:52 +05301403 conn->sec_level = conn->pending_sec_level;
1404 } else
Johan Hedbergda213f42010-06-18 11:08:56 +03001405 conn->sec_level = BT_SECURITY_LOW;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001406
1407 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1408
Marcel Holtmannf8558552008-07-14 20:13:49 +02001409 if (conn->state == BT_CONFIG) {
1410 if (!ev->status && hdev->ssp_mode > 0 &&
1411 conn->ssp_mode > 0) {
1412 struct hci_cp_set_conn_encrypt cp;
1413 cp.handle = ev->handle;
1414 cp.encrypt = 0x01;
1415 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1416 sizeof(cp), &cp);
1417 } else {
1418 conn->state = BT_CONNECTED;
1419 hci_proto_connect_cfm(conn, ev->status);
1420 hci_conn_put(conn);
1421 }
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001422 } else {
Marcel Holtmannf8558552008-07-14 20:13:49 +02001423 hci_auth_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001424
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001425 hci_conn_hold(conn);
1426 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1427 hci_conn_put(conn);
1428 }
1429
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001430 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1431 if (!ev->status) {
1432 struct hci_cp_set_conn_encrypt cp;
Marcel Holtmannf8558552008-07-14 20:13:49 +02001433 cp.handle = ev->handle;
1434 cp.encrypt = 0x01;
1435 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1436 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001437 } else {
1438 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1439 hci_encrypt_cfm(conn, ev->status, 0x00);
1440 }
1441 }
1442 }
1443
1444 hci_dev_unlock(hdev);
1445}
1446
1447static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1448{
Johan Hedberg127178d2010-11-18 22:22:29 +02001449 struct hci_ev_remote_name *ev = (void *) skb->data;
1450 struct hci_conn *conn;
1451
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001452 BT_DBG("%s", hdev->name);
1453
1454 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001455
1456 hci_dev_lock(hdev);
1457
1458 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1459 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
1460 struct hci_cp_auth_requested cp;
1461 cp.handle = __cpu_to_le16(conn->handle);
1462 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1463 }
1464
1465 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001466}
1467
1468static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1469{
1470 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1471 struct hci_conn *conn;
1472
1473 BT_DBG("%s status %d", hdev->name, ev->status);
1474
1475 hci_dev_lock(hdev);
1476
1477 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1478 if (conn) {
1479 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001480 if (ev->encrypt) {
1481 /* Encryption implies authentication */
1482 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001483 conn->link_mode |= HCI_LM_ENCRYPT;
Marcel Holtmannae293192008-07-14 20:13:45 +02001484 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001485 conn->link_mode &= ~HCI_LM_ENCRYPT;
1486 }
1487
1488 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1489
Marcel Holtmannf8558552008-07-14 20:13:49 +02001490 if (conn->state == BT_CONFIG) {
1491 if (!ev->status)
1492 conn->state = BT_CONNECTED;
1493
1494 hci_proto_connect_cfm(conn, ev->status);
1495 hci_conn_put(conn);
1496 } else
1497 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001498 }
1499
1500 hci_dev_unlock(hdev);
1501}
1502
1503static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1504{
1505 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1506 struct hci_conn *conn;
1507
1508 BT_DBG("%s status %d", hdev->name, ev->status);
1509
1510 hci_dev_lock(hdev);
1511
1512 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1513 if (conn) {
1514 if (!ev->status)
1515 conn->link_mode |= HCI_LM_SECURE;
1516
1517 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1518
1519 hci_key_change_cfm(conn, ev->status);
1520 }
1521
1522 hci_dev_unlock(hdev);
1523}
1524
1525static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1526{
1527 struct hci_ev_remote_features *ev = (void *) skb->data;
1528 struct hci_conn *conn;
1529
1530 BT_DBG("%s status %d", hdev->name, ev->status);
1531
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001532 hci_dev_lock(hdev);
1533
1534 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001535 if (!conn)
1536 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001537
Johan Hedbergccd556f2010-11-10 17:11:51 +02001538 if (!ev->status)
1539 memcpy(conn->features, ev->features, 8);
1540
1541 if (conn->state != BT_CONFIG)
1542 goto unlock;
1543
1544 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1545 struct hci_cp_read_remote_ext_features cp;
1546 cp.handle = ev->handle;
1547 cp.page = 0x01;
1548 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001549 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001550 goto unlock;
1551 }
1552
Johan Hedberg127178d2010-11-18 22:22:29 +02001553 if (!ev->status) {
1554 struct hci_cp_remote_name_req cp;
1555 memset(&cp, 0, sizeof(cp));
1556 bacpy(&cp.bdaddr, &conn->dst);
1557 cp.pscan_rep_mode = 0x02;
1558 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1559 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001560
Johan Hedberg127178d2010-11-18 22:22:29 +02001561 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001562 conn->state = BT_CONNECTED;
1563 hci_proto_connect_cfm(conn, ev->status);
1564 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001565 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001566
Johan Hedbergccd556f2010-11-10 17:11:51 +02001567unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001568 hci_dev_unlock(hdev);
1569}
1570
1571static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
1572{
1573 BT_DBG("%s", hdev->name);
1574}
1575
1576static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1577{
1578 BT_DBG("%s", hdev->name);
1579}
1580
1581static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1582{
1583 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1584 __u16 opcode;
1585
1586 skb_pull(skb, sizeof(*ev));
1587
1588 opcode = __le16_to_cpu(ev->opcode);
1589
1590 switch (opcode) {
1591 case HCI_OP_INQUIRY_CANCEL:
1592 hci_cc_inquiry_cancel(hdev, skb);
1593 break;
1594
1595 case HCI_OP_EXIT_PERIODIC_INQ:
1596 hci_cc_exit_periodic_inq(hdev, skb);
1597 break;
1598
1599 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1600 hci_cc_remote_name_req_cancel(hdev, skb);
1601 break;
1602
1603 case HCI_OP_ROLE_DISCOVERY:
1604 hci_cc_role_discovery(hdev, skb);
1605 break;
1606
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001607 case HCI_OP_READ_LINK_POLICY:
1608 hci_cc_read_link_policy(hdev, skb);
1609 break;
1610
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001611 case HCI_OP_WRITE_LINK_POLICY:
1612 hci_cc_write_link_policy(hdev, skb);
1613 break;
1614
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001615 case HCI_OP_READ_DEF_LINK_POLICY:
1616 hci_cc_read_def_link_policy(hdev, skb);
1617 break;
1618
1619 case HCI_OP_WRITE_DEF_LINK_POLICY:
1620 hci_cc_write_def_link_policy(hdev, skb);
1621 break;
1622
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001623 case HCI_OP_RESET:
1624 hci_cc_reset(hdev, skb);
1625 break;
1626
1627 case HCI_OP_WRITE_LOCAL_NAME:
1628 hci_cc_write_local_name(hdev, skb);
1629 break;
1630
1631 case HCI_OP_READ_LOCAL_NAME:
1632 hci_cc_read_local_name(hdev, skb);
1633 break;
1634
1635 case HCI_OP_WRITE_AUTH_ENABLE:
1636 hci_cc_write_auth_enable(hdev, skb);
1637 break;
1638
1639 case HCI_OP_WRITE_ENCRYPT_MODE:
1640 hci_cc_write_encrypt_mode(hdev, skb);
1641 break;
1642
1643 case HCI_OP_WRITE_SCAN_ENABLE:
1644 hci_cc_write_scan_enable(hdev, skb);
1645 break;
1646
1647 case HCI_OP_READ_CLASS_OF_DEV:
1648 hci_cc_read_class_of_dev(hdev, skb);
1649 break;
1650
1651 case HCI_OP_WRITE_CLASS_OF_DEV:
1652 hci_cc_write_class_of_dev(hdev, skb);
1653 break;
1654
1655 case HCI_OP_READ_VOICE_SETTING:
1656 hci_cc_read_voice_setting(hdev, skb);
1657 break;
1658
1659 case HCI_OP_WRITE_VOICE_SETTING:
1660 hci_cc_write_voice_setting(hdev, skb);
1661 break;
1662
1663 case HCI_OP_HOST_BUFFER_SIZE:
1664 hci_cc_host_buffer_size(hdev, skb);
1665 break;
1666
Marcel Holtmann333140b2008-07-14 20:13:48 +02001667 case HCI_OP_READ_SSP_MODE:
1668 hci_cc_read_ssp_mode(hdev, skb);
1669 break;
1670
1671 case HCI_OP_WRITE_SSP_MODE:
1672 hci_cc_write_ssp_mode(hdev, skb);
1673 break;
1674
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001675 case HCI_OP_READ_LOCAL_VERSION:
1676 hci_cc_read_local_version(hdev, skb);
1677 break;
1678
1679 case HCI_OP_READ_LOCAL_COMMANDS:
1680 hci_cc_read_local_commands(hdev, skb);
1681 break;
1682
1683 case HCI_OP_READ_LOCAL_FEATURES:
1684 hci_cc_read_local_features(hdev, skb);
1685 break;
1686
1687 case HCI_OP_READ_BUFFER_SIZE:
1688 hci_cc_read_buffer_size(hdev, skb);
1689 break;
1690
1691 case HCI_OP_READ_BD_ADDR:
1692 hci_cc_read_bd_addr(hdev, skb);
1693 break;
1694
Johan Hedberg23bb5762010-12-21 23:01:27 +02001695 case HCI_OP_WRITE_CA_TIMEOUT:
1696 hci_cc_write_ca_timeout(hdev, skb);
1697 break;
1698
Johan Hedbergb0916ea2011-01-10 13:44:55 +02001699 case HCI_OP_DELETE_STORED_LINK_KEY:
1700 hci_cc_delete_stored_link_key(hdev, skb);
1701 break;
1702
Johan Hedbergd5859e22011-01-25 01:19:58 +02001703 case HCI_OP_SET_EVENT_MASK:
1704 hci_cc_set_event_mask(hdev, skb);
1705 break;
1706
1707 case HCI_OP_WRITE_INQUIRY_MODE:
1708 hci_cc_write_inquiry_mode(hdev, skb);
1709 break;
1710
1711 case HCI_OP_READ_INQ_RSP_TX_POWER:
1712 hci_cc_read_inq_rsp_tx_power(hdev, skb);
1713 break;
1714
1715 case HCI_OP_SET_EVENT_FLT:
1716 hci_cc_set_event_flt(hdev, skb);
1717 break;
1718
Johan Hedberg980e1a52011-01-22 06:10:07 +02001719 case HCI_OP_PIN_CODE_REPLY:
1720 hci_cc_pin_code_reply(hdev, skb);
1721 break;
1722
1723 case HCI_OP_PIN_CODE_NEG_REPLY:
1724 hci_cc_pin_code_neg_reply(hdev, skb);
1725 break;
1726
Ville Tervo6ed58ec2011-02-10 22:38:48 -03001727 case HCI_OP_LE_READ_BUFFER_SIZE:
1728 hci_cc_le_read_buffer_size(hdev, skb);
1729 break;
1730
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001731 default:
1732 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1733 break;
1734 }
1735
Ville Tervo6bd32322011-02-16 16:32:41 +02001736 if (ev->opcode != HCI_OP_NOP)
1737 del_timer(&hdev->cmd_timer);
1738
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001739 if (ev->ncmd) {
1740 atomic_set(&hdev->cmd_cnt, 1);
1741 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001742 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001743 }
1744}
1745
1746static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
1747{
1748 struct hci_ev_cmd_status *ev = (void *) skb->data;
1749 __u16 opcode;
1750
1751 skb_pull(skb, sizeof(*ev));
1752
1753 opcode = __le16_to_cpu(ev->opcode);
1754
1755 switch (opcode) {
1756 case HCI_OP_INQUIRY:
1757 hci_cs_inquiry(hdev, ev->status);
1758 break;
1759
1760 case HCI_OP_CREATE_CONN:
1761 hci_cs_create_conn(hdev, ev->status);
1762 break;
1763
1764 case HCI_OP_ADD_SCO:
1765 hci_cs_add_sco(hdev, ev->status);
1766 break;
1767
Marcel Holtmannf8558552008-07-14 20:13:49 +02001768 case HCI_OP_AUTH_REQUESTED:
1769 hci_cs_auth_requested(hdev, ev->status);
1770 break;
1771
1772 case HCI_OP_SET_CONN_ENCRYPT:
1773 hci_cs_set_conn_encrypt(hdev, ev->status);
1774 break;
1775
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001776 case HCI_OP_REMOTE_NAME_REQ:
1777 hci_cs_remote_name_req(hdev, ev->status);
1778 break;
1779
Marcel Holtmann769be972008-07-14 20:13:49 +02001780 case HCI_OP_READ_REMOTE_FEATURES:
1781 hci_cs_read_remote_features(hdev, ev->status);
1782 break;
1783
1784 case HCI_OP_READ_REMOTE_EXT_FEATURES:
1785 hci_cs_read_remote_ext_features(hdev, ev->status);
1786 break;
1787
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001788 case HCI_OP_SETUP_SYNC_CONN:
1789 hci_cs_setup_sync_conn(hdev, ev->status);
1790 break;
1791
1792 case HCI_OP_SNIFF_MODE:
1793 hci_cs_sniff_mode(hdev, ev->status);
1794 break;
1795
1796 case HCI_OP_EXIT_SNIFF_MODE:
1797 hci_cs_exit_sniff_mode(hdev, ev->status);
1798 break;
1799
Johan Hedberg8962ee72011-01-20 12:40:27 +02001800 case HCI_OP_DISCONNECT:
1801 if (ev->status != 0)
1802 mgmt_disconnect_failed(hdev->id);
1803 break;
1804
Ville Tervofcd89c02011-02-10 22:38:47 -03001805 case HCI_OP_LE_CREATE_CONN:
1806 hci_cs_le_create_conn(hdev, ev->status);
1807 break;
1808
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001809 default:
1810 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1811 break;
1812 }
1813
Ville Tervo6bd32322011-02-16 16:32:41 +02001814 if (ev->opcode != HCI_OP_NOP)
1815 del_timer(&hdev->cmd_timer);
1816
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001817 if (ev->ncmd) {
1818 atomic_set(&hdev->cmd_cnt, 1);
1819 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001820 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001821 }
1822}
1823
1824static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1825{
1826 struct hci_ev_role_change *ev = (void *) skb->data;
1827 struct hci_conn *conn;
1828
1829 BT_DBG("%s status %d", hdev->name, ev->status);
1830
1831 hci_dev_lock(hdev);
1832
1833 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1834 if (conn) {
1835 if (!ev->status) {
1836 if (ev->role)
1837 conn->link_mode &= ~HCI_LM_MASTER;
1838 else
1839 conn->link_mode |= HCI_LM_MASTER;
1840 }
1841
1842 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
1843
1844 hci_role_switch_cfm(conn, ev->status, ev->role);
1845 }
1846
1847 hci_dev_unlock(hdev);
1848}
1849
Linus Torvalds1da177e2005-04-16 15:20:36 -07001850static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
1851{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001852 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001853 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854 int i;
1855
1856 skb_pull(skb, sizeof(*ev));
1857
1858 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
1859
1860 if (skb->len < ev->num_hndl * 4) {
1861 BT_DBG("%s bad parameters", hdev->name);
1862 return;
1863 }
1864
1865 tasklet_disable(&hdev->tx_task);
1866
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001867 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001868 struct hci_conn *conn;
1869 __u16 handle, count;
1870
Harvey Harrison83985312008-05-02 16:25:46 -07001871 handle = get_unaligned_le16(ptr++);
1872 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001873
1874 conn = hci_conn_hash_lookup_handle(hdev, handle);
1875 if (conn) {
1876 conn->sent -= count;
1877
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001878 if (conn->type == ACL_LINK) {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001879 hdev->acl_cnt += count;
1880 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001881 hdev->acl_cnt = hdev->acl_pkts;
Ville Tervo6ed58ec2011-02-10 22:38:48 -03001882 } else if (conn->type == LE_LINK) {
1883 if (hdev->le_pkts) {
1884 hdev->le_cnt += count;
1885 if (hdev->le_cnt > hdev->le_pkts)
1886 hdev->le_cnt = hdev->le_pkts;
1887 } else {
1888 hdev->acl_cnt += count;
1889 if (hdev->acl_cnt > hdev->acl_pkts)
1890 hdev->acl_cnt = hdev->acl_pkts;
1891 }
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001892 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001893 hdev->sco_cnt += count;
1894 if (hdev->sco_cnt > hdev->sco_pkts)
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001895 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001896 }
1897 }
1898 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001899
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001900 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901
1902 tasklet_enable(&hdev->tx_task);
1903}
1904
Marcel Holtmann04837f62006-07-03 10:02:33 +02001905static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001906{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001907 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001908 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909
1910 BT_DBG("%s status %d", hdev->name, ev->status);
1911
1912 hci_dev_lock(hdev);
1913
Marcel Holtmann04837f62006-07-03 10:02:33 +02001914 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1915 if (conn) {
1916 conn->mode = ev->mode;
1917 conn->interval = __le16_to_cpu(ev->interval);
1918
1919 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
1920 if (conn->mode == HCI_CM_ACTIVE)
1921 conn->power_save = 1;
1922 else
1923 conn->power_save = 0;
1924 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001925
1926 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1927 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02001928 }
1929
1930 hci_dev_unlock(hdev);
1931}
1932
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1934{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001935 struct hci_ev_pin_code_req *ev = (void *) skb->data;
1936 struct hci_conn *conn;
1937
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001938 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001939
1940 hci_dev_lock(hdev);
1941
1942 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Marcel Holtmann3d7a9d12009-05-09 12:09:21 -07001943 if (conn && conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001944 hci_conn_hold(conn);
1945 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1946 hci_conn_put(conn);
1947 }
1948
Johan Hedberg03b555e2011-01-04 15:40:05 +02001949 if (!test_bit(HCI_PAIRABLE, &hdev->flags))
1950 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
1951 sizeof(ev->bdaddr), &ev->bdaddr);
1952
Johan Hedberg980e1a52011-01-22 06:10:07 +02001953 if (test_bit(HCI_MGMT, &hdev->flags))
1954 mgmt_pin_code_request(hdev->id, &ev->bdaddr);
1955
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001956 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957}
1958
Linus Torvalds1da177e2005-04-16 15:20:36 -07001959static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1960{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02001961 struct hci_ev_link_key_req *ev = (void *) skb->data;
1962 struct hci_cp_link_key_reply cp;
1963 struct hci_conn *conn;
1964 struct link_key *key;
1965
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001966 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02001967
1968 if (!test_bit(HCI_LINK_KEYS, &hdev->flags))
1969 return;
1970
1971 hci_dev_lock(hdev);
1972
1973 key = hci_find_link_key(hdev, &ev->bdaddr);
1974 if (!key) {
1975 BT_DBG("%s link key not found for %s", hdev->name,
1976 batostr(&ev->bdaddr));
1977 goto not_found;
1978 }
1979
1980 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
1981 batostr(&ev->bdaddr));
1982
1983 if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) && key->type == 0x03) {
1984 BT_DBG("%s ignoring debug key", hdev->name);
1985 goto not_found;
1986 }
1987
1988 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1989
1990 if (key->type == 0x04 && conn && conn->auth_type != 0xff &&
1991 (conn->auth_type & 0x01)) {
1992 BT_DBG("%s ignoring unauthenticated key", hdev->name);
1993 goto not_found;
1994 }
1995
1996 bacpy(&cp.bdaddr, &ev->bdaddr);
1997 memcpy(cp.link_key, key->val, 16);
1998
1999 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
2000
2001 hci_dev_unlock(hdev);
2002
2003 return;
2004
2005not_found:
2006 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2007 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002008}
2009
Linus Torvalds1da177e2005-04-16 15:20:36 -07002010static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2011{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002012 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2013 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002014 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002015
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002016 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002017
2018 hci_dev_lock(hdev);
2019
2020 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2021 if (conn) {
2022 hci_conn_hold(conn);
2023 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002024 pin_len = conn->pin_length;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002025 hci_conn_put(conn);
2026 }
2027
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002028 if (test_bit(HCI_LINK_KEYS, &hdev->flags))
2029 hci_add_link_key(hdev, 1, &ev->bdaddr, ev->link_key,
2030 ev->key_type, pin_len);
2031
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002032 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002033}
2034
Marcel Holtmann04837f62006-07-03 10:02:33 +02002035static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2036{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002037 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002038 struct hci_conn *conn;
2039
2040 BT_DBG("%s status %d", hdev->name, ev->status);
2041
2042 hci_dev_lock(hdev);
2043
2044 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002045 if (conn && !ev->status) {
2046 struct inquiry_entry *ie;
2047
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002048 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2049 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002050 ie->data.clock_offset = ev->clock_offset;
2051 ie->timestamp = jiffies;
2052 }
2053 }
2054
2055 hci_dev_unlock(hdev);
2056}
2057
Marcel Holtmanna8746412008-07-14 20:13:46 +02002058static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2059{
2060 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2061 struct hci_conn *conn;
2062
2063 BT_DBG("%s status %d", hdev->name, ev->status);
2064
2065 hci_dev_lock(hdev);
2066
2067 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2068 if (conn && !ev->status)
2069 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2070
2071 hci_dev_unlock(hdev);
2072}
2073
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002074static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2075{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002076 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002077 struct inquiry_entry *ie;
2078
2079 BT_DBG("%s", hdev->name);
2080
2081 hci_dev_lock(hdev);
2082
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002083 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2084 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002085 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2086 ie->timestamp = jiffies;
2087 }
2088
2089 hci_dev_unlock(hdev);
2090}
2091
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002092static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2093{
2094 struct inquiry_data data;
2095 int num_rsp = *((__u8 *) skb->data);
2096
2097 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2098
2099 if (!num_rsp)
2100 return;
2101
2102 hci_dev_lock(hdev);
2103
2104 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
Szymon Janc138d22e2011-02-17 16:44:23 +01002105 struct inquiry_info_with_rssi_and_pscan_mode *info;
2106 info = (void *) (skb->data + 1);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002107
2108 for (; num_rsp; num_rsp--) {
2109 bacpy(&data.bdaddr, &info->bdaddr);
2110 data.pscan_rep_mode = info->pscan_rep_mode;
2111 data.pscan_period_mode = info->pscan_period_mode;
2112 data.pscan_mode = info->pscan_mode;
2113 memcpy(data.dev_class, info->dev_class, 3);
2114 data.clock_offset = info->clock_offset;
2115 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002116 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002117 info++;
2118 hci_inquiry_cache_update(hdev, &data);
2119 }
2120 } else {
2121 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2122
2123 for (; num_rsp; num_rsp--) {
2124 bacpy(&data.bdaddr, &info->bdaddr);
2125 data.pscan_rep_mode = info->pscan_rep_mode;
2126 data.pscan_period_mode = info->pscan_period_mode;
2127 data.pscan_mode = 0x00;
2128 memcpy(data.dev_class, info->dev_class, 3);
2129 data.clock_offset = info->clock_offset;
2130 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002131 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002132 info++;
2133 hci_inquiry_cache_update(hdev, &data);
2134 }
2135 }
2136
2137 hci_dev_unlock(hdev);
2138}
2139
2140static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2141{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002142 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2143 struct hci_conn *conn;
2144
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002145 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002146
Marcel Holtmann41a96212008-07-14 20:13:48 +02002147 hci_dev_lock(hdev);
2148
2149 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002150 if (!conn)
2151 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002152
Johan Hedbergccd556f2010-11-10 17:11:51 +02002153 if (!ev->status && ev->page == 0x01) {
2154 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002155
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002156 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2157 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002158 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002159
Johan Hedbergccd556f2010-11-10 17:11:51 +02002160 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002161 }
2162
Johan Hedbergccd556f2010-11-10 17:11:51 +02002163 if (conn->state != BT_CONFIG)
2164 goto unlock;
2165
Johan Hedberg127178d2010-11-18 22:22:29 +02002166 if (!ev->status) {
2167 struct hci_cp_remote_name_req cp;
2168 memset(&cp, 0, sizeof(cp));
2169 bacpy(&cp.bdaddr, &conn->dst);
2170 cp.pscan_rep_mode = 0x02;
2171 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
2172 }
Johan Hedberg392599b2010-11-18 22:22:28 +02002173
Johan Hedberg127178d2010-11-18 22:22:29 +02002174 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002175 conn->state = BT_CONNECTED;
2176 hci_proto_connect_cfm(conn, ev->status);
2177 hci_conn_put(conn);
2178 }
2179
2180unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002181 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002182}
2183
2184static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2185{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002186 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2187 struct hci_conn *conn;
2188
2189 BT_DBG("%s status %d", hdev->name, ev->status);
2190
2191 hci_dev_lock(hdev);
2192
2193 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002194 if (!conn) {
2195 if (ev->link_type == ESCO_LINK)
2196 goto unlock;
2197
2198 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2199 if (!conn)
2200 goto unlock;
2201
2202 conn->type = SCO_LINK;
2203 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002204
Marcel Holtmann732547f2009-04-19 19:14:14 +02002205 switch (ev->status) {
2206 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002207 conn->handle = __le16_to_cpu(ev->handle);
2208 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002209
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002210 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002211 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002212 break;
2213
Stephen Coe705e5712010-02-16 11:29:44 -05002214 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002215 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002216 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002217 case 0x1f: /* Unspecified error */
2218 if (conn->out && conn->attempt < 2) {
2219 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2220 (hdev->esco_type & EDR_ESCO_MASK);
2221 hci_setup_sync(conn, conn->link->handle);
2222 goto unlock;
2223 }
2224 /* fall through */
2225
2226 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002227 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002228 break;
2229 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002230
2231 hci_proto_connect_cfm(conn, ev->status);
2232 if (ev->status)
2233 hci_conn_del(conn);
2234
2235unlock:
2236 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002237}
2238
2239static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2240{
2241 BT_DBG("%s", hdev->name);
2242}
2243
Marcel Holtmann04837f62006-07-03 10:02:33 +02002244static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2245{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002246 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002247
2248 BT_DBG("%s status %d", hdev->name, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02002249}
2250
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002251static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2252{
2253 struct inquiry_data data;
2254 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2255 int num_rsp = *((__u8 *) skb->data);
2256
2257 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2258
2259 if (!num_rsp)
2260 return;
2261
2262 hci_dev_lock(hdev);
2263
2264 for (; num_rsp; num_rsp--) {
2265 bacpy(&data.bdaddr, &info->bdaddr);
Szymon Janc138d22e2011-02-17 16:44:23 +01002266 data.pscan_rep_mode = info->pscan_rep_mode;
2267 data.pscan_period_mode = info->pscan_period_mode;
2268 data.pscan_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002269 memcpy(data.dev_class, info->dev_class, 3);
Szymon Janc138d22e2011-02-17 16:44:23 +01002270 data.clock_offset = info->clock_offset;
2271 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002272 data.ssp_mode = 0x01;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002273 info++;
2274 hci_inquiry_cache_update(hdev, &data);
2275 }
2276
2277 hci_dev_unlock(hdev);
2278}
2279
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002280static inline u8 hci_get_auth_req(struct hci_conn *conn)
2281{
2282 /* If remote requests dedicated bonding follow that lead */
2283 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2284 /* If both remote and local IO capabilities allow MITM
2285 * protection then require it, otherwise don't */
2286 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2287 return 0x02;
2288 else
2289 return 0x03;
2290 }
2291
2292 /* If remote requests no-bonding follow that lead */
2293 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
2294 return 0x00;
2295
2296 return conn->auth_type;
2297}
2298
Marcel Holtmann04936842008-07-14 20:13:48 +02002299static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2300{
2301 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2302 struct hci_conn *conn;
2303
2304 BT_DBG("%s", hdev->name);
2305
2306 hci_dev_lock(hdev);
2307
2308 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002309 if (!conn)
2310 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002311
Johan Hedberg03b555e2011-01-04 15:40:05 +02002312 hci_conn_hold(conn);
2313
2314 if (!test_bit(HCI_MGMT, &hdev->flags))
2315 goto unlock;
2316
2317 if (test_bit(HCI_PAIRABLE, &hdev->flags) ||
2318 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002319 struct hci_cp_io_capability_reply cp;
2320
2321 bacpy(&cp.bdaddr, &ev->bdaddr);
2322 cp.capability = conn->io_capability;
2323 cp.oob_data = 0;
2324 cp.authentication = hci_get_auth_req(conn);
2325
2326 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
2327 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002328 } else {
2329 struct hci_cp_io_capability_neg_reply cp;
2330
2331 bacpy(&cp.bdaddr, &ev->bdaddr);
2332 cp.reason = 0x16; /* Pairing not allowed */
2333
2334 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
2335 sizeof(cp), &cp);
2336 }
2337
2338unlock:
2339 hci_dev_unlock(hdev);
2340}
2341
2342static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
2343{
2344 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
2345 struct hci_conn *conn;
2346
2347 BT_DBG("%s", hdev->name);
2348
2349 hci_dev_lock(hdev);
2350
2351 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2352 if (!conn)
2353 goto unlock;
2354
2355 hci_conn_hold(conn);
2356
2357 conn->remote_cap = ev->capability;
2358 conn->remote_oob = ev->oob_data;
2359 conn->remote_auth = ev->authentication;
2360
2361unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002362 hci_dev_unlock(hdev);
2363}
2364
2365static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2366{
2367 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
2368 struct hci_conn *conn;
2369
2370 BT_DBG("%s", hdev->name);
2371
2372 hci_dev_lock(hdev);
2373
2374 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2375 if (conn)
2376 hci_conn_put(conn);
2377
2378 hci_dev_unlock(hdev);
2379}
2380
Marcel Holtmann41a96212008-07-14 20:13:48 +02002381static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2382{
2383 struct hci_ev_remote_host_features *ev = (void *) skb->data;
2384 struct inquiry_entry *ie;
2385
2386 BT_DBG("%s", hdev->name);
2387
2388 hci_dev_lock(hdev);
2389
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002390 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2391 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02002392 ie->data.ssp_mode = (ev->features[0] & 0x01);
2393
2394 hci_dev_unlock(hdev);
2395}
2396
Ville Tervofcd89c02011-02-10 22:38:47 -03002397static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2398{
2399 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
2400 struct hci_conn *conn;
2401
2402 BT_DBG("%s status %d", hdev->name, ev->status);
2403
2404 hci_dev_lock(hdev);
2405
2406 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03002407 if (!conn) {
2408 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
2409 if (!conn) {
2410 BT_ERR("No memory for new connection");
2411 hci_dev_unlock(hdev);
2412 return;
2413 }
2414 }
Ville Tervofcd89c02011-02-10 22:38:47 -03002415
2416 if (ev->status) {
2417 hci_proto_connect_cfm(conn, ev->status);
2418 conn->state = BT_CLOSED;
2419 hci_conn_del(conn);
2420 goto unlock;
2421 }
2422
2423 conn->handle = __le16_to_cpu(ev->handle);
2424 conn->state = BT_CONNECTED;
2425
2426 hci_conn_hold_device(conn);
2427 hci_conn_add_sysfs(conn);
2428
2429 hci_proto_connect_cfm(conn, ev->status);
2430
2431unlock:
2432 hci_dev_unlock(hdev);
2433}
2434
2435static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
2436{
2437 struct hci_ev_le_meta *le_ev = (void *) skb->data;
2438
2439 skb_pull(skb, sizeof(*le_ev));
2440
2441 switch (le_ev->subevent) {
2442 case HCI_EV_LE_CONN_COMPLETE:
2443 hci_le_conn_complete_evt(hdev, skb);
2444 break;
2445
2446 default:
2447 break;
2448 }
2449}
2450
Linus Torvalds1da177e2005-04-16 15:20:36 -07002451void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
2452{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002453 struct hci_event_hdr *hdr = (void *) skb->data;
2454 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002455
2456 skb_pull(skb, HCI_EVENT_HDR_SIZE);
2457
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002458 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002459 case HCI_EV_INQUIRY_COMPLETE:
2460 hci_inquiry_complete_evt(hdev, skb);
2461 break;
2462
2463 case HCI_EV_INQUIRY_RESULT:
2464 hci_inquiry_result_evt(hdev, skb);
2465 break;
2466
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002467 case HCI_EV_CONN_COMPLETE:
2468 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02002469 break;
2470
Linus Torvalds1da177e2005-04-16 15:20:36 -07002471 case HCI_EV_CONN_REQUEST:
2472 hci_conn_request_evt(hdev, skb);
2473 break;
2474
Linus Torvalds1da177e2005-04-16 15:20:36 -07002475 case HCI_EV_DISCONN_COMPLETE:
2476 hci_disconn_complete_evt(hdev, skb);
2477 break;
2478
Linus Torvalds1da177e2005-04-16 15:20:36 -07002479 case HCI_EV_AUTH_COMPLETE:
2480 hci_auth_complete_evt(hdev, skb);
2481 break;
2482
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002483 case HCI_EV_REMOTE_NAME:
2484 hci_remote_name_evt(hdev, skb);
2485 break;
2486
Linus Torvalds1da177e2005-04-16 15:20:36 -07002487 case HCI_EV_ENCRYPT_CHANGE:
2488 hci_encrypt_change_evt(hdev, skb);
2489 break;
2490
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002491 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
2492 hci_change_link_key_complete_evt(hdev, skb);
2493 break;
2494
2495 case HCI_EV_REMOTE_FEATURES:
2496 hci_remote_features_evt(hdev, skb);
2497 break;
2498
2499 case HCI_EV_REMOTE_VERSION:
2500 hci_remote_version_evt(hdev, skb);
2501 break;
2502
2503 case HCI_EV_QOS_SETUP_COMPLETE:
2504 hci_qos_setup_complete_evt(hdev, skb);
2505 break;
2506
2507 case HCI_EV_CMD_COMPLETE:
2508 hci_cmd_complete_evt(hdev, skb);
2509 break;
2510
2511 case HCI_EV_CMD_STATUS:
2512 hci_cmd_status_evt(hdev, skb);
2513 break;
2514
2515 case HCI_EV_ROLE_CHANGE:
2516 hci_role_change_evt(hdev, skb);
2517 break;
2518
2519 case HCI_EV_NUM_COMP_PKTS:
2520 hci_num_comp_pkts_evt(hdev, skb);
2521 break;
2522
2523 case HCI_EV_MODE_CHANGE:
2524 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002525 break;
2526
2527 case HCI_EV_PIN_CODE_REQ:
2528 hci_pin_code_request_evt(hdev, skb);
2529 break;
2530
2531 case HCI_EV_LINK_KEY_REQ:
2532 hci_link_key_request_evt(hdev, skb);
2533 break;
2534
2535 case HCI_EV_LINK_KEY_NOTIFY:
2536 hci_link_key_notify_evt(hdev, skb);
2537 break;
2538
2539 case HCI_EV_CLOCK_OFFSET:
2540 hci_clock_offset_evt(hdev, skb);
2541 break;
2542
Marcel Holtmanna8746412008-07-14 20:13:46 +02002543 case HCI_EV_PKT_TYPE_CHANGE:
2544 hci_pkt_type_change_evt(hdev, skb);
2545 break;
2546
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002547 case HCI_EV_PSCAN_REP_MODE:
2548 hci_pscan_rep_mode_evt(hdev, skb);
2549 break;
2550
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002551 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
2552 hci_inquiry_result_with_rssi_evt(hdev, skb);
2553 break;
2554
2555 case HCI_EV_REMOTE_EXT_FEATURES:
2556 hci_remote_ext_features_evt(hdev, skb);
2557 break;
2558
2559 case HCI_EV_SYNC_CONN_COMPLETE:
2560 hci_sync_conn_complete_evt(hdev, skb);
2561 break;
2562
2563 case HCI_EV_SYNC_CONN_CHANGED:
2564 hci_sync_conn_changed_evt(hdev, skb);
2565 break;
2566
Marcel Holtmann04837f62006-07-03 10:02:33 +02002567 case HCI_EV_SNIFF_SUBRATE:
2568 hci_sniff_subrate_evt(hdev, skb);
2569 break;
2570
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002571 case HCI_EV_EXTENDED_INQUIRY_RESULT:
2572 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002573 break;
2574
Marcel Holtmann04936842008-07-14 20:13:48 +02002575 case HCI_EV_IO_CAPA_REQUEST:
2576 hci_io_capa_request_evt(hdev, skb);
2577 break;
2578
Johan Hedberg03b555e2011-01-04 15:40:05 +02002579 case HCI_EV_IO_CAPA_REPLY:
2580 hci_io_capa_reply_evt(hdev, skb);
2581 break;
2582
Marcel Holtmann04936842008-07-14 20:13:48 +02002583 case HCI_EV_SIMPLE_PAIR_COMPLETE:
2584 hci_simple_pair_complete_evt(hdev, skb);
2585 break;
2586
Marcel Holtmann41a96212008-07-14 20:13:48 +02002587 case HCI_EV_REMOTE_HOST_FEATURES:
2588 hci_remote_host_features_evt(hdev, skb);
2589 break;
2590
Ville Tervofcd89c02011-02-10 22:38:47 -03002591 case HCI_EV_LE_META:
2592 hci_le_meta_evt(hdev, skb);
2593 break;
2594
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002595 default:
2596 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002597 break;
2598 }
2599
2600 kfree_skb(skb);
2601 hdev->stat.evt_rx++;
2602}
2603
2604/* Generate internal stack event */
2605void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
2606{
2607 struct hci_event_hdr *hdr;
2608 struct hci_ev_stack_internal *ev;
2609 struct sk_buff *skb;
2610
2611 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
2612 if (!skb)
2613 return;
2614
2615 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
2616 hdr->evt = HCI_EV_STACK_INTERNAL;
2617 hdr->plen = sizeof(*ev) + dlen;
2618
2619 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
2620 ev->type = type;
2621 memcpy(ev->data, data, dlen);
2622
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002623 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07002624 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002625
Marcel Holtmann0d48d932005-08-09 20:30:28 -07002626 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002627 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02002628 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002629 kfree_skb(skb);
2630}