diff --git a/dfu/src/main/java/no/nordicsemi/android/dfu/BaseDfuImpl.java b/dfu/src/main/java/no/nordicsemi/android/dfu/BaseDfuImpl.java index c423261..fa8c416 100644 --- a/dfu/src/main/java/no/nordicsemi/android/dfu/BaseDfuImpl.java +++ b/dfu/src/main/java/no/nordicsemi/android/dfu/BaseDfuImpl.java @@ -160,7 +160,6 @@ import no.nordicsemi.android.dfu.internal.exception.UploadAbortedException; notifyLock(); } - protected String parse(final BluetoothGattCharacteristic characteristic) { return parse(characteristic.getValue()); } @@ -265,10 +264,16 @@ import no.nordicsemi.android.dfu.internal.exception.UploadAbortedException; mProgressInfo = mService.mProgressInfo.init(size, currentPart, totalParts); // If we are bonded we may want to enable Service Changed characteristic indications. - // Note: This feature will be introduced in the SDK 8.0 as this is the proper way to refresh attribute list on the phone. + // Note: Sending SC indication on services change was introduced in the SDK 8.0. + // Before, the cache had to be clear manually. This Android lib supports both implementations. + // Note: On iOS refreshing services is not available in the API. An app must have Service Change characteristic + // if it intends ever to change its services. In that case on non-bonded devices services will never be cached, + // and on bonded a change is indicated using Service Changed indication. Ergo - Legacy DFU will + // not work by default on iOS with buttonless update on SDKs < 8 on bonded devices. The bootloader must be modified to + // always send the indication when connected. - // This has been fixed on Android 6 (?). Now the Android enables Service Changed indications automatically during bonding. - if (gatt.getDevice().getBondState() == BluetoothDevice.BOND_BONDED) { + // This has been fixed on Android 6. Now the Android enables Service Changed indications automatically after bonding. + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M && gatt.getDevice().getBondState() == BluetoothDevice.BOND_BONDED) { final BluetoothGattService genericAttributeService = gatt.getService(GENERIC_ATTRIBUTE_SERVICE_UUID); if (genericAttributeService != null) { final BluetoothGattCharacteristic serviceChangedCharacteristic = genericAttributeService.getCharacteristic(SERVICE_CHANGED_UUID); diff --git a/dfu/src/main/java/no/nordicsemi/android/dfu/LegacyDfuImpl.java b/dfu/src/main/java/no/nordicsemi/android/dfu/LegacyDfuImpl.java index ca2109b..ee18861 100644 --- a/dfu/src/main/java/no/nordicsemi/android/dfu/LegacyDfuImpl.java +++ b/dfu/src/main/java/no/nordicsemi/android/dfu/LegacyDfuImpl.java @@ -22,9 +22,7 @@ package no.nordicsemi.android.dfu; -import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothGatt; -import android.bluetooth.BluetoothGattCallback; import android.bluetooth.BluetoothGattCharacteristic; import android.bluetooth.BluetoothGattService; import android.content.Intent; @@ -32,7 +30,6 @@ import android.content.SharedPreferences; import android.os.SystemClock; import android.preference.PreferenceManager; -import java.io.IOException; import java.util.UUID; import no.nordicsemi.android.dfu.internal.ArchiveInputStream; @@ -41,8 +38,6 @@ import no.nordicsemi.android.dfu.internal.exception.DfuException; import no.nordicsemi.android.dfu.internal.exception.RemoteDfuException; import no.nordicsemi.android.dfu.internal.exception.UnknownResponseException; import no.nordicsemi.android.dfu.internal.exception.UploadAbortedException; -import no.nordicsemi.android.dfu.internal.scanner.BootloaderScannerFactory; -import no.nordicsemi.android.error.GattError; import no.nordicsemi.android.error.LegacyDfuError; /* package */ class LegacyDfuImpl extends BaseCustomDfuImpl { @@ -395,16 +390,16 @@ import no.nordicsemi.android.error.LegacyDfuError; // A notification will come with confirmation. Let's wait for it a bit response = readNotificationResponse(); - /* - * The response received from the DFU device contains: - * +---------+--------+----------------------------------------------------+ - * | byte no | value | description | - * +---------+--------+----------------------------------------------------+ - * | 0 | 16 | Response code | - * | 1 | 1 | The Op Code of a request that this response is for | - * | 2 | STATUS | See DFU_STATUS_* for status codes | - * +---------+--------+----------------------------------------------------+ - */ + /* + * The response received from the DFU device contains: + * +---------+--------+----------------------------------------------------+ + * | byte no | value | description | + * +---------+--------+----------------------------------------------------+ + * | 0 | 16 | Response code | + * | 1 | 1 | The Op Code of a request that this response is for | + * | 2 | STATUS | Status code | + * +---------+--------+----------------------------------------------------+ + */ status = getStatusCode(response, OP_CODE_START_DFU_KEY); mService.sendLogBroadcast(DfuBaseService.LOG_LEVEL_APPLICATION, "Response received (Op Code = " + response[1] + " Status = " + status + ")"); // If upload was not completed in the previous connection the INVALID_STATE status will be reported. diff --git a/dfu/src/main/java/no/nordicsemi/android/dfu/SecureDfuImpl.java b/dfu/src/main/java/no/nordicsemi/android/dfu/SecureDfuImpl.java index 79a213b..43f49e6 100644 --- a/dfu/src/main/java/no/nordicsemi/android/dfu/SecureDfuImpl.java +++ b/dfu/src/main/java/no/nordicsemi/android/dfu/SecureDfuImpl.java @@ -131,6 +131,14 @@ import no.nordicsemi.android.error.SecureDfuError; return dfuService != null; } + @Override + public boolean hasRequiredCharacteristics(final BluetoothGatt gatt) { + final BluetoothGattService dfuService = gatt.getService(DFU_SERVICE_UUID); + mControlPointCharacteristic = dfuService.getCharacteristic(DFU_CONTROL_POINT_UUID); + mPacketCharacteristic = dfuService.getCharacteristic(DFU_PACKET_UUID); + return mControlPointCharacteristic != null && mPacketCharacteristic != null; + } + @Override public boolean initialize(final Intent intent, final BluetoothGatt gatt, final int fileType, final InputStream firmwareStream, final InputStream initPacketStream) throws DfuException, DeviceDisconnectedException, UploadAbortedException { if (initPacketStream == null) { @@ -142,14 +150,6 @@ import no.nordicsemi.android.error.SecureDfuError; return super.initialize(intent, gatt, fileType, firmwareStream, initPacketStream); } - @Override - public boolean hasRequiredCharacteristics(final BluetoothGatt gatt) { - final BluetoothGattService dfuService = gatt.getService(DFU_SERVICE_UUID); - mControlPointCharacteristic = dfuService.getCharacteristic(DFU_CONTROL_POINT_UUID); - mPacketCharacteristic = dfuService.getCharacteristic(DFU_PACKET_UUID); - return mControlPointCharacteristic != null && mPacketCharacteristic != null; - } - @Override protected BaseBluetoothGattCallback getGattCallback() { return mBluetoothCallback;