diff --git a/src/LoggerBase.cpp b/src/LoggerBase.cpp index 9cb5360d4..09fd82c8d 100644 --- a/src/LoggerBase.cpp +++ b/src/LoggerBase.cpp @@ -2140,9 +2140,10 @@ inline uint16_t Logger::serzQueuedFlushFile() { MS_DEEP_DBG(F("seQFF opened "), tempFn); } - // Get the length of the line being read + // Get the length of the last line that was deserialized num_char = strlen(deszq_line); - // If there is data in the line being read, copy it to the new temp file + // If there is data in the last deserialized line, copy it to the new temp + // file if (num_char) { // Test could be min size, but this unknown MS_DBG(F("seQFF Last POST Failed "), deszq_line); retNum = tgtoutFile.write(deszq_line, num_char); @@ -2154,7 +2155,9 @@ inline uint16_t Logger::serzQueuedFlushFile() { MS_DBG(F("seQFF cpy lines across")); // While still able to read lines from the queue file, copy them to the new - // temp file + // temp file. This will proceed from the last point of entry to the file, + // not from the beginning, so only lines after the last one read will be + // transferred. while (0 < (num_char = serzQueuedFile.fgets(deszq_line, QUEFILE_MAX_LINE))) { #if defined(USE_PS_modularSensorsNetwork) @@ -2166,21 +2169,24 @@ inline uint16_t Logger::serzQueuedFlushFile() { */ postLogLine((MAX_NUMBER_SENDERS + 1), HTTPSTATUS_NC_903); num_skipped++; - } else + } else { #endif // USE_PS_modularSensorsNetwork - { retNum = tgtoutFile.write(deszq_line, num_char); // Squelch last char LF deszq_line[sizeof(deszq_line) - 1] = 0; MS_DBG(deszq_line); - if (retNum != num_char) { + if (retNum != num_char) { // If the number of characters read and + // written don't match PRINTOUT(F("seQFF tgtoutFile write3 err"), num_char, retNum); // sd1_Err("seQFF write4"); break; } + // add one to the total number of lines in the file num_lines++; +#if defined(USE_PS_modularSensorsNetwork) } +#endif // USE_PS_modularSensorsNetwork } if (num_skipped) { PRINTOUT(F("seQFF sendQueue Size "), _sendQueueSz_num, F(",queued"), @@ -2197,8 +2203,9 @@ inline uint16_t Logger::serzQueuedFlushFile() { } } + // rename the old queue file to the deletable queue name retBool = serzQueuedFile.rename(queDelFn); - if (!retBool) { + if (!retBool) { // If rename fails, reboot PRINTOUT(F("seQFF REBOOT rename1 err"), queDelFn); // Problem - unrecoverable, so reboot retBool = serzQueuedFile.close(); @@ -2210,6 +2217,7 @@ inline uint16_t Logger::serzQueuedFlushFile() { } else { MS_DBG(F("seQFF cleanup rename "), serzQueuedFn, F("to"), queDelFn); + // close the original queue file retBool = serzQueuedFile.close(); if (!retBool) { sd1_Err("seQFF serzQueuedFile.close2 err"); @@ -2218,14 +2226,17 @@ inline uint16_t Logger::serzQueuedFlushFile() { MS_DEEP_DBG(F("seQFF close serzQueuedFile")); } + // rename the new temporary file to the proper queue file name retBool = tgtoutFile.rename(serzQueuedFn); if (!retBool) { sd1_Err("seQFF tgtoutFile.rename err"); + // return the number of lines copied from one file to the next return num_lines; } else { MS_DEEP_DBG(F("seQFF rename "), tempFn, F("to"), serzQueuedFn); } + // close the renamed temporary file retBool = tgtoutFile.close(); if (!retBool) { sd1_Err("seQFF tgtoutFile.close1 err"); @@ -2235,6 +2246,7 @@ inline uint16_t Logger::serzQueuedFlushFile() { } } + // return the number of lines copied from one file to the next return num_lines; } // serzQueuedFlushFile @@ -2307,6 +2319,8 @@ char* Logger::deszFind(const char* in_line, char caller_id) { bool Logger::deszRdelStart() { deszLinesRead = 0; + // Reset the pointer for the next character to the start of the pointer for + // the whole line deszq_nextChar = deszq_line; // Open - RD & WR. WR needed to be able to delete when complete. if (!serzRdelFile.open(serzRdelFn_str, (O_RDWR | O_CREAT))) { @@ -2321,6 +2335,8 @@ bool Logger::deszRdelStart() { bool Logger::deszQueuedStart() { deszLinesRead = 0; + // Reset the pointer for the next character to the start of the pointer for + // the whole line deszq_nextChar = deszq_line; // Open - RD & WR. WR needed to be able to delete when complete. // Expect serzQueuedFn to be setup in serzQueuedStart @@ -2414,7 +2430,7 @@ bool Logger::deszqNextCh(void) { // Found end of line MS_DBG(F("dSRN unexpected EOL ")); return false; - } else if (NULL == nextCharEnd) { + } else if (nullptr == nextCharEnd) { // Found EOF ~ nextSr_sz is valid deszq_nextCharSz -= 1; // take off turds MS_DEEP_DBG(F("dSRN info "), deszq_nextCharSz, " '", deszq_nextChar, diff --git a/src/LoggerBase.h b/src/LoggerBase.h index 1fd83a001..f399b2bd2 100644 --- a/src/LoggerBase.h +++ b/src/LoggerBase.h @@ -1499,8 +1499,12 @@ class Logger { * @brief A character buffer holding the current line being deserialized * (read) from the queue file. */ - char deszq_line[QUEFILE_MAX_LINE] = ""; - uint16_t desz_pending_records = 0; + char deszq_line[QUEFILE_MAX_LINE] = ""; + /** + * @brief The number of records that have been added to the data queue + * files. + */ + uint16_t desz_pending_records = 0; // Qu SdFat/sd1_card_fatfs connects to Physical pins or File/logFile or // keep to LFN - capitals https://en.wikipedia.org/wiki/8.3_filename @@ -1512,21 +1516,85 @@ class Logger { #endif // MS_LOGGERBASE_POSTS // que Readings DELAYed (RDEL) ~ serialize/deserialize - File serzRdelFile; + /** + * @brief File reference to the read-delayed file. + * + * The read-delayed file is for records that have never been published at + * all, they're simply in storage waiting their first publishing attempt. + */ + File serzRdelFile; + /** + * @brief String filename of the read-delayed file. + * + * The read-delayed file is for records that have never been published at + * all, they're simply in storage waiting their first publishing attempt. + */ const char* serzRdelFn_str = "RDELAY.TXT"; // QUEueD for reliable delivery // first POST didn't suceed to serialize/deserialize // Potentially multiple versions of files based on dataPublisher[] + + /** + * @brief File reference to the queued data file. + * + * The queue file is for data that has already had one publication attempt, + * which failed due to lack of internet connection or unsuccessful + * serialize/deserialize. + * + * Potentially multiple queue files based on the number of data publishers + * attached to the logger. + */ File serzQueuedFile; + /** + * @brief The buffer size needed for the file name of the + * Logger::serzQueuedFile. + */ #define FN_BUFFER_SZ 13 - char serzQueuedFn[FN_BUFFER_SZ] = ""; - const char* serzQueuedFn_str = "QUE"; // begin of name, keep 8.3 + + /** + * @brief Character string holding the string filename for the queue for the + * current data publisher. + * + * The queue file is for data that has already had one publication + * attempt, which failed due to lack of internet connection or + * unsuccessful serialize/deserialize. + * + * Potentially multiple queue files based on the number of data + * publishers attached to the logger. + * + * The filename will be a concatenation of the Logger::serzQueuedFn_str and + * the uniqueId. + */ + char serzQueuedFn[FN_BUFFER_SZ] = ""; + /** + * @brief The beginning of the filename for the queue files. + */ + const char* serzQueuedFn_str = "QUE"; // begin of name, keep 8.3 // perform a serialize to RdelFile + /** + * @brief Open the [read-delayed file](@ref Logger::serzRdelFile) and + * write a line to it. + * + * The line will have the timestamp, a status code of zero, and the logged + * data values separated by commas. + * + * @return *true* The file was successfully opened. + * @return *false* There was an error in opening the file. + */ bool serzRdel_Line(void); // Uses serzRdelFn_str, File serzRdelFile + /** + * @brief Opens the read-delayed file on the SD-card. + * + * Also sets the pointer for the next character to be read to the start of + * the buffer for the next line. + * + * @return *true* The file was successfully opened. + * @return *false* There was an error in opening the file. + */ bool deszRdelStart(); /** @@ -1544,6 +1612,14 @@ class Logger { */ char* deszFind(const char* in_line, char caller_id); #define deszRdelLine() deszLine(&serzRdelFile) + /** + * @brief Closes the read-delayed file (Logger::serzRdelFile) and deletes it + * if requested. + * + * @param deleteFile True to delete the read-delay file after closing it. + * @return *true* The file was successfully closed. + * @return *false* There was an error in closing the file. + */ bool deszRdelClose(bool deleteFile = false); /** @@ -1569,8 +1645,26 @@ class Logger { */ bool deszQueuedStart(void); #define deszQueuedLine() deszLine(&serzQueuedFile) + /** + * @brief "Flushes" the queued data file by writing all lines from the + * current position forward to a new temporary file, deleting the old queue + * file, and renaming the temporary file to the original queue file name. + * This has the effect of removing all lines from the queue file prior to + * the current read point within the queue file. + * + * @return *uint16_t* The number of lines available in the new queue file. + */ uint16_t serzQueuedFlushFile(); - bool serzQueuedCloseFile(bool action); + /** + * @brief Close the queue file and flush it if requested. + * + * @param flush Whether or not to flush the queue file using + * Logger::serzQueuedFlushFile. + * + * @return *true* The file was successfully closed. + * @return *false* There was an error in closing the file. + */ + bool serzQueuedCloseFile(bool flush); /* bool deszQueuedCleanup(bool debug = false); */