Asterisk权威指南/第十一章 保持和转移

本章集中讨论PBX系统的两个重要方面:Parking一个呼叫并允许它在另外一部分机上恢复,以及Paging功能。利用paging功能,我们可以通报这个呼叫时找谁的以及如何接听这个呼叫。

在Asterisk中,这两个功能是彼此独立的,并且都可以单独使用。一些拥有大型仓库,或者那些员工在办公室中不断移动而不需要整天坐在办公桌旁的商业机构可以利用 paging and parking功能在办公室中转接电话。在本章中,我们将向你展示如何在传统环境中利用parking and paging,以及一些对这一常用功能的更现代用法。

features.conf 编辑

Asterisk支持所有现代PBX系统的通用特性。许多这些特性都需要一些可选得配置参数。features.conf就是Asterisk中用于修改或定义特性参数的文件。

基于DTMF的特性

在features.conf里定义的许多参数只有当呼叫已经通过Dialplan中的Dial()或Queue()应用程序伴随K,k,H,h,T,t,W,w,X,x等参数被成功桥接之后才能生效。用这种方法使用的特性称为基于DTMF的特性(意思是它们不可以通过SIP消息使用,而只能通过语音通道的信号音才能触发)。

SIP channel的呼叫转移(例如从一部SIP电话机上)可以被SIP话机自身的功能处理,不会受到features.conf中的任何定义影响。

The [general] section 编辑

在features.conf的[general]部分,你可以定义一些选项微调Asterisk中park和transfer的一些行为。这些选项参见表格1

表格 1 features.conf [general] section

根据comebacktoorigin选项处理超时Parked Calls

这个选项配置当parked call超时情况下的行为。comebacktoorigin可能的取值包括:

yes(default)

当parked call超时后,Asterisk会尝试将呼叫转回发起这个parked call的channel。如果这个channel不再可用,Asterisk会挂断这个呼叫。

no

当你希望对于超时的parked call执行一些客户化的dialplan功能时,可以使用这个选项。这个parked call会在超后被转给dialplan中的特定位置,在那里会完美的处理这个呼叫(这可能是简单的把这个呼叫转给另一部分机,或者按某种排序做查找)。

你也许需要顾及这样一些parked calls,即无法把这些parked call返回到发起它们的channel。举例来说,当发起这个parked call的channel同时也是另一个系统的trunk时,将没有足够的信息把这个parked call返回到另一个系统中的正确用户。超时后实际要求的处理会比comebacktoorigin=yes能够处理的情况要复杂得多。 当comebacktooriginal=no时超时的parked calls会被转到parkedcallstimeout context 处理。

Dialplan(和contexts)的细节参见第六章。

转回的目标分机由parked这个呼叫的channel名构成。例如,如果名为0004F2040808的SIPpeer parked了这个呼叫,则转回的目标分机是SIP_0004F2040808。

如果这个分机不存在,这个呼叫会被转到parkedcallstimeout context中的s分机。最后,如果parkedcallstimeout的s分机也不存在,呼叫会被转到default context的s分机。

另外,对于配置comebacktooriginal=no的呼叫,Asterisk会在park-dial context下创建一个SIP_0004F2040808分机。这个分机用于利用Dial()拔打SIP/0004F2040808。

The [featuremap] Section 编辑

在这部分可以定义特定的DTMF序列,它们将触发连接的Channel上的不同特性,通过Dial()或Queue()应用程序的选项。请参见表格

默认的blindxfer和disconnect特性码分别是#和*。通常,你可能想要修改它们的默认值,因为它们可能用于你希望做的其它事(例如,如果你在你的Dial()命令中使用了Tt选项,每次你按下#时都会发起一个transfer)。

The [applicationmap] Section 编辑

features.conf的这部分用于映射DTMF码到dialplan应用程序。主叫将进入hold状态,直到相应的应用程序完全执行完。

定义一个应用程序映射的语法如下所示(必须被写在同一行,换行是不允许的):

<FeatureName> => <DTMF_sequence>,<ActivateOn>[/<ActivatedBy>],<Application>([<AppArguments>])[,MOH_Class]

你需要做下述事宜:

  1. 给定映射一个名字,从而可以通过使用channel变量DYNAMIC_FEATURES来使用它;
  2. 定义一个DTMF序列来激活这个特性(我们建议至少使用两个按键);
  3. 定义这个特性在哪个channel上起作用,以及(这是可选项)哪一方可以激活这个特性(默认是双方都可以激活);
  4. 给出这个映射激活的应用程序的名字,以及相关参数;
  5. 给这个特性分配一个呼叫保留音乐组(MOH,Music On Hold),这样对端用户就会在应用程序执行时听到这个音乐。如果你没有定义MOH组,对端用户则听不到任何声音。

下面是触发一个AGI脚本的应用程序映射的例子:

agi_test => *6,self/callee,AGI(agi-test.agi),default

由于通过应用程序映射执行的应用程序是在PBX内核程序之外的,所以你不能执行任何触发dialplan的应用程序(例如Goto(),Macro(),Background(),等等)。如果你希望利用应用程序映射执行一些外部处理(包括执行dialplan代码),你需要通过AGI()或System()应用程序来触发外部应用程序。要特别指出的是,如果你希望利用应用程序映射做一些复杂的工作,你需要非常小心的测试,因为并不是所有事情都会像你期望的那样执行。

为了使用一个应用程序映射,你必须在dialplan中通过在Dial()命令执行前设置DYNAMIC_FEATURES变量来声明它。在变量名前使用双下划线是为了保证应用程序映射在呼叫生命周期内的两个channels中都有效。举例:

exten => 101,n,Set(__DYNAMIC_FEATURES=agi_test)

exten => 101,n,Dial(SIP/0000FFFF0002)

如果你需要在一个呼叫中允许多于一个的应用程序映射,你需要使用#做为多个映射名之间的分隔符:

Set(__DYNAMIC_FEATURES=agi_test#my_other_map)

使用#而不是简单的使用逗号作为分隔符的原因是,老版本的Set()对于逗号的解释与新近的版本不同,而应用程序映射的语法一直没有升级。

不要忘记在修改了features.conf文件后重现加载features module:

*CLI> features reload

你可以通过CLI命令features show来确认你的修改是否生效。请确保你在将你设计的应用程序映射交付客户前测试过它们!

继承Channel变量

Channel变量总是与最初设置它们的channel关联,并且一旦这个channel被呼转则变量不再有效。

为了允许channel变量能够跟随这个channel在系统内呼转,必须使用channel变量继承。有两种修饰符可以让channel变量能够跟随channel:单下划线和双下划线。

单下划线使channel变量可以再一次呼转中被继承,而在其后的呼转中将不再有效。如果你使用双下划线,channel变量将在这个channel的整个生命周期中被继承。

设置channel变量继承只需要简单的在channel名前增加一个单下划线或双下划线前缀。不过channel变量仍然采用不加前缀之前的方法来引用(例如,不要尝试用带下划线的变量名来读取变量的值)。

下面是设置单次呼转继承的channel变量的例子:

exten => example,1,Set(_MyVariable=thisValue)

下面是设置永久呼转继承的channel变量的例子:

exten => example,1,Set(__MyVariable=thisValue)

要读取channel变量的值,不要使用下划线:

exten => example,1,Verbose(1,Value of MyVariable is: ${MyVariable})

Application Map Grouping 编辑

如果你有许多features需要对特定的context或extension使用,你可以在application map grouping中把这样几个features组成一组。因此,当用DYNAMIC_FEATURES变量指定组名时相当于设置了组中所有的features到映射中。 这种application map groupings增加在features.conf的最后。每个组指定一个名字,其后跟随相关的特性列表。

[shifteight]

unpauseMonitor => *1 ; custom key mapping

pauseMonitor => *2 ; custom key mapping

agi_test => ; no custom key mapping

如果你希望在application map grouping中为某个feature指定自定义的按键映射,简单的在=>输入你希望按键映射就可以。如果你没有指定按键映射,则该特性就会使用默认的按键映射(在[featuremap]部分定义)。不管你是否指定自定义按键映射,=>操作符都是必须的。

在dialplan中,你可以用Set()来设置这个application map grouping:

Set(__DYNAMIC_FEATURES=shifteight)

; use the double underscore if you want to ensure

; both call legs have the variable assigned.

Parking Lots 编辑

Parking lot允许呼叫被保留在系统中而不与任何extension关联。然后这个呼叫还可以被知道对应park code的任何人恢复。这个特性通常与吸顶式广播系统一起使用。由于这个原因,它一般被称为park-and-page。然而,需要注意的是实际上parking和paging功能是独立的。

为了在Asterisk中park一个呼叫,你需要将呼叫呼转到feature code指定的parking号码,它通过features.conf文件中的parkext来配置,默认是700:

parkext => 700 ; What extension to dial to park (all parking lots)

你必须等待这个呼转操作完成,直到你从系统得到一个parking恢复号码,否则你将无法恢复这个呼叫。默认的呼转恢复号码,用features.conf中parkpos指定,编码范围是701-720:

parkext => 700 ; What extension to dial to park (all parking lots)

一旦呼叫被parked,任何人都可以通过拨打指定给这个呼叫的恢复号码(parkpos)来恢复通话。然后这个呼叫就会被桥接到拨打了恢复号码的channel。

有两种常用方法来定义怎么分配恢复号码。这可以通过features.conf中的findslot来定义。默认的方法(findslot=>first)总是使用最小的空闲号码。第二种方法(findslot=>next)循环使用恢复号码并每次指定下一个,当最后一个恢复号码使用后怎回到第一个恢复号码。具体选择哪种方法取决于你的parking系统有多忙。如果你很少使用parking,findslot的默认值first是最佳选择(人们将会总是使用同一个恢复号码)。如果你的parking系统很繁忙(例如,当用于一个汽车销售店时),那么每个后继的parking呼叫采用下一个恢复号码会更好,因为你经常会遇到同时有多个parking呼叫。用户需要仔细听用的是哪个恢复号码(而不是总是701),而且有时会发生意外的恢复了错误的呼叫的情况。

如果你使用了parking功能,你大概还需要一个方法宣布这个parked呼叫,从而可以让接听人知道如何恢复这个呼叫。当然你也可以跑到大厅大喊“Bob,有你的电话在701线!”,更专业的做法是使用paging系统(更正式的名字是公共广播系统)

吸顶式和“下巴底下式” Paging (a.k.a. 公共广播) 编辑

许多PBX系统中,都允许用户通过电话把他的声音发送到公共广播系统中。这一般要求拨打一个feature code或者extension和公共广播资源建立连接,然后通过电话机的手柄讲话,就可以广播到所有相连的公共广播设备上。通常,这是一种包括一个连接吸顶式喇叭的放大器的外接广播设备。然而,通过办公电话的免提喇叭的广播系统也非常流行(主要是出于成本原因)。如果你预算足够(或者已经有了一个吸顶式广播系统),吸顶式广播系统一般来说要更好一些,但是基于办公电话的广播系统(a.k.a.“下巴底下式”广播系统)在大多数环境也工作的很好。更常见的情况是混合的广播系统,在这种方案中,举例来说,基于办公电话的广播系统被用于办公室环境,而基于吸顶式喇叭的广播系统被用于仓库,走廊,以及一些公共区域(食堂,接待处等)。 在Asterisk中,Page()应用程序用于广播。这个应用程序简单的用一组channels作为参数,同时呼叫每一个channels,然后,当它们应答后,将每一个都放入会议室。需要注意的是,很明显,paging系统能工作的一个条件式每个目标channel都可以自动应答来电并能用某种方式把语音输出到免提喇叭(换句话说,如果所有被叫电话只是振铃的话,Page()无法工作)。

所以,虽然Page()应用程序本身的使用非常简单,但让所有的目标channel都正确的处理来电广播却要更麻烦一些。我们将简要说明如下。

Page()应用程序有三个参数,分别是需要广播的channel组,选项,以及超时时间:

exten => *724,1,Page(${ChannelsToPage},i,120)

选项给Page()的工作方式提供了一些灵活性,但是大部分这些配置都与目标设备如何处理来电连接有关。我们将在下面的部分研究配置设备接收广播的不同方法。

由于Page()的工作方式,它是非常消耗资源的。我们怎么强调这一点都不过分。仔细阅读本书,我们将讨论如何保证paging不会在一个产品环境中导致性能问题(如果没有正确的设计,这几乎是必然的)。

发送你的广播 编辑

如我们之前所述,Page()本身是非常简单的。窍门在于如何把它们组织到一起。广播可以发送到不同类型的channels中,而且它们都需要不同的配置。

外部广播系统 编辑

如果建筑中已经安装了公共广播系统,通常的做法是连接电话系统到一个外部放大器并通过一个呼叫发送广播到公共广播系统中去。做到这一点的一种方法是在你的服务器上安装一个声卡连接到外部放大器,然后把呼叫发送到名为Console/DSP的channel,但是这是假设你服务器上的声卡驱动工作正常并且正确的设置了音量。另一种,更简单,也更可靠的连接外部广播设备的方法是使用某种带有FXS接口的设备(例如ATA),该设备被连接到诸如Bogen UTI1这样的广播设备接口上,这样就连接到外部广播放大器上了。 在你的dialplan中,向一个外部放大器发送广播的操作就是简单的Dial()到连接着广播设备的设备上。举例来说,如果你有一个ATA在sip.conf中配置为[PagingATA],并且你将这个ATA连接到UTI1,你可以这样来执行广播:

exten => *724,1,Verbose(2,Paging to external amplifier) ; note the '*' in the

; extension is part of

; what you actually dial

same => n,Set(PageDevice=SIP/PagingATA)

same => n,Page(${PageDevice},i,120)

请注意为了这个系统能正常工作,你必须在sip.conf中将你的ATA作为一个SIP设备注册,在这个例子中我们命名这个设备为[PagingATA]。你可以用任何你喜欢的名字命名这个设备(例如,通常我们用MAC地址作为SIP设备的名字),但是无论如何它不是一个用户电话机,使用一个有别于其它设备的名字是有帮助的。

如果你在系统中使用了一张FXS板卡并连接到UNI1上,你可以Dial()到这个channel来代替FXS port:

same => n,Dial(DAHDI/25)

UTI1应答这个呼叫并且打开连接到广播系统的channel;然后你就可以发表广播了。

基于电话机的广播系统 编辑

基于电话机的广播系统第一次变得流行是在按键式电话系统中,在那里办公电话机的免提喇叭被用作穷人的公共广播系统。大部分SIP电话机都具备免提自动接听呼叫的能力,这就实现了基于电话机广播系统的要求。除此而外,还需要同时把语音送往多余一部电话机。Asterisk使用它内置的会议引擎处理这些内部细节。你可以通过使用Page()应用程序实现这一目的。 像Dial()一样,Page()应用程序可以处理多个channels。由于你通常希望Page()一次给多个话机(或者全部的话机)发信号,你可能只能采用如下所示的冗长设备字符串:

Page(SIP/SET1&SIP/SET2&SIP/SET3&SIP/SET4&SIP/SET5&SIP/SET6&SIP/SET7&...

当超过一定规模后,你的Asterisk系统将无法向更多的话机发送广播。例如,如果一个办公室有200个电话机,利用SIP来广播每一个设备是不可能的;你Asterisk服务器的流量和CPU负荷会变得过重。在这种情况下,你应该考虑或者采用多播广播或者外部广播系统。

或许基于SIP的广播系统的最棘手部分是这样一件事,你必须告诉每一部话机它必须自动应答,但是不同的SIP话机制造商使用不同的SIP信息来实现这一点。所以,依赖于你所使用的电话型号,用于实现给予SIP话机的广播命令也会不同。举例如下:

• For Aastra:

exten => *724,1,Verbose(2,Paging to Aastra sets)

same => n,SIPAddHeader(Alert-Info: info=alert-autoanswer)

same => n,Set(PageDevice=SIP/00085D000000)

same => n,Page(${PageDevice},i)

• For Polycom:

exten => *724,1,Verbose(2,Paging to Polycom sets)

same => n,SIPAddHeader(Alert-Info: Ring Answer)

same => n,Set(PageDevice=SIP/0004F2000000)

same => n,Page(${PageDevice},i)

• For Snom:

exten => *724,1,Verbose(2,Paging to Snom sets)

same => n,Set(VXML_URL=intercom=true)

; replace 'domain.com' with the domain of your system

same => n,SIPAddHeader(Call-Info: sip:domain.com\;answer-after=0)

same => n,Set(PageDevice=SIP/000413000000)

same => n,Page(${PageDevice},i)

• For Cisco SPA (the former Linksys phones, not the 79XX series):

exten => *724,1,Verbose(2,Paging to Cisco SPA sets -- but not Cisco 79XX sets)

same => n,SIPAddHeader(Call-Info:\;answer-after=0) ; Cisco SPA phones

same => n,Set(PageDevice=SIP/0004F2000000)

same => n,Page(${PageDevice},i)

估计你已经发现,如果在你的环境中混合了不同的电话机,会发生什么?你如何控制哪种信息头发送给哪种电话机?

无论你从哪方面考虑,这都不好实现。

幸运的是,许多SIP话机都支持IP组播,这是一种向多个话机发送广播的好得多的办法(请仔细阅读)。然而,如果在你的系统中只有少量电话机并且都来自于同一个供应商,基于SIP的广播将是最简单的方法,所以我们并不想完全把你吓跑。

通过MulticastRTP channel实现多播广播 编辑

如果你认证对待通过话机实现广播,并且你有超过100个话机,你需要考虑IP多播。IP多播的概念已经存在很长时间了,但它并没有被广泛应用。然而,它是在一个地点实现广播系统的理想方法。

Asterisk有一个channel(chan_multicast_rtp)是设计用于创建RTP多播的。然后这个流会被不同的电话订阅,结果是当声音出现在多播流上时,电话机会将这个声音通过免提喇叭播放出来。

因为MulticastRTP是一个channel驱动,所以它没有独立的应用程序。但是你可以在dialplan中任何可以使用channel的地方使用它。在我们的例子中,我们将使用Page()应用程序来初始化我们的多播。

为了使用多播channel,你只要像处理任何其它channel一样简单的发送呼叫给它就可以。语法如下:

MulticastRTP/<type>/<ip address:port>[/<linksys address:port>]

其中type可以是basic或linksys。当type是basic时的语法是:

exten => *723,1,Page(MulticastRTP/basic/239.0.0.1:1234)

并不是所有的设备都支持IP多播,但是我们已经在Snom,Linksys/Cisco,Avaya等设备上进行了测试,它们都能正常工作。

在Cisco SPA电话机上使用IP多播广播

在Cisco SPA电话机上实现IP多播广播特性的方法有些奇怪,但是一旦我们配置好,它也能很好的工作。窍门在于你在电话机上配置的多播地址并不是Page()中发送的地址,而更像一个信令channel。

我们发现的窍门是,你完全可以把这个地址当作多播地址一样只用,但是要使用不同的IP端口号。

Dialplan看起来是这样的:

exten => *724,1,Page(MulticastRTP/linksys/239.0.0.1:1234/239.0.0.1:6061)

在SPA电话机上,你需登录到它的WEB管理界面的SIP页面。在这一页非常靠下的地方,你会找到一个名为Linksys Key System Parameters的部分。你需要配置下列参数:

• Linksys Key System: Yes

• Multicast Address: 239.0.0.1:6061

请注意你在这里指定的多播地址是你在Asterisk的MulticastRTP channel中定义的第二个地址(在我们的例子中,这一个使用端口6061)。

请注意当你的环境中混合由SPA电话机(过去是Linksys,现在是Cisco)和其它型号的电话机时,你可以像这个例子中一样书写Page()命令。其它电话机将使用第一个地址,就像你在命令中用basic替代linksys一样。

VoIP广播适配器 编辑

最近,市场上出现了一种基于VoIP的广播喇叭。这种设备在dialplan中的处理与连接到UTI1上的SIP ATA完全相同,但是它们可以被与吸顶式喇叭相同的方法安装。由于它们是自动应答的,所以不需要像对于SIP话机那样向它们发送额外的信息。

对于小型应用(可能只需要不到六个喇叭),这种设备可能是不划算的。然而,对任何更大的系统(或者安装在复杂环境的系统,例如仓库或停车场)来说,你将在远低于通过模拟接口(FXS)连接到传统电话系统的传统模拟公共广播系统的成本的情况下获得更好的性能。

我们不知道这类设备是否支持多播。如果你计划大量使用这种设备,请记住这一点。

组合广播 编辑

在许多组织中,可能既需要基于话机的广播系统也需要外部广播系统。作为一个例子,一家工厂可能希望在办公区使用基于话机的广播系统,而在车间和仓库使用吸顶式喇叭的广播系统。从Asterisk的观点看,这非常容易实现。当你调用Page()应用程序时,你可以简单的指定你希望广播的不同资源,并利用&字符分隔开,这样它们就将都被包含在Page()应用程序创建的会议中。

混合在一起应用 编辑

这时候,你应该有了一张你希望广播的不同channels的列表。由于Page()可以同时向多个channel发信号,我们建议首先定义一个包含所有channels列表的全局变量,然后再调用Page()应用程序:

[global]

MULTICAST=MulticastRTP/linksys/239.0.0.1:1234

;MULTICAST=MulticastRTP/linksys/239.0.0.1:1234/239.0.0.1:6061 ; if you have SPA

; (Linksys/Cisco)

; phones

BOGEN=SIP/ATAforPaging ; This assumes an ATA in your sip.conf file named

; [ATAforPaging]

;BOGEN=DAHDI/25 ; We could do this too, assuming we have an analog

; FXS card at DAHDI channel 25

PAGELIST=${MULTICAST}&${BOGEN} ; All of these variable names are arbitrary.

; Asterisk doesn't care what you call these strings

[page_context] ; You don't need a page context, so long as the extension you

; assign to paging is dialable by your sets

exten => *724,1,Page(${PAGELIST},i,120)

依赖于不同的硬件,这个例子提供了几种可能配置。虽然并不严格要求必须定义PAGELIST变量,但我们发现定义该变量有助于简化管理多种广播资源,特别是在配置和测试阶段。

我们为了这个例子创建了一个用于广播的context。为了让它工作,你或者用include将这个context包含到你的分机进入dialplan的context中,或者利用Goto()跳转过来(例如,Goto(page_context,*724,1))。另一个选择是,你可以在每个需要用到广播的context中写死一个extension用于这个目的。

分区广播 编辑

分区广播在像汽车卖场这样的地方非常流行,在这种地方,新车销售部门和二手车销售部门可能都需要用到广播系统,但并不需要听到其他部门的广播信息。

在分区广播应用中,当一个人发送广播时需要选择她希望向哪个区广播。一般会采用类似PAM2000这样的分区广播控制器来允许发送喜好到不同的分区:Page()应用程序发送信号到分区控制器,分区控制器应答,然后一个额外的数字被发送来选择广播会发送到哪个区。大部分分区控制器允许向所有分区广播,以及向部分分区广播(例如,想新车及二手车销售部门广播)。

你也可以在dialplan中使用独立的extensions来分隔ATAs(或者一组电话机),但是这么做被证明比简单购买一个分区控制器带来更大的复杂性和更高的费用。分区控制器并不需要特别的不同技术,但是它需要有关dialplan和硬件的更多思考和计划。

结论 编辑

在本章中,我们研究了features.conf文件,它包含了很多功能,包括使能基于DTMF的呼叫转移,使能通话过程中的录音,为一个或多个公司配置parking号码。我们也学习了向办公室广播信息的不同方法,包括传统的吸顶式广播系统和利用办公电话的多播广播系统。研究这些利用现代方法实现传统的parking和paging功能的方法有助于展示Asterisk可以提供的灵活性。

注释:

注1.是的,我们了解SIP INFO消息事实上是SIP消息,从技术上说并不是语音通道的一部分。但需要指出的是,在呼叫中你不能通过你的SIP电话机上的“transder”或“park”按键来使用这些特性。你必须通过发送DTMF来使用这些特性。

注2.多读两遍,这是有意义的。

注3.我们希望你了解,实际的extension(分机)命名与parked这个呼叫的channel名相关,但不会真的是SIP_0004F2040808(除非Leif把他实验室的Polycom电话卖给你了)。

注4.虽然也可以采用一些灵活的语法(你可以从示例文件中找到例子),但是我们的例子都是采用我们推荐的语法书写的,因为它是最符合典型的dialplan语法的。

注5.Bogen UTI1接口是非常有用的,因为它可以处理各种各样的输入和输出连接器,它几乎能保证我们能毫不费力的将你的电话系统连接到任何外部广播设备上,无论它有多老或多少见。

注6.在本书中,我们假设外部广播设备已经安装并且是与老式电话系统连接在一起的。

注7.提示:在这里local channel将是你的朋友。

注8.IP多播有专用的D类地址,从224.0.0.0到239.255.255.255(但是请在使用多播地址前仔细研究IP多播)。部分多播地址是私有的,部分多播地址是公共的,以及部分多播地址是用来设计实现与你所希望的不同目的的。关于多播地址的更多信息,请参考http://en.wikipedia.org/wiki/IP_multicast#IP_multicast_addressing_assignments.

注9.非常大声,并且无法调整增益。 注10.迄今为止,我们可以说Polycom设备不支持多播。我们确定无法找到办法来实现。