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

Q/CT XXXX.1-2008

void *j_thread; jpipe_t *j_socketctl; jpipe_t *j_socketctl_event; #endif

osip_fifo_t *j_events;

jauthinfo_t *authinfos;

int keep_alive; int learn_port; #ifndef MINISIZE int http_port; char http_proxy[256];

char http_outbound_proxy[256]; int dontsend_101; #endif

int use_rport;

char ipv4_for_gateway[256]; char ipv6_for_gateway[256]; #ifndef MINISIZE

char event_package[256]; #endif

struct eXosip_dns_cache dns_entries[MAX_EXOSIP_DNS_ENTRY];

struct eXosip_account_info account_entries[MAX_EXOSIP_ACCOUNT_INFO]; struct eXosip_http_auth http_auths[MAX_EXOSIP_HTTP_AUTH];

CbSipCallback cbsipCallback;

p_access_network_info *p_a_n_i; digest_cave_response *cav_v; };

在该结构中,最重要的几个成员变量如下:

1) int j_stop_ua; 协议栈启动和停止的控制参数,当j_stop_ua为0时,lib库启动,为非

0时,lib库停止。

2) eXosip_call_t *j_calls; j_calls用于管理全部的通话,所有的call在这个结构中形成一

个链表结构。Call结构如下:

struct eXosip_call_t {

int c_id;

eXosip_dialog_t *c_dialogs;

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

Q/CT XXXX.1-2008

osip_transaction_t *c_inc_tr; osip_transaction_t *c_out_tr;

int c_retry; /* avoid too many unsuccessfull retry */ void *external_reference;

eXosip_call_t *next; eXosip_call_t *parent; };

其中的c_id为分配的call_id,c_dialogs为同一个call中的dialog的集合。c_inc_tr和c_out_tr为创建该call时的初始化的transaction,一个终端对于一个call不是client端就是server端,所以c_inc_tr和c_out_tr只可能有一个是有transaction的,其中有一个为NULL。

3) eXosip_reg_t *j_reg; j_reg管理sip的注册服务,所有register相关的transaction在j_reg

中形成一个链表。根据sip协议,新的一次的注册必需等到前一次主次完成后才能进行,所以同一个register不会像call一样,同时有多个transaction存在。

4) struct eXtl_protocol *eXtl; 为使用的传输层的协议,在exosip的初始化中需要设置,

在传输层现在了4种不同的传输实现方式,它们的实现以一个结构的形式存在,在exosip_t初始化时注册到exosip全局变量的extl成员变量中。

5) osip_list_t j_transactions;用于管理全部的删除但是还没有系统回收的transaction。这

些transaction不属于call或register或者是call、register中删除的transaction。

6) osip_t *j_osip; 为osip lib库的管理结构,osip Lib的结构在一个任务中也只会有一个

变量存在,用于管理全部的sip协议栈中出现的transaction。根据上面的描述,同一个transaction同时被j_osip管理和call/reg管理,所以当一个transaction被删除时,需要从j_osip中先将该transaction从管理结构中删除,同时从call或者reg中删除,然后加入到j_transaction链表中。在j_osip初始化时,初始化了4条不同类型的transaction的管理链表,同时初始化了message header的解析函数的全局注册变量,在函数increase_ref_count中初始化。同时osip lib库为了实现重入,对被初始化的次数进行了计数。

7) 下面几个字段与协议的认证有关,在register时获取到认证信息,在call时需要将认

证信息添加到http_anth或proxy_anth中以便在进行call时能通过认证。

p_access_network_info *p_a_n_i; digest_cave_response *cav_v; jauthinfo_t *authinfos;

struct eXosip_dns_cache dns_entries[MAX_EXOSIP_DNS_ENTRY];

struct eXosip_account_info account_entries[MAX_EXOSIP_ACCOUNT_INFO];

struct eXosip_http_auth http_auths[MAX_EXOSIP_HTTP_AUTH];

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

Q/CT XXXX.1-2008

8) 在OSIP_MT内部的是为了支持多线程而需要的信号量、锁和线程间的通信方式的

pipe。其中pipe经过了封装,在类unix系统中直接采用pipe,在windows中采用socket通信来模拟pipe。

9) 在MINISIZE内部的为扩展版本,当需要publish,notify等功能时,可以启用。

初始化的流程如下,即初始化全局管理变量exosip的成员变量的值:

设置exosip中的几个常量 event_package, ipv4_for_gateway, ipv6_for_gateway, user_agent, 设置exosip为允许状态:exosip.j_stop_ua = 0初始化多线程使用到的信号量和信号及线程通信方式pipe初始化exosip中的osip,用于管理osip lib库初始化osip的callback注册函数初始化传输层的4种不同的传输方式

在初始化中,osip lib库中的发送message操作、接收message操作、transaction的kill操作、定时器超时操作等会影响到exosip中对transaction、dialog、call、register等的影响,这些操作由上次的exosip决定,所以在进行这些操作时会回调exosip注册在osip变量中的回调函数。在初始化exosip全局变量时会注册这些回调函数,在eXosip_set_callbacks函数中实现,这些注册函数的实现在jcallback.c文件中实现。

exosip lib库的销毁调用函数eXosip_quit,其操作与exosip_init的操作相反,其先置位

j_stop_ua为飞0,使处理线程停止处理sip协议上的rejister和call。然后释放所有申请的内存,释放exosip上保存的所有的call、register和里面使用到的dialog及transaction。 在exosip全局变量的初始化中,部分和业务相关的字段在exosip的外部进行初始化。如部分字段的初始化在函数eXosip_listen_addr,eXosip_masquerade_contact,eXosip_set_user_agent,eXosip_add_authentication_info中实现,参见sip_reg.c文件的winmain,该函数是register的启动测试函数,里面会初始化register使用到的几个值,Sip_reg.c是对lib库应用的一个简单实例。 4.2

Lib库的主处理线程

在exosip lib库初始化成功之后,如果启用多线程,则在新的线程中一直执行

exosip_execute,在主线程中执行eXosip_automatic_action;如果没有启用多线程,则在单线程中每次获取一个exosip lib库上报的事件,然后执行exosip_execute和

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

Q/CT XXXX.1-2008

eXosip_automatic_action。在主线程中每次都会去获取exosip Lib包上报的exEvent,在处理exEvent时会处理call中200应答的重发机制。 4.2.1

2xx应答的重发处理机制

在eXosip_retransmit_lost200ok中对2xx的应答进行重发控制,根据sip协议标准,因为2xx的重传是需要sip协议栈进行控制的,当第一次发送2xx应答后,在规定时间内没有接收到ACK应答,则重传2xx应答。其重传的时间间隔第一次为1s,以后每次翻倍,增长到4秒时每次都间隔为4s。

2xx的重发的停止发生在两种情况:一为2xx应答发送超时,在发送9次之后仍然没有接收到对端发送的ACK应答,则停止重发,说明call的通话出现的了通信错误,则结束该call;二为在发送2xx应答之后,接收到了对端的ACK应答,该ACK应答匹配了这个dialog,则只需要停止2xx的发送,同时释放dialog中保存的2xx消息,并置dialog中的2xx重复参数为停止。

4.2.2 Exosip_execute执行流程

exosip_execute的执行流程比较简单,因为在线程没有被teminate的情况下,线程会一直循环执行exosip_execute,所以在exosip_execute内部只需要顺序执行相关的操作即可。其执行流程如下:

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