Skip to content

Commit a2a7a13

Browse files
committed
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
1 parent 5ac2703 commit a2a7a13

File tree

2 files changed

+70
-29
lines changed

2 files changed

+70
-29
lines changed

src/SparkFun_u-blox_SARA-R5_Arduino_Library.cpp

+69-28
Original file line numberDiff line numberDiff line change
@@ -5580,12 +5580,14 @@ SARA_R5_error_t SARA_R5::getFileContents(String filename, char *contents)
55805580
return err;
55815581
}
55825582

5583-
SARA_R5_error_t SARA_R5::getFileBlock(const String& filename, char* buffer, size_t offset, size_t requested_length, size_t& bytes_read)
5583+
SARA_R5_error_t SARA_R5::getFileBlock(const String& filename, char* buffer, size_t offset, size_t requestedLength, size_t& bytesRead)
55845584
{
55855585
SARA_R5_error_t err;
55865586
char *command;
5587-
bytes_read = 0;
5588-
if (filename.length() < 1 || buffer == nullptr || requested_length < 1)
5587+
char *response;
5588+
5589+
bytesRead = 0;
5590+
if (filename.length() < 1 || buffer == nullptr || requestedLength < 1)
55895591
{
55905592
return SARA_R5_ERROR_UNEXPECTED_PARAM;
55915593
}
@@ -5607,55 +5609,94 @@ SARA_R5_error_t SARA_R5::getFileBlock(const String& filename, char* buffer, size
56075609
return SARA_R5_ERROR_OUT_OF_MEMORY;
56085610
}
56095611
#ifdef ULLONG_MAX
5610-
sprintf(command, "%s=\"%s\",%llu,%llu", SARA_R5_FILE_SYSTEM_READ_BLOCK, filename.c_str(), (unsigned long long) offset, (unsigned long long) requested_length);
5612+
sprintf(command, "%s=\"%s\",%llu,%llu", SARA_R5_FILE_SYSTEM_READ_BLOCK, filename.c_str(), (unsigned long long) offset, (unsigned long long) requestedLength);
56115613
#else
5612-
sprintf(command, "%s=\"%s\",%lu,%lu", SARA_R5_FILE_SYSTEM_READ_BLOCK, filename.c_str(), (unsigned long) offset, (unsigned long) requested_length);
5614+
sprintf(command, "%s=\"%s\",%lu,%lu", SARA_R5_FILE_SYSTEM_READ_BLOCK, filename.c_str(), (unsigned long) offset, (unsigned long) requestedLength);
56135615
#endif
5616+
5617+
response = sara_r5_calloc_char(minimumResponseAllocation);
5618+
if (response == nullptr)
5619+
{
5620+
if (_printDebug == true)
5621+
{
5622+
_debugPort->print(F("getFileBlock: response alloc failed: "));
5623+
_debugPort->println(minimumResponseAllocation);
5624+
}
5625+
free(command);
5626+
return SARA_R5_ERROR_OUT_OF_MEMORY;
5627+
}
5628+
5629+
// Send command and wait for some response
5630+
// Response format: \r\n+URDBLOCK: "filename",64000,"these bytes are the data of the file block"\r\n\r\nOK\r\n
56145631
sendCommand(command, true);
5632+
err = waitForResponse(SARA_R5_FILE_SYSTEM_READ_BLOCK, SARA_R5_RESPONSE_ERROR, 5 * SARA_R5_STANDARD_RESPONSE_TIMEOUT);
5633+
if (err != SARA_R5_ERROR_SUCCESS)
5634+
{
5635+
if (_printDebug == true)
5636+
{
5637+
_debugPort->print(F("getFileBlock: waitForResponse returned err "));
5638+
_debugPort->println(err);
5639+
}
5640+
free(command);
5641+
free(response);
5642+
return err;
5643+
}
56155644

5645+
// Skip the filename in quotes and get the data length index
56165646
int ich;
56175647
char ch;
5618-
int quote_count = 0;
5619-
size_t comma_idx = 0;
5620-
5621-
while (quote_count < 3)
5648+
int quoteCount = 0;
5649+
size_t lengthIndex = 0;
5650+
while (quoteCount < 3 && bytesRead < minimumResponseAllocation)
56225651
{
56235652
ich = _hardSerial->read();
56245653
if (ich < 0)
56255654
{
56265655
continue;
56275656
}
56285657
ch = (char)(ich & 0xFF);
5629-
command[bytes_read++] = ch;
5658+
response[bytesRead++] = ch;
56305659
if (ch == '"')
56315660
{
5632-
quote_count++;
5661+
quoteCount++;
56335662
}
5634-
else if (ch == ',' && quote_count == 2)
5663+
else if (ch == ',' && lengthIndex == 0 && quoteCount == 2)
56355664
{
5636-
comma_idx = bytes_read;
5665+
lengthIndex = bytesRead;
56375666
}
56385667
}
5668+
response[bytesRead] = 0; // Make response a null-terminated string
5669+
response[bytesRead - 2] = 0; // Terminate response string right after block length
5670+
size_t data_length = strtoul(&response[lengthIndex], nullptr, 10);
56395671

5640-
command[bytes_read] = 0;
5641-
command[bytes_read - 2] = 0;
5642-
5643-
// Example response:
5644-
// +URDBLOCK: "wombat.bin",64000,"<data starts here>... "<cr><lf>
5645-
size_t data_length = strtoul(&command[comma_idx], nullptr, 10);
5646-
free(command);
5647-
5648-
bytes_read = 0;
5649-
size_t bytes_remaining = data_length;
5650-
while (bytes_read < data_length)
5672+
// Read file block data directly into supplied buffer
5673+
bytesRead = 0;
5674+
size_t bytesRemaining = data_length;
5675+
while (bytesRead < data_length)
56515676
{
56525677
// This method seems more reliable than reading a byte at a time.
5653-
size_t rc = _hardSerial->readBytes(&buffer[bytes_read], bytes_remaining);
5654-
bytes_read += rc;
5655-
bytes_remaining -= rc;
5678+
size_t rc = _hardSerial->readBytes(&buffer[bytesRead], bytesRemaining);
5679+
bytesRead += rc;
5680+
bytesRemaining -= rc;
56565681
}
56575682

5658-
return SARA_R5_ERROR_SUCCESS;
5683+
// Read rest of response until \r\nOK\r\n
5684+
err = waitForResponse(SARA_R5_RESPONSE_OK, SARA_R5_RESPONSE_ERROR, SARA_R5_STANDARD_RESPONSE_TIMEOUT);
5685+
if (err != SARA_R5_ERROR_SUCCESS)
5686+
{
5687+
if (_printDebug == true)
5688+
{
5689+
_debugPort->print(F("getFileBlock: waitForResponse returned err "));
5690+
_debugPort->println(err);
5691+
}
5692+
free(command);
5693+
free(response);
5694+
return err;
5695+
}
5696+
5697+
free(command);
5698+
free(response);
5699+
return err;
56595700
}
56605701

56615702
SARA_R5_error_t SARA_R5::getFileSize(String filename, int *size)

src/SparkFun_u-blox_SARA-R5_Arduino_Library.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -1010,7 +1010,7 @@ class SARA_R5 : public Print
10101010
// TO DO: add full support for file tags. Default tag to USER
10111011
SARA_R5_error_t getFileContents(String filename, String *contents); // OK for text files. But will fail with binary files (containing \0) on some platforms.
10121012
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.
1013-
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.
1013+
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.
10141014

10151015
// Append data to a file, delete file first to not appends the data.
10161016
SARA_R5_error_t appendFileContents(String filename, String str);

0 commit comments

Comments
 (0)