Mercurial > hg > audiostuff
comparison intercom/intercom.tcl @ 2:13be24d74cd2
import intercom-0.4.1
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 09:57:52 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
1:9cadc470e3da | 2:13be24d74cd2 |
---|---|
1 #!/usr/bin/wish | |
2 | |
3 # intercom.tcl | |
4 # | |
5 # Copyright (C) DFS Deutsche Flugsicherung (2004, 2005). | |
6 # All Rights Reserved. | |
7 # Author: Andre Adrian | |
8 # | |
9 # Voice-over-IP Intercom Graphical User Interface | |
10 # | |
11 # Version 0.3.7 | |
12 # open all UDP sockets before use to fix problem with slow CPUs | |
13 | |
14 | |
15 # UDP "connection" extension for Tcl/Tk | |
16 load /usr/local/lib/libudp1.0.6.so | |
17 | |
18 # ############################################################## | |
19 # Begin Belegt [IS_30] und Umleitung [IS_41] Remote Signallisierung | |
20 | |
21 # intercom.tcl to other intercom.tcl Signalling Receive init | |
22 proc rsig_recv_init {port} { | |
23 set srv [udp_open $port] | |
24 fconfigure $srv -buffering none -translation binary | |
25 fileevent $srv readable [list ::rsig_recv $srv] | |
26 # puts "Listening on udp port: [fconfigure $srv -myport]" | |
27 return $srv | |
28 } | |
29 | |
30 # intercom.tcl to other intercom.tcl Signalling Send init | |
31 proc rsig_send_init {host} { | |
32 global rsig_send_sock | |
33 | |
34 set s [udp_open] | |
35 fconfigure $s -remote [list $host 55004] | |
36 set rsig_send_sock($host) $s | |
37 } | |
38 | |
39 # intercom.tcl to other intercom.tcl Signalling Send | |
40 proc rsig_puts {host str} { | |
41 global rsig_send_sock | |
42 | |
43 puts $rsig_send_sock($host) $str | |
44 flush $rsig_send_sock($host) | |
45 } | |
46 | |
47 # intercom.tcl from other intercom.tcl Signalling Receive | |
48 proc rsig_recv {sock} { | |
49 global ip2tmap tping | |
50 global t_updown umltgmap myipaddr | |
51 | |
52 set msg_body [read $sock] | |
53 set msg_header [fconfigure $sock -peer] | |
54 # puts "udp_server: $msg_header: [string length $msg_body] {$msg_body}" | |
55 | |
56 # to partner is first argument in msg_body | |
57 set argv [split $msg_body] | |
58 set ip_to [lindex $argv 1] | |
59 set t_to $ip2tmap($ip_to) | |
60 | |
61 # from partner is taken from msg_header | |
62 set conn [lindex $msg_header 0] | |
63 set ip_from [lindex $conn 0] | |
64 set t_from $ip2tmap($ip_from) | |
65 | |
66 switch [lindex $argv 0] { | |
67 p {rsig_puts $ip_from "q $ip_to" ;# got application ping | |
68 } | |
69 q {set tping "" ;# got application ping response (pong) | |
70 } | |
71 c {.$t_from configure -highlightbackground cyan ;# got call setup | |
72 incr t_updown($t_from) | |
73 .$t_to configure -highlightbackground cyan | |
74 incr t_updown($t_to) | |
75 } | |
76 h {incr t_updown($t_from) -1 ;# got hangup | |
77 if {$t_updown($t_from) <= 0} { | |
78 set t_updown($t_from) 0 | |
79 .$t_from configure -highlightbackground "#d9d9d9" | |
80 } | |
81 incr t_updown($t_to) -1 | |
82 if {$t_updown($t_to) <= 0} { | |
83 set t_updown($t_to) 0 | |
84 .$t_to configure -highlightbackground "#d9d9d9" | |
85 } | |
86 } | |
87 d { # puts "rsig_recv ip_from=$ip_from ip_to=$ip_to" | |
88 set umltgmap($ip_from) $ip_to ;# got diversion | |
89 # foreach i {1 2 3 4 5 6 7 8} { | |
90 # puts "umltgmap(10.232.35.$i) = $umltgmap(10.232.35.$i)" | |
91 # } | |
92 } | |
93 default {puts "rsig_recv unknown msg=$msg_body"} | |
94 } | |
95 return | |
96 } | |
97 | |
98 # End Belegt [IS_30] und Umleitung [IS_41] Remote Signallisierung | |
99 | |
100 # ############################################################## | |
101 # Begin Stoerung Signalisierung [IS_31] | |
102 | |
103 proc checkping {} { | |
104 global tping | |
105 | |
106 #puts "checkping $tping" | |
107 if {$tping != ""} { | |
108 .$tping configure -background red | |
109 .$tping configure -activebackground red | |
110 .$tping configure -highlightbackground red | |
111 } | |
112 } | |
113 # End Stoerung Signalisierung [IS_31] | |
114 | |
115 # ############################################################## | |
116 # Direct Access Button | |
117 | |
118 # View relevant function Arbeiter | |
119 proc da_update {t state} { | |
120 switch $state { | |
121 0 { .$t configure -foreground black ;# nothing | |
122 .$t configure -activeforeground black | |
123 .$t configure -background "#d9d9d9" ;# button is grey | |
124 .$t configure -activebackground "#d9d9d9"} | |
125 1 { .$t configure -foreground black ;# transmit | |
126 .$t configure -activeforeground black | |
127 .$t configure -background yellow | |
128 .$t configure -activebackground yellow} | |
129 2 { .$t configure -foreground black ;# receive | |
130 .$t configure -activeforeground black | |
131 .$t configure -background magenta | |
132 .$t configure -activebackground magenta} | |
133 3 { .$t configure -foreground black ;# full duplex | |
134 .$t configure -activeforeground black | |
135 .$t configure -background green | |
136 .$t configure -activebackground green} | |
137 } | |
138 } | |
139 | |
140 # View relevant function Vorarbeiter | |
141 proc da_ca_update {t state} { | |
142 global ta_ip ip2tmap | |
143 | |
144 # update DA button | |
145 da_update $t $state | |
146 | |
147 if {[info exists ip2tmap($ta_ip)]} { | |
148 set t_alias $ip2tmap($ta_ip) | |
149 } else { | |
150 set t_alias "" | |
151 } | |
152 | |
153 # Update Common Answer Button | |
154 if { $t_alias == $t } { | |
155 da_update ta $state | |
156 } | |
157 } | |
158 | |
159 # DA/CA button press callback | |
160 proc da_keyPress {t} { | |
161 global t2ipmap state lsig_sock longKey tping umltgmap ip2tmap | |
162 | |
163 set longKey($t) 0 ;# 1 wenn Taste lange gedrückt, sonst 0 | |
164 set ip $t2ipmap($t) ;# ip des remote intercom.tcl | |
165 set uip $umltgmap($ip) ;# Umleitung auf gleiche IP oder andere IP | |
166 | |
167 # avoid two connections to one partner in case of diversion | |
168 if {$ip != $uip} { | |
169 if {$state($t) == 0 || $state($t) == 2} { | |
170 set tumltg $ip2tmap($uip) | |
171 if {$state($tumltg) == 1 || $state($tumltg) == 3} { | |
172 puts "da_keyPress: error: already connection to this partner" | |
173 return | |
174 } | |
175 } | |
176 } | |
177 | |
178 # remote signalling | |
179 switch $state($t) { | |
180 0 {set cmd c | |
181 after 300 [list set longKey($t) 1] | |
182 rsig_puts $uip "p $uip" ;# send application ping | |
183 set tping $t | |
184 after 200 [list checkping]} | |
185 1 {set cmd h} | |
186 2 {set cmd c | |
187 after 300 [list set longKey($t) 1] | |
188 rsig_puts $uip "p $uip" ;# send application ping | |
189 set tping $t | |
190 after 200 [list checkping]} | |
191 3 {set cmd h} | |
192 } | |
193 | |
194 # local signalling to intercomd - maybe with diversion | |
195 puts $lsig_sock "$cmd $uip" | |
196 flush $lsig_sock | |
197 | |
198 # local signalling intercom.tcl - with no diversion | |
199 switch $cmd { | |
200 c {tx_begin $ip} | |
201 r {rx_begin $ip} | |
202 h {tx_end $ip} | |
203 d {rx_end $ip} | |
204 } | |
205 | |
206 # Begin Belegt Signalisierung [IS_30] | |
207 foreach i {t1 t2 t3 t4 t5 t6 t7 t8} { | |
208 set da_ip $t2ipmap($i) | |
209 rsig_puts $da_ip "$cmd $uip" | |
210 } | |
211 # End Belegt Signalisierung [IS_30] | |
212 } | |
213 | |
214 # DA/CA button release callback | |
215 proc da_keyRelease {t} { | |
216 global longKey | |
217 | |
218 if {$longKey($t)} { | |
219 keyPress $t | |
220 } | |
221 } | |
222 | |
223 # ############################################################## | |
224 # Common Answer Button Req IS_14 | |
225 | |
226 proc ca_update {} { | |
227 global ta_ip textmap | |
228 | |
229 # puts "ca_update $ta_ip" | |
230 | |
231 if {[info exists textmap($ta_ip)]} { | |
232 set ta_text $textmap($ta_ip) | |
233 } else { | |
234 set ta_text $ta_ip | |
235 } | |
236 .ta configure -text $ta_text | |
237 } | |
238 | |
239 # ############################################################## | |
240 # Diversion (Umleitung) Req. IS_41 | |
241 | |
242 # Update Umleitungstaste Req. IS_41 | |
243 proc umltg_update {} { | |
244 global umltg_state tu_ip ip2tmap | |
245 | |
246 if {[info exists tu_ip]} { | |
247 set told $ip2tmap($tu_ip) | |
248 .$told configure -background "#d9d9d9" | |
249 .$told configure -activebackground "#d9d9d9" | |
250 } | |
251 switch $umltg_state { | |
252 0 { .tu configure -background "#d9d9d9" | |
253 .tu configure -activebackground "#d9d9d9" | |
254 .tu configure -text "" | |
255 } | |
256 1 { .tu configure -background orange | |
257 .tu configure -activebackground orange | |
258 } | |
259 } | |
260 } | |
261 | |
262 # Diversion Button callback | |
263 proc umltg_keyRelease {} { | |
264 global umltg_state myipaddr t2ipmap | |
265 | |
266 switch $umltg_state { | |
267 0 {set umltg_state 1} | |
268 1 {set umltg_state 0 | |
269 # Diversion release == Diversion to myipaddr | |
270 foreach i {t1 t2 t3 t4 t5 t6 t7 t8} { | |
271 set da_ip $t2ipmap($i) | |
272 rsig_puts $da_ip "d $myipaddr" | |
273 } | |
274 } | |
275 } | |
276 umltg_update | |
277 } | |
278 | |
279 # Direct Access Buttons callback | |
280 proc umltg_da_keyRelease {t} { | |
281 global t2ipmap textmap tu_ip ip2tmap myipaddr umltg_state | |
282 | |
283 # alten Zustand deaktivieren und updaten | |
284 umltg_update | |
285 | |
286 # Model variable ändern | |
287 set tu_ip $t2ipmap($t) | |
288 | |
289 # neuen Zustand updaten | |
290 .$t configure -background orange | |
291 .$t configure -activebackground orange | |
292 set tu_text $textmap($tu_ip) | |
293 .tu configure -text $tu_text | |
294 | |
295 # Begin Umleitung Signalisierung [IS_41] | |
296 foreach i {t1 t2 t3 t4 t5 t6 t7 t8} { | |
297 set da_ip $t2ipmap($i) | |
298 rsig_puts $da_ip "d $tu_ip" | |
299 } | |
300 # End Umleitung Signalisierung [IS_41] | |
301 } | |
302 | |
303 # ############################################################## | |
304 # Direct Access / Diversion Buttons Callbacks | |
305 | |
306 proc keyPress {t} { | |
307 global umltg_state | |
308 | |
309 switch $umltg_state { | |
310 0 {da_keyPress $t} | |
311 1 {} | |
312 } | |
313 } | |
314 | |
315 proc keyRelease {t} { | |
316 global umltg_state told | |
317 | |
318 switch $umltg_state { | |
319 0 {da_keyRelease $t} | |
320 1 {umltg_da_keyRelease $t} | |
321 } | |
322 } | |
323 | |
324 # ############################################################## | |
325 # Direct Access model relevant function | |
326 | |
327 proc tx_begin {ip} { | |
328 global ip2tmap state | |
329 | |
330 set t $ip2tmap($ip) | |
331 #puts "tx_begin $ip $t" | |
332 switch $state($t) { | |
333 0 {set state($t) 1} | |
334 1 { } | |
335 2 {set state($t) 3} | |
336 3 { } | |
337 } | |
338 da_ca_update $t $state($t) | |
339 } | |
340 | |
341 proc rx_begin {ip} { | |
342 global ip2tmap state | |
343 | |
344 set t $ip2tmap($ip) | |
345 #puts "rx_begin $ip $t" | |
346 switch $state($t) { | |
347 0 {set state($t) 2} | |
348 1 {set state($t) 3} | |
349 2 { } | |
350 3 { } | |
351 } | |
352 | |
353 # Answer Button Req IS_14 | |
354 global ta_ip | |
355 | |
356 set ta_ip $ip | |
357 ca_update | |
358 | |
359 .ta configure -command [list keyRelease $t] | |
360 bind .ta <ButtonPress-1> [list keyPress $t] | |
361 # End Answer Button Req IS_14 | |
362 | |
363 da_ca_update $t $state($t) | |
364 } | |
365 | |
366 proc tx_end {ip} { | |
367 global ip2tmap state | |
368 | |
369 set t $ip2tmap($ip) | |
370 #puts "tx_end $ip $t" | |
371 switch $state($t) { | |
372 0 {} | |
373 1 {set state($t) 0} | |
374 2 { } | |
375 3 {set state($t) 2} | |
376 } | |
377 da_ca_update $t $state($t) | |
378 } | |
379 | |
380 proc rx_end {ip} { | |
381 global ip2tmap state | |
382 | |
383 set t $ip2tmap($ip) | |
384 #puts "rx_end $ip $t" | |
385 switch $state($t) { | |
386 0 { } | |
387 1 { } | |
388 2 {set state($t) 0} | |
389 3 {set state($t) 1} | |
390 } | |
391 da_ca_update $t $state($t) | |
392 } | |
393 | |
394 # ############################################################## | |
395 # Local Signalling | |
396 | |
397 # intercom.tcl from own intercomd Signalling Receive | |
398 proc lsig_recv {} { | |
399 global lsig_sock | |
400 | |
401 gets $lsig_sock cmd | |
402 # puts "lsig_recv $cmd" | |
403 set argv [split $cmd] | |
404 # puts $argv | |
405 set ip [lindex $argv 1] | |
406 switch [lindex $argv 0] { | |
407 c {tx_begin $ip} | |
408 r {rx_begin $ip} | |
409 h {tx_end $ip} | |
410 d {rx_end $ip} | |
411 } | |
412 } | |
413 | |
414 # ############################################################## | |
415 # Program exit (abort, close) Handler | |
416 | |
417 proc onDestroy {} { | |
418 global destroyflag lsig_sock rsig_recv_sock | |
419 | |
420 if {$destroyflag == 0} { | |
421 set destroyflag 1 | |
422 puts "Terminate intercomd and intercom" | |
423 close $lsig_sock | |
424 close $rsig_recv_sock | |
425 exec /usr/bin/killall -9 /usr/local/bin/intercomd \ | |
426 /usr/local/bin/intercomd1 | |
427 } | |
428 } | |
429 | |
430 # ############################################################## | |
431 # Read configuration file - hack just use Tcl/Tk parser | |
432 | |
433 proc guiconfig {t text ip} { | |
434 global state longKey ip2tmap t2ipmap umltgmap | |
435 | |
436 set state($t) 0 | |
437 set longKey($t) 0 | |
438 | |
439 rsig_send_init $ip | |
440 | |
441 set ip2tmap($ip) $t | |
442 set t2ipmap($t) $ip | |
443 | |
444 set umltgmap($ip) $ip ;# keine Umleitung | |
445 | |
446 .$t configure -text $text | |
447 .$t configure -command [list keyRelease $t] | |
448 bind .$t <ButtonPress-1> [list keyPress $t] | |
449 | |
450 # Answer Button Req IS_14 | |
451 global textmap | |
452 | |
453 set textmap($ip) $text | |
454 | |
455 da_ca_update $t $state($t) | |
456 } | |
457 | |
458 # ############################################################## | |
459 # Begin main | |
460 | |
461 # init and register programm termination handler | |
462 set destroyflag 0 | |
463 bind . <Destroy> [list onDestroy] | |
464 | |
465 # include GUI | |
466 source /usr/local/bin/intercom.ui.tcl | |
467 intercom_ui . | |
468 | |
469 # init model | |
470 foreach {i} {t1 t2 t3 t4 t5 t6 t7 t8} { | |
471 set t_updown($i) 0 | |
472 } | |
473 | |
474 # init view | |
475 foreach {i} {t1 t2 t3 t4 t5 t6 t7 t8 ta tu} { | |
476 .$i configure -width 5 -height 2 -highlightthickness 12 | |
477 } | |
478 | |
479 # init Common Answer-Button Req. IS_14 | |
480 set ta_ip "" | |
481 | |
482 # init and register Diversion Req. IS_41 | |
483 set umltg_state 0 | |
484 .tu configure -command [list umltg_keyRelease] | |
485 | |
486 # include configuration | |
487 if {[file exists ~/.intercom.conf]} { | |
488 source ~/.intercom.conf | |
489 } else { | |
490 file copy /usr/local/bin/intercom.conf ~/.intercom.conf | |
491 puts "" | |
492 puts "Please edit the file ~/.intercom.conf for your Labels and your" | |
493 puts "IP-addresses. Then start intercom again." | |
494 exit | |
495 } | |
496 | |
497 # init local signalling to intercomd, a TCP connection | |
498 set lsig_sock [socket 127.0.0.1 4999] | |
499 fileevent $lsig_sock readable lsig_recv | |
500 | |
501 # init remote signalling to intercom.tcl, an UDP "connection" | |
502 set rsig_recv_sock [rsig_recv_init 55004] | |
503 | |
504 # set window title | |
505 set nodename [exec uname -n] | |
506 wm title . "intercom $nodename" | |
507 | |
508 # hack: get my ip address | |
509 set hostsline [exec grep $nodename /etc/hosts] | |
510 set myipaddr [lindex [split $hostsline] 0] | |
511 | |
512 # End main | |
513 # ############################################################## |