Dialplan Syntax

The Asterisk dialplan is specified in the configuration file named extensions.conf.

Tip

The extensions.conf file usually resides in the /etc/asterisk/ directory, but its location may vary depending on how you installed Asterisk. Other common locations for this file include /usr/local/etc/asterisk/ and /opt/etc/asterisk/.

The dialplan is made up of four main concepts: contexts, extensions, priorities, and applications. After explaining the role each of these elements plays in the dialplan, we’ll have you build a basic but functioning dialplan.

Contexts

Dialplans are broken into sections called contexts. Contexts keep different parts of the dialplan from interacting with one another. An extension that is defined in one context is completely isolated from extensions in any other context, unless interaction is specifically allowed. (We’ll cover how to allow interaction between contexts near the end of the chapter. See the section called “Includes” for more information.)

As a simple example, let’s imagine we have two companies sharing an Asterisk server. If we place each company’s automated attendant in its own context, they will be completely separated from each other. This allows us to independently define what happens when, say, extension 0 is dialed: Callers dialing 0 from Company A’s voice menu will get Company A’s receptionist, while callers dialing 0 at Company B’s voice menu will get Company B’s receptionist. (This assumes, of course, that we’ve told Asterisk to transfer the calls to the receptionists when callers press 0.[54])

Contexts are defined by placing the name of the context inside square brackets ([]). The name can be made up of the letters A through Z (upper- and lowercase), the numbers 0 through 9, and the hyphen and underscore.[55] A context for incoming calls might look like this:

[incoming]

Note

Context names have a maximum length of 79 characters (80 characters – 1 terminating null).

All of the instructions placed after a context definition are part of that context, until the next context is defined. At the beginning of the dialplan, there are two special contexts named [general] and [globals]. The [general] section contains a list of general dialplan settings (which you’ll probably never have to worry about), and we will discuss the [globals] context in the section the section called “Global variables”. For now, it’s just important to know that these two labels are not really contexts. Avoid the use of [general], [default], and [globals] as context names, but otherwise name your contexts anything you wish.

When you define a channel (which is not done in the extensions.conf file, but rather in files such as sip.conf, iax.conf, chan_dahdi.conf, etc.), one of the required parameters in each channel definition is context. The context is the point in the dialplan where connections from that channel will begin. The context setting for the channel is how you plug the channel into the dialplan. Figure 6.1, “Relation between channel configuration files and contexts in the dialplan” illustrates the relationship between channel configuration files and contexts in the dialplan.

Figure 6.1. Relation between channel configuration files and contexts in the dialplan

Relation between channel configuration files and contexts in the dialplan

Note

This is one of the most important concepts to understand when dealing with channels and dialplans. Once you understand the relationship of the context definition in a channel to the matching context in the dialplan, you will find it much easier to troubleshoot the call flow through an Asterisk system.

An important use of contexts (perhaps the most important use) is to provide security. By using contexts correctly, you can give certain callers access to features (such as long-distance calling) that aren’t made available to others. If you do not design your dialplan carefully, you may inadvertently allow others to fraudulently use your system. Please keep this in mind as you build your Asterisk system; there are many bots on the Internet that were specifically written to identify and exploit poorly secured Asterisk systems.

Warning

The Asterisk wiki at https://wiki.asterisk.org/wiki/display/AST/Important+Security+Considerations outlines several steps you should take to keep your Asterisk system secure. (Chapter 26, Security in this book also deals with security.) It is vitally important that you read and understand this page. If you ignore the security precautions outlined there, you may end up allowing anyone and everyone to make long-distance or toll calls at your expense!

If you don’t take the security of your Asterisk system seriously, you may end up paying—literally. Please take the time and effort to secure your system from toll fraud.

Extensions

In the world of telecommunications, the word extension usually refers to a numeric identifier that, when dialed, will ring a phone (or system resource such as voicemail or a queue). In Asterisk, an extension is far more powerful, as it defines the unique series of steps (each step containing an application) through which Asterisk will take that call.

Within each context, we can define as many (or few) extensions as required. When a particular extension is triggered (by an incoming call or by digits being dialed on a channel), Asterisk will follow the steps defined for that extension. It is the extensions, therefore, that specify what happens to calls as they make their way through the dialplan. Although extensions can, of course, be used to specify phone extensions in the traditional sense (i.e., extension 153 will cause the SIP telephone set on John’s desk to ring), in an Asterisk dialplan, they can be used for much more.

