FreeSwitch的初始化及其模塊加載過程_第1頁
FreeSwitch的初始化及其模塊加載過程_第2頁
FreeSwitch的初始化及其模塊加載過程_第3頁
FreeSwitch的初始化及其模塊加載過程_第4頁
FreeSwitch的初始化及其模塊加載過程_第5頁
已閱讀5頁,還剩27頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

1、FreeSwitch的初始化及其模塊加載過程Freeswitch的主函數(shù)是在文件switch.c中定義的,該文件的260行是整個程序的入口,主函數(shù)主要完成的功能是包括,命令行解析,初始化apr庫,構建全局內存池,模塊加載和初始化核心組件。初始化apr庫是由apr_initialize()函數(shù)完成的,apr庫是apache的可移植動態(tài)庫,完成相關的內存池,線程管理的跨平臺工作。該函數(shù)的調用在主函數(shù)的659行。745行的switch_core_set_globals()主要是完成全局目錄的設置。不過,在switch_core_init()中再一次調用了該函數(shù)。747行的pid=getpid()獲取

2、程序的進程號。754行利用apr_pool_create()創(chuàng)建一個匿名的內存池,由主函數(shù)中定義的switch_memory_pool_t*pool局部指針指向,但是可以知道,該內存池將作為程序的整個運行周期所使用。本分析最關鍵的一點出現(xiàn)在784行,該行調用了switch_core_init_and_modload()函數(shù),該函數(shù)完成了核心組件的初始化以及各個模塊的動態(tài)加載。最終,形成了一個統(tǒng)一的系統(tǒng)。switch_core_init_and_modload()函數(shù)定義在switch_core.c文件中,第1526行。函數(shù)原型如下:SWITCH_DECLARE(switch_status_t)

3、switch_core_init_and_modload(switch_core_flag_tflags,switch_bool_tconsole,constchar*err)其中,SWITCH_DECLARE(type)宏在windows下展開為#defineSWITCH_DECLARE(type)_declspec(dllexport)type_stdcall主要用于將函數(shù)聲明為dll的導出符號,這樣,在其他模塊中,便可以使用該函數(shù)了。而在其他系統(tǒng)平臺上,該宏是一個空宏,例如在linux下,共享庫的符號是全局的,不需要聲明為導出符號。一般來說,freeswitch其他的動態(tài)加載模塊所定義的

4、函數(shù)不需要用該宏聲明,在windows平臺下,各個模塊之間是隔離的,而核心模塊中定義的函數(shù)大部分使用了該宏聲明,因為其他模塊需要大量使用核心模塊中的核心函數(shù),這里所指的核心模塊是FreeSwitchCoreLib共享對象。于是可以知道,switch_core_init_and_modload()函數(shù)可以在其他依賴于核心模塊的動態(tài)加載模塊中使用,這里主函數(shù)所在的模塊是FreeSwitchConsole,依賴于核心模塊,于是,便可以使用該函數(shù)來完成模塊加載。switch_core_init()在該函數(shù)中調用了switch_core_init()函數(shù),用來初始化一些全局化的信息,包括一個全局的swi

5、tch_runtime結構,各種全局的哈希表,互斥變量。一條一條地分心如下:全局的switch_runtime結構runtime部分字段的初始化代碼段如下:if(runtime.runlevel>0)/*onepercustomer*/returnSWITCH_STATUS_SUCCESS;runtime.runlevel+;/從這里可見,runlevel大于0是一個服務器已啟動的標志,所以不必在進行/以下的初始化操作,直接返回SWITCH_STATUS_SUCCESS即可。runtime.dummy_cng_frame.data=runtime.dummy_data;runti

6、me.dummy_cng_frame.datalen=sizeof(runtime.dummy_data);runtime.dummy_cng_frame.buflen=sizeof(runtime.dummy_data);switch_set_flag(&runtime.dummy_cng_frame),SFF_CNG);switch_set_flag(&runtime),SCF_NO_NEW_SESSIONS);runtime.hard_log_level=SWITCH_LOG_DEBUG;runtime.mailer_app="sendmail&

