你可以看到,前面的正則表達式匹配都沒(méi)有成功(Regex (FAIL)),只是到最后匹配到 ^9196$才成功(你看到 Regex (PASS)了),成功后先應答(answer),然后執行 echo。
在這一節里,我們花了很多篇幅來(lái)講解如此簡(jiǎn)單的問(wèn)題。但實(shí)際上,我是想讓你知道,這一節最重要的不是講 Dialplan,而是告訴你如何看 Log。在郵件列表上,大多數新手遇到的問(wèn)題都可以很輕松的從 Log 中看出來(lái),但他們不知道怎么看,或者是看了也不理解。所以,在這里,我想請你再看一下我們的第一個(gè)例子。永遠記住:遇到 Dialplan 的問(wèn)題,按F8打開(kāi)DEBUG級別的日志,從綠色的行開(kāi)始看起(當然,如果你的終端不能顯示顏色,那么,從 Processing 一行看起)。我們的第一個(gè)例子雖然只有短短的四行 Log,但是它包含了所有你需要的信息。
默認的配置文件結構
系統默認提供的配置文件包含三個(gè) Context:default、features和 public,它們分別在三個(gè) XML 文件中。default 是默認的 dialplan,一般來(lái)說(shuō)注冊用戶(hù)都可以使用它來(lái)打電話(huà),如撥打其它分機或外部電話(huà)等。而 public 則是接收外部呼叫,因為從外部進(jìn)來(lái)的呼叫是不可信的,所以要進(jìn)行更嚴格的控制。如,你肯定不想從外部進(jìn)來(lái)的電話(huà)再通過(guò)你的網(wǎng)關(guān)進(jìn)行國內或國際長(cháng)途呼叫。
當然,這么說(shuō)不是絕對的,等你熟悉了 Dialplan 的概念之后,可以發(fā)揮你的想象力進(jìn)行任何有創(chuàng )意的配置。
其中,在 default 和 public 中,又通過(guò) INCLUDE 預處理指令分別加入了 default/ 和 include/ 目錄中的所有 XML 文件。 這些目錄中的文件僅包含一些額外的 Extension。由于 Dialplan 在處理是時(shí)候是順序處理的,所以,一定要注意這些文件的裝入順序。通常,這些文件都按文件名排序,如 00_,01_等等。如果你新加入 Extension,可以在這些目錄里創(chuàng )建文件。但要注意,這些文件的優(yōu)先級比直接寫(xiě)在如 default.xml 中低。我前面已經(jīng)說(shuō)過(guò),由于你不熟悉系統提供的默認的 Dialplan,很可能出現與系統沖突的情況。當然,你已經(jīng)學(xué)會(huì )如何查看 Log,所以能很容易的找到問(wèn)題所在。但在本書(shū)中,我還是堅持將新加的 Extension 加在 Dialplan 中的最前面,以便于說(shuō)明問(wèn)題。
實(shí)際上,由于在處理 Dialplan 時(shí)要對每一項進(jìn)行正則表達式匹配,是非常影響效率的。所以,在生產(chǎn)環(huán)境中,往往要刪除這些默認的 Dialplan,而只配置有用的部分。但我們還不能刪,因為里面有好多例子我們可以學(xué)習。
Dialplan 使用 Perl 兼容的正則表達式(PCRE, Perl-compatible regular expressions)匹配。熟悉編程的同學(xué)肯定已經(jīng)很熟悉它了,為了方便不熟悉的同學(xué),在這里僅作簡(jiǎn)單介紹:
^1234$ ^ 匹配字符串開(kāi)頭,$ 匹配結尾,所以本表達式嚴格匹配 1234
^1234|5678$ | 是或的意思,表示匹配 1234 或 5678
^123[0-9]$ [ ] 表式匹配其中的任意一個(gè)字符,其中的 - 是省略的方式,表示 0 到 9,它等于 [0123456789]
也就是說(shuō)它會(huì )匹配 1230,1231,1232 ... 1239
^123\d$ 同上,\d 等于 [0-9]
^123\d+$ + 號表示1個(gè)或多個(gè)它前面的字符,因為 + 前面是 \d,所以它就等于1個(gè)或多個(gè)數字,實(shí)際上,
它匹配任何以123開(kāi)頭的至少4位數的數字串,如1230,12300,12311,123456789等
^123\d*$ *號與+號的不同在于,它匹配0個(gè)或多個(gè)前面的字符。
所以,它匹配以123開(kāi)頭的至少3位數的數字串,如 123,123789
^123 跟上面一樣,由于沒(méi)有結尾的$,它匹配任何以123開(kāi)頭的數字串,但除此之外,它還匹配后面是字母的情況,如 123abc
123$ 匹配任何以123結尾的字符串
^123\d{5}$ {5}表示精確匹配5位,包含它前面的一個(gè)字符。在這里,它匹配以123開(kāi)頭的所有8位的電話(huà)號碼
^123(\d+)$ ( )在匹配中不起作用,跟^123\d+是相同的,但它對匹配結果有作用,
匹配結果中除123之外的數字都將存儲在$1這個(gè)變量中,在下一步使用
^123(\d)(\d+)$ 如果用它跟12345678匹配,則匹配成功,結果是 $1 = 4, $2 = 5678
簡(jiǎn)單的正則表達式比較容易理解,更深入的學(xué)習請查閱相關(guān)資料。正則表達式功能很強大,但配置不當也容易出現錯誤,輕者造成電話(huà)不通,重者可能會(huì )造成誤撥或套撥,帶來(lái)經(jīng)濟損失。
在 FreeSWITCH 中,每一次呼叫都由一條或多條“腿”(Call Leg)組成,其中的一條腿又稱(chēng)為一個(gè) Channel(信道),每一個(gè) Channel 都有好多屬性,用于標識 Channel 的狀態(tài),性能等,這些屬性稱(chēng)為 Channel Variable(信道變量),簡(jiǎn)寫(xiě)為 Channel Var 或 Chan Var 或 Var。
通過(guò)使用 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 中,為了復習上一節的內容,我們這一次加入 My Echo Test 這一 Extension 的后面,存盤(pán),然后在 FreeSWITCH 命令行上執行 reloadxml。從軟電話(huà)上呼叫 1235,可以看到有很多 Log輸出,還是從綠色的行開(kāi)始看:
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]