2013年9月7日星期六

imsdroid 学习(初认识)


  由于工作的需要,麦洛最近都在研究语音通话的技术。工作中,一个同事无意发现了开源项目idoubs。idoubs是imsdroid的IOS版本。
  从google以及baidu来看,除了官网http://code.google.com/p/imsdroid/ 介绍外,有关imsdroid或idoubs貌似的帖子并不是很多。但从官网的介绍可以知道这个项目确实非常强大。于是赶紧check下来学习。注意check out时要使用http://imsdroid.googlecode.com/svn/这个地址,不要使用trunk目录,作者已经将项目放在了svn这个目录下了。
  check下来的源码结构:
  
  imsdroid或idoubs项目是基于doubango,关于这个项目可以到它的官网http://doubango.org/ 上看看介绍。
  麦洛与iphone的同事试用了一下这个安装包,看一下通话效果。不知道是不是网络原因还是服务器原因,语音通话是可以的,很清晰,有一点回音,但视频却是很难连接成功,或者传播的图像只有一台手机看得到,而另一台则看不到。从源码上看,它还支持高清(1080p),以及多种编码格式。而麦洛感兴趣的正是它丰富的编码格式以及网络传输的实现技术。
  由于介绍imsdroid使用的资料实在是少之又少。学习它的原理,只能从看代码开始。
  从编译项目开始。使用2.0目录下的imsdroid,在eclipse中新建一个android项目,可以命名为imsdroid2.0,将branches下的imsdroid下的res,src下的(不包含src)目录以及manifest文件都copy到新建的imsdroid2.0项目中来。这时候编译imsdroid2.0是会出错的。因为有很多类找不到。原因是由于imsdroid项目基于android-ngn-stack这个库的,作者将其放在了branches下的android-ngn-stack,这个主要是封装了底层的实现,使用jni来调用c库。
  所以使用同样的方法,在eclipse中使用将android-ngn-stack这个库新建为android项目,并把它作为一个库。
  方法是:右击android-ngn-stack 选择 properties 在弹出的窗口中把 is library 勾选上,如:
  
  然后就在imsdroid2.0中引用这个库就行了,引用的方法也是一样的,只是在打开的properties窗口中点击add...按钮,将android-ngn-stack添加进来就行了。这时候,imsdroid2.0就可以编译成功了。
  编译成功后就可以在手机安装试用了么?no!
  这里还有一个问题,就是android-ngn-stack是封装了jni,但真正的实现是c库,所以必须有一个libxxx.so文件才行。那这个文件在哪里呢?答案看下图:
  
  将native-debug/libs目录copy到我们的imsdroid2.0项目中来,就可以了。
  最后,对于doubango这个开源项目http://code.google.com/p/doubango/  同样的,要check out 这个项目, 只要http://doubango.googlecode.com/svn/  就行了,trunk目录下是空的。
  麦洛也是刚开始学习这个开源项目,如果出现问题也是很正常的。可以给麦洛留言,大家一起学习。

  本文是原创博文,如果转载请注明来源,谢谢!

