1 /* 2 * bluetooth.c 3 */ 4 5 /*- 6 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 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 * $FreeBSD$ 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 <netgraph/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 static u_int32_t bluetooth_sco_rtx_timeout_value = 60; /* sec */ 55 56 /* 57 * Define sysctl tree that shared by other parts of Bluetooth stack 58 */ 59 60 SYSCTL_NODE(_net, OID_AUTO, bluetooth, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 61 "Bluetooth family"); 62 SYSCTL_INT(_net_bluetooth, OID_AUTO, version, 63 CTLFLAG_RD, SYSCTL_NULL_INT_PTR, NG_BLUETOOTH_VERSION, "Version of the stack"); 64 65 /* 66 * HCI 67 */ 68 69 SYSCTL_NODE(_net_bluetooth, OID_AUTO, hci, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 70 "Bluetooth HCI family"); 71 72 static int 73 bluetooth_set_hci_command_timeout_value(SYSCTL_HANDLER_ARGS) 74 { 75 u_int32_t value; 76 int error; 77 78 value = bluetooth_hci_command_timeout_value; 79 error = sysctl_handle_int(oidp, &value, 0, req); 80 if (error == 0 && req->newptr != NULL) { 81 if (value > 0) 82 bluetooth_hci_command_timeout_value = value; 83 else 84 error = EINVAL; 85 } 86 87 return (error); 88 } /* bluetooth_set_hci_command_timeout_value */ 89 90 SYSCTL_PROC(_net_bluetooth_hci, OID_AUTO, command_timeout, 91 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 92 &bluetooth_hci_command_timeout_value, 5, 93 bluetooth_set_hci_command_timeout_value, 94 "I", "HCI command timeout (sec)"); 95 96 static int 97 bluetooth_set_hci_connect_timeout_value(SYSCTL_HANDLER_ARGS) 98 { 99 u_int32_t value; 100 int error; 101 102 value = bluetooth_hci_connect_timeout_value; 103 error = sysctl_handle_int(oidp, &value, 0, req); 104 if (error == 0 && req->newptr != NULL) { 105 if (0 < value && value <= bluetooth_l2cap_rtx_timeout_value) 106 bluetooth_hci_connect_timeout_value = value; 107 else 108 error = EINVAL; 109 } 110 111 return (error); 112 } /* bluetooth_set_hci_connect_timeout_value */ 113 114 SYSCTL_PROC(_net_bluetooth_hci, OID_AUTO, connection_timeout, 115 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 116 &bluetooth_hci_connect_timeout_value, 60, 117 bluetooth_set_hci_connect_timeout_value, 118 "I", "HCI connect timeout (sec)"); 119 120 SYSCTL_UINT(_net_bluetooth_hci, OID_AUTO, max_neighbor_age, CTLFLAG_RW, 121 &bluetooth_hci_max_neighbor_age_value, 600, 122 "Maximal HCI neighbor cache entry age (sec)"); 123 124 /* 125 * L2CAP 126 */ 127 128 SYSCTL_NODE(_net_bluetooth, OID_AUTO, l2cap, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 129 "Bluetooth L2CAP family"); 130 131 static int 132 bluetooth_set_l2cap_rtx_timeout_value(SYSCTL_HANDLER_ARGS) 133 { 134 u_int32_t value; 135 int error; 136 137 value = bluetooth_l2cap_rtx_timeout_value; 138 error = sysctl_handle_int(oidp, &value, 0, req); 139 if (error == 0 && req->newptr != NULL) { 140 if (bluetooth_hci_connect_timeout_value <= value && 141 value <= bluetooth_l2cap_ertx_timeout_value) 142 bluetooth_l2cap_rtx_timeout_value = value; 143 else 144 error = EINVAL; 145 } 146 147 return (error); 148 } /* bluetooth_set_l2cap_rtx_timeout_value */ 149 150 SYSCTL_PROC(_net_bluetooth_l2cap, OID_AUTO, rtx_timeout, 151 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 152 &bluetooth_l2cap_rtx_timeout_value, 60, 153 bluetooth_set_l2cap_rtx_timeout_value, 154 "I", "L2CAP RTX timeout (sec)"); 155 156 static int 157 bluetooth_set_l2cap_ertx_timeout_value(SYSCTL_HANDLER_ARGS) 158 { 159 u_int32_t value; 160 int error; 161 162 value = bluetooth_l2cap_ertx_timeout_value; 163 error = sysctl_handle_int(oidp, &value, 0, req); 164 if (error == 0 && req->newptr != NULL) { 165 if (value >= bluetooth_l2cap_rtx_timeout_value) 166 bluetooth_l2cap_ertx_timeout_value = value; 167 else 168 error = EINVAL; 169 } 170 171 return (error); 172 } /* bluetooth_set_l2cap_ertx_timeout_value */ 173 174 SYSCTL_PROC(_net_bluetooth_l2cap, OID_AUTO, ertx_timeout, 175 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 176 &bluetooth_l2cap_ertx_timeout_value, 300, 177 bluetooth_set_l2cap_ertx_timeout_value, 178 "I", "L2CAP ERTX timeout (sec)"); 179 180 /* 181 * Return various sysctl values 182 */ 183 184 u_int32_t 185 bluetooth_hci_command_timeout(void) 186 { 187 return (bluetooth_hci_command_timeout_value * hz); 188 } /* bluetooth_hci_command_timeout */ 189 190 u_int32_t 191 bluetooth_hci_connect_timeout(void) 192 { 193 return (bluetooth_hci_connect_timeout_value * hz); 194 } /* bluetooth_hci_connect_timeout */ 195 196 u_int32_t 197 bluetooth_hci_max_neighbor_age(void) 198 { 199 return (bluetooth_hci_max_neighbor_age_value); 200 } /* bluetooth_hci_max_neighbor_age */ 201 202 u_int32_t 203 bluetooth_l2cap_rtx_timeout(void) 204 { 205 return (bluetooth_l2cap_rtx_timeout_value * hz); 206 } /* bluetooth_l2cap_rtx_timeout */ 207 208 u_int32_t 209 bluetooth_l2cap_ertx_timeout(void) 210 { 211 return (bluetooth_l2cap_ertx_timeout_value * hz); 212 } /* bluetooth_l2cap_ertx_timeout */ 213 214 u_int32_t 215 bluetooth_sco_rtx_timeout(void) 216 { 217 return (bluetooth_sco_rtx_timeout_value * hz); 218 } /* bluetooth_sco_rtx_timeout */ 219 220 /* 221 * RFCOMM 222 */ 223 224 SYSCTL_NODE(_net_bluetooth, OID_AUTO, rfcomm, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 225 "Bluetooth RFCOMM family"); 226 227 /* 228 * SCO 229 */ 230 231 SYSCTL_NODE(_net_bluetooth, OID_AUTO, sco, CTLFLAG_RW | CTLFLAG_MPSAFE, 0, 232 "Bluetooth SCO family"); 233 234 static int 235 bluetooth_set_sco_rtx_timeout_value(SYSCTL_HANDLER_ARGS) 236 { 237 u_int32_t value; 238 int error; 239 240 value = bluetooth_sco_rtx_timeout_value; 241 error = sysctl_handle_int(oidp, &value, 0, req); 242 if (error == 0 && req->newptr != NULL) { 243 if (bluetooth_hci_connect_timeout_value <= value) 244 bluetooth_sco_rtx_timeout_value = value; 245 else 246 error = EINVAL; 247 } 248 249 return (error); 250 } /* bluetooth_set_sco_rtx_timeout_value */ 251 252 SYSCTL_PROC(_net_bluetooth_sco, OID_AUTO, rtx_timeout, 253 CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT, 254 &bluetooth_sco_rtx_timeout_value, 60, 255 bluetooth_set_sco_rtx_timeout_value, 256 "I", "SCO RTX timeout (sec)"); 257 258 /* 259 * Handle loading and unloading for this code. 260 */ 261 262 static int 263 bluetooth_modevent(module_t mod, int event, void *data) 264 { 265 int error = 0; 266 267 switch (event) { 268 case MOD_LOAD: 269 break; 270 271 case MOD_UNLOAD: 272 break; 273 274 default: 275 error = EOPNOTSUPP; 276 break; 277 } 278 279 return (error); 280 } /* bluetooth_modevent */ 281 282 /* 283 * Module 284 */ 285 286 static moduledata_t bluetooth_mod = { 287 "ng_bluetooth", 288 bluetooth_modevent, 289 NULL 290 }; 291 292 DECLARE_MODULE(ng_bluetooth, bluetooth_mod, SI_SUB_PSEUDO, SI_ORDER_ANY); 293 MODULE_VERSION(ng_bluetooth, NG_BLUETOOTH_VERSION); 294 295