freeswitch SIP信令的处理在mod_sofia中
首先在模块的加载(mod_sofia_load)里面会创建一个处理SIP消息的线程:
/* start one message thread */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Starting initial message thread.\n");
sofia_msg_thread_start(0);
然后会调用config_sofia函数.
if (config_sofia(SOFIA_CONFIG_LOAD, NULL) != SWITCH_STATUS_SUCCESS) {
mod_sofia_globals.running = 0;
return SWITCH_STATUS_GENERR;
}
在这个函数里面,会解析conf/sip_profiles里面的profile文件。比如我们熟悉的nternal和external文件就是在这里解析的。解析完后自然就生产了一个对应的C语言里面的sofia_profile_t结构体。
得到sofia_profile_t对象后,会调用launch_sofia_profile_thread()函数
void launch_sofia_profile_thread(sofia_profile_t *profile)
{
//switch_thread_t *thread;
switch_threadattr_t *thd_attr = NULL;
switch_threadattr_create(&thd_attr, profile->pool);
switch_threadattr_detach_set(thd_attr, 1);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME);
switch_thread_create(&profile->thread, thd_attr, sofia_profile_thread_run, profile, profile->pool);
}
在这里会创建一个新的线程,并在新线程里面调用nua_create()创建一个UA(User agent),在nua_create()里面就会创建对应的socket端口(比如我们熟悉的5060),在这个端口你们监听其他人发来的SIP消息。当收到SIP消息后会回调sofia_event_callback()进行处理。
profile->nua = nua_create(profile->s_root, /* Event loop */
sofia_event_callback, /* Callback for processing events */
profile, /* Additional data to pass to callback */
TAG_IF( ! sofia_test_pflag(profile, PFLAG_TLS) || ! profile->tls_only, NUTAG_URL(profile->bindurl)),
NTATAG_USER_VIA(1),
TPTAG_PONG2PING(1),
NTATAG_TCP_RPORT(0),
NTATAG_TLS_RPORT(0),
NUTAG_RETRY_AFTER_ENABLE(0),
TAG_IF(!strchr(profile->sipip, ':'),
SOATAG_AF(SOA_AF_IP4_ONLY)),
TAG_IF(strchr(profile