diff --git a/src/svc/hasp_http.cpp b/src/svc/hasp_http.cpp deleted file mode 100644 index 11b66f44..00000000 --- a/src/svc/hasp_http.cpp +++ /dev/null @@ -1,2121 +0,0 @@ -/* MIT License - Copyright (c) 2020 Francis Van Roie - For full license information read the LICENSE file in the project folder */ - -//#include "webServer.h" -#include "ArduinoJson.h" -#include "ArduinoLog.h" -#include "lvgl.h" - -#if defined(ARDUINO_ARCH_ESP32) -#include "Update.h" -#endif - -#include "hasp_conf.h" - -#include "hasp_gui.h" -#include "hasp_hal.h" -#include "hasp_debug.h" -#include "hasp_config.h" - -#include "hasp/hasp_utilities.h" -#include "hasp/hasp_dispatch.h" -#include "hasp/hasp.h" - -#if HASP_USE_HTTP > 0 - -#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) -File fsUploadFile; -#endif - -//////////////////////////////////////////////////////////////////////////////////////////////////// -bool webServerStarted = false; - -// bool httpEnable = true; -// uint16_t httpPort = 80; -// char httpUser[32] = ""; -// char httpPassword[32] = ""; -hasp_http_config_t http_config; - -#define HTTP_PAGE_SIZE (6 * 256) - -#if defined(STM32F4xx) && HASP_USE_ETHERNET > 0 -#include -EthernetWebServer webServer(80); -#endif - -#if defined(STM32F4xx) && HASP_USE_WIFI > 0 -#include -// #include -EthernetWebServer webServer(80); -#endif - -#if defined(ARDUINO_ARCH_ESP8266) -#include "StringStream.h" -#include -#include -ESP8266WebServer webServer(80); -#endif - -#if defined(ARDUINO_ARCH_ESP32) -#include -#include -WebServer webServer(80); -#endif // ESP32 - -HTTPUpload* upload; - -static const char HTTP_MENU_BUTTON[] PROGMEM = - "

"; - -const char MAIN_MENU_BUTTON[] PROGMEM = - "

"; -const char MIT_LICENSE[] PROGMEM = "
MIT License

"; - -const char HTTP_DOCTYPE[] PROGMEM = - ""; -const char HTTP_META_GO_BACK[] PROGMEM = ""; -const char HTTP_HEADER[] PROGMEM = "%s"; -const char HTTP_STYLE[] PROGMEM = - ""; -const char HTTP_SCRIPT[] PROGMEM = ""; -const char HTTP_HEADER_END[] PROGMEM = - "
"; -const char HTTP_END[] PROGMEM = ""; - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -// URL for auto-update "version.json" -// const char UPDATE_URL[] PROGMEM = "http://haswitchplate.com/update/version.json"; -// // Default link to compiled Arduino firmware image -// String espFirmwareUrl = "http://haswitchplate.com/update/HASwitchPlate.ino.d1_mini.bin"; -// // Default link to compiled Nextion firmware images -// String lcdFirmwareUrl = "http://haswitchplate.com/update/HASwitchPlate.tft"; - -#if HASP_USE_MQTT > 0 -extern char mqttNodeName[16]; -#else -char mqttNodeName[3] = "na"; -#endif - -//////////////////////////////////////////////////////////////////////////////////////////////////// -String getOption(int value, String label, bool selected) -{ - char buffer[128]; - snprintf_P(buffer, sizeof(buffer), PSTR(""), value, - (selected ? PSTR(" selected") : ""), label.c_str()); - return buffer; -} - -String getOption(String value, String label, bool selected) -{ - char buffer[128]; - snprintf_P(buffer, sizeof(buffer), PSTR(""), value.c_str(), - (selected ? PSTR(" selected") : ""), label.c_str()); - return buffer; -} - -static void add_gpio_select_option(String& str, uint8_t gpio, uint8_t bcklpin) -{ - char buffer[10]; - snprintf_P(buffer, sizeof(buffer), PSTR("GPIO %d"), gpio); - str += getOption(gpio, buffer, bcklpin == gpio); -} - -static void add_button(String& str, const __FlashStringHelper* label, const __FlashStringHelper* extra) -{ - str += F(""); -} - -static void close_form(String& str) -{ - str += F("

"); -} - -static void add_form_button(String& str, const __FlashStringHelper* label, const __FlashStringHelper* action, - const __FlashStringHelper* extra) -{ - str += F("

"); - add_button(str, label, extra); - close_form(str); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void webHandleHaspConfig(); - -static inline char* httpGetNodename() -{ - return mqttNodeName; -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -bool httpIsAuthenticated(const __FlashStringHelper* fstr_page) -{ - if(http_config.password[0] != '\0') { // Request HTTP auth if httpPassword is set - if(!webServer.authenticate(http_config.user, http_config.password)) { - webServer.requestAuthentication(); - return false; - } - } - -#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) - LOG_TRACE(TAG_HTTP, F("Sending %S page to client connected from: %s"), fstr_page, - webServer.client().remoteIP().toString().c_str()); -#else - // LOG_INFO(TAG_HTTP,F("Sending %s page to client connected from: %s"), page, - // String(webServer.client().remoteIP()).c_str()); -#endif - - return true; -} - -void webSendFooter() -{ - char buffer[16]; - haspGetVersion(buffer, sizeof(buffer)); - -#if defined(STM32F4xx) - webServer.sendContent(HTTP_END); - webServer.sendContent(buffer); - webServer.sendContent(HTTP_FOOTER); -#else - webServer.sendContent_P(HTTP_END); - webServer.sendContent(buffer); - webServer.sendContent_P(HTTP_FOOTER); -#endif -} - -void webSendPage(char* nodename, uint32_t httpdatalength, bool gohome = false) -{ - { - char buffer[64]; - haspGetVersion(buffer, sizeof(buffer)); - - /* Calculate Content Length upfront */ - uint16_t contentLength = strlen(buffer); // verion length - contentLength += sizeof(HTTP_DOCTYPE) - 1; - contentLength += sizeof(HTTP_HEADER) - 1 - 2 + strlen(nodename); // -2 for %s - contentLength += sizeof(HTTP_SCRIPT) - 1; - contentLength += sizeof(HTTP_STYLE) - 1; - // contentLength += sizeof(HASP_STYLE) - 1; - if(gohome) contentLength += sizeof(HTTP_META_GO_BACK) - 1; - contentLength += sizeof(HTTP_HEADER_END) - 1; - contentLength += sizeof(HTTP_END) - 1; - contentLength += sizeof(HTTP_FOOTER) - 1; - - if(httpdatalength > HTTP_PAGE_SIZE) { - LOG_WARNING(TAG_HTTP, F("Sending page with %u static and %u dynamic bytes"), contentLength, httpdatalength); - } - - webServer.setContentLength(contentLength + httpdatalength); -#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) - webServer.send_P(200, PSTR("text/html"), HTTP_DOCTYPE); // 122 -#else - webServer.send(200, ("text/html"), HTTP_DOCTYPE); // 122 -#endif - - snprintf_P(buffer, sizeof(buffer), HTTP_HEADER, nodename); - webServer.sendContent(buffer); // 17-2+len - } - -#if defined(STM32F4xx) - webServer.sendContent(HTTP_SCRIPT); // 131 - webServer.sendContent(HTTP_STYLE); // 487 - // webServer.sendContent(HASP_STYLE); // 145 - if(gohome) webServer.sendContent(HTTP_META_GO_BACK); // 47 - webServer.sendContent(HTTP_HEADER_END); // 80 -#else - webServer.sendContent_P(HTTP_SCRIPT); // 131 - webServer.sendContent_P(HTTP_STYLE); // 487 - // webServer.sendContent_P(HASP_STYLE); // 145 - if(gohome) webServer.sendContent_P(HTTP_META_GO_BACK); // 47 - webServer.sendContent_P(HTTP_HEADER_END); // 80 -#endif -} - -void saveConfig() -{ - if(webServer.method() == HTTP_POST) { - if(webServer.hasArg(PSTR("save"))) { - String save = webServer.arg(PSTR("save")); - - StaticJsonDocument<256> settings; - for(int i = 0; i < webServer.args(); i++) settings[webServer.argName(i)] = webServer.arg(i); - - if(save == String(PSTR("hasp"))) { - haspSetConfig(settings.as()); - -#if HASP_USE_MQTT > 0 - } else if(save == String(PSTR("mqtt"))) { - mqttSetConfig(settings.as()); -#endif - - } else if(save == String(PSTR("gui"))) { - settings[FPSTR(FP_GUI_POINTER)] = webServer.hasArg(PSTR("cur")); - settings[FPSTR(FP_GUI_INVERT)] = webServer.hasArg(PSTR("inv")); - guiSetConfig(settings.as()); - - } else if(save == String(PSTR("debug"))) { - debugSetConfig(settings.as()); - - } else if(save == String(PSTR("http"))) { - httpSetConfig(settings.as()); - - // Password might have changed - if(!httpIsAuthenticated(F("config"))) return; - -#if HASP_USE_WIFI > 0 - } else if(save == String(PSTR("wifi"))) { - wifiSetConfig(settings.as()); -#endif - } - } - } -} - -void webHandleRoot() -{ - if(!httpIsAuthenticated(F("root"))) return; - - saveConfig(); - { - String httpMessage((char*)0); - httpMessage.reserve(HTTP_PAGE_SIZE); - httpMessage += F("

