FreeSWITCH基本应用

1. 启动&关闭FreeSWITCH

  前台启动:/usr/local/freeswitch/bin/freeswitch         关闭前台FS:shutdown

  后台启动:/usr/local/freeswitch/bin/freeswitch -nc    关闭后台FS:/usr/local/freeswitch/bin/freeswitch -stop

  以上每次启动都需要输入一个很长的一个路径,方便起见可以把[freeswitch]和[fs_cli]加入到[usr/bin],执行命令如下:

  ln -sf /usr/local/freeswitch/bin/freeswitch /usr/bin
  ln -sf /usr/local/freeswitch/bin/fs_cli        /usr/bin

2. 查看FreeSWITCH上已注册话机的信息

  查看命令:show registrations

3. 话机向FreeSWITCH注册流程

  1> 如果注册号码为:1000~1019这20个账号,该20个账号的默认密码为1234,所以只需要知道FS所在服务器的IP地址(默认端口号为5060),既可进行注册。

  2> 如果注册帐号为1000~1019以外的账号,比如8888或者9999。则手册如下:

    (1) 在/usr/local/freeswitch/conf/directory/default目录下,将1000.xml拷贝为你需要注册的账号,如8888.xml,编辑8888.xml并将该文件里所有的1000都替换为8888。修改之后就可以通过话机注册8888账号了,然后你会发现该账号的话机只能进行拨打电话不能接听电话,这是因为还需要修改FS的拨号规则。

    (2) 修改拨号规则:修改/usr/local/freeswitch/conf/dialplan/default.xml,将呼叫规则的正则表达式expression="^(10[01][0-9])$"修改为:expression="^(10[01][0-9]|8888|9999)$"。修改之后加载配置文件即可拨打与呼叫8888账号了。

4. FreeSWITCH配置网关

  如果要实现FS内部已注册账号分别拨打,这个是不需要网关的。但是,你想通过FS内部已注册账号拨打未注册的外线(如手机号码),此时需要FS与外部网关连接,FS引入网关来处理外线拨打功能。(本人是通过使用公司的网关进行操作的)

  FS配置网关需要:用户名,密码以及网关服务器IP地址,FS配置网关如下:

  1> 添加网关配置:如添加[123456]的网关:/usr/local/freeswitch/conf/sip_profiles/external/123456.xml,配置内容如下

<include>
  <gateway name="123456">
    <param name="username" value="123456"/>
    <param name="password" value="888888"/>
    <param name="realm" value="192.168.*.*"/>
    <param name="expire-seconds" value="3600"/>
    <param name="register" value="false"/>
    <param name="retry-seconds" value="60"/>
    <param name="caller-id-in-from" value="false"/>
    <param name="supress-cng" value="false"/>
    <param name="extension-in-contact" value="false"/>
  </gateway>
</include>
View Code

  保存以上代码,并执行命令:sofia profile external restart  对sip profile进行重启。重启后,可以查看网关注册状态,命令为:sofia status。正常情况下网关注册成功,现在虽然注册了网关信息,但是FS内部账号还是不能拨打外线,还需要配置第二部操作。

  2> FreeSWITCH内线通过网关呼叫外线

  追加网关呼叫配置文件:/usr/local/freeswitch/conf/dialplan/default/123456.xml

<include>
  <extension name="extension-call">
    <condition field="destination_number" expression="^(\d{8,12})$">
      <action application="bridge" data="sofia/gateway/123456/$1"/>
    </condition>
  </extension>
</include>
View Code

  保存文件后,FS执行 reloadxml 重新加载配置文件,这样你的内线就能正常拨打符合8到12位的外线了,比如能正常拨打手机号码。然而此时仅仅是能拨打外线,并不能接听外线,要接听外线还需要执行第三部。

  备注:在这一步中本人遇到了一个坑,那就是虽然按上面的保存了配置文件也重新加载了,但是还是不能拨打11位数的手机号码。这是因为在123456.xml同级目录下有个[01_example.com.xml]文件,该文件里有个配置规则正好是11位数的,所以,我配置的11位手机号码没有走到我配置的文件里来,而是被[01_example.com.xml]里的配置规则优先匹配了,此时需要注释[01_example.com.xml]的部分代码,或是删除该文件亦可。

  3> 接收网关发来的呼叫

  对于那些未经认证的呼叫,FS认为是不安全的,即使是网关发送过来的呼叫。FS把这类呼叫路由到public dialplan context中。编辑网关发来的呼叫配置:/usr/local/freeswitch/conf/dialplan/public/123456.xml

<?xml version="1.0" encoding="utf-8"?>
<include>
  <extension name="123456">
    <condition field="destination_number" expression="^(123456)$">
      <action application="set" data="hangup_after_bridge=true"/>
      <action application="export" data="airgo_trunk_number=123456"/>
      <action application="transfer" data="8000 XML default"/>
    </condition>
  </extension>
