Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions src/param_sniffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@
* Author: johan
*/

#include "param_sniffer.h"

#include <stdio.h>
#include <sys/time.h>
#include <pthread.h>
#include <sys/queue.h>
#include <param/param_server.h>
#include <param/param_queue.h>
#include <param/param_serializer.h>
Expand Down Expand Up @@ -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? */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about that ? This is a way for users of this API to register things, we can't be responsible for what they actually register, can we ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left that comment wondering how I should handle it in param_sniffer_UNregister_callback(). Do we unregister all callbacks to that function, or only the first match?
Do we error if that function is already registered?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A solution would be to update the
int param_sniffer_unregister_callback(param_sniffer_callback_f callback)
to:
int param_sniffer_unregister_callback(param_sniffer_callback_f callback, void * context)
and then test for both the callbackand contextto find the correct element to unregister...

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) {
Expand Down Expand Up @@ -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, &timestamp);
param_sniffer_call_callbacks(param);
} else {
printf("Found unknown param node %d id %d\n", node, id);
mpack_discard(&reader);
Expand Down
14 changes: 14 additions & 0 deletions src/param_sniffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,23 @@
#define SRC_PARAM_SNIFFER_H_

#include <csp/csp.h>
#include <param/param.h>
#include <param/param_queue.h>

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. */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we "probably should", why not do it ? :)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I take it you agree then? I will do it!

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_ */