blob: e47676128bb529ac0430b8e3ade04df012fd464f [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 */
Marcel Holtmannc7bdd502008-07-14 20:13:47 +0200799 struct inquiry_entry *ie;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700800 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700801
802 hci_dev_lock(hdev);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200803
Marcel Holtmannc7bdd502008-07-14 20:13:47 +0200804 if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr)))
805 memcpy(ie->data.dev_class, ev->dev_class, 3);
806
Linus Torvalds1da177e2005-04-16 15:20:36 -0700807 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
808 if (!conn) {
809 if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
810 BT_ERR("No memmory for new connection");
811 hci_dev_unlock(hdev);
812 return;
813 }
814 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200815
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 memcpy(conn->dev_class, ev->dev_class, 3);
817 conn->state = BT_CONNECT;
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200818
Linus Torvalds1da177e2005-04-16 15:20:36 -0700819 hci_dev_unlock(hdev);
820
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200821 if (ev->link_type == ACL_LINK || !lmp_esco_capable(hdev)) {
822 struct hci_cp_accept_conn_req cp;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700823
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200824 bacpy(&cp.bdaddr, &ev->bdaddr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700825
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200826 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
827 cp.role = 0x00; /* Become master */
828 else
829 cp.role = 0x01; /* Remain slave */
830
831 hci_send_cmd(hdev, HCI_OP_ACCEPT_CONN_REQ,
832 sizeof(cp), &cp);
833 } else {
834 struct hci_cp_accept_sync_conn_req cp;
835
836 bacpy(&cp.bdaddr, &ev->bdaddr);
Marcel Holtmanna8746412008-07-14 20:13:46 +0200837 cp.pkt_type = cpu_to_le16(conn->pkt_type);
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +0200838
839 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
840 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
841 cp.max_latency = cpu_to_le16(0xffff);
842 cp.content_format = cpu_to_le16(hdev->voice_setting);
843 cp.retrans_effort = 0xff;
844
845 hci_send_cmd(hdev, HCI_OP_ACCEPT_SYNC_CONN_REQ,
846 sizeof(cp), &cp);
847 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848 } else {
849 /* Connection rejected */
850 struct hci_cp_reject_conn_req cp;
851
852 bacpy(&cp.bdaddr, &ev->bdaddr);
853 cp.reason = 0x0f;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200854 hci_send_cmd(hdev, HCI_OP_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700855 }
856}
857
Linus Torvalds1da177e2005-04-16 15:20:36 -0700858static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
859{
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200860 struct hci_ev_disconn_complete *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +0200861 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700862
863 BT_DBG("%s status %d", hdev->name, ev->status);
864
865 if (ev->status)
866 return;
867
868 hci_dev_lock(hdev);
869
Marcel Holtmann04837f62006-07-03 10:02:33 +0200870 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700871 if (conn) {
872 conn->state = BT_CLOSED;
873 hci_proto_disconn_ind(conn, ev->reason);
874 hci_conn_del(conn);
875 }
876
877 hci_dev_unlock(hdev);
878}
879
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200880static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
881{
882 struct hci_ev_auth_complete *ev = (void *) skb->data;
883 struct hci_conn *conn;
884
885 BT_DBG("%s status %d", hdev->name, ev->status);
886
887 hci_dev_lock(hdev);
888
889 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
890 if (conn) {
891 if (!ev->status)
892 conn->link_mode |= HCI_LM_AUTH;
893
894 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
895
896 hci_auth_cfm(conn, ev->status);
897
898 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
899 if (!ev->status) {
900 struct hci_cp_set_conn_encrypt cp;
901 cp.handle = cpu_to_le16(conn->handle);
902 cp.encrypt = 1;
903 hci_send_cmd(conn->hdev,
904 HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp);
905 } else {
906 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
907 hci_encrypt_cfm(conn, ev->status, 0x00);
908 }
909 }
910 }
911
912 hci_dev_unlock(hdev);
913}
914
915static inline void hci_remote_name_evt(struct hci_dev *hdev, struct sk_buff *skb)
916{
917 BT_DBG("%s", hdev->name);
918
919 hci_conn_check_pending(hdev);
920}
921
922static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
923{
924 struct hci_ev_encrypt_change *ev = (void *) skb->data;
925 struct hci_conn *conn;
926
927 BT_DBG("%s status %d", hdev->name, ev->status);
928
929 hci_dev_lock(hdev);
930
931 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
932 if (conn) {
933 if (!ev->status) {
Marcel Holtmannae293192008-07-14 20:13:45 +0200934 if (ev->encrypt) {
935 /* Encryption implies authentication */
936 conn->link_mode |= HCI_LM_AUTH;
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200937 conn->link_mode |= HCI_LM_ENCRYPT;
Marcel Holtmannae293192008-07-14 20:13:45 +0200938 } else
Marcel Holtmanna9de9242007-10-20 13:33:56 +0200939 conn->link_mode &= ~HCI_LM_ENCRYPT;
940 }
941
942 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
943
944 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
945 }
946
947 hci_dev_unlock(hdev);
948}
949
950static inline void hci_change_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
951{
952 struct hci_ev_change_link_key_complete *ev = (void *) skb->data;
953 struct hci_conn *conn;
954
955 BT_DBG("%s status %d", hdev->name, ev->status);
956
957 hci_dev_lock(hdev);
958
959 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
960 if (conn) {
961 if (!ev->status)
962 conn->link_mode |= HCI_LM_SECURE;
963
964 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
965
966 hci_key_change_cfm(conn, ev->status);
967 }
968
969 hci_dev_unlock(hdev);
970}
971
972static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
973{
974 struct hci_ev_remote_features *ev = (void *) skb->data;
975 struct hci_conn *conn;
976
977 BT_DBG("%s status %d", hdev->name, ev->status);
978
979 if (ev->status)
980 return;
981
982 hci_dev_lock(hdev);
983
984 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
985 if (conn)
986 memcpy(conn->features, ev->features, 8);
987
988 hci_dev_unlock(hdev);
989}
990
991static inline void hci_remote_version_evt(struct hci_dev *hdev, struct sk_buff *skb)
992{
993 BT_DBG("%s", hdev->name);
994}
995
996static inline void hci_qos_setup_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
997{
998 BT_DBG("%s", hdev->name);
999}
1000
1001static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1002{
1003 struct hci_ev_cmd_complete *ev = (void *) skb->data;
1004 __u16 opcode;
1005
1006 skb_pull(skb, sizeof(*ev));
1007
1008 opcode = __le16_to_cpu(ev->opcode);
1009
1010 switch (opcode) {
1011 case HCI_OP_INQUIRY_CANCEL:
1012 hci_cc_inquiry_cancel(hdev, skb);
1013 break;
1014
1015 case HCI_OP_EXIT_PERIODIC_INQ:
1016 hci_cc_exit_periodic_inq(hdev, skb);
1017 break;
1018
1019 case HCI_OP_REMOTE_NAME_REQ_CANCEL:
1020 hci_cc_remote_name_req_cancel(hdev, skb);
1021 break;
1022
1023 case HCI_OP_ROLE_DISCOVERY:
1024 hci_cc_role_discovery(hdev, skb);
1025 break;
1026
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001027 case HCI_OP_READ_LINK_POLICY:
1028 hci_cc_read_link_policy(hdev, skb);
1029 break;
1030
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001031 case HCI_OP_WRITE_LINK_POLICY:
1032 hci_cc_write_link_policy(hdev, skb);
1033 break;
1034
Marcel Holtmanne4e8e372008-07-14 20:13:47 +02001035 case HCI_OP_READ_DEF_LINK_POLICY:
1036 hci_cc_read_def_link_policy(hdev, skb);
1037 break;
1038
1039 case HCI_OP_WRITE_DEF_LINK_POLICY:
1040 hci_cc_write_def_link_policy(hdev, skb);
1041 break;
1042
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001043 case HCI_OP_RESET:
1044 hci_cc_reset(hdev, skb);
1045 break;
1046
1047 case HCI_OP_WRITE_LOCAL_NAME:
1048 hci_cc_write_local_name(hdev, skb);
1049 break;
1050
1051 case HCI_OP_READ_LOCAL_NAME:
1052 hci_cc_read_local_name(hdev, skb);
1053 break;
1054
1055 case HCI_OP_WRITE_AUTH_ENABLE:
1056 hci_cc_write_auth_enable(hdev, skb);
1057 break;
1058
1059 case HCI_OP_WRITE_ENCRYPT_MODE:
1060 hci_cc_write_encrypt_mode(hdev, skb);
1061 break;
1062
1063 case HCI_OP_WRITE_SCAN_ENABLE:
1064 hci_cc_write_scan_enable(hdev, skb);
1065 break;
1066
1067 case HCI_OP_READ_CLASS_OF_DEV:
1068 hci_cc_read_class_of_dev(hdev, skb);
1069 break;
1070
1071 case HCI_OP_WRITE_CLASS_OF_DEV:
1072 hci_cc_write_class_of_dev(hdev, skb);
1073 break;
1074
1075 case HCI_OP_READ_VOICE_SETTING:
1076 hci_cc_read_voice_setting(hdev, skb);
1077 break;
1078
1079 case HCI_OP_WRITE_VOICE_SETTING:
1080 hci_cc_write_voice_setting(hdev, skb);
1081 break;
1082
1083 case HCI_OP_HOST_BUFFER_SIZE:
1084 hci_cc_host_buffer_size(hdev, skb);
1085 break;
1086
1087 case HCI_OP_READ_LOCAL_VERSION:
1088 hci_cc_read_local_version(hdev, skb);
1089 break;
1090
1091 case HCI_OP_READ_LOCAL_COMMANDS:
1092 hci_cc_read_local_commands(hdev, skb);
1093 break;
1094
1095 case HCI_OP_READ_LOCAL_FEATURES:
1096 hci_cc_read_local_features(hdev, skb);
1097 break;
1098
1099 case HCI_OP_READ_BUFFER_SIZE:
1100 hci_cc_read_buffer_size(hdev, skb);
1101 break;
1102
1103 case HCI_OP_READ_BD_ADDR:
1104 hci_cc_read_bd_addr(hdev, skb);
1105 break;
1106
1107 default:
1108 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1109 break;
1110 }
1111
1112 if (ev->ncmd) {
1113 atomic_set(&hdev->cmd_cnt, 1);
1114 if (!skb_queue_empty(&hdev->cmd_q))
1115 hci_sched_cmd(hdev);
1116 }
1117}
1118
1119static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
1120{
1121 struct hci_ev_cmd_status *ev = (void *) skb->data;
1122 __u16 opcode;
1123
1124 skb_pull(skb, sizeof(*ev));
1125
1126 opcode = __le16_to_cpu(ev->opcode);
1127
1128 switch (opcode) {
1129 case HCI_OP_INQUIRY:
1130 hci_cs_inquiry(hdev, ev->status);
1131 break;
1132
1133 case HCI_OP_CREATE_CONN:
1134 hci_cs_create_conn(hdev, ev->status);
1135 break;
1136
1137 case HCI_OP_ADD_SCO:
1138 hci_cs_add_sco(hdev, ev->status);
1139 break;
1140
1141 case HCI_OP_REMOTE_NAME_REQ:
1142 hci_cs_remote_name_req(hdev, ev->status);
1143 break;
1144
1145 case HCI_OP_SETUP_SYNC_CONN:
1146 hci_cs_setup_sync_conn(hdev, ev->status);
1147 break;
1148
1149 case HCI_OP_SNIFF_MODE:
1150 hci_cs_sniff_mode(hdev, ev->status);
1151 break;
1152
1153 case HCI_OP_EXIT_SNIFF_MODE:
1154 hci_cs_exit_sniff_mode(hdev, ev->status);
1155 break;
1156
1157 default:
1158 BT_DBG("%s opcode 0x%x", hdev->name, opcode);
1159 break;
1160 }
1161
1162 if (ev->ncmd) {
1163 atomic_set(&hdev->cmd_cnt, 1);
1164 if (!skb_queue_empty(&hdev->cmd_q))
1165 hci_sched_cmd(hdev);
1166 }
1167}
1168
1169static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1170{
1171 struct hci_ev_role_change *ev = (void *) skb->data;
1172 struct hci_conn *conn;
1173
1174 BT_DBG("%s status %d", hdev->name, ev->status);
1175
1176 hci_dev_lock(hdev);
1177
1178 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
1179 if (conn) {
1180 if (!ev->status) {
1181 if (ev->role)
1182 conn->link_mode &= ~HCI_LM_MASTER;
1183 else
1184 conn->link_mode |= HCI_LM_MASTER;
1185 }
1186
1187 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
1188
1189 hci_role_switch_cfm(conn, ev->status, ev->role);
1190 }
1191
1192 hci_dev_unlock(hdev);
1193}
1194
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
1196{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001197 struct hci_ev_num_comp_pkts *ev = (void *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001198 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001199 int i;
1200
1201 skb_pull(skb, sizeof(*ev));
1202
1203 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
1204
1205 if (skb->len < ev->num_hndl * 4) {
1206 BT_DBG("%s bad parameters", hdev->name);
1207 return;
1208 }
1209
1210 tasklet_disable(&hdev->tx_task);
1211
Marcel Holtmann1ebb9252005-11-08 09:57:21 -08001212 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001213 struct hci_conn *conn;
1214 __u16 handle, count;
1215
Harvey Harrison83985312008-05-02 16:25:46 -07001216 handle = get_unaligned_le16(ptr++);
1217 count = get_unaligned_le16(ptr++);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218
1219 conn = hci_conn_hash_lookup_handle(hdev, handle);
1220 if (conn) {
1221 conn->sent -= count;
1222
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001223 if (conn->type == ACL_LINK) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224 if ((hdev->acl_cnt += count) > hdev->acl_pkts)
1225 hdev->acl_cnt = hdev->acl_pkts;
Marcel Holtmann5b7f9902007-07-11 09:51:55 +02001226 } else {
1227 if ((hdev->sco_cnt += count) > hdev->sco_pkts)
1228 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001229 }
1230 }
1231 }
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001232
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233 hci_sched_tx(hdev);
1234
1235 tasklet_enable(&hdev->tx_task);
1236}
1237
Marcel Holtmann04837f62006-07-03 10:02:33 +02001238static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001240 struct hci_ev_mode_change *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001241 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242
1243 BT_DBG("%s status %d", hdev->name, ev->status);
1244
1245 hci_dev_lock(hdev);
1246
Marcel Holtmann04837f62006-07-03 10:02:33 +02001247 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1248 if (conn) {
1249 conn->mode = ev->mode;
1250 conn->interval = __le16_to_cpu(ev->interval);
1251
1252 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
1253 if (conn->mode == HCI_CM_ACTIVE)
1254 conn->power_save = 1;
1255 else
1256 conn->power_save = 0;
1257 }
1258 }
1259
1260 hci_dev_unlock(hdev);
1261}
1262
Linus Torvalds1da177e2005-04-16 15:20:36 -07001263static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1264{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001265 BT_DBG("%s", hdev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001266}
1267
Linus Torvalds1da177e2005-04-16 15:20:36 -07001268static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1269{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001270 BT_DBG("%s", hdev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001271}
1272
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
1274{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001275 BT_DBG("%s", hdev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001276}
1277
Marcel Holtmann04837f62006-07-03 10:02:33 +02001278static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
1279{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001280 struct hci_ev_clock_offset *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001281 struct hci_conn *conn;
1282
1283 BT_DBG("%s status %d", hdev->name, ev->status);
1284
1285 hci_dev_lock(hdev);
1286
1287 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288 if (conn && !ev->status) {
1289 struct inquiry_entry *ie;
1290
1291 if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) {
1292 ie->data.clock_offset = ev->clock_offset;
1293 ie->timestamp = jiffies;
1294 }
1295 }
1296
1297 hci_dev_unlock(hdev);
1298}
1299
Marcel Holtmanna8746412008-07-14 20:13:46 +02001300static inline void hci_pkt_type_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1301{
1302 struct hci_ev_pkt_type_change *ev = (void *) skb->data;
1303 struct hci_conn *conn;
1304
1305 BT_DBG("%s status %d", hdev->name, ev->status);
1306
1307 hci_dev_lock(hdev);
1308
1309 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1310 if (conn && !ev->status)
1311 conn->pkt_type = __le16_to_cpu(ev->pkt_type);
1312
1313 hci_dev_unlock(hdev);
1314}
1315
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001316static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
1317{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001318 struct hci_ev_pscan_rep_mode *ev = (void *) skb->data;
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001319 struct inquiry_entry *ie;
1320
1321 BT_DBG("%s", hdev->name);
1322
1323 hci_dev_lock(hdev);
1324
1325 if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) {
1326 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
1327 ie->timestamp = jiffies;
1328 }
1329
1330 hci_dev_unlock(hdev);
1331}
1332
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001333static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
1334{
1335 struct inquiry_data data;
1336 int num_rsp = *((__u8 *) skb->data);
1337
1338 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1339
1340 if (!num_rsp)
1341 return;
1342
1343 hci_dev_lock(hdev);
1344
1345 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
1346 struct inquiry_info_with_rssi_and_pscan_mode *info = (void *) (skb->data + 1);
1347
1348 for (; num_rsp; num_rsp--) {
1349 bacpy(&data.bdaddr, &info->bdaddr);
1350 data.pscan_rep_mode = info->pscan_rep_mode;
1351 data.pscan_period_mode = info->pscan_period_mode;
1352 data.pscan_mode = info->pscan_mode;
1353 memcpy(data.dev_class, info->dev_class, 3);
1354 data.clock_offset = info->clock_offset;
1355 data.rssi = info->rssi;
1356 info++;
1357 hci_inquiry_cache_update(hdev, &data);
1358 }
1359 } else {
1360 struct inquiry_info_with_rssi *info = (void *) (skb->data + 1);
1361
1362 for (; num_rsp; num_rsp--) {
1363 bacpy(&data.bdaddr, &info->bdaddr);
1364 data.pscan_rep_mode = info->pscan_rep_mode;
1365 data.pscan_period_mode = info->pscan_period_mode;
1366 data.pscan_mode = 0x00;
1367 memcpy(data.dev_class, info->dev_class, 3);
1368 data.clock_offset = info->clock_offset;
1369 data.rssi = info->rssi;
1370 info++;
1371 hci_inquiry_cache_update(hdev, &data);
1372 }
1373 }
1374
1375 hci_dev_unlock(hdev);
1376}
1377
1378static inline void hci_remote_ext_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
1379{
1380 BT_DBG("%s", hdev->name);
1381}
1382
1383static inline void hci_sync_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1384{
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001385 struct hci_ev_sync_conn_complete *ev = (void *) skb->data;
1386 struct hci_conn *conn;
1387
1388 BT_DBG("%s status %d", hdev->name, ev->status);
1389
1390 hci_dev_lock(hdev);
1391
1392 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
Marcel Holtmann9dc0a3a2008-07-14 20:13:46 +02001393 if (!conn) {
1394 if (ev->link_type == ESCO_LINK)
1395 goto unlock;
1396
1397 conn = hci_conn_hash_lookup_ba(hdev, ESCO_LINK, &ev->bdaddr);
1398 if (!conn)
1399 goto unlock;
1400
1401 conn->type = SCO_LINK;
1402 }
Marcel Holtmannb6a0dc82007-10-20 14:55:10 +02001403
1404 if (!ev->status) {
1405 conn->handle = __le16_to_cpu(ev->handle);
1406 conn->state = BT_CONNECTED;
1407 } else
1408 conn->state = BT_CLOSED;
1409
1410 hci_proto_connect_cfm(conn, ev->status);
1411 if (ev->status)
1412 hci_conn_del(conn);
1413
1414unlock:
1415 hci_dev_unlock(hdev);
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001416}
1417
1418static inline void hci_sync_conn_changed_evt(struct hci_dev *hdev, struct sk_buff *skb)
1419{
1420 BT_DBG("%s", hdev->name);
1421}
1422
Marcel Holtmann04837f62006-07-03 10:02:33 +02001423static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
1424{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001425 struct hci_ev_sniff_subrate *ev = (void *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001426 struct hci_conn *conn;
1427
1428 BT_DBG("%s status %d", hdev->name, ev->status);
1429
1430 hci_dev_lock(hdev);
1431
1432 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1433 if (conn) {
1434 }
1435
1436 hci_dev_unlock(hdev);
1437}
1438
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001439static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
1440{
1441 struct inquiry_data data;
1442 struct extended_inquiry_info *info = (void *) (skb->data + 1);
1443 int num_rsp = *((__u8 *) skb->data);
1444
1445 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
1446
1447 if (!num_rsp)
1448 return;
1449
1450 hci_dev_lock(hdev);
1451
1452 for (; num_rsp; num_rsp--) {
1453 bacpy(&data.bdaddr, &info->bdaddr);
1454 data.pscan_rep_mode = info->pscan_rep_mode;
1455 data.pscan_period_mode = info->pscan_period_mode;
1456 data.pscan_mode = 0x00;
1457 memcpy(data.dev_class, info->dev_class, 3);
1458 data.clock_offset = info->clock_offset;
1459 data.rssi = info->rssi;
1460 info++;
1461 hci_inquiry_cache_update(hdev, &data);
1462 }
1463
1464 hci_dev_unlock(hdev);
1465}
1466
Linus Torvalds1da177e2005-04-16 15:20:36 -07001467void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
1468{
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001469 struct hci_event_hdr *hdr = (void *) skb->data;
1470 __u8 event = hdr->evt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001471
1472 skb_pull(skb, HCI_EVENT_HDR_SIZE);
1473
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001474 switch (event) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001475 case HCI_EV_INQUIRY_COMPLETE:
1476 hci_inquiry_complete_evt(hdev, skb);
1477 break;
1478
1479 case HCI_EV_INQUIRY_RESULT:
1480 hci_inquiry_result_evt(hdev, skb);
1481 break;
1482
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001483 case HCI_EV_CONN_COMPLETE:
1484 hci_conn_complete_evt(hdev, skb);
Marcel Holtmann21d9e302005-09-13 01:32:25 +02001485 break;
1486
Linus Torvalds1da177e2005-04-16 15:20:36 -07001487 case HCI_EV_CONN_REQUEST:
1488 hci_conn_request_evt(hdev, skb);
1489 break;
1490
Linus Torvalds1da177e2005-04-16 15:20:36 -07001491 case HCI_EV_DISCONN_COMPLETE:
1492 hci_disconn_complete_evt(hdev, skb);
1493 break;
1494
Linus Torvalds1da177e2005-04-16 15:20:36 -07001495 case HCI_EV_AUTH_COMPLETE:
1496 hci_auth_complete_evt(hdev, skb);
1497 break;
1498
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001499 case HCI_EV_REMOTE_NAME:
1500 hci_remote_name_evt(hdev, skb);
1501 break;
1502
Linus Torvalds1da177e2005-04-16 15:20:36 -07001503 case HCI_EV_ENCRYPT_CHANGE:
1504 hci_encrypt_change_evt(hdev, skb);
1505 break;
1506
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001507 case HCI_EV_CHANGE_LINK_KEY_COMPLETE:
1508 hci_change_link_key_complete_evt(hdev, skb);
1509 break;
1510
1511 case HCI_EV_REMOTE_FEATURES:
1512 hci_remote_features_evt(hdev, skb);
1513 break;
1514
1515 case HCI_EV_REMOTE_VERSION:
1516 hci_remote_version_evt(hdev, skb);
1517 break;
1518
1519 case HCI_EV_QOS_SETUP_COMPLETE:
1520 hci_qos_setup_complete_evt(hdev, skb);
1521 break;
1522
1523 case HCI_EV_CMD_COMPLETE:
1524 hci_cmd_complete_evt(hdev, skb);
1525 break;
1526
1527 case HCI_EV_CMD_STATUS:
1528 hci_cmd_status_evt(hdev, skb);
1529 break;
1530
1531 case HCI_EV_ROLE_CHANGE:
1532 hci_role_change_evt(hdev, skb);
1533 break;
1534
1535 case HCI_EV_NUM_COMP_PKTS:
1536 hci_num_comp_pkts_evt(hdev, skb);
1537 break;
1538
1539 case HCI_EV_MODE_CHANGE:
1540 hci_mode_change_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001541 break;
1542
1543 case HCI_EV_PIN_CODE_REQ:
1544 hci_pin_code_request_evt(hdev, skb);
1545 break;
1546
1547 case HCI_EV_LINK_KEY_REQ:
1548 hci_link_key_request_evt(hdev, skb);
1549 break;
1550
1551 case HCI_EV_LINK_KEY_NOTIFY:
1552 hci_link_key_notify_evt(hdev, skb);
1553 break;
1554
1555 case HCI_EV_CLOCK_OFFSET:
1556 hci_clock_offset_evt(hdev, skb);
1557 break;
1558
Marcel Holtmanna8746412008-07-14 20:13:46 +02001559 case HCI_EV_PKT_TYPE_CHANGE:
1560 hci_pkt_type_change_evt(hdev, skb);
1561 break;
1562
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001563 case HCI_EV_PSCAN_REP_MODE:
1564 hci_pscan_rep_mode_evt(hdev, skb);
1565 break;
1566
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001567 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
1568 hci_inquiry_result_with_rssi_evt(hdev, skb);
1569 break;
1570
1571 case HCI_EV_REMOTE_EXT_FEATURES:
1572 hci_remote_ext_features_evt(hdev, skb);
1573 break;
1574
1575 case HCI_EV_SYNC_CONN_COMPLETE:
1576 hci_sync_conn_complete_evt(hdev, skb);
1577 break;
1578
1579 case HCI_EV_SYNC_CONN_CHANGED:
1580 hci_sync_conn_changed_evt(hdev, skb);
1581 break;
1582
Marcel Holtmann04837f62006-07-03 10:02:33 +02001583 case HCI_EV_SNIFF_SUBRATE:
1584 hci_sniff_subrate_evt(hdev, skb);
1585 break;
1586
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001587 case HCI_EV_EXTENDED_INQUIRY_RESULT:
1588 hci_extended_inquiry_result_evt(hdev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589 break;
1590
Marcel Holtmanna9de9242007-10-20 13:33:56 +02001591 default:
1592 BT_DBG("%s event 0x%x", hdev->name, event);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593 break;
1594 }
1595
1596 kfree_skb(skb);
1597 hdev->stat.evt_rx++;
1598}
1599
1600/* Generate internal stack event */
1601void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
1602{
1603 struct hci_event_hdr *hdr;
1604 struct hci_ev_stack_internal *ev;
1605 struct sk_buff *skb;
1606
1607 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
1608 if (!skb)
1609 return;
1610
1611 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
1612 hdr->evt = HCI_EV_STACK_INTERNAL;
1613 hdr->plen = sizeof(*ev) + dlen;
1614
1615 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
1616 ev->type = type;
1617 memcpy(ev->data, data, dlen);
1618
Marcel Holtmann576c7d82005-08-06 12:36:54 +02001619 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07001620 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02001621
Marcel Holtmann0d48d932005-08-09 20:30:28 -07001622 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001623 skb->dev = (void *) hdev;
1624 hci_send_to_sock(hdev, skb);
1625 kfree_skb(skb);
1626}