Skip to content

Commit 63e0cba

Browse files
committed
Added support for Abort command in Secure DFU (SDK 15+)
1 parent 0645f93 commit 63e0cba

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

iOSDFULibrary/Classes/Implementation/SecureDFU/Peripheral/SecureDFUPeripheral.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,4 +329,12 @@ internal class SecureDFUPeripheral : BaseCommonDFUPeripheral<SecureDFUExecutor,
329329
}
330330
)
331331
}
332+
333+
override func resetDevice() {
334+
guard let dfuService = dfuService, dfuService.supportsReset() else {
335+
super.resetDevice()
336+
return
337+
}
338+
dfuService.sendReset(onError: defaultErrorCallback)
339+
}
332340
}

iOSDFULibrary/Classes/Implementation/SecureDFU/Services/SecureDFUService.swift

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,17 @@ import CoreBluetooth
4747
private let service : CBService
4848
private var dfuPacketCharacteristic : SecureDFUPacket?
4949
private var dfuControlPointCharacteristic : SecureDFUControlPoint?
50+
51+
/// This method returns true if DFU Control Point characteristc has been discovered.
52+
/// A device without this characteristic is not supported and even can't be resetted
53+
/// by sending a Reset command.
54+
internal func supportsReset() -> Bool {
55+
// The Abort (0x0C) command has been added to DFU bootloader in SDK 15.
56+
// https://infocenter.nordicsemi.com/topic/com.nordic.infocenter.sdk5.v15.0.0/lib_dfu_transport.html?cp=8_5_3_3_5_2
57+
// For earlier SDKs there is no way to reset the bootloader other than
58+
// disconnecting and waiting for it to time out after few minutes.
59+
return dfuControlPointCharacteristic != nil
60+
}
5061

5162
private var paused = false
5263
private var aborted = false
@@ -55,7 +66,7 @@ import CoreBluetooth
5566
private var success : Callback?
5667
/// A temporary callback used to report an operation error.
5768
private var report : ErrorCallback?
58-
/// A temporaty callback used to report progress status.
69+
/// A temporary callback used to report progress status.
5970
private var progressDelegate : DFUProgressDelegate?
6071
private var progressQueue : DispatchQueue?
6172

@@ -323,10 +334,19 @@ import CoreBluetooth
323334

324335
- parameter report: A callback called when writing characteristic failed.
325336
*/
326-
private func sendReset(onError report: @escaping ErrorCallback) {
337+
func sendReset(onError report: @escaping ErrorCallback) {
327338
aborted = true
328-
// There is no command to reset a Secure DFU device. We can just disconnect.
329-
targetPeripheral?.disconnect()
339+
// Upon sending the Abort request the device will immediately reboot in application
340+
// mode. There will be no notification with status success returned.
341+
dfuControlPointCharacteristic?.send(.abort,
342+
onSuccess: nil, // Device will disconnected immediately.
343+
onError: { [weak self] _, _ in
344+
// Seems like the Abort request is not supported (indicating SDK 12-14).
345+
// We can just disconnect. The bootloader should reset to app mode after
346+
// a timeout.
347+
self?.targetPeripheral?.disconnect()
348+
}
349+
)
330350
}
331351

332352
//MARK: - Packet commands

0 commit comments

Comments
 (0)