From f7b70b9eec8c8648c7f4a165361c9b7010f6759f Mon Sep 17 00:00:00 2001 From: kivkiv12345 Date: Tue, 4 Nov 2025 21:00:32 +0100 Subject: [PATCH] Added functions to register callbacks to the `param_sniffer()` --- src/param_sniffer.c | 49 +++++++++++++++++++++++++++++++++++++++++++++ src/param_sniffer.h | 14 +++++++++++++ 2 files changed, 63 insertions(+) diff --git a/src/param_sniffer.c b/src/param_sniffer.c index 6907cb1b..6f23d74f 100644 --- a/src/param_sniffer.c +++ b/src/param_sniffer.c @@ -5,9 +5,12 @@ * Author: johan */ +#include "param_sniffer.h" + #include #include #include +#include #include #include #include @@ -141,6 +144,51 @@ int param_sniffer_crc(csp_packet_t * packet) { return 0; } +/* The intention here is to hide the `SLIST` usage behind the `register` and `unregister` API, + so we could change to a statically allocated array instead if desired. */ +typedef struct param_sniffer_callback_s { + param_sniffer_callback_f callback; + void *context; + SLIST_ENTRY(param_sniffer_callback_s) next; +} param_sniffer_callback_t; +static SLIST_HEAD( sniffer_callbacks_head_s, param_sniffer_callback_s ) sniffer_callbacks_head = SLIST_HEAD_INITIALIZER(sniffer_callbacks_head); + +int param_sniffer_register_callback(param_sniffer_callback_f callback, void * context) { + + /* TODO Kevin: What about registering the same callback multiple times? What if it has different contexts? */ + param_sniffer_callback_t * slist_entry = calloc(1, sizeof(*slist_entry)); + slist_entry->callback = callback; + slist_entry->context = context; + SLIST_INSERT_HEAD(&sniffer_callbacks_head, slist_entry, next); + + return 0; +} + +int param_sniffer_unregister_callback(param_sniffer_callback_f callback) { + + param_sniffer_callback_t *callback_entry = NULL; + param_sniffer_callback_t *prev_entry = (param_sniffer_callback_t*)&sniffer_callbacks_head; + + SLIST_FOREACH(callback_entry, &sniffer_callbacks_head, next) { + + if (callback_entry->callback == callback) { + //SLIST_REMOVE_PREVPTR(&prev_entry, callback_entry, next); + SLIST_REMOVE(&sniffer_callbacks_head, callback_entry, param_sniffer_callback_s, next); + } + prev_entry = callback_entry; + } + + return 0; +} + +static void param_sniffer_call_callbacks(param_t * param) { + param_sniffer_callback_t *callback_entry = NULL; + + SLIST_FOREACH(callback_entry, &sniffer_callbacks_head, next) { + callback_entry->callback(param, callback_entry->context); + } +} + static void * param_sniffer(void * param) { csp_promisc_enable(100); while(1) { @@ -200,6 +248,7 @@ static void * param_sniffer(void * param) { param_t * param = param_list_find_id(node, id); if (param) { param_sniffer_log(NULL, &queue, param, offset, &reader, ×tamp); + param_sniffer_call_callbacks(param); } else { printf("Found unknown param node %d id %d\n", node, id); mpack_discard(&reader); diff --git a/src/param_sniffer.h b/src/param_sniffer.h index 46c39b31..ff6b67e7 100644 --- a/src/param_sniffer.h +++ b/src/param_sniffer.h @@ -9,9 +9,23 @@ #define SRC_PARAM_SNIFFER_H_ #include +#include +#include int param_sniffer_crc(csp_packet_t * packet); int param_sniffer_log(void * ctx, param_queue_t *queue, param_t *param, int offset, void *reader, csp_timestamp_t *timestamp); void param_sniffer_init(int add_logfile); +/* TODO Kevin: We should probably pass along `*queue`, `offset` and `*timestamp` as well. */ +typedef void (*param_sniffer_callback_f)(param_t * param, void * context); +/** + * @brief Register a function to be called when a parameter is sniffed and deserialized from the network. + * + * @param callback[in] Callback function to call whenever a decoding error is encountered. + * @param context[in] User-supplied context for the callback function. Must remain valid for as long as the function is registered (is not copied). + * @return int 0 OK, <0 ERROR + */ +int param_sniffer_register_callback(param_sniffer_callback_f callback, void * context); +int param_sniffer_unregister_callback(param_sniffer_callback_f callback); + #endif /* SRC_PARAM_SNIFFER_H_ */