3.2. Variables

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.

Tip

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.

Expanding variables in an extension

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})

General considerations

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}.

Important

Asterisk system variables such as ${EXTEN} must always be uppercase.

String variables

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.

Reserved characters

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")

Integers

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.

Tip

If you need to work with larger integers or floating point numbers, you can use an AGI script.

Defining global variables in extensions.conf

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})

Defining variables with Set()

Set() is used to define a variable inside an extension.[11]

Syntax

Set(<variable1>=<value1>[,<variable2>=<value2>][,<option>])
Setting option g makes the variable global; without it, the variable is treated as a local channel variable.
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})

Inheritance of channel variables

If new channels are spawned while a conversation is in progress, they will have their own channel variables.

Single-level inheritance

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")

Multi-level inheritance

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.

Warning

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 ("__CAKE") is rendered uninheritable by the subsequent entry:
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})

System channel variables

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.

Warning

A complete list of all the pre-defined variables may be found in doc/README.variables (Asterisk 1.2) and doc/channelvariables.txt (Asterisk 1.4). Deprecated variables are not included in this list. For example, the variable ${CALLERIDNUM} (previously commonly used) is not in this list; it is preferable to use the Asterisk function ${CALLERID(num)} instead.

Tip

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]

Note

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.

Manipulating variables

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.

Substring

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.
Syntax
${VARIABLENAME[:start[:length]]}
Examples
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})

Note

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})


[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 .