KOK首页:基于Android的VoIP系统实现原理

栏目:茶油

更新时间:2021-06-10

浏览: 92784

KOK首页:基于Android的VoIP系统实现原理

产品简介

0章节  VoIP(VoiceoverInternetProtocol)即首先数字化语音信号并压缩帧,切换为IP数据包在网络上传输,以此已完成语音通话的业务,是一种利用IP协议传输语音数据的、新兴的通信技术。

产品介绍

本文摘要:0章节  VoIP(VoiceoverInternetProtocol)即首先数字化语音信号并压缩帧,切换为IP数据包在网络上传输,以此已完成语音通话的业务,是一种利用IP协议传输语音数据的、新兴的通信技术。

KOK首页

0章节  VoIP(VoiceoverInternetProtocol)即首先数字化语音信号并压缩帧,切换为IP数据包在网络上传输,以此已完成语音通话的业务,是一种利用IP协议传输语音数据的、新兴的通信技术。  随着我国三网融合的前进,VoIP与IPTV(InteractivePersonalityTV)一起沦为这一可观工程的最重要标志。而目前手机中,VoIP的解决方案并不是很多,特别是在Google公司发售的开源操作系统Android中。尽管该系统发售时间不宽,凭借强劲的功能、较好的界面、普遍的商业反对,为用户带给很好的体验,沦为2010年最热门且发展最慢的手机操作系统。

因此,两者的融合,将是未来的发展趋势。本文明确提出一种基于PJSIP协议栈的解决方案,通过Android本地开发工具(NDK),构建一个高效、平稳且功能强大的VoIP系统,具备较高的参照和实用价值。  1VoIP设计方案  1.1设计目标  本方案所设计的系统包括以下功能:首先,已完成用户终端(如手机)中语音数据的收集与编码,并通过RTP(动态传输协议)/RTCP(RTP传输控制协议)展开传输和掌控;其次,已完成会话的掌控,还包括会话的登记、发动、确保与完结、吊销等;再度,作为一个应用程序,必需构建一个较好的界面,与用户交互;最后,作为一个开放系统,须要具备较好的可扩展性。

  1.2总体设计  本方案基本上合乎Android的NDK框架的研发规范,将系统分成4层,如图1右图。最上层为应用层,该层将在AndroidSDK的框架内,使用Java语言来构建;第二层为JNI层,SIP协议栈有很多种构建,其中,使用C语言的SIP协议栈在效率、速度、系统闲置方面具有打破其他库(如Java协议栈)的优势,因此,该方案将在第三层使用显C语言构建的PJSIP协议栈。为了让Java应用层能调用协议栈层,在两层之间必须一个交会的桥梁,这就是JNI层。

最后一层是驱动层,这部分一般是由手机厂商来构建的,本文将不做到重点讲解。    2VoIP的明确构建  这里将构建一个原始的VoIP系统,还包括协议栈的构建、JNI的撰写以及上层UI的设计构建等。  2.1SIP协议栈及UA  SIP协议栈必要关系到整个系统的质量与效率,本文将使用显C语言研发的PJSIP库。

该库使用C语言研发,且源码对外开放,在兼容性与效率上有显著优势,不仅体积小(原始的SIPPCB也不过150KB),同时还构建了一个内存池,使得安全系数与运营效率深感提升,该系统所使用的就是优化后的PJSIP库。  2.1.1PJSIP协议栈  PJSIP协议栈遵循标准的SIP协议,使用分层架构:SIP/SDP消息编码解析层、传输管理层、SIP终端、事务层、会话层以及应用层等。

由于SIP协议使用文本消息发送到催促和号召,所以首先必须将SIP消息按照巴斯克范式(ABNF)编码和解析,这就是SIP/SDP消息编码解析层所已完成的功能。传输管理层用来管理用户代理与服务器之间的催促和适当;SIP终端是PJSIP货运机制的构建,它主要负责管理各个SIP重新组建,例如像SIP终端实例登记组件,发给消息到事务层、会话层及应用层,传送处理结果,管理定时器、I/O队列等;事务层通过状态机机制管理SIP信令,每一次状态机状态的转变都将启动时消息传递函数;会话层负责管理会话的发动与号召,一般与应用层融合在一起,用作用户交互,有所不同的平台有有所不同的构建,本文用于Andriod的GUI来构建。  PJSIP是一个高度PCB的库,实质上它是通过PJSUA子库来构建应用于的。

