Asterisk權威指南/第八章 語音信箱
在電子郵件和即時通訊變得無所不在之前,語音郵件(Voicemail)是電子留言的流行方法。儘管大多數人更喜歡基於文字的訊息系統,語音郵件仍然是所有 PBX 的必需組件。
Comdial Mail
[編輯]現代電話系統最流行的特性之一就是語音郵件。Asterisk 有一個相當靈活的語音郵件系統,稱為 Comedian Mail 1 。Asterisk 的語音郵件系統的特性包括:
- 支援密碼保護的語音郵件郵箱,每個郵箱都包含一個用於組織語音郵件的資料夾
- 針對「忙線」或「用戶無法接通」提供不同的問候語
- 預設及客制的問候語
- 可以把一個電話關聯多個郵箱,也可以把一個郵箱關聯多個電話
- 電子郵件通知功能,可以將語音郵件作為聲音檔案附件傳送(可選)
- 語音郵件轉發和廣播
- 在 IP 電話機上實現 Message-Waiting Indicator ( 閃燈或斷續的訊號音)
- 基於語音郵件郵箱的公司員工電話本
而這些特性對於 Asterisk 來說只是冰山一角!預設版本的 /etc/asterisk/voicemail.conf 檔案需要做一些調整以提供一個適合大多數場合的組態。
我們將開始討論你可以定義在 voicemail.conf 中的選項(options),然後我們會提供一個範例設定檔,這個設定檔中的設定適合於大多數開發者。voicemail.conf 設定檔分成幾部分來定義參數。下面我們來進行詳細討論。
[general] Section
[編輯]第一個 section,[general],允許你為你的語音郵件系統定義全域設定。可使用的選項參見 Table8-1。
語音郵件密碼的外部驗證
預設情況下, Asterisk 並不驗證用戶密碼以保證它至少有基本的安全性。任何一個維護語音郵件系統的管理員都會告訴你,大部分的語音郵箱用戶將他們的密碼設定為1234 或者 1111,或者一些其它很容易猜到的字串。這表明語音郵件系統有巨大的安全漏洞。
由 於 app_voicemail.so 模組並沒有內建的密碼驗證能力,你可以透過設定externpass, externpassnotify 和 externpasscheck 參數來利用外部程式驗證密碼。Asterisk會呼叫你指定的程式,並將下述參數傳遞個這個程式:
mailbox context oldpass newpass
然後這個指令碼程式會根據你在外部指令碼中定義的規則評估這些參數,並向 Asterisk 返回 VALID 表示驗證成功,返回 INVALID 表示驗證失敗(事實上,一個密碼驗證失敗的返回值可以是除了 VALID 和 FAILURE 之外的任何值)。這個返回值會被輸出到 stdout。
如果這個指令碼返回 IAVALID,Asterisk 會播放一段無效密碼的語音提示並要求用戶重新輸入。理想情況下,你可能希望實現下面這些規則:
密碼長度至少要大於 6 位
密碼不能由重複數字組成(如 11111)
密碼不能由連續的數字組成(如 123456 或 987654)
Asterisk 發行版本包括了一個簡單的指令碼,這個指令碼可以極大地改進你的語音郵件系統的安全性。它位於如下資料夾下:/contrib./scripts/voicemailpwcheck.py。
我們強烈推薦你將這個指令碼拷貝到 /usr/local/bin 資料夾下(或任何你指定的目錄),然後取消 voicemail.conf 檔案中 externpasscheck= 參數的註釋。你的語音郵件系
統就可以執行你已經建立好的密碼安全規則了。
部分[general] section 的選項被稱為進階選項(advanced options)。這些選項(見 Table 8-2)與[general] section 其它選項的定義方式一樣,但是它們可以在每個郵箱的 section 中重新定義,並覆蓋[general] section 中定義的內容。
The [zonemessage] Section
[編輯]在 voicemail.conf 中的下一個 section 是 [zonemessage] section。這個 section 的目的是 允許按時區處理留言,使得你可以以正確的時間戳播放留言訊息。你可以任意設定時區的名 字。在時區名之後,你可以定義這個時區名對應的時區,以及定義如何播放時間戳的選項。 你可以參考 /usr/src/asterisk-complete/asterisk/1.8/configs/voicemail.conf.sample 檔案來獲 得詳細訊息。Asterisk 包含了一個如 Table-3 中所示的例子。
The Contexts Section
[編輯]在 voicemail.conf 檔案中剩下的部分都是郵箱 contexts,你可以分組定義郵箱。
在大多數情況下,你只需要定義一個郵箱 context,我們一把將其命名為[defaule]。值得注意的是,這麼做可以簡化 dialplan 的處理:所有的郵箱相關的 applications 如果沒有特別指出的話,都會使用預設的 context default。換句話說,如果你不需要區分你的郵箱用戶,可以使用 default 作為唯一的郵箱 context。
邮箱定义的格式: mailbox => password[,FirstName LastName[,emal addr[,pager addr[,options]]]]]
豎線(|)在 Asterisk 中的應用過去非常流行。在開始的幾年,它被用作 標準的分界符。但最近,這種用途差不多已經完全被逗號取代了;然而, 仍然有些地方使用豎線(|)做分界符。其中之一就是 voicemail.conf: 例如,作為 mailbox-specific 選項的分隔符,以及作為 format=declarative 格式中的分隔符。你將在我們即將到來的例子中看到這種用法,或者參考 voicemail.conf.sample 檔案。
郵箱的各部分參數定義如下:
mailbox: 邮箱号码。它一般与分机号码关联。
password: 数字密码,语音邮箱的用户通过这个密码访问他的留言信息。如果用户修改她的密码,系统会更新 voicemail.conf 中的对应字段。FirstName LastName语音邮箱拥有者的名字。公司电话本在这个字段使用文字纪录,以允许呼叫者可以读出这个名字。
email address: 语音邮箱拥有者的 email 地址。Asterisk 可以发送一封“新留言提醒”电子邮件(可以将留言本身作为电子邮件附件发送)到指定的电子邮件地址。
pager address: 语音邮箱拥有者的寻呼机或移动电话的关联电子邮件。Asterisk 可以发送一个短的留言提醒到指定的电子邮件地址。
options: 这个字段包含一组选项(options)用于设置邮箱拥有者的时区和覆盖全局语音邮箱设置。一共有九个选项:attach, servermail, tz, saycid, review, operator, callback, dialout,exitcontext. 这些选项应该用 option=value 的格式来设置,不同 option 之间用竖线(|)隔开。tz 选项用来设置用户的时区,取值来自之前[zonemessage] section 中的定义。其它八个选项覆盖全局邮箱设置中的同名选项。
你在 voicemail.conf 中定义的语音邮箱看起来如下列所示:
[default]
100 => 5542,Mike Loukides,mike@shifteight.org
101 => 67674,Tim OReilly,tim@shifteight.org
102 => 36217,Mary JonesSmith,mary.jones-smith@shifteight.org; *** This needs to all be on the same line
103 => 5426,Some Guy,,,dialout=fromvm|callback=fromvm|review=yes|operator=yes|envelope=yes
[shifteight]
100 => 0107,Leif Madsen,leif@shifteight.org
101 => 0523,Jim VanMeggelen,jim@shifteight.org,,attach=no|maxmsg=100
102 => 11042,Tilghman Lesher,,,attach=no|tz=central
- 註:Asterisk 電話本功能不能處理複雜姓氏的概念。這就意味着諸如 O』Reilly,
Jones-Smith 和 Van Meggelen 這種包含標點和空格的姓氏拼寫,必需在將 其加入 voicemail.conf 前將標點和空格去掉。
在 voicemail.conf 中的 context 是個優秀而功能強大的概念,不過你也會發現在一般應用 中使用 default context 就足夠了。
設定檔voicemail.conf範例
[編輯]我們推薦下面的例子作為你理解語音郵箱組態的切入點。你可以參考 ~/asterisk- complete/asterisk/1.8/configs/voicemail.conf.sample 了解詳細訊息:
; Voicemail Configuration [general] format=wav49|wav serveremail=voicemail@shifteight.org attach=yes skipms=3000 maxsilence=10 silencethreshold=128 maxlogins=3 emaildateformat=%A, %B %d, %Y at %r pagerdateformat=%A, %B %d, %Y at %r sendvoicemail=yes ; Allow the user to compose and send a voicemail while inside [zonemessages] eastern=America/New_York|'vm-received' Q 'digits/at' IMp central=America/Chicago|'vm-received' Q 'digits/at' IMp central24=America/Chicago|'vm-received' q 'digits/at' H N 'hours' military=Zulu|'vm-received' q 'digits/at' H N 'hours' 'phonetic/z_p' european=Europe/Copenhagen|'vm-received' a d b 'digits/at' HM [shifteight.org] 100 => 1234,Leif Madsen,leif@shifteight.org 101 => 1234,Jim Van Meggelen,jim@shifteight.org 102 => 1234,Russell Bryant,russell@shifteight.org 103 => 1234,Jared Smith,jared@shifteight.org
組態 Linux 伺服器處理電子郵件的傳送是 Linux 管理員的任務,並且已經超出了本書的範圍。你需要測試你的電子郵件服務以確保電子郵件能夠被 Mail Transfer Agent(MTA)正確的處理,並且垃圾郵件過濾器不會拒絕這個訊息(發生這種情況的原因之一是你的Asterisk 伺服器在電子郵件中使用了一個實際上不能解析的主機名)。
Dialplan整合
[編輯]在 app_voice-mail.so 模組中 Asterisk 提供了兩種主要的 dialplan 應用。第一種, VoiceMail(),負責將留言訊息紀錄到郵箱中。第二種,VoiceMailMain(),允許用戶登錄到語 音郵箱收聽留言訊息。
The VoiceMail() Dialplan Application
[編輯]如果你想把一個呼叫轉移給語音郵箱處理,你需要提供兩個參數:郵箱號碼,用於指示 留言要放到那個訊息中;以及與此相關的其它選項,例如播放哪條問候語或者是否要標記此 訊息為緊急訊息。VoiceMail()命令的格式如下:
VoiceMail ( mailbox [@ context ][& mailbox [@ context ][&...]][, options ])
你可以提供給 VoiceMial()實現進階控制的選項的詳細訊息參見 Table8-4
VoiceMail()應用把呼叫轉給指定的語音郵箱,然後呼叫人可以留下留言。這個郵箱被指 定為 mailbox@context ,其中 context 是 voicemail.conf 中郵箱 context 的名字。選項字母 b 或 u 用於指定問候語的類型。如果字母 b 被使用,呼叫者會聽到語音郵箱主人的「忙線中」 問候語。如果字母 u 被使用,呼叫者會聽到語音郵箱主人的「用戶無法接通」問候語(如果 存在的話)。
考慮一個簡單的例子,假設 John 的分機號碼為 101:
exten => 101,1,Dial(${JOHN})
讓我們增加一個「用戶無法接通」訊息,這個訊息會在 John 沒有接聽電話時播放。請記住, Dial()應用的第二個參數是 timeout。如果呼叫沒有在逾時前被接聽,這個呼叫會執行 dialplan 中的下一條指令。讓我們給 Dial()增加一個 10 秒鐘的逾時,並且增加一條將呼叫轉給語音信 息的指令:
exten => 101,1,Dial(${JOHN},10)
exten => 101,n,VoiceMail(101@default,u)
現在,讓我們修改一下這個例子。使得可以在 John 處於忙線狀態(正在進行另一個通話) 時,對 John 的呼叫會轉給語音郵箱處理,呼叫者會聽到 John 的「忙線中」問候語。要實現 這個功能,我們需要使用${DIALSTSTUS}變數,它包含幾個狀態值(在 Asterisk 控制台輸入 core show application dial 觀察所有可能的取值):
exten => 101,1,Dial(${JOHN},10)
same => n,GotoIf($["${DIALSTATUS}" = "BUSY"]?busy:unavail)
same => n(unavail),VoiceMail(101@default,u)
same => n,Hangup()
same => n(busy),VoiceMail(101@default,b)
same => n,Hangup()
現在,如果 John 處於忙線或無法接通的情況,呼叫者會進入 John 的語音郵箱(伴隨這相應 的問候語) 。然而,還有個小問題沒有解決,John 還沒有辦法收聽他的留言訊息。我們將在 下一節討論這個問題。
The VoiceMialMian() Dialplan Application
[編輯]用戶可以使用 VoiceMailMian()應用取得他們的留言訊息,修改語音郵箱的設定選項, 以及錄製他們的問候語。VoiceMailMain()接受兩個參數:要存取的郵箱的郵箱號碼(可以帶 上 context 名) ,以及一些相關選項。這兩個參數都是可選的。
VoiceMailMian()命令的格式如下: VoiceMailMain([ mailbox ][@ context ][, options ])
如果你不傳遞任何參數給 VoiceMailMain(),它就會播放一個提示訊息要求呼叫者輸入郵箱 號碼。VoiceMailMain()中可以使用的選項參見 Table8-5。
為了允許用戶撥打*98 來存取語音郵箱或者修改郵箱設定,你可以在 dialplan 增加一條如下 的 extension:
[Services] exten => *98,1,VoiceMailMain()
建立一個按名字撥號(Dial-by-Name)的電話本
[編輯]本書希望討論的 Asterisk 語音郵箱系統的最後一個特性是按名字撥號的電話本功能。這 可以用 Directory()應用建立。 這個應用使用定義在 voicemial.conf 中的郵箱擁有者的姓名來提 供給呼叫者一個按姓名撥叫的電話本。
Directory()需要三個參數:郵箱的 context,指出從哪裏獲得姓名訊息;可選的 dialplan context,指出從哪裏執行呼叫;以及一個選項字串(這也是可選的)。在預設情況下, Directory()用名(last name)來尋找用戶,但如果使用了 f 選項則強制用姓(first name)來 搜尋用戶。讓我們在我們的範例 dialplan 中的 incoming context 中增加兩個按名字撥號的電 話本,這樣用戶就可以按照姓氏或名字來搜尋用戶了:
exten => 8,1,Directory(default,incoming,f) exten => 9,1,Directory(default,incoming)
如果呼叫者按下數字 8,就會進入一個按姓氏排列的電話本。如果按下數字 9,就會進入一 個按名字排列的電話本。
使用Jitterbuffer
[編輯]如果使用 Asterisk 作為語音郵箱伺服器 4,你可能希望在語音郵箱和呼叫者之間增加一 個 jitterbuffer。Jitterbuffer 的作用是幫助處理這樣一個事實:當呼叫穿過 IP 網絡時,IP 報文 不會非常準時和按順序的到達目的地。如果報文偶然出現一點延時(jitter)或者沒有按順序 到達,就需要用到 jitterbuffer 來修復這種問題,從而使得語音郵箱系統可以準時並按正確的 順序接收語音流。如果 jitterbuffer 檢測到報文遺失了(或者到達的太遲了以至於沒用了),它可以執行報文遺失補償。這就是說, jitterbuffer 可以製作一幀聲音報文來替代遺失的報文, 從而很難聽出有聲音遺失了。
在 Asterisk 中,jitterbuffer 只能在橋接兩個 channels 時使能。在語音郵箱的例子中,通 常只有一個 channel 連接到語音郵箱。為了使能 jitterbuffer,我們透過使用一個 Local channel 並指定 j 選項來建立兩個 channels 之間的橋接。給 Local channel 額外指定 n 選項可以確保 Local channel 不會被 Asterisk 從呼叫路徑中最佳化; 优化=>zh-mo:最佳化掉:
[Services] exten => *98,1,Dial(Local/vmm@Services/nj) exten => vmm,1,VoiceMailMain()
後端儲存
[編輯]在傳統語音郵件系統中的訊息儲存總是趨向於過分複雜 5 。而 Asterisk 與之相反,不僅 提供一種簡單、合理的,基於檔案系統的儲存機制,而且提供一些額外的訊息儲存選項。
Linux檔案系統
[編輯]預設情況下, Asterisk 會將留言訊息儲存在 spool 資料夾下, /var/spool/asterisk/voicemail/<context>/<mailbox>. 留言訊息可以用多種格式儲存(例如 WAV或 GSM 格式) ,這可以透過 voicemail.conf 中[general] section 的 format 來指定。你的問候語也儲存在這個資料夾下。
注:Asterisk 不会为还没有任何纪录的邮箱创建文件夹(例如新定义的邮箱),所以这个文件夹不适合作为判断系统中有多少个邮箱的可靠方法。
這裏有個例子來展示郵箱資料夾下有哪些東西。這個郵箱在 INBOX 中沒有新訊息,在 Old 資料夾下有兩條已儲存; 保存=>zh-mo:儲存的訊息,以及「忙線」和「呼叫不可達」問候語:
/var/spool/asterisk/voicemail/default ./INBOX ./Old ./Old/msg0000.WAV ./Old/msg0000.txt ./Old/msg0001.WAV ./Old/msg0001.txt ./Urgent ./busy.WAV ./unavail ./unavail.WAV
注:對每條留言來說,都有一個匹配的 msg####.txt 檔案,其中包含了這條留 言的信封訊息。 這種 msg####.txt 檔案對於 message waiting indication ( MWI) 功能也十分重要,因為 Asterisk 是透過檢視 INBOX 中的這種檔案來決定用 戶的留言訊息指示燈是應該開還是關。
ODBC
[編輯]在集中式或分散式系統中,你可能發現訊息是以二進制物件儲存在數據庫中的,而不是 以檔案方式儲存在檔案系統中。我們將在第 16 章「關係型數據庫整合」中進一步討論這個 話題。
IMAP
[編輯]很多人希望將語音郵件作為電子郵件的一部分來管理。這被電信工業稱為「統一訊息」 (unified messaging),其傳統實現方法昂貴而複雜。Asterisk 允許相當簡單的整合語音郵件 和電子郵件,無論是透過其內建的語音郵件到電子郵件的控制代碼,還是透過與 IMAP 伺服器聯 系。我們將在第 16 章「關係型數據庫整合」中進一步討論這個話題。
Asterisk作為獨立的語音郵件伺服器
[編輯]在傳統的電信環境中,語音郵件伺服器是典型的獨立裝置(或者由一台獨立的伺服器實 現,或者用一塊系統上的獨立插卡實現) 。非常少的 PBX 會完全整合語音郵件功能(指語音 郵件是 PBX 不可分割的一部分,而不是一個外圍裝置的情況)。
Asterisk 完全有能力作為一個獨立的語音郵件系統。人們希望這麼做的兩個最流行的原 因是:
1. 當你建設一個大型的,集中管理的系統,並且擁有多個伺服器分別提供特定的功能 時(代理伺服器、媒體網管、語音郵件、會議、等等):
2. 當你希望將一個傳統 PBX 上的語音郵件系統替換為 Asterisk 語音郵件系統時; Asterisk 可以勝任上述任一角色。
將Asterisk作為獨立語音郵件伺服器整合到SIP環境
[編輯]如果你希望將 Asterisk 作為專用的語音郵件伺服器(例如,沒有任何裝置註冊在上面, 也沒有任何其它類型的呼叫透過它) ,從 dialplan 的角度看處理非常簡單。儘管通知終端有 待讀取的訊息會有些困難。
讓我們從一個方塊圖開始。 Figure8-1 顯示了一個關於典型的 SIP 企業環境的非常簡單的例 子。在這個例子中,我們甚至沒有使用 Asterisk 伺服器(除了作為語音郵件伺服器之外), 這是為了給你一個關於 Asterisk 即使在非 Asterisk 環境中也可以作為獨立語音郵件伺服器的 通用範例。
不幸地是,如果不知道這個終端在哪裏的話,Asterisk 不能傳送「你有新留言」通知給 終端。在一個典型的 Asterisk 系統中,終端註冊及語音郵件處理是在同一個伺服器上,這沒 有任何問題,因為 Asterisk 知道這些終端在哪裏。但是在終端並不註冊到 Asterisk 的環境中, 這成為一個棘手的問題。
有幾種互聯網; 互联网=>zh-mo:互聯網上的解決方案建議使用 voicemail.conf 中的 externnotify 選項,一旦郵箱中 有留言(或刪除留言)就觸發一個外部指令碼。雖然這不能說是個壞方法,但我們認為這個方 法比較笨拙,而且它要求系統管理員能理解如何寫一個外部指令碼或程式來處理傳給它的留言。
代的方法是,你可以為每個語音郵件伺服器上的郵箱,在 sip.conf 檔案中定義一個入 口。這個入口用來指示「你有新留言」通知要向哪裏傳送。不同於為每個終端都定義地址, 你可以組態語音郵件伺服器把所有的通知都發給代理伺服器,代理伺服器會正確的中繼這些 「你有新留言」通知到正確的終端。
郵件伺服器仍然需要知道有哪些 SIP 終端,儘管這些裝置不是直接註冊在它上面的。這 可以透過辨識每個 SIP 終端的 sip.conf 檔案實現,或者透過一個實現同樣功能的靜態即時; 实时=>zh-mo:即時數 據庫實現。無論你使用 sip.conf 還是 Asterisk 即時; 实时=>zh-mo:即時架構(ARA, Asterisk Realtime Architecture) ,每個終端都需要一個類似如下的入口:
[messagewaiting](!) ; a template to handle the settings common ; to all mailboxes type=peer subscribecontext=voicemailbox ; the dialplan context on the voicemail server context=voicemailbox ; the dialplan context on the voicemail server host=192.168.1.1 ; ip address of presence server [0000FFFF0001](messagewaiting) ; this will need to match the subscriber ; name on the proxy mailbox=0000FFFF0001@DIR1 ; this has to be in the form mailbox@mailboxcontext defaultuser=0000FFFF0001 ; this will need to match the subscriber ; name on the proxy
注意 Asterisk 的動態即時; 实时=>zh-mo:即時功能並不會隨這個組態變化,因為只有當某個終 端參與呼叫時它的訊息才會載入到記憶體; 内存=>zh-mo:記憶體中。由於在 Asterisk 看來,留言提 醒不是一個呼叫,對於任何一個沒有註冊到 Asterisk 上的終端,使用動態 即時; 实时=>zh-mo:即時功能並不能實現留言提醒。
你不會真的想實現這些功能,除非你是想驗證這個方案的基本操作。儘管我們都同意 SIP 是一個標準協定,但是並不是每個人都會用正確的方法來實現這個協定。結果是,你需 要在這類方案中面對大量相容性挑戰。我們在本書中對這些概念做了基本介紹,但是實現細 節取決於 Asterisk 之外的一些因素,例如你所選用的代理伺服器的能力。
事實上,沒有裝置必需註冊到 Asterisk 上可以顯著地減少 Asterisk 伺服器的負載,其結 果就是這種設計可以允許語音郵件伺服器支援數千個用戶。
對 Dialplan 的要求
[編輯]語音郵件伺服器的 dialplan 可以非常簡單。只需要滿足兩個條件:
1. 能夠接受來電呼叫並把它們轉入相應的郵箱;
2. 能夠處理用戶存取他們自己郵箱的來電;
將呼叫轉給語音郵件伺服器的系統,需要設定一些報文頭以傳遞一些額外額訊息給語音郵件 伺服器。典型地,這些訊息包括與這個呼叫相關的郵箱號/用戶名(mailbox/username) 。在我們的例子中,我們將設定 SIP 報文頭 X-Voicemail-Mailbox 和 X-Voicemail-Context,其中包 含了我們要傳遞給語音郵件伺服器的訊息
如果你的 SIP 系統也是 Asterisk,你可以透過語音郵件應用 SIPAddHeader() 來設定 SIP 報文頭。舉例如下:
exten => sendtovoicemail,1,Verbose(2,Set SIP headers for voicemail) same => n,SipAddHeader(X-Voicemail-Mailbox: <mailbox number>) same => n,SipAddHeader(X-Voicemail-Context: voicemailbox)
注意,這個 dialplan 並不在語音郵件伺服器上。它僅僅在當你系統中的 SIP 伺服器也是 Asterisk 時才有用處。如果你使用不同的 SIP 伺服器,你需要 找到如何組態客戶化 SIP 報文頭的方法,或者找到已經定義好的用於此類 應用的報文頭,然後修改你語音郵件伺服器的 dialplan 使它能處理此類報 文頭。
語音郵件伺服器需要一個包含下屬內容的 extensions.conf 檔案:
[voicemailbox]
; direct incoming calls to a mailbox
exten => Deliver,1,NoOp()
same => n,Set(Mailbox=${SIP_HEADER(X-Voicemail-Mailbox)})
same => n,Set(MailboxContext=${SIP_HEADER(X-Voicemail-Context)})
same => n,VoiceMail(${Mailbox}@${MailboxContext})
same => n,Hangup()
; connect users to their mailbox so that they can retrieve messages exten =>
Retrieve,1,NoOp()
same => n,Set(Mailbox=${SIP_HEADER(X-Voicemail-Mailbox)})
same => n,Set(MailboxContext=${SIP_HEADER(X-Voicemail-Context)})
same => n,VoiceMailMain(${Mailbox}@${MailboxContext})
same => n,Hangup()
對 sip.conf 檔案的要求
[編輯]在語音郵件伺服器的 sip.conf 檔案中,不僅每個郵箱的訊息等待通知(MWI,Message Waiting Notification)服務需要一個入口,而且也需要一些入口用於定義語音郵件伺服器與 其它 SIP 伺服器之間的連接。
[VOICEMAILTRUNK] type=peer defaultuser=voicemail fromuser=voicemail secret=s0m3th1ngs3cur3 canreinvite=no host=< address of proxy/registrar server > disallow=all allow=ulaw dtmfmode=rfc2833 context=voicemailbox
連接的另一端(可能是你的 SIP 代理伺服器)必須組態為能將語音郵件連接到語音郵件服務 器。
用 Asterisk 作為獨立的語音郵件伺服器執行,會帶來明顯的價格優勢,但是必須充分了 解叢集和整合方面的知識。
SMDI (Simplified Message Desk Interface)
[編輯]SMDI 協定(Simplified Message Desk Interface)是用於在電話系統和語音郵件系統之間 傳遞基本訊息的協定。
Asterisk 支援 SMDI,但是鑑於這是一種非常古老的執行在序列埠; 串口=>zh-mo:序列埠上的協定,你會遇到一些 整合上的挑戰。SMDI 在不同的 PBX 和其它裝置上的支援可能不完整。不過,由於這是一個 相當簡單的協定,所以如果你考慮用 Asterisk 作為語音郵件裝置的話,它仍然值得徹底測試 一下。
後面的內容並不是對於如何為 Asterisk 組態 SMDI 的詳細解釋,而是對一些概念和一 些基本例子的介紹。如果你計劃實現 SMDI,你需要書寫一些複雜的 dialplan 邏輯以更好的 理解如何將系統透過序列埠; 串口=>zh-mo:序列埠互聯。
在 Asterisk 中, SMDI 可以透過 voicemail.conf 檔案中[general] section 的兩個選項來使能:
smdienable=yes smdiport=/dev/ttyS0; or whatever serial port you are connecting your SMDI service to
此外,你需要/etc/asterisk 資料夾下的 smdi.conf 檔案來定義 SMDI 組態的細節。如下所 示(關於可用選項的更多訊息,參見 smdi.conf.sample 檔案):
[interfaces] charsize=7 paritybit=even baudrate=1200 ; hopefully a higher bitrate is supported smdiport=/dev/ttyS0 ; or whatever serial port you'll be using to handle ; SMDI messages on asterisk [mailboxes] ; map incoming digit strings (typically DID numbers) ; to a valid mailbox@context in voicemail.conf smdiport=/dev/ttyS0 ; first declare which SMDI port the following mailboxes ; will use 4169671111=1234@default 4165551212=9999@default
在這個 dialplan 中、有兩個函數需要在 SMDI 組態中用到。 SMDI_MSG_RETRIEVE()函數從 SMDI 訊息佇列中彈出相關的訊息。你需要給這個函數輸入一個搜尋鍵值(典型採用與這個 訊息相關的 DID 號碼)、然後這個函數會返回一個 ID、這個 ID 在 SMDI_MSG()函數中需要引 用:
SMDI_MSG_RETRIEVE(< smdi port >,< search key >[, timeout [, options ]]) 一旦你獲得了 SMDI 的訊息 ID, 你就可以使用 SMDI_MSG()函數去存取這個訊息的不同細節, 例如 station、callerID、 type(the SMDI message type):
MDI_MSG(< message_id >、< component >)
在你的 dialplan 中,你需要處理尋找來電的 SMDI 訊息,以保證能正確的處理來電呼叫。舉 例來說,如果一個來電打算交給語音郵箱處理,這個訊息類型應該是 B(for busy)或 N(for unanswered calls) 。如果一個來電打算交給 VoiceMailMain()處理,因為呼叫者希望讀取他的 留言,那麼 SMDI 訊息的類型應該是 D,而且這個訊息必須被處理。
總結
[編輯]儘管 Asterisk 的語音郵件系統相對於 Asterisk 本身來說是相當古老的系統,但它仍然是 一個能夠(並且已經在)與昂貴、私有的語音郵件系統非常成功競爭的強大應用。