你可以看到,前面的正則表達(dá)式匹配都沒有成功(Regex (FAIL)),只是到最后匹配到 ^9196$才成功(你看到 Regex (PASS)了),成功后先應(yīng)答(answer),然后執(zhí)行 echo。
在這一節(jié)里,我們花了很多篇幅來講解如此簡單的問題。但實(shí)際上,我是想讓你知道,這一節(jié)最重要的不是講 Dialplan,而是告訴你如何看 Log。在郵件列表上,大多數(shù)新手遇到的問題都可以很輕松的從 Log 中看出來,但他們不知道怎么看,或者是看了也不理解。所以,在這里,我想請(qǐng)你再看一下我們的第一個(gè)例子。永遠(yuǎn)記。河龅 Dialplan 的問題,按F8打開DEBUG級(jí)別的日志,從綠色的行開始看起(當(dāng)然,如果你的終端不能顯示顏色,那么,從 Processing 一行看起)。我們的第一個(gè)例子雖然只有短短的四行 Log,但是它包含了所有你需要的信息。
默認(rèn)的配置文件結(jié)構(gòu)
系統(tǒng)默認(rèn)提供的配置文件包含三個(gè) Context:default、features和 public,它們分別在三個(gè) XML 文件中。default 是默認(rèn)的 dialplan,一般來說注冊(cè)用戶都可以使用它來打電話,如撥打其它分機(jī)或外部電話等。而 public 則是接收外部呼叫,因?yàn)閺耐獠窟M(jìn)來的呼叫是不可信的,所以要進(jìn)行更嚴(yán)格的控制。如,你肯定不想從外部進(jìn)來的電話再通過你的網(wǎng)關(guān)進(jìn)行國內(nèi)或國際長途呼叫。
當(dāng)然,這么說不是絕對(duì)的,等你熟悉了 Dialplan 的概念之后,可以發(fā)揮你的想象力進(jìn)行任何有創(chuàng)意的配置。
其中,在 default 和 public 中,又通過 INCLUDE 預(yù)處理指令分別加入了 default/ 和 include/ 目錄中的所有 XML 文件。 這些目錄中的文件僅包含一些額外的 Extension。由于 Dialplan 在處理是時(shí)候是順序處理的,所以,一定要注意這些文件的裝入順序。通常,這些文件都按文件名排序,如 00_,01_等等。如果你新加入 Extension,可以在這些目錄里創(chuàng)建文件。但要注意,這些文件的優(yōu)先級(jí)比直接寫在如 default.xml 中低。我前面已經(jīng)說過,由于你不熟悉系統(tǒng)提供的默認(rèn)的 Dialplan,很可能出現(xiàn)與系統(tǒng)沖突的情況。當(dāng)然,你已經(jīng)學(xué)會(huì)如何查看 Log,所以能很容易的找到問題所在。但在本書中,我還是堅(jiān)持將新加的 Extension 加在 Dialplan 中的最前面,以便于說明問題。
實(shí)際上,由于在處理 Dialplan 時(shí)要對(duì)每一項(xiàng)進(jìn)行正則表達(dá)式匹配,是非常影響效率的。所以,在生產(chǎn)環(huán)境中,往往要?jiǎng)h除這些默認(rèn)的 Dialplan,而只配置有用的部分。但我們還不能刪,因?yàn)槔锩嬗泻枚嗬游覀兛梢詫W(xué)習(xí)。
Dialplan 使用 Perl 兼容的正則表達(dá)式(PCRE, Perl-compatible regular expressions)匹配。熟悉編程的同學(xué)肯定已經(jīng)很熟悉它了,為了方便不熟悉的同學(xué),在這里僅作簡單介紹:
^1234$ ^ 匹配字符串開頭,$ 匹配結(jié)尾,所以本表達(dá)式嚴(yán)格匹配 1234
^1234|5678$ | 是或的意思,表示匹配 1234 或 5678
^123[0-9]$ [ ] 表式匹配其中的任意一個(gè)字符,其中的 - 是省略的方式,表示 0 到 9,它等于 [0123456789]
也就是說它會(huì)匹配 1230,1231,1232 ... 1239
^123\d$ 同上,\d 等于 [0-9]
^123\d+$ + 號(hào)表示1個(gè)或多個(gè)它前面的字符,因?yàn)?+ 前面是 \d,所以它就等于1個(gè)或多個(gè)數(shù)字,實(shí)際上,
它匹配任何以123開頭的至少4位數(shù)的數(shù)字串,如1230,12300,12311,123456789等
^123\d*$ *號(hào)與+號(hào)的不同在于,它匹配0個(gè)或多個(gè)前面的字符。
所以,它匹配以123開頭的至少3位數(shù)的數(shù)字串,如 123,123789
^123 跟上面一樣,由于沒有結(jié)尾的$,它匹配任何以123開頭的數(shù)字串,但除此之外,它還匹配后面是字母的情況,如 123abc
123$ 匹配任何以123結(jié)尾的字符串
^123\d{5}$ {5}表示精確匹配5位,包含它前面的一個(gè)字符。在這里,它匹配以123開頭的所有8位的電話號(hào)碼
^123(\d+)$ ( )在匹配中不起作用,跟^123\d+是相同的,但它對(duì)匹配結(jié)果有作用,
匹配結(jié)果中除123之外的數(shù)字都將存儲(chǔ)在$1這個(gè)變量中,在下一步使用
^123(\d)(\d+)$ 如果用它跟12345678匹配,則匹配成功,結(jié)果是 $1 = 4, $2 = 5678
簡單的正則表達(dá)式比較容易理解,更深入的學(xué)習(xí)請(qǐng)查閱相關(guān)資料。正則表達(dá)式功能很強(qiáng)大,但配置不當(dāng)也容易出現(xiàn)錯(cuò)誤,輕者造成電話不通,重者可能會(huì)造成誤撥或套撥,帶來經(jīng)濟(jì)損失。
在 FreeSWITCH 中,每一次呼叫都由一條或多條“腿”(Call Leg)組成,其中的一條腿又稱為一個(gè) Channel(信道),每一個(gè) Channel 都有好多屬性,用于標(biāo)識(shí) Channel 的狀態(tài),性能等,這些屬性稱為 Channel Variable(信道變量),簡寫為 Channel Var 或 Chan Var 或 Var。
通過使用 info 這個(gè) APP,可以查看所有的 Channel Var。我們先修改一下 Dialplan。
<extension name="Show Channel Variable">
<condition field="destination_number" expression="^1235$">
<action application="info" data=""/>
</condition>
</extension>
加入 default.xml 中,為了復(fù)習(xí)上一節(jié)的內(nèi)容,我們這一次加入 My Echo Test 這一 Extension 的后面,存盤,然后在 FreeSWITCH 命令行上執(zhí)行 reloadxml。從軟電話上呼叫 1235,可以看到有很多 Log輸出,還是從綠色的行開始看:
Processing Seven <1000>->1235 in context default
parsing [default->Echo Test] continue=false
Regex (FAIL) [Echo Test] destination_number(1235) =~ /^echo|1234$/ break=on-false
parsing [default->Show Channel Variable] continue=false
Regex (PASS) [Show Channel Variable] destination_number(1235) =~ /^1235$/ break=on-false
Action info()
...
EXECUTE sofia/internal/1000@192.168.7.10 info()
2010-10-23 09:46:31.662281 [INFO] mod_dptools.c:1171 CHANNEL_DATA:
Channel-State: [CS_EXECUTE]
Channel-Call-State: [RINGING]
Channel-State-Number: [4]
Channel-Name: [sofia/internal/1000@192.168.7.10]
Unique-ID: [cfea988b-2dc4-42ec-b731-2cd7ea864fc6]
Caller-Direction: [inbound]
Caller-Username: [1000]
Caller-Dialplan: [XML]
Caller-Caller-ID-Name: [Seven]
Caller-Caller-ID-Number: [1000]
Caller-Network-Addr: [192.168.7.10]
Caller-ANI: [1000]
Caller-Destination-Number: [1235]
variable_direction: [inbound]
variable_uuid: [cfea988b-2dc4-42ec-b731-2cd7ea864fc6]
variable_sip_local_network_addr: [123.130.140.154]
variable_remote_media_ip: [123.130.140.154]
variable_remote_media_port: [8000]
variable_sip_use_codec_name: [PCMA]
variable_sip_use_codec_rate: [8000]
variable_sip_use_codec_ptime: [20]
variable_read_codec: [PCMA]
variable_read_rate: [8000]
variable_write_codec: [PCMA]
variable_write_rate: [8000]
variable_endpoint_disposition: [RECEIVED]
variable_current_application: [info]