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