asterisk12代码学习笔记.docx

上传人:b****8 文档编号:9821144 上传时间:2023-02-06 格式:DOCX 页数:76 大小:374.08KB
下载 相关 举报
asterisk12代码学习笔记.docx_第1页
第1页 / 共76页
asterisk12代码学习笔记.docx_第2页
第2页 / 共76页
asterisk12代码学习笔记.docx_第3页
第3页 / 共76页
asterisk12代码学习笔记.docx_第4页
第4页 / 共76页
asterisk12代码学习笔记.docx_第5页
第5页 / 共76页
点击查看更多>>
下载资源
资源描述

asterisk12代码学习笔记.docx

《asterisk12代码学习笔记.docx》由会员分享,可在线阅读,更多相关《asterisk12代码学习笔记.docx(76页珍藏版)》请在冰豆网上搜索。

asterisk12代码学习笔记.docx

asterisk12代码学习笔记

Ippbx平台相关的

Cvs目前IX在CVS目录ippbx/ipbxsource/ix_src_polylink下,版本可查看目录下的.version文件

命令lsb_release–a和uname–a可以查看OS的信息

查看程序的版本:

在代码的根目录下cat.version

编译方法:

在根目录下make;makeinstall

发布版本:

/PolyLink/usr下的sbin/ippbx、lib/modules

/PolyLink/etc是配置文件

使用ippbx–g(ippbx–gvvvc)开启,然后使用ippbx–r/ippbx-ddddddddvvvvvvvvcr连接上去

重启ippbx用命令(在ippbx–r中)restartnow,stopnow可以停止

在命令行添加命令后要重启ippbx,每次编译完后也要重启

使用reload重新加载某个函数时,会调用模块的reload()函数

ast_log函数的使用debuglevel1app_queue.c

Asterisk的编解码的配置要配置在每个帐号里面。

加在genenal里面是不行的

/PolyLink/etc/modules.conf可以控制是否加载某些模块,参考文件asterisk.c中的main()函数

关键配置文件:

sip.conf,queues.conf(排队相关的),manager.conf(座席,带member的),extension.conf(规则),modules.conf(控制模块加载)

登录座席的时候,先登录座席的软电话才可以登录成功。

intinit_manager(void)中注册的模块用于座席软件通过managerinterface,向PBX发送redirect消息,与命令行无关,ast_cli_register()是注册命令行的。

 

有一个叫sysmoni的进程,先把这个进程杀了,ippbx就不会自己重启了

/////////////////////////////////////////////////////

http:

//192.168.10.121/ipbx/login.do

system123

在web上保存信息时,ippbx会重启。

///////////////////////////////////////////////////////////////////////////////////////////////////

Ipcc外呼相关的:

app_dbspool.c

在192.168.10.121上

mysql-Dpbxdb

select*fromcall_out;

try_calling函数

呼叫座席用函数request_and_dial,然后调用ast_bridge_call

座席相关的代码放在文件app_queue.c的最后。

if(cur->paused||ast_device_state(cur->interface)!

=1){

cur=cur->next;

continue;

}//判断座席是否忙

Functionoutgoing_extenisveryimportant

outgoing_exten->reserve_callout(p,0,0);更改可用的通道数。

reserve_callout=reserve_for_outgoing;//addbyeric.li(forapp_dbspool.so)

//reserve_for_outgoing函数记录可用通道数。

因为一个落地最大的并发数是由上限的,不是无限大的。

callout_thread()去外呼一个用户。

外乎的代码只写在app_queue.c文件中

structcall_queue这个结构体重要,members指座席队列,head指用户队列。

配置文件参数读取相关的

ast_config_engine_register

reload_queues->ast_config_load->ast_config_internal_load->load_func(queues.conf时就是config_text_file_load)->process_text_line

->ast_category_browse

->ast_variable_browse

->queue_set_param

asterisk.c/main->read_config_maps->ast_config_internal_load->config_text_file_load

->ast_variable_browse

->append_mapping

Asterisk1.2增加h264视频

一般配置如下:

sip.conf中[general]节下

videosupport=yes

在分机的设置中

allow=h263;videocodec

allow=h263p;videocodec

allow=h264

相关函数调用过程:

sip_write->ast_rtp_write->ast_rtp_raw_write->sendto//这是个回掉函数,在formats目录下的format_h264.c/load_module中有注册毁掉函数

asterisk小结

查找dialplan是使用主叫的context(在sip.conf中配置的),然后在这个context中查找跟被叫号码匹配的项,挨个执行。

Asterisk架构

 Asterisk核心由以下六部分组成:

(1)PBX交换核心模块(PBXSwitchingCore)

     接受呼叫,并根据dialplan配置,使用ApplicationLancher来进行ring

(2) 调度和I/O管理模块(SchedulerandI/OManager)

     提供给各模块使用

(3)应用调用模块(ApplicationLauncher)

(4)编解码转换模块(CodecTranslator)

(5)动态模块加载器模块(DynamicModuleLoader)

     将各个模块装入,各个部分通过InternalAPI连接。

(6)CDR生成模块(CDRCore)

Asterisk代码架构概述

1    引言

本文档从一个开发者的角度出发,概要描述Asterisk的体系架构。

至于详细的API讨论,请参考公开API头文件所关联的文档。

本文档假定您了解Asterisk的一些知识,并知道如何使用它。

本文的意图是:

从一个高的层次开始了解Asterisk,并逐步深入。

它从Asterisk的组件差异开始,最终讨论这些组件在不同应用场景里的协作关系。

文中,提供了很多交叉引用链接,指向相关API的一些引用参考,也可能指向相关的源码链接。

欢迎对本文档的反馈和贡献。

请将您的真知灼见发给asterisk开发组的邮件组:

 

谢谢,并预祝您享受Asterisk!

2      模块构架

Asterisk是一个高度模块化的应用。

在源码的main/目录下,建立了内核应用。

然而,它(内核)本身的用处并不是很大。

运行时,Asterisk加载了许多模块。

Asterisk的模块都有具体的名称,以标识模块所提供的功能,但是,这些名称没有任何技术意义上的特殊。

Asterisk加载一个模块时,模块向内核注册它所提供的功能。

整个流程看起来是这样的:

1.   启动Asterisk

2.   Asterisk加载模块

3.   模块跟内核说:

嗨,Asterisk,我是一个模块,我能提供X、Y、Z三种功能,用得着的时候要记得我哦。

3    抽象接口类型

Asterisk提供了许多不同类型的接口,具体的模块可以实现这些接口并注册给内核调用。

任何模块,都可以注册任意多种的接口。

通常,一个模块内整合了某些相关的功能。

本节讨论接口的类型,后续将讨论各种场景下不同组件间的协作关系。

3.1   编码解释器CodecInterpreter

编码解释器接口的实现,提供了两种编码间的转换能力。

Asterisk当前只有音频编码转换的能力。

这些模块不了解话务相关的任何信息,也不知为什么要调用它们进行音频转换。

它们仅需要知道音频采样率、音频的输入格式、期待的输出格式这些信息。

如果注册了多个编码解释器,那么编码A转换为编码B的过程,就可能有多种不同的转换路径。

在(编码)模块加载之后,Asterisk建立一张转换表,表中包含不同translator的转换开销评估值,因此,Asterisk能够找出A转换B的最佳路径。

在源码树中,编码模块通常在codecs/目录下。

已有编码解释器的实现列表,请参考:

Module:

Codecs

更多编码解释器API的信息,请参考接口定义文件:

include/asterisk/translate.h.

内核关于编码解释器的相关实现,参考源码:

main/translate.c

3.2   文件格式处理器FileFormatHandler

文件格式处理器接口的实现,为Asterisk提供了读写文件的能力。

文件格式处理器可以提供音频、视频或图像文件的处理能力。

文件处理器的接口是相当原始的。

模块简单地告诉Asterisk内核:

它能处理某种具有待定扩展名的文件,比如说".wav"。

同时,它还说明读取文件之后,将以编码X的形式提供音频。

如果它还提供写文件的能力,那么它还必须说明用它写文件的音频编码要求(即说明它能把什么编码格式的音频编码写成带什么扩展名的文件)。

源码树中,文件格式模块通存放常在formats/目录下。

现有的实现,请参考:

Module:

MediaFileFormats。

文件格式处理器的API定义信息,请参考头文件:

include/asterisk/file.h。

内核中,与文件格式相关的实现,请参考:

main/file.c。

3.3     CAPIProviders

Asterisk有一些可选的CAPI。

内核API是主应用内置的,始终可用。

可选CAPI则是由某个模块提供的,只有在相应模块加载后,才可用。

某些API的提供方,也提供了它自身的接口,供其它模块实现和注册(接口)。

提供CAPI的模块,通常存放在res/目录下。

一些提供CAPI的模块有:

·        res_musiconhold.c

·        res_calendar.c

o   提供一种日历技术接口

·        res_odbc.c

·        res_ael_share.c

·        res_crypto.c

·        res_curl.c

·        res_jabber.c

·        res_monitor.c

·        res_smdi.c

·        res_speech.c

o   提供一种语音识别引擎接口

3.4     ManagerInterface(AMI)Actions

Asterisk管理接口是一个socket接口,用于监视和控制Asterisk。

它是建立于主应用的核心功能。

继而,其它模块可以向AMI注册自己的action供客户端调用。

向AMI注册action的模块,通常提供了某种辅助功能以补充扩展某项主要的功能(这个功能不一定是内核功能,可能是模块自身的功能)。

比方说:

一个提供电话会议功能的模块,提供了一个管理action接口,用于返回与会者列表。

3.5     CLICommands

AsteriskCLI是主应用实现的命令行管理功能。

外围模块可以注册附加的CLI命令。

3.6     ChannelDrivers

Asterisk通道接口是最复杂、最重要的接口。

Asterisk通道API提供了电话协议的抽象,这样,所有Asterisk的其它特性,才能不依赖于具体的电话协议。

通道驱动实现的具体接口是ast_channel_tech所封装的接口。

一个通道驱动,必须实现执行各种呼叫信令任务的回调函数。

比如说,必须实现一个初始化呼叫的方法,实现一个挂断呼叫的方法,等等。

数据结构ast_channel是抽象通道数据结构。

每个ast_channel实例,有一个关联的ast_channel_tech以标识通道类型。

一个ast_channel实例,描述了呼叫中的一条腿(callleg的概念,也就是Asterisk与终端设备间的连接概念)。

源码中,通道驱动通常在channels/目录里。

当前实现的通道驱动列表,请参考:

Module:

AsteriskChannelDrivers。

需要进一步了解通道API,请参考头文件include/asterisk/channel.h。

内核中,关于ast_channel API的实现,则在main/channel.c中。

3.7     桥接技术

桥接,是把两个或多个通道连接在一起的操作。

通道,A到B的呼叫,用的是简单的双通道桥接,而在三方通话或会议中,用的就是多方桥接技术。

桥接API允许其它模块注册桥接技术。

桥接技术的实现,知道如何选择两个(或多个)通道,并将它们连接在一起。

具体是怎样发生的,取决于实现。

这些接口的代码,需要在两个(或多个)通道间交换音频,却又不需要知道交换的实现细节。

在底层,会议可能由操作系统内核实现(通过DAHDI);也可能由Asterisk的内部方法实现;如果有人实现了硬件扩展模块,还可能用硬件实现。

写这篇文档时,桥接API相对来说还比较新,所以执行桥接应用的操作,还没有全部使用这些API。

在拨号计划应用实现里,ConfBridge是在桥接API之上实现的一个会议应用。

桥接技术实现模块,存放在bridges/目录下。

桥接技术的实现列表,请参考:

bridges。

桥接API的更多信息,请参考头文件:

include/asterisk/bridging.h和include/asterisk/bridging_technology.h.。

内核关于桥接技术的实现细节,请参考:

main/bridging.c。

3.8     CDR处理器

Asterisk内核实现了保留通话记录的功能。

这些记录在呼叫处理过程中建立,并缓存在数据结构里。

在通话结束时,这些数据结构将被释放。

