1、關(guān)于PJSIP介紹
PJSIP是開源的SIP協(xié)議棧,在最近的Asterisk版本中,官方已經(jīng)開始使用PJSIP協(xié)議棧作為Asterisk引擎的SIP協(xié)議棧。關(guān)于為什么Asterisk選擇PJSIP作為Asterisk新一代SIP協(xié)議棧的討論讀者可以查閱此鏈接:
SIP Stack Research
https://wiki.asterisk.org/wiki/display/AST/SIP+Stack+Research
PJSIP的核心是SIP endpoint,通過pjsip_endpoint來表示。
pjsip_endpoint負責幾個方面的工作:
- 它具有一個pool factory, 為SIP模塊分配自己的pool。
- 它支持對每個SIP模塊實現(xiàn)定時器管理。
- 它支持一個傳輸管理模塊,傳輸管理模塊支持對SIP傳輸和控制消息解析打印。
- 它支持PJLIB的 ioqueue支持網(wǎng)絡(luò)事件的調(diào)度處理。
- 它提供thread安全保護,對每個應用的thread進行安全管理。
- 它可以管理PJSIP的相關(guān)模塊,拓展,解析處理等功能。
- 它負責從管理模塊接收到的SIP 進入的消息,分發(fā)SIP消息到其他模塊。
因為篇幅的關(guān)系,筆者在這里不再做太多關(guān)于PJSIP的介紹,網(wǎng)絡(luò)有很多關(guān)于PJSIP協(xié)議棧,PJSIPUA的使用方式,讀者可以安裝練習。這里,我們主要介紹pjsip_endpoint的作用,因為它直接影響著我們后續(xù)章節(jié)中所討論的Asterisk呼叫流程。
2、PJSIP在Asterisk的結(jié)構(gòu)
在Asterisk環(huán)境中,PJSIP通過各自的模塊對終端,業(yè)務訂閱,認證和傳輸都進行管理。PJSIP模塊的幾個核心模塊如下:
Asterisk中PJSIP相關(guān)的幾個主要包括:
- res_pjsip 模塊,這是一個基礎(chǔ)模塊,提供對上層其他業(yè)務的支持。
- res_pjsip_session模塊,提供呼叫,媒體和會話管理,包括媒體流處理協(xié)商,DTMF,會話定時器設(shè)置,PRACK/100rel,SIP 原因頭處理,傳輸設(shè)置和媒體加密。
- res_pjsip_regiestrar, 提供SIP注冊模塊的管理。
- res_pjsip_pubsub, 提供對SIP消息的訂閱發(fā)布。
- res_pjsip_messaging, 提供MWI事件包處理,分機/設(shè)備的狀態(tài)拓展支持(例如,PIDF,XPIDF,和CPIM-PIDF)。
3、PSJIP相關(guān)的幾個實體對象說明
我們現(xiàn)在討論的PJSIP和以前的chan_sip配置文件有所不同。在PJSIP中,Asterisk借用了幾個實體概念來部署相關(guān)配置。如果用戶不了解其具體作用的話,可能引起很多的誤解。在前面的介紹中,我們已經(jīng)說明,Endpoint是PJSIP的核心。通過Endpoint關(guān)聯(lián)了很多相關(guān)的配置屬性關(guān)系。以下是一個ER關(guān)系圖實例,讀者可以基本了解其配置關(guān)系:
當一個新的SIP請求進入到PJSIP時,PJSIP的res_pjsip模塊首先需要確認Endpoint在res_pjsip中的注冊類型。注冊類型不同則關(guān)聯(lián)不同的配置參數(shù)設(shè)置。當然,Endpoint的確認也有不同的優(yōu)先級。用戶可以通過CLI命令來檢查這些Endpoint類型:
- *CLI> pjsip show identifiers
- Identifier Names:
- name not specified
- ip
- username
- anonymous
- header
- auth_username
大部分情況下,PJSIP會通過“From”頭中的username來查詢Endpoint中的username。如果匹配到了相應的username,則繼續(xù)匹配其他的配置參數(shù)。
在res_pjsip中提供了對Endpoint的類型定義,不同的類型又和不同的配置進行了綁定,這些具體的配置包括:
- Transport支持,提供對傳輸協(xié)議配置(TCP/UDP),加密配置(TLS/SSL),WS配置。
- AUTH支持,認證部分提供對用戶的Inbound和Outbound的Authentication處理,包括用戶注冊信息處理以及認證方式。
- AOR(Address of Record)支持,此配置通知Asterisk在那里可以連接endpoint終端。如果沒有AOR記錄的話,不能連接endpoint終端。當Asterisk收到一個注冊請求時,它首先需要查詢可用的AOR記錄。
- REGISTRATION注冊,提供對外SIP服務器的注冊支持,對接ITSP trunk配置。
- IDENTIFY支持,此配置控制res_pjsip_endpoint_identifier_ip模塊來決定進入到系統(tǒng)的數(shù)據(jù)是哪種endpoint終端類型。如果Asterisk收到一個來自于某個IP地址的數(shù)據(jù),則匹配這個地址的相應的終端。
- Contact配置選項工作方式類似于SIP URL的別名,保存進入到注冊消息。它可以關(guān)聯(lián)單個獨立的SIP 用戶代理。
以上ER圖例說明了它們之間的關(guān)聯(lián)關(guān)系。如果用戶對某些概念理解有問題的話,可以查閱筆者的歷史文檔,這里不再對基本概念做過多討論,相關(guān)文章包括:
- B2BUA/SBC/Proxy的SIP消息重構(gòu)和RFC7092詳解
- 一封信讀懂SIP注冊消息關(guān)鍵詞
- 深入理解SIP服務器的注冊和定位服務流程中關(guān)于AOR和COntact的說明。
4、Asterisk中PJSIP的處理流程
根據(jù)前面章節(jié)的介紹,一個呼叫通過SIP呼叫到Asterisk系統(tǒng)中,需要經(jīng)過幾個模塊的處理。讀者需要更多關(guān)注Res_pjproject.c文件(啟動PJSIP,分配模塊資源,設(shè)置log等)和Res_pjsip.c 文件。Res_pjsip.c開始加載其其他的上層模塊的邏輯處理,包括創(chuàng)建thread,監(jiān)聽IP和端口,確認Endpoint類型和優(yōu)先級判斷,確認endpoint相關(guān)配置,DTMF,管理SDP,Callerd等。以下圖例是關(guān)于Asterisk服務器中PJSIP協(xié)議如何處理一個呼叫請求的處理流程。
Asterisk中PJSIP的呼叫處理流程如下:
- 首先啟動PJSIP協(xié)議棧。
- 把新的request存放到threadpool中,等待處理。
- 確認Endpoint以及其配置類型。
- 如果有NAT支持,則修改NAT配置。如果沒有,則繼續(xù)執(zhí)行下一步流程。
- 如果有re-INVITE則執(zhí)行,修改媒體狀態(tài);如果沒有,則繼續(xù)進行下一步操作。
- 創(chuàng)建Dialog。
- 對請求進行認證處理。
- 創(chuàng)建一個新的會話。
- 處理SDP Offer。
- 提取Caller ID,保存提取的值。
- 創(chuàng)建一個ast_channel object 對象。
- 檢查是否有T38傳真支持處理。如果沒有則繼續(xù)執(zhí)行下一步流程。
- 正式啟動IPPBX,進入撥號規(guī)則。
5、Asterisk撥號規(guī)則中的PJSIP分機呼叫流程分析
在Asterisk呼叫中,首先需要根據(jù)呼叫的需求編寫一個撥號規(guī)則(dialplan)。 這個撥號規(guī)則定義了呼叫的具體流程。IPPBX的呼叫流程可以非常復雜,也可以非常簡單。為了配合以上內(nèi)容,我們編寫一個簡單的撥號規(guī)則來說明PJSIP分機之間呼叫需要處理的流程。具體撥號規(guī)則的語法如下:
這里需要提前說明,此示例中,分機已經(jīng)創(chuàng)建,撥號規(guī)則和SIP分機可以注冊退出注冊。所以,讀者如果需要測試的話,需要提前安裝Asterisk,如果需要real-time的分機管理的話,需要安裝Asterisk數(shù)據(jù)庫和創(chuàng)建相關(guān)的表(例如,asterisk.ps_endpoints,asterisk.ps_aors等)來存儲PJSIP的AOR,Contacts,Endpoints等數(shù)據(jù)。另外,讀者需要了解關(guān)于PJSIP的CLI命令,方便查看AOR,Contacts,和Auth等數(shù)據(jù)狀態(tài))。以下示例說明了Asterisk環(huán)境中PJSIP分機呼叫的主要處理流程:
在以上的出來流程中,Asterisk大概需要幾個步驟來實現(xiàn)分機之間的呼叫:
- 注冊的分機撥打200發(fā)起一個請求。
- Asterisk檢查此分機是否屬于特別設(shè)置的context,我們這里是hiastar。如果是,則可以進行第三步的流程。這里,讀者可以通過Asterisk CLI 命令檢查AOR 的狀態(tài)。
- 在Asterisk PBX中,首先檢查需要匹配的撥打的號碼,這里用戶撥打了200,當然,用戶也可以撥打其他號碼設(shè)置。
- 如果在撥號規(guī)則中匹配檢測通過,則執(zhí)行app 命令Dial,然后撥打PJSIP協(xié)議通道的分機。
- Asterisk再次檢查分機的狀態(tài),比如相關(guān)分機200的AOR和綁定的Contacts。這里,一些新用戶可能比較迷惑,筆者重點說明一下。如果創(chuàng)建了分機以后,系統(tǒng)可以馬上創(chuàng)建AOR記錄,但是沒有Contacts記錄。如果用戶使用SIP終端注冊登錄以后,Contact 記錄才能顯示,并且綁定了具體的IP地址對象。一個AOR可以綁定多個Contacts地址,也就是說,一個AOR記錄可以支持多臺SIP終端注冊登錄。在筆者的實驗中,一個AOR 200,綁定了兩個SIP 終端,這兩臺終端都已經(jīng)登錄注冊,所以可以顯示兩個不同的IP地址。分機注冊前后的的狀態(tài)
Asterisk檢查到200分機已經(jīng)注冊,并且獲悉了其IP地址以后,對此SIP分機發(fā)送INVITE請求,對其發(fā)起呼叫。
通過以上六個步驟,PJSIP分機之間的呼叫創(chuàng)建完成。
6、總結(jié)
此文章主要介紹了關(guān)于Asterisk環(huán)境中使用PJSIP分機撥號的基本處理流程和其相關(guān)的技術(shù)架構(gòu)。首先,筆者簡單說明了PJSIP的介紹了PJSIP的使用原因和官方說明,然后介紹了PJSIP的核心模塊,然后介紹了PJSIP在Asterisk的架構(gòu)和其相關(guān)的應用服務模塊。因為,PJSIP涉及了SIP協(xié)議幾個主要的概念,筆者又分別說明了幾個概念之間的綁定關(guān)系。為了讓讀者能夠充分了解Asterisk中PJSIP的處理流程,筆者通過圖例的方式,按照總共13個步驟說明了PJSIP是如何一步步進行呼叫流程的處理的。最后,筆者通過一個PJSIP分機呼叫的示例,配合簡單的撥號規(guī)則說明了撥號規(guī)則的處理流程。
參考資料:
www.asterisk.org
www.freepbx.org.cn
www.pjsip.org
關(guān)注微信公眾號:asterisk-cn,獲得有價值的Asterisk行業(yè)分享
Asterisk freepbx,F(xiàn)reeSBC技術(shù)文檔: www.freepbx.org.cn
融合通信商業(yè)解決方案,協(xié)同解決方案首選產(chǎn)品:www.hiastar.com
Asterisk/FreePBX中國合作伙伴,官方qq技術(shù)分享群(3000人):589995817