]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - etc/rc.d/bluetooth
Document SA-19:09, SA-19:11.
[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 desc="Bluetooth setup script"
37 rcvar=
38 start_cmd="bluetooth_start"
39 stop_cmd="bluetooth_stop"
40 required_modules="ng_bluetooth ng_hci ng_l2cap ng_btsocket"
41
42 ##############################################################################
43 # Read and parse Bluetooth device configuration file
44 ##############################################################################
45
46 bluetooth_read_conf()
47 {
48         local _err _file _line _namespace
49
50         _file=$1
51         _namespace=$2
52         _err=0
53
54         if [ ! -e $_file ]; then
55                 return 0
56         fi
57
58         if [ ! -f $_file -o ! -r $_file ]; then
59                 err 1 "Bluetooth configuration file $_file is not a file or not readable"
60         fi
61
62         while read _line
63         do
64                 case "$_line" in
65                 \#*)
66                         continue
67                         ;;
68
69                 *)
70                         if [ -z "$_line" ]; then
71                                 continue;
72                         fi
73
74
75                         if expr "$_line" : "[a-zA-Z0-9_]*=" > /dev/null 2>&1; then
76                                 eval "${_namespace}${_line}"
77                         else
78                                 warn "Unable to parse line \"$_line\" in $_file"
79                                 _err=1
80                         fi
81                         ;;
82                 esac
83         done < $_file
84
85         return $_err
86 }
87
88 ##############################################################################
89 # Setup Bluetooth stack. Create and connect nodes
90 ##############################################################################
91
92 bluetooth_setup_stack()
93 {
94         dev=$1
95         shift
96         hook=$1
97         shift
98
99         # Setup HCI
100         ngctl mkpeer ${dev}: hci ${hook} drv \
101                 > /dev/null 2>&1 || return 1
102
103         ngctl name ${dev}:${hook} ${dev}hci \
104                 > /dev/null 2>&1 || return 1
105
106         ngctl msg ${dev}hci: set_debug ${bluetooth_device_hci_debug_level} \
107                 > /dev/null 2>&1 || return 1
108
109         # Setup L2CAP
110         ngctl mkpeer ${dev}hci: l2cap acl hci \
111                 > /dev/null 2>&1 || return 1
112
113         ngctl name ${dev}hci:acl ${dev}l2cap \
114                 > /dev/null 2>&1 || return 1
115
116         ngctl msg ${dev}l2cap: set_debug ${bluetooth_device_l2cap_debug_level} \
117                 > /dev/null 2>&1 || return 1
118
119         # Connect HCI node to the Bluetooth sockets layer
120         ngctl connect ${dev}hci: btsock_hci_raw: raw ${dev}raw \
121                 > /dev/null 2>&1 || return 1
122
123         # Connect L2CAP node to Bluetooth sockets layer
124         ngctl connect ${dev}l2cap: btsock_l2c_raw: ctl ${dev}ctl \
125                 > /dev/null 2>&1 || return 1
126
127         ngctl connect ${dev}l2cap: btsock_l2c: l2c ${dev}l2c \
128                 > /dev/null 2>&1 || return 1
129
130         # Initilalize HCI node
131         ${hccontrol} -n ${dev}hci reset \
132                 > /dev/null 2>&1 || return 1
133
134         ${hccontrol} -n ${dev}hci read_bd_addr \
135                 > /dev/null 2>&1 || return 1
136
137         ${hccontrol} -n ${dev}hci read_local_supported_features \
138                 > /dev/null 2>&1 || return 1
139
140         ${hccontrol} -n ${dev}hci read_buffer_size \
141                 > /dev/null 2>&1 || return 1
142
143         if checkyesno bluetooth_device_discoverable; then
144                 if checkyesno bluetooth_device_connectable; then
145                         ${hccontrol} -n ${dev}hci write_scan_enable 3 \
146                                 > /dev/null 2>&1 || return 1
147                 else
148                         ${hccontrol} -n ${dev}hci write_scan_enable 1 \
149                                 > /dev/null 2>&1 || return 1
150                 fi
151         else
152                 if checkyesno bluetooth_device_connectable; then
153                         ${hccontrol} -n ${dev}hci write_scan_enable 2 \
154                                 > /dev/null 2>&1 || return 1
155                 else
156                         ${hccontrol} -n ${dev}hci write_scan_enable 0 \
157                                 > /dev/null 2>&1 || return 1
158                 fi
159         fi
160
161
162         ${hccontrol} -n ${dev}hci write_class_of_device ${bluetooth_device_class} \
163                 > /dev/null 2>&1 || return 1
164
165         if checkyesno bluetooth_device_authentication_enable; then
166                 ${hccontrol} -n ${dev}hci write_authentication_enable 1 \
167                         > /dev/null 2>&1 || return 1
168         else
169                 ${hccontrol} -n ${dev}hci write_authentication_enable 0 \
170                         > /dev/null 2>&1 || return 1
171         fi
172
173         case "${bluetooth_device_encryption_mode}" in
174         [Nn][Oo][Nn][Ee]|0)
175                 ${hccontrol} -n ${dev}hci write_encryption_mode 0 \
176                         > /dev/null 2>&1 || return 1
177                 ;;
178
179         [Pp][2][Pp]|1)
180                 ${hccontrol} -n ${dev}hci write_encryption_mode 1 \
181                         > /dev/null 2>&1 || return 1
182                 ;;
183
184         [Al][Ll][Ll]|2)
185                 ${hccontrol} -n ${dev}hci write_encryption_mode 2 \
186                         > /dev/null 2>&1 || return 1
187                 ;;
188
189         *)
190                 warn "Unsupported encryption mode ${bluetooth_device_encryption_mode} for device ${dev}"
191                 return 1
192                 ;;
193         esac
194
195         if checkyesno bluetooth_device_role_switch; then
196                 ${hccontrol} -n ${dev}hci write_node_role_switch 1 \
197                         > /dev/null 2>&1 || return 1
198         else
199                 ${hccontrol} -n ${dev}hci write_node_role_switch 0 \
200                         > /dev/null 2>&1 || return 1
201         fi
202
203         ${hccontrol} -n ${dev}hci change_local_name "${bluetooth_device_local_name}" \
204                 > /dev/null 2>&1 || return 1
205
206         ${hccontrol} -n ${dev}hci initialize \
207                 > /dev/null 2>&1 || return 1
208
209         return 0
210 }
211
212 ##############################################################################
213 # Shutdown Bluetooth stack. Destroy all nodes
214 ##############################################################################
215
216 bluetooth_shutdown_stack()
217 {
218         dev=$1
219
220         ngctl shutdown ${dev}hci: > /dev/null 2>&1
221         ngctl shutdown ${dev}l2cap: > /dev/null 2>&1
222
223         return 0
224 }
225
226 ##############################################################################
227 # bluetooth_start()
228 ##############################################################################
229
230 bluetooth_start()
231 {
232         local _file
233
234         dev=$1
235
236         # Try to figure out device type by looking at device name
237         case "${dev}" in
238         # uartX - serial/UART Bluetooth device
239         uart*)
240                 load_kld ng_h4 || return 1
241
242                 hook="hook"
243
244                 # Obtain unit number from device.
245                 unit=`expr ${dev} : 'uart\([0-9]\{1,\}\)'`
246                 if [ -z "${unit}" ]; then
247                         err 1 "Unable to get uart unit number: ${dev}"
248                 fi
249
250                 ${hcseriald} -f /dev/cuau${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         # uartX - serial/UART Bluetooth device
331         uart*)
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