Javadoc updated.

This commit is contained in:
Aleksander Nowakowski 2015-03-16 13:39:26 +01:00
parent 2228442030
commit b4b5e75870
8 changed files with 97 additions and 17 deletions

View File

@ -38,6 +38,12 @@ import no.nordicsemi.android.dfu.manifest.Manifest;
import no.nordicsemi.android.dfu.manifest.ManifestFile;
import no.nordicsemi.android.dfu.manifest.SoftDeviceBootloaderFileInfo;
/**
* <p>Reads the firmware files from the a ZIP file. The ZIP file must be either created using the <b>nrf utility</b> tool, available together with Master Control Panel v3.8.0+,
* or follow the backward compatibility syntax: must contain only files with names: application.hex/bin, softdevice.hex/dat or bootloader.hex/bin, optionally also application.dat
* and/or system.dat with init packets.</p>
* <p>The ArchiveInputStream will read only files with types specified by <b>types</b> parameter of the constructor.</p>
*/
public class ArchiveInputStream extends ZipInputStream {
/** The name of the manifest file is fixed. */
private static final String MANIFEST = "manifest.json";
@ -379,8 +385,6 @@ public class ArchiveInputStream extends ZipInputStream {
return t;
}
/**
* Sets the currentSource to the new file or to <code>null</code> if the last file has been transmitted.
*
@ -400,26 +404,51 @@ public class ArchiveInputStream extends ZipInputStream {
}
@Override
/**
* Returns the number of bytes that has not been read yet. This value includes only firmwares matching the content type set by the construcotor or the {@link #setContentType(int)} method.
*/
public int available() {
return softDeviceSize + bootloaderSize + applicationSize - bytesRead;
}
/**
* Returns the total size of the SoftDevice firmware. In case the firmware was given as a HEX, this method returns the size of the BIN content of the file.
* @return the size of the SoftDevice firmware (BIN part)
*/
public int softDeviceImageSize() {
return softDeviceSize;
}
/**
* Returns the total size of the Bootloader firmware. In case the firmware was given as a HEX, this method returns the size of the BIN content of the file.
* @return the size of the Bootloader firmware (BIN part)
*/
public int bootloaderImageSize() {
return bootloaderSize;
}
/**
* Returns the total size of the Application firmware. In case the firmware was given as a HEX, this method returns the size of the BIN content of the file.
* @return the size of the Application firmware (BIN part)
*/
public int applicationImageSize() {
return applicationSize;
}
/**
* Returns the content of the init file for SoftDevice and/or Bootloader. When both SoftDevice and Bootloader are present in the ZIP file (as two files using the compatibility mode
* or as one file using the new Distribution packet) the system init contains validation data for those two files combined (e.g. the CRC value). This method may return
* <code>null</code> if there is no SoftDevice nor Bootloader in the ZIP or the DAT file is not present there.
* @return the content of the init packet for SoftDevice and/or Bootloader
*/
public byte[] getSystemInit() {
return systemInitBytes;
}
/**
* Returns the content of the init file for the Application or <code>null</code> if no application file in the ZIP, or the DAT file is not provided.
* @return the content of the init packet for Application
*/
public byte[] getApplicationInit() {
return applicationInitBytes;
}

View File

@ -351,6 +351,16 @@ public abstract class DfuBaseService extends IntentService {
* </ul>
*/
public static final String BROADCAST_ERROR = "no.nordicsemi.android.dfu.broadcast.BROADCAST_ERROR";
/**
* The type of the error. This extra contains information about that kind of error has occurred. Connection state errors and other errors may share the same numbers.
* For example, the {@link BluetoothGattCallback#onCharacteristicWrite(BluetoothGatt, BluetoothGattCharacteristic, int)} method may return a status code 8 (GATT INSUF AUTHORIZATION),
* while the status code 8 returned by {@link BluetoothGattCallback#onConnectionStateChange(BluetoothGatt, int, int)} is a GATT CONN TIMEOUT error.
*/
public static final String EXTRA_ERROR_TYPE = "no.nordicsemi.android.dfu.extra.EXTRA_ERROR_TYPE";
public static final int ERROR_TYPE_OTHER = 0;
public static final int ERROR_TYPE_COMMUNICATION_STATE = 1;
public static final int ERROR_TYPE_COMMUNICATION = 2;
public static final int ERROR_TYPE_DFU_REMOTE = 3;
/**
* If this bit is set than the progress value indicates an error. Use {@link GattError#parse(int)} to obtain error name.
*/
@ -401,6 +411,11 @@ public abstract class DfuBaseService extends IntentService {
* The flag set when one of {@link android.bluetooth.BluetoothGattCallback} methods was called with status other than {@link android.bluetooth.BluetoothGatt#GATT_SUCCESS}.
*/
public static final int ERROR_CONNECTION_MASK = 0x4000;
/**
* The flag set when the {@link android.bluetooth.BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)} method was called with
* status other than {@link android.bluetooth.BluetoothGatt#GATT_SUCCESS}.
*/
public static final int ERROR_CONNECTION_STATE_MASK = 0x8000;
/**
* The log events are only broadcast when there is no nRF Logger installed. The broadcast contains 2 extras:
* <ul>
@ -743,7 +758,7 @@ public abstract class DfuBaseService extends IntentService {
} else {
loge("Connection state change error: " + status + " newState: " + newState);
mPaused = false;
mError = ERROR_CONNECTION_MASK | status;
mError = ERROR_CONNECTION_STATE_MASK | status;
}
// Notify waiting thread
@ -1191,9 +1206,9 @@ public abstract class DfuBaseService extends IntentService {
return;
}
if (mError > 0) { // error occurred
final int error = mError & ~ERROR_CONNECTION_MASK;
final int error = mError & ~ERROR_CONNECTION_STATE_MASK;
loge("An error occurred while connecting to the device:" + error);
sendLogBroadcast(LOG_LEVEL_ERROR, String.format("Connection failed (0x%02X): %s", error, GattError.parse(error)));
sendLogBroadcast(LOG_LEVEL_ERROR, String.format("Connection failed (0x%02X): %s", error, GattError.parseConnectionError(error)));
terminateConnection(gatt, mError);
return;
}
@ -1649,11 +1664,8 @@ public abstract class DfuBaseService extends IntentService {
if (status != DFU_STATUS_SUCCESS)
throw new RemoteDfuException("Device returned validation error", status);
// Disable notifications locally
updateProgressNotification(PROGRESS_DISCONNECTING);
gatt.setCharacteristicNotification(controlPointCharacteristic, false);
// Send Activate and Reset signal.
updateProgressNotification(PROGRESS_DISCONNECTING);
logi("Sending Activate and Reset request (Op Code = 5)");
writeOpCode(gatt, controlPointCharacteristic, OP_CODE_ACTIVATE_AND_RESET);
sendLogBroadcast(LOG_LEVEL_APPLICATION, "Activate and Reset request sent");
@ -1763,13 +1775,18 @@ public abstract class DfuBaseService extends IntentService {
sendLogBroadcast(LOG_LEVEL_ERROR, "Device has disconnected");
// TODO reconnect n times?
loge(e.getMessage());
if (mNotificationsEnabled)
gatt.setCharacteristicNotification(controlPointCharacteristic, false);
close(gatt);
updateProgressNotification(ERROR_DEVICE_DISCONNECTED);
} catch (final DfuException e) {
final int error = e.getErrorNumber() & ~ERROR_CONNECTION_MASK;
sendLogBroadcast(LOG_LEVEL_ERROR, String.format("Error (0x%02X): %s", error, GattError.parse(error)));
int error = e.getErrorNumber();
// Connection state errors and other Bluetooth GATT callbacks share the same error numbers. Therefore we are using bit masks to identify the type.
if ((error & ERROR_CONNECTION_STATE_MASK) > 0) {
error &= ~ERROR_CONNECTION_STATE_MASK;
sendLogBroadcast(LOG_LEVEL_ERROR, String.format("Error (0x%02X): %s", error, GattError.parseConnectionError(error)));
} else {
error &= ~ERROR_CONNECTION_MASK;
sendLogBroadcast(LOG_LEVEL_ERROR, String.format("Error (0x%02X): %s", error, GattError.parse(error)));
}
loge(e.getMessage());
if (mConnectionState == STATE_CONNECTED_AND_READY)
try {
@ -1779,7 +1796,7 @@ public abstract class DfuBaseService extends IntentService {
} catch (final Exception e1) {
// do nothing
}
terminateConnection(gatt, e.getErrorNumber());
terminateConnection(gatt, e.getErrorNumber() /* we return the whole error number, including the error type mask */);
}
} finally {
try {
@ -1899,7 +1916,7 @@ public abstract class DfuBaseService extends IntentService {
}
// Close the device
refreshDeviceCache(gatt, false); // This should be true when DFU Version is 0.5
refreshDeviceCache(gatt, false); // This should be set to true when DFU Version is 0.5 or lower
close(gatt);
updateProgressNotification(error);
}
@ -2670,7 +2687,19 @@ public abstract class DfuBaseService extends IntentService {
private void sendErrorBroadcast(final int error) {
final Intent broadcast = new Intent(BROADCAST_ERROR);
broadcast.putExtra(EXTRA_DATA, error & ~ERROR_CONNECTION_MASK);
if ((error & ERROR_CONNECTION_MASK) > 0) {
broadcast.putExtra(EXTRA_DATA, error & ~ERROR_CONNECTION_MASK);
broadcast.putExtra(EXTRA_ERROR_TYPE, ERROR_TYPE_COMMUNICATION);
} else if ((error & ERROR_CONNECTION_STATE_MASK) > 0) {
broadcast.putExtra(EXTRA_DATA, error & ~ERROR_CONNECTION_STATE_MASK);
broadcast.putExtra(EXTRA_ERROR_TYPE, ERROR_TYPE_COMMUNICATION_STATE);
} else if ((error & ERROR_REMOTE_MASK) > 0) {
broadcast.putExtra(EXTRA_DATA, error);
broadcast.putExtra(EXTRA_ERROR_TYPE, ERROR_TYPE_DFU_REMOTE);
} else {
broadcast.putExtra(EXTRA_DATA, error);
broadcast.putExtra(EXTRA_ERROR_TYPE, ERROR_TYPE_OTHER);
}
broadcast.putExtra(EXTRA_DEVICE_ADDRESS, mDeviceAddress);
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
}

View File

@ -31,7 +31,7 @@ import java.io.InputStream;
import no.nordicsemi.android.dfu.exception.HexFileValidationException;
/**
* Reads the binary content from the HEX file using IntelHex standard: http://www.interlog.com/~speff/usefulinfo/Hexfrmt.pdf
* Reads the binary content from the HEX file using IntelHex standard: http://www.interlog.com/~speff/usefulinfo/Hexfrmt.pdf.
* Truncates the HEX file from all meta data and returns only the BIN content.
* <p>
* In nRF51 chips memory a SoftDevice starts at address 0x1000. From 0x0000 to 0x1000 there is MBR sector (since SoftDevice 7.0.0) which should not be transmitted using DFU. Therefore this class skips

View File

@ -22,6 +22,9 @@
package no.nordicsemi.android.dfu.exception;
/**
* Device has disconnected.
*/
public class DeviceDisconnectedException extends Exception {
private static final long serialVersionUID = -6901728550661937942L;

View File

@ -24,6 +24,9 @@ package no.nordicsemi.android.dfu.exception;
import no.nordicsemi.android.dfu.DfuBaseService;
/**
* A DFU error occurred on the remote DFU target.
*/
public class DfuException extends Exception {
private static final long serialVersionUID = -6901728550661937942L;

View File

@ -24,6 +24,9 @@ package no.nordicsemi.android.dfu.exception;
import java.io.IOException;
/**
* The HEX file could not be parsed.
*/
public class HexFileValidationException extends IOException {
private static final long serialVersionUID = -6467104024030837875L;

View File

@ -22,6 +22,9 @@
package no.nordicsemi.android.dfu.exception;
/**
* A DFU error occurred on the remote DFU target.
*/
public class RemoteDfuException extends Exception {
private static final long serialVersionUID = -6901728550661937942L;

View File

@ -33,6 +33,11 @@ import no.nordicsemi.android.dfu.DfuBaseService;
public class GattError {
// Starts at line 106 of gatt_api.h file
/**
* Converts the connection status given by the {@link android.bluetooth.BluetoothGattCallback#onConnectionStateChange(android.bluetooth.BluetoothGatt, int, int)} to error name.
* @param error the status number
* @return the error name as stated in the gatt_api.h file
*/
public static String parseConnectionError(final int error) {
switch (error) {
case BluetoothGatt.GATT_SUCCESS:
@ -59,6 +64,11 @@ public class GattError {
}
// Starts at line 29 of the gatt_api.h file
/**
* Converts the bluetooth communication status given by other BluetoothGattCallbacks to error name. It also parses the DFU errors.
* @param error the status number
* @return the error name as stated in the gatt_api.h file
*/
public static String parse(final int error) {
switch (error) {
case 0x0001: