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