So you now have a working and hand-built PBX system (albeit a rudimentary one) but you want a more full-featured, commercial-grade PBX system that you can use to impress friends, colleagues, and loved ones. Welcome to Part 2 of our Asterisk set-up!
Okay, first we need to tackle Dialplan, the heart of an Asterisk server and where most of our configuration will take place. Dialplan is configured in /etc/asterisk/extensions.conf where the logic on how calls are routed takes place and unlike most configuration file you've tackled, it's slightly more complex.
The extensions.conf can be broken down into three major parts: Context, Extensions, and variables.
- Context - extensions.conf is divided into sections, and each sections is called context. Context is denoted by placing square brackets ([]) at the head of the section. All extensions placed after a context definition are part of that context, until the next context is defined.
- static controls how Asterisk rewrites the extensions.conf when an extension is added or deleted.
- writeprotect enables a user to rewrite your Dialplan from the command line
- Extensions are the individual entries in your context. These are run by Asterisk and it's corresponding application every time a call is initiated in that context.
- The extension number
- The priority which control the flow of the applications to run
- The application that perform some action.
There are two special context called [general] and [globals].
The [general] context is where global configuration entries resides and it defined how extensions.conf behaves. Here is an example:
[general]
static=no
writeprotect=no
The [globals] context defined global variables. Variables are basically container for information. There are three types of Asterisk variables. Global variables applies throughout your extensions.conf, for instance:
[globals]
PHONE1=DAHDI/1
PHONE2=DAHDI/2
OUTBOUNDTRUNK=dahdi/g1
PHONE1 and PHONE2 refers to your FXS module where your incoming calls are routed. The OUTBOUNDTRUNK variable refer to the FXO module use for making outbound calls (dahdi/g1 refers to group=1 in your chan_dahdi.conf file).
An extension is broken down into three components:
Extensions uses the following syntax exten => name,priority,application()
exten => 123,1,Answer()
Where '123' is the extension number, '1' is the priority number, and Answer() is the name of the application. In most extensions.conf, you will see 'n' value instead of a priority number. The 'n' value is a shortcut for 'next' and tells Asterisk to run the next step one line after the other. This is for convenience so you don't need to re-number the steps if you need to change the flow of your program.
Here is simple Dialplan:
[incoming]
exten => s,1,Answer()
exten => s,n,Playback(hello-world)
exten => s,n,Hangup()
You'll notice here that we have an 's' instead of an extension number. The 's' stands for 'start', this is where the call will be routed if no extension number is given. The Answer() application answer a ringing channel. After the call has been 'pick-up', it will be routed to Playback() which 'plays' a sound file (ie. hello-world) to the caller. Once the sound file has been played, Asterisk hangs up the connection via Hangup() program.
- X - Matches any single digit from 0 to 9
- Z - Matches any single digit from 1 to 9
- N - Matches any single digit from 2 to 9
- . - Matches any one or more characters, no matter what they are.
[outgoing]
exten => _9.,1,Dial(${OUTBOUNDTRUNK}/${EXTEN:1})
In this directive, you need to dial 9 before calling an outside number. The underscore (_) before it indicate that this directive will be pattern matching. The '.' character after 9 will match all the number you press after 9. The '1' indicate that this is the first priority. The Dial() will then route the call to your trunk line. The '${EXTEN:1}' will strip off the first digit (which in this case is 9) before dialling the number.
Last but not the least is the 'include' statement. Basically, it just enables you to include other contexts from within another context. It has the following form:
[default]
include => menu
include => outgoing
include => conference
Here, the [default] have access to the following context: menu, outgoing, conference.
Now that we've tackled extensions.conf, let's take a brief look at some of the common applications used on Dialplan
- Background() is similar to Playback() application but plays the sound file in the background, while waiting for the user to enter the extension number.
- Dial() application dials a channel using the following syntax
- Goto() jumps to specified priority, extensions, and context.
- Set() sets a variable value.
- WaitExten() application waits for the caller to enter the extension numbers and normally called after the Background().
Dial(technology/resource,timeout,option)
Where technology could be DAHDI, SIP, IAX2, etc. Timeout is the length of time in seconds the Dial() will wait until the call is answered. The common option use in Dial() is 'm' which plays music to the caller until the call is answered.
You should now be familiar with basics of extensions.conf, so
Feature 1: Voicemail System
Voicemail is probably one of most popular application of Asterisk, here's how we set it up.
- In your /etc/asterisk/voicemail.conf file, find the [zonemessages] context and add the following settings:
[zonemessages]Note: You can find the time zone information at /usr/share/zoneinfo/ directory.
philippines=Asia/Manila|'vm-received' Q 'digits/at' IMp - In the same file, find the [default] context and configure mailboxes for your user 'Gene':
1000 => 1234,Gene Ordanza,gene@localhost,,|attach=no|tz=philippines - In your extensions.conf, add the following:
- To retrieve your voicemail, add the following in your extensions.conf:
exten => 900,1,VoicemailMain()The extension 900 routes you to the Voicemail system which will then prompt you for mailbox number and password.
Here the '1000' is the Voicemail ID number and '1234' is the numeric password for this mailbox. The name of the mailbox is 'Gene Ordanza' and it's email address is gene@localhos', 'attach=no' mean do not attach the voicemail to his email and timezone is Philippines.
exten => 3,1,Dial(${PHONE2},10,m)
exten => 3,n,Voicemail(1000,u)
exten => 3,n,Hangup()
When a caller hit '3', it will dial the extension number of 'Gene'. When there is no response in 10 seconds, it will be routed to Voicemail ID 1000. The 'u' option plays the 'unavailable' greetings to the caller. You should try leaving a voicemail first before proceeding to the next step.
That's it! Don't forget to restart the Asterisk service every you need to modify your extensions.conf.
Feature 2: Automated Attendant
Auto Attendant are basically call menus. It allow a caller to be automatically transferred to an extension number without going through an operator.
Auto Attendant are commonly interchange with Interactive Voice Response (IVR) since they provide a superficially similar functionality. Think of Auto Attendant as a way to automate transfer of calls to various extension numbers whereas IVRs provide more complexity and customization (ie. phone banking where IVR will prompt you to enter your account number and provide you a way to access your account balance information).
- First, we need to record the audio file for our background menu. In your extensions.conf, add the following:
- Once we have our audio menu, we can now redirect to caller to our Background application using the audio file we created. Find the [incoming] context from our previous settings above. Change [incoming] to [main] context and add the following directives.
exten => 205,1,Answer()
exten => 205,n,Wait(2)
exten => 205,n,Record(mainmenu)
exten => 205,n,Wait(5)
exten => 205,n,Playback(mainmenu)
exten => 205,n,Hangup()
First, we dial 205 extension to get to the recording application. We wait for 2 seconds, then we start recording our main menu prompt. Once you're done, press '#' key, then wait for another 2 seconds, before Asterisk starts to playback our pre-recorded main menu prompt.
By default, it should saved the audio file in /var/lib/asterisk/sounds/ you can use any of your fav music player (ie. Audacious, Amarok, Rhythmbox, etc) to manually listen to it.
[menu]
exten => s,1,Answer()
exten => s,n,Background(mainmenu)
exten => s,n,WaitExten(5)
exten => s,n,Hangup()
When a caller connects to our PBX, he gets the background audio file we recorded. Asterisk waits 5 seconds for an extension to be dialled. If no extension was dialled, the call is disconnected.
Call park is a standard feature of Asterisk. It allows a person to put a call on hold at one telephone set and continue from any other telephone set.
For instance, a caller is looking for personA who is otherwise engaged. You can 'park' the call on line '701'. Once personA is available, you can tell him that someone is waiting on line '701'. Then personA finds an available phone and dial extension '701' to get to the caller.
- In your /etc/asterisk/features.conf file, find the [general] context and add the following:
[general] parkext => 700 parkpos => 701-720 context => parkedcalls parkingtime => 120The settings above means we can park calls by dialling 700, and the call will be placed in the first available extension choosen from 701 to 720. Asterisk will then announced the parking extension number. Assuming we have 20 open lines, we can parked 20 calls. The context from which can access parked calls is 'parkedcalls'. If the calls is not answered in 120 seconds, it will ring back extension number of the user who parked the call.
- In your extensions.conf, include the following line where the calls are being routed.
include => parkedcalls
Asterisk comes built-in with excellent conferencing system. I tried going to one of the local telco provider and ask for a ballpark figure for a PABX with concall feature. The sales guy insisted that we first set a meeting and discuss their SME 'solution'! One of those awkward "if you ask, then you can't afford" situations.
- In your /etc/asterisk/meetme.conf file, add the following:
- In your /etc/asterisk/extensions.conf file, add the following:
[rooms]
conf => 810
conf => 820,1234
conf => 830,1234
We have 3 conference room from the setup above. The conference room '810' is public conference room, meaning everybody can join in, they just need dial the '810' extension. Conference room '820' and '830' is private, the caller needs to type the password '1234' before joining the conference.
[default]
include => conference
[conference]
exten => 810,1,Answer()
exten => 810,n,MeetMeCount()
exten => 810,n,MeetMe(810,i)
exten => 820,1,Answer()
exten => 820,n,MeetMe(820,i,1234)
exten => 820,n,Hangup()
exten => 830,1,Answer()
exten => 830,1,MeetMe(830,i,1234)
exten => 830,n,Hangup()
When a caller dials 810, Asterisk will connect him to the public conference but before that the MeetMeCount() will announce the number of participants in the conference room. The i option in MeetMe will announce new participants and those leaving the conference room.
Note: Conferencing is CPU extensive, more participants means higher load on your processor due to transcoding.
Also, when setting up conferencing feature in Asterisk, you need a timing device. Fortunately, most cards (ie. analog card like TDM410 or digital cards) have built-in timing device. If you have a pure VOIP/Asterisk setup, install the ztdummy driver and load it on the kernel.
MOH feature of Asterisk allow you to play music for the caller while he is on hold. Like most setup above, MOH is straight-forward to configure.
- Download you MOH music here. Get the GSM-formatted MOH (ie. asterisk-moh-freeplay-gsm.tar)
- Uncompress the tar file, create MOH directory, and move the files to the new directory.
- In your /etc/asterisk/musiconhold.conf file, find the [default] context and add the following:
- That's it! You should now be able to use it on your system.
# tar xzvf asterisk-moh-freeplay-gsm.tar
# mkdir /var/lib/asterisk/sound/moh
# mv asterisk-moh-freeplay/* /var/lib/asterisk/sound/moh
[default]
mode=files
directory=/var/lib/asterisk/sound/moh
random=yes
If you wish to use your own MOH sound, make sure you that you encode it in a compatible format like ulaw. It is possible to use mp3, wav or other format, but it'll take some work.
Now, to pull it all together, here's the extensions.conf for our PBX system at home.
Currently revising the dialplan below, might be a syntax error below that I missed.
[general]
static=no
writeprotect=no
[globals]
PHONE1=DAHDI/1
PHONE2=DAHDI/2
OUTBOUNDTRUNK=dahdi/g1
[default]
include => menu
include => outgoing
include => conference
exten => s,1,Answer()
exten => s,n,Goto(menu,123,1)
[menu]
exten => 123,1,Answer()
exten => 123,n,Background(/var/lib/sounds/mainmenu)
;Paolo and CJ's extension number
exten => 1,1,Dial(${PHONE2},10,m)
exten => 1,n,VoiceMail(2000,u)
exten => 1,n,Goto(123,1)
;Gene's extension number
exten => 3,1,Set(VMNUM=1000)
exten => 3,n,Dial(${PHONE2},10,m)
exten => 3,n,Goto(s-${DIALSTATUS},1)
exten => s-NOANSWER,1,Voicemail(${VMNUM},u)
exten => s-BUSY,1,Voicemail(${VMNUM},b)
exten => 2-ANSWER,1,Hangup()
exten => _s-.,1,Goto(s-NOANSWER),1)
exten => 0,1,Dial(${PHONE2},20,m)
exten => 0,n,Playback(hello-world)
exten => 0,n,Goto(123,1)
;For invalid entries
exten => i,1,Playback(pbx-invalid)
exten => i,n,Goto(123,1)
;For timeout entries (caller did not enter any number for 5 seconds)
exten => t,1,Playback(pbx-invalid)
exten => t,n,Goto(123,1)
[conference]
exten => 810,1,Answer()
exten => 810,n,MeetMe(810)
exten => 810,n,MeetMeCount(810)
exten => 820,1,Answer()
exten => 820,n,MeetMe(820,i,1234)
exten => 830,1,Answer()
exten => 830,n,MeetMe(830,i,1234)
exten => 830,n,Hangup()
[outgoing]
exten => _9.,1,Dial(${OUTBOUNDTRUNK}/${EXTEN:1})
IMPORTANT: Make sure to reload your extensions.conf for the changes to take effect. To reload your Asterisk server from command line, run the following:
# asterisk -rx 'module reload'
That's it! Next we'll setup VOIP and scripting on Part III of our Asterisk Setup.
