当一个呼叫在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应该做什么。 语法: 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: 示例2,通过网关呼叫用户: condition condition就是决定当然呼叫是否要在这个extension中处理的一个模式匹配标签。 语法: 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$"> condition> 示例2, 嵌套效果: 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 参见这两个: API Reference 和 Dialplan Functions 示例 示例1 condition>extension> 示例2 示例3 condition>extension> 示例4 condition>extension> 示例5 假设我们有两个不同的profile, profile的配置文件在conf/sip_profiles/ profile> profile> 这两个profile1和profile2 要使用u-law的配置 要使用a-law的配置 示例6 示例7 condition>extension> 示例8 condition> 示例9 将一个DID(Direct inward dailing)路由到一个指定的extension 1001。 本示例是一个发送和查询voicemail的配置示例。 首先是在conf/dialplan/public.xml里: condition> extension 然后在conf/dialplan/default.xml的default context里: condition> 示例10 呼出示例, 可以替换主叫号码 condition> extension> 示例11 根据目标号码不同路由到不同的目标 condition> 示例12 捕捉所有的号码, condition>extension> 示例13 从主号方取得名字,接通被叫并显示主叫名字,如果被叫按“1”则接通主被叫,如果被叫方挂机,则主叫会被路由到voicemail。 这个没搞清楚它是怎么实现的! condition> extension> 示例14 wav格式语音的录/放音 condition> extension> 示例15 用Flite text to speech报时,mod_flite condition> extension>include> SIP特定的拨号字符串 呼叫一个SIP URI 基本语法:sofia/my_profile/user@host, 如: sofia/my_profile/1234@192.168.1.1 呼叫一个注册用户 没有注册别名的情况:sofia/my_profile/1234%mydomain.com 注册别名的情况:sofia/mydomain.com/1234,注意:这里没有显示指定profile文件。也可以这样:user/1234@mydomain.com 通过网关呼叫 sofia/gateway/mygateway.com/1234 其中网关名就是mygateway.com,呼叫的用户1234 呼叫时指定传输协议 传输协议可以是:TCP, UDP, TLS, SCTP,如: sofia/my_profile/1234@192.168.0.1;transport=tcp 指定编解码 {absolute_codec_string=XXXX}sofia/my_profile/user@your.domain.com Getting Fancy With PortAudio,这个没搞明白是做什么用的 If you have PortAudio running and would like to specify the codec you need to originate first and bridge second:originate {absolute_codec_string=XXXX}sofia/default/foo@bar.com bridge:portaudio/auto_answer inline 修改SIP联系人 fs正常会用mod_sofia@ip:port做为内部的联系人,如果想修改一下, {sip_contact_user=foo}sofia/my_profile/1234@192.168.0.1;transport=tcp 使用定制的SIP URI 比如,要发送在“SIP:”开头的URI,sofia/my_profile/sip:xxxx;phone-context=cdp.udp@somedomain.com;user=phone |
|
来自: icecity1306 > 《FreeSWITCH》