10-17-2025 09:01 PM
Hello,
I have the following in a TCL IVR 2.0 script on an ISR:
for {set i 0} {$i < [string length $dtmfString]} {incr i} {
set digitToSend [string index $dtmfString $i]
puts "#### Sending $digitToSend"
leg senddigit leg_outgoing $digitToSend -t 50
}This is being used to send a string of DTMF digits (variable named "dtmfString") out to a call ringing at an FXS port once it is answered. Everything is working properly when "dtmfString" is 7 digits or less, but if it contains more than 7 digits, only the first 7 are actually sent. With "debug voip application script" enabled I can see each digit being printed by the "puts" statement on line 3, but only the first 7 are actually heard on the FXS port.
I have tried the following so far, none of which have made any difference to this behavior:
-Reload the router, and do "call application voice load" to reload my TCL script
-Omit the duration parameter from the "leg senddigit" statement
-Increase or decrease the value of the duration parameter in the "leg senddigit" statement
-Send the digits to "leg_incoming" instead of "leg_outgoing", just for a test
-Try sending digits to "leg_incoming" without having an outgoing leg active at all
-Remove the "puts" statement from the loop
-Tested with other (non-FXS) interfaces
-Wrap "$digitToSend" in double quotes on line 4
The original router I have been testing this on is a 2851 with C2800NM-ADVENTERPRISEK9-M 15.1(4)M9. I have tried it on a couple other routers of various models and IOS versions in my lab, they all have behaved the same.
Is there some limitation to the number of consecutive digits you can send with "leg senddigit", and better yet, is there a better way to send a string of digits like this?
I know that "leg senddigit" can only send one digit at a time, but something tells me that calling it in a for loop like this isn't the right way to be sending a long string of them. There doesn't seem to be any form of event generated when sending of a DTMF digit completes, otherwise I would've done it with the FSM.
Here is my complete TCL 2.0 script:
#number for the appropriate dial-peer to reach the receiver
set destination 1234
#ran once on application loading, and each new session
proc init { } {
}
#ran once on each new call
proc newCall { } {
init
global destination
#setup leg to receiver
puts "#### Placing call to receiver"
leg setup $destination callInfo leg_incoming
}
#send FGD string to receiver
proc sendDigits { } {
global destination
#build DTMF string ANI*DNIS* to be sent
set dtmfString [infotag get leg_ani [infotag get leg_incoming]]
append dtmfString *
append dtmfString $destination
append dtmfString *
puts "#### DTMF string is $dtmfString"
for {set i 0} {$i < [string length $dtmfString]} {incr i} {
set digitToSend [string index $dtmfString $i]
puts "#### Sending $digitToSend"
leg senddigit leg_outgoing $digitToSend -t 50
}
}
#cleanup, close the call
proc cleanup { } {
puts "#### Cleaning up"
call close
}
#an unhandled event was received in any state, log it for debugging purposes
proc unhandledEvent { } {
puts "#### Uhandled event ([infotag get evt_event])"
}
#states:
#SM_INITIAL waiting for a session
#SM_WAITANSWER new call received and outgoing call placed to receiver, waiting for ringing line to be answered
#SM_DONE FGD digits sent to receiver, waiting for disconnect
set fsm(SM_INITIAL,ev_setup_indication) "newCall SM_WAITANSWER"
set fsm(SM_INITIAL,ev_handoff) "newCall SM_WAITANSWER"
set fsm(SM_WAITANSWER,ev_setup_done) "sendDigits SM_DONE"
set fsm(any_state,ev_disconnected) "cleanup same_state"
set fsm(any_state,ev_session_terminate) "cleanup same_state"
set fsm(any_state,ev_any_event) "unhandledEvent same_state"
#define the minimum language version, and run the init function
requiredversion 2.0
init
#define the state machine, start it in SM_INITIAL
fsm define fsm SM_INITIAL
The number "1234" at the top of course is replaced with a valid number to reach a dial-peer that directs the call to an FXS port. For context, this script is intended to transmit a DTMF string similar to the "Feature Group D" MF signalling towards a Sur-Gard System III alarm receiver.
The way it works isn't quite standard as far as I can tell, when it answers an incoming call it immediately expects the ANI, followed by "*", followed by the DNIS, followed by "*" to be sent using DTMF tones. It does not support Bellcore FSK for caller ID combined with DTMF digits for DNIS at the same time like a lot of PBXs do for DID service, that could simply be done with "forward-digits all" on the dial-peer. If there is some way to do this natively within IOS that would solve my problem as well, however to my knowledge it was based around some AT&T PBX system and isn't a standard protocol, hence custom TCL scripting is needed.
Thank you!
-Keith
12-02-2025 11:45 AM
Just as an update, I wasn't able to find any solution to this behavior. I ended up having the script add digits to the "buffer" on an interval using call_timer0. It adds 7 digits to the buffer, starts the timer for 1 second (the minimum), upon the timer expiring it checks if there are more digits to be sent and repeats the process if so. The digit duration is set such that the queued digits finish sending right as the timer expires.
-Keith
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide