App hub and more (#383)

- Added `AppHub` app
- Added `AppHubDetails` app
- Added `cJSON` dependency
- Renamed `AppSim` module to `FirmwareSim`
- Added extra `tt::app::alertdialg::start()`
- Renamed `addApp()`, `removeApp()`, `findAppById()` and `getApps()` to `addAppManifest()`, `removeAppManifest()`, `findAppManifestById()` and `getAppManifests()`
- Added `tt::lvgl::toolbar_clear_actions()`
- Added `tt::network::EspHttpClient` as a thread-safe wrapper around `esp_http_client`
- Added `tt::network::http::download()` to download files
- Added `tt::network::ntp::isSynced()`
- When time is synced, the timestamp is stored in NVS flash. On boot, it is restored. This helps SSL connections when doing a quick reset: when WiFi reconnects, the user doesn't have to wait for NTP sync before SSL works.
- Added `tt::json::Reader` as a `cJSON` wrapper
- Added `int64_t` support for `Preferences`
- Added `int64_t` support for `Bundle`
- Added dependencies: `cJSON`, `esp-tls`
- When time is synced via NTP, disable time sync.
- Added docs to 'tt::file::` functions
- Added `tt::string::join()` that works with `std::vector<const char*>`
- Fixed `tt::file::getLastPathSegment()` for the scenario when a path was passed with only a single segment
- Set `CONFIG_ESP_MAIN_TASK_STACK_SIZE=5120` (from about 3k) for all boards
- Set `CONFIG_MBEDTLS_SSL_PROTO_TLS1_3=y` for all boards
This commit is contained in:
Ken Van Hoeylandt
2025-10-25 00:20:48 +02:00
committed by GitHub
parent e9384e0c11
commit f660550f86
82 changed files with 1237 additions and 82 deletions
@@ -0,0 +1,13 @@
#pragma once
#include <string>
namespace tt::app::apphub {
constexpr auto* CERTIFICATE_PATH = "/system/certificates/WE1.pem";
std::string getAppsJsonUrl();
std::string getDownloadUrl(const std::string& relativePath);
}
@@ -0,0 +1,21 @@
#pragma once
#include <string>
#include <vector>
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<std::string> targetPlatforms;
std::string file;
};
bool parseJson(const std::string& filePath, std::vector<AppHubEntry>& entries);
}
@@ -0,0 +1,9 @@
#pragma once
#include <Tactility/app/apphub/AppHubEntry.h>
namespace tt::app::apphubdetails {
void start(const apphub::AppHubEntry& entry);
} // namespace
+77
View File
@@ -0,0 +1,77 @@
#pragma once
#include <cJSON.h>
#include <string>
#include <vector>
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<std::string>& 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;
}
};
}