引自:https://blog.csdn.net/karl_max/article/details/5046811
当一个呼叫在ROUTING状态下达到命中拨号规则解析器时,相应的拨号规则就开始解析了。随着解析的进行,在xml文件中的符合条件的或标签中的指令形成一个指令表,安装到这个通道中。
你可以将拨号规则文件放到conf/dialplan/default下,这个目录下的拨号规则要比enum拨号规则优先处理。这个目录下的文件执行优先级是按其文件名开头的数字排序(由小到大),最大的那个文件是99999_enum.xml,这个文件捕捉所以的呼叫,所以我们自己定义的文件一定要小于这个文件才可能被先执行。一个以字母开头的文件名会大小999999_enum.xml。
可以通过${api func(api arg ${var_name})}的方式调用一个模块的函数。
通常一个拨号规则文件会包括三个要素:context, extension, condition和action。这些项目会被依次处理,只到达到action。
context
context是一个extension的逻辑组,一个context可以包含一个或多个extension。
context有一个name参数,any是一个保留的name参数值,它代表任何context。name用来标识一个context。在freeswitch.xml的dialplan section中可以有多个context。
extension
extension就是一个呼叫的目标。它有一个name,一些condition和action,这些东西会告诉freeswitch应该做什么。
语法:
<extension name="{exten_name}" [continue="[true|false]"]>
name参数是必须的,它是extension的唯一标识。
另外还有一个可选的参数continue,如果它配置为true的话,即使这个extension已经匹配,在执行完它的action后,还会继续执行后序的extension。其默认值为false。
{exten_name}可以是任何值。有一种特殊情况,如果exten_name正好与destination_number相等的话,解析器会从这个extension开始解析。但这是意味着就会执行它(执行要看它里面的condition)。如果没有这一特殊情况,解析器会从第一个extension开始解析。
如果condition中的field与expression匹配,再执行condition中的action。此时如果expresion中的以()括起来的值话,$1,$2,…,$N会依次得到这些值。在action中的data可以使用这些变量。
如果没有匹配成功,则会执行中的指令。此时,因为没有匹配,所以$1,$2等是没有值的。
condition中除了field和expression参数外,还可以有一个break参数,这个参数指明什么情况下中断这个extension的条件匹配。也就是说extension在什么情况下在这个condition中止查询,这个condition后面的condition不在执行了。
break的值可以是:
‘on-true’ : 如果这个匹配成功,则下面的condition不再查询
‘on-false’: 如果这个匹配失败,则…… (这个是默认值) 。也就是说,默认的情况下,只要有一个condition匹配失败了,这个extension也就不再往下执行了,再换它下面的extension。
‘always’ : 总是在此处停止
‘never’ : 永远不在此处停止
示例1:
<extension>
<condition field="destination_number" expression="^500$">
<action application="bridge" data="sofia/profilename/500%x.x.x.x"/>
condistion>
extension>
示例2,通过网关呼叫用户:
<extension name="testing">
<condition field="destination_number" expression="^(100)$">
<action application="bridge" data="sofia/gateway/gw/$1"/>
condition>
extension>
condition
condition就是决定当然呼叫是否要在这个extension中处理的一个模式匹配标签。
语法:
<condition field="[{field_name}|${variable_name}|${api_func(api_args ${var_name})}]" expression="{expression}" break="[on-true|on-false|always|never]">
<action application="app name" data="app arg"/>
<anti-action application="app name" data="app arg"/>
</condition>
fileld和expression是必须的,break是可选的。
有一些内部变量可以用:
- context Why can we use the context as a field? Give us examples of usages please.
- rdnis Redirected Number, the directory number to which the call was last presented.
- destination_number Called Number, the number this call is trying to reach (within a given context)
- dialplan Name of the dialplan module that are used, the name is provided by each dialplan module. Example: XML
- caller_id_name Name of the caller (provided by the User Agent that has called us).
- caller_id_number Directory Number of the party who called (caller) -- can be masked (hidden)
- ani Automatic Number Identification, the number of the calling party (caller) -- cannot be masked
- aniii The type of device placing the call ANI2
- uuid Unique identifier of the current call? (looks like a GUID)
- source Name of the FreeSWITCH module that received the call (e.g. PortAudio)
- chan_name Name of the current channel (Example: PortAudio/1234). Give us examples when this one can be used.
- network_addr IP address of the signaling source for a VoIP call.
- year Calendar year, 0-9999
- yday Day of year, 1-366
- mon Month, 1-12 (Jan = 1, etc.)
- mday Day of month, 1-31
- week Week of year, 1-53
- mweek Week of month, 1-6
- wday Day of week, 1-7 (Sun = 1, Mon = 2, etc.)
- hour Hour, 0-23
- minute Minute (of the hour), 0-59
- minute-of-day Minute of the day, (1-1440) (midnight = 1, 1am = 60, noon = 720, etc.)
除了上面的变量外,还可以使用自定义的变量${variable},以及一些api函数${api(args)}
这些变量可以在field及expression里。
condition是不能嵌套的,但可以将多个condition堆在一起,并设置break为on-false(默认值),这样的效果与嵌套一样。
示例1,利用cond API函数:
<condition field="${cond(${my_var} > 12 ? YES : NO)}" expression="^YES$"> <action application="log" data="INFO ${my_var} is indeed greater than 12"/> <anti-action application="log" data="INFO ${my_var} is not greater than 12"/> condition>
示例2, 嵌套效果:
<extension name="To PSTN"> <condition field="fdnis" expression="9541231234"/> <condition field="destination_number" expression="(.*)"> <action application="bridge" data="sofia/profilename/$1@x.x.x.x:5061"/> condition> extension>
action
action是在condition匹配的时候执行,而anti-action是在condition不匹配的时候执行。
action有两个参数,一个是application,一个是data。其中application是指一个注册的应用程序。data是给这个应用程序传递的参数。
在anti-action里不能使用$1这样的变量,原因是expression没有匹配成功,所以$1没有值。
内联action
先说说hunting和executing,hunting就是freeswitch扫描符合条件action放到一个队列里,executing就是执行队列里的action。
所以,在通常情况下freeswitch中的hunting和executing是分两步执行的。这说意味着在executing时设置的变量,在hunting时是不可用的。也就是说,即使我们能用可以显示变量的值,但是在我们的xml文件中的condition中可能是不可用的。
要解决这个问题就要用到inline参数。
inline="true" application="set" data="some_var=some_val"/>
action的参数inline设置为"true"时,action会在hunting时执行。这样,后面的condition就可以使用这个${some_var}变量了。
另外,用inline方式执行的application不能显示在cdr里,原因是它们在hunting时就已经执行了。
不是所有的application都可以在hunting时执行。只有那些快速执行get或set变量值,且不会影响当前session的application才可以。它们包括下面这些:
check_acl,
eval,
event,
export,
log,
presence,
set,
set_global,
set_profile_var,
set_user,
sleep,
unset,
verbose_events,
cidlookup,
curl,
easyroute,
enum,
lcr,
nibblebill,
odbc_query
可用的action
示例
示例1
<extension name="Test1">
<condition field="network_addr" expression="^192/.168/.1/.1$"/>
<condition field="destination_number" expression="^(/d+)$">
<action application="bridge" data="sofia/profilename/$1@192.168.2.2"/>
condition>
extension>
<extension name="Test1Wrong">
<condition field="destination_number" expression="^(/d+)$"/>
<condition field="network_addr" expression="^192/.168/.1/.1$">
<action application="bridge" data="sofia/profilename/$1@192.168.2.2"/>
condition>
extension>
<extension name="Test1_2">
<condition field="destination_number" expression="^(/d+)$">
<action application="set" data="dialed_number=$1"/>
condition>
<condition field="network_addr" expression="^192/.168/.1/.1$">
<action application="bridge" data="sofia/profilename/${dialed_number}@192.168.2.2"/>
condition>
extension>
示例2
<extension name="Test2">
<condition field="network_addr" expression="^192/.168/.1/.1$"/>
<condition field="destination_number" expression="^1(/d+)$">
<action application="bridge" data="sofia/profilename/$0@192.168.2.2"/>
condition>
extension>
示例3
<extension name="Test3.1">
<condition field="destination_number" expression="^00(/d+)$">
<action application="bridge" data="sofia/profilename/$1@192.168.2.2"/>
condition>
extension>
<extension name="Test3.2">
<condition field="destination_number" expression="^00(.+)$">
<action application="bridge" data="sofia/profilename/$1@192.168.2.2"/>
condition>
extension>
示例4
<extension name="Test4">
<condition field="destination_number" expression="^00(/d+)$">
<action application="bridge" data="sofia/profilename/011$1@x.x.x.x"/>
condition>
extension>
示例5
假设我们有两个不同的profile, profile的配置文件在conf/sip_profiles/
<profile name="profile1">
<param name="debug" value="1"/>
<param name="rfc2833-pt" value="101"/>
<param name="sip-port" value="5060"/>
<param name="dialplan" value="XML"/>
<param name="dtmf-duration" value="100"/>
<param name="codec-prefs" value="PCMU@20i"/>
<param name="codec-ms" value="20"/>
<param name="use-rtp-timer" value="true"/>
profile>
<profile name="profile2">
<param name="debug" value="1"/>
<param name="rfc2833-pt" value="101"/>
<param name="sip-port" value="5070"/>
<param name="dialplan" value="XML"/>
<param name="dtmf-duration" value="100"/>
<param name="codec-prefs" value="PCMA@20i"/>
<param name="codec-ms" value="20"/>
<param name="use-rtp-timer" value="true"/>
profile>
这两个profile1和profile2
要使用u-law的配置
<extension name="Test5ulaw">
<condition field="network_addr" expression="^192/.168/.1/.1$"/>
<condition field="destination_number" expression="^1(/d+)$">
<action application="bridge" data="sofia/profile1/$0@192.168.2.2"/>
condition>
extension>
要使用a-law的配置
<extension name="Test5alaw">
<condition field="network_addr" expression="^192/.168/.1/.1$"/>
<condition field="destination_number" expression="^1(/d+)$">
<action application="bridge" data="sofia/profile2/$0@192.168.2.2"/>
condition>
extension>
示例6
<extension name="internal">
<condition field="source" expression="mod_sofia" />
<condition field="destination_number" expression="^(4/d+)">
<action application="bridge" data="sofia/local_profile/$0%example.com" />
condition>
extension>
示例7
<extension name="internal">
<condition field="destination_number" expression="^1111">
<action application="set" data="hangup_after_bridge=true"/>
<action application="bridge" data="sofia/local_profile/1111@example1.company.com" />
<action application="bridge" data="sofia/local_profile/1111@example2.company.com" />
condition>
extension>
示例8
<extension name="9191">
<condition field="destination_number" expression="^9191$"/>
<condition field="${sip_authorized}" expression="true">
<anti-action application="reject" data="407"/>
condition>
<condition>
<action application="playback" data="/tmp/itworked.wav"/>
condition>
extension>
示例9
将一个DID(Direct inward dailing)路由到一个指定的extension 1001。
本示例是一个发送和查询voicemail的配置示例。
首先是在conf/dialplan/public.xml里:
<extension name="test_did">
<condition field="destination_number" expression="^(XXXxxxxxxx)$">
<action application="transfer" data="$1 XML default"/>
condition>
extension
然后在conf/dialplan/default.xml的default context里:
<extension name="Local_Extension">
<condition field="destination_number" expression="^(XXXxxxxxxx)$">
<action application="set" data="dialed_ext=$1"/>
condition>
<condition field="destination_number" expression="^${caller_id_number}$">
<action application="set" data="voicemail_authorized=${sip_authorized}"/ >
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="voicemail" data="check default $${domain} ${dialed_ext}"/>
<anti-action application="ring_ready"/>
<anti-action application="set" data="call_timeout=10"/>
<anti-action application="set" data="hangup_after_bridge=true"/>
<anti-action application="set" data="continue_on_fail=true"/>
<anti-action application="bridge" data="USER/1001@$${domain}"/>
<anti-action application="answer"/>
<anti-action application="sleep" data="1000"/>
<anti-action application="voicemail" data="default $${domain} ${dialed_ext}"/>
condition>
extension>
示例10
呼出示例, 可以替换主叫号码
<extension name="asterlink.com">
<condition field="caller_id_number" expression="^1000$"/>
<condition field="destination_number" expression="^(/d{10})$">
<action application="set" data="effective_caller_id_number=8001231234"/>
<action application="set" data="effective_caller_id_name=800 Number"/>
<action application="bridge" data="sofia/gateway/asterlink.com/1208$1"/>
condition>
extension>
示例11
根据目标号码不同路由到不同的目标
<extension>
<condition field="network_addr" expression="^(66/.123/.321/.231|70/.221/.221/.221)$" break="on-false"/>
<condition field="destination_number" expression="^/d+$" break="never">
<action application="set" data="continue_on_fail=NORMAL_TEMPORARY_FAILURE,TIMEOUT,NO_ROUTE_DESTINATION"/>
<action application="set" data="bypass_media=true"/>
<action application="set" data="accountcode=myaccount"/>
condition>
<condition field="destination_number" expression="^(1813/d+|1863/d+|1727/d+|1941/d+|404/d+)$" break="never">
<action application="bridge" data="sofia/outbound_profile/${sip_to_user}@switch1.mydomain.com"/>
<action application="info"/>
<action application="respond" data="503"/>
<action application="hangup"/>
condition>
<condition field="destination_number" expression="^(1404/d+|1678/d+|1770/d+)$">
<action application="bridge" data="sofia/outbound_profile/${sip_to_user}@switch2.mydomain.com"/>
<action application="info"/>
<action application="respond" data="503"/>
<action application="hangup"/>
<anti-action application="respond" data="503"/>
<anti-action application="hangup"/>
condition>
extension>
示例12
捕捉所有的号码,
<extension name="catchall">
<condition field="destination_number" expression=".*" continue="on-true">
<action application="playback" data="bla.wav"/>
condition>
extension>
示例13
从主号方取得名字,接通被叫并显示主叫名字,如果被叫按“1”则接通主被叫,如果被叫方挂机,则主叫会被路由到voicemail。
这个没搞清楚它是怎么实现的!
<extension name="screen">
<condition field="destination_number" expression="^(/d{4})$">
<action application="set" data="call_screen_filename=/tmp/${caller_id_number}-name.wav"/>
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="phrase" data="voicemail_record_name"/>
<action application="playback" data="tone_stream://%(500, 0, 640)"/>
<action application="set" data="playback_terminators=#*0123456789"/>
<action application="record" data="${call_screen_filename} 7 200 2"/>
<action application="set" data="group_confirm_key=1"/>
<action application="set" data="fail_on_single_reject=true"/>
<action application="set" data="group_confirm_file=phrase:screen_confirm:${call_screen_filename}"/>
<action application="set" data="continue_on_fail=true"/>
<action application="bridge" data="user/$1"/>
<action application="voicemail" data="default $${domain} $1"/>
<action application="hangup"/>
condition>
extension>
示例14
wav格式语音的录/放音
<extension name="recording">
<condition field="destination_number" expression="^(2020)$">
<action application="answer"/>
<action application="set" data="playback_terminators=#"/>
<action application="record" data="/tmp/recorded.wav 20 200"/>
condition>
extension>
<extension name="playback">
<condition field="destination_number" expression="^(2021)$">
<action application="answer"/>
<action application="set" data="playback_terminators=#"/>
<action application="playback" data="/tmp/recorded.wav"/>
condition>
extension>
示例15
用Flite text to speech报时,mod_flite
<include>
<extension name="SpeakTime">
<condition field="destination_number" expression="^2910$">
<action application="set" data="actime=${strftime(%H:%M)}"/>
<action application="set" data="tts_engine=flite"/>
<action application="set" data="tts_voice=slt"/>
<action application="speak" data="Is it +${actime}"/>
condition>
extension>
include>
相关推荐
这段代码的作用是定义了一个扩展名为“201”的拨号规则,当目的地号码以“0”开头时,将通过桥接的方式连接到HT503网关上的指定地址(192.168.10.66)。这里的“0”通常表示外线出局码,可以根据实际情况进行调整。 ...
5. **拨号计划**:创建和管理拨号计划,定义号码路由逻辑,实现复杂的呼叫处理规则。 6. **媒体处理**:探讨如何处理音频和视频流,包括编解码设置、混音、录音等功能。 7. **API与脚本编程**:学习如何使用...
2. **配置文件**:熟悉FreeSWITCH的配置结构,包括`conf/autoload_configs`目录下的各种配置文件,如`modules.conf.xml`用于加载模块,`dialplan.xml`定义拨号计划,`vars.xml`设置全局变量。 3. **命令行界面**:...
例如,`拨号计划`(Dialplan)是Freeswitch中的一个重要组件,用于定义电话号码的路由规则。 呼入路由配置主要涉及如何处理来自外部的呼叫。在Freeswitch中,我们可以使用XML拨号计划来指定当一个呼叫到达时应该...
语音通话主要基于SIP协议,用户可以通过配置dialplan来定义拨号规则,将特定的号码映射到特定的用户或目的地。 4.2. 视频通话 视频通话除了语音外,还需要配置视频流的传输,包括选择合适的视频编码标准,如H.264,...
接下来,打开FreeSWITCH的配置文件`\conf\dialplan\default.xml`,找到与拨号规则相关的部分。具体来说,是在以下语句: ```xml ^(10[01][0-8])$"> ``` 在这个条件块的下方,添加一系列设置动作来定义录音文件的...
2. **配置拨号计划**:接着编辑`conf/dialplan/default.xml`文件,找到`<group_dial_billing>`节点,在`</extension>`之后添加新的拨号规则,例如: ```xml ^2003$"> ${domain_name}"/> ``` 这样,当...
例如,"mod_dialplan_xml"模块允许通过XML来定义拨号计划,控制通话路由;"mod_commands"提供了命令行接口,用于控制系统操作;而"mod_v8"则支持JavaScript编程,可以创建复杂的呼叫处理逻辑。 在FreeSwitch的...
2. `dialplan.xml`:拨号计划,定义通话路由规则。 3. `vars.xml`:变量配置,如认证信息、端口设置等。 4. `modules.conf.xml`:模块加载配置,启用或禁用所需模块。 五、启动与管理 1. `cd /usr/local/freeswitch...
- 修改拨号计划:自定义FreeSWITCH的拨号规则,以便处理不同的呼叫需求。 - 记录呼叫到分机:为特定分机设置呼叫录音功能,用于质量监控或存档。 - 启用IPFW和QoS(Quality of Service):利用dummynet工具优化...
`context`定义了一个拨号计划上下文,`extension`则是在该上下文中定义的具体拨号规则。`condition`用于设置匹配条件,而`action`和`anti-action`则分别指定在条件满足和不满足时执行的操作。 条件(condition)中...
针对特定用户或坐席,需要设置独立的密码,并调整拨号计划以实现更加灵活的呼叫规则。 **配置步骤**: 1. 在`conf/dialplan`目录下,编辑`default.xml`文件。 2. 找到相应的`<extension name="Local_Extension">`...
"百问FreeSwitch"文档可能包含以下内容:FreeSwitch的安装与配置,SIP基础及配置,FreeSwitch模块详解,Dialplan(拨号计划)设计,Media处理,转接和桥接规则,录音与回放,API接口开发,WebRTC集成,安全管理,...
- **脚本配置**:如`dialplan.xml`用于定义拨号规则。 **44. 设置日志级别** - **方法**:编辑`log4cxx.properties`文件中的日志配置。 - **级别**:如`INFO`、`DEBUG`、`ERROR`等。 **45. 查看注册用户数量**...
用户可以根据需要自定义拨号规则。 - **录音和回放**:FreeSWITCH支持录音功能,可以记录通话内容。同时,也支持播放预录制的消息或音乐。 ### 进阶功能 - **API集成**:FreeSWITCH提供了一套完善的API,允许...
- mod_dialplan_xml:使用XML定义拨号规则,易于管理。 - mod_http_api:提供HTTP接口,方便远程控制和监控FreeSwitch。 - mod_sofia:SIP栈,处理SIP协议交互。 - mod_skype4com:与Skype集成,实现Skype到VoIP...
- **Dialplan的概念**:Dialplan是FreeSWITCH中用于定义呼叫路由规则的部分,可以根据不同的号码模式将呼叫路由到不同的目的地。 - **编写示例**:提供简单的Dialplan编写示例,展示如何使用条件语句来控制呼叫流。 ...
在FreeSWITCH的配置中,XML是主要的配置语言,用于定义各种软交换功能和行为。然而,手动编辑XML配置文件可能会变得繁琐且容易出错。为此,`conffs`提供了一个Python API,使得开发者能够更方便地通过编程方式来管理...
3. 路由策略和功能应用:定义SIP消息的处理规则,如使用is_method()函数进行消息类型检查。 OpenSIPS的系统结构由脚本控制的核心功能、模块化设计和高效的配置文件解析组成。脚本语言允许开发者使用类似于SIP规范的...