FreeSWITCH Cookbook

5 (2 reviews total)
By Anthony Minessale II , Michael S Collins , Darren Schreiber and 1 more
    Advance your knowledge in tech with a Packt subscription

  • Instant online access to over 7,500+ books and videos
  • Constantly updated with 100+ new titles each month
  • Breadth and depth in over 1,000+ technologies
  1. Routing Calls

About this book

FreeSWITCH is an open source telephony platform designed to facilitate the creation of voice, chat, and video applications. It can scale from a soft-phone to a PBX and even up to an enterprise-class softswitch.

In the FreeSWITCH Cookbook, members of the FreeSWITCH development team share some of their hard-earned knowledge with you in the book’s recipes. Use this knowledge to improve and expand your FreeSWITCH installations.

The FreeSWITCH Cookbook is an essential addition to any VoIP administrator’s library.

The book starts with recipes on how to handle call routing and then discusses connecting your FreeSWITCH server to the outside world.

It then teaches you more advanced topics like CDR handling, practical examples of controlling FreeSWITCH with the event socket, and configuring many features commonly associated with a PBX installation.

Publication date:
February 2012
Publisher
Packt
Pages
150
ISBN
9781849515405

 

Chapter 1. Routing Calls

In this chapter, we will discuss routing calls in various scenarios:

  • Internal calls

  • Incoming DID calls

  • Outgoing calls

  • Ringing multiple endpoints simultaneously

  • Ringing multiple endpoints sequentially (simple failover)

  • Advanced multiple endpoint calling with enterprise originate

  • Time of day routing

  • Manipulating To: headers on registered endpoints to reflect DID numbers

 

Introduction


Routing calls is at the core of any FreeSWITCH server. There are many techniques for accomplishing the surprisingly complex task of connecting one phone to another. However, it is important to make sure that you have the basic tools necessary to complete this task.

The most basic component of routing calls is the dialplan, which is essentially a list of actions to perform depending upon what digits were dialed (as we will see in some of the recipes in this book, there are other factors that can affect the routing of calls). The dialplan is broken up into one or more contexts. Each context is a group of one or more extensions . Finally, each extension contains specific actions that can be performed on the call. The dialplan processor uses regular expressions, which is a pattern-matching system, to determine which extensions and actions to execute.

To make the best use of the recipes in this chapter, it is especially important to understand how to use regular expressions and the three contexts in the default configuration.

Regular expressions

FreeSWITCH uses Perl-compatible regular expressions (PCRE) for pattern matching. Consider this dialplan excerpt:

<extension name="example">
  <condition field="destination_number" expression="^(10\d\d)$">
    <action application="log" data="INFO dialed number is [$1]"/>

This example demonstrates the most common uses of regular expressions in the dialplan: matching against the destination_number field (that is, the digits that the user dialed) and capturing the matched value in a special variable named $1. Let's say that a user dials 1025; our example extension would match 1025 against the pattern ^(10\d\d)$ and determine that this is indeed a match. All actions inside the condition tag would be executed. The action in our example would execute the log application. The log application will then print a message to the console, using the INFO log level, which, by default, will be in green text. The value in $1 is expanded (or interpolated) when printed out:

2011-01-09 13:38:31.864281 [INFO] mod_dptools.c:1152 dialed number is [1025]

Understanding these basic principles will enable you to create effective dialplan extensions. For more tips on using regular expressions, be sure to visit http://wiki.freeswitch.org/wiki/Regex.

Important dialplan contexts in the default configuration

As previously mentioned, contexts are logical groups of extensions. The default FreeSWITCH configuration contains three contexts:

  • default

  • public

  • features

Each of these contexts serves a purpose, and knowing about them will help you leverage their value for your needs.

The default context

The most-used context in the default configuration is the default context. All users whose calls are authenticated by FreeSWITCH will have their calls pass through this context, unless there have been modifications. Some common modifications include using ACLs or disabling authentication altogether (see The public context section that follows). The default context can be thought of as "internal" in nature, that is, it services the users who are connected directly to the FreeSWITCH server, as opposed to outside callers. (again, see The public context section that follows).

Many of the PBX-related (Private Branch Exchange) features are defined in the default context, as are various utility extensions. It is good to open conf/dialplan/default.xml and study the extensions in there. Start with simple extensions like show_info, which performs a simple info dump to the console, and vmain, which allows a user to log into his/her voicemail box.

A particularly useful extension to review is the Local_Extension. This extension does many things:

  • Routes calls between internal users

  • Sends calls to the destination user's voicemail on a no answer condition

  • Enables several in-call features with bind_meta_app

  • Updates the local calls database to allow for a call return and call pickup

Many of the techniques employed in the Local_Extension are discussed in this chapter (see also The features context below for a discussion of the in-call features found in this extension).

The public context

The public context is used to route incoming calls that originate from outside the local network. Calls that initially come in to the public context and are treated as untrusted—if they are not specifically routed to an extension in the default context, then they are simply disconnected. As mentioned above, disabling authentication or using ACLs to let calls into the system will route them into the public context (this is a security precaution that can be overridden if absolutely required). We will use the public context in the recipe Incoming DID calls.

