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.
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
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
.
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)
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")
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
System variables relevant to specific Asterisk functions are
covered again in their respective chapters.[12]
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.
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})
[11] see also Section B.110, “
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
.
No hay comentarios:
Publicar un comentario