freeswitch呼叫流程分析

來源:互聯網
上載者:User

標籤:

今天翻文檔時發現之前整理的關於freeswitch呼叫相關的內容,寫成博文分享出來也方便我以後查閱。

整體結構圖

 

FreeswitchCore模組載入過程

freeswitch主程式初始化時會從modules.conf.xml檔案中讀取配置,如果配置中如下內容生效:

<load module="mod_sofia"/>

則執行載入sofia模組操作。

具體過程如下:

mainswitch_core_init_and_modloadswitch_loadable_module_initswitch_loadable_module_load_module_ex : 讀取xml檔案並載入模組
狀態機器相關狀態機器初始化
switch.c  : mainswitch_core_init_and_modload    => switch_core_init        => switch_core_session_init            => switch_core_session_thread_pool_manager                => check_queue                    => switch_core_session_thread_pool_worker                        => switch_core_session_thread                            => switch_core_session_run   
改變狀態

通過調用switch_channel_set_state來實現狀態機器的狀態改變。

處理狀態變化

當狀態發生變化後,通過switch_channel_set_running_state函數來改變running_state,
並執行相關的回調來通知其狀態已經發生改變了:
endpoint_interface->io_routines->state_run

主叫狀態變化
  • CS_NEW

switch_core_session_run初始狀態為CS_NEW

  • CS_INIT

    sofia_handle_sip_i_state
    case nua_callstate_received (收到invite請求) 修改狀態機器的狀態 :CS_NEW ==> CS_INIT switch_channel_set_state(channel, CS_INIT);

    switch_core_session_run
    狀態機器處理狀態變化 STATE_MACRO(init, "INIT"); on_init 即 : sofia_on_init
    switch_core_standard_on_init

  • CS_ROUTING

    sofia_on_init

    修改狀態機器的狀態 : CS_INIT == > CS_ROUTINGswitch_channel_set_state(channel, CS_ROUTING);

    switch_core_session_run
    狀態機器處理狀態變化 STATE_MACRO(routing, "ROUTING"); on_routing 即 : sofia_on_routing
    switch_core_standard_on_routing

  • CS_EXECUTE

    switch_core_standard_on_routing 修改狀態機器的狀態 : CS_ROUTING == > CS_EXECUTE switch_channel_set_state(session->channel, CS_EXECUTE);

    switch_core_session_run
    狀態機器處理狀態變化 STATE_MACRO(execute, "EXECUTE"); on_execute 即 : sofia_on_execute
    switch_core_standard_on_execute

  • CS_HANGUP

    sofia_handle_sip_i_bye switch_channel_hangup : 即 switch_channel_perform_hangup 修改狀態機器的狀態 channel->state = CS_HANGUP;

        狀態機器處理狀態變化    switch_core_session_hangup_state                    STATE_MACRO(hangup, "HANGUP");
被叫狀態變化
  • CS_NEW

switch_core_session_run初始狀態為CS_NEW

  • CS_INIT

    sofia_outgoing_channel 修改狀態機器的狀態 :CS_NEW ==> CS_INIT switch_channel_set_state(nchannel, CS_INIT);

狀態機器處理邏輯參考主叫。

  • CS_ROUTING

    sofia_on_init
    修改狀態機器的狀態 : CS_INIT == > CS_ROUTING switch_channel_set_state(channel, CS_ROUTING);

狀態機器處理邏輯參考主叫。

  • CS_CONSUME_MEDIA

    originate_on_routing 修改狀態機器的狀態:CS_ROUTING -> CS_CONSUME_MEDIA switch_channel_set_state(channel, CS_CONSUME_MEDIA);

    switch_core_session_run
    狀態機器處理狀態變化 STATE_MACRO(consume_media, "CONSUME_MEDIA"); on_ consume_media 即 : NULL switch_core_standard_on_consume_media

  • CS_EXCHANGE_MEDIA

    switch_core_session_run
    狀態機器處理狀態變化 STATE_MACRO(exchange_media, "EXCHANGE_MEDIA"); on_exchange_media 即 : sofia_on_exchange_media
    switch_core_standard_on_exchange_media

  • CS_HANGUP

    audio_bridge_on_exchange_media
    switch_channel_hangup : 即 switch_channel_perform_hangup 修改狀態機器的狀態 channel->state = CS_HANGUP;

        狀態機器處理狀態變化    switch_core_session_hangup_state        STATE_MACRO(hangup, "HANGUP");
Sofia應用程式層模組載入過程

啟動事件處理線程池 :

SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)    => sofia_msg_thread_start(0);        => sofia_msg_thread_run            => sofia_process_dispatch_event                => our_sofia_event_callback : 處理訊息

啟動伺服器監聽 :

SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load)    => config_sofia(0, NULL)        => launch_sofia_profile_thread            => sofia_profile_thread_run                                => nua_create                    => su_home_new                    => nua_stack_init                                            => nta_agent_create                            => nta_agent_add_tport                                                            => tport_tbind                                    => tport_bind_server                                        => tport_listen : 監聽用戶端發來的資料   
資料表

