exosip2协议栈原理分析以与总结.docx

上传人:b****2 文档编号:2768448 上传时间:2023-05-04 格式:DOCX 页数:16 大小:672.16KB
下载 相关 举报
exosip2协议栈原理分析以与总结.docx_第1页
第1页 / 共16页
exosip2协议栈原理分析以与总结.docx_第2页
第2页 / 共16页
exosip2协议栈原理分析以与总结.docx_第3页
第3页 / 共16页
exosip2协议栈原理分析以与总结.docx_第4页
第4页 / 共16页
exosip2协议栈原理分析以与总结.docx_第5页
第5页 / 共16页
exosip2协议栈原理分析以与总结.docx_第6页
第6页 / 共16页
exosip2协议栈原理分析以与总结.docx_第7页
第7页 / 共16页
exosip2协议栈原理分析以与总结.docx_第8页
第8页 / 共16页
exosip2协议栈原理分析以与总结.docx_第9页
第9页 / 共16页
exosip2协议栈原理分析以与总结.docx_第10页
第10页 / 共16页
exosip2协议栈原理分析以与总结.docx_第11页
第11页 / 共16页
exosip2协议栈原理分析以与总结.docx_第12页
第12页 / 共16页
exosip2协议栈原理分析以与总结.docx_第13页
第13页 / 共16页
exosip2协议栈原理分析以与总结.docx_第14页
第14页 / 共16页
exosip2协议栈原理分析以与总结.docx_第15页
第15页 / 共16页
exosip2协议栈原理分析以与总结.docx_第16页
第16页 / 共16页
亲,该文档总共16页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

exosip2协议栈原理分析以与总结.docx

《exosip2协议栈原理分析以与总结.docx》由会员分享,可在线阅读,更多相关《exosip2协议栈原理分析以与总结.docx(16页珍藏版)》请在冰点文库上搜索。

exosip2协议栈原理分析以与总结.docx

exosip2协议栈原理分析以与总结

exosip2协议栈学习总结

1、exosip2协议栈介绍

eXosip是Osip2的一个扩展协议集,它部分封装了Osip2协议栈,使得它更容易被使用。

使用sip协议建立多媒体会话是一个复杂的过程,exosip库开发的目的在于隐藏这种复杂性。

正如它的名称所表示的,eXosip2-theeXtendedosipLibrary,它扩展了osip库,实现了一个简单的高层API。

通过使用exosip,我们可以避免直接使用osip带来的困难。

需要注意,exosip并不是对osip的简单封装包裹,而是扩展。

Osip专注于sip消息的解析,事务状态机的实现,而exosip则基于osip实现了call、options、register、publish等更倾向于功能性的接口。

当然,这些实现都是依赖于底层osip库已有的功能的。

2、exosip的模块构成

2.1底层连接管理

extl.c、extl_udp.c、extl_tcp.c、extl_dtls.c、extl_tls.c是与网络连接有关的文件。

实现了连接的建立,数据的接收以及发送等相关的接口。

其中,extl_udp.c为使用UDP连接的实现,extl_tcp.c为使用TCP连接的实现。

Extl_dtls.c以及extl_tls.c都是使用安全socket连接的实现。

2.2部功能模块实现

Jauth.c、jcall.c、jdialog.c、jevents.c、jnotify.c、jpublish.c、jreg.c、jrequest.c、jresponse.c、jsubscribe.c等文件实现了部对一些模块的管理,这些模块正如其文件名所表示的,jauth.c

主要是认证,jcall.c则是通话等等。

2.3上层API封装实现

Excall_api.c、exinsubsription_api.c、exmessag_api.c、exoptions_api.c、expublish_api.c、exrefer_api.c、exregister_api.c、exsubsribtion_api.c这几个以api为后缀的文件,实现各个子模块的管理。

应用程序可以调用这里提供的接口,方便的构造或者发送sip消息。

2.4其他

Inet_ntop.c实现ip地址的点分十进制与十六进制表示之间的转换。

Jcallback.c实现一堆回调函数,这些回调函数就是用来注册到osip库的。

我们使用exosip

库,就是避免直接使用osip库,因为一些工作exosip已经帮我们做了,所以这样一来,可

以简化上层的实现。

Udp.c文件主要用来对通过UDP连接接收到的消息进行分类处理。

Exutilis.c文件实现一些杂项的函数。

有ip地址到字符串之间的转换,域名的解析等一些

辅助的功能函数。

Exconf.c文件实现了exosip的初始化相关的接口,包括后台任务的实现。

实际上是

“configurationapi”的实现。

Exosip.c文件实现了与exconf.c文件相似的功能。

比如管道的使用,exosip上事务的创建和查找,register和subscribe的更新,认证信息的处理等。

3、exosip关键数据结构及其说明

3.1eXtl_protocol

eXtl_protocol是为实现网络通信专门定义的一个数据结构,包括了变量和方法两部分。

其中,变量包括了建立网络连接过程中使用的ip地址、端口等;方法部分封装了网络socket编程常用的系统调用接口。

代码中定义了四个该数据结构体的全局变量:

eXtl_udp、eXtl_tcp、eXtl_tls以及eXtl_dtls。

分别针对使用UDP、TCP以及安全加密连接进行了实现。

 

3.2eXosip_call_t

Exosip_call_t定义了call相关的信息,包括call的id,call的dialogs,call上incoming的事务和outgoing的事务。

另外,还包括了前向和后向指针,所以,所有的call可以通过该结构体串接起来。

 

3.3eXosip_dialog_t

exosip_dialog_t包含了dialog相关的信息。

 

3.4eXosip_reg_t

用来管理Register模块

3.5eXosip_subscribe_t

用来管理subscribe模块

3.6eXosip_pub_t

用来管理publish模块

3.7eXosip_notify_t

用来管理notify模块

3.8jinfo_t

这个结构体关联了dialog、call、subscribe以及notify几个结构体

3.9eXosip_event_t

 

与event有关的结构体。

这个结构体主要用来在应用层和exosip之间通信。

Exosip在处理事务的过程中,如果需要将结果反馈给上层应用,则会生成如上结构类型的事件,并将其放到exosip的事件队列中。

应用层会不断循环从事件队列中读取事件,然后进行应用层的处理。

 

3.10eXosip_t

 

exosip_t是exosip中最重要的结构体之一。

从图可以看出,这个结构体比较大,其中包含了exosip中用到的各个子模块的结构。

比如call、reg、pub等等。

代码中定义了一个该

结构类型的全局变量,通过该全局变量,就可以对exosip前的状态进行掌控(许多相关的信息要么包含在该结构上,要么可以通过该结构找到)。

Extl是eXtl_protocol类型的指针,保存了网络接口类。

J_osip保存了osip初始化时返回的osip结构体。

J_transactions一般是等待释放的事务。

在事务经过osip处理完后,不再需要时,exosip会将其放在j_transactions上,等待释放。

 

4、exosip的初始化

Exosip的初始化有两部分组成,这主要是从使用exosip的角度看。

4.1对exosip全局结构体变量的配置

这步通过调用接口eXosip_init完成。

主要完成工作如下:

4.1.1初始化条件变量和互斥信号量。

4.1.2调用osip_init初始化osip库,并将生成osip结构体给exosip,同时也让osip的

application_contexgt指针指向exosip,也就是二者相互指向。

4.1.3调用eXosip_set_callbacks设置osip的回调函数,所以回调函数都是exosip自己实现。

4.1.4调用jpipe创建通信用的pipe,之前已经说了,对于windows平台,是通过socket接口模拟实现的。

4.1.5初始化其上的事务和事件队列。

主要,这不同于osip的事务和事件队列。

4.1.6调用extl指向的结构体的init函数指针,初始化网络接口。

4.2在socket接口上进行监听

这步通过调用eXosip_listen_addr接口完成。

主要完成工作如下:

4.2.1将eXosip全局变量的eXtl指针指向eXtl_udp全局变量。

4.2.2根据参数,配置extl_protocol和exosip上有关ip端口地址等信息。

另外,调用extl_udp的tl_open函数指针,完成在本机指定的端口上监听连接的工作。

需要注意的是,虽然是监听,但是使用的UDP来建立连接的,所以消息的recv和发送在同一个socket上完成。

在osip中设置的out_socket并不会起作用。

4.2.3调用osip_thread_create创建exosip后台任务,用于驱动osip的状态机。

(在osip中,

在发送sip消息部分,提到将9个函数放到一个线程中执行,exosip就是这样做的)

下面展示了初始化的示例代码:

include

inti;

TRACE_INITIALIZE(6,stdout);

