mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
split node and node_type into separate files
This commit is contained in:
parent
10bdf4db51
commit
21d6ff20c4
8 changed files with 212 additions and 188 deletions
|
@ -14,17 +14,11 @@
|
|||
#include <netinet/in.h>
|
||||
#include <libconfig.h>
|
||||
|
||||
#include "node_type.h"
|
||||
#include "sample.h"
|
||||
#include "list.h"
|
||||
#include "queue.h"
|
||||
|
||||
extern struct list node_types; /**< Vtable for virtual node sub types */
|
||||
|
||||
/* Forward declarations */
|
||||
struct node_type;
|
||||
struct settings;
|
||||
typedef struct config_setting_t config_setting_t;
|
||||
|
||||
/** The data structure for a node.
|
||||
*
|
||||
* Every entity which exchanges messages is represented by a node.
|
||||
|
@ -57,135 +51,6 @@ struct node
|
|||
config_setting_t *cfg; /**< A pointer to the libconfig object which instantiated this node */
|
||||
};
|
||||
|
||||
/** C++ like vtable construct for node_types */
|
||||
struct node_type {
|
||||
const char *name; /**< The unique name of this node. This must be allways the first member! */
|
||||
const char *description; /**< A short description of this node type. Will be shown in help text. */
|
||||
int vectorize; /**< Maximal vector length supported by this node type. Zero is unlimited. */
|
||||
|
||||
struct list instances; /**< A list of all existing nodes of this type. */
|
||||
size_t size; /**< Size of private data bock. @see node::_vd */
|
||||
|
||||
enum node_type_state {
|
||||
NODE_TYPE_UNINITIALIZED = 0,
|
||||
NODE_TYPE_INITIALIZED
|
||||
} state;
|
||||
|
||||
/** Global initialization per node type.
|
||||
*
|
||||
* This callback is invoked once per node-type.
|
||||
*
|
||||
* @param argc Number of arguments passed to the server executable (see main()).
|
||||
* @param argv Array of arguments passed to the server executable (see main()).
|
||||
* @param cfg Root libconfig object of global configuration file.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*init)(int argc, char * argv[], config_setting_t *cfg);
|
||||
|
||||
/** Global de-initialization per node type.
|
||||
*
|
||||
* This callback is invoked once per node-type.
|
||||
*
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*deinit)();
|
||||
|
||||
/** Allocate memory for an instance of this type.
|
||||
*
|
||||
* @return A pointer to the node-type specific private data.
|
||||
*/
|
||||
void * (*create)();
|
||||
|
||||
/** Free memory of an instance of this type.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
*/
|
||||
int (*destroy)(struct node *n);
|
||||
|
||||
/** Parse node connection details.‚
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @param cfg A libconfig object pointing to the node.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*parse)(struct node *n, config_setting_t *cfg);
|
||||
|
||||
/** Returns a string with a textual represenation of this node.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @return A pointer to a dynamically allocated string. Must be freed().
|
||||
*/
|
||||
char * (*print)(struct node *n);
|
||||
|
||||
/** Opens the connection to this node.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*open) (struct node *n);
|
||||
|
||||
/** Close the connection to this node.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*close)(struct node *n);
|
||||
|
||||
/** Receive multiple messages at once.
|
||||
*
|
||||
* Messages are received with a single recvmsg() syscall by
|
||||
* using gathering techniques (struct iovec).
|
||||
* The messages will be stored in a circular buffer / array @p m.
|
||||
* Indexes used to address @p m will wrap around after len messages.
|
||||
* Some node types might only support to receive one message at a time.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @param smps An array of pointers to memory blocks where the function should store received samples.
|
||||
* @param cnt The number of messages which should be received.
|
||||
* @return The number of messages actually received.
|
||||
*/
|
||||
int (*read) (struct node *n, struct sample *smps[], unsigned cnt);
|
||||
|
||||
/** Send multiple messages in a single datagram / packet.
|
||||
*
|
||||
* Messages are sent with a single sendmsg() syscall by
|
||||
* using gathering techniques (struct iovec).
|
||||
* The messages have to be stored in a circular buffer / array m.
|
||||
* So the indexes will wrap around after len.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @param smps An array of pointers to memory blocks where samples read from.
|
||||
* @param cnt The number of messages which should be sent.
|
||||
* @return The number of messages actually sent.
|
||||
*/
|
||||
int (*write)(struct node *n, struct sample *smps[], unsigned cnt);
|
||||
|
||||
/** Reverse source and destination of a node.
|
||||
*
|
||||
* This is not supported by all node types!
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
*/
|
||||
int (*reverse)(struct node *n);
|
||||
};
|
||||
|
||||
/** Initialize all registered node type subsystems.
|
||||
*
|
||||
* @see node_type::init
|
||||
*/
|
||||
int node_init(struct node_type *vt, int argc, char *argv[], config_setting_t *cfg);
|
||||
|
||||
/** De-initialize node type subsystems.
|
||||
*
|
||||
* @see node_type::deinit
|
||||
*/
|
||||
int node_deinit(struct node_type *vt);
|
||||
|
||||
/** Create a node by allocating dynamic memory.
|
||||
*
|
||||
* @see node_type::create
|
||||
|
@ -229,9 +94,6 @@ char * node_name(struct node *n);
|
|||
*/
|
||||
char * node_name_long(struct node *n);
|
||||
|
||||
/** Return a pointer to a string which describes the node type */
|
||||
const char * node_name_type(struct node *n);
|
||||
|
||||
/** Reverse local and remote socket address.
|
||||
*
|
||||
* @see node_type::reverse
|
||||
|
@ -263,4 +125,7 @@ int node_parse_list(struct list *list, config_setting_t *cfg, struct list *all);
|
|||
*/
|
||||
int node_parse(struct node *n, config_setting_t *cfg);
|
||||
|
||||
/** Validate node configuration. */
|
||||
int node_check(struct node *n);
|
||||
|
||||
/** @} */
|
150
include/villas/node_type.h
Normal file
150
include/villas/node_type.h
Normal file
|
@ -0,0 +1,150 @@
|
|||
/** Nodes
|
||||
*
|
||||
* @file
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
*
|
||||
* @addtogroup node Node
|
||||
* @{
|
||||
*********************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <libconfig.h>
|
||||
|
||||
#include "list.h"
|
||||
|
||||
/* Forward declarations */
|
||||
struct node;
|
||||
struct sample;
|
||||
|
||||
/** C++ like vtable construct for node_types */
|
||||
struct node_type {
|
||||
const char *name; /**< The unique name of this node. This must be allways the first member! */
|
||||
const char *description; /**< A short description of this node type. Will be shown in help text. */
|
||||
int vectorize; /**< Maximal vector length supported by this node type. Zero is unlimited. */
|
||||
|
||||
struct list instances; /**< A list of all existing nodes of this type. */
|
||||
size_t size; /**< Size of private data bock. @see node::_vd */
|
||||
|
||||
enum node_type_state {
|
||||
NODE_TYPE_UNINITIALIZED = 0,
|
||||
NODE_TYPE_INITIALIZED
|
||||
} state;
|
||||
|
||||
/** Global initialization per node type.
|
||||
*
|
||||
* This callback is invoked once per node-type.
|
||||
*
|
||||
* @param argc Number of arguments passed to the server executable (see main()).
|
||||
* @param argv Array of arguments passed to the server executable (see main()).
|
||||
* @param cfg Root libconfig object of global configuration file.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*init)(int argc, char * argv[], config_setting_t *cfg);
|
||||
|
||||
/** Global de-initialization per node type.
|
||||
*
|
||||
* This callback is invoked once per node-type.
|
||||
*
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*deinit)();
|
||||
|
||||
/** Allocate memory for an instance of this type.
|
||||
*
|
||||
* @return A pointer to the node-type specific private data.
|
||||
*/
|
||||
void * (*create)();
|
||||
|
||||
/** Free memory of an instance of this type.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
*/
|
||||
int (*destroy)(struct node *n);
|
||||
|
||||
/** Parse node connection details.‚
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @param cfg A libconfig object pointing to the node.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*parse)(struct node *n, config_setting_t *cfg);
|
||||
|
||||
/** Returns a string with a textual represenation of this node.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @return A pointer to a dynamically allocated string. Must be freed().
|
||||
*/
|
||||
char * (*print)(struct node *n);
|
||||
|
||||
/** Opens the connection to this node.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*open) (struct node *n);
|
||||
|
||||
/** Close the connection to this node.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @retval 0 Success. Everything went well.
|
||||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*close)(struct node *n);
|
||||
|
||||
/** Receive multiple messages at once.
|
||||
*
|
||||
* Messages are received with a single recvmsg() syscall by
|
||||
* using gathering techniques (struct iovec).
|
||||
* The messages will be stored in a circular buffer / array @p m.
|
||||
* Indexes used to address @p m will wrap around after len messages.
|
||||
* Some node types might only support to receive one message at a time.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @param smps An array of pointers to memory blocks where the function should store received samples.
|
||||
* @param cnt The number of messages which should be received.
|
||||
* @return The number of messages actually received.
|
||||
*/
|
||||
int (*read) (struct node *n, struct sample *smps[], unsigned cnt);
|
||||
|
||||
/** Send multiple messages in a single datagram / packet.
|
||||
*
|
||||
* Messages are sent with a single sendmsg() syscall by
|
||||
* using gathering techniques (struct iovec).
|
||||
* The messages have to be stored in a circular buffer / array m.
|
||||
* So the indexes will wrap around after len.
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
* @param smps An array of pointers to memory blocks where samples read from.
|
||||
* @param cnt The number of messages which should be sent.
|
||||
* @return The number of messages actually sent.
|
||||
*/
|
||||
int (*write)(struct node *n, struct sample *smps[], unsigned cnt);
|
||||
|
||||
/** Reverse source and destination of a node.
|
||||
*
|
||||
* This is not supported by all node types!
|
||||
*
|
||||
* @param n A pointer to the node object.
|
||||
*/
|
||||
int (*reverse)(struct node *n);
|
||||
};
|
||||
|
||||
/** Initialize all registered node type subsystems.
|
||||
*
|
||||
* @see node_type::init
|
||||
*/
|
||||
int node_type_init(struct node_type *vt, int argc, char *argv[], config_setting_t *cfg);
|
||||
|
||||
/** De-initialize node type subsystems.
|
||||
*
|
||||
* @see node_type::deinit
|
||||
*/
|
||||
int node_type_deinit(struct node_type *vt);
|
||||
|
||||
/** @} */
|
|
@ -6,7 +6,8 @@ LIB_SRCS = $(addprefix lib/nodes/, file.c cbuilder.c) \
|
|||
$(addprefix lib/kernel/, kernel.c rt.c) \
|
||||
$(addprefix lib/, sample.c path.c node.c hook.c \
|
||||
log.c utils.c cfg.c hist.c timing.c pool.c list.c \
|
||||
queue.c memory.c advio.c web.c api.c plugin.c stats.c \
|
||||
queue.c memory.c advio.c web.c api.c plugin.c \
|
||||
node_type.c stats.c \
|
||||
)
|
||||
|
||||
LIB_CFLAGS = $(CFLAGS) -fPIC
|
||||
|
|
41
lib/node.c
41
lib/node.c
|
@ -57,42 +57,6 @@ int node_write(struct node *n, struct sample *smps[], unsigned cnt)
|
|||
return nsent;
|
||||
}
|
||||
|
||||
int node_init(struct node_type *vt, int argc, char *argv[], config_setting_t *cfg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (vt->state != NODE_TYPE_UNINITIALIZED)
|
||||
return -1;
|
||||
|
||||
info("Initializing " YEL("%s") " node type", vt->name);
|
||||
{ INDENT
|
||||
ret = vt->init ? vt->init(argc, argv, cfg) : -1;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
vt->state = NODE_TYPE_INITIALIZED;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int node_deinit(struct node_type *vt)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (vt->state != NODE_TYPE_INITIALIZED)
|
||||
return -1;
|
||||
|
||||
info("De-initializing " YEL("%s") " node type", vt->name);
|
||||
{ INDENT
|
||||
ret = vt->deinit ? vt->deinit() : -1;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
vt->state = NODE_TYPE_UNINITIALIZED;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int node_start(struct node *n)
|
||||
{
|
||||
int ret;
|
||||
|
@ -163,11 +127,6 @@ const char * node_name_short(struct node *n)
|
|||
return n->name;
|
||||
}
|
||||
|
||||
const char * node_name_type(struct node *n)
|
||||
{
|
||||
return n->_vt->name;
|
||||
}
|
||||
|
||||
int node_reverse(struct node *n)
|
||||
{
|
||||
return n->_vt->reverse ? n->_vt->reverse(n) : -1;
|
||||
|
|
51
lib/node_type.c
Normal file
51
lib/node_type.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/** Nodes.
|
||||
*
|
||||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2017, Institute for Automation of Complex Power Systems, EONERC
|
||||
*********************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
#include <libconfig.h>
|
||||
|
||||
#include "sample.h"
|
||||
#include "node.h"
|
||||
#include "cfg.h"
|
||||
#include "utils.h"
|
||||
#include "config.h"
|
||||
#include "plugin.h"
|
||||
|
||||
int node_type_init(struct node_type *vt, int argc, char *argv[], config_setting_t *cfg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (vt->state != NODE_TYPE_UNINITIALIZED)
|
||||
return -1;
|
||||
|
||||
info("Initializing " YEL("%s") " node type", vt->name);
|
||||
{ INDENT
|
||||
ret = vt->init ? vt->init(argc, argv, cfg) : -1;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
vt->state = NODE_TYPE_INITIALIZED;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int node_type_deinit(struct node_type *vt)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (vt->state != NODE_TYPE_INITIALIZED)
|
||||
return -1;
|
||||
|
||||
info("De-initializing " YEL("%s") " node type", vt->name);
|
||||
{ INDENT
|
||||
ret = vt->deinit ? vt->deinit() : -1;
|
||||
}
|
||||
|
||||
if (ret == 0)
|
||||
vt->state = NODE_TYPE_UNINITIALIZED;
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -104,8 +104,6 @@ int main(int argc, char *argv[])
|
|||
}
|
||||
else if (argc > 2)
|
||||
usage();
|
||||
|
||||
char *uri = (argc == 2) ? argv[1] : NULL;
|
||||
#endif
|
||||
|
||||
log_init(&cfg.log, V, LOG_ALL);
|
||||
|
@ -123,7 +121,7 @@ int main(int argc, char *argv[])
|
|||
info("Parsing configuration");
|
||||
cfg_init_pre(&cfg);
|
||||
|
||||
cfg_parse(&cfg, uri);
|
||||
cfg_parse_cli(&cfg, argc, argv);
|
||||
|
||||
cfg_init_post(&cfg);
|
||||
|
||||
|
|
|
@ -54,7 +54,7 @@ static void quit(int signal, siginfo_t *sinfo, void *ctx)
|
|||
}
|
||||
|
||||
node_stop(node);
|
||||
node_deinit(node->_vt);
|
||||
node_type_deinit(node->_vt);
|
||||
|
||||
cfg_destroy(&cfg);
|
||||
|
||||
|
@ -229,7 +229,7 @@ int main(int argc, char *argv[])
|
|||
if (reverse)
|
||||
node_reverse(node);
|
||||
|
||||
ret = node_init(node->_vt, argc-optind, argv+optind, config_root_setting(&cfg.cfg));
|
||||
ret = node_type_init(node->_vt, argc-optind, argv+optind, config_root_setting(&cfg.cfg));
|
||||
if (ret)
|
||||
error("Failed to intialize node: %s", node_name(node));
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ int main(int argc, char *argv[])
|
|||
if (!node)
|
||||
error("There's no node with the name '%s'", argv[3]);
|
||||
|
||||
node_init(node->_vt, argc-3, argv+3, config_root_setting(&cfg.cfg));
|
||||
node_type_init(node->_vt, argc-3, argv+3, config_root_setting(&cfg.cfg));
|
||||
node_start(node);
|
||||
|
||||
/* Parse Arguments */
|
||||
|
@ -132,7 +132,7 @@ check: if (optarg == endptr)
|
|||
error("Unknown test: '%s'", argv[2]);
|
||||
|
||||
node_stop(node);
|
||||
node_deinit(node->_vt);
|
||||
node_type_deinit(node->_vt);
|
||||
|
||||
cfg_destroy(&cfg);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue