Skip to content

Commit 3dbd5de

Browse files
author
Nick Kibysh
committed
Merge branch 'feature/66_read_image_list' into develop
2 parents 9936d2e + a3b3033 commit 3dbd5de

26 files changed

+1032
-152
lines changed

android/src/main/kotlin/no/nordicsemi/android/mcumgr_flutter/McumgrFlutterPlugin.kt

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,18 @@ import android.bluetooth.BluetoothAdapter
44
import android.content.Context
55
import android.util.Pair
66
import androidx.annotation.NonNull
7+
import com.google.protobuf.kotlin.toByteString
78
import io.flutter.embedding.engine.plugins.FlutterPlugin
89
import io.flutter.plugin.common.EventChannel
910
import io.flutter.plugin.common.MethodCall
1011
import io.flutter.plugin.common.MethodChannel
1112
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
1213
import io.flutter.plugin.common.MethodChannel.Result
14+
import io.runtime.mcumgr.McuMgrCallback
1315
import io.runtime.mcumgr.dfu.FirmwareUpgradeManager
16+
import io.runtime.mcumgr.exception.McuMgrException
17+
import io.runtime.mcumgr.response.img.McuMgrImageStateResponse
18+
import no.nordicsemi.android.mcumgr_flutter.ext.toProto
1419

1520
import no.nordicsemi.android.mcumgr_flutter.logging.LoggableMcuMgrBleTransport
1621
import no.nordicsemi.android.mcumgr_flutter.utils.*
@@ -67,45 +72,59 @@ class McumgrFlutterPlugin : FlutterPlugin, MethodCallHandler {
6772
initializeUpdateManager(call)
6873
result.success(null)
6974
}
75+
7076
FlutterMethod.update -> {
7177
update(call)
7278
result.success(null)
7379
}
80+
7481
FlutterMethod.updateSingleImage -> {
7582
updateSingleImage(call)
7683
result.success(null)
7784
}
85+
7886
FlutterMethod.pause -> {
7987
retrieveManager(call).pause()
8088
result.success(null)
8189
}
90+
8291
FlutterMethod.resume -> {
8392
retrieveManager(call).resume()
8493
result.success(null)
8594
}
95+
8696
FlutterMethod.cancel -> {
8797
retrieveManager(call).cancel()
8898
result.success(null)
8999
}
100+
90101
FlutterMethod.isPaused -> {
91102
val isPaused = retrieveManager(call).isPaused
92103
result.success(isPaused)
93104
}
105+
94106
FlutterMethod.isInProgress -> {
95107
val isPaused = retrieveManager(call).isInProgress
96108
result.success(isPaused)
97109
}
110+
98111
FlutterMethod.readLogs -> {
99112
result.success(readLogs(call))
100113
}
114+
101115
FlutterMethod.clearLogs -> {
102116
retrieveManager(call).clearLogs()
103117
result.success(null)
104118
}
119+
105120
FlutterMethod.kill -> {
106121
kill(call)
107122
result.success(null)
108123
}
124+
125+
FlutterMethod.readImageList -> {
126+
imageList(call, result)
127+
}
109128
}
110129
} catch (e: FlutterError) {
111130
result.error(e.code, e.message, null)
@@ -162,7 +181,8 @@ class McumgrFlutterPlugin : FlutterPlugin, MethodCallHandler {
162181
)
163182
}
164183

165-
updateManager.start(arg.images.map { Pair.create(it.key, it.value_.toByteArray()) }, config)
184+
val images = arg.images.map { Pair.create(it.image, it.data_.toByteArray()) }
185+
updateManager.start(images, config)
166186
}
167187

168188
@Throws(FlutterError::class)
@@ -235,4 +255,40 @@ class McumgrFlutterPlugin : FlutterPlugin, MethodCallHandler {
235255
}
236256
managers.remove(address)
237257
}
258+
259+
/** Image Manager */
260+
private fun imageList(@NonNull call: MethodCall, result: Result) {
261+
val address = (call.arguments as? String).guard {
262+
throw WrongArguments("Device address expected")
263+
}
264+
val updateManager = managers[address].guard {
265+
throw UpdateManagerDoesNotExist("Update manager does not exist")
266+
}
267+
268+
val callback = object : McuMgrCallback<McuMgrImageStateResponse> {
269+
override fun onResponse(response: McuMgrImageStateResponse) {
270+
var protoResponse: ProtoListImagesResponse
271+
if (response.images != null) {
272+
val images = response.images.map { it.toProto() }
273+
protoResponse = ProtoListImagesResponse(
274+
uuid = address,
275+
images = images,
276+
existing = true
277+
)
278+
} else {
279+
protoResponse = ProtoListImagesResponse(
280+
uuid = address,
281+
existing = false
282+
)
283+
}
284+
result.success(protoResponse.encode())
285+
}
286+
287+
override fun onError(exception: McuMgrException) {
288+
result.error("mcumgr_error", exception.message, null)
289+
}
290+
}
291+
292+
updateManager.imageManager.list(callback)
293+
}
238294
}

android/src/main/kotlin/no/nordicsemi/android/mcumgr_flutter/UpdateManager.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,15 @@ package no.nordicsemi.android.mcumgr_flutter
22

33
import android.util.Log
44
import android.util.Pair
5+
import io.runtime.mcumgr.McuMgrCallback
56
import io.runtime.mcumgr.ble.McuMgrBleTransport
67
import io.runtime.mcumgr.dfu.model.McuMgrImageSet;
78
import io.runtime.mcumgr.dfu.FirmwareUpgradeCallback
89
import io.runtime.mcumgr.dfu.FirmwareUpgradeController
910
import io.runtime.mcumgr.dfu.FirmwareUpgradeManager
1011
import io.runtime.mcumgr.exception.McuMgrException
12+
import io.runtime.mcumgr.managers.ImageManager
13+
import io.runtime.mcumgr.response.img.McuMgrImageStateResponse
1114
import no.nordicsemi.android.mcumgr_flutter.ext.shouldLog
1215
import no.nordicsemi.android.mcumgr_flutter.ext.toProto
1316
import no.nordicsemi.android.mcumgr_flutter.gen.*
@@ -43,6 +46,7 @@ class UpdateManager(
4346
private val manager: FirmwareUpgradeManager = FirmwareUpgradeManager(transport, this)
4447
private val address: String = transport.bluetoothDevice.address
4548
private val transport: LoggableMcuMgrBleTransport = transport as LoggableMcuMgrBleTransport
49+
val imageManager: ImageManager = ImageManager(transport)
4650

4751
init {
4852
manager.setMemoryAlignment(4)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package no.nordicsemi.android.mcumgr_flutter.ext
2+
3+
import io.runtime.mcumgr.response.McuMgrResponse
4+
import io.runtime.mcumgr.response.img.McuMgrImageStateResponse
5+
import no.nordicsemi.android.mcumgr_flutter.gen.ProtoImageSlot
6+
import okio.ByteString
7+
import okio.ByteString.Companion.toByteString
8+
9+
fun McuMgrImageStateResponse.ImageSlot.toProto(): ProtoImageSlot {
10+
return ProtoImageSlot(
11+
slot = this.slot.toLong(),
12+
version = version,
13+
hash = hash.toByteString(),
14+
bootable = bootable,
15+
pending = pending,
16+
confirmed = confirmed,
17+
active = active,
18+
permanent = permanent
19+
)
20+
}

android/src/main/kotlin/no/nordicsemi/android/mcumgr_flutter/utils/FlutterMethod.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ enum class FlutterMethod {
1515
cancel,
1616
readLogs,
1717
clearLogs,
18-
kill;
18+
kill,
19+
readImageList;
1920

2021
companion object {
2122
fun valueOfOrNull(string: String) = try {

example/ios/Podfile.lock

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,18 +39,18 @@ PODS:
3939
- ZIPFoundation (= 0.9.13)
4040
- flutter_blue_plus (0.0.1):
4141
- Flutter
42-
- iOSMcuManagerLibrary (1.4.3):
42+
- iOSMcuManagerLibrary (1.6):
4343
- SwiftCBOR (= 0.4.4)
4444
- mcumgr_flutter (0.0.2):
4545
- Flutter
46-
- iOSMcuManagerLibrary (= 1.4.3)
46+
- iOSMcuManagerLibrary (= 1.6)
4747
- SwiftProtobuf
4848
- path_provider_foundation (0.0.1):
4949
- Flutter
5050
- FlutterMacOS
51-
- SDWebImage (5.18.10):
52-
- SDWebImage/Core (= 5.18.10)
53-
- SDWebImage/Core (5.18.10)
51+
- SDWebImage (5.19.0):
52+
- SDWebImage/Core (= 5.19.0)
53+
- SDWebImage/Core (5.19.0)
5454
- SwiftCBOR (0.4.4)
5555
- SwiftProtobuf (1.25.2)
5656
- SwiftyGif (5.4.4)
@@ -96,10 +96,10 @@ SPEC CHECKSUMS:
9696
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
9797
flutter_archive: 1805fdd3a695fd284b43edb53dc35ca843fb761c
9898
flutter_blue_plus: 4837da7d00cf5d441fdd6635b3a57f936778ea96
99-
iOSMcuManagerLibrary: 6c2ff04a23bd9dbfddce95374638fe28c32f406c
100-
mcumgr_flutter: e4703f2e33405ba3fef314b8c9a93563843a1520
99+
iOSMcuManagerLibrary: 4102a4595be1c69e5286d7f1520a733c82c30b0a
100+
mcumgr_flutter: 097e59bec5917b527ba6d095da57bdaed2de1fa2
101101
path_provider_foundation: 29f094ae23ebbca9d3d0cec13889cd9060c0e943
102-
SDWebImage: fc8f2d48bbfd72ef39d70e981bd24a3f3be53fec
102+
SDWebImage: 981fd7e860af070920f249fd092420006014c3eb
103103
SwiftCBOR: ce5354ec8b660da2d6fc754462881119dbe1f963
104104
SwiftProtobuf: 407a385e97fd206c4fbe880cc84123989167e0d1
105105
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f

example/ios/Runner.xcodeproj/project.pbxproj

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -358,7 +358,7 @@
358358
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
359359
CLANG_ENABLE_MODULES = YES;
360360
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
361-
DEVELOPMENT_TEAM = P3R8YQEV4L;
361+
DEVELOPMENT_TEAM = 88Z93X62R5;
362362
ENABLE_BITCODE = NO;
363363
FRAMEWORK_SEARCH_PATHS = (
364364
"$(inherited)",
@@ -374,7 +374,7 @@
374374
"$(inherited)",
375375
"$(PROJECT_DIR)/Flutter",
376376
);
377-
PRODUCT_BUNDLE_IDENTIFIER = no.nordicsemi.mcumgrFlutterExample;
377+
PRODUCT_BUNDLE_IDENTIFIER = no.nordicsemi.mcumgrFlutterExample2;
378378
PRODUCT_NAME = "$(TARGET_NAME)";
379379
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
380380
SWIFT_VERSION = 5.0;
@@ -496,7 +496,7 @@
496496
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
497497
CLANG_ENABLE_MODULES = YES;
498498
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
499-
DEVELOPMENT_TEAM = P3R8YQEV4L;
499+
DEVELOPMENT_TEAM = 88Z93X62R5;
500500
ENABLE_BITCODE = NO;
501501
FRAMEWORK_SEARCH_PATHS = (
502502
"$(inherited)",
@@ -512,7 +512,7 @@
512512
"$(inherited)",
513513
"$(PROJECT_DIR)/Flutter",
514514
);
515-
PRODUCT_BUNDLE_IDENTIFIER = no.nordicsemi.mcumgrFlutterExample;
515+
PRODUCT_BUNDLE_IDENTIFIER = no.nordicsemi.mcumgrFlutterExample2;
516516
PRODUCT_NAME = "$(TARGET_NAME)";
517517
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
518518
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
@@ -528,7 +528,7 @@
528528
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
529529
CLANG_ENABLE_MODULES = YES;
530530
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
531-
DEVELOPMENT_TEAM = P3R8YQEV4L;
531+
DEVELOPMENT_TEAM = 88Z93X62R5;
532532
ENABLE_BITCODE = NO;
533533
FRAMEWORK_SEARCH_PATHS = (
534534
"$(inherited)",
@@ -544,7 +544,7 @@
544544
"$(inherited)",
545545
"$(PROJECT_DIR)/Flutter",
546546
);
547-
PRODUCT_BUNDLE_IDENTIFIER = no.nordicsemi.mcumgrFlutterExample;
547+
PRODUCT_BUNDLE_IDENTIFIER = no.nordicsemi.mcumgrFlutterExample2;
548548
PRODUCT_NAME = "$(TARGET_NAME)";
549549
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
550550
SWIFT_VERSION = 5.0;

example/lib/src/handlers/firmware_update_handler.dart

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ import 'package:mcumgr_flutter_example/src/repository/firmware_image_repository.
88

99
import 'package:http/http.dart' as http;
1010
import 'package:path_provider/path_provider.dart' as path_provider;
11-
import 'package:tuple/tuple.dart';
1211
import 'package:uuid/uuid.dart';
1312

1413
import 'package:mcumgr_flutter/mcumgr_flutter.dart';
@@ -111,7 +110,11 @@ class FirmwareUnpacker extends FirmwareUpdateHandler {
111110
for (final file in manifest.files) {
112111
final firmwareFile = File('${destinationDir.path}/${file.file}');
113112
final firmwareFileData = await firmwareFile.readAsBytes();
114-
firmware.firmwareImages!.add(Tuple2(file.image, firmwareFileData));
113+
final image = Image(
114+
image: file.image,
115+
data: firmwareFileData,
116+
);
117+
firmware.firmwareImages!.add(image);
115118
}
116119

117120
// delete tempDir
@@ -141,7 +144,7 @@ class FirmwareUpdater extends FirmwareUpdateHandler {
141144

142145
if (request is SingleImageFirmwareUpdateRequest) {
143146
final fwImage = request.firmwareImage;
144-
await updateManager.updateWithImageData(image: fwImage!);
147+
await updateManager.updateWithImageData(imageData: fwImage!);
145148
return updateManager;
146149
} else {
147150
final multiImageRequest = request as MultiImageFirmwareUpdateRequest;

example/lib/src/model/firmware_update_request.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import 'dart:typed_data';
22

3+
import 'package:mcumgr_flutter/mcumgr_flutter.dart';
34
import 'package:mcumgr_flutter_example/src/model/firmware_image.dart';
4-
import 'package:tuple/tuple.dart';
55

66
class FirmwareUpdateRequest {
77
SelectedFirmware? firmware;
@@ -25,7 +25,7 @@ class SingleImageFirmwareUpdateRequest extends FirmwareUpdateRequest {
2525

2626
class MultiImageFirmwareUpdateRequest extends FirmwareUpdateRequest {
2727
Uint8List? zipFile;
28-
List<Tuple2<int, Uint8List>>? firmwareImages;
28+
List<Image>? firmwareImages;
2929

3030
RemoteFirmware? get remoteFirmware => firmware as RemoteFirmware?;
3131

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: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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 data = proto.data
16+
17+
let hash: Data
18+
if proto.hasHash {
19+
hash = proto.hash
20+
} else {
21+
hash = try! McuMgrImage(data: data).hash
22+
}
23+
24+
25+
if proto.hasSlot {
26+
self.init(image: image, slot: slot, hash: hash, data: data)
27+
} else {
28+
self.init(image: image, hash: hash, data: data)
29+
}
30+
31+
}
32+
}

0 commit comments

Comments
 (0)