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/event.c
2019-05-17 17:15:25 +08:00

204 lines
5.3 KiB
C

/*
* 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;
}