翻译-pjsip开发者指南(二)模块

这章有些单词没翻译,感觉不翻译更好。

 Chapter 2:Module
 在pjsip的应用中Module framework是软件组件中分发消息的主要方法。所有的软件组件,包括传输层和会话层,都是作为模块实现。没有modules,核心堆栈将不知道如何去处理sip消息。
module基于一个简单但却功能强大的抽象接口。对于收到的消息,endpoint将消息 从最高级别的模块开始发送至所有模块,直到有一个模块能够处理这条消息。对于发出的消息,endpoint允许module按照自己的意愿在发送到网络之前来修改消息。

 2.1.1 Module Declaration
module的接口定义在 <pjsip/sip_module.h>

所有函数指针都是可选的,如果没有指定,视为返回成功。
 endpoint调用load, start, stop, and unload  这四个指针来控制module的状态。下面的图表展示了module状态的生命周期。

 on_rx_request() 和 on_rx_response() 函数指针是module从endpoint或者其他modules收取消息的主要手段。这些回调的返回值都很重要。如果回调返回非零(即true),则表示module已经处理了这个消息。在这种情形下,endpoint会停止分发消息到其他模块。2.1.3小节将会详细描述modules对收到消息的处理。
 transport manager 在消息传送后调用on_tx_request() 和 on_tx_response()这两个指针,允许一些类型的modules对消息(eg消息签名)做最后的更改。所有modules都必须返回PJ_SUCCESS(le 0),否则传输将被取消。2.1.4小节将对模块对发送消息处理进行详细描述。

 on_tsx_state()用来接收当传输状态改变时的通知,比如收消息,发消息,timer事务,传输错误事务。2.1.5小节详细描述回调函数的信息。

 2.1.2 Module Priorities
模块的优先级指明了处理回调优先调用module的顺序。有较高(数字越小)优先级的module最先调用 on_rx_request() 和 on_rx_response(),最后调用 on_tx_request() 和on_tx_response()。
下面是设置模块优先级的标准

note:优先级的数字越小,代表的优先级越高
 transport manager 使用PJSIP_MOD_PRIORITY_TRANSPORT_LAYER这个优先级。这个优先级目前仅用来控制消息传输,优先级比这个低(数字比较大)的module在传输层处理消息之前将会调用 on_tx_request()/on_tx_response(),而优先级比这个高的则会在传输层已经处理消息之后调用。2.1.4详细介绍module的消息处理。
 事务层使用PJSIP_MOD_PRIORITY_TSX_LAYER优先级。事务层接收所有属于该事务的消息。
 UA层(dialog framework)使用PJSIP_MOD_PRIORITY_UA_PROXY_LAYER优先级。UA层接收所有属于该对话集的消息。
 dialog usages使用PJSIP_MOD_PRIORITY_DIALOG_USAGE优先级。目前PJSIP实现了两类dialog usages:邀请会话和事务订阅会话(包括REFER订阅)。dialog usages 接收所有属于特定会话中的dialog的消息。
 PJSIP_MOD_PRIORITY_APPLICATION是一般应用程序去使用transactions,dialogs和dialog uasegs的一个特定( appropriate value)值。
 2.1.3 Incoming Message Processing by Modules
当有消息传入时,放入接收消息缓冲区( receive message buffer)( struct pjsip_rx_data, 5.1小节 “Receive Data Buffer”)。transport manager解析这个消息,然后把解析后的数据放入接收消息缓冲区中发送到endpoint。
 endpoint通过调用on_rx_request() 或 on_rx_response()来向每个注册过的module分发收到的消息缓存,按照优先级高到低,直到有module返回非零。当有一个module返回非零,意味着已经有module处理这条消息了,所以endpoint会停止向其他的module分发消息。
