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。

File:Asterisk 8 1.png

File:Asterisk 8 2.png

File:Asterisk 8 3.png

File:Asterisk 8 4.png

File:Asterisk 8 5.png

File:Asterisk 8 6.png

File:Asterisk 8 7.png

File:Asterisk 8 8.png

语音邮件密码的外部验证

默认情况下, 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 中定义的内容。

File:Asterisk 8 9.png

File:Asterisk 8 10.png

File:Asterisk 8 11.png

File:Asterisk 8 12.png

File:Asterisk 8 13.png

File:Asterisk 8 14.png

The [zonemessage] Section 编辑

在 voicemail.conf 中的下一个 section 是 [zonemessage] section。这个 section 的目的是 允许按时区处理留言,使得你可以以正确的时间戳播放留言信息。你可以任意设置时区的名 字。在时区名之后,你可以定义这个时区名对应的时区,以及定义如何播放时间戳的选项。 你可以参考 /usr/src/asterisk-complete/asterisk/1.8/configs/voicemail.conf.sample 文件来获 得详细信息。Asterisk 包含了一个如 Table-3 中所示的例子。

File:Asterisk 8 15.png

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

File:Asterisk 8 16.png

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。

File:Asterisk 8 17.png

为了允许用户拨打*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 从呼叫路径中优化掉:

 [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 文件夹下有两条已保存的消息,以及“忙线”和“呼叫不可达”问候语:

 /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 环境中也可以作为独立语音邮件服务器的 通用示例。

File:Asterisk 8 18.png

不幸地是,如果不知道这个终端在哪里的话,Asterisk 不能发送“你有新留言”通知给 终端。在一个典型的 Asterisk 系统中,终端注册及语音邮件处理是在同一个服务器上,这没 有任何问题,因为 Asterisk 知道这些终端在哪里。但是在终端并不注册到 Asterisk 的环境中, 这成为一个棘手的问题。

有几种互联网上的解决方案建议使用 voicemail.conf 中的 externnotify 选项,一旦邮箱中 有留言(或删除留言)就触发一个外部脚本。虽然这不能说是个坏方法,但我们认为这个方 法比较笨拙,而且它要求系统管理员能理解如何写一个外部脚本或程序来处理传给它的留言。

代的方法是,你可以为每个语音邮件服务器上的邮箱,在 sip.conf 文件中定义一个入 口。这个入口用来指示“你有新留言”通知要向哪里发送。不同于为每个终端都定义地址, 你可以配置语音邮件服务器把所有的通知都发给代理服务器,代理服务器会正确的中继这些 “你有新留言”通知到正确的终端。

邮件服务器仍然需要知道有哪些 SIP 终端,尽管这些设备不是直接注册在它上面的。这 可以通过识别每个 SIP 终端的 sip.conf 文件实现,或者通过一个实现同样功能的静态实时数 据库实现。无论你使用 sip.conf 还是 Asterisk 实时架构(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 的动态实时功能并不会随这个配置变化,因为只有当某个终 端参与呼叫时它的信息才会加载到内存中。由于在 Asterisk 看来,留言提 醒不是一个呼叫,对于任何一个没有注册到 Asterisk 上的终端,使用动态 实时功能并不能实现留言提醒。

你不会真的想实现这些功能,除非你是想验证这个方案的基本操作。尽管我们都同意 SIP 是一个标准协议,但是并不是每个人都会用正确的方法来实现这个协议。结果是,你需 要在这类方案中面对大量兼容性挑战。我们在本书中对这些概念做了基本介绍,但是实现细 节取决于 Asterisk 之外的一些因素,例如你所选用的代理服务器的能力。

事实上,没有设备必需注册到 Asterisk 上可以显著地减少 Asterisk 服务器的负载,其结 果就是这种设计可以允许语音邮件服务器支持数千个用户。

对 Dialplan 的要求 编辑

语音邮件服务器的 dialplan 可以非常简单。只需要满足两个条件:

1. 能够接受来电呼叫并把它们转入相应的的邮箱;

2. 能够处理用户访问他们自己邮箱的来电;

将呼叫转给语音邮件服务器的系统,需要设置一些报文头以传递一些额外额信息给语音邮件 服务器。典型地,这些信息包括与这个呼叫相关的邮箱号/用户名(mailbox/username) 。在我们的例子中,我们将设置 SIP 报文头 X-Voicemail-MailboxX-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,但是鉴于这是一种非常古老的运行在串口上的协议,你会遇到一些 集成上的挑战。SMDI 在不同的 PBX 和其它设备上的支持可能不完整。不过,由于这是一个 相当简单的协议,所以如果你考虑用 Asterisk 作为语音邮件设备的话,它仍然值得彻底测试 一下。

后面的内容并不是对于如何为 Asterisk 配置 SMDI 的详细解释,而是对一些概念,和一 些基本例子的介绍。如果你计划实现 SMDI,你需要书写一些复杂的 dialplan 逻辑以更好的 理解如何将系统通过串口互联。

在 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 本身来说是相当古老的系统,但它仍然是 一个能够(并且已经在)与昂贵、私有的语音邮件系统非常成功竞争的强大应用。