c6ae1d61476b24dd6cc103597ba91ab78c828d9a
[dragonfly.git] / sys / netbt / bt_proto.c
1 /* $DragonFly: src/sys/netbt/bt_proto.c,v 1.5 2008/09/23 11:28:49 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
67 struct domain btdomain;
68
69 struct protosw btsw[] = {
70         { /* raw HCI commands */
71                 .pr_type = SOCK_RAW,
72                 .pr_domain = &btdomain,
73                 .pr_protocol = BTPROTO_HCI,
74                 .pr_flags = (PR_ADDR | PR_ATOMIC),
75                 .pr_input = 0,
76                 .pr_output = 0,
77                 .pr_ctlinput = 0,
78                 .pr_ctloutput = hci_ctloutput,
79                 .pr_mport = cpu0_soport,
80                 .pr_init = 0,
81                 .pr_fasttimo =  0,
82                 .pr_slowtimo = 0,
83                 .pr_drain = 0,
84                 .pr_usrreqs = &hci_usrreqs
85         },
86         { /* HCI SCO data (audio) */
87                 .pr_type = SOCK_SEQPACKET,
88                 .pr_domain = &btdomain,
89                 .pr_protocol = BTPROTO_SCO,
90                 .pr_flags = (PR_CONNREQUIRED | PR_ATOMIC ),
91                 .pr_input = 0,
92                 .pr_output = 0,
93                 .pr_ctlinput = 0,
94                 .pr_ctloutput = sco_ctloutput,
95                 .pr_mport = cpu0_soport,
96                 .pr_init = 0,
97                 .pr_fasttimo =  0,
98                 .pr_slowtimo = 0,
99                 .pr_drain = 0,
100                 .pr_usrreqs = &sco_usrreqs
101
102         },
103         { /* L2CAP Connection Oriented */
104                 .pr_type = SOCK_SEQPACKET,
105                 .pr_domain = &btdomain,
106                 .pr_protocol = BTPROTO_L2CAP,
107                 .pr_flags = (PR_CONNREQUIRED | PR_ATOMIC ),
108                 .pr_input = 0,
109                 .pr_output = 0,
110                 .pr_ctlinput = 0,
111                 .pr_ctloutput = l2cap_ctloutput,
112                 .pr_mport = cpu0_soport,
113                 .pr_init = 0,
114                 .pr_fasttimo =  0,
115                 .pr_slowtimo = 0,
116                 .pr_drain = 0,
117                 .pr_usrreqs = &l2cap_usrreqs
118         },
119         { /* RFCOMM */
120                 .pr_type = SOCK_STREAM,
121                 .pr_domain = &btdomain,
122                 .pr_protocol = BTPROTO_RFCOMM,
123                 .pr_flags = (PR_CONNREQUIRED | PR_WANTRCVD),
124                 .pr_input = 0,
125                 .pr_output = 0,
126                 .pr_ctlinput = 0,
127                 .pr_ctloutput = rfcomm_ctloutput,
128                 .pr_mport = cpu0_soport,
129                 .pr_init = 0,
130                 .pr_fasttimo =  0,
131                 .pr_slowtimo = 0,
132                 .pr_drain = 0,
133                 .pr_usrreqs = &rfcomm_usrreqs
134         },
135 };
136
137 static void
138 netbt_dispose(struct mbuf* m)
139 {
140         ZONE_DESTROY(l2cap_pdu_pool);
141         ZONE_DESTROY(l2cap_req_pool);
142         ZONE_DESTROY(rfcomm_credit_pool);
143 }
144
145 static void
146 netbt_init(void)
147 {
148         int error = 1;
149         do {
150                 ZONE_CREATE(l2cap_pdu_pool, struct l2cap_pdu, "l2cap_pdu");
151                 ZONE_CREATE(l2cap_req_pool, struct l2cap_req, "l2cap_req");
152                 ZONE_CREATE(rfcomm_credit_pool, struct rfcomm_credit,
153                     "rfcomm_credit");
154                 error = 0;
155         } while(0); 
156
157         if (error) {
158                 netbt_dispose(NULL);
159                 panic("Can't create vm_zones");
160         }
161 }
162
163 struct domain btdomain = {
164         .dom_family = AF_BLUETOOTH,
165         .dom_name = "bluetooth",
166         .dom_init = netbt_init,
167         .dom_externalize = NULL,
168         .dom_dispose = netbt_dispose,
169         .dom_protosw = btsw,
170         .dom_protoswNPROTOSW = &btsw[sizeof(btsw)/sizeof(btsw[0])],
171         .dom_next = SLIST_ENTRY_INITIALIZER,
172         .dom_rtattach = 0,
173         .dom_rtoffset = 32,
174         .dom_maxrtkey = sizeof(struct sockaddr_bt),
175         .dom_ifattach = 0,
176         .dom_ifdetach = 0,
177 };
178
179 DOMAIN_SET(bt);
180 SYSCTL_NODE(_net, OID_AUTO, bluetooth, CTLFLAG_RD, 0,
181     "Bluetooth Protocol Family");
182
183 /* HCI sysctls */
184 SYSCTL_NODE(_net_bluetooth, OID_AUTO, hci, CTLFLAG_RD, 0,
185     "Host Controller Interface");
186 SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, sendspace, CTLFLAG_RW, &hci_sendspace,
187     0, "Socket Send Buffer Size");
188 SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, recvspace, CTLFLAG_RW, &hci_recvspace,
189     0, "Socket Receive Buffer Size");
190 SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, acl_expiry, CTLFLAG_RW,
191     &hci_acl_expiry, 0, "ACL Connection Expiry Time");
192 SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, memo_expiry, CTLFLAG_RW,
193     &hci_memo_expiry, 0, "Memo Expiry Time");
194 SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, eventq_max, CTLFLAG_RW,
195     &hci_eventq_max, 0, "Max Event queue length");
196 SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, aclrxq_max, CTLFLAG_RW,
197     &hci_aclrxq_max, 0, "Max ACL rx queue length");
198 SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, scorxq_max, CTLFLAG_RW,
199     &hci_scorxq_max, 0, "Max SCO rx queue length");
200
201 /* L2CAP sysctls */
202 SYSCTL_NODE(_net_bluetooth, OID_AUTO, l2cap, CTLFLAG_RD, 0,
203     "Logical Link Control & Adaptation Protocol");
204 SYSCTL_INT(_net_bluetooth_l2cap, OID_AUTO, sendspace, CTLFLAG_RW,
205     &l2cap_sendspace, 0, "Socket Send Buffer Size");
206 SYSCTL_INT(_net_bluetooth_l2cap, OID_AUTO, recvspace, CTLFLAG_RW,
207     &l2cap_recvspace, 0, "Socket Receive Buffer Size");
208 SYSCTL_INT(_net_bluetooth_l2cap, OID_AUTO, rtx, CTLFLAG_RW,
209     &l2cap_response_timeout, 0, "Response Timeout");
210 SYSCTL_INT(_net_bluetooth_l2cap, OID_AUTO, ertx, CTLFLAG_RW,
211     &l2cap_response_extended_timeout, 0, "Extended Response Timeout");
212
213 /* RFCOMM sysctls */
214 SYSCTL_NODE(_net_bluetooth, OID_AUTO, rfcomm, CTLFLAG_RD, 0,
215     "Serial Cable Emulation");
216 SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, sendspace, CTLFLAG_RW,
217     &rfcomm_sendspace, 0, "Socket Send Buffer Size");
218 SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, recvspace, CTLFLAG_RW,
219     &rfcomm_recvspace, 0, "Socket Receive Buffer Size");
220 SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, mtu_default, CTLFLAG_RW,
221     &rfcomm_mtu_default, 0, "Default MTU");
222 SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, ack_timeout, CTLFLAG_RW,
223     &rfcomm_ack_timeout, 0, "Acknowledgement Timer");
224 SYSCTL_INT(_net_bluetooth_rfcomm, OID_AUTO, mcc_timeout, CTLFLAG_RW,
225     &rfcomm_mcc_timeout, 0, "Response Timeout for Multiplexer Control Channel");
226
227 /* SCO sysctls */
228 SYSCTL_NODE(_net_bluetooth, OID_AUTO, sco, CTLFLAG_RD, 0, "SCO data");
229 SYSCTL_INT(_net_bluetooth_sco, OID_AUTO, sendspace, CTLFLAG_RW, &sco_sendspace,
230     0, "Socket Send Buffer Size");
231 SYSCTL_INT(_net_bluetooth_sco, OID_AUTO, recvspace, CTLFLAG_RW, &sco_recvspace,
232     0, "Socket Receive Buffer Size");
233
234 static void
235 netisr_netbt_setup(void *dummy __unused)
236 {
237         netisr_register(NETISR_BLUETOOTH, cpu0_portfn, btintr, 0);
238 }
239
240 SYSINIT(netbt_setup, SI_BOOT2_KLD, SI_ORDER_ANY, netisr_netbt_setup, NULL);