資料庫預設路徑:/usr/local/freeswitch/db

freeswitch core 相關:

  • aliases
  • calls
  • channels
  • complete
  • interfaces
  • nat
  • recovery
  • registrations
  • tasks

sofia相關:

  • sip_authentication
  • sip_dialogs
  • sip_presence
  • sip_registrations
  • sip_shared_appearance_dialogs
  • sip_shared_appearance_subscriptions
  • sip_subscriptions

limit相關:

  • db_data
  • group_data
  • limit_data

fifo相關:

  • fifo_bridge
  • fifo_callers
  • fifo_outbound

語音信箱相關:

  • voicemail_msgs
  • voicemail_prefs
呼叫流程涉及內容

1、 收到A的nua_i_invite,返回407,具體如下:

sofia_handle_sip_i_invite => sofia_reg_handle_register => sofia_reg_auth_challenge => 407

2、 收到A的nua_i_invite,返回180,具體如下:

sofia_handle_sip_i_invite => sofia_reg_handle_register => sofia_reg_parse_auth

處理nua_i_state訊息
sofia.c : sofia_handle_sip_i_state
...
mod_dialplan_xml.c : dialplan_hunt (ring_ready)
解析撥號方案,執行lua指令碼,設定通道變數。
…
發送180事件

涉及資料表:
sip_registrations、ip_dialogs

3、 發送invite給B分機,具體如下:
處理nua_r_invite訊息
sofia_handle_sip_r_invite => originate_on_routing
涉及資料表:
sip_dialogs

4、 B應答,雙方通話,具體如下:

sofia_receive_message : SWITCH_MESSAGE_INDICATE_ANSWER                   => sofia_answer_channel        => sofia_glue_tech_choose_port        => sofia_glue_set_local_sdp        => sofia_glue_activate_rtp
編碼協商過程

這裡描述下後協商流程

  • 先匹配freeswitch預設的codec,從載入的模組中尋找支援類型的具體碼率資訊

sofia_handle_sip_i_invite
=> sofia_glue_tech_prepare_codecs
=> switch_loadable_module_get_codecs_sorted

  • 協商發給被叫的sdp

sofia_glue_do_invite
=> sofia_glue_tech_prepare_codecs
=> switch_loadable_module_get_codecs_sorted

    ocodec + codec_string     
  • 產生M頭,並發送包含sdp的invite

sofia_glue_do_invite
=> sofia_glue_set_local_sdp
=> generate_m
=> nua_invite

  • 協商200 OK的sdp

sofia_answer_channel
=> sofia_glue_tech_prepare_codecs
=> switch_loadable_module_get_codecs_sorted

媒體互動
  • RTP資料互動

audio_bridge_on_exchange_media
=> audio_bridge_thread

收發音頻資料
=> switch_core_session_read_frame
=> session->endpoint_interface->io_routines->read_frame 即: sofia_read_frame

=> switch_core_session_write_frame
=> perform_write
=> session->endpoint_interface->io_routines->write_frame 即: sofia_write_frame

收發視頻資料
1、啟動線程
=> launch_video
=> video_bridge_thread

2、收發資料
=> switch_core_session_read_video_frame
=>session->endpoint_interface->io_routines->read_video_frame
即:sofia_read_video_frame

=> switch_core_session_write_video_frame
=> session->endpoint_interface->io_routines->write_video_frame
即:sofia_write_video_frame

  • 終止RTP互動

audio_bridge_thread
=> switch_core_session_kill_channel(session_b, SWITCH_SIG_BREAK);
即 :switch_core_session_perform_kill_channel
=> session->endpoint_interface->io_routines->kill_channel
即 : sofia_kill_channel
=> switch_rtp_break

Sofia協議棧協議棧結構圖

NUA : 基本的SIP使用者代理程式的功能,其功能包括呼叫管理,訊息和事件檢索。
NTA : sofia SIP事務API(NTA)提供了簡單的介面的SIP事務,傳輸和資訊處理。
Tport : 該模組包含一個由SIP,RTSP 和HTTP協議使用的通用傳輸介面,這是一個協議棧和傳輸協議實現之間的抽象層。

SIP信令具體流程

情境描述: A 呼叫 B ,B接通後通話一段時間後,掛斷電話。

  • A 發送 INVITE 請求

tport.c : tport_recv_data
nta.c : agent_recv_request

  • FS回應100給A分機

nua_server.c : nua_stack_process_request
nua_server.c : SR_STATUS1(sr, SIP_100_TRYING)
nta.c : nta_incoming_treply
nta.c : incoming_reply
tport.c: tport_tsend

  • FS發送認證請求給A分機

nua_application_event

處理nua_i_invite 訊息

sofia.c : sofia_process_dispatch_event
sofia.c : our_sofia_event_callback
sofia.c : sofia_handle_sip_i_invite
sofia.c : sofia_reg_handle_register
sofia_reg.c : sofia_reg_auth_challenge

回複407

nua.c : nua_respond
nua_stack.c : nua_signal
nua_stack.c : nua_stack_signal
nua_server.c : nua_stack_respond
nua_server.c : nua_server_respond

發送407給A分機

nua_invite_server_respond
nua_base_server_respond
nta_incoming_mreply
incoming_reply
tport_tsend
tport_resolve
tport_by_addrinfo
tport_prepare_and_send
tport_send_msg
tport_vsend
sent 407 Proxy Authentication Required for INVITE (1)

call state(A) : init -> received
call state(A) : received -> terminated

  • A分機發送ACK
    nta.c : agent_recv_message
    nta.c : agent_recv_request

  • A分機重新發送 INVITE 請求,附加認證資訊
    tport.c : tport_recv_data
    nta.c : agent_recv_request

  • FS回應100給A分機

nua_server.c : nua_stack_process_request
nua_server.c : SR_STATUS1(sr, SIP_100_TRYING)
nta.c : nta_incoming_treply
nta.c : incoming_reply
tport.c: tport_tsend

  • FS發送 INVITE 給 B分機

switch_ivr_originate.c : switch_ivr_originate

sofia_on_init
sofia_glue_do_invite
nua_invite : nua_r_invite 訊息
nua_signal

sofia.c : sofia_process_dispatch_event
sofia.c : our_sofia_event_callback
sofia.c : sofia_handle_sip_r_invite
...
sofia_on_init
sofia_on_routing
switch_ivr_originate.c :originate_on_routing
...
nua_stack_signal
nua_stack_invite
...
nta_leg_tcreate
...
執行發送invite請求
nta.c : outgoing_send
tport_tsend

call state(B) : init -> calling

  • B分機回應180給FS
    tport_recv_event
    agent_recv_response

處理 nua_r_invite 訊息

sofia.c : sofia_process_dispatch_event
sofia.c : our_sofia_event_callback
sofia.c : sofia_handle_sip_r_invite

call state(B) : calling -> proceeding

  • FS發送180給A分機

nua_session.c : signal_call_state_change
nua_stack_tevent : nua_i_state
nua_application_event

處理nua_i_invite 訊息

sofia.c : sofia_process_dispatch_event
sofia.c : our_sofia_event_callback
sofia.c : sofia_handle_sip_i_invite
sofia_reg.c : sofia_reg_handle_register
sofia_reg.c : sofia_reg_parse_auth

處理nua_i_state訊息
sofia.c : sofia_handle_sip_i_state
...
mod_dialplan_xml.c : dialplan_hunt (ring_ready)
解析撥號方案,執行lua指令碼,設定通道變數。
…

發送180
switch_channel_mark_ring_ready

nua_invite_server_respond
nua_base_server_respond
nta_incoming_mreply
incoming_reply
tport_tsend
tport_resolve
tport_by_addrinfo
tport_prepare_and_send
tport_send_msg
tport_vsend

call state(A) : init -> received

? B發送200 ok
tport_recv_event
agent_recv_response

處理 nua_r_invite 訊息

sofia.c : sofia_process_dispatch_event
sofia.c : our_sofia_event_callback
sofia.c : sofia_handle_sip_r_invite

call state(B) : proceeding -> completing

  • FS發送ACK給B
    nua_ack
    nua_signal : nua_r_ack
    outgoing_send
    tport_tsend

call state(A) : received -> early
call state(B) : completing -> ready

  • FS發送200 OK給A
    sofia_glue_tech_set_codec
    switch_rtp_create
    sofia_glue_negotiate_sdp
    sofia_glue_activate_rtp
    ...
    switch_channel_perform_answer : SWITCH_MESSAGE_INDICATE_ANSWER
    switch_channel_perform_mark_answered
    ...
    auto_record.lua : 執行錄音操作B
    ...
    auto_record.lua : 執行錄音操作A
    ...
    sofia_receive_message (SWITCH_MESSAGE_INDICATE_ANSWER)
    ...
    發送200 OK
    nua_respond : 200
    nua_signal : nua_r_respond
    nua_stack_signal
    nua_stack_respond
    nua_server_respond
    nta_incoming_treply
    nta_incoming_mreply
    incoming_reply
    tport_tsend

call state(A) : early -> completed

  • A回應ACK
    nta.c : agent_recv_message
    nta.c : agent_recv_request

call state(A) : completed -> ready

  • 通話一段時間後,A主動發送BYE
    tport_recv_event
    agent_recv_message
    agent_recv_request
    ...
    sofia_on_hangup

  • FS發送BYE給B
    nua_bye : nua_r_bye
    nua_stack_signal
    outgoing_send
    tport_tsend

  • FS發送200 OK給A
    nta : sent 200 OK for BYE
    tport_tsend

call state(A) : ready -> terminating
call state(A) : terminated

  • B發送200 OK給FS,回應掛斷請求
    nta: received 200 OK for BYE

狀態變化:
call state(B) : ready -> terminating
call state(B) : terminating -> terminated

本文github地址:

https://github.com/mike-zhang/mikeBlogEssays/blob/master/2016/20160907_freeswitch呼叫流程分析.md

歡迎補充 

freeswitch呼叫流程分析

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.