xref: /dragonfly/sys/netbt/bt_proto.c (revision 768af85b)
1 /* $DragonFly: src/sys/netbt/bt_proto.c,v 1.7 2008/11/01 04:22:15 sephe Exp $ */
2 /* $OpenBSD: bt_proto.c,v 1.4 2007/06/24 20:55:27 uwe Exp $ */
3 
4 /*
5  * Copyright (c) 2004 Alexander Yurchenko <grange@openbsd.org>
6  *
7  * Permission to use, copy, modify, and distribute this software for any
8  * purpose with or without fee is hereby granted, provided that the above
9  * copyright notice and this permission notice appear in all copies.
10  *
11  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18  */
19 
20 #include <sys/param.h>
21 #include <sys/domain.h>
22 #include <sys/protosw.h>
23 #include <sys/socket.h>
24 #include <sys/socketvar.h>
25 #include <sys/queue.h>
26 #include <sys/kernel.h>
27 #include <sys/mbuf.h>
28 #include <sys/sysctl.h>
29 #include <sys/bus.h>
30 #include <sys/malloc.h>
31 #include <net/if.h>
32 #include <net/pf/pfvar.h>
33 
34 #include <netbt/bluetooth.h>
35 #include <netbt/hci.h>
36 #include <netbt/l2cap.h>
37 #include <netbt/rfcomm.h>
38 #include <netbt/sco.h>
39 
40 MALLOC_DEFINE(M_BLUETOOTH, "Bluetooth", "Bluetooth system memory");
41 
42 extern struct pr_usrreqs hci_usrreqs;
43 
44 static int
45 netbt_modevent(module_t mod, int type, void *data)
46 {
47 	switch (type) {
48 	case MOD_LOAD:
49 		break;
50 	case MOD_UNLOAD:
51 		return EBUSY;
52 		break;
53 	default:
54 		break;
55 	}
56 	return 0;
57 }
58 
59 static moduledata_t netbt_mod = {
60 	"netbt",
61 	netbt_modevent,
62 	NULL
63 };
64 
65 DECLARE_MODULE(netbt, netbt_mod, SI_SUB_EXEC, SI_ORDER_ANY);
66 MODULE_VERSION(netbt, 1);
67 
68 struct domain btdomain;
69 
70 struct protosw btsw[] = {
71 	{ /* raw HCI commands */
72 		.pr_type = SOCK_RAW,
73 		.pr_domain = &btdomain,
74 		.pr_protocol = BTPROTO_HCI,
75 		.pr_flags = (PR_ADDR | PR_ATOMIC),
76 		.pr_input = 0,
77 		.pr_output = 0,
78 		.pr_ctlinput = 0,
79 		.pr_ctloutput = hci_ctloutput,
80 		.pr_mport = cpu0_soport,
81 		.pr_ctlport = NULL,
82 		.pr_init = 0,
83 		.pr_fasttimo =	0,
84 		.pr_slowtimo = 0,
85 		.pr_drain = 0,
86 		.pr_usrreqs = &hci_usrreqs
87 	},
88 	{ /* HCI SCO data (audio) */
89 		.pr_type = SOCK_SEQPACKET,
90 		.pr_domain = &btdomain,
91 		.pr_protocol = BTPROTO_SCO,
92 		.pr_flags = (PR_CONNREQUIRED | PR_ATOMIC ),
93 		.pr_input = 0,
94 		.pr_output = 0,
95 		.pr_ctlinput = 0,
96 		.pr_ctloutput = sco_ctloutput,
97 		.pr_mport = cpu0_soport,
98 		.pr_ctlport = NULL,
99 		.pr_init = 0,
100 		.pr_fasttimo =	0,
101 		.pr_slowtimo = 0,
102 		.pr_drain = 0,
103 		.pr_usrreqs = &sco_usrreqs
104 
105 	},
106 	{ /* L2CAP Connection Oriented */
107 		.pr_type = SOCK_SEQPACKET,
108 		.pr_domain = &btdomain,
109 		.pr_protocol = BTPROTO_L2CAP,
110 		.pr_flags = (PR_CONNREQUIRED | PR_ATOMIC ),
111 		.pr_input = 0,
112 		.pr_output = 0,
113 		.pr_ctlinput = 0,
114 		.pr_ctloutput = l2cap_ctloutput,
115 		.pr_mport = cpu0_soport,
116 		.pr_ctlport = NULL,
117 		.pr_init = 0,
118 		.pr_fasttimo =	0,
119 		.pr_slowtimo = 0,
120 		.pr_drain = 0,
121 		.pr_usrreqs = &l2cap_usrreqs
122 	},
123 	{ /* RFCOMM */
124 		.pr_type = SOCK_STREAM,
125 		.pr_domain = &btdomain,
126 		.pr_protocol = BTPROTO_RFCOMM,
127 		.pr_flags = (PR_CONNREQUIRED | PR_WANTRCVD),
128 		.pr_input = 0,
129 		.pr_output = 0,
130 		.pr_ctlinput = 0,
131 		.pr_ctloutput = rfcomm_ctloutput,
132 		.pr_mport = cpu0_soport,
133 		.pr_ctlport = NULL,
134 		.pr_init = 0,
135 		.pr_fasttimo =	0,
136 		.pr_slowtimo = 0,
137 		.pr_drain = 0,
138 		.pr_usrreqs = &rfcomm_usrreqs
139 	},
140 };
141 
142 static void
143 netbt_dispose(struct mbuf* m)
144 {
145 	ZONE_DESTROY(l2cap_pdu_pool);
146 	ZONE_DESTROY(l2cap_req_pool);
147 	ZONE_DESTROY(rfcomm_credit_pool);
148 }
149 
150 static void
151 netbt_init(void)
152 {
153 	int error = 1;
154 	do {
155 		ZONE_CREATE(l2cap_pdu_pool, struct l2cap_pdu, "l2cap_pdu");
156 		ZONE_CREATE(l2cap_req_pool, struct l2cap_req, "l2cap_req");
157 		ZONE_CREATE(rfcomm_credit_pool, struct rfcomm_credit,
158 		    "rfcomm_credit");
159 		error = 0;
160 	} while(0);
161 
162 	if (error) {
163 		netbt_dispose(NULL);
164 		panic("Can't create vm_zones");
165 	}
166 }
167 
168 struct domain btdomain = {
169 	.dom_family = AF_BLUETOOTH,
170 	.dom_name = "bluetooth",
171 	.dom_init = netbt_init,
172 	.dom_externalize = NULL,
173 	.dom_dispose = netbt_dispose,
174 	.dom_protosw = btsw,
175 	.dom_protoswNPROTOSW = &btsw[sizeof(btsw)/sizeof(btsw[0])],
176 	.dom_next = SLIST_ENTRY_INITIALIZER,
177 	.dom_rtattach = 0,
178 	.dom_rtoffset = 32,
179 	.dom_maxrtkey = sizeof(struct sockaddr_bt),
180 	.dom_ifattach = 0,
181 	.dom_ifdetach = 0,
182 };
183 
184 DOMAIN_SET(bt);
185 SYSCTL_NODE(_net, OID_AUTO, bluetooth, CTLFLAG_RD, 0,
186     "Bluetooth Protocol Family");
187 
188 /* HCI sysctls */
189 SYSCTL_NODE(_net_bluetooth, OID_AUTO, hci, CTLFLAG_RD, 0,
190     "Host Controller Interface");
191 SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, sendspace, CTLFLAG_RW, &hci_sendspace,
192     0, "Socket Send Buffer Size");
193 SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, recvspace, CTLFLAG_RW, &hci_recvspace,
194     0, "Socket Receive Buffer Size");
195 SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, acl_expiry, CTLFLAG_RW,
196     &hci_acl_expiry, 0, "ACL Connection Expiry Time");
197 SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, memo_expiry, CTLFLAG_RW,
198     &hci_memo_expiry, 0, "Memo Expiry Time");
199 SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, eventq_max, CTLFLAG_RW,
200     &hci_eventq_max, 0, "Max Event queue length");
201 SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, aclrxq_max, CTLFLAG_RW,
202     &hci_aclrxq_max, 0, "Max ACL rx queue length");
203 SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, scorxq_max, CTLFLAG_RW,
204     &hci_scorxq_max, 0, "Max SCO rx queue length");
205 
206 /* L2CAP sysctls */
207 SYSCTL_NODE(_net_bluetooth, OID_AUTO, l2cap, CTLFLAG_RD, 0,
208     "Logical Link Control & Adaptation Protocol");
209 SYSCTL_INT(_net_bluetooth_l2cap, OID_AUTO, sendspace, CTLFLAG_RW,
210     &l2cap_sendspace, 0, "Socket Send Buffer Size");
211 SYSCTL_INT(_net_bluetooth_l2cap, OID_AUTO, recvspace, CTLFLAG_RW,
212     &l2cap_recvspace, 0, "Socket Receive Buffer Size");
213 SYSCTL_INT(_net_bluetooth_l2cap, OID_AUTO, rtx, CTLFLAG_RW,
214     &l2cap_response_timeout, 0, "Response Timeout");
215 SYSCTL_INT(_net_bluetooth_l2cap, OID_AUTO, ertx, CTLFLAG_RW,
216     &l2cap_response_extended_timeout, 0, "Extended Response Timeout");
217 
218 /* RFCOMM sysctls */
219 SYSCTL_NODE(_net_bluetooth, OID_AUTO, rfcomm, CTLFLAG_RD, 0,
220     "Serial Cable Emulation");
221 SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, sendspace, CTLFLAG_RW,
222     &rfcomm_sendspace, 0, "Socket Send Buffer Size");
223 SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, recvspace, CTLFLAG_RW,
224     &rfcomm_recvspace, 0, "Socket Receive Buffer Size");
225 SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, mtu_default, CTLFLAG_RW,
226     &rfcomm_mtu_default, 0, "Default MTU");
227 SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, ack_timeout, CTLFLAG_RW,
228     &rfcomm_ack_timeout, 0, "Acknowledgement Timer");
229 SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, mcc_timeout, CTLFLAG_RW,
230     &rfcomm_mcc_timeout, 0, "Response Timeout for Multiplexer Control Channel");
231 
232 /* SCO sysctls */
233 SYSCTL_NODE(_net_bluetooth, OID_AUTO, sco, CTLFLAG_RD, 0, "SCO data");
234 SYSCTL_INT(_net_bluetooth_sco, OID_AUTO, sendspace, CTLFLAG_RW, &sco_sendspace,
235     0, "Socket Send Buffer Size");
236 SYSCTL_INT(_net_bluetooth_sco, OID_AUTO, recvspace, CTLFLAG_RW, &sco_recvspace,
237     0, "Socket Receive Buffer Size");
238 
239 static void
240 netisr_netbt_setup(void *dummy __unused)
241 {
242 	netisr_register(NETISR_BLUETOOTH, cpu0_portfn, pktinfo_portfn_cpu0,
243 			btintr, NETISR_FLAG_NOTMPSAFE);
244 }
245 
246 SYSINIT(netbt_setup, SI_BOOT2_KLD, SI_ORDER_ANY, netisr_netbt_setup, NULL);
247