From 22e8ee5f25fcf549b4de83dab78717f9b1019d3e Mon Sep 17 00:00:00 2001 From: Dinesh Harjani Date: Mon, 30 Oct 2023 23:09:19 +0000 Subject: [PATCH] Fix: Ignore FirmwareUpgradeManagerConfiguration's 'estimatedSwapTime' for DirectXIP Bootloader As we explained in updated comments, as well as one can do that when coding and waiting for a Scary Fast Apple Event, under DirectXIP Bootloader Mode there's no swap time at all. So we can just ignore any reset time. --- .../Managers/DFU/FirmwareUpgradeManager.swift | 31 +++++++++++++------ Source/McuMgrResponse.swift | 9 ++++++ 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/Source/Managers/DFU/FirmwareUpgradeManager.swift b/Source/Managers/DFU/FirmwareUpgradeManager.swift index 1af9cd1..5655969 100644 --- a/Source/Managers/DFU/FirmwareUpgradeManager.swift +++ b/Source/Managers/DFU/FirmwareUpgradeManager.swift @@ -822,8 +822,8 @@ public class FirmwareUpgradeManager : FirmwareUpgradeController, ConnectionObser guard state == .disconnected else { return } - self.log(msg: "Device has disconnected", atLevel: .info) - self.log(msg: "Reconnecting...", atLevel: .verbose) + + self.log(msg: "Device Has Disconnected", atLevel: .verbose) let timeSinceReset: TimeInterval if let resetResponseTime = resetResponseTime { let now = Date() @@ -833,12 +833,20 @@ public class FirmwareUpgradeManager : FirmwareUpgradeController, ConnectionObser timeSinceReset = 0 } let remainingTime = configuration.estimatedSwapTime - timeSinceReset - if remainingTime > 0 { - DispatchQueue.main.asyncAfter(deadline: .now() + remainingTime) { [weak self] in - self?.reconnect() - } - } else { + + // If DirectXIP, regardless of variant, there's no swap time. So we try to reconnect + // immediately. + let waitForReconnectRequired = !configuration.bootloaderMode.isDirectXIP + && remainingTime > .leastNonzeroMagnitude + guard waitForReconnectRequired else { reconnect() + return + } + + self.log(msg: "Waiting \(Int(configuration.estimatedSwapTime)) (Swap Time) Seconds Before Attempting to Reconnect...", atLevel: .info) + DispatchQueue.main.asyncAfter(deadline: .now() + remainingTime) { [weak self] in + self?.log(msg: "Reconnecting...", atLevel: .info) + self?.reconnect() } } @@ -898,8 +906,13 @@ private extension FirmwareUpgradeManager { public struct FirmwareUpgradeConfiguration: Codable { - /// Estimated time required for swapping images, in seconds. - /// If the mode is set to `.testAndConfirm`, the manager will try to reconnect after this time. 0 by default. + /** + Estimated time required for swapping images, in seconds. + + If the mode is set to `.testAndConfirm`, the manager will try to reconnect after this time. 0 by default. + + Note: This setting is ignored if `bootloaderMode` is in any DirectXIP variant, since there's no swap whatsoever when DirectXIP is involved. Hence, why we can upload the same Image (though different hash) to either slot. + */ public var estimatedSwapTime: TimeInterval /// If enabled, after successful upload but before test/confirm/reset phase, an Erase App Settings Command will be sent and awaited before proceeding. public var eraseAppSettings: Bool diff --git a/Source/McuMgrResponse.swift b/Source/McuMgrResponse.swift index 8f4988d..d407004 100644 --- a/Source/McuMgrResponse.swift +++ b/Source/McuMgrResponse.swift @@ -407,6 +407,15 @@ public final class BootloaderInfoResponse: McuMgrResponse { case directXIPWithRevert = 5 case RAMLoader = 6 + /** + Intended for use cases where it's not important to know what kind of DirectXIP + variant this Bootloader Mode might represent, but instead, whether it's + DirectXIP or not. + */ + public var isDirectXIP: Bool { + return self == .directXIPNoRevert || self == .directXIPWithRevert + } + public var debugDescription: String { switch self { case .unknown: