]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - etc/rc.d/bluetooth
The rune interface was removed by tjr over two years ago.
[FreeBSD/FreeBSD.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
40 ##############################################################################
41 # Read and parse Bluetooth device configuration file
42 ##############################################################################
43
44 bluetooth_read_conf()
45 {
46         _file=$1
47         _namespace=$2
48         _err=0
49
50         if [ ! -e $_file ]; then
51                 return 0
52         fi
53
54         if [ ! -f $_file -o ! -r $_file ]; then
55                 err 1 "Bluetooth configuration file $_file is not a file or not readable"
56         fi
57
58         while read _line
59         do
60                 case "$_line" in
61                 \#*)
62                         continue
63                         ;;
64
65                 *)
66                         if [ -z "$_line" ]; then
67                                 continue;
68                         fi
69
70
71                         if expr "$_line" : "[a-zA-Z0-9_]*=" > /dev/null 2>&1; then
72                                 eval "${_namespace}${_line}"
73                         else
74                                 warn "Unable to parse line \"$_line\" in $_file"
75                                 _err=1
76                         fi
77                         ;;
78                 esac
79         done < $_file
80
81         return $_err
82 }
83
84 ##############################################################################
85 # Setup Bluetooth stack. Create and connect nodes
86 ##############################################################################
87
88 bluetooth_setup_stack()
89 {
90         dev=$1
91         shift
92         hook=$1
93         shift
94
95         # Setup HCI 
96         ngctl mkpeer ${dev}: hci ${hook} drv \
97                 > /dev/null 2>&1 || return 1
98
99         ngctl name ${dev}:${hook} ${dev}hci \
100                 > /dev/null 2>&1 || return 1
101
102         ngctl msg ${dev}hci: set_debug ${bluetooth_device_hci_debug_level} \
103                 > /dev/null 2>&1 || return 1
104
105         # Setup L2CAP
106         ngctl mkpeer ${dev}hci: l2cap acl hci \
107                 > /dev/null 2>&1 || return 1
108
109         ngctl name ${dev}hci:acl ${dev}l2cap \
110                 > /dev/null 2>&1 || return 1
111
112         ngctl msg ${dev}l2cap: set_debug ${bluetooth_device_l2cap_debug_level} \
113                 > /dev/null 2>&1 || return 1
114
115         # Connect HCI node to the Bluetooth sockets layer
116         ngctl connect ${dev}hci: btsock_hci_raw: raw ${dev}raw \
117                 > /dev/null 2>&1 || return 1
118
119         # Connect L2CAP node to Bluetooth sockets layer
120         ngctl connect ${dev}l2cap: btsock_l2c_raw: ctl ${dev}ctl \
121                 > /dev/null 2>&1 || return 1
122
123         ngctl connect ${dev}l2cap: btsock_l2c: l2c ${dev}l2c \
124                 > /dev/null 2>&1 || return 1
125
126         # Initilalize HCI node
127         ${hccontrol} -n ${dev}hci reset \
128                 > /dev/null 2>&1 || return 1
129
130         ${hccontrol} -n ${dev}hci read_bd_addr \
131                 > /dev/null 2>&1 || return 1
132
133         ${hccontrol} -n ${dev}hci read_local_supported_features \
134                 > /dev/null 2>&1 || return 1
135
136         ${hccontrol} -n ${dev}hci read_buffer_size \
137                 > /dev/null 2>&1 || return 1
138
139         if checkyesno bluetooth_device_discoverable; then
140                 if checkyesno bluetooth_device_connectable; then
141                         ${hccontrol} -n ${dev}hci write_scan_enable 3 \
142                                 > /dev/null 2>&1 || return 1
143                 else
144                         ${hccontrol} -n ${dev}hci write_scan_enable 1 \
145                                 > /dev/null 2>&1 || return 1
146                 fi
147         else
148                 if checkyesno bluetooth_device_connectable; then
149                         ${hccontrol} -n ${dev}hci write_scan_enable 2 \
150                                 > /dev/null 2>&1 || return 1
151                 else
152                         ${hccontrol} -n ${dev}hci write_scan_enable 0 \
153                                 > /dev/null 2>&1 || return 1
154                 fi
155         fi
156
157
158         ${hccontrol} -n ${dev}hci write_class_of_device ${bluetooth_device_class} \
159                 > /dev/null 2>&1 || return 1
160
161         if checkyesno bluetooth_device_authentication_enable; then
162                 ${hccontrol} -n ${dev}hci write_authentication_enable 1 \
163                         > /dev/null 2>&1 || return 1
164         else
165                 ${hccontrol} -n ${dev}hci write_authentication_enable 0 \
166                         > /dev/null 2>&1 || return 1
167         fi
168
169         case "${bluetooth_device_encryption_mode}" in
170         [Nn][Oo][Nn][Ee]|0)
171                 ${hccontrol} -n ${dev}hci write_encryption_mode 0 \
172                         > /dev/null 2>&1 || return 1
173                 ;;
174
175         [Pp][2][Pp]|1)
176                 ${hccontrol} -n ${dev}hci write_encryption_mode 1 \
177                         > /dev/null 2>&1 || return 1
178                 ;;
179
180         [Al][Ll][Ll]|2)
181                 ${hccontrol} -n ${dev}hci write_encryption_mode 2 \
182                         > /dev/null 2>&1 || return 1
183                 ;;
184
185         *)
186                 warn "Unsupported encryption mode ${bluetooth_device_encryption_mode} for device ${dev}"
187                 return 1
188                 ;;
189         esac
190
191         if checkyesno bluetooth_device_role_switch; then
192                 ${hccontrol} -n ${dev}hci write_node_role_switch 1 \
193                         > /dev/null 2>&1 || return 1
194         else
195                 ${hccontrol} -n ${dev}hci write_node_role_switch 0 \
196                         > /dev/null 2>&1 || return 1
197         fi
198
199         ${hccontrol} -n ${dev}hci change_local_name "${bluetooth_device_local_name}" \
200                 > /dev/null 2>&1 || return 1
201
202         ${hccontrol} -n ${dev}hci initialize \
203                 > /dev/null 2>&1 || return 1
204
205         return 0
206 }
207
208 ##############################################################################
209 # Shutdown Bluetooth stack. Destroy all nodes
210 ##############################################################################
211
212 bluetooth_shutdown_stack()
213 {
214         dev=$1
215
216         ngctl shutdown ${dev}hci: > /dev/null 2>&1
217         ngctl shutdown ${dev}l2cap: > /dev/null 2>&1
218
219         return 0
220 }
221
222 ##############################################################################
223 # bluetooth_start()
224 ##############################################################################
225
226 bluetooth_start()
227 {
228         dev=$1
229
230         # Automatically load modules
231         kldload ng_bluetooth > /dev/null 2>&1
232         kldload ng_hci > /dev/null 2>&1
233         kldload ng_l2cap > /dev/null 2>&1
234         kldload ng_btsocket > /dev/null 2>&1
235
236         # Try to figure out device type by looking at device name
237         case "${dev}" in
238         # sioX - serial/UART Bluetooth device
239         sio*)
240                 kldload ng_h4 > /dev/null 2>&1
241
242                 hook="hook"
243
244                 # Obtain unit number from device.
245                 unit=`expr ${dev} : 'sio\([0-9]\{1,\}\)'`
246                 if [ -z "${unit}" ]; then
247                         err 1 "Unable to get sio unit number: ${dev}"
248                 fi
249
250                 ${hcseriald} -f /dev/cuad${unit} -n ${dev}
251                 sleep 1 # wait a little bit
252
253                 if [ ! -f "/var/run/hcseriald.${dev}.pid" ]; then
254                         err 1 "Unable to start hcseriald on ${dev}"
255                 fi
256                 ;;
257
258         # 3Com Bluetooth Adapter 3CRWB60-A
259         btccc*)
260                 hook="hook"
261
262                 # Obtain unit number from device.
263                 unit=`expr ${dev} : 'btccc\([0-9]\{1,\}\)'`
264                 if [ -z "${unit}" ]; then
265                         err 1 "Unable to get bt3c unit number: ${dev}"
266                 fi
267                 ;;
268
269         # USB Bluetooth adapters
270         ubt*)
271                 hook="hook"
272
273                 # Obtain unit number from device.
274                 unit=`expr ${dev} : 'ubt\([0-9]\{1,\}\)'`
275                 if [ -z "${unit}" ]; then
276                         err 1 "Unable to get ubt unit number: ${dev}"
277                 fi
278                 ;;
279
280         # Unknown
281         *)
282                 err 1 "Unsupported device: ${dev}"
283                 ;;
284         esac
285
286         # Be backward compatible and setup reasonable defaults 
287         bluetooth_device_authentication_enable="0"
288         bluetooth_device_class="ff:01:0c"
289         bluetooth_device_connectable="1"
290         bluetooth_device_discoverable="1"
291         bluetooth_device_encryption_mode="0"
292         bluetooth_device_hci_debug_level="3"
293         bluetooth_device_l2cap_debug_level="3"
294         bluetooth_device_local_name="`/usr/bin/uname -n` (${dev})"
295         bluetooth_device_role_switch="1"
296
297         # Load default device configuration parameters
298         _file="/etc/defaults/bluetooth.device.conf"
299
300         if ! bluetooth_read_conf $_file bluetooth_device_ ; then
301                 err 1 "Unable to read default Bluetooth configuration from $_file"
302         fi
303
304         # Load device specific overrides
305         _file="/etc/bluetooth/$dev.conf"
306
307         if ! bluetooth_read_conf $_file bluetooth_device_ ; then
308                 err 1 "Unable to read Bluetooth device configuration from $_file"
309         fi
310
311         # Setup stack
312         if ! bluetooth_setup_stack ${dev} ${hook} ; then
313                 bluetooth_shutdown_stack $dev
314                 err 1 "Unable to setup Bluetooth stack for device ${dev}"
315         fi
316                 
317         return 0
318 }
319
320 ##############################################################################
321 # bluetooth_stop()
322 ##############################################################################
323
324 bluetooth_stop()
325 {
326         dev=$1
327
328         # Try to figure out device type by looking at device name
329         case "${dev}" in
330         # sioX - serial/UART Bluetooth device
331         sio*)
332                 if [ -f "/var/run/hcseriald.${dev}.pid" ]; then
333                         kill `cat /var/run/hcseriald.${dev}.pid`
334                         sleep 1 # wait a little bit
335                 fi
336                 ;;
337
338         # 3Com Bluetooth Adapter 3CRWB60-A
339         btccc*)
340                 ;;
341
342         # USB Bluetooth adapters
343         ubt*)
344                 ;;
345
346         # Unknown
347         *)
348                 err 1 "Unsupported device: ${dev}"
349                 ;;
350         esac
351
352         bluetooth_shutdown_stack ${dev}
353
354         return 0
355 }
356
357 ##############################################################################
358 # Start here
359 ##############################################################################
360
361 load_rc_config $name
362 hccontrol="${bluetooth_hccontrol:-/usr/sbin/hccontrol}"
363 hcseriald="${bluetooth_hcseriald:-/usr/sbin/hcseriald}"
364
365 run_rc_command $*
366