基于pjsip实现p2p语音对讲

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/voidreturn/article/details/65634390

目的

为实现跨网络的语音对讲,使位于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

至此,大部分nat后的设备都可以进行p2p的通讯了。

展开阅读全文

没有更多推荐了,返回首页