summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cethcan/.gitignore2
-rw-r--r--cethcan/Makefile14
-rw-r--r--cethcan/can.c46
-rw-r--r--cethcan/cethcan.h60
-rw-r--r--cethcan/main.c45
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;
+}