bluetooth revision 152286
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 152286 2005-11-10 19:09:22Z emax $ 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" 39 40############################################################################## 41# Read and parse Bluetooth device configuration file 42############################################################################## 43 44bluetooth_read_conf() 45{ 46 _file=$1 47 _namespace=$2 48 _err=0 49 50 if [ ! -e $_file ]; then 51 return 0 52 fi 53 54 if [ ! -f $_file -o ! -r $_file ]; then 55 err 1 "Bluetooth configuration file $_file is not a file or not readable" 56 fi 57 58 while read _line 59 do 60 case "$_line" in 61 \#*) 62 continue 63 ;; 64 65 *) 66 if [ -z "$_line" ]; then 67 continue; 68 fi 69 70 71 if expr "$_line" : "[a-zA-Z0-9_]*=" > /dev/null 2>&1; then 72 eval "${_namespace}${_line}" 73 else 74 warn "Unable to parse line \"$_line\" in $_file" 75 _err=1 76 fi 77 ;; 78 esac 79 done < $_file 80 81 return $_err 82} 83 84############################################################################## 85# Setup Bluetooth stack. Create and connect nodes 86############################################################################## 87 88bluetooth_setup_stack() 89{ 90 dev=$1 91 shift 92 hook=$1 93 shift 94 95 # Setup HCI 96 ngctl mkpeer ${dev}: hci ${hook} drv \ 97 > /dev/null 2>&1 || return 1 98 99 ngctl name ${dev}:${hook} ${dev}hci \ 100 > /dev/null 2>&1 || return 1 101 102 ngctl msg ${dev}hci: set_debug ${bluetooth_device_hci_debug_level} \ 103 > /dev/null 2>&1 || return 1 104 105 # Setup L2CAP 106 ngctl mkpeer ${dev}hci: l2cap acl hci \ 107 > /dev/null 2>&1 || return 1 108 109 ngctl name ${dev}hci:acl ${dev}l2cap \ 110 > /dev/null 2>&1 || return 1 111 112 ngctl msg ${dev}l2cap: set_debug ${bluetooth_device_l2cap_debug_level} \ 113 > /dev/null 2>&1 || return 1 114 115 # Connect HCI node to the Bluetooth sockets layer 116 ngctl connect ${dev}hci: btsock_hci_raw: raw ${dev}raw \ 117 > /dev/null 2>&1 || return 1 118 119 # Connect L2CAP node to Bluetooth sockets layer 120 ngctl connect ${dev}l2cap: btsock_l2c_raw: ctl ${dev}ctl \ 121 > /dev/null 2>&1 || return 1 122 123 ngctl connect ${dev}l2cap: btsock_l2c: l2c ${dev}l2c \ 124 > /dev/null 2>&1 || return 1 125 126 # Initilalize HCI node 127 ${hccontrol} -n ${dev}hci reset \ 128 > /dev/null 2>&1 || return 1 129 130 ${hccontrol} -n ${dev}hci read_bd_addr \ 131 > /dev/null 2>&1 || return 1 132 133 ${hccontrol} -n ${dev}hci read_local_supported_features \ 134 > /dev/null 2>&1 || return 1 135 136 ${hccontrol} -n ${dev}hci read_buffer_size \ 137 > /dev/null 2>&1 || return 1 138 139 if checkyesno bluetooth_device_discoverable; then 140 if checkyesno bluetooth_device_connectable; then 141 ${hccontrol} -n ${dev}hci write_scan_enable 3 \ 142 > /dev/null 2>&1 || return 1 143 else 144 ${hccontrol} -n ${dev}hci write_scan_enable 1 \ 145 > /dev/null 2>&1 || return 1 146 fi 147 else 148 if checkyesno bluetooth_device_connectable; then 149 ${hccontrol} -n ${dev}hci write_scan_enable 2 \ 150 > /dev/null 2>&1 || return 1 151 else 152 ${hccontrol} -n ${dev}hci write_scan_enable 0 \ 153 > /dev/null 2>&1 || return 1 154 fi 155 fi 156 157 158 ${hccontrol} -n ${dev}hci write_class_of_device ${bluetooth_device_class} \ 159 > /dev/null 2>&1 || return 1 160 161 if checkyesno bluetooth_device_authentication_enable; then 162 ${hccontrol} -n ${dev}hci write_authentication_enable 1 \ 163 > /dev/null 2>&1 || return 1 164 else 165 ${hccontrol} -n ${dev}hci write_authentication_enable 0 \ 166 > /dev/null 2>&1 || return 1 167 fi 168 169 case "${bluetooth_device_encryption_mode}" in 170 [Nn][Oo][Nn][Ee]|0) 171 ${hccontrol} -n ${dev}hci write_encryption_mode 0 \ 172 > /dev/null 2>&1 || return 1 173 ;; 174 175 [Pp][2][Pp]|1) 176 ${hccontrol} -n ${dev}hci write_encryption_mode 1 \ 177 > /dev/null 2>&1 || return 1 178 ;; 179 180 [Al][Ll][Ll]|2) 181 ${hccontrol} -n ${dev}hci write_encryption_mode 2 \ 182 > /dev/null 2>&1 || return 1 183 ;; 184 185 *) 186 warn "Unsupported encryption mode ${bluetooth_device_encryption_mode} for device ${dev}" 187 return 1 188 ;; 189 esac 190 191 if checkyesno bluetooth_device_role_switch; then 192 ${hccontrol} -n ${dev}hci write_node_role_switch 1 \ 193 > /dev/null 2>&1 || return 1 194 else 195 ${hccontrol} -n ${dev}hci write_node_role_switch 0 \ 196 > /dev/null 2>&1 || return 1 197 fi 198 199 ${hccontrol} -n ${dev}hci change_local_name "${bluetooth_device_local_name}" \ 200 > /dev/null 2>&1 || return 1 201 202 ${hccontrol} -n ${dev}hci initialize \ 203 > /dev/null 2>&1 || return 1 204 205 return 0 206} 207 208############################################################################## 209# Shutdown Bluetooth stack. Destroy all nodes 210############################################################################## 211 212bluetooth_shutdown_stack() 213{ 214 dev=$1 215 216 ngctl shutdown ${dev}hci: > /dev/null 2>&1 217 ngctl shutdown ${dev}l2cap: > /dev/null 2>&1 218 219 return 0 220} 221 222############################################################################## 223# bluetooth_start() 224############################################################################## 225 226bluetooth_start() 227{ 228 dev=$1 229 230 # Automatically load modules 231 kldload ng_bluetooth > /dev/null 2>&1 232 kldload ng_hci > /dev/null 2>&1 233 kldload ng_l2cap > /dev/null 2>&1 234 kldload ng_btsocket > /dev/null 2>&1 235 236 # Try to figure out device type by looking at device name 237 case "${dev}" in 238 # sioX - serial/UART Bluetooth device 239 sio*) 240 kldload ng_h4 > /dev/null 2>&1 241 242 hook="hook" 243 244 # Obtain unit number from device. 245 unit=`expr ${dev} : 'sio\([0-9]\{1,\}\)'` 246 if [ -z "${unit}" ]; then 247 err 1 "Unable to get sio unit number: ${dev}" 248 fi 249 250 ${hcseriald} -f /dev/cuad${unit} -n ${dev} 251 sleep 1 # wait a little bit 252 253 if [ ! -f "/var/run/hcseriald.${dev}.pid" ]; then 254 err 1 "Unable to start hcseriald on ${dev}" 255 fi 256 ;; 257 258 # 3Com Bluetooth Adapter 3CRWB60-A 259 btccc*) 260 hook="hook" 261 262 # Obtain unit number from device. 263 unit=`expr ${dev} : 'btccc\([0-9]\{1,\}\)'` 264 if [ -z "${unit}" ]; then 265 err 1 "Unable to get bt3c unit number: ${dev}" 266 fi 267 ;; 268 269 # USB Bluetooth adapters 270 ubt*) 271 hook="hook" 272 273 # Obtain unit number from device. 274 unit=`expr ${dev} : 'ubt\([0-9]\{1,\}\)'` 275 if [ -z "${unit}" ]; then 276 err 1 "Unable to get ubt unit number: ${dev}" 277 fi 278 ;; 279 280 # Unknown 281 *) 282 err 1 "Unsupported device: ${dev}" 283 ;; 284 esac 285 286 # Be backward compatible and setup reasonable defaults 287 bluetooth_device_authentication_enable="0" 288 bluetooth_device_class="ff:01:0c" 289 bluetooth_device_connectable="1" 290 bluetooth_device_discoverable="1" 291 bluetooth_device_encryption_mode="0" 292 bluetooth_device_hci_debug_level="3" 293 bluetooth_device_l2cap_debug_level="3" 294 bluetooth_device_local_name="`/usr/bin/uname -n` (${dev})" 295 bluetooth_device_role_switch="1" 296 297 # Load default device configuration parameters 298 _file="/etc/defaults/bluetooth.device.conf" 299 300 if ! bluetooth_read_conf $_file bluetooth_device_ ; then 301 err 1 "Unable to read default Bluetooth configuration from $_file" 302 fi 303 304 # Load device specific overrides 305 _file="/etc/bluetooth/$dev.conf" 306 307 if ! bluetooth_read_conf $_file bluetooth_device_ ; then 308 err 1 "Unable to read Bluetooth device configuration from $_file" 309 fi 310 311 # Setup stack 312 if ! bluetooth_setup_stack ${dev} ${hook} ; then 313 bluetooth_shutdown_stack $dev 314 err 1 "Unable to setup Bluetooth stack for device ${dev}" 315 fi 316 317 return 0 318} 319 320############################################################################## 321# bluetooth_stop() 322############################################################################## 323 324bluetooth_stop() 325{ 326 dev=$1 327 328 # Try to figure out device type by looking at device name 329 case "${dev}" in 330 # sioX - serial/UART Bluetooth device 331 sio*) 332 if [ -f "/var/run/hcseriald.${dev}.pid" ]; then 333 kill `cat /var/run/hcseriald.${dev}.pid` 334 sleep 1 # wait a little bit 335 fi 336 ;; 337 338 # 3Com Bluetooth Adapter 3CRWB60-A 339 btccc*) 340 ;; 341 342 # USB Bluetooth adapters 343 ubt*) 344 ;; 345 346 # Unknown 347 *) 348 err 1 "Unsupported device: ${dev}" 349 ;; 350 esac 351 352 bluetooth_shutdown_stack ${dev} 353 354 return 0 355} 356 357############################################################################## 358# Start here 359############################################################################## 360 361load_rc_config $name 362hccontrol="${bluetooth_hccontrol:-/usr/sbin/hccontrol}" 363hcseriald="${bluetooth_hcseriald:-/usr/sbin/hcseriald}" 364 365run_rc_command $* 366 367