Asterisk 1.2.x至1.6.x版本更新分析 (Part of IP PBX产品化预研分析)(转)

1. ASTERISK 版本更新

*本更新包含内容主要是指从asterisk 1.2.x之后的,产品使用到或将使用到的各功能的更新说明,以及为适应开发将用到的新的asterisk功能的应用说明,目前考虑升级使用1.6.x版本进行产品开发,Asterisk 1.2.x-1.6.x的一个重要的中间版本是1.4(且目前仍为主流的商业应用版本,主要的教材及在线文档仍为1.4版本),关于1.6.x版本,由于asterisk的版本发布计划作了重大调整,下文将专门针对asterisk的版本规划作出说明,一旦选定asterisk版本,原则上将不再进行除了官方bugfix之外的版本同步更新; 
1.1 常规功能 
1.1.1 AMI改进(Asterisk Manager Interface )

Asterisk通过开放一个TCP端口(自1.2版本),提供了让外部程序管理asterisk配置及与运行时数据交互的能力,而在1.4版本时,更为了顺应流行的Ajax在线web应用的实时交互,提供了基于http协议的AJAM(Aynchronous Javascript Asterisk Manager)管理接口(并在此基础上提供了内建的简易web服务器及Aster GUI),在最新1.6版本中,基本包括了读写asterisk配置、与后台CLI一样执行各种管理命令查看系统运行时状态及通话中通道的实时查看能力、甚至是呼叫的建立撤销转移等高级呼叫功能,配合优秀的web 2.0 应用设计,几乎能对asterisk的一切进行管理,特别适用于基于Asterisk的各种CRM开发或各种呼叫中心的类C/S方式的实时交互式管理;

自1.6版本,AMI提供了SSL加密管理接口,但一般仍只开放本地访问权限,如直接使用本地Web Server的PHP程序访问本地的AMI接口进行管理;

更多介绍请参阅:http://www.voip-info.org/tiki-index.php?page=Asterisk%20config%20manager.conf

另外,类似Asterisk的AGI接口有众多C、PHP等开发的第三方开发库一样,AMI也有第三方增强,如AstManProxy,提供性能优秀的AMI管理操作的中转(例如在一台专用的管理服务器上,集中管理多台Asterisk服务器),并对AMI管理命令进行了封装简化以及增加了部分适应Web应用的功能增强,可通过简单的HTTP Get或Post,或XML数据等进行管理交互,可能与Asterisk 1.6之后新版本存在功能的重复,但仍是一个优秀的第三方,特别是大量Asterisk的集中管理时或不想让Asterisk服务器对外直接开放管理端口时更为有用,详参:http://www.mattgwatson.ca/2008/06/howto-install-and-configure-astmanproxy/ ; 
1.1.2 AGI接口

对应于AMI接口主要用管理Asterisk的配置数据和运行时数据(新版本也新增了一些用于管理实时呼叫过程中的通道的功能),AGI接口主要用于弥补Asterisk的呼叫计划extension是采用静态的配置文件管理呼叫流程,无法与外界应用交流或实现更灵活复杂的呼叫路由方式的缺陷,通过该接口,可以采用几乎任何可用的编程语言如PHP,C,Perl甚至Shell脚本来管理Asterisk的呼叫流程,来扩展Asterisk的呼叫计划的能力(而不是仅限于使用现有的Extension的匹配规则和内置函数来完成一些功能);

AGI可以看作是将Extension管理的呼叫导入外部程序,由外部程序来管理该呼叫的流程,同时外部程序也可以调用Extension原有可用的Asterisk内建函数,以达到内外交流配合实现复杂的呼叫逻辑,特别适合呼叫由外部数据进行动态管理的应用场景,如中继网关平台;

AGI一般直接由Extension使用agi函数启动,其形态又可分为标准AGI,DeadAGI(一般用于extension的'h'动作后媒体通道释放后使用,此时AGI不可用),FastAGI(通过TCP传输的远程AGI实现,可将本地AGI的执行放到远端另一台主机上实现类似本机AGI的操作,多用于负载平衡和集中呼叫路由管理),EAGI(增强型的AGI,较AGI增加了媒体的管理功能)和1.6版本新引入的AsyncAGI(异步模式,新引入,暂无详细介绍,可能将解决目前AGI阻塞式执行的功能限制); 
1.1.3 Realtime Architecture模式(ARA)

Asterisk可以将配置存入数据库中(支持ODBC,Mysql等多种形式,这里使用MySql),因为可以直接读写数据库配置Asterisk而不是修改平板格式的*.conf文本文件,特别对于外部界面来管理Asterisk运行时,将更为方便可靠,将该模式称之为ARA Static模式,只需要/etc/asterisk/extconfig.conf 中,加入类似

[settings] 
<conf filename> => <driver>,<databasename>[,table_name] 
sip.conf => mysql,asterisk

即可将sip.conf的配置文件转到Mysql的名为asterisk的数据库名为sip(可以指定其它表名)的表中保存,Asterisk仍在加载或重载chan_sip.so模块时,自动去数据库asterisk->sip表中读取,其数据表结构一般为:

CREATE TABLE `ast_config` ( 
`id` int(11) NOT NULL auto_increment, 
`cat_metric` int(11) NOT NULL default '0', 
`var_metric` int(11) NOT NULL default '0', 
`commented` int(11) NOT NULL default '0', 
`filename` varchar(128) NOT NULL default '', 
`category` varchar(128) NOT NULL default 'default', 
`var_name` varchar(128) NOT NULL default '', 
`var_val` varchar(128) NOT NULL default '', 
PRIMARY KEY (`id`), 
KEY `filename_comment` (`filename`,`commented`) 
) TYPE=MyISAM;

即,id和commented作为主索引由asterisk自动管理,cat_metric和var_metric分别表示配置段和参数编号,例如第三配置段第二个参数值 分别为2、1,filename表示对应的配置文件名,category则是配置段名,var_name,var_val则是参数名和参数值,一般和配置文件一一对应;

上述功能只是将配置数据从文本文件转移到数据库,修改数据库后仍需重载相关模块来应用修改,似乎没有提供更多的特性没有实现真正的Realtime,所以还有一种称为ARA RealTime的模式则是真正的实时,它不象上述的ARA Static模式是一个配置文件与一个数据表对应的,而是一个ARA功能特性(即支持实时加载的功能模块或函数等,例如SIP账号,呼叫计划等)对应一个数据表,例如,sippeers对应一个表,sipusers对应一个表,呼叫计划又对应一个表(而不是sippeers,sipusers都是与sip.conf相关就放在一起),而每个表根据不同版本的Asterisk对应字段也不一样,每个功能的表结构当然也不象ARA Static模式时是一样的,但原则上是与对应的功能在各自配置文件中原有的配置段中的字段一一对应,例如sipusers,它的表字段就是sip.conf文件的具体sip账号配置时,该sip账号所要用到的所有参数字段,而也因些其数据表结构也相当复杂,需要查询官方文档得知当前版本Asterisk相关Realtime功能对应的配置文件的指定配置段的指定参数列表方可定义数据库表结构,否则将导致相关模块不能正常应用(而Static模式时数据库表字段错误将导致模块不能加载或Asterisk不能正常启动),不同的Realtime功能特性有不同的Asterisk模块管理,目前主要有app_realtime.so,func_realtime.so和pbx_realtime.so,需要在module.conf里正确加载上述模块才能正常使用所有ARA Realtime功能;

主要的ARA Realtime特性功能有:SIP(包括peers和users分别对应不同的需求,数据表可以合用但最好分开以免混淆)、IAX、H323,VoiceMail,Queue,LDAP,Extensions,Meetme,一般都是实时呼叫时关联的原各自静态*.conf配置文件中的配置段,可以从原来手工修改配置文件实现相关功能时的经验转移至Realtime的应用中来,结合AGI将使呼叫和路由组织更加灵活和方便;

注意:由于Realtime模式时,Asterisk不再在启动过程中解析*.conf文件将其中的配置数据保存在内存中,而是变成实时去查询数据库,对于某些操作,由于数据库的查询不如内存查询高效,会导致操作缓慢,特别是ARA Realtime模式的功能特性一般都是用于呼叫实时进行过程中的,所以例如extensions的ARA Realtime功能启用时,当存在大量通配符格式的呼叫计划时,又同时有大量呼叫进入时,将导致所有呼叫的呼叫计划查询匹配过程变得非常缓慢,这类数据最好不要存入数据库而是保存在extension.conf中或保存在static模式的数据表中,Asterisk可以同时加载Static和Realtime数据,包括一并加载配置文件--但要注意防止 冲突; 
1.1.4 其它更新

CLI控制台变更

较多的命令有所变更,基本上统一为"模块+命令+参数"的格式,可能会影响到原有的AGI程序的接口名称或参数;

SIP 传真T.38 passthrough支持;

Jabber协议的内建(主要是可支持与Google Talk等一批使用开放标准的Jabber协议的IM互通,支持GTalk的呼叫处理);

编译方式采用类似Linux内核的交互式菜单选择模式,能更细化功能裁剪;

内建Radius支持更方便计费系统;

SNMP网管协议支持;

MusicOnHold支持改进;

Zaptel驱动改为DADHI驱动,内建ISDN PRI和SS7(仅ISUP)支持(libpri、libss7);

基于HTTP协议的管理接口,内建简单Web服务器,其中1.6版本进一步增强,支持SSL及JSON格式的数据交互格式,更加方便AJAX应用(AMI中详述);

支持在CLI或AMI等管理接口中,将任意两条活动的通话连接通道进行Bridge

SIP的MWI支持(应该只适用于Asterisk的SIP分机的支持,与Asterisk内建的VM绑定);

SIP Video的支持改进(可能能更好支持Asterisk的SIP终端的视频通话);

大幅提高SIP性能和资源占用(官方说明是50%,可能特指Asterisk的SIP账号,当然,对VOIP Trunk功能的资源占用降低也是有好处的);

大量删除和增加App以及Dialplan函数

我们尽量使用AGI或AMI进行呼叫的路由处理,一般不直接使用Asterisk的Dialplan,但新提供的一些函数仍在某些情况下比较有用,例如,DEVSTATE 可获取目标的状态,而不必等待Dial返回后才能知道目标的状态,而AGI中,一般也可直接使用Dialplan函数或App,故需检查原AGI程序与新的App及Dialplan函数的兼容;

支持按国家地区定制的语音合成逻辑,如时间日期的播报方式; 
1.2 asterisk版本路线

Asterisk从1.6开始执行新的版本发布规划,其主要意思就是,不再以年为单位发布添加了新功能的新版本,例如 1.8,而是每隔几月就发布一个1.6.x版本,其中包含有新的功能,并持续进行稳定,如果有新功能加入,就会新增加1.6.x+1版本,在后继几个月里再次发布新版本,即类似如下的发布规划:

? asterisk/branches 
- asterisk/branches/1.2 
- asterisk/branches/1.4 
- asterisk/branches/1.6.0 
- asterisk/branches/1.6.1 
- asterisk/branches/1.6.2

故,在选用新的Asterisk版本时,可选取符合需求列表的版本,并能尽快得到其稳定版本,而不必再等待以年为单位的时间等待发布稳定的版本; 
1.3 E1及硬件驱动方式

1.6版本去除了zaptel的支持而改用新的DAHDI驱动方式,硬件配置文件使用/etc/dahdi/system.conf ,软件驱动则libpri和libss7可以共存,分别使用不同模块,使用同一个信令配置文件/etc/asterisk/dahdi-channels.conf 配置,产品化后,配置方式考虑采用:

出厂时,根据预装硬件,手工配置好system.conf(硬件端口),界面则仅配置常用具体信令的参数,如libpri时终端类型,libss7的opc、dpc等;

使用dahdi_cfg -vvvvv进行端口配置;

使用/etc/dahdi/modules进行需要的加载模块配置,加载参数在/etc/modprobe.d/dahdi中附加,例如,启用e1还是t1模式;

dahdi_tool查看当前E1卡硬件状态,dahdi_scan则是看当前生效的E1配置参数,dahdi_monitor进行当前通话监控;

Astreisk使用E1卡的软件配置文件为:/etc/asterisk/chan_dahdi.conf

硬件端口配置方式为:

span=1,1,0,ccs,hdb3,crc4

span=2,2,0ccs,hdb3,crc4

bchan=1-15,17-31

dchan=16

PRI配置(E1 30 B+D):

switchtype=euroidsn

signalling=pri_net

context=E1_SPAN1

channel=>1-15,17-31

context=E1_SPAN2

channel=>32-46,48-62

SS7配置:

ss7type=itu [ansi]

ss7_called_nai=national

ss7_calling_nai=dynamic

linkset=1

pointcode=1 [xxx-xxx-xxx] #opc

adjpointcode=2 #dpc

defaultdpc=3 #dpc??

cidbeginswith=1

networkindicator=national

sigchan=16

channel=1-15,17-31 
1.4 编译安装 
1.4.1 SER+RTPproxy

tar zxvf rtpproxy.tgz

make;make install

mkdir /etc/asterisk

配置文件路径在:/etc/asterisk/rtp.conf

unzip ser_096_mbstudio.zip

可能安装时漏装了mysql的开发库,需要手动安装:

rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY*

yum install mysql-devel.i386

由于源码中已做配置,可直接编译,主要是模块的选择,尤其是mysql要加入;

make proper;make install

配置文件在:/usr/local/etc/ser/ser.cfg

可创建链接方便管理:ln /usr/local/etc/ser/ser.cfg /etc/ser.cfg

修改配置文件,配置正确的数据库名及nathelper以正确使用rtpproxy进行私网穿透服务;

数据库创建:

[root@localhost ser]# ser_mysql.sh create

MySql password for root:

Domain (realm) for the default user 'admin': localhost

添加账号:

mysql> insert into subscriber(phplib_id, username, domain, password, last_name, datetime_created , ha1) values(md5(now()), 1000, 'localhost', '1000', '1000', now(), md5('1000'));

删除账号时,除删除本记录外,可能由于该账号在线,还需删除location表中对应username为该账号的记录,同时也能从该表中获取账号的在线注册信息; 
1.4.2 Asterisk+DADHI+libPRI+libSS7

tar zxvf dahdi-linux-2.2.0.2.tar.gz

make && make install

tar zxvf dahdi-tools-2.2.0.tar.gz

./configure

make menuselect (弹出菜单选择需要的功能项,一般可直接保存退出)

make && make install

make config (配置启动项及服务)

原zaptel.conf被换成/etc/dahdi/system.conf ,硬件端口配置方法类似;

原zttool换成dahdi_tool ,同时也新增许多方便管理的新工具dahdi_cfg,dahdi_genconf,dahdi_monitor,dahdi_hardware,dahdi_scan,dahdi_test,dahdi_speed,dahdi_registration;

tar zxvf libpri-1.4.10.1.tar.gz

make && make install

tar zxvf libss7-1.0.2.tar.gz

make;make install

tar zxvf asterisk-1.6.1.6.tar.gz

./configure

make menuselect

make; make install

make samples

添加mysql支持(包括cdr,realtime等功能对msyql数据库的支持):

tar zxvf asterisk-addons-1.6.1.1.tar.gz

./configure

make menuselect (只选择mysql支持)

make;make install

注册服务:

cp contrib/init.d/rc.redhat.asterisk /etc/init.d/asterisk

chkconfig --add asterisk 自启动

service asterisk start

……………………

…………………… 
1.1 Asterisk配置数据库化

修改/etc/asterisk/module.conf启用Realtime:

preload => res_config_mysql.so

修改/etc/asterisk/extconfig.conf启用常用配置的数据库化:

sip.conf => mysql,general,ast_config

extensions.conf => mysql,general,ast_config

*注意,此处的general是指在res_mysql中数据库连接配置段名,它描述了一个数据库的连接;

启用cdr和mysql的realtime连接:

/etc/asterisk/res_mysql.conf :

[general]

dbhost = localhost

dbname = ser

dbuser = mbstudio

dbpass = mbstudio

dbport = 3306

sock=/var/lib/mysql/mysql.sock

/etc/asterisk/cdr_mysql.conf:

[global]

hostname=localhost

dbname=ser

table=cdr

password=mbstudio

user=mbstudio

port=3306

sock=/var/lib/mysql/mysql.sock

静态配置数据表,结构一样,可以放在同一数据表中,以filename即原配置文件名作为区别:

CREATE TABLE `ast_config` (

`id` int(11) NOT NULL auto_increment,

`cat_metric` int(11) NOT NULL default '0',

`var_metric` int(11) NOT NULL default '0',

`commented` int(11) NOT NULL default '1',

注意,可能是Asterisk Bug,文档描述该值为0时启用,但实际试验发现为1时启用,0为注释掉;

`filename` varchar(128) NOT NULL default '',

`category` varchar(128) NOT NULL default 'default',

`var_name` varchar(128) NOT NULL default '',

`var_val` varchar(128) NOT NULL default '',

PRIMARY KEY (`id`),

KEY `filename_comment` (`filename`,`commented`)

)

计费数据表:

CREATE TABLE `cdr` (

`accountcode` varchar(20) NOT NULL default '',

`src` varchar(80) NOT NULL default '',

`dst` varchar(80) NOT NULL default '',

`dcontext` varchar(80) NOT NULL default '',

`clid` varchar(80) NOT NULL default '',

`channel` varchar(80) NOT NULL default '',

`dstchannel` varchar(80) NOT NULL default '',

`lastapp` varchar(80) NOT NULL default '',

`lastdata` varchar(80) NOT NULL default '',

`calldate` datetime NOT NULL default '0000-00-00 00:00:00',

`duration` int(11) NOT NULL default '0',

`billsec` int(11) NOT NULL default '0',

`disposition` varchar(45) NOT NULL default '',

`amaflags` int(11) NOT NULL default '0',

`userfield` varchar(255) NOT NULL default '',

`sflag` tinyint(1) default '0',

KEY `dst` (`dst`),

KEY `accountcode` (`accountcode`)

)

ARA realtime sip数据表:

CREATE TABLE `ast_sip` (

`id` int(11) NOT NULL auto_increment,

`name` varchar(80) NOT NULL default '',

`host` varchar(31) NOT NULL default '',

`type` enum('user','peer','friend') NOT NULL default 'friend',

`busylevel` smallint(5) unsigned default NULL,

`context` varchar(80) default NULL,

`fromuser` varchar(80) default NULL,

`insecure` varchar(15) default NULL,

`md5secret` varchar(80) default NULL,

`secret` varchar(80) default NULL,

`port` smallint(5) unsigned NOT NULL default '0',

`defaultuser` varchar(80) NOT NULL default '',

`crypto` smallint(1) unsigned default 0,

PRIMARY KEY (`id`),

UNIQUE KEY `name` (`name`),

KEY `name_2` (`name`)

)

呼叫计划动态数据表:

CREATE TABLE `ast_ext` (

`id` int(11) NOT NULL auto_increment,

`context` varchar(20) NOT NULL default '',

`exten` varchar(20) NOT NULL default '',

`priority` tinyint(4) NOT NULL default '0',

`app` varchar(20) NOT NULL default '',

`appdata` varchar(128) NOT NULL default '',

PRIMARY KEY (`context`,`exten`,`priority`),

KEY `id` (`id`)

)

SIP.conf静态初始化数据:

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('0','0','sip.conf', 'general', 'context', 'default');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('0','1','sip.conf', 'general', 'allowoverlap', 'no');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('0','2','sip.conf', 'general', 'udpbindaddr', '0.0.0.0:5058');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('0','3','sip.conf', 'general', 'srvlookup', 'no');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('0','4','sip.conf', 'general', 'useragent', 'MBSTUDIO');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('0','5','sip.conf', 'general', 'sdpsession', 'MBSTUDIO');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('0','6','sip.conf', 'general', 'disallow', 'all');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('0','7','sip.conf', 'general', 'allow', 'g729');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('0','8','sip.conf', 'general', 'allow', 'ulaw');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('0','9','sip.conf', 'general', 'allow', 'alaw');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('0','10','sip.conf', 'general', 'dtmfmode', 'auto');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('0','11','sip.conf', 'general', 'canreinvite', 'no');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('0','12','sip.conf', 'general', 'nat', 'yes');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('0','13','sip.conf', 'general', 'usereqphone', 'yes');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('0','14','sip.conf', 'general', 'realm', 'localhost');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('0','15','sip.conf', 'general', 'rtcachefriends', 'yes');

注意:上述条目启用sip show peers的realtime缓存,但有延时,可以手动加载sip show peer PEERNAME load即可看到数据库中数据是否正确配置;

