Mistake on this page? Email us

Integrating FCU with your factory tool

To provision a device, your factory tool must call FCU APIs to:

  1. Creating the FCU keystore and the required keys. This is a one-time operation you perform when you set up your factory line.
  2. Perform a series of operations in sequence for each device:
    1. Create the device bundle.
    2. Process the device response.
    3. Create the device certificate bundle. The factory tool uses this API when FCU configuration includes device-generated keys (when device-key-generation-mode is by_device and when you configure custom properties).

All FCU APIs are available in the fcu.FactoryToolApi class in the FCU Python package.

For a reference implementation of the FCU APIs in a factory tool, see the ft_demo folder in the FCU archive.

Note: If you have not configured FCU yet, follow the FCU configuration instructions before you integrate the APIs into your factory tool.

Usage overview

The basic mode of operation when you use the FCU Python package is to:

  1. Create an instance of fcu.FactoryToolApi.
  2. Invoke the relevant APIs of the above instance.

Creating an instance of FactoryToolApi

Initialize an instance of the FactoryToolApi class by calling its constructor.

Parameters

The FactoryToolApi constructor accepts and initializes the following parameters:

Parameter Description Optional or mandatory
home_dir Specifies the home directory of the FCU library.
The library uses this as the root path of several directories and files it depends on.
If not provided, FCU uses the environment variable FCU_HOME_DIR, if it is set.
Otherwise, FCU uses the current working directory.
Optional
resources_dir Specifies the resources directory of the FCU library.
If not provided, FCU uses the environment variable FCU_RESOURCES_DIR, if it is set.
Otherwise, FCU uses the /<FCU Home>/resources folder.
Optional
logs_dir Specifies the logs directory of the FCU library.
If not provided, FCU uses the environment variable FCU_LOGS_DIR, if it is set.
Otherwise, FCU uses the /<FCU HOME>/logs folder.
Optional
keystore_dir Specifies the keystore directory of the FCU library.
If not provided, FCU uses the environment variable FCU_KEYSTORE_DIR, if it is set.
Otherwise, FCU uses the /<FCU Home>/keystore folder.
Optional
config_file Configuration file name for FCU (including path).
If not provided, FCU expects to use the <FCU HOME>/config/fcu.yml file.
Optional
import fcu

factory_tool_api = fcu.FactoryToolApi(
    home_dir="C:\\extracted-fcu-archive",
    resources_dir="C:\\extracted-fcu-archive\resources",
    config_file="C:\\extracted-fcu-archive\config\fcu.yml")

Creating the FCU keystore and the required keys

API name

FactoryToolApi.setup_factory_configurator_utility

API functionality

Performs the initial setup of FCU as a certificate authority or intermediate certificate authority:

  1. Creates a keystore folder under <FCU HOME>.
  2. In keystore, the API creates:
    • A private key named fcu_private_key.pem.
    • A certificate or CSR, depending on the setup-ca-as-intermediate parameter in the FCU configuration file:
      • If setup-ca-as-intermediate is false:
        The setup command creates a self-signed X.509 certificate named fcu.crt.
      • If setup-ca-as-intermediate is true:
        The setup command creates a CSR named fcu_csr.pem. Use your certificate authority to sign the CSR, and provide the generated certificate chain to FCU as a predefined file name fcu.crt.
        Note: When you use FCU as a certificate authority, if fcu.crt is a certificate chain, you must specify a device-certificate-chain-depth value in the FCU configuration file.
Parameter Description Possible values Optional or mandatory
override_existing_ca Defines whether to override an existing CA configuration. Boolean. Default: false. Mandatory
import fcu

factory_tool_api = fcu.FactoryToolApi()
setup_status = factory_tool_api.setup_factory_configurator_utility(override_existing_ca=False)
if setup_status.ca_ready:
    upload_to_mbed_cloud(setup_status.ca_certificate_file)
else:
    raise Exception('Something went wrong')

Return value

