bluetooth revision 180618
1101704Smjacob#!/bin/sh 2101704Smjacob# 3101704Smjacob# Copyright (c) 2005 Maksim Yevmenkin <m_evmenkin@yahoo.com> 4101704Smjacob# All rights reserved. 5101704Smjacob# 6101704Smjacob# Redistribution and use in source and binary forms, with or without 7101704Smjacob# modification, are permitted provided that the following conditions 8101704Smjacob# are met: 9101704Smjacob# 1. Redistributions of source code must retain the above copyright 10101704Smjacob# notice, this list of conditions and the following disclaimer. 11101704Smjacob# 2. Redistributions in binary form must reproduce the above copyright 12101704Smjacob# notice, this list of conditions and the following disclaimer in the 13101704Smjacob# documentation and/or other materials provided with the distribution. 14101704Smjacob# 15101704Smjacob# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16101704Smjacob# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17101704Smjacob# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18101704Smjacob# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19101704Smjacob# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20101704Smjacob# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21101704Smjacob# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22101704Smjacob# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23101704Smjacob# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24101704Smjacob# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25101704Smjacob# SUCH DAMAGE. 26101704Smjacob# 27101704Smjacob# $FreeBSD: head/etc/rc.d/bluetooth 180618 2008-07-19 20:11:33Z marcel $ 28101704Smjacob 29101704Smjacob# PROVIDE: bluetooth 30101704Smjacob# REQUIRE: DAEMON 31101704Smjacob# KEYWORD: nojail nostart 32101704Smjacob 33101704Smjacob. /etc/rc.subr 34102199Smjacob 35101704Smjacobname="bluetooth" 36101704Smjacobrcvar= 37101704Smjacobstart_cmd="bluetooth_start" 38101704Smjacobstop_cmd="bluetooth_stop" 39101704Smjacobrequired_modules="ng_bluetooth ng_hci ng_l2cap ng_btsocket" 40101704Smjacob 41101704Smjacob############################################################################## 42102199Smjacob# Read and parse Bluetooth device configuration file 43102199Smjacob############################################################################## 44101704Smjacob 45101704Smjacobbluetooth_read_conf() 46102199Smjacob{ 47101704Smjacob local _err _file _line _namespace 48101704Smjacob 49101704Smjacob _file=$1 50101704Smjacob _namespace=$2 51101704Smjacob _err=0 52102199Smjacob 53101704Smjacob if [ ! -e $_file ]; then 54101704Smjacob return 0 55101704Smjacob fi 56101704Smjacob 57101704Smjacob if [ ! -f $_file -o ! -r $_file ]; then 58101704Smjacob err 1 "Bluetooth configuration file $_file is not a file or not readable" 59102199Smjacob fi 60101704Smjacob 61101704Smjacob while read _line 62101704Smjacob do 63101704Smjacob case "$_line" in 64101704Smjacob \#*) 65101704Smjacob continue 66101704Smjacob ;; 67101704Smjacob 68101704Smjacob *) 69101704Smjacob if [ -z "$_line" ]; then 70101704Smjacob continue; 71101704Smjacob fi 72101704Smjacob 73101704Smjacob 74101704Smjacob if expr "$_line" : "[a-zA-Z0-9_]*=" > /dev/null 2>&1; then 75102199Smjacob eval "${_namespace}${_line}" 76101704Smjacob else 77101704Smjacob warn "Unable to parse line \"$_line\" in $_file" 78101704Smjacob _err=1 79101704Smjacob fi 80101704Smjacob ;; 81101704Smjacob esac 82101704Smjacob done < $_file 83101704Smjacob 84101704Smjacob return $_err 85101704Smjacob} 86101704Smjacob 87101704Smjacob############################################################################## 88101704Smjacob# Setup Bluetooth stack. Create and connect nodes 89101704Smjacob############################################################################## 90102199Smjacob 91101704Smjacobbluetooth_setup_stack() 92101704Smjacob{ 93101704Smjacob dev=$1 94101704Smjacob shift 95101704Smjacob hook=$1 96101704Smjacob shift 97101704Smjacob 98101704Smjacob # Setup HCI 99101704Smjacob ngctl mkpeer ${dev}: hci ${hook} drv \ 100101704Smjacob > /dev/null 2>&1 || return 1 101102199Smjacob 102101704Smjacob ngctl name ${dev}:${hook} ${dev}hci \ 103101704Smjacob > /dev/null 2>&1 || return 1 104101704Smjacob 105101704Smjacob ngctl msg ${dev}hci: set_debug ${bluetooth_device_hci_debug_level} \ 106101704Smjacob > /dev/null 2>&1 || return 1 107101704Smjacob 108101704Smjacob # Setup L2CAP 109101704Smjacob ngctl mkpeer ${dev}hci: l2cap acl hci \ 110101704Smjacob > /dev/null 2>&1 || return 1 111101704Smjacob 112101704Smjacob ngctl name ${dev}hci:acl ${dev}l2cap \ 113101704Smjacob > /dev/null 2>&1 || return 1 114101704Smjacob 115101704Smjacob ngctl msg ${dev}l2cap: set_debug ${bluetooth_device_l2cap_debug_level} \ 116101704Smjacob > /dev/null 2>&1 || return 1 117101704Smjacob 118101704Smjacob # Connect HCI node to the Bluetooth sockets layer 119102199Smjacob ngctl connect ${dev}hci: btsock_hci_raw: raw ${dev}raw \ 120101704Smjacob > /dev/null 2>&1 || return 1 121101704Smjacob 122101704Smjacob # Connect L2CAP node to Bluetooth sockets layer 123101704Smjacob ngctl connect ${dev}l2cap: btsock_l2c_raw: ctl ${dev}ctl \ 124101704Smjacob > /dev/null 2>&1 || return 1 125101704Smjacob 126101704Smjacob ngctl connect ${dev}l2cap: btsock_l2c: l2c ${dev}l2c \ 127101704Smjacob > /dev/null 2>&1 || return 1 128101704Smjacob 129101704Smjacob # Initilalize HCI node 130101704Smjacob ${hccontrol} -n ${dev}hci reset \ 131101704Smjacob > /dev/null 2>&1 || return 1 132101704Smjacob 133101704Smjacob ${hccontrol} -n ${dev}hci read_bd_addr \ 134101704Smjacob > /dev/null 2>&1 || return 1 135101704Smjacob 136101704Smjacob ${hccontrol} -n ${dev}hci read_local_supported_features \ 137101704Smjacob > /dev/null 2>&1 || return 1 138101704Smjacob 139101704Smjacob ${hccontrol} -n ${dev}hci read_buffer_size \ 140101704Smjacob > /dev/null 2>&1 || return 1 141101704Smjacob 142101704Smjacob if checkyesno bluetooth_device_discoverable; then 143101704Smjacob if checkyesno bluetooth_device_connectable; then 144101704Smjacob ${hccontrol} -n ${dev}hci write_scan_enable 3 \ 145101704Smjacob > /dev/null 2>&1 || return 1 146101704Smjacob else 147101704Smjacob ${hccontrol} -n ${dev}hci write_scan_enable 1 \ 148101704Smjacob > /dev/null 2>&1 || return 1 149101704Smjacob fi 150101704Smjacob else 151101704Smjacob if checkyesno bluetooth_device_connectable; then 152101704Smjacob ${hccontrol} -n ${dev}hci write_scan_enable 2 \ 153101704Smjacob > /dev/null 2>&1 || return 1 154101704Smjacob else 155101704Smjacob ${hccontrol} -n ${dev}hci write_scan_enable 0 \ 156101704Smjacob > /dev/null 2>&1 || return 1 157101704Smjacob fi 158101704Smjacob fi 159101704Smjacob 160101704Smjacob 161101704Smjacob ${hccontrol} -n ${dev}hci write_class_of_device ${bluetooth_device_class} \ 162101704Smjacob > /dev/null 2>&1 || return 1 163102199Smjacob 164101704Smjacob if checkyesno bluetooth_device_authentication_enable; then 165101704Smjacob ${hccontrol} -n ${dev}hci write_authentication_enable 1 \ 166101704Smjacob > /dev/null 2>&1 || return 1 167101704Smjacob else 168101704Smjacob ${hccontrol} -n ${dev}hci write_authentication_enable 0 \ 169101704Smjacob > /dev/null 2>&1 || return 1 170101704Smjacob fi 171101704Smjacob 172101704Smjacob case "${bluetooth_device_encryption_mode}" in 173101704Smjacob [Nn][Oo][Nn][Ee]|0) 174101704Smjacob ${hccontrol} -n ${dev}hci write_encryption_mode 0 \ 175101704Smjacob > /dev/null 2>&1 || return 1 176101704Smjacob ;; 177101704Smjacob 178101704Smjacob [Pp][2][Pp]|1) 179101704Smjacob ${hccontrol} -n ${dev}hci write_encryption_mode 1 \ 180101704Smjacob > /dev/null 2>&1 || return 1 181101704Smjacob ;; 182101704Smjacob 183101704Smjacob [Al][Ll][Ll]|2) 184101704Smjacob ${hccontrol} -n ${dev}hci write_encryption_mode 2 \ 185101704Smjacob > /dev/null 2>&1 || return 1 186101704Smjacob ;; 187101704Smjacob 188101704Smjacob *) 189101704Smjacob warn "Unsupported encryption mode ${bluetooth_device_encryption_mode} for device ${dev}" 190101704Smjacob return 1 191101704Smjacob ;; 192101704Smjacob esac 193101704Smjacob 194101704Smjacob if checkyesno bluetooth_device_role_switch; then 195101704Smjacob ${hccontrol} -n ${dev}hci write_node_role_switch 1 \ 196101704Smjacob > /dev/null 2>&1 || return 1 197101704Smjacob else 198101704Smjacob ${hccontrol} -n ${dev}hci write_node_role_switch 0 \ 199101704Smjacob > /dev/null 2>&1 || return 1 200101704Smjacob fi 201101704Smjacob 202101704Smjacob ${hccontrol} -n ${dev}hci change_local_name "${bluetooth_device_local_name}" \ 203101704Smjacob > /dev/null 2>&1 || return 1 204101704Smjacob 205101704Smjacob ${hccontrol} -n ${dev}hci initialize \ 206101704Smjacob > /dev/null 2>&1 || return 1 207102199Smjacob 208101704Smjacob return 0 209101704Smjacob} 210101704Smjacob 211101704Smjacob############################################################################## 212101704Smjacob# Shutdown Bluetooth stack. Destroy all nodes 213101704Smjacob############################################################################## 214101704Smjacob 215101704Smjacobbluetooth_shutdown_stack() 216101704Smjacob{ 217101704Smjacob dev=$1 218101704Smjacob 219101704Smjacob ngctl shutdown ${dev}hci: > /dev/null 2>&1 220101704Smjacob ngctl shutdown ${dev}l2cap: > /dev/null 2>&1 221101704Smjacob 222101704Smjacob return 0 223101704Smjacob} 224101704Smjacob 225101704Smjacob############################################################################## 226101704Smjacob# bluetooth_start() 227101704Smjacob############################################################################## 228102199Smjacob 229101704Smjacobbluetooth_start() 230101704Smjacob{ 231101704Smjacob local _file 232101704Smjacob 233101704Smjacob dev=$1 234101704Smjacob 235101704Smjacob # Try to figure out device type by looking at device name 236101704Smjacob case "${dev}" in 237101704Smjacob # uartX - serial/UART Bluetooth device 238101704Smjacob uart*) 239101704Smjacob load_kld ng_h4 || return 1 240101704Smjacob 241102199Smjacob hook="hook" 242101704Smjacob 243101704Smjacob # Obtain unit number from device. 244101704Smjacob unit=`expr ${dev} : 'uart\([0-9]\{1,\}\)'` 245101704Smjacob if [ -z "${unit}" ]; then 246101704Smjacob err 1 "Unable to get uart unit number: ${dev}" 247101704Smjacob fi 248101704Smjacob 249101704Smjacob ${hcseriald} -f /dev/cuau${unit} -n ${dev} 250101704Smjacob sleep 1 # wait a little bit 251101704Smjacob 252101704Smjacob if [ ! -f "/var/run/hcseriald.${dev}.pid" ]; then 253101704Smjacob err 1 "Unable to start hcseriald on ${dev}" 254101704Smjacob fi 255101704Smjacob ;; 256101704Smjacob 257101704Smjacob # 3Com Bluetooth Adapter 3CRWB60-A 258101704Smjacob btccc*) 259101704Smjacob hook="hook" 260102199Smjacob 261101704Smjacob # Obtain unit number from device. 262101704Smjacob unit=`expr ${dev} : 'btccc\([0-9]\{1,\}\)'` 263101704Smjacob if [ -z "${unit}" ]; then 264101704Smjacob err 1 "Unable to get bt3c unit number: ${dev}" 265101704Smjacob fi 266102304Smjacob ;; 267102304Smjacob 268101704Smjacob # USB Bluetooth adapters 269101704Smjacob ubt*) 270101704Smjacob hook="hook" 271101704Smjacob 272101704Smjacob # Obtain unit number from device. 273101704Smjacob unit=`expr ${dev} : 'ubt\([0-9]\{1,\}\)'` 274101704Smjacob if [ -z "${unit}" ]; then 275101704Smjacob err 1 "Unable to get ubt unit number: ${dev}" 276101704Smjacob fi 277101704Smjacob ;; 278101704Smjacob 279101704Smjacob # Unknown 280101704Smjacob *) 281101704Smjacob err 1 "Unsupported device: ${dev}" 282101704Smjacob ;; 283101704Smjacob esac 284101704Smjacob 285101704Smjacob # Be backward compatible and setup reasonable defaults 286101704Smjacob bluetooth_device_authentication_enable="0" 287101704Smjacob bluetooth_device_class="ff:01:0c" 288102199Smjacob bluetooth_device_connectable="1" 289101704Smjacob bluetooth_device_discoverable="1" 290101704Smjacob bluetooth_device_encryption_mode="0" 291101704Smjacob bluetooth_device_hci_debug_level="3" 292101704Smjacob bluetooth_device_l2cap_debug_level="3" 293101704Smjacob bluetooth_device_local_name="`/usr/bin/uname -n` (${dev})" 294101704Smjacob bluetooth_device_role_switch="1" 295102199Smjacob 296101704Smjacob # Load default device configuration parameters 297101704Smjacob _file="/etc/defaults/bluetooth.device.conf" 298101704Smjacob 299101704Smjacob if ! bluetooth_read_conf $_file bluetooth_device_ ; then 300101704Smjacob err 1 "Unable to read default Bluetooth configuration from $_file" 301101704Smjacob fi 302101704Smjacob 303101704Smjacob # Load device specific overrides 304101704Smjacob _file="/etc/bluetooth/$dev.conf" 305101704Smjacob 306101704Smjacob if ! bluetooth_read_conf $_file bluetooth_device_ ; then 307102199Smjacob err 1 "Unable to read Bluetooth device configuration from $_file" 308101704Smjacob fi 309101704Smjacob 310101704Smjacob # Setup stack 311101704Smjacob if ! bluetooth_setup_stack ${dev} ${hook} ; then 312101704Smjacob bluetooth_shutdown_stack $dev 313101704Smjacob err 1 "Unable to setup Bluetooth stack for device ${dev}" 314101704Smjacob fi 315101704Smjacob 316101704Smjacob return 0 317101704Smjacob} 318101704Smjacob 319101704Smjacob############################################################################## 320101704Smjacob# bluetooth_stop() 321101704Smjacob############################################################################## 322101704Smjacob 323101704Smjacobbluetooth_stop() 324101704Smjacob{ 325101704Smjacob dev=$1 326101704Smjacob 327101704Smjacob # Try to figure out device type by looking at device name 328101704Smjacob case "${dev}" in 329101704Smjacob # uartX - serial/UART Bluetooth device 330101704Smjacob uart*) 331101704Smjacob if [ -f "/var/run/hcseriald.${dev}.pid" ]; then 332101704Smjacob kill `cat /var/run/hcseriald.${dev}.pid` 333101704Smjacob sleep 1 # wait a little bit 334101704Smjacob fi 335101704Smjacob ;; 336101704Smjacob 337101704Smjacob # 3Com Bluetooth Adapter 3CRWB60-A 338101704Smjacob btccc*) 339101704Smjacob ;; 340101704Smjacob 341101704Smjacob # USB Bluetooth adapters 342101704Smjacob ubt*) 343101704Smjacob ;; 344101704Smjacob 345101704Smjacob # Unknown 346101704Smjacob *) 347101704Smjacob err 1 "Unsupported device: ${dev}" 348101704Smjacob ;; 349101704Smjacob esac 350101704Smjacob 351101704Smjacob bluetooth_shutdown_stack ${dev} 352101704Smjacob 353101704Smjacob return 0 354101704Smjacob} 355101704Smjacob 356101704Smjacob############################################################################## 357101704Smjacob# Start here 358101704Smjacob############################################################################## 359101704Smjacob 360101704Smjacobload_rc_config $name 361101704Smjacobhccontrol="${bluetooth_hccontrol:-/usr/sbin/hccontrol}" 362101704Smjacobhcseriald="${bluetooth_hcseriald:-/usr/sbin/hcseriald}" 363101704Smjacob 364101704Smjacobrun_rc_command $* 365101704Smjacob 366101704Smjacob