以上为sip.conf常用参数配置,如需增加voip账号,除下文的在ast_config表中增加extension.conf的呼叫上下文配置段外,还需在sip.conf中增加注册账号逻辑,如:

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name`, `var_val` ) VALUES('0', '16', 'sip.conf', 'general', 'register', '4002:4002:[email protected]/4002');

Extension.conf静态配置数据:

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('1','0','extensionsconf', 'localser', 'switch', 'Realtime');

表示为SER组网来源呼叫上下文localser启用Realtime模式,如此操作之后,只需在ast_ext表中动态添加呼叫计划,则可实时应用到呼叫计划中;

但由于我们暂时使用AGI,呼叫计划是固定的,可暂时仅使用Static模式即可;

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('0','0','extensions.conf', 'default', 'include', 'CALL_IN');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('1','0','extensions.conf', 'localser', 'include', 'CALL_IN');

其中,CALL_IN是启用AGI的入口,也是固定在ast_config中静态配置:

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('2','0','extensions.conf', 'CALL_IN', 'exten', '_X.,1,agi(call_route.php)');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('2','1','extensions.conf', 'CALL_IN', 'exten', '_X,1,agi(call_route.php)');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('2','2','extensions.conf', 'CALL_IN', 'exten', '_#.,1,agi(call_route.php)');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('2','3','extensions.conf', 'CALL_IN', 'exten', '_*.,1,agi(call_route.php)');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('2','4','extensions.conf', 'CALL_IN', 'exten', '_S.,1,agi(call_route.php)');

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('2','5','extensions.conf', 'CALL_IN', 'exten', 'h,1,Hangup()');

当增加VOIP账号或VOIP Trunk时,为接受呼入 ,也需要增加呼叫上下文,只需更改其中的category字段,注意cat_metric字段值需与其它配置段不同,可简单查询本filename下cat_metric最大值递增即可,var_metric表示配置参数在配置段中的顺序,一般需递增添加,如无冲突或优先关系,使用相同值也可,例如:

INSERT INTO `ast_config` (`cat_metric` , `var_metric` , `filename` , `category` , `var_name` , `var_val` ) VALUES ('3','0','extensions.conf', 'IP_172.21.55.55', 'include', 'CALL_IN');

注意:上述操作均是ARA的Static模式,需要重载配置,此处可用dialplan reload或直接reload全部;

可使用dialplan show查看当前的活动呼叫计划数据;

VOIP账号或Trunk动态数据:

注意:新增或删除VOIP账号或Trunk时,需同步在ast_config中增加呼叫计划extension.conf相关的上下文(需检查该VOIP_XXX.XXX.XXX.XXX或IP_XXX.XXX.XXX.XX是否已经存在,删除时需检查是否仍有使用该地址作为呼叫上下文的SIPPEER存在于ast_sip表中);

INSERT INTO `ast_sip` (`name`, `host`, `type`, `context`, `insecure`) VALUES('ser', '172.21.33.166', 'peer', 'localser', 'port'); **注意在本机IP地址更改时也需更新本数据,否则本地星型组网来源Trunk呼叫不能正常路由;

该记录是用于本地SER星型组网来源的特殊VOIP Trunk地址,其它VOIP账号或IP Trunk配置规范详细描述见设计文档,以下分别为VOIP账号和IP Trunk的配置数据;

INSERT INTO `ast_sip` (`name`, `host`, `type`, `port`, `defaultuser`, `fromuser`, `secret`, `busylevel`, `insecure`, `context`) VALUES('SRV_1001_172.21.33.166', '172.21.33.166', 'friend', '5060', '1002', '1002', '1002', 'no', invite', 'VOIP_172.21.33.166'); 本记录用于VOIP账号的呼入和呼出时使用;

INSERT INTO `ast_sip` (`name`, `host`, `type`, `port`, `context`, `busylevel`, `crypto`) VALUES('IPTRNK_172.21.55.55', '172.21.55.55', 'peer', '8060', 'IP_172.21.55.55', 'no', '1'); 本记录用于IP Trunk的呼入和呼出使用;

AGI 路由呼叫本地时,呼叫格式为:

dial(SIP/1000@ser) ,故更改IP地址和SER端口时,需更新ast_config中本地特殊trunk的端口和地址;

通过IP Trunk呼出时,格式为1190@IPTRNK_172.21.55.55,其中IPTRNK_172.21.55.55表示一个地址为172.21.55.55的IP Trunk;

呼入时,呼叫计划上下文为IP_172.21.55.55 ;

通过VOIP账号呼出时,格式为dial(SIP/4000@VOIP_4002_172.21.33.133),其中VOIP_4002_172.21.33.133分别表示使用172.21.33.133上的4002账号呼出;

呼入时,呼叫计划上下文为VOIP_172.21.33.133 ;

注意:修改ast_sip即定义VOIP账号或IP Trunk是实时生效的,而如果是添加或删除操作,则需同步更新ast_config中呼叫上下文(注意同一呼叫上下文被多个VOIP账号使用时的情况),且需执行dialplan reload重载呼叫计划;

IP Trunk呼入,通过VOIP账号,IP Trunk或本地SER账号出,测试通过;

VOIP账号呼入,通过IP Trunk,另一VOIP账号或本地SER账号出,测试通过;

本地SER账号通过特殊Trunk呼入,通过IP Trunk或VOIP账号呼出测试通过;

E1暂无测试环境,未测试;

** 由于新版本路由时实现方式及匹配字段查询数据方式有变,原有路由数据的配置页面及数据结构已不适用,且原AGI开发库已停止开发与新版本asterisk 1.6也存在兼容性问题,故需根据新的路由实现方式重新规划路由数据结构定义并对AGI开发库作补丁更新;

且数据库中本地特殊Trunk由于必须包含本机的IP地址(SER的账号呼叫时始终使用其WAN口IP,故传入Asterisk时不可能使用localhost进行匹配),对于使用MySQL进行多台设备进行热备份同步数据时,可能会造成困扰,需进一步研究解决方法,例如,将其与匿名特殊Trunk呼入一并归入同一处理逻辑,但通过其它只有本地Trunk来源呼叫时才带有的特殊字段参数进行区分;

全部测试用数据表如下:

mysql> select * from ast_sip; 
+----+-------------------------+---------------+--------+-----------+--------------------+----------+----------+-----------+--------+------+-------------+--------+

| id | name | host | type | busylevel | context | fromuser | insecure | md5secret | secret | port | defaultuser | crypto |

+----+-------------------------+---------------+--------+-----------+--------------------+----------+----------+-----------+--------+------+-------------+--------+

| 1 | VOIP_4002_172.21.33.133 | 172.21.33.133 | friend | NULL | VOIP_172.21.33.133 | 4002 | invite | NULL | mbstudio | 8060 | 4002 | 0 |

| 3 | ser | 172.21.33.166 | peer | 0 | localser | NULL | port | NULL | NULL | 5060 | | 0 |

| 4 | IPTRNK_172.21.55.55 | 172.21.55.55 | peer | 0 | IP_172.21.55.55 | NULL | NULL | NULL | NULL | 8060 | | 1 |

+----+-------------------------+---------------+--------+-----------+--------------------+----------+----------+-----------+--------+------+-------------+--------+

mysql> select * from ast_config;

+----+------------+------------+-----------+-----------------+--------------------+----------------+----------------------------------------------+

| id | cat_metric | var_metric | commented | filename | category | var_name | var_val |

+----+------------+------------+-----------+-----------------+--------------------+----------------+----------------------------------------------+

| 1 | 0 | 0 | 1 | sip.conf | general | context | default |

| 2 | 0 | 1 | 1 | sip.conf | general | allowoverlap | no |

| 3 | 0 | 2 | 1 | sip.conf | general | udpbindaddr | 0.0.0.0:6060 |

| 4 | 0 | 3 | 1 | sip.conf | general | srvlookup | no |

| 5 | 0 | 4 | 1 | sip.conf | general | useragent | MBSTUDIO|

| 6 | 0 | 5 | 1 | sip.conf | general | sdpsession | MBSTUDIO |

| 7 | 0 | 6 | 1 | sip.conf | general | disallow | all |

| 8 | 0 | 7 | 1 | sip.conf | general | allow | g729 |

| 9 | 0 | 8 | 1 | sip.conf | general | allow | ulaw |

| 10 | 0 | 9 | 1 | sip.conf | general | allow | alaw |

| 11 | 0 | 10 | 1 | sip.conf | general | dtmfmode | auto |

| 12 | 0 | 11 | 1 | sip.conf | general | canreinvite | no |

| 13 | 0 | 12 | 1 | sip.conf | general | nat | yes |

| 14 | 0 | 13 | 1 | sip.conf | general | usereqphone | yes |

| 15 | 0 | 14 | 1 | sip.conf | general | realm | localhost |

| 26 | 0 | 0 | 1 | extensions.conf | default | include | CALL_IN |

| 27 | 1 | 0 | 1 | extensions.conf | localser | exten | _X.,1,dial(SIP/4000@VOIP_4002_172.21.33.133) |

| 28 | 2 | 0 | 1 | extensions.conf | CALL_IN | exten | _X.,1,agi(call_route.php) |

| 31 | 2 | 0 | 1 | extensions.conf | CALL_IN | exten | _*.,1,agi(call_route.php) |

| 30 | 2 | 0 | 1 | extensions.conf | CALL_IN | exten | _#.,1,agi(call_route.php) |

| 29 | 2 | 0 | 1 | extensions.conf | CALL_IN | exten | _X,1,agi(call_route.php) |

| 32 | 2 | 0 | 1 | extensions.conf | CALL_IN | exten | _S.,1,agi(call_route.php) |

| 33 | 2 | 0 | 1 | extensions.conf | CALL_IN | exten | h,1,Hangup() |

| 34 | 0 | 16 | 1 | sip.conf | general | register | 4002:mbstudio:[email protected]:8060/4002 |

| 35 | 0 | 15 | 1 | sip.conf | general | rtcachefriends | yes |

| 36 | 2 | 0 | 1 | extensions.conf | VOIP_172.21.33.133 | exten | _X.,1,dial(SIP/1190@IPTRNK_172.21.55.55) |

| 37 | 3 | 0 | 1 | extensions.conf | IP_172.21.55.55 | exten | _X.,1,dial(SIP/1000@ser) |

+----+------------+------------+-----------+-----------------+--------------------+----------------+----------------------------------------------+ 
1.2 Asterisk AMI接口

tar zxvf asterisk-gui-2.0.4.tar.gz

./configure

make; make install

修改/etc/asterisk/http.conf:

[general]

enabled = yes

bindaddr=127.0.0.1 #只允许本地Apache的PHP管理系统调用Asterisk的Http管理接口进行管理,测试时屏蔽即可;

enablestatic = yes #启用static管理界面,内置的很容易管理界面,可以修改HTML源码扩展或美化功能,代码在 /var/lib/asterisk/static-http/config下

访问http://172.21.33.166:8088/static/index.html即进入内置管理界面,其它http根据应用环境不同,使用不同入口进入,如manager,httpstatus,rawman,mxml,static等;

通过http://172.21.33.166:8088/manager?action=login&action=&command=&username=admin&secret=admin可以试验各种管理命令,而rawman则是以纯文本方式返回,mxml是以xml结构返回,其输入输出值与manager接口一致;

另有AJAM管理接口,主要是用于基于Web的呼叫实时管理时使用,可以实时刷新当前Asterisk系统中活动的呼叫Channel并进行Tranfer或挂断等操作,其Demo程序在http://172.21.33.166:8088/static/ajamdemo.html;

修改/etc/asterisk/manager.conf:

[general]

enabled = yes

webenabled = yes

bindaddr = 127.0.0.1 #只允许本地web管理服务使用AMI接口

[admin] #表示创建admin账号

secret = mbstudiopwd #密码

;deny=0.0.0.0/0.0.0.0 #表示管理来源,只需要本地管理,试验时需要远程管理

;permit=209.16.236.73/255.255.255.0

read = system,call,log,verbose,command,agent,config

write = system,call,log,verbose,command,agent,config

#在Asterisk控制台执行localhost*CLI> manager show commands 可以查看可用的命令;

应用举例:

功能描述

Action

Username

Secret

登录管理

login

admin

admin

功能描述

Action

Command

控制台管理命令:

能在后台执行的命令均可通过本方式执行;

可以通过在界面接受命令执行并返回实现一个基于Web的Asterisk管理控制 台;

command

dialplan reload :

重载呼叫计划

module reload chan_sip.so: 
重载sip模块

…………

功能描述

Action

channel

context

exten

Callerid

Priority

主动接通本地组网分机后呼叫出网

Originate

SIP/1000@ser

localser

94000

1000

1

主动接通外部终端后呼叫本地ser组网分机

Originate

SIP/1190@IPTRNK_172.21.55.55

IP_172.21.55.55

1000

1190

1

功能描述

Action

peer

查看外部SIP账号注册状态;

SIPshowregistry

查看SIP终端,如IP Trunk;

SIPpeers

查看具体SIP终端的参数;

SIPshowpeer

peername,例如ser

功能描述

Action

Filename

获取某配置文件数据

GetConfig

Sip.conf,extensions.conf,……

支持realtime

注意:当某AMI命令返回不是Success或Failure而是Follow时,表示命令已提交但未执行完,需在稍候发磅action:waitevent来查询事件,判断是否已执行完成及执行结果,在呼叫过程中,AGI程序或Dialplan也可在特定条件下发送自定义Event,该特性的使用,一般需结合Ajax应用异步应用实现时才有意义,可参考Asterisk自带的AJAM demo程序,使用astman.js开发库进行自定义应用的开发;

猜你喜欢

转载自coolwhy1.iteye.com/blog/1428058