Initial checkin.
This commit is contained in:
127
src/rpc.c
Normal file
127
src/rpc.c
Normal file
@ -0,0 +1,127 @@
|
||||
#include "rpc.h"
|
||||
#include "main.h"
|
||||
#include "mqtt.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'",
|
||||
ri->tag.len, ri->tag.p, ri->src.len, ri->src.p,
|
||||
ri->method.len, ri->method.p, args.len, args.p));
|
||||
// TODO(pim): log to MQTT
|
||||
}
|
||||
|
||||
// Grab the idx from args and resolve to a GPIO, return true if found, false if not.
|
||||
// If we return false, return_idx and return_gpio are not usable.
|
||||
static bool rpc_args_to_idx_and_gpio(struct mg_rpc_request_info *ri, struct mg_str args, int *return_idx, uint8_t *return_gpio) {
|
||||
int idx;
|
||||
int gpio;
|
||||
|
||||
if (json_scanf(args.p, args.len, ri->args_fmt, &idx) != 1) {
|
||||
mg_rpc_send_errorf(ri, 400, "idx is required");
|
||||
ri = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (idx<0 || idx>2) {
|
||||
mg_rpc_send_errorf(ri, 400, "idx must be 0, 1, 2");
|
||||
ri = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
gpio = channel_gpio_by_idx(idx);
|
||||
if (gpio == GPIO_INVALID) {
|
||||
mg_rpc_send_errorf(ri, 400, "No GPIO for idx");
|
||||
ri = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
*return_gpio = gpio;
|
||||
*return_idx = idx;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void rpc_channel_toggle_handler(struct mg_rpc_request_info *ri, void *cb_arg, struct mg_rpc_frame_info *fi, struct mg_str args) {
|
||||
uint8_t gpio;
|
||||
char msg[100];
|
||||
int idx;
|
||||
|
||||
rpc_log(ri, args);
|
||||
|
||||
if (!rpc_args_to_idx_and_gpio(ri, args, &idx, &gpio))
|
||||
return;
|
||||
|
||||
channel_handler(gpio, NULL);
|
||||
channel_report(idx, msg, sizeof(msg));
|
||||
mg_rpc_send_responsef(ri, msg);
|
||||
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) {
|
||||
uint8_t gpio;
|
||||
char msg[100];
|
||||
int idx;
|
||||
|
||||
rpc_log(ri, args);
|
||||
|
||||
if (!rpc_args_to_idx_and_gpio(ri, args, &idx, &gpio))
|
||||
return;
|
||||
|
||||
channel_report(idx, msg, sizeof(msg));
|
||||
mqtt_publish_stat("channel", msg);
|
||||
mg_rpc_send_responsef(ri, msg);
|
||||
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) {
|
||||
uint8_t gpio;
|
||||
char msg[100];
|
||||
int idx;
|
||||
int value;
|
||||
|
||||
rpc_log(ri, args);
|
||||
|
||||
if (json_scanf(args.p, args.len, ri->args_fmt, &idx, &value) != 2) {
|
||||
mg_rpc_send_errorf(ri, 400, "idx and value are required");
|
||||
ri = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
if (idx<0 || idx>2) {
|
||||
mg_rpc_send_errorf(ri, 400, "idx must be 0, 1, 2");
|
||||
ri = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
gpio = channel_gpio_by_idx(idx);
|
||||
if (gpio == GPIO_INVALID) {
|
||||
mg_rpc_send_errorf(ri, 400, "No GPIO for idx");
|
||||
ri = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
channel_set(idx, (bool) value);
|
||||
channel_report(idx, msg, sizeof(msg));
|
||||
mg_rpc_send_responsef(ri, msg);
|
||||
ri = NULL;
|
||||
|
||||
(void) ri;
|
||||
(void) cb_arg;
|
||||
(void) fi;
|
||||
(void) args;
|
||||
}
|
||||
|
||||
void rpc_init() {
|
||||
struct mg_rpc *c = mgos_rpc_get_global();
|
||||
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}", rpc_channel_set_handler, NULL);
|
||||
}
|
Reference in New Issue
Block a user