diff --git a/esp-link/cgi.c b/esp-link/cgi.c index 3a37347..bfb7028 100644 --- a/esp-link/cgi.c +++ b/esp-link/cgi.c @@ -18,16 +18,64 @@ Some random cgi routines. #include "cgi.h" #include "espfs.h" -void ICACHE_FLASH_ATTR -jsonHeader(HttpdConnData *connData, int code) { +void noCacheHeaders(HttpdConnData *connData, int code) { httpdStartResponse(connData, code); httpdHeader(connData, "Cache-Control", "no-cache, no-store, must-revalidate"); httpdHeader(connData, "Pragma", "no-cache"); httpdHeader(connData, "Expires", "0"); +} + +void ICACHE_FLASH_ATTR +jsonHeader(HttpdConnData *connData, int code) { + noCacheHeaders(connData, code); httpdHeader(connData, "Content-Type", "application/json"); httpdEndHeaders(connData); } +void ICACHE_FLASH_ATTR +errorResponse(HttpdConnData *connData, int code, char *message) { + noCacheHeaders(connData, code); + httpdEndHeaders(connData); + httpdSend(connData, message, -1); + os_printf("HTTP %d error response: \"%s\"\n", code, message); +} + +// look for the HTTP arg 'name' and store it at 'config' with max length 'max_len' (incl +// terminating zero), returns -1 on error, 0 if not found, 1 if found and OK +int ICACHE_FLASH_ATTR +getStringArg(HttpdConnData *connData, char *name, char *config, int max_len) { + char buff[128]; + int len = httpdFindArg(connData->getArgs, name, buff, sizeof(buff)); + if (len < 0) return 0; // not found, skip + if (len >= max_len) { + os_sprintf(buff, "Value for %s too long (%d > %d allowed)", name, len, max_len-1); + errorResponse(connData, 400, buff); + return -1; + } + strcpy(config, buff); + return 1; +} + +int ICACHE_FLASH_ATTR +getBoolArg(HttpdConnData *connData, char *name, bool*config) { + char buff[64]; + int len = httpdFindArg(connData->getArgs, name, buff, sizeof(buff)); + if (len < 0) return 0; // not found, skip + + if (strcmp(buff, "1") == 0 || strcmp(buff, "true") == 0) { + *config = true; + return 1; + } + if (strcmp(buff, "0") == 0 || strcmp(buff, "false") == 0) { + *config = false; + return 1; + } + os_sprintf(buff, "Invalid value for %s", name); + errorResponse(connData, 400, buff); + return -1; +} + + #define TOKEN(x) (os_strcmp(token, x) == 0) #if 0 // Handle system information variables and print their value, returns the number of diff --git a/esp-link/cgi.h b/esp-link/cgi.h index b5690cf..8d61f36 100644 --- a/esp-link/cgi.h +++ b/esp-link/cgi.h @@ -4,6 +4,9 @@ #include "httpd.h" void jsonHeader(HttpdConnData *connData, int code); +void errorResponse(HttpdConnData *connData, int code, char *message); +int getStringArg(HttpdConnData *connData, char *name, char *config, int max_len); +int getBoolArg(HttpdConnData *connData, char *name, bool*config); int cgiMenu(HttpdConnData *connData); #endif diff --git a/esp-link/cgimqtt.c b/esp-link/cgimqtt.c index dbfbc14..cbf4c16 100644 --- a/esp-link/cgimqtt.c +++ b/esp-link/cgimqtt.c @@ -38,34 +38,56 @@ int ICACHE_FLASH_ATTR cgiMqttGet(HttpdConnData *connData) { int ICACHE_FLASH_ATTR cgiMqttSet(HttpdConnData *connData) { if (connData->conn==NULL) return HTTPD_CGI_DONE; -#if 0 - // Handle tcp_enable flag - char buff[128]; - int len = httpdFindArg(connData->getArgs, "tcp_enable", buff, sizeof(buff)); - if (len <= 0) { - jsonHeader(connData, 400); - return HTTPD_CGI_DONE; + // handle MQTT server settings + int mqtt_server = 0; // accumulator for changes/errors + mqtt_server |= getStringArg(connData, "mqtt-host", + flashConfig.mqtt_hostname, sizeof(flashConfig.mqtt_hostname)); + if (mqtt_server < 0) return HTTPD_CGI_DONE; + mqtt_server |= getStringArg(connData, "mqtt-client-id", + flashConfig.mqtt_client, sizeof(flashConfig.mqtt_client)); + if (mqtt_server < 0) return HTTPD_CGI_DONE; + mqtt_server |= getStringArg(connData, "mqtt-username", + flashConfig.mqtt_username, sizeof(flashConfig.mqtt_username)); + if (mqtt_server < 0) return HTTPD_CGI_DONE; + mqtt_server |= getStringArg(connData, "mqtt-password", + flashConfig.mqtt_password, sizeof(flashConfig.mqtt_password)); + if (mqtt_server < 0) return HTTPD_CGI_DONE; + mqtt_server |= getBoolArg(connData, "mqtt-enable", + &flashConfig.mqtt_enable); + + // handle mqtt port + char buff[16]; + if (httpdFindArg(connData->getArgs, "mqtt-port", buff, sizeof(buff)) > 0) { + int32_t port = atoi(buff); + if (port > 0 && port < 65536) { + flashConfig.mqtt_port = port; + mqtt_server |= 1; + } else { + errorResponse(connData, 400, "Invalid MQTT port"); + return HTTPD_CGI_DONE; + } } - flashConfig.tcp_enable = os_strcmp(buff, "true") == 0; - // Handle rssi_enable flag - len = httpdFindArg(connData->getArgs, "rssi_enable", buff, sizeof(buff)); - if (len <= 0) { - jsonHeader(connData, 400); - return HTTPD_CGI_DONE; + // if server setting changed, we need to "make it so" + if (mqtt_server) { + os_printf("MQTT server settings changed, enable=%d\n", flashConfig.mqtt_enable); + // TODO } - flashConfig.rssi_enable = os_strcmp(buff, "true") == 0; - // Handle api_key flag - len = httpdFindArg(connData->getArgs, "api_key", buff, sizeof(buff)); - if (len < 0) { - jsonHeader(connData, 400); + // no action required if mqtt status settings change, they just get picked up at the + // next status tick + if (getBoolArg(connData, "mqtt-status-enable", &flashConfig.mqtt_status_enable) < 0) return HTTPD_CGI_DONE; - } - buff[sizeof(flashConfig.api_key)-1] = 0; // ensure we don't get an overrun - os_strcpy(flashConfig.api_key, buff); -#endif + if (getStringArg(connData, "mqtt-status-topic", + flashConfig.mqtt_status_topic, sizeof(flashConfig.mqtt_status_topic)) < 0) + return HTTPD_CGI_DONE; + + // if SLIP-enable is toggled it gets picked-up immediately by the parser + int slip_update = getBoolArg(connData, "slip-enable", &flashConfig.slip_enable); + if (slip_update < 0) return HTTPD_CGI_DONE; + if (slip_update > 0) os_printf("SLIP-enable changed: %d\n", flashConfig.slip_enable); + os_printf("Saving config\n"); if (configSave()) { httpdStartResponse(connData, 200); httpdEndHeaders(connData); diff --git a/html/mqtt.html b/html/mqtt.html index dd9653c..257c137 100644 --- a/html/mqtt.html +++ b/html/mqtt.html @@ -71,18 +71,17 @@
REST requests are enabled as soon as SLIP is enabled. There are no REST-specific settings.
-