From bc6c50f7345644aa518315734d47cd3488f90681 Mon Sep 17 00:00:00 2001 From: SFEMark Date: Tue, 19 Sep 2023 15:02:10 -0600 Subject: [PATCH 1/6] Create add_issue_to_project.yml Adding issue tracking .yml file for issue tracking in GH Projects. --- .github/workflows/add_issue_to_project.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/add_issue_to_project.yml diff --git a/.github/workflows/add_issue_to_project.yml b/.github/workflows/add_issue_to_project.yml new file mode 100644 index 0000000..6b60cc3 --- /dev/null +++ b/.github/workflows/add_issue_to_project.yml @@ -0,0 +1,18 @@ +name: Add new issue to our main project + +on: + issues: + types: + - opened + +jobs: + add-to-project: + name: Add issue to project + runs-on: ubuntu-latest + steps: + - uses: actions/add-to-project@main + with: + # You can target a project in a different organization + # to the issue + project-url: https://github.com/orgs/sparkfun/projects/19 + github-token: ${{ secrets.DEFECT_ADD_TO_PROJECT }} From 8916bc45fae46823fdf8a4d780a2390dbe424c57 Mon Sep 17 00:00:00 2001 From: Sasha Olenyev Date: Mon, 5 Feb 2024 10:28:26 +0200 Subject: [PATCH 2/6] Change sprintf %zu to %lu in getFileBlock This fixes sparkfun/SparkFun_u-blox_SARA-R5_Arduino_Library#38 When used with ARM GCC Toolchain supplied with Arduino_STM32 newlib nano version is built without C99 formats support, so the %zu format specifier doesn't work, and instead of putting the number it puts "zu" into the resulting string --- src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp index 490a161..9886298 100644 --- a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp +++ b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp @@ -5601,7 +5601,7 @@ SARA_R5_error_t SARA_R5::getFileBlock(const String& filename, char* buffer, size size_t cmd_len = filename.length() + 32; char* cmd = sara_r5_calloc_char(cmd_len); - sprintf(cmd, "at+urdblock=\"%s\",%zu,%zu\r\n", filename.c_str(), offset, requested_length); + sprintf(cmd, "at+urdblock=\"%s\",%lu,%lu\r\n", filename.c_str(), offset, requested_length); sendCommand(cmd, false); int ich; From 7a0d715bd4325f51cd1347bc40455f7d54a40513 Mon Sep 17 00:00:00 2001 From: Sasha Olenyev Date: Mon, 5 Feb 2024 10:33:37 +0200 Subject: [PATCH 3/6] Update getFileBlock This adds more error checking and command formatting to make it similar to other methods. Also makes detecting comma_idx (offset of file size in the response) more reliable --- ...parkFun_u-blox_SARA-R5_Arduino_Library.cpp | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp index 9886298..71e1db3 100644 --- a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp +++ b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp @@ -5582,6 +5582,8 @@ SARA_R5_error_t SARA_R5::getFileContents(String filename, char *contents) SARA_R5_error_t SARA_R5::getFileBlock(const String& filename, char* buffer, size_t offset, size_t requested_length, size_t& bytes_read) { + SARA_R5_error_t err; + char *command; bytes_read = 0; if (filename.length() < 1 || buffer == nullptr || requested_length < 1) { @@ -5599,10 +5601,15 @@ SARA_R5_error_t SARA_R5::getFileBlock(const String& filename, char* buffer, size return SARA_R5_ERROR_INVALID; } - size_t cmd_len = filename.length() + 32; - char* cmd = sara_r5_calloc_char(cmd_len); - sprintf(cmd, "at+urdblock=\"%s\",%lu,%lu\r\n", filename.c_str(), offset, requested_length); - sendCommand(cmd, false); + command = sara_r5_calloc_char(strlen(SARA_R5_FILE_SYSTEM_READ_BLOCK) + filename.length() + 28); + if (command == nullptr) + { + return SARA_R5_ERROR_OUT_OF_MEMORY; + } + + sprintf(command, "%s=\"%s\",%lu,%lu", SARA_R5_FILE_SYSTEM_READ_BLOCK, filename.c_str(), offset, requested_length); + + sendCommand(command, true); int ich; char ch; @@ -5617,24 +5624,24 @@ SARA_R5_error_t SARA_R5::getFileBlock(const String& filename, char* buffer, size continue; } ch = (char)(ich & 0xFF); - cmd[bytes_read++] = ch; + command[bytes_read++] = ch; if (ch == '"') { quote_count++; } - else if (ch == ',' && comma_idx == 0) + else if (ch == ',' && quote_count == 2) { comma_idx = bytes_read; } } - cmd[bytes_read] = 0; - cmd[bytes_read - 2] = 0; + command[bytes_read] = 0; + command[bytes_read - 2] = 0; // Example response: // +URDBLOCK: "wombat.bin",64000,"... " - size_t data_length = strtoul(&cmd[comma_idx], nullptr, 10); - free(cmd); + size_t data_length = strtoul(&command[comma_idx], nullptr, 10); + free(command); bytes_read = 0; size_t bytes_remaining = data_length; From 5ac2703503a618f9da3e1fff549d1fbe23e6cc5d Mon Sep 17 00:00:00 2001 From: Sasha Olenyev Date: Mon, 5 Feb 2024 14:51:26 +0200 Subject: [PATCH 4/6] Update sprintf %lu in getFileBlock Added sprintf arguments type casting from size_t to unsigned long (or unsigned long long on 64-bit arch) --- src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp index 71e1db3..20a0cdc 100644 --- a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp +++ b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp @@ -5606,9 +5606,11 @@ SARA_R5_error_t SARA_R5::getFileBlock(const String& filename, char* buffer, size { return SARA_R5_ERROR_OUT_OF_MEMORY; } - - sprintf(command, "%s=\"%s\",%lu,%lu", SARA_R5_FILE_SYSTEM_READ_BLOCK, filename.c_str(), offset, requested_length); - +#ifdef ULLONG_MAX + sprintf(command, "%s=\"%s\",%llu,%llu", SARA_R5_FILE_SYSTEM_READ_BLOCK, filename.c_str(), (unsigned long long) offset, (unsigned long long) requested_length); +#else + sprintf(command, "%s=\"%s\",%lu,%lu", SARA_R5_FILE_SYSTEM_READ_BLOCK, filename.c_str(), (unsigned long) offset, (unsigned long) requested_length); +#endif sendCommand(command, true); int ich; From a2a7a13ac639cc3e62ebaa171cfa52b3a33d316a Mon Sep 17 00:00:00 2001 From: Sasha Olenyev Date: Mon, 5 Feb 2024 16:23:16 +0200 Subject: [PATCH 5/6] Update getFileBlock response parsing and error handling This adds response error checking for getFileBlock and minor formatting fixes to make it similar to other methods --- ...parkFun_u-blox_SARA-R5_Arduino_Library.cpp | 97 +++++++++++++------ src/SparkFun_u-blox_SARA-R5_Arduino_Library.h | 2 +- 2 files changed, 70 insertions(+), 29 deletions(-) diff --git a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp index 20a0cdc..6d81cba 100644 --- a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp +++ b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp @@ -5580,12 +5580,14 @@ SARA_R5_error_t SARA_R5::getFileContents(String filename, char *contents) return err; } -SARA_R5_error_t SARA_R5::getFileBlock(const String& filename, char* buffer, size_t offset, size_t requested_length, size_t& bytes_read) +SARA_R5_error_t SARA_R5::getFileBlock(const String& filename, char* buffer, size_t offset, size_t requestedLength, size_t& bytesRead) { SARA_R5_error_t err; char *command; - bytes_read = 0; - if (filename.length() < 1 || buffer == nullptr || requested_length < 1) + char *response; + + bytesRead = 0; + if (filename.length() < 1 || buffer == nullptr || requestedLength < 1) { return SARA_R5_ERROR_UNEXPECTED_PARAM; } @@ -5607,18 +5609,45 @@ SARA_R5_error_t SARA_R5::getFileBlock(const String& filename, char* buffer, size return SARA_R5_ERROR_OUT_OF_MEMORY; } #ifdef ULLONG_MAX - sprintf(command, "%s=\"%s\",%llu,%llu", SARA_R5_FILE_SYSTEM_READ_BLOCK, filename.c_str(), (unsigned long long) offset, (unsigned long long) requested_length); + sprintf(command, "%s=\"%s\",%llu,%llu", SARA_R5_FILE_SYSTEM_READ_BLOCK, filename.c_str(), (unsigned long long) offset, (unsigned long long) requestedLength); #else - sprintf(command, "%s=\"%s\",%lu,%lu", SARA_R5_FILE_SYSTEM_READ_BLOCK, filename.c_str(), (unsigned long) offset, (unsigned long) requested_length); + sprintf(command, "%s=\"%s\",%lu,%lu", SARA_R5_FILE_SYSTEM_READ_BLOCK, filename.c_str(), (unsigned long) offset, (unsigned long) requestedLength); #endif + + response = sara_r5_calloc_char(minimumResponseAllocation); + if (response == nullptr) + { + if (_printDebug == true) + { + _debugPort->print(F("getFileBlock: response alloc failed: ")); + _debugPort->println(minimumResponseAllocation); + } + free(command); + return SARA_R5_ERROR_OUT_OF_MEMORY; + } + + // Send command and wait for some response + // Response format: \r\n+URDBLOCK: "filename",64000,"these bytes are the data of the file block"\r\n\r\nOK\r\n sendCommand(command, true); + err = waitForResponse(SARA_R5_FILE_SYSTEM_READ_BLOCK, SARA_R5_RESPONSE_ERROR, 5 * SARA_R5_STANDARD_RESPONSE_TIMEOUT); + if (err != SARA_R5_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("getFileBlock: waitForResponse returned err ")); + _debugPort->println(err); + } + free(command); + free(response); + return err; + } + // Skip the filename in quotes and get the data length index int ich; char ch; - int quote_count = 0; - size_t comma_idx = 0; - - while (quote_count < 3) + int quoteCount = 0; + size_t lengthIndex = 0; + while (quoteCount < 3 && bytesRead < minimumResponseAllocation) { ich = _hardSerial->read(); if (ich < 0) @@ -5626,36 +5655,48 @@ SARA_R5_error_t SARA_R5::getFileBlock(const String& filename, char* buffer, size continue; } ch = (char)(ich & 0xFF); - command[bytes_read++] = ch; + response[bytesRead++] = ch; if (ch == '"') { - quote_count++; + quoteCount++; } - else if (ch == ',' && quote_count == 2) + else if (ch == ',' && lengthIndex == 0 && quoteCount == 2) { - comma_idx = bytes_read; + lengthIndex = bytesRead; } } + response[bytesRead] = 0; // Make response a null-terminated string + response[bytesRead - 2] = 0; // Terminate response string right after block length + size_t data_length = strtoul(&response[lengthIndex], nullptr, 10); - command[bytes_read] = 0; - command[bytes_read - 2] = 0; - - // Example response: - // +URDBLOCK: "wombat.bin",64000,"... " - size_t data_length = strtoul(&command[comma_idx], nullptr, 10); - free(command); - - bytes_read = 0; - size_t bytes_remaining = data_length; - while (bytes_read < data_length) + // Read file block data directly into supplied buffer + bytesRead = 0; + size_t bytesRemaining = data_length; + while (bytesRead < data_length) { // This method seems more reliable than reading a byte at a time. - size_t rc = _hardSerial->readBytes(&buffer[bytes_read], bytes_remaining); - bytes_read += rc; - bytes_remaining -= rc; + size_t rc = _hardSerial->readBytes(&buffer[bytesRead], bytesRemaining); + bytesRead += rc; + bytesRemaining -= rc; } - return SARA_R5_ERROR_SUCCESS; + // Read rest of response until \r\nOK\r\n + err = waitForResponse(SARA_R5_RESPONSE_OK, SARA_R5_RESPONSE_ERROR, SARA_R5_STANDARD_RESPONSE_TIMEOUT); + if (err != SARA_R5_ERROR_SUCCESS) + { + if (_printDebug == true) + { + _debugPort->print(F("getFileBlock: waitForResponse returned err ")); + _debugPort->println(err); + } + free(command); + free(response); + return err; + } + + free(command); + free(response); + return err; } SARA_R5_error_t SARA_R5::getFileSize(String filename, int *size) diff --git a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h index ea1a274..46dd1cd 100644 --- a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h +++ b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.h @@ -1010,7 +1010,7 @@ class SARA_R5 : public Print // TO DO: add full support for file tags. Default tag to USER SARA_R5_error_t getFileContents(String filename, String *contents); // OK for text files. But will fail with binary files (containing \0) on some platforms. SARA_R5_error_t getFileContents(String filename, char *contents); // OK for binary files. Make sure contents can hold the entire file. Get the size first with getFileSize. - SARA_R5_error_t getFileBlock(const String& filename, char* buffer, size_t offset, size_t length, size_t& bytes_read); // OK for binary files. Make sure buffer can hold the requested block size. + SARA_R5_error_t getFileBlock(const String& filename, char* buffer, size_t offset, size_t requestedLength, size_t& bytesRead); // OK for binary files. Make sure buffer can hold the requested block size. // Append data to a file, delete file first to not appends the data. SARA_R5_error_t appendFileContents(String filename, String str); From 71827b73a126f68daac4a7bf517bcc5836312742 Mon Sep 17 00:00:00 2001 From: Sasha Olenyev Date: Mon, 5 Feb 2024 16:45:54 +0200 Subject: [PATCH 6/6] Update sprintf %lu in getFileBlock After more testing, kept only casting from size_t to unsigned long (compatible with 32-bit MCUs) --- src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp index 6d81cba..699610a 100644 --- a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp +++ b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp @@ -5608,11 +5608,7 @@ SARA_R5_error_t SARA_R5::getFileBlock(const String& filename, char* buffer, size { return SARA_R5_ERROR_OUT_OF_MEMORY; } -#ifdef ULLONG_MAX - sprintf(command, "%s=\"%s\",%llu,%llu", SARA_R5_FILE_SYSTEM_READ_BLOCK, filename.c_str(), (unsigned long long) offset, (unsigned long long) requestedLength); -#else sprintf(command, "%s=\"%s\",%lu,%lu", SARA_R5_FILE_SYSTEM_READ_BLOCK, filename.c_str(), (unsigned long) offset, (unsigned long) requestedLength); -#endif response = sara_r5_calloc_char(minimumResponseAllocation); if (response == nullptr)