DFU over Bluetooth Mesh
The DFU specification is implemented in the Zephyr Bluetooth Mesh DFU subsystem as three separate models:
For more information about the Zephyr Bluetooth Mesh DFU subsystem, see Device Firmware Update (DFU).
The Bluetooth Mesh subsystem in nRF Connect SDK provides a set of samples that you can use for evaluation of the Bluetooth Mesh DFU specification and subsystem:
To configure and control DFU on the Firmware Distribution Server, use either the Firmware Distribution Client model or the shell commands.
You can use either the nRF Mesh mobile app or the shell commands to configure and control the DFU process.
Note
The Mesh DFU feature in the nRF Mesh mobile app is currently supported only on iOS.
DFU roles and image transport
The Bluetooth Mesh DFU Model specification defines four DFU roles:
Target - A node that receives a firmware image and applies it. A Target instantiates the Firmware Update Server and BLOB Transfer Server models.
Initiator - An entity that selects the firmware image to distribute and drives the distribution on the Distributor. An Initiator instantiates the Firmware Distribution Client, Firmware Update Client and BLOB Transfer Client models.
Distributor - An intermediary node that stores the firmware image and delivers it to the Target nodes over the mesh network. A Distributor instantiates the Firmware Distribution Server, Firmware Update Client, BLOB Transfer Client and BLOB Transfer Server models.
Standalone Updater - An entity that delivers firmware images to Target nodes directly, without an intermediary Distributor.
Roles of the nRF Mesh mobile app
When used with the samples provided by the nRF Connect SDK, the nRF Mesh mobile app has the following roles:
Provisioner and Configuration Client, used to provision the devices and to bind the application key to the mesh models involved in the DFU procedure.
Initiator, used to select the firmware image, register it on the Distributor, and start the distribution to the Target nodes.
The mobile app is not a Distributor or a Standalone Updater. The Bluetooth Mesh: Device Firmware Update (DFU) distributor sample (or an equivalent device on the mesh network) always has the intermediary Distributor role.
How the firmware image reaches the Distributor
The Bluetooth Mesh DFU Model specification defines two Upload Types on the Firmware Distribution Server:
In-band upload - The Initiator pushes the firmware image to the Distributor over the mesh network using the BLOB Transfer models.
Out-of-band upload - The firmware image reaches the Distributor through a channel outside the mesh network.
For out-of-band upload, the specification describes one concrete mechanism, the Store Firmware OOB procedure on the Firmware Distribution Server, driven by an Upload Firmware OOB procedure on a Firmware Distribution Client. This procedure carries an Upload OOB URI that the Distributor uses to retrieve (pull) the image itself, for example over HTTPS.
The nRF Connect SDK supports a different out-of-band mechanism in the Bluetooth Mesh: Device Firmware Update (DFU) distributor sample. The nRF Mesh mobile app uploads (pushes) the image to the Distributor’s storage slot over the Simple Management Protocol (SMP) provided by the MCUmgr (mcumgr Image Management over a GATT connection), then registers the resulting firmware in a DFU slot and starts the distribution using the Firmware Distribution Client model. Unlike the Store Firmware OOB procedure described in the specification, the SMP-based upload is not driven through the Firmware Distribution Server’s Upload procedures, so it does not update the server’s Upload Type or Upload Phase states. From the Firmware Distribution Server’s point of view, the subsequent distribution to the Target nodes runs identically to a distribution triggered after a spec-defined upload.
For alternatives (in-band BLOB Transfer upload from another Initiator, or out-of-band SMP upload driven from a workstation), see Alternative ways of uploading a firmware image in the Bluetooth Mesh: Device Firmware Update (DFU) distributor sample documentation.
The transfer from the Distributor to the Target nodes always uses in-band BLOB Transfer over the mesh network, regardless of how the image was loaded onto the Distributor.
Connecting to the Distributor
The nRF Mesh app for iOS provides a built-in Firmware Distribution Client model to configure and control the DFU process on the distributor node.
To connect to the distributor node:
Launch the nRF Mesh app for iOS and navigate to the Proxy screen.
If the Proxy section does not show Mesh DFU Distributor, disable Automatic Connection, tap the Proxy name, and choose the distributor node from the list.
Proxy screen with distributor node connection and proxy filter
The Bluetooth Mesh DFU subsystem in Zephyr provides a set of shell commands that you can use instead of the client. For a complete list of commands, see the Firmware Distribution Server model section of the Bluetooth Mesh shell documentation.
You can execute the commands in the following two ways:
Through the shell management subsystem of MCU manager (for example, using an MCU manager-capable mobile app, such as nRF Connect Device Manager application for Android, or Mcumgr command-line tool).
Using the Shell module over UART.
Provisioning and configuring the devices
After programming the samples onto the boards, they need to be provisioned into the same Bluetooth Mesh network with an external provisioner device. See the documentation for provisioning the mesh DFU target device and provisioning the mesh DFU distributor device for how this is done.
After the provisioning has completed, a Configuration Client needs to add a common application key to all devices. The added application key must be bound:
On the Distributor - To the Firmware Distribution Server, Firmware Update Client, BLOB Transfer Server and BLOB Transfer Client models instantiated on the primary element, and to the Firmware Update Server and BLOB Transfer Server models instantiated on the secondary element of the device (see Configuring models on the Distributor node).
On Target nodes - To the Firmware Update Server and BLOB Transfer Server models instantiated on the primary element of the device (see Configuring models on the Target node).
The bound application key will be used in the firmware distribution procedure.
Uploading the firmware
Note
When using the nRF Mesh mobile app for iOS for DFU, bind the application key to the Firmware Distribution Server model on the distributor node. The app binds the application key to the Firmware Update Server models on the Target nodes automatically.
To upload the firmware:
Navigate to the Network screen and tap the Update button in the top right corner.
Network screen with mesh nodes and Update button
On the Firmware Distribution screen, review the distributor node information, the current state of the Firmware Distribution Server model, and the Capabilities section.
Firmware Distributor screen showing details of the Firmware Distributor Server model
Firmware Distributor with firmware image slot empty and available
Tap Next in the top right corner of the Firmware Distribution screen to open the Target Nodes screen.
Tap Select File and select the zip archive intended for distribution. Verify the firmware details shown by the app.
After configuring the models, you can upload a new image to the Distributor. To upload the image, follow the instructions provided in the Alternative ways of uploading a firmware image section of the Bluetooth Mesh: Device Firmware Update (DFU) distributor sample documentation.
The uploaded image needs to be registered in the Bluetooth Mesh DFU subsystem.
Use the mesh models dfu slot add shell command specifying the size of the image (in bytes) that was uploaded to the Distributor.
Optionally, you can provide the firmware ID, metadata and Unique Resource Identifier (URI) parameters that come with the image.
For example, to allocate a slot for the Bluetooth Mesh: Device Firmware Update (DFU) target sample with image size of 241236 bytes, with firmware ID set to 0200000000000000, and metadata generated as described in Generating the firmware metadata section below, use the following command:
mesh models dfu slot add 241236 0200000000000000 020000000000000094cf24017c26f3710100
When the slot is added, the shell will print the slot ID. Take note of this ID as it will be needed to start the DFU transfer:
Adding slot (size: 241236)
Slot added. ID: 0
Note
To update any value in a slot, use the mesh models dfu slot del command specifying the ID of the allocated slot, and then add the slot again.
Populating the Distributor’s receivers list
To add Target nodes to the receivers list:
Scroll down to the AVAILABLE TARGET NODES section.
Select the nodes to update, or tap Select All to select all nodes.
Tap Next in the top right corner of the screen to open the Firmware Distribution screen.
Target Nodes screen with firmware details and available target nodes to select
Add the Target nodes to the DFU transfer using the mesh models dfd receivers-add shell command.
This command specifies the element address of a Target node with the Firmware Update Server instance and the image index on the Target node that needs to be updated.
For example, for two Target nodes with addresses 0x0004 and 0x0005 respectively, and with image index 0, the command looks like this:
mesh models dfd receivers-add 0x0004,0;0x0005,0
Note
To remove all receivers from the list, use the mesh models dfd receivers-delete-all command.
Initiating the distribution
To initialize the distribution:
Set the transfer TTL, Timeout, Transfer Mode, and Update Policy (you may leave default values as is).
To transfer the firmware to several Target nodes simultaneously, select the desired group address under the Multicast Distribution section.
Firmware Distribution screen with transfer parameters and multicast options
To start the DFU transfer, use the mesh models dfd start shell command.
This command requires two mandatory arguments, app_idx and slot_idx:
For
app_idx, use the application key index that is bound to the Firmware Distribution Server and other Firmware Update and BLOB Transfer models on the Distributor and Target nodes.For
slot_idx, use the ID of the slot allocated by themesh models dfu slot addshell command.
For example, to run the DFU transfer in unicast mode, with AppKey index 0 and slot ID 0, use the following command:
mesh models dfd start 0 0
By default, the Firmware Distribution Server will request the Firmware Update Servers to apply the image immediately after the DFU transfer.
To avoid applying the image immediately and only verify it, set the fourth argument to 0:
mesh models dfd start 0 0 0 0
Note
After a successful firmware distribution, set the Firmware Distribution Server to idle state using the mesh models dfd cancel shell command to initiate a new firmware distribution.
Firmware distribution
To start the distribution:
After setting the Firmware Distribution parameters and multicast options, tap Next in the top right corner of the screen. The app binds the necessary keys and subscribes the target nodes to the group address.
When configuration is complete, tap Next again. The app uploads the firmware image to the distributor node over SMP (Firmware Upload; typically a couple of minutes), then instructs the distributor to start the Firmware Distribution process.
Firmware Update screen while uploading image to the distributor
Once the distribution process starts, the screen continues to show the distribution progress and remaining time.
Firmware Update screen during distribution to target nodes
To exit the Firmware Update screen without canceling the distribution, tap the Close button in the top right corner of the screen (the distribution process continues in the background). The mobile device may be disconnected; the distributor node continues the Firmware Distribution process in the background. To get back to the ongoing distribution process, navigate to the Network screen and tap the Update button in the top right corner. To cancel the distribution process, tap the X button in the top left corner.
The transfer will take a couple of minutes, depending on the number of Target nodes and the network quality.
To check the transfer progress, use the mesh models dfd receivers-get shell command, for example:
mesh models dfd receivers-get 0 2
The output might look like this:
{
"target_cnt": 1,
"targets": {
"0": { "blob_addr": 0x0004, "phase": 2, "status": 0, "blob_status": 0, "progress": 50, "img_idx": 0 }
"1": { "blob_addr": 0x0005, "phase": 2, "status": 0, "blob_status": 0, "progress": 50, "img_idx": 0 }
}
}
To see the distribution status, phase and parameters of the DFU transfer, use the mesh models dfd get command.
When the DFU transfer successfully completes, the phase will be set to BT_MESH_DFD_PHASE_TRANSFER_SUCCESS, for example:
{ "status": 0, "phase": 2, "group": 0x0000, "app_idx": 0, "ttl": 255, "timeout_base": 0, "xfer_mode": 1, "apply": 0, "slot_idx": 0 }
The bt_mesh_dfd_phase enumeration contains the complete list of distribution phases.
Suspending the distribution
To suspend the distribution:
Navigate to the Network screen.
Tap the Mesh DFU Distributor node.
Navigate to the element list and tap Element 1, then Firmware Distribution Server.
On the Firmware Distribution Server screen, scroll to the Control section and tap Get to obtain the current state.
Tap the Suspend button.
Firmware Distribution Server screen with status, phase, and control actions
To suspend the firmware distribution, use the mesh models dfd suspend shell command.
The distribution phase is switched to BT_MESH_DFD_PHASE_TRANSFER_SUSPENDED in this case.
To resume the DFU transfer after suspending, use the mesh models dfu cli resume shell command.
Applying the firmware image
Depending on the update policy set at the start of the DFU transfer, the Firmware Distribution Server will do the following:
If
policy_applyis set to true or omitted when the DFU transfer starts, the Firmware Distribution Server will immediately apply the new firmware on the Target nodes upon the DFU transfer completion.If
policy_applyis set to false, the image needs to be applied manually.
When the update policy was set to Verify Only, the target nodes wait for an apply message after the distribution completes. To apply the firmware:
Navigate to the Network screen.
Tap the Mesh DFU Distributor node.
Navigate to the element list and tap Element 1, then Firmware Distribution Server.
On the Firmware Distribution Server screen, scroll to the Control section and tap Get to obtain the current state.
Tap the Apply button.
Firmware Distribution Server screen with status, phase, and control actions
If the update policy was set to Verify Only, use the mesh models dfd apply command to apply the image manually after the DFU transfer is completed.
When the Firmware Distribution Server starts applying the transferred image, the distribution phase is set to BT_MESH_DFD_PHASE_APPLYING_UPDATE.
After applying the new firmware, the Firmware Distribution Server will immediately request firmware ID of the currently running firmware on the Target nodes to confirm that the new firmware has been applied successfully.
Depending on the bt_mesh_dfu_effect value received from the Target nodes after the DFU transfer is started, the following cases are possible:
If the image effect for a particular Target node is
BT_MESH_DFU_EFFECT_UNPROV, the Firmware Distribution Server does not expect any reply from that Target node. If the Distributor does not receive any reply, it will repeat the request several times. If the Distributor eventually receives a reply, the DFU for this particular Target node is considered unsuccessful. Otherwise, the DFU is considered successful.In all other cases, the Distributor expects a reply from the Target node with the firmware ID equal to the firmware ID of the transferred image. If the Target node responds with a different firmware ID or does not respond at all after several requests, the DFU for this particular Target node is considered unsuccessful. Otherwise, the DFU is considered successful.
The DFU ends after the Distributor stops polling the Target nodes.
If the DFU completes successfully for at least one Target node, the firmware distribution is considered successful.
In this case, the distribution phase is set to BT_MESH_DFD_PHASE_COMPLETED.
If the DFU does not complete successfully, the distribution phase is set to BT_MESH_DFD_PHASE_FAILED.
Cancelling the distribution
To cancel the distribution:
Navigate to the Network screen.
Tap the Mesh DFU Distributor node.
Navigate to the element list and tap Element 1, then Firmware Distribution Server.
On the Firmware Distribution Server screen, scroll to the Control section and tap Get to obtain the current state.
Tap the Cancel button.
Alternatively, tap the Update button on the Network screen to open the Firmware Distribution flow, then tap the X button in the top left corner of the Firmware Update screen.
To cancel the firmware distribution, use the mesh models dfd cancel shell command.
You can cancel the firmware distribution on a specific Target node at any time by sending a Firmware Update Cancel message.
Use the mesh models dfu cli cancel shell command specifying the unicast address of the Target node.
Recovering from failed distribution
To recover from a failed distribution, clear the distribution phase and optionally clear the firmware slots so that a new distribution can be started.
To clear the distribution phase and reset the Firmware Distribution Server state, follow the steps in Cancelling the distribution.
To clear the list of firmware slots (for example, to remove slot data from the failed distribution before retrying):
Navigate to the Network screen.
Tap the Mesh DFU Distributor node.
Navigate to the element list, tap Element 1, tap Firmware Distribution Server, and scroll to the Firmware Distribution Slots section.
Tap Get to obtain the current list of firmware slots.
To remove a slot: swipe left on the slot and tap Delete or to remove all slots: tap Delete All.
Then start the distribution process again from the beginning.
If the firmware distribution fails, clear the list of Target nodes and set the distribution phase to BT_MESH_DFD_PHASE_IDLE before making a new attempt.
Use the following shell commands:
mesh models dfd receivers-delete-all
mesh models dfd cancel
To bring a stalled Target node to idle state, use the mesh models dfu cli cancel shell command.
Note
This does not affect the allocated image slots.
Generating the firmware metadata
Note
When using the nRF Mesh app for DFU, the app obtains all required information from the firmware archive generated as part of the build process.
There are two ways to generate the required DFU metadata:
Automated generation using the DFU metadata extraction script integrated in the nRF Connect SDK build system.
Manual generation by using shell commands.
Using the DFU metadata extraction script is the most efficient way of generating the required DFU metadata.
Automated metadata generation
By enabling the SB_CONFIG_DFU_ZIP_BLUETOOTH_MESH_METADATA option in sysbuild, the metadata will be automatically parsed from the .elf and .config files.
The parsed data is stored in the ble_mesh_metadata.json file.
The file is placed in the dfu_application.zip archive in the build folder of the application.
Additionally, the metadata string and, optionally, the firmware ID required by the mesh models dfu slot add command are printed in the command-line window when the application is built:
Bluetooth Mesh Composition metadata generated:
Encoded metadata: 020000000000000094cf24017c26f3710100
Firmware ID: 59000200000000000000
Full metadata written to: APPLICATION_FOLDER\build\zephyr\dfu_application.zip
You can generate the Firmware ID using one of the following options:
To use a user-supplied hex-string as the Firmware ID, enable the
SB_CONFIG_DFU_ZIP_BLUETOOTH_MESH_METADATA_FWID_CUSTOMoption. This is the default behavior.If this option is selected, the
SB_CONFIG_DFU_ZIP_BLUETOOTH_MESH_METADATA_FWID_CUSTOM_HEXoption must be set to a valid Firmware ID. At minimum, it should include a Company ID in little-endian order. The rest of the string is vendor-specific version information.When using the Firmware Distribution Server for distribution, the number of bytes in the Firmware ID of images used during distribution must not exceed the value of the
CONFIG_BT_MESH_DFU_FWID_MAXLENKconfig option set on the distributor node.
To use a Firmware ID consisting of the values of the
CONFIG_BT_COMPANY_IDand theCONFIG_MCUBOOT_IMGTOOL_SIGN_VERSIONKconfig options, enable theSB_CONFIG_DFU_ZIP_BLUETOOTH_MESH_METADATA_FWID_MCUBOOT_VERSIONoption.
Note
The Firmware ID (FWID) specified in the JSON file must match the fwid used when initializing the Firmware Update Server.
This ensures that after the firmware update is applied, the node will respond with the correct Current Firmware ID in the Firmware Update Information Status message.
Note
The Composition Data must be declared with the const qualifier.
If the application contains more than one Composition Data structure (for example, when the structure to be used is picked at runtime), the script will not print any encoded metadata.
In this case, use the JSON file to find the encoded metadata matching the Composition Data to be used by the device after the update.
Additionally, the script is hardcoded to produce a metadata string where the firmware is targeted for the application core.
You can use a separate west command to print the metadata to the console, given that it is already generated by the build system.
This gives you an easy access to this information, without having to enter the .json file in the build folder or to rebuild the application:
west build -t ble_mesh_dfu_metadata
For this particular example, the following output is generated:
{
"sign_version": {
"major": 2,
"minor": 0,
"revision": 0,
"build_number": 0
},
"binary_size": 241236,
"composition_data": {
"cid": 89,
"pid": 0,
"vid": 0,
"crpl": 10,
"features": 7,
"elements": [
{
"location": 1,
"sig_models": [
0,
2,
48962,
48964
],
"vendor_models": []
}
]
},
"composition_hash": 1911760508,
"encoded_metadata": "020000000000000094cf24017c26f3710100",
"firmware_id": "59000200000000000000"
}
Manual metadata generation
The Bluetooth Mesh DFU subsystem provides a set of shell commands that you can use to compose firmware metadata.
The format of metadata is defined in the bt_mesh_dfu_metadata structure.
For the complete list of commands, see DFU metadata.
To start composing metadata, use the mesh models dfu metadata comp-add shell command that encodes a Composition Data header.
For example, for a Target node with product ID 0x0059, zero company and version IDs, 10 entries in the replay list, and with Relay, Proxy and Friend features enabled, the command will be the following:
mesh models dfu metadata comp-add 0x59 0 0 10 7
Now, you need to encode elements that are present on a new image.
For each element to encode, use the mesh models dfu metadata comp-elem-add shell command specifying the location of the element, number of Bluetooth SIG and vendor models and their IDs.
For example, for Bluetooth Mesh: Device Firmware Update (DFU) target sample, which has only one element containing Configuration and Health Server models as well as DFU and BLOB Transfer Server models, the command will be the following:
mesh models dfu metadata comp-elem-add 1 4 0 0x0000 0x0002 0xBF42 0xBF44
Note
In case of any mistakes during the encoding of the Composition Data, use the mesh models dfu metadata comp-clear command to clear the cached value, then start composing the metadata from the beginning.
When all elements are added, generate a hash of the Composition Data using the mesh models dfu metadata comp-hash-get shell command.
For example, using the inputs from the commands above, the output of this command should be the following:
Composition data to be hashed:
CID: 0x0059
PID: 0x0000
VID: 0x0000
CPRL: 10
Features: 0x7
Elem: 1
NumS: 4
NumV: 0
SIG Model ID: 0x0000
SIG Model ID: 0x0002
SIG Model ID: 0xbf42
SIG Model ID: 0xbf44
Composition data hash: 0x71f3267c
The generated hash will then be encoded into the metadata.
Use the mesh models dfu metadata encode shell command to encode the metadata.
For example, using the Composition Data hash generated above, the command to encode the metadata for firmware version 2.0.0+0, with a size of 241236 bytes and targeted to application core, will be the following:
mesh models dfu metadata encode 2 0 0 0 241236 1 0x71f3267c 1
The output of the command will be the following:
Metadata to be encoded:
Version: 2.0.0+0
Size: 241236
Core Type: 0x1
Composition data hash: 0x71f3267c
Elements: 1
User data length: 0
Encoded metadata: 020000000000000094cf24017c26f3710100