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 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 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 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 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 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 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 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 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 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 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 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 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