Call Forker

From Yate Documentation
(Difference between revisions)
Jump to: navigation, search
(Call Forker)
(Providing fake ringback tone while fallback calling through different gateways)
 
(53 intermediate revisions by 4 users not shown)
Line 1: Line 1:
== Call Forker ==
 
  
 
This module is used to route a call to multiple alternative targets. The first target that answers will be connected with the caller while the other calls are abandoned.
 
This module is used to route a call to multiple alternative targets. The first target that answers will be connected with the caller while the other calls are abandoned.
  
A call fork is implemented by connecting the incoming call to a ''fork master''. For each target a ''fork slave'' is created that generates a ''call.execute'' message to create the outgoing call leg. Once one of the outgoing calls answers all other active slaves are disconnected with a [[Call_End_Causes|reason]] of "pickup" and the incoming call leg is connected directly to the answered outgoing one, finishing the forking process.
+
A call fork is implemented by connecting the incoming call to a ''fork master''.
  
'''NOTE: Starting with Yate 3.3.3 (SVN Rev 4485 - 2011-07-12) the module supports separate parameters for each fork branch.'''
+
For each target a ''fork slave'' is created, that generates a ''[[call.execute]]'' message to create the outgoing call leg.
  
The 'callto' parameter of the call.execute message must be 'fork'.
+
Once one of the outgoing calls answers all other active slaves are disconnected with a [[Call_End_Causes|reason]] of "pickup" and the incoming call leg is connected directly to the answered outgoing one, finishing the forking process.
Each fork target must be specified in a callto.index parameter.
+
Fork target parameters can be specified in callto.index.param_name parameters.
+
The module will start looking for targets and parameters starting with index=1 and will stop when the parameter with current index is not found (e.g. for callto.1=sip/sip:1@host1, callto.2=sip/sip:2@host1, callto.4=sip/sip:3@host1 the module will handle the first 2 targets and will ignore callto.4).
+
Special targets like '|' or '|exec' can be specified (e.g. callto.2=|exec).
+
If the message is sent from a C++ module the callto.index parameter may be a NamedPointer carrying a NamedList with target parameters not prefixed (e.g. instead of setting callto.1.maxcall=10000 in the call.execute message a maxcall=10000 parameter can be set in the list of target parameters).
+
Examples will be given below.
+
  
To use as a fallback routing module you should add in regexroute or your routing module something like:
+
'''Note:''' Verify that the module is launched, otherwise add "callfork.yate=yes" to yate.conf.
  
fork sip/sip:1@host1 | h323/2@host2 | sip/sip:3@host3;stoperror=busy
+
== Parameters for each fork branch ==
  
in regexroute.conf this will look like this:  
+
  '''NOTE: Starting with Yate 3.3.3 (SVN Rev 4485 - 2011-07-12) the module supports separate parameters for each fork branch.'''
  
^.*$=fork sip/sip:\0@host1 | h323/\0@host2 | sip/sip:\0@host3;stoperror=busy
+
* The '''callto''' parameter of the call.execute message must be 'fork'.<br>
 +
* Each fork target must be specified in a '''callto.index''' parameter.<br>
 +
* Fork target parameters can be specified in '''callto.index.param_name''' parameters.<br>
 +
* The module will start looking for targets and parameters starting with index=1 and will stop when the parameter with current index is not found (e.g. for callto.1=sip/sip:1@host1, callto.2=sip/sip:2@host1, callto.4=sip/sip:3@host1 the module will handle the first 2 targets and will ignore callto.4).<br>
 +
* Special targets like '''|''' or '''|exec''' can be specified (e.g. callto.2=|exec).<br>
 +
* If the message is sent from a C++ module the callto.index parameter may be a NamedPointer carrying a NamedList with target parameters not prefixed (e.g. instead of setting callto.1.maxcall=10000 in the call.execute message a maxcall=10000 parameter can be set in the list of target parameters).<br>
  
With separate parameters (Yate 3.3.3):
+
===Examples===
  
^.*$=fork;callto.1=sip/sip:\0@host1;callto.1.maxcall=5000;callto.2=|;
+
1. To use as a fallback routing module you should add in regexroute or your routing module something like:  
callto.3=h323/\0@host2;callto.3.maxcall=7000;callto.4=|;callto.5=sip/sip:\0@host3;callto.5.maxcall=9000;stoperror=busy
+
+
  
To use call forking from a routing module you should return a string like: fork target1 target2 target3 ...
+
    fork sip/sip:1@host1 | h323/2@host2 | sip/sip:3@host3;stoperror=busy
  
  fork sip/sip:1@host1  h323/2@host2  sip/sip:3@host3;stoperror=busy 
+
2. To use call forking from a routing module you should return a string like: fork target1 target2 target3 ...
  
in regexroute.conf this will look like this:   
+
    fork sip/sip:1@host1 h323/2@host2  sip/sip:3@host3;stoperror=busy
  
^.*$=fork sip/sip:\0@host1  h323/\0@host2  sip/sip:\0@host3;stoperror=busy
+
3. Implementation in regexroute.conf:
  
With separate parameters (Yate 3.3.3):
+
{|class="wikitable"
 
+
|colspan="2" style="text-align:center;font-weight:bold;"| To use as a fallback routing module
  ^.*$=fork;callto.1=sip/sip:\0@host1;callto.1.maxcall=5000;callto.2=h323/\0@host2;
+
|-
callto.2.maxcall=7000;callto.3=sip/sip:\0@host3;callto.3.maxcall=9000;stoperror=busy
+
|Yate <= 3.3.3
 +
|Yate > 3.3.3
 +
|-
 +
|
 +
^.*$=fork sip/sip:\0@host1 | h323/\0@host2 | sip/sip:\0@host3;stoperror=busy
 +
|
 +
  ^.*$=fork;callto.1=sip/sip:\0@host1;callto.1.maxcall=5000;callto.2=|;
 +
  callto.3=h323/\0@host2;callto.3.maxcall=7000;
 +
  callto.4=|;callto.5=sip/sip:\0@host3;callto.5.maxcall=9000;stoperror=busy
 
   
 
   
 +
|- 
 +
|colspan="2" style="text-align:center;font-weight:bold;"| To use call forking from a routing module
 +
|-
 +
|Yate <= 3.3.3
 +
|Yate > 3.3.3
 +
|-
 +
|
 +
  ^.*$=fork sip/sip:\0@host1  h323/\0@host2  sip/sip:\0@host3;stoperror=busy
 +
|
 +
  ^.*$=fork;callto.1=sip/sip:\0@host1;callto.1.maxcall=5000;callto.2=h323/\0@host2;
 +
  callto.2.maxcall=7000;callto.3=sip/sip:\0@host3;callto.3.maxcall=9000;stoperror=busy
 +
|}
  
Targets must be separated by spaces when set as a single callto (like 'fork sip/sip:1@host1  h323/2@host2').
+
Targets must be separated by spaces when set as a single callto (like 'fork sip/sip:1@host1  h323/2@host2').<br>
A target with the name "|" (the pipe character) has a special meaning, it delimitates group of targets. Groups are called in sequence with targets in each group called simultaneously. Simultaneous targets result in having more than one ''fork slave'' at the same time.
+
A target with the name "|" (the pipe character) has a special meaning, it delimitates group of targets.<br>Groups are called in sequence with targets in each group called simultaneously.<br> Simultaneous targets result in having more than one ''fork slave'' at the same time.
 
+
  
=== Timed advance ===
+
== Timed advance ==
  
 
Starting with Yate 2.2 it is possible to proceed to the next group of targets based on a timer. This is accomplished using a special separator target that still starts with a pipe character:
 
Starting with Yate 2.2 it is possible to proceed to the next group of targets based on a timer. This is accomplished using a special separator target that still starts with a pipe character:
Line 56: Line 71:
 
will start calling initailly 1@host1 and after 3 seconds of no answer will also start calling 2@host2
 
will start calling initailly 1@host1 and after 3 seconds of no answer will also start calling 2@host2
  
=== Jump out of a fork ===
+
== Jump out of a fork ==
  
 
Starting with Yate 3 (SVN Rev 3310 - 2010-05-11) is it possible to jump out of a fork and continue the call without the ''fork master''.
 
Starting with Yate 3 (SVN Rev 3310 - 2010-05-11) is it possible to jump out of a fork and continue the call without the ''fork master''.
Line 69: Line 84:
 
If the SIP targets do not answer in 20 seconds the fork is terminated and will try to send the incoming call to ''queue/desk''. If that queue does not exist or the call cannot be queued it will end up connected to an announcement.
 
If the SIP targets do not answer in 20 seconds the fork is terminated and will try to send the incoming call to ''queue/desk''. If that queue does not exist or the call cannot be queued it will end up connected to an announcement.
  
=== Parameters ===
+
== Parameters of the ''call.execute'' ==
  
The following parameters of the ''call.execute'' message are understood by this module:
+
The following parameters of the ''[[call.execute]]'' message are understood by this module:
  
* fork.stop - regular expression matching the names of the [[Call End Causes|errors]] that will terminate the entire call. ''NOTE: this parameter was previously named stoperror - that form is OBSOLETE''
+
* '''fork.stop''' - regular expression matching the names of the [[Call End Causes|errors]] that will terminate the entire call.  
* fork.fake - a media source that should be attached as fake early media while. The value whould be acceptable in as ''source'' in a ''chan.attach'' message
+
''NOTE: this parameter was previously named stoperror - that form is OBSOLETE''
* rtpstrict - set this parameters to "true" or "yes" to drop with a "nomedia" error calls that don't acknowledge a RTP forward offer
+
* '''fork.fake''' - a media source that should be attached as fake early media. The value would be acceptable as ''source'' in a ''chan.attach'' message
 +
* '''rtpstrict''' - set this parameters to "true" or "yes" to drop with a "nomedia" error calls that don't acknowledge a RTP forward offer
 
'''IMPORTANT:''' All parameters apply to all branches of a forked call. You cannot set parameters specific to one target.
 
'''IMPORTANT:''' All parameters apply to all branches of a forked call. You cannot set parameters specific to one target.
 
Starting with Yate 3.3.3 fork parameters can be specified for each branch.
 
Starting with Yate 3.3.3 fork parameters can be specified for each branch.
Line 85: Line 101:
  
 
The following parameters are understood in return from the ''call.execute'' message and apply only to that branch:
 
The following parameters are understood in return from the ''call.execute'' message and apply only to that branch:
* fork.ringer - set this to "true" to have early media forwarded from that branch. ''NOTE: you should only apply this to the first target of a group as concurrency issues may appear otherwise''
+
* '''fork.ringer''' - set this to "true" to have early media forwarded from that branch.  
* fork.autoring - set this to "true" to have a ''call.ringing'' autogenerated for the call leg (but see below). This implies the same actions of setting "fork.ringer" to true
+
''NOTE: you should only apply this to the first target of a group as concurrency issues may appear otherwise''
* fork.automessage - this provides a replacement for the message sent by ''fork.autoring'' and makes sense only if that is set. The default value is "call.ringing" and you may set it to "call.progress" instead.
+
* '''fork.autoring''' - set this to "true" to have a ''call.ringing'' autogenerated for the call leg (but see below). This implies the same actions of setting "fork.ringer" to true
* fork.calltype - this parameter controls the behaviour of the outgoing call leg. Set it to "auxiliar" to not be counted and be dropped when deciding to move to the next group, set to "persistent" to not be counted but persist until the end of fork
+
* '''fork.automessage''' - this provides a replacement for the message sent by ''fork.autoring'' and makes sense only if that is set. The default value is "call.ringing" and you may set it to "call.progress" instead.
 +
* '''fork.calltype''' - this parameter controls the behaviour of the outgoing call leg. Set it to "auxiliar" to not be counted and be dropped when deciding to move to the next group, set to "persistent" to not be counted but persist until the end of fork
  
 
Other parameters (except "callto") are forwarded to the outgoing calls.
 
