#include #include #include #include #include "../core/plugins.h" #include "api.h" typedef struct p11_msg_t { api_plugin_t from; void *content; size_t content_size; uint8_t priority; unsigned read: 1; TAILQ_ENTRY(p11_msg_t) entries; } p11_msg_t; TAILQ_HEAD(slisthead, p11_msg_t) p11_msgs[256]; static uint8_t p11_plugin_counter; static uint32_t p11_depth = 0; extern internal_plugin_t *plugins_g[256]; static void init_queues() { static uint8_t first_time = 1; if (first_time) { for (size_t i = 0; i < sizeof p11_msgs / sizeof *p11_msgs; ++i) TAILQ_INIT(&p11_msgs[i]); first_time = 0; } if (p11_depth == 0) p11_plugin_counter = get_current_plugin_id(); } uint32_t api_send_message_instant(api_plugin_t dest, void *content, size_t content_size, uint8_t priority) { uint32_t r; init_queues(); p11_depth++; if (p11_depth > 10) { p11_depth--; return 4; } r = api_send_message(dest, content, content_size, priority); if (r == 0) { uint32_t sender_id = p11_plugin_counter; p11_plugin_counter = dest.id; if (plugins_g[dest.id] == NULL || plugins_g[dest.id]->run_instant == NULL) r = 3; else { plugins_g[dest.id]->run_instant(); r = 0; } p11_plugin_counter = sender_id; } p11_depth--; return r; } uint32_t api_send_message(api_plugin_t dest, void *content, size_t content_size, uint8_t priority) { p11_msg_t *new_msg; init_queues(); if ((new_msg = malloc(sizeof *new_msg)) == NULL || (new_msg->content = malloc(content_size)) == NULL) return 1; // TODO: check if destination plugin exists memcpy(new_msg->content, content, content_size); memcpy(&(new_msg->from), &p11_plugin_counter, sizeof p11_plugin_counter); new_msg->priority = priority; new_msg->content_size = content_size; new_msg->read = 0; // TODO: manage priority TAILQ_INSERT_TAIL(&p11_msgs[dest.id], new_msg, entries); printf("[%i] send a message (%p) to %i. It's %lu long and has priority %i.\n", p11_plugin_counter, content, dest.id, content_size, priority); return 0; } uint32_t api_receive_message(api_plugin_t *from, void **content, size_t *content_size) { p11_msg_t *msg; // TODO: manage sender selection init_queues(); p11_plugin_counter = get_current_plugin_id(); msg = TAILQ_FIRST(&(p11_msgs[p11_plugin_counter])); while (msg) { if (msg->read == 0) { *content = msg->content; *content_size = msg->content_size; *from = msg->from; msg->read = 1; printf("[%u] receive a message (%p) from %i. It's %lu long and has priority %i.\n", p11_plugin_counter, *content, from->id, *content_size, msg->priority); return 0; } msg = TAILQ_NEXT(msg, entries); } return 2; } void api_clear_read_messages(uint8_t full) { p11_msg_t *msg; init_queues(); TAILQ_FOREACH(msg, &p11_msgs[p11_plugin_counter], entries) { if (full == 1 || msg->read == 1) { free(msg->content); TAILQ_REMOVE(&p11_msgs[p11_plugin_counter], msg, entries); free(msg); } } }