Giter Club home page Giter Club logo

android-nrf-connect-device-manager's Introduction

Download

nRF Connect Device Manager

nRF Connect Device Manager library is compatible with Mcu Manager, a management subsystem supported by nRF Connect SDK, Zephyr and Apache Mynewt.

The library provides a transport agnostic implementation of the McuManager protocol. It contains a default implementation for BLE transport.

Minimum required Android version is 5.0 (Android Lollipop) due to a requirement for high MTU.

The sample application has been named nRF Connect Device Manager and is available on Google Play.

Note

This repository is a fork of the McuManager Android Library, which has been deprecated. All new features and bug fixes will be added here. Please, migrate to the new version to get future updates. See migration guide.

Importing

McuManager BLE (Recommended)

Contains the core and a BLE transport implementation using Nordic's Android-BLE-Library v2.

implementation 'no.nordicsemi.android:mcumgr-ble:1.9.2'

The core module will be included automatically.

Latest version targeting API 30 (Android 11) is 0.13.0-beta07.

McuManager Core

Core dependency only. Use if you want to provide your own transport implementation.

implementation 'no.nordicsemi.android:mcumgr-core:1.9.2'

Latest version targeting API 30 (Android 11) is 0.13.0-beta07.

Migration from the original repo

The library was initially released as McuManager Android Library.

When migrating from the original version, change

implementation 'io.runtime.mcumgr:mcumgr-ble:0.XX.X'

to the above.

The API and package names have not been changed to ease migration.

Introduction

McuManager is an application layer protocol used to manage and monitor microcontrollers running Apache Mynewt and Zephyr. More specifically, McuManager implements over-the-air (OTA) firmware upgrades, log and stat collection, and file-system and configuration management.

Command Groups

McuManager are organized by functionality into command groups. In this Android library, command groups are called managers and extend the McuManager class. The managers (groups) implemented in the library are:

  • DefaultManager: Contains commands relevant to the OS. This includes task and memory pool statistics, device time read & write, and device reset.
  • ImageManager: Manage image state on the device and perform image uploads.
  • BasicManager: Allows erasing application storage (factory reset) (NCS 2.0+).
  • StatsManager: Read stats from the device.
  • CrashManager: Read crash logs from the device (not supported in Zephyr or NCS).
  • SettingsManager: Read/Write settings values on the device.
  • LogManager: Collect logs from the device.
  • FsManager: Download/upload files from the device file system.
  • ShellManager: Execute shell commands.

Firmware Upgrade

Firmware upgrade is generally a four step process performed using commands from the image and default commands groups: upload, test, reset, and confirm.

This library provides a FirmwareUpgradeManager as a convenience for upgrading the image running on a device.

Example

// Initialize the BLE transporter with context and a BluetoothDevice
McuMgrTransport transport = new McuMgrBleTransport(context, bluetoothDevice);

// Initialize the Firmware Upgrade Manager.
FirmwareUpgradeManager dfuManager = new FirmwareUpgradeManager(transport, dfuCallback)

// Set estimated swap time, in milliseconds. This is an approximate time required by the McuBoot
// to swap images after a successful upgrade.
dfuManager.setEstimatedSwapTime(swapTime);
// Since version 1.1 the window upload is stable. It allows to send multiple packets concurrently,
// without the need to wait for a notification. This may speed up the upload process significantly,
// but it needs to be supported on the device side. See MCUMGR_BUF_COUNT in Zephyr KConfig file.
dfuManager.setWindowUploadCapacity(mcumgrBuffers);
// The memory alignment is read when window upload capacity was set to 2+, otherwise is ignored.
// For devices built on NCS 1.8 or older this may need to be set to 4 (4-byte alignment) on nRF5
// devices. Each packet sent will be trimmed to have number of bytes dividable by given value.
// Since NCS 1.9 the flash implementation can buffer unaligned data instead of discarding.
dfuManager.setMemoryAlignment(memoryAlignment);
// Set a mode: Confirm only, Test only, Test & Confirm or None.
// For multi-core update only the first one is supported. See details below.
dfuManager.setMode(mode);

// Start the firmware upgrade with the image data.
// The "eraseStorage" parameter allows to erase application data before swapping images, and is
// useful when switching to a different, incompatible application, or when upgrading by a major
// version, when app storage is structured differently. Set to false by default.
dfuManager.start(imageData, eraseStorage);

To update multi-core device, use:

List<Pair<Integer, byte[]>> images = new ArrayList<>();
images.add(new Pair<Integer, byte[]>(0 /* image 0 */, appCoreImage));
images.add(new Pair<Integer, byte[]>(1 /* image 1 */, netCoreImage));
dfuManager.start(images, eraseStorage);

You may also use ZipPackage class from the Sample app, which can unpack the ZIP file generated by west in Zephyr or nRF Connect SDK (see example).

Firmware Upgrade Manager

A FirmwareUpgradeManager provides an easy way to perform firmware upgrades on a device. A FirmwareUpgradeManager must be initialized with an McuMgrTransport which defines the transport scheme and device. Once initialized, a FirmwareUpgradeManager can perform one firmware upgrade at a time. Firmware upgrades are started using the start(byte[] imageData, boolean eraseStorage) or start(List<Pair<Integer, byte[]>> images, boolean eraseStorage) methods and can be paused, resumed, and canceled using pause(), resume(), and cancel() respectively.

Firmware Upgrade Mode

McuManager firmware upgrades can actually be performed in few different ways. These different upgrade modes determine the commands sent after the upload step. The FirmwareUpgradeManager can be configured to perform these different methods using setMode(FirmwareUpgradeManager.Mode mode). The different firmware upgrade modes are as follows:

  • TEST_AND_CONFIRM: This mode is the default and recommended mode for performing upgrades due to it's ability to recover from a bad firmware upgrade. Note, that the device must support this feature. Currently, multi-core devices (based on nRF5340) do not support this mode. The process for this mode is UPLOAD, TEST, RESET, CONFIRM.
  • CONFIRM_ONLY: This mode may be used for devices with revert disabled. If the device fails to boot into the new image, it will not be able to recover and will need to be re-flashed. The process for this mode is UPLOAD, CONFIRM, RESET.
  • TEST_ONLY: This mode is useful if you want to run tests on the new image running before confirming it manually as the primary boot image. This mode is recommended for devices that do not support reverting images, i.e. multi core devices. The process for this mode is UPLOAD, TEST, RESET.
  • NONE: This mode should be used if the bootloader does not support reverting images. The process for this mode is UPLOAD, RESET. If the device supports bootloader information command, and the bootloader is in DirectXIP without revert mode, this mode will be selected automatically. This mode was added in library version 1.8.

Note

Devices based on nRF5340 SoC support only CONFIRM_ONLY mode because the image from the Network Core cannot be read from the Application Core, making it impossible to temporarily save it.

Note

Read about MCUboot modes here.

Software Update for Internet of Things (SUIT)

Starting from version 1.9, the library supports SUIT (Software Update for Internet of Things) files. In this case the selected mode is ignored. The process of upgrading is embedded in the SUIT file.

Firmware Upgrade State

FirmwareUpgradeManager acts as a simple, mostly linear state machine which is determined by the Mode. As the manager moves through the firmware upgrade process, state changes are provided through the FirmwareUpgradeCallback's onStateChanged method.

The FirmwareUpgradeManager contains an additional state, VALIDATE, which precedes the upload. The VALIDATE state checks the current image state of the device in an attempt to bypass certain states of the firmware upgrade. For example, if the image to upload is already in slot 1 on the device, the State will skip UPLOAD and move directly to TEST (or CONFIRM if Mode.CONFIRM_ONLY has been set). If the uploaded image is already active, and confirmed in slot 0, the upgrade will succeed immediately. The VALIDATE state makes it easy to reattempt an upgrade without needing to re-upload the image or manually determine where to start.

License

This library is licensed under the Apache 2.0 license. For more info, see the LICENSE file.

android-nrf-connect-device-manager's People

Contributors

andrazp avatar bgiori avatar giulianofranchetto avatar ksidirop-laerdal avatar mikesnyder360 avatar philips77 avatar rdeo-aziwell avatar ritikakapade avatar saty9 avatar twyatt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

android-nrf-connect-device-manager's Issues

Add UI for Shell Manager

With Shell group commands supported on the library side, it would be great to have an option to send shell commands from Nrf Connect Device Manager app.

  • Add new Shell tab
  • Add option to send shell commands
  • Display output of a command
  • Add option to list previously used commands ordered from most recently used to the oldest one

feature request: Zephyr NVS long write command

In the Zephyr project there has been a growing need for long writes for devices (adding certificates in base64 or configuration data) without a filesystem.

There is an early implementation of an mcumgr group for NVS here:

zephyrproject-rtos/zephyr#52318

I'd like to know if it would be interesting for the project to have this feature implemented in the device manager for mobile phones. Otherwise, I might just work on a fork.

Add offset on file upload/download

Hi,

Are you considering adding an offset to the FileUploader and file download?

We implemented this kind of feature with your library, in our project.

If you want to add this feature we can integrate it with you.

Best regards,
Tal

Cannot disconnect from BLE device

From what I can tell, ever since I added the device manager to my gradle, I am not able to disconnect from my device, despite getting the disconnect callbacks. The part of the log that says: "bta_gattc_mark_bg_conn unable to find the bg connection mask for: d4:3f:9b:09:4e:5b" might be of interest.

Right now I am just disconnecting under normal conditions (not DFU related). The device will only disconnect if I disable Bluetooth on my Android device.

Here is my gradle:

    // https://mvnrepository.com/artifact/no.nordicsemi.android/ble-livedata
    implementation 'no.nordicsemi.android:ble-livedata:2.3.1'
    // https://mvnrepository.com/artifact/no.nordicsemi.android.support.v18/scanner
    runtimeOnly 'no.nordicsemi.android.support.v18:scanner:1.5.0'

    // https://mvnrepository.com/artifact/no.nordicsemi.android/mcumgr-core
    implementation 'no.nordicsemi.android:mcumgr-ble:0.13.0-beta04'

Here is the log:

2021-09-23 13:11:18.517 15883-15883/com.r2f.android.orthofit.debug D/BluetoothGatt: cancelOpen() - device: D4:3F:9B:09:4E:5B
2021-09-23 13:11:18.518 14579-14653/com.android.bluetooth D/BtGatt.GattService: clientDisconnect() - address=D4:3F:9B:09:4E:5B, connId=8
2021-09-23 13:11:18.518 14579-14616/com.android.bluetooth E/bt_btif: bta_gattc_mark_bg_conn unable to find the bg connection mask for: d4:3f:9b:09:4e:5b
2021-09-23 13:11:18.519 14579-14600/com.android.bluetooth D/BtGatt.GattService: onDisconnected() - clientIf=8, connId=8, address=D4:3F:9B:09:4E:5B
2021-09-23 13:11:18.519 15883-15939/com.r2f.android.orthofit.debug D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=8 device=D4:3F:9B:09:4E:5B
2021-09-23 13:11:18.521 15883-15939/com.r2f.android.orthofit.debug D/BluetoothGatt: close()
2021-09-23 13:11:18.521 15883-15939/com.r2f.android.orthofit.debug D/BluetoothGatt: unregisterApp() - mClientIf=8
2021-09-23 13:11:18.526 14579-14653/com.android.bluetooth D/BtGatt.GattService: unregisterClient() - clientIf=8
2021-09-23 13:11:18.617 15883-15883/com.r2f.android.orthofit.debug D/BleRepository: ConnectionObserver onDeviceDisconnecting() com.r2f.android.repository.BikeControl@d051f71 D4:3F:9B:09:4E:5B
2021-09-23 13:11:18.621 15883-15883/com.r2f.android.orthofit.debug D/BleRepository: ConnectionObserver onDisconnected() com.r2f.android.repository.BikeControl@d051f71 D4:3F:9B:09:4E:5B 0

Uploading a corrupted .bin file should cause the target device to complain about it before it actually applies the FW on the device

Is there some sort of integrity check performed on the uploaded .bin file that I'm missing? I have intentionally corrupted the firmware .bin file using a hex editor and uploaded it over to a BLE device that runs on Nordic's stack (McuMgr) and the device applied the FW just fine without sweating about it.

Shouldn't the .bin file contain some sort of checksum-check to be 100% sure that the firmware that just got uploaded to the device is indeed healthy, before proceeding to install it?

Please let me know if McuMgr stack actually supports such a feature in a some non-obvious way.

enhancement : adding mcumgr direct image upload option

Hi,

Would it be possible to support a DIRECT_IMAGE_UPLOAD option for image_2 that is supported on linux mcumgr tool shown below?

https://docs.zephyrproject.org/3.0.0/samples/subsys/mgmt/mcumgr/smp_svr/README.html#direct-image-upload-and-image-mapping-to-mcuboot-slot
The mcumgr image upload command may be provided optional -e -n parameter that will select target image (e.g. -e -n 3 is for image_2)

This DFU can be tested with NCS by adding CONFIG_IMG_MGMT_DIRECT_IMAGE_UPLOAD=y.

Best Regards,

Version 1.2.0 does not detect any devices on Android 12 Patch May 5

Scanning does not detect any nearby devices, this used to work previously with the same hardware device.

I notice that the app is no longer asking for Location permission, and does not have it granted in the app settings page. The only permission it has is "Nearby Devices", not sure if an explicit "Location" permission is still required in this Android version. Could this be an issue?

For comparison, the nRF Connect app does have the Location permission, and works fine (detects same device, including the SMP service).

[Request] Keep the resulting byte-code of the generated .aars and .jars Java11-compliant in terms of byte-code so as to make them friendly towards the "Classic Xamarin" (mono) C# java-bindings toolchain

I've explained the issue we're facing here:

#75 (comment)

In my team we created C# nugets that rely on java-bindings under the surface to interact with Nordic BLE devices. Up to version 1.5.1 of your libs everything was working smoothly. In the recent months however something changed in your libs in regard to how the 'sealed' classes are being employed:

https://github.com/search?q=repo%3ANordicSemiconductor%2FAndroid-nRF-Connect-Device-Manager%20sealed&type=code

When we upgraded the underlying java libs to version 1.7.2 we realized that even though our nuget packages where getting properly built (without any errors), when we tried to install+build "Classic Xamarin" apps for Android we would get a build-error like this one:

image

From what I've gathered in so far (and I could be wrong about some details - but the general idea seems to be correct) when the java libs got updated to use gradle 8.x+ in commit cab13d6 (30/06/2023) this caused the entire build system of the project to automatically switch gears over to JDK17+ and in the same vein the source + target compatibility for byte code was upgraded to version 17:

    classpath 'com.android.tools.build:gradle:8.0.2'

    compileOptions {
          sourceCompatibility JavaVersion.VERSION_17   <---
          targetCompatibility JavaVersion.VERSION_17    <---
    }

Before this the generated java-libs where Java11-compatible in terms of the generated byte code. After the gear switch however the projects became incompatible with Java11 bytecode thus leading to the error observed above.

There might be a simple solution to this problem: We can keep the generated java .aar and .jar compatible with Java11 per

https://stackoverflow.com/questions/73453524/what-is-causing-this-error-com-android-tools-r8-internal-nc-sealed-classes-are

