翻譯-pjsip開發者指南(十二)對話邀請會話和用法

Chapter 12:Dialog Invite Session and Usage

12.1 Introduction

對話邀請會話是高級別的邀請會話管理,應用可以使用它來管理邀請會話(包括SDP的管理)。邀請繪畫設計爲完全抽象的基礎對話,所以應用在使用邀請會話的API時不需要使用基本對話API。

應用可以爲每個對話創建一個對話邀請會話。對話邀請會話被對話invite usage管理,這是個PJSIP模型。對話invite usage將事件分發到相應的邀請會話,也能處理forked dialog。

對話邀請會話和實例在單獨的靜態庫中,如pjsip-ua庫。應用必須包含頭文件 <pjsip-ua/sip_inv.h>來使用對話邀請會話/實例的功能。或者,應用可以包含一個頭文件<pjsip-ua.h>來獲取pjsip-ua庫中的函數。

 12.1.1 Terms

對話邀請會話是一個對話中的邀請會話。如果應用要使用高級別的邀請會話管理,需要爲每個對話創建一個並且是唯一的對話邀請會話實例。

對話invite usage是一個PJSIP模型,註冊到PJSIP endpoint。當一個對話有對話邀請會話時,這個模型需要註冊到指定的對話以作爲一個對話實例。邀請會話創建的時候自動完成這些。

 12.1.2 Features

對話邀請會話爲應用提供以下功能:  

#會話的進度報告(如會話進度,連接,確認,斷開連接)

#自動認證處理(收到401/407後重試請求)

#SDP協商處理

#高級別forking處理

#會話超時(週期)

#會話擴展,比如會話計時器,可信任的臨時響應

 12.1.3 Invite Session State

對話invite usage提供回調來通知應用會話的進度。這個對電話應用很有用,會話的狀態通常和電話的通話狀態相關聯。

一個邀請會話的進度在下面的圖表的展示:

下面是每種狀態的描述

PJSIP_INV_STATE_NULL:會話首次創建時的狀態。這個時候沒有任何的發送和接收的消息。

PJSIP_INV_STATE_CALLING:第一次發送INVITE後的會話狀態,但是在收到臨時響應之前。

PJSIP_INV_STATE_INCOMING:第一次收到INVITE消息後的會話狀態,但是在發出任何臨時響應之前。

PJSIP_INV_STATE_EARLY:對話已經發送或接收來自INVITE請求的響應,有To tag時。

PJSIP_INV_STATE_CONNECTING:發送或接收到2xx的最終響應。

PJSIP_INV_STATE_CONFIRMED:收到或發送ACK請求後。

PJSIP_INV_STATE_DISCONNECTED:會話斷開連接,或者INVITE/BYE請求沒有收到成功的最終響應。

 12.1.4 Invite Session Creation

對於傳出的對話(如caller),應用需要調用pjsip_dlg_create_uac()來創建UAC對話。應用之後會調用 pjsip_inv_create_uac()創建邀請會話,將UAC對話實例作爲其中之一的參數傳遞。應用絕不能在邀請會話創建之前發送INVITE請求,否則邀請會話的一些事件會受影響。

對於傳入的對話,應用通過pjsip_inv_verify_request()調用來首先驗證這個請求是許可的。這個函數驗證Supported, Require和請求的消息體來確認接受這個請求。如果這個請求不被接受,將創建對應的拒絕響應。如果請求被接受,應用通過調用 pjsip_dlg_create_uas()來創建UAS對話。應用之後調用 pjsip_inv_create_uas()來爲這個對話創建邀請會話,UAS對話實例作爲其中的一個參數傳遞。邀請會話創建之前,應用絕不能發送任何響應,否則會影響邀請會話的事件。

當一個傳出對話forked,或者當一個邀請會話在源對話中存在,invite usage模塊將爲新(forked)對話自動創建邀請會話。應用通過回調函數通知新會話的創建。

邀請會話創建函數(即pjsip_inv_create_uac()和pjsip_inv_create_uas()函數)自動註冊邀請會話實例到對話中。應用不需要調用 pjsip_dlg_add_usage()來註冊invite usage模型到對話中。

 

 12.1.5 Messages Handling

邀請會話處理所有的可能改變會話狀態的SIP methods。這個版本的PJSIP,邀請會話處理INVITE, BYE,ACK, CANCEL, UPDATE, 和 PRACK 方法。

應用必須使用邀請會話API來創建和發送上述方法的請求和響應。因爲確保邀請和響應的消息已被正確處理是必要的,也包括對話正在使用的一些特性(比如可靠的臨時響應)。

應用也可以使用基本的對話API來創建和發送不止於以上方法的請求和響應消息。例如,應用可以使用基本的對話API在對話內創建和發送MESSAGE 請求。

 12.1.6 Extending the Dialog

如上所述,邀請會話處理對話中出現的INVITE, BYE, ACK, CANCEL,UPDATE和 PRACK 消息。當應用想要支持和處理其他類型的消息,必須自己註冊到對話上作爲一個對話實例。這個使應用能夠處理已存在對話實例不能夠處理的傳入請求。

