From f64c8dfece1ab99919a4a00776bedf8997c8cd3e Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 29 Nov 2024 12:12:46 -0500 Subject: [PATCH 01/19] Made an error message easier to understand --- src/input/InputFPPRemotePlayFile.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/input/InputFPPRemotePlayFile.cpp b/src/input/InputFPPRemotePlayFile.cpp index dd0d9995e..e27479662 100644 --- a/src/input/InputFPPRemotePlayFile.cpp +++ b/src/input/InputFPPRemotePlayFile.cpp @@ -368,7 +368,7 @@ bool c_InputFPPRemotePlayFile::ParseFseqFile () { LastFailedPlayStatusMsg = (String (F ("ParseFseqFile:: Could not start: ")) + PlayItemName + F (" File does not contain enough data to meet the Stated Channel Count * Number of Frames value. Need: ") + - String (NeededDataSize) + F (", Got: ") + String (ActualDataSize)); + String (NeededDataSize) + F (", SD File Size: ") + String (ActualDataSize)); logcon (LastFailedPlayStatusMsg); break; } From 41bb590f380e7254dd09f5b0b2f2419b041943af Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 29 Nov 2024 12:13:43 -0500 Subject: [PATCH 02/19] Added protection against spurious Watchdog timeouts while processing the output data. --- src/input/InputFPPRemote.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/input/InputFPPRemote.cpp b/src/input/InputFPPRemote.cpp index 1c2720f18..442eb993d 100644 --- a/src/input/InputFPPRemote.cpp +++ b/src/input/InputFPPRemote.cpp @@ -51,10 +51,12 @@ void FppRemoteTask (void *arg) PollTime = pdMS_TO_TICKS(1); } vTaskDelay(PollTime); + FeedWDT(); PollStartTime = millis(); pFppRemoteInstance->TaskProcess(); + FeedWDT(); // record the loop end time PollEndTime = millis(); From bc75b478bfaaf8b22b778e26f20b19281e1a0576 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 29 Nov 2024 12:14:52 -0500 Subject: [PATCH 03/19] Fixed a bug in the debug output. --- src/service/FPPDiscovery.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/service/FPPDiscovery.cpp b/src/service/FPPDiscovery.cpp index b9203772f..598d50ce8 100644 --- a/src/service/FPPDiscovery.cpp +++ b/src/service/FPPDiscovery.cpp @@ -499,7 +499,7 @@ static void printReq (AsyncWebServerRequest* request, bool post) for (int i = 0; i < params; i++) { // DEBUG_V (String ("current Param: ") + String (i)); - AsyncWebParameter* p = request->getParam (i); + const AsyncWebParameter* p = request->getParam (i); // DEBUG_V (String (" p->name: ") + String (p->name())); // DEBUG_V (String (" p->value: ") + String (p->value())); From fa6c2d7b83172230a2e3300e6b36a2073899d4f2 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 29 Nov 2024 12:41:44 -0500 Subject: [PATCH 04/19] Enhanced the sync code to only slide the frame count forward or back one frame at a time. Reduces the jerkiness when a major adjustment is in progress. Also added code to make a large adjustment if the code is way off (such as starting in the middle of a sequence), --- src/input/InputFPPRemotePlayFileFsm.cpp | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/input/InputFPPRemotePlayFileFsm.cpp b/src/input/InputFPPRemotePlayFileFsm.cpp index abd051001..9b5f9a03f 100644 --- a/src/input/InputFPPRemotePlayFileFsm.cpp +++ b/src/input/InputFPPRemotePlayFileFsm.cpp @@ -467,7 +467,21 @@ bool fsm_PlayFile_state_PlayingFile::Sync (String& FileName, float ElapsedSecond // Adjust the start of the file time to align with the master FPP noInterrupts (); - p_Parent->FrameControl.ElapsedPlayTimeMS = (TargetElapsedMS + p_Parent->FrameControl.ElapsedPlayTimeMS) / 2; + if (20 < abs (FrameDiff)) + { + // DEBUG_V ("Large Setp Adjustment"); + p_Parent->FrameControl.ElapsedPlayTimeMS = TargetElapsedMS; + } + else if(CurrentFrame > TargetFrameId) + { + // DEBUG_V("go back a frame"); + p_Parent->FrameControl.ElapsedPlayTimeMS -= p_Parent->FrameControl.FrameStepTimeMS; + } + else + { + // DEBUG_V("go forward a frame"); + p_Parent->FrameControl.ElapsedPlayTimeMS += p_Parent->FrameControl.FrameStepTimeMS; + } interrupts (); response = true; From 47c54138d271b4411e2a58e5be8e50a40934c708 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 4 Dec 2024 13:27:38 -0500 Subject: [PATCH 05/19] Added support for ignoring messages created by latest xLights that are not supported by ESPS V4 --- src/WebMgr.cpp | 27 ++++++++++++++++++++++++++- src/service/FPPDiscovery.cpp | 29 +++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/src/WebMgr.cpp b/src/WebMgr.cpp index dc2199b6f..b10e6ad69 100644 --- a/src/WebMgr.cpp +++ b/src/WebMgr.cpp @@ -366,7 +366,7 @@ void c_WebMgr::init () [](AsyncWebServerRequest* request) { RequestReboot(100000);; - }, + }, [](AsyncWebServerRequest* request, String filename, uint32_t index, uint8_t* data, uint32_t len, bool final) {WebMgr.FirmwareUpload (request, filename, index, data, len, final); }); //.setFilter (ON_STA_FILTER); @@ -406,6 +406,31 @@ void c_WebMgr::init () FPPDiscovery.ProcessFPPJson(request); }); + webServer.on ("/api/fppd", HTTP_GET, [](AsyncWebServerRequest* request) + { + FPPDiscovery.ProcessFPPDJson(request); + }); + + webServer.on ("/api/channel", HTTP_GET, [](AsyncWebServerRequest* request) + { + FPPDiscovery.ProcessFPPDJson(request); + }); + + webServer.on ("/api/playlists", HTTP_GET, [](AsyncWebServerRequest* request) + { + FPPDiscovery.ProcessFPPDJson(request); + }); + + webServer.on ("/api/cape", HTTP_GET, [](AsyncWebServerRequest* request) + { + FPPDiscovery.ProcessFPPDJson(request); + }); + + webServer.on ("/api/proxies", HTTP_GET, [](AsyncWebServerRequest* request) + { + FPPDiscovery.ProcessFPPDJson(request); + }); + // Static Handlers webServer.serveStatic ("/UpdRecipe", LittleFS, "/UpdRecipe.json"); webServer.serveStatic ("/conf/config.json", LittleFS, "/config.json"); diff --git a/src/service/FPPDiscovery.cpp b/src/service/FPPDiscovery.cpp index 598d50ce8..56232e9f0 100644 --- a/src/service/FPPDiscovery.cpp +++ b/src/service/FPPDiscovery.cpp @@ -165,6 +165,7 @@ void c_FPPDiscovery::GetStatus (JsonObject & jsonStatus) jsonStatus[F ("pktLastCommand")] = MultiSyncStats.pktLastCommand; jsonStatus[F ("ProcessFPPJson")] = SystemDebugStats.ProcessFPPJson; + jsonStatus[F ("ProcessFPPDJson")] = SystemDebugStats.ProcessFPPDJson; jsonStatus[F ("CmdGetFPPstatus")] = SystemDebugStats.CmdGetFPPstatus; jsonStatus[F ("CmdGetSysInfoJSON")] = SystemDebugStats.CmdGetSysInfoJSON; jsonStatus[F ("CmdGetHostname")] = SystemDebugStats.CmdGetHostname; @@ -1102,6 +1103,34 @@ void c_FPPDiscovery::ProcessFPPJson (AsyncWebServerRequest* request) } // ProcessFPPJson +//----------------------------------------------------------------------------- +void c_FPPDiscovery::ProcessFPPDJson (AsyncWebServerRequest* request) +{ + // DEBUG_START; + printReq(request, false); + + SystemDebugStats.ProcessFPPDJson++; + + do // once + { + if (!request->hasParam (ulrCommand)) + { + request->send (404); + // DEBUG_V (String ("Missing Param: 'command' ")); + + break; + } + + // DEBUG_V (String ("Unknown command: ") + command); + request->send (404); + SystemDebugStats.CmdNotFound++; + + } while (false); + + // DEBUG_END; + +} // ProcessFPPDJson + //----------------------------------------------------------------------------- void c_FPPDiscovery::StartPlaying (String & FileName, float SecondsElapsed) { From c03df2ad52ee009ab31b49c512bfa9eabe5242fb Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 4 Dec 2024 13:28:40 -0500 Subject: [PATCH 06/19] Changes to make the transfer of files from xLights more stable. --- src/FileMgr.cpp | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/src/FileMgr.cpp b/src/FileMgr.cpp index 0ac5585f5..9ab09ecd1 100644 --- a/src/FileMgr.cpp +++ b/src/FileMgr.cpp @@ -1240,7 +1240,7 @@ bool c_FileMgr::OpenSdFile (const String & FileName, FileMode Mode, FileId & Fil // DEBUG_V("Open return"); if (!FileList[FileListIndex].IsOpen) { - logcon(String(F("ERROR: Cannot open '")) + FileName + F("'.")); + logcon(String(F("ERROR: Could not open '")) + FileName + F("'.")); // release the file list entry CloseSdFile(FileHandle); break; @@ -1260,6 +1260,10 @@ bool c_FileMgr::OpenSdFile (const String & FileName, FileMode Mode, FileId & Fil FileIsOpen = true; // DEBUG_V (String ("File.Handle: ") + String (FileList[FileListIndex].handle)); } + else + { + // DEBUG_V("Could not get a file list index"); + } } while (false); @@ -1424,6 +1428,7 @@ void c_FileMgr::CloseSdFile (FileId& FileHandle) { if(!FileList[FileListIndex].Paused) { + delay(10); FileList[FileListIndex].fsFile.close (); } FileList[FileListIndex].IsOpen = false; @@ -1461,12 +1466,19 @@ size_t c_FileMgr::WriteSdFile (const FileId& FileHandle, byte* FileData, size_t // DEBUG_V (String("Bytes to write: ") + String(NumBytesToWrite)); if (-1 == (FileListIndex = FileListFindSdFileHandle (FileHandle))) { + // DEBUG_V (String("FileHandle: ") + String(FileHandle)); logcon (String (F ("WriteSdFile::ERROR::Invalid File Handle: ")) + String (FileHandle)); break; } + delay(10); + FeedWDT(); + feedLoopWDT(); NumBytesWritten = FileList[FileListIndex].fsFile.write(FileData, NumBytesToWrite); FileList[FileListIndex].fsFile.flush(); + FeedWDT(); + feedLoopWDT(); + delay(10); // DEBUG_V (String (" FileHandle: ") + String (FileHandle)); // DEBUG_V (String ("File.Handle: ") + String (FileList[FileListIndex].handle)); @@ -1511,6 +1523,10 @@ size_t c_FileMgr::WriteSdFileBuf (const FileId& FileHandle, byte* FileData, size } #endif // defined (ARDUINO_ARCH_ESP32) + delay(10); + FeedWDT(); + feedLoopWDT(); + // are we using a buffer in front of the SD card? if(nullptr == FileList[FileListIndex].buffer.DataBuffer) { @@ -1554,6 +1570,9 @@ size_t c_FileMgr::WriteSdFileBuf (const FileId& FileHandle, byte* FileData, size } // DEBUG_V (String (" FileHandle: ") + String (FileHandle)); // DEBUG_V (String ("File.Handle: ") + String (FileList[FileListIndex].handle)); + delay(20); + FeedWDT(); + feedLoopWDT(); if(NumBytesWritten != NumBytesToWrite) { @@ -1684,6 +1703,7 @@ void c_FileMgr::PauseSdFile (const FileId & FileHandle) break; } + delay(10); FileList[FileListIndex].fsFile.close (); FileList[FileListIndex].Paused = true; From 547802693ad4003e1f715045f8d6c40aaa680c92 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 4 Dec 2024 13:29:27 -0500 Subject: [PATCH 07/19] Change to silently ignore unsopported requests from xLights. --- include/service/FPPDiscovery.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/service/FPPDiscovery.h b/include/service/FPPDiscovery.h index 943df868b..c81ab10c0 100644 --- a/include/service/FPPDiscovery.h +++ b/include/service/FPPDiscovery.h @@ -99,6 +99,7 @@ class c_FPPDiscovery struct SystemDebugStats_t { uint32_t ProcessFPPJson = 0; + uint32_t ProcessFPPDJson = 0; uint32_t CmdGetFPPstatus = 0; uint32_t CmdGetSysInfoJSON = 0; uint32_t CmdGetHostname = 0; @@ -114,6 +115,7 @@ SystemDebugStats_t SystemDebugStats; void begin (); void ProcessFPPJson (AsyncWebServerRequest* request); + void ProcessFPPDJson (AsyncWebServerRequest* request); void ProcessGET (AsyncWebServerRequest* request); void ProcessPOST (AsyncWebServerRequest* request); void ProcessFile (AsyncWebServerRequest* request, String filename, uint32_t index, uint8_t* data, uint32_t len, bool final, uint32_t contentLength = 0); From 4555f8595a8d15693ba38d8977baa1517acbba18 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 4 Dec 2024 13:30:17 -0500 Subject: [PATCH 08/19] change timing to try to eliminate flicker in some DIG Quad systems. --- include/output/OutputWS2811.hpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/include/output/OutputWS2811.hpp b/include/output/OutputWS2811.hpp index 128b675a2..f662de7cd 100644 --- a/include/output/OutputWS2811.hpp +++ b/include/output/OutputWS2811.hpp @@ -3,7 +3,7 @@ * OutputWS2811.h - WS2811 driver code for ESPixelStick * * Project: ESPixelStick - An ESP8266 / ESP32 and E1.31 based pixel driver -* Copyright (c) 2015, 2022 Shelby Merrick +* Copyright (c) 2015, 2024 Shelby Merrick * http://www.forkineye.com * * This program is provided free for you to use in any way that you wish, @@ -52,10 +52,14 @@ class c_OutputWS2811 : public c_OutputPixel #define WS2811_PIXEL_NS_BIT_TOTAL ( (1.0 / WS2811_PIXEL_DATA_RATE) * NanoSecondsInASecond) #ifdef ARDUINO_ARCH_ESP32 // values have been adjusted to work with seed pixels. - #define WS2811_PIXEL_NS_BIT_0_HIGH 312.0 // = 312 on logic analyzer 220ns - 380ns per datasheet - #define WS2811_PIXEL_NS_BIT_0_LOW 945.0 // = 937 on logic analyzer 580ns - 1.6us per datasheet - #define WS2811_PIXEL_NS_BIT_1_HIGH 975.0 // = 937 on logic analyzer 580ns - 1.6us per datasheet - #define WS2811_PIXEL_NS_BIT_1_LOW 300.0 // = 312 on logic analyzer 220ns - 380ns per datasheet +// #define WS2811_PIXEL_NS_BIT_0_HIGH 312.0 // = 312 on logic analyzer 220ns - 380ns per datasheet +// #define WS2811_PIXEL_NS_BIT_0_LOW 945.0 // = 937 on logic analyzer 580ns - 1.6us per datasheet +// #define WS2811_PIXEL_NS_BIT_1_HIGH 975.0 // = 937 on logic analyzer 580ns - 1.6us per datasheet +// #define WS2811_PIXEL_NS_BIT_1_LOW 300.0 // = 312 on logic analyzer 220ns - 380ns per datasheet + #define WS2811_PIXEL_NS_BIT_0_HIGH 300.0 // 220ns - 380ns per datasheet + #define WS2811_PIXEL_NS_BIT_0_LOW (WS2811_PIXEL_NS_BIT_TOTAL - WS2811_PIXEL_NS_BIT_0_HIGH) + #define WS2811_PIXEL_NS_BIT_1_HIGH WS2811_PIXEL_NS_BIT_0_LOW + #define WS2811_PIXEL_NS_BIT_1_LOW WS2811_PIXEL_NS_BIT_0_HIGH #else #define WS2811_PIXEL_NS_BIT_0_HIGH 312.0 // 220ns - 380ns per datasheet #define WS2811_PIXEL_NS_BIT_0_LOW (WS2811_PIXEL_NS_BIT_TOTAL - WS2811_PIXEL_NS_BIT_0_HIGH) From e17d9d28db661ffec91d30dc67572e4af9effd33 Mon Sep 17 00:00:00 2001 From: Martin Date: Wed, 4 Dec 2024 13:40:30 -0500 Subject: [PATCH 09/19] Remove function not supported by ESP8266 --- src/FileMgr.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/FileMgr.cpp b/src/FileMgr.cpp index 9ab09ecd1..736d720b4 100644 --- a/src/FileMgr.cpp +++ b/src/FileMgr.cpp @@ -1473,11 +1473,9 @@ size_t c_FileMgr::WriteSdFile (const FileId& FileHandle, byte* FileData, size_t delay(10); FeedWDT(); - feedLoopWDT(); NumBytesWritten = FileList[FileListIndex].fsFile.write(FileData, NumBytesToWrite); FileList[FileListIndex].fsFile.flush(); FeedWDT(); - feedLoopWDT(); delay(10); // DEBUG_V (String (" FileHandle: ") + String (FileHandle)); // DEBUG_V (String ("File.Handle: ") + String (FileList[FileListIndex].handle)); @@ -1525,7 +1523,6 @@ size_t c_FileMgr::WriteSdFileBuf (const FileId& FileHandle, byte* FileData, size delay(10); FeedWDT(); - feedLoopWDT(); // are we using a buffer in front of the SD card? if(nullptr == FileList[FileListIndex].buffer.DataBuffer) @@ -1572,7 +1569,6 @@ size_t c_FileMgr::WriteSdFileBuf (const FileId& FileHandle, byte* FileData, size // DEBUG_V (String ("File.Handle: ") + String (FileList[FileListIndex].handle)); delay(20); FeedWDT(); - feedLoopWDT(); if(NumBytesWritten != NumBytesToWrite) { From 80c6eca5aba23081c8959d8995cfe1d3da59b182 Mon Sep 17 00:00:00 2001 From: Martin Date: Fri, 6 Dec 2024 09:55:37 -0500 Subject: [PATCH 10/19] Added some WDT management for long running tasks. --- src/FileMgr.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/FileMgr.cpp b/src/FileMgr.cpp index 736d720b4..18c5ef5b2 100644 --- a/src/FileMgr.cpp +++ b/src/FileMgr.cpp @@ -1700,6 +1700,8 @@ void c_FileMgr::PauseSdFile (const FileId & FileHandle) } delay(10); + FeedWDT(); + FileList[FileListIndex].fsFile.close (); FileList[FileListIndex].Paused = true; @@ -1711,7 +1713,7 @@ void c_FileMgr::PauseSdFile (const FileId & FileHandle) //----------------------------------------------------------------------------- void c_FileMgr::BuildFseqList() { - // DEBUG_START; + DEBUG_START; char entryName [256]; do // once @@ -1722,6 +1724,8 @@ void c_FileMgr::BuildFseqList() break; } + FeedWDT(); + FsFile InputFile; ESP_SD.chdir(); // Set to sd root if(!InputFile.open ("/", O_READ)) @@ -1851,7 +1855,7 @@ void c_FileMgr::BuildFseqList() // ReadSdFile(FSEQFILELIST, Temp); // DEBUG_V(Temp); - // DEBUG_END; + DEBUG_END; } // BuildFseqList @@ -1875,6 +1879,7 @@ bool c_FileMgr::handleFileUpload ( do // once { + FeedWDT(); if ((0 == index)) { // DEBUG_V("New File"); @@ -1933,6 +1938,7 @@ bool c_FileMgr::handleFileUpload ( // cause the remainder in the buffer to be written. WriteSdFileBuf (fsUploadFileHandle, data, 0); uint32_t uploadTime = (uint32_t)(millis() - fsUploadStartTime) / 1000; + FeedWDT(); CloseSdFile (fsUploadFileHandle); fsUploadFileHandle = INVALID_FILE_HANDLE; From 0ea7a6c016f7b1051cebb5630cb37f2a6f385b3e Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 7 Dec 2024 11:07:48 -0500 Subject: [PATCH 11/19] Added comments --- src/FileMgr.cpp | 4 ++-- src/WebMgr.cpp | 7 +++++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/FileMgr.cpp b/src/FileMgr.cpp index 18c5ef5b2..614587a9a 100644 --- a/src/FileMgr.cpp +++ b/src/FileMgr.cpp @@ -1713,7 +1713,7 @@ void c_FileMgr::PauseSdFile (const FileId & FileHandle) //----------------------------------------------------------------------------- void c_FileMgr::BuildFseqList() { - DEBUG_START; + // DEBUG_START; char entryName [256]; do // once @@ -1855,7 +1855,7 @@ void c_FileMgr::BuildFseqList() // ReadSdFile(FSEQFILELIST, Temp); // DEBUG_V(Temp); - DEBUG_END; + // DEBUG_END; } // BuildFseqList diff --git a/src/WebMgr.cpp b/src/WebMgr.cpp index b10e6ad69..8d025dc68 100644 --- a/src/WebMgr.cpp +++ b/src/WebMgr.cpp @@ -377,12 +377,14 @@ void c_WebMgr::init () FPPDiscovery.ProcessGET(request); }); + // URL's needed for FPP Connect fseq uploading and querying webServer.on ("/api/system", HTTP_GET, [](AsyncWebServerRequest* request) { FPPDiscovery.ProcessGET(request); }); + // URL's needed for FPP Connect fseq uploading and querying webServer.on ("/fpp", HTTP_POST | HTTP_PUT, [](AsyncWebServerRequest* request) { @@ -406,26 +408,31 @@ void c_WebMgr::init () FPPDiscovery.ProcessFPPJson(request); }); + // URL's needed for FPP Connect fseq uploading and querying webServer.on ("/api/fppd", HTTP_GET, [](AsyncWebServerRequest* request) { FPPDiscovery.ProcessFPPDJson(request); }); + // URL's needed for FPP Connect fseq uploading and querying webServer.on ("/api/channel", HTTP_GET, [](AsyncWebServerRequest* request) { FPPDiscovery.ProcessFPPDJson(request); }); + // URL's needed for FPP Connect fseq uploading and querying webServer.on ("/api/playlists", HTTP_GET, [](AsyncWebServerRequest* request) { FPPDiscovery.ProcessFPPDJson(request); }); + // URL's needed for FPP Connect fseq uploading and querying webServer.on ("/api/cape", HTTP_GET, [](AsyncWebServerRequest* request) { FPPDiscovery.ProcessFPPDJson(request); }); + // URL's needed for FPP Connect fseq uploading and querying webServer.on ("/api/proxies", HTTP_GET, [](AsyncWebServerRequest* request) { FPPDiscovery.ProcessFPPDJson(request); From c1f5d35612852e4a8cf7feb2a5cd1ceca4c0c058 Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 7 Dec 2024 11:17:18 -0500 Subject: [PATCH 12/19] Updated a comment --- src/WebMgr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebMgr.cpp b/src/WebMgr.cpp index 8d025dc68..b1ae286bf 100644 --- a/src/WebMgr.cpp +++ b/src/WebMgr.cpp @@ -451,7 +451,7 @@ void c_WebMgr::init () // FS Debugging Handler // webServer.serveStatic ("/fs", LittleFS, "/" ); - // if the client posts to the upload page + // if the client posts to the file upload page webServer.on ("/upload", HTTP_POST | HTTP_PUT | HTTP_OPTIONS, [](AsyncWebServerRequest * request) { From a4ca2946e78a7a383963557a575dbb20208a5b8c Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 7 Dec 2024 13:48:35 -0500 Subject: [PATCH 13/19] added wdt call --- src/service/FPPDiscovery.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/service/FPPDiscovery.cpp b/src/service/FPPDiscovery.cpp index 56232e9f0..51587562c 100644 --- a/src/service/FPPDiscovery.cpp +++ b/src/service/FPPDiscovery.cpp @@ -812,7 +812,8 @@ void c_FPPDiscovery::ProcessFile ( if(!inFileUpload) { // DEBUG_V(); - StopPlaying(false); + // wait for the player to become idle + StopPlaying(true); inFileUpload = true; UploadFileName = filename; } @@ -1177,6 +1178,8 @@ void c_FPPDiscovery::StopPlaying (bool wait) { // DEBUG_START; + FeedWDT(); + // DEBUG_V (String (F ("FPPDiscovery::StopPlaying '")) + InputFPPRemotePlayFile.GetFileName() + "'"); // only process if the pointer is valid while (InputFPPRemotePlayFile) From 92df17480bcaefb4a0b7d579beb885b2987c4d09 Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 7 Dec 2024 15:56:43 -0500 Subject: [PATCH 14/19] Implicit parm is now explicit --- src/WebMgr.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/WebMgr.cpp b/src/WebMgr.cpp index b1ae286bf..954d8d71b 100644 --- a/src/WebMgr.cpp +++ b/src/WebMgr.cpp @@ -684,7 +684,7 @@ size_t c_WebMgr::GetFseqFileListChunk(uint8_t *buffer, size_t maxlen, size_t ind buffer[0] = '\0'; // DEBUG_V("Try to open the file"); - if(!FileMgr.OpenSdFile(FSEQFILELIST, c_FileMgr::FileMode::FileRead, FileHandle)) + if(!FileMgr.OpenSdFile(FSEQFILELIST, c_FileMgr::FileMode::FileRead, FileHandle, -1)) { logcon(F("ERROR: Could not open List of Fseq files for reading")); response = FileMgr.GetDefaultFseqFileList(buffer, maxlen); From a4ce94f33aa2535bcc3140f4903ec55ac270e1af Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 7 Dec 2024 15:57:01 -0500 Subject: [PATCH 15/19] Implicit parm is now explicit --- src/input/InputFPPRemotePlayFile.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/input/InputFPPRemotePlayFile.cpp b/src/input/InputFPPRemotePlayFile.cpp index e27479662..41f39b0e5 100644 --- a/src/input/InputFPPRemotePlayFile.cpp +++ b/src/input/InputFPPRemotePlayFile.cpp @@ -297,7 +297,7 @@ bool c_InputFPPRemotePlayFile::ParseFseqFile () if (false == FileMgr.OpenSdFile (PlayItemName, c_FileMgr::FileMode::FileRead, - FileHandleForFileBeingPlayed)) + FileHandleForFileBeingPlayed, -1)) { LastFailedPlayStatusMsg = (String (F ("ParseFseqFile:: Could not open file: filename: '")) + PlayItemName + "'"); logcon (LastFailedPlayStatusMsg); @@ -307,7 +307,7 @@ bool c_InputFPPRemotePlayFile::ParseFseqFile () // DEBUG_V (String ("FileHandleForFileBeingPlayed: ") + String (FileHandleForFileBeingPlayed)); uint32_t BytesRead = FileMgr.ReadSdFile (FileHandleForFileBeingPlayed, (uint8_t*)&fsqRawHeader, - sizeof (fsqRawHeader), 0); + sizeof (fsqRawHeader), size_t(0)); // DEBUG_V (String (" BytesRead: ") + String (BytesRead)); // DEBUG_V (String (" sizeof (fsqRawHeader): ") + String (sizeof (fsqRawHeader))); From 2f93c1574d563d8a16155ea6415a363c388f6f1c Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 7 Dec 2024 15:57:24 -0500 Subject: [PATCH 16/19] Implicit parm is now explicit --- src/service/FPPDiscovery.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/service/FPPDiscovery.cpp b/src/service/FPPDiscovery.cpp index 51587562c..7313319cf 100644 --- a/src/service/FPPDiscovery.cpp +++ b/src/service/FPPDiscovery.cpp @@ -532,7 +532,7 @@ void c_FPPDiscovery::BuildFseqResponse (String fname, c_FileMgr::FileId fseq, St JsonObject JsonData = JsonDoc.to (); FSEQRawHeader fsqHeader; - FileMgr.ReadSdFile (fseq, (byte*)&fsqHeader, sizeof (fsqHeader), 0); + FileMgr.ReadSdFile (fseq, (byte*)&fsqHeader, sizeof (fsqHeader), size_t(0)); JsonData[F ("Name")] = fname; JsonData[CN_Version] = String (fsqHeader.majorVersion) + "." + String (fsqHeader.minorVersion); @@ -581,7 +581,7 @@ void c_FPPDiscovery::BuildFseqResponse (String fname, c_FileMgr::FileId fseq, St uint8_t* RangeDataBuffer = (uint8_t*)malloc (sizeof(FSEQRawRangeEntry) * fsqHeader.numSparseRanges); FSEQRawRangeEntry* CurrentFSEQRangeEntry = (FSEQRawRangeEntry*)RangeDataBuffer; - FileMgr.ReadSdFile (fseq, RangeDataBuffer, sizeof (FSEQRawRangeEntry), fsqHeader.numCompressedBlocks * 8 + 32); + FileMgr.ReadSdFile (fseq, RangeDataBuffer, sizeof (FSEQRawRangeEntry), size_t(fsqHeader.numCompressedBlocks * 8 + 32)); for (int CurrentRangeIndex = 0; CurrentRangeIndex < fsqHeader.numSparseRanges; @@ -689,7 +689,7 @@ void c_FPPDiscovery::ProcessGET (AsyncWebServerRequest* request) c_FileMgr::FileId FileHandle; // DEBUG_V (String (" seq: ") + seq); - if (FileMgr.OpenSdFile (seq, c_FileMgr::FileMode::FileRead, FileHandle)) + if (FileMgr.OpenSdFile (seq, c_FileMgr::FileMode::FileRead, FileHandle, -1)) { if (FileMgr.GetSdFileSize(FileHandle) > 0) { @@ -757,7 +757,7 @@ void c_FPPDiscovery::ProcessPOST (AsyncWebServerRequest* request) // DEBUG_V (String(F ("FileName: ")) + filename); c_FileMgr::FileId FileHandle; - if (false == FileMgr.OpenSdFile (filename, c_FileMgr::FileMode::FileRead, FileHandle)) + if (false == FileMgr.OpenSdFile (filename, c_FileMgr::FileMode::FileRead, FileHandle, -1)) { logcon (String (F ("c_FPPDiscovery::ProcessPOST: File Does Not Exist - FileName: ")) + filename); request->send (404); From 0d184093550819d2c602c3d3190640d3ab315887 Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 7 Dec 2024 16:00:18 -0500 Subject: [PATCH 17/19] Added protection against multiple concurrent accesses to the SD card. --- include/FileMgr.hpp | 38 +++---- src/FileMgr.cpp | 250 +++++++++++++++++++++++--------------------- 2 files changed, 148 insertions(+), 140 deletions(-) diff --git a/include/FileMgr.hpp b/include/FileMgr.hpp index c11df755f..203e0baca 100644 --- a/include/FileMgr.hpp +++ b/include/FileMgr.hpp @@ -81,24 +81,22 @@ class c_FileMgr bool SdCardIsInstalled () { return SdCardInstalled; } FileId CreateSdFileHandle (); - void DeleteSdFile (const String & FileName); - void SaveSdFile (const String & FileName, String & FileData); - void SaveSdFile (const String & FileName, JsonVariant & FileData); - bool OpenSdFile (const String & FileName, FileMode Mode, FileId & FileHandle, int FileListIndex = -1); - size_t ReadSdFile (const FileId & FileHandle, byte * FileData, size_t NumBytesToRead); - size_t ReadSdFile (const FileId & FileHandle, byte * FileData, size_t NumBytesToRead, size_t StartingPosition); - bool ReadSdFile (const String & FileName, String & FileData); - bool ReadSdFile (const String & FileName, JsonDocument & FileData); - size_t WriteSdFileBuf (const FileId & FileHandle, byte * FileData, size_t NumBytesToWrite); - size_t WriteSdFile (const FileId & FileHandle, byte * FileData, size_t NumBytesToWrite); - size_t WriteSdFile (const FileId & FileHandle, byte * FileData, size_t NumBytesToWrite, size_t StartingPosition); - void CloseSdFile (FileId & FileHandle); - void GetListOfSdFiles (std::vector & Response); - uint64_t GetSdFileSize (const String & FileName); - uint64_t GetSdFileSize (const FileId & FileHandle); - void BuildFseqList (); - void ResumeSdFile (const FileId & FileHandle); - void PauseSdFile (const FileId & FileHandle); + void DeleteSdFile (const String & FileName, bool LockStatus = false); + void SaveSdFile (const String & FileName, String & FileData, bool LockStatus = false); + void SaveSdFile (const String & FileName, JsonVariant & FileData, bool LockStatus = false); + bool OpenSdFile (const String & FileName, FileMode Mode, FileId & FileHandle, int FileListIndex, bool LockStatus = false); + size_t ReadSdFile (const FileId & FileHandle, byte * FileData, size_t NumBytesToRead, bool LockStatus = false); + size_t ReadSdFile (const FileId & FileHandle, byte * FileData, size_t NumBytesToRead, size_t StartingPosition, bool LockStatus = false); + bool ReadSdFile (const String & FileName, String & FileData, bool LockStatus = false); + bool ReadSdFile (const String & FileName, JsonDocument & FileData, bool LockStatus = false); + size_t WriteSdFileBuf (const FileId & FileHandle, byte * FileData, size_t NumBytesToWrite, bool LockStatus = false); + size_t WriteSdFile (const FileId & FileHandle, byte * FileData, size_t NumBytesToWrite, bool LockStatus = false); + size_t WriteSdFile (const FileId & FileHandle, byte * FileData, size_t NumBytesToWrite, size_t StartingPosition, bool LockStatus = false); + void CloseSdFile (FileId & FileHandle, bool LockStatus = false); + void GetListOfSdFiles (std::vector & Response, bool LockStatus = false); + uint64_t GetSdFileSize (const String & FileName, bool LockStatus = false); + uint64_t GetSdFileSize (const FileId & FileHandle, bool LockStatus = false); + void BuildFseqList (bool LockStatus = false); void GetDriverName (String& Name) { Name = "FileMgr"; } void NetworkStateChanged (bool NewState); @@ -115,6 +113,8 @@ class c_FileMgr void SetSpiIoPins (); void SetSdSpeed (); void ResetSdCard (); + void LockSd(bool ExistingLockStatus); + void UnLockSd(bool ExistingLockStatus); # define SD_CARD_CLK_MHZ SD_SCK_MHZ(37) // 50 MHz SPI clock #ifndef MaxSdTransSpeedMHz @@ -240,6 +240,8 @@ public: struct __attribute__((__packed__, aligned(4))) CSD { uint32_t LastFileSent = 0; uint32_t expectedIndex = 0; + bool SdAccessSemaphore = false; + protected: }; // c_FileMgr diff --git a/src/FileMgr.cpp b/src/FileMgr.cpp index 614587a9a..799f797d5 100644 --- a/src/FileMgr.cpp +++ b/src/FileMgr.cpp @@ -60,7 +60,7 @@ void ftp_callback(FtpOperation ftpOperation, unsigned int freeSpace, unsigned in case FTP_FREE_SPACE_CHANGE: { - FileMgr.BuildFseqList(); + FileMgr.BuildFseqList(false); LOG_PORT.printf("FTP: Free space change, free %u of %u! Rebuilding FSEQ file list\n", freeSpace, totalSpace); break; } @@ -140,6 +140,7 @@ static PROGMEM const char DefaultFseqResponse[] = ///< Start up the driver and put it into a safe mode c_FileMgr::c_FileMgr () { + SdAccessSemaphore = false; } // c_FileMgr //----------------------------------------------------------------------------- @@ -425,7 +426,7 @@ void c_FileMgr::SetSpiIoPins () DescribeSdCardToUser (); // DEBUG_V(); - BuildFseqList(); + BuildFseqList(false); // DEBUG_V(); } } @@ -1008,16 +1009,21 @@ c_FileMgr::FileId c_FileMgr::CreateSdFileHandle () } // CreateFileHandle //----------------------------------------------------------------------------- -void c_FileMgr::DeleteSdFile (const String & FileName) +void c_FileMgr::DeleteSdFile (const String & FileName, bool LockStatus) { // DEBUG_START; + LockSd(LockStatus); if (ESP_SD.exists (FileName)) { // DEBUG_V (String ("Deleting '") + FileName + "'"); ESP_SD.remove (FileName); - BuildFseqList(); + if(!FileName.equals(FSEQFILELIST)) + { + BuildFseqList(true); + } } + UnLockSd(LockStatus); // DEBUG_END; @@ -1043,9 +1049,10 @@ void c_FileMgr::DescribeSdCardToUser () } // DescribeSdCardToUser //----------------------------------------------------------------------------- -void c_FileMgr::GetListOfSdFiles (std::vector & Response) +void c_FileMgr::GetListOfSdFiles (std::vector & Response, bool LockStatus) { // DEBUG_START; + LockSd(LockStatus); char entryName[256]; FsFile Entry; @@ -1096,6 +1103,7 @@ void c_FileMgr::GetListOfSdFiles (std::vector & Response) dir.close(); } while (false); + UnLockSd(LockStatus); // DEBUG_END; } // GetListOfSdFiles @@ -1142,45 +1150,48 @@ void c_FileMgr::printDirectory (FsFile & dir, int numTabs) } // printDirectory //----------------------------------------------------------------------------- -void c_FileMgr::SaveSdFile (const String & FileName, String & FileData) +void c_FileMgr::SaveSdFile (const String & FileName, String & FileData, bool LockStatus) { // DEBUG_START; + LockSd(LockStatus); do // once { FileId FileHandle = INVALID_FILE_HANDLE; - if (false == OpenSdFile (FileName, FileMode::FileWrite, FileHandle)) + if (false == OpenSdFile (FileName, FileMode::FileWrite, FileHandle, -1, true)) { logcon (String (F ("Could not open '")) + FileName + F ("' for writting.")); break; } - int WriteCount = WriteSdFile (FileHandle, (byte*)FileData.c_str (), (size_t)FileData.length ()); + int WriteCount = WriteSdFile (FileHandle, (byte*)FileData.c_str (), (size_t)FileData.length (), true); logcon (String (F ("Wrote '")) + FileName + F ("' ") + String(WriteCount)); - CloseSdFile (FileHandle); + CloseSdFile (FileHandle, true); } while (false); // DEBUG_END; + UnLockSd(LockStatus); } // SaveSdFile //----------------------------------------------------------------------------- -void c_FileMgr::SaveSdFile (const String & FileName, JsonVariant & FileData) +void c_FileMgr::SaveSdFile (const String & FileName, JsonVariant & FileData, bool LockStatus) { String Temp; serializeJson (FileData, Temp); - SaveSdFile (FileName, Temp); + SaveSdFile (FileName, Temp, false); } // SaveSdFile //----------------------------------------------------------------------------- -bool c_FileMgr::OpenSdFile (const String & FileName, FileMode Mode, FileId & FileHandle, int FileListIndex) +bool c_FileMgr::OpenSdFile (const String & FileName, FileMode Mode, FileId & FileHandle, int FileListIndex, bool LockStatus) { // DEBUG_START; // DEBUG_V(String("Mode: ") + String(Mode)); + LockSd(LockStatus); bool FileIsOpen = false; @@ -1242,7 +1253,7 @@ bool c_FileMgr::OpenSdFile (const String & FileName, FileMode Mode, FileId & Fil { logcon(String(F("ERROR: Could not open '")) + FileName + F("'.")); // release the file list entry - CloseSdFile(FileHandle); + CloseSdFile(FileHandle, true); break; } // DEBUG_V(""); @@ -1267,64 +1278,73 @@ bool c_FileMgr::OpenSdFile (const String & FileName, FileMode Mode, FileId & Fil } while (false); + UnLockSd(LockStatus); + // DEBUG_END; return FileIsOpen; } // OpenSdFile //----------------------------------------------------------------------------- -bool c_FileMgr::ReadSdFile (const String & FileName, String & FileData) +bool c_FileMgr::ReadSdFile (const String & FileName, String & FileData, bool LockStatus) { // DEBUG_START; + LockSd(LockStatus); - bool GotFileData = false; + bool GotFileData = false; FileId FileHandle = INVALID_FILE_HANDLE; // DEBUG_V (String("File '") + FileName + "' is being opened."); - if (true == OpenSdFile (FileName, FileMode::FileRead, FileHandle)) + if (true == OpenSdFile (FileName, FileMode::FileRead, FileHandle, -1, true)) { // DEBUG_V (String("File '") + FileName + "' is open."); int FileListIndex; if (-1 != (FileListIndex = FileListFindSdFileHandle (FileHandle))) { + LockSd(LockStatus); FileList[FileListIndex].fsFile.seek (0); FileData = FileList[FileListIndex].fsFile.readString (); + UnLockSd(LockStatus); } - CloseSdFile (FileHandle); + CloseSdFile (FileHandle, true); GotFileData = (0 != FileData.length()); // DEBUG_V (FileData); } else { - CloseSdFile (FileHandle); + CloseSdFile (FileHandle, true); logcon (String (F ("SD file: '")) + FileName + String (F ("' not found."))); } + UnLockSd(LockStatus); + // DEBUG_END; return GotFileData; } // ReadSdFile //----------------------------------------------------------------------------- -bool c_FileMgr::ReadSdFile (const String & FileName, JsonDocument & FileData) +bool c_FileMgr::ReadSdFile (const String & FileName, JsonDocument & FileData, bool LockStatus) { // DEBUG_START; bool GotFileData = false; FileId FileHandle = INVALID_FILE_HANDLE; + LockSd(LockStatus); // DEBUG_V (String("File '") + FileName + "' is being opened."); - if (true == OpenSdFile (FileName, FileMode::FileRead, FileHandle)) + if (true == OpenSdFile (FileName, FileMode::FileRead, FileHandle, -1, true)) { // DEBUG_V (String("File '") + FileName + "' is open."); int FileListIndex; if (-1 != (FileListIndex = FileListFindSdFileHandle (FileHandle))) { - + LockSd(LockStatus); FileList[FileListIndex].fsFile.seek (0); String RawFileData = FileList[FileListIndex].fsFile.readString (); + UnLockSd(LockStatus); // DEBUG_V ("Convert File to JSON document"); DeserializationError error = deserializeJson (FileData, RawFileData); @@ -1342,22 +1362,25 @@ bool c_FileMgr::ReadSdFile (const String & FileName, JsonDocument & FileData) GotFileData = true; } } - CloseSdFile(FileHandle); + CloseSdFile(FileHandle, true); } else { logcon (String (F ("SD file: '")) + FileName + String (F ("' not found."))); } + UnLockSd(LockStatus); + // DEBUG_END; return GotFileData; } // ReadSdFile //----------------------------------------------------------------------------- -size_t c_FileMgr::ReadSdFile (const FileId& FileHandle, byte* FileData, size_t NumBytesToRead, size_t StartingPosition) +size_t c_FileMgr::ReadSdFile (const FileId& FileHandle, byte* FileData, size_t NumBytesToRead, size_t StartingPosition, bool LockStatus) { // DEBUG_START; + LockSd(LockStatus); size_t response = 0; @@ -1378,24 +1401,27 @@ size_t c_FileMgr::ReadSdFile (const FileId& FileHandle, byte* FileData, size_t N } else { - response = ReadSdFile(FileHandle, FileData, ActualBytesToRead); + response = ReadSdFile(FileHandle, FileData, ActualBytesToRead, true); // DEBUG_V(String(" response: ") + String(response)); } + } else { logcon (String (F ("ReadSdFile::ERROR::Invalid File Handle: ")) + String (FileHandle)); } + UnLockSd(LockStatus); // DEBUG_END; return response; } // ReadSdFile //----------------------------------------------------------------------------- -size_t c_FileMgr::ReadSdFile (const FileId& FileHandle, byte* FileData, size_t NumBytesToRead) +size_t c_FileMgr::ReadSdFile (const FileId& FileHandle, byte* FileData, size_t NumBytesToRead, bool LockStatus) { // DEBUG_START; + LockSd(LockStatus); // DEBUG_V (String (" FileHandle: ") + String (FileHandle)); // DEBUG_V (String (" numBytesToRead: ") + String (NumBytesToRead)); @@ -1412,16 +1438,18 @@ size_t c_FileMgr::ReadSdFile (const FileId& FileHandle, byte* FileData, size_t N logcon (String (F ("ReadSdFile::ERROR::Invalid File Handle: ")) + String (FileHandle)); } + UnLockSd(LockStatus); // DEBUG_END; return response; } // ReadSdFile //----------------------------------------------------------------------------- -void c_FileMgr::CloseSdFile (FileId& FileHandle) +void c_FileMgr::CloseSdFile (FileId& FileHandle, bool LockStatus) { // DEBUG_START; // DEBUG_V(String(" FileHandle: ") + String(FileHandle)); + LockSd(LockStatus); int FileListIndex; if (-1 != (FileListIndex = FileListFindSdFileHandle (FileHandle))) @@ -1450,14 +1478,16 @@ void c_FileMgr::CloseSdFile (FileId& FileHandle) FileHandle = INVALID_FILE_HANDLE; + UnLockSd(LockStatus); // DEBUG_END; } // CloseSdFile //----------------------------------------------------------------------------- -size_t c_FileMgr::WriteSdFile (const FileId& FileHandle, byte* FileData, size_t NumBytesToWrite) +size_t c_FileMgr::WriteSdFile (const FileId& FileHandle, byte* FileData, size_t NumBytesToWrite, bool LockStatus) { // DEBUG_START; + LockSd(LockStatus); size_t NumBytesWritten = 0; do // once @@ -1488,6 +1518,7 @@ size_t c_FileMgr::WriteSdFile (const FileId& FileHandle, byte* FileData, size_t } } while(false); + UnLockSd(LockStatus); // DEBUG_END; return NumBytesWritten; @@ -1498,9 +1529,10 @@ size_t c_FileMgr::WriteSdFile (const FileId& FileHandle, byte* FileData, size_t Specialized function that buffers data until the buffer is full and then writes out the buffer as a single operation. */ -size_t c_FileMgr::WriteSdFileBuf (const FileId& FileHandle, byte* FileData, size_t NumBytesToWrite) +size_t c_FileMgr::WriteSdFileBuf (const FileId& FileHandle, byte* FileData, size_t NumBytesToWrite, bool LockStatus) { // DEBUG_START; + LockSd(LockStatus); size_t NumBytesWritten = 0; do // once @@ -1543,10 +1575,8 @@ size_t c_FileMgr::WriteSdFileBuf (const FileId& FileHandle, byte* FileData, size if(WontFit || WriteRemainder) { // DEBUG_V("Buffer cant hold this data. Write out the buffer"); - ResumeSdFile(FileHandle); size_t bufferWriteSize = FileList[FileListIndex].fsFile.write(FileData, FileList[FileListIndex].buffer.offset); FileList[FileListIndex].fsFile.flush(); - PauseSdFile(FileHandle); if(FileList[FileListIndex].buffer.offset != bufferWriteSize) { logcon (String("WriteSdFileBuf:ERROR:SD Write Failed. Tried to write: ") + @@ -1578,14 +1608,16 @@ size_t c_FileMgr::WriteSdFileBuf (const FileId& FileHandle, byte* FileData, size } } while(false); + UnLockSd(LockStatus); // DEBUG_END; return NumBytesWritten; } // WriteSdFile //----------------------------------------------------------------------------- -size_t c_FileMgr::WriteSdFile (const FileId& FileHandle, byte* FileData, size_t NumBytesToWrite, size_t StartingPosition) +size_t c_FileMgr::WriteSdFile (const FileId& FileHandle, byte* FileData, size_t NumBytesToWrite, size_t StartingPosition, bool LockStatus) { + LockSd(LockStatus); size_t response = 0; int FileListIndex; if (-1 != (FileListIndex = FileListFindSdFileHandle (FileHandle))) @@ -1593,39 +1625,43 @@ size_t c_FileMgr::WriteSdFile (const FileId& FileHandle, byte* FileData, size_t // DEBUG_V (String (" FileHandle: ") + String (FileHandle)); // DEBUG_V (String ("File.Handle: ") + String (FileList[FileListIndex].handle)); FileList[FileListIndex].fsFile.seek (StartingPosition); - response = WriteSdFile (FileHandle, FileData, NumBytesToWrite); + response = WriteSdFile (FileHandle, FileData, NumBytesToWrite, true); } else { logcon (String (F ("WriteSdFile::ERROR::Invalid File Handle: ")) + String (FileHandle)); } + UnLockSd(LockStatus); return response; } // WriteSdFile //----------------------------------------------------------------------------- -uint64_t c_FileMgr::GetSdFileSize (const String& FileName) +uint64_t c_FileMgr::GetSdFileSize (const String& FileName, bool LockStatus) { + LockSd(LockStatus); uint64_t response = 0; FileId Handle = INVALID_FILE_HANDLE; - if(OpenSdFile (FileName, FileMode::FileRead, Handle)) + if(OpenSdFile (FileName, FileMode::FileRead, Handle, -1, true)) { - response = GetSdFileSize(Handle); - CloseSdFile(Handle); + response = GetSdFileSize(Handle, true); + CloseSdFile(Handle, true); } else { logcon(String(F("Could not open '")) + FileName + F("' to check size.")); } + UnLockSd(LockStatus); return response; } // GetSdFileSize //----------------------------------------------------------------------------- -uint64_t c_FileMgr::GetSdFileSize (const FileId& FileHandle) +uint64_t c_FileMgr::GetSdFileSize (const FileId& FileHandle, bool LockStatus) { + LockSd(LockStatus); uint64_t response = 0; int FileListIndex; if (-1 != (FileListIndex = FileListFindSdFileHandle (FileHandle))) @@ -1637,84 +1673,17 @@ uint64_t c_FileMgr::GetSdFileSize (const FileId& FileHandle) logcon (String (F ("GetSdFileSize::ERROR::Invalid File Handle: ")) + String (FileHandle)); } + UnLockSd(LockStatus); return response; } // GetSdFileSize //----------------------------------------------------------------------------- -void c_FileMgr::ResumeSdFile (const FileId & FileHandle) -{ - // DEBUG_START; - - do // once - { - int FileListIndex; - if (-1 == (FileListIndex = FileListFindSdFileHandle (FileHandle))) - { - logcon (String (F ("ResumeSdFile::ERROR::Invalid File Handle: ")) + String (FileHandle)); - break; - } - // DEBUG_V (String (" FileHandle: ") + String (FileHandle)); - // DEBUG_V (String ("File.Handle: ") + String (FileList[FileListIndex].handle)); - - if(!FileList[FileListIndex].Paused) - { - // DEBUG_V("File is not paused. Ignore Resume request"); - break; - } - - FileList[FileListIndex].mode = FileMode::FileAppend; - OpenSdFile(FileList[FileListIndex].Filename, - FileMode::FileAppend, - FileList[FileListIndex].handle, - FileListIndex); - // DEBUG_V (String (" FileHandle: ") + String (FileHandle)); - // DEBUG_V (String ("File.Handle: ") + String (FileList[FileListIndex].handle)); - - } while(false); - - // DEBUG_END; -} // ResumeSdFile - -//----------------------------------------------------------------------------- -void c_FileMgr::PauseSdFile (const FileId & FileHandle) -{ - // DEBUG_START; - - do // once - { - int FileListIndex; - if (-1 == (FileListIndex = FileListFindSdFileHandle (FileHandle))) - { - logcon (String (F ("PauseSdFile::ERROR::Invalid File Handle: ")) + String (FileHandle)); - break; - } - - // DEBUG_V (String (" FileHandle: ") + String (FileHandle)); - // DEBUG_V (String ("File.Handle: ") + String (FileList[FileListIndex].handle)); - - if(FileList[FileListIndex].Paused) - { - // DEBUG_V("File is paused. Ignore Pause request"); - break; - } - - delay(10); - FeedWDT(); - - FileList[FileListIndex].fsFile.close (); - FileList[FileListIndex].Paused = true; - - } while(false); - - // DEBUG_END; -} // PauseSdFile - -//----------------------------------------------------------------------------- -void c_FileMgr::BuildFseqList() +void c_FileMgr::BuildFseqList(bool LockStatus) { // DEBUG_START; char entryName [256]; + LockSd(LockStatus); do // once { @@ -1736,7 +1705,7 @@ void c_FileMgr::BuildFseqList() // open output file, erase old data ESP_SD.chdir(); // Set to sd root - DeleteSdFile(String(FSEQFILELIST)); + DeleteSdFile(String(FSEQFILELIST), true); FsFile OutputFile; if(!OutputFile.open (String(F(FSEQFILELIST)).c_str(), O_WRITE | O_CREAT)) @@ -1854,6 +1823,7 @@ void c_FileMgr::BuildFseqList() // String Temp; // ReadSdFile(FSEQFILELIST, Temp); // DEBUG_V(Temp); + UnLockSd(LockStatus); // DEBUG_END; @@ -1893,10 +1863,10 @@ bool c_FileMgr::handleFileUpload ( { logcon (String(F("ERROR: Expected index: ")) + String(expectedIndex) + F(" does not match actual index: ") + String(index)); - CloseSdFile(fsUploadFileHandle); - DeleteSdFile (fsUploadFileName); + CloseSdFile(fsUploadFileHandle, false); + DeleteSdFile (fsUploadFileName, false); fsUploadFileHandle = INVALID_FILE_HANDLE; - BuildFseqList(); + BuildFseqList(false); expectedIndex = 0; fsUploadFileName = emptyString; } @@ -1913,7 +1883,7 @@ bool c_FileMgr::handleFileUpload ( { // Write data // DEBUG_V ("UploadWrite: " + String (len) + String (" bytes")); - bytesWritten = WriteSdFileBuf (fsUploadFileHandle, data, len); + bytesWritten = WriteSdFileBuf (fsUploadFileHandle, data, len, false); // DEBUG_V (String ("Writing bytes: ") + String (index)); // LOG_PORT.print ("."); } @@ -1922,10 +1892,10 @@ bool c_FileMgr::handleFileUpload ( if(len != bytesWritten) { // DEBUG_V("Write failed. Stop transfer"); - CloseSdFile(fsUploadFileHandle); - DeleteSdFile (fsUploadFileName); + CloseSdFile(fsUploadFileHandle, false); + DeleteSdFile (fsUploadFileName, false); fsUploadFileHandle = INVALID_FILE_HANDLE; - BuildFseqList(); + BuildFseqList(false); expectedIndex = 0; fsUploadFileName = emptyString; break; @@ -1936,20 +1906,20 @@ bool c_FileMgr::handleFileUpload ( if ((true == final) && (fsUploadFileHandle != INVALID_FILE_HANDLE)) { // cause the remainder in the buffer to be written. - WriteSdFileBuf (fsUploadFileHandle, data, 0); + WriteSdFileBuf (fsUploadFileHandle, data, 0, false); uint32_t uploadTime = (uint32_t)(millis() - fsUploadStartTime) / 1000; FeedWDT(); - CloseSdFile (fsUploadFileHandle); + CloseSdFile (fsUploadFileHandle, false); fsUploadFileHandle = INVALID_FILE_HANDLE; logcon (String (F ("Upload File: '")) + fsUploadFileName + F ("' Done (") + String (uploadTime) + F ("s). Received: ") + String(expectedIndex) + F(" Bytes out of ") + String(totalLen) + - F(" bytes. FileLen: ") + GetSdFileSize(filename)); + F(" bytes. FileLen: ") + GetSdFileSize(filename, false)); expectedIndex = 0; - BuildFseqList(); + BuildFseqList(false); // DEBUG_V(String("Expected: ") + String(totalLen)); // DEBUG_V(String(" Got: ") + String(GetSdFileSize(fsUploadFileName))); @@ -1975,7 +1945,7 @@ void c_FileMgr::handleFileUploadNewFile (const String & filename) if (0 != fsUploadFileName.length ()) { logcon (String (F ("Aborting Previous File Upload For: '")) + fsUploadFileName + String (F ("'"))); - CloseSdFile (fsUploadFileHandle); + CloseSdFile (fsUploadFileHandle, false); fsUploadFileName = ""; } @@ -1984,10 +1954,10 @@ void c_FileMgr::handleFileUploadNewFile (const String & filename) logcon (String (F ("Upload File: '")) + fsUploadFileName + String (F ("' Started"))); - DeleteSdFile (fsUploadFileName); + DeleteSdFile (fsUploadFileName, false); // Open the file for writing - OpenSdFile (fsUploadFileName, FileMode::FileWrite, fsUploadFileHandle, -1 /*first access*/); + OpenSdFile (fsUploadFileName, FileMode::FileWrite, fsUploadFileHandle, -1 /*first access*/, false); // DEBUG_END; @@ -2007,5 +1977,41 @@ size_t c_FileMgr::GetDefaultFseqFileList(uint8_t * buffer, size_t maxlen) return strlen((char*)&buffer[0]); } // GetDefaultFseqFileList +//----------------------------------------------------------------------------- +void c_FileMgr::LockSd(bool CurrentLockState) +{ + // DEBUG_START; + + // DEBUG_V(String(" CurrentLockState: ") + CurrentLockState); + // DEBUG_V(String("SdAccessSemaphore: ") + SdAccessSemaphore); + + // are we at the top level method that locked the SD? + if(false == CurrentLockState) + { + // wait to get access to the SD card + while(true == SdAccessSemaphore) + { + delay(1); + } + SdAccessSemaphore = true; + } + // DEBUG_END; +} // LockSd + +//----------------------------------------------------------------------------- +void c_FileMgr::UnLockSd(bool TargetLockState) +{ + // DEBUG_START; + + // DEBUG_V(String(" TargetLockState: ") + TargetLockState); + // DEBUG_V(String("SdAccessSemaphore: ") + SdAccessSemaphore); + // are we at the top level method that locked the SD? + if(false == TargetLockState && true == SdAccessSemaphore) + { + SdAccessSemaphore = false; + } + // DEBUG_END; +} // UnLockSd + // create a global instance of the File Manager c_FileMgr FileMgr; From 569835d6cef7598c899c56501bc232c3572354a0 Mon Sep 17 00:00:00 2001 From: Martin Date: Sat, 7 Dec 2024 16:14:42 -0500 Subject: [PATCH 18/19] Added a debug message. --- src/service/FPPDiscovery.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/service/FPPDiscovery.cpp b/src/service/FPPDiscovery.cpp index 7313319cf..6519968c0 100644 --- a/src/service/FPPDiscovery.cpp +++ b/src/service/FPPDiscovery.cpp @@ -830,6 +830,7 @@ void c_FPPDiscovery::ProcessFile ( // DEBUG_V(); if (final || writeFailed) { + // DEBUG_V("Allow file to play"); inFileUpload = false; UploadFileName = ""; } From 55a18fbda9349357048e5ec7f7a22af6038b7dc1 Mon Sep 17 00:00:00 2001 From: Martin Date: Sun, 8 Dec 2024 11:43:40 -0500 Subject: [PATCH 19/19] Added code to not increment sequence error if the packet sequence number is zero. --- src/input/InputE131.cpp | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/src/input/InputE131.cpp b/src/input/InputE131.cpp index dbc8eab6b..0bc0c20ad 100644 --- a/src/input/InputE131.cpp +++ b/src/input/InputE131.cpp @@ -157,14 +157,12 @@ void c_InputE131::ProcessIncomingE131Data (e131_packet_t * packet) // Do we need to update a sequnce error? if (packet->sequence_number != CurrentUniverse.SequenceNumber) { - // DEBUG_V (F ("E1.31 Sequence Error - expected: ")); - // DEBUG_V (CurrentUniverse.SequenceNumber); - // DEBUG_V (F (" actual: ")); - // DEBUG_V (packet->sequence_number); - // DEBUG_V (" " + String (CN_universe) + " : "); - // DEBUG_V (CurrentUniverseId); - - CurrentUniverse.SequenceErrorCounter++; + // DEBUG_V (String ("E1.31 Sequence Error - expected: ") + String(CurrentUniverse.SequenceNumber) + " actual: " + packet->sequence_number + " " + String (CN_universe) + " : " + CurrentUniverseId); + // zero is special. Some data sources do not use the sequence number and set this field to zero + if(0 != packet->sequence_number) + { + CurrentUniverse.SequenceErrorCounter++; + } CurrentUniverse.SequenceNumber = packet->sequence_number; } @@ -221,7 +219,7 @@ void c_InputE131::SetBufferTranslation () uint32_t InputOffset = FirstUniverseChannelOffset - 1; uint32_t DestinationOffset = 0; - uint32_t BytesLeftToMap = InputDataBufferSize; + uint32_t BytesLeftToMap = InputDataBufferSize; // set up the bytes for the First Universe uint32_t BytesInUniverse = ChannelsPerUniverse - InputOffset;