Some more changes
This commit is contained in:
parent
8b8932fd57
commit
d4e24580d7
|
@ -451,15 +451,18 @@ import no.nordicsemi.android.error.SecureDfuError;
|
||||||
if (info.offset > 0) {
|
if (info.offset > 0) {
|
||||||
try {
|
try {
|
||||||
i = info.offset / info.maxSize;
|
i = info.offset / info.maxSize;
|
||||||
final int bytesSentAndExecuted = info.maxSize * i;
|
int bytesSentAndExecuted = info.maxSize * i;
|
||||||
final int bytesSentNotExecuted = info.offset - bytesSentAndExecuted;
|
int bytesSentNotExecuted = info.offset - bytesSentAndExecuted;
|
||||||
|
|
||||||
// Read the same number of bytes from the current init packet to calculate local CRC32
|
// Read the same number of bytes from the current init packet to calculate local CRC32
|
||||||
if (bytesSentAndExecuted > 0) {
|
if (bytesSentAndExecuted > 0) {
|
||||||
mFirmwareStream.read(new byte[bytesSentAndExecuted]); // Read executed bytes
|
mFirmwareStream.read(new byte[bytesSentAndExecuted]); // Read executed bytes
|
||||||
mFirmwareStream.mark(info.maxSize); // Mark here
|
mFirmwareStream.mark(info.maxSize); // Mark here
|
||||||
}
|
}
|
||||||
mFirmwareStream.read(new byte[bytesSentNotExecuted]); // Read the rest
|
if (bytesSentNotExecuted > 0) {
|
||||||
|
// This may be 0 if the whole last chunk was completed before. It may not have been executed and may have CRC error.
|
||||||
|
mFirmwareStream.read(new byte[bytesSentNotExecuted]); // Read the rest
|
||||||
|
}
|
||||||
|
|
||||||
// Calculate the CRC32
|
// Calculate the CRC32
|
||||||
final int crc = (int) (((ArchiveInputStream) mFirmwareStream).getCrc32() & 0xFFFFFFFFL);
|
final int crc = (int) (((ArchiveInputStream) mFirmwareStream).getCrc32() & 0xFFFFFFFFL);
|
||||||
|
@ -469,10 +472,19 @@ import no.nordicsemi.android.error.SecureDfuError;
|
||||||
mProgressInfo.setBytesReceived(info.offset);
|
mProgressInfo.setBytesReceived(info.offset);
|
||||||
resumeSendingData = true;
|
resumeSendingData = true;
|
||||||
} else {
|
} else {
|
||||||
|
if (bytesSentNotExecuted == 0) {
|
||||||
|
// Looks like the whole last chunk was invalid and not executed. We have to rewind last maxSize bytes as we don't have any mark there.
|
||||||
|
bytesSentAndExecuted -= info.maxSize;
|
||||||
|
bytesSentNotExecuted = info.maxSize;
|
||||||
|
((ArchiveInputStream) mFirmwareStream).rewind(info.maxSize);
|
||||||
|
mFirmwareStream.mark(info.maxSize);
|
||||||
|
}
|
||||||
// The CRC of the current object is not correct. If there was another Data object sent before, its CRC must have been correct,
|
// The CRC of the current object is not correct. If there was another Data object sent before, its CRC must have been correct,
|
||||||
// as it has been executed. Either way, we have to create the current object again.
|
// as it has been executed. Either way, we have to create the current object again.
|
||||||
mProgressInfo.setBytesSent(bytesSentAndExecuted);
|
mProgressInfo.setBytesSent(bytesSentAndExecuted);
|
||||||
mProgressInfo.setBytesReceived(bytesSentAndExecuted);
|
mProgressInfo.setBytesReceived(bytesSentAndExecuted);
|
||||||
|
info.offset -= bytesSentNotExecuted;
|
||||||
|
info.CRC32 = 0; // invalidate
|
||||||
mFirmwareStream.reset();
|
mFirmwareStream.reset();
|
||||||
}
|
}
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
|
@ -486,70 +498,74 @@ import no.nordicsemi.android.error.SecureDfuError;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Each page will be sent in MAX_ATTEMPTS
|
// Each page will be sent in MAX_ATTEMPTS
|
||||||
int attempt = 1;
|
if (info.offset < mImageSizeInBytes) {
|
||||||
while (mProgressInfo.getAvailableObjectSizeIsBytes() > 0) {
|
int attempt = 1;
|
||||||
if (!resumeSendingData) {
|
while (mProgressInfo.getAvailableObjectSizeIsBytes() > 0) {
|
||||||
// Create the Data object
|
if (!resumeSendingData) {
|
||||||
logi("Creating Data object (Op Code = 1, Type = 2, Size = " + mProgressInfo.getAvailableObjectSizeIsBytes() + ") (" + (i + 1) + "/" + count + ")");
|
// Create the Data object
|
||||||
writeCreateRequest(OBJECT_DATA, mProgressInfo.getAvailableObjectSizeIsBytes());
|
logi("Creating Data object (Op Code = 1, Type = 2, Size = " + mProgressInfo.getAvailableObjectSizeIsBytes() + ") (" + (i + 1) + "/" + count + ")");
|
||||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, "Data object (" + (i + 1) + "/" + count + ") created");
|
writeCreateRequest(OBJECT_DATA, mProgressInfo.getAvailableObjectSizeIsBytes());
|
||||||
|
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, "Data object (" + (i + 1) + "/" + count + ") created");
|
||||||
|
|
||||||
resumeSendingData = false;
|
resumeSendingData = false;
|
||||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, "Uploading firmware...");
|
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, "Uploading firmware...");
|
||||||
} else {
|
} else {
|
||||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, "Resuming uploading firmware...");
|
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, "Resuming uploading firmware...");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the current object part
|
// Send the current object part
|
||||||
try {
|
try {
|
||||||
logi("Uploading firmware...");
|
logi("Uploading firmware...");
|
||||||
uploadFirmwareImage(mPacketCharacteristic);
|
uploadFirmwareImage(mPacketCharacteristic);
|
||||||
} catch (final DeviceDisconnectedException e) {
|
} catch (final DeviceDisconnectedException e) {
|
||||||
loge("Disconnected while sending data");
|
loge("Disconnected while sending data");
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate Checksum
|
// Calculate Checksum
|
||||||
logi("Sending Calculate Checksum command (Op Code = 3)");
|
logi("Sending Calculate Checksum command (Op Code = 3)");
|
||||||
final ObjectChecksum checksum = readChecksum();
|
final ObjectChecksum checksum = readChecksum();
|
||||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, String.format(Locale.US, "Checksum received (Offset = %d, CRC = %08X)", checksum.offset, checksum.CRC32));
|
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, String.format(Locale.US, "Checksum received (Offset = %d, CRC = %08X)", checksum.offset, checksum.CRC32));
|
||||||
logi(String.format(Locale.US, "Checksum received (Offset = %d, CRC = %08X)", checksum.offset, checksum.CRC32));
|
logi(String.format(Locale.US, "Checksum received (Offset = %d, CRC = %08X)", checksum.offset, checksum.CRC32));
|
||||||
|
|
||||||
// Calculate the CRC32
|
// Calculate the CRC32
|
||||||
final int crc = (int) (((ArchiveInputStream) mFirmwareStream).getCrc32() & 0xFFFFFFFFL);
|
final int crc = (int) (((ArchiveInputStream) mFirmwareStream).getCrc32() & 0xFFFFFFFFL);
|
||||||
if (crc == checksum.CRC32) {
|
if (crc == checksum.CRC32) {
|
||||||
// Execute Init packet
|
// Execute Init packet
|
||||||
logi("Executing data object (Op Code = 4)");
|
logi("Executing data object (Op Code = 4)");
|
||||||
writeExecute();
|
writeExecute();
|
||||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, "Data object executed");
|
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, "Data object executed");
|
||||||
|
|
||||||
// Increment iterator
|
// Increment iterator
|
||||||
i++;
|
i++;
|
||||||
attempt = 1;
|
attempt = 1;
|
||||||
} else {
|
} else {
|
||||||
if (attempt < MAX_ATTEMPTS) {
|
if (attempt < MAX_ATTEMPTS) {
|
||||||
attempt++;
|
attempt++;
|
||||||
logi("CRC32 does not match! Retrying...(" + attempt + "/" + MAX_ATTEMPTS + ")");
|
logi("CRC32 does not match! Retrying...(" + attempt + "/" + MAX_ATTEMPTS + ")");
|
||||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_WARNING, "CRC32 does not match! Retrying...(" + attempt + "/" + MAX_ATTEMPTS + ")");
|
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_WARNING, "CRC32 does not match! Retrying...(" + attempt + "/" + MAX_ATTEMPTS + ")");
|
||||||
try {
|
try {
|
||||||
mFirmwareStream.reset();
|
mFirmwareStream.reset();
|
||||||
mProgressInfo.setBytesSent(checksum.offset - info.maxSize);
|
mProgressInfo.setBytesSent(checksum.offset - info.maxSize);
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
loge("Error while resetting the firmware stream", e);
|
loge("Error while resetting the firmware stream", e);
|
||||||
mService.terminateConnection(gatt, DfuBaseService.ERROR_FILE_IO_EXCEPTION);
|
mService.terminateConnection(gatt, DfuBaseService.ERROR_FILE_IO_EXCEPTION);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
loge("CRC32 does not match!");
|
||||||
|
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_ERROR, "CRC32 does not match!");
|
||||||
|
mService.terminateConnection(gatt, DfuBaseService.ERROR_CRC_ERROR);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
loge("CRC32 does not match!");
|
|
||||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_ERROR, "CRC32 does not match!");
|
|
||||||
mService.terminateConnection(gatt, DfuBaseService.ERROR_CRC_ERROR);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
final long endTime = SystemClock.elapsedRealtime();
|
||||||
|
logi("Transfer of " + mProgressInfo.getBytesSent() + " bytes has taken " + (endTime - startTime) + " ms");
|
||||||
|
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, "Upload completed in " + (endTime - startTime) + " ms");
|
||||||
|
} else {
|
||||||
|
// Looks as if the whole file was sent correctly but
|
||||||
}
|
}
|
||||||
final long endTime = SystemClock.elapsedRealtime();
|
|
||||||
logi("Transfer of " + mProgressInfo.getBytesSent() + " bytes has taken " + (endTime - startTime) + " ms");
|
|
||||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, "Upload completed in " + (endTime - startTime) + " ms");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -350,6 +350,19 @@ public class ArchiveInputStream extends ZipInputStream {
|
||||||
bytesReadFromMarkedSource = bytesReadFromCurrentSource;
|
bytesReadFromMarkedSource = bytesReadFromCurrentSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void rewind(final int offset) {
|
||||||
|
if (applicationBytes != null && (softDeviceBytes != null || bootloaderBytes != null || softDeviceAndBootloaderBytes != null))
|
||||||
|
throw new UnsupportedOperationException("Application must be sent in a separate connection.");
|
||||||
|
|
||||||
|
bytesRead = Math.max(bytesRead - offset, 0);
|
||||||
|
if (currentSource == bootloaderBytes && softDeviceBytes != null && bytesReadFromCurrentSource - offset < 0) {
|
||||||
|
currentSource = softDeviceBytes;
|
||||||
|
bytesReadFromCurrentSource = Math.max(softDeviceSize - (offset - bytesReadFromCurrentSource), 0);
|
||||||
|
} else {
|
||||||
|
bytesReadFromCurrentSource -= Math.max(bytesReadFromCurrentSource - offset, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void reset() throws IOException {
|
public void reset() throws IOException {
|
||||||
if (applicationBytes != null && (softDeviceBytes != null || bootloaderBytes != null || softDeviceAndBootloaderBytes != null))
|
if (applicationBytes != null && (softDeviceBytes != null || bootloaderBytes != null || softDeviceAndBootloaderBytes != null))
|
||||||
|
|
Loading…
Reference in New Issue