</include>
View Code

  当外来用户通过网关呼叫FS时,FS将来电转移到8000账号。

5. 修改FreeSWITCH默认注册端口号

  FS默认监听端口号是:5060,然而如果FS部署在公网上,则很容易遭到别人恶意攻击与破解,所以建议修改FS默认的注册端口号。修改端口号:编辑配置文件freeswitch/conf/vars.xml

1 <!-- Internal SIP Profile -->
2   <X-PRE-PROCESS cmd="set" data="internal_auth_calls=true"/>
3   <X-PRE-PROCESS cmd="set" data="internal_sip_port=5060"/>
4   <X-PRE-PROCESS cmd="set" data="internal_tls_port=5061"/>
5   <X-PRE-PROCESS cmd="set" data="internal_ssl_enable=false"/>
6 <!-- 可以看到freeswitch的监听端口为5060 如果想监听其他的端口则把5060 改为你要监听的端口号 -->
View Code

6. 修改FreeSWITCH默认认证密码

  FS默认认证密码为:1234,可以根据需要进行修改。编辑配置文件:freeswitch/conf/vars.xml,找到:<X-PRE-PROCESS cmd="set" data="default_password=1234"/> ,将默认的“1234”修改之。

7. 通话录音

   FS可以对通话进行录音,编辑配置文件:vi freeswitch/conf/dialplan/default.xml,对分机进行如下设置:

1 <extension name="Local_Extension">
2       <condition field="destination_number" expression="^(10[01][0-9]|9999)$">
3         <action application="export" data="dialed_extension=$1"/>
4         <!-- add for recording begin -->
5         <action application="record_session" data="$${base_dir}/recordings/${strftime(%Y)}/${strftime(%m)}/${strftime(%d)}/${caller_id_number}_${strftime(%H-%M-%S)}.wav"/>
6         <!-- add recording end -->
View Code

  录音结果如下:

  

  其实,在这里会联想到把录音的配置设置为一个函数,所以在任何地方需要配置录音,只需要设置:<action application="export" data="allow_recording=true"/>即可。以下是通过lua进行录音设置。

8.为FreeSWITCH添加G729编解码模块

  FS默认的G729模块是不支持转码只支持透传,G729编码在FS中Linux平台上有Licence解决方案,购买一路需要10美元,其中包括一个编码器和一个解码器。作为学习和实验,所以在网上找了一个破解版来实现FS的G729转码功能。

  实验环境:Centos6.5 + FreeSWITCH:1.6.0~64bit

  获取模块源代码:mod_g729

  详细操作:
  (1)备份fs源码中的mod_g729。
    cd freeswitch源码目录/src/mod/codecs
    mv mod_9729 mod_g729_bak
  (2)解压刚下载的G729模块源码。
    unzip 1712150417.zip
    mv mod_g729 freeswitch源码目录/src/mod/codecs
  (3)编译G729模块
    cd freeswitch源码目录/src/mod/codecs/mod_g729
    make
  (4)安装
    cd freeswitch源码目录
    make install
    
  (5)配置
    FS添加G729编解码:
      vi /usr/local/freeswitch/conf/vars.xml
      <X-PRE-PROCESS cmd="set"data="global_codec_prefs=G729,OPUS,G722,PCMU,PCMA,VP8"/>
      <X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=G729,OPUS,G722,PCMU,PCMA,VP8"/>
    FS启动时自动加载G729模块:
      vi /usr/local/freeswitch/conf/autoload_configs/modules.conf.xml
      <!-- Codec Interfaces -->
      <load module="mod_g729"/> //这一行不能被注释
    重新加载sofia配置和G729模块:
      sofia profile internal restart //重新加载sofia internal配置
      reload mod_g729 //重新加载mod_g729模块
  (6)测试
    

9.代接

  (1)全局代接

1 <extension name="global-intercept">
2    <condition field="destination_number" expression="^886$">
3      <action application="answer"/>
4      <action application="intercept" data="${hash(select/${domain_name}-last_dial_ext/global)}"/>
5      <action application="sleep" data="2000"/>
6    </condition>
7 </extension>
View Code

  (2)同组代接

1 <extension name="group-intercept">
2       <condition field="destination_number" expression="^\*8$">
3         <action application="answer"/>
4         <action application="intercept" data="${hash(select/${domain_name}-last_dial_ext/${callgroup})}"/>
5         <action application="sleep" data="2000"/>
6       </condition>
7 </extension>
View Code

  (3)指定分机代接

