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