Other parameters (except "callto") are forwarded to the outgoing calls.
  
=== Configuration ===
+
== Configuration ==
  
There is no configuration file for this module. All parameters are taken from the ''call.execute'' message.
+
There is no configuration file for this module. All parameters are taken from the ''[[call.execute]]'' message.
  
==== Example ====
+
=== Example ===
 
A standard line for regexroute.conf will look like:
 
A standard line for regexroute.conf will look like:
 
   
 
   
Line 110: Line 127:
 
A demo query to return same from a database would be:
 
A demo query to return same from a database would be:
 
   
 
   
  SELECT 'fork sip/sip:1@host1 h323/2@host2 | sip/sip:3@host3' AS  
+
  SELECT 'fork sip/sip:1@host1 h323/2@host2 | sip/sip:3@host3' AS location, 'busy' AS stoperror
location, 'busy' AS stoperror
+
  
 
(assuming you have ''result=location'' in register.conf)
 
(assuming you have ''result=location'' in register.conf)
  
=== Call forking when additional parameters have to be supplied ===
+
== Call forking when additional parameters have to be supplied ==
  
'''NOTE: This section applies for Yate older then 3.3.3 (SVN Rev 4485 - 2011-07-12)'''
+
'''NOTE: This section applies for Yate older then 3.3.3 (SVN Rev 4485 - 2011-07-12)'''
Unfortunately routing a call to more than one target doesn't work if
+
per-target parameters must be set. This excludes fork routing to
+
registered accounts as they each need a different "line" parameter.
+
  
