现在的位置: 首页 > 综合 > 正文

Asterisk一些笔记

2014年03月23日 ⁄ 综合 ⁄ 共 3128字 ⁄ 字号 评论关闭
在www.asterisk.org上可以获得asterisk 1.4和asterisk 1.2.18两个版本。前一个是for 2.6内核,后一个是for 2.4内核。
我在Ubuntu 6.06上编译和运行了asterisk 1.4。在RH9上编译和运行了asterisk 1.2。
使用”asterisk –vvvc”命令启动了Asterisk 1.2.18后,出现了
Asterisk Ready.
*CLI>
的提示界面。这是Asterisk的console界面。当在*CLI提示符后面使用”dial”命令后,asterisk开始播放一系列的语音。Dial命令是如何工作的,在asterisk内部,dial命令的运行流程是怎样的一个过程?经过二周的断断续续的对源代码的阅读,大致了解了一些信息,特在此记录。记录的过程也可以帮助我整理一下思路。
在asterisk中,有三个重要的逻辑实体。它们完成管理员设定的各项电话功能。这三个实体是:PBX,Channel,Application。
当一个呼叫业务启动后,就会有一个PBX线程被启动,它掌控着这个呼叫业务,直到呼叫业务的结束。
Channel是完成呼叫业务基本功能的实体。这些基本功能包括:二次拨号(send_digit),挂机(hangup),摘机(answer)等。Channel有很多种:H.323,OSS,SIP,ZAP,ALSA,IAX等。每个channnel实体的代码对应于一个名为chan_xxx.c的源代码文件。比如OSS就对应于chan_oss.c。每个Channel实体被编译为.so文件,成为linux的共享对象(Shared Object)。当asterisk系统启动时,系统根据配置有选择的装入这些共享对象(类似于WINDOWS下的动态链接库)。
Application是对一个呼叫业务进行操作的动作。我觉得叫Action比较好,不清楚为什么叫application,也许我还没有了解更深入吧。这些动作有:拨号(dial),echo,answer,wait,playback等。每个application实体的代码对应于一个名为app_xxx.c的源代码文件。比如wait就对应于app_wait.c。Application类似channel也被编译成为.so。
上面介绍了三个完成asterisk系统各项电话功能的实体,下面介始asterisk系统的几个基本的配置文件。
目前,我只理解了一小部分的配置文件。对于channel,每个channel都有自已的配置文件。同样对于OSS,配置文件是oss.conf。另一个重要的配置文件是extension.conf。它确定了asterisk系统的dial plan。
下面从asterisk系统的main()开始,介绍PBX,Channel,Appliction这三者是如何关联到了一起。
Asterisk.c中的main()是系统的开始入口函数。在2363行,main()调用了load_modules()来装载各个模块(也就是共享对象)。Asterisk会装载channel oss模块,我们转到chan_oss.c文件中的load_modules()函数。在这个函数里,
首先,cfg = ast_config_load(config);装入了oss.conf文件的内容;
其次,ast_channel_register(&oss_tech);将channel的各项基本功能注册到了系统中。oss_tech是一个struct ast_channel_tech结构。它记录了channel oss完成基本功能的各个函数地址。每个channel都是这样注册到系统中的。
最后,ast_cli_register_multiple()将channel oss支持的CLI命令及其对应的回调函数注册到系统中。
这样,一个channel实体被装载了。
回到启动asterisk后的console界面上来。在提示符*CLI>后,输入dial,将听到声卡发出的声音。这个命令是如何被执行的呢?
由于channel oss将自己支持的命令在被装载时,通过ast_cli_register_multiple()注册到了系统中,因此,在系统的*CLI>提示后输入了dial后,系统在注册信息找到了channel oss支持dial这个命令,并确定了chan_oss.c中的console_dial()函数是这个命令的回调函数,这个回调函数被调用。
在console_dial()中,oss_new()被调用是最关键的地方。oss_new()的作用在doc/channel.txt中有说明。事实上,channel.txt中对channel的作用有更清晰的说明。回到oss_new上,oss_new分配了一个新的struct ast_channel c。这个c的exten在ast_channel_alloc()里被缺省赋值为”s”,这一点还是很重要的。然后,oss_new调用了ast_pbx_start()启动了一个PBX线程。这个线程在其生命期里负责处理这个channel的事件。这个线程是pbx.c中的__ast_pbx_run ()。在__ast_pbx_run()里,pbx线程通过ast_exists_extension()和ast_spawn_extension()确定了呼叫的业务流程。
业务流程是由dial plan确定的。Dial plan在extension.conf中配置。对于oss的dial(这是一个呼出),业务流程是如何确定的呢?
在oss.conf中,配置了这个channel的context和extension。对于channel oss ,它的context是local。对于context and extension这两个概念在asterisk handbook中有说明。有了channel oss的contest and extension,pbx线程从extension.conf中去寻找。在extension.conf中,对于oss 的context是这样配置的:
[local]
ignorepat => 9
include => default
include => parkedcalls
……
[default]
include => demo
[demo]
exten => s,1,Wait,1 ; Wait a second, just for fun
exten => s,n,Answer ; Answer the line
exten => s,n,Set(TIMEOUT(digit)=5) ; Set Digit Timeout to 5 seconds
exten => s,n,Set(TIMEOUT(response)=10) ; Set Response Timeout to 10 seconds
exten => s,n(restart),BackGround(demo-congrats) ; Play a congratulatory message
exten => s,n(instruct),BackGround(demo-instruct) ; Play some instructions
exten => s,n,WaitExten ; Wait for an extension to be dialed.
从这个配置上就可以看到,dial命令就对应于一个voice menu。当context为local时,执行demo这个context。Channel oss的extension缺省为”s”。因此,dial plan为先等待1秒,然后,应答它,通过BackGround应用,播放demo-congrats语音文件。 
【上篇】
【下篇】

抱歉!评论已关闭.