在记录丢弃之前,这些数据会传给已注册的CDR处理器。

而处理器则会把记录写入文件或存入DB。

通常,CDR模块的代码存放在cdr/目录下。

CDR处理器的实现列表,请参考:

Module:

CDRDrivers。

CDRAPI相关的更多信息,请参考头文件include/asterisk/cdr.h。

内核中,与CDR相关的实现,请参考main/cdr.c。

3.9     CEL处理器

Asterisk内核实现了一个通用的事件系统,这个系统允许Asterisk组件报告事件,订阅事件。

呼叫事件记录(CEL)就是建立在事件系统之上的一个应用。

CEL和CDR有点类似,它们都跟踪通话历史记录。

通常CDR记录和呼叫是一一对应的关系;而CEL事件和通话则是多对一的关系。

CEL模块和CDR模块看起来很相似。

通常CEL模块存放在cel/目录下。

CELAPI相关的更多信息,请参考头文件include/asterisk/cel.h。

内核关于CELAPI的实现细节,请参考main/cel.c。

3.10拨号计划应用(APP)

app实现Asterisk拨号方案中可以与呼叫交互的功能。

比如说:

在extensions.conf文件中:

exten=>123,1,NoOp()

在上例中,NoOp是一个APP。

当然,实际上NoOp什么事也没做。

这些app使用Asterisk提供的一系列API与通道进行交互。

App最重要的任务之一,是源源不断地从通道里读取音频,同时向通道回写音频。

完成这一任务的细节,通常隐藏在一个API调用的后面,比如说播放文件或等待用户按键输入。

除了与原先执行应用的通道交互之外,APP有时还能创建额外的通道。

比如说:

Dial()这个APP会创建一个外呼通道,并将它与入呼通道桥接在一块。

有关APP功能的进一步讨论,将在场景细节中展开。

源码中,APP的实现代码通常存放在apps/目录下。

APP的实现列表,请参考:

Module:

Dialplanapplications。

Asterisk内核注册APP相关的API定义信息,请参考头文件:

include/asterisk/pbx.h。

3.11   拨号计划功能(FUN)

顾名思义,FUN和APP相同,是提供给Asterisk拨号方案用的。

FUN在拨号方案中的使用方式,大部分和方案中的变量相同。

它们提供读/写接口,还有可选参数。

虽然它们行为上和变量类似,但比起简单的文本值,APP的存储和检索要复杂得多了。

比方说:

CHANNEL()这个FUN能让您访问当前通道上的数据。

exten=>123,1,NoOp(Thischannelhasthename:

${CHANNEL(name)})

通常,FUN的实现代码存放在funcs/目录下。

FUN的实现列表,请参考:

Module:

Dialplanfunctions。

Asterisk内核注册FUN相关的API定义信息,请参考头文件:

include/asterisk/pbx.h。

3.12RTP引擎

Asterisk内核提供处理RTP流的API。

但是,实际上处理这些流的是实现RTP引擎接口的模块。

RTP引擎的实现代码,存放在/res目录下,通常以res_rtp_为文件名前缀。

3.13   定时接口

Asterisk内核实现了定时API,供需要定时服务的组件调用。

比如说,在向主叫方播放语音文件时,插入一个定时器来限定播放时间长度。

这些API依赖定时接口的实现来提供稳定可靠的计时源。

通常,这些接口实现的代码可以在res/目录中找到。

定时接口实现列表,请参考:

timing_interfaces。

与定时API的定义信息,请参考头文件include/asterisk/timing.h。

内核的定时API实现代码,请参考main/timing.c。

4      Asterisk线程模型

Asterisk是一个多线程应用程序。

它用POSIX线程API来管理线程和相碰的服务,比如说锁。

Asterisk中,几乎所有与pthread交互相关的代码,都通过一套统一的封装实现,这样可以减少调试和代码量。

Asterisk里的线程,可以划分为以下几种类型“

·        通道线程(有时也称为PBX线程)

·        网络监视线程

·        服务连接线程

·        其它线程

4.1     通道线程

通道是Asterisk的一个基本概念。

通道不是inbound的,就是outbound的。

