Mercurial > hg > audiostuff
view intercom/intercom.tcl @ 6:22a74b01a099 default tip
implement more meaningful test program
author | Peter Meerwald <pmeerw@cosy.sbg.ac.at> |
---|---|
date | Fri, 25 Jun 2010 16:14:50 +0200 |
parents | 13be24d74cd2 |
children |
line wrap: on
line source
#!/usr/bin/wish # intercom.tcl # # Copyright (C) DFS Deutsche Flugsicherung (2004, 2005). # All Rights Reserved. # Author: Andre Adrian # # Voice-over-IP Intercom Graphical User Interface # # Version 0.3.7 # open all UDP sockets before use to fix problem with slow CPUs # UDP "connection" extension for Tcl/Tk load /usr/local/lib/libudp1.0.6.so # ############################################################## # Begin Belegt [IS_30] und Umleitung [IS_41] Remote Signallisierung # intercom.tcl to other intercom.tcl Signalling Receive init proc rsig_recv_init {port} { set srv [udp_open $port] fconfigure $srv -buffering none -translation binary fileevent $srv readable [list ::rsig_recv $srv] # puts "Listening on udp port: [fconfigure $srv -myport]" return $srv } # intercom.tcl to other intercom.tcl Signalling Send init proc rsig_send_init {host} { global rsig_send_sock set s [udp_open] fconfigure $s -remote [list $host 55004] set rsig_send_sock($host) $s } # intercom.tcl to other intercom.tcl Signalling Send proc rsig_puts {host str} { global rsig_send_sock puts $rsig_send_sock($host) $str flush $rsig_send_sock($host) } # intercom.tcl from other intercom.tcl Signalling Receive proc rsig_recv {sock} { global ip2tmap tping global t_updown umltgmap myipaddr set msg_body [read $sock] set msg_header [fconfigure $sock -peer] # puts "udp_server: $msg_header: [string length $msg_body] {$msg_body}" # to partner is first argument in msg_body set argv [split $msg_body] set ip_to [lindex $argv 1] set t_to $ip2tmap($ip_to) # from partner is taken from msg_header set conn [lindex $msg_header 0] set ip_from [lindex $conn 0] set t_from $ip2tmap($ip_from) switch [lindex $argv 0] { p {rsig_puts $ip_from "q $ip_to" ;# got application ping } q {set tping "" ;# got application ping response (pong) } c {.$t_from configure -highlightbackground cyan ;# got call setup incr t_updown($t_from) .$t_to configure -highlightbackground cyan incr t_updown($t_to) } h {incr t_updown($t_from) -1 ;# got hangup if {$t_updown($t_from) <= 0} { set t_updown($t_from) 0 .$t_from configure -highlightbackground "#d9d9d9" } incr t_updown($t_to) -1 if {$t_updown($t_to) <= 0} { set t_updown($t_to) 0 .$t_to configure -highlightbackground "#d9d9d9" } } d { # puts "rsig_recv ip_from=$ip_from ip_to=$ip_to" set umltgmap($ip_from) $ip_to ;# got diversion # foreach i {1 2 3 4 5 6 7 8} { # puts "umltgmap(10.232.35.$i) = $umltgmap(10.232.35.$i)" # } } default {puts "rsig_recv unknown msg=$msg_body"} } return } # End Belegt [IS_30] und Umleitung [IS_41] Remote Signallisierung # ############################################################## # Begin Stoerung Signalisierung [IS_31] proc checkping {} { global tping #puts "checkping $tping" if {$tping != ""} { .$tping configure -background red .$tping configure -activebackground red .$tping configure -highlightbackground red } } # End Stoerung Signalisierung [IS_31] # ############################################################## # Direct Access Button # View relevant function Arbeiter proc da_update {t state} { switch $state { 0 { .$t configure -foreground black ;# nothing .$t configure -activeforeground black .$t configure -background "#d9d9d9" ;# button is grey .$t configure -activebackground "#d9d9d9"} 1 { .$t configure -foreground black ;# transmit .$t configure -activeforeground black .$t configure -background yellow .$t configure -activebackground yellow} 2 { .$t configure -foreground black ;# receive .$t configure -activeforeground black .$t configure -background magenta .$t configure -activebackground magenta} 3 { .$t configure -foreground black ;# full duplex .$t configure -activeforeground black .$t configure -background green .$t configure -activebackground green} } } # View relevant function Vorarbeiter proc da_ca_update {t state} { global ta_ip ip2tmap # update DA button da_update $t $state if {[info exists ip2tmap($ta_ip)]} { set t_alias $ip2tmap($ta_ip) } else { set t_alias "" } # Update Common Answer Button if { $t_alias == $t } { da_update ta $state } } # DA/CA button press callback proc da_keyPress {t} { global t2ipmap state lsig_sock longKey tping umltgmap ip2tmap set longKey($t) 0 ;# 1 wenn Taste lange gedrückt, sonst 0 set ip $t2ipmap($t) ;# ip des remote intercom.tcl set uip $umltgmap($ip) ;# Umleitung auf gleiche IP oder andere IP # avoid two connections to one partner in case of diversion if {$ip != $uip} { if {$state($t) == 0 || $state($t) == 2} { set tumltg $ip2tmap($uip) if {$state($tumltg) == 1 || $state($tumltg) == 3} { puts "da_keyPress: error: already connection to this partner" return } } } # remote signalling switch $state($t) { 0 {set cmd c after 300 [list set longKey($t) 1] rsig_puts $uip "p $uip" ;# send application ping set tping $t after 200 [list checkping]} 1 {set cmd h} 2 {set cmd c after 300 [list set longKey($t) 1] rsig_puts $uip "p $uip" ;# send application ping set tping $t after 200 [list checkping]} 3 {set cmd h} } # local signalling to intercomd - maybe with diversion puts $lsig_sock "$cmd $uip" flush $lsig_sock # local signalling intercom.tcl - with no diversion switch $cmd { c {tx_begin $ip} r {rx_begin $ip} h {tx_end $ip} d {rx_end $ip} } # Begin Belegt Signalisierung [IS_30] foreach i {t1 t2 t3 t4 t5 t6 t7 t8} { set da_ip $t2ipmap($i) rsig_puts $da_ip "$cmd $uip" } # End Belegt Signalisierung [IS_30] } # DA/CA button release callback proc da_keyRelease {t} { global longKey if {$longKey($t)} { keyPress $t } } # ############################################################## # Common Answer Button Req IS_14 proc ca_update {} { global ta_ip textmap # puts "ca_update $ta_ip" if {[info exists textmap($ta_ip)]} { set ta_text $textmap($ta_ip) } else { set ta_text $ta_ip } .ta configure -text $ta_text } # ############################################################## # Diversion (Umleitung) Req. IS_41 # Update Umleitungstaste Req. IS_41 proc umltg_update {} { global umltg_state tu_ip ip2tmap if {[info exists tu_ip]} { set told $ip2tmap($tu_ip) .$told configure -background "#d9d9d9" .$told configure -activebackground "#d9d9d9" } switch $umltg_state { 0 { .tu configure -background "#d9d9d9" .tu configure -activebackground "#d9d9d9" .tu configure -text "" } 1 { .tu configure -background orange .tu configure -activebackground orange } } } # Diversion Button callback proc umltg_keyRelease {} { global umltg_state myipaddr t2ipmap switch $umltg_state { 0 {set umltg_state 1} 1 {set umltg_state 0 # Diversion release == Diversion to myipaddr foreach i {t1 t2 t3 t4 t5 t6 t7 t8} { set da_ip $t2ipmap($i) rsig_puts $da_ip "d $myipaddr" } } } umltg_update } # Direct Access Buttons callback proc umltg_da_keyRelease {t} { global t2ipmap textmap tu_ip ip2tmap myipaddr umltg_state # alten Zustand deaktivieren und updaten umltg_update # Model variable ändern set tu_ip $t2ipmap($t) # neuen Zustand updaten .$t configure -background orange .$t configure -activebackground orange set tu_text $textmap($tu_ip) .tu configure -text $tu_text # Begin Umleitung Signalisierung [IS_41] foreach i {t1 t2 t3 t4 t5 t6 t7 t8} { set da_ip $t2ipmap($i) rsig_puts $da_ip "d $tu_ip" } # End Umleitung Signalisierung [IS_41] } # ############################################################## # Direct Access / Diversion Buttons Callbacks proc keyPress {t} { global umltg_state switch $umltg_state { 0 {da_keyPress $t} 1 {} } } proc keyRelease {t} { global umltg_state told switch $umltg_state { 0 {da_keyRelease $t} 1 {umltg_da_keyRelease $t} } } # ############################################################## # Direct Access model relevant function proc tx_begin {ip} { global ip2tmap state set t $ip2tmap($ip) #puts "tx_begin $ip $t" switch $state($t) { 0 {set state($t) 1} 1 { } 2 {set state($t) 3} 3 { } } da_ca_update $t $state($t) } proc rx_begin {ip} { global ip2tmap state set t $ip2tmap($ip) #puts "rx_begin $ip $t" switch $state($t) { 0 {set state($t) 2} 1 {set state($t) 3} 2 { } 3 { } } # Answer Button Req IS_14 global ta_ip set ta_ip $ip ca_update .ta configure -command [list keyRelease $t] bind .ta <ButtonPress-1> [list keyPress $t] # End Answer Button Req IS_14 da_ca_update $t $state($t) } proc tx_end {ip} { global ip2tmap state set t $ip2tmap($ip) #puts "tx_end $ip $t" switch $state($t) { 0 {} 1 {set state($t) 0} 2 { } 3 {set state($t) 2} } da_ca_update $t $state($t) } proc rx_end {ip} { global ip2tmap state set t $ip2tmap($ip) #puts "rx_end $ip $t" switch $state($t) { 0 { } 1 { } 2 {set state($t) 0} 3 {set state($t) 1} } da_ca_update $t $state($t) } # ############################################################## # Local Signalling # intercom.tcl from own intercomd Signalling Receive proc lsig_recv {} { global lsig_sock gets $lsig_sock cmd # puts "lsig_recv $cmd" set argv [split $cmd] # puts $argv set ip [lindex $argv 1] switch [lindex $argv 0] { c {tx_begin $ip} r {rx_begin $ip} h {tx_end $ip} d {rx_end $ip} } } # ############################################################## # Program exit (abort, close) Handler proc onDestroy {} { global destroyflag lsig_sock rsig_recv_sock if {$destroyflag == 0} { set destroyflag 1 puts "Terminate intercomd and intercom" close $lsig_sock close $rsig_recv_sock exec /usr/bin/killall -9 /usr/local/bin/intercomd \ /usr/local/bin/intercomd1 } } # ############################################################## # Read configuration file - hack just use Tcl/Tk parser proc guiconfig {t text ip} { global state longKey ip2tmap t2ipmap umltgmap set state($t) 0 set longKey($t) 0 rsig_send_init $ip set ip2tmap($ip) $t set t2ipmap($t) $ip set umltgmap($ip) $ip ;# keine Umleitung .$t configure -text $text .$t configure -command [list keyRelease $t] bind .$t <ButtonPress-1> [list keyPress $t] # Answer Button Req IS_14 global textmap set textmap($ip) $text da_ca_update $t $state($t) } # ############################################################## # Begin main # init and register programm termination handler set destroyflag 0 bind . <Destroy> [list onDestroy] # include GUI source /usr/local/bin/intercom.ui.tcl intercom_ui . # init model foreach {i} {t1 t2 t3 t4 t5 t6 t7 t8} { set t_updown($i) 0 } # init view foreach {i} {t1 t2 t3 t4 t5 t6 t7 t8 ta tu} { .$i configure -width 5 -height 2 -highlightthickness 12 } # init Common Answer-Button Req. IS_14 set ta_ip "" # init and register Diversion Req. IS_41 set umltg_state 0 .tu configure -command [list umltg_keyRelease] # include configuration if {[file exists ~/.intercom.conf]} { source ~/.intercom.conf } else { file copy /usr/local/bin/intercom.conf ~/.intercom.conf puts "" puts "Please edit the file ~/.intercom.conf for your Labels and your" puts "IP-addresses. Then start intercom again." exit } # init local signalling to intercomd, a TCP connection set lsig_sock [socket 127.0.0.1 4999] fileevent $lsig_sock readable lsig_recv # init remote signalling to intercom.tcl, an UDP "connection" set rsig_recv_sock [rsig_recv_init 55004] # set window title set nodename [exec uname -n] wm title . "intercom $nodename" # hack: get my ip address set hostsline [exec grep $nodename /etc/hosts] set myipaddr [lindex [split $hostsline] 0] # End main # ##############################################################