Allow HTTPS on non-PSRAM devices

This commit is contained in:
iranl
2025-06-19 10:10:32 +02:00
parent da837599d3
commit b5ad96f747
9 changed files with 89 additions and 103 deletions

View File

@@ -5,7 +5,7 @@
#define NUKI_HUB_VERSION "9.11"
#define NUKI_HUB_VERSION_INT (uint32_t)911
#define NUKI_HUB_BUILD "unknownbuildnr"
#define NUKI_HUB_DATE "2025-06-18"
#define NUKI_HUB_DATE "2025-06-19"
#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"

View File

@@ -9,6 +9,8 @@
#include "esp_random.h"
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
#include "esp_psram.h"
#endif
#ifdef NUKI_HUB_HTTPS_SERVER
#include "util/SSLCert.hpp"
#endif
#ifndef CONFIG_IDF_TARGET_ESP32H2
@@ -2697,8 +2699,7 @@ bool WebCfgServer::processArgs(PsychicRequest *request, PsychicResponse* resp, S
}
}
}
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
else if(key == "HTTPCRT")
else if(key == "HTTPCRT" && nuki_hub_https_server_enabled)
{
if (!SPIFFS.begin(true)) {
Log->println("SPIFFS Mount Failed");
@@ -2734,7 +2735,7 @@ bool WebCfgServer::processArgs(PsychicRequest *request, PsychicResponse* resp, S
}
}
}
else if(key == "HTTPKEY")
else if(key == "HTTPKEY" && nuki_hub_https_server_enabled)
{
if (!SPIFFS.begin(true)) {
Log->println("SPIFFS Mount Failed");
@@ -2770,14 +2771,15 @@ bool WebCfgServer::processArgs(PsychicRequest *request, PsychicResponse* resp, S
}
}
}
else if(key == "HTTPGEN")
else if(key == "HTTPGEN" && nuki_hub_https_server_enabled)
{
#ifdef NUKI_HUB_HTTPS_SERVER
createSSLCertificate();
#endif
Log->print("Setting changed: ");
Log->println(key);
configChanged = true;
}
#endif
else if(key == "UPTIME")
{
if(_preferences->getBool(preference_update_time, false) != (value == "1"))
@@ -4809,12 +4811,10 @@ esp_err_t WebCfgServer::buildImportExportHtml(PsychicRequest *request, PsychicRe
response.print("<button title=\"Basic export\" onclick=\" window.open('/get?page=export', '_self'); return false;\">Basic export</button>");
response.print("<br><br><button title=\"Export with redacted settings\" onclick=\" window.open('/get?page=export&redacted=1'); return false;\">Export with redacted settings</button>");
response.print("<br><br><button title=\"Export with redacted settings and pairing data\" onclick=\" window.open('/get?page=export&redacted=1&pairing=1'); return false;\">Export with redacted settings and pairing data</button>");
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
if(esp_psram_get_size() > 0)
if(nuki_hub_https_server_enabled)
{
response.print("<br><br><button title=\"Export HTTP SSL certificate and key\" onclick=\" window.open('/get?page=export&type=https'); return false;\">Export HTTP SSL certificate and key</button>");
}
#endif
response.print("<br><br><button title=\"Export MQTT SSL CA, client certificate and client key\" onclick=\" window.open('/get?page=export&type=mqtts'); return false;\">Export MQTT SSL CA, client certificate and client key</button>");
response.print("<br><br><button title=\"Export Coredump\" onclick=\" window.open('/get?page=coredump'); return false;\">Export Coredump</button>");
response.print("</div></body></html>");
@@ -5121,15 +5121,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)
if(nuki_hub_https_server_enabled)
{
response.print("<tr><td>Set HTTP SSL Certificate</td><td><button title=\"Set HTTP SSL Certificate\" onclick=\" window.open('/get?page=httpcrtconfig', '_self'); return false;\">Change</button></td></tr>");
response.print("<tr><td>Set HTTP SSL Key</td><td><button title=\"Set HTTP SSL Key\" onclick=\" window.open('/get?page=httpkeyconfig', '_self'); return false;\">Change</button></td></tr>");
response.print("<tr><td>Generate self-signed HTTP SSL Certificate and key</td><td><button title=\"Generate HTTP SSL Certificate and key\" onclick=\" window.open('/get?page=selfsignhttps', '_self'); return false;\">Generate</button></td></tr>");
printInputField(&response, "HTTPSFQDN", "Nuki Hub FQDN for HTTP redirect", _preferences->getString(preference_https_fqdn, "").c_str(), 255, "");
}
#endif
response.print("</table>");
response.print("<h3>IP Address assignment</h3>");
response.print("<table>");
@@ -5326,7 +5324,6 @@ esp_err_t WebCfgServer::buildHttpSSLConfigHtml(PsychicRequest *request, PsychicR
{
bool found = false;
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
if (!SPIFFS.begin(true)) {
Log->println("SPIFFS Mount Failed");
}
@@ -5350,7 +5347,7 @@ esp_err_t WebCfgServer::buildHttpSSLConfigHtml(PsychicRequest *request, PsychicR
found = true;
}
}
#endif
if (!found)
{
printTextarea(&response, "HTTPCRT", "HTTP SSL Certificate (*, optional)", "", 4400, true, true);
@@ -5360,7 +5357,6 @@ esp_err_t WebCfgServer::buildHttpSSLConfigHtml(PsychicRequest *request, PsychicR
{
bool found = false;
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
if (!SPIFFS.begin(true)) {
Log->println("SPIFFS Mount Failed");
}
@@ -5384,7 +5380,7 @@ esp_err_t WebCfgServer::buildHttpSSLConfigHtml(PsychicRequest *request, PsychicR
found = true;
}
}
#endif
if (!found)
{
printTextarea(&response, "HTTPKEY", "HTTP SSL Key (*, optional)", "", 2200, true, true);
@@ -5941,7 +5937,7 @@ esp_err_t WebCfgServer::buildInfoHtml(PsychicRequest *request, PsychicResponse*
response.print(ESP.getFreeHeap());
response.print("\nTotal internal heap: ");
response.print(ESP.getHeapSize());
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
if(esp_psram_get_size() > 0)
{
response.print("\nPSRAM Available: Yes");
@@ -5958,9 +5954,9 @@ esp_err_t WebCfgServer::buildInfoHtml(PsychicRequest *request, PsychicResponse*
{
response.print("\nPSRAM Available: No");
}
#else
#else
response.print("\nPSRAM Available: No");
#endif
#endif
response.print("\nNetwork task stack high watermark: ");
response.print(uxTaskGetStackHighWaterMark(networkTaskHandle));
response.print("\nNuki task stack high watermark: ");
@@ -6028,30 +6024,19 @@ esp_err_t WebCfgServer::buildInfoHtml(PsychicRequest *request, PsychicResponse*
response.print("\nWeb configurator enabled: ");
response.print(_preferences->getBool(preference_webserver_enabled, true) ? "Yes" : "No");
response.print("\nHTTP SSL: ");
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
if(esp_psram_get_size() > 0)
{
if (!SPIFFS.begin(true)) {
response.print("Disabled");
}
else
{
File file = SPIFFS.open("/http_ssl.crt");
File file2 = SPIFFS.open("/http_ssl.key");
response.print((!file || file.isDirectory() || !file2 || file2.isDirectory()) ? "Disabled" : "Enabled");
file.close();
file2.close();
response.print("\nNuki Hub FQDN for HTTP redirect: ");
response.print(_preferences->getString(preference_https_fqdn, "").length() > 0 ? "***" : "Not set");
}
if (!SPIFFS.begin(true) || !nuki_hub_https_server_enabled) {
response.print("Disabled");
}
else
{
response.print("Disabled");
File file = SPIFFS.open("/http_ssl.crt");
File file2 = SPIFFS.open("/http_ssl.key");
response.print((!file || file.isDirectory() || !file2 || file2.isDirectory()) ? "Disabled" : "Enabled");
file.close();
file2.close();
response.print("\nNuki Hub FQDN for HTTP redirect: ");
response.print(_preferences->getString(preference_https_fqdn, "").length() > 0 ? "***" : "Not set");
}
#else
response.print("Disabled");
#endif
response.print("\nAdvanced menu enabled: ");
response.print(_preferences->getBool(preference_enable_debug_mode, false) ? "Yes" : "No");
response.print("\nPublish free heap over MQTT: ");
@@ -7052,7 +7037,7 @@ const String WebCfgServer::getPreselectionForGpio(const uint8_t &pin) const
return String((int8_t)PinRole::Disabled);
}
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
#ifdef NUKI_HUB_HTTPS_SERVER
void WebCfgServer::createSSLCertificate()
{
SSLCert* cert;

View File

@@ -18,6 +18,7 @@
#include "ImportExport.h"
extern TaskHandle_t nukiTaskHandle;
extern bool nuki_hub_https_server_enabled;
enum class TokenType
{
@@ -86,7 +87,7 @@ private:
#if defined(CONFIG_IDF_TARGET_ESP32) || defined(CONFIG_IDF_TARGET_ESP32P4)
const std::vector<std::pair<String, String>> getNetworkCustomCLKOptions() const;
#endif
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
#ifdef NUKI_HUB_HTTPS_SERVER
void createSSLCertificate();
#endif
const String getPreselectionForGpio(const uint8_t& pin) const;

View File

@@ -9,7 +9,7 @@ dependencies:
espressif/libsodium: "^1.0.20~2"
espressif/esp_hosted:
version: "*"
version: 2.0.10
rules:
- if: "target in [esp32p4]"

View File

@@ -15,6 +15,11 @@
#include "FS.h"
#include "SPIFFS.h"
//#include <ESPmDNS.h>
#ifdef NUKI_HUB_HTTPS_SERVER
bool nuki_hub_https_server_enabled = true;
#else
bool nuki_hub_https_server_enabled = false;
#endif
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
#include "esp_psram.h"
#endif
@@ -249,24 +254,20 @@ void cbSyncTime(struct timeval *tv) {
#ifndef NUKI_HUB_UPDATER
void startWebServer()
{
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
bool failed = false;
bool failed = true;
if (esp_psram_get_size() <= 0) {
if (!nuki_hub_https_server_enabled) {
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
@@ -281,7 +282,6 @@ void startWebServer()
File file2 = SPIFFS.open("/http_ssl.key");
if (!file2 || file2.isDirectory()) {
failed = true;
Log->println("http_ssl.key not found");
}
else
@@ -319,6 +319,7 @@ void startWebServer()
});
psychicSSLServer->begin();
webSSLStarted = true;
failed = false;
}
}
}
@@ -326,7 +327,6 @@ void startWebServer()
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, importExport);
@@ -336,9 +336,7 @@ void startWebServer()
});
psychicServer->begin();
webStarted = true;
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
}
#endif
}
void startNuki(bool lock)
@@ -1042,6 +1040,15 @@ void logCoreDump()
void setup()
{
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
#ifndef FORCE_NUKI_HUB_HTTPS_SERVER
if(esp_psram_get_size() <= 0)
{
nuki_hub_https_server_enabled = false;
}
#endif
#endif
//Set Log level to error for all TAGS
esp_log_level_set("*", ESP_LOG_ERROR);
//Set Log level to none for mqtt TAG
@@ -1050,14 +1057,13 @@ void setup()
Serial.begin(115200);
Log = &Serial;
#if !defined(NUKI_HUB_UPDATER) && !defined(CONFIG_IDF_TARGET_ESP32C5)
//
#if !defined(NUKI_HUB_UPDATER) && !defined(CONFIG_IDF_TARGET_ESP32C5)
stdout = funopen(NULL, NULL, &write_fn, NULL, NULL);
static char linebuf[1024];
setvbuf(stdout, linebuf, _IOLBF, sizeof(linebuf));
esp_rom_install_channel_putc(1, &ets_putc_handler);
//ets_install_putc1(&ets_putc_handler);
#endif
#endif
preferences = new Preferences();
preferences->begin("nukihub", false);
@@ -1121,24 +1127,20 @@ void setup()
if(!doOta)
{
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
bool failed = false;
bool failed = true;
if (esp_psram_get_size() <= 0) {
Log->println("Not running on PSRAM enabled device");
failed = true;
if (!nuki_hub_https_server_enabled) {
Log->println("Not running on HTTPS server enabled device");
}
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
@@ -1153,7 +1155,6 @@ void setup()
File file2 = SPIFFS.open("/http_ssl.key");
if (!file2 || file2.isDirectory()) {
failed = true;
Log->println("http_ssl.key not found");
}
else
@@ -1191,6 +1192,7 @@ void setup()
});
psychicSSLServer->begin();
webSSLStarted = true;
failed = false;
}
}
}
@@ -1198,7 +1200,6 @@ void setup()
if (failed)
{
#endif
psychicServer = new PsychicHttpServer;
psychicServer->config.stack_size = HTTPD_TASK_SIZE;
webCfgServer = new WebCfgServer(network, preferences, network->networkDeviceType() == NetworkDeviceType::WiFi, partitionType, psychicServer, importExport);
@@ -1208,9 +1209,7 @@ void setup()
});
psychicServer->begin();
webStarted = true;
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
}
#endif
}
#else
if(preferences->getBool(preference_enable_bootloop_reset, false))

View File

@@ -7,20 +7,9 @@
#include "SPIFFS.h"
#include "../MqttTopics.h"
#include "PreferencesKeys.h"
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
#include "esp_psram.h"
#endif
void NetworkDevice::init()
{
#ifdef CONFIG_SOC_SPIRAM_SUPPORTED
if(esp_psram_get_size() > 0)
{
//_mqttInternal = true;
_mqttInternal = false;
}
#endif
if(_preferences->getBool(preference_mqtt_ssl_enabled, false)) {
if (!SPIFFS.begin(true)) {
Log->println("SPIFFS Mount Failed");