ng_btsocket.c revision 114878
1107120Sjulian/*
2107120Sjulian * ng_btsocket.c
3107120Sjulian *
4107120Sjulian * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
5107120Sjulian * All rights reserved.
6107120Sjulian *
7107120Sjulian * Redistribution and use in source and binary forms, with or without
8107120Sjulian * modification, are permitted provided that the following conditions
9107120Sjulian * are met:
10107120Sjulian * 1. Redistributions of source code must retain the above copyright
11107120Sjulian *    notice, this list of conditions and the following disclaimer.
12107120Sjulian * 2. Redistributions in binary form must reproduce the above copyright
13107120Sjulian *    notice, this list of conditions and the following disclaimer in the
14107120Sjulian *    documentation and/or other materials provided with the distribution.
15107120Sjulian *
16107120Sjulian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17107120Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18107120Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19107120Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20107120Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21107120Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22107120Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23107120Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24107120Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25107120Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26107120Sjulian * SUCH DAMAGE.
27107120Sjulian *
28114878Sjulian * $Id: ng_btsocket.c,v 1.3 2003/01/19 00:19:04 max Exp $
29107120Sjulian * $FreeBSD: head/sys/netgraph/bluetooth/socket/ng_btsocket.c 114878 2003-05-10 21:44:42Z julian $
30107120Sjulian */
31107120Sjulian
32107120Sjulian#include <sys/param.h>
33107120Sjulian#include <sys/systm.h>
34107120Sjulian#include <sys/errno.h>
35107120Sjulian#include <sys/domain.h>
36107120Sjulian#include <sys/kernel.h>
37107120Sjulian#include <sys/lock.h>
38107120Sjulian#include <sys/mutex.h>
39107120Sjulian#include <sys/protosw.h>
40107120Sjulian#include <sys/socket.h>
41107120Sjulian#include <sys/socketvar.h>
42107120Sjulian#include <sys/sysctl.h>
43114878Sjulian#include <sys/taskqueue.h>
44107120Sjulian#include <bitstring.h>
45107120Sjulian#include <netgraph/ng_message.h>
46107120Sjulian#include <netgraph/netgraph.h>
47107120Sjulian#include "ng_bluetooth.h"
48107120Sjulian#include "ng_hci.h"
49107120Sjulian#include "ng_l2cap.h"
50107120Sjulian#include "ng_btsocket.h"
51107120Sjulian#include "ng_btsocket_hci_raw.h"
52107120Sjulian#include "ng_btsocket_l2cap.h"
53114878Sjulian#include "ng_btsocket_rfcomm.h"
54107120Sjulian
55107120Sjulianstatic int			ng_btsocket_modevent (module_t, int, void *);
56107120Sjulianextern struct domain		ng_btsocket_domain;
57107120Sjulian
58107120Sjulian/*
59107120Sjulian * Bluetooth raw HCI sockets
60107120Sjulian */
61107120Sjulian
62107120Sjulianstatic struct pr_usrreqs	ng_btsocket_hci_raw_usrreqs = {
63107120Sjulian	ng_btsocket_hci_raw_abort,	/* abort */
64107120Sjulian	pru_accept_notsupp,		/* accept */
65107120Sjulian	ng_btsocket_hci_raw_attach,	/* attach */
66107120Sjulian	ng_btsocket_hci_raw_bind,	/* bind */
67107120Sjulian	ng_btsocket_hci_raw_connect,	/* connect */
68107120Sjulian	pru_connect2_notsupp,		/* connect2 */
69107120Sjulian	ng_btsocket_hci_raw_control,	/* control */
70107120Sjulian	ng_btsocket_hci_raw_detach,	/* detach */
71107120Sjulian	ng_btsocket_hci_raw_disconnect,	/* disconnect */
72107120Sjulian	pru_listen_notsupp,		/* listen */
73107120Sjulian	ng_btsocket_hci_raw_peeraddr,	/* peeraddr */
74107120Sjulian	pru_rcvd_notsupp,		/* rcvd */
75107120Sjulian	pru_rcvoob_notsupp,		/* rcvoob */
76107120Sjulian	ng_btsocket_hci_raw_send,	/* send */
77107120Sjulian	pru_sense_null,			/* send */
78107120Sjulian	NULL,				/* shutdown */
79107120Sjulian	ng_btsocket_hci_raw_sockaddr,	/* sockaddr */
80107120Sjulian	sosend,
81107120Sjulian	soreceive,
82107120Sjulian	sopoll
83107120Sjulian};
84107120Sjulian
85107120Sjulian/*
86107120Sjulian * Bluetooth raw L2CAP sockets
87107120Sjulian */
88107120Sjulian
89107120Sjulianstatic struct pr_usrreqs	ng_btsocket_l2cap_raw_usrreqs = {
90107120Sjulian	ng_btsocket_l2cap_raw_abort,	/* abort */
91107120Sjulian	pru_accept_notsupp,		/* accept */
92107120Sjulian	ng_btsocket_l2cap_raw_attach,	/* attach */
93107120Sjulian	ng_btsocket_l2cap_raw_bind,	/* bind */
94107120Sjulian	ng_btsocket_l2cap_raw_connect,	/* connect */
95107120Sjulian	pru_connect2_notsupp,		/* connect2 */
96107120Sjulian	ng_btsocket_l2cap_raw_control,	/* control */
97107120Sjulian	ng_btsocket_l2cap_raw_detach,	/* detach */
98107120Sjulian	ng_btsocket_l2cap_raw_disconnect, /* disconnect */
99107120Sjulian        pru_listen_notsupp,		/* listen */
100107120Sjulian	ng_btsocket_l2cap_raw_peeraddr,	/* peeraddr */
101107120Sjulian	pru_rcvd_notsupp,		/* rcvd */
102107120Sjulian	pru_rcvoob_notsupp,		/* rcvoob */
103107120Sjulian	ng_btsocket_l2cap_raw_send,	/* send */
104107120Sjulian	pru_sense_null,			/* send */
105107120Sjulian	NULL,				/* shutdown */
106107120Sjulian	ng_btsocket_l2cap_raw_sockaddr,	/* sockaddr */
107107120Sjulian	sosend,
108107120Sjulian	soreceive,
109107120Sjulian	sopoll
110107120Sjulian};
111107120Sjulian
112107120Sjulian/*
113107120Sjulian * Bluetooth SEQPACKET L2CAP sockets
114107120Sjulian */
115107120Sjulian
116107120Sjulianstatic struct pr_usrreqs	ng_btsocket_l2cap_usrreqs = {
117107120Sjulian	ng_btsocket_l2cap_abort,	/* abort */
118107120Sjulian	ng_btsocket_l2cap_accept,	/* accept */
119107120Sjulian	ng_btsocket_l2cap_attach,	/* attach */
120107120Sjulian	ng_btsocket_l2cap_bind,		/* bind */
121107120Sjulian	ng_btsocket_l2cap_connect,	/* connect */
122107120Sjulian	pru_connect2_notsupp,		/* connect2 */
123107120Sjulian	ng_btsocket_l2cap_control,	/* control */
124107120Sjulian	ng_btsocket_l2cap_detach,	/* detach */
125107120Sjulian	ng_btsocket_l2cap_disconnect,	/* disconnect */
126107120Sjulian        ng_btsocket_l2cap_listen,	/* listen */
127107120Sjulian	ng_btsocket_l2cap_peeraddr,	/* peeraddr */
128107120Sjulian	pru_rcvd_notsupp,		/* rcvd */
129107120Sjulian	pru_rcvoob_notsupp,		/* rcvoob */
130107120Sjulian	ng_btsocket_l2cap_send,		/* send */
131107120Sjulian	pru_sense_null,			/* send */
132107120Sjulian	NULL,				/* shutdown */
133107120Sjulian	ng_btsocket_l2cap_sockaddr,	/* sockaddr */
134107120Sjulian	sosend,
135107120Sjulian	soreceive,
136107120Sjulian	sopoll
137107120Sjulian};
138107120Sjulian
139114878Sjulian/*
140114878Sjulian * Bluetooth STREAM RFCOMM sockets
141114878Sjulian */
142114878Sjulian
143114878Sjulianstatic struct pr_usrreqs	ng_btsocket_rfcomm_usrreqs = {
144114878Sjulian	ng_btsocket_rfcomm_abort,	/* abort */
145114878Sjulian	ng_btsocket_rfcomm_accept,	/* accept */
146114878Sjulian	ng_btsocket_rfcomm_attach,	/* attach */
147114878Sjulian	ng_btsocket_rfcomm_bind,	/* bind */
148114878Sjulian	ng_btsocket_rfcomm_connect,	/* connect */
149114878Sjulian	pru_connect2_notsupp,		/* connect2 */
150114878Sjulian	ng_btsocket_rfcomm_control,	/* control */
151114878Sjulian	ng_btsocket_rfcomm_detach,	/* detach */
152114878Sjulian	ng_btsocket_rfcomm_disconnect,	/* disconnect */
153114878Sjulian        ng_btsocket_rfcomm_listen,	/* listen */
154114878Sjulian	ng_btsocket_rfcomm_peeraddr,	/* peeraddr */
155114878Sjulian	pru_rcvd_notsupp,		/* rcvd */
156114878Sjulian	pru_rcvoob_notsupp,		/* rcvoob */
157114878Sjulian	ng_btsocket_rfcomm_send,	/* send */
158114878Sjulian	pru_sense_null,			/* send */
159114878Sjulian	NULL,				/* shutdown */
160114878Sjulian	ng_btsocket_rfcomm_sockaddr,	/* sockaddr */
161114878Sjulian	sosend,
162114878Sjulian	soreceive,
163114878Sjulian	sopoll
164114878Sjulian};
165114878Sjulian
166107120Sjulian/*
167107120Sjulian * Definitions of protocols supported in the BLUETOOTH domain
168107120Sjulian */
169107120Sjulian
170107120Sjulianstatic struct protosw		ng_btsocket_protosw[] = {
171107120Sjulian{
172107120Sjulian	SOCK_RAW,			/* protocol type */
173107120Sjulian	&ng_btsocket_domain,		/* backpointer to domain */
174107120Sjulian	BLUETOOTH_PROTO_HCI,		/* protocol */
175107120Sjulian	PR_ATOMIC | PR_ADDR,		/* flags */
176107120Sjulian	NULL, NULL, NULL,		/* input, output, ctlinput */
177107120Sjulian	ng_btsocket_hci_raw_ctloutput,	/* ctloutput */
178107120Sjulian	NULL,				/* ousrreq() */
179107120Sjulian	ng_btsocket_hci_raw_init,	/* init */
180107120Sjulian	NULL, NULL, NULL,		/* fasttimeo, slowtimo, drain */
181107120Sjulian	&ng_btsocket_hci_raw_usrreqs,	/* usrreq table (above) */
182107120Sjulian	/* { NULL } */			/* pfh (protocol filter head?) */
183107120Sjulian},
184107120Sjulian{
185107120Sjulian	SOCK_RAW,			/* protocol type */
186107120Sjulian	&ng_btsocket_domain,		/* backpointer to domain */
187107120Sjulian	BLUETOOTH_PROTO_L2CAP,		/* protocol */
188107120Sjulian	PR_ATOMIC | PR_ADDR,		/* flags */
189107120Sjulian	NULL, NULL, NULL,		/* input, output, ctlinput */
190107120Sjulian	NULL,				/* ctloutput */
191107120Sjulian	NULL,				/* ousrreq() */
192107120Sjulian	ng_btsocket_l2cap_raw_init,	/* init */
193107120Sjulian	NULL, NULL, NULL,		/* fasttimeo, slowtimo, drain */
194107120Sjulian	&ng_btsocket_l2cap_raw_usrreqs,	/* usrreq table (above) */
195107120Sjulian	/* { NULL } */			/* pfh (protocol filter head?) */
196107120Sjulian},
197107120Sjulian{
198107120Sjulian	SOCK_SEQPACKET,			/* protocol type */
199107120Sjulian	&ng_btsocket_domain,		/* backpointer to domain */
200107120Sjulian	BLUETOOTH_PROTO_L2CAP,		/* protocol */
201107120Sjulian	PR_ATOMIC | PR_CONNREQUIRED,	/* flags */
202107120Sjulian	NULL, NULL, NULL,		/* input, output, ctlinput */
203107120Sjulian	ng_btsocket_l2cap_ctloutput,	/* ctloutput */
204107120Sjulian	NULL,				/* ousrreq() */
205107120Sjulian	ng_btsocket_l2cap_init,		/* init */
206107120Sjulian	NULL, NULL, NULL,		/* fasttimeo, slowtimo, drain */
207107120Sjulian	&ng_btsocket_l2cap_usrreqs,	/* usrreq table (above) */
208107120Sjulian	/* { NULL } */			/* pfh (protocol filter head?) */
209114878Sjulian},
210114878Sjulian{
211114878Sjulian	SOCK_STREAM,			/* protocol type */
212114878Sjulian	&ng_btsocket_domain,		/* backpointer to domain */
213114878Sjulian	BLUETOOTH_PROTO_RFCOMM,		/* protocol */
214114878Sjulian	PR_ATOMIC | PR_CONNREQUIRED,	/* flags */
215114878Sjulian	NULL, NULL, NULL,		/* input, output, ctlinput */
216114878Sjulian	ng_btsocket_rfcomm_ctloutput,	/* ctloutput */
217114878Sjulian	NULL,				/* ousrreq() */
218114878Sjulian	ng_btsocket_rfcomm_init,	/* init */
219114878Sjulian	NULL, NULL, NULL,		/* fasttimeo, slowtimo, drain */
220114878Sjulian	&ng_btsocket_rfcomm_usrreqs,	/* usrreq table (above) */
221114878Sjulian	/* { NULL } */			/* pfh (protocol filter head?) */
222107120Sjulian}
223107120Sjulian};
224107120Sjulian#define ng_btsocket_protosw_size \
225107120Sjulian	(sizeof(ng_btsocket_protosw)/sizeof(ng_btsocket_protosw[0]))
226107120Sjulian#define ng_btsocket_protosw_end \
227107120Sjulian	&ng_btsocket_protosw[ng_btsocket_protosw_size]
228107120Sjulian
229107120Sjulian/*
230107120Sjulian * BLUETOOTH domain
231107120Sjulian */
232107120Sjulian
233107120Sjulianstruct domain			ng_btsocket_domain = {
234107120Sjulian	AF_BLUETOOTH,			/* family */
235107120Sjulian	"bluetooth",			/* domain name */
236107120Sjulian	NULL,				/* init() */
237107120Sjulian	NULL,				/* externalize() */
238107120Sjulian	NULL,				/* dispose() */
239107120Sjulian	ng_btsocket_protosw,		/* protosw entry */
240107120Sjulian	ng_btsocket_protosw_end,	/* end of protosw entries */
241107120Sjulian	NULL,				/* next domain in list */
242107120Sjulian	NULL,				/* rtattach() */
243107120Sjulian	0,				/* arg to rtattach in bits */
244107120Sjulian	0				/* maxrtkey */
245107120Sjulian};
246107120Sjulian
247107120Sjulian/*
248107120Sjulian * Socket sysctl tree
249107120Sjulian */
250107120Sjulian
251107120SjulianSYSCTL_NODE(_net_bluetooth_hci, OID_AUTO, sockets, CTLFLAG_RW,
252107120Sjulian	0, "Bluetooth HCI sockets family");
253107120SjulianSYSCTL_NODE(_net_bluetooth_l2cap, OID_AUTO, sockets, CTLFLAG_RW,
254107120Sjulian	0, "Bluetooth L2CAP sockets family");
255114878SjulianSYSCTL_NODE(_net_bluetooth_rfcomm, OID_AUTO, sockets, CTLFLAG_RW,
256114878Sjulian	0, "Bluetooth RFCOMM sockets family");
257107120Sjulian
258107120Sjulian/*
259107120Sjulian * Module
260107120Sjulian */
261107120Sjulian
262107120Sjulianstatic moduledata_t	ng_btsocket_mod = {
263107120Sjulian	"ng_btsocket",
264107120Sjulian	ng_btsocket_modevent,
265107120Sjulian	NULL
266107120Sjulian};
267107120Sjulian
268107120SjulianDECLARE_MODULE(ng_btsocket, ng_btsocket_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
269107120SjulianMODULE_VERSION(ng_btsocket, NG_BLUETOOTH_VERSION);
270107120SjulianMODULE_DEPEND(ng_btsocket, ng_bluetooth, NG_BLUETOOTH_VERSION,
271107120Sjulian	NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION);
272107120SjulianMODULE_DEPEND(ng_btsocket, netgraph, NG_ABI_VERSION,
273107120Sjulian	NG_ABI_VERSION, NG_ABI_VERSION);
274107120Sjulian
275107120Sjulian/*
276107120Sjulian * Handle loading and unloading for this node type.
277107120Sjulian * This is to handle auxiliary linkages (e.g protocol domain addition).
278107120Sjulian */
279107120Sjulian
280107120Sjulianstatic int
281107120Sjulianng_btsocket_modevent(module_t mod, int event, void *data)
282107120Sjulian{
283107120Sjulian	int	error = 0;
284107120Sjulian
285107120Sjulian	switch (event) {
286107120Sjulian	case MOD_LOAD:
287107120Sjulian		net_add_domain(&ng_btsocket_domain);
288107120Sjulian		break;
289107120Sjulian
290107120Sjulian	case MOD_UNLOAD:
291107120Sjulian		/* XXX can't unload protocol domain yet */
292107120Sjulian		error = EBUSY;
293107120Sjulian		break;
294107120Sjulian
295107120Sjulian	default:
296107120Sjulian		error = EOPNOTSUPP;
297107120Sjulian		break;
298107120Sjulian	}
299107120Sjulian
300107120Sjulian	return (error);
301107120Sjulian} /* ng_btsocket_modevent */
302107120Sjulian
303