This page provides an overview of the provisioning procedure and the available API functions for setting up a provisioner and setting up a provisionee.
For more information about provisioning, see Provisioning.
Table of contents
The following diagram illustrates the provisioning procedure, with all function calls, messages, and events.
mesh_init()
in the main.c
file of the light-switch\server
example or any other example exhibiting the Node role.You can exclude code for one of the roles if your device is not using it. To do so, link only the code for the role that you want the device to support. Calling an unsupported function whose role functionality has not been compiled into the library will return NRF_ERROR_NOT_SUPPORTED
.
Provisioners are Bluetooth mesh nodes that are responsible for the configuration of other nodes in the network. Typically, provisioners contain a configuration client and client nodes for controlling specific functionality in other nodes, such as lights or air conditioners. Provisioners are often a part of gateway devices, which are devices that provide a bridge between a Bluetooth mesh network and other networking technologies (such as the Internet).
There are two main ways of setting up a provisioner:
The following figure illustrates the provisioner flow for both setups.
The standalone provisioner provides provisioning functionality without depending on an external host. As such, a standalone provisioner must be able to store information about the provisioned nodes in the network, including their addresses and device keys, which is necessary for the provisioner to be able to configure the nodes.
Because of the limited amount of memory available in embedded processors, using a standalone provisioner limits the amount of nodes that can be provisioned. This limit corresponds to the maximum size of the Bluetooth mesh network.
To provision a device using the standalone provisioner, make sure you implement the following steps in your provisioner application:
To use any provisioning API, a provisioning context must be initialized using the nrf_mesh_prov_init()
function.
The function needs statically allocated provisioning context structure with related parameters.
The provisioning context structure maintains the state of the provisioning process. Among other information, it contains the following data that is initialized based on the parameter values provided by the user:
nrf_mesh_prov_generate_keys()
function. See prov_helper_provisioner_init()
in the static provisioner example (/examples/light-switch/provisioner/src/provisioner_helper.c
) to see how to initialize a provisioner.
The provisioning procedure is started by calling nrf_mesh_prov_provision() API.
Make sure the following parameters are provided to this API:
As a result, the provisioning modules:
The unprovisioned device responds to the Provisioning Invite message by sending a Provisioning Capabilities message. This action generates the NRF_MESH_PROV_EVT_CAPS_RECEIVED event for the provisioner application.
The provisioner application then checks the capabilities of the unprovisioned device reported in the event parameters. It then calls the nrf_mesh_prov_oob_use() function to select the public key exchange mechanism and the authentication method.
After NRF_MESH_PROV_EVT_CAPS_RECEIVED event is generated, make sure you call the nrf_mesh_prov_oob_use() function with the variables and parameters that are used:
capabilities.pubkey_type
to NRF_MESH_PROV_OOB_PUBKEY_TYPE_OOB in the provisioning context. Otherwise, the application should not set this value.method
parameter to one of the following:action
parameter to one of the values mentioned in the nrf_mesh_prov_types.h
file.size
parameter to a value between 0x01
and 0x08
(as defined in Bluetooth mesh profile specification).Exchanging public keys depends on whether you set capabilities.pubkey_type
in Step 3:
capabilities.pubkey_type
is set to NRF_MESH_PROV_OOB_PUBKEY_TYPE_OOB in response to NRF_MESH_PROV_EVT_CAPS_RECEIVED event, the provisioning process will raise NRF_MESH_PROV_EVT_OOB_PUBKEY_REQUEST event for the provisioner application.capabilities.pubkey_type
is not set, the public key will be exchanged In-Band and no event will be generated.Depending on the authentication method choice in Step 3, the stack will generate different events:
If the authentication succeeds:
After this step, the provisioning link will be closed and the NRF_MESH_PROV_EVT_LINK_CLOSED event will be generated.
Serial provisioners use the serial interface to do provisioning, allowing a host controller to interact with the Bluetooth mesh network using an external microcontroller.
The host controller stores information about the nodes on the network, which saves RAM in the external microcontroller for other application-specific uses. The size of the Bluetooth mesh network is limited only by the resources available in the host machine.
The steps to include in your serial provisioner application are the following:
nrf_mesh_serial_init()
and nrf_mesh_serial_enable()
API functions.The ECDH (Elliptic Curve Diffie-Hellman) is a crytographic algorithm used to securely create a shared secret between two devices. It is used to create an encryption key, which is then used for securing the provisioning data as it is being transferred to the provisionee.
Enable the ECDH offloading if you are running multiple provisioners in parallel. The ECDH is a processor-intensive algorithm that can easily become a bottleneck. The ECDH offloading is a feature that lets the host processor calculate the ECDH shared secret, which saves CPU resources in the target processor.
To enable the ECDH offloading, make sure your application calls mesh_opt_prov_ecdh_offloading_set when initializing the device.
Provisionee is a device that will be provisioned by the provisioner. After provisioning completes successfully, this device becomes a node in the Bluetooth mesh network.
The following figure shows a sample flow chart of the provisioning process when the Static OOB authentication is used.
To provision an unprovisioned device, make sure you implement the following steps in your provisionee application:
To use any provisioning API, a provisioning context must be initialized using the nrf_mesh_prov_init()
function.
The function needs statically-allocated provisioning context structure and other related parameters.
The provisioning context structure maintains the state of the provisioning process. Among other information, it contains the following data that is initialized based on the parameter values provided by the user:
nrf_mesh_prov_generate_keys()
function.oob_static_type
, oob_output_size
, oob_output_actions
, oob_input_size
, and oob_input_actions
):oob_static_types
to 0
.0x01
to 0x08
and oob_output_actions to a desired output action.oob_output_size
to 0x00
.0x01
to 0x08
and oob_input_actions to a desired output action.oob_input_size
to 0x00
.For regular Bluetooth mesh devices (the devices exhibiting the node role), the initialization of the provisioning stack with bearers is encapsulated by the Mesh stack within the mesh_provisionee_prov_start() API.
The authentication options can be customized in mesh_provisionee_prov_start() by updating the prov_caps
structure with desired values.
The provisioning procedure is started by the provisioner, which opens a provisioning link and sends a provisioning invite.
Before the provisioning link can be opened, the unprovisioned device must initialize the provisioning APIs and bearers and it must be ready to receive the request to open the link. For Bluetooth mesh example applications, this process is encapsulated in the mesh_provisionee_prov_start() API in the mesh_provisionee.c module and includes the following actions:
To customize public key exchange and authentication options, you can modify the prov_caps
structure values in this API.
prov_caps
options here will change these options for all examples. Alternatively, you can copy this module with some other name, update the prov_caps
values, and use this new module in your project.Once the provisioner opens the link, the Bluetooth mesh stack generates NRF_MESH_PROV_EVT_LINK_ESTABLISHED event. When the Provisioning Invite message is received, the Bluetooth mesh stack generates the NRF_MESH_PROV_EVT_INVITE_RECEIVED event and provides the attention timer duration value as the event parameter. This event is handled by the mesh_provisionee.c module and the user application callback is called to allow the application to attract attention of the end-user. For example, this can mean blinking LEDs for a given duration.
The unprovisioned device will respond to the Provisioning Invite message by sending a Provisioning Capabilities message (with settings specified in Step 1. This will not generate any event for the provisionee application.
The provisioner picks up the public key exchange and the authentication method from the provided capabilities and sends the Provisioning Start message. This generates the NRF_MESH_PROV_EVT_START_RECEIVED event on the provisionee side.
Exchanging public keys depends on whether the provisionee sets capabilities.pubkey_type
to NRF_MESH_PROV_OOB_PUBKEY_TYPE_OOB :
capabilities.pubkey_type
to NRF_MESH_PROV_OOB_PUBKEY_TYPE_OOB, the provisioner:capabilities.pubkey_type
to NRF_MESH_PROV_OOB_PUBKEY_TYPE_OOB :After this step, the authentication will be performed.
Depending on the available capabilities and the authentication method chosen by the provisioner, the Bluetooth mesh stack will generate different events:
If the authentication succeeds:
mesh_provisionee
module saves the provisioning data to the flash.After this step, the provisioning link will be closed and the NRF_MESH_PROV_EVT_LINK_CLOSED event will be generated.
At this point, the device can receive more configuration details from the provisioner through the configuration model. The configuration happens automatically in the background as long as the configuration model server has been initialized (see the Light switch example for an example of how to do this).
If an error occurs in the provisioning procedure, the provisioning link is closed. An NRF_MESH_PROV_EVT_LINK_CLOSED
event is passed to the application. This event contains the nrf_mesh_prov_evt_link_closed_t.close_reason
parameter that can be used to determine what caused the provisioning to fail.
If an NRF_MESH_PROV_EVT_LINK_CLOSED
event is received before an NRF_MESH_PROV_EVT_COMPLETE
event, the provisioning procedure must be considered to have failed.
Additionally, the peer device may send a Provisioning Failed PDU as a result of any error other than the timeout. After receiving the Provisioning Failed PDU, the NRF_MESH_PROV_EVT_FAILED
event is passed to the application. This event contains the failure_code parameter that can be used to determine what caused the Provisioning Failed event.