【Freeswitch从入门到精通】二、初识Freeswitch
【Freeswitch從入門到精通】二、初識Freeswitch
- 1、入門術(shù)語
- 1.1 常見短語
- 1.2 Call Legs
- 2、歷史
- 3、啟動
- 4、dialplan 路由表
- 4.1 測試Demo路由功能
- 4.2 default.xml詳細(xì)配置
- 5、directory 用戶管理
- 6、chatplan 聊天模塊
- 7、api 和 app
- 7.1 APP
- 8、呼叫字符串
- 9、安裝部署
- 10、啟動
- 10.1 生產(chǎn)環(huán)境啟動
- 10.2 測試環(huán)境啟動
- 11、變量
- 11.1 主叫配置變量
- 11.2 普通變量
- 11.3 預(yù)處理變量
- 12 撥打流程
- 12.1 originate user/1000 &echo
- 12.2 originate user/1000 9196 XML default
1、入門術(shù)語
1.1 常見短語
VoIP: Voice over Internet Protocol 基于IP的語音傳輸
SIP: Session Initiation Protocol 會話初始協(xié)議
PSTN:Public Switched Telephone Network 公共交換電話網(wǎng)絡(luò)
MPL:Mozilla Public License 1998年初Netscape的Mozilla小組為其開源軟件項目設(shè)計的軟件許可證,在MPL許可證中對“發(fā)布”的定義是“以源代碼方式發(fā)布的文件”。
IP-PBX Private Branch eXchange 用戶級交換機
NAT:Network Address Translation 網(wǎng)絡(luò)地址轉(zhuǎn)換
OSTAG: Open Source Telephony Advancement Group 開源電話學(xué)進(jìn)步組
B2BUA: 背靠背的代理
PBX: Private Branch Exchange,用戶級交換機,即公司內(nèi)部使用的電話業(yè)務(wù)網(wǎng)絡(luò),系統(tǒng)內(nèi)部分機用戶分享一定數(shù)量的外線。
ITSP:我們的網(wǎng)絡(luò)電話服務(wù)提供商(ITSP),會把撥打DID號碼的電話發(fā)送到我們的"external" SIP profile(演示配置中的5080端口)。我們將使用"external" SIP profile來發(fā)送出局呼叫給ITSP,連接外部世界。在撥號方案中,我們將用一種"gateway"封裝的語法來處理連接ITSP可能需要的鑒權(quán)過程。
1.2 Call Legs
認(rèn)識A leg,與B leg
2、歷史
2005年開始寫,2006年發(fā)布第一個版本
3、啟動
freeswitch -nonat4、dialplan 路由表
4.1 測試Demo路由功能
4.2 default.xml詳細(xì)配置
下面為dialplan/default.xml的詳細(xì)配置:
<extension name="echo"> # 路由名稱<condition field="destination_number" expression="^9196$"> # filed是被叫號碼, expression是正則匹配,被叫號碼匹配上則繼續(xù)<action application="answer"/> # 執(zhí)行回復(fù),相當(dāng)于電話輸入完撥號后的確認(rèn)按鈕<action application="echo"/> # 執(zhí)行回聲,echo相當(dāng)于回聲</condition></extension>freeswitch就是和application的溝通name 名稱任意,只做標(biāo)識,不做邏輯。condition 標(biāo)識條件,field變量,expression正則表達(dá)式action 動作,application APP,data 參數(shù)freeswitch命令:regex:regex 1234 | \d+ 匹配返回true,否則false<extension name="unloop"> <condition field="${unroll_loops}" expression="^true$"/> # unroll_loops 全局變量var.xmls中,默認(rèn)為true<condition field="${sip_looped_call}" expression="^true$"> # <action application="deflect" data="${destination_number}"/> # deflect 防止死循環(huán)</condition></extension><extension name="tod_example" continue="true"> # time of the day 時間例子 ;continue 不管是否匹配,其他擴展也會繼續(xù)走。<condition wday="2-6" hour="9-18"> # 周,時<action application="set" data="open=true"/> # set 設(shè)置變量open為true。</condition></extension><extension name="global-intercept"> # 全局代接攔截,應(yīng)用場景為:同公司其他同事沒在工位,但是有電話打過來,你又懶得過去接,你可以使用自己的電話進(jìn)行攔截接聽,下方表達(dá)式表示,你撥打電話886就可以接入該電話。<condition field="destination_number" expression="^886$"> # 匹配886號碼<action application="answer"/> # 執(zhí)行answer,相當(dāng)于電話按了確認(rèn)鍵。應(yīng)答<action application="intercept" data="${hash(select/${domain_name}-last_dial_ext/global)}"/> # intercept代接, hash()查找哈希表,domain_name 為當(dāng)前的域,global全局,最終結(jié)果為一個uuid,獲取真在振鈴的通話<action application="sleep" data="2000"/> # 暫停2秒鐘</condition></extension><extension name="group-intercept"> # 同組代打<condition field="destination_number" expression="^\*8$"> # 撥打*8<action application="answer"/><action application="intercept" data="${hash(select/${domain_name}-last_dial_ext/${callgroup})}"/> # 獲取當(dāng)前用戶組,每個用戶有默認(rèn)組或者新建組<action application="sleep" data="2000"/></condition></extension><extension name="intercept-ext"> # 代接指定分級<condition field="destination_number" expression="^\*\*(\d+)$"> # 撥打**分機號,就可以代接了<action application="answer"/><action application="intercept" data="${hash(select/${domain_name}-last_dial_ext/$1)}"/> # $1為匹配到的電話號碼<action application="sleep" data="2000"/></condition></extension><extension name="redial"> # 重?fù)?/span><condition field="destination_number" expression="^(redial|870)$"> # 按了重?fù)芑蛘?70<action application="transfer" data="${hash(select/${domain_name}-last_dial/${caller_id_number})}"/> # transfer轉(zhuǎn)接, 以主鍵號碼存key,然后獲取號碼</condition></extension><extension name="global" continue="true"> # 執(zhí)行此擴展后繼續(xù)執(zhí)行其他擴展<condition field="${call_debug}" expression="^true$" break="never"> # call_debug 如果為true,從不break<action application="info"/> # 當(dāng)前呼叫的所有的info變量都輸出。</condition># 如果默認(rèn)密碼為1234,就會輸出提醒修改密碼。<condition field="${default_password}" expression="^1234$" break="never"><action application="log" data="CRIT WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING "/><action application="log" data="CRIT Open $${conf_dir}/vars.xml and change the default_password."/><action application="log" data="CRIT Once changed type 'reloadxml' at the console."/><action application="log" data="CRIT WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING "/><action application="sleep" data="10000"/></condition><condition field="${rtp_has_crypto}" expression="^($${rtp_sdes_suites})$" break="never"> # 如果加密rtp的話, $$為只獲取一次值,$為每次都獲取值<action application="set" data="rtp_secure_media=true"/> #設(shè)置變量為true,為加密通話<!-- Offer SRTP on outbound legs if we have it on inbound. --><!-- <action application="export" data="rtp_secure_media=true"/> --> # 讓呼出channel也加密</condition><condition field="${endpoint_disposition}" expression="^(DELAYED NEGOTIATION)"/> # 如果匹配 晚協(xié)商(freeswitch后面改的晚協(xié)商)<condition field="${switch_r_sdp}" expression="(AES_CM_128_HMAC_SHA1_32|AES_CM_128_HMAC_SHA1_80)" break="never"> # 遠(yuǎn)程sdp如果具有這樣的加密方式的話,執(zhí)行加密為true,即安全方式rtp<action application="set" data="rtp_secure_media=true"/><!-- Offer SRTP on outbound legs if we have it on inbound. --><!-- <action application="export" data="rtp_secure_media=true"/> --> # 同上,呼出channel也加密</condition><condition> # 絕對匹配<action application="hash" data="insert/${domain_name}-spymap/${caller_id_number}/${uuid}"/> # 插入,主叫號碼作為key,uuid作為值插入<action application="hash" data="insert/${domain_name}-last_dial/${caller_id_number}/${destination_number}"/> # 設(shè)置當(dāng)前撥號號碼,用于重?fù)?70<action application="hash" data="insert/${domain_name}-last_dial/global/${uuid}"/> # 全局代接<action application="export" data="RFC2822_DATE=${strftime(%a, %d %b %Y %T %z)}"/> # export 輸出格式化時間</condition></extension><extension name="eavesdrop"> # 監(jiān)聽<condition field="destination_number" expression="^88(\d{4})$|^\*0(.*)$"> # 撥打88+數(shù)字<action application="answer"/> <action application="eavesdrop" data="${hash(select/${domain_name}-spymap/$1$2)}"/> # 獲取監(jiān)聽號碼uuid,并執(zhí)行監(jiān)聽app</condition></extension><extension name="eavesdrop"><condition field="destination_number" expression="^779$"> <action application="answer"/><action application="set" data="eavesdrop_indicate_failed=tone_stream://%(500, 0, 320)"/> # 監(jiān)聽失敗聲音<action application="set" data="eavesdrop_indicate_new=tone_stream://%(500, 0, 620)"/> # 新監(jiān)聽聲音<action application="set" data="eavesdrop_indicate_idle=tone_stream://%(250, 0, 920)"/> # 什么也聽不到,放的聲音<action application="eavesdrop" data="all"/> # 輸入*聽下一個電話</condition></extension><extension name="call_return"> # 回?fù)?/span><condition field="destination_number" expression="^\*69$|^869$|^lcr$"><action application="transfer" data="${hash(select/${domain_name}-call_return/${caller_id_number})}"/></condition></extension><extension name="del-group"> # 將自己移除組中<condition field="destination_number" expression="^80(\d{2})$"><action application="answer"/><action application="group" data="delete:$1@${domain_name}:${sofia_contact(${sip_from_user}@${domain_name})}"/><action application="gentones" data="%(1000, 0, 320)"/> # 刪除成功,返回一個聲音</condition></extension><extension name="add-group"> # 將自己加入組中<condition field="destination_number" expression="^81(\d{2})$"><action application="answer"/><action application="group" data="insert:$1@${domain_name}:${sofia_contact(${sip_from_user}@${domain_name})}"/><action application="gentones" data="%(1000, 0, 640)"/></condition></extension><extension name="call-group-simo"> # 同時呼叫,也叫同震<condition field="destination_number" expression="^82(\d{2})$"><action application="bridge" data="{leg_timeout=15,ignore_early_media=true}${group(call:$1@${domain_name})}"/> # 呼叫超時15秒</condition></extension><extension name="call-group-order"> # 順序呼叫,也叫順震<condition field="destination_number" expression="^83(\d{2})$"><action application="bridge" data="{leg_timeout=15,ignore_early_media=true}${group(call:$1@${domain_name}:order)}"/></condition></extension><extension name="extension-intercom"> # 對某些電話進(jìn)行自動廣播,需要話機支持自動應(yīng)答<condition field="destination_number" expression="^8(10[01][0-9])$"> <action application="set" data="dialed_extension=$1"/><action application="export" data="sip_auto_answer=true"/> # 指定呼叫號碼自動應(yīng)答<action application="bridge" data="user/${dialed_extension}@${domain_name}"/> # 橋連接號碼,直接喊話</condition></extension><extension name="Local_Extension"> # 本地分級<condition field="destination_number" expression="^(10[01][0-9])$"> # 默認(rèn)分機號<action application="export" data="dialed_extension=$1"/><!-- bind_meta_app can have these args <key> [a|b|ab] [a|b|o|s] <app> --><action application="bind_meta_app" data="1 b s execute_extension::dx XML features"/> # 綁定按鍵,,*1綁定 features xml分支,可以通過這個轉(zhuǎn)到其他電話線路中。盲轉(zhuǎn)。<action application="bind_meta_app" data="2 b s record_session::$${recordings_dir}/${caller_id_number}.${strftime(%Y-%m-%d-%H-%M-%S)}.wav"/> # 用戶在通話中按了*2鍵, 綁定在b上,s開始,recore_session:錄音文件路徑,進(jìn)行錄音。<action application="bind_meta_app" data="3 b s execute_extension::cf XML features"/> # 轉(zhuǎn)義到會議中<action application="bind_meta_app" data="4 b s execute_extension::att_xfer XML features"/> # 協(xié)商轉(zhuǎn),1,2,3,4 可以協(xié)商轉(zhuǎn)也可以三方通話<action application="set" data="ringback=${us-ring}"/> # 電弧接通前的設(shè)置回鈴音,這是美國回鈴音<action application="set" data="transfer_ringback=$${hold_music}"/> # 電話接通后的回鈴音,保持通話音<action application="set" data="call_timeout=30"/> # 呼叫超時時間<!-- <action application="set" data="sip_exclude_contact=${network_addr}"/> --><action application="set" data="hangup_after_bridge=true"/> # bridge成功后就掛機。<!--<action application="set" data="continue_on_fail=NORMAL_TEMPORARY_FAILURE,USER_BUSY,NO_ANSWER,TIMEOUT,NO_ROUTE_DESTINATION"/> --> # 默認(rèn)呼叫失敗的狀態(tài)<action application="set" data="continue_on_fail=true"/> # <action application="hash" data="insert/${domain_name}-call_return/${dialed_extension}/${caller_id_number}"/> # 插入主叫號碼<action application="hash" data="insert/${domain_name}-last_dial_ext/${dialed_extension}/${uuid}"/> # 插入最后呼叫分機號<action application="set" data="called_party_callgroup=${user_data(${dialed_extension}@${domain_name} var callgroup)}"/> # 獲取被叫的組<action application="hash" data="insert/${domain_name}-last_dial_ext/${called_party_callgroup}/${uuid}"/> # 插入uuid<action application="hash" data="insert/${domain_name}-last_dial_ext/global/${uuid}"/> # 插入globaluuid<!--<action application="export" data="nolocal:rtp_secure_media=${user_data(${dialed_extension}@${domain_name} var rtp_secure_media)}"/>--><action application="hash" data="insert/${domain_name}-last_dial/${called_party_callgroup}/${uuid}"/> # 給組插入uuid<action application="bridge" data="user/${dialed_extension}@${domain_name}"/> # 產(chǎn)生一條channel,user/1000為呼叫字符串,從location中獲取context被叫地址。此時bridge為阻塞的,直到被叫掛機或其他情況,才關(guān)閉阻塞(受上面hangup_after_bridge和continue_on_fail影響)如果hangup_after_bridge掛機,那么都結(jié)束,如果b不在線或沒正常接聽,continue_on_fail=true=true那么繼續(xù)往下走。<action application="answer"/> # 如果B接聽失敗,freeswitch自動接通<action application="sleep" data="1000"/><action application="bridge" data="loopback/app=voicemail:default ${domain_name} ${dialed_extension}"/> # 用戶無法接聽后,進(jìn)入當(dāng)前用戶語音信箱,進(jìn)行留言。 # voicemail是一個app,default是其中一個配置</condition></extension><extension name="Local_Extension_Skinny"> # 思科是瘦客戶端,每撥一個號碼都會傳到freeswitch。上面的就是胖客戶端,只有撥完號才會傳個freeswitch。<condition field="destination_number" expression="^(11[01][0-9])$"><action application="set" data="dialed_extension=$1"/><action application="export" data="dialed_extension=$1"/><action application="set" data="call_timeout=30"/><action application="set" data="hangup_after_bridge=true"/><action application="set" data="continue_on_fail=true"/><action application="bridge" data="skinny/internal/${destination_number}"/><action application="answer"/><action application="sleep" data="1000"/><action application="bridge" data="loopback/app=voicemail:default ${domain_name} ${dialed_extension}"/></condition></extension><extension name="group_dial_sales"> # directoryu中有sales,support,billing這些組。通過呼叫組號,來呼叫組內(nèi)全部,這些組是靜態(tài)加的,而之前的81系列是動態(tài)加的。<condition field="destination_number" expression="^2000$"><action application="bridge" data="${group_call(sales@${domain_name})}"/></condition></extension><extension name="group_dial_support"><condition field="destination_number" expression="^2001$"><action application="bridge" data="group/support@${domain_name}"/></condition></extension><extension name="group_dial_billing"><condition field="destination_number" expression="^2002$"><action application="bridge" data="group/billing@${domain_name}"/></condition></extension><!-- voicemail operator extension --># 語音信箱<extension name="operator"><condition field="destination_number" expression="^(operator|0)$"><action application="set" data="transfer_ringback=$${hold_music}"/><action application="transfer" data="1000 XML features"/></condition></extension><!-- voicemail main extension --> <extension name="vmain"><condition field="destination_number" expression="^vmain$|^4000$|^\*98$"><action application="answer"/><action application="sleep" data="1000"/><action application="voicemail" data="check default ${domain_name}"/> # 檢查voicemain,會進(jìn)入語音信箱應(yīng)用。</condition></extension><!--This extension is used by mod_portaudio so you can pa call sip:someone@example.commod_portaudio will pass the entire string to the dialplan for routing.--> 直接呼叫sip的地址<extension name="sip_uri"><condition field="destination_number" expression="^sip:(.*)$"><action application="bridge" data="sofia/${use_profile}/$1"/></condition></extension><!--start a dynamic conference with the settings of the "default" conference profile in conference.conf.xml--> 進(jìn)入會議<extension name="nb_conferences"><condition field="destination_number" expression="^(30\d{2})$"><action application="answer"/><action application="conference" data="$1-${domain_name}@default"/></condition></extension><extension name="wb_conferences"><condition field="destination_number" expression="^(31\d{2})$"><action application="answer"/><action application="conference" data="$1-${domain_name}@wideband"/></condition></extension><extension name="uwb_conferences"> # 32k語音<condition field="destination_number" expression="^(32\d{2})$"><action application="answer"/><action application="conference" data="$1-${domain_name}@ultrawideband"/></condition></extension><!-- MONO 48kHz conferences --> # 48k語音<extension name="cdquality_conferences"><condition field="destination_number" expression="^(33\d{2})$"><action application="answer"/><action application="conference" data="$1-${domain_name}@cdquality"/></condition></extension><!-- STEREO 48kHz conferences / Video MCU --> 視頻會議<extension name="cdquality_stereo_conferences"><condition field="destination_number" expression="^(35\d{2}).*?-screen$"> # 共享桌面-screen.<action application="answer"/><action application="send_display" data="FreeSWITCH Conference|$1"/><action application="set" data="conference_member_flags=join-vid-floor"/><action application="conference" data="$1@video-mcu-stereo"/></condition></extension><extension name="conference-canvases" continue="true"> # 都是通過canvases實現(xiàn)畫布來實現(xiàn)視頻會議,多方容屏<condition field="destination_number" expression="(35\d{2})-canvas-(\d+)"><action application="push" data="conference_member_flags=second-screen"/> # 進(jìn)來,把自己貼到哪個畫布<action application="set" data="video_initial_watching_canvas=$2"/> # 進(jìn)來看哪個畫布<action application="transfer" data="$1"/></condition></extension><extension name="conf mod"> # 會議管理員,只設(shè)置了標(biāo)志<condition field="destination_number" expression="^6070-moderator$"> <action application="answer"/><action application="set" data="conference_member_flags=moderator"/><action application="conference" data="$1-${domain_name}@video-mcu-stereo"/></condition></extension><!-- dial the FreeSWITCH conference via SIP--><extension name="freeswitch_public_conf_via_sip"><condition field="destination_number" expression="^9(888|8888|1616|3232)$"><action application="export" data="hold_music=silence"/><!--This will take the SAS from the b-leg and send it to the display on the a-leg phone.Known working with Polycom and Snom maybe others.--><!--<action application="set" data="exec_after_bridge_app=${sched_api(+4 zrtp expand uuid_display ${uuid} \${uuid_getvar(\${uuid_getvar(${uuid} signal_bond)} zrtp_sas1_string )} \${uuid_getvar(\${uuid_getvar(${uuid} signal_bond)} zrtp_sas2_string )} )}"/><action application="export" data="nolocal:zrtp_secure_media=true"/>--><action application="bridge" data="sofia/${use_profile}/$1@conference.freeswitch.org"/></condition></extension><!--This extension will start a conference and invite a group.At anytime the participant can dial *2 to bridge directly to the boss.All other callers are then hung up on.--><extension name="mad_boss_intercom"> # 瘋狂的老板,boss 控制會議<condition field="destination_number" expression="^0911$"><action application="set" data="conference_auto_outcall_caller_id_name=Mad Boss1"/><action application="set" data="conference_auto_outcall_caller_id_number=0911"/><action application="set" data="conference_auto_outcall_timeout=60"/><action application="set" data="conference_utils_auto_outcall_flags=mute"/><action application="set" data="conference_auto_outcall_prefix={sip_auto_answer=true,execute_on_answer='bind_meta_app 2 a s1 transfer::intercept:${uuid} inline'}"/><action application="set" data="sip_exclude_contact=${network_addr}"/><action application="conference_set_auto_outcall" data="${group_call(sales)}"/> # 整個組中都響應(yīng)呼叫<action application="conference" data="madboss_intercom1@default+flags{endconf|deaf}"/> # flags boss退出,整個會議結(jié)束</condition></extension><!--This extension will start a conference and invite a few of people.At anytime the participant can dial *2 to bridge directly to the boss.All other callers are then hung up on.--><extension name="mad_boss_intercom"><condition field="destination_number" expression="^0912$"><action application="set" data="conference_auto_outcall_caller_id_name=Mad Boss2"/><action application="set" data="conference_auto_outcall_caller_id_number=0912"/><action application="set" data="conference_auto_outcall_timeout=60"/><action application="set" data="conference_utils_auto_outcall_flags=mute"/><action application="set" data="conference_auto_outcall_prefix={sip_auto_answer=true,execute_on_answer='bind_meta_app 2 a s1 transfer::intercept:${uuid} inline'}"/><action application="set" data="sip_exclude_contact=${network_addr}"/><action application="conference_set_auto_outcall" data="loopback/9664"/><action application="conference" data="madboss_intercom2@default+flags{endconf|deaf}"/></condition></extension><!--This extension will start a conference and invite several people upon entering --><extension name="mad_boss"><condition field="destination_number" expression="^0913$"><!--These params effect the outcalls made once you join--><action application="set" data="conference_auto_outcall_caller_id_name=Mad Boss"/><action application="set" data="conference_auto_outcall_caller_id_number=0911"/><action application="set" data="conference_auto_outcall_timeout=60"/><action application="set" data="conference_utils_auto_outcall_flags=none"/><!--<action application="set" data="conference_auto_outcall_announce=say:You have been called into an emergency conference"/>--><!--Add as many of these as you need, These are the people you are going to call--><action application="conference_set_auto_outcall" data="loopback/9664"/><action application="conference" data="madboss3@default"/></condition></extension><!-- a sample IVR --><extension name="ivr_demo"><condition field="destination_number" expression="^5000$"><action application="answer"/><action application="sleep" data="2000"/><action application="ivr" data="demo_ivr"/></condition></extension><!-- Create a conference on the fly and pull someone in at the same time. --><extension name="dynamic_conference"># 參加會議,可以拉另外一個人進(jìn)來<condition field="destination_number" expression="^5001$"><action application="conference" data="bridge:mydynaconf:sofia/${use_profile}/1234@conference.freeswitch.org"/></condition></extension><extension name="rtp_multicast_page"> # 廣播應(yīng)用,撥打7243進(jìn)行廣播<condition field="destination_number" expression="^pagegroup$|^7243$"><action application="answer"/><action application="esf_page_group"/></condition></extension><!--Parking extensions... transferring calls to 5900 will park them in a queue.--># 有人在隊列,可以一個一個獲取出來<extension name="park"> # 隊列中加入一個人<condition field="destination_number" expression="^5900$"><action application="set" data="fifo_music=$${hold_music}"/><action application="fifo" data="5900@${domain_name} in"/></condition></extension><!--Parking pickup extension. Calling 5901 will pickup the call.--> # 隊列中去除一個人<extension name="unpark"><condition field="destination_number" expression="^5901$"><action application="answer"/><action application="fifo" data="5900@${domain_name} out nowait"/></condition></extension><!--Valet park retrieval, works with valet_park extension below.Retrieve a valet parked call by dialing 6000 + park number + #--> 有人呼叫進(jìn)來,放到一個位置,如果又有一個人進(jìn)來,那就放到同一個位置<extension name="valet_park"><condition field="destination_number" expression="^(6000)$"><action application="answer"/><action application="valet_park" data="valet_parking_lot ask 1 11 10000 ivr/ivr-enter_ext_pound.wav"/></condition></extension><!--Valet park 6001-6099. Blind x-fer to 6001, 6002, etc. to valet park the call.Dial 6001, 6002, etc. to retrieve a call that is already valet parked.After call is retrieved, park extension is free for another call.--><extension name="valet_park"><condition field="destination_number" expression="^((?!6000)60\d{2})$"><action application="answer"/><action application="valet_park" data="valet_parking_lot $1"/></condition></extension># 傳真<extension name="fax_receive"><condition field="destination_number" expression="^9178$"><action application="answer" /><action application="playback" data="silence_stream://2000"/><action application="rxfax" data="$${temp_dir}/rxfax.tif"/> # 收傳真<action application="hangup"/></condition></extension><extension name="fax_transmit"><condition field="destination_number" expression="^9179$"><action application="txfax" data="$${temp_dir}/txfax.tif"/> # 發(fā)傳真<action application="hangup"/></condition></extension># 視頻錄制和回放,older了。<extension name="video_record"><condition field="destination_number" expression="^9193$"><action application="answer"/><action application="record_fsv" data="$${temp_dir}/testrecord.fsv"/></condition></extension><extension name="video_playback"><condition field="destination_number" expression="^9194$"><action application="answer"/><action application="play_fsv" data="$${temp_dir}/testrecord.fsv"/></condition></extension># 回聲設(shè)置<extension name="delay_echo"> # 延遲回聲,通常用于測試<condition field="destination_number" expression="^9195$"><action application="answer"/><action application="delay_echo" data="5000"/></condition></extension><extension name="echo"><condition field="destination_number" expression="^9196$"><action application="answer"/><action application="echo"/></condition></extension><extension name="milliwatt"><condition field="destination_number" expression="^9197$"><action application="answer"/><action application="playback" data="{loops=-1}tone_stream://%(251,0,1004)"/></condition></extension><extension name="tone_stream"><condition field="destination_number" expression="^9198$"><action application="answer"/><action application="playback" data="{loops=10}tone_stream://path=${conf_dir}/tetris.ttml"/></condition></extension><!-- install zrtp_agent.lua into scripts (ZRTP == 9787) --><extension name="zrtp_enrollement"><condition field="destination_number" expression="^9787$"><action application="lua" data="zrtp_agent.lua"/></condition></extension><!--You will no longer hear the bong tone. The wav file is playing stating the call is secure.The file will not play unless you have both TLS and SRTP active.--><extension name="hold_music"><condition field="destination_number" expression="^9664$"/><condition field="${rtp_has_crypto}" expression="^(AES_CM_128_HMAC_SHA1_32|AES_CM_128_HMAC_SHA1_80)$"><action application="answer"/><action application="execute_extension" data="is_secure XML features"/><action application="playback" data="$${hold_music}"/><anti-action application="set" data="zrtp_secure_media=true"/><anti-action application="answer"/><anti-action application="playback" data="silence_stream://2000"/><anti-action application="execute_extension" data="is_zrtp_secure XML features"/><anti-action application="playback" data="$${hold_music}"/></condition></extension><extension name="laugh break"><condition field="destination_number" expression="^9386$"><action application="answer"/><action application="sleep" data="1500"/><action application="playback" data="phrase:funny_prompts"/><action application="hangup"/></condition></extension>dialplan三要素 extension dialplan類型 contextoriginate 內(nèi)部主動發(fā)起呼叫 originate user/1000 9196 # 9196 默認(rèn)是9196 XML default, 這句話指從freeswitch內(nèi)部主動給1000用戶發(fā)起會話,使用9196的dialplan規(guī)則。originate user/1000 &echo # 使用&標(biāo)識直接執(zhí)行application originate user/1000 echo inline # inline dialplan 是可以直接執(zhí)行application originate user/1000 playback:/1.wav,record:/2.wav inline # inline可以指定多個application;application之間用逗號分割,application與參數(shù)之間用冒號分割。uuid_transfer <uuid> playback:/1.wav,record:/2.wav inline # 將任意會話轉(zhuǎn)接到當(dāng)前dialplan中電話路由怎么走? 找context, 電話撥通使用user下的user_context指定,sip網(wǎng)關(guān)下,使用context指定。 transfer 被叫號碼 使用跟哪個dialplan(XML,enum,inline) context uuid_transfer <uuid> 9196 XML default呼叫字符串示例: originate user/1000 &bridge(user/1001) 先呼叫1000,再呼叫1001,那么1000和1001就通了 originate user/1000 1001 先呼叫1000,1001進(jìn)入路由表先查再撥 originate loopback/1000 1001 偽造假的channle,進(jìn)入dialplan先查再撥。bridge 不能answer,1000-->freeswitch bridge --> 1001,answer是給freeswitch的。 conference 會議自己內(nèi)部有answer5、directory 用戶管理
default目錄下,配置用戶,新增,修改
每個用戶中,可以修改默認(rèn)密碼,不然會被警告
6、chatplan 聊天模塊
注冊:是用于被叫用的,用于freeswitch找到被叫用戶。主叫其實不需要。
7、api 和 app
api:freeswitch 命令
app: application
7.1 APP
使用fs_client
8、呼叫字符串
sofia 電話@網(wǎng)關(guān) &echo
user/1000 # user 類型,1000 用戶,呼叫1000用戶 sofia/gateway/gw1/186xxxxxx # sofia 網(wǎng)關(guān)類型, gw1網(wǎng)關(guān)名稱, 186 電話;注冊網(wǎng)關(guān) sofia/external/186xxxx@192.15.. external profile名稱;這是中級對接 sofia/internal/186xxx@ip:port 不同于external,是端口不一致 sofia/internal/1000%10.0.0.1 # %后接域,通過域找號碼 user/1000@10.0.0.1 originate freeswitch內(nèi)部發(fā)起呼叫 originate user/1000 &echo originate user/1000 &bridge(user/10001)bridge 橋app
<action application='bridgge' data='user/1000'/>conference 會議
conference 3000 dial user/1000 originate {local_addr=192.168.1.1,local_port=4444,remote_addr=xxx,remote_port=xxxx,codec=PCMU,pt=0,rate=8000 }rtp &playback(tmp/xxx)show endpoint 查看呼叫字符串
文件:directory/default.xml
<params><param name="dial-string" value="{^^:sip_invite_domain=${dialed_domain}:presence_id=${dialed_user}@${dialed_domain}}${sofia_contact(*/${dialed_user}@${dialed_domain})},${verto_contact(${dialed_user}@${dialed_domain})}"/><!-- These are required for Verto to function properly --><param name="jsonrpc-allowed-methods" value="verto"/><!-- <param name="jsonrpc-allowed-event-channels" value="demo,conference,presence"/> --> </params>origination_caller_id_number=1100 設(shè)置主叫號碼,freeswitch默認(rèn)為00000000
origination_caller_id_name = 'gaofei' 設(shè)置主叫名稱
hupall 關(guān)閉所有的電話
9、安裝部署
git clone xxx.git
make samples # 編譯默認(rèn)配置文件
/user/local/freeswitch/bin/freeswitch -nonat -nc # 啟動freeswitch,nonat無網(wǎng)絡(luò),nc后臺啟動(用于生產(chǎn)環(huán)境)
status 查看狀態(tài)
|------------------------------------------------------------ UP 0 years, 0 days, 0 hours, 0 minutes, 22 seconds, 794 milliseconds, 26 microseconds FreeSWITCH (Version 1.10.7 883d2cb662 64bit) is ready 0 session(s) since startup 0 session(s) - peak 0, last 5min 0 # peak表示最大多少個session, last 5min 最后5分鐘多少個 0 session(s) per Sec out of max 30, peak 0, last 5min 0 1000 session(s) max # 默認(rèn)支持多少個session min idle cpu 0.00/85.44 |-----------------------------------------------------------sofia status 查看sofia當(dāng)前的狀態(tài)
!-----------------------------Name Type Data State =================================================================================================external-ipv6 profile sip:mod_sofia@[::1]:5080 RUNNING (0)192.168.123.197 alias internal ALIASEDexternal profile sip:mod_sofia@*.*.*.*:5080 RUNNING (0)external::example.com gateway sip:joeuser@example.com NOREGinternal-ipv6 profile sip:mod_sofia@[::1]:5060 RUNNING (0)internal profile sip:mod_sofia@*.*.*.*:5060 RUNNING (0) 4 profiles 1 alias !------------------------------10、啟動
10.1 生產(chǎn)環(huán)境啟動
/usr/local/freeswitch/bin/freeswitch -u freeswitch -g freeswitch -nonat -ncwait
/usr/local/freeswitch/bin/fs_cli 進(jìn)行控制臺介入
10.2 測試環(huán)境啟動
/usr/local/freeswitch/bin/freeswitch
11、變量
freeswitch中有一套變量規(guī)則,調(diào)用變量使用${變量名}, ${方法名()}
在xml配置文件中,可以通過set來進(jìn)行變量的設(shè)置
變量相關(guān)命令:
eval $${變量名} # 獲取全局變量值,eg:eval $${sound_prefix}
show interfaces # 獲取全局接口
global_setvar 變量名=變量值 設(shè)置全局變量
global_getvar 變量名 獲取全局變量值
11.1 主叫配置變量
在extension 下的 condition 中,對于 主叫配置變量 來說,可以直接使用了,并不用$符號來修飾。
username dialplan caller_id_name 主叫名稱 caller_id_number 主叫號碼 callee_id_name callee_id_number network_addr ani aniii rdnis destination_number source uuid context11.2 普通變量
Freeswitch的變量基本上可以用 ${變量名} 來表示。通過app-set來進(jìn)行變量的賦值,創(chuàng)建。
注:app set中左側(cè)變量名也不需要使用$符號,右側(cè)需要。
上圖中,$1表示正則匹配到的第一個括號中的值。
11.3 預(yù)處理變量
預(yù)處理變量的引用,使用$${變量名}來表示,他們不是真正的變量,而是只讀的變量。它們由一個FreeSWITCH配置文件(/usr/local/freeswitch/conf/vars.xml)分配,然后在啟動時替換。
注:如果修改了vars.xml里的預(yù)處理變量值,你必須重啟FreeSWITCH才能讓它生效(只是重載XML配置而沒有重啟FreeSWITCH是不夠的)。
此類變量有(還有更多):
Hostname local_ip_v4 local_mask_v4 local_ip_v6 switch_serial base_dir recordings_dir sound_prefix sounds_dir conf_dir log_dir run_dir db_dir mod_dir htdocs_dir script_dir temp_dir grammar_dir certs_dir storage_dir cache_dir core_uuid zrtp_enabled nat_public_addr nat_private_addr nat_type12 撥打流程
12.1 originate user/1000 &echo
查找user/1000,直接呼叫用戶,并執(zhí)行app echo
12.2 originate user/1000 9196 XML default
查找user/1000, 直接呼叫用戶,并執(zhí)行 路由表,context 為default,diaplan為XML,extension-destination_number=9196(也代表extension)的內(nèi)容。
注:originate 參數(shù)列表
其實call_url 這兒user/1000, fs會去用戶下找context=default。然后去dialplan中找context值為default的路由。
如果call_url為一個sip路徑,那么需要去找對應(yīng)sip_profiles/internal 或者 external,在里面找對應(yīng)的context。如下:sofia status中查找data路徑,然后對應(yīng)profile的name,再去dialplan中找context值為public的路由。
總結(jié)
以上是生活随笔為你收集整理的【Freeswitch从入门到精通】二、初识Freeswitch的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 三天学会MySQL - MySQL数据库
- 下一篇: C语言生成n个随机坐标,c语言如何生成随