SIP软电话开发基本条件和要点

    SIP软电话开发的基本条件和要点
    在VoIP中,我们知道SIP协议有很大的用处。这里,我们就针对SIP协议,来看看SIP软电话开发环境的建立都需要知道哪方面的知识。那么首先我们来看看这个开发平台的条件。要在windows或者linux平台下开发基于SIP软电话,需要以下软件。
    服务器端软件: 注册多个客户端到服务器上,可以进行通话测试
    SIP客户端软件:主要用于测试,可以对别人已经完成的客户端进行抓包,以比对自己程序的发包数据
    SIP协议栈:基于某个现成的SIP协议栈来开发会加快开发进度
    RTP栈:传输语言或者视频数据的协议栈
    抓包测试工具:调试网络程序最有效的办法
    以下介绍这些软件主要以开源软件为主
    一 服务器端软件
    1. Asterisk:Linux系统下开源的IPPBX,功能强大稳定,主要用c语言开发。配置稍麻烦。
    2. Vocal:Linux系统下开源的SIP服务器端。可以作为IPPBX也可以作为运营系统。很多voip虚拟运营商都用这个作为自己的运营系统。提供BS结构的管理界面。
    3. YATE:跨平台(Linux,Windows)的开源SIP服务器端。在windows下安装非常简单。其他方面没有进行过测试。
    4. SER:Linux平台下重量级的SIP服务器断。功能比较丰富,也是很多voip虚拟运营商的系统选择。不过据说配置比较麻烦,具体没有试过。
    5. sipX:Linux平台下的SIP服务器。这个好像不能作为客户端再次注册到其他SIP服务器上。提供BS结构的管理界面。
    二 SIP客户端软件
    1. Windows Messenger 5.1:微软出的SIP客户端,操作方便。
    2. YATE Client:跨平台(Linux,Windows)的开源SIP客户端软件。安装方便,功能简单。
    3. xten:windows平台下的SIP软电话。功能齐全,使用方便。
    三 SIP协议栈
    1. osip:跨平台的开源SIP协议栈。用c语言实现,体积小。
    2. exosip:对osip进行封装,使其方便SIP客户端软件开发。同样开源跨平台。
    3. sipXtackLib:由SIPfoundry提供的开源跨平台的SIP协议栈,功能齐全。C++开发,已经被用于开发数个商业SIP终端。
    四 RTP栈
    1. JRTPLIB: 开源的跨平台rtp栈,用C++语言开发,使用方便。
    五 抓包测试工具
    1. Wireshark:非常有名的开源跨平台网络抓包工具,以前叫做Ethereal。
    上述就是我们在SIP软电话开发中,需要了解的一些内容了,希望对大家能够有所帮助。

用yate建立VoIP服务器 实现免费语音通话(SIP协议)


介绍如何用yate2软件搭建VoIP服务器,并用SIP协议完成语音通话。在我的实例中,使用了局域网内的3台PC,Windows操作系统,接在同一个集线器上,并不是广域网或3G接入。
       网络电话是下一代网络(NGN)的重要应用之一。“下一代网络”是指10年以后的网络,全部基于软交换(Softswitch)技术。但是,拨打VoIP免费网络电话,并不需要在等待10年。基于现有的TCP/IP网络,我们已经可以使用开源的VoIP软件,实现PC-to-PC的免费语音通话。(注:这里的“免费”,是指不需要支付传统语音通话费用,ADSL/FTTB/3G等上网接入仍然是需要费用的)
下面,我将介绍如何用yate软件搭建VoIP服务器,并用SIP协议完成语音通话。在我的实例中,使用了局域网内的3台PC,Windows操作系统,接在同一个集线器上,并不是广域网或3G接入。
yate2建立VoIP服务器
Yate = Yet Another Telephony Engine,是一款开源的VoIP网络电话软件。它可以作为服务器、也可以作为客户端使用。yate2可以在Linux下运行、也可以在Windows下运行。yate2下载地址: www.lxvoip.net/softphone/yate.html 。
VoIP服务器可以干什么?
* 客户端使用各自的用户名和密码登录到服务器上
* 用户通过“电话号码”拨叫另一用户
* 服务器负责转发拨叫请求及此后的其他控制信令
* 服务器可以转发话音数据包
建立服务器这一步不是必须的。yate2支持两个客户端通过IP地址直接连接,而不需要建立服务器。如果你需要支持较多的用户能够互相通话,通常要建立服务器;如果只有2个用户,则可以采用直连方式。
建立VoIP服务器的前提条件
* 一台计算机,作为服务器
* 服务器通常需要拥有固定的公网IP地址
* 服务器上不能再运行客户端(也就是说,客户端、服务器不能同时启动,否则会冲突)
用yate2搭建VoIP服务器的步骤
1. 下载并安装yate2(最好完全安装所有组件,仅30MB)
2. 打开yate2安装目录的conf.d子目录
3. 将regfile.conf.sample复制一份,改名为regfile.conf,打开作下列修改:
* 找到;auth=100、;register=100、;route=100三行,分别去掉前面的分号
* 对需要建立的每一个用户,在文件末尾增加两行:
[用户名]             password=密码
例如建立用户sunny,密码为870212,则写成:             [sunny]            password=870212
这样,yate2服务器就有了身份认证功能
4. 将regexroute.conf.sample复制一份,改名为regexroute.conf,打开作下列修改:
* 找到[default],在后面增加一行             ${username}^$=-;error=noauth
这样未登录的用户就不能拨打电话
* 对需要建立的每一个电话号码,在刚才插入处之后增加一行
^电话号码$=return;called=用户名
例如当有人拨打号码15900941215,就呼叫用户sunny,则写成:             ^15900941215$=return;called=sunny
这样,yate2服务器就有了电话路由功能
5. 开始-管理工具-服务,重新启动Yet Another Telephony Engine服务
如果服务成功启动、没有错误提示,你已经正确建立了最简单的yate2网络电话服务器。
 通过yate2服务器打电话
