在mrcp_sofia_task_initialize中调用nua_create一个UA(User agent)这个跟freeswitch SIP信令的接收,是一样的。在nua_create的时候会设置回调函数:mrcp_sofia_event_callback()。接下来的处理都是一样的,只是有事件的时候的回调不一样。现在调用的是mrcp_sofia_event_callback()。
/** This callback will be called by SIP stack to process incoming events */
static void mrcp_sofia_event_callback(
nua_event_t nua_event,
int status,
char const *phrase,
nua_t *nua,
mrcp_sofia_agent_t *sofia_agent,
nua_handle_t *nh,
mrcp_sofia_session_t *sofia_session,
sip_t const *sip,
tagi_t tags[])
{
apt_log(APT_LOG_MARK,APT_PRIO_INFO,"Receive SIP Event [%s] Status %d %s [%s]",
nua_event_name(nua_event),
status,
phrase,
sofia_agent->sig_agent->id);
switch(nua_event) {
case nua_i_state:
mrcp_sofia_on_state_change(status,sofia_agent,nh,sofia_session,sip,tags);
break;
if(status >= 200) {
/* break main loop of sofia thread */
su_root_break(sofia_agent->root);
}
break;
default:
break;
}
}
case nua_r_invite:
if(status >= 300 && status < 400) {
mrcp_sofia_on_session_redirect(status,sofia_agent,nh,sofia_session,sip,tags);
}
break;
case nua_r_options:
mrcp_sofia_on_resource_discover(status,sofia_agent,nh,sofia_session,sip,tags);
break;
case nua_r_shutdown:
/* if status < 200, shutdown still in progress */
我们这里分析一下nua_i_state的时候的处理,这个时候会调用mrcp_sofia_on_state_change()。
nua_callstate的描述是一个枚举类型,定义为:
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, /*< 2XX received /
nua_callstate_received, /*< INVITE received /
nua_callstate_early, /*< 18X sent (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 /*< BYE complete /
};
接下来看下mrcp_sofia_on_state_change的具体实现
static void mrcp_sofia_on_state_change(
int status,
mrcp_sofia_agent_t *sofia_agent,
nua_handle_t *nh,
mrcp_sofia_session_t *sofia_session,
sip_t const *sip,
tagi_t tags[])
{
int nua_state = nua_callstate_init;
tl_gets(tags,
NUTAG_CALLSTATE_REF(nua_state),
TAG_END());
if(!sofia_session || !sofia_session->session) {
apt_log(APT_LOG_MARK,APT_PRIO_WARNING,"SIP Call State [%s]", nua_callstate_name(nua_state));
return;
}
apt_obj_log(APT_LOG_MARK,APT_PRIO_NOTICE,sofia_session->session->log_obj,"SIP Call State %s [%s]",
sofia_session->session->name,
nua_callstate_name(nua_state));
if(nua_state == nua_callstate_terminated) {
mrcp_sofia_on_session_terminate(status,sofia_agent,nh,sofia_session,sip,tags);
return;
}
if(nua_state == nua_callstate_ready) {
mrcp_sofia_on_session_ready(status,sofia_agent,nh,sofia_session,sip,tags);
}
sofia_session->nua_state = nua_state;
}