From 886d11a6e202d37522f9e4c0bf933e7aa059a7dc Mon Sep 17 00:00:00 2001 From: Dinesh Harjani Date: Thu, 27 Jun 2024 12:19:05 +0100 Subject: [PATCH] McuMgrPackage now parses a SUIT Manifest .ZIP So, for SUIT Zip Packages, we do not care about the other files. We only look for the SUIT Envelope in the Manifest, and that file has a hash, or a digest we can sink our teeth onto, and then we can proceed with SUIT. But again, this is just one small step. --- Example/Example/Util/McuMgrPackage.swift | 19 ++++++++++++++----- Source/McuMgrManifest.swift | 10 ++++++++++ Source/McuMgrSuitEnvelope.swift | 6 ++++++ Source/McuMgrSuitManifest.swift | 4 ---- 4 files changed, 30 insertions(+), 9 deletions(-) diff --git a/Example/Example/Util/McuMgrPackage.swift b/Example/Example/Util/McuMgrPackage.swift index 74a9e9d..2c18dd7 100644 --- a/Example/Example/Util/McuMgrPackage.swift +++ b/Example/Example/Util/McuMgrPackage.swift @@ -120,13 +120,22 @@ fileprivate extension McuMgrPackage { throw McuMgrPackage.Error.manifestFileNotFound } let manifest = try McuMgrManifest(from: dfuManifestURL) - let images = try manifest.files.compactMap { manifestFile -> ImageManager.Image in - guard let imageURL = unzippedURLs.first(where: { $0.absoluteString.contains(manifestFile.file) }) else { + let images: [ImageManager.Image] + if let envelopeFile = manifest.envelopeFile() { + guard let envelopeURL = unzippedURLs.first(where: { $0.absoluteString.contains(envelopeFile.file) }) else { throw McuMgrPackage.Error.manifestImageNotFound } - let imageData = try Data(contentsOf: imageURL) - let imageHash = try McuMgrImage(data: imageData).hash - return ImageManager.Image(manifestFile, hash: imageHash, data: imageData) + let suitEnvelope = try McuMgrSuitEnvelope(from: envelopeURL) + return [suitEnvelope.image()].compactMap({ $0 }) + } else { + images = try manifest.files.compactMap { manifestFile -> ImageManager.Image in + guard let imageURL = unzippedURLs.first(where: { $0.absoluteString.contains(manifestFile.file) }) else { + throw McuMgrPackage.Error.manifestImageNotFound + } + let imageData = try Data(contentsOf: imageURL) + let imageHash = try McuMgrImage(data: imageData).hash + return ImageManager.Image(manifestFile, hash: imageHash, data: imageData) + } } try unzippedURLs.forEach { url in try fileManager.removeItem(at: url) diff --git a/Source/McuMgrManifest.swift b/Source/McuMgrManifest.swift index 6387e2e..283500d 100644 --- a/Source/McuMgrManifest.swift +++ b/Source/McuMgrManifest.swift @@ -12,6 +12,8 @@ import Foundation public struct McuMgrManifest: Codable { + // MARK: Public Properties + public let formatVersion: Int public let time: Int public let files: [File] @@ -25,6 +27,8 @@ public struct McuMgrManifest: Codable { static let LoadAddressRegEx: NSRegularExpression! = try? NSRegularExpression(pattern: #"\"load_address\":0x[0-9a-z]+,"#, options: [.caseInsensitive]) + // MARK: Init + public init(from url: URL) throws { guard let data = try? Data(contentsOf: url), let stringData = String(data: data, encoding: .utf8) else { @@ -42,6 +46,12 @@ public struct McuMgrManifest: Codable { throw Error.unableToDecodeJSON } } + + // MARK: API + + public func envelopeFile() -> File? { + files.first(where: { $0.content == .suitEnvelope }) + } } // MARK: - McuMgrManifest.File diff --git a/Source/McuMgrSuitEnvelope.swift b/Source/McuMgrSuitEnvelope.swift index 10dcb6e..a48bd82 100644 --- a/Source/McuMgrSuitEnvelope.swift +++ b/Source/McuMgrSuitEnvelope.swift @@ -42,6 +42,12 @@ public struct McuMgrSuitEnvelope { // MARK: API + public func image() -> ImageManager.Image? { + // Currently only supported Hash Digest Algorithm is SHA256. + guard let hash = digest.hash(for: .sha256) else { return nil } + return ImageManager.Image(image: 0, hash: hash, data: data) + } + public func sizeString() -> String { return "\(data.count) bytes" } diff --git a/Source/McuMgrSuitManifest.swift b/Source/McuMgrSuitManifest.swift index 0684ddd..d2361db 100644 --- a/Source/McuMgrSuitManifest.swift +++ b/Source/McuMgrSuitManifest.swift @@ -71,13 +71,9 @@ class McuMgrSuitCommonStructure: CBORMappable { class McuMgrSuitSharedSequence: CBORMappable { - public var conditionVendorIdentifier: UInt64? public var conditionClassIdentifier: UInt64? public required init(cbor: CBOR?) throws { - if case let CBOR.unsignedInt(vendorIdentifier)? = cbor?[1] { - self.conditionVendorIdentifier = vendorIdentifier - } if case let CBOR.unsignedInt(classIdentifier)? = cbor?[2] { self.conditionClassIdentifier = classIdentifier }