Mark position after execute for CRC retry

I've noticed when using in a noisy environment if I ever see a CRC error
all of the subsequent retries fail and the download fails.

I noticed if I print the CRC values expected they change on each retry
attempt.  This seems wrong, since I believe the intent is just to re-send
the last chunk.

I suspect there's a mark() call missing in the success transfer case,
and the position of the last successful create->execute transfer should
be saved. The next retry transfer should only reset to this mark position
and not the beginning of the file.

If I add a call to mFirwmareStream.mark in the CRC success case after
writeExecute() completes I am able to successfully recover from CRC errors.
This commit is contained in:
Dan Walkes 2017-02-02 22:34:00 -07:00
parent 136c7bb2d4
commit 18bdda9a37
1 changed files with 5 additions and 2 deletions

View File

@ -514,13 +514,16 @@ import no.nordicsemi.android.error.SecureDfuError;
// Increment iterator
currentChunk++;
attempt = 1;
mFirmwareStream.mark(0);
} else {
if (attempt < MAX_ATTEMPTS) {
attempt++;
logi("CRC does not match! Retrying...(" + attempt + "/" + MAX_ATTEMPTS + ")");
logi(String.format(Locale.US,"CRC does not match! Expected %08X Retrying...(%d/%d)",crc,attempt,MAX_ATTEMPTS));
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_WARNING, "CRC does not match! Retrying...(" + attempt + "/" + MAX_ATTEMPTS + ")");
try {
mFirmwareStream.reset();
final int crcAfterReset = (int) (((ArchiveInputStream) mFirmwareStream).getCrc32() & 0xFFFFFFFFL);
logi(String.format(Locale.US,"CRC after reset is %08X",crcAfterReset));
mProgressInfo.setBytesSent(checksum.offset - info.maxSize);
} catch (final IOException e) {
loge("Error while resetting the firmware stream", e);
@ -528,7 +531,7 @@ import no.nordicsemi.android.error.SecureDfuError;
return;
}
} else {
loge("CRC does not match!");
loge(String.format("CRC does not match! Expected %08X",crc));
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_ERROR, "CRC does not match!");
mService.terminateConnection(gatt, DfuBaseService.ERROR_CRC_ERROR);
return;