diff --git a/config_allfeatures.cmake b/config_allfeatures.cmake index 5f8e1f2..6501142 100644 --- a/config_allfeatures.cmake +++ b/config_allfeatures.cmake @@ -119,6 +119,5 @@ set(BOBBYCAR_BUILDFLAGS -DOLD_NVS -DFEATURE_DNS_NS -DSWITCH_BLINK - -DFEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_FUNKTIONIERT -DFEATURE_ESPNOW ) diff --git a/config_comred.cmake b/config_comred.cmake index b88e761..ea8bd84 100644 --- a/config_comred.cmake +++ b/config_comred.cmake @@ -119,7 +119,7 @@ set(BOBBYCAR_BUILDFLAGS -DOLD_NVS -DFEATURE_DNS_NS -DSWITCH_BLINK -# -DFEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_FUNKTIONIERT + -DFEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET -DFEATURE_ESPNOW ) diff --git a/config_feedc0de.cmake b/config_feedc0de.cmake index 8315f78..e4bae9f 100644 --- a/config_feedc0de.cmake +++ b/config_feedc0de.cmake @@ -100,6 +100,5 @@ set(BOBBYCAR_BUILDFLAGS -DOLD_NVS # -DFEATURE_DNS_NS # -DSWITCH_BLINK - -DFEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_FUNKTIONIERT # -DFEATURE_ESPNOW ) diff --git a/config_nofeatures.cmake b/config_nofeatures.cmake index 4477dcd..07da662 100644 --- a/config_nofeatures.cmake +++ b/config_nofeatures.cmake @@ -119,6 +119,6 @@ set(BOBBYCAR_BUILDFLAGS -DOLD_NVS # -DFEATURE_DNS_NS # -DSWITCH_BLINK -# -DFEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_FUNKTIONIERT + -DFEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET # -DFEATURE_ESPNOW ) diff --git a/config_peter.cmake b/config_peter.cmake index b8974bf..b92556b 100644 --- a/config_peter.cmake +++ b/config_peter.cmake @@ -99,6 +99,7 @@ set(BOBBYCAR_BUILDFLAGS -DOLD_NVS -DFEATURE_DNS_NS -DFEATURE_ESPNOW + -DFEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET ) if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/ignore/lockscreen_plugin.cmake") diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 9e96a9f..ea18466 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -218,6 +218,7 @@ set(headers webserver_ota.h webserver_settings.h webserver_stringsettings.h + webserver_newsettings.h widgets/doubleprogressbar.h displays/menudisplaywithtime.h wifi_bobbycar.h @@ -444,6 +445,7 @@ set(sources webserver_ota.cpp webserver_settings.cpp webserver_stringsettings.cpp + webserver_newsettings.cpp widgets/doubleprogressbar.cpp wifi_bobbycar.cpp wifitexthelpers.cpp diff --git a/main/newsettings.h b/main/newsettings.h index c9db2b9..0187466 100644 --- a/main/newsettings.h +++ b/main/newsettings.h @@ -57,7 +57,7 @@ public: // default allowReset constraints nvsName ConfigWrapper> baseMacAddressOverride{std::nullopt, NoReset, {}, "baseMacAddrOver" }; ConfigWrapper hostname {defaultHostname, DoReset, StringMinMaxSize<4, 32>, "hostname" }; - ConfigWrapper wifiStaEnabled {true, DoReset, {}, "wifi_enabled" }; + ConfigWrapper wifiStaEnabled {true, DoReset, {}, "wifi_enabled" }; std::array wifi_configs { WiFiConfig {"wifi_ssid0", "wifi_key0", "wifi_usestatic0", "wifi_static_ip0", "wifi_stati_sub0", "wifi_stat_gate0", "wifi_usestadns0", "wifi_stat_dnsA0", "wifi_stat_dnsB0", "wifi_stat_dnsC0"}, WiFiConfig {"wifi_ssid1", "wifi_key1", "wifi_usestatic1", "wifi_static_ip1", "wifi_stati_sub1", "wifi_stat_gate1", "wifi_usestadns1", "wifi_stat_dnsA1", "wifi_stat_dnsB1", "wifi_stat_dnsC1"}, @@ -80,122 +80,137 @@ public: ConfigWrapper wifiApChannel {1, DoReset, {}, "wifiApChannel" }; ConfigWrapper wifiApAuthmode{WIFI_AUTH_WPA2_PSK, DoReset, {}, "wifiApAuthmode" }; +#define NEW_SETTINGS(x) \ + x(baseMacAddressOverride) \ + x(hostname) \ + \ + x(wifiStaEnabled) \ + x(wifi_configs[0].ssid) \ + x(wifi_configs[0].key) \ + x(wifi_configs[0].useStaticIp) \ + x(wifi_configs[0].staticIp) \ + x(wifi_configs[0].staticSubnet) \ + x(wifi_configs[0].staticGateway) \ + x(wifi_configs[0].useStaticDns) \ + x(wifi_configs[0].staticDns0) \ + x(wifi_configs[0].staticDns1) \ + x(wifi_configs[0].staticDns2) \ + x(wifi_configs[1].ssid) \ + x(wifi_configs[1].key) \ + x(wifi_configs[1].useStaticIp) \ + x(wifi_configs[1].staticIp) \ + x(wifi_configs[1].staticSubnet) \ + x(wifi_configs[1].staticGateway) \ + x(wifi_configs[1].useStaticDns) \ + x(wifi_configs[1].staticDns0) \ + x(wifi_configs[1].staticDns1) \ + x(wifi_configs[1].staticDns2) \ + x(wifi_configs[2].ssid) \ + x(wifi_configs[2].key) \ + x(wifi_configs[2].useStaticIp) \ + x(wifi_configs[2].staticIp) \ + x(wifi_configs[2].staticSubnet) \ + x(wifi_configs[2].staticGateway) \ + x(wifi_configs[2].useStaticDns) \ + x(wifi_configs[2].staticDns0) \ + x(wifi_configs[2].staticDns1) \ + x(wifi_configs[2].staticDns2) \ + x(wifi_configs[3].ssid) \ + x(wifi_configs[3].key) \ + x(wifi_configs[3].useStaticIp) \ + x(wifi_configs[3].staticIp) \ + x(wifi_configs[3].staticSubnet) \ + x(wifi_configs[3].staticGateway) \ + x(wifi_configs[3].useStaticDns) \ + x(wifi_configs[3].staticDns0) \ + x(wifi_configs[3].staticDns1) \ + x(wifi_configs[3].staticDns2) \ + x(wifi_configs[4].ssid) \ + x(wifi_configs[4].key) \ + x(wifi_configs[4].useStaticIp) \ + x(wifi_configs[4].staticIp) \ + x(wifi_configs[4].staticSubnet) \ + x(wifi_configs[4].staticGateway) \ + x(wifi_configs[4].useStaticDns) \ + x(wifi_configs[4].staticDns0) \ + x(wifi_configs[4].staticDns1) \ + x(wifi_configs[4].staticDns2) \ + x(wifi_configs[5].ssid) \ + x(wifi_configs[5].key) \ + x(wifi_configs[5].useStaticIp) \ + x(wifi_configs[5].staticIp) \ + x(wifi_configs[5].staticSubnet) \ + x(wifi_configs[5].staticGateway) \ + x(wifi_configs[5].useStaticDns) \ + x(wifi_configs[5].staticDns0) \ + x(wifi_configs[5].staticDns1) \ + x(wifi_configs[5].staticDns2) \ + x(wifi_configs[6].ssid) \ + x(wifi_configs[6].key) \ + x(wifi_configs[6].useStaticIp) \ + x(wifi_configs[6].staticIp) \ + x(wifi_configs[6].staticSubnet) \ + x(wifi_configs[6].staticGateway) \ + x(wifi_configs[6].useStaticDns) \ + x(wifi_configs[6].staticDns0) \ + x(wifi_configs[6].staticDns1) \ + x(wifi_configs[6].staticDns2) \ + x(wifi_configs[7].ssid) \ + x(wifi_configs[7].key) \ + x(wifi_configs[7].useStaticIp) \ + x(wifi_configs[7].staticIp) \ + x(wifi_configs[7].staticSubnet) \ + x(wifi_configs[7].staticGateway) \ + x(wifi_configs[7].useStaticDns) \ + x(wifi_configs[7].staticDns0) \ + x(wifi_configs[7].staticDns1) \ + x(wifi_configs[7].staticDns2) \ + x(wifi_configs[8].ssid) \ + x(wifi_configs[8].key) \ + x(wifi_configs[8].useStaticIp) \ + x(wifi_configs[8].staticIp) \ + x(wifi_configs[8].staticSubnet) \ + x(wifi_configs[8].staticGateway) \ + x(wifi_configs[8].useStaticDns) \ + x(wifi_configs[8].staticDns0) \ + x(wifi_configs[8].staticDns1) \ + x(wifi_configs[8].staticDns2) \ + x(wifi_configs[9].ssid) \ + x(wifi_configs[9].key) \ + x(wifi_configs[9].useStaticIp) \ + x(wifi_configs[9].staticIp) \ + x(wifi_configs[9].staticSubnet) \ + x(wifi_configs[9].staticGateway) \ + x(wifi_configs[9].useStaticDns) \ + x(wifi_configs[9].staticDns0) \ + x(wifi_configs[9].staticDns1) \ + x(wifi_configs[9].staticDns2) \ + \ + x(wifiStaMinRssi) \ + \ + x(wifiApEnabled) \ + x(factoryWifiApName) \ + x(wifiApName) \ + x(factoryWifiApKey) \ + x(wifiApKey) \ + x(wifiApChannel) \ + //x(wifiApAuthmode) + + template + void callForEveryConfig(T &&callback) + { +#define HELPER(x) callback(x); + NEW_SETTINGS(HELPER) +#undef HELPER + callback(wifiApAuthmode); + } + auto getAllConfigParams() { return cpputils::make_array( - std::ref(baseMacAddressOverride), - std::ref(hostname), - - std::ref(wifiStaEnabled), - std::ref(wifi_configs[0].ssid), - std::ref(wifi_configs[0].key), - std::ref(wifi_configs[0].useStaticIp), - std::ref(wifi_configs[0].staticIp), - std::ref(wifi_configs[0].staticSubnet), - std::ref(wifi_configs[0].staticGateway), - std::ref(wifi_configs[0].useStaticDns), - std::ref(wifi_configs[0].staticDns0), - std::ref(wifi_configs[0].staticDns1), - std::ref(wifi_configs[0].staticDns2), - std::ref(wifi_configs[1].ssid), - std::ref(wifi_configs[1].key), - std::ref(wifi_configs[1].useStaticIp), - std::ref(wifi_configs[1].staticIp), - std::ref(wifi_configs[1].staticSubnet), - std::ref(wifi_configs[1].staticGateway), - std::ref(wifi_configs[1].useStaticDns), - std::ref(wifi_configs[1].staticDns0), - std::ref(wifi_configs[1].staticDns1), - std::ref(wifi_configs[1].staticDns2), - std::ref(wifi_configs[2].ssid), - std::ref(wifi_configs[2].key), - std::ref(wifi_configs[2].useStaticIp), - std::ref(wifi_configs[2].staticIp), - std::ref(wifi_configs[2].staticSubnet), - std::ref(wifi_configs[2].staticGateway), - std::ref(wifi_configs[2].useStaticDns), - std::ref(wifi_configs[2].staticDns0), - std::ref(wifi_configs[2].staticDns1), - std::ref(wifi_configs[2].staticDns2), - std::ref(wifi_configs[3].ssid), - std::ref(wifi_configs[3].key), - std::ref(wifi_configs[3].useStaticIp), - std::ref(wifi_configs[3].staticIp), - std::ref(wifi_configs[3].staticSubnet), - std::ref(wifi_configs[3].staticGateway), - std::ref(wifi_configs[3].useStaticDns), - std::ref(wifi_configs[3].staticDns0), - std::ref(wifi_configs[3].staticDns1), - std::ref(wifi_configs[3].staticDns2), - std::ref(wifi_configs[4].ssid), - std::ref(wifi_configs[4].key), - std::ref(wifi_configs[4].useStaticIp), - std::ref(wifi_configs[4].staticIp), - std::ref(wifi_configs[4].staticSubnet), - std::ref(wifi_configs[4].staticGateway), - std::ref(wifi_configs[4].useStaticDns), - std::ref(wifi_configs[4].staticDns0), - std::ref(wifi_configs[4].staticDns1), - std::ref(wifi_configs[4].staticDns2), - std::ref(wifi_configs[5].ssid), - std::ref(wifi_configs[5].key), - std::ref(wifi_configs[5].useStaticIp), - std::ref(wifi_configs[5].staticIp), - std::ref(wifi_configs[5].staticSubnet), - std::ref(wifi_configs[5].staticGateway), - std::ref(wifi_configs[5].useStaticDns), - std::ref(wifi_configs[5].staticDns0), - std::ref(wifi_configs[5].staticDns1), - std::ref(wifi_configs[5].staticDns2), - std::ref(wifi_configs[6].ssid), - std::ref(wifi_configs[6].key), - std::ref(wifi_configs[6].useStaticIp), - std::ref(wifi_configs[6].staticIp), - std::ref(wifi_configs[6].staticSubnet), - std::ref(wifi_configs[6].staticGateway), - std::ref(wifi_configs[6].useStaticDns), - std::ref(wifi_configs[6].staticDns0), - std::ref(wifi_configs[6].staticDns1), - std::ref(wifi_configs[6].staticDns2), - std::ref(wifi_configs[7].ssid), - std::ref(wifi_configs[7].key), - std::ref(wifi_configs[7].useStaticIp), - std::ref(wifi_configs[7].staticIp), - std::ref(wifi_configs[7].staticSubnet), - std::ref(wifi_configs[7].staticGateway), - std::ref(wifi_configs[7].useStaticDns), - std::ref(wifi_configs[7].staticDns0), - std::ref(wifi_configs[7].staticDns1), - std::ref(wifi_configs[7].staticDns2), - std::ref(wifi_configs[8].ssid), - std::ref(wifi_configs[8].key), - std::ref(wifi_configs[8].useStaticIp), - std::ref(wifi_configs[8].staticIp), - std::ref(wifi_configs[8].staticSubnet), - std::ref(wifi_configs[8].staticGateway), - std::ref(wifi_configs[8].useStaticDns), - std::ref(wifi_configs[8].staticDns0), - std::ref(wifi_configs[8].staticDns1), - std::ref(wifi_configs[8].staticDns2), - std::ref(wifi_configs[9].ssid), - std::ref(wifi_configs[9].key), - std::ref(wifi_configs[9].useStaticIp), - std::ref(wifi_configs[9].staticIp), - std::ref(wifi_configs[9].staticSubnet), - std::ref(wifi_configs[9].staticGateway), - std::ref(wifi_configs[9].useStaticDns), - std::ref(wifi_configs[9].staticDns0), - std::ref(wifi_configs[9].staticDns1), - std::ref(wifi_configs[9].staticDns2), - - std::ref(wifiStaMinRssi), - - std::ref(wifiApEnabled), - std::ref(factoryWifiApName), - std::ref(wifiApName), - std::ref(factoryWifiApKey), - std::ref(wifiApKey), - std::ref(wifiApChannel), +#define HELPER(x) std::ref(x), + NEW_SETTINGS(HELPER) +#undef HELPER std::ref(wifiApAuthmode) ); } diff --git a/main/webserver.cpp b/main/webserver.cpp index e9fe6e2..391170e 100644 --- a/main/webserver.cpp +++ b/main/webserver.cpp @@ -1,33 +1,65 @@ #include "webserver.h" #include "sdkconfig.h" +// system includes +#include + +// esp-idf includes +#include + +// 3rdparty lib includes +#include +#include +#include +#include +#include +#include +#include +#include + +// local includes +#include "webserver_lock.h" +#include "webserver_displaycontrol.h" +#ifdef FEATURE_OTA +#include "webserver_ota.h" +#endif +#include "webserver_settings.h" +#include "webserver_stringsettings.h" +#include "webserver_newsettings.h" +#ifdef OLD_NVS +#include "webserver_dumpnvs.h" +#endif +#include "globals.h" + using namespace std::chrono_literals; #ifdef FEATURE_WEBSERVER namespace { constexpr const char * const TAG = "BOBBYWEB"; -} // namespace -namespace bobbywebserver { -bool forceRefresh{false}; +//bool forceRefresh{false}; bool lastScreenWasMenu{}; int8_t lastSelectIndex{}; std::vector> menuBuf{}; -} + +esp_err_t webserver_reboot_handler(httpd_req_t *req); +bool menuDisplayChanged(); +esp_err_t webserver_status_handler(httpd_req_t *req); +} // namespace bobbywebserver httpd_handle_t httpdHandle; void initWebserver() { +#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET webserver_lock.construct(); -#ifdef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_FUNKTIONIERT webserver_lock->take(portMAX_DELAY); #endif { httpd_config_t httpConfig HTTPD_DEFAULT_CONFIG(); httpConfig.core_id = 1; - httpConfig.max_uri_handlers = 14; + httpConfig.max_uri_handlers = 16; httpConfig.stack_size = 8192; const auto result = httpd_start(&httpdHandle, &httpConfig); @@ -51,6 +83,8 @@ void initWebserver() httpd_uri_t { .uri = "/saveSettings", .method = HTTP_GET, .handler = webserver_saveSettings_handler, .user_ctx = NULL }, httpd_uri_t { .uri = "/stringSettings", .method = HTTP_GET, .handler = webserver_stringSettings_handler, .user_ctx = NULL }, httpd_uri_t { .uri = "/saveStringSettings", .method = HTTP_GET, .handler = webserver_saveStringSettings_handler, .user_ctx = NULL }, + httpd_uri_t { .uri = "/newSettings", .method = HTTP_GET, .handler = webserver_newSettings_handler, .user_ctx = NULL }, + httpd_uri_t { .uri = "/saveNewSettings", .method = HTTP_GET, .handler = webserver_saveNewSettings_handler, .user_ctx = NULL }, #ifdef OLD_NVS httpd_uri_t { .uri = "/dumpnvs", .method = HTTP_GET, .handler = webserver_dump_nvs_handler, .user_ctx = NULL }, #endif @@ -66,12 +100,15 @@ void initWebserver() void handleWebserver() { -#ifdef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_FUNKTIONIERT +#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET webserver_lock->give(); + vTaskDelay(1); webserver_lock->take(portMAX_DELAY); #endif } +namespace { + esp_err_t webserver_reboot_handler(httpd_req_t *req) { esp_restart(); @@ -81,7 +118,6 @@ esp_err_t webserver_reboot_handler(httpd_req_t *req) bool menuDisplayChanged() { - using namespace bobbywebserver; if (auto currentDisplay = static_cast(espgui::currentDisplay.get())) { lastScreenWasMenu = true; @@ -129,7 +165,7 @@ bool menuDisplayChanged() esp_err_t webserver_status_handler(httpd_req_t *req) { -#ifdef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_FUNKTIONIERT +#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; if (!helper.locked()) { @@ -170,4 +206,5 @@ esp_err_t webserver_status_handler(httpd_req_t *req) } } +} // namespace #endif diff --git a/main/webserver.h b/main/webserver.h index f6770b5..6312b93 100644 --- a/main/webserver.h +++ b/main/webserver.h @@ -1,30 +1,9 @@ #pragma once -// system includes -#include -#include - // esp-idf includes #ifdef FEATURE_WEBSERVER #include #endif -#include - -// 3rdparty lib includes -#include -#include - -// local includes -#include "webserver_lock.h" -#include "webserver_displaycontrol.h" -#ifdef FEATURE_OTA -#include "webserver_ota.h" -#endif -#include "webserver_settings.h" -#include "webserver_stringsettings.h" -#ifdef OLD_NVS -#include "webserver_dumpnvs.h" -#endif #ifdef FEATURE_WEBSERVER extern httpd_handle_t httpdHandle; @@ -32,13 +11,4 @@ extern httpd_handle_t httpdHandle; void initWebserver(); void handleWebserver(); bool MenuDisplayChanged(); -esp_err_t webserver_reboot_handler(httpd_req_t *req); -esp_err_t webserver_status_handler(httpd_req_t *req); - -namespace bobbywebserver { -extern bool forceRefresh; -extern bool lastScreenWasMenu; -extern int8_t lastSelectIndex; -extern std::vector> menuBuf; -} #endif diff --git a/main/webserver_displaycontrol.cpp b/main/webserver_displaycontrol.cpp index 78f96f8..cd3efc7 100644 --- a/main/webserver_displaycontrol.cpp +++ b/main/webserver_displaycontrol.cpp @@ -1,5 +1,29 @@ #include "webserver_displaycontrol.h" +// esp-idf includes +#ifdef FEATURE_WEBSERVER +#include +#endif +#include + +// 3rdparty lib includes +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// local includes +#include "buttons.h" +#include "globals.h" +#include "webserver_lock.h" + #ifdef FEATURE_WEBSERVER using esphttpdutils::HtmlTag; using namespace std::chrono_literals; @@ -10,7 +34,8 @@ constexpr const char * const TAG = "BOBBYWEB"; esp_err_t webserver_root_handler(httpd_req_t *req) { -#ifdef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_FUNKTIONIERT +#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET + ESP_LOGI(TAG, "locking..."); espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; if (!helper.locked()) { @@ -18,6 +43,7 @@ esp_err_t webserver_root_handler(httpd_req_t *req) ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); } + ESP_LOGI(TAG, "succeeded"); #endif std::string body; @@ -160,6 +186,7 @@ esp_err_t webserver_root_handler(httpd_req_t *req) "Settings - " "String Settings - " + "New Settings - " "Dump NVS"; } @@ -221,7 +248,7 @@ esp_err_t webserver_root_handler(httpd_req_t *req) esp_err_t webserver_triggerButton_handler(httpd_req_t *req) { -#ifdef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_FUNKTIONIERT +#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; if (!helper.locked()) { @@ -339,8 +366,7 @@ esp_err_t webserver_triggerButton_handler(httpd_req_t *req) esp_err_t webserver_triggerItem_handler(httpd_req_t *req) { - -#ifdef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_FUNKTIONIERT +#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; if (!helper.locked()) { @@ -428,8 +454,7 @@ esp_err_t webserver_triggerItem_handler(httpd_req_t *req) esp_err_t webserver_setValue_handler(httpd_req_t *req) { - -#ifdef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_FUNKTIONIERT +#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; if (!helper.locked()) { diff --git a/main/webserver_displaycontrol.h b/main/webserver_displaycontrol.h index 2fd9d72..7a7736e 100644 --- a/main/webserver_displaycontrol.h +++ b/main/webserver_displaycontrol.h @@ -4,25 +4,7 @@ #ifdef FEATURE_WEBSERVER #include #endif -#include - -// 3rdparty lib includes -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// local includes -#include "buttons.h" -#include "globals.h" -#include "webserver_lock.h" +#include #ifdef FEATURE_WEBSERVER esp_err_t webserver_root_handler(httpd_req_t *req); diff --git a/main/webserver_dumpnvs.cpp b/main/webserver_dumpnvs.cpp index 8750640..278c8ad 100644 --- a/main/webserver_dumpnvs.cpp +++ b/main/webserver_dumpnvs.cpp @@ -1,5 +1,26 @@ #include "webserver_dumpnvs.h" +// esp-idf includes +#ifdef FEATURE_WEBSERVER +#include +#endif +#include + +// 3rdparty lib includes +#include +#include +#include +#include +#include +#include +#include +#include + +// local includes +#include "globals.h" +#include "webserver_lock.h" +#include "settingsutils.h" + using esphttpdutils::HtmlTag; using namespace espchrono; using namespace std::chrono_literals; @@ -114,8 +135,7 @@ showInputForSetting(std::string_view key, T value, JsonObject &body) esp_err_t webserver_dump_nvs_handler(httpd_req_t *req) { - -#ifdef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_FUNKTIONIERT +#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; if (!helper.locked()) { diff --git a/main/webserver_dumpnvs.h b/main/webserver_dumpnvs.h index c8306aa..9653e26 100644 --- a/main/webserver_dumpnvs.h +++ b/main/webserver_dumpnvs.h @@ -4,22 +4,7 @@ #ifdef FEATURE_WEBSERVER #include #endif -#include - -// 3rdparty lib includes -#include -#include -#include -#include -#include -#include -#include -#include - -// local includes -#include "globals.h" -#include "webserver_lock.h" -#include "settingsutils.h" +#include #ifdef FEATURE_WEBSERVER esp_err_t webserver_dump_nvs_handler(httpd_req_t *req); diff --git a/main/webserver_lock.cpp b/main/webserver_lock.cpp index ae0dbe1..c2215f9 100644 --- a/main/webserver_lock.cpp +++ b/main/webserver_lock.cpp @@ -1,3 +1,5 @@ #include "webserver_lock.h" +#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET cpputils::DelayedConstruction webserver_lock; +#endif diff --git a/main/webserver_lock.h b/main/webserver_lock.h index ddb94b5..e6f2429 100644 --- a/main/webserver_lock.h +++ b/main/webserver_lock.h @@ -4,4 +4,6 @@ #include #include +#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET extern cpputils::DelayedConstruction webserver_lock; +#endif diff --git a/main/webserver_newsettings.cpp b/main/webserver_newsettings.cpp new file mode 100644 index 0000000..72797d0 --- /dev/null +++ b/main/webserver_newsettings.cpp @@ -0,0 +1,437 @@ +#include "webserver_newsettings.h" + +// system includes +#include + +// esp-idf includes +#ifdef FEATURE_WEBSERVER +#include +#endif +#include + +// 3rdparty lib includes +#include +#include +#include +#include +#include +#include +#include + +// local includes +#include "newsettings.h" +#include "webserver_lock.h" + +#ifdef FEATURE_WEBSERVER +using namespace std::chrono_literals; +using esphttpdutils::HtmlTag; + +namespace { +constexpr const char * const TAG = "BOBBYWEB"; + +template +typename std::enable_if< + !std::is_same::value && + !std::is_integral::value && + !std::is_same::value && + !std::is_same::value && + !std::is_same::value +, bool>::type +showInputForSetting(std::string_view key, T value, std::string &body) +{ + HtmlTag spanTag{"span", "style=\"color: red;\"", body}; + body += "Unsupported config type"; + return false; +} + +template +typename std::enable_if< + std::is_same::value +, bool>::type +showInputForSetting(std::string_view key, T value, std::string &body) +{ + body += fmt::format("" + "", + esphttpdutils::htmlentities(key), + value ? "checked " : "", + esphttpdutils::htmlentities(key)); + return true; +} + +template +typename std::enable_if< + !std::is_same::value && + std::is_integral::value +, bool>::type +showInputForSetting(std::string_view key, T value, std::string &body) +{ + body += fmt::format("", + esphttpdutils::htmlentities(key), + value, + std::numeric_limits::min(), + std::numeric_limits::max()); + return true; +} + +template +typename std::enable_if< + std::is_same::value +, bool>::type +showInputForSetting(std::string_view key, T value, std::string &body) +{ + body += fmt::format("", + esphttpdutils::htmlentities(key), + esphttpdutils::htmlentities(value)); + return true; +} + +template +typename std::enable_if< + std::is_same::value +, bool>::type +showInputForSetting(std::string_view key, T value, std::string &body) +{ + body += fmt::format("", + esphttpdutils::htmlentities(key), + esphttpdutils::htmlentities(wifi_stack::toString(value))); + return true; +} + +template +typename std::enable_if< + std::is_same::value +, bool>::type +showInputForSetting(std::string_view key, T value, std::string &body) +{ + body += fmt::format("", + esphttpdutils::htmlentities(key), + esphttpdutils::htmlentities(wifi_stack::toString(value))); + return true; +} +} // namespace + +esp_err_t webserver_newSettings_handler(httpd_req_t *req) +{ +#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET + 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); + } +#endif + + std::string body; + + { + HtmlTag htmlTag{"html", body}; + + { + HtmlTag headTag{"head", body}; + + { + HtmlTag titleTag{"title", body}; + body += "Settings"; + } + + body += ""; + + HtmlTag styleTag{"style", "type=\"text/css\"", body}; + body += + ".form-table {" + "display: table;" + "border-collapse: separate;" + "border-spacing: 10px 0;" + "}" + + ".form-table .form-table-row {" + "display: table-row;" + "}" + + ".form-table .form-table-row .form-table-cell {" + "display: table-cell;" + "}"; + } + + { + HtmlTag bodyTag{"body", body}; + + { + HtmlTag h1Tag{"h1", body}; + body += "Settings"; + } + + { + HtmlTag pTag{"p", body}; + body += "Display control - " +#ifdef FEATURE_OTA + "Update - " +#endif + "Settings - " + "String Settings - " + "New Settings - " + "Dump NVS"; + } + + HtmlTag divTag{"div", "class=\"form-table\"", body}; + + configs.callForEveryConfig([&](const auto &config){ + if (body.size() > 2048) + { + if (const auto result = httpd_resp_send_chunk(req, body.data(), body.size()); result != ESP_OK) + { + ESP_LOGE(TAG, "httpd_resp_send_chunk() failed with %s", esp_err_to_name(result)); + //return result; + } + body.clear(); + } + + const std::string_view nvsName{config.nvsName()}; + + HtmlTag formTag{"form", "class=\"form-table-row\" action=\"/saveNewSettings\" method=\"GET\"", body}; + + { + HtmlTag divTag{"div", "class=\"form-table\"", body}; + HtmlTag bTag{"b", body}; + body += esphttpdutils::htmlentities(nvsName); + } + + { + HtmlTag divTag{"div", "class=\"form-table-cell\"", body}; + showInputForSetting(nvsName, config.value, body); + } + + { + HtmlTag divTag{"div", "class=\"form-table-cell\"", body}; + HtmlTag buttonTag{"button", "type=\"submit\"", body}; + body += "Save"; + } + }); + } + } + + CALL_AND_EXIT_ON_ERROR(httpd_resp_send_chunk, req, body.data(), body.size()); + body.clear(); + CALL_AND_EXIT(httpd_resp_send_chunk, req, nullptr, 0); + //CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::Ok, "text/html", body) +} + +namespace { +template +typename std::enable_if< + !std::is_same::value && + !std::is_integral::value && + !std::is_same::value && + !std::is_same::value && + !std::is_same::value +, bool>::type +saveSetting(ConfigWrapper &config, std::string_view newValue, std::string &body) +{ + body += "Unsupported config type"; + return false; +} + +template +typename std::enable_if< + std::is_same::value +, bool>::type +saveSetting(ConfigWrapper &config, std::string_view newValue, std::string &body) +{ + if (newValue == "true") + { + if (const auto result = configs.write_config(config, true); result) + { + body += "applied"; + return true; + } + else + { + body += result.error(); + return false; + } + } + else if (newValue == "false") + { + if (const auto result = configs.write_config(config, false); result) + { + body += "applied"; + return true; + } + else + { + body += result.error(); + return false; + } + } + else + { + body += fmt::format("only true and false allowed, not {}", newValue); + return false; + } +} + +template +typename std::enable_if< + !std::is_same::value && + std::is_integral::value +, bool>::type +saveSetting(ConfigWrapper &config, std::string_view newValue, std::string &body) +{ + if (auto parsed = cpputils::fromString(newValue)) + { + if (const auto result = configs.write_config(config, *parsed); result) + { + body += "applied"; + return true; + } + else + { + body += result.error(); + return false; + } + } + else + { + body += fmt::format("could not parse {}", newValue); + return false; + } +} + +template +typename std::enable_if< + std::is_same::value +, bool>::type +saveSetting(ConfigWrapper &config, std::string_view newValue, std::string &body) +{ + if (const auto result = configs.write_config(config, std::string{newValue}); result) + { + body += "applied"; + return true; + } + else + { + body += result.error(); + return false; + } +} + +template +typename std::enable_if< + std::is_same::value +, bool>::type +saveSetting(ConfigWrapper &config, std::string_view newValue, std::string &body) +{ + if (const auto parsed = wifi_stack::fromString(newValue); parsed) + { + if (const auto result = configs.write_config(config, *parsed); result) + { + body += "applied"; + return true; + } + else + { + body += result.error(); + return false; + } + } + else + { + body += parsed.error(); + return false; + } +} + +template +typename std::enable_if< + std::is_same::value +, bool>::type +saveSetting(ConfigWrapper &config, std::string_view newValue, std::string &body) +{ + if (const auto parsed = wifi_stack::fromString(newValue); parsed) + { + if (const auto result = configs.write_config(config, *parsed); result) + { + body += "applied"; + return true; + } + else + { + body += result.error(); + return false; + } + } + else + { + body += parsed.error(); + return false; + } +} +} // namespace + +esp_err_t webserver_saveNewSettings_handler(httpd_req_t *req) +{ +#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET + 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); + } +#endif + + std::string query; + if (auto result = esphttpdutils::webserver_get_query(req)) + query = *result; + else + { + ESP_LOGE(TAG, "%.*s", result.error().size(), result.error().data()); + CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", result.error()); + } + + std::string body; + bool success{true}; + + configs.callForEveryConfig([&](auto &config){ + const std::string_view nvsName{config.nvsName()}; + + char valueBufEncoded[256]; + if (const auto result = httpd_query_key_value(query.data(), nvsName.data(), valueBufEncoded, 256); result != ESP_OK) + { + if (result != ESP_ERR_NOT_FOUND) + { + const auto msg = fmt::format("{}: httpd_query_key_value() failed with {}", nvsName, esp_err_to_name(result)); + ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); + body += msg; + body += '\n'; + success = false; + } + return; + } + + char valueBuf[257]; + esphttpdutils::urldecode(valueBuf, valueBufEncoded); + + body += nvsName; + if (!saveSetting(config, valueBuf, body)) + success = false; + body += '\n'; + }); + + if (body.empty()) + CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::Ok, "text/plain", "nothing changed?!") + + if (success) + { + CALL_AND_EXIT_ON_ERROR(httpd_resp_set_hdr, req, "Location", "/newSettings") + body += "\nOk, continue at /newSettings"; + } + + CALL_AND_EXIT(esphttpdutils::webserver_resp_send, + req, + success ? esphttpdutils::ResponseStatus::TemporaryRedirect : esphttpdutils::ResponseStatus::BadRequest, + "text/plain", + body) +} +#endif diff --git a/main/webserver_newsettings.h b/main/webserver_newsettings.h new file mode 100644 index 0000000..5424186 --- /dev/null +++ b/main/webserver_newsettings.h @@ -0,0 +1,12 @@ +#pragma once + +// esp-idf includes +#ifdef FEATURE_WEBSERVER +#include +#endif +#include + +#ifdef FEATURE_WEBSERVER +esp_err_t webserver_newSettings_handler(httpd_req_t *req); +esp_err_t webserver_saveNewSettings_handler(httpd_req_t *req); +#endif diff --git a/main/webserver_ota.cpp b/main/webserver_ota.cpp index 93b72b3..e00a282 100644 --- a/main/webserver_ota.cpp +++ b/main/webserver_ota.cpp @@ -1,6 +1,26 @@ #include "webserver_ota.h" +// esp-idf includes +#ifdef FEATURE_WEBSERVER +#include +#endif +#include +#include + +// 3rdparty lib includes +#include +#include +#include +#include +#include +#include +#include + // local includes +#ifdef FEATURE_OTA +#include "ota.h" +#endif +#include "webserver_lock.h" #include "globals.h" #if defined(FEATURE_WEBSERVER) && defined(FEATURE_OTA) @@ -13,7 +33,7 @@ constexpr const char * const TAG = "BOBBYWEB"; esp_err_t webserver_ota_percentage_handler(httpd_req_t *req) { -#ifdef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_FUNKTIONIERT +#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; if (!helper.locked()) { @@ -72,7 +92,7 @@ esp_err_t webserver_ota_percentage_handler(httpd_req_t *req) esp_err_t webserver_ota_handler(httpd_req_t *req) { -#ifdef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_FUNKTIONIERT +#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; if (!helper.locked()) { @@ -189,6 +209,7 @@ esp_err_t webserver_ota_handler(httpd_req_t *req) "Update - " "Settings - " "String Settings - " + "New Settings - " "Dump NVS"; } @@ -340,6 +361,7 @@ esp_err_t webserver_ota_handler(httpd_req_t *req) esp_err_t webserver_trigger_ota_handler(httpd_req_t *req) { +#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; if (!helper.locked()) { @@ -347,6 +369,7 @@ esp_err_t webserver_trigger_ota_handler(httpd_req_t *req) ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); } +#endif std::string query; if (auto result = esphttpdutils::webserver_get_query(req)) diff --git a/main/webserver_ota.h b/main/webserver_ota.h index 81c11e3..c76ed46 100644 --- a/main/webserver_ota.h +++ b/main/webserver_ota.h @@ -4,23 +4,7 @@ #ifdef FEATURE_WEBSERVER #include #endif -#include -#include - -// 3rdparty lib includes -#include -#include -#include -#include -#include -#include -#include - -// local includes -#ifdef FEATURE_OTA -#include "ota.h" -#endif -#include "webserver_lock.h" +#include #if defined(FEATURE_WEBSERVER) && defined(FEATURE_OTA) esp_err_t webserver_ota_handler(httpd_req_t *req); diff --git a/main/webserver_settings.cpp b/main/webserver_settings.cpp index 0868bae..dd9fee0 100644 --- a/main/webserver_settings.cpp +++ b/main/webserver_settings.cpp @@ -1,12 +1,33 @@ #include "webserver_settings.h" +// system includes +#include + +// esp-idf includes +#ifdef FEATURE_WEBSERVER +#include +#endif +#include + +// 3rdparty lib includes +#include +#include +#include +#include +#include +#include +#include + +// local includes +#include "globals.h" +#include "webserver_lock.h" + #ifdef FEATURE_WEBSERVER using namespace std::chrono_literals; using esphttpdutils::HtmlTag; namespace { constexpr const char * const TAG = "BOBBYWEB"; -} // namespace template typename std::enable_if< @@ -64,9 +85,11 @@ showInputForSetting(std::string_view key, T value, std::string &body) value[3]); return true; } +} // namespace esp_err_t webserver_settings_handler(httpd_req_t *req) { +#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; if (!helper.locked()) { @@ -74,6 +97,7 @@ esp_err_t webserver_settings_handler(httpd_req_t *req) ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); } +#endif std::string body; @@ -123,6 +147,7 @@ esp_err_t webserver_settings_handler(httpd_req_t *req) #endif "Settings - " "String Settings - " + "New Settings - " "Dump NVS"; } @@ -153,6 +178,7 @@ esp_err_t webserver_settings_handler(httpd_req_t *req) CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::Ok, "text/html", body) } +namespace { template typename std::enable_if< !std::is_same::value && @@ -228,9 +254,11 @@ saveSetting(T &value, std::string_view newValue, std::string &body) return false; } } +} // namespace esp_err_t webserver_saveSettings_handler(httpd_req_t *req) { +#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; if (!helper.locked()) { @@ -238,6 +266,7 @@ esp_err_t webserver_saveSettings_handler(httpd_req_t *req) ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); } +#endif std::string query; if (auto result = esphttpdutils::webserver_get_query(req)) diff --git a/main/webserver_settings.h b/main/webserver_settings.h index 71647ab..db6c309 100644 --- a/main/webserver_settings.h +++ b/main/webserver_settings.h @@ -1,26 +1,10 @@ #pragma once -// system includes -#include - // esp-idf includes #ifdef FEATURE_WEBSERVER #include #endif -#include - -// 3rdparty lib includes -#include -#include -#include -#include -#include -#include -#include - -// local includes -#include "globals.h" -#include "webserver_lock.h" +#include #ifdef FEATURE_WEBSERVER esp_err_t webserver_settings_handler(httpd_req_t *req); diff --git a/main/webserver_stringsettings.cpp b/main/webserver_stringsettings.cpp index 716a1a0..92b995e 100644 --- a/main/webserver_stringsettings.cpp +++ b/main/webserver_stringsettings.cpp @@ -1,5 +1,22 @@ #include "webserver_stringsettings.h" +// esp-idf includes +#ifdef FEATURE_WEBSERVER +#include +#endif + +// 3rdparty lib includes +#include +#include +#include +#include +#include +#include + +// local includes +#include "globals.h" +#include "webserver_lock.h" + #ifdef FEATURE_WEBSERVER using namespace std::chrono_literals; using esphttpdutils::HtmlTag; @@ -10,6 +27,7 @@ constexpr const char * const TAG = "BOBBYWEB"; esp_err_t webserver_stringSettings_handler(httpd_req_t *req) { +#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; if (!helper.locked()) { @@ -17,6 +35,7 @@ esp_err_t webserver_stringSettings_handler(httpd_req_t *req) ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); } +#endif std::string body; @@ -66,6 +85,7 @@ esp_err_t webserver_stringSettings_handler(httpd_req_t *req) #endif "Settings - " "String Settings - " + "New Settings - " "Dump NVS"; } @@ -100,6 +120,7 @@ esp_err_t webserver_stringSettings_handler(httpd_req_t *req) esp_err_t webserver_saveStringSettings_handler(httpd_req_t *req) { +#ifndef FEATURE_IS_MIR_EGAL_OB_DER_WEBSERVER_KORREKT_ARBEITET espcpputils::LockHelper helper{webserver_lock->handle, std::chrono::ceil(5s).count()}; if (!helper.locked()) { @@ -107,6 +128,7 @@ esp_err_t webserver_saveStringSettings_handler(httpd_req_t *req) ESP_LOGE(TAG, "%.*s", msg.size(), msg.data()); CALL_AND_EXIT(esphttpdutils::webserver_resp_send, req, esphttpdutils::ResponseStatus::BadRequest, "text/plain", msg); } +#endif std::string query; if (auto result = esphttpdutils::webserver_get_query(req)) diff --git a/main/webserver_stringsettings.h b/main/webserver_stringsettings.h index 0e881f4..abd4309 100644 --- a/main/webserver_stringsettings.h +++ b/main/webserver_stringsettings.h @@ -4,19 +4,7 @@ #ifdef FEATURE_WEBSERVER #include #endif -#include - -// 3rdparty lib includes -#include -#include -#include -#include -#include -#include - -// local includes -#include "globals.h" -#include "webserver_lock.h" +#include #ifdef FEATURE_WEBSERVER esp_err_t webserver_stringSettings_handler(httpd_req_t *req);