blob: 8923b36a67a28d69952807da655cdfb42717119a [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
Marcel Holtmanna9de9242007-10-20 13:33:56 +020061 hci_req_complete(hdev, 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
177 hci_req_complete(hdev, status);
178}
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
186 hci_req_complete(hdev, status);
187}
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
238 hci_req_complete(hdev, status);
239}
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
261 hci_req_complete(hdev, status);
262}
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);
277
278 clear_bit(HCI_PSCAN, &hdev->flags);
279 clear_bit(HCI_ISCAN, &hdev->flags);
280
281 if (param & SCAN_INQUIRY)
282 set_bit(HCI_ISCAN, &hdev->flags);
283
284 if (param & SCAN_PAGE)
285 set_bit(HCI_PSCAN, &hdev->flags);
286 }
287
288 hci_req_complete(hdev, status);
289}
290
291static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
292{
293 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
294
295 BT_DBG("%s status 0x%x", hdev->name, rp->status);
296
297 if (rp->status)
298 return;
299
300 memcpy(hdev->dev_class, rp->dev_class, 3);
301
302 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
303 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
304}
305
306static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
307{
308 __u8 status = *((__u8 *) skb->data);
309 void *sent;
310
311 BT_DBG("%s status 0x%x", hdev->name, status);
312
Marcel Holtmannf383f272008-07-14 20:13:47 +0200313 if (status)
314 return;
315
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200316 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
317 if (!sent)
318 return;
319
Marcel Holtmannf383f272008-07-14 20:13:47 +0200320 memcpy(hdev->dev_class, sent, 3);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200321}
322
323static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
324{
325 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200327
328 BT_DBG("%s status 0x%x", hdev->name, rp->status);
329
330 if (rp->status)
331 return;
332
333 setting = __le16_to_cpu(rp->voice_setting);
334
Marcel Holtmannf383f272008-07-14 20:13:47 +0200335 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200336 return;
337
338 hdev->voice_setting = setting;
339
340 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
341
342 if (hdev->notify) {
343 tasklet_disable(&hdev->tx_task);
344 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
345 tasklet_enable(&hdev->tx_task);
346 }
347}
348
349static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
350{
351 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200352 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353 void *sent;
354
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200355 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700356
Marcel Holtmannf383f272008-07-14 20:13:47 +0200357 if (status)
358 return;
359
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200360 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
361 if (!sent)
362 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363
Marcel Holtmannf383f272008-07-14 20:13:47 +0200364 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365
Marcel Holtmannf383f272008-07-14 20:13:47 +0200366 if (hdev->voice_setting == setting)
367 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368
Marcel Holtmannf383f272008-07-14 20:13:47 +0200369 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370
Marcel Holtmannf383f272008-07-14 20:13:47 +0200371 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
372
373 if (hdev->notify) {
374 tasklet_disable(&hdev->tx_task);
375 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
376 tasklet_enable(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377 }
378}
379
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200380static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200382 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200384 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200386 hci_req_complete(hdev, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700387}
388
Marcel Holtmann333140b2008-07-14 20:13:48 +0200389static void hci_cc_read_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
390{
391 struct hci_rp_read_ssp_mode *rp = (void *) skb->data;
392
393 BT_DBG("%s status 0x%x", hdev->name, rp->status);
394
395 if (rp->status)
396 return;
397
398 hdev->ssp_mode = rp->mode;
399}
400
401static void hci_cc_write_ssp_mode(struct hci_dev *hdev, struct sk_buff *skb)
402{
403 __u8 status = *((__u8 *) skb->data);
404 void *sent;
405
406 BT_DBG("%s status 0x%x", hdev->name, status);
407
408 if (status)
409 return;
410
411 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SSP_MODE);
412 if (!sent)
413 return;
414
415 hdev->ssp_mode = *((__u8 *) sent);
416}
417
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200418static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
419{
420 struct hci_rp_read_local_version *rp = (void *) skb->data;
421
422 BT_DBG("%s status 0x%x", hdev->name, rp->status);
423
424 if (rp->status)
425 return;
426
427 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200428 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
429 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200430
431 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
432 hdev->manufacturer,
433 hdev->hci_ver, hdev->hci_rev);
434}
435
436static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
437{
438 struct hci_rp_read_local_commands *rp = (void *) skb->data;
439
440 BT_DBG("%s status 0x%x", hdev->name, rp->status);
441
442 if (rp->status)
443 return;
444
445 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
446}
447
448static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
449{
450 struct hci_rp_read_local_features *rp = (void *) skb->data;
451
452 BT_DBG("%s status 0x%x", hdev->name, rp->status);
453
454 if (rp->status)
455 return;
456
457 memcpy(hdev->features, rp->features, 8);
458
459 /* Adjust default settings according to features
460 * supported by device. */
461
462 if (hdev->features[0] & LMP_3SLOT)
463 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
464
465 if (hdev->features[0] & LMP_5SLOT)
466 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
467
468 if (hdev->features[1] & LMP_HV2) {
469 hdev->pkt_type |= (HCI_HV2);
470 hdev->esco_type |= (ESCO_HV2);
471 }
472
473 if (hdev->features[1] & LMP_HV3) {
474 hdev->pkt_type |= (HCI_HV3);
475 hdev->esco_type |= (ESCO_HV3);
476 }
477
478 if (hdev->features[3] & LMP_ESCO)
479 hdev->esco_type |= (ESCO_EV3);
480
481 if (hdev->features[4] & LMP_EV4)
482 hdev->esco_type |= (ESCO_EV4);
483
484 if (hdev->features[4] & LMP_EV5)
485 hdev->esco_type |= (ESCO_EV5);
486
Marcel Holtmannefc76882009-02-06 09:13:37 +0100487 if (hdev->features[5] & LMP_EDR_ESCO_2M)
488 hdev->esco_type |= (ESCO_2EV3);
489
490 if (hdev->features[5] & LMP_EDR_ESCO_3M)
491 hdev->esco_type |= (ESCO_3EV3);
492
493 if (hdev->features[5] & LMP_EDR_3S_ESCO)
494 hdev->esco_type |= (ESCO_2EV5 | ESCO_3EV5);
495
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200496 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
497 hdev->features[0], hdev->features[1],
498 hdev->features[2], hdev->features[3],
499 hdev->features[4], hdev->features[5],
500 hdev->features[6], hdev->features[7]);
501}
502
503static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
504{
505 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
506
507 BT_DBG("%s status 0x%x", hdev->name, rp->status);
508
509 if (rp->status)
510 return;
511
512 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
513 hdev->sco_mtu = rp->sco_mtu;
514 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
515 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
516
517 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
518 hdev->sco_mtu = 64;
519 hdev->sco_pkts = 8;
520 }
521
522 hdev->acl_cnt = hdev->acl_pkts;
523 hdev->sco_cnt = hdev->sco_pkts;
524
525 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
526 hdev->acl_mtu, hdev->acl_pkts,
527 hdev->sco_mtu, hdev->sco_pkts);
528}
529
530static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
531{
532 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
533
534 BT_DBG("%s status 0x%x", hdev->name, rp->status);
535
536 if (!rp->status)
537 bacpy(&hdev->bdaddr, &rp->bdaddr);
538
539 hci_req_complete(hdev, rp->status);
540}
541
542static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
543{
544 BT_DBG("%s status 0x%x", hdev->name, status);
545
546 if (status) {
547 hci_req_complete(hdev, status);
548
549 hci_conn_check_pending(hdev);
550 } else
551 set_bit(HCI_INQUIRY, &hdev->flags);
552}
553
Linus Torvalds1da177e2005-04-16 15:20:36 -0700554static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
555{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200556 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700557 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200559 BT_DBG("%s status 0x%x", hdev->name, status);
560
561 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562 if (!cp)
563 return;
564
565 hci_dev_lock(hdev);
566
567 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
568
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200569 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570
571 if (status) {
572 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +0200573 if (status != 0x0c || conn->attempt > 2) {
574 conn->state = BT_CLOSED;
575 hci_proto_connect_cfm(conn, status);
576 hci_conn_del(conn);
577 } else
578 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 }
580 } else {
581 if (!conn) {
582 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
583 if (conn) {
584 conn->out = 1;
585 conn->link_mode |= HCI_LM_MASTER;
586 } else
Gustavo F. Padovan893ef972010-07-18 15:13:37 -0300587 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588 }
589 }
590
591 hci_dev_unlock(hdev);
592}
593
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200594static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700595{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200596 struct hci_cp_add_sco *cp;
597 struct hci_conn *acl, *sco;
598 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200600 BT_DBG("%s status 0x%x", hdev->name, status);
601
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200602 if (!status)
603 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200605 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
606 if (!cp)
607 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200609 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200611 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100612
613 hci_dev_lock(hdev);
614
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200615 acl = hci_conn_hash_lookup_handle(hdev, handle);
616 if (acl && (sco = acl->link)) {
617 sco->state = BT_CLOSED;
618
619 hci_proto_connect_cfm(sco, status);
620 hci_conn_del(sco);
621 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100622
623 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700624}
625
Marcel Holtmannf8558552008-07-14 20:13:49 +0200626static void hci_cs_auth_requested(struct hci_dev *hdev, __u8 status)
627{
628 struct hci_cp_auth_requested *cp;
629 struct hci_conn *conn;
630
631 BT_DBG("%s status 0x%x", hdev->name, status);
632
633 if (!status)
634 return;
635
636 cp = hci_sent_cmd_data(hdev, HCI_OP_AUTH_REQUESTED);
637 if (!cp)
638 return;
639
640 hci_dev_lock(hdev);
641
642 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
643 if (conn) {
644 if (conn->state == BT_CONFIG) {
645 hci_proto_connect_cfm(conn, status);
646 hci_conn_put(conn);
647 }
648 }
649
650 hci_dev_unlock(hdev);
651}
652
653static void hci_cs_set_conn_encrypt(struct hci_dev *hdev, __u8 status)
654{
655 struct hci_cp_set_conn_encrypt *cp;
656 struct hci_conn *conn;
657
658 BT_DBG("%s status 0x%x", hdev->name, status);
659
660 if (!status)
661 return;
662
663 cp = hci_sent_cmd_data(hdev, HCI_OP_SET_CONN_ENCRYPT);
664 if (!cp)
665 return;
666
667 hci_dev_lock(hdev);
668
669 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
670 if (conn) {
671 if (conn->state == BT_CONFIG) {
672 hci_proto_connect_cfm(conn, status);
673 hci_conn_put(conn);
674 }
675 }
676
677 hci_dev_unlock(hdev);
678}
679
Johan Hedberg127178d2010-11-18 22:22:29 +0200680static int hci_outgoing_auth_needed(struct hci_dev *hdev,
Johan Hedberg392599b2010-11-18 22:22:28 +0200681 struct hci_conn *conn)
682{
Johan Hedberg392599b2010-11-18 22:22:28 +0200683 if (conn->state != BT_CONFIG || !conn->out)
684 return 0;
685
686 if (conn->sec_level == BT_SECURITY_SDP)
687 return 0;
688
689 /* Only request authentication for SSP connections or non-SSP
690 * devices with sec_level HIGH */
691 if (!(hdev->ssp_mode > 0 && conn->ssp_mode > 0) &&
692 conn->sec_level != BT_SECURITY_HIGH)
693 return 0;
694
Johan Hedberg392599b2010-11-18 22:22:28 +0200695 return 1;
696}
697
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200698static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
699{
Johan Hedberg127178d2010-11-18 22:22:29 +0200700 struct hci_cp_remote_name_req *cp;
701 struct hci_conn *conn;
702
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200703 BT_DBG("%s status 0x%x", hdev->name, status);
Johan Hedberg127178d2010-11-18 22:22:29 +0200704
705 /* If successful wait for the name req complete event before
706 * checking for the need to do authentication */
707 if (!status)
708 return;
709
710 cp = hci_sent_cmd_data(hdev, HCI_OP_REMOTE_NAME_REQ);
711 if (!cp)
712 return;
713
714 hci_dev_lock(hdev);
715
716 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
717 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
718 struct hci_cp_auth_requested cp;
719 cp.handle = __cpu_to_le16(conn->handle);
720 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
721 }
722
723 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200724}
725
Marcel Holtmann769be972008-07-14 20:13:49 +0200726static void hci_cs_read_remote_features(struct hci_dev *hdev, __u8 status)
727{
728 struct hci_cp_read_remote_features *cp;
729 struct hci_conn *conn;
730
731 BT_DBG("%s status 0x%x", hdev->name, status);
732
733 if (!status)
734 return;
735
736 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_FEATURES);
737 if (!cp)
738 return;
739
740 hci_dev_lock(hdev);
741
742 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
743 if (conn) {
744 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +0200745 hci_proto_connect_cfm(conn, status);
746 hci_conn_put(conn);
747 }
748 }
749
750 hci_dev_unlock(hdev);
751}
752
753static void hci_cs_read_remote_ext_features(struct hci_dev *hdev, __u8 status)
754{
755 struct hci_cp_read_remote_ext_features *cp;
756 struct hci_conn *conn;
757
758 BT_DBG("%s status 0x%x", hdev->name, status);
759
760 if (!status)
761 return;
762
763 cp = hci_sent_cmd_data(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES);
764 if (!cp)
765 return;
766
767 hci_dev_lock(hdev);
768
769 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
770 if (conn) {
771 if (conn->state == BT_CONFIG) {
Marcel Holtmann769be972008-07-14 20:13:49 +0200772 hci_proto_connect_cfm(conn, status);
773 hci_conn_put(conn);
774 }
775 }
776
777 hci_dev_unlock(hdev);
778}
779
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200780static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
781{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200782 struct hci_cp_setup_sync_conn *cp;
783 struct hci_conn *acl, *sco;
784 __u16 handle;
785
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200786 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200787
788 if (!status)
789 return;
790
791 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
792 if (!cp)
793 return;
794
795 handle = __le16_to_cpu(cp->handle);
796
797 BT_DBG("%s handle %d", hdev->name, handle);
798
799 hci_dev_lock(hdev);
800
801 acl = hci_conn_hash_lookup_handle(hdev, handle);
802 if (acl && (sco = acl->link)) {
803 sco->state = BT_CLOSED;
804
805 hci_proto_connect_cfm(sco, status);
806 hci_conn_del(sco);
807 }
808
809 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200810}
811
812static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
813{
814 struct hci_cp_sniff_mode *cp;
815 struct hci_conn *conn;
816
817 BT_DBG("%s status 0x%x", hdev->name, status);
818
819 if (!status)
820 return;
821
822 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
823 if (!cp)
824 return;
825
826 hci_dev_lock(hdev);
827
828 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400829 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200830 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
831
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400832 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
833 hci_sco_setup(conn, status);
834 }
835
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200836 hci_dev_unlock(hdev);
837}
838
839static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
840{
841 struct hci_cp_exit_sniff_mode *cp;
842 struct hci_conn *conn;
843
844 BT_DBG("%s status 0x%x", hdev->name, status);
845
846 if (!status)
847 return;
848
849 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
850 if (!cp)
851 return;
852
853 hci_dev_lock(hdev);
854
855 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400856 if (conn) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200857 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
858
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400859 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
860 hci_sco_setup(conn, status);
861 }
862
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200863 hci_dev_unlock(hdev);
864}
865
866static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
867{
868 __u8 status = *((__u8 *) skb->data);
869
870 BT_DBG("%s status %d", hdev->name, status);
871
872 clear_bit(HCI_INQUIRY, &hdev->flags);
873
874 hci_req_complete(hdev, status);
875
876 hci_conn_check_pending(hdev);
877}
878
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
880{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700881 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200882 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700883 int num_rsp = *((__u8 *) skb->data);
884
885 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
886
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700887 if (!num_rsp)
888 return;
889
Linus Torvalds1da177e2005-04-16 15:20:36 -0700890 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700891
Linus Torvalds1da177e2005-04-16 15:20:36 -0700892 for (; num_rsp; num_rsp--) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700893 bacpy(&data.bdaddr, &info->bdaddr);
894 data.pscan_rep_mode = info->pscan_rep_mode;
895 data.pscan_period_mode = info->pscan_period_mode;
896 data.pscan_mode = info->pscan_mode;
897 memcpy(data.dev_class, info->dev_class, 3);
898 data.clock_offset = info->clock_offset;
899 data.rssi = 0x00;
Marcel Holtmann41a96212008-07-14 20:13:48 +0200900 data.ssp_mode = 0x00;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700901 info++;
902 hci_inquiry_cache_update(hdev, &data);
903 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700904
Linus Torvalds1da177e2005-04-16 15:20:36 -0700905 hci_dev_unlock(hdev);
906}
907
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200908static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700909{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200910 struct hci_ev_conn_complete *ev = (void *) skb->data;
911 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200913 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700914
Linus Torvalds1da177e2005-04-16 15:20:36 -0700915 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700916
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200917 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann94992372009-04-19 19:30:03 +0200918 if (!conn) {
919 if (ev->link_type != SCO_LINK)
920 goto unlock;
921
922 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
923 if (!conn)
924 goto unlock;
925
926 conn->type = SCO_LINK;
927 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700928
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200929 if (!ev->status) {
930 conn->handle = __le16_to_cpu(ev->handle);
Marcel Holtmann769be972008-07-14 20:13:49 +0200931
932 if (conn->type == ACL_LINK) {
933 conn->state = BT_CONFIG;
934 hci_conn_hold(conn);
Marcel Holtmann052b30b2009-04-26 20:01:22 +0200935 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
Marcel Holtmann769be972008-07-14 20:13:49 +0200936 } else
937 conn->state = BT_CONNECTED;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200938
Marcel Holtmann9eba32b2009-08-22 14:19:26 -0700939 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +0200940 hci_conn_add_sysfs(conn);
941
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200942 if (test_bit(HCI_AUTH, &hdev->flags))
943 conn->link_mode |= HCI_LM_AUTH;
944
945 if (test_bit(HCI_ENCRYPT, &hdev->flags))
946 conn->link_mode |= HCI_LM_ENCRYPT;
947
948 /* Get remote features */
949 if (conn->type == ACL_LINK) {
950 struct hci_cp_read_remote_features cp;
951 cp.handle = ev->handle;
Marcel Holtmann769be972008-07-14 20:13:49 +0200952 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES,
953 sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700954 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700955
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200956 /* Set packet type for incoming connection */
Marcel Holtmanna8746412008-07-14 20:13:46 +0200957 if (!conn->out && hdev->hci_ver < 3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200958 struct hci_cp_change_conn_ptype cp;
959 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +0200960 cp.pkt_type = cpu_to_le16(conn->pkt_type);
961 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
962 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200963 }
964 } else
965 conn->state = BT_CLOSED;
966
Marcel Holtmanne73439d2010-07-26 10:06:00 -0400967 if (conn->type == ACL_LINK)
968 hci_sco_setup(conn, ev->status);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700969
Marcel Holtmann769be972008-07-14 20:13:49 +0200970 if (ev->status) {
971 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200972 hci_conn_del(conn);
Marcel Holtmannc89b6e62009-01-15 21:57:03 +0100973 } else if (ev->link_type != ACL_LINK)
974 hci_proto_connect_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200975
976unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200978
979 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700980}
981
Linus Torvalds1da177e2005-04-16 15:20:36 -0700982static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
983{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200984 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985 int mask = hdev->link_mode;
986
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200987 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
988 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989
990 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
991
Johan Hedbergf0358562010-05-18 13:20:32 +0200992 if ((mask & HCI_LM_ACCEPT) && !hci_blacklist_lookup(hdev, &ev->bdaddr)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700993 /* Connection accepted */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +0200994 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700995 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700996
997 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200998
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +0200999 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1000 if (ie)
Marcel Holtmannc7bdd502008-07-14 20:13:47 +02001001 memcpy(ie->data.dev_class, ev->dev_class, 3);
1002
Linus Torvalds1da177e2005-04-16 15:20:36 -07001003 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
1004 if (!conn) {
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001005 conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr);
1006 if (!conn) {
Gustavo F. Padovan893ef972010-07-18 15:13:37 -03001007 BT_ERR("No memory for new connection");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008 hci_dev_unlock(hdev);
1009 return;
1010 }
1011 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001012
Linus Torvalds1da177e2005-04-16 15:20:36 -07001013 memcpy(conn->dev_class, ev->dev_class, 3);
1014 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001015
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016 hci_dev_unlock(hdev);
1017
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001018 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
1019 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001020
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001021 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001022
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001023 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
1024 cp.role = 0x00; /* Become master */
1025 else
1026 cp.role = 0x01; /* Remain slave */
1027
1028 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
1029 sizeof(cp), &cp);
1030 } else {
1031 struct hci_cp_accept_sync_conn_req cp;
1032
1033 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +02001034 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001035
1036 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
1037 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
1038 cp.max_latency = cpu_to_le16(0xffff);
1039 cp.content_format = cpu_to_le16(hdev->voice_setting);
1040 cp.retrans_effort = 0xff;
1041
1042 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
1043 sizeof(cp), &cp);
1044 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001045 } else {
1046 /* Connection rejected */
1047 struct hci_cp_reject_conn_req cp;
1048
1049 bacpy(&cp.bdaddr, &ev->bdaddr);
1050 cp.reason = 0x0f;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001051 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001052 }
1053}
1054
Linus Torvalds1da177e2005-04-16 15:20:36 -07001055static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1056{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001057 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001058 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059
1060 BT_DBG("%s status %d", hdev->name, ev->status);
1061
1062 if (ev->status)
1063 return;
1064
1065 hci_dev_lock(hdev);
1066
Marcel Holtmann04837f62006-07-03 10:02:33 +02001067 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001068 if (conn) {
1069 conn->state = BT_CLOSED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001070
Marcel Holtmann2950f212009-02-12 14:02:50 +01001071 hci_proto_disconn_cfm(conn, ev->reason);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072 hci_conn_del(conn);
1073 }
1074
1075 hci_dev_unlock(hdev);
1076}
1077
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001078static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1079{
1080 struct hci_ev_auth_complete *ev = (void *) skb->data;
1081 struct hci_conn *conn;
1082
1083 BT_DBG("%s status %d", hdev->name, ev->status);
1084
1085 hci_dev_lock(hdev);
1086
1087 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1088 if (conn) {
1089 if (!ev->status)
1090 conn->link_mode |= HCI_LM_AUTH;
Johan Hedbergda213f42010-06-18 11:08:56 +03001091 else
1092 conn->sec_level = BT_SECURITY_LOW;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001093
1094 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1095
Marcel Holtmannf8558552008-07-14 20:13:49 +02001096 if (conn->state == BT_CONFIG) {
1097 if (!ev->status && hdev->ssp_mode > 0 &&
1098 conn->ssp_mode > 0) {
1099 struct hci_cp_set_conn_encrypt cp;
1100 cp.handle = ev->handle;
1101 cp.encrypt = 0x01;
1102 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1103 sizeof(cp), &cp);
1104 } else {
1105 conn->state = BT_CONNECTED;
1106 hci_proto_connect_cfm(conn, ev->status);
1107 hci_conn_put(conn);
1108 }
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001109 } else {
Marcel Holtmannf8558552008-07-14 20:13:49 +02001110 hci_auth_cfm(conn, ev->status);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001111
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001112 hci_conn_hold(conn);
1113 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1114 hci_conn_put(conn);
1115 }
1116
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001117 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
1118 if (!ev->status) {
1119 struct hci_cp_set_conn_encrypt cp;
Marcel Holtmannf8558552008-07-14 20:13:49 +02001120 cp.handle = ev->handle;
1121 cp.encrypt = 0x01;
1122 hci_send_cmd(hdev, HCI_OP_SET_CONN_ENCRYPT,
1123 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001124 } else {
1125 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1126 hci_encrypt_cfm(conn, ev->status, 0x00);
1127 }
1128 }
1129 }
1130
1131 hci_dev_unlock(hdev);
1132}
1133
1134static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
1135{
Johan Hedberg127178d2010-11-18 22:22:29 +02001136 struct hci_ev_remote_name *ev = (void *) skb->data;
1137 struct hci_conn *conn;
1138
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001139 BT_DBG("%s", hdev->name);
1140
1141 hci_conn_check_pending(hdev);
Johan Hedberg127178d2010-11-18 22:22:29 +02001142
1143 hci_dev_lock(hdev);
1144
1145 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1146 if (conn && hci_outgoing_auth_needed(hdev, conn)) {
1147 struct hci_cp_auth_requested cp;
1148 cp.handle = __cpu_to_le16(conn->handle);
1149 hci_send_cmd(hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp);
1150 }
1151
1152 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001153}
1154
1155static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1156{
1157 struct hci_ev_encrypt_change *ev = (void *) skb->data;
1158 struct hci_conn *conn;
1159
1160 BT_DBG("%s status %d", hdev->name, ev->status);
1161
1162 hci_dev_lock(hdev);
1163
1164 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1165 if (conn) {
1166 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +02001167 if (ev->encrypt) {
1168 /* Encryption implies authentication */
1169 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001170 conn->link_mode |= HCI_LM_ENCRYPT;
Marcel Holtmannae293192008-07-14 20:13:45 +02001171 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001172 conn->link_mode &= ~HCI_LM_ENCRYPT;
1173 }
1174
1175 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1176
Marcel Holtmannf8558552008-07-14 20:13:49 +02001177 if (conn->state == BT_CONFIG) {
1178 if (!ev->status)
1179 conn->state = BT_CONNECTED;
1180
1181 hci_proto_connect_cfm(conn, ev->status);
1182 hci_conn_put(conn);
1183 } else
1184 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001185 }
1186
1187 hci_dev_unlock(hdev);
1188}
1189
1190static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1191{
1192 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
1193 struct hci_conn *conn;
1194
1195 BT_DBG("%s status %d", hdev->name, ev->status);
1196
1197 hci_dev_lock(hdev);
1198
1199 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1200 if (conn) {
1201 if (!ev->status)
1202 conn->link_mode |= HCI_LM_SECURE;
1203
1204 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1205
1206 hci_key_change_cfm(conn, ev->status);
1207 }
1208
1209 hci_dev_unlock(hdev);
1210}
1211
1212static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1213{
1214 struct hci_ev_remote_features *ev = (void *) skb->data;
1215 struct hci_conn *conn;
1216
1217 BT_DBG("%s status %d", hdev->name, ev->status);
1218
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001219 hci_dev_lock(hdev);
1220
1221 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001222 if (!conn)
1223 goto unlock;
Marcel Holtmann769be972008-07-14 20:13:49 +02001224
Johan Hedbergccd556f2010-11-10 17:11:51 +02001225 if (!ev->status)
1226 memcpy(conn->features, ev->features, 8);
1227
1228 if (conn->state != BT_CONFIG)
1229 goto unlock;
1230
1231 if (!ev->status && lmp_ssp_capable(hdev) && lmp_ssp_capable(conn)) {
1232 struct hci_cp_read_remote_ext_features cp;
1233 cp.handle = ev->handle;
1234 cp.page = 0x01;
1235 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_EXT_FEATURES,
Marcel Holtmann769be972008-07-14 20:13:49 +02001236 sizeof(cp), &cp);
Johan Hedberg392599b2010-11-18 22:22:28 +02001237 goto unlock;
1238 }
1239
Johan Hedberg127178d2010-11-18 22:22:29 +02001240 if (!ev->status) {
1241 struct hci_cp_remote_name_req cp;
1242 memset(&cp, 0, sizeof(cp));
1243 bacpy(&cp.bdaddr, &conn->dst);
1244 cp.pscan_rep_mode = 0x02;
1245 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1246 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001247
Johan Hedberg127178d2010-11-18 22:22:29 +02001248 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001249 conn->state = BT_CONNECTED;
1250 hci_proto_connect_cfm(conn, ev->status);
1251 hci_conn_put(conn);
Marcel Holtmann769be972008-07-14 20:13:49 +02001252 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001253
Johan Hedbergccd556f2010-11-10 17:11:51 +02001254unlock:
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001255 hci_dev_unlock(hdev);
1256}
1257
1258static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
1259{
1260 BT_DBG("%s", hdev->name);
1261}
1262
1263static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1264{
1265 BT_DBG("%s", hdev->name);
1266}
1267
1268static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1269{
1270 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1271 __u16 opcode;
1272
1273 skb_pull(skb, sizeof(*ev));
1274
1275 opcode = __le16_to_cpu(ev->opcode);
1276
1277 switch (opcode) {
1278 case HCI_OP_INQUIRY_CANCEL:
1279 hci_cc_inquiry_cancel(hdev, skb);
1280 break;
1281
1282 case HCI_OP_EXIT_PERIODIC_INQ:
1283 hci_cc_exit_periodic_inq(hdev, skb);
1284 break;
1285
1286 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1287 hci_cc_remote_name_req_cancel(hdev, skb);
1288 break;
1289
1290 case HCI_OP_ROLE_DISCOVERY:
1291 hci_cc_role_discovery(hdev, skb);
1292 break;
1293
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001294 case HCI_OP_READ_LINK_POLICY:
1295 hci_cc_read_link_policy(hdev, skb);
1296 break;
1297
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001298 case HCI_OP_WRITE_LINK_POLICY:
1299 hci_cc_write_link_policy(hdev, skb);
1300 break;
1301
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001302 case HCI_OP_READ_DEF_LINK_POLICY:
1303 hci_cc_read_def_link_policy(hdev, skb);
1304 break;
1305
1306 case HCI_OP_WRITE_DEF_LINK_POLICY:
1307 hci_cc_write_def_link_policy(hdev, skb);
1308 break;
1309
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001310 case HCI_OP_RESET:
1311 hci_cc_reset(hdev, skb);
1312 break;
1313
1314 case HCI_OP_WRITE_LOCAL_NAME:
1315 hci_cc_write_local_name(hdev, skb);
1316 break;
1317
1318 case HCI_OP_READ_LOCAL_NAME:
1319 hci_cc_read_local_name(hdev, skb);
1320 break;
1321
1322 case HCI_OP_WRITE_AUTH_ENABLE:
1323 hci_cc_write_auth_enable(hdev, skb);
1324 break;
1325
1326 case HCI_OP_WRITE_ENCRYPT_MODE:
1327 hci_cc_write_encrypt_mode(hdev, skb);
1328 break;
1329
1330 case HCI_OP_WRITE_SCAN_ENABLE:
1331 hci_cc_write_scan_enable(hdev, skb);
1332 break;
1333
1334 case HCI_OP_READ_CLASS_OF_DEV:
1335 hci_cc_read_class_of_dev(hdev, skb);
1336 break;
1337
1338 case HCI_OP_WRITE_CLASS_OF_DEV:
1339 hci_cc_write_class_of_dev(hdev, skb);
1340 break;
1341
1342 case HCI_OP_READ_VOICE_SETTING:
1343 hci_cc_read_voice_setting(hdev, skb);
1344 break;
1345
1346 case HCI_OP_WRITE_VOICE_SETTING:
1347 hci_cc_write_voice_setting(hdev, skb);
1348 break;
1349
1350 case HCI_OP_HOST_BUFFER_SIZE:
1351 hci_cc_host_buffer_size(hdev, skb);
1352 break;
1353
Marcel Holtmann333140b2008-07-14 20:13:48 +02001354 case HCI_OP_READ_SSP_MODE:
1355 hci_cc_read_ssp_mode(hdev, skb);
1356 break;
1357
1358 case HCI_OP_WRITE_SSP_MODE:
1359 hci_cc_write_ssp_mode(hdev, skb);
1360 break;
1361
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001362 case HCI_OP_READ_LOCAL_VERSION:
1363 hci_cc_read_local_version(hdev, skb);
1364 break;
1365
1366 case HCI_OP_READ_LOCAL_COMMANDS:
1367 hci_cc_read_local_commands(hdev, skb);
1368 break;
1369
1370 case HCI_OP_READ_LOCAL_FEATURES:
1371 hci_cc_read_local_features(hdev, skb);
1372 break;
1373
1374 case HCI_OP_READ_BUFFER_SIZE:
1375 hci_cc_read_buffer_size(hdev, skb);
1376 break;
1377
1378 case HCI_OP_READ_BD_ADDR:
1379 hci_cc_read_bd_addr(hdev, skb);
1380 break;
1381
1382 default:
1383 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1384 break;
1385 }
1386
1387 if (ev->ncmd) {
1388 atomic_set(&hdev->cmd_cnt, 1);
1389 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001390 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001391 }
1392}
1393
1394static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
1395{
1396 struct hci_ev_cmd_status *ev = (void *) skb->data;
1397 __u16 opcode;
1398
1399 skb_pull(skb, sizeof(*ev));
1400
1401 opcode = __le16_to_cpu(ev->opcode);
1402
1403 switch (opcode) {
1404 case HCI_OP_INQUIRY:
1405 hci_cs_inquiry(hdev, ev->status);
1406 break;
1407
1408 case HCI_OP_CREATE_CONN:
1409 hci_cs_create_conn(hdev, ev->status);
1410 break;
1411
1412 case HCI_OP_ADD_SCO:
1413 hci_cs_add_sco(hdev, ev->status);
1414 break;
1415
Marcel Holtmannf8558552008-07-14 20:13:49 +02001416 case HCI_OP_AUTH_REQUESTED:
1417 hci_cs_auth_requested(hdev, ev->status);
1418 break;
1419
1420 case HCI_OP_SET_CONN_ENCRYPT:
1421 hci_cs_set_conn_encrypt(hdev, ev->status);
1422 break;
1423
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001424 case HCI_OP_REMOTE_NAME_REQ:
1425 hci_cs_remote_name_req(hdev, ev->status);
1426 break;
1427
Marcel Holtmann769be972008-07-14 20:13:49 +02001428 case HCI_OP_READ_REMOTE_FEATURES:
1429 hci_cs_read_remote_features(hdev, ev->status);
1430 break;
1431
1432 case HCI_OP_READ_REMOTE_EXT_FEATURES:
1433 hci_cs_read_remote_ext_features(hdev, ev->status);
1434 break;
1435
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001436 case HCI_OP_SETUP_SYNC_CONN:
1437 hci_cs_setup_sync_conn(hdev, ev->status);
1438 break;
1439
1440 case HCI_OP_SNIFF_MODE:
1441 hci_cs_sniff_mode(hdev, ev->status);
1442 break;
1443
1444 case HCI_OP_EXIT_SNIFF_MODE:
1445 hci_cs_exit_sniff_mode(hdev, ev->status);
1446 break;
1447
1448 default:
1449 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1450 break;
1451 }
1452
1453 if (ev->ncmd) {
1454 atomic_set(&hdev->cmd_cnt, 1);
1455 if (!skb_queue_empty(&hdev->cmd_q))
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001456 tasklet_schedule(&hdev->cmd_task);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001457 }
1458}
1459
1460static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1461{
1462 struct hci_ev_role_change *ev = (void *) skb->data;
1463 struct hci_conn *conn;
1464
1465 BT_DBG("%s status %d", hdev->name, ev->status);
1466
1467 hci_dev_lock(hdev);
1468
1469 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1470 if (conn) {
1471 if (!ev->status) {
1472 if (ev->role)
1473 conn->link_mode &= ~HCI_LM_MASTER;
1474 else
1475 conn->link_mode |= HCI_LM_MASTER;
1476 }
1477
1478 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
1479
1480 hci_role_switch_cfm(conn, ev->status, ev->role);
1481 }
1482
1483 hci_dev_unlock(hdev);
1484}
1485
Linus Torvalds1da177e2005-04-16 15:20:36 -07001486static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
1487{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001488 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001489 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001490 int i;
1491
1492 skb_pull(skb, sizeof(*ev));
1493
1494 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
1495
1496 if (skb->len < ev->num_hndl * 4) {
1497 BT_DBG("%s bad parameters", hdev->name);
1498 return;
1499 }
1500
1501 tasklet_disable(&hdev->tx_task);
1502
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001503 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504 struct hci_conn *conn;
1505 __u16 handle, count;
1506
Harvey Harrison83985312008-05-02 16:25:46 -07001507 handle = get_unaligned_le16(ptr++);
1508 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001509
1510 conn = hci_conn_hash_lookup_handle(hdev, handle);
1511 if (conn) {
1512 conn->sent -= count;
1513
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001514 if (conn->type == ACL_LINK) {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001515 hdev->acl_cnt += count;
1516 if (hdev->acl_cnt > hdev->acl_pkts)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001517 hdev->acl_cnt = hdev->acl_pkts;
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001518 } else {
Andrei Emeltchenko70f230202010-12-01 16:58:25 +02001519 hdev->sco_cnt += count;
1520 if (hdev->sco_cnt > hdev->sco_pkts)
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001521 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001522 }
1523 }
1524 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001525
Marcel Holtmannc78ae282009-11-18 01:02:54 +01001526 tasklet_schedule(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001527
1528 tasklet_enable(&hdev->tx_task);
1529}
1530
Marcel Holtmann04837f62006-07-03 10:02:33 +02001531static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001532{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001533 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001534 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535
1536 BT_DBG("%s status %d", hdev->name, ev->status);
1537
1538 hci_dev_lock(hdev);
1539
Marcel Holtmann04837f62006-07-03 10:02:33 +02001540 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1541 if (conn) {
1542 conn->mode = ev->mode;
1543 conn->interval = __le16_to_cpu(ev->interval);
1544
1545 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
1546 if (conn->mode == HCI_CM_ACTIVE)
1547 conn->power_save = 1;
1548 else
1549 conn->power_save = 0;
1550 }
Marcel Holtmanne73439d2010-07-26 10:06:00 -04001551
1552 if (test_and_clear_bit(HCI_CONN_SCO_SETUP_PEND, &conn->pend))
1553 hci_sco_setup(conn, ev->status);
Marcel Holtmann04837f62006-07-03 10:02:33 +02001554 }
1555
1556 hci_dev_unlock(hdev);
1557}
1558
Linus Torvalds1da177e2005-04-16 15:20:36 -07001559static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1560{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001561 struct hci_ev_pin_code_req *ev = (void *) skb->data;
1562 struct hci_conn *conn;
1563
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001564 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001565
1566 hci_dev_lock(hdev);
1567
1568 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
Marcel Holtmann3d7a9d12009-05-09 12:09:21 -07001569 if (conn && conn->state == BT_CONNECTED) {
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001570 hci_conn_hold(conn);
1571 conn->disc_timeout = HCI_PAIRING_TIMEOUT;
1572 hci_conn_put(conn);
1573 }
1574
1575 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001576}
1577
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1579{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001580 BT_DBG("%s", hdev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581}
1582
Linus Torvalds1da177e2005-04-16 15:20:36 -07001583static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
1584{
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001585 struct hci_ev_link_key_notify *ev = (void *) skb->data;
1586 struct hci_conn *conn;
1587
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001588 BT_DBG("%s", hdev->name);
Marcel Holtmann052b30b2009-04-26 20:01:22 +02001589
1590 hci_dev_lock(hdev);
1591
1592 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1593 if (conn) {
1594 hci_conn_hold(conn);
1595 conn->disc_timeout = HCI_DISCONN_TIMEOUT;
1596 hci_conn_put(conn);
1597 }
1598
1599 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600}
1601
Marcel Holtmann04837f62006-07-03 10:02:33 +02001602static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
1603{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001604 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001605 struct hci_conn *conn;
1606
1607 BT_DBG("%s status %d", hdev->name, ev->status);
1608
1609 hci_dev_lock(hdev);
1610
1611 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612 if (conn && !ev->status) {
1613 struct inquiry_entry *ie;
1614
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001615 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
1616 if (ie) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617 ie->data.clock_offset = ev->clock_offset;
1618 ie->timestamp = jiffies;
1619 }
1620 }
1621
1622 hci_dev_unlock(hdev);
1623}
1624
Marcel Holtmanna8746412008-07-14 20:13:46 +02001625static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1626{
1627 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
1628 struct hci_conn *conn;
1629
1630 BT_DBG("%s status %d", hdev->name, ev->status);
1631
1632 hci_dev_lock(hdev);
1633
1634 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1635 if (conn && !ev->status)
1636 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
1637
1638 hci_dev_unlock(hdev);
1639}
1640
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001641static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
1642{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001643 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001644 struct inquiry_entry *ie;
1645
1646 BT_DBG("%s", hdev->name);
1647
1648 hci_dev_lock(hdev);
1649
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001650 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1651 if (ie) {
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001652 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
1653 ie->timestamp = jiffies;
1654 }
1655
1656 hci_dev_unlock(hdev);
1657}
1658
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001659static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
1660{
1661 struct inquiry_data data;
1662 int num_rsp = *((__u8 *) skb->data);
1663
1664 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1665
1666 if (!num_rsp)
1667 return;
1668
1669 hci_dev_lock(hdev);
1670
1671 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
1672 struct inquiry_info_with_rssi_and_pscan_mode *info = (void *) (skb->data + 1);
1673
1674 for (; num_rsp; num_rsp--) {
1675 bacpy(&data.bdaddr, &info->bdaddr);
1676 data.pscan_rep_mode = info->pscan_rep_mode;
1677 data.pscan_period_mode = info->pscan_period_mode;
1678 data.pscan_mode = info->pscan_mode;
1679 memcpy(data.dev_class, info->dev_class, 3);
1680 data.clock_offset = info->clock_offset;
1681 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001682 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001683 info++;
1684 hci_inquiry_cache_update(hdev, &data);
1685 }
1686 } else {
1687 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
1688
1689 for (; num_rsp; num_rsp--) {
1690 bacpy(&data.bdaddr, &info->bdaddr);
1691 data.pscan_rep_mode = info->pscan_rep_mode;
1692 data.pscan_period_mode = info->pscan_period_mode;
1693 data.pscan_mode = 0x00;
1694 memcpy(data.dev_class, info->dev_class, 3);
1695 data.clock_offset = info->clock_offset;
1696 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001697 data.ssp_mode = 0x00;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001698 info++;
1699 hci_inquiry_cache_update(hdev, &data);
1700 }
1701 }
1702
1703 hci_dev_unlock(hdev);
1704}
1705
1706static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1707{
Marcel Holtmann41a96212008-07-14 20:13:48 +02001708 struct hci_ev_remote_ext_features *ev = (void *) skb->data;
1709 struct hci_conn *conn;
1710
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001711 BT_DBG("%s", hdev->name);
Marcel Holtmann41a96212008-07-14 20:13:48 +02001712
Marcel Holtmann41a96212008-07-14 20:13:48 +02001713 hci_dev_lock(hdev);
1714
1715 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Johan Hedbergccd556f2010-11-10 17:11:51 +02001716 if (!conn)
1717 goto unlock;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001718
Johan Hedbergccd556f2010-11-10 17:11:51 +02001719 if (!ev->status && ev->page == 0x01) {
1720 struct inquiry_entry *ie;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001721
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001722 ie = hci_inquiry_cache_lookup(hdev, &conn->dst);
1723 if (ie)
Johan Hedbergccd556f2010-11-10 17:11:51 +02001724 ie->data.ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann769be972008-07-14 20:13:49 +02001725
Johan Hedbergccd556f2010-11-10 17:11:51 +02001726 conn->ssp_mode = (ev->features[0] & 0x01);
Marcel Holtmann41a96212008-07-14 20:13:48 +02001727 }
1728
Johan Hedbergccd556f2010-11-10 17:11:51 +02001729 if (conn->state != BT_CONFIG)
1730 goto unlock;
1731
Johan Hedberg127178d2010-11-18 22:22:29 +02001732 if (!ev->status) {
1733 struct hci_cp_remote_name_req cp;
1734 memset(&cp, 0, sizeof(cp));
1735 bacpy(&cp.bdaddr, &conn->dst);
1736 cp.pscan_rep_mode = 0x02;
1737 hci_send_cmd(hdev, HCI_OP_REMOTE_NAME_REQ, sizeof(cp), &cp);
1738 }
Johan Hedberg392599b2010-11-18 22:22:28 +02001739
Johan Hedberg127178d2010-11-18 22:22:29 +02001740 if (!hci_outgoing_auth_needed(hdev, conn)) {
Johan Hedbergccd556f2010-11-10 17:11:51 +02001741 conn->state = BT_CONNECTED;
1742 hci_proto_connect_cfm(conn, ev->status);
1743 hci_conn_put(conn);
1744 }
1745
1746unlock:
Marcel Holtmann41a96212008-07-14 20:13:48 +02001747 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001748}
1749
1750static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1751{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001752 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
1753 struct hci_conn *conn;
1754
1755 BT_DBG("%s status %d", hdev->name, ev->status);
1756
1757 hci_dev_lock(hdev);
1758
1759 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02001760 if (!conn) {
1761 if (ev->link_type == ESCO_LINK)
1762 goto unlock;
1763
1764 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1765 if (!conn)
1766 goto unlock;
1767
1768 conn->type = SCO_LINK;
1769 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001770
Marcel Holtmann732547f2009-04-19 19:14:14 +02001771 switch (ev->status) {
1772 case 0x00:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001773 conn->handle = __le16_to_cpu(ev->handle);
1774 conn->state = BT_CONNECTED;
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001775
Marcel Holtmann9eba32b2009-08-22 14:19:26 -07001776 hci_conn_hold_device(conn);
Marcel Holtmann7d0db0a2008-07-14 20:13:51 +02001777 hci_conn_add_sysfs(conn);
Marcel Holtmann732547f2009-04-19 19:14:14 +02001778 break;
1779
Stephen Coe705e5712010-02-16 11:29:44 -05001780 case 0x11: /* Unsupported Feature or Parameter Value */
Marcel Holtmann732547f2009-04-19 19:14:14 +02001781 case 0x1c: /* SCO interval rejected */
Nick Pelly1038a002010-02-03 11:42:26 -08001782 case 0x1a: /* Unsupported Remote Feature */
Marcel Holtmann732547f2009-04-19 19:14:14 +02001783 case 0x1f: /* Unspecified error */
1784 if (conn->out && conn->attempt < 2) {
1785 conn->pkt_type = (hdev->esco_type & SCO_ESCO_MASK) |
1786 (hdev->esco_type & EDR_ESCO_MASK);
1787 hci_setup_sync(conn, conn->link->handle);
1788 goto unlock;
1789 }
1790 /* fall through */
1791
1792 default:
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001793 conn->state = BT_CLOSED;
Marcel Holtmann732547f2009-04-19 19:14:14 +02001794 break;
1795 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001796
1797 hci_proto_connect_cfm(conn, ev->status);
1798 if (ev->status)
1799 hci_conn_del(conn);
1800
1801unlock:
1802 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001803}
1804
1805static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
1806{
1807 BT_DBG("%s", hdev->name);
1808}
1809
Marcel Holtmann04837f62006-07-03 10:02:33 +02001810static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
1811{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001812 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001813 struct hci_conn *conn;
1814
1815 BT_DBG("%s status %d", hdev->name, ev->status);
1816
1817 hci_dev_lock(hdev);
1818
1819 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1820 if (conn) {
1821 }
1822
1823 hci_dev_unlock(hdev);
1824}
1825
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001826static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1827{
1828 struct inquiry_data data;
1829 struct extended_inquiry_info *info = (void *) (skb->data + 1);
1830 int num_rsp = *((__u8 *) skb->data);
1831
1832 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1833
1834 if (!num_rsp)
1835 return;
1836
1837 hci_dev_lock(hdev);
1838
1839 for (; num_rsp; num_rsp--) {
1840 bacpy(&data.bdaddr, &info->bdaddr);
1841 data.pscan_rep_mode = info->pscan_rep_mode;
1842 data.pscan_period_mode = info->pscan_period_mode;
1843 data.pscan_mode = 0x00;
1844 memcpy(data.dev_class, info->dev_class, 3);
1845 data.clock_offset = info->clock_offset;
1846 data.rssi = info->rssi;
Marcel Holtmann41a96212008-07-14 20:13:48 +02001847 data.ssp_mode = 0x01;
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001848 info++;
1849 hci_inquiry_cache_update(hdev, &data);
1850 }
1851
1852 hci_dev_unlock(hdev);
1853}
1854
Marcel Holtmann04936842008-07-14 20:13:48 +02001855static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1856{
1857 struct hci_ev_io_capa_request *ev = (void *) skb->data;
1858 struct hci_conn *conn;
1859
1860 BT_DBG("%s", hdev->name);
1861
1862 hci_dev_lock(hdev);
1863
1864 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1865 if (conn)
1866 hci_conn_hold(conn);
1867
1868 hci_dev_unlock(hdev);
1869}
1870
1871static inline void hci_simple_pair_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1872{
1873 struct hci_ev_simple_pair_complete *ev = (void *) skb->data;
1874 struct hci_conn *conn;
1875
1876 BT_DBG("%s", hdev->name);
1877
1878 hci_dev_lock(hdev);
1879
1880 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1881 if (conn)
1882 hci_conn_put(conn);
1883
1884 hci_dev_unlock(hdev);
1885}
1886
Marcel Holtmann41a96212008-07-14 20:13:48 +02001887static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1888{
1889 struct hci_ev_remote_host_features *ev = (void *) skb->data;
1890 struct inquiry_entry *ie;
1891
1892 BT_DBG("%s", hdev->name);
1893
1894 hci_dev_lock(hdev);
1895
Andrei Emeltchenkocc11b9c2010-11-22 13:21:37 +02001896 ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr);
1897 if (ie)
Marcel Holtmann41a96212008-07-14 20:13:48 +02001898 ie->data.ssp_mode = (ev->features[0] & 0x01);
1899
1900 hci_dev_unlock(hdev);
1901}
1902
Linus Torvalds1da177e2005-04-16 15:20:36 -07001903void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
1904{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001905 struct hci_event_hdr *hdr = (void *) skb->data;
1906 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907
1908 skb_pull(skb, HCI_EVENT_HDR_SIZE);
1909
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001910 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911 case HCI_EV_INQUIRY_COMPLETE:
1912 hci_inquiry_complete_evt(hdev, skb);
1913 break;
1914
1915 case HCI_EV_INQUIRY_RESULT:
1916 hci_inquiry_result_evt(hdev, skb);
1917 break;
1918
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001919 case HCI_EV_CONN_COMPLETE:
1920 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02001921 break;
1922
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923 case HCI_EV_CONN_REQUEST:
1924 hci_conn_request_evt(hdev, skb);
1925 break;
1926
Linus Torvalds1da177e2005-04-16 15:20:36 -07001927 case HCI_EV_DISCONN_COMPLETE:
1928 hci_disconn_complete_evt(hdev, skb);
1929 break;
1930
Linus Torvalds1da177e2005-04-16 15:20:36 -07001931 case HCI_EV_AUTH_COMPLETE:
1932 hci_auth_complete_evt(hdev, skb);
1933 break;
1934
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001935 case HCI_EV_REMOTE_NAME:
1936 hci_remote_name_evt(hdev, skb);
1937 break;
1938
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939 case HCI_EV_ENCRYPT_CHANGE:
1940 hci_encrypt_change_evt(hdev, skb);
1941 break;
1942
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001943 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
1944 hci_change_link_key_complete_evt(hdev, skb);
1945 break;
1946
1947 case HCI_EV_REMOTE_FEATURES:
1948 hci_remote_features_evt(hdev, skb);
1949 break;
1950
1951 case HCI_EV_REMOTE_VERSION:
1952 hci_remote_version_evt(hdev, skb);
1953 break;
1954
1955 case HCI_EV_QOS_SETUP_COMPLETE:
1956 hci_qos_setup_complete_evt(hdev, skb);
1957 break;
1958
1959 case HCI_EV_CMD_COMPLETE:
1960 hci_cmd_complete_evt(hdev, skb);
1961 break;
1962
1963 case HCI_EV_CMD_STATUS:
1964 hci_cmd_status_evt(hdev, skb);
1965 break;
1966
1967 case HCI_EV_ROLE_CHANGE:
1968 hci_role_change_evt(hdev, skb);
1969 break;
1970
1971 case HCI_EV_NUM_COMP_PKTS:
1972 hci_num_comp_pkts_evt(hdev, skb);
1973 break;
1974
1975 case HCI_EV_MODE_CHANGE:
1976 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001977 break;
1978
1979 case HCI_EV_PIN_CODE_REQ:
1980 hci_pin_code_request_evt(hdev, skb);
1981 break;
1982
1983 case HCI_EV_LINK_KEY_REQ:
1984 hci_link_key_request_evt(hdev, skb);
1985 break;
1986
1987 case HCI_EV_LINK_KEY_NOTIFY:
1988 hci_link_key_notify_evt(hdev, skb);
1989 break;
1990
1991 case HCI_EV_CLOCK_OFFSET:
1992 hci_clock_offset_evt(hdev, skb);
1993 break;
1994
Marcel Holtmanna8746412008-07-14 20:13:46 +02001995 case HCI_EV_PKT_TYPE_CHANGE:
1996 hci_pkt_type_change_evt(hdev, skb);
1997 break;
1998
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001999 case HCI_EV_PSCAN_REP_MODE:
2000 hci_pscan_rep_mode_evt(hdev, skb);
2001 break;
2002
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002003 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
2004 hci_inquiry_result_with_rssi_evt(hdev, skb);
2005 break;
2006
2007 case HCI_EV_REMOTE_EXT_FEATURES:
2008 hci_remote_ext_features_evt(hdev, skb);
2009 break;
2010
2011 case HCI_EV_SYNC_CONN_COMPLETE:
2012 hci_sync_conn_complete_evt(hdev, skb);
2013 break;
2014
2015 case HCI_EV_SYNC_CONN_CHANGED:
2016 hci_sync_conn_changed_evt(hdev, skb);
2017 break;
2018
Marcel Holtmann04837f62006-07-03 10:02:33 +02002019 case HCI_EV_SNIFF_SUBRATE:
2020 hci_sniff_subrate_evt(hdev, skb);
2021 break;
2022
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002023 case HCI_EV_EXTENDED_INQUIRY_RESULT:
2024 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002025 break;
2026
Marcel Holtmann04936842008-07-14 20:13:48 +02002027 case HCI_EV_IO_CAPA_REQUEST:
2028 hci_io_capa_request_evt(hdev, skb);
2029 break;
2030
2031 case HCI_EV_SIMPLE_PAIR_COMPLETE:
2032 hci_simple_pair_complete_evt(hdev, skb);
2033 break;
2034
Marcel Holtmann41a96212008-07-14 20:13:48 +02002035 case HCI_EV_REMOTE_HOST_FEATURES:
2036 hci_remote_host_features_evt(hdev, skb);
2037 break;
2038
Marcel Holtmanna9de9242007-10-20 13:33:56 +02002039 default:
2040 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002041 break;
2042 }
2043
2044 kfree_skb(skb);
2045 hdev->stat.evt_rx++;
2046}
2047
2048/* Generate internal stack event */
2049void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
2050{
2051 struct hci_event_hdr *hdr;
2052 struct hci_ev_stack_internal *ev;
2053 struct sk_buff *skb;
2054
2055 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
2056 if (!skb)
2057 return;
2058
2059 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
2060 hdr->evt = HCI_EV_STACK_INTERNAL;
2061 hdr->plen = sizeof(*ev) + dlen;
2062
2063 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
2064 ev->type = type;
2065 memcpy(ev->data, data, dlen);
2066
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002067 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07002068 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02002069
Marcel Holtmann0d48d932005-08-09 20:30:28 -07002070 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002071 skb->dev = (void *) hdev;
2072 hci_send_to_sock(hdev, skb);
2073 kfree_skb(skb);
2074}