zoukankan      html  css  js  c++  java
  • IOT command (based on sip)client API设计 for java

    我们实现的物联网设备控制是通过扩展sip协议来实现的。
    由于是基于pjsip来实现的,而pjsip是使用C编程,如何使得业务层(android端,使用java)更容易使用提供的command API
    是重点,原始的方法就是从底层C开始往上层层封装(c--->jni--->java),这样存在明显的缺陷:
    1. 对于第三方开发开发难度大,工作量多,API设计不合理;
    2. 不同的设备控制业务接入代码都需要集成到主程序iot_sip_cli,高耦合,这是不能接受的(特别对于第三方开发)。
     
    所以倒过来考虑,利用IOC原则(don't call us, we'll call you),让第三方开发直接在java层来实现,提供接口给第三方让其将实现注册到iot_sip_cli_jni层,最后jni层的调用被iot_sip_cli驱动。
     
    举例: 接入一个叫test_plugin的设备类型, 它有两个方法test1, test5.
     
    1. 第三方开发首先定义方法的响应处理
    public class TestPluginCallBack {
               //以下两个方法最终被iot_sip_cli调用
    @CmdCBAnnotation(dev_type = "test_plugin", method_name = "test1")
     public void setId(int ret, String retJson) {
    }
     
     @CmdCBAnnotation(dev_type = "test_plugin", method_name = "test5")
     public void setId2(int ret, String retJson) {
    }
     
    };
     
    2.第三方开发将上面的对象,方法传递给 sdk(由sdk内部的IOTCmdAttachment负责):
         
     IOTCmdAttachment att = IOTCmdAttachment.getSingleton();
     TestPluginCallBack cbObj = new TestPluginCallBack();
     att.registerCmdHandlers(cbObj);
     
    3. 第三方开发,写设备控制的请求发送
            att.inputCommand("test_plugin", "test1", reqJson, toUri); //响应结果retJson通过第一步的方法传到业务层。
     
    这样,第三方开发只要通过上面3个步骤,就能完成对接入设备控制的实现。
     
    过程原理如下图所示(提供给第三方的sdk由CMD_API_4JAVA jar包,和IOT_CMD_JNI so构成):
     
    主要步骤在于IOTCmdAttachment方法registerCmdHandlers的使用:
    利用自定义的java注解CmdCBAnnotation, 识别出需要调用的函数,将其传给 jni_reg_cmdcb(它内部调用reg_handler), 
     public int registerCmdHandlers(Object obj) {
        int status = 0;
        for (Method m : obj.getClass().getMethods()) {
            CmdCBAnnotation a = m.getAnnotation(CmdCBAnnotation.class);
            if (a != null) {
                Log.d(LOG_TAG, "" + a.dev_type() + ":" + a.method_name());
                status =  jni_reg_cmdcb(a.dev_type(), a.method_name(), obj, m);
                if (0 != status)
                return status; 
            }
        }
    
        return status;
     }
     static int reg_handler(jstring dev_type,  jstring method_name,  jobject jobj,
      jobject jmeth) 
    {
         __android_log_print(ANDROID_LOG_INFO, TAGSTR, "reg_handler");
    
         JNIEnv *env = get_jni_env();
         std::string str_devtype = jstring2str(env, dev_type);
         std::string str_methname = jstring2str(env, method_name);
    
        //生成DeviceCmdHandler对象,存储设备类型名,设备方法名(即上面注解@CmdCBAnnotation dev_type, method_name值), 
        //TestPluginCallBack对象,和被注解的java方法
         DeviceCmdHandler * pt_dchdl = new DeviceCmdHandler(str_devtype,
           str_methname, jobj, jmeth);
    
        //DeviceCmdHandler::methodCallBack4c会使用pt_dchdl作为参数,并且它作为回调函数将被iot_sip_cli调用
         int ret = cmd_cb_reg4cpp(str_devtype.c_str(), str_methname.c_str(),
           &DeviceCmdHandler::methodCallBack4c, pt_dchdl);
         if (0 != ret)
         {
              __android_log_print(ANDROID_LOG_ERROR, TAGSTR, "reg_handler fail ret %d:%s %s", ret, str_devtype.c_str(), 
            str_methname.c_str());
         }
         else
         {
            __android_log_print(ANDROID_LOG_INFO, TAGSTR, "reg_handler succ:%s %s", str_devtype.c_str(), str_methname.c_str());
         }
         return ret;
    }

      

     
    DeviceCmdHandler类如下:
     
    int DeviceCmdHandler::methodCallBack4c(int ret_i, const char * ret_json,
      void * pt_obj) {
         return ((DeviceCmdHandler *) pt_obj)->methodCallBack(ret_i, ret_json);
    }
    而 DeviceCmdHandler::methodCallBack(int ret_i, const char * ret_json)方法,最终调用
    CallObjectMethod(env, this->mJmethod, mid, jo, (jobjectArray) texts); 即调用java层的TestPluginCallBack两个注解的方法。
     
    mid获取, 使用java.lang.reflect.Method:
     JLocalRef<jclass> clazz = env->GetObjectClass(this->mJmethod);
     jmethodID mid = env->GetMethodID(clazz, "invoke",   "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;")
  • 相关阅读:
    审 讯 技巧
    带参数的多线程的方式
    通达信日线 数据格式
    visual studio 2012 update3
    单实例运行tz
    维特比算法
    Kooboo CMS的安装步骤
    年龄
    富文本编辑器---非常实用的
    printf 打印 unit32_t
  • 原文地址:https://www.cnblogs.com/europelee/p/4740118.html
Copyright © 2011-2022 走看看