Mistake on this page? Email us

Production process for Device Management Client Lite

Device Management Client Lite uses the device's internal flash to store a small set of configuration items, including Device Management credentials. You can inject the configuration items to a firmware binary with generate_firmware_images.py. To use this script, you need the manifest tool installed to your Python environment.

These are the main steps for preparing the Client Lite application for the production process:

  1. Preparing the Client Lite configuration file.
  2. Preparing the application binary.
  3. Generating the firmware binary, combining the Client Lite configuration and application.
  4. Generating the firmware update binary.

Preparing the Client Lite configuration file

The Client Lite configuration file contains authentication information for connecting to Device Management and updating devices with new firmware. You need to create the configuration file yourself.

The client_lite_configuration.json file supports the following fields:

{
    "endpoint_name" : "example-endpoint-name",
    "update_vendor_domain": "example.vendor.domain",
    "update_model_name": "example model",
    "bootstrap_server_psk_identity" : "0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00",
    "bootstrap_server_psk_secret" : "0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00",
    "bootstrap_server_uri" : "coaps://bootstrap.us-east-1.mbedcloud.com:5684?aid=<your_account_id>",
    "update_psk_identity" : "0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00",
    "update_psk_secret" : "0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00",
    "update_vendor_id" : "0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00",
    "update_class_id" : "0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00",
    "root_of_trust" : "0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00"
}

Mandatory configuration fields

Configuration field Format Description
endpoint_name Printable ASCII, 16-64 characters Unique name for your device.
update_vendor_domain Fully qualified domain name (ASCII, must contain a period) Your organizational name in domain form.
update_model_name Printable ASCII, 16-64 characters An identifier for your device model.

Advanced/Optional configuration fields

Configuration field Format Description
bootstrap_server_psk_identity Comma-separated list of hexadecimal bytes. PSK Identity for bootstrap.
bootstrap_server_psk_secret Comma-separated list of hexadecimal bytes. PSK Secret for bootstrap.
bootstrap_server_uri CoAP/TLS URI. Bootstrap URI to use.
update_psk_identity Comma-separated list of hexadecimal bytes. PSK Identity for update.
update_psk_secret Comma-separated list of hexadecimal bytes. PSK Secret for update.
update_vendor_id Comma-separated list of 16 hexadecimal bytes; RFC-4122 Type 5 UUID Vendor/organizational identifier for update.
update_class_id Comma-separated list of 16 hexadecimal bytes; RFC-4122 Type 5 UUID Device class identifier for update.
root_of_trust Comma-separated list of 16 hexadecimal bytes. Device root of trust.

You can create a complete configuration from just the Mandatory configuration fields.

In some use cases, you need to include some of the Advanced/Optional configuration fields.

An example use case:

  • You have already created the PSK identity for bootstrap or update separately (as part of your device provisioning using serial numbers) and want to use them as Cloud identifiers for your devices. Use the corresponding fields bootstrap_server_psk_identity and update_psk_identity respectively.
  • If you have the Device Management On Premise setup, you have to provide the bootstrap server URI for that setup using the bootstrap_server_uri field.
  • If you want to use your own device identifiers to create device filters to perform update on specific device types, you can use the update_class_id and update_vendor_id fields. If these values are not defined, the tool will create these entries (random UUID value) on your behalf.

If these parameters are missing from client_lite_configuration.json, they are derived from the endpoint_name. Values derived from the Mandatory configuration fields are always overridden by the Advanced/Optional configuration fields if specified.

Note: When creating multiple firmware binaries, endpoint_name is modified for each generated binary. It appends a sequential number starting from 0 to ensure they have unique names. The output file names reflect the final endpoint_name.

Preparing the application binary

To get the Client Lite application and prepare it for the production process:

  1. Clone the embedded application's GitHub repository to your local computer:

     mbed import https://github.com/ARMmbed/mbed-client-lite-example-restricted
    
  2. Enable the production process for the application:

    • In mbed_app.json or in the .json file of your selected configuration:

      "developer-mode": {
         "help": "Enable Developer mode to skip factory enrollment",
         "value": null
        },
      
    • If you are using any other configuration in the configs folder, do the same for the corresponding .json file and set developer-mode to null.

Note: The --app-config option is not supported, as the application configuration files contain relative paths to the bootloader files.

Compiling the application

Use Mbed CLI (release v1.8.0 or above) to detect and configure the target device:

mbed toolchain GCC_ARM
mbed target K64F

To compile the application using default target (K64F) and toolchain (GCC_ARM):

mbed compile

Creating firmware binaries

The generate_firmware_images.py script has a few important command line arguments:

Argument Description
Mandatory arguments
-a <path> Path to the firmware binary created with mbed compile.
-m <target> Target platform name [k64f, nucleo_f429zi].
--input-configuration <path> Path to Client Lite configuration file.
OR
--input-configuration-dir <path> Path to directory containing multiple Client Lite configuration files. <path>/conf/ is also read if no .json files are in <path>.
Optional arguments
--app-config <path> Path to the mbed_app.json or other application configuration file you used with mbed compile. Default is mbed_app.json. (Currently not supported feature).
--count <integer> Number of firmware binaries to create (number of devices) from an input configuration. The default is 1.
--update Enable creation and preparation of firmware update binaries.
--master-key-file <path> Path to a master key file for firmware update. Default: .update-certificates/default.master.psk.
-o <path> Path to generate the output to. Default is current directory.
--api-key <APIKEY> Device Management API key. Use this or MBED_CLOUD_SDK_API_KEY environment variable.

When you run this script, a new file called .update-certificates/default.master.psk, if not already present, is created. This file contains an Update Master Key that is used for generating a future update image that can be updated to a set of devices.

The Update master key is associated with the set of devices created during the firmware generation phase. This key is valid for updating only this set of devices.

If you want to create more firmware devices and want them to be updatable with all existing devices, please make sure that you are using this same Update Master Key.

You need to preserve this key as it will be passed in the manifest file that is used when updating the devices through the Update service. If you lose this key, you cannot update any of your devices associated with it.

The following sections explain the two options of creating multiple firmware images using the generate_firmware_images.py script.

User-provided PSK identities

Use this option if you have defined a set of PSK identities that you would like to assign to your device. For example, you may want to use the device's serial number or some other identification number as its PSK identity on Device Management.

For this, you need individual client_lite_configuration.json files containing the Mandatory configuration fields and some of the Advanced configuration fields that you provide as part of your own configuration.

An example using the script:

You want to create a firmware image for 1000 devices and you want their serial numbers to be the PSK identities in Device Management. You need to prepare 1000 individual client_lite_configuration.json files where each file contains a unique PSK identity that is used to generate its specific firmware image.

Your individual client_lite_configuration.json should be as follows:

{
    "endpoint_name" : "SERIAL-12345",
    "update_vendor_domain": "my.vendor.domain",
    "update_model_name": "pilot model",
    "bootstrap_server_psk_identity" : "0x53, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x2d, 0x31, 0x32, 0x33, 0x34, 0x35",
    "bootstrap_server_psk_secret" : "0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00",
    "update_psk_identity" : "0x53, 0x45, 0x52, 0x49, 0x41, 0x4c, 0x2d, 0x31, 0x32, 0x33, 0x34, 0x35",
    "update_psk_secret" : "0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00",
    "update_vendor_id" : "0x6d, 0x79, 0x2e, 0x76, 0x65, 0x6e, 0x64, 0x6f, 0x72, 0x2e, 0x64, 0x6f, 0x6d, 0x61, 0x69, 0x6e",
    "update_class_id" : "0x70, 0x69, 0x6c, 0x6f, 0x74, 0x20, 0x6d, 0x6f, 0x64, 0x65, 0x6c"
}

Where

  • endpoint_name is the user-provided input.
  • bootstrap_server_psk_identity is a hex representation of endpoint_name.
  • bootstrap_server_psk_secret is a hex representation of the user selected bootstrap PSK secret.
  • update_psk_identity is the same as bootstrap_server_psk_identity.
  • update_psk_secret is a hex representation of the user selected update PSK secret.
  • update_vendor_id is a hex representation of update_vendor_domain.
  • update_class_id is a hex representation of update_model_name.

Note: Do not put these configuration files directly in the root folder. Place them in a new folder, such as input_conf. The script iterates through each configuration file in this folder and creates a unique firmware image for each file.

Note: To test the configuration process, use tools/input-configuration-example/ as the input-configuration-dir in the script below. Replace <APIKEY> with an API key you copy from the portal, and k64f with the device model you're using.

The script:

  1. Creates the firmware binaries under ./flash.
  2. Creates corresponding configuration files for each firmware binary under ./conf/.
  3. Creates the PSK credentials (which are already combined in the firmware binaries) storage blobs separately under ./storage.
  4. Uploads the created PSK identities to Device Management Portal. You can check them in the portal after the script runs:

Run the script:

python tools/generate_firmware_images.py \
-a BUILD/K64F/GCC_ARM/mbed-client-lite-example-restricted.bin \
-m k64f \
--api-key <APIKEY> \
--input-configuration-dir tools/input-configuration-example/

Script-generated PSK identities

You can let the script create the PSK identities for multiple devices. This feature is helpful when running a pilot project that requires tens or hundreds of devices ready without setting up a heavy production setup.

For this, you need the client_lite_configuration.json file with the Mandatory configuration fields only. The remaining parameters are derived from these field values.

An example using the script:

You want to create a firmware image for 10 devices that you want to deploy as part of your pilot project.

Your client_lite_configuration.json should be:

{
    "endpoint_name" : "my-pilot-endpoint-name",
    "update_vendor_domain": "my.pilot.vendor.domain",
    "update_model_name": "pilot model"
}

The script:

  1. Creates the firmware binaries under ./flash.
  2. Creates corresponding configuration files for each firmware binary under ./conf/.
  3. Creates PSK credentials (which are already combined in the firmware binaries) storage blobs separately under ./storage.
  4. Uploads the created PSK identities to Device Management Portal. You can check them in the portal after the script runs:

To produce 10 firmware binaries to be flashed into the devices, use the generate_firmware_images.py script, adding the --count command line argument.

Note: To test the configuration process, use tools/input-configuration-example/ as the input-configuration-dir in the script below. Replace <APIKEY> with an API key you copy from the portal, and k64f with the device model you're using.

Run the script:

python tools/generate_firmware_images.py \
-a BUILD/K64F/GCC_ARM/mbed-client-lite-example.bin \
-m k64f \
--api-key <API_KEY> \
--input-configuration tools/input-configuration-example/input-configuration.json \
--count 10

When creating 10 firmware binaries, endpoint_name is modified for each generated binary. It appends a sequential number starting from 0 to up to the count to ensure they have unique names. Each binary contains a PSK identity named endpoint_name-0, endpoint_name-1, and so on, up to endpoint_name-9. The output binary filenames reflect the PSK identity: endpoint_name-0.bin, endpoint_name-1.bin, and so on.

You can use the configuration files under ./conf/ to verify that all the required fields have been set in the client configuration.

Note: This flow is only an example. You should consider more robust handling (such as HSM) for secrets in production.

Creating an update binary for Device Management Update

To create and prepare the update binaries to be used by the Device Management Update service, the generate_firmware_images.py script has a command line option --update.

The following example command creates an update binary under ./update.

To create the original firmware images of the devices, the input configurations (for preparing the master PSK table required by Update service) must be the same as in User-provided PSK identities or Script-generated PSK identities. This ensures that you are using the same configuration with the same Update master key for creating the manifest and updating the devices.

The update binary is uploaded and registered to the Device Management Update service for launching an update campaign later. The script creates a manifest for the update binary and uploads it to Update service. You can view this manifest in Device Management portal and create an update campaign from there.

Run the script:

python tools/generate_firmware_images.py \
-a BUILD/K64F/GCC_ARM/mbed-client-lite-example-restricted.bin \
-m k64f \
--api-key <APIKEY> \
--input-configuration-dir ./conf/ \
--update