I will look deeper into this and keep you updated. Keep up the good work.

Firmware Upgrade "Image not valid!" only with Android (iOS version working)

Hello,

We use this library (1.4.1) in our mobile app to upgrade our BLE Device firmware (DFU, Zephyr, McuBoot). The iOS version of this library works as expected, but we have issues making this upgrade process work with the Android version. The device image used for both cases is the same.

This issue is also in the nRF Connect application (4.26.0) for Android. nrF Connect app for iOS works (2.5.3).

I have included below the code we use for iOS and Android and the messages from the BLE device during the upgrade process with the Android version. 

Could you please help? Thanks!

BLE Device Output

BLE Deviceuart:~$ *** Booting Zephyr OS version 2.3.99  ***
[00:00:00.003,601] <inf> mcuboot: Starting bootloader
[00:00:00.009,704] <inf> mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.019,561] <inf> mcuboot: Boot source: none
[00:00:00.024,932] <inf> mcuboot: Swap type: perm
[00:00:08.675,231] <err> mcuboot: Image in the secondary slot is not valid!
[00:00:09.051,116] <inf> mcuboot: Bootloader chainload address offset: 0xe000
[00:00:09.058,654] <inf> mcuboot: Jumping to the first image slot

iOS Code (Swift)

private func startDfu(_ address: String, binary: FlutterStandardTypedData, result: @escaping FlutterResult) {
    guard let uuid = UUID(uuidString: address) else {
        result(FlutterError(code: "DEVICE_ADDRESS_ERROR", message: "Device address conversion failed.", details: "Device address \(address) conversion failed"))
        return
    }

    guard let imageData = getImageData(binary: binary) else {
        result(FlutterError(code: "FIRMWARE_NOT_FOUND", message: "Binary file not valid.", details: nil))
        return
    }

    let bleTransport = McuMgrBleTransport(uuid)
    let dfuManager = FirmwareUpgradeManager(transporter: bleTransport, delegate: self)
    dfuManager.logDelegate = UIApplication.shared.delegate as? McuMgrLogDelegate
    dfuManager.estimatedSwapTime = 20.0

    do {
        try dfuManager.start(data: imageData)
    } catch {
        print("Error reading hash: \(error)")
    }
}

Android Code (Kotlin)

fun startDfu(binary: ByteArray): Unit {
    getBleDevice(address) { device ->
        val transport: McuMgrTransport = McuMgrBleTransport(context, device);
        val dfuManager = FirmwareUpgradeManager(transport, this)

        dfuManager.setEstimatedSwapTime(20000)
        dfuManager.setMode(FirmwareUpgradeManager.Mode.CONFIRM_ONLY)

        val eraseStorage = false
        val imageData = getImageData(binary)

        dfuManager.start(imageData, eraseStorage)
    }
}

Reading firmware version number

Hi,

Does anybody have any example on how I would use this library to read the version number of the image in slot 0?

Rick

After upgrade completes, slots revert back to old firmware version

I see the device swap it's slots back (reverting to the old firmware image) after the library reports a successful upgrade. The library reports all stages of the upgrade succeeded (onUpgradeCompleted is invoked), but afterward, when the device is turned off and turned on again, the firmware reverts to the image prior to the upgrade. What could be causing this behavior? I can see the slots swap. I had this issue with 0.13.0-beta08 and also previously 0.11.0. You can see it says the 3.6.11 version has successfully swapped with 3.6.9, but then when I restart the device, the slots are swapped back to 3.6.9 as the primary and 3.6.11 as the secondary.

What is a workaround?

Version: 0.13.0-beta08
Android Version: 10

Relevant log lines:

2021-11-10 12:14:08.810 [main] DEBUG - onStateChanged: old=RESET, new=CONFIRM
2021-11-10 12:14:09.587 [main] DEBUG McuMgrBleTransport - [Callback] Connection state changed with status: 133 and new state: 0 (DISCONNECTED)
2021-11-10 12:14:09.588 [main] WARN  McuMgrBleTransport - Error: (0x85): GATT ERROR
2021-11-10 12:14:09.589 [main] DEBUG McuMgrBleTransport - wait(500)
2021-11-10 12:14:10.094 [main] DEBUG McuMgrBleTransport - gatt.close()
2021-11-10 12:14:10.106 [main] DEBUG McuMgrBleTransport - wait(200)
2021-11-10 12:14:10.308 [main] TRACE McuMgrBleTransport - Retrying...
2021-11-10 12:14:10.311 [main] DEBUG McuMgrBleTransport - gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, LE 1M)
2021-11-10 12:14:10.852 [main] DEBUG McuMgrBleTransport - [Callback] Connection state changed with status: 0 and new state: 2 (CONNECTED)
2021-11-10 12:14:10.854 [main] INFO  McuMgrBleTransport - Connected to F6:4E:EF:5E:A9:DB
2021-11-10 12:14:10.861 [main] DEBUG McuMgrBleTransport - wait(1600)
2021-11-10 12:14:11.507 [main] INFO  McuMgrBleTransport - Connection parameters updated (interval: 7.5ms, latency: 0, timeout: 5000ms)
2021-11-10 12:14:11.862 [main] INFO  McuMgrBleTransport - Connection parameters updated (interval: 48.75ms, latency: 0, timeout: 5000ms)
2021-11-10 12:14:12.467 [main] TRACE McuMgrBleTransport - Discovering services...
2021-11-10 12:14:12.469 [main] DEBUG McuMgrBleTransport - gatt.discoverServices()
2021-11-10 12:14:12.480 [main] INFO  McuMgrBleTransport - Services discovered
2021-11-10 12:14:12.482 [main] TRACE McuMgrBleTransport - Primary service found
2021-11-10 12:14:12.487 [main] TRACE McuMgrBleTransport - Requesting new MTU...
2021-11-10 12:14:12.487 [main] DEBUG McuMgrBleTransport - gatt.requestMtu(498)
2021-11-10 12:14:12.594 [main] INFO  McuMgrBleTransport - MTU changed to: 247
2021-11-10 12:14:12.597 [main] DEBUG McuMgrBleTransport - gatt.setCharacteristicNotification(da2e7828-fbce-4e01-ae9e-261174997c48, true)
2021-11-10 12:14:12.600 [main] TRACE McuMgrBleTransport - Enabling notifications for da2e7828-fbce-4e01-ae9e-261174997c48
2021-11-10 12:14:12.602 [main] DEBUG McuMgrBleTransport - gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x01-00)
2021-11-10 12:14:12.690 [main] INFO  McuMgrBleTransport - Data written to descr. 00002902-0000-1000-8000-00805f9b34fb, value: (0x) 01-00
2021-11-10 12:14:12.693 [main] INFO  McuMgrBleTransport - Notifications enabled
2021-11-10 12:14:12.695 [main] DEBUG FirmwareUpdater - onConnected
2021-11-10 12:14:12.700 [main] INFO  McuMgrBleTransport - Sending (58 bytes) Header (Op: 2, Flags: 0, Len: 50, Group: 1, Seq: 0, Command: 0) CBOR {"confirm":true,"hash":"cYQV7cnhpbmWnj1Jf7ZWqsIDb8A3UMoFaQagI+jLBU8="}
2021-11-10 12:14:12.701 [main] TRACE McuMgrBleTransport - Writing characteristic da2e7828-fbce-4e01-ae9e-261174997c48 (WRITE COMMAND)
2021-11-10 12:14:12.702 [main] DEBUG McuMgrBleTransport - gatt.writeCharacteristic(da2e7828-fbce-4e01-ae9e-261174997c48)
2021-11-10 12:14:12.706 [main] INFO  McuMgrBleTransport - Data written to da2e7828-fbce-4e01-ae9e-261174997c48, value: (0x) 02-00-00-32-00-01-00-00-BF-67-63-6F-6E-66-69-72-6D-F5-64-68-61-73-68-58-20-71-84-15-ED-C9-E1-A5-B9-96-9E-3D-49-7F-B6-56-AA-C2-03-6F-C0-37-50-CA-05-69-06-A0-23-E8-CB-05-4F-FF
2021-11-10 12:14:12.789 [main] INFO  McuMgrBleTransport - Notification received from da2e7828-fbce-4e01-ae9e-261174997c48, value: (0x) 03-00-00-87-00-01-00-00-BF-66-69-6D-61-67-65-73-9F-BF-64-73-6C-6F-74-00-67-76-65-72-73-69-6F-6E-66-33-2E-36-2E-31-31-64-68-61-73-68-58-20-71-84-15-ED-C9-E1-A5-B9-96-9E-3D-49-7F-B6-56-AA-C2-03-6F-C0-37-50-CA-05-69-06-A0-23-E8-CB-05-4F-68-62-6F-6F-74-61-62-6C-65-F5-67-70-65-6E-64-69-6E-67-F4-69-63-6F-6E-66-69-72-6D-65-64-F5-66-61-63-74-69-76-65-F5-69-70-65-72-6D-61-6E-65-6E-74-F4-FF-FF-6B-73-70-6C-69-74-53-74-61-74-75-73-00-FF
2021-11-10 12:14:12.795 [main] INFO  McuMgrBleTransport - Received Header (Op: 3, Flags: 0, Len: 135, Group: 1, Seq: 0, Command: 0) CBOR {"images":[{"slot":0,"version":"3.6.11","hash":"cYQV7cnhpbmWnj1Jf7ZWqsIDb8A3UMoFaQagI+jLBU8=","bootable":true,"pending":false,"confirmed":true,"active":true,"permanent":false}],"splitStatus":0}
2021-11-10 12:14:12.808 [main] TRACE Confirm - Confirm response: {"images":[{"slot":0,"version":"3.6.11","hash":"cYQV7cnhpbmWnj1Jf7ZWqsIDb8A3UMoFaQagI+jLBU8=","bootable":true,"pending":false,"confirmed":true,"active":true,"permanent":false}],"splitStatus":0}
2021-11-10 12:14:12.809 [main] DEBUG - onUpgradeCompleted

Question: Timeout while updating firmware

On certain device when we try to update device firmware we get a timeout with the following

ERROR msg = Transaction 67 timed out without receiving a response

Generally a bluetooth toggle and retry fixes it.

What can be the issue here?

Minimum SDK issue with Jackson dependency

Hello, we see a crash happening on Android 7 when using the McuMgr.
Our app has a minimum SDK of 21, Android 5.

Cause:

Tracing it down, the issue is caused by the Jackson dependency, see this corresponding issue: FasterXML/jackson-databind#3658

As a result, the minimum SDK of Jackson got bumped to API 26 (Android 8) since version 2.14. Which resolves the issue for them.

Looking back at when McuMgr updated to Jackson 2.14+, it dates back to the commit at 22 feb 2023: 006e5ba

Issue/question:

Since McuMgr Android currently describes the requirement of Android 5 as minimum.
Would this mean that the minimum SDK for McuMgr Android should become Android 8?
Or will there come another solution for this?

Workaround:

As a workaround we can use the old McuMgr (version 1.5.2). That version depends on Jackson version 2.13.3 which doesn't have this issue. But we would lack the fixes and features of the later versions of McuMgr of course.

Stacktrace:

For completeness, here is the error stacktrace (happens since version 1.6.0 and the latest version 1.9.1):

java.lang.NoSuchMethodError: No virtual method getParameterCount()I in class Ljava/lang/reflect/Constructor; or its super classes (declaration of 'java.lang.reflect.Constructor' appears in /system/framework/core-oj.jar)
    at com.fasterxml.jackson.databind.util.ClassUtil$Ctor.getParamCount(ClassUtil.java:1450)
    at com.fasterxml.jackson.databind.introspect.AnnotatedCreatorCollector._findPotentialConstructors(AnnotatedCreatorCollector.java:120)
    at com.fasterxml.jackson.databind.introspect.AnnotatedCreatorCollector.collect(AnnotatedCreatorCollector.java:70)
    at com.fasterxml.jackson.databind.introspect.AnnotatedCreatorCollector.collectCreators(AnnotatedCreatorCollector.java:61)
    at com.fasterxml.jackson.databind.introspect.AnnotatedClass._creators(AnnotatedClass.java:403)
    at com.fasterxml.jackson.databind.introspect.AnnotatedClass.getConstructors(AnnotatedClass.java:308)
    at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector._addCreators(POJOPropertiesCollector.java:618)
    at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.collectAll(POJOPropertiesCollector.java:431)
    at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getPropertyMap(POJOPropertiesCollector.java:391)
    at com.fasterxml.jackson.databind.introspect.POJOPropertiesCollector.getProperties(POJOPropertiesCollector.java:233)
    at com.fasterxml.jackson.databind.introspect.BasicBeanDescription._properties(BasicBeanDescription.java:164)
    at com.fasterxml.jackson.databind.introspect.BasicBeanDescription.findProperties(BasicBeanDescription.java:239)
    at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._findCreatorsFromProperties(BasicDeserializerFactory.java:328)
    at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory._constructDefaultValueInstantiator(BasicDeserializerFactory.java:272)
    at com.fasterxml.jackson.databind.deser.BasicDeserializerFactory.findValueInstantiator(BasicDeserializerFactory.java:223)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.buildBeanDeserializer(BeanDeserializerFactory.java:262)
    at com.fasterxml.jackson.databind.deser.BeanDeserializerFactory.createBeanDeserializer(BeanDeserializerFactory.java:151)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer2(DeserializerCache.java:415)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createDeserializer(DeserializerCache.java:350)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCache2(DeserializerCache.java:264)
    at com.fasterxml.jackson.databind.deser.DeserializerCache._createAndCacheValueDeserializer(DeserializerCache.java:244)
    at com.fasterxml.jackson.databind.deser.DeserializerCache.findValueDeserializer(DeserializerCache.java:142)
    at com.fasterxml.jackson.databind.DeserializationContext.findRootValueDeserializer(DeserializationContext.java:648)
    at com.fasterxml.jackson.databind.ObjectMapper._findRootDeserializer(ObjectMapper.java:4861)
    at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4731)
    at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3738)
    at io.runtime.mcumgr.util.CBOR.toObject(CBOR.java:31)
    at io.runtime.mcumgr.response.McuMgrResponse.buildResponse(McuMgrResponse.java:247)
    at io.runtime.mcumgr.ble.McuMgrBleTransport$2.onResponse(McuMgrBleTransport.java:409)
    at io.runtime.mcumgr.ble.callback.SmpProtocolSessionKt.onResponse$lambda$1(SmpProtocolSession.kt:156)
    at io.runtime.mcumgr.ble.callback.SmpProtocolSessionKt.$r8$lambda$y5OWzRv1IbLlvC7QCOqni68WVyI(SmpProtocolSession.kt)
    at io.runtime.mcumgr.ble.callback.SmpProtocolSessionKt$$ExternalSyntheticLambda2.run(D8$$SyntheticClass)
    at android.os.Handler.handleCallback(Handler.java:751)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:154)
    at android.app.ActivityThread.main(ActivityThread.java:6780)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1500)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1390)

nordic chip is not being disconnect after , ncs firmware update completes

we are updating firmware using this library in our nordic chip. but after successful firmware update completes , nordic chip is still connected with our phone . but this case does not happen in ios version of library. can you please brief what should we do , so that chip automatically get disconnects from phone once firmware update completes as like ios .

Mcu Mgr Error: NO_MEMORY (2)

I have been trying to upgrade my device through my Android app using this library, and I continually get the following error in the UPLOAD stage:
2021-11-09 15:07:49.439 6269-6269/com.somewearlabs.sw.debug D/[main] FirmwareUpdater: upgrade failed=UPLOAD; error=io.runtime.mcumgr.exception.McuMgrErrorException: Mcu Mgr Error: NO_MEMORY (2).

I have tried using the standalone NRF Connect Device Manager app, and using Advanced > Select File > Upload, and I get the same NO_MEMORY error there too. I tried restarted the device I'm trying to upgrade, and also tried repeating the upload with fresh images each time. I still get this error.

Could someone please help me with a workaround?

Version: 0.13.0-beta-08
Android Version: 10

More logs attached:

2021-11-09 15:06:47.160 6269-6269/com.somewearlabs.sw.debug D/[main] onStateChanged: old=VALIDATE, new=RESET
2021-11-09 15:06:47.161 6269-6269/com.somewearlabs.sw.debug D/[main] BleUtility: startFirmwareUpdateTimer: start. Expect DFU related disconnect...;
2021-11-09 15:06:47.163 6269-6269/com.somewearlabs.sw.debug I/[main] McuMgrBleTransport: Sending (10 bytes) Header (Op: 2, Flags: 0, Len: 2, Group: 0, Seq: 1, Command: 5) CBOR {}
2021-11-09 15:06:47.163 6269-6269/com.somewearlabs.sw.debug D/[main] McuMgrBleTransport: gatt.writeCharacteristic(da2e7828-fbce-4e01-ae9e-261174997c48)
2021-11-09 15:06:47.165 6269-6269/com.somewearlabs.sw.debug I/[main] McuMgrBleTransport: Data written to da2e7828-fbce-4e01-ae9e-261174997c48, value: (0x) 02-00-00-02-00-00-01-05-BF-FF
2021-11-09 15:06:47.190 6269-6269/com.somewearlabs.sw.debug I/[main] McuMgrBleTransport: Notification received from da2e7828-fbce-4e01-ae9e-261174997c48, value: (0x) 03-00-00-02-00-00-01-05-BF-FF
2021-11-09 15:06:47.194 6269-6269/com.somewearlabs.sw.debug I/[main] McuMgrBleTransport: Received Header (Op: 3, Flags: 0, Len: 2, Group: 0, Seq: 1, Command: 5) CBOR {}
2021-11-09 15:06:47.936 6269-12692/com.somewearlabs.sw.debug D/BluetoothGatt: onClientConnectionState() - status=8 clientIf=5 device=C4:EE:1A:38:C8:50
2021-11-09 15:06:47.942 6269-6269/com.somewearlabs.sw.debug D/[main] McuMgrBleTransport: [Callback] Connection state changed with status: 8 and new state: 0 (DISCONNECTED)
2021-11-09 15:06:47.943 6269-6269/com.somewearlabs.sw.debug W/[main] McuMgrBleTransport: Error: (0x8): GATT CONN TIMEOUT
2021-11-09 15:06:47.943 6269-6269/com.somewearlabs.sw.debug I/[main] McuMgrBleTransport: Disconnected
2021-11-09 15:06:47.969 6269-6269/com.somewearlabs.sw.debug D/[main] McuMgrBleTransport: gatt.close()
2021-11-09 15:06:47.970 6269-6269/com.somewearlabs.sw.debug D/BluetoothGatt: close()
2021-11-09 15:06:47.975 6269-6269/com.somewearlabs.sw.debug D/BluetoothGatt: unregisterApp() - mClientIf=5
2021-11-09 15:06:47.982 6269-6269/com.somewearlabs.sw.debug D/[main] onDisconnected - could be because of RESET stage
2021-11-09 15:06:47.982 6269-6269/com.somewearlabs.sw.debug I/[main] Reset: Device disconnected
2021-11-09 15:07:47.247 6269-6269/com.somewearlabs.sw.debug D/[main] raonStateChanged: old=RESET, new=UPLOAD
2021-11-09 15:07:47.275 6269-15701/com.somewearlabs.sw.debug D/[pool-29-thread-1] McuMgrBleTransport: gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, LE 1M)
2021-11-09 15:07:47.276 6269-15701/com.somewearlabs.sw.debug D/BluetoothAdapter: STATE_ON
2021-11-09 15:07:47.279 6269-15701/com.somewearlabs.sw.debug D/BluetoothGatt: connect() - device: C4:EE:1A:38:C8:50, auto: false
2021-11-09 15:07:47.279 6269-15701/com.somewearlabs.sw.debug D/BluetoothAdapter: isSecureModeEnabled
2021-11-09 15:07:47.279 6269-15701/com.somewearlabs.sw.debug D/BluetoothGatt: registerApp()
2021-11-09 15:07:47.280 6269-15701/com.somewearlabs.sw.debug D/BluetoothGatt: registerApp() - UUID=5cca7371-d537-466c-ab47-488d6687c0c8
2021-11-09 15:07:47.284 6269-12692/com.somewearlabs.sw.debug D/BluetoothGatt: onClientRegistered() - status=0 clientIf=5
2021-11-09 15:07:47.474 6269-12692/com.somewearlabs.sw.debug D/BluetoothGatt: onClientConnectionState() - status=0 clientIf=5 device=C4:EE:1A:38:C8:50
2021-11-09 15:07:47.477 6269-6269/com.somewearlabs.sw.debug D/[main] McuMgrBleTransport: [Callback] Connection state changed with status: 0 and new state: 2 (CONNECTED)
2021-11-09 15:07:47.478 6269-6269/com.somewearlabs.sw.debug I/[main] McuMgrBleTransport: Connected to C4:EE:1A:38:C8:50
2021-11-09 15:07:47.483 6269-6269/com.somewearlabs.sw.debug D/[main] McuMgrBleTransport: wait(1600)
2021-11-09 15:07:48.130 6269-12692/com.somewearlabs.sw.debug D/BluetoothGatt: onConnectionUpdated() - Device=C4:EE:1A:38:C8:50 interval=6 latency=0 timeout=500 status=0
2021-11-09 15:07:48.132 6269-6269/com.somewearlabs.sw.debug I/[main] McuMgrBleTransport: Connection parameters updated (interval: 7.5ms, latency: 0, timeout: 5000ms)
2021-11-09 15:07:48.480 6269-12692/com.somewearlabs.sw.debug D/BluetoothGatt: onConnectionUpdated() - Device=C4:EE:1A:38:C8:50 interval=39 latency=0 timeout=500 status=0
2021-11-09 15:07:48.481 6269-6269/com.somewearlabs.sw.debug I/[main] McuMgrBleTransport: Connection parameters updated (interval: 48.75ms, latency: 0, timeout: 5000ms)
2021-11-09 15:07:49.091 6269-6269/com.somewearlabs.sw.debug D/[main] McuMgrBleTransport: gatt.discoverServices()
2021-11-09 15:07:49.092 6269-6269/com.somewearlabs.sw.debug D/BluetoothGatt: discoverServices() - device: C4:EE:1A:38:C8:50
2021-11-09 15:07:49.101 6269-12692/com.somewearlabs.sw.debug D/BluetoothGatt: onSearchComplete() = Device=C4:EE:1A:38:C8:50 Status=0
2021-11-09 15:07:49.102 6269-6269/com.somewearlabs.sw.debug I/[main] McuMgrBleTransport: Services discovered
2021-11-09 15:07:49.108 6269-6269/com.somewearlabs.sw.debug D/[main] McuMgrBleTransport: gatt.requestMtu(498)
2021-11-09 15:07:49.108 6269-6269/com.somewearlabs.sw.debug D/BluetoothGatt: configureMTU() - device: C4:EE:1A:38:C8:50 mtu: 498
2021-11-09 15:07:49.215 6269-12692/com.somewearlabs.sw.debug D/BluetoothGatt: onConfigureMTU() - Device=C4:EE:1A:38:C8:50 mtu=247 status=0
2021-11-09 15:07:49.218 6269-6269/com.somewearlabs.sw.debug I/[main] McuMgrBleTransport: MTU changed to: 247
2021-11-09 15:07:49.219 6269-6269/com.somewearlabs.sw.debug D/[main] McuMgrBleTransport: gatt.setCharacteristicNotification(da2e7828-fbce-4e01-ae9e-261174997c48, true)
2021-11-09 15:07:49.220 6269-6269/com.somewearlabs.sw.debug D/BluetoothGatt: setCharacteristicNotification() - uuid: da2e7828-fbce-4e01-ae9e-261174997c48 enable: true
2021-11-09 15:07:49.222 6269-6269/com.somewearlabs.sw.debug D/[main] McuMgrBleTransport: gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x01-00)
2021-11-09 15:07:49.311 6269-6269/com.somewearlabs.sw.debug I/[main] McuMgrBleTransport: Data written to descr. 00002902-0000-1000-8000-00805f9b34fb, value: (0x) 01-00
2021-11-09 15:07:49.312 6269-6269/com.somewearlabs.sw.debug I/[main] McuMgrBleTransport: Notifications enabled
2021-11-09 15:07:49.314 6269-6269/com.somewearlabs.sw.debug D/[main] FirmwareUpdater: onConnected
2021-11-09 15:07:49.329 6269-6269/com.somewearlabs.sw.debug I/[main] McuMgrBleTransport: Sending (243 bytes) Header (Op: 2, Flags: 0, Len: 235, Group: 1, Seq: 0, Command: 1) CBOR {"data":"PbjzlgAAAAAAAgAAHCQGAAAAAAADBgsAAAAAAAAAAAD/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////","len":403308,"sha":"Ikzf","off":0}
2021-11-09 15:07:49.331 6269-6269/com.somewearlabs.sw.debug D/[main] McuMgrBleTransport: gatt.writeCharacteristic(da2e7828-fbce-4e01-ae9e-261174997c48)
2021-11-09 15:07:49.333 6269-6269/com.somewearlabs.sw.debug I/[main] McuMgrBleTransport: Data written to da2e7828-fbce-4e01-ae9e-261174997c48, value: (0x) 02-00-00-EB-00-01-00-01-BF-64-64-61-74-61-58-CC-3D-B8-F3-96-00-00-00-00-00-02-00-00-1C-24-06-00-00-00-00-00-03-06-0B-00-00-00-00-00-00-00-00-00-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-FF-63-6C-65-6E-1A-00-06-27-6C-63-73-68-61-43-22-4C-DF-63-6F-66-66-00-FF
2021-11-09 15:07:49.408 6269-6269/com.somewearlabs.sw.debug I/[main] McuMgrBleTransport: Notification received from da2e7828-fbce-4e01-ae9e-261174997c48, value: (0x) 03-00-00-06-00-01-00-01-BF-62-72-63-02-FF
2021-11-09 15:07:49.415 6269-6269/com.somewearlabs.sw.debug I/[main] McuMgrBleTransport: Received Header (Op: 3, Flags: 0, Len: 6, Group: 1, Seq: 0, Command: 1) CBOR {"rc":2}
2021-11-09 15:07:49.439 6269-6269/com.somewearlabs.sw.debug D/[main] FirmwareUpdater: upgrade failed=UPLOAD; error=io.runtime.mcumgr.exception.McuMgrErrorException: Mcu Mgr Error: NO_MEMORY (2)