The features context

The features context is used to expose certain features for calls that are in progress. Consider this excerpt from the Local_Extension in conf/dialplan/default.xml:

<action application="bind_meta_app" data="1 b s execute_extension::dx XML features"/>

This is just one of several features that are enabled for the recipient of the call. The bind_meta_app application listens on the audio stream for a touch-tone * followed by a single digit. The above example is a blind transfer. If the user dials *1, then the command execute_extension::dx XML features is executed. In plain language, this command says, "Go to the features context of the XML dialplan and execute the extension whose destination number is dx". In conf/dialplan/features.xml is the following extension:

<extension name="dx">
  <condition field="destination_number" expression="^dx$">
  ...

The dx extension accepts some digits from the user and then transfers the caller to the destination that the user keyed in.

This process demonstrates several key points:

  • Calls can be transferred from one dialplan context to another

  • The features context logically isolates several extensions that supply in-call features

  • The bind_meta_app dialplan application is one of the means of allowing in-call features

Understanding that calls can flow from one context to another, even after they are in progress, is an important concept to grasp when addressing your call routing scenarios.

 

Internal calls


Calling local extensions is very simple once you know what needs to happen. In this case, we will review how to add a new user and make his or her phone available to be called.

Getting ready

If you are using the default configuration, then users 1000 through 1019 are pre-configured, both in the directory and the dialplan. To create a user outside this range, it is generally easiest to just run the add_user script, found in the FreeSWITCH source directory under scripts/perl. For example, to add the user 1020, launch this script from the FreeSWITCH source directory, specifying the user ID on the command line:

scripts/perl/add_user 1020

You can also specify a range of users:

scripts/perl/add_user –-users=1020-1029

You will see a note about how many users were added. If you have the CPAN module Regexp::Assembly installed, then the script will also generate a 'sample regular expression pattern'. For our example, we will add a range of users 1020-1029.

How to do it...

Follow these steps:

  1. Open the file conf/dialplan/default.xml in a text editor. Locate the Local_Extension entry:

    <extension name="Local_Extension">
      <condition field="destination_number"expression="^(10[01][09])$">
      ...
  2. Edit the expression in the <condition> tag to account for our new users. The expression pattern ^(10[012][0-9])$ will do what we need (look closely to see the difference). The new line will be as follows:

    <condition field="destination_number" expression="^(10[012][09])$">
  3. Save the file and then execute reloadxml from the fs_cli.

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

How it works...

The Local_Extension is the default dialplan entry that allows directory users to be called. Remember, simply adding a user to the directory does not mean that the user can be dialed. (It does, though, usually mean that the user can make outbound calls.) So in order for your new user to be reachable, you need to add his or her user ID to the dialplan. By default, Local_Extension has a regular expression that will match 1000, 1001, … 1019. When adding users outside that number range, it is necessary to modify the regular expression to account for those new numbers. In our example, we added user IDs 1020 through 1029, so we need to match those. We use this regular expression:

^(10[012][0-9])$

This matches 1000 through 1029. Let's say we added another block of user IDs with the range of 1030 through 1039. We could modify our regular expression to catch those as well:

^(10[0123][0-9])$

It is considered a best practice not to add a large range of dialable numbers in the Local_Extension without having the corresponding users in the directory. Doing so can make troubleshooting dialplan issues more difficult.

As a reminder, be sure to execute the reloadxml command each time you modify the regular expression (the changes you make to your XML configuration files will not take effect until they are loaded into memory, which is what reloadxml command does).

See also

  • The Creating Users section in Chapter 5, PBX Functionality

 

Incoming DID calls


Phone calls coming in from the Public Switched Telephone Network (PSTN) are often called DID calls. DID stands for Direct Inward Dialing. DID numbers are delivered by your telephone service provider. They can be delivered over VoIP connections (such as a SIP trunk) or via traditional telephone circuits like PRI lines. These phone numbers are sometimes called "DID numbers" or "external phone numbers".

Getting ready

Routing a call requires two pieces of information—the phone number being routed and a destination for that phone number. In our example, we will use a DID number of 8005551212. Our destination will be user 1000. Replace these sample numbers with the appropriate values for your setup.

How to do it...

Follow these steps:

  1. Create a new file in conf/dialplan/public/ named 01_DID.xml. Add this text:

    <include>
      <extension name="public_did">
        <condition field="destination_number"expression="^(8005551212)$">
          <action application="set" data="domain_name=$${domain}"/>
          <action application="transfer" data="1000 XML default"/>
        </condition>
      </extension>
    </include>
  2. Save the file and then execute reloadxml from the fs_cli.

How it works...

All calls that come in to the FreeSWITCH server from outside (as well as internal calls that are not authenticated) are initially handled in the public dialplan context (dialplan contexts were discussed in more detail in this chapter's introduction). Once the call hits the public context, we try to match the destination_number field. The destination_number is generally the DID number (see the There's more section below for some caveats). Once we match the incoming number, we then set the domain_name channel variable to the default domain value and then transfer the call to user 1000 (FreeSWITCH is domain-based in a way similar to e-mail.

Most systems have only a single domain, although FreeSWITCH supports multiple domains. See the FreeSWITCH wiki for explicit information on multiple domain configuration). The actual transfer happens with this dialplan entry:

<action application="transfer" data="1000 XML default"/>

In plain language, this tells FreeSWITCH to transfer the call to extension 1000 in the XML dialplan and the default context. The default context contains the Local_Extension, which handles calls to users' telephones.

There's more...

Keep in mind the match in destination_number must match what the provider sends to FreeSWITCH, not necessarily what the calling party actually dialed. In North America, there are providers that send DID information in various formats such as:

  • 8005551212

  • 18005551212

  • +18005551212

The expression must match what the provider sends. One way to accomplish this is to have a few optional characters in the pattern. This pattern matches all three formats listed above:

<condition field="destination_number" expression="^\+?1?(8005551212)$">

The value \+? means optionally match a literal + character and the value 1? means "optionally match a literal digit 1". Now our pattern will match all three formats that are commonly used in North America (technically, our pattern will also match +8005551212, but we are not concerned about that. However, the pedantic admin might be, so he or she can use the pattern ^(\+1)?1?(8005551212)$ instead).

See also

  • The Configuring a SIP gateway section in Chapter 2, Connecting Telephones and Service Providers

 

Outgoing calls


In order to make your system useful, you need a way to dial out to the "real world". This section will cover dialing out to the PSTN and allow you to connect to land lines, cellular phones, and so on. In this recipe, we'll make an extension that will allow an outbound call to any valid US number. We'll attempt to complete the call using the gateway named our_sip_provider.

Getting ready

Making outbound calls requires you to know the numbering format that your provider requires. For example, do they require all 11 digits for US dialing? Or will they accept 10? In our example, we're going to assume that our provider will accept a 10-digit format for US dialing.

How to do it...

Routing outbound calls is simply a matter of creating a dialplan entry. Follow these steps:

  1. Create a new file in conf/dialplan/default/ named outbound_calls.xml. Add the following text:

    <include>
      <extension name="outbound_calls">
        <condition field="destination_number" expression="^1?([2-9]\d{2}[2-9]\d{6})$">
          <action application="bridge " data="sofia/gateway/our_sip_provider/$1"/>
        </condition>
      </extension>
    </include>
  2. Save your XML file and press F6 or issue the reloadxml command at the fs_cli.

How it works...

Assuming you have a phone set up on the default context, our regular expression will match any destination_number that follows the US dialing format (10 or 11 digits) and send the call to our_sip_provider in a 10-digit format.

There's more...

The regular expression matching in FreeSWITCH allows the possibility of having very powerful conditions. You can also match caller_id_number to route calls from a user at extension 1011 out to the second gateway called our_sip_provider2 and everyone else at the our_sip_provider. Consider the following alternative outbound_calls.xml file:

<include>
  <extension name="outbound_calls_from_1011">
    <condition field="caller_id_number" expression="^1011$"/>
    <condition field="destination_number" expression="^1?([2-9]\d{2}[2-9]\d{6})$">
      <action application="bridge" data="sofia/gateway/our_sip_provider2/$1"/>
    </condition>
  </extension>
  <extension name="outbound_calls">
    <condition field="destination_number" expression="^1?([2-9]\d{2}[2-9]\d{6})$">
      <action application="bridge" data="sofia/gateway/our_sip_provider/$1"/>
    </condition>
  </extension>
</include>

Note that we have two extensions. The first one tries to match the caller_id_number field to the value 1011. If it matches 1011, then the call gets sent out to the our_sip_provider2 gateway, otherwise the second extension is matched and the call goes out to the our_sip_provider gateway. Note that we use $1 to capture the matching value in the conditions' expressions. In each case, we capture exactly 10 digits which correspond to the area code (three digits), exchange (three digits), and phone number (four digits). These are North American Numbering Plan (NANPA) numbers. The regular expression used to capture dialed digits will vary depending upon the country.

Note

Regular expressions can be a challenge. There are a number of examples with explanations on the FreeSWITCH wiki. See http://wiki.freeswitch.org/wiki/Regular_Expression for further details.

See also

  • The Configuring a SIP phone to register with FreeSWITCH and Configuring a SIP gateway sections in Chapter 2, Connecting Telephones and Service Providers

 

Ringing multiple endpoints simultaneously


FreeSWITCH makes it easy to ring multiple endpoints simultaneously within a single command.

Getting ready

Open conf/dialplan/default.xml in a text editor or create or edit a new XML file in the conf/dialplan/default/ subdirectory.

How to do it...

Add a comma-separated list of endpoints to your bridge (or originate) application. For example, to ring [email protected] and [email protected] simultaneously, use an extension like this:

<extension name="ring_simultaneously">
  <condition field="destination_number" expression="^(2000)$">
    <action application="bridge" data="{ignore_early_media=true}sofia/internal/[email protected],sofia/sip/[email protected]"/> 
  </condition>
</extension>

How it works...