The syntax for an extension is the word exten, followed by an arrow formed by the equals sign and the greater-than sign, like this:

exten =>

This is followed by the name (or number) of the extension. When dealing with traditional telephone systems, we tend to think of extensions as the numbers you would dial to make another phone ring. In Asterisk, you get a whole lot more; for example, extension names can be any combination of numbers and letters. Over the course of this chapter and the next, we’ll use both numeric and alphanumeric extensions.

Tip

Assigning names to extensions may seem like a revolutionary concept, but when you realize that many VoIP transports support (or even actively encourage) dialing by name or email address rather than just by number, it makes perfect sense. This is one of the features that makes Asterisk so flexible and powerful.

Each step in an extension is composed of three components:

  • The name (or number) of the extension

  • The priority (each extension can include multiple steps; the step number is called the “priority”)

  • The application (or command) that will take place at that step

These three components are separated by commas, like this:

exten => name,priority,application()

Here’s a simple example of what a real extension might look like:

exten => 123,1,Answer()

In this example, the extension name is 123, the priority is 1, and the application is Answer().

Priorities

Each extension can have multiple steps, called priorities. The priorities are numbered sequentially, starting with 1, and each executes one specific application. As an example, the following extension would answer the phone (in priority number 1), and then hang it up (in priority number 2):

exten => 123,1,Answer()
exten => 123,2,Hangup()

It’s pretty obvious that this code doesn’t really do anything useful. We’ll get there. The key point to note here is that for a particular extension, Asterisk follows the priorities in order. This style of dialplan syntax is still seen from time to time, although (as you’ll see momentarily) it is not generally used anymore for new code:

exten => 123,1,Answer()
exten => 123,2,do something
exten => 123,3,do something else
exten => 123,4,do one last thing
exten => 123,5,Hangup()

Unnumbered priorities

In older releases of Asterisk, the numbering of priorities caused a lot of problems. Imagine having an extension that had 15 priorities, and then needing to add something at step 2: all of the subsequent priorities would have to be manually renumbered. Asterisk does not handle missing steps or misnumbered priorities, and debugging these types of errors was pointless and frustrating.

Beginning with version 1.2, Asterisk addressed this problem: it introduced the use of the n priority, which stands for “next.” Each time Asterisk encounters a priority named n, it takes the number of the previous priority and adds 1. This makes it easier to make changes to your dialplan, as you don’t have to keep renumbering all your steps. For example, your dialplan might look something like this:

exten => 123,1,Answer()
exten => 123,n,do something
exten => 123,n,do something else
exten => 123,n,do one last thing
exten => 123,n,Hangup()

Internally, Asterisk will calculate the next priority number every time it encounters an n.[56] Bear in mind that you must always specify priority number 1. If you accidentally put an n instead of 1 for the first priority (a common mistake even among experienced dialplan coders), you’ll find after reloading the dialplan that the extension will not exist.

The 'same =>' operator

In the never-ending effort to simplify coding effort, a new construct was created to make extension building and management even easier. As long as the extension remains the same, rather than having to type the full extension on each line, you can simply type same => , followed by the priority and application:

exten => 123,1,Answer()
   same => n,do something
   same => n,do something else
   same => n,do one last thing
   same => n,Hangup()

The indentation is not required, but it may make for easier reading. This style of dialplan will also make it easier to copy code from one extension to another. We prefer this style ourselves, and highly recommend it.

Priority labels

Priority labels allow you to assign a name to a priority within an extension. This is to ensure that you can refer to a priority by something other than its number (which probably isn’t known, given that dialplans now generally use unnumbered priorities). The reason it is important to be able to address a particular priority in an extension is that you will often want to send calls from other parts of the dialplan to a particular priority in a particular extension. We’ll talk about that more later. To assign a text label to a priority, simply add the label inside parentheses after the priority, like this:

exten => 123,n(label),application()

Later, we’ll cover how to jump between different priorities based on dialplan logic. You’ll see a lot more of priority labels, and you’ll use them often in your dialplans.

Warning