再次提醒,不能在运行yate2服务器的计算机上打开yate2客户端软件,否则是无法正常运行的。
1. 开始-Yate-Yate Client,启动yate2客户端
2. Accounts页-New,打开新建帐户对话框,填写各项目:
* Protocol=sip           * Use provider,不要选择
* Account,可以随意输入
* Username=用户名,@后面留空
* Password=密码
* Server=服务器的IP地址
点击OK后,Status应该会显示“Registered”
3. Calls页,Account=前面填写的account名称,然后输入另一个用户的电话号码,点击Call就可以打电话了
4. 如果有电话打进来,选中它并点击Take the call就可以接听
5. 点击Hangup挂断
yate2直连打电话
如果只有2个用户需要相互通话,就不必劳神建立VoIP服务器了(何况服务器还要占据一台计算机)。yate2支持直连通话,配置方法如下:
1. 被叫用户只需开启Yate Client(当然要在防火墙中允许它),不需要配置
2. 主叫用户,Accounts页-New,打开新建帐户对话框,填写各项目:           * Protocol=sip           * Use provider,不要选择           * Account,可以随意输入           * Username,留空           * Password,留空           * Server=被叫用户的IP地址       点击OK后,Status并不会显示“Registered”,但是这没有关系
3. 主叫用户,Calls页,Account=前面填写的account名称,然后随便输入一个号码,点击Call就可以打电话了
4. 被叫用户,选中打进来的电话并点击Take the call就可以接听
5. 点击Hangup挂断
SIP协议
yate2支持SIP、H.323、jabber、iax等多种VoIP协议,而先前我选择的是SIP协议。SIP协议定义了一组VoIP网络电话信令,传输层基于UDP协议、端口号为5060;SIP只提供控制信令,并不负责语音数据的编码和传输。 通过yate2服务器通话,SIP协议分析
我用Wireshark抓包分析了一次通话过程。这次通话的情况如下:(省略)
上面的过程,建立了主叫方-服务器、服务器-被叫方的两个VoIP电话连接;主叫方不知道被叫方的用户名和IP地址,被叫方知道主叫方的用户名、但不知道IP地址 现在出现大量的双向RTP数据包,封装了语音数据(甚至可以解码并窃听语音内容);使用随机高端口(在SIP协议的INVITE、200两种报文中,用SDP协议声明了RTP使用的UDP端口、语音编码方式等),经过服务器转发 登录(Register)与退出(Unregister) 假设有人拨打电话号码1。根据regexroute.conf,服务器知道号码1对应于用户lxvoip1。那么,服务器怎么知道u1的IP地址呢?这就需要通过接收登录与退出消息来记录用户状态。
* 登录:       REGISTER sip:192.168.1.50       Contact:<sip:lxvoip1@192.168.1.183:5060>       Expires:600       To:<sip:lxvoip1@192.168.1.50>     * 退出:       REGISTER sip:192.168.1.50       Contact:<sip:lxvoip1@192.168.1.183:5060>       Expires:0       To:<sip:lxvoip1@192.168.1.50>     * 两者的区别就是Expires,0表示退出,非0表示登录     * 如果缺少身份认证,服务器会返回401;通过身份认证后,服务器返回200 yate2直连通话,SIP协议分析
直接贴出Wireshark的自动分析结果吧~Statistics-VoIP Calls-Graph就可以看到
|Time     | 192.168.1.101     | 192.168.1.183     |
|3.985    |         INVITE SDP                    |SIP From: sip:anonymous@192.168.1.183 To:sip:0@192.168.1.183
|         |(5060)   ------------------>  (5060)   |
|4.004    |         100 Trying|                   |SIP Status
|         |(5060)   <------------------  (5060)   |
|4.035    |         180 Ringing                   |SIP Status
|         |(5060)   <------------------  (5060)   |
|11.818   |         200 OK SDP                    |SIP Status
|         |(5060)   <------------------  (5060)   |
|11.826   |         ACK       |                   |SIP Request
|         |(5060)   ------------------>  (5060)   |
|11.857   |         RTP (g711U)                   |RTP Num packets:281  Duration:5.597s SSRC:0x1726C94E
|         |(27392)  <------------------  (27824)  |
|11.954   |         RTP (g711U)                   |RTP Num packets:280  Duration:5.550s SSRC:0x7805579C
|         |(27392)  ------------------>  (27824)  |
|17.495   |         BYE       |                   |SIP Request
|         |(5060)   <------------------  (5060)   |
|17.514   |         100 Trying|                   |SIP Status
|         |(5060)   ------------------>  (5060)   |
|17.526   |         200 OK    |                   |SIP Status
|         |(5060)   ------------------>  (5060)   |
与经过服务器的通话相比,直连通话就显得非常简单了:没有身份认证过程,不需要转发信令与RTP数据。

