本人承接 sip/ims 视频客户端定制开发,支持 语音,视频,即时通信功能,视频格式支持 h263,h264,mpeg4 软编软解,提供硬件编解码接口对接,提供服务器,有兴趣请联系我。
注册流程(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创建会话层,然后把创建后的会话保存到协议栈的会话层链表。(1)tsip_dialog_register_create(tsip_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设置从传输层过来的注册事件的回调,通知上层。
-
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_cb,tsip_transport_layer_handle_incoming_msg,
tsip_transac_layer_handle_incoming_msg,tsip_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认证过程等)的注册流程分析完毕。