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 -
Q/CT XXXX.1-2008
TIMEOUT_A、TIMEOUT_B和TIMEOUT_D。
在client端发送Invite而需要创建新的ICT的transaction时,TIMEOUT_B被启动,时长为64*DEFAULT_T1(DEFAULT_TI为500ms),TIMEOUT_B为整个transaction的生命周期时长,如果超过这个时间,transaction会被结束。如同传输层使用的是没有传输保证的UDP,则设置TIMEOUT_A,TIMEOUT_D的间隔时间为DEFAULT_T1和64* DEFAULT_T1。如果传输层使用的是面向连接的TCP及相关协议,则直接使用TCP内部的重传机制,不在SIP协议层提供传输的保护机制,所以不启动TIMEOUT_A和TIMEOUT_D。TIMEOUT_A管理Invite的传送,在Invite被发送时,启动定时器TIMEOUT_A,并且在超时时间内还没接收到response的时候,重发该Invite。TIMEOUT_D用于管理ACK,当接收到的response不是>=300时,client端发送ACK,当重复接收到该invite的response时,重发该ACK,确保server端在kill tranction前能接收到ACK。 3.2.2
IST的处理流程
同ICT的处理流程,处理osip中的osip_ist_transaction链表。IST的相关event的注册处理函数在ist_fsm.c文件和ist.c文件。
IST使用了定时器TIMEOUT_G、TIMEOUT_H和TIMEOUT_I。使用方式与ICTL类似,详细见协议栈说明。 3.2.3
NICT的处理流程
同ICT的处理流程,处理osip中的osip_nict_transaction链表。NICT的相关event的注册处理函数在nict_fsm.c文件和nict.c文件。
NICT使用了定时器TIMEOUT_E、TIMEOUT_F和TIMEOUT_K。 3.2.4
NIST的处理流程
同ICT的处理流程,处理osip中的osip_nist_transaction链表。NIST的相关event的注册处
中国IMS网络SIP协议规范总体技术要求 - 9 -
Q/CT XXXX.1-2008
理函数在nist_fsm.c文件和nist.c文件。
NIST使用了定时器TIMEOUT_J。 3.3 Osip报文的解析 3.3.1
sip协议报文的解析整理流程
当接收到一个message的时候,需要解析该message,生成一个代码能够处理的数据结构,该结构定义为struct osip_message,该结构定义的一个message的全部相关信息,这些信息主要是供transaction和dialog及dialog的更上一层如call,notify等的使用。
对一个message的解析流程如下图所示:
osip_message_parse_osip_message_parseosip_util_replace_all_lws__osip_message_startline_parsemsg_headers_parsemsg_osip_body_parse 在接收到一个message时,调用函数osip_message_parse进行message的解析。首先调用函数osip_util_replace_all_lws替换掉message中的连续出现的 ‘\\r\\n\\t’、‘\\r\\t’、‘\\n\\t’、‘\\r\\n ’、‘\\r ’、‘\\n ’为空格,message是以‘\\0’为结束标志的,message的headers和body之间的分界是以’\\r\\n\\r\\n’为标志的,替换只替换到’\\r\\n\\r\\n’为止,即只替换headers部分出现的\\t、\\r、\\n。由于sip协议栈规定,每个headers都是起新行,而且新行的头一个字符不为空格或\\t,所以两个header之间的\\r\\n不会被替换掉,替换的只是一个允许multi合并项的header的内部多个值之间的“\\r\\n\\t”或“\\r\\n ”。
中国IMS网络SIP协议规范总体技术要求 - 10 -