diff --git a/docs/Commands.txt b/docs/Commands.txt index 7d957ed5..a9424709 100644 --- a/docs/Commands.txt +++ b/docs/Commands.txt @@ -177,6 +177,10 @@ Get will give type and settings only, not the protected T1/T2 * List ESP Filesystem [ESP720] pwd= +* Action on ESP Filesystem +rmdir / remove / mkdir / exists +[ESP730]= pwd= + * FW Informations [ESP800] pwd= diff --git a/esp3d/configuration.h b/esp3d/configuration.h index d4b853e3..5a0ce08d 100644 --- a/esp3d/configuration.h +++ b/esp3d/configuration.h @@ -108,8 +108,8 @@ //FILESYSTEM_FEATURE: to host some files on flash //ESP_SPIFFS_FILESYSTEM 0 //ESP_FAT_FILESYSTEM 1 -//ESP_LITTLEFS_FILESYSTEM 2 //Not Yet implemented -#define FILESYSTEM_FEATURE ESP_SPIFFS_FILESYSTEM +//ESP_LITTLEFS_FILESYSTEM 2 +#define FILESYSTEM_FEATURE ESP_FAT_FILESYSTEM //DIRECT_PIN_FEATURE: allow to access pin using ESP201 command #define DIRECT_PIN_FEATURE diff --git a/esp3d/src/core/commands.cpp b/esp3d/src/core/commands.cpp index 459b7a05..59d8bb0f 100644 --- a/esp3d/src/core/commands.cpp +++ b/esp3d/src/core/commands.cpp @@ -453,6 +453,12 @@ bool Commands::execute_internal_command (int cmd, const char* cmd_params, level_ case 720: response = ESP720(cmd_params, auth_type, output); break; + //Action on ESP Filesystem + //rmdir / remove / mkdir / exists + //[ESP730]= pwd= + case 730: + response = ESP730(cmd_params, auth_type, output); + break; #endif //FILESYSTEM_FEATURE //Get fw version firmare target and fw version diff --git a/esp3d/src/core/commands.h b/esp3d/src/core/commands.h index 183bff43..f7536f56 100644 --- a/esp3d/src/core/commands.h +++ b/esp3d/src/core/commands.h @@ -109,6 +109,7 @@ public: #if defined(FILESYSTEM_FEATURE) bool ESP710(const char* cmd_params, level_authenticate_type auth_level, ESP3DOutput * output); bool ESP720(const char* cmd_params, level_authenticate_type auth_level, ESP3DOutput * output); + bool ESP730(const char* cmd_params, level_authenticate_type auth_level, ESP3DOutput * output); #endif //FILESYSTEM_FEATURE bool ESP800(const char* cmd_params, level_authenticate_type auth_level, ESP3DOutput * output); bool ESP900(const char* cmd_params, level_authenticate_type auth_level, ESP3DOutput * output); diff --git a/esp3d/src/core/espcmd/ESP730.cpp b/esp3d/src/core/espcmd/ESP730.cpp new file mode 100644 index 00000000..490ca606 --- /dev/null +++ b/esp3d/src/core/espcmd/ESP730.cpp @@ -0,0 +1,86 @@ +/* + ESP730.cpp - ESP3D command class + + Copyright (c) 2014 Luc Lebosse. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include "../../include/esp3d_config.h" +#if defined (FILESYSTEM_FEATURE) +#include "../commands.h" +#include "../esp3doutput.h" +#include "../settings_esp3d.h" +#include "../../modules/authentication/authentication_service.h" +#include "../../modules/filesystem/esp_filesystem.h" +// Action on ESP Filesystem +//rmdir / remove / mkdir / exists +//[ESP730]= pwd= +bool Commands::ESP730(const char* cmd_params, level_authenticate_type auth_type, ESP3DOutput * output) +{ + bool response = true; + String parameter; + parameter = get_param (cmd_params, ""); +#ifdef AUTHENTICATION_FEATURE + if (auth_type != LEVEL_ADMIN) { + output->printERROR("Wrong authentication!", 401); + return false; + } +#else + (void)auth_type; +#endif //AUTHENTICATION_FEATURE + parameter = get_param (cmd_params, "mkdir="); + if (parameter.length() != 0) { + if (ESP_FileSystem::mkdir(parameter.c_str())) { + output->printMSG ("ok"); + } else { + output->printERROR ("failed!"); + response = false; + } + return response; + } + parameter = get_param (cmd_params, "rmdir="); + if (parameter.length() != 0) { + if (ESP_FileSystem::rmdir(parameter.c_str())) { + output->printMSG ("ok"); + } else { + output->printERROR ("failed!"); + response = false; + } + return response; + } + parameter = get_param (cmd_params, "remove="); + if (parameter.length() != 0) { + if (ESP_FileSystem::remove(parameter.c_str())) { + output->printMSG ("ok"); + } else { + output->printERROR ("failed!"); + response = false; + } + return response; + } + parameter = get_param (cmd_params, "exists="); + if (parameter.length() != 0) { + if (ESP_FileSystem::exists(parameter.c_str())) { + output->printMSG ("yes"); + } else { + output->printMSG ("no"); + } + return response; + } + output->printERROR ("Incorrect command!"); + response = false; +} + +#endif //FILESYSTEM_FEATURE diff --git a/esp3d/src/include/sanity_esp3d.h b/esp3d/src/include/sanity_esp3d.h index 52323ff7..3c25a79a 100644 --- a/esp3d/src/include/sanity_esp3d.h +++ b/esp3d/src/include/sanity_esp3d.h @@ -88,5 +88,8 @@ #if FILESYSTEM_FEATURE == ESP_FAT_FILESYSTEM && defined( ARDUINO_ARCH_ESP8266) #error Fat FS is not available in ESP8266 #endif +#if FILESYSTEM_FEATURE == ESP_LITTLEFS_FILESYSTEM && defined( ARDUINO_ARCH_ESP32) +#error LittleFS is not available in ESP32 +#endif #endif //SANITY_ESP3D_H diff --git a/esp3d/src/modules/display/esplogo.c b/esp3d/src/modules/display/esplogo.cpp similarity index 99% rename from esp3d/src/modules/display/esplogo.c rename to esp3d/src/modules/display/esplogo.cpp index 049174db..22d5658a 100644 --- a/esp3d/src/modules/display/esplogo.c +++ b/esp3d/src/modules/display/esplogo.cpp @@ -1,3 +1,6 @@ +#include "../../include/esp3d_config.h" +#if defined (DISPLAY_DEVICE) && (DISPLAY_UI_TYPE == UI_TYPE_ADVANCED) +extern "C" { #include "lvgl.h" #ifndef LV_ATTRIBUTE_MEM_ALIGN @@ -627,3 +630,7 @@ lv_img_dsc_t esplogo = { .header.cf = LV_IMG_CF_TRUE_COLOR_CHROMA_KEYED, .data = esplogo_map, }; + +}; + +#endif //defined (DISPLAY_DEVICE) && (DISPLAY_UI_TYPE == UI_TYPE_ADVANCED) diff --git a/esp3d/src/modules/filesystem/esp_filesystem.cpp b/esp3d/src/modules/filesystem/esp_filesystem.cpp index e083265d..4e30e9de 100644 --- a/esp3d/src/modules/filesystem/esp_filesystem.cpp +++ b/esp3d/src/modules/filesystem/esp_filesystem.cpp @@ -25,23 +25,13 @@ #endif //FILESYSTEM_TIMESTAMP_FEATURE #include #ifdef ARDUINO_ARCH_ESP32 -#if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) -#include -#endif //ESP_FAT_FILESYSTEM -#if (FILESYSTEM_FEATURE == ESP_FAT_FILESYSTEM) -#include "FFat.h" -#endif //ESP_FAT_FILESYSTEM #include #endif //ARDUINO_ARCH_ESP32 #define ESP_MAX_OPENHANDLE 4 - File tFile_handle[ESP_MAX_OPENHANDLE]; -#ifdef ARDUINO_ARCH_ESP8266 -#if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) -Dir tDir_handle[ESP_MAX_OPENHANDLE]; -#endif //ESP_SPIFFS_FILESYSTEM -#endif //ARDUINO_ARCH_ESP8266 + +bool ESP_FileSystem::_started = false; //constructor ESP_FileSystem::ESP_FileSystem() @@ -69,76 +59,20 @@ String & ESP_FileSystem::formatBytes (uint64_t bytes) return res; } -bool ESP_FileSystem::begin() -{ -#if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) -#if defined(ARDUINO_ARCH_ESP8266) - return SPIFFS.begin(); -#endif //ARDUINO_ARCH_ESP8266 -#if defined(ARDUINO_ARCH_ESP32) - return SPIFFS.begin(true); -#endif //ARDUINO_ARCH_ESP32 -#endif //ESP_SPIFFS_FILESYSTEM -#if (FILESYSTEM_FEATURE == ESP_FAT_FILESYSTEM) - return FFat.begin(); -#endif //ESP_FAT_FILESYSTEM -} -void ESP_FileSystem::end() -{ -#if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) - SPIFFS.end(); -#endif //ESP_SPIFFS_FILESYSTEM -#if (FILESYSTEM_FEATURE == ESP_FAT_FILESYSTEM) - FFat.end(); -#endif //ESP_FAT_FILESYSTEM -} - -size_t ESP_FileSystem::totalBytes() -{ -#if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) -#if defined (ARDUINO_ARCH_ESP8266) - fs::FSInfo info; - SPIFFS.info (info); - return info.totalBytes; -#endif //ARDUINO_ARCH_ESP8266 -#if defined (ARDUINO_ARCH_ESP32) - return SPIFFS.totalBytes(); -#endif //ARDUINO_ARCH_ESP32 -#endif //ESP_SPIFFS_FILESYSTEM -#if (FILESYSTEM_FEATURE == ESP_FAT_FILESYSTEM) - return FFat.totalBytes(); -#endif //ESP_FAT_FILESYSTEM -} - -size_t ESP_FileSystem::usedBytes() -{ -#if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) -#if defined (ARDUINO_ARCH_ESP8266) - fs::FSInfo info; - SPIFFS.info (info); - return info.usedBytes; -#endif //ARDUINO_ARCH_ESP8266 -#if defined (ARDUINO_ARCH_ESP32) - return SPIFFS.usedBytes(); -#endif //ARDUINO_ARCH_ESP32 -#endif //ESP_SPIFFS_FILESYSTEM -#if (FILESYSTEM_FEATURE == ESP_FAT_FILESYSTEM) - return (FFat.totalBytes() - FFat.freeBytes()); -#endif //ESP_FAT_FILESYSTEM -} - size_t ESP_FileSystem::max_update_size() { size_t flashsize = 0; #if defined (ARDUINO_ARCH_ESP8266) flashsize = ESP.getFlashChipSize(); //if higher than 1MB take out SPIFFS - if (flashsize > 1024 * 1024) { + if (flashsize <= 1024 * 1024) { flashsize = (1024 * 1024)-ESP.getSketchSize()-1024; } else { - fs::FSInfo info; - SPIFFS.info (info); - flashsize = flashsize - ESP.getSketchSize()-info.totalBytes-1024; + flashsize = flashsize - ESP.getSketchSize()-totalBytes()-1024; + //max OTA partition is 1019Kb + if (flashsize > 1024 * 1024) { + flashsize = (1024 * 1024) - 1024; + } } #endif //ARDUINO_ARCH_ESP8266 #if defined (ARDUINO_ARCH_ESP32) @@ -155,252 +89,7 @@ size_t ESP_FileSystem::max_update_size() return flashsize; } -const char * ESP_FileSystem::FilesystemName() -{ -#if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) - return "SPIFFS"; -#endif //ESP_SPIFFS_FILESYSTEM -#if (FILESYSTEM_FEATURE == ESP_FAT_FILESYSTEM) - return "FAT"; -#endif //ESP_FAT_FILESYSTEM - return "None"; -} - -bool ESP_FileSystem::format() -{ -#if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) - return SPIFFS.format(); -#endif //ESP_SPIFFS_FILESYSTEM -#if (FILESYSTEM_FEATURE == ESP_FAT_FILESYSTEM) - /* FFat.end();*/ - return FFat.format(); -#endif //ESP_FAT_FILESYSTEM - return false; -} - -ESP_File ESP_FileSystem::open(const char* path, uint8_t mode) -{ - //do some check - if(((strcmp(path,"/") == 0) && ((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) || (strlen(path) == 0)) { - return ESP_File(); - } - // path must start by '/' - if (path[0] != '/') { - return ESP_File(); - } -#if (FILESYSTEM_FEATURE == ESP_FAT_FILESYSTEM) - if (mode != ESP_FILE_READ) { - //check container exists - String p = path; - p.remove(p.lastIndexOf('/') +1); - if (!exists(p.c_str())) { - //log_esp3d("Error opening: %s", path); - return ESP_File(); - } - } -#endif -#if defined (ARDUINO_ARCH_ESP8266) -#if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) - File ftmp = SPIFFS.open(path, (mode == ESP_FILE_READ)?"r":(mode == ESP_FILE_WRITE)?"w":"a"); - if(ftmp) { - //log_esp3d("Success openening: %s", path); - ESP_File esptmp(&ftmp, false,(mode == ESP_FILE_READ)?false:true, path); - return esptmp; - } - (void)mode; - Dir dtmp = SPIFFS.openDir(path); - ESP_File esptmp(&dtmp, true, false, path); - return esptmp; -#endif //ESP_SPIFFS_FILESYSTEM -#endif //ARDUINO_ARCH_ESP8266 -#if defined (ARDUINO_ARCH_ESP32) -#if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) - //TODO add support if path = /DIR1/ <- with last / - File tmp = SPIFFS.open(path, (mode == ESP_FILE_READ)?FILE_READ:(mode == ESP_FILE_WRITE)?FILE_WRITE:FILE_APPEND); -#endif //ESP_SPIFFS_FILESYSTEM -#if (FILESYSTEM_FEATURE == ESP_FAT_FILESYSTEM) - File tmp = FFat.open(path, (mode == ESP_FILE_READ)?FILE_READ:(mode == ESP_FILE_WRITE)?FILE_WRITE:FILE_APPEND); -#endif //ESP_FAT_FILESYSTEM - ESP_File esptmp(&tmp, tmp.isDirectory(),(mode == ESP_FILE_READ)?false:true, path); - return esptmp; -#endif //ARDUINO_ARCH_ESP32 -} - -bool ESP_FileSystem::exists(const char* path) -{ - bool res = false; - //log_esp3d("Check %s", path); - //root should always be there - if (strcmp(path, "/") == 0) { - return true; - } -#if (FILESYSTEM_FEATURE == ESP_FAT_FILESYSTEM) - res = FFat.exists(path); - if (!res) { - ESP_File root = ESP_FileSystem::open(path, ESP_FILE_READ); - if (root) { - res = root.isDirectory(); - } - } -#endif //ESP_FAT_FILESYSTEM -#if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) - String spath = path; - spath.trim(); - if (spath[spath.length()-1] == '/') { - if (spath!="/") { - spath.remove(spath.length()-1); - } - } - res = SPIFFS.exists(spath.c_str()); - if (!res) { - String newpath = spath; - if (newpath[newpath.length()-1] != '/') { - newpath+="/"; - } - newpath+="."; - //log_esp3d("Check %s", newpath.c_str()); - res = SPIFFS.exists(newpath); - if (!res) { - ESP_File f = ESP_FileSystem::open(path, ESP_FILE_READ); - if (f) { - //Check directories - ESP_File sub = f.openNextFile(); - if (sub) { - sub.close(); - res = true; - } - f.close(); - } - } - } -#endif //ESP_SPIFFS_FILESYSTEM - return res; -} - -bool ESP_FileSystem::remove(const char *path) -{ -#if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) - return SPIFFS.remove(path); -#endif //ESP_SPIFFS_FILESYSTEM -#if (FILESYSTEM_FEATURE == ESP_FAT_FILESYSTEM) - return FFat.remove(path); -#endif //ESP_FAT_FILESYSTEM -} - -bool ESP_FileSystem::mkdir(const char *path) -{ -#if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) - //Use file named . to simulate directory - String p = path; - if (p[p.length()-1] != '/') { - p+="/"; - } - p+="."; - //log_esp3d("Dir create : %s", p.c_str()); - ESP_File f = open(p.c_str(), ESP_FILE_WRITE); - if (f) { - f.close(); - return true; - } else { - return false; - } -#endif //ESP_SPIFFS_FILESYSTEM -#if (FILESYSTEM_FEATURE == ESP_FAT_FILESYSTEM) - return FFat.mkdir(path); -#endif //ESP_FAT_FILESYSTEM -} - -bool ESP_FileSystem::rmdir(const char *path) -{ -#if (FILESYSTEM_FEATURE == ESP_FAT_FILESYSTEM) - if (!exists(path)) { - return false; - } - bool res = true; - GenLinkedList pathlist; - String p = path; - pathlist.push(p); - while (pathlist.count() > 0) { - File dir = FFat.open(pathlist.getLast().c_str()); - File f = dir.openNextFile(); - bool candelete = true; - while (f) { - if (f.isDirectory()) { - candelete = false; - String newdir = f.name(); - pathlist.push(newdir); - f.close(); - f = File(); - } else { - FFat.remove(f.name()); - f.close(); - f = dir.openNextFile(); - } - } - if (candelete) { - if (pathlist.getLast() !="/") { - res = FFat.rmdir(pathlist.getLast().c_str()); - } - pathlist.pop(); - } - dir.close(); - } - p = String(); - log_esp3d("count %d", pathlist.count()); - return res; -#endif //ESP_FAT_FILESYSTEM -#if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) -#if defined (ARDUINO_ARCH_ESP8266) - Dir dtmp = SPIFFS.openDir(path); - while (dtmp.next()) { - if (!SPIFFS.remove(dtmp.fileName().c_str())) { - return false; - } - } - return true; -#endif //ARDUINO_ARCH_ESP8266 -#if defined (ARDUINO_ARCH_ESP32) - String spath = path; - spath.trim(); - if (spath[spath.length()-1] == '/') { - if (spath!="/") { - spath.remove(spath.length()-1); - } - } - log_esp3d("Deleting : %s",spath.c_str()); - File ftmp = SPIFFS.open(spath.c_str()); - if (ftmp) { - File pfile = ftmp.openNextFile(); - while (pfile) { - //log_esp3d("File: %s",pfile.name()); - if (!SPIFFS.remove(pfile.name())) { - pfile.close(); - return false; - } - pfile.close(); - pfile = ftmp.openNextFile(); - } - ftmp.close(); - return true; - } else { - return false; - } -#endif //ARDUINO_ARCH_ESP32 -#endif //ESP_SPIFFS_FILESYSTEM -} - -void ESP_FileSystem::closeAll() -{ - for (uint8_t i = 0; i < ESP_MAX_OPENHANDLE; i++) { -#if defined (ARDUINO_ARCH_ESP8266) - tDir_handle[i] = Dir(); -#endif //ARDUINO_ARCH_ESP8266 - tFile_handle[i].close(); - tFile_handle[i] = File(); - } -} - -ESP_File::ESP_File(const char * name, const char * filename, bool isdir) +ESP_File::ESP_File(const char * name, const char * filename, bool isdir, size_t size) { _isdir = isdir; _dirlist = ""; @@ -412,250 +101,7 @@ ESP_File::ESP_File(const char * name, const char * filename, bool isdir) memset (&_lastwrite,0,sizeof(time_t)); #endif //FILESYSTEM_TIMESTAMP_FEATURE _iswritemode = false; - _size = 0; -} - -ESP_File::ESP_File(void* handle, bool isdir, bool iswritemode, const char * path) -{ - _isdir = isdir; - _dirlist = ""; - _isfakedir = false; - _index = -1; - _filename = ""; - _name = ""; -#ifdef FILESYSTEM_TIMESTAMP_FEATURE - memset (&_lastwrite,0,sizeof(time_t)); -#endif //FILESYSTEM_TIMESTAMP_FEATURE - _iswritemode = iswritemode; - _size = 0; - if (!handle) { - return ; - } - bool set =false; -#if defined (ARDUINO_ARCH_ESP8266) - if (_isdir) { - for (uint8_t i=0; (i < ESP_MAX_OPENHANDLE) && !set; i++) { - if (tDir_handle[i].fileName().length() == 0) { - tDir_handle[i] = *((Dir *)handle); - _index = i; - //Path = filename - if (path) { - _filename = path; - if (_filename == "/") { - _filename = "/."; - } - if (_filename[_filename.length()-1] != '.') { - if (_filename[_filename.length()-2] != '/') { - _filename+="/"; - } - _filename+="."; - } - //log_esp3d("Filename: %s", _filename.c_str()); - //Name - if (_filename == "/.") { - _name = "/"; - } else { - _name = _filename; - if (_name.length() >=2) { - if ((_name[_name.length() - 1] == '.') && (_name[_name.length() - 2] == '/')) { - _name.remove( _name.length() - 2,2); - } - } - _name.remove( 0, _name.lastIndexOf('/')+1); - } - } - //log_esp3d("Name: %s index: %d", _name.c_str(), _index); - set = true; - } - } - return; - } -#endif //ARDUINO_ARCH_ESP8266 - - for (uint8_t i=0; (i < ESP_MAX_OPENHANDLE) && !set; i++) { - if (!tFile_handle[i]) { - tFile_handle[i] = *((File*)handle); - //filename - _filename = tFile_handle[i].name(); - - //if root - if (_filename == "/") { - _filename = "/."; - } - if (_isdir) { - if (_filename[_filename.length()-1] != '.') { - if (_filename[_filename.length()-2] != '/') { - _filename+="/"; - } - _filename+="."; - } - } - //name - if (_filename == "/.") { - _name = "/"; - } else { - _name = _filename; - if (_name.endsWith("/.")) { - _name.remove( _name.length() - 2,2); - _isfakedir = true; - _isdir = true; - } - if (_name[0] == '/') { - _name.remove( 0, 1); - } - int pos = _name.lastIndexOf('/'); - if (pos != -1) { - _name.remove( 0, pos+1); - } - } - //size - _size = tFile_handle[i].size(); - //time -#ifdef FILESYSTEM_TIMESTAMP_FEATURE - _lastwrite = tFile_handle[i].getLastWrite(); -#endif //FILESYSTEM_TIMESTAMP_FEATURE - _index = i; - //log_esp3d("Opening File at index %d",_index); - set = true; - } - } -} - -void ESP_File::close() -{ - if (_index != -1) { -#if defined (ARDUINO_ARCH_ESP8266) - if (_isdir && !_isfakedir) { - //log_esp3d("Closing Dir at index %d", _index); - tDir_handle[_index] = Dir(); - _index = -1; - return; - } -#endif //ARDUINO_ARCH_ESP8266 - //log_esp3d("Closing File at index %d", _index); - tFile_handle[_index].close(); - //reopen if mode = write - //udate size + date - if (_iswritemode && !_isdir) { -#if defined (ARDUINO_ARCH_ESP8266) - File ftmp = SPIFFS.open(_filename.c_str(), "r"); -#endif //ARDUINO_ARCH_ESP8266 -#if defined (ARDUINO_ARCH_ESP32) -#if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) - File ftmp = SPIFFS.open(_filename.c_str()); -#endif //ESP_SPIFFS_FILESYSTEM -#if (FILESYSTEM_FEATURE == ESP_FAT_FILESYSTEM) - File ftmp = FFat.open(_filename.c_str()); -#endif //ESP_FAT_FILESYSTEM -#endif //ARDUINO_ARCH_ESP32 - - if (ftmp) { - _size = ftmp.size(); -#ifdef FILESYSTEM_TIMESTAMP_FEATURE - _lastwrite = ftmp.getLastWrite(); -#endif //FILESYSTEM_TIMESTAMP_FEATURE - ftmp.close(); - } - } -#if defined (ARDUINO_ARCH_ESP32) - tFile_handle[_index] = File(); -#endif //ARDUINO_ARCH_ESP32 - //log_esp3d("Closing File at index %d",_index); - _index = -1; - } -} - -ESP_File ESP_File::openNextFile() -{ - if ((_index == -1) || !_isdir) { - log_esp3d("openNextFile failed"); - return ESP_File(); - } -#if defined (ARDUINO_ARCH_ESP8266) - if(tDir_handle[_index].next()) { - //log_esp3d("Getting next file from %s", _filename.c_str()); - File tmp = tDir_handle[_index].openFile("r"); - while (tmp) { - ESP_File esptmp(&tmp); - esptmp.close(); - String sub = esptmp.filename(); - sub.remove(0,_filename.length()-1); - int pos = sub.indexOf("/"); - if (pos!=-1) { - //is subdir - sub = sub.substring(0,pos); - //log_esp3d("file name:%s name: %s %s sub:%s root:%s", esptmp.filename(), esptmp.name(), (esptmp.isDirectory())?"isDir":"isFile", sub.c_str(), _filename.c_str()); - String tag = "*" + sub + "*"; - //test if already in directory list - if (_dirlist.indexOf(tag) == -1) {//not in list so add it and return the info - _dirlist+= tag; - String fname = _filename.substring(0,_filename.length()-1) + sub + "/."; - //log_esp3d("Found dir name: %s filename:%s", sub.c_str(), fname.c_str()); - esptmp = ESP_File(sub.c_str(), fname.c_str()); - return esptmp; - } else { //already in list so ignore it - //log_esp3d("Dir name: %s already in list", sub.c_str()); - if(!tDir_handle[_index].next()) { - return ESP_File(); - } else { - tmp = tDir_handle[_index].openFile("r"); - } - } - } else { //is file - //log_esp3d("file name:%s name: %s %s sub:%s root:%s", esptmp.filename(), esptmp.name(), (esptmp.isDirectory())?"isDir":"isFile", sub.c_str(), _filename.c_str()); - if (sub == ".") { - //log_esp3d("Dir tag, ignore it"); - if(!tDir_handle[_index].next()) { - return ESP_File(); - } else { - tmp = tDir_handle[_index].openFile("r"); - } - } else { - return esptmp; - } - } - } - } - return ESP_File(); -#endif //ARDUINO_ARCH_ESP8266 -#if defined (ARDUINO_ARCH_ESP32) - File tmp = tFile_handle[_index].openNextFile(); - while (tmp) { - //log_esp3d("tmp name :%s %s", tmp.name(), (tmp.isDirectory())?"isDir":"isFile"); - ESP_File esptmp(&tmp, tmp.isDirectory()); - esptmp.close(); - String sub = esptmp.filename(); - sub.remove(0,_filename.length()-1); - int pos = sub.indexOf("/"); - if (pos!=-1) { - //is subdir - sub = sub.substring(0,pos); - //log_esp3d("file name:%s name: %s %s sub:%s root:%s", esptmp.filename(), esptmp.name(), (esptmp.isDirectory())?"isDir":"isFile", sub.c_str(), _filename.c_str()); - String tag = "*" + sub + "*"; - //test if already in directory list - if (_dirlist.indexOf(tag) == -1) {//not in list so add it and return the info - _dirlist+= tag; - String fname = _filename.substring(0,_filename.length()-1) + sub + "/."; - //log_esp3d("Found dir name: %s filename:%s", sub.c_str(), fname.c_str()); - esptmp = ESP_File(sub.c_str(), fname.c_str()); - return esptmp; - } else { //already in list so ignore it - //log_esp3d("Dir name: %s already in list", sub.c_str()); - tmp = tFile_handle[_index].openNextFile(); - } - } else { //is file - //log_esp3d("file name:%s name: %s %s sub:%s root:%s", esptmp.filename(), esptmp.name(), (esptmp.isDirectory())?"isDir":"isFile", sub.c_str(), _filename.c_str()); - if (sub == ".") { - //log_esp3d("Dir tag, ignore it"); - tmp = tFile_handle[_index].openNextFile(); - } else { - return esptmp; - } - } - - } - return ESP_File(); -#endif //ARDUINO_ARCH_ESP32 + _size = size; } ESP_File::~ESP_File() diff --git a/esp3d/src/modules/filesystem/esp_filesystem.h b/esp3d/src/modules/filesystem/esp_filesystem.h index dca6c265..3469d758 100644 --- a/esp3d/src/modules/filesystem/esp_filesystem.h +++ b/esp3d/src/modules/filesystem/esp_filesystem.h @@ -28,11 +28,13 @@ #define ESP_FILE_WRITE 1 #define ESP_FILE_APPEND 2 +#define ESP_MAX_OPENHANDLE 4 + class ESP_File { public: ESP_File(void * handle = nullptr, bool isdir =false, bool iswritemode = false, const char * path = nullptr); - ESP_File(const char * name, const char * filename, bool isdir = true); + ESP_File(const char * name, const char * filename, bool isdir = true, size_t size =0); ~ESP_File(); operator bool() const; bool isDirectory(); @@ -86,6 +88,7 @@ public: static bool rmdir(const char *path); static void closeAll(); private: + static bool _started; }; diff --git a/esp3d/src/modules/filesystem/fat_filesystem.cpp b/esp3d/src/modules/filesystem/fat_filesystem.cpp new file mode 100644 index 00000000..31d4d153 --- /dev/null +++ b/esp3d/src/modules/filesystem/fat_filesystem.cpp @@ -0,0 +1,294 @@ +/* +fat_filesystem.cpp - ESP3D fat filesystem configuration class + + Copyright (c) 2014 Luc Lebosse. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include "../../include/esp3d_config.h" +#if (FILESYSTEM_FEATURE == ESP_FAT_FILESYSTEM) +#include "esp_filesystem.h" +#include "../../core/genLinkedList.h" +#include +#include "FFat.h" + +extern File tFile_handle[ESP_MAX_OPENHANDLE]; + +bool ESP_FileSystem::begin() +{ + _started = FFat.begin(); + return _started; +} + +void ESP_FileSystem::end() +{ + FFat.end(); + _started = false; +} + +size_t ESP_FileSystem::totalBytes() +{ + return FFat.totalBytes(); +} + +size_t ESP_FileSystem::usedBytes() +{ + return (FFat.totalBytes() - FFat.freeBytes()); +} + + +const char * ESP_FileSystem::FilesystemName() +{ + return "FAT"; +} + +bool ESP_FileSystem::format() +{ + return FFat.format(); +} + +ESP_File ESP_FileSystem::open(const char* path, uint8_t mode) +{ + //do some check + if(((strcmp(path,"/") == 0) && ((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) || (strlen(path) == 0)) { + return ESP_File(); + } + // path must start by '/' + if (path[0] != '/') { + return ESP_File(); + } + if (mode != ESP_FILE_READ) { + //check container exists + String p = path; + p.remove(p.lastIndexOf('/') +1); + if (!exists(p.c_str())) { + log_esp3d("Error opening: %s", path); + return ESP_File(); + } + } + File tmp = FFat.open(path, (mode == ESP_FILE_READ)?FILE_READ:(mode == ESP_FILE_WRITE)?FILE_WRITE:FILE_APPEND); + ESP_File esptmp(&tmp, tmp.isDirectory(),(mode == ESP_FILE_READ)?false:true, path); + return esptmp; +} + +bool ESP_FileSystem::exists(const char* path) +{ + bool res = false; + //root should always be there if started + if (strcmp(path, "/") == 0) { + return _started; + } + res = FFat.exists(path); + if (!res) { + ESP_File root = ESP_FileSystem::open(path, ESP_FILE_READ); + if (root) { + res = root.isDirectory(); + } + } + return res; +} + +bool ESP_FileSystem::remove(const char *path) +{ + return FFat.remove(path); +} + +bool ESP_FileSystem::mkdir(const char *path) +{ + return FFat.mkdir(path); +} + +bool ESP_FileSystem::rmdir(const char *path) +{ + if (!exists(path)) { + return false; + } + bool res = true; + GenLinkedList pathlist; + String p = path; + pathlist.push(p); + while (pathlist.count() > 0) { + File dir = FFat.open(pathlist.getLast().c_str()); + File f = dir.openNextFile(); + bool candelete = true; + while (f) { + if (f.isDirectory()) { + candelete = false; + String newdir = f.name(); + pathlist.push(newdir); + f.close(); + f = File(); + } else { + FFat.remove(f.name()); + f.close(); + f = dir.openNextFile(); + } + } + if (candelete) { + if (pathlist.getLast() !="/") { + res = FFat.rmdir(pathlist.getLast().c_str()); + } + pathlist.pop(); + } + dir.close(); + } + p = String(); + log_esp3d("count %d", pathlist.count()); + return res; +} + +void ESP_FileSystem::closeAll() +{ + for (uint8_t i = 0; i < ESP_MAX_OPENHANDLE; i++) { + tFile_handle[i].close(); + tFile_handle[i] = File(); + } +} + +ESP_File::ESP_File(void* handle, bool isdir, bool iswritemode, const char * path) +{ + _isdir = isdir; + _dirlist = ""; + _isfakedir = false; + _index = -1; + _filename = ""; + _name = ""; +#ifdef FILESYSTEM_TIMESTAMP_FEATURE + memset (&_lastwrite,0,sizeof(time_t)); +#endif //FILESYSTEM_TIMESTAMP_FEATURE + _iswritemode = iswritemode; + _size = 0; + if (!handle) { + return ; + } + bool set =false; + for (uint8_t i=0; (i < ESP_MAX_OPENHANDLE) && !set; i++) { + if (!tFile_handle[i]) { + tFile_handle[i] = *((File*)handle); + //filename + _filename = tFile_handle[i].name(); + + //if root + if (_filename == "/") { + _filename = "/."; + } + if (_isdir) { + if (_filename[_filename.length()-1] != '.') { + if (_filename[_filename.length()-2] != '/') { + _filename+="/"; + } + _filename+="."; + } + } + //name + if (_filename == "/.") { + _name = "/"; + } else { + _name = _filename; + if (_name.endsWith("/.")) { + _name.remove( _name.length() - 2,2); + _isfakedir = true; + _isdir = true; + } + if (_name[0] == '/') { + _name.remove( 0, 1); + } + int pos = _name.lastIndexOf('/'); + if (pos != -1) { + _name.remove( 0, pos+1); + } + } + //size + _size = tFile_handle[i].size(); + //time +#ifdef FILESYSTEM_TIMESTAMP_FEATURE + _lastwrite = tFile_handle[i].getLastWrite(); +#endif //FILESYSTEM_TIMESTAMP_FEATURE + _index = i; + //log_esp3d("Opening File at index %d",_index); + set = true; + } + } +} + +void ESP_File::close() +{ + if (_index != -1) { + //log_esp3d("Closing File at index %d", _index); + tFile_handle[_index].close(); + //reopen if mode = write + //udate size + date + if (_iswritemode && !_isdir) { + File ftmp = FFat.open(_filename.c_str()); + if (ftmp) { + _size = ftmp.size(); +#ifdef FILESYSTEM_TIMESTAMP_FEATURE + _lastwrite = ftmp.getLastWrite(); +#endif //FILESYSTEM_TIMESTAMP_FEATURE + ftmp.close(); + } + } + tFile_handle[_index] = File(); + //log_esp3d("Closing File at index %d",_index); + _index = -1; + } +} + +ESP_File ESP_File::openNextFile() +{ + if ((_index == -1) || !_isdir) { + log_esp3d("openNextFile failed"); + return ESP_File(); + } + File tmp = tFile_handle[_index].openNextFile(); + while (tmp) { + log_esp3d("tmp name :%s %s", tmp.name(), (tmp.isDirectory())?"isDir":"isFile"); + ESP_File esptmp(&tmp, tmp.isDirectory()); + esptmp.close(); + String sub = esptmp.filename(); + sub.remove(0,_filename.length()-1); + int pos = sub.indexOf("/"); + if (pos!=-1) { + //is subdir + sub = sub.substring(0,pos); + //log_esp3d("file name:%s name: %s %s sub:%s root:%s", esptmp.filename(), esptmp.name(), (esptmp.isDirectory())?"isDir":"isFile", sub.c_str(), _filename.c_str()); + String tag = "*" + sub + "*"; + //test if already in directory list + if (_dirlist.indexOf(tag) == -1) {//not in list so add it and return the info + _dirlist+= tag; + String fname = _filename.substring(0,_filename.length()-1) + sub + "/."; + //log_esp3d("Found dir name: %s filename:%s", sub.c_str(), fname.c_str()); + esptmp = ESP_File(sub.c_str(), fname.c_str()); + return esptmp; + } else { //already in list so ignore it + //log_esp3d("Dir name: %s already in list", sub.c_str()); + tmp = tFile_handle[_index].openNextFile(); + } + } else { //is file + //log_esp3d("file name:%s name: %s %s sub:%s root:%s", esptmp.filename(), esptmp.name(), (esptmp.isDirectory())?"isDir":"isFile", sub.c_str(), _filename.c_str()); + if (sub == ".") { + //log_esp3d("Dir tag, ignore it"); + tmp = tFile_handle[_index].openNextFile(); + } else { + return esptmp; + } + } + + } + return ESP_File(); +} + + +#endif //ESP_FAT_FILESYSTEM diff --git a/esp3d/src/modules/filesystem/littlefs_filesystem .cpp b/esp3d/src/modules/filesystem/littlefs_filesystem .cpp new file mode 100644 index 00000000..c4b85498 --- /dev/null +++ b/esp3d/src/modules/filesystem/littlefs_filesystem .cpp @@ -0,0 +1,320 @@ +/* +littlefs_filesystem.cpp - ESP3D littlefs filesystem configuration class + + Copyright (c) 2014 Luc Lebosse. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include "../../include/esp3d_config.h" +#if (FILESYSTEM_FEATURE == ESP_LITTLEFS_FILESYSTEM) +#include "esp_filesystem.h" +#include "../../core/genLinkedList.h" +#include +#include + +Dir tDir_handle[ESP_MAX_OPENHANDLE]; +extern File tFile_handle[ESP_MAX_OPENHANDLE]; + +bool ESP_FileSystem::begin() +{ + _started = LittleFS.begin(); + return _started; +} +void ESP_FileSystem::end() +{ + _started = false; + LittleFS.end(); +} + +size_t ESP_FileSystem::totalBytes() +{ + fs::FSInfo info; + LittleFS.info (info); + return info.totalBytes; +} + +size_t ESP_FileSystem::usedBytes() +{ + fs::FSInfo info; + LittleFS.info (info); + return info.usedBytes; +} + + +const char * ESP_FileSystem::FilesystemName() +{ + return "LittleFS"; +} + +bool ESP_FileSystem::format() +{ + return LittleFS.format(); +} + +ESP_File ESP_FileSystem::open(const char* path, uint8_t mode) +{ + //do some check + if(((strcmp(path,"/") == 0) && ((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) || (strlen(path) == 0)) { + return ESP_File(); + } + // path must start by '/' + if (path[0] != '/') { + return ESP_File(); + } + File ftmp = LittleFS.open(path, (mode == ESP_FILE_READ)?"r":(mode == ESP_FILE_WRITE)?"w":"a"); + if(ftmp) { + log_esp3d("Success openening: %s", path); + if (ftmp.isFile()){ + log_esp3d("It is a file"); + ESP_File esptmp(&ftmp, false,(mode == ESP_FILE_READ)?false:true, path); + return esptmp; + } + if (ftmp.isDirectory()){ + log_esp3d("It is a Directory"); + } + ftmp.close(); + } + log_esp3d("Opening as Directory"); + Dir dtmp = LittleFS.openDir(path); + ESP_File esptmp(&dtmp, true, false, path); + return esptmp; +} + +bool ESP_FileSystem::exists(const char* path) +{ + bool res = false; + //root should always be there if started + if (strcmp(path, "/") == 0) { + return _started; + } + String spath = path; + spath.trim(); + if (spath[spath.length()-1] == '/') { + if (spath!="/") { + spath.remove(spath.length()-1); + } + } + return LittleFS.exists(spath.c_str()); +} + +bool ESP_FileSystem::remove(const char *path) +{ + return LittleFS.remove(path); +} + +bool ESP_FileSystem::mkdir(const char *path) +{ + String spath = path; + spath.trim(); + if (spath[spath.length()-1] == '/') { + if (spath!="/") { + spath.remove(spath.length()-1); + } + } + return LittleFS.mkdir(spath.c_str()); +} + +bool ESP_FileSystem::rmdir(const char *path) +{ + if (!exists(path)) { + return false; + } + bool res = true; + GenLinkedList pathlist; + String spath = path; + spath.trim(); + if (spath[spath.length()-1] != '/') { + spath+="/"; + }if (spath[0] != '/') { + spath ="/" + spath; + } + pathlist.push(spath); + while (pathlist.count() > 0) { + spath=pathlist.getLast(); + bool candelete = true; + if (LittleFS.exists(spath.c_str())) { + Dir dir = LittleFS.openDir(pathlist.getLast().c_str()); + while (dir.next()) { + if (dir.isDirectory()) { + candelete = false; + String newdir = pathlist.getLast() + dir.fileName() + "/"; + pathlist.push(newdir); + } else { + log_esp3d("remove %s", dir.fileName().c_str()); + String s = spath + dir.fileName(); + LittleFS.remove(s); + } + } + } + if (candelete) { + if (spath !="/") { + if (spath[spath.length()-1] == '/') { + spath.remove(spath.length()-1); + } + if (LittleFS.exists(spath.c_str())) { + res = LittleFS.rmdir(spath.c_str()); + } + log_esp3d("rmdir %s %d", spath.c_str(), res); + } + pathlist.pop(); + } + } + return res; +} + +void ESP_FileSystem::closeAll() +{ + for (uint8_t i = 0; i < ESP_MAX_OPENHANDLE; i++) { + tDir_handle[i] = Dir(); + tFile_handle[i].close(); + tFile_handle[i] = File(); + } +} + +ESP_File::ESP_File(void* handle, bool isdir, bool iswritemode, const char * path) +{ + _isdir = isdir; + _dirlist = ""; + _isfakedir = false; + _index = -1; + _filename = ""; + _name = ""; +#ifdef FILESYSTEM_TIMESTAMP_FEATURE + memset (&_lastwrite,0,sizeof(time_t)); +#endif //FILESYSTEM_TIMESTAMP_FEATURE + _iswritemode = iswritemode; + _size = 0; + if (!handle) { + return ; + } + bool set =false; + if (_isdir) { + for (uint8_t i=0; (i < ESP_MAX_OPENHANDLE) && !set; i++) { + if (tDir_handle[i].fileName().length() == 0) { + tDir_handle[i] = *((Dir *)handle); + _index = i; + //Path = filename + if (path) { + _filename = path; + _filename.trim(); + if (!((_filename[_filename.length()-1] == '/') || (_filename == "/"))) { + _filename+="/"; + } + //log_esp3d("Filename: %s", _filename.c_str()); + //Name + if (_filename == "/") { + _name = "/"; + } else { + _name.remove( 0, _name.lastIndexOf('/')+1); + } + } + //log_esp3d("Name: %s index: %d", _name.c_str(), _index); + set = true; + } + } + return; + } + + for (uint8_t i=0; (i < ESP_MAX_OPENHANDLE) && !set; i++) { + if (!tFile_handle[i]) { + tFile_handle[i] = *((File*)handle); + //filename + _filename = tFile_handle[i].name(); + if (_isdir) { + if (!((_filename[_filename.length()-1] == '/') || (_filename == "/"))) { + _filename+="/"; + } + } + //name + if (_filename == "/") { + _name = "/"; + } else { + _name = _filename; + if (_name[0] == '/') { + _name.remove( 0, 1); + } + int pos = _name.lastIndexOf('/'); + if (pos != -1) { + _name.remove( 0, pos+1); + } + } + //size + _size = tFile_handle[i].size(); + //time +#ifdef FILESYSTEM_TIMESTAMP_FEATURE + _lastwrite = tFile_handle[i].getLastWrite(); +#endif //FILESYSTEM_TIMESTAMP_FEATURE + _index = i; + //log_esp3d("Opening File at index %d",_index); + set = true; + } + } +} + +void ESP_File::close() +{ + if (_index != -1) { + if (_isdir) { + //log_esp3d("Closing Dir at index %d", _index); + tDir_handle[_index] = Dir(); + _index = -1; + return; + } + //log_esp3d("Closing File at index %d", _index); + tFile_handle[_index].close(); + //reopen if mode = write + //udate size + date + if (_iswritemode && !_isdir) { + File ftmp = LittleFS.open(_filename.c_str(), "r"); + if (ftmp) { + _size = ftmp.size(); +#ifdef FILESYSTEM_TIMESTAMP_FEATURE + _lastwrite = ftmp.getLastWrite(); +#endif //FILESYSTEM_TIMESTAMP_FEATURE + ftmp.close(); + } + } + //log_esp3d("Closing File at index %d",_index); + _index = -1; + } +} + +ESP_File ESP_File::openNextFile() +{ + if ((_index == -1) || !_isdir) { + log_esp3d("openNextFile failed"); + return ESP_File(); + } + if(tDir_handle[_index].next()) { + String name = tDir_handle[_index].fileName(); + log_esp3d("Getting next file from %s", _filename.c_str()); + log_esp3d("name :%s %s", name.c_str(), (tDir_handle[_index].isDirectory())?"isDir":"isFile"); + String s = _filename; + if(s[s.length()-1]!='/')s+="/"; + s+=name.c_str(); + if (tDir_handle[_index].isFile()) { + ESP_File esptmp(name.c_str(), s.c_str(), false, tDir_handle[_index].fileSize()) ; + return esptmp; + } else { + log_esp3d("Found dir name: %s filename:%s",name.c_str(), s.c_str()); + ESP_File esptmp = ESP_File(name.c_str(), s.c_str()); + return esptmp; + } + + } + return ESP_File(); +} + +#endif //ESP_LITTLEFS_FILESYSTEM diff --git a/esp3d/src/modules/filesystem/spiffs_esp32_filesystem.cpp b/esp3d/src/modules/filesystem/spiffs_esp32_filesystem.cpp new file mode 100644 index 00000000..336cf1ca --- /dev/null +++ b/esp3d/src/modules/filesystem/spiffs_esp32_filesystem.cpp @@ -0,0 +1,308 @@ +/* + spiffs_esp32_filesystem.cpp - ESP3D filesystem configuration class + + Copyright (c) 2014 Luc Lebosse. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include "../../include/esp3d_config.h" +#if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) && defined(ARDUINO_ARCH_ESP32) +#include "esp_filesystem.h" +#include "../../core/genLinkedList.h" +#include +#include +extern File tFile_handle[ESP_MAX_OPENHANDLE]; + +bool ESP_FileSystem::begin() +{ + _started = SPIFFS.begin(true); + return _started; +} +void ESP_FileSystem::end() +{ + _started = false; + SPIFFS.end(); +} + +size_t ESP_FileSystem::totalBytes() +{ + return SPIFFS.totalBytes(); +} + +size_t ESP_FileSystem::usedBytes() +{ + return SPIFFS.usedBytes(); +} + + +const char * ESP_FileSystem::FilesystemName() +{ + return "SPIFFS"; +} + +bool ESP_FileSystem::format() +{ + return SPIFFS.format(); +} + +ESP_File ESP_FileSystem::open(const char* path, uint8_t mode) +{ + //do some check + if(((strcmp(path,"/") == 0) && ((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) || (strlen(path) == 0)) { + return ESP_File(); + } + // path must start by '/' + if (path[0] != '/') { + return ESP_File(); + } + //TODO add support if path = /DIR1/ <- with last / + File tmp = SPIFFS.open(path, (mode == ESP_FILE_READ)?FILE_READ:(mode == ESP_FILE_WRITE)?FILE_WRITE:FILE_APPEND); + ESP_File esptmp(&tmp, tmp.isDirectory(),(mode == ESP_FILE_READ)?false:true, path); + return esptmp; +} + +bool ESP_FileSystem::exists(const char* path) +{ + bool res = false; + //root should always be there if started + if (strcmp(path, "/") == 0) { + return _started; + } + String spath = path; + spath.trim(); + if (spath[spath.length()-1] == '/') { + if (spath!="/") { + spath.remove(spath.length()-1); + } + } + res = SPIFFS.exists(spath.c_str()); + if (!res) { + String newpath = spath; + if (newpath[newpath.length()-1] != '/') { + newpath+="/"; + } + newpath+="."; + //log_esp3d("Check %s", newpath.c_str()); + res = SPIFFS.exists(newpath); + if (!res) { + ESP_File f = ESP_FileSystem::open(path, ESP_FILE_READ); + if (f) { + //Check directories + ESP_File sub = f.openNextFile(); + if (sub) { + sub.close(); + res = true; + } + f.close(); + } + } + } + return res; +} + +bool ESP_FileSystem::remove(const char *path) +{ + return SPIFFS.remove(path); +} + +bool ESP_FileSystem::mkdir(const char *path) +{ + //Use file named . to simulate directory + String p = path; + if (p[p.length()-1] != '/') { + p+="/"; + } + p+="."; + //log_esp3d("Dir create : %s", p.c_str()); + ESP_File f = open(p.c_str(), ESP_FILE_WRITE); + if (f) { + f.close(); + return true; + } else { + return false; + } +} + +bool ESP_FileSystem::rmdir(const char *path) +{ + String spath = path; + spath.trim(); + if (spath[spath.length()-1] == '/') { + if (spath!="/") { + spath.remove(spath.length()-1); + } + } + log_esp3d("Deleting : %s",spath.c_str()); + File ftmp = SPIFFS.open(spath.c_str()); + if (ftmp) { + File pfile = ftmp.openNextFile(); + while (pfile) { + //log_esp3d("File: %s",pfile.name()); + if (!SPIFFS.remove(pfile.name())) { + pfile.close(); + return false; + } + pfile.close(); + pfile = ftmp.openNextFile(); + } + ftmp.close(); + return true; + } else { + return false; + } +} + +void ESP_FileSystem::closeAll() +{ + for (uint8_t i = 0; i < ESP_MAX_OPENHANDLE; i++) { + tFile_handle[i].close(); + tFile_handle[i] = File(); + } +} + +ESP_File::ESP_File(void* handle, bool isdir, bool iswritemode, const char * path) +{ + _isdir = isdir; + _dirlist = ""; + _isfakedir = false; + _index = -1; + _filename = ""; + _name = ""; +#ifdef FILESYSTEM_TIMESTAMP_FEATURE + memset (&_lastwrite,0,sizeof(time_t)); +#endif //FILESYSTEM_TIMESTAMP_FEATURE + _iswritemode = iswritemode; + _size = 0; + if (!handle) { + return ; + } + bool set =false; + for (uint8_t i=0; (i < ESP_MAX_OPENHANDLE) && !set; i++) { + if (!tFile_handle[i]) { + tFile_handle[i] = *((File*)handle); + //filename + _filename = tFile_handle[i].name(); + + //if root + if (_filename == "/") { + _filename = "/."; + } + if (_isdir) { + if (_filename[_filename.length()-1] != '.') { + if (_filename[_filename.length()-2] != '/') { + _filename+="/"; + } + _filename+="."; + } + } + //name + if (_filename == "/.") { + _name = "/"; + } else { + _name = _filename; + if (_name.endsWith("/.")) { + _name.remove( _name.length() - 2,2); + _isfakedir = true; + _isdir = true; + } + if (_name[0] == '/') { + _name.remove( 0, 1); + } + int pos = _name.lastIndexOf('/'); + if (pos != -1) { + _name.remove( 0, pos+1); + } + } + //size + _size = tFile_handle[i].size(); + //time +#ifdef FILESYSTEM_TIMESTAMP_FEATURE + _lastwrite = tFile_handle[i].getLastWrite(); +#endif //FILESYSTEM_TIMESTAMP_FEATURE + _index = i; + //log_esp3d("Opening File at index %d",_index); + set = true; + } + } +} + +void ESP_File::close() +{ + if (_index != -1) { + //log_esp3d("Closing File at index %d", _index); + tFile_handle[_index].close(); + //reopen if mode = write + //udate size + date + if (_iswritemode && !_isdir) { + File ftmp = SPIFFS.open(_filename.c_str()); + if (ftmp) { + _size = ftmp.size(); +#ifdef FILESYSTEM_TIMESTAMP_FEATURE + _lastwrite = ftmp.getLastWrite(); +#endif //FILESYSTEM_TIMESTAMP_FEATURE + ftmp.close(); + } + } + tFile_handle[_index] = File(); + //log_esp3d("Closing File at index %d",_index); + _index = -1; + } +} + +ESP_File ESP_File::openNextFile() +{ + if ((_index == -1) || !_isdir) { + log_esp3d("openNextFile failed"); + return ESP_File(); + } + File tmp = tFile_handle[_index].openNextFile(); + while (tmp) { + //log_esp3d("tmp name :%s %s", tmp.name(), (tmp.isDirectory())?"isDir":"isFile"); + ESP_File esptmp(&tmp, tmp.isDirectory()); + esptmp.close(); + String sub = esptmp.filename(); + sub.remove(0,_filename.length()-1); + int pos = sub.indexOf("/"); + if (pos!=-1) { + //is subdir + sub = sub.substring(0,pos); + //log_esp3d("file name:%s name: %s %s sub:%s root:%s", esptmp.filename(), esptmp.name(), (esptmp.isDirectory())?"isDir":"isFile", sub.c_str(), _filename.c_str()); + String tag = "*" + sub + "*"; + //test if already in directory list + if (_dirlist.indexOf(tag) == -1) {//not in list so add it and return the info + _dirlist+= tag; + String fname = _filename.substring(0,_filename.length()-1) + sub + "/."; + //log_esp3d("Found dir name: %s filename:%s", sub.c_str(), fname.c_str()); + esptmp = ESP_File(sub.c_str(), fname.c_str()); + return esptmp; + } else { //already in list so ignore it + //log_esp3d("Dir name: %s already in list", sub.c_str()); + tmp = tFile_handle[_index].openNextFile(); + } + } else { //is file + //log_esp3d("file name:%s name: %s %s sub:%s root:%s", esptmp.filename(), esptmp.name(), (esptmp.isDirectory())?"isDir":"isFile", sub.c_str(), _filename.c_str()); + if (sub == ".") { + //log_esp3d("Dir tag, ignore it"); + tmp = tFile_handle[_index].openNextFile(); + } else { + return esptmp; + } + } + } + return ESP_File(); +} + + +#endif //ESP_SPIFFS_FILESYSTEM diff --git a/esp3d/src/modules/filesystem/spiffs_esp8266_filesystem.cpp b/esp3d/src/modules/filesystem/spiffs_esp8266_filesystem.cpp new file mode 100644 index 00000000..eabb8385 --- /dev/null +++ b/esp3d/src/modules/filesystem/spiffs_esp8266_filesystem.cpp @@ -0,0 +1,353 @@ +/* + spiffs_8266_filesystem.cpp - ESP3D filesystem configuration class + + Copyright (c) 2014 Luc Lebosse. All rights reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include "../../include/esp3d_config.h" +#if (FILESYSTEM_FEATURE == ESP_SPIFFS_FILESYSTEM) && defined (ARDUINO_ARCH_ESP8266) +#include "esp_filesystem.h" +#include "../../core/genLinkedList.h" +#include +Dir tDir_handle[ESP_MAX_OPENHANDLE]; +extern File tFile_handle[ESP_MAX_OPENHANDLE]; + +bool ESP_FileSystem::begin() +{ + _started = SPIFFS.begin(); + return _started; +} +void ESP_FileSystem::end() +{ + _started = false; + SPIFFS.end(); +} + +size_t ESP_FileSystem::totalBytes() +{ + fs::FSInfo info; + SPIFFS.info (info); + return info.totalBytes; +} + +size_t ESP_FileSystem::usedBytes() +{ + fs::FSInfo info; + SPIFFS.info (info); + return info.usedBytes; +} + + +const char * ESP_FileSystem::FilesystemName() +{ + return "SPIFFS"; +} + +bool ESP_FileSystem::format() +{ + return SPIFFS.format(); +} + +ESP_File ESP_FileSystem::open(const char* path, uint8_t mode) +{ + //do some check + if(((strcmp(path,"/") == 0) && ((mode == ESP_FILE_WRITE) || (mode == ESP_FILE_APPEND))) || (strlen(path) == 0)) { + return ESP_File(); + } + // path must start by '/' + if (path[0] != '/') { + return ESP_File(); + } + File ftmp = SPIFFS.open(path, (mode == ESP_FILE_READ)?"r":(mode == ESP_FILE_WRITE)?"w":"a"); + if(ftmp) { + //log_esp3d("Success openening: %s", path); + ESP_File esptmp(&ftmp, false,(mode == ESP_FILE_READ)?false:true, path); + return esptmp; + } + (void)mode; + Dir dtmp = SPIFFS.openDir(path); + ESP_File esptmp(&dtmp, true, false, path); + return esptmp; +} + +bool ESP_FileSystem::exists(const char* path) +{ + bool res = false; + //root should always be there if started + if (strcmp(path, "/") == 0) { + return _started; + } + String spath = path; + spath.trim(); + if (spath[spath.length()-1] == '/') { + if (spath!="/") { + spath.remove(spath.length()-1); + } + } + res = SPIFFS.exists(spath.c_str()); + if (!res) { + String newpath = spath; + if (newpath[newpath.length()-1] != '/') { + newpath+="/"; + } + newpath+="."; + //log_esp3d("Check %s", newpath.c_str()); + res = SPIFFS.exists(newpath); + if (!res) { + ESP_File f = ESP_FileSystem::open(path, ESP_FILE_READ); + if (f) { + //Check directories + ESP_File sub = f.openNextFile(); + if (sub) { + sub.close(); + res = true; + } + f.close(); + } + } + } + return res; +} + +bool ESP_FileSystem::remove(const char *path) +{ + return SPIFFS.remove(path); +} + +bool ESP_FileSystem::mkdir(const char *path) +{ + //Use file named . to simulate directory + String p = path; + if (p[p.length()-1] != '/') { + p+="/"; + } + p+="."; + //log_esp3d("Dir create : %s", p.c_str()); + ESP_File f = open(p.c_str(), ESP_FILE_WRITE); + if (f) { + f.close(); + return true; + } else { + return false; + } +} + +bool ESP_FileSystem::rmdir(const char *path) +{ + Dir dtmp = SPIFFS.openDir(path); + while (dtmp.next()) { + if (!SPIFFS.remove(dtmp.fileName().c_str())) { + return false; + } + } + return true; +} + +void ESP_FileSystem::closeAll() +{ + for (uint8_t i = 0; i < ESP_MAX_OPENHANDLE; i++) { + tDir_handle[i] = Dir(); + tFile_handle[i].close(); + tFile_handle[i] = File(); + } +} + +ESP_File::ESP_File(void* handle, bool isdir, bool iswritemode, const char * path) +{ + _isdir = isdir; + _dirlist = ""; + _isfakedir = false; + _index = -1; + _filename = ""; + _name = ""; +#ifdef FILESYSTEM_TIMESTAMP_FEATURE + memset (&_lastwrite,0,sizeof(time_t)); +#endif //FILESYSTEM_TIMESTAMP_FEATURE + _iswritemode = iswritemode; + _size = 0; + if (!handle) { + return ; + } + bool set =false; + if (_isdir) { + for (uint8_t i=0; (i < ESP_MAX_OPENHANDLE) && !set; i++) { + if (tDir_handle[i].fileName().length() == 0) { + tDir_handle[i] = *((Dir *)handle); + _index = i; + //Path = filename + if (path) { + _filename = path; + if (_filename == "/") { + _filename = "/."; + } + if (_filename[_filename.length()-1] != '.') { + if (_filename[_filename.length()-2] != '/') { + _filename+="/"; + } + _filename+="."; + } + //log_esp3d("Filename: %s", _filename.c_str()); + //Name + if (_filename == "/.") { + _name = "/"; + } else { + _name = _filename; + if (_name.length() >=2) { + if ((_name[_name.length() - 1] == '.') && (_name[_name.length() - 2] == '/')) { + _name.remove( _name.length() - 2,2); + } + } + _name.remove( 0, _name.lastIndexOf('/')+1); + } + } + //log_esp3d("Name: %s index: %d", _name.c_str(), _index); + set = true; + } + } + return; + } + for (uint8_t i=0; (i < ESP_MAX_OPENHANDLE) && !set; i++) { + if (!tFile_handle[i]) { + tFile_handle[i] = *((File*)handle); + //filename + _filename = tFile_handle[i].name(); + + //if root + if (_filename == "/") { + _filename = "/."; + } + if (_isdir) { + if (_filename[_filename.length()-1] != '.') { + if (_filename[_filename.length()-2] != '/') { + _filename+="/"; + } + _filename+="."; + } + } + //name + if (_filename == "/.") { + _name = "/"; + } else { + _name = _filename; + if (_name.endsWith("/.")) { + _name.remove( _name.length() - 2,2); + _isfakedir = true; + _isdir = true; + } + if (_name[0] == '/') { + _name.remove( 0, 1); + } + int pos = _name.lastIndexOf('/'); + if (pos != -1) { + _name.remove( 0, pos+1); + } + } + //size + _size = tFile_handle[i].size(); + //time +#ifdef FILESYSTEM_TIMESTAMP_FEATURE + _lastwrite = tFile_handle[i].getLastWrite(); +#endif //FILESYSTEM_TIMESTAMP_FEATURE + _index = i; + //log_esp3d("Opening File at index %d",_index); + set = true; + } + } +} + +void ESP_File::close() +{ + if (_index != -1) { + if (_isdir && !_isfakedir) { + //log_esp3d("Closing Dir at index %d", _index); + tDir_handle[_index] = Dir(); + _index = -1; + return; + } + //log_esp3d("Closing File at index %d", _index); + tFile_handle[_index].close(); + //reopen if mode = write + //udate size + date + if (_iswritemode && !_isdir) { + File ftmp = SPIFFS.open(_filename.c_str(), "r"); + if (ftmp) { + _size = ftmp.size(); +#ifdef FILESYSTEM_TIMESTAMP_FEATURE + _lastwrite = ftmp.getLastWrite(); +#endif //FILESYSTEM_TIMESTAMP_FEATURE + ftmp.close(); + } + } + //log_esp3d("Closing File at index %d",_index); + _index = -1; + } +} + +ESP_File ESP_File::openNextFile() +{ + if ((_index == -1) || !_isdir) { + log_esp3d("openNextFile failed"); + return ESP_File(); + } + if(tDir_handle[_index].next()) { + //log_esp3d("Getting next file from %s", _filename.c_str()); + File tmp = tDir_handle[_index].openFile("r"); + while (tmp) { + ESP_File esptmp(&tmp); + esptmp.close(); + String sub = esptmp.filename(); + sub.remove(0,_filename.length()-1); + int pos = sub.indexOf("/"); + if (pos!=-1) { + //is subdir + sub = sub.substring(0,pos); + //log_esp3d("file name:%s name: %s %s sub:%s root:%s", esptmp.filename(), esptmp.name(), (esptmp.isDirectory())?"isDir":"isFile", sub.c_str(), _filename.c_str()); + String tag = "*" + sub + "*"; + //test if already in directory list + if (_dirlist.indexOf(tag) == -1) {//not in list so add it and return the info + _dirlist+= tag; + String fname = _filename.substring(0,_filename.length()-1) + sub + "/."; + //log_esp3d("Found dir name: %s filename:%s", sub.c_str(), fname.c_str()); + esptmp = ESP_File(sub.c_str(), fname.c_str()); + return esptmp; + } else { //already in list so ignore it + //log_esp3d("Dir name: %s already in list", sub.c_str()); + if(!tDir_handle[_index].next()) { + return ESP_File(); + } else { + tmp = tDir_handle[_index].openFile("r"); + } + } + } else { //is file + //log_esp3d("file name:%s name: %s %s sub:%s root:%s", esptmp.filename(), esptmp.name(), (esptmp.isDirectory())?"isDir":"isFile", sub.c_str(), _filename.c_str()); + if (sub == ".") { + //log_esp3d("Dir tag, ignore it"); + if(!tDir_handle[_index].next()) { + return ESP_File(); + } else { + tmp = tDir_handle[_index].openFile("r"); + } + } else { + return esptmp; + } + } + } + } + return ESP_File(); +} + + +#endif //ESP_SPIFFS_FILESYSTEM diff --git a/esp3d/src/modules/network/netconfig.cpp b/esp3d/src/modules/network/netconfig.cpp index 23829e33..9d5256f8 100644 --- a/esp3d/src/modules/network/netconfig.cpp +++ b/esp3d/src/modules/network/netconfig.cpp @@ -217,8 +217,9 @@ bool NetConfig::begin() bool res = false; //clear everything end(); + int8_t espMode =Settings_ESP3D::read_byte(ESP_RADIO_MODE); ESP3DOutput output(ESP_ALL_CLIENTS); - output.printMSG("Starting Network"); + if (espMode != NO_NETWORK)output.printMSG("Starting Network"); //setup events if(!_events_registered) { #ifdef ARDUINO_ARCH_ESP8266 @@ -235,7 +236,6 @@ bool NetConfig::begin() } //Get hostname _hostname = Settings_ESP3D::read_string(ESP_HOSTNAME); - int8_t espMode =Settings_ESP3D::read_byte(ESP_RADIO_MODE); _mode = espMode; if (espMode == NO_NETWORK) { ESP3DGlobalOutput::display_IP(); diff --git a/test/fatwrite/fatwrite.ino b/test/fatwrite/fatwrite.ino new file mode 100644 index 00000000..d34795c2 --- /dev/null +++ b/test/fatwrite/fatwrite.ino @@ -0,0 +1,75 @@ +/* + * full system / not flat fs + * directory mode supported + * parsing only File variables + * directory creation: yes + * parsing: one level at once + */ + +#include +#include "FFat.h" + +void setup(){ + Serial.begin(115200); + delay(5000); + Serial.printf("Format()\n"); + if (!FFat.format()) { + Serial.printf("Unable to format(), aborting\n"); + //return; + } + Serial.printf("begin()\n"); + if (!FFat.begin()) { + Serial.printf("Unable to begin(), aborting\n"); + return; + } + File f = FFat.open("/test.txt","w"); + if (f){ + Serial.printf("/test.txt created\n"); + f.print("hello world"); + f.close(); + } else { + Serial.printf("/test.txt creation failed\n"); + } + if (FFat.mkdir("/myDir")){ + Serial.printf("/myDir/ created\n"); + } else { + Serial.printf("/myDir directory creation failed\n"); + } + if (FFat.mkdir("/myDir2")){ + Serial.printf("/myDir2/ created\n"); + } else { + Serial.printf("/myDir2 directory creation failed\n"); + } + f = FFat.open("/myDir/test2.txt","w"); + if (f){ + Serial.printf("/myDir/test2.txt created\n"); + f.print("hello world"); + f.close(); + } else { + Serial.printf("/myDir/test.txt creation failed\n"); + } +} + +void loop(){ + File root = FFat.open("/"); + uint8_t nbf = 0; + uint8_t nbd = 0; + File dir = root.openNextFile(); + while (dir) { + String filename = dir.name(); + size_t fileSize = dir.size(); + if (dir.isDirectory()) + { + Serial.printf("Dir %s\n",filename.c_str() ); + nbd++; + } + if (!dir.isDirectory()) + { + Serial.printf("File %s %d\n",filename.c_str(), fileSize ); + nbf++; + } + dir = root.openNextFile(); + } + Serial.printf("NB Dir: %d, NB File: %d\n",nbd, nbf); + delay(5000); +} diff --git a/test/littlefswrite/littlefswrite.ino b/test/littlefswrite/littlefswrite.ino new file mode 100644 index 00000000..e2bd40f3 --- /dev/null +++ b/test/littlefswrite/littlefswrite.ino @@ -0,0 +1,67 @@ +#include +/* + * full system / not flat + * directory mode supported + * parsing need Dir and File variables + * directory creation / query no `/` at the end + * parsing: one level at once + */ + +void setup(){ + Serial.begin(115200); + delay(5000); + if (!LittleFS.format()) { + Serial.printf("Unable to format(), aborting\n"); + return; + } + if (!LittleFS.begin()) { + Serial.printf("Unable to begin(), aborting\n"); + return; + } + File f = LittleFS.open("/test.txt","w"); + if (f){ + Serial.printf("/test.txt created\n"); + f.write("hello world", strlen("hello world")); + f.close(); + } else { + Serial.printf("/test.txt creation failed\n"); + } + if (LittleFS.mkdir("/myDir")){ + if (LittleFS.mkdir("/myDir/mysubDir")){} + f = LittleFS.open("/myDir/test2.txt","w"); + if (f){ + Serial.printf("/myDir/test2.txt created\n"); + f.write("hello world", strlen("hello world")); + f.close(); + } else { + Serial.printf("/myDir/test.txt creation failed\n"); + } + } else { + Serial.printf("/myDir directory creation failed\n"); + } + if (!LittleFS.mkdir("/myDir/mysubDir/mysubdir2")){ + Serial.printf("/myDir/mysubDir/mysubdir2 directory creation failed\n"); + } +} + +void loop(){ + Dir dir = LittleFS.openDir("/"); + uint8_t nbf = 0; + uint8_t nbd = 0; + while (dir.next()) { + String fileName = dir.fileName(); + size_t fileSize = dir.fileSize(); + if (dir.isDirectory()) + { + Serial.printf("Dir %s\n",fileName.c_str() ); + nbd++; + } + if (dir.isFile()) + { + Serial.printf("File %s %d\n",fileName.c_str(), fileSize ); + nbf++; + } + } + Serial.printf("NB Dir: %d, NB File: %d\n",nbd, nbf); + delay(5000); +} diff --git a/test/spiffs32write/spiffs32write.ino b/test/spiffs32write/spiffs32write.ino new file mode 100644 index 00000000..6c767c02 --- /dev/null +++ b/test/spiffs32write/spiffs32write.ino @@ -0,0 +1,84 @@ +/* + * full system / flat fs + * directory mode not supported + * parsing only File variable + * directory creation: no, need fake dir using . file + * parsing: all levels at once + */ + +#include +#include + +void setup(){ + Serial.begin(115200); + delay(5000); + Serial.printf("Format()\n"); + if (!SPIFFS.format()) { + Serial.printf("Unable to format(), aborting\n"); + return; + } + Serial.printf("begin()\n"); + if (!SPIFFS.begin()) { + Serial.printf("Unable to begin(), aborting\n"); + return; + } + File f = SPIFFS.open("/test.txt","w"); + if (f){ + Serial.printf("/test.txt created\n"); + f.print("hello world"); + f.close(); + } else { + Serial.printf("/test.txt creation failed\n"); + } + if (SPIFFS.mkdir("/myDir")){ + Serial.printf("/myDir/ created\n"); + } else { + Serial.printf("/myDir directory creation failed\n"); + } + if (SPIFFS.mkdir("/myDir2")){ + Serial.printf("/myDir2/ created\n"); + } else { + Serial.printf("/myDir2 directory creation failed\n"); + } + f = SPIFFS.open("/myDir/test2.txt","w"); + if (f){ + Serial.printf("/myDir/test2.txt created\n"); + f.print("hello world"); + f.close(); + } else { + Serial.printf("/myDir/test.txt creation failed\n"); + } + f = SPIFFS.open("/myDir/mysubdir/.","w"); + if (f) { + Serial.printf("/myDir/mysubdir/. created\n"); + f.close(); + } else { + Serial.printf("/myDir/mysubdir/. creation failed\n"); + } + + +} + +void loop(){ + File root = SPIFFS.open("/"); + uint8_t nbf = 0; + uint8_t nbd = 0; + File dir = root.openNextFile(); + while (dir) { + String filename = dir.name(); + size_t fileSize = dir.size(); + if (dir.isDirectory()) + { + Serial.printf("Dir %s\n",filename.c_str() ); + nbd++; + } + if (!dir.isDirectory()) + { + Serial.printf("File %s %d\n",filename.c_str(), fileSize ); + nbf++; + } + dir = root.openNextFile(); + } + Serial.printf("NB Dir: %d, NB File: %d\n",nbd, nbf); + delay(5000); +} diff --git a/test/spiffs8266write/spiffs8266write.ino b/test/spiffs8266write/spiffs8266write.ino new file mode 100644 index 00000000..df3ddae3 --- /dev/null +++ b/test/spiffs8266write/spiffs8266write.ino @@ -0,0 +1,76 @@ +/* + * full system / flat fs + * directory mode not supported ? + * parsing need Dir and File variables + * directory creation: no, need fake dir using . file + * parsing: all levels at once + */ + +#include + +void setup(){ + Serial.begin(115200); + delay(5000); + Serial.printf("Format()\n"); + // if (!SPIFFS.format()) { + // Serial.printf("Unable to format(), aborting\n"); + // return; + // } + Serial.printf("begin()\n"); + if (!SPIFFS.begin()) { + Serial.printf("Unable to begin(), aborting\n"); + return; + } + File f = SPIFFS.open("/test.txt","w"); + if (f){ + Serial.printf("/test.txt created\n"); + f.write("hello world", strlen("hello world")); + f.close(); + } else { + Serial.printf("/test.txt creation failed\n"); + } + if (SPIFFS.mkdir("/myDir")){ + Serial.printf("/myDir/ created\n"); + } else { + Serial.printf("/myDir directory creation failed\n"); + } + f = SPIFFS.open("/myDir/test2.txt","w"); + if (f){ + Serial.printf("/myDir/test2.txt created\n"); + f.write("hello world", strlen("hello world")); + f.close(); + } else { + Serial.printf("/myDir/test.txt creation failed\n"); + } + f = SPIFFS.open("/myDir/mysubdir/.","w"); + if (f) { + Serial.printf("/myDir/mysubdir/. created\n"); + f.close(); + } else { + Serial.printf("/myDir/mysubdir/. creation failed\n"); + } + + +} + +void loop(){ + Dir dir = SPIFFS.openDir("/"); + uint8_t nbf = 0; + uint8_t nbd = 0; + while (dir.next()) { + String fileName = dir.fileName(); + size_t fileSize = dir.fileSize(); + if (dir.isDirectory()) + { + Serial.printf("Dir %s\n",fileName.c_str() ); + nbd++; + } + if (dir.isFile()) + { + Serial.printf("File %s %d\n",fileName.c_str(), fileSize ); + nbf++; + } + } + Serial.printf("NB Dir: %d, NB File: %d\n",nbd, nbf); + delay(5000); +}