應用設置正確的模型級別是很重要的。應用級別設爲 PJSIP_MOD_PRIORITY_APPLICATION。invite usage設爲 PJSIP_MOD_PRIORITY_APPLICATION-1。這樣保證invite usage能夠在應用之前檢測到傳入的請求。

 12.1.7 Extending the Invite Session

以後,邀請會話可能擴展支持更多的SIP擴展,比如呼叫轉移,對話目標鎖定等。目前應用應該能通過手動構造消息來體現這些功能。

 12.2 Reference

12.2.1 Data Structure

頭文件 <pjsip-ua/sip_inv.h>中聲明瞭邀請會話的函數。

 

 

   下面的代碼展示了可用於一個會話的多種選項。創建一個會話的時候要指定這些選項的位掩碼組合。對話創建後(包括early), pjsip_inv_session的成員options展示兩個endpoint中那些功能是通用的。

 12.2.2 Invite Usage Module

invite usage模型在任何會話創建之前都必須已經被初始化。

 

 pj_status_t pjsip_inv_usage_init( pjsip_endpoint *endpt,

pjsip_module *app_module,

const pjsip_inv_callback *callback);

初始化invite usage模型,並註冊到endpoint。callback參數包含邀請會話中發生事件的函數指針的回調。

 pjsip_module* pjsip_inv_usage_instance(void);

獲取invite usage模型的實例。

 12.2.3 Session Callback

pjsip_inv_callback結構體包含了可以由應用程序註冊以便invite usage模塊接收關於invite會話事件的通知的函數指針。

下面是回調函數。

 void on_state_changed( pjsip_inv_session *inv_ses,

pjsip_event *e);

會話狀態改變時調用。

應用可以檢測會話狀態(inv_sess->state)來得到當前的狀態。

這個回調時強制性的。

void on_new_session(pjsip_inv_session *inv_ses, pjsip_event *e);

當invite usage模型爲forked 傳出請求創建了一個新的對話和邀請時的回調。

 void on_tsx_state_changed( pjsip_inv_session *inv_ses,

pjsip_transaction *tsx,

pjsip_event *e );

會話中的任何事物改變了他們的狀態時的回調。應用可以執行這個回調,比如監測發出請求的進度。

這個回調是可選的。

void on_rx_offer( pjsip_inv_session *inv_ses,

const pjmedia_sdp_session *offer );

邀請會話從對端收到一個新的offer時的回調。應用調用pjsip_inv_set_sdp_answer()設置本地應答 。這個函數不會發送傳出消息。只是保留SDP協商進程的應答,並被包含在之後發送的請求或響應中。

這個回調時可選的。當沒有指定時,默認的行爲是用會話的初始能力協商遠端。

 void on_media_update( pjsip_inv_session *inv_ses, pj_status_t status );

SDP offer/answer會話已經完成後的回調。status參數表示offer/answer的狀態,由pjmedia_sdp_neg_negotiation()返回。

這個回調是可選的(從框架的角度),但是所有有用的應用通常都需要執行這個回調。

 12.2.4 Session Creation and Termination

 pj_status_t pjsip_inv_create_uac( pjsip_dialog *dlg,

const pjmedia_sdp_session *local_sdp,

unsigned options,

pjsip_inv_session **inv_sess);

dlg中的對話創建UAC邀請會話。如果應用已經確定了媒體能力,可以在local_sdp中指定SDP。否則爲NULL,讓遠端的UAS來指定一個offer。options參數是pjsip_inv_options枚舉中SIP特性的位掩碼組合。

成功返回時,邀請會話將放入inv_sess參數中,函數返回PJ_SUCCESS。否則將返回響應的錯誤狀態。

 pj_status_t pjsip_inv_verify_request(pjsip_rx_data *rdata,

unsigned *options,

const pjmedia_sdp_session *local_sdp,

pjsip_dialog *dlg,

pjsip_endpoint *endpt,

pjsip_tx_data **tdata);

在創建INVITE會話(甚至對話)之前,應用程序應該在收到rdata中的初始INVITE請求時調用此函數,來驗證邀請會話可以處理INVITE 請求。這個函數驗證本地endpoint能夠處理請求和媒體中所需的SIP擴展(如頭字段),如果請求中有媒體描述的話。

調用這個函數時,options參數必須包含希望應用到會話中的SIP擴展,在請求中已經有Supported,Require和Allow頭之後。

如果本地的媒體能力已經確定了,如果想要驗證INVITE請求中的協商媒體是否能夠處理,必須驗證local_sdp中的媒體能力。如果不指定,這個函數不會驗證媒體能力。

如果所有的都協商成功了,函數將返回PJ_SUCCESS。否則返回失敗原因。

這個函數能夠創建合適的響應消息當驗證失敗時。如果tdata指定了,將創建並返回一個非2xx的最終響應,當驗證失敗時。如果一個對話在調用函數前已經創建了,必須指定dlg參數。否則應用必須指定endpt參數(這是有用處的,比如應用想要發送有狀態的響應)。

 pj_status_t pjsip_inv_create_uas( pjsip_dialog *dlg,

pjsip_rx_data *rdata,

const pjmedia_sdp_session *local_sdp,

unsigned options,

pjsip_inv_session **inv_sess);

