免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4702 | 回复: 0
打印 上一主题 下一主题

Doubango voip 框架分析之tinysip 协议栈 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-12-23 03:58 |只看该作者 |倒序浏览

Doubango voip 框架分析之tinysip 协议栈

 

1. tinysip 介绍 :

 

兼容性 : SIP (RFC 3261) 以及 3GPP IMS/LTE (TS 24.229) implementation

 

依赖 tinySAK, tinyNET, tinySDP, tinyMEDIA, tinyHTTP and tinyIPSec.

 

 

2. SIP 协议 - tinysip 的实现机制

 

SIP 是一个分层结构的协议,这意味着它的行为是根据一组平等独立的处理阶段来描述,每一阶段之间只是松耦合。协议分层描述是为了表达,从而允许功能的描述可在一个部分跨越几个元素。它不指定任何方式的实现。当我们说某元素包含某层,我们是指它顺从该层定义的规则集。

 不是协议规定的每个元素都包含各层。而且,由SIP 规定的元素是逻辑元素,不是物理元素。一个物理实现可以选择作为不同的逻辑元素,甚至可能在一个个事务的基础上。

 SIP 的最底层是语法和编码。它的编码使用增强Backus-Nayr 形式语法(BNF )来规定。

 第二层是传输层。它定义了网络上一个客户机如何发送请求和接收响应以及一个服务器如何接收请求和发送响应。所有的SIP 元素包含传输层。

 

第三层是事务层。事务是SIP 的基本元素。一个事务是由客户机事务发送给服务器事务的请求(使用传输层),以及对应该请求的从服务器事务发送回客户机的所有响应组成。事务层处理应用层重传,匹配响应到请求,以及应用层超时。任何用户代理客户机(UAC )完成的任务使用一组事务产生。用户代理包含一个事务层,有状态的代理也有。无状态的代理不包含事务层。事务层具有客户机组成部分(称为客户机事务)和服务器组成部分(称为服务器事务),每个代表有限的状态机,它被构造来处理特定的请求。

 事务层之上的层称为事务用户(TU )。每个SIP 实体,除了无状态代理,都是事务用户。当一个TU 希望发送请求,它生成一个客户机事务实例并且向它传递请求和IP 地址,端口,和用来发送请求的传输机制。一个TU 生成客户机事务也能够删除它。当客户机取消一个事务时,它请求服务器停止进一步的处理,将状态恢复到事务初始化之前,并且生成特定的错误响应到该事务。这由CANCEL 请求完成,它构成自己的事务,但涉及要取消的事务。

 SIP 通过EMAIL 形式的地址来标明用户地址。每一用户通过一等级化的URL 来标识,它通过诸如用户电话号码或主机名等元素来构造(例如:SIP:vision-com.com )。因为它与EMAIL 地址的相似性,SIP URLs 容易与用户的EMAIL 地址关联。

 SIP 提供它自己的可靠性机制从而独立于分组层,并且只需不可靠的数据包服务即可。SIP 可典型地用于UDPTCP 之上。

 

Register,Invite, Options …

 Nat Tranversal

 Dialog Layer

 Transaction Layer

 Parsing Layer

 Transport Layer

 sip 协议栈分层结构图

 根据sip 消息流向可以分为incoming message outgoing message, incoming 消息从 下到上,即Transport Layer → Register,Invite, Options; outgoing message 消息流向与此相反。

 

3 . 根据以上定义,tinysip 分如下模块:

 

1).api 外部接口,对sip 协议支持的方法的接口封装,协议栈提供的发起请求及接受请求对应的接口, 包括 registar layer, presence layer 等上层应用,当前版本支持如下请求:

 REGISTER SUBSCRIBE( 订阅),MESSAGE( 即时通信),PUBLISH (状态展示),OPTIONS (查询服务器能力),INVITE (发起请求),Cancel (取消一个请求),

BYE (结束通话)。

 2). Nat traversal Nat 穿越层,tinysip 目前支持stunturn 穿透。

 3).Dialog , 会话模块,一路呼叫的唯一标识, 处于sip 事务层之上。

4).parsers sip 消息解析,处于 sip 语法层,解析从传输层传递的数据包为协议栈理解的结构。

 5). transactions , 事务层,事务是一个请求以及与此请求相关的所有响应组成,用 transaction id 唯一标识,由于sip 信令一般由udp 承载,所以不能保证信息的可靠到达,所以事务层必须提供一种机制处理udp 所不能提供的功能,这里一般通过定时器及一个有限状态机来实现。

 6). transports , 传输层,即 udp , TCP, TLS, SCTP socket 系统调用系列,此层隐藏了所有传输层的细节,对于incoming sip message , 此层为sip 消息的入口, 对于outgoing sip message, 此层为sip 消息的出口。

 4. doubango sip 协议栈使用流程:

 

