Chapter 8. Advanced Dialplan Concepts
In the preceding chapters you learned a bit about the power of the XML configuration files used in FreeSWITCH. Specifically, you learned about Dialplan entries and using XML to set general configuration settings. In this chapter, we will dive deep into the general structure of Dialplans, features of the XML Dialplan processing system, and how you can use what appear to be very basic features to achieve very complex results.
Some items in this chapter may appear to be repetitive, but we want to go back over some basic Dialplan functionality talked about elsewhere, and be sure we explain the how's and why's of the Dialplan system. It is quite common for people to use the XML Dialplan in FreeSWITCH without really understanding it, hampering efforts to extend the system or debug complex problems. This chapter aims to make you an expert at exactly how and why things operate the way they do within the Dialplan.
In this chapter, we will presume you have some...
The Dialplan engine in FreeSWITCH is an incredibly flexible piece of software. If you have a background of using other switching systems, you are probably used to the Dialplan being tied to a somewhat flat, static set of logic statements—you pre-program a set of decisions in the switch's native language (that is, answer calls, play files, collect digits, and transfer calls) and this happens for every call. Anything that cannot be done using the pre-built commands and logic statements available in that switch, well, just cannot be done.
In FreeSWITCH,
Dialplan processing is actually done by the loadable module. The logic in this module is called every time a call is handled, and you can even load multiple Dialplan modules so as to process calls in a different way, depending on the logic you need. This is a very important distinction between FreeSWITCH and other systems, and it is often overlooked. By making Dialplan processing modular, a new form of freedom is introduced...
General Dialplan concepts
In general, a Dialplan helps generate a list of actions to take so that a caller can reach the person or people they want to talk to. A Dialplan module implements the decision-making process that powers this. While a Dialplan module is free to implement any concept it wants for organizing how calls are routed, three concepts, in particular, are generally used when processing a call. These three concepts can be broken down by asking the same three questions for every call:
Contexts: Where do we look for a general list of destinations (or features) that the current caller is allowed to reach?
Conditions: Whom,
specifically, is the caller trying to reach?
Actions: What actions need to be taken to reach that party?
These three questions are generally answered by breaking routing decisions into three concepts—caller context, condition matching, and actions. These concepts are not necessarily unique to FreeSWITCH. We'll explore each of these concepts individually in this...
XML Dialplan module review
As we discussed in Chapter 5, the XML Dialplan module is the most popular way to configure FreeSWITCH. At the time of writing this book it is also the most robust. It supports contexts which contain lists of extensions, with each extension containing one or more conditions, and each condition containing a list of actions to execute. Let's review a few concepts to make sure that you are fully comfortable with them.
The searching and processing of Dialplan entries is based on an expected layout that looks something like a multi-dimensional tree.
After a quick glance at the expected structure of your Dialplan and how it is used, it should be somewhat obvious why XML lends itself as a good choice for the creation of a Dialplan. The nesting attributes of XML are a perfect fit for the scenario shown. FreeSWITCH relies on a tree of configuration options in a Dialplan, and XML is naturally a limitless tree-like structure that allows for embedding values within each leaf...
While we would love to go through all the available Dialplan commands, the list far exceeds the space we have for this chapter. Therefore, we will limit our discussion of available Dialplan commands to three areas—Dialplan tools, Sofia connectivity, and general API commands. These Dialplan commands are provided by mod_dptools
, mod_sofia
, and mod_commands
respectively.
mod_dptools:
mod_dptools
is a collection of Dialplan management tools. There are many, many commands available from within the Dialplan. You have already learned how basic commands like answer
, hangup
, bridge
, and set
work. Let us go over a few of the more advanced commands.
bind_meta_app:
bind_meta_app
binds an application to the specified call leg(s). During a bridged call, the DTMF sequence on the bound call leg will trigger the execution of the application. The call leg that is not bound will not hear the DTMF sequence being dialed. You can only bind a single digit, and the binding is always proceeded...
While it has been mentioned previously, the concept of hunting versus executing really deserves a closer look. It is important to understand that the Dialplan processor is different from the actual execution of the Dialplan. Furthermore, you can tweak this behavior to blur the line between this distinction to gain extra power, but at the expense of some added complexity.
To understand hunting versus executing you must first understand that FreeSWITCH breaks calls up into various states for processing. Every call in FreeSWITCH goes through these states – beginning a new channel, routing of the call, executing actions on the call, ending the call, reporting on the call, and finally killing the channel and all associated memory. The two specific states of the call relevant to this chapter are ROUTE
and EXECUTE
. Route refers to the stage when FreeSWITCH is looking for Dialplan actions to take based on the information about a call and your loaded Dialplan module. The ROUTE...
Up to this point we have considered the basic use of channel variables. FreeSWITCH has more advanced ways of using variables, including global variables. Let's round out our understanding of variables by looking at some of these.
Testing variables with regular expressions
We have already discussed the purpose and basic use of the condition XML tag. Now we will discuss the different elements you can actually test to help make decisions about call handling.
FreeSWITCH offers three general categories of variables that you can test – caller profile fields, channel variables, and global variables. In addition, you can utilize macros and API functions and utilize their output in your conditions as well. We will review each of these in detail.
Caller profile fields are variables that are retrieved when a caller is authenticated. The variables are set within the directory and can include things like the caller's area code, codec preferences, and so on. You can...
Dialplan functions are small pieces of functionality that run real-time when processing Dialplan conditions. They can be used to gain a little more control and flexibility when writing your condition statements.
Dialplan functions can actually be used elsewhere – not just in the Dialplan. They are also not related to XML – they can be used anywhere that a FreeSWITCH string processor is invoked. Examples of other places they may appear include external scripts that execute and set variables, bridge
and transfer
statements, and so on. The general format for
Dialplan functions is:
where api_func
is the name of the Dialplan function, api_args
is the name of the arguments to pass to the function, and ${var_name}
is an optional variable name to pass to the function. The format and expected parameters for api_args
vary depending on the function being used. Each available Dialplan function is explained as follows in more detail.
When performing a bridge
to connect two different call legs, you may find that you have a channel variable in the originating leg (the A leg) that you wish to be available also in the B leg. Sometimes you have a value that you want only to appear in one leg or the other. The techniques presented in this section will explain how to accomplish these tasks.
There are two general API commands available to set and modify information about calls and the way the switch will process calls. These commands are named set
and export
.
The
set
command sets variables on a channel, for use during the duration of the channel. These variables can then be accessed by applications (such as CDR) or by Dialplan condition testing. You have seen the set
command used several times in examples throughout this book.
The export
command takes set
a step further. It sets variables on the current channel but also saves the variable for use in any future channels created that stem from...
We present here a few common scenarios that you may need to refer to from time-to-time because they are relatively common. The examples presented in this section are in the mold of the tradition "cookbook" full of "recipes" for the reader to try. Feel free to use and modify these recipes in your custom Dialplans.
Match by IP address and call a number
In the example as follows, 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
The first condition field is terminated by...
We have mentioned that XML is the primary, and most popular, Dialplan parser used in FreeSWITCH but there are some other modules that people have committed that you can also use, such as YAML.
mod_yaml
provides a YAML interface to Dialplan configuration. This Dialplan module can be used in place of the XML Dialplan interface. While the module is not currently in development anymore due to lack of interest, the C code provides an interesting look into how one might write their own Dialplan processing routines.
If you are interested in creating your own Dialplan configuration processing engine, you could analyze components of the YAML Dialplan system.
Note
The history behind mod_yaml
is an interesting anecdote that highlights both the power and flexibility of the FreeSWITCH platform as well as Anthony's iron-like determination to prove that the FreeSWITCH developers are not whimsical when it comes to making important decisions about FreeSWITCH development, including what...
In this chapter we delved very deeply into the operation of the FreeSWITCH Dialplan. Building upon the foundation laid in Chapter 5, we discussed many advanced Dialplan concepts:
How Dialplan parsing works
Using global variables and channel variables
Advanced use of regular expressions
Time of day routing and other advanced routing concepts
The Dialplan system in FreeSWITCH is one of the most important concepts you can learn. The power of FreeSWITCH is truly unleashed within the Dialplan system itself, and understanding the complexities of using various functions within FreeSWITCH is key to ensuring FreeSWITCH performs exactly the way you want.