App Hub improvements

This commit is contained in:
Ken Van Hoeylandt 2026-10-15 21:20:50 +02:00
parent 6f3e76ea36
commit 6515cd6b09
5 changed files with 44 additions and 6 deletions

View File

@ -10,3 +10,8 @@ tactility_add_module(app-hub-module
INCLUDE_DIRS include/
REQUIRES TactilityKernel TactilityKernelCpp app-module service-module http-module cjson-module
)
if (NOT DEFINED ENV{ESP_IDF_VERSION})
# Matches the app binary folder name of app-posix-module, e.g. "posix-x86_64"
target_compile_definitions(app-hub-module PRIVATE "TACTILITY_POSIX_ARCH=\"${CMAKE_SYSTEM_PROCESSOR}\"")
endif ()

View File

@ -7,7 +7,6 @@
#include <string>
#include <vector>
constexpr auto* APP_HUB_CERTIFICATE_PATH = "/system/certificates/WE1.pem";
struct AppHubCatalogEntry {
std::string id;
@ -30,9 +29,15 @@ using AppHubCatalog = std::vector<AppHubCatalogEntry, tt::OptExternalAllocator<A
/** Parse an apps.json file */
bool app_hub_catalog_parse(const char* path, AppHubCatalog& catalog);
/** @return the platform name of this device in the catalog's target platforms, e.g. "esp32s3" or "posix-x86_64" */
const char* app_hub_catalog_get_platform();
/** @return true when this device can install and run the entry's app (target platform, device and RAM requirements) */
bool app_hub_catalog_is_compatible(const AppHubCatalogEntry& entry);
/** @return the path of the certificate that verifies the catalog server, in the "system" file system, or an empty string when it isn't available */
std::string app_hub_catalog_get_certificate_path();
std::string app_hub_catalog_get_url();
std::string app_hub_catalog_get_download_url(const std::string& file);

View File

@ -3,7 +3,9 @@
#include <app/package_manifest.h>
#include <tactility/filesystem/file_system.h>
#include <tactility/log.h>
#include <tactility/paths.h>
#include <cJSON.h>
@ -27,6 +29,16 @@ static std::string get_version_without_postfix() {
return (index == std::string::npos) ? version : version.substr(0, index);
}
std::string app_hub_catalog_get_certificate_path() {
// The system file system is mounted at "/system" on ESP32, but it's a folder elsewhere on the simulator
FileSystem* system = file_system_find_by_name("system");
char path[FILE_MAX_PATH_STRING_LENGTH];
if (system == nullptr || file_system_get_path(system, path, sizeof(path)) != ERROR_NONE) {
return "";
}
return std::string(path) + "/certificates/WE1.pem";
}
std::string app_hub_catalog_get_url() {
return std::format("{}/{}/apps.json", BASE_URL, get_version_without_postfix());
}
@ -149,14 +161,21 @@ bool app_hub_catalog_parse(const char* path, AppHubCatalog& catalog) {
return true;
}
bool app_hub_catalog_is_compatible(const AppHubCatalogEntry& entry) {
// The simulator isn't a real MCU target, so it has no platform to match against
const char* app_hub_catalog_get_platform() {
#ifdef ESP_PLATFORM
return CONFIG_IDF_TARGET;
#else
// Same name as the folder of the app binary that the POSIX app loader looks for
return "posix-" TACTILITY_POSIX_ARCH;
#endif
}
bool app_hub_catalog_is_compatible(const AppHubCatalogEntry& entry) {
// An empty list means that the app supports every platform
if (!entry.target_platforms.empty() &&
std::ranges::find(entry.target_platforms, std::string_view(CONFIG_IDF_TARGET)) == entry.target_platforms.end()) {
std::ranges::find(entry.target_platforms, std::string_view(app_hub_catalog_get_platform())) == entry.target_platforms.end()) {
return false;
}
#endif
// Same device and RAM rules as for installed packages
PackageManifest package {};

View File

@ -278,7 +278,7 @@ error_t download(const char* url, const char* targetPath) {
if (http_download_subscribe(&sub, &workerEvents) != ERROR_NONE) {
return ERROR_RESOURCE;
}
if (http_download_start(url, APP_HUB_CERTIFICATE_PATH, targetPath, &sub) != ERROR_NONE) {
if (http_download_start(url, app_hub_catalog_get_certificate_path().c_str(), targetPath, &sub) != ERROR_NONE) {
http_download_unsubscribe(&sub);
return ERROR_RESOURCE;
}

View File

@ -75,3 +75,12 @@ TEST_CASE("app hub: isCompatible applies the device and RAM requirements") {
CHECK_FALSE(app_hub_catalog_is_compatible(entryWith({ "other-device" }, 0)));
CHECK_FALSE(app_hub_catalog_is_compatible(entryWith({}, 256)));
}
TEST_CASE("app hub: isCompatible requires this device's platform when the app lists platforms") {
auto entry = entryWith({}, 0);
CHECK(app_hub_catalog_is_compatible(entry));
entry.target_platforms = { "some-other-platform" };
CHECK_FALSE(app_hub_catalog_is_compatible(entry));
entry.target_platforms = { "some-other-platform", app_hub_catalog_get_platform() };
CHECK(app_hub_catalog_is_compatible(entry));
}