Option to change MBR size added
git-svn-id: http://svn.nordicsemi.no/applications/mobile/android/DFULibrary/trunk@6151 94a72e49-5737-764a-8bf3-0d5ceb61e552
This commit is contained in:
parent
a1f4dd503d
commit
45912cb27b
|
@ -657,7 +657,7 @@ public abstract class DfuBaseService extends IntentService {
|
||||||
|
|
||||||
// read preferences
|
// read preferences
|
||||||
final boolean packetReceiptNotificationEnabled = preferences.getBoolean(DfuSettingsConstants.SETTINGS_PACKET_RECEIPT_NOTIFICATION_ENABLED, true);
|
final boolean packetReceiptNotificationEnabled = preferences.getBoolean(DfuSettingsConstants.SETTINGS_PACKET_RECEIPT_NOTIFICATION_ENABLED, true);
|
||||||
final String value = preferences.getString(DfuSettingsConstants.SETTINGS_NUMBER_OF_PACKETS, String.valueOf(DfuSettingsConstants.SETTINGS_NUMBER_OF_PACKETS_DEFAULT));
|
String value = preferences.getString(DfuSettingsConstants.SETTINGS_NUMBER_OF_PACKETS, String.valueOf(DfuSettingsConstants.SETTINGS_NUMBER_OF_PACKETS_DEFAULT));
|
||||||
int numberOfPackets = DfuSettingsConstants.SETTINGS_NUMBER_OF_PACKETS_DEFAULT;
|
int numberOfPackets = DfuSettingsConstants.SETTINGS_NUMBER_OF_PACKETS_DEFAULT;
|
||||||
try {
|
try {
|
||||||
numberOfPackets = Integer.parseInt(value);
|
numberOfPackets = Integer.parseInt(value);
|
||||||
|
@ -669,6 +669,17 @@ public abstract class DfuBaseService extends IntentService {
|
||||||
if (!packetReceiptNotificationEnabled)
|
if (!packetReceiptNotificationEnabled)
|
||||||
numberOfPackets = 0;
|
numberOfPackets = 0;
|
||||||
mPacketsBeforeNotification = numberOfPackets;
|
mPacketsBeforeNotification = numberOfPackets;
|
||||||
|
// The Soft Device starts where MBR ends (by default from the address 0x1000). Before there is a MBR section, which should not be transmitted over DFU.
|
||||||
|
// Applications and bootloader starts from bigger address. However, in custom DFU implementations, user may want to transmit the whole whole data, even from address 0x0000.
|
||||||
|
value = preferences.getString(DfuSettingsConstants.SETTINGS_MBR_SIZE, String.valueOf(DfuSettingsConstants.SETTINGS_DEFAULT_MBR_SIZE));
|
||||||
|
int mbrSize = DfuSettingsConstants.SETTINGS_DEFAULT_MBR_SIZE;
|
||||||
|
try {
|
||||||
|
mbrSize = Integer.parseInt(value);
|
||||||
|
if (mbrSize < 0)
|
||||||
|
mbrSize = 0;
|
||||||
|
} catch (final NumberFormatException e) {
|
||||||
|
mbrSize = DfuSettingsConstants.SETTINGS_DEFAULT_MBR_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
sendLogBroadcast(Level.VERBOSE, "Starting DFU service");
|
sendLogBroadcast(Level.VERBOSE, "Starting DFU service");
|
||||||
|
|
||||||
|
@ -679,9 +690,9 @@ public abstract class DfuBaseService extends IntentService {
|
||||||
try {
|
try {
|
||||||
sendLogBroadcast(Level.VERBOSE, "Opening file...");
|
sendLogBroadcast(Level.VERBOSE, "Opening file...");
|
||||||
if (fileUri != null)
|
if (fileUri != null)
|
||||||
is = openInputStream(fileUri, mimeType, fileType);
|
is = openInputStream(fileUri, mimeType, mbrSize, fileType);
|
||||||
else
|
else
|
||||||
is = openInputStream(filePath, mimeType, fileType);
|
is = openInputStream(filePath, mimeType, mbrSize, fileType);
|
||||||
|
|
||||||
mInputStream = is;
|
mInputStream = is;
|
||||||
imageSizeInBytes = mImageSizeInBytes = is.available();
|
imageSizeInBytes = mImageSizeInBytes = is.available();
|
||||||
|
@ -1072,7 +1083,7 @@ public abstract class DfuBaseService extends IntentService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets number of data packets that will be send before the notification will be received
|
* Sets number of data packets that will be send before the notification will be received.
|
||||||
*
|
*
|
||||||
* @param data
|
* @param data
|
||||||
* control point data packet
|
* control point data packet
|
||||||
|
@ -1085,35 +1096,43 @@ public abstract class DfuBaseService extends IntentService {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the binary input stream that returns the firmware image content. A Path to the file is given
|
* Opens the binary input stream that returns the firmware image content. A Path to the file is given.
|
||||||
*
|
*
|
||||||
* @param filePath
|
* @param filePath
|
||||||
* the path to the HEX file
|
* the path to the HEX file
|
||||||
* @param mimeType
|
* @param mimeType
|
||||||
* the file type
|
* the file type
|
||||||
|
* @param mbrSize
|
||||||
|
* the size of MBR, by default 0x1000
|
||||||
|
* @param types
|
||||||
|
* the content files types in ZIP
|
||||||
* @return the input stream with binary image content
|
* @return the input stream with binary image content
|
||||||
*/
|
*/
|
||||||
private InputStream openInputStream(final String filePath, final String mimeType, final int types) throws FileNotFoundException, IOException {
|
private InputStream openInputStream(final String filePath, final String mimeType, final int mbrSize, final int types) throws FileNotFoundException, IOException {
|
||||||
final InputStream is = new FileInputStream(filePath);
|
final InputStream is = new FileInputStream(filePath);
|
||||||
if (MIME_TYPE_ZIP.equals(mimeType))
|
if (MIME_TYPE_ZIP.equals(mimeType))
|
||||||
return new ZipHexInputStream(is, types);
|
return new ZipHexInputStream(is, mbrSize, types);
|
||||||
return new HexInputStream(is);
|
return new HexInputStream(is, mbrSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the binary input stream. A Uri to the stream is given
|
* Opens the binary input stream. A Uri to the stream is given.
|
||||||
*
|
*
|
||||||
* @param stream
|
* @param stream
|
||||||
* the Uri to the stream
|
* the Uri to the stream
|
||||||
* @param mimeType
|
* @param mimeType
|
||||||
* the file type
|
* the file type
|
||||||
|
* @param mbrSize
|
||||||
|
* the size of MBR, by default 0x1000
|
||||||
|
* @param types
|
||||||
|
* the content files types in ZIP
|
||||||
* @return the input stream with binary image content
|
* @return the input stream with binary image content
|
||||||
*/
|
*/
|
||||||
private InputStream openInputStream(final Uri stream, final String mimeType, final int types) throws FileNotFoundException, IOException {
|
private InputStream openInputStream(final Uri stream, final String mimeType, final int mbrSize, final int types) throws FileNotFoundException, IOException {
|
||||||
final InputStream is = getContentResolver().openInputStream(stream);
|
final InputStream is = getContentResolver().openInputStream(stream);
|
||||||
if (MIME_TYPE_ZIP.equals(mimeType))
|
if (MIME_TYPE_ZIP.equals(mimeType))
|
||||||
return new ZipHexInputStream(is, types);
|
return new ZipHexInputStream(is, mbrSize, types);
|
||||||
return new HexInputStream(is);
|
return new HexInputStream(is, mbrSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -3,5 +3,7 @@ package no.nordicsemi.android.dfu;
|
||||||
public interface DfuSettingsConstants {
|
public interface DfuSettingsConstants {
|
||||||
public static final String SETTINGS_PACKET_RECEIPT_NOTIFICATION_ENABLED = "settings_packet_receipt_notification_enabled";
|
public static final String SETTINGS_PACKET_RECEIPT_NOTIFICATION_ENABLED = "settings_packet_receipt_notification_enabled";
|
||||||
public static final String SETTINGS_NUMBER_OF_PACKETS = "settings_number_of_packets";
|
public static final String SETTINGS_NUMBER_OF_PACKETS = "settings_number_of_packets";
|
||||||
|
public static final String SETTINGS_MBR_SIZE = "settings_mbr_size";
|
||||||
|
public static final int SETTINGS_DEFAULT_MBR_SIZE = 0x1000;
|
||||||
public static final int SETTINGS_NUMBER_OF_PACKETS_DEFAULT = 10;
|
public static final int SETTINGS_NUMBER_OF_PACKETS_DEFAULT = 10;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,38 +32,44 @@ public class HexInputStream extends FilterInputStream {
|
||||||
private int size;
|
private int size;
|
||||||
private int lastAddress;
|
private int lastAddress;
|
||||||
private int available, bytesRead;
|
private int available, bytesRead;
|
||||||
|
private int MBRsize;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates the HEX Input Stream. The constructor calculates the size of the BIN content which is available through {@link #sizeInBytes()}. If HEX file is invalid then the bin size is 0.
|
* Creates the HEX Input Stream. The constructor calculates the size of the BIN content which is available through {@link #sizeInBytes()}. If HEX file is invalid then the bin size is 0.
|
||||||
*
|
*
|
||||||
* @param in
|
* @param in
|
||||||
* the input stream to read from
|
* the input stream to read from
|
||||||
|
* @param trim
|
||||||
|
* if <code>true</code> the bin data will be trimmed. All data from addresses < 0x1000 will be skipped. In the Soft Device 7.0.0 it's MBR space and this HEX fragment should not be
|
||||||
|
* transmitted. However, other DFU implementations (f.e. without Soft Device) may require uploading the whole file.
|
||||||
* @throws HexFileValidationException
|
* @throws HexFileValidationException
|
||||||
* if HEX file is invalid. F.e. there is no semicolon (':') on the beginning of each line.
|
* if HEX file is invalid. F.e. there is no semicolon (':') on the beginning of each line.
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
* if the stream is closed or another IOException occurs.
|
* if the stream is closed or another IOException occurs.
|
||||||
*/
|
*/
|
||||||
protected HexInputStream(final InputStream in) throws HexFileValidationException, IOException {
|
protected HexInputStream(final InputStream in, final int mbrSize) throws HexFileValidationException, IOException {
|
||||||
super(new BufferedInputStream(in));
|
super(new BufferedInputStream(in));
|
||||||
localBuf = new byte[LINE_LENGTH];
|
this.localBuf = new byte[LINE_LENGTH];
|
||||||
localPos = LINE_LENGTH; // we are at the end of the local buffer, new one must be obtained
|
this.localPos = LINE_LENGTH; // we are at the end of the local buffer, new one must be obtained
|
||||||
size = localBuf.length;
|
this.size = localBuf.length;
|
||||||
lastAddress = 0;
|
this.lastAddress = 0;
|
||||||
|
this.MBRsize = mbrSize;
|
||||||
|
|
||||||
available = calculateBinSize();
|
this.available = calculateBinSize(mbrSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected HexInputStream(final byte[] data) throws HexFileValidationException, IOException {
|
protected HexInputStream(final byte[] data, final int mbrSize) throws HexFileValidationException, IOException {
|
||||||
super(new ByteArrayInputStream(data));
|
super(new ByteArrayInputStream(data));
|
||||||
localBuf = new byte[LINE_LENGTH];
|
this.localBuf = new byte[LINE_LENGTH];
|
||||||
localPos = LINE_LENGTH; // we are at the end of the local buffer, new one must be obtained
|
this.localPos = LINE_LENGTH; // we are at the end of the local buffer, new one must be obtained
|
||||||
size = localBuf.length;
|
this.size = localBuf.length;
|
||||||
lastAddress = 0;
|
this.lastAddress = 0;
|
||||||
|
this.MBRsize = mbrSize;
|
||||||
|
|
||||||
available = calculateBinSize();
|
this.available = calculateBinSize(mbrSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int calculateBinSize() throws IOException {
|
private int calculateBinSize(final int mbrSize) throws IOException {
|
||||||
int binSize = 0;
|
int binSize = 0;
|
||||||
final InputStream in = this.in;
|
final InputStream in = this.in;
|
||||||
in.mark(in.available());
|
in.mark(in.available());
|
||||||
|
@ -96,7 +102,7 @@ public class HexInputStream extends FilterInputStream {
|
||||||
break;
|
break;
|
||||||
case 0x00:
|
case 0x00:
|
||||||
// data type line
|
// data type line
|
||||||
if ((lastULBA << 16) + offset >= 0x1000) // we must skip all data from below address 0x1000 as those are the MBR. The Soft Device starts at 0x1000, the app and bootloader futher more
|
if ((lastULBA << 16) + offset >= mbrSize) // we must skip all data from below last MBR address (default 0x1000) as those are the MBR. The Soft Device starts at the end of MBR (0x1000), the app and bootloader farther more
|
||||||
binSize += lineSize;
|
binSize += lineSize;
|
||||||
// no break!
|
// no break!
|
||||||
case 0x02:
|
case 0x02:
|
||||||
|
@ -233,7 +239,7 @@ public class HexInputStream extends FilterInputStream {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 0x00:
|
case 0x00:
|
||||||
// data type
|
// data type
|
||||||
if ((lastAddress << 16) + offset < 0x1000) {
|
if ((lastAddress << 16) + offset < MBRsize) { // skip MBR
|
||||||
type = -1; // some other than 0
|
type = -1; // some other than 0
|
||||||
pos += in.skip(lineSize * 2 /* 2 hex per one byte */+ 2 /* check sum */);
|
pos += in.skip(lineSize * 2 /* 2 hex per one byte */+ 2 /* check sum */);
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,9 +41,12 @@ public class ZipHexInputStream extends ZipInputStream {
|
||||||
* the Zip Input Stream
|
* the Zip Input Stream
|
||||||
* @param types
|
* @param types
|
||||||
* files to read
|
* files to read
|
||||||
|
* @param trim
|
||||||
|
* if <code>true</code> the bin data will be trimmed. All data from addresses < 0x1000 will be skipped. In the Soft Device 7.0.0 it's MBR space and this HEX fragment should not be
|
||||||
|
* transmitted. However, other DFU implementations (f.e. without Soft Device) may require uploading the whole file.
|
||||||
* @throws IOException
|
* @throws IOException
|
||||||
*/
|
*/
|
||||||
public ZipHexInputStream(final InputStream stream, final int types) throws IOException {
|
public ZipHexInputStream(final InputStream stream, final int mbrSize, final int types) throws IOException {
|
||||||
super(stream);
|
super(stream);
|
||||||
|
|
||||||
this.bytesRead = 0;
|
this.bytesRead = 0;
|
||||||
|
@ -76,7 +79,7 @@ public class ZipHexInputStream extends ZipInputStream {
|
||||||
|
|
||||||
// Create HexInputStream from bytes and copy BIN content to arrays
|
// Create HexInputStream from bytes and copy BIN content to arrays
|
||||||
byte[] source = null;
|
byte[] source = null;
|
||||||
final HexInputStream is = new HexInputStream(bytes);
|
final HexInputStream is = new HexInputStream(bytes, mbrSize);
|
||||||
if (softDevice) {
|
if (softDevice) {
|
||||||
source = softDeviceBytes = new byte[softDeviceSize = is.available()];
|
source = softDeviceBytes = new byte[softDeviceSize = is.available()];
|
||||||
is.read(softDeviceBytes);
|
is.read(softDeviceBytes);
|
||||||
|
|
Loading…
Reference in New Issue