"); - httpMessage += httpGetNodename(); - httpMessage += F("


"); - - httpMessage += F("

"); - - httpMessage += F("

"); - httpMessage += - F("

"); - add_form_button(httpMessage, F(D_HTTP_CONFIGURATION), F("/config"), F("")); - // httpMessage += F("

"); - - httpMessage += F("

"); - -#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 - if(HASP_FS.exists(F("/edit.htm.gz"))) { - httpMessage += - F("

"); - } -#endif - - httpMessage += F("

"); - - webSendPage(httpGetNodename(), httpMessage.length(), false); - webServer.sendContent(httpMessage); - } - // httpMessage.clear(); - webSendFooter(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void httpHandleReboot() -{ // http://plate01/reboot - if(!httpIsAuthenticated(F("reboot"))) return; - - { - String httpMessage((char*)0); - httpMessage.reserve(HTTP_PAGE_SIZE); - httpMessage += F("

"); - httpMessage += httpGetNodename(); - httpMessage += F("


"); - httpMessage = F(D_DISPATCH_REBOOT); - - webSendPage(httpGetNodename(), httpMessage.length(), true); - webServer.sendContent(httpMessage); - } - // httpMessage.clear(); - webSendFooter(); - - delay(200); - dispatch_reboot(true); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void webHandleScreenshot() -{ // http://plate01/screenshot - if(!httpIsAuthenticated(F("screenshot"))) return; - - if(webServer.hasArg(F("a"))) { - if(webServer.arg(F("a")) == F("next")) { - dispatch_page_next(); - } else if(webServer.arg(F("a")) == F("prev")) { - dispatch_page_prev(); - } - } - - if(webServer.hasArg(F("q"))) { - lv_disp_t* disp = lv_disp_get_default(); - webServer.setContentLength(122 + disp->driver.hor_res * disp->driver.ver_res * sizeof(lv_color_t)); - webServer.send_P(200, PSTR("image/bmp"), ""); - guiTakeScreenshot(); - webServer.client().stop(); - - } else { - { - String httpMessage((char*)0); - httpMessage.reserve(HTTP_PAGE_SIZE); - httpMessage += F("

"); - httpMessage += httpGetNodename(); - httpMessage += F("


"); - - httpMessage += - F(""); - httpMessage += F("

"); - - httpMessage += F("

"); - httpMessage += - F("

"); - httpMessage += - F("

"); - httpMessage += FPSTR(MAIN_MENU_BUTTON); - - webSendPage(httpGetNodename(), httpMessage.length(), false); - webServer.sendContent(httpMessage); - } - // httpMessage.clear(); - webSendFooter(); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// - -void webHandleAbout() -{ // http://plate01/about - if(!httpIsAuthenticated(F("about"))) return; - - { - String httpMessage((char*)0); - httpMessage.reserve(HTTP_PAGE_SIZE); - - httpMessage += F("

HASP OpenHardware edition

Copyright© 2020 Francis Van Roie "); - httpMessage += FPSTR(MIT_LICENSE); - httpMessage += F("

Based on the previous work of the following open source developers.


"); - httpMessage += F("

HASwitchPlate

Copyright© 2019 Allen Derusha allen@derusha.org"); - httpMessage += FPSTR(MIT_LICENSE); - httpMessage += - F("

LittlevGL

Copyright© 2016 Gábor Kiss-Vámosi
Copyright© 2019 " - "LittlevGL"); - httpMessage += FPSTR(MIT_LICENSE); - httpMessage += F("

zi Font Engine

Copyright© 2020 Francis Van Roie"); - httpMessage += FPSTR(MIT_LICENSE); - httpMessage += F("

TFT_eSPI Library

Copyright© 2020 Bodmer (https://github.com/Bodmer) All " - "rights reserved.
FreeBSD License

"); - httpMessage += - F("

includes parts from the Adafruit_GFX library
Copyright© 2012 Adafruit Industries. " - "All rights reserved
BSD License

"); - httpMessage += F("

ArduinoJson

Copyright© 2014-2020 Benoit BLANCHON"); - httpMessage += FPSTR(MIT_LICENSE); - httpMessage += F("

PubSubClient

Copyright© 2008-2015 Nicholas O'Leary"); - httpMessage += FPSTR(MIT_LICENSE); - httpMessage += - F("

ArduinoLog

Copyright© 2017,2018 Thijs Elenbaas, MrRobot62, rahuldeo2047, NOX73, " - "dhylands, Josha blemasle, mfalkvidd"); - httpMessage += FPSTR(MIT_LICENSE); -#if HASP_USE_SYSLOG > 0 - // Replaced with WiFiUDP client - // httpMessage += F("

Syslog

Copyright© 2016 Martin Sloup"); - // httpMessage += FPSTR(MIT_LICENSE); -#endif -#if HASP_USE_QRCODE > 0 - httpMessage += F("

QR Code generator

Copyright© Project Nayuki"); - httpMessage += FPSTR(MIT_LICENSE); -#endif - httpMessage += F("

AceButton

Copyright© 2018 Brian T. Park"); - httpMessage += FPSTR(MIT_LICENSE); - - httpMessage += FPSTR(MAIN_MENU_BUTTON); - - webSendPage(httpGetNodename(), httpMessage.length(), false); - webServer.sendContent(httpMessage); - } - // httpMessage.clear(); - webSendFooter(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void webHandleInfo() -{ // http://plate01/ - if(!httpIsAuthenticated(F("info"))) return; - - { - char size_buf[32]; - String httpMessage((char*)0); - httpMessage.reserve(HTTP_PAGE_SIZE); - httpMessage += F("

"); - httpMessage += httpGetNodename(); - httpMessage += F("


"); - - /* HASP Stats */ - httpMessage += F("HASP Version: "); - { - char version[32]; - haspGetVersion(version, sizeof(version)); - httpMessage += version; - } - httpMessage += F("
Build DateTime: "); - httpMessage += __DATE__; - httpMessage += F(" "); - httpMessage += __TIME__; - httpMessage += F(" CET
Uptime: "); - - unsigned long time = millis() / 1000; - uint16_t day = time / 86400; - time = time % 86400; - uint8_t hour = time / 3600; - time = time % 3600; - uint8_t min = time / 60; - time = time % 60; - uint8_t sec = time; - - if(day > 0) { - httpMessage += String(day); - httpMessage += F("d "); - } - if(day > 0 || hour > 0) { - httpMessage += String(hour); - httpMessage += F("h "); - } - if(day > 0 || hour > 0 || min > 0) { - httpMessage += String(min); - httpMessage += F("m "); - } - httpMessage += String(sec); - httpMessage += F("s"); - - httpMessage += F("
Free Memory: "); - hasp_util_format_bytes(halGetFreeHeap(), size_buf, sizeof(size_buf)); - httpMessage += size_buf; - httpMessage += F("
Memory Fragmentation: "); - httpMessage += String(halGetHeapFragmentation()); - -#if ARDUINO_ARCH_ESP32 - if(psramFound()) { - httpMessage += F("
Free PSRam: "); - hasp_util_format_bytes(ESP.getFreePsram(), size_buf, sizeof(size_buf)); - httpMessage += size_buf; - httpMessage += F("
PSRam Size: "); - hasp_util_format_bytes(ESP.getPsramSize(), size_buf, sizeof(size_buf)); - httpMessage += size_buf; - } -#endif - - /* LVGL Stats */ - lv_mem_monitor_t mem_mon; - lv_mem_monitor(&mem_mon); - httpMessage += F("

LVGL Memory: "); - hasp_util_format_bytes(mem_mon.total_size, size_buf, sizeof(size_buf)); - httpMessage += size_buf; - httpMessage += F("
LVGL Free: "); - hasp_util_format_bytes(mem_mon.free_size, size_buf, sizeof(size_buf)); - httpMessage += size_buf; - httpMessage += F("
LVGL Fragmentation: "); - httpMessage += mem_mon.frag_pct; - - // httpMessage += F("
LCD Model: ")) + String(LV_HASP_HOR_RES_MAX) + " x " + - // String(LV_HASP_VER_RES_MAX); httpMessage += F("
LCD Version: ")) + - // String(lcdVersion); - httpMessage += F("

LCD Active Page: "); - httpMessage += String(haspGetPage()); - - /* Wifi Stats */ -#if HASP_USE_WIFI > 0 - httpMessage += F("

SSID: "); - httpMessage += String(WiFi.SSID()); - httpMessage += F("
Signal Strength: "); - - int8_t rssi = WiFi.RSSI(); - httpMessage += String(rssi); - httpMessage += F("dBm ("); - - if(rssi >= -50) { - httpMessage += F("Excellent)"); - } else if(rssi >= -60) { - httpMessage += F("Good)"); - } else if(rssi >= -70) { - httpMessage += F("Fair)"); - } else if(rssi >= -80) { - httpMessage += F("Weak)"); - } else { - httpMessage += F("Very Bad)"); - } -#if defined(STM32F4xx) - byte mac[6]; - WiFi.macAddress(mac); - char macAddress[16]; - snprintf_P(macAddress, sizeof(macAddress), PSTR("%02x%02x%02x"), mac[0], mac[1], mac[2], mac[3], mac[4], - mac[5]); - httpMessage += F("
IP Address: "); - httpMessage += String(WiFi.localIP()); - httpMessage += F("
Gateway: "); - httpMessage += String(WiFi.gatewayIP()); - httpMessage += F("
MAC Address: "); - httpMessage += String(macAddress); -#else - httpMessage += F("
IP Address: "); - httpMessage += String(WiFi.localIP().toString()); - httpMessage += F("
Gateway: "); - httpMessage += String(WiFi.gatewayIP().toString()); - httpMessage += F("
DNS Server: "); - httpMessage += String(WiFi.dnsIP().toString()); - httpMessage += F("
MAC Address: "); - httpMessage += String(WiFi.macAddress()); -#endif -#endif -#if HASP_USE_ETHERNET > 0 -#if defined(ARDUINO_ARCH_ESP32) - httpMessage += F("

Ethernet: "); - httpMessage += String(ETH.linkSpeed()); - httpMessage += F(" Mbps"); - if(ETH.fullDuplex()) { - httpMessage += F(" FULL_DUPLEX"); - } - httpMessage += F("
IP Address: "); - httpMessage += String(ETH.localIP().toString()); - httpMessage += F("
Gateway: "); - httpMessage += String(ETH.gatewayIP().toString()); - httpMessage += F("
DNS Server: "); - httpMessage += String(ETH.dnsIP().toString()); - httpMessage += F("
MAC Address: "); - httpMessage += String(ETH.macAddress()); -#endif -#endif -/* Mqtt Stats */ -#if HASP_USE_MQTT > 0 - httpMessage += F("

MQTT Status: "); - if(mqttIsConnected()) { // Check MQTT connection - httpMessage += F("Connected"); - } else { - httpMessage += F("Disconnected, return code: "); - // +String(mqttClient.returnCode()); - } - httpMessage += F("
MQTT ClientID: "); - - { - char mqttClientId[64]; - String mac = halGetMacAddress(3, ""); - mac.toLowerCase(); - snprintf_P(mqttClientId, sizeof(mqttClientId), PSTR("%s-%s"), mqttNodeName, mac.c_str()); - httpMessage += mqttClientId; - } - -#endif // MQTT - - /* ESP Stats */ - httpMessage += F("

