mirror of
https://github.com/arendst/Tasmota.git
synced 2025-07-29 05:36:39 +00:00
Update xdrv_98_filesystem.ino
This commit is contained in:
parent
2dd3065aff
commit
0a882f53ba
@ -17,17 +17,19 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/*
|
||||
this driver adds universal file system support for
|
||||
ESP8266 (sd card or littlfs on > 1 M devices with special linker file e.g. eagle.flash.4m2m.ld)
|
||||
(makes no sense on 1M devices without sd card)
|
||||
and
|
||||
ESP32 (sd card or little fs or sfatfile system)
|
||||
the sd card chip select is the standard SPI_CS or when not found SDCARD_CS_PIN
|
||||
initializes the FS System Pointer ufsp which can be used by all standard file system calls
|
||||
the only specific call is ufs_fsinfo() which gets the total size (0) and free size (1)
|
||||
a button is created in the setup section to show up the file directory to download and upload files
|
||||
subdirectories are supported
|
||||
#ifdef USE_UFILESYS
|
||||
/*********************************************************************************************\
|
||||
This driver adds universal file system support for ESP8266 (sd card or littlfs on > 1 M devices
|
||||
with special linker file e.g. eagle.flash.4m2m.ld) (makes no sense on 1M devices without sd card)
|
||||
and ESP32 (sd card or little fs or sfatfile system).
|
||||
|
||||
The sd card chip select is the standard SDCARD_CS or when not found SDCARD_CS_PIN and initializes
|
||||
the FS System Pointer ufsp which can be used by all standard file system calls.
|
||||
|
||||
The only specific call is ufs_fsinfo() which gets the total size (0) and free size (1).
|
||||
|
||||
A button is created in the setup section to show up the file directory to download and upload files
|
||||
subdirectories are supported.
|
||||
|
||||
console calls :
|
||||
|
||||
@ -36,32 +38,32 @@ ufstype get filesytem type 0=none 1=SD 2=Flashfile
|
||||
ufssize total size in kB
|
||||
ufsfree free size in kB
|
||||
|
||||
driver enabled by
|
||||
|
||||
#define USE_UFILESYS
|
||||
|
||||
*/
|
||||
|
||||
|
||||
#ifdef USE_UFILESYS
|
||||
The driver enabled by #define USE_UFILESYS
|
||||
\*********************************************************************************************/
|
||||
|
||||
#define XDRV_98 98
|
||||
|
||||
#ifndef SDCARD_CS_PIN
|
||||
#define SDCARD_CS_PIN 4
|
||||
#endif
|
||||
|
||||
#ifdef ESP8266
|
||||
#include <LittleFS.h>
|
||||
#include <SPI.h>
|
||||
#ifdef USE_SDCARD
|
||||
#include <SD.h>
|
||||
#include <SDFAT.h>
|
||||
#endif
|
||||
#else
|
||||
#endif // USE_SDCARD
|
||||
#endif // ESP8266
|
||||
|
||||
#ifdef ESP32
|
||||
#include <LITTLEFS.h>
|
||||
#ifdef USE_SDCARD
|
||||
#include <SD.h>
|
||||
#endif
|
||||
#endif // USE_SDCARD
|
||||
#include "FFat.h"
|
||||
#include "FS.h"
|
||||
#endif
|
||||
#endif // ESP32
|
||||
|
||||
#define UFS_FILE_WRITE "w"
|
||||
#define UFS_FILE_READ "r"
|
||||
@ -71,11 +73,6 @@ FS *ufsp;
|
||||
char ufs_path[48];
|
||||
File ufs_upload_file;
|
||||
|
||||
|
||||
#ifndef SDCARD_CS_PIN
|
||||
#define SDCARD_CS_PIN 4
|
||||
#endif
|
||||
|
||||
// 0 = none, 1 = SD, 2 = ffat, 3 = littlefs
|
||||
// spiffs should be obsolete
|
||||
uint8_t ufs_type;
|
||||
@ -92,19 +89,20 @@ void UFSInit(void) {
|
||||
|
||||
|
||||
#ifdef USE_SDCARD
|
||||
// if (TasmotaGlobal.spi_enabled) {
|
||||
if (1) {
|
||||
if (TasmotaGlobal.spi_enabled) {
|
||||
// if (1) {
|
||||
int8_t cs = SDCARD_CS_PIN;
|
||||
if (PinUsed(GPIO_SPI_CS)) {
|
||||
cs = Pin(GPIO_SPI_CS);
|
||||
if (PinUsed(GPIO_SDCARD_CS)) {
|
||||
cs = Pin(GPIO_SDCARD_CS);
|
||||
}
|
||||
|
||||
if (SD.begin(cs)) {
|
||||
#ifdef ESP8266
|
||||
ufsp = (FS*)&SD;
|
||||
#else
|
||||
#endif // ESP8266
|
||||
#ifdef ESP32
|
||||
ufsp = &SD;
|
||||
#endif
|
||||
#endif // ESP32
|
||||
ufs_type = UFS_TSDC;
|
||||
return;
|
||||
}
|
||||
@ -117,7 +115,8 @@ void UFSInit(void) {
|
||||
if (!LittleFS.begin()) {
|
||||
return;
|
||||
}
|
||||
#else
|
||||
#endif // ESP8266
|
||||
#ifdef ESP32
|
||||
// try lfs first
|
||||
ufsp = &LITTLEFS;
|
||||
if (!LITTLEFS.begin(true)) {
|
||||
@ -129,33 +128,35 @@ void UFSInit(void) {
|
||||
ufs_type = UFS_TFAT;
|
||||
return;
|
||||
}
|
||||
#endif // ESP8266
|
||||
#endif // ESP32
|
||||
ufs_type = UFS_TLFS;
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t ufs_fsinfo(uint32_t sel) {
|
||||
uint32_t result = 0;
|
||||
|
||||
#ifdef ESP8266
|
||||
FSInfo64 fsinfo;
|
||||
#endif
|
||||
#endif // ESP8266
|
||||
|
||||
switch (ufs_type) {
|
||||
case UFS_TSDC:
|
||||
#ifdef USE_SDCARD
|
||||
#ifdef ESP32
|
||||
if (sel == 0) {
|
||||
result = SD.totalBytes();
|
||||
} else {
|
||||
result = (SD.totalBytes() - SD.usedBytes());
|
||||
}
|
||||
#else
|
||||
#ifdef ESP8266
|
||||
ufsp->info64(fsinfo);
|
||||
if (sel == 0) {
|
||||
result = fsinfo.totalBytes;
|
||||
} else {
|
||||
result = (fsinfo.totalBytes - fsinfo.usedBytes);
|
||||
}
|
||||
#endif // ESP8266
|
||||
#ifdef ESP32
|
||||
if (sel == 0) {
|
||||
result = SD.totalBytes();
|
||||
} else {
|
||||
result = (SD.totalBytes() - SD.usedBytes());
|
||||
}
|
||||
#endif
|
||||
#endif //USE_SDCARD
|
||||
break;
|
||||
@ -168,13 +169,14 @@ FSInfo64 fsinfo;
|
||||
} else {
|
||||
result = (fsinfo.totalBytes - fsinfo.usedBytes);
|
||||
}
|
||||
#else
|
||||
#endif // ESP8266
|
||||
#ifdef ESP32
|
||||
if (sel == 0) {
|
||||
result = LITTLEFS.totalBytes();
|
||||
} else {
|
||||
result = LITTLEFS.totalBytes() - LITTLEFS.usedBytes();
|
||||
}
|
||||
#endif // ESP8266
|
||||
#endif // ESP32
|
||||
break;
|
||||
|
||||
case UFS_TFAT:
|
||||
@ -200,21 +202,20 @@ FSInfo64 fsinfo;
|
||||
#endif
|
||||
|
||||
uint8_t ufs_reject(char *name) {
|
||||
|
||||
char *lcp = strrchr(name,'/');
|
||||
if (lcp) {
|
||||
name = lcp + 1;
|
||||
}
|
||||
|
||||
while (*name=='/') name++;
|
||||
if (*name=='_') return 1;
|
||||
if (*name=='.') return 1;
|
||||
while (*name=='/') { name++; }
|
||||
if (*name=='_') { return 1; }
|
||||
if (*name=='.') { return 1; }
|
||||
|
||||
if (!strncasecmp(name, "SPOTLI~1", REJCMPL)) return 1;
|
||||
if (!strncasecmp(name, "TRASHE~1", REJCMPL)) return 1;
|
||||
if (!strncasecmp(name, "FSEVEN~1", REJCMPL)) return 1;
|
||||
if (!strncasecmp(name, "SYSTEM~1", REJCMPL)) return 1;
|
||||
if (!strncasecmp(name, "System Volume", 13)) return 1;
|
||||
if (!strncasecmp(name, "SPOTLI~1", REJCMPL)) { return 1; }
|
||||
if (!strncasecmp(name, "TRASHE~1", REJCMPL)) { return 1; }
|
||||
if (!strncasecmp(name, "FSEVEN~1", REJCMPL)) { return 1; }
|
||||
if (!strncasecmp(name, "SYSTEM~1", REJCMPL)) { return 1; }
|
||||
if (!strncasecmp(name, "System Volume", 13)) { return 1; }
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -225,7 +226,7 @@ void UFS_form1000(uint32_t number, char *dp, char sc) {
|
||||
char *sp = str;
|
||||
uint32_t inum = strlen(sp)/3;
|
||||
uint32_t fnum = strlen(sp)%3;
|
||||
if (!fnum) inum--;
|
||||
if (!fnum) { inum--; }
|
||||
for (uint32_t count = 0; count <= inum; count++) {
|
||||
if (fnum) {
|
||||
memcpy(dp, sp, fnum);
|
||||
@ -244,16 +245,16 @@ void UFS_form1000(uint32_t number, char *dp, char sc) {
|
||||
*dp = 0;
|
||||
}
|
||||
|
||||
|
||||
const char kUFSCommands[] PROGMEM = "UFS" "|" // Prefix
|
||||
"|" "TYPE" "|" "SIZE" "|" "FREE";
|
||||
const char kUFSCommands[] PROGMEM = "Ufs" "|" // Prefix
|
||||
"|" "Type" "|" "Size" "|" "Free";
|
||||
|
||||
void (* const kUFSCommand[])(void) PROGMEM = {
|
||||
&UFS_info, &UFS_type, &UFS_size, &UFS_free};
|
||||
|
||||
void UFS_info(void) {
|
||||
Response_P(PSTR("{\"UFS\":{\"TYPE\":%d,\"SIZE\":%d,\"FREE\":%d}}"),ufs_type,ufs_fsinfo(0),ufs_fsinfo(1));
|
||||
Response_P(PSTR("{\"Ufs\":{\"Type\":%d,\"Size\":%d,\"Free\":%d}}"), ufs_type, ufs_fsinfo(0), ufs_fsinfo(1));
|
||||
}
|
||||
|
||||
void UFS_type(void) {
|
||||
ResponseCmndNumber(ufs_type);
|
||||
}
|
||||
@ -324,7 +325,6 @@ void UFSdirectory(void) {
|
||||
WSContentSpaceButton(BUTTON_CONFIGURATION);
|
||||
WSContentStop();
|
||||
Web.upload_error = 0;
|
||||
|
||||
}
|
||||
|
||||
void UFS_ListDir(char *path, uint8_t depth) {
|
||||
@ -338,10 +338,13 @@ void UFS_ListDir(char *path, uint8_t depth) {
|
||||
dir.rewindDirectory();
|
||||
if (strlen(path)>1) {
|
||||
snprintf_P(npath, sizeof(npath), PSTR("http://%s/ufsd?download=%s"), WiFi.localIP().toString().c_str(), path);
|
||||
for (uint8_t cnt = strlen(npath) - 1; cnt>0; cnt--) {
|
||||
for (uint32_t cnt = strlen(npath) - 1; cnt > 0; cnt--) {
|
||||
if (npath[cnt] == '/') {
|
||||
if (npath[cnt - 1]=='=') npath[cnt + 1] = 0;
|
||||
else npath[cnt] = 0;
|
||||
if (npath[cnt - 1] == '=') {
|
||||
npath[cnt + 1] = 0;
|
||||
} else {
|
||||
npath[cnt] = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -355,17 +358,17 @@ void UFS_ListDir(char *path, uint8_t depth) {
|
||||
}
|
||||
// esp32 returns path here, shorten to filename
|
||||
ep = (char*)entry.name();
|
||||
if (*ep=='/') ep++;
|
||||
if (*ep == '/') { ep++; }
|
||||
char *lcp = strrchr(ep,'/');
|
||||
if (lcp) {
|
||||
ep = lcp + 1;
|
||||
}
|
||||
time_t tm = entry.getLastWrite();
|
||||
char tstr[24];
|
||||
strftime(tstr, 22, "%d-%m-%Y - %H:%M:%S ", localtime(&tm));
|
||||
strftime(tstr, 22, "%d-%m-%Y - %H:%M:%S ", localtime(&tm)); // Theo note to me. Isn't strftime expensive? SHould use ISO Date/Time
|
||||
|
||||
char *pp = path;
|
||||
if (!*(pp + 1)) pp++;
|
||||
if (!*(pp + 1)) { pp++; }
|
||||
char *cp = name;
|
||||
// osx formatted disks contain a lot of stuff we dont want
|
||||
if (!ufs_reject((char*)ep)) {
|
||||
@ -401,13 +404,13 @@ uint8_t UFS_DownloadFile(char *file) {
|
||||
WiFiClient download_Client;
|
||||
|
||||
if (!ufsp->exists(file)) {
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("file not found"));
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("UFS: File not found"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
download_file = ufsp->open(file, UFS_FILE_READ);
|
||||
if (!download_file) {
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("could not open file"));
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("UFS: Could not open file"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -423,7 +426,7 @@ uint8_t UFS_DownloadFile(char *file) {
|
||||
|
||||
char attachment[100];
|
||||
char *cp;
|
||||
for (uint8_t cnt = strlen(file); cnt>=0; cnt--) {
|
||||
for (uint32_t cnt = strlen(file); cnt >= 0; cnt--) {
|
||||
if (file[cnt] == '/') {
|
||||
cp = &file[cnt + 1];
|
||||
break;
|
||||
@ -434,14 +437,14 @@ uint8_t UFS_DownloadFile(char *file) {
|
||||
WSSend(200, CT_STREAM, "");
|
||||
|
||||
uint8_t buff[512];
|
||||
uint16_t bread;
|
||||
uint32_t bread;
|
||||
|
||||
// transfer is about 150kb/s
|
||||
uint8_t cnt = 0;
|
||||
uint32_t cnt = 0;
|
||||
while (download_file.available()) {
|
||||
bread = download_file.read(buff, sizeof(buff));
|
||||
uint16_t bw = download_Client.write((const char*)buff, bread);
|
||||
if (!bw) break;
|
||||
uint32_t bw = download_Client.write((const char*)buff, bread);
|
||||
if (!bw) { break; }
|
||||
cnt++;
|
||||
if (cnt > 7) {
|
||||
cnt = 0;
|
||||
@ -464,11 +467,15 @@ void UFS_Upload(void) {
|
||||
sprintf(npath, "%s/%s", ufs_path, upload.filename.c_str());
|
||||
ufsp->remove(npath);
|
||||
ufs_upload_file = ufsp->open(npath, UFS_FILE_WRITE);
|
||||
if (!ufs_upload_file) Web.upload_error = 1;
|
||||
} else if(upload.status == UPLOAD_FILE_WRITE) {
|
||||
if (ufs_upload_file) ufs_upload_file.write(upload.buf, upload.currentSize);
|
||||
} else if(upload.status == UPLOAD_FILE_END) {
|
||||
if (ufs_upload_file) ufs_upload_file.close();
|
||||
if (!ufs_upload_file) { Web.upload_error = 1; }
|
||||
}
|
||||
else if (upload.status == UPLOAD_FILE_WRITE) {
|
||||
if (ufs_upload_file) {
|
||||
ufs_upload_file.write(upload.buf, upload.currentSize);
|
||||
}
|
||||
}
|
||||
else if (upload.status == UPLOAD_FILE_END) {
|
||||
if (ufs_upload_file) { ufs_upload_file.close(); }
|
||||
if (Web.upload_error) {
|
||||
AddLog_P(LOG_LEVEL_INFO, PSTR("HTP: upload error"));
|
||||
}
|
||||
@ -513,7 +520,10 @@ bool Xdrv98(uint8_t function) {
|
||||
case FUNC_WEB_ADD_HANDLER:
|
||||
Webserver->on("/ufsd", UFSdirectory);
|
||||
Webserver->on("/ufsu", HTTP_GET, UFSFileUploadSuccess);
|
||||
Webserver->on("/ufsu", HTTP_POST,[]() { Webserver->sendHeader("Location","/ufsu");Webserver->send(303);}, UFS_Upload);
|
||||
Webserver->on("/ufsu", HTTP_POST,[]() {
|
||||
Webserver->sendHeader("Location","/ufsu");
|
||||
Webserver->send(303);
|
||||
}, UFS_Upload);
|
||||
break;
|
||||
#endif // USE_WEBSERVER
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user