tsip_stack_handle_t 实例
1. tsip_stack_handle_t的创建
在底层,真正运转的协议栈结构式tsip_stack_handle_t的一个实例,它的创建时机为SipStack类在构造时,也就是说,当上层不管用何种方式触发一个SipStack的创建动作时。在上层,SipStack会被继续抽象封装,这种封装有可能是封装成为一个java类,一个C#类,但是都不重要,重要的是,这些高层代码类必然关联了一个粘合层的SipStack实例。当粘合层(SipStack.cxx)中得SipStack被创建时,其构造函数会被调用。在它的构造函数类,会调用底层函数tsip_stack_create(…) 创建协议栈结构实例。
2. tsip_stack_handle_t 创建过程
A. 记录通过可变参数传入的一系列变量到stack(tsip_stack_handle_t实例)中。包括服务器地址(假设为:192.168.1.101),本机用户名(假设为:1002),sip-uri(sip:1002@192.168.1.101)。这些都将以字符窜形式记录到对应的stack字段中。
需要注意的是:由于传入的字符串可能是托管资源,因此,这里我们没有必要去显式释放它们。释放他们应该是高层代码的责任(有可能通过托管释放,也有可能需要手动释放)。设置为tsip_stack_set(tsip_stack_handle_t * stack,…)这是一个通过可变参数进行结构类实例设置的函数,设置时通过type-value的形势传递参数,也就是在一系列的可变参数中,其中一对可能是(type: tsip_pname_realm, value:”192.168.1.101”),在该函数内,对于字符串有一个拷贝动作。也就是说,记录的是stack自己管理的内存区。
B. 记录粘合层SipStack提供的回调函数到stack->callback字段,以提供sipevent到来时的回调。在上一节中,可以看到SipStack类提供的回调函数为:
Int stack_callback(tsip_event_t *);
C. 创建一个基于stack的全局timer管理结构,用来处理该协议栈中各种需要定时器功能的模块,在后面我们可以看到,对于一个dialog的四种事物:tsip_trsaction_ict,
tsip_trsaction_ist, tsip_trsaction_nict, tsip_trsaction_nist,都需要有定时重传的机制,这里仅仅是创建了这个定时管理结构,还没有启动该定时线程,定时线程稍后会在start stack 的时候启动,定时线程拥有两个队列:收集队列和分发队列。
D. 创建一个sessions的队列,用来管理基于该stack的各种session。
E. 最后创建三个层,可以说,sip协议是层次分明的,上层提供给下一层的回调,下一层将sip消息处理后传递给上一层处理,这是典型的网络处理方式。
三个层次为:
struct tsip_dialog_layer_s *layer_dialog;
struct tsip_transac_layer_s *layer_transac;
struct tsip_transport_layer_s *layer_transport;
分别是对话层,事物层和传输层,具体关系以后分析。
3. 对于tsip_stack_t(tsip_stack_handle_t 是其别名) 结构而言,定义也是明晰的。
/* 3GPP IMS/LTE stack (forinternal use). only tsip_stack_handle_t should be visible. */
typedef struct tsip_stack_s
{
TSK_DECLARE_RUNNABLE;//用于标志该结构是一个可以运行run()线程的结构
tsk_bool_t timer_mgr_started; //全局定时器启动标志
tsk_bool_t started; //协议栈启动标志
tsip_stack_callback_f callback;//记录粘合层的回调函数
tsip_uris_L_t* paths;
tsip_uris_L_t* service_routes;
tsip_uris_L_t* associated_uris;
/* DNS context */
tnet_dns_ctx_t *dns_ctx;
/* DHCP context */
/* QoS */
/* Internals. */
//tsk_timer_manager_handle_t* timer_mgr;
tsip_timers_t timers;
tsip_ssessions_L_t *ssessions; //会话队列
tsk_params_L_t *headers; //记录的各种键值对
const void* userdata; //上层用户私有数据,一般记录粘合层SipStack实例地址
/* Layers */
}
tsip_stack_t;