Creating a Dialplan in Asterisk 1.6: Part 1

Exclusive offer: get 50% off this eBook here
Asterisk 1.6

Asterisk 1.6 — Save 50%

Build feature-rich telephony systems with Asterisk

$23.99    $12.00
by Barrie Dempster David Gomillion David Merel | September 2009 | Networking & Telephony

In this two-part article by Barrie Dempster, David Gomillion, and David Merel we will learn how to create your dialplan that determines how your calls are routed through the Asterisk server. We will also cover how to create extensions, distribute calls in an orderly manner using queues, and present callers with a greeting using automated attendants (IVR). In this part we will learn to create a context, extension, and outgoing extensions.

When calls come into the switch, we tell Asterisk step-by-step how to handle the call. Steps can be as simple as playing a sound file to running a customized script. We are limited mostly by our imaginations at this point.

We define all the steps we want Asterisk to perform in our extensions.conf file, in the customary location /etc/asterisk. Before we begin, we need to set priorityjumping=yes in the [general] section of extensions.conf. This will allow the tips and tricks in this article to work with Asterisk 1.6.x.

Creating a context

What is a context? Simply said, a context is a group of extensions. Each extension must exist within a context. There is more to contexts than grouping extensions though. In our extensions.conf file (or any included files), a context is denoted by square brackets "[ ]", as shown:

[mycontext]
. . .

So, if a context is a group of extensions, why do we need more than one? Let's think for a minute. Not all employees should be able to dial every phone. Would you trust your 16-year-old intern with the ability to dial international calls? I wouldn't. Also, do you want your president to be bothered by customers in the waiting room who use a courtesy phone and misdial? We could find that hazardous to our continued employment.

Certain extensions are hidden or made inaccessible from other extensions by context. This gives us some level of security. It also allows us to host multiple phone systems on a single server.

Imagine you have two businesses on the same phone system, each with only two handsets. It'd be a pain to have each dial four digits to reach the other handset. We can use contexts to treat each company as if it were on a separate server.

Something very important about contexts is we can include other contexts through the use of the include directive. This means all extensions in an included context are available. The value of this may not be immediately apparent, but soon we will see the full power of this tool.

Suppose we have some context named bob. If we wanted bob to include default, then we would have the following in our extensions.conf:

[bob]
include => default

This single line placed in any context gives that context the ability to dial any extension in the default context, as well as all contexts included in the default context. This means that if the default context included the foo context, then anybody in the bob context could dial extensions in the foo context.

Suppose we had the following in our extensions.conf file:

[foo]
exten => 1,1,Playback(tt-monkeys)
include => bar
[bar]
exten => 1,1,Playback(tt-weasels)

Now I know that we haven't yet discussed the definition of extensions. That's OK. All we need to know is that extension 1 in foo will play back a file that sounds like monkeys, and extension 1 in bar will play back a file that says, "weasels have taken over our phone system".

If we are in context foo and press 1, which file will play? This shows us the danger of include. We should be careful not to include multiple matches for the same extension. If we do include multiple contexts, the first included context with a match will win. Consider the following file:

[foobar1]
include => foo
include => bar
[foobar2]
include => bar
include => foo

If we are in context foobar1 and press 1, we will hear monkeys, while if we are in context foobar2 and press 1, we will hear weasels. While this can trip the unwary, we will use it to our advantage later on.

Creating an extension

We all have a good idea about what an extension is. On our legacy PBX, each handset was an extension. Pretty simple, right?

While conceptually simple, there is a little wrinkle. If all we want to do is provide a few handsets, then there's one extension per phone. But Asterisk can do much more! We need to think of an extension as a group of commands that tells Asterisk to do some things. As amorphous as that may be, it's true.

An extension can be tied to one handset, a queue, groups of handsets, or voicemail. An extension can be attributed to many different areas of the system. If you're familiar with programming terms, perhaps you could say that extensions are polymorphic.

To go further, extensions can be used to provide access to other applications, sound files, or other services of Asterisk. Extensions are important to the magic of Asterisk.

Now that we know why we create extensions, let's think about how we create them. Again, they are in the extensions.conf file, or any files that you include from there.

