FreeSWITCH源碼分析之主函數main()






FreeSWITCH源碼分析之主函數main()





原創

2017年08月21日 16:19:54

        <ul class="article_tags clearfix csdn-tracking-statistics tracking-click" data-mod="popu_377" style="display: none;">
            <li class="tit">標籤:</li>







    Freeswitch的主函數是在文件switch.c中定義的,該文件的260行是整個程序的入口,主函數主要完成的功能是包括,命令行解析,初始化apr庫,構建全局內存池,模塊加載和初始化核心組件。

    初始化apr庫是由apr_initialize()函數完成的,apr庫是apache的可移植動態庫,完成相關的內存池,線程管理的跨平臺工作。該函數的調用在主函數的659行。

745行的switch_core_set_globals()主要是完成全局目錄的設置。不過,在switch_core_init()中再一次調用了該函數。

747行的pid= getpid()獲取程序的進程號。

754行利用apr_pool_create()創建一個匿名的內存池,由主函數中定義的switch_memory_pool_t*pool局部指針指向,但是可以知道,該內存池將作爲程序的整個運行週期所使用。

本分析最關鍵的一點出現在784行,該行調用了switch_core_init_and_modload()函數,該函數完成了核心組件的初始化以及各個模塊的動態加載。最終,形成了一個統一的系統。


switch_core_init_and_modload()

函數定義在switch_core.c文件中,第1526行。函數原型如下:

  1. SWITCH_DECLARE(switch_status_t)  
  2.   
  3. switch_core_init_and_modload(switch_core_flag_tflags, switch_bool_t console, const char **err)  
  4.   
  5. 其中,SWITCH_DECLARE(type)宏在windows下展開爲  
  6.   
  7. #define SWITCH_DECLARE(type) __declspec(dllexport) type __stdcall  
SWITCH_DECLARE(switch_status_t)

switch_core_init_and_modload(switch_core_flag_tflags, switch_bool_t console, const char **err)

其中,SWITCH_DECLARE(type)宏在windows下展開爲





#define SWITCH_DECLARE(type) __declspec(dllexport) type __stdcall

主要用於將函數聲明爲dll的導出符號,這樣,在其他模塊中,便可以使用該函數了。而在其他系統平臺上,該宏是一個空宏,例如在linux下,共享庫的符號是全局的,不需要聲明爲導出符號。一般來說,freeswitch其他的動態加載模塊所定義的函數不需要用該宏聲明,在windows平臺下,各個模塊之間是隔離的,而核心模塊中定義的函數大部分使用了該宏聲明,因爲其他模塊需要大量使用核心模塊中的核心函數,這裏所指的核心模塊是FreeSwitchCoreLib共享對象。


於是可以知道,switch_core_init_and_modload()函數可以在其他依賴於核心模塊的動態加載模塊中使用,這裏主函數所在的模塊是FreeSwitchConsole,依賴於核心模塊,於是,便可以使用該函數來完成模塊加載。


switch_core_init()

在該函數中調用了switch_core_init()函數,用來初始化一些全局化的信息,包括一個全局的switch_runtime結構,各種全局的哈希表,互斥變量。一條一條地分心如下:

①  全局的switch_runtime結構runtime部分字段的初始化——

代碼段如下:

  1. if(runtime.runlevel > 0) {  
  2.   
  3.     /* one percustomer */  
  4.   
  5.     returnSWITCH_STATUS_SUCCESS;  
  6.   
  7. }  
  8.   
  9.   
  10.   
  11. runtime.runlevel++;//從這裏可見,runlevel大於0是一個服務器已啓動的標誌,所以不必在進行  
  12.   
  13. //以下的初始化操作,直接返回SWITCH_STATUS_SUCCESS即可。  
  14.   
  15. runtime.dummy_cng_frame.data =runtime.dummy_data;  
  16.   
  17. runtime.dummy_cng_frame.datalen = sizeof(runtime.dummy_data);  
  18.   
  19. runtime.dummy_cng_frame.buflen = sizeof(runtime.dummy_data);  
  20.   
  21. switch_set_flag((&runtime.dummy_cng_frame),SFF_CNG);  
  22.   
  23.   
  24.   
  25. switch_set_flag((&runtime),SCF_NO_NEW_SESSIONS);  
  26.   
  27. runtime.hard_log_level = SWITCH_LOG_DEBUG;  
  28.   
  29. runtime.mailer_app = ”sendmail”;  
  30.   
  31. runtime.mailer_app_args = ”-t”;  
  32.   
  33. runtime.max_dtmf_duration =SWITCH_MAX_DTMF_DURATION;  
  34.   
  35. runtime.default_dtmf_duration =SWITCH_DEFAULT_DTMF_DURATION;  
  36.   
  37. runtime.min_dtmf_duration= SWITCH_MIN_DTMF_DURATION;  
     if(runtime.runlevel > 0) {

         /* one percustomer */

         returnSWITCH_STATUS_SUCCESS;

     }



     runtime.runlevel++;//從這裏可見,runlevel大於0是一個服務器已啓動的標誌,所以不必在進行

     //以下的初始化操作,直接返回SWITCH_STATUS_SUCCESS即可。

     runtime.dummy_cng_frame.data =runtime.dummy_data;

     runtime.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";

     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庫,很奇怪,不知道是不是一個多餘的步驟。^_^

 

  1. /* INIT APR andCreate the pool context */  
  2.   
  3. if(apr_initialize() != SWITCH_STATUS_SUCCESS) {  
  4.   
  5.     *err = ”FATALERROR! Could not initialize APR\n”;  
  6.   
  7.     returnSWITCH_STATUS_MEMERR;  
  8.   
  9. }  
  10.   
  11. if(!(runtime.memory_pool = switch_core_memory_init())) {  
  12.   
  13.     *err = ”FATALERROR! Could not allocate memory pool\n”;  
  14.   
  15.     returnSWITCH_STATUS_MEMERR;  
     /* INIT APR andCreate the pool context */

     if(apr_initialize() != SWITCH_STATUS_SUCCESS) {

         *err = "FATALERROR! Could not initialize APR\n";

         returnSWITCH_STATUS_MEMERR;

     }

     if(!(runtime.memory_pool = switch_core_memory_init())) {

         *err = "FATALERROR! Could not allocate memory pool\n";

         returnSWITCH_STATUS_MEMERR;
  1. <span style=“color:rgb(51,51,51);font-family:verdana, Arial, Helvetica, sans-serif;font-size:14px;”>}//從這裏可以看見,全局的runtime是有一個內存池來管理它所需要的其他資源的。</span>  
}//從這裏可以看見,全局的runtime是有一個內存池來管理它所需要的其他資源的。


②  安裝時的目錄信息的相關設置,與runtime結構掛鉤,代碼如下

  1. switch_dir_make_recursive(SWITCH_GLOBAL_dirs.base_dir,SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);//主目錄,即工程所在目錄,一般爲./bin,./表示安裝路徑  
  2.   
  3. switch_dir_make_recursive(SWITCH_GLOBAL_dirs.mod_dir,SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);//模塊所在目錄,一般爲安裝目錄./mod,./表示安裝路徑  
  4.   
  5. switch_dir_make_recursive(SWITCH_GLOBAL_dirs.conf_dir,SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);//配置文件所在目錄,一般爲./conf  
  6.   
  7. switch_dir_make_recursive(SWITCH_GLOBAL_dirs.log_dir,SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);//日誌所在的目錄。一般爲./log  
  8.   
  9. switch_dir_make_recursive(SWITCH_GLOBAL_dirs.run_dir,SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);//進程文件所在目錄,一般爲./run,進程文件爲freeswitch.pid  
  10.   
  11. switch_dir_make_recursive(SWITCH_GLOBAL_dirs.db_dir,SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);//數據庫文件所在目錄,一般爲./db  
  12.   
  13. switch_dir_make_recursive(SWITCH_GLOBAL_dirs.script_dir,SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);//腳本文件所在目錄,一般爲./script,存放系統需要執行的腳本文件,  
  14.   
  15. //比較常用的由javascript腳本和lua腳本。  
  16.   
  17. switch_dir_make_recursive(SWITCH_GLOBAL_dirs.htdocs_dir,SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);  
  18.   
  19. switch_dir_make_recursive(SWITCH_GLOBAL_dirs.grammar_dir,SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);  
  20.   
  21. switch_dir_make_recursive(SWITCH_GLOBAL_dirs.recordings_dir,SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);//錄音文件所在目錄  
  22.   
  23. switch_dir_make_recursive(SWITCH_GLOBAL_dirs.sounds_dir,SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);//聲音文件所在目錄。  
  24.   
  25. switch_dir_make_recursive(SWITCH_GLOBAL_dirs.temp_dir,SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);//臨時目錄。  
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_dirs.conf_dir,SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);//配置文件所在目錄,一般爲./conf

switch_dir_make_recursive(SWITCH_GLOBAL_dirs.log_dir,SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);//日誌所在的目錄。一般爲./log

switch_dir_make_recursive(SWITCH_GLOBAL_dirs.run_dir,SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);//進程文件所在目錄,一般爲./run,進程文件爲freeswitch.pid

switch_dir_make_recursive(SWITCH_GLOBAL_dirs.db_dir,SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);//數據庫文件所在目錄,一般爲./db

switch_dir_make_recursive(SWITCH_GLOBAL_dirs.script_dir,SWITCH_DEFAULT_DIR_PERMS, runtime.memory_pool);//腳本文件所在目錄,一般爲./script,存放系統需要執行的腳本文件,

//比較常用的由javascript腳本和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, 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);//臨時目錄。


③     全局的互斥變量和哈希表初始化,代碼片段如下:

  1.  switch_mutex_init(&runtime.uuid_mutex,SWITCH_MUTEX_NESTED, runtime.memory_pool);  
  2.   
  3.  switch_mutex_init(&runtime.throttle_mutex,SWITCH_MUTEX_NESTED, runtime.memory_pool);  
  4.   
  5.  switch_mutex_init(&runtime.session_hash_mutex,SWITCH_MUTEX_NESTED, runtime.memory_pool);  
  6.   
  7.  switch_mutex_init(&runtime.global_mutex,SWITCH_MUTEX_NESTED, runtime.memory_pool);  
  8.   
  9.  switch_mutex_init(&runtime.global_var_mutex,SWITCH_MUTEX_NESTED, runtime.memory_pool);  
  10.   
  11.   
  12.   
  13. switch_core_hash_init(&runtime.global_vars,runtime.memory_pool);  
  14.   
  15. switch_core_hash_init(&runtime.mime_types,runtime.memory_pool);  
     switch_mutex_init(&runtime.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_MUTEX_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);


 

④     系統相關的很重要的初始化

  1. 1.       switch_core_set_globals()  
  2.   
  3. 由於在主函數中已經設置好了各個安裝目錄,所以此次調用將不做任何實際意義的工作。  
  4.   
  5. 2.       switch_core_session_init(runtime.memory_pool)  
  6.   
  7. 3.       load_mime_types()  
  8.   
  9. 4.       gethostname(hostname, sizeof(hostname))獲取主機名  
  10.   
  11. 5.       switch_find_local_ip(guess_ip,sizeof(guess_ip), &mask, AF_INET)獲取主機的ip地址。這裏主要是獲取ipv4的地址,下面還要重新調用一次該函數獲取ipv6的地址。  
  12.   
  13. 6.        switch_console_init(runtime.memory_pool)初始化控制檯。函數的實際代碼如下:  
  14.   
  15. a)   SWITCH_DECLARE(switch_status_t)switch_console_init(switch_memory_pool_t *pool)  
  16.   
  17. b)   {  
  18.   
  19. c)    switch_mutex_init(&globals.func_mutex,SWITCH_MUTEX_NESTED, pool);  
  20.   
  21. d)    switch_core_hash_init(&globals.func_hash,pool);  
  22.   
  23. e)    switch_console_add_complete_func(”::console::list_uuid”,(switch_console_complete_callback_t) switch_console_list_uuid);  
  24.   
  25. f)    returnSWITCH_STATUS_SUCCESS;  
  26.   
  27. g)        }  
  28.   
  29. 7.       switch_event_init(runtime.memory_pool)初始化freeswitch整個系統的事件機制,這個初始化很重要,在函數內部除了初始化一些互斥量,哈希隊列,還創建了三個用於事件循環的隊列,然後啓動三個線程,分別代表了三個隊列的時間循環處理線程。而所有的資源,都有runtime.memory_pool進行管理,event事件的循環處理見後續分析。  
  30.   
  31. 8.       switch_xml_init(runtime.memory_pool,err)進行xml配置文件相關的初始化。  
  32.   
  33. 9.       switch_log_init(runtime.memory_pool,runtime.colorize_console)日誌系統的初始化。  
  34.   
  35. 10.    switch_load_core_config(”switch.conf”)讀取全局的配置文件,然後根據該配置文件中的指令,依次讀取後續的子目錄下面的各個配置文件,詳見後續分析。  
  36.   
  37. 11.    switch_core_state_machine_init(runtime.memory_pool)state_machine是整個FS系統的核心部位了,即通話狀態機,根據各個channel的狀態執行相應的狀態處理函數,見後續分析。此處的函數爲空函數。  
  38.   
  39. 12.    switch_core_sqldb_start()sql數據庫的相關初始化。  
  40.   
  41. 13.    switch_rtp_init(runtime.memory_pool)rtp協議的初始化。函數內調用srtp_init()初始化rtp協議棧,freeswitch所用的rtp庫是libsrtp。  
  42.   
  43. 14.    switch_scheduler_add_task(switch_epoch_time_now(NULL),heartbeat_callback, ”heartbeat”“core”, 0, NULL, SSHF_NONE |SSHF_NO_DEL)  
1.       switch_core_set_globals()

由於在主函數中已經設置好了各個安裝目錄,所以此次調用將不做任何實際意義的工作。

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的地址,下面還要重新調用一次該函數獲取ipv6的地址。

6.        switch_console_init(runtime.memory_pool)初始化控制檯。函數的實際代碼如下:

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("::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整個系統的事件機制,這個初始化很重要,在函數內部除了初始化一些互斥量,哈希隊列,還創建了三個用於事件循環的隊列,然後啓動三個線程,分別代表了三個隊列的時間循環處理線程。而所有的資源,都有runtime.memory_pool進行管理,event事件的循環處理見後續分析。

8.       switch_xml_init(runtime.memory_pool,err)進行xml配置文件相關的初始化。

9.       switch_log_init(runtime.memory_pool,runtime.colorize_console)日誌系統的初始化。

10.    switch_load_core_config("switch.conf")讀取全局的配置文件,然後根據該配置文件中的指令,依次讀取後續的子目錄下面的各個配置文件,詳見後續分析。

11.    switch_core_state_machine_init(runtime.memory_pool)state_machine是整個FS系統的核心部位了,即通話狀態機,根據各個channel的狀態執行相應的狀態處理函數,見後續分析。此處的函數爲空函數。

12.    switch_core_sqldb_start()sql數據庫的相關初始化。

13.    switch_rtp_init(runtime.memory_pool)rtp協議的初始化。函數內調用srtp_init()初始化rtp協議棧,freeswitch所用的rtp庫是libsrtp。

14.    switch_scheduler_add_task(switch_epoch_time_now(NULL),heartbeat_callback, "heartbeat", "core", 0, NULL, SSHF_NONE |SSHF_NO_DEL)


在freeswitch中有一個task調度機制,這裏講heartbeat加入到task隊列中。事件由

  1. switch_scheduler_task_container_t結構描述,在switch_scheduler.c中,通過全局的  
  2.   
  3. static struct {  
  4.   
  5. switch_scheduler_task_container_t*task_list;  
  6.   
  7. switch_mutex_t*task_mutex;  
  8.   
  9. uint32_t task_id;  
  10.   
  11. int task_thread_running;  
  12.   
  13. switch_memory_pool_t *memory_pool;  
  14.   
  15. } globals;  
switch_scheduler_task_container_t結構描述,在switch_scheduler.c中,通過全局的

static struct {

switch_scheduler_task_container_t*task_list;

switch_mutex_t*task_mutex;

uint32_t task_id;

int task_thread_running;

switch_memory_pool_t *memory_pool;

} globals;


 

Globals變量對task隊列進行管理。Task的調度的線程也是在switch_core_init()中啓動的,具體的啓動函數時switch_scheduler_task_thread_start().該函數內部生成的線程主函數爲switch_scheduler_task_thread():函數裏有主循環;

  1. while (globals.task_thread_running == 1) {  
  2.   
  3.          if(task_thread_loop(0)) {  
  4.   
  5.               break;  
  6.   
  7.          }  
  8.   
  9.          switch_yield(500000);  
  10.   
  11. }  
while (globals.task_thread_running == 1) {

         if(task_thread_loop(0)) {

              break;

         }

         switch_yield(500000);

}


通過層層剝離,會進入task_thread_loop中一次執行掛接在switch_scheduler.c中得全局globals的task隊列。

  

switch_loadable_module_init()

在switch_core_init_and_modload()中還調用了switch_loadable_module_init(),這裏就是根據目錄信息加載各個動態模塊的地方了。函數定義在switch_loadable_module.c文件中,屬於核心組件的一部分。

 

函數內根據平臺做了相關處理,在win32平臺下,還需要通過函數switch_loadable_module_path_init()獲取環境變量的相關信息。另外需要注意的是,該函數內部重新重新生成了一個memory_pool不再是上面描述的runtime的memory_pool了。代碼如下:

  1. switch_core_new_memory_pool(&loadable_modules.pool);  
  2.   
  3. 其中loadable_modules是一個文件作用域範圍的全局量,  
  4.   
  5. static structswitch_loadable_module_container loadable_modules;類型爲  
  6.   
  7. switch_loadable_module_container,定義如下:  
  8.   
  9. //************* switch_loadable_module_container的定義*****************************//  
  10.   
  11. structswitch_loadable_module_container {  
  12.   
  13. switch_hash_t *module_hash;//存放各個模塊結構的哈希表指針  
  14.   
  15. switch_hash_t *endpoint_hash;// 存放各個endpoint_interface的哈希表指針  
  16.   
  17. switch_hash_t *codec_hash; // 存放各個codec_interface的哈希表指針  
  18.   
  19. switch_hash_t *dialplan_hash; // 存放各個diaplan_interface的哈希表指針  
  20.   
  21. switch_hash_t *timer_hash;// // 存放各個計時器的哈希表指針  
  22.   
  23. switch_hash_t *application_hash;//存放各個application_interface的哈希表指針  
  24.   
  25. switch_hash_t *api_hash; // 存放各個api_interface的哈希表指針  
  26.   
  27. switch_hash_t *file_hash;  
  28.   
  29. switch_hash_t *speech_hash;  
  30.   
  31. switch_hash_t *asr_hash;  
  32.   
  33. switch_hash_t *directory_hash;  
  34.   
  35. switch_hash_t *chat_hash;  
  36.   
  37. switch_hash_t *say_hash;  
  38.   
  39. switch_hash_t *management_hash;  
  40.   
  41. switch_mutex_t *mutex;//全局互斥量  
  42.   
  43. switch_memory_pool_t *pool;//用於模塊相關的apr內存池  
  44.   
  45. };  
switch_core_new_memory_pool(&loadable_modules.pool);

其中loadable_modules是一個文件作用域範圍的全局量,

static structswitch_loadable_module_container loadable_modules;類型爲

switch_loadable_module_container,定義如下:

//************* switch_loadable_module_container的定義*****************************//

structswitch_loadable_module_container {

switch_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_hash;//存放各個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_memory_pool_t *pool;//用於模塊相關的apr內存池

};


該結構包含了若該的哈希表指針,分別指向存放各個接口結構的哈希表。

//***********************************************************************************//

 

接下來函數初始化了用於存放各個接口的哈希表,以及全局互斥量。

 

該函數是通過switch_loadable_module_load_module_ex((char *) SWITCH_GLOBAL_dirs.mod_dir, (char *) val, SWITCH_FALSE, global, &err)函數加載模塊的。可見這裏使用到了模塊的目錄信息SWITCH_GLOBAL_dirs.mod_dir。

 

 

switch_loadable_module_load_module_ex()

函數原型爲:

static switch_status_t switch_loadable_module_load_module_ex(char *dir, char*fname, switch_bool_t runtime, switch_bool_t global, constchar **err)

這裏講該函數頂定義成了一個static類型,只能在本文件中被調用。dir是上面個傳下來的目錄信息,fname是讀取配置文件得到的需要加載的動態對象名(例如mod_conference.dll,mod_sofia.dll或mod_conference.so,mod_sofia.so等)

 

在該函數中,通過以下兩個函數完成動態對象的加載:

1.  switch_loadable_module_load_file(path,file, global, &new_module),這裏我是用了調用時的實參,globals並非上面提出的全局管理結構,而是一個SWITCH_STATUS的枚舉對象。Path是加上了路徑的完整文件名,而file仍然是配置文件中取得的名稱。New_module是一個秒速模塊的結構對象,具體的類型爲

  1. a)   struct switch_loadable_module {  
  2.   
  3. b)        char *key;  
  4.   
  5. c)        char*filename;  
  6.   
  7. d)        int perm;  
  8.   
  9. e)        switch_loadable_module_interface_t*module_interface;  
  10.   
  11. f)        switch_dso_lib_t lib;  
  12.   
  13. g)        switch_module_load_t switch_module_load;  
  14.   
  15. h)        switch_module_runtime_tswitch_module_runtime;  
  16.   
  17. i)        switch_module_shutdown_tswitch_module_shutdown;  
  18.   
  19. j)        switch_memory_pool_t *pool;  
  20.   
  21. k)        switch_status_t status;  
  22.   
  23. l)        switch_thread_t *thread;  
  24.   
  25. m)        switch_bool_t shutting_down;  
  26.   
  27. n)        calltime_t *time_record;  
  28.   
  29. o)   };  
a)   struct switch_loadable_module {

b)        char *key;

c)        char*filename;

d)        int perm;

e)        switch_loadable_module_interface_t*module_interface;

f)        switch_dso_lib_t lib;

g)        switch_module_load_t switch_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_t status;

l)        switch_thread_t *thread;

m)        switch_bool_t shutting_down;

n)        calltime_t *time_record;

o)   };


在switch_loadable_module_load_module_ex函數的開始出定義 

switch_loadable_module_t*new_module = NULL;

在switch_loadable_module_load_file函數中,會爲每一個模塊生成一個資源池

switch_core_new_memory_pool(&pool);

2.  switch_loadable_module_process(file,new_module)函數主要是將new_module以及module中定義的各個接口結構加入全局哈希表,在插入哈希表的過程中,由loadable_modules.mutex進行臨界保護,舉例如下:

  1. ①   switch_core_hash_insert(loadable_modules.module_hash, key,new_module);//將new_module  
  2.   
  3. //插入loadable_modules.module_hash指向的哈希表。  
  4.   
  5. ②   if (new_module->module_interface->endpoint_interface){  
  6.   
  7. constswitch_endpoint_interface_t *ptr;  
  8.   
  9.           for (ptr =new_module->module_interface->endpoint_interface; ptr; ptr =ptr->next) {  
  10.   
  11. switch_core_hash_insert(loadable_modules.endpoint_hash,ptr->interface_name, (const void *) ptr);  
  12.   
  13. }//end if  
①   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->module_interface->endpoint_interface; ptr; ptr =ptr->next) {

switch_core_hash_insert(loadable_modules.endpoint_hash,ptr->interface_name, (const void *) ptr);

}//end if


//若new_module的module_interface中包含endpoint_interface,則將該endpoint_interface插入全局的endpoint_interface哈希表。

至此,模塊加載也結束了。各個模塊加載後各自進入自己的主線程中循環處理。

                </div>
