blob: 4baea1e3865222cff1bb8c2238eafd11712ba39a [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
Marcel Holtmann5b7f9902007-07-11 09:51:55 +0200353 if (hdev->features[1] & LMP_HV2) {
354 hdev->pkt_type |= (HCI_HV2);
355 hdev->esco_type |= (ESCO_HV2);
356 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357
Marcel Holtmann5b7f9902007-07-11 09:51:55 +0200358 if (hdev->features[1] & LMP_HV3) {
359 hdev->pkt_type |= (HCI_HV3);
360 hdev->esco_type |= (ESCO_HV3);
361 }
362
363 if (hdev->features[3] & LMP_ESCO)
364 hdev->esco_type |= (ESCO_EV3);
365
366 if (hdev->features[4] & LMP_EV4)
367 hdev->esco_type |= (ESCO_EV4);
368
369 if (hdev->features[4] & LMP_EV5)
370 hdev->esco_type |= (ESCO_EV5);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371
Marcel Holtmann1143e5a2006-09-23 09:57:20 +0200372 BT_DBG("%s: features 0x%x 0x%x 0x%x", hdev->name,
373 lf->features[0], lf->features[1], lf->features[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700374
375 break;
376
377 case OCF_READ_BUFFER_SIZE:
378 bs = (struct hci_rp_read_buffer_size *) skb->data;
379
380 if (bs->status) {
381 BT_DBG("%s READ_BUFFER_SIZE failed %d", hdev->name, bs->status);
382 hci_req_complete(hdev, bs->status);
383 break;
384 }
385
386 hdev->acl_mtu = __le16_to_cpu(bs->acl_mtu);
Marcel Holtmannda1f5192006-07-03 10:02:29 +0200387 hdev->sco_mtu = bs->sco_mtu;
388 hdev->acl_pkts = __le16_to_cpu(bs->acl_max_pkt);
389 hdev->sco_pkts = __le16_to_cpu(bs->sco_max_pkt);
390
391 if (test_bit(HCI_QUIRK_FIXUP_BUFFER_SIZE, &hdev->quirks)) {
392 hdev->sco_mtu = 64;
393 hdev->sco_pkts = 8;
394 }
395
396 hdev->acl_cnt = hdev->acl_pkts;
397 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700398
399 BT_DBG("%s mtu: acl %d, sco %d max_pkt: acl %d, sco %d", hdev->name,
400 hdev->acl_mtu, hdev->sco_mtu, hdev->acl_pkts, hdev->sco_pkts);
401 break;
402
403 case OCF_READ_BD_ADDR:
404 ba = (struct hci_rp_read_bd_addr *) skb->data;
405
406 if (!ba->status) {
407 bacpy(&hdev->bdaddr, &ba->bdaddr);
408 } else {
409 BT_DBG("%s: READ_BD_ADDR failed %d", hdev->name, ba->status);
410 }
411
412 hci_req_complete(hdev, ba->status);
413 break;
414
415 default:
416 BT_DBG("%s Command complete: ogf INFO_PARAM ocf %x", hdev->name, ocf);
417 break;
418 }
419}
420
421/* Command Status OGF LINK_CTL */
422static inline void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
423{
424 struct hci_conn *conn;
425 struct hci_cp_create_conn *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_CREATE_CONN);
426
427 if (!cp)
428 return;
429
430 hci_dev_lock(hdev);
431
432 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
433
434 BT_DBG("%s status 0x%x bdaddr %s conn %p", hdev->name,
435 status, batostr(&cp->bdaddr), conn);
436
437 if (status) {
438 if (conn && conn->state == BT_CONNECT) {
Marcel Holtmann4c67bc72006-10-15 17:30:56 +0200439 if (status != 0x0c || conn->attempt > 2) {
440 conn->state = BT_CLOSED;
441 hci_proto_connect_cfm(conn, status);
442 hci_conn_del(conn);
443 } else
444 conn->state = BT_CONNECT2;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700445 }
446 } else {
447 if (!conn) {
448 conn = hci_conn_add(hdev, ACL_LINK, &cp->bdaddr);
449 if (conn) {
450 conn->out = 1;
451 conn->link_mode |= HCI_LM_MASTER;
452 } else
453 BT_ERR("No memmory for new connection");
454 }
455 }
456
457 hci_dev_unlock(hdev);
458}
459
460static void hci_cs_link_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
461{
462 BT_DBG("%s ocf 0x%x", hdev->name, ocf);
463
464 switch (ocf) {
465 case OCF_CREATE_CONN:
466 hci_cs_create_conn(hdev, status);
467 break;
468
469 case OCF_ADD_SCO:
470 if (status) {
471 struct hci_conn *acl, *sco;
472 struct hci_cp_add_sco *cp = hci_sent_cmd_data(hdev, OGF_LINK_CTL, OCF_ADD_SCO);
473 __u16 handle;
474
475 if (!cp)
476 break;
477
478 handle = __le16_to_cpu(cp->handle);
479
480 BT_DBG("%s Add SCO error: handle %d status 0x%x", hdev->name, handle, status);
481
482 hci_dev_lock(hdev);
483
484 acl = hci_conn_hash_lookup_handle(hdev, handle);
485 if (acl && (sco = acl->link)) {
486 sco->state = BT_CLOSED;
487
488 hci_proto_connect_cfm(sco, status);
489 hci_conn_del(sco);
490 }
491
492 hci_dev_unlock(hdev);
493 }
494 break;
495
496 case OCF_INQUIRY:
497 if (status) {
498 BT_DBG("%s Inquiry error: status 0x%x", hdev->name, status);
499 hci_req_complete(hdev, status);
500 } else {
501 set_bit(HCI_INQUIRY, &hdev->flags);
502 }
503 break;
504
505 default:
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900506 BT_DBG("%s Command status: ogf LINK_CTL ocf %x status %d",
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507 hdev->name, ocf, status);
508 break;
509 }
510}
511
512/* Command Status OGF LINK_POLICY */
513static void hci_cs_link_policy(struct hci_dev *hdev, __u16 ocf, __u8 status)
514{
515 BT_DBG("%s ocf 0x%x", hdev->name, ocf);
516
517 switch (ocf) {
Marcel Holtmann04837f62006-07-03 10:02:33 +0200518 case OCF_SNIFF_MODE:
519 if (status) {
520 struct hci_conn *conn;
521 struct hci_cp_sniff_mode *cp = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_SNIFF_MODE);
522
523 if (!cp)
524 break;
525
526 hci_dev_lock(hdev);
527
528 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
529 if (conn) {
530 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
531 }
532
533 hci_dev_unlock(hdev);
534 }
535 break;
536
537 case OCF_EXIT_SNIFF_MODE:
538 if (status) {
539 struct hci_conn *conn;
540 struct hci_cp_exit_sniff_mode *cp = hci_sent_cmd_data(hdev, OGF_LINK_POLICY, OCF_EXIT_SNIFF_MODE);
541
542 if (!cp)
543 break;
544
545 hci_dev_lock(hdev);
546
547 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(cp->handle));
548 if (conn) {
549 clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend);
550 }
551
552 hci_dev_unlock(hdev);
553 }
554 break;
555
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556 default:
Marcel Holtmann04837f62006-07-03 10:02:33 +0200557 BT_DBG("%s Command status: ogf LINK_POLICY ocf %x", hdev->name, ocf);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700558 break;
559 }
560}
561
562/* Command Status OGF HOST_CTL */
563static void hci_cs_host_ctl(struct hci_dev *hdev, __u16 ocf, __u8 status)
564{
565 BT_DBG("%s ocf 0x%x", hdev->name, ocf);
566
567 switch (ocf) {
568 default:
569 BT_DBG("%s Command status: ogf HOST_CTL ocf %x", hdev->name, ocf);
570 break;
571 }
572}
573
574/* Command Status OGF INFO_PARAM */
575static void hci_cs_info_param(struct hci_dev *hdev, __u16 ocf, __u8 status)
576{
577 BT_DBG("%s: hci_cs_info_param: ocf 0x%x", hdev->name, ocf);
578
579 switch (ocf) {
580 default:
581 BT_DBG("%s Command status: ogf INFO_PARAM ocf %x", hdev->name, ocf);
582 break;
583 }
584}
585
586/* Inquiry Complete */
587static inline void hci_inquiry_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
588{
589 __u8 status = *((__u8 *) skb->data);
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100590 struct hci_conn *pend;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700591
592 BT_DBG("%s status %d", hdev->name, status);
593
594 clear_bit(HCI_INQUIRY, &hdev->flags);
595 hci_req_complete(hdev, status);
Marcel Holtmann6bd57412006-11-18 22:14:22 +0100596
597 hci_dev_lock(hdev);
598
599 pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
600 if (pend)
601 hci_acl_connect(pend);
602
603 hci_dev_unlock(hdev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700604}
605
606/* Inquiry Result */
607static inline void hci_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
608{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700609 struct inquiry_data data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700610 struct inquiry_info *info = (struct inquiry_info *) (skb->data + 1);
611 int num_rsp = *((__u8 *) skb->data);
612
613 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
614
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700615 if (!num_rsp)
616 return;
617
Linus Torvalds1da177e2005-04-16 15:20:36 -0700618 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700619
Linus Torvalds1da177e2005-04-16 15:20:36 -0700620 for (; num_rsp; num_rsp--) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700621 bacpy(&data.bdaddr, &info->bdaddr);
622 data.pscan_rep_mode = info->pscan_rep_mode;
623 data.pscan_period_mode = info->pscan_period_mode;
624 data.pscan_mode = info->pscan_mode;
625 memcpy(data.dev_class, info->dev_class, 3);
626 data.clock_offset = info->clock_offset;
627 data.rssi = 0x00;
628 info++;
629 hci_inquiry_cache_update(hdev, &data);
630 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700631
Linus Torvalds1da177e2005-04-16 15:20:36 -0700632 hci_dev_unlock(hdev);
633}
634
635/* Inquiry Result With RSSI */
636static inline void hci_inquiry_result_with_rssi_evt(struct hci_dev *hdev, struct sk_buff *skb)
637{
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700638 struct inquiry_data data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639 int num_rsp = *((__u8 *) skb->data);
640
641 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
642
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700643 if (!num_rsp)
644 return;
645
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646 hci_dev_lock(hdev);
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700647
648 if ((skb->len - 1) / num_rsp != sizeof(struct inquiry_info_with_rssi)) {
649 struct inquiry_info_with_rssi_and_pscan_mode *info =
650 (struct inquiry_info_with_rssi_and_pscan_mode *) (skb->data + 1);
651
652 for (; num_rsp; num_rsp--) {
653 bacpy(&data.bdaddr, &info->bdaddr);
654 data.pscan_rep_mode = info->pscan_rep_mode;
655 data.pscan_period_mode = info->pscan_period_mode;
656 data.pscan_mode = info->pscan_mode;
657 memcpy(data.dev_class, info->dev_class, 3);
658 data.clock_offset = info->clock_offset;
659 data.rssi = info->rssi;
660 info++;
661 hci_inquiry_cache_update(hdev, &data);
662 }
663 } else {
664 struct inquiry_info_with_rssi *info =
665 (struct inquiry_info_with_rssi *) (skb->data + 1);
666
667 for (; num_rsp; num_rsp--) {
668 bacpy(&data.bdaddr, &info->bdaddr);
669 data.pscan_rep_mode = info->pscan_rep_mode;
670 data.pscan_period_mode = info->pscan_period_mode;
671 data.pscan_mode = 0x00;
672 memcpy(data.dev_class, info->dev_class, 3);
673 data.clock_offset = info->clock_offset;
674 data.rssi = info->rssi;
675 info++;
676 hci_inquiry_cache_update(hdev, &data);
677 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700678 }
Marcel Holtmann45bb4bf2005-08-09 20:27:49 -0700679
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680 hci_dev_unlock(hdev);
681}
682
Marcel Holtmann21d9e302005-09-13 01:32:25 +0200683/* Extended Inquiry Result */
684static inline void hci_extended_inquiry_result_evt(struct hci_dev *hdev, struct sk_buff *skb)
685{
686 struct inquiry_data data;
687 struct extended_inquiry_info *info = (struct extended_inquiry_info *) (skb->data + 1);
688 int num_rsp = *((__u8 *) skb->data);
689
690 BT_DBG("%s num_rsp %d", hdev->name, num_rsp);
691
692 if (!num_rsp)
693 return;
694
695 hci_dev_lock(hdev);
696
697 for (; num_rsp; num_rsp--) {
698 bacpy(&data.bdaddr, &info->bdaddr);
699 data.pscan_rep_mode = info->pscan_rep_mode;
700 data.pscan_period_mode = info->pscan_period_mode;
701 data.pscan_mode = 0x00;
702 memcpy(data.dev_class, info->dev_class, 3);
703 data.clock_offset = info->clock_offset;
704 data.rssi = info->rssi;
705 info++;
706 hci_inquiry_cache_update(hdev, &data);
707 }
708
709 hci_dev_unlock(hdev);
710}
711
Linus Torvalds1da177e2005-04-16 15:20:36 -0700712/* Connect Request */
713static inline void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
714{
715 struct hci_ev_conn_request *ev = (struct hci_ev_conn_request *) skb->data;
716 int mask = hdev->link_mode;
717
718 BT_DBG("%s Connection request: %s type 0x%x", hdev->name,
719 batostr(&ev->bdaddr), ev->link_type);
720
721 mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
722
723 if (mask & HCI_LM_ACCEPT) {
724 /* Connection accepted */
725 struct hci_conn *conn;
726 struct hci_cp_accept_conn_req cp;
727
728 hci_dev_lock(hdev);
729 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
730 if (!conn) {
731 if (!(conn = hci_conn_add(hdev, ev->link_type, &ev->bdaddr))) {
732 BT_ERR("No memmory for new connection");
733 hci_dev_unlock(hdev);
734 return;
735 }
736 }
737 memcpy(conn->dev_class, ev->dev_class, 3);
738 conn->state = BT_CONNECT;
739 hci_dev_unlock(hdev);
740
741 bacpy(&cp.bdaddr, &ev->bdaddr);
742
743 if (lmp_rswitch_capable(hdev) && (mask & HCI_LM_MASTER))
744 cp.role = 0x00; /* Become master */
745 else
746 cp.role = 0x01; /* Remain slave */
747
Marcel Holtmann04837f62006-07-03 10:02:33 +0200748 hci_send_cmd(hdev, OGF_LINK_CTL,
749 OCF_ACCEPT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700750 } else {
751 /* Connection rejected */
752 struct hci_cp_reject_conn_req cp;
753
754 bacpy(&cp.bdaddr, &ev->bdaddr);
755 cp.reason = 0x0f;
Marcel Holtmann04837f62006-07-03 10:02:33 +0200756 hci_send_cmd(hdev, OGF_LINK_CTL,
757 OCF_REJECT_CONN_REQ, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700758 }
759}
760
761/* Connect Complete */
762static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
763{
764 struct hci_ev_conn_complete *ev = (struct hci_ev_conn_complete *) skb->data;
Marcel Holtmann4c67bc72006-10-15 17:30:56 +0200765 struct hci_conn *conn, *pend;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700766
767 BT_DBG("%s", hdev->name);
768
769 hci_dev_lock(hdev);
770
771 conn = hci_conn_hash_lookup_ba(hdev, ev->link_type, &ev->bdaddr);
772 if (!conn) {
773 hci_dev_unlock(hdev);
774 return;
775 }
776
777 if (!ev->status) {
778 conn->handle = __le16_to_cpu(ev->handle);
779 conn->state = BT_CONNECTED;
780
781 if (test_bit(HCI_AUTH, &hdev->flags))
782 conn->link_mode |= HCI_LM_AUTH;
783
784 if (test_bit(HCI_ENCRYPT, &hdev->flags))
785 conn->link_mode |= HCI_LM_ENCRYPT;
786
Marcel Holtmann04837f62006-07-03 10:02:33 +0200787 /* Get remote features */
788 if (conn->type == ACL_LINK) {
789 struct hci_cp_read_remote_features cp;
790 cp.handle = ev->handle;
791 hci_send_cmd(hdev, OGF_LINK_CTL,
792 OCF_READ_REMOTE_FEATURES, sizeof(cp), &cp);
793 }
794
Linus Torvalds1da177e2005-04-16 15:20:36 -0700795 /* Set link policy */
796 if (conn->type == ACL_LINK && hdev->link_policy) {
797 struct hci_cp_write_link_policy cp;
798 cp.handle = ev->handle;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -0700799 cp.policy = cpu_to_le16(hdev->link_policy);
Marcel Holtmann04837f62006-07-03 10:02:33 +0200800 hci_send_cmd(hdev, OGF_LINK_POLICY,
801 OCF_WRITE_LINK_POLICY, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700802 }
803
804 /* Set packet type for incoming connection */
805 if (!conn->out) {
806 struct hci_cp_change_conn_ptype cp;
807 cp.handle = ev->handle;
YOSHIFUJI Hideaki8e87d142007-02-09 23:24:33 +0900808 cp.pkt_type = (conn->type == ACL_LINK) ?
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -0700809 cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK):
810 cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700811
Marcel Holtmann04837f62006-07-03 10:02:33 +0200812 hci_send_cmd(hdev, OGF_LINK_CTL,
813 OCF_CHANGE_CONN_PTYPE, sizeof(cp), &cp);
Marcel Holtmann37e97b42006-09-28 15:29:09 -0700814 } else {
815 /* Update disconnect timer */
816 hci_conn_hold(conn);
817 hci_conn_put(conn);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818 }
819 } else
820 conn->state = BT_CLOSED;
821
822 if (conn->type == ACL_LINK) {
823 struct hci_conn *sco = conn->link;
824 if (sco) {
825 if (!ev->status)
826 hci_add_sco(sco, conn->handle);
827 else {
828 hci_proto_connect_cfm(sco, ev->status);
829 hci_conn_del(sco);
830 }
831 }
832 }
833
834 hci_proto_connect_cfm(conn, ev->status);
835 if (ev->status)
836 hci_conn_del(conn);
837
Marcel Holtmann4c67bc72006-10-15 17:30:56 +0200838 pend = hci_conn_hash_lookup_state(hdev, ACL_LINK, BT_CONNECT2);
839 if (pend)
840 hci_acl_connect(pend);
841
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842 hci_dev_unlock(hdev);
843}
844
845/* Disconnect Complete */
846static inline void hci_disconn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
847{
848 struct hci_ev_disconn_complete *ev = (struct hci_ev_disconn_complete *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +0200849 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700850
851 BT_DBG("%s status %d", hdev->name, ev->status);
852
853 if (ev->status)
854 return;
855
856 hci_dev_lock(hdev);
857
Marcel Holtmann04837f62006-07-03 10:02:33 +0200858 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859 if (conn) {
860 conn->state = BT_CLOSED;
861 hci_proto_disconn_ind(conn, ev->reason);
862 hci_conn_del(conn);
863 }
864
865 hci_dev_unlock(hdev);
866}
867
868/* Number of completed packets */
869static inline void hci_num_comp_pkts_evt(struct hci_dev *hdev, struct sk_buff *skb)
870{
871 struct hci_ev_num_comp_pkts *ev = (struct hci_ev_num_comp_pkts *) skb->data;
Marcel Holtmann1ebb9252005-11-08 09:57:21 -0800872 __le16 *ptr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700873 int i;
874
875 skb_pull(skb, sizeof(*ev));
876
877 BT_DBG("%s num_hndl %d", hdev->name, ev->num_hndl);
878
879 if (skb->len < ev->num_hndl * 4) {
880 BT_DBG("%s bad parameters", hdev->name);
881 return;
882 }
883
884 tasklet_disable(&hdev->tx_task);
885
Marcel Holtmann1ebb9252005-11-08 09:57:21 -0800886 for (i = 0, ptr = (__le16 *) skb->data; i < ev->num_hndl; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 struct hci_conn *conn;
888 __u16 handle, count;
889
890 handle = __le16_to_cpu(get_unaligned(ptr++));
891 count = __le16_to_cpu(get_unaligned(ptr++));
892
893 conn = hci_conn_hash_lookup_handle(hdev, handle);
894 if (conn) {
895 conn->sent -= count;
896
Marcel Holtmann5b7f9902007-07-11 09:51:55 +0200897 if (conn->type == ACL_LINK) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898 if ((hdev->acl_cnt += count) > hdev->acl_pkts)
899 hdev->acl_cnt = hdev->acl_pkts;
Marcel Holtmann5b7f9902007-07-11 09:51:55 +0200900 } else {
901 if ((hdev->sco_cnt += count) > hdev->sco_pkts)
902 hdev->sco_cnt = hdev->sco_pkts;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700903 }
904 }
905 }
906 hci_sched_tx(hdev);
907
908 tasklet_enable(&hdev->tx_task);
909}
910
911/* Role Change */
912static inline void hci_role_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
913{
914 struct hci_ev_role_change *ev = (struct hci_ev_role_change *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +0200915 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700916
917 BT_DBG("%s status %d", hdev->name, ev->status);
918
919 hci_dev_lock(hdev);
920
921 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &ev->bdaddr);
922 if (conn) {
923 if (!ev->status) {
924 if (ev->role)
925 conn->link_mode &= ~HCI_LM_MASTER;
926 else
927 conn->link_mode |= HCI_LM_MASTER;
928 }
929
930 clear_bit(HCI_CONN_RSWITCH_PEND, &conn->pend);
931
932 hci_role_switch_cfm(conn, ev->status, ev->role);
933 }
934
935 hci_dev_unlock(hdev);
936}
937
Marcel Holtmann04837f62006-07-03 10:02:33 +0200938/* Mode Change */
939static inline void hci_mode_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700940{
Marcel Holtmann04837f62006-07-03 10:02:33 +0200941 struct hci_ev_mode_change *ev = (struct hci_ev_mode_change *) skb->data;
942 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700943
944 BT_DBG("%s status %d", hdev->name, ev->status);
945
946 hci_dev_lock(hdev);
947
Marcel Holtmann04837f62006-07-03 10:02:33 +0200948 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
949 if (conn) {
950 conn->mode = ev->mode;
951 conn->interval = __le16_to_cpu(ev->interval);
952
953 if (!test_and_clear_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
954 if (conn->mode == HCI_CM_ACTIVE)
955 conn->power_save = 1;
956 else
957 conn->power_save = 0;
958 }
959 }
960
961 hci_dev_unlock(hdev);
962}
963
964/* Authentication Complete */
965static inline void hci_auth_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
966{
967 struct hci_ev_auth_complete *ev = (struct hci_ev_auth_complete *) skb->data;
968 struct hci_conn *conn;
969
970 BT_DBG("%s status %d", hdev->name, ev->status);
971
972 hci_dev_lock(hdev);
973
974 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975 if (conn) {
976 if (!ev->status)
977 conn->link_mode |= HCI_LM_AUTH;
978
979 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
980
981 hci_auth_cfm(conn, ev->status);
982
983 if (test_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) {
984 if (!ev->status) {
985 struct hci_cp_set_conn_encrypt cp;
YOSHIFUJI Hideakiaca31922007-03-25 20:12:50 -0700986 cp.handle = cpu_to_le16(conn->handle);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987 cp.encrypt = 1;
988 hci_send_cmd(conn->hdev, OGF_LINK_CTL,
Marcel Holtmann04837f62006-07-03 10:02:33 +0200989 OCF_SET_CONN_ENCRYPT, sizeof(cp), &cp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700990 } else {
991 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
992 hci_encrypt_cfm(conn, ev->status, 0x00);
993 }
994 }
995 }
996
997 hci_dev_unlock(hdev);
998}
999
1000/* Encryption Change */
1001static inline void hci_encrypt_change_evt(struct hci_dev *hdev, struct sk_buff *skb)
1002{
1003 struct hci_ev_encrypt_change *ev = (struct hci_ev_encrypt_change *) skb->data;
Marcel Holtmann04837f62006-07-03 10:02:33 +02001004 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001005
1006 BT_DBG("%s status %d", hdev->name, ev->status);
1007
1008 hci_dev_lock(hdev);
1009
Marcel Holtmann04837f62006-07-03 10:02:33 +02001010 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001011 if (conn) {
1012 if (!ev->status) {
1013 if (ev->encrypt)
1014 conn->link_mode |= HCI_LM_ENCRYPT;
1015 else
1016 conn->link_mode &= ~HCI_LM_ENCRYPT;
1017 }
1018
1019 clear_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend);
1020
1021 hci_encrypt_cfm(conn, ev->status, ev->encrypt);
1022 }
1023
1024 hci_dev_unlock(hdev);
1025}
1026
1027/* Change Connection Link Key Complete */
1028static inline void hci_change_conn_link_key_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
1029{
1030 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 +02001031 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001032
1033 BT_DBG("%s status %d", hdev->name, ev->status);
1034
1035 hci_dev_lock(hdev);
1036
Marcel Holtmann04837f62006-07-03 10:02:33 +02001037 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001038 if (conn) {
1039 if (!ev->status)
1040 conn->link_mode |= HCI_LM_SECURE;
1041
1042 clear_bit(HCI_CONN_AUTH_PEND, &conn->pend);
1043
1044 hci_key_change_cfm(conn, ev->status);
1045 }
1046
1047 hci_dev_unlock(hdev);
1048}
1049
1050/* Pin Code Request*/
1051static inline void hci_pin_code_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1052{
1053}
1054
1055/* Link Key Request */
1056static inline void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
1057{
1058}
1059
1060/* Link Key Notification */
1061static inline void hci_link_key_notify_evt(struct hci_dev *hdev, struct sk_buff *skb)
1062{
1063}
1064
Marcel Holtmann04837f62006-07-03 10:02:33 +02001065/* Remote Features */
1066static inline void hci_remote_features_evt(struct hci_dev *hdev, struct sk_buff *skb)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001067{
Marcel Holtmann04837f62006-07-03 10:02:33 +02001068 struct hci_ev_remote_features *ev = (struct hci_ev_remote_features *) skb->data;
1069 struct hci_conn *conn;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001070
1071 BT_DBG("%s status %d", hdev->name, ev->status);
1072
1073 hci_dev_lock(hdev);
1074
Marcel Holtmann04837f62006-07-03 10:02:33 +02001075 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1076 if (conn && !ev->status) {
1077 memcpy(conn->features, ev->features, sizeof(conn->features));
1078 }
1079
1080 hci_dev_unlock(hdev);
1081}
1082
1083/* Clock Offset */
1084static inline void hci_clock_offset_evt(struct hci_dev *hdev, struct sk_buff *skb)
1085{
1086 struct hci_ev_clock_offset *ev = (struct hci_ev_clock_offset *) skb->data;
1087 struct hci_conn *conn;
1088
1089 BT_DBG("%s status %d", hdev->name, ev->status);
1090
1091 hci_dev_lock(hdev);
1092
1093 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094 if (conn && !ev->status) {
1095 struct inquiry_entry *ie;
1096
1097 if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) {
1098 ie->data.clock_offset = ev->clock_offset;
1099 ie->timestamp = jiffies;
1100 }
1101 }
1102
1103 hci_dev_unlock(hdev);
1104}
1105
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001106/* Page Scan Repetition Mode */
1107static inline void hci_pscan_rep_mode_evt(struct hci_dev *hdev, struct sk_buff *skb)
1108{
1109 struct hci_ev_pscan_rep_mode *ev = (struct hci_ev_pscan_rep_mode *) skb->data;
1110 struct inquiry_entry *ie;
1111
1112 BT_DBG("%s", hdev->name);
1113
1114 hci_dev_lock(hdev);
1115
1116 if ((ie = hci_inquiry_cache_lookup(hdev, &ev->bdaddr))) {
1117 ie->data.pscan_rep_mode = ev->pscan_rep_mode;
1118 ie->timestamp = jiffies;
1119 }
1120
1121 hci_dev_unlock(hdev);
1122}
1123
Marcel Holtmann04837f62006-07-03 10:02:33 +02001124/* Sniff Subrate */
1125static inline void hci_sniff_subrate_evt(struct hci_dev *hdev, struct sk_buff *skb)
1126{
1127 struct hci_ev_sniff_subrate *ev = (struct hci_ev_sniff_subrate *) skb->data;
1128 struct hci_conn *conn;
1129
1130 BT_DBG("%s status %d", hdev->name, ev->status);
1131
1132 hci_dev_lock(hdev);
1133
1134 conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(ev->handle));
1135 if (conn) {
1136 }
1137
1138 hci_dev_unlock(hdev);
1139}
1140
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
1142{
1143 struct hci_event_hdr *hdr = (struct hci_event_hdr *) skb->data;
1144 struct hci_ev_cmd_complete *ec;
1145 struct hci_ev_cmd_status *cs;
1146 u16 opcode, ocf, ogf;
1147
1148 skb_pull(skb, HCI_EVENT_HDR_SIZE);
1149
1150 BT_DBG("%s evt 0x%x", hdev->name, hdr->evt);
1151
1152 switch (hdr->evt) {
1153 case HCI_EV_NUM_COMP_PKTS:
1154 hci_num_comp_pkts_evt(hdev, skb);
1155 break;
1156
1157 case HCI_EV_INQUIRY_COMPLETE:
1158 hci_inquiry_complete_evt(hdev, skb);
1159 break;
1160
1161 case HCI_EV_INQUIRY_RESULT:
1162 hci_inquiry_result_evt(hdev, skb);
1163 break;
1164
1165 case HCI_EV_INQUIRY_RESULT_WITH_RSSI:
1166 hci_inquiry_result_with_rssi_evt(hdev, skb);
1167 break;
1168
Marcel Holtmann21d9e302005-09-13 01:32:25 +02001169 case HCI_EV_EXTENDED_INQUIRY_RESULT:
1170 hci_extended_inquiry_result_evt(hdev, skb);
1171 break;
1172
Linus Torvalds1da177e2005-04-16 15:20:36 -07001173 case HCI_EV_CONN_REQUEST:
1174 hci_conn_request_evt(hdev, skb);
1175 break;
1176
1177 case HCI_EV_CONN_COMPLETE:
1178 hci_conn_complete_evt(hdev, skb);
1179 break;
1180
1181 case HCI_EV_DISCONN_COMPLETE:
1182 hci_disconn_complete_evt(hdev, skb);
1183 break;
1184
1185 case HCI_EV_ROLE_CHANGE:
1186 hci_role_change_evt(hdev, skb);
1187 break;
1188
Marcel Holtmann04837f62006-07-03 10:02:33 +02001189 case HCI_EV_MODE_CHANGE:
1190 hci_mode_change_evt(hdev, skb);
1191 break;
1192
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 case HCI_EV_AUTH_COMPLETE:
1194 hci_auth_complete_evt(hdev, skb);
1195 break;
1196
1197 case HCI_EV_ENCRYPT_CHANGE:
1198 hci_encrypt_change_evt(hdev, skb);
1199 break;
1200
1201 case HCI_EV_CHANGE_CONN_LINK_KEY_COMPLETE:
1202 hci_change_conn_link_key_complete_evt(hdev, skb);
1203 break;
1204
1205 case HCI_EV_PIN_CODE_REQ:
1206 hci_pin_code_request_evt(hdev, skb);
1207 break;
1208
1209 case HCI_EV_LINK_KEY_REQ:
1210 hci_link_key_request_evt(hdev, skb);
1211 break;
1212
1213 case HCI_EV_LINK_KEY_NOTIFY:
1214 hci_link_key_notify_evt(hdev, skb);
1215 break;
1216
Marcel Holtmann04837f62006-07-03 10:02:33 +02001217 case HCI_EV_REMOTE_FEATURES:
1218 hci_remote_features_evt(hdev, skb);
1219 break;
1220
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 case HCI_EV_CLOCK_OFFSET:
1222 hci_clock_offset_evt(hdev, skb);
1223 break;
1224
Marcel Holtmann85a1e932005-08-09 20:28:02 -07001225 case HCI_EV_PSCAN_REP_MODE:
1226 hci_pscan_rep_mode_evt(hdev, skb);
1227 break;
1228
Marcel Holtmann04837f62006-07-03 10:02:33 +02001229 case HCI_EV_SNIFF_SUBRATE:
1230 hci_sniff_subrate_evt(hdev, skb);
1231 break;
1232
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233 case HCI_EV_CMD_STATUS:
1234 cs = (struct hci_ev_cmd_status *) skb->data;
1235 skb_pull(skb, sizeof(cs));
1236
1237 opcode = __le16_to_cpu(cs->opcode);
1238 ogf = hci_opcode_ogf(opcode);
1239 ocf = hci_opcode_ocf(opcode);
1240
1241 switch (ogf) {
1242 case OGF_INFO_PARAM:
1243 hci_cs_info_param(hdev, ocf, cs->status);
1244 break;
1245
1246 case OGF_HOST_CTL:
1247 hci_cs_host_ctl(hdev, ocf, cs->status);
1248 break;
1249
1250 case OGF_LINK_CTL:
1251 hci_cs_link_ctl(hdev, ocf, cs->status);
1252 break;
1253
1254 case OGF_LINK_POLICY:
1255 hci_cs_link_policy(hdev, ocf, cs->status);
1256 break;
1257
1258 default:
1259 BT_DBG("%s Command Status OGF %x", hdev->name, ogf);
1260 break;
1261 }
1262
1263 if (cs->ncmd) {
1264 atomic_set(&hdev->cmd_cnt, 1);
1265 if (!skb_queue_empty(&hdev->cmd_q))
1266 hci_sched_cmd(hdev);
1267 }
1268 break;
1269
1270 case HCI_EV_CMD_COMPLETE:
1271 ec = (struct hci_ev_cmd_complete *) skb->data;
1272 skb_pull(skb, sizeof(*ec));
1273
1274 opcode = __le16_to_cpu(ec->opcode);
1275 ogf = hci_opcode_ogf(opcode);
1276 ocf = hci_opcode_ocf(opcode);
1277
1278 switch (ogf) {
1279 case OGF_INFO_PARAM:
1280 hci_cc_info_param(hdev, ocf, skb);
1281 break;
1282
1283 case OGF_HOST_CTL:
1284 hci_cc_host_ctl(hdev, ocf, skb);
1285 break;
1286
1287 case OGF_LINK_CTL:
1288 hci_cc_link_ctl(hdev, ocf, skb);
1289 break;
1290
1291 case OGF_LINK_POLICY:
1292 hci_cc_link_policy(hdev, ocf, skb);
1293 break;
1294
1295 default:
1296 BT_DBG("%s Command Completed OGF %x", hdev->name, ogf);
1297 break;
1298 }
1299
1300 if (ec->ncmd) {
1301 atomic_set(&hdev->cmd_cnt, 1);
1302 if (!skb_queue_empty(&hdev->cmd_q))
1303 hci_sched_cmd(hdev);
1304 }
1305 break;
1306 }
1307
1308 kfree_skb(skb);
1309 hdev->stat.evt_rx++;
1310}
1311
1312/* Generate internal stack event */
1313void hci_si_event(struct hci_dev *hdev, int type, int dlen, void *data)
1314{
1315 struct hci_event_hdr *hdr;
1316 struct hci_ev_stack_internal *ev;
1317 struct sk_buff *skb;
1318
1319 skb = bt_skb_alloc(HCI_EVENT_HDR_SIZE + sizeof(*ev) + dlen, GFP_ATOMIC);
1320 if (!skb)
1321 return;
1322
1323 hdr = (void *) skb_put(skb, HCI_EVENT_HDR_SIZE);
1324 hdr->evt = HCI_EV_STACK_INTERNAL;
1325 hdr->plen = sizeof(*ev) + dlen;
1326
1327 ev = (void *) skb_put(skb, sizeof(*ev) + dlen);
1328 ev->type = type;
1329 memcpy(ev->data, data, dlen);
1330
Marcel Holtmann576c7d82005-08-06 12:36:54 +02001331 bt_cb(skb)->incoming = 1;
Patrick McHardya61bbcf2005-08-14 17:24:31 -07001332 __net_timestamp(skb);
Marcel Holtmann576c7d82005-08-06 12:36:54 +02001333
Marcel Holtmann0d48d932005-08-09 20:30:28 -07001334 bt_cb(skb)->pkt_type = HCI_EVENT_PKT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335 skb->dev = (void *) hdev;
1336 hci_send_to_sock(hdev, skb);
1337 kfree_skb(skb);
1338}