DFU OTA suddenly fails on "non secure" bootloaders but works on "secure" bootloaders.

Suddenly DFU OTA fails most of the time while trying to update units with code & "not secure" bootloader that has been working for years. The FW upload stops at 2% to 8% but if i restart my phone sometimes it reaches 15% and on happy days I can update the unit after rebooting the phone.

With the same DFU app DFU update works well with another unit with "secure" bootloader.

I am NOT trying to update a unit with "not secure" bootloader with code made for units with "secure bootloader" and vice versa.

What can suddenly be the problem?

Phone: Samsung Galaxy S21 Ultra 5G

Android version: 14

DFU app version: 2.9.0 (build 24123065)

Parents
  • Exact the same result with a Galaxy Tab A, model SM-T550 with Android 6.0.1, DFU app version: 2.9.0 (build 24123065)

  • Hi again.

    The problem has also been encounteed by our customers who can no longer update our products.

    - The "legacy" DFU bootloader has been the same and working in our product for several years, the DFu bootloader can't be the   problem.

    - The same "Update file" that has been working for years can't no longer be sent to the "product". The "Update file" can't be the problem.

    Devices with secure DFU bootloaders can be updated without problem.

    Devices with legacy DFU bootloaders can't be updated.

    I have found on Internet 2 possible reasons to this problem and they are:

    1. MTU Size Mismatch: DFU libraries, such as the Nordic DFU Library, often default to setting the Maximum Transmission Unit (MTU) size to 247 bytes. However, legacy bootloaders typically support a smaller MTU size of 23 bytes. This discrepancy can lead to upload failures, where the DFU process stalls or does not complete successfully. A user reported that reducing the MTU size to 23 bytes resolved the issue in their case. GitHub
    1. Secure DFU Service Blocking: Some platforms, like Google's Web Bluetooth API, have blacklisted the UUID associated with Nordic's legacy DFU service due to its lack of security features. This blacklist prevents web applications from utilizing this DFU method, leading developers to seek alternative solutions, such as implementing the Secure DFU Service or using different bootloader configurations. RAKwireless Forum

    Can you please help me find a solution to our problem?

     

  • Yes, you are correct. I have tried to DFu as I have always done before using nRF DFU and recently collecting logs in nRF Connect.

    Now I have got a log using nRF Connect, it still fails but perhaps gives more info then before.

    Log file below

    nRF Connect, 2025-04-02
    Dfu_V2.0 (F5:9A:55:96:A5:6B)
    V 11:22:16.411 Connecting to F5:9A:55:96:A5:6B...
    D 11:22:16.411 gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, preferred PHY = LE 1M)
    D 11:22:16.675 [Callback] Connection state changed with status: 0 and new state: CONNECTED (2)
    I 11:22:16.675 Connected to F5:9A:55:96:A5:6B
    V 11:22:16.687 Discovering services...
    D 11:22:16.687 gatt.discoverServices()
    D 11:22:16.893 [Broadcast] Action received: android.bluetooth.device.action.ACL_CONNECTED
    I 11:22:17.181 Connection parameters updated (interval: 30.0ms, latency: 0, timeout: 4000ms)
    I 11:22:17.430 Connection parameters updated (interval: 7.5ms, latency: 0, timeout: 5000ms)
    D 11:22:17.573 [Callback] Services discovered with status: 0
    I 11:22:17.573 Services discovered
    V 11:22:17.580 Generic Access (0x1800)
    - Device Name [R W] (0x2A00)
    - Appearance [R] (0x2A01)
    - Peripheral Preferred Connection Parameters [R] (0x2A04)
    Generic Attribute (0x1801)
    - Service Changed [I] (0x2A05)
       Client Characteristic Configuration (0x2902)
    Device Firmware Update Service (00001530-1212-efde-1523-785feabcd123)
    - DFU Packet [WNR] (00001532-1212-efde-1523-785feabcd123)
    - DFU Control Point [N W] (00001531-1212-efde-1523-785feabcd123)
       Client Characteristic Configuration (0x2902)
    - DFU Version [R] (00001534-1212-efde-1523-785feabcd123)
    D 11:22:17.581 gatt.setCharacteristicNotification(00002a05-0000-1000-8000-00805f9b34fb, true)
    I 11:22:17.646 Connection parameters updated (interval: 30.0ms, latency: 0, timeout: 4000ms)
    I 11:22:18.167 Connection parameters updated (interval: 30.0ms, latency: 0, timeout: 4000ms)
    V 11:22:29.130 [DFU] DFU service started
    V 11:22:29.130 [DFU] Opening file...
    I 11:22:29.141 [DFU] Firmware file opened successfully
    V 11:22:29.141 [DFU] Connecting to DFU target...
    D 11:22:29.141 [DFU] gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, preferredPhy = LE_1M | LE_2M)
    I 11:22:29.154 [DFU] Connected to F5:9A:55:96:A5:6B
    V 11:22:29.154 [DFU] Discovering services...
    D 11:22:29.154 [DFU] gatt.discoverServices()
    I 11:22:29.156 [DFU] Services discovered
    V 11:22:29.181 [DFU] Reading DFU version number...
    D 11:22:29.181 [DFU] gatt.readCharacteristic(00001534-1212-efde-1523-785feabcd123)
    I 11:22:29.234 [DFU] Read Response received from 00001534-1212-efde-1523-785feabcd123, value (0x): 08-00
    A 11:22:29.234 [DFU] Version number read: 0.8
    V 11:22:29.234 [DFU] Requesting new MTU...
    D 11:22:29.234 [DFU] gatt.requestMtu(517)
    I 11:22:29.295 [DFU] MTU changed to: 23
    V 11:22:29.295 [DFU] Enabling notifications for 00001531-1212-efde-1523-785feabcd123
    D 11:22:29.295 [DFU] gatt.setCharacteristicNotification(00001531-1212-efde-1523-785feabcd123, true)
    D 11:22:29.295 [DFU] gatt.writeDescriptor(00002902-0000-1000-8000-00805f9b34fb, value=0x01-00)
    I 11:22:29.354 [DFU] Data written to descr.00001531-1212-efde-1523-785feabcd123
    V 11:22:29.354 [DFU] Notifications enabled for 00001531-1212-efde-1523-785feabcd123
    A 11:22:29.354 [DFU] Notifications enabled
    V 11:22:29.354 [DFU] Writing to characteristic 00001531-1212-efde-1523-785feabcd123, value (0x): 01-04
    D 11:22:29.354 [DFU] gatt.writeCharacteristic(00001531-1212-efde-1523-785feabcd123, value=0x01-04, WRITE_TYPE_DEFAULT)
    I 11:22:29.414 [DFU] Data written to 00001531-1212-efde-1523-785feabcd123
    A 11:22:29.414 [DFU] DFU Start sent (Op Code = 1, Upload Mode = 4)
    V 11:22:29.414 [DFU] Writing to characteristic 00001532-1212-efde-1523-785feabcd123, value (0x): 00-00-00-00-00-00-00-00-C0-7F-00-00
    D 11:22:29.414 [DFU] gatt.writeCharacteristic(00001532-1212-efde-1523-785feabcd123, value=00-00-00-00-00-00-00-00-C0-7F-00-00, WRITE_TYPE_NO_RESPONSE)
    I 11:22:29.415 [DFU] Data written to 00001532-1212-efde-1523-785feabcd123
    A 11:22:29.415 [DFU] Firmware image size sent (0b, 0b, 32704b)
    I 11:22:31.065 [DFU] Notification received from 00001531-1212-efde-1523-785feabcd123, value (0x): 10-01-01
    A 11:22:31.066 [DFU] Response received (Op Code = 1 Status = 1)
    V 11:22:31.066 [DFU] Requesting high connection priority...
    D 11:22:31.066 [DFU] gatt.requestConnectionPriority(HIGH)
    A 11:22:31.070 [DFU] Writing Initialize DFU Parameters...
    V 11:22:31.070 [DFU] Writing to characteristic 00001531-1212-efde-1523-785feabcd123, value (0x): 02-00
    D 11:22:31.070 [DFU] gatt.writeCharacteristic(00001531-1212-efde-1523-785feabcd123, value=0x02-00, WRITE_TYPE_DEFAULT)
    I 11:22:31.155 [DFU] Data written to 00001531-1212-efde-1523-785feabcd123
    V 11:22:31.156 [DFU] Writing to characteristic 00001532-1212-efde-1523-785feabcd123 value (0x): FF-FF-FF-FF-FF-FF-FF-FF-01-00-FE-FF-4B-5E
    D 11:22:31.156 [DFU] gatt.writeCharacteristic(00001532-1212-efde-1523-785feabcd123, value=0xFF-FF-FF-FF-FF-FF-FF-FF-01-00-FE-FF-4B-5E, WRITE_TYPE_NO_RESPONSE)
    I 11:22:31.159 [DFU] Data written to 00001532-1212-efde-1523-785feabcd123
    V 11:22:31.159 [DFU] Writing to characteristic 00001531-1212-efde-1523-785feabcd123, value (0x): 02-01
    D 11:22:31.159 [DFU] gatt.writeCharacteristic(00001531-1212-efde-1523-785feabcd123, value=0x02-01, WRITE_TYPE_DEFAULT)
    I 11:22:31.215 [DFU] Data written to 00001531-1212-efde-1523-785feabcd123
    A 11:22:31.215 [DFU] Initialize DFU Parameters completed
    I 11:22:31.215 [DFU] Notification received from 00001531-1212-efde-1523-785feabcd123, value (0x): 10-02-01
    A 11:22:31.215 [DFU] Response received (Op Code = 2, Status = 1)
    V 11:22:31.215 [DFU] Writing to characteristic 00001531-1212-efde-1523-785feabcd123, value (0x): 03
    D 11:22:31.215 [DFU] gatt.writeCharacteristic(00001531-1212-efde-1523-785feabcd123, value=0x03, WRITE_TYPE_DEFAULT)
    I 11:22:31.274 [DFU] Data written to 00001531-1212-efde-1523-785feabcd123
    A 11:22:31.275 [DFU] Receive Firmware Image request sent
    A 11:22:31.290 [DFU] Uploading firmware...
    V 11:22:31.290 [DFU] Sending firmware to characteristic 00001532-1212-efde-1523-785feabcd123...
    I 11:22:31.318 Connection parameters updated (interval: 15.0ms, latency: 0, timeout: 5000ms)
    I 11:22:31.363 [DFU] Notification received from 00001531-1212-efde-1523-785feabcd123, value (0x): 10-03-06
    I 11:22:31.363 [DFU] Data written to 00001532-1212-efde-1523-785feabcd123
    A 11:22:31.363 [DFU] Response received (Op Code = 3, Status = 6)
    E 11:22:31.364 [DFU] Remote DFU error: OPERATION FAILED
    V 11:22:31.364 [DFU] Writing to characteristic 00001531-1212-efde-1523-785feabcd123, value (0x): 06
    D 11:22:31.364 [DFU] gatt.writeCharacteristic(00001531-1212-efde-1523-785feabcd123, value=0x06, WRITE_TYPE_DEFAULT)
    D 11:22:36.452 [Callback] Connection state changed with status: 8 and new state: DISCONNECTED (0)
    E 11:22:36.453 Error 8 (0x8): GATT CONN TIMEOUT
    I 11:22:36.453 Disconnected
    A 11:22:36.461 [DFU] Reset request sent
    D 11:22:36.461 [DFU] gatt.refresh() (hidden)
    D 11:22:36.461 [DFU] gatt.disconnect()
    D 11:22:36.464 [DFU] gatt.close()
    D 11:22:36.468 [DFU] wait(600)
    D 11:22:36.500 [Broadcast] Action received: android.bluetooth.device.action.ACL_DISCONNECTED
    D 11:22:36.501 [DFU] [Broadcast] Action received: android.bluetooth.device.action.ACL_DISCONNECTED
    D 11:22:37.071 gatt.close()
    D 11:22:37.074 wait(200)
    V 11:22:37.274 Connecting to F5:9A:55:96:A5:6B...
    D 11:22:37.274 gatt = device.connectGatt(autoConnect = false, TRANSPORT_LE, preferred PHY = LE 1M)
    D 11:22:47.290 [Callback] Connection state changed with status: 133 and new state: DISCONNECTED (0)
    E 11:22:47.290 Error 133 (0x85): GATT ERROR
    I 11:22:47.290 Disconnected

  • Thank you, this is great. As you may see, the device responds with error 6:

    A 11:22:31.363 [DFU] Response received (Op Code = 3, Status = 6)
    E 11:22:31.364 [DFU] Remote DFU error: OPERATION FAILED

    This error is usually sent when the firmware is unable to store data as fast as they are transfered.

    At that moment the device hangs, or disconnects and the phone awaits for supervision timeout (5 seconds) before realizing that the connection was terminated, hence the timeout error.

    My recommendation is to enable Package Receipt Notifications and set the value to 6. This should work, as this will ensure that the phone will wait until 6 packets are stored before sending more. If you'll get the same error with 6 try lower value down to 1, meaning there will be a sPRN nortification coming after each 20 bytes sent.

    You may enable PRNs in nRF Connect in Settings -> nRF5 DFU options. Set the "Packet receipt notifications procedure" to ON and set the value in the field below. You may also set the same in nRF DFU app in Settings.

  • Ha!

    Thank you so very much!!!!!!!!

    Setting Package Receipt Notifications to 6 makes DFU work both with "nRF Connect DFU" and "nRF DFU"

    You have lifted a very weight from my shoulders, i just wonder why Nordic themselves didn't come up with this solution.

    Once again a GREAT BIG thank you!

  • There is a lot of factors that affect the upload speed, including the phone hardware and device capabilities. Modern phones are able to send a lot of packets in a single connection interval, exceeding the flash speed. Older phones didn't have this problem. In theory, it is the device that should control the flow, as it able to ignore writes that it cannot handle and simply not reply to them (on link layer).

    Instead, we try to calibrate it from the app side not knowing any of that.

    Also, we do have some logic here: https://github.com/NordicSemiconductor/Android-DFU-Library/blob/b0d73c655ea336b3cce0265614aac4d7d082e66f/lib/dfu/src/main/java/no/nordicsemi/android/dfu/LegacyDfuImpl.java#L503 that is trying to set PRN to 6, but only to decrease the value if it was set to >10. Also, room for improvement.

  • Great to hear that it works now. Thanks for the update. Regarding the packet receipt notification, this was suggested earlier. Also,   is a developer and maintainer of the DFU library.

    Anyway, please install the nRF DFU app and and in the app settings, set the PRN (packet receipt notification) to 1.
Reply Children
Related