转载:http://blog.chinaunix.net/space.php?uid=2555411&do=blog&id=68019
asterisk使用之Channel Variables (通道变量)[1]
零:什么是channel(what is a channel?)
通道可以看作将一个连接,这个连接将一个通话连到asterisk PBX上。可以是到一个普通话机的连接,可以是连到普通电话线的连接,也可以是到一同逻辑通话的连接(如互联网电话)。Asterisk并不区分FXO和FXS通道(就是说,它不区分电话[telephones]和电话线[telephone lines])。每个通话(call)都会被加到一个通道中。
一:通道变量(channel variables)
介绍(Introduction)
在asterisk的拨号方案中有两种级别的参数求值方法。
1.第一种,也是最常用的,就是用变量的值对其引用进行置换
2.然后就是下面的文章中会讨论到的,使用$[...]对表达式进行求值
参数引号(Parameter Quoting)
l exten => s,5,Background,blabla
上面的参数blabla也可以被引号引起来("blabla")。在这个例子中,逗号并没有终止该字段,双引号会传给Background命令。变量替换的一些特殊字符,表达式求值等都可以被引号引起来。例如,为了在字符串"$1231"中使用$这个字符,可以使用\前缀加在$前面。下面的这些特殊字符必须使用引号引起来才能使用,它们是[]$"\。
这些双引号和转义字符在asterisk配置文件的级别上被解析,也就是说它们被asterisk的配置文件解析器来解析。
双引号也可以用在表达式里面,下面将讨论到。
变量(Variables)
变量字符串可以包含变量。变量名可以是任意的字符串。它们被存储在各自的通道结构(channel structure)中。
为了给变量赋上一个特定的值,可以使用下面的语句:
* exten => 1,2,Set(varname=value)
你可以在任意的位置使用${variablename}来替换变量值。例如,如果要将$lala添加在$blabla的后面连成的值存储在$koko中,可以这样做:
* exten => 1,2,Set(koko=${blabla}${lala})
有两种引用模式(reference modes) —— 值引用和名字引用。要使用变量的名字来进行引用,只需要写名字就好。而要引用该变量的值,则要使用${variablename}。例如,Set命令把第一个参数作为变量的名字:
* exten => 1,2,Set(koko=lala)
exten => 1,3,Set(${koko}=blabla)
上面的例子将变量"koko"和"lala"都赋值为"blabla"
变量继承(Variable Inheritance)
如果在一个通道(channel)中用"_"作为一个变量的前缀对变量进行赋值,那么这个变量将被继承到在之后的和前一个channel相关的channel中。当继承后,在之后的channel中,前缀将被自动移除。如果以"__"作为前缀最变量进行赋值,那么除了会发生继承外,当继承后,前缀还保持有效。
在拨号方案中,对这些变量的引用(包括带前缀的和不带前缀的)都是对同一变量的引用。注意,如果对一种变量进行了赋值,那么将把之前的变量特性移除,譬如如果之前赋值了__variablename,之后又对其进行了variablename的赋值,那么这个变量保持的就是不带"__"变量的特性。
例子:
Set(__FOO=bar) ; 设置了FOO变量的继承版本
Set(FOO=bar) ; 移除了FOO变量的继承特性
从变量中挑选字符(Selecting Characters from Variables)
从变量中挑选字符的格式可以表达如下:
* ${variable_name[:offset[:length]]}
如果你想要从变量字符串中挑选N个字符,仅仅需要在变量后便添加冒号和数字M,这样的话,将跳过变量的前M个字符,而选择后面的所有字符。
* ; 移除第一个字符,将之后的字符保存到number变量中。
exten => _9X.,1,Set(number=${EXTEN:1})
假设我们拨打918005551234,那么保存进number变量的值是18005551234。当我们需要用户拨打外线,但是不希望传第一个数字时,这种情况非常有用。
如果你用了一个负的偏移值,asterisk则从字符串的最后开始数起,然后选择之后的所有字符。下面的例子我们仍然假设拨打918005551234,将把数字1234存储在number变量中。
;将拨打号码最后四位的前面的数字全部移除
exten => _9X.,1,Set(number=${EXTEN:-4})
我们也可以限定选择的字符的数量。这只需要再添加一个冒号和一个长度值即可。下面的例子将555保存到变量number中。
; 只保存中间的555到变量number中
exten => _9X.,1,Set(number=${EXTEN:5:3})
长度值也可以和负的偏移值联合使用。当不知道字符串的长度,但是知道末尾的数字的时候,这种用法很有用。下面的例子中,即使字符串的开头的一些字符比我们想象的多,我们仍然能够把555保存到number变量中。
; Save the numbers 555 to the 'number' variable
exten => _9X.,1,Set(number=${EXTEN:-7:3})
如果使用了负的长度值,asterisk将从字符串后面移除这么长的字符数量。
; Set pin to everything but the trailing #.
exten => _XXXX#,1,Set(pin=${EXTEN:0:-1})
表达式(Expressions)
像这样格式的字符串$[….]是一个表达式,可以被用来求值。“表达式求值”同“变量替换”使用方式类似:表达式(包括方括号)被表达式求值的结果替代。
例子:
exten => 1,1,Set(lala=$[1 + 2])
exten => 1,2,Set(koko=$[2 * ${lala}])
变量koko的值被赋为6
下面的例子:
exten => 1,1,Set,(lala=$[ 1 + 2 ]);
将按照之前的想法进行解析。多余的空格被忽略了。
变量值中的空格(Spaces Inside Variables Values)
如果求值的变量中包含空格,可能会产生问题。
对于这些情况,包含空格的字符串被引号引起来将把包含的文本强制解析成一个单独的标记。双引号将被当作标记的一部分。
例子:
exten => s,6,GotoIf($[ "${CALLERID(name)}" : "Privacy Manager" ]?callerid-liar,s,1:s,7)
变量CALLERID(name)可以被求值为”DELOREAN MOTORS”(带一个空格),但是上面的将被求值为”DELOREAN MOTORS” : “Privacy Manager” 该值为0
如果上面的例子不带双引号,那么将被求为:
DELOREAN MOTORS : Privacy Manager
并且将导致语法错误,因为标记DELOREAN被MOTORS跟着,表达式解析器不知道怎么求这种表达式,其不符合语法。
运算符(Operators)
下面的运算符以优先级递增的方式列在下面。同等优先级别的操作符被放在{}符号中。
- expr1 | expr2
如果expr1的值既不为空串也不为0,那么则返回expr1的值;否则,返回expr2的值
- expr1 & expr2
如果expr1表达式的值不为空也不为0则返回expr1的值;否则返回0
- expr1 {=, >, >=, <, <=, !=} expr2
如果两个参数是数字的话,则返回浮点数比较的结果;否则返回使用本地描述对并排序方法得到的字符串比较的结果。如果指定的关系为真,则每次比较的结果是1,否则为0。
- expr1 {+, -} expr2
返回浮点参数相加,或相减的结果。
- expr1 {*, /, %} expr2
返回乘,浮点数相除,和参数求余的结果。
- - expr1
返回0减去expr1的结果。此运算符称为一元减法运算符,是右关联(right associative)的运算符,其同!运算符的优先级相同。
- ! expr1
返回expr1的逻辑补码的结果。换句话说,如果expr1是null,0,空串,或串“0”,怎返回a 1。否则,返回a 0。它同一元减法运算符的优先级相同,也是有关联的。
- expr1 : expr2
:运算符使expr1同expr2进行匹配,expr2必须是正则表达式。而这个正则表达式需要使用隐式的’^’来锚定字符串的起始处(译者注:也就是说,expr2都是从开头匹配)
如果匹配成功并且模式中包含至少一个正则子表达式’…’,则相对于’\1’的字符串会被返回;否则匹配运算符则返回匹配字符的数量。如果匹配失败并且模式包含一个正则子表达式,那么null将被返回,否则返回0.
一般地,包含字符串的双引号被当作该字符串的一部分。这种情况对于:运算符是灾难性的。因此,在匹配进行前,双引号字符的开始和结尾会被从模式和字符串中被剔除。
- expr1 =~ expr2
大部分都和:运算符相同,唯一不同的是此运算符的匹配不是从字符串的开始处锚定。:和=~的优先级别是相同的。
- expr1 ? expr2 :: expr3
传统的条件操作符。如果expr1求值为0(false),则返回expr3的结果。否则expr2被返回。如果expr1是一个字符串,并且求值是一个空串,或是两个字符“”,那么返回expr3。否则,返回expr2。在asterisk中,所有的这3个expr都会被求值;如果expr1为”true”,expr2被返回,否则返回expr3。这个操作符的优先级别最低。
- expr1 ~~ expr2
联接操作符。这两个expr都会被求值,然后转化成字符串(剔除了双引号的),最后被合并成一个没有中间空格的字符串。这个操作符从1.6.0之后的版本才出现;在目前存在的extensions.conf代码中是不需要的。
asterisk使用之Channel Variables (通道变量)[2]
1.6及其以后的版本,我们将整数替换为浮点数来进行表达式的计算。可能的话,我们使用‘long double’,long double包括12个字节,提供16个数字的数字精度。
要指定一个浮点数常量,必须使用下面的格式:D.D,D是10进制的一个字符串。你可以写成0.10,但是不能写成.10或是20. – 我们希望这不是一个过分的限制!
可以使用printf函数的’%g’/’%Lg’将浮点数转变成字符串。这就允许这些数字在那些依靠整数进行操作的行为中看起来仍然像一个整数。如果你想将1/4求值为0,需要写成这样TRUNC(1/4)。我们会在下一节列出asterisk所有的截断/凑整的能力(truncation/rounding capabilities)。
函数(Functions)
1.6以后的版本,我们升级了$[]表达式,使其处理浮点数。因此,传统的使用整数进行的操作就变得异常了。为了使结果一致成为可能,一些凑整和整数截断函数被添加进了Expr2解析器的核心部分。的确,拨号方案函数不需要${}操作符也可以从$[…]表达式被调用了。唯一的麻烦可能就是这些函数的参数必须用逗号来指定。譬如,如果你试着调用MATH函数,3 + MATH(7*8),表达式解析器会将7*8求值为56提供给你,MATH函数很可能会抱怨它的输入没有任何意义。
我们也提供了一些访问C库中的浮点数函数的方法(不包括所有的函数)。
我们不希望人们在拨号方案中做傅立叶分析,但是我们也不会阻止他们。
下面是Expr2的一份内建函数的列表。所有的其他的拨号方案函数可以简单的通过调用它们来获得。换句话说,你不再需要使用${}在$[]中将函数包起来。但是,千万不要现在下结论—— 因为你仍然需要用花括号将变量名给括起来。
1.COS(x) x 是弧度,结果值从-1到1
2.SIN(x) x是弧度,结果值从-1到1
3.TAN(x) x 是弧度
4.ACOS(x) x 应该是一个从-1到1的值
5.ASIN(x) x应该是一个从-1到1的值
6.ATAN(x) 以弧度表示返回反正切值; 值介于-PI/2和PI/2之间
7.ATAN2(x,y) 除非两个参数被用来决定结果所在的象限,否则返回一个类似于y/x的结果。结果值以弧度表示,介于-PI和PI之间。
8.POW(x,y) 返回x的y次幂。
9.SQRT(x) 返回x的平方根。
10.FLOOR(x) 将x向下凑整为最接近的整数。
11.CEIL(x) 将x向上凑整为最接近的整数。
12.ROUND(x) rounds x to the nearest integer, but round halfway cases away from zero.
13.RINT(x) rounds x to the nearest integer, rounding halfway cases to the nearest even integer.
14.TRUNC(x) 将x凑整为不大于实际值的最接近的整数。
15.REMAINDER(x,y) computes the remainder of dividing x by y. The return value is x - n*y, where n is the value x/y, rounded to the nearest integer. If this quotient is 1/2, it is rounded to the nearest even number.
16.EXP(x) 返回e的x次幂。
17.EXP2(x) 返回2的x次幂。
18.LOG(x) 返回x的自然对数。
19.LOG2(x) 返回以2为基数的x的log值。
20.LOG10(x) 返回以10为基数的x的log值。
例子(Examples)
"One Thousand Five Hundred" =~ "(T[^ ]+)"
返回: Thousand
"One Thousand Five Hundred" =~ "T[^ ]+"
返回: 8
"One Thousand Five Hundred" : "T[^ ]+"
返回: 0
"8015551212" : "(...)"
返回: 801
"3075551212":"...(...)"
返回: 555
! "One Thousand Five Hundred" =~ "T[^ ]+"
返回: 0
!( "One Thousand Five Hundred" : "T[^ ]+" )
返回: 1
2 + 8 / 2
返回6.
2+8/2
返回6.
(2+8)/2
返回5
(3+8)/2
返回5.5.
TRUNC((3+8)/2)
返回5.
FLOOR(2.5)
返回2
FLOOR(-2.5)
返回-3
CEIL(2.5)
返回3.
CEIL(-2.5)
返回-2.
ROUND(2.5)
返回3.
ROUND(3.5)
返回4.
ROUND(-2.5)
返回-3
RINT(2.5)
返回2.
RINT(3.5)
返回4.
RINT(-2.5)
返回-2.
RINT(-3.5)
返回-4.
TRUNC(2.5)
返回2.
TRUNC(3.5)
返回3.
TRUNC(-3.5)
returns -3.
当然,上面的所有例子使用的都是常量,但是如果使用变量引用来替代数字或字符串常量,效果是一样的,譬如${CALLERID(num)}。
数字 Vs. 字符串
完全由数(numbers)组成的标记如果可能的话,会转换成’long double’类型,根据操作系统,编译器和硬件的不同,有80到128位不等。这就意味着当数(numbers)超过18个数字(digits)时,可能会发生溢出(根据位数的不同有所不同)。这种情况下,警告将被记录在log文件中。
条件语句(Conditionals)
有一种条件语句的应用——按条件goto到不同的标签(labels)
exten => 1,2,GotoIf(condition?label1:label2)
如果条件为真,则转到label1,否则转到label2。在通常的goto命令中,标签都会被正确的解释。
“条件”仅仅是一个字符串。如果该字符串为空或为“0”,则被认为是假(false),否则被认为是真(true)。这种设计被用来和上面描述的表达式语法一起使用,如:
exten => 1,2,GotoIf($[${CALLERID(all)} = 123456]?2,1:3,1)
其他的例子:
exten => s,2,Set(vara=1)
exten => s,3,Set(varb=$[${vara} + 2])
exten => s,4,Set(varc=$[${varb} * 2])
exten => s,5,GotoIf($[${varc} = 6]?99,1:s,6)
解析错误(Parse Errors)
目前语法错误会有3行输出信息。
如果在extensions.conf文件中包含如下的内容:
exten => s,6,GotoIf($[ "${CALLERID(num)}" = "3071234567" & & "${CALLERID(name)}" : "Privacy Manager" ]?callerid-liar,s,1:s,7)
日志中的信息告诉你碰到了一个语法错误。它还告诉你(以一种极其标准的bison格式),它遇到了一个没有意料到的”AND(&)”标记,而它希望是一个MINUS(-),LP(左括号)或是一个无格式标记[plain token](字符串或数字)
接下来的一行显示了被求出的表达式的值,之后的行信息,以及由“^”字符标记的遇到的解析错误的位置信息。
NULL字符串(NULL Strings)
判断一个字符串是否为null可以通过下面的两种方式:
exten => _XX.,1,GotoIf($["${calledid}" != ""]?3)
或是
exten => _XX.,1,GotoIf($[foo${calledid} != foo]?3)
上面的第二种方法是WIKI中建议的。只要所求值中没有空格,就有效。第一种方法在任何情况下都可以使用,事实上,它可能是目前处理这种情况的最安全的方法。
警告(Warning)
如果你需要使用字符串来做一些复杂的事情,asterisk表达式不是最好的选择。AGI脚本可能是处理这种需要的最佳选择,它可以使你发挥出你确定使用的编程语言的完全的能力(Perl, C, C++, Cobol, RPG, Java, Snobol, PL/I, Scheme, Common Lisp, Shell scripts, Tcl, Forth, Modula, Pascal, APL, assembler, 等。)
不兼容(Incompatibilities)
Asterisk的表达式解析器已经经历了一些变化。希望这些变化是积极的。
原来的表达式解析器有一个简单的,手写的(hand-written)扫描器和一套简单的bison语法。现在已经升级到一套更加复杂的bison语法和一个允许空格并能够产生更好的错误诊断的手写扫描器。但是相应的需要升级到bison 1.85版本。
接着需要升级的包括新的bison和flex的输入文件(input files),makefile文件也被升级到可以侦测flex和bison的当前版本,版本符合的话它会对新的文件进行编译和链接。
如果你已经1年没有碰你的extensions.conf文件了,那么上面的升级动作可能会给你带来一些头疼的情况,因为已经做过一些变化,而这些变化将影响到asterisk的一些行为以及遗留下来的extensions.conf的构造。虽然这些变化已经设计的尽可能的减小了这些影响,但是却仍然是个问题。
下面的列表给出了一些extensions.conf文件中遗留的一些可能会有影响的内容:
1.空格分隔的标记(token)。之前,标记是由空格来进行分隔的。因此,’1 + 1’被求值为’2’,但是’1+1’却被求值为字符串’1+1’。如果这个行为仍然成立,那么表达式求值的规则将被破坏。所以,现在’1+1’将被求值为’2’,那么有些语句就可能无法正确执行。要防止这些字符串被求值,只需要将它们用双引号括起来即可,如’”1+1”’。
2.冒号操作符。双引号之前的版本,冒号将右方的字符串当作正则表达式的模式(regex pattern),用它来和左边的字符串进行匹配。在开头有一个隐式的^操作符,它的意思就是只从左边字符串的开头进行匹配。如果正则表达式模式或是欲匹配的字符串有双引号引起来,那么它们(double quotes)也参与到匹配当中。而现在,在匹配之前,双引号将被移除。之所以这么做,是因为扫描表达式的新的方式是不再使用空格来进行对标记的分隔,并且正则中的操作符将被扫描器当作表达式操作符。因此,除非该模式被双引号引起来,否则将会有麻烦。譬如,${VAR1} : (Who|What*)+在以前的版本中可能正常有效,但是现在,除非你加上双引号,否则就要当心了!像下面这样”${VAR1}”:”(Who|What*)+”将能像以前一样正常有效。
3.Variables and Double Quotes Before these changes, if a variable's value contained one or more double quotes, it was no reason for concern. It is now!
4.LE, GE, NE操作符被移除。以前的代码支持这些操作符,但是没有被写入文档。取而代之的是符号操作符<=, >=和!=。
5.增加了一元’-’操作符。所以你可以像这样写3+-4从而得到-1。
6.增加了一元’!’操作符(逻辑补码)。基本的,如果字符串或数字为null,空或’0’,将返回1。否则,将返回0。
7.增加了’=~’操作符,这是为了可以去匹配字符串中任何位置的子字符串。它和’:’操作符的唯一区别就在于它不用从字符串的开头开始匹配。
8.增加了条件操作符’expr1 ? true_expr : false_expr’。首先,所有的3个exprs都会被求值,如果expr1为假(false),结果将返回’false_expr’,否则返回’true_expr’。要了解详细内容,可以看前面章节。
9.一元操作符’-’和’!’能够被正确的关联使用。
调试提示(Debugging Hints)注:可能在有些版本不适用
你可以构建两个实用的工具来帮助你调试extensions.conf文件中的$[]。
首先,也是最简单的,就是执行下面的命令:
make testexpr2
在asterisk源码的文件夹的顶层目录中,上面的命令将构建一个小的可执行文件,这个可执行文件将运行表达式解析器。不会有变量替换产生。这可能是最安全的将表达式用单引号引起来的方式。例如:
testexpr2 '2*2+2/2'
在utils文件夹中,你可以输入:
make check_expr
于是,一个小的程序被构建,这个程序将检查第一个命令行参数提到的文件,当你使用flex-2.5.31的时候,对于任何表达式都会有问题。当你从原来的flex-2.5.31版本升级到更高版本的时候,这个程序被设计用来帮助找到可能的不兼容。
一个新的功能被加进了check_expr,这个功能可能更加有用。它对所有的变量进行简单的有意的求值,然后将$[]exprs传给解析器。如果有任何的解析错误,它们将被写进log文件。你可以用check_expr对你的extensions.conf文件进行合理的检查,从而发现一些语法错误。
简单有意(simple-minded)的变量替换用类似’555’来替代了${varname}的变量引用。对于变量值,你可以通过在命令行中的文件参数后添加var=val 参数来重写555,所以,下面的例子
check_expr /etc/asterisk/extensions.conf CALLERID(num)=3075551212 DIALSTATUS=TORTURE EXTEN=121
将使用3075551212来替代文件中的任何${CALLERID(num)}变量引用,’TORTURE’替代${DIALSTATUS},’121’替代${EXTEN}。不过如果在引用中有一些特殊的写法,那么这些将不起作用。在${…}中的内容必须要匹配才行。所以,如果想要替换${EXTEN:2}引用,你最好写成这样:
check_expr /etc/asterisk/extensions.conf CALLERID(num)=3075551212 DIALSTATUS=TORTURE EXTEN:2=121
你将看到在标准输出stdout中显示:
OK -- $[ "${DIALSTATUS}" = "TORTURE" | "${DIALSTATUS}" = "DONTCALL" ] at line 416
在生成的expr2_log文件中,你将看到:
line 416, evaluation of $[ "TORTURE" = "TORTURE" | "TORTURE" = "DONTCALL" ] result: 1
check_expr只是一个很简单的算法,它不能解决所有的问题,但是希望它对于你的工作有用。
asterisk使用之Channel Variables (通道变量)[3]
在asterisk中,定义了许多变量,或是有些变量能够被其读取。下面给出了它们的列表。在每一个application的帮助文档中,你可以获得更多的信息。所有这些变量都是大写的。
被*标记的变量是内建函数,不能在拨号方案中被设置,只能被读取。对这些变量的赋值将被忽略。
${CDR(accountcode)} * Account code (if specified)
${BLINDTRANSFER} The name of the channel on the other side of a blind transfer
${BRIDGEPEER} Bridged peer
${BRIDGEPVTCALLID} Bridged peer PVT call ID (SIP Call ID if a SIP call)
${CALLERID(ani)} * Caller ANI (PRI channels)
${CALLERID(ani2)} * ANI2 (Info digits) also called Originating line information or OLI
${CALLERID(all)} * Caller ID
${CALLERID(dnid)} * Dialed Number Identifier
${CALLERID(name)} * Caller ID Name only
${CALLERID(num)} * Caller ID Number only
${CALLERID(rdnis)} * Redirected Dial Number ID Service
${CALLINGANI2} * Caller ANI2 (PRI channels)
${CALLINGPRES} * Caller ID presentation for incoming calls (PRI channels)
${CALLINGTNS} * Transit Network Selector (PRI channels)
${CALLINGTON} * Caller Type of Number (PRI channels)
${CHANNEL} * Current channel name
${CONTEXT} * Current context
${DATETIME} * Current date time in the format: DDMMYYYY-HH:MM:SS
(Deprecated; use ${STRFTIME(${EPOCH},,%d%m%Y-%H:%M:%S)})
${DB_RESULT} Result value of DB_EXISTS() dial plan function
${EPOCH} * Current unix style epoch
${EXTEN} * Current extension
${ENV(VAR)} Environmental variable VAR
${GOTO_ON_BLINDXFR} Transfer to the specified context/extension/priority
after a blind transfer (use ^ characters in place of
| to separate context/extension/priority when setting
this variable from the dialplan)
${HANGUPCAUSE} * Asterisk cause of hangup (inbound/outbound)
${HINT} * Channel hints for this extension
${HINTNAME} * Suggested Caller*ID name for this extension
${INVALID_EXTEN} The invalid called extension (used in the "i" extension)
${LANGUAGE} * Current language (Deprecated; use ${LANGUAGE()})
${LEN(VAR)} * String length of VAR (integer)
${PRIORITY} * Current priority in the dialplan
${PRIREDIRECTREASON} Reason for redirect on PRI, if a call was directed
${TIMESTAMP} * Current date time in the format: YYYYMMDD-HHMMSS
(Deprecated; use ${STRFTIME(${EPOCH},,%Y%m%d-%H%M%S)})
${TRANSFER_CONTEXT} Context for transferred calls
${FORWARD_CONTEXT} Context for forwarded calls
${UNIQUEID} * Current call unique identifier
${SYSTEMNAME} * value of the systemname option of asterisk.conf
${ENTITYID} * Global Entity ID set automatically, or from asterisk.conf
Application的返回值(Application return values)
当你调用有些application的时候,它们会返回一个值供你读取。对于每一个application,这些状态字段是唯一的。各种状态值,前参考每个application的帮助文档。
${AGISTATUS} * agi()
${AQMSTATUS} * addqueuemember()
${AVAILSTATUS} * chanisavail()
${CHECKGROUPSTATUS} * checkgroup()
${CHECKMD5STATUS} * checkmd5()
${CPLAYBACKSTATUS} * controlplayback()
${DIALSTATUS} * dial()
${DBGETSTATUS} * dbget()
${ENUMSTATUS} * enumlookup()
${HASVMSTATUS} * hasnewvoicemail()
${LOOKUPBLSTATUS} * lookupblacklist()
${OSPAUTHSTATUS} * ospauth()
${OSPLOOKUPSTATUS} * osplookup()
${OSPNEXTSTATUS} * ospnext()
${OSPFINISHSTATUS} * ospfinish()
${PARKEDAT} * parkandannounce()
${PLAYBACKSTATUS} * playback()
${PQMSTATUS} * pausequeuemember()
${PRIVACYMGRSTATUS} * privacymanager()
${QUEUESTATUS} * queue()
${RQMSTATUS} * removequeuemember()
${SENDIMAGESTATUS} * sendimage()
${SENDTEXTSTATUS} * sendtext()
${SENDURLSTATUS} * sendurl()
${SYSTEMSTATUS} * system()
${TRANSFERSTATUS} * transfer()
${TXTCIDNAMESTATUS} * txtcidname()
${UPQMSTATUS} * unpausequeuemember()
${VMSTATUS} * voicmail()
${VMBOXEXISTSSTATUS} * vmboxexists()
${WAITSTATUS} * waitforsilence()
各种application的相关变量(Various application variables)
${CURL} * Resulting page content for curl()
${ENUM} * Result of application EnumLookup
${EXITCONTEXT} Context to exit to in IVR menu (app background())
or in the RetryDial() application
${MONITOR} * Set to "TRUE" if the channel is/has been monitored (app monitor())
${MONITOR_EXEC} Application to execute after monitoring a call
${MONITOR_EXEC_ARGS} Arguments to application
${MONITOR_FILENAME} File for monitoring (recording) calls in queue
${QUEUE_PRIO} Queue priority
${QUEUE_MAX_PENALTY} Maximum member penalty allowed to answer caller
${QUEUE_MIN_PENALTY} Minimum member penalty allowed to answer caller
${QUEUESTATUS} Status of the call, one of:
(TIMEOUT | FULL | JOINEMPTY | LEAVEEMPTY | JOINUNAVAIL | LEAVEUNAVAIL)
${RECORDED_FILE} * Recorded file in record()
${TALK_DETECTED} * Result from talkdetect()
${TOUCH_MONITOR} The filename base to use with Touch Monitor (auto record)
${TOUCH_MONITOR_PREF} * The prefix for automonitor recording filenames.
${TOUCH_MONITOR_FORMAT} The audio format to use with Touch Monitor (auto record)
${TOUCH_MONITOR_OUTPUT} * Recorded file from Touch Monitor (auto record)
${TOUCH_MONITOR_MESSAGE_START} Recorded file to play for both channels at start of monitoring session
${TOUCH_MONITOR_MESSAGE_STOP} Recorded file to play for both channels at end of monitoring session
${TXTCIDNAME} * Result of application TXTCIDName
${VPB_GETDTMF} chan_vpb
MeetMe会议桥[会议电话桥分器](The MeetMe Conference Bridge)
${MEETME_RECORDINGFILE} Name of file for recording a conference with the "r" option
${MEETME_RECORDINGFORMAT} Format of file to be recorded
${MEETME_EXIT_CONTEXT} Context for exit out of meetme meeting
${MEETME_AGI_BACKGROUND} AGI script for Meetme (DAHDI only)
${MEETMESECS} * Number of seconds a user participated in a MeetMe conference
${CONF_LIMIT_TIMEOUT_FILE} File to play when time is up. Used with the L() option.
${CONF_LIMIT_WARNING_FILE} File to play as warning if 'y' is defined. The default is to say the time remaining. Used with the L() option.
The VoiceMail() application
${VM_CATEGORY} Sets voicemail category
${VM_NAME} * Full name in voicemail
${VM_DUR} * Voicemail duration
${VM_MSGNUM} * Number of voicemail message in mailbox
${VM_CALLERID} * Voicemail Caller ID (Person leaving vm)
${VM_CIDNAME} * Voicemail Caller ID Name
${VM_CIDNUM} * Voicemail Caller ID Number
${VM_DATE} * Voicemail Date
${VM_MESSAGEFILE} * Path to message left by caller
The VMAuthenticate() application
${AUTH_MAILBOX} * Authenticated mailbox
${AUTH_CONTEXT} * Authenticated mailbox context
DUNDiLookup()
${DUNDTECH} * The Technology of the result from a call to DUNDiLookup()
${DUNDDEST} * The Destination of the result from a call to DUNDiLookup()
chan_dahdi
${ANI2} * The ANI2 Code provided by the network on the incoming call. (ie, Code 29 identifies call as a Prison/Inmate Call)
${CALLTYPE} * Type of call (Speech, Digital, etc)
${CALLEDTON} * Type of number for incoming PRI extension i.e. 0=unknown, 1=international, 2=domestic, 3=net_specific, 4=subscriber, 6=abbreviated, 7=reserved
${CALLINGSUBADDR} * Called PRI Subaddress
${FAXEXTEN} * The extension called before being redirected to "fax"
${PRIREDIRECTREASON} * Reason for redirect, if a call was directed
${SMDI_VM_TYPE} * When an call is received with an SMDI message, the 'type' of message 'b' or 'u'
chan_sip
${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 (deprecated)
${SIPURI} * SIP uri
${SIP_CODEC} Set the SIP codec for a call
${SIP_URI_OPTIONS} * additional options to add to the URI for an outgoing call
${RTPAUDIOQOS} RTCP QoS report for the audio of this call
${RTPVIDEOQOS} RTCP QoS report for the video of this call
chan_agent
${AGENTMAXLOGINTRIES} Set the maximum number of failed logins
${AGENTUPDATECDR} Whether to update the CDR record with Agent channel data
${AGENTGOODBYE} Sound file to use for "Good Bye" when agent logs out
${AGENTACKCALL} Whether the agent should acknowledge the incoming call
${AGENTAUTOLOGOFF} Auto logging off for an agent
${AGENTWRAPUPTIME} Setting the time for wrapup between incoming calls
${AGENTNUMBER} * Agent number (username) set at login
${AGENTSTATUS} * Status of login ( fail | on | off )
${AGENTEXTEN} * Extension for logged in agent
The Dial() application
${DIALEDPEERNAME} * Dialed peer name
${DIALEDPEERNUMBER} * Dialed peer number
${DIALEDTIME} * Time for the call (seconds). Is only set if call was answered.
${ANSWEREDTIME} * Time from answer to hangup (seconds)
${DIALSTATUS} * Status of the call, one of: (CHANUNAVAIL | CONGESTION | BUSY | NOANSWER | ANSWER | CANCEL | DONTCALL | TORTURE)
${DYNAMIC_FEATURES} * The list of features (from the [applicationmap] section of features.conf) to activate during the call, with feature names separated by '#' characters
${LIMIT_PLAYAUDIO_CALLER} Soundfile for call limits
${LIMIT_PLAYAUDIO_CALLEE} Soundfile for call limits
${LIMIT_WARNING_FILE} Soundfile for call limits
${LIMIT_TIMEOUT_FILE} Soundfile for call limits
${LIMIT_CONNECT_FILE} Soundfile for call limits
${OUTBOUND_GROUP} Default groups for peer channels (as in SetGroup) * See "show application dial" for more information
The chanisavail() application
${AVAILCHAN} * the name of the available channel if one was found
${AVAILORIGCHAN} * the canonical channel name that was used to create the channel
${AVAILSTATUS} * Status of requested channel
拨号方案宏(Dialplan Macros)
${MACRO_EXTEN} * The calling extensions
${MACRO_CONTEXT} * The calling context
${MACRO_PRIORITY} * The calling priority
${MACRO_OFFSET} Offset to add to priority at return from macro
The ChanSpy() application
${SPYGROUP} * A ':' (colon) separated list of group names. (To be set on spied on channel and matched against the g(grp) option)
OSP
${OSPINHANDLE} OSP handle of in_bound call
${OSPINTIMELIMIT} Duration limit for in_bound call
${OSPOUTHANDLE} OSP handle of out_bound call
${OSPTECH} OSP technology
${OSPDEST} OSP destination
${OSPCALLING} OSP calling number
${OSPOUTTOKEN} OSP token to use for out_bound call
${OSPOUTTIMELIMIT} Duration limit for out_bound call
${OSPRESULTS} Number of remained destinations