注冊(cè)流程(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創(chuàng)建注冊(cè)請(qǐng)求, tsip_dialog_layer_new 創(chuàng)建注冊(cè)session,為后續(xù)進(jìn)入狀態(tài)機(jī)作準(zhǔn)備, tsip_dialog_fsm_act 進(jìn)入狀態(tài)機(jī)模式。 1._tsip_action_create 創(chuàng)建注冊(cè)請(qǐng)求,這里只是創(chuàng)建一個(gè)抽象的請(qǐng)求,請(qǐng)求對(duì)應(yīng)sip的方法,sip協(xié)議定義了 register,invite,publish,subscribe, bye,message等方法。 然后調(diào)用_tsip_action_set初始化上層(java)傳過來的參數(shù)。 2. 請(qǐng)求創(chuàng)建成功后創(chuàng)建會(huì)話層tsip_dialog_layer_new sip協(xié)議中每個(gè)請(qǐng)求方法對(duì)應(yīng)一個(gè)會(huì)話,即session,此函數(shù)根據(jù)會(huì)話類型創(chuàng)建相應(yīng)會(huì)話的session.對(duì)于注冊(cè)會(huì)話,回調(diào)用tsip_dialog_register_create創(chuàng)建會(huì)話層,然后把創(chuàng)建后的會(huì)話保存到協(xié)議棧的會(huì)話層鏈表。(1)tsip_dialog_register_create(tsip_dialog_register.c)創(chuàng)建注冊(cè)會(huì)話 內(nèi)部new一個(gè)注冊(cè)對(duì)象tsip_dialog_register_def_t,構(gòu)造函數(shù)中執(zhí)行如下動(dòng)作。 tsip_dialog_register_ctor內(nèi)部分三步: a.tsip_dialog_init 初始化基本的會(huì)話信息,這里分客戶端及服務(wù)器端。同時(shí)會(huì)創(chuàng)建此會(huì)話的狀態(tài)機(jī),并初始化狀態(tài)機(jī)的狀態(tài)。 b.tsk_fsm_set_callback_terminated 設(shè)置注冊(cè)會(huì)話結(jié)束狀態(tài)機(jī)回調(diào) c.tsip_dialog_register_init 初始化具體注冊(cè)會(huì)話信息. tsip_dialog_register_client_init初始化注冊(cè)請(qǐng)求的客戶端狀態(tài)機(jī)回調(diào)。 這里實(shí)際上是當(dāng)一個(gè)請(qǐng)求過程中,當(dāng)請(qǐng)求從一個(gè)狀態(tài)到另一個(gè)狀態(tài)時(shí)應(yīng)該調(diào)用的回調(diào)函數(shù)。 tsip_dialog_register_server_init功能相同。 tsip_dialog_register_event_callback設(shè)置從傳輸層過來的注冊(cè)事件的回調(diào),通知上層。
tsip_dialog_fsm_act,是所有sip會(huì)話開始進(jìn)入狀態(tài)機(jī)的入口。 參數(shù)為 會(huì)話,會(huì)話類型,sip消息,請(qǐng)求! 此函數(shù)內(nèi)部會(huì)調(diào)用狀態(tài)機(jī)通用函數(shù)tsk_fsm_act。執(zhí)行一個(gè)具體的請(qǐng)求,同時(shí)可能改變相應(yīng)會(huì)話的狀態(tài)機(jī)的狀態(tài)。 inttsk_fsm_act(tsk_fsm_t* self, tsk_fsm_action_id action, const void*cond_data1, const void* cond_data2, …)
內(nèi)部是一個(gè)循環(huán),不斷檢測(cè)狀態(tài),根據(jù)狀態(tài)調(diào)用相應(yīng)的回調(diào)。 每個(gè)狀態(tài)機(jī)都有一個(gè)初始狀態(tài)作為運(yùn)轉(zhuǎn)入口,對(duì)于注冊(cè)請(qǐng)求,入口為, 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一開始會(huì)執(zhí)行tsip_dialog_register_Started_2_InProgress_X_oRegister回調(diào), 此回調(diào)是由狀態(tài)_fsm_state_Started到_fsm_state_InProgress時(shí)執(zhí)行的操作, 內(nèi)部先更改自己的當(dāng)前狀態(tài)為_fsm_state_InProgress,這樣給tsk_fsm_act 提供了調(diào)用下一個(gè)狀態(tài)的入口。 函數(shù)內(nèi)部調(diào)用tsip_dialog_register_send_REGISTER 創(chuàng)建事務(wù)層,初始化事務(wù)層狀態(tài)機(jī),最后調(diào)用傳輸層socket接口把請(qǐng)求發(fā)送出去。 由于sip根據(jù)請(qǐng)求的類型把事務(wù)層分為幾種類型,包括客戶端請(qǐng)求(invite)事務(wù),客戶端非請(qǐng)求事務(wù)(如bye,register),服務(wù)器端請(qǐng)求事務(wù),服務(wù)器端非請(qǐng)求事務(wù)。
所以對(duì)于注冊(cè)請(qǐng)求,會(huì)創(chuàng)建非請(qǐng)求客戶端事務(wù)層。 tsip_dialog_register_send_REGISTER---> tsip_dialog_request_new --->tsip_dialog_request_send---->tsip_transac_layer_new--->tsip_transac_start --->tsip_transac_nict_start,進(jìn)入事務(wù)層狀態(tài)機(jī)模式。 這里,在創(chuàng)建事務(wù)層時(shí)會(huì)設(shè)置事務(wù)層事件回調(diào),tsip_transac_nict_event_callback。 比如發(fā)出register請(qǐng)求,服務(wù)器端給200ok響應(yīng)。此時(shí)傳輸層會(huì)把此響應(yīng)作為事件給事務(wù)層,事務(wù)層收到此時(shí)間并解析后進(jìn)入狀態(tài)機(jī)。 所以對(duì)于 一次 sip請(qǐng)求,有兩個(gè)狀態(tài)機(jī)在運(yùn)轉(zhuǎn),一個(gè)為會(huì)話層狀態(tài)機(jī),一個(gè)為事務(wù)層狀態(tài)機(jī)。
至此,一個(gè)register請(qǐng)求已經(jīng)發(fā)送出去,會(huì)話層,事務(wù)層狀態(tài)機(jī)都在運(yùn)轉(zhuǎn), 此時(shí),如果服務(wù)器返回注冊(cè)成功,則會(huì)給客戶端傳輸層發(fā)送200ok響應(yīng)。 tsip_transport_layer_dgram_cb,tsip_transport_layer_handle_incoming_msg, tsip_transac_layer_handle_incoming_msg,tsip_transac_layer_find_client 客戶端傳輸層收到響應(yīng)后會(huì)根據(jù)響應(yīng)的事務(wù)id查找是否為已經(jīng)創(chuàng)建的事務(wù)。 ,找到后會(huì)根據(jù)此事務(wù)創(chuàng)建時(shí)指定的回調(diào),調(diào)用響應(yīng)事務(wù)層的回調(diào)函數(shù),這里為tsip_transac_nict_event_callback,此函數(shù)內(nèi)部根據(jù)消息類型調(diào)用tsip_transac_fsm_act執(zhí)行事務(wù)層狀態(tài)機(jī),比如 200ok ,會(huì)調(diào)用事務(wù)層創(chuàng)建時(shí)指定的回調(diào)。這里為tsip_transac_nict_Trying_2_Completed_X_200_to_699。 內(nèi)部調(diào)用會(huì)話層回調(diào)通知上層注冊(cè)成功。tsip_dialog_register_event_callback 此函數(shù)根據(jù)狀態(tài)調(diào)用相應(yīng)會(huì)話層狀態(tài)機(jī),tsip_dialog_register_InProgress_2_Connected_X_2xx,修改狀態(tài)機(jī)當(dāng)前狀態(tài),為下一個(gè)狀態(tài)作準(zhǔn)備,最后調(diào)用TSIP_DIALOG_REGISTER_SIGNAL發(fā)射 注冊(cè)成功事件給上層用戶。 這里事件機(jī)制:TSIP_DIALOG_REGISTER_SIGNAL 通過tsip_register_event_signal創(chuàng)建一個(gè)注冊(cè)事件,然后把此事件放入?yún)f(xié)議棧啟動(dòng)時(shí)的事件隊(duì)列中, tsip_stack_start內(nèi)部啟動(dòng)run線程處理協(xié)議棧事件。 /* ===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線程中不斷掃描事件隊(duì)列,pop出一個(gè)事件,然后送給sip協(xié)議棧創(chuàng)建時(shí)指定的事件回調(diào),從而把協(xié)議棧事件(事務(wù)層事件,會(huì)話層事件,協(xié)議棧事件)返回給上層用戶。 至此,一次正常(沒考慮異常,401認(rèn)證過程等)的注冊(cè)流程分析完畢。 |