| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: hci_event.c,v 1.19 2009/08/20 21:40:59 plunky Exp $ */ | | 1 | /* $NetBSD: hci_event.c,v 1.20 2009/08/24 20:37:36 plunky Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2005 Iain Hibbert. | | 4 | * Copyright (c) 2005 Iain Hibbert. |
5 | * Copyright (c) 2006 Itronix Inc. | | 5 | * Copyright (c) 2006 Itronix Inc. |
6 | * All rights reserved. | | 6 | * All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -21,41 +21,42 @@ | | | @@ -21,41 +21,42 @@ |
21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | | 21 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | | 22 | * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY | | 23 | * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY |
24 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | | 24 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES |
25 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | | 25 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; |
26 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | | 26 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND |
27 | * ON ANY THEORY OF LIABILITY, WHETHER IN | | 27 | * ON ANY THEORY OF LIABILITY, WHETHER IN |
28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | | 28 | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | | 29 | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
30 | * POSSIBILITY OF SUCH DAMAGE. | | 30 | * POSSIBILITY OF SUCH DAMAGE. |
31 | */ | | 31 | */ |
32 | | | 32 | |
33 | #include <sys/cdefs.h> | | 33 | #include <sys/cdefs.h> |
34 | __KERNEL_RCSID(0, "$NetBSD: hci_event.c,v 1.19 2009/08/20 21:40:59 plunky Exp $"); | | 34 | __KERNEL_RCSID(0, "$NetBSD: hci_event.c,v 1.20 2009/08/24 20:37:36 plunky Exp $"); |
35 | | | 35 | |
36 | #include <sys/param.h> | | 36 | #include <sys/param.h> |
37 | #include <sys/kernel.h> | | 37 | #include <sys/kernel.h> |
38 | #include <sys/malloc.h> | | 38 | #include <sys/malloc.h> |
39 | #include <sys/mbuf.h> | | 39 | #include <sys/mbuf.h> |
40 | #include <sys/proc.h> | | 40 | #include <sys/proc.h> |
41 | #include <sys/systm.h> | | 41 | #include <sys/systm.h> |
42 | | | 42 | |
43 | #include <netbt/bluetooth.h> | | 43 | #include <netbt/bluetooth.h> |
44 | #include <netbt/hci.h> | | 44 | #include <netbt/hci.h> |
45 | #include <netbt/sco.h> | | 45 | #include <netbt/sco.h> |
46 | | | 46 | |
47 | static void hci_event_inquiry_result(struct hci_unit *, struct mbuf *); | | 47 | static void hci_event_inquiry_result(struct hci_unit *, struct mbuf *); |
48 | static void hci_event_rssi_result(struct hci_unit *, struct mbuf *); | | 48 | static void hci_event_rssi_result(struct hci_unit *, struct mbuf *); |
| | | 49 | static void hci_event_extended_result(struct hci_unit *, struct mbuf *); |
49 | static void hci_event_command_status(struct hci_unit *, struct mbuf *); | | 50 | static void hci_event_command_status(struct hci_unit *, struct mbuf *); |
50 | static void hci_event_command_compl(struct hci_unit *, struct mbuf *); | | 51 | static void hci_event_command_compl(struct hci_unit *, struct mbuf *); |
51 | static void hci_event_con_compl(struct hci_unit *, struct mbuf *); | | 52 | static void hci_event_con_compl(struct hci_unit *, struct mbuf *); |
52 | static void hci_event_discon_compl(struct hci_unit *, struct mbuf *); | | 53 | static void hci_event_discon_compl(struct hci_unit *, struct mbuf *); |
53 | static void hci_event_con_req(struct hci_unit *, struct mbuf *); | | 54 | static void hci_event_con_req(struct hci_unit *, struct mbuf *); |
54 | static void hci_event_num_compl_pkts(struct hci_unit *, struct mbuf *); | | 55 | static void hci_event_num_compl_pkts(struct hci_unit *, struct mbuf *); |
55 | static void hci_event_auth_compl(struct hci_unit *, struct mbuf *); | | 56 | static void hci_event_auth_compl(struct hci_unit *, struct mbuf *); |
56 | static void hci_event_encryption_change(struct hci_unit *, struct mbuf *); | | 57 | static void hci_event_encryption_change(struct hci_unit *, struct mbuf *); |
57 | static void hci_event_change_con_link_key_compl(struct hci_unit *, struct mbuf *); | | 58 | static void hci_event_change_con_link_key_compl(struct hci_unit *, struct mbuf *); |
58 | static void hci_event_read_clock_offset_compl(struct hci_unit *, struct mbuf *); | | 59 | static void hci_event_read_clock_offset_compl(struct hci_unit *, struct mbuf *); |
59 | static void hci_cmd_read_bdaddr(struct hci_unit *, struct mbuf *); | | 60 | static void hci_cmd_read_bdaddr(struct hci_unit *, struct mbuf *); |
60 | static void hci_cmd_read_buffer_size(struct hci_unit *, struct mbuf *); | | 61 | static void hci_cmd_read_buffer_size(struct hci_unit *, struct mbuf *); |
61 | static void hci_cmd_read_local_features(struct hci_unit *, struct mbuf *); | | 62 | static void hci_cmd_read_local_features(struct hci_unit *, struct mbuf *); |
| @@ -185,26 +186,30 @@ hci_event(struct mbuf *m, struct hci_uni | | | @@ -185,26 +186,30 @@ hci_event(struct mbuf *m, struct hci_uni |
185 | | | 186 | |
186 | case HCI_EVENT_NUM_COMPL_PKTS: | | 187 | case HCI_EVENT_NUM_COMPL_PKTS: |
187 | hci_event_num_compl_pkts(unit, m); | | 188 | hci_event_num_compl_pkts(unit, m); |
188 | break; | | 189 | break; |
189 | | | 190 | |
190 | case HCI_EVENT_INQUIRY_RESULT: | | 191 | case HCI_EVENT_INQUIRY_RESULT: |
191 | hci_event_inquiry_result(unit, m); | | 192 | hci_event_inquiry_result(unit, m); |
192 | break; | | 193 | break; |
193 | | | 194 | |
194 | case HCI_EVENT_RSSI_RESULT: | | 195 | case HCI_EVENT_RSSI_RESULT: |
195 | hci_event_rssi_result(unit, m); | | 196 | hci_event_rssi_result(unit, m); |
196 | break; | | 197 | break; |
197 | | | 198 | |
| | | 199 | case HCI_EVENT_EXTENDED_RESULT: |
| | | 200 | hci_event_extended_result(unit, m); |
| | | 201 | break; |
| | | 202 | |
198 | case HCI_EVENT_CON_COMPL: | | 203 | case HCI_EVENT_CON_COMPL: |
199 | hci_event_con_compl(unit, m); | | 204 | hci_event_con_compl(unit, m); |
200 | break; | | 205 | break; |
201 | | | 206 | |
202 | case HCI_EVENT_DISCON_COMPL: | | 207 | case HCI_EVENT_DISCON_COMPL: |
203 | hci_event_discon_compl(unit, m); | | 208 | hci_event_discon_compl(unit, m); |
204 | break; | | 209 | break; |
205 | | | 210 | |
206 | case HCI_EVENT_CON_REQ: | | 211 | case HCI_EVENT_CON_REQ: |
207 | hci_event_con_req(unit, m); | | 212 | hci_event_con_req(unit, m); |
208 | break; | | 213 | break; |
209 | | | 214 | |
210 | case HCI_EVENT_AUTH_COMPL: | | 215 | case HCI_EVENT_AUTH_COMPL: |
| @@ -482,26 +487,56 @@ hci_event_rssi_result(struct hci_unit *u | | | @@ -482,26 +487,56 @@ hci_event_rssi_result(struct hci_unit *u |
482 | rr.bdaddr.b[5], rr.bdaddr.b[4], rr.bdaddr.b[3], | | 487 | rr.bdaddr.b[5], rr.bdaddr.b[4], rr.bdaddr.b[3], |
483 | rr.bdaddr.b[2], rr.bdaddr.b[1], rr.bdaddr.b[0]); | | 488 | rr.bdaddr.b[2], rr.bdaddr.b[1], rr.bdaddr.b[0]); |
484 | | | 489 | |
485 | memo = hci_memo_new(unit, &rr.bdaddr); | | 490 | memo = hci_memo_new(unit, &rr.bdaddr); |
486 | if (memo != NULL) { | | 491 | if (memo != NULL) { |
487 | memo->page_scan_rep_mode = rr.page_scan_rep_mode; | | 492 | memo->page_scan_rep_mode = rr.page_scan_rep_mode; |
488 | memo->page_scan_mode = 0; | | 493 | memo->page_scan_mode = 0; |
489 | memo->clock_offset = rr.clock_offset; | | 494 | memo->clock_offset = rr.clock_offset; |
490 | } | | 495 | } |
491 | } | | 496 | } |
492 | } | | 497 | } |
493 | | | 498 | |
494 | /* | | 499 | /* |
| | | 500 | * Extended Inquiry Result |
| | | 501 | * |
| | | 502 | * as above but provides only one response and extended service info |
| | | 503 | */ |
| | | 504 | static void |
| | | 505 | hci_event_extended_result(struct hci_unit *unit, struct mbuf *m) |
| | | 506 | { |
| | | 507 | hci_extended_result_ep ep; |
| | | 508 | struct hci_memo *memo; |
| | | 509 | |
| | | 510 | KASSERT(m->m_pkthdr.len >= sizeof(ep)); |
| | | 511 | m_copydata(m, 0, sizeof(ep), &ep); |
| | | 512 | m_adj(m, sizeof(ep)); |
| | | 513 | |
| | | 514 | if (ep.num_responses != 1) |
| | | 515 | return; |
| | | 516 | |
| | | 517 | DPRINTFN(1, "bdaddr %02x:%02x:%02x:%02x:%02x:%02x\n", |
| | | 518 | ep.bdaddr.b[5], ep.bdaddr.b[4], ep.bdaddr.b[3], |
| | | 519 | ep.bdaddr.b[2], ep.bdaddr.b[1], ep.bdaddr.b[0]); |
| | | 520 | |
| | | 521 | memo = hci_memo_new(unit, &ep.bdaddr); |
| | | 522 | if (memo != NULL) { |
| | | 523 | memo->page_scan_rep_mode = ep.page_scan_rep_mode; |
| | | 524 | memo->page_scan_mode = 0; |
| | | 525 | memo->clock_offset = ep.clock_offset; |
| | | 526 | } |
| | | 527 | } |
| | | 528 | |
| | | 529 | /* |
495 | * Connection Complete | | 530 | * Connection Complete |
496 | * | | 531 | * |
497 | * Sent to us when a connection is made. If there is no link | | 532 | * Sent to us when a connection is made. If there is no link |
498 | * structure already allocated for this, we must have changed | | 533 | * structure already allocated for this, we must have changed |
499 | * our mind, so just disconnect. | | 534 | * our mind, so just disconnect. |
500 | */ | | 535 | */ |
501 | static void | | 536 | static void |
502 | hci_event_con_compl(struct hci_unit *unit, struct mbuf *m) | | 537 | hci_event_con_compl(struct hci_unit *unit, struct mbuf *m) |
503 | { | | 538 | { |
504 | hci_con_compl_ep ep; | | 539 | hci_con_compl_ep ep; |
505 | hci_write_link_policy_settings_cp cp; | | 540 | hci_write_link_policy_settings_cp cp; |
506 | struct hci_link *link; | | 541 | struct hci_link *link; |
507 | int err; | | 542 | int err; |