1 <extension name="intercept-ext">
2       <condition field="destination_number" expression="^\*\*(\d+)$">
3         <action application="answer"/>
4         <action application="intercept" data="${hash(select/${domain_name}-last_dial_ext/$1)}"/>
5         <action application="sleep" data="2000"/>
6       </condition>
7 </extension>
View Code

10.转接

1 <action application="bind_meta_app" data="1 b s execute_extension::dx XML features"/> *1 忙转
2 <action application="bind_meta_app" data="3 b s execute_extension::cf XML features"/>
3 <action application="bind_meta_app" data="4 b s execute_extension::att_xfer XML features"/> *4 协商转
View Code

 11.定时呼叫

  有时想定呼叫一个电话。关于定时任务,可以使用Linux自动的crontable,但是我用golang语言自己写了个定时任务,来调用lua脚本进行呼叫。

 1 // golang 主要代码
 2 func main() {
 3     c := cron.New()
 4     spec := "0 * * * * *" // 每分钟执行一次
 5     c.AddFunc(spec, call)
 6     c.Start()
 7     select {}
 8 }
 9 
10 func call() {
11     cmd := exec.Command("/usr/local/freeswitch/bin/fs_cli", "-x", "luarun /home/tom/call.lua")
12     if err := cmd.Run(); err != nil {
13         fmt.Println(err)
14     }
15 }
16 
17 // lua脚本。其中gw代表的是外呼所用的网关,187代表的是需要呼叫的号码
18 session = freeswitch.Session("{origination_caller_id_number=9999,origination_caller_id_name=9999}user/9999");
19 if session:ready() then
20     session2 = freeswitch.Session("sofia/gateway/gw/187********");
21     if session2:ready() then
22         freeswitch.bridge(session, session2)
23         session:hangup();
24     end
25 end
26 
27 最终实现每分钟呼叫一次187的号码。
View Code

 12.FreeSWITCH设置中文Phrase

  FS默认是没有中文的语音文件配置的,如果需要让FS支持中文语音则需要手动配置。

  (1)添加中文配置文件。
    cd /usr/local/freeswitch/conf/lang //进入lang目录
    cp -R en zh //从en目录复制生成zh目录
    cd zh //进入zh目录
    mv en.xml zh.xml //将en.xml改为zh.xml
    vi zh.xml //编辑zh.xml,将language一行修改如下
    <language name="zh" say-module="zh" sound-prefix="$${sounds_dir}/zh/cn/callie" tts-engine="cepstral" tts-voice="callie">

  (2)加载中文配置文件
    vi /usr/local/freeswitch/conf/freeswitch.xml //编辑配置文件
    <section name="languages" description="Language Management">
      <X-PRE-PROCESS cmd="include" data="lang/zh/*.xml"/> //添加该行

  (3)修改FS默认语音为中文
    vi /usr/local/freeswitch/conf/vars.xml //编辑配置文件
      <X-PRE-PROCESS cmd="set" data="sound_prefix=$${sounds_dir}/zh/cn/callie"/>

  (4)Say接口加载中文模块
    Say接口支持各种语言,如需支持中文语言,则需要编译源码价值mod_say_zh模块
    make mod_say_zh-install
    freeswitch>reload mod_say_zh
    为了让FS启动时自动加载该模块,编辑配置文件conf/autoload_configs/modules.conf.xml,添加:<load module="mod_say_zh"/>

  参考资料:http://www.cnblogs.com/zxqdlenovo/p/4031060.html

 12.fs_cli连接FreeSWITCH时报错

  报错内容:[ERROR] fs_cli.c:1610 main() Error Connecting [Socket Connection Error]

  错误原因:FreeSWITCH 没有启动或 mod_event_socket 没有正确加载,请检查TCP端口8021端口是否处于监听状态或被其它进程占用(netstat -anp | grep 8021)。我的解决如下:

 1 vi /usr/local/freeswitch/conf/autoload_configs/event_socket.conf.xml
 2 <configuration name="event_socket.conf" description="Socket Client">
 3   <settings>
 4     <param name="nat-map" value="false"/>
 5     <!--<param name="listen-ip" value="::"/> 将该行注释并添加下行-->
 6     <param name="listen-ip" value="0.0.0.0"/>
 7     <param name="listen-port" value="8021"/>
 8     <param name="password" value="ClueCon"/>
 9     <!--<param name="apply-inbound-acl" value="loopback.auto"/>-->
10     <!--<param name="stop-on-bind-error" value="true"/>-->
11   </settings>
12 </configuration>
View Code

  13.ivr按键无效时需设置按键类型

  <action application="set" data="dtmf_type=inband"/>
  <action application="start_dtmf" data=""/>

 14.条件运算符(cond <expr> ? <true val> :<false val>)

