diff --git a/server/include/config.h b/server/include/config.h index 5dec0bcd8..bbd2094f5 100644 --- a/server/include/config.h +++ b/server/include/config.h @@ -53,10 +53,12 @@ { "/dev/sda2", "\x53\xf6\xb5\xeb\x8b\x16\x46\xdc\x8d\x8f\x5b\x70\xb8\xc9\x1a\x2a", 0x468 } } /* Hook function configuration */ -#define HOOK_FIR_INDEX 1 /**< The first value of message should be filtered. */ -#define HOOK_TS_INDEX -1 /**< The last value of message should be overwritten by a timestamp. */ -#define HOOK_DECIMATE_RATIO 30 /**< Only forward every 30th message to the destination nodes. */ +#define HOOK_FIR_INDEX 1 /**< The first value of message should be filtered. */ +#define HOOK_TS_INDEX -1 /**< The last value of message should be overwritten by a timestamp. */ +#define HOOK_DECIMATE_RATIO 30 /**< Only forward every 30th message to the destination nodes. */ +#define HOOK_DEDUP_TYPE HOOK_ASYNC +#define HOOK_DEDUP_TRESH 1e-3 /**< Do not send messages when difference of values to last message is smaller than this threshold */ /** Global configuration */ struct settings { /** Process priority (lower is better) */ diff --git a/server/include/hooks.h b/server/include/hooks.h index 8cc8094ae..b54e11f82 100644 --- a/server/include/hooks.h +++ b/server/include/hooks.h @@ -76,6 +76,9 @@ struct hook { * @{ */ +/** Example hook: Drop messages whose values are similiar to the previous ones */ +int hook_deduplicate(struct path *); + /** Example hook: Print the message. */ int hook_print(struct path *p); diff --git a/server/src/hooks.c b/server/src/hooks.c index 733d2ba9b..8647c48c7 100644 --- a/server/src/hooks.c +++ b/server/src/hooks.c @@ -13,6 +13,7 @@ *********************************************************************************/ #include +#include #include "timing.h" #include "config.h" @@ -25,6 +26,33 @@ struct list hooks; +REGISTER_HOOK("deduplicate", 99, hook_deduplicate, HOOK_DEDUP_TYPE) +int hook_deduplicate(struct path *p) +{ + int ret = 0; +#if HOOK_DEDUP_TYPE == HOOK_ASYNC + /** Thread local storage (TLS) is used to maintain a copy of the last run of the hook */ + static __thread struct msg previous = MSG_INIT(0); + struct msg *prev = &previous; +#else + struct msg *prev = p->previous; +#endif + struct msg *cur = p->current; + + for (int i = 0; i < MIN(cur->length, prev->length); i++) { + if (fabs(cur->data[i].f - prev->data[i].f) > HOOK_DEDUP_TRESH) + goto out; + } + + ret = -1; /* no appreciable change in values, we will drop the packet */ + +out: +#if HOOK_DEDUP_TYPE == HOOK_ASYNC + memcpy(prev, cur, sizeof(struct msg)); /* save current message for next run */ +#endif + return ret; +} + REGISTER_HOOK("print", 99, hook_print, HOOK_MSG) int hook_print(struct path *p) {