1 /* $NetBSD: hci_socket.c,v 1.18 2009/08/10 18:25:20 plunky Exp $ */
4 * Copyright (c) 2005 Iain Hibbert.
5 * Copyright (c) 2006 Itronix Inc.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
16 * 3. The name of Itronix Inc. may not be used to endorse
17 * or promote products derived from this software without specific
18 * prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
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
24 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
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
27 * ON ANY THEORY OF LIABILITY, WHETHER IN
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
30 * POSSIBILITY OF SUCH DAMAGE.
33 #include <sys/cdefs.h>
34 __KERNEL_RCSID(0, "$NetBSD: hci_socket.c,v 1.18 2009/08/10 18:25:20 plunky Exp $");
36 /* load symbolic names */
37 #ifdef BLUETOOTH_DEBUG
42 #include <sys/param.h>
43 #include <sys/domain.h>
44 #include <sys/kauth.h>
45 #include <sys/kernel.h>
48 #include <sys/protosw.h>
49 #include <sys/socket.h>
50 #include <sys/socketvar.h>
51 #include <sys/systm.h>
53 #include <netbt/bluetooth.h>
54 #include <netbt/hci.h>
56 /*******************************************************************************
58 * HCI SOCK_RAW Sockets - for control of Bluetooth Devices
63 * the raw HCI protocol control block
66 struct socket
*hp_socket
; /* socket */
67 kauth_cred_t hp_cred
; /* owner credential */
68 unsigned int hp_flags
; /* flags */
69 bdaddr_t hp_laddr
; /* local address */
70 bdaddr_t hp_raddr
; /* remote address */
71 struct hci_filter hp_efilter
; /* user event filter */
72 struct hci_filter hp_pfilter
; /* user packet filter */
73 LIST_ENTRY(hci_pcb
) hp_next
; /* next HCI pcb */
77 #define HCI_DIRECTION (1<<1) /* direction control messages */
78 #define HCI_PROMISCUOUS (1<<2) /* listen to all units */
80 LIST_HEAD(hci_pcb_list
, hci_pcb
) hci_pcb
= LIST_HEAD_INITIALIZER(hci_pcb
);
83 int hci_sendspace
= HCI_CMD_PKT_SIZE
;
84 int hci_recvspace
= 4096;
86 /* unprivileged commands opcode table */
89 uint8_t offs
; /* 0 - 63 */
90 uint8_t mask
; /* bit 0 - 7 */
91 uint8_t length
; /* approved length */
94 0, 0x01, sizeof(hci_inquiry_cp
) },
95 { HCI_CMD_REMOTE_NAME_REQ
,
96 2, 0x08, sizeof(hci_remote_name_req_cp
) },
97 { HCI_CMD_READ_REMOTE_FEATURES
,
98 2, 0x20, sizeof(hci_read_remote_features_cp
) },
99 { HCI_CMD_READ_REMOTE_EXTENDED_FEATURES
,
100 2, 0x40, sizeof(hci_read_remote_extended_features_cp
) },
101 { HCI_CMD_READ_REMOTE_VER_INFO
,
102 2, 0x80, sizeof(hci_read_remote_ver_info_cp
) },
103 { HCI_CMD_READ_CLOCK_OFFSET
,
104 3, 0x01, sizeof(hci_read_clock_offset_cp
) },
105 { HCI_CMD_READ_LMP_HANDLE
,
106 3, 0x02, sizeof(hci_read_lmp_handle_cp
) },
107 { HCI_CMD_ROLE_DISCOVERY
,
108 4, 0x80, sizeof(hci_role_discovery_cp
) },
109 { HCI_CMD_READ_LINK_POLICY_SETTINGS
,
110 5, 0x02, sizeof(hci_read_link_policy_settings_cp
) },
111 { HCI_CMD_READ_DEFAULT_LINK_POLICY_SETTINGS
,
113 { HCI_CMD_READ_PIN_TYPE
,
115 { HCI_CMD_READ_LOCAL_NAME
,
117 { HCI_CMD_READ_CON_ACCEPT_TIMEOUT
,
119 { HCI_CMD_READ_PAGE_TIMEOUT
,
121 { HCI_CMD_READ_SCAN_ENABLE
,
123 { HCI_CMD_READ_PAGE_SCAN_ACTIVITY
,
125 { HCI_CMD_READ_INQUIRY_SCAN_ACTIVITY
,
127 { HCI_CMD_READ_AUTH_ENABLE
,
129 { HCI_CMD_READ_ENCRYPTION_MODE
,
131 { HCI_CMD_READ_UNIT_CLASS
,
133 { HCI_CMD_READ_VOICE_SETTING
,
135 { HCI_CMD_READ_AUTO_FLUSH_TIMEOUT
,
136 9, 0x10, sizeof(hci_read_auto_flush_timeout_cp
) },
137 { HCI_CMD_READ_NUM_BROADCAST_RETRANS
,
139 { HCI_CMD_READ_HOLD_MODE_ACTIVITY
,
141 { HCI_CMD_READ_XMIT_LEVEL
,
142 10, 0x04, sizeof(hci_read_xmit_level_cp
) },
143 { HCI_CMD_READ_SCO_FLOW_CONTROL
,
145 { HCI_CMD_READ_LINK_SUPERVISION_TIMEOUT
,
146 11, 0x01, sizeof(hci_read_link_supervision_timeout_cp
) },
147 { HCI_CMD_READ_NUM_SUPPORTED_IAC
,
149 { HCI_CMD_READ_IAC_LAP
,
151 { HCI_CMD_READ_PAGE_SCAN_PERIOD
,
153 { HCI_CMD_READ_PAGE_SCAN
,
155 { HCI_CMD_READ_INQUIRY_SCAN_TYPE
,
157 { HCI_CMD_READ_INQUIRY_MODE
,
159 { HCI_CMD_READ_PAGE_SCAN_TYPE
,
161 { HCI_CMD_READ_AFH_ASSESSMENT
,
163 { HCI_CMD_READ_LOCAL_VER
,
165 { HCI_CMD_READ_LOCAL_COMMANDS
,
167 { HCI_CMD_READ_LOCAL_FEATURES
,
169 { HCI_CMD_READ_LOCAL_EXTENDED_FEATURES
,
170 14, 0x40, sizeof(hci_read_local_extended_features_cp
) },
171 { HCI_CMD_READ_BUFFER_SIZE
,
173 { HCI_CMD_READ_COUNTRY_CODE
,
175 { HCI_CMD_READ_BDADDR
,
177 { HCI_CMD_READ_FAILED_CONTACT_CNTR
,
178 15, 0x04, sizeof(hci_read_failed_contact_cntr_cp
) },
179 { HCI_CMD_READ_LINK_QUALITY
,
180 15, 0x10, sizeof(hci_read_link_quality_cp
) },
182 15, 0x20, sizeof(hci_read_rssi_cp
) },
183 { HCI_CMD_READ_AFH_CHANNEL_MAP
,
184 15, 0x40, sizeof(hci_read_afh_channel_map_cp
) },
185 { HCI_CMD_READ_CLOCK
,
186 15, 0x80, sizeof(hci_read_clock_cp
) },
187 { HCI_CMD_READ_LOOPBACK_MODE
,
189 { HCI_CMD_READ_EXTENDED_INQUIRY_RSP
,
191 { HCI_CMD_READ_SIMPLE_PAIRING_MODE
,
193 { HCI_CMD_READ_INQUIRY_RSP_XMIT_POWER
,
195 { HCI_CMD_READ_DEFAULT_ERRDATA_REPORTING
,
200 * supply a basic device send/recv policy
203 hci_device_cb(kauth_cred_t cred
, kauth_action_t action
, void *cookie
,
204 void *arg0
, void *arg1
, void *arg2
, void *arg3
)
208 result
= KAUTH_RESULT_DEFER
;
211 case KAUTH_DEVICE_BLUETOOTH_SEND
: {
212 struct hci_unit
*unit
= (struct hci_unit
*)arg0
;
213 hci_cmd_hdr_t
*hdr
= (hci_cmd_hdr_t
*)arg1
;
216 * Allow sending unprivileged commands if the packet size
217 * is correct and the unit claims to support it
220 if (hdr
->type
!= HCI_CMD_PKT
)
223 for (i
= 0; i
< __arraycount(hci_cmds
); i
++) {
224 if (hdr
->opcode
== hci_cmds
[i
].opcode
225 && hdr
->length
== hci_cmds
[i
].length
226 && (unit
->hci_cmds
[hci_cmds
[i
].offs
] & hci_cmds
[i
].mask
)) {
227 result
= KAUTH_RESULT_ALLOW
;
235 case KAUTH_DEVICE_BLUETOOTH_RECV
:
236 switch((uint8_t)(uintptr_t)arg0
) {
238 uint16_t opcode
= (uint16_t)(uintptr_t)arg1
;
241 * Allow to see any unprivileged command packet
244 for (i
= 0; i
< __arraycount(hci_cmds
); i
++) {
245 if (opcode
== hci_cmds
[i
].opcode
) {
246 result
= KAUTH_RESULT_ALLOW
;
254 case HCI_EVENT_PKT
: {
255 uint8_t event
= (uint8_t)(uintptr_t)arg1
;
258 * Allow to receive most events
262 case HCI_EVENT_RETURN_LINK_KEYS
:
263 case HCI_EVENT_LINK_KEY_NOTIFICATION
:
264 case HCI_EVENT_USER_CONFIRM_REQ
:
265 case HCI_EVENT_USER_PASSKEY_NOTIFICATION
:
266 case HCI_EVENT_VENDOR
:
270 result
= KAUTH_RESULT_ALLOW
;
277 case HCI_ACL_DATA_PKT
:
278 case HCI_SCO_DATA_PKT
: {
279 /* uint16_t handle = (uint16_t)(uintptr_t)arg1; */
281 * don't normally allow receiving data packets
300 * HCI protocol init routine,
301 * - set up a kauth listener to provide basic packet access policy
307 if (kauth_listen_scope(KAUTH_SCOPE_DEVICE
, hci_device_cb
, NULL
) == NULL
)
308 panic("Bluetooth HCI: cannot listen on device scope");
312 * When command packet reaches the device, we can drop
313 * it from the socket buffer (called from hci_output_acl)
318 struct socket
*so
= arg
;
320 sbdroprecord(&so
->so_snd
);
325 * HCI socket is going away and has some pending packets. We let them
326 * go by design, but remove the context pointer as it will be invalid
327 * and we no longer need to be notified.
330 hci_cmdwait_flush(struct socket
*so
)
332 struct hci_unit
*unit
;
336 DPRINTF("flushing %p\n", so
);
338 SIMPLEQ_FOREACH(unit
, &hci_unit_list
, hci_next
) {
339 m
= MBUFQ_FIRST(&unit
->hci_cmdwait
);
341 ctx
= M_GETCTX(m
, struct socket
*);
352 * This came from userland, so check it out.
355 hci_send(struct hci_pcb
*pcb
, struct mbuf
*m
, bdaddr_t
*addr
)
357 struct hci_unit
*unit
;
363 KASSERT(addr
!= NULL
);
365 /* wants at least a header to start with */
366 if (m
->m_pkthdr
.len
< sizeof(hdr
)) {
370 m_copydata(m
, 0, sizeof(hdr
), &hdr
);
371 hdr
.opcode
= le16toh(hdr
.opcode
);
373 /* only allows CMD packets to be sent */
374 if (hdr
.type
!= HCI_CMD_PKT
) {
379 /* validates packet length */
380 if (m
->m_pkthdr
.len
!= sizeof(hdr
) + hdr
.length
) {
385 /* finds destination */
386 unit
= hci_unit_lookup(addr
);
392 /* security checks for unprivileged users */
393 if (pcb
->hp_cred
!= NULL
394 && kauth_authorize_device(pcb
->hp_cred
,
395 KAUTH_DEVICE_BLUETOOTH_SEND
,
396 unit
, &hdr
, NULL
, NULL
) != 0) {
401 /* makess a copy for precious to keep */
402 m0
= m_copypacket(m
, M_DONTWAIT
);
407 sbappendrecord(&pcb
->hp_socket
->so_snd
, m0
);
408 M_SETCTX(m
, pcb
->hp_socket
); /* enable drop callback */
410 DPRINTFN(2, "(%s) opcode (%03x|%04x)\n", device_xname(unit
->hci_dev
),
411 HCI_OGF(hdr
.opcode
), HCI_OCF(hdr
.opcode
));
414 if (unit
->hci_num_cmd_pkts
== 0)
415 MBUFQ_ENQUEUE(&unit
->hci_cmdwait
, m
);
417 hci_output_cmd(unit
, m
);
422 DPRINTF("packet (%d bytes) not sent (error %d)\n",
423 m
->m_pkthdr
.len
, err
);
432 * optional mbuf chain containing message
433 * ioctl command (PRU_CONTROL)
435 * optional mbuf chain containing an address
436 * ioctl data (PRU_CONTROL)
437 * optionally, protocol number (PRU_ATTACH)
438 * ctl is optional mbuf chain containing socket options
439 * l is pointer to process requesting action (if any)
441 * we are responsible for disposing of m and ctl if
442 * they are mbuf chains
445 hci_usrreq(struct socket
*up
, int req
, struct mbuf
*m
,
446 struct mbuf
*nam
, struct mbuf
*ctl
, struct lwp
*l
)
448 struct hci_pcb
*pcb
= (struct hci_pcb
*)up
->so_pcb
;
449 struct sockaddr_bt
*sa
;
452 DPRINTFN(2, "%s\n", prurequests
[req
]);
456 mutex_enter(bt_lock
);
457 err
= hci_ioctl((unsigned long)m
, (void *)nam
, l
);
465 if (up
->so_lock
== NULL
) {
466 mutex_obj_hold(bt_lock
);
467 up
->so_lock
= bt_lock
;
470 KASSERT(solocked(up
));
473 err
= soreserve(up
, hci_sendspace
, hci_recvspace
);
477 pcb
= malloc(sizeof(struct hci_pcb
), M_PCB
, M_NOWAIT
| M_ZERO
);
485 pcb
->hp_cred
= kauth_cred_dup(l
->l_cred
);
488 * Set default user filter. By default, socket only passes
489 * Command_Complete and Command_Status Events.
491 hci_filter_set(HCI_EVENT_COMMAND_COMPL
, &pcb
->hp_efilter
);
492 hci_filter_set(HCI_EVENT_COMMAND_STATUS
, &pcb
->hp_efilter
);
493 hci_filter_set(HCI_EVENT_PKT
, &pcb
->hp_pfilter
);
495 LIST_INSERT_HEAD(&hci_pcb
, pcb
, hp_next
);
500 /* anything after here *requires* a pcb */
508 bdaddr_copy(&pcb
->hp_raddr
, BDADDR_ANY
);
510 /* XXX we cannot call soisdisconnected() here, as it sets
511 * SS_CANTRCVMORE and SS_CANTSENDMORE. The problem being,
512 * that soisconnected() does not clear these and if you
513 * try to reconnect this socket (which is permitted) you
514 * get a broken pipe when you try to write any data.
516 up
->so_state
&= ~SS_ISCONNECTED
;
520 soisdisconnected(up
);
521 /* fall through to */
523 if (up
->so_snd
.sb_mb
!= NULL
)
524 hci_cmdwait_flush(up
);
526 if (pcb
->hp_cred
!= NULL
)
527 kauth_cred_free(pcb
->hp_cred
);
530 LIST_REMOVE(pcb
, hp_next
);
535 KASSERT(nam
!= NULL
);
536 sa
= mtod(nam
, struct sockaddr_bt
*);
538 if (sa
->bt_len
!= sizeof(struct sockaddr_bt
))
541 if (sa
->bt_family
!= AF_BLUETOOTH
)
544 bdaddr_copy(&pcb
->hp_laddr
, &sa
->bt_bdaddr
);
546 if (bdaddr_any(&sa
->bt_bdaddr
))
547 pcb
->hp_flags
|= HCI_PROMISCUOUS
;
549 pcb
->hp_flags
&= ~HCI_PROMISCUOUS
;
554 KASSERT(nam
!= NULL
);
555 sa
= mtod(nam
, struct sockaddr_bt
*);
557 if (sa
->bt_len
!= sizeof(struct sockaddr_bt
))
560 if (sa
->bt_family
!= AF_BLUETOOTH
)
563 if (hci_unit_lookup(&sa
->bt_bdaddr
) == NULL
)
564 return EADDRNOTAVAIL
;
566 bdaddr_copy(&pcb
->hp_raddr
, &sa
->bt_bdaddr
);
571 KASSERT(nam
!= NULL
);
572 sa
= mtod(nam
, struct sockaddr_bt
*);
574 memset(sa
, 0, sizeof(struct sockaddr_bt
));
576 sa
->bt_len
= sizeof(struct sockaddr_bt
);
577 sa
->bt_family
= AF_BLUETOOTH
;
578 bdaddr_copy(&sa
->bt_bdaddr
, &pcb
->hp_raddr
);
582 KASSERT(nam
!= NULL
);
583 sa
= mtod(nam
, struct sockaddr_bt
*);
585 memset(sa
, 0, sizeof(struct sockaddr_bt
));
587 sa
->bt_len
= sizeof(struct sockaddr_bt
);
588 sa
->bt_family
= AF_BLUETOOTH
;
589 bdaddr_copy(&sa
->bt_bdaddr
, &pcb
->hp_laddr
);
599 sa
= mtod(nam
, struct sockaddr_bt
*);
601 if (sa
->bt_len
!= sizeof(struct sockaddr_bt
)) {
606 if (sa
->bt_family
!= AF_BLUETOOTH
) {
612 if (ctl
) /* have no use for this */
615 return hci_send(pcb
, m
, (sa
? &sa
->bt_bdaddr
: &pcb
->hp_raddr
));
618 return 0; /* (no sense - Doh!) */
622 return EOPNOTSUPP
; /* (no release) */
650 * get/set socket options
653 hci_ctloutput(int req
, struct socket
*so
, struct sockopt
*sopt
)
655 struct hci_pcb
*pcb
= (struct hci_pcb
*)so
->so_pcb
;
658 DPRINTFN(2, "req %s\n", prcorequests
[req
]);
663 if (sopt
->sopt_level
!= BTPROTO_HCI
)
668 switch (sopt
->sopt_name
) {
669 case SO_HCI_EVT_FILTER
:
670 err
= sockopt_set(sopt
, &pcb
->hp_efilter
,
671 sizeof(struct hci_filter
));
675 case SO_HCI_PKT_FILTER
:
676 err
= sockopt_set(sopt
, &pcb
->hp_pfilter
,
677 sizeof(struct hci_filter
));
681 case SO_HCI_DIRECTION
:
682 err
= sockopt_setint(sopt
,
683 (pcb
->hp_flags
& HCI_DIRECTION
? 1 : 0));
694 switch (sopt
->sopt_name
) {
695 case SO_HCI_EVT_FILTER
: /* set event filter */
696 err
= sockopt_get(sopt
, &pcb
->hp_efilter
,
697 sizeof(pcb
->hp_efilter
));
701 case SO_HCI_PKT_FILTER
: /* set packet filter */
702 err
= sockopt_get(sopt
, &pcb
->hp_pfilter
,
703 sizeof(pcb
->hp_pfilter
));
707 case SO_HCI_DIRECTION
: /* request direction ctl messages */
708 err
= sockopt_getint(sopt
, &optval
);
713 pcb
->hp_flags
|= HCI_DIRECTION
;
715 pcb
->hp_flags
&= ~HCI_DIRECTION
;
733 * HCI mbuf tap routine
735 * copy packets to any raw HCI sockets that wish (and are
736 * permitted) to see them
739 hci_mtap(struct mbuf
*m
, struct hci_unit
*unit
)
742 struct mbuf
*m0
, *ctlmsg
, **ctl
;
743 struct sockaddr_bt sa
;
748 KASSERT(m
->m_len
>= sizeof(type
));
750 type
= *mtod(m
, uint8_t *);
752 memset(&sa
, 0, sizeof(sa
));
753 sa
.bt_len
= sizeof(struct sockaddr_bt
);
754 sa
.bt_family
= AF_BLUETOOTH
;
755 bdaddr_copy(&sa
.bt_bdaddr
, &unit
->hci_bdaddr
);
757 LIST_FOREACH(pcb
, &hci_pcb
, hp_next
) {
759 * filter according to source address
761 if ((pcb
->hp_flags
& HCI_PROMISCUOUS
) == 0
762 && bdaddr_same(&pcb
->hp_laddr
, &sa
.bt_bdaddr
) == 0)
766 * filter according to packet type filter
768 if (hci_filter_test(type
, &pcb
->hp_pfilter
) == 0)
772 * filter according to event/security filters
776 KASSERT(m
->m_len
>= sizeof(hci_event_hdr_t
));
778 event
= mtod(m
, hci_event_hdr_t
*)->event
;
780 if (hci_filter_test(event
, &pcb
->hp_efilter
) == 0)
787 KASSERT(m
->m_len
>= sizeof(hci_cmd_hdr_t
));
788 arg1
= le16toh(mtod(m
, hci_cmd_hdr_t
*)->opcode
);
791 case HCI_ACL_DATA_PKT
:
792 KASSERT(m
->m_len
>= sizeof(hci_acldata_hdr_t
));
793 arg1
= le16toh(mtod(m
, hci_acldata_hdr_t
*)->con_handle
);
794 arg1
= HCI_CON_HANDLE(arg1
);
797 case HCI_SCO_DATA_PKT
:
798 KASSERT(m
->m_len
>= sizeof(hci_scodata_hdr_t
));
799 arg1
= le16toh(mtod(m
, hci_scodata_hdr_t
*)->con_handle
);
800 arg1
= HCI_CON_HANDLE(arg1
);
808 if (pcb
->hp_cred
!= NULL
809 && kauth_authorize_device(pcb
->hp_cred
,
810 KAUTH_DEVICE_BLUETOOTH_RECV
,
811 KAUTH_ARG(type
), KAUTH_ARG(arg1
), NULL
, NULL
) != 0)
815 * create control messages
819 if (pcb
->hp_flags
& HCI_DIRECTION
) {
820 int dir
= m
->m_flags
& M_LINK0
? 1 : 0;
822 *ctl
= sbcreatecontrol(&dir
, sizeof(dir
),
823 SCM_HCI_DIRECTION
, BTPROTO_HCI
);
826 ctl
= &((*ctl
)->m_next
);
832 m0
= m_copypacket(m
, M_DONTWAIT
);
833 if (m0
&& sbappendaddr(&pcb
->hp_socket
->so_rcv
,
834 (struct sockaddr
*)&sa
, m0
, ctlmsg
)) {
835 sorwakeup(pcb
->hp_socket
);