翻译-pjsip开发者指南(十二)对话邀请会话和用法

本文档介绍了PJSIP中的对话邀请会话(Dialog Invite Session)及其使用,包括其功能、状态管理、创建过程、消息处理、会话扩展等。对话邀请会话提供了会话进度报告、自动认证、SDP协商等高级功能,适用于电话应用。创建邀请会话时,应用需要先创建对话,然后根据传出或传入对话调用相应的创建函数。对话邀请会话处理多种SIP方法,如INVITE、BYE、ACK等,并通过回调通知会话状态变化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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。

 

 

 

 

 

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值