Returns the setup_status object FactoryToolApi.get_setup_status. For details, see the SetupStatus object description in the references.

import fcu

factory_tool_api = fcu.FactoryToolApi()
try:
    setup_status = factory_tool_api.get_setup_status()
    if setup_status.ca_ready:
        pass  # Do something here
except FactoryConfiguratorErrorBase as error:
	      pass  # Do something here
	      raise error

Creating the device bundle

API name

FactoryToolApi.prepare_device_configuration

API functionality

Generates the device configuration bundle in a CBOR format compatible with the device's requirements.

Parameter Description Possible values Optional or mandatory
endpoint_name Device's endpoint name String
Note: For the endpoint-name attribute, we recommend using only the characters a-z, A-Z,0-9, '+,-.:/= and SPACE. For more information, see endpoint name.
Mandatory
serial_number Device's serial number String Mandatory
device_keys_location If the device key generation mode is externally_supplied, this parameter specifies the location of the device's DTLS keys and certificates.
If the generation mode is by_tool, this parameter is ignored.
String. Default: None. Mandatory if device-key-generation-mode is externally_supplied
device_config_yml Custom properties provided in YAML format. For more information, see Custom properties. String Optional
factory_fcc_disable Sets factory disabled flag to disable further use of the factory configuration client (FCC). Boolean.
Default: None.
Optional

Return value

Returns the DeviceConfigurationRequest object as described in the references.

import fcu

factory_tool_api = fcu.FactoryToolApi()
try:
    prepared_config = factory_tool_api.prepare_device_configuration(
       	endpoint_name='some-endpoint',
       	serial_number='some-sn-for-device',
       	device_keys_location='/local/arm/mbed/factory-configurator/per-device-resources/your-device')
except FactoryConfiguratorErrorBase as error:
	      warning_list = error.warning_lis
	      error_list = error.error_list

Processing the device response

API name

FactoryToolApi.verify_device_response

API functionality

Receives the device's response (a CBOR formatted blob) after injection, processes and verifies it, and returns the status.

Parameter Description Possible values Optional or mandatory
endpoint_name The device's endpoint String
Note: For the endpoint-name attribute, we recommend using only the characters a-z, A-Z,0-9, '+,-.:/= and SPACE. For more information, see endpoint name.
Mandatory
device_response The CBOR blob received from the device in response to injection. Bytes Mandatory

Return value

Returns the DeviceResponseStatus object as described in the references.

import fcu

# The following read_device_response() call assumes that the factory tool
# can read the device's response (after sending the device configuration bundle).
device_response_bytes = read_device_response()
try:
    factory_tool_api = fcu.FactoryToolApi()
    response_status = factory_tool_api.verify_device_response(
        endpoint_name='some-endpoint',
        device_response=device_response_bytes)
except FactoryConfiguratorErrorBase as error:
	      raise error
if response_status.status != 0:
    pass

Creating device certificates

API name

FactoryToolApi.do_next_operation

API functionality

Generates the device certificate configuration bundle in CBOR format compatible with the device's requirements.

Parameter Description Possible values Optional or mandatory
fcu_operation_context The operation context object, as described in the references. Includes:
endpoint_name
enrollment_id
warning_list
next_operation
Object Mandatory
device_response The CBOR blob received from the device in response to injection. Bytes Mandatory

Return value

Returns the DeviceConfigurationRequest object as described in the references.

import fcu

factory_tool_api = fcu.FactoryToolApi()

# Prepare device configuation, add your own arguments (pseudo)
device_config_req = factory_tool_api.prepare_device_configuration(...)

# Process request to device and device respone here (pseudo)
device_response_bytes = get_your_device_response_bytes(device_config_req, ...)

# If original configuration required more operations, continue with next operation:
if device_config_req.fcu_operation_context.next_operation != fcu.OperationName.NO_OP:
    device_configuration_request = factory_tool_api.do_next_operation(
        fcu_operation_context=device_config_req.fcu_operation_context,
        device_response=device_response_bytes)