KOK首页

一个原始的PJSUA生命周期,首先必须初始化,通过函数init()来构建。在这个函数中,将创立代理、初始化变量和堆栈,以及创立一个UDP传输并在最后启动代理;第二步将为UA加到用户,如果需要的话,还要向服务器登记用户;当用户加到顺利后,此时可以创建一个调用相连,发动不会话;当会话相连顺利后,就可以用于SRTP协议动态传输加密后的数据,展开通话。最后的过程是悬挂或封存调用。  2.1.2UA原理  UA(UserAgency)是协议栈的明确构建,PJSIP通过PCB了的PJSUA来构建,在这一点上,大部分的SIP库都大同小异,在此将讲解UA的工作原理。

  一个典型的UA包括UAC(UserAgencyClient)和UAS(UserAgencyServer)两部分。会话由UAC发动。当调用发动时,UAC将首先发送到IN-VITE消息给SIP代理服务器,服务器接到INVITE消息后将回到一个接收者200OK,并问ACK展开证实,同时通报主叫用户(即不会话发动用户)上线通话。

如果主叫末端(用户端)主动完结不会话,UAC将回到BYE消息,同时通报服务器;如果用户端接到服务器传到的BY-E消息,问200,并完结不会话。  服务器端,UAS接到UAC(用户端)发去的INVITE消息,首先从消息中萃取出主、从前对象,然后检查当前否有空闲信道,若没则回到486BUSYHERE(即系统整天)消息;接着将检查从前用户否在服务区,如果从前对象不出服务范围,则回到404NOTFOUND(即用户不出服务区);若从前用户顺利上线,则回到200OK,同时打算开始不会话。  SIP协议栈一般用于SIP统一资源定位八字(URL)来标识,它根据URL来传输速率,如集群用户200,300分别对应SIP用户为200@192.168.1.100,300@192.168.1.100。

本文中也用于这种方式来测试通信。  2.2JNI的构建  PJSIP库和Java类相连是通过JNI来构建的,这也是AndroidNDK的构建机制,JNI是SUN公司发售的用作Java调用其他语言的模块。  首先必须一个中间类,这个类中主要创建一些方法用作调用C/C++本地函数。它们的类型皆为publicstaticnativeint,以便其他的Java类需要调用。

KOK首页

  2.2.1新建PJSIP类  为各个待构建的类新建一个包,可以命名为com.android.VoIP.pjsip,在该包中加到该系统涉及的一些类,主要有如下6个类:    这些类分别为上节中原理各个步骤的构建。这部分意味着是为C库的调用获取一个模块,因此明确的构建将放到本地C/C++程序中。  2.2.2头文件的分解  C库与Java间还须要通过一个后缀为.h的头文件来交会,这个头文件可以手动撰写,也可以通过Javah来分解,该工具包括在JDK中,是由SUN公司获取的。

  Javah生产的头文件包括一定的规则,例如,本例中,它将分解的函数声明为Java_com_android_IMSandroid_pjsip_**的形式,以便在调用C库时能准确辨识。  由于Java中的数据类型与C/C++不尽相同,因此还必需留意参数传递时参数类型的切换。本文所牵涉到到的Java数据类型有String和int型,Javah分解的头文件中会先定义好必须传送的参数类型以及函数回到类型,例如方法add_account(Stringsip_user,Stringsip_dom-ain,Stringsip_passwd),在头文件中将定义函数的形式为JNIEXPORTjintJNICALLJava_com_android_IMSandroid_pjsip_add_lac-count(JNIEnv*,jclass,jstring,jstring,jstring),其中JNIEXPORT为JNI外部函数声明,jint是jni.h中定义C语言中整形的对应类型,JNCALL是JNI关键字。

