doubango sip/ims 注册流程


注册流程(java-->C++-->C)

register(NgnSipService.java)

|

register(NgnRegistrationSession.java)

|

register_(sipsession.cxx)

|

tsip_action_REGISTER(stip_api_register.c)

tsip_action_REGISTER

分三步:

_tsip_action_create创建注册请求, tsip_dialog_layer_new 创建注册session,为后续进入状态机作准备, tsip_dialog_fsm_act 进入状态机模式。

1._tsip_action_create

创建注册请求,这里只是创建一个抽象的请求,请求对应sip的方法,sip协议定义了

register,invite,publish,subscribe, bye,message等方法。

然后调用_tsip_action_set初始化上层(java)传过来的参数。

2. 请求创建成功后创建会话层tsip_dialog_layer_new

sip协议中每个请求方法对应一个会话,session,此函数根据会话类型创建相应会话的session.对于注册会话,回调用tsip_dialog_register_create创建会话层,然后把创建后的会话保存到协议栈的会话层链表。(1tsip_dialog_register_createtsip_dialog_register.c)创建注册会话

内部new一个注册对象tsip_dialog_register_def_t,构造函数中执行如下动作。

tsip_dialog_register_ctor内部分三步:

a.tsip_dialog_init 初始化基本的会话信息,这里分客户端及服务器端。同时会创建此会话的状态机,并初始化状态机的状态。

b.tsk_fsm_set_callback_terminated 设置注册会话结束状态机回调

c.tsip_dialog_register_init 初始化具体注册会话信息.

tsip_dialog_register_client_init初始化注册请求的客户端状态机回调。

这里实际上是当一个请求过程中,当请求从一个状态到另一个状态时应该调用的回调函数。

tsip_dialog_register_server_init功能相同。

tsip_dialog_register_event_callback设置从传输层过来的注册事件的回调,通知上层。

  1. tsip_dialog_fsm_act,是所有sip会话开始进入状态机的入口。

    参数为 会话,会话类型,sip消息,请求。】

    此函数内部会调用状态机通用函数tsk_fsm_act。执行一个具体的请求,同时可能改变相应会话的状态机的状态。

    inttsk_fsm_act(tsk_fsm_t* self, tsk_fsm_action_id action, const void*cond_data1, const void* cond_data2, …)

内部是一个循环,不断检测状态,根据状态调用相应的回调。

每个状态机都有一个初始状态作为运转入口,对于注册请求,入口为,

TSK_FSM_ADD_ALWAYS(_fsm_state_Started,_fsm_action_oREGISTER, _fsm_state_InProgress,tsip_dialog_register_Started_2_InProgress_X_oRegister,"tsip_dialog_register_Started_2_InProgress_X_oRegister"),

    tsk_fsm_act一开始会执行tsip_dialog_register_Started_2_InProgress_X_oRegister回调,

    此回调是由状态_fsm_state_Started_fsm_state_InProgress时执行的操作,

    内部先更改自己的当前状态为_fsm_state_InProgress,这样给tsk_fsm_act 提供了调用下一个状态的入口。

    函数内部调用tsip_dialog_register_send_REGISTER 创建事务层,初始化事务层状态机,最后调用传输层socket接口把请求发送出去。

    由于sip根据请求的类型把事务层分为几种类型,包括客户端请求(invite)事务,客户端非请求事务(bye,register),服务器端请求事务,服务器端非请求事务。

所以对于注册请求,会创建非请求客户端事务层。

tsip_dialog_register_send_REGISTER---> tsip_dialog_request_new

--->tsip_dialog_request_send---->tsip_transac_layer_new--->tsip_transac_start

--->tsip_transac_nict_start,进入事务层状态机模式。

这里,在创建事务层时会设置事务层事件回调,tsip_transac_nict_event_callback

比如发出register请求,服务器端给200ok响应。此时传输层会把此响应作为事件给事务层,事务层收到此时间并解析后进入状态机。

所以对于 一次 sip请求,有两个状态机在运转,一个为会话层状态机,一个为事务层状态机。

至此,一个register请求已经发送出去,会话层,事务层状态机都在运转,

此时,如果服务器返回注册成功,则会给客户端传输层发送200ok响应。

tsip_transport_layer_dgram_cbtsip_transport_layer_handle_incoming_msg

tsip_transac_layer_handle_incoming_msgtsip_transac_layer_find_client

客户端传输层收到响应后会根据响应的事务id查找是否为已经创建的事务。

,找到后会根据此事务创建时指定的回调,调用响应事务层的回调函数,这里为tsip_transac_nict_event_callback,此函数内部根据消息类型调用tsip_transac_fsm_act执行事务层状态机,比如 200ok ,会调用事务层创建时指定的回调。这里为tsip_transac_nict_Trying_2_Completed_X_200_to_699

内部调用会话层回调通知上层注册成功。tsip_dialog_register_event_callback

此函数根据状态调用相应会话层状态机,tsip_dialog_register_InProgress_2_Connected_X_2xx,修改状态机当前状态,为下一个状态作准备,最后调用TSIP_DIALOG_REGISTER_SIGNAL发射 注册成功事件给上层用户。

这里事件机制:TSIP_DIALOG_REGISTER_SIGNAL 通过tsip_register_event_signal创建一个注册事件,然后把此事件放入协议栈启动时的事件队列中,

tsip_stack_start内部启动run线程处理协议栈事件。

/* ===Runnable === */

TSK_RUNNABLE(stack)->run= run;

if((ret= tsk_runnable_start(TSK_RUNNABLE(stack), tsip_event_def_t))){

stack_error_desc= "Failed to start timer manager";

TSK_DEBUG_ERROR("%s",stack_error_desc);

gotobail;

}

run线程中不断扫描事件队列,pop出一个事件,然后送给sip协议栈创建时指定的事件回调,从而把协议栈事件(事务层事件,会话层事件,协议栈事件)返回给上层用户。

至此,一次正常(没考虑异常,401认证过程等)的注册流程分析完毕。

你可能感兴趣的:(Go)