參見<Asterisk 將來之路>git
by lwb12915@163.comweb
Asterisk譯爲星號(*)在不少應用中被用作通配符,Astrisk作爲PBX系統的完美名稱,緣由之一是Asterisk能夠鏈接數目龐大的接口類型,包括:正則表達式
1模擬接接口,如你的電話線或模擬電話.express
2數字線路,如T-1和E-1線路安全
3Voip協議,如SIP和IAX服務器
目前正式版本是IAX2,可是IAX1的全部格式都已經停掉.因此當說到IAX都是特拽IAX2app
使用接口配置文件dom
1.Zaptel.conf:硬件接口基層配置,咱們將創建一個FX0和一個FXS通道.ide
2.zapata.conf:硬件配置Asterisk的接口.函數
3.extension.conf:撥號方案文件.
4.sip.conf:配置SIP協議的文件
5.iax.conf:配置呼入和呼出IAX通道的文件
FXO與FXS通訊
區別:區別簡單,就在於鏈接的那端提供撥號音.FXO不生成撥號音,而是接收.FXS端口提供撥號音和震鈴電壓,在有呼叫的時候提醒用戶.二者接口都提供雙向通信(同時雙方向的通信傳輸).
若是Asterisk有個兼容FXO端口,就能夠把電話線接入這端口,可使用這根電話線呼叫和接收電話呼叫.同理,若是有個FXS端口,能夠鏈接一部模擬電話,Asterisk就能夠呼叫這部電話,可能也能夠呼叫.(端口:經過配置使用的信令進行定義)
FXS卡必須像中心局(CO)進行運轉,使用FXO信令.同理,FXO卡鏈接CO,就意味着它須要像終端進行運轉,使用FXS信令.
Zaptel配置(FXO)
在/etc/zaptel.conf文件,用於配置硬件,能夠定義FXS端口與FXO信令的配置
fxsks=1 ;定義fxs端口採用通道1以ks信令協議 ;fxoks=2 ;定義fxo端口採用通道2以ks信令協議 loadzone=us defaultzone=us |
信令協議:Loop start(ls),ground start(gs),kewlstart(ks),使用ks外信令協議,把fxoks中的ks替換ls或gs,Asterisk的模擬電路推薦ks信令協議.
******編輯完zaptel.conf文件,須要使用/sbin/ztcfg -vv裝載配置到硬件(不需要詳細輸出能夠省略-vv);修改信令方法須要重啓.在編輯sip.conf和iax.conf文檔後,分別須要裝載chan_iax2.so和chan_sip.so
Zapata配置
[trunkgroups] ;定義一個主幹組 ; define any trunk groups [channels] ;硬件通道和他們選項信令方式. ; hardware channels ;硬件通道 ; default ;默認 busydetect=yes ;增長這兩行,要不FXO口不能檢測到掛機信號。 usecallerid=yes ;設置來電顯示 hidecallerid=no ;設置去電不隱藏號碼 callwaiting=yes ;設置呼叫等待 threewaycalling=yes ;開啓三方通話(先閃斷,再呼叫第三方,再閃斷,就能夠實現三方通話) transfer=yes ;轉叫前轉(須要三方通話支持) echocancel=yes ;回聲消除 echotraining=yes ;迴音練習(會話前發個聲音,用於測試回聲) ; define channels ;定義通道 context=from-test ; Context內執行指令須要在extensions.conf內定義 [from-test] signalling=fxs_ks ;FXO通道使用FXS信令 channel => 2 ; PSTN放在端口2上 |
容許zaptel和其它設備經過PCI硬件安裝到系統中,編輯udev
[root@ask asterisk]# vi /etc/udev/rules.d/50-udev.rules #在末尾添加上如下 KERNEL="zapctl", NAME="zap/ctl" KERNEL="zaptimer", NAME="zap/timer" KERNEL="zapchannel", NAME="zap/channel" KERNEL="zappseudo", NAME="zap/pseudo" KERNEL="zap[0-9]*", NAME="zap/%n" |
Dialplan配置
基本的撥號方案,使用Echo()校驗工做通道雙向通信;
[from-test] exten => s,1,Answer() exten => s,n,Echo() |
SIP
SIP(會話初始協議),一般用於VOIP電話,進行呼叫創建,呼叫協商,呼叫結束.它幫助兩個端互相通認,但它不處理媒體;當呼叫創建後,他經過實時傳輸協議(RTP)在電話A到電話B直接傳輸媒體.
SIP和RTP
SIP是一個應用層的信令協議.他使用的端口是5060(一般)進行通訊.SIP能夠經過UDP和TCP傳輸層協議進行傳輸.Asterisk目前沒有TCP用於傳輸SIP信息.
RTP用於端點間傳輸媒體(語音),Asterisk中RTP使用大數字的無特權端口(默認10,000到20,000)
SIP優勢:普通的被接受和結構靈活.其它的VOIP協議還有H.323,IAX,MGCP.
SIP配置
/etc/asterisk/sip.conf文件中:
[general] context=default srvlookup=yet ;創建一個邏輯和可解析地址的方法,你能夠達到這個地址,還能夠獲取DNS不少好處 [10000] username=10000 ;用戶名 type=friend ;能夠定義用戶(user)\端(peer)\朋友(friend) secret=123456 ;認證密碼 record_out=Always;去電錄音Adhoc需要時,Never從不,Always老是 callgroup ;呼叫組,默認爲"1" pickupgroup ;代接組 disallow ;不容許編碼 allow ;容許編碼 port=5060 ;端口號 qualify=yes ;監視Asterisk服務器與電話之間是否延時(默認2,000可達;yes可替換毫秒) context=default ;指令的地點 host=dynamic ;要求號碼要註冊,以便Asterisk如何找到電話.(static則不須要註冊) dtmfmode=rfc2833 ; callerid=test1 <10000> canreinvite=no ; |
用戶戶類型是用於認證呼入呼叫;端類型用於呼出呼叫;朋友類型兩種都用.(這個經常使用在sip.conf與iax.conf中用到)
IAX
IAX(Inter Aasterisk eXchange)協議一般用於服務器間通訊.IAX和SIP協議最大區別在於媒體(語音)在端點之間傳輸的方式不一樣.
Asterisk默認狀況是在5060端口接收SIP信令,在10000-20000端口接收RTP(媒體)流.而IAX全部的信令和媒體流都經過一個端口4569進行傳輸.這種方式的好處是IAX協議能更適合在NAT相關拓撲的應用.
IAX用戶習慣對進入PBX系統的呼叫進行鑑權和處理.對從PBX系統呼出的呼叫,Asterisk應用IAX的iax.conf文件的端點進入(條目)對遠端進行鑑權)
經過iax.conf設置進行呼叫的鑑權和處理:
[general] ;至少須要一個主要段落,主要定義IAX協議的相關設置. jitterbuffer=no
register => remote_number:password@domain ;註冊到遠程服務器上,告訴服務器當前位置(互聯網位置)在哪
[REC_SERVER] type=user ;用user來定義呼入呼叫的類型 context=incoming ;進行呼入呼叫鑑定 auth=rsa inkeys= ;公鑰,是Asterisk標準
經過extensions.conf設置一個incoming的context: [incoming] exten => remote_number,1,Dial(SIP/number) ;撥打遠程號碼時(呼入)轉移到number(內部)號碼上 |
--------以上是IAX入局配置,下面配置出局IAX鏈接--------
在iax.conf設置呼出條目
[REMOTE_SERVER] type=peer ;用peer定義呼出類型 host=my.receiving.server.ca ;接收服務器域名或IP地址 username=number ;接收服務器認證用戶(帳戶號碼) secret=password ;接收服務器認證密碼(帳戶密碼) qualify=yes ;不時檢查遠端的服務器是否響應用 disallow=all ;用於復位原來設置的全部編碼信息 allow=gsm ;支持gsm編碼 allow=libc ;支持libc編碼 allow=g726 ;支持持g726編碼 ****使用disallow復位原來設置的全部編碼信息.再從新設置支持的編碼,優先級從高到低 |
在extensions.conf設置
[to_remove] exten => remove_number,1,Dial(IAX2/REMOVE_SERVER/number) |
撥號方案語法
Asterisk的撥號方案在文件extensions.conf中定義(/etc/asterisk/extensions.con)
extensions.conf(四部分:context,extension,priorities,application)
context:用於對extensions組命名,把撥號方案的不一樣部分進行分離,省得交織在一塊兒.
表示方法是把名字放在[]的中間,名字只能用a~z,A~Z,0~9,以及連字號和下劃線組成(空格不在容許的字符裏面,context中不要使用空 格).如:[context1],[incoming],[default];全部放在context定義的以後的指令都是這個context一部分,直 到下一個context定義的開始.
context的一個重要用途就是增強安全性.若是沒有仔細設計撥號方案,可能會形成別人盜用你的系統的不良後果.
extensions:extensions是asterisk要執行的指令,由來電或通道上所撥數字來觸發.能夠定義電話分機
extension的語法是單詞exten後面跟着一個由等號和大於號組成的箭頭,如:exten => extension的名字
一個完整的extension由三部分組成:
extensions的名字或號碼 priority(每一個extension能夠有多個步驟,步驟的編號稱做priority) |
應用(或者命令),針對呼叫完成一些動做
這三個部分用英文逗號分開,如:
exten => name,priority,application() |
priorities:每一個extension均可以有幾個步驟,稱做priorities。如:
exten=>50001,1,Answer() #編號爲1的priority,執行接聽電話 exten=>50001,2,Hangup() #編號爲2的priority,而後掛電話 |
必須確保priority從1開始而且連續的編號
application:動做,好比:播放聲音,接受音頻撥號輸入或者掛斷電話等.
Application
Answer(),Playback()和Hangup()應用
Answer()應用於接聽正在響鈴通道,它不須要任何參數.
Playback()應用在通道上播放事先錄製好的語音文件.指定一個文件名(不帶擴展名),可使用絕對路徑與相對路徑.
Hangup()應用在於掛斷一個正在活動的通道.
Background(),Goto()應用
Background()它也播放事先錄製好的語音文件,但它等待按鍵,而後執行對應extension.
防止Background()後超出按鍵範圍,使用i來解決問題.
防止Background長時間沒有選擇,使用t來決解問題.
Goto()應用使得在撥號方案的不一樣部分有序的轉移很是容易.
Goto()應用有三個參量分別是context,extension,和priority.即Goto(context,extension,priority)
Dial()應用
Dial()有4個參量,
第一個是:呼叫的被叫地(傳輸技術/遠地資源)如:SIP/50000或Zap/1.能夠同時撥打多個通道如:
exten => 601,1,Dial(Zap/1&SIP/50000&IAX/60000) |
第二個是:超時,單位"秒".給定超時參量Dial會一直對被叫地進行呼叫,直到超時後才放棄,若是沒有給定,將直到接聽或主叫掛機,若是呼叫在超時前接聽,通道就被橋接,撥號完成
補充:若是超時後被叫地沒有應答,則會繼續Dial()的extension下一個priority.若是被叫地通道忙,Dial()將轉到 priority n+101(n是Dial()被調用的priority),若是存在的話,將可以處理被叫地忙的方式接叫未接電話.
第三個是:可選擇參量,它會能夠影響到Dial()的行爲,如:
exten => 601,1,Dial(SIP/50000,30,Ttwr) |
其中T表示容許主叫用戶按"#"轉接呼叫;t表示容許被叫用戶按"#"轉接呼叫;r表示爲被叫用戶產生振鈴聲;w用戶按"*"鍵開始錄音.
最後一個是:URL參量.如:
exten => 601,1,Dial(SIP/60000@asterisk.voip.org) exten => 602,1,Dial(Zap/1/5732381) |
任何參量均可覺得空如:
exten => 601,1,Dial(SIP/60000,,T) 或 exten => 601,1,Dial(SIP/60000) |
綜合上面舉個例子:
[test] exten => s,1,Answer() exten => s,2,Background(enter-ext-of-person) exten => 601,1,Dial(Zap/1,30,Ttrw) exten => 601,2,Playback(vm-nobodyavail) exten => 601,3,Hangup() exten => 601,102,Playback(tt-allbusy) exten => 601,103,Hangup() exten => 602,1,Dial(SIP/50000,30,Ttrw) exten => 602,2,Playback(vm-nobodyavail) exten => 602,3,Hangup() exten => 602,102,Playback(tt-allbusy) exten => 602,103,Hangup( ) exten => i,1,Playback(pbx-invalid) exten => i,2,Goto(test,s,1) exten => t,1,Playback(vm-goodbye) exten => t,2,Hangup() |
Extension,不能多於80個字符,也不能少於1個字符(601/602)
------2007-01-05-修改
變量
在撥號方案中使用變量能夠減小打字、增長清晰度,也有助於在撥號方案中加入邏輯.
這裏的變量有全局變量,通道變量和環境變量.
全局變量:
全局變量應該在extensions.conf文件的開始利用[globals]這個context定義或利用 SetGlobalVar()應用.如:
[globals] 80000=Zap/1 或 [internal] exten => 123,1,SetGlobalVar(80000=Zap/1) |
通道變量
通道變量與特定的呼叫相關的變量,通道變量只能在當前呼叫存在其間定義,並只能用於參與該呼叫的通道.通道變量使用 Set()應用來設置.如:
exten => 601,1,Set(80000=Zap/1) |
環境變量
環境變量是一種在 Asterisk 中訪問操做系統環境變量的方法.這些變量以${ENV(var)}形式引用,其中的 var 是所要引用的操做系統環境變量.
綜合上面舉例:
[globals] PSTN=Zap/1 TEST=SIP/80000
[test] exten => s,1,Answer() exten => s,2,Background(enter-ext-of-person) exten => 101,1,Dial(${PSTN},10) exten => 101,2,Playback(vm-nobodyavail) exten => 101,3,Hangup() exten => 101,102,Playback(tt-allbusy) exten => 101,103,Hangup() exten => 102,1,Dial(${TEST},10) exten => 102,2,Playback(vm-nobodyavail) exten => 102,3,Hangup() exten => 102,102,Playback(tt-allbusy) exten => 102,103,Hangup() exten => i,1,Playback(pbx-invalid) exten => i,2,Goto(incoming,s,1) exten => t,1,Playback(vm-goodbye) exten => t,2,Hangup()
[default] exten => 101,1,Dial(${PSTN},,r) exten => 102,1,Dial(${TEST},,r) |
模式匹配
模式匹配
使用模式及匹配是用不一樣的字母和符號來表明可能要匹配的數字.模式老是用一個下劃線 (_) 開始,它告訴Asterisk 要作模式匹配,這不是一個 extension 名字.(這意味着不能使用下劃線做爲 extension 名字的開始字符.)
模式匹配語法
在下劃線以後,可使用一個或者多個下面列出來的字符:
X:匹配 0-9 的任何數字; Z:匹配 1-9 的任何數字; N:匹配 2-9 的任何數字; .(句號)通配符,匹配一個或多個字符; [15-7]:匹配1,5,6,7; |
使用EXTEN通道變量:Asterisk會把通道變量{EXTEN}設置爲所撥的數字.經過sayDigits()檢測撥到號碼內容如:
exten => _9XXXXXXX,1,SayDigits(${EXTEN}) ;SayDigits()應用會把所撥的8位extension讀出來
exten => _9XXXXXXX,1,SayDigits(${EXTEN:1}) ;只讀出來後7位數,其中"1"表示不撥前面1位數
exten => _9XXXXXXX,1,SayDigits(${EXTEN:-1}) ;只讀出來最後1位,其中"1"表示只撥出最後1位數 |
去話撥號(PSTN)
舉例:按"9"後撥打外線,去電時,去除"9";加放"ignorepat => 9"是爲了使按完"9"後還能夠聽到撥號音;加入"Congestion()"應用是掛機或忙的時候播放快忙音(擁擠聲音).
---本地去話撥號--- [outbound-local] ignorepat => 9 exten => _9NXXXXXX,1,Dial(Zap/1/${EXTEN:1}) exten => _9NXXXXXX,2,Congestion() exten => _9NXXXXXX,102,Congestion() ---再加入緊急電話撥號--- exten => 9119,1,Dial(Zap/1/119) exten => 119,1,Dial(Zap/1/119) exten => 9110,1,Dial(Zap/1/110) exten => 110,1,Dial(Zap/1/110) ---長途電話撥號--- [outbound-long] exten => _90NXXNXXXXXX,1,Dial(Zap/1/${EXTEN:1}) exten => _90NXXNXXXXXX,2,Congestion() exten => _90NXXNXXXXXX,102,Congestion() |
Includes
Asterisk經過Includes實如今一個context中使用另外一個context.格式:includes => context
[internal] include => outbound-local include => outbound-long exten => _80XXX,1,Dial(SIP/${EXTEN},30,r) exten => _80XXX,2,Playback(vm-nobodyavail) exten => _80XXX,3,Hangup() exten => _80XXX,102,Playback(tt-allbusy) exten => _80XXX,103,Hangup() |
表達式和可變操做
表達式
表達式是變量,運算符和數值的聯合,當你把它們組合到一塊兒就會獲得一個表達式結果.在Asterisk 中,表達式老是以$符合做爲開始,以方括號「[]」來擴住表達式.如:
$[expression] [{COUNT} + 1] [{COUNT} / 2] ;引用變量,必須把這個變量名用花括號"{}"括起來,並且在前面加上美圓符號"$" 標示出來 |
運算符
布爾型運算符
expr1 | expr2("|"或運算):若是expr1的值是真值,那麼運算符將賦expr1的值,不然將賦expr2的值.
expr1 & expr2("&"與運算):若是兩個表達式的值都爲true,運算符將賦值爲expr1,不然賦值爲0.
expr1{=,>,>=,<,<=,|=}expr2:若是自變量都是整數,這些運算符將獲得一個整數的比較結果;不然,它們將獲得字符串的結果.若是給定的關係是正確地,這個結果是1,不然就是0.
數學運算符
expr1{+, -}expr2:運算符能獲得整數自變量的加法或者減法地結果.
expr1{*,/,%}expr2:運算符能分別獲得整數自變量的乘法,除法或是餘數的結果.
正則表達式運算符
expr1:expr2:運算符匹配 expr2到expr1,這裏的expr2必須是一個正則表達式.
***Asterisk 的分析程序很是簡單,所以在你輸入時,在運算符和其餘數值之間至少須要一個空格.
撥號方案函數
撥號方案函數可使你增長更多的功能到你的表達式中.
語法
基本語法:FUNCTION_NAME(argument).若是要引用函數的值,和引用變量的值同樣,用美圓符號「 $」 加上花括號「{}」 括起函數表達式.如:
${FUNCTION_NAME(argument)} |
函數也能夠嵌套封裝其餘的函數,如:
{FUNCTION_NAME({FUNCTION_NAME(argument)})} |
撥號方案函數
函數經常用來鏈接set()應用,來取得或者賦值一個變量的值.舉個例子,計算一下一個字符串的長度,並讀出這個長度;
exten=>123,1,set(TEST=example) ;賦值example變量給TEST exten=>123,2,saynumber({LEN({TEST})}) ;計算出變量TEST長度,並讀出長度數 結果是:7 |
若是咱們要設置一個動態通道的超時,應該用TIMEOUT()函數.這個函數能夠接受如下三個中的一個作爲自變量,分別是absolute,digit 和response.他們對應的應用是AbsoluteTimeout(),DigitTimeout()和ResponseTimeout().用 timeout()函數,設置數字的超時,咱們能夠set()函數, 如:
exten=>s,1,set(TIMEOUT(digit)=30) |
***這個函數中沒有.它和給一個自變量賦值一樣,我們就賦值給一個函數,是不使用{}封裝的.