blob: 936d3fc479cdd9d2029a729e1a6ba63b4a7ab11d [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
55/* Command Complete OGF LINK_CTL */
56static void hci_cc_link_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
57{
58 __u8 status;
Marcel Holtmann6bd57412006-11-18 22:14:22 +010059 struct hci_conn *pend;
Linus Torvalds1da177e2005-04-16 15:20:36 -070060
61 BT_DBG("%s ocf 0x%x", hdev->name, ocf);
62
63 switch (ocf) {
64 case OCF_INQUIRY_CANCEL:
Marcel Holtmanndefc7612006-09-21 16:04:00 +020065 case OCF_EXIT_PERIODIC_INQ:
Linus Torvalds1da177e2005-04-16 15:20:36 -070066 status = *((__u8 *) skb->data);
67
68 if (status) {
69 BT_DBG("%s Inquiry cancel error: status 0x%x", hdev->name, status);
70 } else {
71 clear_bit(HCI_INQUIRY, &hdev->flags);
72 hci_req_complete(hdev, status);
73 }
Marcel Holtmann6bd57412006-11-18 22:14:22 +010074
75 hci_dev_lock(hdev);
76
77 pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
78 if (pend)
79 hci_acl_connect(pend);
80
81 hci_dev_unlock(hdev);
82
Linus Torvalds1da177e2005-04-16 15:20:36 -070083 break;
84
85 default:
86 BT_DBG("%s Command complete: ogf LINK_CTL ocf %x", hdev->name, ocf);
87 break;
88 }
89}
90
91/* Command Complete OGF LINK_POLICY */
92static void hci_cc_link_policy(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
93{
94 struct hci_conn *conn;
95 struct hci_rp_role_discovery *rd;
Marcel Holtmann04837f62006-07-03 10:02:33 +020096 struct hci_rp_write_link_policy *lp;
97 void *sent;
Linus Torvalds1da177e2005-04-16 15:20:36 -070098
99 BT_DBG("%s ocf 0x%x", hdev->name, ocf);
100
101 switch (ocf) {
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900102 case OCF_ROLE_DISCOVERY:
Linus Torvalds1da177e2005-04-16 15:20:36 -0700103 rd = (void *) skb->data;
104
105 if (rd->status)
106 break;
107
108 hci_dev_lock(hdev);
109
110 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rd->handle));
111 if (conn) {
112 if (rd->role)
113 conn->link_mode &= ~HCI_LM_MASTER;
114 else
115 conn->link_mode |= HCI_LM_MASTER;
116 }
117
118 hci_dev_unlock(hdev);
119 break;
120
Marcel Holtmann04837f62006-07-03 10:02:33 +0200121 case OCF_WRITE_LINK_POLICY:
122 sent = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_WRITE_LINK_POLICY);
123 if (!sent)
124 break;
125
126 lp = (struct hci_rp_write_link_policy *) skb->data;
127
128 if (lp->status)
129 break;
130
131 hci_dev_lock(hdev);
132
133 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(lp->handle));
134 if (conn) {
135 __le16 policy = get_unaligned((__le16 *) (sent + 2));
136 conn->link_policy = __le16_to_cpu(policy);
137 }
138
139 hci_dev_unlock(hdev);
140 break;
141
Linus Torvalds1da177e2005-04-16 15:20:36 -0700142 default:
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900143 BT_DBG("%s: Command complete: ogf LINK_POLICY ocf %x",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700144 hdev->name, ocf);
145 break;
146 }
147}
148
149/* Command Complete OGF HOST_CTL */
150static void hci_cc_host_ctl(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
151{
152 __u8 status, param;
153 __u16 setting;
154 struct hci_rp_read_voice_setting *vs;
155 void *sent;
156
157 BT_DBG("%s ocf 0x%x", hdev->name, ocf);
158
159 switch (ocf) {
160 case OCF_RESET:
161 status = *((__u8 *) skb->data);
162 hci_req_complete(hdev, status);
163 break;
164
165 case OCF_SET_EVENT_FLT:
166 status = *((__u8 *) skb->data);
167 if (status) {
168 BT_DBG("%s SET_EVENT_FLT failed %d", hdev->name, status);
169 } else {
170 BT_DBG("%s SET_EVENT_FLT succeseful", hdev->name);
171 }
172 break;
173
174 case OCF_WRITE_AUTH_ENABLE:
175 sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_AUTH_ENABLE);
176 if (!sent)
177 break;
178
179 status = *((__u8 *) skb->data);
180 param = *((__u8 *) sent);
181
182 if (!status) {
183 if (param == AUTH_ENABLED)
184 set_bit(HCI_AUTH, &hdev->flags);
185 else
186 clear_bit(HCI_AUTH, &hdev->flags);
187 }
188 hci_req_complete(hdev, status);
189 break;
190
191 case OCF_WRITE_ENCRYPT_MODE:
192 sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_ENCRYPT_MODE);
193 if (!sent)
194 break;
195
196 status = *((__u8 *) skb->data);
197 param = *((__u8 *) sent);
198
199 if (!status) {
200 if (param)
201 set_bit(HCI_ENCRYPT, &hdev->flags);
202 else
203 clear_bit(HCI_ENCRYPT, &hdev->flags);
204 }
205 hci_req_complete(hdev, status);
206 break;
207
208 case OCF_WRITE_CA_TIMEOUT:
209 status = *((__u8 *) skb->data);
210 if (status) {
211 BT_DBG("%s OCF_WRITE_CA_TIMEOUT failed %d", hdev->name, status);
212 } else {
213 BT_DBG("%s OCF_WRITE_CA_TIMEOUT succeseful", hdev->name);
214 }
215 break;
216
217 case OCF_WRITE_PG_TIMEOUT:
218 status = *((__u8 *) skb->data);
219 if (status) {
220 BT_DBG("%s OCF_WRITE_PG_TIMEOUT failed %d", hdev->name, status);
221 } else {
222 BT_DBG("%s: OCF_WRITE_PG_TIMEOUT succeseful", hdev->name);
223 }
224 break;
225
226 case OCF_WRITE_SCAN_ENABLE:
227 sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_SCAN_ENABLE);
228 if (!sent)
229 break;
230
231 status = *((__u8 *) skb->data);
232 param = *((__u8 *) sent);
233
234 BT_DBG("param 0x%x", param);
235
236 if (!status) {
237 clear_bit(HCI_PSCAN, &hdev->flags);
238 clear_bit(HCI_ISCAN, &hdev->flags);
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900239 if (param & SCAN_INQUIRY)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700240 set_bit(HCI_ISCAN, &hdev->flags);
241
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900242 if (param & SCAN_PAGE)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700243 set_bit(HCI_PSCAN, &hdev->flags);
244 }
245 hci_req_complete(hdev, status);
246 break;
247
248 case OCF_READ_VOICE_SETTING:
249 vs = (struct hci_rp_read_voice_setting *) skb->data;
250
251 if (vs->status) {
252 BT_DBG("%s READ_VOICE_SETTING failed %d", hdev->name, vs->status);
253 break;
254 }
255
256 setting = __le16_to_cpu(vs->voice_setting);
257
258 if (hdev->voice_setting != setting ) {
259 hdev->voice_setting = setting;
260
261 BT_DBG("%s: voice setting 0x%04x", hdev->name, setting);
262
263 if (hdev->notify) {
264 tasklet_disable(&hdev->tx_task);
265 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
266 tasklet_enable(&hdev->tx_task);
267 }
268 }
269 break;
270
271 case OCF_WRITE_VOICE_SETTING:
272 sent = hci_sent_cmd_data(hdev, OGF_HOST_CTL, OCF_WRITE_VOICE_SETTING);
273 if (!sent)
274 break;
275
276 status = *((__u8 *) skb->data);
Marcel Holtmann1ebb9252005-11-08 09:57:21 -0800277 setting = __le16_to_cpu(get_unaligned((__le16 *) sent));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700278
279 if (!status && hdev->voice_setting != setting) {
280 hdev->voice_setting = setting;
281
282 BT_DBG("%s: voice setting 0x%04x", hdev->name, setting);
283
284 if (hdev->notify) {
285 tasklet_disable(&hdev->tx_task);
286 hdev->notify(hdev, HCI_NOTIFY_VOICE_SETTING);
287 tasklet_enable(&hdev->tx_task);
288 }
289 }
290 hci_req_complete(hdev, status);
291 break;
292
293 case OCF_HOST_BUFFER_SIZE:
294 status = *((__u8 *) skb->data);
295 if (status) {
296 BT_DBG("%s OCF_BUFFER_SIZE failed %d", hdev->name, status);
297 hci_req_complete(hdev, status);
298 }
299 break;
300
301 default:
302 BT_DBG("%s Command complete: ogf HOST_CTL ocf %x", hdev->name, ocf);
303 break;
304 }
305}
306
307/* Command Complete OGF INFO_PARAM */
308static void hci_cc_info_param(struct hci_dev *hdev, __u16 ocf, struct sk_buff *skb)
309{
Marcel Holtmann1143e5a2006-09-23 09:57:20 +0200310 struct hci_rp_read_loc_version *lv;
Marcel Holtmann04837f62006-07-03 10:02:33 +0200311 struct hci_rp_read_local_features *lf;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700312 struct hci_rp_read_buffer_size *bs;
313 struct hci_rp_read_bd_addr *ba;
314
315 BT_DBG("%s ocf 0x%x", hdev->name, ocf);
316
317 switch (ocf) {
Marcel Holtmann1143e5a2006-09-23 09:57:20 +0200318 case OCF_READ_LOCAL_VERSION:
319 lv = (struct hci_rp_read_loc_version *) skb->data;
320
321 if (lv->status) {
322 BT_DBG("%s READ_LOCAL_VERSION failed %d", hdev->name, lf->status);
323 break;
324 }
325
326 hdev->hci_ver = lv->hci_ver;
327 hdev->hci_rev = btohs(lv->hci_rev);
328 hdev->manufacturer = btohs(lv->manufacturer);
329
330 BT_DBG("%s: manufacturer %d hci_ver %d hci_rev %d", hdev->name,
331 hdev->manufacturer, hdev->hci_ver, hdev->hci_rev);
332
333 break;
334
Linus Torvalds1da177e2005-04-16 15:20:36 -0700335 case OCF_READ_LOCAL_FEATURES:
Marcel Holtmann04837f62006-07-03 10:02:33 +0200336 lf = (struct hci_rp_read_local_features *) skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700337
338 if (lf->status) {
339 BT_DBG("%s READ_LOCAL_FEATURES failed %d", hdev->name, lf->status);
340 break;
341 }
342
343 memcpy(hdev->features, lf->features, sizeof(hdev->features));
344
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900345 /* Adjust default settings according to features
Linus Torvalds1da177e2005-04-16 15:20:36 -0700346 * supported by device. */
347 if (hdev->features[0] & LMP_3SLOT)
348 hdev->pkt_type |= (HCI_DM3 | HCI_DH3);
349
350 if (hdev->features[0] & LMP_5SLOT)
351 hdev->pkt_type |= (HCI_DM5 | HCI_DH5);
352
353 if (hdev->features[1] & LMP_HV2)
354 hdev->pkt_type |= (HCI_HV2);
355
356 if (hdev->features[1] & LMP_HV3)
357 hdev->pkt_type |= (HCI_HV3);
358
Marcel Holtmann1143e5a2006-09-23 09:57:20 +0200359 BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name,
360 lf->features[0], lf->features[1], lf->features[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700361
362 break;
363
364 case OCF_READ_BUFFER_SIZE:
365 bs = (struct hci_rp_read_buffer_size *) skb->data;
366
367 if (bs->status) {
368 BT_DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
369 hci_req_complete(hdev, bs->status);
370 break;
371 }
372
373 hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu);
Marcel Holtmannda1f5192006-07-03 10:02:29 +0200374 hdev->sco_mtu = bs->sco_mtu;
375 hdev->acl_pkts = __le16_to_cpu(bs->acl_max_pkt);
376 hdev->sco_pkts = __le16_to_cpu(bs->sco_max_pkt);
377
378 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
379 hdev->sco_mtu = 64;
380 hdev->sco_pkts = 8;
381 }
382
383 hdev->acl_cnt = hdev->acl_pkts;
384 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700385
386 BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
387 hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
388 break;
389
390 case OCF_READ_BD_ADDR:
391 ba = (struct hci_rp_read_bd_addr *) skb->data;
392
393 if (!ba->status) {
394 bacpy(&hdev->bdaddr, &ba->bdaddr);
395 } else {
396 BT_DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
397 }
398
399 hci_req_complete(hdev, ba->status);
400 break;
401
402 default:
403 BT_DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
404 break;
405 }
406}
407
408/* Command Status OGF LINK_CTL */
409static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
410{
411 struct hci_conn *conn;
412 struct hci_cp_create_conn *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
413
414 if (!cp)
415 return;
416
417 hci_dev_lock(hdev);
418
419 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
420
421 BT_DBG("%s status 0x%x bdaddr %s conn %p", hdev->name,
422 status, batostr(&cp->bdaddr), conn);
423
424 if (status) {
425 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +0200426 if (status != 0x0c || conn->attempt > 2) {
427 conn->state = BT_CLOSED;
428 hci_proto_connect_cfm(conn, status);
429 hci_conn_del(conn);
430 } else
431 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 }
433 } else {
434 if (!conn) {
435 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
436 if (conn) {
437 conn->out = 1;
438 conn->link_mode |= HCI_LM_MASTER;
439 } else
440 BT_ERR("No memmory for new connection");
441 }
442 }
443
444 hci_dev_unlock(hdev);
445}
446
447static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
448{
449 BT_DBG("%s ocf 0x%x", hdev->name, ocf);
450
451 switch (ocf) {
452 case OCF_CREATE_CONN:
453 hci_cs_create_conn(hdev, status);
454 break;
455
456 case OCF_ADD_SCO:
457 if (status) {
458 struct hci_conn *acl, *sco;
459 struct hci_cp_add_sco *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_ADD_SCO);
460 __u16 handle;
461
462 if (!cp)
463 break;
464
465 handle = __le16_to_cpu(cp->handle);
466
467 BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status);
468
469 hci_dev_lock(hdev);
470
471 acl = hci_conn_hash_lookup_handle(hdev, handle);
472 if (acl && (sco = acl->link)) {
473 sco->state = BT_CLOSED;
474
475 hci_proto_connect_cfm(sco, status);
476 hci_conn_del(sco);
477 }
478
479 hci_dev_unlock(hdev);
480 }
481 break;
482
483 case OCF_INQUIRY:
484 if (status) {
485 BT_DBG("%s Inquiry error: status 0x%x", hdev->name, status);
486 hci_req_complete(hdev, status);
487 } else {
488 set_bit(HCI_INQUIRY, &hdev->flags);
489 }
490 break;
491
492 default:
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900493 BT_DBG("%s Command status: ogf LINK_CTL ocf %x status %d",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700494 hdev->name, ocf, status);
495 break;
496 }
497}
498
499/* Command Status OGF LINK_POLICY */
500static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
501{
502 BT_DBG("%s ocf 0x%x", hdev->name, ocf);
503
504 switch (ocf) {
Marcel Holtmann04837f62006-07-03 10:02:33 +0200505 case OCF_SNIFF_MODE:
506 if (status) {
507 struct hci_conn *conn;
508 struct hci_cp_sniff_mode *cp = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_SNIFF_MODE);
509
510 if (!cp)
511 break;
512
513 hci_dev_lock(hdev);
514
515 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
516 if (conn) {
517 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
518 }
519
520 hci_dev_unlock(hdev);
521 }
522 break;
523
524 case OCF_EXIT_SNIFF_MODE:
525 if (status) {
526 struct hci_conn *conn;
527 struct hci_cp_exit_sniff_mode *cp = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_EXIT_SNIFF_MODE);
528
529 if (!cp)
530 break;
531
532 hci_dev_lock(hdev);
533
534 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
535 if (conn) {
536 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
537 }
538
539 hci_dev_unlock(hdev);
540 }
541 break;
542
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 default:
Marcel Holtmann04837f62006-07-03 10:02:33 +0200544 BT_DBG("%s Command status: ogf LINK_POLICY ocf %x", hdev->name, ocf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700545 break;
546 }
547}
548
549/* Command Status OGF HOST_CTL */
550static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
551{
552 BT_DBG("%s ocf 0x%x", hdev->name, ocf);
553
554 switch (ocf) {
555 default:
556 BT_DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
557 break;
558 }
559}
560
561/* Command Status OGF INFO_PARAM */
562static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
563{
564 BT_DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
565
566 switch (ocf) {
567 default:
568 BT_DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
569 break;
570 }
571}
572
573/* Inquiry Complete */
574static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
575{
576 __u8 status = *((__u8 *) skb->data);
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100577 struct hci_conn *pend;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578
579 BT_DBG("%s status %d", hdev->name, status);
580
581 clear_bit(HCI_INQUIRY, &hdev->flags);
582 hci_req_complete(hdev, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100583
584 hci_dev_lock(hdev);
585
586 pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
587 if (pend)
588 hci_acl_connect(pend);
589
590 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591}
592
593/* Inquiry Result */
594static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
595{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700596 struct inquiry_data data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700597 struct inquiry_info *info = (struct inquiry_info *) (skb->data + 1);
598 int num_rsp = *((__u8 *) skb->data);
599
600 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
601
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700602 if (!num_rsp)
603 return;
604
Linus Torvalds1da177e2005-04-16 15:20:36 -0700605 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700606
Linus Torvalds1da177e2005-04-16 15:20:36 -0700607 for (; num_rsp; num_rsp--) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700608 bacpy(&data.bdaddr, &info->bdaddr);
609 data.pscan_rep_mode = info->pscan_rep_mode;
610 data.pscan_period_mode = info->pscan_period_mode;
611 data.pscan_mode = info->pscan_mode;
612 memcpy(data.dev_class, info->dev_class, 3);
613 data.clock_offset = info->clock_offset;
614 data.rssi = 0x00;
615 info++;
616 hci_inquiry_cache_update(hdev, &data);
617 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700618
Linus Torvalds1da177e2005-04-16 15:20:36 -0700619 hci_dev_unlock(hdev);
620}
621
622/* Inquiry Result With RSSI */
623static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
624{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700625 struct inquiry_data data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700626 int num_rsp = *((__u8 *) skb->data);
627
628 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
629
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700630 if (!num_rsp)
631 return;
632
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700634
635 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
636 struct inquiry_info_with_rssi_and_pscan_mode *info =
637 (struct inquiry_info_with_rssi_and_pscan_mode *) (skb->data + 1);
638
639 for (; num_rsp; num_rsp--) {
640 bacpy(&data.bdaddr, &info->bdaddr);
641 data.pscan_rep_mode = info->pscan_rep_mode;
642 data.pscan_period_mode = info->pscan_period_mode;
643 data.pscan_mode = info->pscan_mode;
644 memcpy(data.dev_class, info->dev_class, 3);
645 data.clock_offset = info->clock_offset;
646 data.rssi = info->rssi;
647 info++;
648 hci_inquiry_cache_update(hdev, &data);
649 }
650 } else {
651 struct inquiry_info_with_rssi *info =
652 (struct inquiry_info_with_rssi *) (skb->data + 1);
653
654 for (; num_rsp; num_rsp--) {
655 bacpy(&data.bdaddr, &info->bdaddr);
656 data.pscan_rep_mode = info->pscan_rep_mode;
657 data.pscan_period_mode = info->pscan_period_mode;
658 data.pscan_mode = 0x00;
659 memcpy(data.dev_class, info->dev_class, 3);
660 data.clock_offset = info->clock_offset;
661 data.rssi = info->rssi;
662 info++;
663 hci_inquiry_cache_update(hdev, &data);
664 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700665 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700666
Linus Torvalds1da177e2005-04-16 15:20:36 -0700667 hci_dev_unlock(hdev);
668}
669
Marcel Holtmann21d9e302005-09-13 01:32:25 +0200670/* Extended Inquiry Result */
671static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
672{
673 struct inquiry_data data;
674 struct extended_inquiry_info *info = (struct extended_inquiry_info *) (skb->data + 1);
675 int num_rsp = *((__u8 *) skb->data);
676
677 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
678
679 if (!num_rsp)
680 return;
681
682 hci_dev_lock(hdev);
683
684 for (; num_rsp; num_rsp--) {
685 bacpy(&data.bdaddr, &info->bdaddr);
686 data.pscan_rep_mode = info->pscan_rep_mode;
687 data.pscan_period_mode = info->pscan_period_mode;
688 data.pscan_mode = 0x00;
689 memcpy(data.dev_class, info->dev_class, 3);
690 data.clock_offset = info->clock_offset;
691 data.rssi = info->rssi;
692 info++;
693 hci_inquiry_cache_update(hdev, &data);
694 }
695
696 hci_dev_unlock(hdev);
697}
698
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699/* Connect Request */
700static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
701{
702 struct hci_ev_conn_request *ev = (struct hci_ev_conn_request *) skb->data;
703 int mask = hdev->link_mode;
704
705 BT_DBG("%s Connection request: %s type 0x%x", hdev->name,
706 batostr(&ev->bdaddr), ev->link_type);
707
708 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
709
710 if (mask & HCI_LM_ACCEPT) {
711 /* Connection accepted */
712 struct hci_conn *conn;
713 struct hci_cp_accept_conn_req cp;
714
715 hci_dev_lock(hdev);
716 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
717 if (!conn) {
718 if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
719 BT_ERR("No memmory for new connection");
720 hci_dev_unlock(hdev);
721 return;
722 }
723 }
724 memcpy(conn->dev_class, ev->dev_class, 3);
725 conn->state = BT_CONNECT;
726 hci_dev_unlock(hdev);
727
728 bacpy(&cp.bdaddr, &ev->bdaddr);
729
730 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
731 cp.role = 0x00; /* Become master */
732 else
733 cp.role = 0x01; /* Remain slave */
734
Marcel Holtmann04837f62006-07-03 10:02:33 +0200735 hci_send_cmd(hdev, OGF_LINK_CTL,
736 OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700737 } else {
738 /* Connection rejected */
739 struct hci_cp_reject_conn_req cp;
740
741 bacpy(&cp.bdaddr, &ev->bdaddr);
742 cp.reason = 0x0f;
Marcel Holtmann04837f62006-07-03 10:02:33 +0200743 hci_send_cmd(hdev, OGF_LINK_CTL,
744 OCF_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700745 }
746}
747
748/* Connect Complete */
749static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
750{
751 struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data;
Marcel Holtmann4c67bc72006-10-15 17:30:56 +0200752 struct hci_conn *conn, *pend;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700753
754 BT_DBG("%s", hdev->name);
755
756 hci_dev_lock(hdev);
757
758 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
759 if (!conn) {
760 hci_dev_unlock(hdev);
761 return;
762 }
763
764 if (!ev->status) {
765 conn->handle = __le16_to_cpu(ev->handle);
766 conn->state = BT_CONNECTED;
767
768 if (test_bit(HCI_AUTH, &hdev->flags))
769 conn->link_mode |= HCI_LM_AUTH;
770
771 if (test_bit(HCI_ENCRYPT, &hdev->flags))
772 conn->link_mode |= HCI_LM_ENCRYPT;
773
Marcel Holtmann04837f62006-07-03 10:02:33 +0200774 /* Get remote features */
775 if (conn->type == ACL_LINK) {
776 struct hci_cp_read_remote_features cp;
777 cp.handle = ev->handle;
778 hci_send_cmd(hdev, OGF_LINK_CTL,
779 OCF_READ_REMOTE_FEATURES, sizeof(cp), &cp);
780 }
781
Linus Torvalds1da177e2005-04-16 15:20:36 -0700782 /* Set link policy */
783 if (conn->type == ACL_LINK && hdev->link_policy) {
784 struct hci_cp_write_link_policy cp;
785 cp.handle = ev->handle;
786 cp.policy = __cpu_to_le16(hdev->link_policy);
Marcel Holtmann04837f62006-07-03 10:02:33 +0200787 hci_send_cmd(hdev, OGF_LINK_POLICY,
788 OCF_WRITE_LINK_POLICY, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700789 }
790
791 /* Set packet type for incoming connection */
792 if (!conn->out) {
793 struct hci_cp_change_conn_ptype cp;
794 cp.handle = ev->handle;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900795 cp.pkt_type = (conn->type == ACL_LINK) ?
Linus Torvalds1da177e2005-04-16 15:20:36 -0700796 __cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK):
797 __cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
798
Marcel Holtmann04837f62006-07-03 10:02:33 +0200799 hci_send_cmd(hdev, OGF_LINK_CTL,
800 OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp);
Marcel Holtmann37e97b42006-09-28 15:29:09 -0700801 } else {
802 /* Update disconnect timer */
803 hci_conn_hold(conn);
804 hci_conn_put(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 }
806 } else
807 conn->state = BT_CLOSED;
808
809 if (conn->type == ACL_LINK) {
810 struct hci_conn *sco = conn->link;
811 if (sco) {
812 if (!ev->status)
813 hci_add_sco(sco, conn->handle);
814 else {
815 hci_proto_connect_cfm(sco, ev->status);
816 hci_conn_del(sco);
817 }
818 }
819 }
820
821 hci_proto_connect_cfm(conn, ev->status);
822 if (ev->status)
823 hci_conn_del(conn);
824
Marcel Holtmann4c67bc72006-10-15 17:30:56 +0200825 pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
826 if (pend)
827 hci_acl_connect(pend);
828
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829 hci_dev_unlock(hdev);
830}
831
832/* Disconnect Complete */
833static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
834{
835 struct hci_ev_disconn_complete *ev = (struct hci_ev_disconn_complete *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +0200836 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700837
838 BT_DBG("%s status %d", hdev->name, ev->status);
839
840 if (ev->status)
841 return;
842
843 hci_dev_lock(hdev);
844
Marcel Holtmann04837f62006-07-03 10:02:33 +0200845 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846 if (conn) {
847 conn->state = BT_CLOSED;
848 hci_proto_disconn_ind(conn, ev->reason);
849 hci_conn_del(conn);
850 }
851
852 hci_dev_unlock(hdev);
853}
854
855/* Number of completed packets */
856static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
857{
858 struct hci_ev_num_comp_pkts *ev = (struct hci_ev_num_comp_pkts *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -0800859 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700860 int i;
861
862 skb_pull(skb, sizeof(*ev));
863
864 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
865
866 if (skb->len < ev->num_hndl * 4) {
867 BT_DBG("%s bad parameters", hdev->name);
868 return;
869 }
870
871 tasklet_disable(&hdev->tx_task);
872
Marcel Holtmann1ebb9252005-11-08 09:57:21 -0800873 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 struct hci_conn *conn;
875 __u16 handle, count;
876
877 handle = __le16_to_cpu(get_unaligned(ptr++));
878 count = __le16_to_cpu(get_unaligned(ptr++));
879
880 conn = hci_conn_hash_lookup_handle(hdev, handle);
881 if (conn) {
882 conn->sent -= count;
883
884 if (conn->type == SCO_LINK) {
885 if ((hdev->sco_cnt += count) > hdev->sco_pkts)
886 hdev->sco_cnt = hdev->sco_pkts;
887 } else {
888 if ((hdev->acl_cnt += count) > hdev->acl_pkts)
889 hdev->acl_cnt = hdev->acl_pkts;
890 }
891 }
892 }
893 hci_sched_tx(hdev);
894
895 tasklet_enable(&hdev->tx_task);
896}
897
898/* Role Change */
899static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
900{
901 struct hci_ev_role_change *ev = (struct hci_ev_role_change *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +0200902 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903
904 BT_DBG("%s status %d", hdev->name, ev->status);
905
906 hci_dev_lock(hdev);
907
908 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
909 if (conn) {
910 if (!ev->status) {
911 if (ev->role)
912 conn->link_mode &= ~HCI_LM_MASTER;
913 else
914 conn->link_mode |= HCI_LM_MASTER;
915 }
916
917 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
918
919 hci_role_switch_cfm(conn, ev->status, ev->role);
920 }
921
922 hci_dev_unlock(hdev);
923}
924
Marcel Holtmann04837f62006-07-03 10:02:33 +0200925/* Mode Change */
926static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700927{
Marcel Holtmann04837f62006-07-03 10:02:33 +0200928 struct hci_ev_mode_change *ev = (struct hci_ev_mode_change *) skb->data;
929 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930
931 BT_DBG("%s status %d", hdev->name, ev->status);
932
933 hci_dev_lock(hdev);
934
Marcel Holtmann04837f62006-07-03 10:02:33 +0200935 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
936 if (conn) {
937 conn->mode = ev->mode;
938 conn->interval = __le16_to_cpu(ev->interval);
939
940 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
941 if (conn->mode == HCI_CM_ACTIVE)
942 conn->power_save = 1;
943 else
944 conn->power_save = 0;
945 }
946 }
947
948 hci_dev_unlock(hdev);
949}
950
951/* Authentication Complete */
952static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
953{
954 struct hci_ev_auth_complete *ev = (struct hci_ev_auth_complete *) skb->data;
955 struct hci_conn *conn;
956
957 BT_DBG("%s status %d", hdev->name, ev->status);
958
959 hci_dev_lock(hdev);
960
961 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962 if (conn) {
963 if (!ev->status)
964 conn->link_mode |= HCI_LM_AUTH;
965
966 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
967
968 hci_auth_cfm(conn, ev->status);
969
970 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
971 if (!ev->status) {
972 struct hci_cp_set_conn_encrypt cp;
973 cp.handle = __cpu_to_le16(conn->handle);
974 cp.encrypt = 1;
975 hci_send_cmd(conn->hdev, OGF_LINK_CTL,
Marcel Holtmann04837f62006-07-03 10:02:33 +0200976 OCF_SET_CONN_ENCRYPT, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977 } else {
978 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
979 hci_encrypt_cfm(conn, ev->status, 0x00);
980 }
981 }
982 }
983
984 hci_dev_unlock(hdev);
985}
986
987/* Encryption Change */
988static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
989{
990 struct hci_ev_encrypt_change *ev = (struct hci_ev_encrypt_change *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +0200991 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700992
993 BT_DBG("%s status %d", hdev->name, ev->status);
994
995 hci_dev_lock(hdev);
996
Marcel Holtmann04837f62006-07-03 10:02:33 +0200997 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998 if (conn) {
999 if (!ev->status) {
1000 if (ev->encrypt)
1001 conn->link_mode |= HCI_LM_ENCRYPT;
1002 else
1003 conn->link_mode &= ~HCI_LM_ENCRYPT;
1004 }
1005
1006 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1007
1008 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
1009 }
1010
1011 hci_dev_unlock(hdev);
1012}
1013
1014/* Change Connection Link Key Complete */
1015static inline void hci_change_conn_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1016{
1017 struct hci_ev_change_conn_link_key_complete *ev = (struct hci_ev_change_conn_link_key_complete *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001018 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001019
1020 BT_DBG("%s status %d", hdev->name, ev->status);
1021
1022 hci_dev_lock(hdev);
1023
Marcel Holtmann04837f62006-07-03 10:02:33 +02001024 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 if (conn) {
1026 if (!ev->status)
1027 conn->link_mode |= HCI_LM_SECURE;
1028
1029 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1030
1031 hci_key_change_cfm(conn, ev->status);
1032 }
1033
1034 hci_dev_unlock(hdev);
1035}
1036
1037/* Pin Code Request*/
1038static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1039{
1040}
1041
1042/* Link Key Request */
1043static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1044{
1045}
1046
1047/* Link Key Notification */
1048static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
1049{
1050}
1051
Marcel Holtmann04837f62006-07-03 10:02:33 +02001052/* Remote Features */
1053static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054{
Marcel Holtmann04837f62006-07-03 10:02:33 +02001055 struct hci_ev_remote_features *ev = (struct hci_ev_remote_features *) skb->data;
1056 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057
1058 BT_DBG("%s status %d", hdev->name, ev->status);
1059
1060 hci_dev_lock(hdev);
1061
Marcel Holtmann04837f62006-07-03 10:02:33 +02001062 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1063 if (conn && !ev->status) {
1064 memcpy(conn->features, ev->features, sizeof(conn->features));
1065 }
1066
1067 hci_dev_unlock(hdev);
1068}
1069
1070/* Clock Offset */
1071static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
1072{
1073 struct hci_ev_clock_offset *ev = (struct hci_ev_clock_offset *) skb->data;
1074 struct hci_conn *conn;
1075
1076 BT_DBG("%s status %d", hdev->name, ev->status);
1077
1078 hci_dev_lock(hdev);
1079
1080 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001081 if (conn && !ev->status) {
1082 struct inquiry_entry *ie;
1083
1084 if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) {
1085 ie->data.clock_offset = ev->clock_offset;
1086 ie->timestamp = jiffies;
1087 }
1088 }
1089
1090 hci_dev_unlock(hdev);
1091}
1092
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001093/* Page Scan Repetition Mode */
1094static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
1095{
1096 struct hci_ev_pscan_rep_mode *ev = (struct hci_ev_pscan_rep_mode *) skb->data;
1097 struct inquiry_entry *ie;
1098
1099 BT_DBG("%s", hdev->name);
1100
1101 hci_dev_lock(hdev);
1102
1103 if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) {
1104 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
1105 ie->timestamp = jiffies;
1106 }
1107
1108 hci_dev_unlock(hdev);
1109}
1110
Marcel Holtmann04837f62006-07-03 10:02:33 +02001111/* Sniff Subrate */
1112static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
1113{
1114 struct hci_ev_sniff_subrate *ev = (struct hci_ev_sniff_subrate *) skb->data;
1115 struct hci_conn *conn;
1116
1117 BT_DBG("%s status %d", hdev->name, ev->status);
1118
1119 hci_dev_lock(hdev);
1120
1121 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1122 if (conn) {
1123 }
1124
1125 hci_dev_unlock(hdev);
1126}
1127
Linus Torvalds1da177e2005-04-16 15:20:36 -07001128void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
1129{
1130 struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data;
1131 struct hci_ev_cmd_complete *ec;
1132 struct hci_ev_cmd_status *cs;
1133 u16 opcode, ocf, ogf;
1134
1135 skb_pull(skb, HCI_EVENT_HDR_SIZE);
1136
1137 BT_DBG("%s evt 0x%x", hdev->name, hdr->evt);
1138
1139 switch (hdr->evt) {
1140 case HCI_EV_NUM_COMP_PKTS:
1141 hci_num_comp_pkts_evt(hdev, skb);
1142 break;
1143
1144 case HCI_EV_INQUIRY_COMPLETE:
1145 hci_inquiry_complete_evt(hdev, skb);
1146 break;
1147
1148 case HCI_EV_INQUIRY_RESULT:
1149 hci_inquiry_result_evt(hdev, skb);
1150 break;
1151
1152 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
1153 hci_inquiry_result_with_rssi_evt(hdev, skb);
1154 break;
1155
Marcel Holtmann21d9e302005-09-13 01:32:25 +02001156 case HCI_EV_EXTENDED_INQUIRY_RESULT:
1157 hci_extended_inquiry_result_evt(hdev, skb);
1158 break;
1159
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160 case HCI_EV_CONN_REQUEST:
1161 hci_conn_request_evt(hdev, skb);
1162 break;
1163
1164 case HCI_EV_CONN_COMPLETE:
1165 hci_conn_complete_evt(hdev, skb);
1166 break;
1167
1168 case HCI_EV_DISCONN_COMPLETE:
1169 hci_disconn_complete_evt(hdev, skb);
1170 break;
1171
1172 case HCI_EV_ROLE_CHANGE:
1173 hci_role_change_evt(hdev, skb);
1174 break;
1175
Marcel Holtmann04837f62006-07-03 10:02:33 +02001176 case HCI_EV_MODE_CHANGE:
1177 hci_mode_change_evt(hdev, skb);
1178 break;
1179
Linus Torvalds1da177e2005-04-16 15:20:36 -07001180 case HCI_EV_AUTH_COMPLETE:
1181 hci_auth_complete_evt(hdev, skb);
1182 break;
1183
1184 case HCI_EV_ENCRYPT_CHANGE:
1185 hci_encrypt_change_evt(hdev, skb);
1186 break;
1187
1188 case HCI_EV_CHANGE_CONN_LINK_KEY_COMPLETE:
1189 hci_change_conn_link_key_complete_evt(hdev, skb);
1190 break;
1191
1192 case HCI_EV_PIN_CODE_REQ:
1193 hci_pin_code_request_evt(hdev, skb);
1194 break;
1195
1196 case HCI_EV_LINK_KEY_REQ:
1197 hci_link_key_request_evt(hdev, skb);
1198 break;
1199
1200 case HCI_EV_LINK_KEY_NOTIFY:
1201 hci_link_key_notify_evt(hdev, skb);
1202 break;
1203
Marcel Holtmann04837f62006-07-03 10:02:33 +02001204 case HCI_EV_REMOTE_FEATURES:
1205 hci_remote_features_evt(hdev, skb);
1206 break;
1207
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208 case HCI_EV_CLOCK_OFFSET:
1209 hci_clock_offset_evt(hdev, skb);
1210 break;
1211
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001212 case HCI_EV_PSCAN_REP_MODE:
1213 hci_pscan_rep_mode_evt(hdev, skb);
1214 break;
1215
Marcel Holtmann04837f62006-07-03 10:02:33 +02001216 case HCI_EV_SNIFF_SUBRATE:
1217 hci_sniff_subrate_evt(hdev, skb);
1218 break;
1219
Linus Torvalds1da177e2005-04-16 15:20:36 -07001220 case HCI_EV_CMD_STATUS:
1221 cs = (struct hci_ev_cmd_status *) skb->data;
1222 skb_pull(skb, sizeof(cs));
1223
1224 opcode = __le16_to_cpu(cs->opcode);
1225 ogf = hci_opcode_ogf(opcode);
1226 ocf = hci_opcode_ocf(opcode);
1227
1228 switch (ogf) {
1229 case OGF_INFO_PARAM:
1230 hci_cs_info_param(hdev, ocf, cs->status);
1231 break;
1232
1233 case OGF_HOST_CTL:
1234 hci_cs_host_ctl(hdev, ocf, cs->status);
1235 break;
1236
1237 case OGF_LINK_CTL:
1238 hci_cs_link_ctl(hdev, ocf, cs->status);
1239 break;
1240
1241 case OGF_LINK_POLICY:
1242 hci_cs_link_policy(hdev, ocf, cs->status);
1243 break;
1244
1245 default:
1246 BT_DBG("%s Command Status OGF %x", hdev->name, ogf);
1247 break;
1248 }
1249
1250 if (cs->ncmd) {
1251 atomic_set(&hdev->cmd_cnt, 1);
1252 if (!skb_queue_empty(&hdev->cmd_q))
1253 hci_sched_cmd(hdev);
1254 }
1255 break;
1256
1257 case HCI_EV_CMD_COMPLETE:
1258 ec = (struct hci_ev_cmd_complete *) skb->data;
1259 skb_pull(skb, sizeof(*ec));
1260
1261 opcode = __le16_to_cpu(ec->opcode);
1262 ogf = hci_opcode_ogf(opcode);
1263 ocf = hci_opcode_ocf(opcode);
1264
1265 switch (ogf) {
1266 case OGF_INFO_PARAM:
1267 hci_cc_info_param(hdev, ocf, skb);
1268 break;
1269
1270 case OGF_HOST_CTL:
1271 hci_cc_host_ctl(hdev, ocf, skb);
1272 break;
1273
1274 case OGF_LINK_CTL:
1275 hci_cc_link_ctl(hdev, ocf, skb);
1276 break;
1277
1278 case OGF_LINK_POLICY:
1279 hci_cc_link_policy(hdev, ocf, skb);
1280 break;
1281
1282 default:
1283 BT_DBG("%s Command Completed OGF %x", hdev->name, ogf);
1284 break;
1285 }
1286
1287 if (ec->ncmd) {
1288 atomic_set(&hdev->cmd_cnt, 1);
1289 if (!skb_queue_empty(&hdev->cmd_q))
1290 hci_sched_cmd(hdev);
1291 }
1292 break;
1293 }
1294
1295 kfree_skb(skb);
1296 hdev->stat.evt_rx++;
1297}
1298
1299/* Generate internal stack event */
1300void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
1301{
1302 struct hci_event_hdr *hdr;
1303 struct hci_ev_stack_internal *ev;
1304 struct sk_buff *skb;
1305
1306 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
1307 if (!skb)
1308 return;
1309
1310 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
1311 hdr->evt = HCI_EV_STACK_INTERNAL;
1312 hdr->plen = sizeof(*ev) + dlen;
1313
1314 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
1315 ev->type = type;
1316 memcpy(ev->data, data, dlen);
1317
Marcel Holtmann576c7d82005-08-06 12:36:54 +02001318 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07001319 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02001320
Marcel Holtmann0d48d932005-08-09 20:30:28 -07001321 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001322 skb->dev = (void *) hdev;
1323 hci_send_to_sock(hdev, skb);
1324 kfree_skb(skb);
1325}