Import app manager, samples and test-tools

This commit is contained in:
wenyongh
2019-05-17 17:15:25 +08:00
parent b6e29e2153
commit dd5b133fa5
164 changed files with 21123 additions and 496 deletions

View File

@ -0,0 +1,28 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
include_directories (.
include
platform/include
platform/${PLATFORM}
../classlib/include
utils/coap/er-coap
utils/coap/extension
../external/iwasm/include)
file (GLOB_RECURSE source_all ../../app-manager/*.c)
add_library (appmgrlib ${source_all})

View File

@ -0,0 +1,406 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "app_manager.h"
#include "app_manager_host.h"
#include "bh_queue.h"
#include "bh_memory.h"
#include "bh_thread.h"
#include "attr_container.h"
#include "event.h"
#include "watchdog.h"
#include "coap_ext.h"
/* Queue of app manager */
static bh_queue *g_app_mgr_queue;
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;
}
vm_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: vm_mutex_unlock(&module_data_list_lock);
attr_container_destroy(attr_cont);
}
static int get_applets_count()
{
module_data *m_data;
int num = 0;
vm_mutex_lock(&module_data_list_lock);
m_data = module_data_list;
while (m_data) {
num++;
m_data = m_data->next;
}
vm_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;
}
vm_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: vm_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[8] = { 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)
{
request_t *request = (request_t *) bh_message_payload((bh_message_t)message);
int mid = request->mid, module_type, offset;
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");
/* Enter loop run */
bh_queue_enter_loop_run(g_app_mgr_queue, app_manager_queue_callback);
fail2: module_data_list_destroy();
fail1: bh_queue_destroy(g_app_mgr_queue);
}
#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
};

View File

@ -0,0 +1,107 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef APP_MANAGER_H
#define APP_MANAGER_H
#include "bh_platform.h"
#include "bh_common.h"
#include "bh_queue.h"
#include "korp_types.h"
#include "app_manager_export.h"
#include "native_interface.h"
#include "shared_utils.h"
#ifdef __cplusplus
extern "C" {
#endif
#ifndef __ZEPHYR__
#define app_manager_printf printf
#else
#define app_manager_printf printk
#endif
#define ID_HOST -3
#define ID_APP_MGR -2
#define ID_NONE (uint32)-1
#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 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);
#if BEIHAI_ENABLE_TOOL_AGENT != 0
void *
app_manager_get_tool_agent_queue();
#endif
#ifdef __cplusplus
} /* end of extern "C" */
#endif
#endif

View File

@ -0,0 +1,303 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "bh_common.h"
#include "korp_types.h"
#include "app_manager_host.h"
#include "app_manager.h"
#include "app_manager_export.h"
#include "coap_ext.h"
#include "bh_memory.h"
#include "bh_thread.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
} 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) {
bh_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)) {
#ifndef __ZEPHYR__
ctx->message.payload_size = ntohl(ctx->message.payload_size);
#else
if (is_little_endian())
exchange32((uint8*)&ctx->message.payload_size);
#endif
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) {
bh_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.payload_size > 1024 * 1024) {
ctx->phase = Phase_Non_Start;
return 0;
}
if (ctx->message.message_type != INSTALL_WASM_BYTECODE_APP) {
ctx->message.payload = (char *) bh_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_BYTECODE_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 */
ctx->phase = Phase_Non_Start;
return 0;
}
return 0;
} else {
ctx->phase = Phase_Non_Start;
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;
}
}
return 0;
}
int aee_host_msg_callback(void *msg, uint16_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 {
printf("unexpected host msg type: %d\n", msg_type);
}
bh_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)
{
vm_mutex_init(&host_lock);
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)
return host_commu.init();
return true;
}
int app_manager_host_send_msg(int msg_type, const unsigned 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];
vm_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) {
vm_mutex_unlock(&host_lock);
return 0;
}
/* payload */
n = host_commu.send(NULL, buf, size);
vm_mutex_unlock(&host_lock);
printf("sent %d bytes to host\n", n);
return n;
} else {
printf("no send api provided\n");
}
return 0;
}

View File

@ -0,0 +1,35 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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

View File

@ -0,0 +1,23 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
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/${TARGET_PLATFORM}/*.c)
set (APP_MGR_SOURCE ${source_all})

View File

@ -0,0 +1,126 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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)
bh_free(dev_info->scan_response);
if (dev_info->private_data != NULL)
bh_free(dev_info->private_data);
if (dev_info->adv_data != NULL)
bh_free(dev_info->adv_data);
if (dev_info != NULL)
bh_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

View File

@ -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

View File

@ -0,0 +1,203 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <string.h>
#include "event.h"
#include "app_manager.h"
#include "bh_memory.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;
bh_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 *) bh_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*) bh_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;
bh_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 *)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;
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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_ */

View File

@ -0,0 +1,98 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "app_manager.h"
#include "app_manager_host.h"
#include "event.h"
#include "attr_container.h"
#include "bh_memory.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);
bh_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;
}

View File

@ -0,0 +1,34 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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_ */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,40 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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_ */

View File

@ -0,0 +1,226 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "app_manager.h"
#include "app_manager_host.h"
#include "bh_queue.h"
#include "bh_memory.h"
#include "bh_thread.h"
#include "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 !vm_mutex_init(&module_data_list_lock) ? true : false;
}
void module_data_list_destroy()
{
vm_mutex_lock(&module_data_list_lock);
if (module_data_list) {
while (module_data_list) {
module_data *p = module_data_list->next;
bh_free(module_data_list);
module_data_list = p;
}
}
vm_mutex_unlock(&module_data_list_lock);
vm_mutex_destroy(&module_data_list_lock);
}
static void module_data_list_add(module_data *m_data)
{
static uint32 module_id_max = 1;
vm_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;
}
vm_mutex_unlock(&module_data_list_lock);
}
void module_data_list_remove(module_data *m_data)
{
vm_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;
}
}
vm_mutex_unlock(&module_data_list_lock);
}
module_data*
module_data_list_lookup(const char *module_name)
{
vm_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)) {
vm_mutex_unlock(&module_data_list_lock);
return p;
}
p = p->next;
}
}
vm_mutex_unlock(&module_data_list_lock);
return NULL;
}
module_data*
module_data_list_lookup_id(unsigned int module_id)
{
vm_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) {
vm_mutex_unlock(&module_data_list_lock);
return p;
}
p = p->next;
}
}
vm_mutex_unlock(&module_data_list_lock);
return NULL;
}
module_data *
app_manager_get_module_data(uint32 module_type)
{
if (g_module_interfaces[module_type]
&& g_module_interfaces[module_type]->module_get_module_data)
return g_module_interfaces[module_type]->module_get_module_data();
return NULL;
}
void*
app_manager_get_module_queue(uint32 module_type)
{
return app_manager_get_module_data(module_type)->queue;
}
const char*
app_manager_get_module_name(uint32 module_type)
{
return app_manager_get_module_data(module_type)->module_name;
}
unsigned int app_manager_get_module_id(uint32 module_type)
{
return app_manager_get_module_data(module_type)->id;
}
void*
app_manager_get_module_heap(uint32 module_type)
{
return app_manager_get_module_data(module_type)->heap;
}
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)
{
return app_manager_get_module_data(module_type)->wd_timer.is_interrupting;
}
extern void destory_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;
destory_module_timer_ctx(m_data->id);
bh_free(m_data);
}
int check_modules_timer_expiry()
{
vm_mutex_lock(&module_data_list_lock);
module_data *p = module_data_list;
int ms_to_expiry = -1;
while (p) {
int next = get_expiry_ms(p->timer_ctx);
if (next != -1) {
if (ms_to_expiry == -1 || ms_to_expiry > next)
ms_to_expiry = next;
}
p = p->next;
}
vm_mutex_unlock(&module_data_list_lock);
return ms_to_expiry;
}

View File

@ -0,0 +1,992 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "module_wasm_app.h"
#include "native_interface.h" /* for request_t type */
#include "app_manager_host.h"
#include "bh_queue.h"
#include "attr_container.h"
#include "bh_thread.h"
#include "bh_memory.h"
#include "coap_ext.h"
#include "event.h"
#include "watchdog.h"
#include "runtime_lib.h"
/* Wasm app 4 magic bytes */
static unsigned char wasm_app_magics[] = { (unsigned char) 0x00,
(unsigned char) 0x61, (unsigned char) 0x73, (unsigned char) 0x6d };
/* Wasm app 4 version bytes */
static unsigned char wasm_app_version[] = { (unsigned char) 0x01,
(unsigned char) 0x00, (unsigned char) 0x00, (unsigned char) 0x00 };
/* 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,
Phase_Wasm_Magic,
Phase_Wasm_Version,
Phase_Wasm_Section_Type,
Phase_Wasm_Section_Size,
Phase_Wasm_Section_Content
} wasm_app_install_req_recv_phase_t;
/* Message for insall wasm app */
typedef struct install_wasm_app_msg_t {
uint8_t request_version;
uint8_t request_action;
uint16_t request_fmt;
uint32_t request_mid;
uint32_t request_sender;
uint16_t request_url_len;
uint32_t wasm_app_size; /* payload size is just wasm app binary size */
char *request_url;
wasm_app_file_t wasm_app_binary;
} 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 bytecode 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);
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);
static void destroy_wasm_sections_list(wasm_section_t *sections);
static void destroy_wasm_section_from_list(wasm_section_t **sections, int type);
#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 };
static unsigned align_uint(unsigned v, unsigned b)
{
unsigned m = b - 1;
return (v + m) & ~m;
}
static void app_instance_queue_callback(void *queue_msg)
{
uint32 argv[2];
wasm_function_inst_t func_onRequest, func_onTimer;
module_data *m_data = app_manager_get_module_data(Module_WASM_App);
wasm_data *wasm_app_data = (wasm_data*) m_data->internal_data;
wasm_module_inst_t inst = wasm_app_data->wasm_module_inst;
int message_type = bh_message_type(queue_msg);
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 = wasm_runtime_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) {
app_manager_printf("Got exception running wasm code: %s\n",
wasm_runtime_get_exception(inst));
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(inst, NULL, func_onRequest, 2, argv)) {
app_manager_printf("Got exception running wasm code: %s\n",
wasm_runtime_get_exception(inst));
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: {
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);
wasm_function_inst_t func_onResponse = wasm_runtime_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) {
app_manager_printf("Got exception running wasm code: %s\n",
wasm_runtime_get_exception(inst));
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(inst, NULL, func_onResponse, 2, argv)) {
app_manager_printf("Got exception running wasm code: %s\n",
wasm_runtime_get_exception(inst));
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;
}
case TIMER_EVENT_WASM: {
if (bh_message_payload(queue_msg)) {
/* Call Timer.callOnTimer() method */
func_onTimer = wasm_runtime_lookup_function(inst,
"_on_timer_callback", "(i32)");
if (!func_onTimer) {
app_manager_printf("Cannot find function _on_timer_callback\n");
break;
}
unsigned int timer_id = (unsigned int) bh_message_payload(
queue_msg);
argv[0] = timer_id;
if (!wasm_runtime_call_wasm(inst, NULL, func_onTimer, 1, argv)) {
app_manager_printf("Got exception running wasm code: %s\n",
wasm_runtime_get_exception(inst));
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;
}
}
}
/* 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;
korp_tid thread = wasm_app_data->thread_id;
/* attach newly created thread to the VM managed instance */
if (!wasm_runtime_attach_current_thread(inst, m_data)) {
goto fail1;
}
app_manager_printf("WASM app '%s' started\n", m_data->module_name);
/* Call app's onInit() method */
func_onInit = wasm_runtime_lookup_function(inst, "_on_init", "()");
if (!func_onInit) {
app_manager_printf("Cannot find function on_init().\n");
goto fail2;
}
if (!wasm_runtime_call_wasm(inst, NULL, func_onInit, 0, NULL)) {
printf("Got exception running WASM code: %s\n",
wasm_runtime_get_exception(inst));
wasm_runtime_clear_exception(inst);
/* call on_destroy() in case some resources are opened in on_init()
* and then exception thrown */
goto fail3;
}
/* Enter queue loop run to receive and process applet queue message */
bh_queue_enter_loop_run(m_data->queue, app_instance_queue_callback);
app_manager_printf("App instance main thread exit.\n");
fail3:
/* Call WASM app onDestroy() method if there is */
func_onDestroy = wasm_runtime_lookup_function(inst, "_on_destroy", "()");
if (func_onDestroy)
wasm_runtime_call_wasm(inst, NULL, func_onDestroy, 0, NULL);
fail2: wasm_runtime_detach_current_thread(inst);
fail1:
vm_thread_detach(thread);
vm_thread_exit(NULL);
return NULL;
}
static void cleanup_app_resource(module_data *m_data)
{
int i;
wasm_data *wasm_app_data = (wasm_data*) m_data->internal_data;
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) from list. */
destroy_wasm_sections_list(wasm_app_data->sections);
if (wasm_app_data->wasm_module)
wasm_runtime_unload(wasm_app_data->wasm_module);
/* 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)
{
/* Initialize WASM VM*/
if (!wasm_runtime_init()) {
app_manager_printf("WASM runtime environment initialization failed.\n");
return false;
}
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, wasm_app_aot_file_len, heap_size, timeout, timers,
err_size;
char *properties;
int properties_offset, i;
uint8 *wasm_app_aot_file;
wasm_app_file_t *wasm_app_file;
wasm_data *wasm_app_data;
package_type_t package_type;
module_data *m_data;
wasm_module_t module = NULL;
wasm_module_inst_t inst = NULL;
char m_name[APP_NAME_MAX_LEN] = { 0 }, timeout_str[MAX_INT_STR_LEN] = { 0 },
heap_size_str[MAX_INT_STR_LEN] = { 0 },
timers_str[MAX_INT_STR_LEN] = { 0 }, err[256];
/* Useless sections after load */
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,
/*SECTION_TYPE_CODE,*/
/*SECTION_TYPE_DATA*/};
/* Useless sections after instantiate */
uint8 sections2[] = { SECTION_TYPE_DATA };
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;
}
/* Check app name */
properties_offset = check_url_start(msg->url, strlen(msg->url), "/applet");
bh_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,
"Install WASM app failed: invalid app name.");
return false;
}
if (app_manager_lookup_module_data(m_name)) {
SEND_ERR_RESPONSE(msg->mid,
"Install WASM app failed: app already installed.");
return false;
}
/* 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;
}
/* Judge the app type is AOTed or not */
package_type = get_package_type((uint8 *) msg->payload, msg->payload_len);
/* Load WASM file and instantiate*/
if (package_type == Wasm_Module_AoT) {
wasm_app_aot_file = (uint8 *) msg->payload;
wasm_app_aot_file_len = msg->payload_len;
inst = wasm_runtime_load_aot(wasm_app_aot_file, wasm_app_aot_file_len,
heap_size, err, err_size);
if (!inst) {
SEND_ERR_RESPONSE(msg->mid,
"Install WASM app failed: load wasm aot binary failed.");
return false;
}
} else if (package_type == Wasm_Module_Bytecode) {
wasm_app_file = (wasm_app_file_t *) msg->payload;
module = wasm_runtime_load_from_sections(wasm_app_file->sections, err,
err_size);
if (!module) {
SEND_ERR_RESPONSE(msg->mid,
"Install WASM app failed: load WASM file failed.");
printf("error: %s\n", err);
destroy_wasm_sections_list(wasm_app_file->sections);
return false;
}
/* Destroy useless sections from list after load */
for (i = 0; i < sizeof(sections1); i++)
destroy_wasm_section_from_list(&wasm_app_file->sections,
sections1[i]);
inst = wasm_runtime_instantiate(module, 0, heap_size, err, err_size);
if (!inst) {
SEND_ERR_RESPONSE(msg->mid,
"Install WASM app failed: instantiate wasm runtime failed.");
printf("error: %s\n", err);
wasm_runtime_unload(module);
destroy_wasm_sections_list(wasm_app_file->sections);
return false;
}
/* Destroy useless sections from list after instantiate */
for (i = 0; i < sizeof(sections2); i++)
destroy_wasm_section_from_list(&wasm_app_file->sections,
sections2[i]);
} else {
SEND_ERR_RESPONSE(msg->mid,
"Install WASM app failed: invalid wasm package type.");
return false;
}
/* 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 = bh_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;
wasm_app_data->sections = wasm_app_file->sections;
/* 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;
}
/* create a thread. This thread may not dedicate for this WASM app.
WASM app instance needs to attach to one thread */
if (vm_thread_create(&wasm_app_data->thread_id, wasm_app_routine,
(void*) m_data, APP_THREAD_STACK_SIZE_DEFAULT) != 0) {
module_data_list_remove(m_data);
SEND_ERR_RESPONSE(msg->mid,
"Install WASM app failed: create app threadf 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);
wasm_runtime_deinstantiate(inst);
if (package_type == Wasm_Module_Bytecode)
wasm_runtime_unload(module);
if (package_type == Wasm_Module_Bytecode)
destroy_wasm_sections_list(wasm_app_file->sections);
return false;
}
/* 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;
vm_thread_join(wasm_app_data->thread_id, NULL, -1);
cleanup_app_resource(m_data);
app_manager_post_applets_update_event();
app_manager_printf("Uninstall WASM app successful!\n");
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) queue_msg);
return false;
}
static module_data*
wasm_app_module_get_module_data(void)
{
return wasm_runtime_get_current_thread_data();
}
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{ \
unsigned char *p = (unsigned char *)&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)
{
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) {
unsigned char *p = (unsigned char *) &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 = bh_malloc(
recv_ctx.message.request_url_len + 1);
if (NULL == recv_ctx.message.request_url)
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_Wasm_Magic;
recv_ctx.size_in_phase = 0;
}
return true;
} else if (recv_ctx.phase == Phase_Wasm_Magic) {
/* start to receive wasm app binary */
unsigned char *p =
(unsigned char *) &recv_ctx.message.wasm_app_binary.magic;
if (ch == wasm_app_magics[recv_ctx.size_in_phase])
p[recv_ctx.size_in_phase++] = ch;
else
goto fail;
if (recv_ctx.size_in_phase
== sizeof(recv_ctx.message.wasm_app_binary.magic)) {
recv_ctx.phase = Phase_Wasm_Version;
recv_ctx.size_in_phase = 0;
}
return true;
} else if (recv_ctx.phase == Phase_Wasm_Version) {
unsigned char *p =
(unsigned char *) &recv_ctx.message.wasm_app_binary.version;
if (ch == wasm_app_version[recv_ctx.size_in_phase])
p[recv_ctx.size_in_phase++] = ch;
else
goto fail;
if (recv_ctx.size_in_phase
== sizeof(recv_ctx.message.wasm_app_binary.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) {
wasm_section_t *new_section;
if (!(new_section = (wasm_section_t *) bh_malloc(sizeof(wasm_section_t))))
goto fail;
memset(new_section, 0, sizeof(wasm_section_t));
new_section->section_type = ch;
new_section->next = NULL;
/* add the section to tail of link list */
if (NULL == recv_ctx.message.wasm_app_binary.sections) {
recv_ctx.message.wasm_app_binary.sections = new_section;
recv_ctx.message.wasm_app_binary.section_end = new_section;
} else {
recv_ctx.message.wasm_app_binary.section_end->next = new_section;
recv_ctx.message.wasm_app_binary.section_end = new_section;
}
recv_ctx.phase = Phase_Wasm_Section_Size;
recv_ctx.size_in_phase = 0;
return true;
} else if (recv_ctx.phase == Phase_Wasm_Section_Size) {
/* the last section is the current receiving one */
wasm_section_t *section = recv_ctx.message.wasm_app_binary.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");
goto fail;
}
if ((byte & 0x80) == 0) {
/* leb128 encoded section size parsed done */
if (!(section->section_body = bh_malloc(section->section_body_size)))
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.wasm_app_binary.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)) {
bh_free(recv_ctx.message.request_url);
recv_ctx.message.request_url = NULL;
memset(&recv_ctx, 0, sizeof(recv_ctx));
return true;
} else
goto fail;
} else {
recv_ctx.phase = Phase_Wasm_Section_Type;
recv_ctx.size_in_phase = 0;
return true;
}
}
return true;
}
fail: if (recv_ctx.message.wasm_app_binary.sections != NULL) {
destroy_wasm_sections_list(recv_ctx.message.wasm_app_binary.sections);
recv_ctx.message.wasm_app_binary.sections = NULL;
}
if (recv_ctx.message.request_url != NULL) {
bh_free(recv_ctx.message.request_url);
recv_ctx.message.request_url = NULL;
}
recv_ctx.phase = Phase_Req_Ver;
recv_ctx.size_in_phase = 0;
recv_ctx.total_received_size = 0;
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 *) bh_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->wasm_app_binary);
request->payload = bh_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 */
memcpy(request->payload, &message->wasm_app_binary, 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;
}
static void destroy_wasm_sections_list(wasm_section_t *sections)
{
wasm_section_t *cur = sections;
/* App-manager-host and module_wasm won't access the
* section list concurrently, so need lock to protect. */
while (cur) {
wasm_section_t *next = cur->next;
if (cur->section_body != NULL)
bh_free(cur->section_body);
bh_free(cur);
cur = next;
}
}
static void destroy_wasm_section_from_list(wasm_section_t **sections, int type)
{
wasm_section_t *cur, *prev = NULL;
/* App-manager-host and module_wasm won't access the
* section list concurrently, so need lock to protect. */
cur = *sections;
while (cur) {
wasm_section_t *next = cur->next;
if (type == cur->section_type) {
if (prev)
prev->next = next;
else
*sections = next;
if (cur->section_body != NULL)
bh_free(cur->section_body);
bh_free(cur);
break;
} else {
prev = cur;
}
cur = next;
}
}

