/* support_filesystem.ino - Filesystem support for Tasmota Copyright (C) 2020 Theo Arends This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program 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 General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /*********************************************************************************************\ * ESP32 Filesystem Support \*********************************************************************************************/ #ifdef ESP32 #ifdef USE_TFS //#define USE_LITTLEFS // LittleFS not tested yet as currently ESP8266 only //#define USE_FFAT // FFat minimal 983k partition (4096 sector size) - tested #define USE_SPIFFS // SPIFFS - tested #ifdef USE_LITTLEFS #include #define TASMOTA_FS LittleFS #endif #ifdef USE_FFAT #include #define TASMOTA_FS FFat #endif #ifdef USE_SPIFFS #include #define TASMOTA_FS SPIFFS #endif bool TfsInit(void) { static uint8_t FsMounted = 0; if (FsMounted) { return FsMounted -1; } AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: Mounting...")); if (!TASMOTA_FS.begin()) { AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: Formatting...")); TASMOTA_FS.format(); if (!TASMOTA_FS.begin()) { AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: Failed")); FsMounted = 1; // false return false; } } AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: Mounted")); FsMounted = 2; // true return true; } bool TfsFileExists(const char *fname){ if (!TfsInit()) { return false; } bool yes = false; File file = TASMOTA_FS.open(fname, "r"); if (!file.isDirectory()) { yes = true; } else { AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: File not found")); } file.close(); return yes; } bool TfsSaveFile(const char *fname, const uint8_t *buf, uint32_t len) { if (!TfsInit()) { return false; } File file = TASMOTA_FS.open(fname, "w"); if (!file) { AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: Save failed")); return false; } file.write(buf, len); file.close(); return true; } bool TfsEraseFile(const char *fname, uint32_t len) { if (!TfsInit()) { return false; } File file = TASMOTA_FS.open(fname, "w"); if (!file) { AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: Erase failed")); return false; } uint8_t init_value = 0xff; for (uint32_t i = 0; i < len; i++) { file.write(&init_value, 1); } file.close(); return true; } bool TfsLoadFile(const char *fname, uint8_t *buf, uint32_t len) { if (!TfsInit()) { return false; } if (!TfsFileExists(fname)) { return false; } File file = TASMOTA_FS.open(fname, "r"); if (!file) { AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: File not found")); return false; } file.read(buf, len); file.close(); return true; } void TfsInfo(void) { if (!TfsInit()) { return; } uint32_t total_bytes = TASMOTA_FS.totalBytes(); #ifdef USE_SPIFFS uint32_t used_bytes = TASMOTA_FS.usedBytes(); #endif // USE_SPIFFS #ifdef USE_FFAT uint32_t used_bytes = total_bytes - TASMOTA_FS.freeBytes(); #endif // USE_FFAT AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: Used %d/%d bytes"), used_bytes, total_bytes); File root = TASMOTA_FS.open("/"); File file = root.openNextFile(); while (file) { String filename = file.name(); size_t filesize = file.size(); AddLog_P(LOG_LEVEL_INFO, PSTR("TFS: File %s, size %d"), filename.c_str(), filesize); file = root.openNextFile(); } } #endif // USE_TFS #endif // ESP32