MCU Model: "); - httpMessage += halGetChipModel(); - httpMessage += F("
CPU Frequency: "); - httpMessage += String(halGetCpuFreqMHz()); - httpMessage += F("MHz"); - -#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) - httpMessage += F("
Flash Chip Size: "); - hasp_util_format_bytes(ESP.getFlashChipSize(), size_buf, sizeof(size_buf)); - httpMessage += size_buf; - - httpMessage += F("
Program Size: "); - hasp_util_format_bytes(ESP.getSketchSize(), size_buf, sizeof(size_buf)); - httpMessage += size_buf; - - httpMessage += F("
Free Program Space: "); - hasp_util_format_bytes(ESP.getFreeSketchSpace(), size_buf, sizeof(size_buf)); - httpMessage += size_buf; -#endif - - //#if defined(ARDUINO_ARCH_ESP32) - // httpMessage += F("
ESP SDK version: "); - // httpMessage += String(ESP.getSdkVersion()); - //#else - httpMessage += F("
Core version: "); - httpMessage += String(halGetCoreVersion()); - //#endif - httpMessage += F("
Last Reset: "); - httpMessage += halGetResetInfo(); - - httpMessage += FPSTR(MAIN_MENU_BUTTON); - - webSendPage(httpGetNodename(), httpMessage.length(), false); - webServer.sendContent(httpMessage); - } - // httpMessage.clear(); - webSendFooter(); -} - -// String getContentType(String filename) -// { -// if(webServer.hasArg(F("download"))) { -// return F("application/octet-stream"); -// } else if(filename.endsWith(F(".htm")) || filename.endsWith(F(".html"))) { -// return F("text/html"); -// } else if(filename.endsWith(F(".css"))) { -// return F("text/css"); -// } else if(filename.endsWith(F(".js"))) { -// return F("application/javascript"); -// } else if(filename.endsWith(F(".png"))) { -// return F("image/png"); -// } else if(filename.endsWith(F(".gif"))) { -// return F("image/gif"); -// } else if(filename.endsWith(F(".jpg"))) { -// return F("image/jpeg"); -// } else if(filename.endsWith(F(".ico"))) { -// return F("image/x-icon"); -// } else if(filename.endsWith(F(".xml"))) { -// return F("text/xml"); -// } else if(filename.endsWith(F(".pdf"))) { -// return F("application/x-pdf"); -// } else if(filename.endsWith(F(".zip"))) { -// return F("application/x-zip"); -// } else if(filename.endsWith(F(".gz"))) { -// return F("application/x-gzip"); -// } -// return F("text/plain"); -// } - -static String getContentType(const String& path) -{ - char buff[sizeof(mime::mimeTable[0].mimeType)]; - // Check all entries but last one for match, return if found - for(size_t i = 0; i < sizeof(mime::mimeTable) / sizeof(mime::mimeTable[0]) - 1; i++) { - strcpy_P(buff, mime::mimeTable[i].endsWith); - if(path.endsWith(buff)) { - strcpy_P(buff, mime::mimeTable[i].mimeType); - return String(buff); - } - } - // Fall-through and just return default type - strcpy_P(buff, mime::mimeTable[sizeof(mime::mimeTable) / sizeof(mime::mimeTable[0]) - 1].mimeType); - return String(buff); -} - -/* String urldecode(String str) -{ - String encodedString = ""; - char c; - for(unsigned int i = 0; i < str.length(); i++) { - c = str.charAt(i); - if(c == '+') { - encodedString += ' '; - } else if(c == '%') { - // char buffer[3]; - char buffer[128]; - i++; - buffer[0] = str.charAt(i); - i++; - buffer[1] = str.charAt(i); - buffer[2] = '\0'; - c = (char)strtol((const char *)&buffer, NULL, 16); - encodedString += c; - } else { - encodedString += c; - } - yield(); - } - return encodedString; -} */ - -static unsigned long htppLastLoopTime = 0; -void webUploadProgress() -{ - long t = webServer.header("Content-Length").toInt(); - if(millis() - htppLastLoopTime >= 1250) { - LOG_VERBOSE(TAG_HTTP, F(D_BULLET "Uploaded %u / %d bytes"), upload->totalSize + upload->currentSize, t); - htppLastLoopTime = millis(); - } - if(t > 0) t = (upload->totalSize + upload->currentSize) * 100 / t; - haspProgressVal(t); -} - -#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) -static inline void webUpdatePrintError() -{ -#if defined(ARDUINO_ARCH_ESP8266) - String output((char*)0); - output.reserve(128); - StringStream stream((String&)output); - Update.printError(stream); // ESP8266 only has printError() - LOG_ERROR(TAG_HTTP, output.c_str()); - haspProgressMsg(output.c_str()); -#elif defined(ARDUINO_ARCH_ESP32) - LOG_ERROR(TAG_HTTP, Update.errorString()); // ESP32 has errorString() - haspProgressMsg(Update.errorString()); -#endif -} - -void webUpdateReboot() -{ - LOG_INFO(TAG_HTTP, F("Update Success: %u bytes received. Rebooting..."), upload->totalSize); - - { - String httpMessage((char*)0); - httpMessage.reserve(HTTP_PAGE_SIZE); - httpMessage += F("

"); - httpMessage += httpGetNodename(); - httpMessage += F("


