基于Asterisk的VoIP開發(fā)指南——Asterisk模塊編寫指南
2008/06/12
1.開源項(xiàng)目概述
 
                  圖1 Asterisk結(jié)構(gòu)圖
2.Asterisk二次開發(fā)概述
                    
                      Asterisk是一個(gè)開源的PBX架構(gòu);但它并不是一個(gè)成品。通常情況下,由于企業(yè)應(yīng)用的多樣性,很難有一個(gè)成型的PBX產(chǎn)品可以滿足企業(yè)的各種需求。傳統(tǒng)的PBX成品,要么功能和靈活性不足,要么配置和維護(hù)復(fù)雜;而且都具有一個(gè)致命的缺點(diǎn),那就是開放性、可擴(kuò)展性。
                    
                      Asterisk具有傳統(tǒng)PBX無法比擬的優(yōu)點(diǎn),那就是其靈活性,可擴(kuò)展能力;Asterisk的擴(kuò)展能力是通過開放相應(yīng)的架構(gòu)和接口來實(shí)現(xiàn)的。這就意味著Asterisk是一個(gè)組件而不是一個(gè)成型的產(chǎn)品,Asterisk的核心提供了一個(gè)基本的可運(yùn)行環(huán)境,而外圍相應(yīng)的能力則可以通過加載和配置相關(guān)的插件和模塊來實(shí)現(xiàn)。
                    
                      Asterisk是一個(gè)開源的PBX架構(gòu);但它并不是一個(gè)成品。Asterisk的擴(kuò)展能力是通過開放相應(yīng)的架構(gòu)和接口來實(shí)現(xiàn)的。這就意味著Asterisk是一個(gè)組件而不是一個(gè)成型的產(chǎn)品,Asterisk的核心提供了一個(gè)基本的可運(yùn)行環(huán)境,而外圍相應(yīng)的能力則可以通過加載和配置相關(guān)的插件和模塊來實(shí)現(xiàn)。
                    
                      因此,使用Asterisk,一定會(huì)面臨二次開發(fā)問題,這些二次開發(fā)主要圍繞以下幾個(gè)方面:
                    
                      (1)內(nèi)部核心模塊 

圖2 Asterisk PBX呼叫流程
 4.RADIUS協(xié)議的概述
                    
                      (1)Radius協(xié)議在協(xié)議棧中的位置
                    
                    Radius是一種流行的AAA協(xié)議,同時(shí)其采用的是UDP協(xié)議傳輸模式,AAA協(xié)議在協(xié)議棧中位置如圖3所示。 
 
                  圖3 Radius協(xié)議在協(xié)議棧中的位置
