summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cethcan/cethcan.h6
-rw-r--r--cethcan/light.c36
-rw-r--r--cethcan/rpc.c38
3 files changed, 80 insertions, 0 deletions
diff --git a/cethcan/cethcan.h b/cethcan/cethcan.h
index 73492cc..6adf6bb 100644
--- a/cethcan/cethcan.h
+++ b/cethcan/cethcan.h
@@ -80,6 +80,12 @@ extern void rpc_perform(struct evbuffer *request,
void (*response_handler)(void *arg, struct evbuffer *data),
void *handler_arg);
+struct light;
+extern struct light *light_find(const char *name);
+extern int light_set(struct light *l, unsigned value);
+extern unsigned light_getset(struct light *l);
+extern unsigned light_getact(struct light *l);
+
extern void json_bump_longpoll(void);
extern int socan_init(json_t *config);
diff --git a/cethcan/light.c b/cethcan/light.c
index cd646d8..da6aefb 100644
--- a/cethcan/light.c
+++ b/cethcan/light.c
@@ -6,6 +6,7 @@ struct value {
};
struct light {
+ struct light *next;
struct can_user *u;
char *name;
@@ -14,6 +15,38 @@ struct light {
struct value set, actual;
};
+static struct light *lights = NULL, **plights = &lights;
+
+struct light *light_find(const char *name)
+{
+ struct light *l;
+ for (l = lights; l; l = l->next)
+ if (!strcmp(l->name, name))
+ break;
+ return l;
+}
+
+int light_set(struct light *l, unsigned value)
+{
+ struct can_message msg;
+ msg.daddr = CANA_LIGHT_F(0, l->logical_addr);
+ msg.dlc = 1;
+ msg.bytes[0] = value;
+ can_broadcast(l->u, &msg);
+
+ return 0;
+}
+
+unsigned light_getset(struct light *l)
+{
+ return l->set.val;
+}
+
+unsigned light_getact(struct light *l)
+{
+ return l->actual.val;
+}
+
static void light_json_handler(void *arg, json_t *json, enum json_subtype type)
{
struct light *l = arg;
@@ -89,5 +122,8 @@ int light_init_conf(json_t *config)
l->u = can_register_alloc(l, light_can_handler, "light[%s]", l->name);
l->u->json = light_json_handler;
+
+ *plights = l;
+ plights = &l->next;
return 0;
}
diff --git a/cethcan/rpc.c b/cethcan/rpc.c
index 57cb117..f9a47fc 100644
--- a/cethcan/rpc.c
+++ b/cethcan/rpc.c
@@ -9,8 +9,46 @@ static int rpc_ping(void *apparg, json_t *json_params, json_t **result)
return 0;
}
+static int rpc_light_set(void *apparg, json_t *json_params, json_t **result)
+{
+ struct light *l;
+ const char *name = json_string_value(json_array_get(json_params, 0));
+ unsigned val = json_integer_value(json_array_get(json_params, 1));
+
+ l = light_find(name);
+ if (!l) {
+ *result = jsonrpc_error_object(JSONRPC_INVALID_PARAMS,
+ json_string("cann't find specified light"));
+ return JSONRPC_INVALID_PARAMS;
+ }
+ *result = json_boolean(!light_set(l, val));
+ return 0;
+}
+
+static int rpc_light_get(void *apparg, json_t *json_params, json_t **result)
+{
+ struct light *l;
+ const char *name = json_string_value(json_array_get(json_params, 0));
+ unsigned set, actual;
+
+ l = light_find(name);
+ if (!l) {
+ *result = jsonrpc_error_object(JSONRPC_INVALID_PARAMS,
+ json_string("cannot find specified light"));
+ return JSONRPC_INVALID_PARAMS;
+ }
+
+ set = light_getset(l);
+ actual = light_getact(l);
+
+ *result = json_pack("{s:i,s:i}", "set", set, "actual", actual);
+ return 0;
+}
+
struct jsonrpc_method_entry_t method_table[] = {
{ "ping", rpc_ping, "" },
+ { "light_set", rpc_light_set, "[si]" },
+ { "light_get", rpc_light_get, "[s]" },
{ NULL, NULL, NULL },
};