xref: /freebsd/sys/netgraph/bluetooth/socket/ng_btsocket.c (revision b84b10f92fe9e702a9f39d4c6b5c4ce70669fa25)
1878ed226SJulian Elischer /*
2878ed226SJulian Elischer  * ng_btsocket.c
3878ed226SJulian Elischer  *
4878ed226SJulian Elischer  * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
5878ed226SJulian Elischer  * All rights reserved.
6878ed226SJulian Elischer  *
7878ed226SJulian Elischer  * Redistribution and use in source and binary forms, with or without
8878ed226SJulian Elischer  * modification, are permitted provided that the following conditions
9878ed226SJulian Elischer  * are met:
10878ed226SJulian Elischer  * 1. Redistributions of source code must retain the above copyright
11878ed226SJulian Elischer  *    notice, this list of conditions and the following disclaimer.
12878ed226SJulian Elischer  * 2. Redistributions in binary form must reproduce the above copyright
13878ed226SJulian Elischer  *    notice, this list of conditions and the following disclaimer in the
14878ed226SJulian Elischer  *    documentation and/or other materials provided with the distribution.
15878ed226SJulian Elischer  *
16878ed226SJulian Elischer  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17878ed226SJulian Elischer  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18878ed226SJulian Elischer  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19878ed226SJulian Elischer  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20878ed226SJulian Elischer  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21878ed226SJulian Elischer  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22878ed226SJulian Elischer  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23878ed226SJulian Elischer  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24878ed226SJulian Elischer  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25878ed226SJulian Elischer  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26878ed226SJulian Elischer  * SUCH DAMAGE.
27878ed226SJulian Elischer  *
280986ab12SMaksim Yevmenkin  * $Id: ng_btsocket.c,v 1.4 2003/09/14 23:29:06 max Exp $
29878ed226SJulian Elischer  * $FreeBSD$
30878ed226SJulian Elischer  */
31878ed226SJulian Elischer 
32878ed226SJulian Elischer #include <sys/param.h>
33878ed226SJulian Elischer #include <sys/systm.h>
340986ab12SMaksim Yevmenkin #include <sys/bitstring.h>
35878ed226SJulian Elischer #include <sys/errno.h>
36878ed226SJulian Elischer #include <sys/domain.h>
37878ed226SJulian Elischer #include <sys/kernel.h>
38878ed226SJulian Elischer #include <sys/lock.h>
39878ed226SJulian Elischer #include <sys/mutex.h>
40878ed226SJulian Elischer #include <sys/protosw.h>
41878ed226SJulian Elischer #include <sys/socket.h>
42878ed226SJulian Elischer #include <sys/socketvar.h>
43878ed226SJulian Elischer #include <sys/sysctl.h>
44f2bb1caeSJulian Elischer #include <sys/taskqueue.h>
45878ed226SJulian Elischer #include <netgraph/ng_message.h>
46878ed226SJulian Elischer #include <netgraph/netgraph.h>
47b84b10f9SMaksim Yevmenkin #include <netgraph/bluetooth/include/ng_bluetooth.h>
48b84b10f9SMaksim Yevmenkin #include <netgraph/bluetooth/include/ng_hci.h>
49b84b10f9SMaksim Yevmenkin #include <netgraph/bluetooth/include/ng_l2cap.h>
50b84b10f9SMaksim Yevmenkin #include <netgraph/bluetooth/include/ng_btsocket.h>
51b84b10f9SMaksim Yevmenkin #include <netgraph/bluetooth/include/ng_btsocket_hci_raw.h>
52b84b10f9SMaksim Yevmenkin #include <netgraph/bluetooth/include/ng_btsocket_l2cap.h>
53b84b10f9SMaksim Yevmenkin #include <netgraph/bluetooth/include/ng_btsocket_rfcomm.h>
54878ed226SJulian Elischer 
55878ed226SJulian Elischer static int			ng_btsocket_modevent (module_t, int, void *);
56878ed226SJulian Elischer extern struct domain		ng_btsocket_domain;
57878ed226SJulian Elischer 
58878ed226SJulian Elischer /*
59878ed226SJulian Elischer  * Bluetooth raw HCI sockets
60878ed226SJulian Elischer  */
61878ed226SJulian Elischer 
62878ed226SJulian Elischer static struct pr_usrreqs	ng_btsocket_hci_raw_usrreqs = {
63878ed226SJulian Elischer 	ng_btsocket_hci_raw_abort,	/* abort */
64878ed226SJulian Elischer 	pru_accept_notsupp,		/* accept */
65878ed226SJulian Elischer 	ng_btsocket_hci_raw_attach,	/* attach */
66878ed226SJulian Elischer 	ng_btsocket_hci_raw_bind,	/* bind */
67878ed226SJulian Elischer 	ng_btsocket_hci_raw_connect,	/* connect */
68878ed226SJulian Elischer 	pru_connect2_notsupp,		/* connect2 */
69878ed226SJulian Elischer 	ng_btsocket_hci_raw_control,	/* control */
70878ed226SJulian Elischer 	ng_btsocket_hci_raw_detach,	/* detach */
71878ed226SJulian Elischer 	ng_btsocket_hci_raw_disconnect,	/* disconnect */
72878ed226SJulian Elischer 	pru_listen_notsupp,		/* listen */
73878ed226SJulian Elischer 	ng_btsocket_hci_raw_peeraddr,	/* peeraddr */
74878ed226SJulian Elischer 	pru_rcvd_notsupp,		/* rcvd */
75878ed226SJulian Elischer 	pru_rcvoob_notsupp,		/* rcvoob */
76878ed226SJulian Elischer 	ng_btsocket_hci_raw_send,	/* send */
77878ed226SJulian Elischer 	pru_sense_null,			/* send */
78878ed226SJulian Elischer 	NULL,				/* shutdown */
79878ed226SJulian Elischer 	ng_btsocket_hci_raw_sockaddr,	/* sockaddr */
80878ed226SJulian Elischer 	sosend,
81878ed226SJulian Elischer 	soreceive,
82a557af22SRobert Watson 	sopoll,
83a557af22SRobert Watson 	pru_sosetlabel_null
84878ed226SJulian Elischer };
85878ed226SJulian Elischer 
86878ed226SJulian Elischer /*
87878ed226SJulian Elischer  * Bluetooth raw L2CAP sockets
88878ed226SJulian Elischer  */
89878ed226SJulian Elischer 
90878ed226SJulian Elischer static struct pr_usrreqs	ng_btsocket_l2cap_raw_usrreqs = {
91878ed226SJulian Elischer 	ng_btsocket_l2cap_raw_abort,	/* abort */
92878ed226SJulian Elischer 	pru_accept_notsupp,		/* accept */
93878ed226SJulian Elischer 	ng_btsocket_l2cap_raw_attach,	/* attach */
94878ed226SJulian Elischer 	ng_btsocket_l2cap_raw_bind,	/* bind */
95878ed226SJulian Elischer 	ng_btsocket_l2cap_raw_connect,	/* connect */
96878ed226SJulian Elischer 	pru_connect2_notsupp,		/* connect2 */
97878ed226SJulian Elischer 	ng_btsocket_l2cap_raw_control,	/* control */
98878ed226SJulian Elischer 	ng_btsocket_l2cap_raw_detach,	/* detach */
99878ed226SJulian Elischer 	ng_btsocket_l2cap_raw_disconnect, /* disconnect */
100878ed226SJulian Elischer         pru_listen_notsupp,		/* listen */
101878ed226SJulian Elischer 	ng_btsocket_l2cap_raw_peeraddr,	/* peeraddr */
102878ed226SJulian Elischer 	pru_rcvd_notsupp,		/* rcvd */
103878ed226SJulian Elischer 	pru_rcvoob_notsupp,		/* rcvoob */
104878ed226SJulian Elischer 	ng_btsocket_l2cap_raw_send,	/* send */
105878ed226SJulian Elischer 	pru_sense_null,			/* send */
106878ed226SJulian Elischer 	NULL,				/* shutdown */
107878ed226SJulian Elischer 	ng_btsocket_l2cap_raw_sockaddr,	/* sockaddr */
108878ed226SJulian Elischer 	sosend,
109878ed226SJulian Elischer 	soreceive,
110a557af22SRobert Watson 	sopoll,
111a557af22SRobert Watson 	pru_sosetlabel_null
112878ed226SJulian Elischer };
113878ed226SJulian Elischer 
114878ed226SJulian Elischer /*
115878ed226SJulian Elischer  * Bluetooth SEQPACKET L2CAP sockets
116878ed226SJulian Elischer  */
117878ed226SJulian Elischer 
118878ed226SJulian Elischer static struct pr_usrreqs	ng_btsocket_l2cap_usrreqs = {
119878ed226SJulian Elischer 	ng_btsocket_l2cap_abort,	/* abort */
120878ed226SJulian Elischer 	ng_btsocket_l2cap_accept,	/* accept */
121878ed226SJulian Elischer 	ng_btsocket_l2cap_attach,	/* attach */
122878ed226SJulian Elischer 	ng_btsocket_l2cap_bind,		/* bind */
123878ed226SJulian Elischer 	ng_btsocket_l2cap_connect,	/* connect */
124878ed226SJulian Elischer 	pru_connect2_notsupp,		/* connect2 */
125878ed226SJulian Elischer 	ng_btsocket_l2cap_control,	/* control */
126878ed226SJulian Elischer 	ng_btsocket_l2cap_detach,	/* detach */
127878ed226SJulian Elischer 	ng_btsocket_l2cap_disconnect,	/* disconnect */
128878ed226SJulian Elischer         ng_btsocket_l2cap_listen,	/* listen */
129878ed226SJulian Elischer 	ng_btsocket_l2cap_peeraddr,	/* peeraddr */
130878ed226SJulian Elischer 	pru_rcvd_notsupp,		/* rcvd */
131878ed226SJulian Elischer 	pru_rcvoob_notsupp,		/* rcvoob */
132878ed226SJulian Elischer 	ng_btsocket_l2cap_send,		/* send */
133878ed226SJulian Elischer 	pru_sense_null,			/* send */
134878ed226SJulian Elischer 	NULL,				/* shutdown */
135878ed226SJulian Elischer 	ng_btsocket_l2cap_sockaddr,	/* sockaddr */
136878ed226SJulian Elischer 	sosend,
137878ed226SJulian Elischer 	soreceive,
138a557af22SRobert Watson 	sopoll,
139a557af22SRobert Watson 	pru_sosetlabel_null
140878ed226SJulian Elischer };
141878ed226SJulian Elischer 
142878ed226SJulian Elischer /*
143f2bb1caeSJulian Elischer  * Bluetooth STREAM RFCOMM sockets
144f2bb1caeSJulian Elischer  */
145f2bb1caeSJulian Elischer 
146f2bb1caeSJulian Elischer static struct pr_usrreqs	ng_btsocket_rfcomm_usrreqs = {
147f2bb1caeSJulian Elischer 	ng_btsocket_rfcomm_abort,	/* abort */
148f2bb1caeSJulian Elischer 	ng_btsocket_rfcomm_accept,	/* accept */
149f2bb1caeSJulian Elischer 	ng_btsocket_rfcomm_attach,	/* attach */
150f2bb1caeSJulian Elischer 	ng_btsocket_rfcomm_bind,	/* bind */
151f2bb1caeSJulian Elischer 	ng_btsocket_rfcomm_connect,	/* connect */
152f2bb1caeSJulian Elischer 	pru_connect2_notsupp,		/* connect2 */
153f2bb1caeSJulian Elischer 	ng_btsocket_rfcomm_control,	/* control */
154f2bb1caeSJulian Elischer 	ng_btsocket_rfcomm_detach,	/* detach */
155f2bb1caeSJulian Elischer 	ng_btsocket_rfcomm_disconnect,	/* disconnect */
156f2bb1caeSJulian Elischer         ng_btsocket_rfcomm_listen,	/* listen */
157f2bb1caeSJulian Elischer 	ng_btsocket_rfcomm_peeraddr,	/* peeraddr */
158f2bb1caeSJulian Elischer 	pru_rcvd_notsupp,		/* rcvd */
159f2bb1caeSJulian Elischer 	pru_rcvoob_notsupp,		/* rcvoob */
160f2bb1caeSJulian Elischer 	ng_btsocket_rfcomm_send,	/* send */
161f2bb1caeSJulian Elischer 	pru_sense_null,			/* send */
162f2bb1caeSJulian Elischer 	NULL,				/* shutdown */
163f2bb1caeSJulian Elischer 	ng_btsocket_rfcomm_sockaddr,	/* sockaddr */
164f2bb1caeSJulian Elischer 	sosend,
165f2bb1caeSJulian Elischer 	soreceive,
166a557af22SRobert Watson 	sopoll,
167a557af22SRobert Watson 	pru_sosetlabel_null
168f2bb1caeSJulian Elischer };
169f2bb1caeSJulian Elischer 
170f2bb1caeSJulian Elischer /*
171878ed226SJulian Elischer  * Definitions of protocols supported in the BLUETOOTH domain
172878ed226SJulian Elischer  */
173878ed226SJulian Elischer 
174878ed226SJulian Elischer static struct protosw		ng_btsocket_protosw[] = {
175878ed226SJulian Elischer {
176878ed226SJulian Elischer 	SOCK_RAW,			/* protocol type */
177878ed226SJulian Elischer 	&ng_btsocket_domain,		/* backpointer to domain */
178878ed226SJulian Elischer 	BLUETOOTH_PROTO_HCI,		/* protocol */
179878ed226SJulian Elischer 	PR_ATOMIC | PR_ADDR,		/* flags */
180878ed226SJulian Elischer 	NULL, NULL, NULL,		/* input, output, ctlinput */
181878ed226SJulian Elischer 	ng_btsocket_hci_raw_ctloutput,	/* ctloutput */
182878ed226SJulian Elischer 	NULL,				/* ousrreq() */
183878ed226SJulian Elischer 	ng_btsocket_hci_raw_init,	/* init */
184878ed226SJulian Elischer 	NULL, NULL, NULL,		/* fasttimeo, slowtimo, drain */
185878ed226SJulian Elischer 	&ng_btsocket_hci_raw_usrreqs,	/* usrreq table (above) */
186878ed226SJulian Elischer 	/* { NULL } */			/* pfh (protocol filter head?) */
187878ed226SJulian Elischer },
188878ed226SJulian Elischer {
189878ed226SJulian Elischer 	SOCK_RAW,			/* protocol type */
190878ed226SJulian Elischer 	&ng_btsocket_domain,		/* backpointer to domain */
191878ed226SJulian Elischer 	BLUETOOTH_PROTO_L2CAP,		/* protocol */
192878ed226SJulian Elischer 	PR_ATOMIC | PR_ADDR,		/* flags */
193878ed226SJulian Elischer 	NULL, NULL, NULL,		/* input, output, ctlinput */
194878ed226SJulian Elischer 	NULL,				/* ctloutput */
195878ed226SJulian Elischer 	NULL,				/* ousrreq() */
196878ed226SJulian Elischer 	ng_btsocket_l2cap_raw_init,	/* init */
197878ed226SJulian Elischer 	NULL, NULL, NULL,		/* fasttimeo, slowtimo, drain */
198878ed226SJulian Elischer 	&ng_btsocket_l2cap_raw_usrreqs,	/* usrreq table (above) */
199878ed226SJulian Elischer 	/* { NULL } */			/* pfh (protocol filter head?) */
200878ed226SJulian Elischer },
201878ed226SJulian Elischer {
202878ed226SJulian Elischer 	SOCK_SEQPACKET,			/* protocol type */
203878ed226SJulian Elischer 	&ng_btsocket_domain,		/* backpointer to domain */
204878ed226SJulian Elischer 	BLUETOOTH_PROTO_L2CAP,		/* protocol */
205878ed226SJulian Elischer 	PR_ATOMIC | PR_CONNREQUIRED,	/* flags */
206878ed226SJulian Elischer 	NULL, NULL, NULL,		/* input, output, ctlinput */
207878ed226SJulian Elischer 	ng_btsocket_l2cap_ctloutput,	/* ctloutput */
208878ed226SJulian Elischer 	NULL,				/* ousrreq() */
209878ed226SJulian Elischer 	ng_btsocket_l2cap_init,		/* init */
210878ed226SJulian Elischer 	NULL, NULL, NULL,		/* fasttimeo, slowtimo, drain */
211878ed226SJulian Elischer 	&ng_btsocket_l2cap_usrreqs,	/* usrreq table (above) */
212878ed226SJulian Elischer 	/* { NULL } */			/* pfh (protocol filter head?) */
213f2bb1caeSJulian Elischer },
214f2bb1caeSJulian Elischer {
215f2bb1caeSJulian Elischer 	SOCK_STREAM,			/* protocol type */
216f2bb1caeSJulian Elischer 	&ng_btsocket_domain,		/* backpointer to domain */
217f2bb1caeSJulian Elischer 	BLUETOOTH_PROTO_RFCOMM,		/* protocol */
218f2bb1caeSJulian Elischer 	PR_ATOMIC | PR_CONNREQUIRED,	/* flags */
219f2bb1caeSJulian Elischer 	NULL, NULL, NULL,		/* input, output, ctlinput */
220f2bb1caeSJulian Elischer 	ng_btsocket_rfcomm_ctloutput,	/* ctloutput */
221f2bb1caeSJulian Elischer 	NULL,				/* ousrreq() */
222f2bb1caeSJulian Elischer 	ng_btsocket_rfcomm_init,	/* init */
223f2bb1caeSJulian Elischer 	NULL, NULL, NULL,		/* fasttimeo, slowtimo, drain */
224f2bb1caeSJulian Elischer 	&ng_btsocket_rfcomm_usrreqs,	/* usrreq table (above) */
225f2bb1caeSJulian Elischer 	/* { NULL } */			/* pfh (protocol filter head?) */
226878ed226SJulian Elischer }
227878ed226SJulian Elischer };
228878ed226SJulian Elischer #define ng_btsocket_protosw_size \
229878ed226SJulian Elischer 	(sizeof(ng_btsocket_protosw)/sizeof(ng_btsocket_protosw[0]))
230878ed226SJulian Elischer #define ng_btsocket_protosw_end \
231878ed226SJulian Elischer 	&ng_btsocket_protosw[ng_btsocket_protosw_size]
232878ed226SJulian Elischer 
233878ed226SJulian Elischer /*
234878ed226SJulian Elischer  * BLUETOOTH domain
235878ed226SJulian Elischer  */
236878ed226SJulian Elischer 
237878ed226SJulian Elischer struct domain			ng_btsocket_domain = {
238878ed226SJulian Elischer 	AF_BLUETOOTH,			/* family */
239878ed226SJulian Elischer 	"bluetooth",			/* domain name */
240878ed226SJulian Elischer 	NULL,				/* init() */
241878ed226SJulian Elischer 	NULL,				/* externalize() */
242878ed226SJulian Elischer 	NULL,				/* dispose() */
243878ed226SJulian Elischer 	ng_btsocket_protosw,		/* protosw entry */
244878ed226SJulian Elischer 	ng_btsocket_protosw_end,	/* end of protosw entries */
245878ed226SJulian Elischer 	NULL,				/* next domain in list */
246878ed226SJulian Elischer 	NULL,				/* rtattach() */
247878ed226SJulian Elischer 	0,				/* arg to rtattach in bits */
248878ed226SJulian Elischer 	0				/* maxrtkey */
249878ed226SJulian Elischer };
250878ed226SJulian Elischer 
251878ed226SJulian Elischer /*
252878ed226SJulian Elischer  * Socket sysctl tree
253878ed226SJulian Elischer  */
254878ed226SJulian Elischer 
255878ed226SJulian Elischer SYSCTL_NODE(_net_bluetooth_hci, OID_AUTO, sockets, CTLFLAG_RW,
256878ed226SJulian Elischer 	0, "Bluetooth HCI sockets family");
257878ed226SJulian Elischer SYSCTL_NODE(_net_bluetooth_l2cap, OID_AUTO, sockets, CTLFLAG_RW,
258878ed226SJulian Elischer 	0, "Bluetooth L2CAP sockets family");
259f2bb1caeSJulian Elischer SYSCTL_NODE(_net_bluetooth_rfcomm, OID_AUTO, sockets, CTLFLAG_RW,
260f2bb1caeSJulian Elischer 	0, "Bluetooth RFCOMM sockets family");
261878ed226SJulian Elischer 
262878ed226SJulian Elischer /*
263878ed226SJulian Elischer  * Module
264878ed226SJulian Elischer  */
265878ed226SJulian Elischer 
266878ed226SJulian Elischer static moduledata_t	ng_btsocket_mod = {
267878ed226SJulian Elischer 	"ng_btsocket",
268878ed226SJulian Elischer 	ng_btsocket_modevent,
269878ed226SJulian Elischer 	NULL
270878ed226SJulian Elischer };
271878ed226SJulian Elischer 
272878ed226SJulian Elischer DECLARE_MODULE(ng_btsocket, ng_btsocket_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
273878ed226SJulian Elischer MODULE_VERSION(ng_btsocket, NG_BLUETOOTH_VERSION);
274878ed226SJulian Elischer MODULE_DEPEND(ng_btsocket, ng_bluetooth, NG_BLUETOOTH_VERSION,
275878ed226SJulian Elischer 	NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION);
276878ed226SJulian Elischer MODULE_DEPEND(ng_btsocket, netgraph, NG_ABI_VERSION,
277878ed226SJulian Elischer 	NG_ABI_VERSION, NG_ABI_VERSION);
278878ed226SJulian Elischer 
279878ed226SJulian Elischer /*
280878ed226SJulian Elischer  * Handle loading and unloading for this node type.
281878ed226SJulian Elischer  * This is to handle auxiliary linkages (e.g protocol domain addition).
282878ed226SJulian Elischer  */
283878ed226SJulian Elischer 
284878ed226SJulian Elischer static int
285878ed226SJulian Elischer ng_btsocket_modevent(module_t mod, int event, void *data)
286878ed226SJulian Elischer {
287878ed226SJulian Elischer 	int	error = 0;
288878ed226SJulian Elischer 
289878ed226SJulian Elischer 	switch (event) {
290878ed226SJulian Elischer 	case MOD_LOAD:
291878ed226SJulian Elischer 		net_add_domain(&ng_btsocket_domain);
292878ed226SJulian Elischer 		break;
293878ed226SJulian Elischer 
294878ed226SJulian Elischer 	case MOD_UNLOAD:
295878ed226SJulian Elischer 		/* XXX can't unload protocol domain yet */
296878ed226SJulian Elischer 		error = EBUSY;
297878ed226SJulian Elischer 		break;
298878ed226SJulian Elischer 
299878ed226SJulian Elischer 	default:
300878ed226SJulian Elischer 		error = EOPNOTSUPP;
301878ed226SJulian Elischer 		break;
302878ed226SJulian Elischer 	}
303878ed226SJulian Elischer 
304878ed226SJulian Elischer 	return (error);
305878ed226SJulian Elischer } /* ng_btsocket_modevent */
306878ed226SJulian Elischer 
307