xref: /dflybsd-src/sys/netgraph7/bluetooth/socket/ng_btsocket.c (revision 84bfc1a1b84f23538385f60e555d3723a9c81c33)
1b06ebda0SMatthew Dillon /*
2b06ebda0SMatthew Dillon  * ng_btsocket.c
3b06ebda0SMatthew Dillon  */
4b06ebda0SMatthew Dillon 
5b06ebda0SMatthew Dillon /*-
6b06ebda0SMatthew Dillon  * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
7b06ebda0SMatthew Dillon  * All rights reserved.
8b06ebda0SMatthew Dillon  *
9b06ebda0SMatthew Dillon  * Redistribution and use in source and binary forms, with or without
10b06ebda0SMatthew Dillon  * modification, are permitted provided that the following conditions
11b06ebda0SMatthew Dillon  * are met:
12b06ebda0SMatthew Dillon  * 1. Redistributions of source code must retain the above copyright
13b06ebda0SMatthew Dillon  *    notice, this list of conditions and the following disclaimer.
14b06ebda0SMatthew Dillon  * 2. Redistributions in binary form must reproduce the above copyright
15b06ebda0SMatthew Dillon  *    notice, this list of conditions and the following disclaimer in the
16b06ebda0SMatthew Dillon  *    documentation and/or other materials provided with the distribution.
17b06ebda0SMatthew Dillon  *
18b06ebda0SMatthew Dillon  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19b06ebda0SMatthew Dillon  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20b06ebda0SMatthew Dillon  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21b06ebda0SMatthew Dillon  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22b06ebda0SMatthew Dillon  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23b06ebda0SMatthew Dillon  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24b06ebda0SMatthew Dillon  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25b06ebda0SMatthew Dillon  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26b06ebda0SMatthew Dillon  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27b06ebda0SMatthew Dillon  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28b06ebda0SMatthew Dillon  * SUCH DAMAGE.
29b06ebda0SMatthew Dillon  *
30b06ebda0SMatthew Dillon  * $Id: ng_btsocket.c,v 1.4 2003/09/14 23:29:06 max Exp $
31b06ebda0SMatthew Dillon  * $FreeBSD: src/sys/netgraph/bluetooth/socket/ng_btsocket.c,v 1.13 2006/07/21 17:11:13 rwatson Exp $
32b06ebda0SMatthew Dillon  */
33b06ebda0SMatthew Dillon 
34b06ebda0SMatthew Dillon #include <sys/param.h>
35b06ebda0SMatthew Dillon #include <sys/systm.h>
36*84bfc1a1SSascha Wildner #include <sys/bitstring.h>
37b06ebda0SMatthew Dillon #include <sys/errno.h>
38b06ebda0SMatthew Dillon #include <sys/domain.h>
39b06ebda0SMatthew Dillon #include <sys/kernel.h>
40b06ebda0SMatthew Dillon #include <sys/lock.h>
41b06ebda0SMatthew Dillon #include <sys/mbuf.h>
42b06ebda0SMatthew Dillon #include <sys/protosw.h>
43b06ebda0SMatthew Dillon #include <sys/socket.h>
44b06ebda0SMatthew Dillon #include <sys/socketvar.h>
45b06ebda0SMatthew Dillon #include <sys/sysctl.h>
46b06ebda0SMatthew Dillon #include <sys/taskqueue.h>
47e85b99abSSascha Wildner #include <netgraph7/ng_message.h>
48e85b99abSSascha Wildner #include <netgraph7/netgraph.h>
49e85b99abSSascha Wildner #include <netgraph7/bluetooth/include/ng_bluetooth.h>
50e85b99abSSascha Wildner #include <netgraph7/bluetooth/include/ng_hci.h>
51e85b99abSSascha Wildner #include <netgraph7/bluetooth/include/ng_l2cap.h>
52e85b99abSSascha Wildner #include <netgraph7/bluetooth/include/ng_btsocket.h>
53e85b99abSSascha Wildner #include <netgraph7/bluetooth/include/ng_btsocket_hci_raw.h>
54e85b99abSSascha Wildner #include <netgraph7/bluetooth/include/ng_btsocket_l2cap.h>
55e85b99abSSascha Wildner #include <netgraph7/bluetooth/include/ng_btsocket_rfcomm.h>
56b06ebda0SMatthew Dillon 
57b06ebda0SMatthew Dillon static int			ng_btsocket_modevent (module_t, int, void *);
58b06ebda0SMatthew Dillon extern struct domain		ng_btsocket_domain;
59b06ebda0SMatthew Dillon 
60b06ebda0SMatthew Dillon /*
61b06ebda0SMatthew Dillon  * Bluetooth raw HCI sockets
62b06ebda0SMatthew Dillon  */
63b06ebda0SMatthew Dillon 
64b06ebda0SMatthew Dillon static struct pr_usrreqs	ng_btsocket_hci_raw_usrreqs = {
65b06ebda0SMatthew Dillon 	.pru_abort =		ng_btsocket_hci_raw_abort,
66b06ebda0SMatthew Dillon 	.pru_attach =		ng_btsocket_hci_raw_attach,
67b06ebda0SMatthew Dillon 	.pru_bind =		ng_btsocket_hci_raw_bind,
68b06ebda0SMatthew Dillon 	.pru_connect =		ng_btsocket_hci_raw_connect,
69b06ebda0SMatthew Dillon 	.pru_control =		ng_btsocket_hci_raw_control,
70b06ebda0SMatthew Dillon 	.pru_detach =		ng_btsocket_hci_raw_detach,
71b06ebda0SMatthew Dillon 	.pru_disconnect =	ng_btsocket_hci_raw_disconnect,
72b06ebda0SMatthew Dillon 	.pru_peeraddr =		ng_btsocket_hci_raw_peeraddr,
73b06ebda0SMatthew Dillon 	.pru_send =		ng_btsocket_hci_raw_send,
74b06ebda0SMatthew Dillon 	.pru_shutdown =		NULL,
75b06ebda0SMatthew Dillon 	.pru_sockaddr =		ng_btsocket_hci_raw_sockaddr,
76e85b99abSSascha Wildner #if 0 /* XXX */
77b06ebda0SMatthew Dillon 	.pru_close =		ng_btsocket_hci_raw_close,
78e85b99abSSascha Wildner #endif
79e85b99abSSascha Wildner 	.pru_sosend =		sosend,
80e85b99abSSascha Wildner 	.pru_soreceive =	soreceive,
81b06ebda0SMatthew Dillon };
82b06ebda0SMatthew Dillon 
83b06ebda0SMatthew Dillon /*
84b06ebda0SMatthew Dillon  * Bluetooth raw L2CAP sockets
85b06ebda0SMatthew Dillon  */
86b06ebda0SMatthew Dillon 
87b06ebda0SMatthew Dillon static struct pr_usrreqs	ng_btsocket_l2cap_raw_usrreqs = {
88b06ebda0SMatthew Dillon 	.pru_abort =		ng_btsocket_l2cap_raw_abort,
89b06ebda0SMatthew Dillon 	.pru_attach =		ng_btsocket_l2cap_raw_attach,
90b06ebda0SMatthew Dillon 	.pru_bind =		ng_btsocket_l2cap_raw_bind,
91b06ebda0SMatthew Dillon 	.pru_connect =		ng_btsocket_l2cap_raw_connect,
92b06ebda0SMatthew Dillon 	.pru_control =		ng_btsocket_l2cap_raw_control,
93b06ebda0SMatthew Dillon 	.pru_detach =		ng_btsocket_l2cap_raw_detach,
94b06ebda0SMatthew Dillon 	.pru_disconnect =	ng_btsocket_l2cap_raw_disconnect,
95b06ebda0SMatthew Dillon 	.pru_peeraddr =		ng_btsocket_l2cap_raw_peeraddr,
96b06ebda0SMatthew Dillon 	.pru_send =		ng_btsocket_l2cap_raw_send,
97b06ebda0SMatthew Dillon 	.pru_shutdown =		NULL,
98b06ebda0SMatthew Dillon 	.pru_sockaddr =		ng_btsocket_l2cap_raw_sockaddr,
99e85b99abSSascha Wildner #if 0 /* XXX */
100b06ebda0SMatthew Dillon 	.pru_close =		ng_btsocket_l2cap_raw_close,
101e85b99abSSascha Wildner #endif
102e85b99abSSascha Wildner 	.pru_sosend =		sosend,
103e85b99abSSascha Wildner 	.pru_soreceive =	soreceive,
104b06ebda0SMatthew Dillon };
105b06ebda0SMatthew Dillon 
106b06ebda0SMatthew Dillon /*
107b06ebda0SMatthew Dillon  * Bluetooth SEQPACKET L2CAP sockets
108b06ebda0SMatthew Dillon  */
109b06ebda0SMatthew Dillon 
110b06ebda0SMatthew Dillon static struct pr_usrreqs	ng_btsocket_l2cap_usrreqs = {
111b06ebda0SMatthew Dillon 	.pru_abort =		ng_btsocket_l2cap_abort,
112b06ebda0SMatthew Dillon 	.pru_accept =		ng_btsocket_l2cap_accept,
113b06ebda0SMatthew Dillon 	.pru_attach =		ng_btsocket_l2cap_attach,
114b06ebda0SMatthew Dillon 	.pru_bind =		ng_btsocket_l2cap_bind,
115b06ebda0SMatthew Dillon 	.pru_connect =		ng_btsocket_l2cap_connect,
116b06ebda0SMatthew Dillon 	.pru_control =		ng_btsocket_l2cap_control,
117b06ebda0SMatthew Dillon 	.pru_detach =		ng_btsocket_l2cap_detach,
118b06ebda0SMatthew Dillon 	.pru_disconnect =	ng_btsocket_l2cap_disconnect,
119b06ebda0SMatthew Dillon         .pru_listen =		ng_btsocket_l2cap_listen,
120b06ebda0SMatthew Dillon 	.pru_peeraddr =		ng_btsocket_l2cap_peeraddr,
121b06ebda0SMatthew Dillon 	.pru_send =		ng_btsocket_l2cap_send,
122b06ebda0SMatthew Dillon 	.pru_shutdown =		NULL,
123b06ebda0SMatthew Dillon 	.pru_sockaddr =		ng_btsocket_l2cap_sockaddr,
124e85b99abSSascha Wildner #if 0 /* XXX */
125b06ebda0SMatthew Dillon 	.pru_close =		ng_btsocket_l2cap_close,
126e85b99abSSascha Wildner #endif
127e85b99abSSascha Wildner 	.pru_sosend =		sosend,
128e85b99abSSascha Wildner 	.pru_soreceive =	soreceive,
129b06ebda0SMatthew Dillon };
130b06ebda0SMatthew Dillon 
131b06ebda0SMatthew Dillon /*
132b06ebda0SMatthew Dillon  * Bluetooth STREAM RFCOMM sockets
133b06ebda0SMatthew Dillon  */
134b06ebda0SMatthew Dillon 
135b06ebda0SMatthew Dillon static struct pr_usrreqs	ng_btsocket_rfcomm_usrreqs = {
136b06ebda0SMatthew Dillon 	.pru_abort =		ng_btsocket_rfcomm_abort,
137b06ebda0SMatthew Dillon 	.pru_accept =		ng_btsocket_rfcomm_accept,
138b06ebda0SMatthew Dillon 	.pru_attach =		ng_btsocket_rfcomm_attach,
139b06ebda0SMatthew Dillon 	.pru_bind =		ng_btsocket_rfcomm_bind,
140b06ebda0SMatthew Dillon 	.pru_connect =		ng_btsocket_rfcomm_connect,
141b06ebda0SMatthew Dillon 	.pru_control =		ng_btsocket_rfcomm_control,
142b06ebda0SMatthew Dillon 	.pru_detach =		ng_btsocket_rfcomm_detach,
143b06ebda0SMatthew Dillon 	.pru_disconnect =	ng_btsocket_rfcomm_disconnect,
144b06ebda0SMatthew Dillon         .pru_listen =		ng_btsocket_rfcomm_listen,
145b06ebda0SMatthew Dillon 	.pru_peeraddr =		ng_btsocket_rfcomm_peeraddr,
146b06ebda0SMatthew Dillon 	.pru_send =		ng_btsocket_rfcomm_send,
147b06ebda0SMatthew Dillon 	.pru_shutdown =		NULL,
148b06ebda0SMatthew Dillon 	.pru_sockaddr =		ng_btsocket_rfcomm_sockaddr,
149e85b99abSSascha Wildner #if 0 /* XXX */
150b06ebda0SMatthew Dillon 	.pru_close =		ng_btsocket_rfcomm_close,
151e85b99abSSascha Wildner #endif
152e85b99abSSascha Wildner 	.pru_sosend =		sosend,
153e85b99abSSascha Wildner 	.pru_soreceive =	soreceive,
154b06ebda0SMatthew Dillon };
155b06ebda0SMatthew Dillon 
156b06ebda0SMatthew Dillon /*
157b06ebda0SMatthew Dillon  * Definitions of protocols supported in the BLUETOOTH domain
158b06ebda0SMatthew Dillon  */
159b06ebda0SMatthew Dillon 
160b06ebda0SMatthew Dillon static struct protosw		ng_btsocket_protosw[] = {
161b06ebda0SMatthew Dillon {
162b06ebda0SMatthew Dillon 	.pr_type =		SOCK_RAW,
163b06ebda0SMatthew Dillon 	.pr_domain =		&ng_btsocket_domain,
164b06ebda0SMatthew Dillon 	.pr_protocol =		BLUETOOTH_PROTO_HCI,
165b06ebda0SMatthew Dillon 	.pr_flags =		PR_ATOMIC|PR_ADDR,
166b06ebda0SMatthew Dillon 	.pr_ctloutput =		ng_btsocket_hci_raw_ctloutput,
167b06ebda0SMatthew Dillon 	.pr_init =		ng_btsocket_hci_raw_init,
168b06ebda0SMatthew Dillon 	.pr_usrreqs =		&ng_btsocket_hci_raw_usrreqs,
169b06ebda0SMatthew Dillon },
170b06ebda0SMatthew Dillon {
171b06ebda0SMatthew Dillon 	.pr_type =		SOCK_RAW,
172b06ebda0SMatthew Dillon 	.pr_domain =		&ng_btsocket_domain,
173b06ebda0SMatthew Dillon 	.pr_protocol =		BLUETOOTH_PROTO_L2CAP,
174b06ebda0SMatthew Dillon 	.pr_flags =		PR_ATOMIC|PR_ADDR,
175b06ebda0SMatthew Dillon 	.pr_init =		ng_btsocket_l2cap_raw_init,
176b06ebda0SMatthew Dillon 	.pr_usrreqs =		&ng_btsocket_l2cap_raw_usrreqs,
177b06ebda0SMatthew Dillon },
178b06ebda0SMatthew Dillon {
179b06ebda0SMatthew Dillon 	.pr_type =		SOCK_SEQPACKET,
180b06ebda0SMatthew Dillon 	.pr_domain =		&ng_btsocket_domain,
181b06ebda0SMatthew Dillon 	.pr_protocol =		BLUETOOTH_PROTO_L2CAP,
182b06ebda0SMatthew Dillon 	.pr_flags =		PR_ATOMIC|PR_CONNREQUIRED,
183b06ebda0SMatthew Dillon 	.pr_ctloutput =		ng_btsocket_l2cap_ctloutput,
184b06ebda0SMatthew Dillon 	.pr_init =		ng_btsocket_l2cap_init,
185b06ebda0SMatthew Dillon 	.pr_usrreqs =		&ng_btsocket_l2cap_usrreqs,
186b06ebda0SMatthew Dillon },
187b06ebda0SMatthew Dillon {
188b06ebda0SMatthew Dillon 	.pr_type =		SOCK_STREAM,
189b06ebda0SMatthew Dillon 	.pr_domain =		&ng_btsocket_domain,
190b06ebda0SMatthew Dillon 	.pr_protocol =		BLUETOOTH_PROTO_RFCOMM,
191b06ebda0SMatthew Dillon 	.pr_flags =		PR_CONNREQUIRED,
192b06ebda0SMatthew Dillon 	.pr_ctloutput =		ng_btsocket_rfcomm_ctloutput,
193b06ebda0SMatthew Dillon 	.pr_init =		ng_btsocket_rfcomm_init,
194b06ebda0SMatthew Dillon 	.pr_usrreqs =		&ng_btsocket_rfcomm_usrreqs,
195b06ebda0SMatthew Dillon }
196b06ebda0SMatthew Dillon };
197c157ff7aSSascha Wildner #define ng_btsocket_protosw_size NELEM(ng_btsocket_protosw)
198b06ebda0SMatthew Dillon #define ng_btsocket_protosw_end \
199b06ebda0SMatthew Dillon 	&ng_btsocket_protosw[ng_btsocket_protosw_size]
200b06ebda0SMatthew Dillon 
201b06ebda0SMatthew Dillon /*
202b06ebda0SMatthew Dillon  * BLUETOOTH domain
203b06ebda0SMatthew Dillon  */
204b06ebda0SMatthew Dillon 
205b06ebda0SMatthew Dillon struct domain			ng_btsocket_domain = {
206b06ebda0SMatthew Dillon 	.dom_family =		AF_BLUETOOTH,
207b06ebda0SMatthew Dillon 	.dom_name =		"bluetooth",
208b06ebda0SMatthew Dillon 	.dom_protosw =		ng_btsocket_protosw,
209b06ebda0SMatthew Dillon 	.dom_protoswNPROTOSW =	ng_btsocket_protosw_end
210b06ebda0SMatthew Dillon };
211b06ebda0SMatthew Dillon 
212b06ebda0SMatthew Dillon /*
213b06ebda0SMatthew Dillon  * Socket sysctl tree
214b06ebda0SMatthew Dillon  */
215b06ebda0SMatthew Dillon 
216b06ebda0SMatthew Dillon SYSCTL_NODE(_net_bluetooth_hci, OID_AUTO, sockets, CTLFLAG_RW,
217b06ebda0SMatthew Dillon 	0, "Bluetooth HCI sockets family");
218b06ebda0SMatthew Dillon SYSCTL_NODE(_net_bluetooth_l2cap, OID_AUTO, sockets, CTLFLAG_RW,
219b06ebda0SMatthew Dillon 	0, "Bluetooth L2CAP sockets family");
220b06ebda0SMatthew Dillon SYSCTL_NODE(_net_bluetooth_rfcomm, OID_AUTO, sockets, CTLFLAG_RW,
221b06ebda0SMatthew Dillon 	0, "Bluetooth RFCOMM sockets family");
222b06ebda0SMatthew Dillon 
223b06ebda0SMatthew Dillon /*
224b06ebda0SMatthew Dillon  * Module
225b06ebda0SMatthew Dillon  */
226b06ebda0SMatthew Dillon 
227b06ebda0SMatthew Dillon static moduledata_t	ng_btsocket_mod = {
228b06ebda0SMatthew Dillon 	"ng_btsocket",
229b06ebda0SMatthew Dillon 	ng_btsocket_modevent,
230b06ebda0SMatthew Dillon 	NULL
231b06ebda0SMatthew Dillon };
232b06ebda0SMatthew Dillon 
233b06ebda0SMatthew Dillon DECLARE_MODULE(ng_btsocket, ng_btsocket_mod, SI_SUB_PROTO_DOMAIN,
234b06ebda0SMatthew Dillon 	SI_ORDER_ANY);
235b06ebda0SMatthew Dillon MODULE_VERSION(ng_btsocket, NG_BLUETOOTH_VERSION);
236b06ebda0SMatthew Dillon MODULE_DEPEND(ng_btsocket, ng_bluetooth, NG_BLUETOOTH_VERSION,
237b06ebda0SMatthew Dillon 	NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION);
238b06ebda0SMatthew Dillon MODULE_DEPEND(ng_btsocket, netgraph, NG_ABI_VERSION,
239b06ebda0SMatthew Dillon 	NG_ABI_VERSION, NG_ABI_VERSION);
240b06ebda0SMatthew Dillon 
241b06ebda0SMatthew Dillon /*
242b06ebda0SMatthew Dillon  * Handle loading and unloading for this node type.
243b06ebda0SMatthew Dillon  * This is to handle auxiliary linkages (e.g protocol domain addition).
244b06ebda0SMatthew Dillon  */
245b06ebda0SMatthew Dillon 
246b06ebda0SMatthew Dillon static int
ng_btsocket_modevent(module_t mod,int event,void * data)247b06ebda0SMatthew Dillon ng_btsocket_modevent(module_t mod, int event, void *data)
248b06ebda0SMatthew Dillon {
249b06ebda0SMatthew Dillon 	int	error = 0;
250b06ebda0SMatthew Dillon 
251b06ebda0SMatthew Dillon 	switch (event) {
252b06ebda0SMatthew Dillon 	case MOD_LOAD:
253b06ebda0SMatthew Dillon 		net_add_domain(&ng_btsocket_domain);
254b06ebda0SMatthew Dillon 		break;
255b06ebda0SMatthew Dillon 
256b06ebda0SMatthew Dillon 	case MOD_UNLOAD:
257b06ebda0SMatthew Dillon 		/* XXX can't unload protocol domain yet */
258b06ebda0SMatthew Dillon 		error = EBUSY;
259b06ebda0SMatthew Dillon 		break;
260b06ebda0SMatthew Dillon 
261b06ebda0SMatthew Dillon 	default:
262b06ebda0SMatthew Dillon 		error = EOPNOTSUPP;
263b06ebda0SMatthew Dillon 		break;
264b06ebda0SMatthew Dillon 	}
265b06ebda0SMatthew Dillon 
266b06ebda0SMatthew Dillon 	return (error);
267b06ebda0SMatthew Dillon } /* ng_btsocket_modevent */
268b06ebda0SMatthew Dillon 
269