-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
doc: provisioning: Add documentation #11704
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
.. _lib_nrf_provisioning: | ||
|
||
nRF Device provisioning | ||
####################### | ||
|
||
.. contents:: | ||
:local: | ||
:depth: 2 | ||
|
||
The nRF Device provisioning library enables a device to connect to nRF Cloud Provisioning Service, part of nRF Cloud Security Services. | ||
It abstracts and hides the details of the transport and encoding scheme that are used for the payload. | ||
The current implementation supports the following technologies: | ||
|
||
* AT-command based provisioning commands | ||
* Writing key-value pair based settings to the :ref:`settings_api` storage | ||
* TLS-secured HTTP as the communication protocol | ||
* Client authentication with attestation token | ||
* Client authentication with JWT token | ||
* CBOR as the data format | ||
|
||
Configuration | ||
************* | ||
|
||
To enable the library, set the :kconfig:option:`CONFIG_NRF_PROVISIONING` Kconfig option to ``y``. | ||
|
||
Configuration options for transport protocol | ||
============================================ | ||
|
||
Currently, HTTP is the only supported transport protocol. | ||
|
||
* :kconfig:option:`CONFIG_NRF_PROVISIONING_SYS_INIT` - Initializes the client in the system initialization phase | ||
* :kconfig:option:`CONFIG_NRF_PROVISIONING_ROOT_CA_SEC_TAG` - Root CA security tag for the Provisioning Service | ||
* :kconfig:option:`CONFIG_NRF_PROVISIONING_HTTP_HOSTNAME` - HTTP API hostname for the Provisioning Service | ||
* :kconfig:option:`CONFIG_NRF_PROVISIONING_HTTP_PORT` - Port number for the Provisioning Service | ||
* :kconfig:option:`CONFIG_NRF_PROVISIONING_HTTP_TIMEOUT_MS` - Timeout in milliseconds for HTTP connection of the Provisioning Service | ||
* :kconfig:option:`CONFIG_NRF_PROVISIONING_HTTP_RX_BUF_SZ` - HTTP response payload buffer size | ||
* :kconfig:option:`CONFIG_NRF_PROVISIONING_HTTP_TX_BUF_SZ` - HTTP request body size | ||
* :kconfig:option:`CONFIG_NRF_PROVISIONING_HTTP_JWT` - Chooses JWT token for client authentication | ||
* :kconfig:option:`CONFIG_NRF_PROVISIONING_HTTP_ATTESTTOKEN` - Chooses attestation token for client authentication | ||
|
||
.. _lib_nrf_provisioning_start: | ||
|
||
Usage | ||
***** | ||
|
||
The usage of the nRF Device provisioning library is described in the following sections. | ||
|
||
Initialization | ||
============== | ||
|
||
Once initialized, the provisioning client runs on its own in the background. | ||
The provisioning client can be initialized in one of the following ways: | ||
|
||
* The application calls :c:func:`nrf_provisioning_init`, which starts the client. | ||
* Set the client to initialize during Zephyr's system initialization phase. | ||
In this case, it is assumed that a network connection has been established in the same phase. | ||
|
||
The function uses the following arguments: | ||
|
||
* A pointer to a callback function, which is called when the modem state changes. | ||
* A pointer that must be called once provisioning is done. | ||
|
||
If you provide ``null`` as a callback function address argument, a corresponding default callback is used. | ||
Subsequent calls to the initialization function will only change the callback functions. | ||
This behavior is beneficial when the client has been initialized during the system initialization phase, but the application wants to register its own callback functions afterwards. | ||
|
||
Provisioning | ||
============ | ||
|
||
By default, when provisioning is done after receiving the ``FINISHED`` command, the device is rebooted. | ||
The behavior can be overwritten by providing a unique callback function for the initialization function. | ||
|
||
If anything is written to the modem's non-volatile memory, the modem needs to be set in offline mode. | ||
This is because the modem cannot be connected while any data is being written to its storage area. | ||
Once the memory write is complete, the aforementioned callback function must be called again to set the modem to the desired state. | ||
To use the default implementation, ``NULL`` can be passed as an argument to the :c:func:`nrf_provisioning_init` function. | ||
Copy and modify the default callback function as necessary. | ||
|
||
The library starts provisioning when it initializes, then according to the configured interval. | ||
The interval is read from the storage settings and can be updated with a provisioning command like any other key-value pair. | ||
|
||
During provisioning, the library first tries to establish the transport for communicating with the service. | ||
This procedure involves a TLS handshake where the client establishes the correct server. | ||
The server uses the attestation token or JWT generated by the device to authenticate the client. | ||
See :ref:`lib_modem_attest_token` and :ref:`lib_modem_jwt` for more information on client authentication. | ||
|
||
The TLS handshake happens twice: | ||
|
||
* Before requesting commands. | ||
* After the execution of the commands, to report the results. | ||
|
||
If you are using `AT commands <AT Commands Reference Guide_>`_, the library shuts down the modem for writing data to the modem's non-volatile memory. | ||
Once the memory writes are complete, the connection is re-established to report the results back to the server. | ||
The results are reported back to the server when either all the commands succeed or when an error occurs. | ||
If an error occurs, the results of all the commands that are successfully executed before the error and the erroneous result are reported back to the server. | ||
All successfully executed commands will be removed from the server-side queue, but if any errors occur, the erroneous command and all the remaining unexecuted commands are removed from the server-side queue. | ||
The log contains more information about the issue. | ||
|
||
Immediate provisioning can be requested by calling the :c:func:`nrf_provisioning_trigger_manually` function. | ||
Otherwise, the library attempts provisioning according to the set interval. | ||
To trigger immediate provisioning, the library must be initialized first. | ||
|
||
The following message sequence chart shows a successful provisioning sequence: | ||
|
||
.. msc:: | ||
hscale = "1.5"; | ||
Owner,Server,Device; | ||
Owner>>Server [label="Provision: cmd1, cmd2, finished"]; | ||
Server<<Device [label="Get commands"]; | ||
Server>>Device [label="Return commands"]; | ||
Device box Device [label="Decode commands"]; | ||
Device box Device [label="Set modem offline"]; | ||
Device box Device [label="Write to non-volatile memory"]; | ||
Device box Device [label="Restore modem state"]; | ||
Server<<Device [label="cmd1,cmd2, finished succeeded"]; | ||
|
||
The following message sequence chart shows a failing provisioning sequence: | ||
|
||
.. msc:: | ||
hscale = "1.5"; | ||
Owner,Server,Device; | ||
Owner>>Server [label="Provision: cmd1, cmd2, cmd3, finished"]; | ||
Server<<Device [label="Get commands"]; | ||
Server>>Device [label="Return commands"]; | ||
Device box Device [label="Decode commands"]; | ||
Device box Device [label="Set modem offline"]; | ||
Device box Device [label="cmd1: Write to non-volatile memory"]; | ||
Device box Device [label="cmd2: Fails"]; | ||
Device box Device [label="Restore modem state"]; | ||
Server<<Device [label="cmd1 success, cmd2 failed"]; | ||
Server>>Server [label="Empty the command queue"]; | ||
Server>>Owner [label="cmd2 failed"]; | ||
|
||
.. _nrf_provisioning_shell: | ||
|
||
nRF Provisioning shell | ||
********************** | ||
|
||
To test the client, you can enable Zephyr's shell and provisioning command, which allow you to control the client over UART. | ||
The feature is enabled by selecting :kconfig:option:`CONFIG_NRF_PROVISIONING_SHELL`. | ||
|
||
.. note:: | ||
The shell is meant for testing. | ||
Do not enable it in production. | ||
|
||
.. code-block:: console | ||
|
||
uart:~$ nrf_provisioning | ||
nrf_provisioning - nRF Provisioning commands | ||
Subcommands: | ||
init :Start the client | ||
now :Do provisioning now | ||
token :Get the attestation token | ||
uuid :Get device UUID | ||
|
||
.. _nrf_provisioning_api: | ||
|
||
API documentation | ||
***************** | ||
|
||
| Header file: :file:`include/net/nrf_provisioning.h` | ||
| Source files: :file:`subsys/net/lib/nrf_provisioning/src/` | ||
|
||
.. doxygengroup:: nrf_provisioning | ||
:project: nrf | ||
:members: |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
.. _nrf_provisioning_sample: | ||
|
||
Cellular: nRF Device provisioning | ||
################################# | ||
|
||
.. contents:: | ||
:local: | ||
:depth: 2 | ||
|
||
This sample demonstrates how to use the :ref:`lib_nrf_provisioning` service on your device. | ||
|
||
Requirements | ||
************ | ||
|
||
The sample supports the following development kits: | ||
|
||
.. table-from-rows:: /includes/sample_board_rows.txt | ||
:header: heading | ||
:rows: nrf9161dk_nrf9161_ns | ||
|
||
.. include:: /includes/tfm.txt | ||
|
||
The sample requires that the device's private key is installed on the device and the associated device UUID is obtained from the Identity Service. | ||
|
||
.. note:: | ||
This sample requires modem firmware v2.0.0 or later. | ||
|
||
Overview | ||
******** | ||
|
||
The sample shows how the device performs the following actions: | ||
|
||
* Connects to nRF Cloud Provisioning Service. | ||
* Fetches available device-specific provisioning configuration. | ||
* Decodes the commands. | ||
* Acts on any AT commands, if available. | ||
* Reports the results back to the server. | ||
In the case of an error, stops processing the commands at the first error and reports it back to server. | ||
* Sends ``FINISHED`` response if all the previous commands are executed without errors provided and ``FINISHED`` is one of the set provisioning commands. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure what 'without errors provided and There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. FINISHED refers to the provisioning command which tells to the device that provisioning process has been finished. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK. So this refers specifically to something in the sample, and not the Provisioning Service. |
||
|
||
User interface | ||
************** | ||
|
||
Device side interaction is not required. | ||
You must define the provisioning configuration at the server side. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
See `nRF Cloud provisioning configuration`_. | ||
|
||
Configuration | ||
************* | ||
|
||
|config| | ||
|
||
Configuration options | ||
===================== | ||
|
||
Check and configure the following configuration options for the sample: | ||
|
||
.. _CONFIG_NRF_PROVISIONING_ROOT_CA_SEC_TAG: | ||
|
||
CONFIG_NRF_PROVISIONING_ROOT_CA_SEC_TAG | ||
Root CA security tag for the nRF Cloud Provisioning Service. | ||
Needs to be set explicitly and if not, the compilation fails. | ||
|
||
.. _CONFIG_NRF_PROVISIONING_HTTP_HOSTNAME: | ||
|
||
CONFIG_NRF_PROVISIONING_HTTP_HOSTNAME | ||
Configures the hostname of the nRF Device provisioning service. | ||
|
||
.. _CONFIG_NRF_PROVISIONING_HTTP_PORT: | ||
|
||
CONFIG_NRF_PROVISIONING_HTTP_PORT | ||
Configures the HTTP port of the nRF Device provisioning service. | ||
|
||
.. _CONFIG_NRF_PROVISIONING_HTTP_TIMEOUT_MS: | ||
|
||
CONFIG_NRF_PROVISIONING_HTTP_TIMEOUT_MS | ||
Configures the HTTP timeout. | ||
|
||
.. _CONFIG_RF_PROVISIONING_HTTP_RX_BUF_S: | ||
|
||
CONFIG_RF_PROVISIONING_HTTP_RX_BUF_S | ||
Configures the response payload buffer size. | ||
|
||
.. _CONFIG_NRF_PROVISIONING_HTTP_TX_BUF_SZ: | ||
|
||
CONFIG_NRF_PROVISIONING_HTTP_TX_BUF_SZ | ||
Configures the command request body size. | ||
|
||
Building and running | ||
******************** | ||
|
||
.. |sample path| replace:: :file:`samples/cellular/nrf_provisioning` | ||
|
||
.. include:: /includes/build_and_run_ns.txt | ||
|
||
Testing | ||
======= | ||
|
||
|test_sample| | ||
|
||
#. |connect_kit| | ||
#. |connect_terminal| | ||
#. Add a provisioning configuration using the nRF Cloud Provisioning Service. | ||
See `nRF Cloud provisioning configuration`. | ||
#. Power on or reset your device. | ||
#. Observe that the sample starts and connects to the LTE network. | ||
#. Observe that provisioning pauses and resumes while fetching and executing provisioning commands. | ||
|
||
Sample output | ||
============= | ||
|
||
The following is an example output of the sample when there is no provisioning configuration on the server side: | ||
|
||
.. code-block:: console | ||
|
||
<inf> nrf_provisioning_sample: Establishing LTE link ... | ||
<inf> nrf_provisioning_http: Connected | ||
<inf> nrf_provisioning_http: No more commands to process on server side | ||
|
||
The following is an example output when the sample is processing commands from the server: | ||
|
||
.. code-block:: console | ||
|
||
<inf> nrf_provisioning_sample: Establishing LTE link ... | ||
<inf> nrf_provisioning_http: Connected | ||
<inf> nrf_provisioning: Disconnected from network - provisioning paused | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I assume between "Disconnected" and "Connected" on the next line, some actual provisioning is happening? It might be nice to say so (obviously that requires a change to the code itself, not just this documentation). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good point. I'll create a new PR for this. |
||
<inf> nrf_provisioning: Connected; home network - provisioning resumed | ||
<inf> nrf_provisioning_sample: Modem connection restored | ||
<inf> nrf_provisioning_sample: Waiting for modem to acquire network time... | ||
<inf> nrf_provisioning_sample: Network time obtained | ||
<inf> nrf_provisioning_http: Connected | ||
<inf> nrf_provisioning_http: No more commands to process on server side | ||
|
||
Dependencies | ||
************ | ||
|
||
This sample uses the following |NCS| libraries: | ||
|
||
* :ref:`lte_lc_readme` | ||
* :ref:`modem_info_readme` | ||
* :ref:`lib_nrf_provisioning` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Passive voice (be initialized) makes it unclear if this is something that I can automate, or if I need to initialize it manually.