1關(guān)于VoIP中CDR處理的背景介紹
在PSTN時(shí)代,運(yùn)營(yíng)商的CDR計(jì)費(fèi)本身已經(jīng)存在了,隨著IP語(yǔ)音的突飛猛進(jìn),包括現(xiàn)在基于VoLTE語(yǔ)音的部署,計(jì)費(fèi)的模式也逐漸發(fā)生了變化。在目前最新的VoLTE網(wǎng)絡(luò)中,因?yàn)橐粋(gè)SIP呼叫跨越了很多的節(jié)點(diǎn)路徑,計(jì)費(fèi)的流程更加長(zhǎng)一些,涉及的各種延遲也更多一些,比較重要的參數(shù)例如,Post-dial delay(PDD或者SRD)。這些延遲會(huì)影響計(jì)費(fèi)的時(shí)長(zhǎng)和話單的準(zhǔn)確性。另外,每個(gè)國(guó)家可能因?yàn)榄h(huán)境的不同對(duì)CDR參數(shù)設(shè)置也有不同的要求,還有很多場(chǎng)景中需要緊急電話服務(wù)的話,電話系統(tǒng)必須需要支持規(guī)范的呼叫格式和對(duì)呼叫進(jìn)行不同的定義。

此圖例以及以下圖例均來(lái)自于互聯(lián)網(wǎng)資源
因?yàn)樵赟IP網(wǎng)絡(luò)中,根據(jù)不同的SIP初始請(qǐng)求所產(chǎn)生的事務(wù)和dialog也可能完全不同,因此請(qǐng)求的不同也產(chǎn)生了不同的CDR消息記錄。這些請(qǐng)求可以是:INVITE,REGISTER,SUBSCRIBE,OPTIONS,MESSAGE和INFO。

這些請(qǐng)求的返回?cái)?shù)據(jù)都需要根據(jù)不同的請(qǐng)求生成一個(gè)完整的CDR記錄。這些數(shù)據(jù)的處理相對(duì)就復(fù)雜很多,需要專門(mén)的CDR服務(wù)器做解析生成。另外,在CDR生成時(shí),SIP dialog和事務(wù)都有各自的會(huì)話結(jié)束方式,這又增加了CDR生成的邏輯流程,它們通過(guò)bCDR和cCDR實(shí)現(xiàn)基礎(chǔ)CDR和合并CDR的生成,并且創(chuàng)建了dialog和事務(wù)的連接。

研究人員Tamás Tóthfalusi 發(fā)布了針對(duì)VoLTE的CDR生成做了比較詳細(xì)的分享說(shuō)明和關(guān)于CDR生成的研究成果。在其論文中比較詳細(xì)說(shuō)明了VoLET環(huán)境中SIP呼叫和CDR生成的研究。讀者可以參考其論文做進(jìn)一步的研究。
3GPP針對(duì)CDR有著非常詳細(xì)的規(guī)范說(shuō)明(ETSI TS 132 240),包括了漫游,在線費(fèi)用,離線費(fèi)用,呼叫和服務(wù)費(fèi)用等非常詳細(xì)的說(shuō)明。用戶如果有興趣的話,可以參考ETSI TS 132 240 3GPP規(guī)范做更多了解。

3GPP僅是針對(duì)網(wǎng)絡(luò)環(huán)境做的關(guān)于CDR的規(guī)范說(shuō)明,一些國(guó)家也專門(mén)發(fā)布了自己的運(yùn)營(yíng)商CDR規(guī)范說(shuō)明。在英國(guó)的CDR規(guī)范說(shuō)明中包括了固話,VoIP呼叫,移動(dòng)端和呼入呼叫(包括多腿呼叫費(fèi)用計(jì)算)。呼叫類型包括:
V = outbound voice call,
VOIP = Voice over IP call
D = Data/ISDN Call
C = Conference call
N = Inbound call (billable)
I = Standard Inbound call (usually not billable e.g. Raw call data)
U = Unanswered call
B = Busy Call
X = Call failed
M = Mobile call (made from mobile device)
G = GPRS Data
UK的CDR格式中規(guī)定了42個(gè)必要的呼叫參數(shù),其中部分參數(shù)是可選參數(shù)。

UK的CDR的標(biāo)準(zhǔn)的呼入格式規(guī)范:

除了標(biāo)準(zhǔn)的呼叫計(jì)費(fèi)以外,美國(guó)特別針對(duì)NG9-1-1呼叫的計(jì)費(fèi)也有規(guī)范說(shuō)明。此規(guī)范的目的是針對(duì)電話運(yùn)營(yíng)商提供的緊急呼叫中計(jì)費(fèi)的規(guī)范定義。為了滿足NG9-1-1的規(guī)范,很多呼叫的定義需要增加一些相應(yīng)的變量設(shè)置,例如對(duì)呼叫的定義和總呼叫時(shí)長(zhǎng)的變量設(shè)置和log事件:



