1/*
2 * bluetooth.c
3 */
4
5/*-
6 * Copyright (c) 2001-2002 Maksim Yevmenkin <[email protected]>
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 */
33
34#include <sys/param.h>
35#include <sys/systm.h>
36#include <sys/errno.h>
37#include <sys/kernel.h>
38#include <sys/module.h>
39#include <sys/sysctl.h>
40
41#include <netgraph7/bluetooth/include/ng_bluetooth.h>
42
43/*
44 * Bluetooth stack sysctl globals
45 */
46
47static u_int32_t    bluetooth_hci_command_timeout_value  = 5;   /* sec */
48static u_int32_t    bluetooth_hci_connect_timeout_value  = 60;  /* sec */
49static u_int32_t    bluetooth_hci_max_neighbor_age_value = 600; /* sec */
50static u_int32_t    bluetooth_l2cap_rtx_timeout_value    = 60;  /* sec */
51static u_int32_t    bluetooth_l2cap_ertx_timeout_value   = 300; /* sec */
52
53/*
54 * Define sysctl tree that shared by other parts of Bluetooth stack
55 */
56
57SYSCTL_NODE(_net, OID_AUTO, bluetooth, CTLFLAG_RW, 0, "Bluetooth family");
58SYSCTL_INT(_net_bluetooth, OID_AUTO, version,
59    CTLFLAG_RD, 0, NG_BLUETOOTH_VERSION, "");
60
61/*
62 * HCI
63 */
64
65SYSCTL_NODE(_net_bluetooth, OID_AUTO, hci, CTLFLAG_RW,
66    0, "Bluetooth HCI family");
67
68static int
69bluetooth_set_hci_command_timeout_value(SYSCTL_HANDLER_ARGS)
70{
71    u_int32_t   value;
72    int     error;
73
74    value = bluetooth_hci_command_timeout_value;
75    error = sysctl_handle_int(oidp, &value, 0, req);
76    if (error == 0 && req->newptr != NULL) {
77        if (value > 0)
78            bluetooth_hci_command_timeout_value = value;
79        else
80            error = EINVAL;
81    }
82
83    return (error);
84} /* bluetooth_set_hci_command_timeout_value */
85
86SYSCTL_PROC(_net_bluetooth_hci, OID_AUTO, command_timeout,
87    CTLTYPE_INT | CTLFLAG_RW,
88    &bluetooth_hci_command_timeout_value, 5,
89    bluetooth_set_hci_command_timeout_value,
90    "I", "HCI command timeout (sec)");
91
92static int
93bluetooth_set_hci_connect_timeout_value(SYSCTL_HANDLER_ARGS)
94{
95    u_int32_t   value;
96    int     error;
97
98    value = bluetooth_hci_connect_timeout_value;
99    error = sysctl_handle_int(oidp, &value, 0, req);
100    if (error == 0 && req->newptr != NULL) {
101        if (0 < value && value <= bluetooth_l2cap_rtx_timeout_value)
102            bluetooth_hci_connect_timeout_value = value;
103        else
104            error = EINVAL;
105    }
106
107    return (error);
108} /* bluetooth_set_hci_connect_timeout_value */
109
110SYSCTL_PROC(_net_bluetooth_hci, OID_AUTO, connection_timeout,
111    CTLTYPE_INT | CTLFLAG_RW,
112    &bluetooth_hci_connect_timeout_value, 60,
113    bluetooth_set_hci_connect_timeout_value,
114    "I", "HCI connect timeout (sec)");
115
116SYSCTL_INT(_net_bluetooth_hci, OID_AUTO, max_neighbor_age, CTLFLAG_RW,
117    &bluetooth_hci_max_neighbor_age_value, 600,
118    "Maximal HCI neighbor cache entry age (sec)");
119
120/*
121 * L2CAP
122 */
123
124SYSCTL_NODE(_net_bluetooth, OID_AUTO, l2cap, CTLFLAG_RW,
125    0, "Bluetooth L2CAP family");
126
127static int
128bluetooth_set_l2cap_rtx_timeout_value(SYSCTL_HANDLER_ARGS)
129{
130    u_int32_t   value;
131    int     error;
132
133    value = bluetooth_l2cap_rtx_timeout_value;
134    error = sysctl_handle_int(oidp, &value, 0, req);
135    if (error == 0 && req->newptr != NULL) {
136        if (bluetooth_hci_connect_timeout_value <= value &&
137            value <= bluetooth_l2cap_ertx_timeout_value)
138            bluetooth_l2cap_rtx_timeout_value = value;
139        else
140            error = EINVAL;
141    }
142
143    return (error);
144} /* bluetooth_set_l2cap_rtx_timeout_value */
145
146SYSCTL_PROC(_net_bluetooth_l2cap, OID_AUTO, rtx_timeout,
147    CTLTYPE_INT | CTLFLAG_RW,
148    &bluetooth_l2cap_rtx_timeout_value, 60,
149    bluetooth_set_l2cap_rtx_timeout_value,
150    "I", "L2CAP RTX timeout (sec)");
151
152static int
153bluetooth_set_l2cap_ertx_timeout_value(SYSCTL_HANDLER_ARGS)
154{
155    u_int32_t   value;
156    int     error;
157
158    value = bluetooth_l2cap_ertx_timeout_value;
159    error = sysctl_handle_int(oidp, &value, 0, req);
160    if (error == 0 && req->newptr != NULL) {
161        if (value >= bluetooth_l2cap_rtx_timeout_value)
162            bluetooth_l2cap_ertx_timeout_value = value;
163        else
164            error = EINVAL;
165    }
166
167    return (error);
168} /* bluetooth_set_l2cap_ertx_timeout_value */
169
170SYSCTL_PROC(_net_bluetooth_l2cap, OID_AUTO, ertx_timeout,
171    CTLTYPE_INT | CTLFLAG_RW,
172    &bluetooth_l2cap_ertx_timeout_value, 300,
173    bluetooth_set_l2cap_ertx_timeout_value,
174    "I", "L2CAP ERTX timeout (sec)");
175
176/*
177 * Return various sysctl values
178 */
179
180u_int32_t
181bluetooth_hci_command_timeout(void)
182{
183    return (bluetooth_hci_command_timeout_value * hz);
184} /* bluetooth_hci_command_timeout */
185
186u_int32_t
187bluetooth_hci_connect_timeout(void)
188{
189    return (bluetooth_hci_connect_timeout_value * hz);
190} /* bluetooth_hci_connect_timeout */
191
192u_int32_t
193bluetooth_hci_max_neighbor_age(void)
194{
195    return (bluetooth_hci_max_neighbor_age_value);
196} /* bluetooth_hci_max_neighbor_age */
197
198u_int32_t
199bluetooth_l2cap_rtx_timeout(void)
200{
201    return (bluetooth_l2cap_rtx_timeout_value * hz);
202} /* bluetooth_l2cap_rtx_timeout */
203
204u_int32_t
205bluetooth_l2cap_ertx_timeout(void)
206{
207    return (bluetooth_l2cap_ertx_timeout_value * hz);
208} /* bluetooth_l2cap_ertx_timeout */
209
210/*
211 * RFCOMM
212 */
213
214SYSCTL_NODE(_net_bluetooth, OID_AUTO, rfcomm, CTLFLAG_RW,
215    0, "Bluetooth RFCOMM family");
216
217/*
218 * Handle loading and unloading for this code.
219 */
220
221static int
222bluetooth_modevent(module_t mod, int event, void *data)
223{
224    int error = 0;
225
226    switch (event) {
227    case MOD_LOAD:
228        break;
229
230    case MOD_UNLOAD:
231        break;
232
233    default:
234        error = EOPNOTSUPP;
235        break;
236    }
237
238    return (error);
239} /* bluetooth_modevent */
240
241/*
242 * Module
243 */
244
245static moduledata_t bluetooth_mod = {
246    "ng_bluetooth",
247    bluetooth_modevent,
248    NULL
249};
250
251DECLARE_MODULE(ng_bluetooth, bluetooth_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
252MODULE_VERSION(ng_bluetooth, NG_BLUETOOTH_VERSION);
253
254