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