View File

@ -0,0 +1,95 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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
enum {
WASM_Msg_Start = BASE_EVENT_MAX, TIMER_EVENT_WASM, SENSOR_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;
/* section list of wasm bytecode */
wasm_section_list_t sections;
} 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 App File */
typedef struct wasm_app_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_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);
#ifdef __cplusplus
} /* end of extern "C" */
#endif
#endif /* _MODULE_WASM_APP_H_ */

View File

@ -0,0 +1,59 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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)
{
return NULL;
}
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 };

View File

@ -0,0 +1,32 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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_ */

View File

@ -0,0 +1,54 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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;
}

View File

@ -0,0 +1,72 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "app_manager.h"
#include "bh_platform.h"
#include "bh_memory.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 = bh_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)
{
bh_free(timer);
}
void app_manager_timer_start(void *timer, int timeout)
{
k_timer_start(timer, timeout, 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

View File

@ -0,0 +1,214 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "native_interface.h"
#include "shared_utils.h"
#include "app_manager.h"
#include "app_manager_export.h"
#include "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) 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 = strrchr(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 *)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 *)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 *) bh_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) {
bh_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;
bh_free(r->url);
bh_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;
}
}

View File

@ -0,0 +1,140 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "watchdog.h"
#include "bh_queue.h"
#include "bh_thread.h"
#include "bh_memory.h"
#include "jeff_export.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);
vm_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));
}
vm_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 (BH_SUCCESS != vm_mutex_init(&wd_timer->lock))
return false;
if (!(wd_timer->timer_handle =
app_manager_timer_create(watchdog_timer_callback, wd_timer))) {
vm_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);
vm_mutex_destroy(&wd_timer->lock);
#endif
}
void watchdog_timer_start(watchdog_timer *wd_timer)
{
vm_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);
vm_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;
}