"); - httpMessage += F("Upload complete. Rebooting device, please wait..."); - - webSendPage(httpGetNodename(), httpMessage.length(), true); - webServer.sendContent(httpMessage); - } - // httpMessage.clear(); - webSendFooter(); - - delay(250); - dispatch_reboot(true); // Save the current config -} - -void webHandleFirmwareUpload() -{ - upload = &webServer.upload(); - - if(upload->status == UPLOAD_FILE_START) { - if(!httpIsAuthenticated(F("update"))) return; - LOG_TRACE(TAG_HTTP, F("Update: %s"), upload->filename.c_str()); - haspProgressMsg(upload->filename.c_str()); - // WiFiUDP::stopAll(); - uint32_t maxSketchSpace = (ESP.getFreeSketchSpace() - 0x1000) & 0xFFFFF000; - // if(!Update.begin(UPDATE_SIZE_UNKNOWN)) { // start with max available size - if(!Update.begin(maxSketchSpace)) { // start with max available size - webUpdatePrintError(); - } - - } else if(upload->status == UPLOAD_FILE_WRITE) { - // flashing firmware to ESP - if(Update.write(upload->buf, upload->currentSize) != upload->currentSize) { - webUpdatePrintError(); - } else { - webUploadProgress(); - } - - } else if(upload->status == UPLOAD_FILE_END) { - haspProgressVal(100); - if(Update.end(true)) { // true to set the size to the current progress - haspProgressMsg(F(D_OTA_UPDATE_APPLY)); - webUpdateReboot(); - } else { - webUpdatePrintError(); - } - } -} -#endif - -#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 -bool handleFileRead(String path) -{ - if(!httpIsAuthenticated(F("fileread"))) return false; - - path = webServer.urlDecode(path).substring(0, 31); - if(path.endsWith("/")) { - path += F("index.htm"); - } - String pathWithGz = path + F(".gz"); - if(HASP_FS.exists(pathWithGz) || HASP_FS.exists(path)) { - if(HASP_FS.exists(pathWithGz)) path += F(".gz"); - - File file = HASP_FS.open(path, "r"); - String contentType = getContentType(path); - if(path == F("/edit.htm.gz")) { - contentType = F("text/html"); - } - webServer.streamFile(file, contentType); - file.close(); - return true; - } - return false; -} - -void handleFileUpload() -{ - if(webServer.uri() != "/edit") { - return; - } - upload = &webServer.upload(); - if(upload->status == UPLOAD_FILE_START) { - if(!httpIsAuthenticated(F("fileupload"))) return; - LOG_INFO(TAG_HTTP, F("Total size: %s"), webServer.headerName(0).c_str()); - String filename((char*)0); - filename.reserve(128); - filename = upload->filename; - if(!filename.startsWith("/")) { - filename = "/"; - filename += upload->filename; - } - if(filename.length() < 32) { - fsUploadFile = HASP_FS.open(filename, "w"); - LOG_TRACE(TAG_HTTP, F("handleFileUpload Name: %s"), filename.c_str()); - haspProgressMsg(fsUploadFile.name()); - } else { - LOG_ERROR(TAG_HTTP, F("Filename %s is too long"), filename.c_str()); - } - } else if(upload->status == UPLOAD_FILE_WRITE) { - // DBG_OUTPUT_PORT.print("handleFileUpload Data: "); debugPrintln(upload.currentSize); - if(fsUploadFile) { - if(fsUploadFile.write(upload->buf, upload->currentSize) != upload->currentSize) { - LOG_ERROR(TAG_HTTP, F("Failed to write received data to file")); - } else { - webUploadProgress(); // Moved to httpEverySecond Loop - } - } - } else if(upload->status == UPLOAD_FILE_END) { - if(fsUploadFile) { - LOG_INFO(TAG_HTTP, F("Uploaded %s (%u bytes)"), fsUploadFile.name(), upload->totalSize); - fsUploadFile.close(); - } - haspProgressVal(255); - - // Redirect to /config/hasp page. This flushes the web buffer and frees the memory - webServer.sendHeader(String(F("Location")), String(F("/config/hasp")), true); - webServer.send_P(302, PSTR("text/plain"), ""); - // httpReconnect(); - } -} - -void handleFileDelete() -{ - if(!httpIsAuthenticated(F("filedelete"))) return; - - char mimetype[16]; - snprintf_P(mimetype, sizeof(mimetype), PSTR("text/plain")); - - if(webServer.args() == 0) { - return webServer.send_P(500, mimetype, PSTR("BAD ARGS")); - } - String path = webServer.arg(0); - LOG_TRACE(TAG_HTTP, F("handleFileDelete: %s"), path.c_str()); - if(path == "/") { - return webServer.send_P(500, mimetype, PSTR("BAD PATH")); - } - if(!HASP_FS.exists(path)) { - return webServer.send_P(404, mimetype, PSTR("FileNotFound")); - } - HASP_FS.remove(path); - webServer.send_P(200, mimetype, PSTR("")); - // path.clear(); -} - -void handleFileCreate() -{ - if(!httpIsAuthenticated(F("filecreate"))) return; - - if(webServer.args() == 0) { - return webServer.send(500, PSTR("text/plain"), PSTR("BAD ARGS")); - } - String path = webServer.arg(0); - LOG_TRACE(TAG_HTTP, F("handleFileCreate: %s"), path.c_str()); - if(path == "/") { - return webServer.send(500, PSTR("text/plain"), PSTR("BAD PATH")); - } - if(HASP_FS.exists(path)) { - return webServer.send(500, PSTR("text/plain"), PSTR("FILE EXISTS")); - } - File file = HASP_FS.open(path, "w"); - if(file) { - file.close(); - } else { - return webServer.send(500, PSTR("text/plain"), PSTR("CREATE FAILED")); - } - webServer.send(200, PSTR("text/plain"), ""); - path.clear(); -} - -void handleFileList() -{ - if(!httpIsAuthenticated(F("filelist"))) return; - - if(!webServer.hasArg(F("dir"))) { - webServer.send(500, PSTR("text/plain"), PSTR("BAD ARGS")); - return; - } - - String path = webServer.arg(F("dir")); - LOG_TRACE(TAG_HTTP, F("handleFileList: %s"), path.c_str()); - path.clear(); - -#if defined(ARDUINO_ARCH_ESP32) - File root = HASP_FS.open("/", FILE_READ); - File file = root.openNextFile(); - String output = "["; - - while(file) { - if(output != "[") { - output += ','; - } - bool isDir = false; - output += F("{\"type\":\""); - output += (isDir) ? F("dir") : F("file"); - output += F("\",\"name\":\""); - if(file.name()[0] == '/') { - output += &(file.name()[1]); - } else { - output += file.name(); - } - output += F("\"}"); - - // file.close(); - file = root.openNextFile(); - } - output += "]"; - webServer.send(200, PSTR("text/json"), output); -#elif defined(ARDUINO_ARCH_ESP8266) - Dir dir = HASP_FS.openDir(path); - String output = "["; - while(dir.next()) { - File entry = dir.openFile("r"); - if(output != "[") { - output += ','; - } - bool isDir = false; - output += F("{\"type\":\""); - output += (isDir) ? F("dir") : F("file"); - output += F("\",\"name\":\""); - if(entry.name()[0] == '/') { - output += &(entry.name()[1]); - } else { - output += entry.name(); - } - output += F("\"}"); - entry.close(); - } - output += "]"; - webServer.send(200, PSTR("text/json"), output); -#endif -} -#endif - -//////////////////////////////////////////////////////////////////////////////////////////////////// -#if HASP_USE_CONFIG > 0 -void webHandleConfig() -{ // http://plate01/config - if(!httpIsAuthenticated(F("config"))) return; - - saveConfig(); - -// Reboot after saving wifi config in AP mode -#if HASP_USE_WIFI > 0 && !defined(STM32F4xx) - if(WiFi.getMode() != WIFI_STA) { - httpHandleReboot(); - } -#endif - - { - String httpMessage((char*)0); - httpMessage.reserve(HTTP_PAGE_SIZE); - httpMessage += F("

"); - httpMessage += httpGetNodename(); - httpMessage += F("


"); - -#if HASP_USE_WIFI > 0 - httpMessage += F("

"); -#endif - -#if HASP_USE_MQTT > 0 - httpMessage += F("

"); -#endif - - httpMessage += F("

"); - - httpMessage += F("

"); - - // httpMessage += - // F("

"); - -#if HASP_USE_GPIO > 0 - httpMessage += F("

"); -#endif - - httpMessage += F("

"); - - httpMessage += - F("

"); - - httpMessage += FPSTR(MAIN_MENU_BUTTON); - - webSendPage(httpGetNodename(), httpMessage.length(), false); - webServer.sendContent(httpMessage); - } - // httpMessage.clear(); - webSendFooter(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -#if HASP_USE_MQTT > 0 -void webHandleMqttConfig() -{ // http://plate01/config/mqtt - if(!httpIsAuthenticated(F("config/mqtt"))) return; - - StaticJsonDocument<256> settings; - mqttGetConfig(settings.to()); - - { - // char buffer[128]; - String httpMessage((char*)0); - httpMessage.reserve(HTTP_PAGE_SIZE); - httpMessage += F("

"); - httpMessage += httpGetNodename(); - httpMessage += F("


"); - - httpMessage += F("
"); - httpMessage += F("HASP Node Name (required. lowercase letters, numbers, and _ only)" - "

Group Name (required)

MQTT Broker (required)
MQTT Port (required)
MQTT User (optional)
MQTT Password (optional)

"); - - add_form_button(httpMessage, F("↩ " D_HTTP_CONFIGURATION), F("/config"), F("")); - // httpMessage += PSTR("

"); - - webSendPage(httpGetNodename(), httpMessage.length(), false); - webServer.sendContent(httpMessage); - } - // httpMessage.clear(); - webSendFooter(); -} -#endif - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void webHandleGuiConfig() -{ // http://plate01/config/wifi - if(!httpIsAuthenticated(F("config/gui"))) return; - - { - StaticJsonDocument<256> settings; - guiGetConfig(settings.to()); - - String httpMessage((char*)0); - httpMessage.reserve(HTTP_PAGE_SIZE); - httpMessage += F("

"); - httpMessage += httpGetNodename(); - httpMessage += F("


"); - - httpMessage += F("
"); - - httpMessage += F("

Short Idle

"); - - httpMessage += F("

Long Idle

"); - - int8_t rotation = settings[FPSTR(FP_GUI_ROTATION)].as(); - httpMessage += F("

Orientation

"); - - httpMessage += F("

()) httpMessage += F(" checked"); - httpMessage += F(">Invert Colors"); - - httpMessage += F("

()) httpMessage += F(" checked"); - httpMessage += F(">Show Pointer"); - - int8_t bcklpin = settings[FPSTR(FP_GUI_BACKLIGHTPIN)].as(); - httpMessage += F("

Backlight Control

"); - - add_button(httpMessage, F(D_HTTP_SAVE_SETTINGS), F("name='save' value='gui'")); - close_form(httpMessage); - // httpMessage += - // F("

"); - -#if TOUCH_DRIVER == 2046 && defined(TOUCH_CS) - add_form_button(httpMessage, F(D_HTTP_CALIBRATE), F("/config/gui"), F("name='action' value='calibrate'")); - -// httpMessage += PSTR("

"); -#endif - - add_form_button(httpMessage, F("↩ " D_HTTP_CONFIGURATION), F("/config"), F("")); - - // httpMessage += PSTR("

"); - - webSendPage(httpGetNodename(), httpMessage.length(), false); - webServer.sendContent(httpMessage); - } - webSendFooter(); - - if(webServer.hasArg(F("action"))) dispatch_text_line(webServer.arg(F("action")).c_str()); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -#if HASP_USE_WIFI > 0 -void webHandleWifiConfig() -{ // http://plate01/config/wifi - if(!httpIsAuthenticated(F("config/wifi"))) return; - - StaticJsonDocument<256> settings; - wifiGetConfig(settings.to()); - - String httpMessage((char*)0); - httpMessage.reserve(HTTP_PAGE_SIZE); - httpMessage += F("

"); - httpMessage += httpGetNodename(); - httpMessage += F("


"); - - httpMessage += F("
"); - httpMessage += F("WiFi SSID (required)
WiFi Password (required)

"); - -#if HASP_USE_WIFI > 0 && !defined(STM32F4xx) - if(WiFi.getMode() == WIFI_STA) { - add_form_button(httpMessage, F("↩ " D_HTTP_CONFIGURATION), F("/config"), F("")); - // httpMessage += PSTR("

"); - } -#endif - - webSendPage(httpGetNodename(), httpMessage.length(), false); - webServer.sendContent(httpMessage); -#if defined(STM32F4xx) - httpMessage = ""; -#else - httpMessage.clear(); -#endif - webSendFooter(); -} -#endif - -//////////////////////////////////////////////////////////////////////////////////////////////////// -#if HASP_USE_HTTP > 0 -void webHandleHttpConfig() -{ // http://plate01/config/http - if(!httpIsAuthenticated(F("config/http"))) return; - - { - StaticJsonDocument<256> settings; - httpGetConfig(settings.to()); - - // String httpMessage((char *)0); - // httpMessage.reserve(HTTP_PAGE_SIZE); - // httpMessage += F("

"); - // httpMessage += httpGetNodename(); - // httpMessage += F("


"); - - // httpMessage += F("
"); - // httpMessage += F("Web Username (optional)
Web Password (optional)

"); - - // httpMessage += PSTR("

"); - - char httpMessage[HTTP_PAGE_SIZE]; - - size_t len = snprintf_P( - httpMessage, sizeof(httpMessage), - PSTR("

%s


" - "
" - "Web Username (optional)" - "
" - "Web Password (optional)" - "" - "

" - "

"), - httpGetNodename(), settings[FPSTR(FP_CONFIG_USER)].as().c_str(), - settings[FPSTR(FP_CONFIG_PASS)].as().c_str()); - - // if(settings[FPSTR(FP_CONFIG_PASS)].as() != "") { - // httpMessage += F(D_PASSWORD_MASK); - // } - - webSendPage(httpGetNodename(), len, false); - webServer.sendContent(httpMessage); - } - // httpMessage.clear(); - webSendFooter(); -} -#endif - -//////////////////////////////////////////////////////////////////////////////////////////////////// -#if defined(HASP_USE_GPIO) && (HASP_USE_GPIO > 0) -void webHandleGpioConfig() -{ // http://plate01/config/gpio - if(!httpIsAuthenticated(F("config/gpio"))) return; - uint8_t configCount = 0; - - // StaticJsonDocument<256> settings; - // gpioGetConfig(settings.to()); - - if(webServer.hasArg(PSTR("save"))) { - uint8_t id = webServer.arg(F("id")).toInt(); - uint8_t pin = webServer.arg(F("pin")).toInt(); - uint8_t type = webServer.arg(F("type")).toInt() + webServer.arg(F("state")).toInt(); - uint8_t group = webServer.arg(F("group")).toInt(); - uint8_t pinfunc = webServer.arg(F("func")).toInt(); - gpioSavePinConfig(id, pin, type, group, pinfunc); - } - if(webServer.hasArg(PSTR("del"))) { - uint8_t id = webServer.arg(F("id")).toInt(); - uint8_t pin = webServer.arg(F("pin")).toInt(); - gpioSavePinConfig(id, pin, HASP_GPIO_FREE, 0, 0); - } - - { - String httpMessage((char*)0); - httpMessage.reserve(HTTP_PAGE_SIZE); - httpMessage += F("

"); - httpMessage += httpGetNodename(); - httpMessage += F("


"); - - httpMessage += F("
"); - - httpMessage += F(""); - - for(uint8_t gpio = 0; gpio < NUM_DIGITAL_PINS; gpio++) { - for(uint8_t id = 0; id < HASP_NUM_GPIO_CONFIG; id++) { - hasp_gpio_config_t conf = gpioGetPinConfig(id); - if((conf.pin == gpio) && gpioConfigInUse(id) && gpioInUse(gpio) && !gpioIsSystemPin(gpio)) { - httpMessage += F(""); - configCount++; - } - } - } - - httpMessage += F("
PinTypeGroupDefaultAction
"); - httpMessage += halGpioName(gpio); - httpMessage += F(""); - - switch(conf.type & 0xfe) { - case HASP_GPIO_SWITCH: - // case HASP_GPIO_SWITCH_INVERTED: - httpMessage += F("Switch"); - break; - case HASP_GPIO_BUTTON: - // case HASP_GPIO_BUTTON_INVERTED: - httpMessage += F("Button"); - break; - case HASP_GPIO_LED: - // case HASP_GPIO_LED_INVERTED: - httpMessage += F("Led"); - break; - case HASP_GPIO_LED_R: - case HASP_GPIO_LED_G: - case HASP_GPIO_LED_B: - // case HASP_GPIO_LED_INVERTED: - httpMessage += F("Mood "); - break; - case HASP_GPIO_RELAY: - // case HASP_GPIO_RELAY_INVERTED: - httpMessage += F("Relay"); - break; - case HASP_GPIO_PWM: - // case HASP_GPIO_PWM_INVERTED: - httpMessage += F("PWM"); - break; - default: - httpMessage += F("Unknown"); - } - - switch(conf.type & 0xfe) { - case HASP_GPIO_LED_R: - httpMessage += F("Red"); - break; - case HASP_GPIO_LED_G: - httpMessage += F("Green"); - break; - case HASP_GPIO_LED_B: - httpMessage += F("Blue"); - break; - } - - httpMessage += F(""); - httpMessage += conf.group; - httpMessage += F(""); - - // bool inverted = (conf.type == HASP_GPIO_BUTTON_INVERTED) || - // (conf.type == HASP_GPIO_SWITCH_INVERTED) || (conf.type == HASP_GPIO_LED_INVERTED) - // || (conf.type == HASP_GPIO_RELAY_INVERTED) || (conf.type == - // HASP_GPIO_PWM_INVERTED); - - httpMessage += (conf.type & 0x1) ? F("High") : F("Low"); - - httpMessage += F("Edit Delete
"); - - if(configCount < HASP_NUM_GPIO_CONFIG) { - httpMessage += F("

"); - httpMessage += F("

"); - } - - add_form_button(httpMessage, F("↩ " D_HTTP_CONFIGURATION), F("/config"), F("")); - // httpMessage += F("

"); - - webSendPage(httpGetNodename(), httpMessage.length(), false); - webServer.sendContent(httpMessage); - } - // httpMessage.clear(); - webSendFooter(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void webHandleGpioOptions() -{ // http://plate01/config/gpio/options - if(!httpIsAuthenticated(F("config/gpio/options"))) return; - - { - StaticJsonDocument<256> settings; - guiGetConfig(settings.to()); - - uint8_t config_id = webServer.arg(F("id")).toInt(); - - String httpMessage((char*)0); - httpMessage.reserve(HTTP_PAGE_SIZE); - httpMessage += F("

"); - httpMessage += httpGetNodename(); - httpMessage += F("


"); - - httpMessage += F("
"); - httpMessage += F(""); - - httpMessage += F("

GPIO Options"); - httpMessage += config_id; - httpMessage += F(" Options

"); - - httpMessage += F("

Pin

"); - - bool selected; - httpMessage += F("

Type

"); - - httpMessage += F("

Group

"); - - httpMessage += F("

Default State

"); - - httpMessage += - F("

"); - - httpMessage += PSTR("

"); - - webSendPage(httpGetNodename(), httpMessage.length(), false); - webServer.sendContent(httpMessage); - } - webSendFooter(); - - if(webServer.hasArg(F("action"))) dispatch_text_line(webServer.arg(F("action")).c_str()); // Security check -} -#endif // HASP_USE_GPIO - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void webHandleDebugConfig() -{ // http://plate01/config/debug - if(!httpIsAuthenticated(F("config/debug"))) return; - - StaticJsonDocument<256> settings; - debugGetConfig(settings.to()); - - { - String httpMessage((char*)0); - httpMessage.reserve(HTTP_PAGE_SIZE); - httpMessage += F("

"); - httpMessage += httpGetNodename(); - httpMessage += F("


"); - - httpMessage += F("
"); - - uint16_t baudrate = settings[FPSTR(FP_CONFIG_BAUD)].as(); - httpMessage += F("

Serial Port

Telemetry Period (Seconds, 0=disable) " - "

"); - -#if HASP_USE_SYSLOG > 0 - httpMessage += F("Syslog Hostame (optional)
Syslog Port (optional) Syslog Facility
Syslog Protocol () == 0) httpMessage += F(" checked"); - httpMessage += F(">IETF (RFC 5424)   () == 1) httpMessage += F(" checked"); - httpMessage += F(">BSD (RFC 3164)"); -#endif - - httpMessage += - F("

"); - - add_form_button(httpMessage, F("↩ " D_HTTP_CONFIGURATION), F("/config"), F("")); - // httpMessage += PSTR("

"); - - webSendPage(httpGetNodename(), httpMessage.length(), false); - webServer.sendContent(httpMessage); - } - // httpMessage.clear(); - webSendFooter(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void webHandleHaspConfig() -{ // http://plate01/config/http - if(!httpIsAuthenticated(F("config/hasp"))) return; - - StaticJsonDocument<256> settings; - haspGetConfig(settings.to()); - - { - String httpMessage((char*)0); - httpMessage.reserve(HTTP_PAGE_SIZE); - httpMessage += F("

"); - httpMessage += httpGetNodename(); - httpMessage += F("


"); - - httpMessage += F("

"); - httpMessage += F("


"); - - // httpMessage += F("
"); - httpMessage += F(""); - httpMessage += F("

UI Theme (required)
"); - httpMessage += - F("Hue

"); - httpMessage += F("

Default Font

"); - - httpMessage += F("

Startup Layout (optional)
Startup Page (required)

Startup Brightness (required)

"); - - httpMessage += - F("

"); - - // httpMessage += - // F("

"); - httpMessage += FPSTR(MAIN_MENU_BUTTON); - - webSendPage(httpGetNodename(), httpMessage.length(), false); - webServer.sendContent(httpMessage); - } - // httpMessage.clear(); - webSendFooter(); -} -#endif // HASP_USE_CONFIG - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void httpHandleNotFound() -{ // webServer 404 -#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 - if(handleFileRead(webServer.uri())) return; -#endif - -#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) - LOG_TRACE(TAG_HTTP, F("Sending 404 to client connected from: %s"), - webServer.client().remoteIP().toString().c_str()); -#else - // LOG_TRACE(TAG_HTTP,F("Sending 404 to client connected from: %s"), String(webServer.client().remoteIP()).c_str()); -#endif - - String httpMessage((char*)0); - httpMessage.reserve(HTTP_PAGE_SIZE); - - httpMessage += F("File Not Found\n\nURI: "); - httpMessage += webServer.uri(); - httpMessage += F("\nMethod: "); - httpMessage += (webServer.method() == HTTP_GET) ? F("GET") : F("POST"); - httpMessage += F("\nArguments: "); - httpMessage += webServer.args(); - httpMessage += "\n"; - for(int i = 0; i < webServer.args(); i++) { - httpMessage += " " + webServer.argName(i) + ": " + webServer.arg(i) + "\n"; - } - webServer.send(404, PSTR("text/plain"), httpMessage.c_str()); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void webHandleFirmware() -{ - if(!httpIsAuthenticated(F("firmware"))) return; - - { - String httpMessage((char*)0); - httpMessage.reserve(HTTP_PAGE_SIZE); - httpMessage += F("

"); - httpMessage += httpGetNodename(); - httpMessage += F("


"); - - httpMessage += F("

"); - httpMessage += F("

"); - - // httpMessage += F("

"); - // httpMessage += F("

"); - - httpMessage += FPSTR(MAIN_MENU_BUTTON); - - webSendPage(httpGetNodename(), httpMessage.length(), false); - webServer.sendContent(httpMessage); - } - // httpMessage.clear(); - webSendFooter(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void httpHandleEspFirmware() -{ // http://plate01/espfirmware - if(!httpIsAuthenticated(F("espfirmware"))) return; - - { - String httpMessage((char*)0); - httpMessage.reserve(HTTP_PAGE_SIZE); - httpMessage += F("

"); - httpMessage += httpGetNodename(); - httpMessage += F("


"); - - httpMessage += F("

ESP update

Updating ESP firmware from: "); - httpMessage += webServer.arg("espFirmware"); - - webSendPage(httpGetNodename(), httpMessage.length(), true); - webServer.sendContent(httpMessage); - // httpMessage.clear(); - } - webSendFooter(); - - LOG_TRACE(TAG_HTTP, F("Attempting ESP firmware update from: %s"), webServer.arg("espFirmware").c_str()); - // espStartOta(webServer.arg("espFirmware")); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -#if HASP_USE_CONFIG > 0 -void webHandleSaveConfig() -{ - if(!httpIsAuthenticated(F("saveConfig"))) return; - - configWriteConfig(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void httpHandleResetConfig() -{ // http://plate01/resetConfig - if(!httpIsAuthenticated(F("resetConfig"))) return; - - bool resetConfirmed = webServer.arg(F("confirm")) == F("yes"); - - { - String httpMessage((char*)0); - httpMessage.reserve(HTTP_PAGE_SIZE); - httpMessage += F("

"); - httpMessage += httpGetNodename(); - httpMessage += F("


"); - - if(resetConfirmed) { // User has confirmed, so reset everything - bool formatted = configClearEeprom(); - if(formatted) { - httpMessage += F("Resetting all saved settings and restarting device"); - } else { - httpMessage += F("Failed to format the internal flash partition"); - resetConfirmed = false; - } - } else { - httpMessage += - F("

Warning

This process will reset all settings to the default values. The internal flash " - "will " - "be erased and the device is restarted. You may need to connect to the WiFi AP displayed on the " - "panel to " - "re-configure the device before accessing it again. ALL FILES WILL BE LOST!" - "


" - "

" - "


"); - - add_form_button(httpMessage, F("↩ " D_HTTP_CONFIGURATION), F("/config"), F("")); - // httpMessage += - // PSTR("

"); - } - - webSendPage(httpGetNodename(), httpMessage.length(), resetConfirmed); - webServer.sendContent(httpMessage); - } - // httpMessage.clear(); - webSendFooter(); - - if(resetConfirmed) { - delay(250); - // configClearSaved(); - dispatch_reboot(false); // Do not save the current config - } -} -#endif // HASP_USE_CONFIG - -void httpStart() -{ - webServer.begin(); - webServerStarted = true; -#if HASP_USE_WIFI > 0 -#if defined(STM32F4xx) - IPAddress ip; - ip = WiFi.localIP(); - LOG_INFO(TAG_HTTP, F(D_SERVICE_STARTED " @ http://%d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]); -#else - LOG_INFO(TAG_HTTP, F(D_SERVICE_STARTED " @ http://%s"), - (WiFi.getMode() != WIFI_STA ? WiFi.softAPIP().toString().c_str() : WiFi.localIP().toString().c_str())); -#endif -#else - IPAddress ip; -#if defined(ARDUINO_ARCH_ESP32) - ip = ETH.localIP(); -#else - ip = Ethernet.localIP(); -#endif - LOG_INFO(TAG_HTTP, F(D_SERVICE_STARTED " @ http://%d.%d.%d.%d"), ip[0], ip[1], ip[2], ip[3]); -#endif -} - -void httpStop() -{ - webServer.stop(); - webServerStarted = false; - LOG_WARNING(TAG_HTTP, F(D_SERVICE_STOPPED)); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void httpSetup() -{ - // httpSetConfig(settings); - - // ask server to track these headers - const char* headerkeys[] = {"Content-Length"}; // "Authentication" - size_t headerkeyssize = sizeof(headerkeys) / sizeof(char*); - webServer.collectHeaders(headerkeys, headerkeyssize); - - // Shared pages - webServer.on(F("/about"), webHandleAbout); - webServer.onNotFound(httpHandleNotFound); - -#if HASP_USE_WIFI > 0 -#if !defined(STM32F4xx) - -#if HASP_USE_CONFIG > 0 - if(WiFi.getMode() != WIFI_STA) { - LOG_TRACE(TAG_HTTP, F("Wifi access point")); - webServer.on(F("/"), webHandleWifiConfig); - webServer.on(F("/config"), webHandleConfig); - return; - } - -#endif -#endif -#endif - - webServer.on(F("/page/"), []() { - String pageid = webServer.arg(F("page")); - webServer.send(200, PSTR("text/plain"), "Page: '" + pageid + "'"); - haspSetPage(pageid.toInt()); - }); - -#if HASP_USE_SPIFFS > 0 || HASP_USE_LITTLEFS > 0 - webServer.on(F("/list"), HTTP_GET, handleFileList); - // load editor - webServer.on(F("/edit"), HTTP_GET, []() { - if(!handleFileRead("/edit.htm")) { - char mimetype[16]; - snprintf_P(mimetype, sizeof(mimetype), PSTR("text/plain")); - webServer.send_P(404, mimetype, PSTR("FileNotFound")); - } - }); - webServer.on(F("/edit"), HTTP_PUT, handleFileCreate); - webServer.on(F("/edit"), HTTP_DELETE, handleFileDelete); - // first callback is called after the request has ended with all parsed arguments - // second callback handles file uploads at that location - webServer.on( - F("/edit"), HTTP_POST, - []() { - webServer.send(200, "text/plain", ""); - LOG_VERBOSE(TAG_HTTP, F("Headers: %d"), webServer.headers()); - }, - handleFileUpload); -#endif - - webServer.on(F("/"), webHandleRoot); - webServer.on(F("/info"), webHandleInfo); - webServer.on(F("/screenshot"), webHandleScreenshot); - webServer.on(F("/firmware"), webHandleFirmware); - webServer.on(F("/reboot"), httpHandleReboot); - -#if HASP_USE_CONFIG > 0 - webServer.on(F("/config/hasp"), webHandleHaspConfig); - webServer.on(F("/config/http"), webHandleHttpConfig); - webServer.on(F("/config/gui"), webHandleGuiConfig); - webServer.on(F("/config/debug"), webHandleDebugConfig); -#if HASP_USE_MQTT > 0 - webServer.on(F("/config/mqtt"), webHandleMqttConfig); -#endif -#if HASP_USE_WIFI > 0 - webServer.on(F("/config/wifi"), webHandleWifiConfig); -#endif -#if HASP_USE_GPIO > 0 - webServer.on(F("/config/gpio"), webHandleGpioConfig); - webServer.on(F("/config/gpio/options"), webHandleGpioOptions); -#endif - webServer.on(F("/saveConfig"), webHandleSaveConfig); - webServer.on(F("/resetConfig"), httpHandleResetConfig); - webServer.on(F("/config"), webHandleConfig); -#endif // HASP_USE_CONFIG - -#if defined(ARDUINO_ARCH_ESP32) || defined(ARDUINO_ARCH_ESP8266) - webServer.on( - F("/update"), HTTP_POST, - []() { - webServer.send(200, "text/plain", ""); - LOG_VERBOSE(TAG_HTTP, F("Total size: %s"), webServer.hostHeader().c_str()); - }, - webHandleFirmwareUpload); - webServer.on(F("/espfirmware"), httpHandleEspFirmware); -#endif - - LOG_INFO(TAG_HTTP, F(D_SERVICE_STARTED)); - // webStart(); Wait for network connection -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void httpReconnect() -{ - if(!http_config.enable) return; - - if(webServerStarted) { - httpStop(); - } else -#if HASP_USE_WIFI > 0 && !defined(STM32F4xx) - if(WiFi.status() == WL_CONNECTED || WiFi.getMode() != WIFI_STA) -#endif - { - httpStart(); - } -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void httpLoop(void) -{ - if(http_config.enable) webServer.handleClient(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -void httpEvery5Seconds() -{ - // if(httpEnable && !webServerStarted) httpReconnect(); -} - -//////////////////////////////////////////////////////////////////////////////////////////////////// -#if HASP_USE_CONFIG > 0 -bool httpGetConfig(const JsonObject& settings) -{ - bool changed = false; - - settings[FPSTR(FP_CONFIG_ENABLE)] = http_config.enable; - - if(http_config.port != settings[FPSTR(FP_CONFIG_PORT)].as()) changed = true; - settings[FPSTR(FP_CONFIG_PORT)] = http_config.port; - - if(strcmp(http_config.user, settings[FPSTR(FP_CONFIG_USER)].as().c_str()) != 0) changed = true; - settings[FPSTR(FP_CONFIG_USER)] = http_config.user; - - if(strcmp(http_config.password, settings[FPSTR(FP_CONFIG_PASS)].as().c_str()) != 0) changed = true; - settings[FPSTR(FP_CONFIG_PASS)] = http_config.password; - - if(changed) configOutput(settings, TAG_HTTP); - return changed; -} - -/** Set HTTP Configuration. - * - * Read the settings from json and sets the application variables. - * - * @note: data pixel should be formated to uint32_t RGBA. Imagemagick requirements. - * - * @param[in] settings JsonObject with the config settings. - **/ -bool httpSetConfig(const JsonObject& settings) -{ - configOutput(settings, TAG_HTTP); - bool changed = false; - - changed |= configSet(http_config.port, settings[FPSTR(FP_CONFIG_PORT)], F("httpPort")); - - if(!settings[FPSTR(FP_CONFIG_USER)].isNull()) { - changed |= strcmp(http_config.user, settings[FPSTR(FP_CONFIG_USER)]) != 0; - strncpy(http_config.user, settings[FPSTR(FP_CONFIG_USER)], sizeof(http_config.user)); - } - - if(!settings[FPSTR(FP_CONFIG_PASS)].isNull()) { - changed |= strcmp(http_config.password, settings[FPSTR(FP_CONFIG_PASS)]) != 0; - strncpy(http_config.password, settings[FPSTR(FP_CONFIG_PASS)], sizeof(http_config.password)); - } - - return changed; -} -#endif // HASP_USE_CONFIG - -size_t httpClientWrite(const uint8_t* buf, size_t size) -{ - /***** Sending 16Kb at once freezes on STM32 EthernetClient *****/ - size_t bytes_sent = 0; - while(bytes_sent < size) { - if(!webServer.client()) return bytes_sent; - if(size - bytes_sent >= 2048) { - bytes_sent += webServer.client().write(buf + bytes_sent, 2048); - } else { - bytes_sent += webServer.client().write(buf + bytes_sent, size - bytes_sent); - } - // Serial.println(bytes_sent); - - // stm32_eth_scheduler(); // already in write - // webServer.client().flush(); - delay(1); // Fixes the freeze - } - return bytes_sent; -} - -#endif \ No newline at end of file diff --git a/src/sys/svc/hasp_http.cpp b/src/sys/svc/hasp_http.cpp index 14c1e1d6..95232d91 100644 --- a/src/sys/svc/hasp_http.cpp +++ b/src/sys/svc/hasp_http.cpp @@ -1940,7 +1940,7 @@ void httpSetup() // These two endpoints are needed in STA and AP mode webServer.on(F("/"), webHandleWifiConfig); - webServer.on(F("/config"), webHandleWifiConfig); + webServer.on(F("/config"), webHandleConfig); #if !defined(STM32F4xx)