Merge pull request #136 from NordicSemiconductor/feature/upload-part2-when-part1-fails

Send App when SD+BL failed in Secure DFU
This commit is contained in:
Aleksander Nowakowski 2018-10-17 17:45:49 +02:00 committed by GitHub
commit 1d3865b06a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 37 additions and 5 deletions

View File

@ -263,6 +263,7 @@ import no.nordicsemi.android.dfu.internal.exception.UploadAbortedException;
/**
* Wends the whole init packet stream to the given characteristic.
* @param characteristic the target characteristic
* @param crc32 the CRC object to be updated based on the data sent
* @throws DfuException
* @throws DeviceDisconnectedException
* @throws UploadAbortedException

View File

@ -29,6 +29,7 @@ import android.content.Intent;
import android.os.Build;
import android.os.SystemClock;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Locale;
@ -44,7 +45,9 @@ import no.nordicsemi.android.dfu.internal.exception.UnknownResponseException;
import no.nordicsemi.android.dfu.internal.exception.UploadAbortedException;
import no.nordicsemi.android.error.SecureDfuError;
/* package */ class SecureDfuImpl extends BaseCustomDfuImpl {
/* package */
@SuppressWarnings("JavaDoc")
class SecureDfuImpl extends BaseCustomDfuImpl {
// UUIDs used by the DFU
protected static final UUID DEFAULT_DFU_SERVICE_UUID = new UUID(0x0000FE5900001000L, 0x800000805F9B34FBL); // 16-bit UUID assigned by Bluetooth SIG
protected static final UUID DEFAULT_DFU_CONTROL_POINT_UUID = new UUID(0x8EC90001F3154F60L, 0x9FB8838830DAEA50L);
@ -220,7 +223,33 @@ import no.nordicsemi.android.error.SecureDfuError;
mService.waitFor(1000);
// End
sendInitPacket(gatt);
try {
sendInitPacket(gatt, true);
} catch (final RemoteDfuException e) {
// If the SD+BL upload failed, we may still be able to upload the App.
// The SD+BL might have been updated before.
if (!mProgressInfo.isLastPart()) {
mRemoteErrorOccurred = false;
logw("Sending SD+BL failed. Trying to send App only");
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_WARNING, "Invalid system components. Trying to send application");
mFileType = DfuBaseService.TYPE_APPLICATION;
// Set new content type in the ZIP Input Stream and update sizes of images
final ArchiveInputStream zhis = (ArchiveInputStream) mFirmwareStream;
zhis.setContentType(mFileType);
final byte[] applicationInit = zhis.getApplicationInit();
mInitPacketStream = new ByteArrayInputStream(applicationInit);
mInitPacketSizeInBytes = applicationInit.length;
mImageSizeInBytes = zhis.applicationImageSize();
mProgressInfo.init(mImageSizeInBytes, 2, 2);
sendInitPacket(gatt, false);
} else {
// There's noting we could do about it.
throw e;
}
}
sendFirmware(gatt);
// The device will reset so we don't have to send Disconnect signal.
@ -273,14 +302,16 @@ import no.nordicsemi.android.error.SecureDfuError;
* Init file as the previous one was different.</li>
* </ol>
* Sending of the Init packet is done without using PRNs (Packet Receipt Notifications), so they are disabled prior to sending the data.
* @param gatt the target GATT device
*
* @param gatt the target GATT device
* @param allowResume true to allow resuming sending Init Packet. If false, it will be started again.
* @throws RemoteDfuException
* @throws DeviceDisconnectedException
* @throws DfuException
* @throws UploadAbortedException
* @throws UnknownResponseException
*/
private void sendInitPacket(final BluetoothGatt gatt) throws RemoteDfuException, DeviceDisconnectedException, DfuException, UploadAbortedException, UnknownResponseException {
private void sendInitPacket(final BluetoothGatt gatt, final boolean allowResume) throws RemoteDfuException, DeviceDisconnectedException, DfuException, UploadAbortedException, UnknownResponseException {
final CRC32 crc32 = new CRC32(); // Used to calculate CRC32 of the Init packet
ObjectChecksum checksum;
@ -298,7 +329,7 @@ import no.nordicsemi.android.error.SecureDfuError;
// and resume sending the init packet, or even skip sending it if the whole file was sent before.
boolean skipSendingInitPacket = false;
boolean resumeSendingInitPacket = false;
if (info.offset > 0 && info.offset <= mInitPacketSizeInBytes) {
if (allowResume && info.offset > 0 && info.offset <= mInitPacketSizeInBytes) {
try {
// Read the same number of bytes from the current init packet to calculate local CRC32
final byte[] buffer = new byte[info.offset];