返回非零的回调module也可以向其他module分发消息。例如,事务层module,根据收到的消息,处理并发送至同样必须是module的transaction user。  transaction通过调用本模块的 on_rx_request() 和on_rx_response()发送消息至transaction user。通过在收消息的缓冲区设置transaction field,来区分消息是在事务里还是事务外。
下面的图表展示了modules是如何一层层调用其他module的。

 2.1.4 Outgoing Message Processing by Modules
发出的请求和响应放到 传输数据缓冲区(transmit data buffer-pjsip_tx_data),其中包含消息结构本身,内存池,连续缓冲区和传输信息。
当调用pjsip_transport_send()发送消息时,transport manager调用on_tx_request()或on_tx_response ()从最低优先级开始发往各个module。这些回调函数被调用的时候,消息可能被传输层处理了,也可能没有。传输层需要把这些信息放入传输缓冲区(transmit buffer):
    #传输信息
    #在连续的缓冲区内打印消息结构
优先级低于PJSIP_MOD_PRIORITY_TRANSPORT_LAYER的modules将会在获得这些信息之前收消息。也就是说没有计算目标地址,也没有打印连续缓冲区。
如果modules想要在打印进缓冲区前修改消息结构,设置的优先级就必须比传输层的优先级高。如果modules想要在传输到网络时看到真实的数据包字节(logging purpose),就必须设置优先级低于传输层。
   note: 设置优先级高于传输层的一个实例就是logging module,它想打印已经放入连续缓冲区并且计算过目的地址的发送消息。
这种情况下,module必须以PJ_SUCCESS作为回调的返回值。如果module返回其他错误码,传输会被取消,错误码会返给 pjsip_transport_send()的调用者。

 2.1.5 Transaction User and State Callback
module定义中一个特殊的回调(on_tsx_state)被用于接收事务状态改变时特定事务的通知。这个回调是唯一的因为传输的状态可能由非消息相关的事务改变(比如timer超时,传输错误)。
module在特定的事务中已经注册为transaction user后,才可以调用回调函数。每一个事务中只允许一个transaction user。transaction user可以在每个事务的基础上添加至事务中。
对于dialog中的事务创建,transaction user在特定的dialog中添加到UA层的module。当应用程序手动创建事务时,可以将自己设为transaction user。

 收到重传的请求或响应不会调用 on_tsx_state()。注意传输或收到临时响应不被视为是重传,也就是说会调用这个回调函数。

 2.1.6 Module Specific Data
一些PJSIP组件可以放置module的数据。方便的来说这种container叫 mod_data,是void类型的指针数组,以module ID作为索引。
例如,一个收到数据包的buffer (pjsip_rx_data) 有如下的module数据定义:

mod_data数组以module ID为索引。module ID在module向endpoint注册时确定。
当把收到的数据buffer(pjsip_rx_data)传递到modules时,module可以把数据(module specific data)以一个合适的索引放到mod_data里,之后这个值可以被module或者应用程序获取。例如,事务层在mod_data里放入匹配的事务实例,UA层放入匹配的会话实例。应用程序可以通过调用简单的数组查找函数pjsip_rdata_get_tsx()或pjsip_rdata_get_dlg ()来检索id。如下:
                                
 2.1.7 Callback Summary
下表总结了事务的发生以及特定回调的触发。on_tsx_state()仅有在程序选择处理有状态的请求时调用。

Event

on_rx_request() or
on_rx_response()

on_tsx_state()

Receipt of new requests or responses

收到请求或响应

Called

Called

Receipt retransmissions of requests or
responses.

收到请求或响应的重传

Called ONLY when
priority number is lower
than transaction layer

仅当优先级高于事务层时调用

Not Called

Transmission of new requests or responses.

传递新的请求或相应

Not Called

Called

Retransmissions of requests or responses.

请求或响应的重传

Not Called

Not Called

Transaction timeout

事务超时

Not Called

Called

Other transaction failure events (e.g. DNS
query failure, transport failure)

事务失败(DNS,查询失败,传输失败)

Not Called

Called

 2.1.8 Sample Callback Diagrams
