osip源代码框架详解 下载本文

Q/CT XXXX.1-2008

eXosip_read_messageosip_timers_ict_executeosip_timers_nict_executeosip_timers_ist_executeosip_timers_nist_executeosip_nist_executeosip_nict_executeosip_ist_executeosip_ict_executeeXosip_release_terminated_callseXosip_release_terminated_registrationseXosip_release_terminated_publications_eXosip_keep_alive

在每次执行eXosip_execute时,先会去读取message,所以运行线程一直在监听是否有消息发送到本客户端,对于要发送的message,都是管理程序主动调用接口进行发送的。在处理接收到的message时可能会创建新的call、新的transaction,生成新的transaction的event,还有exosip的event。其中exosip的event是上报给管理程序的,在管理程序中根据具体的实际情况进行处理。其能够参数的各种event的定义在文件exosip.h的枚举typedef enum eXosip_event_type中。

在读取完一个message并做了预处理之后(也可能没有新的message需要处理),

exosip_execute开始处理osip中4条transaction链表中的定时器,如果定时器超时,则产生新的定时器事件并放入transaction的事件队列中,然后开始执行4条transaction链表中的每个transaction的事件,其中包括对message部分的后半部处理。这两部分的代码分析在osip lib包分析部分已经有分析。

在处理完上面部分后,开始释放已经结束的call、registration和publication。其中在registration和publication的释放的时候,只是将其中的transation从registration和publication的结构中删除,然后放在exosip全局变量的j_transaction链表中。该链表中的transaction最终会在eXosip_release_terminated_calls中释放。

同时,如果传输层使用的是UDP协议,则需要调用_eXosip_keep_alive为registration发送报文保存UDP的通信,防止UDP超时该端口被系统关闭。

中国IMS网络SIP协议规范总体技术要求 - 25 -

Q/CT XXXX.1-2008

4.2.2.1 Exosip_read_message的处理

Exosip_read_message根据使用的传输层协议,调用传输层的tl_read_message函数从TCP/IP协议栈底层读取message。如果从传输层读取message成功,则交给

_eXosip_handle_incoming_message进行处理。在_eXosip_handle_incoming_message中,首先解析该message,如果解析成功,在解析完之后,检查message中的必要字段call_id number。如果管理程序在exosip中注册了message的消息处理函数,则回调注册该函数。然后根据message的类型,检查合法性并确定该message的产生的transaction的event的类型,因为是接收到message,所以类型全部为RCV_XXX类型,在发送message时,产生SND_XXX的event。因为是新接收到的message,有三种可能,一是能匹配已经存在的transaction,即是某个请求的应答或ACK;如果不能匹配,根据message中的状态码,如果是0,说明是一个请求,而且这个请求不能匹配已经存在的transaction,所以是一个新请求,对新请求的处理在函数eXosip_process_newrequest中;如果status不为0,则是一个response,因为response是对一个request的回应,而发送request的时候在本端肯定已经建立了新的transaction,如果逻辑处理正确,该response应该匹配到某一个存在的transaction,现在没有匹配到,说明该response是一个错误发送的response,对response的处理在函数

eXosip_process_response_out_of_transaction中。Exosip_read_message的处理流程如下:

中国IMS网络SIP协议规范总体技术要求 - 26 -

Q/CT XXXX.1-2008

eXosip_read_messageeXtl_udp.tl_read_messageeXtl_tcp.tl_read_messageeXtl_dtls.tl_read_messageeXtl_tls.tl_read_message_eXosip_handle_incoming_messageosip_message_initosip_message_parseeXosip.cbsipCallbackosip_message_fix_last_via_headerosip_find_transaction_and_add_eventFind transaction successNoMSG_IS_REQUESTYesNoeXosip_process_response_out_of_transactionYeseXosip_process_newrequest返回success

eXosip_process_newrequest的处理流程如下:

a) 根据message的类型,获取到ctx_type的类型,因为是接收端,所以本端为

server,如果message既不是INVITE,也不是ACK,同时不是其它REQUEST的情况,则直接释放这个message。

b) 如果是ACK,则肯定是对200的response的一个回应。不需要建立新的

transaction。

c) 如果是CANCEL,则直接转eXosip_process_cancel进行处理。

d) 查看该message是否属于某一个dialog,因为匹配dialog会比匹配transaction

的条件简答,多个transaction可以属于同一个dialog。如果匹配到某一个dialog,则检查该新的message的cseq_number和dialog中保存的cseq_number的大小,如果没有大于dialog中保存的remote cseq number,说明接收到的message是一个错误的request,则释放该message并返回。

中国IMS网络SIP协议规范总体技术要求 - 27 -

Q/CT XXXX.1-2008

e) 如果是INVITE并且没有定义最小化该协议栈操作的情况下,则先发送一个

100的临时应答。

f) 如果这个message匹配到某一个dialog

i.

并且不是ACK和BYE,则检查这个dialog是否已经结束,既该dialog已经发送或接收到过BYE请求,则根据sip协议标准发送一个481的错误提示应答。

如果不是ACK,因为已经通过协议的合法性检查,同时匹配到一个dialog,所以需要根据该message更新dialog的remote cseq。 如果message是INVITE

1. 检查这个dialog中最近的一个接收到的INVITE是否已经到结束状

态,如果没有,则根据sip协议标准将这个new INVITE删除,并发送一个500的提示错误应答。

2. 接着检查这个dialog中最近的一个发送出去的INVITE是否已经到结

束状态,如果没有,则根据sip协议标准将这个new INVITE删除,并发送一个491的提示错误应答。

3. 否则该INVITE是个合法的请求,则更新dialog的route set,因为该

INVITE并不是创建该dialog的第一个请求,所以调用eXosip_process_reinvite处理该INVITE请求。

如果message是BYE请求

1. 先检查该BYE请求的参数合法性,是否包含to tag,因为本端发送的

response里面肯定包含有to tag,所以对端发送的BYE应该是一个包含to tag的合法的message。

2. 检查dialog中是否已经接收到BYE,如果已经接收到BYE,说明对

方重发了BYE请求,直接回复500错误提示应答 3. 否则调用eXosip_process_bye处理BYE请求。 v. 如果是ACK,直接调用eXosip_process_ack处理该ACK请求 vi. 如果是其它请求,则调用eXosip_process_message_within_dialog处理该请

求。

g) 否则,没有匹到某一个dialog,说明是全新的一个请求 i. 如果是ACK,说明该200的ACK没有匹配到任何dialog,所以是一个错

误的ACK,直接释放message即可,因为是ACK,所以并没有建立transaction,不需要对transaction进行操作。 ii. 如果是INFO,直接回复481应答。 iv.

ii.

iii.

中国IMS网络SIP协议规范总体技术要求 - 28 -