summaryrefslogtreecommitdiffstats
path: root/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-03-09 13:19:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-03-09 13:19:22 +0000
commitc21c3b0befeb46a51b6bf3758ffa30813bea0ff0 (patch)
tree9754ff1ca740f6346cf8483ec915d4054bc5da2d /fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr
parentAdding upstream version 1.43.2. (diff)
downloadnetdata-c21c3b0befeb46a51b6bf3758ffa30813bea0ff0.tar.xz
netdata-c21c3b0befeb46a51b6bf3758ffa30813bea0ff0.zip
Adding upstream version 1.44.3.upstream/1.44.3
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr')
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/README.md8
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_manager.c431
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_manager.h86
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_manager_host.c324
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_manager_host.h23
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_mgr.cmake17
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/ble_msg.c115
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/coding_rule.txt15
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/event.c204
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/event.h41
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/message.c88
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_config.h23
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_jeff.c1883
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_jeff.h29
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_utils.c230
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_wasm_app.c1743
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_wasm_app.h143
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_wasm_lib.c58
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_wasm_lib.h21
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/platform/darwin/app_mgr_darwin.c1
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/platform/linux/app_mgr_linux.c46
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/platform/zephyr/app_mgr_zephyr.c64
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/resource_reg.c211
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/watchdog.c140
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/watchdog.h40
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-mgr-shared/app_manager_export.h307
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-mgr-shared/app_mgr_shared.cmake16
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-mgr-shared/host_link.h31
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/module.json52
29 files changed, 6390 insertions, 0 deletions
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/README.md b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/README.md
new file mode 100644
index 000000000..31c705e1f
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/README.md
@@ -0,0 +1,8 @@
+# Remote application management
+
+The WAMR application manager supports [remote application management](../core/app-mgr) from the host environment or the cloud through any physical communications such as TCP, UPD, UART, BLE, etc. Its modular design makes it able to support application management for different managed runtimes.
+
+The tool [host_tool](../test-tools/host-tool) communicates to the WAMR app manager for installing/uninstalling the WASM applications on companion chip from the host system. And the [IoT App Store Demo](../test-tools/IoT-APP-Store-Demo/) shows the conception of remotely managing the device applications from the cloud.
+
+
+<img src="../../doc/pics/wamr-arch.JPG" width="80%">
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_manager.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_manager.c
new file mode 100644
index 000000000..b27ee96eb
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_manager.c
@@ -0,0 +1,431 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include "app_manager.h"
+#include "app_manager_host.h"
+#include "bh_platform.h"
+#include "bi-inc/attr_container.h"
+#include "event.h"
+#include "watchdog.h"
+#include "coap_ext.h"
+
+/* Queue of app manager */
+static bh_queue *g_app_mgr_queue;
+static bool g_app_mgr_started;
+
+void *
+get_app_manager_queue()
+{
+ return g_app_mgr_queue;
+}
+
+void
+app_manager_post_applets_update_event()
+{
+ module_data *m_data;
+ attr_container_t *attr_cont;
+ request_t msg;
+ int num = 0, i = 0;
+ char *url = "/applets";
+
+ if (!event_is_registered(url))
+ return;
+
+ if (!(attr_cont = attr_container_create("All Applets"))) {
+ app_manager_printf("Post applets update event failed: "
+ "allocate memory failed.");
+ return;
+ }
+
+ os_mutex_lock(&module_data_list_lock);
+
+ m_data = module_data_list;
+ while (m_data) {
+ num++;
+ m_data = m_data->next;
+ }
+
+ if (!(attr_container_set_int(&attr_cont, "num", num))) {
+ app_manager_printf("Post applets update event failed: "
+ "set attr container key failed.");
+ goto fail;
+ }
+
+ m_data = module_data_list;
+ while (m_data) {
+ char buf[32];
+ i++;
+ snprintf(buf, sizeof(buf), "%s%d", "applet", i);
+ if (!(attr_container_set_string(&attr_cont, buf,
+ m_data->module_name))) {
+ app_manager_printf("Post applets update event failed: "
+ "set attr applet name key failed.");
+ goto fail;
+ }
+ snprintf(buf, sizeof(buf), "%s%d", "heap", i);
+ if (!(attr_container_set_int(&attr_cont, buf, m_data->heap_size))) {
+ app_manager_printf("Post applets update event failed: "
+ "set attr heap key failed.");
+ goto fail;
+ }
+ m_data = m_data->next;
+ }
+
+ memset(&msg, 0, sizeof(msg));
+ msg.url = url;
+ msg.action = COAP_EVENT;
+ msg.payload = (char *)attr_cont;
+ send_request_to_host(&msg);
+
+ app_manager_printf("Post applets update event success!\n");
+ attr_container_dump(attr_cont);
+
+fail:
+ os_mutex_unlock(&module_data_list_lock);
+ attr_container_destroy(attr_cont);
+}
+
+static int
+get_applets_count()
+{
+ module_data *m_data;
+ int num = 0;
+
+ os_mutex_lock(&module_data_list_lock);
+
+ m_data = module_data_list;
+ while (m_data) {
+ num++;
+ m_data = m_data->next;
+ }
+
+ os_mutex_unlock(&module_data_list_lock);
+
+ return num;
+}
+
+/* Query fw apps info if name = NULL, otherwise query specify app */
+static bool
+app_manager_query_applets(request_t *msg, const char *name)
+{
+ module_data *m_data;
+ attr_container_t *attr_cont;
+ int num = 0, i = 0, len;
+ bool ret = false, found = false;
+ response_t response[1] = { 0 };
+
+ attr_cont = attr_container_create("Applets Info");
+ if (!attr_cont) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Query Applets failed: allocate memory failed.");
+ return false;
+ }
+
+ os_mutex_lock(&module_data_list_lock);
+
+ m_data = module_data_list;
+ while (m_data) {
+ num++;
+ m_data = m_data->next;
+ }
+
+ if (name == NULL && !(attr_container_set_int(&attr_cont, "num", num))) {
+ SEND_ERR_RESPONSE(
+ msg->mid, "Query Applets failed: set attr container key failed.");
+ goto fail;
+ }
+
+ m_data = module_data_list;
+ while (m_data) {
+ char buf[32];
+
+ if (name == NULL) {
+ i++;
+ snprintf(buf, sizeof(buf), "%s%d", "applet", i);
+ if (!(attr_container_set_string(&attr_cont, buf,
+ m_data->module_name))) {
+ SEND_ERR_RESPONSE(msg->mid, "Query Applets failed: "
+ "set attr container key failed.");
+ goto fail;
+ }
+ snprintf(buf, sizeof(buf), "%s%d", "heap", i);
+ if (!(attr_container_set_int(&attr_cont, buf, m_data->heap_size))) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Query Applets failed: "
+ "set attr container heap key failed.");
+ goto fail;
+ }
+ }
+ else if (!strcmp(name, m_data->module_name)) {
+ found = true;
+ if (!(attr_container_set_string(&attr_cont, "name",
+ m_data->module_name))) {
+ SEND_ERR_RESPONSE(msg->mid, "Query Applet failed: "
+ "set attr container key failed.");
+ goto fail;
+ }
+ if (!(attr_container_set_int(&attr_cont, "heap",
+ m_data->heap_size))) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Query Applet failed: "
+ "set attr container heap key failed.");
+ goto fail;
+ }
+ }
+
+ m_data = m_data->next;
+ }
+
+ if (name != NULL && !found) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Query Applet failed: the app is not found.");
+ goto fail;
+ }
+
+ len = attr_container_get_serialize_length(attr_cont);
+
+ make_response_for_request(msg, response);
+ set_response(response, CONTENT_2_05, FMT_ATTR_CONTAINER, (char *)attr_cont,
+ len);
+ send_response_to_host(response);
+
+ ret = true;
+ app_manager_printf("Query Applets success!\n");
+ attr_container_dump(attr_cont);
+
+fail:
+ os_mutex_unlock(&module_data_list_lock);
+ attr_container_destroy(attr_cont);
+ return ret;
+}
+
+void
+applet_mgt_reqeust_handler(request_t *request, void *unused)
+{
+ bh_message_t msg;
+ /* deep copy, but not use app self heap, but use global heap */
+ request_t *req = clone_request(request);
+
+ if (!req)
+ return;
+
+ msg = bh_new_msg(RESTFUL_REQUEST, req, sizeof(*req), request_cleaner);
+ if (!msg) {
+ request_cleaner(req);
+ return;
+ }
+
+ bh_post_msg2(get_app_manager_queue(), msg);
+}
+
+/* return -1 for error */
+static int
+get_module_type(char *kv_str)
+{
+ int module_type = -1;
+ char type_str[16] = { 0 };
+
+ find_key_value(kv_str, strlen(kv_str), "type", type_str,
+ sizeof(type_str) - 1, '&');
+
+ if (strlen(type_str) == 0)
+ module_type = Module_WASM_App;
+ else if (strcmp(type_str, "jeff") == 0)
+ module_type = Module_Jeff;
+ else if (strcmp(type_str, "wasm") == 0)
+ module_type = Module_WASM_App;
+ else if (strcmp(type_str, "wasmlib") == 0)
+ module_type = Module_WASM_Lib;
+
+ return module_type;
+}
+
+#define APP_NAME_MAX_LEN 128
+
+/* Queue callback of App Manager */
+
+static void
+app_manager_queue_callback(void *message, void *arg)
+{
+ request_t *request = (request_t *)bh_message_payload((bh_message_t)message);
+ int mid = request->mid, module_type, offset;
+
+ (void)arg;
+
+ if ((offset =
+ check_url_start(request->url, strlen(request->url), "/applet"))
+ > 0) {
+ module_type = get_module_type(request->url + offset);
+
+ if (module_type == -1) {
+ SEND_ERR_RESPONSE(mid,
+ "Applet Management failed: invalid module type.");
+ goto fail;
+ }
+
+ /* Install Applet */
+ if (request->action == COAP_PUT) {
+ if (get_applets_count() >= MAX_APP_INSTALLATIONS) {
+ SEND_ERR_RESPONSE(
+ mid,
+ "Install Applet failed: exceed max app installations.");
+ goto fail;
+ }
+
+ if (!request->payload) {
+ SEND_ERR_RESPONSE(mid,
+ "Install Applet failed: invalid payload.");
+ goto fail;
+ }
+ if (g_module_interfaces[module_type]
+ && g_module_interfaces[module_type]->module_install) {
+ if (!g_module_interfaces[module_type]->module_install(request))
+ goto fail;
+ }
+ }
+ /* Uninstall Applet */
+ else if (request->action == COAP_DELETE) {
+ module_type = get_module_type(request->url + offset);
+ if (module_type == -1) {
+ SEND_ERR_RESPONSE(
+ mid, "Uninstall Applet failed: invalid module type.");
+ goto fail;
+ }
+
+ if (g_module_interfaces[module_type]
+ && g_module_interfaces[module_type]->module_uninstall) {
+ if (!g_module_interfaces[module_type]->module_uninstall(
+ request))
+ goto fail;
+ }
+ }
+ /* Query Applets installed */
+ else if (request->action == COAP_GET) {
+ char name[APP_NAME_MAX_LEN] = { 0 };
+ char *properties = request->url + offset;
+ find_key_value(properties, strlen(properties), "name", name,
+ sizeof(name) - 1, '&');
+ if (strlen(name) > 0)
+ app_manager_query_applets(request, name);
+ else
+ app_manager_query_applets(request, NULL);
+ }
+ else {
+ SEND_ERR_RESPONSE(mid, "Invalid request of applet: invalid action");
+ }
+ }
+ /* Event Register/Unregister */
+ else if ((offset = check_url_start(request->url, strlen(request->url),
+ "/event/"))
+ > 0) {
+ char url_buf[256] = { 0 };
+
+ strncpy(url_buf, request->url + offset, sizeof(url_buf) - 1);
+
+ if (!event_handle_event_request(request->action, url_buf, ID_HOST)) {
+ SEND_ERR_RESPONSE(mid, "Handle event request failed.");
+ goto fail;
+ }
+ send_error_response_to_host(mid, CONTENT_2_05, NULL); /* OK */
+ }
+ else {
+ int i;
+ for (i = 0; i < Module_Max; i++) {
+ if (g_module_interfaces[i]
+ && g_module_interfaces[i]->module_handle_host_url) {
+ if (g_module_interfaces[i]->module_handle_host_url(request))
+ break;
+ }
+ }
+ }
+
+fail:
+ return;
+}
+
+static void
+module_interfaces_init()
+{
+ int i;
+ for (i = 0; i < Module_Max; i++) {
+ if (g_module_interfaces[i] && g_module_interfaces[i]->module_init)
+ g_module_interfaces[i]->module_init();
+ }
+}
+
+void
+app_manager_startup(host_interface *interface)
+{
+ module_interfaces_init();
+
+ /* Create queue of App Manager */
+ g_app_mgr_queue = bh_queue_create();
+ if (!g_app_mgr_queue)
+ return;
+
+ if (!module_data_list_init())
+ goto fail1;
+
+ if (!watchdog_startup())
+ goto fail2;
+
+ /* Initialize Host */
+ app_manager_host_init(interface);
+
+ am_register_resource("/app/", targeted_app_request_handler, ID_APP_MGR);
+
+ /* /app/ and /event/ are both processed by applet_mgt_reqeust_handler */
+ am_register_resource("/applet", applet_mgt_reqeust_handler, ID_APP_MGR);
+ am_register_resource("/event/", applet_mgt_reqeust_handler, ID_APP_MGR);
+
+ app_manager_printf("App Manager started.\n");
+
+ g_app_mgr_started = true;
+
+ /* Enter loop run */
+ bh_queue_enter_loop_run(g_app_mgr_queue, app_manager_queue_callback, NULL);
+
+ g_app_mgr_started = false;
+
+ /* Destroy registered resources */
+ am_cleanup_registeration(ID_APP_MGR);
+
+ /* Destroy watchdog */
+ watchdog_destroy();
+
+fail2:
+ module_data_list_destroy();
+
+fail1:
+ bh_queue_destroy(g_app_mgr_queue);
+}
+
+bool
+app_manager_is_started(void)
+{
+ return g_app_mgr_started;
+}
+
+#include "module_config.h"
+
+module_interface *g_module_interfaces[Module_Max] = {
+#if ENABLE_MODULE_JEFF != 0
+ &jeff_module_interface,
+#else
+ NULL,
+#endif
+
+#if ENABLE_MODULE_WASM_APP != 0
+ &wasm_app_module_interface,
+#else
+ NULL,
+#endif
+
+#if ENABLE_MODULE_WASM_LIB != 0
+ &wasm_lib_module_interface
+#else
+ NULL
+#endif
+};
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_manager.h b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_manager.h
new file mode 100644
index 000000000..ce83bd170
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_manager.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifndef APP_MANAGER_H
+#define APP_MANAGER_H
+
+#include "bh_platform.h"
+#include "app_manager_export.h"
+#include "native_interface.h"
+#include "bi-inc/shared_utils.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define APP_MGR_MALLOC wasm_runtime_malloc
+#define APP_MGR_FREE wasm_runtime_free
+
+/* os_printf is defined in each platform */
+#define app_manager_printf os_printf
+
+#define SEND_ERR_RESPONSE(mid, err_msg) \
+ do { \
+ app_manager_printf("%s\n", err_msg); \
+ send_error_response_to_host(mid, INTERNAL_SERVER_ERROR_5_00, err_msg); \
+ } while (0)
+
+extern module_interface *g_module_interfaces[Module_Max];
+
+/* Lock of the module data list */
+extern korp_mutex module_data_list_lock;
+
+/* Module data list */
+extern module_data *module_data_list;
+
+void
+app_manager_add_module_data(module_data *m_data);
+
+void
+app_manager_del_module_data(module_data *m_data);
+
+bool
+module_data_list_init();
+
+void
+module_data_list_destroy();
+
+bool
+app_manager_is_interrupting_module(uint32 module_type, void *module_inst);
+
+void
+release_module(module_data *m_data);
+
+void
+module_data_list_remove(module_data *m_data);
+
+void *
+app_manager_timer_create(void (*timer_callback)(void *),
+ watchdog_timer *wd_timer);
+
+void
+app_manager_timer_destroy(void *timer);
+
+void
+app_manager_timer_start(void *timer, int timeout);
+
+void
+app_manager_timer_stop(void *timer);
+
+watchdog_timer *
+app_manager_get_wd_timer_from_timer_handle(void *timer);
+
+int
+app_manager_signature_verify(const uint8_t *file, unsigned int file_len,
+ const uint8_t *signature, unsigned int sig_size);
+
+void
+targeted_app_request_handler(request_t *request, void *unused);
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_manager_host.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_manager_host.c
new file mode 100644
index 000000000..08b5df309
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_manager_host.c
@@ -0,0 +1,324 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include "bh_platform.h"
+#include "app_manager_host.h"
+#include "app_manager.h"
+#include "app_manager_export.h"
+#include "coap_ext.h"
+
+/* host communication interface */
+static host_interface host_commu;
+
+/* IMRTLink Two leading bytes */
+static unsigned char leadings[] = { (unsigned char)0x12, (unsigned char)0x34 };
+
+/* IMRTLink Receiving Phase */
+typedef enum recv_phase_t {
+ Phase_Non_Start,
+ Phase_Leading,
+ Phase_Type,
+ Phase_Size,
+ Phase_Payload,
+ Phase_Ignoring
+} recv_phase_t;
+
+/* IMRTLink Receive Context */
+typedef struct recv_context_t {
+ recv_phase_t phase;
+ bh_link_msg_t message;
+ int size_in_phase;
+} recv_context_t;
+
+/* Current IMRTLink receive context */
+static recv_context_t recv_ctx;
+
+/* Lock for device write */
+static korp_mutex host_lock;
+
+static bool enable_log = false;
+
+static bool
+is_little_endian()
+{
+ long i = 0x01020304;
+ unsigned char *c = (unsigned char *)&i;
+ return (*c == 0x04) ? true : false;
+}
+
+static void
+exchange32(uint8 *pData)
+{
+ uint8 value = *pData;
+ *pData = *(pData + 3);
+ *(pData + 3) = value;
+
+ value = *(pData + 1);
+ *(pData + 1) = *(pData + 2);
+ *(pData + 2) = value;
+}
+
+/* return:
+ * 1: complete message received
+ * 0: incomplete message received
+ */
+static int
+on_imrt_link_byte_arrive(unsigned char ch, recv_context_t *ctx)
+{
+ if (ctx->phase == Phase_Non_Start) {
+ ctx->message.payload_size = 0;
+
+ if (ctx->message.payload) {
+ APP_MGR_FREE(ctx->message.payload);
+ ctx->message.payload = NULL;
+ }
+
+ if (ch == leadings[0]) {
+ if (enable_log)
+ app_manager_printf("##On byte arrive: got leading 0\n");
+ ctx->phase = Phase_Leading;
+ }
+
+ return 0;
+ }
+ else if (ctx->phase == Phase_Leading) {
+ if (ch == leadings[1]) {
+ if (enable_log)
+ app_manager_printf("##On byte arrive: got leading 1\n");
+ ctx->phase = Phase_Type;
+ }
+ else
+ ctx->phase = Phase_Non_Start;
+
+ return 0;
+ }
+ else if (ctx->phase == Phase_Type) {
+ if (ctx->size_in_phase++ == 0) {
+ if (enable_log)
+ app_manager_printf("##On byte arrive: got type 0\n");
+ ctx->message.message_type = ch;
+ }
+ else {
+ if (enable_log)
+ app_manager_printf("##On byte arrive: got type 1\n");
+ ctx->message.message_type |= (ch << 8);
+ ctx->message.message_type = ntohs(ctx->message.message_type);
+ ctx->phase = Phase_Size;
+ ctx->size_in_phase = 0;
+ }
+
+ return 0;
+ }
+ else if (ctx->phase == Phase_Size) {
+ unsigned char *p = (unsigned char *)&ctx->message.payload_size;
+
+ if (enable_log)
+ app_manager_printf("##On byte arrive: got payload_size, byte %d\n",
+ ctx->size_in_phase);
+ p[ctx->size_in_phase++] = ch;
+
+ if (ctx->size_in_phase == sizeof(ctx->message.payload_size)) {
+ ctx->message.payload_size = ntohl(ctx->message.payload_size);
+ ctx->phase = Phase_Payload;
+
+ if (enable_log)
+ app_manager_printf("##On byte arrive: payload_size: %d\n",
+ ctx->message.payload_size);
+ if (ctx->message.payload) {
+ APP_MGR_FREE(ctx->message.payload);
+ ctx->message.payload = NULL;
+ }
+
+ /* message completion */
+ if (ctx->message.payload_size == 0) {
+ ctx->phase = Phase_Non_Start;
+ if (enable_log)
+ app_manager_printf("##On byte arrive: receive end, "
+ "payload_size is 0.\n");
+ return 1;
+ }
+
+ if (ctx->message.message_type != INSTALL_WASM_APP) {
+ ctx->message.payload =
+ (char *)APP_MGR_MALLOC(ctx->message.payload_size);
+ if (!ctx->message.payload) {
+ ctx->phase = Phase_Non_Start;
+ return 0;
+ }
+ }
+
+ ctx->phase = Phase_Payload;
+ ctx->size_in_phase = 0;
+ }
+
+ return 0;
+ }
+ else if (ctx->phase == Phase_Payload) {
+ if (ctx->message.message_type == INSTALL_WASM_APP) {
+ int received_size;
+ module_on_install_request_byte_arrive_func module_on_install =
+ g_module_interfaces[Module_WASM_App]->module_on_install;
+
+ ctx->size_in_phase++;
+
+ if (module_on_install != NULL) {
+ if (module_on_install(ch, ctx->message.payload_size,
+ &received_size)) {
+ if (received_size == ctx->message.payload_size) {
+ /* whole wasm app received */
+ ctx->phase = Phase_Non_Start;
+ return 1;
+ }
+ }
+ else {
+ /* receive or handle fail */
+ if (ctx->size_in_phase < ctx->message.payload_size) {
+ ctx->phase = Phase_Ignoring;
+ }
+ else {
+ ctx->phase = Phase_Non_Start;
+ ctx->size_in_phase = 0;
+ }
+ return 0;
+ }
+ }
+ else {
+ ctx->phase = Phase_Non_Start;
+ ctx->size_in_phase = 0;
+ return 0;
+ }
+ }
+ else {
+ ctx->message.payload[ctx->size_in_phase++] = ch;
+
+ if (ctx->size_in_phase == ctx->message.payload_size) {
+ ctx->phase = Phase_Non_Start;
+ if (enable_log)
+ app_manager_printf("##On byte arrive: receive end, "
+ "payload_size is %d.\n",
+ ctx->message.payload_size);
+ return 1;
+ }
+ return 0;
+ }
+ }
+ else if (ctx->phase == Phase_Ignoring) {
+ ctx->size_in_phase++;
+ if (ctx->size_in_phase == ctx->message.payload_size) {
+ if (ctx->message.payload)
+ APP_MGR_FREE(ctx->message.payload);
+ memset(ctx, 0, sizeof(*ctx));
+ return 0;
+ }
+ }
+
+ return 0;
+}
+
+int
+aee_host_msg_callback(void *msg, uint32_t msg_len)
+{
+ unsigned char *p = msg, *p_end = p + msg_len;
+
+ /*app_manager_printf("App Manager receive %d bytes from Host\n", msg_len);*/
+
+ for (; p < p_end; p++) {
+ int ret = on_imrt_link_byte_arrive(*p, &recv_ctx);
+
+ if (ret == 1) {
+ if (recv_ctx.message.payload) {
+ int msg_type = recv_ctx.message.message_type;
+
+ if (msg_type == REQUEST_PACKET) {
+ request_t request;
+ memset(&request, 0, sizeof(request));
+
+ if (!unpack_request(recv_ctx.message.payload,
+ recv_ctx.message.payload_size,
+ &request))
+ continue;
+
+ request.sender = ID_HOST;
+
+ am_dispatch_request(&request);
+ }
+ else {
+ app_manager_printf("unexpected host msg type: %d\n",
+ msg_type);
+ }
+
+ APP_MGR_FREE(recv_ctx.message.payload);
+ recv_ctx.message.payload = NULL;
+ recv_ctx.message.payload_size = 0;
+ }
+
+ memset(&recv_ctx, 0, sizeof(recv_ctx));
+ }
+ }
+
+ return 0;
+}
+
+bool
+app_manager_host_init(host_interface *interface)
+{
+ if (os_mutex_init(&host_lock) != 0) {
+ return false;
+ }
+ memset(&recv_ctx, 0, sizeof(recv_ctx));
+
+ host_commu.init = interface->init;
+ host_commu.send = interface->send;
+ host_commu.destroy = interface->destroy;
+
+ if (host_commu.init != NULL) {
+ if (!host_commu.init()) {
+ os_mutex_destroy(&host_lock);
+ return false;
+ }
+ }
+
+ return true;
+}
+
+int
+app_manager_host_send_msg(int msg_type, const char *buf, int size)
+{
+ /* send an IMRT LINK message contains the buf as payload */
+ if (host_commu.send != NULL) {
+ int size_s = size, n;
+ char header[16];
+
+ os_mutex_lock(&host_lock);
+ /* leading bytes */
+ bh_memcpy_s(header, 2, leadings, 2);
+
+ /* message type */
+ /* TODO: check if use network byte order!!! */
+ *((uint16 *)(header + 2)) = htons(msg_type);
+
+ /* payload length */
+ if (is_little_endian())
+ exchange32((uint8 *)&size_s);
+
+ bh_memcpy_s(header + 4, 4, &size_s, 4);
+ n = host_commu.send(NULL, header, 8);
+ if (n != 8) {
+ os_mutex_unlock(&host_lock);
+ return 0;
+ }
+
+ /* payload */
+ n = host_commu.send(NULL, buf, size);
+ os_mutex_unlock(&host_lock);
+
+ app_manager_printf("sent %d bytes to host\n", n);
+ return n;
+ }
+ else {
+ app_manager_printf("no send api provided\n");
+ }
+ return 0;
+}
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_manager_host.h b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_manager_host.h
new file mode 100644
index 000000000..b19404f91
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_manager_host.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifndef _APP_MANAGER_HOST_H_
+#define _APP_MANAGER_HOST_H_
+
+#include "wasm_export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define HOST_MODE_AON 1
+#define HOST_MODE_UART 2
+#define HOST_MODE_TEST 3
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_mgr.cmake b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_mgr.cmake
new file mode 100644
index 000000000..fd6e69098
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_mgr.cmake
@@ -0,0 +1,17 @@
+# Copyright (C) 2019 Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+set (__APP_MGR_DIR ${CMAKE_CURRENT_LIST_DIR})
+
+include_directories(${__APP_MGR_DIR})
+
+
+file (GLOB source_all ${__APP_MGR_DIR}/*.c ${__APP_MGR_DIR}/platform/${WAMR_BUILD_PLATFORM}/*.c)
+
+set (APP_MGR_SOURCE ${source_all})
+
+file (GLOB header
+ ${__APP_MGR_DIR}/module_wasm_app.h
+)
+LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header})
+
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/ble_msg.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/ble_msg.c
new file mode 100644
index 000000000..1d19dddaf
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/ble_msg.c
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#if 0
+
+#define BLUETOOTH_INTERFACE_ADVERTISMENT_DATA_LENGTH 31
+/* ble_device_info */
+typedef struct ble_device_info {
+
+ /* address type */
+ uint8_t address_type;
+ /* MAC of Device */
+ uint8_t mac[6];
+ /* security level */
+ uint8_t security_level;
+ /* signal strength */
+ int8_t rssi;
+ /* uuid_16_type */
+ int8_t uuid_16_type;
+ /* uuid_32_type */
+ int8_t uuid_32_type;
+ /* uuid_128_type */
+ int8_t uuid_128_type;
+ /* error code */
+ uint8_t error_code;
+ /* scan response length*/
+ uint16_t adv_data_len;
+ /* advertisement data */
+ uint8_t *adv_data;
+ /* scan response length*/
+ uint16_t scan_response_len;
+ /* scan response */
+ uint8_t *scan_response;
+ /* next device */
+ struct ble_device_info *next;
+ /* private data length */
+ int private_data_length;
+ /* private data */
+ uint8_t *private_data;
+ /* value handle*/
+ uint16_t value_handle;
+ /* ccc handle*/
+ uint16_t ccc_handle;
+
+}ble_device_info;
+
+/* BLE message sub type */
+typedef enum BLE_SUB_EVENT_TYPE {
+ BLE_SUB_EVENT_DISCOVERY,
+ BLE_SUB_EVENT_CONNECTED,
+ BLE_SUB_EVENT_DISCONNECTED,
+ BLE_SUB_EVENT_NOTIFICATION,
+ BLE_SUB_EVENT_INDICATION,
+ BLE_SUB_EVENT_PASSKEYENTRY,
+ BLE_SUB_EVENT_SECURITY_LEVEL_CHANGE
+}BLE_SUB_EVENT_TYPE;
+
+/* Queue message, for BLE Event */
+typedef struct bh_queue_ble_sub_msg_t {
+ /* message type, should be one of QUEUE_MSG_TYPE */
+ BLE_SUB_EVENT_TYPE type;
+ /* payload size */
+ /*uint32_t payload_size;*/
+ char payload[1];
+}bh_queue_ble_sub_msg_t;
+
+static void
+app_instance_free_ble_msg(char *msg)
+{
+ bh_queue_ble_sub_msg_t *ble_msg = (bh_queue_ble_sub_msg_t *)msg;
+ ble_device_info *dev_info;
+
+ dev_info = (ble_device_info *) ble_msg->payload;
+
+ if (dev_info->scan_response != NULL)
+ APP_MGR_FREE(dev_info->scan_response);
+
+ if (dev_info->private_data != NULL)
+ APP_MGR_FREE(dev_info->private_data);
+
+ if (dev_info->adv_data != NULL)
+ APP_MGR_FREE(dev_info->adv_data);
+
+ if (dev_info != NULL)
+ APP_MGR_FREE(dev_info);
+}
+
+static void
+app_instance_queue_free_callback(bh_message_t queue_msg)
+{
+
+ char * payload = (char *)bh_message_payload(queue_msg);
+ if(payload == NULL)
+ return;
+
+ switch (bh_message_type(queue_msg))
+ {
+ /*
+ case SENSOR_EVENT: {
+ bh_sensor_event_t *sensor_event = (bh_sensor_event_t *) payload;
+ attr_container_t *event = sensor_event->event;
+ attr_container_destroy(event);
+ }
+ break;
+ */
+ case BLE_EVENT: {
+ app_instance_free_ble_msg(payload);
+ break;
+ }
+ }
+}
+
+#endif
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/coding_rule.txt b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/coding_rule.txt
new file mode 100644
index 000000000..4598872a3
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/coding_rule.txt
@@ -0,0 +1,15 @@
+Coding rules:
+
+1. module implementation can include the export head files of associated runtime
+
+2. app manager only call access the module implementation through the interface API
+
+3. module implementation can call the app manager API from following files:
+ - util.c
+ - message.c
+
+4. platform API: To define it
+
+5. Any platform dependent implementation of app manager should be implemented in the
+ platform specific source file, such as app_mgr_zephyr.c
+
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/event.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/event.c
new file mode 100644
index 000000000..a21065fab
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/event.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include <string.h>
+
+#include "event.h"
+
+#include "app_manager.h"
+#include "coap_ext.h"
+
+typedef struct _subscribe {
+ struct _subscribe *next;
+ uint32 subscriber_id;
+} subscribe_t;
+
+typedef struct _event {
+ struct _event *next;
+ int subscriber_size;
+ subscribe_t *subscribers;
+ char url[1]; /* event url */
+} event_reg_t;
+
+event_reg_t *g_events = NULL;
+
+static bool
+find_subscriber(event_reg_t *reg, uint32 id, bool remove_found)
+{
+ subscribe_t *c = reg->subscribers;
+ subscribe_t *prev = NULL;
+ while (c) {
+ subscribe_t *next = c->next;
+ if (c->subscriber_id == id) {
+ if (remove_found) {
+ if (prev)
+ prev->next = next;
+ else
+ reg->subscribers = next;
+
+ APP_MGR_FREE(c);
+ }
+
+ return true;
+ }
+ else {
+ prev = c;
+ c = next;
+ }
+ }
+
+ return false;
+}
+
+static bool
+check_url(const char *url)
+{
+ if (*url == 0)
+ return false;
+
+ return true;
+}
+
+bool
+am_register_event(const char *url, uint32_t reg_client)
+{
+ event_reg_t *current = g_events;
+
+ app_manager_printf("am_register_event adding url:(%s)\n", url);
+
+ if (!check_url(url)) {
+ app_manager_printf("am_register_event: invaild url:(%s)\n", url);
+ return false;
+ }
+ while (current) {
+ if (strcmp(url, current->url) == 0)
+ break;
+ current = current->next;
+ }
+
+ if (current == NULL) {
+ if (NULL
+ == (current = (event_reg_t *)APP_MGR_MALLOC(
+ offsetof(event_reg_t, url) + strlen(url) + 1))) {
+ app_manager_printf("am_register_event: malloc fail\n");
+ return false;
+ }
+
+ memset(current, 0, sizeof(event_reg_t));
+ bh_strcpy_s(current->url, strlen(url) + 1, url);
+ current->next = g_events;
+ g_events = current;
+ }
+
+ if (find_subscriber(current, reg_client, false)) {
+ return true;
+ }
+ else {
+ subscribe_t *s = (subscribe_t *)APP_MGR_MALLOC(sizeof(subscribe_t));
+ if (s == NULL)
+ return false;
+
+ memset(s, 0, sizeof(subscribe_t));
+ s->subscriber_id = reg_client;
+ s->next = current->subscribers;
+ current->subscribers = s;
+ app_manager_printf("client: %d registered event (%s)\n", reg_client,
+ url);
+ }
+
+ return true;
+}
+
+// @url: NULL means the client wants to unregister all its subscribed items
+bool
+am_unregister_event(const char *url, uint32_t reg_client)
+{
+ event_reg_t *current = g_events, *pre = NULL;
+
+ while (current != NULL) {
+ if (url == NULL || strcmp(current->url, url) == 0) {
+ event_reg_t *next = current->next;
+ if (find_subscriber(current, reg_client, true)) {
+ app_manager_printf("client: %d deregistered event (%s)\n",
+ reg_client, current->url);
+ }
+
+ // remove the registration if no client subscribe it
+ if (current->subscribers == NULL) {
+ app_manager_printf("unregister for event deleted url:(%s)\n",
+ current->url);
+ if (pre)
+ pre->next = next;
+ else
+ g_events = next;
+ APP_MGR_FREE(current);
+ current = next;
+ continue;
+ }
+ }
+ pre = current;
+ current = current->next;
+ }
+
+ return true;
+}
+
+bool
+event_handle_event_request(uint8_t code, const char *event_url,
+ uint32_t reg_client)
+{
+ if (code == COAP_PUT) { /* register */
+ return am_register_event(event_url, reg_client);
+ }
+ else if (code == COAP_DELETE) { /* unregister */
+ return am_unregister_event(event_url, reg_client);
+ }
+ else {
+ /* invalid request */
+ return false;
+ }
+}
+
+void
+am_publish_event(request_t *event)
+{
+ bh_assert(event->action == COAP_EVENT);
+
+ event_reg_t *current = g_events;
+ while (current) {
+ if (0 == strcmp(event->url, current->url)) {
+ subscribe_t *c = current->subscribers;
+ while (c) {
+ if (c->subscriber_id == ID_HOST) {
+ send_request_to_host(event);
+ }
+ else {
+ module_request_handler(event,
+ (void *)(uintptr_t)c->subscriber_id);
+ }
+ c = c->next;
+ }
+
+ return;
+ }
+
+ current = current->next;
+ }
+}
+
+bool
+event_is_registered(const char *event_url)
+{
+ event_reg_t *current = g_events;
+
+ while (current != NULL) {
+ if (strcmp(current->url, event_url) == 0) {
+ return true;
+ }
+ current = current->next;
+ }
+
+ return false;
+}
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/event.h b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/event.h
new file mode 100644
index 000000000..36ced521d
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/event.h
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifndef _EVENT_H_
+#define _EVENT_H_
+
+#include "bh_platform.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * Handle event request from host agent
+ *
+ * @param code the coap packet code
+ * @param event_url the event url
+ *
+ * @return true if success, false otherwise
+ */
+bool
+event_handle_event_request(uint8_t code, const char *event_url,
+ uint32_t register);
+
+/**
+ * Test whether the event is registered
+ *
+ * @param event_url the event url
+ *
+ * @return true for registered, false for not registered
+ */
+bool
+event_is_registered(const char *event_url);
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif /* _EVENT_H_ */
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/message.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/message.c
new file mode 100644
index 000000000..aac7a2364
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/message.c
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include "app_manager.h"
+#include "app_manager_host.h"
+#include "event.h"
+#include "bi-inc/attr_container.h"
+#include "coap_ext.h"
+
+#if 0
+bool send_coap_packet_to_host(coap_packet_t * packet)
+{
+ int size;
+ uint8_t *buf;
+
+ size = coap_serialize_message_tcp(&packet, &buf);
+ if (!buf || size == 0)
+ return false;
+
+ app_manager_host_send_msg(buf, size);
+ APP_MGR_FREE(buf);
+
+ return true;
+}
+#endif
+
+bool
+send_request_to_host(request_t *msg)
+{
+ if (COAP_EVENT == msg->action && !event_is_registered(msg->url)) {
+ app_manager_printf("Event is not registered\n");
+ return false;
+ }
+
+ int size;
+ char *packet = pack_request(msg, &size);
+ if (packet == NULL)
+ return false;
+
+ app_manager_host_send_msg(REQUEST_PACKET, packet, size);
+
+ free_req_resp_packet(packet);
+
+ return true;
+}
+
+bool
+send_response_to_host(response_t *response)
+{
+ int size;
+ char *packet = pack_response(response, &size);
+ if (packet == NULL)
+ return false;
+
+ app_manager_host_send_msg(RESPONSE_PACKET, packet, size);
+
+ free_req_resp_packet(packet);
+
+ return true;
+}
+
+bool
+send_error_response_to_host(int mid, int status, const char *msg)
+{
+ int payload_len = 0;
+ attr_container_t *payload = NULL;
+ response_t response[1] = { 0 };
+
+ if (msg) {
+ payload = attr_container_create("");
+ if (payload) {
+ attr_container_set_string(&payload, "error message", msg);
+ payload_len = attr_container_get_serialize_length(payload);
+ }
+ }
+
+ set_response(response, status, FMT_ATTR_CONTAINER, (const char *)payload,
+ payload_len);
+ response->mid = mid;
+
+ send_response_to_host(response);
+
+ if (payload)
+ attr_container_destroy(payload);
+ return true;
+}
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_config.h b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_config.h
new file mode 100644
index 000000000..b742fed3a
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_config.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifndef _MODULE_CONFIG_H_
+#define _MODULE_CONFIG_H_
+
+#define ENABLE_MODULE_JEFF 0
+#define ENABLE_MODULE_WASM_APP 1
+#define ENABLE_MODULE_WASM_LIB 1
+
+#ifdef ENABLE_MODULE_JEFF
+#include "module_jeff.h"
+#endif
+#ifdef ENABLE_MODULE_WASM_APP
+#include "module_wasm_app.h"
+#endif
+#ifdef ENABLE_MODULE_WASM_LIB
+#include "module_wasm_lib.h"
+#endif
+
+#endif /* _MODULE_CONFIG_H_ */
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_jeff.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_jeff.c
new file mode 100644
index 000000000..7c7f9510d
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_jeff.c
@@ -0,0 +1,1883 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifdef ENABLE_JEFF
+
+#include "module_jeff.h"
+#include "jeff_export.h"
+#include "../vmcore_jeff/jeff-runtime.h"
+#include "../vmcore_jeff/jeff-thread.h"
+#include "../vmcore_jeff/jeff-buffer.h"
+#include "../vmcore_jeff/jeff-tool.h"
+#include "../vmcore_jeff/jeff-tool-priv.h"
+#include "app_manager-host.h"
+#include "bh_queue.h"
+#include "attr-container.h"
+#include "attr-container-util.h"
+#include "bh_thread.h"
+#include "ems_gc.h"
+#include "coap_ext.h"
+#include "libcore.h"
+#include "event.h"
+#include "watchdog.h"
+
+#define DEFAULT_APPLET_TIMEOUT (3 * 60 * 1000)
+#define DEFAULT_APPLET_HEAP_SIZE (48 * 1024)
+#define MIN_APPLET_HEAP_SIZE (2 * 1024)
+#define MAX_APPLET_HEAP_SIZE (1024 * 1024)
+
+typedef struct jeff_applet_data {
+ /* Java Applet Object */
+ JeffObjectRef applet_obj;
+
+#if BEIHAI_ENABLE_TOOL_AGENT != 0
+ /* Whether the applet is in debug mode */
+ bool debug_mode;
+ /* Queue of the tool agent */
+ bh_queue *tool_agent_queue;
+#endif
+
+ /* VM instance */
+ JeffInstanceLocalRoot *vm_instance;
+ /* Applet Main file */
+ JeffFileHeaderLinked *main_file;
+ /* Permissions of the Java Applet */
+ char *perms;
+} jeff_applet_data;
+
+/* Jeff class com.intel.aee.AEEApplet */
+static JeffClassHeaderLinked *class_AEEApplet;
+/* Jeff class com.intel.aee.Request */
+static JeffClassHeaderLinked *class_AEERequest;
+/* Jeff class com.intel.aee.Timer */
+static JeffClassHeaderLinked *class_Timer;
+/* Jeff class com.intel.aee.Sensor */
+static JeffClassHeaderLinked *class_Sensor;
+/* Jeff class com.intel.aee.ble.BLEManager */
+static JeffClassHeaderLinked *class_BLEManager;
+/* Jeff class com.intel.aee.ble.BLEDevice */
+static JeffClassHeaderLinked *class_BLEDevice;
+/* Jeff class com.intel.aee.ble.BLEGattService */
+JeffClassHeaderLinked *class_BLEGattService;
+/* Jeff class com.intel.aee.ble.BLEGattCharacteristic */
+JeffClassHeaderLinked *class_BLEGattCharacteristic;
+/* Jeff class com.intel.aee.ble.BLEGattDescriptor */
+JeffClassHeaderLinked *class_BLEGattDescriptor;
+/* Jeff class com.intel.aee.gpio.GPIOChannel */
+static JeffClassHeaderLinked *class_GPIOChannel;
+/* Jeff method void com.intel.aee.AEEApplet.onInit() */
+static JeffMethodLinked *method_AEEApplet_onInit;
+/* Jeff method void com.intel.aee.AEEApplet.onDestroy() */
+static JeffMethodLinked *method_AEEApplet_onDestroy;
+/* Jeff method void com.intel.aee.AEEApplet.callOnRequest(Request request) */
+static JeffMethodLinked *method_AEEApplet_callOnRequest;
+/* Jeff method void com.intel.aee.Timer.callOnTimer() */
+static JeffMethodLinked *method_callOnTimer;
+/* Jeff method void com.intel.aee.Sensor.callOnSensorEvent() */
+static JeffMethodLinked *method_callOnSensorEvent;
+/* Jeff method void com.intel.aee.ble.BLEManager.callOnBLEStartDiscovery() */
+static JeffMethodLinked *method_callOnBLEStartDiscovery;
+/* Jeff method void com.intel.aee.ble.BLEManager.callOnBLEConnected() */
+static JeffMethodLinked *method_callOnBLEConnected;
+/* Jeff method void com.intel.aee.ble.BLEManager.callOnBLEDisonnected() */
+static JeffMethodLinked *method_callOnBLEDisconnected;
+/* Jeff method void com.intel.aee.ble.BLEManager.callOnBLENotification() */
+static JeffMethodLinked *method_callOnBLENotification;
+/* Jeff method void com.intel.aee.ble.BLEManager.callOnBLEIndication() */
+static JeffMethodLinked *method_callOnBLEIndication;
+/* Jeff method void com.intel.aee.ble.BLEManager.callOnBLEPasskeyEntry() */
+static JeffMethodLinked *method_callOnBLEPasskeyEntry;
+/* Jeff method void com.intel.aee.gpio.GPIOChannel.callOnGPIOInterrupt() */
+static JeffMethodLinked *method_callOnGPIOInterrupt;
+/* Jeff method void com.intel.aee.ble.BLEManager.getBLEDevice() */
+static JeffMethodLinked *method_callOnBLEManagerGetBLEDevice;
+
+static jeff_applet_data *
+app_manager_get_jeff_applet_data()
+{
+ module_data *m_data = app_manager_get_module_data(Module_Jeff);
+ return (jeff_applet_data *)m_data->internal_data;
+}
+
+#if BEIHAI_ENABLE_TOOL_AGENT != 0
+void *
+app_manager_get_tool_agent_queue()
+{
+ return app_manager_get_jeff_applet_data()->tool_agent_queue;
+}
+#endif
+
+#if BEIHAI_ENABLE_TOOL_AGENT != 0
+static bool
+is_tool_agent_running(module_data *m_data)
+{
+ jeff_applet_data *applet_data = (jeff_applet_data *)m_data->internal_data;
+ return (applet_data->debug_mode && applet_data->tool_agent_queue
+ && applet_data->vm_instance->tool_agent);
+}
+#endif
+
+static char *
+get_class_qname(const JeffString *pname, const JeffString *cname)
+{
+ unsigned int length =
+ pname->length ? pname->length + 2 + cname->length : cname->length + 1;
+ char *buf = APP_MGR_MALLOC(length), *p;
+
+ if (!buf)
+ return NULL;
+
+ p = buf;
+ if (pname->length) {
+ bh_memcpy_s(p, pname->length, pname->value, pname->length);
+ p += pname->length;
+ *p++ = '.';
+ }
+
+ bh_memcpy_s(p, cname->length, cname->value, cname->length);
+ p += cname->length;
+ *p = '\0';
+
+ return buf;
+}
+
+static void
+send_exception_event_to_host(const char *applet_name, const char *exc_name)
+{
+ attr_container_t *payload;
+ bh_request_msg_t msg;
+ char *url;
+ int url_len;
+
+ payload = attr_container_create("exception detail");
+ if (!payload) {
+ app_manager_printf("Send exception to host fail: allocate memory");
+ return;
+ }
+
+ if (!attr_container_set_string(&payload, "exception name", exc_name)
+ || !attr_container_set_string(&payload, "stack trace", "TODO")
+ || !attr_container_set_string(&payload, "applet name", applet_name)) {
+ app_manager_printf("Send exception to host fail: set attr");
+ goto fail;
+ }
+
+ url_len = strlen("/exception/") + strlen(applet_name);
+ url = APP_MGR_MALLOC(url_len + 1);
+ if (!url) {
+ app_manager_printf("Send exception to host fail: allocate memory");
+ goto fail;
+ }
+ memset(url, 0, url_len + 1);
+ bh_strcpy_s(url, url_len + 1, "/exception/");
+ bh_strcat_s(url, url_len + 1, applet_name);
+
+ memset(&msg, 0, sizeof(msg));
+ msg.url = url;
+ msg.action = COAP_PUT;
+ msg.payload = (char *)payload;
+
+ app_send_request_msg_to_host(&msg);
+
+ APP_MGR_FREE(url);
+
+fail:
+ attr_container_destroy(payload);
+}
+
+static bool
+check_exception()
+{
+ if (jeff_runtime_get_exception()) {
+ jeff_printf("V1.Exception thrown when running applet '%s':\n",
+ app_manager_get_module_name(Module_Jeff));
+ jeff_runtime_print_exception();
+ jeff_printf("\n");
+ jeff_printf(NULL);
+ }
+
+ if (!app_manager_is_interrupting_module(Module_Jeff)) {
+ attr_container_t *payload;
+ int payload_len;
+ JeffClassHeaderLinked *exc_class =
+ jeff_object_class_pointer(jeff_runtime_get_exception());
+ char *qname_buf = get_class_qname(jeff_get_class_pname(exc_class),
+ jeff_get_class_cname(exc_class));
+
+ /* Send exception event to host */
+ if (qname_buf) {
+ send_exception_event_to_host(
+ app_manager_get_module_name(Module_Jeff), qname_buf);
+ APP_MGR_FREE(qname_buf);
+ }
+
+ /* Uninstall the applet */
+ if ((payload = attr_container_create("uninstall myself"))) {
+ if (attr_container_set_string(
+ &payload, "name", app_manager_get_module_name(Module_Jeff))
+ /* Set special flag to prevent app manager making response
+ since this is an internal message */
+ && attr_container_set_bool(&payload, "do not reply me", true)) {
+ request_t request = { 0 };
+ payload_len = attr_container_get_serialize_length(payload);
+
+ init_request(request, "/applet", COAP_DELETE, (char *)payload, payload_len));
+ app_mgr_lookup_resource(&request);
+
+ // TODO: confirm this is right
+ attr_container_destroy(payload);
+ }
+ }
+
+ jeff_runtime_set_exception(NULL);
+ return true;
+ }
+
+ return false;
+}
+
+static bool
+app_manager_initialize_class(JeffClassHeaderLinked *c)
+{
+ jeff_runtime_initialize_class(c);
+ return !check_exception();
+}
+
+static bool
+app_manager_initialize_object(JeffObjectRef obj)
+{
+ jeff_runtime_initialize_object(obj);
+ return !check_exception();
+}
+
+static bool
+app_manager_call_java(JeffMethodLinked *method, unsigned int argc,
+ uint32 argv[], uint8 argt[])
+{
+ module_data *m_data = app_manager_get_module_data(Module_Jeff);
+ watchdog_timer *wd_timer = &m_data->wd_timer;
+ bool is_wd_started = false;
+
+#if BEIHAI_ENABLE_TOOL_AGENT != 0
+ /* Only start watchdog when debugger is not running */
+ if (!is_tool_agent_running(m_data)) {
+#endif
+ watchdog_timer_start(wd_timer);
+ is_wd_started = true;
+#if BEIHAI_ENABLE_TOOL_AGENT != 0
+ }
+#endif
+
+ jeff_runtime_call_java(method, argc, argv, argt);
+
+ if (is_wd_started) {
+ os_mutex_lock(&wd_timer->lock);
+ if (!wd_timer->is_interrupting) {
+ wd_timer->is_stopped = true;
+ watchdog_timer_stop(wd_timer);
+ }
+ os_mutex_unlock(&wd_timer->lock);
+ }
+
+ return !check_exception();
+}
+
+static AEEBLEDevice
+create_object_BLEDevice(ble_device_info *dev_info)
+{
+ JeffLocalObjectRef ref;
+ AEEBLEDevice dev_struct;
+
+ jeff_runtime_push_local_object_ref(&ref);
+
+ ref.val = jeff_runtime_new_object(class_BLEDevice);
+
+ if (!ref.val) {
+ jeff_runtime_pop_local_object_ref(1);
+ return NULL;
+ }
+
+ dev_struct = (AEEBLEDevice)(ref.val);
+ dev_struct->rssi = dev_info->rssi;
+ dev_struct->mac =
+ (jbyteArray)jeff_runtime_create_byte_array((int8 *)dev_info->mac, 6);
+
+ app_manager_printf("adv_data_len:%d,scan_response_len:%d\n",
+ dev_info->adv_data_len, dev_info->scan_response_len);
+
+ dev_struct->advData = (jbyteArray)jeff_runtime_create_byte_array(
+ (int8 *)dev_info->adv_data, dev_info->adv_data_len);
+ dev_struct->scanResponse = (jbyteArray)jeff_runtime_create_byte_array(
+ (int8 *)dev_info->scan_response, dev_info->scan_response_len);
+ dev_struct->addressType = dev_info->address_type;
+ jeff_runtime_initialize_object(ref.val);
+ jeff_runtime_pop_local_object_ref(1);
+ if ((dev_struct->mac == NULL) || (dev_struct->advData == NULL)
+ || (dev_struct->scanResponse == NULL)) {
+ return NULL;
+ }
+ return (AEEBLEDevice)ref.val;
+}
+
+static void
+app_instance_process_ble_msg(char *msg)
+{
+ bh_queue_ble_sub_msg_t *ble_msg = (bh_queue_ble_sub_msg_t *)msg;
+ unsigned int argv[5];
+ uint8 argt[5];
+
+ ble_device_info *dev_info;
+
+ dev_info = (ble_device_info *)ble_msg->payload;
+ AEEBLEDevice ble_dev;
+
+ argv[0] = (unsigned int)(jbyteArray)jeff_runtime_create_byte_array(
+ (int8 *)dev_info->mac, 6);
+ argt[0] = 1;
+ if (!app_manager_call_java(method_callOnBLEManagerGetBLEDevice, 1, argv,
+ argt)) {
+ app_manager_printf(
+ "app_manager_call_java BLEManagerGetBLEDevice fail error\n");
+ goto fail;
+ }
+ ble_dev = (AEEBLEDevice)argv[0];
+ if (ble_dev == NULL) {
+ ble_dev = create_object_BLEDevice(dev_info);
+ if (ble_dev == NULL) {
+ goto fail;
+ }
+ }
+
+ switch (ble_msg->type) {
+ case BLE_SUB_EVENT_DISCOVERY:
+ {
+ argv[0] = (unsigned int)ble_dev;
+ argt[0] = 1;
+ ble_dev->rssi = dev_info->rssi;
+ if (!app_manager_call_java(method_callOnBLEStartDiscovery, 1, argv,
+ argt)) {
+ app_manager_printf(
+ "app_manager_call_java method_callOnBLEStartDiscovery "
+ "fail error\n");
+ goto fail;
+ }
+ break;
+ }
+
+ case BLE_SUB_EVENT_CONNECTED:
+ {
+ if (ble_dev) {
+ argv[0] = (unsigned int)ble_dev;
+ argv[1] = 0;
+ argt[0] = 1;
+ argt[1] = 1;
+ if (!app_manager_call_java(method_callOnBLEConnected, 2, argv,
+ argt)) {
+ app_manager_printf(
+ "app_manager_call_java method_callOnBLEConnected "
+ "fail error\n");
+ goto fail;
+ }
+ }
+ break;
+ }
+
+ case BLE_SUB_EVENT_DISCONNECTED:
+ {
+ app_manager_printf("app instance received disconnected\n");
+
+ if (ble_dev) {
+ argv[0] = (unsigned int)ble_dev;
+ argv[1] = 0;
+ argt[0] = 1;
+ argt[1] = 1;
+ ble_dev->rssi = dev_info->rssi;
+ if (!app_manager_call_java(method_callOnBLEDisconnected, 2,
+ argv, argt)) {
+ app_manager_printf(
+ "app_manager_call_java "
+ "method_callOnBLEDisconnected fail error\n");
+ goto fail;
+ }
+ }
+ break;
+ }
+
+ case BLE_SUB_EVENT_NOTIFICATION:
+ {
+ if (ble_dev) {
+ argv[0] = (unsigned int)ble_dev;
+ argv[1] =
+ (unsigned int)(jbyteArray)jeff_runtime_create_byte_array(
+ (int8 *)dev_info->private_data,
+ dev_info->private_data_length);
+ argv[2] = dev_info->value_handle;
+ argv[3] = dev_info->ccc_handle;
+ argt[1] = 1;
+ argt[2] = 0;
+ argt[3] = 0;
+ ble_dev->rssi = dev_info->rssi;
+ if (!app_manager_call_java(method_callOnBLENotification, 4,
+ argv, argt)) {
+ app_manager_printf(
+ "app_manager_call_java "
+ "method_callOnBLENotification fail error\n");
+ goto fail;
+ }
+ }
+ break;
+ }
+
+ case BLE_SUB_EVENT_INDICATION:
+ {
+ if (ble_dev) {
+ argv[0] = (unsigned int)ble_dev;
+ argv[1] =
+ (unsigned int)(jbyteArray)jeff_runtime_create_byte_array(
+ (int8 *)dev_info->private_data,
+ dev_info->private_data_length);
+ argv[2] = dev_info->value_handle;
+ argv[3] = dev_info->ccc_handle;
+ argt[0] = 1;
+ argt[1] = 1;
+ argt[2] = 0;
+ argt[3] = 0;
+ ble_dev->rssi = dev_info->rssi;
+ if (!app_manager_call_java(method_callOnBLEIndication, 4, argv,
+ argt)) {
+ app_manager_printf(
+ "app_manager_call_java method_callOnBLEIndication "
+ "fail error\n");
+ goto fail;
+ }
+ }
+ break;
+ }
+
+ case BLE_SUB_EVENT_PASSKEYENTRY:
+ {
+
+ if (ble_dev) {
+ argv[0] = (unsigned int)ble_dev;
+ argt[0] = 1;
+ argt[1] = 1;
+ ble_dev->rssi = dev_info->rssi;
+ if (!app_manager_call_java(method_callOnBLEPasskeyEntry, 1,
+ argv, argt)) {
+ app_manager_printf(
+ "app_manager_call_java "
+ "method_callOnBLEPasskeyEntry fail error\n");
+ goto fail;
+ }
+ }
+ break;
+ }
+
+ case BLE_SUB_EVENT_SECURITY_LEVEL_CHANGE:
+ {
+ if (ble_dev) {
+ ble_dev->securityLevel = dev_info->security_level;
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+
+fail:
+ if (dev_info->scan_response != NULL) {
+ APP_MGR_FREE(dev_info->scan_response);
+ }
+ if (dev_info->private_data != NULL) {
+ APP_MGR_FREE(dev_info->private_data);
+ }
+
+ if (dev_info->adv_data != NULL) {
+ APP_MGR_FREE(dev_info->adv_data);
+ }
+ if (dev_info != NULL) {
+ APP_MGR_FREE(dev_info);
+ }
+}
+
+static void
+app_instance_free_ble_msg(char *msg)
+{
+ bh_queue_ble_sub_msg_t *ble_msg = (bh_queue_ble_sub_msg_t *)msg;
+ ble_device_info *dev_info;
+
+ dev_info = (ble_device_info *)ble_msg->payload;
+
+ if (dev_info->scan_response != NULL)
+ APP_MGR_FREE(dev_info->scan_response);
+
+ if (dev_info->private_data != NULL)
+ APP_MGR_FREE(dev_info->private_data);
+
+ if (dev_info->adv_data != NULL)
+ APP_MGR_FREE(dev_info->adv_data);
+
+ if (dev_info != NULL)
+ APP_MGR_FREE(dev_info);
+}
+
+static void
+app_instance_queue_free_callback(void *queue_msg)
+{
+ bh_queue_msg_t *msg = (bh_queue_msg_t *)queue_msg;
+
+ switch (msg->message_type) {
+ case APPLET_REQUEST:
+ {
+ bh_request_msg_t *req_msg = (bh_request_msg_t *)msg->payload;
+ APP_MGR_FREE(req_msg);
+ break;
+ }
+
+ case TIMER_EVENT:
+ {
+ break;
+ }
+
+ case SENSOR_EVENT:
+ {
+ if (msg->payload) {
+ bh_sensor_event_t *sensor_event =
+ (bh_sensor_event_t *)msg->payload;
+ attr_container_t *event = sensor_event->event;
+
+ attr_container_destroy(event);
+ APP_MGR_FREE(sensor_event);
+ }
+ break;
+ }
+
+ case BLE_EVENT:
+ {
+ if (msg->payload) {
+ app_instance_free_ble_msg(msg->payload);
+ APP_MGR_FREE(msg->payload);
+ }
+ break;
+ }
+
+ case GPIO_INTERRUPT_EVENT:
+ {
+ break;
+ }
+
+ default:
+ {
+ break;
+ }
+ }
+
+ APP_MGR_FREE(msg);
+}
+
+static void
+app_instance_queue_callback(void *queue_msg)
+{
+ bh_queue_msg_t *msg = (bh_queue_msg_t *)queue_msg;
+ unsigned int argv[5];
+ uint8 argt[5];
+
+ if (app_manager_is_interrupting_module(Module_Jeff)) {
+ app_instance_queue_free_callback(queue_msg);
+ return;
+ }
+
+ switch (msg->message_type) {
+ case APPLET_REQUEST:
+ {
+ JeffLocalObjectRef ref;
+ AEERequest req_obj;
+ bh_request_msg_t *req_msg = (bh_request_msg_t *)msg->payload;
+ attr_container_t *attr_cont = (attr_container_t *)req_msg->payload;
+ module_data *m_data = app_manager_get_module_data(Module_Jeff);
+ jeff_applet_data *applet_data =
+ (jeff_applet_data *)m_data->internal_data;
+
+ app_manager_printf("Applet %s got request, url %s, action %d\n",
+ m_data->module_name, req_msg->url,
+ req_msg->action);
+
+ /* Create Request object */
+ req_obj =
+ (AEERequest)jeff_object_new(m_data->heap, class_AEERequest);
+ if (!req_obj) {
+ app_manager_printf("Applet process request failed: create "
+ "request obj failed.\n");
+ goto fail1;
+ }
+
+ jeff_runtime_push_local_object_ref(&ref);
+ ref.val = (JeffObjectRef)req_obj;
+
+ req_obj->mid = req_msg->mid;
+ req_obj->action = req_msg->action;
+ req_obj->fmt = req_msg->fmt;
+
+ /* Create Java url string */
+ if (req_msg->url) {
+ req_obj->url =
+ (jstring)jeff_runtime_create_java_string(req_msg->url);
+ if (!req_obj->url) {
+ app_manager_printf("Applet process request failed: "
+ "create url string failed.\n");
+ goto fail2;
+ }
+ }
+
+ /* Create Java AttributeObject payload */
+ if (attr_cont
+ && !attr_container_to_attr_obj(attr_cont, &req_obj->payload)) {
+ app_manager_printf("Applet process request failed: convert "
+ "payload failed.\n");
+ goto fail2;
+ }
+
+ /* Call AEEApplet.callOnRequest(Request request) method */
+ argv[0] = (unsigned int)applet_data->applet_obj;
+ argv[1] = (unsigned int)req_obj;
+ argt[0] = argt[1] = 1;
+ app_manager_call_java(method_AEEApplet_callOnRequest, 2, argv,
+ argt);
+ app_manager_printf("Applet process request success.\n");
+
+ fail2:
+ jeff_runtime_pop_local_object_ref(1);
+ fail1:
+ APP_MGR_FREE(req_msg);
+ break;
+ }
+
+ case TIMER_EVENT:
+ {
+ if (msg->payload) {
+ /* Call Timer.callOnTimer() method */
+ argv[0] = (unsigned int)msg->payload;
+ argt[0] = 1;
+ app_manager_call_java(method_callOnTimer, 1, argv, argt);
+ }
+ break;
+ }
+
+ case SENSOR_EVENT:
+ {
+ if (msg->payload) {
+ bh_sensor_event_t *sensor_event =
+ (bh_sensor_event_t *)msg->payload;
+ AEESensor sensor = sensor_event->sensor;
+ attr_container_t *event = sensor_event->event;
+ bool ret = attr_container_to_attr_obj(event, &sensor->event);
+
+ attr_container_destroy(event);
+ APP_MGR_FREE(sensor_event);
+
+ if (ret) {
+ /* Call Sensor.callOnSensorEvent() method */
+ argv[0] = (unsigned int)sensor;
+ argt[0] = 1;
+ app_manager_call_java(method_callOnSensorEvent, 1, argv,
+ argt);
+ }
+ }
+ break;
+ }
+
+ case BLE_EVENT:
+ {
+ if (msg->payload) {
+ app_instance_process_ble_msg(msg->payload);
+ APP_MGR_FREE(msg->payload);
+ }
+ break;
+ }
+
+ case GPIO_INTERRUPT_EVENT:
+ {
+ AEEGPIOChannel gpio_ch = (AEEGPIOChannel)msg->payload;
+
+ if ((gpio_ch == NULL) || (gpio_ch->callback == 0)
+ || (gpio_ch->listener == NULL)) {
+ break;
+ }
+ argv[0] = (unsigned int)gpio_ch;
+ argt[0] = 1;
+ bool ret_value = app_manager_call_java(method_callOnGPIOInterrupt,
+ 1, argv, argt);
+
+ if (!ret_value) {
+ app_manager_printf(
+ "app_manager_call_java "
+ "method_method_callOnGPIOInterrupt return false\n");
+ }
+ break;
+ }
+
+ default:
+ {
+ app_manager_printf(
+ "Invalid message type of applet queue message.\n");
+ break;
+ }
+ }
+
+ APP_MGR_FREE(msg);
+}
+
+static JeffClassHeaderLinked *
+find_main_class(JeffFileHeaderLinked *main_file)
+{
+ JeffClassHeaderLinked *c = NULL, *ci;
+ unsigned int i;
+
+ for (i = 0; i < main_file->internal_class_count; i++) {
+ ci = main_file->class_header[i];
+
+ if (jeff_is_super_class(class_AEEApplet, ci)
+ && (ci->access_flag & JEFF_ACC_PUBLIC)) {
+ if (c) {
+ jeff_printe_more_than_one_main_class();
+ return NULL;
+ }
+
+ c = ci;
+ }
+ }
+
+ if (!c)
+ jeff_printe_no_main_class();
+
+ return c;
+}
+
+/* Java applet thread main routine */
+static void *
+app_instance_main(void *arg)
+{
+ module_data *m_data = (module_data *)arg;
+ jeff_applet_data *applet_data = (jeff_applet_data *)m_data->internal_data;
+ JeffClassHeaderLinked *object_class;
+ JeffMethodLinked *m;
+ unsigned int argv[1];
+ uint8 argt[1];
+
+ app_manager_printf("Java Applet '%s' started\n", m_data->module_name);
+
+#if BEIHAI_ENABLE_TOOL_AGENT != 0
+ if (applet_data->debug_mode)
+ jeff_tool_suspend_self();
+#endif
+
+ applet_data->vm_instance->applet_object = applet_data->applet_obj;
+ object_class = jeff_object_class_pointer(applet_data->applet_obj);
+ m = jeff_select_method_virtual(object_class, method_AEEApplet_onInit);
+ bh_assert(m != NULL);
+ /* Initialize applet class which call <clinit> */
+ if (!app_manager_initialize_class(object_class)) {
+ app_manager_printf("Call <clinit> fail\n");
+ goto fail;
+ }
+
+ /* Initialize applet object which call <init> */
+ if (!app_manager_initialize_object(applet_data->applet_obj)) {
+ app_manager_printf("Call <init> fail\n");
+ goto fail;
+ }
+
+ /* Call applet's onInit() method */
+ argv[0] = (unsigned int)applet_data->applet_obj;
+ argt[0] = 1;
+ if (app_manager_call_java(m, 1, argv, argt))
+ /* Enter queue loop run to receive and process applet queue message
+ */
+ bh_queue_enter_loop_run(m_data->queue, app_instance_queue_callback);
+
+fail:
+ applet_data->vm_instance->applet_object = applet_data->applet_obj;
+ object_class = jeff_object_class_pointer(applet_data->applet_obj);
+ m = jeff_select_method_virtual(object_class, method_AEEApplet_onDestroy);
+ bh_assert(m != NULL);
+ /* Call User Applet or AEEApplet onDestroy() method */
+ app_manager_call_java(m, 1, argv, argt);
+ if (m != method_AEEApplet_onDestroy) {
+ /*If 'm' is user onDestroy, then Call AEEApplet.onDestroy() method*/
+ app_manager_call_java(method_AEEApplet_onDestroy, 1, argv, argt);
+ }
+ app_manager_printf("Applet instance main thread exit.\n");
+ return NULL;
+}
+
+static bool
+verify_signature(JeffFileHeader *file, unsigned size)
+{
+ uint8 *sig;
+ unsigned sig_size;
+
+#if BEIHAI_ENABLE_NO_SIGNATURE != 0
+ /* no signature */
+ if (file->file_signature == 0)
+ return true;
+#endif
+
+ if (file->file_length != size
+#if BEIHAI_ENABLE_NO_SIGNATURE == 0
+ || file->file_signature == 0
+#endif
+ || file->file_signature >= file->file_length)
+ return false;
+
+ sig = (uint8 *)file + file->file_signature;
+ sig_size = file->file_length - file->file_signature;
+
+ if (0
+ == app_manager_signature_verify((uint8_t *)file, file->file_signature,
+ sig, sig_size))
+ return false;
+
+ return true;
+}
+
+/* Install Java Applet */
+static bool
+jeff_module_install(bh_request_msg_t *msg)
+{
+ unsigned int size, bpk_file_len, main_file_len, heap_size, timeout;
+ uint8 *bpk_file;
+ JeffFileHeaderLinked *main_file;
+ JeffClassHeaderLinked *main_class;
+ module_data *m_data;
+ jeff_applet_data *applet_data;
+ char *applet_name, *applet_perm;
+ attr_container_t *attr_cont;
+ bool debug = false;
+
+ /* Check url */
+ if (!msg->url || strcmp(msg->url, "/applet") != 0) {
+ SEND_ERR_RESPONSE(msg->mid, "Install Applet failed: invalid url.");
+ return false;
+ }
+
+ /* Check payload */
+ attr_cont = (attr_container_t *)msg->payload;
+ if (!attr_cont
+ || !(bpk_file = (uint8 *)attr_container_get_as_bytearray(
+ attr_cont, "bpk", &bpk_file_len))) {
+ SEND_ERR_RESPONSE(msg->mid, "Install Applet failed: invalid bpk file.");
+ return false;
+ }
+
+ /* Check applet name */
+ applet_name = attr_container_get_as_string(attr_cont, "name");
+
+ if (!applet_name || strlen(applet_name) == 0) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install Applet failed: invalid applet name.");
+ return false;
+ }
+
+ if (app_manager_lookup_module_data(applet_name)) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install Applet failed: applet already installed.");
+ return false;
+ }
+
+ /* TODO: convert bpk file to Jeff file */
+ main_file_len = bpk_file_len;
+ main_file = APP_MGR_MALLOC(main_file_len);
+ if (!main_file) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install Applet failed: allocate memory failed.");
+ return false;
+ }
+ bh_memcpy_s(main_file, main_file_len, bpk_file, main_file_len);
+
+ /* Verify signature */
+ if (!verify_signature((JeffFileHeader *)main_file, main_file_len)) {
+ SEND_ERR_RESPONSE(
+ msg->mid,
+ "Install Applet failed: verify Jeff file signature failed.");
+ goto fail1;
+ }
+
+ /* Load Jeff main file */
+ if (!jeff_runtime_load(main_file, main_file_len, false, NULL, NULL)) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install Applet failed: load Jeff file failed.");
+ goto fail1;
+ }
+
+ /* Find main class */
+ main_class = find_main_class(main_file);
+ if (!main_class) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install Applet failed: find applet class failed.");
+ goto fail2;
+ }
+
+ /* Create module data */
+ size = offsetof(module_data, module_name) + strlen(applet_name) + 1;
+ size = align_uint(size, 4);
+ m_data = APP_MGR_MALLOC(size + sizeof(jeff_applet_data));
+ if (!m_data) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install Applet failed: allocate memory failed.");
+ goto fail2;
+ }
+
+ memset(m_data, 0, size + sizeof(jeff_applet_data));
+ m_data->module_type = Module_Jeff;
+ m_data->internal_data = (uint8 *)m_data + size;
+ applet_data = (jeff_applet_data *)m_data->internal_data;
+ bh_strcpy_s(m_data->module_name, strlen(applet_name) + 1, applet_name);
+ applet_data->main_file = main_file;
+
+ /* Set applet execution timeout */
+ timeout = DEFAULT_APPLET_TIMEOUT;
+ if (attr_container_contain_key(attr_cont, "execution timeout"))
+ timeout = attr_container_get_as_int(attr_cont, "execution timeout");
+ m_data->timeout = timeout;
+
+ /* Create applet permissions */
+ applet_perm = attr_container_get_as_string(attr_cont, "perm");
+ if (applet_perm != NULL) {
+ applet_data->perms = APP_MGR_MALLOC(strlen(applet_perm) + 1);
+ if (!applet_data->perms) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install Applet failed: allocate memory for "
+ "applet permissions failed.");
+ goto fail3;
+ }
+
+ bh_strcpy_s(applet_data->perms, strlen(applet_perm) + 1, applet_perm);
+ }
+
+ /* Create applet queue */
+ m_data->queue = bh_queue_create();
+ if (!m_data->queue) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install Applet failed: create applet queue failed.");
+ goto fail3_1;
+ }
+
+ /* Set heap size */
+ heap_size = DEFAULT_APPLET_HEAP_SIZE;
+ if (attr_container_contain_key(attr_cont, "heap size")) {
+ heap_size = attr_container_get_as_int(attr_cont, "heap size");
+ if (heap_size < MIN_APPLET_HEAP_SIZE)
+ heap_size = MIN_APPLET_HEAP_SIZE;
+ else if (heap_size > MAX_APPLET_HEAP_SIZE)
+ heap_size = MAX_APPLET_HEAP_SIZE;
+ }
+
+ m_data->heap_size = heap_size;
+
+ /* Create applet heap */
+ m_data->heap = gc_init_for_instance(heap_size);
+ if (!m_data->heap) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install Applet failed: create heap failed.");
+ goto fail4;
+ }
+
+ /* Create applet object */
+ applet_data->applet_obj = jeff_object_new(m_data->heap, main_class);
+ if (!applet_data->applet_obj) {
+ SEND_ERR_RESPONSE(
+ msg->mid, "Install Applet failed: create applet object failed.");
+ goto fail5;
+ }
+
+ /* Initialize watchdog timer */
+ if (!watchdog_timer_init(m_data)) {
+ SEND_ERR_RESPONSE(
+ msg->mid,
+ "Install Applet failed: create applet watchdog timer failed.");
+ goto fail5;
+ }
+
+#if BEIHAI_ENABLE_TOOL_AGENT != 0
+ /* Check whether applet is debuggable */
+ if (attr_container_contain_key(attr_cont, "debug"))
+ debug = attr_container_get_as_bool(attr_cont, "debug");
+
+ applet_data->debug_mode = debug;
+
+ /* Create tool agent queue */
+ if (debug && !(applet_data->tool_agent_queue = bh_queue_create())) {
+ SEND_ERR_RESPONSE(
+ msg->mid, "Install Applet failed: create tool agent queue failed.");
+ goto fail5_1;
+ }
+#endif
+
+ /* Create applet instance */
+ applet_data->vm_instance = jeff_runtime_create_instance(
+ main_file, m_data->heap, 16, app_instance_main, m_data, NULL);
+ if (!applet_data->vm_instance) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install Applet failed: create Java VM failed");
+ goto fail6;
+ }
+
+ /* Add applet data to applet data list */
+ applet_data->vm_instance->applet_object = applet_data->applet_obj;
+ app_manager_add_module_data(m_data);
+ app_manager_post_applets_update_event();
+
+#if BEIHAI_ENABLE_TOOL_AGENT != 0
+ /* Start tool agent thread */
+ if (debug
+ && !jeff_tool_start_agent(applet_data->vm_instance,
+ applet_data->tool_agent_queue)) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install Applet failed: start tool agent failed");
+ goto fail6;
+ }
+#endif
+
+ app_manager_printf("Install Applet success!\n");
+ app_send_response_to_host(msg->mid, CREATED_2_01, NULL); /* CREATED */
+ return true;
+
+fail6:
+#if BEIHAI_ENABLE_TOOL_AGENT != 0
+ if (debug)
+ bh_queue_destroy(applet_data->tool_agent_queue);
+#endif
+
+fail5_1:
+ watchdog_timer_destroy(&m_data->wd_timer);
+
+fail5:
+ gc_destroy_for_instance(m_data->heap);
+
+fail4:
+ bh_queue_destroy(m_data->queue, NULL);
+
+fail3_1:
+ APP_MGR_FREE(applet_data->perms);
+
+fail3:
+ APP_MGR_FREE(applet_data);
+
+fail2:
+ jeff_runtime_unload(main_file);
+
+fail1:
+ APP_MGR_FREE(main_file);
+
+ return false;
+}
+
+static void
+cleanup_applet_resource(module_data *m_data)
+{
+ jeff_applet_data *applet_data = (jeff_applet_data *)m_data->internal_data;
+
+ /* Unload Jeff main file and free it */
+ jeff_runtime_unload(applet_data->main_file);
+ APP_MGR_FREE(applet_data->main_file);
+
+ /* Destroy queue */
+ bh_queue_destroy(m_data->queue, app_instance_queue_free_callback);
+
+ /* Destroy heap */
+ gc_destroy_for_instance(m_data->heap);
+
+ /* Destroy watchdog timer */
+ watchdog_timer_destroy(&m_data->wd_timer);
+
+ /* Remove module data from module data list and free it */
+ app_manager_del_module_data(m_data);
+ APP_MGR_FREE(applet_data->perms);
+ APP_MGR_FREE(m_data);
+}
+
+/* Uninstall Java Applet */
+static bool
+jeff_module_uninstall(bh_request_msg_t *msg)
+{
+ module_data *m_data;
+ jeff_applet_data *applet_data;
+ attr_container_t *attr_cont;
+ char *applet_name;
+ bool do_not_reply = false;
+
+ /* Check payload and applet name*/
+ attr_cont = (attr_container_t *)msg->payload;
+
+ /* Check whether need to reply this request */
+ if (attr_container_contain_key(attr_cont, "do not reply me"))
+ do_not_reply = attr_container_get_as_bool(attr_cont, "do not reply me");
+
+ /* Check url */
+ if (!msg->url || strcmp(msg->url, "/applet") != 0) {
+ if (!do_not_reply)
+ SEND_ERR_RESPONSE(msg->mid,
+ "Uninstall Applet failed: invalid url.");
+ else
+ app_manager_printf("Uninstall Applet failed: invalid url.");
+ return false;
+ }
+
+ if (!attr_cont
+ || !(applet_name = attr_container_get_as_string(attr_cont, "name"))
+ || strlen(applet_name) == 0) {
+ if (!do_not_reply)
+ SEND_ERR_RESPONSE(msg->mid,
+ "Uninstall Applet failed: invalid applet name.");
+ else
+ app_manager_printf("Uninstall Applet failed: invalid applet name.");
+ return false;
+ }
+
+ m_data = app_manager_lookup_module_data(applet_name);
+ if (!m_data) {
+ if (!do_not_reply)
+ SEND_ERR_RESPONSE(msg->mid,
+ "Uninstall Applet failed: no applet found.");
+ else
+ app_manager_printf("Uninstall Applet failed: no applet found.");
+ return false;
+ }
+
+ if (m_data->module_type != Module_Jeff) {
+ if (!do_not_reply)
+ SEND_ERR_RESPONSE(msg->mid,
+ "Uninstall Applet failed: invlaid module type.");
+ else
+ app_manager_printf("Uninstall Applet failed: invalid module type.");
+ return false;
+ }
+
+ if (m_data->wd_timer.is_interrupting) {
+ if (!do_not_reply)
+ SEND_ERR_RESPONSE(msg->mid,
+ "Uninstall Applet failed: applet is being "
+ "interrupted by watchdog.");
+ else
+ app_manager_printf("Uninstall Applet failed: applet is being "
+ "interrupted by watchdog.");
+ return false;
+ }
+
+ /* Exit applet queue loop run */
+ bh_queue_exit_loop_run(m_data->queue);
+
+ applet_data = (jeff_applet_data *)m_data->internal_data;
+#if BEIHAI_ENABLE_TOOL_AGENT != 0
+ /* Exit tool agent queue loop run */
+ if (is_tool_agent_running(m_data)) {
+ bh_queue_exit_loop_run(applet_data->tool_agent_queue);
+ }
+#endif
+
+ /* Wait the end of the applet instance and then destroy it */
+ if (applet_data->vm_instance->main_file)
+ jeff_runtime_wait_for_instance(applet_data->vm_instance, -1);
+ jeff_runtime_destroy_instance(applet_data->vm_instance);
+
+ cleanup_applet_resource(m_data);
+ app_manager_post_applets_update_event();
+
+ app_manager_printf("Uninstall Applet success!\n");
+
+ if (!do_not_reply)
+ app_send_response_to_host(msg->mid, DELETED_2_02, NULL); /* DELETED */
+ return true;
+}
+
+#define PERM_PREFIX "AEE.permission."
+
+static bool
+check_permission_format(const char *perm)
+{
+ const char *prefix = PERM_PREFIX;
+ const char *p;
+
+ if (perm == NULL || strncmp(perm, prefix, strlen(prefix)) != 0
+ || *(p = perm + strlen(prefix)) == '\0')
+ return false;
+
+ do {
+ if (!(*p == '.' || ('A' <= *p && *p <= 'Z')
+ || ('a' <= *p && *p <= 'z')))
+ return false;
+ } while (*++p != '\0');
+
+ return true;
+}
+
+static bool
+match(const char *haystack, const char *needle, char delim)
+{
+ const char *p = needle;
+
+ if (haystack == NULL || *haystack == '\0' || needle == NULL
+ || *needle == '\0')
+ return false;
+
+ while (true) {
+ while (true) {
+ if ((*haystack == '\0' || *haystack == delim) && *p == '\0') {
+ return true;
+ }
+ else if (*p == *haystack) {
+ ++p;
+ ++haystack;
+ }
+ else {
+ break;
+ }
+ }
+ while (*haystack != '\0' && *haystack != delim) {
+ ++haystack;
+ }
+ if (*haystack == '\0') {
+ return false;
+ }
+ else {
+ ++haystack;
+ p = needle;
+ }
+ }
+}
+
+bool
+bh_applet_check_permission(const char *perm)
+{
+ return check_permission_format(perm)
+ && match(app_manager_get_jeff_applet_data()->perms,
+ perm + strlen(PERM_PREFIX), ' ');
+}
+
+static bool
+jeff_module_init()
+{
+ JeffDescriptorFull d[] = { { JEFF_TYPE_VOID, 0, NULL } };
+ JeffDescriptorFull d1[] = { { JEFF_TYPE_OBJECT | JEFF_TYPE_REF, 0, NULL },
+ { JEFF_TYPE_VOID, 0, NULL } };
+
+ /* Resolve class com.intel.aee.AEEApplet */
+ class_AEEApplet =
+ jeff_runtime_resolve_class_full_name("com.intel.aee.AEEApplet");
+ if (!class_AEEApplet) {
+ app_manager_printf(
+ "App Manager start failed: resolve class AEEApplet failed.\n");
+ return false;
+ }
+
+ /* Resolve class com.intel.aee.Request */
+ class_AEERequest =
+ jeff_runtime_resolve_class_full_name("com.intel.aee.Request");
+ if (!class_AEERequest) {
+ app_manager_printf(
+ "App Manager start failed: resolve class Request failed.\n");
+ return false;
+ }
+
+ /* Resolve class com.intel.aee.Timer */
+ class_Timer = jeff_runtime_resolve_class_full_name("com.intel.aee.Timer");
+ if (!class_Timer) {
+ app_manager_printf(
+ "App Manager start failed: resolve class Timer failed.\n");
+ return false;
+ }
+
+ /* Resolve class com.intel.aee.Sensor */
+ class_Sensor = jeff_runtime_resolve_class_full_name("com.intel.aee.Sensor");
+ if (!class_Sensor) {
+ app_manager_printf(
+ "App Manager start failed: resolve class Sensor failed.\n");
+ return false;
+ }
+
+ /* Resolve class com.intel.aee.ble.BLEManager */
+ class_BLEManager =
+ jeff_runtime_resolve_class_full_name("com.intel.aee.ble.BLEManager");
+ if (!class_BLEManager) {
+ app_manager_printf(
+ "App Manager start failed: resolve class BLEManager failed.\n");
+ return false;
+ }
+
+ /* Resolve class com.intel.aee.ble.BLEDevice */
+ class_BLEDevice =
+ jeff_runtime_resolve_class_full_name("com.intel.aee.ble.BLEDevice");
+ if (!class_BLEDevice) {
+ app_manager_printf(
+ "App Manager start failed: resolve class BLEDevice failed.\n");
+ return false;
+ }
+ /* Resolve class com.intel.aee.ble.BLEDevice */
+ class_BLEGattService = jeff_runtime_resolve_class_full_name(
+ "com.intel.aee.ble.BLEGattService");
+ if (!class_BLEGattService) {
+ app_manager_printf("App Manager start failed: resolve class "
+ "BLEGattService failed.\n");
+ return false;
+ }
+
+ /* Resolve class com.intel.aee.ble.BLEDevice */
+ class_BLEGattCharacteristic = jeff_runtime_resolve_class_full_name(
+ "com.intel.aee.ble.BLEGattCharacteristic");
+ if (!class_BLEGattCharacteristic) {
+ app_manager_printf("App Manager start failed: resolve class "
+ "BLEGattCharacteristic failed.\n");
+ return false;
+ }
+
+ /* Resolve class com.intel.aee.ble.BLEDevice */
+ class_BLEGattDescriptor = jeff_runtime_resolve_class_full_name(
+ "com.intel.aee.ble.BLEGattDescriptor");
+ if (!class_BLEGattDescriptor) {
+ app_manager_printf("App Manager start failed: resolve class "
+ "BLEGattDescriptor failed.\n");
+ return false;
+ }
+ /* Resolve class com.intel.aee.gpio.GPIOChannel */
+ class_GPIOChannel =
+ jeff_runtime_resolve_class_full_name("com.intel.aee.gpio.GPIOChannel");
+ if (!class_GPIOChannel) {
+ app_manager_printf("App Manager start failed: resolve class "
+ "GPIOChannel failed.\n");
+ return false;
+ }
+
+ /* Resolve method com.intel.aee.AEEApplet.onInit() */
+ method_AEEApplet_onInit =
+ jeff_lookup_method(class_AEEApplet, "onInit", 0, d);
+ if (!method_AEEApplet_onInit) {
+ app_manager_printf("App Manager start failed: resolve method "
+ "Applet.onInit() failed.\n");
+ return false;
+ }
+
+ /* Resolve method com.intel.aee.AEEApplet.onDestroy() */
+ method_AEEApplet_onDestroy =
+ jeff_lookup_method(class_AEEApplet, "onDestroy", 0, d);
+ if (!method_AEEApplet_onDestroy) {
+ app_manager_printf("App Manager start failed: resolve method "
+ "AEEApplet.onDestroy() failed.\n");
+ return false;
+ }
+
+ /* Resolve method com.intel.aee.AEEApplet.callOnRequest(Request) */
+ d1[0].class_header = class_AEERequest;
+ method_AEEApplet_callOnRequest =
+ jeff_lookup_method(class_AEEApplet, "callOnRequest", 1, d1);
+ if (!method_AEEApplet_callOnRequest) {
+ app_manager_printf("App Manager start failed: resolve method "
+ "AEEApplet.callOnRequest() failed.\n");
+ return false;
+ }
+
+ /* Resolve method com.intel.aee.Timer.callOnTimer() */
+ method_callOnTimer = jeff_lookup_method(class_Timer, "callOnTimer", 0, d);
+ if (!method_callOnTimer) {
+ app_manager_printf("App Manager start failed: resolve method "
+ "Timer.callOnTimer() failed.\n");
+ return false;
+ }
+
+ /* Resolve method com.intel.aee.Sensor.callOnSensorEvent() */
+ method_callOnSensorEvent =
+ jeff_lookup_method(class_Sensor, "callOnSensorEvent", 0, d);
+ if (!method_callOnSensorEvent) {
+ app_manager_printf("App Manager start failed: resolve method "
+ "Sensor.callOnSensorEvent() failed.\n");
+ return false;
+ }
+
+ /* Resovle method
+ * com.intel.aee.ble.BLEManager.callOnBLEStartDiscovery(BLEDevice) */
+ d1[0].class_header = class_BLEDevice;
+ method_callOnBLEStartDiscovery =
+ jeff_lookup_method(class_BLEManager, "callOnBLEStartDiscovery", 1, d1);
+ if (!method_callOnBLEStartDiscovery) {
+ app_manager_printf("App Manager start failed: resolve method "
+ "BLEManager.callOnBLEStartDiscovery() failed.\n");
+ return false;
+ }
+
+ /* Resovle method
+ * com.intel.aee.ble.BLEManager.callOnBLEConnected(BLEDevice) */
+ JeffDescriptorFull d2_1[] = { { JEFF_TYPE_OBJECT | JEFF_TYPE_REF, 0,
+ class_BLEDevice },
+ { JEFF_TYPE_INT, 0, NULL },
+ { JEFF_TYPE_VOID, 0, NULL } };
+ method_callOnBLEConnected =
+ jeff_lookup_method(class_BLEManager, "callOnBLEConnected", 2, d2_1);
+ if (!method_callOnBLEConnected) {
+ app_manager_printf("App Manager start failed: resolve method "
+ "BLEManager.callOnBLEConnected() failed.\n");
+ return false;
+ }
+
+ /* Resovle method
+ * com.intel.aee.ble.BLEManager.method_callOnBLENotification(BLEDevice,byte[])
+ */
+ JeffDescriptorFull d2_2[] = {
+ { JEFF_TYPE_OBJECT | JEFF_TYPE_REF, 0, class_BLEDevice },
+ { JEFF_TYPE_BYTE | JEFF_TYPE_REF | JEFF_TYPE_MONO, 1, NULL },
+ { JEFF_TYPE_INT, 0, NULL },
+ { JEFF_TYPE_INT, 0, NULL },
+ { JEFF_TYPE_VOID, 0, NULL }
+ };
+ method_callOnBLENotification =
+ jeff_lookup_method(class_BLEManager, "callOnBLENotification", 4, d2_2);
+ if (!method_callOnBLENotification) {
+ app_manager_printf("App Manager start failed: resolve method "
+ "BLEManager.callOnBLENotification() failed.\n");
+ return false;
+ }
+
+ /* Resovle method
+ * com.intel.aee.ble.BLEManager.callOnBLEConnected(BLEDevice,byte[]) */
+ method_callOnBLEIndication =
+ jeff_lookup_method(class_BLEManager, "callOnBLEIndication", 4, d2_2);
+ if (!method_callOnBLEIndication) {
+ app_manager_printf("App Manager start failed: resolve method "
+ "BLEManager.callOnBLEIndication() failed.\n");
+ return false;
+ }
+
+ /* Resovle method
+ * com.intel.aee.ble.BLEManager.callOnBLEConnected(BLEDevice) */
+ d1[0].class_header = class_BLEDevice;
+ method_callOnBLEDisconnected =
+ jeff_lookup_method(class_BLEManager, "callOnBLEDisconnected", 1, d1);
+ if (!method_callOnBLEDisconnected) {
+ app_manager_printf("App Manager start failed: resolve method "
+ "BLEManager.callOnBLEDisconnected() failed.\n");
+ return false;
+ }
+
+ /* Resovle method
+ * com.intel.aee.ble.BLEManager.callOnBLEConnected(BLEDevice) */
+ method_callOnBLEPasskeyEntry =
+ jeff_lookup_method(class_BLEManager, "callOnBLEPasskeyEntry", 1, d1);
+ if (!method_callOnBLEPasskeyEntry) {
+ app_manager_printf("App Manager start failed: resolve method "
+ "BLEManager.callOnBLEPasskeyEntry() failed.\n");
+ return false;
+ }
+ /* Resovle method void
+ * com.intel.aee.gpio.GPIOChannel.callOnGPIOInterrupt() */
+ method_callOnGPIOInterrupt =
+ jeff_lookup_method(class_GPIOChannel, "callOnGPIOInterrupt", 0, d);
+ if (!method_callOnGPIOInterrupt) {
+ app_manager_printf("App Manager start failed: resolve method "
+ "GPIOChannel.callOnGPIOInterrupt() failed.\n");
+ return false;
+ }
+
+ JeffDescriptorFull d2[] = {
+ { JEFF_TYPE_BYTE | JEFF_TYPE_REF | JEFF_TYPE_MONO, 1, NULL },
+ { JEFF_TYPE_OBJECT | JEFF_TYPE_REF, 0, class_BLEDevice }
+ };
+ /* Resovle method com.intel.aee.ble.BLEManager.getBLEDevice(byte []) */
+ method_callOnBLEManagerGetBLEDevice =
+ jeff_lookup_method(class_BLEManager, "getBLEDevice", 1, d2);
+ if (!method_callOnBLEManagerGetBLEDevice) {
+ app_manager_printf("App Manager start failed: resolve method "
+ "BLEManager.getBLEDevice() failed.\n");
+ return false;
+ }
+
+ return true;
+}
+
+static void
+jeff_module_watchdog_kill(module_data *m_data)
+{
+ jeff_applet_data *applet_data = (jeff_applet_data *)m_data->internal_data;
+
+ app_manager_printf("Watchdog interrupt the applet %s\n",
+ m_data->module_name);
+
+ jeff_runtime_interrupt_instance(applet_data->vm_instance, true);
+
+ /* Exit applet queue loop run */
+ bh_queue_exit_loop_run(m_data->queue);
+
+ /* Wait the end of the applet instance. If timeout, it means applet
+ * is busy executing native code, then try to cancle the main thread. */
+ if (applet_data->vm_instance->main_file)
+ jeff_runtime_wait_for_instance(applet_data->vm_instance, 3000);
+
+ if (applet_data->vm_instance->main_file) {
+ app_manager_printf("Watchdog cancel applet main thread.\n");
+ os_thread_cancel(applet_data->vm_instance->main_tlr.handle);
+ /* k_thread_abort(applet_data->vm_instance->main_tlr.handle); */
+ }
+
+ send_exception_event_to_host(m_data->module_name,
+ "java.lang.InterruptedException");
+ cleanup_applet_resource(m_data);
+ app_manager_printf("Watchdog interrupt Jeff applet done.\n");
+}
+
+static bool
+jeff_module_handle_host_url(void *queue_msg)
+{
+#if BEIHAI_ENABLE_TOOL_AGENT != 0
+ bh_queue_msg_t *msg = (bh_queue_msg_t *)queue_msg;
+
+ if (msg->message_type == COAP_PARSED) {
+ coap_packet_t *packet = (coap_packet_t *)msg->payload;
+ attr_container_t *attr_cont = (attr_container_t *)packet->payload;
+ const char *url = NULL;
+ int url_len = 0, mid;
+
+ bh_memcpy_s(&mid, sizeof(uint32), packet->token, sizeof(uint32));
+ url_len = coap_get_header_uri_path(packet, &url);
+
+ /* Send request to tool agent */
+ if (url_len >= 12 && memcmp(url, "/tool_agent/", 12) == 0) {
+ module_data *m_data;
+ jeff_applet_data *applet_data;
+ unsigned attr_cont_len = 0, req_msg_len;
+ bh_queue_msg_t *tool_agent_msg;
+ bh_request_msg_t *req_msg;
+ char url_buf[256] = { 0 }, *p = url_buf;
+ char applet_name[128] = { 0 };
+
+ /* Resolve applet name */
+ bh_memcpy_s(url_buf, sizeof(url_buf), url + 12, url_len - 12);
+ while (*p != '/' && *p != '\0')
+ p++;
+
+ bh_memcpy_s(applet_name, sizeof(applet_name), url_buf, p - url_buf);
+ app_manager_printf("Send request to tool agent of applet: %s\n",
+ applet_name);
+
+ /* Check applet name */
+ if (!(m_data = app_manager_lookup_module_data(applet_name))) {
+ SEND_ERR_RESPONSE(mid, "Send request to tool agent failed: "
+ "invalid applet name");
+ return false;
+ }
+
+ applet_data = (jeff_applet_data *)m_data->internal_data;
+ /* Attach debug: start the tool agent firstly */
+ if (packet->code == COAP_PUT) {
+ if (is_tool_agent_running(m_data)) {
+ SEND_ERR_RESPONSE(mid, "Attach debug failed: tool "
+ "agent is already exist.");
+ return false;
+ }
+
+ applet_data->debug_mode = true;
+
+ /* Create tool agent queue */
+ if (!(applet_data->tool_agent_queue = bh_queue_create())) {
+ SEND_ERR_RESPONSE(mid, "Attach debug failed: create "
+ "tool agent queue failed.");
+ return false;
+ }
+
+ /* Start tool agent thread */
+ if (!jeff_tool_start_agent(applet_data->vm_instance,
+ applet_data->tool_agent_queue)) {
+ bh_queue_destroy(applet_data->tool_agent_queue, NULL);
+ SEND_ERR_RESPONSE(
+ mid, "Attach debug failed: start tool agent failed");
+ return false;
+ }
+
+ app_manager_printf("Attach debug: start tool agent of "
+ "applet %s success.\n",
+ applet_name);
+ app_send_response_to_host(mid, CREATED_2_01, NULL); /* OK */
+ }
+ else {
+ /* Check tool agent running */
+ if (!is_tool_agent_running(m_data)) {
+ SEND_ERR_RESPONSE(mid, "Send request to tool agent failed: "
+ "tool agent is not running");
+ return false;
+ }
+
+ /* Create queue message for tool agent */
+ if (!(tool_agent_msg =
+ APP_MGR_MALLOC(sizeof(bh_queue_msg_t)))) {
+ SEND_ERR_RESPONSE(mid, "Send request to tool agent failed: "
+ "allocate memory failed");
+ return false;
+ }
+
+ if (attr_cont)
+ attr_cont_len =
+ attr_container_get_serialize_length(attr_cont);
+
+ req_msg_len =
+ sizeof(bh_request_msg_t) + strlen(p) + 1 + attr_cont_len;
+
+ /* Create request message */
+ if (!(req_msg = APP_MGR_MALLOC(req_msg_len))) {
+ SEND_ERR_RESPONSE(mid, "Send request to applet failed: "
+ "allocate memory failed");
+ APP_MGR_FREE(tool_agent_msg);
+ return false;
+ }
+
+ /* Set request message */
+ memset(req_msg, 0, req_msg_len);
+ req_msg->mid = mid;
+ req_msg->url = (char *)req_msg + sizeof(bh_request_msg_t);
+ bh_strcpy_s(req_msg->url, strlen(p) + 1,
+ p); /* Actual url sent to tool agent */
+ req_msg->action = packet->code;
+ req_msg->fmt = 0;
+ if (attr_cont) {
+ req_msg->payload = (char *)req_msg
+ + sizeof(bh_request_msg_t) + strlen(p)
+ + 1;
+ attr_container_serialize(req_msg->payload, attr_cont);
+ }
+
+ /* Set queue message and send to tool agent's queue */
+ tool_agent_msg->message_type = JDWP_REQUEST;
+ tool_agent_msg->payload_size = req_msg_len;
+ tool_agent_msg->payload = (char *)req_msg;
+ if (!bh_queue_send_message(applet_data->tool_agent_queue,
+ tool_agent_msg)) {
+ APP_MGR_FREE(req_msg);
+ APP_MGR_FREE(tool_agent_msg);
+ SEND_ERR_RESPONSE(mid, "Send request to tool agent failed: "
+ "send queue msg failed.");
+ return false;
+ }
+
+ /* app_manager_printf("Send request to tool agent of applet
+ * %s success.\n", applet_name); */
+ }
+
+ return true;
+ }
+ }
+#endif /* BEIHAI_ENABLE_TOOL_AGENT != 0 */
+ return false;
+}
+
+static module_data *
+jeff_module_get_module_data(void)
+{
+ JeffThreadLocalRoot *self = jeff_runtime_get_tlr();
+ return (module_data *)self->il_root->start_routine_arg;
+}
+
+#if BEIHAI_ENABLE_TOOL_AGENT != 0
+
+#define JDWP_HANDSHAKE_MAGIC "JDWP-Handshake"
+#define JDWP_HANDSHAKE_LEN (sizeof(JDWP_HANDSHAKE_MAGIC) - 1)
+
+#define JDWP_PAYLOAD_KEY "jdwp"
+
+static bool debug = true;
+
+static bool
+send_msg_to_host(int mid, const char *url, int code, const uint8 *msg,
+ unsigned size)
+{
+ bool ret;
+ int payload_len = 0;
+ attr_container_t *payload = NULL;
+
+ if (msg) {
+ if ((payload = attr_container_create(""))) {
+ attr_container_set_bytearray(&payload, JDWP_PAYLOAD_KEY,
+ (const int8_t *)msg, size);
+ payload_len = attr_container_get_serialize_length(payload);
+ }
+ }
+ ret = app_send_msg_to_host(mid, url, code, (char *)payload, payload_len);
+
+ if (payload)
+ attr_container_destroy(payload);
+
+ return ret;
+}
+
+static bool
+send_response(int mid, int code, const uint8 *msg, unsigned size)
+{
+ return send_msg_to_host(mid, NULL, code, msg, size);
+}
+
+static bool
+send_packet_response(int mid, int code, JeffBuffer *packet)
+{
+ int size;
+
+ if ((size = jeff_buffer_size(packet)) == 0)
+ /* No data need to be written, succeed. */
+ return true;
+
+ return send_msg_to_host(mid, NULL, code, jeff_buffer_at(packet, 0), size);
+}
+
+void
+jeff_tool_event_publish(uint8 *evtbuf, unsigned size)
+{
+ char *prefix = "/jdwp/", *url = NULL;
+ int url_len;
+
+ url_len = strlen(prefix) + strlen(app_manager_get_module_name(Module_Jeff));
+ if (NULL == (url = jeff_runtime_malloc(url_len + 1)))
+ return;
+
+ bh_strcpy_s(url, url_len + 1, prefix);
+ bh_strcat_s(url, url_len + 1, app_manager_get_module_name(Module_Jeff));
+
+ /* Event is sent as request so we set code as COAP_PUT */
+ if (event_is_registered(url))
+ send_msg_to_host(0, url, COAP_PUT, evtbuf, size);
+
+ jeff_runtime_free(url);
+}
+
+#define SEND_ERROR_RESPONSE(err_msg) \
+ do { \
+ app_manager_printf("%s\n", err_msg); \
+ send_response(req_msg->mid, INTERNAL_SERVER_ERROR_5_00, \
+ (uint8 *)err_msg, strlen(err_msg) + 1); \
+ } while (0)
+
+/* Queue callback of tool agent */
+void
+tool_agent_queue_callback(void *arg)
+{
+ bh_queue_msg_t *msg = (bh_queue_msg_t *)arg;
+
+ if (msg->message_type == JDWP_REQUEST) {
+ bh_request_msg_t *req_msg = (bh_request_msg_t *)msg->payload;
+ attr_container_t *attr_cont = (attr_container_t *)req_msg->payload;
+ JeffThreadLocalRoot *self = jeff_runtime_get_tlr();
+ JeffInstanceLocalRoot *cur_instance = self->il_root;
+ JeffToolAgent *agent = cur_instance->tool_agent;
+ bh_queue *queue = (bh_queue *)self->start_routine_arg;
+
+ if (debug)
+ app_manager_printf(
+ "Tool Agent of applet %s got request, url %s, action %d\n",
+ app_manager_get_module_name(Module_Jeff), req_msg->url,
+ req_msg->action);
+
+ /* Handshake or Process Request */
+ if (req_msg->action == COAP_GET) {
+ uint8 *buf;
+ unsigned buf_len;
+
+ if (!attr_cont
+ || !(buf = (uint8 *)attr_container_get_as_bytearray(
+ attr_cont, JDWP_PAYLOAD_KEY, &buf_len))) {
+ SEND_ERROR_RESPONSE("Tool Agent fail: invalid JDWP payload.");
+ goto fail;
+ }
+
+ if (!agent->connected) {
+ if (buf_len != JDWP_HANDSHAKE_LEN
+ || memcmp(buf, JDWP_HANDSHAKE_MAGIC, JDWP_HANDSHAKE_LEN)) {
+ SEND_ERROR_RESPONSE("Tool Agent fail: handshake fail.");
+ goto fail;
+ }
+
+ /* Handshake success and response */
+ agent->connected = true;
+ send_response(req_msg->mid, CONTENT_2_05, buf, buf_len);
+ }
+ else {
+ /* TODO: tool-agent thread should reuse the request/reply
+ * buffer to avoid allocating memory repeatedly */
+ JeffBuffer request, reply;
+
+ /* Initialize the package buffers. */
+ jeff_buffer_init(&request);
+ jeff_buffer_init(&reply);
+
+ if (!jeff_buffer_resize(&request, buf_len)) {
+ SEND_ERROR_RESPONSE("Tool Agent fail: resize buffer fail.");
+ jeff_buffer_destroy(&request);
+ jeff_buffer_destroy(&reply);
+ goto fail;
+ }
+
+ /* Copy data from request to jeff buffer */
+ bh_memcpy_s(jeff_buffer_at(&request, 0),
+ jeff_buffer_size(&request), buf, buf_len);
+
+ /* Handle JDWP request */
+ if (!jeff_tool_handle_packet(agent, &request, &reply)) {
+ SEND_ERROR_RESPONSE(
+ "Tool agent fail: handle request fail.");
+ jeff_buffer_destroy(&request);
+ jeff_buffer_destroy(&reply);
+ goto fail;
+ }
+
+ /* Response JDWP reply */
+ send_packet_response(req_msg->mid, CONTENT_2_05, &reply);
+
+ /* Destroy the package buffers. */
+ jeff_buffer_destroy(&request);
+ jeff_buffer_destroy(&reply);
+ }
+ }
+ /* Debugger disconnect */
+ else if (req_msg->action == COAP_DELETE) {
+ send_response(req_msg->mid, DELETED_2_02, NULL, 0);
+ bh_queue_exit_loop_run(queue);
+ }
+ else {
+ SEND_ERROR_RESPONSE("Tool agent fail: invalid request.");
+ goto fail;
+ }
+
+ APP_MGR_FREE(req_msg);
+ APP_MGR_FREE(msg);
+ return;
+
+ fail:
+ bh_queue_exit_loop_run(queue);
+ APP_MGR_FREE(req_msg);
+ }
+
+ APP_MGR_FREE(msg);
+}
+
+void
+tool_agent_queue_free_callback(void *message)
+{
+ bh_queue_msg_t *msg = (bh_queue_msg_t *)message;
+
+ if (msg->message_type == JDWP_REQUEST) {
+ bh_request_msg_t *req_msg = (bh_request_msg_t *)msg->payload;
+ APP_MGR_FREE(req_msg);
+ }
+
+ APP_MGR_FREE(msg);
+}
+
+#endif /* BEIHAI_ENABLE_TOOL_AGENT != 0 */
+
+/* clang-format off */
+module_interface jeff_module_interface = {
+ jeff_module_init,
+ jeff_module_install,
+ jeff_module_uninstall,
+ jeff_module_watchdog_kill,
+ jeff_module_handle_host_url,
+ jeff_module_get_module_data,
+ NULL
+};
+/* clang-format on */
+
+#endif
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_jeff.h b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_jeff.h
new file mode 100644
index 000000000..bb39f27e4
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_jeff.h
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifndef _MODULE_JEFF_H_
+#define _MODULE_JEFF_H_
+
+#include "app_manager.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern module_interface jeff_module_interface;
+
+/* sensor event */
+typedef struct bh_sensor_event_t {
+ /* Java sensor object */
+ void *sensor;
+ /* event of attribute container from context core */
+ void *event;
+} bh_sensor_event_t;
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif /* _MODULE_JEFF_H_ */
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_utils.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_utils.c
new file mode 100644
index 000000000..b4b25e4a9
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_utils.c
@@ -0,0 +1,230 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include "app_manager.h"
+#include "app_manager_host.h"
+#include "bh_platform.h"
+#include "bi-inc/attr_container.h"
+#include "event.h"
+#include "watchdog.h"
+#include "coap_ext.h"
+
+/* Lock of the module data list */
+korp_mutex module_data_list_lock;
+
+/* Module data list */
+module_data *module_data_list;
+
+bool
+module_data_list_init()
+{
+ module_data_list = NULL;
+ return !os_mutex_init(&module_data_list_lock) ? true : false;
+}
+
+void
+module_data_list_destroy()
+{
+
+ os_mutex_lock(&module_data_list_lock);
+ if (module_data_list) {
+ while (module_data_list) {
+ module_data *p = module_data_list->next;
+ APP_MGR_FREE(module_data_list);
+ module_data_list = p;
+ }
+ }
+ os_mutex_unlock(&module_data_list_lock);
+ os_mutex_destroy(&module_data_list_lock);
+}
+
+static void
+module_data_list_add(module_data *m_data)
+{
+ static uint32 module_id_max = 1;
+ os_mutex_lock(&module_data_list_lock);
+ // reserve some special ID
+ // TODO: check the new id is not already occupied!
+ if (module_id_max == 0xFFFFFFF0)
+ module_id_max = 1;
+ m_data->id = module_id_max++;
+ if (!module_data_list) {
+ module_data_list = m_data;
+ }
+ else {
+ /* Set as head */
+ m_data->next = module_data_list;
+ module_data_list = m_data;
+ }
+ os_mutex_unlock(&module_data_list_lock);
+}
+
+void
+module_data_list_remove(module_data *m_data)
+{
+ os_mutex_lock(&module_data_list_lock);
+ if (module_data_list) {
+ if (module_data_list == m_data)
+ module_data_list = module_data_list->next;
+ else {
+ /* Search and remove it */
+ module_data *p = module_data_list;
+
+ while (p && p->next != m_data)
+ p = p->next;
+ if (p && p->next == m_data)
+ p->next = p->next->next;
+ }
+ }
+ os_mutex_unlock(&module_data_list_lock);
+}
+
+module_data *
+module_data_list_lookup(const char *module_name)
+{
+ os_mutex_lock(&module_data_list_lock);
+ if (module_data_list) {
+ module_data *p = module_data_list;
+
+ while (p) {
+ /* Search by module name */
+ if (!strcmp(module_name, p->module_name)) {
+ os_mutex_unlock(&module_data_list_lock);
+ return p;
+ }
+ p = p->next;
+ }
+ }
+ os_mutex_unlock(&module_data_list_lock);
+ return NULL;
+}
+
+module_data *
+module_data_list_lookup_id(unsigned int module_id)
+{
+ os_mutex_lock(&module_data_list_lock);
+ if (module_data_list) {
+ module_data *p = module_data_list;
+
+ while (p) {
+ /* Search by module name */
+ if (module_id == p->id) {
+ os_mutex_unlock(&module_data_list_lock);
+ return p;
+ }
+ p = p->next;
+ }
+ }
+ os_mutex_unlock(&module_data_list_lock);
+ return NULL;
+}
+
+module_data *
+app_manager_get_module_data(uint32 module_type, void *module_inst)
+{
+ if (module_type < Module_Max && g_module_interfaces[module_type]
+ && g_module_interfaces[module_type]->module_get_module_data)
+ return g_module_interfaces[module_type]->module_get_module_data(
+ module_inst);
+ return NULL;
+}
+
+void *
+app_manager_get_module_queue(uint32 module_type, void *module_inst)
+{
+ module_data *m_data = app_manager_get_module_data(module_type, module_inst);
+ return m_data ? m_data->queue : NULL;
+}
+
+const char *
+app_manager_get_module_name(uint32 module_type, void *module_inst)
+{
+ module_data *m_data = app_manager_get_module_data(module_type, module_inst);
+ return m_data ? m_data->module_name : NULL;
+}
+
+unsigned int
+app_manager_get_module_id(uint32 module_type, void *module_inst)
+{
+ module_data *m_data = app_manager_get_module_data(module_type, module_inst);
+ return m_data ? m_data->id : ID_NONE;
+}
+
+void *
+app_manager_get_module_heap(uint32 module_type, void *module_inst)
+{
+ module_data *m_data = app_manager_get_module_data(module_type, module_inst);
+ return m_data ? m_data->heap : NULL;
+}
+
+module_data *
+app_manager_lookup_module_data(const char *name)
+{
+ return module_data_list_lookup(name);
+}
+
+void
+app_manager_add_module_data(module_data *m_data)
+{
+ module_data_list_add(m_data);
+}
+
+void
+app_manager_del_module_data(module_data *m_data)
+{
+ module_data_list_remove(m_data);
+
+ release_module(m_data);
+}
+
+bool
+app_manager_is_interrupting_module(uint32 module_type, void *module_inst)
+{
+ module_data *m_data = app_manager_get_module_data(module_type, module_inst);
+ return m_data ? m_data->wd_timer.is_interrupting : false;
+}
+
+extern void
+destroy_module_timer_ctx(unsigned int module_id);
+
+void
+release_module(module_data *m_data)
+{
+ watchdog_timer_destroy(&m_data->wd_timer);
+
+#ifdef HEAP_ENABLED /* TODO */
+ if (m_data->heap)
+ gc_destroy_for_instance(m_data->heap);
+#endif
+
+ if (m_data->queue)
+ bh_queue_destroy(m_data->queue);
+
+ m_data->timer_ctx = NULL;
+
+ destroy_module_timer_ctx(m_data->id);
+
+ APP_MGR_FREE(m_data);
+}
+
+uint32
+check_modules_timer_expiry()
+{
+ os_mutex_lock(&module_data_list_lock);
+ module_data *p = module_data_list;
+ uint32 ms_to_expiry = (uint32)-1;
+
+ while (p) {
+ uint32 next = get_expiry_ms(p->timer_ctx);
+ if (next != (uint32)-1) {
+ if (ms_to_expiry == (uint32)-1 || ms_to_expiry > next)
+ ms_to_expiry = next;
+ }
+
+ p = p->next;
+ }
+ os_mutex_unlock(&module_data_list_lock);
+ return ms_to_expiry;
+}
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_wasm_app.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_wasm_app.c
new file mode 100644
index 000000000..2005ad8e8
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_wasm_app.c
@@ -0,0 +1,1743 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include "module_wasm_app.h"
+
+#include "native_interface.h" /* for request_t type */
+#include "app_manager_host.h"
+#include "bh_platform.h"
+#include "bi-inc/attr_container.h"
+#include "coap_ext.h"
+#include "event.h"
+#include "watchdog.h"
+#include "runtime_lib.h"
+#if WASM_ENABLE_INTERP != 0
+#include "wasm.h"
+#endif
+#if WASM_ENABLE_AOT != 0
+#include "aot_export.h"
+#endif
+
+/* clang-format off */
+#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
+/* Wasm bytecode file 4 version bytes */
+static uint8 wasm_bytecode_version[4] = {
+ (uint8)0x01,
+ (uint8)0x00,
+ (uint8)0x00,
+ (uint8)0x00
+};
+#endif
+
+#if WASM_ENABLE_AOT != 0
+/* Wasm aot file 4 version bytes */
+static uint8 wasm_aot_version[4] = {
+ (uint8)0x02,
+ (uint8)0x00,
+ (uint8)0x00,
+ (uint8)0x00
+};
+#endif
+/* clang-format on */
+
+static union {
+ int a;
+ char b;
+} __ue = { .a = 1 };
+
+#define is_little_endian() (__ue.b == 1)
+/* Wasm App Install Request Receiving Phase */
+typedef enum wasm_app_install_req_recv_phase_t {
+ Phase_Req_Ver,
+ Phase_Req_Action,
+ Phase_Req_Fmt,
+ Phase_Req_Mid,
+ Phase_Req_Sender,
+ Phase_Req_Url_Len,
+ Phase_Req_Payload_Len, /* payload is wasm app binary */
+ Phase_Req_Url,
+
+ /* Magic phase */
+ Phase_App_Magic,
+
+#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
+ /* Phases of wasm bytecode file */
+ Phase_Wasm_Version,
+ Phase_Wasm_Section_Type,
+ Phase_Wasm_Section_Size,
+ Phase_Wasm_Section_Content,
+#endif
+
+#if WASM_ENABLE_AOT != 0
+ /* Phases of wasm AOT file */
+ Phase_AOT_Version,
+ Phase_AOT_Section_ID,
+ Phase_AOT_Section_Size,
+ Phase_AOT_Section_Content
+#endif
+} wasm_app_install_req_recv_phase_t;
+
+/* Message for insall wasm app */
+typedef struct install_wasm_app_msg_t {
+ uint8 request_version;
+ uint8 request_action;
+ uint16 request_fmt;
+ uint32 request_mid;
+ uint32 request_sender;
+ uint16 request_url_len;
+ uint32 wasm_app_size; /* payload size is just wasm app binary size */
+ char *request_url;
+ wasm_app_file_t app_file;
+ int app_file_magic;
+} install_wasm_app_msg_t;
+
+/* Wasm App Install Request Receive Context */
+typedef struct wasm_app_install_req_recv_ctx_t {
+ wasm_app_install_req_recv_phase_t phase;
+ int size_in_phase;
+ install_wasm_app_msg_t message;
+ int total_received_size;
+} wasm_app_install_req_recv_ctx_t;
+
+/* Current wasm app install request receive context */
+static wasm_app_install_req_recv_ctx_t recv_ctx;
+
+static bool
+wasm_app_module_init(void);
+
+static bool
+wasm_app_module_install(request_t *msg);
+
+static bool
+wasm_app_module_uninstall(request_t *msg);
+
+static void
+wasm_app_module_watchdog_kill(module_data *module_data);
+
+static bool
+wasm_app_module_handle_host_url(void *queue_msg);
+
+static module_data *
+wasm_app_module_get_module_data(void *inst);
+
+static bool
+wasm_app_module_on_install_request_byte_arrive(uint8 ch, int request_total_size,
+ int *received_size);
+
+static bool
+module_wasm_app_handle_install_msg(install_wasm_app_msg_t *message);
+
+#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
+static void
+destroy_all_wasm_sections(wasm_section_list_t sections);
+
+static void
+destroy_part_wasm_sections(wasm_section_list_t *p_sections,
+ uint8 *section_types, int section_cnt);
+#endif
+
+#if WASM_ENABLE_AOT != 0
+static void
+destroy_all_aot_sections(aot_section_list_t sections);
+
+static void
+destroy_part_aot_sections(aot_section_list_t *p_sections, uint8 *section_types,
+ int section_cnt);
+#endif
+
+#define Max_Msg_Callback 10
+int g_msg_type[Max_Msg_Callback] = { 0 };
+message_type_handler_t g_msg_callbacks[Max_Msg_Callback] = { 0 };
+
+#define Max_Cleanup_Callback 10
+static resource_cleanup_handler_t g_cleanup_callbacks[Max_Cleanup_Callback] = {
+ 0
+};
+
+module_interface wasm_app_module_interface = {
+ wasm_app_module_init,
+ wasm_app_module_install,
+ wasm_app_module_uninstall,
+ wasm_app_module_watchdog_kill,
+ wasm_app_module_handle_host_url,
+ wasm_app_module_get_module_data,
+ wasm_app_module_on_install_request_byte_arrive
+};
+
+#if WASM_ENABLE_INTERP == 0
+static unsigned
+align_uint(unsigned v, unsigned b)
+{
+ unsigned m = b - 1;
+ return (v + m) & ~m;
+}
+#endif
+
+static void
+exchange_uint32(uint8 *p_data)
+{
+ uint8 value = *p_data;
+ *p_data = *(p_data + 3);
+ *(p_data + 3) = value;
+
+ value = *(p_data + 1);
+ *(p_data + 1) = *(p_data + 2);
+ *(p_data + 2) = value;
+}
+
+static wasm_function_inst_t
+app_manager_lookup_function(const wasm_module_inst_t module_inst,
+ const char *name, const char *signature)
+{
+ wasm_function_inst_t func;
+
+ func = wasm_runtime_lookup_function(module_inst, name, signature);
+ if (!func && name[0] == '_')
+ func = wasm_runtime_lookup_function(module_inst, name + 1, signature);
+ return func;
+}
+
+static void
+app_instance_queue_callback(void *queue_msg, void *arg)
+{
+ uint32 argv[2];
+ wasm_function_inst_t func_onRequest, func_onTimer;
+
+ wasm_module_inst_t inst = (wasm_module_inst_t)arg;
+ module_data *m_data = app_manager_get_module_data(Module_WASM_App, inst);
+ wasm_data *wasm_app_data;
+ int message_type;
+
+ bh_assert(m_data);
+ wasm_app_data = (wasm_data *)m_data->internal_data;
+ message_type = bh_message_type(queue_msg);
+
+ if (message_type < BASE_EVENT_MAX) {
+ switch (message_type) {
+ case RESTFUL_REQUEST:
+ {
+ request_t *request = (request_t *)bh_message_payload(queue_msg);
+ int size;
+ char *buffer;
+ int32 buffer_offset;
+
+ app_manager_printf("App %s got request, url %s, action %d\n",
+ m_data->module_name, request->url,
+ request->action);
+
+ func_onRequest = app_manager_lookup_function(
+ inst, "_on_request", "(i32i32)");
+ if (!func_onRequest) {
+ app_manager_printf("Cannot find function onRequest\n");
+ break;
+ }
+
+ buffer = pack_request(request, &size);
+ if (buffer == NULL)
+ break;
+
+ buffer_offset =
+ wasm_runtime_module_dup_data(inst, buffer, size);
+ if (buffer_offset == 0) {
+ const char *exception = wasm_runtime_get_exception(inst);
+ if (exception) {
+ app_manager_printf(
+ "Got exception running wasm code: %s\n", exception);
+ wasm_runtime_clear_exception(inst);
+ }
+ free_req_resp_packet(buffer);
+ break;
+ }
+
+ free_req_resp_packet(buffer);
+
+ argv[0] = (uint32)buffer_offset;
+ argv[1] = (uint32)size;
+
+ if (!wasm_runtime_call_wasm(wasm_app_data->exec_env,
+ func_onRequest, 2, argv)) {
+ const char *exception = wasm_runtime_get_exception(inst);
+ bh_assert(exception);
+ app_manager_printf("Got exception running wasm code: %s\n",
+ exception);
+ wasm_runtime_clear_exception(inst);
+ wasm_runtime_module_free(inst, buffer_offset);
+ break;
+ }
+
+ wasm_runtime_module_free(inst, buffer_offset);
+ app_manager_printf("Wasm app process request success.\n");
+ break;
+ }
+ case RESTFUL_RESPONSE:
+ {
+ wasm_function_inst_t func_onResponse;
+ response_t *response =
+ (response_t *)bh_message_payload(queue_msg);
+ int size;
+ char *buffer;
+ int32 buffer_offset;
+
+ app_manager_printf("App %s got response_t,status %d\n",
+ m_data->module_name, response->status);
+
+ func_onResponse = app_manager_lookup_function(
+ inst, "_on_response", "(i32i32)");
+ if (!func_onResponse) {
+ app_manager_printf("Cannot find function on_response\n");
+ break;
+ }
+
+ buffer = pack_response(response, &size);
+ if (buffer == NULL)
+ break;
+
+ buffer_offset =
+ wasm_runtime_module_dup_data(inst, buffer, size);
+ if (buffer_offset == 0) {
+ const char *exception = wasm_runtime_get_exception(inst);
+ if (exception) {
+ app_manager_printf(
+ "Got exception running wasm code: %s\n", exception);
+ wasm_runtime_clear_exception(inst);
+ }
+ free_req_resp_packet(buffer);
+ break;
+ }
+
+ free_req_resp_packet(buffer);
+
+ argv[0] = (uint32)buffer_offset;
+ argv[1] = (uint32)size;
+
+ if (!wasm_runtime_call_wasm(wasm_app_data->exec_env,
+ func_onResponse, 2, argv)) {
+ const char *exception = wasm_runtime_get_exception(inst);
+ bh_assert(exception);
+ app_manager_printf("Got exception running wasm code: %s\n",
+ exception);
+ wasm_runtime_clear_exception(inst);
+ wasm_runtime_module_free(inst, buffer_offset);
+ break;
+ }
+
+ wasm_runtime_module_free(inst, buffer_offset);
+ app_manager_printf("Wasm app process response success.\n");
+ break;
+ }
+ default:
+ {
+ for (int i = 0; i < Max_Msg_Callback; i++) {
+ if (g_msg_type[i] == message_type) {
+ g_msg_callbacks[i](m_data, queue_msg);
+ return;
+ }
+ }
+ app_manager_printf(
+ "Invalid message type of WASM app queue message.\n");
+ break;
+ }
+ }
+ }
+ else {
+ switch (message_type) {
+ case TIMER_EVENT_WASM:
+ {
+ unsigned int timer_id;
+ if (bh_message_payload(queue_msg)) {
+ /* Call Timer.callOnTimer() method */
+ func_onTimer = app_manager_lookup_function(
+ inst, "_on_timer_callback", "(i32)");
+
+ if (!func_onTimer) {
+ app_manager_printf(
+ "Cannot find function _on_timer_callback\n");
+ break;
+ }
+ timer_id =
+ (unsigned int)(uintptr_t)bh_message_payload(queue_msg);
+ argv[0] = timer_id;
+ if (!wasm_runtime_call_wasm(wasm_app_data->exec_env,
+ func_onTimer, 1, argv)) {
+ const char *exception =
+ wasm_runtime_get_exception(inst);
+ bh_assert(exception);
+ app_manager_printf(
+ "Got exception running wasm code: %s\n", exception);
+ wasm_runtime_clear_exception(inst);
+ }
+ }
+ break;
+ }
+ default:
+ {
+ for (int i = 0; i < Max_Msg_Callback; i++) {
+ if (g_msg_type[i] == message_type) {
+ g_msg_callbacks[i](m_data, queue_msg);
+ return;
+ }
+ }
+ app_manager_printf(
+ "Invalid message type of WASM app queue message.\n");
+ break;
+ }
+ }
+ }
+}
+
+#if WASM_ENABLE_LIBC_WASI != 0
+static bool
+wasm_app_prepare_wasi_dir(wasm_module_t module, const char *module_name,
+ char *wasi_dir_buf, uint32 buf_size)
+{
+ const char *wasi_root = wasm_get_wasi_root_dir();
+ char *p = wasi_dir_buf;
+ uint32 module_name_len = strlen(module_name);
+ uint32 wasi_root_len = strlen(wasi_root);
+ uint32 total_size;
+ struct stat st = { 0 };
+
+ bh_assert(wasi_root);
+
+ /* wasi_dir: wasi_root/module_name */
+ total_size = wasi_root_len + 1 + module_name_len + 1;
+ if (total_size > buf_size)
+ return false;
+ memcpy(p, wasi_root, wasi_root_len);
+ p += wasi_root_len;
+ *p++ = '/';
+ memcpy(p, module_name, module_name_len);
+ p += module_name_len;
+ *p++ = '\0';
+
+ if (mkdir(wasi_dir_buf, 0777) != 0) {
+ if (errno == EEXIST) {
+ /* Failed due to dir already exist */
+ if ((stat(wasi_dir_buf, &st) == 0) && (st.st_mode & S_IFDIR)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ return true;
+}
+#endif
+
+/* WASM app thread main routine */
+static void *
+wasm_app_routine(void *arg)
+{
+ wasm_function_inst_t func_onInit;
+ wasm_function_inst_t func_onDestroy;
+
+ module_data *m_data = (module_data *)arg;
+ wasm_data *wasm_app_data = (wasm_data *)m_data->internal_data;
+ wasm_module_inst_t inst = wasm_app_data->wasm_module_inst;
+
+ /* Set m_data to the VM managed instance's custom data */
+ wasm_runtime_set_custom_data(inst, m_data);
+
+ app_manager_printf("WASM app '%s' started\n", m_data->module_name);
+
+#if WASM_ENABLE_LIBC_WASI != 0
+ if (wasm_runtime_is_wasi_mode(inst)) {
+ wasm_function_inst_t func_start;
+ /* In wasi mode, we should call function named "_start"
+ which initializes the wasi envrionment. The "_start" function
+ will call "main" function */
+ if ((func_start = wasm_runtime_lookup_wasi_start_function(inst))) {
+ if (!wasm_runtime_call_wasm(wasm_app_data->exec_env, func_start, 0,
+ NULL)) {
+ const char *exception = wasm_runtime_get_exception(inst);
+ bh_assert(exception);
+ app_manager_printf(
+ "Got exception running wasi start function: %s\n",
+ exception);
+ wasm_runtime_clear_exception(inst);
+ goto fail1;
+ }
+ }
+ /* if no start function is found, we execute
+ the _on_init function as normal */
+ }
+#endif
+
+ /* Call app's onInit() method */
+ func_onInit = app_manager_lookup_function(inst, "_on_init", "()");
+ if (!func_onInit) {
+ app_manager_printf("Cannot find function on_init().\n");
+ goto fail1;
+ }
+
+ if (!wasm_runtime_call_wasm(wasm_app_data->exec_env, func_onInit, 0,
+ NULL)) {
+ const char *exception = wasm_runtime_get_exception(inst);
+ bh_assert(exception);
+ app_manager_printf("Got exception running WASM code: %s\n", exception);
+ wasm_runtime_clear_exception(inst);
+ /* call on_destroy() in case some resources are opened in on_init()
+ * and then exception thrown */
+ goto fail2;
+ }
+
+ /* Enter queue loop run to receive and process applet queue message */
+ bh_queue_enter_loop_run(m_data->queue, app_instance_queue_callback, inst);
+
+ app_manager_printf("App instance main thread exit.\n");
+
+fail2:
+ /* Call WASM app onDestroy() method if there is */
+ func_onDestroy = app_manager_lookup_function(inst, "_on_destroy", "()");
+ if (func_onDestroy) {
+ if (!wasm_runtime_call_wasm(wasm_app_data->exec_env, func_onDestroy, 0,
+ NULL)) {
+ const char *exception = wasm_runtime_get_exception(inst);
+ bh_assert(exception);
+ app_manager_printf("Got exception running WASM code: %s\n",
+ exception);
+ wasm_runtime_clear_exception(inst);
+ }
+ }
+
+fail1:
+
+ return NULL;
+}
+
+static void
+cleanup_app_resource(module_data *m_data)
+{
+ int i;
+ wasm_data *wasm_app_data = (wasm_data *)m_data->internal_data;
+ bool is_bytecode = wasm_app_data->is_bytecode;
+
+ am_cleanup_registeration(m_data->id);
+
+ am_unregister_event(NULL, m_data->id);
+
+ for (i = 0; i < Max_Cleanup_Callback; i++) {
+ if (g_cleanup_callbacks[i] != NULL)
+ g_cleanup_callbacks[i](m_data->id);
+ else
+ break;
+ }
+
+ wasm_runtime_deinstantiate(wasm_app_data->wasm_module_inst);
+
+ /* Destroy remain sections (i.e. data segment section for bytecode file
+ * or text section of aot file) from app file's section list. */
+ if (is_bytecode) {
+#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
+ destroy_all_wasm_sections(
+ (wasm_section_list_t)(wasm_app_data->sections));
+#else
+ bh_assert(0);
+#endif
+ }
+ else {
+#if WASM_ENABLE_AOT != 0
+ destroy_all_aot_sections((aot_section_list_t)(wasm_app_data->sections));
+#else
+ bh_assert(0);
+#endif
+ }
+
+ if (wasm_app_data->wasm_module)
+ wasm_runtime_unload(wasm_app_data->wasm_module);
+
+ if (wasm_app_data->exec_env)
+ wasm_runtime_destroy_exec_env(wasm_app_data->exec_env);
+
+ /* Destroy watchdog timer */
+ watchdog_timer_destroy(&m_data->wd_timer);
+
+ /* Remove module data from module data list and free it */
+ app_manager_del_module_data(m_data);
+}
+
+/************************************************************/
+/* Module specific functions implementation */
+/************************************************************/
+
+static bool
+wasm_app_module_init(void)
+{
+ uint32 version;
+
+#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
+ version = WASM_CURRENT_VERSION;
+ if (!is_little_endian())
+ exchange_uint32((uint8 *)&version);
+ bh_memcpy_s(wasm_bytecode_version, 4, &version, 4);
+#endif
+
+#if WASM_ENABLE_AOT != 0
+ version = AOT_CURRENT_VERSION;
+ if (!is_little_endian())
+ exchange_uint32((uint8 *)&version);
+ bh_memcpy_s(wasm_aot_version, 4, &version, 4);
+#endif
+ return true;
+}
+
+#define APP_NAME_MAX_LEN 128
+#define MAX_INT_STR_LEN 11
+
+static bool
+wasm_app_module_install(request_t *msg)
+{
+ unsigned int m_data_size, heap_size, stack_size;
+ unsigned int timeout, timers, err_size;
+ char *properties;
+ int properties_offset;
+ wasm_app_file_t *wasm_app_file;
+ wasm_data *wasm_app_data;
+ package_type_t package_type;
+ module_data *m_data = NULL;
+ wasm_module_t module = NULL;
+ wasm_module_inst_t inst = NULL;
+ wasm_exec_env_t exec_env = NULL;
+ char m_name[APP_NAME_MAX_LEN] = { 0 };
+ char timeout_str[MAX_INT_STR_LEN] = { 0 };
+ char heap_size_str[MAX_INT_STR_LEN] = { 0 };
+ char timers_str[MAX_INT_STR_LEN] = { 0 }, err[128], err_resp[256];
+#if WASM_ENABLE_LIBC_WASI != 0
+ char wasi_dir_buf[PATH_MAX] = { 0 };
+ const char *wasi_dir_list[] = { wasi_dir_buf };
+#endif
+
+ err_size = sizeof(err);
+
+ /* Check payload */
+ if (!msg->payload || msg->payload_len == 0) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install WASM app failed: invalid wasm file.");
+ return false;
+ }
+
+ /* Judge the app type is AOTed or not */
+ package_type = get_package_type((uint8 *)msg->payload, msg->payload_len);
+ wasm_app_file = (wasm_app_file_t *)msg->payload;
+
+ /* Check app name */
+ properties_offset = check_url_start(msg->url, strlen(msg->url), "/applet");
+ bh_assert(properties_offset > 0);
+ if (properties_offset <= 0) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install WASM app failed: invalid app name.");
+ goto fail;
+ }
+
+ properties = msg->url + properties_offset;
+ find_key_value(properties, strlen(properties), "name", m_name,
+ sizeof(m_name) - 1, '&');
+
+ if (strlen(m_name) == 0) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install WASM app failed: invalid app name.");
+ goto fail;
+ }
+
+ if (app_manager_lookup_module_data(m_name)) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install WASM app failed: app already installed.");
+ goto fail;
+ }
+
+ /* Parse heap size */
+ heap_size = APP_HEAP_SIZE_DEFAULT;
+ find_key_value(properties, strlen(properties), "heap", heap_size_str,
+ sizeof(heap_size_str) - 1, '&');
+ if (strlen(heap_size_str) > 0) {
+ heap_size = atoi(heap_size_str);
+ if (heap_size < APP_HEAP_SIZE_MIN)
+ heap_size = APP_HEAP_SIZE_MIN;
+ else if (heap_size > APP_HEAP_SIZE_MAX)
+ heap_size = APP_HEAP_SIZE_MAX;
+ }
+
+ /* Load WASM file and instantiate*/
+ switch (package_type) {
+#if WASM_ENABLE_AOT != 0
+ case Wasm_Module_AoT:
+ {
+ wasm_aot_file_t *aot_file;
+ /* clang-format off */
+ /* Sections to be released after loading */
+ uint8 sections1[] = {
+ AOT_SECTION_TYPE_TARGET_INFO,
+ AOT_SECTION_TYPE_INIT_DATA,
+ AOT_SECTION_TYPE_FUNCTION,
+ AOT_SECTION_TYPE_EXPORT,
+ AOT_SECTION_TYPE_RELOCATION,
+ AOT_SECTION_TYPE_SIGANATURE,
+ AOT_SECTION_TYPE_CUSTOM,
+ };
+ /* clang-format on */
+
+ aot_file = &wasm_app_file->u.aot;
+
+ /* Load AOT module from sections */
+ module = wasm_runtime_load_from_sections(aot_file->sections, true,
+ err, err_size);
+ if (!module) {
+ snprintf(err_resp, sizeof(err_resp),
+ "Install WASM app failed: %s", err);
+ SEND_ERR_RESPONSE(msg->mid, err_resp);
+ goto fail;
+ }
+ /* Destroy useless sections from list after load */
+ destroy_part_aot_sections(&aot_file->sections, sections1,
+ sizeof(sections1) / sizeof(uint8));
+
+#if WASM_ENABLE_LIBC_WASI != 0
+ if (!wasm_app_prepare_wasi_dir(module, m_name, wasi_dir_buf,
+ sizeof(wasi_dir_buf))) {
+ SEND_ERR_RESPONSE(
+ msg->mid,
+ "Install WASM app failed: prepare wasi env failed.");
+ goto fail;
+ }
+ wasm_runtime_set_wasi_args(module, wasi_dir_list, 1, NULL, 0, NULL,
+ 0, NULL, 0);
+#endif
+
+ /* Instantiate the AOT module */
+ inst =
+ wasm_runtime_instantiate(module, 0, heap_size, err, err_size);
+ if (!inst) {
+ snprintf(err_resp, sizeof(err_resp),
+ "Install WASM app failed: %s", err);
+ SEND_ERR_RESPONSE(msg->mid, err);
+ goto fail;
+ }
+ break;
+ }
+#endif /* endof WASM_ENABLE_AOT != 0 */
+
+#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
+ case Wasm_Module_Bytecode:
+ {
+ wasm_bytecode_file_t *bytecode_file;
+ /* Sections to be released after loading */
+ uint8 sections1[] = {
+ SECTION_TYPE_USER,
+ SECTION_TYPE_TYPE,
+ SECTION_TYPE_IMPORT,
+ SECTION_TYPE_FUNC,
+ SECTION_TYPE_TABLE,
+ SECTION_TYPE_MEMORY,
+ SECTION_TYPE_GLOBAL,
+ SECTION_TYPE_EXPORT,
+ SECTION_TYPE_START,
+ SECTION_TYPE_ELEM,
+#if WASM_ENABLE_BULK_MEMORY != 0
+ SECTION_TYPE_DATACOUNT
+#endif
+
+ };
+ /* Sections to be released after instantiating */
+ uint8 sections2[] = { SECTION_TYPE_DATA };
+
+ bytecode_file = &wasm_app_file->u.bytecode;
+
+ /* Load wasm module from sections */
+ module = wasm_runtime_load_from_sections(bytecode_file->sections,
+ false, err, err_size);
+ if (!module) {
+ snprintf(err_resp, sizeof(err_resp),
+ "Install WASM app failed: %s", err);
+ SEND_ERR_RESPONSE(msg->mid, err_resp);
+ goto fail;
+ }
+
+ /* Destroy useless sections from list after load */
+ destroy_part_wasm_sections(&bytecode_file->sections, sections1,
+ sizeof(sections1) / sizeof(uint8));
+
+#if WASM_ENABLE_LIBC_WASI != 0
+ if (!wasm_app_prepare_wasi_dir(module, m_name, wasi_dir_buf,
+ sizeof(wasi_dir_buf))) {
+ SEND_ERR_RESPONSE(
+ msg->mid,
+ "Install WASM app failed: prepare wasi env failed.");
+ goto fail;
+ }
+ wasm_runtime_set_wasi_args(module, wasi_dir_list, 1, NULL, 0, NULL,
+ 0, NULL, 0);
+#endif
+
+ /* Instantiate the wasm module */
+ inst =
+ wasm_runtime_instantiate(module, 0, heap_size, err, err_size);
+ if (!inst) {
+ snprintf(err_resp, sizeof(err_resp),
+ "Install WASM app failed: %s", err);
+ SEND_ERR_RESPONSE(msg->mid, err_resp);
+ goto fail;
+ }
+
+ /* Destroy useless sections from list after instantiate */
+ destroy_part_wasm_sections(&bytecode_file->sections, sections2,
+ sizeof(sections2) / sizeof(uint8));
+ break;
+ }
+#endif /* endof WASM_ENALBE_INTERP != 0 || WASM_ENABLE_JIT != 0 */
+ default:
+ SEND_ERR_RESPONSE(
+ msg->mid,
+ "Install WASM app failed: invalid wasm package type.");
+ goto fail;
+ }
+
+ /* Create module data including the wasm_app_data as its internal_data*/
+ m_data_size = offsetof(module_data, module_name) + strlen(m_name) + 1;
+ m_data_size = align_uint(m_data_size, 4);
+ m_data = APP_MGR_MALLOC(m_data_size + sizeof(wasm_data));
+ if (!m_data) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install WASM app failed: allocate memory failed.");
+ goto fail;
+ }
+ memset(m_data, 0, m_data_size + sizeof(wasm_data));
+
+ m_data->module_type = Module_WASM_App;
+ m_data->internal_data = (uint8 *)m_data + m_data_size;
+ wasm_app_data = (wasm_data *)m_data->internal_data;
+ wasm_app_data->wasm_module_inst = inst;
+ wasm_app_data->wasm_module = module;
+ wasm_app_data->m_data = m_data;
+ if (package_type == Wasm_Module_Bytecode) {
+ wasm_app_data->is_bytecode = true;
+ wasm_app_data->sections = wasm_app_file->u.bytecode.sections;
+ }
+ else {
+ wasm_app_data->is_bytecode = false;
+ wasm_app_data->sections = wasm_app_file->u.aot.sections;
+ }
+
+ if (!(wasm_app_data->exec_env = exec_env =
+ wasm_runtime_create_exec_env(inst, DEFAULT_WASM_STACK_SIZE))) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install WASM app failed: create exec env failed.");
+ goto fail;
+ }
+
+ /* Set module data - name and module type */
+ bh_strcpy_s(m_data->module_name, strlen(m_name) + 1, m_name);
+
+ /* Set module data - execution timeout */
+ timeout = DEFAULT_WATCHDOG_INTERVAL;
+ find_key_value(properties, strlen(properties), "wd", timeout_str,
+ sizeof(timeout_str) - 1, '&');
+ if (strlen(timeout_str) > 0)
+ timeout = atoi(timeout_str);
+ m_data->timeout = timeout;
+
+ /* Set module data - create queue */
+ m_data->queue = bh_queue_create();
+ if (!m_data->queue) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install WASM app failed: create app queue failed.");
+ goto fail;
+ }
+
+ /* Set heap size */
+ m_data->heap_size = heap_size;
+
+ /* Set module data - timers number */
+ timers = DEFAULT_TIMERS_PER_APP;
+ find_key_value(properties, strlen(properties), "timers", timers_str,
+ sizeof(timers_str) - 1, '&');
+ if (strlen(timers_str) > 0) {
+ timers = atoi(timers_str);
+ if (timers > MAX_TIMERS_PER_APP)
+ timers = MAX_TIMERS_PER_APP;
+ }
+
+ /* Attention: must add the module before start the thread! */
+ app_manager_add_module_data(m_data);
+
+ m_data->timer_ctx = create_wasm_timer_ctx(m_data->id, timers);
+ if (!m_data->timer_ctx) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install WASM app failed: create app timers failed.");
+ goto fail;
+ }
+
+ /* Initialize watchdog timer */
+ if (!watchdog_timer_init(m_data)) {
+ SEND_ERR_RESPONSE(
+ msg->mid,
+ "Install WASM app failed: create app watchdog timer failed.");
+ goto fail;
+ }
+
+ stack_size = APP_THREAD_STACK_SIZE_DEFAULT;
+#ifdef OS_ENABLE_HW_BOUND_CHECK
+ stack_size += 4 * BH_KB;
+#endif
+ /* Create WASM app thread. */
+ if (os_thread_create(&wasm_app_data->thread_id, wasm_app_routine,
+ (void *)m_data, stack_size)
+ != 0) {
+ module_data_list_remove(m_data);
+ SEND_ERR_RESPONSE(msg->mid,
+ "Install WASM app failed: create app thread failed.");
+ goto fail;
+ }
+
+ /* only when thread is created it is the flag of installation success */
+ app_manager_post_applets_update_event();
+
+ app_manager_printf("Install WASM app success!\n");
+ send_error_response_to_host(msg->mid, CREATED_2_01, NULL); /* CREATED */
+
+ return true;
+
+fail:
+ if (m_data)
+ release_module(m_data);
+
+ if (inst)
+ wasm_runtime_deinstantiate(inst);
+
+ if (module)
+ wasm_runtime_unload(module);
+
+ if (exec_env)
+ wasm_runtime_destroy_exec_env(exec_env);
+
+ switch (package_type) {
+#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
+ case Wasm_Module_Bytecode:
+ destroy_all_wasm_sections(wasm_app_file->u.bytecode.sections);
+ break;
+#endif
+#if WASM_ENABLE_AOT != 0
+ case Wasm_Module_AoT:
+ destroy_all_aot_sections(wasm_app_file->u.aot.sections);
+ break;
+#endif
+ default:
+ break;
+ }
+
+ return false;
+}
+
+/* For internal use: if defined to 1, the process will
+ * exit when wasm app is uninstalled. Hence valgrind can
+ * print memory leak report. */
+#ifndef VALGRIND_CHECK
+#define VALGRIND_CHECK 0
+#endif
+
+/* Uninstall WASM app */
+static bool
+wasm_app_module_uninstall(request_t *msg)
+{
+ module_data *m_data;
+ wasm_data *wasm_app_data;
+ char m_name[APP_NAME_MAX_LEN] = { 0 };
+ char *properties;
+ int properties_offset;
+
+ properties_offset = check_url_start(msg->url, strlen(msg->url), "/applet");
+ /* TODO: assert(properties_offset > 0) */
+ if (properties_offset <= 0)
+ return false;
+ properties = msg->url + properties_offset;
+ find_key_value(properties, strlen(properties), "name", m_name,
+ sizeof(m_name) - 1, '&');
+
+ if (strlen(m_name) == 0) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Uninstall WASM app failed: invalid app name.");
+ return false;
+ }
+
+ m_data = app_manager_lookup_module_data(m_name);
+ if (!m_data) {
+ SEND_ERR_RESPONSE(msg->mid, "Uninstall WASM app failed: no app found.");
+ return false;
+ }
+
+ if (m_data->module_type != Module_WASM_App) {
+ SEND_ERR_RESPONSE(msg->mid,
+ "Uninstall WASM app failed: invalid module type.");
+ return false;
+ }
+
+ if (m_data->wd_timer.is_interrupting) {
+ SEND_ERR_RESPONSE(
+ msg->mid,
+ "Uninstall WASM app failed: app is being interrupted by watchdog.");
+ return false;
+ }
+
+ /* Exit app queue loop run */
+ bh_queue_exit_loop_run(m_data->queue);
+
+ /* Wait for wasm app thread to exit */
+ wasm_app_data = (wasm_data *)m_data->internal_data;
+ os_thread_join(wasm_app_data->thread_id, NULL);
+
+ cleanup_app_resource(m_data);
+
+ app_manager_post_applets_update_event();
+
+ app_manager_printf("Uninstall WASM app successful!\n");
+
+#ifdef COLLECT_CODE_COVERAGE
+ /* Exit app manager so as to collect code coverage data */
+ if (!strcmp(m_name, "__exit_app_manager__")) {
+ app_manager_printf("Exit app manager\n");
+ bh_queue_exit_loop_run(get_app_manager_queue());
+ }
+#endif
+
+#if VALGRIND_CHECK != 0
+ bh_queue_exit_loop_run(get_app_manager_queue());
+#endif
+
+ send_error_response_to_host(msg->mid, DELETED_2_02, NULL); /* DELETED */
+ return true;
+}
+
+static bool
+wasm_app_module_handle_host_url(void *queue_msg)
+{
+ /* TODO: implement in future */
+ app_manager_printf("App handles host url address %d\n",
+ (int)(uintptr_t)queue_msg);
+ return false;
+}
+
+static module_data *
+wasm_app_module_get_module_data(void *inst)
+{
+ wasm_module_inst_t module_inst = (wasm_module_inst_t)inst;
+ return (module_data *)wasm_runtime_get_custom_data(module_inst);
+}
+
+static void
+wasm_app_module_watchdog_kill(module_data *m_data)
+{
+ /* TODO: implement in future */
+ app_manager_printf("Watchdog kills app: %s\n", m_data->module_name);
+ return;
+}
+
+bool
+wasm_register_msg_callback(int message_type,
+ message_type_handler_t message_handler)
+{
+ int i;
+ int freeslot = -1;
+ for (i = 0; i < Max_Msg_Callback; i++) {
+ /* replace handler for the same event registered */
+ if (g_msg_type[i] == message_type)
+ break;
+
+ if (g_msg_callbacks[i] == NULL && freeslot == -1)
+ freeslot = i;
+ }
+
+ if (i != Max_Msg_Callback)
+ g_msg_callbacks[i] = message_handler;
+ else if (freeslot != -1) {
+ g_msg_callbacks[freeslot] = message_handler;
+ g_msg_type[freeslot] = message_type;
+ }
+ else
+ return false;
+
+ return true;
+}
+
+bool
+wasm_register_cleanup_callback(resource_cleanup_handler_t handler)
+{
+ int i;
+
+ for (i = 0; i < Max_Cleanup_Callback; i++) {
+ if (g_cleanup_callbacks[i] == NULL) {
+ g_cleanup_callbacks[i] = handler;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+#define RECV_INTEGER(value, next_phase) \
+ do { \
+ uint8 *p = (uint8 *)&value; \
+ p[recv_ctx.size_in_phase++] = ch; \
+ if (recv_ctx.size_in_phase == sizeof(value)) { \
+ if (sizeof(value) == 4) \
+ value = ntohl(value); \
+ else if (sizeof(value) == 2) \
+ value = ntohs(value); \
+ recv_ctx.phase = next_phase; \
+ recv_ctx.size_in_phase = 0; \
+ } \
+ } while (0)
+
+/* return:
+ * 1: whole wasm app arrived
+ * 0: one valid byte arrived
+ * -1: fail to process the byte arrived, e.g. allocate memory fail
+ */
+static bool
+wasm_app_module_on_install_request_byte_arrive(uint8 ch, int request_total_size,
+ int *received_size)
+{
+ uint8 *p;
+ int magic;
+ package_type_t package_type = Package_Type_Unknown;
+
+ if (recv_ctx.phase == Phase_Req_Ver) {
+ recv_ctx.phase = Phase_Req_Ver;
+ recv_ctx.size_in_phase = 0;
+ recv_ctx.total_received_size = 0;
+ }
+
+ recv_ctx.total_received_size++;
+ *received_size = recv_ctx.total_received_size;
+
+ if (recv_ctx.phase == Phase_Req_Ver) {
+ if (ch != 1 /* REQUES_PACKET_VER from restful_utils.c */)
+ return false;
+ recv_ctx.phase = Phase_Req_Action;
+ return true;
+ }
+ else if (recv_ctx.phase == Phase_Req_Action) {
+ recv_ctx.message.request_action = ch;
+ recv_ctx.phase = Phase_Req_Fmt;
+ recv_ctx.size_in_phase = 0;
+ return true;
+ }
+ else if (recv_ctx.phase == Phase_Req_Fmt) {
+ RECV_INTEGER(recv_ctx.message.request_fmt, Phase_Req_Mid);
+ return true;
+ }
+ else if (recv_ctx.phase == Phase_Req_Mid) {
+ RECV_INTEGER(recv_ctx.message.request_mid, Phase_Req_Sender);
+ return true;
+ }
+ else if (recv_ctx.phase == Phase_Req_Sender) {
+ RECV_INTEGER(recv_ctx.message.request_sender, Phase_Req_Url_Len);
+ return true;
+ }
+ else if (recv_ctx.phase == Phase_Req_Url_Len) {
+ p = (uint8 *)&recv_ctx.message.request_url_len;
+
+ p[recv_ctx.size_in_phase++] = ch;
+ if (recv_ctx.size_in_phase
+ == sizeof(recv_ctx.message.request_url_len)) {
+ recv_ctx.message.request_url_len =
+ ntohs(recv_ctx.message.request_url_len);
+ recv_ctx.message.request_url =
+ APP_MGR_MALLOC(recv_ctx.message.request_url_len + 1);
+ if (NULL == recv_ctx.message.request_url) {
+ app_manager_printf("Allocate memory failed!\n");
+ SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
+ "Install WASM app failed: "
+ "allocate memory failed.");
+ goto fail;
+ }
+ memset(recv_ctx.message.request_url, 0,
+ recv_ctx.message.request_url_len + 1);
+ recv_ctx.phase = Phase_Req_Payload_Len;
+ recv_ctx.size_in_phase = 0;
+ }
+ return true;
+ }
+ else if (recv_ctx.phase == Phase_Req_Payload_Len) {
+ RECV_INTEGER(recv_ctx.message.wasm_app_size, Phase_Req_Url);
+ return true;
+ }
+ else if (recv_ctx.phase == Phase_Req_Url) {
+ recv_ctx.message.request_url[recv_ctx.size_in_phase++] = ch;
+ if (recv_ctx.size_in_phase == recv_ctx.message.request_url_len) {
+ recv_ctx.phase = Phase_App_Magic;
+ recv_ctx.size_in_phase = 0;
+ }
+ return true;
+ }
+ else if (recv_ctx.phase == Phase_App_Magic) {
+ /* start to receive wasm app magic: bytecode or aot */
+ p = (uint8 *)&recv_ctx.message.app_file_magic;
+
+ p[recv_ctx.size_in_phase++] = ch;
+
+ if (recv_ctx.size_in_phase == sizeof(recv_ctx.message.app_file_magic)) {
+ magic = recv_ctx.message.app_file_magic;
+ package_type = get_package_type((uint8 *)&magic, sizeof(magic) + 1);
+ switch (package_type) {
+#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
+ case Wasm_Module_Bytecode:
+ recv_ctx.message.app_file.u.bytecode.magic =
+ recv_ctx.message.app_file_magic;
+ recv_ctx.phase = Phase_Wasm_Version;
+ recv_ctx.size_in_phase = 0;
+ break;
+#endif
+#if WASM_ENABLE_AOT != 0
+ case Wasm_Module_AoT:
+ recv_ctx.message.app_file.u.aot.magic =
+ recv_ctx.message.app_file_magic;
+ recv_ctx.phase = Phase_AOT_Version;
+ recv_ctx.size_in_phase = 0;
+ break;
+#endif
+ default:
+ SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
+ "Install WASM app failed: "
+ "invalid file format.");
+ goto fail;
+ }
+ }
+ return true;
+ }
+#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
+ else if (recv_ctx.phase == Phase_Wasm_Version) {
+ p = (uint8 *)&recv_ctx.message.app_file.u.bytecode.version;
+
+ if (ch == wasm_bytecode_version[recv_ctx.size_in_phase])
+ p[recv_ctx.size_in_phase++] = ch;
+ else {
+ app_manager_printf("Invalid WASM version!\n");
+ SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
+ "Install WASM app failed: invalid WASM version.");
+ goto fail;
+ }
+
+ if (recv_ctx.size_in_phase
+ == sizeof(recv_ctx.message.app_file.u.bytecode.version)) {
+ recv_ctx.phase = Phase_Wasm_Section_Type;
+ recv_ctx.size_in_phase = 0;
+ }
+ return true;
+ }
+ else if (recv_ctx.phase == Phase_Wasm_Section_Type) {
+ uint8 section_type = ch;
+#if WASM_ENABLE_BULK_MEMORY == 0
+ uint8 section_type_max = SECTION_TYPE_DATA;
+#else
+ uint8 section_type_max = SECTION_TYPE_DATACOUNT;
+#endif
+ if (section_type <= section_type_max) {
+ wasm_section_t *new_section;
+ if (!(new_section = (wasm_section_t *)APP_MGR_MALLOC(
+ sizeof(wasm_section_t)))) {
+ app_manager_printf("Allocate memory failed!\n");
+ SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
+ "Install WASM app failed: "
+ "allocate memory failed.");
+ goto fail;
+ }
+ memset(new_section, 0, sizeof(wasm_section_t));
+ new_section->section_type = section_type;
+ new_section->next = NULL;
+
+ /* add the section to tail of link list */
+ if (NULL == recv_ctx.message.app_file.u.bytecode.sections) {
+ recv_ctx.message.app_file.u.bytecode.sections = new_section;
+ recv_ctx.message.app_file.u.bytecode.section_end = new_section;
+ }
+ else {
+ recv_ctx.message.app_file.u.bytecode.section_end->next =
+ new_section;
+ recv_ctx.message.app_file.u.bytecode.section_end = new_section;
+ }
+
+ recv_ctx.phase = Phase_Wasm_Section_Size;
+ recv_ctx.size_in_phase = 0;
+
+ return true;
+ }
+ else {
+ char error_buf[128];
+
+ app_manager_printf("Invalid wasm section type: %d\n", section_type);
+ snprintf(error_buf, sizeof(error_buf),
+ "Install WASM app failed: invalid wasm section type %d",
+ section_type);
+ SEND_ERR_RESPONSE(recv_ctx.message.request_mid, error_buf);
+ goto fail;
+ }
+ }
+ else if (recv_ctx.phase == Phase_Wasm_Section_Size) {
+ /* the last section is the current receiving one */
+ wasm_section_t *section =
+ recv_ctx.message.app_file.u.bytecode.section_end;
+ uint32 byte;
+
+ bh_assert(section);
+
+ byte = ch;
+
+ section->section_body_size |=
+ ((byte & 0x7f) << recv_ctx.size_in_phase * 7);
+ recv_ctx.size_in_phase++;
+ /* check leab128 overflow for uint32 value */
+ if (recv_ctx.size_in_phase
+ > (sizeof(section->section_body_size) * 8 + 7 - 1) / 7) {
+ app_manager_printf("LEB overflow when parsing section size\n");
+ SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
+ "Install WASM app failed: "
+ "LEB overflow when parsing section size");
+ goto fail;
+ }
+
+ if ((byte & 0x80) == 0) {
+ /* leb128 encoded section size parsed done */
+ if (!(section->section_body =
+ APP_MGR_MALLOC(section->section_body_size))) {
+ app_manager_printf("Allocate memory failed!\n");
+ SEND_ERR_RESPONSE(
+ recv_ctx.message.request_mid,
+ "Install WASM app failed: allocate memory failed");
+ goto fail;
+ }
+ recv_ctx.phase = Phase_Wasm_Section_Content;
+ recv_ctx.size_in_phase = 0;
+ }
+
+ return true;
+ }
+ else if (recv_ctx.phase == Phase_Wasm_Section_Content) {
+ /* the last section is the current receiving one */
+ wasm_section_t *section =
+ recv_ctx.message.app_file.u.bytecode.section_end;
+
+ bh_assert(section);
+
+ section->section_body[recv_ctx.size_in_phase++] = ch;
+
+ if (recv_ctx.size_in_phase == section->section_body_size) {
+ if (recv_ctx.total_received_size == request_total_size) {
+ /* whole wasm app received */
+ if (module_wasm_app_handle_install_msg(&recv_ctx.message)) {
+ APP_MGR_FREE(recv_ctx.message.request_url);
+ recv_ctx.message.request_url = NULL;
+ memset(&recv_ctx, 0, sizeof(recv_ctx));
+ return true;
+ }
+ else {
+ app_manager_printf("Handle install message failed!\n");
+ SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
+ "Install WASM app failed: "
+ "handle install message failed");
+ /**
+ * The sections were destroyed inside
+ * module_wasm_app_handle_install_msg(),
+ * no need to destroy again.
+ */
+ return false;
+ }
+ }
+ else {
+ recv_ctx.phase = Phase_Wasm_Section_Type;
+ recv_ctx.size_in_phase = 0;
+ return true;
+ }
+ }
+
+ return true;
+ }
+#endif /* end of WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0 */
+#if WASM_ENABLE_AOT != 0
+ else if (recv_ctx.phase == Phase_AOT_Version) {
+ p = (uint8 *)&recv_ctx.message.app_file.u.aot.version;
+
+ if (ch == wasm_aot_version[recv_ctx.size_in_phase])
+ p[recv_ctx.size_in_phase++] = ch;
+ else {
+ app_manager_printf("Invalid AOT version!\n");
+ SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
+ "Install WASM app failed: invalid AOT version");
+ goto fail;
+ }
+
+ if (recv_ctx.size_in_phase
+ == sizeof(recv_ctx.message.app_file.u.aot.version)) {
+ recv_ctx.phase = Phase_AOT_Section_ID;
+ recv_ctx.size_in_phase = 0;
+ }
+ return true;
+ }
+ else if (recv_ctx.phase == Phase_AOT_Section_ID) {
+ aot_section_t *cur_section;
+ uint32 aot_file_cur_offset =
+ recv_ctx.total_received_size - 1
+ - 18 /* Request fixed part */ - recv_ctx.message.request_url_len;
+
+ if (recv_ctx.size_in_phase == 0) {
+ /* Skip paddings */
+ if (aot_file_cur_offset % 4)
+ return true;
+
+ if (!(cur_section =
+ (aot_section_t *)APP_MGR_MALLOC(sizeof(aot_section_t)))) {
+ app_manager_printf("Allocate memory failed!\n");
+ SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
+ "Install WASM app failed: "
+ "allocate memory failed");
+ goto fail;
+ }
+ memset(cur_section, 0, sizeof(aot_section_t));
+
+ /* add the section to tail of link list */
+ if (NULL == recv_ctx.message.app_file.u.aot.sections) {
+ recv_ctx.message.app_file.u.aot.sections = cur_section;
+ recv_ctx.message.app_file.u.aot.section_end = cur_section;
+ }
+ else {
+ recv_ctx.message.app_file.u.aot.section_end->next = cur_section;
+ recv_ctx.message.app_file.u.aot.section_end = cur_section;
+ }
+ }
+ else {
+ cur_section = recv_ctx.message.app_file.u.aot.section_end;
+ bh_assert(cur_section);
+ }
+
+ p = (uint8 *)&cur_section->section_type;
+ p[recv_ctx.size_in_phase++] = ch;
+ if (recv_ctx.size_in_phase == sizeof(cur_section->section_type)) {
+ /* Notes: integers are always little endian encoded in AOT file */
+ if (!is_little_endian())
+ exchange_uint32(p);
+ if (cur_section->section_type < AOT_SECTION_TYPE_SIGANATURE
+ || cur_section->section_type == AOT_SECTION_TYPE_CUSTOM) {
+ recv_ctx.phase = Phase_AOT_Section_Size;
+ recv_ctx.size_in_phase = 0;
+ }
+ else {
+ char error_buf[128];
+
+ app_manager_printf("Invalid AOT section id: %d\n",
+ cur_section->section_type);
+ snprintf(error_buf, sizeof(error_buf),
+ "Install WASM app failed: invalid AOT section id %d",
+ cur_section->section_type);
+ SEND_ERR_RESPONSE(recv_ctx.message.request_mid, error_buf);
+ goto fail;
+ }
+ }
+
+ return true;
+ }
+ else if (recv_ctx.phase == Phase_AOT_Section_Size) {
+ /* the last section is the current receiving one */
+ aot_section_t *section = recv_ctx.message.app_file.u.aot.section_end;
+ bh_assert(section);
+
+ p = (uint8 *)&section->section_body_size;
+ p[recv_ctx.size_in_phase++] = ch;
+ if (recv_ctx.size_in_phase == sizeof(section->section_body_size)) {
+ /* Notes: integers are always little endian encoded in AOT file */
+ if (!is_little_endian())
+ exchange_uint32(p);
+ /* Allocate memory for section body */
+ if (section->section_body_size > 0) {
+ if (section->section_type == AOT_SECTION_TYPE_TEXT) {
+ int map_prot =
+ MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC;
+#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
+ || defined(BUILD_TARGET_RISCV64_LP64D) \
+ || defined(BUILD_TARGET_RISCV64_LP64)
+ /* aot code and data in x86_64 must be in range 0 to 2G due
+ to relocation for R_X86_64_32/32S/PC32 */
+ int map_flags = MMAP_MAP_32BIT;
+#else
+ int map_flags = MMAP_MAP_NONE;
+#endif
+ uint64 total_size = (uint64)section->section_body_size
+ + aot_get_plt_table_size();
+ total_size = (total_size + 3) & ~((uint64)3);
+ if (total_size >= UINT32_MAX
+ || !(section->section_body =
+ os_mmap(NULL, (uint32)total_size, map_prot,
+ map_flags))) {
+ app_manager_printf(
+ "Allocate executable memory failed!\n");
+ SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
+ "Install WASM app failed: "
+ "allocate memory failed");
+ goto fail;
+ }
+#if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)
+ /* address must be in the first 2 Gigabytes of
+ the process address space */
+ bh_assert((uintptr_t)section->section_body < INT32_MAX);
+#endif
+ }
+ else {
+ if (!(section->section_body =
+ APP_MGR_MALLOC(section->section_body_size))) {
+ app_manager_printf("Allocate memory failed!\n");
+ SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
+ "Install WASM app failed: "
+ "allocate memory failed");
+ goto fail;
+ }
+ }
+ }
+
+ recv_ctx.phase = Phase_AOT_Section_Content;
+ recv_ctx.size_in_phase = 0;
+ }
+
+ return true;
+ }
+ else if (recv_ctx.phase == Phase_AOT_Section_Content) {
+ /* the last section is the current receiving one */
+ aot_section_t *section = recv_ctx.message.app_file.u.aot.section_end;
+ bh_assert(section && section->section_body);
+
+ section->section_body[recv_ctx.size_in_phase++] = ch;
+
+ if (recv_ctx.size_in_phase == section->section_body_size) {
+ if (section->section_type == AOT_SECTION_TYPE_TEXT) {
+ uint32 total_size =
+ section->section_body_size + aot_get_plt_table_size();
+ total_size = (total_size + 3) & ~3;
+ if (total_size > section->section_body_size) {
+ memset(section->section_body + section->section_body_size,
+ 0, total_size - section->section_body_size);
+ section->section_body_size = total_size;
+ }
+ }
+ if (recv_ctx.total_received_size == request_total_size) {
+ /* whole aot file received */
+ if (module_wasm_app_handle_install_msg(&recv_ctx.message)) {
+ APP_MGR_FREE(recv_ctx.message.request_url);
+ recv_ctx.message.request_url = NULL;
+ memset(&recv_ctx, 0, sizeof(recv_ctx));
+ return true;
+ }
+ else {
+ app_manager_printf("Handle install message failed!\n");
+ SEND_ERR_RESPONSE(recv_ctx.message.request_mid,
+ "Install WASM app failed: "
+ "handle install message failed");
+ /**
+ * The sections were destroyed inside
+ * module_wasm_app_handle_install_msg(),
+ * no need to destroy again.
+ */
+ return false;
+ }
+ }
+ else {
+ recv_ctx.phase = Phase_AOT_Section_ID;
+ recv_ctx.size_in_phase = 0;
+ return true;
+ }
+ }
+
+ return true;
+ }
+#endif /* end of WASM_ENABLE_AOT != 0 */
+
+fail:
+ /* Restore the package type */
+ magic = recv_ctx.message.app_file_magic;
+ package_type = get_package_type((uint8 *)&magic, sizeof(magic) + 1);
+ switch (package_type) {
+#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
+ case Wasm_Module_Bytecode:
+ destroy_all_wasm_sections(
+ recv_ctx.message.app_file.u.bytecode.sections);
+ break;
+#endif
+#if WASM_ENABLE_AOT != 0
+ case Wasm_Module_AoT:
+ destroy_all_aot_sections(recv_ctx.message.app_file.u.aot.sections);
+ break;
+#endif
+ default:
+ break;
+ }
+
+ if (recv_ctx.message.request_url != NULL) {
+ APP_MGR_FREE(recv_ctx.message.request_url);
+ recv_ctx.message.request_url = NULL;
+ }
+
+ memset(&recv_ctx, 0, sizeof(recv_ctx));
+ return false;
+}
+
+static bool
+module_wasm_app_handle_install_msg(install_wasm_app_msg_t *message)
+{
+ request_t *request = NULL;
+ bh_message_t msg;
+
+ request = (request_t *)APP_MGR_MALLOC(sizeof(request_t));
+ if (request == NULL)
+ return false;
+
+ memset(request, 0, sizeof(*request));
+ request->action = message->request_action;
+ request->fmt = message->request_fmt;
+ request->url = bh_strdup(message->request_url);
+ request->sender = ID_HOST;
+ request->mid = message->request_mid;
+ request->payload_len = sizeof(message->app_file);
+ request->payload = APP_MGR_MALLOC(request->payload_len);
+
+ if (request->url == NULL || request->payload == NULL) {
+ request_cleaner(request);
+ return false;
+ }
+
+ /* Request payload is set to wasm_app_file_t struct,
+ * but not whole app buffer */
+ bh_memcpy_s(request->payload, request->payload_len, &message->app_file,
+ request->payload_len);
+
+ /* Since it's a wasm app install request, so directly post to app-mgr's
+ * queue. The benefit is that section list can be freed when the msg
+ * failed to post to app-mgr's queue. The defect is missing url check. */
+ if (!(msg = bh_new_msg(RESTFUL_REQUEST, request, sizeof(*request),
+ request_cleaner))) {
+ request_cleaner(request);
+ return false;
+ }
+
+ if (!bh_post_msg2(get_app_manager_queue(), msg))
+ return false;
+
+ return true;
+}
+
+#if WASM_ENABLE_INTERP != 0 || WASM_ENABLE_JIT != 0
+static void
+destroy_all_wasm_sections(wasm_section_list_t sections)
+{
+ wasm_section_t *cur = sections;
+ while (cur) {
+ wasm_section_t *next = cur->next;
+ if (cur->section_body != NULL)
+ APP_MGR_FREE(cur->section_body);
+ APP_MGR_FREE(cur);
+ cur = next;
+ }
+}
+
+static void
+destroy_part_wasm_sections(wasm_section_list_t *p_sections,
+ uint8 *section_types, int section_cnt)
+{
+ int i;
+ for (i = 0; i < section_cnt; i++) {
+ uint8 section_type = section_types[i];
+ wasm_section_t *cur = *p_sections, *prev = NULL;
+
+ while (cur) {
+ wasm_section_t *next = cur->next;
+ if (cur->section_type == section_type) {
+ if (prev)
+ prev->next = next;
+ else
+ *p_sections = next;
+
+ if (cur->section_body != NULL)
+ APP_MGR_FREE(cur->section_body);
+ APP_MGR_FREE(cur);
+ break;
+ }
+ else {
+ prev = cur;
+ cur = next;
+ }
+ }
+ }
+}
+#endif
+
+#if WASM_ENABLE_AOT != 0
+static void
+destroy_all_aot_sections(aot_section_list_t sections)
+{
+ aot_section_t *cur = sections;
+ while (cur) {
+ aot_section_t *next = cur->next;
+ if (cur->section_body != NULL) {
+ if (cur->section_type == AOT_SECTION_TYPE_TEXT)
+ os_munmap(cur->section_body, cur->section_body_size);
+ else
+ APP_MGR_FREE(cur->section_body);
+ }
+ APP_MGR_FREE(cur);
+ cur = next;
+ }
+}
+
+static void
+destroy_part_aot_sections(aot_section_list_t *p_sections, uint8 *section_types,
+ int section_cnt)
+{
+ int i;
+ for (i = 0; i < section_cnt; i++) {
+ uint8 section_type = section_types[i];
+ aot_section_t *cur = *p_sections, *prev = NULL;
+
+ while (cur) {
+ aot_section_t *next = cur->next;
+ if (cur->section_type == section_type) {
+ if (prev)
+ prev->next = next;
+ else
+ *p_sections = next;
+
+ if (cur->section_body != NULL) {
+ if (cur->section_type == AOT_SECTION_TYPE_TEXT)
+ os_munmap(cur->section_body, cur->section_body_size);
+ else
+ APP_MGR_FREE(cur->section_body);
+ }
+ APP_MGR_FREE(cur);
+ break;
+ }
+ else {
+ prev = cur;
+ cur = next;
+ }
+ }
+ }
+}
+#endif
+
+#if WASM_ENABLE_LIBC_WASI != 0
+static char wasi_root_dir[PATH_MAX] = { '.' };
+
+bool
+wasm_set_wasi_root_dir(const char *root_dir)
+{
+ char *path, resolved_path[PATH_MAX];
+
+ if (!(path = realpath(root_dir, resolved_path)))
+ return false;
+
+ snprintf(wasi_root_dir, sizeof(wasi_root_dir), "%s", path);
+ return true;
+}
+
+const char *
+wasm_get_wasi_root_dir()
+{
+ return wasi_root_dir;
+}
+#endif
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_wasm_app.h b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_wasm_app.h
new file mode 100644
index 000000000..8a7ae4e54
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_wasm_app.h
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifndef _MODULE_WASM_APP_H_
+#define _MODULE_WASM_APP_H_
+
+#include "bh_queue.h"
+#include "app_manager_export.h"
+#include "wasm_export.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define SECTION_TYPE_USER 0
+#define SECTION_TYPE_TYPE 1
+#define SECTION_TYPE_IMPORT 2
+#define SECTION_TYPE_FUNC 3
+#define SECTION_TYPE_TABLE 4
+#define SECTION_TYPE_MEMORY 5
+#define SECTION_TYPE_GLOBAL 6
+#define SECTION_TYPE_EXPORT 7
+#define SECTION_TYPE_START 8
+#define SECTION_TYPE_ELEM 9
+#define SECTION_TYPE_CODE 10
+#define SECTION_TYPE_DATA 11
+
+typedef enum AOTSectionType {
+ AOT_SECTION_TYPE_TARGET_INFO = 0,
+ AOT_SECTION_TYPE_INIT_DATA = 1,
+ AOT_SECTION_TYPE_TEXT = 2,
+ AOT_SECTION_TYPE_FUNCTION = 3,
+ AOT_SECTION_TYPE_EXPORT = 4,
+ AOT_SECTION_TYPE_RELOCATION = 5,
+ AOT_SECTION_TYPE_SIGANATURE = 6,
+ AOT_SECTION_TYPE_CUSTOM = 100,
+} AOTSectionType;
+
+enum {
+ WASM_Msg_Start = BASE_EVENT_MAX,
+ TIMER_EVENT_WASM,
+ SENSOR_EVENT_WASM,
+ CONNECTION_EVENT_WASM,
+ WIDGET_EVENT_WASM,
+ WASM_Msg_End = WASM_Msg_Start + 100
+};
+
+typedef struct wasm_data {
+ /* for easily access the containing wasm module */
+ wasm_module_t wasm_module;
+ wasm_module_inst_t wasm_module_inst;
+ /* Permissions of the WASM app */
+ char *perms;
+ /* thread list mapped with this WASM module */
+ korp_tid thread_id;
+ /* for easily access the containing module data */
+ module_data *m_data;
+ /* is bytecode or aot */
+ bool is_bytecode;
+ /* sections of wasm bytecode or aot file */
+ void *sections;
+ /* execution environment */
+ wasm_exec_env_t exec_env;
+} wasm_data;
+
+/* sensor event */
+typedef struct _sensor_event_data {
+ uint32 sensor_id;
+
+ int data_fmt;
+ /* event of attribute container from context core */
+ void *data;
+} sensor_event_data_t;
+
+/* WASM Bytecode File */
+typedef struct wasm_bytecode_file {
+ /* magics */
+ int magic;
+ /* current version */
+ int version;
+ /* WASM section list */
+ wasm_section_list_t sections;
+ /* Last WASM section in the list */
+ wasm_section_t *section_end;
+} wasm_bytecode_file_t;
+
+/* WASM AOT File */
+typedef struct wasm_aot_file {
+ /* magics */
+ int magic;
+ /* current version */
+ int version;
+ /* AOT section list */
+ aot_section_list_t sections;
+ /* Last AOT section in the list */
+ aot_section_t *section_end;
+} wasm_aot_file_t;
+
+/* WASM App File */
+typedef struct wasm_app_file_t {
+ union {
+ wasm_bytecode_file_t bytecode;
+ wasm_aot_file_t aot;
+ } u;
+} wasm_app_file_t;
+
+extern module_interface wasm_app_module_interface;
+
+typedef void (*message_type_handler_t)(module_data *m_data, bh_message_t msg);
+extern bool
+wasm_register_msg_callback(int msg_type,
+ message_type_handler_t message_handler);
+
+typedef void (*resource_cleanup_handler_t)(uint32 module_id);
+extern bool
+wasm_register_cleanup_callback(resource_cleanup_handler_t handler);
+
+/**
+ * Set WASI root dir for modules. On each wasm app installation, a sub dir named
+ * with the app's name will be created autamically. That wasm app can only
+ * access this sub dir.
+ *
+ * @param root_dir the root dir to set
+ * @return true for success, false otherwise
+ */
+bool
+wasm_set_wasi_root_dir(const char *root_dir);
+
+/**
+ * Get WASI root dir
+ *
+ * @return the WASI root dir
+ */
+const char *
+wasm_get_wasi_root_dir();
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif /* _MODULE_WASM_APP_H_ */
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_wasm_lib.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_wasm_lib.c
new file mode 100644
index 000000000..0b5c07ea7
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_wasm_lib.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include "module_wasm_lib.h"
+
+static bool
+wasm_lib_module_init(void)
+{
+ return false;
+}
+
+static bool
+wasm_lib_module_install(request_t *msg)
+{
+ (void)msg;
+ return false;
+}
+
+static bool
+wasm_lib_module_uninstall(request_t *msg)
+{
+ (void)msg;
+ return false;
+}
+
+static void
+wasm_lib_module_watchdog_kill(module_data *m_data)
+{
+ (void)m_data;
+}
+
+static bool
+wasm_lib_module_handle_host_url(void *queue_msg)
+{
+ (void)queue_msg;
+ return false;
+}
+
+static module_data *
+wasm_lib_module_get_module_data(void *inst)
+{
+ (void)inst;
+ return NULL;
+}
+
+/* clang-format off */
+module_interface wasm_lib_module_interface = {
+ wasm_lib_module_init,
+ wasm_lib_module_install,
+ wasm_lib_module_uninstall,
+ wasm_lib_module_watchdog_kill,
+ wasm_lib_module_handle_host_url,
+ wasm_lib_module_get_module_data,
+ NULL
+};
+/* clang-format on */
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_wasm_lib.h b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_wasm_lib.h
new file mode 100644
index 000000000..63ffd92b5
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/module_wasm_lib.h
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifndef _MODULE_WASM_LIB_H_
+#define _MODULE_WASM_LIB_H_
+
+#include "app_manager.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern module_interface wasm_lib_module_interface;
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif /* _MODULE_WASM_LIB_H_ */
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/platform/darwin/app_mgr_darwin.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/platform/darwin/app_mgr_darwin.c
new file mode 100644
index 000000000..1c7409f55
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/platform/darwin/app_mgr_darwin.c
@@ -0,0 +1 @@
+#include "../linux/app_mgr_linux.c"
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/platform/linux/app_mgr_linux.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/platform/linux/app_mgr_linux.c
new file mode 100644
index 000000000..5e51788bc
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/platform/linux/app_mgr_linux.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include "app_manager.h"
+
+void *
+app_manager_timer_create(void (*timer_callback)(void *),
+ watchdog_timer *wd_timer)
+{
+ /* TODO */
+ return NULL;
+}
+
+void
+app_manager_timer_destroy(void *timer)
+{
+ /* TODO */
+}
+
+void
+app_manager_timer_start(void *timer, int timeout)
+{
+ /* TODO */
+}
+
+void
+app_manager_timer_stop(void *timer)
+{
+ /* TODO */
+}
+
+watchdog_timer *
+app_manager_get_wd_timer_from_timer_handle(void *timer)
+{
+ /* TODO */
+ return NULL;
+}
+
+int
+app_manager_signature_verify(const uint8_t *file, unsigned int file_len,
+ const uint8_t *signature, unsigned int sig_size)
+{
+ return 1;
+}
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/platform/zephyr/app_mgr_zephyr.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/platform/zephyr/app_mgr_zephyr.c
new file mode 100644
index 000000000..650e536f1
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/platform/zephyr/app_mgr_zephyr.c
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include "app_manager.h"
+#include "bh_platform.h"
+#include <autoconf.h>
+#include <zephyr.h>
+#include <kernel.h>
+#if 0
+#include <sigverify.h>
+#endif
+typedef struct k_timer_watchdog {
+ struct k_timer timer;
+ watchdog_timer *wd_timer;
+} k_timer_watchdog;
+
+void *
+app_manager_timer_create(void (*timer_callback)(void *),
+ watchdog_timer *wd_timer)
+{
+ struct k_timer_watchdog *timer =
+ APP_MGR_MALLOC(sizeof(struct k_timer_watchdog));
+
+ if (timer) {
+ k_timer_init(&timer->timer, (void (*)(struct k_timer *))timer_callback,
+ NULL);
+ timer->wd_timer = wd_timer;
+ }
+
+ return timer;
+}
+
+void
+app_manager_timer_destroy(void *timer)
+{
+ APP_MGR_FREE(timer);
+}
+
+void
+app_manager_timer_start(void *timer, int timeout)
+{
+ k_timer_start(timer, Z_TIMEOUT_MS(timeout), Z_TIMEOUT_MS(0));
+}
+
+void
+app_manager_timer_stop(void *timer)
+{
+ k_timer_stop(timer);
+}
+
+watchdog_timer *
+app_manager_get_wd_timer_from_timer_handle(void *timer)
+{
+ return ((k_timer_watchdog *)timer)->wd_timer;
+}
+#if 0
+int app_manager_signature_verify(const uint8_t *file, unsigned int file_len,
+ const uint8_t *signature, unsigned int sig_size)
+{
+ return signature_verify(file, file_len, signature, sig_size);
+}
+#endif
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/resource_reg.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/resource_reg.c
new file mode 100644
index 000000000..4e930890e
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/resource_reg.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include "native_interface.h"
+#include "app_manager.h"
+#include "app_manager_export.h"
+#include "bi-inc/shared_utils.h"
+#include "bi-inc/attr_container.h"
+#include "coap_ext.h"
+
+typedef struct _app_res_register {
+ struct _app_res_register *next;
+ char *url;
+ void (*request_handler)(request_t *, void *);
+ uint32 register_id;
+} app_res_register_t;
+
+static app_res_register_t *g_resources = NULL;
+
+void
+module_request_handler(request_t *request, void *user_data)
+{
+ unsigned int mod_id = (unsigned int)(uintptr_t)user_data;
+ bh_message_t msg;
+ module_data *m_data;
+ request_t *req;
+
+ /* Check module name */
+ m_data = module_data_list_lookup_id(mod_id);
+ if (!m_data) {
+ return;
+ }
+
+ if (m_data->wd_timer.is_interrupting) {
+ return;
+ }
+
+ req = clone_request(request);
+ if (!req) {
+ return;
+ }
+
+ /* Set queue message and send to applet's queue */
+ msg = bh_new_msg(RESTFUL_REQUEST, req, sizeof(*req), request_cleaner);
+ if (!msg) {
+ request_cleaner(req);
+ return;
+ }
+
+ if (!bh_post_msg2(m_data->queue, msg)) {
+ return;
+ }
+
+ app_manager_printf("Send request to app %s success.\n",
+ m_data->module_name);
+}
+
+void
+targeted_app_request_handler(request_t *request, void *unused)
+{
+ char applet_name[128] = { 0 };
+ int offset;
+ char *url = request->url;
+ module_data *m_data;
+
+ offset = check_url_start(request->url, strlen(request->url), "/app/");
+
+ if (offset <= 0) {
+ return;
+ }
+
+ strncpy(applet_name, request->url + offset, sizeof(applet_name) - 1);
+ char *p = strchr(applet_name, '/');
+ if (p) {
+ *p = 0;
+ }
+ else
+ return;
+ app_manager_printf("Send request to applet: %s\n", applet_name);
+
+ request->url = p + 1;
+
+ /* Check module name */
+ m_data = module_data_list_lookup(applet_name);
+ if (!m_data) {
+ SEND_ERR_RESPONSE(request->mid,
+ "Send request to applet failed: invalid applet name");
+ goto end;
+ }
+
+ module_request_handler(request, (void *)(uintptr_t)m_data->id);
+end:
+ request->url = url;
+}
+
+void
+am_send_response(response_t *response)
+{
+ module_data *m_data;
+
+ // if the receiver is not any of modules, just forward it to the host
+ m_data = module_data_list_lookup_id(response->reciever);
+ if (!m_data) {
+ send_response_to_host(response);
+ }
+ else {
+ response_t *resp_for_send = clone_response(response);
+ if (!resp_for_send) {
+ return;
+ }
+
+ bh_message_t msg = bh_new_msg(RESTFUL_RESPONSE, resp_for_send,
+ sizeof(*resp_for_send), response_cleaner);
+ if (!msg) {
+ response_cleaner(resp_for_send);
+ return;
+ }
+
+ if (!bh_post_msg2(m_data->queue, msg)) {
+ return;
+ }
+ }
+}
+
+void *
+am_dispatch_request(request_t *request)
+{
+ app_res_register_t *r = g_resources;
+
+ while (r) {
+ if (check_url_start(request->url, strlen(request->url), r->url) > 0) {
+ r->request_handler(request, (void *)(uintptr_t)r->register_id);
+ return r;
+ }
+ r = r->next;
+ }
+ return NULL;
+}
+
+bool
+am_register_resource(const char *url,
+ void (*request_handler)(request_t *, void *),
+ uint32 register_id)
+{
+ app_res_register_t *r = g_resources;
+ int register_num = 0;
+
+ while (r) {
+ if (strcmp(r->url, url) == 0) {
+ return false;
+ }
+
+ if (r->register_id == register_id)
+ register_num++;
+
+ r = r->next;
+ }
+
+ if (strlen(url) > RESOUCE_EVENT_URL_LEN_MAX)
+ return false;
+
+ if (register_num >= RESOURCE_REGISTRATION_NUM_MAX)
+ return false;
+
+ r = (app_res_register_t *)APP_MGR_MALLOC(sizeof(app_res_register_t));
+ if (r == NULL)
+ return false;
+
+ memset(r, 0, sizeof(*r));
+ r->url = bh_strdup(url);
+ if (r->url == NULL) {
+ APP_MGR_FREE(r);
+ return false;
+ }
+
+ r->request_handler = request_handler;
+ r->next = g_resources;
+ r->register_id = register_id;
+ g_resources = r;
+
+ return true;
+}
+
+void
+am_cleanup_registeration(uint32 register_id)
+{
+ app_res_register_t *r = g_resources;
+ app_res_register_t *prev = NULL;
+
+ while (r) {
+ app_res_register_t *next = r->next;
+
+ if (register_id == r->register_id) {
+ if (prev)
+ prev->next = next;
+ else
+ g_resources = next;
+
+ APP_MGR_FREE(r->url);
+ APP_MGR_FREE(r);
+ }
+ else
+ /* if r is freed, should not change prev. Only set prev to r
+ when r isn't freed. */
+ prev = r;
+
+ r = next;
+ }
+}
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/watchdog.c b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/watchdog.c
new file mode 100644
index 000000000..ba5bb05f5
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/watchdog.c
@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include "watchdog.h"
+#include "bh_platform.h"
+
+#define WATCHDOG_THREAD_PRIORITY 5
+
+/* Queue of watchdog */
+static bh_queue *watchdog_queue;
+
+#ifdef WATCHDOG_ENABLED /* TODO */
+static void
+watchdog_timer_callback(void *timer)
+{
+ watchdog_timer *wd_timer =
+ app_manager_get_wd_timer_from_timer_handle(timer);
+
+ watchdog_timer_stop(wd_timer);
+
+ os_mutex_lock(&wd_timer->lock);
+
+ if (!wd_timer->is_stopped) {
+
+ wd_timer->is_interrupting = true;
+
+ bh_post_msg(watchdog_queue, WD_TIMEOUT, wd_timer->module_data,
+ sizeof(module_data));
+ }
+
+ os_mutex_unlock(&wd_timer->lock);
+}
+#endif
+
+bool
+watchdog_timer_init(module_data *m_data)
+{
+#ifdef WATCHDOG_ENABLED /* TODO */
+ watchdog_timer *wd_timer = &m_data->wd_timer;
+
+ if (0 != os_mutex_init(&wd_timer->lock))
+ return false;
+
+ if (!(wd_timer->timer_handle =
+ app_manager_timer_create(watchdog_timer_callback, wd_timer))) {
+ os_mutex_destroy(&wd_timer->lock);
+ return false;
+ }
+
+ wd_timer->module_data = m_data;
+ wd_timer->is_interrupting = false;
+ wd_timer->is_stopped = false;
+#endif
+ return true;
+}
+
+void
+watchdog_timer_destroy(watchdog_timer *wd_timer)
+{
+#ifdef WATCHDOG_ENABLED /* TODO */
+ app_manager_timer_destroy(wd_timer->timer_handle);
+ os_mutex_destroy(&wd_timer->lock);
+#endif
+}
+
+void
+watchdog_timer_start(watchdog_timer *wd_timer)
+{
+ os_mutex_lock(&wd_timer->lock);
+
+ wd_timer->is_interrupting = false;
+ wd_timer->is_stopped = false;
+ app_manager_timer_start(wd_timer->timer_handle,
+ wd_timer->module_data->timeout);
+
+ os_mutex_unlock(&wd_timer->lock);
+}
+
+void
+watchdog_timer_stop(watchdog_timer *wd_timer)
+{
+ app_manager_timer_stop(wd_timer->timer_handle);
+}
+
+#ifdef WATCHDOG_ENABLED /* TODO */
+static void
+watchdog_queue_callback(void *queue_msg)
+{
+ if (bh_message_type(queue_msg) == WD_TIMEOUT) {
+ module_data *m_data = (module_data *)bh_message_payload(queue_msg);
+ if (g_module_interfaces[m_data->module_type]
+ && g_module_interfaces[m_data->module_type]->module_watchdog_kill) {
+ g_module_interfaces[m_data->module_type]->module_watchdog_kill(
+ m_data);
+ app_manager_post_applets_update_event();
+ }
+ }
+}
+#endif
+
+#ifdef WATCHDOG_ENABLED /* TODO */
+static void *
+watchdog_thread_routine(void *arg)
+{
+ /* Enter loop run */
+ bh_queue_enter_loop_run(watchdog_queue, watchdog_queue_callback);
+
+ (void)arg;
+ return NULL;
+}
+#endif
+
+bool
+watchdog_startup()
+{
+ if (!(watchdog_queue = bh_queue_create())) {
+ app_manager_printf(
+ "App Manager start failed: create watchdog queue failed.\n");
+ return false;
+ }
+#if 0
+//todo: enable watchdog
+ /* Start watchdog thread */
+ if (!jeff_runtime_create_supervisor_thread_with_prio(watchdog_thread_routine, NULL,
+ WATCHDOG_THREAD_PRIORITY)) {
+ bh_queue_destroy(watchdog_queue);
+ return false;
+ }
+#endif
+ return true;
+}
+
+void
+watchdog_destroy()
+{
+ bh_queue_exit_loop_run(watchdog_queue);
+ bh_queue_destroy(watchdog_queue);
+}
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/watchdog.h b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/watchdog.h
new file mode 100644
index 000000000..d960df03b
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/watchdog.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifndef _WATCHDOG_H_
+#define _WATCHDOG_H_
+
+#include "app_manager.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+bool
+watchdog_timer_init(module_data *module_data);
+
+void
+watchdog_timer_destroy(watchdog_timer *wd_timer);
+
+void
+watchdog_timer_start(watchdog_timer *wd_timer);
+
+void
+watchdog_timer_stop(watchdog_timer *wd_timer);
+
+watchdog_timer *
+app_manager_get_watchdog_timer(void *timer);
+
+bool
+watchdog_startup();
+
+void
+watchdog_destroy();
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif /* _WATCHDOG_H_ */
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-mgr-shared/app_manager_export.h b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-mgr-shared/app_manager_export.h
new file mode 100644
index 000000000..54b59b944
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-mgr-shared/app_manager_export.h
@@ -0,0 +1,307 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifndef _APP_MANAGER_EXPORT_H_
+#define _APP_MANAGER_EXPORT_H_
+
+#include "native_interface.h"
+#include "bi-inc/shared_utils.h"
+#include "bh_queue.h"
+#include "host_link.h"
+#include "runtime_timer.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Special module IDs */
+#define ID_HOST -3
+#define ID_APP_MGR -2
+/* Invalid module ID */
+#define ID_NONE ((uint32)-1)
+
+struct attr_container;
+
+/* Queue message type */
+typedef enum QUEUE_MSG_TYPE {
+ COAP_PARSED = LINK_MSG_TYPE_MAX + 1,
+ RESTFUL_REQUEST,
+ RESTFUL_RESPONSE,
+ TIMER_EVENT = 5,
+ SENSOR_EVENT = 6,
+ GPIO_INTERRUPT_EVENT = 7,
+ BLE_EVENT = 8,
+ JDWP_REQUEST = 9,
+ WD_TIMEOUT = 10,
+ BASE_EVENT_MAX = 100
+
+} QUEUE_MSG_TYPE;
+
+typedef enum {
+ Module_Jeff,
+ Module_WASM_App,
+ Module_WASM_Lib,
+ Module_Max
+} Module_Type;
+
+struct module_data;
+
+/* Watchdog timer of module */
+typedef struct watchdog_timer {
+ /* Timer handle of the platform */
+ void *timer_handle;
+ /* Module of the watchdog timer */
+ struct module_data *module_data;
+ /* Lock of the watchdog timer */
+ korp_mutex lock;
+ /* Flag indicates module is being interrupted by watchdog */
+ bool is_interrupting;
+ /* Flag indicates watchdog timer is stopped */
+ bool is_stopped;
+} watchdog_timer;
+
+typedef struct module_data {
+ struct module_data *next;
+
+ /* ID of the module */
+ uint32 id;
+
+ /* Type of the module */
+ Module_Type module_type;
+
+ /* Heap of the module */
+ void *heap;
+
+ /* Heap size of the module */
+ int heap_size;
+
+ /* Module execution timeout in millisecond */
+ int timeout;
+
+ /* Queue of the module */
+ bh_queue *queue;
+
+ /* Watchdog timer of the module*/
+ struct watchdog_timer wd_timer;
+
+ timer_ctx_t timer_ctx;
+
+ /* max timers number app can create */
+ int timers;
+
+ /* Internal data of the module */
+ void *internal_data;
+
+ /* Module name */
+ char module_name[1];
+} module_data;
+
+/* Module function types */
+typedef bool (*module_init_func)(void);
+typedef bool (*module_install_func)(request_t *msg);
+typedef bool (*module_uninstall_func)(request_t *msg);
+typedef void (*module_watchdog_kill_func)(module_data *module_data);
+typedef bool (*module_handle_host_url_func)(void *queue_msg);
+typedef module_data *(*module_get_module_data_func)(void *inst);
+
+/**
+ * @typedef module_on_install_request_byte_arrive_func
+ *
+ * @brief Define the signature of function to handle one byte of
+ * module app install request for struct module_interface.
+ *
+ * @param ch the byte to be received and handled
+ * @param total_size total size of the request
+ * @param received_total_size currently received total size when
+ * the function return
+ *
+ * @return true if success, false otherwise
+ */
+typedef bool (*module_on_install_request_byte_arrive_func)(
+ uint8 ch, int total_size, int *received_total_size);
+
+/* Interfaces of each module */
+typedef struct module_interface {
+ module_init_func module_init;
+ module_install_func module_install;
+ module_uninstall_func module_uninstall;
+ module_watchdog_kill_func module_watchdog_kill;
+ module_handle_host_url_func module_handle_host_url;
+ module_get_module_data_func module_get_module_data;
+ module_on_install_request_byte_arrive_func module_on_install;
+} module_interface;
+
+/**
+ * @typedef host_init_func
+ * @brief Define the host initialize callback function signature for
+ * struct host_interface.
+ *
+ * @return true if success, false if fail
+ */
+typedef bool (*host_init_func)(void);
+
+/**
+ * @typedef host_send_fun
+ * @brief Define the host send callback function signature for
+ * struct host_interface.
+ *
+ * @param buf data buffer to send.
+ * @param size size of the data to send.
+ *
+ * @return size of the data sent in bytes
+ */
+typedef int (*host_send_fun)(void *ctx, const char *buf, int size);
+
+/**
+ * @typedef host_destroy_fun
+ * @brief Define the host receive callback function signature for
+ * struct host_interface.
+ *
+ */
+typedef void (*host_destroy_fun)();
+
+/* Interfaces of host communication */
+typedef struct host_interface {
+ host_init_func init;
+ host_send_fun send;
+ host_destroy_fun destroy;
+} host_interface;
+
+/**
+ * Initialize communication with Host
+ *
+ * @param interface host communication interface
+ *
+ * @return true if success, false otherwise
+ */
+bool
+app_manager_host_init(host_interface *intf);
+
+/* Startup app manager */
+void
+app_manager_startup(host_interface *intf);
+
+/* Return whether app manager is started */
+bool
+app_manager_is_started(void);
+
+/* Get queue of current applet */
+void *
+app_manager_get_module_queue(uint32 module_type, void *module_inst);
+
+/* Get applet name of current applet */
+const char *
+app_manager_get_module_name(uint32 module_type, void *module_inst);
+
+/* Get heap of current applet */
+void *
+app_manager_get_module_heap(uint32 module_type, void *module_inst);
+
+void *
+get_app_manager_queue();
+
+module_data *
+app_manager_get_module_data(uint32 module_type, void *module_inst);
+
+unsigned int
+app_manager_get_module_id(uint32 module_type, void *module_inst);
+
+module_data *
+app_manager_lookup_module_data(const char *name);
+
+module_data *
+module_data_list_lookup(const char *module_name);
+
+module_data *
+module_data_list_lookup_id(unsigned int module_id);
+
+void
+app_manager_post_applets_update_event();
+
+bool
+am_register_resource(const char *url,
+ void (*request_handler)(request_t *, void *),
+ uint32 register_id);
+
+void
+am_cleanup_registeration(uint32 register_id);
+
+bool
+am_register_event(const char *url, uint32_t reg_client);
+
+bool
+am_unregister_event(const char *url, uint32_t reg_client);
+
+void
+am_publish_event(request_t *event);
+
+void *
+am_dispatch_request(request_t *request);
+
+void
+am_send_response(response_t *response);
+
+void
+module_request_handler(request_t *request, void *user_data);
+
+/**
+ * Send request message to host
+ *
+ * @param msg the request or event message.
+ * It is event when msg->action==COAP_EVENT
+ *
+ * @return true if success, false otherwise
+ */
+bool
+send_request_to_host(request_t *msg);
+
+/**
+ * Send response message to host
+ *
+ * @param msg the response message
+ *
+ * @return true if success, false otherwise
+ */
+bool
+send_response_to_host(response_t *msg);
+
+/**
+ * Send response with mid and code to host
+ *
+ * @param mid the message id of response
+ * @param code the code/status of response
+ * @param msg the detailed message
+ *
+ * @return true if success, false otherwise
+ */
+bool
+send_error_response_to_host(int mid, int code, const char *msg);
+
+/**
+ * Check whether the applet has the permission
+ *
+ * @param perm the permission needed to check
+ *
+ * @return true if success, false otherwise
+ */
+bool
+bh_applet_check_permission(const char *perm);
+
+/**
+ * Send message to Host
+ *
+ * @param buf buffer to send
+ * @param size size of buffer
+ *
+ * @return size of buffer sent
+ */
+int
+app_manager_host_send_msg(int msg_type, const char *buf, int size);
+
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
+
+#endif
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-mgr-shared/app_mgr_shared.cmake b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-mgr-shared/app_mgr_shared.cmake
new file mode 100644
index 000000000..f370e8b29
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-mgr-shared/app_mgr_shared.cmake
@@ -0,0 +1,16 @@
+# Copyright (C) 2019 Intel Corporation. All rights reserved.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+set (APP_MGR_SHARED_DIR ${CMAKE_CURRENT_LIST_DIR})
+
+include_directories(${APP_MGR_SHARED_DIR})
+
+
+file (GLOB_RECURSE source_all ${APP_MGR_SHARED_DIR}/*.c)
+
+set (APP_MGR_SHARED_SOURCE ${source_all})
+
+file (GLOB header
+ ${APP_MGR_SHARED_DIR}/*.h
+)
+LIST (APPEND RUNTIME_LIB_HEADER_LIST ${header})
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-mgr-shared/host_link.h b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-mgr-shared/host_link.h
new file mode 100644
index 000000000..e3a37fb40
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-mgr-shared/host_link.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 Intel Corporation. All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#ifndef DEPS_APP_MGR_APP_MGR_SHARED_HOST_LINK_H_
+#define DEPS_APP_MGR_APP_MGR_SHARED_HOST_LINK_H_
+
+typedef enum LINK_MSG_TYPE {
+ COAP_TCP_RAW = 0,
+ COAP_UDP_RAW = 1,
+ REQUEST_PACKET,
+ RESPONSE_PACKET,
+ INSTALL_WASM_APP,
+ CBOR_GENERIC = 30,
+
+ LINK_MSG_TYPE_MAX = 50
+} LINK_MSG_TYPE;
+
+/* Link message, or message between host and app manager */
+typedef struct bh_link_msg_t {
+ /* 2 bytes leading */
+ uint16_t leading_bytes;
+ /* message type, must be COAP_TCP or COAP_UDP */
+ uint16_t message_type;
+ /* size of payload */
+ uint32_t payload_size;
+ char *payload;
+} bh_link_msg_t;
+
+#endif /* DEPS_APP_MGR_APP_MGR_SHARED_HOST_LINK_H_ */
diff --git a/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/module.json b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/module.json
new file mode 100644
index 000000000..b2faeca5f
--- /dev/null
+++ b/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/module.json
@@ -0,0 +1,52 @@
+{
+ "name": "aee",
+ "version": "0.0.1",
+ "description": "aee",
+ "type": "source",
+ "category": "middleware",
+ "arch": "x86, arc, posix",
+ "includes": [
+ "Beihai/classlib/include",
+ "Beihai/runtime/include",
+ "Beihai/runtime/platform/include",
+ "Beihai/runtime/platform/zephyr",
+ "Beihai/runtime/utils/coap/er-coap",
+ "Beihai/runtime/utils/coap/extension",
+ "iwasm/runtime/include",
+ "iwasm/runtime/platform/include",
+ "iwasm/runtime/platform/zephyr",
+ "iwasm/runtime/vmcore_wasm"
+ ],
+ "sources": [
+ "Beihai/classlib/native/internal/*.c",
+ "Beihai/classlib/native/*.c",
+ "Beihai/runtime/gc/*.c",
+ "Beihai/runtime/platform/zephyr/*.c",
+ "Beihai/runtime/utils/*.c",
+ "Beihai/runtime/utils/coap/er-coap/*.c",
+ "Beihai/runtime/utils/coap/extension/*.c",
+ "Beihai/runtime/vmcore_jeff/*.c",
+ "app-manager/app-manager.c",
+ "app-manager/app-manager-host.c",
+ "app-manager/app_mgr_zephyr.c",
+ "app-manager/event.c",
+ "app-manager/message.c",
+ "app-manager/module_jeff.c",
+ "app-manager/module_wasm_lib.c",
+ "app-manager/module_wasm_app.c",
+ "app-manager/watchdog.c",
+ "Beihai/products/iMRT/*.c",
+ "iwasm/runtime/utils/*.c",
+ "iwasm/runtime/platform/zephyr/*.c",
+ "iwasm/runtime/vmcore_wasm/*.c",
+ "iwasm/lib/lib-export\.c",
+ "iwasm/lib/aee/*.c",
+ "iwasm/products/zephyr/sample/src/*.c"
+ ],
+ "compile_definitions": [
+ "__JLF__",
+ "__ZEPHYR__"
+ ],
+ "target": "aee",
+ "dependencies": []
+}