Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Internal Structures Support for targeting specific Image Slot #136

Merged
merged 1 commit into from
Oct 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 13 additions & 8 deletions Example/Example/Util/McuMgrPackage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,23 @@ public struct McuMgrPackage {

// MARK: - API

static func imageName(at index: Int) -> String {
switch index {
case 0: return "App Core"
case 1: return "Net Core"
default: return "Image \(index)"
func imageName(at index: Int) -> String {
let coreName: String
switch images[index].image {
case 0:
coreName = "App Core"
case 1:
coreName = "Net Core"
default:
coreName = "Image \(index)"
}
return "\(coreName) Slot \(images[index].slot)"
}

func sizeString() -> String {
var sizeString = ""
for (i, image) in images.enumerated() {
sizeString += "\(image.data.count) bytes (\(Self.imageName(at: i)))"
sizeString += "\(image.data.count) bytes (\(imageName(at: i)))"
guard i != images.count - 1 else { continue }
sizeString += "\n"
}
Expand All @@ -54,7 +59,7 @@ public struct McuMgrPackage {
for (i, image) in images.enumerated() {
let hash = try McuMgrImage(data: image.data).hash
let hashString = hash.hexEncodedString(options: .upperCase)
result += "0x\(hashString.prefix(6))...\(hashString.suffix(6)) (\(Self.imageName(at: i)))"
result += "0x\(hashString.prefix(6))...\(hashString.suffix(6)) (\(imageName(at: i)))"
guard i != images.count - 1 else { continue }
result += "\n"
}
Expand Down Expand Up @@ -120,7 +125,7 @@ fileprivate extension McuMgrPackage {
throw McuMgrPackage.Error.manifestImageNotFound
}
let imageData = try Data(contentsOf: imageURL)
return (manifestFile.image, imageData)
return ImageManager.Image(manifestFile, data: imageData)
}
try unzippedURLs.forEach { url in
try fileManager.removeItem(at: url)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,10 @@ class FirmwareUploadViewController: UIViewController, McuMgrViewController {
guard let package = package else { return }
uploadImageSize = nil

let images: [ImageManager.Image]
if package.images.count > 1 {
images = package.images.map { ImageManager.Image(image: $0.image, data: $0.data) }
} else {
images = Self.uploadImages.map { ImageManager.Image(image: $0, data: package.images[0].data) }
}

let alertController = UIAlertController(title: "Select Core Slot", message: nil, preferredStyle: .actionSheet)
let alertController = UIAlertController(title: "Select", message: nil, preferredStyle: .actionSheet)
let configuration = uploadConfiguration
for image in images {
alertController.addAction(UIAlertAction(title: McuMgrPackage.imageName(at: image.image), style: .default) { [weak self]
for (i, image) in package.images.enumerated() {
alertController.addAction(UIAlertAction(title: package.imageName(at: i), style: .default) { [weak self]
action in
self?.actionBuffers.isEnabled = false
self?.actionAlignment.isEnabled = false
Expand All @@ -119,10 +112,10 @@ class FirmwareUploadViewController: UIViewController, McuMgrViewController {
self?.actionPause.isHidden = false
self?.actionCancel.isHidden = false
self?.actionSelect.isEnabled = false
self?.imageSlot = image.image
self?.packageImageIndex = i
self?.status.textColor = .primary
self?.status.text = "UPLOADING \(McuMgrPackage.imageName(at: image.image))..."
_ = self?.imageManager.upload(images: [ImageManager.Image(image: image.image, data: image.data)],
self?.status.text = "UPLOADING \(package.imageName(at: i))..."
_ = self?.imageManager.upload(images: [image],
using: configuration, delegate: self)
})
}
Expand All @@ -148,8 +141,8 @@ class FirmwareUploadViewController: UIViewController, McuMgrViewController {

@IBAction func resume(_ sender: UIButton) {
status.textColor = .primary
if let image = self.imageSlot {
status.text = "UPLOADING IMAGE \(McuMgrPackage.imageName(at: image))..."
if let package, let i = packageImageIndex {
status.text = "UPLOADING IMAGE \(package.imageName(at: i))..."
} else {
status.text = "UPLOADING..."
}
Expand All @@ -163,8 +156,8 @@ class FirmwareUploadViewController: UIViewController, McuMgrViewController {
imageManager.cancelUpload()
}

private var imageSlot: Int?
private var package: McuMgrPackage?
private var packageImageIndex: Int?
private var imageManager: ImageManager!
var transporter: McuMgrTransport! {
didSet {
Expand Down
11 changes: 7 additions & 4 deletions Source/Managers/DFU/FirmwareUpgradeManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,14 @@ public class FirmwareUpgradeManager : FirmwareUpgradeController, ConnectionObser
/// - parameter data: `Data` to upload to App Core (Image 0).
/// - parameter configuration: Fine-tuning of details regarding the upgrade process.
public func start(data: Data, using configuration: FirmwareUpgradeConfiguration = FirmwareUpgradeConfiguration()) throws {
try start(images: [(0, data)], using: configuration)
try start(images: [ImageManager.Image(image: 0, data: data)],
using: configuration)
}

/// Start the firmware upgrade.
///
/// This is the full-featured API to start DFU update, including support for Multi-Image uploads.
/// - parameter images: An Array of (Image, `Data`) pairs with the Image Core/Index and its corresponding `Data` to upload.
/// - parameter images: An Array of (`ImageManager.Image`) to upload.
/// - parameter configuration: Fine-tuning of details regarding the upgrade process.
public func start(images: [ImageManager.Image], using configuration: FirmwareUpgradeConfiguration = FirmwareUpgradeConfiguration()) throws {
objc_sync_enter(self)
Expand Down Expand Up @@ -179,7 +180,7 @@ public class FirmwareUpgradeManager : FirmwareUpgradeController, ConnectionObser
if !paused {
let imagesToUpload = images
.filter { !$0.uploaded }
.map { ImageManager.Image($0.image, $0.data) }
.map { ImageManager.Image($0) }
guard !imagesToUpload.isEmpty else {
log(msg: "Nothing to be uploaded", atLevel: .info)
uploadDidFinish()
Expand Down Expand Up @@ -996,11 +997,12 @@ public protocol FirmwareUpgradeDelegate: AnyObject {

// MARK: - FirmwareUpgradeImage

fileprivate struct FirmwareUpgradeImage {
internal struct FirmwareUpgradeImage {

// MARK: Properties

let image: Int
let slot: Int
let data: Data
let hash: Data
var uploaded: Bool
Expand All @@ -1011,6 +1013,7 @@ fileprivate struct FirmwareUpgradeImage {

init(_ image: ImageManager.Image) throws {
self.image = image.image
self.slot = image.slot
self.data = image.data
self.hash = try McuMgrImage(data: image.data).hash
self.uploaded = false
Expand Down
34 changes: 33 additions & 1 deletion Source/Managers/ImageManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,40 @@ import Foundation
import CoreBluetooth
import SwiftCBOR

// MARK: - ImageManager

public class ImageManager: McuManager {
public typealias Image = (image: Int, data: Data)

// MARK: Image

public struct Image {
public let image: Int
public let slot: Int
public let data: Data

/**
So far, only DirectXIP would target `slot` 0 (Primary). So if not specifically
stated, all of the previous code / modes target `slot` 1 (Secondary). Hence,
why that's the default.
*/
public init(image: Int, slot: Int = 1, data: Data) {
self.image = image
self.slot = slot
self.data = data
}

public init(_ manifest: McuMgrManifest.File, data: Data) {
self.image = manifest.image
self.slot = manifest.slot
self.data = data
}

internal init(_ image: FirmwareUpgradeImage) {
self.image = image.image
self.slot = image.slot
self.data = image.data
}
}

override class var TAG: McuMgrLogCategory { .image }

Expand Down