DBMNG数据库管理与应用

书籍是全世界的营养品。生活里没有书籍,就好像没有阳光;智慧里没有书籍,就好像鸟儿没有翅膀。
当前位置:首页 > 移动应用 > Android

CSipSimple程序之基本功能

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。

[java] view plaincopy
  1. <pre name="code" class="java">// Service monitoring stuff  
  2.     private void startSipService() {  
  3.         Thread t = new Thread("StartSip") {  
  4.             public void run() {  
  5.                 Intent serviceIntent = new Intent(SipManager.INTENT_SIP_SERVICE);   
  6.                 serviceIntent.putExtra(SipManager.EXTRA_OUTGOING_ACTIVITY, new ComponentName(SipHome.this, SipHome.class));  
  7.                 startService(serviceIntent); //启动了SipService  
  8.                 postStartSipService();  
  9.             };  
  10.         };  
  11.         t.start();  
  12.   
  13.     }</pre>  


图13 通过Intent启动SipService

         Service的生命周期因不同的启动方式会有所不同,这里是通过context.startService启动的。所以其生命周期如下:context.startService() ->onCreate()- >onStart()->Service running-->context.stopService()->onDestroy() ->Service stop。通过onStart()函数,加载JNI库(会跳到PjSipService的tryToLoadStack方法执行),如图14所示:

[java] view plaincopy
  1. public boolean tryToLoadStack() {  
  2.         if (hasSipStack) {  
  3.             return true;  
  4.         }  
  5.   
  6.         // File stackFile = NativeLibManager.getStackLibFile(service);  
  7.         if (!sipStackIsCorrupted) {  
  8.             try {  
  9.                 // Try to load the stack  
  10.                 // System.load(NativeLibManager.getBundledStackLibFile(service,  
  11.                 // "libcrypto.so").getAbsolutePath());  
  12.                 // System.load(NativeLibManager.getBundledStackLibFile(service,  
  13.                 // "libssl.so").getAbsolutePath());  
  14.                 // System.loadLibrary("crypto");  
  15.                 // System.loadLibrary("ssl");  
  16.                 System.loadLibrary(NativeLibManager.STD_LIB_NAME); //加载jni本地库  
  17.                 System.loadLibrary(NativeLibManager.STACK_NAME);  
  18.                 hasSipStack = true;  
  19.                 return true;  
  20.             } catch (UnsatisfiedLinkError e) {  
  21.                 ...  
  22.             } catch (Exception e) {  
  23.                ...  
  24.             }  
  25.         }  
  26.         return false;  
  27.     }  


图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的作用。

本站文章内容,部分来自于互联网,若侵犯了您的权益,请致邮件chuanghui423#sohu.com(请将#换为@)联系,我们会尽快核实后删除。
Copyright © 2006-2023 DBMNG.COM All Rights Reserved. Powered by DEVSOARTECH            豫ICP备11002312号-2

豫公网安备 41010502002439号