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/[email protected]: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纔可以。它們包括下面這些:

可用的action

參見這兩個: API ReferenceDialplan 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/[email protected]"/>
  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/[email protected]"/>
  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/[email protected]"/>
  condition>
extension>

示例3

<extension name="Test3.1">
   
  <condition field="destination_number" expression="^00(/d+)$">
    <action application="bridge" data="sofia/profilename/[email protected]"/>
  condition>
extension>

<extension name="Test3.2">
  
  <condition field="destination_number" expression="^00(.+)$">
    <action application="bridge" data="sofia/profilename/[email protected]"/>
  condition>
extension>

示例4

<extension name="Test4">
  
  <condition field="destination_number" expression="^00(/d+)$">
    <action application="bridge" data="sofia/profilename/[email protected]"/>
  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/[email protected]"/>
  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/[email protected]"/>
  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/[email protected]" />
    
    <action application="bridge" data="sofia/local_profile/[email protected]" />
  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/[email protected]

 

呼叫一個註冊用戶

沒有註冊別名的情況:sofia/my_profile/1234%mydomain.com

註冊別名的情況:sofia/mydomain.com/1234,注意:這裏沒有顯示指定profile文件。也可以這樣:user/[email protected]

 

通過網關呼叫

sofia/gateway/mygateway.com/1234

其中網關名就是mygateway.com,呼叫的用戶1234

 

呼叫時指定傳輸協議

傳輸協議可以是:TCP, UDP, TLS, SCTP,如:

sofia/my_profile/[email protected];transport=tcp

 

指定編解碼

{absolute_codec_string=XXXX}sofia/my_profile/[email protected]

 

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/[email protected] bridge:portaudio/auto_answer inline

 

修改SIP聯繫人

fs正常會用mod_sofia@ip:port做爲內部的聯繫人,如果想修改一下,

{sip_contact_user=foo}sofia/my_profile/[email protected];transport=tcp

 

使用定製的SIP URI

比如,要發送在“SIP:”開頭的URI,

sofia/my_profile/sip:xxxx;[email protected];user=phone
發佈了46 篇原創文章 · 獲贊 4 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章