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