通過(guò)以上簡(jiǎn)單的背景介紹,我們可以看到,生成一個(gè)完整的CDR是非常復(fù)雜的流程,這里需要數(shù)據(jù)業(yè)務(wù)數(shù)據(jù)的參與,同時(shí)需要滿足不同國(guó)家的規(guī)范的要求,并且有時(shí)如果電話系統(tǒng)需要緊急呼叫支持的話,系統(tǒng)配置也要具備一定的靈活性支持其業(yè)務(wù)要求。在第二個(gè)章節(jié),筆者將具體介紹OpenSIPS環(huán)境中的ACC模塊的存儲(chǔ)方式討論。
2OpenSIPS的Accounting 事件的存儲(chǔ)討論
為了幫助大家了解更多關(guān)于CDR計(jì)費(fèi)的基本概念和應(yīng)用的場(chǎng)景,筆者在前面章節(jié)介紹了一些關(guān)于CDR計(jì)費(fèi)的一些基本知識(shí),行業(yè)規(guī)范和幾個(gè)具體的應(yīng)用廣泛,其目的是幫助讀者了解CDR計(jì)費(fèi)以外的一些業(yè)務(wù)要求,在擴(kuò)充CDR支持能力時(shí)可以對(duì)其要求有比較充分的認(rèn)識(shí)。當(dāng)然,因?yàn)樗劫Y源有限,筆者也沒(méi)有能力對(duì)CDR處理有非常全面的了解,這里主要是提醒讀者了解更多關(guān)于簡(jiǎn)單CDR以外的內(nèi)容。
如果具體到今天核心的主題-SIP網(wǎng)絡(luò)環(huán)境或者OpenSIPS平臺(tái)的話,我們主要介紹關(guān)于OpenSIPS環(huán)境中ACC模塊的功能和其存儲(chǔ)方式。OpenSIPS的呼叫ACC模塊或者Accounting是一個(gè)非常重要的模塊。用戶在部署OpenSIPS時(shí)不可避免需要接觸到ACC模塊。ACC模塊涉及了幾個(gè)主要的概念,包括ACC event,ACC核心內(nèi)容和ACC后端存儲(chǔ)處理,其他ACC拓展參數(shù)支持和多腿呼叫的CDR記錄等幾個(gè)方面的內(nèi)容。
首先,我們需要明確的是ACC事件,ACC事件簡(jiǎn)單來(lái)說(shuō)就是事務(wù)處理狀態(tài)的事件,包括成功事務(wù)事件,失敗事務(wù)事件和丟失的事務(wù)事件等。這些事件和呼叫本身有緊密的聯(lián)系。我們前面的討論中也說(shuō)明,根據(jù)CDR規(guī)范,呼叫的事件都需要通過(guò)兩種方式進(jìn)行存儲(chǔ),一種是系統(tǒng)log的形式,另外一種是后端數(shù)據(jù)庫(kù)存儲(chǔ)的方式。OpenSIPS也同樣遵守這個(gè)規(guī)范。在前面的介紹中和以前的歷史文檔筆者都有說(shuō)明,在一個(gè)呼叫中需要通過(guò)事務(wù)處理和dialog處理,它們有著各自不同的處理方式,因此,在ACC需要支持事務(wù)和dialog實(shí)現(xiàn)對(duì)CDR的完整記錄。OpenSIPS的ACC模塊可以支持消息,事務(wù)和dialog。ACC中的消息包括多種消息,例如INVITE和BYE等。這些ACC的消息都可以通過(guò)log,數(shù)據(jù)庫(kù)存儲(chǔ),Radius和Events形式進(jìn)行存儲(chǔ)。筆者在后續(xù)的章節(jié)會(huì)分別介紹這些處理過(guò)程。
如果讀者不清楚關(guān)于事務(wù),會(huì)話和dialog的區(qū)別的話,建議首先閱讀筆者歷史文章: 再論SIP呼叫中的Call,Dialog和Transaction
在后續(xù)的關(guān)于CDR計(jì)費(fèi)時(shí)長(zhǎng)的討論中,我們將使用事務(wù)處理的概念,讀者一定要明確這個(gè)概念,以免混淆了整個(gè)計(jì)費(fèi)的設(shè)置。
- OpenSIPS可以對(duì)以上數(shù)據(jù)進(jìn)行后端存儲(chǔ)支持,支持的存儲(chǔ)方式包括:
- log,支持系統(tǒng)的log文件
- 數(shù)據(jù)庫(kù),支持MYSQL,PG和甲骨文數(shù)據(jù)庫(kù)等開(kāi)源數(shù)據(jù)庫(kù)
- AAA,支持Radius和Diameter(比較老的版本可能支持,讀者自己查閱官方文檔)
- EVI,event接口包括RabbitMQ,Datagram Event
關(guān)于Acc Scope的具體設(shè)置支持,和其他數(shù)據(jù)庫(kù)設(shè)置支持的細(xì)節(jié),讀者可以訪問(wèn)官方文檔做進(jìn)一步了解。需要注意,如果需要設(shè)置ACC 模塊時(shí),用戶需要經(jīng)過(guò)幾個(gè)流程設(shè)置:
- 加載模塊和相應(yīng)參數(shù)
- 為初始的INVITE請(qǐng)求設(shè)置ACC支持
- 為BYE請(qǐng)求設(shè)置ACC支持
- 為ACC設(shè)置支持丟失呼叫配置
3Accounting 事件的討論
在OpenSIPS的ACC模塊中,主要支持四種事件的狀態(tài),包括事務(wù)成功事件,成功的dialog事件,丟失的呼叫事件,失敗的事務(wù)事件。

在以上的事件狀態(tài)中,其他幾種事件相對(duì)比較容易處理,丟失的呼叫事件是一個(gè)相對(duì)比較困難處理的事件。在丟失呼叫的事件中包括兩種狀態(tài),一種是丟失的事件,另外一種是成功的事件。因此,如果做CDR處理時(shí)需要同時(shí)記錄這兩種事件對(duì)應(yīng)不同的UAS。我們經(jīng)?赡苡龅,如果是一個(gè)fork呼叫或者按續(xù)呼叫過(guò)程中,如果第一個(gè)呼叫失敗以后會(huì)繼續(xù)呼叫,繼續(xù)對(duì)第二個(gè)目的地進(jìn)行按續(xù)呼叫的流程。這種丟失呼叫的事件需要特別留意,否則CDR統(tǒng)計(jì)結(jié)果就會(huì)產(chǎn)生錯(cuò)誤。
這里提醒讀者,在處理這些事件中,成功的事務(wù)處理和失敗事務(wù)處理會(huì)存儲(chǔ)到同一ACC的表中,丟失的呼叫事件則會(huì)存儲(chǔ)到missed call 的表中。當(dāng)然,用戶也可以自己修改表名稱方便自己的部署環(huán)境。
4OpenSIPS中關(guān)于多腿呼叫的計(jì)費(fèi)討論
計(jì)費(fèi)是一個(gè)非常重要的功能,無(wú)論是使用開(kāi)源媒體服務(wù)器,例如Asterisk還是FreeSWITCH,或者使用SIP軟交換服務(wù)器,例如OpenSIPS和Kamailio或者很多商業(yè)IPPBX。很多用戶忽略了一個(gè)非常復(fù)雜或非常細(xì)節(jié)的問(wèn)題,那就是在呼叫經(jīng)過(guò)多次轉(zhuǎn)接或者?恳院蟮挠(jì)費(fèi)處理。通常的CDR中,我們僅簡(jiǎn)單計(jì)算了從呼叫方到被呼叫方的總時(shí)長(zhǎng)。特別是在企業(yè)IPPBX的應(yīng)用場(chǎng)景中,我們僅考慮了呼入方到一個(gè)內(nèi)部分機(jī)之間的呼叫時(shí)長(zhǎng),但是,讀者是否考慮過(guò)如果呼入以后涉及了電話盲轉(zhuǎn)或者詢轉(zhuǎn),或者執(zhí)行了一個(gè)分機(jī)隨行以后繼續(xù)呼叫一個(gè)外部電話號(hào)碼或者長(zhǎng)途固定電話。如果涉及到了其他額外呼叫流程的話,嚴(yán)格來(lái)說(shuō),這些呼叫都需要分段計(jì)費(fèi),有的呼叫可能是不計(jì)費(fèi)的(例如呼入)并且通過(guò)分段計(jì)費(fèi)最后聚會(huì)成一個(gè)完整的CDR計(jì)費(fèi)。不幸的是,很多的IPPBX并沒(méi)有進(jìn)行這么詳細(xì)的處理,僅簡(jiǎn)單籠統(tǒng)地計(jì)算了一個(gè)呼叫的總時(shí)長(zhǎng)。因此,這樣的處理結(jié)果不是一個(gè)正確的CDR計(jì)費(fèi)流程,只能算是一個(gè)CDR統(tǒng)計(jì),它不能作為話單結(jié)算數(shù)據(jù)。在如下示例中,按照目前正常的計(jì)費(fèi)模式,如果A呼叫B,B然后轉(zhuǎn)接到C端手機(jī)的話,從A到B是免費(fèi)的,但是,從B到C端可能是付費(fèi)的,這里涉及了誰(shuí)將為B到C支付問(wèn)題。如果按照標(biāo)準(zhǔn)的CDR計(jì)費(fèi)的話,A應(yīng)該對(duì)C端付費(fèi),事實(shí)上這完全是一種錯(cuò)誤的計(jì)費(fèi)方式。因此,針對(duì)復(fù)雜業(yè)務(wù)場(chǎng)景中,多腿分段計(jì)費(fèi)是一個(gè)必要的計(jì)費(fèi)方式。為了支持多腿呼叫,OpenSIPS支持多腿計(jì)費(fèi)時(shí)需要重新創(chuàng)建一個(gè)新的acc_new_leg()進(jìn)行支持。

作為一個(gè)運(yùn)營(yíng)級(jí)的SIP軟交換,OpenSIPS和Kamailio在早期版本并沒(méi)有真正實(shí)現(xiàn)多腿CDR的支持。在后期的OpenSIPS的發(fā)布版本中開(kāi)始支持了多腿CDR記錄支持。通過(guò)多腿計(jì)費(fèi)保證了CDR的準(zhǔn)確性和完整性。OpenSIPS在多腿CDR支持時(shí)增加了一個(gè)對(duì)中間跳板的記錄,分別對(duì)分段處理進(jìn)行存儲(chǔ)支持。正常的CDR僅保存呼叫源和最終目的地的存儲(chǔ)。OpenSIPS通過(guò)支持多腿CDR實(shí)現(xiàn)了非常完整準(zhǔn)確的CDR計(jì)費(fèi)。這里提醒讀者,在ACC中,事務(wù)記錄中的duration是為空的,在CDR記錄中則包含了duration值。

在數(shù)據(jù)庫(kù)生成的示例數(shù)據(jù)如下,包括了用戶1到用戶2,用戶2到用戶3的完整的多腿CDR記錄。

5OpenSIPS環(huán)境中關(guān)于BYE丟失的處理
在呼叫過(guò)程中,因?yàn)榫W(wǎng)絡(luò)原因或者其他的終端原因,很多情況下我們會(huì)遇到呼叫失敗的問(wèn)題。呼叫失敗不僅僅會(huì)影響呼叫方的體驗(yàn),同時(shí)也影響計(jì)費(fèi)結(jié)算結(jié)果。在一些呼叫中,我們經(jīng)常會(huì)收到?jīng)]有BYE請(qǐng)求返回的問(wèn)題,或者叫BYE消息丟失的問(wèn)題。沒(méi)有BYE消息的話,CDR計(jì)費(fèi)就產(chǎn)生錯(cuò)誤。這對(duì)CDR生成是一個(gè)非常大的挑戰(zhàn)。在以前的歷史文檔中,我們討論了dialog狀態(tài)和計(jì)費(fèi)啟動(dòng)的機(jī)制,讀者可以參考OpenSIPS中的dialog使用和計(jì)費(fèi)的說(shuō)明:
OpenSIPS學(xué)習(xí)筆記-Dialog的五種狀態(tài)及配置示例
研究人員Dimitris Geneiatakis在早期發(fā)表的關(guān)于CDR算法討論-A Mechanism for Ensuring the Validity and Accuracy of the Billing Services in IP Telephony中對(duì)CDR做了最簡(jiǎn)單的描述:

這里可以看出,BYE消息是計(jì)費(fèi)計(jì)算的一個(gè)基準(zhǔn)數(shù)。

有時(shí),如果沒(méi)有及時(shí)處理BYE消息丟失的問(wèn)題的話,可能CDR時(shí)長(zhǎng)就會(huì)不斷增加。本來(lái)一個(gè)呼叫可能已經(jīng)在3分鐘內(nèi)結(jié)束了,但是因?yàn)闆](méi)有收到BYE消息,最后通話時(shí)長(zhǎng)可能是10分鐘或者20分鐘甚至于更長(zhǎng)時(shí)間。這樣計(jì)費(fèi)就會(huì)產(chǎn)生很多問(wèn)題。如果出現(xiàn)了丟失BYE消息以后,系統(tǒng)平臺(tái)應(yīng)該有一定的機(jī)制來(lái)及時(shí)正確執(zhí)行掛機(jī),保證其CDR計(jì)費(fèi)出現(xiàn)問(wèn)題。另外,如果系統(tǒng)平臺(tái)對(duì)并發(fā)呼叫有限制的話,丟失了BYE消息以后,這樣的限制設(shè)置可能會(huì)產(chǎn)生錯(cuò)誤的結(jié)果。
目前,在SIP網(wǎng)絡(luò)環(huán)境中,OpenSIPS運(yùn)營(yíng)平臺(tái)結(jié)合其他手段來(lái)執(zhí)行丟失BYE消息以后的掛機(jī)處理。各種處理方式都有其各自的特點(diǎn)。

使用標(biāo)準(zhǔn)的SIP定時(shí)器時(shí),SIP會(huì)話定時(shí)器設(shè)置超時(shí)以后,結(jié)束會(huì)話或者重新發(fā)起一個(gè)re-INVITE請(qǐng)求或者update,經(jīng)過(guò)幾個(gè)周期以后對(duì)呼叫掛機(jī)。它要求客戶端或者網(wǎng)關(guān)能夠支持會(huì)話定時(shí)器設(shè)置支持。當(dāng)然,如果終端和網(wǎng)關(guān)都在同一公司內(nèi)網(wǎng)環(huán)境中的話,用戶可以控制設(shè)備的配置,比較容易設(shè)置定時(shí)器支持。如果是運(yùn)營(yíng)級(jí)的應(yīng)用場(chǎng)景的話,建議用戶通過(guò)網(wǎng)關(guān)或者SBC來(lái)設(shè)置定時(shí)器支持。RFC4028對(duì)SIP會(huì)話定時(shí)器有非常明確的規(guī)范,讀者可以參考RFC4028做進(jìn)一步了解。
通過(guò)dialog的ping實(shí)現(xiàn)BYE消息丟失的掛機(jī)控制的話,這是一種非標(biāo)準(zhǔn)的控制手段,它需要通過(guò)SIP 信令發(fā)送OPTIONS消息來(lái)實(shí)現(xiàn)。當(dāng)然要求客戶端或者網(wǎng)關(guān)支持OPTIONS/INVIET消息。因?yàn)槟壳昂芏嘟K端都支持發(fā)送OPTIONS消息或者re-INVITE, 相對(duì)來(lái)說(shuō)是一種比較簡(jiǎn)單的處理BYE消息丟失的方式,所以筆者推薦終端,ATA和網(wǎng)關(guān)設(shè)置OPTIONS消息檢測(cè)來(lái)實(shí)現(xiàn)BYE消息丟失的掛機(jī)處理。
最后一種方式是通過(guò)RTP提示來(lái)對(duì)BYE消息丟失進(jìn)行處理。這種處理方式也是一種非標(biāo)準(zhǔn)的處理方式,但是,它需要通過(guò)RTP流的檢測(cè)來(lái)實(shí)現(xiàn)。OpenSIPS不能支持RTP超時(shí)檢測(cè),所以只能通過(guò)媒體服務(wù)器端通過(guò)對(duì)雙方的RTP流檢測(cè)或者靜音檢測(cè)來(lái)實(shí)現(xiàn)掛機(jī)處理。如果媒體服務(wù)器檢測(cè)到雙方的RTP語(yǔ)音流無(wú)任何有效數(shù)據(jù)時(shí),說(shuō)明雙方已不再繼續(xù)通話,所以執(zhí)行掛機(jī)處理。這種檢測(cè)方式也沒(méi)有對(duì)終端有任何的要求。如果以上兩種處理方式不能使用時(shí),讀者也可以考慮通過(guò)媒體服務(wù)器檢測(cè)RTP語(yǔ)音超時(shí)來(lái)實(shí)現(xiàn)。開(kāi)源媒體軟交換Asterisk和FreeSWITCH都可以支持這樣的檢測(cè)機(jī)制來(lái)實(shí)現(xiàn)BYE消息丟失的掛機(jī)。但是,這種檢測(cè)機(jī)制很難非常準(zhǔn)確及時(shí)地實(shí)現(xiàn)掛機(jī)處理。因此,如果要實(shí)現(xiàn)CDR記錄的完整性和準(zhǔn)確性,這是一個(gè)相對(duì)比較差的選擇。
再次說(shuō)明,選擇何種處理方式需要用戶根據(jù)自己的部署環(huán)境做判斷,最終使用一個(gè)較低成本的方式來(lái)解決問(wèn)題,筆者僅提供一個(gè)比較完整的建議。
6CDR計(jì)費(fèi)中網(wǎng)絡(luò)故障和會(huì)話時(shí)延的問(wèn)題討論
大部分情況下,我們的通話是在正常狀態(tài)完成,整個(gè)CDR數(shù)據(jù)也非常正確。但是,在基于SIP網(wǎng)絡(luò)環(huán)境中,特別是基于云平臺(tái)或者全球部署的呼叫環(huán)境中,呼叫過(guò)程中出現(xiàn)網(wǎng)絡(luò)故障是非常正常的事情。因?yàn)榫W(wǎng)絡(luò)故障,整個(gè)Acc 模塊的記錄就會(huì)出現(xiàn)問(wèn)題,最終導(dǎo)致CDR和話單錯(cuò)誤。如下示例中,如果運(yùn)營(yíng)商和用戶代理服務(wù)器之間出現(xiàn)了網(wǎng)絡(luò)故障,如何進(jìn)行結(jié)算是一個(gè)比較頭疼的問(wèn)題。

在以上示例中,運(yùn)營(yíng)商已經(jīng)對(duì)代理服務(wù)器發(fā)送了200 OK,但是代理服務(wù)器和運(yùn)營(yíng)商之間的網(wǎng)絡(luò)出現(xiàn)了故障以后,我們需要特別關(guān)注是運(yùn)營(yíng)商支付這個(gè)話單還是我們的代理服務(wù)器負(fù)責(zé)支付這個(gè)話單。這里有幾個(gè)爭(zhēng)議的地方需要大家討論:
對(duì)運(yùn)營(yíng)商來(lái)說(shuō),它已經(jīng)發(fā)送了 200 OK, 網(wǎng)絡(luò)問(wèn)題可能不是運(yùn)營(yíng)商端的網(wǎng)絡(luò)問(wèn)題。
對(duì)客戶代理服務(wù)器來(lái)說(shuō),代理服務(wù)器沒(méi)有收到 200 OK, 當(dāng)然也沒(méi)有繼續(xù)發(fā)送后續(xù)回復(fù)(BYE,ACK等)信息到運(yùn)營(yíng)商端,客戶代理服務(wù)器也可能拒絕支付這個(gè)話單。但是,如果是運(yùn)營(yíng)商上游呼叫的話,運(yùn)營(yíng)商和上游呼叫方已經(jīng)產(chǎn)生了話單,如何處理這個(gè)呼叫的話單也是一個(gè)問(wèn)題。
運(yùn)營(yíng)商是否應(yīng)該提供定時(shí)器設(shè)置來(lái)網(wǎng)絡(luò)檢測(cè)確認(rèn) 200 OK返回ACK消息,以便確認(rèn)話單的準(zhǔn)確性。
一些運(yùn)營(yíng)商和代理之間的網(wǎng)絡(luò)問(wèn)題很難準(zhǔn)確及時(shí)到位。
UDP過(guò)度碎片化或者超過(guò)MTU數(shù)據(jù)限定,終端編碼協(xié)商等導(dǎo)致的問(wèn)題。
網(wǎng)絡(luò)質(zhì)量差導(dǎo)致的PDD時(shí)延
在一些小并發(fā)的呼叫環(huán)境中,可能這樣的故障不會(huì)引起太多的問(wèn)題,但是如果并發(fā)量在1W以上的話,網(wǎng)絡(luò)故障引起的計(jì)費(fèi)就會(huì)導(dǎo)致很大問(wèn)題。這里,筆者拋出的這些問(wèn)題的目的是讓用戶知道這些問(wèn)題的存在,具體如何兌付話單和運(yùn)營(yíng)商如何協(xié)商不在筆者討論范圍之內(nèi),很多運(yùn)營(yíng)商對(duì)此問(wèn)題有著不同的商務(wù)解決方案。筆者在這里討論的目的是網(wǎng)絡(luò)穩(wěn)定是正確計(jì)費(fèi)的非常重要的前提條件。
計(jì)費(fèi)中另外一個(gè)比較重要的話題是會(huì)話掛機(jī)時(shí)延。大家討論到計(jì)費(fèi)通常可能比較關(guān)心的是價(jià)格。事實(shí)上,在運(yùn)營(yíng)商提供的SIP trunk或者其他線路服務(wù)環(huán)境中,除了價(jià)格以外,語(yǔ)音穩(wěn)定和語(yǔ)音質(zhì)量以外,用戶好像沒(méi)有太多的指標(biāo)來(lái)判斷線路運(yùn)營(yíng)商的服務(wù)水平。事實(shí)上,除了筆者前面提到的結(jié)果指標(biāo)以外,用戶端可能還要注意幾個(gè)潛在的問(wèn)題。這些設(shè)置指標(biāo)可能有的是運(yùn)營(yíng)商故意設(shè)置的,有的是因?yàn)檫\(yùn)營(yíng)網(wǎng)絡(luò)被動(dòng)體現(xiàn)出來(lái)的。
一些比較“聰明”的運(yùn)營(yíng)商為客戶提供了相對(duì)比較低的價(jià)格,用戶自己體驗(yàn)也沒(méi)有發(fā)現(xiàn)什么大的問(wèn)題。但是,如果運(yùn)營(yíng)商因?yàn)榉⻊?wù)器處理能力問(wèn)題或者其他硬件問(wèn)題的限制,在計(jì)費(fèi)中故意設(shè)置了一些參數(shù)的話,整個(gè)呼叫的時(shí)間就會(huì)延長(zhǎng),但是,一般用戶可能沒(méi)有什么特別明顯的反應(yīng)。在呼叫流程中,幾個(gè)需要用戶特別關(guān)注的延遲設(shè)置可能會(huì)導(dǎo)致整個(gè)通話的時(shí)延,而且運(yùn)營(yíng)商在任何一個(gè)節(jié)點(diǎn)做延遲設(shè)置都可能影響整個(gè)通話的計(jì)費(fèi)。因此,時(shí)延的問(wèn)題需要讀者認(rèn)真去考慮。以下示例就是在SIP呼叫中,各種會(huì)話響應(yīng)之間的的創(chuàng)建所消耗的時(shí)間。

在以上圖例中,我們可以看到各種時(shí)延的設(shè)置。根據(jù)RFC6076規(guī)范,各種會(huì)話時(shí)延都有比較明確的規(guī)定,包括9個(gè)評(píng)價(jià)指標(biāo):
Registration Request Delay (RRD)
Session Request Delay (SRD)
Session Disconnect Delay (SDD)
Session Duration Time (SDT)
Session Establishment Ratio (SER)
Session Establishment Effectiveness Ratio (SEER)
Session Completion Ratio (SCR)
Ineffective Session Attempts (ISAs) 等。
如果是傳統(tǒng)PSTN的話可能還要涉及到其他的時(shí)延,例如PDD時(shí)延。
這些時(shí)延構(gòu)成了評(píng)價(jià)SIP端對(duì)端性能的評(píng)價(jià)指標(biāo)。雖然很多SIP運(yùn)營(yíng)商都聲稱自己的SIP服務(wù)如何優(yōu)質(zhì),但是,筆者建議避免使用空洞夸張的市場(chǎng)語(yǔ)言來(lái)說(shuō)服用戶,最好還是給出一個(gè)客觀的數(shù)據(jù)來(lái)說(shuō)服用戶。在SIP端對(duì)端的執(zhí)行性能評(píng)價(jià)指標(biāo)中,SDD是一個(gè)非常重要的指標(biāo)。在INVITE呼叫中其中一個(gè)比較重要的時(shí)延就是SDD的時(shí)長(zhǎng)。根據(jù)RFC6076規(guī)范說(shuō)明,SDD是介于BYE消息和其200 OK返回消息之間的時(shí)延時(shí)間。

