1. 程式人生 > >基於pjsip實現p2p語音對講

基於pjsip實現p2p語音對講

目的

為實現跨網路的語音對講,使位於NAT後的兩個裝置進行p2p的語音通訊,此處選用pjsip開源專案來實現。
未解決的問題:對稱型的NAT無法實現p2p打洞,pjsip採用turn服務進行轉發,不能稱之為純粹的p2p。

pjisp簡介

PJSIP是一個開放原始碼的SIP協議棧,它支援多種SIP的擴充套件功能 。它的實現是為了能在嵌入式裝置上高效實現SIP/VOIP。(摘自百度百科)
專案網址:http://www.pjsip.org/

pjsip的編譯

下載並解壓相應pjsip原始碼後,在根目錄執行./configure;make dep;make命令即可完成編譯。
注:pjsip依賴libasound庫,可通過apt-get install libasound2-dev進行安裝

pjsip測試程式說明

pjsip提供的文件比較多,比較分散,如果不仔細瀏覽各個文件,不太容易搞清楚build完的整個工程要如何使用,以及生成的測試程式要如何使用。
首先:工程編譯成功後,在pjsip-apps/bin/目錄下會生成一些測試程式。其中sample目錄下有很多單一功能的測試程式。不過我們更關心的是bin目錄下的pjsua-x86_64-unknown-linux-gnu(這裡吐槽下pjsip的文件,大部分文件中只會提到pjsua,而不會提到字尾,也沒有指出生成目錄,導致找了半天找不到pjsua)
pjsua-xxx的使用說明文件:http://www.pjsip.org/pjsua.htm

執行pjsua需要的前置條件

config-file
大家先大致瀏覽上面的pjsua文件說明,對整個pjsua的選項有個瞭解。然後我們關注到最後的config_file。
# This is a comment in the config file.
--id sip:[email protected]
--registrar sip:example.com
--realm *
--username alice
--password secret

sipserver
不瞭解sip的開發者對上面的sip:example.com 可能會有些疑惑,不知道這個sip:example.com指的是什麼?
pjsua這裡只是一個客戶端,要完成sip的通訊,需要一個sip伺服器,我們可以自己搭建,也可以找一些線上的免費sipserver(我只找到一個minisipserver是免費線上可用的,不過十分不穩定)。
自己搭建可以選擇opensip等開源的sipserver。
我選擇的是minisipserver windows安裝版,配置十分簡單,具體安裝配置參考:

http://blog.csdn.net/cazicaquw/article/details/7345327
安裝好後新增兩個分機user1:123456,user2:123456後即可進行下一步測試操作。

測試環境搭建
需要三臺pc進行測試,兩臺pc執行./pjsua客戶端,一臺執行sipserver。另外需要三臺路由器,兩臺pc客戶端執行分別執行在兩臺路由器下,sipserver執行在上級路由網路。

執行pjsip

按照前面的說明,分別生成user1和user2兩個conf檔案。
在兩個客戶端系統執行命令:./pjsua-x86_64-unknown-linux-gnu –config-file userX.conf
然後按照提示說明即可完成sip呼叫的過程。不過大概率情況下,你應該是不能進行語音對講的。因為兩個pjsua處於兩個不同網路下,需要nat穿透。

nat穿透之–stun-srv

檢視pjsip文件,我們發現可以通過–stun-srv選項進行nat穿透。–stun-srv後跟stun server的地址,pjsip的文件提供了一個公網的stun server地址:stun.pjsip.org,不過由於我們的sipserver搭建在內網,所以不能使用這個server,如果你安裝minisipserver時留意過會發現,minisipserver也啟動了一個stun server服務。這樣我們只需要在–stun-srv後跟上我們的minisipserver的地址即可了。
再次執行pjsua客戶端,進行呼叫,應該就可以進行語音對講了。
如果你仍然不能聽到語音,請抓包確認是否有rtp,udp包從對端發過來。如果沒有,請聯絡我,並告知你的路由器型號,我正想找一個這種路由器。

nat穿透之–turn-srv

前面如果你遇到語音不通的情況,大概應該是你的路由器的nat模式是對稱型的,stun是無法穿透對稱型nat的,此處需要用到turn,按照協議介紹turn是對stun的一種補充,對於無法穿透的對稱型nat,需要藉助turn進行轉發,我的理解turn已經不是純粹的p2p了。
turn server搭建:
這裡我們選擇restund作為turn server
restund的安裝參考:http://nil.uniza.sk/sip/installing-and-configuring-restund-stunturn-server
(注意啟動restund服務時,修改/etc/restund.conf裡面的server ip)
我們需要將該restund server部署到sipserver同一網路中。
–turn-srv引數:
pjsip文件中關於–turn-srv的sample大概是這樣子的:

 Another example to use TURN and ICE:

 $ ./pjsua --use-ice --use-turn --turn-srv turn.pjsip.org --turn-user [username] --turn-passwd ***

不瞭解turn的對這裡的–turn-user和–turn-passwd會十分疑惑。
我們檢視restund服務配置/etc/restund.auth:

#
# restund.auth
#
# this file contains a list of authenticated users, with one
# user per line in the format:
#
#     username:HA1
#
# the HA1 value can be calculated using util/genha1.sh
#

# sample user for testing:
#
#     username = demo
#     realm    = myrealm
#     password = secret
#
demo:c5dcdebd926706f33065ec3b65bf103c

這裡的預設的username就是demo,password就是secret了。
這樣上面的引數可以這麼填寫:

./pjsua --use-ice --use-turn --turn-srv restund_ip:3478 --turn-user demo --turn-passwd secret

至此,大部分nat後的裝置都可以進行p2p的通訊了。