From 697c749a8dddf83644ef7dada39d153652455c3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 15 Mar 2022 22:22:05 +0100 Subject: [PATCH 1/3] LittleFS recursive display and erase. Cause we got directories now, baby! --- src/FSCommon.cpp | 37 +++++-- src/mesh/http/ContentHandler.cpp | 163 ++++++++++++++++++------------- 2 files changed, 124 insertions(+), 76 deletions(-) diff --git a/src/FSCommon.cpp b/src/FSCommon.cpp index fb3dd42fd..cae9556ef 100644 --- a/src/FSCommon.cpp +++ b/src/FSCommon.cpp @@ -1,22 +1,43 @@ #include "configuration.h" #include "FSCommon.h" +void listDir(fs::FS &fs, const char * dirname, uint8_t levels) +#ifdef FSCom +{ + File root = fs.open(dirname); + if(!root){ + return; + } + if(!root.isDirectory()){ + return; + } + + File file = root.openNextFile(); + while(file){ + if(file.isDirectory()){ + if(levels){ + listDir(fs, file.name(), levels -1); + } + } else { + DEBUG_MSG(" %s (%i Bytes)\n", file.name(), file.size()); + } + file.close(); + file = root.openNextFile(); + } + file.close(); +#endif +} + void fsInit() { #ifdef FSCom if (!FSBegin()) { - DEBUG_MSG("ERROR filesystem mount Failed\n"); + DEBUG_MSG("ERROR filesystem mount Failed. Formatting...\n"); assert(0); // FIXME - report failure to phone } DEBUG_MSG("Filesystem files:\n"); - File dir = FSCom.open("/"); - File f = dir.openNextFile(); - while (f) { - DEBUG_MSG(" %s\n", f.name()); - f.close(); - f = dir.openNextFile(); - } + listDir(FSCom, "/", 10); #endif } diff --git a/src/mesh/http/ContentHandler.cpp b/src/mesh/http/ContentHandler.cpp index 4eb6cb7e5..d055db4b6 100644 --- a/src/mesh/http/ContentHandler.cpp +++ b/src/mesh/http/ContentHandler.cpp @@ -272,60 +272,97 @@ void handleAPIv1ToRadio(HTTPRequest *req, HTTPResponse *res) DEBUG_MSG("webAPI handleAPIv1ToRadio\n"); } +bool firstFile = 1; + +void htmlDeleteDir(fs::FS &fs, const char * dirname) +{ + File root = fs.open(dirname); + if(!root){ + return; + } + if(!root.isDirectory()){ + return; + } + + File file = root.openNextFile(); + while(file){ + if(file.isDirectory()){ + htmlDeleteDir(fs, file.name()); + file.close(); + } else { + String fileName = String(file.name()); + file.close(); + DEBUG_MSG(" %s\n", fileName.c_str()); + fs.remove(fileName); + + } + file = root.openNextFile(); + } + root.close(); +} + +void htmlListDir(fs::FS &fs, HTTPResponse *res, const char * dirname, uint8_t levels) +{ + File root = fs.open(dirname); + if(!root){ + return; + } + if(!root.isDirectory()){ + return; + } + + File file = root.openNextFile(); + while(file){ + if(file.isDirectory()){ + if(levels){ + htmlListDir(fs, res, file.name(), levels -1); + } + } else { + if (firstFile) { + firstFile = 0; + } else { + res->println(","); + } + res->println("{"); + if (String(file.name()).substring(1).endsWith(".gz")) { + String modifiedFile = String(file.name()).substring(1); + modifiedFile.remove((modifiedFile.length() - 3), 3); + res->print("\"nameModified\": \"" + modifiedFile + "\","); + res->print("\"name\": \"" + String(file.name()).substring(1) + "\","); + } else { + res->print("\"name\": \"" + String(file.name()).substring(1) + "\","); + } + res->print("\"size\": " + String(file.size())); + res->print("}"); + } + file.close(); + file = root.openNextFile(); + } + root.close(); +} + void handleFsBrowseStatic(HTTPRequest *req, HTTPResponse *res) { res->setHeader("Content-Type", "application/json"); res->setHeader("Access-Control-Allow-Origin", "*"); res->setHeader("Access-Control-Allow-Methods", "GET"); - - File root = FSCom.open("/"); - - if (root.isDirectory()) { - res->println("{"); - res->println("\"data\": {"); - - File file = root.openNextFile(); - res->print("\"files\": ["); - bool firstFile = 1; - while (file) { - String filePath = String(file.name()); - if (filePath.indexOf("/static") == 0) { - if (firstFile) { - firstFile = 0; - } else { - res->println(","); - } - - res->println("{"); - - if (String(file.name()).substring(1).endsWith(".gz")) { - String modifiedFile = String(file.name()).substring(1); - modifiedFile.remove((modifiedFile.length() - 3), 3); - res->print("\"nameModified\": \"" + modifiedFile + "\","); - res->print("\"name\": \"" + String(file.name()).substring(1) + "\","); - - } else { - res->print("\"name\": \"" + String(file.name()).substring(1) + "\","); - } - res->print("\"size\": " + String(file.size())); - res->print("}"); - } - - file = root.openNextFile(); - } - res->print("],"); - res->print("\"filesystem\" : {"); - res->print("\"total\" : " + String(FSCom.totalBytes()) + ","); - res->print("\"used\" : " + String(FSCom.usedBytes()) + ","); - res->print("\"free\" : " + String(FSCom.totalBytes() - FSCom.usedBytes())); - res->println("}"); - res->println("},"); - res->println("\"status\": \"ok\""); - res->println("}"); - } + res->println("{"); + res->println("\"data\": {"); + res->print("\"files\": ["); + htmlListDir(FSCom, res, "/", 10); + res->print("],"); + res->print("\"filesystem\" : {"); + res->print("\"total\" : " + String(FSCom.totalBytes()) + ","); + res->print("\"used\" : " + String(FSCom.usedBytes()) + ","); + res->print("\"free\" : " + String(FSCom.totalBytes() - FSCom.usedBytes())); + res->println("}"); + res->println("},"); + res->println("\"status\": \"ok\""); + res->println("}"); } + void handleFsDeleteStatic(HTTPRequest *req, HTTPResponse *res) { ResourceParameters *params = req->getParams(); @@ -369,6 +406,11 @@ void handleStatic(HTTPRequest *req, HTTPResponse *res) bool has_set_content_type = false; + if (filename == "/static/") { + filename = "/static/index.html"; + filenameGzip = "/static/index.html.gz"; + } + if (FSCom.exists(filename.c_str())) { file = FSCom.open(filename.c_str()); if (!file.available()) { @@ -715,19 +757,9 @@ void handleUpdateFs(HTTPRequest *req, HTTPResponse *res) if (streamptr != nullptr) { DEBUG_MSG("Connection to content server ... success!\n"); - File root = FSCom.open("/"); - File file = root.openNextFile(); - DEBUG_MSG("Deleting files from /static : \n"); - while (file) { - String filePath = String(file.name()); - if (filePath.indexOf("/static") == 0) { - DEBUG_MSG(" %s\n", file.name()); - FSCom.remove(file.name()); - } - file = root.openNextFile(); - } + htmlDeleteDir(FSCom, "/static"); delay(5); // Let other network operations run @@ -754,6 +786,8 @@ void handleUpdateFs(HTTPRequest *req, HTTPResponse *res) if (!TARUnpacker->tarStreamExpander(streamptr, streamSize, FSCom, "/static")) { res->printf("tarStreamExpander failed with return code #%d\n", TARUnpacker->tarGzGetError()); Serial.printf("tarStreamExpander failed with return code #%d\n", TARUnpacker->tarGzGetError()); + // Close the connection on error and free up memory + client->stop(); return; } else { @@ -773,6 +807,8 @@ void handleUpdateFs(HTTPRequest *req, HTTPResponse *res) res->printf("Failed to establish http connection\n"); Serial.println("Failed to establish http connection"); return; + // Close the connection on error and free up memory + client->stop(); } res->println("Done! Restarting the device. Click this in 10 seconds"); @@ -794,19 +830,10 @@ void handleDeleteFsContent(HTTPRequest *req, HTTPResponse *res) res->println("

