知行合一
全部博文(31)
分类: 系统运维
2010-04-11 20:38:34
AEL纯粹是为了描述asterisk拨号方案而专门发明的一种语言。
目前的版本是Steve Murphy写的,是原始版本的翻写版。
这个新的版本是对AEL的扩展,提供了更加灵活的语法,更好的出错信息,并增加了一些缺失的功能。
AEL是4中不同语言(或者说是语法)的合集:
* 第一种,也是最显而易见的就是AEL语法本身。文档的最后我们会提供BNF
* 第二种,就是表达式语法,是类似于括在$[...]中的表达式,是被asterisk分机引擎(asterisk extension engine)正常处理的语法。赋值语句的右边被AEL括在$[...]当中,同样存在于if和while的表达式中。
* 第三种就是值引用语法(variable reference
syntax),被大括号${...}括起来的那一堆东西。它不仅仅是把一个变量的名字放在里面这么简单。可以包含一个函数(function)以及它们的参数,甚至会有一些字符串的操作记法存在其中。
* 最后一种语法是AEL的基础,并且没有被AEL直接使用,它就是分机语言语法(Extension Language Syntax)。这种语言是你在extensions.conf当中看到的那样,AEL将更高层次的AEL语言编译成extensions和priorities,并且通过函数将其传递给asterisk。嵌入在这种语言中的是Application/AGI命令,每一步的application调用,或者priority都可能是有该命令组成的。你可以将其想象成一种AEL编译进去的宏汇编(”macro assembler”)语言。
任何的AEL的程序员要熟悉它的语法,当然还有表达式语法和变量引用语法。
asterisk担当的是服务器的责任。在电话通信中的设备,诸如DAHDI卡,或voip电话,都会指明他们自己的上下文(context),这些上下文应该由他们自己激活。可以看看IAX,SIP,dahdi.conf等配置文件的格式。他们用来帮助描述设备,他们全都会指定上下文,当有人拿起电话,或是从voip话机或是从电话公司来了一通通话,这些上下文都将被激活。
上下文是分机扩展(extensions)的组合。
上下文也可以包含其他的上下文。可以把它想象成为一种运行时的操作的组合,由是包含在上下文A中的分机扩展被添加进了包含A的上下文B中。
一段上下文包含0个或多个分机。也有几个预定义的分机。“s”分机是“开始”分机,当一个设备激活一段上下文的时候,“s”分机将会执行。其他的分机是超时分机“t”,无效应答或是“i”分机,还有“fax”分机。例如,一个正常的通话会激活“s”分机,但是一个传真呼入会到“fax”分机中(如果其存在的话)去执行。(顺便说一句,asterisk可以通过传真机每几秒中发一次的“beep”声音来识别是否是一通传真通话。)
分机包含一些优先级(priorities),他们是单独可以执行的语句。一些语句相当简单,就是一些赋值的语句。而有些比较复杂,如语音信箱应用。优先级按照顺序被执行。
当“s”分机执行完成后,asterisk会等到用户应答结束为止。如果应答符合这段上下文中的分机样式,那么将转到该分机处去执行。通常,应答是用户按键发出的。譬如,和一个桌面话机相关的一段上下文可能没有“s”分机。用户拨号之前,一直会播放拨号音,用户拨号时,则会采集用户输入的数字,找到对应的分机样式,然后开始执行这段分机。这段分机可能会为该用户通过电话线外呼某个号码,然后将两者连接在一起。
分机也可以包含“goto”或是“jump”命令跳转到其他上下文中的分机。
可以把宏看作是拥有未命名分机的一段上下文的结合或是一段子程序(subroutine)。它也有参数。宏可以在一个分机中被调用,在宏执行结束后,再去执行宏调用之后的下一条语句。宏也可以调用其他的宏。他们就像函数一样工作。
应用调用,像“Dial()”或是“Hangup()”又或是“Answer()”都可以被用户用来完成拨号方案的执行。在本篇文章完成的时候,已经有超过145个应用了,并且数量还会随着需求的增加而增长。一些应用提供比较简单功能,而有一些则会提供非常复杂的服务。
但愿,上面的那些对象可以让你在asterisk的环境中作任何你需要作的事!
AEL解析器(res_ael.so)不同于解析extensions.conf(pbx_config.so)的模块。要使用AEL,唯一要做的一件事情就是加载res_ael.so模块。如果在/etc/asterisk/modules.conf中autoload选项设为yes,那么该模块将被自动加载。当模块加载的时候,asterisk会在/etc/asterisk文件夹下面找到extensions.ael文件。如果有需要的话extensions.conf和extensions.ael文件会被同时使用。有些用户可能会想要使用extensions.conf中”general”本分的配置功能。
要重新加在extensions.ael,可以在CLI中输入下面的命令:
*CLI>ael reload
目前,下面的命令可以被使用,但是没有用:
打开AEL上下文调试
*CLI>ael debug contexts
打开AEL宏调试
*CLI>ael debug macros
打开AEL读调试
*CLI>ael debug read
打开AEL记号调试
*CLI>ael debug tokens
关闭AEL调试信息
*CLI>ale no debug
如果你的拨号方案出现了问题,你可以使用下面的方法来调试你的文件:
1.查看/var/log/asterisk中的日志文件。2.asterisk中的”show dialplan”命令。3.一个标准的可执行程序”aelparse”
你可以使用”aelparse”程序来检查你的extensions.ael文件。在将该文件提交给asterisk之前解决掉大部分的错误岂不是一件非常美好的事么?
aelparse在asterisk发行版的utils文件夹下面被编译。它没有被安装,但是你可以将起拷贝到你的PATH路径下面。
Aelparse有下面两个参数:
* -d 使用当前的文件夹作为当前的配置文件夹。Aelparse将去找到当前文件夹下面的extensions.ael文件以及包含在该文件中的当前文件夹下的所有ael文件。
* -n 只显示出错和告警信息。
现在的语法和风格是比较自由的。大括号不必要同在其之前的关键字放在同一行。每一个语句也可以分开多行放置,只要记号(token)不被拆开就行。多个语句也可以放在同一行中。
譬如,你可以这样来写,
* if(${x}=1) { NoOp(hello!); goto
s,3; } else { NoOp(Goodbye!); goto s,12; }
也可以象这样来写:
* if(${x}=1)
{
NoOp(hello!);
goto s,3;
}
else
{
NoOp(Goodbye!);
goto s,12;
}
或者:
if(${x}=1) {
NoOp(hello!);
goto s,3;
} else {
NoOp(Goodbye!);
goto s,12;
}
又或者:
if (${x}=1) {
NoOp(hello!); goto s,3;
} else {
NoOp(Goodbye!); goto s,12;
}
AEL的关键字是大小写敏感的。如果应用(application)的名字和关键字重叠了,那么可能是有原因的,你应该考虑用AEL语句来替代该应用调用(application call)。如果你不希望这么做,那么你仍然可以通过在它的名字中加入大写字母来使用该应用。在AEL中,应用的名字是大小写无关的。
下面是AEL中的一些关键字:
abstract
context
macro
globals
ignorepat
switch
if
ifTime
else
random
goto
jump
local
return
break
continue
regexten
hint
for
while
case
pattern
default NOTE: the
"default" keyword can be used as a context name, for those who would
like to do so.
catch
switches
eswitches
includes
AEL首先将extensions.ael文件解析到内存结构中。整个文件的内容被一棵pval结构的树所替代。这棵树然后被语义解析流程处理,之后又被编译处理,再之后从内存中被释放。
可以写一个程序来构建一棵pval结构的树,还可以提供打印的函数将数据转存为文件,或者可以将数据整合进asterisk的拨号方案中。这种设计的模块化为开发者简化产生拨号方案数据提供了机会。