CSipSimple程序之基本功能(三)
来源:互联网 发布:舜宇光学 知乎 编辑:程序博客网 时间:2024/06/04 23:24
4 PJSUA操作
在上面的添加用户操作中,其实已经和底层的JNI打交道了,如执行SipService.setAccountRegistration()这个函数之后就会调用底层的JNI库。而在执行这些JNI库之前。又关于PJSUA的一些初始化设置。这一节主要说明这个。
在说明进行初始化之前,先说明下PJSIP库框架,其框架如图12所示:
图12 PJSIP框架
图12展示了PJSIP框架的各模块,可以看出从上到下,Application(pjsua)模块可调用下层所有的模块,也即是PJSUA处于最高层,其整合了下层模块的全部功能,所以这也就是为什么我们基本的操作都在PJSUA这里进行。是因为通过PJSUA,我们就能很方便的深入到其他模块中。接着Application模块往下就是PJSUA_lib层,要让应用层(PJSUA)能更好的调用,当然得有个封装好的库,这个库就是PJSUA_LIB库,称为高层用户代理库,集合SIP,Media以及NAT穿越,所以也就有了往下的PJMEDIA-CODEC和PJMEDIA(负责SDP协商媒体编码和媒体传输),PJNATH(解决NAT穿越),PJSUA-UA(提供SIP用户代理库),PJSIP-SIMPLE(实现presence和及时消息),PJSIP(核协议栈,SIP协议),PJLIB-UTIL(提供有用的工具函数)以及PJLIB(每个功能根据其所在的层次以及负责的功能提供丰富的接口)等模块。
知道了PJSIP的基本框架之后,我们回到CSipSimple,在SIP_HOME UI中的OnResume函数下会进行SipService开启。即通过如图13语句之后进入SipService。
// Service monitoring stuff private void startSipService() { Thread t = new Thread("StartSip") { public void run() { Intent serviceIntent = new Intent(SipManager.INTENT_SIP_SERVICE); serviceIntent.putExtra(SipManager.EXTRA_OUTGOING_ACTIVITY, new ComponentName(SipHome.this, SipHome.class)); startService(serviceIntent); //启动了SipService postStartSipService(); }; }; t.start(); }
图13 通过Intent启动SipService
Service的生命周期因不同的启动方式会有所不同,这里是通过context.startService启动的。所以其生命周期如下:context.startService() ->onCreate()- >onStart()->Service running-->context.stopService()->onDestroy() ->Service stop。通过onStart()函数,加载JNI库(会跳到PjSipService的tryToLoadStack方法执行),如图14所示:
public boolean tryToLoadStack() { if (hasSipStack) { return true; } // File stackFile = NativeLibManager.getStackLibFile(service); if (!sipStackIsCorrupted) { try { // Try to load the stack // System.load(NativeLibManager.getBundledStackLibFile(service, // "libcrypto.so").getAbsolutePath()); // System.load(NativeLibManager.getBundledStackLibFile(service, // "libssl.so").getAbsolutePath()); // System.loadLibrary("crypto"); // System.loadLibrary("ssl"); System.loadLibrary(NativeLibManager.STD_LIB_NAME); //加载jni本地库 System.loadLibrary(NativeLibManager.STACK_NAME); hasSipStack = true; return true; } catch (UnsatisfiedLinkError e) { ... } catch (Exception e) { ... } } return false; }
图14 PjSipService类加载JNI库
而何时进行PJSUA初始化,CSipSimple中,在SipService开始,通过相关的调用完成的。从图7可看到,当注册完广播接收器之后还进行了这一步:deviceStateReceiver.startMonitoring()。这是程序进入DynamicReciever4的startMonitoring()函数,进而在onConnectivityChanged()函数中调用了SipService的restartSipStack函数,从而进入startSipStack()函数并调用了pjService.sipStart()方法。而这个sipStart()函数就是PJSUA初始化的所在处。
我们进入sipStart函数,结合PJSIP开发文档。从开发文档中我们知道,基础的PJSUA-API控制PJSUA的创建,初始化,启动,同时还提供各种辅助功能。在sipStart函数中,通过status = pjsua.create();完成pjsua的创建,除其他事项外,还初始化PJLIB,PJLIB-UTIL,并创建了一个SIP endpoint。在调用任何PJLIB功能之前这是至关重要的一步。
进行了上面的初始化之后,并进行一些General Configure。一般情况下,应用程序都将通常需要执行一些任务,使用pjsua_transport_create()方法(该方法是C语言)来创建SIP传输。故在CSipSimple中有createTransport这样的方法来创建SIP传输。完成这些初始化之后,应用程序必须调用status = pjsua.start()开始PJSUA,此函数将检查所有的配置是否正确,如果没有则采用默认配置。
经过上面的初始化之后,我们就可以进一步解释2.3节的添加用户操作中,PJSUA是如何操作的。
在2.3节中已经说过,用户添加是从接收器DynamicReceiver4执行了SipService.setAccountRegistration这个函数开始的,确切的讲,连接底层JNI库的都在PjSipService中进行,此处也是这样。进入到PjSipService中的setAccountRegistration方法。然后根据account的不同情况进行不同的操作,首次添加用户将会进行这一步status = pjsua.acc_add(account.cfg, pjsuaConstants.PJ_FALSE, accId)。这里acc_add即调用了底层的JNI库的pjsuaJNI.acc_add,从而返回添加成功与否的状态。根据该状态进行相应状态的改变,从而改变显示界面,这也是2.3节中最后一点讲到的内容观察者ContentObserver的作用。
- CSipSimple程序之基本功能(三)
- CSipSimple程序之基本功能(一)
- CSipSimple程序之基本功能(二)
- CSipSimple程序之框架介绍
- CSipSimple程序之拨打电话
- CSipSimple程序之拨打电话
- CSipSimple程序
- 微信小程序之六(表单基本功能)
- FreeSwitch:三、编译CSipSimple
- Android 语音通话模块介绍(三) CSipSimple介绍
- 语音通话模块介绍(三) CSipSimple介绍
- opengl学习之三:OpenGL基本功能
- php框架laravel学习 三 (基本功能)
- WebGIS小结之二(基本功能概述)
- bash基本功能之别名(alias)
- jiglib 最基本功能程序
- 模拟实现ASP.NET框架基本功能(三)
- 简易聊天程序教程(二)服务器的基本功能
- S3C2440上LCD驱动(FrameBuffer)开发(一)
- fedora18启动ssh服务 & filezilla连接fedora
- C语言值传递 地址传递 引用传递
- MiniGUI 体系结构之四——图形抽象层和输入抽象层及 Native Engine 的实现(一)
- Failed to retrieve procctx from ht. constr
- CSipSimple程序之基本功能(三)
- LCS算法学习
- JAVA---金字塔
- 黑马程序员 java基础--》 if语句与switch语句 小结
- 重新再来
- MiniGUI 体系结构之四——图形抽象层和输入抽象层及 Native Engine 的实现(二)
- 个人博客开通啦~~~~
- S3C2440上LCD驱动(FrameBuffer)开发(二)
- 砝码 碎片问题