Validating firmware word-alignment
This commit is contained in:
parent
3605c1cbdb
commit
dcfa4b0f3c
|
@ -1,5 +1,6 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
|
<component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
|
||||||
|
<file url="PROJECT" charset="UTF-8" />
|
||||||
|
</component>
|
||||||
</project>
|
</project>
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,7 @@ import no.nordicsemi.android.dfu.internal.exception.DeviceDisconnectedException;
|
||||||
import no.nordicsemi.android.dfu.internal.exception.DfuException;
|
import no.nordicsemi.android.dfu.internal.exception.DfuException;
|
||||||
import no.nordicsemi.android.dfu.internal.exception.HexFileValidationException;
|
import no.nordicsemi.android.dfu.internal.exception.HexFileValidationException;
|
||||||
import no.nordicsemi.android.dfu.internal.exception.RemoteDfuException;
|
import no.nordicsemi.android.dfu.internal.exception.RemoteDfuException;
|
||||||
|
import no.nordicsemi.android.dfu.internal.exception.SizeValidationException;
|
||||||
import no.nordicsemi.android.dfu.internal.exception.UnknownResponseException;
|
import no.nordicsemi.android.dfu.internal.exception.UnknownResponseException;
|
||||||
import no.nordicsemi.android.dfu.internal.exception.UploadAbortedException;
|
import no.nordicsemi.android.dfu.internal.exception.UploadAbortedException;
|
||||||
import no.nordicsemi.android.dfu.internal.scanner.BootloaderScannerFactory;
|
import no.nordicsemi.android.dfu.internal.scanner.BootloaderScannerFactory;
|
||||||
|
@ -378,7 +379,7 @@ public abstract class DfuBaseService extends IntentService {
|
||||||
*/
|
*/
|
||||||
public static final int ERROR_FILE_ERROR = ERROR_MASK | 0x02;
|
public static final int ERROR_FILE_ERROR = ERROR_MASK | 0x02;
|
||||||
/**
|
/**
|
||||||
* Thrown then input file is not a valid HEX or ZIP file.
|
* Thrown when input file is not a valid HEX or ZIP file.
|
||||||
*/
|
*/
|
||||||
public static final int ERROR_FILE_INVALID = ERROR_MASK | 0x03;
|
public static final int ERROR_FILE_INVALID = ERROR_MASK | 0x03;
|
||||||
/**
|
/**
|
||||||
|
@ -386,7 +387,7 @@ public abstract class DfuBaseService extends IntentService {
|
||||||
*/
|
*/
|
||||||
public static final int ERROR_FILE_IO_EXCEPTION = ERROR_MASK | 0x04;
|
public static final int ERROR_FILE_IO_EXCEPTION = ERROR_MASK | 0x04;
|
||||||
/**
|
/**
|
||||||
* Error thrown then {@code gatt.discoverServices();} returns false.
|
* Error thrown when {@code gatt.discoverServices();} returns false.
|
||||||
*/
|
*/
|
||||||
public static final int ERROR_SERVICE_DISCOVERY_NOT_STARTED = ERROR_MASK | 0x05;
|
public static final int ERROR_SERVICE_DISCOVERY_NOT_STARTED = ERROR_MASK | 0x05;
|
||||||
/**
|
/**
|
||||||
|
@ -413,6 +414,10 @@ public abstract class DfuBaseService extends IntentService {
|
||||||
* DFU Bootloader version 0.6+ requires sending the Init packet. If such bootloader version is detected, but the init packet has not been set this error is thrown.
|
* DFU Bootloader version 0.6+ requires sending the Init packet. If such bootloader version is detected, but the init packet has not been set this error is thrown.
|
||||||
*/
|
*/
|
||||||
public static final int ERROR_INIT_PACKET_REQUIRED = ERROR_MASK | 0x0B;
|
public static final int ERROR_INIT_PACKET_REQUIRED = ERROR_MASK | 0x0B;
|
||||||
|
/**
|
||||||
|
* Thrown when the firmware file is not word-aligned. The firmware size must be dividable by 4 bytes.
|
||||||
|
*/
|
||||||
|
public static final int ERROR_FILE_SIZE_INVALID = ERROR_MASK | 0x0C;
|
||||||
/**
|
/**
|
||||||
* Flag set then the DFU target returned a DFU error. Look for DFU specification to get error codes.
|
* Flag set then the DFU target returned a DFU error. Look for DFU specification to get error codes.
|
||||||
*/
|
*/
|
||||||
|
@ -770,6 +775,8 @@ public abstract class DfuBaseService extends IntentService {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
loge("Connection state change error: " + status + " newState: " + newState);
|
loge("Connection state change error: " + status + " newState: " + newState);
|
||||||
|
if (newState == BluetoothGatt.STATE_DISCONNECTED)
|
||||||
|
mConnectionState = STATE_DISCONNECTED;
|
||||||
mPaused = false;
|
mPaused = false;
|
||||||
mError = ERROR_CONNECTION_STATE_MASK | status;
|
mError = ERROR_CONNECTION_STATE_MASK | status;
|
||||||
}
|
}
|
||||||
|
@ -1178,6 +1185,10 @@ public abstract class DfuBaseService extends IntentService {
|
||||||
|
|
||||||
mInputStream = is;
|
mInputStream = is;
|
||||||
imageSizeInBytes = mImageSizeInBytes = is.available();
|
imageSizeInBytes = mImageSizeInBytes = is.available();
|
||||||
|
|
||||||
|
if ((imageSizeInBytes % 4) != 0)
|
||||||
|
throw new SizeValidationException("The new firmware is not word-aligned.");
|
||||||
|
|
||||||
// Update the file type bit field basing on the ZIP content
|
// Update the file type bit field basing on the ZIP content
|
||||||
if (fileType == TYPE_AUTO && MIME_TYPE_ZIP.equals(mimeType)) {
|
if (fileType == TYPE_AUTO && MIME_TYPE_ZIP.equals(mimeType)) {
|
||||||
final ArchiveInputStream zhis = (ArchiveInputStream) is;
|
final ArchiveInputStream zhis = (ArchiveInputStream) is;
|
||||||
|
@ -1187,6 +1198,15 @@ public abstract class DfuBaseService extends IntentService {
|
||||||
// Set the Init packet stream in case of a ZIP file
|
// Set the Init packet stream in case of a ZIP file
|
||||||
if (MIME_TYPE_ZIP.equals(mimeType)) {
|
if (MIME_TYPE_ZIP.equals(mimeType)) {
|
||||||
final ArchiveInputStream zhis = (ArchiveInputStream) is;
|
final ArchiveInputStream zhis = (ArchiveInputStream) is;
|
||||||
|
|
||||||
|
// Validate sizes
|
||||||
|
if ((fileType & TYPE_APPLICATION) > 0 && (zhis.applicationImageSize() % 4) != 0)
|
||||||
|
throw new SizeValidationException("Application firmware is not word-aligned.");
|
||||||
|
if ((fileType & TYPE_BOOTLOADER) > 0 && (zhis.bootloaderImageSize() % 4) != 0)
|
||||||
|
throw new SizeValidationException("Bootloader firmware is not word-aligned.");
|
||||||
|
if ((fileType & TYPE_SOFT_DEVICE) > 0 && (zhis.softDeviceImageSize() % 4) != 0)
|
||||||
|
throw new SizeValidationException("Soft Device firmware is not word-aligned.");
|
||||||
|
|
||||||
if (fileType == TYPE_APPLICATION) {
|
if (fileType == TYPE_APPLICATION) {
|
||||||
if (zhis.getApplicationInit() != null)
|
if (zhis.getApplicationInit() != null)
|
||||||
initIs = new ByteArrayInputStream(zhis.getApplicationInit());
|
initIs = new ByteArrayInputStream(zhis.getApplicationInit());
|
||||||
|
@ -1204,6 +1224,10 @@ public abstract class DfuBaseService extends IntentService {
|
||||||
loge("An exception occurred while opening file", e);
|
loge("An exception occurred while opening file", e);
|
||||||
updateProgressNotification(ERROR_FILE_NOT_FOUND);
|
updateProgressNotification(ERROR_FILE_NOT_FOUND);
|
||||||
return;
|
return;
|
||||||
|
} catch (final SizeValidationException e) {
|
||||||
|
loge("Firmware not word-aligned", e);
|
||||||
|
updateProgressNotification(ERROR_FILE_SIZE_INVALID);
|
||||||
|
return;
|
||||||
} catch (final IOException e) {
|
} catch (final IOException e) {
|
||||||
loge("An exception occurred while calculating file size", e);
|
loge("An exception occurred while calculating file size", e);
|
||||||
updateProgressNotification(ERROR_FILE_ERROR);
|
updateProgressNotification(ERROR_FILE_ERROR);
|
||||||
|
@ -2844,12 +2868,10 @@ public abstract class DfuBaseService extends IntentService {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loge(final String message) {
|
private void loge(final String message) {
|
||||||
if (BuildConfig.DEBUG)
|
|
||||||
Log.e(TAG, message);
|
Log.e(TAG, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void loge(final String message, final Throwable e) {
|
private void loge(final String message, final Throwable e) {
|
||||||
if (BuildConfig.DEBUG)
|
|
||||||
Log.e(TAG, message, e);
|
Log.e(TAG, message, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
/*************************************************************************************************************************************************
|
||||||
|
* Copyright (c) 2015, Nordic Semiconductor
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
||||||
|
*
|
||||||
|
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
|
||||||
|
* software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||||
|
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
************************************************************************************************************************************************/
|
||||||
|
|
||||||
|
package no.nordicsemi.android.dfu.internal.exception;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This exception is thrown when the firmware size is not word-aligned (number of bytes does not divide by 4).
|
||||||
|
* This is the requirement for the DFU Bootloader.
|
||||||
|
*/
|
||||||
|
public class SizeValidationException extends IOException {
|
||||||
|
private static final long serialVersionUID = -6467104024030837875L;
|
||||||
|
|
||||||
|
public SizeValidationException(final String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
}
|
|
@ -151,6 +151,8 @@ public class GattError {
|
||||||
return "DFU FILE ERROR";
|
return "DFU FILE ERROR";
|
||||||
case DfuBaseService.ERROR_FILE_INVALID:
|
case DfuBaseService.ERROR_FILE_INVALID:
|
||||||
return "DFU NOT A VALID HEX FILE";
|
return "DFU NOT A VALID HEX FILE";
|
||||||
|
case DfuBaseService.ERROR_FILE_SIZE_INVALID:
|
||||||
|
return "DFU FILE NOT WORD ALIGNED";
|
||||||
case DfuBaseService.ERROR_FILE_IO_EXCEPTION:
|
case DfuBaseService.ERROR_FILE_IO_EXCEPTION:
|
||||||
return "DFU IO EXCEPTION";
|
return "DFU IO EXCEPTION";
|
||||||
case DfuBaseService.ERROR_FILE_NOT_FOUND:
|
case DfuBaseService.ERROR_FILE_NOT_FOUND:
|
||||||
|
|
Loading…
Reference in New Issue