diff --git a/.github/actions/build-simulator/action.yml b/.github/actions/build-simulator/action.yml index 3d3eb962..b257b2c7 100644 --- a/.github/actions/build-simulator/action.yml +++ b/.github/actions/build-simulator/action.yml @@ -36,14 +36,16 @@ runs: WLR_LIBINPUT_NO_DEVICES: 1 WAYLAND_DISPLAY: wayland-1 GTK_USE_PORTAL: 0 - - name: "Configure Project" - uses: threeal/cmake-action@v1.3.0 + - name: Setup cmake + uses: jwlawson/actions-setup-cmake@v2 + with: + cmake-version: '3.31.x' - name: "Prepare Project" shell: bash run: cmake -S ./ -B buildsim - name: "Build Tests" shell: bash - run: cmake --build buildsim --target AppSim + run: cmake --build buildsim --target FirmwareSim - name: 'Release' shell: bash run: Buildscripts/release-simulator.sh buildsim release/Simulator-${{ inputs.os_name }}-${{ inputs.platform_name }} diff --git a/.gitmodules b/.gitmodules index 4c25edde..85b6156b 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "Libraries/minitar/minitar"] path = Libraries/minitar/minitar url = https://github.com/ByteWelder/minitar.git +[submodule "Libraries/cJSON/cJSON"] + path = Libraries/cJSON/cJSON + url = git@github.com:DaveGamble/cJSON.git diff --git a/Buildscripts/release-simulator.sh b/Buildscripts/release-simulator.sh index 0506bfcc..16ab106d 100755 --- a/Buildscripts/release-simulator.sh +++ b/Buildscripts/release-simulator.sh @@ -12,6 +12,6 @@ target_path=$2 mkdir -p $target_path cp version.txt $target_path -cp $build_path/App/AppSim $target_path/ +cp $build_path/Firmware/FirmwareSim $target_path/ cp -r Data/data $target_path/ cp -r Data/system $target_path/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 9f3d735d..149c2773 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,8 @@ if (NOT DEFINED ENV{ESP_IDF_VERSION}) # FreeRTOS set(FREERTOS_CONFIG_FILE_DIRECTORY ${PROJECT_SOURCE_DIR}/Boards/Simulator/Source CACHE STRING "") set(FREERTOS_PORT GCC_POSIX CACHE STRING "") + + add_subdirectory(Libraries/cJSON) add_subdirectory(Libraries/FreeRTOS-Kernel) add_subdirectory(Libraries/lv_screenshot) add_subdirectory(Libraries/QRCode) @@ -92,18 +94,20 @@ if (NOT DEFINED ENV{ESP_IDF_VERSION}) set(ENABLE_PROGRAMS OFF) add_subdirectory(Libraries/mbedtls) + # SDL + set(SDL_STATIC ON CACHE BOOL "" FORCE) + set(SDL_SHARED OFF CACHE BOOL "" FORCE) + add_subdirectory(Libraries/SDL) # Added as idf component for ESP and as library for other targets + + # LVGL + add_compile_definitions($<$:LV_USE_DRAW_SDL=1>) + add_subdirectory(Libraries/lvgl) # Added as idf component for ESP and as library for other targets + target_link_libraries(lvgl PRIVATE SDL2-static) + # Sim app add_subdirectory(Firmware) # Tests add_subdirectory(Tests) - # SDL - add_compile_definitions($<$:LV_USE_DRAW_SDL=1>) - add_subdirectory(Libraries/SDL) # Added as idf component for ESP and as library for other targets - - # LVGL - add_subdirectory(Libraries/lvgl) # Added as idf component for ESP and as library for other targets - target_link_libraries(lvgl PRIVATE SDL2-static) - endif () diff --git a/Data/system/certificates/WE1.pem b/Data/system/certificates/WE1.pem new file mode 100644 index 00000000..c0ce8f2c --- /dev/null +++ b/Data/system/certificates/WE1.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE----- +MIICnzCCAiWgAwIBAgIQf/MZd5csIkp2FV0TttaF4zAKBggqhkjOPQQDAzBHMQsw +CQYDVQQGEwJVUzEiMCAGA1UEChMZR29vZ2xlIFRydXN0IFNlcnZpY2VzIExMQzEU +MBIGA1UEAxMLR1RTIFJvb3QgUjQwHhcNMjMxMjEzMDkwMDAwWhcNMjkwMjIwMTQw +MDAwWjA7MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVR29vZ2xlIFRydXN0IFNlcnZp +Y2VzMQwwCgYDVQQDEwNXRTEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAARvzTr+ +Z1dHTCEDhUDCR127WEcPQMFcF4XGGTfn1XzthkubgdnXGhOlCgP4mMTG6J7/EFmP +LCaY9eYmJbsPAvpWo4H+MIH7MA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggr +BgEFBQcDAQYIKwYBBQUHAwIwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU +kHeSNWfE/6jMqeZ72YB5e8yT+TgwHwYDVR0jBBgwFoAUgEzW63T/STaj1dj8tT7F +avCUHYwwNAYIKwYBBQUHAQEEKDAmMCQGCCsGAQUFBzAChhhodHRwOi8vaS5wa2ku +Z29vZy9yNC5jcnQwKwYDVR0fBCQwIjAgoB6gHIYaaHR0cDovL2MucGtpLmdvb2cv +ci9yNC5jcmwwEwYDVR0gBAwwCjAIBgZngQwBAgEwCgYIKoZIzj0EAwMDaAAwZQIx +AOcCq1HW90OVznX+0RGU1cxAQXomvtgM8zItPZCuFQ8jSBJSjz5keROv9aYsAm5V +sQIwJonMaAFi54mrfhfoFNZEfuNMSQ6/bIBiNLiyoX46FohQvKeIoJ99cx7sUkFN +7uJW +-----END CERTIFICATE----- diff --git a/Documentation/ideas.md b/Documentation/ideas.md index d1bc80b8..5614d13b 100644 --- a/Documentation/ideas.md +++ b/Documentation/ideas.md @@ -9,6 +9,7 @@ ## Higher Priority - Calculator bugs (see GitHub issue) +- Store last synced timestamp in NVS (see how HTTPS client example app) - External app loading: Check the version of Tactility and check ESP target hardware to check for compatibility Check during installation process, but also when starting (SD card might have old app install from before Tactility OS update) - Make a URL handler. Use it for handling local files. Match file types with apps. diff --git a/Firmware/CMakeLists.txt b/Firmware/CMakeLists.txt index 864bec8a..f791b19f 100644 --- a/Firmware/CMakeLists.txt +++ b/Firmware/CMakeLists.txt @@ -15,8 +15,8 @@ if (DEFINED ENV{ESP_IDF_VERSION}) ) else () - add_executable(AppSim ${SOURCE_FILES}) - target_link_libraries(AppSim + add_executable(FirmwareSim ${SOURCE_FILES}) + target_link_libraries(FirmwareSim PRIVATE Tactility PRIVATE TactilityCore PRIVATE Simulator diff --git a/Libraries/cJSON/CMakeLists.txt b/Libraries/cJSON/CMakeLists.txt new file mode 100644 index 00000000..104bab31 --- /dev/null +++ b/Libraries/cJSON/CMakeLists.txt @@ -0,0 +1,6 @@ +file(GLOB SOURCES "cJSON/*.c") + +add_library(cJSON STATIC) +target_sources(cJSON PRIVATE ${SOURCES}) +include_directories(cJSON "cJSON/") +target_include_directories(cJSON PUBLIC "cJSON/") diff --git a/Libraries/cJSON/README.md b/Libraries/cJSON/README.md new file mode 100644 index 00000000..4e7da5df --- /dev/null +++ b/Libraries/cJSON/README.md @@ -0,0 +1,3 @@ +# cJSON + +This wrapper exists because the original CMake scripts break the builds for Linux and macOS (linker errors) diff --git a/Libraries/cJSON/cJSON b/Libraries/cJSON/cJSON new file mode 160000 index 00000000..acc76239 --- /dev/null +++ b/Libraries/cJSON/cJSON @@ -0,0 +1 @@ +Subproject commit acc76239bee01d8e9c858ae2cab296704e52d916 diff --git a/Tactility/CMakeLists.txt b/Tactility/CMakeLists.txt index b13d9cc9..a1e6e9bb 100644 --- a/Tactility/CMakeLists.txt +++ b/Tactility/CMakeLists.txt @@ -15,8 +15,10 @@ if (DEFINED ENV{ESP_IDF_VERSION}) QRCode esp_http_server esp_http_client + esp-tls esp_lvgl_port esp_wifi + json minitar minmea nvs_flash @@ -68,6 +70,7 @@ else() add_definitions(-D_Nonnull=) target_link_libraries(Tactility + PUBLIC cJSON PUBLIC TactilityCore PUBLIC freertos_kernel PUBLIC lvgl diff --git a/Tactility/Include/Tactility/Preferences.h b/Tactility/Include/Tactility/Preferences.h index b1f778ac..8e5a921d 100644 --- a/Tactility/Include/Tactility/Preferences.h +++ b/Tactility/Include/Tactility/Preferences.h @@ -24,14 +24,17 @@ public: bool hasBool(const std::string& key) const; bool hasInt32(const std::string& key) const; + bool hasInt64(const std::string& key) const; bool hasString(const std::string& key) const; bool optBool(const std::string& key, bool& out) const; bool optInt32(const std::string& key, int32_t& out) const; + bool optInt64(const std::string& key, int64_t& out) const; bool optString(const std::string& key, std::string& out) const; void putBool(const std::string& key, bool value); void putInt32(const std::string& key, int32_t value); + void putInt64(const std::string& key, int64_t value); void putString(const std::string& key, const std::string& value); }; diff --git a/Tactility/Include/Tactility/app/AppRegistration.h b/Tactility/Include/Tactility/app/AppRegistration.h index ec6c122d..9890a016 100644 --- a/Tactility/Include/Tactility/app/AppRegistration.h +++ b/Tactility/Include/Tactility/app/AppRegistration.h @@ -9,18 +9,18 @@ namespace tt::app { struct AppManifest; /** Register an application with its manifest */ -void addApp(const AppManifest& manifest); +void addAppManifest(const AppManifest& manifest); /** Remove an app from the registry */ -bool removeApp(const std::string& id); +bool removeAppManifest(const std::string& id); /** Find an application manifest by its id * @param[in] id the manifest id * @return the application manifest if it was found */ -_Nullable std::shared_ptr findAppById(const std::string& id); +_Nullable std::shared_ptr findAppManifestById(const std::string& id); /** @return a list of all registered apps. This includes user and system apps. */ -std::vector> getApps(); +std::vector> getAppManifests(); } // namespace diff --git a/Tactility/Include/Tactility/app/alertdialog/AlertDialog.h b/Tactility/Include/Tactility/app/alertdialog/AlertDialog.h index 10f38ee8..baac6d43 100644 --- a/Tactility/Include/Tactility/app/alertdialog/AlertDialog.h +++ b/Tactility/Include/Tactility/app/alertdialog/AlertDialog.h @@ -22,6 +22,14 @@ namespace tt::app::alertdialog { * @return the launch id */ LaunchId start(const std::string& title, const std::string& message, const std::vector& buttonLabels); +/** + * Show a dialog with the provided title, message and 0, 1 or more buttons. + * @param[in] title the title to show in the toolbar + * @param[in] message the message to display + * @param[in] buttonLabels the buttons to show + * @return the launch id + */ +LaunchId start(const std::string& title, const std::string& message, const std::vector& buttonLabels); /** * Show a dialog with the provided title, message and an OK button diff --git a/Tactility/Include/Tactility/lvgl/Toolbar.h b/Tactility/Include/Tactility/lvgl/Toolbar.h index 381716f8..503fea19 100644 --- a/Tactility/Include/Tactility/lvgl/Toolbar.h +++ b/Tactility/Include/Tactility/lvgl/Toolbar.h @@ -6,7 +6,6 @@ #include namespace tt::lvgl { - #define TOOLBAR_ACTION_LIMIT 4 /** Create a toolbar widget that shows the app name as title */ @@ -60,4 +59,10 @@ lv_obj_t* toolbar_add_switch_action(lv_obj_t* obj); */ lv_obj_t* toolbar_add_spinner_action(lv_obj_t* obj); +/** + * Remove all actions from the toolbar + * @param[in] obj the toolbar instance + */ +void toolbar_clear_actions(lv_obj_t* obj); + } // namespace diff --git a/Tactility/Include/Tactility/network/EspHttpClient.h b/Tactility/Include/Tactility/network/EspHttpClient.h new file mode 100644 index 00000000..8642ab48 --- /dev/null +++ b/Tactility/Include/Tactility/network/EspHttpClient.h @@ -0,0 +1,104 @@ +#pragma once + +#ifdef ESP_PLATFORM + +#include + +namespace tt::network { + +class EspHttpClient { + + static constexpr auto* TAG = "EspHttpClient"; + + std::unique_ptr config = nullptr; + esp_http_client_handle_t client; + bool isOpen = false; + +public: + + ~EspHttpClient() { + if (isOpen) { + esp_http_client_close(client); + } + + if (client != nullptr) { + esp_http_client_cleanup(client); + } + } + + bool init(std::unique_ptr inConfig) { + TT_LOG_I(TAG, "init(%s)", inConfig->url); + assert(this->config == nullptr); + config = std::move(inConfig); + client = esp_http_client_init(config.get()); + return client != nullptr; + } + + bool open() { + assert(client != nullptr); + TT_LOG_I(TAG, "open()"); + auto result = esp_http_client_open(client, 0); + + if (result != ESP_OK) { + TT_LOG_E(TAG, "open() failed: %s", esp_err_to_name(result)); + return false; + } + + isOpen = true; + return true; + } + + bool fetchHeaders() const { + assert(client != nullptr); + TT_LOG_I(TAG, "fetchHeaders()"); + return esp_http_client_fetch_headers(client) >= 0; + } + + bool isStatusCodeOk() const { + assert(client != nullptr); + const auto status_code = getStatusCode(); + return status_code >= 200 && status_code < 300; + } + + int getStatusCode() const { + assert(client != nullptr); + const auto status_code = esp_http_client_get_status_code(client); + TT_LOG_I(TAG, "Status code %d", status_code); + return status_code; + } + + int getContentLength() const { + assert(client != nullptr); + return esp_http_client_get_content_length(client); + } + + int read(char* bytes, int size) const { + assert(client != nullptr); + TT_LOG_I(TAG, "read(%d)", size); + return esp_http_client_read(client, bytes, size); + } + + int readResponse(char* bytes, int size) const { + assert(client != nullptr); + TT_LOG_I(TAG, "readResponse(%d)", size); + return esp_http_client_read_response(client, bytes, size); + } + + bool close() { + assert(client != nullptr); + TT_LOG_I(TAG, "close()"); + return esp_http_client_close(client) == ESP_OK; + } + + bool cleanup() { + assert(client != nullptr); + TT_LOG_I(TAG, "cleanup()"); + const auto result = esp_http_client_cleanup(client); + client = nullptr; + return result == ESP_OK; + } +}; + +} + +#endif \ No newline at end of file diff --git a/Tactility/Include/Tactility/network/Http.h b/Tactility/Include/Tactility/network/Http.h new file mode 100644 index 00000000..c843f309 --- /dev/null +++ b/Tactility/Include/Tactility/network/Http.h @@ -0,0 +1,15 @@ +#pragma once + +#include + +namespace tt::network::http { + +void download( + const std::string& url, + const std::string& certFilePath, + const std::string &downloadFilePath, + std::function onSuccess, + std::function onError +); + +} diff --git a/Tactility/Include/Tactility/network/Ntp.h b/Tactility/Include/Tactility/network/Ntp.h new file mode 100644 index 00000000..42bc199b --- /dev/null +++ b/Tactility/Include/Tactility/network/Ntp.h @@ -0,0 +1,7 @@ +#pragma once + +namespace tt::network::ntp { + +bool isSynced(); + +} \ No newline at end of file diff --git a/Tactility/Private/Tactility/app/apphub/AppHub.h b/Tactility/Private/Tactility/app/apphub/AppHub.h new file mode 100644 index 00000000..dae8b76e --- /dev/null +++ b/Tactility/Private/Tactility/app/apphub/AppHub.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +namespace tt::app::apphub { + +constexpr auto* CERTIFICATE_PATH = "/system/certificates/WE1.pem"; + +std::string getAppsJsonUrl(); + +std::string getDownloadUrl(const std::string& relativePath); + +} \ No newline at end of file diff --git a/Tactility/Private/Tactility/app/apphub/AppHubEntry.h b/Tactility/Private/Tactility/app/apphub/AppHubEntry.h new file mode 100644 index 00000000..4ec80e1c --- /dev/null +++ b/Tactility/Private/Tactility/app/apphub/AppHubEntry.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include + +namespace tt::app::apphub { + +struct AppHubEntry { + std::string appId; + std::string appVersionName; + int32_t appVersionCode; + std::string appName; + std::string appDescription; + std::string targetSdk; + std::vector targetPlatforms; + std::string file; +}; + +bool parseJson(const std::string& filePath, std::vector& entries); + +} \ No newline at end of file diff --git a/Tactility/Private/Tactility/app/apphubdetails/AppHubDetailsApp.h b/Tactility/Private/Tactility/app/apphubdetails/AppHubDetailsApp.h new file mode 100644 index 00000000..28b8c30c --- /dev/null +++ b/Tactility/Private/Tactility/app/apphubdetails/AppHubDetailsApp.h @@ -0,0 +1,9 @@ +#pragma once + +#include + +namespace tt::app::apphubdetails { + +void start(const apphub::AppHubEntry& entry); + +} // namespace diff --git a/Tactility/Private/Tactility/json/Reader.h b/Tactility/Private/Tactility/json/Reader.h new file mode 100644 index 00000000..deb81f0f --- /dev/null +++ b/Tactility/Private/Tactility/json/Reader.h @@ -0,0 +1,77 @@ +#pragma once + +#include +#include +#include + +namespace tt::json { + +class Reader { + + const cJSON* root; + static constexpr const char* TAG = "json::Reader"; + +public: + + explicit Reader(const cJSON* root) : root(root) {} + + bool readString(const char* key, std::string& output) const { + const auto* child = cJSON_GetObjectItemCaseSensitive(root, key); + if (!cJSON_IsString(child)) { + TT_LOG_E(TAG, "%s is not a string", key); + return false; + } + output = cJSON_GetStringValue(child); + return true; + } + + bool readInt32(const char* key, int32_t& output) const { + double buffer; + if (!readNumber(key, buffer)) { + return false; + } + output = buffer; + return true; + } + + bool readInt(const char* key, int& output) const { + double buffer; + if (!readNumber(key, buffer)) { + return false; + } + output = buffer; + return true; + } + + bool readNumber(const char* key, double& output) const { + const auto* child = cJSON_GetObjectItemCaseSensitive(root, key); + if (!cJSON_IsNumber(child)) { + TT_LOG_E(TAG, "%s is not a string", key); + return false; + } + output = cJSON_GetNumberValue(child); + return true; + } + + bool readStringArray(const char* key, std::vector& output) const { + const auto* child = cJSON_GetObjectItemCaseSensitive(root, key); + if (!cJSON_IsArray(child)) { + TT_LOG_E(TAG, "%s is not an array", key); + return false; + } + const auto size = cJSON_GetArraySize(child); + TT_LOG_I(TAG, "Processing %d array children", size); + output.resize(size); + for (int i = 0; i < size; ++i) { + const auto string_json = cJSON_GetArrayItem(child, i); + if (!cJSON_IsString(string_json)) { + TT_LOG_E(TAG, "array child of %s is not a string", key); + return false; + } + output[i] = cJSON_GetStringValue(string_json); + } + return true; + } +}; + +} \ No newline at end of file diff --git a/Tactility/Source/PreferencesEsp.cpp b/Tactility/Source/PreferencesEsp.cpp index bf75721f..263e952a 100644 --- a/Tactility/Source/PreferencesEsp.cpp +++ b/Tactility/Source/PreferencesEsp.cpp @@ -1,14 +1,14 @@ #ifdef ESP_PLATFORM -#include "nvs_flash.h" -#include "Tactility/Preferences.h" - +#include #include -#define TAG "preferences" +#include namespace tt { +constexpr auto* TAG = "Preferences"; + bool Preferences::optBool(const std::string& key, bool& out) const { nvs_handle_t handle; if (nvs_open(namespace_, NVS_READWRITE, &handle) != ESP_OK) { @@ -37,6 +37,18 @@ bool Preferences::optInt32(const std::string& key, int32_t& out) const { } } +bool Preferences::optInt64(const std::string& key, int64_t& out) const { + nvs_handle_t handle; + if (nvs_open(namespace_, NVS_READWRITE, &handle) != ESP_OK) { + TT_LOG_E(TAG, "Failed to open namespace %s", namespace_); + return false; + } else { + bool success = nvs_get_i64(handle, key.c_str(), &out) == ESP_OK; + nvs_close(handle); + return success; + } +} + bool Preferences::optString(const std::string& key, std::string& out) const { nvs_handle_t handle; if (nvs_open(namespace_, NVS_READWRITE, &handle) != ESP_OK) { @@ -63,6 +75,11 @@ bool Preferences::hasInt32(const std::string& key) const { return optInt32(key, temp); } +bool Preferences::hasInt64(const std::string& key) const { + int64_t temp; + return optInt64(key, temp); +} + bool Preferences::hasString(const std::string& key) const { std::string temp; return optString(key, temp); @@ -92,6 +109,18 @@ void Preferences::putInt32(const std::string& key, int32_t value) { } } +void Preferences::putInt64(const std::string& key, int64_t value) { + nvs_handle_t handle; + if (nvs_open(namespace_, NVS_READWRITE, &handle) == ESP_OK) { + if (nvs_set_i64(handle, key.c_str(), value) != ESP_OK) { + TT_LOG_E(TAG, "Failed to write %s:%s", namespace_, key.c_str()); + } + nvs_close(handle); + } else { + TT_LOG_E(TAG, "Failed to open namespace %s", namespace_); + } +} + void Preferences::putString(const std::string& key, const std::string& text) { nvs_handle_t handle; if (nvs_open(namespace_, NVS_READWRITE, &handle) == ESP_OK) { diff --git a/Tactility/Source/PreferencesMock.cpp b/Tactility/Source/PreferencesMock.cpp index 44b39152..d6536079 100644 --- a/Tactility/Source/PreferencesMock.cpp +++ b/Tactility/Source/PreferencesMock.cpp @@ -30,6 +30,11 @@ bool Preferences::hasInt32(const std::string& key) const { return preferences.hasInt32(bundle_key); } +bool Preferences::hasInt64(const std::string& key) const { + std::string bundle_key = get_bundle_key(namespace_, key); + return preferences.hasInt64(bundle_key); +} + bool Preferences::hasString(const std::string& key) const { std::string bundle_key = get_bundle_key(namespace_, key); return preferences.hasString(bundle_key); @@ -45,6 +50,11 @@ bool Preferences::optInt32(const std::string& key, int32_t& out) const { return preferences.optInt32(bundle_key, out); } +bool Preferences::optInt64(const std::string& key, int64_t& out) const { + std::string bundle_key = get_bundle_key(namespace_, key); + return preferences.optInt64(bundle_key, out); +} + bool Preferences::optString(const std::string& key, std::string& out) const { std::string bundle_key = get_bundle_key(namespace_, key); return preferences.optString(bundle_key, out); @@ -60,6 +70,11 @@ void Preferences::putInt32(const std::string& key, int32_t value) { return preferences.putInt32(bundle_key, value); } +void Preferences::putInt64(const std::string& key, int64_t value) { + std::string bundle_key = get_bundle_key(namespace_, key); + return preferences.putInt64(bundle_key, value); +} + void Preferences::putString(const std::string& key, const std::string& value) { std::string bundle_key = get_bundle_key(namespace_, key); return preferences.putString(bundle_key, value); diff --git a/Tactility/Source/Tactility.cpp b/Tactility/Source/Tactility.cpp index 81e390f0..4734ffd5 100644 --- a/Tactility/Source/Tactility.cpp +++ b/Tactility/Source/Tactility.cpp @@ -56,6 +56,8 @@ namespace service { namespace app { namespace addgps { extern const AppManifest manifest; } + namespace apphub { extern const AppManifest manifest; } + namespace apphubdetails { extern const AppManifest manifest; } namespace alertdialog { extern const AppManifest manifest; } namespace appdetails { extern const AppManifest manifest; } namespace applist { extern const AppManifest manifest; } @@ -99,53 +101,55 @@ namespace app { // List of all apps excluding Boot app (as Boot app calls this function indirectly) static void registerInternalApps() { - addApp(app::alertdialog::manifest); - addApp(app::appdetails::manifest); - addApp(app::applist::manifest); - addApp(app::appsettings::manifest); - addApp(app::display::manifest); - addApp(app::files::manifest); - addApp(app::fileselection::manifest); - addApp(app::imageviewer::manifest); - addApp(app::inputdialog::manifest); - addApp(app::launcher::manifest); - addApp(app::localesettings::manifest); - addApp(app::notes::manifest); - addApp(app::settings::manifest); - addApp(app::selectiondialog::manifest); - addApp(app::systeminfo::manifest); - addApp(app::timedatesettings::manifest); - addApp(app::timezone::manifest); - addApp(app::wifiapsettings::manifest); - addApp(app::wificonnect::manifest); - addApp(app::wifimanage::manifest); + addAppManifest(app::alertdialog::manifest); + addAppManifest(app::appdetails::manifest); + addAppManifest(app::apphub::manifest); + addAppManifest(app::apphubdetails::manifest); + addAppManifest(app::applist::manifest); + addAppManifest(app::appsettings::manifest); + addAppManifest(app::display::manifest); + addAppManifest(app::files::manifest); + addAppManifest(app::fileselection::manifest); + addAppManifest(app::imageviewer::manifest); + addAppManifest(app::inputdialog::manifest); + addAppManifest(app::launcher::manifest); + addAppManifest(app::localesettings::manifest); + addAppManifest(app::notes::manifest); + addAppManifest(app::settings::manifest); + addAppManifest(app::selectiondialog::manifest); + addAppManifest(app::systeminfo::manifest); + addAppManifest(app::timedatesettings::manifest); + addAppManifest(app::timezone::manifest); + addAppManifest(app::wifiapsettings::manifest); + addAppManifest(app::wificonnect::manifest); + addAppManifest(app::wifimanage::manifest); #if defined(CONFIG_TINYUSB_MSC_ENABLED) && CONFIG_TINYUSB_MSC_ENABLED - addApp(app::usbsettings::manifest); + addAppManifest(app::usbsettings::manifest); #endif #if TT_FEATURE_SCREENSHOT_ENABLED - addApp(app::screenshot::manifest); + addAppManifest(app::screenshot::manifest); #endif #ifdef ESP_PLATFORM - addApp(app::chat::manifest); - addApp(app::crashdiagnostics::manifest); - addApp(app::development::manifest); + addAppManifest(app::chat::manifest); + addAppManifest(app::crashdiagnostics::manifest); + addAppManifest(app::development::manifest); #endif if (!hal::getConfiguration()->i2c.empty()) { - addApp(app::i2cscanner::manifest); - addApp(app::i2csettings::manifest); + addAppManifest(app::i2cscanner::manifest); + addAppManifest(app::i2csettings::manifest); } if (!hal::getConfiguration()->uart.empty()) { - addApp(app::addgps::manifest); - addApp(app::gpssettings::manifest); + addAppManifest(app::addgps::manifest); + addAppManifest(app::gpssettings::manifest); } if (hal::hasDevice(hal::Device::Type::Power)) { - addApp(app::power::manifest); + addAppManifest(app::power::manifest); } } @@ -172,7 +176,7 @@ static void registerInstalledApp(std::string path) { manifest.appCategory = app::Category::User; manifest.appLocation = app::Location::external(path); - app::addApp(manifest); + app::addAppManifest(manifest); } static void registerInstalledApps(const std::string& path) { @@ -266,7 +270,7 @@ void run(const Configuration& config) { TT_LOG_I(TAG, "Starting boot app"); // The boot app takes care of registering system apps, user services and user apps - addApp(app::boot::manifest); + addAppManifest(app::boot::manifest); app::start(app::boot::manifest.appId); TT_LOG_I(TAG, "Main dispatcher ready"); diff --git a/Tactility/Source/app/AppInstall.cpp b/Tactility/Source/app/AppInstall.cpp index f6c8220d..8343eae3 100644 --- a/Tactility/Source/app/AppInstall.cpp +++ b/Tactility/Source/app/AppInstall.cpp @@ -188,7 +188,7 @@ bool install(const std::string& path) { manifest.appLocation = Location::external(renamed_target_path); - addApp(manifest); + addAppManifest(manifest); return true; } @@ -211,7 +211,7 @@ bool uninstall(const std::string& appId) { return false; } - if (!removeApp(appId)) { + if (!removeAppManifest(appId)) { TT_LOG_W(TAG, "Failed to remove app %s from registry", appId.c_str()); } diff --git a/Tactility/Source/app/AppRegistration.cpp b/Tactility/Source/app/AppRegistration.cpp index 44baf640..8c6e7bc3 100644 --- a/Tactility/Source/app/AppRegistration.cpp +++ b/Tactility/Source/app/AppRegistration.cpp @@ -15,7 +15,7 @@ typedef std::unordered_map> AppManifes static AppManifestMap app_manifest_map; static Mutex hash_mutex(Mutex::Type::Normal); -void addApp(const AppManifest& manifest) { +void addAppManifest(const AppManifest& manifest) { TT_LOG_I(TAG, "Registering manifest %s", manifest.appId.c_str()); hash_mutex.lock(); @@ -29,7 +29,7 @@ void addApp(const AppManifest& manifest) { hash_mutex.unlock(); } -bool removeApp(const std::string& id) { +bool removeAppManifest(const std::string& id) { TT_LOG_I(TAG, "Removing manifest for %s", id.c_str()); auto lock = hash_mutex.asScopedLock(); @@ -38,7 +38,7 @@ bool removeApp(const std::string& id) { return app_manifest_map.erase(id) == 1; } -_Nullable std::shared_ptr findAppById(const std::string& id) { +_Nullable std::shared_ptr findAppManifestById(const std::string& id) { hash_mutex.lock(); auto result = app_manifest_map.find(id); hash_mutex.unlock(); @@ -49,7 +49,7 @@ _Nullable std::shared_ptr findAppById(const std::string& id) { } } -std::vector> getApps() { +std::vector> getAppManifests() { std::vector> manifests; hash_mutex.lock(); for (const auto& item: app_manifest_map) { diff --git a/Tactility/Source/app/alertdialog/AlertDialog.cpp b/Tactility/Source/app/alertdialog/AlertDialog.cpp index 0e5468d6..27c09f9a 100644 --- a/Tactility/Source/app/alertdialog/AlertDialog.cpp +++ b/Tactility/Source/app/alertdialog/AlertDialog.cpp @@ -31,6 +31,15 @@ LaunchId start(const std::string& title, const std::string& message, const std:: return app::start(manifest.appId, bundle); } +LaunchId start(const std::string& title, const std::string& message, const std::vector& buttonLabels) { + std::string items_joined = string::join(buttonLabels, PARAMETER_ITEM_CONCATENATION_TOKEN); + auto bundle = std::make_shared(); + bundle->putString(PARAMETER_BUNDLE_KEY_TITLE, title); + bundle->putString(PARAMETER_BUNDLE_KEY_MESSAGE, message); + bundle->putString(PARAMETER_BUNDLE_KEY_BUTTON_LABELS, items_joined); + return app::start(manifest.appId, bundle); +} + LaunchId start(const std::string& title, const std::string& message) { auto bundle = std::make_shared(); bundle->putString(PARAMETER_BUNDLE_KEY_TITLE, title); @@ -57,8 +66,6 @@ static std::string getTitleParameter(std::shared_ptr bundle) { class AlertDialogApp : public App { -private: - static void onButtonClickedCallback(lv_event_t* e) { auto app = std::static_pointer_cast(getCurrentApp()); assert(app != nullptr); @@ -66,7 +73,6 @@ private: } void onButtonClicked(lv_event_t* e) { - lv_event_code_t code = lv_event_get_code(e); auto index = reinterpret_cast(lv_event_get_user_data(e)); TT_LOG_I(TAG, "Selected item at index %d", index); diff --git a/Tactility/Source/app/appdetails/AppDetails.cpp b/Tactility/Source/app/appdetails/AppDetails.cpp index 8d40ac12..95fd55f8 100644 --- a/Tactility/Source/app/appdetails/AppDetails.cpp +++ b/Tactility/Source/app/appdetails/AppDetails.cpp @@ -42,7 +42,7 @@ public: const auto parameters = app.getParameters(); tt_check(parameters != nullptr, "Parameters missing"); auto app_id = parameters->getString("appId"); - manifest = findAppById(app_id); + manifest = findAppManifestById(app_id); assert(manifest != nullptr); } diff --git a/Tactility/Source/app/apphub/AppHub.cpp b/Tactility/Source/app/apphub/AppHub.cpp new file mode 100644 index 00000000..82284e48 --- /dev/null +++ b/Tactility/Source/app/apphub/AppHub.cpp @@ -0,0 +1,27 @@ +#include + +#include + +namespace tt::app::apphub { + +constexpr auto* BASE_URL = "https://cdn.tactility.one/apps"; + +static std::string getVersionWithoutPostfix() { + std::string version(TT_VERSION); + auto index = version.find_first_of('-'); + if (index == std::string::npos) { + return version; + } else { + return version.substr(0, index); + } +} + +std::string getAppsJsonUrl() { + return std::format("{}/{}/apps.json", BASE_URL, getVersionWithoutPostfix()); +} + +std::string getDownloadUrl(const std::string& relativePath) { + return std::format("{}/{}/{}", BASE_URL, getVersionWithoutPostfix(), relativePath); +} + +} diff --git a/Tactility/Source/app/apphub/AppHubApp.cpp b/Tactility/Source/app/apphub/AppHubApp.cpp new file mode 100644 index 00000000..4cb0d51f --- /dev/null +++ b/Tactility/Source/app/apphub/AppHubApp.cpp @@ -0,0 +1,186 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace tt::app::apphub { + +constexpr auto* TAG = "AppHub"; + +extern const AppManifest manifest; + +class AppHubApp final : public App { + + lv_obj_t* contentWrapper = nullptr; + lv_obj_t* refreshButton = nullptr; + std::string cachedAppsJsonFile = std::format("{}/app_hub.json", getTempPath()); + std::unique_ptr thread; + std::vector entries; + Mutex mutex; + + static std::shared_ptr _Nullable findAppInstance() { + auto app_context = getCurrentAppContext(); + if (app_context->getManifest().appId != manifest.appId) { + return nullptr; + } + return std::static_pointer_cast(app_context->getApp()); + } + + static void onAppPressed(lv_event_t* e) { + const auto* self = static_cast(lv_event_get_user_data(e)); + auto* widget = lv_event_get_target_obj(e); + const auto* user_data = lv_obj_get_user_data(widget); +#ifdef ESP_PLATFORM + const int index = reinterpret_cast(user_data); +#else + const long long index = reinterpret_cast(user_data); +#endif + self->mutex.lock(); + if (index < self->entries.size()) { + apphubdetails::start(self->entries[index]); + } + self->mutex.unlock(); + } + + static void onRefreshPressed(lv_event_t* e) { + auto* self = static_cast(lv_event_get_user_data(e)); + self->refresh(); + } + + void onRefreshSuccess() { + TT_LOG_I(TAG, "Request success"); + auto lock = lvgl::getSyncLock()->asScopedLock(); + lock.lock(); + + showApps(); + } + + void onRefreshError(const char* error) { + TT_LOG_E(TAG, "Request failed: %s", error); + auto lock = lvgl::getSyncLock()->asScopedLock(); + lock.lock(); + + showRefreshFailedError("Cannot reach server"); + } + + static void createAppWidget(const std::shared_ptr& manifest, lv_obj_t* list) { + lv_obj_t* btn = lv_list_add_button(list, nullptr, manifest->appName.c_str()); + lv_obj_add_event_cb(btn, &onAppPressed, LV_EVENT_SHORT_CLICKED, manifest.get()); + } + + void showRefreshFailedError(const char* message) { + lv_obj_clean(contentWrapper); + + auto* label = lv_label_create(contentWrapper); + lv_label_set_text(label, message); + lv_obj_align(label, LV_ALIGN_CENTER, 0, 0); + + lv_obj_remove_flag(refreshButton, LV_OBJ_FLAG_HIDDEN); + } + + void showNoInternet() { + showRefreshFailedError("No Internet Connection"); + } + + void showTimeNotSynced() { + showRefreshFailedError("Time is not synced yet.\nIt's required to establish a secure connection."); + } + + void showApps() { + lv_obj_clean(contentWrapper); + mutex.lock(); + if (parseJson(cachedAppsJsonFile, entries)) { + std::ranges::sort(entries, [](auto left, auto right) { + return left.appName < right.appName; + }); + + auto* list = lv_list_create(contentWrapper); + lv_obj_set_style_pad_all(list, 0, LV_STATE_DEFAULT); + lv_obj_set_size(list, LV_PCT(100), LV_SIZE_CONTENT); + for (int i = 0; i < entries.size(); i++) { + auto& entry = entries[i]; + TT_LOG_I(TAG, "Adding %s", entry.appName.c_str()); + const char* icon = findAppManifestById(entry.appId) != nullptr ? LV_SYMBOL_OK : nullptr; + auto* entry_button = lv_list_add_button(list, icon, entry.appName.c_str()); + lv_obj_set_user_data(entry_button, reinterpret_cast(i)); + lv_obj_add_event_cb(entry_button, onAppPressed, LV_EVENT_SHORT_CLICKED, this); + } + } else { + showRefreshFailedError("Failed to load content"); + } + mutex.unlock(); + } + + void refresh() { + lv_obj_clean(contentWrapper); + auto* spinner = lvgl::spinner_create(contentWrapper); + lv_obj_align(spinner, LV_ALIGN_CENTER, 0, 0); + + lv_obj_add_flag(refreshButton, LV_OBJ_FLAG_HIDDEN); + + if (service::wifi::getRadioState() != service::wifi::RadioState::ConnectionActive) { + showNoInternet(); + return; + } + + if (file::isFile(cachedAppsJsonFile)) { + showApps(); + } + + network::http::download( + getAppsJsonUrl(), + CERTIFICATE_PATH, + cachedAppsJsonFile, + [] { + auto app = findAppInstance(); + if (app != nullptr) { + app->onRefreshSuccess(); + } + }, + [](const char* error) { + auto app = findAppInstance(); + if (app != nullptr) { + app->onRefreshError(error); + } + } + ); + } + +public: + + void onShow(TT_UNUSED AppContext& app, lv_obj_t* parent) override { + lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN); + lv_obj_set_style_pad_row(parent, 0, LV_STATE_DEFAULT); + + auto* toolbar = lvgl::toolbar_create(parent, app); + refreshButton = lvgl::toolbar_add_image_button_action(toolbar, LV_SYMBOL_REFRESH, onRefreshPressed, this); + lv_obj_add_flag(refreshButton, LV_OBJ_FLAG_HIDDEN); + + contentWrapper = lv_obj_create(parent); + lv_obj_set_width(contentWrapper, LV_PCT(100)); + lv_obj_set_flex_grow(contentWrapper, 1); + lv_obj_set_style_pad_all(contentWrapper, 0, LV_STATE_DEFAULT); + lv_obj_set_style_pad_ver(contentWrapper, 0, LV_STATE_DEFAULT); + + refresh(); + } +}; + +extern const AppManifest manifest = { + .appId = "AppHub", + .appName = "App Hub", + .appCategory = Category::System, + .createApp = create, +}; + +} // namespace diff --git a/Tactility/Source/app/apphub/AppHubEntry.cpp b/Tactility/Source/app/apphub/AppHubEntry.cpp new file mode 100644 index 00000000..d0459462 --- /dev/null +++ b/Tactility/Source/app/apphub/AppHubEntry.cpp @@ -0,0 +1,56 @@ +#include +#include +#include + +namespace tt::app::apphub { + +constexpr auto* TAG = "AppHubJson"; + +static bool parseEntry(const cJSON* object, AppHubEntry& entry) { + const json::Reader reader(object); + return reader.readString("appId", entry.appId) && + reader.readString("appVersionName", entry.appVersionName) && + reader.readInt32("appVersionCode", entry.appVersionCode) && + reader.readString("appName", entry.appName) && + reader.readString("appDescription", entry.appDescription) && + reader.readString("targetSdk", entry.targetSdk) && + reader.readString("file", entry.file) && + reader.readStringArray("targetPlatforms", entry.targetPlatforms); +} + +bool parseJson(const std::string& filePath, std::vector& entries) { + auto lock = file::getLock(filePath)->asScopedLock(); + lock.lock(); + + auto data = file::readString(filePath); + auto data_ptr = reinterpret_cast(data.get()); + auto* json = cJSON_Parse(data_ptr); + if (json == nullptr) { + TT_LOG_E(TAG, "Failed to parse %s", filePath.c_str()); + return false; + } + + const cJSON* apps_json = cJSON_GetObjectItemCaseSensitive(json, "apps"); + if (!cJSON_IsArray(apps_json)) { + cJSON_Delete(json); + TT_LOG_E(TAG, "apps is not an array"); + return false; + } + + auto apps_size = cJSON_GetArraySize(apps_json); + entries.resize(apps_size); + for (int i = 0; i < apps_size; ++i) { + auto& entry = entries.at(i); + auto* entry_json = cJSON_GetArrayItem(apps_json, i); + if (!parseEntry(entry_json, entry)) { + TT_LOG_E(TAG, "Failed to read entry"); + cJSON_Delete(json); + return false; + } + } + + cJSON_Delete(json); + return true; +} + +} diff --git a/Tactility/Source/app/apphubdetails/AppHubDetailsApp.cpp b/Tactility/Source/app/apphubdetails/AppHubDetailsApp.cpp new file mode 100644 index 00000000..1bde0a75 --- /dev/null +++ b/Tactility/Source/app/apphubdetails/AppHubDetailsApp.cpp @@ -0,0 +1,248 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +namespace tt::app::apphubdetails { + +extern const AppManifest manifest; +constexpr auto* TAG = "AppHubDetails"; + +static std::shared_ptr toBundle(const apphub::AppHubEntry& entry) { + auto bundle = std::make_shared(); + bundle->putString("appId", entry.appId); + bundle->putString("appVersionName", entry.appVersionName); + bundle->putInt32("appVersionCode", entry.appVersionCode); + bundle->putString("appName", entry.appName); + bundle->putString("appDescription", entry.appDescription); + bundle->putString("targetSdk", entry.targetSdk); + bundle->putString("file", entry.file); + bundle->putString("targetPlatforms", string::join(entry.targetPlatforms, ",")); + return bundle; +} + +static bool fromBundle(const Bundle& bundle, apphub::AppHubEntry& entry) { + std::string target_platforms_string; + auto result = bundle.optString("appId", entry.appId) && + bundle.optString("appVersionName", entry.appVersionName) && + bundle.optInt32("appVersionCode", entry.appVersionCode) && + bundle.optString("appName", entry.appName) && + bundle.optString("appDescription", entry.appDescription) && + bundle.optString("targetSdk", entry.targetSdk) && + bundle.optString("file", entry.file) && + bundle.optString("targetPlatforms", target_platforms_string); + entry.targetPlatforms = string::split(target_platforms_string, ","); + return result; +} + +class AppHubDetailsApp final : public App { + + static constexpr auto* CONFIRM_TEXT = "Confirm"; + static constexpr auto* CANCEL_TEXT = "Cancel"; + static constexpr auto CONFIRMATION_BUTTON_INDEX = 0; + const std::vector CONFIRM_CANCEL_LABELS = { CONFIRM_TEXT, CANCEL_TEXT }; + + apphub::AppHubEntry entry; + std::shared_ptr entryManifest; + lv_obj_t* toolbar = nullptr; + lv_obj_t* spinner = nullptr; + lv_obj_t* updateButton = nullptr; + lv_obj_t* updateLabel = nullptr; + LaunchId installLaunchId = -1; + LaunchId uninstallLaunchId = -1; + LaunchId updateLaunchId = -1; + + LaunchId showConfirmDialog(const char* action) { + const auto message = std::format("{} {}?", action, entry.appName); + return alertdialog::start(CONFIRM_TEXT, message, CONFIRM_CANCEL_LABELS); + } + + static void onInstallPressed(lv_event_t* e) { + auto* self = static_cast(lv_event_get_user_data(e)); + self->installLaunchId = self->showConfirmDialog("Install"); + } + + static void onUninstallPressed(lv_event_t* e) { + auto* self = static_cast(lv_event_get_user_data(e)); + self->uninstallLaunchId = self->showConfirmDialog("Uninstall"); + } + + static void onUpdatePressed(lv_event_t* e) { + auto* self = static_cast(lv_event_get_user_data(e)); + self->updateLaunchId = self->showConfirmDialog("Update"); + } + + void uninstallApp() { + TT_LOG_I(TAG, "Uninstall"); + + lvgl::getSyncLock()->lock(); + lv_obj_remove_flag(spinner, LV_OBJ_FLAG_HIDDEN); + lvgl::getSyncLock()->unlock(); + + uninstall(entry.appId); + + lvgl::getSyncLock()->lock(); + updateViews(); + lvgl::getSyncLock()->unlock(); + } + + void doInstall() { + auto url = apphub::getDownloadUrl(entry.file); + auto file_name = file::getLastPathSegment(entry.file); + auto temp_file_path = std::format("{}/{}", getTempPath(), file_name); + network::http::download( + url, + apphub::CERTIFICATE_PATH, + temp_file_path, + [this, temp_file_path] { + install(temp_file_path); + + if (!file::deleteFile(temp_file_path.c_str())) { + TT_LOG_W(TAG, "Failed to remove %s", temp_file_path.c_str()); + } else { + TT_LOG_I(TAG, "Deleted temporary file %s", temp_file_path.c_str()); + } + + lvgl::getSyncLock()->lock(); + updateViews(); + lvgl::getSyncLock()->unlock(); + }, + [temp_file_path](const char* errorMessage) { + TT_LOG_E(TAG, "Download failed: %s", errorMessage); + alertdialog::start("Error", "Failed to install app"); + + if (file::isFile(temp_file_path) && !file::deleteFile(temp_file_path.c_str())) { + TT_LOG_W(TAG, "Failed to remove %s", temp_file_path.c_str()); + } + } + ); + } + + void installApp() { + TT_LOG_I(TAG, "Install"); + + lvgl::getSyncLock()->lock(); + lv_obj_remove_flag(spinner, LV_OBJ_FLAG_HIDDEN); + lvgl::getSyncLock()->unlock(); + + doInstall(); + } + + void updateApp() { + TT_LOG_I(TAG, "Update"); + + lvgl::getSyncLock()->lock(); + lv_obj_remove_flag(spinner, LV_OBJ_FLAG_HIDDEN); + lvgl::getSyncLock()->unlock(); + + TT_LOG_I(TAG, "Removing previous version"); + uninstall(entry.appId); + TT_LOG_I(TAG, "Installing new version"); + doInstall(); + } + + void updateViews() { + lvgl::toolbar_clear_actions(toolbar); + const auto manifest = findAppManifestById(entry.appId); + spinner = lvgl::toolbar_add_spinner_action(toolbar); + lv_obj_add_flag(spinner, LV_OBJ_FLAG_HIDDEN); + lv_obj_add_flag(updateLabel, LV_OBJ_FLAG_HIDDEN); + if (manifest != nullptr) { + if (manifest->appVersionCode < entry.appVersionCode) { + updateButton = lvgl::toolbar_add_image_button_action(toolbar, LV_SYMBOL_DOWNLOAD, onUpdatePressed, this); + lv_obj_remove_flag(updateLabel, LV_OBJ_FLAG_HIDDEN); + } + lvgl::toolbar_add_image_button_action(toolbar, LV_SYMBOL_TRASH, onUninstallPressed, this); + } else { + lvgl::toolbar_add_image_button_action(toolbar, LV_SYMBOL_DOWNLOAD, onInstallPressed, this); + } + } + +public: + + void onCreate(AppContext& appContext) override { + auto parameters = appContext.getParameters(); + if (parameters == nullptr) { + TT_LOG_E(TAG, "No parameters"); + stop(); + return; + } + + if (!fromBundle(*parameters.get(), entry)) { + TT_LOG_E(TAG, "Invalid parameters"); + stop(); + } + } + + void onShow(TT_UNUSED AppContext& app, lv_obj_t* parent) override { + lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_COLUMN); + lv_obj_set_style_pad_row(parent, 0, LV_STATE_DEFAULT); + + toolbar = lvgl::toolbar_create(parent, entry.appName.c_str()); + auto* wrapper = lv_obj_create(parent); + lv_obj_set_width(wrapper, LV_PCT(100)); + lv_obj_set_flex_grow(wrapper, 1); + lv_obj_set_flex_flow(wrapper, LV_FLEX_FLOW_COLUMN); + + updateLabel = lv_label_create(wrapper); + lv_label_set_text(updateLabel, "Update available!"); + lv_obj_set_style_text_color(updateLabel, lv_color_make(0xff, 0xff, 00), LV_STATE_DEFAULT); + + auto* description_label = lv_label_create(wrapper); + lv_obj_set_width(description_label, LV_PCT(100)); + lv_label_set_long_mode(description_label, LV_LABEL_LONG_MODE_WRAP); + if (!entry.appDescription.empty()) { + lv_label_set_text(description_label, entry.appDescription.c_str()); + } else { + lv_label_set_text(description_label, "This app has no description yet."); + } + + auto* version_label = lv_label_create(wrapper); + lv_label_set_text_fmt(version_label, "Version %s", entry.appVersionName.c_str()); + + updateViews(); + } + + void onResult(AppContext& appContext, LaunchId launchId, Result result, std::unique_ptr resultData) override { + if (result != Result::Ok) { + return; + } + + if (alertdialog::getResultIndex(*resultData.get()) != CONFIRMATION_BUTTON_INDEX) { + return; + } + + if (launchId == installLaunchId) { + installApp(); + } else if (launchId == uninstallLaunchId) { + uninstallApp(); + } else if (launchId == updateLaunchId) { + updateApp(); + } + } +}; + +void start(const apphub::AppHubEntry& entry) { + const auto bundle = toBundle(entry); + app::start(manifest.appId, bundle); +} + +extern const AppManifest manifest = { + .appId = "AppHubDetails", + .appName = "App Details", + .appCategory = Category::System, + .appFlags = AppManifest::Flags::Hidden, + .createApp = create, +}; + +} // namespace diff --git a/Tactility/Source/app/applist/AppList.cpp b/Tactility/Source/app/applist/AppList.cpp index db700ae6..89dd6d77 100644 --- a/Tactility/Source/app/applist/AppList.cpp +++ b/Tactility/Source/app/applist/AppList.cpp @@ -36,7 +36,7 @@ public: auto parent_content_height = lv_obj_get_content_height(parent); lv_obj_set_height(list, parent_content_height - toolbar_height); - auto manifests = getApps(); + auto manifests = getAppManifests(); std::ranges::sort(manifests, SortAppManifestByName); for (const auto& manifest: manifests) { diff --git a/Tactility/Source/app/appsettings/AppSettings.cpp b/Tactility/Source/app/appsettings/AppSettings.cpp index ba8e1411..b0268378 100644 --- a/Tactility/Source/app/appsettings/AppSettings.cpp +++ b/Tactility/Source/app/appsettings/AppSettings.cpp @@ -37,7 +37,7 @@ public: auto parent_content_height = lv_obj_get_content_height(parent); lv_obj_set_height(list, parent_content_height - toolbar_height); - auto manifests = getApps(); + auto manifests = getAppManifests(); std::ranges::sort(manifests, SortAppManifestByName); size_t app_count = 0; diff --git a/Tactility/Source/app/files/View.cpp b/Tactility/Source/app/files/View.cpp index 31da848a..1387882f 100644 --- a/Tactility/Source/app/files/View.cpp +++ b/Tactility/Source/app/files/View.cpp @@ -92,7 +92,8 @@ void View::viewFile(const std::string& path, const std::string& filename) { // install(filename); auto message = std::format("Do you want to install {}?", filename); installAppPath = processed_filepath; - installAppLaunchId = alertdialog::start("Install?", message, { "Yes", "No" }); + auto choices = std::vector { "Yes", "No" }; + installAppLaunchId = alertdialog::start("Install?", message, choices); #endif } else if (isSupportedImageFile(filename)) { imageviewer::start(processed_filepath); diff --git a/Tactility/Source/app/settings/Settings.cpp b/Tactility/Source/app/settings/Settings.cpp index 13d21974..190bde12 100644 --- a/Tactility/Source/app/settings/Settings.cpp +++ b/Tactility/Source/app/settings/Settings.cpp @@ -35,7 +35,7 @@ class SettingsApp final : public App { lv_obj_set_width(list, LV_PCT(100)); lv_obj_set_flex_grow(list, 1); - auto manifests = getApps(); + auto manifests = getAppManifests(); std::ranges::sort(manifests, SortAppManifestByName); for (const auto& manifest: manifests) { if (manifest->appCategory == Category::Settings) { diff --git a/Tactility/Source/lvgl/Toolbar.cpp b/Tactility/Source/lvgl/Toolbar.cpp index 5047a9a5..7fe758b3 100644 --- a/Tactility/Source/lvgl/Toolbar.cpp +++ b/Tactility/Source/lvgl/Toolbar.cpp @@ -220,4 +220,9 @@ lv_obj_t* toolbar_add_spinner_action(lv_obj_t* obj) { return spinner; } +void toolbar_clear_actions(lv_obj_t* obj) { + auto* toolbar = reinterpret_cast(obj); + lv_obj_clean(toolbar->action_container); +} + } // namespace diff --git a/Tactility/Source/network/Http.cpp b/Tactility/Source/network/Http.cpp new file mode 100644 index 00000000..ae4bde3c --- /dev/null +++ b/Tactility/Source/network/Http.cpp @@ -0,0 +1,102 @@ +#include +#include +#include + +#ifdef ESP_PLATFORM +#include +#include +#include +#endif + +namespace tt::network::http { + +constexpr auto* TAG = "HTTP"; + +void download( + const std::string& url, + const std::string& certFilePath, + const std::string &downloadFilePath, + std::function onSuccess, + std::function onError +) { + TT_LOG_I(TAG, "Downloading %s to %s", url.c_str(), downloadFilePath.c_str()); +#ifdef ESP_PLATFORM + getMainDispatcher().dispatch([url, certFilePath, downloadFilePath, onSuccess, onError] { + TT_LOG_I(TAG, "Loading certificate"); + auto certificate = file::readString(certFilePath); + auto certificate_length = strlen(reinterpret_cast(certificate.get())) + 1; + + auto config = std::make_unique(esp_http_client_config_t { + .url = url.c_str(), + .auth_type = HTTP_AUTH_TYPE_NONE, + .cert_pem = reinterpret_cast(certificate.get()), + .cert_len = certificate_length, + .tls_version = ESP_HTTP_CLIENT_TLS_VER_TLS_1_3, + .method = HTTP_METHOD_GET, + .timeout_ms = 5000, + .transport_type = HTTP_TRANSPORT_OVER_SSL + }); + + auto client = std::make_unique(); + if (!client->init(std::move(config))) { + onError("Failed to initialize client"); + return -1; + } + + if (!client->open()) { + onError("Failed to open connection"); + return -1; + } + + if (!client->fetchHeaders()) { + onError("Failed to get request headers"); + return -1; + } + + if (!client->isStatusCodeOk()) { + onError("Server response is not OK"); + return -1; + } + + auto bytes_left = client->getContentLength(); + + auto lock = file::getLock(downloadFilePath)->asScopedLock(); + lock.lock(); + auto file_exists = file::isFile(downloadFilePath); + auto* file_mode = file_exists ? "r+" : "w"; + TT_LOG_I(TAG, "opening %s with mode %s", downloadFilePath.c_str(), file_mode); + auto* file = fopen(downloadFilePath.c_str(), file_mode); + if (file == nullptr) { + onError("Failed to open file"); + return -1; + } + + TT_LOG_I(TAG, "Writing %d bytes to %s", bytes_left, downloadFilePath.c_str()); + char buffer[512]; + while (bytes_left > 0) { + int data_read = client->read(buffer, 512); + if (data_read <= 0) { + fclose(file); + onError("Failed to read data"); + return -1; + } + bytes_left -= data_read; + if (fwrite(buffer, 1, data_read, file) != data_read) { + fclose(file); + onError("Failed to write all bytes"); + return -1; + } + } + fclose(file); + TT_LOG_I(TAG, "Downloaded %s to %s", url.c_str(), downloadFilePath.c_str()); + onSuccess(); + return 0; + }); +#else + getMainDispatcher().dispatch([onError] { + onError("Not implemented"); + }); +#endif +} + +} diff --git a/Tactility/Source/network/HttpServer.cpp b/Tactility/Source/network/HttpServer.cpp index 756aa408..65b2a164 100644 --- a/Tactility/Source/network/HttpServer.cpp +++ b/Tactility/Source/network/HttpServer.cpp @@ -14,7 +14,7 @@ bool HttpServer::startInternal() { config.uri_match_fn = matchUri; if (httpd_start(&server, &config) != ESP_OK) { - TT_LOG_E(TAG, "Failed to start http server on port %d", port); + TT_LOG_E(TAG, "Failed to start http server on port %lu", port); return false; } diff --git a/Tactility/Source/network/HttpdReq.cpp b/Tactility/Source/network/HttpdReq.cpp index 3dccd58b..08200f9c 100644 --- a/Tactility/Source/network/HttpdReq.cpp +++ b/Tactility/Source/network/HttpdReq.cpp @@ -1,11 +1,11 @@ #include +#include +#include +#include #include #include #include -#include -#include -#include #ifdef ESP_PLATFORM diff --git a/Tactility/Source/network/Ntp.cpp b/Tactility/Source/network/Ntp.cpp index 4c6fb107..940564e9 100644 --- a/Tactility/Source/network/Ntp.cpp +++ b/Tactility/Source/network/Ntp.cpp @@ -1,4 +1,5 @@ -#include "Tactility/network/NtpPrivate.h" +#include +#include #ifdef ESP_PLATFORM #include @@ -7,19 +8,43 @@ #include #endif -#define TAG "ntp" - namespace tt::network::ntp { +constexpr auto* TAG = "NTP"; +static bool processedSyncEvent = false; + #ifdef ESP_PLATFORM -static void onTimeSynced(struct timeval* tv) { +void storeTimeInNvs() { + time_t now; + time(&now); + + auto preferences = std::make_unique("time"); + preferences->putInt64("syncTime", now); + TT_LOG_I(TAG, "Stored time %llu", now); +} + +void setTimeFromNvs() { + auto preferences = std::make_unique("time"); + time_t synced_time; + if (preferences->optInt64("syncTime", synced_time)) { + TT_LOG_I(TAG, "Restoring last known time to %llu", synced_time); + timeval get_nvs_time; + get_nvs_time.tv_sec = synced_time; + settimeofday(&get_nvs_time, nullptr); + } +} + +static void onTimeSynced(timeval* tv) { TT_LOG_I(TAG, "Time synced (%llu)", tv->tv_sec); + processedSyncEvent = true; + esp_netif_sntp_deinit(); + storeTimeInNvs(); kernel::publishSystemEvent(kernel::SystemEvent::Time); } void init() { - esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG("pool.ntp.org"); + esp_sntp_config_t config = ESP_NETIF_SNTP_DEFAULT_CONFIG("time.cloudflare.com"); config.sync_cb = onTimeSynced; esp_netif_sntp_init(&config); } @@ -27,8 +52,13 @@ void init() { #else void init() { + processedSyncEvent = true; } #endif +bool isSynced() { + return processedSyncEvent; +} + } diff --git a/Tactility/Source/service/development/DevelopmentService.cpp b/Tactility/Source/service/development/DevelopmentService.cpp index c4c23625..04a4cf12 100644 --- a/Tactility/Source/service/development/DevelopmentService.cpp +++ b/Tactility/Source/service/development/DevelopmentService.cpp @@ -209,7 +209,7 @@ esp_err_t DevelopmentService::handleAppUninstall(httpd_req_t* request) { return ESP_FAIL; } - if (!app::findAppById(id_key_pos->second)) { + if (!app::findAppManifestById(id_key_pos->second)) { TT_LOG_I(TAG, "[200] /app/uninstall %s (app wasn't installed)", id_key_pos->second.c_str()); httpd_resp_send(request, nullptr, 0); return ESP_OK; diff --git a/Tactility/Source/service/loader/Loader.cpp b/Tactility/Source/service/loader/Loader.cpp index 2471a949..bca45bc2 100644 --- a/Tactility/Source/service/loader/Loader.cpp +++ b/Tactility/Source/service/loader/Loader.cpp @@ -43,7 +43,7 @@ static const char* appStateToString(app::State state) { void LoaderService::onStartAppMessage(const std::string& id, app::LaunchId launchId, std::shared_ptr parameters) { TT_LOG_I(TAG, "Start by id %s", id.c_str()); - auto app_manifest = app::findAppById(id); + auto app_manifest = app::findAppManifestById(id); if (app_manifest == nullptr) { TT_LOG_E(TAG, "App not found: %s", id.c_str()); return; diff --git a/TactilityC/Include/tt_lvgl_toolbar.h b/TactilityC/Include/tt_lvgl_toolbar.h index 700b4d4a..b681fcd1 100644 --- a/TactilityC/Include/tt_lvgl_toolbar.h +++ b/TactilityC/Include/tt_lvgl_toolbar.h @@ -60,6 +60,13 @@ lv_obj_t* tt_lvgl_toolbar_add_switch_action(lv_obj_t* obj); */ lv_obj_t* tt_lvgl_toolbar_add_spinner_action(lv_obj_t* obj); + +/** + * Remove all actions from the toolbar + * @param[in] obj the toolbar instance + */ +void tt_lvgl_toolbar_clear_actions(lv_obj_t* obj); + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/TactilityC/Source/tt_init.cpp b/TactilityC/Source/tt_init.cpp index 3e301b2a..37ba4a81 100644 --- a/TactilityC/Source/tt_init.cpp +++ b/TactilityC/Source/tt_init.cpp @@ -276,6 +276,7 @@ const esp_elfsym main_symbols[] { ESP_ELFSYM_EXPORT(tt_lvgl_toolbar_add_text_button_action), ESP_ELFSYM_EXPORT(tt_lvgl_toolbar_add_switch_action), ESP_ELFSYM_EXPORT(tt_lvgl_toolbar_add_spinner_action), + ESP_ELFSYM_EXPORT(tt_lvgl_toolbar_clear_actions), ESP_ELFSYM_EXPORT(tt_message_queue_alloc), ESP_ELFSYM_EXPORT(tt_message_queue_free), ESP_ELFSYM_EXPORT(tt_message_queue_put), diff --git a/TactilityC/Source/tt_lvgl_toolbar.cpp b/TactilityC/Source/tt_lvgl_toolbar.cpp index 7c004929..36c3a678 100644 --- a/TactilityC/Source/tt_lvgl_toolbar.cpp +++ b/TactilityC/Source/tt_lvgl_toolbar.cpp @@ -35,4 +35,8 @@ lv_obj_t* tt_lvgl_toolbar_add_spinner_action(lv_obj_t* obj) { return tt::lvgl::toolbar_add_spinner_action(obj); } +void tt_lvgl_toolbar_clear_actions(lv_obj_t* obj) { + tt::lvgl::toolbar_clear_actions(obj); +} + } diff --git a/TactilityCore/Include/Tactility/Bundle.h b/TactilityCore/Include/Tactility/Bundle.h index 9b5c70bf..030e65ae 100644 --- a/TactilityCore/Include/Tactility/Bundle.h +++ b/TactilityCore/Include/Tactility/Bundle.h @@ -20,6 +20,7 @@ class Bundle final { enum class Type { Bool, Int32, + Int64, String, }; @@ -28,6 +29,7 @@ class Bundle final { union { bool value_bool; int32_t value_int32; + int64_t value_int64; }; std::string value_string; } Value; @@ -44,18 +46,22 @@ public: bool getBool(const std::string& key) const; int32_t getInt32(const std::string& key) const; + int64_t getInt64(const std::string& key) const; std::string getString(const std::string& key) const; bool hasBool(const std::string& key) const; bool hasInt32(const std::string& key) const; + bool hasInt64(const std::string& key) const; bool hasString(const std::string& key) const; bool optBool(const std::string& key, bool& out) const; bool optInt32(const std::string& key, int32_t& out) const; + bool optInt64(const std::string& key, int64_t& out) const; bool optString(const std::string& key, std::string& out) const; void putBool(const std::string& key, bool value); void putInt32(const std::string& key, int32_t value); + void putInt64(const std::string& key, int64_t value); void putString(const std::string& key, const std::string& value); }; diff --git a/TactilityCore/Include/Tactility/StringUtils.h b/TactilityCore/Include/Tactility/StringUtils.h index 5ad0713a..e248d655 100644 --- a/TactilityCore/Include/Tactility/StringUtils.h +++ b/TactilityCore/Include/Tactility/StringUtils.h @@ -51,6 +51,16 @@ void split(const std::string& input, const std::string& delimiter, std::function */ std::string join(const std::vector& input, const std::string& delimiter); +/** + * Join a set of tokens into a single string, given a delimiter (separator). + * If the input is an empty list, the result will be an empty string. + * The delimeter is only placed inbetween tokens and not appended at the end of the resulting string. + * + * @param input the tokens to join together + * @param delimiter the separator to join with + */ +std::string join(const std::vector& input, const std::string& delimiter); + /** * Returns the lowercase value of a string. * @warning This only works for strings with 1 byte per character diff --git a/TactilityCore/Include/Tactility/file/File.h b/TactilityCore/Include/Tactility/file/File.h index a2b45002..5e6b2054 100644 --- a/TactilityCore/Include/Tactility/file/File.h +++ b/TactilityCore/Include/Tactility/file/File.h @@ -99,8 +99,18 @@ bool deleteDirectory(const std::string& path); */ std::string getChildPath(const std::string& basePath, const std::string& childPath); +/** + * Find the last part of the path. This can either be the filename or the deepest folder name. + * @param path an absolute or relative path + * @return the last segment of the specified path + */ std::string getLastPathSegment(const std::string& path); +/** + * Find the first part of the path. This is either the root folder, or a file if the latter has no parent folder. + * @param path an absolute or relative path + * @return the first segment of the specified path + */ std::string getFirstPathSegment(const std::string& path); typedef int (*ScandirFilter)(const dirent*); diff --git a/TactilityCore/Source/Bundle.cpp b/TactilityCore/Source/Bundle.cpp index 8e78f8c2..e0819ba6 100644 --- a/TactilityCore/Source/Bundle.cpp +++ b/TactilityCore/Source/Bundle.cpp @@ -10,6 +10,10 @@ int32_t Bundle::getInt32(const std::string& key) const { return this->entries.find(key)->second.value_int32; } +int64_t Bundle::getInt64(const std::string& key) const { + return this->entries.find(key)->second.value_int64; +} + std::string Bundle::getString(const std::string& key) const { return this->entries.find(key)->second.value_string; } @@ -24,6 +28,11 @@ bool Bundle::hasInt32(const std::string& key) const { return entry != std::end(this->entries) && entry->second.type == Type::Int32; } +bool Bundle::hasInt64(const std::string& key) const { + auto entry = this->entries.find(key); + return entry != std::end(this->entries) && entry->second.type == Type::Int64; +} + bool Bundle::hasString(const std::string& key) const { auto entry = this->entries.find(key); return entry != std::end(this->entries) && entry->second.type == Type::String; @@ -49,6 +58,16 @@ bool Bundle::optInt32(const std::string& key, int32_t& out) const { } } +bool Bundle::optInt64(const std::string& key, int64_t& out) const { + auto entry = this->entries.find(key); + if (entry != std::end(this->entries) && entry->second.type == Type::Int64) { + out = entry->second.value_int32; + return true; + } else { + return false; + } +} + bool Bundle::optString(const std::string& key, std::string& out) const { auto entry = this->entries.find(key); if (entry != std::end(this->entries) && entry->second.type == Type::String) { @@ -75,6 +94,14 @@ void Bundle::putInt32(const std::string& key, int32_t value) { }; } +void Bundle::putInt64(const std::string& key, int64_t value) { + this->entries[key] = { + .type = Type::Int64, + .value_int64 = value, + .value_string = "" + }; +} + void Bundle::putString(const std::string& key, const std::string& value) { this->entries[key] = { .type = Type::String, diff --git a/TactilityCore/Source/StringUtils.cpp b/TactilityCore/Source/StringUtils.cpp index 43afa563..ff0b7924 100644 --- a/TactilityCore/Source/StringUtils.cpp +++ b/TactilityCore/Source/StringUtils.cpp @@ -54,6 +54,28 @@ std::vector split(const std::string&input, const std::string&delimi return result; } +std::string join(const std::vector& input, const std::string& delimiter) { + std::stringstream stream; + size_t size = input.size(); + + if (size == 0) { + return ""; + } else if (size == 1) { + return input.front(); + } else { + auto iterator = input.begin(); + while (iterator != input.end()) { + stream << *iterator; + iterator++; + if (iterator != input.end()) { + stream << delimiter; + } + } + } + + return stream.str(); +} + std::string join(const std::vector& input, const std::string& delimiter) { std::stringstream stream; size_t size = input.size(); diff --git a/TactilityCore/Source/file/File.cpp b/TactilityCore/Source/file/File.cpp index 6af278c6..d9a78def 100644 --- a/TactilityCore/Source/file/File.cpp +++ b/TactilityCore/Source/file/File.cpp @@ -247,7 +247,7 @@ std::string getLastPathSegment(const std::string& path) { if (index != std::string::npos) { return path.substr(index + 1); } else { - return ""; + return path; } } diff --git a/sdkconfig.board.cyd-2432s024c b/sdkconfig.board.cyd-2432s024c index fae7a74d..e1057d56 100644 --- a/sdkconfig.board.cyd-2432s024c +++ b/sdkconfig.board.cyd-2432s024c @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.cyd-2432s028r b/sdkconfig.board.cyd-2432s028r index 8dbf2574..d52e6608 100644 --- a/sdkconfig.board.cyd-2432s028r +++ b/sdkconfig.board.cyd-2432s028r @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.cyd-2432s032c b/sdkconfig.board.cyd-2432s032c index feb9b267..a8ef668d 100644 --- a/sdkconfig.board.cyd-2432s032c +++ b/sdkconfig.board.cyd-2432s032c @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.cyd-4848s040c b/sdkconfig.board.cyd-4848s040c index 79063dd5..280bc2bc 100644 --- a/sdkconfig.board.cyd-4848s040c +++ b/sdkconfig.board.cyd-4848s040c @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.cyd-8048s043c b/sdkconfig.board.cyd-8048s043c index c83b50bc..d33a8142 100644 --- a/sdkconfig.board.cyd-8048s043c +++ b/sdkconfig.board.cyd-8048s043c @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.cyd-e32r28t b/sdkconfig.board.cyd-e32r28t index 5d617bf0..91bf7b84 100644 --- a/sdkconfig.board.cyd-e32r28t +++ b/sdkconfig.board.cyd-e32r28t @@ -1,5 +1,6 @@ # Software defaults CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y diff --git a/sdkconfig.board.cyd-jc2432w328c b/sdkconfig.board.cyd-jc2432w328c index 8668e85a..607d35e9 100644 --- a/sdkconfig.board.cyd-jc2432w328c +++ b/sdkconfig.board.cyd-jc2432w328c @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.cyd-jc8048w550c b/sdkconfig.board.cyd-jc8048w550c index c80d9aad..21433033 100644 --- a/sdkconfig.board.cyd-jc8048w550c +++ b/sdkconfig.board.cyd-jc8048w550c @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.elecrow-crowpanel-advance-28 b/sdkconfig.board.elecrow-crowpanel-advance-28 index 9d3a8d6c..7f5b8f9c 100644 --- a/sdkconfig.board.elecrow-crowpanel-advance-28 +++ b/sdkconfig.board.elecrow-crowpanel-advance-28 @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.elecrow-crowpanel-advance-35 b/sdkconfig.board.elecrow-crowpanel-advance-35 index 333f6f03..38d5149e 100644 --- a/sdkconfig.board.elecrow-crowpanel-advance-35 +++ b/sdkconfig.board.elecrow-crowpanel-advance-35 @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.elecrow-crowpanel-advance-50 b/sdkconfig.board.elecrow-crowpanel-advance-50 index 1a5455f1..d2d0fd68 100644 --- a/sdkconfig.board.elecrow-crowpanel-advance-50 +++ b/sdkconfig.board.elecrow-crowpanel-advance-50 @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.elecrow-crowpanel-basic-28 b/sdkconfig.board.elecrow-crowpanel-basic-28 index 113f3fa6..45a621e0 100644 --- a/sdkconfig.board.elecrow-crowpanel-basic-28 +++ b/sdkconfig.board.elecrow-crowpanel-basic-28 @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.elecrow-crowpanel-basic-35 b/sdkconfig.board.elecrow-crowpanel-basic-35 index e21a8d84..d80f269e 100644 --- a/sdkconfig.board.elecrow-crowpanel-basic-35 +++ b/sdkconfig.board.elecrow-crowpanel-basic-35 @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.elecrow-crowpanel-basic-50 b/sdkconfig.board.elecrow-crowpanel-basic-50 index 1ba98de3..c8778c92 100644 --- a/sdkconfig.board.elecrow-crowpanel-basic-50 +++ b/sdkconfig.board.elecrow-crowpanel-basic-50 @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.lilygo-tdeck b/sdkconfig.board.lilygo-tdeck index 2b2f8341..7ba20445 100644 --- a/sdkconfig.board.lilygo-tdeck +++ b/sdkconfig.board.lilygo-tdeck @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y @@ -56,4 +58,4 @@ CONFIG_LV_DISP_DEF_REFR_PERIOD=10 CONFIG_LV_THEME_DEFAULT_DARK=y # USB CONFIG_TINYUSB_MSC_ENABLED=y -CONFIG_TINYUSB_MSC_MOUNT_PATH="/sdcard" \ No newline at end of file +CONFIG_TINYUSB_MSC_MOUNT_PATH="/sdcard" diff --git a/sdkconfig.board.lilygo-tdeck.dev b/sdkconfig.board.lilygo-tdeck.dev index 6f9d8072..dd0af3c2 100644 --- a/sdkconfig.board.lilygo-tdeck.dev +++ b/sdkconfig.board.lilygo-tdeck.dev @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.lilygo-tdongle-s3 b/sdkconfig.board.lilygo-tdongle-s3 index 0eb4843d..db110d98 100644 --- a/sdkconfig.board.lilygo-tdongle-s3 +++ b/sdkconfig.board.lilygo-tdongle-s3 @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.lilygo-tlora-pager b/sdkconfig.board.lilygo-tlora-pager index 64bbd456..fa8ed338 100644 --- a/sdkconfig.board.lilygo-tlora-pager +++ b/sdkconfig.board.lilygo-tlora-pager @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.m5stack-cardputer b/sdkconfig.board.m5stack-cardputer index 4ff29671..979335f1 100644 --- a/sdkconfig.board.m5stack-cardputer +++ b/sdkconfig.board.m5stack-cardputer @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.m5stack-core2 b/sdkconfig.board.m5stack-core2 index 14930da0..9cb8e0de 100644 --- a/sdkconfig.board.m5stack-core2 +++ b/sdkconfig.board.m5stack-core2 @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.m5stack-cores3 b/sdkconfig.board.m5stack-cores3 index b7231c96..7ebdaf9c 100644 --- a/sdkconfig.board.m5stack-cores3 +++ b/sdkconfig.board.m5stack-cores3 @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.m5stack-stickc-plus b/sdkconfig.board.m5stack-stickc-plus index 0384c380..c549db85 100644 --- a/sdkconfig.board.m5stack-stickc-plus +++ b/sdkconfig.board.m5stack-stickc-plus @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.m5stack-stickc-plus2 b/sdkconfig.board.m5stack-stickc-plus2 index 9f7bbb16..b8eb2782 100644 --- a/sdkconfig.board.m5stack-stickc-plus2 +++ b/sdkconfig.board.m5stack-stickc-plus2 @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.unphone b/sdkconfig.board.unphone index 5cbf94f9..43b62561 100644 --- a/sdkconfig.board.unphone +++ b/sdkconfig.board.unphone @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.waveshare-s3-lcd-13 b/sdkconfig.board.waveshare-s3-lcd-13 index d2e964e6..86b0fa6e 100644 --- a/sdkconfig.board.waveshare-s3-lcd-13 +++ b/sdkconfig.board.waveshare-s3-lcd-13 @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.waveshare-s3-touch-43 b/sdkconfig.board.waveshare-s3-touch-43 index 87e34b4a..8bb518f6 100644 --- a/sdkconfig.board.waveshare-s3-touch-43 +++ b/sdkconfig.board.waveshare-s3-touch-43 @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.waveshare-s3-touch-lcd-128 b/sdkconfig.board.waveshare-s3-touch-lcd-128 index fa2382c9..de9535bd 100644 --- a/sdkconfig.board.waveshare-s3-touch-lcd-128 +++ b/sdkconfig.board.waveshare-s3-touch-lcd-128 @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.board.waveshare-s3-touch-lcd-147 b/sdkconfig.board.waveshare-s3-touch-lcd-147 index 2c656a84..90a6873e 100644 --- a/sdkconfig.board.waveshare-s3-touch-lcd-147 +++ b/sdkconfig.board.waveshare-s3-touch-lcd-147 @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware: Main CONFIG_PARTITION_TABLE_CUSTOM=y diff --git a/sdkconfig.defaults b/sdkconfig.defaults index 2376e1d1..63eb6841 100644 --- a/sdkconfig.defaults +++ b/sdkconfig.defaults @@ -1,6 +1,7 @@ # Software defaults # Increase stack size for WiFi (fixes crash after scan) CONFIG_ESP_SYSTEM_EVENT_TASK_STACK_SIZE=3072 +CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120 CONFIG_LV_FONT_MONTSERRAT_14=y CONFIG_LV_FONT_MONTSERRAT_18=y CONFIG_LV_USE_USER_DATA=y @@ -28,6 +29,7 @@ CONFIG_WL_SECTOR_SIZE_512=y CONFIG_WL_SECTOR_SIZE=512 CONFIG_WL_SECTOR_MODE_SAFE=y CONFIG_WL_SECTOR_MODE=1 +CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y # Hardware defaults CONFIG_PARTITION_TABLE_CUSTOM=y