A workaround would be to catch and alter each individual call.execute  
+
Unfortunately routing a call to more than one target doesn't work if per-target parameters must be set. This excludes fork routing to registered accounts as they each need a different '''line''' parameter.
message like this:
+
 
 +
A workaround would be to catch and alter each individual [[call.execute]] message like this:
 
   
 
   
 
  [default]
 
  [default]
 
  ^.*$=fork $(rotate,$idx001, sip/\0@fwd, sip/\0@other, ...)
 
  ^.*$=fork $(rotate,$idx001, sip/\0@fwd, sip/\0@other, ...)
 
 
  [extra]
 
  [extra]
 
  call.execute=80
 
  call.execute=80
 
 
  [call.execute]
 
  [call.execute]
  ${callto}^\([a-zA-Z0-9]\+\)/\([0-9]\+\)@\([a-zA-Z0-9_-]\+\)$=return;callto=\1/\2;
+
  ${callto}^\([a-zA-Z0-9]\+\)/\([0-9]\+\)@\([a-zA-Z0-9_-]\+\)$=return;callto=\1/\2;line=\3
line=\3
+
  
This will turn any proto/user@acct into proto/user and set line=acct. The account name must contain only letters, digits, underscores and dashes. In particular a dot cannot be allowed as it would make impossible to discriminate regular domain names or IP addresses.
+
This will turn any proto/user@acct into proto/user and set '''line=acct'''.
 +
 
 +
The account name must contain only letters, digits, underscores and dashes.  
 +
 
 +
In particular a dot cannot be allowed as it would make impossible to discriminate regular domain names or IP addresses.
  
 
To apply more complex changes you can jump to computed contexts like:
 
To apply more complex changes you can jump to computed contexts like:
Line 142: Line 157:
 
  ${callto}^\([a-zA-Z0-9]\+\)/\([0-9]\+\)@\([a-zA-Z_-]\+\)$=goto exec_\3;
 
  ${callto}^\([a-zA-Z0-9]\+\)/\([0-9]\+\)@\([a-zA-Z_-]\+\)$=goto exec_\3;
 
  callto=\1/\2;line=\3
 
  callto=\1/\2;line=\3
 
 
  [exec_fwd]
 
  [exec_fwd]
 
  .*=return;caller=xxx
 
  .*=return;caller=xxx
 
 
  [exec_other]
 
  [exec_other]
 
  .*=return;caller=yyy;callername=It's me!
 
  .*=return;caller=yyy;callername=It's me!
  
 
+
For '''round-robin with fallback''' you would need something like:
For round-robin with fallback you would need something like:
+
  
 
  ^.*$=fork $(rotate,$idx001,| sip/\0@fwd,| sip/\0@other,| ...)
 
  ^.*$=fork $(rotate,$idx001,| sip/\0@fwd,| sip/\0@other,| ...)
  
You should consider adding a maxcall parameter (maximum time until answer  
+
You should consider adding a maxcall parameter (maximum time until answer in milliseconds) so that unresponsive gateways can be skipped.
in milliseconds) so that unresponsive gateways can be skipped.
+
  
For round-robin without fallback you would need something like:
+
For '''round-robin without fallback''' you would need something like:
 
  ^.*$=$(index,$idx001,sip/\0@fwd,sip/\0@other,...)
 
  ^.*$=$(index,$idx001,sip/\0@fwd,sip/\0@other,...)
  
 
Please see [[Routing]] for more examples of round-robin and/or fallback routing.
 
Please see [[Routing]] for more examples of round-robin and/or fallback routing.
  
=== Forking a call routed by a different module ===
+
== Forking a call routed by a different module ==
  
 
Sometimes you have to modify a call that is routed by another module like [[Regfile|regfile]].
 
Sometimes you have to modify a call that is routed by another module like [[Regfile|regfile]].
Line 171: Line 182:
 
  [extra]
 
  [extra]
 
  call.execute=80
 
  call.execute=80
 
 
  [call.execute]
 
  [call.execute]
 
  ; can't fork an already forked call or calls to scripts (IVR and such)
 
  ; can't fork an already forked call or calls to scripts (IVR and such)
Line 181: Line 191:
 
If the original called resource doesn't answer in 30 seconds the call will be routed to voicemail.
 
If the original called resource doesn't answer in 30 seconds the call will be routed to voicemail.
  
=== Providing fake ringback tone while fallback calling through different gateways ===
+
== Providing fake ringback tone while fallback calling through different gateways ==
  
  
  ^1$=fork earlymedia sip/sip:1@host1 h323/2@host2 | sip/sip:3@host3;
+
  ^1$=fork earlymedia sip/sip:1@host1 h323/2@host2 |next=20000 sip/sip:3@host3;stoperror=busy
stoperror=busy;maxcall=20000
+
 
+
 
  [extra]
 
  [extra]
 
  call.execute=80
 
  call.execute=80
 
+
 
  [call.execute]
 
  [call.execute]
  ${callto}^earlymedia$=return;callto=tone/ring;fork.calltype=persistent;
+
  ${callto}^earlymedia$=return;callto=tone/ring;fork.calltype=persistent;fork.autoring=true;fork.automessage=call.progress
fork.autoring=true;fork.automessage=call.progress
+
  
  
 
'''Starting with Yate 3.3.3 (SVN Rev 4485 - 2011-07-12) this can be set in a single rule:'''
 
'''Starting with Yate 3.3.3 (SVN Rev 4485 - 2011-07-12) this can be set in a single rule:'''
 
   
 
   
  ^1$=fork;callto.1=tone/ring;callto.2=sip/sip:1@host1;callto.3=h323/2@host2;callto.4=|;
+
  ^1$=fork;callto.1=tone/ring;callto.2=sip/sip:1@host1;callto.3=h323/2@host2;callto.4=|;\
callto.5=sip/sip:3@host3;stoperror=busy;maxcall=20000;
+
  callto.5=sip/sip:3@host3;stoperror=busy;maxcall=20000;\
callto.1.fork.calltype=persistent;callto.1.fork.autoring=true;
+
  callto.1.fork.calltype=persistent;callto.1.fork.autoring=true;\
callto.1.fork.automessage=call.progress
+
  callto.1.fork.automessage=call.progress
 
+
(this could be a very long line but is wrapped using backslashes for readability)
  
 
The persistent tone/ring will not prevent moving over to call sip/sip:3@host3 but will persist and provide fake early media until the call is answered or finally fails.
 
The persistent tone/ring will not prevent moving over to call sip/sip:3@host3 but will persist and provide fake early media until the call is answered or finally fails.
  
Another solution is to use the fork.fake to set the fake early media. This is an easy way to provide custom ringback.
+
== Providing just ringback tone ==
 +
 
 +
Use the '''fork.fake''' to set the fake early media. This is an easy way to provide custom ringback.
 
   
 
   
 
  ^1$=fork sip/sip:1@host1;fork.fake=tone/ring
 
  ^1$=fork sip/sip:1@host1;fork.fake=tone/ring
 +
 +
 +
'''See also'''
 +
 +
* [[Example of forking a call using lateroute]]
 +
* [[Call End Causes]]
 +
* [[Routing]]
 +
 +
[[Category:Routing]] [[Category:Call groups]] [[Category:Hunting groups]] [[Category:Call fork]] [[Category:Fallback routing]] [[Category:Regexroute]]

Latest revision as of 13:24, 5 June 2014

This module is used to route a call to multiple alternative targets. The first target that answers will be connected with the caller while the other calls are abandoned.

A call fork is implemented by connecting the incoming call to a fork master.

For each target a fork slave is created, that generates a call.execute message to create the outgoing call leg.

Once one of the outgoing calls answers all other active slaves are disconnected with a reason of "pickup" and the incoming call leg is connected directly to the answered outgoing one, finishing the forking process.

Note: Verify that the module is launched, otherwise add "callfork.yate=yes" to yate.conf.

Contents

[edit] Parameters for each fork branch

NOTE: Starting with Yate 3.3.3 (SVN Rev 4485 - 2011-07-12) the module supports separate parameters for each fork branch.
  • The callto parameter of the call.execute message must be 'fork'.
  • Each fork target must be specified in a callto.index parameter.
  • Fork target parameters can be specified in callto.index.param_name parameters.
  • The module will start looking for targets and parameters starting with index=1 and will stop when the parameter with current index is not found (e.g. for callto.1=sip/sip:1@host1, callto.2=sip/sip:2@host1, callto.4=sip/sip:3@host1 the module will handle the first 2 targets and will ignore callto.4).
  • Special targets like | or |exec can be specified (e.g. callto.2=|exec).
  • If the message is sent from a C++ module the callto.index parameter may be a NamedPointer carrying a NamedList with target parameters not prefixed (e.g. instead of setting callto.1.maxcall=10000 in the call.execute message a maxcall=10000 parameter can be set in the list of target parameters).

[edit] Examples

1. To use as a fallback routing module you should add in regexroute or your routing module something like:

   fork sip/sip:1@host1 | h323/2@host2 | sip/sip:3@host3;stoperror=busy 

2. To use call forking from a routing module you should return a string like: fork target1 target2 target3 ...

   fork sip/sip:1@host1  h323/2@host2  sip/sip:3@host3;stoperror=busy

3. Implementation in regexroute.conf:

To use as a fallback routing module
Yate <= 3.3.3 Yate > 3.3.3
^.*$=fork sip/sip:\0@host1 | h323/\0@host2 | sip/sip:\0@host3;stoperror=busy 
^.*$=fork;callto.1=sip/sip:\0@host1;callto.1.maxcall=5000;callto.2=|;
 callto.3=h323/\0@host2;callto.3.maxcall=7000;
 callto.4=|;callto.5=sip/sip:\0@host3;callto.5.maxcall=9000;stoperror=busy

To use call forking from a routing module
Yate <= 3.3.3 Yate > 3.3.3
 ^.*$=fork sip/sip:\0@host1  h323/\0@host2  sip/sip:\0@host3;stoperror=busy
 ^.*$=fork;callto.1=sip/sip:\0@host1;callto.1.maxcall=5000;callto.2=h323/\0@host2;
 callto.2.maxcall=7000;callto.3=sip/sip:\0@host3;callto.3.maxcall=9000;stoperror=busy

Targets must be separated by spaces when set as a single callto (like 'fork sip/sip:1@host1 h323/2@host2').
A target with the name "|" (the pipe character) has a special meaning, it delimitates group of targets.
Groups are called in sequence with targets in each group called simultaneously.
Simultaneous targets result in having more than one fork slave at the same time.

[edit] Timed advance

Starting with Yate 2.2 it is possible to proceed to the next group of targets based on a timer. This is accomplished using a special separator target that still starts with a pipe character:

  • |next=N - advance to the next group of targets after N milliseconds, keep calling current targets
  • |drop=N - drop current targets and advance to next group after N milliseconds

If you have something like

fork sip/sip:1@host1 |next=3000 sip/sip:2@host2 

will start calling initailly 1@host1 and after 3 seconds of no answer will also start calling 2@host2

[edit] Jump out of a fork

Starting with Yate 3 (SVN Rev 3310 - 2010-05-11) is it possible to jump out of a fork and continue the call without the fork master.

  • |exec - for next targets do not create new slave call legs but dispatch directly call.execute
  • |exec=N - effectively identical to |drop=N |exec

Once the |exec target is reached all remaining targets will be attempted sequentially until call.execute returns true.

[edit] Example

fork sip/sip:1@host1 sip/sip:2@host2 |exec=20000 queue/desk wave/play/queue_full.au 

If the SIP targets do not answer in 20 seconds the fork is terminated and will try to send the incoming call to queue/desk. If that queue does not exist or the call cannot be queued it will end up connected to an announcement.

[edit] Parameters of the call.execute

The following parameters of the call.execute message are understood by this module:

  • fork.stop - regular expression matching the names of the errors that will terminate the entire call.
NOTE: this parameter was previously named stoperror - that form is OBSOLETE
  • fork.fake - a media source that should be attached as fake early media. The value would be acceptable as source in a chan.attach message
  • rtpstrict - set this parameters to "true" or "yes" to drop with a "nomedia" error calls that don't acknowledge a RTP forward offer

IMPORTANT: All parameters apply to all branches of a forked call. You cannot set parameters specific to one target. Starting with Yate 3.3.3 fork parameters can be specified for each branch. For example a global fork.stop 'busy' can be overridden for a second target like this:

^.*$=fork;fork.stop=busy;callto.3.fork.stop=rejected;callto.1=sip/sip:\0@host1;
callto.2=|;callto.3=h323/\0@host2;callto.4=|;callto.5=sip/sip:\0@host3 

Starting with SVN Rev. 4527 (2011-07-28) the fork.stop condition can be reversed by adding a ^ character at the end. For example ^congestion$^ will terminate the fork on all errors except congestion.

The following parameters are understood in return from the call.execute message and apply only to that branch:

  • fork.ringer - set this to "true" to have early media forwarded from that branch.
NOTE: you should only apply this to the first target of a group as concurrency issues may appear otherwise
  • fork.autoring - set this to "true" to have a call.ringing autogenerated for the call leg (but see below). This implies the same actions of setting "fork.ringer" to true
  • fork.automessage - this provides a replacement for the message sent by fork.autoring and makes sense only if that is set. The default value is "call.ringing" and you may set it to "call.progress" instead.
  • fork.calltype - this parameter controls the behaviour of the outgoing call leg. Set it to "auxiliar" to not be counted and be dropped when deciding to move to the next group, set to "persistent" to not be counted but persist until the end of fork

Other parameters (except "callto") are forwarded to the outgoing calls.

[edit] Configuration

There is no configuration file for this module. All parameters are taken from the call.execute message.

[edit] Example

A standard line for regexroute.conf will look like:

^1$=fork sip/sip:1@host1 h323/2@host2 | sip/sip:3@host3;stoperror=busy

That means when someone is calling extension 1 the call will proceed as follows:

  • simultaneously call 1@host1 on SIP and 2@host2 on H.323
  • if one call is answered connect to it and drop the other
  • if a busy is received drop the entire call
  • after both outgoing calls fail call 3@host3 on SIP
  • if that fails too, finish the call with the most recent error (that returned by 3@host3 in the last step)

A demo query to return same from a database would be:

SELECT 'fork sip/sip:1@host1 h323/2@host2 | sip/sip:3@host3' AS location, 'busy' AS stoperror

(assuming you have result=location in register.conf)

[edit] Call forking when additional parameters have to be supplied

NOTE: This section applies for Yate older then 3.3.3 (SVN Rev 4485 - 2011-07-12)

Unfortunately routing a call to more than one target doesn't work if per-target parameters must be set. This excludes fork routing to registered accounts as they each need a different line parameter.

A workaround would be to catch and alter each individual call.execute message like this:

[default]
^.*$=fork $(rotate,$idx001, sip/\0@fwd, sip/\0@other, ...)
[extra]
call.execute=80
[call.execute]
${callto}^\([a-zA-Z0-9]\+\)/\([0-9]\+\)@\([a-zA-Z0-9_-]\+\)$=return;callto=\1/\2;line=\3

This will turn any proto/user@acct into proto/user and set line=acct.

The account name must contain only letters, digits, underscores and dashes.

In particular a dot cannot be allowed as it would make impossible to discriminate regular domain names or IP addresses.

To apply more complex changes you can jump to computed contexts like:

[call.execute]
${callto}^\([a-zA-Z0-9]\+\)/\([0-9]\+\)@\([a-zA-Z_-]\+\)$=goto exec_\3;
callto=\1/\2;line=\3
[exec_fwd]
.*=return;caller=xxx
[exec_other]
.*=return;caller=yyy;callername=It's me!

For round-robin with fallback you would need something like:

^.*$=fork $(rotate,$idx001,| sip/\0@fwd,| sip/\0@other,| ...)

You should consider adding a maxcall parameter (maximum time until answer in milliseconds) so that unresponsive gateways can be skipped.

For round-robin without fallback you would need something like:

^.*$=$(index,$idx001,sip/\0@fwd,sip/\0@other,...)

Please see Routing for more examples of round-robin and/or fallback routing.

[edit] Forking a call routed by a different module

Sometimes you have to modify a call that is routed by another module like regfile. This is impossible using the call.route message but there is the option of altering the parameters of the call.execute message.

An example of implementing dropping call into voicemail would be:

[extra]
call.execute=80
[call.execute]
; can't fork an already forked call or calls to scripts (IVR and such)
${callto}^fork=return
${callto}^external=return
; but fork all other calls to the original and the leave mail script (after 30s)
${maxcall}^$=return;callto=fork ${callto} | external/nodata/leavemail.php;maxcall=30000

If the original called resource doesn't answer in 30 seconds the call will be routed to voicemail.

[edit] Providing fake ringback tone while fallback calling through different gateways

^1$=fork earlymedia sip/sip:1@host1 h323/2@host2 |next=20000 sip/sip:3@host3;stoperror=busy

[extra]
call.execute=80

[call.execute]
${callto}^earlymedia$=return;callto=tone/ring;fork.calltype=persistent;fork.autoring=true;fork.automessage=call.progress


Starting with Yate 3.3.3 (SVN Rev 4485 - 2011-07-12) this can be set in a single rule:

^1$=fork;callto.1=tone/ring;callto.2=sip/sip:1@host1;callto.3=h323/2@host2;callto.4=|;\
 callto.5=sip/sip:3@host3;stoperror=busy;maxcall=20000;\
 callto.1.fork.calltype=persistent;callto.1.fork.autoring=true;\
 callto.1.fork.automessage=call.progress

(this could be a very long line but is wrapped using backslashes for readability)

The persistent tone/ring will not prevent moving over to call sip/sip:3@host3 but will persist and provide fake early media until the call is answered or finally fails.

[edit] Providing just ringback tone

Use the fork.fake to set the fake early media. This is an easy way to provide custom ringback.

^1$=fork sip/sip:1@host1;fork.fake=tone/ring


See also

Personal tools
Namespaces

Variants
Actions
Preface
Configuration
Administrators
Developers