21#include "storage/FatFsStorageManager.h"
40 TRACE(
"SD mount appears successful, but directory listing failed — treating as mount failure\n");
50 TRACE(
"SD card mounted successfully\n");
67 TRACE(
"[FatFs] Checking if path exists: %s\n", path.c_str());
70 printf(
"[FatFs] SD card not mounted — cannot check path exists: %s\n", path.c_str());
78 int err = ff_stat(
resolvePath(path).c_str(), &xStat);
79 TRACE(
"[FatFs] ff_stat returned: %d\n", err);
80 if (err == FF_ERR_NONE){
81 TRACE(
"[FatFs] Path exists: %s, size: %ld bytes\n",
resolvePath(path).c_str(), xStat.st_size);
84 TRACE(
"Path does not exist: %s\n", path.c_str());
92 TRACE(
"SD card not mounted — cannot list directory: %s\n", path.c_str());
95 TRACE(
"[FatFs] Listing directory: %s\n", path.c_str());
96 FF_FindData_t xFindStruct{};
97 std::string searchPath =
resolvePath(path.empty() ?
"/" : path);
98 TRACE(
"[FatFs] Search path: %s\n", searchPath.c_str());
99 int result = ff_findfirst(searchPath.c_str(), &xFindStruct);
101 if (result != FF_ERR_NONE) {
102 printf(
"[FatFs] ff_findfirst failed with error: %d\n", result);
107 if (xFindStruct.pcFileName && strlen(xFindStruct.pcFileName) > 0) {
109 info.
name = xFindStruct.pcFileName;
110 info.
isDirectory = xFindStruct.ucAttributes & FF_FAT_ATTR_DIR;
111 info.
isReadOnly = xFindStruct.ucAttributes & FF_FAT_ATTR_READONLY;
112 info.
size =
static_cast<size_t>(xFindStruct.ulFileSize);
115 }
while (ff_findnext(&xFindStruct) == FF_ERR_NONE);
124 TRACE(
"SD card not mounted — cannot create directory: %s\n", path.c_str());
127 TRACE(
"[FatFs] Creating directory: %s\n", path.c_str());
128 return ff_mkdir(
resolvePath(path).c_str()) == FF_ERR_NONE;
135 TRACE(
"SD card not mounted — cannot remove directory: %s\n", path.c_str());
138 return ff_rmdir(
resolvePath(path).c_str()) == FF_ERR_NONE;
146 TRACE(
"SD card not mounted — cannot read file: %s\n", path.c_str());
149 FF_FILE *file = ff_fopen(
resolvePath(path).c_str(),
"r");
153 ff_fseek(file, 0, SEEK_END);
154 long fileSize = ff_ftell(file);
155 ff_fseek(file, 0, SEEK_SET);
163 buffer.resize(fileSize);
164 ff_fread(buffer.data(), 1, fileSize, file);
174 TRACE(
"SD card not mounted — cannot write to file: %s\n", path.c_str());
177 FF_FILE *file = ff_fopen(
resolvePath(path).c_str(),
"w");
181 ff_fwrite(data.data(), 1, data.size(), file);
190 TRACE(
"SD card not mounted — cannot write to file: %s\n", path.c_str());
194 FF_FILE* file = ff_fopen(
resolvePath(path).c_str(),
"w");
198 size_t written = ff_fwrite(data, 1, size, file);
201 return (written == size);
209 TRACE(
"SD card not mounted — cannot remove file: %s\n", path.c_str());
212 return ff_remove(
resolvePath(path).c_str()) == FF_ERR_NONE;
220 TRACE(
"SD card not mounted — cannot rename file %s to file: %s\n", from.c_str(), to.c_str());
231 TRACE(
"SD card not mounted — cannot stream file: %s\n", path.c_str());
234 FF_FILE *file = ff_fopen(
resolvePath(path).c_str(),
"r");
240 while ((bytes = ff_fread(buffer, 1,
sizeof(buffer), file)) > 0)
242 chunkCallback(buffer, bytes);
254 TRACE(
"SD card not mounted — cannot get file size: %s\n", path.c_str());
257 FF_FILE *file = ff_fopen(
resolvePath(path).c_str(),
"r");
261 ff_fseek(file, 0, SEEK_END);
262 long size = ff_ftell(file);
265 return (size >= 0) ?
static_cast<size_t>(size) : 0;
273 TRACE(
"SD card not mounted — cannot append to file: %s\n", path.c_str());
276 FF_FILE *file = ff_fopen(
resolvePath(path).c_str(),
"a");
280 size_t written = ff_fwrite(data, 1, size, file);
282 return written == size;
297 std::string normalized;
298 bool lastWasSlash =
false;
299 for (
char c : fullPath)
312 lastWasSlash =
false;
337 TRACE(
"SD no longer accessible — marking as unmounted\n");
344 FF_FindData_t xFindStruct = {};
346 int result = ff_findfirst(root.c_str(), &xFindStruct);
347 return result == FF_ERR_NONE;
353 printf(
"[FatFs] Cannot format: card not mounted\n");
358 printf(
"[FatFs] Format failed for device: %s\n",
mountPoint.c_str());
362 printf(
"[FatFs] Format successful for device: %s\n",
mountPoint.c_str());
375 TRACE(
"SD card not mounted — cannot read file string: %s\n", path.c_str());
379 FF_FILE *file = ff_fopen(
resolvePath(path).c_str(),
"r");
382 TRACE(
"Failed to open file: %s\n", path.c_str());
386 ff_fseek(file, 0, SEEK_END);
387 size_t fileSize = ff_ftell(file);
388 if (startPosition >= fileSize)
395 size_t readLength = std::min<size_t>(length, fileSize - startPosition);
396 ff_fseek(file, startPosition, SEEK_SET);
398 buffer.resize(readLength);
399 size_t bytesRead = ff_fread(buffer.data(), 1, readLength, file);
402 if (bytesRead != readLength)
404 buffer.resize(bytesRead);
405 TRACE(
"Read only %zu bytes from file: %s\n", bytesRead, path.c_str());
417 auto reader = std::make_unique<FatFsFileReader>();
418 if (!reader->open(
resolvePath(path)))
return nullptr;
Macro-based debug trace system with optional SD file logging.
#define TRACE_INIT(MODULE_NAME)
Declare trace usage in a source file for a given module.
#define TRACE(...)
Default trace (INFO level).
Concrete implementation of StorageManager using FatFs.
bool rename(const std::string &from, const std::string &to) override
Rename a file or directory.
bool exists(const std::string &path) override
Check if the path exists.
bool formatStorage() override
Format the storage device.
bool unmount() override
Unmount the filesystem.
FatFsStorageManager()
Construct a new FatFsStorageManager object.
bool mount() override
Mount the filesystem at the specified mount point.
bool createDirectory(const std::string &path) override
Create a directory at the specified path.
bool writeFile(const std::string &path, const std::vector< uint8_t > &data) override
Write a memory buffer to a file.
bool mounted
Indicates if the filesystem is currently mounted.
bool readFileString(const std::string &path, uint32_t startPosition, uint32_t length, std::string &buffer)
Read a file string into a std::string.
bool streamFile(const std::string &path, std::function< void(const uint8_t *, size_t)> chunkCallback) override
Stream a file in chunks via callback.
std::string mountPoint
Default mount point.
size_t getFileSize(const std::string &path) override
Get the size of a file.
bool appendToFile(const std::string &path, const uint8_t *data, size_t size) override
Append data to a file.
bool removeDirectory(const std::string &path) override
Remove a directory at the specified path.
bool listDirectory(const std::string &path, std::vector< FileInfo > &out) override
List the contents of a directory.
std::string resolvePath(const std::string &path) const
Helper function to normalize full path based on mountPoint and relative path.
bool isMounted() const override
Check if the filesystem is currently mounted.
bool readFile(const std::string &path, std::vector< uint8_t > &buffer) override
Read a file into a memory buffer.
bool remove(const std::string &path) override
Remove a file or directory at the specified path.
std::unique_ptr< StorageFileReader > openReader(const std::string &path) override
open a file for streaming read access.
Delegates to user or system configuration.
#define HTTP_BUFFER_SIZE
Size of the HTTP buffer for request/response data.
Structure representing metadata for a file or directory.
bool isDirectory
True if item is a directory.
size_t size
Size in bytes.
bool isReadOnly
True if item is read-only.
std::string name
File or directory name.