From d6217492c70b4072649583e028444dede7b3217c Mon Sep 17 00:00:00 2001 From: 0xFEEDC0DE64 Date: Sun, 19 Sep 2021 02:51:16 +0200 Subject: [PATCH] lots of stability improvements --- main/CMakeLists.txt | 1 + main/buttons.h | 4 ++-- main/cloud.h | 9 +++++-- main/displays/statusdisplay.h | 6 ++--- main/presets.h | 2 +- main/webserver.h | 15 +++++------- main/webserver_displaycontrol.h | 35 +++++++++++++++++++++++++++ main/webserver_lock.h | 11 +++++++++ main/webserver_ota.h | 19 +++++++++++++++ main/webserver_settings.h | 42 +++++++++++++++++++++++++-------- main/webserver_stringsettings.h | 34 +++++++++++++++++++++----- 11 files changed, 145 insertions(+), 33 deletions(-) create mode 100644 main/webserver_lock.h diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index b5d0965..cf41118 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -148,6 +148,7 @@ set(headers utils.h webserver.h webserver_displaycontrol.h + webserver_lock.h webserver_ota.h webserver_settings.h webserver_stringsettings.h diff --git a/main/buttons.h b/main/buttons.h index c951a2a..2188b53 100644 --- a/main/buttons.h +++ b/main/buttons.h @@ -31,14 +31,14 @@ class InputDispatcher public: static void update() { - if (upPressedSince && espchrono::ago(*upPressedSince) > (upPressRepeat > 3 ? 100ms : 500ms)) + if (upPressedSince && espchrono::ago(*upPressedSince) > (upPressRepeat > 2 ? 50ms : 400ms)) { upPressedSince = espchrono::millis_clock::now(); upPressRepeat++; rotated -= 1; } - if (downPressedSince && espchrono::ago(*downPressedSince) > (downPressRepeat > 3 ? 100ms : 500ms)) + if (downPressedSince && espchrono::ago(*downPressedSince) > (downPressRepeat > 2 ? 50ms : 400ms)) { downPressedSince = espchrono::millis_clock::now(); downPressRepeat++; diff --git a/main/cloud.h b/main/cloud.h index e54e823..2fc8097 100644 --- a/main/cloud.h +++ b/main/cloud.h @@ -6,6 +6,7 @@ // 3rdparty lib includes #include #include +#include // local includes #include "globals.h" @@ -23,7 +24,9 @@ void startCloud(); void initCloud() { - if (settings.cloudSettings.cloudEnabled) + if (settings.cloudSettings.cloudEnabled && + !stringSettings.cloudUrl.empty() && + esphttpdutils::urlverify(stringSettings.cloudUrl)) { createCloud(); if (!cloudClient) @@ -38,7 +41,9 @@ void initCloud() void handleCloud() { - if (settings.cloudSettings.cloudEnabled) + if (settings.cloudSettings.cloudEnabled && + !stringSettings.cloudUrl.empty() && + esphttpdutils::urlverify(stringSettings.cloudUrl)) { if (!cloudClient) { diff --git a/main/displays/statusdisplay.h b/main/displays/statusdisplay.h index 0cf0569..d7ae2be 100644 --- a/main/displays/statusdisplay.h +++ b/main/displays/statusdisplay.h @@ -100,7 +100,7 @@ private: Label m_labelWifiStatus{35, bottomLines[0]}; // 120, 15 Label m_labelLimit0{205, bottomLines[0]}; // 35, 15 Label m_labelIpAddress{25, bottomLines[1]}; // 130, 15 - Label m_labelSignal{120, bottomLines[1]}; // 130, 15 + Label m_labelSignal{125, bottomLines[1]}; // 130, 15 Label m_labelLimit1{205, bottomLines[1]}; // 35, 15 Label m_labelPerformance{40, bottomLines[2]}; // 40, 15 Label m_labelFreeMem{70, bottomLines[2]}; // 40, 15 @@ -132,12 +132,12 @@ void StatusDisplay::initScreen() tft.setTextFont(2); tft.drawString("WiFi:", 0, bottomLines[0]); m_labelWifiStatus.start(); - tft.drawString("Limit0:", 160, bottomLines[0]); + tft.drawString("Lim0:", 173, bottomLines[0]); m_labelLimit0.start(); tft.drawString("IP:", 0, bottomLines[1]); m_labelIpAddress.start(); m_labelSignal.start(); - tft.drawString("Limit1:", 160, bottomLines[1]); + tft.drawString("Lim1:", 173, bottomLines[1]); m_labelLimit1.start(); tft.drawString("Perf:", 0, bottomLines[2]); m_labelPerformance.start(); diff --git a/main/presets.h b/main/presets.h index c962f26..90d6a96 100644 --- a/main/presets.h +++ b/main/presets.h @@ -168,7 +168,7 @@ constexpr Settings::BoardcomputerHardware defaultBoardcomputerHardware { #ifdef FEATURE_CLOUD constexpr Settings::CloudSettings defaultCloudSettings { - .cloudEnabled = true, + .cloudEnabled = false, .cloudTransmitTimeout = 10 }; #endif diff --git a/main/webserver.h b/main/webserver.h index 5ad9382..16e4d27 100644 --- a/main/webserver.h +++ b/main/webserver.h @@ -15,6 +15,7 @@ #include // local includes +#include "webserver_lock.h" #include "webserver_displaycontrol.h" #ifdef FEATURE_OTA #include "webserver_ota.h" @@ -26,8 +27,6 @@ namespace { httpd_handle_t httpdHandle; -std::atomic shouldReboot; - void initWebserver(); void handleWebserver(); esp_err_t webserver_reboot_handler(httpd_req_t *req); @@ -36,7 +35,8 @@ esp_err_t webserver_reboot_handler(httpd_req_t *req); namespace { void initWebserver() { - shouldReboot = false; + webserver_lock.construct(); + webserver_lock->take(portMAX_DELAY); { httpd_config_t httpConfig HTTPD_DEFAULT_CONFIG(); @@ -74,16 +74,13 @@ void initWebserver() void handleWebserver() { - if (shouldReboot) - { - shouldReboot = false; - esp_restart(); - } + webserver_lock->give(); + webserver_lock->take(portMAX_DELAY); } esp_err_t webserver_reboot_handler(httpd_req_t *req) { - shouldReboot = true; + esp_restart(); CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::Ok, "text/plain", "REBOOT called...") } diff --git a/main/webserver_displaycontrol.h b/main/webserver_displaycontrol.h index 0ed43a7..ef5ad7e 100644 --- a/main/webserver_displaycontrol.h +++ b/main/webserver_displaycontrol.h @@ -15,10 +15,13 @@ #include #include #include +#include +#include // local includes #include "buttons.h" #include "globals.h" +#include "webserver_lock.h" #ifdef FEATURE_WEBSERVER namespace { @@ -33,6 +36,14 @@ using esphttpdutils::HtmlTag; namespace { esp_err_t webserver_root_handler(httpd_req_t *req) { + espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; + if (!helper.locked()) + { + constexpr const std::string_view msg = "could not lock webserver_lock"; + ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); + CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); + } + std::string body; { @@ -125,6 +136,14 @@ esp_err_t webserver_root_handler(httpd_req_t *req) esp_err_t webserver_triggerButton_handler(httpd_req_t *req) { + espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; + if (!helper.locked()) + { + constexpr const std::string_view msg = "could not lock webserver_lock"; + ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); + CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); + } + std::string query; if (auto result = esphttpdutils::webserver_get_query(req)) query = *result; @@ -233,6 +252,14 @@ esp_err_t webserver_triggerButton_handler(httpd_req_t *req) esp_err_t webserver_triggerItem_handler(httpd_req_t *req) { + espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; + if (!helper.locked()) + { + constexpr const std::string_view msg = "could not lock webserver_lock"; + ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); + CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); + } + std::string query; if (auto result = esphttpdutils::webserver_get_query(req)) query = *result; @@ -311,6 +338,14 @@ esp_err_t webserver_triggerItem_handler(httpd_req_t *req) esp_err_t webserver_setValue_handler(httpd_req_t *req) { + espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; + if (!helper.locked()) + { + constexpr const std::string_view msg = "could not lock webserver_lock"; + ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); + CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); + } + std::string query; if (auto result = esphttpdutils::webserver_get_query(req)) query = *result; diff --git a/main/webserver_lock.h b/main/webserver_lock.h new file mode 100644 index 0000000..fa5a494 --- /dev/null +++ b/main/webserver_lock.h @@ -0,0 +1,11 @@ +#pragma once + +// 3rdparty lib includes +#include +#include + +namespace { + +cpputils::DelayedConstruction webserver_lock; + +} // namespace diff --git a/main/webserver_ota.h b/main/webserver_ota.h index 8035e42..732cb44 100644 --- a/main/webserver_ota.h +++ b/main/webserver_ota.h @@ -11,11 +11,14 @@ #include #include #include +#include +#include // local includes #ifdef FEATURE_OTA #include "ota.h" #endif +#include "webserver_lock.h" #if defined(FEATURE_WEBSERVER) && defined(FEATURE_OTA) namespace { @@ -28,6 +31,14 @@ using esphttpdutils::HtmlTag; namespace { esp_err_t webserver_ota_handler(httpd_req_t *req) { + espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; + if (!helper.locked()) + { + constexpr const std::string_view msg = "could not lock webserver_lock"; + ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); + CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); + } + std::string body; { @@ -208,6 +219,14 @@ esp_err_t webserver_ota_handler(httpd_req_t *req) esp_err_t webserver_trigger_ota_handler(httpd_req_t *req) { + espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; + if (!helper.locked()) + { + constexpr const std::string_view msg = "could not lock webserver_lock"; + ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); + CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); + } + std::string query; if (auto result = esphttpdutils::webserver_get_query(req)) query = *result; diff --git a/main/webserver_settings.h b/main/webserver_settings.h index 3fe3dd0..84450d2 100644 --- a/main/webserver_settings.h +++ b/main/webserver_settings.h @@ -15,9 +15,12 @@ #include #include #include +#include +#include // local includes #include "globals.h" +#include "webserver_lock.h" #ifdef FEATURE_WEBSERVER namespace { @@ -41,11 +44,11 @@ template typename std::enable_if::value, bool>::type showInputForSetting(std::string_view key, T value, std::string &body) { - body += fmt::format("" - "", + body += fmt::format("" + "", esphttpdutils::htmlentities(key), - esphttpdutils::htmlentities(key), - value ? "checked " : ""); + value ? "checked " : "", + esphttpdutils::htmlentities(key)); return true; } @@ -63,6 +66,14 @@ showInputForSetting(std::string_view key, T value, std::string &body) esp_err_t webserver_settings_handler(httpd_req_t *req) { + espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; + if (!helper.locked()) + { + constexpr const std::string_view msg = "could not lock webserver_lock"; + ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); + CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); + } + std::string body; { @@ -190,6 +201,14 @@ saveSetting(T &value, std::string_view newValue, std::string &body) esp_err_t webserver_saveSettings_handler(httpd_req_t *req) { + espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; + if (!helper.locked()) + { + constexpr const std::string_view msg = "could not lock webserver_lock"; + ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); + CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); + } + std::string query; if (auto result = esphttpdutils::webserver_get_query(req)) query = *result; @@ -204,13 +223,16 @@ esp_err_t webserver_saveSettings_handler(httpd_req_t *req) settings.executeForEveryCommonSetting([&](std::string_view key, auto &value){ char valueBufEncoded[256]; - if (const auto result = httpd_query_key_value(query.data(), key.data(), valueBufEncoded, 256); result != ESP_OK && result != ESP_ERR_NOT_FOUND) + if (const auto result = httpd_query_key_value(query.data(), key.data(), valueBufEncoded, 256); result != ESP_OK) { - const auto msg = fmt::format("{}: httpd_query_key_value() failed with {}", key, esp_err_to_name(result)); - ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); - body += msg; - body += '\n'; - success = false; + if (result != ESP_ERR_NOT_FOUND) + { + const auto msg = fmt::format("{}: httpd_query_key_value() failed with {}", key, esp_err_to_name(result)); + ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); + body += msg; + body += '\n'; + success = false; + } return; } diff --git a/main/webserver_stringsettings.h b/main/webserver_stringsettings.h index e4bacc6..b27a4eb 100644 --- a/main/webserver_stringsettings.h +++ b/main/webserver_stringsettings.h @@ -11,9 +11,12 @@ #include #include #include +#include +#include // local includes #include "globals.h" +#include "webserver_lock.h" #ifdef FEATURE_WEBSERVER namespace { @@ -26,6 +29,14 @@ using esphttpdutils::HtmlTag; namespace { esp_err_t webserver_stringSettings_handler(httpd_req_t *req) { + espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; + if (!helper.locked()) + { + constexpr const std::string_view msg = "could not lock webserver_lock"; + ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); + CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); + } + std::string body; { @@ -107,6 +118,14 @@ esp_err_t webserver_stringSettings_handler(httpd_req_t *req) esp_err_t webserver_saveStringSettings_handler(httpd_req_t *req) { + espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; + if (!helper.locked()) + { + constexpr const std::string_view msg = "could not lock webserver_lock"; + ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); + CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); + } + std::string query; if (auto result = esphttpdutils::webserver_get_query(req)) query = *result; @@ -121,13 +140,16 @@ esp_err_t webserver_saveStringSettings_handler(httpd_req_t *req) stringSettings.executeForEveryCommonSetting([&](std::string_view key, auto &value){ char valueBufEncoded[256]; - if (const auto result = httpd_query_key_value(query.data(), key.data(), valueBufEncoded, 256); result != ESP_OK && result != ESP_ERR_NOT_FOUND) + if (const auto result = httpd_query_key_value(query.data(), key.data(), valueBufEncoded, 256); result != ESP_OK) { - const auto msg = fmt::format("{}: httpd_query_key_value() failed with {}", key, esp_err_to_name(result)); - ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); - body += msg; - body += '\n'; - success = false; + if (result != ESP_ERR_NOT_FOUND) + { + const auto msg = fmt::format("{}: httpd_query_key_value() failed with {}", key, esp_err_to_name(result)); + ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); + body += msg; + body += '\n'; + success = false; + } return; }