第五个镜头已经接触了简单的拨号内容的修改——新增了一个SIP用户。
拨号计划
简单来说其实就是一个路由表,决定通话寻址流程。观看这一镜头前,最好对前面镜头描述的内容比较清楚
初识
FreeSWITCH的拨号计划定义在conf/dialplan目录中,目录中有几个xml文件,打开default.xml,可以看到如下结构内容,每个文件中都有一个分组
<context></context>
<context name="default">
<extension name="unloop">
<condition field="${unroll_loops}" expression="^true$"/>
<condition field="${sip_looped_call}" expression="^true$">
<action application="deflect" data="${destination_number}"/>
</condition>
</extension>
...省略...
<extension name="Local_Extension">
<condition field="destination_number" expression="^(10[01][0-9])$">
...省略...
</condition>
</extension>
</context>
同目录下的xml都是这样的结构,最外围是
<context></context>
标签,内部包含多个<extension></extension>
标签,不同文件中的配置在逻辑上是隔离的
相知
每对
<extension></extension>
相当于一个路由表项,其中的<condition />
是判定条件,满足<condition />
中描述的判定条件则执行其中的动作即<action />
。我们分析默认配置default.xml中的<extension name="Local_Extension">
这个路由项
<!--
dial the extension (1000-1019) for 30 seconds and go to voicemail if the call fails (continue_on_fail=true), otherwise hang up after a successful bridge (hangup_after_bridge=true)
-->
<extension name="Local_Extension">
<condition field="destination_number" expression="^(10[01][0-9])$">
<action application="export" data="dialed_extension=$1"/>
<!-- bind_meta_app can have these args <key> [a|b|ab] [a|b|o|s] <app> -->
<action application="bind_meta_app" data="1 b s execute_extension::dx XML features"/>
<action application="bind_meta_app" data="2 b s record_session::$${recordings_dir}/${caller_id_number}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/>
<action application="bind_meta_app" data="3 b s execute_extension::cf XML features"/>
<action application="bind_meta_app" data="4 b s execute_extension::att_xfer XML features"/>
<action application="set" data="ringback=${us-ring}"/>
<action application="set" data="transfer_ringback=$${hold_music}"/>
<action application="set" data="call_timeout=30"/>
<!-- <action application="set" data="sip_exclude_contact=${network_addr}"/> -->
<action application="set" data="hangup_after_bridge=true"/>
<!--<action application="set" data="continue_on_fail=NORMAL_TEMPORARY_FAILURE,USER_BUSY,NO_ANSWER,TIMEOUT,NO_ROUTE_DESTINATION"/> -->
<action application="set" data="continue_on_fail=true"/>
<action application="hash" data="insert/${domain_name}-call_return/${dialed_extension}/${caller_id_number}"/>
<action application="hash" data="insert/${domain_name}-last_dial_ext/${dialed_extension}/${uuid}"/>
<action application="set" data="called_party_callgroup=${user_data(${dialed_extension}@${domain_name} var callgroup)}"/>
<action application="hash" data="insert/${domain_name}-last_dial_ext/${called_party_callgroup}/${uuid}"/>
<action application="hash" data="insert/${domain_name}-last_dial_ext/global/${uuid}"/>
<!--<action application="export" data="nolocal:rtp_secure_media=${user_data(${dialed_extension}@${domain_name} var rtp_secure_media)}"/>-->
<action application="hash" data="insert/${domain_name}-last_dial/${called_party_callgroup}/${uuid}"/>
<action application="bridge" data="user/${dialed_extension}@${domain_name}"/>
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="bridge" data="loopback/app=voicemail:default ${domain_name} ${dialed_extension}"/>
</condition>
</extension>
<condition>
直译过来就是环境
,在这里表示判断是否满足制定条件
<condition field="destination_number" expression="^(10[01][0-9])$">
field
是待判定的属性,这里是目标号码
expression
是field
对应的属性值需要满足的条件(正则表达式),这里是匹配1000-1019的20个数字
整个判定条件可以描述为“目标号码满足条件^(10[01][0-9])$
则执行这个环境中的<action />
”
<action />
直译过来就是动作
,在这里表示满足<condition>
后执行的动作
<action application="export" data="dialed_extension=$1"/>
<action application="bridge" data="user/${dialed_extension}@${domain_name}"/>
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="bridge" data="loopback/app=voicemail:default ${domain_name} ${dialed_extension}"/>
application
可曾记得在第八个镜头中介绍的APP
,就是他
第一行的application
是export
,功能是设置环境变量,整句的含义就是设置环境变量dialed_extension
为$1
(目标号码)
第二行的application
是bridge
,第八个镜头中有介绍,是用来桥接桥接两个UA进行通话,这里是尝试桥接到目标号码UA
其它APP这里不做详细介绍,大家可以去mod_dptools查询,里面有很详细的介绍
相爱
细心的观众可以看到,每个外围标签几乎都有一个
name
属性,什么作用呢?拨号功能上其实并没什么乱用。但是在调试查看日志查找问题用处就比较明显了。为每个拨号计划起一个易懂的名字在LOG中就可以一目了然的追踪到路由记录,便于定位问题
为了能够很好的定制自己的拨号计划,<condition>
中的正则匹配提供了无限的可能性,下面是基本使用方法的例子和说明
相杀
我们看到有很多的
<extension>
,实际处理中拨号会匹配每一个<extension>
,所以生产环境我们需要删除默认的无用的<extension>
。尤其下面这段坑(default.xml中),匹配的是密码,如果没删除而且默认密码还是1234或者含有1234都会路由进入这里然后被提醒修改密码还会等待10s
<condition field="${default_password}" expression="^1234$" break="never">
<action application="log" data="CRIT WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING "/>
<action application="log" data="CRIT Open $${conf_dir}/vars.xml and change the default_password."/>
<action application="log" data="CRIT Once changed type 'reloadxml' at the console."/>
<action application="log" data="CRIT WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING "/>
<action application="sleep" data="10000"/>
</condition>