1107120Sjulian/*
2107120Sjulian * bluetooth.c
3139823Simp */
4139823Simp
5139823Simp/*-
6107120Sjulian * Copyright (c) 2001-2002 Maksim Yevmenkin <m_evmenkin@yahoo.com>
7107120Sjulian * All rights reserved.
8107120Sjulian *
9107120Sjulian * Redistribution and use in source and binary forms, with or without
10107120Sjulian * modification, are permitted provided that the following conditions
11107120Sjulian * are met:
12107120Sjulian * 1. Redistributions of source code must retain the above copyright
13107120Sjulian *    notice, this list of conditions and the following disclaimer.
14107120Sjulian * 2. Redistributions in binary form must reproduce the above copyright
15107120Sjulian *    notice, this list of conditions and the following disclaimer in the
16107120Sjulian *    documentation and/or other materials provided with the distribution.
17107120Sjulian *
18107120Sjulian * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19107120Sjulian * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20107120Sjulian * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21107120Sjulian * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
22107120Sjulian * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23107120Sjulian * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24107120Sjulian * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25107120Sjulian * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26107120Sjulian * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27107120Sjulian * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28107120Sjulian * SUCH DAMAGE.
29107120Sjulian *
30114878Sjulian * $Id: ng_bluetooth.c,v 1.3 2003/04/26 22:37:31 max Exp $
31107120Sjulian * $FreeBSD$
32107120Sjulian */
33107120Sjulian
34107120Sjulian#include <sys/param.h>
35107120Sjulian#include <sys/systm.h>
36107120Sjulian#include <sys/errno.h>
37107120Sjulian#include <sys/kernel.h>
38129880Sphk#include <sys/module.h>
39107120Sjulian#include <sys/sysctl.h>
40107120Sjulian
41128688Semax#include <netgraph/bluetooth/include/ng_bluetooth.h>
42107120Sjulian
43107120Sjulian/*
44107120Sjulian * Bluetooth stack sysctl globals
45107120Sjulian */
46107120Sjulian
47107120Sjulianstatic u_int32_t	bluetooth_hci_command_timeout_value  = 5;   /* sec */
48107120Sjulianstatic u_int32_t	bluetooth_hci_connect_timeout_value  = 60;  /* sec */
49107120Sjulianstatic u_int32_t	bluetooth_hci_max_neighbor_age_value = 600; /* sec */
50107120Sjulianstatic u_int32_t	bluetooth_l2cap_rtx_timeout_value    = 60;  /* sec */
51107120Sjulianstatic u_int32_t	bluetooth_l2cap_ertx_timeout_value   = 300; /* sec */
52180399Semaxstatic u_int32_t	bluetooth_sco_rtx_timeout_value      = 60;  /* sec */
53107120Sjulian
54107120Sjulian/*
55107120Sjulian * Define sysctl tree that shared by other parts of Bluetooth stack
56107120Sjulian */
57107120Sjulian
58107120SjulianSYSCTL_NODE(_net, OID_AUTO, bluetooth, CTLFLAG_RW, 0, "Bluetooth family");
59107120SjulianSYSCTL_INT(_net_bluetooth, OID_AUTO, version,
60180508Strhodes	CTLFLAG_RD, 0, NG_BLUETOOTH_VERSION, "Version of the stack");
61107120Sjulian
62107120Sjulian/*
63107120Sjulian * HCI
64107120Sjulian */
65107120Sjulian
66107120SjulianSYSCTL_NODE(_net_bluetooth, OID_AUTO, hci, CTLFLAG_RW,
67107120Sjulian	0, "Bluetooth HCI family");
68107120Sjulian
69107120Sjulianstatic int
70107120Sjulianbluetooth_set_hci_command_timeout_value(SYSCTL_HANDLER_ARGS)
71107120Sjulian{
72107120Sjulian	u_int32_t	value;
73107120Sjulian	int		error;
74107120Sjulian
75107120Sjulian	value = bluetooth_hci_command_timeout_value;
76170289Sdwmalone	error = sysctl_handle_int(oidp, &value, 0, req);
77107120Sjulian	if (error == 0 && req->newptr != NULL) {
78107120Sjulian		if (value > 0)
79107120Sjulian			bluetooth_hci_command_timeout_value = value;
80107120Sjulian		else
81107120Sjulian			error = EINVAL;
82107120Sjulian	}
83107120Sjulian
84107120Sjulian	return (error);
85107120Sjulian} /* bluetooth_set_hci_command_timeout_value */
86107120Sjulian
87107120SjulianSYSCTL_PROC(_net_bluetooth_hci, OID_AUTO, command_timeout,
88107120Sjulian	CTLTYPE_INT | CTLFLAG_RW,
89107120Sjulian	&bluetooth_hci_command_timeout_value, 5,
90107120Sjulian	bluetooth_set_hci_command_timeout_value,
91107120Sjulian	"I", "HCI command timeout (sec)");
92107120Sjulian
93107120Sjulianstatic int
94107120Sjulianbluetooth_set_hci_connect_timeout_value(SYSCTL_HANDLER_ARGS)
95107120Sjulian{
96107120Sjulian	u_int32_t	value;
97107120Sjulian	int		error;
98107120Sjulian
99107120Sjulian	value = bluetooth_hci_connect_timeout_value;
100170289Sdwmalone	error = sysctl_handle_int(oidp, &value, 0, req);
101107120Sjulian	if (error == 0 && req->newptr != NULL) {
102107120Sjulian		if (0 < value && value <= bluetooth_l2cap_rtx_timeout_value)
103107120Sjulian			bluetooth_hci_connect_timeout_value = value;
104107120Sjulian		else
105107120Sjulian			error = EINVAL;
106107120Sjulian	}
107107120Sjulian
108107120Sjulian	return (error);
109107120Sjulian} /* bluetooth_set_hci_connect_timeout_value */
110107120Sjulian
111107120SjulianSYSCTL_PROC(_net_bluetooth_hci, OID_AUTO, connection_timeout,
112107120Sjulian	CTLTYPE_INT | CTLFLAG_RW,
113107120Sjulian	&bluetooth_hci_connect_timeout_value, 60,
114107120Sjulian	bluetooth_set_hci_connect_timeout_value,
115107120Sjulian	"I", "HCI connect timeout (sec)");
116107120Sjulian
117217320SmdfSYSCTL_UINT(_net_bluetooth_hci, OID_AUTO, max_neighbor_age, CTLFLAG_RW,
118107120Sjulian	&bluetooth_hci_max_neighbor_age_value, 600,
119107120Sjulian	"Maximal HCI neighbor cache entry age (sec)");
120107120Sjulian
121107120Sjulian/*
122107120Sjulian * L2CAP
123107120Sjulian */
124107120Sjulian
125107120SjulianSYSCTL_NODE(_net_bluetooth, OID_AUTO, l2cap, CTLFLAG_RW,
126107120Sjulian	0, "Bluetooth L2CAP family");
127107120Sjulian
128107120Sjulianstatic int
129107120Sjulianbluetooth_set_l2cap_rtx_timeout_value(SYSCTL_HANDLER_ARGS)
130107120Sjulian{
131107120Sjulian	u_int32_t	value;
132107120Sjulian	int		error;
133107120Sjulian
134107120Sjulian	value = bluetooth_l2cap_rtx_timeout_value;
135170289Sdwmalone	error = sysctl_handle_int(oidp, &value, 0, req);
136107120Sjulian	if (error == 0 && req->newptr != NULL) {
137107120Sjulian		if (bluetooth_hci_connect_timeout_value <= value &&
138107120Sjulian		    value <= bluetooth_l2cap_ertx_timeout_value)
139107120Sjulian			bluetooth_l2cap_rtx_timeout_value = value;
140107120Sjulian		else
141107120Sjulian			error = EINVAL;
142107120Sjulian	}
143107120Sjulian
144107120Sjulian	return (error);
145107120Sjulian} /* bluetooth_set_l2cap_rtx_timeout_value */
146107120Sjulian
147107120SjulianSYSCTL_PROC(_net_bluetooth_l2cap, OID_AUTO, rtx_timeout,
148107120Sjulian	CTLTYPE_INT | CTLFLAG_RW,
149107120Sjulian	&bluetooth_l2cap_rtx_timeout_value, 60,
150107120Sjulian	bluetooth_set_l2cap_rtx_timeout_value,
151107120Sjulian	"I", "L2CAP RTX timeout (sec)");
152107120Sjulian
153107120Sjulianstatic int
154107120Sjulianbluetooth_set_l2cap_ertx_timeout_value(SYSCTL_HANDLER_ARGS)
155107120Sjulian{
156107120Sjulian	u_int32_t	value;
157107120Sjulian	int		error;
158107120Sjulian
159107120Sjulian	value = bluetooth_l2cap_ertx_timeout_value;
160170289Sdwmalone	error = sysctl_handle_int(oidp, &value, 0, req);
161107120Sjulian	if (error == 0 && req->newptr != NULL) {
162107120Sjulian		if (value >= bluetooth_l2cap_rtx_timeout_value)
163107120Sjulian			bluetooth_l2cap_ertx_timeout_value = value;
164107120Sjulian		else
165107120Sjulian			error = EINVAL;
166107120Sjulian	}
167107120Sjulian
168107120Sjulian	return (error);
169107120Sjulian} /* bluetooth_set_l2cap_ertx_timeout_value */
170107120Sjulian
171107120SjulianSYSCTL_PROC(_net_bluetooth_l2cap, OID_AUTO, ertx_timeout,
172107120Sjulian	CTLTYPE_INT | CTLFLAG_RW,
173107120Sjulian	&bluetooth_l2cap_ertx_timeout_value, 300,
174107120Sjulian	bluetooth_set_l2cap_ertx_timeout_value,
175107120Sjulian	"I", "L2CAP ERTX timeout (sec)");
176107120Sjulian
177107120Sjulian/*
178107120Sjulian * Return various sysctl values
179107120Sjulian */
180107120Sjulian
181107120Sjulianu_int32_t
182107120Sjulianbluetooth_hci_command_timeout(void)
183107120Sjulian{
184107120Sjulian	return (bluetooth_hci_command_timeout_value * hz);
185107120Sjulian} /* bluetooth_hci_command_timeout */
186107120Sjulian
187107120Sjulianu_int32_t
188107120Sjulianbluetooth_hci_connect_timeout(void)
189107120Sjulian{
190107120Sjulian	return (bluetooth_hci_connect_timeout_value * hz);
191107120Sjulian} /* bluetooth_hci_connect_timeout */
192107120Sjulian
193107120Sjulianu_int32_t
194107120Sjulianbluetooth_hci_max_neighbor_age(void)
195107120Sjulian{
196107120Sjulian	return (bluetooth_hci_max_neighbor_age_value);
197107120Sjulian} /* bluetooth_hci_max_neighbor_age */
198107120Sjulian
199107120Sjulianu_int32_t
200107120Sjulianbluetooth_l2cap_rtx_timeout(void)
201107120Sjulian{
202107120Sjulian	return (bluetooth_l2cap_rtx_timeout_value * hz);
203107120Sjulian} /* bluetooth_l2cap_rtx_timeout */
204107120Sjulian
205107120Sjulianu_int32_t
206107120Sjulianbluetooth_l2cap_ertx_timeout(void)
207107120Sjulian{
208107120Sjulian	return (bluetooth_l2cap_ertx_timeout_value * hz);
209107120Sjulian} /* bluetooth_l2cap_ertx_timeout */
210107120Sjulian
211180399Semaxu_int32_t
212180399Semaxbluetooth_sco_rtx_timeout(void)
213180399Semax{
214180399Semax	return (bluetooth_sco_rtx_timeout_value * hz);
215180399Semax} /* bluetooth_sco_rtx_timeout */
216180399Semax
217114878Sjulian/*
218114878Sjulian * RFCOMM
219114878Sjulian */
220114878Sjulian
221114878SjulianSYSCTL_NODE(_net_bluetooth, OID_AUTO, rfcomm, CTLFLAG_RW,
222114878Sjulian	0, "Bluetooth RFCOMM family");
223114878Sjulian
224180399Semax/*
225180399Semax * SCO
226180399Semax */
227180399Semax
228180399SemaxSYSCTL_NODE(_net_bluetooth, OID_AUTO, sco, CTLFLAG_RW,
229180399Semax	0, "Bluetooth SCO family");
230180399Semax
231180399Semaxstatic int
232180399Semaxbluetooth_set_sco_rtx_timeout_value(SYSCTL_HANDLER_ARGS)
233180399Semax{
234180399Semax	u_int32_t	value;
235180399Semax	int		error;
236180399Semax
237180399Semax	value = bluetooth_sco_rtx_timeout_value;
238180399Semax	error = sysctl_handle_int(oidp, &value, 0, req);
239180399Semax	if (error == 0 && req->newptr != NULL) {
240180399Semax		if (bluetooth_hci_connect_timeout_value <= value)
241180399Semax			bluetooth_sco_rtx_timeout_value = value;
242180399Semax		else
243180399Semax			error = EINVAL;
244180399Semax	}
245180399Semax
246180399Semax	return (error);
247180399Semax} /* bluetooth_set_sco_rtx_timeout_value */
248180399Semax
249180399SemaxSYSCTL_PROC(_net_bluetooth_sco, OID_AUTO, rtx_timeout,
250180399Semax	CTLTYPE_INT | CTLFLAG_RW,
251180399Semax	&bluetooth_sco_rtx_timeout_value, 60,
252180399Semax	bluetooth_set_sco_rtx_timeout_value,
253180399Semax	"I", "SCO RTX timeout (sec)");
254180399Semax
255107120Sjulian/*
256107120Sjulian * Handle loading and unloading for this code.
257107120Sjulian */
258107120Sjulian
259107120Sjulianstatic int
260107120Sjulianbluetooth_modevent(module_t mod, int event, void *data)
261107120Sjulian{
262107120Sjulian	int	error = 0;
263107120Sjulian
264107120Sjulian	switch (event) {
265107120Sjulian	case MOD_LOAD:
266107120Sjulian		break;
267107120Sjulian
268107120Sjulian	case MOD_UNLOAD:
269107120Sjulian		break;
270107120Sjulian
271107120Sjulian	default:
272107120Sjulian		error = EOPNOTSUPP;
273107120Sjulian		break;
274107120Sjulian	}
275107120Sjulian
276107120Sjulian	return (error);
277107120Sjulian} /* bluetooth_modevent */
278107120Sjulian
279107120Sjulian/*
280107120Sjulian * Module
281107120Sjulian */
282107120Sjulian
283107120Sjulianstatic moduledata_t	bluetooth_mod = {
284144781Speter	"ng_bluetooth",
285107120Sjulian	bluetooth_modevent,
286107120Sjulian	NULL
287107120Sjulian};
288107120Sjulian
289107120SjulianDECLARE_MODULE(ng_bluetooth, bluetooth_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
290107120SjulianMODULE_VERSION(ng_bluetooth, NG_BLUETOOTH_VERSION);
291107120Sjulian
292