2014-08-31 14:43:28 +00:00
|
|
|
/** Hook funktions
|
|
|
|
*
|
2015-06-10 15:10:51 +02:00
|
|
|
* Every path can register hook functions which are called at specific events.
|
|
|
|
* A list of supported events is described by enum hook_flags.
|
|
|
|
* Please note that there are several hook callbacks which are hard coded into path_create().
|
2014-08-31 14:43:28 +00:00
|
|
|
*
|
|
|
|
* This file includes some examples.
|
|
|
|
*
|
|
|
|
* @author Steffen Vogel <stvogel@eonerc.rwth-aachen.de>
|
2015-06-02 21:53:04 +02:00
|
|
|
* @copyright 2014-2015, Institute for Automation of Complex Power Systems, EONERC
|
|
|
|
* This file is part of S2SS. All Rights Reserved. Proprietary and confidential.
|
2015-08-07 01:11:43 +02:00
|
|
|
* Unauthorized copying of this file, via any medium is strictly prohibited.
|
2015-06-02 21:53:04 +02:00
|
|
|
*********************************************************************************/
|
2015-03-18 16:13:18 +01:00
|
|
|
|
2014-08-31 14:43:28 +00:00
|
|
|
#include <string.h>
|
|
|
|
|
2015-06-10 15:05:36 +02:00
|
|
|
#include "timing.h"
|
2015-05-06 11:38:57 +02:00
|
|
|
#include "config.h"
|
2014-08-31 14:43:28 +00:00
|
|
|
#include "msg.h"
|
|
|
|
#include "hooks.h"
|
2015-03-18 16:13:18 +01:00
|
|
|
#include "path.h"
|
|
|
|
#include "utils.h"
|
2014-08-31 14:43:28 +00:00
|
|
|
|
2015-06-10 15:10:51 +02:00
|
|
|
/* Some hooks can be configured by constants in te file "config.h" */
|
|
|
|
|
2015-09-19 15:26:30 +02:00
|
|
|
struct list hooks;
|
2015-08-07 01:11:43 +02:00
|
|
|
|
2015-09-19 15:26:30 +02:00
|
|
|
REGISTER_HOOK("print", 99, hook_print, HOOK_MSG)
|
2015-06-10 15:10:51 +02:00
|
|
|
int hook_print(struct path *p)
|
2014-08-31 14:43:28 +00:00
|
|
|
{
|
2015-06-10 15:05:36 +02:00
|
|
|
struct msg *m = p->current;
|
|
|
|
struct timespec ts = MSG_TS(m);
|
2015-08-07 01:11:43 +02:00
|
|
|
|
2015-06-10 15:05:36 +02:00
|
|
|
fprintf(stdout, "%.3e+", time_delta(&ts, &p->ts_recv)); /* Print delay */
|
2014-08-31 14:43:28 +00:00
|
|
|
msg_fprint(stdout, m);
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-09-19 15:26:30 +02:00
|
|
|
REGISTER_HOOK("tofixed", 99, hook_tofixed, HOOK_MSG)
|
2015-06-10 15:10:51 +02:00
|
|
|
int hook_tofixed(struct path *p)
|
2014-08-31 14:43:28 +00:00
|
|
|
{
|
2015-06-10 15:10:51 +02:00
|
|
|
struct msg *m = p->current;
|
|
|
|
|
2015-09-19 12:24:11 +02:00
|
|
|
for (int i = 0; i < m->length; i++)
|
2015-08-07 01:11:43 +02:00
|
|
|
m->data[i].i = m->data[i].f * 1e3;
|
|
|
|
|
2014-08-31 14:43:28 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-09-19 15:26:30 +02:00
|
|
|
REGISTER_HOOK("ts", 99, hook_ts, HOOK_MSG)
|
2015-06-10 15:10:51 +02:00
|
|
|
int hook_ts(struct path *p)
|
2015-03-18 16:13:18 +01:00
|
|
|
{
|
2015-06-10 15:05:36 +02:00
|
|
|
struct msg *m = p->current;
|
|
|
|
|
|
|
|
m->ts.sec = p->ts_recv.tv_sec;
|
|
|
|
m->ts.nsec = p->ts_recv.tv_nsec;
|
2015-08-07 01:11:43 +02:00
|
|
|
|
2015-03-18 16:13:18 +01:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2015-09-19 15:26:30 +02:00
|
|
|
REGISTER_HOOK("fir", 99, hook_fir, HOOK_POST)
|
2015-06-10 15:10:51 +02:00
|
|
|
int hook_fir(struct path *p)
|
2014-08-31 14:43:28 +00:00
|
|
|
{
|
2015-04-01 13:27:10 +02:00
|
|
|
/** Simple FIR-LP: F_s = 1kHz, F_pass = 100 Hz, F_block = 300
|
|
|
|
* Tip: Use MATLAB's filter design tool and export coefficients
|
2015-08-07 01:11:43 +02:00
|
|
|
* with the integrated C-Header export */
|
2015-04-01 13:27:10 +02:00
|
|
|
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 };
|
2015-08-07 01:11:43 +02:00
|
|
|
|
2015-03-18 16:13:18 +01:00
|
|
|
/* Accumulator */
|
|
|
|
double sum = 0;
|
2015-08-07 01:11:43 +02:00
|
|
|
|
2015-04-01 13:27:10 +02:00
|
|
|
/** Trim FIR length to length of history buffer */
|
2015-05-06 11:38:57 +02:00
|
|
|
int len = MIN(ARRAY_LEN(coeffs), p->poolsize);
|
2015-04-01 13:27:10 +02:00
|
|
|
|
2015-09-19 12:24:11 +02:00
|
|
|
for (int i = 0; i < len; i++) {
|
2015-05-06 11:38:57 +02:00
|
|
|
struct msg *old = &p->pool[(p->poolsize+p->received-i) % p->poolsize];
|
2015-08-07 01:11:43 +02:00
|
|
|
|
2015-04-01 13:27:10 +02:00
|
|
|
sum += coeffs[i] * old->data[HOOK_FIR_INDEX].f;
|
2015-03-18 16:13:18 +01:00
|
|
|
}
|
|
|
|
|
2015-06-10 15:10:51 +02:00
|
|
|
p->current->data[HOOK_FIR_INDEX].f = sum;
|
2015-03-18 16:13:18 +01:00
|
|
|
|
|
|
|
return 0;
|
2014-08-31 14:43:28 +00:00
|
|
|
}
|
2015-04-01 14:27:52 +02:00
|
|
|
|
2015-09-19 15:26:30 +02:00
|
|
|
REGISTER_HOOK("decimate", 99, hook_decimate, HOOK_POST)
|
2015-06-10 15:10:51 +02:00
|
|
|
int hook_decimate(struct path *p)
|
2015-04-01 14:27:52 +02:00
|
|
|
{
|
2015-05-06 13:20:18 +02:00
|
|
|
/* Only sent every HOOK_DECIMATE_RATIO'th message */
|
2015-06-10 15:10:51 +02:00
|
|
|
return p->received % HOOK_DECIMATE_RATIO;
|
2015-04-01 14:27:52 +02:00
|
|
|
}
|
|
|
|
|
2015-09-19 15:26:30 +02:00
|
|
|
REGISTER_HOOK("dft", 99, hook_dft, HOOK_POST)
|
2015-06-10 15:10:51 +02:00
|
|
|
int hook_dft(struct path *p)
|
|
|
|
{
|
2015-09-19 12:24:11 +02:00
|
|
|
return 0; /** @todo Implement */
|
2015-06-10 15:10:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/** System hooks */
|
|
|
|
|
|
|
|
int hook_restart(struct path *p)
|
|
|
|
{
|
|
|
|
if (p->current->sequence == 0 &&
|
|
|
|
p->previous->sequence <= UINT32_MAX - 32) {
|
|
|
|
char buf[33];
|
|
|
|
path_print(p, buf, sizeof(buf));
|
|
|
|
warn("Simulation for path %s restarted (prev->seq=%u, current->seq=%u)",
|
|
|
|
buf, p->previous->sequence, p->current->sequence);
|
|
|
|
|
|
|
|
path_reset(p);
|
|
|
|
}
|
2015-08-07 01:11:43 +02:00
|
|
|
|
2015-06-10 15:10:51 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int hook_verify(struct path *p)
|
2015-04-01 14:27:52 +02:00
|
|
|
{
|
2015-06-10 15:10:51 +02:00
|
|
|
int reason = msg_verify(p->current);
|
|
|
|
if (reason) {
|
|
|
|
p->invalid++;
|
|
|
|
warn("Received invalid message (reason=%d)", reason);
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
}
|
2015-08-07 01:11:43 +02:00
|
|
|
|
2015-05-06 11:38:57 +02:00
|
|
|
return 0;
|
2015-06-10 15:10:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int hook_drop(struct path *p)
|
|
|
|
{
|
|
|
|
int dist = p->current->sequence - (int32_t) p->previous->sequence;
|
|
|
|
if (dist <= 0 && p->received > 1) {
|
|
|
|
p->dropped++;
|
|
|
|
return -1;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return 0;
|
2015-08-07 01:11:43 +02:00
|
|
|
}
|