blob: bf3fbf9817b4324b2df9eccc562037128ea414d0 [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
Marcel Holtmannf383f272008-07-14 20:13:47 +0200201 if (status)
202 return;
203
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200204 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_LOCAL_NAME);
205 if (!sent)
206 return;
207
Marcel Holtmannf383f272008-07-14 20:13:47 +0200208 memcpy(hdev->dev_name, sent, 248);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200209}
210
211static void hci_cc_read_local_name(struct hci_dev *hdev, struct sk_buff *skb)
212{
213 struct hci_rp_read_local_name *rp = (void *) skb->data;
214
215 BT_DBG("%s status 0x%x", hdev->name, rp->status);
216
217 if (rp->status)
218 return;
219
220 memcpy(hdev->dev_name, rp->name, 248);
221}
222
223static void hci_cc_write_auth_enable(struct hci_dev *hdev, struct sk_buff *skb)
224{
225 __u8 status = *((__u8 *) skb->data);
226 void *sent;
227
228 BT_DBG("%s status 0x%x", hdev->name, status);
229
230 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_AUTH_ENABLE);
231 if (!sent)
232 return;
233
234 if (!status) {
235 __u8 param = *((__u8 *) sent);
236
237 if (param == AUTH_ENABLED)
238 set_bit(HCI_AUTH, &hdev->flags);
239 else
240 clear_bit(HCI_AUTH, &hdev->flags);
241 }
242
243 hci_req_complete(hdev, status);
244}
245
246static void hci_cc_write_encrypt_mode(struct hci_dev *hdev, struct sk_buff *skb)
247{
248 __u8 status = *((__u8 *) skb->data);
249 void *sent;
250
251 BT_DBG("%s status 0x%x", hdev->name, status);
252
253 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_ENCRYPT_MODE);
254 if (!sent)
255 return;
256
257 if (!status) {
258 __u8 param = *((__u8 *) sent);
259
260 if (param)
261 set_bit(HCI_ENCRYPT, &hdev->flags);
262 else
263 clear_bit(HCI_ENCRYPT, &hdev->flags);
264 }
265
266 hci_req_complete(hdev, status);
267}
268
269static void hci_cc_write_scan_enable(struct hci_dev *hdev, struct sk_buff *skb)
270{
271 __u8 status = *((__u8 *) skb->data);
272 void *sent;
273
274 BT_DBG("%s status 0x%x", hdev->name, status);
275
276 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_SCAN_ENABLE);
277 if (!sent)
278 return;
279
280 if (!status) {
281 __u8 param = *((__u8 *) sent);
282
283 clear_bit(HCI_PSCAN, &hdev->flags);
284 clear_bit(HCI_ISCAN, &hdev->flags);
285
286 if (param & SCAN_INQUIRY)
287 set_bit(HCI_ISCAN, &hdev->flags);
288
289 if (param & SCAN_PAGE)
290 set_bit(HCI_PSCAN, &hdev->flags);
291 }
292
293 hci_req_complete(hdev, status);
294}
295
296static void hci_cc_read_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
297{
298 struct hci_rp_read_class_of_dev *rp = (void *) skb->data;
299
300 BT_DBG("%s status 0x%x", hdev->name, rp->status);
301
302 if (rp->status)
303 return;
304
305 memcpy(hdev->dev_class, rp->dev_class, 3);
306
307 BT_DBG("%s class 0x%.2x%.2x%.2x", hdev->name,
308 hdev->dev_class[2], hdev->dev_class[1], hdev->dev_class[0]);
309}
310
311static void hci_cc_write_class_of_dev(struct hci_dev *hdev, struct sk_buff *skb)
312{
313 __u8 status = *((__u8 *) skb->data);
314 void *sent;
315
316 BT_DBG("%s status 0x%x", hdev->name, status);
317
Marcel Holtmannf383f272008-07-14 20:13:47 +0200318 if (status)
319 return;
320
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200321 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_CLASS_OF_DEV);
322 if (!sent)
323 return;
324
Marcel Holtmannf383f272008-07-14 20:13:47 +0200325 memcpy(hdev->dev_class, sent, 3);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200326}
327
328static void hci_cc_read_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
329{
330 struct hci_rp_read_voice_setting *rp = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700331 __u16 setting;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200332
333 BT_DBG("%s status 0x%x", hdev->name, rp->status);
334
335 if (rp->status)
336 return;
337
338 setting = __le16_to_cpu(rp->voice_setting);
339
Marcel Holtmannf383f272008-07-14 20:13:47 +0200340 if (hdev->voice_setting == setting)
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200341 return;
342
343 hdev->voice_setting = setting;
344
345 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
346
347 if (hdev->notify) {
348 tasklet_disable(&hdev->tx_task);
349 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
350 tasklet_enable(&hdev->tx_task);
351 }
352}
353
354static void hci_cc_write_voice_setting(struct hci_dev *hdev, struct sk_buff *skb)
355{
356 __u8 status = *((__u8 *) skb->data);
Marcel Holtmannf383f272008-07-14 20:13:47 +0200357 __u16 setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700358 void *sent;
359
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200360 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361
Marcel Holtmannf383f272008-07-14 20:13:47 +0200362 if (status)
363 return;
364
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200365 sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_VOICE_SETTING);
366 if (!sent)
367 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700368
Marcel Holtmannf383f272008-07-14 20:13:47 +0200369 setting = get_unaligned_le16(sent);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370
Marcel Holtmannf383f272008-07-14 20:13:47 +0200371 if (hdev->voice_setting == setting)
372 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373
Marcel Holtmannf383f272008-07-14 20:13:47 +0200374 hdev->voice_setting = setting;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700375
Marcel Holtmannf383f272008-07-14 20:13:47 +0200376 BT_DBG("%s voice setting 0x%04x", hdev->name, setting);
377
378 if (hdev->notify) {
379 tasklet_disable(&hdev->tx_task);
380 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
381 tasklet_enable(&hdev->tx_task);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382 }
383}
384
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200385static void hci_cc_host_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200387 __u8 status = *((__u8 *) skb->data);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200389 BT_DBG("%s status 0x%x", hdev->name, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700390
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200391 hci_req_complete(hdev, status);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700392}
393
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200394static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb)
395{
396 struct hci_rp_read_local_version *rp = (void *) skb->data;
397
398 BT_DBG("%s status 0x%x", hdev->name, rp->status);
399
400 if (rp->status)
401 return;
402
403 hdev->hci_ver = rp->hci_ver;
Marcel Holtmanne4e8e372008-07-14 20:13:47 +0200404 hdev->hci_rev = __le16_to_cpu(rp->hci_rev);
405 hdev->manufacturer = __le16_to_cpu(rp->manufacturer);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200406
407 BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name,
408 hdev->manufacturer,
409 hdev->hci_ver, hdev->hci_rev);
410}
411
412static void hci_cc_read_local_commands(struct hci_dev *hdev, struct sk_buff *skb)
413{
414 struct hci_rp_read_local_commands *rp = (void *) skb->data;
415
416 BT_DBG("%s status 0x%x", hdev->name, rp->status);
417
418 if (rp->status)
419 return;
420
421 memcpy(hdev->commands, rp->commands, sizeof(hdev->commands));
422}
423
424static void hci_cc_read_local_features(struct hci_dev *hdev, struct sk_buff *skb)
425{
426 struct hci_rp_read_local_features *rp = (void *) skb->data;
427
428 BT_DBG("%s status 0x%x", hdev->name, rp->status);
429
430 if (rp->status)
431 return;
432
433 memcpy(hdev->features, rp->features, 8);
434
435 /* Adjust default settings according to features
436 * supported by device. */
437
438 if (hdev->features[0] & LMP_3SLOT)
439 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
440
441 if (hdev->features[0] & LMP_5SLOT)
442 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
443
444 if (hdev->features[1] & LMP_HV2) {
445 hdev->pkt_type |= (HCI_HV2);
446 hdev->esco_type |= (ESCO_HV2);
447 }
448
449 if (hdev->features[1] & LMP_HV3) {
450 hdev->pkt_type |= (HCI_HV3);
451 hdev->esco_type |= (ESCO_HV3);
452 }
453
454 if (hdev->features[3] & LMP_ESCO)
455 hdev->esco_type |= (ESCO_EV3);
456
457 if (hdev->features[4] & LMP_EV4)
458 hdev->esco_type |= (ESCO_EV4);
459
460 if (hdev->features[4] & LMP_EV5)
461 hdev->esco_type |= (ESCO_EV5);
462
463 BT_DBG("%s features 0x%.2x%.2x%.2x%.2x%.2x%.2x%.2x%.2x", hdev->name,
464 hdev->features[0], hdev->features[1],
465 hdev->features[2], hdev->features[3],
466 hdev->features[4], hdev->features[5],
467 hdev->features[6], hdev->features[7]);
468}
469
470static void hci_cc_read_buffer_size(struct hci_dev *hdev, struct sk_buff *skb)
471{
472 struct hci_rp_read_buffer_size *rp = (void *) skb->data;
473
474 BT_DBG("%s status 0x%x", hdev->name, rp->status);
475
476 if (rp->status)
477 return;
478
479 hdev->acl_mtu = __le16_to_cpu(rp->acl_mtu);
480 hdev->sco_mtu = rp->sco_mtu;
481 hdev->acl_pkts = __le16_to_cpu(rp->acl_max_pkt);
482 hdev->sco_pkts = __le16_to_cpu(rp->sco_max_pkt);
483
484 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
485 hdev->sco_mtu = 64;
486 hdev->sco_pkts = 8;
487 }
488
489 hdev->acl_cnt = hdev->acl_pkts;
490 hdev->sco_cnt = hdev->sco_pkts;
491
492 BT_DBG("%s acl mtu %d:%d sco mtu %d:%d", hdev->name,
493 hdev->acl_mtu, hdev->acl_pkts,
494 hdev->sco_mtu, hdev->sco_pkts);
495}
496
497static void hci_cc_read_bd_addr(struct hci_dev *hdev, struct sk_buff *skb)
498{
499 struct hci_rp_read_bd_addr *rp = (void *) skb->data;
500
501 BT_DBG("%s status 0x%x", hdev->name, rp->status);
502
503 if (!rp->status)
504 bacpy(&hdev->bdaddr, &rp->bdaddr);
505
506 hci_req_complete(hdev, rp->status);
507}
508
509static inline void hci_cs_inquiry(struct hci_dev *hdev, __u8 status)
510{
511 BT_DBG("%s status 0x%x", hdev->name, status);
512
513 if (status) {
514 hci_req_complete(hdev, status);
515
516 hci_conn_check_pending(hdev);
517 } else
518 set_bit(HCI_INQUIRY, &hdev->flags);
519}
520
Linus Torvalds1da177e2005-04-16 15:20:36 -0700521static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
522{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200523 struct hci_cp_create_conn *cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700524 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700525
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200526 BT_DBG("%s status 0x%x", hdev->name, status);
527
528 cp = hci_sent_cmd_data(hdev, HCI_OP_CREATE_CONN);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 if (!cp)
530 return;
531
532 hci_dev_lock(hdev);
533
534 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
535
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200536 BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&cp->bdaddr), conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537
538 if (status) {
539 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +0200540 if (status != 0x0c || conn->attempt > 2) {
541 conn->state = BT_CLOSED;
542 hci_proto_connect_cfm(conn, status);
543 hci_conn_del(conn);
544 } else
545 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700546 }
547 } else {
548 if (!conn) {
549 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
550 if (conn) {
551 conn->out = 1;
552 conn->link_mode |= HCI_LM_MASTER;
553 } else
554 BT_ERR("No memmory for new connection");
555 }
556 }
557
558 hci_dev_unlock(hdev);
559}
560
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200561static void hci_cs_add_sco(struct hci_dev *hdev, __u8 status)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700562{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200563 struct hci_cp_add_sco *cp;
564 struct hci_conn *acl, *sco;
565 __u16 handle;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200567 BT_DBG("%s status 0x%x", hdev->name, status);
568
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200569 if (!status)
570 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200572 cp = hci_sent_cmd_data(hdev, HCI_OP_ADD_SCO);
573 if (!cp)
574 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700575
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200576 handle = __le16_to_cpu(cp->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700577
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200578 BT_DBG("%s handle %d", hdev->name, handle);
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100579
580 hci_dev_lock(hdev);
581
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200582 acl = hci_conn_hash_lookup_handle(hdev, handle);
583 if (acl && (sco = acl->link)) {
584 sco->state = BT_CLOSED;
585
586 hci_proto_connect_cfm(sco, status);
587 hci_conn_del(sco);
588 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100589
590 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591}
592
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200593static void hci_cs_remote_name_req(struct hci_dev *hdev, __u8 status)
594{
595 BT_DBG("%s status 0x%x", hdev->name, status);
596}
597
598static void hci_cs_setup_sync_conn(struct hci_dev *hdev, __u8 status)
599{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200600 struct hci_cp_setup_sync_conn *cp;
601 struct hci_conn *acl, *sco;
602 __u16 handle;
603
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200604 BT_DBG("%s status 0x%x", hdev->name, status);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200605
606 if (!status)
607 return;
608
609 cp = hci_sent_cmd_data(hdev, HCI_OP_SETUP_SYNC_CONN);
610 if (!cp)
611 return;
612
613 handle = __le16_to_cpu(cp->handle);
614
615 BT_DBG("%s handle %d", hdev->name, handle);
616
617 hci_dev_lock(hdev);
618
619 acl = hci_conn_hash_lookup_handle(hdev, handle);
620 if (acl && (sco = acl->link)) {
621 sco->state = BT_CLOSED;
622
623 hci_proto_connect_cfm(sco, status);
624 hci_conn_del(sco);
625 }
626
627 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200628}
629
630static void hci_cs_sniff_mode(struct hci_dev *hdev, __u8 status)
631{
632 struct hci_cp_sniff_mode *cp;
633 struct hci_conn *conn;
634
635 BT_DBG("%s status 0x%x", hdev->name, status);
636
637 if (!status)
638 return;
639
640 cp = hci_sent_cmd_data(hdev, HCI_OP_SNIFF_MODE);
641 if (!cp)
642 return;
643
644 hci_dev_lock(hdev);
645
646 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
647 if (conn)
648 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
649
650 hci_dev_unlock(hdev);
651}
652
653static void hci_cs_exit_sniff_mode(struct hci_dev *hdev, __u8 status)
654{
655 struct hci_cp_exit_sniff_mode *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_EXIT_SNIFF_MODE);
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 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
672
673 hci_dev_unlock(hdev);
674}
675
676static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
677{
678 __u8 status = *((__u8 *) skb->data);
679
680 BT_DBG("%s status %d", hdev->name, status);
681
682 clear_bit(HCI_INQUIRY, &hdev->flags);
683
684 hci_req_complete(hdev, status);
685
686 hci_conn_check_pending(hdev);
687}
688
Linus Torvalds1da177e2005-04-16 15:20:36 -0700689static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
690{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700691 struct inquiry_data data;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200692 struct inquiry_info *info = (void *) (skb->data + 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693 int num_rsp = *((__u8 *) skb->data);
694
695 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
696
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700697 if (!num_rsp)
698 return;
699
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700701
Linus Torvalds1da177e2005-04-16 15:20:36 -0700702 for (; num_rsp; num_rsp--) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700703 bacpy(&data.bdaddr, &info->bdaddr);
704 data.pscan_rep_mode = info->pscan_rep_mode;
705 data.pscan_period_mode = info->pscan_period_mode;
706 data.pscan_mode = info->pscan_mode;
707 memcpy(data.dev_class, info->dev_class, 3);
708 data.clock_offset = info->clock_offset;
709 data.rssi = 0x00;
710 info++;
711 hci_inquiry_cache_update(hdev, &data);
712 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700713
Linus Torvalds1da177e2005-04-16 15:20:36 -0700714 hci_dev_unlock(hdev);
715}
716
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200717static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200719 struct hci_ev_conn_complete *ev = (void *) skb->data;
720 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700721
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200722 BT_DBG("%s", hdev->name);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700723
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700725
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200726 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
727 if (!conn)
728 goto unlock;
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700729
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200730 if (!ev->status) {
731 conn->handle = __le16_to_cpu(ev->handle);
732 conn->state = BT_CONNECTED;
733
734 if (test_bit(HCI_AUTH, &hdev->flags))
735 conn->link_mode |= HCI_LM_AUTH;
736
737 if (test_bit(HCI_ENCRYPT, &hdev->flags))
738 conn->link_mode |= HCI_LM_ENCRYPT;
739
740 /* Get remote features */
741 if (conn->type == ACL_LINK) {
742 struct hci_cp_read_remote_features cp;
743 cp.handle = ev->handle;
744 hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, sizeof(cp), &cp);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700745 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700746
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200747 /* Set packet type for incoming connection */
Marcel Holtmanna8746412008-07-14 20:13:46 +0200748 if (!conn->out && hdev->hci_ver < 3) {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200749 struct hci_cp_change_conn_ptype cp;
750 cp.handle = ev->handle;
Marcel Holtmanna8746412008-07-14 20:13:46 +0200751 cp.pkt_type = cpu_to_le16(conn->pkt_type);
752 hci_send_cmd(hdev, HCI_OP_CHANGE_CONN_PTYPE,
753 sizeof(cp), &cp);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200754 } else {
755 /* Update disconnect timer */
756 hci_conn_hold(conn);
757 hci_conn_put(conn);
758 }
759 } else
760 conn->state = BT_CLOSED;
761
762 if (conn->type == ACL_LINK) {
763 struct hci_conn *sco = conn->link;
764 if (sco) {
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200765 if (!ev->status) {
766 if (lmp_esco_capable(hdev))
767 hci_setup_sync(sco, conn->handle);
768 else
769 hci_add_sco(sco, conn->handle);
770 } else {
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200771 hci_proto_connect_cfm(sco, ev->status);
772 hci_conn_del(sco);
773 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700774 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700775 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700776
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200777 hci_proto_connect_cfm(conn, ev->status);
778 if (ev->status)
779 hci_conn_del(conn);
780
781unlock:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200783
784 hci_conn_check_pending(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785}
786
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
788{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200789 struct hci_ev_conn_request *ev = (void *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790 int mask = hdev->link_mode;
791
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200792 BT_DBG("%s bdaddr %s type 0x%x", hdev->name,
793 batostr(&ev->bdaddr), ev->link_type);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700794
795 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
796
797 if (mask & HCI_LM_ACCEPT) {
798 /* Connection accepted */
799 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800
801 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200802
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
804 if (!conn) {
805 if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
806 BT_ERR("No memmory for new connection");
807 hci_dev_unlock(hdev);
808 return;
809 }
810 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200811
Linus Torvalds1da177e2005-04-16 15:20:36 -0700812 memcpy(conn->dev_class, ev->dev_class, 3);
813 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200814
Linus Torvalds1da177e2005-04-16 15:20:36 -0700815 hci_dev_unlock(hdev);
816
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200817 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
818 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200820 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700821
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200822 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
823 cp.role = 0x00; /* Become master */
824 else
825 cp.role = 0x01; /* Remain slave */
826
827 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
828 sizeof(cp), &cp);
829 } else {
830 struct hci_cp_accept_sync_conn_req cp;
831
832 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +0200833 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200834
835 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
836 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
837 cp.max_latency = cpu_to_le16(0xffff);
838 cp.content_format = cpu_to_le16(hdev->voice_setting);
839 cp.retrans_effort = 0xff;
840
841 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
842 sizeof(cp), &cp);
843 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844 } else {
845 /* Connection rejected */
846 struct hci_cp_reject_conn_req cp;
847
848 bacpy(&cp.bdaddr, &ev->bdaddr);
849 cp.reason = 0x0f;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200850 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700851 }
852}
853
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
855{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200856 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +0200857 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858
859 BT_DBG("%s status %d", hdev->name, ev->status);
860
861 if (ev->status)
862 return;
863
864 hci_dev_lock(hdev);
865
Marcel Holtmann04837f62006-07-03 10:02:33 +0200866 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700867 if (conn) {
868 conn->state = BT_CLOSED;
869 hci_proto_disconn_ind(conn, ev->reason);
870 hci_conn_del(conn);
871 }
872
873 hci_dev_unlock(hdev);
874}
875
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200876static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
877{
878 struct hci_ev_auth_complete *ev = (void *) skb->data;
879 struct hci_conn *conn;
880
881 BT_DBG("%s status %d", hdev->name, ev->status);
882
883 hci_dev_lock(hdev);
884
885 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
886 if (conn) {
887 if (!ev->status)
888 conn->link_mode |= HCI_LM_AUTH;
889
890 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
891
892 hci_auth_cfm(conn, ev->status);
893
894 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
895 if (!ev->status) {
896 struct hci_cp_set_conn_encrypt cp;
897 cp.handle = cpu_to_le16(conn->handle);
898 cp.encrypt = 1;
899 hci_send_cmd(conn->hdev,
900 HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp);
901 } else {
902 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
903 hci_encrypt_cfm(conn, ev->status, 0x00);
904 }
905 }
906 }
907
908 hci_dev_unlock(hdev);
909}
910
911static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
912{
913 BT_DBG("%s", hdev->name);
914
915 hci_conn_check_pending(hdev);
916}
917
918static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
919{
920 struct hci_ev_encrypt_change *ev = (void *) skb->data;
921 struct hci_conn *conn;
922
923 BT_DBG("%s status %d", hdev->name, ev->status);
924
925 hci_dev_lock(hdev);
926
927 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
928 if (conn) {
929 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +0200930 if (ev->encrypt) {
931 /* Encryption implies authentication */
932 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200933 conn->link_mode |= HCI_LM_ENCRYPT;
Marcel Holtmannae293192008-07-14 20:13:45 +0200934 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200935 conn->link_mode &= ~HCI_LM_ENCRYPT;
936 }
937
938 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
939
940 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
941 }
942
943 hci_dev_unlock(hdev);
944}
945
946static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
947{
948 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
949 struct hci_conn *conn;
950
951 BT_DBG("%s status %d", hdev->name, ev->status);
952
953 hci_dev_lock(hdev);
954
955 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
956 if (conn) {
957 if (!ev->status)
958 conn->link_mode |= HCI_LM_SECURE;
959
960 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
961
962 hci_key_change_cfm(conn, ev->status);
963 }
964
965 hci_dev_unlock(hdev);
966}
967
968static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
969{
970 struct hci_ev_remote_features *ev = (void *) skb->data;
971 struct hci_conn *conn;
972
973 BT_DBG("%s status %d", hdev->name, ev->status);
974
975 if (ev->status)
976 return;
977
978 hci_dev_lock(hdev);
979
980 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
981 if (conn)
982 memcpy(conn->features, ev->features, 8);
983
984 hci_dev_unlock(hdev);
985}
986
987static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
988{
989 BT_DBG("%s", hdev->name);
990}
991
992static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
993{
994 BT_DBG("%s", hdev->name);
995}
996
997static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
998{
999 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1000 __u16 opcode;
1001
1002 skb_pull(skb, sizeof(*ev));
1003
1004 opcode = __le16_to_cpu(ev->opcode);
1005
1006 switch (opcode) {
1007 case HCI_OP_INQUIRY_CANCEL:
1008 hci_cc_inquiry_cancel(hdev, skb);
1009 break;
1010
1011 case HCI_OP_EXIT_PERIODIC_INQ:
1012 hci_cc_exit_periodic_inq(hdev, skb);
1013 break;
1014
1015 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1016 hci_cc_remote_name_req_cancel(hdev, skb);
1017 break;
1018
1019 case HCI_OP_ROLE_DISCOVERY:
1020 hci_cc_role_discovery(hdev, skb);
1021 break;
1022
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001023 case HCI_OP_READ_LINK_POLICY:
1024 hci_cc_read_link_policy(hdev, skb);
1025 break;
1026
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001027 case HCI_OP_WRITE_LINK_POLICY:
1028 hci_cc_write_link_policy(hdev, skb);
1029 break;
1030
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001031 case HCI_OP_READ_DEF_LINK_POLICY:
1032 hci_cc_read_def_link_policy(hdev, skb);
1033 break;
1034
1035 case HCI_OP_WRITE_DEF_LINK_POLICY:
1036 hci_cc_write_def_link_policy(hdev, skb);
1037 break;
1038
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001039 case HCI_OP_RESET:
1040 hci_cc_reset(hdev, skb);
1041 break;
1042
1043 case HCI_OP_WRITE_LOCAL_NAME:
1044 hci_cc_write_local_name(hdev, skb);
1045 break;
1046
1047 case HCI_OP_READ_LOCAL_NAME:
1048 hci_cc_read_local_name(hdev, skb);
1049 break;
1050
1051 case HCI_OP_WRITE_AUTH_ENABLE:
1052 hci_cc_write_auth_enable(hdev, skb);
1053 break;
1054
1055 case HCI_OP_WRITE_ENCRYPT_MODE:
1056 hci_cc_write_encrypt_mode(hdev, skb);
1057 break;
1058
1059 case HCI_OP_WRITE_SCAN_ENABLE:
1060 hci_cc_write_scan_enable(hdev, skb);
1061 break;
1062
1063 case HCI_OP_READ_CLASS_OF_DEV:
1064 hci_cc_read_class_of_dev(hdev, skb);
1065 break;
1066
1067 case HCI_OP_WRITE_CLASS_OF_DEV:
1068 hci_cc_write_class_of_dev(hdev, skb);
1069 break;
1070
1071 case HCI_OP_READ_VOICE_SETTING:
1072 hci_cc_read_voice_setting(hdev, skb);
1073 break;
1074
1075 case HCI_OP_WRITE_VOICE_SETTING:
1076 hci_cc_write_voice_setting(hdev, skb);
1077 break;
1078
1079 case HCI_OP_HOST_BUFFER_SIZE:
1080 hci_cc_host_buffer_size(hdev, skb);
1081 break;
1082
1083 case HCI_OP_READ_LOCAL_VERSION:
1084 hci_cc_read_local_version(hdev, skb);
1085 break;
1086
1087 case HCI_OP_READ_LOCAL_COMMANDS:
1088 hci_cc_read_local_commands(hdev, skb);
1089 break;
1090
1091 case HCI_OP_READ_LOCAL_FEATURES:
1092 hci_cc_read_local_features(hdev, skb);
1093 break;
1094
1095 case HCI_OP_READ_BUFFER_SIZE:
1096 hci_cc_read_buffer_size(hdev, skb);
1097 break;
1098
1099 case HCI_OP_READ_BD_ADDR:
1100 hci_cc_read_bd_addr(hdev, skb);
1101 break;
1102
1103 default:
1104 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1105 break;
1106 }
1107
1108 if (ev->ncmd) {
1109 atomic_set(&hdev->cmd_cnt, 1);
1110 if (!skb_queue_empty(&hdev->cmd_q))
1111 hci_sched_cmd(hdev);
1112 }
1113}
1114
1115static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
1116{
1117 struct hci_ev_cmd_status *ev = (void *) skb->data;
1118 __u16 opcode;
1119
1120 skb_pull(skb, sizeof(*ev));
1121
1122 opcode = __le16_to_cpu(ev->opcode);
1123
1124 switch (opcode) {
1125 case HCI_OP_INQUIRY:
1126 hci_cs_inquiry(hdev, ev->status);
1127 break;
1128
1129 case HCI_OP_CREATE_CONN:
1130 hci_cs_create_conn(hdev, ev->status);
1131 break;
1132
1133 case HCI_OP_ADD_SCO:
1134 hci_cs_add_sco(hdev, ev->status);
1135 break;
1136
1137 case HCI_OP_REMOTE_NAME_REQ:
1138 hci_cs_remote_name_req(hdev, ev->status);
1139 break;
1140
1141 case HCI_OP_SETUP_SYNC_CONN:
1142 hci_cs_setup_sync_conn(hdev, ev->status);
1143 break;
1144
1145 case HCI_OP_SNIFF_MODE:
1146 hci_cs_sniff_mode(hdev, ev->status);
1147 break;
1148
1149 case HCI_OP_EXIT_SNIFF_MODE:
1150 hci_cs_exit_sniff_mode(hdev, ev->status);
1151 break;
1152
1153 default:
1154 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1155 break;
1156 }
1157
1158 if (ev->ncmd) {
1159 atomic_set(&hdev->cmd_cnt, 1);
1160 if (!skb_queue_empty(&hdev->cmd_q))
1161 hci_sched_cmd(hdev);
1162 }
1163}
1164
1165static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1166{
1167 struct hci_ev_role_change *ev = (void *) skb->data;
1168 struct hci_conn *conn;
1169
1170 BT_DBG("%s status %d", hdev->name, ev->status);
1171
1172 hci_dev_lock(hdev);
1173
1174 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1175 if (conn) {
1176 if (!ev->status) {
1177 if (ev->role)
1178 conn->link_mode &= ~HCI_LM_MASTER;
1179 else
1180 conn->link_mode |= HCI_LM_MASTER;
1181 }
1182
1183 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
1184
1185 hci_role_switch_cfm(conn, ev->status, ev->role);
1186 }
1187
1188 hci_dev_unlock(hdev);
1189}
1190
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
1192{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001193 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001194 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 int i;
1196
1197 skb_pull(skb, sizeof(*ev));
1198
1199 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
1200
1201 if (skb->len < ev->num_hndl * 4) {
1202 BT_DBG("%s bad parameters", hdev->name);
1203 return;
1204 }
1205
1206 tasklet_disable(&hdev->tx_task);
1207
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001208 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001209 struct hci_conn *conn;
1210 __u16 handle, count;
1211
Harvey Harrison83985312008-05-02 16:25:46 -07001212 handle = get_unaligned_le16(ptr++);
1213 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214
1215 conn = hci_conn_hash_lookup_handle(hdev, handle);
1216 if (conn) {
1217 conn->sent -= count;
1218
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001219 if (conn->type == ACL_LINK) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220 if ((hdev->acl_cnt += count) > hdev->acl_pkts)
1221 hdev->acl_cnt = hdev->acl_pkts;
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001222 } else {
1223 if ((hdev->sco_cnt += count) > hdev->sco_pkts)
1224 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001225 }
1226 }
1227 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001228
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229 hci_sched_tx(hdev);
1230
1231 tasklet_enable(&hdev->tx_task);
1232}
1233
Marcel Holtmann04837f62006-07-03 10:02:33 +02001234static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001235{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001236 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001237 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001238
1239 BT_DBG("%s status %d", hdev->name, ev->status);
1240
1241 hci_dev_lock(hdev);
1242
Marcel Holtmann04837f62006-07-03 10:02:33 +02001243 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1244 if (conn) {
1245 conn->mode = ev->mode;
1246 conn->interval = __le16_to_cpu(ev->interval);
1247
1248 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
1249 if (conn->mode == HCI_CM_ACTIVE)
1250 conn->power_save = 1;
1251 else
1252 conn->power_save = 0;
1253 }
1254 }
1255
1256 hci_dev_unlock(hdev);
1257}
1258
Linus Torvalds1da177e2005-04-16 15:20:36 -07001259static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1260{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001261 BT_DBG("%s", hdev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001262}
1263
Linus Torvalds1da177e2005-04-16 15:20:36 -07001264static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1265{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001266 BT_DBG("%s", hdev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001267}
1268
Linus Torvalds1da177e2005-04-16 15:20:36 -07001269static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
1270{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001271 BT_DBG("%s", hdev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001272}
1273
Marcel Holtmann04837f62006-07-03 10:02:33 +02001274static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
1275{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001276 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001277 struct hci_conn *conn;
1278
1279 BT_DBG("%s status %d", hdev->name, ev->status);
1280
1281 hci_dev_lock(hdev);
1282
1283 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001284 if (conn && !ev->status) {
1285 struct inquiry_entry *ie;
1286
1287 if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) {
1288 ie->data.clock_offset = ev->clock_offset;
1289 ie->timestamp = jiffies;
1290 }
1291 }
1292
1293 hci_dev_unlock(hdev);
1294}
1295
Marcel Holtmanna8746412008-07-14 20:13:46 +02001296static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1297{
1298 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
1299 struct hci_conn *conn;
1300
1301 BT_DBG("%s status %d", hdev->name, ev->status);
1302
1303 hci_dev_lock(hdev);
1304
1305 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1306 if (conn && !ev->status)
1307 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
1308
1309 hci_dev_unlock(hdev);
1310}
1311
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001312static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
1313{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001314 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001315 struct inquiry_entry *ie;
1316
1317 BT_DBG("%s", hdev->name);
1318
1319 hci_dev_lock(hdev);
1320
1321 if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) {
1322 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
1323 ie->timestamp = jiffies;
1324 }
1325
1326 hci_dev_unlock(hdev);
1327}
1328
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001329static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
1330{
1331 struct inquiry_data data;
1332 int num_rsp = *((__u8 *) skb->data);
1333
1334 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1335
1336 if (!num_rsp)
1337 return;
1338
1339 hci_dev_lock(hdev);
1340
1341 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
1342 struct inquiry_info_with_rssi_and_pscan_mode *info = (void *) (skb->data + 1);
1343
1344 for (; num_rsp; num_rsp--) {
1345 bacpy(&data.bdaddr, &info->bdaddr);
1346 data.pscan_rep_mode = info->pscan_rep_mode;
1347 data.pscan_period_mode = info->pscan_period_mode;
1348 data.pscan_mode = info->pscan_mode;
1349 memcpy(data.dev_class, info->dev_class, 3);
1350 data.clock_offset = info->clock_offset;
1351 data.rssi = info->rssi;
1352 info++;
1353 hci_inquiry_cache_update(hdev, &data);
1354 }
1355 } else {
1356 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
1357
1358 for (; num_rsp; num_rsp--) {
1359 bacpy(&data.bdaddr, &info->bdaddr);
1360 data.pscan_rep_mode = info->pscan_rep_mode;
1361 data.pscan_period_mode = info->pscan_period_mode;
1362 data.pscan_mode = 0x00;
1363 memcpy(data.dev_class, info->dev_class, 3);
1364 data.clock_offset = info->clock_offset;
1365 data.rssi = info->rssi;
1366 info++;
1367 hci_inquiry_cache_update(hdev, &data);
1368 }
1369 }
1370
1371 hci_dev_unlock(hdev);
1372}
1373
1374static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1375{
1376 BT_DBG("%s", hdev->name);
1377}
1378
1379static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1380{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001381 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
1382 struct hci_conn *conn;
1383
1384 BT_DBG("%s status %d", hdev->name, ev->status);
1385
1386 hci_dev_lock(hdev);
1387
1388 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02001389 if (!conn) {
1390 if (ev->link_type == ESCO_LINK)
1391 goto unlock;
1392
1393 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1394 if (!conn)
1395 goto unlock;
1396
1397 conn->type = SCO_LINK;
1398 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001399
1400 if (!ev->status) {
1401 conn->handle = __le16_to_cpu(ev->handle);
1402 conn->state = BT_CONNECTED;
1403 } else
1404 conn->state = BT_CLOSED;
1405
1406 hci_proto_connect_cfm(conn, ev->status);
1407 if (ev->status)
1408 hci_conn_del(conn);
1409
1410unlock:
1411 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001412}
1413
1414static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
1415{
1416 BT_DBG("%s", hdev->name);
1417}
1418
Marcel Holtmann04837f62006-07-03 10:02:33 +02001419static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
1420{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001421 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001422 struct hci_conn *conn;
1423
1424 BT_DBG("%s status %d", hdev->name, ev->status);
1425
1426 hci_dev_lock(hdev);
1427
1428 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1429 if (conn) {
1430 }
1431
1432 hci_dev_unlock(hdev);
1433}
1434
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001435static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1436{
1437 struct inquiry_data data;
1438 struct extended_inquiry_info *info = (void *) (skb->data + 1);
1439 int num_rsp = *((__u8 *) skb->data);
1440
1441 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1442
1443 if (!num_rsp)
1444 return;
1445
1446 hci_dev_lock(hdev);
1447
1448 for (; num_rsp; num_rsp--) {
1449 bacpy(&data.bdaddr, &info->bdaddr);
1450 data.pscan_rep_mode = info->pscan_rep_mode;
1451 data.pscan_period_mode = info->pscan_period_mode;
1452 data.pscan_mode = 0x00;
1453 memcpy(data.dev_class, info->dev_class, 3);
1454 data.clock_offset = info->clock_offset;
1455 data.rssi = info->rssi;
1456 info++;
1457 hci_inquiry_cache_update(hdev, &data);
1458 }
1459
1460 hci_dev_unlock(hdev);
1461}
1462
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
1464{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001465 struct hci_event_hdr *hdr = (void *) skb->data;
1466 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467
1468 skb_pull(skb, HCI_EVENT_HDR_SIZE);
1469
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001470 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471 case HCI_EV_INQUIRY_COMPLETE:
1472 hci_inquiry_complete_evt(hdev, skb);
1473 break;
1474
1475 case HCI_EV_INQUIRY_RESULT:
1476 hci_inquiry_result_evt(hdev, skb);
1477 break;
1478
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001479 case HCI_EV_CONN_COMPLETE:
1480 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02001481 break;
1482
Linus Torvalds1da177e2005-04-16 15:20:36 -07001483 case HCI_EV_CONN_REQUEST:
1484 hci_conn_request_evt(hdev, skb);
1485 break;
1486
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 case HCI_EV_DISCONN_COMPLETE:
1488 hci_disconn_complete_evt(hdev, skb);
1489 break;
1490
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491 case HCI_EV_AUTH_COMPLETE:
1492 hci_auth_complete_evt(hdev, skb);
1493 break;
1494
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001495 case HCI_EV_REMOTE_NAME:
1496 hci_remote_name_evt(hdev, skb);
1497 break;
1498
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499 case HCI_EV_ENCRYPT_CHANGE:
1500 hci_encrypt_change_evt(hdev, skb);
1501 break;
1502
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001503 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
1504 hci_change_link_key_complete_evt(hdev, skb);
1505 break;
1506
1507 case HCI_EV_REMOTE_FEATURES:
1508 hci_remote_features_evt(hdev, skb);
1509 break;
1510
1511 case HCI_EV_REMOTE_VERSION:
1512 hci_remote_version_evt(hdev, skb);
1513 break;
1514
1515 case HCI_EV_QOS_SETUP_COMPLETE:
1516 hci_qos_setup_complete_evt(hdev, skb);
1517 break;
1518
1519 case HCI_EV_CMD_COMPLETE:
1520 hci_cmd_complete_evt(hdev, skb);
1521 break;
1522
1523 case HCI_EV_CMD_STATUS:
1524 hci_cmd_status_evt(hdev, skb);
1525 break;
1526
1527 case HCI_EV_ROLE_CHANGE:
1528 hci_role_change_evt(hdev, skb);
1529 break;
1530
1531 case HCI_EV_NUM_COMP_PKTS:
1532 hci_num_comp_pkts_evt(hdev, skb);
1533 break;
1534
1535 case HCI_EV_MODE_CHANGE:
1536 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001537 break;
1538
1539 case HCI_EV_PIN_CODE_REQ:
1540 hci_pin_code_request_evt(hdev, skb);
1541 break;
1542
1543 case HCI_EV_LINK_KEY_REQ:
1544 hci_link_key_request_evt(hdev, skb);
1545 break;
1546
1547 case HCI_EV_LINK_KEY_NOTIFY:
1548 hci_link_key_notify_evt(hdev, skb);
1549 break;
1550
1551 case HCI_EV_CLOCK_OFFSET:
1552 hci_clock_offset_evt(hdev, skb);
1553 break;
1554
Marcel Holtmanna8746412008-07-14 20:13:46 +02001555 case HCI_EV_PKT_TYPE_CHANGE:
1556 hci_pkt_type_change_evt(hdev, skb);
1557 break;
1558
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001559 case HCI_EV_PSCAN_REP_MODE:
1560 hci_pscan_rep_mode_evt(hdev, skb);
1561 break;
1562
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001563 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
1564 hci_inquiry_result_with_rssi_evt(hdev, skb);
1565 break;
1566
1567 case HCI_EV_REMOTE_EXT_FEATURES:
1568 hci_remote_ext_features_evt(hdev, skb);
1569 break;
1570
1571 case HCI_EV_SYNC_CONN_COMPLETE:
1572 hci_sync_conn_complete_evt(hdev, skb);
1573 break;
1574
1575 case HCI_EV_SYNC_CONN_CHANGED:
1576 hci_sync_conn_changed_evt(hdev, skb);
1577 break;
1578
Marcel Holtmann04837f62006-07-03 10:02:33 +02001579 case HCI_EV_SNIFF_SUBRATE:
1580 hci_sniff_subrate_evt(hdev, skb);
1581 break;
1582
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001583 case HCI_EV_EXTENDED_INQUIRY_RESULT:
1584 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001585 break;
1586
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001587 default:
1588 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589 break;
1590 }
1591
1592 kfree_skb(skb);
1593 hdev->stat.evt_rx++;
1594}
1595
1596/* Generate internal stack event */
1597void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
1598{
1599 struct hci_event_hdr *hdr;
1600 struct hci_ev_stack_internal *ev;
1601 struct sk_buff *skb;
1602
1603 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
1604 if (!skb)
1605 return;
1606
1607 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
1608 hdr->evt = HCI_EV_STACK_INTERNAL;
1609 hdr->plen = sizeof(*ev) + dlen;
1610
1611 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
1612 ev->type = type;
1613 memcpy(ev->data, data, dlen);
1614
Marcel Holtmann576c7d82005-08-06 12:36:54 +02001615 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07001616 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02001617
Marcel Holtmann0d48d932005-08-09 20:30:28 -07001618 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001619 skb->dev = (void *) hdev;
1620 hci_send_to_sock(hdev, skb);
1621 kfree_skb(skb);
1622}