這里讀者一定要注意,在OpenSIPS的CDR中的呼叫時(shí)長(zhǎng)是基于事務(wù)(Transaction)時(shí)長(zhǎng)來(lái)計(jì)算的,不是基于請(qǐng)求時(shí)長(zhǎng)來(lái)計(jì)算的。我們假設(shè)已經(jīng)收到了BYE消息,但是,計(jì)費(fèi)結(jié)束是以BYE消息的200 OK返回消息為計(jì)算基準(zhǔn)的,如果BYE消息和其返回的200 OK消息之間的時(shí)長(zhǎng)有過(guò)多時(shí)延的話,計(jì)費(fèi)就不是非常準(zhǔn)確,運(yùn)營(yíng)商端處理返回消息出現(xiàn)了時(shí)延,可能最后導(dǎo)致客戶端實(shí)際數(shù)據(jù)延長(zhǎng)。如果運(yùn)營(yíng)商和客戶端之間的事務(wù)結(jié)束時(shí)間延遲以后,這個(gè)計(jì)費(fèi)時(shí)長(zhǎng)就會(huì)延長(zhǎng)。運(yùn)營(yíng)商收到BYE以后,在正常時(shí)間范圍內(nèi)(1秒鐘內(nèi))返回200 OK是正常的,但是,如果運(yùn)營(yíng)商在一定延遲以后再發(fā)送200 OK,整個(gè)計(jì)費(fèi)時(shí)長(zhǎng)就會(huì)增加。
很多企業(yè)級(jí)的IPPBX或者SIP軟交換平臺(tái)沒(méi)有具體的采集SIP metrics 集成解決方案,這里筆者介紹一個(gè)開(kāi)源的解決方案 SIP3,它可以集成多個(gè)SIP IPPBX,和RTP語(yǔ)音評(píng)價(jià)指標(biāo),通過(guò)界面來(lái)顯示其相關(guān)的SIP評(píng)價(jià)指標(biāo)。具體項(xiàng)目鏈接查閱參考資料。

7OpenSIPS的ACC模塊和多l(xiāng)eg CDR示例配置
OpenSIPS 支持ACC和CDR的模塊來(lái)實(shí)現(xiàn)計(jì)費(fèi)處理。如果需要實(shí)現(xiàn)ACC模塊和CDR模塊的處理需要經(jīng)過(guò)以下幾個(gè)步驟。
首先,用戶需要在ACC的表中插入acc的參數(shù),通過(guò)mysql 命令執(zhí)行此命令:
mysql -u root opensips
然后執(zhí)行:
ALTER TABLE `acc` ADD `caller_id` CHAR( 64 ) NOT NULL ;
ALTER TABLE `acc` ADD `callee_id` CHAR( 64 ) NOT NULL ;
ALTER TABLE `acc` ADD `leg_type` CHAR(10) NOT NULL;
ALTER TABLE `missed_calls` ADD `caller_id` CHAR( 64 ) NOT NULL ;
ALTER TABLE `missed_calls` ADD `callee_id` CHAR( 64 ) NOT NULL ;
ALTER TABLE `missed_calls` ADD `leg_type` CHAR(10) NOT NULL;
接下來(lái)配置cfg文件,加載必要的模塊和參數(shù):
loadmodule "acc.so"
modparam("acc", "db_url", "mysql://opensips:opensipsrw@localhost/opensips")
modparam("acc", "extra_fields",
"db: CALLER->caller_id; CALLEE->callee_id; TYPE->leg_type") // 添加了CDR拓展支持
modparam("acc", "db_table_missed_calls", "acc")
增加acc的參數(shù):
do_accounting("db","cdr|missed");
$acc_extra(CALLER) = $fU;
$acc_extra(CALLEE) = $rU;
增加拓展支持,對(duì)PSTN進(jìn)行cdr處理:
$acc_extra(TYPE) = "PSTN";
然后重新啟動(dòng)OpenSIPS,通過(guò)PSTN呼叫進(jìn)行測(cè)試,通過(guò)OpenSIPS Control Panel -> System -> CDRViewer查看CDR記錄。
如果需要支持多腿呼叫CDR的話,用戶需要執(zhí)行以下步驟。修改cfg配置文件,加載多腿CDR支持
modparam("acc", "leg_fields",
"db: CALLER->caller_id;CALLEE->callee_id;TYPE->leg_type")
在leg 1的設(shè)置中增加:
$acc_leg(TYPE) = "USER";
acc_new_leg(); // 創(chuàng)建了一個(gè)新的leg
在leg 2增加
$acc_leg(CALLER) = $(acc_leg(CALLEE)[-2]);
$acc_leg(CALLEE) = $rU;
xlog("forwarded unconditionally to: $avp(callfwd)");
執(zhí)行了呼叫前轉(zhuǎn)設(shè)置。重新啟動(dòng)OpenSIPS,然后再通過(guò)界面修改用戶配置文件,增加前轉(zhuǎn)支持,呼叫從1002前轉(zhuǎn)到一個(gè)PSTN的號(hào)碼上。

保存以上配置。然后進(jìn)行呼叫測(cè)試,通過(guò)1000呼叫SIP 用戶1002,1002將會(huì)前轉(zhuǎn)到一個(gè)PSTN的號(hào)碼上。通過(guò)控制界面查看CDR記錄,我們會(huì)看到分別與兩個(gè)腿的呼叫,從1000到1002,然后1002到2345678 PSTN號(hào)碼。

默認(rèn)環(huán)境下,CDRVIEWER記錄僅支持CDR的記錄,沒(méi)有顯示ACC表的記錄消息。用戶可以通過(guò)修改CDR的配置文件顯示更多關(guān)于ACC模塊的參數(shù)設(shè)置。用戶需要修改配置文件:
vim /var/www/html/opensips-cp/config/tools/system/cdrviewer/local.inc.php
增加對(duì)ACC的數(shù)據(jù)支持,添加以下三行數(shù)據(jù):
$show_field[9]['caller_id'] = "Caller ID";
$show_field[10]['callee_id'] = "Callee ID";
$show_field[11]['leg_type'] = "Call type";
用戶需要重新刷新界面,查看CDRviewer,用戶會(huì)看到我們剛才添加到ACC模塊數(shù)據(jù)。

8總結(jié)
CDR處理是VOIP的核心功能,每個(gè)運(yùn)營(yíng)商和很多國(guó)家對(duì)關(guān)于其部署和使用都有非常明確的規(guī)范,特別是在VoLTE網(wǎng)絡(luò)中,CDR的處理變得更加復(fù)雜。筆者在本文章中討論了關(guān)于OpenSIPS的ACC模塊和CDR計(jì)費(fèi)模塊的細(xì)節(jié)流程,另外討論了關(guān)于CDR計(jì)費(fèi)時(shí)的一些相關(guān)問(wèn)題的處理,多腿計(jì)費(fèi)的正確處理流程,特別針對(duì)丟失BYE消息的處理,需要關(guān)注關(guān)于網(wǎng)絡(luò)故障以后的CDR數(shù)據(jù)生成,會(huì)話關(guān)閉時(shí)延問(wèn)題討論和關(guān)于OpenSIPS環(huán)境下多腿示例的配置以及如何修改cdrviewer顯示ACC 表的更多信息。
因?yàn)镃DR的細(xì)節(jié)很多涉及了具體的業(yè)務(wù)規(guī)范,筆者這里討論的僅局限于OpenSIPS和一般的企業(yè)IPPBX呼叫場(chǎng)景中,這里沒(méi)有涉及一些運(yùn)營(yíng)商級(jí)的CDR級(jí)或者其他業(yè)務(wù)場(chǎng)景的討論,很多場(chǎng)景實(shí)際上和具體業(yè)務(wù)規(guī)范有非常緊密的關(guān)系,因此在處理方式上也存在很多差異。希望讀者根據(jù)自己的業(yè)務(wù)場(chǎng)景來(lái)理解CDR的流程,筆者文章作為一個(gè)部署OpenSIPS的參考。
另外,我們的討論僅局限于比較簡(jiǎn)單的呼叫流程。因?yàn)楹艚辛鞒躺婕暗胶芏嗑唧w的企業(yè)融合通信的業(yè)務(wù)流程,呼叫流程可能涵蓋多個(gè)終端或者其他第三方的應(yīng)用,在CDR處理方面需要更多的靈活的支持,這些支持也需要媒體服務(wù)器做相應(yīng)的配合支持。如果單純完全依靠OpenSIPS一個(gè)環(huán)境來(lái)處理的話顯然是不現(xiàn)實(shí)的。因此,為了能夠完整處理CDR數(shù)據(jù),需要配合多個(gè)平臺(tái)聚合數(shù)據(jù)庫(kù)數(shù)據(jù)才能更加準(zhǔn)確實(shí)現(xiàn)CDR,ACC的功能。
參考資料:
www.rbbn.cn Ribbon SBC
www.freepbx.cn
https://kamailio.org/docs/modules/devel/modules/acc.html
https://www.opensips.org/Documentation/Tutorials-Advanced-Accounting
https://www.fcs.org.uk/image_upload/files/UK%20Standard%20CDR%20Format%20v3%20-%20Final.pdf
https://tools.ietf.org/html/rfc2865
https://tools.ietf.org/html/rfc2866
http://www.cs.columbia.edu/~dgen/papers/conferences/conference-10.pdf
https://tools.ietf.org/html/rfc6076
https://github.com/sip3io/sip3-ansible
- 融合通信/IPPBX/FreePBX商業(yè)解決方案:www.hiastar.com
- 最新Asterisk完整中文用戶手冊(cè)詳解:www.asterisk.org.cn
- Freepbx/FreeSBC技術(shù)文檔: www.freepbx.org.cn
- 如何使用免費(fèi)會(huì)話邊界控制器-FreeSBC,qq技術(shù)分享群:334023047
- 關(guān)注微信公眾號(hào):asterisk-cn,獲得有價(jià)值的通信行業(yè)技術(shù)分享