1 /*
2 * bluetooth.c
3 */
4
5 /*-
6 * SPDX-License-Identifier: BSD-2-Clause
7 *
8 * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
31 *
32 * $Id: ng_bluetooth.c,v 1.3 2003/04/26 22:37:31 max Exp $
33 */
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/errno.h>
38 #include <sys/kernel.h>
39 #include <sys/module.h>
40 #include <sys/sysctl.h>
41
42 #include <netgraph/bluetooth/include/ng_bluetooth.h>
43
44 /*
45 * Bluetooth stack sysctl globals
46 */
47
48 static u_int32_t bluetooth_hci_command_timeout_value = 5; /* sec */
49 static u_int32_t bluetooth_hci_connect_timeout_value = 60; /* sec */
50 static u_int32_t bluetooth_hci_max_neighbor_age_value = 600; /* sec */
51 static u_int32_t bluetooth_l2cap_rtx_timeout_value = 60; /* sec */
52 static u_int32_t bluetooth_l2cap_ertx_timeout_value = 300; /* sec */
53 static u_int32_t bluetooth_sco_rtx_timeout_value = 60; /* sec */
54
55 /*
56 * Define sysctl tree that shared by other parts of Bluetooth stack
57 */
58
59 SYSCTL_NODE(_net, OID_AUTO, bluetooth, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
60 "Bluetooth family");
61 SYSCTL_INT(_net_bluetooth, OID_AUTO, version,
62 CTLFLAG_RD, SYSCTL_NULL_INT_PTR, NG_BLUETOOTH_VERSION, "Version of the stack");
63
64 /*
65 * HCI
66 */
67
68 SYSCTL_NODE(_net_bluetooth, OID_AUTO, hci, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
69 "Bluetooth HCI family");
70
71 static int
bluetooth_set_hci_command_timeout_value(SYSCTL_HANDLER_ARGS)72 bluetooth_set_hci_command_timeout_value(SYSCTL_HANDLER_ARGS)
73 {
74 u_int32_t value;
75 int error;
76
77 value = bluetooth_hci_command_timeout_value;
78 error = sysctl_handle_int(oidp, &value, 0, req);
79 if (error == 0 && req->newptr != NULL) {
80 if (value > 0)
81 bluetooth_hci_command_timeout_value = value;
82 else
83 error = EINVAL;
84 }
85
86 return (error);
87 } /* bluetooth_set_hci_command_timeout_value */
88
89 SYSCTL_PROC(_net_bluetooth_hci, OID_AUTO, command_timeout,
90 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
91 &bluetooth_hci_command_timeout_value, 5,
92 bluetooth_set_hci_command_timeout_value,
93 "I", "HCI command timeout (sec)");
94
95 static int
bluetooth_set_hci_connect_timeout_value(SYSCTL_HANDLER_ARGS)96 bluetooth_set_hci_connect_timeout_value(SYSCTL_HANDLER_ARGS)
97 {
98 u_int32_t value;
99 int error;
100
101 value = bluetooth_hci_connect_timeout_value;
102 error = sysctl_handle_int(oidp, &value, 0, req);
103 if (error == 0 && req->newptr != NULL) {
104 if (0 < value && value <= bluetooth_l2cap_rtx_timeout_value)
105 bluetooth_hci_connect_timeout_value = value;
106 else
107 error = EINVAL;
108 }
109
110 return (error);
111 } /* bluetooth_set_hci_connect_timeout_value */
112
113 SYSCTL_PROC(_net_bluetooth_hci, OID_AUTO, connection_timeout,
114 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
115 &bluetooth_hci_connect_timeout_value, 60,
116 bluetooth_set_hci_connect_timeout_value,
117 "I", "HCI connect timeout (sec)");
118
119 SYSCTL_UINT(_net_bluetooth_hci, OID_AUTO, max_neighbor_age, CTLFLAG_RW,
120 &bluetooth_hci_max_neighbor_age_value, 600,
121 "Maximal HCI neighbor cache entry age (sec)");
122
123 /*
124 * L2CAP
125 */
126
127 SYSCTL_NODE(_net_bluetooth, OID_AUTO, l2cap, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
128 "Bluetooth L2CAP family");
129
130 static int
bluetooth_set_l2cap_rtx_timeout_value(SYSCTL_HANDLER_ARGS)131 bluetooth_set_l2cap_rtx_timeout_value(SYSCTL_HANDLER_ARGS)
132 {
133 u_int32_t value;
134 int error;
135
136 value = bluetooth_l2cap_rtx_timeout_value;
137 error = sysctl_handle_int(oidp, &value, 0, req);
138 if (error == 0 && req->newptr != NULL) {
139 if (bluetooth_hci_connect_timeout_value <= value &&
140 value <= bluetooth_l2cap_ertx_timeout_value)
141 bluetooth_l2cap_rtx_timeout_value = value;
142 else
143 error = EINVAL;
144 }
145
146 return (error);
147 } /* bluetooth_set_l2cap_rtx_timeout_value */
148
149 SYSCTL_PROC(_net_bluetooth_l2cap, OID_AUTO, rtx_timeout,
150 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
151 &bluetooth_l2cap_rtx_timeout_value, 60,
152 bluetooth_set_l2cap_rtx_timeout_value,
153 "I", "L2CAP RTX timeout (sec)");
154
155 static int
bluetooth_set_l2cap_ertx_timeout_value(SYSCTL_HANDLER_ARGS)156 bluetooth_set_l2cap_ertx_timeout_value(SYSCTL_HANDLER_ARGS)
157 {
158 u_int32_t value;
159 int error;
160
161 value = bluetooth_l2cap_ertx_timeout_value;
162 error = sysctl_handle_int(oidp, &value, 0, req);
163 if (error == 0 && req->newptr != NULL) {
164 if (value >= bluetooth_l2cap_rtx_timeout_value)
165 bluetooth_l2cap_ertx_timeout_value = value;
166 else
167 error = EINVAL;
168 }
169
170 return (error);
171 } /* bluetooth_set_l2cap_ertx_timeout_value */
172
173 SYSCTL_PROC(_net_bluetooth_l2cap, OID_AUTO, ertx_timeout,
174 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
175 &bluetooth_l2cap_ertx_timeout_value, 300,
176 bluetooth_set_l2cap_ertx_timeout_value,
177 "I", "L2CAP ERTX timeout (sec)");
178
179 /*
180 * Return various sysctl values
181 */
182
183 u_int32_t
bluetooth_hci_command_timeout(void)184 bluetooth_hci_command_timeout(void)
185 {
186 return (bluetooth_hci_command_timeout_value * hz);
187 } /* bluetooth_hci_command_timeout */
188
189 u_int32_t
bluetooth_hci_connect_timeout(void)190 bluetooth_hci_connect_timeout(void)
191 {
192 return (bluetooth_hci_connect_timeout_value * hz);
193 } /* bluetooth_hci_connect_timeout */
194
195 u_int32_t
bluetooth_hci_max_neighbor_age(void)196 bluetooth_hci_max_neighbor_age(void)
197 {
198 return (bluetooth_hci_max_neighbor_age_value);
199 } /* bluetooth_hci_max_neighbor_age */
200
201 u_int32_t
bluetooth_l2cap_rtx_timeout(void)202 bluetooth_l2cap_rtx_timeout(void)
203 {
204 return (bluetooth_l2cap_rtx_timeout_value * hz);
205 } /* bluetooth_l2cap_rtx_timeout */
206
207 u_int32_t
bluetooth_l2cap_ertx_timeout(void)208 bluetooth_l2cap_ertx_timeout(void)
209 {
210 return (bluetooth_l2cap_ertx_timeout_value * hz);
211 } /* bluetooth_l2cap_ertx_timeout */
212
213 u_int32_t
bluetooth_sco_rtx_timeout(void)214 bluetooth_sco_rtx_timeout(void)
215 {
216 return (bluetooth_sco_rtx_timeout_value * hz);
217 } /* bluetooth_sco_rtx_timeout */
218
219 /*
220 * RFCOMM
221 */
222
223 SYSCTL_NODE(_net_bluetooth, OID_AUTO, rfcomm, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
224 "Bluetooth RFCOMM family");
225
226 /*
227 * SCO
228 */
229
230 SYSCTL_NODE(_net_bluetooth, OID_AUTO, sco, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
231 "Bluetooth SCO family");
232
233 static int
bluetooth_set_sco_rtx_timeout_value(SYSCTL_HANDLER_ARGS)234 bluetooth_set_sco_rtx_timeout_value(SYSCTL_HANDLER_ARGS)
235 {
236 u_int32_t value;
237 int error;
238
239 value = bluetooth_sco_rtx_timeout_value;
240 error = sysctl_handle_int(oidp, &value, 0, req);
241 if (error == 0 && req->newptr != NULL) {
242 if (bluetooth_hci_connect_timeout_value <= value)
243 bluetooth_sco_rtx_timeout_value = value;
244 else
245 error = EINVAL;
246 }
247
248 return (error);
249 } /* bluetooth_set_sco_rtx_timeout_value */
250
251 SYSCTL_PROC(_net_bluetooth_sco, OID_AUTO, rtx_timeout,
252 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
253 &bluetooth_sco_rtx_timeout_value, 60,
254 bluetooth_set_sco_rtx_timeout_value,
255 "I", "SCO RTX timeout (sec)");
256
257 /*
258 * Handle loading and unloading for this code.
259 */
260
261 static int
bluetooth_modevent(module_t mod,int event,void * data)262 bluetooth_modevent(module_t mod, int event, void *data)
263 {
264 int error = 0;
265
266 switch (event) {
267 case MOD_LOAD:
268 break;
269
270 case MOD_UNLOAD:
271 break;
272
273 default:
274 error = EOPNOTSUPP;
275 break;
276 }
277
278 return (error);
279 } /* bluetooth_modevent */
280
281 /*
282 * Module
283 */
284
285 static moduledata_t bluetooth_mod = {
286 "ng_bluetooth",
287 bluetooth_modevent,
288 NULL
289 };
290
291 DECLARE_MODULE(ng_bluetooth, bluetooth_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
292 MODULE_VERSION(ng_bluetooth, NG_BLUETOOTH_VERSION);
293