[Feature] Make the library bindings-friendly for the sake of C# / Xamarin

Currently there are some severe problems when it comes to binding kotlin stuff over to C#. To my knowledge there's no official C# / Xamarin bindings project for this library. Maybe you could take up on this side-quest and introduce such a project? It would definately be highly appreciated.

can't disconnect from device after firmware update

I'm using the FirmwareUpgradeManager and it's working great, except at the end of the upgrade, it appears to still be connected to the device. This means my own code can no longer connect to it as it's not advertising.

I start the process like this:

        this.transport = McuMgrBleTransport(activity, this.device.bluetoothDevice)
        val dfuManager = FirmwareUpgradeManager(this.transport!!, this.dfuCallback)

        val path = firmwarePath("firmware_$INSTALL_FIRMWARE_VERSION")
        val resId = activity.resources.getIdentifier(path, "raw", activity.packageName)
        val stream = activity.resources.openRawResource(resId)
        val buf = ByteArray(stream.available())
        stream.read(buf)

        dfuManager.setMode(FirmwareUpgradeManager.Mode.TEST_AND_CONFIRM)
        dfuManager.start(buf)

When FirmwareUpgradeCallback.onUpgradeCompleted() is called, I tried disconnecting explicitly:

        this.transport!!.disconnect()

but it didn't seem to have any effect.

Is there another way I should be disconnecting?

Payload (250 bytes) too long for MTU: 249

Problem I started to see today:

E/Uploader: Upload failed
    Payload (250 bytes) too long for MTU: 249
        at io.runtime.mcumgr.ble.McuMgrBleTransport.lambda$send$0$io-runtime-mcumgr-ble-McuMgrBleTransport(McuMgrBleTransport.java:356)
        at io.runtime.mcumgr.ble.McuMgrBleTransport$$ExternalSyntheticLambda3.onRequestCompleted(Unknown Source:13)
        at no.nordicsemi.android.ble.Request.lambda$notifySuccess$1$no-nordicsemi-android-ble-Request(Request.java:1239)
        at no.nordicsemi.android.ble.Request$$ExternalSyntheticLambda2.run(Unknown Source:4)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:226)
        at android.os.Looper.loop(Looper.java:313)
        at android.os.HandlerThread.run(HandlerThread.java:67)

I solved this by downgrading
no.nordicsemi.android:mcumgr-ble:1.5.0
to
no.nordicsemi.android:mcumgr-ble:1.4.1'

in my app and it works now.

My guess is that the "Ble library update":
"BLE library updated to version 2.6.0-alpha04 by @philips77" in @#84
has to do something with this issue.

FS Upload file - Error Payload too long

Hello,
I'm having issue when uploading larger files onto the device:

Screenshot_20221012-101813

By the error prompt it seems that the FS layer is trying to send larger chunk than supported MTU.

nRF9160 Mcumgr FMFU update support

Hello,
i would like to ask you, whether you are planing to implement the FMFU part of the Nordic Connect SDK into the nRF connect device manager application.

  • The sdk is supporting this by custom nordic implementation, which is not public. It is distributed as closed source DLL.
  • Due to the release of modem firmware 1.3.2, we will be forced to update the firmware on our devices, yet we are still missing open implementation for this. We would be also satisfied with closed one integrated into nrf connect device manager.
  • We have verified the functionality that our mcumgr inside the device is capable of receiving the fmfu by using other transport layer(UART). However, we would like to have ability to update the modem firmware from the mobile.
  • I think we are definitely not alone who will face this issue, with upcoming releases of the modem firmware.

FMFU

File Manager - Windows capability

Hello,
i wanted to ask you what is the support or roadmap to implement the same principle for the File Manager as for the Image Uploader that uses windowUpload. Is there a way how to speed up the File download/upload process ?

Task: Save files from device download on Smartphone

Hello, I use the app to exchange data between my BLE device and the smartphone. Is it possible to extend the download function so that the files are not only displayed, but also are stored in the file system of the smartphone afterwards?

Best regards

Transaction xxx timed out without receiving a response

I have encountered very randomly occurring error when uploading firmware image from the Device Manager. Using only the older imageUpload method, i have tested also the windowUpload method however i do not have logs from this one. The issue is present in both of the implementations.
It occurs pretty randomly sometime i can upload for hours without any issue sometimes i cannot finish even single image upload.

I have encountered the issue after updating from version 0.11 inside our own app when using the library. Afterwards we have traced the issue within the sample application Device Manager for the latest master commit. So i suspect that the earlier version might not be effected, however that version is ancient history by now.

The issue is that the SMP response is somehow lost inside the mcumgr layer of the library. I have logs that clearly shows that the response has arrived and it arrived bellow the timeout threshold of the SmpProtocolSession.kt.

I have added timestamps to the lower level logging of the McuMgrBleTransport to demonstrate that the response indeed arrived.

Could you kindly look at the logs attached bellow and somehow try to reproduce/find/fix the issue ?

First occurance Logs without timestamps:
ble-mcumgr
ble-mcumgr.log

Second occurrence logs with millisecond timestamps + Device logs for img_mgmt upload method recieve and response times:
ble-mcumgr
ble-mcumgr.log
ble-mcumgr-dev.log

Firmware Upgrade "Connection timed out" in 1.4.0 example app

Using smp_svr example from nRFConnect SDK 2.0.0, with overlay-bt.conf (which should have improved DFU speed)
Android 10 (Huawei P20 pro), nRF52840dk

Expected: Firmware upgrade works
Actual: Firmware upgrade "Connection timed out". Sometimed on Validate step, sometimes at start of Uploading step

Similar to iOS version?

Using different SMP service and characteristics UUID for McuMgrBleTransport

What is considered to be the best approach to choosing different SMP service and characteristics UUID for the McuMgrBleTransport instance? Forgive me if I'm wrong, but there doesn't seem to be any sensible mechanism in the code for extending the current McuMgrBleTransport with UUIDs overrides.

The only option seems to be replacing the whole McuMgrGattCallback class in the CustomMcuMgrBleTransport.getGattCallback(), which contains many references to internal structure of the McuMgrBleTransport, such as mSmpCharacteristicNotify, mSmpCharacteristicWrite, mSmpProtocol and so on, so as a result it's not an option at all. Our goal is not to write completely custom transport or completely custom GattCallback. We would like to use the exactly same logic that is already present in the McuMgrBleTransport, just with different UUIDs.

Is there any reason for such strict access control in these methods and subclasses? Our device has exposed two SMP services (we have two nRF chips on board) and we need to access both SMP services with single mobile application. Unfortunately we're currently not able to do this without very ugly hacks and code duplication, which also effectively prevents us from easily updating to the latest library version.

The most appreciated solution for this would be parametrized constructor of McuMgrTransport, which would allow us to choose different UUIDs. Is this possible to include with the library?

(Sorry for making this question an issue, I'd rather use the discussions feature, but it's disabled for this repo)

Detailed explanation of NO_ENTRY(5) error

I'm receiving this error while trying to upload .bin file, could you provide more detailed explanation of this error? Can it be connected to .bin file itself?

"No entry was found for the request. This commonly means that the command group has not been enabled on the device, although the exact meaning."

Cannot connect with sample project "smp_svr" on Android App

When trying to connect to a device using the "smp_svr" sample from the Nordic Connect SDK on an Android app, the connection doesn't hold. After briefly connecting, it immediately disconnects, showing reason code 0x08. This happens consistently across my two Android 8 devices.

Steps to Reproduce:

  • Burn the "smp_svr" sample on a "NRF52840 dongle".
  • Connect to the device using the Android app.
  • Notice that the connection gets established but quickly disconnects with reason code 0x08.
  • Repeat these steps on various Android devices to see the same result.

Expected Behaviour:

  • The connection should stay stable without disconnecting immediately after being established.

Additional Information:

  • Connecting to the same device works fine with the nRF Connect mobile app on both Android and iOS.
  • Device Manager app on iOS can also connect and perform DFU successfully.
  • Logs from the device show successful connection followed by immediate disconnection, then advertising restarts.

Environment:

  • Android Devices Used: [Huawei Nova 2, Huawei Mate 10 light]
  • Nordic Connect SDK Version: [2.5.0, 2.5.1]

Attempted Solutions:

  • Tried reconnecting multiple times without success.
  • Confirmed the issue occurs on different Android devices.

Screenshots/Logs:

image

image

image

WhatsApp Image 2024-02-21 at 14 29 36

Reading multiple Settings via settingsManager returns same result for different settings

I am trying to read multiple settings from inside a composable from my Device via the settingsManager. I am using the following code

@Composable
fun DetailsScreen(navController: NavController) {
    val device = bluetoothViewModel.selectedDevice ?: return
    val context = LocalContext.current

    fun readSetting(device: BluetoothDevice, settingName: String, settingState: MutableState<String?>) {
        val transport = McuMgrBleTransport(context, device)
        val settingsManager = SettingsManager(transport)
        Log.d("readSetting","Start reading Setting ${settingName}")

        settingsManager.read(
            settingName,
            object : McuMgrCallback<McuMgrSettingsReadResponse> {
                override fun onResponse(response: McuMgrSettingsReadResponse) {
                    if (response.isSuccess) {
                        val byteArray = response.`val`
                        settingState.value = byteArray.toString(Charsets.UTF_8)
                        Log.d("Callback", "onResponse called. Setting: $settingName, Response: ${settingState.value}")
                    }
                }

                override fun onError(p0: McuMgrException) {
                    Toast.makeText(
                        context,
                        "Konnte Setting \"$settingName\" nicht lesen: ${p0.message}, ${p0.cause}",
                        Toast.LENGTH_LONG
                    ).show()
                }
            })
   }

    val ssidState = remember { mutableStateOf<String?>(null) }
    val passwordState = remember { mutableStateOf<String?>(null) }

    // Rufen Sie die Funktion für die gewünschten Einstellungen auf
    LaunchedEffect(device) {
        readSetting(device, "wifi/ssid", ssidState)
        readSetting(device, "wifi/password", passwordState)
    }

    Surface(modifier = Modifier.fillMaxSize(), color = MaterialTheme.colorScheme.background) {
        Column {
            if (device != null) {
                Column(
                    modifier = Modifier.weight(1f),
                    verticalArrangement = Arrangement.Top
                ) {
                    Text(text = "${device.name}")
                    Text(text = "Wifi SSID: ${ssidState.value ?: "Lade..."}")
                    Text(text = "Wifi Password: ${passwordState.value ?: "Lade..."}")
                }
            } else {
                Text(text = "Kein Gerät ausgewählt")
            }

            // Button zum Zurückkehren zur vorherigen Ansicht
            Button(onClick = { navController.popBackStack() }) {
                Text("Zurück")
            }
        }
    }
}

The android logs show the same string result for both requests:

2024-01-27 01:09:18.546  6535-6535  Callback                com.example.test                     D  onResponse called. Setting: wifi/ssid, Response: <my-ssid-string>??
2024-01-27 01:09:18.564  6535-6535  Callback                com.example.test                     D  onResponse called. Setting: wifi/password, Response: <my-ssid-string>??

I can see that my device returns the right content (printed in the logs):

[00:48:43.819,702] <inf> settings_mgmt: Read Key: wifi/ssid
[00:48:43.819,732] <inf> app_settings: Look for Key: ssid, max_length: 32
[00:48:43.819,793] <inf> app_settings: Found content: <my-ssid-string>, length: 9
[00:48:43.907,989] <inf> settings_mgmt: Read Key: wifi/password
[00:48:43.908,020] <inf> app_settings: Look for Key: password, max_length: 32
[00:48:43.908,050] <inf> app_settings: Found content: <here-is-my-password>, length: 12

Unfortunately both texts in my Surface show the same string (either SSID or password). How do I read multiple settings in parallel?

Kernel oops with version 1.6.0 and Zephyr 3.3

Hi,

I get a kernel oops on my zephyr app while upgrading the firmware via v1.6.0 of this app. It occurs while doing the upload (app log attached).

On Zephyr side of things, this assertion fails
WEST_TOPDIR/zephyr/subsys/bluetooth/controller/ll_sw/nordic/lll/lll.c:473

 diff += HAL_TICKER_CNTR_CMP_OFFSET_MIN;
        if (diff > HAL_TICKER_US_TO_TICKS(EVENT_OVERHEAD_START_US)) {
                /* TODO: for Low Latency Feature with Advanced XTAL feature.
                 * 1. Release retained HF clock.
                 * 2. Advance the radio event to accommodate normal prepare
                 *    duration.
                 * 3. Increase the preempt to start ticks for future events.
                 */
                LL_ASSERT_MSG(false, "%s: Actual EVENT_OVERHEAD_START_US = %u",
                              __func__, HAL_TICKER_TICKS_TO_US(diff));

                return 1U;

Relevant notes:

  1. v1.5.2 worked fine on same app on Zephyr 3.2 (haven't tried v1.5.2 on Zephyr 3.3)
  2. IOS-nRF-Connect-Device-Manager 1.3 works fine on both Zephyr 3.2 and 3.3
  3. mcumgr go app works fine on both Zephyr 3.2 and 3.3

kernel oops.txt

Happy to provide more info, if required.
Thanks

File download command

I use the device manager to test my PCB (BLE) (nordic 52845)running Zephyr (NCS 2.6). I can send hellos, perform DFUs, and write/read files. I was looking for the command that the app uses to read a file because I am looking for a way to read the file and save it to the Android mobile phone. Is the file download command use a mcumgr command? Is it possible to replicate this command and send it as shell command?
Thanks for your help
Giorgio

Firmware upgrade: "Image is identical to the active one"

When is "Image is identical to the active one" message returned when "test" or "confirm" images?

I have an image in slot 1 that has a different version and different hash compared to image in slot 0,
but im still getting "Image is identical to the active one" when doing "test" or "confirm" in the images card.

Hard coded constants

Hi,

It seems like you have hard coded the timeout values in the writeInternal function from the Uploader class, you use:
val timeout = if (chunk.offset == 0) 40_000L else 2_500L
instead of using the constants from the McuManager class:

    protected final static long DEFAULT_TIMEOUT = 40_000; // ms
    protected final static long SHORT_TIMEOUT = 2_500; // ms

Just wanted to let you know.

FS module download/upload speed

Hi,
i would like to ask you, if there is plan to focus on download speed for the Mcumgr FS Module. The download speed of this module is rather slow. Do you experience similar issue ?

We are downloading about 0.5MB of logs from the device and it takes ages. I guess the similar issue will be when anyone uploads files to the device(That is another issue). We would like to be able to download files from the device in reasonable times.

Is there a plan to create similar window download method as for the Image upload ?

Transaction 122 timed out without receiving a response

Hello,

I am trying to perform an update.

         val settings = ScanSettings.Builder()
                .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                .setLegacy(false)
                .setReportDelay(500)
                .setUseHardwareBatchingIfSupported(false)
                .build()

            val scanner = BluetoothLeScannerCompat.getScanner()
            scanner.startScan(null, settings, scanCallback)

then I receive always:

I/BLE: onUploadProgressChanged 1635374864707: 13269/285440
W/System.err: io.runtime.mcumgr.exception.McuMgrException: io.runtime.mcumgr.ble.callback.TransactionTimeoutException: Transaction 122 timed out without receiving a response
W/System.err:     at io.runtime.mcumgr.ble.McuMgrBleTransport$2.onFailure(McuMgrBleTransport.java:346)
W/System.err:     at io.runtime.mcumgr.ble.callback.SmpProtocolSessionKt.onFailure$lambda-2(SmpProtocolSession.kt:154)
W/System.err:     at io.runtime.mcumgr.ble.callback.SmpProtocolSessionKt.$r8$lambda$7L6qCCwSP_thKdWCrsPHc5-FQUM(Unknown Source:0)
W/System.err:     at io.runtime.mcumgr.ble.callback.SmpProtocolSessionKt$$ExternalSyntheticLambda0.run(Unknown Source:4)
W/System.err:     at android.os.Handler.handleCallback(Handler.java:938)
W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:99)
W/System.err:     at android.os.Looper.loop(Looper.java:223)
W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:7700)
W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:612)
W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:997)
W/System.err: Caused by: io.runtime.mcumgr.ble.callback.TransactionTimeoutException: Transaction 122 timed out without receiving a response
W/System.err:     at io.runtime.mcumgr.ble.callback.SmpProtocolSession$writer$2$1.invokeSuspend(SmpProtocolSession.kt:102)
W/System.err:     at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
W/System.err:     at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
W/System.err:     at kotlinx.coroutines.scheduling.CoroutineScheduler.runSafely(CoroutineScheduler.kt:571)
W/System.err:     at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.executeTask(CoroutineScheduler.kt:750)
W/System.err:     at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.runWorker(CoroutineScheduler.kt:678)
W/System.err:     at kotlinx.coroutines.scheduling.CoroutineScheduler$Worker.run(CoroutineScheduler.kt:665)

Its working with the sample. What will cause this Exception?

Migration to Kotlin BLE library

Hi, I just wanted to ask if there are any plans regarding migration to Kotlin BLE library. As I understand it, as long as I am using managers from this library, I am locked to using McuMgrBleTransport and the old Android BLE library, is that correct?

Of course I could use both libraries at the same time, but that kind of defeats the purpose of migrating and makes things a lot more complicated.

Looking forward to hear about next steps.

Firmware upgrade not working on Android 13 devices

We've tested using SDK v1.3.1 (which did not included Android 13 support) as well as SDK v1.5.2 (which is supposed to support Android 13). In both cases we're unable to perform OTA for our devices that use Nordic's nRF52 chips.

We've tested using a diversity of Android phones ranging from Samsung's S21 to Google Pixel phones using Android 13.

The OTA does work correctly on Android 12 or lower phones.

Also, we've tested using Nordic's Device Manager app v1.5.2 and we're seeing the same results.

We would love to know if you're aware of these issues and if you have any workaround available that we may use since we have these devices in production and we'll start facing these issues even more often as more users upgrade to Android 13.

Pause() and Resume() image upload from different devices

Hello, I am using Mcumgr for DFU on nRF52832DK.
I wanted to implement robust DFU, so that if the connection is suddenly terminated during a session with one device, it can be resumed on the consequent connection from another device.

The README file says pause() and resume() is supported only for window capacity set to 1.
However, while testing I noticed that if bonding information is stored, the upload can be resumed on reconnection with the same device even when window capacity set higher(3).

Is this feature also supported for pausing image upload from one and resume from another device?

Upgrade mode "NONE" with no reset

On the firmware side, MCUmgr supports DFU callbacks. Specifically, there's an event called MGMT_EVT_OP_IMG_MGMT_DFU_PENDING which occurs when an image finished being transferred.

I haven't used this library yet, but for the "NONE" firmware upgrade mode, the README.md states that:

The process for this mode is UPLOAD, RESET.

What if I want to use MGMT_EVT_OP_IMG_MGMT_DFU_PENDING to perform some post-upload work and handle test / confirm on the firmware side? I would not want to reset right after upload.

Should there be a NONE_NO_RESET upgrade mode?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.