Integrating FCU with your factory tool
To provision a device, your factory tool must call FCU APIs to:
- Creating the FCU keystore and the required keys. This is a one-time operation you perform when you set up your factory line.
- Perform a series of operations in sequence for each device:
- Create the device bundle.
- Process the device response.
- Create the device certificate bundle. The factory tool uses this API when FCU configuration includes device-generated keys (when
device-key-generation-mode
isby_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:
- Create an instance of
fcu.FactoryToolApi
. - 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:
- Creates a
keystore
folder under<FCU HOME>
. - 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
isfalse
:
The setup command creates a self-signed X.509 certificate namedfcu.crt
. - If
setup-ca-as-intermediate
istrue
:
The setup command creates a CSR namedfcu_csr.pem
. Use your certificate authority to sign the CSR, and provide the generated certificate chain to FCU as a predefined file namefcu.crt
.
Note: When you use FCU as a certificate authority, iffcu.crt
is a certificate chain, you must specify adevice-certificate-chain-depth
value in the FCU configuration file.
- If
- A private key named
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)