diff options
-rw-r--r-- | cethcan/.gitignore | 2 | ||||
-rw-r--r-- | cethcan/Makefile | 14 | ||||
-rw-r--r-- | cethcan/can.c | 46 | ||||
-rw-r--r-- | cethcan/cethcan.h | 60 | ||||
-rw-r--r-- | cethcan/main.c | 45 |
5 files changed, 167 insertions, 0 deletions
diff --git a/cethcan/.gitignore b/cethcan/.gitignore new file mode 100644 index 0000000..35ab3a7 --- /dev/null +++ b/cethcan/.gitignore @@ -0,0 +1,2 @@ +*.o +cethcan diff --git a/cethcan/Makefile b/cethcan/Makefile new file mode 100644 index 0000000..33b2069 --- /dev/null +++ b/cethcan/Makefile @@ -0,0 +1,14 @@ +love: cethcan +.PHONY: love + +PKGS="libevent jansson" + +cethcan: main.o can.o + gcc -g -o $@ `pkg-config --libs $(PKGS)` $^ + +clean: + rm -f *.o *.y.c *.y.h *.l.c cethcan + +%.o: %.c *.h + gcc -c -g -O0 -Wall -Wextra -Wshadow -pedantic -Wno-unused-parameter -Wno-format -std=gnu99 `pkg-config --cflags $(PKGS)` -o $@ $< + diff --git a/cethcan/can.c b/cethcan/can.c new file mode 100644 index 0000000..be8c635 --- /dev/null +++ b/cethcan/can.c @@ -0,0 +1,46 @@ +#include "cethcan.h" + +static struct can_user *users = NULL, **userlast = &users; + +void can_register(struct can_user *user) +{ + user->next = NULL; + *userlast = user; + userlast = &user->next; +} + +struct can_user *can_register_alloc(void *arg, can_handler handler, + const char *fmt, ...) +{ + struct can_user *user; + char *name = NULL; + va_list ap; + + va_start(ap, fmt); + vasprintf(&name, fmt, ap); + va_end(ap); + + user = calloc(sizeof(*user), 1); + user->arg = arg; + user->handler = handler; + user->name = name; + + can_register(user); + return user; +} + +void can_broadcast(struct can_user *origin, struct can_message *msg) +{ + struct can_user *u; + + msg->origin = origin; + for (u = users; u; u = u->next) + if (u != origin) + u->handler(u->arg, msg); +} + +void can_init(void) +{ + /* nothing to do */ +} + diff --git a/cethcan/cethcan.h b/cethcan/cethcan.h new file mode 100644 index 0000000..1ac898f --- /dev/null +++ b/cethcan/cethcan.h @@ -0,0 +1,60 @@ +#ifndef _CETHCAN_H +#define _CETHCAN_H + +#define _GNU_SOURCE + +#include <stdlib.h> +#include <stdint.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdarg.h> +#include <string.h> +#include <errno.h> +#include <unistd.h> +#include <ctype.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <sys/mman.h> +#include <sys/uio.h> +#include <fcntl.h> +#include <time.h> +#include <assert.h> + +#include <event2/event.h> +#include <jansson.h> + +extern struct event_base *ev_base; +extern json_t *config; + +struct can_user; + +struct can_message { + struct can_user *origin; + + uint32_t daddr; + + uint32_t flags; +#define CAN_MSGF_RTR (1 << 0) + + size_t dlc; + uint8_t bytes[8]; +}; + +typedef void (*can_handler)(void *arg, struct can_message *msg); + +struct can_user { + struct can_user *next; + + const char *name; + + void *arg; + can_handler handler; +}; + +extern void can_register(struct can_user *user); +extern struct can_user *can_register_alloc(void *arg, can_handler handler, + const char *fmt, ...); +extern void can_broadcast(struct can_user *origin, struct can_message *msg); +extern void can_init(void); + +#endif /* _CETHCAN_H */ diff --git a/cethcan/main.c b/cethcan/main.c new file mode 100644 index 0000000..938721e --- /dev/null +++ b/cethcan/main.c @@ -0,0 +1,45 @@ +#include "cethcan.h" + +struct event_base *ev_base; +json_t *config; + +int main(int argc, char **argv) +{ + int optch = 0; + const char *cfgfile = "cethcan.json"; + json_error_t je; + + do { + optch = getopt(argc, argv, "c:"); + switch (optch) { + case 'c': + cfgfile = optarg; + break; + case -1: + break; + } + } while (optch != -1); + + if (optind < argc) { + fprintf(stderr, "leftover arguments\n"); + return 1; + } + + config = json_load_file(cfgfile, JSON_REJECT_DUPLICATES, &je); + if (!config) { + fprintf(stderr, "failed to load config:\n%s:%d:%d %s\n", + je.source, je.line, je.column, je.text); + return 1; + } + if (!json_is_object(config)) { + fprintf(stderr, "config must be object/dictionary\n"); + return 1; + } + + ev_base = event_base_new(); + + can_init(); + + event_base_loop(ev_base, 0); + return 0; +} |