99e4705144d0bc0172cf6b8e363e13850a186d08
[hqbeamer.git] / script / beamer.sh
1 #!/bin/bash
2
3 # Andreas Schiermeier <andreas@schiermeier.name>
4
5 # BT Pairing using a PIN
6 # Debian squeeze:
7 # bluetooth-agent PIN 00:07:80:43:76:05
8 # Debian wheezy:
9 # bluez-simple-agent hci0 00:07:80:43:76:05
10
11 BT_IF="rfcomm0"
12 BT_SPEED="9600"
13
14 control_pipe="/dev/stdin"
15 output="/dev/stdout"
16 rfcomm_init=0
17 pipe_client=0
18
19 declare -A commands
20 commands=(
21   ['POWERON']='!'
22   ['POWEROFF']='"'
23   ['INPUTCOMP1']='_r1'
24   ['INPUTCOMP2']='_r2'
25   ['INPUTDVI']='_d1'
26   ['INPUTVIDEO']='_v1'
27   ['INPUTSVIDEO']='_v2'
28   ['MUTEON']='MUTE1'
29   ['MUTEOFF']='MUTE0'
30   ['VOLUP']='r06'
31   ['VOLDOWN']='r07'
32   ['KEYSTONE']='r43'
33   ['EXPAND']='r02'
34   ['PINP']='r04'
35   ['MUTE']='ra6'
36   ['UP']='r53'
37   ['DOWN']='r2b'
38   ['LEFT']='r4f'
39   ['RIGHT']='r59'
40   ['MENU']='r54'
41   ['ENTER']='r10'
42   ['AUTOPOS']='r09'
43   ['STILL']='ra4'
44   ['ASPECT']='re2'
45   ['WALLSCREEN']='rd7'
46   ['CE']='re7'
47   )
48
49 function spawnRfcomm {
50   # try to establish a conecting to the projectors BT dongle
51   # in the background
52   (
53     while true
54     do
55       if [ -c "/dev/${BT_IF}" ]
56       then
57         rfcomm release "${BT_IF}" &> /dev/null
58       fi
59       # establish raw (-r) connection to projectors serial if
60       rfcomm -r connect "${BT_IF}" &> /dev/null
61       sleep 2
62     done
63   ) &
64   # clean up process group processes (rfcomm) in case the script exits
65   trap 'kill 0' EXIT
66 }
67
68 function sendCmd {
69   trycount=0
70   # is the device available?
71   while [ ! -c "/dev/${BT_IF}" ]
72   do
73     # try three times before giving up
74     let trycount++
75     if [ ${trycount} -gt 3 ]
76     then
77       return 1
78     fi
79     sleep 1 
80   done
81   # is the device the one we've already initialized?
82   rfcomm_created=$(stat -c %Z "/dev/${BT_IF}")
83   if [ ${rfcomm_created} -gt ${rfcomm_init} ]
84   then
85     # configure speed and enable CR to NL conversion for incoming data
86     stty -F "/dev/${BT_IF}" "${BT_SPEED}" icrnl
87     # \r ensures there is no grabage left on the serial connection to the projector
88     echo -en '\r' > "/dev/${BT_IF}"
89     rfcomm_init=${rfcomm_created}
90   fi
91   # empty action is used to init the connection
92   if [ -n "${1}" ]
93   then
94     echo -en '00'${commands[$1]}'\r' > "/dev/${BT_IF}"
95     # with for projectors reply up to one second
96     read -t1 ret < "/dev/${BT_IF}"
97     # projector replies back accepted commands
98     if [ "${ret}" != "00${commands[$1]}" ]
99     then
100       return 2
101     fi
102   fi
103 }
104
105 function usage {
106   cat <<__EOF>&2
107   
108 usage:  $0 [-c] [/path/to/namedpipe]
109
110
111 __EOF
112   exit
113 }
114
115 while getopts ":c" optname; do
116     case "${optname}" in
117         c)
118             pipe_client=1
119             ;;
120         *)
121             usage
122             ;;
123     esac
124 done
125 shift $((OPTIND-1))
126
127 if [ -p "${1}" ]
128 then
129   control_pipe="${1}"
130   if [ ${pipe_client} -eq 0 ]
131   then
132     output="/dev/null"
133   fi
134 fi
135
136 if [ ${pipe_client} -eq 0 ]
137 then
138   spawnRfcomm
139 fi
140
141 cat <<'EOF' > "${output}"
142 MENU m, POWERON p, POWEROFF P, UP k, DOWN j, LEFT h, RIGHT l, STILL s
143 INPUTCOMP1 1, INPUTCOMP2 2. INPUTDVI 3, INPUTVIDEO 4, INPUTSVIDEO 5, ENTER Return
144 TOGGLE INPUTCOMP1/DVI1 ~
145 QUIT Q
146
147 ready.
148 EOF
149
150 while true
151 do
152   # read from STDIN when acting as pipe client
153   if [ ${pipe_client} -eq 0 ]
154   then
155     read_pipe="${control_pipe}"
156   else
157     read_pipe="/dev/stdin"
158   fi
159   cmd=""
160   # read one key each time from STDIN / pipe
161   read -s -N 1 key < "${read_pipe}"
162   case "${key}" in
163     "m")
164       cmd='MENU'
165       ;;
166     "p")
167       cmd='POWERON'
168       ;;
169     "P")
170       cmd='POWEROFF'
171       ;;
172     "k"|"A") # A is part of the escape sequence sent by the arrow key (^]A)
173       cmd='UP'
174       ;;
175     "j"|"B") # B is part of the escape sequence sent by the arrow key (^]B)
176       cmd='DOWN'
177       ;;
178     "h"|"D") # K is part of the escape sequence sent by the arrow key (^]D)
179       cmd='LEFT'
180       ;;
181     "l"|"C") # C is part of the escape sequence sent by the arrow key (^]C)
182       cmd='RIGHT'
183       ;;
184     "s")
185       cmd='STILL'
186       ;;
187     "1")
188       cmd='INPUTCOMP1'
189       ;;
190     "2")
191       cmd='INPUTCOMP2'
192       ;;
193     "3")
194       cmd='INPUTDVI'
195       ;;
196     "4")
197       cmd='INPUTVIDEO'
198       ;;
199     "5")
200       cmd='INPUTSVIDEO'
201       ;;
202     "")
203       cmd='ENTER'
204       ;;
205     "~")
206       # SPECIAL CMD: toggle VGA1 and DVI
207       # --------------------------------
208       if [ ${pipe_client} -eq 0 ]
209       then
210         # init connection
211         sendCmd ''
212         # request selected input
213         echo -en '00vI\r' > "/dev/${BT_IF}"
214         read -t1 ret < "/dev/${BT_IF}"
215         # ret contains 00vIr1 for VGA1, 00vId1 for DVI
216         case "${ret}" in
217           00vIr1)
218             # VGA1 is active, switch to DVI
219             sendCmd 'INPUTDVI'
220             ;;
221           *)
222             # otherwise switch to VGA1
223             sendCmd 'INPUTCOMP1'
224             ;;
225         esac
226       fi  
227       ;;
228     "Q")
229       exit
230       ;;
231     *)
232       continue
233       ;;
234   esac
235   # just write key to pipe when acting as pipe client
236   # otherwise call sendCmd
237   if [ ${pipe_client} -eq 1 ]
238   then
239     echo -n "${key}" > "${control_pipe}"
240   elif [ -n "${cmd}" ]
241   then
242     echo -n "${cmd}: " > "${output}"
243     # sendCmd returns 0 if projector replied back the sent command
244     #                 1 if serial device is not available
245     #                 2 if projector doesn't reply the sent command within one second
246     if sendCmd "${cmd}"
247     then
248       echo "OK." > "${output}"
249     else
250       echo "failed (err: $?)." > "${output}"
251     fi
252   fi
253 done
254