Add exFAT support (#150)

## Summary

* Swap to updated SDCardManager which uses SdFat
* Add exFAT support
  * Swap to using FsFile everywhere
* Use newly exposed `SdMan` macro to get to static instance of
SDCardManager
* Move a bunch of FsHelpers up to SDCardManager
This commit is contained in:
Dave Allie
2025-12-30 15:09:30 +10:00
committed by GitHub
parent d4bd119950
commit fb5fc32c5d
50 changed files with 289 additions and 355 deletions

View File

@@ -2,7 +2,7 @@
#include <ArduinoJson.h>
#include <FsHelpers.h>
#include <SD.h>
#include <SDCardManager.h>
#include <WiFi.h>
#include <algorithm>
@@ -170,7 +170,7 @@ void CrossPointWebServer::handleStatus() const {
}
void CrossPointWebServer::scanFiles(const char* path, const std::function<void(FileInfo)>& callback) const {
File root = SD.open(path);
FsFile root = SdMan.open(path);
if (!root) {
Serial.printf("[%lu] [WEB] Failed to open directory: %s\n", millis(), path);
return;
@@ -184,9 +184,11 @@ void CrossPointWebServer::scanFiles(const char* path, const std::function<void(F
Serial.printf("[%lu] [WEB] Scanning files in: %s\n", millis(), path);
File file = root.openNextFile();
FsFile file = root.openNextFile();
char name[128];
while (file) {
auto fileName = String(file.name());
file.getName(name, sizeof(name));
auto fileName = String(name);
// Skip hidden items (starting with ".")
bool shouldHide = fileName.startsWith(".");
@@ -279,7 +281,7 @@ void CrossPointWebServer::handleFileListData() const {
}
// Static variables for upload handling
static File uploadFile;
static FsFile uploadFile;
static String uploadFileName;
static String uploadPath = "/";
static size_t uploadSize = 0;
@@ -334,13 +336,13 @@ void CrossPointWebServer::handleUpload() const {
filePath += uploadFileName;
// Check if file already exists
if (SD.exists(filePath.c_str())) {
if (SdMan.exists(filePath.c_str())) {
Serial.printf("[%lu] [WEB] [UPLOAD] Overwriting existing file: %s\n", millis(), filePath.c_str());
SD.remove(filePath.c_str());
SdMan.remove(filePath.c_str());
}
// Open file for writing
if (!FsHelpers::openFileForWrite("WEB", filePath, uploadFile)) {
if (!SdMan.openFileForWrite("WEB", filePath, uploadFile)) {
uploadError = "Failed to create file on SD card";
Serial.printf("[%lu] [WEB] [UPLOAD] FAILED to create file: %s\n", millis(), filePath.c_str());
return;
@@ -393,7 +395,7 @@ void CrossPointWebServer::handleUpload() const {
String filePath = uploadPath;
if (!filePath.endsWith("/")) filePath += "/";
filePath += uploadFileName;
SD.remove(filePath.c_str());
SdMan.remove(filePath.c_str());
}
uploadError = "Upload aborted";
Serial.printf("[%lu] [WEB] Upload aborted\n", millis());
@@ -444,13 +446,13 @@ void CrossPointWebServer::handleCreateFolder() const {
Serial.printf("[%lu] [WEB] Creating folder: %s\n", millis(), folderPath.c_str());
// Check if already exists
if (SD.exists(folderPath.c_str())) {
if (SdMan.exists(folderPath.c_str())) {
server->send(400, "text/plain", "Folder already exists");
return;
}
// Create the folder
if (SD.mkdir(folderPath.c_str())) {
if (SdMan.mkdir(folderPath.c_str())) {
Serial.printf("[%lu] [WEB] Folder created successfully: %s\n", millis(), folderPath.c_str());
server->send(200, "text/plain", "Folder created: " + folderName);
} else {
@@ -500,7 +502,7 @@ void CrossPointWebServer::handleDelete() const {
}
// Check if item exists
if (!SD.exists(itemPath.c_str())) {
if (!SdMan.exists(itemPath.c_str())) {
Serial.printf("[%lu] [WEB] Delete failed - item not found: %s\n", millis(), itemPath.c_str());
server->send(404, "text/plain", "Item not found");
return;
@@ -512,10 +514,10 @@ void CrossPointWebServer::handleDelete() const {
if (itemType == "folder") {
// For folders, try to remove (will fail if not empty)
File dir = SD.open(itemPath.c_str());
FsFile dir = SdMan.open(itemPath.c_str());
if (dir && dir.isDirectory()) {
// Check if folder is empty
File entry = dir.openNextFile();
FsFile entry = dir.openNextFile();
if (entry) {
// Folder is not empty
entry.close();
@@ -526,10 +528,10 @@ void CrossPointWebServer::handleDelete() const {
}
dir.close();
}
success = SD.rmdir(itemPath.c_str());
success = SdMan.rmdir(itemPath.c_str());
} else {
// For files, use remove
success = SD.remove(itemPath.c_str());
success = SdMan.remove(itemPath.c_str());
}
if (success) {