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 }} diff --git a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp index 490a161..699610a 100644 --- a/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp +++ b/src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp @@ -5580,10 +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) { - bytes_read = 0; - if (filename.length() < 1 || buffer == nullptr || requested_length < 1) + SARA_R5_error_t err; + char *command; + char *response; + + bytesRead = 0; + if (filename.length() < 1 || buffer == nullptr || requestedLength < 1) { return SARA_R5_ERROR_UNEXPECTED_PARAM; } @@ -5599,17 +5603,47 @@ 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\",%zu,%zu\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(), (unsigned long) offset, (unsigned long) requestedLength); + 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) @@ -5617,36 +5651,48 @@ SARA_R5_error_t SARA_R5::getFileBlock(const String& filename, char* buffer, size continue; } ch = (char)(ich & 0xFF); - cmd[bytes_read++] = ch; + response[bytesRead++] = ch; if (ch == '"') { - quote_count++; + quoteCount++; } - else if (ch == ',' && comma_idx == 0) + 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); - cmd[bytes_read] = 0; - cmd[bytes_read - 2] = 0; - - // Example response: - // +URDBLOCK: "wombat.bin",64000,"... " - size_t data_length = strtoul(&cmd[comma_idx], nullptr, 10); - free(cmd); - - 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);