Yate 网络电话引擎 Linux下安装

Yate (Yet Another Telephony Engine)

主要支持功能:

VoIP 服务器
VoIP 客户端
VoIP to PSTN 网关
PC2Phone and Phone2PC 网关
H.323 网守
H.323 多端点服务器
H.323<->SIP 转换代理
SIP session border controller
SIP 路由
SIP 注册服务
Jingle 即时聊天
ISDN passive and active recorder
IAX2服务器客户端
电话服务器和客户端
呼叫中心服务器 (会议,队列)
IVR语音交互应答
预付费,后付费电话卡系统
兼容Asteirsk的zaptel中继卡测试环境准备:RedHat Linux AS 4 U4 DVD 镜像 或者Trixbox
安装包准备

cd /opt
wget http://downloads.sourceforge.net/openh323/pwlib-v1_10_3-src-tar.gz
wget http://downloads.sourceforge.net/openh323/openh323-v1_18_0-src-tar.gz
wget ftp://ftp.cn.postgresql.org/pub/postgresql//source/v8.2.5/postgresql-8.2.5.tar.bz2

下载yate源码,

wget http://voip.null.ro/tarballs/yate1/yate-1.3.0-1.tar.gz

安装h.323共享文件
tar zxvf pwlib-v1_10_3-src-tar.gz
cd pwlib_v1_10_3/
./configure
make opt
make install
export PWLIBDIR=`pwd`
cd ..

tar zxvf openh323-v1_18_0-src-tar.gz
./configure
make opt
make install
export OPENH323DIR=`pwd`
cd ..

#更新 /usr/local/lib共享库
echo “/usr/local/lib” >> /etc/ld.so.conf
ldconfig

#安装yate

tar zxvf yate-1.3.0-1.tar.gz

cd yate
./configure –with-pwlib=$PWLIBDIR –with-openh323=$OPENH323DIR
make
make install