View File

@ -0,0 +1,49 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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();
#ifdef __cplusplus
} /* end of extern "C" */
#endif
#endif /* _WATCHDOG_H_ */

View File

@ -0,0 +1,300 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _APP_MANAGER_EXPORT_H_
#define _APP_MANAGER_EXPORT_H_
#include "native_interface.h"
#include "shared_utils.h"
#include "bh_queue.h"
#include "host_link.h"
#include "runtime_timer.h"
#ifdef __cplusplus
extern "C" {
#endif
struct attr_container_t;
/* 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;
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);
/**
* @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 *interface);
/**
* Send message to Host
*
* @param buf buffer to send
* @param size size of buffer
*
* @return size of buffer sent
*/
/* Startup app manager */
void
app_manager_startup(host_interface *interface);
/* Get queue of current applet */
void *
app_manager_get_module_queue(uint32 module_type);
/* Get applet name of current applet */
const char *
app_manager_get_module_name(uint32 module_type);
/* Get heap of current applet */
void *
app_manager_get_module_heap(uint32 module_type);
void*
get_app_manager_queue();
module_data*
app_manager_get_module_data(uint32 module_type);
unsigned int
app_manager_get_module_id(uint32 module_type);
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
*/
int
app_manager_host_send_msg(int msg_type, const unsigned char *buf, int size);
bool
bh_applet_check_permission(const char *perm);
#ifdef __cplusplus
} /* end of extern "C" */
#endif
#endif

View File

@ -0,0 +1,23 @@
# Copyright (C) 2019 Intel Corporation. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
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})

View File

@ -0,0 +1,42 @@
/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#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_BYTECODE_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_ */

53
core/app-mgr/module.json Normal file
View File

@ -0,0 +1,53 @@
{
"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": [
"NVALGRIND",
"__JLF__",
"__ZEPHYR__"
],
"target": "aee",
"dependencies": []
}