较为类似的是JNIEnv,它是一个指向类型为JNIEnv_的一个类似JNI数据结构的指针,它的每个元素都指向一个JNI函数的指针,jclass不会根据提到Java类的有所不同而有所不同,本文中pjsip.class是静态类,因此这里的jclass所指的是类本身,如果所谓静态类则所指的是对象。后面几个就是pjsip类必须传送的参数,根据jni.h的定义,String类型对应jstring,int对应jint。然而这只是函数重申与类中方法的形式对应,参数的明确传送还必须适当的转化成,明确构建将在下一节详尽讲解。

  2.2.3JNI接口函数的构建  创立了pjsip库类和头文件之后,必需应用于一个库接口函数,这部分是pjsip模块的构建,仅限于篇幅,本文只介绍几个最重要函数的构建。  (1)init函数  首先是init函数,对应的接口函数为JNICALLJava_com_android_IMSandroid_pjsip_init。

该函数在系统初始化时调用,其起到是配备涉及参数,并发动一个pjsua应用于。它再行通过函数pjsua_create()创立一个pjsua应用于,然后通过三个函数pjsua_config_default(&cfg),pjsua_logging_config_default(log_cfg),pjsua_media_config_default(&media_cfg)配备其涉及参数,其中cfg是pjsua的涉及参数,主要是状态转变时的消息传递函数;log_cfg用来配备log级别;media_cfg中包括时钟频率、声道数目等涉及参数。  已完成配备之后就可以用于pjsua_init(&cfg,&log_cfg,&media_cfg)将先前配备的参数初始化。

KOK平台

在初始化之后,还需为pjsua加到一个udp传输,这一步是通过pjsua_transport_create(PJSIP_TRANSPORT_UDP,cfg,NULL)来构建的,cfg中包括登录的通讯端口,3GPP建议用于5060。  必须留意的是,配备完了以上参数之后,还须要登录SPEEX编码优先级,一般将其划为仅次于,可以通过函数pisua_codec_set_priority(&-speex_codec_id,255)来构建。

所有配备已完成之后,就可以发动pjsua,即最后调用pjsua_start()。顺利的话,本函数的回到类型为PJ_SUCCESS。

  (2)make_call函数  另一个很最重要的函数是make_call,其在本模块文件中对应的函数为Java_com_Android_IMSandroid_pjsip_make_lcall,这个函数一般在发动不会话时调用,它与上一个函数在结构上仅次于的有所不同在于本函数必须传送一个字符串参数,前面提及,Java与C/C++在参数结构上并不完全相同,因此这里必须将Java传送过来的String类型的参数转化成,可以通过url_ptr=(char*)env-》GetStringUTFChars(url,iscopy)来构建。env-》GetStringUTFChars在jni.h中定义,其功能是将jsting类型(Java)的url读取char*类型(C)的url_ptr中,以此来已完成参数类型的切换。  为了确保传送地址的有效性,还必须用于pjsua_verify_sip_url(url_ptr)检验,这个函数主要检验url_ptr是合乎SIP的规则,即是否是一个合法的SIP地址。

然而char*型的地址pjsua中还是无法必要用于的,这是因为pjsua新的PCB了参数类型,所以最后还必须将其转化成pj_str_t类型,pjlib获取pj_str()函数可以已完成转化成。在已完成了参数的转化成后,调用pjsua_call_make_call(),将发动不会话。  (3)hangup函数和pjsua_destroy函数  这两个函数用来封存和挂断不会话,一般在须要完结的时候调用,它们在接口函数中对应Java_com_android_  IMSandroid_pjsip_hangup和Java_com_android_IMSandroid_pjsip_destroy,由于没参数传递,也没其他的调用,因此这两个函数非常简单,基本上必要调用pjsua获取的pjsua_call_hangup_all()和pjsua_destroy()就能构建。

pisua中这两个函数将已完成内存获释、账户吊销等工作。  (4)add_account函数  该函数在基本的pjsua中并不是必需的,但如果要用于SIP服务器的话,就必需构建该函数,它在接口函数中对应Java_com_android_I-MSandroid_pjsip_add_1account,同make_call一样,也必须传送参数,有所不同的是,它传送三个参数,只是原理大体一样。

  首先它将参数转化成后维持到cfg,通过pjsua_acc_add(&cfg,PJ_TRUE,&ace_id)将参数加到到pjsua。pjsua将以其中的sip服务器为目的地址,登记不会话发动申请人,经过一系列的操作者之后,与目的地址发动不会话。


本文关键词:KOK官网,KOK平台,KOK首页

本文来源:KOK官网-www.autocarsphere.com