bluetooth revision 152286
1152286Semax#!/bin/sh 2152286Semax# 3152286Semax# Copyright (c) 2005 Maksim Yevmenkin <m_evmenkin@yahoo.com> 4152286Semax# All rights reserved. 5152286Semax# 6152286Semax# Redistribution and use in source and binary forms, with or without 7152286Semax# modification, are permitted provided that the following conditions 8152286Semax# are met: 9152286Semax# 1. Redistributions of source code must retain the above copyright 10152286Semax# notice, this list of conditions and the following disclaimer. 11152286Semax# 2. Redistributions in binary form must reproduce the above copyright 12152286Semax# notice, this list of conditions and the following disclaimer in the 13152286Semax# documentation and/or other materials provided with the distribution. 14152286Semax# 15152286Semax# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16152286Semax# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17152286Semax# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18152286Semax# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19152286Semax# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20152286Semax# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21152286Semax# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22152286Semax# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23152286Semax# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24152286Semax# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25152286Semax# SUCH DAMAGE. 26152286Semax# 27152286Semax# $FreeBSD: head/etc/rc.d/bluetooth 152286 2005-11-10 19:09:22Z emax $ 28152286Semax 29152286Semax# PROVIDE: bluetooth 30152286Semax# REQUIRE: DAEMON 31152286Semax# KEYWORD: nojail nostart 32152286Semax 33152286Semax. /etc/rc.subr 34152286Semax 35152286Semaxname="bluetooth" 36152286Semaxrcvar= 37152286Semaxstart_cmd="bluetooth_start" 38152286Semaxstop_cmd="bluetooth_stop" 39152286Semax 40152286Semax############################################################################## 41152286Semax# Read and parse Bluetooth device configuration file 42152286Semax############################################################################## 43152286Semax 44152286Semaxbluetooth_read_conf() 45152286Semax{ 46152286Semax _file=$1 47152286Semax _namespace=$2 48152286Semax _err=0 49152286Semax 50152286Semax if [ ! -e $_file ]; then 51152286Semax return 0 52152286Semax fi 53152286Semax 54152286Semax if [ ! -f $_file -o ! -r $_file ]; then 55152286Semax err 1 "Bluetooth configuration file $_file is not a file or not readable" 56152286Semax fi 57152286Semax 58152286Semax while read _line 59152286Semax do 60152286Semax case "$_line" in 61152286Semax \#*) 62152286Semax continue 63152286Semax ;; 64152286Semax 65152286Semax *) 66152286Semax if [ -z "$_line" ]; then 67152286Semax continue; 68152286Semax fi 69152286Semax 70152286Semax 71152286Semax if expr "$_line" : "[a-zA-Z0-9_]*=" > /dev/null 2>&1; then 72152286Semax eval "${_namespace}${_line}" 73152286Semax else 74152286Semax warn "Unable to parse line \"$_line\" in $_file" 75152286Semax _err=1 76152286Semax fi 77152286Semax ;; 78152286Semax esac 79152286Semax done < $_file 80152286Semax 81152286Semax return $_err 82152286Semax} 83152286Semax 84152286Semax############################################################################## 85152286Semax# Setup Bluetooth stack. Create and connect nodes 86152286Semax############################################################################## 87152286Semax 88152286Semaxbluetooth_setup_stack() 89152286Semax{ 90152286Semax dev=$1 91152286Semax shift 92152286Semax hook=$1 93152286Semax shift 94152286Semax 95152286Semax # Setup HCI 96152286Semax ngctl mkpeer ${dev}: hci ${hook} drv \ 97152286Semax > /dev/null 2>&1 || return 1 98152286Semax 99152286Semax ngctl name ${dev}:${hook} ${dev}hci \ 100152286Semax > /dev/null 2>&1 || return 1 101152286Semax 102152286Semax ngctl msg ${dev}hci: set_debug ${bluetooth_device_hci_debug_level} \ 103152286Semax > /dev/null 2>&1 || return 1 104152286Semax 105152286Semax # Setup L2CAP 106152286Semax ngctl mkpeer ${dev}hci: l2cap acl hci \ 107152286Semax > /dev/null 2>&1 || return 1 108152286Semax 109152286Semax ngctl name ${dev}hci:acl ${dev}l2cap \ 110152286Semax > /dev/null 2>&1 || return 1 111152286Semax 112152286Semax ngctl msg ${dev}l2cap: set_debug ${bluetooth_device_l2cap_debug_level} \ 113152286Semax > /dev/null 2>&1 || return 1 114152286Semax 115152286Semax # Connect HCI node to the Bluetooth sockets layer 116152286Semax ngctl connect ${dev}hci: btsock_hci_raw: raw ${dev}raw \ 117152286Semax > /dev/null 2>&1 || return 1 118152286Semax 119152286Semax # Connect L2CAP node to Bluetooth sockets layer 120152286Semax ngctl connect ${dev}l2cap: btsock_l2c_raw: ctl ${dev}ctl \ 121152286Semax > /dev/null 2>&1 || return 1 122152286Semax 123152286Semax ngctl connect ${dev}l2cap: btsock_l2c: l2c ${dev}l2c \ 124152286Semax > /dev/null 2>&1 || return 1 125152286Semax 126152286Semax # Initilalize HCI node 127152286Semax ${hccontrol} -n ${dev}hci reset \ 128152286Semax > /dev/null 2>&1 || return 1 129152286Semax 130152286Semax ${hccontrol} -n ${dev}hci read_bd_addr \ 131152286Semax > /dev/null 2>&1 || return 1 132152286Semax 133152286Semax ${hccontrol} -n ${dev}hci read_local_supported_features \ 134152286Semax > /dev/null 2>&1 || return 1 135152286Semax 136152286Semax ${hccontrol} -n ${dev}hci read_buffer_size \ 137152286Semax > /dev/null 2>&1 || return 1 138152286Semax 139152286Semax if checkyesno bluetooth_device_discoverable; then 140152286Semax if checkyesno bluetooth_device_connectable; then 141152286Semax ${hccontrol} -n ${dev}hci write_scan_enable 3 \ 142152286Semax > /dev/null 2>&1 || return 1 143152286Semax else 144152286Semax ${hccontrol} -n ${dev}hci write_scan_enable 1 \ 145152286Semax > /dev/null 2>&1 || return 1 146152286Semax fi 147152286Semax else 148152286Semax if checkyesno bluetooth_device_connectable; then 149152286Semax ${hccontrol} -n ${dev}hci write_scan_enable 2 \ 150152286Semax > /dev/null 2>&1 || return 1 151152286Semax else 152152286Semax ${hccontrol} -n ${dev}hci write_scan_enable 0 \ 153152286Semax > /dev/null 2>&1 || return 1 154152286Semax fi 155152286Semax fi 156152286Semax 157152286Semax 158152286Semax ${hccontrol} -n ${dev}hci write_class_of_device ${bluetooth_device_class} \ 159152286Semax > /dev/null 2>&1 || return 1 160152286Semax 161152286Semax if checkyesno bluetooth_device_authentication_enable; then 162152286Semax ${hccontrol} -n ${dev}hci write_authentication_enable 1 \ 163152286Semax > /dev/null 2>&1 || return 1 164152286Semax else 165152286Semax ${hccontrol} -n ${dev}hci write_authentication_enable 0 \ 166152286Semax > /dev/null 2>&1 || return 1 167152286Semax fi 168152286Semax 169152286Semax case "${bluetooth_device_encryption_mode}" in 170152286Semax [Nn][Oo][Nn][Ee]|0) 171152286Semax ${hccontrol} -n ${dev}hci write_encryption_mode 0 \ 172152286Semax > /dev/null 2>&1 || return 1 173152286Semax ;; 174152286Semax 175152286Semax [Pp][2][Pp]|1) 176152286Semax ${hccontrol} -n ${dev}hci write_encryption_mode 1 \ 177152286Semax > /dev/null 2>&1 || return 1 178152286Semax ;; 179152286Semax 180152286Semax [Al][Ll][Ll]|2) 181152286Semax ${hccontrol} -n ${dev}hci write_encryption_mode 2 \ 182152286Semax > /dev/null 2>&1 || return 1 183152286Semax ;; 184152286Semax 185152286Semax *) 186152286Semax warn "Unsupported encryption mode ${bluetooth_device_encryption_mode} for device ${dev}" 187152286Semax return 1 188152286Semax ;; 189152286Semax esac 190152286Semax 191152286Semax if checkyesno bluetooth_device_role_switch; then 192152286Semax ${hccontrol} -n ${dev}hci write_node_role_switch 1 \ 193152286Semax > /dev/null 2>&1 || return 1 194152286Semax else 195152286Semax ${hccontrol} -n ${dev}hci write_node_role_switch 0 \ 196152286Semax > /dev/null 2>&1 || return 1 197152286Semax fi 198152286Semax 199152286Semax ${hccontrol} -n ${dev}hci change_local_name "${bluetooth_device_local_name}" \ 200152286Semax > /dev/null 2>&1 || return 1 201152286Semax 202152286Semax ${hccontrol} -n ${dev}hci initialize \ 203152286Semax > /dev/null 2>&1 || return 1 204152286Semax 205152286Semax return 0 206152286Semax} 207152286Semax 208152286Semax############################################################################## 209152286Semax# Shutdown Bluetooth stack. Destroy all nodes 210152286Semax############################################################################## 211152286Semax 212152286Semaxbluetooth_shutdown_stack() 213152286Semax{ 214152286Semax dev=$1 215152286Semax 216152286Semax ngctl shutdown ${dev}hci: > /dev/null 2>&1 217152286Semax ngctl shutdown ${dev}l2cap: > /dev/null 2>&1 218152286Semax 219152286Semax return 0 220152286Semax} 221152286Semax 222152286Semax############################################################################## 223152286Semax# bluetooth_start() 224152286Semax############################################################################## 225152286Semax 226152286Semaxbluetooth_start() 227152286Semax{ 228152286Semax dev=$1 229152286Semax 230152286Semax # Automatically load modules 231152286Semax kldload ng_bluetooth > /dev/null 2>&1 232152286Semax kldload ng_hci > /dev/null 2>&1 233152286Semax kldload ng_l2cap > /dev/null 2>&1 234152286Semax kldload ng_btsocket > /dev/null 2>&1 235152286Semax 236152286Semax # Try to figure out device type by looking at device name 237152286Semax case "${dev}" in 238152286Semax # sioX - serial/UART Bluetooth device 239152286Semax sio*) 240152286Semax kldload ng_h4 > /dev/null 2>&1 241152286Semax 242152286Semax hook="hook" 243152286Semax 244152286Semax # Obtain unit number from device. 245152286Semax unit=`expr ${dev} : 'sio\([0-9]\{1,\}\)'` 246152286Semax if [ -z "${unit}" ]; then 247152286Semax err 1 "Unable to get sio unit number: ${dev}" 248152286Semax fi 249152286Semax 250152286Semax ${hcseriald} -f /dev/cuad${unit} -n ${dev} 251152286Semax sleep 1 # wait a little bit 252152286Semax 253152286Semax if [ ! -f "/var/run/hcseriald.${dev}.pid" ]; then 254152286Semax err 1 "Unable to start hcseriald on ${dev}" 255152286Semax fi 256152286Semax ;; 257152286Semax 258152286Semax # 3Com Bluetooth Adapter 3CRWB60-A 259152286Semax btccc*) 260152286Semax hook="hook" 261152286Semax 262152286Semax # Obtain unit number from device. 263152286Semax unit=`expr ${dev} : 'btccc\([0-9]\{1,\}\)'` 264152286Semax if [ -z "${unit}" ]; then 265152286Semax err 1 "Unable to get bt3c unit number: ${dev}" 266152286Semax fi 267152286Semax ;; 268152286Semax 269152286Semax # USB Bluetooth adapters 270152286Semax ubt*) 271152286Semax hook="hook" 272152286Semax 273152286Semax # Obtain unit number from device. 274152286Semax unit=`expr ${dev} : 'ubt\([0-9]\{1,\}\)'` 275152286Semax if [ -z "${unit}" ]; then 276152286Semax err 1 "Unable to get ubt unit number: ${dev}" 277152286Semax fi 278152286Semax ;; 279152286Semax 280152286Semax # Unknown 281152286Semax *) 282152286Semax err 1 "Unsupported device: ${dev}" 283152286Semax ;; 284152286Semax esac 285152286Semax 286152286Semax # Be backward compatible and setup reasonable defaults 287152286Semax bluetooth_device_authentication_enable="0" 288152286Semax bluetooth_device_class="ff:01:0c" 289152286Semax bluetooth_device_connectable="1" 290152286Semax bluetooth_device_discoverable="1" 291152286Semax bluetooth_device_encryption_mode="0" 292152286Semax bluetooth_device_hci_debug_level="3" 293152286Semax bluetooth_device_l2cap_debug_level="3" 294152286Semax bluetooth_device_local_name="`/usr/bin/uname -n` (${dev})" 295152286Semax bluetooth_device_role_switch="1" 296152286Semax 297152286Semax # Load default device configuration parameters 298152286Semax _file="/etc/defaults/bluetooth.device.conf" 299152286Semax 300152286Semax if ! bluetooth_read_conf $_file bluetooth_device_ ; then 301152286Semax err 1 "Unable to read default Bluetooth configuration from $_file" 302152286Semax fi 303152286Semax 304152286Semax # Load device specific overrides 305152286Semax _file="/etc/bluetooth/$dev.conf" 306152286Semax 307152286Semax if ! bluetooth_read_conf $_file bluetooth_device_ ; then 308152286Semax err 1 "Unable to read Bluetooth device configuration from $_file" 309152286Semax fi 310152286Semax 311152286Semax # Setup stack 312152286Semax if ! bluetooth_setup_stack ${dev} ${hook} ; then 313152286Semax bluetooth_shutdown_stack $dev 314152286Semax err 1 "Unable to setup Bluetooth stack for device ${dev}" 315152286Semax fi 316152286Semax 317152286Semax return 0 318152286Semax} 319152286Semax 320152286Semax############################################################################## 321152286Semax# bluetooth_stop() 322152286Semax############################################################################## 323152286Semax 324152286Semaxbluetooth_stop() 325152286Semax{ 326152286Semax dev=$1 327152286Semax 328152286Semax # Try to figure out device type by looking at device name 329152286Semax case "${dev}" in 330152286Semax # sioX - serial/UART Bluetooth device 331152286Semax sio*) 332152286Semax if [ -f "/var/run/hcseriald.${dev}.pid" ]; then 333152286Semax kill `cat /var/run/hcseriald.${dev}.pid` 334152286Semax sleep 1 # wait a little bit 335152286Semax fi 336152286Semax ;; 337152286Semax 338152286Semax # 3Com Bluetooth Adapter 3CRWB60-A 339152286Semax btccc*) 340152286Semax ;; 341152286Semax 342152286Semax # USB Bluetooth adapters 343152286Semax ubt*) 344152286Semax ;; 345152286Semax 346152286Semax # Unknown 347152286Semax *) 348152286Semax err 1 "Unsupported device: ${dev}" 349152286Semax ;; 350152286Semax esac 351152286Semax 352152286Semax bluetooth_shutdown_stack ${dev} 353152286Semax 354152286Semax return 0 355152286Semax} 356152286Semax 357152286Semax############################################################################## 358152286Semax# Start here 359152286Semax############################################################################## 360152286Semax 361152286Semaxload_rc_config $name 362152286Semaxhccontrol="${bluetooth_hccontrol:-/usr/sbin/hccontrol}" 363152286Semaxhcseriald="${bluetooth_hcseriald:-/usr/sbin/hcseriald}" 364152286Semax 365152286Semaxrun_rc_command $* 366152286Semax 367