Asterisk权威指南/第六章 拨号计划基础
撥號計劃是你的Asterisk系統的心臟。它定義了呼叫是如何流進和流出系統的。撥號計劃用一種腳本語言寫成的,Asterisk依照其中的指令響應外部觸發。和傳統電話系統相比,Asterisk的撥號計劃是完全可定制的。
本章介紹Asterisk的基本概念。這里講的內容對你理解撥號計劃代碼至關重要,同時也是你寫任何撥號計劃的基礎。示例的設計是有前后承接關系的,我們建議你不要逃過本章的太多內容,因為本章對理解Asterisk十分重要。也請你明白本章不可能是對撥號計劃的能力的完全闡述;我們的目標是基礎知識。后面的章節我們會介紹撥號計劃更高級的內容。我們鼓勵你做試驗。
目錄
- 1撥號計劃語法
- 1.1上下文
- 1.2分機
- 1.3優先級
- 1.3.1不編號的優先級
- 1.3.2“same =>”操作符
- 1.3.3優先級標號
- 1.4應用程序
- 1.5Answer(),Playback()和Hangup()應用程序
- 2一個簡單的撥號計劃
- 2.1Hello World
- 3構建一個交互式撥號計劃
- 3.1Goto(),Background(),和WaitExten()應用程序
- 3.2處理無效入口和超時
- 3.3使用Dial()應用程序
- 3.3.1參數一:目標
- 3.3.2參數二:超時
- 3.3.3參數三:選項
- 3.3.4參數四:URI
- 3.3.5更新撥號計劃
- 3.3.6空白參數
- 3.4使用變量
- 3.4.1全局變量
- 3.4.2信道變量
- 3.4.3環境變量
- 3.4.4為撥號計劃添加變量
- 3.5模式匹配
- 3.5.1模式匹配語法
- 3.5.2模式匹配范例
- 3.5.3使用${EXTEN}信道變量
- 3.6包含
- 4結束語
撥號計劃語法
Asterisk撥號計劃在名為extensions.conf的配置文件中定義。
注:extensions.conf文件通常位于/etc/asterisk目錄下,但它的位置會視你如何安裝Asterisk而不同。這個文件的其他常見位置包括/usr/local/etc/asterisk和/opt/etc/asterisk。
撥號計劃由四個主要概念構成:上下文、分機、優先級和應用程序。在解釋完這些要素在撥號計劃中各自扮演的角色后,我們將讓你建立一個基本的但是能工作的撥號計劃。
注:示例配置文件。如果你在安裝Asterisk的時候安裝了示例配置文件,你就很可能已經有了一個現成的extensions.conf文件。不要從示例文件喀什,我們建議你從空白開始建立你自己的extensions.conf文件。對于學習如何建立撥號計劃來說,從示例文件開始不是最好的方式,也不是最容易的方式。
上下文
撥號計劃被分成不同的部分,稱為上下文。上下文使得撥號計劃的不同部分之間不會發生交互。在某個上下文中定義的分機是跟任何其他上下文中的分機完全隔離的,除非明確指定有交互。我們會在本章的末尾講到如何允許上下文之間發生交互。
作為一個簡單的例子,想象一下我們有兩家公司共享一臺Asterisk服務器。如果我們把每家公司的自動接待都放在他們各自的上下文中,他們彼此間就完全分開了。這就允許我們獨立地定義什么分機做什么,比如撥分機0的時候:從A公司的語音菜單撥分機0會找到A公司的接待員,而從B公司的語音菜單撥分機0會找到B公司的接待員。(當然,這也表示我們已經告訴了Asterisk撥0的意思就是把呼叫轉到接待員。)
上下文通過把名字放到方括號中來定義。名字由字母(大寫或小寫)、數字、連字符(就是減號)和下劃線構成。入局呼叫(incoming>
注:“插”這個概念對于掌握信道和撥號計劃至關重要。一旦你理解了在信道中指定的上下文和撥號計劃中相應的上下文的關系,就很容易調試呼叫流程的異常問題了。
上下文一個很重要的用途(也許是最重要的用途)就是提供安全控制。通過正確地使用上下文,你能夠控制某些特性(比如打長途電話)只對部分用戶開放。如果你設計撥號計劃的時候不謹慎,就可能有人不正當地使用你的系統。構建Asterisk系統時一定要留意這一點;Internet上有很多機器人程序專門設計用于識別那些不安全的Asterisk系統,然后盜用它們。
注:https://wiki.asterisk.org/wiki/display/AST/Important+Security+Considerations總結了一些使你的Asterisk系統保持安全的步驟,閱讀并理解這篇文章至關重要。如果你忽略這些安全警告,可能會導致任何人都可以用你的系統打長途電話而不用掏錢!如果你不認真地對待Asterisk的系統安全,可能會損失慘重。請確保在系統安全上有足夠的投入,以防止盜用。
分機
在通訊行業,分機這個詞一般指的是一串數字,當撥出的時候,可以打通一個電話(或者訪問某項系統資源,比如語音信箱,或呼叫隊列)。在Asterisk中,分機的概念要強大很多,因為它定義了一個步驟序列(每個步驟包含一個應用程序),Asterisk會按照這些步驟來處理呼叫。
在每個上下文中,我們可以根據需要定義任意數量的分機。當某個分機被觸發(通過入局呼叫,或者通過信道上撥出的數字)時,Asterisk會執行分機中定義的步驟。所以,當呼叫流經撥號計劃時,是分機決定了系統做什么。分機當然可以用于指定傳統意義上的電話號碼(比如,分機153可以撥通John的SIP電話機),但在Asterisk中,分機的用途遠不止于此。
分機的語法是,一個關鍵字exten,后面跟一個由等號和大于號構成的箭頭,像這樣:
exten =>后面再跟分機的名字(或數字)。當使用傳統電話系統時,我們傾向于認為分機就是用于打通另外一部電話的數字號碼。在Asterisk中,完全不一樣;例如,分機名可以是字母、數字的任意組合。在本章和下一章,數字分機和字母數字分機我們都會用到。
注:為分機指定名字看起來是一個革命性的概念,但是當你意識到很多VoIP運營商支持(甚至鼓勵)用名字或者email地址撥號時,這種方式是很有意義的。這是使得Asterisk靈活和強大的特性之一。
分機中的每個步驟都是由三個組件構成的:
- 分機的名字(或號碼)
- 優先級(分機包含很多步驟;步驟的序號被稱為“優先級”)
- 應用程序(或者說命令),該步驟要執行的動作
這三個組件用逗號隔開,像這樣:
exten =>>在這個例子中,分機名是123,優先級是1,應用程序是Answer()。
優先級
每個分機能夠有多個步驟,叫做優先級。優先級按順序編號,從1開始,并執行一個指定的應用程序。看下面這個例子,分機123接聽電話(優先級1),然后掛斷(優先級2):
exten => 123,1,Answer() exten => 123,2,Hangup()很明顯,這段代碼沒有做什么有意義的事情。這里要說明的問題是,在一個分機中,Asterisk按順序執行優先級。這種風格的語法還會不時地出現,盡管新代碼已經不再這么寫了(你很快就會看到了):
exten => 123,1,Answer() exten => 123,2,do>不編號的優先級
在老版本的Asterisk中,給優先級編號引起了不少問題。想象一下,某個分機有15個優先級,后來需要在第2步插入什么東西:后面所有的優先級都需要重新編號。Asterisk不能處理漏掉的步驟,也不能處理編錯了號的優先級,調試這種問題會很沒有頭緒,也很沒意思。
從1.2開始,Asterisk解決了這個問題:它引入了優先級n的使用,n表示next。只要Asterisk碰到了優先級n,就把上一個優先級拿過來加1。這就使得修改撥號計劃容易了,因為你不在需要為所有步驟編號了。例如,你的撥號計劃看起來會像這樣:
exten => 123,1,Answer() exten => 123,n,do>在內部,Asterisk碰到n時會計算優先級編號。需要注意的是,你必須指定優先級編號1。如果你不小心為第一個優先級指定了n而不是1,你會發現重新裝載撥號計劃后該分機不存在。
“same =>”操作符
在簡化編碼工作的持續努力下,一個新的結構出現了,使得分機的編寫和維護更容易。只要分機不變,就不再需要每行都寫分機名了,只需要寫same =>,后面跟優先級和應用程序:
exten => 123,1,Answer()>縮進不是必須的,但它便于閱讀。這種風格的撥號計劃,使得它更容易在分機之間拷貝代碼。我們自己很喜歡這種風格,也強烈建議它。
優先級標號
優先級標號允許你為分機中的優先級指定一個名字。這使得你可以避免用數字引用某個優先級(而且你也知道,優先級是可以不編號的)。能夠引用優先級之所以重要是因為,你會經常把呼叫從撥號計劃的一個部分轉移到某個分機的某個優先級。后面我們會詳細談到這個問題。要為優先級指定文字標號,簡單地把標號放到優先級后面的括號里就可以了,像這樣:
exten => 123,n(label),application()后面我們會講到如何根據撥號計劃的邏輯,在不同的的優先級之間實現跳轉。你會看到很多優先級標號,你也會在自己的撥號計劃中用到它們。
一個常見的錯誤就是,寫標號的時候在n和(之間插入一個逗號,像這樣:
exten => 123,n,(label),application() ;<-- THIS IS NOT GOING TO WORK這個錯誤將導致該部分撥號計劃無法工作,并且會有錯誤提示說“應用程序找不到”。
應用程序
應用程序是撥號計劃的工作部件。每個應用程序在當前信道上執行一個特定的動作,比如播放一段聲音,接收按鍵輸入,在數據庫中查找什么東西,撥打一個信道,掛斷電話,諸如此類。在上面的例子中,你看到了兩個簡單的應用程序:Answer()和Hangup()。你很快就會學習他們是如何工作的。
一些應用程序,像Answer()和Hangup(),不需要更多的信息就能完成工作了。然而,大多數應用程序都需要額外的信息。這些額外的信息被稱為參數,被傳遞給應用程序以影響它們如何完成工作。要給應用程序傳遞參數,把它們放到應用程序名后面的括號里,用逗號隔開。
注:有時候你也會看到用管道符(|)分隔參數,而不是逗號。從Asterisk 1.6.0開始,就不再支持用管道符作為分隔符了。
Answer(),Playback()和Hangup()應用程序
Answer()應用程序用于應答一個正在響鈴的信道。它會完成信道的初始設置,以便接收來電。正如我們之前提到的,Answer()沒有參數。Answer()不是必須的(在有些情況下甚至不用它更好),但它能保證在執行進一步的動作之前信道已經被連接了。
注:Progress()應用程序。有時候在應答一個呼叫之前向網絡傳回一些信息是很有用的。Progress()應用程序嘗試向來電信道提供呼叫進度信息。有些運營商需要這個,所以有時候你可以通過插入一個Progress()來解決一些奇怪的信號問題。
Playback()應用程序用于在信道上播放一個事先錄制的聲音文件。用戶輸入被忽略了,這意味著你不能在自動接待中使用Playback(),除非你不想在其間接收用戶輸入。
注:Asterisk有很多專業錄制的聲音文件,位于缺省的聲音目錄下(一般是/var/lib/asterisk/sounds)。編譯Asterisk的時候,你可以選擇安裝各種不同語言、不同格式的聲音文件。我們將在很多例子中使用這些文件。例子中的有些文件來自附加聲音包,所以請安裝它(見“安裝Asterisk”)。你也可以訪問http://www.theivrvoice.com/,以同樣的語音錄制你自己的聲音提示。本書的后面,我們還會談到如何用電話和撥號計劃建立和管理你自己的聲音提示。
使用Playback(),需要指定一個文件名(不帶擴展名)作為參數。例如,Playback(filename)將播放名為filename.wav的聲音文件,假設它位于缺省的聲音目錄下。你也可使用文件的完整路徑,像這樣:
Playback(/home/john/sounds/filename)這個例子將播放/home/john/sounds/目錄下的filename.wav文件。使用相對路徑也可以,比如:
Playback(custom/filename)這個例子將播放缺省聲音目錄的子目錄custom/下的filename.wav文件(可能是/var/lib/asterisk/sounds/custom/filename.wav)。如果指定的路徑下存在多個同名但擴展名不同的文件,Asterisk將自己選擇一個(根據轉碼的代價)。
Hangup()做得事情就和它的名字一樣:它掛斷當前的活動信道。你想結束當前呼叫的時候應該使用它,以防止在你沒有意識到的情況下當前呼叫還被保持在撥號計劃的某處。Hangup()應用程序不需要參數,但你可以給它傳一個ISDN碼,如果你希望的話。
隨著本書的展開,我們將會向你介紹更多的Asterisk應用程序。
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的Asterisk权威指南/第六章 拨号计划基础的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 用mingw链接msvc生成的库时,无定
- 下一篇: 短期理财哪个比较好?买短期理财的技巧