A variable is a placeholder for an actual value. Exactly what that value is depends on the kind of variable. In Asterisk, variables can contain numbers, letters and strings (sequences of letters and numbers). Variables are useful because they let us create rules for call flow that apply in changing circumstances and make it easier to accommodate future changes in the telephone application or system.
|
|
|
If you've never worked with variables before, we recommend you read an introduction to the subject at http://en.wikipedia.org/wiki/Variables#In_computer_programming . |
In Asterisk, variables have varying scope. There are local
variables (called channel variables in Asterisk),
which can only set values for the current, active channel, and global
variables, which set values for all channels. We should already be
familiar with some of the variables Asterisk sets from our exposure to
them as configuration parameters in the Asterisk configuration files (such
as sip.conf, for example). We also have the freedom to define
our own variables and use them in configuration files.
The value of a variable can be obtained using the syntax
${VARIABLENAME}. There are variables that are automatically
set by Asterisk. For example, the called number is always stored in the
Asterisk system variable ${EXTEN}. Using patterns and
variables, it is often possible to dramatically compress a long
dialplan.
Before:
exten => 100,1,Dial(SIP/100) exten => 101,1,Dial(SIP/101) exten => 102,1,Dial(SIP/102) exten => 103,1,Dial(SIP/103) exten => 104,1,Dial(SIP/104) exten => 105,1,Dial(SIP/105) exten => 106,1,Dial(SIP/106) exten => 107,1,Dial(SIP/107) exten => 108,1,Dial(SIP/108) exten => 109,1,Dial(SIP/109)
After:
exten => _10X,1,Dial(SIP/${EXTEN})
Variable names needn't be in all uppercase as in our examples, nor
are user-defined variables case-sensitive. It is a good idea to use
uppercase variable names nonetheless because it makes the variables
easier to identify and the dialplan code easier to read. The primary
disadvantage of this is that it means you cannot distinguish variable
names based on case. For example, ${FOO} is considered the
same as ${foo}.
|
|
|
Asterisk system variables such as ${EXTEN} must always be uppercase. |
String variables (meaning variables that contain text and not numbers) should be defined using double quotes, though Asterisk will still accept them without double quotes - the following two entries are functionally identical:
exten => 1234,1,Set(FRUIT=Apple) exten => 1234,2,Set(FRUIT="Apple")
If the string contains commas or spaces, you must use double quotes:
exten => 1234,1,Set(FRUITTYPES="Apple, Pear, etc.")
This is why it is a good idea to get into the habit of using them for any string variables you define.
Sometimes a variable will contain reserved characters
(characters that have special functions and are interpreted
differently). For example, if you want to variable to contain the
underscore character ("_") you must use an "escape"
character to tell the dialplan interpreter that it should ignore the
reserved character. The following characters must be escaped when used
in a variable:
[ ] $ " \
The escape character in extensions.conf is
"\" (backslash):
Example:
exten => 1234,1,Set(AMOUNT="\$10.00")
Similarly, if you want to use the backslash character in a variable, you must escape it:
exten => 1234,1,Set(ROOMNUMBER="48\\10")
If a variable contains an integer, it can have no more than 18 digits. Anything larger will cause an error which will be recorded in the log file.
|
|
|
If you need to work with larger integers or floating point numbers, you can use an AGI script (see ???). |
Global variables are defined at the beginning of
extensions.conf. You must place them in the special
[globals] context, which follows
[general].
Example:
[general]
[globals]
RINGTIME=90
[from-intern]
exten => _XXX,1,Dial(SIP/${EXTEN},${RINGTIME})
exten => _XXX,n,VoiceMail(${EXTEN})
is used to define a variable
inside an extension.[11]Set()
Set(<variable1>=<value1>[,<variable2>=<value2>][,<option>])
Setting option makes the
variable global; without it, the variable is treated as a local
channel variable.g
Example:
; Set a global variable:
exten => 10,1,Set(RINGTIME=90,g)
; Set a local channel variable:
exten => 10,2,Set(FAVORITEFRUIT="Apple")
; Set two channel variables at once:
exten => 10,3,Set(VAR1=10,VAR2=23)
; Print variables to the CLI
exten => 10,4,NoOp(RINGTIME = ${RINGTIME})
exten => 10,5,NoOp(FAVORITEFRUIT = ${FAVORITEFRUIT})
exten => 10,6,NoOp(VAR1 = ${VAR1})
exten => 10,7,NoOp(VAR2 = ${VAR2})
If new channels are spawned while a conversation is in progress, they will have their own channel variables.
Sometimes you want to have a channel variable persist into the spawned channel. You can do this by prefixing the variable with an "_" (underscore) character. When the variable is inherited by the spawned channel, Asterisk automatically removes the prefix. This ensures that the variable is inherited only once.
Example:
exten => 1234,1,Set(_CAKE="Marble cake")
If you need unlimited inheritance of a channel variable, you can do this by prefixing the variable with two "_" (underscore) characters. Variables prefixed in this way will always be inherited by spawned channels.
|
|
|
Asterisk makes no distinction between variable names that are
preceded with an underscore and those that are not. In the example
below, a variable with multi-level inheritance
(" exten => 1234,1,Set(__CAKE="Marble cake") exten => 1234,n,Set(CAKE="Marble cake") |
Example:
exten => 1234,1,Set(__CAKE="Sponge cake")
When calling an inherited variable, it doesn't matter if it is called with a prefix or not. These entries will give the same output in the CLI:
exten => 1234,1,NoOp(${__CAKE})
exten => 1234,n,NoOp(${CAKE})
The following list describes the more important system channel
variables. These variables may be read but not overwritten by entries in
extensions.conf, as they are pre-defined by
Asterisk.
|
|
|
A complete list of all the pre-defined variables may be found
in |
|
|
|
It is a good practice to replace dialplan code that depends on deprecated variables or functions with code that uses the recommended replacements. This will reduce the chance of an installation breaking when you upgrade Asterisk. |
System variables relevant to specific Asterisk functions are covered again in their respective chapters.[12]
|
|
|
Some of the "variables" described here are not really variables but in fact built-in functions. In practice, they often play a similar role, so they are listed here for convenience. |
${ANSWEREDTIME}
The total elapsed time for the active connection (in other words, the number of seconds since the conversation started).
${BLINDTRANSFER}
The name of the channel on the other side of a blind transfer.
${CHANNEL}
Name of the current channel.
${CONTEXT}
Name of the current context.
${EPOCH}
Current Unix time (total number of seconds elapsed since the beginning of the Unix "epoch", which began at midnight UTC, January 1st, 1970)
${EXTEN}
Currently dialed extension.
${ENV(VARIABLENAME)}
Environment variable VARIABLENAME
${HANGUPCAUSE}
Cause of connection hang-up.
${INVALID_EXTEN}
Used in the i extension and contains the
dialed extension.
${PRIORITY}
Current priority in the current extension.
${TRANSFER_CONTEXT}
Context of a transferred call.
${UNIQUEID}
The unique ID for the current connection.
${SYSTEMNAME}
The system name as defined by systemname in
/etc/asterisk/asterisk.conf.
Variables are most useful when we can change their contents at execution time. This gives us the flexibility to impart complex and powerful behavior to our Asterisk system.
In general, a string consistes of a sequence of individual
characters. The size of a string is determined by the number of
characters contained in it. For example, the string "apple tree" has
10 characters (we must include the space). Any string can be broken
into substrings. For example, "apple", "tree", "app" and "le tre" are
all valid substrings of "apple tree". In theory, a string can be of
any length; this entire book could be contained in a single string,
though it would be impractical. Manipulation of strings is an
important technique in programming applications. Asterisk lets you
manipulate strings and substrings using the : (colon)
character. Using the : character, you can extract a
specified portion of an existing string variable.
Many telephone systems require that a prefix digit be dialled
in order to get an outside line (In North America, this is usually
"9"). The target number, however, cannot include this prefix digit.
If we dial 9-1-202-7075000, we can store the actual
outside number in the ${OUTGOINGNUMBER} using the
following dialplan entry.[13]
exten => _0X.,1,Set(OUTGOINGNUMBER=${EXTEN:1})
If the length option is omitted, the rest of the string is taken automatically.
What if we only need the last seven digits of the dialed
number? I this case we use a negative number for the start
parameter. The following entry would store 7075000 from our example
above in the variable ${LOCALNUMBER}.[14]
exten => _0X.,1,Set(LOCALNUMBER=${EXTEN:-7})
We can also capture just the area code:
exten => _0X.,1,Set(AREACODE=${EXTEN:2:3})
|
|
|
Obviously, readers in other parts of the world (e.g. the United Kingdom, Australia, or elsewhere) will have different national dialplans which impact how outside numbers should be processed. Some countries have area and city codes which are variable in length; in those cases, this kind of number filtering will not be practical. |
Here, then, is how we might extract useful information from a dialed number:
exten => _9X.,1,Set(AREACODE=${EXTEN:2:3})
exten => _9X.,n,Set(LOCALNUMBER=${EXTEN:5})
[11] see also the section called “Set()”
[12] A classic "Which comes first, the chicken or the egg?" problem!
[13] For our curious readers: this is the general information number for the Library of Congress in Washington, D.C.
[14] Under the original rules of the NANP (North American Numbering Plan) the last seven digits of a number constituted the local portion of the number. That is, if your telephone number was in the same area code as the dialed number, you needed only to dial seven digits. Population growth and density means that the number spaces of many area codes are becoming depleted. To minimize disruption, the NANP has been extended with overlay dialplans. In areas with overlay plans, two telephone lines on the same street, or even in the same building, may have different area codes. You are in an overlay area if you are required to dial 10 digits for local calls. In this case, a local number filter as depicted above will not be appropriate. Also, many area codes covering larger areas still have portions of the number space that are treated as long distance. You can read more about this at http://en.wikipedia.org/wiki/Overlay_plan .