1. 初始化

 doubango sip 协议栈依赖于tinyNET 模块,所以必须先调用tnet_startup 函数初始化,退出时调用tnet_cleanup 清除资源,初始化sip

 协议栈之前必须设置用户的域(realm 参见(1) 及用户的私有(IMPI2 ))及共有标别(IMPU3 )), 这些为ims 引入的概念。

 (1) realm 解释:reaml 为域名,用来作客户端认证用(authenticate. 必须是一个有效的 sip uri 如:sip:vision-com.com.cn realm sip 协议栈启动之前必须设置的选项,一旦协议栈启动realm 就不可以更改,如果不填写sip 代理服务器地址,则系统会用realm 通过 dns NAPTR + SRV 或者DHCP ( 还没实现) 动态 查找机制确定sip 服务器地址。

 (2) 用户私有标识,为用户所属网络赋予的唯一值,用来做验证,为IMS 中的概念,如果用doubango sip 协议栈作为普通sip 功能,即非IMS 网络中的sip 功能,此处的impi 意义与sip 协议栈中的验证域名相同。

 (3 )用户公有标识,ims 网络中 一个impi 可以对应多个impu. 对比理解,比如我们的手机只能属于一个地方,而当我们到不同外地后会有漫游,此处的impi 即是我们手机本地给的唯一标识,而impu 是手机到外地后,当地网络给的一个标识。

 

2. 创建以及启动


通过调用 tsip_stack_create 创建协议栈, 调用tsip_stack_start 启动,

 完整例子:

 tsip_stack_handle_t *stack = tsk_null;

 int ret;

 const char* realm_uri = "sip:vision-com.com.cn";

 const char* impi_uri = "lideping@vision-com.com.cn";

 const char* impu_uri = "sip:bob@vision-com.com.cn";

  // ... 必须先初始化tnet 工具

 tnet_startup();

 // ...

 // 创建协议栈,指定回调函数,参数为域名,公有及私有标识。

 stack = tsip_stack_create(sip_callback, realm_uri, impi_uri, impu_uri,

 TSIP_STACK_SET_PASSWORD("yourpassword"),

 // ...other macros...

 // 此处初始化 其他信息,比如代理服务器地址,编码信息等。

 tsip_stack_start(stack) // 启动协议栈

 TSIP_STACK_SET_NULL()); // 用来终止传给app_callback 的参数。

 TSK_OBJECT_SAFE_FREE(stack);

tnet_cleanup();

 // 释放资源

 // 事件回调

 int sip_callback(const tsip_event_t *sipevent)

 {

 // 事件类型

 switch(sipevent->type){

 case tsip_event_register:

 { /* REGISTER */

 break;

 }

 case tsip_event_invite:

 { /* INVITE */

 break

 }

 case tsip_event_message:

 { /* MESSAGE */

 break

 }

 case tsip_event_publish:

 { /* PUBLISH */

 break

 }

case tsip_event_subscribe:

 { /* SUBSCRIBE */

 break

 }

 case tsip_event_options:

 { /* OPTIONS */

 break

 }

 case tsip_event_dialog:

 { /* Common to all dialogs */

 break

 }

 /* case …*/

 }

 

 3. 代码分析

 首先调用tsip_stack_create 创建协议栈 ,tsip_stack_create 内部首先检查参数是否合法,然后创建协议栈结构tsip_stack_t ,设置realm, IMPI and IMPU ,初始化一些协议栈默认值。创建 SigComp 信令压缩模块(可选) 创建dns 处理模宽,DHCP context ,接下来创建上面提到的sip 协议栈各层,分别调用tsip_dialog_layer_createtsip_transac_layer_create,tsip_transport_layer_create 创建会话层,事务层及传输层。至此,创建协议栈毕。

 在真正启动协议栈之前,即 tsip_stack_create tsip_stack_start 之间 可调用协议栈提供的api 初始化其他参数, 然后调用tsip_stack_start 启动协议栈,首先启动定时器线程,这里定时器主要在事务层提供状态机功调度功能。然后设置传输层类型,设置是否用ipsecsip 信令加密, 然后如果协议栈是处于客户端模式并且代理服务器地址没有设置则用认证的域名查找代理服务器的地址(用S NAPTR+SRV), 然后设置Runnable 回调,启动run 线程,run 内部不断从消息队列里取消息,这里的消息是从传输层从下到上传送过来,最终串联到消息队列,然后调用协议栈创建时指定的回调sip_callback ,所有incoming sip 消息以及媒体信息的改变最终都会走到此回调函数,此函数内部根据消息类型的不同调用相应的handler , 接下来启动nat 穿越模块,设置stun 地址。然后调用tsip_transport_layer_start 启动传输层线程,在sip 端口5060 接收数据,最后,设置stack->started = tsk_true; 至此协议栈启动完毕,各层在相应端口或状态机上监听,不断轮询到来的事件并处理。

 

驱动过程:

协议栈启动完毕后,对于每一个incoming outgoing 消息的 入口是不一样的,下面分别分析对于呼入请求(incoming) 及外乎请求(outgoing) 的代码流程。

 a. 呼入请求

 1 )客户端传输层在5060 端口上接收到udp 包,语法层解析成识别的sip 消息后传给事务层。

2 )事务层锁住本地事务链表,根据sip 消息的 事务id 在事务链查找是否存在匹配的事务,没有则创建。

3 )一旦找到事务或创建新事务完毕,释放锁并把消息传递到会话层。

 4 )会话层收到sip 消息后查找会话链,找不到则创建会话,同时根据消息类型(invite, ack 等)设置此消息的状态机,状态机内指定具体事件的回调。

 b. 呼出请求

 ........

  外部编程接口

 为了在android 上层通过java 访问doubango 核心,imsdroid doubango voip 框架做了面向对象封装,根据具体模块功能抽象成具体Java 类供应用层使用,应用层通过jni 访问doubango 核心,同时,在imsdroid 2.0 版本中,根据android 上应用层的架构抽象出一个类库,doubango-ngn-stack, 利用此类库我们可以在android 上自己开发一些客户端应用程序,包括语音,视频,即时通信,多媒体共享,会议等应用。Imsdroid 2.0 即是构建在 doubango-ngn-stack 上的一个具体应用。

 Doubango-ngn-stack 原理

doubango-ngn-stack 是对doubango voip 框架的一个java 层封装,内部通过java 本地调用技术实现(jni), 这与android 上的框架设计是相符的(java 类库提供的摄像头功能即依赖于底层驱动,上层通过jni 访问底层驱动)

 doubango/bindings/java

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP