概述
freeswitch是一款简单好用的VOIP开源软交换平台。
fs使用dialplan配置文件执行业务流程,condition条件变量的配置是必然会使用的,这里记录一次配置过程中的错误示范。
环境
CentOS 7.9
freeswitch 1.10.7
问题描述
dialplan配置如下,本意是根据通道变量${poolType}的值,执行不同的app。
<context name="saxb_bind_axb">
<extension name="saxb_bind_axb" continue="true">
<condition field="${call_result}" expression="0" break="never">
<condition field="${poolType}" expression="APP" break="never">
<action application="saxb_bind_axb" />
<action application="transfer" data="${destination_number} XML saxb_bridge"/>
</condition>
<condition field="${poolType}" expression="SIP" break="never">
<action application="transfer" data="${destination_number} XML saxb_bridge"/>
</condition>
<condition field="${poolType}" expression="AX" break="never">
<action application="saxb_bind_ax" />
<action application="transfer" data="${destination_number} XML saxb_bridge"/>
</condition>
<condition field="${poolType}" expression="AXB" break="never">
<action application="saxb_bind_axb" />
<action application="transfer" data="${destination_number} XML saxb_bridge"/>
</condition>
<anti-action application="transfer" data="${destination_number} XML saxb_get_ax2"/>
</condition>
</extension>
</context>
问题现象
呼叫发起后的日志如下,其中通道变量${poolType}的值为AXB,但是在AX和AXB的分支都匹配成功并PASS了,业务流程执行了错误的分支。
2024-07-29 16:10:48.492821 [INFO] mod_dialplan_xml.c:637 Processing 10011 <10011>->13987654321 in context saxb_bind_axb
Dialplan: sofia/external/10011@10.55.55.138 parsing [saxb_bind_axb->saxb_bind_axb] continue=true
Dialplan: sofia/external/10011@10.55.55.138 Regex (PASS) [saxb_bind_axb] ${call_result}(0) =~ /0/ break=never
|--- Dialplan: Processing recursive conditions level:1 [saxb_bind_axb_recur_1] require-nested=TRUE
|--- Dialplan: sofia/external/10011@10.55.55.138 Regex (FAIL) [saxb_bind_axb_recur_1] ${poolType}(AXB) =~ /APP/ break=never
|--- Dialplan: sofia/external/10011@10.55.55.138 Regex (FAIL) [saxb_bind_axb_recur_1] ${poolType}(AXB) =~ /SIP/ break=never
|--- Dialplan: sofia/external/10011@10.55.55.138 Regex (PASS) [saxb_bind_axb_recur_1] ${poolType}(AXB) =~ /AX/ break=never
|--- Dialplan: sofia/external/10011@10.55.55.138 Action saxb_bind_ax()
|--- Dialplan: sofia/external/10011@10.55.55.138 Action transfer(${destination_number} XML saxb_bridge)
|--- Dialplan: sofia/external/10011@10.55.55.138 Regex (PASS) [saxb_bind_axb_recur_1] ${poolType}(AXB) =~ /AXB/ break=never
|--- Dialplan: sofia/external/10011@10.55.55.138 Action saxb_bind_axb()
|--- Dialplan: sofia/external/10011@10.55.55.138 Action transfer(${destination_number} XML saxb_bridge)
问题分析
<condition field="${poolType}" expression="AX" break="never">
默认的模式匹配不是精确匹配,所以也可以匹配通过。
解决方案
修改配置如下,修改"AX"字符串为"^AX$"。
<condition field="${poolType}" expression="^AX$" break="never">
测试结果如下。
|--- Dialplan: sofia/external/10011@10.55.55.138 Regex (FAIL) [saxb_bind_axb_recur_1] ${poolType}(AXB) =~ /^AX$/ break=never
condition匹配规则
在 FreeSWITCH 的拨号计划(dialplan)中,condition 是一个非常强大的特性,它允许你基于特定的条件来匹配和执行不同的命令。condition 可以匹配各种类型的字符串,包括但不限于用户输入、呼叫变量、环境变量等。
以下是一些常见的 condition 匹配规则。
精确匹配:
使用等号 == 进行精确匹配。如果左侧的表达式与右侧的字符串完全相同,则条件为真。
<condition field="destination_number" expression="^13712345678$">
正则表达式匹配:
使用 =~ 进行正则表达式匹配。FreeSWITCH 支持 Perl 兼容的正则表达式。
<condition field="destination_number" expression="^137[1-9]\d{7}$">
分组:
使用|匹配多个值。
<condition field="destination_number" expression="^13712345678|13799999999$">
多条件组合。
<conditionregex="all|any|xor">
<regexfield="some_field"expression="Some Value"/>
<regexfield="another_field"expression="^Another Value$"/>
<action(s)...>
<anti-action(s)...>
</condition>
asterisk模式。该模式没有xml模式灵活,应该是为了兼容老版本的过度模式。
<condition field="destination_number" expression="_13712345678">
总结
fs的dialplan配置很方便,但是也容易出错。
空空如常
求真得真