mirror of
				https://github.com/bytecodealliance/wasm-micro-runtime.git
				synced 2025-10-31 05:11: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;
 | |
| }
 | 
