From 31dcf28ff0e6d763df1d138db941dd83107cd621 Mon Sep 17 00:00:00 2001 From: Pim van Pelt Date: Sun, 4 Nov 2018 16:45:05 +0100 Subject: [PATCH] Add Timespec.{Get,Clear,Add} RPCs --- src/rpc.c | 109 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 103 insertions(+), 6 deletions(-) diff --git a/src/rpc.c b/src/rpc.c index cca6d59..08b5ad9 100644 --- a/src/rpc.c +++ b/src/rpc.c @@ -1,6 +1,7 @@ #include "rpc.h" #include "main.h" #include "mqtt.h" +#include "timespec.h" static void rpc_log(struct mg_rpc_request_info *ri, struct mg_str args) { LOG(LL_INFO, ("tag=%.*s src=%.*s method=%.*s args='%.*s'", @@ -53,10 +54,8 @@ static void rpc_channel_toggle_handler(struct mg_rpc_request_info *ri, void *cb_ mg_rpc_send_responsef(ri, "{idx: %d, relay_state: %d}", idx, channel_get(idx)); ri = NULL; - (void)ri; (void)cb_arg; (void)fi; - (void)args; } static void rpc_channel_get_handler(struct mg_rpc_request_info *ri, void *cb_arg, struct mg_rpc_frame_info *fi, struct mg_str args) { @@ -72,10 +71,8 @@ static void rpc_channel_get_handler(struct mg_rpc_request_info *ri, void *cb_arg mg_rpc_send_responsef(ri, "{idx: %d, relay_state: %d}", idx, channel_get(idx)); ri = NULL; - (void)ri; (void)cb_arg; (void)fi; - (void)args; } static void rpc_channel_set_handler(struct mg_rpc_request_info *ri, void *cb_arg, struct mg_rpc_frame_info *fi, struct mg_str args) { @@ -122,10 +119,107 @@ static void rpc_channel_set_handler(struct mg_rpc_request_info *ri, void *cb_arg mg_rpc_send_responsef(ri, "{idx: %d, relay_state: %d}", idx, channel_get(idx)); ri = NULL; - (void)ri; (void)cb_arg; (void)fi; - (void)args; +} + +static void rpc_timespec_get_handler(struct mg_rpc_request_info *ri, void *cb_arg, struct mg_rpc_frame_info *fi, struct mg_str args) { + struct mgos_timespec *ts; + char buf[200]; + int idx; + rpc_log(ri, args); + + json_scanf(args.p, args.len, ri->args_fmt, &idx); + if (idx < 0 || idx >= channel_get_total()) { + mg_rpc_send_errorf(ri, 400, "idx must be between 0 and %d", channel_get_total() - 1); + ri = NULL; + return; + } + ts=channel_get_timespec(idx); + if (!ts) { + mg_rpc_send_errorf(ri, 400, "timespec on channel %d isn't set", idx); + ri = NULL; + return; + } + if (!timespec_get_spec(ts, buf, sizeof(buf))) { + mg_rpc_send_errorf(ri, 400, "Could not get timespec on channel %d", idx); + ri = NULL; + return; + } + + mg_rpc_send_responsef(ri, "{idx: %d, spec: %Q}", idx, buf); + ri = NULL; + + (void)cb_arg; + (void)fi; +} + +static void rpc_timespec_clear_handler(struct mg_rpc_request_info *ri, void *cb_arg, struct mg_rpc_frame_info *fi, struct mg_str args) { + struct mgos_timespec *ts; + int idx; + + rpc_log(ri, args); + + json_scanf(args.p, args.len, ri->args_fmt, &idx); + if (idx < 0 || idx >= channel_get_total()) { + mg_rpc_send_errorf(ri, 400, "idx must be between 0 and %d", channel_get_total() - 1); + ri = NULL; + return; + } + ts=channel_get_timespec(idx); + if (!ts) { + mg_rpc_send_errorf(ri, 400, "timespec on channel %d isn't set", idx); + ri = NULL; + return; + } + + if (!timespec_clear_spec(ts)) { + mg_rpc_send_errorf(ri, 400, "Failed to clear timespec on channel %d", idx); + ri = NULL; + return; + } + channel_override_set(idx); + + mg_rpc_send_responsef(ri, "{idx: %d}", idx); + ri = NULL; + + (void)cb_arg; + (void)fi; +} + +static void rpc_timespec_add_handler(struct mg_rpc_request_info *ri, void *cb_arg, struct mg_rpc_frame_info *fi, struct mg_str args) { + struct mgos_timespec *ts; + int idx; + char *spec = NULL; + + rpc_log(ri, args); + + json_scanf(args.p, args.len, ri->args_fmt, &idx, &spec); + if (idx < 0 || idx >= channel_get_total()) { + mg_rpc_send_errorf(ri, 400, "idx must be between 0 and %d", channel_get_total() - 1); + ri = NULL; + goto exit; + } + ts=channel_get_timespec(idx); + if (!ts) { + mg_rpc_send_errorf(ri, 400, "timespec on channel %d isn't set", idx); + ri = NULL; + goto exit; + } + if (!timespec_add_spec(ts, spec)) { + mg_rpc_send_errorf(ri, 400, "timespec '%Q' is malformed", spec); + ri = NULL; + goto exit; + } + channel_override_set(idx); + + mg_rpc_send_responsef(ri, "{idx: %d}", idx); + ri = NULL; + +exit: + if (spec) free(spec); + (void)cb_arg; + (void)fi; } void rpc_init() { @@ -134,4 +228,7 @@ void rpc_init() { mg_rpc_add_handler(c, "Channel.Toggle", "{idx: %d}", rpc_channel_toggle_handler, NULL); mg_rpc_add_handler(c, "Channel.Get", "{idx: %d}", rpc_channel_get_handler, NULL); mg_rpc_add_handler(c, "Channel.Set", "{idx: %d, value: %d, duration: %d}", rpc_channel_set_handler, NULL); + mg_rpc_add_handler(c, "Timespec.Get", "{idx: %d}", rpc_timespec_get_handler, NULL); + mg_rpc_add_handler(c, "Timespec.Clear", "{idx: %d}", rpc_timespec_clear_handler, NULL); + mg_rpc_add_handler(c, "Timespec.Add", "{idx: %d, spec: %Q}", rpc_timespec_add_handler, NULL); }