ng_btsocket.c revision 122875
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.4 2003/09/14 23:29:06 max Exp $
29 * $FreeBSD: head/sys/netgraph/bluetooth/socket/ng_btsocket.c 122875 2003-11-18 00:39:07Z rwatson $
30 */
31
32#include <sys/param.h>
33#include <sys/systm.h>
34#include <sys/bitstring.h>
35#include <sys/errno.h>
36#include <sys/domain.h>
37#include <sys/kernel.h>
38#include <sys/lock.h>
39#include <sys/mutex.h>
40#include <sys/protosw.h>
41#include <sys/socket.h>
42#include <sys/socketvar.h>
43#include <sys/sysctl.h>
44#include <sys/taskqueue.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	pru_sosetlabel_null
84};
85
86/*
87 * Bluetooth raw L2CAP sockets
88 */
89
90static struct pr_usrreqs	ng_btsocket_l2cap_raw_usrreqs = {
91	ng_btsocket_l2cap_raw_abort,	/* abort */
92	pru_accept_notsupp,		/* accept */
93	ng_btsocket_l2cap_raw_attach,	/* attach */
94	ng_btsocket_l2cap_raw_bind,	/* bind */
95	ng_btsocket_l2cap_raw_connect,	/* connect */
96	pru_connect2_notsupp,		/* connect2 */
97	ng_btsocket_l2cap_raw_control,	/* control */
98	ng_btsocket_l2cap_raw_detach,	/* detach */
99	ng_btsocket_l2cap_raw_disconnect, /* disconnect */
100        pru_listen_notsupp,		/* listen */
101	ng_btsocket_l2cap_raw_peeraddr,	/* peeraddr */
102	pru_rcvd_notsupp,		/* rcvd */
103	pru_rcvoob_notsupp,		/* rcvoob */
104	ng_btsocket_l2cap_raw_send,	/* send */
105	pru_sense_null,			/* send */
106	NULL,				/* shutdown */
107	ng_btsocket_l2cap_raw_sockaddr,	/* sockaddr */
108	sosend,
109	soreceive,
110	sopoll,
111	pru_sosetlabel_null
112};
113
114/*
115 * Bluetooth SEQPACKET L2CAP sockets
116 */
117
118static struct pr_usrreqs	ng_btsocket_l2cap_usrreqs = {
119	ng_btsocket_l2cap_abort,	/* abort */
120	ng_btsocket_l2cap_accept,	/* accept */
121	ng_btsocket_l2cap_attach,	/* attach */
122	ng_btsocket_l2cap_bind,		/* bind */
123	ng_btsocket_l2cap_connect,	/* connect */
124	pru_connect2_notsupp,		/* connect2 */
125	ng_btsocket_l2cap_control,	/* control */
126	ng_btsocket_l2cap_detach,	/* detach */
127	ng_btsocket_l2cap_disconnect,	/* disconnect */
128        ng_btsocket_l2cap_listen,	/* listen */
129	ng_btsocket_l2cap_peeraddr,	/* peeraddr */
130	pru_rcvd_notsupp,		/* rcvd */
131	pru_rcvoob_notsupp,		/* rcvoob */
132	ng_btsocket_l2cap_send,		/* send */
133	pru_sense_null,			/* send */
134	NULL,				/* shutdown */
135	ng_btsocket_l2cap_sockaddr,	/* sockaddr */
136	sosend,
137	soreceive,
138	sopoll,
139	pru_sosetlabel_null
140};
141
142/*
143 * Bluetooth STREAM RFCOMM sockets
144 */
145
146static struct pr_usrreqs	ng_btsocket_rfcomm_usrreqs = {
147	ng_btsocket_rfcomm_abort,	/* abort */
148	ng_btsocket_rfcomm_accept,	/* accept */
149	ng_btsocket_rfcomm_attach,	/* attach */
150	ng_btsocket_rfcomm_bind,	/* bind */
151	ng_btsocket_rfcomm_connect,	/* connect */
152	pru_connect2_notsupp,		/* connect2 */
153	ng_btsocket_rfcomm_control,	/* control */
154	ng_btsocket_rfcomm_detach,	/* detach */
155	ng_btsocket_rfcomm_disconnect,	/* disconnect */
156        ng_btsocket_rfcomm_listen,	/* listen */
157	ng_btsocket_rfcomm_peeraddr,	/* peeraddr */
158	pru_rcvd_notsupp,		/* rcvd */
159	pru_rcvoob_notsupp,		/* rcvoob */
160	ng_btsocket_rfcomm_send,	/* send */
161	pru_sense_null,			/* send */
162	NULL,				/* shutdown */
163	ng_btsocket_rfcomm_sockaddr,	/* sockaddr */
164	sosend,
165	soreceive,
166	sopoll,
167	pru_sosetlabel_null
168};
169
170/*
171 * Definitions of protocols supported in the BLUETOOTH domain
172 */
173
174static struct protosw		ng_btsocket_protosw[] = {
175{
176	SOCK_RAW,			/* protocol type */
177	&ng_btsocket_domain,		/* backpointer to domain */
178	BLUETOOTH_PROTO_HCI,		/* protocol */
179	PR_ATOMIC | PR_ADDR,		/* flags */
180	NULL, NULL, NULL,		/* input, output, ctlinput */
181	ng_btsocket_hci_raw_ctloutput,	/* ctloutput */
182	NULL,				/* ousrreq() */
183	ng_btsocket_hci_raw_init,	/* init */
184	NULL, NULL, NULL,		/* fasttimeo, slowtimo, drain */
185	&ng_btsocket_hci_raw_usrreqs,	/* usrreq table (above) */
186	/* { NULL } */			/* pfh (protocol filter head?) */
187},
188{
189	SOCK_RAW,			/* protocol type */
190	&ng_btsocket_domain,		/* backpointer to domain */
191	BLUETOOTH_PROTO_L2CAP,		/* protocol */
192	PR_ATOMIC | PR_ADDR,		/* flags */
193	NULL, NULL, NULL,		/* input, output, ctlinput */
194	NULL,				/* ctloutput */
195	NULL,				/* ousrreq() */
196	ng_btsocket_l2cap_raw_init,	/* init */
197	NULL, NULL, NULL,		/* fasttimeo, slowtimo, drain */
198	&ng_btsocket_l2cap_raw_usrreqs,	/* usrreq table (above) */
199	/* { NULL } */			/* pfh (protocol filter head?) */
200},
201{
202	SOCK_SEQPACKET,			/* protocol type */
203	&ng_btsocket_domain,		/* backpointer to domain */
204	BLUETOOTH_PROTO_L2CAP,		/* protocol */
205	PR_ATOMIC | PR_CONNREQUIRED,	/* flags */
206	NULL, NULL, NULL,		/* input, output, ctlinput */
207	ng_btsocket_l2cap_ctloutput,	/* ctloutput */
208	NULL,				/* ousrreq() */
209	ng_btsocket_l2cap_init,		/* init */
210	NULL, NULL, NULL,		/* fasttimeo, slowtimo, drain */
211	&ng_btsocket_l2cap_usrreqs,	/* usrreq table (above) */
212	/* { NULL } */			/* pfh (protocol filter head?) */
213},
214{
215	SOCK_STREAM,			/* protocol type */
216	&ng_btsocket_domain,		/* backpointer to domain */
217	BLUETOOTH_PROTO_RFCOMM,		/* protocol */
218	PR_ATOMIC | PR_CONNREQUIRED,	/* flags */
219	NULL, NULL, NULL,		/* input, output, ctlinput */
220	ng_btsocket_rfcomm_ctloutput,	/* ctloutput */
221	NULL,				/* ousrreq() */
222	ng_btsocket_rfcomm_init,	/* init */
223	NULL, NULL, NULL,		/* fasttimeo, slowtimo, drain */
224	&ng_btsocket_rfcomm_usrreqs,	/* usrreq table (above) */
225	/* { NULL } */			/* pfh (protocol filter head?) */
226}
227};
228#define ng_btsocket_protosw_size \
229	(sizeof(ng_btsocket_protosw)/sizeof(ng_btsocket_protosw[0]))
230#define ng_btsocket_protosw_end \
231	&ng_btsocket_protosw[ng_btsocket_protosw_size]
232
233/*
234 * BLUETOOTH domain
235 */
236
237struct domain			ng_btsocket_domain = {
238	AF_BLUETOOTH,			/* family */
239	"bluetooth",			/* domain name */
240	NULL,				/* init() */
241	NULL,				/* externalize() */
242	NULL,				/* dispose() */
243	ng_btsocket_protosw,		/* protosw entry */
244	ng_btsocket_protosw_end,	/* end of protosw entries */
245	NULL,				/* next domain in list */
246	NULL,				/* rtattach() */
247	0,				/* arg to rtattach in bits */
248	0				/* maxrtkey */
249};
250
251/*
252 * Socket sysctl tree
253 */
254
255SYSCTL_NODE(_net_bluetooth_hci, OID_AUTO, sockets, CTLFLAG_RW,
256	0, "Bluetooth HCI sockets family");
257SYSCTL_NODE(_net_bluetooth_l2cap, OID_AUTO, sockets, CTLFLAG_RW,
258	0, "Bluetooth L2CAP sockets family");
259SYSCTL_NODE(_net_bluetooth_rfcomm, OID_AUTO, sockets, CTLFLAG_RW,
260	0, "Bluetooth RFCOMM sockets family");
261
262/*
263 * Module
264 */
265
266static moduledata_t	ng_btsocket_mod = {
267	"ng_btsocket",
268	ng_btsocket_modevent,
269	NULL
270};
271
272DECLARE_MODULE(ng_btsocket, ng_btsocket_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
273MODULE_VERSION(ng_btsocket, NG_BLUETOOTH_VERSION);
274MODULE_DEPEND(ng_btsocket, ng_bluetooth, NG_BLUETOOTH_VERSION,
275	NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION);
276MODULE_DEPEND(ng_btsocket, netgraph, NG_ABI_VERSION,
277	NG_ABI_VERSION, NG_ABI_VERSION);
278
279/*
280 * Handle loading and unloading for this node type.
281 * This is to handle auxiliary linkages (e.g protocol domain addition).
282 */
283
284static int
285ng_btsocket_modevent(module_t mod, int event, void *data)
286{
287	int	error = 0;
288
289	switch (event) {
290	case MOD_LOAD:
291		net_add_domain(&ng_btsocket_domain);
292		break;
293
294	case MOD_UNLOAD:
295		/* XXX can't unload protocol domain yet */
296		error = EBUSY;
297		break;
298
299	default:
300		error = EOPNOTSUPP;
301		break;
302	}
303
304	return (error);
305} /* ng_btsocket_modevent */
306
307