第4章Asterisk的基本配置
摘錄<<Asterisk.The.Future.of.Telephony>>
先探討對(duì)模擬接口如FXS和FXO端口的基本配置.然后配置兩個(gè)VoIP接口:一個(gè)連接軟電話的本地SIP通道,一個(gè)通過(guò)Asterisk內(nèi)部協(xié)議(Inter-eXchange protocol IAX)連接全球免費(fèi)通信(Free World Dialup).
4.1 我到底需要什么
Asterisk可以連接的數(shù)目龐大的接口類型,包括:
模擬接口,如你的電話線(FXS)和模擬電話(FXO)
數(shù)字線路,如T-1和E-1線路
VoIP協(xié)議如SIP和IAX
4.2 使用接口配置文件
注意,這種硬件接口不是必須的,如果你想建立一個(gè)純IP的配置,你可以跳到SIP配置的章節(jié).
配置文件如下:
zaptel.conf
做硬件接口的基層配置.我們將建立一個(gè)FXO和一個(gè)FXS通道.
zapata.conf
為硬件配置Asterisk的接口.
extensions.conf
創(chuàng)建的撥號(hào)方案會(huì)比較粗糙,但是將證明系統(tǒng)可用.
sip.conf
配置SIP協(xié)議的文件.
iax.conf
配置呼入和呼出IAX通道的文件.
以下章節(jié)中,將編輯幾個(gè)配置文件,并且將這些文件裝載到你的交換機(jī)上,使它們生效.編輯完zaptel.conf文件,需要使用/sbin/ztcfg-vv裝載配置到硬件.然而,改變信令方法需要重啟.在編輯iax.conf和sip.conf文檔后,分別需要裝載chan_iax2.so和chan_sip.so
4.3 FXO和FXS通道
FXO和FXS通道的區(qū)別簡(jiǎn)單,就在于連接的哪端提供撥號(hào)音.FXO端口不生成撥號(hào)音,而是接受.通常的例子是撥號(hào)音由你的電話公司提供.
FXS端口提供撥號(hào)音和震鈴電壓,在有呼入的時(shí)候提醒用戶.兩種接口都提供雙向通訊.
如果你的Asterisk服務(wù)器有一個(gè)兼容的FXO端口,你可以把你的電話公司的電話線插入這個(gè)端口.Asterisk可以使用這根電話線呼出和接受電話呼叫(我的理解,此時(shí)的Asterisk服務(wù)器相當(dāng)于電信公司的一部電話終端).同理,如果你的Asterisk服務(wù)器有一個(gè)兼容的FXS端口,你可以連接一部模擬電話,Asterisk就可以呼叫這部電話,同時(shí)你也可以進(jìn)行呼叫(我的理解,此時(shí)的Asterisk服務(wù)器相當(dāng)于電信公司的程控交換機(jī)).
端口是通過(guò)配置使用的信令進(jìn)行定義的,而不會(huì)是物理端口類型.例如,一個(gè)物理的FXO(FXS)端口可以在配置中使用FXS(FXO)信令定義.FX_板卡不是通過(guò)他們是什么進(jìn)行命名,而是根據(jù)他們連接的設(shè)備進(jìn)行命名.因此FXS卡,是連接終端的,為了做它的工作,FXS卡必須像中心局(CO)進(jìn)行運(yùn)轉(zhuǎn),使用FXO信令.同理,FXO卡連接CO,意味著它需要像終端那樣進(jìn)行運(yùn)轉(zhuǎn),使用FXS信令.
在你的TDM400p上決定FXO和FXS端口
模塊1是綠色的FXS模塊,模塊2是橙紅色的FXO模塊,右下角是Molex連接器,從這里利用電腦提供電源.
注意,插入一個(gè)FXS端口(綠色模塊)到PSTN會(huì)損壞模塊和板卡.如果你有FXS模塊,一定要將你電腦的電源連接到TDM400P的Molex連接器,用于生成電話震鈴的電壓.如果你只有FXO模塊,那么不要求有Molex連接器.
4.4 配置FXO通道
Zaptel硬件配置
Zapata硬件配置
Dialplan配置
4.5 配置FXS通道
Zaptel硬件配置
Zapata硬件配置
Dialplan配置
4.6 SIP配置
會(huì)話初始協(xié)議(SIP),通常用于VoIP電話(硬件電話或者軟電話),進(jìn)行呼叫建立和呼叫結(jié)束,和呼叫進(jìn)程中的協(xié)商.基本上,它幫助兩個(gè)端點(diǎn)互相通話.SIP不處理媒體,當(dāng)呼叫建立后,它通過(guò)實(shí)時(shí)傳輸協(xié)議(RTP)在電話A和電話B之間直接傳輸媒體.
SIP和RTP
SIP是一個(gè)應(yīng)用層的信令協(xié)議,使用眾所周知的5060端口進(jìn)行通信.SIP可以通過(guò)UDP或者TCP傳輸層協(xié)議進(jìn)行傳輸.
RTP用于在端點(diǎn)之間傳輸媒體(例如語(yǔ)音).Asterisk中RPT使用大數(shù)字的無(wú)特權(quán)的端口(默認(rèn)是10,000到20,000).
SIP配置
下面是基本的sip.conf文件:
[general]
context=default
srvlookup=yes
[tim]
type=friend
secret=welcome
qualify=yes ;Qualify peer is no more than 2000 ms away
nat=no ;this phone is not natted
host=dynamic ;this device registers with us
canreinvite=no ;Asterisk by default tries to redirect
context=internal ;the internal context controls what we cando
sip.conf文件開始是一個(gè)[general]section,包含通道設(shè)置,所有用戶和對(duì)端的默認(rèn)選項(xiàng).在一個(gè)端-用戶/端的基礎(chǔ)上,可以不考慮默認(rèn)的配置,而在user/peer定義中重新進(jìn)行配置.
域名系統(tǒng)服務(wù)記錄(DNS SRV records)是建立一個(gè)邏輯和可解析地址的方法,你可以到達(dá)這個(gè)地址.這種方法可以是呼叫傳輸?shù)讲煌牡攸c(diǎn),而不需要改變邏輯地址.使用SRV記錄,你可以獲取DNS的很多好處,然而禁止它們打破SIPRFC的規(guī)定,而且禁止了基于域名的SIP呼叫.(注意如果多個(gè)記錄返回,Asterisk只會(huì)使用第一個(gè)).
DNS SRV記錄查詢?cè)贏sterisk默認(rèn)禁止,但是強(qiáng)烈建議你打開.啟動(dòng)使用sip.conf中[general]section里面的srvlookup=yes.
每個(gè)連接都會(huì)定義為用戶,端或者朋友.用戶類型是用于認(rèn)證呼入呼叫.端類型用于呼出呼叫.朋友類型兩種都用.擴(kuò)展名用中括號(hào)定義([]).本例中我們已經(jīng)定義了一個(gè)端點(diǎn)為朋友.
Secret是用于認(rèn)證的密碼.我們的secret是welcome.我們可以監(jiān)視Asterisk服務(wù)器和電話之間的延時(shí),使用qualify=yes,確認(rèn)遠(yuǎn)端設(shè)備是否可達(dá).可以用于監(jiān)視任何遠(yuǎn)端設(shè)備,包括其他的Asterisk服務(wù)器.默認(rèn)情況是Asterisk認(rèn)為時(shí)延在2,000ms(2 seconds)以內(nèi)的設(shè)備可達(dá),你可以配置Asterisk判斷對(duì)端是否可達(dá)的時(shí)間,通過(guò)將yes替換為毫秒.
如果一個(gè)號(hào)碼的網(wǎng)絡(luò)地址翻譯(NAT)設(shè)備后面,例如路由器或者防火墻,配置nat=yes,強(qiáng)迫Asterisk忽略號(hào)碼的聯(lián)系信息,使用收到的包的地址信息.
設(shè)置host=dynamic將要求號(hào)碼注冊(cè),以便Asterisk可以知道如何找到電話.將一個(gè)端點(diǎn)綁定到一個(gè)單獨(dú)地址或者fully qualified domain name(FQDN),將dynamic替換IP地址或者域名.注意這只是限制你呼叫的目的地址,用戶允許從任何地點(diǎn)發(fā)起呼叫(假定它成功鑒權(quán)).如果你設(shè)置host=static,則終端設(shè)備不需要注冊(cè).
我們已經(jīng)設(shè)置了canreinvite=no.在SIP協(xié)議,邀請(qǐng)用于發(fā)起呼叫,重定向媒體.在初始邀請(qǐng)后相同對(duì)話中發(fā)起的任何邀請(qǐng)都被視作重邀請(qǐng)(reinvite).例如,假設(shè)雙方正在交換媒體信息,如果一方呼叫等待,Asterisk設(shè)置為播放呼叫等待音樂(lè),Asterisk會(huì)發(fā)起到第二個(gè)客戶端的重邀請(qǐng),告訴將他的媒體流定向到PBX,然后就開始傳輸音樂(lè)流,或者一個(gè)等待客戶的通知.
最開始的用戶再到PBX的重邀請(qǐng)中發(fā)起一個(gè)摘機(jī)的命令,然后PBX發(fā)起一個(gè)重邀請(qǐng)到第二方,要求它將媒體流重新定向到發(fā)起方,結(jié)束呼叫等待音樂(lè),重新連接客戶端.
通常,當(dāng)兩個(gè)端點(diǎn)建立起呼叫,他們直接從一端到另一端傳輸媒體.Asterisk通常在媒體通道打破這個(gè)規(guī)則,允許它聽到電話鍵盤上的撥號(hào)音.這是必須的,因?yàn)槿绻鸄sterisk不能確定呼叫長(zhǎng)度,計(jì)費(fèi)將不準(zhǔn)確.配置canreinvite=no讓Asterisk媒體通道經(jīng)過(guò)自己,而不允許RTP信息直接在端點(diǎn)之間傳送.
Asterisk在以下的任何情況下都不會(huì)發(fā)起重邀請(qǐng):
如果客戶端的任何一方配置為canreinvite=no;
如果客戶端不能協(xié)商編碼,Asterisk需要執(zhí)行語(yǔ)音編碼轉(zhuǎn)換;
如果客戶端的任何一方配置為 nat=yes;
如果Asterisk在呼叫中需要監(jiān)聽雙音多頻(DTMF)音(用于呼叫前轉(zhuǎn)或者其他功能).
最后context=internal定義了指令的地點(diǎn),用于控制電話的權(quán)限,以及如何處理此號(hào)碼的呼入呼叫.sip.conf中設(shè)置的context名稱和extensions.conf中的匹配.
如果你配置了相似的一組用戶,你可以使用相似的命令在[general]字段.Asterisk會(huì)使用默認(rèn)的定義,除非他們?cè)谟脩舻呐渲梦臋n中明確改變.
客戶端配置
下載軟電話X-ten的X-Lite客戶端 http://www.xten.com,配置客戶端.最重要的是注冊(cè)的用戶名和密碼,和你要注冊(cè)的Asterisk服務(wù)器的地址.
出現(xiàn)的問(wèn)題:
(1) X-ten提示login timedout.但是網(wǎng)絡(luò)正常,進(jìn)行本機(jī)呼叫.
解決:
不能設(shè)置成環(huán)回地址127.0.0.1
(2)CVsSocket::AsyncSend:sendfailed:拒絕連接,但是x-ten運(yùn)行正常,可正常呼叫.
解決:
:(
(3) pbx.c:1738 pbx_extension_helper: Cannot findextension context 'internal'
解決:
在/etc/asterisk/extensions.conf文件中添加呼叫規(guī)則如下:
[internal]
exten=>100,1,Dial(SIP/tim)
exten=>611,1,Echo()
(4) NOTICE[2200]: res_musiconhold.c:507monmp3thread: Request to schedule in thepast?!?!
解決:
進(jìn)入asterisk安裝目錄,重新安裝asterisk,安裝mpg123.
# cd /usr/src/asterisk-1.2.7.1
# make clean
# make
# make mpg123
# make install
4.7 配置入局IAX連接
IAX(Inter-Asterisk eXchange)協(xié)議通常用于服務(wù)器間通信.IAX和SIP協(xié)議最大的區(qū)別在于媒體(語(yǔ)音)在端點(diǎn)之間傳輸?shù)姆绞讲煌?
SIP協(xié)議中,相對(duì)于使用信令模式來(lái)說(shuō),RTP(媒體)流使用不同的端口進(jìn)行傳輸.例如,Asterisk默認(rèn)的情況是在5060端口接收SIP信令,在10000-20000端口接收RTP(媒體)流.IAX協(xié)議則不同,所有的信令和媒體流都通過(guò)一個(gè)4569端口進(jìn)行傳輸.這種方式的好處是IAX協(xié)議能更適合在有NAT相關(guān)拓?fù)涞膽?yīng)用.
IAX用戶習(xí)慣對(duì)進(jìn)入PBX系統(tǒng)的呼叫進(jìn)行鑒權(quán)和處理.對(duì)從PBX系統(tǒng)呼出的呼叫,Asterisk應(yīng)用IAX的iax.conf文件的端點(diǎn)進(jìn)入(條目)對(duì)遠(yuǎn)端進(jìn)行鑒權(quán).
講解創(chuàng)建iax.conf和extensions.conf,使你可以接受從其它FWD(一個(gè)免費(fèi)的Voip運(yùn)營(yíng)商)用戶發(fā)出的呼叫.呼出IAX連接的章節(jié)講述如何發(fā)起呼叫.
iax.conf配置
在iax.conf文件中,段落是由方括號(hào)定義的([]).每個(gè)iax.conf文件至少需要一個(gè)主要段落:[general].在這個(gè)段落中,定義使用IAX協(xié)議的相關(guān)設(shè)置,你可以不考慮在[general]段落中默認(rèn)編碼,而在user orpeer定義中進(jìn)行設(shè)置.
略
4.9 調(diào)試
連接控制臺(tái)
直接在控制臺(tái)啟動(dòng)Asterisk:
# /usr/sbin/asterisk -c
用遠(yuǎn)程連接控制臺(tái),然后連接:
# /usr/sbin/asterisk
# /usr/sbin/asterisk -r
如果遇到某個(gè)模塊不能載入的問(wèn)題,或者某個(gè)模塊導(dǎo)致Asterisk不能載人,用-cflag啟動(dòng)Asterisk進(jìn)程,監(jiān)視模塊載人狀態(tài).
啟動(dòng)Verbosity和Debugging
Asterisk可以以WARNING,NOTICE和ERROR消息形式輸出調(diào)試信息.激活不同級(jí)別的verbosity,使用setverbose,附加一個(gè)數(shù)值.有效值從3-10,例如設(shè)置verbosity的最高數(shù)值,使用:
# set verbose 10
你也可以通過(guò)設(shè)置調(diào)試級(jí)別激活核心調(diào)試信息.激活控制臺(tái)的DEBUG輸出,需要在logger.conf文件中增加debug到console=>文段,例如:
console=>warning,notice,error,event,debug
設(shè)置調(diào)試級(jí)別的有效值為3-10,例如:
# set debug 10
第5章撥號(hào)方案基礎(chǔ)
摘錄<<Asterisk.The.Future.of.Telephony>>
撥號(hào)方案定義了Asterisk如何處理來(lái)話和去話,它由指令和步驟列表組成,Asterisk按步驟來(lái)執(zhí)行這些指令.與傳統(tǒng)電話系統(tǒng)不同,Asterisk的撥號(hào)方案是完全可定制的.
5.1 撥號(hào)方案語(yǔ)法
撥號(hào)方案在文件extensions.conf中定義.文件extensions.conf通常在/etc/asterisk/目錄下.但是其位置可以改變,取決于Asterisk的安裝方式.其它常見的位置包括/usr/local/asterisk/etc/和/opt/asterisk/etc/.
撥號(hào)方案由4部分組成:contexts,extensions,priorities和applications.
Context
Dialplans被分成幾個(gè)段,這些段稱為context.Context用來(lái)對(duì)extension的組命名.在一個(gè)context中定義的extension完全獨(dú)立于另一個(gè)context中定義的extensiont,本章末尾將介紹如何允許context之間相互交織.
Contexts的表示方法是把名字放在方括號(hào)([])的中間.這個(gè)名字可以由A-Z,數(shù)字0-9,以及連字號(hào)和下劃線組成.如:[incoming]
Extension
在每一個(gè)context內(nèi),可以定義一個(gè)或者多個(gè)extension. extension是Asterisk要執(zhí)行的指令,由來(lái)電或者通道上所撥數(shù)字來(lái)觸發(fā).
extension的語(yǔ)法是:exten=>
之后是extension的名字.在于電話系統(tǒng)打交道的時(shí)候,我們把extension看作是呼叫另一部電話所撥的號(hào)碼.在asterisk上,意味著更多的東西.
一個(gè)完整的extension由三部分組成:
Extension的名字或者號(hào)碼
Priority(每個(gè)extension可以有多個(gè)步驟,步驟的編號(hào)稱作Priority)
應(yīng)用(或者命令),針對(duì)呼叫完成一些動(dòng)作
這三個(gè)部分用英文逗號(hào)分開,如:
exten=>name,priority,application()
例如:
exten=>123,1,Answer()
在這個(gè)例子中,extension的名字是123, priority是1, 應(yīng)用是Answer().
Priority
每個(gè)extension可以有多個(gè)步驟,稱作priorities. 每個(gè)priority都按順序編號(hào),從1開始.每個(gè)priority執(zhí)行一個(gè)規(guī)定的應(yīng)用.下面給出一個(gè)例子,這個(gè)extension接聽電話(編號(hào)為1的priority),然后掛斷(編號(hào)為2的priority):
exten=>123,1,Answer()
exten=>123,2,Hangup()
注意:必須確保priority從1開始并且是連續(xù)的編號(hào).對(duì)于特定的extension,Asterisk遵從priority的數(shù)字順序.
Application
無(wú)序號(hào)的priority
在Asterisk1.2版本里,Priority編號(hào)增加了新的變化,引入了npriority,表示"下一個(gè)"的意思.每次Asterisk遇n這個(gè)priority的時(shí)候,就取出前一個(gè)priority的編號(hào)加上1.例如:
extern=>123,1,Answer()
extern=>123,n,do something
extern=>123,n,do something else
extern=>123,n,do[] one last thing
extern=>123,n,Hangup()
1.2版也允許給priority分配一個(gè)文字標(biāo)號(hào).要給priority分配文字標(biāo)號(hào),只需要在priority后面的括號(hào)內(nèi)加上這個(gè)標(biāo)號(hào),如:
extern=>123,n(label),do something
5.2 一個(gè)簡(jiǎn)單的撥號(hào)方案
我們以一個(gè)簡(jiǎn)單的例子來(lái)開始.在呼叫進(jìn)來(lái)時(shí),Asterisk應(yīng)答這個(gè)呼叫,播放聲音文件,然后掛斷,用這個(gè)簡(jiǎn)單例子來(lái)指出撥號(hào)方案基本原理.
為了工作正確,至少創(chuàng)建一個(gè)通道(Zap或Sip通道),并且作了配置.
s Extension
在著手撥號(hào)方案前,先介紹一個(gè)特別的extension,名字叫做s. 當(dāng)沒(méi)有指定extension的呼叫(例如,正在振鈴的FXO線路)進(jìn)入context的時(shí)候,就由這個(gè)sextension來(lái)處理.(s表示"start"開始,因?yàn)槎鄶?shù)的呼叫都是從sextension開始).我們要在呼叫上完成三個(gè)動(dòng)作(接聽,播放聲音文件,最后掛斷),所以要?jiǎng)?chuàng)建有三個(gè)priority的sextension. 我們把這三個(gè)priority放到[incoming]里,所有來(lái)話都應(yīng)該從這個(gè)context開始:
[incoming]
exten=>s,1,application()
exten=>s,2,application()
exten=>s,3,application()
現(xiàn)在我們所要做的事情就是填寫應(yīng)用.
Answer(),Playback()和Hangup()應(yīng)用
Answer()應(yīng)用用于接聽正在振鈴的通道,并不為接受來(lái)話的通道進(jìn)行初始化設(shè)定(確有不少應(yīng)用不需要先應(yīng)答通道,但是在完成其它動(dòng)作之前進(jìn)行適當(dāng)?shù)膽?yīng)答是一個(gè)好習(xí)慣).Answer()不需要任何參量.
Playback()應(yīng)用用于在通道上播放事先錄制好的語(yǔ)音文件.在使用Playback()應(yīng)用時(shí),系統(tǒng)不會(huì)理會(huì)來(lái)自用戶的輸入.Asterisk帶有很多專業(yè)錄制的語(yǔ)音文件,默認(rèn)的目錄通常是/var/lib/asterisk/sounds/. 這些文件都是GSM格式.使用格式如下:
Playback(filename) ;將播放文件名為filename.gsm的語(yǔ)音文件,并假定這個(gè)文件 位于默認(rèn)的語(yǔ)音文件目錄內(nèi).
Playback(/home/tim/sounds/filename) ;也可以包括完整路徑,將播放/home/tim/sounds/目錄下的filename.gsm文件.
Playback(custom/filename) ;將播放默認(rèn)語(yǔ)音文件目錄內(nèi)custom/子目錄中的filename.gsm文件.
Hangup()完成掛斷一個(gè)正在活動(dòng)的通道.主叫方將收到通話掛斷的指示.當(dāng)要結(jié)束通話時(shí),可以在context的末尾使用這個(gè)應(yīng)用,以確保主叫不會(huì)繼續(xù)停留在撥號(hào)方案內(nèi).這個(gè)應(yīng)用不需要參量.
第一個(gè)撥號(hào)方案
方案如下:
[incoming]
exten=>s,1,Answer()
exten=>s,2,Playback(hello-world)
exten=>s,3,Hangup()
5.3 在撥號(hào)方案中加入邏輯
剛剛建立的撥號(hào)方案是靜態(tài)的,對(duì)每個(gè)呼叫總是作相同的事情,現(xiàn)在加入一些邏輯,讓它根據(jù)用戶的輸入來(lái)完成一些不同的動(dòng)作.
Background()和Goto()應(yīng)用
構(gòu)建交互式Asterisk系統(tǒng)的關(guān)鍵是Background()應(yīng)用.與Playback()相同的是,它也播放事先錄制好的語(yǔ)音文件;與Playback()不同的是,當(dāng)主叫方按下電話鍵(1個(gè)或者多個(gè))的時(shí)候,會(huì)中斷語(yǔ)音的播放,轉(zhuǎn)到與所按數(shù)字對(duì)應(yīng)的extension. 例如,假設(shè)主叫方按下5,Asterisk停止播放語(yǔ)音,把呼叫的控制發(fā)送給extension 5的第一個(gè)priority.Background()語(yǔ)法與Playback()類似.
Background()應(yīng)用通常用于創(chuàng)建語(yǔ)音菜單,以免接待員接聽每一個(gè)電話
另外一個(gè)有用的應(yīng)用是Goto().它用于把呼叫發(fā)送到另一個(gè)context,extension,以及priority. Goto應(yīng)用使得在撥號(hào)方案的不同部分有序的轉(zhuǎn)移非常容易.語(yǔ)法如下:
exten=>123,1,Goto(context,extension,priority)
看下面例子:
[incoming]
exten=>s,1,Answer()
exten=>s,2,Background(enter-ext-of-person)
exten=>1,1,Playback(digits/1)
exten=>1,2,Goto(incoming,s,1)
exten=>2,1,Playback(digits/1)
exten=>2,2,Goto(incoming,s,1)
非法輸入和超時(shí)的處理
第一個(gè)語(yǔ)音菜單已經(jīng)完成,我們?cè)诩尤霂讉€(gè)附加的特殊extension.首先,需要一個(gè)用來(lái)處理非法輸入的extension,從而在主叫方按下一個(gè)無(wú)效輸入(比如在上面的例子中按下3),呼叫被送到 iextension. 其次,需要一個(gè)extension來(lái)處理主叫方?jīng)]有及時(shí)(默認(rèn)的時(shí)間是10秒)輸入的情況.如果主叫方在Background()完成語(yǔ)音文件播放之后很久才按鍵,呼叫將被轉(zhuǎn)移到 t extension. 如下:
[incoming]
exten=>s,1,Answer()
exten=>s,2,Background(enter-ext-of-person)
exten=>1,1,Playback(digits/1)
exten=>1,2,Goto(incoming,s,1)
exten=>2,1,Playback(digits/2)
exten=>2,2,Goto(incoming,s,1)
exten=>i,1,Playback(pbx-invalid)
exten=>i,2,Goto(incoming,s,1)
exten=>t,1,Playback(vm-goodbye)
exten=>t,2,Hangup()
現(xiàn)在功能還是有限,因?yàn)橥饷娴闹鹘袩o(wú)法與實(shí)際的人聯(lián)系.為了做到這一點(diǎn),我們還需要一個(gè)Dial()應(yīng)用.
使用Dial()應(yīng)用
Dial()需要4個(gè)參量.第1個(gè)是呼叫的被叫地,由呼叫所采用的(傳輸)技術(shù),反斜線,遠(yuǎn)地資源(通常是通道名稱或編號(hào))等組成.例如,假定我們要呼叫名字為Zap/1的Zap通道(連接了普通模擬電話的FXS通道),那么技術(shù)是Zap,資源是1.與此類似,到一個(gè)SIP設(shè)備的呼叫的被叫地是SIP/1234, 而到一個(gè)IAX設(shè)備的呼叫的被叫地是IAX/fred. 假如在extension123到達(dá)撥號(hào)方案時(shí),要Asterisk對(duì)Zap/1通道振鈴,要加入下面這個(gè)extension:
exten=>123,1,Dial(Zap/1)
當(dāng)這個(gè)extension被執(zhí)行時(shí),Asterisk會(huì)連接通道上Zap/1的電話振鈴,也可以同時(shí)撥多個(gè)通道,如下:
exten=>123,1,Dial(Zap/1&Zap/2&Zap/3)
Dial()會(huì)橋連來(lái)電,無(wú)論被叫地中的哪一個(gè)通道先接聽.
Dial()應(yīng)用的第2個(gè)參量是超時(shí),單位為秒.如果給定了超時(shí)參量,Dial()會(huì)一直對(duì)被叫地進(jìn)行呼叫,直到超時(shí)后才放棄,然后轉(zhuǎn)移到該extension中的下一個(gè)priority. 如果沒(méi)有指定超時(shí)時(shí)間,Dial()會(huì)一直呼叫該通道,直到有人接聽,或者主叫掛機(jī).我們把10秒超時(shí)加到extension中:
exten=>123,1,Dial(Zap/1,10)
如果呼叫在超時(shí)之前被接聽,通道就被橋連,撥號(hào)方案完成,如果被叫地沒(méi)有應(yīng)答,Dial()會(huì)繼續(xù)到該extension的下一個(gè)priority.但是如果被叫通道忙,Dial()將轉(zhuǎn)到priority n+101, 如果其存在的話(其中的n是Dial()被調(diào)用的priority).這樣我們就能夠以不同于被叫地忙的方式來(lái)處理未接聽電話.如下:
exten=>123,1,Dial(Zap/1,10)
exten=>123,2,Playback(vm-nobodyavail)
exten=>123,3,Hangup()
exten=>123,102,Playback(tt-albusy)
exten=>123,103,Hangup()
正如你所看到的,在這個(gè)例子中,如果呼叫未被接聽,將播放vm-nobodyavail.gsm語(yǔ)音文件,如果Zap/1通道正忙,則播放tt-allbusy.gsm語(yǔ)音文件.
Dial()應(yīng)用的第3個(gè)參量是可選擇的字符串.它包含一個(gè)或多個(gè)能夠影響Dial()應(yīng)用行為的字符.最常用的是字母r.如果把r作為第3個(gè)參量,在通知被叫通道有來(lái)電的這段時(shí)間內(nèi),主叫方會(huì)聽到振鈴聲音.
此時(shí),已經(jīng)知道如何使用Dial()應(yīng)用,撥號(hào)方案中編號(hào)為1和2的extension變得沒(méi)有用了.我們把它們用extension101和102來(lái)代替,這樣就允許外部的主叫方把電話打給tim和david:
[incoming]
exten=>s,1,Answer()
exten=>s,2,Background(enter-ext-of-person)
exten=>101,1,Dial(Zap/1,10)
exten=>101,2,Playback(vm-nobodyavail)
exten=>101,3,Hangup()
exten=>101,102,Playback(tt-allbusy)
exten=>101,103,Hangup()
exten=>102,1,Dial(SIP/david,10)
exten=>102,2,Playback(vm-nobodyavail)
exten=>102,3,Hangup()
exten=>102,102,Playback(tt-allbusy)
exten=>102,103,Hangup()
exten=>i,1,Playback(pbx-invalid)
exten=>i,2,Goto(incoming,s,1)
exten=>t,1,Playback(vm-goodbye)
exten=>t,2,Hangup()
Dial()應(yīng)用的最后一個(gè)參量是URL.如果被叫通道支持在呼叫的同時(shí)接受URL,那么所指定的URL將被發(fā)送,這個(gè)參量很少使用.
如果要在FXOZap通道上產(chǎn)生一個(gè)去話,可以使用下面的語(yǔ)法在那個(gè)通道上撥號(hào):
exten=>123,1,Dial(Zap/4/5551212)
這個(gè)例子在Zap/4通道上撥號(hào)碼555-1212.對(duì)于其它類型的通道,如SIP和IAX,簡(jiǎn)單的把被叫地作為資源,見下:
exten=>123,1,Dial(SIP/1234)
exten=>124,1,Dial(IAX2/tim@asteriskdocs.org)
注意:任何參量為空,如保留超時(shí)參量為空,如下:
exten=>123,1,Dial(Zap/1,,r)
給內(nèi)部呼叫增加Context
context的一個(gè)重要功能是為不同的主叫用戶區(qū)分特權(quán)(如長(zhǎng)途通話,或者呼叫特定的extension).在下面例子中,我們建立兩個(gè)內(nèi)部電話的extension,加到撥號(hào)方案里去,然后配置這兩個(gè)extension可以彼此呼叫.為達(dá)到這個(gè)目的,創(chuàng)建一個(gè)新的叫做[internal]的context.
[incoming]
exten=>s,1,Answer()
exten=>s,2,Background(enter-ext-of-person)
exten=>101,1,Dial(Zap/1,10)
exten=>101,2,Playback(vm-nobodyavail)
exten=>101,3,Hangup()
exten=>101,102,Playback(tt-allbusy)
exten=>101,103,Hangup()
exten=>102,1,Dial(SIP/david,10)
exten=>102,2,Playback(vm-nobodyavail)
exten=>102,3,Hangup()
exten=>102,102,Playback(tt-allbusy)
exten=>102,103,Hangup()
exten=>i,1,Playback(pbx-invalid)
exten=>i,2,Goto(incoming,s,1)
exten=>t,1,Playback(vm-goodbye)
exten=>t,2,Hangup()
[internal]
exten=>101,1,Dial(Zap/1,,r)
exten=>102,1,Dial(SIP/david,,r)
在這個(gè)例子中,我們?cè)赱interanl]context中加了兩個(gè)新的extension.這樣,使用通道Zap/1的人可以拿起電話撥102來(lái)?yè)艽蛲ǖ纁hannelSIP/david上的人,同樣,注冊(cè)為SIP/david的電話可以撥打101來(lái)?yè)艽騔ap/1的電話.
如果你認(rèn)為你的用戶可能通過(guò)支持名字的VoIP來(lái)傳輸撥號(hào),添加使用名字的extension也不是什么不好的事情.如下修改:
[internal]
exten=>101,1,Dial(Zap/1,,r)
exten=>tim,1,Dial(Zap/1,,r)
exten=>102,1,Dial(SIP/david,,r)
exten=>david,1,Dial(SIP/david,,r)
使用變量
例如,建立一個(gè)叫做TIM的變量,并給其賦予值Zap/1.這樣,在寫撥號(hào)方案時(shí),可以利用名字來(lái)引用Tim的通道,不需要直接記住Tim使用的Zap/1.為了把指賦給變量,只需要輸入變量名稱,等號(hào)和值,如下所示:
TIM=Zap/1
引用變量有兩種方法.若要引用變量的名字,僅僅需要輸入變量的名字就可以了,例如:TIM;但如果要引用變量的值,則必須輸入美元符號(hào),緊接著是大括號(hào),在大括號(hào)內(nèi)輸入變量名.下面的例子說(shuō)明了如何在應(yīng)用中引用變量:
exten=>555,1,Dial(${TIM},,r)
在撥號(hào)方案中有三種變量可以使用:全局變量,通道變量和環(huán)境變量.
1.全局變量
全局變量適用于所有context里的所有extensions.全局變量的好用之處在于它可以用于撥號(hào)方案中的任何地方,能夠增加可讀性和可管理性.
全局變量應(yīng)該在extensions.conf文件的開始利用[globals]context定義.也可以使用編程的方式定義,利用SetGlobalVar()應(yīng)用.如下:
[globals]
TIM=Zap/1
或
[internal]
exten=>123,1,SetGlobalVar(TIM=Zap/1)
2.通道變量
通道變量與特定的呼叫相關(guān)的變量(如Caller*IDnumber),與全局變量不同,通道變量只能在當(dāng)前呼叫存在期間定義,并只能用于參與該呼叫的通道.
有很多的預(yù)先定義的通道變量可以用于撥號(hào)方案,在Asterisk源程序的doc子目錄下README文件中有詳細(xì)的說(shuō)明.通道變量使用Set()應(yīng)用來(lái)設(shè)置:
exten=>123,1,Set(MAGICNUMBER=42)
3.環(huán)境變量
環(huán)境變量是一種在Asterisk中訪問(wèn)操作系統(tǒng)環(huán)境變量的方法.這些變量以${ENV(var)}形式引用,其中的var是所要引用的操作系統(tǒng)環(huán)境變量.
4.在撥號(hào)方案中加入變量
我們?yōu)閮蓚€(gè)人,Tim和David加入變量:
[globals]
TIM=SIP/tim
DAVID=Zap/1
[incoming]
exten=>s,1,Answer()
exten=>s,2,Background(enter-ext-of-person)
exten=>101,1,Dial(${TIM},10)
exten=>101,2,Playback(vm-nobodyavail)
exten=>101,3,Hangup()
exten=>101,102,Playback(tt-allbusy)
exten=>101,103,Hangup()
exten=>102,1,Dial(${DAVID},10)
exten=>102,2,Playback(vm-nobodyavail)
exten=>102,3,Hangup()
exten=>102,102,Playback(tt-allbusy)
exten=>102,103,Hangup()
exten=>i,1,Playback(pbx-invalid)
exten=>i,2,Goto(incoming,s,1)
exten=>t,1,Playback(vm-goodbye)
exten=>t,2,Hangup()
[internal]
exten=>101,1,Dial(${TIM},,r)
exten=>102,1,Dial(${DAVID},,r)
模式匹配
模式匹配可以使用一段代碼來(lái)對(duì)應(yīng)許多不同的extensions.
1.模式匹配語(yǔ)法
使用模式匹配的時(shí)候,用不同的字母和符號(hào)來(lái)代表肯恩個(gè)要匹配的數(shù)字.模式總是用一個(gè)下劃線(_)開始,它告訴Asterisk要做模式匹配,這不是一個(gè)extension名字.(這意味著不能用下劃線作為extension名字的開始字符)
在下劃線之后,可以使用一個(gè)或者多個(gè)下面列出的字符:
X
匹配0-9的任何數(shù)字.
Z
匹配1-9的任何數(shù)字
N
匹配2-9的任何數(shù)字
[15-7]
匹配任何數(shù)字或者指定的數(shù)字范圍.在這個(gè)例子中,匹配1,5,6或7.
.(句號(hào))
通配符,匹配一個(gè)或多個(gè)字符.
應(yīng)該在匹配了其他數(shù)字之后在使用通配符,如:
_.
實(shí)際上,如果你試圖使用它,Asterisk會(huì)警告你.如果可能,盡量使用下面的模式:
_X.
若要在撥號(hào)方案中使用模式匹配,只要把模式放在extension名字的位置:
exten=>_NXX,1,Playback(auth-thankyou)
在這個(gè)例子中,模式會(huì)匹配3位的extension,從200到999,這就是說(shuō),在這個(gè)context中,如果主叫撥200-999之間的任何extension,都會(huì)聽到聲音文件auth-thankyou.gsm的聲音.
必須了解的一件事情是,如果Asterisk發(fā)現(xiàn)有多個(gè)模式與所撥的extension匹配,它會(huì)使用最接近的那一個(gè)模式.比如說(shuō)定義了下面的兩個(gè)模式,主叫方撥的號(hào)碼是888-555-1212:
exten=>_555XXXX,1,Playback(digits/1)
exten=>_55512XX,1,Playback(digits/2)
在這個(gè)例子中,會(huì)選擇第2個(gè)extension,因?yàn)樗咏?
2.模式匹配的實(shí)例
NANP與話費(fèi)欺詐
略
3.使用${EXTEN}通道變量
一旦撥了某個(gè)extension,Asterisk會(huì)把通道變量${EXTEN}設(shè)置為所撥的數(shù)字.可以使用應(yīng)用SayDigits()來(lái)檢測(cè)出來(lái):
exten=>_XXX,1,SayDigits(${EXTEN})
在這個(gè)例子中,SayDigits()應(yīng)用會(huì)把所撥的3位extension讀出來(lái).
通常,把extension的前面幾位去掉對(duì)于處理${EXTEN}是很有用的.可以利用這樣的語(yǔ)法來(lái)實(shí)現(xiàn):${EXTEN:x},其中x是要去掉的位數(shù).例如,假設(shè)EXTEN的值是95551212,那么${EXTEN:1}等于5551212. 再來(lái)看另外一個(gè)例子:
exten=>_XXX,1,SayDigits(${EXTEN:1})
在這個(gè)例子中,SayDigits()應(yīng)用把所撥的extension的最后兩位讀出來(lái).如果x是負(fù)數(shù),SayDigits()給出所撥的extension的最后x位.在下面的例子中,SayDigits()只讀出所撥的extension的最后1位:
exten=>_XXX,1,SayDigits(${EXTEN:-1})
開啟去話撥號(hào)
允許用戶向外撥打電話,首先要做的一件事情是給[globals]context加一個(gè)變量,用于定義那一個(gè)通道可以用來(lái)向外撥打電話:
[globals]
TIM=SIP/tim
DAVID=Zap/1
OUTBOUNDTRUNK=Zap/4
接下來(lái),在撥號(hào)方案中添加一個(gè)用于去話的context.使用一個(gè)單獨(dú)的context的目的是能夠規(guī)定和控制誰(shuí)可以撥打電話,以及可以撥打什么樣的去話.
首先,建立一個(gè)用于本地電話的context.為了與傳統(tǒng)電話交換機(jī)保持一致,我們?cè)谀J街胺派?,因此用戶必須在呼叫外部號(hào)碼之前撥9:
[outbound-local]
exten=>_9NXXXXXX,1,Dial(${OUTBOUNDTRUNK}/${EXTEN:1})
exten=>_9NXXXXXX,2,Congestion()
exten=>_9NXXXXXX,102,Congestion()
注意: 撥9并沒(méi)有立即給你外線,這和傳統(tǒng)的PBX系統(tǒng)不同.一旦在FXS線路上撥9,撥號(hào)音會(huì)停止.如果在撥9之后還希望有撥號(hào)音,加入下面一行(就在context定義之后):
ignorepat=>9
這個(gè)指令告訴Asterisk繼續(xù)提供撥號(hào)音,即便是在主叫方已經(jīng)撥了指示的模式.
回顧一下我們剛剛所做的事情.增加了一個(gè)全局變量OUTBOUNDTRUNK,它會(huì)控制使用哪一個(gè)通道用于去話,還增加了一個(gè)用于本地去話的context.在priority1中,取出所撥的extension,用${EXTEN:1}語(yǔ)法去掉9,然后試圖在變量OUTBOUNDTRUNK所指定的通道上撥這個(gè)號(hào)碼.如果呼叫成功,主叫方就與去話通道建立橋連.如果呼叫不成功(要么是通道忙,要么是因?yàn)槟撤N原因不能撥這個(gè)號(hào)碼,調(diào)用Congestion()應(yīng)用,播放"快忙音"(擁擠聲音)讓主叫方知道呼叫不成功.
在進(jìn)一步往下走之前,先確認(rèn)一下這個(gè)撥號(hào)方案允許撥打緊急電話號(hào)碼:
[outbound-local]
exten=>_9NXXXXXX,1,Dial(${OUTBOUNDTRUNK}/${EXTEN:1})
exten=>_9NXXXXXX,2,Congestion()
exten=>_9NXXXXXX,102,Congestion()
exten=>911,1,Dial(${OUTBOUNDTRUNK}/911)
exten=>9911,1,Dial(${OUTBOUNDTRUNK}/911)
下面,給撥號(hào)方案加一個(gè)用于長(zhǎng)途電話的context:
[outbound-long-distance]
exten=>_9NXXXXXX,1,Dial(${OUTBOUNDTRUNK}/${EXTEN:1})
exten=>_91NXXNXXXXXX,2,Congestion()
exten=>_91NXXNXXXXXX,102,Congestion()
現(xiàn)在有了兩個(gè)新的context,如何允許內(nèi)部用戶利用它們?我們需要一種辦法來(lái)使得一個(gè)context能夠使用另一個(gè)context.
INCLUDES
Asterisk允許在一個(gè)context中使用另一個(gè)context,通過(guò)include指令來(lái)實(shí)現(xiàn).這用來(lái)授予訪問(wèn)給不同的撥號(hào)方案段.我們使用include功能來(lái)讓[internal]context中的用戶能夠撥打去話.首先介紹一下語(yǔ)法.
include語(yǔ)句的形式如下所示,其中的是我們要包含在當(dāng)前context的遠(yuǎn)地context:
include=>context
在當(dāng)前context包含另外的context時(shí),必須注意包含的順序.Asterisk首先試圖在當(dāng)前context中匹配extension.如果不成功,會(huì)去嘗試第一個(gè)包含進(jìn)來(lái)的context,然后按照包含順序再去嘗試其他的context.
到目前為止,撥號(hào)方案有兩個(gè)context用于去話.但是[internal]context中的人還不能夠使用它們.我們用在[internal]context包含兩個(gè)去話context來(lái)實(shí)現(xiàn)使用,如下所示:
[globals]
TIM=SIP/tim
DAVID=Zap/1
OUTBOUNDTRUNK=Zap/4
[incoming]
exten=>s,1,Answer()
exten=>s,2,Background(enter-ext-of-person)
exten=>101,1,Dial(${TIM},10)
exten=>101,2,Playback(vm-nobodyavail)
exten=>101,3,Hangup()
exten=>101,102,Playback(tt-allbusy)
exten=>101,103,Hangup()
exten=>102,1,Dial(${DAVID},10)
exten=>102,2,Playback(vm-nobodyavail)
exten=>102,3,Hangup()
exten=>102,102,Playback(tt-allbusy)
exten=>102,103,Hangup()
exten=>i,1,Playback(pbx-invalid)
exten=>i,2,Goto(incoming,s,1)
exten=>t,1,Playback(vm-goodbye)
exten=>t,2,Hangup()
[internal]
include=>outbound-local
include=>outbound-long-distance
exten=>101,1,Dial(${TIM},,r)
exten=>102,1,Dial(${DAVID},,r)
[outbound-local]
exten=>_9NXXXXXX,1,Dial(${OUTBOUNDTRUNK}/${EXTEN:1})
exten=>_9NXXXXXX,2,Congestion()
exten=>_9NXXXXXX,102,Congestion()
exten=>911,1,Dial(${OUTBOUNDTRUNK}/911)
exten=>9911,1,Dial(${OUTBOUNDTRUNK}/911)
[outbound-long-distance]
exten=>_9NXXXXXX,1,Dial(${OUTBOUNDTRUNK}/${EXTEN:1})
exten=>_91NXXNXXXXXX,2,Congestion()
exten=>_91NXXNXXXXXX,102,Congestion()
這兩個(gè)include語(yǔ)句讓[internal]context內(nèi)的主叫方可以撥打去話.應(yīng)該注意到,出于安全的考慮,要確保[inbound]context永遠(yuǎn)不要允許撥打去話.(如果一旦給了這樣的機(jī)會(huì),外面的人可以撥入你的系統(tǒng),然后在撥打收費(fèi)電話出去,讓你來(lái)承擔(dān)通話費(fèi)用!)
愛華網(wǎng)



