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