呼叫到达Asterisk系统时,创建一个inbound通道。

这些通道是Asterisk拨号方案的执行方。

每个执行拨号方案的通道,都建立一个线程。

这些线程称为通道线程。

因为这些线程的主要任务是为inbound呼叫执行Asterisk的拨号方案,所以有时也称它们为PBX线程。

一个通道线程开始只负责一个Asterisk通道。

然而,有时一个通道线程里也会有第二个通道的存在。

当inbound通道执行了诸如Dial()的APP之后,就在inbound线程里创建了一个outbound通道,并在对方应答之后将两个通道桥接在一起。

拨号方案的APP始终在一个通道线程的上下文里执行。

FUN也是如此。

虽然可以通过AMI或CLI之类的异步接口读写FUN,但无论如何,通道线程始终是ast_channel数据结构的执行主体。

4.2     网络监视线程

Asterisk中,几乎所有主要通道驱动都有网络监视线程。

这些线程负责监视网络连接(无论是IP网络还是PSTN等)、入呼和其它请求。

它们处理呼叫连接建立的前期步骤,如权鉴和拨号验证。

最后,当呼叫建立之后,监视线程创建一个Asterisk通道(ast_channel),并启动一个通道线程来处理余下的呼叫时间。

4.3     服务连接线程

有许多基于TCP的服务也使用线程。

比如SIP和AMI。

在这些场景下,用线程来处理每个TCP连接。

Asterisk的CLI也以同样的方式操作。

然而,它用的不是TCP,而是UNIXsocket连接。

4.4     其它线程

系统里,存在着各种执行某项待定任务的线程。

比如说:

事件API(include/asterisk/event.h)使用一个内部线程(main/event.c)来处理异步事件分发。

又如devicestateAPI(include/asterisk/devicestate.h)使用一个内部线程(main/devicestate.c)来处理异步的设备状态变化信息。

5      其它架构概念

本节涵盖了其它一些重要的Asterisk架构概念。

5.1     通道桥接

正如前面讨论通道技术接口时所提及的,桥接动作把一个或多个通道连接在一起,使它们之间能够彼此交换音频包。

然而,前面也提到,现在的Asterisk代码中,很多地方还没有使用新的桥接架构设计。

因为,本节讨论传统的桥接功能,它在Dial()和Queue()这些APP里还在使用。

当调用这些APP,决定把两个通道桥接在一起时,它执行ast_channel_bridge()API调用。

从这里开始,有可能出现两种不同的桥接:

1.   通用桥接GenericBridge:

通用桥接(ast_generic_bridge())是一种与具体使用的通道技术无关的桥接方法。

它通过Asterisk抽象的通道和帧接口交换音频数和信令,因此,它可以在任意两种通道驱动间通信。

虽然这是最灵活的桥接方式,但同时它也是最低效的方式,因此它需要抽象层参与。

2.   本地桥接NativeBridge:

通道驱动可以选择实现自己的桥接功能函数。

具体说来,这意味着要实现ast_channel_tech结构中的bridge回调函数。

如果被桥接双方的驱动类型相同,并且驱动程序实现了本地桥接方法,那么Asterisk没理由迫使呼叫驻留在内核处理,这时它会调用本地桥接函数。

这使得通道驱动能够利用类型相同的优势,优化桥接处理。

在使用DAHDI的场合中,这意味着通道在硬件层面直接桥接了。

在使用SIP时,这意味着Asterisk可以让音频流直接在终端间交互,而只要求信令流经过Asterisk。

6      代码流程实例

现在,我们已经讨论了Asterisk的各种组件,本节通过实例来说明这些组件是如何协同工作,向外提供强大的功能的。

6.1     SIP呼叫到Playback

这个例子假设通过SIP协议呼入Asterisk。

Asterisk接受这通呼叫,然后向呼叫方播放一个语音文件,最后挂机。

实例拨号规则:

exten=>5551212,1,Answer()

exten=>5551212,n,Playback(demo-congrats)

exten=>5551212,n,Hangup()

 

1.   呼叫建立:

从一个SIPIN

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 高考

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1