i=eXosip_init();

if(i!

=0)

return-1;

i=eXosip_listen_addr(IPPROTO_UDP,NULL,port,AF_INET,0);

if(i!

=0)

{

eXosip_quit();

fprintf(stderr,"couldnotinitializetransportlayer\n");

return-1;

}

...thenyouhavetosendmessagesandwaitforeXosipevents...

这样,在初始化完成后,我们基本上完成了对存中所用数据结构的配置,同时启动了

一个后台任务负责osip状态机的驱动。

5、数据收发整体框架

5.1接收过程

在初始化过程中我们创建了一个后台任务,现在可以看看这个后台任务都做了哪些操作。

任务的执行函数为_eXosip_thread,在该接口中,循环不断的调用eXosip_execute。

在每一次

的eXosip_execute执行中,完成如下的工作:

a.首先计算出底层osip离当前时间最近的超时时间。

也就是查看底层所有的超时事件,

找出其中的最小值,然后将其与当前时间做差,结果就是最小的超时间隔了。

这步是通

过调用接口osip_timers_gettimeout完成的。

主要检查osip全局结构体上的ict、ist、nict、

nist以及ixt上所有事务的事件的超时时间。

如果ict事务队列上没有事件,则说明没

有有效的数据交互存在,返回值为默认的一年,实际上就是让后面的接收接口死等。

果有事务队列上的事件的超时时间小于当前值,则说明已经超时了,需要马上处理,此

时将超时时间清为零,并返回。

b.调用eXosip_read_message接口从底层接收消息并处理。

如果返回-2,则任务退出。

c.执行osip的状态机。

具体为执行osip_timers_ict(ist|nict|nist)_execute和osip_ict

(ist|nict|nist)_execute这几个函数。

最后还检查释放已经终结的call、registrations以及

publications。

d.如果keep_alive设置了,则调用_eXosip_keep_alive检查发送keep_alive消息。

这样,当远端的终端代理发送sip消息过来时,会被之前创建的监听端口捕获(sip协议

默认的端口为5060)。

在调用eXosip_read_message接口时会将其接收上来。

接收上来的数据存放在buffer给接口_eXosip_handle_incoming_message来处理。

在其中首先调用osip_parse进行消息的解析,这是osip的核心功能之一。

数据解析后,会生成一个osip_event类型的事件。

接着调用osip_message_fix_last_via_header将接收到该消息的ip地址和端口根据需要设置到数据头的via域中。

这在消息返回时有可能发挥作用。

为了能够让消息正确的被处理,调用osip_find_transaction_and_add_event接口将其添加到osip的事务队列上。

处理在这之后发生了分叉,如果osip接纳了该事件,接口直接返回,因为这说明该事件在osip上已经有匹配的事务了,或者说该事件是某一个事务过程的一部分。

这样在后面执行状态机的接口时,该事件会被正确的处理。

如果osip没有拿走该事件,则说明针对该事件还没有事务与之对应。

此时,我们首先检查其类型,如果是request,则说明很可能是一个新的事件到来(这将触发服务端的状态机的建立),调用eXosip_process_newrequest接口进行处理。

如果是response,则调用接口eXosip_process_response_out_of_transaction处理。

在eXosip_process_newrequest接口中,如果是合法的事件,则会为其创建一个新的事务。

也就是说这是新事务的第一个事件。

经过一大堆的处理后,该事件可能就被osip消化了,

或者被exosip消化了。

如果需要上报给应用,由应用拿来对一些信息进行存储或者进行图

形显示之类,则会将该事件添加到exosip的事件队列上。

如下图所示:

应用程序在exosip初始化完之后需要调用如下类似的代码,不断从事件队列上读取事件,

并进行处理。

eXosip_event_t*je;

for(;;)

{

je=eXosip_event_wait(0,50);

eXosip_lock();

eXosip_automatic_action();

eXosip_unlock();

if(je==NULL)

break;

if(je->type==EXOSIP_CALL_NEW)

{

....

....

}

elseif(je->type==EXOSIP_CALL_ACK)

{

....

....

}

elseif(je->type==EXOSIP_CALL_ANSWERED)

{

....

....

}

else.....

....

....

eXosip_event_free(je);

}

读到事件后,判断其类型进行对应的处理。

这样整个接收流程就完成了。

5.2发送过程

要发送数据时,需要根据消息类型,调用exosip对应模块的api接口函数来完成。

