summaryrefslogtreecommitdiffstats
path: root/fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_manager_host.c
diff options
context:
space:
mode:
Diffstat (limited to 'fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_manager_host.c')
-rw-r--r--fluent-bit/lib/wasm-micro-runtime-WAMR-1.2.2/core/app-mgr/app-manager/app_manager_host.c324
1 files changed, 324 insertions, 0 deletions
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;
+}