[RESOLVED] Attended Transfer Timeout


#1

How can I change the timeout for attended transfers?

That is, a call rings in to the receptionist. She answers it and determines it is for Bob. She dials the code for attended transfer (*2 in our case). She hears the prompt “Transfer”. She dials Bob’s extension and it begins to ring. After 10 seconds, Bob’s phone stops ringing and the receptionist is re-connected to the caller.

How can I change that timout to something other than 10 seconds?

Thanks!


#2

Its in the diaplan.

The line for bob (or thwe macro) reads like

exten=>Dial/Technology/Bob,10,moreOptions)

The “10” is the value you need to change.
If there is no value, asterisk is using the default value which is…IIRC in the general section of extensions.conf


#3

Richard,

Thanks for the help, but that is not the problem. I have tried adjusting the timeout value in the Dial applicatoin up and down, but the timout on the transfer remains exactly 10 seconds.

For clarity, I better start using real names. The call rings in to Matt, and Matt tries to transfer to Sarah (not Bob).

Here is the relevant information from extensions.conf (the output from Asterisk console follows):

; **************************************

; This is the macro we use to define internal phone extensions.
; ${ARG1} - Device(s) to ring

[macro-InternalPhoneExtension]

exten => s,1,Dial(${ARG1},40,tT) ; Call the extension and let it ring 40
; seconds. Note that either party can
; transfer the call.

exten => s,2,VoiceMail(su${MACRO_EXTEN}) ; If they don’t answer, send the call
; to voicemail. The ‘u’ tells the
; VoiceMail application to play the
; unavailable greeting (‘b’ would tell
; the VoiceMail application to play
; the busy greeting). The ‘s’ tells
; the voicemail application to skip
; the “please leave your message, when
; you have finished…” prompt.

exten => s,3,Hangup() ; Always finish by hanging up just to
; be sure everything cleans up.

exten => s,102,VoiceMail(su${MACRO_EXTEN}) ; If we got to this step, the dial
; command failed, so the user must
; be busy. Note that busy means there
; are no more call appearances available
; on the phone, NOT that the user is
; on another call. Send the call to
; voicemail using the 'u’navailable
; greeting because the 'b’usy greeting
; might be mis-used. The ‘s’ tells
; the voicemail application to skip
; the “please leave your message, when
; you have finished…” prompt.

exten => s,103,Hangup() ; Always finish by hanging up just to
; be sure everything cleans up.

exten => 175,1,Macro(InternalPhoneExtension,${SarahPhone})

Here is the output from the Asterisk console:

SIP/Matt-0dab answered Zap/2-1
– Started music on hold, class ‘default’, on channel ‘Zap/2-1’
– Playing ‘pbx-transfer’ (language ‘en’)
– Stopped music on hold on Zap/2-1
– Executing Macro(“Local/175@Internal-d199,2”, “InternalPhoneExtension|SIP/Sarah”) in new stack
– Executing Dial(“Local/175@Internal-d199,2”, “SIP/Sarah|40|tT”) in new stack
– Called Sarah
– SIP/Sarah-a717 is ringing
– Local/175@Internal-d199,1 is ringing
Apr 14 10:29:42 NOTICE[21763]: res_features.c:1123 ast_feature_request_and_dial: We exceeded our AT-timeout
== Spawn extension (macro-InternalPhoneExtension, s, 1) exited non-zero on ‘Local/175@Internal-d199,2’ in macro ‘InternalPhoneExtension’
== Spawn extension (macro-InternalPhoneExtension, s, 1) exited non-zero on ‘Local/175@Internal-d199,2’

[quote=“RichardHH”]Its in the diaplan.

The line for bob (or thwe macro) reads like

exten=>Dial/Technology/Bob,10,moreOptions)

The “10” is the value you need to change.
If there is no value, asterisk is using the default value which is…IIRC in the general section of extensions.conf[/quote]


#4