We may decide to break up files such as extensions.conf into multiple configuration files. A common example of this is when we create large groups of extensions and choose to give each its own file. This also applies to the other configuration files we use.

The general format for a line in the extensions.conf file is:

exten => extensionnum,priority,action

Let's take a closer look. Each line begins with the command exten. This is a directive inside Asterisk. You do not change this for each extension.

Next, we have the extension number. Each extension has a unique number. This number is how Asterisk knows which set of commands to run. This extension can be detected in three major ways. First, the phone company may send it in with the calls, as is the case with DID numbers. Users can enter an extension using their touch-tone keys. Finally, there are a few special extensions defined. Some of these are:

  • s: start extension. If no other extension number is entered, then this is the extension to execute.
  • t: timeout extension. If a user is required to give input, but does not do so quickly enough, this is the extension that will be executed.
  • i: invalid extension . If a user enters an extension that is not valid, this is the extension that will be executed.
  • fax: fax calls. If Asterisk detects a fax, the call will be rerouted to this extension.

Then we have the priority. Asterisk will start at priority 1 by default, complete the requested command, and then proceed to priority n+1. Some commands can force Asterisk to jump to priority n+101, allowing us to route based on decisions, such as if the phone is busy.

Finally, we have the action. This is where we tell Asterisk what we want to do. Some of the more common actions we may want to perform are:

  • Answer: This accepts the call. Many applications require that the call be answered before they can run as expected.
  • Playback(filename): This command plays a file in .wav or .gsm format. It is important to note that the call must be answered before playing.
  • Background(filename): This command is like Playback, except that it listens for input from the user. It too requires that the call be answered first.
  • Goto(context,extension,priority): Here, we send the call to the specified context, extension, and priority. While useful, this can be a bad style, as it can be very confusing to us if something goes wrong. However, it can be a good style if it keeps us from duplicating extension definitions, as moves, adds, or changes would only have to be updated in one place.
  • Queue(queuename|options): This command does what it seems like it should. It places the current call in the queue, which we should have already defined in the queues.conf file.
  • Voicemail(extension): This transfers the current call to the voicemail application. There are some special options as well. If we preceed the extension with the letter s, it skips the greeting. When we place the letter u before the extension, it uses the unavailable greeting, and b uses the busy greeting.
  • VoicemailMain: This application allows users to listen to their messages, and also record their greetings and name, and set other configuration options.
  • Dial(technology/id,options,timeout): This is where we tell Asterisk to make the phone ring, and when the line is answered, to bridge the call. Common options include:
    • t: Allow the called user to transfer the call by pressing the # key.
    • T: Allow the calling user to transfer the call by pressing the # key.
    • r: Indicate ringing to the calling party.
    • m: Provide music on hold to the calling party.
    • H: Allow the calling party to hang up by pressing the * key.
    • g: Go on in the context if the destination hangs up.

While this list is not exhaustive, it should be enough to get us started. Suppose we just want to make a DAHDI phone ring, which is on interface 1, and we are going to work completely in the default context. Our extensions.conf file would look like:

[default]
exten => s,1,Dial(dahdi/1)

Pretty simple, right? Now, imagine we want to transfer to the voicemail of user 100 if someone is on the phone. As Dial sends you to priority n+101 when the line is busy or not available, all we have to do is define what we want to do. Our dialplan would look like:

[default]
exten => s,1,Dial(dahdi/1)
exten => s,102,Voicemail(b100)

Great! We have some of the functionality that users have come to expect. But are you happy yet? The problem is that a phone could ring for years before someone picks it up.

So, for our next exercise, suppose we want to transfer the call to voicemail when the phone is not answered in 30 seconds. So, obviously, we're going to have to use the option in Dial to define a time-out. Our dialplan would have something like:

[default]
exten => s,1,Dial(dahdi/1|30)
exten => s,2,Voicemail(u100)
exten => s,102,Voicemail(b100)

All we're doing is telling Asterisk how to handle the call, in a step-by-step way. It is important to think about all scenarios that a call can go through, and plan for them. Just to reiterate a point I made earlier, planning ahead will save us hours of debugging later.

