Device Firmware upgrade
Performing DFU
DFU stands for “Device Firmware Update. Occasionally we will release a new CorsanoSDK with new firmware for the bracelet. Is is usually because we have improvements in the firmware.
In the iOS SDK we have implemented a mechanisme which is injected with the firmware version you get from the status of the bracelet. Please see the getting bracelet status section.
Example:
func braceletModelChanged(_ model: BraceletModel) {
self.bracelet = model
self.setBatteryLevel(model)
self.setHwId(model)
self.setBondedState(model.isBonded)
self.setActivityState(model)
self.braceletName = model.deviceName
self.braceletFWVersion = model.fwVersion
self.braceletSerialNumber = model.serialNumber
self.isInitialising = model.isInitialising
self.braceletPlatformId = String(model.hardwareKind?.rawValue ?? 0)
DFUUpdateViewModel.instance.checkFWStatus(fwString: braceletFWVersion, bondingState: isBonded, platformId: braceletPlatformId)
}
As you can see, the last line of this function injects the firmware version into the DFUUpdateViewModel. This will start a DFU if needed.
Implementations in DFUUpdateViewModel
Please implement the DFUUpdateDelegate delegate in your viewmodel. See our example app for a code example.
How to check if DFU is needed
if fwVersionToCheck < SDKManager.instance.getSDK().bluetoothManager.getLatestFWVersion(forPlatform: platformId) {
//needs dfu
SDKManager.instance.getSDK().bluetoothManager.startDFU()
}
We compare the firmware version on the bracelet with the firmware version in the SDK. If the version in the SDK is newer, you will need to perform a DFU.
We would suggest you to use the code in the example app. We also include the status update delegates in the example app for showing the status of the DFU in your custom UI.
Status of running DFU
The status of the running DFU is been send to the app via the delegate DFUUpdateDelegate
func didChange(state: DFUState) {
switch state {
case .connecting:
self.DFUMessage = "Connecting"
case .starting:
self.DFUMessage = "Starting"
case .enablingDfuMode:
self.DFUMessage = "Enabling DFU Bootloader..."
case .uploading:
self.DFUMessage = "Uploading"
case .validating:
self.DFUMessage = "Validating..."
case .disconnecting:
self.DFUMessage = "Disconecting..."
case .completed:
self.DFUMessage = "Upload complete\n\nDevice restarting\nplease wait few seconds..."
default:
break
}
}
func didChangeProgress(part: Int, totalParts: Int, progress: Int, currentSpeedBytesPerSecond: Double, avgSpeedBytesPerSecond: Double) {
self.DFUPercentage = progress
self.DFUMessage = String(format: "Updating. Part %d of %d: %d %%", part,totalParts,progress)
}
func didLogMessage(_ message: String) {}
func dfuError(_ error: DFUError, didOccurWithMessage message: String) {
self.DFUMessage = message
self.DFUError = true
}
DFU Restore
Please implement this code snippet to start a DFU restore. On startup set a timer to check for a userDefaults string after 10 seconds. If it’s present, we need to do a DFU restore.
DFUUpdateViewModel.swift
func initialise() {
SDKManager.instance.getSDK().delegates.dfuUpdateDelegate = self
// DFU restore, see documentation on DFU
DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(10)) {
if let _ = UserDefaults.standard.string(forKey: "DFURecoveryId") {
self.dfuRecoveryMode = true
self.needDFU = true
}
}
}