BLE Mesh DFU Recovery Question(NCS v2.7.0)

Hello,

I have a question regarding the internal handling of the update recovery process for BLE mesh DFU, specifically within the DFU Server model + BLOB Server model.

I know there's support for a target to recover if it gets rebooted in the middle of an update, and that on the user's end, the transfer recovery callback must be defined and must provide a valid BLOB stream for the server model. But is the write address for the next received chunk automatically stored and restored with the rest of the transfer state so that, upon reboot + recovery, the transfer process can automatically resume at the correct starting location? Or is this something that I'll need to manage in my application? I tried to work it out by looking through the source code and saw that both the DFU Server and the BLOB Server models use their own "store_state" function regularly throughout the transfer process, but it's not immediately clear to me if the write address is part of the stored state.

I ask because I'm providing the BLOB stream in the transfer recovery callback using bt_mesh_blob_io_flash_init(), which takes a parameter representing the "offset into the flash area, in bytes". But after a reboot, I don't have direct access to this offset.

Please let me know if any additional information is needed! Thank you!

Parents
  • Hi Amira,

    I am going to help you with this case, but I am unfamiliar with the BLOB models and its implementation, so I will need some time to read up the specification and source code.
    I should be back in 2 working days unless someone else in the community already answered you then.

    Hieu

  • Hi Hieu,

    Thank you for geting back to me and letting me know! I'll keep an eye out for your response.

  • Hi Amira,

    Referring to the implementation in blob_io_flash.c, the write address is calculated from the current block and chunk data.

    While the chunk data isn't a part of the BLOB Server data structure, the block data is. Therefore, information about blocks received is stored with the store_state() function.

    So, we can conclude that the flash write address of the next block, not chunk, is stored regularly and can be recovered from power loss.

  • Hi Hieu,

    Apologies for the late response, I was out sick this past week. Thank you for getting back to me with an answer! That leads me to believe that all necessary state tracking is handled internally, but in the event of DFU recovery, is it sufficient to provide a BLOB flash stream initialized with no offset?

  • Hi Amira,

    No problem at all. I hope you are well now.

    Amira R. said:
    but in the event of DFU recovery, is it sufficient to provide a BLOB flash stream initialized with no offset?

    We examined the current implementation closely, and the answer is a slightly complicated "yes and no."

    Resume will work just fine without any special initialization if block size is left to the default 4096.
    Leaving CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MIN and CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MAX at their default values will achieve this. 

    If the block size is not a multiple of the page size, suspend-resume will not work when the transfer gets suspended and the transfer will be aborted instead. It can be workaround by some slightly complex application implementation, but we can't recommend this.

    Meanwhile, with block sizes larger than 4096, more chunks will have to be resent when the transfer is suspended and resumed.

    Thus, keeping the default block size of 4096 is strongly recommended.

    We will improve the feature so that it is more convenient to work with any sizes of blocks, but we cannot comment on the timeline on DevZone. 

    Our apology for the inconvenience.

Reply
  • Hi Amira,

    No problem at all. I hope you are well now.

    Amira R. said:
    but in the event of DFU recovery, is it sufficient to provide a BLOB flash stream initialized with no offset?

    We examined the current implementation closely, and the answer is a slightly complicated "yes and no."

    Resume will work just fine without any special initialization if block size is left to the default 4096.
    Leaving CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MIN and CONFIG_BT_MESH_BLOB_BLOCK_SIZE_MAX at their default values will achieve this. 

    If the block size is not a multiple of the page size, suspend-resume will not work when the transfer gets suspended and the transfer will be aborted instead. It can be workaround by some slightly complex application implementation, but we can't recommend this.

    Meanwhile, with block sizes larger than 4096, more chunks will have to be resent when the transfer is suspended and resumed.

    Thus, keeping the default block size of 4096 is strongly recommended.

    We will improve the feature so that it is more convenient to work with any sizes of blocks, but we cannot comment on the timeline on DevZone. 

    Our apology for the inconvenience.

Children
No Data
Related