This repository has been archived on 2023-11-05. You can view files and clone it, but cannot push or open issues or pull requests.
wasm-micro-runtime/core/app-mgr/app-manager/resource_reg.c
Wenyong Huang 54e82ec439
Fix app manager fail to install large app file issue (#555)
Remove the limit of app file size no larger than 1 MB, fix possible memory leak issues when fail to install app file, change message size of aee_host_msg_callback() from uint16 type to uint32 type to fix possible integer overflow issue, and fix some coding style issues of app manager.

Signed-off-by: Wenyong Huang <wenyong.huang@intel.com>
2021-03-03 20:19:24 +08:00

205 lines
4.8 KiB
C

/*
* Copyright (C) 2019 Intel Corporation. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/
#include "native_interface.h"
#include "app_manager.h"
#include "app_manager_export.h"
#include "bi-inc/shared_utils.h"
#include "bi-inc/attr_container.h"
#include "coap_ext.h"
typedef struct _app_res_register {
struct _app_res_register *next;
char * url;
void (*request_handler)(request_t *, void *);
uint32 register_id;
} app_res_register_t;
static app_res_register_t * g_resources = NULL;
void module_request_handler(request_t *request, void *user_data)
{
unsigned int mod_id = (unsigned int)(uintptr_t)user_data;
bh_message_t msg;
module_data *m_data;
request_t *req;
/* Check module name */
m_data = module_data_list_lookup_id(mod_id);
if (!m_data) {
return;
}
if (m_data->wd_timer.is_interrupting) {
return;
}
req = clone_request(request);
if (!req) {
return;
}
/* Set queue message and send to applet's queue */
msg = bh_new_msg(RESTFUL_REQUEST, req, sizeof(*req), request_cleaner);
if (!msg) {
request_cleaner(req);
return;
}
if (!bh_post_msg2(m_data->queue, msg)) {
return;
}
app_manager_printf("Send request to app %s success.\n",
m_data->module_name);
}
void targeted_app_request_handler(request_t *request, void *unused)
{
char applet_name[128] = { 0 };
int offset;
char *url = request->url;
module_data *m_data;
offset = check_url_start(request->url, strlen(request->url), "/app/");
if (offset <= 0) {
return;
}
strncpy(applet_name, request->url + offset, sizeof(applet_name) - 1);
char *p = strchr(applet_name, '/');
if (p) {
*p = 0;
} else
return;
app_manager_printf("Send request to applet: %s\n", applet_name);
request->url = p + 1;
/* Check module name */
m_data = module_data_list_lookup(applet_name);
if (!m_data) {
SEND_ERR_RESPONSE(request->mid,
"Send request to applet failed: invalid applet name");
goto end;
}
module_request_handler(request, (void *)(uintptr_t)m_data->id);
end: request->url = url;
}
void am_send_response(response_t *response)
{
module_data *m_data;
// if the receiver is not any of modules, just forward it to the host
m_data = module_data_list_lookup_id(response->reciever);
if (!m_data) {
send_response_to_host(response);
} else {
response_t * resp_for_send = clone_response(response);
if (!resp_for_send) {
return;
}
bh_message_t msg = bh_new_msg(RESTFUL_RESPONSE, resp_for_send,
sizeof(*resp_for_send), response_cleaner);
if (!msg) {
response_cleaner(resp_for_send);
return;
}
if (!bh_post_msg2(m_data->queue, msg)) {
return;
}
}
}
void * am_dispatch_request(request_t *request)
{
app_res_register_t *r = g_resources;
while (r) {
if (check_url_start(request->url, strlen(request->url), r->url) > 0) {
r->request_handler(request, (void *)(uintptr_t)r->register_id);
return r;
}
r = r->next;
}
return NULL;
}
bool am_register_resource(const char *url,
void (*request_handler)(request_t *, void *),
uint32 register_id)
{
app_res_register_t * r = g_resources;
int register_num = 0;
while (r) {
if (strcmp(r->url, url) == 0) {
return false;
}
if (r->register_id == register_id)
register_num++;
r = r->next;
}
if (strlen(url) > RESOUCE_EVENT_URL_LEN_MAX)
return false;
if (register_num >= RESOURCE_REGISTRATION_NUM_MAX)
return false;
r = (app_res_register_t *)APP_MGR_MALLOC(sizeof(app_res_register_t));
if (r == NULL)
return false;
memset(r, 0, sizeof(*r));
r->url = bh_strdup(url);
if (r->url == NULL) {
APP_MGR_FREE(r);
return false;
}
r->request_handler = request_handler;
r->next = g_resources;
r->register_id = register_id;
g_resources = r;
return true;
}
void am_cleanup_registeration(uint32 register_id)
{
app_res_register_t * r = g_resources;
app_res_register_t * prev = NULL;
while (r) {
app_res_register_t *next = r->next;
if (register_id == r->register_id) {
if (prev)
prev->next = next;
else
g_resources = next;
APP_MGR_FREE(r->url);
APP_MGR_FREE(r);
} else
/* if r is freed, should not change prev. Only set prev to r
when r isn't freed. */
prev = r;
r = next;
}
}