Validating firmware word-alignment

This commit is contained in:
Aleksander Nowakowski 2015-07-27 11:11:26 +02:00
parent 3605c1cbdb
commit dcfa4b0f3c
4 changed files with 71 additions and 9 deletions

View File

@ -1,5 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding" useUTFGuessing="true" native2AsciiForPropertiesFiles="false" />
<component name="Encoding" defaultCharsetForPropertiesFiles="UTF-8">
<file url="PROJECT" charset="UTF-8" />
</component>
</project>

View File

@ -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.HexFileValidationException;
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.UploadAbortedException;
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;
/**
* 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;
/**
@ -386,7 +387,7 @@ public abstract class DfuBaseService extends IntentService {
*/
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;
/**
@ -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.
*/
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.
*/
@ -770,6 +775,8 @@ public abstract class DfuBaseService extends IntentService {
}
} else {
loge("Connection state change error: " + status + " newState: " + newState);
if (newState == BluetoothGatt.STATE_DISCONNECTED)
mConnectionState = STATE_DISCONNECTED;
mPaused = false;
mError = ERROR_CONNECTION_STATE_MASK | status;
}
@ -1178,6 +1185,10 @@ public abstract class DfuBaseService extends IntentService {
mInputStream = is;
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
if (fileType == TYPE_AUTO && MIME_TYPE_ZIP.equals(mimeType)) {
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
if (MIME_TYPE_ZIP.equals(mimeType)) {
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 (zhis.getApplicationInit() != null)
initIs = new ByteArrayInputStream(zhis.getApplicationInit());
@ -1204,6 +1224,10 @@ public abstract class DfuBaseService extends IntentService {
loge("An exception occurred while opening file", e);
updateProgressNotification(ERROR_FILE_NOT_FOUND);
return;
} catch (final SizeValidationException e) {
loge("Firmware not word-aligned", e);
updateProgressNotification(ERROR_FILE_SIZE_INVALID);
return;
} catch (final IOException e) {
loge("An exception occurred while calculating file size", e);
updateProgressNotification(ERROR_FILE_ERROR);
@ -2844,13 +2868,11 @@ public abstract class DfuBaseService extends IntentService {
}
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) {
if (BuildConfig.DEBUG)
Log.e(TAG, message, e);
Log.e(TAG, message, e);
}
private void logw(final String message) {

View File

@ -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);
}
}

View File

@ -151,6 +151,8 @@ public class GattError {
return "DFU FILE ERROR";
case DfuBaseService.ERROR_FILE_INVALID:
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:
return "DFU IO EXCEPTION";
case DfuBaseService.ERROR_FILE_NOT_FOUND: