Skip to content

Commit 07f64c6

Browse files
author
Nick Kibysh
committed
feat(NordicSemiconductor#66): Update Proto
Updated proto file: - Created new 'ProtoImage' model with hash, data, slot and image fields - Added 'hash' to single image update arguments. Updated Swift code: - added extension for ImageManager.Image struct to create it with Proto model - fixed code after upgrade to v1.6 Flutter and Android pard are still broken
1 parent 3db45b3 commit 07f64c6

File tree

10 files changed

+234
-111
lines changed

10 files changed

+234
-111
lines changed

example/pubspec.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ packages:
382382
path: ".."
383383
relative: true
384384
source: path
385-
version: "0.2.0+1"
385+
version: "0.3.3"
386386
meta:
387387
dependency: transitive
388388
description:
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
//
2+
// Image+Proto.swift
3+
// mcumgr_flutter
4+
//
5+
// Created by Nick Kibysh on 18/03/2024.
6+
//
7+
8+
import Foundation
9+
import iOSMcuManagerLibrary
10+
11+
extension ImageManager.Image {
12+
init(proto: ProtoImage) {
13+
let image = Int(proto.image)
14+
let slot = Int(proto.slot)
15+
let hash = proto.hash
16+
let data = proto.data
17+
18+
if proto.hasSlot {
19+
self.init(image: image, slot: slot, hash: hash, data: data)
20+
} else {
21+
self.init(image: image, hash: hash, data: data)
22+
}
23+
24+
}
25+
}

ios/Classes/SwiftMcumgrFlutterPlugin.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ public class SwiftMcumgrFlutterPlugin: NSObject, FlutterPlugin {
159159
throw FlutterError(code: ErrorCode.updateManagerDoesNotExist.rawValue, message: "Update manager does not exist", details: call.debugDetails)
160160
}
161161

162-
let images = args.images.map { (Int($0.key), $0.value) }
162+
let images = args.images.map { ImageManager.Image(proto: $0) }
163163
let config = args.hasConfiguration ? FirmwareUpgradeConfiguration(proto: args.configuration) : FirmwareUpgradeConfiguration()
164164

165165
try manager.update(images: images, config: config)
@@ -177,7 +177,7 @@ public class SwiftMcumgrFlutterPlugin: NSObject, FlutterPlugin {
177177

178178
let config = args.hasConfiguration ? FirmwareUpgradeConfiguration(proto: args.configuration) : FirmwareUpgradeConfiguration()
179179

180-
try manager.update(data: args.firmwareData, config: config)
180+
try manager.update(hash: args.hash, data: args.firmwareData, config: config)
181181
}
182182

183183
private func kill(call: FlutterMethodCall) throws {

ios/Classes/UpdateManager.swift

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,14 @@ class UpdateManager {
3232
self.logStreamHandler = logStreamHandler
3333
}
3434

35-
func update(data: Data, config: FirmwareUpgradeConfiguration) throws {
35+
func update(hash: Data, data: Data, config: FirmwareUpgradeConfiguration) throws {
3636
dfuManager.logDelegate = updateLogger
37-
try dfuManager.start(data: data, using: config)
37+
// try dfuManager.start(hash: , data: data, using: config)
3838
}
3939

40-
func update(images: [(Int, Data)], config: FirmwareUpgradeConfiguration) throws {
40+
func update(images: [ImageManager.Image], config: FirmwareUpgradeConfiguration) throws {
4141
dfuManager.logDelegate = updateLogger
42-
let imgs = images.map { ImageManager.Image(image: $0.0, data: $0.1) }
43-
try dfuManager.start(images: imgs, using: config)
42+
try dfuManager.start(images: images)
4443
}
4544

4645
func pause() {

ios/Classes/lib/proto/flutter_mcu.pb.swift

Lines changed: 66 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ struct ProtoUpdateCallArgument {
2828

2929
var deviceUuid: String = String()
3030

31+
var hash: Data = Data()
32+
3133
var firmwareData: Data = Data()
3234

3335
var configuration: ProtoFirmwareUpgradeConfiguration {
@@ -58,19 +60,31 @@ struct ProtoError {
5860
init() {}
5961
}
6062

61-
/// Firmware image pair
62-
struct Pair {
63+
struct ProtoImage {
6364
// SwiftProtobuf.Message conformance is added in an extension below. See the
6465
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
6566
// methods supported on all messages.
6667

67-
var key: Int32 = 0
68+
var image: Int32 = 0
69+
70+
var slot: Int32 {
71+
get {return _slot ?? 0}
72+
set {_slot = newValue}
73+
}
74+
/// Returns true if `slot` has been explicitly set.
75+
var hasSlot: Bool {return self._slot != nil}
76+
/// Clears the value of `slot`. Subsequent reads from it will return its default value.
77+
mutating func clearSlot() {self._slot = nil}
78+
79+
var hash: Data = Data()
6880

69-
var value: Data = Data()
81+
var data: Data = Data()
7082

7183
var unknownFields = SwiftProtobuf.UnknownStorage()
7284

7385
init() {}
86+
87+
fileprivate var _slot: Int32? = nil
7488
}
7589

7690
struct ProtoUpdateWithImageCallArguments {
@@ -80,7 +94,7 @@ struct ProtoUpdateWithImageCallArguments {
8094

8195
var deviceUuid: String = String()
8296

83-
var images: [Pair] = []
97+
var images: [ProtoImage] = []
8498

8599
var configuration: ProtoFirmwareUpgradeConfiguration {
86100
get {return _configuration ?? ProtoFirmwareUpgradeConfiguration()}
@@ -206,7 +220,7 @@ struct ProtoUpdateStateChanges {
206220

207221
extension ProtoUpdateStateChanges.FirmwareUpgradeState: CaseIterable {
208222
// The compiler won't synthesize support with the UNRECOGNIZED case.
209-
static let allCases: [ProtoUpdateStateChanges.FirmwareUpgradeState] = [
223+
static var allCases: [ProtoUpdateStateChanges.FirmwareUpgradeState] = [
210224
.none,
211225
.validate,
212226
.upload,
@@ -319,7 +333,7 @@ struct ProtoFirmwareUpgradeConfiguration {
319333

320334
extension ProtoFirmwareUpgradeConfiguration.ImageUploadAlignment: CaseIterable {
321335
// The compiler won't synthesize support with the UNRECOGNIZED case.
322-
static let allCases: [ProtoFirmwareUpgradeConfiguration.ImageUploadAlignment] = [
336+
static var allCases: [ProtoFirmwareUpgradeConfiguration.ImageUploadAlignment] = [
323337
.disabled,
324338
.twoByte,
325339
.fourByte,
@@ -330,7 +344,7 @@ extension ProtoFirmwareUpgradeConfiguration.ImageUploadAlignment: CaseIterable {
330344

331345
extension ProtoFirmwareUpgradeConfiguration.FirmwareUpgradeMode: CaseIterable {
332346
// The compiler won't synthesize support with the UNRECOGNIZED case.
333-
static let allCases: [ProtoFirmwareUpgradeConfiguration.FirmwareUpgradeMode] = [
347+
static var allCases: [ProtoFirmwareUpgradeConfiguration.FirmwareUpgradeMode] = [
334348
.testOnly,
335349
.confirmOnly,
336350
.testAndConfirm,
@@ -541,7 +555,7 @@ struct ProtoLogMessage {
541555

542556
extension ProtoLogMessage.LogCategory: CaseIterable {
543557
// The compiler won't synthesize support with the UNRECOGNIZED case.
544-
static let allCases: [ProtoLogMessage.LogCategory] = [
558+
static var allCases: [ProtoLogMessage.LogCategory] = [
545559
.transport,
546560
.config,
547561
.crash,
@@ -557,7 +571,7 @@ extension ProtoLogMessage.LogCategory: CaseIterable {
557571

558572
extension ProtoLogMessage.LogLevel: CaseIterable {
559573
// The compiler won't synthesize support with the UNRECOGNIZED case.
560-
static let allCases: [ProtoLogMessage.LogLevel] = [
574+
static var allCases: [ProtoLogMessage.LogLevel] = [
561575
.debug,
562576
.verbose,
563577
.info,
@@ -600,7 +614,7 @@ struct ProtoReadMessagesResponse {
600614
#if swift(>=5.5) && canImport(_Concurrency)
601615
extension ProtoUpdateCallArgument: @unchecked Sendable {}
602616
extension ProtoError: @unchecked Sendable {}
603-
extension Pair: @unchecked Sendable {}
617+
extension ProtoImage: @unchecked Sendable {}
604618
extension ProtoUpdateWithImageCallArguments: @unchecked Sendable {}
605619
extension ProtoUpdateStateChangesStreamArg: @unchecked Sendable {}
606620
extension ProtoUpdateStateChanges: @unchecked Sendable {}
@@ -624,8 +638,9 @@ extension ProtoUpdateCallArgument: SwiftProtobuf.Message, SwiftProtobuf._Message
624638
static let protoMessageName: String = "ProtoUpdateCallArgument"
625639
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
626640
1: .standard(proto: "device_uuid"),
627-
2: .standard(proto: "firmware_data"),
628-
3: .same(proto: "configuration"),
641+
2: .same(proto: "hash"),
642+
3: .standard(proto: "firmware_data"),
643+
4: .same(proto: "configuration"),
629644
]
630645

631646
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@@ -635,8 +650,9 @@ extension ProtoUpdateCallArgument: SwiftProtobuf.Message, SwiftProtobuf._Message
635650
// enabled. https://github.com/apple/swift-protobuf/issues/1034
636651
switch fieldNumber {
637652
case 1: try { try decoder.decodeSingularStringField(value: &self.deviceUuid) }()
638-
case 2: try { try decoder.decodeSingularBytesField(value: &self.firmwareData) }()
639-
case 3: try { try decoder.decodeSingularMessageField(value: &self._configuration) }()
653+
case 2: try { try decoder.decodeSingularBytesField(value: &self.hash) }()
654+
case 3: try { try decoder.decodeSingularBytesField(value: &self.firmwareData) }()
655+
case 4: try { try decoder.decodeSingularMessageField(value: &self._configuration) }()
640656
default: break
641657
}
642658
}
@@ -650,17 +666,21 @@ extension ProtoUpdateCallArgument: SwiftProtobuf.Message, SwiftProtobuf._Message
650666
if !self.deviceUuid.isEmpty {
651667
try visitor.visitSingularStringField(value: self.deviceUuid, fieldNumber: 1)
652668
}
669+
if !self.hash.isEmpty {
670+
try visitor.visitSingularBytesField(value: self.hash, fieldNumber: 2)
671+
}
653672
if !self.firmwareData.isEmpty {
654-
try visitor.visitSingularBytesField(value: self.firmwareData, fieldNumber: 2)
673+
try visitor.visitSingularBytesField(value: self.firmwareData, fieldNumber: 3)
655674
}
656675
try { if let v = self._configuration {
657-
try visitor.visitSingularMessageField(value: v, fieldNumber: 3)
676+
try visitor.visitSingularMessageField(value: v, fieldNumber: 4)
658677
} }()
659678
try unknownFields.traverse(visitor: &visitor)
660679
}
661680

662681
static func ==(lhs: ProtoUpdateCallArgument, rhs: ProtoUpdateCallArgument) -> Bool {
663682
if lhs.deviceUuid != rhs.deviceUuid {return false}
683+
if lhs.hash != rhs.hash {return false}
664684
if lhs.firmwareData != rhs.firmwareData {return false}
665685
if lhs._configuration != rhs._configuration {return false}
666686
if lhs.unknownFields != rhs.unknownFields {return false}
@@ -700,11 +720,13 @@ extension ProtoError: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementatio
700720
}
701721
}
702722

703-
extension Pair: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
704-
static let protoMessageName: String = "Pair"
723+
extension ProtoImage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
724+
static let protoMessageName: String = "ProtoImage"
705725
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
706-
1: .same(proto: "key"),
707-
2: .same(proto: "value"),
726+
1: .same(proto: "image"),
727+
2: .same(proto: "slot"),
728+
3: .same(proto: "hash"),
729+
4: .same(proto: "data"),
708730
]
709731

710732
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@@ -713,26 +735,40 @@ extension Pair: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase,
713735
// allocates stack space for every case branch when no optimizations are
714736
// enabled. https://github.com/apple/swift-protobuf/issues/1034
715737
switch fieldNumber {
716-
case 1: try { try decoder.decodeSingularInt32Field(value: &self.key) }()
717-
case 2: try { try decoder.decodeSingularBytesField(value: &self.value) }()
738+
case 1: try { try decoder.decodeSingularInt32Field(value: &self.image) }()
739+
case 2: try { try decoder.decodeSingularInt32Field(value: &self._slot) }()
740+
case 3: try { try decoder.decodeSingularBytesField(value: &self.hash) }()
741+
case 4: try { try decoder.decodeSingularBytesField(value: &self.data) }()
718742
default: break
719743
}
720744
}
721745
}
722746

723747
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
724-
if self.key != 0 {
725-
try visitor.visitSingularInt32Field(value: self.key, fieldNumber: 1)
748+
// The use of inline closures is to circumvent an issue where the compiler
749+
// allocates stack space for every if/case branch local when no optimizations
750+
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
751+
// https://github.com/apple/swift-protobuf/issues/1182
752+
if self.image != 0 {
753+
try visitor.visitSingularInt32Field(value: self.image, fieldNumber: 1)
754+
}
755+
try { if let v = self._slot {
756+
try visitor.visitSingularInt32Field(value: v, fieldNumber: 2)
757+
} }()
758+
if !self.hash.isEmpty {
759+
try visitor.visitSingularBytesField(value: self.hash, fieldNumber: 3)
726760
}
727-
if !self.value.isEmpty {
728-
try visitor.visitSingularBytesField(value: self.value, fieldNumber: 2)
761+
if !self.data.isEmpty {
762+
try visitor.visitSingularBytesField(value: self.data, fieldNumber: 4)
729763
}
730764
try unknownFields.traverse(visitor: &visitor)
731765
}
732766

733-
static func ==(lhs: Pair, rhs: Pair) -> Bool {
734-
if lhs.key != rhs.key {return false}
735-
if lhs.value != rhs.value {return false}
767+
static func ==(lhs: ProtoImage, rhs: ProtoImage) -> Bool {
768+
if lhs.image != rhs.image {return false}
769+
if lhs._slot != rhs._slot {return false}
770+
if lhs.hash != rhs.hash {return false}
771+
if lhs.data != rhs.data {return false}
736772
if lhs.unknownFields != rhs.unknownFields {return false}
737773
return true
738774
}

lib/models/image.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import 'dart:typed_data';
2+
3+
class Image {
4+
int image;
5+
int slot;
6+
Uint8List hash;
7+
Uint8List data;
8+
9+
Image({
10+
required this.image,
11+
required this.slot,
12+
required this.hash,
13+
required this.data,
14+
});
15+
}

0 commit comments

Comments
 (0)