以1002 呼叫 1003 为例。
Sip的状态流程
1002向FS发起INVITE消息,经过一次认证通过,1002在此向FS发起INIVTE消息。此时FS所做的处理为:
1. 捕获该sip消息,在sofia中有一个对于ua Event消息事件的枚举定义:
typedef enum nua_event_e {
……….
nua_i_invite;//这个值表明回调sofia_event_callback时,是一个invite事件到来。
………
nua_i_state;//这个值表明回调sofia_event_callback时,Call state 发生了变化。
}
所谓的Callstate,就是服务器对sip协议进展过程的状态变换。
例如 1002---à1003时,FreeSwitch的sip协议栈会按照如下流程进行sip状态转化:
① 收到INVITE后,向1002发送100Trying,此时,在sofia提供的状态转化机中,会产生
nua_i_state 的event,因此根据此event回调sofia_event_callback(…)函数,并根据相应的event事件进入对应的事件处理函数,这里进入的事件处理函数是sofia_handle_sip_i_state(…)。而表示消息event的序号是100,m描述状态字符串phrase是”100 Trying”。进入处理函数后,FS会根据state判断进入相应的处理流程,这里,将会进入到nua_callstate_recveied的处理流程。
② 当FreeSwitch向1003发送INVITE同样会引发event回调,并传回一个相应的state,需要弄清楚的是:FreeSwitch是怎样进行内部处理的。
③ 当1003 最终的”200ok” 和1002 最终的”Ack”抵达时,FreeSwitch会根据回调的state进入sofia_handle_sip_i_state(…)nua_callstate_ready的处理流程,意味着双方都已最好准备,可以通话了。
④ 需要注意的两点,一是在sofia_event_callback中是根据event类型选择处理函数,而event类型为nua_i_state时进入sofia_handle_sip_i_state(…)处理callstate状态变化事件。二是对于call state的描述同样是一个枚举类型,定义为:
enum nua_callstate {
nua_callstate_init, /**<Initial state */
nua_callstate_authenticating, /**< 401/407 received */
nua_callstate_calling, /**< INVITE sent*/
nua_callstate_proceeding, /**< 18X received */
nua_callstate_completing, /**< 2XXreceived */
nua_callstate_received, /**< INVITEreceived */
nua_callstate_early, /**< 18Xsent (w/SDP) */
nua_callstate_completed, /**< 2XX sent*/
nua_callstate_ready, /**< 2XX received, ACK sent, or vice versa */
nua_callstate_terminating, /**< BYE sent */
nua_callstate_terminated /**< BYEcomplete */
};
所以,sofia_handle_sip_i_state(…)函数将会根据此枚举类型和传入的status,phrase(函数形参)来选择不同的处理流程。
B2B Channel的状态流程
INVITE达到sofia模块的处理
Channel在FreeSwitch中描述了一个UA与US之间的数据传送通道。也就是说,channel更多的概念是与协议无关的,而是与数据传送有关。因此,channel的状态变化不可