bluetooth revision 165683
1#!/bin/sh 2# 3# Copyright (c) 2005 Maksim Yevmenkin <m_evmenkin@yahoo.com> 4# All rights reserved. 5# 6# Redistribution and use in source and binary forms, with or without 7# modification, are permitted provided that the following conditions 8# are met: 9# 1. Redistributions of source code must retain the above copyright 10# notice, this list of conditions and the following disclaimer. 11# 2. Redistributions in binary form must reproduce the above copyright 12# notice, this list of conditions and the following disclaimer in the 13# documentation and/or other materials provided with the distribution. 14# 15# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25# SUCH DAMAGE. 26# 27# $FreeBSD: head/etc/rc.d/bluetooth 165683 2006-12-31 10:37:18Z yar $ 28 29# PROVIDE: bluetooth 30# REQUIRE: DAEMON 31# KEYWORD: nojail nostart 32 33. /etc/rc.subr 34 35name="bluetooth" 36rcvar= 37start_cmd="bluetooth_start" 38stop_cmd="bluetooth_stop" 39required_modules="ng_bluetooth ng_hci ng_l2cap ng_btsocket" 40 41############################################################################## 42# Read and parse Bluetooth device configuration file 43############################################################################## 44 45bluetooth_read_conf() 46{ 47 local _err _file _line _namespace 48 49 _file=$1 50 _namespace=$2 51 _err=0 52 53 if [ ! -e $_file ]; then 54 return 0 55 fi 56 57 if [ ! -f $_file -o ! -r $_file ]; then 58 err 1 "Bluetooth configuration file $_file is not a file or not readable" 59 fi 60 61 while read _line 62 do 63 case "$_line" in 64 \#*) 65 continue 66 ;; 67 68 *) 69 if [ -z "$_line" ]; then 70 continue; 71 fi 72 73 74 if expr "$_line" : "[a-zA-Z0-9_]*=" > /dev/null 2>&1; then 75 eval "${_namespace}${_line}" 76 else 77 warn "Unable to parse line \"$_line\" in $_file" 78 _err=1 79 fi 80 ;; 81 esac 82 done < $_file 83 84 return $_err 85} 86 87############################################################################## 88# Setup Bluetooth stack. Create and connect nodes 89############################################################################## 90 91bluetooth_setup_stack() 92{ 93 dev=$1 94 shift 95 hook=$1 96 shift 97 98 # Setup HCI 99 ngctl mkpeer ${dev}: hci ${hook} drv \ 100 > /dev/null 2>&1 || return 1 101 102 ngctl name ${dev}:${hook} ${dev}hci \ 103 > /dev/null 2>&1 || return 1 104 105 ngctl msg ${dev}hci: set_debug ${bluetooth_device_hci_debug_level} \ 106 > /dev/null 2>&1 || return 1 107 108 # Setup L2CAP 109 ngctl mkpeer ${dev}hci: l2cap acl hci \ 110 > /dev/null 2>&1 || return 1 111 112 ngctl name ${dev}hci:acl ${dev}l2cap \ 113 > /dev/null 2>&1 || return 1 114 115 ngctl msg ${dev}l2cap: set_debug ${bluetooth_device_l2cap_debug_level} \ 116 > /dev/null 2>&1 || return 1 117 118 # Connect HCI node to the Bluetooth sockets layer 119 ngctl connect ${dev}hci: btsock_hci_raw: raw ${dev}raw \ 120 > /dev/null 2>&1 || return 1 121 122 # Connect L2CAP node to Bluetooth sockets layer 123 ngctl connect ${dev}l2cap: btsock_l2c_raw: ctl ${dev}ctl \ 124 > /dev/null 2>&1 || return 1 125 126 ngctl connect ${dev}l2cap: btsock_l2c: l2c ${dev}l2c \ 127 > /dev/null 2>&1 || return 1 128 129 # Initilalize HCI node 130 ${hccontrol} -n ${dev}hci reset \ 131 > /dev/null 2>&1 || return 1 132 133 ${hccontrol} -n ${dev}hci read_bd_addr \ 134 > /dev/null 2>&1 || return 1 135 136 ${hccontrol} -n ${dev}hci read_local_supported_features \ 137 > /dev/null 2>&1 || return 1 138 139 ${hccontrol} -n ${dev}hci read_buffer_size \ 140 > /dev/null 2>&1 || return 1 141 142 if checkyesno bluetooth_device_discoverable; then 143 if checkyesno bluetooth_device_connectable; then 144 ${hccontrol} -n ${dev}hci write_scan_enable 3 \ 145 > /dev/null 2>&1 || return 1 146 else 147 ${hccontrol} -n ${dev}hci write_scan_enable 1 \ 148 > /dev/null 2>&1 || return 1 149 fi 150 else 151 if checkyesno bluetooth_device_connectable; then 152 ${hccontrol} -n ${dev}hci write_scan_enable 2 \ 153 > /dev/null 2>&1 || return 1 154 else 155 ${hccontrol} -n ${dev}hci write_scan_enable 0 \ 156 > /dev/null 2>&1 || return 1 157 fi 158 fi 159 160 161 ${hccontrol} -n ${dev}hci write_class_of_device ${bluetooth_device_class} \ 162 > /dev/null 2>&1 || return 1 163 164 if checkyesno bluetooth_device_authentication_enable; then 165 ${hccontrol} -n ${dev}hci write_authentication_enable 1 \ 166 > /dev/null 2>&1 || return 1 167 else 168 ${hccontrol} -n ${dev}hci write_authentication_enable 0 \ 169 > /dev/null 2>&1 || return 1 170 fi 171 172 case "${bluetooth_device_encryption_mode}" in 173 [Nn][Oo][Nn][Ee]|0) 174 ${hccontrol} -n ${dev}hci write_encryption_mode 0 \ 175 > /dev/null 2>&1 || return 1 176 ;; 177 178 [Pp][2][Pp]|1) 179 ${hccontrol} -n ${dev}hci write_encryption_mode 1 \ 180 > /dev/null 2>&1 || return 1 181 ;; 182 183 [Al][Ll][Ll]|2) 184 ${hccontrol} -n ${dev}hci write_encryption_mode 2 \ 185 > /dev/null 2>&1 || return 1 186 ;; 187 188 *) 189 warn "Unsupported encryption mode ${bluetooth_device_encryption_mode} for device ${dev}" 190 return 1 191 ;; 192 esac 193 194 if checkyesno bluetooth_device_role_switch; then 195 ${hccontrol} -n ${dev}hci write_node_role_switch 1 \ 196 > /dev/null 2>&1 || return 1 197 else 198 ${hccontrol} -n ${dev}hci write_node_role_switch 0 \ 199 > /dev/null 2>&1 || return 1 200 fi 201 202 ${hccontrol} -n ${dev}hci change_local_name "${bluetooth_device_local_name}" \ 203 > /dev/null 2>&1 || return 1 204 205 ${hccontrol} -n ${dev}hci initialize \ 206 > /dev/null 2>&1 || return 1 207 208 return 0 209} 210 211############################################################################## 212# Shutdown Bluetooth stack. Destroy all nodes 213############################################################################## 214 215bluetooth_shutdown_stack() 216{ 217 dev=$1 218 219 ngctl shutdown ${dev}hci: > /dev/null 2>&1 220 ngctl shutdown ${dev}l2cap: > /dev/null 2>&1 221 222 return 0 223} 224 225############################################################################## 226# bluetooth_start() 227############################################################################## 228 229bluetooth_start() 230{ 231 local _file 232 233 dev=$1 234 235 # Try to figure out device type by looking at device name 236 case "${dev}" in 237 # sioX - serial/UART Bluetooth device 238 sio*) 239 load_kld ng_h4 || return 1 240 241 hook="hook" 242 243 # Obtain unit number from device. 244 unit=`expr ${dev} : 'sio\([0-9]\{1,\}\)'` 245 if [ -z "${unit}" ]; then 246 err 1 "Unable to get sio unit number: ${dev}" 247 fi 248 249 ${hcseriald} -f /dev/cuad${unit} -n ${dev} 250 sleep 1 # wait a little bit 251 252 if [ ! -f "/var/run/hcseriald.${dev}.pid" ]; then 253 err 1 "Unable to start hcseriald on ${dev}" 254 fi 255 ;; 256 257 # 3Com Bluetooth Adapter 3CRWB60-A 258 btccc*) 259 hook="hook" 260 261 # Obtain unit number from device. 262 unit=`expr ${dev} : 'btccc\([0-9]\{1,\}\)'` 263 if [ -z "${unit}" ]; then 264 err 1 "Unable to get bt3c unit number: ${dev}" 265 fi 266 ;; 267 268 # USB Bluetooth adapters 269 ubt*) 270 hook="hook" 271 272 # Obtain unit number from device. 273 unit=`expr ${dev} : 'ubt\([0-9]\{1,\}\)'` 274 if [ -z "${unit}" ]; then 275 err 1 "Unable to get ubt unit number: ${dev}" 276 fi 277 ;; 278 279 # Unknown 280 *) 281 err 1 "Unsupported device: ${dev}" 282 ;; 283 esac 284 285 # Be backward compatible and setup reasonable defaults 286 bluetooth_device_authentication_enable="0" 287 bluetooth_device_class="ff:01:0c" 288 bluetooth_device_connectable="1" 289 bluetooth_device_discoverable="1" 290 bluetooth_device_encryption_mode="0" 291 bluetooth_device_hci_debug_level="3" 292 bluetooth_device_l2cap_debug_level="3" 293 bluetooth_device_local_name="`/usr/bin/uname -n` (${dev})" 294 bluetooth_device_role_switch="1" 295 296 # Load default device configuration parameters 297 _file="/etc/defaults/bluetooth.device.conf" 298 299 if ! bluetooth_read_conf $_file bluetooth_device_ ; then 300 err 1 "Unable to read default Bluetooth configuration from $_file" 301 fi 302 303 # Load device specific overrides 304 _file="/etc/bluetooth/$dev.conf" 305 306 if ! bluetooth_read_conf $_file bluetooth_device_ ; then 307 err 1 "Unable to read Bluetooth device configuration from $_file" 308 fi 309 310 # Setup stack 311 if ! bluetooth_setup_stack ${dev} ${hook} ; then 312 bluetooth_shutdown_stack $dev 313 err 1 "Unable to setup Bluetooth stack for device ${dev}" 314 fi 315 316 return 0 317} 318 319############################################################################## 320# bluetooth_stop() 321############################################################################## 322 323bluetooth_stop() 324{ 325 dev=$1 326 327 # Try to figure out device type by looking at device name 328 case "${dev}" in 329 # sioX - serial/UART Bluetooth device 330 sio*) 331 if [ -f "/var/run/hcseriald.${dev}.pid" ]; then 332 kill `cat /var/run/hcseriald.${dev}.pid` 333 sleep 1 # wait a little bit 334 fi 335 ;; 336 337 # 3Com Bluetooth Adapter 3CRWB60-A 338 btccc*) 339 ;; 340 341 # USB Bluetooth adapters 342 ubt*) 343 ;; 344 345 # Unknown 346 *) 347 err 1 "Unsupported device: ${dev}" 348 ;; 349 esac 350 351 bluetooth_shutdown_stack ${dev} 352 353 return 0 354} 355 356############################################################################## 357# Start here 358############################################################################## 359 360load_rc_config $name 361hccontrol="${bluetooth_hccontrol:-/usr/sbin/hccontrol}" 362hcseriald="${bluetooth_hcseriald:-/usr/sbin/hcseriald}" 363 364run_rc_command $* 365 366