Putting comma-separated endpoints in the argument to bridge causes all of the endpoints in that list to be dialed simultaneously. It sounds simple, however, there are several factors to consider when ringing multiple devices simultaneously in a real environment. The bridge application will connect the call to whoever sends media first. This includes early media (ringing). To put this another way, if you bridge a call to two parties and one party starts sending a ringing signal back to you, that may be considered media and the call will be connected to that party only. Ringing of the other phones will cease.

If you find that calls always go to a specific number on your list of endpoints versus ringing all numbers, or that all phones ring for a moment before ringing only a single number, your call may be getting bridged prematurely because of early media. Notice that we added ignore_early_media=true at the beginning of the dial string. As its name implies, ignore_early_media tells the bridge application not to connect the calling party to the called party when receiving early media (such as a ringing or busy signal). Instead, bridge will only connect the calling party to the called party who actually answers the call. In most cases, it is useful to ignore early media when ringing multiple endpoints simultaneously.

There's more...

In some scenarios, you may also wish to ring specific devices for a limited amount of time. You can apply the leg_timeout parameter to each leg of the bridge to specify how long to ring each endpoint, like this:

<action application="bridge" data="[leg_timeout=20]sofia/internal/[email protected],[leg_timeout=30]sofia/sip/[email protected]"/>

In this example, userA's phone would ring for a maximum of 20 seconds while userB's phone would ring for a maximum of 30 seconds.

Tip

Call legs and the leg_timeout variable

The leg_timeout variable is unique in that it implies the ignoring of early media. When using the leg_timeout variable on each call leg in a bridge attempt, there is no need to explicitly use {ignore_early_media=true} in the bridge argument. For a more complete discussion of using { and } (curly braces) versus [ and ] (square brackets), see http://wiki.freeswitch.org/wiki/Channel_Variables#Channel_Variables_in_Dial_strings.

