From c8c2980537ad031eeb8346512f198fa8795fbe55 Mon Sep 17 00:00:00 2001 From: iranl Date: Tue, 31 Dec 2024 14:54:10 +0100 Subject: [PATCH] HTTPS server --- README.md | 39 +++++--- platformio.ini | 4 +- sdkconfig.defaults | 11 ++- src/Config.h | 2 +- src/WebCfgServer.cpp | 180 +++++++++++++++++++++++++++++++++++-- src/WebCfgServer.h | 11 +-- src/main.cpp | 180 +++++++++++++++++++++++++++++++++---- updater/sdkconfig.defaults | 13 ++- 8 files changed, 389 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index dc27cfc..3a662fb 100644 --- a/README.md +++ b/README.md @@ -52,20 +52,16 @@ See the "[Connecting via Ethernet](#connecting-via-ethernet-optional)" section f ## Recommended ESP32 devices -- If WIFI6 is absolutely required: ESP32-C6 -- If PoE is required: Any of the above mentioned devices with PoE or any other ESP device in combination with a SPI Ethernet module ([W5500](https://www.aliexpress.com/w/wholesale-w5500.html)) and [PoE to Ethernet and USB type B/C splitter](https://aliexpress.com/w/wholesale-poe-splitter-usb-c.html) -- If you want maximum performance and intend to run any or multiple of the following: - - a Nuki Lock and Nuki Opener and/or - - MQTT SSL and/or - - HTTP SSL and/or - - large amounts of keypad codes, timecontrol or authorization entries - - Developing/debugging Nuki devices and/or Nuki Hub +We don't recommend using single-core ESP32 devices (ESP32-C3, ESP32-C6, ESP32-H2, ESP32-Solo1).
+Although NukiHub supports single-core devices, NukiHub uses both CPU cores (if available) to process tasks (e.g. HTTP server/MQTT client/BLE scanner/BLE client) and thus runs much better on dual-core devices.
- An ESP32-S3 with 2MB of PSRAM or more (look for an ESP32-S3 with the designation N>=4 and R>=2 such as an ESP32-S3 N16R8) - -- In general when buying a new device when size and a couple of dollars more or less are not an issue: An ESP32-S3 with 2MB of PSRAM or more.
+When buying a new device in 2025 we can only recommend the ESP32-S3 with PSRAM (look for an ESP32-S3 with the designation N>=4 and R>=2 such as an ESP32-S3 N16R8).
+The ESP32-S3 is a dual-core CPU with many GPIO's, ability to enlarge RAM using PSRAM, ability to connect Ethernet modules over SPI and optionally power the device with a PoE splitter.
+The only functions missing from the ESP32-S3 as compared to other ESP devices is the ability to use some Ethernet modules only supported by the original ESP32 (and ESP32-P4) and the ability to connect over WIFI6 (C6 or ESP32-P4 with C6 module) -The ESP32-S3 is a dual-core CPU with many GPIO's, ability to enlarge RAM using PSRAM, ability to connect Ethernet modules over SPI and optionally power the device with a PoE splitter. The only functions missing from the ESP32-S3 as compared to other ESP devices is the ability to use some Ethernet modules only supported by the original ESP32 and the ability to connect over WIFI6 (C6) +Other considerations: +- If PoE is required: An ESP32-S3 with PSRAM in combination with a SPI Ethernet module ([W5500](https://www.aliexpress.com/w/wholesale-w5500.html)) and [PoE to Ethernet and USB type B/C splitter](https://aliexpress.com/w/wholesale-poe-splitter-usb-c.html) or the M5stack Atom S3R with the M5stack AtomPoe W5500 module +- If WIFI6 is absolutely required (it probably isn't): ESP32-C6 ## Feature comparison @@ -194,6 +190,8 @@ In a browser navigate to the IP address assigned to the ESP32. - RSSI Publish interval: Set to a positive integer to set the amount of seconds between updates to the maintenance/wifiRssi MQTT topic with the current Wi-Fi RSSI, set to -1 to disable, default 60. - Restart on disconnect: Enable to restart the Nuki Hub when disconnected from the network. - Check for Firmware Updates every 24h: Enable to allow the Nuki Hub to check the latest release of the Nuki Hub firmware on boot and every 24 hours. Requires the Nuki Hub to be able to connect to github.com. The latest version will be published to MQTT and will be visible on the main page of the Web Configurator. +- HTTP SSL Certificate (PSRAM enabled devices only): Optionally set to the SSL certificate of the HTTPS server, see the "[HTTPS Server](#https-server-optional-psram-enabled-devices-only)" section of this README. +- HTTP SSL Key (PSRAM enabled devices only): Optionally set to the SSL key of the HTTPS server, see the "[HTTPS Server](#https-server-optional-psram-enabled-devices-only)" section of this README. #### IP Address assignment @@ -575,6 +573,23 @@ openssl req -new -key server.key -out server.csr -subj "/C=US/ST=YourState/L=You # sign it openssl x509 -req -in server.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out server.crt -days 3650 ``` + +## HTTPS Server (optional, PSRAM enabled devices only) + +The Webconfigurator can use/force HTTPS on PSRAM enabled devices.
+To enable SSL encryption, supply the certificate and key in the Network configuration page and reboot NukiHub.
+ +Example self-signed certificate creation for your HTTPS server: +```console + +# make a Certificate and key pair, MAKE SURE THE CN MATCHES THE DOMAIN AT WHICH NUKIHUB IS AVAILABLE +openssl req -x509 -nodes -days 3650 -newkey rsa:2048 -keyout nukihub.key -out nukihub.crt -subj "/C=US/ST=YourState/L=YourCity/O=YourOrganization/OU=YourUnit/CN=YourCAName" + +``` + +Although you can use the HTTPS server in this way your client device will not trust the certificate by default. +An option would be to configure a proxy SSL server (such as Caddy, Traefik, nginx) with a non-self signed (e.g. let's encrypt) SSL certificate and have this proxy server connect to NukiHub over SSL and trust the self-signed NukiHub certificate for this connection. + ## Home Assistant Discovery (optional) This software supports [MQTT Discovery](https://www.home-assistant.io/docs/mqtt/discovery/) for integrating Nuki Hub with Home Assistant.
diff --git a/platformio.ini b/platformio.ini index 37ddf68..08f6a64 100644 --- a/platformio.ini +++ b/platformio.ini @@ -33,8 +33,8 @@ build_unflags = build_flags = -fexceptions -DTLS_CA_MAX_SIZE=2200 - -DTLS_CERT_MAX_SIZE=1500 - -DTLS_KEY_MAX_SIZE=1800 + -DTLS_CERT_MAX_SIZE=2200 + -DTLS_KEY_MAX_SIZE=2200 -DESP_PLATFORM -DESP32 -DARDUINO_ARCH_ESP32 diff --git a/sdkconfig.defaults b/sdkconfig.defaults index 3465515..7a29d2b 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -74,7 +74,6 @@ CONFIG_ARDUINO_SELECTIVE_ESP_SR=n CONFIG_ARDUINO_SELECTIVE_Zigbee=n CONFIG_ARDUINO_SELECTIVE_SD=n CONFIG_ARDUINO_SELECTIVE_SD_MMC=n -CONFIG_ARDUINO_SELECTIVE_SPIFFS=n CONFIG_ARDUINO_SELECTIVE_FFat=n CONFIG_ARDUINO_SELECTIVE_LittleFS=n CONFIG_ARDUINO_SELECTIVE_PPP=n @@ -98,11 +97,15 @@ CONFIG_MBEDTLS_CUSTOM_CERTIFICATE_BUNDLE_PATH="resources/github_root_ca.pem" CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH=y CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH=y -CONFIG_HTTPD_MAX_REQ_HDR_LEN=1024 +CONFIG_HTTPD_MAX_REQ_HDR_LEN=2048 CONFIG_HTTPD_MAX_URI_LEN=512 CONFIG_HTTPD_ERR_RESP_NO_DELAY=y CONFIG_HTTPD_PURGE_BUF_LEN=32 CONFIG_HTTPD_WS_SUPPORT=y -CONFIG_ESP_HTTPS_SERVER_ENABLE=n +CONFIG_ESP_HTTPS_SERVER_ENABLE=y CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE=y -CONFIG_BOOTLOADER_WDT_TIME_MS=120000 \ No newline at end of file +CONFIG_BOOTLOADER_WDT_TIME_MS=120000 +CONFIG_LWIP_MAX_SOCKETS=24 +CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y +CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=1024 +CONFIG_ARDUINO_LOOP_STACK_SIZE=12288 \ No newline at end of file diff --git a/src/Config.h b/src/Config.h index aaa471f..0814eab 100644 --- a/src/Config.h +++ b/src/Config.h @@ -5,7 +5,7 @@ #define NUKI_HUB_VERSION "9.07" #define NUKI_HUB_VERSION_INT (uint32_t)907 #define NUKI_HUB_BUILD "unknownbuildnr" -#define NUKI_HUB_DATE "2024-12-30" +#define NUKI_HUB_DATE "2024-12-31" #define GITHUB_LATEST_RELEASE_URL (char*)"https://github.com/technyon/nuki_hub/releases/latest" #define GITHUB_OTA_MANIFEST_URL (char*)"https://raw.githubusercontent.com/technyon/nuki_hub/binary/ota/manifest.json" diff --git a/src/WebCfgServer.cpp b/src/WebCfgServer.cpp index ef6ad57..945c9f6 100644 --- a/src/WebCfgServer.cpp +++ b/src/WebCfgServer.cpp @@ -5,7 +5,9 @@ #include "RestartReason.h" #include #ifdef CONFIG_SOC_SPIRAM_SUPPORTED -#include +#include "esp_psram.h" +#include "FS.h" +#include "SPIFFS.h" #endif #ifndef CONFIG_IDF_TARGET_ESP32H2 #include @@ -77,13 +79,13 @@ void WebCfgServer::initialize() { _psychicServer->onOpen([&](PsychicClient* client) { Log->printf("[http] connection #%u connected from %s\n", client->socket(), client->localIP().toString().c_str()); }); _psychicServer->onClose([&](PsychicClient* client) { Log->printf("[http] connection #%u closed from %s\n", client->socket(), client->localIP().toString().c_str()); }); - + HTTPAuthMethod auth_type = BASIC_AUTH; if (_preferences->getBool(preference_http_auth_type, false)) { auth_type = DIGEST_AUTH; } - + _psychicServer->on("/", HTTP_GET, [&](PsychicRequest *request, PsychicResponse* resp) { if(strlen(_credUser) > 0 && strlen(_credPassword) > 0 && !request->authenticate(_credUser, _credPassword)) @@ -297,6 +299,14 @@ void WebCfgServer::initialize() { return buildMqttSSLConfigHtml(request, resp, 2); } + else if (value == "httpcrtconfig") + { + return buildHttpSSLConfigHtml(request, resp, 1); + } + else if (value == "httpkeyconfig") + { + return buildHttpSSLConfigHtml(request, resp, 2); + } else if (value == "nukicfg") { return buildNukiConfigHtml(request, resp); @@ -428,6 +438,10 @@ void WebCfgServer::initialize() { return buildConfirmHtml(request, resp, message, 3, true, "/get?page=mqttconfig"); } + else if(request->hasParam("httpssl")) + { + return buildConfirmHtml(request, resp, message, 3, true, "/get?page=ntwconfig"); + } else { return buildConfirmHtml(request, resp, message, 3, true); @@ -491,7 +505,7 @@ void WebCfgServer::initialize() { return request->requestAuthentication(auth_type, "Nuki Hub", "You must log in."); } - + return handleOtaUpload(request, filename, index, data, len, last); }); @@ -501,7 +515,7 @@ void WebCfgServer::initialize() { return request->requestAuthentication(auth_type, "Nuki Hub", "You must log in."); } - + String result; if (!Update.hasError()) { @@ -1588,6 +1602,74 @@ bool WebCfgServer::processArgs(PsychicRequest *request, PsychicResponse* resp, S configChanged = true; } } + #ifdef CONFIG_SOC_SPIRAM_SUPPORTED + else if(key == "HTTPCRT") + { + if (!SPIFFS.begin(true)) { + Log->println("SPIFFS Mount Failed"); + } + else + { + if(value != "") + { + File file = SPIFFS.open("/http_ssl.crt", FILE_WRITE); + if (!file) { + Log->println("Failed to open /http_ssl.crt for writing"); + } + else + { + if (!file.print(value)) + { + Log->println("Failed to write /http_ssl.crt"); + } + file.close(); + } + } + else + { + if (!SPIFFS.remove("/http_ssl.crt")) { + Serial.println("Failed to delete /http_ssl.crt"); + } + } + Log->print(F("Setting changed: ")); + Log->println(key); + configChanged = true; + } + } + else if(key == "HTTPKEY") + { + if (!SPIFFS.begin(true)) { + Log->println("SPIFFS Mount Failed"); + } + else + { + if(value != "") + { + File file = SPIFFS.open("/http_ssl.key", FILE_WRITE); + if (!file) { + Log->println("Failed to open /http_ssl.key for writing"); + } + else + { + if (!file.print(value)) + { + Log->println("Failed to write /http_ssl.key"); + } + file.close(); + } + } + else + { + if (!SPIFFS.remove("/http_ssl.key")) { + Serial.println("Failed to delete /http_ssl.key"); + } + } + Log->print(F("Setting changed: ")); + Log->println(key); + configChanged = true; + } + } + #endif else if(key == "NWHW") { if(_preferences->getInt(preference_network_hardware, 0) != value.toInt()) @@ -3681,6 +3763,13 @@ esp_err_t WebCfgServer::buildNetworkConfigHtml(PsychicRequest *request, PsychicR printCheckBox(&response, "RSTDISC", "Restart on disconnect", _preferences->getBool(preference_restart_on_disconnect), ""); printCheckBox(&response, "CHECKUPDATE", "Check for Firmware Updates every 24h", _preferences->getBool(preference_check_updates), ""); printCheckBox(&response, "FINDBESTRSSI", "Find WiFi AP with strongest signal", _preferences->getBool(preference_find_best_rssi, false), ""); + #ifdef CONFIG_SOC_SPIRAM_SUPPORTED + if(esp_psram_get_size() > 0) + { + response.print("Set HTTP SSL Certificate"); + response.print("Set HTTP SSL Key"); + } + #endif response.print(""); response.print("

IP Address assignment

"); response.print(""); @@ -3722,7 +3811,7 @@ esp_err_t WebCfgServer::buildMqttConfigHtml(PsychicRequest *request, PsychicResp printCheckBox(&response, "OPENERCONT", "Set Nuki Opener Lock/Unlock action in Home Assistant to Continuous mode", _preferences->getBool(preference_opener_continuous_mode), ""); } response.print(""); - response.print(""); + response.print(""); response.print(""); printInputField(&response, "NETTIMEOUT", "MQTT Timeout until restart (seconds; -1 to disable)", _preferences->getInt(preference_network_timeout), 5, ""); printCheckBox(&response, "MQTTLOG", "Enable MQTT logging", _preferences->getBool(preference_mqtt_log_enabled), ""); @@ -3773,6 +3862,81 @@ esp_err_t WebCfgServer::buildMqttSSLConfigHtml(PsychicRequest *request, PsychicR return response.endSend(); } +esp_err_t WebCfgServer::buildHttpSSLConfigHtml(PsychicRequest *request, PsychicResponse* resp, int type) +{ + PsychicStreamResponse response(resp, "text/html"); + response.beginSend(); + buildHtmlHeader(&response); + response.print(""); + response.print(""); + response.print(""); + response.print("

HTTP SSL Configuration

"); + response.print("
Set MQTT SSL CA Certificate
Set MQTT SSL Client Certificate
Set MQTT SSL Client Certificate
Set MQTT SSL Client Key
"); + + if (type == 1) + { + char cert[4400] = {0}; + + #ifdef CONFIG_SOC_SPIRAM_SUPPORTED + if (!SPIFFS.begin(true)) { + Log->println("SPIFFS Mount Failed"); + } + else + { + File file = SPIFFS.open("/http_ssl.crt"); + if (!file || file.isDirectory()) { + Log->println("http_ssl.crt not found"); + } + else + { + Log->println("Reading http_ssl.crt"); + uint32_t i = 0; + while(file.available()){ + cert[i] = file.read(); + i++; + } + file.close(); + } + } + #endif + printTextarea(&response, "HTTPCRT", "HTTP SSL Certificate (*, optional)", cert, 4400, true, true); + } + else + { + char key[2200] = {0}; + + #ifdef CONFIG_SOC_SPIRAM_SUPPORTED + if (!SPIFFS.begin(true)) { + Log->println("SPIFFS Mount Failed"); + } + else + { + File file = SPIFFS.open("/http_ssl.key"); + if (!file || file.isDirectory()) { + Log->println("http_ssl.key not found"); + } + else + { + Log->println("Reading http_ssl.key"); + uint32_t i = 0; + while(file.available()){ + key[i] = file.read(); + i++; + } + file.close(); + } + } + #endif + printTextarea(&response, "HTTPKEY", "HTTP SSL Key (*, optional)", key, 2200, true, true); + } + response.print("
"); + response.print("
"); + response.print(""); + response.print(""); + response.print(""); + return response.endSend(); +} + esp_err_t WebCfgServer::buildAdvancedConfigHtml(PsychicRequest *request, PsychicResponse* resp) { PsychicStreamResponse response(resp, "text/html"); @@ -4348,6 +4512,10 @@ esp_err_t WebCfgServer::buildInfoHtml(PsychicRequest *request, PsychicResponse* response.print(_preferences->getString(preference_cred_password, "").length() > 0 ? "***" : "Not set"); response.print("\nWeb configurator enabled: "); response.print(_preferences->getBool(preference_webserver_enabled, true) ? "Yes" : "No"); + //response.print("\nHTTP SSL CRT: "); + //response.print(_preferences->getString(preference_http_crt, "").length() > 0 ? "***" : "Not set"); + //response.print("\nHTTP SSL Key: "); + //response.print(_preferences->getString(preference_http_key, "").length() > 0 ? "***" : "Not set"); response.print("\nPublish debug information enabled: "); response.print(_preferences->getBool(preference_publish_debug_info, false) ? "Yes" : "No"); response.print("\nMQTT log enabled: "); diff --git a/src/WebCfgServer.h b/src/WebCfgServer.h index 3886f08..0865d81 100644 --- a/src/WebCfgServer.h +++ b/src/WebCfgServer.h @@ -59,7 +59,8 @@ private: esp_err_t buildNetworkConfigHtml(PsychicRequest *request, PsychicResponse* resp); esp_err_t buildMqttConfigHtml(PsychicRequest *request, PsychicResponse* resp); esp_err_t buildMqttSSLConfigHtml(PsychicRequest *request, PsychicResponse* resp, int type=0); - esp_err_t buildStatusHtml(PsychicRequest *request, PsychicResponse* resp); + esp_err_t buildHttpSSLConfigHtml(PsychicRequest *request, PsychicResponse* resp, int type=0); + esp_err_t buildStatusHtml(PsychicRequest *request, PsychicResponse* resp); esp_err_t buildAdvancedConfigHtml(PsychicRequest *request, PsychicResponse* resp); esp_err_t buildNukiConfigHtml(PsychicRequest *request, PsychicResponse* resp); esp_err_t buildGpioConfigHtml(PsychicRequest *request, PsychicResponse* resp); @@ -94,12 +95,12 @@ private: bool _brokerConfigured = false; bool _rebootRequired = false; #endif - + std::vector _ssidList; std::vector _rssiList; String generateConfirmCode(); String _confirmCode = "----"; - + esp_err_t buildSSIDListHtml(PsychicRequest *request, PsychicResponse* resp); esp_err_t buildConfirmHtml(PsychicRequest *request, PsychicResponse* resp, const String &message, uint32_t redirectDelay = 5, bool redirect = false, String redirectTo = "/"); esp_err_t buildOtaHtml(PsychicRequest *request, PsychicResponse* resp, bool debug = false); @@ -113,11 +114,11 @@ private: #ifndef CONFIG_IDF_TARGET_ESP32H2 esp_err_t buildWifiConnectHtml(PsychicRequest *request, PsychicResponse* resp); bool processWiFi(PsychicRequest *request, PsychicResponse* resp, String& message); - + #endif void printInputField(PsychicStreamResponse *response, const char* token, const char* description, const char* value, const size_t& maxLength, const char* args, const bool& isPassword = false, const bool& showLengthRestriction = false); void printInputField(PsychicStreamResponse *response, const char* token, const char* description, const int value, size_t maxLength, const char* args); - + PsychicHttpServer* _psychicServer = nullptr; NukiNetwork* _network = nullptr; Preferences* _preferences = nullptr; diff --git a/src/main.cpp b/src/main.cpp index 18a5317..430ca33 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -10,6 +10,11 @@ #include "esp32-hal-log.h" #include "hal/wdt_hal.h" #include "esp_chip_info.h" +#ifdef CONFIG_SOC_SPIRAM_SUPPORTED +#include "esp_psram.h" +#include "FS.h" +#include "SPIFFS.h" +#endif #ifndef NUKI_HUB_UPDATER #include "NukiWrapper.h" @@ -65,8 +70,10 @@ int64_t restartTs = 10 * 60 * 1000; #endif PsychicHttpServer* psychicServer = nullptr; +PsychicHttpsServer* psychicSSLServer = nullptr; NukiNetwork* network = nullptr; WebCfgServer* webCfgServer = nullptr; +WebCfgServer* webCfgServerSSL = nullptr; Preferences* preferences = nullptr; RTC_NOINIT_ATTR int espRunning; @@ -539,14 +546,84 @@ void setup() if(!doOta) { - psychicServer = new PsychicHttpServer; - psychicServer->config.stack_size = HTTPD_TASK_SIZE; - webCfgServer = new WebCfgServer(network, preferences, network->networkDeviceType() == NetworkDeviceType::WiFi, partitionType, psychicServer); - webCfgServer->initialize(); - psychicServer->onNotFound([](PsychicRequest* request, PsychicResponse* response) { - return response->redirect("/"); - }); - psychicServer->begin(); + #ifdef CONFIG_SOC_SPIRAM_SUPPORTED + bool failed = false; + + if (esp_psram_get_size() <= 0) { + Log->println("Not running on PSRAM enabled device"); + failed = true; + } + else + { + if (!SPIFFS.begin(true)) { + Log->println("SPIFFS Mount Failed"); + failed = true; + } + else + { + File file = SPIFFS.open("/http_ssl.crt"); + if (!file || file.isDirectory()) { + failed = true; + Log->println("http_ssl.crt not found"); + } + else + { + char cert[4400] = {0}; + + Log->println("Reading http_ssl.crt"); + uint32_t i = 0; + while(file.available()){ + cert[i] = file.read(); + i++; + } + file.close(); + + File file2 = SPIFFS.open("/http_ssl.key"); + if (!file2 || file2.isDirectory()) { + failed = true; + Log->println("http_ssl.key not found"); + } + else + { + char key[2200] = {0}; + + Log->println("Reading http_ssl.key"); + i = 0; + while(file2.available()){ + key[i] = file2.read(); + i++; + } + file2.close(); + + psychicSSLServer = new PsychicHttpsServer; + psychicSSLServer->ssl_config.httpd.max_open_sockets = 8; + psychicSSLServer->setCertificate(cert, key); + psychicSSLServer->config.stack_size = HTTPD_TASK_SIZE; + webCfgServerSSL = new WebCfgServer(network, preferences, network->networkDeviceType() == NetworkDeviceType::WiFi, partitionType, psychicSSLServer); + webCfgServerSSL->initialize(); + psychicSSLServer->onNotFound([](PsychicRequest* request, PsychicResponse* response) { + return response->redirect("/"); + }); + psychicSSLServer->begin(); + } + } + } + } + + if (failed) + { + #endif + psychicServer = new PsychicHttpServer; + psychicServer->config.stack_size = HTTPD_TASK_SIZE; + webCfgServer = new WebCfgServer(network, preferences, network->networkDeviceType() == NetworkDeviceType::WiFi, partitionType, psychicServer); + webCfgServer->initialize(); + psychicServer->onNotFound([](PsychicRequest* request, PsychicResponse* response) { + return response->redirect("/"); + }); + psychicServer->begin(); + #ifdef CONFIG_SOC_SPIRAM_SUPPORTED + } + #endif } #else if(preferences->getBool(preference_enable_bootloop_reset, false)) @@ -633,17 +710,86 @@ void setup() if(!doOta && !disableNetwork && (forceEnableWebServer || preferences->getBool(preference_webserver_enabled, true) || preferences->getBool(preference_webserial_enabled, false))) { - psychicServer = new PsychicHttpServer; - psychicServer->config.stack_size = HTTPD_TASK_SIZE; - if(forceEnableWebServer || preferences->getBool(preference_webserver_enabled, true)) { - webCfgServer = new WebCfgServer(nuki, nukiOpener, network, gpio, preferences, network->networkDeviceType() == NetworkDeviceType::WiFi, partitionType, psychicServer); - webCfgServer->initialize(); - psychicServer->onNotFound([](PsychicRequest* request, PsychicResponse* response) { - return response->redirect("/"); - }); - psychicServer->begin(); + #ifdef CONFIG_SOC_SPIRAM_SUPPORTED + bool failed = false; + + if (esp_psram_get_size() <= 0) { + Log->println("Not running on PSRAM enabled device"); + failed = true; + } + else + { + if (!SPIFFS.begin(true)) { + Log->println("SPIFFS Mount Failed"); + failed = true; + } + else + { + File file = SPIFFS.open("/http_ssl.crt"); + if (!file || file.isDirectory()) { + failed = true; + Log->println("http_ssl.crt not found"); + } + else + { + char cert[4400] = {0}; + + Log->println("Reading http_ssl.crt"); + uint32_t i = 0; + while(file.available()){ + cert[i] = file.read(); + i++; + } + file.close(); + + File file2 = SPIFFS.open("/http_ssl.key"); + if (!file2 || file2.isDirectory()) { + failed = true; + Log->println("http_ssl.key not found"); + } + else + { + char key[2200] = {0}; + + Log->println("Reading http_ssl.key"); + i = 0; + while(file2.available()){ + key[i] = file2.read(); + i++; + } + file2.close(); + + psychicSSLServer = new PsychicHttpsServer; + psychicSSLServer->ssl_config.httpd.max_open_sockets = 8; + psychicSSLServer->setCertificate(cert, key); + psychicSSLServer->config.stack_size = HTTPD_TASK_SIZE; + webCfgServerSSL = new WebCfgServer(nuki, nukiOpener, network, gpio, preferences, network->networkDeviceType() == NetworkDeviceType::WiFi, partitionType, psychicSSLServer); + webCfgServerSSL->initialize(); + psychicSSLServer->onNotFound([](PsychicRequest* request, PsychicResponse* response) { + return response->redirect("/"); + }); + psychicSSLServer->begin(); + } + } + } + } + + if (failed) + { + #endif + psychicServer = new PsychicHttpServer; + psychicServer->config.stack_size = HTTPD_TASK_SIZE; + webCfgServer = new WebCfgServer(nuki, nukiOpener, network, gpio, preferences, network->networkDeviceType() == NetworkDeviceType::WiFi, partitionType, psychicServer); + webCfgServer->initialize(); + psychicServer->onNotFound([](PsychicRequest* request, PsychicResponse* response) { + return response->redirect("/"); + }); + psychicServer->begin(); + #ifdef CONFIG_SOC_SPIRAM_SUPPORTED + } + #endif } /* #ifdef DEBUG_NUKIHUB diff --git a/updater/sdkconfig.defaults b/updater/sdkconfig.defaults index 3d1adba..274c771 100644 --- a/updater/sdkconfig.defaults +++ b/updater/sdkconfig.defaults @@ -18,7 +18,6 @@ CONFIG_ARDUINO_SELECTIVE_ESP_SR=n CONFIG_ARDUINO_SELECTIVE_Zigbee=n CONFIG_ARDUINO_SELECTIVE_SD=n CONFIG_ARDUINO_SELECTIVE_SD_MMC=n -CONFIG_ARDUINO_SELECTIVE_SPIFFS=n CONFIG_ARDUINO_SELECTIVE_FFat=n CONFIG_ARDUINO_SELECTIVE_LittleFS=n CONFIG_ARDUINO_SELECTIVE_PPP=n @@ -43,10 +42,16 @@ CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL=y CONFIG_ESP_HTTP_CLIENT_ENABLE_HTTPS=y CONFIG_ESP_HTTP_CLIENT_ENABLE_BASIC_AUTH=y CONFIG_ESP_HTTP_CLIENT_ENABLE_DIGEST_AUTH=y -CONFIG_HTTPD_MAX_REQ_HDR_LEN=1024 +CONFIG_HTTPD_MAX_REQ_HDR_LEN=2048 CONFIG_HTTPD_MAX_URI_LEN=512 CONFIG_HTTPD_ERR_RESP_NO_DELAY=y CONFIG_HTTPD_PURGE_BUF_LEN=32 CONFIG_HTTPD_WS_SUPPORT=y -CONFIG_ESP_HTTPS_SERVER_ENABLE=n -CONFIG_LOG_MASTER_LEVEL=y \ No newline at end of file +CONFIG_ESP_HTTPS_SERVER_ENABLE=y +CONFIG_BOOTLOADER_WDT_DISABLE_IN_USER_CODE=y +CONFIG_BOOTLOADER_WDT_TIME_MS=120000 +CONFIG_BOOTLOADER_WDT_TIME_MS=120000 +CONFIG_LWIP_MAX_SOCKETS=24 +CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y +CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=1024 +CONFIG_ARDUINO_LOOP_STACK_SIZE=12288 \ No newline at end of file