dlg中指定的的對話創建UAS邀請會話。應用必須在rdata中指定收到的INVITE請求。邀請會話需要檢查收到的請求來確認請求是否包含支持的特性。

應用必須在調用這個函數之前先調用認證函數,來確保成功創建會話。

如果應用已經確定了媒體能力,它可以在local_sdp中指定這個能力。如果在初始的INVITE中收到了SDP,UAS的local_sdp中指定的能力和收到的offer中的不一致;SDP的協商者能夠重新在響應中加上offer匹配的媒體能力。

options參數是pjsip_inv_options枚舉中的SIP特性的位掩碼組合。

成功返回時,邀請會話放入inv_sess 參數中並且函數返回PJ_SUCCESS。否則失敗的相應錯誤。

 pj_status_t pjsip_inv_terminate( pjsip_inv_session *inv,

int st_code,

pj_bool_t notify );

提前終止邀請會話並且銷燬對話(如果對話沒有其他實例)。這個函數只在初始化INVITE會話失敗的時候調用。一般的情形下,應用必須調用 pjsip_inv_end_session()來終止INVITE會話。

st_code參數指定了SIP狀態碼作爲連接斷開的原因。如果notify是true,應用回調被調用。

 

 12.2.5 Session Operations

pj_status_t pjsip_inv_invite( pjsip_inv_session *inv,

pjsip_tx_data **tdata );

 

爲會話創建初始請求。這個函數只能被UAC會話調用。這個初始INVITE請求將放入到tdata中如果成功創建。

如果會話創建的時候本地媒體能力指定了,這個函數會把SDP放到發出的INVITE中。否則發送的請求就不包含SDP體。

 pj_status_t pjsip_inv_answer( pjsip_inv_session *inv,

int st_code,

const pj_str_t *st_text,

const pjmedia_sdp_session *local_sdp,

pjsip_tx_data **tdata );

爲初始INVITE請求創建響應消息。st_code包含了被髮送的狀態碼,可能是臨時或最終響應。如果需要自定義狀態文本,可以指定st_text;否則這個參數就是NULL,使用默認的狀態文本。

如果應用已經在創建UAS邀請會話期間指定了媒體能力,local_sdp必須是NULL。這是因爲在單獨的INVITE事務中應用不能有超過一個的SDP answer/offer會話。

如果在此期間沒有指定,可能或必須指定local_sdp參數,這個取決於st_code是否表示2xx最終響應。

 pj_status_t pjsip_inv_end_session( pjsip_inv_session *inv,

int st_code,

const pj_str_t *st_text,

pjsip_tx_data **tdata );

創建一個SIP消息來啓動邀請會話的終止。取決於會話的狀態,這個函數可能返回CANCEL請求,一個非2xx最終響應,或者一個BYE請求。如果會話沒有應答收到的INVITE,這個函數創建一個非2xx最終響應,指定st_code和可選的st_text

 pj_status_t pjsip_inv_reinvite( pjsip_inv_session *inv,

const pj_str_t *new_contact,

const pjmedia_sdp_session *new_offer,

pjsip_tx_data **tdata );

創建重邀請會話。如果應用想要去更新本地contact並通知peer用新contact更新target,可以指定new_contact參數爲新的contact;否則這個參數是NULL。

如果沒有綁定的應答要發送或接收,應用可以啓動一個新的SDP offer/answer在請求中。應用可以通過邀請會話的SDP協商狀態來檢查這種情形。如果新的offer要發送到遠端,offer必須放入new_offer,否則爲NULL。

 pj_status_t pjsip_inv_update ( pjsip_inv_session *inv,

const pj_str_t *new_contact,

const pjmedia_sdp_session *new_offer,

pjsip_tx_data **tdata );

創建一個UPDATE請求。如果應用想要去更新本地contact並通知peer用新contact更新target,可以指定new_contact參數爲新的contact;否則這個參數是NULL。如果沒有綁定的應答要發送或接收,應用可以啓動一個新的SDP offer/answer在請求中。應用可以通過邀請會話的SDP協商狀態來檢查這種情形。如果新的offer要發送到遠端,offer必須放入new_offer,否則爲NULL。(和上面的函數描述一樣?)

 pj_status_t pjsip_inv_send_msg( pjsip_inv_session *inv,

pjsip_tx_data *tdata,

void *token );

tdata中發送請求或響應消息。token一個任意的應用程序數據,它將放在事務的mod_data數組中,位於應用模塊的索引處。

 12.2.6 Auxiliary API

pjsip_inv_session* pjsip_dlg_get_inv_session( pjsip_dialog *dlg );

獲取與dlg相關聯的邀請會話實例,或NULL。

 pjsip_inv_session* pjsip_tsx_get_inv_session( pjsip_transaction *tsx );

獲取與tsx事務相關聯的邀請會話實例,或NULL。

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章