Q/CT XXXX.1-2008
transaction组合而成的dialog。
在message的处理方面,可以分为两类,一类为发送的message,因为是主动发送,所以上层管理层知道是什么类型的message,lib库直接提供各类接口供使用。一类为接收到的message,因为不知道是哪种类型,所以需要根据解析出来的message的信息来进行处理,这部分的处理在udp.c文件中。
整个lib库的初始化在exOsip中介绍。 3
Osip包的源代码框架解析
在osip源代码包中最主要的包括了message的相关操作,其中最重要的为message的解析,即从获取到的一个message中解析生成一个能够被代码直接处理的message数据结构-——osip_message_t。与message结构相关的操作包括根据message数据结构的信息安装sip协议规范组装成一个message字符串;message结构的初始化和释放;message结构的拷贝操作;以及从message结构中获取各种已经解析的成员变量的值和设置各个成员变量的值。在message的解析部分,除了message的头之外,还包括了body的解析,涉及到sdp协议,包括对每个sdp字段的解析。
在osip源代码包中,设计了一个与同一个请求相关的所有message的集合——transaction,在发送或接收到一个新的请求的时候就会生成一个transaction,其中ACK和CANCEL请求是比较特殊的,对于非2xx应答的ACK和初始INVITE请求是属于同一个transaction的,而对于2xx的请求是属于单独的transaction的,所以其重传操作由UAC来控制,而不在INVITE的transaction内部进行控制。CANCEL的请求除了本身建立一个transaction外,根据协议它还会去匹配要CANCEL掉的请求的transaction,如果匹配成功会CANCEL掉相应的transaction。
在osip包中同样设计了dialog相关操作,包括dialog的建立,dialog信息的保存,dialog的匹配及删除等操作。
其它方面,包括多线程中使用到的锁和信号量及信号,内部使用到的链表,用于事件的队列(需要先进先出策略),一些平台无关的封装,定时器以及常量等的定义。这部分比较简单,而且都是最底层函数,直接封装了系统调用层。 3.1 osip的transaction的event的产生
transaction的状态变化是由事件来驱动的,当transaction上有事件产生时,根据事件的类型和当前transaction的状态来处理该event。
Transaction上的事件分为两类:一为定时器事件,在设定的定时器超时时会产生相应的定时器事件;另一类为事件驱动事件,如发送一个请求、应答或接收到一个请求、应答,发送一个ACK和接收到一个ACK,即是由报文产生的事件。
中国IMS网络SIP协议规范总体技术要求 - 5 -
Q/CT XXXX.1-2008
3.1.1 定时器事件的产生过程
osip_timers_ict_execute (osip_t * osip)__osip_ict_need_timer_b_eventHave timer b?noyes__osip_ict_need_timer_a_eventHave timer a?yes添加event到transaction的transactionff队列no__osip_ict_need_timer_b_eventyesHave timer b?no退出ICT、IST、NICT和NIST的定时器的事件产生流程都一样,对于每一个transaction,其定时器是有顺序的,ICT流程中TIMEOUT_B的优先级最高,TIMEOUT_B定时器触发后,会触发kill transaction的操作。当transactionff队列中有未处理的事件时,不处理定时器,直接返回,所以在transactionff队列中总的事件的数量是不多的。
所有的定时器函数调用底层同一个定时器检查函数__osip_transaction_need_timer_x_event。该函数会先检查该定时器是否启动,判断条件为(timer->tv_sec == -1),如果启动,检查当前时间是否超过定时器中设定的时间,如果是,则产生新的定时器事件。
因为定时器没有一个单独的任务,所以是采样轮训的方式检查是否有新的定时器事件产生,而不是根据系统时钟中断进行检测,因此会比较占用系统资源。
定时器的启动和修改使用接口osip_gettimeofday和add_gettimeofday。只需要设定定时器的超时时间,即设定了一个新的定时器。取消一个定时器,只需要修改定时器的timer->tv_sev为-1。
中国IMS网络SIP协议规范总体技术要求 - 6 -
Q/CT XXXX.1-2008
3.1.2 报文触发的事件
_eXosip_transaction_initosip_new_outgoing_sipmessage (invite)osip_transaction_add_event(transaction, sipevent) 包括一个新的invite、response、ack的发送或接收,除了对非2xx的应答ack外,其他的请求和应答都会产生一个新的transaction,并且产生一个新的sipevent事件。
3.2 osip 的transaction的event处理流程
在sip协议栈中为了更快更好的处理transaction,根据协议栈的描述,划分为四种不同的transaction,分别为ICT、IST、NICT和NIST。四种不同的transaction会有不同的处理流程和状态转换表,以及使用到不同的定时器。
ICT、IST、NICT和NIST的状态转换采样注册函数处理方式,为便于管理和使用注册函数,源码中使用了四个全局变量管理四种不同类型transaction的转换表:ict_fsm、ist_fsm、nist_fsm和nist_fsm。
osip结构如下:
struct osip {
void *application_context;
/* list of transactions for ict, ist, nict, nist */ osip_list_t osip_ict_transactions; osip_list_t osip_ist_transactions; osip_list_t osip_nist_transactions; ?? }
/**< list of ict transactions */ /**< list of ist transactions */ /**< list of nist transactions */ /**< User defined Pointer */
osip_list_t osip_nict_transactions; /**< list of nict transactions */
整体简单处理流程如下图:
中国IMS网络SIP协议规范总体技术要求 - 7 -
Q/CT XXXX.1-2008
osip_ict_execute (osip_t * osip)osip_ist_execute (osip_t * osip)osip_nict_execute (osip_t * osip)osip_nict_execute (osip_t * osip)osip_transaction_executeKill event?Yosip_free (evt)Nofsm_callmethod
图 3-1:transaction的event处理流程
3.2.1
ICT的处理流程
如上图,ICT事件处理时:
1)
检查osip管理结构中的osip_ict_transactions链表,如果没有链表元素,直接返回OSIP_SUCCESS
2) 3)
获取链表中元素个数,并保存transaction到临时局部数组
遍历所有transaction,osip_fifo_tryget顺序获取每个transaction中的事件,调用osip_transaction_execute处理每个事件,直到所有transaction中的所有事件被处理完毕,然后返回。
Osip_transacton_execute执行时,根据传入的参数osip_transaction_t * transaction中的transactionde 类型获取到状态转移表的全局管理变量ict_fsm,并且根据event的type和transaction的状态调用fsm_callmethod——在文件fsm_misc.c,是状态转移注册函数的总入口——查询找到event的处理函数,并调用处理函数进行event的处理。
ICT的相关event的注册处理函数在ict_fsm.c文件和ict.c文件。ICT使用到了3个定时器:
中国IMS网络SIP协议规范总体技术要求 - 8 -