1、前言
本文檔以asterisk-1.4.32爲基礎。web
2、Asterisk dialplan 基本結構
正則表達式
Asterisk dialplan 的語法能夠分爲四個關鍵點,也就是語法結構的四個組成部分,四個部分分別context ,extensionnum ,priority 和 action。由這四個組成部分dialplan的結構爲:
[context]
exten => extensionnum,priority,action
一、context
context是指dialplan的流程塊,整個dialplan就是由每一個context的內容組成,他們協做完成整個asterisk命令邏輯的運 轉。context的名字必須放在中括號之中,好比PSTN外線打進系統所執行的流程咱們都習慣叫from-pstn,在語法裏面就寫作"[from- pstn]"。全部屬於這個流程的內容都寫在這個下面。每個命令都由換行符來隔開,也就是說每一行就是一個命令,每一行命令都必須由"exten => "(這個裏面的空格能夠沒有)開頭。流程的結尾就是遇到到下一個流程標識截止。
二、extensionnum
extensionnum是指流程塊裏面的流程匹配標識(也就是asterisk裏面說的extension),這個匹配標識其實一般就是咱們要撥的號碼 (固然這個匹配標識不光是數字也能夠是字母或者一些特殊字符)。好比你撥分機101,而你設置的撥分機的流程塊是dial-ext,那麼asterisk 就會在dial-ext流程塊裏面尋找能匹配101的流程,找到了就會執行。說到匹配你們就會想到通配符吧,哈哈,asterisk裏面也有相似的通配 符,下面我就介紹一下asterisk裏面關於extension的通配符。
X和x表示單個0-9的數字
N和n表示單個1-9的數字
Z和z表示單個2-9的數字
.表示單個的任何字符和數字
[]中括號裏面能夠是你想任意的匹配的數字或者字母,好比你想匹配一、3或者6,那麼你就能夠這樣[136]或者[1,3,6],在中括號裏面還支持這樣[1-8]是指匹配1到8的任意一個數字。
當你的extensionnum中含有任何通配符的時候你就要用一個短的下劃線"_"來做爲extensionnum的開頭除了這些之外asterisk還有一些特殊意義的匹配字符,
s :是指Start extension,也就是當沒有extension的時候就會執行這個流程(例如在模擬外線進線沒有收到callerID的狀況下就會轉到這個 extension來執行),另外在zapata.conf的channels段裏面若是設定了immediate=yes程序就會自動找到s這流程來執 行。
t :是指timeout extension,也就是說若是等待用戶輸入超時後就會轉到t這個流程來執行,在這裏你能夠設置一些提示音來告訴客戶超時了。
i :是指invalid extension,也就是說若是客戶輸入無效的時候會轉到i這個流程來執行
fax :是指fax calls,也就是說若是asterisk檢測到傳真信號的時候就會自動轉到這個流程裏面來執行。
h :是指hangup extension,就是說呼叫終止後執行的流程,在這裏通道已經終止,放音、發送DTMF等命令都不可用了,只能作一些呼叫結束後處理的一些工做。
須要注意的是,無論你設置的流程是什麼都是屬於某個流程塊的,在不相互包含的狀況下,流程塊與流程塊之間是相互獨立的,流程或者變量是不會衝突的。
三、priority
priority是指流程裏面的命令的執行優先級,除了跳轉的狀況,都是按照priority值的之從 小到大執行的。在流程裏面你會常常看見"n"這個priority,它是指next也就是上一個priority+1.咱們一般還會給某個 priority取個名字,來方便咱們流程跳轉,也方便流程的閱讀。語法是這樣的 exten => extensionnum,priority(name),action ,name就是這個priority的名字。
exten => _123409XX,1,GotoIf([{EXTEN}=12340910]?ivr1:normal)
exten => _123409XX,n(normal),Dial(SIP/101)
exten => _123409XX,n,Goto(end)
exten => _123409XX,n(ivr1),BackGround(MyVox/Greeting)
exten => _123409XX,n(end),Hangup
上面這段代碼就是當匹配的號碼是12340901時就跳轉到ivr1這個priority上不然就跳轉到normal這個priority上。上面這段流程也能夠寫成:
exten => _123409XX,1,GotoIf([{EXTEN}=12340910]?4:2)
exten => _123409XX,2,Dial(SIP/101)
exten => _123409XX,3,Goto(5)
exten => _123409XX,4,BackGround(MyVox/Greeting)
exten => _123409XX,5,Hangup
四、action
action就相對好理解多了就是流程裏面你要執行的命令,asterisk支持的命令不少,我就介紹幾個比較經常使用的。全部命令的規則裏中括號裏面是可選 的部分,沒有中括號的必須填加的。參數之間的分隔符是"|",其實","來分隔也能夠,可是1.6版本的asterisk不行,1.6的只能用"|"。還 應該注意的是action的命令名有大小寫之分,寫錯將會出現錯誤,當命令沒有參數時能夠不用寫小括號。
1)、Answer
語法:Answer([delay])
應答一個振鈴的Channel。若是呼叫沒有被應答此方法將應答這個呼叫,若是delay這個參數指定那麼應答成功後將等待delay秒後再 返回執行下條命令,應答不成功就會直接返回錯誤返回值而不執行delay延遲。這個命令用於呼入的狀況,呼出的時候不會真正執行answer操做可是會執 行delay延遲。
2)、Playback
語法:Playback(filename[&filename2...][|option])
給當前Channel播放語音文件。第一個參數是語音文件,語音文件的格式asterisk默認的是gsm,其餘wav、sln、vox、pcm等也都支 持,可是最好用gsm格式的文件,若是沒有gsm格式的能夠用sox這個工具把格式變爲gsm的,通常變成gsm格式的語音播放起來就不會有什麼問題了。 播放的語音文件也能夠是多個,每一個之間用"&"來分隔,語音文件的擴展名不用寫,語音文件中不能有空格,最好就是字母和數字的組合,爲了語義的需 要能夠用下劃線來分隔。當一個語音文件出現問題時命令就會中止,後面的語音文件就不會再被播放了。語音文件是相對地址也能夠是絕對地址,相對地址的默認路 徑是/var/lib/asterisk/sounds/。
第二個參數是一些控制變量,這個參數是可選的:
skip :若是這個變量設置,並且當前通道沒有UP,命令就會馬上結束,不播聽任何語音。
noanswer :若是設置這個變量,在當前通道沒有UP的時候,就不會執行anwser來UP這個通道。
say :若是設置這個變量,在播放語音以前會把要播放的語音文件名都出來。
j :若是設置這個變量,當語音文件播放出現問題的時候,流程就會跳轉到priority+101這個priority繼續執行。
通道變量PLAYBACKSTATUS,通道變量的值一般都是一個字符串,當語音播放成功後PLAYBACKSTATUS爲SUCCESS,不然爲FAILED。當播放多個文件時只要有一個文件播放失敗PLAYBACKSTATUS即爲FAILED。
3)、BackGround
語法:Background(filename1[&filename2...][|options[|langoverride][|context]])
給當前Channel播放語音文件,並等待客戶輸入,來執行相應的extension。第一個參數是語音文件,這個參數的用法跟Playbcak的第一參數用法同樣。
第二個參數是一些控制變量,這個參數是可選的:
s :若是這個變量設置,並且當前通道沒有UP,命令就會馬上結束,不播聽任何語音。
n :播放語音前不用answer這個通道
m :只有當用戶輸入的能和參數context中的流程匹配才結束。
p :只播放不接受用戶輸入。
第三個參數是指播放聲音的語言,這個參數是可選的。
第四個參數是指當用戶輸入後要去尋找匹配並執行的context,在多層的IVR中這個參數是關鍵,這個參數是可選的。
4)、Dial
語法:Dial(Technology/resource[&Tech2/resource2...][|timeout][|options][|URL])
這個命令會是當前通道呼叫一個或多個Channel,其中有一個Channel應答,當前通道就會和這個Channel橋接在一塊兒,其餘Channel就會掛斷。
第一個參數是要呼叫的通道能夠是多個每一個之間用"&"來分隔。
第二個參數是超時時間,單位爲秒,若是不設置超時時間,呼叫就會一直等到對方應答爲止。
第三個參數是一些控制變量:
A(x) :當被叫方應答的時候給被叫方播放一段語音,x爲要播放的語音文件
C :從新設置CDR
d :容許主叫方在等待被叫方應答的時候,按一個數字鍵跳轉到這個數字所能匹配的流程中,新的流程是指定在EXITCONTEXT變量中設置的流程,若是EXITCONTEXT沒有被指定那麼就在當前context中尋找。
D([called][:calling]) :發送DTMF到主叫方或者被叫方,當被叫應答可是通道尚未橋接的時候。
f :強制爲被叫方Channel設置CallerID,用當前的extension
g :當對方掛機的後,接着當前的context執行
G(context^exten^pri) :當呼叫被應答以後,將主叫方跳轉到指定的priority中執行,被叫跳轉到指定的priority+1中執行,指定的priority由G的參數指定。
h :容許被叫方按"*"結束會話
H :容許主叫方按"*"結束會話
i :忽略任何forwarding請求
j :當全部呼叫請求都忙的時候跳轉到當前priority+101處
k :容許被叫使用parking功能
K :容許主叫使用parking功能
L(x[:y][:z]) :限定呼叫'x'ms,當剩下'y'ms時播放一個警告,重複這個警告每隔'z'ms。下面這些變量是用於這個操做:
LIMIT_PLAYAUDIO_CALLER yes|no (default yes) 對主叫播放語音
LIMIT_PLAYAUDIO_CALLEE yes|no 對被叫播放語音
LIMIT_TIMEOUT_FILE 時間到的時候播放的語音
LIMIT_CONNECT_FILE 呼叫開始時播放的語音
LIMIT_WARNING_FILE y定義的那個警告的語音,通常都是播放還剩多少時間
m([class]) :爲主叫提供hold music在Channel應答以前。
M(x[^arg]) :爲被叫Channel執行指定的宏,在還未和主叫橋接以前。被指定的參數能夠用"^"來分隔。宏執行完後後會返回一個變量MACRO_RESULT來指示接下來要執行的命令:
ABORT 通話兩端都掛斷
CONGESTION 當線路催掛的時候執行,也就是設置完CONGESTION狀態,而後繼續執行流程
BUSY 當線路忙的時候執行,若是j這個參數被設置則,跳轉到priority+101處執行
CONTINUE 掛斷被叫,主叫繼續執行流程
GOTO:<context>^<exten>^<priority> 跳轉到指定的流程處繼續執行
注意:TIMEOUT()函數不能用在宏中
n([x])和N :修改screen/privacy模式. ;screen/privacy就是在被叫應答後尚未橋接以前給被叫播放一段IVR來讓它作一些操做,其中就有選擇是否願意接受這個呼叫
p和P([x]) :設置screen/privacy模式.
o :指定主叫Channel的callerID爲被叫Channel的CallerID。
O([x]) :設置Operator Services模式,只對zaptel和dahdi通道有效
r :主叫等待應答是爲主叫播放回鈴音
S(x) :應答後x秒掛斷通話
t :容許被叫發送DTMF實現transfer主叫 詳細信息在features.conf中設置
T :容許主叫發送DTMF實現transfer被叫 詳細信息在features.conf中設置
w :容許被叫發送DTMF爲通話錄音 詳細信息在features.conf中設置
W :容許主叫發送DTMF爲通話錄音 詳細信息在features.conf中設置
第四個參數是一個url地址,若是通道支持這個url將發送給被叫
通道變量:
DIALEDTIME 這個變量是指從呼叫開始到會話結束的時間
ANSWEREDTIME 這個變量是指應答開始到會話結束的時間
DIALSTATUS 這個變量顯示的是呼叫的結果狀態有如下一些值CHANUNAVAIL | CONGESTION | NOANSWER | BUSY | ANSWER | CANCEL | DONTCALL | TORTURE | INVALIDARGS ,在Privacy和Screening模式中,被叫選擇發送主叫到'Go Away'腳本時狀態變爲DONTCALL;發送到'torture'腳本時狀態變爲TORTURE。
5)、Hangup
語法:Hangup([causecode])
這個命令是掛斷一個Channel。可選的參數是指定掛機的緣由。
6)、Goto
語法:Goto([[context|]extension|]priority)
這個命令是跳轉到指定priority處執行,默認是當前的context和extension。當輸入的context直接掛機,當輸入的 extension和priority錯誤會在當前context尋找i流程來執行,若是i不存在就尋找h流程來執行,若是連h也不存在,就掛機。當沒有 任何參數的時候該通道也會掛機。
7)、GotoIf
語法:GotoIf(condition?[labeliftrue]:[labeliffalse])
這個命令是有條件的跳轉,跟c語言中的?:語句有點相似,當condition的條件爲1時跳轉到labeliftrue處,不然跳轉到 labeliffalse處。label的格式爲[[context|]extension|]priority。其餘就跟Goto命令同樣。
就先介紹這幾個經常使用的,別的一些會在下一篇中介紹。
3、Dialplan中的變量和邏輯表達
a、Dialplan中的變量經過變量名來引用和標識,變量名不一定要大些,但是大些可有助於閱讀。 1)、全局變量 全局變量適用於所有的Context所有的extension。全局變量可以在[globals]段中定義,也可以通過SetGlobalVar()來定義。下面舉個例子。 [globals] OUTLINE=Zap/g1 或 [from−ext] exten=>9XXXXXXX.,1,SetGlobalVar(OUTLINE=Zap/g1) 2)、通道變量 通道變量是特定的呼叫相關的變量,與全局變量不同,通道變量只能在當前呼叫存在期間定義,並只能用於參與該呼叫的通道。有很多預先定義的通道變來那個可以用於Dialplan,在asterisk源程序中的doc子目錄下channelvariables.txt文件中有詳細的介紹。通道變量可以通過Set()來設置。例如: exten=>123409XX,1,Set(INCOMING={EXTEN})
EXTEN就是一個asterisk已經預先定義的變量,他表示的就是當前的extension。既然提到了EXTEN變量在這裏順便就說一下變量的截取,語法是這樣的:variablename[:offset[:length]]。舉個例子倆說明一下: exten=>12340900,1,Set(INCOMING={EXTEN})
這個裏面EXTEN就是12340900,如果我只想要後四位那怎麼辦那?{EXTEN:4}就表示0900了,也就是去掉了EXTEN的前四位;那要是想要前四位怎麼辦那?很簡單{EXTEN:0:4}就表示1234了。offset和length也能夠是負數,offset是負數表示 要的是從後面數|offset|個數,length是負數表示要的是除了從後面數的|length|個數。哈哈,說的不太明白舉個例子 吧。EXTEN:−4也表示0900,{EXTEN:-2}就表示00,EXTEN:2:4表示3409,{EXTEN:2:-2}也表 示3409,EXTEN:−6:−2也表示3409. 3)、環境變量 環境變量是一種在asterisk裏面訪問操做系統環境變量的一種方法。這些變量以{ENV(var)}的形式引用,其中var就是要引用的操做系統環境變量。
b、邏輯表達式,你應該沒有忘記var表示變量,邏輯表達式和這個差不多[expression].[1 +
2]就表示1+2的結果3.中括號中運算符和變量之間最好用空格分開,不然可能會出現錯誤的結果。固然中括號裏面能夠是任意運算符。這些預算符包括:
1)、邏輯運算符
expr1
|
expr2
當expr1爲真,賦值爲expr1的值,不然爲expr2的值
expr1
&
expr2 當expr1和expr2的值都爲真時,賦值爲expr1的值,不然賦值爲0
expr1
{=, >, >=, <,
<=, !=}
expr2 若是自變量都是整數,將獲得一個整數的比較結果;不然他們將獲得字符串的結果,若是給定的關係是正確的,這個結果是1,不然就是0.
!
expr1 取反,當expr1是NULL、0、一個空字符串、或者一個字符串"0",返回1;不然返回0.
2)、數學運算符
expr1
{+, -, *, /, %}
expr2 加減乘除餘數
-
expr1 取負
3)、正則表達式運算符
expr1
:
expr2 這個運算符expr2匹配到expr1,expr2必須是個表達式,若是匹配成功,被匹配的表達式包括了至少一個正則表達式的字表達式,整個表達式對應返回(1
or \1);另外,匹配操做符返回字符匹配上的數量。若是匹配失敗,返回空值。其餘狀況返回0.
expr1
=~
expr2 這個運算符和:很像,惟一區別就是這個能夠不從字符串的開始匹配。
4)、三態運算符
expr1
? expr2 :
expr3 這個用法就不用說了,說說expr1的否的條件就好了,數字的話是0,字符串時""(空串)。
c、運算符優先級
1)、(,)
2)、!,-
3)、:,=~
4)、*,/,%
5)、+,-
6)、=,!=,<,>,<=,>=
7)、|,&
8)、?:
4、撥號方案函數
撥號方案函數能夠增長更多功能到你的表達式中,你能夠想象他們運行起來和操做符相似,可是更高級一些。
語法:FUNCTION_NAME(argument)
很是像變量,你能夠引用函數名,可是你若是要引用函數的值,就要用美圓""放在前面,用花括號"{}"括起函數表達式。就像這樣:
FUNCTIONNAME(argument) 函數也可以嵌套封裝其他的函數,如下:{FUNCTION_NAME({FUNCTION_NAME(argument)})}
舉個例子吧:
exten
=> 123,1,Set(TEST=example)
exten
=> 123,2,SayNumber({LEN({TEST})})
上面這個例子能算出字符串example有7個字符,將字符串的數量賦值給變量長度,而後將數量送給SayNumber().
5、Include
Asterisk容許在一個context中使用另外一個context,經過include指令來實現。這用來授予訪問權給不一樣的撥號方案段。介紹一下語法:
語法:include =>
context
在當前context包含另外的context時,必須注意包含順序。Asterisk首先試圖在當前context中匹配
extension。若是不成功,會試圖嘗試第一個包含進來的context,而後按照包含順序再去嘗試其餘的context。就跟把包含的contex
拷貝到當前context的後面有點相似。另外還有一種include的應用就是一個dialplan文件包含另外一個dialplan文件,意思和上面說
的include用法差很少,只不過這回是文件。
語法:#include FILENAME
這個在elastrix中應用的比較多,差很少每一個關鍵的配置文件都包含另外一個附加的配置文件。舉個在elastrix裏面的例子,在extensions.conf
文件中你會發現這樣的語句:
#include
extensions_additional.conf
#include
extensions_custom.conf
6、宏macro
你若是熟悉計算機編程,那麼你對宏就確定不會陌生,dialplan也支持。你能夠定義一個宏指令,它包含多步的指令列表,而後讓電話extension指向這個宏指令。
語法:[macro-MACRONAME]
exten
=> s,1,action
exten
=> s,n,action
exten
=> s,n,action
調用語法:exten =>
Macro(macroname,arg1,arg2...)
宏指令的名字必須以macro-做爲開始。這是他們與常規的context的區別。Dialplan中的宏指令的命令同其餘任何命令很類似。惟一的限制因素是宏指令只能用"s"extension。咱們先定義一個宏指令:
[macro-dial]
exten =>
s,1,Dial(SIP/101)
exten =>
s,n,VoiceMail(101)
接下來咱們看看怎樣調用宏指令:
exten
=>
_123409XX,1,GotoIf([EXTEN=12340910]?4:2) exten=>123409XX,2,Macro(dial) exten=>123409XX,3,Goto(5) exten=>123409XX,4,BackGround(MyVox/Greeting) exten=>123409XX,5,Hangup 此外Macro()程序也定義了幾種特別的變量來爲我們使用。它們包括:{MACRO_CONTEXT} 這個被調用宏中,初始的context
MACROEXTEN 這個被調用宏中,初始的extension{MACRO_PRIORITY} 這個被調用宏中,初始的priority
MACROOFFSET 宏返回後從{MACRO_OFFSET}+n+1的priority處執行
ARGn 傳遞到宏指令的第n個變量。例如第一個自變量是{ARG1},第二個是ARG2 爲了舉個使用變量的例子,我們把上面例子的宏修改一下: [macro−dial] exten=>s,1,Dial(SIP/1{MACRO_EXTEN:6})
exten => s,n,VoiceMail(1${MACRO_EXTEN:6})
這樣當撥的是12340901時宏就執行Dial(SIP/101),並給並留言到101語音信箱裏面。express