7、quot;runtime.mailer_app_args="-t"runtime.max_dtmf_duration=SWITCH_MAX_DTMF_DURATION;runtime.default_dtmf_duration=SWITCH_DEFAULT_DTMF_DURATION;runtime.min_dtmf_duration=SWITCH_MIN_DTMF_DURATION;接下來又重新初始化了一遍apr庫,很奇怪,不知道是不是一個多余的步驟。A_A/*INITAPRandCreatethepoolcontext*/if(apr_initialize()!=SWI

8、TCH_STATUS_SUCCESS)*err="FATALERROR!CouldnotinitializeAPRn"returnSWITCH_STATUS_MEMERR;if(!(runtime.memory_pool=switch_core_memory_init()*err="FATALERROR!Couldnotallocatememorypooln"returnSWITCH_STATUS_MEMERR;/從這里可以看見,全局的runtime是有一個內存池來管理它所需要的其他資源的。 安裝時的目錄信息的相關設置,與runtime結構掛鉤,代碼如下

9、switch_dir_make_recursive(SWITCH_GLOBAL_dirs.base_dir,SWITCH_DEFAULT_DIR_PERMS,runtime.memory_pool);/主目錄,即工程所在目錄,一般為./bin,./表示安裝路徑switch_dir_make_recursive(SWITCH_GLOBAL_dirs.mod_dir,SWITCH_DEFAULT_DIR_PERMS,runtime.memory_pool);/模塊所在目錄,一般為安裝目錄./mod,./表示安裝路徑switch_dir_make_recursive(SWITCH_GLOBAL_di

10、rs.conf_dir,SWITCH_DEFAULT_DIR_PERMS,runtime.memory_pool);/配置文件所在目錄,一般為./confswitch_dir_make_recursive(SWITCH_GLOBAL_dirs.log_dir,SWITCH_DEFAULT_DIR_PERMS,runtime.memory_pool);/日志所在的目錄。一般為./logswitch_dir_make_recursive(SWITCH_GLOBAL_dirs.run_dir,SWITCH_DEFAULT_DIR_PERMS,runtime.memory_pool);/進程文件所在目

11、錄,一般為./run,進程文件為freeswitch.pidswitch_dir_make_recursive(SWITCH_GLOBAL_dirs.db_dir,SWITCH_DEFAULT_DIR_PERMS,runtime.memory_pool);/數(shù)據(jù)庫文件所在目錄,一般為./dbswitch_dir_make_recursive(SWITCH_GLOBAL_dirs.script_dir,SWITCH_DEFAULT_DIR_PERMS,runtime.memory_pool);/腳本文件所在目錄,一般為./script,存放系統(tǒng)需要執(zhí)行的腳本文件,/比較常用的由javascrip

12、t腳本和lua腳本。switch_dir_make_recursive(SWITCH_GLOBAL_dirs.htdocs_dir,SWITCH_DEFAULT_DIR_PERMS,runtime.memory_pool);switch_dir_make_recursive(SWITCH_GLOBAL_dirs.grammar_dir,SWITCH_DEFAULT_DIR_PERMS,runtime.memory_pool);switch_dir_make_recursive(SWITCH_GLOBAL_dirs.recordings_dir,SWITCH_DEFAULT_DIR_PERMS,

13、runtime.memory_pool);/錄音文件所在目錄switch_dir_make_recursive(SWITCH_GLOBAL_dirs.sounds_dir,SWITCH_DEFAULT_DIR_PERMS,runtime.memory_pool);/聲音文件所在目錄。switch_dir_make_recursive(SWITCH_GLOBAL_dirs.temp_dir,SWITCH_DEFAULT_DIR_PERMS,runtime.memory_pool);/臨時目錄。 全局的互斥變量和哈希表初始化,代碼片段如下:switch_mutex_init(&ru

14、ntime.uuid_mutex,SWITCH_MUTEX_NESTED,runtime.memory_pool);switch_mutex_init(&runtime.throttle_mutex,SWITCH_MUTEX_NESTED,runtime.memory_pool);switch_mutex_init(&runtime.session_hash_mutex,SWITCH_MUTEX_NESTED,runtime.memory_pool);switch_mutex_init(&runtime.global_mutex,SWITCH_M

15、UTEX_NESTED,runtime.memory_pool);switch_mutex_init(&runtime.global_var_mutex,SWITCH_MUTEX_NESTED,runtime.memory_pool);以及switch_core_hash_init(&runtime.global_vars,runtime.memory_pool);switch_core_hash_init(&runtime.mime_types,runtime.memory_pool); 系統(tǒng)相關的很重要的初始化1. switch_core_s

16、et_globals()由于在主函數(shù)中已經(jīng)設置好了各個安裝目錄,所以此次調用將不做任何實際意義的工作。2. switch_core_session_init(runtime.memory_pool)3. load_mime_types()4. gethostname(hostname,sizeof(hostname)摩取主機名5. switch_find_local_ip(guess_ip,sizeof(guess_ip),&mask,AF_INET)獲取主機的ip地址。這里主要是獲取ipv4的地址,下面還要重新調用一次該函數(shù)獲取ipv6的地址。6. switch_consol

17、e_init(runtime.memory_pool)初始化控制臺。函數(shù)的實際代碼如下:a)SWITCH_DECLARE(switch_status_t)switch_console_init(switch_memory_pool_t*pool)b) c)switch_mutex_init(&globals.func_mutex,SWITCH_MUTEX_NESTED,pool);d) switch_core_hash_init(&globals.func_hash,pool);e)switch_console_add_complete_func(":

18、console:list_uuid",(switch_console_complete_callback_t)switch_console_list_uuid);f) returnSWITCH_STATUS_SUCCESS;g) 7. switch_event_init(runtime.memory_pool)初始化freeswitch整個系統(tǒng)的事件機制,這個初始化很重要,在函數(shù)內部除了初始化一些互斥量,哈希隊列,還創(chuàng)建了三個用于事件循環(huán)的隊列,然后啟動三個線程,分別代表了三個隊列的時間循環(huán)處理線程。而所有的資源,都有runtime.memory_pool進行管理,event事件的循

19、環(huán)處理見后續(xù)分析。8. switch_xml_init(runtime.memory_pool,err)進行xml配置文件相關的初始化。9.switch_log_init(runtime.memory_pool,runtime.colorize_console)日志系統(tǒng)的初始化。10. switch_load_core_config("switch.conf")讀取全局的配置文件,然后根據(jù)該配置文件中的指令,依次讀取后續(xù)的子目錄下面的各個配置文件,詳見后續(xù)分析。11.switch_core_state_machine_init(runtime.memory_pool)sta

20、te_machine是整個FS系統(tǒng)的核心部位了,即通話狀態(tài)機,根據(jù)各個channel的狀態(tài)執(zhí)行相應的狀態(tài)處理函數(shù),見后續(xù)分析。此處的函數(shù)為空函數(shù)。12. switch_core_sqldb_start()sql數(shù)據(jù)庫的相關初始化。13. switch_rtp_init(runtime.memory_pool)rtp協(xié)議的初始化。函數(shù)內調用srtp_init()初始化rtp協(xié)議棧,freeswitch所用的rtp庫是libsrtp。14.switch_scheduler_add_task(switch_epoch_time_now(NULL),heartbeat_callback,"h

21、eartbeat","core",0,NULL,SSHF_NONE|SSHF_NO_DEL)在freeswitch中有一個task調度機制,這里講heartbeat加入到task隊列中。事件由switch_scheduler_task_container_t結構描述,在switch_scheduler.c中,通過全局的staticstructswitch_scheduler_task_container_t*task_list;switch_mutex_t*task_mutex;uint32_ttask_id;inttask_thread_running;swit

22、ch_memory_pool_t*memory_pool;globals;Globals變量對task隊列進行管理。Task的調度的線程也是在switch_core_init()中啟動的,具體的啟動函數(shù)時switch_scheduler_task_thread_start().該函數(shù)內部生成的線程主函數(shù)為switch_scheduler_task_thread():函數(shù)里有主循環(huán);while(globals.task_thread_running=1)if(task_thread_loop(0)break;switch_yield(500000);通過層層剝離,會進入task_thread_l

23、oop中一次執(zhí)行掛接在switch_scheduler.c中得全局globals的task隊列。switch_loadable_module_init()在switch_core_init_and_modload()中還調用了switch_loadable_module_init(),這里就是根據(jù)目錄信息加載各個動態(tài)模塊的地方了。函數(shù)定義在switch_loadable_module.c文件中,屬于核心組件的一部分。函數(shù)內根據(jù)平臺做了相關處理,在win32平臺下,還需要通過函數(shù)switch_loadable_module_path_init()獲取環(huán)境變量的相關信息。另外需要注意的是,該函數(shù)內

24、部重新重新生成了一個memory_pool不再是上面描述的runtime的memory_pool了。代碼如下:switch_core_new_memory_pool(&loadable_modules.pool);其中l(wèi)oadable_modules是一個文件作用域范圍的全局量,staticstructswitch_loadable_module_containerloadable_modules;類型為switch_loadable_module_container,定義如下:/*switch_loadable_module_container的定義*/*structswit

25、ch_loadable_module_containerswitch_hash_t*module_hash;/存放各個模塊結構的哈希表指針switch_hash_t*endpoint_hash;/存放各個endpoint_interface的哈希表指針switch_hash_t*codec_hash;/存放各個codec_interface的哈希表指針switch_hash_t*dialplan_hash;/存放各個diaplan_interface的哈希表指針switch_hash_t*timer_hash;/存放各個計時器的哈希表指針switch_hash_t*application_ha

26、sh;/存放各個application_interface的哈希表指針switch_hash_t*api_hash;/存放各個api_interface的哈希表指針switch_hash_t*file_hash;switch_hash_t*speech_hash;switch_hash_t*asr_hash;switch_hash_t*directory_hash;switch_hash_t*chat_hash;switch_hash_t*say_hash;switch_hash_t*management_hash;switch_mutex_t*mutex;/全局互斥量switch_memor

27、y_pool_t*pool;/用于模塊相關的apr內存池;該結構包含了若該的哈希表指針,分別指向存放各個接口結構的哈希表。/*/接下來函數(shù)初始化了用于存放各個接口的哈希表,以及全局互斥量。該函數(shù)是通過switch_loadable_module_load_module_ex(char*)SWITCH_GLOBAL_dirs.mod_dir,(char*)val,SWITCH_FALSE,global,&err)函數(shù)加載模塊的??梢娺@里使用到了模塊的目錄信息SWITCH_GLOBAL_dirs.mod_dir。switch_loadable_module_load_module_

28、ex()函數(shù)原型為:staticswitch_status_tswitch_loadable_module_load_module_ex(char*dir,char*fname,switch_bool_truntime,switch_bool_tglobal,constchar*err)這里講該函數(shù)頂定義成了一個static類型,只能在本文件中被調用。dir是上面?zhèn)€傳下來的目錄信息,fname是讀取配置文件得到的需要加載的動態(tài)對象名(例如mod_conference.dll,mod_sofia.dll或mod_conference.so,mod_sofia.so在該函數(shù)中,通過以下兩個函數(shù)完成

29、動態(tài)對象的加載:1. switch_loadable_module_load_file(path,file,global,&new_module),這里我是用了調用時的實參,globals并非上面提出的全局管理結構,而是一個SWITCH_STATUS的枚舉對象。Path是加上了路徑的完整文件名,而file仍然是配置文件中取得的名稱。New_module是一個秒速模塊的結構對象,具體的類型為a) structswitch_loadable_moduleb) char*key;c) char*filename;d) intperm;e)switch_loadable_module_

30、interface_t*module_interface;f) switch_dso_lib_tlib;g) switch_module_load_tswitch_module_load;h) switch_module_runtime_tswitch_module_runtime;i)switch_module_shutdown_tswitch_module_shutdown;j) switch_memory_pool_t*pool;k) switch_status_tstatus;l) switch_thread_t*thread;m) switch_bool_tshutting_down

31、;n) calltime_t*time_record;o);在switch_loadable_module_load_module_ex函數(shù)的開始出定義switch_loadable_module_t*new_module=NULL;在switch_loadable_module_load_file函數(shù)中,會為每一個模塊生成一個資源池switch_core_new_memory_pool(&pool);2. switch_loadable_module_process(file,new_module)函數(shù)主要是將new_module以及module中定義的各個接口結構加入全局哈

32、希表,在插入哈希表的過程中,由loadable_modules.mutex進行臨界保護,舉例如下:switch_core_hash_insert(loadable_modules.module_hash,key,new_module);/將new_module/插入loadable_modules.module_hash指向的哈希表。if(new_module->module_interface->endpoint_interface)constswitch_endpoint_interface_t*ptr;for(ptr=new_module->mo

33、dule_interface->endpoint_interface;ptr;ptr=ptr->next)switch_core_hash_insert(loadable_modules.endpoint_hash,ptr->interface_name,(constvoid*)ptr);/endif/若new_module的module_interface中包含endpoint_interface,則將該endpoint_interface插入全局的endpoint_interface哈希表。至此,模塊加載也結束了。各個模塊加載后各自進入自己的主線程

34、中循環(huán)處理。posted2012-11-2022:54einyboy閱讀(297)評論(0)編輯運行FreeSWITCH我建了一個Freeswitch內核研究交流群,45211986,歡迎加入,另外,提供基于SIP的通信服務器及客戶端解決方案。讀到本章,你應該對FreeSWITCH有了一個比較全面的了解,迫切地想實驗它強大的功能了。讓我們從最初的運行開始,一步一步進入FreeSWITCH的神秘世界。命令行參數(shù)一般來說,F(xiàn)reeSWITCH不需要任何命令行參數(shù)就可以啟動,但在某些情況下,你需要以一些特殊的參數(shù)啟動。在此,僅作簡單介紹。如果你知道是什么意思,那么你就可以使用,如果不知道,多半你用不

35、到。使用freeswitch-help或freeswitch-help會顯示以下信息:-nf-noforking-uuser-啟動后以非root用戶user身份運行-ggroup-啟動后以非root組group身份運行-help-顯示本幫助信息-version-顯示版本信息-waste-允許浪費內存,F(xiàn)reeSWITCH僅需240K的??臻g你可以使用ulimit-s240限制棧空間使用,或使用該選擇忽略警告信息-core-出錯時進行內核轉儲-hp-以高優(yōu)先級運行-vg-在valgrind下運行,調試內存泄露時使用-nosql-不使用SQL,showchannels類的命令將不能顯示結果-hea

36、vy-timer-更精確的時鐘。可能會更精確,但對系統(tǒng)要求更高-nonat-如果路由器支持uPnP或NAT-PMP,則FreeSWITCH可以自動解決NAT穿越問題。如果路由器不支持,則該選項可以使啟動更快-nocal-關閉時鐘核準。FreeSWTICH理想的運行環(huán)境是1000Hz的內核時鐘如果你的內核時鐘小于1000Hz或在虛擬機上,可以嘗試關閉該選項-nort-關閉實時時鐘-stop-關閉FreeSWTICH,它會在run目錄中查找PID文件-nc-c-啟動到后臺模式,沒有控制臺-啟動到控制臺,默認-confconfdir-指定其它的配置文件所在目錄,須與-log、-db合用-loglog

37、dir-指定其它的日志目錄-runrundir-指定其它存放PID文件的運行目錄- dbdbdir-指定其它數(shù)據(jù)庫目錄- modmoddir-指定其它模塊目錄- htdocshtdocsdir-指定其它HTTP根目錄-scripts scriptsdir- 指定其它腳本目錄系統(tǒng)啟動腳本在學習調試階段,你可以啟動到前臺,而系統(tǒng)真正運行時,你可以使用-nc參數(shù)啟動到后臺,然后通過查看log/freeswitch.log跟蹤系統(tǒng)運行情況(你可以用tail-f命令實時跟蹤,我一般使用less)。一般情況下,啟動到前臺更容易調試,但你又不想在每次關Terminal時停止FreeSWITCH,那么,你可以

38、借助screen來實現(xiàn)。在真正的生產(chǎn)系統(tǒng)上,你需要它能跟系統(tǒng)一起啟動。在*nix系統(tǒng)上,啟動腳本一般放在/etc/init.d/。你可以在系統(tǒng)源代碼目錄下找到不同系統(tǒng)啟動腳本debian/freeswitch.init及build/freeswitch.init.*,參考使用。在Windows上,你也可以注冊為Windows服務,參見附錄中的FAQ??刂婆_與命令客戶端系統(tǒng)不帶參數(shù)會啟動到控制臺,在控制臺上你可以輸入各種命令以控制或查詢FreeSWITCH的狀態(tài)。試試輸入以下命令:version-顯示當前版本status-顯示當前狀態(tài)sofiastatus-顯示sofia狀態(tài)help-顯示幫助為

39、了調試方便,F(xiàn)reeSWITCH還在conf/autoload_configs/switch.conf.xml中定義了一些控制臺快捷鍵。你可以通過F1-F12來使用它們(不過,在某些操作系統(tǒng)上,有些快捷鍵可能與操作系統(tǒng)的相沖突,那你就只直接輸入這些命令或重新定義他們了)。<cli-keybindings><keyname="1"value="help"/><keyname="2"value="status"/><key

40、name="3"value="showchannels"/><keyname="4"value="showcalls"/><keyname="5"value="sofiastatus"/><keyname="6"value="reloadxml"/><keyname="7"value="conso

41、leloglevel0"/><keyname="8"value="consoleloglevel7"/><keyname="9"value="sofiastatusprofileinternal"/><keyname="10"value="sofiaprofileinternalsiptraceon"/><keyname="11"val

42、ue="sofiaprofileinternalsiptraceoff"/><keyname="12"value="version"/></cli-keybindings>FreeSWITCH是Client-Server結構,不管FreeSWITCH運行在前臺還是后臺,你都可以使用客戶端軟件fs_cli連接FreeSWITCH.fs_cli是一個類似Telnet的客戶端(也類似于Asterisk中的asterisk-r命令),它使用FreeSWITCH的ESL(Ev

43、entSocketLibrary)庫與FreeSWITCH通信。當然,需要加載模塊mod_event_socket。該模塊是默認加載的。正常情況下,直接輸入bin/fs_cli即可連接上,并出現(xiàn)系統(tǒng)提示符。如果出現(xiàn):ERRORlibs/esl/fs_cli.c:652main()ErrorConnectingSocketConnectionError這樣的錯誤,說明FreeSWITCH沒有啟動或mod_event_socket沒有正確加載,請檢查TCP端口8021端口是否處于監(jiān)聽狀態(tài)或被其它進程占用。fs_cli也支持很多命令行參數(shù),值得一提的是-x參數(shù),它允許執(zhí)行一條命令后退出,這在編寫腳本

44、程序時非常有用(如果它能支持管道會更有用,但是它不支持):bin/fs/_cli-x"version"bin/fs/_cli-x"status"其它的參數(shù)都可以通過配置文件來實現(xiàn),在這里就不多說了??梢詤⒁姡?wiki/Fs_cli使用fs_cli,不僅可以連接到本機的FreeSWITCH,也可以連接到其它機器的FreeSWITCH上(或本機另外的FreeSWITCH實例上),通過在用戶主目錄下編輯配置文件.fs_cli_conf(注意前面的點".”),可以定義要連接的多個機器:server1h

45、ost=>0port=>8021password=>secret_passworddebug=>7server2host=>1port=>8021password=>someother_passworddebug=>0注意:如果要連接到其它機器,要確保FreeSWITCH的EventSocket是監(jiān)聽在真實網(wǎng)卡的IP地址上,而不是。另外,在UNIX中,以點開頭的文件是隱藏文件,普通的ls命令是不能列出它的,可以使用ls-a

46、。一旦配置好,就可以這樣使用它:bin/fs_cliserver1bin/fs_cliserver2在fs_cli中,有幾個特殊的命令,它們是以“/”開頭的,這些命令并不直接發(fā)送到FreeSWITCH,而是先由fs_cli處理。/quit、/bye、/exit、Ctrl+D都可以退出fs_cli;/help是幫助。其它一些“/”開頭的指令與EventSocket中相關的命令相同,如:/event-開啟事件接收/noevents-關閉事件接收/nixevent-除了特定一種外,開啟所有事件/log-設置log級別,如/loginfo或/logdebug等/nolog-關閉log/filter-過

47、濾事件另外,一些“重要”命令不能直接在fs_cli中執(zhí)行,如shutdown命令,在控制臺上可以直接執(zhí)行,但在fs_cli中,需要執(zhí)行fsctlshutdown。除此之外,其它命令都與直接在FreeSWITCH控制臺上執(zhí)行是一樣的。它也支持快捷鍵,最常用的快捷鍵是F6(reloadxml)、F7(關閉10g輸由)、F8(開啟debug級別的log輸出)。在*nix上,兩者都通過libeditline支持命令行編輯功能。可以通過上、下箭頭查看命令歷史。發(fā)起呼叫可以在FreeSWITCH中使用originate命令發(fā)起一次呼叫,如果用戶1000已經(jīng)注冊,那么:originateuser/alice

48、&echo上述命令在呼叫1000這個用戶后,便執(zhí)行echo這個程序。echo是一個回音程序,即它會把任何它“聽到”的聲音(或視頻)再返回(說)給對方。因此,如果這時候用戶1000接了電話,無論說什么都能聽到自己的聲音。呼叫字符串上面的例子中,user/alice稱為呼叫字符串,或呼叫URL。user是一種特殊的呼叫字符串。我們先來復習一下第四章的場景。FreeSWITCHUA的地址為:5050,aliceUA的地址為:5090,bobUA的地址為:26000。若alice已向FreeSWITCH注冊,在FreeS

49、WITCH中就可以看到她的注冊信息:freeswitchdu-sevens-mac-pro.local>sofiastatusprofileinternalregRegistrations:Call-ID:ZTRkYjdjYzY0OWFhNDRhOGFkNDUxMTdhMWJhNjRmNmE.User:aliceContact:"Alice"<sip:alice:5090;rinstance=a86a656037ccfaba;transport=UDP>Agent:Zoiperrev.54

50、15Status:Registered(UDP)(unknown)EXP(2010-05-0218:10:53)Host:du-sevens-mac-pro.localIP:Port:5090Auth-User:aliceAuth-Realm:MWI-Account:aliceFreeSWITCH根據(jù)Contact字段知道alice的SIP地址sip:alice:5090。當使用originate呼叫user/alice這個地址時,F(xiàn)reeSWITCH便查找本地數(shù)據(jù)庫,向alice的地址sip:alice1

51、:5090發(fā)送INVITE請求(實際的呼叫字符串是由用戶目錄中的dial-string參數(shù)決定的)。API與APP在上面的例子中,originate是一個命令(Command),它用于控制FreeSWITCH發(fā)起一個呼叫。FreeSWITCH的命令不僅可以在控制臺上使用,也可以在各種嵌入式腳本、EventSocket(fs_cli就是使用了ESL庫)或HTTPRPC上使用,所有命令都遵循一個抽像的接口,因而這些命令又稱APICommands。echo()則是一個程序(Application,簡稱APP),它的作用是控制一個Channel的一端。我們知道,一個Channel有

52、兩端,在上面的例子中,alice是一端,別一端就是echo()。電話接通后相當于alice在跟echo()這個家伙在通話。另一個常用的APP是park()originateuser/alice&park()我們初始化了一個呼叫,在alice接電話后對端必須有一個人在跟也講話,否則的話,一個Channel只有一端,那是不可思議的。而如果這時FreeSWITCH找不到一個合適的人跟alice通話,那么它可以將該電話“桂起”,park()便是執(zhí)行這個功能,它相當于一個Channel特殊的一端。park()的用戶體驗不好,alice不知道要等多長時間才有人接電話,由于她聽不到任何聲音,

53、實際上她在奇怪電話到底有沒有接通。相對而言,另一個程序hold()則比較友好,它能在等待的同時播放保持音樂(MOH,MusiconHold)。originateuser/alice&hold()當然,你也可以直接播放一個特定的聲音文件:originateuser/alice&playback(/root/welcome.wav)或者,直接錄音:originateuser/alice&record(/root/voice_of_alice.wav)以上的例子實際上都只是建立一個Channel,相當于FreeSWITCH作為一個UA跟alice通話。它是個一條腿(oneleg,只有a-leg)的通話。在大多數(shù)情況下,F(xiàn)reeSWITCH都是做為一個B2BUA來橋接兩個UA進行通話話的。在alice接聽電話以后,bridge()程序可以再啟動一個UA呼叫bob

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經(jīng)權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論