我建了一個 Freeswitch 核心研究 交流群, 45211986, 歡迎加入, 另外,提供基於SIP的通訊伺服器及用戶端解決方案。
比較零散,先放這留個腳印,慢慢添加整理。
1 .
freeswitch 分機號都儲存在conf/directory 目錄下
系統啟動時載入分機資訊到記憶體,當收到註冊包時在directory目錄下的usr 被搜尋,搜尋依據是註冊請求的to ,from 頭域的網域名稱為系統所在的網域名稱,
分機設定檔的分級結構:
domain
groups
group
usr
usr
group
groups
domain
directory 目錄下包含若干xml檔案,可以每個使用者一個xml profile,系統啟動時動態載入,
除了通過檔案方式配置使用者外,可以通過 mod_xml_curl模組 訪問web server, web server 在
訪問資料庫,實現大批量分機的添加。
可以在使用者的設定檔中設定一些附加給此使用者的變數。
directory 目錄的內容載入後可以被系統的所有模組擷取,這樣減少資料冗餘。
dialplan 全域變數 用 $${default_areacode}" 訪問,通道變數用${default_areacode}"訪問
conf/var.xml檔案定義了系統的全域變數。
單個使用者 的設定檔範本
<include>
<user id="1000"> //id 代表使用者名稱,認證時使用者名稱。
<params>
<param name="password" value="$${default_password}"/>
</params>
<variables>
<variable name="toll_allow value="domestic,international,local"/> //此使用者的 channel會設定此變數,使用者的許可權
其她可設定的變數:
accountcode :使用者賬戶,會出現在CDR中。
user_context: 使用者打電話時走dialplan中context名為 user_context 的值
effective_caller_id_name: 呼叫其他使用者時顯示給對方的使用者名稱,(只有被叫在系統上註冊才有效)
effective_caller_id_number :給對方顯示的使用者號,(只有被叫在系統上註冊才有效)
outbound_caller_id_name:通過 sip中繼外乎時給對方送的使用者名稱
outbound_caller_id_number :通過 sip中繼外乎時給對方送的使用者號碼
callgroup :附加屬性,
</variables>
</user>
</include>
一個分機預設配置包含:
A username for SIP and for authorization
A voicemail password
A means of allowing/restricting dialling
A means of handling caller ID being sent out
Several arbitrary variables that can be used or ignored as needed
配置一個分機過程:
#>cd /usr/local/freeswitch/conf/directory/default
#>cp 1000.xml 1030.xml
Replace all occurrences of "1000" with "1030"
修改default dialplan
重新載入設定檔使配置生效:
reloadxml
控制台查看哪些分機主上已經註冊:
sofia status profile internal
freeswitch的dialplan單獨一個目錄,分機的conext 為dialplan目錄下的conext.xml
與外部連結:
freeswitch通過 sip網關聯絡外部世界,freeswitch此時在sip server 來看是一個user.
配置網關方式:
建立中繼檔案:
conf/sip_profiles/external/test.xml
<include>
<gateway name="custom">
<param name="username" value="MY_USER_NAME"/> //sip provider提供的使用者名稱及密碼
<param name="password" value="MY_PASSWORD"/>
<param name="realm" value="iptel.org"/>
<!-- iptel.org requires a 'proxy' parameter -->
<param name="proxy" value="sip.iptel.org"/>
</gateway>-->
</include>
使配置生效:
cli 執行:
sofia profile external restart reloadxml (此命令會把正在通話的分機掛掉,更安全的方式是用 sofia profile external rescan reloadxml)
cli執行 sofia status
返回系統sip 配置資訊
主要分兩類:1.網關(gateway) 2.本地註冊使用者(profile)
mod_xml_curl:
此模組為與Asterisk realtime 機制差不多,可以通過此模讓freeswitch 需要時動態訪問外部資料庫或Web Server.這樣可以實現動態控制freeswitch核心。
比如 分機的添加可以通過在資料庫配置,freeswitch通過此模組來載入分機。
通過此模組可以綁定:
1 .dialplan
<param name="gateway-url" value="http://localhost:8080" bindings="Dialplan"/>
每次呼叫,系統都會先訪問8080
.....
2. 設定檔
sofia.conf 檔案:
global_settings 節點:
子節點:
log-level
tracelevel
debug-presence
debug-sla
auto-restart
rewrite-multicasted-fs-path
to_host
original_server_host
original_hostname
profiles 節點: conf/sip_profiles/*.xml
預設有兩個
internalx.ml
external.xml
freeswitch 高效能技術特性:memory pool,task queue, event driven,multithread,hash,state Machine,記憶體池,多線程,任務隊列,事件驅動,雜湊,狀態機器。
核心啟動流程:
兩個函數
switch_core_init 負責核心的初始化
apr_initialize(),
switch_core_session_init,
switch_core_hash_init,
switch_console_init,
switch_event_init,
switch_xml_init,
switch_log_init,
switch_core_state_machine_init
switch_scheduler_task_thread_start
switch_nat_late_init,
switch_rtp_init,
switch_loadable_module_init 各個模組的初始化。
呼叫流程:呼入
sip協議棧 從傳輸層收到sip訊息,最終轉到SIPUA層,進入 sofia_event_callback->sofia_queue_message
sofia_msg_thread_start->sofia_msg_thread_run->
sofia_process_dispatch_event-----------------
->our_sofia_event_callback->sofia_handle_sip_i_invite->switch_core_session_request
switch_core_session_thread_launch -> switch_core_session_thread_launch--->switch_ivr_originate()
外乎: fifo, conferrance,switch_ivr_originate
enterprise_originate_thread-> switch_ivr_originate----switch_core_session_outgoing_channel---->sofia_outgoing_channel->switch_core_session_request->
freeswitch 核心幾個概念:session,channle, tec_private,event,
核心通過一個有限狀態機器來管理呼叫過程中每個狀態對應的回調。
一個呼叫進入系統後建立一條channel,此channle屬於一個 server 維護的session,核心通過狀態機器來調度session以實現事件的流轉。
一個典型的呼叫流程 uac1-uas, uas-uac2, uac1-bridge-uac2,呼叫進入系統,系統建立session後啟動switch_core_session_thread_launch 線程不斷監聽session狀態,根據狀態調用相應的回調,當然,這裡的狀態機器是一個狀態有限的,freeswitch 狀態機器分 以下狀態:
on_init,
on_routing,
on_execute,
on_hangup,
on_exchange_media
on_soft_execute,
on_consume_media,
on_hibernate,
on_reset,
on_park,
on_reporting,
on_destroy。
實際呼叫過程為這些狀態的流轉。
uac1-uas: 呼入系統,系統建立session:
sofia_handle_sip_i_invite->switch_core_session_request->switch_core_session_thread_launch,
解析請求後從CS_NEW -> CS_INIT, 初始化後進入dialplan : CS_INIT -> CS_ROUTING, 狀態機器回調 switch_core_standard_on_routing 尋找dialplan
系統根據主叫,被叫的sip設定尋找其對應的dialplan,然後載入到記憶體,
呼叫狀態 轉換:CS_ROUTING -> CS_EXECUT,狀態機器調用 switch_core_standard_on_execute,然後按照規則一條一條執行剛載入的dialplan,這裡即是可程式化軟交換的體現,根據需求靈活控制提供給一個呼叫的服務。當執行到bridge action 時,是讓系統呼叫uac2, 調用switch_ivr_originate 外乎uac2,建立uac2在伺服器端的session,channel,
最後啟動狀態機器線程switch_core_session_thread_launch進入狀態機器模式,CS_NEW -> CS_INIT-> CS_ROUTING-> CS_CONSUME_MEDIA,
usc2最終應答 200 ok,伺服器 根據200 ok sdp訊息體與uac1提供的sdp協商,成功後發200 ok給 uac1,呼叫橋接成功。uac2狀態機器轉換CS_CONSUME_MEDIA -> CS_EXCHANGE_MEDIA,媒體流橋接開始。
狀態機器流轉節點:
/*! \enum switch_channel_state_t \brief Channel States (these are the defaults, CS_SOFT_EXECUTE, CS_EXCHANGE_MEDIA, and CS_CONSUME_MEDIA are often overridden by specific apps)<pre>CS_NEW - Channel is newly created.CS_INIT - Channel has been initilized.CS_ROUTING - Channel is looking for an extension to execute.CS_SOFT_EXECUTE - Channel is ready to execute from 3rd party control.CS_EXECUTE - Channel is executing it's dialplan.CS_EXCHANGE_MEDIA - Channel is exchanging media with another channel.CS_PARK - Channel is accepting media awaiting commands.CS_CONSUME_MEDIA - Channel is consuming all media and dropping it.CS_HIBERNATE - Channel is in a sleep state.CS_RESET - Channel is in a reset state.CS_HANGUP - Channel is flagged for hangup and ready to end.CS_REPORTING - Channel is ready to collect call detail.CS_DESTROY - Channel is ready to be destroyed and out of the state machine</pre> */