]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - libexec/rc/rc.d/bluetooth
awk: Merge 20210729 from One True Awk upstream (0592de4a)
[FreeBSD/FreeBSD.git] / libexec / rc / 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         # USB Bluetooth adapters
259         ubt*)
260                 hook="hook"
261
262                 # Obtain unit number from device.
263                 unit=`expr ${dev} : 'ubt\([0-9]\{1,\}\)'`
264                 if [ -z "${unit}" ]; then
265                         err 1 "Unable to get ubt unit number: ${dev}"
266                 fi
267                 ;;
268
269         # Unknown
270         *)
271                 err 1 "Unsupported device: ${dev}"
272                 ;;
273         esac
274
275         # Be backward compatible and setup reasonable defaults
276         bluetooth_device_authentication_enable="0"
277         bluetooth_device_class="ff:01:0c"
278         bluetooth_device_connectable="1"
279         bluetooth_device_discoverable="0"
280         bluetooth_device_encryption_mode="0"
281         bluetooth_device_hci_debug_level="3"
282         bluetooth_device_l2cap_debug_level="3"
283         bluetooth_device_local_name="`/usr/bin/uname -n` (${dev})"
284         bluetooth_device_role_switch="1"
285
286         # Load default device configuration parameters
287         _file="/etc/defaults/bluetooth.device.conf"
288
289         if ! bluetooth_read_conf $_file bluetooth_device_ ; then
290                 err 1 "Unable to read default Bluetooth configuration from $_file"
291         fi
292
293         # Load device specific overrides
294         _file="/etc/bluetooth/$dev.conf"
295
296         if ! bluetooth_read_conf $_file bluetooth_device_ ; then
297                 err 1 "Unable to read Bluetooth device configuration from $_file"
298         fi
299
300         # Setup stack
301         if ! bluetooth_setup_stack ${dev} ${hook} ; then
302                 bluetooth_shutdown_stack $dev
303                 err 1 "Unable to setup Bluetooth stack for device ${dev}"
304         fi
305
306         return 0
307 }
308
309 ##############################################################################
310 # bluetooth_stop()
311 ##############################################################################
312
313 bluetooth_stop()
314 {
315         dev=$1
316
317         # Try to figure out device type by looking at device name
318         case "${dev}" in
319         # uartX - serial/UART Bluetooth device
320         uart*)
321                 if [ -f "/var/run/hcseriald.${dev}.pid" ]; then
322                         kill `cat /var/run/hcseriald.${dev}.pid`
323                         sleep 1 # wait a little bit
324                 fi
325                 ;;
326
327         # 3Com Bluetooth Adapter 3CRWB60-A
328         btccc*)
329                 ;;
330
331         # USB Bluetooth adapters
332         ubt*)
333                 ;;
334
335         # Unknown
336         *)
337                 err 1 "Unsupported device: ${dev}"
338                 ;;
339         esac
340
341         bluetooth_shutdown_stack ${dev}
342
343         return 0
344 }
345
346 ##############################################################################
347 # Start here
348 ##############################################################################
349
350 load_rc_config $name
351 hccontrol="${bluetooth_hccontrol:-/usr/sbin/hccontrol}"
352 hcseriald="${bluetooth_hcseriald:-/usr/sbin/hcseriald}"
353
354 run_rc_command $*
355