Mistake on this page? Email us

Building your device application for factory provisioning

You can set up your device application to carry out the factory provisioning process without Factory Configurator Utility (FCU) using two modules that are part of Device Management Client:

  • The factory configurator client (FCC) module exposes APIs for initiating and finalizing the factory flow, carrying out the injection process, and verifying that the device is ready to connect to Device Management.
  • The key and configuration manager (KCM) module exposes APIs for storing, retrieving, deleting, and verifying items in the device's secure storage.

This section explains how to use these two modules in your device application to enable the provisioning process. The process involves the following steps, which are explained in greater detail below:

  1. Initializing FCC.
  2. Configuring the device.
  3. Storing data on the device.
  4. Setting the Bootstrap CA identification flag
  5. Verifying device configuration.
  6. Switching on the factory disable flag.
  7. Finalizing FCC and KCM.

For details about FCC and KCM APIs, please see the FCC and KCM API documentation.

Initializing FCC

Use the fcc_init() function to initialize FCC at the beginning of your application code.

Configuring the device

Use FCC to configure device parameters such as:

  • Entropy (fcc_entropy_set)
  • Root of trust (RoT) (fcc_rot_set)

Storing data on the device

For the device to connect to Device Management, you must store all of the mandatory items listed in the provisioning information section on the device during the factory process. The item names must match the table exactly. To store keys, certificates, and configuration parameters, you use the KCM module.

Setting the Bootstrap CA identification flag

The fcc_trust_ca_cert_id_set function sets and stores the Bootstrap CA identification. Call this function only after you store the Bootstrap CA certificate on the device.

Verifying device configuration

If you want to verify that the device is correctly configured for Device Management, use the fcc_verify_device_configured_4mbed_cloud() function. It verifies that all mandatory items exist and performs additional checks to ensure that parameters are set correctly for connection to Device Management.

The list of the validations can be found in the provisioning information section.

Errors and warnings in the verification process

If the verification process raises an error or a warning, the fcc_output_info_s structure records all relevant information.

After fcc_verify_device_configured_4mbed_cloud() is processed, you can call the fcc_get_error_and_warning_data() API to get all recorded warnings and errors.

If there were no warnings and errors, the error_string_info and head_of_warning_list will be NULL, and size_of_warning_info_list will be 0.

Switching on the factory disable flag

Raise the factory disable flag by calling fcc_factory_disable() to indicate that the factory process has completed.

Finalizing FCC and KCM

Use the fcc_finalize() function to finalize FCC, release resources, and conclude the workflow. This also finalizes the KCM module, so you don't need to finalize it manually.

Factory process example

#include "factory_configurator_client.h"
#include "fcc_status.h"

int main()
{
    fcc_status_e fcc_status;
    kcm_status_e kcm_status;
    fcc_output_info_s *output_info = NULL;
    fcc_warning_info_s *warning_list = NULL;

    uint64_t epoch_time = TBD;
    uint8_t use_bootstrap_mode = 1;

    fcc_status = fcc_init();
    if (fcc_status != FCC_STATUS_SUCCESS) {
        return 1;
    }

    // Set device time
    fcc_status = fcc_time_set(epoch_time);
    if (fcc_status != FCC_STATUS_SUCCESS) {
        return 1;
    }

    // Storing the useBootstrap configuration parameter
    kcm_status = kcm_item_store(g_fcc_use_bootstrap_parameter_name,
                                strlen(g_fcc_use_bootstrap_parameter_name),
                                KCM_CONFIG_ITEM,
                                true,
                                use_bootstrap_mode,
                                sizeof(use_bootstrap_mode),
                                NULL);
    if (kcm_status != KCM_STATUS_SUCCESS) {
        return 1;
    }

    // Additional storing operations
    // such as bootstrap ca certificate and other mandatory and optional
    // items listed in provisioning info section

    // Set bootstrap ca identification
    fcc_status = fcc_trust_ca_cert_id_set();
    if (fcc_status != FCC_STATUS_SUCCESS) {
        return 1;
    }

    // Verify the device was configure correctly
    fcc_status = fcc_verify_device_configured_4mbed_cloud();
    if (fcc_status != FCC_STATUS_SUCCESS) {
        return 1;
    }

    // Check the verify process results
    output_info = fcc_get_error_and_warning_data();
    if (output_info != NULL) {
        // Handle errors and warnings as required

        // Check if there is an error
        if (output_info->error_string_info != NULL) {
            // Handle output_info->error_string_info as required. For example, print it to the stdout
        }
        // Check if there are warnings
        if (output_info->size_of_warning_info_list > 0) {

            // Set warning_list to point on the head of the list
            warning_list = output_info->head_of_warning_list;

            // Iterate the list
            while (warning_list != NULL) {
                // Handle warning_list->warning_info_string as required. For example, print it to the stdout

                // Move warning_list to point on the next warning in the list
                warning_list = warning_list->next;
            }
        }
    }

    // Raise factory disable flag
    fcc_status = fcc_factory_disable();
    if (fcc_status != FCC_STATUS_SUCCESS) {
        return 1;
    }

    // Finalization
    fcc_status = fcc_finalize();
    if (fcc_status != FCC_STATUS_SUCCESS) {
        return 1;
    }
}