FreeSWITCH模块之mod_freeTDM启动和发起呼叫简介

    代码基于FreeSWITCH-1.4.20版本讲解,阅读前提是你已经可以编译并安装FreeTDM模块,编译安装步骤。

    使用场景为:一个语音卡上有4个FXS口,接上模拟话机,能摘机拨打电话。

    第一步:修改配置配置文件。转到FreeSWITC的安装目录,当前目录下有: freetdm.conf和autoload_cofigs/freetdm.conf.xml文件。

            1、修改freetdm.conf文件,找到如下文字:

            [span wanpipe myWanpipe]

            trunk_type => FXS 

            fxs-channel => 1:3-4

                修改为:

            [span wanpipe andywang]

            trunk_type => FXS 

            fxs-channel => 1:1-4

         2、修改freetdm.conf.xml文件,找到如下文字:

                <span name="myAnalog">

                    修改为:   

                <span name="andywang"

            注:“andywang”字符要和freetdm.conf完成一致,程序中会进行对比,通过此来寻找。

            其他地方暂时不做修改。

    第二步:查看源码加载

             1、mod_freetdm是freeswitch的一个模块,加载过程和其他模块一致,入口函数在mod_freetdm.c文件中5567行,函数:

                SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load)

                函数中包含三个主要函数:1) ftdm_global_init():此函数主要是初始化一些全局数据结构,包括后面使用的哈希表,互斥锁,调度策略,目的是运行的基础环境进行初始化,和配置无关。

                    

                2) ftdm_global_configuration():此函数通过解析freetdm.conf文件来对程序进行配置,根据配置,malloc对应span结构体,malloc出1到4个通道的得通道结构体,并对通道进行初始化,创建通道句柄。此配置文件主要是配置不同类型的IO操作,可以认为不涉及信令部分。

                

                3)load_config():此函数通过读取freetdm.conf.xml进行配置,根据不同的信令配置,组合相应的IO模块,进行信令配置。运行信令模块。

 



    第三部:深入源码,具体的执行过程:

    

        在整个配置加载完成后,一个analog得span会创建一个线程,线程的函数为(1181行,ftmod_analog.c):

             static void *ftdm_analog_run(ftdm_thread_t *me, void *obj)


          线程函数一直运行,会通过poll读取各个通道摘机、挂机和按键信号。


         1、手动摘机,通道会上传一个FTDM_OOB_RING_START事件,具体的代码执行

                                   ( 1018 行)   FTDM_OOB_RING_START:

          会在此处创建一个通道的线程,具体创建代码如下:                                    ftdm_thread_create_detached(ftdm_analog_channel_run, event->channel);            


          2、拨号时会有按键数字放置在队里面,通道的线程会读取对应的队列,判断是否有数字,具体的代码在:

            (825行)  if ((dlen = ftdm_channel_dequeue_dtmf(ftdmchan, dtmf + dtmf_offset, sizeof(dtmf) - strlen(dtmf)))) 


        3、当你的拨号满足你设置的拨号方案,或者超时,拨号过程完成,进入正式呼叫过程,具体代码在:

         

848         if (last_digit && (!collecting || ((elapsed - last_digit > analog_data->digit_timeout) || strlen(dtmf) >= analog_data->max_dialstr))) {

 849             ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Number obtained [%s]\n", dtmf);

 850             ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RING);

 851             last_digit = 0;

 852             collecting = 0;

 853         }


                    4、从FreeTDM转入到FreeSWITCH核心的呼叫,是从ftdm_analog.c文件中的代码:

 698             case FTDM_CHANNEL_STATE_RING:

 699                 {

 700                     ftdm_channel_use(ftdmchan);

 701                     sig.event_id = FTDM_SIGEVENT_START;

 702 

 703                     if (ftdmchan->type == FTDM_CHAN_TYPE_FXO) {

 704                         ftdm_set_string(ftdmchan->caller_data.dnis.digits, ftdmchan->chan_number);

 705                     } else {

 706                         ftdm_set_string(ftdmchan->caller_data.dnis.digits, dtmf);

 707                     }

 708

 709                     ftdm_span_send_signal(ftdmchan->span, &sig);

 710                     continue;

 711                 }

 712                 break;

      转入到mod_freetdm.c文件代码中的:

2298     case FTDM_SIGEVENT_START:

2299         {

2300             status = ftdm_channel_from_event(sigmsg, &session);

2301             if (status != FTDM_SUCCESS) {

2302                 ftdm_channel_call_hangup(sigmsg->channel);

2303             }

2304         }

2305         break;


    这个函数ftdm_channel_from_event(sigmsg, &session)会执行具体的呼叫,转入到FreeSWITCH得CORE,然后调用mod_sofia模块进行SIP协议的组合,进行正式的SIP呼叫。



    


                    

 


你可能感兴趣的:(freeswitch,FreeTDM)