stability improvements

- changed ESPAsyncWebServer and AsyncTCP (both not properly maintained for more than 5 years) to more recent fork with bugfixes
- fixed concurrency issues in /imgupload. Hurts the upload performance a lot, but probably that's not a real issue. Parallel uploads are now possible (still within the max 5 TCP connection limit)
This commit is contained in:
Nic Limper
2024-01-21 11:04:35 +01:00
parent fd13cccdd9
commit 83bd0ec177
4 changed files with 86 additions and 57 deletions

View File

@@ -4,7 +4,13 @@
platform = espressif32
framework = arduino
lib_deps =
https://github.com/me-no-dev/ESPAsyncWebServer
; original ESPAsyncWebServer
; https://github.com/me-no-dev/ESPAsyncWebServer
; alternative AsyncTCP + ESPAsyncwebserver fork
https://github.com/yubox-node-org/ESPAsyncWebServer#yuboxfixes-0xFEEDC0DE64-cleanup
https://github.com/yubox-node-org/AsyncTCPSock
bblanchon/ArduinoJson@^6.19.4
bodmer/TFT_eSPI
https://github.com/Bodmer/TJpg_Decoder.git
@@ -12,6 +18,9 @@ lib_deps =
https://github.com/nlimper/QRCodeGenerator
fastled/FastLED
https://github.com/MajenkoLibraries/SoftSPI
lib_ignore =
; Replaced with better version (AsyncTCPSock)
AsyncTCP
platform_packages =
board_build.filesystem = littlefs
monitor_filters = esp32_exception_decoder

View File

@@ -144,7 +144,7 @@ void setup() {
config.runStatus = RUNSTATUS_PAUSE;
}
xTaskCreate(delayedStart, "delaystart", 2000, NULL, 2, NULL);
xTaskCreate(delayedStart, "delaystart", 5000, NULL, 2, NULL);
wsSendSysteminfo();
util::printHeap();

View File

@@ -450,6 +450,17 @@ void cleanupCurrent() {
file = dir.openNextFile();
}
dir.close();
dir = contentFS->open("/temp");
file = dir.openNextFile();
while (file) {
String filename = file.name();
filename = file.path();
file.close();
contentFS->remove(filename);
file = dir.openNextFile();
}
dir.close();
}
void pushTagInfo(tagRecord* taginfo) {

View File

@@ -667,69 +667,78 @@ void init_web() {
}
void doImageUpload(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final) {
static bool imageUploadBusy = false;
Serial.println("upload part " + String(index));
String uploadfilename;
if (!index) {
if (config.runStatus != RUNSTATUS_RUN || imageUploadBusy) {
if (config.runStatus != RUNSTATUS_RUN) {
request->send(409, "text/plain", "Come back later");
return;
}
if (request->hasParam("mac", true)) {
filename = request->getParam("mac", true)->value() + ".jpg";
} else {
filename = "unknown.jpg";
}
imageUploadBusy = true;
logLine("http imageUpload " + filename);
xSemaphoreTake(fsMutex, portMAX_DELAY);
request->_tempFile = contentFS->open("/" + filename, "w");
}
if (len) {
request->_tempFile.write(data, len);
}
if (final) {
request->_tempFile.close();
xSemaphoreGive(fsMutex);
if (request->hasParam("mac", true)) {
String dst = request->getParam("mac", true)->value();
uint8_t mac[8];
if (hex2mac(dst, mac)) {
tagRecord *taginfo = tagRecord::findByMAC(mac);
if (taginfo != nullptr) {
uint8_t dither = 1;
if (request->hasParam("dither", true)) {
dither = request->getParam("dither", true)->value().toInt();
}
uint32_t ttl = 0;
if (request->hasParam("ttl", true)) {
ttl = request->getParam("ttl", true)->value().toInt();
}
uint8_t preload = 0;
uint8_t preloadlut = 0;
uint8_t preloadtype = 0;
if (request->hasParam("preloadtype", true)) {
preload = 1;
preloadtype = request->getParam("preloadtype", true)->value().toInt();
if (request->hasParam("preloadlut", true)) {
preloadlut = request->getParam("preloadlut", true)->value().toInt();
}
}
taginfo->modeConfigJson = "{\"filename\":\"" + dst + ".jpg\",\"timetolive\":\"" + String(ttl) + "\",\"dither\":\"" + String(dither) + "\",\"delete\":\"1\", \"preload\":\"" + String(preload) + "\", \"preload_lut\":\"" + String(preloadlut) + "\", \"preload_type\":\"" + String(preloadtype) + "\"}";
if (request->hasParam("contentmode", true)) {
taginfo->contentMode = request->getParam("contentmode", true)->value().toInt();
} else {
taginfo->contentMode = 24;
}
taginfo->nextupdate = 0;
wsSendTaginfo(mac, SYNC_USERCFG);
request->send(200, "text/plain", "Ok, saved");
} else {
request->send(400, "text/plain", "mac not found");
}
}
uploadfilename = request->getParam("mac", true)->value() + "_" + String(millis()) + ".jpg";
} else {
request->send(400, "text/plain", "parameters incomplete");
return;
}
logLine("http imageUpload " + uploadfilename);
request->_tempObject = (void *)new String(uploadfilename);
}
String *savedFilename = static_cast<String *>(request->_tempObject);
if (savedFilename != nullptr) {
uploadfilename = *savedFilename;
if (len) {
xSemaphoreTake(fsMutex, portMAX_DELAY);
File file = contentFS->open("/temp/" + uploadfilename, "a");
if (file) {
file.seek(index);
file.write(data, len);
file.close();
} else {
logLine("Failed to open file for appending: " + uploadfilename);
}
xSemaphoreGive(fsMutex);
}
if (final) {
Serial.println("upload final");
if (request->hasParam("mac", true)) {
String dst = request->getParam("mac", true)->value();
uint8_t mac[8];
if (hex2mac(dst, mac)) {
tagRecord *taginfo = tagRecord::findByMAC(mac);
if (taginfo != nullptr) {
uint8_t dither = 1;
if (request->hasParam("dither", true)) {
dither = request->getParam("dither", true)->value().toInt();
}
uint32_t ttl = 0;
if (request->hasParam("ttl", true)) {
ttl = request->getParam("ttl", true)->value().toInt();
}
uint8_t preload = 0;
uint8_t preloadlut = 0;
uint8_t preloadtype = 0;
if (request->hasParam("preloadtype", true)) {
preload = 1;
preloadtype = request->getParam("preloadtype", true)->value().toInt();
if (request->hasParam("preloadlut", true)) {
preloadlut = request->getParam("preloadlut", true)->value().toInt();
}
}
taginfo->modeConfigJson = "{\"filename\":\"/temp/" + uploadfilename + "\",\"timetolive\":\"" + String(ttl) + "\",\"dither\":\"" + String(dither) + "\",\"delete\":\"1\", \"preload\":\"" + String(preload) + "\", \"preload_lut\":\"" + String(preloadlut) + "\", \"preload_type\":\"" + String(preloadtype) + "\"}";
if (request->hasParam("contentmode", true)) {
taginfo->contentMode = request->getParam("contentmode", true)->value().toInt();
} else {
taginfo->contentMode = 24;
}
taginfo->nextupdate = 0;
wsSendTaginfo(mac, SYNC_USERCFG);
request->send(200, "text/plain", "Ok, saved");
} else {
request->send(400, "text/plain", "mac not found");
}
}
}
}
imageUploadBusy = false;
}
}