blob: 09cb29e8713abd9f0506e75a99996148b82be235 [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,
Johan Hedberg392599b2010-11-18 22:22:28 +0200941 struct hci_conn *conn)
942{
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
Johan Hedbergf0358562010-05-18 13:20:32 +02001296 if ((mask & HCI_LM_ACCEPT) && !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001297 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001298 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001299 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300
1301 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001302
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001303 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1304 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001305 memcpy(ie->data.dev_class, ev->dev_class, 3);
1306
Linus Torvalds1da177e2005-04-16 15:20:36 -07001307 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1308 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001309 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1310 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001311 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001312 hci_dev_unlock(hdev);
1313 return;
1314 }
1315 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001316
Linus Torvalds1da177e2005-04-16 15:20:36 -07001317 memcpy(conn->dev_class, ev->dev_class, 3);
1318 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001319
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320 hci_dev_unlock(hdev);
1321
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001322 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1323 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001324
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001325 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001326
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001327 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1328 cp.role = 0x00; /* Become master */
1329 else
1330 cp.role = 0x01; /* Remain slave */
1331
1332 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1333 sizeof(cp), &cp);
1334 } else {
1335 struct hci_cp_accept_sync_conn_req cp;
1336
1337 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001338 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001339
1340 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1341 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1342 cp.max_latency = cpu_to_le16(0xffff);
1343 cp.content_format = cpu_to_le16(hdev->voice_setting);
1344 cp.retrans_effort = 0xff;
1345
1346 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1347 sizeof(cp), &cp);
1348 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349 } else {
1350 /* Connection rejected */
1351 struct hci_cp_reject_conn_req cp;
1352
1353 bacpy(&cp.bdaddr, &ev->bdaddr);
1354 cp.reason = 0x0f;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001355 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356 }
1357}
1358
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1360{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001361 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001362 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363
1364 BT_DBG("%s status %d", hdev->name, ev->status);
1365
Johan Hedberg8962ee72011-01-20 12:40:27 +02001366 if (ev->status) {
1367 mgmt_disconnect_failed(hdev->id);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368 return;
Johan Hedberg8962ee72011-01-20 12:40:27 +02001369 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001370
1371 hci_dev_lock(hdev);
1372
Marcel Holtmann04837f62006-07-03 10:02:33 +02001373 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergf7520542011-01-20 12:34:39 +02001374 if (!conn)
1375 goto unlock;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001376
Johan Hedbergf7520542011-01-20 12:34:39 +02001377 conn->state = BT_CLOSED;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378
Johan Hedbergf7520542011-01-20 12:34:39 +02001379 if (conn->type == ACL_LINK)
1380 mgmt_disconnected(hdev->id, &conn->dst);
1381
1382 hci_proto_disconn_cfm(conn, ev->reason);
1383 hci_conn_del(conn);
1384
1385unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386 hci_dev_unlock(hdev);
1387}
1388
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001389static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1390{
1391 struct hci_ev_auth_complete *ev = (void *) skb->data;
1392 struct hci_conn *conn;
1393
1394 BT_DBG("%s status %d", hdev->name, ev->status);
1395
1396 hci_dev_lock(hdev);
1397
1398 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1399 if (conn) {
Johan Hedberg765c2a92011-01-19 12:06:52 +05301400 if (!ev->status) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001401 conn->link_mode |= HCI_LM_AUTH;
Johan Hedberg765c2a92011-01-19 12:06:52 +05301402 conn->sec_level = conn->pending_sec_level;
1403 } else
Johan Hedbergda213f42010-06-18 11:08:56 +03001404 conn->sec_level = BT_SECURITY_LOW;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001405
1406 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1407
Marcel Holtmannf8558552008-07-14 20:13:49 +02001408 if (conn->state == BT_CONFIG) {
1409 if (!ev->status && hdev->ssp_mode > 0 &&
1410 conn->ssp_mode > 0) {
1411 struct hci_cp_set_conn_encrypt cp;
1412 cp.handle = ev->handle;
1413 cp.encrypt = 0x01;
1414 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1415 sizeof(cp), &cp);
1416 } else {
1417 conn->state = BT_CONNECTED;
1418 hci_proto_connect_cfm(conn, ev->status);
1419 hci_conn_put(conn);
1420 }
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001421 } else {
Marcel Holtmannf8558552008-07-14 20:13:49 +02001422 hci_auth_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001423
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001424 hci_conn_hold(conn);
1425 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1426 hci_conn_put(conn);
1427 }
1428
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001429 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1430 if (!ev->status) {
1431 struct hci_cp_set_conn_encrypt cp;
Marcel Holtmannf8558552008-07-14 20:13:49 +02001432 cp.handle = ev->handle;
1433 cp.encrypt = 0x01;
1434 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1435 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001436 } else {
1437 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1438 hci_encrypt_cfm(conn, ev->status, 0x00);
1439 }
1440 }
1441 }
1442
1443 hci_dev_unlock(hdev);
1444}
1445
1446static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1447{
Johan Hedberg127178d2010-11-18 22:22:29 +02001448 struct hci_ev_remote_name *ev = (void *) skb->data;
1449 struct hci_conn *conn;
1450
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001451 BT_DBG("%s", hdev->name);
1452
1453 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001454
1455 hci_dev_lock(hdev);
1456
1457 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1458 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
1459 struct hci_cp_auth_requested cp;
1460 cp.handle = __cpu_to_le16(conn->handle);
1461 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1462 }
1463
1464 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001465}
1466
1467static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1468{
1469 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1470 struct hci_conn *conn;
1471
1472 BT_DBG("%s status %d", hdev->name, ev->status);
1473
1474 hci_dev_lock(hdev);
1475
1476 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1477 if (conn) {
1478 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001479 if (ev->encrypt) {
1480 /* Encryption implies authentication */
1481 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001482 conn->link_mode |= HCI_LM_ENCRYPT;
Marcel Holtmannae293192008-07-14 20:13:45 +02001483 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001484 conn->link_mode &= ~HCI_LM_ENCRYPT;
1485 }
1486
1487 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1488
Marcel Holtmannf8558552008-07-14 20:13:49 +02001489 if (conn->state == BT_CONFIG) {
1490 if (!ev->status)
1491 conn->state = BT_CONNECTED;
1492
1493 hci_proto_connect_cfm(conn, ev->status);
1494 hci_conn_put(conn);
1495 } else
1496 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001497 }
1498
1499 hci_dev_unlock(hdev);
1500}
1501
1502static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1503{
1504 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1505 struct hci_conn *conn;
1506
1507 BT_DBG("%s status %d", hdev->name, ev->status);
1508
1509 hci_dev_lock(hdev);
1510
1511 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1512 if (conn) {
1513 if (!ev->status)
1514 conn->link_mode |= HCI_LM_SECURE;
1515
1516 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1517
1518 hci_key_change_cfm(conn, ev->status);
1519 }
1520
1521 hci_dev_unlock(hdev);
1522}
1523
1524static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1525{
1526 struct hci_ev_remote_features *ev = (void *) skb->data;
1527 struct hci_conn *conn;
1528
1529 BT_DBG("%s status %d", hdev->name, ev->status);
1530
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001531 hci_dev_lock(hdev);
1532
1533 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001534 if (!conn)
1535 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001536
Johan Hedbergccd556f2010-11-10 17:11:51 +02001537 if (!ev->status)
1538 memcpy(conn->features, ev->features, 8);
1539
1540 if (conn->state != BT_CONFIG)
1541 goto unlock;
1542
1543 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1544 struct hci_cp_read_remote_ext_features cp;
1545 cp.handle = ev->handle;
1546 cp.page = 0x01;
1547 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001548 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001549 goto unlock;
1550 }
1551
Johan Hedberg127178d2010-11-18 22:22:29 +02001552 if (!ev->status) {
1553 struct hci_cp_remote_name_req cp;
1554 memset(&cp, 0, sizeof(cp));
1555 bacpy(&cp.bdaddr, &conn->dst);
1556 cp.pscan_rep_mode = 0x02;
1557 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1558 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001559
Johan Hedberg127178d2010-11-18 22:22:29 +02001560 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001561 conn->state = BT_CONNECTED;
1562 hci_proto_connect_cfm(conn, ev->status);
1563 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001564 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001565
Johan Hedbergccd556f2010-11-10 17:11:51 +02001566unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001567 hci_dev_unlock(hdev);
1568}
1569
1570static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
1571{
1572 BT_DBG("%s", hdev->name);
1573}
1574
1575static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1576{
1577 BT_DBG("%s", hdev->name);
1578}
1579
1580static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1581{
1582 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1583 __u16 opcode;
1584
1585 skb_pull(skb, sizeof(*ev));
1586
1587 opcode = __le16_to_cpu(ev->opcode);
1588
1589 switch (opcode) {
1590 case HCI_OP_INQUIRY_CANCEL:
1591 hci_cc_inquiry_cancel(hdev, skb);
1592 break;
1593
1594 case HCI_OP_EXIT_PERIODIC_INQ:
1595 hci_cc_exit_periodic_inq(hdev, skb);
1596 break;
1597
1598 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1599 hci_cc_remote_name_req_cancel(hdev, skb);
1600 break;
1601
1602 case HCI_OP_ROLE_DISCOVERY:
1603 hci_cc_role_discovery(hdev, skb);
1604 break;
1605
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001606 case HCI_OP_READ_LINK_POLICY:
1607 hci_cc_read_link_policy(hdev, skb);
1608 break;
1609
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001610 case HCI_OP_WRITE_LINK_POLICY:
1611 hci_cc_write_link_policy(hdev, skb);
1612 break;
1613
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001614 case HCI_OP_READ_DEF_LINK_POLICY:
1615 hci_cc_read_def_link_policy(hdev, skb);
1616 break;
1617
1618 case HCI_OP_WRITE_DEF_LINK_POLICY:
1619 hci_cc_write_def_link_policy(hdev, skb);
1620 break;
1621
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001622 case HCI_OP_RESET:
1623 hci_cc_reset(hdev, skb);
1624 break;
1625
1626 case HCI_OP_WRITE_LOCAL_NAME:
1627 hci_cc_write_local_name(hdev, skb);
1628 break;
1629
1630 case HCI_OP_READ_LOCAL_NAME:
1631 hci_cc_read_local_name(hdev, skb);
1632 break;
1633
1634 case HCI_OP_WRITE_AUTH_ENABLE:
1635 hci_cc_write_auth_enable(hdev, skb);
1636 break;
1637
1638 case HCI_OP_WRITE_ENCRYPT_MODE:
1639 hci_cc_write_encrypt_mode(hdev, skb);
1640 break;
1641
1642 case HCI_OP_WRITE_SCAN_ENABLE:
1643 hci_cc_write_scan_enable(hdev, skb);
1644 break;
1645
1646 case HCI_OP_READ_CLASS_OF_DEV:
1647 hci_cc_read_class_of_dev(hdev, skb);
1648 break;
1649
1650 case HCI_OP_WRITE_CLASS_OF_DEV:
1651 hci_cc_write_class_of_dev(hdev, skb);
1652 break;
1653
1654 case HCI_OP_READ_VOICE_SETTING:
1655 hci_cc_read_voice_setting(hdev, skb);
1656 break;
1657
1658 case HCI_OP_WRITE_VOICE_SETTING:
1659 hci_cc_write_voice_setting(hdev, skb);
1660 break;
1661
1662 case HCI_OP_HOST_BUFFER_SIZE:
1663 hci_cc_host_buffer_size(hdev, skb);
1664 break;
1665
Marcel Holtmann333140b2008-07-14 20:13:48 +02001666 case HCI_OP_READ_SSP_MODE:
1667 hci_cc_read_ssp_mode(hdev, skb);
1668 break;
1669
1670 case HCI_OP_WRITE_SSP_MODE:
1671 hci_cc_write_ssp_mode(hdev, skb);
1672 break;
1673
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001674 case HCI_OP_READ_LOCAL_VERSION:
1675 hci_cc_read_local_version(hdev, skb);
1676 break;
1677
1678 case HCI_OP_READ_LOCAL_COMMANDS:
1679 hci_cc_read_local_commands(hdev, skb);
1680 break;
1681
1682 case HCI_OP_READ_LOCAL_FEATURES:
1683 hci_cc_read_local_features(hdev, skb);
1684 break;
1685
1686 case HCI_OP_READ_BUFFER_SIZE:
1687 hci_cc_read_buffer_size(hdev, skb);
1688 break;
1689
1690 case HCI_OP_READ_BD_ADDR:
1691 hci_cc_read_bd_addr(hdev, skb);
1692 break;
1693
Johan Hedberg23bb5762010-12-21 23:01:27 +02001694 case HCI_OP_WRITE_CA_TIMEOUT:
1695 hci_cc_write_ca_timeout(hdev, skb);
1696 break;
1697
Johan Hedbergb0916ea2011-01-10 13:44:55 +02001698 case HCI_OP_DELETE_STORED_LINK_KEY:
1699 hci_cc_delete_stored_link_key(hdev, skb);
1700 break;
1701
Johan Hedbergd5859e22011-01-25 01:19:58 +02001702 case HCI_OP_SET_EVENT_MASK:
1703 hci_cc_set_event_mask(hdev, skb);
1704 break;
1705
1706 case HCI_OP_WRITE_INQUIRY_MODE:
1707 hci_cc_write_inquiry_mode(hdev, skb);
1708 break;
1709
1710 case HCI_OP_READ_INQ_RSP_TX_POWER:
1711 hci_cc_read_inq_rsp_tx_power(hdev, skb);
1712 break;
1713
1714 case HCI_OP_SET_EVENT_FLT:
1715 hci_cc_set_event_flt(hdev, skb);
1716 break;
1717
Johan Hedberg980e1a52011-01-22 06:10:07 +02001718 case HCI_OP_PIN_CODE_REPLY:
1719 hci_cc_pin_code_reply(hdev, skb);
1720 break;
1721
1722 case HCI_OP_PIN_CODE_NEG_REPLY:
1723 hci_cc_pin_code_neg_reply(hdev, skb);
1724 break;
1725
Ville Tervo6ed58ec2011-02-10 22:38:48 -03001726 case HCI_OP_LE_READ_BUFFER_SIZE:
1727 hci_cc_le_read_buffer_size(hdev, skb);
1728 break;
1729
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001730 default:
1731 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1732 break;
1733 }
1734
Ville Tervo6bd32322011-02-16 16:32:41 +02001735 if (ev->opcode != HCI_OP_NOP)
1736 del_timer(&hdev->cmd_timer);
1737
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001738 if (ev->ncmd) {
1739 atomic_set(&hdev->cmd_cnt, 1);
1740 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001741 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001742 }
1743}
1744
1745static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
1746{
1747 struct hci_ev_cmd_status *ev = (void *) skb->data;
1748 __u16 opcode;
1749
1750 skb_pull(skb, sizeof(*ev));
1751
1752 opcode = __le16_to_cpu(ev->opcode);
1753
1754 switch (opcode) {
1755 case HCI_OP_INQUIRY:
1756 hci_cs_inquiry(hdev, ev->status);
1757 break;
1758
1759 case HCI_OP_CREATE_CONN:
1760 hci_cs_create_conn(hdev, ev->status);
1761 break;
1762
1763 case HCI_OP_ADD_SCO:
1764 hci_cs_add_sco(hdev, ev->status);
1765 break;
1766
Marcel Holtmannf8558552008-07-14 20:13:49 +02001767 case HCI_OP_AUTH_REQUESTED:
1768 hci_cs_auth_requested(hdev, ev->status);
1769 break;
1770
1771 case HCI_OP_SET_CONN_ENCRYPT:
1772 hci_cs_set_conn_encrypt(hdev, ev->status);
1773 break;
1774
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001775 case HCI_OP_REMOTE_NAME_REQ:
1776 hci_cs_remote_name_req(hdev, ev->status);
1777 break;
1778
Marcel Holtmann769be972008-07-14 20:13:49 +02001779 case HCI_OP_READ_REMOTE_FEATURES:
1780 hci_cs_read_remote_features(hdev, ev->status);
1781 break;
1782
1783 case HCI_OP_READ_REMOTE_EXT_FEATURES:
1784 hci_cs_read_remote_ext_features(hdev, ev->status);
1785 break;
1786
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001787 case HCI_OP_SETUP_SYNC_CONN:
1788 hci_cs_setup_sync_conn(hdev, ev->status);
1789 break;
1790
1791 case HCI_OP_SNIFF_MODE:
1792 hci_cs_sniff_mode(hdev, ev->status);
1793 break;
1794
1795 case HCI_OP_EXIT_SNIFF_MODE:
1796 hci_cs_exit_sniff_mode(hdev, ev->status);
1797 break;
1798
Johan Hedberg8962ee72011-01-20 12:40:27 +02001799 case HCI_OP_DISCONNECT:
1800 if (ev->status != 0)
1801 mgmt_disconnect_failed(hdev->id);
1802 break;
1803
Ville Tervofcd89c02011-02-10 22:38:47 -03001804 case HCI_OP_LE_CREATE_CONN:
1805 hci_cs_le_create_conn(hdev, ev->status);
1806 break;
1807
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001808 default:
1809 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1810 break;
1811 }
1812
Ville Tervo6bd32322011-02-16 16:32:41 +02001813 if (ev->opcode != HCI_OP_NOP)
1814 del_timer(&hdev->cmd_timer);
1815
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001816 if (ev->ncmd) {
1817 atomic_set(&hdev->cmd_cnt, 1);
1818 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001819 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001820 }
1821}
1822
1823static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1824{
1825 struct hci_ev_role_change *ev = (void *) skb->data;
1826 struct hci_conn *conn;
1827
1828 BT_DBG("%s status %d", hdev->name, ev->status);
1829
1830 hci_dev_lock(hdev);
1831
1832 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1833 if (conn) {
1834 if (!ev->status) {
1835 if (ev->role)
1836 conn->link_mode &= ~HCI_LM_MASTER;
1837 else
1838 conn->link_mode |= HCI_LM_MASTER;
1839 }
1840
1841 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
1842
1843 hci_role_switch_cfm(conn, ev->status, ev->role);
1844 }
1845
1846 hci_dev_unlock(hdev);
1847}
1848
Linus Torvalds1da177e2005-04-16 15:20:36 -07001849static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
1850{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001851 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001852 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001853 int i;
1854
1855 skb_pull(skb, sizeof(*ev));
1856
1857 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
1858
1859 if (skb->len < ev->num_hndl * 4) {
1860 BT_DBG("%s bad parameters", hdev->name);
1861 return;
1862 }
1863
1864 tasklet_disable(&hdev->tx_task);
1865
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001866 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001867 struct hci_conn *conn;
1868 __u16 handle, count;
1869
Harvey Harrison83985312008-05-02 16:25:46 -07001870 handle = get_unaligned_le16(ptr++);
1871 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001872
1873 conn = hci_conn_hash_lookup_handle(hdev, handle);
1874 if (conn) {
1875 conn->sent -= count;
1876
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001877 if (conn->type == ACL_LINK) {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001878 hdev->acl_cnt += count;
1879 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001880 hdev->acl_cnt = hdev->acl_pkts;
Ville Tervo6ed58ec2011-02-10 22:38:48 -03001881 } else if (conn->type == LE_LINK) {
1882 if (hdev->le_pkts) {
1883 hdev->le_cnt += count;
1884 if (hdev->le_cnt > hdev->le_pkts)
1885 hdev->le_cnt = hdev->le_pkts;
1886 } else {
1887 hdev->acl_cnt += count;
1888 if (hdev->acl_cnt > hdev->acl_pkts)
1889 hdev->acl_cnt = hdev->acl_pkts;
1890 }
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001891 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001892 hdev->sco_cnt += count;
1893 if (hdev->sco_cnt > hdev->sco_pkts)
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001894 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001895 }
1896 }
1897 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001898
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001899 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001900
1901 tasklet_enable(&hdev->tx_task);
1902}
1903
Marcel Holtmann04837f62006-07-03 10:02:33 +02001904static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001906 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001907 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001908
1909 BT_DBG("%s status %d", hdev->name, ev->status);
1910
1911 hci_dev_lock(hdev);
1912
Marcel Holtmann04837f62006-07-03 10:02:33 +02001913 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1914 if (conn) {
1915 conn->mode = ev->mode;
1916 conn->interval = __le16_to_cpu(ev->interval);
1917
1918 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
1919 if (conn->mode == HCI_CM_ACTIVE)
1920 conn->power_save = 1;
1921 else
1922 conn->power_save = 0;
1923 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001924
1925 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1926 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02001927 }
1928
1929 hci_dev_unlock(hdev);
1930}
1931
Linus Torvalds1da177e2005-04-16 15:20:36 -07001932static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1933{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001934 struct hci_ev_pin_code_req *ev = (void *) skb->data;
1935 struct hci_conn *conn;
1936
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001937 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001938
1939 hci_dev_lock(hdev);
1940
1941 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Marcel Holtmann3d7a9d12009-05-09 12:09:21 -07001942 if (conn && conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001943 hci_conn_hold(conn);
1944 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1945 hci_conn_put(conn);
1946 }
1947
Johan Hedberg03b555e2011-01-04 15:40:05 +02001948 if (!test_bit(HCI_PAIRABLE, &hdev->flags))
1949 hci_send_cmd(hdev, HCI_OP_PIN_CODE_NEG_REPLY,
1950 sizeof(ev->bdaddr), &ev->bdaddr);
1951
Johan Hedberg980e1a52011-01-22 06:10:07 +02001952 if (test_bit(HCI_MGMT, &hdev->flags))
1953 mgmt_pin_code_request(hdev->id, &ev->bdaddr);
1954
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001955 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001956}
1957
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1959{
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02001960 struct hci_ev_link_key_req *ev = (void *) skb->data;
1961 struct hci_cp_link_key_reply cp;
1962 struct hci_conn *conn;
1963 struct link_key *key;
1964
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001965 BT_DBG("%s", hdev->name);
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02001966
1967 if (!test_bit(HCI_LINK_KEYS, &hdev->flags))
1968 return;
1969
1970 hci_dev_lock(hdev);
1971
1972 key = hci_find_link_key(hdev, &ev->bdaddr);
1973 if (!key) {
1974 BT_DBG("%s link key not found for %s", hdev->name,
1975 batostr(&ev->bdaddr));
1976 goto not_found;
1977 }
1978
1979 BT_DBG("%s found key type %u for %s", hdev->name, key->type,
1980 batostr(&ev->bdaddr));
1981
1982 if (!test_bit(HCI_DEBUG_KEYS, &hdev->flags) && key->type == 0x03) {
1983 BT_DBG("%s ignoring debug key", hdev->name);
1984 goto not_found;
1985 }
1986
1987 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1988
1989 if (key->type == 0x04 && conn && conn->auth_type != 0xff &&
1990 (conn->auth_type & 0x01)) {
1991 BT_DBG("%s ignoring unauthenticated key", hdev->name);
1992 goto not_found;
1993 }
1994
1995 bacpy(&cp.bdaddr, &ev->bdaddr);
1996 memcpy(cp.link_key, key->val, 16);
1997
1998 hci_send_cmd(hdev, HCI_OP_LINK_KEY_REPLY, sizeof(cp), &cp);
1999
2000 hci_dev_unlock(hdev);
2001
2002 return;
2003
2004not_found:
2005 hci_send_cmd(hdev, HCI_OP_LINK_KEY_NEG_REPLY, 6, &ev->bdaddr);
2006 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002007}
2008
Linus Torvalds1da177e2005-04-16 15:20:36 -07002009static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
2010{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002011 struct hci_ev_link_key_notify *ev = (void *) skb->data;
2012 struct hci_conn *conn;
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002013 u8 pin_len = 0;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002014
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002015 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002016
2017 hci_dev_lock(hdev);
2018
2019 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2020 if (conn) {
2021 hci_conn_hold(conn);
2022 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Johan Hedberg980e1a52011-01-22 06:10:07 +02002023 pin_len = conn->pin_length;
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002024 hci_conn_put(conn);
2025 }
2026
Johan Hedberg55ed8ca12011-01-17 14:41:05 +02002027 if (test_bit(HCI_LINK_KEYS, &hdev->flags))
2028 hci_add_link_key(hdev, 1, &ev->bdaddr, ev->link_key,
2029 ev->key_type, pin_len);
2030
Marcel Holtmann052b30b2009-04-26 20:01:22 +02002031 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002032}
2033
Marcel Holtmann04837f62006-07-03 10:02:33 +02002034static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
2035{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002036 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002037 struct hci_conn *conn;
2038
2039 BT_DBG("%s status %d", hdev->name, ev->status);
2040
2041 hci_dev_lock(hdev);
2042
2043 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002044 if (conn && !ev->status) {
2045 struct inquiry_entry *ie;
2046
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002047 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2048 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002049 ie->data.clock_offset = ev->clock_offset;
2050 ie->timestamp = jiffies;
2051 }
2052 }
2053
2054 hci_dev_unlock(hdev);
2055}
2056
Marcel Holtmanna8746412008-07-14 20:13:46 +02002057static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
2058{
2059 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
2060 struct hci_conn *conn;
2061
2062 BT_DBG("%s status %d", hdev->name, ev->status);
2063
2064 hci_dev_lock(hdev);
2065
2066 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2067 if (conn && !ev->status)
2068 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
2069
2070 hci_dev_unlock(hdev);
2071}
2072
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002073static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
2074{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002075 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002076 struct inquiry_entry *ie;
2077
2078 BT_DBG("%s", hdev->name);
2079
2080 hci_dev_lock(hdev);
2081
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002082 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2083 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002084 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
2085 ie->timestamp = jiffies;
2086 }
2087
2088 hci_dev_unlock(hdev);
2089}
2090
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002091static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
2092{
2093 struct inquiry_data data;
2094 int num_rsp = *((__u8 *) skb->data);
2095
2096 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2097
2098 if (!num_rsp)
2099 return;
2100
2101 hci_dev_lock(hdev);
2102
2103 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
2104 struct inquiry_info_with_rssi_and_pscan_mode *info = (void *) (skb->data + 1);
2105
2106 for (; num_rsp; num_rsp--) {
2107 bacpy(&data.bdaddr, &info->bdaddr);
2108 data.pscan_rep_mode = info->pscan_rep_mode;
2109 data.pscan_period_mode = info->pscan_period_mode;
2110 data.pscan_mode = info->pscan_mode;
2111 memcpy(data.dev_class, info->dev_class, 3);
2112 data.clock_offset = info->clock_offset;
2113 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002114 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002115 info++;
2116 hci_inquiry_cache_update(hdev, &data);
2117 }
2118 } else {
2119 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
2120
2121 for (; num_rsp; num_rsp--) {
2122 bacpy(&data.bdaddr, &info->bdaddr);
2123 data.pscan_rep_mode = info->pscan_rep_mode;
2124 data.pscan_period_mode = info->pscan_period_mode;
2125 data.pscan_mode = 0x00;
2126 memcpy(data.dev_class, info->dev_class, 3);
2127 data.clock_offset = info->clock_offset;
2128 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002129 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002130 info++;
2131 hci_inquiry_cache_update(hdev, &data);
2132 }
2133 }
2134
2135 hci_dev_unlock(hdev);
2136}
2137
2138static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2139{
Marcel Holtmann41a96212008-07-14 20:13:48 +02002140 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
2141 struct hci_conn *conn;
2142
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002143 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002144
Marcel Holtmann41a96212008-07-14 20:13:48 +02002145 hci_dev_lock(hdev);
2146
2147 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02002148 if (!conn)
2149 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002150
Johan Hedbergccd556f2010-11-10 17:11:51 +02002151 if (!ev->status && ev->page == 0x01) {
2152 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002153
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002154 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
2155 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02002156 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02002157
Johan Hedbergccd556f2010-11-10 17:11:51 +02002158 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02002159 }
2160
Johan Hedbergccd556f2010-11-10 17:11:51 +02002161 if (conn->state != BT_CONFIG)
2162 goto unlock;
2163
Johan Hedberg127178d2010-11-18 22:22:29 +02002164 if (!ev->status) {
2165 struct hci_cp_remote_name_req cp;
2166 memset(&cp, 0, sizeof(cp));
2167 bacpy(&cp.bdaddr, &conn->dst);
2168 cp.pscan_rep_mode = 0x02;
2169 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
2170 }
Johan Hedberg392599b2010-11-18 22:22:28 +02002171
Johan Hedberg127178d2010-11-18 22:22:29 +02002172 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02002173 conn->state = BT_CONNECTED;
2174 hci_proto_connect_cfm(conn, ev->status);
2175 hci_conn_put(conn);
2176 }
2177
2178unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02002179 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002180}
2181
2182static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2183{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002184 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
2185 struct hci_conn *conn;
2186
2187 BT_DBG("%s status %d", hdev->name, ev->status);
2188
2189 hci_dev_lock(hdev);
2190
2191 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02002192 if (!conn) {
2193 if (ev->link_type == ESCO_LINK)
2194 goto unlock;
2195
2196 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
2197 if (!conn)
2198 goto unlock;
2199
2200 conn->type = SCO_LINK;
2201 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002202
Marcel Holtmann732547f2009-04-19 19:14:14 +02002203 switch (ev->status) {
2204 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002205 conn->handle = __le16_to_cpu(ev->handle);
2206 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002207
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07002208 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02002209 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02002210 break;
2211
Stephen Coe705e5712010-02-16 11:29:44 -05002212 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002213 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08002214 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02002215 case 0x1f: /* Unspecified error */
2216 if (conn->out && conn->attempt < 2) {
2217 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
2218 (hdev->esco_type & EDR_ESCO_MASK);
2219 hci_setup_sync(conn, conn->link->handle);
2220 goto unlock;
2221 }
2222 /* fall through */
2223
2224 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002225 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02002226 break;
2227 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02002228
2229 hci_proto_connect_cfm(conn, ev->status);
2230 if (ev->status)
2231 hci_conn_del(conn);
2232
2233unlock:
2234 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002235}
2236
2237static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
2238{
2239 BT_DBG("%s", hdev->name);
2240}
2241
Marcel Holtmann04837f62006-07-03 10:02:33 +02002242static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
2243{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002244 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02002245 struct hci_conn *conn;
2246
2247 BT_DBG("%s status %d", hdev->name, ev->status);
2248
2249 hci_dev_lock(hdev);
2250
2251 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
2252 if (conn) {
2253 }
2254
2255 hci_dev_unlock(hdev);
2256}
2257
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002258static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
2259{
2260 struct inquiry_data data;
2261 struct extended_inquiry_info *info = (void *) (skb->data + 1);
2262 int num_rsp = *((__u8 *) skb->data);
2263
2264 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
2265
2266 if (!num_rsp)
2267 return;
2268
2269 hci_dev_lock(hdev);
2270
2271 for (; num_rsp; num_rsp--) {
2272 bacpy(&data.bdaddr, &info->bdaddr);
2273 data.pscan_rep_mode = info->pscan_rep_mode;
2274 data.pscan_period_mode = info->pscan_period_mode;
2275 data.pscan_mode = 0x00;
2276 memcpy(data.dev_class, info->dev_class, 3);
2277 data.clock_offset = info->clock_offset;
2278 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02002279 data.ssp_mode = 0x01;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002280 info++;
2281 hci_inquiry_cache_update(hdev, &data);
2282 }
2283
2284 hci_dev_unlock(hdev);
2285}
2286
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002287static inline u8 hci_get_auth_req(struct hci_conn *conn)
2288{
2289 /* If remote requests dedicated bonding follow that lead */
2290 if (conn->remote_auth == 0x02 || conn->remote_auth == 0x03) {
2291 /* If both remote and local IO capabilities allow MITM
2292 * protection then require it, otherwise don't */
2293 if (conn->remote_cap == 0x03 || conn->io_capability == 0x03)
2294 return 0x02;
2295 else
2296 return 0x03;
2297 }
2298
2299 /* If remote requests no-bonding follow that lead */
2300 if (conn->remote_auth == 0x00 || conn->remote_auth == 0x01)
2301 return 0x00;
2302
2303 return conn->auth_type;
2304}
2305
Marcel Holtmann04936842008-07-14 20:13:48 +02002306static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
2307{
2308 struct hci_ev_io_capa_request *ev = (void *) skb->data;
2309 struct hci_conn *conn;
2310
2311 BT_DBG("%s", hdev->name);
2312
2313 hci_dev_lock(hdev);
2314
2315 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002316 if (!conn)
2317 goto unlock;
Marcel Holtmann04936842008-07-14 20:13:48 +02002318
Johan Hedberg03b555e2011-01-04 15:40:05 +02002319 hci_conn_hold(conn);
2320
2321 if (!test_bit(HCI_MGMT, &hdev->flags))
2322 goto unlock;
2323
2324 if (test_bit(HCI_PAIRABLE, &hdev->flags) ||
2325 (conn->remote_auth & ~0x01) == HCI_AT_NO_BONDING) {
Johan Hedberg17fa4b92011-01-25 13:28:33 +02002326 struct hci_cp_io_capability_reply cp;
2327
2328 bacpy(&cp.bdaddr, &ev->bdaddr);
2329 cp.capability = conn->io_capability;
2330 cp.oob_data = 0;
2331 cp.authentication = hci_get_auth_req(conn);
2332
2333 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
2334 sizeof(cp), &cp);
Johan Hedberg03b555e2011-01-04 15:40:05 +02002335 } else {
2336 struct hci_cp_io_capability_neg_reply cp;
2337
2338 bacpy(&cp.bdaddr, &ev->bdaddr);
2339 cp.reason = 0x16; /* Pairing not allowed */
2340
2341 hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_NEG_REPLY,
2342 sizeof(cp), &cp);
2343 }
2344
2345unlock:
2346 hci_dev_unlock(hdev);
2347}
2348
2349static inline void hci_io_capa_reply_evt(struct hci_dev *hdev, struct sk_buff *skb)
2350{
2351 struct hci_ev_io_capa_reply *ev = (void *) skb->data;
2352 struct hci_conn *conn;
2353
2354 BT_DBG("%s", hdev->name);
2355
2356 hci_dev_lock(hdev);
2357
2358 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2359 if (!conn)
2360 goto unlock;
2361
2362 hci_conn_hold(conn);
2363
2364 conn->remote_cap = ev->capability;
2365 conn->remote_oob = ev->oob_data;
2366 conn->remote_auth = ev->authentication;
2367
2368unlock:
Marcel Holtmann04936842008-07-14 20:13:48 +02002369 hci_dev_unlock(hdev);
2370}
2371
2372static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2373{
2374 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
2375 struct hci_conn *conn;
2376
2377 BT_DBG("%s", hdev->name);
2378
2379 hci_dev_lock(hdev);
2380
2381 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
2382 if (conn)
2383 hci_conn_put(conn);
2384
2385 hci_dev_unlock(hdev);
2386}
2387
Marcel Holtmann41a96212008-07-14 20:13:48 +02002388static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
2389{
2390 struct hci_ev_remote_host_features *ev = (void *) skb->data;
2391 struct inquiry_entry *ie;
2392
2393 BT_DBG("%s", hdev->name);
2394
2395 hci_dev_lock(hdev);
2396
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02002397 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
2398 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02002399 ie->data.ssp_mode = (ev->features[0] & 0x01);
2400
2401 hci_dev_unlock(hdev);
2402}
2403
Ville Tervofcd89c02011-02-10 22:38:47 -03002404static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
2405{
2406 struct hci_ev_le_conn_complete *ev = (void *) skb->data;
2407 struct hci_conn *conn;
2408
2409 BT_DBG("%s status %d", hdev->name, ev->status);
2410
2411 hci_dev_lock(hdev);
2412
2413 conn = hci_conn_hash_lookup_ba(hdev, LE_LINK, &ev->bdaddr);
Ville Tervob62f3282011-02-10 22:38:50 -03002414 if (!conn) {
2415 conn = hci_conn_add(hdev, LE_LINK, &ev->bdaddr);
2416 if (!conn) {
2417 BT_ERR("No memory for new connection");
2418 hci_dev_unlock(hdev);
2419 return;
2420 }
2421 }
Ville Tervofcd89c02011-02-10 22:38:47 -03002422
2423 if (ev->status) {
2424 hci_proto_connect_cfm(conn, ev->status);
2425 conn->state = BT_CLOSED;
2426 hci_conn_del(conn);
2427 goto unlock;
2428 }
2429
2430 conn->handle = __le16_to_cpu(ev->handle);
2431 conn->state = BT_CONNECTED;
2432
2433 hci_conn_hold_device(conn);
2434 hci_conn_add_sysfs(conn);
2435
2436 hci_proto_connect_cfm(conn, ev->status);
2437
2438unlock:
2439 hci_dev_unlock(hdev);
2440}
2441
2442static inline void hci_le_meta_evt(struct hci_dev *hdev, struct sk_buff *skb)
2443{
2444 struct hci_ev_le_meta *le_ev = (void *) skb->data;
2445
2446 skb_pull(skb, sizeof(*le_ev));
2447
2448 switch (le_ev->subevent) {
2449 case HCI_EV_LE_CONN_COMPLETE:
2450 hci_le_conn_complete_evt(hdev, skb);
2451 break;
2452
2453 default:
2454 break;
2455 }
2456}
2457
Linus Torvalds1da177e2005-04-16 15:20:36 -07002458void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
2459{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002460 struct hci_event_hdr *hdr = (void *) skb->data;
2461 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002462
2463 skb_pull(skb, HCI_EVENT_HDR_SIZE);
2464
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002465 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002466 case HCI_EV_INQUIRY_COMPLETE:
2467 hci_inquiry_complete_evt(hdev, skb);
2468 break;
2469
2470 case HCI_EV_INQUIRY_RESULT:
2471 hci_inquiry_result_evt(hdev, skb);
2472 break;
2473
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002474 case HCI_EV_CONN_COMPLETE:
2475 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02002476 break;
2477
Linus Torvalds1da177e2005-04-16 15:20:36 -07002478 case HCI_EV_CONN_REQUEST:
2479 hci_conn_request_evt(hdev, skb);
2480 break;
2481
Linus Torvalds1da177e2005-04-16 15:20:36 -07002482 case HCI_EV_DISCONN_COMPLETE:
2483 hci_disconn_complete_evt(hdev, skb);
2484 break;
2485
Linus Torvalds1da177e2005-04-16 15:20:36 -07002486 case HCI_EV_AUTH_COMPLETE:
2487 hci_auth_complete_evt(hdev, skb);
2488 break;
2489
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002490 case HCI_EV_REMOTE_NAME:
2491 hci_remote_name_evt(hdev, skb);
2492 break;
2493
Linus Torvalds1da177e2005-04-16 15:20:36 -07002494 case HCI_EV_ENCRYPT_CHANGE:
2495 hci_encrypt_change_evt(hdev, skb);
2496 break;
2497
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002498 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
2499 hci_change_link_key_complete_evt(hdev, skb);
2500 break;
2501
2502 case HCI_EV_REMOTE_FEATURES:
2503 hci_remote_features_evt(hdev, skb);
2504 break;
2505
2506 case HCI_EV_REMOTE_VERSION:
2507 hci_remote_version_evt(hdev, skb);
2508 break;
2509
2510 case HCI_EV_QOS_SETUP_COMPLETE:
2511 hci_qos_setup_complete_evt(hdev, skb);
2512 break;
2513
2514 case HCI_EV_CMD_COMPLETE:
2515 hci_cmd_complete_evt(hdev, skb);
2516 break;
2517
2518 case HCI_EV_CMD_STATUS:
2519 hci_cmd_status_evt(hdev, skb);
2520 break;
2521
2522 case HCI_EV_ROLE_CHANGE:
2523 hci_role_change_evt(hdev, skb);
2524 break;
2525
2526 case HCI_EV_NUM_COMP_PKTS:
2527 hci_num_comp_pkts_evt(hdev, skb);
2528 break;
2529
2530 case HCI_EV_MODE_CHANGE:
2531 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002532 break;
2533
2534 case HCI_EV_PIN_CODE_REQ:
2535 hci_pin_code_request_evt(hdev, skb);
2536 break;
2537
2538 case HCI_EV_LINK_KEY_REQ:
2539 hci_link_key_request_evt(hdev, skb);
2540 break;
2541
2542 case HCI_EV_LINK_KEY_NOTIFY:
2543 hci_link_key_notify_evt(hdev, skb);
2544 break;
2545
2546 case HCI_EV_CLOCK_OFFSET:
2547 hci_clock_offset_evt(hdev, skb);
2548 break;
2549
Marcel Holtmanna8746412008-07-14 20:13:46 +02002550 case HCI_EV_PKT_TYPE_CHANGE:
2551 hci_pkt_type_change_evt(hdev, skb);
2552 break;
2553
Marcel Holtmann85a1e932005-08-09 20:28:02 -07002554 case HCI_EV_PSCAN_REP_MODE:
2555 hci_pscan_rep_mode_evt(hdev, skb);
2556 break;
2557
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002558 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
2559 hci_inquiry_result_with_rssi_evt(hdev, skb);
2560 break;
2561
2562 case HCI_EV_REMOTE_EXT_FEATURES:
2563 hci_remote_ext_features_evt(hdev, skb);
2564 break;
2565
2566 case HCI_EV_SYNC_CONN_COMPLETE:
2567 hci_sync_conn_complete_evt(hdev, skb);
2568 break;
2569
2570 case HCI_EV_SYNC_CONN_CHANGED:
2571 hci_sync_conn_changed_evt(hdev, skb);
2572 break;
2573
Marcel Holtmann04837f62006-07-03 10:02:33 +02002574 case HCI_EV_SNIFF_SUBRATE:
2575 hci_sniff_subrate_evt(hdev, skb);
2576 break;
2577
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002578 case HCI_EV_EXTENDED_INQUIRY_RESULT:
2579 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002580 break;
2581
Marcel Holtmann04936842008-07-14 20:13:48 +02002582 case HCI_EV_IO_CAPA_REQUEST:
2583 hci_io_capa_request_evt(hdev, skb);
2584 break;
2585
Johan Hedberg03b555e2011-01-04 15:40:05 +02002586 case HCI_EV_IO_CAPA_REPLY:
2587 hci_io_capa_reply_evt(hdev, skb);
2588 break;
2589
Marcel Holtmann04936842008-07-14 20:13:48 +02002590 case HCI_EV_SIMPLE_PAIR_COMPLETE:
2591 hci_simple_pair_complete_evt(hdev, skb);
2592 break;
2593
Marcel Holtmann41a96212008-07-14 20:13:48 +02002594 case HCI_EV_REMOTE_HOST_FEATURES:
2595 hci_remote_host_features_evt(hdev, skb);
2596 break;
2597
Ville Tervofcd89c02011-02-10 22:38:47 -03002598 case HCI_EV_LE_META:
2599 hci_le_meta_evt(hdev, skb);
2600 break;
2601
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002602 default:
2603 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604 break;
2605 }
2606
2607 kfree_skb(skb);
2608 hdev->stat.evt_rx++;
2609}
2610
2611/* Generate internal stack event */
2612void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
2613{
2614 struct hci_event_hdr *hdr;
2615 struct hci_ev_stack_internal *ev;
2616 struct sk_buff *skb;
2617
2618 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
2619 if (!skb)
2620 return;
2621
2622 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
2623 hdr->evt = HCI_EV_STACK_INTERNAL;
2624 hdr->plen = sizeof(*ev) + dlen;
2625
2626 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
2627 ev->type = type;
2628 memcpy(ev->data, data, dlen);
2629
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002630 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07002631 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002632
Marcel Holtmann0d48d932005-08-09 20:30:28 -07002633 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002634 skb->dev = (void *) hdev;
Johan Hedbergeec8d2b2010-12-16 10:17:38 +02002635 hci_send_to_sock(hdev, skb, NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002636 kfree_skb(skb);
2637}