天天看點

Pjsip信令逾時機制修改

  1. 逾時機制

Sip信令的逾時,主要指逾時重發機制。Sip信令互動可以使用TCP或者UDP,如果是TCP,不需要重發,可以保證信令的時效性。但是UPD本身的機制問題,存在丢包等的情況。而sip信令的丢失容易造成sip狀态的混亂。

Pjsip本身已經實作了信令的逾時重發機制,主要包括INVITE信令,普通的BYE,UPDATE等信令的重發。

UAC:呼叫發

UAS:被叫方

  1. 逾時修改

自組網是一個不穩定的網絡,丢包情況嚴重,延時也厲害。如果不修改逾時重發機制,會導緻在短時重複發送sip指令,導緻自組網帶寬占用和sip狀态的不穩定性。

根據目前自組網的性能,每個UDP網絡包,從發送到對方接收,在隻有1跳的情況下,普遍耗時2秒~3秒。是以sip信令重複發送時間太短,就沒什麼意義。

    1. 逾時時間定義

在sip_transaction.c的檔案中,有如下逾時定義:

static pj_time_val t1_timer_val = { PJSIP_T1_TIMEOUT/1000,

                                    PJSIP_T1_TIMEOUT%1000 };

static pj_time_val t2_timer_val = { PJSIP_T2_TIMEOUT/1000,

                                    PJSIP_T2_TIMEOUT%1000 };

static pj_time_val t4_timer_val = { PJSIP_T4_TIMEOUT/1000,

                                    PJSIP_T4_TIMEOUT%1000 };

static pj_time_val td_timer_val = { PJSIP_TD_TIMEOUT/1000,

                                    PJSIP_TD_TIMEOUT%1000 };

static pj_time_val timeout_timer_val = { (64*PJSIP_T1_TIMEOUT)/1000,

                                         (64*PJSIP_T1_TIMEOUT)%1000 };

T1,T2,T4,TD的定義在pjsip/include/pjsip/sip_config.h中。

#if !defined(PJSIP_T1_TIMEOUT)

#  define PJSIP_T1_TIMEOUT      3000 //set to 3 second by dengfei

#endif

#if !defined(PJSIP_T2_TIMEOUT)

#  define PJSIP_T2_TIMEOUT      4000

#endif

#if !defined(PJSIP_T4_TIMEOUT)

#  define PJSIP_T4_TIMEOUT      5000

#endif

#if !defined(PJSIP_TD_TIMEOUT)

#  define PJSIP_TD_TIMEOUT      60000 //set to 60 second by dengfei

    1. INVITE信令逾時修改

在撥打電話時,由呼叫方(UAC)發出INVITE信令給對方,并攜帶協商的SDP等資訊。

每條sip信令都存在一個生存周期。Pjsip的實作主要在sip_transaction.c中。

UAC:

INVITE信令的生存周期如下:

NULL ------Tx INVITE-----> Calling -----Rx 100 trying---> Processing ----Rx 180 Ringing---> Processing ---Rx 200 OK---> Terminated ---Tx ACK ----> Destroyed

其他信令的生存周期:

比如BYE

NULL---Tx Bye---> Calling ---Rx 200 OK---> Completed---time out--> Terminated ----time out---> Destroyed

UAS:

INVITE信令的生存周期如下:

NULL ------Rx INVITE-----> Trying -----Tx 100 trying---> Processing ----Tx 180 Ringing---> Processing ---Tx 200 OK---> Completed---Rx ACK ---->Terminated ---time out ----> Destroyed

其他信令的生存周期:

比如BYE

NULL---Rx Bye---> Trying ---Tx 200 OK---> Completed---time out--> Terminated ----time out---> Destroyed

根據UAC         的INVITE信令生存周期,在發送INVITE信令時,會先進入NULL狀态。

該狀态的處理函數為:tsx_on_state_null

目前自組網中, sip信令傳輸使用的是UDP協定,是以tsx->is_reliable的值為false。會設定重複發送的timeout時間,并計時。

設定計時的函數為:tsx_schedule_timer。重複發送的timer名稱為retransmit_timer。所有的sip信令逾時重複發送都是 用的這個timer。

未修改時,INVITE的time out時間,設定的是t1_timer_val。根據t1的定義。未修改前的時間為500ms。

在寬帶網絡情況下,500ms的時間完全可以完成信令的發送并接收到被叫方回複的100 trying信令。

當在自組網中,這個時間是無法達到了,是以每次都會重複發送。我們把INVITE的首次信令重複發送時間修改為:t4_timer_val,大概為5秒時間。在1跳的情況下,差不多可以接收到100 trying信令的接收。

當首次逾時時,在tsx_on_state_calling會收到逾時的消息,并進行處理。

第二次逾時:

原來的方案是:1 << (tsx->retransmit_count)) * pjsip_cfg()->tsx.t1

可以看出,根據重複發送的次數*2倍增時間,tsx.t1為原來的500ms,算下來,重複發送的時間為:0.5秒,1秒,2秒,4秒,8秒,16秒,32秒……

修改偶,t1設定成3秒,根據重複的次數相加,算下來時間為:5秒,3秒,6秒,9秒,12秒,15秒,18秒….

    1. 普通信令逾時時間

普通信令的逾時重複發送時間間隔為:

代碼:

if (tsx->role==PJSIP_ROLE_UAC && tsx->status_code >= 100)

        msec_time = pjsip_cfg()->tsx.t2;

用的是t2的時間。T2設定成4秒。

    1. INV生命周期time out修改

除了信令的生命周期,還存在一個INV的生命周期,主要用于未收到信令時,用于整個通話的挂斷。

這個time out使用的的timer為:timeout_timer。

使用的逾時時間:td_timer_val,td設定為1分鐘。

    1. 網絡異常時逾時挂斷修改

網絡異常或者對方掉網逾時挂斷,總時間主要有兩方面組成。

  1. sip_time.c檔案pjsip_timer_setting_default函數,設定PJSIP_SESS_TIMER_DEF_SE和ABS_MIN_SE,這兩個宏定義在sip_config.h中,可以修改逾時時間。這個時間是設定timer定時發送update信令,update發送時間間隔為:PJSIP_SESS_TIMER_DEF_SE的二分之一時間。
  2. update信令在發送後,如果收不到對方的回報,會有個60秒的信令逾時。
  3. 如果ABS_MIN_SE設定為30,PJSIP_SESS_TIMER_DEF_SE設定為60,則網絡異常時,大緻1分鐘時,會自動挂斷電話