1、Asterisk 入门教程subscriber:加入某个 group,从而遵从某一个 call restricionsubscriber group:可以使用 1 种 call restriction。call restriction:将 numbering plan 中各项取出,各自组成成不同的呼叫限制方案numbering plan:通用,是一个整体的计划,里面包括长途,本地,等各种形式的方案-以上,用于拨入号码的预处理,实际上是一种过滤,下面才是真正的呼叫处理。-route:一种策略,根据号码匹配的模式,选择走哪个 trunk。trunk:实际上做通一个链路,供 route 选择。ana
2、log 的,一个 POTS 就是一条 analog trunkanalog 的数量由设备定,ip trunk 没有限制数量,并且一个 ip trunk 连到对方 IPPBX 后,对方的 subscriber 数量是不确定的,由那个 IP PBX 决定。Asterisk,开始吧-什么是 asterisk?开源电话平台Asterisk 通过了电话的开源平台。基本上就是一个软件的 PBX。最初是 Digium 公司的 Mark Spencer 编写的,这个公司就是他创立的,专门生产并销售Asterisk 使用的硬件。Asterisk 简直就是一场电话的革命。为什么使用 Asterisk?现在电信行业
3、的混乱,因为各种专利技术应用在各种层次的网络上,导致很大的混乱。Asterisk 就是答案给电信行业普遍的混乱环境带来秩序的革命。专利技术有什么错?没错,如果专利技术独立工作的话。就像你有剃须刀和剃须膏没错一样!但是让各种技术互相操作,专利技术就会除了要价过高、客户不满,以及缓慢的开发速度等问题之外的刻板和局限。我们要 Asterisk 做什么?根据情况而定。在一个小实验室,一个 pc(x86) ,500MHz 的奔三,合适的内存,合适的电源,还有 Linux (其他 os 也可以支持) 。此外还有 Digium 板卡插在系统中,以便连接本地 PSTN。Asterisk 支持什么技术?与 Vo
4、IP, PSTN, ISDN, AIX, SIP 有关的任何东西。比较好的 Asterisk 参考书?(http:/www.asterisk-docs.o.找到,编译,安装,在第 3,4 章中,包含了到哪里去找那些文件之类的信息。还有编译时的需要注意的选项,需要配置的模块,和在运行时载入的模块。相关:gcc, glibc-kernheaders, cpp, binutils, glibc-headers, glibc-devel此外, 安装 bison 和 open ssl大多数标准的 distro 都自带推荐 distro:基于 RedHat 和 RH 的 distro (版本没指定)组件:
5、AsteriskZaptellibpriAsterisk:Asterisk 程序文件,还有配置,监控的工具Zaptel: Zapata 项目中硬件的核心模块和驱动,如果要与 PSTN 或者其他网络接口,需要它。libpri: 与 Primary Rate Interface ISDN 的接口库。还有,如果基准时间参考,需要安装 ztdummy 模块(第 3 章中解释)有用的网页:PSTN: http:/en.wikipedia.org/wi.G.729: http:/en.wikipedia.org/wi.G.711: http:/www.freesoft.org/CI.Digium: htt
6、p:/en.wikipedia.org/wi.Asterisk: http:/en.wikipedia.org/wi.Free World Dial-up: http:/en.wikipedia.org/wi.Asterisk Architecture: http:/www.asteriskdocs.or.重要链接: Putty:http:/www.chiark.greenend.Asterisk 通道:http:/www.voip-info.org/w.重要信息:Asterisk machine on the LAN: 90.0.0.3Asterisk 的目录结构:(更确切的说,是 Aste
7、risk 使用的目录)/etc包含了 zaptel.conf 文件(只有一个)/usr/lib/asterisk/modules所有的 asterisk 可载入的模块都在这里,一般来说,所以的模块都是启动的时候载入的注意:要更改启动时载入的模块,或者是模块载入的方式,你可以修改/etc/asterisk/modules.conf 文件/etc/asterisk包含了所有的 asterisk 配置文件/var/lib/asteriskagi-bin: agi 脚本固件:兼容设备固件映像:在这个目录下寻找映像(如果通道支持)关键字:这个文件中有基于 RSA 一类的认证关键字mohmp3:当配置了持
8、有音乐的时候,这个目录是放置 mp3 的(注意,mp3 应该使用恒比特率编码,并且没有 id 标签。 )sounds:所有的语音提示/var/spool/asteriskqcall:撤销了 包含了特殊呼叫方法的呼叫信息文件不是打电话的好方法,因为这种方式太硬性了不再使用。使用 outgoing 替代。Outgoing:现在打电话的法国闹事 呼叫信息目录普遍使用。Tmp:中间/临时数据Voicemail:语音和问候语。通过修改/etc/asterisk/voicemail.conf 文件可以修改。/var/run处理系统中运行进程的 id(包括 asterisk)/var/log/asteris
9、kAsterisk 在这里生产日志,通过 /etc/asterisk/logger.conf 来配置。/var/log/asterisk/cdr-csv用来存储呼叫详细记录,逗号分割,例如 csv(地址簿格式)重要:很多时间会使用 cdr,ast 附件包的代码可以在 mysql 数据库中存储 cdr,用于记录呼叫详细记录外部交换借口/通道接口FXO : Digium Dev-Lite kit 上的红口:Foriegn eXchange Office:这个通道(接口)的动作角色是 fxo,利用 fxs 协议就是说这个模块需要插入到 pstn。FXS(Digium 卡的绿口):Foriegn eX
10、change Station,它表现得像 fxs,读的是 fxo 协议所以要插入终端设备注意,这里插 pstn,会烧坏!配置 Foriegn eXchange Station 文件:让你对常见的通道接口进行管理/comm 通道硬件,决定如何在连接的设备之间进行握手。注意:使用 zapata.conf 文件完成非常重要的通道配置激活或者失效类似回形针、回声处理之类的功能。详细程度到 pstn 添加到那个端口,信令控制等如果这里配置不正确,甭指望系统能工作正常。拨号计划:在 extensions.conf 中指定。Dialplan:拨号计划:在 /etc/asterisk 文件中 拨号计划语法由以
11、下组成部分:上下文(context) :写在里面 , 定义上下文来创建独立的空间注意:最重要的一个上下文的应用就是提供安全性:要获得更多信息,看安装文件中SECURITY 文件。例如:incomingstatement 1-statement 2-next-context注意:当下一个定义的上下文开始的时候,现在这个上下文就结束了。分机:非常简单。与普通的 PBX 一样。分机号的意思是你在连接到系统之后拨打的号码以获得某个终端/服务-不仅是 asterisk分机以如下格式定义:exten =分机的组成部分:exten = name, priority, application()例如 exte
12、n = 123, 1, Answer() 的意思是当另一端拨打 123,调用 asterisk/apps /Answer(),优先级别为 1。优先级别通常从 1 开始。数字越小,级别越高。例如,级别 1 就比级别 2要高。 (现在,有一些称为非数字化的级别非常好,继续读!)一个很好的例子:exten = 123, 1, Answer()exten = 123, 2, Hangup()会发生什么情况,无论什么人拨打 123,系统都会首先执行 answer() ,然后当 answer 结束的时候,过渡到 hungup() 。你看,都是执行的顺序和优先级。还有一些特殊的分机,例如 s,比如我们前面的
13、例子中 123 的位置,后面再解释记住:所有的优先级别都是从 1 开始,其他的必须遵循这个顺序。Ast 不会处理其他的,会认为是出错。分机可是任何,不仅是数字,例如名字。优先级:我想在前面讨论分机的时候已经讨论了优先级别。非数字的优先级:我们会在 Answer() . Hangup() 后使用 n 来代替实际的优先级别数字。exten = 123, 1, Answer()exten = 123, n, Hangup()Asterisk 会自动给优先级别+1, 所以你就不用每次记着并输入这个数字了Also, in Asterisk v2, weve got a way to put labels
14、 tp priorities:exten = 123, 1, Answer()exten = 123, n(Hangup), Hangup()Applications:应用程序:应用程序是真正执行你的拨号计划的程序。拨号计划定义了顺序应用程序就按照它去做。工作内容可以是任何东西,从播放声音到接受当前通道上的按键输入。(http:/www.voip-info.org/w.了解 asterisk 通道,虽然听起来很好笑,但是我是对通道很迷惑)简而言之,应用程序是真正干活的,当有人拨打 123 的时候,参考以上示例。我们可以通过友好的邻居应用程序传递参数,把它们放在逗号或者竖线分割的列表中。例如:e
15、xten = 123, 1, DoSomething(Arg_1,Arg_2,Arg_3,Arg_n)或者 exten = 123, 1, DoSomething(Arg_1|Arg_2|Arg_3|Arg_n)开源中,你随意!特别分机:s是个特别的分机它处理环境中任何的输入,没有特定目标。S 意味着开始。例如incomingexten = s,1,application( )exten = s,2,application( )exten = s,3,application( )现在,只要呼叫进入,就带有最高级别,进入 s。当我们补充了应用程序之后,我们就是创建了自己的拨号计划填入应用程序名(
16、分配正确的优先级别)exten = s,1,Answer( )exten = s,2,Playback(hello-world)exten = s,3,Hangup( )这就是 asg 拨号计划了这个拨号计划会:1. 接电话 (接听已经建立了通道的呼叫,这个呼叫就是从这个通道来的,在进行任何处理之前,先把电话接听.没有参数传递。2. 播放语音,给出了语音文件的路径,通常在 /var/lib/asterisk/sounds/, gsm 格式,后缀名为.gsm。如果有多个文件都符合这个文件名,ast 就播放那个 cpu 负载(翻译成本)最小的,翻译成本与不同的文件格式有关。在 cli 下面输入 s
17、how translation 可以看到,参数,语音文件名,还有路径,如果这个文件没有在标准路径下。3. 挂掉活动通道,主叫方就是从这个通道进行呼叫的,很必要,确保主叫没有继续拨号计划。没有参数为拨号计划添加逻辑:Background() 应用程序: 它与 playback() 非常像, 只是在播放语音的时候,如果用户拨打号码,语音中断,然后呼叫那个分机。例如,主叫拨打分机 x,会以第一优先级转到分机x 上面去。语法:Background(sound_file)例子:extend = s,n,Background(sound_filename)回拨语音文件,直到用户输入分机号,在创建语音菜单的
18、时候有用。但是 playback()不会接受输入,会一直拨,直到语音文件结束。Goto() 应用: 如其名,主叫跳到某个 context / extension / priority 上去.语法:Goto(context, extension, priority)例子:exten = 1,n,Goto(incoming,s,1)把控制权交给下一个上下文,分机 s, 优先级别 1 预先订制拨号计划跳转的流程,链接:Xlite sip 电话- 免费的: http:/ Ubuntu:Ubuntu, 是一个比较新的桌面友好的 distro ,放在 Asterisk 专用的机器上.重要内容:Ubuntu
19、 很好 对桌面来说我们必须装很多内容才能在 ast 服务器上用.所以一般来说: 不要使用桌面 disrto ,如果你计划在上面跑服务器的话- Fedora 是更好的选择.但是也没有坏处- 有耐心,万事可达 .载入 Ubuntu 的基本原因就是为了图形化工具 Firefox 和 Acrobat。只是费很多 CPU 和内存,x 历史遗留问题。所以我们继续的是一台新机器,从新开始运行 ast下面开始真正体验 ast 系统。经过良好调整的 Ubuntu 可以阅读 PDF 文档。带有 safe_asterisk 脚本的 ast 二进制文件在/usr/sbin 中,昨天咱们编译过了如果 ast 异常,sa
20、fe_asterisk 脚本会引起 ast 的 core dump,默认情况下是在第 9 终端开启 ast。开始 ast 我们使用 safe_asterisk 脚本,或者运行 ast 二进制文件来手工启动 ast。在运行safe_asterisk 脚本的时候,在 9 终端上载入 ast 的 CLI(终端号可以配置) ,执行 ast 二进制文件载入 ast,作为后台程序我们还可以用初始化脚本来启动或者关闭 ast。见书 71 页求助:asterisk -h其它命令行参数:-c 显示 Asterisk CLI (或控制面板)-v 设置 CLI 的详细程度 - 例如 v (verbose), vv
21、(very verbose), vvv (very very verbose)-g 告诉 asterisk 创建 core dump,一会用 gdb 调试-r 远程-连接到一个已经运行的 Asterisk 进程上 (与网络远程连接没有关系)-rx 远程执行 执行引号内的命令 ( “restart now“) 不需要真的启动 CLI还有好多命令Beginning an affair with Asterisk - Day 6asterisk-dev 准备好 -asterisk-dev 的配置:Distro: Ubuntu 5.10 (Breezy Badger)Asterisk version:
22、 1.2.1运行配置: 图形下完全多用户模式 (运行级别 5)asterisk-dev 机器上还装载了很多其他内容.本章的任务:1. Linux 下 Xlite 客户端的配置,以便与 asterisk-dev 上我们的测试 Asterisk 服务器共同工作.链接:Xten 网站: http:/ 下载页面 e: http:/ 录些 gsm 音频格式的音频文件 :welcome messegetimeout messege我们使用免费的基于 Windows 的软件(aghhh) 来进行录制,格式转换和音频标准化 . 它工作非常好,并且最重要符合我们的要求- 快速录制,不需要撞墙很长时间。链接: 录
23、制/ 转换/ 处理软件-录制: Recordpad Trial Version - http:/.au/reco.音频转换(WAV to GSM): Switch Freeware Version - http:/.au/swit.音频编辑和处理: Wavepad Trial Version - http:/.au/wave.轻松快速创建音频文件,转换格式,并且标准化到正常的语音级别,让声音没有分叉。可惜不是开源并且在 Linux 下. .注意:以上软件只是生成测试录音,为学习而已。 Enterux Solutions (或者客户端, Enterux) 许可证要求不需用于任何商业目的。这个开源
24、的 zgsmplay 可用来测试我们的新 gsm 音频文件,在 Linux 上链接: http:/ 写第一个拨号方案:我们的分机配置文件 extensions.conf 如下:incoming欢迎界面,exten = s,1,Background(enterux/welcome)exten = i,1,Playback(enterux/invalid-extension)exten = i,n,Goto(incoming,s,1)exten = t,1,Playback(enterux/call-will-be-disconnected)exten = t,n,Hangup(); 呼叫方可以拨
25、打的用户分机exten = 0,1,Dial(SIP/0) ; Operatorexten = 1,1,Dial(SIP/1) ; Sales staff 使用 Support staff -使用用户添加 0-operator, 1-sales ,2-support0user=0type=friendsecret=1234host=dynamiccontext=incoming1user=1type=friendsecret=1234host=dynamiccontext=incoming2user=2type=friendsecret=1234host=dynamiccontext=inco
26、ming配置 Xlite,完成拨号计划。参考 103 页(拨号计划基本章节)4.观察结果:如果一个登录到 ast 服务器上的一个软电话拨打 201/202,预记录就会播放欢迎语音。“Welcome to Enterux Solutions. Press 0 for an operator, 1 for sales and 2 for Support. Thank you.“拨打 0,1 , 2 之后,通过 Dial() 应用程序拨打合适的用户如果分机号码不对,就播放语音“You have dialled an invalid extension. Please try again.“.软件电话
27、 Xlite 没有声音了,出错说找不到声音驱动分别试验了 Kiax ,Linphone. TwinkleTwinkle 好用了. (仍然出错 “无法读 .DCOPserver_asterisk-dev_0; Please check that the dcopserver program is running“ 在启动栏 这样就好了).继续,测试拨号计划链接:Twinkle SoftPhone: http:/www.twinklephone.co.装好 Twinkle (and a little prayer) 我们修改#1 号拨号计划:extensions.conf 文件:incoming;
28、 欢迎exten = s,1,Background(enterux/welcome)exten = i,1,Playback(enterux/invalid-extension)exten = i,n,Goto(incoming,s,1)exten = t,1,Playback(enterux/call-timeout)exten = t,n,Playback(enterux/thankyou)exten = t,n,Hangup()exten = 0,1,Playback(enterux/connecting-to-operator)exten = 0,n,Dial(SIP/0,10,r)
29、; Operatorexten = 0,n,Playback(enterux/line-not-answering)exten = 0,n,Hangup()exten = 0,102,Playback(enterux/line-busy)exten = 0,103,Hangup()exten = 1,1,Playback(enterux/connecting-to-sales)exten = 1,n,Dial(SIP/1,10,r) ; 用户添加 operator, sales and support0user=0type=friendsecret=1234host=dynamiccontex
30、t=incoming1user=1type=friendsecret=1234host=dynamiccontext=incoming2user=2type=friendsecret=1234host=dynamiccontext=incoming以下是拨号计划的内容:系统可接收 0,1,2,201,202.现在,我们的接线总机连到了 201 和 202 上面就是说,欢迎信息只在拨打 201 和 202分机时播放。我们添加了超时、忙碌和没有应答的功能。阅读 106 页代码。Ast 的设置是,当没有人接听电话的时候,被叫分机就响 2 声,然后回拨错误消息。如果被叫的分机应答了,ast 就接通,两
31、个人可以占用一个全双工通道。这是个非常简单的配置,只有最基本的应答函数,最基本的呼叫处理和连接两个用户的能力,用 Dial()这个应用程序。我们实际测试过,虽然有实质的延迟, 2-4 秒,就好像是一个人在讲话,另一个人在重复。这确实存在。有能力的话就写几行代码让两个语音通道互连(相似类型或者不同类型) 。现在我们只试验 “incoming“ 这一条,还添加了另外的 “internal“ 并对这个文件extensions.conf 进行了验证:incoming; Extensions for welcoming callerexten = s,1,Background(enterux/welco
32、me)exten = i,1,Playback(enterux/invalid-extension)exten = i,n,Goto(incoming,s,1)exten = t,1,Playback(enterux/call-timeout)exten = t,n,Playback(enterux/thankyou)exten = t,n,Hangup()exten = 202,1,Goto(incoming,s,1)exten = 201,1,Goto(incoming,s,1); 呼叫正确的分机exten = 0,1,Playback(enterux/connecting-to-oper
33、ator)exten = 0,n,Dial(SIP/0,10,r) ; Operatorexten = 0,n,Playback(enterux/line-not-answering)exten = 0,n,Hangup()exten = 0,102,Playback(enterux/line-busy)exten = 0,103,Hangup()exten = 1,1,Playback(enterux/connecting-to-sales)exten = 1,n,Dial(SIP/1,10,r) ;exten = 1,n,Playback(enterux/line-not-answerin
34、g)exten = 1,n,Hangup()exten = 1,102,Playback(enterux,line-busy)exten = 1,103,Hangup()exten = 2,1,Playback(enterux/connecting-to-support)exten = 2,n,Dial(SIP/2,10,r) ; 0: operator, 1:sales and 2:support0user=0type=friendsecret=1234host=dynamiccontext=internal1user=1type=friendsecret=1234host=dynamicc
35、ontext=internal2user=2type=friendsecret=1234host=dynamiccontext=internal0,1 , 2 的条款发生了变化从incoming 到 internal与以前类似,只是现在要使用的是不同的 contexts。-在 Asterisk 拨号计划中使用变量在拨号计划中使用变量在 asterisk 中设置变量 :JOHN=SIP/1引用变量 Asterisk:exten = 123,1,Dial($JOHN)很简单.注意:不需要大写变量名 这里是为了清晰变量的类型:全局变量:所有的 context 都可以访问的变量。全局变量在拨号计划的最
36、前面globals context 中声明.还可以在拨号计划中声明全局变量:globalJOHN=SIP/1或者some contextexten = 123,1,SetGlobalVar(JOHN=SIP/1)全局变量的生命周期是到 ast 关闭为止。渠道变量:渠道变量与特定呼叫或者呼叫通道有关。渠道变量的生命周期限制在呼叫的范围内.有许多预定义的渠道变量- 见 README.variables 文件 doc/ subdirectory.设置渠道变量:exten = 123,1,Set(MAGICNUMBER=42)环境变量:提供了通过 dialplans 访问 Unix 环境变量的方法.参
37、考环境变量:UNIXPATH=$ENV(PATH)Asterisk 中的模式匹配:Asterisk 会尝试匹配任何以下划线开头的符号 你可以在模式匹配中使用如下的符号:X 表示 0 到 9Z 表示 1 到 9N 表示 2 到 9 表示范围 (例如, 15-7 匹配 1,5,6 or 7). 通配符举例:_9. 会匹配所有以 9 开头的数字,例如 92, 932344,99999,91,等._XXX 匹配 3 个数字的串,每个数字的范围是 0 到 9,例如 321, 999,123, 等.使用匹配模式,:通常手工添加每个可能的分机是非常枯燥乏味的。模式匹配简单多了。出线中继(Outbound t
38、runk):要让用户可以通过 ast 网络拨打外面的电话号码,我们可以启用出线中继。比较好的方案如下:- 使用变量名来引用中继名。这可以让我们即时修改中继,不会引起错误- 使用编写正确的 context 来合理划分拨号计划. 这可以保证系统免受意外,或者恶意的未经授权的使用。下面看一些函数和条件分支,看看 extensions.conf incoming; s 和 t 分机 exten = s,1,Background(enterux/welcome)exten = t,1,Hangup(); 接受对 201 的呼叫exten = 201,1,Goto(s,1); GotoIf() 函数ext
39、en = 345,1,Set(TEST=greet)exten = 345,n,GotoIf(TEST=greet?10:20); Asterisk 给 GotoIf 传递一串参数exten = 345,10,Playback(weasels-eaten-phonesys)exten = 345,20,Playback(office-iguanas); 倒数,使用 GotoIf() 和命名的优先级exten = 346,1,Set(COUNT=10)exten = 346,n(say),SayNumber($COUNT)exten = 346,n,Set(COUNT=COUNT-1)exten
40、 = 346,n,GotoIf(COUNT0?say:thank)exten = 346,n(thank),Playback(auth-thankyou)exten = 346,n,Hangup(); 基于 Caller Id 识别的呼叫拒绝exten = 347,1,Set(REJECT_NUM=201) ; The number to be rejected (can also be done without a variable)exten = 347,n,Set(CALLER=$CALLERIDNUM)exten = 347,n,GotoIf(CALLER=$REJECT_NUM?re
41、ject-messege:welcome)exten = 347,n(reject-messege),Playback(abandon-all-hope)exten = 347,n,Hangup()exten = 347,n(welcome),Playback(welcome)exten = 347,n,Hangup(); 不同的呼叫拒绝示例 347exten = 348,1,GotoIf(CALLERIDNUM=201?30:20)exten = 348,20,Goto(201,1)exten = 348,30,Playback(abandon-all-hope)exten = 348,n,
42、Hangup(); 按时间播放语音,利用 GotoIfTime()函数exten = 349,1,Playback(good)exten = 349,n,GotoIfTime(04:00-11:59,*,*,*?good-morn)exten = 349,n,GotoIfTime(12:00-16:59,*,*,*?good-aft)exten = 349,n,GotoIfTime(17:00-03:59,*,*,*?good-eve)exten = 349,n(good-morn),Playback(morning)exten = 349,n(good-aft),Playback(after
43、noon)exten = 349,n(good-eve),Playback(evening)exten = 349,n,Hangup(); Planning on holidayexten = 350,1,GotoIfTime(*,*,26,jan?closed,s,1); 以上的意思是说,如果是 1 月 26,按照以下的优先级别 1 of s 的 close context 分机优先级别,否则是 open context 的 1 of s extension; 如下所示exten = 350,n,Goto(open,s,1)exten = 350,n,Hangup()openexten =
44、s,1,Playback(welcome)exten = s,n,Hangup()closedexten = s,1,Playback(sorry2)exten = s,n,Hangup()你可以拨打相应的分机B2BUA 的 hardphone call flow 2006-10-25 11:37:03 大中小 基本流程很正常,已经很熟悉说其中的细节:B2BUA 的方式,就是两个 UA 背靠背,分别接通两边的会话,做个中间人。5088141 - PBX 12 - 5010131-INVITE 501012TO:501012FROM:501012VIA:141CONTACT:5088141INVITE 5010131TO:5010131FROM:508812VIA:12CONTACT:508812ACK 5010131TO:5010131FROM:508812VIA:12ACK 501012TO:501012FROM:508812VIA:12200TO:508812FROM:501012VIA:131CONTACT:508812200TO:508812FROM:501012VIA:12