]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - libexec/rc/rc.d/bluetooth
Merge commit 'ce929fe84f9c453263af379f3b255ff8eca01d48'
[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         # USB Bluetooth adapters
239         ubt*)
240                 hook="hook"
241
242                 # Obtain unit number from device.
243                 unit=`expr ${dev} : 'ubt\([0-9]\{1,\}\)'`
244                 if [ -z "${unit}" ]; then
245                         err 1 "Unable to get ubt unit number: ${dev}"
246                 fi
247                 ;;
248
249         # Unknown
250         *)
251                 err 1 "Unsupported device: ${dev}"
252                 ;;
253         esac
254
255         # Be backward compatible and setup reasonable defaults
256         bluetooth_device_authentication_enable="0"
257         bluetooth_device_class="ff:01:0c"
258         bluetooth_device_connectable="1"
259         bluetooth_device_discoverable="0"
260         bluetooth_device_encryption_mode="0"
261         bluetooth_device_hci_debug_level="3"
262         bluetooth_device_l2cap_debug_level="3"
263         bluetooth_device_local_name="`/usr/bin/uname -n` (${dev})"
264         bluetooth_device_role_switch="1"
265
266         # Load default device configuration parameters
267         _file="/etc/defaults/bluetooth.device.conf"
268
269         if ! bluetooth_read_conf $_file bluetooth_device_ ; then
270                 err 1 "Unable to read default Bluetooth configuration from $_file"
271         fi
272
273         # Load device specific overrides
274         _file="/etc/bluetooth/$dev.conf"
275
276         if ! bluetooth_read_conf $_file bluetooth_device_ ; then
277                 err 1 "Unable to read Bluetooth device configuration from $_file"
278         fi
279
280         # Setup stack
281         if ! bluetooth_setup_stack ${dev} ${hook} ; then
282                 bluetooth_shutdown_stack $dev
283                 err 1 "Unable to setup Bluetooth stack for device ${dev}"
284         fi
285
286         return 0
287 }
288
289 ##############################################################################
290 # bluetooth_stop()
291 ##############################################################################
292
293 bluetooth_stop()
294 {
295         dev=$1
296
297         # Try to figure out device type by looking at device name
298         case "${dev}" in
299         # USB Bluetooth adapters
300         ubt*)
301                 ;;
302
303         # Unknown
304         *)
305                 err 1 "Unsupported device: ${dev}"
306                 ;;
307         esac
308
309         bluetooth_shutdown_stack ${dev}
310
311         return 0
312 }
313
314 ##############################################################################
315 # Start here
316 ##############################################################################
317
318 load_rc_config $name
319 hccontrol="${bluetooth_hccontrol:-/usr/sbin/hccontrol}"
320
321 run_rc_command $*
322