Advanced XML Syntax
There are several elements used to build an XML dialplan. In general, the dialplan groups logically similar functions and calling activities into a ‘context’. Within a context are extensions, each with ‘condition’ rules and associated ‘actions’ to perform when the condition rules match.
The following is a sample dialplan to illustrate these concepts. We have left out the XML “wrapper” to help make the basic concepts more clear:
<context name="example">
<extension name="500">
<condition field="destination_number" expression="^500$">
<action application="bridge" data="user/500"/>
</ condition>
</ extension>
<extension name="501">
<condition field="destination_number" expression="^501$">
<action application="bridge" data="user/501"/>
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="bridge" data="loopback/app=voicemail:default ${domain_name} ${dialed_extension}"/>
</ condition>
</ extension>
</ context >
Each rule is processed in order until you reach the action tag which tells SBC what action to perform. You are not limited to only one condition or action tag for a given extension.
In our above example, a call to extension 501 rings the extensions. If the user does not answer, the second action answers the call, and following actions delay for 1000 milliseconds (which is 1 second) and connect the call to the voicemail system.
Context
Contexts are a logical grouping of extensions. You may have multiple extensions contained within a single context.
The context tag has a required parameter of ‘name’. There is one reserved name, any, which matches any context. The name is used by incoming call handlers (like the [Sofia] SIP driver) to select the dialplan that runs when it needs to route a call. There is often more than one context in a dialplan.
A fully qualified context definition is shown below. Typically you’ll not need all the trimmings, but they are shown here for completeness.
<?xml version="1.0"?>
<document type="freeswitch/xml">
<section name="dialplan" description="Regex/XML Dialplan">
<!-- the default context is a safe start -->
<context name="default">
<!-- one or more extension tags -->
</context>
< !-- more optional contexts -->
</section>
</document>
Extensions
Extensions are destinations for a call. This is the meat of SBC routing dialed numbers. They are given a name and contain a group of conditions, that if met, will execute certain actions.
A ‘name’ parameter is required: It must be a unique name assigned to an extension for identification and later use.
For example:
<extension name="Your extension name here">
<condition(s)...
<action(s) .../>
</condition>
</extension>
*Typically when an extension is matched in your dialplan, the corresponding actions are performed and dialplan processing stops. An optional continue parameter allows your dialplan to continue running.
Conditions
Dialplan conditions are typically used to match a destination number to an extension. They have, however, much more power than may appear on the surface.
SBC has a set of built-in variables used for testing. In this example, the built-in variable destination_number is compared against the regular expression ^500$.
This comparison is ‘true’ if is set to 500.
Each condition is parsed with the Perl Compatible Regular Expression library. (go here for PCRE syntax information).
If a regular expression contains any terms wrapped in parentheses, and the expression matches, the variables $1,$2..$N will be set to the matching contents within the parenthesis, and may be used in subsequent action tags within this extension’s block.
For example, this simple expression matches a four digit extension number, and captures the last two digits into $1.
A destination number of 3425 would set $1 to 25 and then bridge the call to the phone at 25@example.com
Multiple Conditions (Logical AND)
You can emulate the logical AND operation available in many programming languages using multiple conditions. When you place more than one condition in an extension, all conditions must match before the actions will be executed. For example, this block will only execute the actions if the destination number is 500 AND it is Sunday.
Keep in mind that you must observe correct XML syntax when using this structure. Be sure to close all conditions except the last one with />. The last condition contains the final actions to be run, and is closed on the line after the last action.
By default, if any condition is false, SBC will move on to the anti-actions or the next extension without even evaluating any more conditions.
Multiple Conditions (Logical OR, XOR)
It is possible to emulate the logical OR operation available in many programming languages, using multiple conditions. In this situation, if one of the conditions matches, the actions are executed.
For example, this block executes its actions if the destination number is 501 OR the destination number is 502.
This method works well if your OR condition is for the same field. However, if you need to use two or more different fields then use the new regex syntax
Using this method it becomes easier to match the caller’s name OR caller ID number and execute actions whether either is true.
A slightly more advanced use of this method is demonstrated here:
Basically, for this new syntax you can have a condition to have a “regex” attr instead of “field” and “expression” etc. When there is a “regex” attr, that means you plan to have one or more tags that are similar to the condition tag itself that it has field and expression in it.
The value of the “regex” attr is either “all” or “any” or “xor indicating if all expressions must match or just any expression or only one must match(xor) . If it’s set to “any” it will stop testing the regex tags as soon as it finds one match, if it is set to “all”, it will stop as soon as it finds one failure.
From there it will behave like a normal condition tag either executing the actions or anti-actions and breaking based on the “break” attr.
The basic difference here is once there is a “regex” attr, the tags parsed for “all” or “any” take the place of the single “field” and “condition”
*Also, if any captures are done in the “expression” attrs of a tag, only the data from the newest capture encountered will be considered in the $n expansion or FIELD_DATA creation. In addition, you can set DP_REGEX_MATCH_1 .. DP_REGEX_MATCH_N to preserve captures into arrays.
This is another example to show that all regex conditions must be true, then the action will get executed; otherwise, the anti-action will. This is the same logic as follows:
*IF (cond1 AND cond2 AND cond3) THEN
do actions
ELSE
do other actions
ENDIF
Basically, the <condition regex="all">
tells the parser, “Hey, execute the <action>
’s only if all regexes PASS, otherwise execute any <anti-action>
’s”.
Complex Condition/Action Rules
Here is a more complex example, performing time-based routing for a support organization. The user dials extension 1100. The actual support extension is 1105 and is staffed every day from 8am to 10pm, except Friday, when it is staffed between 8am and 1pm. At all other times, calls to 1100 are sent to the support after-hours mailbox.
In this example, we use the break=never parameter to cause the first condition to ‘fall-through’ to the next condition no matter if the first condition is true or false. This is useful to set certain flags as part of extension processing. This example sets the variable begins_with_one if the destination number begins with 1.
Variables
Condition statements can match against channel variables, or against an array of built in variables.
Built-In Variables
The following variables, called ‘caller profile fields’, can be accessed from condition statements directly:
Dialplan Variable | Description |
---|---|
context | Why can we use the context as a field? Give us examples of usages please. |
rdnis | Redirected Number, the directory number to which the call was last presented. |
destination_number | Called Number, the number this call is trying to reach (within a given context) |
dialplan | Name of the dialplan module that are used, the name is provided by each dialplan module. Example: XML |
caller_id_name | Name of the caller (provided by the User Agent that has called us). |
caller_id_number | Directory Number of the party who called (caller) — can be masked (hidden) |
ani | Automatic Number Identification, the number of the calling party (caller) — cannot be masked |
aniii | The type of device placing the call ANI2 |
uuid | Unique identifier of the current call? (looks like a GUID) |
source | Name of the FreeSWITCH module that received the call (e.g. PortAudio) |
chan_name | Name of the current channel (Example: PortAudio/1234). |
network_addr | IP address of the signaling source for a VoIP call. |
year | Calendar year, 0-9999 |
yday | Day of year, 1-366 |
mon | Month, 1-12 (Jan = 1, etc.) |
mday | Day of month, 1-31 |
week | Week of year, 1-53 |
mweek | Week of month, 1-6 |
wday | Day of week, 1-7 (Sun = 1, Mon = 2, etc.) or “sun”, “mon”, “tue”, etc. |
hour | Hour, 0-23 |
minute | Minute (of the hour), 0-59 |
minute-of-day | Minute of the day, (1-1440) (midnight = 1, 1am = 60, noon = 720, etc.) |
time-of-day | Time range formatted: hh:mm[:ss]-hh:mm[:ss] (seconds optional) Example: “08:00-17:00” |
date-time | Date/time range formatted: YYYY-MM-DD hh:mm[:ss]~YYYY-MM-DD hh:mm[:ss] |