diff options
author | emax <emax@FreeBSD.org> | 2005-11-10 19:09:22 +0000 |
---|---|---|
committer | emax <emax@FreeBSD.org> | 2005-11-10 19:09:22 +0000 |
commit | 3e42392551e4268614fa93c66761c62d91572e44 (patch) | |
tree | 90d65f258beeb3e9749b80171b3ab20ec92581f6 | |
parent | c82c5ba499665e44341dee9630ef960a16eca899 (diff) | |
download | FreeBSD-src-3e42392551e4268614fa93c66761c62d91572e44.zip FreeBSD-src-3e42392551e4268614fa93c66761c62d91572e44.tar.gz |
Start integrating Bluetooth into rc.d system.
Introduce /etc/rc.d/bluetooth script to start/stop Bluetooth devices. It
will be called from devd(8) in response to device arrival/departure events.
It is also possible to call it by hand to start/stop particular device
without unplugging it.
Introduce generic way to set configuration parameters for Bluetooth devices.
By default /etc/rc.d/bluetooth script has hardwired defaults compatible
with old rc.bluetooth from /usr/share/netgraph/bluetooth/examples. These
can be overridden using /etc/defaults/bluetooth.device.conf file (system
wide defaults). Finally, there could be another device specific override
file located in /etc/bluetooth/$device.conf (where $device is ubt0, btccc0
etc.)
The list of configuration parameters and their meaning described in the
/etc/defaults/bluetooth.device.conf file. Even though Bluetooth device
configuration files are not shell scripts, they must follow basic sh(1) syntax.
The bluetooth.device.conf(5) and handbook update will follow shortly.
Inspired by: Panagiotis Astithas ( past at ebs dot gr )
Reviewed by: brooks, yar
MFC after: 1 week
-rw-r--r-- | etc/bluetooth/hosts | 3 | ||||
-rw-r--r-- | etc/bluetooth/protocols | 3 | ||||
-rw-r--r-- | etc/defaults/Makefile | 2 | ||||
-rw-r--r-- | etc/defaults/bluetooth.device.conf | 112 | ||||
-rwxr-xr-x | etc/rc.d/Makefile | 2 | ||||
-rw-r--r-- | etc/rc.d/bluetooth | 366 |
6 files changed, 483 insertions, 5 deletions
diff --git a/etc/bluetooth/hosts b/etc/bluetooth/hosts index 4ad0a04..b704248 100644 --- a/etc/bluetooth/hosts +++ b/etc/bluetooth/hosts @@ -7,5 +7,4 @@ # # BD_ADDR Name [ alias0 alias1 ... ] -ff:ff:ff:00:00:00 localhost local # Magic sdpd address - +# 00:11:22:33:44:55 phone diff --git a/etc/bluetooth/protocols b/etc/bluetooth/protocols index 222798b..6715094 100644 --- a/etc/bluetooth/protocols +++ b/etc/bluetooth/protocols @@ -3,7 +3,8 @@ # # Bluetooth Protocol/Service Multiplexor (PSM) names and numbers # -# See also http://www.bluetoothsig.org/assigned-numbers/ +# See also +# https://www.bluetooth.org/foundry/assignnumb/document/assigned_numbers # # Protocol PSM Alias Reference diff --git a/etc/defaults/Makefile b/etc/defaults/Makefile index 3c613fb..7fe5ae8 100644 --- a/etc/defaults/Makefile +++ b/etc/defaults/Makefile @@ -1,6 +1,6 @@ # $FreeBSD$ -FILES= devfs.rules pccard.conf periodic.conf rc.conf +FILES= bluetooth.device.conf devfs.rules pccard.conf periodic.conf rc.conf NO_OBJ= FILESDIR= /etc/defaults FILESMODE= 444 diff --git a/etc/defaults/bluetooth.device.conf b/etc/defaults/bluetooth.device.conf new file mode 100644 index 0000000..7e22dbb --- /dev/null +++ b/etc/defaults/bluetooth.device.conf @@ -0,0 +1,112 @@ +# Copyright (c) 2005 Maksim Yevmenkin <m_evmenkin@yahoo.com> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ + +# The authentication_enable parameter controls if the device requires to +# authenticate the remote device at connection setup. At connection setup, +# only the devices with the authentication_enable parameter enabled will +# try to authenticate the other device. +# +# Possible values: +# +# NO or 0 authentication disabled (default); +# YES or 1 authentication enabled. + +# authentication_enable="NO" + +# The class parameter is used to indicate the capabilities of the device to +# other devices. +# +# For more details see +# https://www.bluetooth.org/foundry/assignnumb/document/baseband +# +# Possible value: +# +# xx:xx:xx where xx is a hex number + +# class="ff:01:0c" + +# The connectable parameter controls whether or not the device should +# periodically scan for page attempts from other devices. +# +# Possible values: +# +# NO or 0 do not scan for page attempts; +# YES or 1 scan for page attempts (default). + +# connectable="YES" + +# The discoverable parameter controls whether or not the device should +# periodically scan for inquiry requests from other devices. +# +# Possible values: +# +# NO or 0 do not scan for inquiry requests; +# YES or 1 scan for inquiry requests (default). + +# discoverable="YES" + +# The encryption_mode parameter controls if the device requires encryption +# to the remote device at connection setup. At connection setup, only the +# devices with the authentication_enable parameter enabled and encryption_mode +# parameter enabled will try to encrypt the connection to the other device. +# +# Possible values: +# +# NONE or 0 encryption disabled (default); +# P2P or 1 encryption only for point-to-point packets; +# ALL or 2 encryption for both point-to-point and broadcast packets. + +# encryption_mode="NONE" + +# HCI node debug level. Higher values mean more verbose output. +# +# Possible values: 0 - 4 + +# hci_debug_level="3" + +# L2CAP node debug level. Higher values mean more verbose output. +# +# Possible values: 0 - 4 + +# l2cap_debug_level="3" + +# The local_name parameter provides the ability to modify the user friendly +# name for the device. + +# local_name="My device" + +# The role_switch parameter controls whether the local device should perform +# role switch. By default, if role switch is supported, the local device will +# try to perform role switch and become Master on incoming connection. Some +# devices do not support role switch and thus incomming connections from such +# devices will fail. If role switch is disabled then accepting device will +# remain Slave. +# +# NO or 0 do not perform role switch; +# YES or 1 perform role switch (default). + +# role_switch="YES" + diff --git a/etc/rc.d/Makefile b/etc/rc.d/Makefile index 76ae80d..56ce8be 100755 --- a/etc/rc.d/Makefile +++ b/etc/rc.d/Makefile @@ -4,7 +4,7 @@ FILES= DAEMON LOGIN NETWORKING SERVERS \ abi accounting addswap adjkerntz amd \ apm apmd archdep atm1 atm2 atm3 \ - bgfsck bootparams bsnmpd \ + bgfsck bluetooth bootparams bsnmpd \ ccd cleanvar cleartmp cron \ devd devfs dhclient \ dmesg dumpon \ diff --git a/etc/rc.d/bluetooth b/etc/rc.d/bluetooth new file mode 100644 index 0000000..54806f3 --- /dev/null +++ b/etc/rc.d/bluetooth @@ -0,0 +1,366 @@ +#!/bin/sh +# +# Copyright (c) 2005 Maksim Yevmenkin <m_evmenkin@yahoo.com> +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +# SUCH DAMAGE. +# +# $FreeBSD$ + +# PROVIDE: bluetooth +# REQUIRE: DAEMON +# KEYWORD: nojail nostart + +. /etc/rc.subr + +name="bluetooth" +rcvar= +start_cmd="bluetooth_start" +stop_cmd="bluetooth_stop" + +############################################################################## +# Read and parse Bluetooth device configuration file +############################################################################## + +bluetooth_read_conf() +{ + _file=$1 + _namespace=$2 + _err=0 + + if [ ! -e $_file ]; then + return 0 + fi + + if [ ! -f $_file -o ! -r $_file ]; then + err 1 "Bluetooth configuration file $_file is not a file or not readable" + fi + + while read _line + do + case "$_line" in + \#*) + continue + ;; + + *) + if [ -z "$_line" ]; then + continue; + fi + + + if expr "$_line" : "[a-zA-Z0-9_]*=" > /dev/null 2>&1; then + eval "${_namespace}${_line}" + else + warn "Unable to parse line \"$_line\" in $_file" + _err=1 + fi + ;; + esac + done < $_file + + return $_err +} + +############################################################################## +# Setup Bluetooth stack. Create and connect nodes +############################################################################## + +bluetooth_setup_stack() +{ + dev=$1 + shift + hook=$1 + shift + + # Setup HCI + ngctl mkpeer ${dev}: hci ${hook} drv \ + > /dev/null 2>&1 || return 1 + + ngctl name ${dev}:${hook} ${dev}hci \ + > /dev/null 2>&1 || return 1 + + ngctl msg ${dev}hci: set_debug ${bluetooth_device_hci_debug_level} \ + > /dev/null 2>&1 || return 1 + + # Setup L2CAP + ngctl mkpeer ${dev}hci: l2cap acl hci \ + > /dev/null 2>&1 || return 1 + + ngctl name ${dev}hci:acl ${dev}l2cap \ + > /dev/null 2>&1 || return 1 + + ngctl msg ${dev}l2cap: set_debug ${bluetooth_device_l2cap_debug_level} \ + > /dev/null 2>&1 || return 1 + + # Connect HCI node to the Bluetooth sockets layer + ngctl connect ${dev}hci: btsock_hci_raw: raw ${dev}raw \ + > /dev/null 2>&1 || return 1 + + # Connect L2CAP node to Bluetooth sockets layer + ngctl connect ${dev}l2cap: btsock_l2c_raw: ctl ${dev}ctl \ + > /dev/null 2>&1 || return 1 + + ngctl connect ${dev}l2cap: btsock_l2c: l2c ${dev}l2c \ + > /dev/null 2>&1 || return 1 + + # Initilalize HCI node + ${hccontrol} -n ${dev}hci reset \ + > /dev/null 2>&1 || return 1 + + ${hccontrol} -n ${dev}hci read_bd_addr \ + > /dev/null 2>&1 || return 1 + + ${hccontrol} -n ${dev}hci read_local_supported_features \ + > /dev/null 2>&1 || return 1 + + ${hccontrol} -n ${dev}hci read_buffer_size \ + > /dev/null 2>&1 || return 1 + + if checkyesno bluetooth_device_discoverable; then + if checkyesno bluetooth_device_connectable; then + ${hccontrol} -n ${dev}hci write_scan_enable 3 \ + > /dev/null 2>&1 || return 1 + else + ${hccontrol} -n ${dev}hci write_scan_enable 1 \ + > /dev/null 2>&1 || return 1 + fi + else + if checkyesno bluetooth_device_connectable; then + ${hccontrol} -n ${dev}hci write_scan_enable 2 \ + > /dev/null 2>&1 || return 1 + else + ${hccontrol} -n ${dev}hci write_scan_enable 0 \ + > /dev/null 2>&1 || return 1 + fi + fi + + + ${hccontrol} -n ${dev}hci write_class_of_device ${bluetooth_device_class} \ + > /dev/null 2>&1 || return 1 + + if checkyesno bluetooth_device_authentication_enable; then + ${hccontrol} -n ${dev}hci write_authentication_enable 1 \ + > /dev/null 2>&1 || return 1 + else + ${hccontrol} -n ${dev}hci write_authentication_enable 0 \ + > /dev/null 2>&1 || return 1 + fi + + case "${bluetooth_device_encryption_mode}" in + [Nn][Oo][Nn][Ee]|0) + ${hccontrol} -n ${dev}hci write_encryption_mode 0 \ + > /dev/null 2>&1 || return 1 + ;; + + [Pp][2][Pp]|1) + ${hccontrol} -n ${dev}hci write_encryption_mode 1 \ + > /dev/null 2>&1 || return 1 + ;; + + [Al][Ll][Ll]|2) + ${hccontrol} -n ${dev}hci write_encryption_mode 2 \ + > /dev/null 2>&1 || return 1 + ;; + + *) + warn "Unsupported encryption mode ${bluetooth_device_encryption_mode} for device ${dev}" + return 1 + ;; + esac + + if checkyesno bluetooth_device_role_switch; then + ${hccontrol} -n ${dev}hci write_node_role_switch 1 \ + > /dev/null 2>&1 || return 1 + else + ${hccontrol} -n ${dev}hci write_node_role_switch 0 \ + > /dev/null 2>&1 || return 1 + fi + + ${hccontrol} -n ${dev}hci change_local_name "${bluetooth_device_local_name}" \ + > /dev/null 2>&1 || return 1 + + ${hccontrol} -n ${dev}hci initialize \ + > /dev/null 2>&1 || return 1 + + return 0 +} + +############################################################################## +# Shutdown Bluetooth stack. Destroy all nodes +############################################################################## + +bluetooth_shutdown_stack() +{ + dev=$1 + + ngctl shutdown ${dev}hci: > /dev/null 2>&1 + ngctl shutdown ${dev}l2cap: > /dev/null 2>&1 + + return 0 +} + +############################################################################## +# bluetooth_start() +############################################################################## + +bluetooth_start() +{ + dev=$1 + + # Automatically load modules + kldload ng_bluetooth > /dev/null 2>&1 + kldload ng_hci > /dev/null 2>&1 + kldload ng_l2cap > /dev/null 2>&1 + kldload ng_btsocket > /dev/null 2>&1 + + # Try to figure out device type by looking at device name + case "${dev}" in + # sioX - serial/UART Bluetooth device + sio*) + kldload ng_h4 > /dev/null 2>&1 + + hook="hook" + + # Obtain unit number from device. + unit=`expr ${dev} : 'sio\([0-9]\{1,\}\)'` + if [ -z "${unit}" ]; then + err 1 "Unable to get sio unit number: ${dev}" + fi + + ${hcseriald} -f /dev/cuad${unit} -n ${dev} + sleep 1 # wait a little bit + + if [ ! -f "/var/run/hcseriald.${dev}.pid" ]; then + err 1 "Unable to start hcseriald on ${dev}" + fi + ;; + + # 3Com Bluetooth Adapter 3CRWB60-A + btccc*) + hook="hook" + + # Obtain unit number from device. + unit=`expr ${dev} : 'btccc\([0-9]\{1,\}\)'` + if [ -z "${unit}" ]; then + err 1 "Unable to get bt3c unit number: ${dev}" + fi + ;; + + # USB Bluetooth adapters + ubt*) + hook="hook" + + # Obtain unit number from device. + unit=`expr ${dev} : 'ubt\([0-9]\{1,\}\)'` + if [ -z "${unit}" ]; then + err 1 "Unable to get ubt unit number: ${dev}" + fi + ;; + + # Unknown + *) + err 1 "Unsupported device: ${dev}" + ;; + esac + + # Be backward compatible and setup reasonable defaults + bluetooth_device_authentication_enable="0" + bluetooth_device_class="ff:01:0c" + bluetooth_device_connectable="1" + bluetooth_device_discoverable="1" + bluetooth_device_encryption_mode="0" + bluetooth_device_hci_debug_level="3" + bluetooth_device_l2cap_debug_level="3" + bluetooth_device_local_name="`/usr/bin/uname -n` (${dev})" + bluetooth_device_role_switch="1" + + # Load default device configuration parameters + _file="/etc/defaults/bluetooth.device.conf" + + if ! bluetooth_read_conf $_file bluetooth_device_ ; then + err 1 "Unable to read default Bluetooth configuration from $_file" + fi + + # Load device specific overrides + _file="/etc/bluetooth/$dev.conf" + + if ! bluetooth_read_conf $_file bluetooth_device_ ; then + err 1 "Unable to read Bluetooth device configuration from $_file" + fi + + # Setup stack + if ! bluetooth_setup_stack ${dev} ${hook} ; then + bluetooth_shutdown_stack $dev + err 1 "Unable to setup Bluetooth stack for device ${dev}" + fi + + return 0 +} + +############################################################################## +# bluetooth_stop() +############################################################################## + +bluetooth_stop() +{ + dev=$1 + + # Try to figure out device type by looking at device name + case "${dev}" in + # sioX - serial/UART Bluetooth device + sio*) + if [ -f "/var/run/hcseriald.${dev}.pid" ]; then + kill `cat /var/run/hcseriald.${dev}.pid` + sleep 1 # wait a little bit + fi + ;; + + # 3Com Bluetooth Adapter 3CRWB60-A + btccc*) + ;; + + # USB Bluetooth adapters + ubt*) + ;; + + # Unknown + *) + err 1 "Unsupported device: ${dev}" + ;; + esac + + bluetooth_shutdown_stack ${dev} + + return 0 +} + +############################################################################## +# Start here +############################################################################## + +load_rc_config $name +hccontrol="${bluetooth_hccontrol:-/usr/sbin/hccontrol}" +hcseriald="${bluetooth_hcseriald:-/usr/sbin/hcseriald}" + +run_rc_command $* + |