mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-30 00:00:11 +01:00
added first version of configurable hook support with a few examples
TODO: this is not tested yet git-svn-id: https://zerberus.eonerc.rwth-aachen.de:8443/svn/s2ss/trunk@177 8ec27952-4edc-4aab-86aa-e87bb2611832
This commit is contained in:
parent
183b5e158a
commit
64cead2f2e
7 changed files with 147 additions and 9 deletions
|
@ -5,7 +5,7 @@ SRCS = server.c send.c receive.c random.c node.c path.c utils.c msg.c cfg.c if.c
|
|||
all: $(TARGETS)
|
||||
|
||||
# Dependencies for individual binaries
|
||||
server: node.o msg.o utils.o path.o cfg.o if.o tc.o
|
||||
server: node.o msg.o utils.o path.o cfg.o if.o tc.o hooks.o
|
||||
send: node.o msg.o utils.o
|
||||
receive: node.o msg.o utils.o
|
||||
random: node.o msg.o utils.o
|
||||
|
|
|
@ -34,6 +34,7 @@ paths = (
|
|||
reverse = true, # Setup a path in the reverse direction too
|
||||
in = "acs", # Name of the node we listen to (see above)
|
||||
out = "sintef", # Name of the node we send to
|
||||
rate = 100 # Send message over this path with a fixed (equalized) rate
|
||||
rate = 100, # Send message over this path with a fixed (equalized) rate
|
||||
hook = "print" # Register custom hook funktion (see src/hooks.c)
|
||||
}
|
||||
);
|
||||
|
|
60
server/include/hooks.h
Normal file
60
server/include/hooks.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/** Hook funktions
|
||||
*
|
||||
* Every path can register a hook function which is called for every received
|
||||
* message. This can be used to debug the data flow, get statistics
|
||||
* or alter the message.
|
||||
*
|
||||
* This file includes some examples.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014, Institute for Automation of Complex Power Systems, EONERC
|
||||
* @file
|
||||
*/
|
||||
|
||||
#ifndef _HOOKS_H_
|
||||
#define _HOOKS_H_
|
||||
|
||||
struct msg;
|
||||
struct path;
|
||||
|
||||
/** Callback type of hook function
|
||||
*
|
||||
* @todo Add a way to pass custom data to the hooks
|
||||
* @param m The message which is forwarded
|
||||
* @param p The path which is processing this message.
|
||||
* @retval 0 Success. Continue processing the message.
|
||||
* @retval <0 Error. Drop the message.
|
||||
*/
|
||||
typedef int (*hook_cb_t)(struct msg *m, struct path *p);
|
||||
|
||||
/** This is a static list of available hooks.
|
||||
*
|
||||
* It's used by hook_lookup to parse hook identfiers from the configuration file.
|
||||
* The list must be terminated by NULL pointers!
|
||||
*/
|
||||
struct hook_id {
|
||||
hook_cb_t cb;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
/** Get a function pointer of a hook function by its name
|
||||
*
|
||||
* @param name The name of the requested hook
|
||||
* @retval NULL There is no hook registred with name.
|
||||
* @retval >0 A function pointer to the requested hook_cb_t hook.
|
||||
*/
|
||||
hook_cb_t hook_lookup(const char *name);
|
||||
|
||||
/** Example hook: Print the message. */
|
||||
int hook_print(struct msg *m, struct path *p);
|
||||
|
||||
/** Example hook: Filter the message on some criteria. */
|
||||
int hook_filter(struct msg *m, struct path *p);
|
||||
|
||||
/** Example hook: Convert the message values to fixed precision. */
|
||||
int hook_tofixed(struct msg *m, struct path *p);
|
||||
|
||||
/** Example hook: Chain multiple hooks */
|
||||
int hook_multiple(struct msg *m, struct path *p);
|
||||
|
||||
#endif /* _HOOKS_H_ */
|
|
@ -14,6 +14,7 @@
|
|||
#include "config.h"
|
||||
#include "node.h"
|
||||
#include "msg.h"
|
||||
#include "hooks.h"
|
||||
|
||||
/** The datastructure for a path.
|
||||
*
|
||||
|
@ -26,12 +27,8 @@ struct path
|
|||
/** Pointer to the outgoing node */
|
||||
struct node *out;
|
||||
|
||||
/** If non NULL this function is called for every received message.
|
||||
*
|
||||
* This hook can be used to filter messages on a user-defined criteria.
|
||||
* If the function has a non-zero return value the message will be dropped.
|
||||
*/
|
||||
int (*hook)(struct msg *m);
|
||||
/** Function pointer of the hook */
|
||||
hook_cb_t hook;
|
||||
|
||||
/** Send messages with a fixed rate over this path */
|
||||
double rate;
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include "node.h"
|
||||
#include "path.h"
|
||||
#include "utils.h"
|
||||
#include "hooks.h"
|
||||
|
||||
int config_parse(const char *filename, config_t *cfg, struct settings *set,
|
||||
struct node **nodes, struct path **paths)
|
||||
|
@ -101,6 +102,13 @@ int config_parse_path(config_setting_t *cfg,
|
|||
cerror(cfg, "Invalid output node '%s'", out);
|
||||
|
||||
/* Optional settings */
|
||||
if (config_setting_lookup_string(cfg, "hook", &hook)) {
|
||||
path->hook = hook_lookup(hook);
|
||||
|
||||
if (!path->hook)
|
||||
cerror(cfg, "Failed to lookup hook function. Not registred?");
|
||||
}
|
||||
|
||||
config_setting_lookup_bool(cfg, "enabled", &enabled);
|
||||
config_setting_lookup_bool(cfg, "reverse", &reverse);
|
||||
config_setting_lookup_float(cfg, "rate", &path->rate);
|
||||
|
|
72
server/src/hooks.c
Normal file
72
server/src/hooks.c
Normal file
|
@ -0,0 +1,72 @@
|
|||
/** Hook funktions
|
||||
*
|
||||
* Every path can register a hook function which is called for every received
|
||||
* message. This can be used to debug the data flow, get statistics
|
||||
* or alter the message.
|
||||
*
|
||||
* This file includes some examples.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014, Institute for Automation of Complex Power Systems, EONERC
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "msg.h"
|
||||
#include "hooks.h"
|
||||
|
||||
/** @todo Make const */
|
||||
static struct hook_id hook_list[] = {
|
||||
{ hook_print, "print" },
|
||||
{ hook_filter, "filter" },
|
||||
{ hook_tofixed, "tofixed" },
|
||||
{ hook_multiple, "multiple" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
hook_cb_t hook_lookup(const char *name)
|
||||
{
|
||||
for (struct hook_id *hid = hook_list; hid->cb; hid++) {
|
||||
if (!strcmp(name, hid->name)) {
|
||||
return hid->cb;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL; /* No matching hook was found */
|
||||
}
|
||||
|
||||
int hook_print(struct msg *m, struct path *p)
|
||||
{
|
||||
/* Print every message once to stdout */
|
||||
msg_fprint(stdout, m);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hook_filter(struct msg *m, struct path *p)
|
||||
{
|
||||
/* Drop every 10th message */
|
||||
if (m->sequence % 10 == 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hook_tofixed(struct msg *m, struct path *p)
|
||||
{
|
||||
for (int i=0; i<m->length; i++) {
|
||||
m->data[i].i = m->data[i].f * 1e3;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hook_multiple(struct msg *m, struct path *p)
|
||||
{
|
||||
if (hook_print(m, p))
|
||||
return -1;
|
||||
else if (hook_tofixed(m, p))
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
|
@ -108,7 +108,7 @@ static void * path_run(void *arg)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (p->hook && p->hook(m)) {
|
||||
if (p->hook && p->hook(m, p)) {
|
||||
p->skipped++;
|
||||
continue;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue