zoukankan      html  css  js  c++  java
  • CSipSimple结构浅析

      最近做一个VOIP的项目,调研了CSipSimple。都说CSipSimple结构清晰,但是代码下下来看了一下,还是一头雾水,不知从何看起。于是想到从最简单的打电话开始,借助网上一篇博文"CSipSimple 拨通电话机制分析",看看整个流程是怎么走的。由于工程围绕sip协议这个核心,因此我们从底层往上层逐步分析。

    流程梳理

       1. jni

      CSipSimple底层sip协议栈用的是pjsip,而pjsip是用c写的,这必然牵扯到jni的问题。jni的代码位于org.pjsip.pjsua包中。该包里面的文件非常多。目前我们先关心两个,一个是pjsuaJNI.java,另一个是pjsua.java,分别对应两个类。 ua是User Agent的简称,也就是客户端代理,用于处理打开会话,维护,收发等。pjsuaJNI里面的函数都有native关键字,这些函数是直接调用so库中用c写的函数的。从这里往上是java代码,是我们要关注的;往下是c代码,也就是pjsip的内容,暂时不管。pusua对pjsuaJNI作了一个轻度封装:基本上是直接调用。这样就对上层屏蔽了本地调用的代码。

         2. sip协议接口

      上面说到pjsua。该类可以理解为java层sip协议的接口。我们要用sip协议的哪个功能,最终都要调用该类的方法。与打电话相关的函数名为call_make_call,具体参数暂不作分析。另外还有call_setting_default函数等进行一些设置。

      3. sip服务

      sip协议接口中的函数都是基本函数,功能单一,不方便使用,因此作进一步分装。该封装位于包com.csipsimple.pjsip中。最主要的类为PjSipService。与打电话对应的函数是makeCall,它在打电话之前作了一些设置。PjSipService可以认为是高层次的API。目前来看,进行二次开发基本上调用这一层的代码就可以了。

      4. android框架

      以上其实都没有涉及到android的部分。为了维护一些状态等,也为了方便使用,CSipSimple把sip服务封装成了android中的标准service。所有的csipsimple的服务接口都定义在com.csipsimple.api中,与sip服务相关的定义是ISipService.aidl,其中关于打电话的函数是makeCallWithOptions。服务接口定义在aidl文件中,看来是为了方便进程间通信,不过这是后话,先不管。

      当然,eclipse会把aidl编译为java文件,在gen文件中,包名仍为com.csipsimple.api,文件名为ISipService.java。打开文件,毫无疑问会有一个makeCallWithOptions函数。

      接口的实现在com.csipsimple.service包中的SipService类。

      

    // Implement public interface for the service
        private final ISipService.Stub binder = new ISipService.Stub() {
            /**
             * {@inheritDoc}
             */
            @Override
            public void sipStart() throws RemoteException {
                SipService.this.enforceCallingOrSelfPermission(SipManager.PERMISSION_USE_SIP, null);
                Log.d(THIS_FILE, "Start required from third party app/serv");
                getExecutor().execute(new StartRunnable());
            }
            ... ...
    }

      上述服务肯定是要在android的服务管理器中注册的。

      5. 使用服务

      既然是标准的android服务,那么使用起来也是很简单的。使用服务的基本方法可以参考com.csipsimple.ui.dialpad.DialerFragment.java。先调用ServiceConnection.onServiceConnected()获得IBinder对象,再用ISipService.Stub.asInterface((IBinder)service)转为ISipService对象,这样就可以调用它的函数了。

    流程简图

      综合上述分析,可以得出如下简要流程图。  

      

      

      

  • 相关阅读:
    CentOS 5.5和5.6 安装后的网络配置
    CentOS 5.5 系统安全配置
    printk: messages suppressed
    “找不到出路的”vb6.0
    用户控件的烦扰
    rman恢复
    oracle数据字典
    oracle自关联表的子删父变功能实现
    oracle自治事务
    oracle表空间更名
  • 原文地址:https://www.cnblogs.com/zhizhizhiyuan/p/3816397.html
Copyright © 2011-2022 走看看