This method of calling multiple parties works well for small numbers of endpoints. However, it does not scale to dozens or more users. Consider using a FIFO queue in such an environment (FreeSWITCH's mod_fifo is discussed at length online at http://wiki.freeswitch.org/wiki/Mod_fifo). See also Ringing multiple endpoints sequentially (simple failover) for an example of ringing a group of endpoints one at a time, which includes an expanded discussion of using call timeouts.

See also

  • The Ringing multiple endpoints sequentially (simple failover) section that follows

 

Ringing multiple endpoints sequentially (simple failover)


Sometimes it is necessary to ring additional endpoints, but only if the first endpoint fails to connect. The FreeSWITCH XML dialplan makes this very simple.

Getting ready

Open conf/dialplan/default.xml in a text editor or create or edit a new XML file in the conf/dialplan/default/ subdirectory.

How to do it...

Add a pipe-separated list of endpoints to your bridge (or originate) application. For example, to ring [email protected] and [email protected] sequentially, use an extension like this:

<extension name="ring_sequentially">
  <condition field="destination_number" expression="^(2001)$">
    <action application="bridge" data="{ignore_early_media=true}sofia/internal/[email protected]|sofia/sip/[email protected]"/> 
  </condition>
</extension>

How it works...

Putting pipe-separated endpoints in the argument to bridge causes all of the endpoints in that list to be dialed sequentially. The first endpoint on the list that is successfully connected will be bridged and the other endpoints will not be dialed. There are several factors to consider when ringing multiple devices sequentially.

Notice that we added ignore_early_media=true at the beginning of the dial string. As its name implies, ignore_early_media tells the bridge application not to connect the calling party to the called party when receiving early media (such as a ringing or busy signal). Instead, bridge will only connect the calling party if the called party actually answers the call. In most cases you will need to ignore early media when dialing multiple endpoints sequentially.

There's more...

Handling various failure conditions can be a challenge. FreeSWITCH has a number of options that lets you tailor bridge and originate to your specific requirements.

Handling busy and other failure conditions

For example, when calling a user who is on the phone, one service provider might return SIP message 486 (USER_BUSY) whereas many providers will simply send a SIP 183 with SDP, and a media stream with a busy signal. In the latter case, how will the bridge application know that there is a failure if it is ignoring the early media that contains the busy signal? FreeSWITCH gives us a tool that allows us to monitor early media even while "ignoring" it.

Consider two very common examples of failed calls where the failure condition is signaled in-band:

  • Calling a line that is in use

  • Calling a disconnected phone number

These conditions are commonly communicated to the caller via specific sounds: busy signals and special information tones, or SIT tones. In order for the early media to be meaningful, we need to be able to listen for specific tones or frequencies. Additionally, we need to be able to specify that certain frequencies mean different kinds of failure conditions (this becomes important for reporting, as in call detail records or CDRs). The tool that FreeSWITCH provides us is a special channel variable called monitor_early_media_fail. Its use is best illustrated with an example:

<action application="bridge" data="{ignore_early_media=true,monitor_early_media_fail=user_busy:2:480+620!destination_out_of_order:2:1776.7}sofia/internal/[email protected]|sofia/sip/[email protected]"/>

Here we have a bridge application that ignores early media and that sets two failure conditions, one for busy and one for destination out of order. We specify the name of the condition we are checking, the number of hits, and the frequencies to detect. The format for monitor_early_media_fail is:

condition_name:number_of_hits:tone_detect_frequencies

The user_busy condition is defined as user_busy:2:480+620. This condition looks for both 480 Hz and 620 Hz frequencies (which is the U.S. busy signal) and if they are detected twice, then the call will fail. The exclamation point (!) is the delimiter between conditions. The destination_out_of_order condition is defined as:

destination_out_of_order:2:1776.7. 

This looks for two occurrences of 1776.7 Hz, which is a common SIT tone frequency in the U.S (there is a nice introductory article on SIT tones at http://en.wikipedia.org/wiki/Special_information_tones). If 1776.7 Hz is heard twice, then the call will fail as destination out of order.

When using monitor_early_media_fail, only the designated frequencies are detected. All other tones and frequencies are ignored.

Handling no answer conditions

Handling a no answer condition is different from busy and other in-band errors. In some cases, the service provider will send back a SIP message 480 (NO_ANSWER) whereas others will send a ringing signal in the early media until the caller decides to hang up. The former scenario is handled automatically by the bridge application. The latter can be customized with the use of special timeout variables:

  • call_timeout: Sets the call timeout for all legs when using bridge

  • originate_timeout: Sets the call timeout for all legs when using originate

  • leg_timeout: Sets a different timeout value for each leg

  • originate_continue_on_timeout: Specifies whether or not the entire bridge or originate operation should fail if a single call leg times out

By default, each call leg has a timeout of 60 seconds and bridge/originate will stop after any leg times out. The three timeout variables allow you to customize the timeout settings for the various call legs. Use call_timeout when using the bridge application and use originate_timeout when using the originate API. Use leg_timeout if you wish to have a different timeout value for each dialstring. In that case, use the [leg_timeout=###] notation for each dialstring:

<action application="bridge" data="[leg_timeout=10]sofia/internal/[email protected]|[leg_timeout=15]sofia/internal/[email protected]"/>

Use originate_continue_on_timeout to force bridge or originate to continue dialing even if one of the endpoints fails with a timeout:

<action application="bridge" data="{originate_continue_on_timeout=true}[leg_timeout=10]sofia/internal/[email protected]|[leg_timeout=15]sofia/internal/[email protected]"/>

Keep in mind that, by default, a timeout (that is, a no answer) will end the entire bridge or originate if you do not set originate_continue_on_timeout to true.

One other thing to keep in mind is handling cases where you are calling a phone number that has voicemail. For example, if you are trying to implement a type of "find me, follow me" and one of the numbers being called is a mobile phone with voicemail, you need to decide if you want that phone's voicemail to answer your call. If it does answer, then the bridge will be completed. If you do not want to have the voicemail answer and end the bridge (so that your bridge will keep dialing the other endpoints), then be sure to set the leg_timeout to a relatively low value. If the voicemail picks up after 15 seconds, then you may wish to set leg_timeout=12. In most cases, you will need to make several test calls to find the best timeout values for your various endpoints.

Using individual bridge calls

In some cases, you may find that it is helpful to make a dial attempt to a single endpoint and then do some processing prior to dialing the next endpoint. In these cases, the pipe-separated list of endpoints will not suffice. However, the FreeSWITCH XML dialplan allows you to do this in another way. Consider this excerpt:

<extension name="ring_sequentially">
  <condition field="destination_number" expression="^(2001)$">
    <action application="set" data="continue_on_fail=true"/>
    <action application="set" data="hangup_after_bridge=true"/>
    <action application="bridge" data={ignore_early_media=true}sofia/internal/[email protected]"/>
    <action application="log" data="INFO call to userA failed."/>
    <action application="bridge" data={ignore_early_media=true}sofia/internal/[email protected]"/>
    <action application="log" data="INFO call to userB failed."/>
  </condition>
</extension>

The key to this operation is the highlighted lines. In the first one, we set continue_on_fail to true. This channel variable tells FreeSWITCH to keep processing the actions in the extension even if a bridge attempt fails. After each bridge attempt, you can then do some processing. Note, too, that we set hangup_after_bridge to true. This is done so that the dialplan does not keep processing after a successful bridge attempt. (For example, if the call to userA was successful, we would not want to call userB after userA hung up.) You may add as many additional bridge endpoints as needed.

See also

  • The Ringing multiple endpoints simultaneously and Advanced multiple endpoint calling with enterprise originate sections in this chapter

 

Advanced multiple endpoint calling with enterprise originate


You've seen many ways to ring multiple destinations with many options, but in some cases this is still not good enough. Say you wanted to call two destinations at once but each of those two destinations was a separate set of simultaneous or sequential destinations.

For instance, you want to call Bill and Susan at the same time, but Bill prefers you to try his cell first, then try all of his landlines at the same time. Susan prefers you to call her desk first, then her cell, and then her home. This is a complicated problem and the solution to that problem is called enterprise originate. The term enterprise is used to indicate an increased level of indirection, dimension, or scale. Basically, you are doing everything the originate syntax has to offer, but you are doing entire originates in parallel in a sort-of super originate.

Getting ready

The first thing you need to do to take advantage of enterprise originate is to fully understand the regular originate. Originate is the term used to indicate making an outbound call. Although there is an originate command that can be used at the fs_cli, the method by which you mostly use the originate command is with the bridge dialplan application.

Tip

The bridge application versus the originate command

Why do we talk about a regular originate when discussing the bridge application? Are not the bridge application and the originate command completely different? No! This is a common misconception, and it is incorrect. The bridge application is used in the dialplan, but it does exactly the same thing that the originate command does – it creates a new call leg. In fact, bridge and originate use exactly the same code in the FreeSWITCH core. The only difference between the two is where they are used. The originate command is used at the fs_cli to create a new call leg. The bridge application is used in the dialplan to create a new call to which an existing call leg can be connected or bridged.

You will need to open conf/dialplan/default.xml in a text editor or create or edit a new XML file in the conf/dialplan/default/ subdirectory.

How to do it...

The usage of enterprise originate is similar to the ring simultaneously example, but an alternate delimiter (:_:) is used:

<extension name="enterprise_originate">
  <condition field="destination_number" expression="^(2000)$">
    <action application="bridge" data="{ignore_early_media=true}sofia/internal/[email protected]:_:{myoption=true}sofia/sip/[email protected]"/> 
  </condition>
</extension>

<extension name="enterprise_originate2">
  <condition field="destination_number" expression="^(2001)$">
    <action application="bridge" data="{ignore_early_media=true}sofia/internal/[email protected],sofia/sip/[email protected]:_:sofia/internal/[email protected],sofia/internal/[email protected]"/> 
  </condition>
</extension>

How it works...

The entire input string is broken up into smaller strings, based on the :_: symbol.

Each of those smaller strings is fed to the regular originate engine in parallel and the first channel to answer will be bridged to the caller. Once one endpoint answers, the rest of the calls in the enterprise will be canceled.

There's more...

Enterprise originate has a few special aspects to consider when using it to place calls.

Setting variables

As you know, you can use the {var=val} syntax to define special variables to be set on all channels produced by originate and [var=val] to define variables per leg in a call with many simultaneous targets. Enterprise originate uses these as well, but remember that each string separated by the :_: delimiter is its own self-contained instance of originate so {var=val} becomes local only to that single originate string. If you want to define variables to be set on every channel of every originate, you must define them at the very beginning of the string using the <var=val> notation. This indicates that you should pass these variables to every leg inside every originate. Consider the following enterprise originate:

<action application="bridge" data="<ignore_early_media=true>{myvar=inner1}[who=userA]sofia/internal/[email protected],[who=userB]sofia/sip/[email protected]:_:{myvar=inner2}[who=userC]sofia/internal/[email protected],[who=userD]sofia/internal/[email protected]"/> 

At first glance, this may seem confusing, but when you break it down, you can see what the values of the variables are for each channel. This table shows the values:

Channel

${ignore_early_media}

${myvar}

${who}

[email protected]

true

inner1

userA

[email protected]

true

inner1

userB

[email protected]

true

inner2

userC

[email protected]

true

inner2

userD

Once you know which syntax to use, it becomes a simple matter to set channel variables for individual legs, inside originates, or the entire enterprise originate.

Ringback

Unlike the regular originate, signaling cannot be passed back from one of the inner originates because there are too many call paths open to properly handle it. Therefore, when using bridge with the enterprise originate, you must define the ringback variable if you want to send a ring tone back to the caller.

See also

To learn more about originate and enterprise originate, look at some of the other examples in this chapter and study the default dialplan distributed with FreeSWITCH. There are several examples of the many things you can do when placing outbound calls found in conf/dialplan/default.xml.

 

Time of day routing


It is common for routing of calls to be different, depending upon the time of day or day of the week. The FreeSWITCH XML dialplan has a number of parameters to allow this functionality.

Getting ready

Determine the parameters for your routing. In this example, we will define business hours as Monday through Friday, 8AM to 5PM. Additionally, we will add a day_part variable to reflect morning (midnight to noon), afternoon (noon to 5PM), or evening (6PM to midnight).

How to do it...

Create an extension at the beginning of your dialplan by following these steps:

  1. Add this extension to the beginning of your dialplan context:

    <extension name="Time of day, day of week setup" continue="true">
      <condition wday="2-6" hour="8-17" break="never">
        <action application="set" data="office_status=open"inline="true"/>
        <anti-action application="set" data="office_status=closed" inline="true"/>
      </condition>
      <condition hour="0-11" break="never">
        <action application="set" data="day_part=morning" inline="true"/>
      </condition>
      <condition hour="12-17" break="never">
        <action application="set" data="day_part=afternoon" inline="true"/>
      </condition>
      <condition hour="18-23" break="never">
        <action application="set" data="day_part=evening" inline="true"/>
      </condition>
    </extension>
  2. Later in your dialplan, you can use the variables office_status and day_part. office_status will contain either "open" or "closed" and day_part will contain "morning", "afternoon", or "evening". A typical usage would be to play different greetings to the caller, depending upon whether or not the office is open. Add these dialplan extensions, which will accomplish the task:

    <extension name="tod route, x5001">
      <condition field="destination_number" expression="^(5001)$">
        <action application="execute_extension" data="5001_${office_status}"/>
      </condition>
    </extension>
    <extension name="office is open">
      <condition field="destination_number" expression="^(5001_open)$">
        <action application="answer"/>
        <action application="sleep" data="1000"/>
        <action application="playback" data="ivr/ivr-good_${day_part}.wav"/>
        <action application="sleep" data="500"/>
        <!-- play IVR for office open -->
      </condition>
      </extension>
    <extension name="office is closed">
        <condition field="destination_number" expression="^(5001_closed)$">
          <action application="answer"/>
          <action application="sleep" data="1000"/>
          <action application="playback" data="ivr/ivr-good_${day_part}.wav"/>
          <action application="sleep" data="500"/>
        <!-- play IVR for office closed -->
      </condition>
    </extension>
  3. Save your XML file and press F6 or issue the reloadxml command at the fs_cli.

How it works...

The Time of day , day of week setup extension defines two channel variables, namely, office_status and day_part. Note the use of inline="true" in our set applications. These allow for immediate use of the channel variables in later dialplan condition statements. Every call that hits this dialplan context will now have these two channel variables set (they will also show up in CDR records if you need them). You may have also noticed continue="true" in the extension tag and break="never" in the condition tags. These tell the dialplan parser to keep looking for more matches when it would otherwise stop doing so. For example, without continue="true" set, when the dialplan matched one of the conditions in the Time of day , day of week setup extension, then it would stop looking at any more extensions in the dialplan. In a similar way, the break="never" attribute tells the parser to keep looking for more conditions to match within the current extension (by default, when the parser hits a failed condition, it stops processing any more conditions within the current extension).

Note

A detailed discussion of dialplan processing can be found in chapters 5 and 8 of Packt Publishing's FreeSWITCH 1.0.6 book.

Our sample extension number is 5001. Note the action it takes:

<action application="execute_extension" data="5001_${office_status}"/>

This sends the call back through the dialplan looking for a destination_number of 5001_open or 5001_closed. We have defined both of those destinations with the extensions "office is open" and "office is closed," respectively. Now we can play different greetings to the caller—one for when the office is open and a different one for when the office is closed. As a nice touch, for all calls, we play a sound file that says, "Good morning", "Good afternoon", or "Good evening", depending on what value is in the channel variable day_part.

Tip

The execute_extension and transfer dialplan applications

These two applications both tell FreeSWITCH to execute another part of the dialplan. The primary difference is that execute_extension will return after executing another portion of the dialplan, whereas a transfer sends control to the target extension. In programming parlance, execute_extension is like a gosub command and transfer is like a goto command. The former comes back but the latter does not.

There's more...

You may be wondering why we did not simply use a condition to test office_status for the value open and then use action tags for "office open" and anti-action tags for "office closed". There is nothing preventing us from doing this. However, what if you need to have an office status other than "open" or "closed"? For example, what if you have an office that needs to play a completely different greeting during lunch time? This is difficult to accomplish with only anti-action tags, but with our example, it is almost trivial. Let's make it a bit more challenging by adding a lunch period that runs from 11:30AM to 12:30PM. We cannot use hour="11.5-12.5", however, we do have another value we can test—time-of-day. This parameter lets us define periods in the day at a granularity of minutes or even seconds. The value range is 00:00 through 23:59 or 00:00:00 through 23:59:59. Consider this new Time of day, day of week setup snippet:

<extension name="Time of day, day of week setup" continue="true">
  <condition wday="2-6" hour="8-17" break="never">
    <action application="set" data="office_status=open" inline="true"/>
    <anti-action application="set" data="office_status=closed" inline="true"/>
  </condition>
  <condition wday="2-6" time-of-day="11:30-12:30" break="never">
    <action application="set" data="office_status=lunch" inline="true"/>
  </condition>

Notice that we need to explicitly define the weekend, since we cannot rely on a simple boolean open or closed condition. However, we now have a new office_status of lunch available to us. We define an additional extension to handle this case:

<extension name="office is at lunch">
  <condition field="destination_number" expression="^(5001_lunch)$">

Add the specific dialplan actions for handling calls during the office's lunch hour and you are done. You can add as many new office statuses as you need.

See also

Refer to the XML dialplan wiki page (http://wiki.freeswitch.org/wiki/Dialplan_XML) for more information on the usage of break, continue, and inline attributes.

 

Manipulating To: headers on registered endpoints to reflect DID numbers


Sometimes, when routing calls to endpoints that are registered to your system, you want to utilize custom To: headers. For example, if you are routing DIDs to a PBX or switch, the device you are calling might expect the phone number you wish to reach in the To: header. However, the customer or PBX may only have a single registration to your service that represents multiple DIDs that need to be routed.

By default, no flags exist to change the To: header to match the DID when calling a registered endpoint. Since the registration to your server is typically done via a generic username that is not related to the DID, you must program your dialplan to retrieve a user's registration information and parse out the username portion of the To: header, replacing it with your own. Care must be taken to replace only the username portion and to keep the remaining parameters intact, especially if NAT traversal is expected to continue operating.

Getting ready

Be sure that you have your DIDs and users configured. In this example, we will use testuser as the username with a phone number of 4158867999 and our domain is my.phoneco.test.

How to do it...

Create a dialplan extension, specifically for handling calls to the DID number and use some regular expression syntax to parse out the information. Here is an example:

<extension name="call_4158867999">
  <condition field="destination_number" expression="^\+?1?4158867999$"/>
  <condition field="${sofia_contact([email protected])}" expression="^[^\@]+(.*)">
    <action application="bridge" data="sofia/external/4158867999$1"/>
  </condition>
</extension>

How it works...

You would typically make bridge calls to testuser using the bridge command with an argument of user/testuser. In this scenario, however, you wish to call testuser's registered endpoint but replace testuser with a phone number – 4158867999, in our example. To do this, you must retrieve testuser's current dialstring and remove the username, replacing it with the DID number.

In the example, we leverage the sofia_contact API and some regular expression magic. The first condition simply matches the user's DID phone number—we only want to act if the destination number is 4158867999. The interesting stuff happens in the second condition. The field is ${sofia_contact([email protected])}. By wrapping an API call in ${}, the dialplan literally executes the API and uses the result as the field value. If we go to fs_cli and type sofia_contact [email protected], we get the result, which is something like this:

sofia/external/[email protected];fs_nat=yes

The regular expression pattern ^[^\@]+(.*) is applied against this value. The result is that everything after the @ is placed in the $1 variable. In our example, $1 contains @12.13.56.7;fs_nat=yes. Finally, we execute the bridge with the dialstring sofia/external/4158867999$1. With $1 expanded out, our destination is as follows:

sofia/external/[email protected];fs_nat=yes

We have successfully replaced testuser with 4158867999 while preserving the necessary IP address and parameters for contacting the server and sent the call to the proper destination.

About the Authors

  • Anthony Minessale II

    Anthony Minessale II is the primary author and founding member of the FreeSWITCH Open Source Soft-Switch. Anthony has spent around 20 years working with open source software. In 2001, Anthony spent a great deal of time contributing code to the Asterisk PBX and has authored numerous features and fixes to that project. In 2005, Anthony started coding a new idea for an open source voice application. The FreeSWITCH project was officially open to the public on January 1 2006. In the years that followed, Anthony has been actively maintaining and leading the software development of the FreeSWITCH project. Anthony also founded the ClueCon Technology Conference in 2005, and he continues to oversee the production of this annual event.

    Anthony has been the author of several FreeSWITCH books, including FreeSWITCH 1.0.6, FreeSWITCH 1.2, FreeSWITCH Cookbook, FreeSWITCH 1.6 Cookbook, and Mastering FreeSWITCH

    Browse publications by this author
  • Michael S Collins

    Michael S Collins is a telephony and open source software enthusiast. Having worked as a PBX technician for 5 years and the head of IT for a call center for more than 9 years, he is a PBX veteran. He is an active member of the FreeSWITCH community and has coauthored FreeSWITCH Cookbook, by Packt Publishing in 2012. Michael lives in Central California with his wife and two children.

    Browse publications by this author
  • Darren Schreiber

    Darren Schreiber is the CEO and Co-founder of 2600 Hz. He began working heavily in open source voice with the FreeSWITCH project, where he engaged with Brian, Mike, and Anthony. His projects have since evolved into two enterprise VoIP platforms that allow a multitude of development of voice, SMS, and video applications to be delivered to customers.

    He has 15 years of voice and IT experience including developing multiple enterprise SaaS infrastructures for hosting and remotely managing IT, voice, and e-commerce services. He is a guest lecturer at major universities on VoIP technology and leads paid international VoIP trainings. As a serious telephony enthusiast since a young age, he has worked extensively with VoIP technologies. He graduated from Rensselaer Polytechnic Institute with a degree in Computer Science and Business Management.

    He is also a co-author of FreeSWITCH Cookbook, Packt Publishing.

    Browse publications by this author
  • Raymond Chandler

    Raymond Chandler(@intralanman) has been working with, and contributing to, open source projects for over a decade. Raymond's VoIP experience started with a small CLEC/ITSP using SER for call routing, and Asterisk for voicemail and advanced services. After encountering limits in Asterisk and looking for features not easily found in SER, he moved to using OpenSER and CallWeaver (then known as OpenPBX.org). While that combination was better, he still had not found his perfect solution. In 2006, he was introduced to FreeSWITCH. Since then, he's been using FreeSWITCH and regularly contributing to the community. He is the author of mod_lcr and several utility PHP/Perl scripts. He now works with Anthony Minessale as a CudaTel Software Engineer at Barracuda Networks (@CudaTel and @Barracuda). In the spring of 2011, he was among the founding members of the Open Source Telephony Advancement Group (@OSTAG), whose mission is to advance open source telephony to new heights by funding open source projects through funds received by generous contributions and grants from those who share the OSTAG vision.

    Browse publications by this author

Latest Reviews

(2 reviews total)
Very good written book with examples and real life scanarios. It helped us to deploy and configure FreeSwitch.
Clear and well written book.
FreeSWITCH Cookbook
Unlock this book and the full library for FREE
Start free trial