#安装成功后。。启动yate测试
yate&
netstat -utnlp #执行结果会看到1720 4569 5060 端口被监听。说明启动成功
#这是yate只启动了h.323的EP,还没有运行GK,修改一下配置文件即可
cd /usr/local/etc/yate
vi h323chan.conf

[gk]
;server = false
;interface1=10.0.0.1
;port = 1719
;name = YateGatekeeper
;registeredonly=false

改为
[gk]
server = on
interface1=51.136.XX.XX ;你的网卡IP
port = 1719
name = YateGatekeeper

killall yate
yate&
netstat -utnlp #如果成功将会看到1719也被监听,这是yate就可以注册h323端点或网关
安装postgresql,
cd /opt
准备数据库
tar jxvf postgresql-8.2.5.tar.bz2
cd postgresql-8.2.5/
./configuer
make
make install
adduser postgres #添加用户
mkdir /usr/local/pgsql/data #创建目录
chown postgres /usr/local/pgsql/data   #添加权限
#操作数据库
su postgres //切换用户
/usr/local/pgsql/bin/initdb -D /usr/local/pgsql/data #初始化数据库
/usr/local/pgsql/bin/postmaster -D /usr/local/pgsql/data & #启动数据库
#添加yateadmin 数据库
bash-3.00$ /usr/local/pgsql/bin/createdb yateadmim
CREATE DATABASE
#数据库创建成功

安装yateadmin管理界面
cd /opt/yateadmin
./install
Installer for Yate Administrator v1
At the following prompts you can enter the word ‘no’ to disable defaults
Install Yate config file in: [/usr/local/etc/yate] 回车
Install Web pages in: [/var/www/html/yateadmin] 回车
Database host: [localhost] 回车
Database name: [yateadmin] 回车
Database user: [postgres] 回车
Database password: []      回车
PostgreSQL command: [] /usr/local/pgsql/bin/psql 输入
再次回车完成安装
进入http://your IP/yateadmin
帐号密码admin
点击Lines 添加
Operations with single line
Insert line [] 输入分机号码
Add 点击
Edit
Delete (use with care!)

按提示输入密码

现在可以用sip终端或者iaxlite测试了

sipdroid【源代码】

 
1.       sipdroid\src\org\zoolu 中是sip协议栈的实现
2.       sipdroid\src\org\sipdroid 中是软电话的实现
3.       sipdroid\src\com 中是stun相关的实现
4.        sipdroid默认使用的编码格式为G711-A率。
5.        直接用ant debug的方法编译出的程序,只支持A率和U率两种音频编码格式,其他的都需要通过NDK的方法导入后,才能使用。
6.        如果对端终端支持视频的话(如linphone),菜单如下:
保持,静音,
转移 发送视频 挂断
注意:只能发送视频,接收不到对端的视频。
7.        如果对端终端不支持视频的话(如yate),菜单如下:
保持,静音,
转移  挂断
8.       sipdroid\src\org\sipdroid\sipua\ui 中的VideoCamera.java,有视频捕获,发送,接收的实现。
9.       sipdroid\src\org\sipdroid\sipua\ui 中的CallScreen.java中的  VIDEO_MENU_ITEM 标识了 “发送视频”
10.       Activity2.java 实现了跳转到InCallScreen.java
11.        class InCallScreenextends CallScreen
12.       sipdroid.java 中有“关于 退出 设置”菜单的实现。
在AndroidManifest.xml中,
<intent-filter>
               <actionandroid:name="android.intent.action.MAIN" />
               <categoryandroid:name="android.intent.category.LAUNCHER" />
</intent-filter>
表明了哪个Activity先启动。
13.        网络传来的音频数据通过AudioTrack类进行播放。
14.        本地的音频数据通过AudioRecord类进行录制。
15.        在本地播放数据包中的视频流,可以先提取位图,再显示。由于系统没有提供直接播放的相关方法。
16.        线程同步的方法 – synchronized
17.       F:\sipdroid\res\drawable 中的图标可以更换
18.       sipdroid\res\values-zh-rCN 修改【关于】显示框的内容

