FreeSwitch呼出流程分析

        为了简单起见,用下面的fs cli命令发起一路单边外呼:

originate sofia/192.168.1.8/1000 &playback(ivr/8000/ivr-welcome_to_freeswitch.wav)

        注意连接串写的是sofia/192.168.1.8/1000,直接指定sofia的具体profile,而不是用user/1000,因为后者是个虚拟的逻辑概念,定位过程中会引入originate的递归调用,增加复杂度。        

        打开fs_cli,输入命令。

       fs_cli是典型的ESL客户端,所以接收端是mod_event_socket的监听线程listener_run。收到消息后,调用parse_command()解析,进入调用链:api_exec==>switch_api_execute==>originate_function==>switch_ivr_originate。\freeswitch-1.8.7\src\switch_ivr_originate.c文件里实现的switch_ivr_originate函数是originate操作的实际执行体。这个函数很长,很长,让人望而生畏。最关键的一行代码:


       调用switch_core_session_outgoing_channel()创建Session和Channel。然后对Channel的变量及属性一一设置,继而进入另一个关键调用点:

        调用switch_core_session_thread_launch()激活外呼的工作线程。

         switch_core_session_outgoing_channel函数里,调用endpoint_interface->io_routines->outgoing_channel接口,对应到soia模块就是sofia_outgoing_channel()函数。sofia_outgoing_channel里调用switch_core_session_request_uuid()创建Session对象,并调用switch_channel_set_state()把状态机置为CS_INIT。

        状态机驱动之后,调用sofia模块的状态回调函数sofia_on_init()时,调用sofia_glue_do_invite函数发出INVITE消息。然后,核心状态函数switch_core_standard_on_init驱动状态迁移到CS_ROUTING状态。这时拨号方案执行列表就是我们最开始的命令:&playback(ivr/8000/ivr-welcome_to_freeswitch.wav)。

        originate模块添加的状态回调函数originate_on_routing被调用时,驱动状态机迁移到CS_CONSUME_MEDIA状态。这时originate 挂起,等待被叫方的响应。

        sofia协议栈收到消息时,抛出事件,并调用sofia_event_callback回调函数。对于应答消息18X和2XX,调用链差不多:sofia_event_callback==>sofia_queue_message==>sofia_process_dispatch_event==>our_sofia_event_callback==>sofia_handle_sip_i_state。最后18X调用switch_channel_mark_pre_answered,而2XX调用switch_channel_mark_answered。

        被叫应答后,之前被挂起的originate激活,根据返回的结果,驱动状态机继续迁移,对于200OK,也就是answer,置状态为CS_EXECUTE。

       接下来的迁移就取决于后续的处理了,本例是,执行完playback,没有后续的APP,核心触发hangup,这和单边的呼入处理是一样的。

FreeSwitch呼出流程分析_第1张图片

 

你可能感兴趣的:(FreeSWITCH)