ng_btsocket.c revision 139823
1107120Sjulian/*
2107120Sjulian * ng_btsocket.c
3139823Simp */
4139823Simp
5139823Simp/*-
6107120Sjulian * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
7107120Sjulian * All rights reserved.
8107120Sjulian *
9107120Sjulian * Redistribution and use in source and binary forms, with or without
10107120Sjulian * modification, are permitted provided that the following conditions
11107120Sjulian * are met:
12107120Sjulian * 1. Redistributions of source code must retain the above copyright
13107120Sjulian *    notice, this list of conditions and the following disclaimer.
14107120Sjulian * 2. Redistributions in binary form must reproduce the above copyright
15107120Sjulian *    notice, this list of conditions and the following disclaimer in the
16107120Sjulian *    documentation and/or other materials provided with the distribution.
17107120Sjulian *
18107120Sjulian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19107120Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20107120Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21107120Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22107120Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23107120Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24107120Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25107120Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26107120Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27107120Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28107120Sjulian * SUCH DAMAGE.
29107120Sjulian *
30121054Semax * $Id: ng_btsocket.c,v 1.4 2003/09/14 23:29:06 max Exp $
31107120Sjulian * $FreeBSD: head/sys/netgraph/bluetooth/socket/ng_btsocket.c 139823 2005-01-07 01:45:51Z imp $
32107120Sjulian */
33107120Sjulian
34107120Sjulian#include <sys/param.h>
35107120Sjulian#include <sys/systm.h>
36121054Semax#include <sys/bitstring.h>
37107120Sjulian#include <sys/errno.h>
38107120Sjulian#include <sys/domain.h>
39107120Sjulian#include <sys/kernel.h>
40107120Sjulian#include <sys/lock.h>
41131118Semax#include <sys/mbuf.h>
42107120Sjulian#include <sys/mutex.h>
43107120Sjulian#include <sys/protosw.h>
44107120Sjulian#include <sys/socket.h>
45107120Sjulian#include <sys/socketvar.h>
46107120Sjulian#include <sys/sysctl.h>
47114878Sjulian#include <sys/taskqueue.h>
48107120Sjulian#include <netgraph/ng_message.h>
49107120Sjulian#include <netgraph/netgraph.h>
50128688Semax#include <netgraph/bluetooth/include/ng_bluetooth.h>
51128688Semax#include <netgraph/bluetooth/include/ng_hci.h>
52128688Semax#include <netgraph/bluetooth/include/ng_l2cap.h>
53128688Semax#include <netgraph/bluetooth/include/ng_btsocket.h>
54128688Semax#include <netgraph/bluetooth/include/ng_btsocket_hci_raw.h>
55128688Semax#include <netgraph/bluetooth/include/ng_btsocket_l2cap.h>
56128688Semax#include <netgraph/bluetooth/include/ng_btsocket_rfcomm.h>
57107120Sjulian
58107120Sjulianstatic int			ng_btsocket_modevent (module_t, int, void *);
59107120Sjulianextern struct domain		ng_btsocket_domain;
60107120Sjulian
61107120Sjulian/*
62107120Sjulian * Bluetooth raw HCI sockets
63107120Sjulian */
64107120Sjulian
65107120Sjulianstatic struct pr_usrreqs	ng_btsocket_hci_raw_usrreqs = {
66137386Sphk	.pru_abort =		ng_btsocket_hci_raw_abort,
67137386Sphk	.pru_attach =		ng_btsocket_hci_raw_attach,
68137386Sphk	.pru_bind =		ng_btsocket_hci_raw_bind,
69137386Sphk	.pru_connect =		ng_btsocket_hci_raw_connect,
70137386Sphk	.pru_control =		ng_btsocket_hci_raw_control,
71137386Sphk	.pru_detach =		ng_btsocket_hci_raw_detach,
72137386Sphk	.pru_disconnect =	ng_btsocket_hci_raw_disconnect,
73137386Sphk	.pru_peeraddr =		ng_btsocket_hci_raw_peeraddr,
74137386Sphk	.pru_send =		ng_btsocket_hci_raw_send,
75137386Sphk	.pru_shutdown =		NULL,
76137386Sphk	.pru_sockaddr =		ng_btsocket_hci_raw_sockaddr,
77107120Sjulian};
78107120Sjulian
79107120Sjulian/*
80107120Sjulian * Bluetooth raw L2CAP sockets
81107120Sjulian */
82107120Sjulian
83107120Sjulianstatic struct pr_usrreqs	ng_btsocket_l2cap_raw_usrreqs = {
84137386Sphk	.pru_abort =		ng_btsocket_l2cap_raw_abort,
85137386Sphk	.pru_attach =		ng_btsocket_l2cap_raw_attach,
86137386Sphk	.pru_bind =		ng_btsocket_l2cap_raw_bind,
87137386Sphk	.pru_connect =		ng_btsocket_l2cap_raw_connect,
88137386Sphk	.pru_control =		ng_btsocket_l2cap_raw_control,
89137386Sphk	.pru_detach =		ng_btsocket_l2cap_raw_detach,
90137386Sphk	.pru_disconnect =	ng_btsocket_l2cap_raw_disconnect,
91137386Sphk	.pru_peeraddr =		ng_btsocket_l2cap_raw_peeraddr,
92137386Sphk	.pru_send =		ng_btsocket_l2cap_raw_send,
93137386Sphk	.pru_shutdown =		NULL,
94137386Sphk	.pru_sockaddr =		ng_btsocket_l2cap_raw_sockaddr,
95107120Sjulian};
96107120Sjulian
97107120Sjulian/*
98107120Sjulian * Bluetooth SEQPACKET L2CAP sockets
99107120Sjulian */
100107120Sjulian
101107120Sjulianstatic struct pr_usrreqs	ng_btsocket_l2cap_usrreqs = {
102137386Sphk	.pru_abort =		ng_btsocket_l2cap_abort,
103137386Sphk	.pru_accept =		ng_btsocket_l2cap_accept,
104137386Sphk	.pru_attach =		ng_btsocket_l2cap_attach,
105137386Sphk	.pru_bind =		ng_btsocket_l2cap_bind,
106137386Sphk	.pru_connect =		ng_btsocket_l2cap_connect,
107137386Sphk	.pru_control =		ng_btsocket_l2cap_control,
108137386Sphk	.pru_detach =		ng_btsocket_l2cap_detach,
109137386Sphk	.pru_disconnect =	ng_btsocket_l2cap_disconnect,
110137386Sphk        .pru_listen =		ng_btsocket_l2cap_listen,
111137386Sphk	.pru_peeraddr =		ng_btsocket_l2cap_peeraddr,
112137386Sphk	.pru_send =		ng_btsocket_l2cap_send,
113137386Sphk	.pru_shutdown =		NULL,
114137386Sphk	.pru_sockaddr =		ng_btsocket_l2cap_sockaddr,
115107120Sjulian};
116107120Sjulian
117114878Sjulian/*
118114878Sjulian * Bluetooth STREAM RFCOMM sockets
119114878Sjulian */
120114878Sjulian
121114878Sjulianstatic struct pr_usrreqs	ng_btsocket_rfcomm_usrreqs = {
122137386Sphk	.pru_abort =		ng_btsocket_rfcomm_abort,
123137386Sphk	.pru_accept =		ng_btsocket_rfcomm_accept,
124137386Sphk	.pru_attach =		ng_btsocket_rfcomm_attach,
125137386Sphk	.pru_bind =		ng_btsocket_rfcomm_bind,
126137386Sphk	.pru_connect =		ng_btsocket_rfcomm_connect,
127137386Sphk	.pru_control =		ng_btsocket_rfcomm_control,
128137386Sphk	.pru_detach =		ng_btsocket_rfcomm_detach,
129137386Sphk	.pru_disconnect =	ng_btsocket_rfcomm_disconnect,
130137386Sphk        .pru_listen =		ng_btsocket_rfcomm_listen,
131137386Sphk	.pru_peeraddr =		ng_btsocket_rfcomm_peeraddr,
132137386Sphk	.pru_send =		ng_btsocket_rfcomm_send,
133137386Sphk	.pru_shutdown =		NULL,
134137386Sphk	.pru_sockaddr =		ng_btsocket_rfcomm_sockaddr,
135114878Sjulian};
136114878Sjulian
137107120Sjulian/*
138107120Sjulian * Definitions of protocols supported in the BLUETOOTH domain
139107120Sjulian */
140107120Sjulian
141107120Sjulianstatic struct protosw		ng_btsocket_protosw[] = {
142107120Sjulian{
143107120Sjulian	SOCK_RAW,			/* protocol type */
144107120Sjulian	&ng_btsocket_domain,		/* backpointer to domain */
145107120Sjulian	BLUETOOTH_PROTO_HCI,		/* protocol */
146107120Sjulian	PR_ATOMIC | PR_ADDR,		/* flags */
147107120Sjulian	NULL, NULL, NULL,		/* input, output, ctlinput */
148107120Sjulian	ng_btsocket_hci_raw_ctloutput,	/* ctloutput */
149107120Sjulian	NULL,				/* ousrreq() */
150107120Sjulian	ng_btsocket_hci_raw_init,	/* init */
151107120Sjulian	NULL, NULL, NULL,		/* fasttimeo, slowtimo, drain */
152107120Sjulian	&ng_btsocket_hci_raw_usrreqs,	/* usrreq table (above) */
153107120Sjulian	/* { NULL } */			/* pfh (protocol filter head?) */
154107120Sjulian},
155107120Sjulian{
156107120Sjulian	SOCK_RAW,			/* protocol type */
157107120Sjulian	&ng_btsocket_domain,		/* backpointer to domain */
158107120Sjulian	BLUETOOTH_PROTO_L2CAP,		/* protocol */
159107120Sjulian	PR_ATOMIC | PR_ADDR,		/* flags */
160107120Sjulian	NULL, NULL, NULL,		/* input, output, ctlinput */
161107120Sjulian	NULL,				/* ctloutput */
162107120Sjulian	NULL,				/* ousrreq() */
163107120Sjulian	ng_btsocket_l2cap_raw_init,	/* init */
164107120Sjulian	NULL, NULL, NULL,		/* fasttimeo, slowtimo, drain */
165107120Sjulian	&ng_btsocket_l2cap_raw_usrreqs,	/* usrreq table (above) */
166107120Sjulian	/* { NULL } */			/* pfh (protocol filter head?) */
167107120Sjulian},
168107120Sjulian{
169107120Sjulian	SOCK_SEQPACKET,			/* protocol type */
170107120Sjulian	&ng_btsocket_domain,		/* backpointer to domain */
171107120Sjulian	BLUETOOTH_PROTO_L2CAP,		/* protocol */
172107120Sjulian	PR_ATOMIC | PR_CONNREQUIRED,	/* flags */
173107120Sjulian	NULL, NULL, NULL,		/* input, output, ctlinput */
174107120Sjulian	ng_btsocket_l2cap_ctloutput,	/* ctloutput */
175107120Sjulian	NULL,				/* ousrreq() */
176107120Sjulian	ng_btsocket_l2cap_init,		/* init */
177107120Sjulian	NULL, NULL, NULL,		/* fasttimeo, slowtimo, drain */
178107120Sjulian	&ng_btsocket_l2cap_usrreqs,	/* usrreq table (above) */
179107120Sjulian	/* { NULL } */			/* pfh (protocol filter head?) */
180114878Sjulian},
181114878Sjulian{
182114878Sjulian	SOCK_STREAM,			/* protocol type */
183114878Sjulian	&ng_btsocket_domain,		/* backpointer to domain */
184114878Sjulian	BLUETOOTH_PROTO_RFCOMM,		/* protocol */
185114878Sjulian	PR_ATOMIC | PR_CONNREQUIRED,	/* flags */
186114878Sjulian	NULL, NULL, NULL,		/* input, output, ctlinput */
187114878Sjulian	ng_btsocket_rfcomm_ctloutput,	/* ctloutput */
188114878Sjulian	NULL,				/* ousrreq() */
189114878Sjulian	ng_btsocket_rfcomm_init,	/* init */
190114878Sjulian	NULL, NULL, NULL,		/* fasttimeo, slowtimo, drain */
191114878Sjulian	&ng_btsocket_rfcomm_usrreqs,	/* usrreq table (above) */
192114878Sjulian	/* { NULL } */			/* pfh (protocol filter head?) */
193107120Sjulian}
194107120Sjulian};
195107120Sjulian#define ng_btsocket_protosw_size \
196107120Sjulian	(sizeof(ng_btsocket_protosw)/sizeof(ng_btsocket_protosw[0]))
197107120Sjulian#define ng_btsocket_protosw_end \
198107120Sjulian	&ng_btsocket_protosw[ng_btsocket_protosw_size]
199107120Sjulian
200107120Sjulian/*
201107120Sjulian * BLUETOOTH domain
202107120Sjulian */
203107120Sjulian
204107120Sjulianstruct domain			ng_btsocket_domain = {
205107120Sjulian	AF_BLUETOOTH,			/* family */
206107120Sjulian	"bluetooth",			/* domain name */
207107120Sjulian	NULL,				/* init() */
208107120Sjulian	NULL,				/* externalize() */
209107120Sjulian	NULL,				/* dispose() */
210107120Sjulian	ng_btsocket_protosw,		/* protosw entry */
211107120Sjulian	ng_btsocket_protosw_end,	/* end of protosw entries */
212107120Sjulian	NULL,				/* next domain in list */
213107120Sjulian	NULL,				/* rtattach() */
214107120Sjulian	0,				/* arg to rtattach in bits */
215107120Sjulian	0				/* maxrtkey */
216107120Sjulian};
217107120Sjulian
218107120Sjulian/*
219107120Sjulian * Socket sysctl tree
220107120Sjulian */
221107120Sjulian
222107120SjulianSYSCTL_NODE(_net_bluetooth_hci, OID_AUTO, sockets, CTLFLAG_RW,
223107120Sjulian	0, "Bluetooth HCI sockets family");
224107120SjulianSYSCTL_NODE(_net_bluetooth_l2cap, OID_AUTO, sockets, CTLFLAG_RW,
225107120Sjulian	0, "Bluetooth L2CAP sockets family");
226114878SjulianSYSCTL_NODE(_net_bluetooth_rfcomm, OID_AUTO, sockets, CTLFLAG_RW,
227114878Sjulian	0, "Bluetooth RFCOMM sockets family");
228107120Sjulian
229107120Sjulian/*
230107120Sjulian * Module
231107120Sjulian */
232107120Sjulian
233107120Sjulianstatic moduledata_t	ng_btsocket_mod = {
234107120Sjulian	"ng_btsocket",
235107120Sjulian	ng_btsocket_modevent,
236107120Sjulian	NULL
237107120Sjulian};
238107120Sjulian
239138238SmlaierDECLARE_MODULE(ng_btsocket, ng_btsocket_mod, SI_SUB_PROTO_DOMAIN,
240138238Smlaier	SI_ORDER_ANY);
241107120SjulianMODULE_VERSION(ng_btsocket, NG_BLUETOOTH_VERSION);
242107120SjulianMODULE_DEPEND(ng_btsocket, ng_bluetooth, NG_BLUETOOTH_VERSION,
243107120Sjulian	NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION);
244107120SjulianMODULE_DEPEND(ng_btsocket, netgraph, NG_ABI_VERSION,
245107120Sjulian	NG_ABI_VERSION, NG_ABI_VERSION);
246107120Sjulian
247107120Sjulian/*
248107120Sjulian * Handle loading and unloading for this node type.
249107120Sjulian * This is to handle auxiliary linkages (e.g protocol domain addition).
250107120Sjulian */
251107120Sjulian
252107120Sjulianstatic int
253107120Sjulianng_btsocket_modevent(module_t mod, int event, void *data)
254107120Sjulian{
255107120Sjulian	int	error = 0;
256107120Sjulian
257107120Sjulian	switch (event) {
258107120Sjulian	case MOD_LOAD:
259107120Sjulian		net_add_domain(&ng_btsocket_domain);
260107120Sjulian		break;
261107120Sjulian
262107120Sjulian	case MOD_UNLOAD:
263107120Sjulian		/* XXX can't unload protocol domain yet */
264107120Sjulian		error = EBUSY;
265107120Sjulian		break;
266107120Sjulian
267107120Sjulian	default:
268107120Sjulian		error = EOPNOTSUPP;
269107120Sjulian		break;
270107120Sjulian	}
271107120Sjulian
272107120Sjulian	return (error);
273107120Sjulian} /* ng_btsocket_modevent */
274107120Sjulian
275