bluetooth revision 180618
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 180618 2008-07-19 20:11:33Z marcel $ 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" 39165683Syarrequired_modules="ng_bluetooth ng_hci ng_l2cap ng_btsocket" 40152286Semax 41152286Semax############################################################################## 42152286Semax# Read and parse Bluetooth device configuration file 43152286Semax############################################################################## 44152286Semax 45152286Semaxbluetooth_read_conf() 46152286Semax{ 47165664Syar local _err _file _line _namespace 48165664Syar 49152286Semax _file=$1 50152286Semax _namespace=$2 51152286Semax _err=0 52152286Semax 53152286Semax if [ ! -e $_file ]; then 54152286Semax return 0 55152286Semax fi 56152286Semax 57152286Semax if [ ! -f $_file -o ! -r $_file ]; then 58152286Semax err 1 "Bluetooth configuration file $_file is not a file or not readable" 59152286Semax fi 60152286Semax 61152286Semax while read _line 62152286Semax do 63152286Semax case "$_line" in 64152286Semax \#*) 65152286Semax continue 66152286Semax ;; 67152286Semax 68152286Semax *) 69152286Semax if [ -z "$_line" ]; then 70152286Semax continue; 71152286Semax fi 72152286Semax 73152286Semax 74152286Semax if expr "$_line" : "[a-zA-Z0-9_]*=" > /dev/null 2>&1; then 75152286Semax eval "${_namespace}${_line}" 76152286Semax else 77152286Semax warn "Unable to parse line \"$_line\" in $_file" 78152286Semax _err=1 79152286Semax fi 80152286Semax ;; 81152286Semax esac 82152286Semax done < $_file 83152286Semax 84152286Semax return $_err 85152286Semax} 86152286Semax 87152286Semax############################################################################## 88152286Semax# Setup Bluetooth stack. Create and connect nodes 89152286Semax############################################################################## 90152286Semax 91152286Semaxbluetooth_setup_stack() 92152286Semax{ 93152286Semax dev=$1 94152286Semax shift 95152286Semax hook=$1 96152286Semax shift 97152286Semax 98152286Semax # Setup HCI 99152286Semax ngctl mkpeer ${dev}: hci ${hook} drv \ 100152286Semax > /dev/null 2>&1 || return 1 101152286Semax 102152286Semax ngctl name ${dev}:${hook} ${dev}hci \ 103152286Semax > /dev/null 2>&1 || return 1 104152286Semax 105152286Semax ngctl msg ${dev}hci: set_debug ${bluetooth_device_hci_debug_level} \ 106152286Semax > /dev/null 2>&1 || return 1 107152286Semax 108152286Semax # Setup L2CAP 109152286Semax ngctl mkpeer ${dev}hci: l2cap acl hci \ 110152286Semax > /dev/null 2>&1 || return 1 111152286Semax 112152286Semax ngctl name ${dev}hci:acl ${dev}l2cap \ 113152286Semax > /dev/null 2>&1 || return 1 114152286Semax 115152286Semax ngctl msg ${dev}l2cap: set_debug ${bluetooth_device_l2cap_debug_level} \ 116152286Semax > /dev/null 2>&1 || return 1 117152286Semax 118152286Semax # Connect HCI node to the Bluetooth sockets layer 119152286Semax ngctl connect ${dev}hci: btsock_hci_raw: raw ${dev}raw \ 120152286Semax > /dev/null 2>&1 || return 1 121152286Semax 122152286Semax # Connect L2CAP node to Bluetooth sockets layer 123152286Semax ngctl connect ${dev}l2cap: btsock_l2c_raw: ctl ${dev}ctl \ 124152286Semax > /dev/null 2>&1 || return 1 125152286Semax 126152286Semax ngctl connect ${dev}l2cap: btsock_l2c: l2c ${dev}l2c \ 127152286Semax > /dev/null 2>&1 || return 1 128152286Semax 129152286Semax # Initilalize HCI node 130152286Semax ${hccontrol} -n ${dev}hci reset \ 131152286Semax > /dev/null 2>&1 || return 1 132152286Semax 133152286Semax ${hccontrol} -n ${dev}hci read_bd_addr \ 134152286Semax > /dev/null 2>&1 || return 1 135152286Semax 136152286Semax ${hccontrol} -n ${dev}hci read_local_supported_features \ 137152286Semax > /dev/null 2>&1 || return 1 138152286Semax 139152286Semax ${hccontrol} -n ${dev}hci read_buffer_size \ 140152286Semax > /dev/null 2>&1 || return 1 141152286Semax 142152286Semax if checkyesno bluetooth_device_discoverable; then 143152286Semax if checkyesno bluetooth_device_connectable; then 144152286Semax ${hccontrol} -n ${dev}hci write_scan_enable 3 \ 145152286Semax > /dev/null 2>&1 || return 1 146152286Semax else 147152286Semax ${hccontrol} -n ${dev}hci write_scan_enable 1 \ 148152286Semax > /dev/null 2>&1 || return 1 149152286Semax fi 150152286Semax else 151152286Semax if checkyesno bluetooth_device_connectable; then 152152286Semax ${hccontrol} -n ${dev}hci write_scan_enable 2 \ 153152286Semax > /dev/null 2>&1 || return 1 154152286Semax else 155152286Semax ${hccontrol} -n ${dev}hci write_scan_enable 0 \ 156152286Semax > /dev/null 2>&1 || return 1 157152286Semax fi 158152286Semax fi 159152286Semax 160152286Semax 161152286Semax ${hccontrol} -n ${dev}hci write_class_of_device ${bluetooth_device_class} \ 162152286Semax > /dev/null 2>&1 || return 1 163152286Semax 164152286Semax if checkyesno bluetooth_device_authentication_enable; then 165152286Semax ${hccontrol} -n ${dev}hci write_authentication_enable 1 \ 166152286Semax > /dev/null 2>&1 || return 1 167152286Semax else 168152286Semax ${hccontrol} -n ${dev}hci write_authentication_enable 0 \ 169152286Semax > /dev/null 2>&1 || return 1 170152286Semax fi 171152286Semax 172152286Semax case "${bluetooth_device_encryption_mode}" in 173152286Semax [Nn][Oo][Nn][Ee]|0) 174152286Semax ${hccontrol} -n ${dev}hci write_encryption_mode 0 \ 175152286Semax > /dev/null 2>&1 || return 1 176152286Semax ;; 177152286Semax 178152286Semax [Pp][2][Pp]|1) 179152286Semax ${hccontrol} -n ${dev}hci write_encryption_mode 1 \ 180152286Semax > /dev/null 2>&1 || return 1 181152286Semax ;; 182152286Semax 183152286Semax [Al][Ll][Ll]|2) 184152286Semax ${hccontrol} -n ${dev}hci write_encryption_mode 2 \ 185152286Semax > /dev/null 2>&1 || return 1 186152286Semax ;; 187152286Semax 188152286Semax *) 189152286Semax warn "Unsupported encryption mode ${bluetooth_device_encryption_mode} for device ${dev}" 190152286Semax return 1 191152286Semax ;; 192152286Semax esac 193152286Semax 194152286Semax if checkyesno bluetooth_device_role_switch; then 195152286Semax ${hccontrol} -n ${dev}hci write_node_role_switch 1 \ 196152286Semax > /dev/null 2>&1 || return 1 197152286Semax else 198152286Semax ${hccontrol} -n ${dev}hci write_node_role_switch 0 \ 199152286Semax > /dev/null 2>&1 || return 1 200152286Semax fi 201152286Semax 202152286Semax ${hccontrol} -n ${dev}hci change_local_name "${bluetooth_device_local_name}" \ 203152286Semax > /dev/null 2>&1 || return 1 204152286Semax 205152286Semax ${hccontrol} -n ${dev}hci initialize \ 206152286Semax > /dev/null 2>&1 || return 1 207152286Semax 208152286Semax return 0 209152286Semax} 210152286Semax 211152286Semax############################################################################## 212152286Semax# Shutdown Bluetooth stack. Destroy all nodes 213152286Semax############################################################################## 214152286Semax 215152286Semaxbluetooth_shutdown_stack() 216152286Semax{ 217152286Semax dev=$1 218152286Semax 219152286Semax ngctl shutdown ${dev}hci: > /dev/null 2>&1 220152286Semax ngctl shutdown ${dev}l2cap: > /dev/null 2>&1 221152286Semax 222152286Semax return 0 223152286Semax} 224152286Semax 225152286Semax############################################################################## 226152286Semax# bluetooth_start() 227152286Semax############################################################################## 228152286Semax 229152286Semaxbluetooth_start() 230152286Semax{ 231165664Syar local _file 232165664Syar 233152286Semax dev=$1 234152286Semax 235152286Semax # Try to figure out device type by looking at device name 236152286Semax case "${dev}" in 237180618Smarcel # uartX - serial/UART Bluetooth device 238180618Smarcel uart*) 239165683Syar load_kld ng_h4 || return 1 240152286Semax 241152286Semax hook="hook" 242152286Semax 243152286Semax # Obtain unit number from device. 244180618Smarcel unit=`expr ${dev} : 'uart\([0-9]\{1,\}\)'` 245152286Semax if [ -z "${unit}" ]; then 246180618Smarcel err 1 "Unable to get uart unit number: ${dev}" 247152286Semax fi 248152286Semax 249180618Smarcel ${hcseriald} -f /dev/cuau${unit} -n ${dev} 250152286Semax sleep 1 # wait a little bit 251152286Semax 252152286Semax if [ ! -f "/var/run/hcseriald.${dev}.pid" ]; then 253152286Semax err 1 "Unable to start hcseriald on ${dev}" 254152286Semax fi 255152286Semax ;; 256152286Semax 257152286Semax # 3Com Bluetooth Adapter 3CRWB60-A 258152286Semax btccc*) 259152286Semax hook="hook" 260152286Semax 261152286Semax # Obtain unit number from device. 262152286Semax unit=`expr ${dev} : 'btccc\([0-9]\{1,\}\)'` 263152286Semax if [ -z "${unit}" ]; then 264152286Semax err 1 "Unable to get bt3c unit number: ${dev}" 265152286Semax fi 266152286Semax ;; 267152286Semax 268152286Semax # USB Bluetooth adapters 269152286Semax ubt*) 270152286Semax hook="hook" 271152286Semax 272152286Semax # Obtain unit number from device. 273152286Semax unit=`expr ${dev} : 'ubt\([0-9]\{1,\}\)'` 274152286Semax if [ -z "${unit}" ]; then 275152286Semax err 1 "Unable to get ubt unit number: ${dev}" 276152286Semax fi 277152286Semax ;; 278152286Semax 279152286Semax # Unknown 280152286Semax *) 281152286Semax err 1 "Unsupported device: ${dev}" 282152286Semax ;; 283152286Semax esac 284152286Semax 285152286Semax # Be backward compatible and setup reasonable defaults 286152286Semax bluetooth_device_authentication_enable="0" 287152286Semax bluetooth_device_class="ff:01:0c" 288152286Semax bluetooth_device_connectable="1" 289152286Semax bluetooth_device_discoverable="1" 290152286Semax bluetooth_device_encryption_mode="0" 291152286Semax bluetooth_device_hci_debug_level="3" 292152286Semax bluetooth_device_l2cap_debug_level="3" 293152286Semax bluetooth_device_local_name="`/usr/bin/uname -n` (${dev})" 294152286Semax bluetooth_device_role_switch="1" 295152286Semax 296152286Semax # Load default device configuration parameters 297152286Semax _file="/etc/defaults/bluetooth.device.conf" 298152286Semax 299152286Semax if ! bluetooth_read_conf $_file bluetooth_device_ ; then 300152286Semax err 1 "Unable to read default Bluetooth configuration from $_file" 301152286Semax fi 302152286Semax 303152286Semax # Load device specific overrides 304152286Semax _file="/etc/bluetooth/$dev.conf" 305152286Semax 306152286Semax if ! bluetooth_read_conf $_file bluetooth_device_ ; then 307152286Semax err 1 "Unable to read Bluetooth device configuration from $_file" 308152286Semax fi 309152286Semax 310152286Semax # Setup stack 311152286Semax if ! bluetooth_setup_stack ${dev} ${hook} ; then 312152286Semax bluetooth_shutdown_stack $dev 313152286Semax err 1 "Unable to setup Bluetooth stack for device ${dev}" 314152286Semax fi 315152286Semax 316152286Semax return 0 317152286Semax} 318152286Semax 319152286Semax############################################################################## 320152286Semax# bluetooth_stop() 321152286Semax############################################################################## 322152286Semax 323152286Semaxbluetooth_stop() 324152286Semax{ 325152286Semax dev=$1 326152286Semax 327152286Semax # Try to figure out device type by looking at device name 328152286Semax case "${dev}" in 329180618Smarcel # uartX - serial/UART Bluetooth device 330180618Smarcel uart*) 331152286Semax if [ -f "/var/run/hcseriald.${dev}.pid" ]; then 332152286Semax kill `cat /var/run/hcseriald.${dev}.pid` 333152286Semax sleep 1 # wait a little bit 334152286Semax fi 335152286Semax ;; 336152286Semax 337152286Semax # 3Com Bluetooth Adapter 3CRWB60-A 338152286Semax btccc*) 339152286Semax ;; 340152286Semax 341152286Semax # USB Bluetooth adapters 342152286Semax ubt*) 343152286Semax ;; 344152286Semax 345152286Semax # Unknown 346152286Semax *) 347152286Semax err 1 "Unsupported device: ${dev}" 348152286Semax ;; 349152286Semax esac 350152286Semax 351152286Semax bluetooth_shutdown_stack ${dev} 352152286Semax 353152286Semax return 0 354152286Semax} 355152286Semax 356152286Semax############################################################################## 357152286Semax# Start here 358152286Semax############################################################################## 359152286Semax 360152286Semaxload_rc_config $name 361152286Semaxhccontrol="${bluetooth_hccontrol:-/usr/sbin/hccontrol}" 362152286Semaxhcseriald="${bluetooth_hcseriald:-/usr/sbin/hcseriald}" 363152286Semax 364152286Semaxrun_rc_command $* 365152286Semax 366