blob: 9af181a61650d8aa788cef70c982884ea08a2eb7 [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
3 Copyright (C) 2000-2001 Qualcomm Incorporated
4
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>
42#include <asm/uaccess.h>
43#include <asm/unaligned.h>
44
45#include <net/bluetooth/bluetooth.h>
46#include <net/bluetooth/hci_core.h>
47
48#ifndef CONFIG_BT_HCI_CORE_DEBUG
49#undef BT_DBG
50#define BT_DBG(D...)
51#endif
52
53/* Handle HCI Event packets */
54
Marcel Holtmanna9de9242007-10-20 13:33:56 +020055static void hci_cc_inquiry_cancel(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070056{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020057 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -070058
Marcel Holtmanna9de9242007-10-20 13:33:56 +020059 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070060
Marcel Holtmanna9de9242007-10-20 13:33:56 +020061 if (status)
62 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070063
Marcel Holtmanna9de9242007-10-20 13:33:56 +020064 clear_bit(HCI_INQUIRY, &hdev->flags);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010065
Marcel Holtmanna9de9242007-10-20 13:33:56 +020066 hci_req_complete(hdev, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +010067
Marcel Holtmanna9de9242007-10-20 13:33:56 +020068 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070069}
70
Marcel Holtmanna9de9242007-10-20 13:33:56 +020071static void hci_cc_exit_periodic_inq(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -070072{
Marcel Holtmanna9de9242007-10-20 13:33:56 +020073 __u8 status = *((__u8 *) skb->data);
74
75 BT_DBG("%s status 0x%x", hdev->name, status);
76
77 if (status)
78 return;
79
80 clear_bit(HCI_INQUIRY, &hdev->flags);
81
82 hci_conn_check_pending(hdev);
83}
84
85static void hci_cc_remote_name_req_cancel(struct hci_dev *hdev, struct sk_buff *skb)
86{
87 BT_DBG("%s", hdev->name);
88}
89
90static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb)
91{
92 struct hci_rp_role_discovery *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -070093 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -070094
Marcel Holtmanna9de9242007-10-20 13:33:56 +020095 BT_DBG("%s status 0x%x", hdev->name, rp->status);
Linus Torvalds1da177e2005-04-16 15:20:36 -070096
Marcel Holtmanna9de9242007-10-20 13:33:56 +020097 if (rp->status)
98 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -070099
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200100 hci_dev_lock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700101
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200102 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
103 if (conn) {
104 if (rp->role)
105 conn->link_mode &= ~HCI_LM_MASTER;
106 else
107 conn->link_mode |= HCI_LM_MASTER;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200109
110 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700111}
112
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200113static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
114{
115 struct hci_rp_read_link_policy *rp = (void *) skb->data;
116 struct hci_conn *conn;
117
118 BT_DBG("%s status 0x%x", hdev->name, rp->status);
119
120 if (rp->status)
121 return;
122
123 hci_dev_lock(hdev);
124
125 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
126 if (conn)
127 conn->link_policy = __le16_to_cpu(rp->policy);
128
129 hci_dev_unlock(hdev);
130}
131
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200132static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200134 struct hci_rp_write_link_policy *rp = (void *) skb->data;
135 struct hci_conn *conn;
136 void *sent;
137
138 BT_DBG("%s status 0x%x", hdev->name, rp->status);
139
140 if (rp->status)
141 return;
142
143 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LINK_POLICY);
144 if (!sent)
145 return;
146
147 hci_dev_lock(hdev);
148
149 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle));
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200150 if (conn)
Harvey Harrison83985312008-05-02 16:25:46 -0700151 conn->link_policy = get_unaligned_le16(sent + 2);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200152
153 hci_dev_unlock(hdev);
154}
155
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200156static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
157{
158 struct hci_rp_read_def_link_policy *rp = (void *) skb->data;
159
160 BT_DBG("%s status 0x%x", hdev->name, rp->status);
161
162 if (rp->status)
163 return;
164
165 hdev->link_policy = __le16_to_cpu(rp->policy);
166}
167
168static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb)
169{
170 __u8 status = *((__u8 *) skb->data);
171 void *sent;
172
173 BT_DBG("%s status 0x%x", hdev->name, status);
174
175 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY);
176 if (!sent)
177 return;
178
179 if (!status)
180 hdev->link_policy = get_unaligned_le16(sent);
181
182 hci_req_complete(hdev, status);
183}
184
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200185static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb)
186{
187 __u8 status = *((__u8 *) skb->data);
188
189 BT_DBG("%s status 0x%x", hdev->name, status);
190
191 hci_req_complete(hdev, status);
192}
193
194static void hci_cc_write_local_name(struct hci_dev *hdev, struct sk_buff *skb)
195{
196 __u8 status = *((__u8 *) skb->data);
197 void *sent;
198
199 BT_DBG("%s status 0x%x", hdev->name, status);
200
201 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
202 if (!sent)
203 return;
204
205 if (!status)
206 memcpy(hdev->dev_name, sent, 248);
207}
208
209static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
210{
211 struct hci_rp_read_local_name *rp = (void *) skb->data;
212
213 BT_DBG("%s status 0x%x", hdev->name, rp->status);
214
215 if (rp->status)
216 return;
217
218 memcpy(hdev->dev_name, rp->name, 248);
219}
220
221static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
222{
223 __u8 status = *((__u8 *) skb->data);
224 void *sent;
225
226 BT_DBG("%s status 0x%x", hdev->name, status);
227
228 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
229 if (!sent)
230 return;
231
232 if (!status) {
233 __u8 param = *((__u8 *) sent);
234
235 if (param == AUTH_ENABLED)
236 set_bit(HCI_AUTH, &hdev->flags);
237 else
238 clear_bit(HCI_AUTH, &hdev->flags);
239 }
240
241 hci_req_complete(hdev, status);
242}
243
244static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
245{
246 __u8 status = *((__u8 *) skb->data);
247 void *sent;
248
249 BT_DBG("%s status 0x%x", hdev->name, status);
250
251 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
252 if (!sent)
253 return;
254
255 if (!status) {
256 __u8 param = *((__u8 *) sent);
257
258 if (param)
259 set_bit(HCI_ENCRYPT, &hdev->flags);
260 else
261 clear_bit(HCI_ENCRYPT, &hdev->flags);
262 }
263
264 hci_req_complete(hdev, status);
265}
266
267static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
268{
269 __u8 status = *((__u8 *) skb->data);
270 void *sent;
271
272 BT_DBG("%s status 0x%x", hdev->name, status);
273
274 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
275 if (!sent)
276 return;
277
278 if (!status) {
279 __u8 param = *((__u8 *) sent);
280
281 clear_bit(HCI_PSCAN, &hdev->flags);
282 clear_bit(HCI_ISCAN, &hdev->flags);
283
284 if (param & SCAN_INQUIRY)
285 set_bit(HCI_ISCAN, &hdev->flags);
286
287 if (param & SCAN_PAGE)
288 set_bit(HCI_PSCAN, &hdev->flags);
289 }
290
291 hci_req_complete(hdev, status);
292}
293
294static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
295{
296 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
297
298 BT_DBG("%s status 0x%x", hdev->name, rp->status);
299
300 if (rp->status)
301 return;
302
303 memcpy(hdev->dev_class, rp->dev_class, 3);
304
305 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
306 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
307}
308
309static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
310{
311 __u8 status = *((__u8 *) skb->data);
312 void *sent;
313
314 BT_DBG("%s status 0x%x", hdev->name, status);
315
316 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
317 if (!sent)
318 return;
319
320 if (!status)
321 memcpy(hdev->dev_class, sent, 3);
322}
323
324static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
325{
326 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700327 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200328
329 BT_DBG("%s status 0x%x", hdev->name, rp->status);
330
331 if (rp->status)
332 return;
333
334 setting = __le16_to_cpu(rp->voice_setting);
335
336 if (hdev->voice_setting == setting )
337 return;
338
339 hdev->voice_setting = setting;
340
341 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
342
343 if (hdev->notify) {
344 tasklet_disable(&hdev->tx_task);
345 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
346 tasklet_enable(&hdev->tx_task);
347 }
348}
349
350static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
351{
352 __u8 status = *((__u8 *) skb->data);
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 Holtmanna9de9242007-10-20 13:33:56 +0200357 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
358 if (!sent)
359 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200361 if (!status) {
Harvey Harrison83985312008-05-02 16:25:46 -0700362 __u16 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200364 if (hdev->voice_setting != setting) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 hdev->voice_setting = setting;
366
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200367 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368
369 if (hdev->notify) {
370 tasklet_disable(&hdev->tx_task);
371 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
372 tasklet_enable(&hdev->tx_task);
373 }
374 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375 }
376}
377
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200378static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700379{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200380 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700381
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200382 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700383
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200384 hci_req_complete(hdev, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385}
386
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200387static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
388{
389 struct hci_rp_read_local_version *rp = (void *) skb->data;
390
391 BT_DBG("%s status 0x%x", hdev->name, rp->status);
392
393 if (rp->status)
394 return;
395
396 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200397 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
398 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200399
400 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
401 hdev->manufacturer,
402 hdev->hci_ver, hdev->hci_rev);
403}
404
405static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
406{
407 struct hci_rp_read_local_commands *rp = (void *) skb->data;
408
409 BT_DBG("%s status 0x%x", hdev->name, rp->status);
410
411 if (rp->status)
412 return;
413
414 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
415}
416
417static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
418{
419 struct hci_rp_read_local_features *rp = (void *) skb->data;
420
421 BT_DBG("%s status 0x%x", hdev->name, rp->status);
422
423 if (rp->status)
424 return;
425
426 memcpy(hdev->features, rp->features, 8);
427
428 /* Adjust default settings according to features
429 * supported by device. */
430
431 if (hdev->features[0] & LMP_3SLOT)
432 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
433
434 if (hdev->features[0] & LMP_5SLOT)
435 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
436
437 if (hdev->features[1] & LMP_HV2) {
438 hdev->pkt_type |= (HCI_HV2);
439 hdev->esco_type |= (ESCO_HV2);
440 }
441
442 if (hdev->features[1] & LMP_HV3) {
443 hdev->pkt_type |= (HCI_HV3);
444 hdev->esco_type |= (ESCO_HV3);
445 }
446
447 if (hdev->features[3] & LMP_ESCO)
448 hdev->esco_type |= (ESCO_EV3);
449
450 if (hdev->features[4] & LMP_EV4)
451 hdev->esco_type |= (ESCO_EV4);
452
453 if (hdev->features[4] & LMP_EV5)
454 hdev->esco_type |= (ESCO_EV5);
455
456 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
457 hdev->features[0], hdev->features[1],
458 hdev->features[2], hdev->features[3],
459 hdev->features[4], hdev->features[5],
460 hdev->features[6], hdev->features[7]);
461}
462
463static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
464{
465 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
466
467 BT_DBG("%s status 0x%x", hdev->name, rp->status);
468
469 if (rp->status)
470 return;
471
472 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
473 hdev->sco_mtu = rp->sco_mtu;
474 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
475 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
476
477 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
478 hdev->sco_mtu = 64;
479 hdev->sco_pkts = 8;
480 }
481
482 hdev->acl_cnt = hdev->acl_pkts;
483 hdev->sco_cnt = hdev->sco_pkts;
484
485 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
486 hdev->acl_mtu, hdev->acl_pkts,
487 hdev->sco_mtu, hdev->sco_pkts);
488}
489
490static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
491{
492 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
493
494 BT_DBG("%s status 0x%x", hdev->name, rp->status);
495
496 if (!rp->status)
497 bacpy(&hdev->bdaddr, &rp->bdaddr);
498
499 hci_req_complete(hdev, rp->status);
500}
501
502static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
503{
504 BT_DBG("%s status 0x%x", hdev->name, status);
505
506 if (status) {
507 hci_req_complete(hdev, status);
508
509 hci_conn_check_pending(hdev);
510 } else
511 set_bit(HCI_INQUIRY, &hdev->flags);
512}
513
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
515{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200516 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700518
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200519 BT_DBG("%s status 0x%x", hdev->name, status);
520
521 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522 if (!cp)
523 return;
524
525 hci_dev_lock(hdev);
526
527 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
528
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200529 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530
531 if (status) {
532 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +0200533 if (status != 0x0c || conn->attempt > 2) {
534 conn->state = BT_CLOSED;
535 hci_proto_connect_cfm(conn, status);
536 hci_conn_del(conn);
537 } else
538 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700539 }
540 } else {
541 if (!conn) {
542 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
543 if (conn) {
544 conn->out = 1;
545 conn->link_mode |= HCI_LM_MASTER;
546 } else
547 BT_ERR("No memmory for new connection");
548 }
549 }
550
551 hci_dev_unlock(hdev);
552}
553
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200554static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200556 struct hci_cp_add_sco *cp;
557 struct hci_conn *acl, *sco;
558 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200560 BT_DBG("%s status 0x%x", hdev->name, status);
561
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200562 if (!status)
563 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200565 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
566 if (!cp)
567 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200569 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700570
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200571 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100572
573 hci_dev_lock(hdev);
574
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200575 acl = hci_conn_hash_lookup_handle(hdev, handle);
576 if (acl && (sco = acl->link)) {
577 sco->state = BT_CLOSED;
578
579 hci_proto_connect_cfm(sco, status);
580 hci_conn_del(sco);
581 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100582
583 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584}
585
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200586static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
587{
588 BT_DBG("%s status 0x%x", hdev->name, status);
589}
590
591static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
592{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200593 struct hci_cp_setup_sync_conn *cp;
594 struct hci_conn *acl, *sco;
595 __u16 handle;
596
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200597 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200598
599 if (!status)
600 return;
601
602 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
603 if (!cp)
604 return;
605
606 handle = __le16_to_cpu(cp->handle);
607
608 BT_DBG("%s handle %d", hdev->name, handle);
609
610 hci_dev_lock(hdev);
611
612 acl = hci_conn_hash_lookup_handle(hdev, handle);
613 if (acl && (sco = acl->link)) {
614 sco->state = BT_CLOSED;
615
616 hci_proto_connect_cfm(sco, status);
617 hci_conn_del(sco);
618 }
619
620 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200621}
622
623static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
624{
625 struct hci_cp_sniff_mode *cp;
626 struct hci_conn *conn;
627
628 BT_DBG("%s status 0x%x", hdev->name, status);
629
630 if (!status)
631 return;
632
633 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
634 if (!cp)
635 return;
636
637 hci_dev_lock(hdev);
638
639 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
640 if (conn)
641 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
642
643 hci_dev_unlock(hdev);
644}
645
646static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
647{
648 struct hci_cp_exit_sniff_mode *cp;
649 struct hci_conn *conn;
650
651 BT_DBG("%s status 0x%x", hdev->name, status);
652
653 if (!status)
654 return;
655
656 cp = hci_sent_cmd_data(hdev, HCI_OP_EXIT_SNIFF_MODE);
657 if (!cp)
658 return;
659
660 hci_dev_lock(hdev);
661
662 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
663 if (conn)
664 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
665
666 hci_dev_unlock(hdev);
667}
668
669static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
670{
671 __u8 status = *((__u8 *) skb->data);
672
673 BT_DBG("%s status %d", hdev->name, status);
674
675 clear_bit(HCI_INQUIRY, &hdev->flags);
676
677 hci_req_complete(hdev, status);
678
679 hci_conn_check_pending(hdev);
680}
681
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
683{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700684 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200685 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 int num_rsp = *((__u8 *) skb->data);
687
688 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
689
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700690 if (!num_rsp)
691 return;
692
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700694
Linus Torvalds1da177e2005-04-16 15:20:36 -0700695 for (; num_rsp; num_rsp--) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700696 bacpy(&data.bdaddr, &info->bdaddr);
697 data.pscan_rep_mode = info->pscan_rep_mode;
698 data.pscan_period_mode = info->pscan_period_mode;
699 data.pscan_mode = info->pscan_mode;
700 memcpy(data.dev_class, info->dev_class, 3);
701 data.clock_offset = info->clock_offset;
702 data.rssi = 0x00;
703 info++;
704 hci_inquiry_cache_update(hdev, &data);
705 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700706
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 hci_dev_unlock(hdev);
708}
709
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200710static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200712 struct hci_ev_conn_complete *ev = (void *) skb->data;
713 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200715 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700716
Linus Torvalds1da177e2005-04-16 15:20:36 -0700717 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700718
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200719 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
720 if (!conn)
721 goto unlock;
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700722
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200723 if (!ev->status) {
724 conn->handle = __le16_to_cpu(ev->handle);
725 conn->state = BT_CONNECTED;
726
727 if (test_bit(HCI_AUTH, &hdev->flags))
728 conn->link_mode |= HCI_LM_AUTH;
729
730 if (test_bit(HCI_ENCRYPT, &hdev->flags))
731 conn->link_mode |= HCI_LM_ENCRYPT;
732
733 /* Get remote features */
734 if (conn->type == ACL_LINK) {
735 struct hci_cp_read_remote_features cp;
736 cp.handle = ev->handle;
737 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700738 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700739
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200740 /* Set packet type for incoming connection */
Marcel Holtmanna8746412008-07-14 20:13:46 +0200741 if (!conn->out && hdev->hci_ver < 3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200742 struct hci_cp_change_conn_ptype cp;
743 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +0200744 cp.pkt_type = cpu_to_le16(conn->pkt_type);
745 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
746 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200747 } else {
748 /* Update disconnect timer */
749 hci_conn_hold(conn);
750 hci_conn_put(conn);
751 }
752 } else
753 conn->state = BT_CLOSED;
754
755 if (conn->type == ACL_LINK) {
756 struct hci_conn *sco = conn->link;
757 if (sco) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200758 if (!ev->status) {
759 if (lmp_esco_capable(hdev))
760 hci_setup_sync(sco, conn->handle);
761 else
762 hci_add_sco(sco, conn->handle);
763 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200764 hci_proto_connect_cfm(sco, ev->status);
765 hci_conn_del(sco);
766 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700767 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700769
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200770 hci_proto_connect_cfm(conn, ev->status);
771 if (ev->status)
772 hci_conn_del(conn);
773
774unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200776
777 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700778}
779
Linus Torvalds1da177e2005-04-16 15:20:36 -0700780static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
781{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200782 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700783 int mask = hdev->link_mode;
784
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200785 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
786 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787
788 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
789
790 if (mask & HCI_LM_ACCEPT) {
791 /* Connection accepted */
792 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700793
794 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200795
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
797 if (!conn) {
798 if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
799 BT_ERR("No memmory for new connection");
800 hci_dev_unlock(hdev);
801 return;
802 }
803 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200804
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 memcpy(conn->dev_class, ev->dev_class, 3);
806 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200807
Linus Torvalds1da177e2005-04-16 15:20:36 -0700808 hci_dev_unlock(hdev);
809
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200810 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
811 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200813 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700814
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200815 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
816 cp.role = 0x00; /* Become master */
817 else
818 cp.role = 0x01; /* Remain slave */
819
820 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
821 sizeof(cp), &cp);
822 } else {
823 struct hci_cp_accept_sync_conn_req cp;
824
825 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +0200826 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200827
828 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
829 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
830 cp.max_latency = cpu_to_le16(0xffff);
831 cp.content_format = cpu_to_le16(hdev->voice_setting);
832 cp.retrans_effort = 0xff;
833
834 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
835 sizeof(cp), &cp);
836 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837 } else {
838 /* Connection rejected */
839 struct hci_cp_reject_conn_req cp;
840
841 bacpy(&cp.bdaddr, &ev->bdaddr);
842 cp.reason = 0x0f;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200843 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844 }
845}
846
Linus Torvalds1da177e2005-04-16 15:20:36 -0700847static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
848{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200849 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +0200850 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851
852 BT_DBG("%s status %d", hdev->name, ev->status);
853
854 if (ev->status)
855 return;
856
857 hci_dev_lock(hdev);
858
Marcel Holtmann04837f62006-07-03 10:02:33 +0200859 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860 if (conn) {
861 conn->state = BT_CLOSED;
862 hci_proto_disconn_ind(conn, ev->reason);
863 hci_conn_del(conn);
864 }
865
866 hci_dev_unlock(hdev);
867}
868
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200869static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
870{
871 struct hci_ev_auth_complete *ev = (void *) skb->data;
872 struct hci_conn *conn;
873
874 BT_DBG("%s status %d", hdev->name, ev->status);
875
876 hci_dev_lock(hdev);
877
878 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
879 if (conn) {
880 if (!ev->status)
881 conn->link_mode |= HCI_LM_AUTH;
882
883 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
884
885 hci_auth_cfm(conn, ev->status);
886
887 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
888 if (!ev->status) {
889 struct hci_cp_set_conn_encrypt cp;
890 cp.handle = cpu_to_le16(conn->handle);
891 cp.encrypt = 1;
892 hci_send_cmd(conn->hdev,
893 HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp);
894 } else {
895 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
896 hci_encrypt_cfm(conn, ev->status, 0x00);
897 }
898 }
899 }
900
901 hci_dev_unlock(hdev);
902}
903
904static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
905{
906 BT_DBG("%s", hdev->name);
907
908 hci_conn_check_pending(hdev);
909}
910
911static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
912{
913 struct hci_ev_encrypt_change *ev = (void *) skb->data;
914 struct hci_conn *conn;
915
916 BT_DBG("%s status %d", hdev->name, ev->status);
917
918 hci_dev_lock(hdev);
919
920 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
921 if (conn) {
922 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +0200923 if (ev->encrypt) {
924 /* Encryption implies authentication */
925 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200926 conn->link_mode |= HCI_LM_ENCRYPT;
Marcel Holtmannae293192008-07-14 20:13:45 +0200927 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200928 conn->link_mode &= ~HCI_LM_ENCRYPT;
929 }
930
931 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
932
933 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
934 }
935
936 hci_dev_unlock(hdev);
937}
938
939static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
940{
941 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
942 struct hci_conn *conn;
943
944 BT_DBG("%s status %d", hdev->name, ev->status);
945
946 hci_dev_lock(hdev);
947
948 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
949 if (conn) {
950 if (!ev->status)
951 conn->link_mode |= HCI_LM_SECURE;
952
953 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
954
955 hci_key_change_cfm(conn, ev->status);
956 }
957
958 hci_dev_unlock(hdev);
959}
960
961static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
962{
963 struct hci_ev_remote_features *ev = (void *) skb->data;
964 struct hci_conn *conn;
965
966 BT_DBG("%s status %d", hdev->name, ev->status);
967
968 if (ev->status)
969 return;
970
971 hci_dev_lock(hdev);
972
973 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
974 if (conn)
975 memcpy(conn->features, ev->features, 8);
976
977 hci_dev_unlock(hdev);
978}
979
980static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
981{
982 BT_DBG("%s", hdev->name);
983}
984
985static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
986{
987 BT_DBG("%s", hdev->name);
988}
989
990static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
991{
992 struct hci_ev_cmd_complete *ev = (void *) skb->data;
993 __u16 opcode;
994
995 skb_pull(skb, sizeof(*ev));
996
997 opcode = __le16_to_cpu(ev->opcode);
998
999 switch (opcode) {
1000 case HCI_OP_INQUIRY_CANCEL:
1001 hci_cc_inquiry_cancel(hdev, skb);
1002 break;
1003
1004 case HCI_OP_EXIT_PERIODIC_INQ:
1005 hci_cc_exit_periodic_inq(hdev, skb);
1006 break;
1007
1008 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1009 hci_cc_remote_name_req_cancel(hdev, skb);
1010 break;
1011
1012 case HCI_OP_ROLE_DISCOVERY:
1013 hci_cc_role_discovery(hdev, skb);
1014 break;
1015
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001016 case HCI_OP_READ_LINK_POLICY:
1017 hci_cc_read_link_policy(hdev, skb);
1018 break;
1019
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001020 case HCI_OP_WRITE_LINK_POLICY:
1021 hci_cc_write_link_policy(hdev, skb);
1022 break;
1023
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001024 case HCI_OP_READ_DEF_LINK_POLICY:
1025 hci_cc_read_def_link_policy(hdev, skb);
1026 break;
1027
1028 case HCI_OP_WRITE_DEF_LINK_POLICY:
1029 hci_cc_write_def_link_policy(hdev, skb);
1030 break;
1031
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001032 case HCI_OP_RESET:
1033 hci_cc_reset(hdev, skb);
1034 break;
1035
1036 case HCI_OP_WRITE_LOCAL_NAME:
1037 hci_cc_write_local_name(hdev, skb);
1038 break;
1039
1040 case HCI_OP_READ_LOCAL_NAME:
1041 hci_cc_read_local_name(hdev, skb);
1042 break;
1043
1044 case HCI_OP_WRITE_AUTH_ENABLE:
1045 hci_cc_write_auth_enable(hdev, skb);
1046 break;
1047
1048 case HCI_OP_WRITE_ENCRYPT_MODE:
1049 hci_cc_write_encrypt_mode(hdev, skb);
1050 break;
1051
1052 case HCI_OP_WRITE_SCAN_ENABLE:
1053 hci_cc_write_scan_enable(hdev, skb);
1054 break;
1055
1056 case HCI_OP_READ_CLASS_OF_DEV:
1057 hci_cc_read_class_of_dev(hdev, skb);
1058 break;
1059
1060 case HCI_OP_WRITE_CLASS_OF_DEV:
1061 hci_cc_write_class_of_dev(hdev, skb);
1062 break;
1063
1064 case HCI_OP_READ_VOICE_SETTING:
1065 hci_cc_read_voice_setting(hdev, skb);
1066 break;
1067
1068 case HCI_OP_WRITE_VOICE_SETTING:
1069 hci_cc_write_voice_setting(hdev, skb);
1070 break;
1071
1072 case HCI_OP_HOST_BUFFER_SIZE:
1073 hci_cc_host_buffer_size(hdev, skb);
1074 break;
1075
1076 case HCI_OP_READ_LOCAL_VERSION:
1077 hci_cc_read_local_version(hdev, skb);
1078 break;
1079
1080 case HCI_OP_READ_LOCAL_COMMANDS:
1081 hci_cc_read_local_commands(hdev, skb);
1082 break;
1083
1084 case HCI_OP_READ_LOCAL_FEATURES:
1085 hci_cc_read_local_features(hdev, skb);
1086 break;
1087
1088 case HCI_OP_READ_BUFFER_SIZE:
1089 hci_cc_read_buffer_size(hdev, skb);
1090 break;
1091
1092 case HCI_OP_READ_BD_ADDR:
1093 hci_cc_read_bd_addr(hdev, skb);
1094 break;
1095
1096 default:
1097 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1098 break;
1099 }
1100
1101 if (ev->ncmd) {
1102 atomic_set(&hdev->cmd_cnt, 1);
1103 if (!skb_queue_empty(&hdev->cmd_q))
1104 hci_sched_cmd(hdev);
1105 }
1106}
1107
1108static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
1109{
1110 struct hci_ev_cmd_status *ev = (void *) skb->data;
1111 __u16 opcode;
1112
1113 skb_pull(skb, sizeof(*ev));
1114
1115 opcode = __le16_to_cpu(ev->opcode);
1116
1117 switch (opcode) {
1118 case HCI_OP_INQUIRY:
1119 hci_cs_inquiry(hdev, ev->status);
1120 break;
1121
1122 case HCI_OP_CREATE_CONN:
1123 hci_cs_create_conn(hdev, ev->status);
1124 break;
1125
1126 case HCI_OP_ADD_SCO:
1127 hci_cs_add_sco(hdev, ev->status);
1128 break;
1129
1130 case HCI_OP_REMOTE_NAME_REQ:
1131 hci_cs_remote_name_req(hdev, ev->status);
1132 break;
1133
1134 case HCI_OP_SETUP_SYNC_CONN:
1135 hci_cs_setup_sync_conn(hdev, ev->status);
1136 break;
1137
1138 case HCI_OP_SNIFF_MODE:
1139 hci_cs_sniff_mode(hdev, ev->status);
1140 break;
1141
1142 case HCI_OP_EXIT_SNIFF_MODE:
1143 hci_cs_exit_sniff_mode(hdev, ev->status);
1144 break;
1145
1146 default:
1147 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1148 break;
1149 }
1150
1151 if (ev->ncmd) {
1152 atomic_set(&hdev->cmd_cnt, 1);
1153 if (!skb_queue_empty(&hdev->cmd_q))
1154 hci_sched_cmd(hdev);
1155 }
1156}
1157
1158static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1159{
1160 struct hci_ev_role_change *ev = (void *) skb->data;
1161 struct hci_conn *conn;
1162
1163 BT_DBG("%s status %d", hdev->name, ev->status);
1164
1165 hci_dev_lock(hdev);
1166
1167 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1168 if (conn) {
1169 if (!ev->status) {
1170 if (ev->role)
1171 conn->link_mode &= ~HCI_LM_MASTER;
1172 else
1173 conn->link_mode |= HCI_LM_MASTER;
1174 }
1175
1176 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
1177
1178 hci_role_switch_cfm(conn, ev->status, ev->role);
1179 }
1180
1181 hci_dev_unlock(hdev);
1182}
1183
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
1185{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001186 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001187 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001188 int i;
1189
1190 skb_pull(skb, sizeof(*ev));
1191
1192 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
1193
1194 if (skb->len < ev->num_hndl * 4) {
1195 BT_DBG("%s bad parameters", hdev->name);
1196 return;
1197 }
1198
1199 tasklet_disable(&hdev->tx_task);
1200
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001201 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001202 struct hci_conn *conn;
1203 __u16 handle, count;
1204
Harvey Harrison83985312008-05-02 16:25:46 -07001205 handle = get_unaligned_le16(ptr++);
1206 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001207
1208 conn = hci_conn_hash_lookup_handle(hdev, handle);
1209 if (conn) {
1210 conn->sent -= count;
1211
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001212 if (conn->type == ACL_LINK) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 if ((hdev->acl_cnt += count) > hdev->acl_pkts)
1214 hdev->acl_cnt = hdev->acl_pkts;
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001215 } else {
1216 if ((hdev->sco_cnt += count) > hdev->sco_pkts)
1217 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 }
1219 }
1220 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001221
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 hci_sched_tx(hdev);
1223
1224 tasklet_enable(&hdev->tx_task);
1225}
1226
Marcel Holtmann04837f62006-07-03 10:02:33 +02001227static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001228{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001229 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001230 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231
1232 BT_DBG("%s status %d", hdev->name, ev->status);
1233
1234 hci_dev_lock(hdev);
1235
Marcel Holtmann04837f62006-07-03 10:02:33 +02001236 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1237 if (conn) {
1238 conn->mode = ev->mode;
1239 conn->interval = __le16_to_cpu(ev->interval);
1240
1241 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
1242 if (conn->mode == HCI_CM_ACTIVE)
1243 conn->power_save = 1;
1244 else
1245 conn->power_save = 0;
1246 }
1247 }
1248
1249 hci_dev_unlock(hdev);
1250}
1251
Linus Torvalds1da177e2005-04-16 15:20:36 -07001252static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1253{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001254 BT_DBG("%s", hdev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001255}
1256
Linus Torvalds1da177e2005-04-16 15:20:36 -07001257static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1258{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001259 BT_DBG("%s", hdev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260}
1261
Linus Torvalds1da177e2005-04-16 15:20:36 -07001262static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
1263{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001264 BT_DBG("%s", hdev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001265}
1266
Marcel Holtmann04837f62006-07-03 10:02:33 +02001267static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
1268{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001269 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001270 struct hci_conn *conn;
1271
1272 BT_DBG("%s status %d", hdev->name, ev->status);
1273
1274 hci_dev_lock(hdev);
1275
1276 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001277 if (conn && !ev->status) {
1278 struct inquiry_entry *ie;
1279
1280 if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) {
1281 ie->data.clock_offset = ev->clock_offset;
1282 ie->timestamp = jiffies;
1283 }
1284 }
1285
1286 hci_dev_unlock(hdev);
1287}
1288
Marcel Holtmanna8746412008-07-14 20:13:46 +02001289static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1290{
1291 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
1292 struct hci_conn *conn;
1293
1294 BT_DBG("%s status %d", hdev->name, ev->status);
1295
1296 hci_dev_lock(hdev);
1297
1298 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1299 if (conn && !ev->status)
1300 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
1301
1302 hci_dev_unlock(hdev);
1303}
1304
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001305static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
1306{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001307 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001308 struct inquiry_entry *ie;
1309
1310 BT_DBG("%s", hdev->name);
1311
1312 hci_dev_lock(hdev);
1313
1314 if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) {
1315 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
1316 ie->timestamp = jiffies;
1317 }
1318
1319 hci_dev_unlock(hdev);
1320}
1321
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001322static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
1323{
1324 struct inquiry_data data;
1325 int num_rsp = *((__u8 *) skb->data);
1326
1327 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1328
1329 if (!num_rsp)
1330 return;
1331
1332 hci_dev_lock(hdev);
1333
1334 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
1335 struct inquiry_info_with_rssi_and_pscan_mode *info = (void *) (skb->data + 1);
1336
1337 for (; num_rsp; num_rsp--) {
1338 bacpy(&data.bdaddr, &info->bdaddr);
1339 data.pscan_rep_mode = info->pscan_rep_mode;
1340 data.pscan_period_mode = info->pscan_period_mode;
1341 data.pscan_mode = info->pscan_mode;
1342 memcpy(data.dev_class, info->dev_class, 3);
1343 data.clock_offset = info->clock_offset;
1344 data.rssi = info->rssi;
1345 info++;
1346 hci_inquiry_cache_update(hdev, &data);
1347 }
1348 } else {
1349 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
1350
1351 for (; num_rsp; num_rsp--) {
1352 bacpy(&data.bdaddr, &info->bdaddr);
1353 data.pscan_rep_mode = info->pscan_rep_mode;
1354 data.pscan_period_mode = info->pscan_period_mode;
1355 data.pscan_mode = 0x00;
1356 memcpy(data.dev_class, info->dev_class, 3);
1357 data.clock_offset = info->clock_offset;
1358 data.rssi = info->rssi;
1359 info++;
1360 hci_inquiry_cache_update(hdev, &data);
1361 }
1362 }
1363
1364 hci_dev_unlock(hdev);
1365}
1366
1367static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1368{
1369 BT_DBG("%s", hdev->name);
1370}
1371
1372static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1373{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001374 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
1375 struct hci_conn *conn;
1376
1377 BT_DBG("%s status %d", hdev->name, ev->status);
1378
1379 hci_dev_lock(hdev);
1380
1381 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02001382 if (!conn) {
1383 if (ev->link_type == ESCO_LINK)
1384 goto unlock;
1385
1386 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1387 if (!conn)
1388 goto unlock;
1389
1390 conn->type = SCO_LINK;
1391 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001392
1393 if (!ev->status) {
1394 conn->handle = __le16_to_cpu(ev->handle);
1395 conn->state = BT_CONNECTED;
1396 } else
1397 conn->state = BT_CLOSED;
1398
1399 hci_proto_connect_cfm(conn, ev->status);
1400 if (ev->status)
1401 hci_conn_del(conn);
1402
1403unlock:
1404 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001405}
1406
1407static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
1408{
1409 BT_DBG("%s", hdev->name);
1410}
1411
Marcel Holtmann04837f62006-07-03 10:02:33 +02001412static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
1413{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001414 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001415 struct hci_conn *conn;
1416
1417 BT_DBG("%s status %d", hdev->name, ev->status);
1418
1419 hci_dev_lock(hdev);
1420
1421 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1422 if (conn) {
1423 }
1424
1425 hci_dev_unlock(hdev);
1426}
1427
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001428static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1429{
1430 struct inquiry_data data;
1431 struct extended_inquiry_info *info = (void *) (skb->data + 1);
1432 int num_rsp = *((__u8 *) skb->data);
1433
1434 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1435
1436 if (!num_rsp)
1437 return;
1438
1439 hci_dev_lock(hdev);
1440
1441 for (; num_rsp; num_rsp--) {
1442 bacpy(&data.bdaddr, &info->bdaddr);
1443 data.pscan_rep_mode = info->pscan_rep_mode;
1444 data.pscan_period_mode = info->pscan_period_mode;
1445 data.pscan_mode = 0x00;
1446 memcpy(data.dev_class, info->dev_class, 3);
1447 data.clock_offset = info->clock_offset;
1448 data.rssi = info->rssi;
1449 info++;
1450 hci_inquiry_cache_update(hdev, &data);
1451 }
1452
1453 hci_dev_unlock(hdev);
1454}
1455
Linus Torvalds1da177e2005-04-16 15:20:36 -07001456void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
1457{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001458 struct hci_event_hdr *hdr = (void *) skb->data;
1459 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001460
1461 skb_pull(skb, HCI_EVENT_HDR_SIZE);
1462
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001463 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001464 case HCI_EV_INQUIRY_COMPLETE:
1465 hci_inquiry_complete_evt(hdev, skb);
1466 break;
1467
1468 case HCI_EV_INQUIRY_RESULT:
1469 hci_inquiry_result_evt(hdev, skb);
1470 break;
1471
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001472 case HCI_EV_CONN_COMPLETE:
1473 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02001474 break;
1475
Linus Torvalds1da177e2005-04-16 15:20:36 -07001476 case HCI_EV_CONN_REQUEST:
1477 hci_conn_request_evt(hdev, skb);
1478 break;
1479
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480 case HCI_EV_DISCONN_COMPLETE:
1481 hci_disconn_complete_evt(hdev, skb);
1482 break;
1483
Linus Torvalds1da177e2005-04-16 15:20:36 -07001484 case HCI_EV_AUTH_COMPLETE:
1485 hci_auth_complete_evt(hdev, skb);
1486 break;
1487
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001488 case HCI_EV_REMOTE_NAME:
1489 hci_remote_name_evt(hdev, skb);
1490 break;
1491
Linus Torvalds1da177e2005-04-16 15:20:36 -07001492 case HCI_EV_ENCRYPT_CHANGE:
1493 hci_encrypt_change_evt(hdev, skb);
1494 break;
1495
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001496 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
1497 hci_change_link_key_complete_evt(hdev, skb);
1498 break;
1499
1500 case HCI_EV_REMOTE_FEATURES:
1501 hci_remote_features_evt(hdev, skb);
1502 break;
1503
1504 case HCI_EV_REMOTE_VERSION:
1505 hci_remote_version_evt(hdev, skb);
1506 break;
1507
1508 case HCI_EV_QOS_SETUP_COMPLETE:
1509 hci_qos_setup_complete_evt(hdev, skb);
1510 break;
1511
1512 case HCI_EV_CMD_COMPLETE:
1513 hci_cmd_complete_evt(hdev, skb);
1514 break;
1515
1516 case HCI_EV_CMD_STATUS:
1517 hci_cmd_status_evt(hdev, skb);
1518 break;
1519
1520 case HCI_EV_ROLE_CHANGE:
1521 hci_role_change_evt(hdev, skb);
1522 break;
1523
1524 case HCI_EV_NUM_COMP_PKTS:
1525 hci_num_comp_pkts_evt(hdev, skb);
1526 break;
1527
1528 case HCI_EV_MODE_CHANGE:
1529 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001530 break;
1531
1532 case HCI_EV_PIN_CODE_REQ:
1533 hci_pin_code_request_evt(hdev, skb);
1534 break;
1535
1536 case HCI_EV_LINK_KEY_REQ:
1537 hci_link_key_request_evt(hdev, skb);
1538 break;
1539
1540 case HCI_EV_LINK_KEY_NOTIFY:
1541 hci_link_key_notify_evt(hdev, skb);
1542 break;
1543
1544 case HCI_EV_CLOCK_OFFSET:
1545 hci_clock_offset_evt(hdev, skb);
1546 break;
1547
Marcel Holtmanna8746412008-07-14 20:13:46 +02001548 case HCI_EV_PKT_TYPE_CHANGE:
1549 hci_pkt_type_change_evt(hdev, skb);
1550 break;
1551
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001552 case HCI_EV_PSCAN_REP_MODE:
1553 hci_pscan_rep_mode_evt(hdev, skb);
1554 break;
1555
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001556 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
1557 hci_inquiry_result_with_rssi_evt(hdev, skb);
1558 break;
1559
1560 case HCI_EV_REMOTE_EXT_FEATURES:
1561 hci_remote_ext_features_evt(hdev, skb);
1562 break;
1563
1564 case HCI_EV_SYNC_CONN_COMPLETE:
1565 hci_sync_conn_complete_evt(hdev, skb);
1566 break;
1567
1568 case HCI_EV_SYNC_CONN_CHANGED:
1569 hci_sync_conn_changed_evt(hdev, skb);
1570 break;
1571
Marcel Holtmann04837f62006-07-03 10:02:33 +02001572 case HCI_EV_SNIFF_SUBRATE:
1573 hci_sniff_subrate_evt(hdev, skb);
1574 break;
1575
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001576 case HCI_EV_EXTENDED_INQUIRY_RESULT:
1577 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578 break;
1579
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001580 default:
1581 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582 break;
1583 }
1584
1585 kfree_skb(skb);
1586 hdev->stat.evt_rx++;
1587}
1588
1589/* Generate internal stack event */
1590void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
1591{
1592 struct hci_event_hdr *hdr;
1593 struct hci_ev_stack_internal *ev;
1594 struct sk_buff *skb;
1595
1596 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
1597 if (!skb)
1598 return;
1599
1600 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
1601 hdr->evt = HCI_EV_STACK_INTERNAL;
1602 hdr->plen = sizeof(*ev) + dlen;
1603
1604 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
1605 ev->type = type;
1606 memcpy(ev->data, data, dlen);
1607
Marcel Holtmann576c7d82005-08-06 12:36:54 +02001608 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07001609 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02001610
Marcel Holtmann0d48d932005-08-09 20:30:28 -07001611 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001612 skb->dev = (void *) hdev;
1613 hci_send_to_sock(hdev, skb);
1614 kfree_skb(skb);
1615}