# app_hookflash.tcl
#
# written by Bryan Deaver based on the default session application.
# This is an example of converting a * dtmf event into hookflash out the fxo port.
#
# This is written as is with no claims of support. It has been shown to work
# to convert a * h245-alhpanumeric event from callmanager while running on a c2800
# gateway running 12.4(20)T. There are other modifications that would be done
# for example look at * 8 before forwarding the other digits.
# Or converting an A/B/C/D dtmf event into hookflash to interwork with
# other applications. If you find a useful modification, please do drop me a note
# at bdeaver@cisco.com
#
# This is based upon the default session application as seen with
# "show call application voice session" on the router. This provides an
# easy start by which to modify scripts to fit your needs.
#
# The modification of the session script was to add the act_ProcessDTMF function,
# add a section to look for digits coming in from the outgoing call leg
# as well as add an entry to the fsm table.
#
#---------------------------------
# Example Script
#-----------------
proc act_Setup { } {
global dest
global beep
set beep 0
if { [infotag get leg_isdid] } {
set dest [infotag get leg_dnis]
leg proceeding leg_incoming
leg setup $dest callInfo leg_incoming
fsm setstate PLACECALL
} else {
leg setupack leg_incoming
playtone leg_incoming tn_dial
set param(dialPlan) true
leg collectdigits leg_incoming param
}
}
proc act_GotDest { } {
global dest
set status [infotag get evt_status]
if { $status == "cd_004" } {
set dest [infotag get evt_dcdigits]
leg proceeding leg_incoming
leg setup $dest callInfo leg_incoming
} else {
puts "\nCall [infotag get con_all] got event $status collecting destination"
# use invalid-number cause code
leg disconnect leg_incoming -c28
call close
}
}
# here is the process that intercepts the '*' and sends out a hookflash
proc act_ProcessDTMF { } {
# get the dtmf and duration
set dtmf_value [infotag get evt_digit]
set dtmf_duration [infotag get evt_digit_duration]
if {$dtmf_value == "A"} {
leg sendhookflash leg_incoming
} else {
# ok, not a * so playout the dtmf event with the same duration
leg senddigit leg_incoming $dtmf_value -t $dtmf_duration
}
}
proc act_CallSetupDone { } {
global beep
set status [infotag get evt_status]
if { $status == "ls_000"} {
set creditTimeLeft [infotag get leg_settlement_time leg_all]
if { ($creditTimeLeft == "unlimited") ||
($creditTimeLeft == "uninitialized") } {
puts "\n Unlimited Time"
} else {
# start the timer for ...
if { $creditTimeLeft < 10 } {
set beep 1
set delay $creditTimeLeft
} else {
set delay [expr $creditTimeLeft - 10]
}
timer start leg_timer $delay leg_incoming
}
# setup the outgoing leg to monitor for digits
set param(consumeDigit) true
set param(enableReporting) true
leg collectdigits leg_outgoing param
} else {
puts "Call [infotag get con_all] got event $status collecting destination"
call close
}
}
proc act_Timer { } {
global beep
global incoming
global outgoing
set incoming [infotag get leg_incoming]
set outgoing [infotag get leg_outgoing]
if { $beep == 0 } {
#insert a beep ...to the caller
connection destroy con_all
set beep 1
} else {
connection destroy con_all
fsm setstate LASTWARN
}
}
proc act_LastWarn { } {
media play leg_incoming flash:out_of_time.au }
proc act_Destroy { } {
media play leg_incoming flash:beep.au }
proc act_Beeped { } {
global incoming
global outgoing
connection create $incoming $outgoing }
proc act_ConnectedAgain { } {
timer start leg_timer 10 leg_incoming }
proc act_Ignore { } {
# Dummy
puts "Event Capture"
}
proc act_Cleanup { } {
call close
}
#------------------
# State Machine
#----------------------------------
set fsm(any_state,ev_disconnected) "act_Cleanup same_state"
set fsm(any_state,ev_digit_end) "act_ProcessDTMF same_state"
set fsm(CALL_INIT,ev_setup_indication) "act_Setup GETDEST"
set fsm(GETDEST,ev_collectdigits_done) "act_GotDest PLACECALL"
set fsm(PLACECALL,ev_setup_done) "act_CallSetupDone CALLACTIVE"
set fsm(CALLACTIVE,ev_leg_timer) "act_Timer INSERTBEEP"
set fsm(INSERTBEEP,ev_destroy_done) "act_Destroy same_state"
set fsm(INSERTBEEP,ev_media_done) "act_Beeped same_state"
set fsm(INSERTBEEP,ev_create_done) "act_ConnectedAgain CALLACTIVE"
set fsm(LASTWARN,ev_destroy_done) "act_LastWarn CALLDISCONNECT"
set fsm(CALLACTIVE,ev_disconnected) "act_Cleanup CALLDISCONNECT"
set fsm(CALLDISCONNECT,ev_disconnected) "act_Cleanup same_state"
set fsm(CALLDISCONNECT,ev_media_done) "act_Cleanup same_state"
set fsm(CALLDISCONNECT,ev_disconnect_done) "act_Cleanup same_state"
set fsm(CALLDISCONNECT,ev_leg_timer) "act_Cleanup same_state"
fsm define fsm CALL_INIT