diff options
Diffstat (limited to 'cethcan')
-rw-r--r-- | cethcan/cethcan.h | 6 | ||||
-rw-r--r-- | cethcan/light.c | 36 | ||||
-rw-r--r-- | cethcan/rpc.c | 38 |
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 }, }; |