九九久久久久午夜精选,欧美一二区视频,国产成人精品一区二三区2022,日本色妞,久久久99精品,亚洲国产精品久久精品成人,91热久久免费频精品99欧美

 首頁(yè) > 新聞 > 專家觀點(diǎn) >

《FreeSWITCH: VoIP實(shí)戰(zhàn)》:撥號(hào)計(jì)劃- Dialplan

2012-08-17 15:51:59   作者:杜金房   來(lái)源:CTI論壇   評(píng)論:0  點(diǎn)擊:


  撥號(hào)計(jì)劃是 FreeSWITCH 中至關(guān)重要的一部分。它的主要作用就是對(duì)電話進(jìn)行路由(從這一點(diǎn)上來(lái)說(shuō),相當(dāng)于一個(gè)路由表)。說(shuō)的簡(jiǎn)明一點(diǎn),就是當(dāng)一個(gè)用戶撥號(hào)時(shí),對(duì)用戶所撥的號(hào)碼進(jìn)行分析,進(jìn)而決定下一步該做什么。當(dāng)然,實(shí)際上,它所能做的比你想象的要強(qiáng)大的多。

  我們?cè)诘诙轮幸呀?jīng)提到過(guò)修改過(guò)撥號(hào)計(jì)劃,單從配置文件看,還算比較簡(jiǎn)單直觀。實(shí)際上,它的概念也不是很復(fù)雜。如果你理解正則表達(dá)式,那你應(yīng)該能看懂系統(tǒng)系統(tǒng)自帶的大部分的配置。但是,在實(shí)際應(yīng)用中,有許多問(wèn)題還是常常令初學(xué)者感到疑惑。主要的問(wèn)題是,要理解 Dialplan,還需要了解 FS 是怎樣工作的(第五章),API 與 APP 的區(qū)別等。

  通過(guò)本章,我們除了要了解 Dialplan 的基本概念和運(yùn)作方式,還要以理論與實(shí)踐相結(jié)合的方式來(lái)進(jìn)行學(xué)習(xí),使用初學(xué)者能快速上手,有經(jīng)驗(yàn)的人也能學(xué)到新的維護(hù)和調(diào)試技巧。

  XML Dialplan

  Dialplan 是 FreeSWITCH 中一個(gè)抽象的部分,它可以支持多種不同的格式,如類似 Asterisk 的格式(由 mod_dialplan_asterisk提供)。但在實(shí)際使用中,用的最多的還是 XML 格式。下面,我們就先討論這種格式。

  配置文件的結(jié)構(gòu)

  撥號(hào)計(jì)劃的配置文件在 conf/dialplan 中,在前面的章節(jié)中我們講過(guò),它們是在 freeswitch.xml 中,由 <X-PRE-PROCESS cmd="include" data="dialplan/*.xml"/> 裝入的。

  撥號(hào)計(jì)劃由多個(gè) Context (上下文/環(huán)境)組成。每個(gè) Context 中有多個(gè) Extension (分支,在簡(jiǎn)單的 PBX 中也可以認(rèn)為是分機(jī)號(hào),但很顯然,Extension 涵蓋的內(nèi)容遠(yuǎn)比分機(jī)號(hào)多)。所以,Context 就是多個(gè) Extension 的邏輯集合,它相當(dāng)于一個(gè)分組,一個(gè) Context 中的 Extension 與其它 Context 中的 Extension 在邏輯上是隔離的。

  下面是 Dialplan 的完整結(jié)構(gòu):

<?xml version="1.0"?>
<document type="freeswitch/xml">
  <section name="dialplan" description="Regex/XML Dialplan">
    <context name="default">
         <extension name="Test Extension">
         </extension>
    </context>
  </section>
</document>

  Extension 相當(dāng)于路由表中的表項(xiàng),其中,每一個(gè) Extension 都有一個(gè) name 屬性。它可以是任何合法的字符串,本身對(duì)呼叫流程沒(méi)有任何影響,但取一個(gè)好聽的名字,有助于你在查看 Log 時(shí)發(fā)現(xiàn)它。

  在 Extension 中可以對(duì)一些 condition (條件)進(jìn)行判斷,如果滿足測(cè)試條件所指定的表達(dá)式,則執(zhí)行相對(duì)應(yīng)的 action (動(dòng)作)。