收到的transaction和dialog外的消息

处理过程如下
1)transport manager(pjsip_tpmgr)向endpoint发送所有收到的消息(解析消息后)。
2)endpoint(pjsip_endpt)向已注册的回调分发消息。回调列表的第一个是事务层。事务层把消息放到事务表里,且没有相匹配的事务。
3)endpoint向回调列表的下一个即UA发送消息。
4)UA把消息放到哈希表中,且没有匹配的dialog set。
5)endpoint继续向下一个注册的回调发送消息直到应用程序。应用程序处理消息(有状态的响应,创建UAS事务,代理请求,创建dialog)。
收到事务中的消息

处理如下:
1)transport manager(pjsip_tpmgr)向endpoint发送所有的消息(解析消息后)。
2)endpoint(pjsip_endpt)向已注册的回调分发消息。回调列表的第一个是事务层。事务层把消息放到事务表里,且有匹配的事务。
3)因为事务回调返回pj_true,所以endpoint不会继续分发消息。
4)事务处理响应。如果消息是重发,停止处理。否则把消息发到transaction的transaction user(TU),可以是dialog或应用程序。
5)如果TU是一个dialog,dialog处理响应并发送至dialog user(DU,如应用程序)。
6)如果收到的消息已经改变了事务的状态,事务将会通知TU这个新状态。
7)如果TU是一个dialog,可能还会通知应用程序dialog状态的改变。

收到的消息在dialog里但不在事务里

处理如下:
1)transport manager(pjsip_tpmgr)向endpoint发送所有的消息(解析消息后)。
2)endpoint(pjsip_endpt)向已注册的回调分发消息。回调列表的第一个是事务层。事务层把消息放到事务表里,并且没有相匹配的事务。
3)endpoint向modules列表的下一个发送消息,直到UA module
4)UA把消息放到dialog的哈希表中,且有匹配的dialog。
5)UA把消息发送到相应的dialog。
6)dialog为收到的请求创建事务,然后通过调用dialog usages的on_rx_request()和on_tsx_state ()分发请求。

 2.2 Module Management
pjsip的endpoint管理modules。应用程序必须手动向endpoint注册每个module,以便于堆栈的识别。
 2.2.1 Module Management API
module管理的API在 <pjsip/sip_endpt.h>

 pj_status_t pjsip_endpt_register_module( pjsip_endpoint *endpt,pjsip_module *module );
向endpoint注册module。endpoint会调用load和start函数来初始化module,并分配给module一个module ID。

 pj_status_t pjsip_endpt_unregister_module( pjsip_endpoint *endpt,pjsip_module *module );
向endpoint解绑module。endpoint调用stop和unload函数来结束一个module。

 2.2.2 Module Capabilities
module可以向endpoint声明新的功能。目前endpoint管理如下的功能:
  #允许sip方法(允许的头字段)
  #支持的sip扩展(支持的头字段)
  #支持的content type(接受的头字段)
这些头字段将根据需要自动添加到发出的请求或响应中。
 module通过调用pjsip_endpt_add_capability()来声明新的功能。

 

 pj_status_t pjsip_endpt_add_capability( pjsip_endpoint *endpt,
                                        pjsip_module *mod,
                                        int htype,
                                        const pj_str_t *hname,
                                        unsigned count,
                                        const pj_str_t tags[]);
向endpoint注册新功能。htype参数指明向哪个头添加功能,比如 PJSIP_H_ACCEPT,PJSIP_H_ALLOW, and PJSIP_H_SUPPORTED。hname是可选项,用来指明核心堆栈无法识别的头字段功能。count和tags参数指明了加入头字段的tag字符串数组。

 

const pjsip_hdr* pjsip_endpt_get_capability( pjsip_endpoint *endpt,
                                             int htype,
                                             const pj_str_t *hname);
获取功能头字段,包含为特定字段注册到endpoint的所有功能。


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值