
要明白怎么配置,首先你需要明白180和183的來(lái)龍去脈。另外,你自己還要知道你要干什么。
“什么?我提的問(wèn)題我當(dāng)然知道我要干什么!” 也許你會(huì)這樣咆哮,也許你真的知道你要干什么,但是,我不知道。所以,在你得到有效的回答之前,你得先學(xué)會(huì)讓我知道。
好了,先不爭(zhēng)論這個(gè),我們來(lái)說(shuō)說(shuō)什么是180和183。
在SIP通信中,所有1開(kāi)頭的響應(yīng)叫臨時(shí)響應(yīng),常見(jiàn)的有100,180和183。這些響應(yīng)一般是對(duì)INVITE請(qǐng)求的響應(yīng)。使用場(chǎng)景是這樣的:主叫用戶(hù)(A)在發(fā)起一個(gè)呼叫時(shí),會(huì)向被叫用戶(hù)(B)發(fā)起一個(gè)INVITE請(qǐng)求,被叫用戶(hù)在收到這個(gè)請(qǐng)求后,會(huì)給主叫用戶(hù)一個(gè)響應(yīng),一般的響應(yīng)流程是回100,緊接著回180,或(和)183。
INVITE
A <-----------> B
180/183
其中,100主要是信令層的,它的作用是B告訴A它收到了A的INVITE請(qǐng)求。關(guān)于它的作用實(shí)際也可以講一講的,但那就到信令的底層了,大家一般可以不用關(guān)注。
180/183的作用是B告訴A,你可以聽(tīng)回鈴音了。
什么是回鈴音?這要從更早的模擬電話(huà)時(shí)代講起。A給B打電話(huà),B的話(huà)機(jī)會(huì)振鈴,同時(shí)A的話(huà)機(jī)回放回鈴音(嘟嘟聲),這樣,A就知道B的話(huà)機(jī)振鈴了。
所以,回鈴音是模擬電話(huà)時(shí)代的事情,它的作用就是給A一個(gè)提示,對(duì)方的電話(huà)正在振鈴,這樣,A就可以放心地等待B接電話(huà)。當(dāng)然,隨著技術(shù)的進(jìn)步和時(shí)代的發(fā)展,回鈴音也在進(jìn)步,典型地,除了嘟嘟聲以外,電信運(yùn)營(yíng)商也會(huì)利用這段等待的時(shí)間給用戶(hù)放一些音樂(lè),甚至是廣告,反正閑著也是閑著。這些音樂(lè)或廣告就稱(chēng)為彩鈴,這些是在A與B正式通話(huà)前播放的,因此不對(duì)A收費(fèi)。但是由于彩鈴也是資源,因此運(yùn)營(yíng)商可能會(huì)對(duì)B收費(fèi)(B放音樂(lè)提高自己的逼格,或者放廣告提升自己的形象甚至獲取商業(yè)利益,收費(fèi)也是有道理的)。
到了SIP時(shí)代,就需要在SIP中描述這些回鈴音或彩鈴,這些回鈴音或彩鈴是真正的聲音數(shù)據(jù),稱(chēng)為媒體(Media)。但為了將它與真正的媒體(即A與B真正的通話(huà)數(shù)據(jù))相區(qū)別,將其為早期媒體,即Early Media。
SIP的全稱(chēng)是(Session Initiation Protocol,即會(huì)話(huà)初始協(xié)議),它僅僅是完成會(huì)話(huà)的協(xié)商,但是實(shí)際的媒體如何傳輸卻需要另外一個(gè)協(xié)議來(lái)協(xié)商,負(fù)責(zé)描述媒體的協(xié)議稱(chēng)為SDP(Session Description Protocol),即會(huì)話(huà)描述協(xié)議。不過(guò),SDP寄生在SIP中,典型地,它寄生在INVITE消息和183消息中。當(dāng)A向B發(fā)起呼叫時(shí),它需要把自己的SDP放到INVITE消息中發(fā)給B,同時(shí),B在183消息中放入自己的SDP,回送給A。當(dāng)雙方都知道對(duì)方的SDP后,真正的媒體數(shù)據(jù)就可以傳輸了,這時(shí),A才聽(tīng)到B的Early Media。
為了幫助大家理解SDP,我們?cè)龠M(jìn)一步。假設(shè)B接聽(tīng)了電話(huà),B會(huì)響應(yīng)200 OK消息,該消息也帶了SDP(可能跟183中的相同也可能不同),用于建立A與B真正的通話(huà),畢竟A給B打電話(huà)是為了跟B通話(huà),而不是為了聽(tīng)Early Media中的音樂(lè)或廣告。
所以,不管是183中的SDP,還是200 OK中的SDP,都是為了建立媒體服務(wù)的。區(qū)別只是一個(gè)叫Early Media,另一個(gè)叫Media。其實(shí)Early Media和Media差別除了一個(gè)是廣告一個(gè)是真正的B的聲音外,差別也不大,非要說(shuō)差別的話(huà),那就是運(yùn)營(yíng)商的收費(fèi)方面有差別,因?yàn)镋arly Media是不收費(fèi)的。
也許有人開(kāi)始嫌我羅嗦了,但是,我確信,有些人真的不是從根本上理解我上面說(shuō)的這些,包括一些開(kāi)始嫌我羅嗦的人。不信,耐心點(diǎn)接著往下看。
好吧,183和200好像有點(diǎn)懂了,那180和183又有什么區(qū)別呢?
180和183之間就差個(gè)3。
你說(shuō)我開(kāi)玩笑?好吧,這些狗屎都是RFC定義的,RFC就沒(méi)定義他們的區(qū)別!
不過(guò),RFC劃出道來(lái)大家就要走啊,因此,大家就都按照自己的理解實(shí)現(xiàn)了180和183。
現(xiàn)在最流行的實(shí)現(xiàn)方式是:180不帶SDP,183帶SDP。FreeSWITCH也遵守這種約定。
所以,180與183的區(qū)別不是3,也不是其它的,關(guān)鍵是看它們帶不帶SDP,即180也可以帶SDP,183也可以不帶SDP。為了防止思維混亂,我們下面認(rèn)為180不帶SDP,而183帶SDP。如上面所說(shuō),這些符合絕大多數(shù)人的思維。
那么,帶SDP的183我們上面講過(guò)了,180不帶SDP有什么用呢?
我們上面不是說(shuō)到時(shí)代進(jìn)步了嗎?SIP終端屬于智能終端,比以前的模擬電話(huà)可先進(jìn)多了。其中的一點(diǎn)就是它能區(qū)別180和183。如果A的SIP終端收到183,它就協(xié)商媒體,將B端發(fā)過(guò)來(lái)的Early Media在自己的揚(yáng)聲器里放出來(lái);但如果收到的是180,沒(méi)有SDP就沒(méi)法協(xié)商媒體,因此,B就沒(méi)法給A發(fā)Early Media了。怎么辦,總不能讓主叫用戶(hù)干等著啊,所以,A的話(huà)機(jī)在這種情況下能自己產(chǎn)生一個(gè)回鈴音,或任何用戶(hù)在A話(huà)機(jī)上設(shè)置的音樂(lè)。
好吧,到這里,不管你有沒(méi)有理解,反正我把該說(shuō)的都說(shuō)了。
那么,言歸正傳,如何在FreeSWITCH中配置回180還是183呢?
FreeSWITCH是一個(gè)多功能的SIP服務(wù)器,在此,為了簡(jiǎn)單起見(jiàn),我們先把它當(dāng)成一個(gè)普通的SIP UA。比方說(shuō),它就是B。
在FreeSWITCH內(nèi)部,F(xiàn)reeSWITCH的行為靠一些稱(chēng)為Application的功能函數(shù)控制的。當(dāng)一個(gè)呼叫到來(lái)時(shí),F(xiàn)reeSWITCH會(huì)查找撥號(hào)計(jì)劃(Dialplan)來(lái)決定執(zhí)行哪些Application。如,下面的Dialplan,當(dāng)一個(gè)呼叫到來(lái)時(shí),它首先執(zhí)行Answer,給對(duì)方回200 OK,然后執(zhí)行playback給對(duì)方放一段聲音(從聲音文件中讀。,然后掛機(jī)。
如果你自己測(cè)試這段Dialplan,就會(huì)發(fā)現(xiàn),F(xiàn)reeSWITCH不會(huì)回180也不會(huì)回183,而是直接回200。這里,answer想當(dāng)于B摘機(jī)應(yīng)答,在SIP中就直接回200。
當(dāng)然,“紙上得來(lái)終覺(jué)淺,絕知此事要躬行。” 至于真是是不是這樣你還自己自己去試,學(xué)習(xí)SIP最好的辦法不是看RFC,而是照著我說(shuō)的這些(以及《FreeSWITCH權(quán)威指南上的例子》)自己抓包去看。如果試著不對(duì)的話(huà),也不要怪我,也許是你的Dialplan里邊東西太多,在這幾個(gè)Application前執(zhí)行了你不知道的其它的Application。
好吧,那怎么讓它回183呢?
在上面的Dialplan中把a(bǔ)nswer那一行去掉,就回183了。
為什么呢?
因?yàn)閜layback的作用是向A播放一段聲音,但,在B向A發(fā)送聲音前要建立媒體通道。如果有answer,F(xiàn)reeSWITCH會(huì)發(fā)送200 OK,帶SDP建立媒體通道。如果沒(méi)有answer,那么FreeSWITCH就會(huì)發(fā)送183,帶SDP建立媒體通道,而這時(shí),hello.wav的媒體內(nèi)容就成了Early Media。
所以,送不送183就看你在answer前還是answer后執(zhí)行playback。
那么180呢?也很簡(jiǎn)單,那就是在發(fā)送180前執(zhí)行一個(gè) ring_ready,即:
在上面的例子中,如果你抓包,就可以看到180,但你很可能聽(tīng)不到回鈴音。原因很簡(jiǎn)單,answer執(zhí)行的太快了。嘗試在ring_ready和answer之間停頓一下,就可以聽(tīng)到回鈴音了。下面例子中的sleep可以在發(fā)送完180后暫停2秒鐘(2000毫秒)再發(fā)送200 OK:
我們已經(jīng)知道怎么讓FreeSWITCH發(fā)180還是183了,問(wèn)題解決了嗎?
顯然沒(méi)有,我知道你在實(shí)際應(yīng)用中沒(méi)這么簡(jiǎn)單。我們?cè)谶@里把FreeSWITCH當(dāng)成了B,但實(shí)際你希望FreeSWITCH是FreeSWITCH,B是B。什么意思呢?FreeSWITCH實(shí)際上是一個(gè)B2BUA,它是一個(gè)中間人,你希望的拓?fù)浣Y(jié)構(gòu)是這樣的:
A <--------> FreeSWITCH <---------> B
哎呀呀,你看你看,我第一句話(huà)說(shuō)中了吧,針對(duì)你提的問(wèn)題,答案遠(yuǎn)沒(méi)你想象的簡(jiǎn)單,F(xiàn)在,我們需要列出(猜出)你想要的各種情況了。
好吧,就算這回我猜中了,繼續(xù)往下說(shuō)。
中間人也是不好當(dāng)?shù),因(yàn),他可以有N種不同的策略。至于使用哪種策略,看B的心情,也要看FreeSWITCH的心情。啊,說(shuō)白了,又是沒(méi)有標(biāo)準(zhǔn)答案。所以你還是要把你想要的告訴我。如果你不告訴我,我就得猜,或者把所有N種可能的情況都告訴你。
首先,我們先看一種熟悉的情況。FreeSWITCH可以假裝它就是B,這樣,配置方法跟上面講的基本一樣,只是它在假裝后還要假戲真做,要用bridge這個(gè)Application再去呼叫B,并把電話(huà)接通。
所以在上面的配置中,至于是回180還是183,配置方式跟上面講的一模一樣,就沒(méi)必要多說(shuō)了。
其次,F(xiàn)reeSWITCH心情好,想聽(tīng)聽(tīng)B的意見(jiàn)。如果它即不執(zhí)行ring_ready,也不執(zhí)行answer,而是直接用bridge去呼叫B。
這種情況其實(shí)也簡(jiǎn)單,那就是,如果B向FreeSWITCH回復(fù)180,F(xiàn)reeSWITCH就向A回180;如果B回183,F(xiàn)reeSWITCH就向A回183。這種情況其實(shí)就相當(dāng)于FreeSWITCH不存在,所有消息都是透明的。(不過(guò),要記住:FreeSWITCH是一個(gè)B2BUA,即它是一個(gè)中間人,它不會(huì)直接拿B回給它的180或183消息“轉(zhuǎn)”給A,而是自己新產(chǎn)生了一個(gè)180或183消息回給A。當(dāng)然,也許你不關(guān)心這個(gè),但你說(shuō)得越不清楚,我越累啊,要不然人家還會(huì)說(shuō)我的回答不嚴(yán)謹(jǐn)呢。或者,萬(wàn)一我猜錯(cuò)的你問(wèn)的意思呢?)
再次,F(xiàn)reeSWITCH跟B這兩天不大對(duì)付,什么事情都擰把。B回180,F(xiàn)reeSWITCH就回183,B回183,F(xiàn)reeSWITCH就回180。
好吧,看起來(lái)是越來(lái)越復(fù)雜了。又是兩種情況。
先看B回180的情況。FreeSWITCH要想給A回一個(gè)183,由于B的180中不帶媒體,F(xiàn)reeSWITCH就要“造”一個(gè)媒體出來(lái),因此,它想了這種一種辦法,在bridge之前造一個(gè)媒體:
由于在執(zhí)行bridge之前還沒(méi)有B,因此FreeSWITCH不知道什么時(shí)候B回180還是183。通過(guò)在bridge之前使用set設(shè)置一個(gè)變量(ringback),實(shí)際上相當(dāng)于FreeSWITCH給bridge下了一個(gè)套,到了bridge階段,不管你什么時(shí)候B回180,F(xiàn)reeSWITCH都會(huì)向A播放事先“造”好的回鈴音ring.wav。當(dāng)然,F(xiàn)reeSWITCH要向A發(fā)送媒體前要先用183建立媒體通道,這就完成了180到183的轉(zhuǎn)換。
所以,這也是FreeSWITCH設(shè)計(jì)精巧之處——同是一個(gè)bridge,通過(guò)一個(gè)ringback變量改變了它的行為。
再看183變180的情況。
如果B向FreeSWITCH回了183,F(xiàn)reeSWITCH要向A回180,那就不能把媒體信息送給A。所以,實(shí)現(xiàn)也很簡(jiǎn)單,還是一個(gè)簡(jiǎn)單的bridge,只是,把B送來(lái)的Early Media忽略掉就行了:
跟set不同。set是一個(gè)Application,它作用于當(dāng)前的Channel,即A那一個(gè)Channel(那時(shí)候還沒(méi)有B)。而{ignore_early_media=true}這種語(yǔ)法,在建立B端的Channel的同時(shí),將ignore_early_media作用于B。再?gòu)?qiáng)調(diào)一次,F(xiàn)reeSWITCH是一個(gè)B2BUA,因此A跟B間的通話(huà)要產(chǎn)生兩個(gè)Channel,即所謂的a-leg和b-leg。
在建立B通道的時(shí)候,ignore_early_media也是給bridge下了一個(gè)套。即不管什么時(shí)候B回了183,忽略它。由于我們選擇了忽略,因此,為了讓A仍能聽(tīng)到回鈴音,我們用ring_ready在bridge前送一個(gè)180。嚴(yán)格來(lái)說(shuō),它不是183變180,因?yàn)镕reeSWITCH以收到183前就已經(jīng)送出了180,但是,如果你不趴在FreeSWITCH內(nèi)部看,誰(shuí)知道什么時(shí)候變得呢?
N種情況講了N種了,永遠(yuǎn)都會(huì)有N+1。既然FreeSWITCH位于中間,那它能不能把B發(fā)過(guò)來(lái)的廣告(彩鈴)換成它自己的廣告呢?能是能,但我不教你怎么做。不過(guò),不幸的是,如果你不是特別笨的話(huà),我上面已經(jīng)教會(huì)你了……
讀到這里,你認(rèn)為這個(gè)問(wèn)題好答嗎?