如果

要发送的sip消息不属于当前已有的任何事务,则类似接收过程,调用osip的相关接口创建

一个新的事务,同时根据消息生成一个事件,加到事务的事件队列上。

最后,唤醒exosip

后台进程,使其驱动osip状态机,执行刚添加的事件,从而完成数据的状态处理和发送。

当然,也有一些消息并不通过osip状态机,而是由exosip直接调用回调函数cb_snd_message

完成发送。

 

6、exosip与上层应用以及osip之间的流程关系

exosip是对osip库的扩展,那么它与osip之间是什么样的关系呢,这可参看下图:

上图为接收过程的示意图。

Exosip后台任务不断从网络另一端读取sip消息,交给osip

的parser模块解析,并将其转换为events,添加到事务队列上。

同时,exosip后台任务在不断的驱动osip的状态机,这样,事务队列上的事件就会被处理。

如果需要响应对端,状态机会根据回调函数的设置,直接完成数据的发送。

同样,如果要将当前处理反馈给应用,则将其发送到事件队列上(这里是exosip的事件队列),并通过e-ctl管道通知应用进行处理。

应用需要发送数据时,流程如下图所示:

此时,应用调用exosip提供的辅助函数(上图中虚线示意此关系),构造osip事件,将

其添加到osip的事务队列上。

同时,应用通过s-ctl管道通知exosip后台任务执行状态机。

在exosip执行状态机的过程中,sip消息会被发送到网络另一端的终端。

7、linphone与exosip2的关系分析

7.1linphone功能模块说明

Liblinphone核心引擎实现了linphone所有的功能函数,而且能够方便的添加音频和视频的呼叫功能。

Liblinphone也提供高层的API,用来初始化,接收或者终止呼叫。

Liblinphone依赖于下面三个组件:

1Mediastreamer2

这是一个支持多种平台的轻量级的流技术引擎,主要适合于开发语音和视频应用程序。

该引擎主要为linphone的多媒体流的收发,包括语音和视频的捕获、编码解码以及渲染。

2ortp2

Ortp是一个RTP库。

为基于RTP协议的媒体流传输提供支持。

通过mediastream2编码的数据就是使用ortp库发送到网络的另一端。

3eXosip2

Exosip2为sip协议的实现。

这部分实际上是由exosip2和osip2两个库共同完成的。

使用sip协议完成路由、媒体协商以及会话的建立和管理,为直接的媒体流的传输提供基础。

通话双方在通信前使用exosip进行会话协商。

Exosip后台任务完成数据的接收和发送,并通过事件队列通知linphone底层的状态变化。

filter的构建在会话协商成功建立后就顺带完成了,并且ticker任务也跑起来了。

此时按照filtergraphics构建的通道,音视频流不断的从硬件设备上读取,并经过编码压缩送给RTP会话,之后送到对端,对端到达的音视频流也经过RTP会话接收送到解码解压缩filter,还原出原始的音视频流交给硬件设备播放。

媒体数据在这两路流中源源不断的流动,完成了双方的可视通话。

上层linphone的core任务也不断的对底层进行迭代检查。

所做的基本工作如下:

对于sip协议部分,core一直等待从事件队列上拿事件。

这些事件是exosip任务在处理sip消息过程中添加到事件队列上的。

每当得到新的事件后,core就从应用层的角度出发,进行处理。

对于视频流:

基本上只处理rtcp数据包到达的事件。

stream上也有一个事件队列,用于保存该流上的相关事件。

对于rtcp数据包事件,core也只处理sr类型rtcp包,即发送端报告,得到jitter和包丢失率。

如果设置了自适应比特率,则调用相关接口进行处理。

此过程不断进行,直到当前事件上的包处理完。

对于音频流,检查流是否还是活动的。

通过比较RTPstats中接收的数据包数目是否发生变化,如果在超时时间到达后,接收的数据量还没有发生变化,则认为音频没有响应。

7.2linphone中sal模块完成对exosip的封装

Sal模块其实应该是最重要的,最核心的模块了。

该模块对exosip进行了简单的封装,间接的对osip模块进行了封装,使用该模块的接口可以完成sip协议的处理以及媒体描述的处理。

Sal.c文件主要是对一些sal相关的结构体的操作,包括SalMediaDescription和sal_op。

处理包括创建这些结构体的实例,获取或者设置其中的一些操作域。

