# Copyright (c) 2001 Courtney Bailey Court_Bailey@bigfoot.com # Phone Connection for TivoWeb # development Status: # V .1a - Added Daily Call # V .3a - Inital Event Capture # V .5a - Revised Event Capture # V .7a - JavaScript # V .9b - First Beta # V 1.4b - lots of headaches later we have a poor man's server push # V 1.5.2F - Cleaned code, made "Guide Data TO" more fault tolerrant # V 1.5.5F - Completly change how we get "Guide data to:" again =P # V 1.5.6F - Add Assoc Array for Data, and decreased reload time # V 1.6 - Make the TmkEvent calls conditional on software version # # $Id: phone.itcl,v 1.2 2005/08/03 06:02:46 davidlallen Exp $ if {$::version > 4} {continue} # ---------Debuging function # Prints Event Data to console when enabled, surf to "http://tivo/Pbug" to toggle proc action_Pbug {chan path env} { global PHInfo if { $PHInfo(Debug_mode) == 0 } { set PHInfo(Debug_mode) 1 } else { set PHInfo(Debug_mode) 0 } action_Phone $chan $path $env } # --------- End Debug function #config variables and Constants need for Calls catch {source $tcl_library/tv/StatusStrings.itcl} # --------- config/Start Event Capture for Dialup Events # Our Callback function borrowed from screenTestsFramework proc DialupCallback { type subtype } { global EventData PHInfo switch -exact -- $subtype { 0 { set info "IMMEDIATE"; set PHInfo(CallInProgress) 1; set PHInfo(Data) [PHGetMessage 4]; set PHInfo(Stat) 4} 1 { set info "config" } 2 { set info "HEADEND" } 3 { set info "TEST"; set PHInfo(CallInProgress) 1; set PHInfo(Data) [PHGetMessage 4]; set PHInfo(Stat) 4} 4 { set info "TESTSTRING" } 5 { set info "ALLHEADENDS" } 6 { set info "FORCE" } 7 { set info "SUCCEED"; set PHInfo(CallInProgress) 0; set PHInfo(Stat) $PHInfo(Stat)} 8 { set info "FAIL"; set PHInfo(CallInProgress) 0; set PHInfo(Stat) $PHInfo(Stat) } 9 { set info "CHANGE"; set PHInfo(CallInProgress) 1 } 10 { set info "ONLINE" } 11 { set info "OFFLINE" } default { set info "XXX" } } binary scan $EventData c20 bytes set data "EventData: $bytes" set PHInfo(Debug) $data if { $info == "CHANGE" } { regsub "\000.*\$" $EventData {} data append info " $data" regsub -nocase {[a-z][a-z][\|]} $data {} PHInfo(Stat) if { $PHInfo(Stat) == 30 } { #give those good people not using modems their LED back if {$::version < 6} { event send $TmkEvent::EVT_DIALUPEVENT 10 0 } } if { [regexp {%} $PHInfo(Stat)] } { set PHInfo(Data) "Loading Data... $PHInfo(Stat)" set PHInfo(Stat) 42 } else { set PHInfo(Data) [PHGetMessage $PHInfo(Stat)] } } append PHInfo(Debug) " $info" if { $PHInfo(Debug_mode) == 1 } { puts "Phone.itcl: $PHInfo(Debug)" } } # Start Capture of Dialup Events event connect # # The registration of a callback can help trigger the v3.0 Event Bug # So let's only do it if the user actually tries to use the module. # if {$reload == 0} { set phone_callback 0 } proc setup_CallBack {} { global phone_callback if {$::version < 6 && $phone_callback == 0} { set phone_callback 1 event register $TmkEvent::EVT_DIALUPEVENT DialupCallback } } # --------- End Event Capture # --------- Phone Body # Daily Call proc action_Dcall {chan path env} { global PHInfo setup_CallBack if { $PHInfo(CallInProgress) == 0 } { set PHInfo(CallInProgress) 1 set PHInfo(Data) [PHGetMessage 4] set PHInfo(Stat) 4 set Daily [binary format c20 "127 -60 126 100 127 -1 -15 -80 1 -78 92 -56 127 -18 -5 116 127 -75 -91 -8"] if {$::version < 6} { event send $TmkEvent::EVT_DIALUPEVENT 0 $Daily } } action_Phone $chan $path $env } # Test Call proc action_Tcall {chan path env} { global PHInfo setup_CallBack if { $PHInfo(CallInProgress) == 0 } { set PHInfo(CallInProgress) 1 set PHInfo(Data) [PHGetMessage 4] set PHInfo(Stat) 4 set Test [binary format c20 "127 -65 98 28 127 -1 -17 -80 0 0 0 0 127 -1 -16 56 127 -76 42 40"] if {$::version < 6} { event send $TmkEvent::EVT_DIALUPEVENT 3 $Test } } action_Phone $chan $path $env } proc action_Phone {chan path env} { global PHInfo action_Phone_UI $chan $path $env if { $PHInfo(CallInProgress) == 1 } { catch {flush $chan} vwait PHInfo(Stat) puts $chan "" } } # User Interface proc action_Phone_UI {chan path env} { puts $chan [html_start "Phone"] global tivoswversion global PHInfo global phone_callback PHUpdateData if {$::lang == "en"} { set seconds [expr $PHInfo(GuideDataTo) * 86400] set daystr [nth [clock format $seconds -format "%e"]] set CD_gdt [clock format $seconds -format "%A, $daystr %b %Y"] set seconds [expr $PHInfo(LastSuccessCall)] set daystr [nth [ftime $seconds "%e"]] set CD_lsc [ftime $seconds "%A, $daystr %b at %H:%M"] set seconds [expr $PHInfo(LastCallAttempt)] set daystr [nth [ftime $seconds "%e"]] set CD_lca [ftime $seconds "%A, $daystr %b at %H:%M"] set seconds [expr $PHInfo(NextCallAttempt)] set daystr [nth [ftime $seconds "%e"]] set CD_nsc [ftime $seconds "%A, $daystr %b at %H:%M"] } else { set CD_gdt [clock format [expr $PHInfo(GuideDataTo) * 86400] -format "%A, %b %d, %Y"] set CD_lsc [ftime [expr $PHInfo(LastSuccessCall)] "%A, %b %d at %1I:%M %P"] set CD_lca [ftime [expr $PHInfo(LastCallAttempt)] "%A, %b %d at %1I:%M %P"] set CD_nsc [ftime [expr $PHInfo(NextCallAttempt)] "%A, %b %d at %1I:%M %P"] } set CD_las $PHInfo(LastCallStatus) puts $chan "
" puts $chan [html_table_start "" "" ""] if { $PHInfo(Debug_mode) == 0 } { puts $chan [tr "" [th "COLSPAN=2" "Calls and Updates"]] } else { puts $chan [tr "" [th "COLSPAN=2" "Calls and Updates - Debug"]] } puts $chan [tr "" [td "" "Last Successful Call:"][td "" "" ]] puts $chan [tr "" [td "" "Last Call Attempt:"] [td "" "" ]] puts $chan [tr "" [td "" "Last Attempt Status:"] [td "" "" ]] puts $chan [tr "" [td "" "Next Scheduled Call: "] [td "" "" ]] puts $chan [tr "" [td "" "Prog. Guide Data to:"] [td "" "" ]] puts $chan [tr "" [td "" "Software Version:"] [td "" "" ]] # If Call is in progress we do not want the user starting another if { $PHInfo(CallInProgress) == 0 } { puts $chan [tr "" [td "" [html_link "/Tcall" "Make Test Call Now"]] [td "" [html_link "/Dcall" "Make Daily Call Now" ]]] } else { puts $chan [tr "" [td "" [html_link "JavaScript:alert('Call Currently In Progress!!! Please Wait!!!');document.location=/Phone/;" "Make Test Call Now"]] [td "" [html_link "JavaScript:alert('Call Currently In Progress!!! Please Wait!!!');document.location=/Phone/;" "Make Daily Call Now" ]]] } puts $chan [html_table_end] puts $chan [html_form_end] if {$phone_callback == 1} { puts $chan "Callback is active" } puts $chan [html_end] } # --------- End Phone Body # --------- Update Data proc PHUpdateData { } { global db PHInfo set continue 0 if { $PHInfo(CallInProgress) == 1} { set PHInfo(LastCallStatus) $PHInfo(Data) return } if {$::version >= 3} { set config "/State/PhoneConfig" set suffix "SecInDay" } else { set config "/Setup" set suffix "" } RetryTransaction { set config [db $db open $config] set LastCallAttempt [dbobj $config get LastCallAttempt$suffix] if { $LastCallAttempt > $PHInfo(LastCallAttempt) } { set PHInfo(LastCallAttempt) $LastCallAttempt if {$::version >= 3} { set serviceinfo $config } else { set serviceinfo [dbobj $config get ServiceInfo] } set LastCallStatus [dbobj $config get LastCallStatus] if { $LastCallStatus == "Failed"} { set csi [dbobj $serviceinfo get CallStatusInfo] if {$csi != "Failed" } { regexp {[0-9]+} $csi LastCallStatus set LastCallStatus [PHGetMessage $LastCallStatus] } } regsub {(\{([A-Za-z]+)+\})} $LastCallStatus {\2} PHInfo(LastCallStatus) set PHInfo(LastSuccessCall) [dbobj $config get LastSuccessCall$suffix] set PHInfo(NextCallAttempt) [dbobj $config get NextCallAttempt$suffix] set continue 1 } } # while { $continue == 1 } { set PHInfo(GuideDataTo) [PHGetGuideDays] # if { $PHInfo(CallInProgress) != 1 && $PHInfo(GuideDataTo) <= 0 } { # set continue 1 # } else { # set continue 0 # } # } } # --------- End Update Data # --------- Start GetGuideDays proc PHGetGuideDays { } { set count 0 set lastday 0 ForeachMfsFile fsid name type /Schedule "" { set date [lindex [split $name ":"] 1] if { $date > $lastday } { set lastday $date } incr count if { $count >= 100 } { return $lastday } } return $lastday } # --------- End GetGuideDays # --------- Start GetMessage # Replaces PHInfo(Messages) global variable proc PHGetMessage { item } { return [lindex {"Blank" "Succeeded" "PendingRestart" \ "InitializationFailure" "SettingUp" "InProgress" \ "UnknownError" "Failure during Housekeeping" \ "Failure during Preparation" "Failed. Line unavailable" \ "Failed. No dial tone" "Failed. Couldn't dial" "Failed. Wrong number" \ "Failed. Service is not answering" "Failed. Service unavailable" \ "Failed. Service denied" "Failed. Call interrupted" \ "Failed while expanding data" "Failed while preparing data" \ "Failed while loading series" "Failed while indexing shows" "Failed to set clock" \ "Failed getting account status" "Failure downloading messages" "Failed. Phone is busy" \ "Failed while indexing days" "Failed getting account status" "In Progress" \ "Housekeeping" "Preparing to call" "Dialing..." "Answering..." "Answered" \ "Connecting..." "Getting account status" "Setting clock..." "Downloading messages" \ "Processing..." "Downloading..." "Hanging up" "Expanding data" "Preparing data" \ "Loading data" "Indexing series" "Indexing shows" "Indexing days" \ "Failed. Modem is not responding" "Configuring modem" "Failed. No dial-in number chosen." \ "Finishing up..."} $item ] } # --------- End GetMessage # Get init values if { $reload == 0 } { # --------- Phone Data Array global PHInfo array set PHInfo [list \ {Debug} {""} \ {Debug_mode} {0} \ {Stat} {-1} \ {Data} {""} \ {CallInProgress} {0} \ {GuideDataTo} {0} \ {LastCallStatus} {0} \ {LastSuccessCall} {0} \ {LastCallAttempt} {0} \ {NextCallAttempt} {0} ] # --------- End Phone Data Array PHUpdateData } # Register module with TiVoWeb register_module "Phone" "Phone" "Phone Connection"