瀏覽代碼

提交初始代码

wjg 1 年之前
父節點
當前提交
d796eddb8e
共有 100 個文件被更改,包括 9875 次插入0 次删除
  1. 69 0
      app/build.gradle.kts
  2. 21 0
      app/proguard-rules.pro
  3. 26 0
      app/src/androidTest/java/com/ch/jedge/demo/glm/ExampleInstrumentedTest.java
  4. 54 0
      app/src/main/AndroidManifest.xml
  5. 10 0
      app/src/main/assets/cfg/jbot.json
  6. 11 0
      app/src/main/assets/cfg/jsmart.json
  7. 10 0
      app/src/main/assets/cfg/llm.json
  8. 11 0
      app/src/main/assets/cfg/tvass.json
  9. 22 0
      app/src/main/assets/cfg/vdb.json
  10. 89 0
      app/src/main/cpp/CMakeLists.txt
  11. 11 0
      app/src/main/cpp/inc/awasl/awaker_main.h
  12. 247 0
      app/src/main/cpp/inc/cmdnsc/cJSON.h
  13. 77 0
      app/src/main/cpp/inc/cmdnsc/cm_hashtable.h
  14. 195 0
      app/src/main/cpp/inc/cmdnsc/cmdns.h
  15. 67 0
      app/src/main/cpp/inc/cmdnsc/cmdns_hal_intf.h
  16. 35 0
      app/src/main/cpp/inc/cosasl/BodySensorTimer.h
  17. 46 0
      app/src/main/cpp/inc/cosasl/CThread.h
  18. 34 0
      app/src/main/cpp/inc/cosasl/CThreadPool.h
  19. 16 0
      app/src/main/cpp/inc/cosasl/CWorkerThread.h
  20. 22 0
      app/src/main/cpp/inc/cosasl/CossBridgeClass.h
  21. 107 0
      app/src/main/cpp/inc/cosasl/CossDevPropertyUtil.h
  22. 18 0
      app/src/main/cpp/inc/cosasl/CossHttpService.h
  23. 13 0
      app/src/main/cpp/inc/cosasl/CossInterface.h
  24. 34 0
      app/src/main/cpp/inc/cosasl/DaemonWorker.h
  25. 115 0
      app/src/main/cpp/inc/cosasl/DevTree.h
  26. 108 0
      app/src/main/cpp/inc/cosasl/DeviceExtra.h
  27. 40 0
      app/src/main/cpp/inc/cosasl/DeviceInfo.h
  28. 44 0
      app/src/main/cpp/inc/cosasl/DeviceStatusService.h
  29. 27 0
      app/src/main/cpp/inc/cosasl/DoorSensorTimer.h
  30. 21 0
      app/src/main/cpp/inc/cosasl/FileWriteWorker.h
  31. 110 0
      app/src/main/cpp/inc/cosasl/GasTransTable.h
  32. 37 0
      app/src/main/cpp/inc/cosasl/JECossServer.h
  33. 68 0
      app/src/main/cpp/inc/cosasl/LightjiaSceneProcess.h
  34. 23 0
      app/src/main/cpp/inc/cosasl/MessagePackUtil.h
  35. 67 0
      app/src/main/cpp/inc/cosasl/MgBusInterface.h
  36. 61 0
      app/src/main/cpp/inc/cosasl/MgBusManager.h
  37. 1306 0
      app/src/main/cpp/inc/cosasl/OriginalHttplib.h
  38. 190 0
      app/src/main/cpp/inc/cosasl/SceneManager.h
  39. 36 0
      app/src/main/cpp/inc/cosasl/SceneThreadPool.h
  40. 47 0
      app/src/main/cpp/inc/cosasl/SceneWorker.h
  41. 19 0
      app/src/main/cpp/inc/cosasl/SystemCmd.h
  42. 28 0
      app/src/main/cpp/inc/cosasl/TimerWorker.h
  43. 74 0
      app/src/main/cpp/inc/cosasl/app_request_process.h
  44. 12 0
      app/src/main/cpp/inc/cosasl/cosasl_main.h
  45. 186 0
      app/src/main/cpp/inc/cosasl/coss_comm.h
  46. 29 0
      app/src/main/cpp/inc/cosasl/device_msg_process.h
  47. 48 0
      app/src/main/cpp/inc/cosasl/lightjiaapp_request_process.h
  48. 97 0
      app/src/main/cpp/inc/cosasl/log_tool.h
  49. 12 0
      app/src/main/cpp/inc/cosasl/msg_process.h
  50. 76 0
      app/src/main/cpp/inc/cosasl/scene_comm.h
  51. 22 0
      app/src/main/cpp/inc/cross/DllUtil.h
  52. 43 0
      app/src/main/cpp/inc/cross/SystemUtil.h
  53. 10 0
      app/src/main/cpp/inc/cross/ctypes.h
  54. 36 0
      app/src/main/cpp/inc/cross/ifaddr.h
  55. 54 0
      app/src/main/cpp/inc/cross/platform.h
  56. 16 0
      app/src/main/cpp/inc/cross/sysdef.h
  57. 210 0
      app/src/main/cpp/inc/do/JADebugOperationService.h
  58. 104 0
      app/src/main/cpp/inc/do/JAExtCommandor.h
  59. 62 0
      app/src/main/cpp/inc/do/JAVdaoDebuggers.h
  60. 20 0
      app/src/main/cpp/inc/exlib/EXFileUtils.h
  61. 135 0
      app/src/main/cpp/inc/exlib/JAMgModuleHelper.h
  62. 32 0
      app/src/main/cpp/inc/exlib/JGateClient.h
  63. 186 0
      app/src/main/cpp/inc/exlib/QExMgbusServer.h
  64. 260 0
      app/src/main/cpp/inc/exlib/QJAExObjects.h
  65. 21 0
      app/src/main/cpp/inc/exlib/QJAExtModuleBase.h
  66. 45 0
      app/src/main/cpp/inc/exlib/QJAMgUtils.h
  67. 131 0
      app/src/main/cpp/inc/exlib/QJAServer.h
  68. 337 0
      app/src/main/cpp/inc/exlib/QJAService.h
  69. 93 0
      app/src/main/cpp/inc/exlib/QJAServiceEntry.h
  70. 68 0
      app/src/main/cpp/inc/exlib/QJedgeJniServiceUtil.h
  71. 154 0
      app/src/main/cpp/inc/exlib/QMqttClient.h
  72. 66 0
      app/src/main/cpp/inc/exlib/QMqttMessageDeliver.h
  73. 180 0
      app/src/main/cpp/inc/exlib/QTaskManager.h
  74. 71 0
      app/src/main/cpp/inc/exlib/http/ECSInvokeService.h
  75. 84 0
      app/src/main/cpp/inc/exlib/http/QASyncHttpServer.h
  76. 120 0
      app/src/main/cpp/inc/exlib/http/QHttpClient.h
  77. 17 0
      app/src/main/cpp/inc/exlib/http/QHttpCommon.h
  78. 80 0
      app/src/main/cpp/inc/exlib/http/QHttpSSLClient.h
  79. 127 0
      app/src/main/cpp/inc/exlib/http/QHttpServer.h
  80. 41 0
      app/src/main/cpp/inc/exlib/sock/JESockCommProtocol.h
  81. 36 0
      app/src/main/cpp/inc/exlib/sock/MgNodeManagerService.h
  82. 134 0
      app/src/main/cpp/inc/exlib/sock/QNodeClient.h
  83. 184 0
      app/src/main/cpp/inc/exlib/sock/QNodeServer.h
  84. 51 0
      app/src/main/cpp/inc/exlib/sock/QSockClient.h
  85. 150 0
      app/src/main/cpp/inc/exlib/sysdev/SysDevcie.h
  86. 202 0
      app/src/main/cpp/inc/exlib/sysdev/SysDeviceService.h
  87. 578 0
      app/src/main/cpp/inc/exlibv/JAExObjectV.h
  88. 43 0
      app/src/main/cpp/inc/exlibv/JAExUtil.h
  89. 84 0
      app/src/main/cpp/inc/exlibv/JedpUtil.h
  90. 87 0
      app/src/main/cpp/inc/exlibv/SerialUtil.h
  91. 403 0
      app/src/main/cpp/inc/gafasl/QGAActionObjects.h
  92. 20 0
      app/src/main/cpp/inc/gafasl/QGABaseObject.h
  93. 362 0
      app/src/main/cpp/inc/gafasl/QGADataPool.h
  94. 13 0
      app/src/main/cpp/inc/gafasl/QGaConsts.h
  95. 131 0
      app/src/main/cpp/inc/gafasl/QGaControllerUtil.h
  96. 88 0
      app/src/main/cpp/inc/gafasl/QGaCypherPluginEntry.h
  97. 37 0
      app/src/main/cpp/inc/gafasl/QGaHongdouPluginEntry.h
  98. 223 0
      app/src/main/cpp/inc/gafasl/QGaHongmeiPluginEntry.h
  99. 43 0
      app/src/main/cpp/inc/gafasl/QGaJedgePluginEntry.h
  100. 55 0
      app/src/main/cpp/inc/gafasl/QGaUdGaoImpl.h

+ 69 - 0
app/build.gradle.kts

@@ -0,0 +1,69 @@
+plugins {
+    id("com.android.application")
+}
+
+android {
+    namespace = "com.ch.jedge.demo.glm"
+    compileSdk = 33
+
+    defaultConfig {
+        applicationId = "com.ch.jedge.demo.glm"
+        minSdk = 24
+        targetSdk = 33
+        versionCode = 1
+        versionName = "1.0"
+
+        testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
+        externalNativeBuild {
+            cmake {
+                cppFlags += ""
+                abiFilters("armeabi-v7a")
+            }
+        }
+        ndk {
+            abiFilters.add("armeabi-v7a")
+        }
+    }
+
+    buildTypes {
+        release {
+            isMinifyEnabled = false
+            proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro")
+        }
+    }
+    compileOptions {
+        sourceCompatibility = JavaVersion.VERSION_1_8
+        targetCompatibility = JavaVersion.VERSION_1_8
+    }
+    externalNativeBuild {
+        cmake {
+            path = file("src/main/cpp/CMakeLists.txt")
+            version = "3.22.1"
+        }
+    }
+}
+
+dependencies {
+
+    implementation("androidx.appcompat:appcompat:1.6.1")
+    implementation("com.google.android.material:material:1.8.0")
+    implementation("androidx.constraintlayout:constraintlayout:2.1.4")
+    implementation(files("libs\\qlibj.jar"))
+    implementation(files("libs\\jedge.jar"))
+    implementation(files("libs\\jesock.jar"))
+    implementation(files("libs\\fastjson-1.2.28.jar"))
+    implementation(files("libs\\okhttp-3.14.9.jar"))
+    implementation(files("libs\\okhttp-sse-3.14.9.jar"))
+    implementation(files("libs\\druid-1.2.4.jar"))
+    implementation(files("libs\\commons-math3-3.6.1.jar"))
+    implementation(files("libs\\slf4j-api-1.7.30.jar"))
+    implementation(files("libs\\gson-2.8.9.jar"))
+    implementation(files("libs\\okio-1.17.2.jar"))
+    implementation(files("libs\\java-jwt-4.2.2.jar"))
+    implementation(files("libs\\jackson-annotations-2.12.7.jar"))
+    implementation(files("libs\\jackson-core-2.12.7.jar"))
+    implementation(files("libs\\jackson-databind-2.12.7.1.jar"))
+    testImplementation("junit:junit:4.13.2")
+    androidTestImplementation("androidx.test.ext:junit:1.1.5")
+    androidTestImplementation("androidx.test.espresso:espresso-core:3.5.1")
+}

+ 21 - 0
app/proguard-rules.pro

@@ -0,0 +1,21 @@
+# Add project specific ProGuard rules here.
+# You can control the set of applied configuration files using the
+# proguardFiles setting in build.gradle.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
+
+# Uncomment this to preserve the line number information for
+# debugging stack traces.
+#-keepattributes SourceFile,LineNumberTable
+
+# If you keep the line number information, uncomment this to
+# hide the original source file name.
+#-renamesourcefileattribute SourceFile

+ 26 - 0
app/src/androidTest/java/com/ch/jedge/demo/glm/ExampleInstrumentedTest.java

@@ -0,0 +1,26 @@
+package com.ch.jedge.demo.glm;
+
+import android.content.Context;
+
+import androidx.test.platform.app.InstrumentationRegistry;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.junit.Assert.*;
+
+/**
+ * Instrumented test, which will execute on an Android device.
+ *
+ * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
+ */
+@RunWith(AndroidJUnit4.class)
+public class ExampleInstrumentedTest {
+    @Test
+    public void useAppContext() {
+        // Context of the app under test.
+        Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
+        assertEquals("com.ch.jedge.demo.glm", appContext.getPackageName());
+    }
+}

+ 54 - 0
app/src/main/AndroidManifest.xml

@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
+
+    <uses-permission android:name="android.permission.INTERNET"/>
+    <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL"
+        tools:ignore="ProtectedPermissions" />
+    <uses-permission
+        android:name="android.permission.WRITE_EXTERNAL_STORAGE"
+        tools:ignore="ScopedStorage" />
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+    <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
+
+    <application
+        android:allowBackup="true"
+        android:dataExtractionRules="@xml/data_extraction_rules"
+        android:fullBackupContent="@xml/backup_rules"
+        android:icon="@mipmap/ic_launcher"
+        android:label="@string/app_name"
+        android:roundIcon="@mipmap/ic_launcher_round"
+        android:supportsRtl="true"
+        android:theme="@style/Theme.JedgeGLMDemo"
+        tools:targetApi="31">
+        <activity
+            android:name=".MainActivity"
+            android:exported="true">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+
+        <service
+            android:name=".service.MgsService"
+            android:exported="false">
+        </service>
+        <service
+            android:name=".service.JBotService"
+            android:exported="false">
+        </service>
+        <service
+            android:name=".service.JGlmService"
+            android:exported="false">
+        </service>
+        <service
+            android:name=".service.TVAgentService"
+            android:exported="false">
+        </service>
+
+    </application>
+
+</manifest>

+ 10 - 0
app/src/main/assets/cfg/jbot.json

@@ -0,0 +1,10 @@
+{
+  "jedge": {
+    "host1": "hw.jedge.top",
+    "host3": "hw.jedge.top",
+    "host4": "localhost",
+    "host": "127.0.0.1",
+    "port": 8877,
+    "name": "jbot!"
+  }
+}

+ 11 - 0
app/src/main/assets/cfg/jsmart.json

@@ -0,0 +1,11 @@
+{
+  "debug": true,
+  "jedge": {
+    "host1": "hw.jedge.top",
+    "host3": "hw.jedge.top",
+    "host4": "localhost",
+    "host": "127.0.0.1",
+    "port": 8877,
+    "name": "jsm"
+  }
+}

+ 10 - 0
app/src/main/assets/cfg/llm.json

@@ -0,0 +1,10 @@
+{
+  "jedge": {
+    "host1": "hw.jedge.top",
+    "host3": "hw.jedge.top",
+    "host4": "localhost",
+    "host": "127.0.0.1",
+    "port": 8877,
+    "name": "llm!"
+  }
+}

+ 11 - 0
app/src/main/assets/cfg/tvass.json

@@ -0,0 +1,11 @@
+{
+  "debug": true,
+  "jedge": {
+    "host1": "hw.jedge.top",
+    "host3": "hw.jedge.top",
+    "host4": "localhost",
+    "host": "127.0.0.1",
+    "port": 8877,
+    "name": "tvass"
+  }
+}

+ 22 - 0
app/src/main/assets/cfg/vdb.json

@@ -0,0 +1,22 @@
+{
+  "debug": true,
+  "jedge": {
+    "host1": "hw.jedge.top",
+    "host3": "hw.jedge.top",
+    "host4": "localhost",
+    "host": "192.168.1.20",
+    "port": 8877,
+    "name": "vdb!"
+  },
+  "milvus": {
+    "hosts":[{
+      "host":"192.168.1.202",
+      "port":19530,
+      "collections1":[
+        "JedgeVec"
+      ]
+    }],
+    "prop":true,
+    "default":"testLab"
+  }
+}

+ 89 - 0
app/src/main/cpp/CMakeLists.txt

@@ -0,0 +1,89 @@
+
+# For more information about using CMake with Android Studio, read the
+# documentation: https://d.android.com/studio/projects/add-native-code.html.
+# For more examples on how to use CMake, see https://github.com/android/ndk-samples.
+
+# Sets the minimum CMake version required for this project.
+cmake_minimum_required(VERSION 3.22.1)
+
+# Declares the project name. The project name can be accessed via ${ PROJECT_NAME},
+# Since this is the top level CMakeLists.txt, the project name is also accessible
+# with ${CMAKE_PROJECT_NAME} (both CMake variables are in-sync within the top level
+# build script scope).
+project("JedgeGLMDemo")
+
+# Creates and names a library, sets it as either STATIC
+# or SHARED, and provides the relative paths to its source code.
+# You can define multiple libraries, and CMake builds them for you.
+# Gradle automatically packages shared libraries with your APK.
+#
+# In this top level CMakeLists.txt, ${CMAKE_PROJECT_NAME} is used to define
+# the target library name; in the sub-module's CMakeLists.txt, ${PROJECT_NAME}
+# is preferred for the same purpose.
+#
+# In order to load a library into your app from Java/Kotlin, you must call
+# System.loadLibrary() and pass the name of the library defined here;
+# for GameActivity/NativeActivity derived applications, the same library name must be
+# used in the AndroidManifest.xml file.
+add_library( # Sets the name of the library.
+        mgs-driver
+        # Sets the library as a shared library.
+        SHARED
+        # Provides a relative path to your source file(s).
+        mgs-driver.cpp)
+
+target_include_directories(mgs-driver PRIVATE
+        ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/inc)
+
+add_library(cross SHARED IMPORTED)
+set_target_properties(cross PROPERTIES IMPORTED_LOCATION
+        ${CMAKE_SOURCE_DIR}/../jniLibs/armeabi-v7a/libcross.so)
+
+add_library(cmdnsc SHARED IMPORTED)
+set_target_properties(cmdnsc PROPERTIES IMPORTED_LOCATION
+        ${CMAKE_SOURCE_DIR}/../jniLibs/armeabi-v7a/libcmdnsc.so)
+
+add_library(json SHARED IMPORTED)
+set_target_properties(json PROPERTIES IMPORTED_LOCATION
+        ${CMAKE_SOURCE_DIR}/../jniLibs/armeabi-v7a/libjson.so)
+
+add_library(qlibc SHARED IMPORTED)
+set_target_properties(qlibc PROPERTIES IMPORTED_LOCATION
+        ${CMAKE_SOURCE_DIR}/../jniLibs/armeabi-v7a/libqlibc.so)
+
+add_library(jadom2 SHARED IMPORTED)
+set_target_properties(jadom2 PROPERTIES IMPORTED_LOCATION
+        ${CMAKE_SOURCE_DIR}/../jniLibs/armeabi-v7a/libjadom2.so)
+
+add_library(mgbus SHARED IMPORTED)
+set_target_properties(mgbus PROPERTIES IMPORTED_LOCATION
+        ${CMAKE_SOURCE_DIR}/../jniLibs/armeabi-v7a/libmgbus.so)
+
+add_library(exlib SHARED IMPORTED)
+set_target_properties(exlib PROPERTIES IMPORTED_LOCATION
+        ${CMAKE_SOURCE_DIR}/../jniLibs/armeabi-v7a/libexlib.so)
+
+add_library(mgsasl SHARED IMPORTED)
+set_target_properties(mgsasl PROPERTIES IMPORTED_LOCATION
+        ${CMAKE_SOURCE_DIR}/../jniLibs/armeabi-v7a/libmgsasl.so)
+
+add_library(exlibv SHARED IMPORTED)
+set_target_properties(exlibv PROPERTIES IMPORTED_LOCATION
+        ${CMAKE_SOURCE_DIR}/../jniLibs/armeabi-v7a/libexlibv.so)
+
+find_library( # Sets the name of the path variable.
+        std-lib
+        # Specifies the name of the NDK library that
+        # you want CMake to locate.
+        log )
+
+# Specifies libraries CMake should link to your target library. You
+# can link libraries from various origins, such as libraries defined in this
+# build script, prebuilt third-party libraries, or Android system libraries.
+target_link_libraries( # Specifies the target library.
+        mgs-driver
+        # Links the target library to the log library
+        # included in the NDK.
+        ${log-lib}
+        ${std-lib} mgsasl
+        cross cmdnsc json qlibc jadom2 mgbus exlib )

+ 11 - 0
app/src/main/cpp/inc/awasl/awaker_main.h

@@ -0,0 +1,11 @@
+//
+// Created by Ht on 2022/12/16.
+//
+
+#ifndef INC_1_LIBDEVCPP_AWAKER_MAIN_H
+#define INC_1_LIBDEVCPP_AWAKER_MAIN_H
+
+void awakerasl_main(const std::string& dir, const std::string& dir_cache);
+
+
+#endif //INC_1_LIBDEVCPP_AWAKER_MAIN_H

+ 247 - 0
app/src/main/cpp/inc/cmdnsc/cJSON.h

@@ -0,0 +1,247 @@
+/*
+Copyright (c) 2009-2017 Dave Gamble and cJSON contributors
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+*/
+
+#ifndef cJSON__h
+#define cJSON__h
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+	/* project version */
+#define CJSON_VERSION_MAJOR 1
+#define CJSON_VERSION_MINOR 5
+#define CJSON_VERSION_PATCH 3
+
+#include <stdint.h>
+#include <stddef.h>
+
+	/* cJSON Types: */
+#define cJSON_Invalid (0)
+#define cJSON_False  (1 << 0)
+#define cJSON_True   (1 << 1)
+#define cJSON_NULL   (1 << 2)
+#define cJSON_Number (1 << 3)
+#define cJSON_String (1 << 4)
+#define cJSON_Array  (1 << 5)
+#define cJSON_Object (1 << 6)
+#define cJSON_Raw    (1 << 7) /* raw json */
+
+#define cJSON_IsReference 256
+#define cJSON_StringIsConst 512
+
+	/* The cJSON structure: */
+	typedef struct cJSON
+	{
+		/* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */
+		struct cJSON *next;
+		struct cJSON *prev;
+		/* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */
+		struct cJSON *child;
+
+		/* The type of the item, as above. */
+		int type;
+
+		/* The item's string, if type==cJSON_String  and type == cJSON_Raw */
+		char *valuestring;
+		/* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */
+		int valueint;
+		/* The item's number, if type==cJSON_Number */
+		double valuedouble;
+
+		/* The item's name string, if this item is the child of, or is in the list of subitems of an object. */
+		char *string;
+	} cJSON;
+
+	typedef int cJSON_bool;
+
+#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32))
+#define __WINDOWS__
+#endif
+#ifdef __WINDOWS__
+
+	/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention.  For windows you have 2 define options:
+	CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols
+	CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default)
+	CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol
+	For *nix builds that support visibility attribute, you can define similar behavior by
+	setting default visibility to hidden by adding
+	-fvisibility=hidden (for gcc)
+	or
+	-xldscope=hidden (for sun cc)
+	to CFLAGS
+	then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does
+	*/
+
+	/* export symbols by default, this is necessary for copy pasting the C and header file */
+#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS)
+#define CJSON_EXPORT_SYMBOLS
+#endif
+
+#if defined(CJSON_HIDE_SYMBOLS)
+#define CJSON_PUBLIC(type)   type __stdcall
+#elif defined(CJSON_EXPORT_SYMBOLS)
+#define CJSON_PUBLIC(type)   __declspec(dllexport) type __stdcall
+#elif defined(CJSON_IMPORT_SYMBOLS)
+#define CJSON_PUBLIC(type)   __declspec(dllimport) type __stdcall
+#endif
+#else /* !WIN32 */
+#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY)
+#define CJSON_PUBLIC(type)   __attribute__((visibility("default"))) type
+#else
+#define CJSON_PUBLIC(type) type
+#endif
+#endif
+
+	/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them.
+	* This is to prevent stack overflows. */
+#ifndef CJSON_NESTING_LIMIT
+#define CJSON_NESTING_LIMIT 1000
+#endif
+
+	/* returns the version of cJSON as a string */
+	CJSON_PUBLIC(const char*) cJSON_Version(void);
+
+	/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */
+	/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */
+	CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value);
+	/* Render a cJSON entity to text for transfer/storage. */
+	CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item);
+	/* Render a cJSON entity to text for transfer/storage without any formatting. */
+	CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item);
+	/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */
+	CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt);
+	/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */
+	/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */
+	CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format);
+	/* Delete a cJSON entity and all subentities. */
+	CJSON_PUBLIC(void) cJSON_Delete(cJSON *c);
+
+	/* Returns the number of items in an array (or object). */
+	CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array);
+	/* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */
+	CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index);
+	/* Get item "string" from object. Case insensitive. */
+	CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string);
+	CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string);
+	CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string);
+	/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */
+	CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void);
+
+	/* These functions check the type of an item */
+	CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item);
+	CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item);
+	CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item);
+	CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item);
+	CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item);
+	CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item);
+	CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item);
+	CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item);
+	CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item);
+	CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item);
+
+	/* These calls create a cJSON item of the appropriate type. */
+	CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void);
+	CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void);
+	CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void);
+	CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean);
+	CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num);
+	CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string);
+	/* raw json */
+	CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw);
+	CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void);
+	CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void);
+
+	/* These utilities create an Array of count items. */
+	CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count);
+	CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count);
+	CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count);
+	CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char **strings, int count);
+
+	/* Append item to the specified array/object. */
+	CJSON_PUBLIC(void) cJSON_AddItemToArray(cJSON *array, cJSON *item);
+	CJSON_PUBLIC(void) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item);
+	/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object.
+	* WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before
+	* writing to `item->string` */
+	CJSON_PUBLIC(void) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item);
+	/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */
+	CJSON_PUBLIC(void) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item);
+	CJSON_PUBLIC(void) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item);
+
+	/* Remove/Detatch items from Arrays/Objects. */
+	CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item);
+	CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which);
+	CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which);
+	CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string);
+	CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string);
+	CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string);
+	CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string);
+
+	/* Update array items. */
+	CJSON_PUBLIC(void) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */
+	CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement);
+	CJSON_PUBLIC(void) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem);
+	CJSON_PUBLIC(void) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem);
+	CJSON_PUBLIC(void) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem);
+
+	/* Duplicate a cJSON item */
+	CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse);
+	/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will
+	need to be released. With recurse!=0, it will duplicate any children connected to the item.
+	The item->next and ->prev pointers are always zero on return from Duplicate. */
+	/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal.
+	* case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */
+	CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive);
+
+
+	/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */
+	/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error. If not, then cJSON_GetErrorPtr() does the job. */
+	CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated);
+
+	CJSON_PUBLIC(void) cJSON_Minify(char *json);
+
+	/* Macros for creating things quickly. */
+#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull())
+#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue())
+#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse())
+#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b))
+#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n))
+#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s))
+#define cJSON_AddRawToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateRaw(s))
+
+	/* When assigning an integer value, it needs to be propagated to valuedouble too. */
+#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number))
+	/* helper for the cJSON_SetNumberValue macro */
+	CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number);
+#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number))
+
+	/* Macro for iterating over an array or object */
+#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next)
+
+	/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */
+	CJSON_PUBLIC(void *) cJSON_malloc(size_t size);
+	CJSON_PUBLIC(void) cJSON_free(void *object);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 77 - 0
app/src/main/cpp/inc/cmdnsc/cm_hashtable.h

@@ -0,0 +1,77 @@
+//
+// Created by Ht on 2021/2/6.
+//
+
+#ifndef CMDNS_CM_HASHTABLE_H
+#define CMDNS_CM_HASHTABLE_H
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "cmdns_hal_intf.h"
+/**
+ * 需要改造,添加指针、遍历等工具
+ */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define CMHASHSIZE 101
+
+typedef struct _node{
+    char *name;
+    void *payload;
+    struct _node *next;
+} CmHashNode;
+
+typedef struct _hashtable {
+    unsigned char  auto_release_;
+    unsigned int   size_;
+    CmHashNode     **table_;
+} CmHashTable;
+
+JE_API CmHashTable* initCmHashtable(CmHashTable** table);
+
+JE_API CmHashTable* initCmHashtableEx(CmHashTable** table, unsigned char autoRelease);
+
+JE_API unsigned int hashValueCm(CmHashTable* table, char *key);
+
+JE_API CmHashNode* cmLookup(CmHashTable* table, char *key);
+
+JE_API char* strdupCm(const char *s);
+
+JE_API void* removeCmHashtable(CmHashTable* table, char* name);
+
+JE_API void* getCmHashtable(CmHashTable* table, char* name);
+
+JE_API void* putCmHashtable(CmHashTable* table, char* name, void* data);
+
+/* A pretty useless but good debugging function,
+which simply displays the hashtable in (key.value) pairs
+*/
+
+typedef CMBool (*NodeAccesser)(const char* key, void* node);
+typedef CMBool (*NodeIdxAccesser)(unsigned int idx, const char* key, void* node);
+
+JE_API void enumerateOnTable(CmHashTable* table, NodeAccesser accesser);
+JE_API void enumerateOnTableEx(CmHashTable* table, NodeIdxAccesser accesser);
+
+JE_API void releaseHashtable(CmHashTable* table);
+
+JE_API void cleanHashTable(CmHashTable* table);
+
+
+#ifdef DEBUG
+CMBool __cmPrintTable(unsigned int idx, const char* key, void* node);
+#define PrintCmHashtable(table) enumerateOnTableEx((table), __cmPrintTable)
+#else
+#define PrintCmHashtable(table)
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //CMDNS_CM_HASHTABLE_H

+ 195 - 0
app/src/main/cpp/inc/cmdnsc/cmdns.h

@@ -0,0 +1,195 @@
+//
+// Created by Ht on 2021/2/6.
+//
+
+#ifndef LIBDEVCPP_CMDNS_H
+#define LIBDEVCPP_CMDNS_H
+
+
+/**
+ *  基于UDP广播的名字地址服务
+ *      运行后,各服务可向其广播源,其它服务可向其查询服务。
+ *      1、服务的定义,由json消息结构完成。各通信消息不分包;
+ *      2、局域网采用组播机制进行通信;
+        ~,命令类型,p为公告服务
+        @,服务端口类型
+        #,安全印记,用于较长生存周期的服务、防止其它非法撤销该服务
+        l,数据有效生成周期,整型、单位秒
+        d,服务数据:
+            k:服务关键字
+            h:主机地址、必须与数据的来源端口相同,可选
+            p:服务端口
+            i:服务优先级
+            c: 服务描述
+
+ *      已发现的服务结构分类树:
+ *          tcp
+ *            +----- key1
+ *                     +==== priority->source_ip : port : disc
+ *                     +==== priority->source_ip : port : disc
+ *            +----- key2
+ *                     +==== priority->source_ip : port : disc
+ *                     +==== priority->source_ip : port : disc
+ *          udp
+ *            +----- key1
+ *                     +==== priority->source_ip : port : disc
+ *                     +==== priority->source_ip : port : disc
+ *            +----- key2
+ *                     +==== priority->source_ip : port : disc
+ *                     +==== priority->source_ip : port : disc
+ */
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include "cm_hashtable.h"
+#include "cmdns_hal_intf.h"
+
+static const char *vkey_cmdns_cmd_ = "~";
+static const char *vkey_cmdns_type_ = "@";
+static const char *vkey_cmdns_secc_ = "#";
+static const char *vkey_cmdns_ttl_ = "l";
+static const char *vkey_cmdns_payload_ = "d";
+static const char *vkey_cmdns_payload_key_ = "k";
+static const char *vkey_cmdns_payload_sub_ = "n";       //子网
+static const char *vkey_cmdns_payload_host_ = "h";
+static const char *vkey_cmdns_payload_port_ = "p";
+static const char *vkey_cmdns_payload_priority_ = "i";
+static const char *vkey_cmdns_payload_query_type_ = "t";
+static const char *vkey_cmdns_payload_comment_ = "c";
+
+static const char *sval_default_cmdns_type_tcp_ = "tcp";
+static const char *sval_default_cmdns_type_udp_ = "udp";
+static const char *sval_default_cmdns_subnet_open_ = "#0";
+
+static const int ival_default_cmdns_priority = 1000; //默认优先级
+static const int ival_default_cmdns_ttl = 20;        //服务生存有效期
+static const unsigned char ucval_sec_key_len_ = 8;   //安全码长度,16
+static const char *sval_default_cmdns_addr_ = "224.0.0.253";
+static const int ival_default_cmdns_port_ = 61053;
+static const int ival_default_cmdns_port_min_ = 10000;
+static const char *sval_default_cmdns_query_type_ = "a";
+static const int MAX_CMDNS_BUFF_SIZE = 2048;
+
+static const char *publishMessage
+        = "{\"~\":\"p\",\"@\":\"%s\",\"l\":%d,\"d\":{\"#\":\"%s\",\"k\":\"%s\", \"p\":%d,\"i\":%d,\"c\":\"%s\",\"n\":\"%s\"}}";
+
+static const char *withdrawMessage
+        = "{\"~\":\"w\",\"@\":\"%s\",\"d\":{\"#\":\"%s\", \"k\":\"%s\",\"n\":\"%s\"}}";
+
+static const char *queryMessage
+        = "{\"~\":\"q\",\"@\":\"%s\",\"l\":%d,\"d\":{\"#\":\"%s\",\"k\":\"%s\",\"t\":\"%s\",\"n\":\"%s\"}}";
+
+static const char *answerMessage
+        = "{\"~\":\"r\",\"@\":\"%s\",\"d\":%s}";
+
+static const char *quitMessage
+        = "{\"~\":\"x\",\"#\":\"%s\"}";
+
+typedef struct _cmdns {
+    CmHashTable *pubs_;
+    CmHashTable *qrys_;
+    void *context_obj_;
+    char* addr_;
+    int   port_;
+} CMDns;
+
+typedef void (*servicePublishLocker) (void *publish, CMBool lockType);
+
+typedef struct _service_pub {
+    CMDns *cmdns_;
+    const char *type_;
+    const char *service_key_;
+    int priority_;
+    int port;
+    const char *code;
+    int ttl;
+    const char *comment_;
+    const char *subnet_;
+
+    char *publish_buff_;
+    CMSize publish_buff_size_;
+    char *withdraw_buff_;
+    CMSize withdraw_buff_size_;
+    CMTimer *timer_post_;
+    CMNetIntf *net_intf_;
+    CMBool stop_;
+
+    servicePublishLocker locker_;
+    pthread_mutex_t*    mutex_;
+} CMDnsServicePublish;
+
+typedef struct _service_queried {
+    const char *type;
+    const char *service_key;
+    int priority;
+    const char *host;
+    int port;
+    const char *code;
+    const char *comment;
+    const char *subnet;
+} CMdnsServiceQueried;
+
+//回调函数
+typedef void (*serviceQueryHandler) (void *query,const CMdnsServiceQueried services[], int svc_cnt, const char* ip, int port);
+typedef void (*serviceQueryLocker) (void *query, CMBool lockType);
+
+typedef struct _service_qry {
+    CMDns *cmdns_;
+    const char *type_;
+    const char *service_key_;
+    const char *subnet_;
+    const char *code;   //查询码,标志查询本身
+    int ttl;
+    const char *query_type_;
+    char *query_buff_;
+    CMSize query_buff_size_;
+    CMTimer *timer_post_;
+
+    char *read_buff_;
+    CMSize read_buff_size_;
+    CMTimer *timer_read_;
+    CMNetIntf *net_intf_;
+    serviceQueryHandler handler_;
+    serviceQueryLocker  locker_;
+    pthread_mutex_t*    mutex_;
+    unsigned char stop_;
+} CMDnsServiceQuery;
+
+
+JE_API CMDns *createCmDns(CMDns **cmdns, void *obj);
+JE_API void releaseCmDns(CMDns *cmdns);
+JE_API void clearCmDns(CMDns *cmdns);
+JE_API void setCmDnsAddr(CMDns *cmdns, const char* addr, int port);
+
+JE_API CMDnsServicePublish *
+createCmDnsServicePublishP(CMDns *cmdns, const char *type, const char *key, int priority, int port, int ttl, const char *comment, const char* subnet, servicePublishLocker locker);
+
+JE_API CMDnsServicePublish *
+createCmDnsServicePublish(CMDns *cmdns, const char *type, const char *key, int priority, int port, int ttl, const char *comment, const char* subnet);
+
+
+JE_API void releaseServicePublish(CMDns *cmdns, CMDnsServicePublish *pub);
+JE_API CMBool publishCmDnsService(CMDns *cmdns, CMDnsServicePublish *pub);
+JE_API void withdrawService(CMDns *cmdns, CMDnsServicePublish *pub);
+
+JE_API CMDnsServiceQuery *
+createCmDnsServiceQueryP(CMDns *cmdns, const char *type, const char *key, const char *subnet, int ttl, const char *queryType,
+                        serviceQueryHandler handler, serviceQueryLocker locker);
+JE_API CMDnsServiceQuery *
+createCmDnsServiceQuery(CMDns *cmdns, const char *type, const char *key, const char *subnet, int ttl, const char *queryType,
+                        serviceQueryHandler handler);
+
+JE_API void releaseServiceQuery(CMDns *cmdns, CMDnsServiceQuery *query);
+JE_API CMBool queryCmDnsService(CMDns *cmdns, CMDnsServiceQuery *query);
+
+JE_API void stopQuery(CMDns *cmdns, CMDnsServiceQuery *query);
+JE_API void stopQueries(CMDns *cmdns);
+
+#if defined(__cplusplus)
+}
+#endif
+
+
+#endif //LIBDEVCPP_CMDNS_H

+ 67 - 0
app/src/main/cpp/inc/cmdnsc/cmdns_hal_intf.h

@@ -0,0 +1,67 @@
+//
+// Created by Ht on 2021/2/8.
+//
+
+#ifndef CMDNS_CMDNS_HAL_INTF_H
+#define CMDNS_CMDNS_HAL_INTF_H
+
+#include <pthread.h>
+#include <jebase/config.h>
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+typedef unsigned char CMBool;
+
+#define CMTrue      1
+#define CMFalse     0
+
+typedef struct {
+    int net_intf_;
+    void* sock_addr_;
+} CMNetIntf;
+
+typedef unsigned int CMSize;
+
+JE_API void* HAL_Malloc(unsigned int size);
+JE_API void  HAL_Free(void*);
+
+JE_API void  HAL_Release(); //释放所有剩余资源
+
+//利用Socket及timer发送,不同系统具有不同的创建模式
+//需要如下几个hal接口:创建、释放socket,创建、释放timer(OS线程模式),发送socket、读取socket
+
+//网络接口创建
+JE_API CMNetIntf*  HAL_Create_NetIntf(CMNetIntf** intf, const char* host, int port);
+JE_API void  HAL_Release_NetIntf(CMNetIntf*intf);
+
+//Timer的创建和停止
+typedef CMBool (*TimerTask)(void* context);
+
+typedef struct {
+    CMBool       quit_:1;
+    CMBool       quitted_:1;
+    unsigned int interval_;
+    void*        context_;
+    pthread_t    thread_;
+    pthread_cond_t*     cond_;
+    pthread_mutex_t*    mutex_;
+    TimerTask    task_;
+} CMTimer;
+
+JE_API CMTimer*  HAL_Create_Timer(CMTimer** timer, void* context, TimerTask func);
+JE_API void  HAL_Release_Timer(CMTimer* timer);
+JE_API CMBool HAL_Start_Timer(CMTimer* timer, unsigned int interval);
+
+//网络消息的发送和接收
+JE_API void  HAL_Send_Diagram(CMNetIntf* intf, char* buff,  CMSize size);
+JE_API typedef void (*NetDataHandler)(void* context, char* buff,  CMSize size, const char* ip, int port);
+JE_API void  HAL_Read_Diagram(CMNetIntf* intf, void* context, char* buff,  CMSize size, NetDataHandler handler);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif //CMDNS_CMDNS_HAL_INTF_H

+ 35 - 0
app/src/main/cpp/inc/cosasl/BodySensorTimer.h

@@ -0,0 +1,35 @@
+//
+// Created by WJG on 2021-8-23.
+//
+
+#ifndef SMARTPANEL_COSS_BODYSENSORTIMER_H
+#define SMARTPANEL_COSS_BODYSENSORTIMER_H
+
+#include <string>
+#include "../MsgSchedule/CThread.h"
+
+class BodySensorTimer : public CThread{
+public:
+    BodySensorTimer(const std::string& id,const std::string& uuid);
+    void Run() override ;
+    void resetTimer();
+
+private:
+    int counter;            //自上次以来的触发计数
+    unsigned int s_timer;
+    int trg_counter;        //自上次触发以来的计时
+    bool can_trigger;       //可否再次触发
+
+    bool is_looping;        //退出触发器计时循环
+    bool stop_timer;        //退出计时器
+    std::string sensor_id;
+    std::string sensor_uuid;
+
+    std::mutex  mutex_;
+    void sendSensorMessage(int value);
+    void setTriggerStatus();
+
+    void clearBodyStatus();
+};
+
+#endif //SMARTPANEL_COSS_BODYSENSORTIMER_H

+ 46 - 0
app/src/main/cpp/inc/cosasl/CThread.h

@@ -0,0 +1,46 @@
+/*
+ * CThread.h
+ *
+ *  Created on: 2019-6-26
+ *      Author: fiona fan
+ */
+
+#ifndef CTHREAD_H_
+#define CTHREAD_H_
+
+#include "../CossCore/log_tool.h"
+#include <stdint.h>
+#include <stdio.h>
+#include <stddef.h>
+#include <functional>
+
+//namespace message_manager {
+
+using EndOfThread = std::function<void(void*)>;
+
+class CThread {
+
+private:
+	pthread_t  m_thread_id;
+    EndOfThread* end = nullptr;
+
+public:
+    void *param;
+
+    explicit CThread();
+	virtual ~CThread();
+
+	void thread_exit();
+	void thread_cancel(pthread_t thread);
+	virtual void Run() = 0;
+	static void* thread_run_temp(void* param);
+	int8_t Start(void*obj, void* run_param);
+	pthread_t GetThreadID();
+
+    void onEnd();
+
+    void setEndHandler(const EndOfThread &endHandler);
+};
+
+//} /* namespace message_manager */
+#endif /* CTHREAD_H_ */

+ 34 - 0
app/src/main/cpp/inc/cosasl/CThreadPool.h

@@ -0,0 +1,34 @@
+//
+// Created by WJG on 2020-5-12.
+//
+
+#ifndef MGCORE_CTHREADPOOL_H
+#define MGCORE_CTHREADPOOL_H
+
+#include <list>
+#include <mutex>
+#include <condition_variable>
+#include "json/json.h"
+
+class CThreadPool {
+public:
+    int thread_num;
+    int quit;
+    std::mutex msg_ListMutex;
+    std::mutex msg_ReadyMutex;
+    std::condition_variable msg_ReadyCond;
+    std::list<Json::Value> msg_List;
+
+    explicit CThreadPool(int num);
+    ~CThreadPool();
+    int putMsg(const Json::Value &value);
+    int putMsgFirst(const Json::Value &value);
+    void stopThread();
+
+private:
+    void intiThreadPool();
+
+};
+
+
+#endif //MGCORE_CTHREADPOOL_H

+ 16 - 0
app/src/main/cpp/inc/cosasl/CWorkerThread.h

@@ -0,0 +1,16 @@
+//
+// Created by WJG on 2020-5-12.
+//
+
+#ifndef MGCORE_CWORKERTHREAD_H
+#define MGCORE_CWORKERTHREAD_H
+
+#include "CThreadPool.h"
+#include "CThread.h"
+
+class CWorkerThread : public CThread{
+public:
+    void Run() override ;
+};
+
+#endif //MGCORE_CWORKERTHREAD_H

+ 22 - 0
app/src/main/cpp/inc/cosasl/CossBridgeClass.h

@@ -0,0 +1,22 @@
+//
+// Created by Ht on 2021/3/8.
+//
+
+#ifndef COSSDEV_COSSBRIDGECLASS_H
+#define COSSDEV_COSSBRIDGECLASS_H
+
+#include "mgbus/MgBusHolder.h"
+
+class CossBridgeClass {
+protected:
+    jedge::MgBusHolder& mHolder;
+
+public:
+    explicit  CossBridgeClass(jedge::MgBusHolder& holder);
+    virtual ~CossBridgeClass() = default;
+
+    bool handleMgbusMessage(qlibc::QData &msg, qlibc::QData *rsp);
+};
+
+
+#endif //COSSDEV_COSSBRIDGECLASS_H

+ 107 - 0
app/src/main/cpp/inc/cosasl/CossDevPropertyUtil.h

@@ -0,0 +1,107 @@
+//
+// Created by Ht on 2022/10/1.
+//
+
+#ifndef INC_0_LIBDEVCPP_COSSDEVPROPERTYUTIL_H
+#define INC_0_LIBDEVCPP_COSSDEVPROPERTYUTIL_H
+
+#include <qlibc/qlibc.h>
+#include "../DevTree/DevTree.h"
+
+namespace jedge {
+
+    class JE_API CossDevPropertyUtil {
+    public:
+
+        static  bool isStringInJsonArray(const Json::Value& val, const std::string& str) {
+            if(!val.isArray() || val.empty()) return false;
+            for(const auto& v : val) {
+                if(v.isString() && strcmp(v.asCString(), str.c_str())==0)
+                    return true;
+            }
+            return false;
+        }
+
+        static  bool removeStringFromJsonArray(Json::Value& val, const std::string& str) {
+            if((!val.isArray() || val.empty())) return false;
+            int i = (int)val.size()-1;
+            for(;i>=0;i--) {
+                const auto& v = val[i];
+                if(v.isString() &&
+                strcmp(v.asCString(), str.c_str())==0) {
+                    Json::Value del;
+                    val.removeIndex(i, &del);
+                    return true;
+                }
+            }
+            return false;
+        }
+
+        static bool addStringToJsonArray(Json::Value& group, const std::string& strVal) {
+            if(!group.isArray()) {
+                if (group.isString()) {
+                    auto old = group.asString();
+                    group = Json::arrayValue;
+                    group.append(old);
+                } else {
+                    group = Json::arrayValue;
+                }
+            }
+            //查重
+            for(const auto& ov : group) {
+                if(ov.isString() && strVal==ov.asString())
+                    return false;
+            }
+            group.append(strVal);
+            return true;
+        }
+
+        //从一个设备的字符串数组的属性中移除一个指定的值,如果为空,则删除这个属性
+        static void removeStringFromJsonArrayProperty(DevTree& devTree, const std::string& devId, const std::string& propName, const std::string& strVal ) {
+            Json::Value group;
+            devTree.getDevInfoAsJsonValue(group, devId, propName);
+            //从数组中移除一个值,如果非数组的值,直接返回false
+            if(removeStringFromJsonArray(group, strVal))
+            {
+                if(group.empty())
+                    devTree.deleteDeviceInfo(devId, propName);
+                else
+                    devTree.updateDeviceInfo(devId, propName, StringUtils::valueToJsonString(group));
+            }
+        }
+
+        //更新设备的组地址引用增加一个不会重复的string值,如果该值不是数组,则拓展为数组
+        static void addStringToJsonArrayProperty(DevTree& devTree, const std::string& devId, const std::string& propName, const std::string& strVal ) {
+            Json::Value group;
+            devTree.getDevInfoAsJsonValue(group, devId, propName);
+            //从数组中移除一个值
+            if(addStringToJsonArray(group, strVal))
+            {
+                if(group.empty())
+                    devTree.deleteDeviceInfo(devId, propName);
+                else
+                    devTree.updateDeviceInfo(devId, propName, StringUtils::valueToJsonString(group));
+            }
+        }
+
+        //设备的数组属性是否为空
+        static bool isJsonArrayPropertyEmpty(DevTree& devTree, const std::string& devId, const std::string& propName) {
+            Json::Value group;
+            devTree.getDevInfoAsJsonValue(group, devId, propName);
+            auto validContent = group.isInt() || (group.isArray() && !group.empty()) || (group.isString() && !group.empty());
+            return !validContent;
+        }
+
+        //测试属性值是否位于某值中
+        static bool isStrValExistsInJsonArrayProperty(DevTree& devTree, const std::string& devId, const std::string& propName, const std::string& strVal) {
+            Json::Value group;
+            devTree.getDevInfoAsJsonValue(group, devId, propName);
+            auto exists = ((group.isArray() && !group.empty() && isStringInJsonArray(group, strVal))
+                    || (group.isString() && strcmp(group.asCString(), strVal.c_str())==0));
+            return exists;
+        }
+    };
+
+}
+
+#endif //INC_0_LIBDEVCPP_COSSDEVPROPERTYUTIL_H

+ 18 - 0
app/src/main/cpp/inc/cosasl/CossHttpService.h

@@ -0,0 +1,18 @@
+//
+// Created by WJG on 2021-1-18.
+//
+
+#ifndef NEWCOSS_HTTPSERVICE_H
+#define NEWCOSS_HTTPSERVICE_H
+
+#include "OriginalHttplib.h"
+
+bool startHttpService();
+void stopHttpService();
+
+void systemRequest_process(const ORhttplib::Request &req, ORhttplib::Response &res);
+void deviceControl(const ORhttplib::Request &req, ORhttplib::Response &res);
+void lightjia_process(const ORhttplib::Request &req, ORhttplib::Response &res);
+void testuserLogin_process(const ORhttplib::Request &req, ORhttplib::Response &res);
+
+#endif //NEWCOSS_HTTPSERVICE_H

+ 13 - 0
app/src/main/cpp/inc/cosasl/CossInterface.h

@@ -0,0 +1,13 @@
+//
+// Created by WJG on 2021-3-9.
+//
+
+#ifndef COSSDEV_COSSINTERFACE_H
+#define COSSDEV_COSSINTERFACE_H
+
+#include <string>
+
+int coss_start(const std::string& file_path, const std::string& base_path);
+int coss_stop();
+
+#endif //COSSDEV_COSSINTERFACE_H

+ 34 - 0
app/src/main/cpp/inc/cosasl/DaemonWorker.h

@@ -0,0 +1,34 @@
+//
+// Created by WJG on 2021-9-15.
+//
+
+#ifndef SMARTPANEL_COSS_DAEMONWORKER_H
+#define SMARTPANEL_COSS_DAEMONWORKER_H
+
+#include <unordered_set>
+#include "../MsgSchedule/CThread.h"
+
+class DaemonWorker : public CThread{
+public:
+    explicit DaemonWorker(std::unordered_set<std::string>);
+//    explicit DaemonWorker(int t);
+    void Run() override ;
+    void setDelayTime(int t_second);
+    void setNumber(int all, int num);
+    void setStop(bool set_v);
+    void resetCounter();
+    void setSuccessDevices(std::string did);
+
+private:
+    unsigned int counter;
+    int delay_time;
+    int total;
+    int number;
+    bool is_stoping;
+    std::unordered_set<std::string> all_devices;
+    std::unordered_set<std::string> success_devices;
+
+    void sendEndMsg();
+};
+
+#endif //SMARTPANEL_COSS_DAEMONWORKER_H

+ 115 - 0
app/src/main/cpp/inc/cosasl/DevTree.h

@@ -0,0 +1,115 @@
+//
+// Created by WJG on 2020-5-7.
+//
+
+#ifndef NEWCOSS_DEVTREE_H
+#define NEWCOSS_DEVTREE_H
+
+#include <mutex>
+#include <unordered_map>
+#include <unordered_set>
+#include <qlibc/StringUtils.hpp>
+#include <qlibc/QData.hpp>
+#include "json/json.h"
+#include "DeviceInfo.h"
+#include "../CossCore/FileWriteWorker.h"
+#include "../CossCore/coss_comm.h"
+
+class DevTree{
+public:
+    static DevTree& GetInstance()
+    {
+        if ( m_pInstance == nullptr )
+            m_pInstance = new DevTree();
+        return *m_pInstance;
+    };
+
+    ~DevTree();
+
+    static std::string config_file_dir;
+    static std::string config_file_dir_init;
+
+    int initDevTree(const std::string &file_dir, const std::string& init_dir);
+    Json::Value getAllDev();
+    string getDevInfo(const std::string &device_id, const std::string &key);
+    void getDevInfoAsJsonValue(Json::Value &val, const string &device_id, const string &key);
+    Json::Value getDevAllInfo(const std::string &device_id);
+    void getDevAllInfo(Json::Value &ret, const string &device_id);
+    int updateDeviceInfo(const std::string &device_id, const Json::Value &info);
+    int updateDeviceInfo(const std::string &device_id, const std::string &key, const std::string &value);
+    int cacheDeviceInfo(const std::string &device_id, const Json::Value &info);
+    bool cachesaveDeviceInfo(const std::string &device_id, const Json::Value &info);
+    int addUserLocation(const Json::Value &location);
+    int deleteUserLocation(const Json::Value &location);
+    // void printGroupInfo();
+
+    std::vector<std::string> getDevbyGroup(const std::string &nick_name, const std::string &device_type,const std::string &device_location);
+    Json::Value getDevbyLocation(const std::string &location);
+    Json::Value getDevBaseInfo(const std::string &device_id);
+    int rmLocationDev(const std::string &device_id, const std::string &location_name);
+    std::string getDevbyAddress(const std::string &device_addr);
+    std::string getDevbyUuid(const std::string &device_uuid);
+    bool hasDevice(const std::string &device_id);
+    int deleteDevice(const std::string &device_id);
+    int addNewDevice(const std::string &device_id, const Json::Value &info);
+    int deleteDeviceInfo(const std::string &device_id, const std::string &key);
+    Json::Value getGroupDevice();
+    int deleteGroupDevice(const std::string& device_id);
+    int cacheOtherDevice(const std::string &device_id, const Json::Value &info);
+    std::vector<std::string> getDevbyNickName(const std::string &nick_name);
+    int updateNickNameMap(const std::string &device_id, const std::string &nick_name, const std::string &old_name);
+    void saveDeviceInfo(const std::string& device_id);
+//    int saveDefaultGroupAddrDev(const std::string& gpadr, const Json::Value& dev);
+//    Json::Value getDefaultGroupAddrDev();
+//    void delDefaultGroupAddrDev();
+    int updatePanelName(const std::string& nick_name);
+    int updatePanelUUID(const std::string& uuid);
+    int updatePanelMac(const std::string& mac);
+    std::string getPanelName();
+    std::string getPanelUUID();
+    std::string getPanelMac();
+    bool hasDefaultGroupId(const std::string &gp_id);
+
+    void setDefaultGroupId(const std::string &groupAddr);
+
+    //获取所有原始设备的短地址列表,不包含组地址
+    void getAtomDevShortAddrList(QStringList& list, const std::string& type = "", const std::string& devClass = "");
+
+    DeviceInfo* getDevInfoByAddress(const std::string &device_address);
+
+    void removeDuplicatedWired();
+    void upgradeGroupIdFormmat();
+
+private:
+    static DevTree* m_pInstance;
+    std::recursive_mutex treeMutex;
+    FileWriteWorker *filewriteWorker;
+    unordered_map<std::string, DeviceInfo> allDevice;
+    //unordered_map<分组类型名,unordered_map<分组名,unordered_set<设备id>>
+    unordered_map<std::string, unordered_map<std::string,unordered_set<std::string>>> groupInfo;
+    unordered_map<std::string, std::string> devAddrIdMap;
+    unordered_map<std::string, std::string> devUuidIdMap;
+    unordered_set<std::string> groupDevices;
+    unordered_map<std::string,unordered_set<std::string>> devNickNameMap;
+
+    DevTree();
+    int initGroupInfoKey();
+    int updateLocationKey(int opt, const Json::Value &value);
+    int updateDeviceLocation(const unordered_set<std::string> &device_set, const std::string &location);
+
+    int updateGroupInfo(const std::string &device_id, const Json::Value &value);
+    int CreatDeviceInfo(const std::string &file_dir);
+
+    std::mutex devFileMutex;
+    std::string defaultLightGroupId;
+    qlibc::QData mCossConfig;
+
+    unordered_set<std::string> defaultGroupAddress_set;
+
+#ifdef DEVICE_FILE_TEST
+Json::Value parseFromFile(const string &fn);
+#endif
+
+};
+
+#endif //NEWCOSS_DEVTREE_H

+ 108 - 0
app/src/main/cpp/inc/cosasl/DeviceExtra.h

@@ -0,0 +1,108 @@
+//
+// Created by WJG on 2020-9-10.
+//
+
+#ifndef NEWCOSS_DEVICEEXTRA_H
+#define NEWCOSS_DEVICEEXTRA_H
+
+#include "json/json.h"
+#include "DeviceInfo.h"
+#include <mutex>
+#include <unordered_map>
+#include <unordered_set>
+
+#define CPAD_WIRED_CONTROL_DEV_CLASS "WIRED_DEV"
+#define CPAD_WIRED_CONTROL_DEV_TYPE "WiredControl"
+
+#define MUTIL_PANEL_ENABLDE 1
+
+class DeviceExtra {
+public:
+//    static int setDevice2Home(const Json::Value &device);
+//    static int delHomeDevice(const Json::Value &device);
+//    static Json::Value getHomeDevice();
+//    static int setDevice2Shortcut(const Json::Value &device);
+//    static int delShortcutDevice(const Json::Value &device);
+//    static Json::Value getShortcutDevice();
+    static Json::Value getDefaultLocation();
+    static Json::Value getUserDefineLocation();
+    static Json::Value getMultiDevice();
+    static Json::Value getLocalUserLocation();
+
+    static int updateTempHumi(const Json::Value &value);
+    static Json::Value getTempHumi();
+//    static void resetBodySensor(std::string dev_id);
+//    static void updateBodySensor();
+    static void updateBodySensor(std::string dev_id, std::string dev_uuid);
+    static void updateDoorSensor(std::string dev_id, std::string dev_uuid, int status);
+    static void process_multi_msg(const Json::Value &value);
+    static std::vector<std::string> getDevByName(std::string nick_name);
+    static void update_device2other_panel();
+    static Json::Value getPanelList();
+    static int initMultiDevice(const std::string &file_dir);
+    static std::string getPanelMgnet(const std::string &panel_sn);
+    static void remotePanelName(const Json::Value &value);
+    static int localPanelName(const std::string &panel_name);
+    static std::string getLocalPanelSN();
+    static void updateRoomInfo();
+
+    static void devEventRegister_process(const Json::Value& value);
+    static void devActionRegister_process(const Json::Value& value);
+    static void devEventTrigger_process(const Json::Value& value);
+
+    static Json::Value getDevInfo(const std::string &device_id);
+    static void addNewModuleDevice(std::string dev_id, std::string module);
+
+private:
+    static void post_device2other_panel(std::string mgnet);
+    static void process_online_msg(const Json::Value &value);
+    static void process_offline_msg(const Json::Value &value);
+    static void process_room_info(const Json::Value &value);
+    static void process_dev_list(const Json::Value &value);
+    static void process_dev_status(const Json::Value &value);
+    static void update_dev_list(const Json::Value &value);
+    static std::string parse_mgnet_info(const Json::Value &value);
+    static std::string get_panel_sn();
+    static std::string get_panel_name();
+    static void process_module_offline(const Json::Value &value);
+
+//    static std::string panel_device_dir;
+
+//    static std::mutex s_map_Mutex;
+//    static std::unordered_set<std::string> panel_room_set;
+    static std::unordered_map<std::string, std::unordered_set<std::string>> panel_sn_room_map;
+
+    //unordered_map<panel_sn,unordered_set<dev_id>>
+    static std::unordered_map<std::string, std::unordered_set<std::string>> panel_sn_devid_map;
+
+    //unordered_map<nick_name,unordered_set<dev_id>>
+    static std::unordered_map<std::string, std::unordered_set<std::string>> nickname_devid_map;
+
+    //unordered_map<dev_id, devJson_Info>
+    static std::unordered_map<std::string, DeviceInfo> dev_map;
+    static std::mutex dev_map_mutex;
+    static std::mutex name_dev_map_mutex;
+
+    //unordered_set<nick_name>
+//    static std::unordered_set<std::string> nick_name_reged_set;
+
+    //unordered_map<sn, name>
+    static std::unordered_map<std::string, std::string> panel_sn_name_map;
+
+    //unordered_map<mgnet, sn>
+    static std::unordered_map<std::string, std::string> panel_mgnet_sn_map;
+
+    //unordered_map<sn, mgnet>
+    static std::unordered_map<std::string, std::string> panel_sn_mgnet_map;
+
+    //unordered_map<dev_id, devJson_cmdparam>
+    static std::unordered_map<std::string, Json::Value> devid_cmdparam_map;
+
+    //unordered_map<dev_id, unordered_set<dev_event>>
+    static std::unordered_map<std::string, std::unordered_set<std::string>> devid_event_map;
+
+    //unordered_map<module_id, unordered_set<dev_id>>
+    static std::unordered_map<std::string, std::unordered_set<std::string>> moduleid_devid_map;
+};
+
+#endif //NEWCOSS_DEVICEEXTRA_H

+ 40 - 0
app/src/main/cpp/inc/cosasl/DeviceInfo.h

@@ -0,0 +1,40 @@
+//
+// Created by WJG on 2020-5-7.
+//
+
+#ifndef NEWCOSS_DEVICEINFO_H
+#define NEWCOSS_DEVICEINFO_H
+
+#include <unordered_map>
+#include "json/json.h"
+
+using namespace std;
+
+class DeviceInfo {
+public:
+    DeviceInfo();
+    DeviceInfo(const DeviceInfo &dev);
+    ~DeviceInfo();
+
+    void setInfo(const Json::Value &value);
+    void setInfo(const std::string &key, const std::string &value);
+    void deleteInfo(const std::string &key);
+//    void setName(string name);
+//    void setType(string type);
+//    void setId(string id);
+//    void setNickName(string nick);
+//    void setGroup(string group);
+//    void setConnectType(string contype);
+//    void setOnlineState(string state);
+
+    Json::Value getAllInfo();
+    void getAllInfo(Json::Value &info);
+    std::string getInfo(const std::string &key);
+//    void saveDeviceInfo();
+
+protected:
+    unordered_map<std::string, std::string> deviceInfo;
+//    unordered_map<std::string, std::string> statusInfo;
+};
+
+#endif //NEWCOSS_DEVICEINFO_H

+ 44 - 0
app/src/main/cpp/inc/cosasl/DeviceStatusService.h

@@ -0,0 +1,44 @@
+//
+// Created by Ht on 2020/7/26.
+//
+
+#ifndef LIBDEVCPP_USERSTATUSSERVICE_H
+#define LIBDEVCPP_USERSTATUSSERVICE_H
+
+#include <mgbus/MgBusService.h>
+
+namespace jedge {
+
+
+    class DeviceStatusService :
+            public MgBusService {
+
+    protected:
+
+    public:
+        explicit DeviceStatusService(MgBusHolder& opr, const std::string& name, const qlibc::QData& config = qlibc::QData()) : MgBusService(opr, name, config){}
+
+        ~DeviceStatusService() override = default;
+
+        void preparePattern() override;
+
+        bool queryStatus(qlibc::QData &message, qlibc::QData *response);
+
+        void onServiceStart(const qlibc::QData &config) override;
+
+        void onServiceStop() override;
+
+        bool bNeedSave = false;
+
+        qlibc::QRTimer mTimer = nullptr;
+
+        std::recursive_mutex  mm;
+
+
+        void doSaveWork();
+
+        void cacheSaveData(const std::string& key, qlibc::QData& dataToSave);
+    };
+}
+
+#endif //LIBDEVCPP_USERSTATUSSERVICE_H

+ 27 - 0
app/src/main/cpp/inc/cosasl/DoorSensorTimer.h

@@ -0,0 +1,27 @@
+//
+// Created by WJG on 2021-8-25.
+//
+
+#ifndef SMARTPANEL_COSS_DOORSENSORTIMER_H
+#define SMARTPANEL_COSS_DOORSENSORTIMER_H
+
+#include <string>
+#include "../MsgSchedule/CThread.h"
+
+class DoorSensorTimer : public CThread{
+public:
+    explicit DoorSensorTimer(std::string id, std::string uuid);
+    void Run() override ;
+    void resetTimer(int status);
+
+private:
+    int counter;
+    unsigned int s_timer;
+    bool stop_timer;
+    bool is_looping;
+    std::string sensor_id;
+    std::string sensor_uuid;
+    void sendSensorMessage(int value);
+};
+
+#endif //SMARTPANEL_COSS_DOORSENSORTIMER_H

+ 21 - 0
app/src/main/cpp/inc/cosasl/FileWriteWorker.h

@@ -0,0 +1,21 @@
+//
+// Created by WJG on 2021-11-18.
+//
+
+#ifndef SMARTPANEL_COSS_FILEWRITEWORKER_H
+#define SMARTPANEL_COSS_FILEWRITEWORKER_H
+
+#include <unordered_set>
+#include "../MsgSchedule/CThread.h"
+
+class FileWriteWorker : public CThread{
+public:
+    void Run() override ;
+    void setDevId(std::string dev_id);
+
+private:
+    std::unordered_set<std::string> did_set;
+    std::mutex did_set_mutex;
+};
+
+#endif //SMARTPANEL_COSS_FILEWRITEWORKER_H

+ 110 - 0
app/src/main/cpp/inc/cosasl/GasTransTable.h

@@ -0,0 +1,110 @@
+//
+// Created by ljx on 2021/12/27.
+//
+
+#ifndef SMARTPANEL_COSS_GASTRANSTABLE_H
+#define SMARTPANEL_COSS_GASTRANSTABLE_H
+
+#include <qlibc/QData.hpp>
+#include <qlibc/QPObjectHolder.h>
+#include "../DevTree/DevTree.h"
+
+using CommandHandler = std::function<void(const qlibc::QData& msgSrc, qlibc::QData& msgDest)>;
+
+
+class GasTransTable{
+
+protected:
+    qlibc::QPObjectHolder<CommandHandler> controlTables;
+    DevTree& mDevTree_;
+
+public:
+    explicit GasTransTable(DevTree& mDevTree):mDevTree_(mDevTree){
+        initControlTables();
+    }
+    void transControlToGas(const qlibc::QData &req, qlibc::QData &req2Gas){
+        std::string device_id = req.getString("device_id");
+        std::string command = req.getString("command");
+        Json::Value v = mDevTree_.getDevAllInfo(device_id);
+        qlibc::QData v_data(v);
+        std::string device_address = v_data.getString("device_address");
+        std::stringstream ss;
+        QHLog("control message all info is %s ", v_data.toJSONString(true).c_str());
+        if(v_data.getString("device_class") == "GroupDevice"){
+            int addr = atoi(device_address.c_str());
+            ss << std::hex << addr;
+            device_address = ss.str();
+        }
+
+        req2Gas.putString("gw_sn", v_data.getString("sn"));
+        req2Gas.putString("device_address", device_address);
+        req2Gas.putString("command", command);
+        req2Gas.putString("uri", "/lightGW/controlDevice");
+        req2Gas.putString("cmd_source", "cpad");
+
+        auto handler = controlTables.findObject(command);
+        if(handler != nullptr)
+            handler->operator () (req, req2Gas);
+
+    }
+
+private:
+
+
+    void initControlTables(){
+        controlTables.appendNew("turnOn", new CommandHandler([](const qlibc::QData &req, qlibc::QData &req2Gas) {
+            qlibc::QData qd_param;
+            req2Gas.putObjFmtData("param", qd_param);
+        }));
+        controlTables.appendNew("turnOff", new CommandHandler([](const qlibc::QData &req, qlibc::QData &req2Gas) {
+            qlibc::QData qd_param;
+            req2Gas.putObjFmtData("param", qd_param);
+        }));
+        controlTables.appendNew("setBrightness", new CommandHandler([](const qlibc::QData &req, qlibc::QData &req2Gas) {
+            req2Gas.putObjFmtString("param.set_value", req.getObjFmtString("param.set_value"));
+        }));
+        controlTables.appendNew("adjustBrightness", new CommandHandler([](const qlibc::QData &req, qlibc::QData &req2Gas) {
+            qlibc::QData qd_param;
+            qd_param.putString("flag", req.getObjFmtString("param.flag"));
+            qd_param.putString("adjust_value", req.getObjFmtString("param.adjust_value"));
+            req2Gas.putData("param", qd_param);
+        }));
+        controlTables.appendNew("adjustColorTemperature", new CommandHandler([](const qlibc::QData &req, qlibc::QData &req2Gas) {
+            qlibc::QData qd_param;
+            qd_param.putString("flag", req.getObjFmtString("param.flag"));
+            qd_param.putString("adjust_value", req.getObjFmtString("param.adjust_value"));
+            req2Gas.putData("param", qd_param);
+        }));
+        controlTables.appendNew("setColorTemperature", new CommandHandler([](const qlibc::QData &req, qlibc::QData &req2Gas) {
+            req2Gas.putObjFmtString("param.set_value", req.getObjFmtString("param.set_value"));
+        }));
+        controlTables.appendNew("setSaturation", new CommandHandler([](const qlibc::QData &req, qlibc::QData &req2Gas) {
+            req2Gas.putObjFmtString("param.set_value", req.getObjFmtString("param.set_value"));
+        }));
+        controlTables.appendNew("setLighterMode", new CommandHandler([](const qlibc::QData &req, qlibc::QData &req2Gas) {
+            req2Gas.putObjFmtString("param.set_value", req.getObjFmtString("param.set_value"));
+        }));
+        controlTables.appendNew("setColorMode", new CommandHandler([this](const qlibc::QData &req, qlibc::QData &req2Gas) {
+            qlibc::QData qd_param;
+            Json::Value v = mDevTree_.getDevAllInfo(req.getString("device_id"));
+            qlibc::QData v_data(v);
+//            qd_param.putString("lightness", v_data.getString("brightness_value"));
+            qd_param.putString("lightness", req.getObjFmtString("param.lightness"));
+            qd_param.putString("hue", req.getObjFmtString("param.hue"));
+            req2Gas.putData("param", qd_param);
+        }));
+        controlTables.appendNew("setFlowMode", new CommandHandler([](const qlibc::QData &req, qlibc::QData &req2Gas) {
+            req2Gas.putObjFmtString("param.flow_speed", req.getObjFmtString("param.flow_speed"));
+        }));
+        controlTables.appendNew("setCurtain", new CommandHandler([](const qlibc::QData &req, qlibc::QData &req2Gas) {
+            req2Gas.putObjFmtString("param.set_value", req.getObjFmtString("param.set_value"));
+        }));
+
+    }
+
+};
+
+
+
+#endif //SMARTPANEL_COSS_GASTRANSTABLE_H
+

+ 37 - 0
app/src/main/cpp/inc/cosasl/JECossServer.h

@@ -0,0 +1,37 @@
+//
+// Created by Ht on 2020/12/29.
+//
+
+#ifndef LIBDEVCPP_JIPVDALSERVER_H
+#define LIBDEVCPP_JIPVDALSERVER_H
+
+#include <exlib/http/QASyncHttpServer.h>
+#include <mgbus/QMgbusModule.h>
+#include "CossBridgeClass.h"
+
+namespace jedge {
+
+    class JECossServer :
+            public jedge::QMgbusModule {
+    protected:
+        CossBridgeClass  mBridge;
+
+    public:
+        explicit JECossServer(const qlibc::QData& initConfig);
+
+        ImplServerRelease(JECossServer)
+
+    public:
+        bool start(const qlibc::QData &config) override;
+        void shutdown() override;
+
+    protected:
+        void prepareService(const qlibc::QData &config) override;
+
+        bool handleOriginalMessage(qlibc::QData &msg, qlibc::QData *rsp);
+    };
+
+}
+
+
+#endif //LIBDEVCPP_JIPVDALSERVER_H

+ 68 - 0
app/src/main/cpp/inc/cosasl/LightjiaSceneProcess.h

@@ -0,0 +1,68 @@
+//
+// Created by WJG on 2022-3-18.
+//
+
+#ifndef SMARTPANEL_COSS_LIGHTJIASCENEPROCESS_H
+#define SMARTPANEL_COSS_LIGHTJIASCENEPROCESS_H
+
+#include "json/json.h"
+#include "scene_comm.h"
+
+
+#define SCENE_GROUP_FILE "/scene_cfg.json"
+#define MAX_GROUP_OF_SINGLE_DEVICE 6
+class LightjiaSceneProcess {
+public:
+    explicit LightjiaSceneProcess(const std::string& base_path);
+    explicit LightjiaSceneProcess(const std::string& base_path, const std::string& sid);
+    ~LightjiaSceneProcess();
+
+    // forceNoGroup: 不是否进行智能分组尝试,清理分组时不尝试
+    // doGroupActionNow: 如需要、是否立即向vdal进行分组指令发送
+    int parseLightjiaSceneFile(bool &groupped, const std::string &lightjia_file, const std::string &scene_file_dir,
+                               bool doGroupActionNow, bool forceNoGroup = false );
+    int refreshSceneConfig();
+
+private:
+    std::string basePath;
+
+    Json::Value result;
+    Json::Value actions;
+    Json::Value conditions;
+    Json::Value rules;
+    Json::Value new_actions;
+
+    std::string scene_id;
+    Json::Value scene_cfg_root;
+
+    bool parseLightjiaAction(const Json::Value &_lac);
+    bool parseLightjiaCondition(const Json::Value &_lcons);
+    int regroupLightjiaAction(bool &groupped, bool doRegroupAction);
+//    void defaultSubscribeLight();
+    std::string getDevidHash(const std::unordered_set<std::string>& did_set);
+    std::string divideIntoGroup(int &cntOfGroup, string &did_hash, unordered_set<std::string> &did_set, bool doRegroupActionNow);
+    int regroupProcess(int start_pos, int end_pos, bool doRegroupActionNow);
+    bool breakFromGroup(const std::string& gp_id, Json::Value dev_array);
+
+    //清空指定场景的分组信息
+    void clearSceneGroupPairConfigIfExists();
+
+    int secondCheckSceneGroupPair();
+    void saveSceneConfig();
+    void loadSceneConfig();
+
+public:
+    int clearScenelessGroups();
+    std::string getSceneGroupAddr();
+};
+
+
+class SceneRegroupWorker : public CThread {
+    void Run() override ;
+};
+
+class SceneClearGroupWorker : public CThread {
+    void Run() override ;
+};
+
+#endif //SMARTPANEL_COSS_LIGHTJIASCENEPROCESS_H

+ 23 - 0
app/src/main/cpp/inc/cosasl/MessagePackUtil.h

@@ -0,0 +1,23 @@
+//
+// Created by Ht on 2022/6/21.
+//
+
+#ifndef IOT_EDGE_SMARTPANEL_MESSAGEPACKUTIL_H
+#define IOT_EDGE_SMARTPANEL_MESSAGEPACKUTIL_H
+
+#include <string>
+
+/**
+ *  幂等操作工具:
+ *      当在最小间隔时间内输入大量的同频事件时,该队列下的事件、仅让最后一条有效。中间队列中的事件被清理。
+ */
+
+class MessagePackUtil {
+
+
+public:
+    static void pushEventTag(const Json::Value& param);
+};
+
+
+#endif //IOT_EDGE_SMARTPANEL_MESSAGEPACKUTIL_H

+ 67 - 0
app/src/main/cpp/inc/cosasl/MgBusInterface.h

@@ -0,0 +1,67 @@
+//
+// Created by WJG on 2020-5-11.
+//
+
+#ifndef MGCORE_MGBUSINTERFACE_H
+#define MGCORE_MGBUSINTERFACE_H
+
+#include <stdint.h>
+#include <vector>
+#include "../JECossServer.h"
+#include "../service/DeviceStatusService.h"
+
+using namespace std;
+
+/*****************************************************************************
+ 定义 名  : MSG_PROC_CALLBACK
+ 功能描述  : 各模块消息处理模块函数,通过reg_msg_proc_callback注册,有消息时被调用
+ 输入参数  : msg:待处理消息;len:消息长度;
+ 返 回 值  : 无
+*****************************************************************************/
+typedef void (*MSG_PROC_CALLBACK)(const string &msg);
+
+/*****************************************************************************
+ 函 数 名  : msg_bus_start
+ 功能描述  : 启动消息管理模块
+ 输入参数  : needMultiThreading:是否需要多线程支持,true-需要,false-不需要;
+ 返 回 值  : 0:成功; -1:失败; 1:已经启动;
+ 说    明  : 如果需要多线程支持,则MgBus会有多个线程分别调用MSG_PROC_CALLBACK处理消息,
+             MSG_PROC_CALLBACK内部应对相关资源做好互斥;
+             如果不需要多线程支持,则MgBus只有一个线程调用MSG_PROC_CALLBACK处理消息,
+             MSG_PROC_CALLBACK应尽快对消息进行处理,避免线程阻塞。
+*****************************************************************************/
+int msg_manager_start(bool needMultiThreading);
+
+/*****************************************************************************
+ 函 数 名  : msg_bus_stop
+ 功能描述  : 停止消息管理模块
+ 输入参数  : 无
+ 返 回 值  : 五
+*****************************************************************************/
+void msg_manager_stop();
+
+/*****************************************************************************
+ 函 数 名  : msg_put_bus
+ 功能描述  : 将消息放入MgBus,之后由MgBus将消息发送至目的地进行处理
+// 输入参数  : source:消息源;target:消息目的地;msg:要发送的消息;
+ 输入参数  : sourceModule:消息源模块名;targetModule:消息目的模块名;msg:要发送的消息;
+ 返 回 值  : 消息放入结果,0:成功,非0失败
+*****************************************************************************/
+int msg_put_in(const string &sourceModule, const string &targetMoudle, const string &msg);
+
+/*****************************************************************************
+ 函 数 名  : reg_msg_proc_callback
+ 功能描述  : 各模块向MgBus注册消息处理回调函数
+//输入参数  : mode:模块id;func:MSG_PROC_CALLBACK回调函数;
+ 输入参数  : moduleName:模块名;func:MSG_PROC_CALLBACK回调函数;
+ 返 回 值  : 无
+*****************************************************************************/
+int reg_msg_proc_callback(const string &moduleName, MSG_PROC_CALLBACK func);
+
+void set_post_handler(jedge::DeviceStatusService *jdss);
+
+int msg_post_in(const string &mod, const string &uri, qlibc::QData &data);
+
+int msg_post_in_res(const string &mod, const string &uri, qlibc::QData &data, qlibc::QData &resp);
+
+#endif //MGCORE_MGBUSINTERFACE_H

+ 61 - 0
app/src/main/cpp/inc/cosasl/MgBusManager.h

@@ -0,0 +1,61 @@
+//
+// Created by WJG on 2020-5-11.
+//
+
+#ifndef MGCORE_MGBUSMANAGER_H
+#define MGCORE_MGBUSMANAGER_H
+
+#include <string>
+#include <algorithm>
+#include <sys/types.h>
+#include "MgBusInterface.h"
+#include "../CossCore/log_tool.h"
+#include "CThreadPool.h"
+#include "mgbus/MgBusHolder.h"
+
+#define MSG_SOURCE "source"
+#define MSG_TARGET "target"
+#define MSG_BODY  "msgbody"
+
+using namespace std;
+
+class MgBusManager {
+public:
+    static MgBusManager& GetInstance()
+    {
+        if ( m_pInstance == nullptr )
+            m_pInstance = new MgBusManager();
+        return *m_pInstance;
+    };
+
+    int startMgBusModule(bool needMultiThreading);
+    void stopMgBusModule();
+    int putMsg2Queue(const string &sourceModule, const string &targetMoudle, const string &msg);
+    int sendMsg2Target(const Json::Value &value);
+    int sendMsg2Target(const std::string& mod, const std::string& uri, qlibc::QData& msg);
+    int sendMsg2TargetResp(const std::string& mod, const std::string& uri, qlibc::QData& msg, qlibc::QData &resp);
+
+    int regMegProcessFun(const string &yourModule, MSG_PROC_CALLBACK func);
+
+    void setMgBusHolder(jedge::MgBusHolder &holder);
+
+
+    MSG_PROC_CALLBACK getCallbackFun(const string &moduleName);
+    vector<string> getModuleName();
+    ~MgBusManager();
+
+private:
+    static MgBusManager* m_pInstance;
+    vector<string> moduleVector;
+    unordered_map<string, MSG_PROC_CALLBACK> moduleFun;
+    std::mutex vectorMutex;
+    CThreadPool* mThreadPool;
+    unsigned char hasStarted;
+    jedge::MgBusHolder *mgBusHolder;
+
+    MgBusManager();
+
+};
+
+
+#endif //MGCORE_MGBUSMANAGER_H

+ 1306 - 0
app/src/main/cpp/inc/cosasl/OriginalHttplib.h

@@ -0,0 +1,1306 @@
+//
+//  httplib.h
+//
+//  Copyright (c) 2020 Yuji Hirose. All rights reserved.
+//  MIT License
+//
+
+#ifndef ORIGINAL_CPPHTTPLIB_HTTPLIB_H
+#define ORIGINAL_CPPHTTPLIB_HTTPLIB_H
+
+/*
+ * Configuration
+ */
+
+#ifndef CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND
+#define CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND 5
+#endif
+
+#ifndef CPPHTTPLIB_KEEPALIVE_MAX_COUNT
+#define CPPHTTPLIB_KEEPALIVE_MAX_COUNT 5
+#endif
+
+#ifndef CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND
+#define CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND 300
+#endif
+
+#ifndef CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND
+#define CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND 0
+#endif
+
+#ifndef CPPHTTPLIB_READ_TIMEOUT_SECOND
+#define CPPHTTPLIB_READ_TIMEOUT_SECOND 5
+#endif
+
+#ifndef CPPHTTPLIB_READ_TIMEOUT_USECOND
+#define CPPHTTPLIB_READ_TIMEOUT_USECOND 0
+#endif
+
+#ifndef CPPHTTPLIB_WRITE_TIMEOUT_SECOND
+#define CPPHTTPLIB_WRITE_TIMEOUT_SECOND 5
+#endif
+
+#ifndef CPPHTTPLIB_WRITE_TIMEOUT_USECOND
+#define CPPHTTPLIB_WRITE_TIMEOUT_USECOND 0
+#endif
+
+#ifndef CPPHTTPLIB_IDLE_INTERVAL_SECOND
+#define CPPHTTPLIB_IDLE_INTERVAL_SECOND 0
+#endif
+
+#ifndef CPPHTTPLIB_IDLE_INTERVAL_USECOND
+#ifdef _WIN32
+#define CPPHTTPLIB_IDLE_INTERVAL_USECOND 10000
+#else
+#define CPPHTTPLIB_IDLE_INTERVAL_USECOND 0
+#endif
+#endif
+
+#ifndef CPPHTTPLIB_REQUEST_URI_MAX_LENGTH
+#define CPPHTTPLIB_REQUEST_URI_MAX_LENGTH 8192
+#endif
+
+#ifndef CPPHTTPLIB_REDIRECT_MAX_COUNT
+#define CPPHTTPLIB_REDIRECT_MAX_COUNT 20
+#endif
+
+#ifndef CPPHTTPLIB_PAYLOAD_MAX_LENGTH
+#define CPPHTTPLIB_PAYLOAD_MAX_LENGTH ((std::numeric_limits<size_t>::max)())
+#endif
+
+#ifndef CPPHTTPLIB_TCP_NODELAY
+#define CPPHTTPLIB_TCP_NODELAY false
+#endif
+
+#ifndef CPPHTTPLIB_RECV_BUFSIZ
+#define CPPHTTPLIB_RECV_BUFSIZ size_t(4096u)
+#endif
+
+#ifndef CPPHTTPLIB_COMPRESSION_BUFSIZ
+#define CPPHTTPLIB_COMPRESSION_BUFSIZ size_t(16384u)
+#endif
+
+#ifndef CPPHTTPLIB_THREAD_POOL_COUNT
+#define CPPHTTPLIB_THREAD_POOL_COUNT                                           \
+  ((std::max)(8u, std::thread::hardware_concurrency() > 0                      \
+                      ? std::thread::hardware_concurrency() - 1                \
+                      : 0))
+#endif
+
+#ifndef CPPHTTPLIB_RECV_FLAGS
+#define CPPHTTPLIB_RECV_FLAGS 0
+#endif
+
+#ifndef CPPHTTPLIB_SEND_FLAGS
+#define CPPHTTPLIB_SEND_FLAGS 0
+#endif
+
+/*
+ * Headers
+ */
+
+#ifdef _WIN32
+#ifndef _CRT_SECURE_NO_WARNINGS
+#define _CRT_SECURE_NO_WARNINGS
+#endif //_CRT_SECURE_NO_WARNINGS
+
+#ifndef _CRT_NONSTDC_NO_DEPRECATE
+#define _CRT_NONSTDC_NO_DEPRECATE
+#endif //_CRT_NONSTDC_NO_DEPRECATE
+
+#if defined(_MSC_VER)
+#ifdef _WIN64
+using ssize_t = __int64;
+#else
+using ssize_t = int;
+#endif
+
+#if _MSC_VER < 1900
+#define snprintf _snprintf_s
+#endif
+#endif // _MSC_VER
+
+#ifndef S_ISREG
+#define S_ISREG(m) (((m)&S_IFREG) == S_IFREG)
+#endif // S_ISREG
+
+#ifndef S_ISDIR
+#define S_ISDIR(m) (((m)&S_IFDIR) == S_IFDIR)
+#endif // S_ISDIR
+
+#ifndef NOMINMAX
+#define NOMINMAX
+#endif // NOMINMAX
+
+#include <io.h>
+#include <winsock2.h>
+
+#include <wincrypt.h>
+#include <ws2tcpip.h>
+
+#ifndef WSA_FLAG_NO_HANDLE_INHERIT
+#define WSA_FLAG_NO_HANDLE_INHERIT 0x80
+#endif
+
+#ifdef _MSC_VER
+#pragma comment(lib, "ws2_32.lib")
+#pragma comment(lib, "crypt32.lib")
+#pragma comment(lib, "cryptui.lib")
+#endif
+
+#ifndef strcasecmp
+#define strcasecmp _stricmp
+#endif // strcasecmp
+
+using socket_t = SOCKET;
+#ifdef CPPHTTPLIB_USE_POLL
+#define poll(fds, nfds, timeout) WSAPoll(fds, nfds, timeout)
+#endif
+
+#else // not _WIN32
+
+#include <arpa/inet.h>
+#include <cstring>
+#include <ifaddrs.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#ifdef __linux__
+#include <resolv.h>
+#endif
+#include <netinet/tcp.h>
+#ifdef CPPHTTPLIB_USE_POLL
+#include <poll.h>
+#endif
+#include <csignal>
+#include <pthread.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+using socket_t = int;
+#define INVALID_SOCKET (-1)
+#endif //_WIN32
+
+#include <algorithm>
+#include <array>
+#include <atomic>
+#include <cassert>
+#include <cctype>
+#include <climits>
+#include <condition_variable>
+#include <errno.h>
+#include <fcntl.h>
+#include <fstream>
+#include <functional>
+#include <iomanip>
+#include <iostream>
+#include <list>
+#include <map>
+#include <memory>
+#include <mutex>
+#include <random>
+#include <regex>
+#include <sstream>
+#include <string>
+#include <sys/stat.h>
+#include <thread>
+
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
+#include <openssl/err.h>
+#include <openssl/md5.h>
+#include <openssl/ssl.h>
+#include <openssl/x509v3.h>
+
+#if defined(_WIN32) && defined(OPENSSL_USE_APPLINK)
+#include <openssl/applink.c>
+#endif
+
+#include <iostream>
+#include <sstream>
+
+#if OPENSSL_VERSION_NUMBER < 0x1010100fL
+#error Sorry, OpenSSL versions prior to 1.1.1 are not supported
+#endif
+
+#if OPENSSL_VERSION_NUMBER < 0x10100000L
+#include <openssl/crypto.h>
+inline const unsigned char *ASN1_STRING_get0_data(const ASN1_STRING *asn1) {
+  return M_ASN1_STRING_data(asn1);
+}
+#endif
+#endif
+
+#ifdef CPPHTTPLIB_ZLIB_SUPPORT
+#include <zlib.h>
+#endif
+
+#ifdef CPPHTTPLIB_BROTLI_SUPPORT
+#include <brotli/decode.h>
+#include <brotli/encode.h>
+#endif
+
+/*
+ * Declaration
+ */
+namespace ORhttplib {
+
+namespace detail {
+
+/*
+ * Backport std::make_unique from C++14.
+ *
+ * NOTE: This code came up with the following stackoverflow post:
+ * https://stackoverflow.com/questions/10149840/c-arrays-and-make-unique
+ *
+ */
+
+template <class T, class... Args>
+typename std::enable_if<!std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(Args &&... args) {
+  return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
+}
+
+template <class T>
+typename std::enable_if<std::is_array<T>::value, std::unique_ptr<T>>::type
+make_unique(std::size_t n) {
+  typedef typename std::remove_extent<T>::type RT;
+  return std::unique_ptr<T>(new RT[n]);
+}
+
+struct ci {
+  bool operator()(const std::string &s1, const std::string &s2) const {
+    return std::lexicographical_compare(s1.begin(), s1.end(), s2.begin(),
+                                        s2.end(),
+                                        [](unsigned char c1, unsigned char c2) {
+                                          return ::tolower(c1) < ::tolower(c2);
+                                        });
+  }
+};
+
+} // namespace detail
+
+using Headers = std::multimap<std::string, std::string, detail::ci>;
+
+using Params = std::multimap<std::string, std::string>;
+using Match = std::smatch;
+
+using Progress = std::function<bool(uint64_t current, uint64_t total)>;
+
+struct Response;
+using ResponseHandler = std::function<bool(const Response &response)>;
+
+struct MultipartFormData {
+  std::string name;
+  std::string content;
+  std::string filename;
+  std::string content_type;
+};
+using MultipartFormDataItems = std::vector<MultipartFormData>;
+using MultipartFormDataMap = std::multimap<std::string, MultipartFormData>;
+
+class DataSink {
+public:
+  DataSink() : os(&sb_), sb_(*this) {}
+
+  DataSink(const DataSink &) = delete;
+  DataSink &operator=(const DataSink &) = delete;
+  DataSink(DataSink &&) = delete;
+  DataSink &operator=(DataSink &&) = delete;
+
+  std::function<void(const char *data, size_t data_len)> write;
+  std::function<void()> done;
+  std::function<bool()> is_writable;
+  std::ostream os;
+
+private:
+  class data_sink_streambuf : public std::streambuf {
+  public:
+    explicit data_sink_streambuf(DataSink &sink) : sink_(sink) {}
+
+  protected:
+    std::streamsize xsputn(const char *s, std::streamsize n) {
+      sink_.write(s, static_cast<size_t>(n));
+      return n;
+    }
+
+  private:
+    DataSink &sink_;
+  };
+
+  data_sink_streambuf sb_;
+};
+
+using ContentProvider =
+    std::function<bool(size_t offset, size_t length, DataSink &sink)>;
+
+using ContentProviderWithoutLength =
+    std::function<bool(size_t offset, DataSink &sink)>;
+
+using ContentReceiverWithProgress =
+    std::function<bool(const char *data, size_t data_length, uint64_t offset,
+                       uint64_t total_length)>;
+
+using ContentReceiver =
+    std::function<bool(const char *data, size_t data_length)>;
+
+using MultipartContentHeader =
+    std::function<bool(const MultipartFormData &file)>;
+
+class ContentReader {
+public:
+  using Reader = std::function<bool(ContentReceiver receiver)>;
+  using MultipartReader = std::function<bool(MultipartContentHeader header,
+                                             ContentReceiver receiver)>;
+
+  ContentReader(Reader reader, MultipartReader multipart_reader)
+      : reader_(std::move(reader)),
+        multipart_reader_(std::move(multipart_reader)) {}
+
+  bool operator()(MultipartContentHeader header,
+                  ContentReceiver receiver) const {
+    return multipart_reader_(std::move(header), std::move(receiver));
+  }
+
+  bool operator()(ContentReceiver receiver) const {
+    return reader_(std::move(receiver));
+  }
+
+  Reader reader_;
+  MultipartReader multipart_reader_;
+};
+
+using Range = std::pair<ssize_t, ssize_t>;
+using Ranges = std::vector<Range>;
+
+struct Request {
+  std::string method;
+  std::string path;
+  Headers headers;
+  std::string body;
+
+  std::string remote_addr;
+  int remote_port = -1;
+
+  // for server
+  std::string version;
+  std::string target;
+  Params params;
+  MultipartFormDataMap files;
+  Ranges ranges;
+  Match matches;
+
+  // for client
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
+  const SSL *ssl;
+#endif
+
+  bool has_header(const char *key) const;
+  std::string get_header_value(const char *key, size_t id = 0) const;
+  template <typename T>
+  T get_header_value(const char *key, size_t id = 0) const;
+  size_t get_header_value_count(const char *key) const;
+  void set_header(const char *key, const char *val);
+  void set_header(const char *key, const std::string &val);
+
+  bool has_param(const char *key) const;
+  std::string get_param_value(const char *key, size_t id = 0) const;
+  size_t get_param_value_count(const char *key) const;
+
+  bool is_multipart_form_data() const;
+
+  bool has_file(const char *key) const;
+  MultipartFormData get_file_value(const char *key) const;
+
+  // private members...
+  size_t redirect_count_ = CPPHTTPLIB_REDIRECT_MAX_COUNT;
+  ResponseHandler response_handler_;
+  ContentReceiverWithProgress content_receiver_;
+  size_t content_length_ = 0;
+  ContentProvider content_provider_;
+  bool is_chunked_content_provider_ = false;
+  Progress progress_;
+  size_t authorization_count_ = 0;
+};
+
+struct Response {
+  std::string version;
+  int status = -1;
+  std::string reason;
+  Headers headers;
+  std::string body;
+  std::string location; // Redirect location
+
+  bool has_header(const char *key) const;
+  std::string get_header_value(const char *key, size_t id = 0) const;
+  template <typename T>
+  T get_header_value(const char *key, size_t id = 0) const;
+  size_t get_header_value_count(const char *key) const;
+  void set_header(const char *key, const char *val);
+  void set_header(const char *key, const std::string &val);
+
+  void set_redirect(const char *url, int status = 302);
+  void set_redirect(const std::string &url, int status = 302);
+  void set_content(const char *s, size_t n, const char *content_type);
+  void set_content(const std::string &s, const char *content_type);
+
+  void set_content_provider(
+      size_t length, const char *content_type, ContentProvider provider,
+      const std::function<void()> &resource_releaser = nullptr);
+
+  void set_content_provider(
+      const char *content_type, ContentProviderWithoutLength provider,
+      const std::function<void()> &resource_releaser = nullptr);
+
+  void set_chunked_content_provider(
+      const char *content_type, ContentProviderWithoutLength provider,
+      const std::function<void()> &resource_releaser = nullptr);
+
+  Response() = default;
+  Response(const Response &) = default;
+  Response &operator=(const Response &) = default;
+  Response(Response &&) = default;
+  Response &operator=(Response &&) = default;
+  ~Response() {
+    if (content_provider_resource_releaser_) {
+      content_provider_resource_releaser_();
+    }
+  }
+
+  // private members...
+  size_t content_length_ = 0;
+  ContentProvider content_provider_;
+  std::function<void()> content_provider_resource_releaser_;
+  bool is_chunked_content_provider_ = false;
+};
+
+class Stream {
+public:
+  virtual ~Stream() = default;
+
+  virtual bool is_readable() const = 0;
+  virtual bool is_writable() const = 0;
+
+  virtual ssize_t read(char *ptr, size_t size) = 0;
+  virtual ssize_t write(const char *ptr, size_t size) = 0;
+  virtual void get_remote_ip_and_port(std::string &ip, int &port) const = 0;
+  virtual socket_t socket() const = 0;
+
+  template <typename... Args>
+  ssize_t write_format(const char *fmt, const Args &... args);
+  ssize_t write(const char *ptr);
+  ssize_t write(const std::string &s);
+};
+
+class TaskQueue {
+public:
+  TaskQueue() = default;
+  virtual ~TaskQueue() = default;
+
+  virtual void enqueue(std::function<void()> fn) = 0;
+  virtual void shutdown() = 0;
+
+  virtual void on_idle(){};
+};
+
+class ThreadPool : public TaskQueue {
+public:
+  explicit ThreadPool(size_t n) : shutdown_(false) {
+    while (n) {
+      threads_.emplace_back(worker(*this));
+      n--;
+    }
+  }
+
+  ThreadPool(const ThreadPool &) = delete;
+  ~ThreadPool() override = default;
+
+  void enqueue(std::function<void()> fn) override {
+    std::unique_lock<std::mutex> lock(mutex_);
+    jobs_.push_back(std::move(fn));
+    cond_.notify_one();
+  }
+
+  void shutdown() override {
+    // Stop all worker threads...
+    {
+      std::unique_lock<std::mutex> lock(mutex_);
+      shutdown_ = true;
+    }
+
+    cond_.notify_all();
+
+    // Join...
+    for (auto &t : threads_) {
+      t.join();
+    }
+  }
+
+private:
+  struct worker {
+    explicit worker(ThreadPool &pool) : pool_(pool) {}
+
+    void operator()() {
+      for (;;) {
+        std::function<void()> fn;
+        {
+          std::unique_lock<std::mutex> lock(pool_.mutex_);
+
+          pool_.cond_.wait(
+              lock, [&] { return !pool_.jobs_.empty() || pool_.shutdown_; });
+
+          if (pool_.shutdown_ && pool_.jobs_.empty()) { break; }
+
+          fn = pool_.jobs_.front();
+          pool_.jobs_.pop_front();
+        }
+
+        assert(true == static_cast<bool>(fn));
+        fn();
+      }
+    }
+
+    ThreadPool &pool_;
+  };
+  friend struct worker;
+
+  std::vector<std::thread> threads_;
+  std::list<std::function<void()>> jobs_;
+
+  bool shutdown_;
+
+  std::condition_variable cond_;
+  std::mutex mutex_;
+};
+
+using Logger = std::function<void(const Request &, const Response &)>;
+
+using SocketOptions = std::function<void(socket_t sock)>;
+
+inline void default_socket_options(socket_t sock) {
+  int yes = 1;
+#ifdef _WIN32
+  setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char *>(&yes),
+             sizeof(yes));
+  setsockopt(sock, SOL_SOCKET, SO_EXCLUSIVEADDRUSE,
+             reinterpret_cast<char *>(&yes), sizeof(yes));
+#else
+#ifdef SO_REUSEPORT
+  setsockopt(sock, SOL_SOCKET, SO_REUSEPORT, reinterpret_cast<void *>(&yes),
+             sizeof(yes));
+#else
+  setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<void *>(&yes),
+             sizeof(yes));
+#endif
+#endif
+}
+
+class Server {
+public:
+  using Handler = std::function<void(const Request &, Response &)>;
+  using HandlerWithContentReader = std::function<void(
+      const Request &, Response &, const ContentReader &content_reader)>;
+  using Expect100ContinueHandler =
+      std::function<int(const Request &, Response &)>;
+
+  Server();
+
+  virtual ~Server();
+
+  virtual bool is_valid() const;
+
+  Server &Get(const char *pattern, Handler handler);
+  Server &Post(const char *pattern, Handler handler);
+  Server &Post(const char *pattern, HandlerWithContentReader handler);
+  Server &Put(const char *pattern, Handler handler);
+  Server &Put(const char *pattern, HandlerWithContentReader handler);
+  Server &Patch(const char *pattern, Handler handler);
+  Server &Patch(const char *pattern, HandlerWithContentReader handler);
+  Server &Delete(const char *pattern, Handler handler);
+  Server &Delete(const char *pattern, HandlerWithContentReader handler);
+  Server &Options(const char *pattern, Handler handler);
+
+  bool set_base_dir(const char *dir, const char *mount_point = nullptr);
+  bool set_mount_point(const char *mount_point, const char *dir,
+                       Headers headers = Headers());
+  bool remove_mount_point(const char *mount_point);
+  void set_file_extension_and_mimetype_mapping(const char *ext,
+                                               const char *mime);
+  void set_file_request_handler(Handler handler);
+
+  void set_error_handler(Handler handler);
+  void set_expect_100_continue_handler(Expect100ContinueHandler handler);
+  void set_logger(Logger logger);
+
+  void set_tcp_nodelay(bool on);
+  void set_socket_options(SocketOptions socket_options);
+
+  void set_keep_alive_max_count(size_t count);
+  void set_keep_alive_timeout(time_t sec);
+  void set_read_timeout(time_t sec, time_t usec = 0);
+  void set_write_timeout(time_t sec, time_t usec = 0);
+  void set_idle_interval(time_t sec, time_t usec = 0);
+
+  void set_payload_max_length(size_t length);
+
+  bool bind_to_port(const char *host, int port, int socket_flags = 0);
+  int bind_to_any_port(const char *host, int socket_flags = 0);
+  bool listen_after_bind();
+
+  bool listen(const char *host, int port, int socket_flags = 0);
+
+  bool is_running() const;
+  void stop();
+
+  std::function<TaskQueue *(void)> new_task_queue;
+
+protected:
+  bool process_request(Stream &strm, bool close_connection,
+                       bool &connection_closed,
+                       const std::function<void(Request &)> &setup_request);
+
+  std::atomic<socket_t> svr_sock_;
+  size_t keep_alive_max_count_ = CPPHTTPLIB_KEEPALIVE_MAX_COUNT;
+  time_t keep_alive_timeout_sec_ = CPPHTTPLIB_KEEPALIVE_TIMEOUT_SECOND;
+  time_t read_timeout_sec_ = CPPHTTPLIB_READ_TIMEOUT_SECOND;
+  time_t read_timeout_usec_ = CPPHTTPLIB_READ_TIMEOUT_USECOND;
+  time_t write_timeout_sec_ = CPPHTTPLIB_WRITE_TIMEOUT_SECOND;
+  time_t write_timeout_usec_ = CPPHTTPLIB_WRITE_TIMEOUT_USECOND;
+  time_t idle_interval_sec_ = CPPHTTPLIB_IDLE_INTERVAL_SECOND;
+  time_t idle_interval_usec_ = CPPHTTPLIB_IDLE_INTERVAL_USECOND;
+  size_t payload_max_length_ = CPPHTTPLIB_PAYLOAD_MAX_LENGTH;
+
+private:
+  using Handlers = std::vector<std::pair<std::regex, Handler>>;
+  using HandlersForContentReader =
+      std::vector<std::pair<std::regex, HandlerWithContentReader>>;
+
+  socket_t create_server_socket(const char *host, int port, int socket_flags,
+                                SocketOptions socket_options) const;
+  int bind_internal(const char *host, int port, int socket_flags);
+  bool listen_internal();
+
+  bool routing(Request &req, Response &res, Stream &strm);
+  bool handle_file_request(const Request &req, Response &res,
+                           bool head = false);
+  bool dispatch_request(Request &req, Response &res, const Handlers &handlers);
+  bool
+  dispatch_request_for_content_reader(Request &req, Response &res,
+                                      ContentReader content_reader,
+                                      const HandlersForContentReader &handlers);
+
+  bool parse_request_line(const char *s, Request &req);
+  void apply_ranges(const Request &req, Response &res,
+                    std::string &content_type, std::string &boundary);
+  bool write_response(Stream &strm, bool close_connection, const Request &req,
+                      Response &res);
+  bool write_response_with_content(Stream &strm, bool close_connection,
+                                   const Request &req, Response &res);
+  bool write_response_core(Stream &strm, bool close_connection,
+                           const Request &req, Response &res,
+                           bool need_apply_ranges);
+  bool write_content_with_provider(Stream &strm, const Request &req,
+                                   Response &res, const std::string &boundary,
+                                   const std::string &content_type);
+  bool read_content(Stream &strm, Request &req, Response &res);
+  bool
+  read_content_with_content_receiver(Stream &strm, Request &req, Response &res,
+                                     ContentReceiver receiver,
+                                     MultipartContentHeader multipart_header,
+                                     ContentReceiver multipart_receiver);
+  bool read_content_core(Stream &strm, Request &req, Response &res,
+                         ContentReceiver receiver,
+                         MultipartContentHeader mulitpart_header,
+                         ContentReceiver multipart_receiver);
+
+  virtual bool process_and_close_socket(socket_t sock);
+
+  struct MountPointEntry {
+    std::string mount_point;
+    std::string base_dir;
+    Headers headers;
+  };
+  std::vector<MountPointEntry> base_dirs_;
+
+  std::atomic<bool> is_running_;
+  std::map<std::string, std::string> file_extension_and_mimetype_map_;
+  Handler file_request_handler_;
+  Handlers get_handlers_;
+  Handlers post_handlers_;
+  HandlersForContentReader post_handlers_for_content_reader_;
+  Handlers put_handlers_;
+  HandlersForContentReader put_handlers_for_content_reader_;
+  Handlers patch_handlers_;
+  HandlersForContentReader patch_handlers_for_content_reader_;
+  Handlers delete_handlers_;
+  HandlersForContentReader delete_handlers_for_content_reader_;
+  Handlers options_handlers_;
+  Handler error_handler_;
+  Logger logger_;
+  Expect100ContinueHandler expect_100_continue_handler_;
+
+  bool tcp_nodelay_ = CPPHTTPLIB_TCP_NODELAY;
+  SocketOptions socket_options_ = default_socket_options;
+};
+
+enum Error {
+  Success = 0,
+  Unknown,
+  Connection,
+  BindIPAddress,
+  Read,
+  Write,
+  ExceedRedirectCount,
+  Canceled,
+  SSLConnection,
+  SSLLoadingCerts,
+  SSLServerVerification,
+  UnsupportedMultipartBoundaryChars,
+  Compression,
+};
+
+class Result {
+public:
+  Result(std::unique_ptr<Response> res, Error err)
+      : res_(std::move(res)), err_(err) {}
+  operator bool() const { return res_ != nullptr; }
+  bool operator==(std::nullptr_t) const { return res_ == nullptr; }
+  bool operator!=(std::nullptr_t) const { return res_ != nullptr; }
+  const Response &value() const { return *res_; }
+  Response &value() { return *res_; }
+  const Response &operator*() const { return *res_; }
+  Response &operator*() { return *res_; }
+  const Response *operator->() const { return res_.get(); }
+  Response *operator->() { return res_.get(); }
+  Error error() const { return err_; }
+
+private:
+  std::unique_ptr<Response> res_;
+  Error err_;
+};
+
+class ClientImpl {
+public:
+  explicit ClientImpl(const std::string &host);
+
+  explicit ClientImpl(const std::string &host, int port);
+
+  explicit ClientImpl(const std::string &host, int port,
+                      const std::string &client_cert_path,
+                      const std::string &client_key_path);
+
+  virtual ~ClientImpl();
+
+  virtual bool is_valid() const;
+
+  Result Get(const char *path);
+  Result Get(const char *path, const Headers &headers);
+  Result Get(const char *path, Progress progress);
+  Result Get(const char *path, const Headers &headers, Progress progress);
+  Result Get(const char *path, ContentReceiver content_receiver);
+  Result Get(const char *path, const Headers &headers,
+             ContentReceiver content_receiver);
+  Result Get(const char *path, ContentReceiver content_receiver,
+             Progress progress);
+  Result Get(const char *path, const Headers &headers,
+             ContentReceiver content_receiver, Progress progress);
+  Result Get(const char *path, ResponseHandler response_handler,
+             ContentReceiver content_receiver);
+  Result Get(const char *path, const Headers &headers,
+             ResponseHandler response_handler,
+             ContentReceiver content_receiver);
+  Result Get(const char *path, ResponseHandler response_handler,
+             ContentReceiver content_receiver, Progress progress);
+  Result Get(const char *path, const Headers &headers,
+             ResponseHandler response_handler, ContentReceiver content_receiver,
+             Progress progress);
+
+  Result Head(const char *path);
+  Result Head(const char *path, const Headers &headers);
+
+  Result Post(const char *path);
+  Result Post(const char *path, const std::string &body,
+              const char *content_type);
+  Result Post(const char *path, const Headers &headers, const std::string &body,
+              const char *content_type);
+  Result Post(const char *path, size_t content_length,
+              ContentProvider content_provider, const char *content_type);
+  Result Post(const char *path, ContentProviderWithoutLength content_provider,
+              const char *content_type);
+  Result Post(const char *path, const Headers &headers, size_t content_length,
+              ContentProvider content_provider, const char *content_type);
+  Result Post(const char *path, const Headers &headers,
+              ContentProviderWithoutLength content_provider,
+              const char *content_type);
+  Result Post(const char *path, const Params &params);
+  Result Post(const char *path, const Headers &headers, const Params &params);
+  Result Post(const char *path, const MultipartFormDataItems &items);
+  Result Post(const char *path, const Headers &headers,
+              const MultipartFormDataItems &items);
+  Result Post(const char *path, const Headers &headers,
+              const MultipartFormDataItems &items, const std::string &boundary);
+
+  Result Put(const char *path);
+  Result Put(const char *path, const std::string &body,
+             const char *content_type);
+  Result Put(const char *path, const Headers &headers, const std::string &body,
+             const char *content_type);
+  Result Put(const char *path, size_t content_length,
+             ContentProvider content_provider, const char *content_type);
+  Result Put(const char *path, ContentProviderWithoutLength content_provider,
+             const char *content_type);
+  Result Put(const char *path, const Headers &headers, size_t content_length,
+             ContentProvider content_provider, const char *content_type);
+  Result Put(const char *path, const Headers &headers,
+             ContentProviderWithoutLength content_provider,
+             const char *content_type);
+  Result Put(const char *path, const Params &params);
+  Result Put(const char *path, const Headers &headers, const Params &params);
+
+  Result Patch(const char *path, const std::string &body,
+               const char *content_type);
+  Result Patch(const char *path, const Headers &headers,
+               const std::string &body, const char *content_type);
+  Result Patch(const char *path, size_t content_length,
+               ContentProvider content_provider, const char *content_type);
+  Result Patch(const char *path, ContentProviderWithoutLength content_provider,
+               const char *content_type);
+  Result Patch(const char *path, const Headers &headers, size_t content_length,
+               ContentProvider content_provider, const char *content_type);
+  Result Patch(const char *path, const Headers &headers,
+               ContentProviderWithoutLength content_provider,
+               const char *content_type);
+
+  Result Delete(const char *path);
+  Result Delete(const char *path, const std::string &body,
+                const char *content_type);
+  Result Delete(const char *path, const Headers &headers);
+  Result Delete(const char *path, const Headers &headers,
+                const std::string &body, const char *content_type);
+
+  Result Options(const char *path);
+  Result Options(const char *path, const Headers &headers);
+
+  bool send(const Request &req, Response &res, Error &error);
+  Result send(const Request &req);
+
+  size_t is_socket_open() const;
+
+  void stop();
+
+  void set_default_headers(Headers headers);
+
+  void set_tcp_nodelay(bool on);
+  void set_socket_options(SocketOptions socket_options);
+
+  void set_connection_timeout(time_t sec, time_t usec = 0);
+  void set_read_timeout(time_t sec, time_t usec = 0);
+  void set_write_timeout(time_t sec, time_t usec = 0);
+
+  void set_basic_auth(const char *username, const char *password);
+  void set_bearer_token_auth(const char *token);
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
+  void set_digest_auth(const char *username, const char *password);
+#endif
+
+  void set_keep_alive(bool on);
+  void set_follow_location(bool on);
+
+  void set_compress(bool on);
+
+  void set_decompress(bool on);
+
+  void set_interface(const char *intf);
+
+  void set_proxy(const char *host, int port);
+  void set_proxy_basic_auth(const char *username, const char *password);
+  void set_proxy_bearer_token_auth(const char *token);
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
+  void set_proxy_digest_auth(const char *username, const char *password);
+#endif
+
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
+  void enable_server_certificate_verification(bool enabled);
+#endif
+
+  void set_logger(Logger logger);
+
+protected:
+  struct Socket {
+    socket_t sock = INVALID_SOCKET;
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
+    SSL *ssl = nullptr;
+#endif
+
+    bool is_open() const { return sock != INVALID_SOCKET; }
+  };
+
+  virtual bool create_and_connect_socket(Socket &socket, Error &error);
+
+  // All of:
+  //   shutdown_ssl
+  //   shutdown_socket
+  //   close_socket
+  // should ONLY be called when socket_mutex_ is locked.
+  // Also, shutdown_ssl and close_socket should also NOT be called concurrently
+  // with a DIFFERENT thread sending requests using that socket.
+  virtual void shutdown_ssl(Socket &socket, bool shutdown_gracefully);
+  void shutdown_socket(Socket &socket);
+  void close_socket(Socket &socket);
+
+  // Similar to shutdown_ssl and close_socket, this should NOT be called
+  // concurrently with a DIFFERENT thread sending requests from the socket
+  void lock_socket_and_shutdown_and_close();
+
+  bool process_request(Stream &strm, const Request &req, Response &res,
+                       bool close_connection, Error &error);
+
+  bool write_content_with_provider(Stream &strm, const Request &req,
+                                   Error &error);
+
+  void copy_settings(const ClientImpl &rhs);
+
+  // Socket endoint information
+  const std::string host_;
+  const int port_;
+  const std::string host_and_port_;
+
+  // Current open socket
+  Socket socket_;
+  mutable std::mutex socket_mutex_;
+  std::recursive_mutex request_mutex_;
+
+  // These are all protected under socket_mutex
+  size_t socket_requests_in_flight_ = 0;
+  std::thread::id socket_requests_are_from_thread_ = std::thread::id();
+  bool socket_should_be_closed_when_request_is_done_ = false;
+
+  // Default headers
+  Headers default_headers_;
+
+  // Settings
+  std::string client_cert_path_;
+  std::string client_key_path_;
+
+  time_t connection_timeout_sec_ = CPPHTTPLIB_CONNECTION_TIMEOUT_SECOND;
+  time_t connection_timeout_usec_ = CPPHTTPLIB_CONNECTION_TIMEOUT_USECOND;
+  time_t read_timeout_sec_ = CPPHTTPLIB_READ_TIMEOUT_SECOND;
+  time_t read_timeout_usec_ = CPPHTTPLIB_READ_TIMEOUT_USECOND;
+  time_t write_timeout_sec_ = CPPHTTPLIB_WRITE_TIMEOUT_SECOND;
+  time_t write_timeout_usec_ = CPPHTTPLIB_WRITE_TIMEOUT_USECOND;
+
+  std::string basic_auth_username_;
+  std::string basic_auth_password_;
+  std::string bearer_token_auth_token_;
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
+  std::string digest_auth_username_;
+  std::string digest_auth_password_;
+#endif
+
+  bool keep_alive_ = false;
+  bool follow_location_ = false;
+
+  bool tcp_nodelay_ = CPPHTTPLIB_TCP_NODELAY;
+  SocketOptions socket_options_ = nullptr;
+
+  bool compress_ = false;
+  bool decompress_ = true;
+
+  std::string interface_;
+
+  std::string proxy_host_;
+  int proxy_port_ = -1;
+
+  std::string proxy_basic_auth_username_;
+  std::string proxy_basic_auth_password_;
+  std::string proxy_bearer_token_auth_token_;
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
+  std::string proxy_digest_auth_username_;
+  std::string proxy_digest_auth_password_;
+#endif
+
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
+  bool server_certificate_verification_ = true;
+#endif
+
+  Logger logger_;
+
+private:
+  socket_t create_client_socket(Error &error) const;
+  bool read_response_line(Stream &strm, const Request &req, Response &res);
+  bool write_request(Stream &strm, const Request &req, bool close_connection,
+                     Error &error);
+  bool redirect(const Request &req, Response &res, Error &error);
+  bool handle_request(Stream &strm, const Request &req, Response &res,
+                      bool close_connection, Error &error);
+  std::unique_ptr<Response> send_with_content_provider(
+      const char *method, const char *path, const Headers &headers,
+      const std::string &body, size_t content_length,
+      ContentProvider content_provider,
+      ContentProviderWithoutLength content_provider_without_length,
+      const char *content_type, Error &error);
+  Result send_with_content_provider(
+      const char *method, const char *path, const Headers &headers,
+      const std::string &body, size_t content_length,
+      ContentProvider content_provider,
+      ContentProviderWithoutLength content_provider_without_length,
+      const char *content_type);
+
+  virtual bool process_socket(const Socket &socket,
+                              std::function<bool(Stream &strm)> callback);
+  virtual bool is_ssl() const;
+};
+
+class Client {
+public:
+  // Universal interface
+  explicit Client(const char *scheme_host_port);
+
+  explicit Client(const char *scheme_host_port,
+                  const std::string &client_cert_path,
+                  const std::string &client_key_path);
+
+  // HTTP only interface
+  explicit Client(const std::string &host, int port);
+
+  explicit Client(const std::string &host, int port,
+                  const std::string &client_cert_path,
+                  const std::string &client_key_path);
+
+  ~Client();
+
+  bool is_valid() const;
+
+  Result Get(const char *path);
+  Result Get(const char *path, const Headers &headers);
+  Result Get(const char *path, Progress progress);
+  Result Get(const char *path, const Headers &headers, Progress progress);
+  Result Get(const char *path, ContentReceiver content_receiver);
+  Result Get(const char *path, const Headers &headers,
+             ContentReceiver content_receiver);
+  Result Get(const char *path, ContentReceiver content_receiver,
+             Progress progress);
+  Result Get(const char *path, const Headers &headers,
+             ContentReceiver content_receiver, Progress progress);
+  Result Get(const char *path, ResponseHandler response_handler,
+             ContentReceiver content_receiver);
+  Result Get(const char *path, const Headers &headers,
+             ResponseHandler response_handler,
+             ContentReceiver content_receiver);
+  Result Get(const char *path, const Headers &headers,
+             ResponseHandler response_handler, ContentReceiver content_receiver,
+             Progress progress);
+  Result Get(const char *path, ResponseHandler response_handler,
+             ContentReceiver content_receiver, Progress progress);
+
+  Result Head(const char *path);
+  Result Head(const char *path, const Headers &headers);
+
+  Result Post(const char *path);
+  Result Post(const char *path, const std::string &body,
+              const char *content_type);
+  Result Post(const char *path, const Headers &headers, const std::string &body,
+              const char *content_type);
+  Result Post(const char *path, size_t content_length,
+              ContentProvider content_provider, const char *content_type);
+  Result Post(const char *path, ContentProviderWithoutLength content_provider,
+              const char *content_type);
+  Result Post(const char *path, const Headers &headers, size_t content_length,
+              ContentProvider content_provider, const char *content_type);
+  Result Post(const char *path, const Headers &headers,
+              ContentProviderWithoutLength content_provider,
+              const char *content_type);
+  Result Post(const char *path, const Params &params);
+  Result Post(const char *path, const Headers &headers, const Params &params);
+  Result Post(const char *path, const MultipartFormDataItems &items);
+  Result Post(const char *path, const Headers &headers,
+              const MultipartFormDataItems &items);
+  Result Post(const char *path, const Headers &headers,
+              const MultipartFormDataItems &items, const std::string &boundary);
+  Result Put(const char *path);
+  Result Put(const char *path, const std::string &body,
+             const char *content_type);
+  Result Put(const char *path, const Headers &headers, const std::string &body,
+             const char *content_type);
+  Result Put(const char *path, size_t content_length,
+             ContentProvider content_provider, const char *content_type);
+  Result Put(const char *path, ContentProviderWithoutLength content_provider,
+             const char *content_type);
+  Result Put(const char *path, const Headers &headers, size_t content_length,
+             ContentProvider content_provider, const char *content_type);
+  Result Put(const char *path, const Headers &headers,
+             ContentProviderWithoutLength content_provider,
+             const char *content_type);
+  Result Put(const char *path, const Params &params);
+  Result Put(const char *path, const Headers &headers, const Params &params);
+  Result Patch(const char *path, const std::string &body,
+               const char *content_type);
+  Result Patch(const char *path, const Headers &headers,
+               const std::string &body, const char *content_type);
+  Result Patch(const char *path, size_t content_length,
+               ContentProvider content_provider, const char *content_type);
+  Result Patch(const char *path, ContentProviderWithoutLength content_provider,
+               const char *content_type);
+  Result Patch(const char *path, const Headers &headers, size_t content_length,
+               ContentProvider content_provider, const char *content_type);
+  Result Patch(const char *path, const Headers &headers,
+               ContentProviderWithoutLength content_provider,
+               const char *content_type);
+
+  Result Delete(const char *path);
+  Result Delete(const char *path, const std::string &body,
+                const char *content_type);
+  Result Delete(const char *path, const Headers &headers);
+  Result Delete(const char *path, const Headers &headers,
+                const std::string &body, const char *content_type);
+
+  Result Options(const char *path);
+  Result Options(const char *path, const Headers &headers);
+
+  bool send(const Request &req, Response &res, Error &error);
+  Result send(const Request &req);
+
+  size_t is_socket_open() const;
+
+  void stop();
+
+  void set_default_headers(Headers headers);
+
+  void set_tcp_nodelay(bool on);
+  void set_socket_options(SocketOptions socket_options);
+
+  void set_connection_timeout(time_t sec, time_t usec = 0);
+  void set_read_timeout(time_t sec, time_t usec = 0);
+  void set_write_timeout(time_t sec, time_t usec = 0);
+
+  void set_basic_auth(const char *username, const char *password);
+  void set_bearer_token_auth(const char *token);
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
+  void set_digest_auth(const char *username, const char *password);
+#endif
+
+  void set_keep_alive(bool on);
+  void set_follow_location(bool on);
+
+  void set_compress(bool on);
+
+  void set_decompress(bool on);
+
+  void set_interface(const char *intf);
+
+  void set_proxy(const char *host, int port);
+  void set_proxy_basic_auth(const char *username, const char *password);
+  void set_proxy_bearer_token_auth(const char *token);
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
+  void set_proxy_digest_auth(const char *username, const char *password);
+#endif
+
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
+  void enable_server_certificate_verification(bool enabled);
+#endif
+
+  void set_logger(Logger logger);
+
+  // SSL
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
+  void set_ca_cert_path(const char *ca_cert_file_path,
+                        const char *ca_cert_dir_path = nullptr);
+
+  void set_ca_cert_store(X509_STORE *ca_cert_store);
+
+  long get_openssl_verify_result() const;
+
+  SSL_CTX *ssl_context() const;
+#endif
+
+private:
+  std::unique_ptr<ClientImpl> cli_;
+
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
+  bool is_ssl_ = false;
+#endif
+};
+
+#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
+class SSLServer : public Server {
+public:
+  SSLServer(const char *cert_path, const char *private_key_path,
+            const char *client_ca_cert_file_path = nullptr,
+            const char *client_ca_cert_dir_path = nullptr);
+
+  SSLServer(X509 *cert, EVP_PKEY *private_key,
+            X509_STORE *client_ca_cert_store = nullptr);
+
+  ~SSLServer() override;
+
+  bool is_valid() const override;
+
+private:
+  bool process_and_close_socket(socket_t sock) override;
+
+  SSL_CTX *ctx_;
+  std::mutex ctx_mutex_;
+};
+
+class SSLClient : public ClientImpl {
+public:
+  explicit SSLClient(const std::string &host);
+
+  explicit SSLClient(const std::string &host, int port);
+
+  explicit SSLClient(const std::string &host, int port,
+                     const std::string &client_cert_path,
+                     const std::string &client_key_path);
+
+  explicit SSLClient(const std::string &host, int port, X509 *client_cert,
+                     EVP_PKEY *client_key);
+
+  ~SSLClient() override;
+
+  bool is_valid() const override;
+
+  void set_ca_cert_path(const char *ca_cert_file_path,
+                        const char *ca_cert_dir_path = nullptr);
+
+  void set_ca_cert_store(X509_STORE *ca_cert_store);
+
+  long get_openssl_verify_result() const;
+
+  SSL_CTX *ssl_context() const;
+
+private:
+  bool create_and_connect_socket(Socket &socket, Error &error) override;
+  void shutdown_ssl(Socket &socket, bool shutdown_gracefully) override;
+
+  bool process_socket(const Socket &socket,
+                      std::function<bool(Stream &strm)> callback) override;
+  bool is_ssl() const override;
+
+  bool connect_with_proxy(Socket &sock, Response &res, bool &success,
+                          Error &error);
+  bool initialize_ssl(Socket &socket, Error &error);
+
+  bool load_certs();
+
+  bool verify_host(X509 *server_cert) const;
+  bool verify_host_with_subject_alt_name(X509 *server_cert) const;
+  bool verify_host_with_common_name(X509 *server_cert) const;
+  bool check_host_name(const char *pattern, size_t pattern_len) const;
+
+  SSL_CTX *ctx_;
+  std::mutex ctx_mutex_;
+  std::once_flag initialize_cert_;
+
+  std::vector<std::string> host_components_;
+
+  std::string ca_cert_file_path_;
+  std::string ca_cert_dir_path_;
+  long verify_result_ = 0;
+
+  friend class ClientImpl;
+};
+#endif
+
+
+} // namespace ORhttplib
+
+#endif // ORIGINAL_CPPHTTPLIB_HTTPLIB_H

+ 190 - 0
app/src/main/cpp/inc/cosasl/SceneManager.h

@@ -0,0 +1,190 @@
+//
+// Created by WJG on 2020-7-7.
+//
+
+#ifndef NEWCOSS_SCENEMANAGER_H
+#define NEWCOSS_SCENEMANAGER_H
+
+#include <string>
+#include <unordered_map>
+#include <unordered_set>
+#include <mutex>
+#include "json/json.h"
+#include "scene_comm.h"
+#include "TimerWorker.h"
+#include "SceneThreadPool.h"
+#include <jebase/config.h>
+#include <qlibc/QPObjectHolder.h>
+
+class JE_API SceneWorkHandler {
+public:
+     virtual void cancelSceneRunning() = 0;
+};
+
+class JE_API RunningScene {
+protected:
+    std::string id_;
+    std::string name_;
+    SceneWorkHandler* worker_;
+public:
+    explicit RunningScene(std::string id, std::string name, SceneWorkHandler* worker) :
+        id_(std::move(id)), name_(std::move(name)), worker_(worker) {
+    }
+
+    SceneWorkHandler* getSceneWorker() {
+        return worker_;
+    }
+};
+
+struct SceneFeature_T {
+    std::string scene_id;
+    std::string scene_name;
+    std::string scene_status;    //该场景状态。 disable - 未启用; enable - 已启用
+    std::string scene_describe;   //规则描述
+    std::string scene_type;      //场景类别:customise - 用户自定义; recommend - 推荐
+    std::string run_type;        //场景执行方式。auto - 自动执行, manual - 手动执行
+    std::string run_day;        //当repeat_condition字段为4时,取值0~6,星期天为0;如星期二/星期五执行,则数据为字符串"25".
+    int familyId;               //家庭
+    std::string backgroundUri;   //背景图片
+    Json::UInt64 update_time;
+    int repeat_condition;  //复规则:0-单次;1-工作日;2-周末;3-每天;4-自定义
+    Json::Value scene_trigger;
+    Json::Value scene_rules;
+    unsigned long last_active_time;
+};
+
+class SceneManager {
+public:
+    static SceneManager& GetInstance()
+    {
+        if(m_pInstance == nullptr)
+            m_pInstance = new SceneManager();
+        return *m_pInstance;
+    };
+
+    ~SceneManager();
+
+    std::string scene_file_path;
+    std::string scene_file_path_init;
+
+    int initScenePool(const std::string &path, const std::string& init_dir);
+    int reloadScenePool();
+    int reloadScene(const std::string &scene_id);
+    std::unordered_set<std::string> getScenebyTrigger(const std::string &trigger);
+    Json::Value getEnableSceneRule(const std::string &scene_id);
+    Json::Value getSceneRule(const std::string &scene_id);
+    int getSceneCount();
+    int enableScene(const std::string &scene_id);
+    int disableScene(const std::string &scene_id);
+    int activeScene(const std::string& from, std::string &scene_id);
+    int activeScenebyName(std::string &scene_name);
+    int activeScenebyExternal(std::string &scene_name);
+    Json::Value getSceneInfo();
+    Json::Value getSceneInfo(const std::string &scene_id);
+//    Json::Value getSceneContent();
+    Json::Value getSceneContent(const std::string &scene_id);
+//    int setShortcutScene(const Json::Value &scene);
+//    Json::Value getShortcutSceneInfo();
+//    int delShortcutScene(const Json::Value &scene_id);
+
+    //针对Light+场景的处理
+    int addLightjiaScene(Json::Value &data);
+    int deleteLightjiaScene(std::string &scene_id);
+
+    // forceNoGroup: 是否强制不进行智能分组尝试,清理分组时使用
+    int parseLightjiaScene(const std::string &scene_id, bool forceNoGroup = false);
+    //分组加速
+    int regroupLightjiaScene(const std::string &scene_id);
+    //清理分组加速
+    int clearGroupInLightjiaScene(const std::string &scene_id);
+
+    bool hasSceneRunning();
+    bool setSceneRunning(const std::string &id, const std::string &name, SceneWorkHandler *pWorker);
+    void setSceneQuitting(const std::string& id);
+    int putScene2Queue(const Json::Value& scene_job);
+    int runScene(const Json::Value &data);
+    int removeScene(const std::string &scene_id);
+
+    int editLinkage(const std::string &scene_id, const std::string &pad_sn, const std::string &pad_accept);
+    int cleanLinkage(const std::string &scene_id);
+    Json::Value getLinkage(const std::string &scene_id);
+    int cleanUserScene();
+//    int deleteUserScene(const std::string &scene_id);
+    std::unordered_set<std::string> checkUserScene(std::unordered_set<std::string> cloud_id_set);
+    std::unordered_set<std::string> getUserScene();
+
+    static bool checkSceneRunning(SceneFeature_T& sc);
+
+    bool isDefaultScene(const std::string &sceneId);
+
+    void setDefaultScene(const std::string &sceneId);
+
+    void getOriginalSceneContent(const std::string &scene_id, Json::Value &scene);
+
+    int stopSceneTimerWorker(const std::string &scene_id);
+    bool addSceneTimerWorker(const std::string &scene_id, TimerWorker *tWorker);
+
+private:
+    static SceneManager* m_pInstance;
+    SceneManager();
+    int enable_number;
+    int disable_number;
+
+    std::string default_light_scene_id;
+    std::unordered_map<std::string, SceneFeature_T> scene_pool;
+    std::unordered_map<std::string, SceneFeature_T> enableScene_pool;
+    std::unordered_map<std::string, SceneFeature_T> disableScene_pool;
+    std::recursive_mutex scene_mutex;
+    std::unordered_map<std::string, std::unordered_set<std::string>> device_data_trigger;  //<trigger, scene_id>
+    std::unordered_map<std::string, std::unordered_set<std::string>> app_cmd_trigger;  //<trigger, scene_id>
+//    std::unordered_map<std::string, std::unordered_set<std::string>> system_cmd_trigger;
+    std::unordered_map<std::string, std::unordered_set<std::string>> system_timer_trigger;
+
+    int creatScenePool();
+    int parseSceneFile(const std::string& fname);
+    int parseDefaultSceneFile(const std::string& fname);
+
+    SceneThreadPool* sThreadPool;
+    TimerWorker *timerWorker;
+    std::unordered_map<std::string, std::string> sceneIdTimeMap;   //<id, updateTime>
+    std::mutex sceneIdTime_mutex;
+//    void defalutSubscribeLight(Json::Value actions);
+    Json::Value linkage_sceneid_json;
+    std::unordered_set<std::string> user_scene_id_set;
+
+    //用一个map记录已经在跑的场景
+    qlibc::QPObjectHolder<RunningScene> mRunningScenes;
+
+    //记录场景id对应的在跑的Timer
+    std::unordered_map<std::string, std::list<TimerWorker *>> mTimerMap;
+    std::list<TimerWorker *> mDelTimerList;
+    std::mutex _timer_mutex;
+
+    //add or modify by hutao.
+    bool quit_scene_ = false;
+    short showType = 0;
+
+#if 1 //defined(DEBUG)
+    short showCount = 0;
+    static const short showCountPoint = 5;
+#endif
+    //add by hutao , 2022.06.03
+public:
+    void triggerMultiPanelScene(const std::string &scene_id, const std::string &msg);
+
+protected:
+    void addTriggertoPool(std::unordered_map<std::string, std::unordered_set<std::string>> &tirggerMap,
+                          const std::string &trigger, const std::string& sceneId);
+
+    void loadSceneTriggers(const SceneFeature_T &sceneData);
+
+    void loadTrigger(const std::string& trigger, const std::string& scendId);
+
+    void showLoadedScenesAndTriggers(short udType = -1);
+
+    void removeTriggers(SceneFeature_T &sceneT);
+
+};
+
+
+#endif //NEWCOSS_SCENEMANAGER_H

+ 36 - 0
app/src/main/cpp/inc/cosasl/SceneThreadPool.h

@@ -0,0 +1,36 @@
+//
+// Created by WJG on 2021-11-3.
+//
+
+#ifndef SMARTPANEL_COSS_SCENETHREADPOOL_H
+#define SMARTPANEL_COSS_SCENETHREADPOOL_H
+
+#include <list>
+#include <mutex>
+#include <condition_variable>
+#include "json/json.h"
+
+class SceneThreadPool {
+public:
+    int thread_num;
+    int quit;
+    std::mutex msg_ListMutex;
+    std::mutex msg_ReadyMutex;
+    std::condition_variable msg_ReadyCond;
+    std::list<Json::Value> msg_List;
+    bool is_cancel;
+
+    explicit SceneThreadPool(int num);
+    ~SceneThreadPool();
+    int putMsg(const Json::Value& value);
+    int putMsgFirst(const Json::Value& value);
+    int clearMsgList();
+    int cancelMsg();
+    void stopThread();
+
+private:
+    void intiThreadPool();
+
+};
+
+#endif //SMARTPANEL_COSS_SCENETHREADPOOL_H

+ 47 - 0
app/src/main/cpp/inc/cosasl/SceneWorker.h

@@ -0,0 +1,47 @@
+//
+// Created by WJG on 2020-11-16.
+//
+
+#ifndef NEWCOSS_SCENEWORKER_H
+#define NEWCOSS_SCENEWORKER_H
+
+#include "json/json.h"
+#include "../MsgSchedule/CThread.h"
+#include "SceneManager.h"
+
+class SceneWorker : public CThread, SceneWorkHandler {
+public:
+    void Run() override;
+
+private:
+    SceneThreadPool *pool;
+    int exe_mod;   //0-条件触发执行,1-app触发执行,2-场景触发执行
+    std::string scene_id;
+    std::string scene_name;
+    std::vector<Json::Value> rules_vector;
+    Json::Value scene_rule;
+    Json::Value input_param;
+
+    std::mutex   m_;
+    bool         cancel_ = false;
+    std::condition_variable sleep_wait_;
+
+    void processScnenRule();
+    bool dealRule(Json::Value &rule);
+    bool dealAction(Json::Value &action);
+    bool dealSpecialAction(Json::Value &actions);
+    bool dealCondition(Json::Value &condition, int mul_cmp);
+    bool dealOperator(const std::string &op, const std::string &cmp_value, const std::string &value1, const std::string& value2);
+    bool dealOperator(const std::string &op, int cmp_value, int value1, int value2);
+//    bool dealOperator(std::string &op, std::string &rule_value, Json::Value &in_param);
+//    void deviceAction(std::string &action_str, Json::Value &action_param);
+//    void systemAction(std::string &action_str, Json::Value &action_param);
+//    void appAction(std::string &action_str, Json::Value &action_param);
+
+    void cancelSceneRunning() override;
+
+    bool checkCondition(const std::string& condition_key, const std::string& condition_cmp,
+                        const std::string& dev_value, const std::string& condition_v1, const std::string& condition_v2);
+};
+
+#endif //NEWCOSS_SCENEWORKER_H

+ 19 - 0
app/src/main/cpp/inc/cosasl/SystemCmd.h

@@ -0,0 +1,19 @@
+//
+// Created by WJG on 2020-11-19.
+//
+
+#ifndef NEWCOSS_SYSTEMCMD_H
+#define NEWCOSS_SYSTEMCMD_H
+
+#include "json/json.h"
+
+class SystemCmd{
+public:
+    static int systemCmd_process(const std::string& cmd, const Json::Value& data);
+
+    static int enableScene(const Json::Value& data);
+    static int disableScene(const Json::Value& data);
+    static int activeScene(const Json::Value& data);
+};
+
+#endif //NEWCOSS_SYSTEMCMD_H

+ 28 - 0
app/src/main/cpp/inc/cosasl/TimerWorker.h

@@ -0,0 +1,28 @@
+//
+// Created by WJG on 2020-11-24.
+//
+
+#ifndef NEWCOSS_TIMERWORKER_H
+#define NEWCOSS_TIMERWORKER_H
+
+#include "../MsgSchedule/CThread.h"
+
+class TimerWorker : public CThread{
+public:
+    TimerWorker(int delay_second, bool is_loop);
+    void Run() override ;
+    void stopRun();
+    void setDelayTime(int t_second);
+    void setMsgData(std::string source, std::string target, std::string msg);
+
+private:
+    unsigned int counter;
+    unsigned int delay_time;
+    bool is_looping;
+    bool is_stop;
+    std::string msg_target;
+    std::string msg_source;
+    std::string mgs_body;
+};
+
+#endif //NEWCOSS_TIMERWORKER_H

+ 74 - 0
app/src/main/cpp/inc/cosasl/app_request_process.h

@@ -0,0 +1,74 @@
+//
+// Created by WJG on 2020-6-3.
+//
+
+#ifndef NEWCOSS_APP_REQUEST_PROCESS_H
+#define NEWCOSS_APP_REQUEST_PROCESS_H
+
+#include <string>
+#include "json/json.h"
+#include <qlibc/QData.hpp>
+
+bool check_token(const std::string& token);
+void appInterface_init();
+void appRequest_process(const std::string& cmd, const Json::Value& data, Json::Value &resp);
+//void appRequest_process(const std::string& cmd, const Json::Value& data);
+//void gateLogin(const Json::Value& data);
+
+//Json::Value Welcome(const Json::Value& data);
+//Json::Value unSupport(const Json::Value& data);
+//Json::Value getGateInfo(const Json::Value& data);
+void getDeviceList(const Json::Value& data, Json::Value &resp);
+void getDeviceInfo(const Json::Value& data, Json::Value &resp);
+void getPanelList(const Json::Value& data, Json::Value &resp);
+void addDevice(const Json::Value& data, Json::Value &resp);
+void deleteDevice(const Json::Value& data, Json::Value &resp);
+//void deleteUnusedDevice(const Json::Value& data, Json::Value &resp);
+//Json::Value controlDevice(const Json::Value& data);
+void updateNickName(const Json::Value& data, Json::Value &resp);
+void getLocationList(const Json::Value& data, Json::Value &resp);
+void updateDeviceLocation(const Json::Value& data, Json::Value &resp);
+void addLocation(const Json::Value& data, Json::Value &resp);
+void deleteLocation(const Json::Value& data, Json::Value &resp);
+void getSceneList(const Json::Value& data, Json::Value &resp);
+void getSceneContent(const Json::Value& data, Json::Value &resp);
+void activateScene(const Json::Value& data, Json::Value &resp);
+void activateScenebyName(const Json::Value& data, Json::Value &resp);
+void runScene(const Json::Value& data, Json::Value &resp);
+void enableScene(const Json::Value& data, Json::Value &resp);
+void disableScene(const Json::Value& data, Json::Value &resp);
+//void addCossScene(const Json::Value& data, Json::Value &resp);
+void removeScene(const Json::Value& data, Json::Value &resp);
+void reloadScene(const Json::Value& data, Json::Value &resp);
+void getMessage(const Json::Value& data, Json::Value &resp);
+//void setHomeDevice(const Json::Value& data, Json::Value &resp);
+//void deleteHomeDevice(const Json::Value& data, Json::Value &resp);
+//void getHomeDevice(const Json::Value& data, Json::Value &resp);
+//void setShortcutDevice(const Json::Value& data, Json::Value &resp);
+//void deleteShortcutDevice(const Json::Value& data, Json::Value &resp);
+//void getShortcutDevice(const Json::Value& data, Json::Value &resp);
+void getLocationDevice(const Json::Value& data, Json::Value &resp);
+//void setShortcutScene(const Json::Value& data, Json::Value &resp);
+//void getShortcutScene(const Json::Value& data, Json::Value &resp);
+//void deleteShortcutScene(const Json::Value& data, Json::Value &resp);
+void getTempHumidity(const Json::Value& data, Json::Value &resp);
+void testScene(const Json::Value& data, Json::Value &resp);
+void testDevice(const Json::Value& data, Json::Value &resp);
+void getGroupDevice(const Json::Value& data, Json::Value &resp);
+void padKeyEvent(const Json::Value& data, Json::Value &resp);
+void PostVoiceResp(const Json::Value& data, Json::Value &resp);
+void EditSceneLinkageMode(const Json::Value& data, Json::Value &resp);
+
+void getGWDeviceList(const Json::Value& data, Json::Value &resp);
+void GWDeviceList(const Json::Value& data, Json::Value &resp);
+//void devideDevList(qlibc::QData & qd_data, qlibc::QData &qd_dvd_data);
+//void deleteGWDevice(qlibc::QData & data);
+void postGWDeleteInfo(const Json::Value& data, Json::Value &resp);
+void EditSceneMode(const Json::Value& data, Json::Value &resp);
+void GetScenePads(const Json::Value& data, Json::Value &resp);
+void reset(const Json::Value& data, Json::Value &resp);
+
+void multiPanelTrig(const Json::Value& data, Json::Value &resp);
+
+
+#endif //NEWCOSS_APP_REQUEST_PROCESS_H

+ 12 - 0
app/src/main/cpp/inc/cosasl/cosasl_main.h

@@ -0,0 +1,12 @@
+//
+// Created by Ht on 2022/12/16.
+//
+
+#ifndef INC_1_LIBDEVCPP_COSASL_MAIN_H
+#define INC_1_LIBDEVCPP_COSASL_MAIN_H
+
+
+void cosasl_main(const std::string& dir, const std::string& dir_cache);
+
+
+#endif //INC_1_LIBDEVCPP_COSASL_MAIN_H

+ 186 - 0
app/src/main/cpp/inc/cosasl/coss_comm.h

@@ -0,0 +1,186 @@
+//
+// Created by WJG on 2020-5-7.
+//
+
+#ifndef NEWCOSS_COSS_COMM_H
+#define NEWCOSS_COSS_COMM_H
+
+//#define USE_MONGOOSE 1
+//#define DEVICE_TEST
+#define DEVICE_DB
+
+#define SPACE_CHAR 32
+
+#define HTTP_NAME "http"
+#define COSS_NAME "coss"
+#define VDAL_NAME "vdal-mesh"
+#define VDAL_ZIG_NAME "vdal-zig"
+#define MUFIS_NAME "mufis"
+#define GAFFIC_NAME "gaffic"
+#define CPAD_NAME "cpad"
+#define UNKNOWN "unknown"
+#define COMMAND_SOURCE "cmd_source"
+#define MSG_SRC "mg_src"
+#define COSS_CFG_NAME "coss_cache.json"
+
+#define APP_SOURCE "app"
+#define CPAD_SOURCE "cpad"
+#define VOICE_SOURCE "voice"
+#define AUTO_SCENE_SOURCE "auto"
+#define MANUAL_SCENE_SOURCE "manual"
+#define CONFIG_CMD_SOURCE "cfg"
+
+#define DEFAULT_FROUP_FILE "default_group.json"
+#define LIGHTJIA_TYPE_FILE "lightjia_type.json"
+#define GROUP_ID_MAP_FILE "group_id_map.json"
+
+#define DEVICE_UUID "device_uuid"
+#define DEVICE_ADDRESS "device_address"
+#define DEVICE_NAME "device_name"
+#define DEVICE_GENTYPE "genType"
+#define DEVICE_HIDE "device_hide"   //不显示设备,已分组,且不是保留显示状态
+#define DEVICE_ID "device_id"
+#define DEVICE_MAC "device_mac"
+#define DEVICE_CLASS "device_class"
+#define DEVICE_TYPE "device_type"
+#define DEVICE_LOCATION "device_location"
+#define NICK_NAME "nick_name"
+#define CONNECT_TYPE "connect_type"
+#define ONLINE_STATE "online_state"
+#define RUNNING_STATE "running_state"
+#define DEVICE_BRAND "device_brand"
+#define DEVICE_GROUP_ADDR "group_addr"
+#define GROUP_DEVICE_LIST "group_dev_list"
+#define GROUP_DEVICE_CLASS "GroupDevice"
+#define STATUS_TYPE "status_type"
+#define DEVICE_LIST "device_list"
+#define FACTORY_NAME "factory_name"
+#define SOFT_VERSION "soft_ver"
+
+#define GAFFIC_SRC_SITE "$site"
+
+#define QIJIAN_COMPANY "qijian"
+
+#define ON_LINE "online"
+#define OFF_LINE "offline"
+#define DEVICE_ON "on"
+#define DEVICE_OFF "off"
+
+#define DEFAULT_GROUP "default_group"
+
+#define BASIC_PROPERTIES "basic_properties"
+
+#define LOCATION_LIST "location_list"
+#define DEFAULT_LOCATION "default_location"
+#define USER_LOCATION "user_location"
+#define LOCATION_NAME "location_name"
+
+#define REQUEST_PARAM "param"
+#define APP_TOKEN "accessToken"
+#define CALL_ID "cid"
+#define URI_KEY "uri"
+#define CMD_PARAM "param"
+
+#define URI_SPLIT "/"
+
+//#define RULE_NAME "rule_name"
+
+#define USRE_PASSWORD "password"
+#define GATE_NAME "ChanghongIoTEdge"
+#define DEFAULT_PWD "123456"
+
+#define JD_CMD "jdcmd"
+#define REQUEST "JDRequest"
+#define RESPONSE "JDResponse"
+#define SSESSION_KEY "session_key"
+#define REQUEST_2_SYSTEM "system"
+#define REQUEST_2_DEV "device"
+#define REQUEST_LIGHTJIA "lightjia"
+
+#define DEV_NAME_SPLIT "_"
+
+#define WELCOME "Welcome"
+#define UNSUPPORT "unSupport"
+
+#define CMD_GATE_LOGIN "gateLogin"
+
+#define DEVICE_CONTROL_URI "/device/controlDevice"
+#define DEVICE_RESPONSE_URI "/device/response"
+
+#define PATH_SPLIT "/"
+#define COSS_CONFIG_DIR "coss_config"
+#define DEVICE_FILE_DIR "device_info"
+#define DEV_TEST_FILE "device_test.json"
+#define USER_DEFINE_LOCATION_FILE "user_define_location.json"
+#define HOME_DEVICE_FILE "home_device.json"
+#define SHORTCUT_DEVICE_FILE "shortcut_device.json"
+#define HOME_DEVICE_LIST "home_device_list"
+#define SHORTCUT_DEVICE_LIST "shortcut_device_list"
+#define LOCATION_DEVICE_LIST "device_list"
+
+#define CONTROL_COMMAND "command"
+#define DEVICE_RESPONSE "response"
+#define RESPONSE_PARAM "param"
+#define SCAN_INFO "scan_info"
+#define SCAN_END "terminate"
+#define SCAN_DEVICE "scanDevice"
+#define ADD_DEVICE "addDevice"
+#define STOP_SCAN_DEVICE "stopScanDevice"
+#define RESET_GATE "reset"
+#define SCAN_RESULT "scanResult"
+#define ADD_RESULT "addResult"
+#define ADD_BEGIN "addBegin"
+#define ADD_RESULT_STRIP "addResultStrip"
+#define STATUS_REPORT "statusValue"
+#define SUBSCRIBE_RESULT "subscribeLightResult"
+#define CANCEL_SUBSCRIBE_RESULT "cancelSubscribeLightResult"
+#define SENSOR_REPORT "sensorValue"
+#define SENSOR_TYPE "sensor_type"
+#define SENSOR_PROPERTY "sensor_property"
+#define SUCCESS "success"
+#define FAIL "fail"
+#define OPEN_COMMAND "open"
+#define CLOSE_COMMAND "close"
+#define TURN_ON_ALL_COMMAND "turnOnAll"
+#define TURN_OFF_ALL_COMMAND "turnOffAll"
+#define TURN_ON_COMMAND "turnOn"
+#define TURN_OFF_COMMAND "turnOff"
+
+#define DEFAULT_ROOM_CN "默认房间"
+#define BRIGHTNESS "brightness_value"
+#define COLORTEMPERATURE "colortemperature_value"
+#define SATURATION "saturation_value"
+#define MODE_VALUE "mode_value"
+#define FLOW_SPEED "flow_speed"
+#define COLOR_HUE "hue_value"
+
+#define CPAD_CONNECT_TYPE "cpad"
+#define LIGHTER_CLASS "灯"
+#define SWITCH_CLASS "开关"
+#define PLUG_CLASS "插座"
+#define SENSOR_CLASS  "传感器"
+#define CURTAIN_CLASS "窗帘"
+
+#define STRING_DEVICE "device"
+#define STRING_PANEL "SmartPanel"
+#define STRING_PANEL_CN "智能面板"
+
+#define VOICE_SCENE_NOT_FOUND "对不起,你好像还没有编辑此场景"
+#define VOICE_DEVICE_NOT_FOUND "对不起,未能匹配到设备,请换个说法"
+
+#define SCENE_ACC_RESPONSE "/scene/regroupResult"
+#define SCENE_UNACC_RESPONSE "/scene/clearGroupResult"
+
+#define PAYLOAD "payload"
+#define CODE "code"
+#define MESSAGE "msg"
+#define MSG_SUCCESS "successs"
+#define MSG_FAIL "fail"
+#define RESPON_FAIL_MSG "Request return failed,please check url,token and param."
+#define CODE_SUCCESS 200
+#define CODE_FAIL 201
+#define CODE_UNSUPPORT 202
+#define CODE_PARAM_ERR 203
+#define CODE_DEVICE_NOTFOUND 204
+
+#endif //NEWCOSS_COSS_COMM_H

+ 29 - 0
app/src/main/cpp/inc/cosasl/device_msg_process.h

@@ -0,0 +1,29 @@
+//
+// Created by WJG on 2020-7-14.
+//
+
+#ifndef NEWCOSS_DEVICE_MSG_PROCESS_H
+#define NEWCOSS_DEVICE_MSG_PROCESS_H
+
+#define COSS_MSG_DEVICE_INFO "PostDeviceStatus"
+
+//void lightjiaRequest_process(const Json::Value& data);
+void devRequest_process(const Json::Value& data, Json::Value& resp);
+void devResponse_process(const Json::Value& data);
+void devResponse_gw_process(const Json::Value& data);
+void devRegister_process(const Json::Value& data);
+//void devRequest_process_gateway(const Json::Value& data, Json::Value& resp);
+void tryPostMultiPanel(const std::string& summary, Json::Value &value);
+
+void setCmdDeldevMark();
+
+void response2app(const std::string& call_id, Json::Value& rsp);
+void devMsgPut(const std::string& summary, const std::string& content);
+Json::Value devMsgGet();
+void addDevinterrupt();
+
+void getMgsMods();
+void setVdalMesh();
+void setVdalZig();
+
+#endif //NEWCOSS_DEVICE_MSG_PROCESS_H

+ 48 - 0
app/src/main/cpp/inc/cosasl/lightjiaapp_request_process.h

@@ -0,0 +1,48 @@
+//
+// Created by WJG on 2020-12-29.
+//
+
+#ifndef NEWCOSS_LIGHTJIAAPP_REQUEST_PROCESS_H
+#define NEWCOSS_LIGHTJIAAPP_REQUEST_PROCESS_H
+
+#include <string>
+#include "json/json.h"
+
+void lightjiaInterface_init();
+
+void lightjiaAppRequest_process(const std::string& cmd, const Json::Value& data, Json::Value &resp);
+
+void controlDevice(const Json::Value& data, Json::Value &resp);
+void removeDevice(const Json::Value& data, Json::Value &resp);
+void roomMsg(const Json::Value& data, Json::Value &resp);
+void deleteRoom(const Json::Value& data, Json::Value &resp);
+void changeDeviceLocation(const Json::Value& data, Json::Value &resp);
+void changeDeviceNickName(const Json::Value& data, Json::Value &resp);
+void sceneMsg(const Json::Value& data, Json::Value &resp);
+void deleteSceneMsg(const Json::Value& data, Json::Value &resp);
+void groupOperation(const Json::Value& data, Json::Value &resp);
+void getDevices(const Json::Value& data, Json::Value &resp);
+void getGroups(const Json::Value& data, Json::Value &resp);
+void executeScene(const Json::Value& data, Json::Value &resp);
+void sceneSwitch(const Json::Value& data, Json::Value &resp);  //情景开关
+void lightSwitch(const Json::Value& data, Json::Value &resp);  //照明开关
+void fourKeySwitch(const Json::Value& data, Json::Value &resp);  //四键开关
+void changeRoomName(const Json::Value& data, Json::Value &resp);
+void deleteGroup(const Json::Value& data, Json::Value &resp);
+void modifyPanelName(const Json::Value& data, Json::Value &resp);   //修改面板名
+void unbindAccount(const Json::Value& data, Json::Value &resp);   //面板和app账户解除绑定
+void updateSceneList(const Json::Value& data, Json::Value &resp);  //更新场景列表
+void getGwSceneList(const Json::Value& data, Json::Value &resp);   //gaffic获取本地场景列表
+void pushGwScene2Cloud(const Json::Value& data, Json::Value &resp);   //gaffic获取本地场景列表
+
+void regroupSceneFile(const Json::Value& data, Json::Value &resp);  //场景加速优化
+void clearSceneGroup(const Json::Value& data, Json::Value &resp);   //取消场景加速
+
+void queryDeviceInfo(const Json::Value& data, Json::Value &resp);   //向gaffic反馈设备状态消息。
+//void modifyPanelLocation(const Json::Value& data, Json::Value &resp);
+//void modifyPanelFamily(const Json::Value& data, Json::Value &resp);
+//void modifyPanelPhoto(const Json::Value& data, Json::Value &resp);
+//void deletePanel(const Json::Value& data, Json::Value &resp);
+
+
+#endif //NEWCOSS_LIGHTJIAAPP_REQUEST_PROCESS_H

+ 97 - 0
app/src/main/cpp/inc/cosasl/log_tool.h

@@ -0,0 +1,97 @@
+#ifndef MGCORE_LOGTOOL_H
+#define MGCORE_LOGTOOL_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <netdb.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/un.h>  
+#include <sys/ioctl.h>
+#include <sys/wait.h>  
+#include <arpa/inet.h>
+//#include <linux/types.h>
+//#include <linux/netlink.h>
+//#include <linux/if_ether.h>
+#include <pthread.h>
+#include <signal.h>
+#include <ctype.h>  
+#include <errno.h>  
+#include <fcntl.h>
+#include <errno.h>
+#include <termios.h>
+#include <dirent.h>
+#include <sys/time.h>
+#include <semaphore.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define LOG_OPEN	1
+#define _DEBUG      1
+#define sleep_ms(x)                     usleep(x * 1000)
+#define sleep_s(s)						sleep(s)
+#define sleep_us(us)					usleep(us)
+
+	/*log function define*/
+#if LOG_OPEN
+
+#ifdef __ANDROID_SYSTEM__
+#include <android/log.h>
+#define LOG_TAG "COSS_TAG"
+#define ipp_LogV(...) __android_log_print(ANDROID_LOG_VERBOSE, LOG_TAG, __VA_ARGS__)
+#define ipp_LogD(...) __android_log_print(ANDROID_LOG_DEBUG,   LOG_TAG, __VA_ARGS__)
+#define ipp_LogI(...) __android_log_print(ANDROID_LOG_INFO,    LOG_TAG, __VA_ARGS__)
+#define ipp_LogW(...) __android_log_print(ANDROID_LOG_WARN,    LOG_TAG, __VA_ARGS__)
+#define ipp_LogE(...) __android_log_print(ANDROID_LOG_ERROR,   LOG_TAG, __VA_ARGS__)
+
+#define ipp_LogV_Prefix ipp_LogV
+#define ipp_LogD_Prefix ipp_LogD
+#define ipp_LogI_Prefix ipp_LogI
+#define ipp_LogW_Prefix ipp_LogW
+#define ipp_LogE_Prefix ipp_LogE
+
+#else
+#define ipp_LogV_Prefix(__fmt__, ...) do{printf("[IPP]:" __fmt__, ##__VA_ARGS__);}while(0)
+#define ipp_LogD_Prefix(__fmt__, ...) do{printf("[IPP_DEBUG]:" __fmt__, ##__VA_ARGS__);}while(0)
+#define ipp_LogI_Prefix(__fmt__, ...) do{printf("[IPP_INFO]:" __fmt__, ##__VA_ARGS__);}while(0)
+#define ipp_LogW_Prefix(__fmt__, ...) do{printf("[IPP_WARNING]:" __fmt__, ##__VA_ARGS__);}while(0)
+#define ipp_LogE_Prefix(__fmt__, ...) do{printf("[IPP_ERROR]:" __fmt__, ##__VA_ARGS__);}while(0)
+
+#define ipp_LogV(__fmt__, ...) do{printf(__fmt__, ##__VA_ARGS__);}while(0)
+#define ipp_LogD(__fmt__, ...) do{printf(__fmt__, ##__VA_ARGS__);}while(0)
+#define ipp_LogI(__fmt__, ...) do{printf(__fmt__, ##__VA_ARGS__);}while(0)
+#define ipp_LogW(__fmt__, ...) do{printf(__fmt__, ##__VA_ARGS__);}while(0)
+#define ipp_LogE(__fmt__, ...) do{printf(__fmt__, ##__VA_ARGS__);}while(0)
+#endif
+
+#else
+#define ipp_LogV_Prefix(__fmt__, ...)
+#define ipp_LogD_Prefix(__fmt__, ...)
+#define ipp_LogI_Prefix(__fmt__, ...)
+#define ipp_LogW_Prefix(__fmt__, ...)
+#define ipp_LogE_Prefix(__fmt__, ...)
+
+#define ipp_LogV(__fmt__, ...)
+#define ipp_LogD(__fmt__, ...)
+#define ipp_LogI(__fmt__, ...)
+#define ipp_LogW(__fmt__, ...)
+#define ipp_LogE(__fmt__, ...)
+#endif
+/*log function define end*/
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif/*#ifndef MGCORE_LOGTOOL_H*/
+

+ 12 - 0
app/src/main/cpp/inc/cosasl/msg_process.h

@@ -0,0 +1,12 @@
+//
+// Created by WJG on 2020-6-3.
+//
+
+#ifndef NEWCOSS_MSG_PROCESS_H
+#define NEWCOSS_MSG_PROCESS_H
+
+#include <string>
+
+int cossEngine_start(const string& path, const std::string& init_dir);
+
+#endif //NEWCOSS_MSG_PROCESS_H

+ 76 - 0
app/src/main/cpp/inc/cosasl/scene_comm.h

@@ -0,0 +1,76 @@
+//
+// Created by WJG on 2020-11-11.
+//
+
+#ifndef NEWCOSS_SCENE_COMM_H
+#define NEWCOSS_SCENE_COMM_H
+
+#define SCENE_MODULE "scene"
+#define SCENE_FILE_DIR "scene_file"
+#define LIGHTJIA_SCENE_DIR "lightjia"
+
+#define SCENE_ID "id"
+#define SCENE_NAME "name"
+//#define SCENE_SUMMARY "summary"
+#define SCENE_DESCRIBE "describe"
+#define SCENE_TRIGGER "trigger"
+#define SCENE_STATUS "status"
+#define SCENE_TYPE "type"
+#define SCENE_FAMILY "familyId"
+#define SCENE_BACKGROUND "backgroundImage"
+#define SCENE_RUN_TYPE "runType"
+#define SCENE_RULE "rules"
+#define SCENE_PARAM "sceneParam"
+
+#define RULE_CONDITION "conditions"
+#define SUB_CONDITION "condition"
+#define RULE_ACTION "actions"
+#define SUB_ACTION "action"
+#define ACTION_PARAM "param"
+#define TRIGGER_PARAM "param"
+#define MULTI_CONDITION "multiCondition"
+
+#define DEVICE_TRIGGER "device/"
+#define SYSTEM_CMD_TRIGGER "system/cmd"
+#define SYSTEM_TIMER_TRIGGER "system/timer"
+#define APP_TRIGGER "app/"
+#define TEMP_HUMI_SENSOR_TRIGGER "device/sensor/TempHumi"
+#define PM25_SENSOR_TRIGGER "device/sensor/pm25"
+
+#define STRING_SLASH "/"
+#define STRING_AT_SIGN "@"
+#define STRING_DEVICE "device"
+#define STRING_SYSTEM "system"
+#define STRING_APP "app"
+
+#define SCENE_DISABLE   "disable"
+#define SCENE_ENABLE    "enable"
+#define SCENE_ACTIVE    "active"
+#define SCENE_INACTIVE  "inactive"
+#define SCENE_TYPE_USER "customise"   //用户自定义
+#define SCENE_TYPE_RECOMMEND  "recommend"  //推荐
+#define SCENE_RUN_AUTO "auto" //自动执行
+#define SCENE_RUN_MANUAL "manual" //手动执行
+#define CROSS_TRIGGER "cr_trigger" //跨面板触发
+
+#define APP_CMD_ACTIVE_SCENE "app/activeScene/"
+#define SYSTEM_CMD_ACTIVE_SCENE "system/activeScene/"
+
+#define SHORTCUT_SCENE_FILE "shortcut_scene.json"
+#define SHORTCUT_SCENE_LIST "shortcut_scene_list"
+
+#define CONDITION_OBJECT "condition_obj"
+#define CONDITION_OBJECT_DEVICE "device"
+#define CONDITION_OBJECT_GROUP "group"
+#define CONDITION_OBJECT_TEMPERATURE "temperature"
+#define CONDITION_OBJECT_HUMIDITY "humidity"
+#define CONDITION_OBJECT_PM25 "pm25"
+#define CONDITION_OBJECT_SUNTIME "sunTime"
+#define CONDITION_OBJECT_FIXEDTIME "fixedTime"
+#define CONDITION_OBJECT_SECTIONTIME "sectionTime"
+#define CONDITION_OBJECT_EXTERNAL_TEMPERATURE "externalTemperature"
+#define CONDITION_OBJECT_EXTERNAL_HUMIDITY "externalHumidity"
+
+#define LIGHT_DEFAULT_GROUP_SCENE_NAME "开关灯"
+
+#endif //NEWCOSS_SCENE_COMM_H

+ 22 - 0
app/src/main/cpp/inc/cross/DllUtil.h

@@ -0,0 +1,22 @@
+//
+// Created by Ht on 2022/1/7.
+//
+
+#ifndef INC_1_LIBDEVCPP_DLLUTIL_H
+#define INC_1_LIBDEVCPP_DLLUTIL_H
+
+#include <jebase/config.h>
+#include <string>
+
+class JE_API DllUtil {
+public:
+    static void* openLibrary(const std::string& name, std::string* errMsg = nullptr);
+
+    static void closeLibrary(void* handler, std::string* errMsg = nullptr);
+
+    static void *getFunctionAddr(void *handler, const std::string &funcName, std::string *errMsg = nullptr);
+
+    static const char *getDllFileExt();
+};
+
+#endif //INC_1_LIBDEVCPP_DLLUTIL_H

+ 43 - 0
app/src/main/cpp/inc/cross/SystemUtil.h

@@ -0,0 +1,43 @@
+//
+// Created by Ht on 2019/7/29.
+//
+
+#ifndef PROJECT_ESYSTEMUTIL_H
+#define PROJECT_ESYSTEMUTIL_H
+
+#include <string>
+#include "sysdef.h"
+#include <jebase/config.h>
+#include <vector>
+#include <mutex>
+
+class JE_API SystemUtil {
+
+public:
+    static std::string system(const char *cmd, int buffSize = 256);
+
+    static std::string getCurrentPath();
+
+    //加载路径下的目录列表到目标变量中
+    static void loadFileList(const std::string& dirName, std::vector<std::string> fileList);
+
+    static int SysSleep(unsigned long msecs, bool inerruptable = true);
+
+    static void tryWait(unsigned long ms);
+
+    static void createDirs(const std::string& dir);
+};
+
+//线程互锁
+#define SINGLE_LOCK(m) std::unique_lock<std::mutex>  __locker##m(m)
+#define SINGLE_LOCK_A(m,a) std::unique_lock<std::mutex>  __locker##m##a(m)
+#define SINGLE_LOCK_B(m,a) std::unique_lock<std::mutex>  __locker##a(m)
+//线程重入
+#define RECURSIVE_LOCK(m) std::unique_lock<std::recursive_mutex>  __locker##m(m)
+#define RECURSIVE_LOCK_A(m,a) std::unique_lock<std::recursive_mutex>  __locker##m##a(m)
+#define RECURSIVE_LOCK_B(m,b) std::unique_lock<std::recursive_mutex>  __locker##a(m)
+//直接访问名字
+#define LOCKER_NAME(m) __locker##m
+#define LOCKER_NAME_A(m,a) __locker##m##a
+
+#endif //PROJECT_ESYSTEMUTIL_H

+ 10 - 0
app/src/main/cpp/inc/cross/ctypes.h

@@ -0,0 +1,10 @@
+//
+// Created by 胡涛 on 2019/12/7.
+//
+
+#ifndef LIBDEVCPP_CTYPES_H
+#define LIBDEVCPP_CTYPES_H
+
+typedef long long ulong;
+
+#endif //LIBDEVCPP_CTYPES_H

+ 36 - 0
app/src/main/cpp/inc/cross/ifaddr.h

@@ -0,0 +1,36 @@
+//
+// Created by Ht on 2021/1/15.
+//
+
+//ifaddrs.h
+#ifndef	_IFADDRS_H_
+#define	_IFADDRS_H_
+
+#ifdef ANDROID
+struct ifaddrs {
+    struct ifaddrs  *ifa_next;
+    char		*ifa_name;
+    unsigned int	 ifa_flags;
+    struct sockaddr	*ifa_addr;
+    struct sockaddr	*ifa_netmask;
+    struct sockaddr	*ifa_dstaddr;
+    void		*ifa_data;
+};
+
+/*
+ * This may have been defined in <net/if.h>.  Note that if <net/if.h> is
+ * to be included it must be included before this header file.
+ */
+#ifndef	ifa_broadaddr
+#define	ifa_broadaddr	ifa_dstaddr	/* broadcast address interface */
+#endif
+
+#include <sys/cdefs.h>
+
+__BEGIN_DECLS
+extern int getifaddrs(struct ifaddrs **ifap);
+extern void freeifaddrs(struct ifaddrs *ifa);
+__END_DECLS
+#endif
+
+#endif

+ 54 - 0
app/src/main/cpp/inc/cross/platform.h

@@ -0,0 +1,54 @@
+#ifndef _PLATFORM_H_
+#define _PLATFORM_H_
+
+#include <netinet/in.h>
+#include <sys/socket.h>
+#include <pthread.h>
+#include <fcntl.h>
+#include <errno.h>
+//#include <android/log.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#include <semaphore.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef DELETE_POINTER
+#define DELETE_POINTER(p) \
+do\
+{\
+	if (nullptr != p)\
+	{\
+		delete p;\
+		p = nullptr;\
+	}\
+} while (0)
+#endif
+
+#ifndef DELETE_POINTER_ARRAY
+#define DELETE_POINTER_ARRAY(p) \
+do\
+{\
+	if (nullptr != p)\
+	{\
+		delete[] p;\
+		p = nullptr;\
+	}\
+} while (0)
+#endif
+
+#define sleep_ms(x)                     usleep(x * 1000)
+#define sleep_s(s)						sleep(s)
+#define sleep_us(us)					usleep(us)
+
+#define NetworkInit()
+#define NetworkCleanUp();
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif/*#ifndef _PLATFORM_H_*/
+

+ 16 - 0
app/src/main/cpp/inc/cross/sysdef.h

@@ -0,0 +1,16 @@
+//
+// Created by Ht on 2019/12/8.
+//
+
+#ifndef LIBDEVCPP_SYSDEF_H
+#define LIBDEVCPP_SYSDEF_H
+
+#if defined(_WIN32)
+#define FILE_SEP_CHR  ('\\')
+#define FILE_SEP_STR  ("\\")
+#else
+#define FILE_SEP_CHR  ('/')
+#define FILE_SEP_STR  ("/")
+#endif
+
+#endif //LIBDEVCPP_SYSDEF_H

+ 210 - 0
app/src/main/cpp/inc/do/JADebugOperationService.h

@@ -0,0 +1,210 @@
+//
+// Created by Ht on 2022/1/8.
+//
+
+
+/**
+ *      开发测试支持工具,
+ *          便于快速实现一些功能的测试。
+ *
+ */
+
+#ifndef INC_0_LIBDEVCPP_QJAGAFFICSERVICE_H
+#define INC_0_LIBDEVCPP_QJAGAFFICSERVICE_H
+
+#include <exlib/QJAServiceEntry.h>
+#include <exlib/http/QHttpServer.h>
+#include "debug/JAVdaoDebuggers.h"
+
+namespace jedge {
+
+#define getFieldCStr(_field, _jsobj) \
+    const auto* _field = (_jsobj).isMember(#_field) ? h.operator[](#_field).asCString() : ""
+#define getFieldVal(_field, _jsobj) \
+    auto _field = (_jsobj).isMember(#_field) ? h.operator[](#_field) : Json::nullValue;
+
+    static const char* fileMsg = R"({"code":200,"payload":[{"device_mode":"SmartPadOs","item_key":"android-px30-v1","ver":"%s"}]})";
+    static const char* vkey_target_info_query_module_ = "cpad";
+    static const char* sval_mod_target = "vdalt";
+
+    class JE_API JEDebugTargetDevice {
+    public:
+        std::string                 mModule;
+        std::string                 mPanelName;
+        std::string                 mPanelSn;
+        std::string                 mPanelIp;
+        std::string                 mAppVer;
+        std::string                 mGateVer;
+        std::string                 mSysVer;
+
+        Json::Value                 mUpdateMeshDevs;
+        Json::Value                 mDevices;
+
+        explicit JEDebugTargetDevice(std::string mod, std::string panel,
+                                     std::string sn, std::string ip,
+                                     std::string av, std::string gv,
+                                     std::string ver) :
+                mModule(std::move(mod)) ,
+                mPanelName(std::move(panel)),
+                mPanelSn(std::move(sn)),
+                mPanelIp(std::move(ip)),
+                mAppVer(std::move(av)),
+                mGateVer(std::move(gv)),
+                mSysVer(std::move(ver)),
+                mUpdateMeshDevs(Json::arrayValue),
+                mDevices(Json::arrayValue) {
+        }
+    };
+
+    class JEMeshDevice {
+    public:
+        JEMeshDevice(std::string idx, std::string disc, std::string cap) :
+                     key_(std::move(idx)), disc_(std::move(disc)),cap_(std::move(cap)) {
+        }
+
+        std::string key_;
+        std::string disc_;
+        std::string cap_;
+    };
+
+    class JADebugOperationService :
+            public  QJAPluginService {
+    protected:
+        std::string         data_base_path_;          //
+        std::string         target_module_;           //
+
+        std::recursive_mutex m_;
+        qlibc::QPObjectHolder<JEMeshDevice>
+                            mDeviceTypes;
+        qlibc::QPObjectHolder<JEDebugTargetDevice>
+                            mJEdgeNodes;
+
+        qlibc::QRTimer      showTimer;
+
+        unsigned long       runCount = 0;
+        bool                showNodes = false;
+
+    public:
+        explicit JADebugOperationService(jedge::QJAMgServer& opr, const std::string &name, const qlibc::QData &config);
+
+        //面板操作:显示所有可用面板,设置活跃面板,显示当前活跃面板
+        // panel    显示当前活跃的面板
+        // panel -l 列举当前所有可用面板
+        // panel <sn|a,b,c,...> 选择一个活跃节点用于开发
+        bool panelOperation(qlibc::JCArgNode& param);
+
+        //vdal端口操作
+        // port             列举子命令帮助
+        // port -l          列举远程面板的可用port
+        // port <name>      选择一个远程port
+        // port name <name> 选择一个远程port
+        // port name        显示当前的已选port
+        // port reload      远程port重载
+        // port path [<newPath>] 显示本地vdao文件的路径[设置路径]
+        // port local       列举本地的可用vdao文件
+        // port list        列举远程可用的vdao资源文件
+        // port upload  <file>   上传一个本地的vdao文件到远程动态vdao目录,并立即加载这个vdao文件
+        // port remove  <file>   删除一个远程vdao资源文件
+        // port show        显示远程port中已加载的vdao资源(gao -l <grepKey>)
+        // port jedp-show   显示远程port中已加载的jedp资源项
+        // port jedp-local  显示本地可用jedp资源
+        // port jedp-upload 上传一个jedp文件到远程(如有同名文件,则覆盖之,覆盖后自动重载port)
+    ImplementCommandHandler(portOperation, JAVdaoDebuggers);
+
+        //设备操作
+        // dev list         列举当前所有可用操作设备
+        // dev              显示当前的设备操作对象
+        // dev set <dev>    设置默认的设备操作对象
+    ImplementCommandHandler(devOperation, JAVdaoDevOperator);
+
+        //消息资源调式:  用于基于vdal的消息发送和返回调试.
+        // sc                   显示子命令的帮助信息
+        // sc path [<scPath>]   显示[设置]调试消息路径
+        // sc list [<grep_key>] 列举scPath路径中的所有可用脚本文件
+        // sc file [<name>]     设置本地默认脚本文件
+        // sc show [<file>]     列举本地默认脚本[文件]中可用的消息
+        // sc send [<file>.]<msgNo> 发送一个脚本消息(执行<file>.msgNo)
+        // sc p,step [<file>.]<msgNo> 启动一个消息动作调试
+        // sc n,next            执行消息的下一个响应,并观察返回的消息log
+        // sc g,go              执行完毕当前的VDAO指令序列
+        // sc c,cancel          取消当前单步执行系列
+    ImplementCommandHandler(debugMessage, JAVdaoScRunner);
+
+        //串口模拟消息调式:
+        // ss                   显示子命令的帮助信息
+        // sc path [<scPath>]   显示[设置]调试串口资源库的消息路径
+        // ss list              列举scPath路径中的所有可用脚本文件
+        // ss file [<name>]     列举本地脚本文件
+        // ss show [<file>]     列举本地脚本文件中可用的消息
+        // ss [<file>].no       发送一个文件资源中的串口(编号)消息的字节流到vdal模拟串口上报消息
+        // ss "bytes"           发送一个串口命令
+    ImplementCommandHandler(debugSerial, JAVdaoSerialEmulator);
+
+        inline void markShowDebugNodes() {
+            showNodes = true;
+        }
+
+        void checkPanelOnlineInfo(const std::string& mgnet, bool forceRecheck, bool showBle, bool showDev , QStringList& toDel, std::mutex& m);
+
+
+        void checkMgbusNodeOffline(bool forceRecheck, bool showBle = false, bool showDev = false);
+
+        void queryOnlineMgbusModules(QStringList& mods);
+
+        void onServiceStart(const QData &config) override;
+
+        void onServiceStop() override {
+            //停止自动显示扫描到的panel列表
+            operator_.timerEngineRef()->stopTimer(showTimer);
+            MgService::onServiceStop();
+        }
+
+
+        const std::string& getCaptionOfDeviceType(const std::string& mode);
+
+        const std::string& getDiscriptionOfDeviceType(const std::string& mode);
+
+        void showMeshDevices(Json::Value &value, const char* showMark = qlog_LOG);
+
+        //是否显示ble设备
+        void showDebugNodeList(bool showBle = true, bool showDev = false, const std::string& PanelToShow = "");
+
+
+        /**
+         *      device.txt
+         *          02 22,bubble,球泡灯
+         *          01 01,gate,mesh网关
+         *          ……
+         * @param fn
+         */
+        void loadDeviceDefine(const std::string& fn);
+
+        bool dbgLog(qlibc::QData &req, qlibc::QData *resp);
+
+        void preparePattern() override {
+            prepareSelfBind;
+            bindHandler(dbgLog);
+        }
+
+        //mgnet, panelName, ip, appver, gatever, sysver
+        bool checkMgbusNodeOk(const std::string &mgnet, std::string &panelName, std::string & ip,
+                              std::string & appver, std::string & gatever, std::string & sysver,
+                              bool forceRecheck = false);
+
+        bool insertIfOldNotExistsNorEquals(const std::string &mgnet,const std::string &mod,const std::string &panelName,const std::string & sn, const std::string & ip,
+                                           const std::string & appver, const std::string & gatever,const std::string & sysver);
+
+        bool queryPanelInfos(const std::string &mgnet, const std::string &mod);
+
+        bool OnModuleConnected(MgTriggerWatcher &w, const string &k, const QData &m) override;
+
+        bool OnModuleDisconnected(MgTriggerWatcher &w, const string &k, const QData &m) override {
+            emtpyWatchers();
+            return QJAMgService::OnModuleDisconnected(w, k, m);
+        }
+
+    };
+
+}
+#endif //INC_0_LIBDEVCPP_QJAGAFFICSERVICE_H
+

+ 104 - 0
app/src/main/cpp/inc/do/JAExtCommandor.h

@@ -0,0 +1,104 @@
+//
+// Created by Ht on 2022/10/29.
+//
+
+#ifndef INC_1_LIBDEVCPP_JAEXTCOMMANDOR_H
+#define INC_1_LIBDEVCPP_JAEXTCOMMANDOR_H
+
+#include <qlibc/qlibc.h>
+#include <qlibc/cmd/JCArgNode.h>
+#include <exlib/QJAServer.h>
+#include <exlib/QJAService.h>
+
+#include <utility>
+
+namespace qlibc {
+
+    class JAExtCommandor;
+
+    using JAExtCommandHandler = std::function<bool(qlibc::JCArgNode& node)>;
+    using JAExtCommandHandlerR = std::shared_ptr<JAExtCommandHandler>;
+
+    using JAExtFuncCommandHandler = std::function<bool(JAExtCommandor& cmdor, qlibc::JCArgNode& node)>;
+    using JAExtFuncCommandHandlerR = std::shared_ptr<JAExtFuncCommandHandler>;
+
+    class JE_API JAExtCommandHandlerInfo {
+    public:
+        explicit JAExtCommandHandlerInfo(const JAExtCommandHandler& handler, std::string help):
+            handler_(std::make_shared<JAExtCommandHandler>(handler)), help_info_(std::move(help)){}
+        explicit JAExtCommandHandlerInfo(const JAExtFuncCommandHandler& handler, std::string help):
+                func_(std::make_shared<JAExtFuncCommandHandler>(handler)), help_info_(std::move(help)){}
+        JAExtCommandHandlerR handler_;
+        JAExtFuncCommandHandlerR func_;
+        std::string          help_info_;
+    };
+
+    using JAExtCommandHandlerInfoR = std::shared_ptr<JAExtCommandHandlerInfo>;
+    /**
+     *  扩展命令实现模块,用于快速生成二级命令实现模块
+     *
+     *
+     */
+    class JE_API JAExtCommandor {
+    protected:
+        qlibc::QSharedObjectHolder<JAExtCommandHandlerInfo>  handlers_;
+        std::string cmd_;
+
+    public:
+        jedge::QJAMgServer& server_;
+        jedge::QJAMgService& service_;
+        std::string target_mod_;
+
+        explicit JAExtCommandor(std::string cmdKey, jedge::QJAMgServer& opr, jedge::QJAMgService& svc) :
+            cmd_(std::move(cmdKey)), server_(opr), service_(svc)
+            {}
+        virtual ~JAExtCommandor() = default;
+
+        virtual void buildCommandHandlers() {}
+
+        bool accept(const std::string &cmd);
+
+        void showHelpInfo();
+
+        bool handleCommand(qlibc::JCArgNode &node);
+
+        void initHandlers(const std::string& debugModule);
+
+        void appendHandler(const std::string& cmdKey, const JAExtCommandHandler& handler,const std::string& help);
+        void appendHandler(const std::string& cmdKey, const JAExtFuncCommandHandler& handler,const std::string& help);
+    };
+
+    using JAExtCommandorR = std::shared_ptr<JAExtCommandor>;
+
+#define defineCommandorHandler(_func,_help) \
+    appendHandler(#_func, [this](qlibc::JCArgNode& _nd)->bool { \
+        return _func(_nd); \
+    },_help)
+
+#define defineCommandorFuncHandler(_func,_help) \
+    appendHandler(#_func, [](qlibc::JAExtCommandor& _cd, qlibc::JCArgNode& _nd)->bool { \
+        return _func(_cd,_nd); \
+    },_help)
+
+#define defineCommandorFuncHandlerBy(_cmd,_func,_help) \
+    appendHandler(_cmd, [](qlibc::JAExtCommandor& _cd, qlibc::JCArgNode& _nd)->bool { \
+        return _func(_cd,_nd); \
+    },_help)
+
+#define BindServiceCommandHandlers(_cmd, _help, _handler, _cmdor,_mod) \
+            BindServiceCommand(_cmd, _help, _handler);\
+            _handler##_cmdor = std::make_shared<jedge::_cmdor>(_cmd,getContextServer(),*this);   \
+            _handler##_cmdor->initHandlers(_mod);
+
+#define ImplementCommandHandler(_handler,_cmdor) \
+    protected:  std::shared_ptr<jedge::_cmdor> _handler##_cmdor; \
+    public:  bool _handler(qlibc::JCArgNode& _p) { \
+        if((_handler##_cmdor)!=nullptr && (_handler##_cmdor)->handleCommand(_p)) \
+            return true; \
+        QWarn("Unhandled command : %s", _p.toJSONString().c_str()); \
+        return true; \
+    }
+
+}
+
+#endif //INC_1_LIBDEVCPP_JAEXTCOMMANDOR_H

+ 62 - 0
app/src/main/cpp/inc/do/JAVdaoDebuggers.h

@@ -0,0 +1,62 @@
+//
+// Created by Ht on 2022/10/29.
+//
+
+#ifndef INC_1_LIBDEVCPP_JAVDAODEBUGGERS_H
+#define INC_1_LIBDEVCPP_JAVDAODEBUGGERS_H
+
+#include "../cmder/JAExtCommandor.h"
+
+namespace jedge {
+
+    class JE_API JAVdaoDebuggers :
+            public qlibc::JAExtCommandor {
+    public:
+        explicit JAVdaoDebuggers(const std::string& cmdKey, jedge::QJAMgServer& opr, jedge::QJAMgService& svc) :
+                qlibc::JAExtCommandor(cmdKey, opr, svc) {
+        }
+
+        void buildCommandHandlers() override;
+    };
+
+    using JAVdaoDebuggersR = std::shared_ptr<JAVdaoDebuggers>;
+
+    class JE_API JAVdaoDevOperator :
+            public qlibc::JAExtCommandor {
+    public:
+        explicit JAVdaoDevOperator(const std::string& cmdKey, jedge::QJAMgServer& opr, jedge::QJAMgService& svc) :
+                qlibc::JAExtCommandor(cmdKey, opr, svc) {}
+
+        void buildCommandHandlers() override;
+    };
+
+    using JAVdaoDebuggersR = std::shared_ptr<JAVdaoDebuggers>;
+
+    class JE_API JAVdaoScRunner :
+            public qlibc::JAExtCommandor {
+    public:
+        explicit JAVdaoScRunner(const std::string& cmdKey, jedge::QJAMgServer& opr, jedge::QJAMgService& svc) :
+        qlibc::JAExtCommandor(cmdKey, opr, svc) {}
+
+        void buildCommandHandlers() override;
+    };
+
+    using JAVdaoDebuggersR = std::shared_ptr<JAVdaoDebuggers>;
+
+    class JE_API JAVdaoSerialEmulator :
+            public qlibc::JAExtCommandor {
+    public:
+        explicit JAVdaoSerialEmulator(const std::string& cmdKey, jedge::QJAMgServer& opr, jedge::QJAMgService& svc) :
+        qlibc::JAExtCommandor(cmdKey, opr, svc) {}
+
+        void buildCommandHandlers() override;
+    };
+
+    using JAVdaoDebuggersR = std::shared_ptr<JAVdaoDebuggers>;
+
+    void showResultLog(ChannelOperator& opr, const std::string& command, qlibc::QData *resp);
+
+    void setDefaultDebuggerTarget(const std::string& debug_module);
+}
+
+#endif //INC_1_LIBDEVCPP_JAVDAODEBUGGERS_H

+ 20 - 0
app/src/main/cpp/inc/exlib/EXFileUtils.h

@@ -0,0 +1,20 @@
+//
+// Created by Ht on 2020/7/6.
+//
+
+#ifndef JVDALUNIT_EXFILEUTILS_H
+#define JVDALUNIT_EXFILEUTILS_H
+
+#include <string>
+#include <jebase/config.h>
+
+class JE_API EXFileUtils {
+
+public:
+    static bool fileExists(std::string& fileName);
+
+    static void extOfFileName(const std::string &filename, std::string& ext);
+};
+
+
+#endif //JVDALUNIT_EXFILEUTILS_H

+ 135 - 0
app/src/main/cpp/inc/exlib/JAMgModuleHelper.h

@@ -0,0 +1,135 @@
+//
+// Created by Ht on 2021/12/2.
+//
+
+#ifndef INC_0_LIBDEVCPP_JAMGMODULEHELPER_H
+#define INC_0_LIBDEVCPP_JAMGMODULEHELPER_H
+
+#include <qlibc/cmd/JCCmdRunnerHelper.h>
+#include <exlib/QJAService.h>
+
+
+namespace jedge {
+
+    using QJAServicePreBinder = std::function<void(jedge::QJAMgServer& server, const qlibc::QData &config)>;
+
+    class JE_API JAMgModuleObjHelper : public QJAMgServer {
+    protected:
+        //用户自定义服务加载器,可加载一些用户自定义的C++服务
+        QJAServicePreBinder* servic_binder_ = nullptr;
+    public:
+        explicit JAMgModuleObjHelper(qlibc::QData& cfg, const std::string& appName,  const QJAServicePreBinder& binder) :
+                QJAMgServer(cfg, rebuildMgbusConfig(cfg, appName), cfg.getString("sc_type")!="tcp"?typeUDP:typeTCP) {
+            //处理代码
+            servic_binder_ = new QJAServicePreBinder(binder);
+        }
+
+        explicit JAMgModuleObjHelper(qlibc::QData& cfg, const std::string& appName) :
+                QJAMgServer(cfg, rebuildMgbusConfig(cfg, appName), cfg.getString("sc_type")!="tcp"?typeUDP:typeTCP) {
+        }
+
+        ~JAMgModuleObjHelper() override {
+            delete servic_binder_;
+        }
+
+    protected:
+        void prepareService(const qlibc::QData &config) override {
+            MgBusHolder::prepareService(config);
+            if(servic_binder_!=nullptr) {
+                try { servic_binder_->operator()(*this, config);
+                } catch (std::bad_function_call& e) {}
+            }
+        }
+    };
+
+    class JE_API JAMgModuleHelperUtil {
+
+    public:
+        static void prepareJedgeAppInitParam(qlibc::QData& auxData, const int argc, const char* argv[]);
+
+        /**
+         *  快速启动一个JAM应用 可在argv中添加参数
+         *      --jam  <name>
+         *      --sc_type  <type>               接入类型 tcp : typeTCP, other : typeUDP
+         *      --mg_host  <host>:127.0.0.1     mgbus主机地址
+         *      --mg_port  <port>:8877          mgbus端口
+         *
+         * @param argc
+         * @param argv
+         * @param appname
+         */
+
+        static void createJAMgModuleInstance(int argc, const char *argv[], const  char* appname, const qlibc::QData& auxData, bool changePath);
+
+        static void createJAMgModuleInstanceWithInitScripts(int argc, const char *argv[], const char* appname, const qlibc::QData& auxData, bool changePath, bool showPrompt=false, const std::string& initCmd = "");
+
+        static void createJAMgModuleInstance(int argc, const char *argv[], const char* appname, const qlibc::QData& auxData, const QJAServicePreBinder&  binder,
+                                             bool changePath, const std::string& initCmd = "");
+
+        static void createJAMgModuleInstance(int argc, const char *argv[], const  char* appname, bool changePath) {
+            createJAMgModuleInstance(argc, argv, appname, qlibc::QData(), changePath);
+        }
+
+        static void createJAMgModuleInstanceWithInitScripts(int argc, const char *argv[], const char* appname,
+                                                            bool changePath, bool showPrompt=false, const std::string& initCmd = "") {
+            createJAMgModuleInstanceWithInitScripts(argc, argv, appname, qlibc::QData(), changePath, showPrompt, initCmd);
+        }
+
+        static void createJAMgModuleInstance(int argc, const char *argv[], const char* appname,
+                                             const QJAServicePreBinder&  binder, bool changePath, const std::string& initCmd = "") {
+            createJAMgModuleInstance(argc, argv, appname, qlibc::QData(), binder, changePath, initCmd);
+        }
+    };
+
+#define createJAInstance(argc, argv, appname) \
+    int _nargc = 0; const char** _nargv = nullptr; \
+    qlibc::JCCmdRunnerHelper::updateArgsForPath(argc, argv, _nargc, &_nargv, appname, qlibc::changeDirSetForDebug); \
+    jedge::JAMgModuleHelperUtil::createJAMgModuleInstance(_nargc, _nargv, appname, qlibc::changeDirSetForDebug); \
+    if(_nargv!= nullptr && _nargv!=(argv)) delete _nargv
+
+#define createJAInstanceWithAux(argc, argv, appname, auxData) \
+    int _nargc = 0; const char** _nargv = nullptr; \
+    qlibc::JCCmdRunnerHelper::updateArgsForPath(argc, argv, _nargc, &_nargv, appname, qlibc::changeDirSetForDebug); \
+    jedge::JAMgModuleHelperUtil::createJAMgModuleInstance(_nargc, _nargv, appname, auxData, qlibc::changeDirSetForDebug); \
+    if(_nargv!= nullptr && _nargv!=(argv)) delete _nargv
+
+#define createJAInstanceWithInitScript(argc, argv, appname, initCmd) \
+    int _nargc = 0; const char** _nargv = nullptr; \
+    qlibc::JCCmdRunnerHelper::updateArgsForPath(argc, argv, _nargc, &_nargv, appname, qlibc::changeDirSetForDebug); \
+    jedge::JAMgModuleHelperUtil::createJAMgModuleInstanceWithInitScripts(_nargc, _nargv, appname, qlibc::changeDirSetForDebug, false, initCmd); \
+    if(_nargv!= nullptr && _nargv!=(argv)) delete _nargv
+
+#define createJAInstanceWithInitScriptWithAux(argc, argv, appname, auxData, initCmd) \
+    int _nargc = 0; const char** _nargv = nullptr; \
+    qlibc::JCCmdRunnerHelper::updateArgsForPath(argc, argv, _nargc, &_nargv, appname, qlibc::changeDirSetForDebug); \
+    jedge::JAMgModuleHelperUtil::createJAMgModuleInstanceWithInitScripts(_nargc, _nargv, appname, auxData, qlibc::changeDirSetForDebug, false, initCmd); \
+    if(_nargv!= nullptr && _nargv!=(argv)) delete _nargv
+
+#define createJAInstanceWithInitScriptAndCommand(argc, argv, appname, initCmd) \
+    int _nargc = 0; const char** _nargv = nullptr; \
+    qlibc::JCCmdRunnerHelper::updateArgsForPath(argc, argv, _nargc, &_nargv, appname,  qlibc::changeDirSetForDebug); \
+    jedge::JAMgModuleHelperUtil::createJAMgModuleInstanceWithInitScripts(_nargc, _nargv, appname, qlibc::changeDirSetForDebug, true, initCmd); \
+    if(_nargv!= nullptr && _nargv!=(argv)) delete _nargv
+
+#define createJAInstanceWithInitScriptAndCommandWithAux(argc, argv, appname, auxData, initCmd) \
+    int _nargc = 0; const char** _nargv = nullptr; \
+    qlibc::JCCmdRunnerHelper::updateArgsForPath(argc, argv, _nargc, &_nargv, appname,  qlibc::changeDirSetForDebug); \
+    jedge::JAMgModuleHelperUtil::createJAMgModuleInstanceWithInitScripts(_nargc, _nargv, appname, auxData, qlibc::changeDirSetForDebug, true, initCmd); \
+    if(_nargv!= nullptr && _nargv!=(argv)) delete _nargv
+
+    //start with argc, argv , appname, binder, initCmd
+#define createJAInstanceWithBinder(argc, argv, appname, binder, initCmd) \
+    int _nargc = 0; const char** _nargv = nullptr; \
+    qlibc::JCCmdRunnerHelper::updateArgsForPath(argc, argv, _nargc, &_nargv, appname, qlibc::changeDirSetForDebug); \
+    jedge::JAMgModuleHelperUtil::createJAMgModuleInstance(_nargc, _nargv, appname, binder, qlibc::changeDirSetForDebug, initCmd); \
+    if(_nargv!= nullptr && _nargv!=(argv)) delete _nargv
+
+    //start with argc, argv , appname, auxData, binder, initCmd
+#define createJAInstanceWithBinderWithAux(argc, argv, appname, auxData, binder, initCmd) \
+    int _nargc = 0; const char** _nargv = nullptr; \
+    qlibc::JCCmdRunnerHelper::updateArgsForPath(argc, argv, _nargc, &_nargv, appname, qlibc::changeDirSetForDebug); \
+    (auxData).putString("plat",APP_PLATFORM);                                                                          \
+    jedge::JAMgModuleHelperUtil::createJAMgModuleInstance(_nargc, _nargv, appname, auxData, binder, qlibc::changeDirSetForDebug, initCmd); \
+    if(_nargv!= nullptr && _nargv!=(argv)) delete _nargv
+}
+#endif //INC_0_LIBDEVCPP_JAMGMODULEHELPER_H

+ 32 - 0
app/src/main/cpp/inc/exlib/JGateClient.h

@@ -0,0 +1,32 @@
+//
+// Created by Ht on 2020/12/16.
+//
+
+#ifndef LIBDEVCPP_JGATECLIENT_H
+#define LIBDEVCPP_JGATECLIENT_H
+
+#include <string>
+#include <jebase/config.h>
+#include <qlibc/qlibc.h>
+
+namespace jedge {
+
+    class JE_API JGateClient {
+
+    protected:
+        qlibc::QData config_;
+
+    public:
+        explicit JGateClient(const qlibc::QData &config) : config_(config){
+        }
+
+        virtual ~JGateClient() = default;
+
+        virtual bool start() = 0;
+
+        virtual void shutdown() = 0;
+    };
+}
+
+
+#endif //LIBDEVCPP_JGATECLIENT_H

+ 186 - 0
app/src/main/cpp/inc/exlib/QExMgbusServer.h

@@ -0,0 +1,186 @@
+//
+// Created by Ht on 2021/4/17.
+//
+
+#ifndef INC_0_LIBDEVCPP_QEXMGBUSSERVER_H
+#define INC_0_LIBDEVCPP_QEXMGBUSSERVER_H
+
+#include <mgbus/QMgbusModule.h>
+#include <exlib/http/QASyncHttpServer.h>
+#include <exlib/sock/QNodeServer.h>
+#include <exlib/http/ECSInvokeService.h>
+#include <exlib/sock/MgNodeManagerService.h>
+
+namespace jedge {
+
+    class JE_API MgbusModuleWithHttp : public QMgbusModule {
+    public:
+        explicit MgbusModuleWithHttp(const qlibc::QData& initConfig, const std::string& modulename)
+                : QMgbusModule(initConfig, modulename), mHttpServer(*this), cmdns_client_(threadPool(), timerEngine()) {
+            markDataChannel(DATA_CHANNEL_HTTP, mHttpServer);
+        };
+
+        ~MgbusModuleWithHttp() override = default;
+
+    protected:
+        QASyncHttpServer mHttpServer;
+        QCMDnsClient     cmdns_client_;
+
+        void prepareService(const qlibc::QData &config) override {
+            //消息转发调试服务,可模拟向自己或其它指定模块发送mgbus消息
+#ifdef DEBUG
+            DefineMgbusService("@i", ECSInvokeService, config);
+#endif
+            MgBusHolder::prepareService(config);
+        }
+
+    public:
+        declareHttpUriHandlers(mHttpServer);
+
+        void doServerShutdown() override {
+            mHttpServer.shutdown();
+        }
+
+        virtual int defaultHttpPort() = 0;
+
+        bool doServerStart(const qlibc::QData& config) override {
+            int http_port = runData_.getInt("http_port", defaultHttpPort());
+
+            if(http_port<1) {
+                QErr("Invalid http server port: %d .", http_port);
+                return false;
+            }
+
+            if(!mHttpServer.start(http_port)){
+                QErr("Bind http server on %d failed.", http_port);
+                return false;
+            }
+
+            //@mg.module.service 标志开头的默认全部转发
+            bindMgBusTransfer(mHttpServer);
+
+            return true;
+        }
+    };
+
+    class JE_API MgbusModuleWithSocket : public QMgbusModule {
+    public:
+        explicit MgbusModuleWithSocket(const qlibc::QData& initConfig, const std::string& modulename, SocketMode sockType = typeUDP)
+                : QMgbusModule(initConfig, modulename, sockType), mSockServer(*this) {
+            markDataChannel(DATA_CHANNEL_SOCK, mSockServer);
+        };
+
+        ~MgbusModuleWithSocket() override = default;
+
+    protected:
+        QNodeServer      mSockServer;
+
+    public:
+        void prepareService(const qlibc::QData &config) override {
+            //可向指定的node发送消息,消息处理接口,响应来自mgbus或http的的mm请求
+            DefineMgbusServiceWithInitFieldObj("mm", MgNodeManagerService, config, mSockServer);
+            MgBusHolder::prepareService(config);
+        }
+
+        void doServerShutdown() override {
+            mSockServer.shutdown();
+        }
+
+        virtual int defaultSocketPort()  = 0;
+
+        bool doServerStart(const qlibc::QData& data) override {
+            int ms_port = runData_.getInt("sc_port", defaultSocketPort());
+            if(ms_port<1){
+                QErr("Invalid socket server port: %d .", ms_port);
+                return false;
+            }
+
+            std::string sockType = runData_.getString("sc_type", "tcp");
+            if(!mSockServer.start(runData_, ms_port, sockType=="udp"?typeUDP:typeTCP)){
+                QErr("Fail to start socket Server on port : %d.", ms_port);
+                return false;
+            }
+            return true;
+        }
+    };
+
+    class JE_API MgbusModuleMix : public QMgbusModule {
+    protected:
+        QASyncHttpServer mHttpServer;
+        QNodeServer      mSockServer;
+
+    public:
+        declareHttpUriHandlers(mHttpServer);
+
+        explicit MgbusModuleMix(const qlibc::QData& initConfig, const std::string& modulename)
+                : QMgbusModule(initConfig, modulename), mHttpServer(*this), mSockServer(*this) {
+            markDataChannel(DATA_CHANNEL_SOCK, mSockServer);
+            markDataChannel(DATA_CHANNEL_HTTP, mHttpServer);
+            //Http的消息推送,该从本地的Socket发起
+            mHttpServer.setASyncPostHandler([this](ChannelOperator& opr, qlibc::QData &response)->bool {
+                return mSockServer.postRawMessage(response);
+            });
+        };
+
+        ~MgbusModuleMix() override = default;
+
+        void prepareService(const qlibc::QData &config) override {
+            //消息转发调试服务,可模拟向自己或其它指定模块发送mgbus消息
+#ifdef DEBUG
+            DefineMgbusService("@i", ECSInvokeService, config);
+#endif
+            //可向指定的node发送消息,消息处理接口,响应来自mgbus或http的的mm请求
+            DefineMgbusServiceWithInitFieldObj("mm", MgNodeManagerService, config, mSockServer);
+            MgBusHolder::prepareService(config);
+        }
+
+        virtual int defaultHttpPort() = 0;
+
+        virtual int defaultSocketPort() = 0;
+
+        void doServerShutdown() override {
+            mHttpServer.shutdown();
+            mSockServer.shutdown();
+        }
+
+        bool doServerStart(const qlibc::QData& config) override {
+            int http_port = runData_.getInt("http_port", defaultHttpPort());
+            if(http_port<1) {
+                QErr("Invalid http server port: %d .", http_port);
+                return false;
+            }
+            if(!mHttpServer.start(http_port)) {
+                QErr("Bind http server on %d failed.", http_port);
+                return false;
+            }
+            //@mg.module.service 标志开头的默认全部转发
+            bindMgBusTransfer(mHttpServer);
+
+            int ms_port = runData_.getInt("sc_port", defaultSocketPort());
+            if(ms_port<1){
+                QErr("Invalid socket server port: %d .", ms_port);
+                mHttpServer.shutdown(); //停止已启动的http服务器
+                return false;
+            }
+
+            std::string sockType = runData_.getString("sc_type", "udp");
+            if(!mSockServer.start(runData_, ms_port, sockType=="udp"?typeUDP:typeTCP)){
+                QErr("Fail to start socket Server on port : %d.", ms_port);
+                mHttpServer.shutdown(); //停止已启动的http服务器
+                return false;
+            }
+            return true;
+        }
+    };
+
+
+    //MgbusModuleWithSocketClient
+
+
+    //MgbusModuleWithMqttClient
+
+
+    //MgbusModuleWithMixClient
+}
+
+#endif //INC_0_LIBDEVCPP_QEXMGBUSSERVER_H

+ 260 - 0
app/src/main/cpp/inc/exlib/QJAExObjects.h

@@ -0,0 +1,260 @@
+//
+// Created by Ht on 2021/11/29.
+//
+
+#ifndef INC_0_LIBDEVCPP_QJAEXOBJECTS_H
+#define INC_0_LIBDEVCPP_QJAEXOBJECTS_H
+
+#include <jadom2/JAIndexedDom.h>
+#include <exlib/sock/QNodeServer.h>
+#include <exlib/sock/QSockClient.h>
+#include <exlib/http/QHttpSSLClient.h>
+#include <exlib/http/QASyncHttpServer.h>
+#include <exlib/QMqttClient.h>
+#include <mgbus/QMgbusModule.h>
+#include <exlib/QJAService.h>
+#include <exlib/sock/QNodeClient.h>
+#include <exlib/QJAMgUtils.h>
+
+namespace jedge {
+
+    static const char* sval_cls_name_mqtt_client = "mqttClient";
+    static const char* sval_cls_name_http_client = "httpClient";
+    static const char* sval_cls_name_https_client = "httpSSLClient";
+    static const char* sval_cls_name_socket_client = "socketClient";
+    static const char* sval_cls_name_http_server = "httpServer";
+    static const char* sval_cls_name_socket_server = "socketServer";
+
+    class JAHttpSSLClient : public ja::JAObject ,
+                            public UriHandlerHolder {
+    protected:
+        jedge::QHttpSSLClient*  mClient;
+
+    public:
+        explicit JAHttpSSLClient(ja::JAContext& ctx, const qlibc::QData &data):
+                JAObject(ctx, data, sval_cls_name_https_client),
+                UriHandlerHolder(dynamic_cast<ChannelOperator&>(ctx)) {
+        }
+
+        ~JAHttpSSLClient() override;
+
+        jedge::QHttpSSLClient* getClient() {
+            return mClient;
+        }
+
+        //obj.handler /abc/uri ja_block
+        bool handler(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //httpClient.post 'https://192.168.1.193:8080/sbrbusy/' $${result} ${msg} 3000(timeout)
+        bool post(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //httpClient.async_post 'https://192.168.1.193:8080/sbrbusy/' ${msg} 3000(timeout)
+        bool aspost(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //httpClient.get 'https://192.168.1.193:8080/sbrbusy/' $${result} ${msg} 3000(timeout)
+        bool get(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //httpClient.file 'https://192.168.1.193:8080/juras/' localPath(<data-cache-dir>/http/<localPath>
+        bool file(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //${@httpClient.req:https://192.168.1.193:8080/juras/panel/check,${msg},3000(timeout),k=v,k2=v2,...}
+        bool funcPost(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //${@httpClient.get:https://192.168.1.193:8080/juras/panel/check,k=v,k2=v2,...}
+        bool funcGet(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+    };
+
+    class JAHttpClient : public ja::JAObject ,
+                         public UriHandlerHolder {
+    protected:
+        jedge::QHttpClient*  mClient;
+
+    public:
+        explicit JAHttpClient(ja::JAContext& ctx, const qlibc::QData &data);
+
+        ~JAHttpClient() override;
+
+        jedge::QHttpClient* getClient() {
+            return mClient;
+        }
+
+        //obj.handler /abc/uri ja_block
+        bool handler(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //httpClient.post 'http://192.168.1.193:8080/sbrbusy/' $${result} ${msg} 3000(timeout)
+        bool post(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //httpClient.async_post 'http://192.168.1.193:8080/sbrbusy/' ${msg} 3000(timeout)
+        bool aspost(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //httpClient.get 'http://192.168.1.193:8080/sbrbusy/' $${result} ${msg} 3000(timeout)
+        bool get(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //httpClient.file 'http://192.168.1.193:8080/juras/' localPat h(<data-cache-dir>/http/<localPath>
+        bool file(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //${@httpClient.req:http://192.168.1.193:8080/juras/panel/check,${msg},3000(timeout),k=v,k2=v2,...}
+        bool funcPost(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //${@httpClient.get:http://192.168.1.193:8080/juras/panel/check,k=v,k2=v2,...}
+        bool funcGet(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+    };
+
+    class JAMqttClient : public ja::JAObject ,
+                         public UriHandlerHolder {
+    protected:
+        jedge::QMqttClient*         mqttClient = nullptr;
+        jedge::QMqttMessageDeliver* deliver = nullptr;
+        std::string                 default_post_topic_;
+    public:
+        explicit JAMqttClient(ja::JAContext& ctx, const qlibc::QData &data);
+
+        ~JAMqttClient() override;
+
+        jedge::QMqttClient* getClient() {
+            return mqttClient;
+        }
+
+        //connect host clientid --port <port> --username uid --password pid
+        bool connect(qlibc::JCArgNode &param, qlibc::QData *result);
+
+        bool disconnect(qlibc::JCArgNode &param, qlibc::QData *result);
+
+        bool isConnected(qlibc::JCArgNode &param, qlibc::QData *result);
+
+        // subscribe topic
+        bool subscribe(qlibc::JCArgNode &param, qlibc::QData *result);
+
+        // unsubscribe topic
+        bool unsubscribe(qlibc::JCArgNode &param, qlibc::QData *result);
+
+        // publish topic  ${message} [qos] --key value ...
+        bool publish(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //  publish uri $${result} ${message}  --key value ...
+        bool publishReq(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        bool returnTopic(qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //obj.handler /abc/uri ja_block
+        bool handler(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+
+        //DirectCall
+        bool directPublish(const std::string& topic, const std::string& content);
+        bool directSubscribe(const std::string& topic);
+        bool directUnsubscribe(const std::string& topic);
+    };
+
+
+    class JASocketClient : public ja::JAObject {
+    protected:
+        jedge::QSockClient *mClient = nullptr;
+        bool keep_:1;
+        bool login_:1;
+
+    public:
+        explicit JASocketClient(ja::JAContext& ctx, const qlibc::QData &data);
+
+        ~JASocketClient() override;
+
+        jedge::QSockClient* getClient() {
+            return mClient;
+        }
+
+        //sclt.connect 192.168.1.30 6013 tcp --keep
+        bool connect(qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //client.handler /usi/bbb  ja_block
+        bool handler(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //client.req uri $${result} ${msg} to params...
+        bool req(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //client.msg uri ${msg} params...
+        bool msg(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        bool login(qlibc::JCArgNode &param, qlibc::QData *result);
+
+        bool close(qlibc::JCArgNode &param, qlibc::QData *result);
+
+        bool isActive();
+
+        bool isLogin();
+    };
+
+    class JASocketServer : public ja::JAObject {
+    protected:
+        jedge::QNodeServer*      mSockServer = nullptr;
+
+    public:
+        explicit JASocketServer(ja::JAContext& ctx, const qlibc::QData &data);
+
+        ~JASocketServer() override;
+
+        //
+        bool start(qlibc::JCArgNode &param, qlibc::QData *result);
+
+        bool shutdown(qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //clientMsg clientId ${msg} --key value
+        bool clientMsg(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //getClientList $${resp}
+        bool getClientList(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //clientReq clientId uri $${resp} ${msg} --key value
+        bool clientReq(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //添加一个uri的handler, param的第一个参数微返回对象
+        //obj.handler /uri/uri  block / current:api
+        bool handler(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        bool isActive();
+
+        jedge::QNodeServer* getServer();
+    };
+
+    class JAHttpServer : public ja::JAObject {
+    protected:
+        jedge::QASyncHttpServer*      mHttpServer = nullptr;
+
+    public:
+        explicit JAHttpServer(ja::JAContext& ctx,const qlibc::QData &data);
+
+        ~JAHttpServer() override;
+
+        //添加一个uri的handler, param的第一个参数微返回对象
+        //obj.handler /uri/uri  script/file:entry  [channel(default:msg)] entry
+        bool handler(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //添加start
+        //obj.start 30000 <subnet>
+        bool start(qlibc::JCArgNode &param, qlibc::QData *result);
+
+        //添加shutdown
+        //obj.shutdown
+        bool shutdown(qlibc::JCArgNode &param, qlibc::QData *result);
+
+        bool isActive();
+
+        jedge::QASyncHttpServer* getServer();
+
+        //缓存一个可访问的文件
+        //obj.cacheFile <filePath>
+        bool cacheFile(ja::JAStack &s, qlibc::JCArgNode &param, QData *result);
+
+        //设置http服务的基础文件目录
+        //obj.setBase <filePath>
+        bool setWWWBase(ja::JAStack &s, qlibc::JCArgNode &param, QData *result);
+
+    };
+
+    class JE_API QJAExObjectUtils {
+    public:
+        static void loadExObjects(QJAMgServer& server, ja::JARClassObject &cls);
+    };
+}
+
+
+#endif //INC_0_LIBDEVCPP_QJAEXOBJECTS_H

+ 21 - 0
app/src/main/cpp/inc/exlib/QJAExtModuleBase.h

@@ -0,0 +1,21 @@
+//
+// Created by Ht on 2022/12/3.
+//
+
+#ifndef INC_1_LIBDEVCPP_QJAEXTMODULEBASE_H
+#define INC_1_LIBDEVCPP_QJAEXTMODULEBASE_H
+
+#include "QJAServer.h"
+
+namespace jedge {
+
+    class JE_API QJAExtModuleBase :
+            public QJAMgServer {
+    public:
+        explicit QJAExtModuleBase(qlibc::QData& cfg, const std::string& appName) :
+            QJAMgServer(cfg, rebuildMgbusConfig(cfg, appName), cfg.getString("sc_type")!="tcp"?typeUDP:typeTCP) {
+        }
+    };
+}
+
+#endif //INC_1_LIBDEVCPP_QJAEXTMODULEBASE_H

+ 45 - 0
app/src/main/cpp/inc/exlib/QJAMgUtils.h

@@ -0,0 +1,45 @@
+//
+// Created by Ht on 2021/12/19.
+//
+
+#ifndef INC_0_LIBDEVCPP_QJAMGUTILS_H
+#define INC_0_LIBDEVCPP_QJAMGUTILS_H
+
+
+#include <qlibc/QData.hpp>
+#include <qlibc/QPObjectHolder.h>
+#include <mgbus/ChannelOperator.h>
+
+namespace jedge {
+    using UriMessageHandler = std::function<bool(jedge::ChannelOperator &o, const std::string &u,
+                                                 qlibc::QData &m)>;
+
+    class UriHandlerHolder {
+    protected:
+        ChannelOperator &opr_;
+        qlibc::QSharedObjectHolder<UriMessageHandler> ud_handlers_;
+
+    public:
+        explicit UriHandlerHolder(ChannelOperator &o) : opr_(o) {}
+
+        void releaseUdHandlers() {
+            ud_handlers_.releaseAll();
+        }
+
+        void addHandler(const std::string &uri, const UriMessageHandler &handler) {
+            ud_handlers_.appendNew(uri, new UriMessageHandler(handler));
+        }
+
+        bool handleMessage(const std::string &uri, qlibc::QData &message) {
+            auto handler = ud_handlers_.findObject(uri);
+            if (handler != nullptr) {
+                try {
+                    return handler->operator()(opr_, uri, message);
+                } catch (std::bad_function_call &e) {}
+            }
+            return false;
+        }
+    };
+}
+
+#endif //INC_0_LIBDEVCPP_QJAMGUTILS_H

+ 131 - 0
app/src/main/cpp/inc/exlib/QJAServer.h

@@ -0,0 +1,131 @@
+//
+// Created by Ht on 2022/1/8.
+//
+
+#ifndef INC_0_LIBDEVCPP_QJASERVER_H
+#define INC_0_LIBDEVCPP_QJASERVER_H
+
+#include <mgbus/QMgbusModule.h>
+#include <qlibc/plugin/QPluginManager.h>
+#include <jadom2/JAIndexedDom.h>
+
+namespace jedge {
+
+    class JE_API QJAMgServer :
+        public ja::JAIndexNodeContext,
+        public QMgbusModule {
+    protected:
+        class QTimeOutObjNode {
+        public:
+            explicit QTimeOutObjNode(JAObjectOwner &owner, JAObject *obj) :
+                    owner_(owner), obj_(obj) {
+            }
+            JAObjectOwner&          owner_;
+            JAObject*               obj_;
+        };
+
+        std::vector<QTimeOutObjNode*>* tobjs_ = nullptr;
+        qlibc::QRTimer               timeout_cleaner_;
+        std::mutex                  clean_mutex_;
+        std::string                 target_service_;
+
+        qlibc::QPluginManager*      plugin_mgr_ = nullptr;
+
+        std::string                 pre_command_;
+
+        void loadPluginClassDefs();
+        void loadAllPluginServices();
+
+    public:
+        explicit QJAMgServer(const qlibc::QData &initConfig, const std::string &name, SocketMode mode = jedge::typeUDP);
+
+        ~QJAMgServer() override;
+
+        bool start(const qlibc::QData &config) override;
+
+        void shutdown() override;
+
+        virtual void prepareJsonActionContext(const qlibc::QData &config) {};
+
+        virtual void clearJsonActionContext();
+
+        void setServerConfig(std::string &result, const std::string &key, const Json::Value &val) override;
+
+        void appendTimeoutObject(JAObjectOwner& owner, JAObject* objKey);
+
+        void clearTimeoutObject(JAObject* obj);
+
+        bool appendUserService (const std::string &key, const qlibc::QData &config, MgService* service) override;
+
+    protected:
+        public:
+        bool prepareContext(const qlibc::QData& data) override;
+
+        protected:
+        void loadInnerClasses() override;
+
+        void removeTimeoutObjects();
+        bool runServerScript(const std::string& event, qlibc::QData& param);
+
+        void stopTimeoutCleaner();
+
+        void prepareInnerObjects() override;
+
+    public:
+        qlibc::QRTimerEngine getTimerEngine() override;
+
+        httplib::RThreadPool getThreadPoolRef() override;
+
+        qlibc::QRTriggerEngine getTriggerEngine() override;
+
+        bool resetTarget(qlibc::JCArgNode &p);
+
+        bool runJAScriptFromCommand(qlibc::JCArgNode &p);
+
+        bool mgbus(qlibc::JCArgNode &param, qlibc::QData* re);
+
+        bool MgbusVersion(qlibc::JCArgNode &param, qlibc::QData* re);
+
+        bool pre_command(qlibc::JCArgNode &param, qlibc::QData* re);
+
+        bool ping(qlibc::JCArgNode &param, qlibc::QData* re);
+
+        virtual bool makeJedgeRequestPost(qlibc::JCArgNode &param, qlibc::QData* re, ja::JAStack* s);
+
+        virtual bool makeJedgeMessagePost(qlibc::JCArgNode &param, qlibc::QData* re, ja::JAStack* s);
+
+        bool findMgbusHosts(qlibc::JCArgNode &param, qlibc::QData* re);
+
+        bool listMgbusClients(qlibc::JCArgNode &param, qlibc::QData* re);
+
+        bool gather(qlibc::JCArgNode &param, qlibc::QData* re);
+
+        bool ShowSocketIOLog(qlibc::JCArgNode &param, qlibc::QData* re);
+
+        bool listOnlineMgbusNodeSn(qlibc::JCArgNode &param, qlibc::QData* re);
+
+        bool getContextName(qlibc::JCArgNode &param, qlibc::QData* re);
+
+        bool showPool(qlibc::JCArgNode &param, qlibc::QData* re);
+
+        bool getModuleAddress(qlibc::JCArgNode &param, qlibc::QData* re);
+
+        bool handleJsonActionFiles(qlibc::JCArgNode &param, qlibc::QData* re);
+
+        void releasePluginClassDefs();
+
+        static std::string defaultFilePath(const qlibc::QData &cfg, const std::string &name);
+    };
+
+#define MgServer(opr)\
+    (dynamic_cast<jedge::QJAMgServer&>(opr))
+
+#define PQJAMgServer(opr)\
+    auto* opr = (dynamic_cast<jedge::QJAMgServer*>(&operator_))
+
+#define IsAMgServer(opr) \
+    (dynamic_cast<jedge::QJAMgServer*>(&(opr)) !=nullptr)
+
+}
+
+#endif //INC_0_LIBDEVCPP_QJASERVER_H

+ 337 - 0
app/src/main/cpp/inc/exlib/QJAService.h

@@ -0,0 +1,337 @@
+//
+// Created by Ht on 2021/4/30.
+//
+
+#ifndef INC_0_LIBDEVCPP_QJSONACTIONSERVICE_H
+#define INC_0_LIBDEVCPP_QJSONACTIONSERVICE_H
+
+#include "QJAServer.h"
+
+#include <mgbus/MgBusService.h>
+
+namespace jedge {
+
+    static const char* sval_ja_service_def_ = "jaservice.json";
+
+    static const char* sval_cls_name_bind = "bind";
+    static const char* vkey_mqtt_topic_store_ = "~t";
+
+    class JE_API QJAMgService :
+            public MgBusService ,
+            public ja::JAIndexedInstance {
+    protected:
+        ja::JAHandlerDocker* dynamic_handler_ = nullptr;
+    public:
+        explicit QJAMgService(jedge::QJAMgServer& opr, const std::string &name, const qlibc::QData &config);
+
+        ~QJAMgService() override;
+
+    protected:
+        inline QJAMgServer& getContextServer() {
+            return *dynamic_cast<QJAMgServer*>(&operator_);
+        }
+
+        void beforeObjectErase(JAObject *object) override;
+
+        ja::JAHandlerDocker *getScriptDocker();
+
+    public:
+        void reloadServiceJsonAction(const std::string& keylist = ja::vkey_default_ja_script_channel_keys) override;
+
+        void onConfigDataUpdated(const std::string &cfgFileName) override;
+
+        void preparePattern() override;
+        virtual void prepareJAServicePattern();
+
+        virtual bool jaMessageCall(qlibc::QData &msg, qlibc::QData *rsp);
+        bool printJAHandler(qlibc::QData &msg, qlibc::QData *rsp);
+
+        virtual bool loadServiceJAClasses() { return true;};
+
+        bool prepareInstance() override;
+
+        virtual bool start(const qlibc::QData& param) {
+            runScript("start", param);
+            return true;
+        }
+
+        bool runScript(const char *uri, const qlibc::QData& param);
+
+        bool runScript(const char *uri);
+
+        void createDefaultJAFile(const string &scriptFn) override;
+
+        virtual void shutdown() {
+            runScript("shutdown");
+            clearAllObjectRefs();
+            clearStacks();
+        }
+
+        virtual bool DefineWatcherHandler(OnModuleConnected, w, k, m) {
+            runScript("OnModuleConnected");
+            return true;
+        }
+
+        virtual bool DefineWatcherHandler(OnModuleDisconnected, w, k, m) {
+            runScript("OnModuleDisconnected");
+            return true;
+        }
+
+        void onServiceStart(const qlibc::QData &config) override;
+
+        bool watchMgEvent(ja::JAStack& stack, qlibc::JCArgNode &param, QData *re);
+
+        bool unwatchMgEvent(ja::JAStack& stack, qlibc::JCArgNode &param, QData *re);
+
+        bool trigMgEvent(ja::JAStack& stack, qlibc::JCArgNode &param, QData *re);
+
+//        bool queryServiceHandlers(qlibc::JCArgNode &node, QData *rsp);
+        void releaseServiceResources();
+
+    };
+
+#define  DefineJAService(name_str, service_class, config) \
+    {appendService((name_str), (config).getData((name_str)), [this](jedge::MgBusHolder& opr, const std::string& name, const qlibc::QData& service_cfg)->jedge::MgBusService* {   \
+        return new service_class(*this, name, service_cfg);   \
+    }); \
+    auto* service##config = dynamic_cast<jedge::QJAMgService*>(findService((name_str))); \
+    if(service##config!=nullptr){ ObjectRef((name_str), *service##config); }}
+
+#define  DefineJAServiceForServer(_s,name_str, service_class,_config) \
+    {(_s).appendService((name_str), (_config).getData((name_str)), [&_s](jedge::MgBusHolder& opr, const std::string& name, const qlibc::QData& service_cfg)->jedge::MgBusService* {   \
+        return new service_class(_s, name, service_cfg);   \
+    }); \
+    auto* service##_config = dynamic_cast<jedge::QJAMgService*>((_s).findService((name_str))); \
+    if(service##_config!=nullptr){ (_s).ObjectRef((name_str), *service##_config); }}
+}
+
+#define JAMgUDClassMethodFastCall(var, pobj, objcls,func) \
+    qlibc::JCArgNode param;\
+    JCArgUtil::handleArgs(sp, param);\
+    auto rsp = s.findObject("rsp"); \
+    qlibc::QData *result = (rsp==nullptr)?(var).getBlankMessage() : rsp.get();\
+    auto* cls_obj = dynamic_cast<objcls*>(pobj); \
+    if(cls_obj==nullptr) return false;\
+    auto ok = cls_obj->func(param, result);\
+    clearJedgeCallInfo(*result);\
+    if(rsp==nullptr) (var).releaseMessage(result); \
+    return ok
+
+#define JAMgUDClassMethodFastCallWithStack(server, pobj, stack, objcls, func) \
+    qlibc::JCArgNode param;\
+    JCArgUtil::handleArgs(sp, param);\
+    auto rsp = (stack).findObject("rsp"); \
+    qlibc::QData *result = (rsp==nullptr)?(server).getBlankMessage() : rsp.get();\
+    auto* cls_obj = dynamic_cast<objcls*>(pobj); \
+    if(cls_obj==nullptr) return false;\
+    auto ok = cls_obj->func(stack, param, result);\
+    clearJedgeCallInfo(*result);\
+    if(rsp==nullptr) (server).releaseMessage(result); \
+    return ok
+
+#define JAMgUDServerMethodFastCall(func) \
+    qlibc::JCArgNode param;\
+    JCArgUtil::handleArgs(sp, param);\
+    auto rsp = s.findObject("rsp"); \
+    qlibc::QData *result = (rsp==nullptr)?getBlankMessage() : rsp.get();\
+    auto ok = func(param, result);\
+    clearJedgeCallInfo(*result);\
+    if(rsp==nullptr) releaseMessage(result); \
+    return ok
+
+#define JAMgUDClassFuncFastCall(var,objcls,func) \
+    qlibc::JCArgNode param;\
+    JCArgUtil::handleArgs(slp, param);\
+    auto *result = (var).getBlankMessage(); \
+    auto *cls_obj = dynamic_cast<objcls*>(&o); \
+    if (cls_obj == nullptr) return false; \
+    auto ok = cls_obj->func(param, result); \
+    (*result).removeKey(jedge::JEDGE_MGCALL_PREFIX_HEAD); \
+    if(ok && result->containsKey(ja::ja_return_val_)) { \
+        const auto& r = result->asValueConst().operator[](ja::ja_return_val_); \
+        if(r.isObject() || r.isArray()) { s.setJsonValueRef(r,sr,true); }      \
+        else { StringUtils::valueToJsonString(r,sr);} } \
+    else { sr = ja::ja_object_val_null_; }\
+    (var).releaseMessage(result); \
+    return ok;
+
+#define JAUDS_DEFINE_SERVER_METHOD_WITH_STACK(cls, name, function) \
+    cls->Method(name, [this]JAMethodConst(s, o, qm, sp) { \
+                qlibc::JCArgNode param; \
+                JCArgUtil::handleArgs(sp, param); \
+                auto rsp = (s).findObject("rsp"); \
+                qlibc::QData *result = (rsp == nullptr) ? (*this).getBlankMessage() : rsp.get(); \
+                auto ok = function(param, result, &s); \
+                clearJedgeCallInfo(*result); \
+                if (rsp == nullptr)(*this).releaseMessage(result); \
+                return ok;\
+    })
+
+#define JAMgUDClassFuncFastCallWithStack(var,s,objcls,func) \
+    qlibc::JCArgNode param;\
+    JCArgUtil::handleArgs(slp, param);\
+    auto *result = (var).getBlankMessage(); \
+    auto *cls_obj = dynamic_cast<objcls*>(&o); \
+    if (cls_obj == nullptr) return false; \
+    auto ok = cls_obj->func(s, param, result); \
+    (*result).removeKey(jedge::JEDGE_MGCALL_PREFIX_HEAD); \
+    if(ok && result->containsKey(ja::ja_return_val_)) { \
+        const auto& r = result->asValueConst().operator[](ja::ja_return_val_); \
+        if(r.isObject() || r.isArray()) { s.setJsonValueRef(r,sr,true); }      \
+        else { StringUtils::valueToJsonString(r,sr);} } \
+    else { sr = ja::ja_object_val_null_; }\
+    (var).releaseMessage(result); \
+    return ok;
+
+#define JAUDS_DEFINE_SERVER_METHOD(cls, name, function) \
+    cls->Method(name, [this]JAMethodConst(s, o, qm, sp) { \
+        JAMgUDServerMethodFastCall(function); \
+    })
+
+#define JAUDS_SERVER_METHOD(cls, function) \
+    cls->Method(#function, [this]JAMethodConst(s, o, qm, sp) { \
+        JAMgUDServerMethodFastCall(function); \
+    })
+
+#define JAUDS_DEFINE_CLASS_HANDLER(cls, objcls, function) \
+    cls->Method(#function, []JAMethodConst(s, o, qm, sp) { \
+        qlibc::JCArgNode param; \
+        JCArgUtil::handleArgs(sp, param); \
+        auto* obj = dynamic_cast<objcls*>(&o); \
+        if(obj!=nullptr) { \
+            obj->function(s, param); \
+        }\
+        return true;\
+    })
+
+#define JAUDS_DEFINE_CLASS_METHOD(server, cls, objcls, function) \
+    cls->Method(#function, [&server]JAMethodConst(s, o, qm, sp) { \
+        JAMgUDClassMethodFastCall(server, &o, objcls, function); \
+    })
+
+#define JAUDS_DEFINE_CLASS_FUNCTION(server, cls, objcls, function) \
+    cls->Func(#function, [&server]JAFuncConst(s, o, sr, slp) { \
+        JAMgUDClassFuncFastCall(server,objcls, function); \
+    })
+
+#define JAUDS_KEY_DEFINE_CLASS_FUNCTION(key, server, cls, objcls, function) \
+    cls->Func((key), [&server]JAFuncConst(s, o, sr, slp) { \
+        JAMgUDClassFuncFastCall(server,objcls, function); \
+    })
+
+#define JAUDS_DEFINE_CLASS_METHOD_WITH_STACK(server, cls, objcls, function) \
+    cls->Method(#function, [&server]JAMethodConst(s, o, qm, sp) { \
+        JAMgUDClassMethodFastCallWithStack(server, &o, s, objcls, function); \
+    })
+
+#define JAUDS_DEFINE_CLASS_FUNCTION_WITH_STACK(server, cls, objcls, function) \
+    cls->Func(#function, [&server]JAFuncConst(s, o, sr, slp) { \
+        JAMgUDClassFuncFastCallWithStack(server,s, objcls, function); \
+    })
+
+
+#define JAUDS_KEY_DEFINE_CLASS_FUNCTION_WITH_STACK(key, server, cls, objcls, function) \
+    cls->Func((key), [&server]JAFuncConst(s, o, sr, slp) { \
+        JAMgUDClassFuncFastCallWithStack(server,s, objcls, function); \
+    })
+
+
+#define DefineUserModeCommand(rcls,mod, func)\
+    DefCmdCallback(func, s, p, rcls, mod) { \
+        p.removeParamAt(nullptr, 0);\
+        return s.func(p, nullptr);\
+    }
+
+    /**
+     *
+     */
+#define bindJAServiceRunnerCallBackTable_Begin(rcls,mod) \
+    DefCmdCallback(__##rcls##_ServiceTarget, s, p, rcls, mod) { \
+        return s.resetTarget(p);\
+    } \
+    DefCmdCallback(__##rcls##_ServerDeviceCommand, s, p, rcls, mod) { \
+        return s.runJAScriptFromCommand(p);\
+    } \
+    DefCmdCallback(__##rcls##_mgbus, s, p, rcls, mod) { \
+        p.removeParamAt(nullptr, 0);\
+        return s.mgbus(p, nullptr);\
+    } \
+    DefCmdCallback(__##rcls##_mgver, s, p, rcls, mod) { \
+        p.removeParamAt(nullptr, 0);\
+        return s.MgbusVersion(p, nullptr);\
+    } \
+    DefCmdCallback(__##rcls##_pre, s, p, rcls, mod) { \
+        p.removeParamAt(nullptr, 0);\
+        return s.pre_command(p, nullptr);\
+    } \
+    DefCmdCallback(__##rcls##_ShowSocketIOLog, s, p, rcls, mod) { \
+        p.removeParamAt(nullptr, 0);\
+        return s.ShowSocketIOLog(p, nullptr);\
+    } \
+    DefCmdCallback(__##rcls##_ping, s, p, rcls, mod) { \
+        p.removeParamAt(nullptr, 0);\
+        return s.ping(p, nullptr);\
+    } \
+    DefCmdCallback(__##rcls##_makeJedgeRequestPost, s, p, rcls, mod) { \
+        p.removeParamAt(nullptr, 0);\
+        return s.makeJedgeRequestPost(p, nullptr, nullptr);\
+    } \
+    DefCmdCallback(__##rcls##_findMgbusHosts, s, p, rcls, mod) { \
+        p.removeParamAt(nullptr, 0);\
+        return s.findMgbusHosts(p, nullptr);\
+    } \
+    DefCmdCallback(__##rcls##_makeJedgeMessagePost, s, p, rcls, mod) { \
+        p.removeParamAt(nullptr, 0);\
+        return s.makeJedgeMessagePost(p, nullptr, nullptr);\
+    } \
+    DefCmdCallback(__##rcls##_handleJsonActionFiles, s, p, rcls, mod) { \
+        p.removeParamAt(nullptr, 0);\
+        return s.handleJsonActionFiles(p, nullptr);\
+    } \
+    DefCmdCallback(__##rcls##_listMgbusClients, s, p, rcls, mod) { \
+        p.removeParamAt(nullptr, 0);\
+        return s.listMgbusClients(p, nullptr);\
+    } \
+    DefCmdCallback(__##rcls##_listOnlineMgbusNodeSn, s, p, rcls, mod) { \
+        p.removeParamAt(nullptr, 0);\
+        return s.listOnlineMgbusNodeSn(p, nullptr);\
+    } \
+    DefCmdCallback(__##rcls##_gather, s, p, rcls, mod) { \
+        p.removeParamAt(nullptr, 0);\
+        return s.gather(p, nullptr);\
+    } \
+    DefCmdCallback(__##rcls##_showPool, s, p, rcls, mod) { \
+        p.removeParamAt(nullptr, 0);\
+        return s.showPool(p, nullptr);\
+    } \
+    DefCmdCallback(__##rcls##_getContextName, s, p, rcls, mod) { \
+        p.removeParamAt(nullptr, 0);\
+        return s.getContextName(p, nullptr);\
+    } \
+    DefCmdCallback(__##rcls##_getModuleAddress, s, p, rcls, mod) { \
+        p.removeParamAt(nullptr, 0);\
+        return s.getModuleAddress(p, nullptr);\
+    } \
+    bindServiceRunnerCallbackTable_Begin(rcls)\
+        RegisterFunctionCommandWithHelp("c,t,ja", __##rcls##_ServerDeviceCommand, "Server back-end control command. e.g. >> run hongmei.info");\
+        RegisterFunctionCommandWithHelp("find", __##rcls##_findMgbusHosts, "Find mgbus host on net by cmdns. e.g. : >>find [target [subnet [3 (continuous secs)]]]");\
+        RegisterFunctionCommandWithHelp("svc", __##rcls##_ServiceTarget, "Set local command target. e.g. : >>svc gaffic");\
+        RegisterFunctionCommandWithHelp("sockio", __##rcls##_ShowSocketIOLog, "show socket io message. e.g. : >>sockio on/off");\
+        RegisterFunctionCommandWithHelp("name,who", __##rcls##_getContextName, "Show local name on mgbus. e.g. : >>svc gaffic");\
+        RegisterFunctionCommandWithHelp("addr", __##rcls##_getModuleAddress, "Show local socket address on mgbus. e.g. : >>svc gaffic");\
+        RegisterFunctionCommandWithHelp("host,mgbus", __##rcls##_mgbus, "reset mgbus address, and restart, then reconnect to new host. e.g. >> host/mgserver 192.168.1.193 8877; restart");\
+        RegisterFunctionCommandWithHelp("opool", __##rcls##_showPool, "reset mgbus address, and restart, then reconnect to new host. e.g. >> host/mgserver 192.168.1.193 8877; restart");\
+        RegisterFunctionCommandWithHelp("g,pre", __##rcls##_pre, "设置重复命令:e.g. g|pre -s \"req vui /media/playMusic --text \" :设置重复命令,g|pre -w :显示重复命令, g|pre -c:清空重复命令, g|pre params 以重复命令执行");\
+        RegisterFunctionCommandWithHelp("mgver", __##rcls##_mgver, "show version of current mgbus app base libs");\
+        RegisterFunctionCommandWithHelp("ping", __##rcls##_ping, "exec req mod @c/ping ");\
+        RegisterFunctionCommandWithHelp("req", __##rcls##_makeJedgeRequestPost, "send a mgbus request");\
+        RegisterFunctionCommandWithHelp("msg", __##rcls##_makeJedgeMessagePost, "send a mgbus message");\
+        RegisterFunctionCommandWithHelp("sc,scripts", __##rcls##_handleJsonActionFiles, "list available json action script files. e.g. : >>sc vdal/vdalTest.json");\
+        RegisterFunctionCommandWithHelp("ln", __##rcls##_listMgbusClients, "list nodes of mgbus, e.g. ln / ln -a / ln --host node");\
+        RegisterFunctionCommandWithHelp("gather", __##rcls##_gather, "instantly clean objects galleries.");\
+        RegisterFunctionCommandWithHelp("ldsn", __##rcls##_listOnlineMgbusNodeSn, "list sn of mgbus nods, e.g. ldsn");
+
+#define bindJAServiceRunnerCallBackTable_End(rcls,mod) bindCallbackTable_End(rcls)
+
+
+#endif //INC_0_LIBDEVCPP_JSONACTIONSERVICE_H

+ 93 - 0
app/src/main/cpp/inc/exlib/QJAServiceEntry.h

@@ -0,0 +1,93 @@
+//
+// Created by Ht on 2022/1/8.
+//
+
+#ifndef INC_0_LIBDEVCPP_QJASERVICEENTRY_H
+#define INC_0_LIBDEVCPP_QJASERVICEENTRY_H
+
+#include <qlibc/plugin/QPluginEntry.h>
+#include "QJAService.h"
+#include <memory>
+
+namespace jedge {
+
+    class JE_API QJAPluginService :
+            public jedge::QJAMgService {
+    public:
+        explicit QJAPluginService(jedge::QJAMgServer& opr, const std::string &name, const qlibc::QData &config);
+
+#ifdef ANDROID
+        jedge::MgBusHolder *getHolder() override {
+            return (jedge::MgBusHolder*)(&operator_);
+        }
+
+    protected:
+        auto getTrigerService() -> MgTriggerManager * override {
+            auto* holder = getHolder();
+            auto* s = holder==nullptr?nullptr:holder->findService(JEDGE_MGBUS_EVENT_SERVICE_NAME);
+            return (s == nullptr)?(nullptr):(MgTriggerManager*)(s);
+        }
+#endif
+
+    };
+
+    class JE_API QJAClassExtEntry :
+            public qlibc::QPluginEntry {
+    public:
+        explicit QJAClassExtEntry(std::string name, std::string type = "", int ver = 0);
+
+        ~QJAClassExtEntry() override { }
+
+        virtual void loadInnerClasses(jedge::QJAMgServer& server) = 0;
+
+        virtual void releaseClasses(QJAMgServer &server) = 0;
+    };
+
+    using QJAPluginServiceCreator = std::function<QJAPluginService*(jedge::QJAMgServer& server, const std::string &name, const qlibc::QData &config)>;
+
+    class JE_API QJAServiceEntry :
+        public qlibc::QPluginEntry {
+    protected:
+        QJAPluginService* service_ = nullptr;
+        QJAPluginServiceCreator* creator_ = nullptr;
+    public:
+        explicit QJAServiceEntry(std::string name, std::string type = "service", int ver = 0);
+
+        ~QJAServiceEntry() override;
+
+        void setServiceCreator(const QJAPluginServiceCreator& cr);
+
+        virtual QJAPluginService * getPluginService(QJAMgServer& server);
+    };
+
+    using QPluginServiceList = std::vector<QJAPluginService*>;
+
+    class JE_API QJAMultiServiceEntry :
+        public qlibc::QPluginEntry {
+    protected:
+        qlibc::QPObjectHolder<QJAPluginServiceCreator> creators_;
+    public:
+        explicit QJAMultiServiceEntry(std::string name, std::string type = "multiService", int ver = 0) :
+            qlibc::QPluginEntry(std::move(name), std::move(type), ver) {
+        }
+
+        ~QJAMultiServiceEntry() override {}
+
+        void bindServiceCreator(const std::string& key, const QJAPluginServiceCreator& cr);
+
+        //ÿ¸öservice¸´ÖÆÒ»¸öÒýÓÃ
+        virtual std::shared_ptr<QPluginServiceList> getPluginService(QJAMgServer& server);
+    };
+
+#define DefinePluginService(_e, _cls) \
+        ((QJAServiceEntry*)(_e))->setServiceCreator([](jedge::QJAMgServer& _s, const std::string &_n, const qlibc::QData &_c)->QJAPluginService* { \
+            return new _cls(_s,_n,_c); \
+        })
+
+#define BindMultiPluginService(_e, _k, _cls) \
+        ((QJAMultiServiceEntry*)(_e))->bindServiceCreator(_k, [](jedge::QJAMgServer& _s, const std::string &_n, const qlibc::QData &_c)->QJAPluginService* { \
+            return new _cls(_s,_n,_c); \
+        })
+}
+
+#endif //INC_0_LIBDEVCPP_QJASERVICEENTRY_H

+ 68 - 0
app/src/main/cpp/inc/exlib/QJedgeJniServiceUtil.h

@@ -0,0 +1,68 @@
+//
+// Created by Ht on 2021/1/12.
+//
+
+#ifndef LIBDEVCPP_QJEDGEJNISERVICEUTIL_H
+#define LIBDEVCPP_QJEDGEJNISERVICEUTIL_H
+
+
+#ifdef ANDROID
+
+#include <jni.h>
+#include <string>
+#include <qlibc/QJNIUtil.h>
+#include <qlibc/QLogger.h>
+
+#define JedgeGlobalVar() glServer
+
+#define JedgeImplServiceApi(pkg,server_type,service_name) \
+\
+server_type* glServer = nullptr; \
+implJni(pkg, jstring, getServiceName)(\
+    JNIEnv* env,\
+    jobject /* this */) { \
+    return env->NewStringUTF(service_name);\
+}\
+\
+implJni(pkg, jboolean, startService)(\
+    JNIEnv* env,\
+    jobject /* this */, jobject initData) {\
+    QLog("Starting %s ...", service_name);\
+    if(glServer!=nullptr){\
+        return false;\
+    }\
+    qlibc::QData d;\
+    qlibc::QJNIUtil::CppQDataFromJavaQData(env, d, initData);\
+    glServer = new server_type(d); \
+    if(!glServer->start(d)){\
+        delete glServer;\
+        glServer = nullptr;\
+        QLog("Failed.");\
+        return false;\
+    }\
+    QLog("Ok.");\
+    return true;\
+}\
+\
+implJni(pkg, void, shutdownService) (\
+    JNIEnv* env,\
+    jobject /* this */) {\
+    if(glServer!=nullptr){\
+        if(glServer->isRunning()){\
+            glServer->shutdown();\
+        }\
+        delete glServer;\
+        glServer = nullptr;\
+        QLog("Service shutdown.");\
+    }\
+}\
+\
+implJni(pkg, jboolean, isRunning) (\
+    JNIEnv* env,\
+    jobject /* this */) {\
+    return glServer!= nullptr && glServer->isRunning();\
+}\
+
+#endif //ANDROID
+
+#endif //LIBDEVCPP_QJEDGEJNISERVICEUTIL_H

+ 154 - 0
app/src/main/cpp/inc/exlib/QMqttClient.h

@@ -0,0 +1,154 @@
+//
+// Created by Ht on 2020/12/3.
+//
+
+#ifndef LIBDEVCPP_QMQTTCLIENT_H
+#define LIBDEVCPP_QMQTTCLIENT_H
+
+#include <string>
+#include <queue>
+
+#include <qlibc/httplib.h>
+#include <qlibc/qlibc.h>
+#include <mgbus/MgDataChannel.h>
+#include <mgbus/SocketBuffer.h>
+#include <mqtt/MQTTAsync.h>
+#include <unordered_set>
+#include <qlibc/QObjectEventHolder.h>
+
+#include "QMqttMessageDeliver.h"
+
+namespace jedge {
+
+
+    static const char* _default = "@mq_dft";
+    static const char* _pre_hook = "@mq_prehook";
+
+    static const char* sval_event_lost_connection = "onConnectionLost";
+    static const char* sval_event_get_connection =  "onConnect";
+    static const char* sval_event_dis_connection =  "onDisconnect";
+    static const char* sval_event_subscribed =      "onSubscribe";
+    static const char* sval_event_subscribe_fail =  "onSubscribeFail";
+
+    static int ival_mqtt_connect_timeout = 10000;
+
+    using QMqttDataHooker = std::function<bool(const std::string& topic, void *payload, int payloadLen, char* buffer, int* len)>;
+    using QMqttMessageHandler = std::function<bool(const std::string& topic, qlibc::QData& message)>;
+
+    typedef struct {
+        int mQos;
+        int retained;
+        std::string topicName;
+        std::string message;
+    } QWillDef;
+
+    class JE_API QMqttClient :
+        public jedge::MgDataChannel,
+        public qlibc::QObjectEventHolder {
+
+    private:
+        MQTTAsync client = nullptr;
+        int mQos = 2;
+        int mbKeepAlive = 60;  //超时退出
+        bool mConnected:1;
+        bool mUsingSSL:1;
+        bool subscribeOk:1;
+        bool mQuit:1;
+
+        std::string mServerUrl;
+        std::string mClientId;
+
+        std::string mMqttUserName;
+        std::string mMqttPassword;
+
+        std::string mSslCertFileName;
+
+        QWillDef mWillDef;
+
+        qlibc::QSharedObjectHolder<QMqttDataHooker>*
+                mHookers = nullptr;
+
+        qlibc::QSharedObjectHolder<QMqttMessageHandler>
+                mHandlers;
+
+        std::unordered_set<std::string>
+                mSubscribedTopics;
+
+        std::recursive_mutex mStatusMutex;
+
+        std::mutex              m_;
+        std::condition_variable cnntd_;
+
+        jedge::QMqttMessageDeliver *mMsgDeliver;
+        bool                    inner_deliver_;
+
+        static int onMsgArrvd(void *context, char *topicName, int topicLen, MQTTAsync_message *message);
+        static void onConnectionLost(void *context, char *cause);
+        static void onConnectFailure(void *context, MQTTAsync_failureData *response);
+        static void onConnect(void *context, char *cause);
+        static void onSubscribeFailure(void *context, MQTTAsync_failureData *response);
+        static void onSubscribe(void *context, MQTTAsync_successData *response);
+        static void onSend(void *context, MQTTAsync_successData *response);
+        static void onDisconnect(void *context, MQTTAsync_successData *response);
+
+    public:
+        explicit QMqttClient(ChannelOperator &opr, QMqttMessageDeliver &deliver, const std::string& name = "mqttClient");
+        explicit QMqttClient(ChannelOperator &opr, const std::string& name = "mqttClient");
+
+        ~QMqttClient();
+
+        //初始化参数设置
+        void resetWithInitData(const std::string &server, int port, const std::string &username, const std::string &password, const std::string &clientId);
+
+        bool isConnected();
+        bool connect();
+        bool disConnect();
+
+        void setDefaultHandler(const QMqttMessageHandler& handler);
+        void setTopicHandler(const std::string& topic, const QMqttMessageHandler& handler);
+        void removeTopicHandler(const std::string& topic);
+
+        void addDataHooker(const QMqttDataHooker& handler, const std::string& key = "");
+        void removeDataHooker(const std::string& key);
+
+        bool publish(const std::string &topic, const char* strMsg, int iQos = 0);
+        bool subscribe(const std::string& topic);
+
+        void setEventConnectionLostHandler(const qlibc::QObjectEventHandler &handler);
+
+        void setWillInfo(const std::string &serverTopic, const std::string &panelSn);
+
+        void removeDefaultHandler();
+
+        bool postRawMessage(qlibc::QData &message) override;
+
+        bool unsubscribe(const std::string& topic);
+
+        //用于动态设置uri响应器
+        jedge::QMqttMessageDeliver& getMessageDeliver() {
+            return *mMsgDeliver;
+        }
+
+        const std::string& getServer() {
+            return mServerUrl;
+        }
+
+        const std::string& getClientId() {
+            return mClientId;
+        }
+
+    protected:
+        void onMessageArrived(const std::string &topic, int msgid, int qos, void *payload, int payloadLen);
+        void onConnected();
+        void onConnectionLost(const char *cause);
+        void onDisconnected(MQTTAsync_successData *resp);
+        void onMessageSentOK(MQTTAsync_successData *resp);
+        void onSubscribeOk(MQTTAsync_successData *resp);
+        void onSubscribeFail(MQTTAsync_failureData *failData);
+    };
+
+};
+
+
+
+#endif //LIBDEVCPP_QMQTTCLIENT_H

+ 66 - 0
app/src/main/cpp/inc/exlib/QMqttMessageDeliver.h

@@ -0,0 +1,66 @@
+//
+// Created by Ht on 2020/4/24.
+//
+
+#ifndef TESTBIN_JMQTTMESSAGEDELIVER_H
+#define TESTBIN_JMQTTMESSAGEDELIVER_H
+
+#include <mutex>
+#include <unordered_map>
+#include <functional>
+
+#include <qlibc/qlibc.h>
+#include <mgbus/ChannelOperator.h>
+
+namespace jedge {
+
+    static const char* _default_topic_key = "_@df";
+
+    using QMqttRawHandler    = std::function<bool (ChannelOperator& o, const std::string& t, const byte b[], int l)>;
+    using QMqttHandler       = std::function<bool (ChannelOperator& o, const std::string& t, qlibc::QData& m)>;
+    using QMqttUriRspHandler    = std::function<bool (ChannelOperator& o, const std::string& u, qlibc::QData& m)>;
+    using QMqttUriReqHandler    = std::function<bool (qlibc::QData& r, ChannelOperator& o, const std::string& u, qlibc::QData& q)>;
+    using QMqttResponseSender   = std::function<void(const qlibc::QData& p)>;
+
+    class JE_API QMqttMessageDeliver {
+
+    private:
+        qlibc::QSharedObjectHolder<QMqttUriRspHandler>
+                    mUriRspHandlers;
+        qlibc::QSharedObjectHolder<QMqttUriReqHandler>
+                    mUriReqHandlers;
+        qlibc::QSharedObjectHolder<QMqttHandler>
+                    mTopicHandlers;
+        qlibc::QSharedObjectHolder<QMqttRawHandler>
+                    mTopicRawHandlers;
+
+        ChannelOperator& opr_;
+        QMqttResponseSender*
+                         mRspSender_ = nullptr;
+
+    public:
+        explicit QMqttMessageDeliver(jedge::ChannelOperator& sender) : opr_(sender) {};
+
+        virtual ~QMqttMessageDeliver();
+
+        int handleMessage(const std::string &topic, const unsigned char* buff, int buff_len);
+
+        void appendTopicHandler(const QMqttHandler& handler, const std::string &topic = _default_topic_key);      //topic为空时,为默认handler,可能屏蔽所有uri的handler
+
+        void appendTopicHandler(const QMqttRawHandler& handler, const std::string &topic = _default_topic_key);   //topic为空时,为默认handler,可能屏蔽所有uri的handler
+
+        void appendUriHandler(const std::string &uri, const QMqttUriReqHandler& handler);
+
+        void appendUriHandler(const std::string &uri, const QMqttUriRspHandler& handler);
+
+        void setRespnoseSender(const jedge::QMqttResponseSender& sender) ;
+
+    protected:
+        bool handleResponse(qlibc::QData& message);
+
+        bool handleRequest(qlibc::QData& message);
+
+    };
+}
+
+#endif //TESTBIN_Jconst MQTTMESSAGEDELIV&ER_H

+ 180 - 0
app/src/main/cpp/inc/exlib/QTaskManager.h

@@ -0,0 +1,180 @@
+//
+// Created by Ht on 2020/8/13.
+//
+
+#ifndef LIBDEVCPP_QTASKMANAGER_H
+#define LIBDEVCPP_QTASKMANAGER_H
+
+#include <qlibc/QPObjectHolder.h>
+#include <qlibc/QTimerEngine.h>
+#include <mgbus/ChannelOperator.h>
+
+/**
+ *      任务队列管理器
+ *          (1) 可以load预定义内置的Task
+ *          (2)可从json文件加载任务
+ *          (3)任务生命周期管理:
+ *              ·加载/卸载任务
+ *              ·触发任务:创建线程、并执行任务,任务在执行周期中,可能处于等待状态、需要被消息激活。
+ *              ·终止任务:
+ *              ·任务休眠、任务激活、任务超时
+ *         (4)管理结构:
+ *              ·可用任务表
+ *              ·激活任务表
+ *
+ */
+
+namespace jedge {
+    /**
+     *  任务类:
+     *      虚类,需要被继承实现
+     */
+    class JE_API QBaseTask :
+        public qlibc::QData {
+    protected:
+        std::string name_;
+
+    public:
+        explicit QBaseTask() : qlibc::QData () {
+            name_ = StringUtils::randomChars(16);
+            putString("name", name_);
+        }
+
+        explicit QBaseTask(qlibc::QData& data) : qlibc::QData(data){
+            name_ = data.getString("name");
+            if(name_.empty())
+                name_ = StringUtils::randomChars(16);
+        }
+
+        const string& taskName() {
+            return name_;
+        }
+
+    };
+
+    /**
+     *  用户定义任务,用于加载Json文件定义的外部任务
+     *
+     */
+    class JE_API QUserTask :
+            public QBaseTask {
+
+
+    };
+
+    using QTaskID = unsigned long;
+
+    class JE_API QTaskRunner :
+            public QBaseTask {
+        //需要记录Context及Stack
+    protected:
+        QBaseTask&     task_temp_;
+        QTaskID        task_id_;
+
+    public:
+        explicit QTaskRunner(QBaseTask& task, QTaskID id) : task_temp_(task), task_id_(id) {}
+
+        virtual bool cancel() {
+            return true;
+        }
+
+        virtual bool suspend() {
+            return true;
+        }
+
+        virtual bool resume() {
+            return true;
+        }
+
+        virtual bool finish() {
+            return true;
+        }
+
+    };
+
+    using QTaskDefs = qlibc::QPObjectHolder<QBaseTask> ;
+
+    using QTaskPool = qlibc::QPObjectHolder<QTaskRunner> ;
+
+    class JE_API QTaskManager {
+    protected:
+        ChannelOperator& operator_;
+
+        qlibc::QTimerEngine& timers_;
+
+    protected:
+        QTaskDefs    task_defs_;
+        QTaskPool    active_task_;
+
+    public:
+        explicit QTaskManager(ChannelOperator &opr, qlibc::QTimerEngine& engine) : operator_(opr) , timers_(engine) {
+        }
+
+        virtual ~QTaskManager() = default;
+
+        void clearTasks();
+
+    public:
+        bool loadTask(const std::string& name, const QBaseTask& task){
+            return true;
+        }
+
+        bool loadUserDefinedTask(const std::string& taskFile){
+            return true;
+        }
+
+        bool loadUserDefinedTasks(const std::string& tasksDir){
+            return true;
+        }
+
+        void unloadTask(const std::string& key){
+
+        }
+
+        //激活一个任务
+        int activateTask(const std::string& key) {
+            return 0;
+        }
+
+        //取消一个任务
+        bool cancelTask(const int task_id){
+            return true;
+        }
+
+        //保存任务
+        bool saveActiveTask(const int task_id){
+            return true;
+        }
+
+        //恢复任务
+        bool resumeTask(const int task_id){
+            return true;
+        }
+
+        //任务日志管理
+        void saveTaskLog(const int task_id){
+
+        }
+
+    protected:
+
+        void checkTaskStatus(){
+
+        }
+
+        void clearTimeoutTasks() {
+
+        }
+
+        void pauseActiveTasks(){
+
+        }
+
+        void resumeActiveTasks(){
+
+        }
+    };
+
+}
+
+#endif //LIBDEVCPP_QTASKMANAGER_H

+ 71 - 0
app/src/main/cpp/inc/exlib/http/ECSInvokeService.h

@@ -0,0 +1,71 @@
+//
+// Created by Ht on 2020/8/26.
+//
+
+#ifndef LIBDEVCPP_ECSInvokeService_H
+#define LIBDEVCPP_ECSInvokeService_H
+
+
+#include <mgbus/MgBusService.h>
+
+namespace jedge {
+
+    static const char* JEDGE_MUFIS_KEY_CLIENT_NAME = "payload.name";   //mgbus 客户端命名
+    static const char* je_http_invoker_sync_call_prefix = "/@t/@s"; //同步调用测试
+    static const char* je_http_invoker_async_call_prefix = "/@t/@a";//异步调用测试
+    static const unsigned char je_http_invoker_call_prefix_len = 6;
+
+    //用于测试向在线的客户端反向推送消息的测试服务。
+
+#define getTestTargetUri(req)\
+    (req).getString(MG_SERVICE_URI_PATTERN).substr(je_http_invoker_call_prefix_len)
+
+#define resetTestTargetUri(req) \
+    (req).putString(MG_SERVICE_URI_PATTERN, message.getString(MG_SERVICE_URI_PATTERN).substr(je_http_invoker_call_prefix_len))
+
+    //将所有带有mgbus直接请求标志的http请求,转发到内部服务中去
+#define bindMgBusTransfer(targetObj) \
+    targetObj.addPatternHandler(DATA_CHANNEL_HTTP, std::string(MG_MODULE_PATH_SIGN_PREFIX) + "*/**",  [](ChannelOperator& opr, const httplib::Request &httprequest, \
+        qlibc::QData &request,qlibc::QData &response) -> bool { \
+            return jedge::ECSInvokeService::httpDirectMgBusCall(opr, httprequest, request, response); \
+        })
+
+    class ECSInvokeService :
+            public MgBusService {
+
+    protected:
+
+    public:
+        explicit ECSInvokeService(jedge::MgBusHolder& opr, const std::string& name, const qlibc::QData& config = qlibc::QData()) :
+            MgBusService(opr, name, config){}
+        ~ECSInvokeService() override = default;
+
+        void preparePattern() override;
+
+    protected:
+        bool handle_Sync(qlibc::QData &message, qlibc::QData *response);
+
+        bool handle_ASync(qlibc::QData &message, qlibc::QData *response);
+
+        bool handle_Default(qlibc::QData &message, qlibc::QData *response) override;
+
+    public:
+
+        /**
+         *          mgcall 转发
+         *
+         * @param opr
+         * @param httprequest
+         * @param request
+         * @param response
+         * @return
+         */
+
+        static bool httpDirectMgBusCall(ChannelOperator& opr, const httplib::Request &httprequest,
+                                        qlibc::QData& request, qlibc::QData& response);
+
+    };
+
+}
+
+#endif //LIBDEVCPP_MUFISTESTSERVICE_H

+ 84 - 0
app/src/main/cpp/inc/exlib/http/QASyncHttpServer.h

@@ -0,0 +1,84 @@
+//
+// Created by Ht on 2020/7/13.
+//
+
+#ifndef JMUFISUNIT_QAYNCHTTPSERVER_H
+#define JMUFISUNIT_QAYNCHTTPSERVER_H
+
+#include <exlib/http/QHttpServer.h>
+
+namespace jedge {
+
+
+    using QASyncHttpHandler = std::function<bool (ChannelOperator& opr, const httplib::Request &httprequest,
+            qlibc::QData &request, qlibc::QData &response)>;
+
+    using QASyncHttpPostHandler = std::function<bool (ChannelOperator& opr, qlibc::QData &response)>;
+
+#define bindHttpPath(targetObj, patten, method) \
+    targetObj.addPathHandler(DATA_CHANNEL_HTTP, (patten),  [this](ChannelOperator& opr, const httplib::Request &httprequest, \
+            qlibc::QData &request,qlibc::QData &response) { \
+        this->method(opr, httprequest, request, response); \
+    })
+
+#define bindHttpPattern(targetObj, patten, method) \
+    targetObj.addPatternHandler(DATA_CHANNEL_HTTP, (patten),  [this](ChannelOperator& opr, const httplib::Request &httprequest, \
+            qlibc::QData &request,qlibc::QData &response) -> bool { \
+        return this->method(opr, httprequest, request, response); \
+    })
+
+#define bindHttpDefault(targetObj, method) \
+    bindHttpPattern(targetObj, "/**" ,method)
+
+        /**
+         * 绑定:  http://host/baseuri/...到一个指定的method
+         */
+#define bindHttpBaseDefault(targetObj, baseUri, method) \
+    bindHttpPath(targetObj, StringUtils::formatString("/%s", key.c_str()) ,method);\
+    bindHttpPattern(targetObj, StringUtils::formatString("/%s/**", key.c_str()) ,method)
+
+    class JE_API QASyncHttpServer :
+            public QHttpServer,
+            public MgDataChannel {
+    protected:
+        qlibc::QObjectMemoryPool<MgbusRequest, MESSAGE_POOL_SIZE> mg_req_pool_;
+        QASyncHttpPostHandler*   post_handler_ = nullptr;
+    public:
+        explicit QASyncHttpServer(ChannelOperator &opr) :
+                QHttpServer(opr),
+                MgDataChannel(opr), mg_req_pool_([]()->MgbusRequest*{ return new MgbusRequest;})
+                {}
+
+        const string &objId() override;
+
+        ~QASyncHttpServer() override {
+            delete post_handler_;
+        };
+
+        void addPathHandler(const string& srcChn, const string& path, const QASyncHttpHandler& handler);
+
+        void addPatternHandler(const string& srcChn, const string& pattern, const QASyncHttpHandler& handler);
+
+        bool postRawMessage(qlibc::QData &message) override;
+
+        void removePatherHandler(const string &pattern);
+
+        void addASyncRawHandler(QHttpHandlerMap& target, const string& srcChn, const string& key, const QASyncHttpHandler& handler, bool ordered = false);
+
+        void setASyncPostHandler(const QASyncHttpPostHandler& handler);
+    };
+
+    //用于mgbus holder的子类添加http接口时使用
+#define declareHttpUriHandlers(httpServer) \
+        void appendMessageHandlers(const std::string &dataChannel, const QStringList &pattern_list) override { \
+            for(const auto& path : pattern_list){ \
+                (httpServer).addPatternHandler(DATA_CHANNEL_HTTP, path,  \
+                        [&dataChannel](ChannelOperator& opr, const httplib::Request &httprequest, qlibc::QData  &request, qlibc::QData &response) ->bool { \
+                    return opr.postAsyncMessage(DATA_CHANNEL_HTTP, dataChannel, request); \
+                }); \
+            }\
+            MgBusHolder::appendMessageHandlers(dataChannel, pattern_list);\
+        }
+
+}
+#endif //JMUFISUNIT_QAYNCHTTPSERVER_H

+ 120 - 0
app/src/main/cpp/inc/exlib/http/QHttpClient.h

@@ -0,0 +1,120 @@
+//
+// Created by Ht on 2020/7/27.
+//
+
+#ifndef LIBDEVCPP_QHTTPCLIENT_H
+#define LIBDEVCPP_QHTTPCLIENT_H
+
+#include <qlibc/qlibc.h>
+#include <string>
+#include <mgbus/ChannelOperator.h>
+#include <mgbus/MgDataChannel.h>
+#include <qlibc/QObjectEventHolder.h>
+
+#include "QHttpCommon.h"
+
+namespace jedge {
+    //
+
+    static const char* sval_default_http_host = "@df";
+
+    using HttpASyncCallback = JE_API std::function<bool(const std::shared_ptr<httplib::Client>& fromClient, const string &uri, qlibc::QData &message)>;
+    using QHttpClientR = std::shared_ptr<httplib::Client>;
+
+    using HttpRawEncryptor = std::function<bool(std::string&, std::string&)>;
+    using HttpRawDecryptor = std::function<bool(std::string&, std::string&)>;
+
+    class JE_API QHttpUtil {
+    public:
+        static void httpResultToResponse(httplib::Response &http_res, qlibc::QData &response, HttpRawDecryptor* decryptor = nullptr);
+    };
+
+    class JE_API QHttpClient :
+            public MgDataChannel,
+            public qlibc::QObjectEventHolder {
+
+    protected:
+        qlibc::QSharedObjectHolder<httplib::Client> http_clients_;
+        std::unordered_map<std::string , std::string>  prefixs_;
+
+        HttpRawEncryptor*   encryptor_ = nullptr;
+        HttpRawDecryptor*   decryptor_ = nullptr;
+
+        unsigned long time_out_secs_;           //客户端自动清理时间,默认客户端不清理,0表示永久不清理
+        qlibc::QRTimer  timer_check_timeout_ = nullptr;
+        bool quit_ = false;
+
+        HttpASyncCallback *handler_ = nullptr;
+        std::recursive_mutex  http_client_mutex_;
+
+    public:
+        explicit QHttpClient(ChannelOperator &opr, unsigned long auto_clear = 10 * 60 * 1000);  // ten minutes
+
+        virtual ~QHttpClient();
+
+        QHttpClientR addHost(const std::string& name, const std::string& host, int port = 80);
+
+        //未找到时,直接使用默认Client
+        QHttpClientR findHttpClient(const std::string& name);
+
+        void setASyncHttpResponseCallback(const HttpASyncCallback& callback);
+
+        void removeASyncHttpResponseCallback();
+
+        bool postHttpRaw(const std::string& httpUri, const std::string& payload, const char* httpContent);
+
+        QHttpClientR prepareHost(const std::string& name, const std::string& host, int port);
+
+        void    setClientBase(const std::string& hostKey, const std::string& prefix);
+
+        bool checkAddUriPrefix(std::string& uri, const std::string& hostKey);
+
+        bool     postSyncHttpRequestByHost(const std::string& name, qlibc::QData& request, qlibc::QData& response);
+
+        bool     postASyncHttpRequestByHost(const std::string& name, qlibc::QData& reqeust);
+
+        bool     postSyncHttpRequestByUri(const std::string& uri, qlibc::QData& request, qlibc::QData& response);
+
+        bool     postASyncHttpRequestByUri(const std::string& uri, qlibc::QData& reqeust);
+
+    protected:
+        bool doPostHttpRequest(const std::shared_ptr<httplib::Client>& client, const std::string& uri, const qlibc::QData &request, qlibc::QData &response) const;
+
+        bool doPostAsyncHttpRequest(const std::shared_ptr<httplib::Client>&client, qlibc::QData &request) const;
+
+        virtual void handleASyncHttpResponse(const std::shared_ptr<httplib::Client>& fromClient, const string &uri, qlibc::QData &message) const;
+
+    public:
+
+        bool postRawMessage(qlibc::QData &message) override;
+
+        bool postHttpRequest(const std::string &uri, const qlibc::QData &data, qlibc::QData& resp) const;
+
+        void clearHttpClients();
+
+        void setEncryptor(const HttpRawEncryptor& encryptor) {
+            delete encryptor_;
+            encryptor_ = new HttpRawEncryptor(encryptor);
+        }
+
+        void setDecryptor(const HttpRawDecryptor& encryptor) {
+            delete decryptor_;
+            decryptor_ = new HttpRawDecryptor(encryptor);
+        }
+
+        void checkParamEncryption(qlibc::QData &msg) {
+            if(encryptor_== nullptr || !msg.containsKey("$param")) return;
+            auto orgStr = StringUtils::valueToJsonString(msg.asValue().operator[]("$param"));
+            std::string encryptedStr;
+            if((*encryptor_)(orgStr, encryptedStr))
+                msg.putString("$param", encryptedStr);
+        }
+
+    protected:
+        void checkClientTimeout();
+    };
+
+}
+
+
+#endif //LIBDEVCPP_QHTTPCLIENT_H

+ 17 - 0
app/src/main/cpp/inc/exlib/http/QHttpCommon.h

@@ -0,0 +1,17 @@
+//
+// Created by Ht on 2020/7/29.
+//
+
+#ifndef LIBDEVCPP_QHTTPCOMMON_H
+#define LIBDEVCPP_QHTTPCOMMON_H
+
+namespace jedge {
+
+    static const char* QHTTP_PAYLOAD_KEY = "param";
+    static const char* QHTTP_PAYLOAD_KEY_RAW = "$param";
+    static const char* QHTTP_CONTENT_TYPE_JSON = "application/json";
+//    static const char
+
+}
+
+#endif //LIBDEVCPP_QHTTPCOMMON_H

+ 80 - 0
app/src/main/cpp/inc/exlib/http/QHttpSSLClient.h

@@ -0,0 +1,80 @@
+//
+// Created by Ht on 2022/8/27.
+//
+
+#ifndef INC_1_LIBDEVCPP_QHTTPSSLCLIENT_H
+#define INC_1_LIBDEVCPP_QHTTPSSLCLIENT_H
+
+#include "QHttpClient.h"
+
+
+namespace jedge {
+    using HttpsASyncCallback = JE_API std::function<bool(const std::shared_ptr<httplib::SSLClient>& fromClient, const string &uri, qlibc::QData &message)>;
+    using HttpsClientR = std::shared_ptr<httplib::SSLClient>;
+
+    class JE_API QHttpSSLClient :
+        public MgDataChannel,
+        public qlibc::QObjectEventHolder {
+
+    protected:
+        qlibc::QSharedObjectHolder<httplib::SSLClient> ssl_clients_;
+        std::unordered_map<std::string , std::string>  prefixs_;
+
+        unsigned long time_out_secs_;           //客户端自动清理时间,默认客户端不清理,0表示永久不清理
+        qlibc::QRTimer  timer_check_timeout_ = nullptr;
+        bool quit_ = false;
+
+        HttpsASyncCallback *handler_ = nullptr;
+        std::recursive_mutex  httpssl_client_mutex_;
+
+    public:
+        //ChannelOperator &opr, unsigned long auto_clear = 10 * 60 * 1000
+        explicit QHttpSSLClient(ChannelOperator &opr, const std::string& name, unsigned long auto_clear = 10 * 60 * 1000) :
+            MgDataChannel(opr, name), time_out_secs_(auto_clear) {
+            auto self = getSelfRef();
+            timer_check_timeout_ = operator_.timerEngine().repeatRun([this, self] lamdaTimerTask(t,p) {
+                if(!available()) return false;
+                checkClientTimeout(); return true;
+            }, HEART_BEAT_GAP_, HEART_BEAT_GAP_);
+        }
+
+        ~QHttpSSLClient() override;
+
+        HttpsClientR addHttpsWebSite(const std::string& name, const std::string& host, const std::string& ca_cert_path, int port=443);
+
+        //未找到时,直接使用默认Client
+        HttpsClientR findHttpSSLClient(const std::string& name = "");
+
+        HttpsClientR prepareHost(const std::string& name, const std::string& host, int port, const std::string& cert_path = "");
+
+        void setClientBase(const std::string& hostKey, const std::string& prefix);
+
+        bool checkAddUriPrefix(std::string& uri, const std::string& hostKey);
+
+        bool postSyncHttpRequestByHost(const std::string& name, qlibc::QData& request, qlibc::QData& response);
+
+        bool postSyncHttpRequestByUri(const std::string& uri, qlibc::QData& request, qlibc::QData& response);
+
+        bool postASyncHttpRequestByUri(const std::string& uri, qlibc::QData& request);
+
+        bool postRawMessage(qlibc::QData &message) override {
+            //仅仅是转发,而不一定需要回调。
+            return true;
+        }
+
+        void clearHttpsClients();
+
+        bool postHttpsRaw(const std::string& httpUri, const std::string& payload, const char* httpContent);
+
+    protected:
+
+        virtual void handleASyncHttpResponse(const HttpsClientR& fromClient, const string &uri, qlibc::QData &message) const;
+
+        bool doPostHttpRequest(const HttpsClientR& client, const std::string& uri, const qlibc::QData &request, qlibc::QData &response) const;
+
+        bool doPostAsyncHttpRequest(const HttpsClientR& client, qlibc::QData &request) const;
+
+        void checkClientTimeout();
+    };
+}
+#endif //INC_1_LIBDEVCPP_QHTTPSSLCLIENT_H

+ 127 - 0
app/src/main/cpp/inc/exlib/http/QHttpServer.h

@@ -0,0 +1,127 @@
+//
+// Created by Ht on 2020/5/8.
+//
+
+#ifndef TESTBIN_MisHTTPSERVER_H
+#define TESTBIN_MisHTTPSERVER_H
+
+#include <iostream>
+#include <vector>
+
+#include <qlibc/qlibc.h>
+
+#include <mgbus/MgDataChannel.h>
+
+#include "QHttpCommon.h"
+
+#include <mgbus/ChannelOperator.h>
+
+namespace jedge {
+
+    //监听http端口
+    static const char* midx_base_file_path = "./www";
+
+    const static char* DATA_CHANNEL_HTTP = "http";
+
+    const static int ival_default_http_timeout_ms_ = 10000;
+
+    //并发线程数量
+    static const int MGBUS_DATA_HANDLE_THREAD_COUNT = 10;
+
+    using QHttpHandler = std::function<bool (const httplib::Request &httprequest, const qlibc::QData& request, qlibc::QData& response)>;
+    using QHttpHandlerMap = std::unordered_map<std::string, httplib::Server::Handler>;
+
+#define AppendHttpPathHandler(targetObj, patten, method) \
+    targetObj.addPathHandler((patten),  [this](const httplib::Request & httpreq, const qlibc::QData& request, qlibc::QData& respnose) -> bool { \
+        return this->method(httpreq,  request, respnose); \
+    })
+
+#define AppendHttpPatternHandler(targetObj, patten, method) \
+    targetObj.addPatternHandler((patten),  [this](const httplib::Request & httpreq, const qlibc::QData& request, qlibc::QData& respnose) -> bool { \
+        return this->method(httpreq,  request, respnose); \
+    })
+
+    class JE_API QHttpServer : public qlibc::QSelfRefObject {
+    protected:
+        ChannelOperator& opr_;
+        httplib::Server* server_;
+        std::vector<std::string>  key_order_list_;          //多种规则并存时、规则key的优先级顺序
+        QHttpHandlerMap mPathHandlers;
+        QHttpHandlerMap mPatternHandlers;
+        httplib::Logger mLogger;
+        qlibc::QSharedObjectHolder<ifstream> mFileCache;
+        string mBasePath;
+
+        int http_timeout_ms_ = ival_default_http_timeout_ms_;
+
+        CMDnsServicePublish *mcmdns_pub_ = nullptr;
+
+        int port_ = -1;
+
+        bool active_ = false;
+    public:
+        explicit QHttpServer(ChannelOperator& opr);
+
+        ~QHttpServer();
+
+        const string &objId() override;
+
+    protected:
+        void addRawHandler(QHttpHandlerMap& target, const string& key, const QHttpHandler& handler, bool ordered = false);
+
+    public:
+        void shutdown();
+
+        bool start(int httpPort, const std::string& subnet = "", const std::string& key="");
+
+        void addPathHandler(const string& path, const QHttpHandler& handler);
+
+        void addPatternHandler(const string& pattern, const QHttpHandler& handler);
+
+        void removeAllHanlders();
+
+        virtual bool defaultHandler(const httplib::Request & httpreq, const qlibc::QData& req, qlibc::QData &res);
+
+        bool MisBindHttpPort(const std::string& hostAddr, int httpPort);
+
+        void buildHttpResponse(httplib::Response &response, const qlibc::QData &jrres);
+
+        void buildHttpInputParams(qlibc::QData &jrreq, const httplib::Request &httprequest);
+
+        void setBasePath(const string &basePath);
+
+        const string& getBasePath();
+
+        void findFile(qlibc::QData &response, const string &fileName, const string& mime = "");
+
+        std::shared_ptr<ifstream> getCachedStream(const string &file, bool autoRemove = true);
+
+        void closeCachedStream(const std::shared_ptr<std::ifstream>& fs, const std::string& file = "");
+
+    public:
+        static void MimeNameFromExt(const string &ext, string& mime);
+
+        static void MimeNameFromFileName(const std::string &fileName, std::string &mime);
+
+        void
+        doAddHttpHandler(const httplib::Server::Handler &httpHandler, QHttpHandlerMap &target, const string &key,
+                         bool ordered);
+
+        bool isActive();
+
+        inline void setTimeout(int to_ms) {
+            http_timeout_ms_ = to_ms;
+        }
+
+        int getCurrentHttpPort() {
+            return port_;
+        }
+
+    protected:
+        void prepareHttpServer();
+
+        bool doCacheFile(const std::string &cacheFile);
+    };
+
+}
+#endif //TESTBIN_MisHTTPSERVER_H

+ 41 - 0
app/src/main/cpp/inc/exlib/sock/JESockCommProtocol.h

@@ -0,0 +1,41 @@
+//
+// Created by Ht on 2020/8/21.
+//
+
+#ifndef LIBDEVCPP_JESOCKCOMMPROTOCOL_H
+#define LIBDEVCPP_JESOCKCOMMPROTOCOL_H
+
+#include <mgbus/QCommonProtocol.h>
+
+namespace jedge {
+
+    static const char* mf_protocol_key_beat_ = "beat";
+    static const char* mf_protocol_key_auth_ = "auth";
+    static const char* mf_protocol_key_quit_ = "quit";
+    static const char* mf_protocol_key_group_ = "group";
+    static const char* mf_protocol_key_net_ = "net";
+    static const char* mf_protocol_key_client_name_ = "payload.name";
+
+    //处理Mgbus的基础通信消息,采用默认的JedgeCommonProtocol
+    class JE_API JECommSockProtocol :
+            public QCommonProtocol {
+    public:
+        //初始化协议表
+        void initProtocol() override {
+            qlibc::QData d;d.putObjFmtString(JEDGE_MGBUS_CMD_KEY, jedge_mgbus_cmd_heart_beat_);
+            addMessage(mf_protocol_key_beat_, d);
+            d.putObjFmtString(JEDGE_MGBUS_CMD_KEY, jedge_mgbus_cmd_regist_);
+            addMessage(mf_protocol_key_auth_, d);
+            d.putObjFmtString(JEDGE_MGBUS_CMD_KEY, jedge_mgbus_cmd_quit_);
+            addMessage(mf_protocol_key_quit_, d);
+            d.putObjFmtString(JEDGE_MGBUS_CMD_KEY, jedge_mgbus_cmd_group_);
+            addMessage(mf_protocol_key_group_, d);
+            d.putObjFmtString(JEDGE_MGBUS_CMD_KEY, jedge_mgbus_cmd_net_);
+            addMessage(mf_protocol_key_net_, d);
+            QCommonProtocol::initProtocol();
+        }
+    };
+
+}
+
+#endif //LIBDEVCPP_JESOCKCOMMPROTOCOL_H

+ 36 - 0
app/src/main/cpp/inc/exlib/sock/MgNodeManagerService.h

@@ -0,0 +1,36 @@
+//
+// Created by Ht on 2021/2/18.
+//
+
+#ifndef LIBDEVCPP_MGNODEMANAGERSERVICE_H
+#define LIBDEVCPP_MGNODEMANAGERSERVICE_H
+
+#include <mgbus/MgBusService.h>
+#include "QNodeServer.h"
+
+namespace jedge {
+
+    /**
+     *  用于管理Mbgus的
+     *
+     *
+     *
+     */
+
+    class MgNodeManagerService :
+            public MgBusService {
+    protected:
+        QNodeServer& mSocketServer;
+    public:
+        explicit MgNodeManagerService(jedge::MgBusHolder& opr,const std::string &name,
+                const qlibc::QData &config, jedge::QNodeServer& server);
+
+        void preparePattern() override;
+
+        bool listNodes(qlibc::QData &message, qlibc::QData *response);
+
+        bool postNodeMessage(qlibc::QData &message, qlibc::QData *response);
+    };
+}
+
+#endif //LIBDEVCPP_MGNODEMANAGERSERVICE_H

+ 134 - 0
app/src/main/cpp/inc/exlib/sock/QNodeClient.h

@@ -0,0 +1,134 @@
+//
+// Created by Ht on 2021/2/1.
+//
+
+#ifndef LIBDEVCPP_QNODECLIENT_H
+#define LIBDEVCPP_QNODECLIENT_H
+
+#include <mgbus/QJsonSocketClient.h>
+#include <mgbus/MgBusService.h>
+#include <mgbus/MgServerIntf.h>
+#include <mgbus/MgBusHolder.h>
+#include <mgbus/QCMDnsClient.h>
+
+#include <exlib/http/QHttpClient.h>
+#include "JESockCommProtocol.h"
+
+namespace jedge {
+
+    static const char* DATA_CHANNEL_SOCKET_CLIENT = "sockc";           //socket client的名字
+    static const char* DATA_CHANNEL_HTTP_CLIENT = "httpc";     //描述http返回的目标服务的信息
+
+    static const char*  vkey_sock_client_config_host_    = "sc_host";
+    static const char*  vkey_sock_client_config_port_    = "sc_port";
+    static const char*  vkey_sock_client_config_sock_mode_    = "sc_udp";
+
+#define CLIENT_MESSAGE_POOL_SIZE (128)                             //预设消息内存池大小
+
+    class JE_API QNodeClient :
+            public jedge::MgServerIntf,
+            public jedge::ChannelOperator {
+    protected:
+        qlibc::QData init_config_;
+        qlibc::QData run_param_;
+        qlibc::QData runData_;
+        std::string  name_;
+        std::string  service_name_;
+        std::string  cache_fn_;
+
+        std::string host;
+        int port = -1;
+
+        qlibc::QObjectMemoryPool<MgbusRequest, CLIENT_MESSAGE_POOL_SIZE> mg_req_pool_;
+
+        jedge::QHttpClient       client_http_;
+        jedge::QJsonSocketClient client_sock_;
+        QCMDnsClient             cmdns_client_;
+
+        std::mutex              mgconn_wait_mutex_;
+        std::condition_variable mgconn_wait_;
+
+        jedge::JECommSockProtocol   protocol_;
+
+        qlibc::QRTimer   heart_timer_ = nullptr;
+
+        QByte  tick = 0;
+
+        bool   quit_ = false;
+        bool   udp_login_ok_ = false;       //在收到login ok 之前,都需要不断地注册
+        bool   starting_ = false;
+
+        std::recursive_mutex  holder_op_mutex_;
+    public:
+
+        explicit QNodeClient(const qlibc::QData& config, const std::string& name = "",
+                             const httplib::RThreadPool& pool = nullptr, const qlibc::QRTimerEngine& engine = nullptr);
+
+        bool isActive() override;
+
+        explicit QNodeClient(const std::string& config, const std::string& name = "",
+                             const httplib::RThreadPool& pool = nullptr, const qlibc::QRTimerEngine& engine = nullptr);
+
+        QCMDnsClient &getCmdnsClient() override;
+
+        ~QNodeClient() override = default;
+
+        bool postSyncMessage(const string &src, const string &target, qlibc::QData &message,
+                             qlibc::QData &response) override;
+
+        bool postAsyncMessage(const string &src, const string &target, qlibc::QData &message) override;
+
+        bool start(const qlibc::QData &config) override;
+
+        void shutdown() override;
+
+        const string &name() override {
+            return name_;
+        };
+
+        bool postSyncHttpRequestByHost(const std::string& name, qlibc::QData& request, qlibc::QData& response);
+
+        bool postASyncHttpRequestByHost(const std::string& name, qlibc::QData& request, const JsonSocketHandler& handler);
+
+        bool postSyncHttpRequestByUri(const std::string& uri, qlibc::QData& request, qlibc::QData& response);
+
+        bool postASyncHttpRequestByUri(const std::string& uri, qlibc::QData& request, const JsonSocketHandler& handler);
+
+        void appendMessageHandler(const string &pattern, const JsonSocketHandler& handler);
+
+        inline void Uri(const std::string&uri, const JsonSocketHandler& handler) {
+            client_sock_.Uri(uri, handler);
+        };
+
+        inline void Regex(const std::string& pattern, const JsonSocketHandler& handler) {
+            client_sock_.Regex(pattern, handler);
+        };
+
+        MgDataChannel &getClientChannel();
+
+    protected:
+        bool startNodeClient(const qlibc::QData &config, SocketMode mode = typeTCP);
+
+        bool OnASyncHttpResponse(httplib::Client *fromClient, const string &uri, qlibc::QData &message);
+
+        bool onClientAuth(const std::string& sockKey, const std::string &cmd, qlibc::QData &msg, SocketMode mode);
+
+        bool onClientQuit(const std::string& sockKey, const std::string &cmd, qlibc::QData &msg, SocketMode mode);
+
+        bool onHeartBeatMsg(const std::string& sockKey, const std::string &cmd, qlibc::QData &msg, SocketMode mode);
+
+        void heart_beat();
+
+        void putRequestInQueue(qlibc::QData &request, const JsonSocketHandler *handler);
+
+        void preppareHandler(const std::string &name);
+
+        virtual bool targetDecided();
+
+        virtual void findTargetHost(const std::string& name, const std::string& subnet, SocketMode mode);
+
+        virtual int findProperIndex(const CMdnsServiceQueried services[], int cnt);
+    };
+
+}
+#endif //LIBDEVCPP_QNODECLIENT_H

+ 184 - 0
app/src/main/cpp/inc/exlib/sock/QNodeServer.h

@@ -0,0 +1,184 @@
+//
+// Created by Ht on 2020/5/8.
+//
+
+#ifndef TESTBIN_MUFISSOCKETSERVER_H
+#define TESTBIN_MUFISSOCKETSERVER_H
+
+#include <mgbus/MgDataChannel.h>
+#include <mgbus/QSocketServer.h>
+#include <mgbus/QCMDnsClient.h>
+#include <mgbus/SocketClient.h>
+#include <mgbus/SocketHandlerHolder.h>
+
+#include "JESockCommProtocol.h"
+
+namespace jedge {
+
+    class JE_API QClientNode :
+            public qlibc::QData {
+
+    protected:
+        std::string src_key_;
+        QJsonSocketServer &server_;
+        QByte       tick_ = 0;
+
+    public:
+        explicit QClientNode(const std::string &sockKey, std::string clientName,
+                             qlibc::QData &datamsg, QJsonSocketServer &server) : qlibc::QData(datamsg),
+                                                                                 src_key_(std::move(clientName)), server_(server)
+        {}
+
+        virtual bool postMessage(qlibc::QData &datamsg) = 0;
+
+        virtual bool postMessage(const std::string &datamsg) = 0;
+
+        virtual void closeNode() = 0;
+
+        virtual const string& sockKey() = 0;
+
+        bool checkUpdateKey(const std::string& skey, qlibc::QData &datamsg);
+
+        const string &mufisKey() {
+            return src_key_;
+        }
+
+        bool timeout(QByte max_tick) {
+            tick_++;
+            return tick_>max_tick;
+        }
+
+        void resetTimeout() {
+            tick_=0;
+        }
+
+        SocketMode mode() {
+            return typeTCP;
+        }
+    };
+
+
+    class JE_API QTcpClientNode :
+            public QClientNode {
+    protected:
+        std::shared_ptr<SocketClientNode> client_node_;
+    public:
+        explicit QTcpClientNode(const string &sockKey, const string &src, QData &datamsg, QJsonSocketServer &server)
+                : QClientNode(sockKey, src, datamsg, server), client_node_(server.findTCPNode(sockKey)){
+        }
+
+        bool postMessage(qlibc::QData &datamsg) override {
+            return (client_node_!= nullptr && client_node_->write(datamsg));
+        };
+
+        bool postMessage(const std::string &datamsg) override {
+            return (client_node_!= nullptr && client_node_->write(datamsg+"\n"));
+        }
+
+        void closeNode() override {
+            if(client_node_!= nullptr) client_node_->close();
+        }
+
+        const string &sockKey() override {
+            return client_node_->sockKey();
+        }
+    };
+
+    class JE_API QUdpClientNode :
+            public QClientNode {
+    protected:
+        std::string sockKey_;
+        std::string host_;
+        int         port_;
+
+    public:
+        explicit QUdpClientNode(const std::string &sockKey, const std::string &src, qlibc::QData &datamsg, QJsonSocketServer &server)
+                : QClientNode(sockKey, src, datamsg, server), sockKey_(sockKey){
+            host_ = StringUtils::getSubStrBefore(sockKey,':',1);
+            port_ = NumberUtils::stringToInt(StringUtils::getSubStrAfter(sockKey,':',1));
+        }
+
+        bool postMessage(qlibc::QData &datamsg) override {
+            return server_.sendMsgByUdp(host_, port_, datamsg);
+        }
+
+        bool postMessage(const std::string &datamsg) override {
+            const char* buff = datamsg.c_str();
+            return server_.sendDataByUdp(host_, port_, buff, datamsg.size());
+        }
+
+        void closeNode() override {
+        }
+
+        const string &sockKey() override {
+            return sockKey_;
+        }
+    };
+
+    //用于启动一个与mgbus紧密相连的socketServer。
+    //其作用,是向mgbus转发消息。
+    class JE_API QNodeServer :
+            public MgDataChannel {
+    protected:
+        QJsonSocketServer*  server_;
+        qlibc::QSharedObjectHolder<QClientNode> client_nodes_;
+        qlibc::QSharedObjectHolder<QClientNode> key_nodes_;
+
+        qlibc::QSharedObjectHolder<jedge::JsonSocketRequestUDHandler>* server_ud_handlers_ = nullptr;
+
+        std::recursive_mutex       node_server_mutex_;
+        jedge::JECommSockProtocol  protocol_;
+        qlibc::QRTimer             heart_timer_ = nullptr;
+
+        CMDnsServicePublish *mcmdns_pub_ = nullptr;
+        bool  active_:1;
+        bool  quit_:1;
+
+        bool onClientAuth(const std::string& sockKey, const std::string &cmd, qlibc::QData &msg, SocketMode mode);
+
+        bool onClientQuit(const std::string& sockKey, const std::string &cmd, qlibc::QData &msg, SocketMode mode);
+
+        bool onHeartBeatMsg(const std::string& sockKey, const std::string &cmd, qlibc::QData &msg, SocketMode mode);
+
+        bool doHandleServerMessage(qlibc::QData &message);
+
+        void heart_beat();
+
+        void onTcpConnectionClosed(SocketClientNode &node);
+
+        bool appendMessageSrc(const string &sourceKey, qlibc::QData &datamsg);
+
+    public:
+        explicit QNodeServer(ChannelOperator& manager, const std::string& name = jedge::DATA_CHANNEL_SOCK);
+        ~QNodeServer() override;
+
+        virtual bool handleJsonMessage(SocketClientNode* node, qlibc::QData &msg);
+
+        virtual bool handleUdpSocketMessage(const string &host, int port, qlibc::QData &message);
+
+        virtual void shutdown();
+
+        virtual bool start(const qlibc::QData& config, int default_port , SocketMode mode = typeTCP);
+
+        bool postRawMessage(qlibc::QData &message) override;
+
+        void publishServiceToCMdns(const std::string &type, const std::string &service, int port, const std::string& subnet = "",
+                                   const std::string& comment = "", int priority = ival_default_cmdns_priority, int ttl = ival_default_cmdns_ttl);
+
+        void getNodeLists(qlibc::QDataList& dl);
+
+        bool postClientMessage(const std::string& clientid, qlibc::QData& message);
+        bool postClientRequest(const std::string& clientid, qlibc::QData& message, qlibc::QData& resp, int timeout = -1);
+
+        bool isActive();
+
+        bool addUriHandler(const std::string &pattern, const jedge::JsonSocketRequestUDHandler& handler);
+
+        bool userDefinedHandle(const std::string& uri, qlibc::QData &msg);
+
+        int getCurrentPort();
+
+        std::string getCurrentSocketType();
+    };
+}
+#endif //TESTBIN_MUFISSOCKETSERVER_H

+ 51 - 0
app/src/main/cpp/inc/exlib/sock/QSockClient.h

@@ -0,0 +1,51 @@
+//
+// Created by Ht on 2021/8/1.
+//
+
+#ifndef INC_0_LIBDEVCPP_NEW_JA_QSOCKCLIENT_H
+#define INC_0_LIBDEVCPP_NEW_JA_QSOCKCLIENT_H
+
+#include <mgbus/ChannelOperator.h>
+#include <mgbus/MgDataChannel.h>
+#include <mgbus/QJsonSocketClient.h>
+#include <jadom2/JAUtil.h>
+
+namespace jedge {
+
+    static const char* sval_event_connect = "onConnect";
+    static const char* sval_event_timeout = "onTimeout";
+
+    class JE_API QSockClient :
+            public jedge::QJsonSocketClient {
+    protected:
+        qlibc::QSharedObjectHolder<jedge::JsonSocketRequestUDHandler>* client_ud_handlers_ = nullptr;
+        qlibc::QRTimer  heart_timer_ = nullptr;
+        QByte  tick = 0;
+
+    public:
+        explicit QSockClient(ChannelOperator& manager, const std::string& name = jedge::DATA_CHANNEL_SOCK) :
+                QJsonSocketClient(manager, name)  {
+            markObjectEvent(sval_event_connect);
+            markObjectEvent(sval_event_timeout);
+        };
+
+        ~QSockClient() override;
+
+        bool addUriHandler(const string &pattern, const JsonSocketRequestUDHandler& handler);
+
+        bool checkSocketMessageLegal(qlibc::QData &data) override;
+
+        bool deliverClientMessage(ChannelOperator &opr, qlibc::QData &message);
+
+        bool connect(const std::string &host, int port, SocketMode mode);
+
+        void heart_beat();
+
+        void onClientTimeout();
+
+        bool postSocketRequest(const string &uri, qlibc::QData &req, qlibc::QData &rsp, int timeout);
+    };
+
+}
+
+#endif //INC_0_LIBDEVCPP_NEW_JA_QSOCKCLIENT_H

+ 150 - 0
app/src/main/cpp/inc/exlib/sysdev/SysDevcie.h

@@ -0,0 +1,150 @@
+//
+// Created by Ht on 2021/4/26.
+//
+
+#ifndef INC_0_LIBDEVCPP_SYSDEVCIE_H
+#define INC_0_LIBDEVCPP_SYSDEVCIE_H
+
+#include <qlibc/qlibc.h>
+#include <mutex>
+#include <condition_variable>
+#include <mgbus/ChannelOperator.h>
+#include <mgbus/MgBusService.h>
+
+namespace jedge {
+
+    /**
+     *  系统功能设备
+     */
+    static const char *vkey_coss_command_ = "command";
+
+#define MAKE_DEVICE_EVENT(d, msg, cmd) \
+        auto* __##msg##_data = operator_.getBlankMessage(); \
+        __##msg##_data->clear();\
+        __##msg##_data->putString("device_id", d->getName());\
+        __##msg##_data->putString(vkey_coss_command_, (cmd))
+
+#define REPORT_DEVICE_EVENT(d, msg)\
+        d->postEventMessage("/device/response", *__##msg##_data); \
+        operator_.releaseMessage(__##msg##_data)
+
+
+    class JE_API SysDevice : public qlibc::QData, public qlibc::QSelfRefObject {
+    protected:
+        jedge::ChannelOperator& operator_;
+        jedge::MgBusService&    service_;
+        std::recursive_mutex    status_mutex_;
+        bool                    started_ = false;
+        bool                    updated_ = false;
+        std::condition_variable status_wait_;
+        std::mutex              status_wait_mutex_;
+        QStringList             mTargets;
+        qlibc::QRTimer          mTimer = nullptr;
+
+        virtual bool doLocalStart(const string &target, int frequency, const qlibc::QData& data) {
+            return false;
+        }
+
+        virtual void doReadLocalStatus(qlibc::QData &data) {
+            //要注意比对是否已更新数值
+        }
+
+        virtual void doLocalStop() {
+
+        }
+
+        virtual bool doHandleControl(const std::string& action, const qlibc::QData& param) {
+            return false;
+        }
+
+        virtual void readProperty(const std::string& property, std::string& value) {
+
+        }
+
+    public:
+        explicit SysDevice(jedge::ChannelOperator& opr, jedge::MgBusService&  svc, const qlibc::QData& def, const std::string& devName="") : qlibc::QData(def), operator_(opr), service_(svc) {
+            setName(devName.empty()?"LocalDev_"+StringUtils::randomChars(2):devName);
+        }
+
+        ~SysDevice() override {
+            if(started_) stopLocal();
+        }
+
+        bool isLocalStarted() {
+            return started_;
+        }
+
+        void postEventMessage(const std::string &uri, qlibc::QData &msg) {
+            RECURSIVE_LOCK(status_mutex_);
+            for(auto& target:mTargets) {
+                service_.postServiceMessage(target, "/device/response", msg);
+            }
+        }
+
+        void readLocalStatus() {
+            QLog("Reading Sensor Status ...");
+            RECURSIVE_LOCK(status_mutex_);
+            auto* msg = operator_.getBlankMessage<qlibc::QData>();
+            msg->clear();
+            doReadLocalStatus(*msg);
+            if(updated_) {
+                msg->putString(vkey_coss_command_, "statusValue");
+                postEventMessage("/device/response", *msg);
+            }
+            operator_.releaseMessage<qlibc::QData>(msg);
+        }
+
+        void stopLocal() {
+            if(isLocalStarted()) {
+                RECURSIVE_LOCK(status_mutex_);
+                operator_.timerEngine().stopTimer(mTimer);
+                mTimer = nullptr;
+                doLocalStop();
+                auto* msg = operator_.getBlankMessage<qlibc::QData>();
+                msg->clear();
+                msg->putString("command","devOffline");  //设备上线。如果coss发现设备尚未注册,则注册该设备。
+                msg->putString("device_id", getName());
+                for(const auto& target : mTargets) {
+                    service_.postServiceMessage(target, "/device/response", *msg);
+                }
+                operator_.releaseMessage<qlibc::QData>(msg);
+                started_ = false;
+            }
+        }
+
+        void addTarget(const std::string &target) {
+            if(!target.empty()) {
+                RECURSIVE_LOCK(status_mutex_);
+                mTargets.emplace_back(target);
+                auto* msg = operator_.getBlankMessage<qlibc::QData>();
+                msg->clear();
+                msg->putString("command","devOnline");  //设备上线。如果coss发现设备尚未注册,则注册该设备。
+                msg->putString("device_id", getName());
+                service_.postServiceMessage(target, "/device/response", *msg);
+                operator_.releaseMessage<qlibc::QData>(msg);
+            }
+        }
+
+        bool startLocal(const std::string &target, int frequency, const qlibc::QData& data) {
+            if(!isLocalStarted()) {
+                RECURSIVE_LOCK(status_mutex_);
+                if(!doLocalStart(target, frequency, data)){
+                    QLog("Start device %s for target failed ...", getName().c_str());
+                    return false;
+                }
+                auto self = getSelfRef();
+                mTimer = operator_.timerEngine().repeatRun( [this, self] lamdaTimerTask(t,p) {
+                    AssertAvailableValue(true);
+                    readLocalStatus(); return true;
+                    },frequency, frequency);
+                addTarget(target);
+                started_ = true;
+            }else{
+                addTarget(target);
+            }
+            return true;
+        }
+    };
+}
+
+#endif //INC_0_LIBDEVCPP_SYSDEVCIE_H

+ 202 - 0
app/src/main/cpp/inc/exlib/sysdev/SysDeviceService.h

@@ -0,0 +1,202 @@
+//
+// Created by Ht on 2021/4/26.
+//
+
+#ifndef INC_0_LIBDEVCPP_SYSDEVICESERVICE_H
+#define INC_0_LIBDEVCPP_SYSDEVICESERVICE_H
+
+
+#include <mgbus/MgBusService.h>
+#include "SysDevcie.h"
+
+/**
+ *  本地系统功能中的模拟设备
+ *
+ */
+namespace jedge {
+
+    static const char* sval_service_local_device_ = "locals";
+
+    using DevCreator = std::function<jedge::SysDevice*(const std::string &device, const qlibc::QData& def)>;
+    using DeviceHandlerSettor = std::function<void(jedge::SysDevice* device)>;
+    class JE_API SysDeviceService: public jedge::MgBusService {
+    protected:
+        qlibc::QSharedObjectHolder<jedge::SysDevice>        mDevices;
+        qlibc::QSharedObjectHolder<qlibc::QData>            mDeviceModes;
+        qlibc::QSharedObjectHolder<jedge::DevCreator>       mDeviceCreators;
+        qlibc::QSharedObjectHolder<jedge::DeviceHandlerSettor> mDeviceHandlerSettors;
+        std::recursive_mutex                            operate_mutex_;
+
+    public:
+        explicit SysDeviceService(jedge::MgBusHolder &opr, const std::string &name, const qlibc::QData &config) :
+                jedge::MgBusService (opr, name,config) {
+
+        }
+
+        ~SysDeviceService() override {
+            RECURSIVE_LOCK(operate_mutex_);
+            mDevices.invokeOnAllObject([] SharedHolderAccessor(k, d, jedge::SysDevice) {
+                d->stopLocal();
+                return true;
+            });
+        }
+
+        void preparePattern() override {
+            MgBusService::preparePattern();
+            prepareSelfBind;
+            bindHandler(startLocal);
+            bindHandler(stopLocal);
+        }
+
+        SysDevice *loadLocalDevice(const std::string &deviceName, const std::string& type) {
+            RECURSIVE_LOCK(operate_mutex_);
+            //find creator && setup it.
+            auto cr = mDeviceCreators.findObject(type);
+            auto st = mDeviceHandlerSettors.findObject(type);
+            if(cr==nullptr) return nullptr;
+            auto m = mDeviceModes.findObject(type);
+            if(m== nullptr) return nullptr;
+            SysDevice* d = nullptr;
+            try{ d = cr->operator()(deviceName, *m);
+            } catch (std::bad_function_call& e) {}
+            if(d!=nullptr){
+                if(st!=nullptr) { try { st->operator()(d); } catch (std::bad_function_call& e) {} }
+                mDevices.appendNew(deviceName, d);
+            }
+            return d;
+        }
+
+        bool startLocal(qlibc::QData &message, qlibc::QData *rsp) {
+            RECURSIVE_LOCK(operate_mutex_);
+            //目前暂时默认发向coss
+            std::string deviceName = message.getString("device_id");
+            std::string type = message.getString("device_type");
+            if(type.empty()) {
+                FailPRspMsg(rsp, "No device set.");
+                return true;
+            }
+
+            if(deviceName.empty()) deviceName = type;
+
+            std::string target = message.getString("target", "coss");
+            int frequency = message.getInt("frequncy", 60 * 1000);
+            if(frequency<10) frequency = 10;
+            if(target.empty()) {
+                FailPRspMsg(rsp, "No message return target.");
+                return true;
+            }
+            auto* d = loadLocalDevice(deviceName, type);
+            if(d==nullptr){
+                FailPRspMsgFmt(rsp, "Device %s load failed.", deviceName.c_str());
+                return false;
+            }
+
+            if(!d->startLocal(target, frequency, message)){
+                FailPRspMsgFmt(rsp, "Device %s start failed for target.", target.c_str());
+                return false;
+            }
+            //发送上线消息
+            MAKE_DEVICE_EVENT(d, msg, "devOnline");
+            REPORT_DEVICE_EVENT(d, msg);
+            OkPRspMsgFmt(rsp, "Device %s load ok", deviceName.c_str(), target.c_str());
+            return true;
+        };
+
+        bool startLocal(const std::string& deviceName, const std::string& type,
+                const std::string& target, int frequency, const qlibc::QData& data = qlibc::QData()) {
+            RECURSIVE_LOCK(operate_mutex_);
+            //目前暂时默认发向coss
+            if(type.empty()) {
+                QWarn("No device type set.");
+                return false;
+            }
+
+            if(frequency<10) frequency = 10;
+            if(target.empty()) {
+                QWarn("No message return target.");
+                return true;
+            }
+            auto* d = loadLocalDevice(deviceName.empty()?type:deviceName, type);
+            if(d==nullptr){
+                QWarn("Device %s load failed.", deviceName.c_str());
+                return false;
+            }
+
+            if(!d->startLocal(target, frequency, data)){
+                QWarn("Device %s start failed for target.", target.c_str());
+                return false;
+            }
+            //发送上线消息
+            MAKE_DEVICE_EVENT(d, msg, "devOnline");
+            REPORT_DEVICE_EVENT(d, msg);
+            QMark("Device %s load ok", deviceName.c_str(), target.c_str());
+            return true;
+        };
+
+        bool stopLocal(qlibc::QData &message, qlibc::QData *rsp) {
+            RECURSIVE_LOCK(operate_mutex_);
+            //
+            std::string device = message.getString("device_id");
+            auto d = mDevices.findObject(device);
+            if(d== nullptr){
+                FailPRspMsgFmt(rsp, "Target %s not exists.", device.c_str());
+            } else {
+                d->stopLocal();
+                //发送下线消息
+                MAKE_DEVICE_EVENT(d, msg, "devOffline");
+                REPORT_DEVICE_EVENT(d, msg);
+                OkPRspMsg(rsp, "ok");
+            }
+            return true;
+        };
+
+        bool stopLocal(const std::string& deviceName) {
+            RECURSIVE_LOCK(operate_mutex_);
+            //
+            auto d = mDevices.findObject(deviceName);
+            if(d== nullptr){
+                QWarn("Target %s not exists.", deviceName.c_str());
+            } else {
+                d->stopLocal();
+                MAKE_DEVICE_EVENT(d, msg, "devOffline");
+                REPORT_DEVICE_EVENT(d, msg);
+                QMark( "Device %s stop ok", deviceName.c_str());
+            }
+            return true;
+        };
+
+        void loadDeviceConfigs(const std::string& basePath) {
+            RECURSIVE_LOCK(operate_mutex_);
+            QStringList devMods;
+            FileUtils::listFiles(basePath, "json", devMods);
+            for(auto& f : devMods){
+                auto* dm = operator_.getBlankMessage<qlibc::QData>();
+                dm->loadFromFile(f);
+                //加载文件
+                mDeviceModes.appendNew(FileUtils::fileNameWithoutExt(f), dm);
+            }
+        }
+
+        bool regiserDeviceType(const std::string& devType, const jedge::DevCreator& creator) {
+            RECURSIVE_LOCK(operate_mutex_);
+            if(devType.empty() || !mDeviceModes.existObject(devType) ) {
+                QWarn("Device type %s empty or mode not exists!", devType.c_str());
+                return false;
+            }
+            mDeviceCreators.appendNew(devType, new DevCreator(creator));
+            return true;
+        }
+
+        bool OnDeviceCreated(const std::string& devType,  const jedge::DeviceHandlerSettor& settor){
+            RECURSIVE_LOCK(operate_mutex_);
+            if(devType.empty() || !mDeviceModes.existObject(devType) || !mDeviceCreators.existObject(devType)) {
+                QWarn("Device type %s empty or mode/creator not exists!", devType.c_str());
+                return false;
+            }
+            mDeviceHandlerSettors.appendNew(devType, new DeviceHandlerSettor(settor));
+            return true;
+        }
+    };
+}
+
+#endif //INC_0_LIBDEVCPP_SYSDEVICESERVICE_H

+ 578 - 0
app/src/main/cpp/inc/exlibv/JAExObjectV.h

@@ -0,0 +1,578 @@
+//
+// Created by Ht on 2022/10/18.
+//
+
+#ifndef IOT_EDGE_VDALNEW_JAEXOBJECTV_H
+#define IOT_EDGE_VDALNEW_JAEXOBJECTV_H
+
+#include <qlibc/QLogger.h>
+#include <qlibc/plugin/QPluginEntry.h>
+#include <qlibc/QBufferManager.h>
+#include <exlib/QJAServiceEntry.h>
+#include <exlib/QJAMgUtils.h>
+#include <memory>
+#include <qlibc/QByteTransfer.h>
+#include <qlibc/QFlowController.h>
+#include "serial/SerialPort.h"
+#include "serial/SerialIOGate.h"
+#include "jedp/JEDPAnalyzer.h"
+
+namespace jedge {
+
+    static const char* sval_cls_name_serial_port = "serialPort";
+    static const char* sval_class_name_jedp_ = "jedp";
+    static const int ival_default_serial_gap_ = 800;    //默认800ms
+
+    class QJAJedpTranser : public ja::JAObject,
+                           public qlibc::QByteTransfer {
+
+    protected:
+        std::string       rule_;
+        JEDPAnalyzer*     analyzer_ = nullptr;
+        JEDPAnalyzer*     analyzer_decoder_ = nullptr;       //部分可能是编解码分开定义
+
+    public:
+        explicit QJAJedpTranser(ja::JAContext &ctx, const qlibc::QData &data) :
+                JAObject(ctx, data, sval_class_name_jedp_) {
+        }
+
+        ~QJAJedpTranser() override {
+            delete analyzer_;
+            delete analyzer_decoder_;
+        }
+
+        const std::string& getUriKey() override {
+            auto* targetAnalyzer = analyzer_decoder_== nullptr? analyzer_: analyzer_decoder_;
+            if(targetAnalyzer== nullptr) return rule_;  //通常不会发生
+            return targetAnalyzer->getDataBaseKey();
+        }
+
+        void deTransferBytes(unsigned char *data, uint16_t len, QRByte &newbuff, size_t &newlen) override {
+            auto* targetAnalyzer = analyzer_decoder_== nullptr? analyzer_: analyzer_decoder_;
+            if(targetAnalyzer== nullptr) return;
+            if(!targetAnalyzer->deTransferBytes(data, len ,newbuff, newlen)) {
+                newlen = 0;
+            }
+        }
+
+        bool decodeMessage(QData &data, QByte *buff, uint16_t len) override {
+            auto* targetAnalyzer = analyzer_decoder_== nullptr? analyzer_: analyzer_decoder_;
+            if(targetAnalyzer== nullptr) return false;
+            return targetAnalyzer->buildJRJsonMessage(data, buff, len);
+        }
+
+        bool encodeMessage(QData &data, QByte **buff, size_t &len) override {
+            if(analyzer_== nullptr) return false;
+            return analyzer_->encodeJRJsonMessage(data, buff, len);
+        }
+
+        //BasePath::
+        //  jedpobj.loadRule ${@context.getCacheDir}/rules/bluetooch.json ${@context.getCacheDir}/rules/bluetooch_rsp.json
+        //  jedpobj.loadRule --ruleName BLE_QJ
+        bool loadRule(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result) {
+            auto fn = param.getParam(0);
+            rule_ = param.getString("ruleName");
+            if(fn.empty()) {
+                if(rule_.empty()) {
+                    QWarn("Empty rule, no rule loaded.");
+                    return false;
+                }
+                fn = MgServer(s.getContext()).getSubCacheDirFullPath("vdal/rule", (rule_ + ".json").c_str(), nullptr);
+            }
+            QData data;
+            data.loadFromFile(fn);
+            if (data.isEmpty()) {
+                QWarn("Empty rule, no rule loaded.");
+                return false;
+            }
+            data.putString(vkey_def_fn , fn);
+            if(analyzer_!= nullptr)
+                delete analyzer_;
+            //构建一个Analyzer
+            analyzer_ = new JEDPAnalyzer(data);
+            if(!analyzer_->isValid()) {
+                QWarn("Invalid rule, no rule loaded : %s", fn.c_str());
+                delete (analyzer_);
+                analyzer_ = nullptr;
+                return false;
+            }
+            if(rule_.empty())
+                rule_ = FileUtils::fileNameWithoutExt(fn);
+            QHLog("jedp obj %s is loaded rule %s ...", name_.c_str(), rule_.c_str());
+            auto fnDe = param.getParam(1);
+            if(fnDe.empty())
+                fnDe = MgServer(s.getContext()).getSubCacheDirFullPath("vdal/rule", (rule_ + "_RSP.json").c_str(), nullptr);
+            data.loadFromFile(fnDe);
+            if (!data.isEmpty()) {
+                data.putString(vkey_def_fn , fn);
+                if (analyzer_decoder_ != nullptr)
+                    delete analyzer_decoder_;
+                //构建一个Analyzer
+                analyzer_decoder_ = new JEDPAnalyzer(data);
+                if (!analyzer_decoder_->isValid()) {
+                    QWarn("Invalid rule, no rule loaded : %s", fn.c_str());
+                    delete (analyzer_decoder_);
+                    analyzer_decoder_ = nullptr;
+                } else
+                    QEMark("jedp encode obj %s is loaded rule %s_RSP ...", name_.c_str(), rule_.c_str());
+            }
+            return true;
+        }
+
+        //使用方法:
+        //  将serial等使用buffer的对象,通过调用BufferHolder对象去获取其对象指针,然后访问其buffer对象
+        //将一个json object对象,转化成一个全局buffer中,stack的bufferId中存放这个buffer的id值
+        //可发送出去
+        //jedpObj.loadRule ${@context.getCacheDir}/rules/bluetooth
+        // ...
+        //jedpObj.makeMsg $${bufferId} ${msg} --key value   //bufferId存放在stack中的动态变量,是动态变化的
+        //
+        bool makeMsg(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result) {
+            if(analyzer_== nullptr) {
+                QWarn("Empty rule.");
+                return false;
+            }
+            auto* buffId = s.getStoredValueTarget(param,0);
+            if(buffId== nullptr) {
+                QWarn("Invalid message stored target !");
+                return false;
+            }
+            *buffId = StringUtils::randomChars(5);
+            auto objVal = s.getValueRefParam(param,1);
+            if(!objVal.isObject())
+                param.copyDataFromValue(objVal);
+            param.clearDataStartWith("@");
+            QWarn("jedp obj %s is starting ...", name_.c_str());
+            auto targetBuff = getBlankBuffer();
+            //将qlibc::QData的内容编码到byte的buffer中
+            //如果buffer超标,则提示出错,丢弃消息
+            QByte* buff = nullptr;
+            if(!analyzer_->encodeJRJsonMessage(param, &buff, targetBuff->buff_size_)) {
+                releaseBuffer(targetBuff);
+                QWarn("Fail to transfer message %s:%s ", name_.c_str(), param.toJSONString().c_str());
+                return true;
+            }
+            memcpy(targetBuff->buff_, buff, targetBuff->buff_size_);
+            delete[] buff;
+            pushBufferWithId(buffId->asString(), targetBuff);
+            return true;
+        }
+
+        //使用方法:
+        //  从一个buffer中读取消息: serial在收到消息后,自动调用jedp的代码对消息进行解析。
+        //jedpobj.loadRule ${@context.getCacheDir}/rules/bluetooch
+        //jedpObj.loadMsg  $${msg} ${bufferId} --transfer/t
+        bool loadMsg(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result) {
+            if(analyzer_== nullptr) {
+                QWarn("Empty rule.");
+                return false;
+            }
+            auto* target = s.getStoredValueTarget(param, 0, true);
+            auto* buffId = s.getStoredValueTarget(param,1);
+            *buffId = StringUtils::randomChars(5);
+            QLog("loadMsg from buffer %s.%s ...", name_.c_str(), buffId->asCString());
+            auto buffer = getBlankBuffer();
+            auto* msg = MgServer(s.getContext()).getBlankMessage();
+            analyzer_->buildJRJsonMessage(*msg, buffer->buff_, buffer->buff_size_, param.getBool("t,transfer",true));
+            if(target!= nullptr)
+                *target = msg->asValueConst();
+            JAServer(s.getContext()).releaseMessage(msg);
+            return true;
+        }
+
+    };
+
+    //如何处理buffer的handler
+
+    class JE_API BufferContactor {
+        static const int DATA_IDX = 6;
+        static const int LEN_IDX = 1;
+        static const int CMD_IDX = 3;
+        static const int SAR_IDX = 5;
+        static const int BUFF_SIZE = 4096;
+
+    protected:
+        QByte result_buff_[BUFF_SIZE]{};
+        uint16_t buff_len = 0;
+        uint16_t data_len = 0;
+        std::shared_ptr<qlibc::QByteTransfer> decoder_;
+        std::mutex op_mutex_;
+    public:
+        /**
+    * 【处理逻辑】
+    * 从串口获取的bytes数据包,首先进行
+    * step1:转义
+    * step2:根据sar_enum字段判断该数据包是否是个完整的包
+    * step3:
+    * 1)sar_enum = 00 完整的包,直接交给JEDP;
+    * 2)sar_enum = 01 代表第一个数据包,截取data字段放入字符串数组Q[]中;
+    * 3)sar_enum = 02 代表中间数据包,同上步;
+    * 4)sar_enum = 03 代表最后一个数据包,截取data字段Qn,并依次将Q[]中的字符串拼接,然后拼上Qn,清空Q[],最后构造出头尾发送给JEDP
+    * */
+        // "@field":  ["start","len(cmd,sar_enum,data)", "cmd", "sar_enum","data","end"],
+        //  "@bitlen": [8,       16,                       16,    8,        0,     8],*/
+        //   byteindex  0         1                         3     5         6      6+data,len.
+
+        const QByte* handleBuffer(const std::string& serial_type, const uint8_t *srcbuff, int32_t srclen, size_t& newlen) {
+            //转义规则说明:
+            //按照0x01 0x03为首尾、 0x02为转义前置符号,
+            //每个消息段00开头,表示为单各分段数据消息
+            //01-03开头为多个分段消息
+            //  01第一个分段
+            //  02中间分段,多个
+            //  03最后分段
+            //*
+            size_t len = 0;
+            const QByte *buff, *rebuff;
+
+            QRByte transferred_buff;
+            //转义
+            if(decoder_ != nullptr)
+                decoder_->deTransferBytes((QByte*)srcbuff, len, transferred_buff, newlen);
+            if(transferred_buff != nullptr) {   //转义成功,使用转义后的数据
+                buff = transferred_buff.get();
+            } else { //直接使用源
+                buff = srcbuff;
+                len = srclen;
+            }
+            std::unique_lock<std::mutex> locker(op_mutex_); //操作互斥
+            size_t msg_datalen = 0;
+            if(len<SAR_IDX+1) return nullptr;   //消息分段长度为0,不处理
+            switch (*(buff+SAR_IDX)){
+                case 0x00:  //单分段数据消息
+                    newlen = len;
+                    rebuff = buff;
+                    break;
+                case 0x01:  //首段数据
+                    memcpy(result_buff_, buff, len);//全拷贝
+                    buff_len = len;
+                    BYTES_TO_WORD_BE(buff + LEN_IDX, data_len);
+                    rebuff = nullptr; //无buffer返回
+                    break;
+                case 0x02:  //次段数据
+                BYTES_TO_WORD_BE(buff + LEN_IDX, msg_datalen);
+                    memcpy(result_buff_ + buff_len, buff + DATA_IDX, msg_datalen);//仅拷贝数据段
+                    buff_len += msg_datalen;
+                    data_len += msg_datalen;
+                    rebuff = nullptr; //无buffer返回
+                    break;
+                case 0x03:
+                BYTES_TO_WORD_BE(buff + LEN_IDX, msg_datalen);
+                    memcpy(result_buff_ + buff_len, buff + DATA_IDX, msg_datalen);//仅拷贝数据段
+                    buff_len += msg_datalen;
+                    data_len += msg_datalen;
+                    //设置数据段长度
+                    BYTES_FROM_WORD_BE(result_buff_ + LEN_IDX, data_len);
+                    //设置buff长度
+                    newlen = buff_len;
+                    //设置尾数据,
+                    rebuff = result_buff_; //返回缓存数据
+                    buff_len = 0;
+                    break;
+                default:    //reserved, 无效数据
+                    QLog("Using reserved value %03X on message : %s", *buff, QHexStr(buff, len));
+                    rebuff = nullptr; //无buffer返回
+                    break;
+            }
+            return rebuff;
+        }
+
+        void setDecoder(std::shared_ptr<qlibc::QByteTransfer> &decoder) {
+            decoder_ = decoder;
+        }
+    };
+
+    class JASerialPort : public ja::JAObject ,
+                         public jedge::SerialIOHolderInterface,
+                         public UriHandlerHolder {
+    protected:
+        std::shared_ptr<jedge::SerialPort> mSerialPort;
+        ja::JARInstance                    mCallbackInstance;
+        std::string   portName;
+        QJAMgServer&  holder_;
+        qlibc::QFlowController flowController_;
+        std::shared_ptr<qlibc::QByteTransfer> decoder;
+        std::shared_ptr<qlibc::QByteTransfer> encoder;
+        BufferContactor preProcessor;
+        std::mutex      mutex_;
+
+    public:
+        explicit JASerialPort(ja::JAContext& context, const qlibc::QData &data) :
+                JAObject(context, data, sval_cls_name_serial_port) ,
+                UriHandlerHolder(dynamic_cast<ChannelOperator&>(context)) ,
+                holder_(dynamic_cast<QJAMgServer&>(context)),
+                flowController_(holder_.threadPoolRef(), ival_default_serial_gap_) {
+            resetClass(sval_cls_name_serial_port);
+        }
+
+        ~JASerialPort() override {
+            //释放相关客户端资源
+            releaseUdHandlers();
+            if(mSerialPort!=nullptr) {
+                jedge::SerialIOGate::closeSerial(portName);
+                mSerialPort = nullptr;
+            }
+            QLog("Https client %s unloaded", name_.c_str());
+        }
+
+        void setByteTransfer(std::shared_ptr<qlibc::QByteTransfer> jedp) {
+            decoder = (std::move(jedp));
+            preProcessor.setDecoder(decoder);
+        }
+
+        void onSerialDataRead(const string &port, QByte *data, uint16_t len) override {
+            //解码、并调用相关的rule
+            QDLog("Serial data read as %s", NumberUtils::bytesToHexStr(data, len).c_str());
+            QRByte transferred_buff;        //auomatically released.
+            size_t newlen = 0;
+            //转义
+            if(decoder != nullptr)
+                decoder->deTransferBytes(data, len, transferred_buff, newlen);
+            if(transferred_buff != nullptr) {   //转义成功,使用转义后的数据
+                data = transferred_buff.get();
+                len = newlen;
+            }
+            {
+                //避免数据重复进入
+                SINGLE_LOCK(mutex_);
+                const auto *relBuff = preProcessor.handleBuffer("name", data, len, newlen);
+                if (relBuff == nullptr)
+                    return;
+                QWarn("RECV HEX-String:%s", NumberUtils::bytesToHexStr(relBuff, newlen).c_str());
+            }
+            qlibc::QData* rmsg = holder_.getBlankMessage();
+            //jedp转义
+            if(decoder != nullptr) {
+                //转义到json结构
+                if(!decoder->decodeMessage(*rmsg, data, len)) {
+                    QWarn("Fail decoding message : %s ", NumberUtils::bytesToHexStr(data, len).c_str());
+                    return;
+                }
+            }
+
+            auto s = self();
+            //响应消息函数
+            holder_.threadPool().enqueue([this, s, rmsg]() {
+                //handleSerialMessage(srcPort, rmsg);
+                //触发对service的调用
+                QHLog("Command decoded: \n%s",rmsg->toJSONString(true).c_str());
+                if(decoder==nullptr) return;    //串口默认响应函数?
+                auto subCmd = rmsg->getObjFmtString(decoder->getUriKey());
+
+                //触发handler回调函数,如果uri未定义、则调用default,调用serial中的uri对应的回调函数
+                auto handler = ud_handlers_.findObject("/"+subCmd);
+                if(handler!=nullptr) {
+                    handler->operator()(holder_, subCmd, *rmsg);
+                } else {
+                    if(mCallbackInstance!=nullptr) {
+                        rmsg->putString(ja::vkey_def_handler_name_, subCmd);
+                        mCallbackInstance->runJAScript(ja::vkey_handler_channel_,nullptr,*rmsg);
+                    }
+                }
+                //default是调用serial的默认uri
+                holder_.releaseMessage(rmsg);
+            });
+        }
+
+        void onSerialStart() override {
+            //初始化回调函数
+            handleMessage("/serialStart", *self());     //触发对特定函数的回调调用
+        }
+
+        bool writeSerialRawData(QByte *buff, int32_t len) override {
+            return mSerialPort!= nullptr && mSerialPort->writeData(buff, len);
+        }
+
+        //obj.handler /abc/uri ja_block
+        bool handler(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *result) {
+            std::string uri = param.getParam(0);
+            if(uri.empty()) return true;
+            if(uri[0]!='/') uri.insert(0, "/");
+            auto block = param.getParam(1);
+            auto* service = &s.getInstance();
+            auto shandler = copyInstanceHandler(s, block, uri);
+            addHandler(uri, [service, shandler](ChannelOperator &o,
+                                                const std::string &u, qlibc::QData &m) -> bool {
+                m.putString(ja::vkey_def_handler_name_, u);
+                return service->runJAScript(shandler, m);
+            });
+            return true;
+        }
+
+        //添加open
+        //obj.open serialName --jedp BLE_QJ --rate 115200
+        bool open(ja::JAStack& stack, qlibc::JCArgNode &param, qlibc::QData *result) {
+            portName = param.getParam(0);
+            auto rate = param.getInt("rate", 115200);
+            setString("port", portName);
+            setInt("rate", rate);
+            if(portName.empty()) {
+                QWarn("open serial with empty port");
+                return false;
+            }
+            QStringList comNameList;
+            SerialIOGate::scanForTargetComPorts(comNameList, portName);
+            bool initOk = false;
+            for(const auto& s : comNameList) { // NOLINT(altera-unroll-loops)
+                auto ref = self();
+                auto ioHolder = std::dynamic_pointer_cast<SerialIOHolderInterface>(ref);
+                if (!SerialIOGate::openSerial(ioHolder, s, portName))
+                    QErr("Failed to open serial device %s.", s.c_str());
+                else {
+                    initOk = true;
+                    mSerialPort = SerialIOGate::getGateInstance()->getSerialPort(s);
+                }
+            }
+            auto jedp = param.getString("jedp");
+            if(!jedp.empty()) {
+                auto JedpObj = stack.findContextObject(jedp);
+                if(JedpObj!=nullptr) {
+                    auto trans = std::dynamic_pointer_cast<qlibc::QByteTransfer>(JedpObj);
+                    if (trans != nullptr) {
+                        decoder = trans;
+                        QHLog("DecoderJedp of %s is set to %s", name_.c_str(), jedp.c_str());
+                    }
+                }
+            }
+            if(mSerialPort!=nullptr){
+                auto inst = stack.getInstance().self();
+                mCallbackInstance = std::dynamic_pointer_cast<ja::JAInstance>(inst);
+            }
+            return initOk;
+        }
+
+        //serial.close
+        bool close(qlibc::JCArgNode &param, qlibc::QData *result) {
+            if(mSerialPort!=nullptr) {
+                mSerialPort->closeSerialPort();
+                mSerialPort=nullptr;
+            }
+            return true;
+        }
+
+        //srObj.setFlowControl 500
+        bool setFlowControl(qlibc::JCArgNode &param, qlibc::QData *re) {
+            auto flowGap = param.getParamAsInt(0);
+            if(flowGap<10) flowGap = 10;
+            flowController_.updateTimeGap(flowGap);
+            QHLog("Flow controller gap set to %d", flowGap);
+            return true;
+        }
+
+        //srObj.setEncoderJedp encoderJedp
+        bool setEncoderJedp(ja::JAStack& s,qlibc::JCArgNode &param, qlibc::QData *re) {
+            auto jedp = param.getParam(0);
+            if(!jedp.empty()) {
+                auto JedpObj = s.findContextObject(jedp);
+                if(JedpObj!=nullptr) {
+                    auto trans = std::dynamic_pointer_cast<qlibc::QByteTransfer>(JedpObj);
+                    if (trans != nullptr) {
+                        decoder = trans;
+                        QHLog("EncoderJedp of %s is set to %s", name_.c_str(), jedp.c_str());
+                    }
+                }
+            }
+            return true;
+        }
+
+        //srObj.setCallbackInstance service
+        bool setMsgHandle(qlibc::JCArgNode &param, qlibc::QData *re) {
+            auto instanceName = param.getParam(0);
+            if(!instanceName.empty()) {
+                auto obj = holder_.findObject(instanceName);
+                auto inst = std::dynamic_pointer_cast<ja::JAInstance>(obj);
+                if(inst!=nullptr) {
+                    mCallbackInstance = inst;
+                    QHLog("Flow controller gap set to %s", instanceName.c_str());
+                }
+            }
+            return true;
+        }
+
+        //serial.writeHex 'EF 98'   ,是否自动加转义和分段
+        //serial.writeHex '0xEF98'  ,两种格式
+        bool writeHex(qlibc::JCArgNode &param, qlibc::QData *re) {
+            if(mSerialPort==nullptr) {
+                MkPRsp(re, 501, "Not open serial.");
+                return true;
+            }
+            auto data = param.getParam(0);
+            if(!StringUtils::isHexString(data)) {
+                MkPRsp(re, 501, StringUtils::formatString("Invalid hex data string : %s", data.c_str()));
+                return true;
+            }
+            QByte* buff = nullptr;
+            auto size = NumberUtils::hexStrToBytes(data, &buff);
+            //写入串口
+            flowController_.call([this, buff, size]() {
+                QEMark("Write Hex : %s", NumberUtils::bytesToHexStr(buff,size).c_str());
+                mSerialPort->writeData(buff, (int)size);
+                delete buff;
+            });
+            MkPRsp(re, 200, "OK[Serial write].");
+            return true;
+        }
+
+        bool writeMsg(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *re) {
+            if(mSerialPort==nullptr) {
+                MkPRsp(re, 501, "Not open serial.");
+                return true;
+            }
+            auto* data = s.getStoredValueTarget(param, 0);
+            if(data == nullptr || !data->isObject()) {
+                MkPRsp(re, 501, "Nothing or Invalid Object to write.");
+                return true;
+            }
+            //调用object转义到Buffer,再写入到buffer中
+            auto* msg = holder_.getBlankMessage();
+            msg->setInitValue(*data);
+            //jedp转义
+            auto en = encoder;
+            if(en==nullptr) en = decoder;
+            if(en != nullptr) {
+                //转义到json结构
+                size_t len;
+                QByte *buff = nullptr;
+                if(!en->encodeMessage( *msg, &buff, len)) {
+                    QWarn("Fail encoding message : %s ", NumberUtils::bytesToHexStr(buff, len).c_str());
+                    return true;
+                }
+                if(buff!= nullptr) {
+                    //写入串口,流控,意味着如果写入速度过快时,将被做流量控制
+                    flowController_.call([this, buff, len]() {
+                        QEMark("Write Hex : %s", NumberUtils::bytesToHexStr(buff, len).c_str());
+                        mSerialPort->writeData(buff, (int) len);
+                        delete[] buff;
+                    });
+                }
+                MkPRsp(re, 200, "OK[Serial write].");
+            }
+            return true;
+        }
+
+        //serial.setJedp JedpObjName
+        bool setJedp(ja::JAStack& s, qlibc::JCArgNode &param, qlibc::QData *re) {
+            auto jedp = param.getParam(1);
+            if(!jedp.empty()) {
+                auto JedpObj = s.findContextObject(jedp);
+                if(JedpObj!=nullptr) {
+                    auto trans = std::dynamic_pointer_cast<qlibc::QByteTransfer>(JedpObj);
+                    if (trans != nullptr)
+                        decoder = trans;
+                }
+            }
+            return true;
+        }
+
+        bool isOpen(qlibc::JCArgNode &param, qlibc::QData *result) {
+            if(mSerialPort != nullptr) {
+                if(result!= nullptr)
+                    result->setBool(ja::ja_return_val_, true);
+            }
+            MkPRsp(result, 200, "ok");
+            return true;
+        }
+    };
+}
+
+#endif //IOT_EDGE_VDALNEW_JAEXOBJECTV_H

+ 43 - 0
app/src/main/cpp/inc/exlibv/JAExUtil.h

@@ -0,0 +1,43 @@
+//
+// Created by Ht on 2022/11/10.
+//
+
+#ifndef IOT_EDGE_VDALNEW_JAEXUTIL_H
+#define IOT_EDGE_VDALNEW_JAEXUTIL_H
+
+#include <qlibc/qlibc.h>
+
+namespace ja {
+    class JE_API JAExUtil {
+    public:
+
+        static void clearTypePrefix (std::string& dest) {
+            if(dest.empty() || dest == "$null") {
+                dest.clear();
+                return;
+            }
+            //查找
+            auto next = dest.find("__$");
+            auto size = dest.size();
+            while(next!=std::string::npos && next < size-1) {
+                auto t = dest[next+3];
+                switch (t) {
+                    case 'n':   //数字  __$n
+                    case 'b':   //布尔
+                    case 'f':   //浮点
+                    case 's':   //字符串
+                    case 'o':   //对象
+                        dest.erase(next, 4);
+                        size = dest.size();
+                        break;
+                    default:    //不做改变
+                        break;
+                }
+                if(next>=size) break;
+                next = dest.find("__$", next+1);
+            }
+        }
+    };
+
+}
+#endif //IOT_EDGE_VDALNEW_JAEXUTIL_H

+ 84 - 0
app/src/main/cpp/inc/exlibv/JedpUtil.h

@@ -0,0 +1,84 @@
+//
+// Created by Ht on 2022/10/18.
+//
+
+#ifndef IOT_EDGE_VDALNEW_SERIALUTIL_H
+#define IOT_EDGE_VDALNEW_SERIALUTIL_H
+
+#include "JAExObjectV.h"
+
+namespace jedge {
+
+    class JE_API SerialUtil {
+    public:
+        static void loadInnerClasses(QJAMgServer &server) {
+            auto cls = server.Class(sval_class_name_jedp_);
+            bindJAClassCreator(cls, QJAJedpTranser);
+            JAUDS_DEFINE_CLASS_METHOD_WITH_STACK(server, cls, QJAJedpTranser, makeMsg);
+            JAUDS_DEFINE_CLASS_METHOD_WITH_STACK(server, cls, QJAJedpTranser, loadMsg);
+            JAUDS_DEFINE_CLASS_METHOD_WITH_STACK(server, cls, QJAJedpTranser, loadRule);
+
+            //创建一个Jedp对象
+            auto stack_ = server.findClass("stack");
+
+            //查看当前可用的rule情况
+            stack_->Method("rules", [&server] JAMethodConst(s,o,qm,sp) {
+                FLogR("Run rule load command as : loadJedp <file>[.json]. Available belows:");
+                QStringList fl;
+                auto base = server.getSubCacheDirFullPath("vdal/rule",nullptr);
+                auto bsize= base.size()+1;
+                FileUtils::listFiles(base , "json", fl);
+                auto re = s.findObject("rsp");
+                for (const auto &f :fl) // NOLINT(altera-unroll-loops)
+                    FLogR("\t->%s%s%s", qlog_HighLight, f.substr(bsize).c_str(), qlog_LOG);
+                FLogR("==END");
+                if(re!=nullptr) {
+                    Json::Value files;
+                    for (const auto &f :fl) // NOLINT(altera-unroll-loops)
+                        files.append(f.substr(bsize));
+                    OkRsp(*re);
+                    re->put("files", files);
+                }
+                return true;
+            });
+
+            //loadJedp ruleName [objName, [ruleFilePath]]
+            //创建一个rule对象,并加载某路径
+            stack_->Method("loadJedp", [&server] JAMethodConst(s,o,qm,sp) {
+                PREPARE_PARAM(param, sp);
+                auto ruleName = param.getParam(0);
+                auto objName = param.getParam(1, ruleName);
+                param.putString("ruleName", ruleName);
+                //相对路径
+                auto rulePath = param.getParam(2);
+                param.clearDataStartWith("@");
+                if(rulePath.empty()) {
+                    rulePath = server.getSubCacheDirFullPath("vdal/rule", (objName + ".json").c_str(), nullptr);
+                    param.insertParamAt(0, rulePath.c_str(), nullptr);
+                }
+                qlibc::QData config;
+                config.copyDataNotStartWith(param, '@');
+                auto* jedp = new QJAJedpTranser(s.getContext(), config);
+                jedp->setName(objName);
+                if(!jedp->loadRule(s, param, nullptr)) {
+                    delete jedp;
+                    QWarn("Fail to load jedp %s : %s", objName.c_str(), rulePath.c_str());
+                    return false;
+                }
+                s.getContext().Object(objName, jedp);    //首先占用缓存。如果http服务已经存在,则覆盖之、前序http服务器被释放
+                QLog("create a default jedp server ok named %s as Rule : %s", objName.c_str(), ruleName.c_str());
+                return true;
+            });
+        }
+
+        static void releaseClasses(QJAMgServer &server) {
+            server.releaseClass(sval_class_name_jedp_);
+            server.removeClassMethod("stack", "loadJedp");
+            server.removeClassMethod("stack", "rules");
+        }
+    };
+
+
+}
+
+#endif //IOT_EDGE_VDALNEW_SERIALUTIL_H

+ 87 - 0
app/src/main/cpp/inc/exlibv/SerialUtil.h

@@ -0,0 +1,87 @@
+//
+// Created by Ht on 2022/10/18.
+//
+
+#ifndef IOT_EDGE_VDALNEW_SERIALUTIL_H
+#define IOT_EDGE_VDALNEW_SERIALUTIL_H
+
+#include "JAExObjectV.h"
+
+namespace jedge {
+
+    class JE_API SerialUtil {
+    public:
+        static void loadInnerClasses(QJAMgServer &server) {
+            auto clsStack = server.findClass("stack");
+            //创建一个serial客户端
+            //格式启动一个 //serial testIntf
+            //openSerial serialName BLE_QJ [objName] --rate 115200
+            clsStack->Method("openSerial", [&server]JAMethodConst(s,o,qm,sp) {
+                PREPARE_PARAM(param, sp);
+                auto serialPort = param.getParam(0);
+                if(serialPort.empty()) {
+                    QWarn("emtpy serial port.");
+                    return false;   //stop running else code.
+                }
+                auto JedpRule = param.getParam(1);
+                auto JedpObj = s.findContextObject(JedpRule);
+                auto trans = std::dynamic_pointer_cast<qlibc::QByteTransfer>(JedpObj);
+                if(JedpRule.empty() || trans==nullptr) {
+                    QWarn("No valid jedp rule set.");
+                    return false;
+                }
+                auto obj_name = param.getParam(2, "serialObj");
+
+                //创建一个serial接口操作对象
+                auto* data = server.getBlankMessage();
+                param.setName(obj_name);
+                param.setString("class", sval_cls_name_serial_port);
+                param.setString("port", serialPort);
+                data->copyDataNotStartWith(param, "@");
+                s.getContext().clearObjectRef(obj_name);
+                auto* port = new JASerialPort(s.getContext(), *data);
+                port->setByteTransfer(trans);
+                if(!port->open(s, param, nullptr)) {
+                    delete port;
+                    QWarn("Fail to open serial port %s", serialPort.c_str());
+                    return false;
+                }
+                s.getContext().Object(obj_name, port);
+                QLog("create a serial client %s ok", obj_name.c_str());
+                //创建一个默认对象
+                server.releaseMessage(data);
+                return true;
+            });
+
+            auto seiral_port_cls = server.Class(sval_cls_name_serial_port, "object", false);
+            bindJAClassCreator(seiral_port_cls, JASerialPort);
+
+            // serialObj.open ttyUSB0 --rate 115200 --jedp BLE_QJ
+            // serialObj.close
+            // serialObj.writeHex '01 FF 33 03'
+            // serialObj.writeMsg ${myMessage}
+            // serialObj.handler /uri 'handler code'
+            // serialObj.handler /uri 'handler code'
+            JAUDS_DEFINE_CLASS_METHOD_WITH_STACK(server, seiral_port_cls, JASerialPort, open);
+            JAUDS_DEFINE_CLASS_METHOD(server, seiral_port_cls, JASerialPort, close);
+            JAUDS_DEFINE_CLASS_METHOD(server, seiral_port_cls, JASerialPort, writeHex);
+            JAUDS_DEFINE_CLASS_METHOD(server, seiral_port_cls, JASerialPort, setFlowControl);
+            JAUDS_DEFINE_CLASS_METHOD(server, seiral_port_cls, JASerialPort, setMsgHandle);
+            JAUDS_DEFINE_CLASS_METHOD_WITH_STACK(server, seiral_port_cls, JASerialPort, setEncoderJedp);
+            JAUDS_DEFINE_CLASS_METHOD_WITH_STACK(server, seiral_port_cls, JASerialPort, setJedp);
+            JAUDS_DEFINE_CLASS_METHOD_WITH_STACK(server, seiral_port_cls, JASerialPort, writeMsg);
+            JAUDS_DEFINE_CLASS_METHOD_WITH_STACK(server, seiral_port_cls, JASerialPort, handler);
+            // ${@serialObj.isOpen} 函数返回值
+            JAUDS_DEFINE_CLASS_FUNCTION(server, seiral_port_cls, JASerialPort, isOpen);
+        }
+
+        static void releaseClasses(QJAMgServer &server) {
+            server.releaseClass(sval_cls_name_serial_port);
+            server.removeClassMethod("stack", "openSerial");
+        }
+    };
+
+
+}
+
+#endif //IOT_EDGE_VDALNEW_SERIALUTIL_H

+ 403 - 0
app/src/main/cpp/inc/gafasl/QGAActionObjects.h

@@ -0,0 +1,403 @@
+//
+// Created by Ht on 2022/8/28.
+//
+
+#ifndef INC_1_LIBDEVCPP_QGAACTIONOBJECTS_H
+#define INC_1_LIBDEVCPP_QGAACTIONOBJECTS_H
+
+#include <exlib/http/QHttpSSLClient.h>
+#include <exlib/QJAService.h>
+#include <exlib/QMqttClient.h>
+
+#include <utility>
+
+#include "QGABaseObject.h"
+#include "QGaControllerUtil.h"
+#include "QGaVarFuncs.h"
+
+namespace jedge {
+
+    static const char func_sign_ = '@';
+    static const char* cache_auto_save_ = "ac";
+    static const char* vkey_channel_call_ = "$call";
+    //可以是 http/https/mgbus/mqtt/cache/log/return
+    //设计多种channel通道,并将这些通道的发送函数记录进去。在DataPool中封装这些内容。
+
+
+    class QGaDataAction;
+
+    class JE_API QGADataChannel {
+    public:
+        virtual ~QGADataChannel() = default;
+
+        virtual bool handleChannelMessage(QGaDataAction* action, qlibc::QData& msg, qlibc::QData* resp) = 0;
+
+    protected:
+        bool checkAutocacheSet(qlibc::QData &msg) {
+            auto autoCache = msg.getBool(cache_auto_save_);
+            msg.removeKey(cache_auto_save_);
+            return autoCache;
+        }
+    };
+
+    class JE_API QGAChannelHolder {
+    protected:
+        qlibc::QPObjectHolder<QGADataChannel> channels_;
+    public:
+
+        void addDataChannel(const std::string& type, QGADataChannel* channel){
+            channels_.appendNew(type, channel);
+        }
+
+        QGADataChannel* findDataChannel(const std::string& type) {
+            return channels_.findObject(type);
+        }
+    };
+
+    class JE_API QGAActionObject : public QGABaseObject {
+
+    protected:
+        explicit QGAActionObject() : QGABaseObject() {}
+        explicit QGAActionObject(const qlibc::QData &data) : QGABaseObject(data) {}
+    };
+
+    class QGaDataAction;
+
+    using gaoFinder = std::function<QGaDataAction*(const std::string& indexKey, const std::string& channel)>;
+
+
+    class JE_API QGADataPoolBase {
+    public:
+        virtual std::string     getSiteName() = 0;
+        virtual GaVarFinder*    getVarFinder() = 0;
+        virtual gaoFinder*      getGaoFinder() = 0;
+        virtual QJAMgServer&    getJAServer() = 0;
+        virtual QJAMgService&   getJAService() = 0;
+        virtual QGAChannelHolder& getChannelPool() = 0;
+        virtual bool            isDebuggingMessage() = 0;
+    };
+
+    /**
+     *  描述一个程序体,可以是request、deliver。
+     *      request:  单向向外发送请求,结果缓存或反馈给指定数据接收方
+     *      deliver:  被其它数据源投递消息,可调用request或cache,可返回数据投递方数据
+     *      cycler:   定时器,可请求第三方数据,或定时投递数据
+    */
+
+    using QGaChannelActionList = std::vector<QGaDataAction*>;
+
+    class JE_API QGaDataAction : public QGAActionObject, QGaDataActionBase {
+    protected:
+        QGADataPoolBase& data_pool_;
+        qlibc::QSharedObjectHolder<QGaDataActionController>*
+                        controllers_ = nullptr;
+        std::mutex  m_;
+
+        //添加针对每个通道的行为
+        QGaChannelActionList* subActions_ = nullptr;
+        std::string channel_;
+        std::string full_key_;
+        std::string control_;
+        std::string cond_;
+        std::string templ_;
+        const int order_;
+
+    public:
+        explicit QGaDataAction(QGADataPoolBase& dp) : QGAActionObject(), data_pool_(dp), order_(9999)  {}
+
+        explicit QGaDataAction(QGADataPoolBase& dp, const qlibc::QData& reqParam) :
+                QGAActionObject(reqParam), data_pool_(dp), order_(9999)  {
+        }
+
+        explicit QGaDataAction(QGADataPoolBase& dp, std::string channel, const qlibc::QData& reqParam) :
+                QGAActionObject(reqParam), data_pool_(dp),channel_(std::move(channel)), order_(9999) {
+            StringUtils::trimString(channel_);
+        }
+
+        explicit QGaDataAction(QGADataPoolBase& dp, std::string channel) :
+                QGAActionObject(), data_pool_(dp),channel_(std::move(channel)), order_(9999) {
+            StringUtils::trimString(channel_);
+        }
+
+        explicit QGaDataAction(QGADataPoolBase& dp, int line, std::string control,  std::string cond) :
+                QGAActionObject(qlibc::QData()), data_pool_(dp), control_(std::move(control)), cond_(std::move(cond)), order_(line) {
+            StringUtils::trimString(control_);
+            StringUtils::trimString(cond_);
+        }
+
+        ~QGaDataAction() override;
+
+        virtual bool performAction(qlibc::QData *req, qlibc::QData *resp);
+
+        void setUpSubChannelActions(QGaChannelActionList &connActions);
+
+        int getActionOrder() {
+            return order_;
+        }
+
+        void setPathKey(const std::string& pathKey);
+
+        void setMsgTemplateName(const std::string& templName) {
+            templ_ = templName;
+        }
+
+        inline const std::string& getTemplateName() {
+            return templ_;
+        }
+
+        const std::string& getPathKey() override;
+
+        const std::string& getChannel() {
+            return channel_;
+        };
+
+        void addSubAction(QGaDataAction *subDataAction);
+
+        QGaChannelActionList* getSubActions();
+
+        bool hasSubActions();
+
+        virtual void setAutoCache(bool autoCache);
+
+        void updateCommonParam(qlibc::QData &commonParam);
+
+        void clearSubActions();
+
+        void parseParam(Json::Value& ret, const std::string& src, const qlibc::QData* req) override;
+
+        bool checkCondition(QData *req, QData *resp) override;
+
+        bool runThisAction(QData *req, QData *resp) override;
+
+        bool runActionStopIfFail(QData *req, QData *resp) override;
+
+        QGaDataActionControllerR findCacheControl(qlibc::QData *req, qlibc::QData *resp);
+
+        void clearController();
+
+        void handleMessageVars(Json::Value &var, QData *req);
+    };
+
+    class JE_API QGaCachedVar : public QGAActionObject {
+    protected:
+        QGAChannelHolder& pool_;
+        std::string channel_;
+        std::string indexKey_;
+        std::string bind_key_;
+        const gaoFinder* finder_;   //不可能为空,但不能删除该指针。
+
+    public:
+        explicit QGaCachedVar(QGAChannelHolder& pl, const qlibc::QData& data, const std::string &idxKey, const gaoFinder* finder);
+
+        void checkUpdated();
+
+        void addBindedKey(const std::string &idxKey) {
+            bind_key_ = idxKey;
+        }
+
+        const std::string& getBindKey() {
+            return bind_key_;
+        }
+
+        inline const std::string& getPathKey() {
+            return indexKey_;
+        }
+    };
+
+    using QGaActionImpl = std::function<bool(QGAChannelHolder& pool, qlibc::QData *req, qlibc::QData *resp)>;
+
+    class JE_API QGAUserDefAction : public QGaDataAction {
+    protected:
+        QGaActionImpl& handler_;
+
+    public:
+        explicit QGAUserDefAction(QGADataPoolBase& dp,const QGaActionImpl& func) :
+            QGaDataAction(dp),  handler_(*new QGaActionImpl(func)) {
+        }
+
+        ~QGAUserDefAction() {
+            delete &handler_;
+        }
+
+        bool performAction(qlibc::QData *req, qlibc::QData *resp) override {
+            return handler_.operator()(data_pool_.getChannelPool(), req, resp);
+        }
+
+    };
+
+    class JE_API QGAStringRefAction : public QGaDataAction {
+    protected:
+        std::string index_key_;
+
+    public:
+        explicit QGAStringRefAction(QGADataPoolBase& dp, std::string channel, std::string indexKey) :
+            QGaDataAction(dp, std::move(channel)),index_key_(std::move(indexKey)) {
+        }
+
+        //引用, 主要是针对 request 进行, 需要从pool_等地方找到这个GAO,然后调用它
+        bool performAction(qlibc::QData *req, qlibc::QData *resp) override;
+    };
+
+    /**
+     *  request :   被本地调用,
+     *      向外部投递或请求数据, 更多的是请求, 结果定向转发或cache
+     */
+    class JE_API QGARequestAction : public QGaDataAction {
+
+    public:
+        explicit QGARequestAction(QGADataPoolBase& dp, qlibc::QData& reqParam, QGaChannelActionList& subConns) :
+                QGaDataAction(dp, reqParam) {
+            QGaDataAction::setUpSubChannelActions(subConns);
+        }
+    };
+
+    /**
+     *  deliver :   被外部调用,
+     *      外部向节点投递数据,  再通过request/return等进行数据转发,也可以被本地cache
+     */
+    class JE_API QGADeliverAction : public QGaDataAction {
+    public:
+        explicit QGADeliverAction(QGADataPoolBase& dp, qlibc::QData& reqParam, QGaChannelActionList& subConns) :
+            QGaDataAction(dp, reqParam) {
+            QGaDataAction::setUpSubChannelActions(subConns);
+        }
+
+        //ac选项无效
+        void setAutoCache(bool autoCache) override {}
+    };
+
+    /**
+     *
+     *      数据处理通道
+     *
+     *
+     */
+
+    class JE_API LogChannel : public QGADataChannel {
+    public:
+        bool handleChannelMessage(QGaDataAction* action, qlibc::QData &msg, qlibc::QData* resp) override;
+    };
+
+    using QGaRedirector = std::function<bool(const std::string &userKey, const std::string &indexKey,qlibc::QData &req,qlibc::QData *resp)>;
+    class JE_API ReDicrectChannel : public QGADataChannel {
+    protected:
+        QJAMgServer &opr_;
+        const QGaRedirector* redirector_;
+    public:
+        explicit ReDicrectChannel(const QGaRedirector* red, QJAMgServer &opr): opr_(opr), redirector_(red) {}
+        bool handleChannelMessage(QGaDataAction* action, qlibc::QData &msg, qlibc::QData* resp) override;
+    };
+
+    using QGaCachedVarUpdater = std::function<void(QGaCachedVar*)>;
+
+    class JE_API QGaCacheChannel : public QGADataChannel {
+    protected:
+        qlibc::QPObjectHolder<QGaCachedVar> &cachePool_;
+        QGaCachedVarUpdater*                 auto_savor_;
+        QGAChannelHolder                      &pool_;
+        const gaoFinder*                     gao_finder_;   //不可能为空,但不能删除该指针。
+
+    public:
+        explicit QGaCacheChannel(qlibc::QPObjectHolder<QGaCachedVar>& vars, QGaCachedVarUpdater* updater,
+                                 QGAChannelHolder& pl, const gaoFinder* finder) :
+                cachePool_(vars), auto_savor_(updater), pool_(pl), gao_finder_(finder) {
+            fast_str_call_ = true;
+        }
+
+        //保存到 DataPool的cached中
+        bool handleChannelMessage(QGaDataAction* action, qlibc::QData &msg, qlibc::QData* resp) override;
+    };
+
+    class JE_API QGaReturnChannel : public QGADataChannel {
+    protected:
+        QJAMgService &service_;
+    public:
+        explicit QGaReturnChannel(jedge::QJAMgService& service) : service_(service) { }
+
+        //需要把mgbus的调用源置入其中
+        bool handleChannelMessage(QGaDataAction* action, qlibc::QData &msg, qlibc::QData* resp) override;
+    };
+
+    class JE_API QGaFileChannel : public QGADataChannel {
+    public:
+        explicit QGaFileChannel() {}
+
+        //需要把mgbus的调用源置入其中
+        bool handleChannelMessage(QGaDataAction* action, qlibc::QData &msg, qlibc::QData* resp) override;
+    };
+
+    using GaAutoCacher = std::function<void(const std::string& cacherKey, qlibc::QData& result)>;
+
+    class JE_API QGaMgbusChannel : public QGADataChannel {
+    protected:
+        QJAMgService &service_;
+        GaAutoCacher *auto_cacher_;
+    public:
+        explicit QGaMgbusChannel(jedge::QJAMgService& service, GaAutoCacher* cacher) :
+                service_(service), auto_cacher_(cacher) { }
+
+        bool handleChannelMessage(QGaDataAction* action, qlibc::QData &msg, qlibc::QData* resp) override;
+    };
+
+    class JE_API QGaHttpChannel : public QGADataChannel {
+    protected:
+        jedge::QHttpClient &client_;
+        GaAutoCacher       *auto_cacher_;
+
+    public:
+        explicit QGaHttpChannel(jedge::QHttpClient& client, GaAutoCacher* cacher) :
+                client_(client), auto_cacher_(cacher){ }
+
+        bool handleChannelMessage(QGaDataAction* action, qlibc::QData &msg, qlibc::QData* resp) override;
+
+        inline void setEncryptor(const HttpRawEncryptor& encryptor) {
+            client_.setEncryptor(encryptor);
+        }
+
+        inline void setDecryptor(const HttpRawDecryptor& decryptor) {
+            client_.setDecryptor(decryptor);
+        }
+    };
+
+    class JE_API QGaSSLChannel : public QGADataChannel {
+    protected:
+        jedge::QHttpSSLClient &client_;
+        GaAutoCacher       *auto_cacher_;
+    public:
+        explicit QGaSSLChannel(jedge::QHttpSSLClient& client, GaAutoCacher* cacher) :
+                client_(client), auto_cacher_(cacher) { }
+
+        bool handleChannelMessage(QGaDataAction* action, qlibc::QData &msg, qlibc::QData* resp) override;
+    };
+
+    class JE_API QStringRefChannel : public QGADataChannel {
+    protected:
+        std::string channel_ref_;
+    public:
+        explicit QStringRefChannel(string chn) : channel_ref_(std::move(chn)) { }
+
+        bool handleChannelMessage(QGaDataAction* action, qlibc::QData &msg, qlibc::QData* resp) override;;
+    };
+
+    using GaMsgEncryptor = std::function<bool(const std::string& src, std::string &target)>;
+
+    class JE_API QGaMqttChannel : public QGADataChannel {
+    protected:
+        jedge::QMqttClient &client_;
+        GaMsgEncryptor*    encryptor_;
+        std::string        default_topic_;
+    public:
+        explicit QGaMqttChannel(jedge::QMqttClient& client, GaMsgEncryptor* encryptor, std::string dftTopic="") :
+            client_(client), encryptor_(encryptor), default_topic_(std::move(dftTopic)) { }
+
+        bool handleChannelMessage(QGaDataAction* action, qlibc::QData &msg, qlibc::QData* resp) override;
+    };
+
+    class JE_API QGaMsgTemplate {
+    public:
+        explicit QGaMsgTemplate(std::string key):  command_key_(std::move(key)){}
+
+        std::string command_key_;
+    };
+}
+#endif //INC_1_LIBDEVCPP_QGAACTIONOBJECTS_H

+ 20 - 0
app/src/main/cpp/inc/gafasl/QGABaseObject.h

@@ -0,0 +1,20 @@
+//
+// Created by Ht on 2022/8/28.
+//
+
+#ifndef INC_1_LIBDEVCPP_AJABASEOBJECT_H
+#define INC_1_LIBDEVCPP_AJABASEOBJECT_H
+
+#include <qlibc/qlibc.h>
+
+namespace jedge {
+
+    class JE_API QGABaseObject :
+        public qlibc::QData {
+    protected:
+        explicit QGABaseObject() : qlibc::QData() {}
+        explicit QGABaseObject(const qlibc::QData &data) : qlibc::QData(data) {}
+    };
+}
+
+#endif //INC_1_LIBDEVCPP_AJABASEOBJECT_H

+ 362 - 0
app/src/main/cpp/inc/gafasl/QGADataPool.h

@@ -0,0 +1,362 @@
+//
+// Created by Ht on 2022/8/28.
+//
+
+#ifndef INC_1_LIBDEVCPP_QGADATAPOOL_H
+#define INC_1_LIBDEVCPP_QGADATAPOOL_H
+
+
+#include <qlibc/qlibc.h>
+#include <jadom2/JABaseDom.h>
+#include <exlib/QJAServer.h>
+#include <exlib/QJAService.h>
+#include <exlib/QMqttClient.h>
+#include <exlib/http/QHttpSSLClient.h>
+
+#include "gao/QGAActionObjects.h"
+#include "gao/QGaVarFuncs.h"
+
+#include "QJAGafficUtil.h"
+#include <exception>
+
+namespace jedge {
+
+
+    //系统方法调用的响应者
+    using SiteCtrLMethodHandler = std::function<bool(qlibc::QData& msg, qlibc::QData* resp)>;
+
+    //一个数据池。
+    class JE_API QGADataPool :
+            public qlibc::QData, public QGADataPoolBase {
+    protected:
+        QJAMgServer &opr_;
+        QJAMgService &service_;
+
+        std::string base_path_;
+        std::string cache_file_path_;
+        bool quit_ = false;
+
+#ifdef DEBUG
+        bool debugging_message_ = true;
+#else
+        bool debugging_message_ = false;
+#endif
+        std::recursive_mutex dp_m_;
+
+        //数据访问接口
+        jedge::QMqttClient*     mqtt_Client_ = nullptr;
+        jedge::QHttpSSLClient*  ssl_client_ = nullptr;
+        jedge::QHttpClient*     http_client_ = nullptr;
+        std::mutex              mmqq_;
+        std::condition_variable wmqq_;
+
+        QStringList             mqttTopics_;
+        std::string             default_publish_;
+        qlibc::QRTimer          hbTimer = nullptr;  //mqtt心跳维持的timer
+
+        qlibc::QPObjectHolder<QGaCachedVar>  glvars_;  //全局的对象
+        qlibc::QPObjectHolder<QGaCachedVar>  glvars_idx_;  //全局的对象
+        qlibc::QPObjectHolder<GaUserDefFunction>  glUdFuncs_;  //全局的对象
+        qlibc::QPObjectHolder<GaUserDefFunctionVar>  glUdVarFuncs_;  //全局的对象
+
+        //数据源
+        qlibc::QPObjectHolder<QGaDataAction> gaoPool_;
+
+        //数据通道,不重置
+        QGAChannelHolder          channelPool_;
+
+        qlibc::QPObjectHolder<int>
+                                deliverIndexKeys_;  //已经支持的indexKey的计数
+
+        gaoFinder*              gao_finder_;
+        GaAutoCacher*           auto_cacher_;
+        GaVarFinder*            var_finder_;
+        GaMsgEncryptor*         msg_encryptor_;
+        QGaCachedVarUpdater*    cache_auto_savor_;
+        QGaRedirector*          redirector_;
+
+        qlibc::QPObjectHolder<SiteCtrLMethodHandler>  glSysCalls_;  //全局的对象
+
+        qlibc::QPObjectHolder<QGaMsgTemplate>  glMsgTemplates_;  //全局的对象
+
+        //    protected:
+        std::string checkFileInPath(const std::string& fileName) {
+            return fileName.empty()?"": FileUtils::contactFilename(base_path_, fileName);
+        }
+
+        std::string getFullSiteFilePath(const std::string& fileName) {
+            return FileUtils::contactFilename(base_path_, fileName);
+        }
+
+        void setupCachedVars(qlibc::QData &data);
+
+        virtual void setupMgbusConnection(qlibc::QData &data);
+
+        virtual void setupMqttConnection(qlibc::QData &data);
+
+        virtual void setupHttpSSL(qlibc::QData &data);
+
+        virtual void setupHttp(qlibc::QData &data);
+
+        virtual void setupUserChannel(const std::string& channel, qlibc::QData &data);
+
+        void buildDataActions(const std::string& conn, QData &data);
+
+        virtual void reprepareMqttTopics(const qlibc::QData& data);;
+
+        virtual bool decodeMqttMessage(const std::string& topic, void *payload, int payloadLen, char* buffer, int* len) {return false; };
+
+        virtual bool encryptMqttMessage(const std::string& payload, std::string& encryptOut) {return false; };
+
+        virtual bool handleMqttMessage(const std::string &topic, qlibc::QData &message);
+
+        virtual void resyncMqttStatus() {};
+
+        void restartHeartBeat();
+
+        virtual void mqttHeartBeat();
+
+        bool returnMqttMessage(const std::string& topic, qlibc::QData& message) {
+            message.putString("topic",topic);
+            return returnMqttMessage(message);
+        }
+
+        bool returnMqttMessage(qlibc::QData& message);
+
+    public:
+        explicit QGADataPool(QJAMgServer &server, QJAMgService &service, qlibc::QData& siteCfg, const std::string& name, std::string basePath);
+
+        virtual ~QGADataPool();
+
+        QJAMgServer& getOperator();
+
+        virtual void buildSiteData();
+        virtual void clearSiteData();
+
+        std::string getSiteName() override;
+
+        inline const std::string& getDeviceSerialNumber() {
+            return service_.getLocalMgbusHostSn();
+        };
+
+        QGaDataAction* findGAO(const std::string &fullKey);
+
+        QGaDataAction* findGAO(const std::string& conn, const std::string& gatype, const std::string &objKey);
+
+        QGaDataAction* findDeliverGAO(const std::string& conn, const std::string& indexKey, const std::string &objKey);
+
+        virtual QGaDataAction *createActionFromValue(std::string& key, const char *type, const Json::Value &value);
+
+        void buildDataChannelActions(QGaChannelActionList &tempChannelActions, const std::string& kk, const Json::Value &value);
+
+
+        /**
+         * request是单纯的对外动作,并可在deliver动作或cylcer动作中被引用。
+         * request 动作中,可引用cache、log或其它request动作,但无法调用return等动作。
+         *  可根据结果进行不同的cache动作调用
+         */
+        virtual QGaDataAction *createDeliverActionFromValue(const std::string& key, const Json::Value &value);
+
+        virtual QGaDataAction *createRequestActionFromValue(const std::string& key, const Json::Value &value);
+
+        /**
+         *  自定义响应函数
+         */
+        void addUserDefinedGAO(const std::string& channelPathKey, const QGaActionImpl& handler);
+
+        void addUserMgbusDeliverGAO(const string &actionkey, const QGaActionImpl& handler) {
+            addUserDefinedGAO("mgbus.deliver.uri."+actionkey, handler);
+        }
+
+        void addUserMqttDeliverGAO(const string &idxKey, const string &actionkey, const QGaActionImpl& handler) {
+            addUserDefinedGAO("mqtt."+idxKey+"."+actionkey, handler);
+        }
+
+        void addUserHttpsRequestGAO(const string &actionkey, const QGaActionImpl& handler) {
+            addUserDefinedGAO("https.request."+actionkey, handler);
+        }
+
+        void addUserDefineGAO(const std::string &userArea, const  std::string& indexKey, const QGaActionImpl& handler) {
+            addUserDefinedGAO(userArea+"."+indexKey, handler);
+        }
+
+        virtual void handleMqttOfflineEvent(QData &data) {}
+
+        //获取Cached的Key
+        Json::Value *getCachedVarValue(const std::string& varKey);
+
+        //获取Cached的Key
+        QGaCachedVar *getCachedVar(const std::string& varKey) {
+            return glvars_idx_.findObject(varKey);
+        }
+
+        bool mqttPublish(const std::string& topic, qlibc::QData& msg, int qos = 0) {
+            if(mqtt_Client_!=nullptr && mqtt_Client_->isConnected())
+                return mqtt_Client_->publish(topic, msg.toJSONString().c_str(), qos);
+            return false;
+        }
+
+        bool mqttPublish(const std::string& topic, const char* buff, int qos = 0) {
+            if(mqtt_Client_!=nullptr && mqtt_Client_->isConnected())
+                return mqtt_Client_->publish(topic, buff, qos);
+            return false;
+        }
+
+        bool httpSyncPost(const std::string& host, const std::string& uriKey, qlibc::QData& req, qlibc::QData& resp);
+
+        bool httpsSyncPost(const std::string& host, const std::string& uriKey, qlibc::QData& req, qlibc::QData& resp);
+
+        bool httpSyncPost(const std::string& uriKey, qlibc::QData& resp);
+
+        bool httpsSyncPost(const std::string& uriKey,qlibc::QData& resp);
+
+        bool mgbusRequest(const std::string& mod, const std::string& uriKey, qlibc::QData& req, qlibc::QData& resp) {
+            return service_.postServiceRequest(mod, uriKey, req, resp);
+        }
+
+        bool mgbusMessage(const std::string& mod, const std::string& uriKey, qlibc::QData& req) {
+            return service_.postServiceMessage(mod, uriKey, req);
+        }
+
+        bool mgbusRequest(const std::string& uriKey, qlibc::QData& resp);
+
+        bool mgbusMessage(const std::string& uriKey);
+
+        void stopHeartbeat();
+
+        void defaultMqttHeartBeat();
+
+        void prepareDefaultMqttParams(qlibc::QData& cfg, std::string& username, std::string& password, std::string& clientId);
+
+        bool handleDefaultMqttMessage(const std::string &topic, qlibc::QData &msg);
+
+        bool handleDefaultMgbusMessage(QData &req, QData *rsp);
+
+        bool httpSyncPostRaw(const std::string& httpUri, const std::string& payload, const char* httpContent);
+
+        bool httpsSyncPostRaw(const std::string& httpUri, const std::string& payload, const char* httpContent);
+
+        virtual void prepareMqttParams(qlibc::QData& cfg, std::string& username, std::string& password, std::string& clientId);
+
+        virtual bool handleMgbusMessage(QData &req, QData *rsp);
+
+        QGaDataAction* buildDataChannelAction(const std::string &channel, const std::string &control, const std::string &cond, int ln, const Json::Value &actions);
+
+        void autoCacheResult(const std::string &actKey, qlibc::QData &result);
+
+        bool handleGaLocalVars(Json::Value &ret, const string &varKey, const qlibc::QData &msg);
+
+        bool handleGaFunc(Json::Value &ret, const string &funcKey, const qlibc::QData &msg);
+
+        void setupUserDefinedGaoFuncs();
+
+        void bindUserDefinedGAOFunction(const std::string& funcKey, const GaUserDefFunction& funcBody);
+
+        //针对某个uri的特殊处理逻辑
+        void setupMgbusUserHandler(qlibc::QData& config, const std::string& udIndex);
+
+        //消息子协议区分响应
+        virtual auto handleUserHandler(const std::string& userKey, const std::string& indexKey, QData *req, QData *resp) -> bool;
+
+        //显示cache变量的值
+        void showCachedVars(const std::string &cacheVarKey, bool full, bool update);
+
+        void showCachedVar(const std::string &cacheVarKey,QGaCachedVar *var,bool full,  bool update);
+
+        void addCachedVar(const std::string &key, const std::string &path, QGaCachedVar *cachedVar);
+
+        void checkRemoveKey(const std::string &oldKey);
+
+        void saveCacheVar(QGaCachedVar *cv);
+
+        void loadSavedCacheVar(QGaCachedVar *cv);
+
+        const std::string &getDefaultPublishTopic();
+
+        const std::string &getCacheFilePath() {
+            return cache_file_path_;
+        }
+
+        void listGaoItems(const std::string& grepKey);
+
+        bool runDirectGao(const std::string& fullKey,  qlibc::QData *req, qlibc::QData *resp);
+
+        //触发系统事件
+        bool invokeDPEvent(const std::string& channel, const std::string& evtKey, qlibc::QData &param);
+
+        bool callGaoSystemMethod(const std::string &method, qlibc::QData &req, qlibc::QData *resp);
+
+        void reloadSite();
+
+        GaVarFinder *getVarFinder() override;
+
+        QJAMgServer &getJAServer() override;
+
+        QJAMgService &getJAService() override;
+
+        QGAChannelHolder &getChannelPool() override;
+
+        gaoFinder *getGaoFinder() override;
+
+        void removeCacheData() {
+            FileUtils::removeDir(cache_file_path_);
+        }
+
+        bool isDebuggingMessage() override;
+
+        void setDebuggingMessage(bool debug = true) {
+            debugging_message_ = debug;
+        }
+
+    protected:
+        void addTopicString(const Json::Value &topicValue);
+
+        void handleConfigVars(string &result, const string &src);
+
+        void setupExGaoActions(qlibc::QData& data);
+
+        //siteCtrl方法:加载自定义消息模板,清理自定义消息模板
+        bool reloadMessageTempl(qlibc::QData &req, qlibc::QData *resp);
+        bool clearMessageTempl(qlibc::QData &req, qlibc::QData *resp);
+
+        void setupMsgTemplates(QData &data);
+
+        void loadMessageTemplate(const string &tpFile);
+        void clearMessageTemplate(const string &tpName);
+
+        bool createDevlierDataActionByDefValue(const string &gaoPath, const Json::Value &actsDefObj,
+                                               const string &tmplName="");
+
+        void addDeliverKeyIndex(const std::string& key);
+
+        void updateTemplateCacheNames();
+
+        void setupSystemCacheVar();
+    };
+
+#define bindDeliverGaoHandler(_handler)  data_pool_->addUserMgbusDeliverGAO(#_handler, \
+            [this](QGAChannelPool& pool, qlibc::QData *req, qlibc::QData *resp)->bool { \
+                return this->_handler(pool,req,resp);\
+            })
+
+#define bindDeliverGaoHandlerFunc(_handler)  data_pool_->addUserMgbusDeliverGAO(#_handler, \
+            [](QGAChannelPool& pool, qlibc::QData *req, qlibc::QData *resp)->bool { \
+                return _handler(pool,req,resp);\
+            })
+
+#define GaoHandler(_func,_pool,_r,_p) auto _func(QGAChannelHolder& _pool, qlibc::QData *_r, qlibc::QData *_p)->bool
+
+    class JE_API QGaSiteCtrlChannel : public QGADataChannel {
+    protected:
+        QGADataPool &site_;
+
+    public:
+        explicit QGaSiteCtrlChannel(QGADataPool &site): site_(site) {}
+
+        bool handleChannelMessage(QGaDataAction* action, qlibc::QData &msg, qlibc::QData* resp) override;
+    };
+
+
+}
+
+#endif //INC_1_LIBDEVCPP_QGADATAPOOL_H

+ 13 - 0
app/src/main/cpp/inc/gafasl/QGaConsts.h

@@ -0,0 +1,13 @@
+//
+// Created by Ht on 2022/10/6.
+//
+
+#ifndef INC_1_LIBDEVCPP_QGACONSTS_H
+#define INC_1_LIBDEVCPP_QGACONSTS_H
+
+
+namespace jedge {
+    static const char* vkey_base_site_ = "$site";
+}
+
+#endif //INC_1_LIBDEVCPP_QGACONSTS_H

+ 131 - 0
app/src/main/cpp/inc/gafasl/QGaControllerUtil.h

@@ -0,0 +1,131 @@
+//
+// Created by Ht on 2022/10/2.
+//
+
+#ifndef INC_1_LIBDEVCPP_QGACONTROLLERUTIL_H
+#define INC_1_LIBDEVCPP_QGACONTROLLERUTIL_H
+
+#include <qlibc/qlibc.h>
+#include <exlib/QJAServer.h>
+
+namespace jedge {
+
+    class JE_API QGaDataActionBase {
+    public:
+        virtual void parseParam(Json::Value& ret, const std::string& src, const qlibc::QData* msg) = 0;
+
+        virtual bool runActionStopIfFail(qlibc::QData *req, qlibc::QData *resp) = 0;
+
+        virtual bool runThisAction(qlibc::QData *req, qlibc::QData *resp) = 0;
+
+        virtual bool checkCondition(qlibc::QData *req, qlibc::QData *resp) = 0;
+
+        virtual const std::string& getPathKey() = 0;
+    };
+
+    class QGaDataActionController;
+
+    using QGaControllerHandler = std::function<bool(QGaDataActionController* ctrl, qlibc::QData* req, qlibc::QData* resp)>;
+
+    class JE_API QGaDataActionController : public qlibc::QData {
+    protected:
+        const QGaControllerHandler* handler_;
+
+    public:
+        QJAMgServer& ctx_;
+        QGaDataActionBase& base_;
+        qlibc::QRTimer timer;
+        qlibc::QData *newReq = nullptr, *newResp = nullptr;
+
+        std::recursive_mutex m_;
+        std::mutex wm_;
+        std::condition_variable w_;
+        bool quit_ = false;
+
+        explicit QGaDataActionController(QJAMgServer& ctx, QGaDataActionBase& base, const QGaControllerHandler& execBody) : handler_(new QGaControllerHandler(execBody)), ctx_(ctx), base_(base) {
+        }
+
+        bool runDataAction (qlibc::QData* req, qlibc::QData* resp) {
+            return (handler_!= nullptr) && (*handler_)(this, req, resp);
+        }
+
+        void stopControl() {
+            RECURSIVE_LOCK(m_);
+            quit_ = true;
+            if(timer!= nullptr) {
+                ctx_.timerEngine().stopTimer(timer);
+                timer = nullptr;
+            }
+
+            if(newReq!= nullptr) {
+                ctx_.releaseMessage(newReq);
+            }
+
+            if(newResp!= nullptr) {
+                ctx_.releaseMessage(newResp);
+            }
+            SINGLE_LOCK(wm_);
+            w_.notify_all();
+        }
+
+        void initDataWith(QData *req, QData *resp) {
+            RECURSIVE_LOCK(m_);
+            if(newReq!= nullptr)
+                newReq->clear();
+            else
+                newReq = ctx_.getBlankMessage();
+            if(req!= nullptr)
+                newReq->copyData(*req);
+            if(newResp!= nullptr)
+                newResp->clear();
+            else
+                newResp = ctx_.getBlankMessage();
+            if(resp!= nullptr)
+                newResp->copyData(*resp);
+        }
+    };
+    using QGaDataActionControllerR = std::shared_ptr<QGaDataActionController>;
+
+    using QGaDataActionControllerCreator = std::function<QGaDataActionController*(
+            QJAMgServer& ctx, QGaDataActionBase &action, const std::string& ctrlKey, QStringList& params, const qlibc::QData* msg)>;
+
+    class JE_API QGaControllerUtil {
+    protected:
+        qlibc::QPObjectHolder<QGaDataActionControllerCreator> creators_;
+        explicit QGaControllerUtil();
+
+    public:
+
+        static QGaControllerUtil& instance();
+
+        //添加一个controller的创建对象
+        void addDataActionController(const std::string& ctrlKey, const QGaDataActionControllerCreator& creator);
+
+        //创建一个controller
+        QGaDataActionController* createController(QJAMgServer& ctx, QGaDataActionBase &action, const std::string& controller, const qlibc::QData* msg);
+    };
+
+#define DAControllerLamda(_c,_r,_s) (QGaDataActionController* (_c), qlibc::QData* (_r), qlibc::QData* (_s))->bool
+#define DAControllerCreator(_ctx,_ac,_ck,_pm,_mg) (QJAMgServer& (_ctx), QGaDataActionBase &(_ac), const std::string& (_ck), QStringList& (_pm), const qlibc::QData* (_mg))->QGaDataActionController*
+
+#define GaoActionControllerCreatorName(_t) createFor##_t
+#define GaoActionRunnerName(_t) _t##Runner
+
+#define bindGAOActionController(_t) \
+       QGaControllerUtil::instance().addDataActionController(#_t, [this]DAControllerCreator(ctx,ac,ck,pm,mg) {\
+            return GaoActionControllerCreatorName(_t)(ctx,ac,ck,pm,mg); \
+       })
+#define implGAOActionControllerCreator(_t,_ctx,_ac,_ck,_pm,_mg) \
+        GaoActionControllerCreatorName(_t)(QJAMgServer &(_ctx), QGaDataActionBase &(_ac), const string &(_ck), QStringList &(_pm), const qlibc::QData* (_mg))
+
+#define implGAOActionRunner(_t,_c,_r,_p) \
+        GaoActionRunnerName(_t)(QGaDataActionController *(_c), qlibc::QData *(_r), qlibc::QData *(_p))
+
+#define CreateControllerWithRunner(_t,_ctx,_ac) \
+        new QGaDataActionController((_ctx), (_ac),\
+            [](QGaDataActionController *_ctrl, qlibc::QData *_req, qlibc::QData *_resp) -> bool { \
+            return GaoActionRunnerName(_t)(_ctrl, _req, _resp); \
+        })
+}
+
+#endif //INC_1_LIBDEVCPP_QGACONTROLLERUTIL_H

+ 88 - 0
app/src/main/cpp/inc/gafasl/QGaCypherPluginEntry.h

@@ -0,0 +1,88 @@
+
+//
+// Created by Ht on 2022/8/28.
+//
+
+#ifndef INC_1_LIBDEVCPP_QGACYPHERPLUGINENTRY_H
+#define INC_1_LIBDEVCPP_QGACYPHERPLUGINENTRY_H
+
+#include <jebase/config.h>
+#include "../QGADataPool.h"
+
+namespace jedge {
+
+    /**
+     * 处理加密函数的插件:
+     *      获得 mqtt加密、 mqtt解密、 登录加密等函数的入口,并可获得一些额外的标准函数接口。
+     */
+
+    class JE_API QGaCypherPluginEntry :
+        public qlibc::QPluginEntry {
+    protected:
+        QGADataPool *data_pool_ = nullptr;
+        std::string sn_;
+
+    public:
+        explicit QGaCypherPluginEntry(std::string name, std::string type = "cypher", int ver = 0) :
+                qlibc::QPluginEntry(std::move(name), std::move(type), ver) {
+        }
+
+        virtual QGaCypherPluginEntry* duplication(const std::string& name) {
+            auto* dup = new QGaCypherPluginEntry(name, typeKey_, ver_);
+            dup->sn_ = sn_;
+            return dup;
+        }
+
+        ~QGaCypherPluginEntry() override {}
+
+        virtual void setDataPool(QGADataPool &pool);
+
+        virtual void prepareSiteMqttTopics(QStringList &topics) {  };
+
+        virtual void resyncMqttStatus() {}
+
+        virtual void handleMqttOfflineEvent() {}
+
+        virtual bool decodeMqttMessage(const string &topic, void *payload, int payloadLen, char *buffer, int *len) {
+            return false;   //未加密消息
+        }
+
+        virtual bool encryptMqttMessage(const std::string &payload, std::string &encryptOut) {
+            return false;
+        }
+
+        virtual void makeMqttHeartBeat();
+
+        virtual void prepareMqttParams(qlibc::QData &config, string &username, string &password, string &clientId);
+
+        virtual bool handleMqttMessage(const string &topic, qlibc::QData &msg);
+
+        bool handleMgbusMessage(qlibc::QData &req, qlibc::QData *rsp);
+
+        virtual void buildSiteData(qlibc::QData &data) {}
+
+        virtual void clearSiteData(qlibc::QData &data) {}
+    };
+
+#define bindDeliverGaoPluginHandler(_handler)  data_pool_->addUserMgbusDeliverGAO(#_handler, \
+            [this](QGAChannelHolder& pool, qlibc::QData *req, qlibc::QData *resp)->bool { \
+                return this->_handler(pool,req,resp);\
+            })
+
+#define bindDeliverGaoPluginHandlerFunc(_handler)  data_pool_->addUserMgbusDeliverGAO(#_handler, \
+            [](QGAChannelHolder& pool, qlibc::QData *req, qlibc::QData *resp)->bool { \
+                return _handler(pool,req,resp);\
+            })
+
+#define bindUserDefPluginHandler(area, _handler)  data_pool_->addUserDefineGAO(area, #_handler, \
+            [this](QGAChannelHolder& pool, qlibc::QData *req, qlibc::QData *resp)->bool { \
+                return this->_handler(pool,req,resp);\
+            })
+
+#define bindUserDefPluginHandlerFunc(area, _handler)  data_pool_->addUserDefineGAO(area, #_handler, \
+            [](QGAChannelPool& pool, qlibc::QData *req, qlibc::QData *resp)->bool { \
+                return _handler(pool,req,resp);\
+            })
+}
+
+#endif //INC_1_LIBDEVCPP_QGACYPHERPLUGINENTRY_H

+ 37 - 0
app/src/main/cpp/inc/gafasl/QGaHongdouPluginEntry.h

@@ -0,0 +1,37 @@
+//
+// Created by Ht on 2022/8/29.
+//
+
+#ifndef INC_1_LIBDEVCPP_QGAHONGDOUPLUGINENTRY_H
+#define INC_1_LIBDEVCPP_QGAHONGDOUPLUGINENTRY_H
+
+#include "../../src/plugin/QGaCypherPluginEntry.h"
+#include "../../src/QGADataPool.h"
+#include <mqtt/Base64.h>
+#include "hongdouEncrypt.h"
+
+namespace jedge {
+
+//    const char* webKey = "1k8VKDqpOMndSxtDhrExYtTAsV";
+
+    class JE_API  QGaHongdouPluginEntry :
+            public QGaCypherPluginEntry {
+    protected:
+        uint8_t cypherCode[16] = {0xa9,0x31,0x61,0x86,0x9a,0x89,0x2a,0x29,0x01,0x3c,0xcf,0x7e,0x03,0x0d,0x87,0x91};
+        uint8_t iv_key[16] = {0x62,0x6f,0x74,0x68,0x61,0x72,0x65,0x65,0x6e,0x67,0x69,0x6e,0x65,0x65,0x72,0x73};
+
+    public:
+        explicit QGaHongdouPluginEntry(std::string name, std::string type = "cypher", int ver = 0);
+
+        void buildSiteData(qlibc::QData &data) override;
+
+        QGaCypherPluginEntry *duplication(const string &name) override;
+
+        bool decodeMqttMessage(const string &topic, void *payload, int payloadLen, char *buffer, int *len) override;
+
+        bool encryptMqttMessage(const std::string& payload, std::string& encryptOut) override;
+    };
+}
+
+
+#endif //INC_1_LIBDEVCPP_QGAWANJAPLUGINENTRY_H

+ 223 - 0
app/src/main/cpp/inc/gafasl/QGaHongmeiPluginEntry.h

@@ -0,0 +1,223 @@
+//
+// Created by Ht on 2022/8/29.
+//
+
+#ifndef INC_1_LIBDEVCPP_QGAHONGMEIPLUGINENTRY_H
+#define INC_1_LIBDEVCPP_QGAHONGMEIPLUGINENTRY_H
+
+#include "../../src/plugin/QGaCypherPluginEntry.h"
+#include "../../src/QGADataPool.h"
+#include <mgbus/SocketClient.h>
+#include <set>
+#include "messageHandle.h"
+#include "hmcrypt/lancommn.h"
+#include "messageHandle.h"
+#include "udgao/QGaUdGaoImpl.h"
+#include "udgao/QGaoUdRespGaoImpl.h"
+
+namespace jedge {
+
+    class JE_API  QGaHongmeiPluginEntry :
+            public QGaCypherPluginEntry {
+    protected:
+        uint8_t cypherCode[50];
+        std::set<std::string> mGreped;
+        QRTimer updateKeyTimer_;
+
+    public:
+        explicit QGaHongmeiPluginEntry(std::string name, std::string type = "cypher", int ver = 0) :
+            jedge::QGaCypherPluginEntry(std::move(name), std::move(type), ver) {
+        }
+
+        ~QGaHongmeiPluginEntry() override { }
+
+        GaoHandler(response,pool,r,p) {
+            //用户自定义子协议的调用响应
+            return data_pool_->handleUserHandler(ud_gao_area_mgbus_response_, "command", r, p);
+        }
+
+        GaoHandler(addBegin,pool,r,p) {
+            auto ok = false;
+            qlibc::QDataList deviceBeginArray;
+            r->getDataList("begin_list", deviceBeginArray);
+            size_t deviceBeginArraySize = deviceBeginArray.getItemCount();
+            for(auto i = 0; i < deviceBeginArraySize; i++) {
+                qlibc::QData ithData;
+                deviceBeginArray.getItem(i, ithData);
+                ithData.setString("command", "addBeginIt");
+                ok = data_pool_->handleUserHandler(ud_gao_area_mgbus_response_, "command",&ithData, nullptr) || ok;
+            }
+            OkPRspMsg(p, "ok");
+            return ok;
+        }
+
+        GaoHandler(addResult,pool,r,p) {
+            auto ok = false;
+            qlibc::QDataList deviceSuccessArray;
+            r->getDataList("success_list", deviceSuccessArray);
+            size_t deviceSuccessArraySize = deviceSuccessArray.getItemCount();
+            for(size_t i = 0; i < deviceSuccessArraySize; i++) {
+                qlibc::QData ithData;
+                deviceSuccessArray.getItem(i, ithData);
+                ithData.setString("command", "addResultSuccessIt");
+                /**
+                 * 每个设备添加成功后,需要处理三个动作:
+                 * (1)注册设备;           (http实现)
+                 * (2)上报添加成功;       (mqtt实现)
+                 * (3)更新设备状态。       (mqtt实现)
+                 */
+                ok = data_pool_->handleUserHandler(ud_gao_area_mgbus_response_, "command", &ithData, p) || ok;
+            }
+            qlibc::QDataList deviceFailArray;
+            r->getDataList("failed_list", deviceFailArray);
+            size_t deviceFailArraySize = deviceFailArray.getItemCount();
+            for(size_t i = 0; i < deviceFailArraySize; i++) {
+                qlibc::QData ithData;
+                deviceFailArray.getItem(i, ithData);
+                ithData.setString("command", "addResultFailIt");
+                ok = data_pool_->handleUserHandler(ud_gao_area_mgbus_response_, "command", &ithData, p) || ok;
+            }
+            //重新cache设备
+            data_pool_->runDirectGao("https.request.getBtDevsBySnUrl", r, p);
+            OkPRspMsg(p, "ok");
+            return ok;
+        }
+
+        auto deleteResult(QGAChannelHolder& pool, qlibc::QData *req, qlibc::QData *resp) ->bool {
+            auto ok = false;
+            qlibc::QDataList deleteList;
+            req->getDataList("delete_list", deleteList);
+            size_t deleteListCount = deleteList.getItemCount();
+            for(size_t i = 0; i < deleteListCount; i++) {
+                qlibc::QData ithData;
+                deleteList.getItem(i, ithData);
+                ithData.setString("command", "deleteResultIt");
+                ok = data_pool_->handleUserHandler(ud_gao_area_mgbus_response_, "command", &ithData, resp) || ok;
+            }
+            //删除设备后,需要场景同步一次, 调用获取所有的在线设备信息
+            data_pool_->runDirectGao("base.request.syncScene", req, resp);
+            OkPRspMsg(resp, "ok");
+            return true;
+        }
+
+        GaoHandler(addDevice,pool,r,p) {
+            OkPRspMsg(p, "ok");
+            return true;
+        }
+
+        void buildSiteData(QData &data) override {
+            data_pool_->setupMgbusUserHandler(data, ud_gao_area_mgbus_response_);
+            bindDeliverGaoPluginHandler(response);
+            bindUserDefPluginHandler(ud_gao_area_mgbus_response_command_, addBegin);
+            bindUserDefPluginHandler(ud_gao_area_mgbus_response_command_, addResult);
+            bindDeliverGaoPluginHandler(deleteResult);
+
+            bindDeliverGaoPluginHandler(addDevice);
+
+            bindDeliverGaoPluginHandlerFunc(debugMode);
+            bindDeliverGaoPluginHandlerFunc(encryptMode);
+            bindDeliverGaoPluginHandlerFunc(publishResponse2app);
+            bindDeliverGaoPluginHandlerFunc(setServerOption);
+            bindDeliverGaoPluginHandlerFunc(getServerOption);
+            bindDeliverGaoPluginHandlerFunc(isBelong2Family);
+            bindDeliverGaoPluginHandlerFunc(getPanelClientParameter);
+            bindDeliverGaoPluginHandlerFunc(getSnDeviceList);
+        }
+
+        void setDataPool(QGADataPool &pool) override {
+            QGaCypherPluginEntry::setDataPool(pool);
+            //读取dp的配置
+            auto grepCmdSrc = pool.getString("commandSource");
+            if(!grepCmdSrc.empty()) {
+                QStringList srcs;
+                StringUtils::SplitString(grepCmdSrc, ",", srcs);
+                for(const auto& k :srcs) {
+                    mGreped.emplace(k);
+                }
+            }
+        }
+
+        QGaCypherPluginEntry *duplication(const string &name) override {
+            auto* dup = new QGaHongmeiPluginEntry(name, typeKey_, ver_);
+            dup->sn_ = sn_;
+            return dup;
+        }
+
+        void regenerateMqttCypherKey() {
+            std::string uploadBuffer; char* tmpCode = nullptr;
+            messagehandle::gen_mqtt_comm_key (data_pool_->getDeviceSerialNumber(), uploadBuffer, &tmpCode);
+            //上传key
+            QInfo("Uploading -->: %s", uploadBuffer.c_str());
+            if(!data_pool_->httpSyncPostRaw(R"(http://superapp.mymlsoft.com/saserver/safe/saveOrUpdate)", uploadBuffer, R"(text/plain)")) {
+                QErr("Fail to update mqtt cypher key!");
+            }
+            memset(cypherCode, 0, 50);
+            hex_to_bytes(reinterpret_cast<uint8_t *>(tmpCode), cypherCode);
+        }
+
+        //mqtt上线后的行为
+        void resyncMqttStatus() override {
+            regenerateMqttCypherKey();
+
+            //通知app立即更新key
+            while(!data_pool_->mqttPublish("d/" + sn_ + "/m", "00")) {
+                QWarn("Fail to notify app to update key.");
+                SystemUtil::tryWait(3000);
+            }
+
+
+            const QRTimerEngine &te = data_pool_->getOperator().timerEngineRef();
+            te->stopTimer(updateKeyTimer_);
+            //更新与App通信的Key。
+            updateKeyTimer_ =  te->repeatRun([this]lamdaTimerTask(t,p){
+                regenerateMqttCypherKey();
+                QLog("======>update the key successfuly<======\n");
+                return true;
+            }, 1000 * 60 * 60* 24, 1000*60*60*12);    //12小时后、每24小时更新一次密钥
+        }
+
+        bool decodeMqttMessage(const string &topic, void *payload, int payloadLen, char *buffer, int *len) override {
+            string payloadMessage(reinterpret_cast<char*>(payload), 0, payloadLen);
+            QLog("==>in dataHooker: %s\n", payloadMessage.c_str());
+            if(topic == "d/" + sn_ + "/i") {   //只有sn被设置才能连接到服务器,才会有消息进入到这里
+                string out;
+                messagehandle::decrypt_mqttReceiveCommand(cypherCode, topic, reinterpret_cast<byte*>(payload), payloadLen,out);
+                memset(buffer, 0, out.size() + 1);
+                memcpy(buffer, out.data(), out.size());
+                *len = (int)out.size();
+                return true;
+            }
+            return false;
+        }
+
+        bool encryptMqttMessage(const std::string& payload, std::string& encryptOut) override {
+            return messagehandle::encrypt_uploadMessage(cypherCode, payload, encryptOut);
+        }
+
+        void prepareMqttParams(QData &config, string &username, string &password, string &clientId) override {
+            auto sn = data_pool_->getDeviceSerialNumber();
+            username = sn;
+            password = config.getString("password");
+            clientId =  "d:" + sn;
+        }
+
+        void makeMqttHeartBeat() override {
+            //发起mqtt心跳
+            if(data_pool_!= nullptr) {
+                data_pool_->mqttPublish("d/" + sn_ + "/m", "00");
+            }
+        }
+
+        bool handleMqttMessage(const string &topic, QData &msg) override {
+            //过滤command_source
+            auto cmdSrc = msg.getString("commandSource");
+            if(!cmdSrc.empty() && !mGreped.empty() && mGreped.find(cmdSrc)==mGreped.end()) {
+                return true;
+            }
+            return QGaCypherPluginEntry::handleMqttMessage(topic, msg);
+        }
+    };
+}
+
+
+#endif //INC_1_LIBDEVCPP_QGAHONGMEIPLUGINENTRY_H

+ 43 - 0
app/src/main/cpp/inc/gafasl/QGaJedgePluginEntry.h

@@ -0,0 +1,43 @@
+//
+// Created by Ht on 2022/8/29.
+//
+
+#ifndef INC_1_LIBDEVCPP_QJIUZHOUPLUGINENTRY_H
+#define INC_1_LIBDEVCPP_QJIUZHOUPLUGINENTRY_H
+
+#include "../../src/plugin/QGaCypherPluginEntry.h"
+#include "../../src/QGADataPool.h"
+#include <mqtt/Base64.h>
+
+namespace jedge {
+
+    class JE_API  QGaJedgePluginEntry :
+            public QGaCypherPluginEntry {
+    public:
+        explicit QGaJedgePluginEntry(std::string name, std::string type = "cypher", int ver = 0) :
+                jedge::QGaCypherPluginEntry(std::move(name), std::move(type), ver) {
+        }
+
+        QGaCypherPluginEntry *duplication(const string &name) override {
+            auto* dup = new QGaJedgePluginEntry(name, typeKey_, ver_);
+            dup->sn_ = sn_;
+            return dup;
+        }
+
+        //构造时调用
+        void setDataPool(QGADataPool &pool) override {
+            QGaCypherPluginEntry::setDataPool(pool);
+            //
+//            bindGAOActionController(forEachEqual1);
+            //需要重新载入用户自定义的函数
+        }
+
+        //重载时调用,用户自定义函数等需要在这里添加
+        void buildSiteData(qlibc::QData &data) override {
+            QGaCypherPluginEntry::buildSiteData(data);
+        }
+    };
+}
+
+
+#endif //INC_1_LIBDEVCPP_QJIUZHOUPLUGINENTRY_H

+ 55 - 0
app/src/main/cpp/inc/gafasl/QGaUdGaoImpl.h

@@ -0,0 +1,55 @@
+//
+// Created by Ht on 2022/9/6.
+//
+
+#ifndef INC_1_LIBDEVCPP_QGAUDGAOIMPL_H
+#define INC_1_LIBDEVCPP_QGAUDGAOIMPL_H
+
+
+#include "../../../src/QGADataPool.h"
+
+namespace jedge {
+
+    static auto debugMode(QGAChannelHolder& pool, qlibc::QData *req, qlibc::QData *resp)->bool {
+        QDCmtR("Unhandled : \n%s", req->toJSONString(true).c_str());
+        return true;
+    }
+
+    static auto encryptMode(QGAChannelHolder& pool, qlibc::QData *req, qlibc::QData *resp)->bool {
+        QDCmtR("Unhandled : \n%s", req->toJSONString(true).c_str());
+        return true;
+    }
+
+    static auto publishResponse2app(QGAChannelHolder& pool, qlibc::QData *req, qlibc::QData *resp)->bool {
+        QDCmtR("Unhandled : \n%s", req->toJSONString(true).c_str());
+        return true;
+    }
+
+    static auto setServerOption(QGAChannelHolder& pool, qlibc::QData *req, qlibc::QData *resp)->bool {
+        QDCmtR("Unhandled : \n%s", req->toJSONString(true).c_str());
+        return true;
+    }
+
+    static auto getServerOption(QGAChannelHolder& pool, qlibc::QData *req, qlibc::QData *resp)->bool {
+        QDCmtR("Unhandled : \n%s", req->toJSONString(true).c_str());
+        return true;
+    }
+
+    static auto isBelong2Family(QGAChannelHolder& pool, qlibc::QData *req, qlibc::QData *resp)->bool {
+        QDCmtR("Unhandled : \n%s", req->toJSONString(true).c_str());
+        return true;
+    }
+
+    static auto getPanelClientParameter(QGAChannelHolder& pool, qlibc::QData *req, qlibc::QData *resp)->bool {
+        QDCmtR("Unhandled : \n%s", req->toJSONString(true).c_str());
+        return true;
+    }
+
+    static auto getSnDeviceList(QGAChannelHolder& pool, qlibc::QData *req, qlibc::QData *resp)->bool {
+        QDCmtR("Unhandled : \n%s", req->toJSONString(true).c_str());
+        return true;
+    }
+
+}
+
+#endif //INC_1_LIBDEVCPP_QGAUDGAOIMPL_H

部分文件因文件數量過多而無法顯示