Splitting implementation into 2 methods
This commit is contained in:
parent
258a6ade64
commit
8b8932fd57
|
@ -207,17 +207,75 @@ import no.nordicsemi.android.error.SecureDfuError;
|
|||
// End
|
||||
|
||||
try {
|
||||
sendInitPacket(gatt);
|
||||
sendFirmware(gatt);
|
||||
|
||||
// The device will reset so we don't have to send Disconnect signal.
|
||||
mProgressInfo.setProgress(DfuBaseService.PROGRESS_DISCONNECTING);
|
||||
mService.waitUntilDisconnected();
|
||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_INFO, "Disconnected by the remote device");
|
||||
|
||||
// We are ready with DFU, the device is disconnected, let's close it and finalize the operation.
|
||||
finalize(intent, false);
|
||||
} catch (final UnknownResponseException e) {
|
||||
final int error = DfuBaseService.ERROR_INVALID_RESPONSE;
|
||||
loge(e.getMessage());
|
||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_ERROR, e.getMessage());
|
||||
mService.terminateConnection(gatt, error);
|
||||
} catch (final RemoteDfuException e) {
|
||||
final int error = DfuBaseService.ERROR_REMOTE_MASK | e.getErrorNumber();
|
||||
loge(e.getMessage());
|
||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_ERROR, String.format("Remote DFU error: %s", SecureDfuError.parse(error)));
|
||||
|
||||
try {
|
||||
final ErrorMessage details = readLastError();
|
||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_ERROR, "Details: " + details.message + " (Code = " + details.code + ")");
|
||||
logi("Error details: " + details.message + " (Code = " + details.code + ")");
|
||||
} catch (final Exception e1) {
|
||||
loge("Reading error details failed", e1);
|
||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_WARNING, "Reading error details failed");
|
||||
}
|
||||
mService.terminateConnection(gatt, error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method does the following:
|
||||
* <ol>
|
||||
* <li>Reads Command Object Info - this returns the maximum acceptable size of a command object, and the offset and CRC32 of the command
|
||||
* that is already stored in the device (in case the DFU was started in a previous connection and disconnected before it has finished).</li>
|
||||
* <li>If the offset received is greater than 0 and less or equal to the size of the Init file that is to be sent, it will compare the
|
||||
* received CRC with the local one and, if they match:
|
||||
* <ul>
|
||||
* <li>If offset < init file size - it will continue sending the Init file from the point it stopped before,</li>
|
||||
* <li>If offset == init file size - it will send the Calculate Checksum request to obtain a CRC of a current object.
|
||||
* <ul>
|
||||
* <li>If the received CRC is the same as above ones, it will send Execute command to execute the Init file, as it may have not been executed before.</li>
|
||||
* <li>If the received CRC is different, that means that the Data Object has already been created in the previous connection and this method will return.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li>If the CRCs don't match, or the received offset is > init file size, it create the Command Object and send the whole 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
|
||||
* @throws RemoteDfuException
|
||||
* @throws DeviceDisconnectedException
|
||||
* @throws DfuException
|
||||
* @throws UploadAbortedException
|
||||
* @throws UnknownResponseException
|
||||
*/
|
||||
private void sendInitPacket(final BluetoothGatt gatt) throws RemoteDfuException, DeviceDisconnectedException, DfuException, UploadAbortedException, UnknownResponseException {
|
||||
final CRC32 crc32 = new CRC32(); // Used to calculate CRC32 of the Init packet
|
||||
ObjectChecksum checksum;
|
||||
ObjectInfo info;
|
||||
byte[] response;
|
||||
int status;
|
||||
|
||||
// First, read the Command Object Info. This give information about the maximum command size and whether there is already
|
||||
// one saved from a previous connection. It offset and CRC returned are not equal zero, we can compare it with the current init file
|
||||
// and skip sending it for the second time.
|
||||
logi("Sending Read Command Object Info command (Op Code = 6, Type = 1)");
|
||||
info = readObjectInfo(OBJECT_COMMAND);
|
||||
final ObjectInfo info = readObjectInfo(OBJECT_COMMAND);
|
||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, String.format(Locale.US, "Command object info received (Max size = %d, Offset = %d, CRC = %08X)", info.maxSize, info.offset, info.CRC32));
|
||||
if (mInitPacketSizeInBytes > info.maxSize) {
|
||||
// Ignore this. DFU target will send an error if init packet is too large after sending the 'Create object' command
|
||||
|
@ -227,7 +285,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) {
|
||||
if (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];
|
||||
|
@ -251,7 +309,7 @@ import no.nordicsemi.android.error.SecureDfuError;
|
|||
}
|
||||
} else {
|
||||
// A different Init packet was sent before, or the error occurred while sending.
|
||||
// We have to send the while Init packet again.
|
||||
// We have to send the whole Init packet again.
|
||||
mInitPacketStream.reset();
|
||||
crc32.reset();
|
||||
}
|
||||
|
@ -352,7 +410,18 @@ import no.nordicsemi.android.error.SecureDfuError;
|
|||
// It looks like we have started sending the Data already, let's continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This method enables
|
||||
* @param gatt the target GATT device
|
||||
* @throws RemoteDfuException
|
||||
* @throws DeviceDisconnectedException
|
||||
* @throws DfuException
|
||||
* @throws UploadAbortedException
|
||||
* @throws UnknownResponseException
|
||||
*/
|
||||
private void sendFirmware(final BluetoothGatt gatt) throws RemoteDfuException, DeviceDisconnectedException, DfuException, UploadAbortedException, UnknownResponseException {
|
||||
// Send the number of packets of firmware before receiving a receipt notification
|
||||
final int numberOfPacketsBeforeNotification = mPacketsBeforeNotification;
|
||||
if (numberOfPacketsBeforeNotification > 0) {
|
||||
|
@ -366,7 +435,7 @@ import no.nordicsemi.android.error.SecureDfuError;
|
|||
|
||||
logi("Sending Read Data Object Info command (Op Code = 6, Type = 2)");
|
||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, "Reading data object info...");
|
||||
info = readObjectInfo(OBJECT_DATA);
|
||||
final ObjectInfo info = readObjectInfo(OBJECT_DATA);
|
||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, String.format(Locale.US, "Data object info received (Max size = %d, Offset = %d, CRC = %08X)", info.maxSize, info.offset, info.CRC32));
|
||||
mProgressInfo.setMaxObjectSizeInBytes(info.maxSize);
|
||||
|
||||
|
@ -442,7 +511,7 @@ import no.nordicsemi.android.error.SecureDfuError;
|
|||
|
||||
// Calculate Checksum
|
||||
logi("Sending Calculate Checksum command (Op Code = 3)");
|
||||
checksum = readChecksum();
|
||||
final ObjectChecksum checksum = readChecksum();
|
||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, String.format(Locale.US, "Checksum received (Offset = %d, CRC = %08X)", checksum.offset, checksum.CRC32));
|
||||
logi(String.format(Locale.US, "Checksum received (Offset = %d, CRC = %08X)", checksum.offset, checksum.CRC32));
|
||||
|
||||
|
@ -481,34 +550,6 @@ import no.nordicsemi.android.error.SecureDfuError;
|
|||
final long endTime = SystemClock.elapsedRealtime();
|
||||
logi("Transfer of " + mProgressInfo.getBytesSent() + " bytes has taken " + (endTime - startTime) + " ms");
|
||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, "Upload completed in " + (endTime - startTime) + " ms");
|
||||
|
||||
// The device will reset so we don't have to send Disconnect signal.
|
||||
mProgressInfo.setProgress(DfuBaseService.PROGRESS_DISCONNECTING);
|
||||
mService.waitUntilDisconnected();
|
||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_INFO, "Disconnected by the remote device");
|
||||
|
||||
// We are ready with DFU, the device is disconnected, let's close it and finalize the operation.
|
||||
finalize(intent, false);
|
||||
} catch (final UnknownResponseException e) {
|
||||
final int error = DfuBaseService.ERROR_INVALID_RESPONSE;
|
||||
loge(e.getMessage());
|
||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_ERROR, e.getMessage());
|
||||
mService.terminateConnection(gatt, error);
|
||||
} catch (final RemoteDfuException e) {
|
||||
final int error = DfuBaseService.ERROR_REMOTE_MASK | e.getErrorNumber();
|
||||
loge(e.getMessage());
|
||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_ERROR, String.format("Remote DFU error: %s", SecureDfuError.parse(error)));
|
||||
|
||||
try {
|
||||
final ErrorMessage details = readLastError();
|
||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_ERROR, "Details: " + details.message + " (Code = " + details.code + ")");
|
||||
logi("Error details: " + details.message + " (Code = " + details.code + ")");
|
||||
} catch (final Exception e1) {
|
||||
loge("Reading error details failed", e1);
|
||||
mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_WARNING, "Reading error details failed");
|
||||
}
|
||||
mService.terminateConnection(gatt, error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue