目的
為實現跨網絡的語音對講,使位于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:alice@example.com
--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