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$
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>
48195837Srwatson
49253346Srodrigc#include <net/vnet.h>
50253346Srodrigc
51107120Sjulian#include <netgraph/ng_message.h>
52107120Sjulian#include <netgraph/netgraph.h>
53128688Semax#include <netgraph/bluetooth/include/ng_bluetooth.h>
54128688Semax#include <netgraph/bluetooth/include/ng_hci.h>
55128688Semax#include <netgraph/bluetooth/include/ng_l2cap.h>
56128688Semax#include <netgraph/bluetooth/include/ng_btsocket.h>
57128688Semax#include <netgraph/bluetooth/include/ng_btsocket_hci_raw.h>
58128688Semax#include <netgraph/bluetooth/include/ng_btsocket_l2cap.h>
59128688Semax#include <netgraph/bluetooth/include/ng_btsocket_rfcomm.h>
60181033Semax#include <netgraph/bluetooth/include/ng_btsocket_sco.h>
61107120Sjulian
62107120Sjulianstatic int			ng_btsocket_modevent (module_t, int, void *);
63195837Srwatsonstatic struct domain		ng_btsocket_domain;
64107120Sjulian
65107120Sjulian/*
66107120Sjulian * Bluetooth raw HCI sockets
67107120Sjulian */
68107120Sjulian
69107120Sjulianstatic struct pr_usrreqs	ng_btsocket_hci_raw_usrreqs = {
70137386Sphk	.pru_abort =		ng_btsocket_hci_raw_abort,
71137386Sphk	.pru_attach =		ng_btsocket_hci_raw_attach,
72137386Sphk	.pru_bind =		ng_btsocket_hci_raw_bind,
73137386Sphk	.pru_connect =		ng_btsocket_hci_raw_connect,
74137386Sphk	.pru_control =		ng_btsocket_hci_raw_control,
75137386Sphk	.pru_detach =		ng_btsocket_hci_raw_detach,
76137386Sphk	.pru_disconnect =	ng_btsocket_hci_raw_disconnect,
77137386Sphk	.pru_peeraddr =		ng_btsocket_hci_raw_peeraddr,
78137386Sphk	.pru_send =		ng_btsocket_hci_raw_send,
79137386Sphk	.pru_shutdown =		NULL,
80137386Sphk	.pru_sockaddr =		ng_btsocket_hci_raw_sockaddr,
81160549Srwatson	.pru_close =		ng_btsocket_hci_raw_close,
82107120Sjulian};
83107120Sjulian
84107120Sjulian/*
85107120Sjulian * Bluetooth raw L2CAP sockets
86107120Sjulian */
87107120Sjulian
88107120Sjulianstatic struct pr_usrreqs	ng_btsocket_l2cap_raw_usrreqs = {
89137386Sphk	.pru_abort =		ng_btsocket_l2cap_raw_abort,
90137386Sphk	.pru_attach =		ng_btsocket_l2cap_raw_attach,
91137386Sphk	.pru_bind =		ng_btsocket_l2cap_raw_bind,
92137386Sphk	.pru_connect =		ng_btsocket_l2cap_raw_connect,
93137386Sphk	.pru_control =		ng_btsocket_l2cap_raw_control,
94137386Sphk	.pru_detach =		ng_btsocket_l2cap_raw_detach,
95137386Sphk	.pru_disconnect =	ng_btsocket_l2cap_raw_disconnect,
96137386Sphk	.pru_peeraddr =		ng_btsocket_l2cap_raw_peeraddr,
97137386Sphk	.pru_send =		ng_btsocket_l2cap_raw_send,
98137386Sphk	.pru_shutdown =		NULL,
99137386Sphk	.pru_sockaddr =		ng_btsocket_l2cap_raw_sockaddr,
100160549Srwatson	.pru_close =		ng_btsocket_l2cap_raw_close,
101107120Sjulian};
102107120Sjulian
103107120Sjulian/*
104107120Sjulian * Bluetooth SEQPACKET L2CAP sockets
105107120Sjulian */
106107120Sjulian
107107120Sjulianstatic struct pr_usrreqs	ng_btsocket_l2cap_usrreqs = {
108137386Sphk	.pru_abort =		ng_btsocket_l2cap_abort,
109137386Sphk	.pru_accept =		ng_btsocket_l2cap_accept,
110137386Sphk	.pru_attach =		ng_btsocket_l2cap_attach,
111137386Sphk	.pru_bind =		ng_btsocket_l2cap_bind,
112137386Sphk	.pru_connect =		ng_btsocket_l2cap_connect,
113137386Sphk	.pru_control =		ng_btsocket_l2cap_control,
114137386Sphk	.pru_detach =		ng_btsocket_l2cap_detach,
115137386Sphk	.pru_disconnect =	ng_btsocket_l2cap_disconnect,
116137386Sphk        .pru_listen =		ng_btsocket_l2cap_listen,
117137386Sphk	.pru_peeraddr =		ng_btsocket_l2cap_peeraddr,
118137386Sphk	.pru_send =		ng_btsocket_l2cap_send,
119137386Sphk	.pru_shutdown =		NULL,
120137386Sphk	.pru_sockaddr =		ng_btsocket_l2cap_sockaddr,
121160549Srwatson	.pru_close =		ng_btsocket_l2cap_close,
122107120Sjulian};
123107120Sjulian
124114878Sjulian/*
125114878Sjulian * Bluetooth STREAM RFCOMM sockets
126114878Sjulian */
127114878Sjulian
128114878Sjulianstatic struct pr_usrreqs	ng_btsocket_rfcomm_usrreqs = {
129137386Sphk	.pru_abort =		ng_btsocket_rfcomm_abort,
130137386Sphk	.pru_accept =		ng_btsocket_rfcomm_accept,
131137386Sphk	.pru_attach =		ng_btsocket_rfcomm_attach,
132137386Sphk	.pru_bind =		ng_btsocket_rfcomm_bind,
133137386Sphk	.pru_connect =		ng_btsocket_rfcomm_connect,
134137386Sphk	.pru_control =		ng_btsocket_rfcomm_control,
135137386Sphk	.pru_detach =		ng_btsocket_rfcomm_detach,
136137386Sphk	.pru_disconnect =	ng_btsocket_rfcomm_disconnect,
137137386Sphk        .pru_listen =		ng_btsocket_rfcomm_listen,
138137386Sphk	.pru_peeraddr =		ng_btsocket_rfcomm_peeraddr,
139137386Sphk	.pru_send =		ng_btsocket_rfcomm_send,
140137386Sphk	.pru_shutdown =		NULL,
141137386Sphk	.pru_sockaddr =		ng_btsocket_rfcomm_sockaddr,
142160549Srwatson	.pru_close =		ng_btsocket_rfcomm_close,
143114878Sjulian};
144114878Sjulian
145181033Semax/*
146181033Semax * Bluetooth SEQPACKET SCO sockets
147181033Semax */
148181033Semax
149181033Semaxstatic struct pr_usrreqs	ng_btsocket_sco_usrreqs = {
150181033Semax	.pru_abort =		ng_btsocket_sco_abort,
151181033Semax	.pru_accept =		ng_btsocket_sco_accept,
152181033Semax	.pru_attach =		ng_btsocket_sco_attach,
153181033Semax	.pru_bind =		ng_btsocket_sco_bind,
154181033Semax	.pru_connect =		ng_btsocket_sco_connect,
155181033Semax	.pru_control =		ng_btsocket_sco_control,
156181033Semax	.pru_detach =		ng_btsocket_sco_detach,
157181033Semax	.pru_disconnect =	ng_btsocket_sco_disconnect,
158181033Semax	.pru_listen =		ng_btsocket_sco_listen,
159181033Semax	.pru_peeraddr =		ng_btsocket_sco_peeraddr,
160181033Semax	.pru_send =		ng_btsocket_sco_send,
161181033Semax	.pru_shutdown =		NULL,
162181033Semax	.pru_sockaddr =		ng_btsocket_sco_sockaddr,
163181033Semax	.pru_close =		ng_btsocket_sco_close,
164181033Semax};
165181033Semax
166107120Sjulian/*
167107120Sjulian * Definitions of protocols supported in the BLUETOOTH domain
168107120Sjulian */
169107120Sjulian
170107120Sjulianstatic struct protosw		ng_btsocket_protosw[] = {
171107120Sjulian{
172152242Sru	.pr_type =		SOCK_RAW,
173152242Sru	.pr_domain =		&ng_btsocket_domain,
174152242Sru	.pr_protocol =		BLUETOOTH_PROTO_HCI,
175152242Sru	.pr_flags =		PR_ATOMIC|PR_ADDR,
176152242Sru	.pr_ctloutput =		ng_btsocket_hci_raw_ctloutput,
177152242Sru	.pr_init =		ng_btsocket_hci_raw_init,
178152242Sru	.pr_usrreqs =		&ng_btsocket_hci_raw_usrreqs,
179107120Sjulian},
180107120Sjulian{
181152242Sru	.pr_type =		SOCK_RAW,
182152242Sru	.pr_domain =		&ng_btsocket_domain,
183152242Sru	.pr_protocol =		BLUETOOTH_PROTO_L2CAP,
184152242Sru	.pr_flags =		PR_ATOMIC|PR_ADDR,
185152242Sru	.pr_init =		ng_btsocket_l2cap_raw_init,
186152242Sru	.pr_usrreqs =		&ng_btsocket_l2cap_raw_usrreqs,
187107120Sjulian},
188107120Sjulian{
189152242Sru	.pr_type =		SOCK_SEQPACKET,
190152242Sru	.pr_domain =		&ng_btsocket_domain,
191152242Sru	.pr_protocol =		BLUETOOTH_PROTO_L2CAP,
192152242Sru	.pr_flags =		PR_ATOMIC|PR_CONNREQUIRED,
193152242Sru	.pr_ctloutput =		ng_btsocket_l2cap_ctloutput,
194152242Sru	.pr_init =		ng_btsocket_l2cap_init,
195152242Sru	.pr_usrreqs =		&ng_btsocket_l2cap_usrreqs,
196114878Sjulian},
197114878Sjulian{
198152242Sru	.pr_type =		SOCK_STREAM,
199152242Sru	.pr_domain =		&ng_btsocket_domain,
200152242Sru	.pr_protocol =		BLUETOOTH_PROTO_RFCOMM,
201152242Sru	.pr_flags =		PR_CONNREQUIRED,
202152242Sru	.pr_ctloutput =		ng_btsocket_rfcomm_ctloutput,
203152242Sru	.pr_init =		ng_btsocket_rfcomm_init,
204152242Sru	.pr_usrreqs =		&ng_btsocket_rfcomm_usrreqs,
205181033Semax},
206181033Semax{
207181033Semax	.pr_type =		SOCK_SEQPACKET,
208181033Semax	.pr_domain =		&ng_btsocket_domain,
209181033Semax	.pr_protocol =		BLUETOOTH_PROTO_SCO,
210181033Semax	.pr_flags =		PR_ATOMIC|PR_CONNREQUIRED,
211181033Semax	.pr_ctloutput =		ng_btsocket_sco_ctloutput,
212181033Semax	.pr_init =		ng_btsocket_sco_init,
213181033Semax	.pr_usrreqs =		&ng_btsocket_sco_usrreqs,
214181033Semax},
215107120Sjulian};
216107120Sjulian#define ng_btsocket_protosw_size \
217107120Sjulian	(sizeof(ng_btsocket_protosw)/sizeof(ng_btsocket_protosw[0]))
218107120Sjulian#define ng_btsocket_protosw_end \
219107120Sjulian	&ng_btsocket_protosw[ng_btsocket_protosw_size]
220107120Sjulian
221107120Sjulian/*
222107120Sjulian * BLUETOOTH domain
223107120Sjulian */
224107120Sjulian
225195837Srwatsonstatic struct domain ng_btsocket_domain = {
226152242Sru	.dom_family =		AF_BLUETOOTH,
227152242Sru	.dom_name =		"bluetooth",
228152242Sru	.dom_protosw =		ng_btsocket_protosw,
229152242Sru	.dom_protoswNPROTOSW =	ng_btsocket_protosw_end
230107120Sjulian};
231107120Sjulian
232107120Sjulian/*
233107120Sjulian * Socket sysctl tree
234107120Sjulian */
235107120Sjulian
236107120SjulianSYSCTL_NODE(_net_bluetooth_hci, OID_AUTO, sockets, CTLFLAG_RW,
237107120Sjulian	0, "Bluetooth HCI sockets family");
238107120SjulianSYSCTL_NODE(_net_bluetooth_l2cap, OID_AUTO, sockets, CTLFLAG_RW,
239107120Sjulian	0, "Bluetooth L2CAP sockets family");
240114878SjulianSYSCTL_NODE(_net_bluetooth_rfcomm, OID_AUTO, sockets, CTLFLAG_RW,
241114878Sjulian	0, "Bluetooth RFCOMM sockets family");
242181033SemaxSYSCTL_NODE(_net_bluetooth_sco, OID_AUTO, sockets, CTLFLAG_RW,
243181033Semax	0, "Bluetooth SCO sockets family");
244107120Sjulian
245107120Sjulian/*
246107120Sjulian * Module
247107120Sjulian */
248107120Sjulian
249107120Sjulianstatic moduledata_t	ng_btsocket_mod = {
250107120Sjulian	"ng_btsocket",
251107120Sjulian	ng_btsocket_modevent,
252107120Sjulian	NULL
253107120Sjulian};
254107120Sjulian
255138238SmlaierDECLARE_MODULE(ng_btsocket, ng_btsocket_mod, SI_SUB_PROTO_DOMAIN,
256138238Smlaier	SI_ORDER_ANY);
257107120SjulianMODULE_VERSION(ng_btsocket, NG_BLUETOOTH_VERSION);
258107120SjulianMODULE_DEPEND(ng_btsocket, ng_bluetooth, NG_BLUETOOTH_VERSION,
259107120Sjulian	NG_BLUETOOTH_VERSION, NG_BLUETOOTH_VERSION);
260107120SjulianMODULE_DEPEND(ng_btsocket, netgraph, NG_ABI_VERSION,
261107120Sjulian	NG_ABI_VERSION, NG_ABI_VERSION);
262107120Sjulian
263107120Sjulian/*
264107120Sjulian * Handle loading and unloading for this node type.
265107120Sjulian * This is to handle auxiliary linkages (e.g protocol domain addition).
266107120Sjulian */
267107120Sjulian
268107120Sjulianstatic int
269107120Sjulianng_btsocket_modevent(module_t mod, int event, void *data)
270107120Sjulian{
271107120Sjulian	int	error = 0;
272107120Sjulian
273107120Sjulian	switch (event) {
274107120Sjulian	case MOD_LOAD:
275107120Sjulian		break;
276107120Sjulian
277107120Sjulian	case MOD_UNLOAD:
278107120Sjulian		/* XXX can't unload protocol domain yet */
279107120Sjulian		error = EBUSY;
280107120Sjulian		break;
281107120Sjulian
282107120Sjulian	default:
283107120Sjulian		error = EOPNOTSUPP;
284107120Sjulian		break;
285107120Sjulian	}
286107120Sjulian
287107120Sjulian	return (error);
288107120Sjulian} /* ng_btsocket_modevent */
289107120Sjulian
290253346SrodrigcVNET_DOMAIN_SET(ng_btsocket_);
291