The transfer timeout is actually hard-coded (yuck!) in res_features.c:

		newchan = ast_feature_request_and_dial(transferer, "Local", ast_best_codec(transferer->nativeformats), dialstr, 15000, &outstate, cid_num, cid_name);

I simply changed the 15000 (milliseconds) parameter to a larger number, and it worked.

It’s not likely I’ll ever make any significant contributions to Asterisk development effort, but how do I recommend that nothing should EVER be hard-coded (there should at least be a #define) and as many values as possible (timers in particular) should be configurable?


#5

Ahhh…there is the key:
You are using the LOCAL!! channel.

Thats why your hardcoding made a diff. Normally, it shouldnt because the transfer should be in your spawn-context.

The attended transfer looks like this in res_f…:

if(ast_tvdiff_ms(ast_tvnow(), started) > timeout) {
state = AST_CONTROL_UNHOLD;
ast_log(LOG_NOTICE, “We exceeded our AT-timeout\n”);
break; /doh! timeout/

and timeout is a variable here.

I just rechecked it with my PBX, the attended transfer timeout is taken from the dialstring, like i said before. This is the CLI of my test just:

I called from 36 to 44.
44 is putting 36 on hold and initiates an att.transfer to 37:

– Executing Dial(“SIP/36-e922”, “SIP/44|45|wW”) in new stack
– Called 44
– SIP/44-e66d is ringing
– SIP/44-e66d answered SIP/36-e922
– Attempting native bridge of SIP/36-e922 and SIP/44-e66d
– Started music on hold, class ‘default’, on SIP/36-e922
– Executing Macro(“SIP/44-06d6”, “stdexten|37|SIP/37|37”) in new stack
– Executing Set(“SIP/44-06d6”, “nummer@SIP/37=37|g”) in new stack
== Setting global variable ‘nummer@SIP/37’ to ‘37’
– Executing Dial(“SIP/44-06d6”, “SIP/37|45|wW”) in new stack
– Called 37
– SIP/37-6248 is ringing
– SIP/37-6248 is ringing
– SIP/37-6248 is ringing
– SIP/37-6248 is ringing
– SIP/37-6248 is ringing
– SIP/37-6248 is ringing
– SIP/37-6248 is ringing
– SIP/37-6248 is ringing
– SIP/37-6248 is ringing
– Nobody picked up in 45000 ms
etc.

As we see, the 45000 is the timeout from my dialstring.

I think you should check, why your att.transfer is using the local channel.
Or did you define “phones” in the local context ?

I would try to avoid the local channel, i experienced a lot of bugs and flaws with it.

One for instance, is the hardcoded transfer timing :imp:


#6

Richard,

Thanks for the tip on the local channel, but I’m not sure I completely understand. I do think I understand that you can use “local/extension” to manuever into any part of the dialplan. What I don’t understandis what I am doing that causes me to use the local channel.

Here is my complete dialplan. Please show me what I could do to avoid using the local channel. Thanks!

[globals]

; MATT - I define most of my variables here.

; Create variables for the phones.

ConniePhone=SIP/Connie
MattPhone=SIP/Matt
MikePhone=SIP/Mike
SarahPhone=SIP/Sarah
ShanePhone=SIP/Shane

; Create a list of all phones

AllPhoneList=${ConniePhone}&${MattPhone}&${MikePhone}&${SarahPhone}&${ShanePhone}

; Create a variable for the phones that should ring when an outside trunk rings in.

TrunkRinginPhoneList=${AllPhoneList}

; Create variables for the trunks.

Trunk1=Zap/1
Trunk2=Zap/2
Trunk3=Zap/3
Trunk4=Zap/4

; Create a variable for the general mailbox. Note that this should match the mailbox
; defined in voicemail.conf

VMGeneralMailbox=146

; **************************************

; This is the macro we use to define internal phone extensions.
; ${ARG1} - Device(s) to ring

[macro-InternalPhoneExtension]

exten => s,1,Dial(${ARG1},20,tT) ; Call the extension and let it ring 20
; seconds. Note that either party can
; transfer the call.

exten => s,2,VoiceMail(su${MACRO_EXTEN}) ; If they don’t answer, send the call
; to voicemail. The ‘u’ tells the
; VoiceMail application to play the
; unavailable greeting (‘b’ would tell
; the VoiceMail application to play
; the busy greeting). The ‘s’ tells
; the voicemail application to skip
; the “please leave your message, when
; you have finished…” prompt.

exten => s,3,Hangup() ; Always finish by hanging up just to
; be sure everything cleans up.

exten => s,102,VoiceMail(su${MACRO_EXTEN}) ; If we got to this step, the dial
; command failed, so the user must
; be busy. Note that busy means there
; are no more call appearances available
; on the phone, NOT that the user is
; on another call. Send the call to
; voicemail using the 'u’navailable
; greeting because the 'b’usy greeting
; might be mis-used. The ‘s’ tells
; the voicemail application to skip
; the “please leave your message, when
; you have finished…” prompt.

exten => s,103,Hangup() ; Always finish by hanging up just to
; be sure everything cleans up.

; **************************************

; This is the macro we use to define extensions for leaving voicemail without calling the
; person.
;
; ${ARG1} - voice mailbox number of the extension

[macro-LeaveVoicemail]

exten => s,1,Answer() ; Answer the call in case this is a
; transfer. This gives the party
; that is transferring the call the
; chance to hang up and complete the
; transfer before voice mail
; actually answers.

exten => s,2,Wait(3) ; Wait three seconds in case this is a
; transfer. This gives the party
; that is transferring the call a little
; time to hang up and complete the
; transfer before voice mail
; actually starts playing the greeting.

exten => s,3,VoiceMail(su${ARG1}) ; Call voice mail passing in the proper
; voice mailbox. The ‘u’ tells the
; VoiceMail application to play the
; unavailable greeting (‘b’ would tell
; the VoiceMail application to play
; the busy greeting). The ‘s’ tells
; the voicemail application to skip
; the “please leave your message, when
; you have finished…” prompt.

exten => s,4,Hangup() ; Always finish by hanging up just to
; be sure everything cleans up.

exten => s,104,Hangup() ; Always finish by hanging up just to
; be sure everything cleans up.

; **************************************

; Intercom extensions.

[Internal] ; This is the context we named in sip.conf

include => Outgoing ; Allow internal users to make outgoing
; calls.

; **************************************
; Create the extensions.

exten => 124,1,Macro(InternalPhoneExtension,${ConniePhone})
exten => 1124,1,Macro(LeaveVoicemail,124)

exten => 165,1,Macro(InternalPhoneExtension,${MattPhone})
exten => 1165,1,Macro(LeaveVoicemail,165)

exten => 169,1,Macro(InternalPhoneExtension,${MikePhone})
exten => 1169,1,Macro(LeaveVoicemail,169)

exten => 175,1,Macro(InternalPhoneExtension,${SarahPhone})
exten => 1175,1,Macro(LeaveVoicemail,175)

exten => 177,1,Macro(InternalPhoneExtension,${ShanePhone})
exten => 1177,1,Macro(LeaveVoicemail,177)

;***************************************
; Create an extension for voicemail main (for checking messages, changing options, etc).

exten => 186,1,VoiceMailMain(s${CALLERIDNUM}) ; The ‘s’ says to skip the voice mail
; prompt, and the CALLERIDNUM tells
; voice mail to log into the caller’s
; mailbox (note that the caller’s
; extension must match his voice
; mailbox number).

exten => 186,2,Hangup() ; Always finish by hanging up.
exten => 186,102,Hangup()

;***************************************
; Create another extension for voicemail main without the mailbox (for calling from
; a different phone or from outside).

exten => 178,1,VoiceMailMain()

exten => 178,2,Hangup() ; Always finish by hanging up.
exten => 178,102,Hangup()

; **************************************

; Public Network interface extensions.

[PublicNetworkRingin] ; This is the context we named in
; zapata.conf

exten => s,1,Dial(${TrunkRinginPhoneList}, 20, t) ; This is the action that takes place
; when a public network device rings in.
; We dial all of the destinaton devices
; for 20 seconds. If one answers,
; Asterisk bridges the caller to the
; answering device. The “t” option allows
; the answering device to transfer the
; call.

exten => s,2,Dial(Voicemail(su${VMGeneralMailbox})) ; After 20 seconds, send the call to the
; general mailbox. The ‘u’ tells the
; VoiceMail application to use the
; unavailable greeting, the ‘s’ tells
; the VoiceMail application to skip
; the built in prompt.

exten => s,3,Hangup() ; If we get here, something went wrong.
exten => s,102,Hangup() ; Terminate the call.

;********************************************************************************************

; Outgoing calls.

[Outgoing]

;********************************************************************************************

ignorepat => 9 ; When Asterisk is interpreting digits
; (such as during a transfer), this
; tells Asterisk to continue playing
; dialtone even after a ‘9’ is dialed.

;********************************************************************************************

; 911

exten => 911,1,Dial(${Trunk1}/w${EXTEN}&${Trunk2}/w${EXTEN}&${Trunk3}/w${EXTEN}&${Trunk4}/w${EXTEN},T)
; If somebody dials 911, we seize
; one of the outbound trunks and
; dial 911.
; Note the “w” before the number to
; dial. We put this in because the
; FXO channels on the TDM400 were
; dialing the digits before the central
; office was returning dialtone (so
; leading digits were being lost).
; Each “w” causes the TDM400 to “wait”
; 1/2 second, so we put in a
; 1/2 second wait to prevent the
; problem.

exten => 911,2,Hangup() ; Always finish by hanging up.

exten => _9X,102,congestion(5) ; All lines must be busy. Indicate
exten => _9x,103,Hangup() ; congestion for 5 seconds then hangup.

;********************************************************************************************

; 9 followed by a number

exten => _9X.,1,Dial(${Trunk1}/w${EXTEN:1}&${Trunk2}/w${EXTEN:1}&${Trunk3}/w${EXTEN:1}&${Trunk4}/w${EXTEN:1},T)
; Dialing 9 followed by at least one
; digit causes us to seize one of the
; outbound trunks and dial all of the
; numbers following the leading 9.
; Note the “w” before the number to
; dial. We put this in because the
; FXO channels on the TDM400 were
; dialing the digits before the central
; office was returning dialtone (so
; leading digits were being lost).
; Each “w” causes the TDM400 to “wait”
; 1/2 second, so we put in a
; 1/2 second wait to prevent the
; problem.

exten => _9X.,2,Hangup() ; Always finish by hanging up.

exten => _9X,102,congestion(5) ; All lines must be busy. Indicate
exten => _9x,103,Hangup() ; congestion for 5 seconds then hangup.


#7

Heya !

Your conf is fine !:slight_smile:

The reason, the transfer is spawning a localchannel extension is here:
[PublicNetworkRingin]

This is the context where a caller arrives.
And this context is not “connected” to your local extensions in any way.
So asterisk needs to pass the call to the locals via the localchannel (pseudo).

To avoid this, define your in-lines in the same context the internal phones are defined.

No worrys, its secure when you use absolute MSNs and no patterns for the in-lines.

Like
Exten=>555-50-50,1,dial(${AllPhoneList},45,tT)
Exten=>555-50-50,2,hangup

But note, that whoever answers the call is spawning within the context with the dialed extension.
This is important for the voicemail !

You need to define an extra VM line therefore:
Exten=>555-50-50,102,VoiceMail(su${VMGeneralMailbox})
Exten=>555-50-50,103,hangup

That would avoid the local channel use but it requires a little “strategychange” within your dialplan.


#8

Richard,

Thanks for all of the advice. I went ahead and put everything into one, big context, and it is working great just as you said.

I am a bit worried about toll fraud. That is, I am worried that an unscrupulous sort my find a way to call into our system, then use our lines to make outgoing toll calls. I don’t know how they might do that, but it worries me.

Thanks again!