Sal_exosip2_sdp.c基于osip库提供的sdp相关操作的接口,在sal层实现将其与sal相关的结构体关联起来操作。

比如根据SalMediaDescription结构体信息将其转换为sdp结构体,或者反之。

Sal_exosip2_presence.c包括了对in和out的subscribe的操作。

Text数据的发送(基于osip和exosip)。

Sal_exosip2.csip这块比较重要的封装。

包含了对sal_op结构体的创建和基本操作。

对exosip重要结构体的封装,包括初始化和释放。

包含了对sal结构体的创建和基本操作的封装,更重要的是包含了对sal和sal_op,sal_media_desc,sal_stream_desc这些上层结构体与底层osip_message,

sip_message,sdp_message等数据结构之间数据的转换和共享,以及对底层相关接口的调用。

这种调用主要包括跟据上层结构体中包含的信息设置底层结构体,并调用底层接口完成具体功能,以及根据底层结构体得到的数据设置上层结构体的相关信息。

一个基本的描述就是:

sal作为signalabstractlayer包含了上层所主要理解的交互信息,这些信息对于理解操作而言已经足够了,在底层,选择了osip和exosip来支持这项操作。

所以实际上来说,可以用其他支持sip的库的接口来替代现有的,保留sal层接口的功能定义。

在linphone中,虽然大部分使用了sal层的封装来完成sip交互过程,但是也调用osip和exosip库本身的其他接口,所以这层封装主要还是再次简化协议层的处理,使得功能更具体,而不是更单一。

几个关键数据结构之间的关系:

Sal一个基本的结构体,通过这个结构体可以搜寻到上层所需的所有sip协议相关的信息。

具体的call,register等信息保存在sal_op这个结构体中,多个实体通过链表串接起来,挂在sal上。

Sal_op包含了sal_op_base结构体,这个结构体保存了一些通用的不变的信息,对多个实体而言,比如路由信息,本地媒体信息,远端媒体信息等。

其root指针由返回指向了sal这个基础,所以通过sal_op可以找到sal。

另外,在媒体信息中包含了所有流的信息,所有这些类似一个树的组织结构,sal类似树根,通过它可以找到所有的枝叶及其上的信息。

7.3linphone初始化过程中对sip协议栈的初始化

7.3.1调用sal_init进行sip协议栈的初始化。

该过程将返回一个sal结构体。

Exosip全局结构体的创建以及初始化。

需要注意,在这里相当于有三层封装调用:

一层为sal层的封装调用,一层为exosip层的封装调用,最底层为osip层的基本调用。

另外需要注意的是在这里没有创建exosip任务,而是在后面的读取并配置sip配置信息时才创建

exosip任务,并监听特定端口。

将lc->sal的up指针指回linphonecore全局结构体

设置sal上的回调函数,这些回调函数在对应的sip协议处理完后用于调用来处理外层有关call与media流的一些处理。

如果配置文件中没有设置sip会话的过期时间,则在这时将其设置为200将所有sipsetup配置串联到registered_sip_setups全局链表上

7.3.2读取配置文件中有关sip协议的相关信息,并以此来配置linphone的sip模块。

配置是否在发送数字时使用sipinfo信息。

配置是否在发送数字时使用rfc2833信息

配置是否使用ipv6

配置sip的传输端口信息。

指定是使用随机值还是知名5060端口

将端口信息设置到linphonecore中,并启动sip监听。

这样,当sip协议数据到达时即可被处理。

首先调用sal_listen_port启动监听端口。

在这里,协议层被选择和设置,一般情况下都是udp,这里为eXtl_udp。

之后创建并启动_eXosip_thread任务,该任务处理sip协议数据的接收,协议的处理,状态机的处理,数据的发送等。

即几乎所有与sip协议有关的处理都会在该任务中处理完。

最后保存用户代理信息。

获取配置文件中的联系人信息,如果联系人为空,或者配置文件中联系人信息不为空,但在将其设置为主联系人信息时出错(比如格式错误),则基于环境变量中的host和user信息创建主联系人,否则将配置文件中的联系人信息设置到sip_conf结构体的联系人上。

如果配置文件中设置了猜测主机名,则将该配置设置到linphonecore的sipconfigure结构体上配置incomingcall的超时时间

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

当前位置:首页 > 党团工作 > 入党转正申请

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2