例如,我們將下列 Extension 配置加入到 conf/dialplan/default.xml 中。并作為第一個(gè) Extension。

<extension name="My Echo Test">
  <condition field="destination_number" expression="^echo|1234$">
    <action application="echo" data=""/>
  </condition>
</extension>

  FreeSWITCH 安裝時(shí),提供了很多例子,為了避免與提供的例子沖突,強(qiáng)列建議在學(xué)習(xí)時(shí)把自己寫的 Extension 寫在最前面。當(dāng)然我說(shuō)的最前面并不是 default.xml 的第一行,而是放到第一個(gè) Extension 的位置,就是以下語(yǔ)句的后面(你通常能在第13-14行找到它們):

<include>
  <context name="default">

  用你喜歡的編譯器編輯好并存盤后,在 FreeSWITCH 命令行上(Console 或 fs_cli)執(zhí)行 reloadxml 或按 F6鍵,使 FreeSWITCH 重新讀入你修改過(guò)的配置文件。并按 F8 鍵將 log 級(jí)別設(shè)置為 DEBUG,以看到詳細(xì)日志.然后,將軟電話注冊(cè)上,并撥叫 1234 或 echo (大部分軟電話都能呼叫字母,如Zoiper,Xlite可以使用空格鍵切換數(shù)字和字母)。

你將會(huì)看到很多 Log, 注意如下的行:

Processing Seven <1000>->1234 in context default
parsing [default->My Echo Test] continue=false
Regex (PASS) [Echo Test] destination_number(1234) =~ /^echo|1234$/ break=on-false
Action echo()

  在我的終端上,上面的第一行是以綠色顯示的。當(dāng)然,為了排版方便,我省去了 Log 中的日期以及其它不關(guān)鍵的一些信息。

   第一行,Processing 說(shuō)明是在處理 Dialplan,Seven 是我的的 SIP 名字,1000 是我的分機(jī)號(hào), 1234 是我所撥叫的號(hào)碼,這里,我直接撥叫了 1234。它完整意思是說(shuō),呼叫已經(jīng)達(dá)到路由階段,要從 XML Dialplan 中查找路由,該呼叫來(lái)自 Seven,分機(jī)號(hào)是1000,它所呼叫的被叫號(hào)碼是 1234 (或 echo,如果你撥叫 echo 的話)。

   第二行,呼叫進(jìn)入 parsing (解析XML) 階段,它首先找到 XML 中的一個(gè) Context,這里是 default(它是在 user directory 中定義的,看第五章。user directory 中有一項(xiàng) , 說(shuō)明,如果 1000 這個(gè)用戶發(fā)起呼叫,則它的 context 就是 default,所以要從 XML Dialplan 中的 default 這個(gè) Context 查起)。它首先找到的第一個(gè) Extension 的 name 是 My Echo Test(還記得吧?我們我們把它放到了 Dialplan 的最前面)。continue=false 的意思我們后面再講。

  第三行,由于該 Extension 中有一個(gè) Condition,它的測(cè)試條件是 destination_number,也就是被叫號(hào)碼,所以, FreeSWITCH 測(cè)試被叫號(hào)碼(這里是 1234)是否與配置文件中的正則表達(dá)式相匹配。 ^echo|1234$ 是正則表達(dá)式,它匹配 echo 或 1234。所以這里匹配成功,Log 中顯示 Regex (PASS)。 當(dāng)然既然匹配成功了,它就開始執(zhí)行動(dòng)作 echo(它是一個(gè) APP),所以你就聽到了自己的聲音。

   這是最簡(jiǎn)單的路由查找。前面我已經(jīng)說(shuō)了,系統(tǒng)自帶了一些 Dialplan 的例子,也許在第二章你已經(jīng)測(cè)試過(guò)了。下面,我們?cè)囈幌孪到y(tǒng)自帶的 echo 的例子。這次,我呼叫的是 9196。在 Log 中,還是從綠色的行開始看:

Processing Seven <1000>->9196 in context default
parsing [default->My Echo Test] continue=false
Regex (FAIL) [Echo Test] destination_number(9196) =~ /^echo|1234$/ break=on-false
parsing [default->unloop] continue=false
Regex (PASS) [unloop] ${unroll_loops}(true) =~ /^true$/ break=on-false
Regex (FAIL) [unloop] ${sip_looped_call}() =~ /^true$/ break=on-false
parsing [default->tod_example] continue=true
Date/Time Match (FAIL) [tod_example] break=on-false
parsing [default->holiday_example] continue=true
Date/Time Match (FAIL) [holiday_example] break=on-false
parsing [default->global-intercept] continue=false
Regex (FAIL) [global-intercept] destination_number(9196) =~ /^886$/ break=on-false
parsing [default->group-intercept] continue=false
Regex (FAIL) [group-intercept] destination_number(9196) =~ /^\*8$/ break=on-false
parsing [default->intercept-ext] continue=false
Regex (FAIL) [intercept-ext] destination_number(9196) =~ /^\*\*(\d+)$/ break=on-false
parsing [default->redial] continue=false
Regex (FAIL) [redial] destination_number(9196) =~ /^(redial|870)$/ break=on-false
parsing [default->global] continue=true
Regex (FAIL) [global] ${call_debug}(false) =~ /^true$/ break=never

parsing [default->fax_receive] continue=false
Regex (FAIL) [fax_receive] destination_number(9196) =~ /^9178$/ break=on-false
parsing [default->fax_transmit] continue=false
Regex (FAIL) [fax_transmit] destination_number(9196) =~ /^9179$/ break=on-false
parsing [default->ringback_180] continue=false
Regex (FAIL) [ringback_180] destination_number(9196) =~ /^9180$/ break=on-false
parsing [default->ringback_183_uk_ring] continue=false
Regex (FAIL) [ringback_183_uk_ring] destination_number(9196) =~ /^9181$/ break=on-false
parsing [default->ringback_183_music_ring] continue=false
Regex (FAIL) [ringback_183_music_ring] destination_number(9196) =~ /^9182$/ break=on-false
parsing [default->ringback_post_answer_uk_ring] continue=false
Regex (FAIL) [ringback_post_answer_uk_ring] destination_number(9196) =~ /^9183$/ break=on-false
parsing [default->ringback_post_answer_music] continue=false
Regex (FAIL) [ringback_post_answer_music] destination_number(9196) =~ /^9184$/ break=on-false
parsing [default->ClueCon] continue=false
Regex (FAIL) [ClueCon] destination_number(9196) =~ /^9191$/ break=on-false
parsing [default->show_info] continue=false
Regex (FAIL) [show_info] destination_number(9196) =~ /^9192$/ break=on-false
parsing [default->video_record] continue=false
Regex (FAIL) [video_record] destination_number(9196) =~ /^9193$/ break=on-false
parsing [default->video_playback] continue=false
Regex (FAIL) [video_playback] destination_number(9196) =~ /^9194$/ break=on-false
parsing [default->delay_echo] continue=false
Regex (FAIL) [delay_echo] destination_number(9196) =~ /^9195$/ break=on-false
parsing [default->echo] continue=false
Regex (PASS) [echo] destination_number(9196) =~ /^9196$/ break=on-false
Action answer()
Action echo()

分享到: 收藏

專題

吉木萨尔县| 长泰县| 洪江市| 鄄城县| 旬邑县| 吴江市| 中牟县| 新宁县| 宜宾市| 白朗县| 疏附县| 金堂县| 齐齐哈尔市| 微博| 沈丘县| 讷河市| 巴楚县| 玉树县| 西乌| 星座| 彰化市| 昭苏县| 甘泉县| 礼泉县| 武鸣县| 东安县| 义乌市| 虎林市| 辽阳市| 东丽区| 墨竹工卡县| 祁连县| 阿坝县| 信丰县| 玛沁县| 石狮市| 永靖县| 孝感市| 兴和县| 皋兰县| 卢氏县|