# app_session.tcl #------------------------------------------------------------------ # August 1999, Saravanan Shanmugham # # Copyright (c) 1998, 1999, 2000, 2001, 2002, 2003 by cisco Systems, Inc. # All rights reserved. #------------------------------------------------------------------ # # Changes: #------------------------------------------------------------------ # 2005/11/07 Martin Streule # Name/Number can be configured in IOS config (similar to "modify_caller_name.tcl") # ISDN Cause code "User busy" is set if IP destination busy # # config example: # call application voice name clid_prefix1 00714992362 # call application voice name display_name1 "Swisscom Widmer" # call application voice name calling_number1 7099 # #------------------------------------------------------------------ # # This tcl script mimics the default SESSION app # # If DID is configured, just place the call to the dnis # Otherwise, output dial-tone and collect digits from the # caller against the dial-plan. # # Then place the call. If successful, connect it up, otherwise # the caller should hear a busy or congested signal. # The main routine just establishes the statemachine and then exits. # From then on the system drives the statemachine depending on the # events it recieves and calls the appropriate tcl procedure #--------------------------------- # Example Script #--------------------------------- proc act_Setup { } { global dest global beep set beep 0 if { [infotag get leg_isdid] } { set dest [infotag get leg_dnis] # number/name insert - begin # set dnis [infotag get leg_dnis] set ani [infotag get leg_ani] puts "dnis: $dnis ani: $ani" set no_match 1 set x 1 while {1} { if {[infotag get cfg_avpair_exists clid_prefix$x] && [infotag get cfg_avpair_exists display_name$x] } { set clid_prefix [infotag get cfg_avpair clid_prefix$x] set display_name [infotag get cfg_avpair display_name$x] puts "clid_prefix: $clid_prefix display_name: $display_name" set len [string length clid_prefix] set match [string first $clid_prefix $ani] puts "len: $len match: $match" if { $match == 0 } { set no_match 0 set callInfo(displayInfo) $display_name if {[infotag get cfg_avpair_exists calling_number$x]} { set calling_number [infotag get cfg_avpair calling_number$x] set callInfo(originationNum) $calling_number puts "\n ========================================" puts "\n Found a match: setting calling_number to $calling_number" puts "\n ========================================" } puts "\n ========================================" puts "\n Found a match: setting name to $display_name" puts "\n ========================================" break } } else { puts "No more prefixes or name at $x" break } incr x if { $x > 1000 } { puts "Too many prefixes and names" } } if {$no_match} { if {[infotag get cfg_avpair_exists display_name_default]} { set display_name [infotag get cfg_avpair display_name_default] set callInfo(displayInfo) $display_name puts "Setting to default display name: $display_name" } } puts "Final name $display_name" # # number/name insert - end 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 } } 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 } } else { puts "\n ==================================================================" puts "\n *** Call [infotag get con_all] got event $status ***" puts "\n ==================================================================" # use user busy cause code if { $status == "ls_009"} { puts "\n *** ls_009 User busy will be sent to ISDN as cause 17 ***" leg disconnect leg_incoming -c 17 } 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(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