<- ...Back>   Continue... ->

Understanding Extensions


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











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





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




; Support phones




exten => 1000,1,Dial(${SUPPORTPHONES})



exten => 2010,1,Dial(${SUPPORTPHONES})






exten => 1000,1,Dial(SIP/2205&SIP/2206&SIP/2207&SIP/2208&SIP/2209)



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










We'll use this later on when we setup some extensions.



Special Variables


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:





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.









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




exten => _0[1-8].,1,Dial(ZAP/g1/${EXTEN})


exten => i,1,Congestion



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)







Include, Not Exclude


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:




exten => 100,1,Dial(SIP/100)




exten => 100,1,Dial(SIP/500)



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.



<- ...Back>   Continue... ->