19
在Sipdroid开源项目像服务器进行数据的发送统一是由SipProvider的sendMessage,因为首先得知道是什么连接是UDP啊,还是TCP,然后就是message的封装

20.
是无连接的包投递服务,为什么是无连接呢,客户端和服务器压根就没有建立连接,服务器只是开放了端口来接受数据,有了就接受,没有就悬挂阻塞.
21双边的视频观看,走的还是数据报包,有数据报包的ip和端口就行了

22 但是Sipdroid可以直接的从MediaRecord里面已经生成好的视频数据中提取出H264/H263的数据,这些数据已经经过了相应的编码
23如何观看视频:
mVideoFrame.setVideoURI(Uri.parse("rtsp://"+Receiver.engine(mContext).getRemoteAddr()+"/"+
         Receiver.engine(mContext).getRemoteVideo()+"/sipdroid"));
24 通过内置的videoview来通过RTSP来进行播放,那么也就是说服务器会将传递的RTP的视频数据流封装成RTSP的流传递给手机的videoview来实现观看,同样也不需要解码库,
所以Sipdroid开源代码里只有声音的编码库,没有视频的编码库.

25
最好的实现该软件的方法是,借助Android的MediaRecorder实时提取出H263/H264数据,然后经过RTP封装传给RTSP服务器,这种实现方式最理想,通过获取onPrewFrame来获取预览帧编码,无论怎么弄,不可避免的,延时,丢帧各种情况都会让你非常的棘手

sipdroid 源码下载编译


用svn从官网上下载sipdroid源码

  1). 进入doc命令, 切换到sdk安装目录的tool目录下(如果是别的目录,会导致android命令无法被识别!!) 然后运行命令: android update project -p SipDroid所在目录(我的目录: E:\android\workspace\SipUA) -t android-8

如:D:\android-sdk-windows\tools>android update project -p E:\android\workspace\SipU
A -t android-8
Updated default.properties
Updated local.properties
Added file E:\android\workspace\SipUA\build.xml

 2). 以上步骤完成之后,进入目绿只要执行: ant debug命令, 编译完成之后直接导入Eclipse就不会报错了.
 也可以先倒入eclipse再编译
如: 
E:\android\workspace\SipUA>ant debug
Buildfile: E:\android\workspace\SipUA\build.xml
    [setup] Android SDK Tools Revision 6
    [setup] Project Target: Android 2.2
    [setup] API level: 8
    [setup] WARNING: Attribute minSdkVersion in AndroidManifest.xml (3) is lower
 than the project target API level (8)
    [setup] Importing rules file: platforms\android-8\ant\ant_rules_r2.xml

Sipdroid

ipdroid初尝

今天把Sipdroid在手机上跑起来了,下面记录这次过程。
  • 首先下载yate服务器
http://yate.null.ro/pmwiki/index.php?n=Main.HomePage
到上面的yate主页下载到适合Windows的服务器,然后添加用户,启动服务。
  • 之后将手机上面的账号设置好,服务器那里直接填IP。
  • 最后在另一台电脑上装好yate,就可以实现通话了
不过这个过程中碰到了点问题,首先是501错误,后来不知道怎么好了,等继续深入研究的时候再解决吧。
还有个问题就是延迟比较大,音质比不上电话网络,估计是手机的3G网络不给力,在wifi环境下应该会好一点。不过随着无线通信的数据速率越来越高,这个问题应该不会很影响。

接下来的时间就是把Sipdroid源码看懂,改成自己的网络电话,如果可能再自己写一个注册服务器程序,这样就可以完全自己控制了。
下面记录一些关于Sipdroid参考地址:
http://sipdroid.org/   sipdroid的官网
http://blog.csdn.net/banketree/article/details/7979327
http://www.rosoo.net/a/201112/15477.html
http://www.apkbus.com/Android-161-1.html