mirror of
https://github.com/bytecodealliance/wasm-micro-runtime.git
synced 2025-02-06 15:05:19 +00:00
193 lines
4.8 KiB
C
193 lines
4.8 KiB
C
/*
|
|
* Copyright (C) 2019 Intel Corporation. All rights reserved.
|
|
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
*/
|
|
|
|
#include <string.h>
|
|
|
|
#include "event.h"
|
|
|
|
#include "app_manager.h"
|
|
#include "coap_ext.h"
|
|
|
|
typedef struct _subscribe {
|
|
struct _subscribe * next;
|
|
uint32 subscriber_id;
|
|
} subscribe_t;
|
|
|
|
typedef struct _event {
|
|
struct _event *next;
|
|
int subscriber_size;
|
|
subscribe_t * subscribers;
|
|
char url[1]; /* event url */
|
|
} event_reg_t;
|
|
|
|
event_reg_t *g_events = NULL;
|
|
|
|
static bool find_subscriber(event_reg_t * reg, uint32 id, bool remove_found)
|
|
{
|
|
subscribe_t* c = reg->subscribers;
|
|
subscribe_t * prev = NULL;
|
|
while (c) {
|
|
subscribe_t * next = c->next;
|
|
if (c->subscriber_id == id) {
|
|
if (remove_found) {
|
|
if (prev)
|
|
prev->next = next;
|
|
else
|
|
reg->subscribers = next;
|
|
|
|
APP_MGR_FREE(c);
|
|
}
|
|
|
|
return true;
|
|
} else {
|
|
prev = c;
|
|
c = next;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
static bool check_url(const char *url)
|
|
{
|
|
if (*url == 0)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
bool am_register_event(const char *url, uint32_t reg_client)
|
|
{
|
|
event_reg_t *current = g_events;
|
|
|
|
app_manager_printf("am_register_event adding url:(%s)\n", url);
|
|
|
|
if (!check_url(url)) {
|
|
app_manager_printf("am_register_event: invaild url:(%s)\n", url);
|
|
return false;
|
|
}
|
|
while (current) {
|
|
if (strcmp(url, current->url) == 0)
|
|
break;
|
|
current = current->next;
|
|
}
|
|
|
|
if (current == NULL) {
|
|
if (NULL
|
|
== (current = (event_reg_t *) APP_MGR_MALLOC(
|
|
offsetof(event_reg_t, url) + strlen(url) + 1))) {
|
|
app_manager_printf("am_register_event: malloc fail\n");
|
|
return false;
|
|
}
|
|
|
|
memset(current, 0, sizeof(event_reg_t));
|
|
bh_strcpy_s(current->url, strlen(url) + 1, url);
|
|
current->next = g_events;
|
|
g_events = current;
|
|
}
|
|
|
|
if (find_subscriber(current, reg_client, false)) {
|
|
return true;
|
|
} else {
|
|
subscribe_t * s = (subscribe_t*) APP_MGR_MALLOC(sizeof(subscribe_t));
|
|
if (s == NULL)
|
|
return false;
|
|
|
|
memset(s, 0, sizeof(subscribe_t));
|
|
s->subscriber_id = reg_client;
|
|
s->next = current->subscribers;
|
|
current->subscribers = s;
|
|
app_manager_printf("client: %d registered event (%s)\n", reg_client,
|
|
url);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
// @url: NULL means the client wants to unregister all its subscribed items
|
|
bool am_unregister_event(const char *url, uint32_t reg_client)
|
|
{
|
|
event_reg_t *current = g_events, *pre = NULL;
|
|
|
|
while (current != NULL) {
|
|
if (url == NULL || strcmp(current->url, url) == 0) {
|
|
event_reg_t * next = current->next;
|
|
if (find_subscriber(current, reg_client, true)) {
|
|
app_manager_printf("client: %d deregistered event (%s)\n",
|
|
reg_client, current->url);
|
|
}
|
|
|
|
// remove the registration if no client subscribe it
|
|
if (current->subscribers == NULL) {
|
|
app_manager_printf("unregister for event deleted url:(%s)\n",
|
|
current->url);
|
|
if (pre)
|
|
pre->next = next;
|
|
else
|
|
g_events = next;
|
|
APP_MGR_FREE(current);
|
|
current = next;
|
|
continue;
|
|
}
|
|
}
|
|
pre = current;
|
|
current = current->next;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
bool event_handle_event_request(uint8_t code, const char *event_url,
|
|
uint32_t reg_client)
|
|
{
|
|
if (code == COAP_PUT) { /* register */
|
|
return am_register_event(event_url, reg_client);
|
|
} else if (code == COAP_DELETE) { /* unregister */
|
|
return am_unregister_event(event_url, reg_client);
|
|
} else {
|
|
/* invalid request */
|
|
return false;
|
|
}
|
|
}
|
|
|
|
void am_publish_event(request_t * event)
|
|
{
|
|
bh_assert(event->action == COAP_EVENT);
|
|
|
|
event_reg_t *current = g_events;
|
|
while (current) {
|
|
if (0 == strcmp(event->url, current->url)) {
|
|
subscribe_t* c = current->subscribers;
|
|
while (c) {
|
|
if (c->subscriber_id == ID_HOST) {
|
|
send_request_to_host(event);
|
|
} else {
|
|
module_request_handler
|
|
(event, (void *)(uintptr_t)c->subscriber_id);
|
|
}
|
|
c = c->next;
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
current = current->next;
|
|
}
|
|
}
|
|
|
|
bool event_is_registered(const char *event_url)
|
|
{
|
|
event_reg_t *current = g_events;
|
|
|
|
while (current != NULL) {
|
|
if (strcmp(current->url, event_url) == 0) {
|
|
return true;
|
|
}
|
|
current = current->next;
|
|
}
|
|
|
|
return false;
|
|
}
|