1 <condition field="${cond(${my_var} > 12 ? YES : NO)}" expression="^YES$">  
2    <action application="log" data="INFO ${my_var} is indeed greater than 12"/>  
3    <anti-action application="log" data="INFO ${my_var} is not greater than 12"/>  
4  </condition>
View Code

 15.接通后再录音

  需求:录音时不要将前置媒体录制进去.
  用法:<action application="set" data="media_bug_answer_req=true"/>

16.录音文件的路径权限如何修改为755

  由于录音文件的路径权限(文件夹权限)默认是750权限,所以通过http获取不到录音文件,需要把录音文件的路径权限改为755。
  解决方案:修改源码重新编译(如果有多台服务器的freeswitch需要解决该问题,不需要单独编译,只需在一台服务器上编译,然后把编译后得到的libfreeswitch.so.1.0.0文件拷贝到对应路径(/usr/local/freeswitch/lib/libfreeswitch.so.1.0.0)即可

 1 cd /usr/local/src/freeswitch/src
 2 vi switch_ivr_async.c
 3 # 在函数 switch_ivr_record_session()
 4 # 修改前为(L2529):if (switch_dir_make_recursive(path, SWITCH_DEFAULT_DIR_PERMS, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
 5 # 修改后如下(把 SWITCH_DEFAULT_DIR_PERMS 修改为 SWITCH_FPROT_OS_DEFAULT):
 6 if (switch_dir_make_recursive(path, SWITCH_FPROT_OS_DEFAULT, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
 7 # 保存&退出
 8 cd /usr/local/src/freeswitch
 9 make
10 make install
View Code

17.如何关闭写freeswitch.log

  由于freeswitch默认会加载mod_logfile模块,日积月累会写很多log文件导致磁盘空间不足,默认日志路径是:/usr/local/freeswitch/log/freeswitch.log。所以可以关闭mod_logfile模块。

1 # 取消启动自加载mod_logfile
2 vim /usr/local/freeswitch/conf/autoload_configs/modules.conf.xml 注释掉 <load module="mod_logfile"/> ,然后重启freeswitch即可。如果不想启动freeswitch,则可在控制台执行:unload mod_logfile
View Code

18.freeswitch支持G729编码

  (1). 设置全局的G729编码

1 vim /usr/local/freeswitch/conf/vars.xml
2 # 以下设置需要的编码
3 <X-PRE-PROCESS cmd="set" data="global_codec_prefs=PCMU,PCMA,G729"/>
4 <X-PRE-PROCESS cmd="set" data="outbound_codec_prefs=PCMU,PCMA,G729"/>
View Code

  (2).自动外呼程序指定使用G729编码

   autodialer_task 表 originate_variables 字段设置 {absolute_codec_string=g729}
  (3).替换 freeswitch/mod 文件夹下的:mod_g729.so、mod_g729.la 文件( 下载 提取密码: rcli)。

19.呼入接收带内(inband)按键

  <extension name="ivr_demo">
    <condition field="destination_number" expression="5000">
      <action application="answer"/>
      <action application="start_dtmf"/>
      <action application="ivr" data="demo_ivr"/>
    </condition>
  </extension>

20.顺振&共振

      场景1:分机顺振(若要改为共振仅需将“|”改为“,”即可)内部分机,测试效果好使,能满足预期。

  <extension name="顺振">
    <condition field="destination_number" expression="^(41001)$">
      <action application="set" data="continue_on_timeout=true"/>
      <action application="set" data="hangup_after_bridge=true"/>
      <action application="bridge" data="[leg_timeout=15]user/8000|[leg_timeout=15]user/8001"/>
    </condition>
  </extension>

 

 

      场景2:外呼顺振,即通过网关先拨打手机号1,若手机号未接通则再拨手机号2。测试结果不如人意,因为手机号拨打的话会出现即使未接通都会听到“您拨打的电话无人接通,请稍后再拨”

  <extension name="test_outbound">
    <condition field="destination_number" expression="^(56789)$">
      <action application="set" data="continue_on_timeout=true"/>
      <action application="set" data="hangup_after_bridge=true"/>
      <action application="set" data="continue_on_fail=NORMAL_TEMPORARY_FAILURE,TIMEOUT,NO_ROUTE_DESTINATION,USER_BUSY,NO_ANSWER,NO_USER_RESPONSE,CALL_REJECTED,OUTGOING_CALL_BARRED,ALLOTTED_TIMEOUT"/>
      <action application="set" data="effective_caller_id_name=${outbound_caller_id_name}"/>
      <action application="set" data="effective_caller_id_number=${outbound_caller_id_number}"/>
      <action application="bridge" data="[leg_timeout=15]sofia/gateway/gw/176x|[leg_timeout=15]sofia/gateway/gw/159x"/>
    </condition>
  </extension>

posted @ 2015-10-19 10:29  hezhixiong  阅读(4550)  评论(0编辑  收藏  举报