Asterisk开源工程分析12.docx
- 文档编号:23883077
- 上传时间:2023-05-21
- 格式:DOCX
- 页数:28
- 大小:54.93KB
Asterisk开源工程分析12.docx
《Asterisk开源工程分析12.docx》由会员分享,可在线阅读,更多相关《Asterisk开源工程分析12.docx(28页珍藏版)》请在冰豆网上搜索。
Asterisk开源工程分析12
Asterisk开源工程分析(1.2)
曾盛金
2008-4-18
记录
修改日期
修改人
原因
2008-4-18
曾盛金
创建
Asterisk开源工程分析(1.2)1
1、序言:
3
2、asterisk的架构3
3、启动5
3、1Ulaw初始化5
3、2alaw初始化5
3、3Callerid初始化5
3.4、64参数表初始化5
3.5、Tdd初始化5
3.6处理根配置文件5
3.7、term的初始化6
3.8、配置CLI命令解释器6
3.9、建立管理用的socket6
3.10、载入模块6
3.11、通道初始化6
3.12、管理器初始化6
3.13、cdr_engine初始化6
3.14、device_state初始化7
3.15、rtp初始化7
3.16、图像管理初始化7
3.17、pbx初始化7
3.18、modules的再次初始化7
3.19、其他初始化7
4、通话流程(以sip为例)7
4.1、通话的处理流程8
4.2、通话中可以使用的控制台处理函数9
5、asterisk的核心9
5.1、pbx交换模块9
5.1、Pbx的桥接10
5.2、pbx桥接的数据转换问题11
6、Asterisk的通道管理(channel.c)11
6、1、通道模块有:
(channels目录下)11
6、2、通道接口应该实现的接口12
6、2、1通道启动12
6、2、2开始一个电话呼叫12
7、拨号方案管理13
8、io管理(io.c)14
9、呼叫记录管理(cdr.c)15
10、通信用户管理(db.c)15
11、iax管理15
12、日志管理16
13、应用管理16
14、媒体流管理16
15、媒体文件16
16、软件解码文件17
17、asterisk的下载和安装17
1、序言:
Asterisk是开源的IPPBX,其支持模式有:
ip电话与传统电话之间的数据交换、ip电话与ip电话之间的数据交换,传统电话与传统电话之间的数据交换。
总的来说,asterisk主要在下面3个方面进行数据的交换。
(1)、模拟接口,如模拟电话
(2)、数字接口,如T1和E1
(3)、voip协议,如sip,iax
(注:
其支持语音邮箱、坐席和会议室)
Asterisk主要在linux上运行,其最初设计的目的就是与linux一样,支持开源的方式,其最初的发起者也就选择了linux平台。
如果要支持传统的电话系统,需要配置对应的TDM卡(主要支持FXO和FXS模式)来支持,也可以支持T1/E1。
业界对单个Asterisk可以支持的用户数没有统一的定论,考虑到cpu既要做信令的管理还要做数据的采集、处理、交换、传输,因此支持的用户数量有一定的限制。
下面是一个参考:
系统
通道数
最小要求
非专业系统
<5
400Mcpu,256M内存
Soho系统
5~10
1Gcpu,512M内存
小型商用系统
10~15
3Gcpu,1G内存
中等商用系统
>15
双处理器,在分布式架构中采用多个服务器
2、asterisk的架构
Asterisk的架构非常灵活,其支持的很多功能都做成模块的方式来单独加载。
它支持CLI命令,支持通过网络的方式与管理核心通信。
而其作为通道的接口都是采用动态库的方式来加入到系统中,使得系统得构建非常灵活。
下面是asterisk得一个构建示意图,上面得pbx是系统的电话交换核心,中间的是asterisk支持的通道接口,下面是管理接口,它可以直接对通道进行管理。
拨号策略
(对应的是apps目录下的程序),在拨号策略中,可能需要dial,go,answer,playback
这也对应于配置文件的extensions.conf中的设置
Asterisk的交换核心
(pbx.c,channel.c,app_dial.c,dsp.c,cdr.c等组成)
其他接口
I
A
X
2
E1
F
X
O
F
X
S
Sip
电话
Cli接口(控制台命令接口)cli.c
Asterisk的程序源代码的分布为:
Asterisk-1.2.0---核心模块pbx.c,启动模块等
---codecs/解码器等模块,对应是否需要码流转换。
---channels/各种通道模块
---apps/主要是拨号模块
---sounds/存放声音demo声音文件
---cdr/记录通话模块
---formats/支持录放音的格式
Asterisk的很多信息都是采用配置文件来进行处理,其中asterisk很有创意的设计是拨号方案。
在extensions.conf文件中,可以定义很多拨号模式,采用模式匹配的方式进行。
3、启动
在Asterisk的main函数中,顺序初始化ulaw,alaw,callerid,utils,tdd参数信息,初始化CLI的命令管理,建立命令管理用的socket,初始化日志管理,dns管理,开始载入模块,初始化通道管理,引擎管理,设备管理,rtp管理,转入pbx核心,初始化fram管理,初始化数据库管理。
注:
asterisk必须在root的用户下运行
3、1Ulaw初始化
1、初始化__ast_mulaw数组。
2、初始化__ast_lin2mu数组
3、2alaw初始化
1、__ast_alaw初始化
2、__ast_lin2a的初始化
3、3Callerid初始化
给cid_dr,cid_di,sasdr,sasdi,casdr1,casdi1,casdr2,casdi2设置初始值。
用于逆fft计算。
3.4、64参数表初始化
主要是进行字母与数字的查表转换。
3.5、Tdd初始化
主要是用于逆fft。
3.6处理根配置文件
配置文件的配置信息(/etc/asterisk/asterisk.conf),这个配置信息在编译的时候是可以修改的。
从根配置文件主要是想得到:
1、其他配置文件的位置,如sip,iax,
2、模块加载位置:
如chan_sip.so,app_mp3.so,chan_phone.so,chan_mgcp.so等等
3、库的位置:
存放播放的一些语音文件等
4、日志位置,主要是asterisk的运行过程中产生的一些日志
5、还有其他的一些信息
注:
这些配置文件的解析主要在config.c的ast_config_load函数处理
3.7、term的初始化
如果在环境变量中配置有TERM信息,需要对其进行配置。
主要配置的有颜色,大小等信息。
3.8、配置CLI命令解释器
主要把CLI的结构进行初始化。
在配置后,把程序推倒后台执行。
3.9、建立管理用的socket
其不是tcp或udp类别的socket,主要就是给管理模块提供连接使用。
在使用asterisk–r时,需要调用在asterisk.c中的netconsole来处理用户的命令。
3.10、载入模块
首先载入在配置的模块目录下的模块,依次调用模块中的load_module函数,完整对应模块的初始化等。
3.11、通道初始化
控制台显示通道格式化信息和函数注册
3.12、管理器初始化
主要注册Ping、events、logoff、Handup、status等等的命令行函数入口。
3.13、cdr_engine初始化
初始化呼叫详细记录引擎。
3.14、device_state初始化
主要启动一条线程来监视state_changes集合的变化。
3.15、rtp初始化
注册rtp的命令行接口和rtp协议自身的初始化。
3.16、图像管理初始化
注册图形的cli接口
3.17、pbx初始化
公用的pbx处理接口注册,如超时,应答等。
3.18、modules的再次初始化
这次的初始化才真正进行通道的模块的动态加载。
3.19、其他初始化
4、通话流程(以sip为例)
在channels/chan_sip.c中,首先调用load_module完成sip的初始化,主要根据配置文件,设置对应的配置参数,把sip中提供的服务注册到通道对应的管理程序中,注册rtp服务,监视sip的服务请求。
下面是一个sip通信的示意图
...
.proxyproxy.
..
Alice’s............................................Bob’s
softphoneSIPPhone
||||
|INVITEF1|||
|--------------->|INVITEF2||
|100TryingF3|--------------->|INVITEF4|
|<---------------|100TryingF5|--------------->|
||<--------------|180RingingF6|
||180RingingF7|<---------------|
|180RingingF8|<---------------|200OKF9|
|<---------------|200OKF10|<---------------|
|200OKF11|<---------------||
|<---------------|||
|ACKF12|
|------------------------------------------------->|
|MediaSession|
|<================================================>|
|BYEF13|
|<-------------------------------------------------|
|200OKF14|
|------------------------------------------------->|
||
4.1、通话的处理流程
在sip启动的时候,首先把sip的读函数注册到io管理程序中,注册一条线程do_monitor,在其中等待数据到达的信号,等有数据报的io信息到达,直接调用sipsock_read函数进行分析。
sipsock_read函数读取数据报,分离出sip的协议信息。
找到对应的方法,进行处理。
看一个INVITE的情况。
1、在收到信息时,首先进行协议分析,(如果需要rtp处理,则开始一个新的rtp的绑定)然后调用handle_request函数进行处理,确认是INVITE的类别时,调用handle_request_invite函数进行处理。
2、handle_request_invite首先处理一些不支持的信息,如果是合法的,则给请求初始化者一个代码为100的响应(Trying),同时调用ast_pbx_start新创建一个pbx,准备呼叫被叫用户。
3、ast_pbx_start根据判断用户是否存在,然后根据呼叫策略,找到对应的应用管理程序,如dial拨号策略,则使用apps/app_dial.c中的程序进行处理。
Dial创建与呼叫相关的一个通道(可能不再是sip而是电话)。
4、找到被叫的通道信息后,开始调用对应通道的request完成通道占用的准备。
5、准备成功后,调用对应通道的call函数开始进行呼叫。
6、把为主叫方准备的语音通信的句柄和为被叫方准备的句柄放在select接口中等待。
分支:
1、对应通道的io管理监视到其通道有信号进入。
如果是被叫方的信息。
2、被叫方给对应的通道一个响应
3、对应通道开始处理这样的响应,等处理结束后,对应通道又重新监视io信息
回到前面的6:
7、在检测到语音通道有信号后,根据情况,给主叫用户一个应答。
8、开始桥接两个通道,与主叫通信的通道和与被叫通信的通道进行关联(ast_channel_make_compatible―>ast_bridge_call→ast_channel_bridge→在此可能回播放文件或ast_generic_bridge->ast_waitfor_n(等通道有信号)→ast_read(读取通道数据,在需要转换数据格式的情况下,调用转换函数进行数据格式的转换,可以考虑使用dsp来处理)→ast_write(把语音数据转发给另外一个通道))。
9、开始在两个用户之间进行数据的转发。
(asterisk希望数据流都从自己走,好进行通信的记费等管理)
10、通话结束,其中一个用户发出BYE的请求。
11、对应通道得到信息后,给出同意的信号,同时给另外一方BYE的请求。
把自己的通信管理设置为断开的方式。
12、在语音数据的转发中,每次转发都需要检测通道的状态,如果已经断开,则拆出通道,通话工程中,需要调用对应通话通道的read和write函数,以及转换函数,如ulaw等的处理。
13、完成一次通话。
4.2、通话中可以使用的控制台处理函数
为方面管理员对asterisk的管理,每个通道都需要注册直接的管理函数和状态函数到CLI接口中,这主要使用ast_cli_register_multiple来完成注册,主要的函数有:
sip_notify
sip_show_objects
sip_show_users
sip_show_user
sip_show_subscriptions
。
。
。
sip_reload
等函数来支持控制台的命令调用。
借助这些函数,在命令行控制台中可以查看到当前的通话的信息。
5、asterisk的核心
Asterisk的核心有许多模块组成。
重要的有交换模块、通道管理模块,io管理模块,日志管理模块,控制台命令管理模块,数据库管理模块等。
下面逐步进行分析。
5.1、pbx交换模块
在所有的呼叫中,asterisk在接受到用户的呼叫后,都会开始一个新的代理,此代理完成呼叫被叫用户。
在用户开始呼叫的时候,检测完是授权用户,则开始创建一个通道(ast_channel_alloc完成,此时主要就是建立一个与主叫用户的通道)
其触发过程就是调用ast_pbx_start函数。
1、ast_pbx_start函数创建一个pbx_thread线程来处理请求。
2、在线程中,主要处理顺序如下:
调用ast_exists_extension判断用户是否在extension中有配置,如果没有,则调用默认的配置,这个配置文件主要是看:
extensions.conf中的每个节中的配置。
3、如果有,开始调用ast_spawn_extension来处理,主要做一些检测,接下来调用存在apps/app_dial.c中的dial_exec_full来开始准备呼叫。
3、dial_exec_full函数
通过分析呼叫的类别,由ast_request来进行分析,主要是按照extensions.conf中对应的节的exten来按照类别依次调用(此时主要调用的是对应通道的requester函数),
4、在requester函数中,构建一个新的通道(此通道对应asterisk与被叫用户之间的通
道)
主要做的事有:
(1)、从有限通道中选择一个通道或从没有限制的创建一个通道
(2)、在通道的创建中,会有两个句柄建立,用于语音数据通信
(3)、把此通道对应的函数服务给此创建对象。
5、转入对应的channels的处理类别(调用对应的call函数),如果是sip,则又回到chan_sip
的sip_call函数,来完成相被叫用户的呼叫,如果是电话,这调用chan_phone的
phone_call函数进行呼叫。
call主要完成的工作:
(1)、如果在phone中,则开始响铃
(2)、如果是在sip中,则构建一个INVITE的信息,发送给被叫用户。
6、在得到sip_call的信息后,如果发送消息出去后没有报错(在对应的call函数中不能进行等待,否则会阻塞其他相同的服务),如果需要给主叫用户一个响铃,则发送响铃信息给主叫用户,然后开始等待对方应答
wait_for_answer
在此需要注意的是:
控制权暂时回到对应通道的单个通道中。
(注,此时是通道进行io检测,实际上是等待用户的信息)
在chan_sip.c或chan_phone.c等中的do_monitor函数在一直检测对应的协议块中是否有信号等待处理,如果有,处理结束时候,再检测是否有需要唤醒的等待信号,有则唤醒。
如果被呼叫的用户给出ok的响应,则在chan_sip.c或其他通道中的接受函数会得到此消息,设置subclass变量为AST_CONTROL_ANSWER模式,发出被叫用户已经摘机的状态变化。
7、在有音频数据连接后,Wait_for_answer被唤醒,判断是否需要给呼叫发起者一个应到,如果需要,则产生一个应答。
8、把两个对等通信的用户桥接起来,开始接管音频数据流通信。
9、在接管音频数据流后,开始不停的接受数据,同时检测用户是否挂断对话,如果是,则开始处理退出的工作。
5.1、Pbx的桥接
桥接是pbx的核心,在上面pbx的处理流程中,我们发现,当需要在不同或相同类别的用户进行通话时,语音数据是需要pbx进行桥接的。
由于对应的通道在响应被叫用户的时候,把通道的subclass设置为AST_CONTROL_ANSWER,在Wait_for_answer等待后,根据上面的标志表示对应的被叫用户和pbx已经连接上。
开始调用ast_bridge_call进行后面的处理,
1、首先调用主叫用户的应答函数,对主叫进行连接成功的响应。
2、接下来调用ast_channel_bridge来进行两个用户的桥接。
(ast_channel_bridge定义在Channel.c中,是通道管理函数之一)。
在此函数中,把两个通道的语音通道进行交换,设置通话的时间片,媒体格式等。
3、ast_generic_bridge函数中开始语音的转接。
每当桥接的双发的句柄有信号的时候,
其开始读数据,按照要求进行处理后,然后转发给另外一方。
5.2、pbx桥接的数据转换问题
由于桥接的时候,数据可能是从不同的通道进入和转发出去,因此得到的声音编码方式可能不会一致,这是应该调用转换函数进行转换,然后在把数据发送给对应的通道。
数据的具体格式支持ulaw方式,G72.1G72.3格式
6、Asterisk的通道管理(channel.c)
通道管理是Asterisk把各种不同的设备进行通信组织在一起的。
通道函数包含下面一些服务:
1、注册,ast_channel_register,在每个通道初始化后,需要把自己的服务调用此函数来告诉通道管理系统。
在管理函数中,是一个链表组成的管理队列。
2、取消注册,ast_channel_unregister。
3、代理发起应答,ast_answer,调用对应的通道完成应答处理,对应的是phone_answer,sip_answer等
4、ast_call,调用对应的通道完成呼叫,对应的是phone_call,sip_call等
5、ast_indicate,调用对应的通道完成响铃,主要是设置一个状态
6、。
。
。
这些服务都有pbx和控制台来调用,完成对应的通道处理。
6、1、通道模块有:
(channels目录下)
1、chan_zap.so,isdn或T1或E1通道支持
2、chan_phone.so,电话支持
3、chan_sip.so,网络电话支持
4、chan_iax2.so,asterisk组网模块支持
5、chan_modem.so,支持电话猫模块
6、chan_h323.so,支持h323模块
7、chan_mgcp.so,支持媒体网关模块
8、chan_oss.so
9、chan_local.so
10、chan_skinny.so
11、chan_vpb.so给VoiceTronix配置的接口。
注,为了支持新的设备,可以在此编写对应的接口。
6、2、通道接口应该实现的接口
1、load_module,在这个接口对新加的设备完成初始化和注册
2、定义staticconststructast_channel_tech类型变量,完成下面的一些信息的注册
(1)、类型,用于在extensions.conf的dial函数中的开始部分
(2)、描述,填写一个关于这种设置的信息,以便控制台可以管理
(3)、capabilities,支持的信息的能力,主要有AST_FORMAT_G723_1,AST_FORMAT_SLINEAR,AST_FORMAT_ULAW等选项。
(4)、电话请求requester
(5)、发送数字信号send_digit
(6)、呼叫call
(7)、挂机
(8)、应答,用户此通道是主叫时的情况
(9)、read,处理音频数据的读
(10)、write,处理音频数据的写
(11)、例外处理
(12)、修复当前呼叫
6、2、1通道启动
1、首先在load_module中分析自己的配置文件,当然也可以写在程序中。
注册标准接
口。
2、创建一条线程,开始对自己的设备状态进行监视。
如果某个通道有自己的宿主(就是使用者),则不进行监视。
3、当检测到有信号的时候,分析是那种信号到来。
4、如果需要创建新的电话,则开始一个新的电话
如果是挂断,则开始设置标志,通知电话结束
如果是摘机信号,则开始设置摘机信号标志,同时切换到通话状态(有的不用切
换,如信令和语音数据不在一个通道的情况)。
如果是响铃,则设置响铃信号
6、2、2开始一个电话呼叫
看电话中的例子:
1、在FXS口检测到用户摘机的时候,回送按键音。
2、用户输入电话号码后,FXS口给chan_phone一个信号,在此设备上等待的
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Asterisk 工程 分析 12