A very common mistake when writing labels is to insert a comma between the n and the (, like this:

exten => 123,n,(label),application() ;<-- THIS IS NOT GOING TO WORK

This mistake will break that part of your dialplan, and you will get an error stating that the application cannot be found.

Applications

Applications are the workhorses of the dialplan. Each application performs a specific action on the current channel, such as playing a sound, accepting touch-tone input, looking something up in a database, dialing a channel, hanging up the call, and so forth. In the previous example, you were introduced to two simple applications: Answer() and Hangup(). You’ll learn more about how these work momentarily.

Some applications, including Answer() and Hangup(), need no other instructions to do their jobs. Most applications, however, require additional information. These additional elements, or arguments, are passed on to the applications to affect how they perform their actions. To pass arguments to an application, place them between the parentheses that follow the application name, separated by commas.

Tip

Occasionally, you may also see the pipe character (|) being used as a separator between arguments, instead of a comma. Starting in Asterisk 1.6.0, support for the pipe as a separator character has been removed.[57]

The Answer(), Playback(), and Hangup() Applications

The Answer() application is used to answer a channel that is ringing. This does the initial setup for the channel that receives the incoming call. As we mentioned earlier, Answer() takes no arguments. Answer() is not always required (in fact, in some cases it may not be desirable at all), but it is an effective way to ensure a channel is connected before performing further actions.

The Playback() application is used for playing a previously recorded sound file over a channel. Input from the user is ignored, which means that you would not use Playback() in an auto attendant, for example, unless you did not want to accept input at that point.[58]

Tip

Asterisk comes with many professionally recorded sound files, which should be found in the default sounds directory (usually /var/lib/asterisk/sounds/). When you compile Asterisk, you can choose to install various sets of sample sounds that have been recorded in a variety of languages and file formats. We’ll be using these files in many of our examples. Several of the files in our examples come from the Extra Sound Package, so please take the time to install it (see Chapter 3, Installing Asterisk). You can also have your own sound prompts recorded in the same voices as the stock prompts by visiting http://www.theivrvoice.com/. Later in the book we’ll talk more about how you can use a telephone and the dialplan to create and manage your own system recordings.

To use Playback(), specify a filename (without a file extension) as the argument. For example, Playback(filename) would play the sound file called filename.wav, assuming it was located in the default sounds directory. Note that you can include the full path to the file if you want, like this:

Playback(/home/john/sounds/filename)

The previous example would play filename.wav from the /home/john/sounds/ directory. You can also use relative paths from the Asterisk sounds directory, as follows:

Playback(custom/filename)

This example would play filename.wav from the custom/ subdirectory of the default sounds directory (probably /var/lib/asterisk/sounds/custom/filename.wav). Note that if the specified directory contains more than one file with that filename but with different file extensions, Asterisk automatically plays the best file.[59]

The Hangup() application does exactly as its name implies: it hangs up the active channel. You should use this application at the end of a context when you want to end the current call, to ensure that callers don’t continue on in the dialplan in a way you might not have anticipated. The Hangup() application does not require any arguments, but you can pass an ISDN cause code if you want (e.g., Hangup(16)).

As we work through the book, we will be introducing you to many more Asterisk applications.



[54] This is a very important consideration. With traditional PBXs, there are generally a set of defaults for things like reception, which means that if you forget to define them, they will probably work anyway. In Asterisk, the opposite is true. If you do not tell Asterisk how to handle every situation, and it comes across something it cannot handle, the call will typically be disconnected. We’ll cover some best practices later that will help ensure this does not happen. See the section called “Handling Invalid Entries and Timeouts” for more information.

[55] Please note that the space is conspicuously absent from the list of allowed characters. Don’t use spaces in your context names—you won’t like the result!

[56] Asterisk permits simple arithmetic within the priority, such as n+200, and the priority s (for same), but their usage is somewhat deprecated due to the existence of priority labels. Please note that extension s and priority s are two distinct concepts.

[57] Except in some parts of voicemail.conf.

[58] There is another application called Background() that is very similar to Playback(), except that it does allow input from the caller. You can read more about this application in Chapter 15, The Automated Attendant and Chapter 17, Interactive Voice Response.

[59] Asterisk selects the best file based on translation cost—that is, it selects the file that is the least CPU-intensive to convert to its native audio format. When you start Asterisk, it calculates the translation costs between the different audio formats (they often vary from system to system). You can see these translation costs by typing show translation at the Asterisk command-line interface. The numbers shown represent how many milliseconds it takes Asterisk to transcode one second of audio. We’ll talk more about the different audio formats (known as codecs) in the section called “Codecs”.