zoukankan      html  css  js  c++  java
  • freeswitch的拨号规则配置

    当一个呼叫在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
    参见这两个: API Reference 和 Dialplan Functions

    示例
    示例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>
    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
    ---------------------
    作者:karl_max
    来源:CSDN
    原文:https://blog.csdn.net/karl_max/article/details/5046811
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    ORACLE 查询所有用户调度作业
    【ORACLE】查看死锁进程并结束死锁的脚本
    Oracle12c中数据泵新特性之功能增强(expdp, impdp)
    oracle常用查询sql
    记一次异机rman还原后的操作
    Oracle 11gR2 RAC网络配置,更改public ip、vip和scanip
    记一次异机rman还原后的操作
    oracle通过impdp导入不同表用户、不同表空间的数据
    telegram即时通信软件和outline ---- by 余弦 by倾旋
    Vue -3:单文件组件
  • 原文地址:https://www.cnblogs.com/keystone/p/10755902.html
Copyright © 2011-2022 走看看