(2)Radius協(xié)議選擇UDP作為傳輸層協(xié)議
5.認(rèn)證計(jì)費(fèi)功能概述
                    
                      IP-PBX呼叫控制功能,主要是VoIP終端用戶的認(rèn)證計(jì)費(fèi)控制過程,是VoIP系統(tǒng)商業(yè)化運(yùn)營的核心模塊。
                    
                      Radius Client端,也叫NAS,主要的任務(wù)就是根據(jù)VoIP終端的呼叫請求攜帶的各種屬性,包括賬戶ID、被叫號碼、通話時(shí)間等,封裝成標(biāo)準(zhǔn)的Radius數(shù)據(jù)包發(fā)送到Radius 
                    Server端,達(dá)到賬戶信息實(shí)時(shí)更新的效果。整個(gè)NAS端程序主要由兩個(gè)模塊構(gòu)成:認(rèn)證模塊和計(jì)費(fèi)模塊,并把這兩個(gè)模塊整合到開源IP-PBX項(xiàng)目 
                    Asterisk中。
                    
                      5.1 標(biāo)準(zhǔn)RADIUS協(xié)議分析 
                    
                      (1)Radius Packet
                    
                      RADIUS數(shù)據(jù)包被包裝在UDP數(shù)據(jù)報(bào)的數(shù)據(jù)塊(Data field))中,其中的目的端口為1812,RADIUS協(xié)議包結(jié)構(gòu)如圖4所示。
 0 1 2 3
                    
                    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 
                    9 0 1
                    
                    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    
                    | Code | Identifier | Length |
                    
                    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    
                    | |
                    
                    | Authenticator |
                    
                    | |
                    
                    | |
                    
                    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    
                    | Attributes ...(不定長)
                    
                    +-+-+-+-+-+-+-+-+-+-+-+-+-
                    
                    
                    
                      Attribute:
                    
                    0 1 2 
                    
                    0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 
                    
                    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    
                    | Type | Length | Value …(不定長) 
                    
                    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
                    
                    圖4 RADIUS協(xié)議包結(jié)構(gòu)圖 
   (2)對Radius Packet格式各個(gè)域解釋 
                    
                      Code:包類型,一個(gè)字節(jié)長,指示RADIUS包的類型,包含不合法的Code的Radius包將被直接丟棄,code域主要包含了以下值類型。
                    
                      1)code=1 Access-Request——認(rèn)證請求數(shù)據(jù)包
                    
                      本文AAA功能就是構(gòu)建code=1的認(rèn)證請求數(shù)據(jù)包。
                    
                      2)code=2 Access-Accept——認(rèn)證響應(yīng)數(shù)據(jù)包
                    
                      3) code=3 Access-Reject——認(rèn)證拒絕數(shù)據(jù)包
                    
                      4)code=4 Accounting-Request——計(jì)費(fèi)請求數(shù)據(jù)包
                    
                      本文Asterisk的AAA功能另外一個(gè)重點(diǎn)任務(wù)就是構(gòu)建code=4的計(jì)費(fèi)請求數(shù)據(jù)包,Accounting-Request 
                    數(shù)據(jù)包中的兩種狀態(tài)類型(Acct-Status-Type)的計(jì)費(fèi)請求數(shù)據(jù)包:Start(Value=1):Client開始對指定用戶提供服務(wù),計(jì)費(fèi)開始;Stop(Value=2):Client停止對指定用戶提供服務(wù),計(jì)費(fèi)結(jié)束。
                    
                      5)code=5 Accounting-Response——計(jì)費(fèi)響應(yīng)數(shù)據(jù)包
                    
                      因?yàn)槭且沦~戶信息,所以目前本文不需要處理計(jì)費(fèi)響應(yīng)數(shù)據(jù)包。
                    
                      Identifier:包標(biāo)識符,一個(gè)字節(jié)長,用于匹配請求包和響應(yīng)包,同一組請求包和響應(yīng)包的Identifier應(yīng)相同。協(xié)議規(guī)定:
                    
                      1) 在任何時(shí)間,發(fā)給同一個(gè)RADIUS服務(wù)器的不同包的Identifier域不能相同,如果出現(xiàn)相同的情況,RADIUS將認(rèn)為后一個(gè)包是前一個(gè)包的拷貝而不對其進(jìn)行處理。
                    
                      2) Radius針對某個(gè)請求包的響應(yīng)包應(yīng)與該請求包在Identifier上相匹配(相同)。
                    
                      Length:包長度,兩個(gè)字節(jié)長,說明數(shù)據(jù)包的長度,是code、identifier、length、authenticator 
                    attribute fields的長度總和,有效范圍是20~4096,超出范圍的數(shù)據(jù)將被視為附加數(shù)據(jù)(Padding)或直接被忽略。
                    
                      Authenticator:驗(yàn)證字,16字節(jié)長,用于驗(yàn)證消息的負(fù)載,對包進(jìn)行簽名,該驗(yàn)證字分為兩種。
                    
                      1) 請求驗(yàn)證字---Request Authenticator,用在請求報(bào)文中,必須為全局唯一的隨機(jī)值。
                    
                      2) 響應(yīng)驗(yàn)證字---Response Authenticator,用在響應(yīng)報(bào)文中,用于鑒別響應(yīng)報(bào)文的合法性。響應(yīng)驗(yàn)證字=MD5(Code+ID+Length+請求驗(yàn)證字+Attributes+Key)。
                    
                      Attributes:Type指示了Atribute的類型,通用的有幾十種,在系統(tǒng)中使用到的,如表4.1所示。Asterisk 
                    AAA模塊的構(gòu)建主要是構(gòu)建表1列出的這些屬性值的RADIUS數(shù)據(jù)包。
                    
                      表1 Atribute的屬性列表 
|   屬性值  | 
                          | 
                          屬性意義  | 
                      
|   1  | 
                          User-Name  | 
                          用戶賬戶ID  | 
                      
|   2  | 
                          User-Password    | 
                          用戶密碼  | 
                      
|   4  | 
                          Nas-IP-Address  | 
                          Nas的ip地址  | 
                      
|   5  | 
                          Nas-Port  | 
                          用戶接入端口號  | 
                      
|   6  | 
                          Service-Type  | 
                          服務(wù)類型  | 
                      
|   7  | 
                          Framed-Protocol     | 
                          協(xié)議類型  | 
                      
|   8  | 
                          Framed-IP-Address  | 
                          為用戶提供的IP地址  | 
                      
|   11  | 
                            Filter-Id  | 
                          過濾表的名稱  | 
                      
|   27  | 
                          Session-Timeout  | 
                          通知NAS該用戶可用的會(huì)話時(shí)長 (時(shí)長預(yù)付費(fèi))  | 
                      
|   32  | 
                          NAS-Identifier  | 
                          標(biāo)識NAS的字符串  | 
                      
|   40  | 
                          Acct-Status-Type  | 
                          計(jì)費(fèi)請求報(bào)文的類型  | 
                      
|    
                                   41  | 
                          Acct-Delay-Time    | 
                          Radius客戶端發(fā)送計(jì)費(fèi)報(bào)文耗費(fèi)的時(shí)間  | 
                      
|     44   | 
                          Acct-Session-Id  | 
                          計(jì)費(fèi)會(huì)話標(biāo)識  | 
                      
|   45  | 
                          Acct-Authentic  | 
                          在計(jì)費(fèi)包中標(biāo)識用戶認(rèn)證通過的方式  | 
                      
|   46  | 
                          Acct-Session-Time  | 
                          通話時(shí)長(用戶在線時(shí)長)  | 
                      
|   49  | 
                          Acct-Terminate-Case    | 
                          | 
                      
   5.2 選擇一個(gè)合適的Radius Client API  
                    
                      上個(gè)小節(jié)介紹的RADIUS數(shù)據(jù)包格式,是構(gòu)建應(yīng)用協(xié)議層數(shù)據(jù)包的封裝所關(guān)注的,在Asterisk中如果需要親自把標(biāo)準(zhǔn)RADIUS數(shù)據(jù)包的發(fā)送、接收等過程從零開始寫起,那本文就把重點(diǎn)放在了RADIUS 
                    UDP數(shù)據(jù)包與服務(wù)器通信過程的編寫中了,實(shí)際本文關(guān)注的是在Asterisk中根據(jù)VoIP通信中的業(yè)務(wù)需求,構(gòu)建RADIUS認(rèn)證計(jì)費(fèi)模塊,重點(diǎn)是業(yè)務(wù)應(yīng)用層的開發(fā),即如何組織認(rèn)證包、計(jì)費(fèi)包的數(shù)據(jù)結(jié)構(gòu)等,而RADIUS數(shù)據(jù)包傳輸層直接調(diào)用現(xiàn)成的開源API,目前主要有兩種這樣的開源項(xiàng)目。
                    
                      (1)pam_radius  
                    
                      一個(gè)PAM模塊提供了RADIUS客戶端的功能。它是從開源項(xiàng)目Freeradius中提取出來的,如果要使用需要對代碼做大量的修改、打補(bǔ)丁后才能使用。
                    
                      (2)radiusclient-ng 
                    
                      相對比PAM的pam_radius模塊而言,radiusclient-ng的動(dòng)態(tài)庫代碼不用修改就可以拿過來使用,只需安裝radiusclient-ng的動(dòng)態(tài)庫,然后根據(jù)配置文件、開放的API接口修改Asterisk代碼就可以完成Asterisk 
                    AAA模塊的構(gòu)建。
                    
                      所以在本文使用radiusclient-ng開源軟件包。 
| 基于Asterisk的VoIP開發(fā)指南—實(shí)現(xiàn)基本呼叫功能 2008-06-12 | 
| 基于Asterisk的VoIP開發(fā)—Asterisk AGI程序編寫指南 2008-06-12 | 
| 無線IPPBX系統(tǒng)的設(shè)計(jì)與實(shí)現(xiàn) 2008-06-12 | 
| 淺論美國寬帶電話(VOIP)監(jiān)管的新動(dòng)向 2008-06-11 | 
| 網(wǎng)絡(luò)電話(VoIP)成功應(yīng)用美軍軍事系統(tǒng) 2008-06-06 |