Understanding the
extensions.conf file is a crucial part of getting to grips with Asterisk and in
this section I'll try to get you up to speed and understanding the concepts.
First of all the sample extensions.conf file that comes with an Asterisk
install is full of stuff you probably don't understand, so we'll get rid of it
and start with a clean one. Actually when I say 'get rid of', I really mean
we'll just rename it, that way you can go back and look at it later. Connect to
the machine that has Asterisk installed on it, login as the user root and type
the following commands:
|
cd
/etc/asterisk mv extensions.conf
old_extensions.conf |
|
Now we'll edit the
new version of the file
|
vi extensions.conf |
|
So hit your insert
key and you should see the word insert appear in the bottom left of your
screen. The first thing we'll do is add some whitespace at the top of the file,
this will stop us accidentally overwriting anything at the top of the file
accidentally when we start up vi. Hit your return key a couple or three times.
Sometimes it's
useful to add comments in the configuration files, you can do that in
extensions.conf using the semi-colon (;) character, anything that appears on a
line after a semi-colon is a comment. Comments can also appear at the end of
lines
|
; I am a
comment static=yes ; I'm a comment too |
|
Naturally your
comments should make sense and be relevant.
The first section
of the extensions.conf file we will add is the general section, type in these
lines
|
[general] static=yes writeprotect=yes |
|
These lines simply
stop anyone from being able to save the extensions.conf file from the Asterisk
command line. If you are running Asterisk and have the Asterisk command prompt
on your screen you can add and remove extensions dynamically, you can also
write your changes using the save dialplan command. Seriously, disable it with
the lines above in your extensions.conf file, it's not worth wiping out your
extensions because you made a mistake and did a save dialplan – save dialplan
also removes all of your carefully crafted comments from the file, bad news.
The next section
we'll add is a globals section. This section allows us do define variables that
will apply throughout the extensions.conf file. These global variables can be useful for defining things you will
refer to later in the file using the ${VARIABLENAME} notation. Using global
variables means that if you want to change something, you only need to change the definition in the globals section for
it to affect all the references. For example in my extensions.conf I have the
following
|
; Support
phones SUPPORTPHONES=SIP/2205&SIP/2206&SIP/2207&SIP/2208&SIP/2209 |
|
Within my dialplan
I can simply refer to ${SUPPORTPHONES} for an action, such as a dial, to be
applied to multiple devices. Imagine if I'd not used a variable to list the
phones and then added a new one. With the variable defined I'd just change it
in the globals section and be done, without the variable I'd have to find every
location in the file I wanted to perform the task with those devices and change
them individually. Not clear?
Ok, I'm talking
this
|
[globals] ; Support
phones SUPPORTPHONES=SIP/2205&SIP/2206&SIP/2207&SIP/2208&SIP/2209 [somecontext] exten =>
1000,1,Dial(${SUPPORTPHONES}) [anothercontext] exten =>
2010,1,Dial(${SUPPORTPHONES}) |
Versus:
|
[somecontext] exten =>
1000,1,Dial(SIP/2205&SIP/2206&SIP/2207&SIP/2208&SIP/2209) [anothercontext] exten =>
2010,1,Dial(SIP/2205&SIP/2206&SIP/2207&SIP/2208&SIP/2209) |
In the top example
I only need to modify the SUPPORTPHONES= line if I add another phone, say
SIP/2210 to the list of support numbers, but in the second example I need to
change the dial command in two places. The more times you need to change it,
the more likely you are to make a mistake or even, in a large extensions.conf
file, miss one out accidentally.
Add the following
lines to your extensions.conf
|
[globals] XLITE=SIP/1000 |
|
We'll use this
later on when we setup some extensions.
Asterisk has some
special variables that are automatically defined when a new channel (call)
starts up. Later you will see an example of using the ${EXTEN} variable. These
definitions come from the README.variables file.
${ACCOUNTCODE} Account code (if specified)
${CALLERID} Caller ID
${CALLERIDNAME} Caller ID Name only
${CALLERIDNUM} Caller ID Number only
${CALLINGPRES} PRI Caller ID presentation for incoming
calls
${CHANNEL} Current channel name
${CONTEXT} Current context
${DATETIME} Current date time in the format:
YYYY-MM-DD_HH:MM:SS
${DNID} Dialed Number Identifier
${ENUM} Result of application EnumLookup
${EPOCH} Current unix style epoch
${EXTEN} Current extension
${ENV(VAR)} Environmental variable VAR
${HANGUPCAUSE} Asterisk hangup cause
${INVALID_EXTEN} The invalid called extension (used in the
"i" extension)
${LANGUAGE} Current language
${LEN(VAR)} String length of VAR (integer)
${MEETMESECS} Number of seconds a user participated in a
MeetMe
${PRIORITY} Current priority
${RDNIS} Redirected Dial Number ID
Service
${TIMESTAMP} Current date time in the format:
YYYYMMDD-HHMMSS
${TXTCIDNAME} Result of application TXTCIDName
${UNIQUEID} Current call unique identifier
${SIPCALLID} SIP Call-ID: header verbatim (for
logging or CDR matching)
${SIPDOMAIN} SIP destination domain of an inbound
call (if appropriate)
${SIPUSERAGENT} SIP user agent
The dial()
application sets the following variables:
${DIALEDPEERNAME} Dialed peer name
${DIALEDPEERNUMBER} Dialed peer number
${DIALEDTIME} Total time for the call in
seconds (Network time).
${ANSWEREDTIME} Time from answer to end of call in
seconds.
${DIALSTATUS} Status of the call, one of:
CHANUNAVAIL | CONGESTION |
BUSY | NOANSWER | ANSWER | CANCEL
|
|
NOTE:
Attempting to set any of these special variables will not change their
value, but will not display any warning either. |
When you talk to
someone you talk in context. Both of you know the topic of conversation and
thus you have a meaningful, conversation. Asterisk uses context too when
talking to devices like phones or when remote services call in to your server.
Remember when you
set up the softphone, you added the line context=mytest? Well, your phone wants
to talk (dial) in that context to Asterisk so we need to create one. If you'd
jumped the gun a little when we setup the phone and tried to dial a number you
should have got a series of tones, what we call fast-busy, indicating that the
number you tried to dial doesn't exist in the context that the phone talks to.
To explain how
contexts work, take a look at the picture below. You'll see the image of two
network switches with a couple of IP Phones connected.
|
switch-1 |
switch-2 |
|
This is basic
networking stuff, so you should have no problem understanding the concept. The
two switches [contexts] above are not connected to each other at all, this
means that any traffic flowing on switch-1 [context-1] will never get to
switch-2 [context-2] and the phones connected to either switch [context] can
only talk to phones on the same switch
[in the same context]. They are in effect, isolated from each other.
You may think that
this isn't very useful, but in fact it's an extremely powerful feature.
Consider this simple example:
The Problem
You have children
and each has a phone in their bedroom. You want them to be able to call their
friends but not dial 0900 (Premium rate) numbers. However, you need to be able
to call your banking service from your study, which uses an 0900 number.
The Solution
You register each
child's phone and place them in the children context and the phone in
your study in the study context. In the children context you
allow them to dial all numbers except 0900 numbers, and in the study
context you allow the dialing of all numbers. This may look something like this
in your extensions.conf
|
[children] exten =>
_0[1-8].,1,Dial(ZAP/g1/${EXTEN}) exten =>
i,1,Congestion [study] exten =>
_0.,1,Dial(ZAP/g1/${EXTEN}) |
This is a very
basic example of limiting numbers, the children context exten line
basically says:
When
a number dialed starts with a 0 (zero) and the next digit is one to eight
(inclusive) then dial out using the ZAPtel interface (phone line). If a number
starts 09 then the number is regarded as invalid and will jump to the i extension,
which plays congestion tones. When you call from the study, all numbers are
allowed.
Ok, it's a simple
and very basic example, and it probably wouldn't take the children long to work
out your phone does work, but you get the idea.
|
|
There are a
number of special extensions available in Asterisk i = invalid, jump here when an invalid number is dialed. t = timeout, jump here when we timeout. h = hangup, jump here when a call in hung up. s = standard, jump here if the dialed extension is unknown
(used for generic processing). o = operator, a special extension to escape voice mail
(configurable) |
|
|
|
Now that you've
grasped that example, I'll tell you it's really the wrong way to go about
limiting the numbers you can dial. Yes, yes, I know I told you that's how you
can do it, that's the point you can do it like that, but it's not the
best way.
“Tell us why then”
- Ok, I will. The solution above may be fine for a small installation, perhaps
at home, but think about it in a larger install, keeping track of all the
extensions and contexts could end up being a nightmare. If you've ever used a
firewall (If you haven't you should go and stand in the corner now!) you should
be aware of the implied 'deny all' rule that many of them use. This rule simply
states:
If there is no rule explicitly allowing this traffic then I
should deny it.
So what's the
relevance to Asterisk? Well, we need to use the same mindset, if we don't
explicitly allow a phone to make a call to a number then we should deny it.
This of course is the default in Asterisk contexts, but we need to apply it to
our whole thinking in extensions.conf.
So How do we go
about this? Well, using the same example as we did before, we create our
general dialing rules and then use a function called include within our dialplan. Time for an example I
think...
|
[0900-allow] ;
Allow 0900 numbers to be dialed exten =>
_0900X.,1,Dial(ZAP/g1/${EXTEN}) [general-dialing]
; Allow all non 09 numbers to be dialed exten =>
_0[1-8].,1,Dial(ZAP/g1/${EXTEN}) [children] ;
Children only get general dialing rule include =>
general-dialing exten =>
i,1,Congestion [study] ;
study gets both rules include =>
0900-allow include =>
general-dialing |
What we have done
here is separate the two rules, since the children context only includes the
general-dialing context they would not be able to dial 0900 numbers (actually
they wouldn't be able to dial any number starting with 09. In my locale premium
rate numbers start 09, they are split into sub categories eg 0909 tend to be
sex lines. No I haven't called them! Unfortunately Dutch television goes down
the toilet after about 11:30pm, you can be quite happily watching an episode of
Friends and suddenly find yourself in the middle of a 10 minute (I kid you not)
series of adverts with naked women gyrating and begging you to satisfy their
needs by giving them a call – but I digress).
|
|
You can also
use the include feature to select the order in which extensions are searched
for example: [context-1] exten =>
100,1,Dial(SIP/100) [context-2] exten =>
100,1,Dial(SIP/500) [mycontext] include =>
context-2 include =>
context-1 If my phone
is in mycontext and I dial 100, SIP/500 is the phone that will actually
ring, since the include for its context comes before the include for
context-1 This is a
useful feature you can use to override extensions at different times of the
day/week/month etc. |
The study
context includes both the 0900-allow and the general-dialing,
allowing the phone in the study to dial both 0900 and other non 09 numbers.