summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lamparter <equinox@diac24.net>2013-03-25 23:01:50 +0100
committerDavid Lamparter <equinox@diac24.net>2013-03-25 23:01:50 +0100
commit1b5e4f4ba195ad4ed02cfac6129c386c4aeaf7cd (patch)
tree585729717365831250afc150b95f51809d1330f5
parent2de09bbd1dc380734946b2389f1177f48ae0b4e5 (diff)
cethcan: more code
-rw-r--r--cethcan/Makefile2
-rw-r--r--cethcan/cethcan.h3
-rw-r--r--cethcan/light.c69
-rw-r--r--cethcan/main.c9
-rw-r--r--cethcan/protocol.h24
5 files changed, 105 insertions, 2 deletions
diff --git a/cethcan/Makefile b/cethcan/Makefile
index a81124c..f0d5d4b 100644
--- a/cethcan/Makefile
+++ b/cethcan/Makefile
@@ -3,7 +3,7 @@ love: cethcan
PKGS="libevent jansson"
-cethcan: main.o can.o ether.o
+cethcan: main.o can.o ether.o light.o
gcc -g -o $@ `pkg-config --libs $(PKGS)` $^
clean:
diff --git a/cethcan/cethcan.h b/cethcan/cethcan.h
index 477221e..292b5c9 100644
--- a/cethcan/cethcan.h
+++ b/cethcan/cethcan.h
@@ -23,6 +23,8 @@
#include <event2/event.h>
#include <jansson.h>
+#include "protocol.h"
+
#define lprintf(...) do { \
struct timeval tv; struct tm tm; char tvbuf[64]; \
gettimeofday(&tv, NULL); localtime_r(&tv.tv_sec, &tm); \
@@ -66,5 +68,6 @@ extern void can_broadcast(struct can_user *origin, struct can_message *msg);
extern void can_init(void);
extern int ether_init(json_t *config);
+extern int light_init_conf(json_t *config);
#endif /* _CETHCAN_H */
diff --git a/cethcan/light.c b/cethcan/light.c
new file mode 100644
index 0000000..2bc6b2f
--- /dev/null
+++ b/cethcan/light.c
@@ -0,0 +1,69 @@
+#include "cethcan.h"
+
+struct value {
+ uint8_t val;
+ time_t change, valid;
+};
+
+struct light {
+ struct can_user *u;
+
+ char *name;
+ unsigned logical_addr;
+
+ struct value set, actual;
+};
+
+static void light_can_handler(void *arg, struct can_message *msg)
+{
+ struct light *l = arg;
+ struct value *v = NULL;
+ unsigned laddr;
+ uint8_t dval;
+
+ if ((msg->daddr & CANA_PROTOCOL) == CANA_LIGHT)
+ v = &l->set;
+ if ((msg->daddr & CANA_PROTOCOL) == CANA_SENSOR)
+ v = &l->actual;
+ if (!v)
+ return;
+
+ laddr = msg->daddr & 0xfff;
+ if (l->logical_addr < laddr)
+ return;
+ if (l->logical_addr - laddr >= msg->dlc)
+ return;
+ dval = msg->bytes[l->logical_addr - laddr];
+
+ time(&v->valid);
+ if (dval != v->val || v->change == 0) {
+ v->val = dval;
+ time(&v->change);
+ lprintf("%s: set %02x", l->u->name, dval);
+ }
+}
+
+int light_init_conf(json_t *config)
+{
+ struct light *l;
+
+ if (!json_is_object(config)) {
+ lprintf("light config must be an object/dictionary");
+ return 1;
+ }
+ if (!json_is_integer(json_object_get(config, "addr"))) {
+ lprintf("light config must have an 'addr' key");
+ return 1;
+ }
+ if (!json_is_string(json_object_get(config, "name"))) {
+ lprintf("light config must have a 'name' key");
+ return 1;
+ }
+
+ l = calloc(sizeof(*l), 1);
+ l->name = strdup(json_string_value(json_object_get(config, "name")));
+ l->logical_addr = json_integer_value(json_object_get(config, "addr"));
+
+ l->u = can_register_alloc(l, light_can_handler, "light[%s]", l->name);
+ return 0;
+}
diff --git a/cethcan/main.c b/cethcan/main.c
index 6d79a9f..0794254 100644
--- a/cethcan/main.c
+++ b/cethcan/main.c
@@ -7,7 +7,7 @@ int main(int argc, char **argv)
int optch = 0;
const char *cfgfile = "cethcan.json";
json_error_t je;
- json_t *config, *ethercfg;
+ json_t *config, *ethercfg, *lightcfg;
do {
optch = getopt(argc, argv, "c:");
@@ -47,6 +47,13 @@ int main(int argc, char **argv)
return 1;
}
+ lightcfg = json_object_get(config, "lights");
+ for (size_t i = 0; i < json_array_size(lightcfg); i++) {
+ json_t *c = json_array_get(lightcfg, i);
+ if (light_init_conf(c))
+ return 1;
+ }
+
event_base_loop(ev_base, 0);
return 0;
}
diff --git a/cethcan/protocol.h b/cethcan/protocol.h
new file mode 100644
index 0000000..34327d2
--- /dev/null
+++ b/cethcan/protocol.h
@@ -0,0 +1,24 @@
+ /* addrs: SSSEEEEE
+ * 8 -> extended addr
+ * 14 -> unused
+ */
+#define CANA_TIME 0x10080000
+#define CANA_DISCOVERY 0x4c080000
+#define CANA_DISCOVERY_F(pg,dst) (CANA_DISCOVERY | (((uint32_t)(pg) & 0xf) << 12) | ((dst) & 0xfff))
+#define CANA_LIGHT 0xcc080000
+#define CANA_LIGHT_F(src,dst) (CANA_LIGHT | (((src) & 0x3f) << 12) | ((dst) & 0xfff))
+#define CANA_SENSOR 0xe6080000
+#define CANA_SENSOR_F(src) (CANA_SENSOR | ((src) & 0xfff))
+#define CANA_DEBUG 0xe7000000
+
+#define CANA_PROTOCOL 0xffe80000
+
+/*
+#define can_rx_isext() (can_rx_addr.b[1] & 0x08)
+#define can_rx_ext_rr() (can_rx_dlc & 0x40)
+#define can_rx_len() (can_rx_dlc & 0x0f)
+
+#define can_rx_sublab_proto() ((can_rx_addr.b[0] << 8) | (can_rx_addr.b[1] & 0xe8))
+#define can_rx_sublab_addr() (((can_rx_addr.b[2] & 0x0f) << 8) | can_rx_addr.b[3])
+#define can_rx_sublab_disco_page() ((can_rx_addr.b[2] & 0xf0) >> 4)
+*/