Meshtastic

\n"); res->println("Deleting Content in /static/*"); - File root = FSCom.open("/"); - File file = root.openNextFile(); + DEBUG_MSG("Deleting files from /static/* : \n"); - DEBUG_MSG("Deleting files from /static : \n"); + htmlDeleteDir(FSCom, "/static"); - while (file) { - String filePath = String(file.name()); - if (filePath.indexOf("/static") == 0) { - DEBUG_MSG(" %s\n", file.name()); - FSCom.remove(file.name()); - } - file = root.openNextFile(); - } res->println("


Back to admin\n"); } From e435453363bbc35e73bc3359e10ae24d32c5cfc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Tue, 15 Mar 2022 22:49:06 +0100 Subject: [PATCH 2/3] fix building for nRF52 --- src/FSCommon.cpp | 8 ++++---- src/mesh/http/ContentHandler.cpp | 20 ++++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/FSCommon.cpp b/src/FSCommon.cpp index cae9556ef..81ff48f2c 100644 --- a/src/FSCommon.cpp +++ b/src/FSCommon.cpp @@ -1,10 +1,10 @@ #include "configuration.h" #include "FSCommon.h" -void listDir(fs::FS &fs, const char * dirname, uint8_t levels) +void listDir(const char * dirname, uint8_t levels) #ifdef FSCom { - File root = fs.open(dirname); + File root = FSCom.open(dirname); if(!root){ return; } @@ -16,7 +16,7 @@ void listDir(fs::FS &fs, const char * dirname, uint8_t levels) while(file){ if(file.isDirectory()){ if(levels){ - listDir(fs, file.name(), levels -1); + listDir(file.name(), levels -1); } } else { DEBUG_MSG(" %s (%i Bytes)\n", file.name(), file.size()); @@ -38,6 +38,6 @@ void fsInit() } DEBUG_MSG("Filesystem files:\n"); - listDir(FSCom, "/", 10); + listDir("/", 10); #endif } diff --git a/src/mesh/http/ContentHandler.cpp b/src/mesh/http/ContentHandler.cpp index d055db4b6..a186e918e 100644 --- a/src/mesh/http/ContentHandler.cpp +++ b/src/mesh/http/ContentHandler.cpp @@ -274,9 +274,9 @@ void handleAPIv1ToRadio(HTTPRequest *req, HTTPResponse *res) bool firstFile = 1; -void htmlDeleteDir(fs::FS &fs, const char * dirname) +void htmlDeleteDir(const char * dirname) { - File root = fs.open(dirname); + File root = FSCom.open(dirname); if(!root){ return; } @@ -287,13 +287,13 @@ void htmlDeleteDir(fs::FS &fs, const char * dirname) File file = root.openNextFile(); while(file){ if(file.isDirectory()){ - htmlDeleteDir(fs, file.name()); + htmlDeleteDir(file.name()); file.close(); } else { String fileName = String(file.name()); file.close(); DEBUG_MSG(" %s\n", fileName.c_str()); - fs.remove(fileName); + FSCom.remove(fileName); } file = root.openNextFile(); @@ -301,9 +301,9 @@ void htmlDeleteDir(fs::FS &fs, const char * dirname) root.close(); } -void htmlListDir(fs::FS &fs, HTTPResponse *res, const char * dirname, uint8_t levels) +void htmlListDir( HTTPResponse *res, const char * dirname, uint8_t levels) { - File root = fs.open(dirname); + File root = FSCom.open(dirname); if(!root){ return; } @@ -315,7 +315,7 @@ void htmlListDir(fs::FS &fs, HTTPResponse *res, const char * dirname, uint8_t l while(file){ if(file.isDirectory()){ if(levels){ - htmlListDir(fs, res, file.name(), levels -1); + htmlListDir(res, file.name(), levels -1); } } else { if (firstFile) { @@ -350,7 +350,7 @@ void handleFsBrowseStatic(HTTPRequest *req, HTTPResponse *res) res->println("{"); res->println("\"data\": {"); res->print("\"files\": ["); - htmlListDir(FSCom, res, "/", 10); + htmlListDir(res, "/", 10); res->print("],"); res->print("\"filesystem\" : {"); res->print("\"total\" : " + String(FSCom.totalBytes()) + ","); @@ -759,7 +759,7 @@ void handleUpdateFs(HTTPRequest *req, HTTPResponse *res) DEBUG_MSG("Deleting files from /static : \n"); - htmlDeleteDir(FSCom, "/static"); + htmlDeleteDir("/static"); delay(5); // Let other network operations run @@ -832,7 +832,7 @@ void handleDeleteFsContent(HTTPRequest *req, HTTPResponse *res) DEBUG_MSG("Deleting files from /static/* : \n"); - htmlDeleteDir(FSCom, "/static"); + htmlDeleteDir("/static"); res->println("


Back to admin\n"); } From cb6846ebc6cf8a5102fef6d034914679dba0f8fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Wed, 16 Mar 2022 08:30:38 +0100 Subject: [PATCH 3/3] fix PortduinoFS integration for Firmware. --- src/FSCommon.cpp | 2 +- src/mesh/http/ContentHandler.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/FSCommon.cpp b/src/FSCommon.cpp index 81ff48f2c..3a2f8a92e 100644 --- a/src/FSCommon.cpp +++ b/src/FSCommon.cpp @@ -14,7 +14,7 @@ void listDir(const char * dirname, uint8_t levels) File file = root.openNextFile(); while(file){ - if(file.isDirectory()){ + if(file.isDirectory() && !String(file.name()).endsWith(".")) { if(levels){ listDir(file.name(), levels -1); } diff --git a/src/mesh/http/ContentHandler.cpp b/src/mesh/http/ContentHandler.cpp index a186e918e..cd0bcfe90 100644 --- a/src/mesh/http/ContentHandler.cpp +++ b/src/mesh/http/ContentHandler.cpp @@ -286,7 +286,7 @@ void htmlDeleteDir(const char * dirname) File file = root.openNextFile(); while(file){ - if(file.isDirectory()){ + if(file.isDirectory() && !String(file.name()).endsWith(".")) { htmlDeleteDir(file.name()); file.close(); } else { @@ -301,7 +301,7 @@ void htmlDeleteDir(const char * dirname) root.close(); } -void htmlListDir( HTTPResponse *res, const char * dirname, uint8_t levels) +void htmlListDir(HTTPResponse *res, const char * dirname, uint8_t levels) { File root = FSCom.open(dirname); if(!root){ @@ -313,7 +313,7 @@ void htmlListDir( HTTPResponse *res, const char * dirname, uint8_t levels) File file = root.openNextFile(); while(file){ - if(file.isDirectory()){ + if(file.isDirectory() && !String(file.name()).endsWith(".")) { if(levels){ htmlListDir(res, file.name(), levels -1); }