This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

DFU example for NRF_DFU_OP_FIRMWARE_VERSION

Is there any code example for Android or iOS on how to build / send a DFU request for NRF_DFU_OP_FIRMWARE_VERSION and then how to interpret the response that comes back?

Does it not make sense for the DFU module from inside the nRF Toolbox to also have a way to send this request to a device in DFU mode for instance to check the existing values that are programmed in the device? (and then show a popup to the user for instance to let him know if he needs to update things)?

Parents
  • Hi,

    We don't have any code for that. It's up to the application's implementation to know the version, a suggestion is to have a sw version and hw version string in the proper charecteristic.

  • I really think Nordic should provide at least some support for these DFU requests.

    Having the application report the versions is fine as long as the application is working properly. But consider failure scenarios. What if I make a huge mistake and release a buggy application that makes the characteristics inaccessible? The bootloader can still be launched, but how does the iOS/Android DFU library now know what hardware it is talking to? (I have one phone app for several HW variants).

    I am considering adding the HW version as manufacturer specific data to the advertising packets sent by the bootloader. But it would be simpler to just ask for the information since the commands seem to be already defined.

  • Hi @Catalin, @mrono,

    Both Legacy (since SDK 7.1) and Secure DFU provide a security check to prevent wrong firmware to be flashed on your device. In the init packet there is hardware identifier. IDs of required softdevice(s).

    Secure DFU and late Legacy DFU (optinally) prevent also from flashing modified fw by checking the hash and signature (although Legacy DFU does it incorrectly and device still can be bricked, even having a valid fw file).

    The following requests:

    NRF_DFU_OP_MTU_GET              = 0x07,     //!< Retrieve MTU size.
    NRF_DFU_OP_OBJECT_WRITE         = 0x08,     //!< Write selected object.
    NRF_DFU_OP_PING                 = 0x09,     //!< Ping.
    NRF_DFU_OP_HARDWARE_VERSION     = 0x0A,     //!< Retrieve hardware version.
    NRF_DFU_OP_FIRMWARE_VERSION     = 0x0B,     //!< Retrieve firmware version.
    NRF_DFU_OP_ABORT                = 0x0C

    were added to the DFU for the sake of the new nRF52840 Dongle, which uses DFU to flash firmware. On BLE such requests should either return the requested value, or return NOT SUPPORTED status code.

    However, as I tested it out, the bootloader replies with 0x60-[Command ID]-01 (success), but the value is empty. According to me it's a bug and I reported it to the SDK team. I don't know which way they decide to go.

  • However, as I tested it out

    So how did you do that? The original question by Catalin, as well as my followup question was precisely on how to send those requests and how to interpret the response. If you could provide some kind of example on how to issue those requests using the iOS/Android DFU libraries then I could probably work out the rest with our iOS contractor.

    If the bootloader currently doesn't return the requested values then issuing these requests is pointless. I believe could fix this in the bootloader myself, but that creates another compatibility challenge if an official fix is later done. I have already added the HW version and bootloader version as manufacturer specific data to the advertising packet sent by the bootloader, so I have a solution for the time being.

    Since you have reported this to the SDK team, I have an additional related suggestion: According to the DFU protocol spec the response to the NRF_DFU_HARDWARE_VERSION request contains info on the processor variant and memory size, but not the hardware version checked during DFU. Please add this info to the response. Or if the HW version is available somewhere else please tell me where and how.

  • Both Legacy (since SDK 7.1) and Secure DFU provide a security check to prevent wrong firmware to be flashed on your device. In the init packet there is hardware identifier.

    So just to summarize what I'm trying to achieve here:

    I have a single iOS/Android app that is supposed to update the firmware of N different hardware variants. Assume that the existing firmware is non-functional, and I can only communicate with the bootloader. How can I tell which of the N DFU zip packages I should send to the device? Yes, wrong ones will be rejected but do I really need to try to send all of them until one is accepted? I'd like to ask the bootloader this info.

Reply
  • Both Legacy (since SDK 7.1) and Secure DFU provide a security check to prevent wrong firmware to be flashed on your device. In the init packet there is hardware identifier.

    So just to summarize what I'm trying to achieve here:

    I have a single iOS/Android app that is supposed to update the firmware of N different hardware variants. Assume that the existing firmware is non-functional, and I can only communicate with the bootloader. How can I tell which of the N DFU zip packages I should send to the device? Yes, wrong ones will be rejected but do I really need to try to send all of them until one is accepted? I'd like to ask the bootloader this info.

Children
  • To test it I just used nRF Connect. I flashed the DFU buttonless app and DFU service from SDK 15.2 on nRF25832 DK, connected, jumped to bootloader, reconnected to a new device (address has changed), enabled notifications on Secure DFU Control Point and sent 0x07, ... to this characteristic.

    As a result I received 0x60-07-01. The expected value should be 0x60-07-01-BB-AA where AA-BB is the MTU (BB-AA as Little Endian is used).

    The SDK team says that UART and USB DFU samples report those values correctly, only the BLE part does not. You need to modify both the preparation of the request in on_write() and the serialization of the response in ble_dfu_req_handler_callback(). See nrf_dfu_serial.c for reference. I guess @Mmtrinh may help you. After you implement the changes I mentioned above, yoou could request the HW version from the device before starting DFU. DFU Library will not use those features as it assumes that the firmware you try to send is correct and will in worst case handle validation error.

    I forwarded the issue you mention to the SDK team. The response I got:

    It makes sense. We probably won't change it though, but they are free to add it themselves, or to consolidate the HW version with some value reported by this command.

  • Thank you for the instructions. It is so simple I should have figured that out. But I was too focused on trying to use the DFU library for this...

    I could implement those changes myself but I don't think I will. I fear that I might make them slightly different than the official fix I presume will be done for some future SDK. And slight compatibility issues are the worst kind. Obvious ones are much easier to work with. I have a solution that works (add the values to the advertising packet), so I'll keep using that and re-evaluate this issue if there is an SDK that has those fixes.

  • There is indeed a bug in the BLE transport code in the library, most of the codes that are correctly handled in \Nordic152\components\libraries\bootloader\serial_dfu\nrf_dfu_serial.c are not handled at all under \Nordic152\components\libraries\bootloader\ble_dfu\nrf_dfu_ble.c , making the bootloader library buggy and incomplete at this point Disappointed

    What is even worse is that any bootloader already programmed in any device will need first to be updated to support the correct and full specification for the version of protocol that the library was supposed to implement Disappointed Disappointed

  • Hi, the issue with BLE bootloader reporting 0x60-[Command ID]-01 (success) instead of a value or NOT SUPPORTED has been fixed in SDK 15.3.

Related