mirror of
https://git.rwth-aachen.de/acs/public/villas/node/
synced 2025-03-09 00:00:00 +01:00
removed trailing whitespace
This commit is contained in:
parent
5f8cbe6914
commit
5f038bf6bd
24 changed files with 328 additions and 329 deletions
|
@ -10,7 +10,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#ifndef _NODE_H_
|
||||
|
@ -68,7 +68,7 @@ struct node_vtable {
|
|||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*parse)(config_setting_t *cfg, struct node *n);
|
||||
|
||||
|
||||
/** Print details of socket connection
|
||||
*
|
||||
* @param n A pointer to the node structure
|
||||
|
@ -85,7 +85,7 @@ struct node_vtable {
|
|||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*open) (struct node *n);
|
||||
|
||||
|
||||
/** Close the socket.
|
||||
*
|
||||
* @param n A pointer to the node.
|
||||
|
@ -93,7 +93,7 @@ struct node_vtable {
|
|||
* @retval <0 Error. Something went wrong.
|
||||
*/
|
||||
int (*close)(struct node *n);
|
||||
|
||||
|
||||
/** Receive multiple messages from single datagram / packet.
|
||||
*
|
||||
* Messages are received with a single recvmsg() syscall by
|
||||
|
@ -109,7 +109,7 @@ struct node_vtable {
|
|||
* @return The number of messages actually received.
|
||||
*/
|
||||
int (*read) (struct node *n, struct msg *pool, int poolsize, int first, int cnt);
|
||||
|
||||
|
||||
/** Send multiple messages in a single datagram / packet.
|
||||
*
|
||||
* Messages are sent with a single sendmsg() syscall by
|
||||
|
@ -125,10 +125,10 @@ struct node_vtable {
|
|||
* @return The number of messages actually sent.
|
||||
*/
|
||||
int (*write)(struct node *n, struct msg *pool, int poolsize, int first, int cnt);
|
||||
|
||||
|
||||
int (*init)(int argc, char *argv[], struct settings *set);
|
||||
int (*deinit)();
|
||||
|
||||
|
||||
int refcnt;
|
||||
};
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*
|
||||
* @addtogroup socket BSD Socket Node Type
|
||||
* @{
|
||||
|
@ -50,7 +50,7 @@ int socket_deinit();
|
|||
int socket_open(struct node *n);
|
||||
|
||||
/** @see node_vtable::close */
|
||||
int socket_close(struct node *n);
|
||||
int socket_close(struct node *n);
|
||||
|
||||
/** @see node_vtable::write */
|
||||
int socket_write(struct node *n, struct msg *pool, int poolsize, int first, int cnt);
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -41,7 +41,7 @@ int config_parse(const char *filename, config_t *cfg, struct settings *set,
|
|||
config_error_file(cfg) ? config_error_file(cfg) : filename,
|
||||
config_error_line(cfg)
|
||||
);
|
||||
|
||||
|
||||
config_setting_t *cfg_root = config_root_setting(cfg);
|
||||
|
||||
/* Parse global settings */
|
||||
|
@ -51,13 +51,13 @@ int config_parse(const char *filename, config_t *cfg, struct settings *set,
|
|||
|
||||
config_parse_global(cfg_root, set);
|
||||
}
|
||||
|
||||
|
||||
/* Parse nodes */
|
||||
if (nodes) {
|
||||
config_setting_t *cfg_nodes = config_setting_get_member(cfg_root, "nodes");
|
||||
if (!cfg_nodes || !config_setting_is_group(cfg_nodes))
|
||||
error("Missing node section in config file: %s", filename);
|
||||
|
||||
|
||||
for (int i = 0; i < config_setting_length(cfg_nodes); i++) {
|
||||
config_setting_t *cfg_node = config_setting_get_elem(cfg_nodes, i);
|
||||
config_parse_node(cfg_node, nodes);
|
||||
|
@ -97,14 +97,14 @@ int config_parse_path(config_setting_t *cfg,
|
|||
const char *in;
|
||||
int enabled;
|
||||
int reverse;
|
||||
|
||||
|
||||
struct path *p = path_create();
|
||||
|
||||
/* Input node */
|
||||
struct config_setting_t *cfg_in = config_setting_get_member(cfg, "in");
|
||||
if (!cfg_in || config_setting_type(cfg_in) != CONFIG_TYPE_STRING)
|
||||
cerror(cfg, "Invalid input node for path");
|
||||
|
||||
|
||||
in = config_setting_get_string(cfg_in);
|
||||
p->in = node_lookup_name(in, nodes);
|
||||
if (!p->in)
|
||||
|
@ -124,7 +124,7 @@ int config_parse_path(config_setting_t *cfg,
|
|||
struct config_setting_t *cfg_hook = config_setting_get_member(cfg, "hook");
|
||||
if (cfg_hook)
|
||||
config_parse_hooklist(cfg_hook, p->hooks);
|
||||
|
||||
|
||||
if (!config_setting_lookup_bool(cfg, "enabled", &enabled))
|
||||
enabled = 1;
|
||||
if (!config_setting_lookup_bool(cfg, "reverse", &reverse))
|
||||
|
@ -139,12 +139,12 @@ int config_parse_path(config_setting_t *cfg,
|
|||
if (enabled) {
|
||||
p->in->refcnt++;
|
||||
p->in->vt->refcnt++;
|
||||
|
||||
|
||||
FOREACH(&p->destinations, it) {
|
||||
it->node->refcnt++;
|
||||
it->node->vt->refcnt++;
|
||||
}
|
||||
|
||||
|
||||
if (reverse) {
|
||||
if (list_length(&p->destinations) > 1)
|
||||
error("Can't reverse path with multiple destination nodes");
|
||||
|
@ -153,7 +153,7 @@ int config_parse_path(config_setting_t *cfg,
|
|||
|
||||
r->in = p->out; /* Swap in/out */
|
||||
r->out = p->in;
|
||||
|
||||
|
||||
list_push(&r->destinations, r->out);
|
||||
|
||||
r->in->refcnt++;
|
||||
|
@ -163,13 +163,13 @@ int config_parse_path(config_setting_t *cfg,
|
|||
|
||||
list_push(paths, r);
|
||||
}
|
||||
|
||||
|
||||
list_push(paths, p);
|
||||
}
|
||||
else {
|
||||
char buf[128];
|
||||
path_print(p, buf, sizeof(buf));
|
||||
|
||||
|
||||
warn("Path %s is not enabled", buf);
|
||||
path_destroy(p);
|
||||
}
|
||||
|
@ -180,32 +180,32 @@ int config_parse_path(config_setting_t *cfg,
|
|||
int config_parse_nodelist(config_setting_t *cfg, struct list *nodes, struct list *all) {
|
||||
const char *str;
|
||||
struct node *node;
|
||||
|
||||
|
||||
switch (config_setting_type(cfg)) {
|
||||
case CONFIG_TYPE_STRING:
|
||||
str = config_setting_get_string(cfg);
|
||||
node = node_lookup_name(str, all);
|
||||
if (!node)
|
||||
cerror(cfg, "Invalid outgoing node '%s'", str);
|
||||
|
||||
|
||||
list_push(nodes, node);
|
||||
break;
|
||||
|
||||
|
||||
case CONFIG_TYPE_ARRAY:
|
||||
for (int i=0; i<config_setting_length(cfg); i++) {
|
||||
str = config_setting_get_string_elem(cfg, i);
|
||||
node = node_lookup_name(str, all);
|
||||
if (!node)
|
||||
cerror(config_setting_get_elem(cfg, i), "Invalid outgoing node '%s'", str);
|
||||
|
||||
|
||||
list_push(nodes, node);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
cerror(cfg, "Invalid output node(s)");
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -219,27 +219,27 @@ int config_parse_hooklist(config_setting_t *cfg, struct list *hooks) {
|
|||
hook = hook_lookup(str);
|
||||
if (!hook)
|
||||
cerror(cfg, "Invalid hook function '%s'", str);
|
||||
|
||||
|
||||
debug(10, "Adding hook %s to chain %u with prio %u", hook->name, hook->type, hook->priority);
|
||||
|
||||
|
||||
list_insert(&hooks[hook->type], hook->priority, hook->callback);
|
||||
break;
|
||||
|
||||
|
||||
case CONFIG_TYPE_ARRAY:
|
||||
for (int i=0; i<config_setting_length(cfg); i++) {
|
||||
str = config_setting_get_string_elem(cfg, i);
|
||||
hook = hook_lookup(str);
|
||||
if (!hook)
|
||||
cerror(config_setting_get_elem(cfg, i), "Invalid hook function '%s'", str);
|
||||
|
||||
|
||||
list_insert(&hooks[hook->type], hook->priority, hook->callback);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
cerror(cfg, "Invalid hook functions");
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -258,10 +258,10 @@ int config_parse_node(config_setting_t *cfg, struct list *nodes)
|
|||
|
||||
if (!config_setting_lookup_string(cfg, "type", &type))
|
||||
cerror(cfg, "Missing node type");
|
||||
|
||||
|
||||
if (!config_setting_lookup_int(cfg, "combine", &n->combine))
|
||||
n->combine = 1;
|
||||
|
||||
|
||||
n->vt = node_lookup_vtable(type);
|
||||
if (!n->vt)
|
||||
cerror(cfg, "Invalid type for node '%s'", n->name);
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <unistd.h>
|
||||
|
@ -27,7 +27,7 @@ int file_deinit()
|
|||
int file_print(struct node *n, char *buf, int len)
|
||||
{
|
||||
struct file *f = n->file;
|
||||
|
||||
|
||||
return snprintf(buf, len, "in=%s, out=%s, mode=%s, rate=%.1f",
|
||||
f->path_in, f->path_out, f->mode, f->rate);
|
||||
}
|
||||
|
@ -35,27 +35,27 @@ int file_print(struct node *n, char *buf, int len)
|
|||
int file_parse(config_setting_t *cfg, struct node *n)
|
||||
{
|
||||
struct file *f = alloc(sizeof(struct file));
|
||||
|
||||
|
||||
const char *out;
|
||||
if (config_setting_lookup_string(cfg, "out", &out)) {
|
||||
time_t t = time(NULL);
|
||||
struct tm *tm = localtime(&t);
|
||||
|
||||
|
||||
f->path_out = alloc(FILE_MAX_PATHLEN);
|
||||
if (strftime(f->path_out, FILE_MAX_PATHLEN, out, tm) == 0)
|
||||
cerror(cfg, "Invalid path for output");
|
||||
|
||||
|
||||
}
|
||||
config_setting_lookup_string(cfg, "in", &f->path_in);
|
||||
|
||||
|
||||
if (!config_setting_lookup_string(cfg, "mode", &f->mode))
|
||||
f->mode = "w+";
|
||||
|
||||
|
||||
if (!config_setting_lookup_float(cfg, "rate", &f->rate))
|
||||
f->rate = 0;
|
||||
|
||||
|
||||
n->file = f;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -67,11 +67,11 @@ int file_open(struct node *n)
|
|||
f->in = fopen(f->path_in, "r");
|
||||
if (!f->in)
|
||||
serror("Failed to open file for reading: '%s'", f->path_in);
|
||||
|
||||
|
||||
f->tfd = timerfd_create(CLOCK_MONOTONIC, 0);
|
||||
if (f->tfd < 0)
|
||||
serror("Failed to create timer");
|
||||
|
||||
|
||||
/* Arm the timer */
|
||||
struct itimerspec its;
|
||||
if (f->rate) {
|
||||
|
@ -84,34 +84,34 @@ int file_open(struct node *n)
|
|||
time_fscan(f->in, &f->offset);
|
||||
rewind(f->in);
|
||||
}
|
||||
|
||||
|
||||
int ret = timerfd_settime(f->tfd, 0, &its, NULL);
|
||||
if (ret)
|
||||
serror("Failed to start timer");
|
||||
}
|
||||
|
||||
|
||||
if (f->path_out) {
|
||||
f->out = fopen(f->path_out, f->mode);
|
||||
if (!f->out)
|
||||
serror("Failed to open file for writing: '%s'", f->path_out);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int file_close(struct node *n)
|
||||
{
|
||||
struct file *f = n->file;
|
||||
|
||||
|
||||
if (f->tfd)
|
||||
close(f->tfd);
|
||||
if (f->in)
|
||||
fclose(f->in);
|
||||
if (f->out)
|
||||
fclose(f->out);
|
||||
|
||||
|
||||
free(f->path_out);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -119,22 +119,21 @@ int file_read(struct node *n, struct msg *pool, int poolsize, int first, int cnt
|
|||
{
|
||||
int i = 0;
|
||||
struct file *f = n->file;
|
||||
|
||||
|
||||
if (f->in) {
|
||||
struct timespec ts;
|
||||
|
||||
for (i = 0; i < cnt; i++)
|
||||
msg_fscan(f->in, &pool[(first+i) % poolsize]);
|
||||
|
||||
|
||||
if (f->rate)
|
||||
timerfd_wait(f->tfd);
|
||||
else
|
||||
timerfd_wait_until(f->tfd, &ts);
|
||||
|
||||
}
|
||||
else
|
||||
warn("Can not read from node '%s'", n->name);
|
||||
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
|
@ -142,7 +141,7 @@ int file_write(struct node *n, struct msg *pool, int poolsize, int first, int cn
|
|||
{
|
||||
int i = 0;
|
||||
struct file *f = n->file;
|
||||
|
||||
|
||||
if (f->out) {
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
|
@ -152,6 +151,6 @@ int file_write(struct node *n, struct msg *pool, int poolsize, int first, int cn
|
|||
}
|
||||
else
|
||||
warn("Can not write to node '%s", n->name);
|
||||
|
||||
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -34,13 +34,13 @@ int gtfpga_init(int argc, char * argv[], struct settings *set)
|
|||
{
|
||||
pacc = pci_alloc(); /* Get the pci_access structure */
|
||||
pci_init(pacc); /* Initialize the PCI library */
|
||||
|
||||
|
||||
pacc->error = (log_cb_t) error; /* Replace logging and debug functions */
|
||||
pacc->warning = (log_cb_t) warn;
|
||||
pacc->debug = gtfpga_debug;
|
||||
|
||||
|
||||
pci_scan_bus(pacc); /* We want to get the list of devices */
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,7 @@ int gtfpga_parse(config_setting_t *cfg, struct node *n)
|
|||
|
||||
const char *slot, *id, *err;
|
||||
config_setting_t *cfg_slot, *cfg_id;
|
||||
|
||||
|
||||
/* Checks */
|
||||
if (n->combine != 1) {
|
||||
config_setting_t *cfg_combine = config_setting_get_member(cfg, "combine");
|
||||
|
@ -89,10 +89,10 @@ int gtfpga_parse(config_setting_t *cfg, struct node *n)
|
|||
else
|
||||
cerror(cfg_slot, "Invalid id format");
|
||||
}
|
||||
|
||||
|
||||
if (!config_setting_lookup_float(cfg, "rate", &g->rate))
|
||||
g->rate = 0;
|
||||
|
||||
|
||||
n->gtfpga = g;
|
||||
|
||||
return 0;
|
||||
|
@ -120,34 +120,34 @@ static int gtfpga_load_driver(struct pci_dev *d)
|
|||
FILE *f;
|
||||
char slot[16];
|
||||
int ret;
|
||||
|
||||
|
||||
/* Prepare slot identifier */
|
||||
snprintf(slot, sizeof(slot), "%04x:%02x:%02x.%x",
|
||||
d->domain, d->bus, d->dev, d->func);
|
||||
|
||||
|
||||
/* Load uio_pci_generic module */
|
||||
ret = system2("modprobe uio_pci_generic");
|
||||
if (ret)
|
||||
serror("Failed to load module");
|
||||
|
||||
|
||||
/* Add new ID to uio_pci_generic */
|
||||
f = fopen(SYSFS_PATH "/drivers/uio_pci_generic/new_id", "w");
|
||||
if (!f)
|
||||
serror("Failed to add PCI id to uio_pci_generic driver");
|
||||
|
||||
|
||||
debug(5, "Adding ID to uio_pci_generic module: %04x %04x", d->vendor_id, d->device_id);
|
||||
fprintf(f, "%04x %04x", d->vendor_id, d->device_id);
|
||||
fclose(f);
|
||||
|
||||
|
||||
/* Bind to uio_pci_generic */
|
||||
f = fopen(SYSFS_PATH "/drivers/uio_pci_generic/bind", "w");
|
||||
if (!f)
|
||||
serror("Failed to add PCI id to uio_pci_generic driver");
|
||||
|
||||
|
||||
debug(5, "Bind slot to uio_pci_generic module: %s", slot);
|
||||
fprintf(f, "%s\n", slot);
|
||||
fclose(f);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -178,7 +178,7 @@ static int gtfpga_mmap(struct gtfpga *g)
|
|||
void *map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr);
|
||||
if (map == MAP_FAILED)
|
||||
serror("Failed mmap()");
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -201,15 +201,15 @@ int gtfpga_open(struct node *n)
|
|||
|
||||
/* Show some debug infos */
|
||||
pci_fill_info(dev, PCI_FILL_IDENT | PCI_FILL_BASES | PCI_FILL_CLASS); /* Fill in header info we need */
|
||||
|
||||
|
||||
g->name = pci_lookup_name(pacc, g->name, 512, PCI_LOOKUP_DEVICE, dev->vendor_id, dev->device_id);
|
||||
|
||||
|
||||
/* Setup timer */
|
||||
if (g->rate) {
|
||||
g->fd_irq = timerfd_create(CLOCK_MONOTONIC, 0);
|
||||
if (g->fd_irq < 0)
|
||||
serror("Failed to create timer");
|
||||
|
||||
|
||||
struct itimerspec its = {
|
||||
.it_interval = time_from_double(1 / g->rate),
|
||||
.it_value = { 1, 0 }
|
||||
|
@ -221,11 +221,11 @@ int gtfpga_open(struct node *n)
|
|||
else
|
||||
/** @todo implement UIO interrupts */
|
||||
error("UIO irq not implemented yet. Use 'rate' setting");
|
||||
|
||||
|
||||
char buf[1024];
|
||||
gtfpga_print(n, buf, sizeof(buf));
|
||||
debug(5, "Found GTFPGA card: %s", buf);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -247,14 +247,14 @@ int gtfpga_close(struct node *n)
|
|||
int gtfpga_read(struct node *n, struct msg *pool, int poolsize, int first, int cnt)
|
||||
{
|
||||
struct gtfpga *g = n->gtfpga;
|
||||
|
||||
|
||||
struct msg *m = &pool[first % poolsize];
|
||||
|
||||
|
||||
uint64_t runs;
|
||||
read(g->fd_irq, &runs, sizeof(runs));
|
||||
|
||||
|
||||
static int seq;
|
||||
|
||||
|
||||
m->sequence = seq++;
|
||||
|
||||
return 0;
|
||||
|
@ -264,7 +264,7 @@ int gtfpga_read(struct node *n, struct msg *pool, int poolsize, int first, int c
|
|||
int gtfpga_write(struct node *n, struct msg *pool, int poolsize, int first, int cnt)
|
||||
{
|
||||
// struct gtfpga *g = n->gtfpga;
|
||||
|
||||
|
||||
// struct msg *m = &pool[first % poolsize];
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -26,7 +26,7 @@ void hist_create(struct hist *h, double low, double high, double resolution)
|
|||
h->resolution = resolution;
|
||||
h->length = (high - low) / resolution;
|
||||
h->data = alloc(h->length * sizeof(unsigned));
|
||||
|
||||
|
||||
hist_reset(h);
|
||||
}
|
||||
|
||||
|
@ -38,13 +38,13 @@ void hist_destroy(struct hist *h)
|
|||
void hist_put(struct hist *h, double value)
|
||||
{
|
||||
int idx = INDEX(h, value);
|
||||
|
||||
|
||||
/* Update min/max */
|
||||
if (value > h->highest)
|
||||
h->highest = value;
|
||||
if (value < h->lowest)
|
||||
h->lowest = value;
|
||||
|
||||
|
||||
/* Check bounds and increment */
|
||||
if (idx >= h->length)
|
||||
h->higher++;
|
||||
|
@ -52,9 +52,9 @@ void hist_put(struct hist *h, double value)
|
|||
h->lower++;
|
||||
else
|
||||
h->data[idx]++;
|
||||
|
||||
|
||||
h->total++;
|
||||
|
||||
|
||||
/* Online / running calculation of variance and mean
|
||||
* by Donald Knuth’s Art of Computer Programming, Vol 2, page 232, 3rd edition */
|
||||
if (h->total == 1) {
|
||||
|
@ -64,12 +64,12 @@ void hist_put(struct hist *h, double value)
|
|||
else {
|
||||
h->_m[0] = h->_m[1] + (value - h->_m[1]) / h->total;
|
||||
h->_s[0] = h->_s[1] + (value - h->_m[1]) * (value - h->_m[0]);
|
||||
|
||||
|
||||
// set up for next iteration
|
||||
h->_m[1] = h->_m[0];
|
||||
h->_m[1] = h->_m[0];
|
||||
h->_s[1] = h->_s[0];
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void hist_reset(struct hist *h)
|
||||
|
@ -77,10 +77,10 @@ void hist_reset(struct hist *h)
|
|||
h->total = 0;
|
||||
h->higher = 0;
|
||||
h->lower = 0;
|
||||
|
||||
|
||||
h->highest = DBL_MIN;
|
||||
h->lowest = DBL_MAX;
|
||||
|
||||
|
||||
memset(h->data, 0, h->length * sizeof(unsigned));
|
||||
}
|
||||
|
||||
|
@ -111,10 +111,10 @@ void hist_print(struct hist *h)
|
|||
warn("Missed: %u values above %f", h->higher, h->high);
|
||||
if (h->lower > 0)
|
||||
warn("Missed: %u values below %f", h->lower, h->low);
|
||||
|
||||
|
||||
if (h->total - h->higher - h->lower > 0) {
|
||||
hist_plot(h);
|
||||
|
||||
|
||||
char buf[(h->length + 1) * 8];
|
||||
hist_dump(h, buf, sizeof(buf));
|
||||
info(buf);
|
||||
|
@ -125,7 +125,7 @@ void hist_plot(struct hist *h)
|
|||
{
|
||||
char buf[HIST_HEIGHT];
|
||||
memset(buf, '#', sizeof(buf));
|
||||
|
||||
|
||||
hist_cnt_t max = 1;
|
||||
|
||||
/* Get highest bar */
|
||||
|
@ -133,14 +133,14 @@ void hist_plot(struct hist *h)
|
|||
if (h->data[i] > max)
|
||||
max = h->data[i];
|
||||
}
|
||||
|
||||
|
||||
/* Print plot */
|
||||
info("%3s | %9s | %5s | %s", "#", "Value", "Occur", "Plot");
|
||||
line();
|
||||
|
||||
for (int i = 0; i < h->length; i++) {
|
||||
int bar = HIST_HEIGHT * ((double) h->data[i] / max);
|
||||
|
||||
|
||||
info("%3u | %+5.2e | " "%5u" " | %.*s", i, VAL(h, i), h->data[i], bar, buf);
|
||||
}
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ void hist_matlab(struct hist *h, FILE *f)
|
|||
{
|
||||
char buf[h->length * 8];
|
||||
hist_dump(h, buf, sizeof(buf));
|
||||
|
||||
|
||||
fprintf(f, "%lu = struct( ", time(NULL));
|
||||
fprintf(f, "'min', %f, 'max', %f, ", h->low, h->high);
|
||||
fprintf(f, "'ok', %u, too_high', %u, 'too_low', %u, ", h->total, h->higher, h->lower);
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
@ -27,7 +27,7 @@
|
|||
*
|
||||
* It's used by hook_lookup to parse hook identfiers from the configuration file.
|
||||
* The list must be terminated by NULL pointers!
|
||||
*/
|
||||
*/
|
||||
static const struct hook hook_list[] = {
|
||||
/* Priority, Callback, Name, Type */
|
||||
{ 99, hook_print, "print", HOOK_MSG },
|
||||
|
@ -51,18 +51,18 @@ const struct hook* hook_lookup(const char *name)
|
|||
int hook_run(struct path *p, enum hook_type t)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
|
||||
FOREACH(&p->hooks[t], it)
|
||||
ret += ((hook_cb_t) it->ptr)(p);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int hook_print(struct path *p)
|
||||
{
|
||||
struct msg *m = p->current;
|
||||
struct timespec ts = MSG_TS(m);
|
||||
|
||||
|
||||
fprintf(stdout, "%.3e+", time_delta(&ts, &p->ts_recv)); /* Print delay */
|
||||
msg_fprint(stdout, m);
|
||||
|
||||
|
@ -74,8 +74,8 @@ int hook_tofixed(struct path *p)
|
|||
struct msg *m = p->current;
|
||||
|
||||
for (int i=0; i<m->length; i++)
|
||||
m->data[i].i = m->data[i].f * 1e3;
|
||||
|
||||
m->data[i].i = m->data[i].f * 1e3;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ int hook_ts(struct path *p)
|
|||
|
||||
m->ts.sec = p->ts_recv.tv_sec;
|
||||
m->ts.nsec = p->ts_recv.tv_nsec;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -93,22 +93,22 @@ int hook_fir(struct path *p)
|
|||
{
|
||||
/** Simple FIR-LP: F_s = 1kHz, F_pass = 100 Hz, F_block = 300
|
||||
* Tip: Use MATLAB's filter design tool and export coefficients
|
||||
* with the integrated C-Header export */
|
||||
* with the integrated C-Header export */
|
||||
static const double coeffs[] = {
|
||||
-0.003658148158728, -0.008882653268281, 0.008001024183003,
|
||||
0.08090485991761, 0.2035239551043, 0.3040703593515,
|
||||
0.3040703593515, 0.2035239551043, 0.08090485991761,
|
||||
0.008001024183003, -0.008882653268281,-0.003658148158728 };
|
||||
|
||||
|
||||
/* Accumulator */
|
||||
double sum = 0;
|
||||
|
||||
|
||||
/** Trim FIR length to length of history buffer */
|
||||
int len = MIN(ARRAY_LEN(coeffs), p->poolsize);
|
||||
|
||||
for (int i=0; i<len; i++) {
|
||||
struct msg *old = &p->pool[(p->poolsize+p->received-i) % p->poolsize];
|
||||
|
||||
|
||||
sum += coeffs[i] * old->data[HOOK_FIR_INDEX].f;
|
||||
}
|
||||
|
||||
|
@ -142,7 +142,7 @@ int hook_restart(struct path *p)
|
|||
|
||||
path_reset(p);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -155,7 +155,7 @@ int hook_verify(struct path *p)
|
|||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -168,4 +168,4 @@ int hook_drop(struct path *p)
|
|||
}
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -49,7 +49,7 @@ void if_destroy(struct interface *i)
|
|||
int if_start(struct interface *i, int affinity)
|
||||
{
|
||||
info("Starting interface '%s' (index=%u)", i->name, i->index);
|
||||
|
||||
|
||||
{ INDENT
|
||||
/* Assign fwmark's to socket nodes which have netem options */
|
||||
int mark = 0;
|
||||
|
@ -58,14 +58,14 @@ int if_start(struct interface *i, int affinity)
|
|||
if (s->netem)
|
||||
s->mark = 1 + mark++;
|
||||
}
|
||||
|
||||
|
||||
/* Abort if no node is using netem */
|
||||
if (mark == 0)
|
||||
return 0;
|
||||
|
||||
/* Replace root qdisc */
|
||||
tc_prio(i, TC_HDL(4000, 0), mark);
|
||||
|
||||
|
||||
/* Create netem qdisks and appropriate filter per netem node */
|
||||
FOREACH(&i->sockets, it) {
|
||||
struct socket *s = it->socket;
|
||||
|
@ -89,7 +89,7 @@ int if_stop(struct interface *i)
|
|||
|
||||
{ INDENT
|
||||
if_setaffinity(i, -1L);
|
||||
|
||||
|
||||
/* Only reset tc if it was initialized before */
|
||||
FOREACH(&i->sockets, it) {
|
||||
if (it->socket->netem) {
|
||||
|
@ -132,7 +132,7 @@ int if_getegress(struct sockaddr *sa)
|
|||
struct sockaddr_ll *sll = (struct sockaddr_ll *) sa;
|
||||
return sll->sll_ifindex;
|
||||
}
|
||||
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include "utils.h"
|
||||
|
@ -14,7 +14,7 @@
|
|||
void list_init(struct list *l, dtor_cb_t dtor)
|
||||
{
|
||||
pthread_mutex_init(&l->lock, NULL);
|
||||
|
||||
|
||||
l->destructor = dtor;
|
||||
l->length = 0;
|
||||
l->head = NULL;
|
||||
|
@ -24,7 +24,7 @@ void list_init(struct list *l, dtor_cb_t dtor)
|
|||
void list_destroy(struct list *l)
|
||||
{
|
||||
pthread_mutex_lock(&l->lock);
|
||||
|
||||
|
||||
struct list_elm *elm = l->head;
|
||||
while (elm) {
|
||||
struct list_elm *tmp = elm;
|
||||
|
@ -35,7 +35,7 @@ void list_destroy(struct list *l)
|
|||
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
|
||||
pthread_mutex_unlock(&l->lock);
|
||||
pthread_mutex_destroy(&l->lock);
|
||||
}
|
||||
|
@ -43,13 +43,13 @@ void list_destroy(struct list *l)
|
|||
void list_push(struct list *l, void *p)
|
||||
{
|
||||
struct list_elm *e = alloc(sizeof(struct list_elm));
|
||||
|
||||
|
||||
pthread_mutex_lock(&l->lock);
|
||||
|
||||
|
||||
e->ptr = p;
|
||||
e->prev = l->tail;
|
||||
e->next = NULL;
|
||||
|
||||
|
||||
if (l->tail)
|
||||
l->tail->next = e;
|
||||
if (l->head)
|
||||
|
@ -67,18 +67,18 @@ void list_insert(struct list *l, int prio, void *p)
|
|||
{
|
||||
struct list_elm *d;
|
||||
struct list_elm *e = alloc(sizeof(struct list_elm));
|
||||
|
||||
|
||||
e->priority = prio;
|
||||
e->ptr = p;
|
||||
|
||||
|
||||
pthread_mutex_lock(&l->lock);
|
||||
|
||||
/* Search for first entry with higher priority */
|
||||
for (d = l->head; d && d->priority < prio; d = d->next);
|
||||
|
||||
|
||||
/* Insert new element in front of d */
|
||||
e->next = d;
|
||||
|
||||
|
||||
if (d) { /* Between or Head */
|
||||
e->prev = d->prev;
|
||||
|
||||
|
@ -89,7 +89,7 @@ void list_insert(struct list *l, int prio, void *p)
|
|||
}
|
||||
else { /* Tail or Head */
|
||||
e->prev = l->tail;
|
||||
|
||||
|
||||
if (l->length == 0) /* List was empty */
|
||||
l->head = e;
|
||||
else
|
||||
|
@ -97,14 +97,14 @@ void list_insert(struct list *l, int prio, void *p)
|
|||
|
||||
l->tail = e;
|
||||
}
|
||||
|
||||
|
||||
l->length++;
|
||||
|
||||
|
||||
pthread_mutex_unlock(&l->lock);
|
||||
}
|
||||
|
||||
struct list_elm * list_search(struct list *l, int (*cmp)(void *))
|
||||
{
|
||||
{
|
||||
FOREACH(l, it) {
|
||||
if (!cmp(it->ptr))
|
||||
return it;
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
|
@ -79,7 +79,7 @@ void log_vprint(const char *lvl, const char *fmt, va_list ap)
|
|||
|
||||
/* Severity */
|
||||
strap(buf, sizeof(buf), BLD("%5s "), lvl);
|
||||
|
||||
|
||||
/* Indention */
|
||||
#ifdef __GNUC__
|
||||
for (int i = 0; i < indent; i++)
|
||||
|
@ -89,7 +89,7 @@ void log_vprint(const char *lvl, const char *fmt, va_list ap)
|
|||
|
||||
/* Format String */
|
||||
vstrap(buf, sizeof(buf), fmt, ap);
|
||||
|
||||
|
||||
/* Output */
|
||||
#ifdef ENABLE_OPAL_ASYNC
|
||||
OpalPrint("S2SS: %s\n", buf);
|
||||
|
@ -101,7 +101,7 @@ void line()
|
|||
{
|
||||
char buf[LOG_WIDTH];
|
||||
memset(buf, 0x71, sizeof(buf));
|
||||
|
||||
|
||||
log_print("", "\b" ACS("%.*s"), LOG_WIDTH, buf);
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ void warn(const char *fmt, ...)
|
|||
log_vprint(WARN, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
|
||||
void error(const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
@ -149,11 +149,11 @@ void serror(const char *fmt, ...)
|
|||
{
|
||||
va_list ap;
|
||||
char buf[1024];
|
||||
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
|
||||
log_print(ERROR, "%s: %m (%u)", buf, errno);
|
||||
die();
|
||||
}
|
||||
|
@ -162,15 +162,15 @@ void cerror(config_setting_t *cfg, const char *fmt, ...)
|
|||
{
|
||||
va_list ap;
|
||||
char buf[1024];
|
||||
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
|
||||
log_print(ERROR, "%s in %s:%u", buf,
|
||||
config_setting_source_file(cfg)
|
||||
? config_setting_source_file(cfg)
|
||||
: "(stdio)",
|
||||
config_setting_source_line(cfg));
|
||||
: "(stdio)",
|
||||
config_setting_source_line(cfg));
|
||||
die();
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -67,7 +67,7 @@ int msg_fscan(FILE *f, struct msg *m)
|
|||
|
||||
if (!fgets(line, sizeof(line), f))
|
||||
return 0;
|
||||
|
||||
|
||||
m->ts.sec = (uint32_t) strtoul(ptr, &ptr, 10); ptr++;
|
||||
m->ts.nsec = (uint32_t) strtoul(ptr, &ptr, 10);
|
||||
m->sequence = (uint16_t) strtoul(ptr, &ptr, 10);
|
||||
|
@ -80,14 +80,14 @@ int msg_fscan(FILE *f, struct msg *m)
|
|||
|
||||
while (m->length < MSG_VALUES) {
|
||||
m->data[m->length].f = strtod(ptr, &next);
|
||||
|
||||
|
||||
if (next == ptr)
|
||||
break;
|
||||
|
||||
ptr = next;
|
||||
m->length++;
|
||||
}
|
||||
|
||||
|
||||
return m->length;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
@ -51,7 +51,7 @@ int node_init(int argc, char *argv[], struct settings *set)
|
|||
vt->init(argc, argv, set);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -97,7 +97,7 @@ int node_start(struct node *n)
|
|||
|
||||
char str[256];
|
||||
node_print(n, str, sizeof(str));
|
||||
|
||||
|
||||
debug(1, "Starting node '%s' of type '%s' (%s)", n->name, n->vt->name, str);
|
||||
|
||||
{ INDENT
|
||||
|
@ -109,11 +109,11 @@ int node_stop(struct node *n)
|
|||
{ INDENT
|
||||
int ret;
|
||||
info("Stopping node '%s'", n->name);
|
||||
|
||||
|
||||
{ INDENT
|
||||
ret = n->vt->close(n);
|
||||
}
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -22,43 +22,43 @@ static struct list opals;
|
|||
int opal_init(int argc, char *argv[], struct settings *set)
|
||||
{ INDENT
|
||||
int err;
|
||||
|
||||
|
||||
if (argc != 4)
|
||||
return -1;
|
||||
|
||||
og = alloc(sizeof(struct opal_global));
|
||||
|
||||
|
||||
pthread_mutex_init(&og->lock, NULL);
|
||||
|
||||
|
||||
og->async_shmem_name = argv[1];
|
||||
og->async_shmem_size = atoi(argv[2]);
|
||||
og->print_shmem_name = argv[3];
|
||||
|
||||
|
||||
/* Enable the OpalPrint function. This prints to the OpalDisplay. */
|
||||
if ((err = OpalSystemCtrl_Register(og->print_shmem_name)) != EOK)
|
||||
error("OpalPrint() access not available (%d)", err);
|
||||
|
||||
|
||||
/* Open Share Memory created by the model. */
|
||||
if ((err = OpalOpenAsyncMem(og->async_shmem_size, og->async_shmem_name)) != EOK)
|
||||
error("Model shared memory not available (%d)", err);
|
||||
|
||||
if ((err = OpalGetAsyncCtrlParameters(&og->params, sizeof(Opal_GenAsyncParam_Ctrl))) != EOK)
|
||||
error("Could not get OPAL controller parameters (%d)", err);
|
||||
|
||||
|
||||
/* Get list of Send and RecvIDs */
|
||||
if ((err = OpalGetNbAsyncSendIcon(&og->send_icons)) != EOK)
|
||||
error("Failed to get number of send blocks (%d)", err);
|
||||
if ((err = OpalGetNbAsyncRecvIcon(&og->recv_icons)) != EOK)
|
||||
error("Failed to get number of recv blocks (%d)", err);
|
||||
|
||||
|
||||
og->send_ids = alloc(og->send_icons * sizeof(int));
|
||||
og->recv_ids = alloc(og->recv_icons * sizeof(int));
|
||||
|
||||
|
||||
if ((err = OpalGetAsyncSendIDList(og->send_ids, og->send_icons * sizeof(int))) != EOK)
|
||||
error("Failed to get list of send ids (%d)", err);
|
||||
if ((err = OpalGetAsyncRecvIDList(og->recv_ids, og->recv_icons * sizeof(int))) != EOK)
|
||||
error("Failed to get list of recv ids (%d)", err);
|
||||
|
||||
|
||||
info("Started as OPAL Asynchronous process");
|
||||
info("This is Simulator2Simulator Server (S2SS) %s (built on %s, %s)",
|
||||
VERSION, __DATE__, __TIME__);
|
||||
|
@ -73,23 +73,23 @@ int opal_deinit()
|
|||
|
||||
if (!og)
|
||||
return 0;
|
||||
|
||||
|
||||
if ((err = OpalCloseAsyncMem(og->async_shmem_size, og->async_shmem_name)) != EOK)
|
||||
error("Failed to close shared memory area (%d)", err);
|
||||
|
||||
|
||||
debug(4, "Closing OPAL shared memory mapping");
|
||||
|
||||
|
||||
if ((err = OpalSystemCtrl_UnRegister(og->print_shmem_name)) != EOK)
|
||||
error("Failed to close shared memory for system control (%d)", err);
|
||||
|
||||
|
||||
pthread_mutex_destroy(&og->lock);
|
||||
|
||||
|
||||
free(og->send_ids);
|
||||
free(og->recv_ids);
|
||||
free(og);
|
||||
|
||||
og = NULL;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -97,12 +97,12 @@ int opal_print_global(struct opal_global *g)
|
|||
{ INDENT
|
||||
char sbuf[512] = "";
|
||||
char rbuf[512] = "";
|
||||
|
||||
|
||||
for (int i = 0; i < og->send_icons; i++)
|
||||
strap(sbuf, sizeof(sbuf), "%u ", og->send_ids[i]);
|
||||
for (int i = 0; i < og->recv_icons; i++)
|
||||
strap(rbuf, sizeof(rbuf), "%u ", og->recv_ids[i]);
|
||||
|
||||
|
||||
debug(2, "Controller ID: %u", og->params.controllerID);
|
||||
debug(2, "Send Blocks: %s", sbuf);
|
||||
debug(2, "Receive Blocks: %s", rbuf);
|
||||
|
@ -112,27 +112,27 @@ int opal_print_global(struct opal_global *g)
|
|||
debug(2, "FloatParam[]%u] = %f", i, og->params.FloatParam[i]);
|
||||
for (int i=0; i<GENASYNC_NB_STRING_PARAM; i++)
|
||||
debug(2, "StringParam[%u] = %s", i, og->params.StringParam[i]);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opal_parse(config_setting_t *cfg, struct node *n)
|
||||
{
|
||||
struct opal *o = alloc(sizeof(struct opal));
|
||||
|
||||
|
||||
/* Checks */
|
||||
if (n->combine != 1) {
|
||||
config_setting_t *cfg_combine = config_setting_get_member(cfg, "combine");
|
||||
cerror(cfg_combine, "The OPAL-RT node type does not support combining!");
|
||||
}
|
||||
|
||||
|
||||
config_setting_lookup_int(cfg, "send_id", &o->send_id);
|
||||
config_setting_lookup_int(cfg, "recv_id", &o->recv_id);
|
||||
config_setting_lookup_bool(cfg, "reply", &o->reply);
|
||||
|
||||
n->opal = o;
|
||||
n->cfg = cfg;
|
||||
|
||||
|
||||
list_push(&opals, o);
|
||||
|
||||
return 0;
|
||||
|
@ -141,9 +141,9 @@ int opal_parse(config_setting_t *cfg, struct node *n)
|
|||
int opal_print(struct node *n, char *buf, int len)
|
||||
{
|
||||
struct opal *o = n->opal;
|
||||
|
||||
|
||||
/** @todo: Print send_params, recv_params */
|
||||
|
||||
|
||||
return snprintf(buf, len, "send_id=%u, recv_id=%u, reply=%u",
|
||||
o->send_id, o->recv_id, o->reply);
|
||||
}
|
||||
|
@ -151,22 +151,22 @@ int opal_print(struct node *n, char *buf, int len)
|
|||
int opal_open(struct node *n)
|
||||
{
|
||||
struct opal *o = n->opal;
|
||||
|
||||
|
||||
if (!og)
|
||||
error("The server was not started as an OPAL asynchronous process!");
|
||||
|
||||
|
||||
/* Search for valid send and recv ids */
|
||||
int sfound = 0, rfound = 0;
|
||||
for (int i = 0; i < og->send_icons; i++)
|
||||
sfound += og->send_ids[i] == o->send_id;
|
||||
for (int i = 0; i<og->send_icons; i++)
|
||||
rfound += og->send_ids[i] == o->send_id;
|
||||
|
||||
|
||||
if (!sfound)
|
||||
error("Invalid send_id '%u' for node '%s'", o->send_id, n->name);
|
||||
if (!rfound)
|
||||
error("Invalid recv_id '%u' for node '%s'", o->recv_id, n->name);
|
||||
|
||||
|
||||
/* Get some more informations and paramters from OPAL-RT */
|
||||
OpalGetAsyncSendIconMode(&o->mode, o->send_id);
|
||||
OpalGetAsyncSendParameters(&o->send_params, sizeof(Opal_SendAsyncParam), o->send_id);
|
||||
|
@ -183,14 +183,14 @@ int opal_close(struct node *n)
|
|||
int opal_read(struct node *n, struct msg *pool, int poolsize, int first, int cnt)
|
||||
{
|
||||
struct opal *o = n->opal;
|
||||
|
||||
|
||||
int state, len, ret;
|
||||
unsigned id;
|
||||
|
||||
|
||||
struct msg *m = &pool[first % poolsize];
|
||||
|
||||
double data[MSG_VALUES];
|
||||
|
||||
|
||||
double data[MSG_VALUES];
|
||||
|
||||
/* This call unblocks when the 'Data Ready' line of a send icon is asserted. */
|
||||
do {
|
||||
if ((ret = OpalWaitForAsyncSendRequest(&id)) != EOK) {
|
||||
|
@ -244,13 +244,13 @@ int opal_read(struct node *n, struct msg *pool, int poolsize, int first, int cnt
|
|||
int opal_write(struct node *n, struct msg *pool, int poolsize, int first, int cnt)
|
||||
{
|
||||
struct opal *o = n->opal;
|
||||
|
||||
|
||||
struct msg *m = &pool[first % poolsize];
|
||||
|
||||
|
||||
int state;
|
||||
int len;
|
||||
double data[m->length];
|
||||
|
||||
|
||||
state = OpalGetAsyncModelState();
|
||||
if ((state == STATE_RESET) || (state == STATE_STOP))
|
||||
error("OpalGetAsyncModelState(): Model stopped or resetted!");
|
||||
|
@ -263,11 +263,11 @@ int opal_write(struct node *n, struct msg *pool, int poolsize, int first, int cn
|
|||
if (len > sizeof(data))
|
||||
warn("OPAL node '%s' is expecting more signals (%u) than values in message (%u)",
|
||||
n->name, len / sizeof(double), m->length);
|
||||
|
||||
|
||||
for (int i = 0; i < m->length; i++)
|
||||
data[i] = (double) m->data[i].f; /* OPAL expects double precission */
|
||||
|
||||
OpalSetAsyncRecvIconData(data, m->length * sizeof(double), o->recv_id);
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -34,7 +34,7 @@ static void path_write(struct path *p)
|
|||
|
||||
debug(1, "Sent %u messages to node '%s'", sent, it->node->name);
|
||||
p->sent += sent;
|
||||
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &p->ts_sent);
|
||||
}
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ static void * path_run_async(void *arg)
|
|||
struct path *p = arg;
|
||||
|
||||
/* Block until 1/p->rate seconds elapsed */
|
||||
while (timerfd_wait(p->tfd))
|
||||
while (timerfd_wait(p->tfd))
|
||||
path_write(p);
|
||||
|
||||
return NULL;
|
||||
|
@ -55,7 +55,7 @@ static void * path_run_async(void *arg)
|
|||
static void * path_run(void *arg)
|
||||
{
|
||||
struct path *p = arg;
|
||||
|
||||
|
||||
/* Allocate memory for message pool */
|
||||
p->pool = alloc(p->poolsize * sizeof(struct msg));
|
||||
p->previous = p->current = p->pool;
|
||||
|
@ -64,38 +64,38 @@ static void * path_run(void *arg)
|
|||
for(;;) {
|
||||
/* Receive message */
|
||||
int recv = node_read(p->in, p->pool, p->poolsize, p->received, p->in->combine);
|
||||
|
||||
|
||||
/** @todo Replace this timestamp by hardware timestamping */
|
||||
clock_gettime(CLOCK_REALTIME, &p->ts_recv);
|
||||
|
||||
|
||||
debug(10, "Received %u messages from node '%s'", recv, p->in->name);
|
||||
|
||||
|
||||
/* Run preprocessing hooks */
|
||||
if (hook_run(p, HOOK_PRE)) {
|
||||
p->skipped += recv;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* For each received message... */
|
||||
for (int i = 0; i < recv; i++) {
|
||||
p->previous = &p->pool[(p->received-1) % p->poolsize];
|
||||
p->current = &p->pool[ p->received % p->poolsize];
|
||||
|
||||
p->previous = p->current;
|
||||
p->current = &p->pool[ p->received % p->poolsize];
|
||||
|
||||
p->received++;
|
||||
|
||||
|
||||
/* Run hooks for filtering, stats collection and manipulation */
|
||||
if (hook_run(p, HOOK_MSG)) {
|
||||
p->skipped++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Run post processing hooks */
|
||||
if (hook_run(p, HOOK_POST)) {
|
||||
p->skipped += recv;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
/* At fixed rate mode, messages are send by another thread */
|
||||
if (!p->rate)
|
||||
path_write(p);
|
||||
|
@ -108,9 +108,9 @@ int path_start(struct path *p)
|
|||
{ INDENT
|
||||
char buf[33];
|
||||
path_print(p, buf, sizeof(buf));
|
||||
|
||||
|
||||
info("Starting path: %s (poolsize = %u)", buf, p->poolsize);
|
||||
|
||||
|
||||
if (hook_run(p, HOOK_PATH_START))
|
||||
return -1;
|
||||
|
||||
|
@ -138,9 +138,9 @@ int path_stop(struct path *p)
|
|||
{ INDENT
|
||||
char buf[33];
|
||||
path_print(p, buf, sizeof(buf));
|
||||
|
||||
|
||||
info("Stopping path: %s", buf);
|
||||
|
||||
|
||||
pthread_cancel(p->recv_tid);
|
||||
pthread_join(p->recv_tid, NULL);
|
||||
|
||||
|
@ -150,7 +150,7 @@ int path_stop(struct path *p)
|
|||
|
||||
close(p->tfd);
|
||||
}
|
||||
|
||||
|
||||
if (hook_run(p, HOOK_PATH_STOP))
|
||||
return -1;
|
||||
|
||||
|
@ -160,9 +160,9 @@ int path_stop(struct path *p)
|
|||
int path_print(struct path *p, char *buf, int len)
|
||||
{
|
||||
*buf = 0;
|
||||
|
||||
|
||||
strap(buf, len, "%s " MAG("=>"), p->in->name);
|
||||
|
||||
|
||||
if (list_length(&p->destinations) > 1) {
|
||||
strap(buf, len, " [");
|
||||
FOREACH(&p->destinations, it)
|
||||
|
@ -171,7 +171,7 @@ int path_print(struct path *p, char *buf, int len)
|
|||
}
|
||||
else
|
||||
strap(buf, len, " %s", p->out->name);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -185,7 +185,7 @@ int path_reset(struct path *p)
|
|||
p->invalid =
|
||||
p->skipped =
|
||||
p->dropped = 0;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -194,26 +194,26 @@ struct path * path_create()
|
|||
struct path *p = alloc(sizeof(struct path));
|
||||
|
||||
list_init(&p->destinations, NULL);
|
||||
|
||||
|
||||
for (int i = 0; i < HOOK_MAX; i++)
|
||||
list_init(&p->hooks[i], NULL);
|
||||
|
||||
#define hook_add(type, priority, cb) list_insert(&p->hooks[type], priority, cb)
|
||||
|
||||
|
||||
hook_add(HOOK_MSG, 1, hook_verify);
|
||||
hook_add(HOOK_MSG, 2, hook_restart);
|
||||
hook_add(HOOK_MSG, 3, hook_drop);
|
||||
hook_add(HOOK_MSG, 4, stats_collect);
|
||||
|
||||
|
||||
hook_add(HOOK_PATH_START, 1, stats_start);
|
||||
|
||||
|
||||
hook_add(HOOK_PATH_STOP, 1, stats_line);
|
||||
hook_add(HOOK_PATH_STOP, 2, stats_show);
|
||||
hook_add(HOOK_PATH_STOP, 3, stats_stop);
|
||||
|
||||
|
||||
hook_add(HOOK_PATH_RESTART, 1, stats_line);
|
||||
hook_add(HOOK_PATH_RESTART, 3, stats_reset);
|
||||
|
||||
|
||||
hook_add(HOOK_PERIODIC, 1, stats_line);
|
||||
|
||||
return p;
|
||||
|
@ -222,10 +222,10 @@ struct path * path_create()
|
|||
void path_destroy(struct path *p)
|
||||
{
|
||||
list_destroy(&p->destinations);
|
||||
|
||||
|
||||
for (int i = 0; i < HOOK_MAX; i++)
|
||||
list_destroy(&p->hooks[i]);
|
||||
|
||||
|
||||
free(p->pool);
|
||||
free(p);
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*
|
||||
* @addtogroup tools Test and debug tools
|
||||
* @{
|
||||
|
@ -56,16 +56,16 @@ int main(int argc, char *argv[])
|
|||
/* Block until 1/p->rate seconds elapsed */
|
||||
for (;;) {
|
||||
m.sequence += timerfd_wait(tfd);
|
||||
|
||||
|
||||
struct timespec ts;
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
|
||||
|
||||
m.ts.sec = ts.tv_sec;
|
||||
m.ts.nsec = ts.tv_nsec;
|
||||
|
||||
msg_random(&m);
|
||||
msg_fprint(stdout, &m);
|
||||
|
||||
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
|
@ -74,4 +74,4 @@ int main(int argc, char *argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*
|
||||
* @addtogroup tools Test and debug tools
|
||||
* @{
|
||||
|
@ -36,7 +36,7 @@ static void quit()
|
|||
{
|
||||
node_stop(node);
|
||||
node_deinit();
|
||||
|
||||
|
||||
list_destroy(&nodes);
|
||||
free(pool);
|
||||
|
||||
|
@ -61,11 +61,11 @@ static void usage(char *name)
|
|||
int main(int argc, char *argv[])
|
||||
{
|
||||
int reverse = 0;
|
||||
|
||||
|
||||
struct config_t config;
|
||||
|
||||
|
||||
_mtid = pthread_self();
|
||||
|
||||
|
||||
char c;
|
||||
while ((c = getopt(argc, argv, "hr")) != -1) {
|
||||
switch (c) {
|
||||
|
@ -91,14 +91,14 @@ int main(int argc, char *argv[])
|
|||
list_init(&nodes, (dtor_cb_t) node_destroy);
|
||||
config_init(&config);
|
||||
config_parse(argv[optind], &config, &set, &nodes, NULL);
|
||||
|
||||
|
||||
node = node_lookup_name(argv[optind+1], &nodes);
|
||||
if (!node)
|
||||
error("There's no node with the name '%s'", argv[optind+1]);
|
||||
|
||||
|
||||
if (reverse)
|
||||
node_reverse(node);
|
||||
|
||||
|
||||
node->refcnt++;
|
||||
node->vt->refcnt++;
|
||||
|
||||
|
@ -124,4 +124,4 @@ int main(int argc, char *argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
|
|
@ -4,8 +4,8 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*
|
||||
* @addtogroup tools Test and debug tools
|
||||
* @{
|
||||
*********************************************************************************/
|
||||
|
@ -37,11 +37,11 @@ static void quit()
|
|||
{
|
||||
node_stop(node);
|
||||
node_deinit();
|
||||
|
||||
|
||||
list_destroy(&nodes);
|
||||
config_destroy(&config);
|
||||
free(pool);
|
||||
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
|
@ -63,7 +63,7 @@ static void usage(char *name)
|
|||
int main(int argc, char *argv[])
|
||||
{
|
||||
int reverse = 0;
|
||||
|
||||
|
||||
_mtid = pthread_self();
|
||||
|
||||
char c;
|
||||
|
@ -74,7 +74,7 @@ int main(int argc, char *argv[])
|
|||
case '?': usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (argc - optind != 2)
|
||||
usage(argv[0]);
|
||||
|
||||
|
@ -91,14 +91,14 @@ int main(int argc, char *argv[])
|
|||
list_init(&nodes, (dtor_cb_t) node_destroy);
|
||||
config_init(&config);
|
||||
config_parse(argv[optind], &config, &set, &nodes, NULL);
|
||||
|
||||
|
||||
node = node_lookup_name(argv[optind+1], &nodes);
|
||||
if (!node)
|
||||
error("There's no node with the name '%s'", argv[optind+1]);
|
||||
|
||||
if (reverse)
|
||||
node_reverse(node);
|
||||
|
||||
|
||||
node->refcnt++;
|
||||
node->vt->refcnt++;
|
||||
|
||||
|
@ -109,7 +109,7 @@ int main(int argc, char *argv[])
|
|||
node_start(node);
|
||||
|
||||
pool = alloc(sizeof(struct msg) * node->combine);
|
||||
|
||||
|
||||
/* Print header */
|
||||
fprintf(stderr, "# %-20s\t%s\t%s\n", "timestamp", "seqno", "data[]");
|
||||
|
||||
|
@ -118,13 +118,13 @@ int main(int argc, char *argv[])
|
|||
msg_fscan(stdin, &pool[i]);
|
||||
msg_fprint(stdout, &pool[i]);
|
||||
}
|
||||
|
||||
|
||||
node_write(node, pool, node->combine, 0, node->combine);
|
||||
}
|
||||
|
||||
|
||||
quit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** @} */
|
||||
/** @} */
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -49,7 +49,7 @@ static void quit()
|
|||
list_destroy(&paths);
|
||||
list_destroy(&nodes);
|
||||
config_destroy(&config);
|
||||
|
||||
|
||||
info("Goodbye!");
|
||||
|
||||
_exit(EXIT_SUCCESS);
|
||||
|
@ -117,7 +117,7 @@ int main(int argc, char *argv[])
|
|||
if (argc != 2)
|
||||
#endif
|
||||
usage(argv[0]);
|
||||
|
||||
|
||||
char *configfile = (argc == 2) ? argv[1] : "opal-shmem.conf";
|
||||
|
||||
log_reset();
|
||||
|
@ -134,7 +134,7 @@ int main(int argc, char *argv[])
|
|||
/* Initialize lists */
|
||||
list_init(&nodes, (dtor_cb_t) node_destroy);
|
||||
list_init(&paths, (dtor_cb_t) path_destroy);
|
||||
|
||||
|
||||
info("Initialize real-time system");
|
||||
realtime_init();
|
||||
|
||||
|
@ -144,7 +144,7 @@ int main(int argc, char *argv[])
|
|||
info("Parsing configuration");
|
||||
config_init(&config);
|
||||
config_parse(configfile, &config, &settings, &nodes, &paths);
|
||||
|
||||
|
||||
info("Initialize node types");
|
||||
node_init(argc, argv, &settings);
|
||||
|
||||
|
@ -161,7 +161,7 @@ int main(int argc, char *argv[])
|
|||
info("%-32s : %-8s %-8s %-8s %-8s %-8s",
|
||||
"Source " MAG("=>") " Destination", "#Sent", "#Recv", "#Drop", "#Skip", "#Inval");
|
||||
line();
|
||||
|
||||
|
||||
for (;;) FOREACH(&paths, it) {
|
||||
usleep(settings.stats * 1e6);
|
||||
hook_run(it->path, HOOK_PERIODIC);
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <string.h>
|
||||
|
@ -41,7 +41,7 @@ static struct list sockets;
|
|||
int socket_init(int argc, char * argv[], struct settings *set)
|
||||
{ INDENT
|
||||
list_init(&interfaces, (dtor_cb_t) if_destroy);
|
||||
|
||||
|
||||
/* Gather list of used network interfaces */
|
||||
FOREACH(&sockets, it) {
|
||||
struct socket *s = it->socket;
|
||||
|
@ -60,10 +60,10 @@ int socket_init(int argc, char * argv[], struct settings *set)
|
|||
|
||||
list_push(&i->sockets, s);
|
||||
}
|
||||
|
||||
|
||||
FOREACH(&interfaces, it)
|
||||
if_start(it->interface, set->affinity);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -71,9 +71,9 @@ int socket_deinit()
|
|||
{ INDENT
|
||||
FOREACH(&interfaces, it)
|
||||
if_stop(it->interface);
|
||||
|
||||
|
||||
list_destroy(&interfaces);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -83,7 +83,7 @@ int socket_print(struct node *n, char *buf, int len)
|
|||
|
||||
char local[INET6_ADDRSTRLEN + 16];
|
||||
char remote[INET6_ADDRSTRLEN + 16];
|
||||
|
||||
|
||||
socket_print_addr(local, sizeof(local), (struct sockaddr *) &s->local);
|
||||
socket_print_addr(remote, sizeof(remote), (struct sockaddr *) &s->remote);
|
||||
|
||||
|
@ -96,7 +96,7 @@ int socket_open(struct node *n)
|
|||
struct sockaddr_in *sin = (struct sockaddr_in *) &s->local;
|
||||
struct sockaddr_ll *sll = (struct sockaddr_ll *) &s->local;
|
||||
int ret;
|
||||
|
||||
|
||||
/* Create socket */
|
||||
switch (node_type(n)) {
|
||||
case UDP: s->sd = socket(sin->sin_family, SOCK_DGRAM, IPPROTO_UDP); break;
|
||||
|
@ -105,15 +105,15 @@ int socket_open(struct node *n)
|
|||
default:
|
||||
error("Invalid socket type!");
|
||||
}
|
||||
|
||||
|
||||
if (s->sd < 0)
|
||||
serror("Failed to create socket");
|
||||
|
||||
|
||||
/* Bind socket for receiving */
|
||||
ret = bind(s->sd, (struct sockaddr *) &s->local, sizeof(s->local));
|
||||
if (ret < 0)
|
||||
serror("Failed to bind socket");
|
||||
|
||||
|
||||
/* Set fwmark for outgoing packets */
|
||||
if (setsockopt(s->sd, SOL_SOCKET, SO_MARK, &s->mark, sizeof(s->mark)))
|
||||
serror("Failed to set fwmark for outgoing packets");
|
||||
|
@ -140,14 +140,14 @@ int socket_open(struct node *n)
|
|||
debug(4, "Set socket priority for node '%s' to %u", n->name, prio);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int socket_close(struct node *n)
|
||||
{
|
||||
struct socket *s = n->socket;
|
||||
|
||||
|
||||
if (s->sd >= 0)
|
||||
close(s->sd);
|
||||
|
||||
|
@ -167,24 +167,24 @@ int socket_read(struct node *n, struct msg *pool, int poolsize, int first, int c
|
|||
.msg_iov = iov,
|
||||
.msg_iovlen = ARRAY_LEN(iov)
|
||||
};
|
||||
|
||||
|
||||
/* Wait until next packet received */
|
||||
poll(&(struct pollfd) { .fd = s->sd, .events = POLLIN }, 1, -1);
|
||||
/* Get size of received packet in bytes */
|
||||
ioctl(s->sd, FIONREAD, &bytes);
|
||||
|
||||
ioctl(s->sd, FIONREAD, &bytes);
|
||||
|
||||
/* Check packet integrity */
|
||||
if (bytes % (cnt * 4) != 0)
|
||||
error("Packet length not dividable by 4!");
|
||||
if (bytes / cnt > sizeof(struct msg))
|
||||
error("Packet length is too large!");
|
||||
|
||||
|
||||
for (int i = 0; i < cnt; i++) {
|
||||
/* All messages of a packet must have equal length! */
|
||||
iov[i].iov_base = &pool[(first+poolsize+i) % poolsize];
|
||||
iov[i].iov_len = bytes / cnt;
|
||||
}
|
||||
|
||||
|
||||
/* Receive message from socket */
|
||||
int ret = recvmsg(s->sd, &mhdr, 0);
|
||||
if (ret == 0)
|
||||
|
@ -197,10 +197,10 @@ int socket_read(struct node *n, struct msg *pool, int poolsize, int first, int c
|
|||
|
||||
/* Check integrity of packet */
|
||||
bytes -= MSG_LEN(n);
|
||||
|
||||
|
||||
/* Convert headers to host byte order */
|
||||
n->sequence = ntohs(n->sequence);
|
||||
|
||||
|
||||
/* Convert message to host endianess */
|
||||
if (n->endian != MSG_ENDIAN_HOST)
|
||||
msg_swap(n);
|
||||
|
@ -245,7 +245,7 @@ int socket_write(struct node *n, struct msg *pool, int poolsize, int first, int
|
|||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
ret = sendmsg(s->sd, &mhdr, 0);
|
||||
if (ret < 0)
|
||||
serror("Failed send");
|
||||
|
@ -257,7 +257,7 @@ int socket_parse(config_setting_t *cfg, struct node *n)
|
|||
{
|
||||
const char *local, *remote;
|
||||
int ret;
|
||||
|
||||
|
||||
struct socket *s = alloc(sizeof(struct socket));
|
||||
|
||||
if (!config_setting_lookup_string(cfg, "remote", &remote))
|
||||
|
@ -280,12 +280,12 @@ int socket_parse(config_setting_t *cfg, struct node *n)
|
|||
config_setting_t *cfg_netem = config_setting_get_member(cfg, "netem");
|
||||
if (cfg_netem) {
|
||||
s->netem = alloc(sizeof(struct netem));
|
||||
|
||||
|
||||
tc_parse(cfg_netem, s->netem);
|
||||
}
|
||||
|
||||
|
||||
n->socket = s;
|
||||
|
||||
|
||||
list_push(&sockets, s);
|
||||
|
||||
return 0;
|
||||
|
@ -304,7 +304,7 @@ int socket_print_addr(char *buf, int len, struct sockaddr *sa)
|
|||
struct sockaddr_ll *sll = (struct sockaddr_ll *) sa;
|
||||
char ifname[IF_NAMESIZE];
|
||||
|
||||
return snprintf(buf, len, "%s%%%s:%#hx",
|
||||
return snprintf(buf, len, "%s%%%s:%#hx",
|
||||
ether_ntoa((struct ether_addr *) &sll->sll_addr),
|
||||
if_indextoname(sll->sll_ifindex, ifname),
|
||||
ntohs(sll->sll_protocol));
|
||||
|
@ -313,7 +313,7 @@ int socket_print_addr(char *buf, int len, struct sockaddr *sa)
|
|||
default:
|
||||
return snprintf(buf, len, "address family: %u", sa->sa_family);
|
||||
}
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -323,8 +323,8 @@ int socket_parse_addr(const char *addr, struct sockaddr *sa, enum node_type type
|
|||
|
||||
char *copy = strdup(addr);
|
||||
int ret;
|
||||
|
||||
if (type == IEEE_802_3) { /* Format: "ab:cd:ef:12:34:56%ifname:protocol" */
|
||||
|
||||
if (layer == LAYER_ETH) { /* Format: "ab:cd:ef:12:34:56%ifname:protocol" */
|
||||
struct sockaddr_ll *sll = (struct sockaddr_ll *) sa;
|
||||
|
||||
/* Split string */
|
||||
|
@ -351,7 +351,7 @@ int socket_parse_addr(const char *addr, struct sockaddr *sa, enum node_type type
|
|||
.ai_flags = flags,
|
||||
.ai_family = AF_INET
|
||||
};
|
||||
|
||||
|
||||
/* Split string */
|
||||
char *node = strtok(copy, ":");
|
||||
char *service = strtok(NULL, "\0");
|
||||
|
@ -388,13 +388,13 @@ int socket_parse_addr(const char *addr, struct sockaddr *sa, enum node_type type
|
|||
struct sockaddr_in *sin = (struct sockaddr_in *) result->ai_addr;
|
||||
sin->sin_port = htons(result->ai_protocol);
|
||||
}
|
||||
|
||||
memcpy(sa, result->ai_addr, result->ai_addrlen);
|
||||
|
||||
|
||||
memcpy(sa, result->ai_addr, result->ai_addrlen);
|
||||
|
||||
freeaddrinfo(result);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
free(copy);
|
||||
|
||||
return ret;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include "stats.h"
|
||||
|
@ -16,7 +16,7 @@ int stats_line(struct path *p)
|
|||
{
|
||||
char buf[33];
|
||||
path_print(p, buf, sizeof(buf));
|
||||
|
||||
|
||||
info("%-32s : %-8u %-8u %-8u %-8u %-8u", buf,
|
||||
p->sent, p->received, p->dropped, p->skipped, p->invalid);
|
||||
|
||||
|
@ -28,7 +28,7 @@ int stats_show(struct path *p)
|
|||
if (p->hist_delay.length) { info("One-way delay:"); hist_print(&p->hist_delay); }
|
||||
if (p->hist_gap.length) { info("Message gap time:"); hist_print(&p->hist_gap); }
|
||||
if (p->hist_sequence.length) { info("Sequence number gaps:"); hist_print(&p->hist_sequence); }
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -39,10 +39,10 @@ int stats_collect(struct path *p)
|
|||
struct timespec ts1 = MSG_TS(p->current);
|
||||
struct timespec ts2 = MSG_TS(p->previous);
|
||||
|
||||
hist_put(&p->hist_sequence, dist);
|
||||
hist_put(&p->hist_sequence, dist);
|
||||
hist_put(&p->hist_delay, time_delta(&ts1, &p->ts_recv));
|
||||
hist_put(&p->hist_gap, time_delta(&ts2, &ts1));
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -52,7 +52,7 @@ int stats_start(struct path *p)
|
|||
hist_create(&p->hist_sequence, -HIST_SEQ, +HIST_SEQ, 1);
|
||||
hist_create(&p->hist_delay, 0, 2, 100e-3);
|
||||
hist_create(&p->hist_gap, 0, 40e-3, 1e-3);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -61,7 +61,7 @@ int stats_stop(struct path *p)
|
|||
hist_destroy(&p->hist_sequence);
|
||||
hist_destroy(&p->hist_delay);
|
||||
hist_destroy(&p->hist_gap);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -70,6 +70,6 @@ int stats_reset(struct path *p)
|
|||
hist_reset(&p->hist_sequence);
|
||||
hist_reset(&p->hist_delay);
|
||||
hist_reset(&p->hist_gap);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include "utils.h"
|
||||
|
@ -43,7 +43,7 @@ int tc_reset(struct interface *i)
|
|||
|
||||
if (system2(cmd))
|
||||
error("Failed to add reset traffic control for interface '%s'", i->name);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -64,7 +64,7 @@ int tc_prio(struct interface *i, tc_hdl_t handle, int bands)
|
|||
|
||||
if (system2(cmd))
|
||||
error("Failed to add prio qdisc for interface '%s'", i->name);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -61,7 +61,7 @@ void quit()
|
|||
int main(int argc, char *argv[])
|
||||
{
|
||||
config_t config;
|
||||
|
||||
|
||||
_mtid = pthread_self();
|
||||
|
||||
if (argc < 4) {
|
||||
|
@ -90,7 +90,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
config_init(&config);
|
||||
config_parse(argv[1], &config, &settings, &nodes, NULL);
|
||||
|
||||
|
||||
node = node_lookup_name(argv[3], &nodes);
|
||||
if (!node)
|
||||
error("There's no node with the name '%s'", argv[3]);
|
||||
|
@ -100,7 +100,7 @@ int main(int argc, char *argv[])
|
|||
|
||||
node_init(argc-3, argv+3, &settings);
|
||||
node_start(node);
|
||||
|
||||
|
||||
/* Parse Arguments */
|
||||
char c, *endptr;
|
||||
while ((c = getopt (argc-3, argv+3, "l:h:r:f:c:")) != -1) {
|
||||
|
@ -131,7 +131,7 @@ int main(int argc, char *argv[])
|
|||
default:
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
continue;
|
||||
check:
|
||||
if (optarg == endptr)
|
||||
|
@ -152,7 +152,7 @@ check:
|
|||
|
||||
void test_rtt() {
|
||||
struct msg m = MSG_INIT(sizeof(struct timespec) / sizeof(float));
|
||||
|
||||
|
||||
struct timespec ts;
|
||||
struct timespec *ts1 = (struct timespec *) &m.data;
|
||||
struct timespec *ts2 = alloc(sizeof(struct timespec));
|
||||
|
@ -174,7 +174,7 @@ void test_rtt() {
|
|||
|
||||
if (rtt < 0)
|
||||
warn("Negative RTT: %f", rtt);
|
||||
|
||||
|
||||
hist_put(&hist, rtt);
|
||||
|
||||
clock_gettime(CLOCK_REALTIME, &ts);
|
||||
|
@ -191,7 +191,7 @@ void test_rtt() {
|
|||
free(ts2);
|
||||
|
||||
hist_print(&hist);
|
||||
|
||||
|
||||
struct stat st;
|
||||
if (!fstat(fd, &st)) {
|
||||
FILE *f = fdopen(fd, "w");
|
||||
|
@ -199,6 +199,6 @@ void test_rtt() {
|
|||
}
|
||||
else
|
||||
error("Invalid file descriptor: %u", fd);
|
||||
|
||||
|
||||
hist_destroy(&hist);
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <unistd.h>
|
||||
|
@ -14,7 +14,7 @@
|
|||
uint64_t timerfd_wait(int fd)
|
||||
{
|
||||
uint64_t runs;
|
||||
|
||||
|
||||
return read(fd, &runs, sizeof(runs)) < 0 ? 0 : runs;
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@ uint64_t timerfd_wait_until(int fd, struct timespec *until)
|
|||
struct itimerspec its = {
|
||||
.it_value = *until
|
||||
};
|
||||
|
||||
|
||||
if (timerfd_settime(fd, TFD_TIMER_ABSTIME, &its, NULL))
|
||||
return 0;
|
||||
else
|
||||
|
@ -41,7 +41,7 @@ struct timespec time_add(struct timespec *start, struct timespec *end)
|
|||
sum.tv_sec += 1;
|
||||
sum.tv_nsec -= 1000000000;
|
||||
}
|
||||
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
|
@ -56,14 +56,14 @@ struct timespec time_diff(struct timespec *start, struct timespec *end)
|
|||
diff.tv_sec -= 1;
|
||||
diff.tv_nsec += 1000000000;
|
||||
}
|
||||
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
struct timespec time_from_double(double secs)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
|
||||
ts.tv_sec = secs;
|
||||
ts.tv_nsec = 1.0e9 * (secs - ts.tv_sec);
|
||||
|
||||
|
@ -78,7 +78,7 @@ double time_to_double(struct timespec *ts)
|
|||
double time_delta(struct timespec *start, struct timespec *end)
|
||||
{
|
||||
struct timespec diff = time_diff(start, end);
|
||||
|
||||
|
||||
return time_to_double(&diff);
|
||||
}
|
||||
|
||||
|
@ -90,4 +90,4 @@ int time_fscan(FILE *f, struct timespec *ts)
|
|||
int time_fprint(FILE *f, struct timespec *ts)
|
||||
{
|
||||
return fprintf(f, "%lu.%09lu\t", ts->tv_sec, ts->tv_nsec);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
||||
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
||||
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
||||
*********************************************************************************/
|
||||
|
||||
#include <stdarg.h>
|
||||
|
@ -67,12 +67,12 @@ void die()
|
|||
int strap(char *dest, size_t size, const char *fmt, ...)
|
||||
{
|
||||
int ret;
|
||||
|
||||
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
ret = vstrap(dest, size, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -104,7 +104,7 @@ void * alloc(size_t bytes)
|
|||
error("Failed to allocate memory");
|
||||
|
||||
memset(p, 0, bytes);
|
||||
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
|
@ -113,13 +113,13 @@ int system2(const char *cmd, ...)
|
|||
{
|
||||
va_list ap;
|
||||
char buf[1024];
|
||||
|
||||
|
||||
va_start(ap, cmd);
|
||||
vsnprintf(buf, sizeof(buf), cmd, ap);
|
||||
va_end(ap);
|
||||
|
||||
|
||||
strap(buf, sizeof(buf), " 2>&1", sizeof(buf)); /* redirect stderr to stdout */
|
||||
|
||||
|
||||
debug(1, "System: %s", buf);
|
||||
|
||||
FILE *f = popen(buf, "r");
|
||||
|
|
Loading…
Add table
Reference in a new issue