Dialplan XML

From FreeSWITCH Wiki

Jump to: navigation, search

Contents

Introduction

The XML Dialplan is the default dialplan that is used. This creates a flexible dialplan, and allows for 3rd party tools to be quickly and easily created since there is an abundance of software that can manipulate dialplans. XML is also easily and readily edited by hand without requiring any special tools other than a text editor.

The XML dialplans allow for Perl Regular Expression matching on fields, which gives you a lot of flexibility in a standardized format which some may be accustomed to already, and others can readily find documentation on how to work with Perl Regular Expressions.

About Dialplan Variables

Availability of variables - Asterisk users must read!

The XML Dialplan has the ability to test a number of conditions based upon variables with expressions, however it needs to be understood that some variables may not be available for conditional testing until the first transfer or execute_extension is performed (see workarounds below).

Why

In essence the XML Dialplan is to be used for Call Routing rather than for complex or extensive conditional tests and evaluations. This is why FreeSWITCH makes Lua, JavaScript, Perl, Python and other API's available since they are far better alternatives than coming up with a convoluted XML solution, or worse yet some arcane and convoluted acronym such as "AEL".

Clarification

This may be confusing to former asterisk users since the info application such as <action application="info"/> will in fact display the variables as if they are available for a conditional test when in fact they may not.

The reason for this is that FreeSWITCH does the hunting and the executing in two separate steps. First - based on conditions, actions and anti-actions - all applications that need to be executed are gathered. Second, that sequence of applications is executed. This means that channel variables set by the executed applications won't be available to conditions at hunting time.

This is why you may find that your XML condition is failing even though the variable and its value are displayed with the <action application="info"/>.

Workarounds

The workaround for this is to either implement the vast majority of your dialplan logic within Lua, JavaScript or one of the other Dialplan scripting languages, OR execute an extension which will make those variables you seek to do conditional evaluations on available for parsing within your XML Dialplan condition.

NOTE: Since svn rev 14906 it is possible for certain applications to be run inline. This means that they are executed at hunting time which has the effect that channel variables set by these applications are available to the following conditions at hunting time.

Caller Profile fields or Channel variables

One thing that may seem confusing is the distinction between a caller profile field and a variable when constructing your XML Dialplan.

Caller profile fields would be referred to as:

<condition field="destination_number" blah...>

As opposed to:

<condition field="${sip_has_crypto}" blah...>

Please take note of the ${variable_name} syntax.

Dial plan parser

The dialplan is parsed once when the call hits the dialplan parser in the ROUTING state. With one pass across the XML the result will be a complete list of instructions installed into the channel based on parsed <action> or <anti-action> tags.

Those accustomed to Asterisk may expect the call to follow the dialplan by executing the applications as it parses them allowing data obtained from one action to influence the next action. This is not the case with the exception being the ${api func(api arg ${var_name})} field type where a pluggable api call from a module may be executed as the parsing occurs. This is meant to be used to draw real-time info such as date and time or other quickly accessible information and should not be abused.

Anatomy of the XML Dialplan

There are several elements in the XML dialplan. In general you have context, extension, condition and action. Each is processed in order until you reach the action tag which tells FreeSWITCH what action to perform. You are not limited to only one condition or action tag for a given extension.

Anatomy of the XML Dialplan at the Directory level

You might want to consider putting your extension in the conf/dialplan/default directory in its own XML file. Extensions in that directory are always inserted into the dialplan prior to the enum extension. If you want your specific XML file to be parsed prior to the other files in there then be sure to name it with a low number, like 001_My_Extensions.xml. Note that there are a few files in there already. The file you are particularly interested in is 99999_enum.xml. As long as your number is lower than “99999” then you’ll get your file parsed first. NOTE: A filename beginning with an alpha character is not “smaller” than 99999! Definitely name your files with at least one digit first in the filename! The Filename needs to be *before* (alphabetical) the enum extension because the enum extension is the catch-all – it grabs everything that hasn’t already been matched in the dialplan.

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 to assist you in identifying the context. The "dialplan" section of the freeswitch.xml meta document may contain several contexts

<?xml version="1.0"?>
<document type="freeswitch/xml">
  <section name="dialplan" description="Regex/XML Dialplan">
    <context name="default">
    </context>
  </section>
</document>

Extension

Extensions are destinations for a call. They are given a name and a grouping of conditions and actions are contained within them instructing FreeSWITCH what to do.

A 'name' parameter is required: It's an unique, arbitrary name assigned to an extension for identification and later use. An optional argument of 'continue' can be set to true or false: If continue is true even if a match is found, FreeSWITCH will continue executing any subsequent, applicable extensions once the present extension has completed its actions. The default is to not continue.

For example, to add extension 500 to your dialplan (and thereby allow incoming calls to ring and arrive on the phone whose extension is 500), add the following section to your dialplan as indicated above:
Informational Tip

"destination_number" is a FreeSWITCH variable; it shouldn't be changed.


 


Edit This
 <!--- ext 500 -->
 <extension name="500">
   <condition field="destination_number" expression="^500$">
       <!--- The % behind the username tells FS to lookup the user in it's local sip_registration database -->
       <action application="bridge" data="sofia/profilename/500%x.x.x.x"/> 
       <!--- x.x.x.x in the line above is the IP address to the FreeSWITCH server/device -->
       <!--- If you don't want to bridge a call to a local registered user, but to a SIP URI, use the @ instead of %: 
       <action application="bridge" data="sofia/profilename/500@x.x.x.x"/> -->
   </condition>
 </extension>

 


Legend: Text wrapped in [] indicates optional and is not part of the actual code. An '|' inside [] indicates mutiple possible values and also is not part of the code. Text wrapped in {} indicates it's a description of the parameter in place of the param itself.

<extension name="{exten_name}" [continue="[true|false]"]>
  • continue=true means even if an extension executes to continue parsing the next extension too. continue="false" is the default behavior and need not be specified.

The {exten_name} above may be anything but if it's an exact match with the destination number the parser will leap to this extension to begin the searching, but that does not mean it will execute the extension. Searching will either begin at the first extension in the context, or at the point the parser has jumped to in the case described above. Each condition is parsed in turn first taking the 'field' param. The parser will apply the Perl Compatible Regular Expression (go here for PCRE syntax information) to each 'field' param encountered. If the expression matches, it will parse each existing <action> tag in turn and add the data from the <application> tags to the channel's todo list. If a matched expression contains any data wrapped in () the variables $1,$2..$N will be valid and expanded in any of 'data' params from the subsequent action tags.

If the expression does NOT match, it will parse each <anti-action> tag in turn and add the data from the <application> tags to the channels todo list.

Informational Tip

since there was no match the () feature is not available in anti-actions


 


The 'break' param indicates how to behave in relation to matching:

  • 'on-true' - stop searching conditions after the first successful match.
  • 'on-false' - stop searching after the first unsuccessful match. (default behavior)
  • 'always' - stop at this condition regardless of a match or non-match.
  • 'never' - continue searching regardless of a match or non-match.

If not specified, it defaults to 'on-false'.

 <condition field="[{field_name}|${variable_name}|${api_func(api_args ${var_name})}]" expression="{expression}" break="[on-true|on-false|always|never]">
   <action application="app name" data="app arg"/>
   <anti-action application="app name" data="app arg"/>
 </condition>
 <!-- any number of condition tags may follow where the same rules apply -->
 </extension>

Dialing through gateways

"gateway" is treated as a keyword by mod_sofia, it obviously means the call will be placed through a configured gateway. This is an exception for the pattern sofia/profilename/extension@ip-address.

If a gateway, for instance, is named "gw", the bridge string for sending a call to gw's extension 100 would be:

<extension name="testing">
  <condition field="destination_number" expression="^(100)$">
    <action application="bridge" data="sofia/gateway/gw/$1"/>
  </condition>
</extension>

Condition

Conditions are pattern matching tags that help FreeSWITCH decide if the current call should be processed in this extension or not. When matching conditions against the current call you have several variables that you can compare against.

  • 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). Give us examples when this one can be used.
  • 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.)
  • 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.)

In addition to the above you can also do variables using the syntax ${variable} or API functions using the syntax ${api(args)}

For example, you can use the cond API:

  <condition field="${cond(${my_var} > 12 ? YES : NO)}" expression="^YES$">
    <action application="log" data="INFO ${my_var} is indeed greater than 12"/>
    <anti-action application="log" data="INFO ${my_var} is not greater than 12"/>
  </condition>

Variables may be used in either the field or the expression, as follows

<condition field="destination_number" expression="^${some_destination}$">

Or,

<condition field="${some_var}" expression="^([[:alnum:]]*)$">

You have two tags that are required for conditions, 'field' which contains the variable you wish to match against and 'expression' which contains the regular expression to apply. Using () in a regular expression will result in $1, $2 ... $N being populated appropriately which can be used later in the action tag. There is an optional tag 'break' which can take the values on-true, on-false, always and never. This lets you select how FreeSWITCH will continue to process the extension, if for example you have break="on-false" and a condition does not match, FreeSWITCH discontinues processing any more conditions in this extension and moves onto the next. If the optional tag 'break' is not given, it defaults to break="on-false".

In the next example, an SPA3000 device has been configured to register with FreeSWITCH as a GW to make PSTN calls. The IP x.x.x.x is the IP address of the GW. (The SPA3000 GW is configured the same as if it were to be connected to Asterisk. The external line is on port 5061 on the SPA3000. You can find instructions by searching this Wiki).

<extension name="To PSTN">
  <condition field="fdnis" expression="9541231234"/> 
  <condition field="destination_number" expression="(.*)">
      <action application="bridge" data="sofia/profilename/$1@x.x.x.x:5061"/>
   </condition>
</extension>

If you need to do "nested conditions", you can accomplish the same thing using break="on-false" and thinking of the conditions as being "stacked". If the first condition fails, it will not continue to the next condition, thus achieving the same effect as nesting conditions (which is not allowed).

Action and Anti-Action

Action tags are executed when there is a match, anti-action tags are executed when there is not a match. There are two arguments to action tags, application and data. Application is the registered application to execute, for example bridge, data is the argument to that application for example sofia/profilename/123@myserver. When you use anti-action tags you cannot use $1 since the regexp did not match, that value will not be populated.

<context name="default">
  <extension name="demo">
    <condition field="destination_number" expression="^(\d{7})$">
      <action application="bridge" data="sofia/profilename/$1@myprovider"/>
      <anti-action application="playback" data="number-is-invalid.wav"/>
    </condition>
  </extension>
</context>

Available Actions

See API Reference and Dialplan Functions

Inline Actions

You may set an extra attribute inline="true" on an action so that it will be executed during the hunting phase of the dialplan:

<action inline="true" application="set" data="some_var=some_val"/>

This makes it possible to have a condition in the following extension, that matches on the ${some_var} field.

Note that the only applications that may be run inline are the ones that quickly get- or set some variable(s) and that don't access or modify the state of the current session.

Applications that are allowed to be run inline are:

Also keep in mind that inline executed applications don't show up in your cdr's like normally run applications do.

EXAMPLES

NOTE:

  if you plan to include your extension in a separated .XML file:
  • please disable or change enum extension if you don't need it
  • add the tag "<include> and close it with </include>

Example 1: Matching a condition

In the example below, the particular extension will be selected only if the IP address of the calling endpoint is 192.168.1.1. In the second condition, the dialed number is extracted in variable $1 and put in the data of the bridge application, in order to dial out to IP address 192.168.2.2

<extension name="Test1">
  <condition field="network_addr" expression="^192\.168\.1\.1$"/>
  <condition field="destination_number" expression="^(\d+)$">
    <action application="bridge" data="sofia/profilename/$1@192.168.2.2"/>
  </condition>
</extension>

Note that the first condition field is TERMINATED by a / !!! The last condition field which contains the action/anti-action is terminated by a regular </condition> tag. Also note that the above example is NOT the same as below:

<extension name="Test1Wrong">
  <condition field="destination_number" expression="^(\d+)$"/>
  <condition field="network_addr" expression="^192\.168\.1\.1$">
    <action application="bridge" data="sofia/profilename/$1@192.168.2.2"/>
  </condition>
</extension>

The Test1Wrong example will not route the call properly, because the variable $1 will not have any value, since the destination number was matched in a different condition field.

You can also solve the Test1Wrong example by setting a variable in the first condition which you then use inside the second condition's action:

<extension name="Test1_2">
  <condition field="destination_number" expression="^(\d+)$">
    <action application="set" data="dialed_number=$1"/>
  </condition>
  <condition field="network_addr" expression="^192\.168\.1\.1$">
    <action application="bridge" data="sofia/profilename/${dialed_number}@192.168.2.2"/>
  </condition>
</extension>

Note that you cannot use a variable set inside an extension for further conditions/matches as the extension is evaluated when the action is called.

If you need to do different actions based on a variable set inside an extension you need to either use execute_extension or a transfer for the variable to be set.

Example 2: Matching multiple conditions (AND)

In this example we need to match a called number beginning with the prefix 1 AND match the incoming IP address at the same time.

<extension name="Test2">
  <condition field="network_addr" expression="^192\.168\.1\.1$"/>
  <condition field="destination_number" expression="^1(\d+)$">
    <action application="bridge" data="sofia/profilename/$0@192.168.2.2"/>
  </condition>
</extension>

Here, although we match with the rule 1(\d+)$ we don't use the variable $1 which would contain only the rest of the dialed number with the leading 1 stripped off, we use the variable $0 which contains the original destination number.

Example 3: Striping leading digits

In this example we need to match a called number beginning with 00 but we also need to strip the leading digits. Assuming that FreeSWITCH™ receives the number 00123456789 and we need to strip the leading 00 digits, then we can use the following extension:

<extension name="Test3.1">
  <condition field="destination_number" expression="^00(\d+)$">
    <action application="bridge" data="sofia/profilename/$1@192.168.2.2"/>
  </condition>
</extension>


On the other hand, if you anticipate receiving non-digits, or you want to match on more than just digits, use ".+" instead of "\d+" because \d+ matches numeric digits only, whereas a .+ will match all characters from the current position to the end of the string:

<extension name="Test3.2">
  <condition field="destination_number" expression="^00(.+)$">
    <action application="bridge" data="sofia/profilename/$1@192.168.2.2"/>
  </condition>
</extension>

NOTE: Please be careful with regular expressions containing (.*) or (.+). It's a good practice not to use catchall expressions because you cannot trust information from the sender. In nearly all dialplans, the capture group should be numeric so use \d.

Example 4: Adding a prefix

In this example we need to strip the leading digits as above, but we also need to place a new prefix before the called number. Assuming that FreeSWITCH™ receives the number 00123456789 and we need to replace the 00 with the 011, we can use the following extension:

<extension name="Test4">
  <condition field="destination_number" expression="^00(\d+)$">
    <action application="bridge" data="sofia/profilename/011$1@x.x.x.x"/>
  </condition>
</extension>

Example 5: SIP Profiles (dialing with different configurations)

In this example we will demonstrate the use of profiles when using a FreeSWITCH endpoint that supports profiles, like mod_sofia. Assuming that we want to use different call settings (codecs, DTMF modes, etc) for sending the calls to different IP addresses, we can create different profiles. For example, in the configuration of sofia.conf, we see an example profile named "test", which we rename to profile1 for this example, and add a profile2 for comparison:

<profile name="profile1">
  <param name="debug" value="1"/>
  <param name="rfc2833-pt" value="101"/>
  <param name="sip-port" value="5060"/>
  <param name="dialplan" value="XML"/>
  <param name="dtmf-duration" value="100"/>
  <param name="codec-prefs" value="PCMU@20i"/>
  <param name="codec-ms" value="20"/>
  <param name="use-rtp-timer" value="true"/>
</profile>
<profile name="profile2">
  <param name="debug" value="1"/>
  <param name="rfc2833-pt" value="101"/>
  <param name="sip-port" value="5070"/>
  <param name="dialplan" value="XML"/>
  <param name="dtmf-duration" value="100"/>
  <param name="codec-prefs" value="PCMA@20i"/>
  <param name="codec-ms" value="20"/>
  <param name="use-rtp-timer" value="true"/>
</profile>

The difference between the two profiles are in the codecs. The first uses G.711 uLaw and the second G711 ALaw.

Continuing the examples above, we have:

<extension name="Test5ulaw">
  <condition field="network_addr" expression="^192\.168\.1\.1$"/>
  <condition field="destination_number" expression="^1(\d+)$">
    <action application="bridge" data="sofia/profile1/$0@192.168.2.2"/>
  </condition>
</extension>

to send the call in G.711 uLaw and

<extension name="Test5alaw">
  <condition field="network_addr" expression="^192\.168\.1\.1$"/>
  <condition field="destination_number" expression="^1(\d+)$">
    <action application="bridge" data="sofia/profile2/$0@192.168.2.2"/>
  </condition>
</extension>

Example 6: Calling registered user

This example shows how to bridge to devices that have registered with your FreeSWITCH box. In this example we assume that you have setup a sofia profile called 'local_profile' and your phones are registering with the domain example.com. Note the '%' instead of '@' in the data string.

<extension name="internal">
  <condition field="source" expression="mod_sofia" />
  <condition field="destination_number" expression="^(4\d+)">
    <action application="bridge" data="sofia/local_profile/$0%example.com" />
  </condition>
</extension>

Example 7: Action failover on failed action

The following example shows how it is possible to call another action if the first action fails.

If the first action is successful the call is bridged to 1111@example1.company.com and will exist until one of the parties hangs up. After this, no other processing will be done because the caller's channel is closed. (i.e.: 1111@example2.company.com is not called)

If the initial call to 1111@example1.company.com was not successful the channel will not be closed and the second action will be called.

<extension name="internal">
  <condition field="destination_number" expression="^1111">
    <action application="set" data="hangup_after_bridge=true"/>
    <action application="bridge" data="sofia/local_profile/1111@example1.company.com" />
    <action application="bridge" data="sofia/local_profile/1111@example2.company.com" />
  </condition>
</extension>

Note: If you have more than one action and the application of the first action

  • DOES hangup the channel, the second action will NOT be called.
  • DOES NOT hangup the channel, the second action will be called.

Example 8: Check user is authenticated

The following example requires that a caller be authenticated before passing through. It was yanked from a mailing list post.

 <extension name="9191">
   <condition field="destination_number" expression="^9191$"/>
   <condition field="${sip_authorized}" expression="true">
     <anti-action application="reject" data="407"/>
   </condition>

   <condition>
     <action application="playback" data="/tmp/itworked.wav"/>
   </condition>
 </extension>

Example 9: Routing DID to an extension

To route incoming calls which come in to a certain DID to a fixed extension 1001, do something LIKE the following (from a mailing list post) (where XXXxxxxxxx is the phone number of your incoming DID)

In public.xml:

   <extension name="test_did">
     <condition field="destination_number" expression="^(XXXxxxxxxx)$">
       <action application="transfer" data="$1 XML default"/>
     </condition>
   </extension>

and then in default.xml have something like this in the default context:

     <extension name="Local_Extension">
     <condition field="destination_number" expression="^(XXXxxxxxxx)$">
       <action application="set" data="dialed_ext=$1"/>
     </condition>
     <condition field="destination_number" expression="^${caller_id_number}$">
       <action application="set" data="voicemail_authorized=${sip_authorized}"/>
       <action application="answer"/>
       <action application="sleep" data="1000"/>
       <action application="voicemail" data="check default $${domain} ${dialed_ext}"/>
       <anti-action application="ring_ready"/>
       <anti-action application="set" data="call_timeout=10"/>
       <anti-action application="set" data="hangup_after_bridge=true"/>
       <anti-action application="set" data="continue_on_fail=true"/>
       <anti-action application="bridge" data="USER/1001@$${domain}"/>
       <anti-action application="answer"/>
       <anti-action application="sleep" data="1000"/>
       <anti-action application="voicemail" data="default $${domain} ${dialed_ext}"/>
     </condition>
   </extension>

(the 1001 in the "bridge" line is the extension we're ringing)

FYI, calls from the "public" go into the public context where they then need to be transferred to another more friendly context for processing, like default. That is why you add the entry to public and the 'data="$1 XML PFC"' says to transfer called number $1 to the context PFC using XML dialplan. In the default context is where you actually ring the phone.

$${domain} a variable that it automatically fills in for you with your domain (most likely your IP) and the calling number. Just leave them as is.

Example 10: Route to a gateway extension with custom caller id

In this example we demonstrate an outgoing call with 10 digits from extension 1000 then route it to the asterlink.com gateway. This examples shows how to route for a specific extension and allows custom caller id for that extension.

   <extension name="asterlink.com">
     <condition field="caller_id_number" expression="^1000$"/>
     <condition field="destination_number" expression="^(\d{10})$">        
         <action application="set" data="effective_caller_id_number=8001231234"/>
         <action application="set" data="effective_caller_id_name=800 Number"/>
         <action application="bridge" data="sofia/gateway/asterlink.com/1208$1"/>
     </condition>
   </extension>

Example 11: Route based on number prefix

In this example we demonstrate routing to different destination based on NPANXX. Also how to respond to the calling party with a different failure message than the destination sends to FreeSWITCH.

<extension>
  <condition field="network_addr" expression="^(66\.123\.321\.231|70\.221\.221\.221)$" break="on-false"/>
  <condition field="destination_number" expression="^\d+$" break="never">
  <action application="set" data="continue_on_fail=NORMAL_TEMPORARY_FAILURE,TIMEOUT,NO_ROUTE_DESTINATION"/>
  <action application="set" data="bypass_media=true"/>
  <action application="set" data="accountcode=myaccount"/>
  </condition>
  <condition field="destination_number" expression="^(1813\d+|1863\d+|1727\d+|1941\d+|404\d+)$" break="never">
  <action application="bridge" data="sofia/outbound_profile/${sip_to_user}@switch1.mydomain.com"/>
  <action application="info"/>
  <action application="respond" data="503"/>
  <action application="hangup"/>
  </condition>
  <condition field="destination_number" expression="^(1404\d+|1678\d+|1770\d+)$">
  <action application="bridge" data="sofia/outbound_profile/${sip_to_user}@switch2.mydomain.com"/>
  <action application="info"/>
  <action application="respond" data="503"/>
  <action application="hangup"/>
  <anti-action application="respond" data="503"/>
  <anti-action application="hangup"/>
  </condition>
</extension>


Example 12: Handle calls which match no extension

In this example we demonstrate how to catch invalid extensions/Destinations.

  • You need to add this extension at bottom of your dialplan before ENUM can get included.
  • See mod_enum.
<extension name="catchall">
  <condition field="destination_number" expression=".*" continue="on-true">
   <action application="playback" data="bla.wav"/>
  </condition>
</extension>

Example 13: Call Screening

In this example, we ask the caller for a name, connect to the called party and announce that name. The called party may then press 1 to accept the call, or hang up. If the called party hangs up, the caller is connected with voicemail.

 <extension name="screen">
   <condition field="destination_number" expression="^(\d{4})$">
     <action application="set" data="call_screen_filename=/tmp/${caller_id_number}-name.wav"/>
     <action application="answer"/>
     <action application="sleep" data="1000"/>
     <action application="phrase" data="voicemail_record_name"/>
     <action application="playback" data="tone_stream://%(500, 0, 640)"/>
     <action application="set" data="playback_terminators=#*0123456789"/>
     <action application="record" data="${call_screen_filename} 7 200 2"/>
     <action application="set" data="group_confirm_key=1"/>
     <action application="set" data="fail_on_single_reject=true"/>
     <action application="set" data="group_confirm_file=phrase:screen_confirm:${call_screen_filename}"/>
     <action application="set" data="continue_on_fail=true"/>
     <action application="bridge" data="user/$1"/>
     <action application="voicemail" data="default $${domain} $1"/>
     <action application="hangup"/>
   </condition>
 </extension>

Example 14: Media recording

This extension is used to play/record media in audio (wav) format recording / playback extension

  • Thanks to rupa for the help.
     <extension name="recording">
       <condition field="destination_number" expression="^(2020)$">
         <action application="answer"/>
         <action application="set" data="playback_terminators=#"/>
         <action application="record" data="/tmp/recorded.wav 20 200"/>
       </condition>
     </extension>
     <extension name="playback">
       <condition field="destination_number" expression="^(2021)$">
         <action application="answer"/>
         <action application="set" data="playback_terminators=#"/>
         <action application="playback" data="/tmp/recorded.wav"/>
       </condition>
     </extension>

Example 15: Speaking Clock

This example will speak time using the Flite text to speech engine.

<include>
  <extension name="SpeakTime">
    <condition field="destination_number" expression="^2910$">
      <action application="set" data="actime=${strftime(%H:%M)}"/>
      <action application="set" data="tts_engine=flite"/>
      <action application="set" data="tts_voice=slt"/>
      <action application="speak" data="It is +${actime}"/>
    </condition>
  </extension>
</include>

SIP-Specific Dialstrings

SIP dialing has several options. Here are some aspects of what you might call the anatomy of a SIP dialstring.

Dialing A SIP URI

Basic syntax is: sofia/my_profile/user@host Host can be a name or an IP address, for example:

sofia/my_profile/1234@192.168.0.1

This would dial 1234 at host 192.168.0.1 via the profile "my_profile". If you use a name instead of an IP address, sofia will try to resolve the name as a NAPTR or SRV record before trying it as a standard A record.

Dialing A Registered User

There are two options depending upon whether or not there is an alias for the domain.
Without an alias you can do this:

sofia/my_profile/1234%mydomain.com

If you have an alias for the domain then this syntax is valid:

sofia/mydomain.com/1234

Note how the profile does not need to be explicitly supplied in the dialstring.

Also you can do it this way for local domains

user/1234@mydomain.com

Dialing Through A Gateway(SIP Provider)

A gateway is a means for making outbound calls through a SIP provider. For example:

sofia/gateway/mygateway.com/1234

This will dial through the gateway named "mygateway.com" to user 1234.
Note how there is no need to append anything after the user "1234"
This is an example of how not to do it:

sofia/gateway/mygateway.com/1234@mygateway.com  <==== WRONG WRONG WRONG

Dialing With A Specific Transport

Sometimes you will need to specify the transport, for example TCP, UDP, TLS, or SCTP.
This can be done by appending a semicolon and the transport method. For example:

sofia/my_profile/1234@192.168.0.1;transport=tcp

Specifying The Codec

Occasionally you may want to force the system to use a specific codec. This syntax will accomplish that:

{absolute_codec_string=XXXX}sofia/my_profile/user@your.domain.com

In this example, XXXX represents the codec to be used. The possible codec values are listed here.

Getting Fancy With PortAudio

If you have PortAudio running and would like to specify the codec you need to originate first and bridge second:

originate {absolute_codec_string=XXXX}sofia/default/foo@bar.com bridge:portaudio/auto_answer inline

Changing the SIP Contact user

FreeSWITCH normally uses mod_sofia@ip:port for the internal SIP contact. To change this to foo@ip:port, there is a variable, sip_contact_user:

{sip_contact_user=foo}sofia/my_profile/1234@192.168.0.1;transport=tcp

Using a Custom SIP URI

FreeSWITCH allows you to specify custom URI's as needed. For example, you may need to interoperate with equipment that accepts a URI only if it is formatted in a particular way. The key is to prefix your SIP URI with "sip:" in the dialstring. For example:

sofia/my_profile/sip:xxxx;phone-context=cdp.udp@somedomain.com;user=phone

The above example will send the the URI exactly as specified after the "sip:" prefix.

Related

Personal tools
Community
Support FreeSWITCH