</article>
  <div class="readall_box csdn-tracking-statistics tracking-click readall_box_nobg" data-mod="popu_376" style="display: none;">
      <div class="read_more_mask"></div>
      <a class="btn btn-large btn-gray-fred read_more_btn" target="_self">閱讀全文</a>
  </div>
  <div class="article_copyright">

          </div>
  <ul class="article_collect clearfix csdn-tracking-statistics tracking-click" data-mod="popu_378" style="display: none;">
      <li class="tit">本文已收錄於以下專欄:</li>




                  <form action="//blog.csdn.net/y_xianjun/phoenix/comment/submit?id=77451174" method="post" onsubmit="return subform(this);" id="commentform">
                      <textarea class="comment_content" name="comment_content" id="comment_content" placeholder="嚴禁討論涉及中國之軍/政相關話題,違者會被禁言、封號!" style="height: 28px;"></textarea>
                      <div class="bot_bar clearfix" style="opacity: 0;">
                          <div id="ubbtools" class="add_code">
                              <a href="#insertcode" code="code" target="_self"><i class="icon iconfont icon-daima"></i></a>
                          </div>

                          <input type="hidden" id="comment_replyId" name="comment_replyId">
                          <input type="hidden" id="comment_userId" name="comment_userId" value="">
                          <input type="hidden" id="commentId" name="commentId" value="">
                          <input type="submit" class="btn btn-redborder" value="發表評論">
                          <span id="tip_comment" class="tip">
                          <div style="display: none;" class="csdn-tracking-statistics tracking-click" data-mod="popu_384"><a href="#" target="_blank" class="comment_area_btn">發表評論</a></div>

                          <div id="lang_list" code="code">
                              <a href="#html" style="width:95px;" class="long_name" target="_self">HTML/XML</a>
                              <a href="#objc" style="width:95px;" class="long_name" target="_self">objective-c</a>
                              <a href="#delphi" style="width:58px;" class="zhong_name" target="_self">Delphi</a>
                              <a href="#ruby" class="zhong_name" target="_self">Ruby</a>
                              <a href="#php" target="_self">PHP</a>
                              <a href="#csharp" class="duan_name" target="_self">C#</a>
                              <a style=" border-right: none;" href="#cpp" class="duan_name" target="_self">C++</a>
                              <a style=" border-bottom:none;width:95px;" href="#javascript" class="long_name" target="_self">JavaScript</a>
                              <a style=" border-bottom:none;width:95px;" href="#vb" class="long_name" target="_self">Visual Basic</a>
                              <a style=" border-bottom:none;" href="#python" class="zhong_name" target="_self">Python</a>
                              <a style=" border-bottom:none;" href="#java" class="zhong_name" target="_self">Java</a>
                              <a style="border-bottom:none;" href="#css" class="duan_name" target="_self">CSS</a>
                              <a style="border-bottom:none;" href="#sql" class="duan_name" target="_self">SQL</a>
                              <a style="border:none; " href="#plain" class="duan_name" target="_self">其它</a>
                              <span class="arrb"></span>
                          </div>
                      </span></div>
                  </form>
              </div>
                          </div>
      </div>
  </div>
  <div class="comment_li_outbox"></div>

  <div class="more_comment" style="display: none;">
      <div id="comment_bar" class="trackgin-ad" data-mod="popu_385"></div>
  </div>

  <!-- <h3 class="recommend_tit" id="related">相關文章推薦</h3> -->
  <div class="recommend_list clearfix" id="rasss">
                                      <dl class="clearfix csdn-tracking-statistics recommend_article recommend_article_out" data-mod="popu_387" data-poputype="feed" data-feed-show="true" data-dsm="post">
            <a href="http://blog.csdn.net/educast/article/details/17970117" target="_blank" strategy="BlogCommendFromBaidu_0">
                <dd>
                    <h2 style="margin-bottom: 0px;">FreeSWITCH代碼分析</h2>
                    <ul class="floatR">
                        <li class="avatar_img"><img src="//avatar.csdn.net/C/8/E/3_educast.jpg" alt="educast" title="educast"></li>
                        <li class="user_name">educast</li>
                        <li class="time">2014年01月07日 21:40</li>
                        <li class="visited_num"><i class="icon iconfont icon-read"></i><span>9363</span></li>
                    </ul><div class="summary">
                        什麼是FreeSWITCH

FreeSWITCH 是一個可擴展的開源跨平臺的電話平臺,支持音頻、視頻、文本或任何其他形式的媒體使用的協議的路由與交互。它於2006年成立。FreeSWITCH也提…

                </dd>
            </a>
        </dl>
                                                <dl class="clearfix csdn-tracking-statistics recommend_article recommend_article_out" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
            <a href="http://blog.csdn.net/L_yangliu/article/details/46457203" target="_blank" strategy="BlogCommendFromBaidu_1">
                <dd>
                    <h2 style="margin-bottom: 0px;">freeswitch源碼研究</h2>
                    <ul class="floatR">
                        <li class="avatar_img"><img src="//avatar.csdn.net/5/6/5/3_l_yangliu.jpg" alt="L_yangliu" title="L_yangliu"></li>
                        <li class="user_name">L_yangliu</li>
                        <li class="time">2015年06月11日 14:24</li>
                        <li class="visited_num"><i class="icon iconfont icon-read"></i><span>1769</span></li>
                    </ul><div class="summary">
                        熟悉的過程:

switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, “Activate Eventing Engine.\n”);
將日誌輸…

                </dd>
            </a>
        </dl>
                                      <dl class="">
        <script>
        (function() {
          var s = "_" + Math.random().toString(36).slice(2);
          document.write('<div id="' + s + '"></div>');
          (window.slotbydup=window.slotbydup || []).push({
            id: '4765209',
            container: s,
            size: '808,120',
            display: 'inlay-fix'
          });
        })();
        </script><div id="_f1arky7oz3fx8s2rm9m5cdi"></div><script charset="utf-8" src="http://pos.baidu.com/ncfm?di=4765209&amp;dri=0&amp;dis=0&amp;dai=0&amp;ps=9982x243&amp;enu=encoding&amp;dcb=___adblockplus&amp;dtm=SSP_JSONP&amp;dvi=0.0&amp;dci=-1&amp;dpt=none&amp;tsr=0&amp;tpr=1521083181316&amp;ti=FreeSWITCH%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E4%B9%8B%E4%B8%BB%E5%87%BD%E6%95%B0main()%20-%20CSDN%E5%8D%9A%E5%AE%A2&amp;ari=2&amp;dbv=2&amp;drs=1&amp;pcs=1522x709&amp;pss=1522x10016&amp;cfv=0&amp;cpl=31&amp;chi=1&amp;cce=true&amp;cec=UTF-8&amp;tlm=1521083181&amp;rw=709&amp;ltu=http%3A%2F%2Fblog.csdn.net%2Fy_xianjun%2Farticle%2Fdetails%2F77451174&amp;ltr=http%3A%2F%2Fblog.csdn.net%2Fl_yangliu%2Farticle%2Fdetails%2F46457203&amp;ecd=1&amp;uc=1920x1040&amp;pis=-1x-1&amp;sr=1920x1080&amp;tcn=1521083181"></script><iframe scrolling="no" style="width: 100%; height: 113px; border: 0px;"></iframe>
      </dl>
                                    <dl class="clearfix csdn-tracking-statistics recommend_article recommend_article_out" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
            <a href="http://blog.csdn.net/Neohan/article/details/48288491" target="_blank" strategy="BlogCommendFromBaidu_2">
                <dd>
                    <h2>FreeSWITCH - mod_xml_rpc源碼分析七server.c</h2>
                    <div class="summary">
                        xcx                        </div>

                    <ul>
                        <li class="avatar_img"><img src="//avatar.csdn.net/E/9/4/3_neohan.jpg" alt="Neohan" title="Neohan"></li>
                        <li class="user_name">Neohan</li>
                        <li class="time">2015年10月07日 10:15</li>
                        <li class="visited_num"><i class="icon iconfont icon-read"></i><span>737</span></li>
                    </ul>
                </dd>
            </a>
        </dl>
                                                <dl class="clearfix csdn-tracking-statistics recommend_article recommend_article_out" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
            <a href="http://blog.csdn.net/luozirong/article/details/78881825" target="_blank" strategy="BlogCommendFromBaidu_3">
                <dd>
                    <h2>freeswitch mrcp 源碼分析--event事件產生</h2>
                    <div class="summary">
                        event事件的構建主要在speech_thread()函數裏面。static void *SWITCH_THREAD_FUNC speech_thread(switch_thread_t *thre...                        </div>

                    <ul>
                        <li class="avatar_img"><img src="//avatar.csdn.net/7/C/5/3_luozirong.jpg" alt="luozirong" title="luozirong"></li>
                        <li class="user_name">luozirong</li>
                        <li class="time">2017年12月23日 19:52</li>
                        <li class="visited_num"><i class="icon iconfont icon-read"></i><span>235</span></li>
                    </ul>
                </dd>
            </a>
        </dl>
                                                <dl class="clearfix csdn-tracking-statistics recommend_article recommend_article_out" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
            <a href="http://blog.csdn.net/luozirong/article/details/78876787" target="_blank" strategy="BlogCommendFromBaidu_4">
                <dd>
                    <h2>freeswitch mrcp 源碼分析--數據接收(下)</h2>
                    <div class="summary">
                        在前兩篇我們介紹了mrcp接收後的處理,最後會調用apr_queue_push扔到消息隊列裏面。 

對應的,在apt_consumer_task.apt_consumer_task_run()中會循環…

                    <ul>
                        <li class="avatar_img"><img src="//avatar.csdn.net/7/C/5/3_luozirong.jpg" alt="luozirong" title="luozirong"></li>
                        <li class="user_name">luozirong</li>
                        <li class="time">2017年12月22日 21:03</li>
                        <li class="visited_num"><i class="icon iconfont icon-read"></i><span>247</span></li>
                    </ul>
                </dd>
            </a>
        </dl><dl id="yd_a_d_feed_5" class="yd_a_d_feed_cla" style="height:124px;overflow: hidden;"><iframe scrolling="no" style="width: 100%; height: 90px; border: 0px;"></iframe></dl>
                                                <dl class="clearfix csdn-tracking-statistics recommend_article recommend_article_out" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
            <a href="http://blog.csdn.net/y_xianjun/article/details/47107393" target="_blank" strategy="BlogCommendFromBaidu_5">
                <dd>
                    <h2>軟交換FreeSWITCH系統概要和源代碼分析預備知識</h2>
                    <div class="summary">
                        asterisk與freeswitch的比較:

1:Asterisk是針對1百人以下的小型系統,相同的硬件配置下單系統最多併發200路,而根據國外愛好者測試freeswitch可達到2000-300…

                    <ul>
                        <li class="avatar_img"><img src="//avatar.csdn.net/B/5/1/3_y_xianjun.jpg" alt="y_xianjun" title="y_xianjun"></li>
                        <li class="user_name">y_xianjun</li>
                        <li class="time">2015年07月28日 16:35</li>
                        <li class="visited_num"><i class="icon iconfont icon-read"></i><span>799</span></li>
                    </ul>
                </dd>
            </a>
        </dl>
                                                <dl class="clearfix csdn-tracking-statistics recommend_article recommend_article_out" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
            <a href="http://blog.csdn.net/turbocc/article/details/78900178" target="_blank" strategy="BlogCommendFromBaidu_6">
                <dd>
                    <h2 style="margin-bottom: 0px;">freeswitch代碼分析筆記</h2>
                    <ul class="floatR">
                        <li class="avatar_img"><img src="//avatar.csdn.net/F/1/4/3_turbocc.jpg" alt="turbocc" title="turbocc"></li>
                        <li class="user_name">turbocc</li>
                        <li class="time">2017年12月26日 11:10</li>
                        <li class="visited_num"><i class="icon iconfont icon-read"></i><span>117</span></li>
                    </ul><div class="summary">
                        一、main分析

1.調用switch_core_init_and_modload加載模塊
->建立內存池switch_core_new_memory_pool(&loadable_modules…

                </dd>
            </a>
        </dl>
                                                <dl class="clearfix csdn-tracking-statistics recommend_article recommend_article_out" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
            <a href="http://blog.csdn.net/zoutian007/article/details/7772020" target="_blank" strategy="BlogCommendFromBaidu_7">
                <dd>
                    <h2 style="margin-bottom: 0px;">如何看懂源代碼–(分析源代碼方法)</h2>
                    <ul class="floatR">
                        <li class="avatar_img"><img src="//avatar.csdn.net/E/3/4/3_zoutian007.jpg" alt="zoutian007" title="zoutian007"></li>
                        <li class="user_name">zoutian007</li>
                        <li class="time">2012年07月22日 10:53</li>
                        <li class="visited_num"><i class="icon iconfont icon-read"></i><span>2193</span></li>
                    </ul><div class="summary">
                        我們在寫程式時,有不少時間都是在看別人的代碼。例如看小組的代碼,看小組整合的守則,若一開始沒規劃怎麼看,

就會“嚕看嚕苦(臺語) ”

不管是參考也好,從開源抓下來研究也好,爲了瞭解箇中含意,在…

                </dd>
            </a>
        </dl>
                                                <dl class="clearfix csdn-tracking-statistics recommend_article recommend_article_out" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
            <a href="http://blog.csdn.net/educast/article/details/17969985" target="_blank" strategy="BlogCommendFromBaidu_8">
                <dd>
                    <h2>軟交換freeswitch系統概要和源代碼分析初步</h2>
                    <div class="summary">
                        asterisk與freeswitch的比較:

1:Asterisk是針對1百人以下的小型系統,相同的硬件配置下單系統最多併發200路,而根據國外愛好者測試freeswitch可達到2000-300…

                    <ul>
                        <li class="avatar_img"><img src="//avatar.csdn.net/C/8/E/3_educast.jpg" alt="educast" title="educast"></li>
                        <li class="user_name">educast</li>
                        <li class="time">2014年01月07日 21:34</li>
                        <li class="visited_num"><i class="icon iconfont icon-read"></i><span>3675</span></li>
                    </ul>
                </dd>
            </a>
        </dl>
                                                <dl class="clearfix csdn-tracking-statistics downloadElement" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
            <a class="clearfix" href="https://download.csdn.net/download/luolaigen2008/4067404" target="_blank" strategy="BlogCommendFromBaidu_9">
                <dd class="floatL">
                    <div class="summary">
                        <h2>Freeswitch軟件架構分析</h2>
                        <div class="summary">
                            <ul>
                                <li class="time">2012年02月16日 12:57</li>
                                <li class="visited_num fileSize">840KB</li>
                                <li class="download_btn">下載</li>
                            </ul>
                        </div>
                    </div>
                </dd>
                <dt class="floatR"><img class="maxwidth" src="http://csdnimg.cn/release/download/old_static/images/minetype/doc.svg" alt="" title=""></dt>
            </a>
        </dl>
                                                              <dl class="clearfix csdn-tracking-statistics recommend_article recommend_article_out" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
            <a href="http://blog.csdn.net/luozirong/article/details/78857016" target="_blank" strategy="BlogCommendFromBaidu_10">
                <dd>
                    <h2 style="margin-bottom: 0px;">freeswitch mrcp 源碼分析--數據解析</h2>
                    <ul class="floatR">
                        <li class="avatar_img"><img src="//avatar.csdn.net/7/C/5/3_luozirong.jpg" alt="luozirong" title="luozirong"></li>
                        <li class="user_name">luozirong</li>
                        <li class="time">2017年12月20日 20:12</li>
                        <li class="visited_num"><i class="icon iconfont icon-read"></i><span>214</span></li>
                    </ul><div class="summary">
                        /** Parse message by raising corresponding event handlers */

APT_DECLARE(apt_message_status_e) apt_m…

                </dd>
            </a>
        </dl><div id="yd_a_d_feed_11" class="yd_a_d_feed_cla" style="height:124px;overflow: hidden;"><div id="BAIDU_SSP__wrapper_u3203594_0"><iframe id="iframeu3203594_0" name="iframeu3203594_0" src="http://pos.baidu.com/ncfm?conwid=920&amp;conhei=117&amp;rdid=3203594&amp;dc=3&amp;di=u3203594&amp;dri=0&amp;dis=0&amp;dai=4&amp;ps=10997x223&amp;enu=encoding&amp;dcb=___adblockplus&amp;dtm=HTML_POST&amp;dvi=0.0&amp;dci=-1&amp;dpt=none&amp;tsr=0&amp;tpr=1521083181316&amp;ti=FreeSWITCH%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E4%B9%8B%E4%B8%BB%E5%87%BD%E6%95%B0main()%20-%20CSDN%E5%8D%9A%E5%AE%A2&amp;ari=2&amp;dbv=2&amp;drs=3&amp;pcs=1522x709&amp;pss=1522x12385&amp;cfv=0&amp;cpl=31&amp;chi=1&amp;cce=true&amp;cec=UTF-8&amp;tlm=1521083181&amp;rw=709&amp;ltu=http%3A%2F%2Fblog.csdn.net%2Fy_xianjun%2Farticle%2Fdetails%2F77451174&amp;ltr=http%3A%2F%2Fblog.csdn.net%2Fl_yangliu%2Farticle%2Fdetails%2F46457203&amp;ecd=1&amp;uc=1920x1040&amp;pis=-1x-1&amp;sr=1920x1080&amp;tcn=1521083182&amp;qn=a9ce559d29ffdbaa&amp;tt=1521083181148.842.842.843" width="920" height="117" align="center,center" vspace="0" hspace="0" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" style="border:0;vertical-align:bottom;margin:0;width:920px;height:117px" allowtransparency="true"></iframe></div><script type="text/javascript">var cpro_id = "u3203594";</script><script type="text/javascript" src="//cpro.baidustatic.com/cpro/ui/c.js"></script></div>
                                                <dl class="clearfix csdn-tracking-statistics recommend_article recommend_article_out" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
            <a href="http://blog.csdn.net/wh8_2011/article/details/53064977" target="_blank" strategy="BlogCommendFromBaidu_11">
                <dd>
                    <h2 style="margin-bottom: 0px;">linux內核奇遇記之md源代碼解讀之一</h2>
                    <ul class="floatR">
                        <li class="avatar_img"><img src="//avatar.csdn.net/D/4/6/3_wh8_2011.jpg" alt="wh8_2011" title="wh8_2011"></li>
                        <li class="user_name">wh8_2011</li>
                        <li class="time">2016年11月07日 11:49</li>
                        <li class="visited_num"><i class="icon iconfont icon-read"></i><span>313</span></li>
                    </ul><div class="summary">
                        linux內核奇遇記之md源代碼解讀之一

轉載請註明出處:http://blog.csdn.net/liumangxiong
最近花了一段時間認真地學習了一下md代碼,並且在原代碼的基礎上開發…

                </dd>
            </a>
        </dl>
                                                <dl class="clearfix csdn-tracking-statistics recommend_article recommend_article_out" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
            <a href="http://blog.csdn.net/y_xianjun/article/details/47107551" target="_blank" strategy="BlogCommendFromBaidu_12">
                <dd>
                    <h2 style="margin-bottom: 0px;">FreeSWITCH代碼分析</h2>
                    <ul class="floatR">
                        <li class="avatar_img"><img src="//avatar.csdn.net/B/5/1/3_y_xianjun.jpg" alt="y_xianjun" title="y_xianjun"></li>
                        <li class="user_name">y_xianjun</li>
                        <li class="time">2015年07月28日 16:41</li>
                        <li class="visited_num"><i class="icon iconfont icon-read"></i><span>1656</span></li>
                    </ul><div class="summary">
                        什麼是FreeSWITCH

FreeSWITCH 是一個可擴展的開源跨平臺的電話平臺,支持音頻、視頻、文本或任何其他形式的媒體使用的協議的路由與交互。它於2006年成立。FreeSWITCH也提…

                </dd>
            </a>
        </dl>
                                                <dl class="clearfix csdn-tracking-statistics downloadElement" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
            <a class="clearfix" href="https://download.csdn.net/download/qgjrbnz/9869694" target="_blank" strategy="BlogCommendFromBaidu_13">
                <dd class="floatL">
                    <div class="summary">
                        <h2>開源軟交換系統freeSwitch sip模塊的源碼初步分析</h2>
                        <div class="summary">
                            <ul>
                                <li class="time">2017年06月13日 21:04</li>
                                <li class="visited_num fileSize">253KB</li>
                                <li class="download_btn">下載</li>
                            </ul>
                        </div>
                    </div>
                </dd>
                <dt class="floatR"><img class="maxwidth" src="http://csdnimg.cn/release/download/old_static/images/minetype/pdf.svg" alt="" title=""></dt>
            </a>
        </dl>
                                                <dl class="clearfix csdn-tracking-statistics downloadElement" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
            <a class="clearfix" href="https://download.csdn.net/download/hxdhxd_hxd/6850459" target="_blank" strategy="searchFromBaidu_14">
                <dd class="floatL">
                    <div class="summary">
                        <h2>freeswitch源代碼</h2>
                        <div class="summary">
                            <ul>
                                <li class="time">2014年01月15日 10:31</li>
                                <li class="visited_num fileSize">36.13MB</li>
                                <li class="download_btn">下載</li>
                            </ul>
                        </div>
                    </div>
                </dd>
                <dt class="floatR"><img class="maxwidth" src="http://csdnimg.cn/release/download/old_static/images/minetype/unkonw.svg" alt="" title=""></dt>
            </a>
        </dl>
                                                <dl class="clearfix csdn-tracking-statistics recommend_article recommend_article_out" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
            <a href="http://blog.csdn.net/y_xianjun/article/details/77451174" target="_blank" strategy="searchFromBaidu_15">
                <dd>
                    <h2 style="margin-bottom: 0px;">FreeSWITCH源碼分析之主函數main()</h2>
                    <ul class="floatR">
                        <li class="avatar_img"><img src="//avatar.csdn.net/B/5/1/3_y_xianjun.jpg" alt="y_xianjun" title="y_xianjun"></li>
                        <li class="user_name">y_xianjun</li>
                        <li class="time">2017年08月21日 16:19</li>
                        <li class="visited_num"><i class="icon iconfont icon-read"></i><span>234</span></li>
                    </ul><div class="summary">
                        Freeswitch的主函數是在文件switch.c中定義的,該文件的260行是整個程序的入口,主函數主要完成的功能是包括,命令行解析,初始化apr庫,構建全局內存池,模塊加載和初始化核心組件。

 …

                </dd>
            </a>
        </dl><dl id="yd_a_d_feed_17" class="yd_a_d_feed_cla" style="height:124px;overflow: hidden;"><iframe scrolling="no" style="width: 100%; height: 90px; border: 0px;"></iframe></dl>
                                                <dl class="clearfix csdn-tracking-statistics recommend_article recommend_article_out" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
            <a href="http://blog.csdn.net/educast/article/details/17921619" target="_blank" strategy="BlogCommendFromQuerySearch_16">
                <dd>
                    <h2 style="margin-bottom: 0px;">運行 FreeSWITCH</h2>
                    <ul class="floatR">
                        <li class="avatar_img"><img src="//avatar.csdn.net/C/8/E/3_educast.jpg" alt="educast" title="educast"></li>
                        <li class="user_name">educast</li>
                        <li class="time">2014年01月06日 16:43</li>
                        <li class="visited_num"><i class="icon iconfont icon-read"></i><span>2652</span></li>
                    </ul><div class="summary">
                        讀到本章,你應該對 FreeSWITCH 有了一個比較全面的瞭解,迫切地想實驗它強大的功能了。讓我們從最初的運行開始,一步一步進入 FreeSWITCH 的神祕世界。

命令行參數

一般來說…

                </dd>
            </a>
        </dl>
                                                <dl class="clearfix csdn-tracking-statistics recommend_article recommend_article_out" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
            <a href="http://blog.csdn.net/y_xianjun/article/details/73480840" target="_blank" strategy="BlogCommendFromQuerySearch_17">
                <dd>
                    <h2 style="margin-bottom: 0px;">FreeSWITCH源碼分析之mod_xml_curl</h2>
                    <ul class="floatR">
                        <li class="avatar_img"><img src="//avatar.csdn.net/B/5/1/3_y_xianjun.jpg" alt="y_xianjun" title="y_xianjun"></li>
                        <li class="user_name">y_xianjun</li>
                        <li class="time">2017年06月20日 20:24</li>
                        <li class="visited_num"><i class="icon iconfont icon-read"></i><span>583</span></li>
                    </ul><div class="summary">
                        近期又開始了我的FreeSWITCH研究之路, 因爲項目中需要, &nbsp;使用sip_profile中的internal端點來處理sipUA的註冊及在線保持做被叫, 打開了登錄及呼叫認證的開關, 我們都知道...                        </div>


                </dd>
            </a>
        </dl>
                                                <dl class="clearfix csdn-tracking-statistics recommend_article recommend_article_out" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
            <a href="http://blog.csdn.net/u012377333/article/details/44346807" target="_blank" strategy="searchFromBaidu_18">
                <dd>
                    <h2 style="margin-bottom: 0px;">FreeSWITCH代碼分析</h2>
                    <ul class="floatR">
                        <li class="avatar_img"><img src="//avatar.csdn.net/4/2/4/3_u012377333.jpg" alt="u012377333" title="u012377333"></li>
                        <li class="user_name">u012377333</li>
                        <li class="time">2015年03月17日 19:53</li>
                        <li class="visited_num"><i class="icon iconfont icon-read"></i><span>1268</span></li>
                    </ul><div class="summary">
                        轉載:http://blog.csdn.net/educast/article/details/17970117

什麼是FreeSWITCH

FreeSWITCH 是一個可擴展的開源跨平臺…

                </dd>
            </a>
        </dl>
                                                <dl class="clearfix csdn-tracking-statistics recommend_article recommend_article_out" data-mod="popu_387" data-poputype="feed" data-feed-show="false" data-dsm="post">
            <a href="http://blog.csdn.net/huoyin/article/details/39327849" target="_blank" strategy="searchFromBaidu_19">
                <dd>
                    <h2>軟交換freeswitch系統概要和源代碼分析初步</h2>
                    <div class="summary">
                        asterisk與freeswitch的比較:

1:Asterisk是針對1百人以下的小型系統,相同的硬件配置下單系統最多併發200路,而根據國外愛好者測試freeswitch可達到2000-300…

                    <ul>
                        <li class="avatar_img"><img src="//avatar.csdn.net/A/A/5/3_huoyin.jpg" alt="huoyin" title="huoyin"></li>
                        <li class="user_name">huoyin</li>
                        <li class="time">2014年09月17日 00:24</li>
                        <li class="visited_num"><i class="icon iconfont icon-read"></i><span>1199</span></li>
                    </ul>
                </dd>
            </a>
        </dl>
                    </div>

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章