Suppose we want to send anyone who is in a place where they shouldn't be to user 0's voicemail, which will be checked periodically by the receptionist.

[default]
exten => s,1,Dial(dahdi/1|30)
exten => s,2,Voicemail(u100)
exten => s,102,Voicemail(b100)
exten => i,1,Voicemail(s0)
exten => t,1,Voicemail(s0)

All right, we're getting somewhere now! At least we know each call will be handled in some way. What about faxes? Suppose we have only one fax machine (or a centralized fax server) on DAHDI interface 2, then our dialplan should look similar to:

[default]
exten => s,1,Dial(dahdi/1|30)
exten => s,2,Voicemail(u100)
exten => s,102,Voicemail(b100)
exten => i,1,Voicemail(s0)
exten => t,1,Voicemail(s0)
exten => fax,1,Dial(dahdi/2)

Congratulations! We now have a working phone system. May be not the most interesting yet, but we're making great progress. Don't worry, our phone system will grow in features.

Now, to create a list of useful extensions, we need to define a set of commands for each handset we have. Suppose we have three SIP phone users—1001-1003, with extensions 1001-1003. Our default context would look like:

[default]
exten => 1001,1,Dial(SIP/1001|30)
exten => 1001,2,Voicemail(u1001)
exten => 1001,102,Voicemail(b1001)
exten => 1002,1,Dial(SIP/1002|30)
exten => 1002,2,Voicemail(u1002)
exten => 1002,102,Voicemail(b1002)
exten => 1003,1,Dial(SIP/1003|30)
exten => 1003,2,Voicemail(u1003)
exten => 1003,102,Voicemail(b1003)
exten => i,1,Voicemail(s0)
exten => t,1,Voicemail(s0)
exten => fax,1,Dial(dahdi/2)

For every extension we add, the length of extensions.conf will grow by four lines (three lines of code, and one line of whitespace). This is not very easy to read, and it is very easy to make mistakes. There has to be a better way, right? Of course there is!

We can use macros to define common actions. We will create a special macro context. The name of these contexts always starts with macro-. Suppose we want to call this one macro-normal. We would have:

[macro-normal]
exten => s,1,Dial(${ARG2}|30)
exten => s,2,Voicemail(u${ARG1})
exten => s,102,Voicemail(b${ARG1})

Now, to create the same three extensions, we would have:

exten => 1001,1,Macro(normal|1001|SIP/1001)
exten => 1002,1,Macro(normal|1002|SIP/1002)
exten => 1003,1,Macro(normal|1003|SIP/1003)

So now, each extension we add requires only one extra line in extensions.conf. This is much more efficient and less prone to errors. But what if we knew that any four-digit extension beginning with a 1 would be a normal, SIP extension?

Here it is time for us to discuss Asterisk's powerful pattern-matching capabilities. We can define extensions with certain special wildcards in them, and Asterisk will match any extension that fits the description.

Using the underscore (_) character warns Asterisk that the extension number will include pattern matching. When matching patterns, the X character represents any number (0 to 9), the Z character will match the numbers 1 to 9, the N character represents numbers 2 to 9, and the period (.) represents a string of any number of digits.

Also, we can use certain variables in our dialplan. One such variable is ${EXTEN}, which represents the extension that was used.

So, for this example, we could use the following definition:

exten => _1XXX,1,Macro(normal|${EXTEN}|SIP/${EXTEN})

This one line of code has now defined 1000 extensions, from 1000 to 1999. All we have to do is ensure that our voicemail user, extension, and SIP user are all the same number. Pretty cool, huh?

Note that if we wish to modify the behavior of all extensions, all we have to do is modify the macro. This should help us quite a bit as we tweak Asterisk to fit our business needs.

Asterisk 1.6 Build feature-rich telephony systems with Asterisk
Published: September 2009
eBook Price: $23.99
Book Price: $39.99
See more
Select your format and quantity:

Creating outgoing extensions

With this dialplan, we have only catered for incoming calls. Of course we will want to create extensions to dial out.

How these outgoing extensions look depends on the plan we made earlier. It also depends on how you want the switch to act for your users. We always want to make it as similar to any old system as possible to reduce the need to retrain users.

