modular-worm/plugins/11_message.c

115 lines
3.0 KiB
C

#include <sys/queue.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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);
}
}
}