diff --git a/idf_zacus/components/game_endpoint/CMakeLists.txt b/idf_zacus/components/game_endpoint/CMakeLists.txt index dd44449..7b95817 100644 --- a/idf_zacus/components/game_endpoint/CMakeLists.txt +++ b/idf_zacus/components/game_endpoint/CMakeLists.txt @@ -16,6 +16,7 @@ idf_component_register( joltwallet__littlefs puzzle_state media_manager + sd_storage PRIV_REQUIRES local_puzzles ) diff --git a/idf_zacus/components/game_endpoint/game_endpoint.c b/idf_zacus/components/game_endpoint/game_endpoint.c index a3657bb..85b4e6e 100644 --- a/idf_zacus/components/game_endpoint/game_endpoint.c +++ b/idf_zacus/components/game_endpoint/game_endpoint.c @@ -19,6 +19,7 @@ #include "esp_littlefs.h" #include "esp_log.h" #include "media_manager.h" +#include "sd_storage.h" #include "esp_system.h" #include "freertos/FreeRTOS.h" #include "freertos/task.h" @@ -1001,22 +1002,36 @@ static esp_err_t handle_file_post(httpd_req_t *req) { sizeof(path_param)) != ESP_OK) { return send_error(req, "400 Bad Request", "missing path param"); } - if (strncmp(path_param, "apps/", 5) != 0 || strstr(path_param, "..") || + // Route: apps/<…> → /littlefs/apps/<…> (display shell tiles, ≤256 KiB); + // sd/<…> → /sdcard/<…> (P4 large assets: audio, images). + const bool to_sd = (strncmp(path_param, "sd/", 3) == 0); + const bool to_apps = (strncmp(path_param, "apps/", 5) == 0); + if ((!to_sd && !to_apps) || strstr(path_param, "..") || path_param[strlen(path_param) - 1] == '/') { - return send_error(req, "403 Forbidden", "path must be under apps/"); + return send_error(req, "403 Forbidden", "path must be under apps/ or sd/"); } - if (req->content_len <= 0 || - req->content_len > GAME_ENDPOINT_MAX_FILE_BYTES) { - return send_error(req, "400 Bad Request", "size 1..262144 bytes"); - } - if (mount_storage_lazy() != ESP_OK) { - return send_error(req, "503 Service Unavailable", "storage_unavailable"); + const long max_bytes = to_sd ? (8L * 1024 * 1024) : GAME_ENDPOINT_MAX_FILE_BYTES; + if (req->content_len <= 0 || (long) req->content_len > max_bytes) { + return send_error(req, "400 Bad Request", "file too large"); } - char full[160]; - snprintf(full, sizeof(full), "/littlefs/%s", path_param); + char full[192]; + size_t root_len; + if (to_sd) { + if (!sd_storage_ready()) { + return send_error(req, "503 Service Unavailable", "sd_not_mounted"); + } + snprintf(full, sizeof(full), "/sdcard/%s", path_param + 3); // strip "sd/" + root_len = strlen("/sdcard/"); + } else { + if (mount_storage_lazy() != ESP_OK) { + return send_error(req, "503 Service Unavailable", "storage_unavailable"); + } + snprintf(full, sizeof(full), "/littlefs/%s", path_param); + root_len = strlen("/littlefs/"); + } // mkdir -p for intermediate directories. - for (char *p = full + strlen("/littlefs/"); *p; p++) { + for (char *p = full + root_len; *p; p++) { if (*p == '/') { *p = '\0'; mkdir(full, 0775); // EEXIST is fine diff --git a/idf_zacus/components/media_manager/media_manager.c b/idf_zacus/components/media_manager/media_manager.c index 057b56b..5c2b426 100644 --- a/idf_zacus/components/media_manager/media_manager.c +++ b/idf_zacus/components/media_manager/media_manager.c @@ -158,10 +158,20 @@ static void resolve_play_path(char *out, size_t out_len, const char *path) { return; } if (path[0] == '/') { - copy_text(out, out_len, path); - } else { - snprintf(out, out_len, "%s/%s", s_media.config.music_dir, path); + copy_text(out, out_len, path); // absolute: /sdcard/... or /littlefs/... + return; } + // Relative cue: prefer the microSD copy when present (P4 — large asset + // store), else fall back to the LittleFS music_dir. file_exists() returns + // false when no card is mounted, so this is transparent without a hard + // dependency on sd_storage. + char sd_try[MEDIA_PATH_MAX]; + snprintf(sd_try, sizeof(sd_try), "/sdcard/music/%s", path); + if (file_exists(sd_try)) { + copy_text(out, out_len, sd_try); + return; + } + snprintf(out, out_len, "%s/%s", s_media.config.music_dir, path); } static void sanitize_filename(char *out, size_t out_len, diff --git a/idf_zacus/components/sd_storage/sd_storage.h b/idf_zacus/components/sd_storage/sd_storage.h index 8ba2ade..f474f06 100644 --- a/idf_zacus/components/sd_storage/sd_storage.h +++ b/idf_zacus/components/sd_storage/sd_storage.h @@ -8,6 +8,7 @@ #pragma once #include +#include #include "esp_err.h" #ifdef __cplusplus