Most phone systems require a user to dial a certain digit to designate the call as one that has a destination outside the switch. In our legacy PBX, we accessed outgoing lines by dialing a 9. To copy this behavior, we could do something like:

[outgoing]
exten => _9.,1,Dial(dahdi/g1/${EXTEN:1})

Notice that we are using pattern matching as we did before. Also notice that we used g1 as the DAHDI interface. This is a good use for a group. This simply means "any free interface in group 1". Thus, if we put all of our outgoing lines in group 1, when we dial an outside number, we do not have to guess which channel is free.

Remember that the variable EXTEN represents the extension that we are in. If a user dials 95555555, then EXTEN is equal to 95555555. By using ${EXTEN:1}, we instruct Asterisk to strip the first (leftmost) digit. Thus, ${EXTEN:1} equals 5555555. If we wanted to strip the two leftmost digits, it would be ${EXTEN:2}.

Many discount long distance carriers will charge the same for local calls as long distance. In a case like that, we would want to make sure that local and toll-free calls went out on lines connected to the local telephone company, while calls destined for long distance locations should go out through our discount carrier. For this example, we will assume that the discount carrier is DAHDI group 1, and the local telephone company is DAHDI group 2.

[outgoing]
exten => _9N.,1,Dial(Zap/g2/${EXTEN:1})
exten => _91.,1,Dial(Zap/g1/${EXTEN:1})

Therefore, if the number dialed is preceded with a 9 and a 1, then the call will go out through our DAHDI group 1 lines, and if it does not have a 1, it will go out through our group 2 lines.

What if we had used the following?

[outgoing]
exten => _9X.,1,Dial(Zap/g2/${EXTEN:1})
exten => _91.,1,Dial(Zap/g1/${EXTEN:1})

Notice that this is a problem. When we dial 9, followed by 1, we have two statements that match. When you start Asterisk, you will notice that the system parses the extensions.conf (and included files) and immediately reorders all of the extensions before building a database file. Therefore, it is ambiguous as to which statement it will execute.

While this method is technically functional, it is not the best way to do it. A better way would be:

[outgoing]
exten => _9NXXXXXX,1,Dial(Zap/g2/${EXTEN:1})
exten => _91NXXNXXXXXX,1,Dial(Zap/g1/${EXTEN:1})

This does not allow for medium distance dialing. It also does not handle the case of all lines being busy in one of the groups. Let's see how we could take care of that:

[outgoing]
exten => _9NXXXXXX,1,Dial(Zap/g2/${EXTEN:1})
exten => _9NXXXXXX,2,Dial(Zap/g1/${EXTEN:1})
exten => _91NXXNXXXXXX,1,Dial(Zap/g1/${EXTEN:1})
exten => _91NXXNXXXXXX,2,Dial(Zap/g2/${EXTEN:1})
exten => _91NXXXXXX,1,Dial(Zap/g1/${EXTEN:1})
exten => _91NXXXXXX,2,Dial(Zap/g2/${EXTEN:1})

This is getting much better, but what when all of our lines are busy for both groups? We should probably notify the user that their call didn't go through because all lines are in use. We could do something like this:

[outgoing]
exten => _9NXXXXXX,1,Dial(Zap/g2/${EXTEN:1})
exten => _9NXXXXXX,2,Dial(Zap/g1/${EXTEN:1})
exten => _9NXXXXXX,3,Congestion
exten => _91NXXNXXXXXX,1,Dial(Zap/g1/${EXTEN:1})
exten => _91NXXNXXXXXX,2,Dial(Zap/g2/${EXTEN:1})
exten => _91NXXNXXXXXX,3,Congestion
exten => _91NXXXXXX,1,Dial(Zap/g1/${EXTEN:1})
exten => _91NXXXXXX,2,Dial(Zap/g2/${EXTEN:1})
exten => _91NXXXXXX,3,Congestion

Imagine a phone switch, in which all extensions were exactly four digits long. How would this knowledge affect our outgoing lines? Perhaps the fundamental question is whether we really need to dial the 9 at all. While people generally expect to dial a 9 at work, they do not seem to care to do so from home. May be we should do this:

[outgoing]
exten => _NXXXXXX,1,Dial(Zap/g2/${EXTEN:1})
exten => _NXXXXXX,2,Dial(Zap/g1/${EXTEN:1})
exten => _NXXXXXX,3,Congestion
exten => _1NXXNXXXXXX,1,Dial(Zap/g1/${EXTEN:1})
exten => _1NXXNXXXXXX,2,Dial(Zap/g2/${EXTEN:1})
exten => _1NXXNXXXXXX,3,Congestion
exten => _1NXXXXXX,1,Dial(Zap/g1/${EXTEN:1})
exten => _1NXXXXXX,2,Dial(Zap/g2/${EXTEN:1})
exten => _1NXXXXXX,3,Congestion

There is a drawback to this configuration. If you are using DAHDI interfaces, and people are touch-tone dialing, Asterisk will have to wait for a timeout period to complete dialing some four-digit extensions. The reason for this is simple. Any extension number that partially matches the beginning of the patterns above will have to be held to see if more digits are coming. However, SIP and IAX phones do not seem to suffer the same issue.

Because of this issue, from here we will assume that all outgoing calls are preceded with the digit 9.

We have already discussed that contexts can provide security for outgoing phone calls, but this example fails to describe such security. Suppose you have two groups of employees, those who may make toll calls, and those who may not. All employees have an individual handset. The most logical choice is to make two contexts:

[longdistance]
exten => _9NXXXXXX,1,Dial(Zap/g2/${EXTEN:1})
exten => _9NXXXXXX,2,Dial(Zap/g1/${EXTEN:1})
exten => _9NXXXXXX,3,Congestion
exten => _91NXXNXXXXXX,1,Dial(Zap/g1/${EXTEN:1})
exten => _91NXXNXXXXXX,2,Dial(Zap/g2/${EXTEN:1})
exten => _91NXXNXXXXXX,3,Congestion
exten => _91NXXXXXX,1,Dial(Zap/g1/${EXTEN:1})
exten => _91NXXXXXX,2,Dial(Zap/g2/${EXTEN:1})
exten => _91NXXXXXX,3,Congestion
[local]
exten => _9NXXXXXX,1,Dial(Zap/g2/${EXTEN:1})
exten => _9NXXXXXX,2,Dial(Zap/g1/${EXTEN:1})
exten => _9NXXXXXX,3,Congestion

We simply place each handset into one of the two contexts, based upon what numbers we want them to be able to dial. While this would work, we duplicated three lines between the contexts. Remember when we discussed contexts, and I mentioned that we can use the include directive? Here's a good place to do so. So now, we have:

[longdistance]
exten => _91NXXNXXXXXX,1,Dial(Zap/g1/${EXTEN:1})
exten => _91NXXNXXXXXX,2,Dial(Zap/g2/${EXTEN:1})
exten => _91NXXNXXXXXX,3,Congestion
exten => _91NXXXXXX,1,Dial(Zap/g1/${EXTEN:1})
exten => _91NXXXXXX,2,Dial(Zap/g2/${EXTEN:1})
exten => _91NXXXXXX,3,Congestion
include => local
[local]
exten => _9NXXXXXX,1,Dial(Zap/g2/${EXTEN:1})
exten => _9NXXXXXX,2,Dial(Zap/g1/${EXTEN:1})
exten => _9NXXXXXX,3,Congestion

Let's take a quick look at what we have. We can now place handsets in the local or longdistance context. This gives us a good bit of security, but there is one small problem. Do you see it? If we put our users into either context, they cannot dial internal extensions. Assuming we allowed calling our local extensions in the default context, we should update the local context like so:

[local]
exten => _9NXXXXXX,1,Dial(Zap/g2/${EXTEN:1})
exten => _9NXXXXXX,2,Dial(Zap/g1/${EXTEN:1})
exten => _9NXXXXXX,3,Congestion
include => default

By so doing, we give access to the extensions for the local context. We also give access to the default context for those in the longdistance context because longdistance includes local, which in turn includes default.

