aboutsummaryrefslogtreecommitdiff
path: root/main/param
diff options
context:
space:
mode:
Diffstat (limited to 'main/param')
-rw-r--r--main/param/fraction.c139
-rw-r--r--main/param/ratio.c139
2 files changed, 278 insertions, 0 deletions
diff --git a/main/param/fraction.c b/main/param/fraction.c
new file mode 100644
index 0000000..adfc769
--- /dev/null
+++ b/main/param/fraction.c
@@ -0,0 +1,139 @@
+#include "param.h"
+#include "http_server.h"
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static inline uint8_t clamp_u8(int v)
+{
+ if (v < 0) return 0;
+ if (v > 255) return 255;
+ return (uint8_t)v;
+}
+
+static int parse_fraction(const char* s, fraction_t* out)
+{
+ if (!s) return -1;
+ char* end = NULL;
+ float f = strtof(s, &end);
+ if (end == s) {
+ return -1;
+ }
+ *out = clamp_u8((int)lroundf(f * 255.0f));
+ return 0;
+}
+
+void cmd_handle(fraction_t)(const char* attr, sockbuf_t* sockbuf, fraction_t* ptr)
+{
+ char op_[8];
+ char buf_[32];
+
+ char* op = read_token(sockbuf, op_, sizeof(op_));
+ char* value = read_token(sockbuf, buf_, sizeof(buf_));
+
+ fraction_t curval = *ptr;
+ fraction_t parsed = 0;
+
+ if (!strcmp(op, "+=") || !strcmp(op, "-=") || !strcmp(op, "=")) {
+ if (parse_fraction(value, &parsed) != 0) {
+ sockbuf_write(sockbuf, "Invalid value\n");
+ return;
+ }
+ if (!strcmp(op, "+=")) {
+ curval = clamp_u8((int)curval + (int)parsed);
+ } else if (!strcmp(op, "-=")) {
+ curval = clamp_u8((int)curval - (int)parsed);
+ } else {
+ curval = parsed;
+ }
+ } else {
+ sockbuf_write(sockbuf, "Unknown operation: '");
+ sockbuf_write(sockbuf, op);
+ sockbuf_write(sockbuf, "'\n");
+ return;
+ }
+
+ *ptr = curval;
+ snprintf(buf_, sizeof(buf_), "%s = %.3f\n", attr, curval / 255.0f);
+ sockbuf_write(sockbuf, buf_);
+}
+
+size_t serialize_to_json(fraction_t)(
+ char** out, size_t len, const char* attr, const char* dn, fraction_t value)
+{
+ float fval = value / 255.0f;
+ size_t newlen = snprintf(
+ *out,
+ len,
+ "\"%s\":{\"type\":\"fraction\",\"value\":\"%.4f\",\"disp\":\"%s\"}",
+ attr,
+ fval,
+ dn);
+ *out += newlen;
+ return len - newlen;
+}
+
+#define TAG "param_fraction"
+void http_handle(fraction_t)(httpd_req_t* req, fraction_t* val)
+{
+ char buf[128];
+ int buf_len = httpd_req_get_url_query_len(req) + 1;
+ esp_err_t err;
+
+ if (buf_len > 1) {
+ if (buf_len > sizeof(buf)) {
+ ESP_LOGI(TAG, "Invalid request. Query string too long.");
+ httpd_resp_set_status(req, HTTPD_400);
+ return;
+ }
+
+ if ((err = httpd_req_get_url_query_str(req, buf, buf_len)) == ESP_OK) {
+ char param[32];
+ fraction_t parsed;
+ if (httpd_query_key_value(buf, "add", param, sizeof(param)) == ESP_OK) {
+ if (parse_fraction(param, &parsed) != 0) {
+ httpd_resp_set_status(req, HTTPD_400);
+ return;
+ }
+ *val = clamp_u8((int)(*val) + (int)parsed);
+ } else if (
+ httpd_query_key_value(buf, "set", param, sizeof(param)) == ESP_OK) {
+ if (parse_fraction(param, &parsed) != 0) {
+ httpd_resp_set_status(req, HTTPD_400);
+ return;
+ }
+ *val = parsed;
+ } else if (
+ httpd_query_key_value(buf, "sub", param, sizeof(param)) == ESP_OK) {
+ if (parse_fraction(param, &parsed) != 0) {
+ httpd_resp_set_status(req, HTTPD_400);
+ return;
+ }
+ *val = clamp_u8((int)(*val) - (int)parsed);
+ } else {
+ ESP_LOGI(TAG, "No valid parameters.");
+ httpd_resp_set_status(req, HTTPD_400);
+ return;
+ }
+ } else {
+ ESP_LOGI(TAG, "Unable to get URL query string. [%d]", err);
+ httpd_resp_set_status(req, HTTPD_500);
+ return;
+ }
+ } else {
+ ESP_LOGI(TAG, "No query string provided?");
+ httpd_resp_set_status(req, HTTPD_400);
+ return;
+ }
+
+ httpd_resp_set_status(req, HTTPD_204);
+}
+
+void print(fraction_t)(sockbuf_t* sockbuf, const char* attr, fraction_t val)
+{
+ char buf[128];
+ snprintf(buf, sizeof(buf), "%s: %.3f :: fraction\n", attr, val / 255.0f);
+ sockbuf_write(sockbuf, buf);
+}
diff --git a/main/param/ratio.c b/main/param/ratio.c
new file mode 100644
index 0000000..bd7e3f4
--- /dev/null
+++ b/main/param/ratio.c
@@ -0,0 +1,139 @@
+#include "param.h"
+#include "http_server.h"
+
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static inline uint16_t clamp_u16(int v)
+{
+ if (v < 0) return 0;
+ if (v > 65535) return 65535;
+ return (uint16_t)v;
+}
+
+static int parse_ratio(const char* s, ratio_t* out)
+{
+ if (!s) return -1;
+ char* end = NULL;
+ float f = strtof(s, &end);
+ if (end == s) {
+ return -1;
+ }
+ *out = clamp_u16((int)lroundf(f * 255.0f));
+ return 0;
+}
+
+void cmd_handle(ratio_t)(const char* attr, sockbuf_t* sockbuf, ratio_t* ptr)
+{
+ char op_[8];
+ char buf_[32];
+
+ char* op = read_token(sockbuf, op_, sizeof(op_));
+ char* value = read_token(sockbuf, buf_, sizeof(buf_));
+
+ ratio_t curval = *ptr;
+ ratio_t parsed = 0;
+
+ if (!strcmp(op, "+=") || !strcmp(op, "-=") || !strcmp(op, "=")) {
+ if (parse_ratio(value, &parsed) != 0) {
+ sockbuf_write(sockbuf, "Invalid value\n");
+ return;
+ }
+ if (!strcmp(op, "+=")) {
+ curval = clamp_u16((int)curval + (int)parsed);
+ } else if (!strcmp(op, "-=")) {
+ curval = clamp_u16((int)curval - (int)parsed);
+ } else {
+ curval = parsed;
+ }
+ } else {
+ sockbuf_write(sockbuf, "Unknown operation: '");
+ sockbuf_write(sockbuf, op);
+ sockbuf_write(sockbuf, "'\n");
+ return;
+ }
+
+ *ptr = curval;
+ snprintf(buf_, sizeof(buf_), "%s = %.3f\n", attr, curval / 255.0f);
+ sockbuf_write(sockbuf, buf_);
+}
+
+size_t serialize_to_json(ratio_t)(
+ char** out, size_t len, const char* attr, const char* dn, ratio_t value)
+{
+ float fval = value / 255.0f;
+ size_t newlen = snprintf(
+ *out,
+ len,
+ "\"%s\":{\"type\":\"ratio\",\"value\":\"%.4f\",\"disp\":\"%s\"}",
+ attr,
+ fval,
+ dn);
+ *out += newlen;
+ return len - newlen;
+}
+
+#define TAG "param_ratio"
+void http_handle(ratio_t)(httpd_req_t* req, ratio_t* val)
+{
+ char buf[128];
+ int buf_len = httpd_req_get_url_query_len(req) + 1;
+ esp_err_t err;
+
+ if (buf_len > 1) {
+ if (buf_len > sizeof(buf)) {
+ ESP_LOGI(TAG, "Invalid request. Query string too long.");
+ httpd_resp_set_status(req, HTTPD_400);
+ return;
+ }
+
+ if ((err = httpd_req_get_url_query_str(req, buf, buf_len)) == ESP_OK) {
+ char param[32];
+ ratio_t parsed;
+ if (httpd_query_key_value(buf, "add", param, sizeof(param)) == ESP_OK) {
+ if (parse_ratio(param, &parsed) != 0) {
+ httpd_resp_set_status(req, HTTPD_400);
+ return;
+ }
+ *val = clamp_u16((int)(*val) + (int)parsed);
+ } else if (
+ httpd_query_key_value(buf, "set", param, sizeof(param)) == ESP_OK) {
+ if (parse_ratio(param, &parsed) != 0) {
+ httpd_resp_set_status(req, HTTPD_400);
+ return;
+ }
+ *val = parsed;
+ } else if (
+ httpd_query_key_value(buf, "sub", param, sizeof(param)) == ESP_OK) {
+ if (parse_ratio(param, &parsed) != 0) {
+ httpd_resp_set_status(req, HTTPD_400);
+ return;
+ }
+ *val = clamp_u16((int)(*val) - (int)parsed);
+ } else {
+ ESP_LOGI(TAG, "No valid parameters.");
+ httpd_resp_set_status(req, HTTPD_400);
+ return;
+ }
+ } else {
+ ESP_LOGI(TAG, "Unable to get URL query string. [%d]", err);
+ httpd_resp_set_status(req, HTTPD_500);
+ return;
+ }
+ } else {
+ ESP_LOGI(TAG, "No query string provided?");
+ httpd_resp_set_status(req, HTTPD_400);
+ return;
+ }
+
+ httpd_resp_set_status(req, HTTPD_204);
+}
+
+void print(ratio_t)(sockbuf_t* sockbuf, const char* attr, ratio_t val)
+{
+ char buf[128];
+ snprintf(buf, sizeof(buf), "%s: %.3f :: ratio\n", attr, val / 255.0f);
+ sockbuf_write(sockbuf, buf);
+}