Thus, we must be very careful about what we include. When we include any context, we are in turn including all contexts it includes. It is easy to include our way out of the security we set up.

Summary

In this part of the article we saw how to create a context, extension, and outgoing extensions. In the next part, we will learn about Advanced Call Distribution, Automated attendants, and System services.

 

If you have read this article you may be interested to view :

Asterisk 1.6 Build feature-rich telephony systems with Asterisk
Published: September 2009
eBook Price: $23.99
Book Price: $39.99
See more
Select your format and quantity:

About the Author :


Barrie Dempster

Barrie Dempster is currently employed as a Senior Security Consultant for NGS Software Ltd a world-renowned security consultancy well known for their focus in enterprise-level application vulnerability research and database security. He has a background in Infrastructure and Information Security in a number of specialised environments such as financial services institutions, telecommunications companies, call centres, and other organisations across multiple continents. Barrie has experience in the integration of network infrastructure and telecommunications systems requiring high calibre secure design, testing and management. He has been involved in a variety of projects from the design and implementation of Internet banking systems to large-scale conferencing and telephony infrastructure, as well as penetration testing and other security assessments of business critical infrastructure.

David Gomillion

David Gomillion currently serves as Director of Information Technology for the Eye Center of North Florida. There, he orchestrates all of the technological undertakings of this four-location medical practice, including computers, software (off-the-shelf and custom development), server systems, telephony, networking, as well as specialized diagnostic and treatment systems. David received a Bachelor's of Science in Computer Science from Brigham Young University in August, 2005. There he learned the theory behind his computer experience, and became a much more efficient programmer. David has worked actively in the Information Technology sector since his freshman year at BYU. He has been a Networking Assistant, an Assistant Network Administrator, a Supervisor of a large Network and Server Operations unit, a Network Administrator, and finally a Director of Information Technology. Through his increasing responsibilities, he has learned to prioritize needs and wants, and applies this ability to his Asterisk installations.

David Merel

David Merel is the founder and CEO of Thinkbright LLC a local/long distance telephone company as well as a cutting-edge Voice Over IP carrier, providing businesses of all sizes with sophisticated and low cost VOIP solutions.

David started Thinkbright in 2005 and continues to manage the company and its employees, all of whom are dedicated IT professionals. He acts as the company’s chief architect, designing new technologies that have added significant revenues to the company’s operations. During his many years at Thinkbright, David has worked with the latest Voice Over IP technology, including all VOIP equipment from major manufacturers such as Cisco, Polycom, Grandstream, and Aastra. He also works with customers ranging from small businesses to Fortune 500 companies, and interacts with system integrators and IT consultants who call Thinkbright on a daily basis for assistance with all of the VOIP solutions that Thinkbright offers. Thinkbright manages its own PBX system, providing customers with PBX features such as Auto Attendants, Waiting Rooms, and Ring Groups, or assists customers in managing their own PBX network while providing these customers with the service for incoming and outgoing calls.

David has many years of experience with Trixbox and Asterisk, and has installed countless custom configurations and deployments using those solutions.

David earned a Bachelor of Arts triple majoring in philosophy, politics and law from SUNY Binghamton. David holds a CCNA (a Cisco Certified Network Associate) certificate and is proficient in over 10 languages and databases, various operating systems, VOIP and related protocol, and other business applications.

Books From Packt

FreePBX 2.5 Powerful Telephony Solutions
FreePBX 2.5 Powerful Telephony Solutions

Cacti 0.8 Network Monitoring
Cacti 0.8 Network Monitoring

Building Enterprise Ready Telephony Systems with sipXecs 4.0
Building Enterprise Ready Telephony Systems with sipXecs 4.0

Building Telephony Systems with OpenSER
Building Telephony Systems with OpenSER

trixbox CE 2.6
trixbox CE 2.6

Asterisk 1.4 – the Professional’s Guide
Asterisk 1.4 – the Professional’s Guide

Zabbix 1.6 Network Monitoring [RAW]
Zabbix 1.6 Network Monitoring [RAW]

ModSecurity 2.5
ModSecurity 2.5

 

 

Your rating: None Average: 5 (1 vote)

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
R
6
t
6
d
E
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software