From 9bde2106fbfb67842fb05ec523b957fb806c193a Mon Sep 17 00:00:00 2001 From: Juha Ylinen Date: Wed, 5 Jul 2023 13:02:49 +0300 Subject: [PATCH] doc: provisioning: Add documentation Add documentation for nrf_provisioning library and sample. Update changelog. Signed-off-by: Juha Ylinen --- .../libraries/networking/nrf_provisioning.rst | 166 ++++++++++++++++++ doc/nrf/links.txt | 1 + .../releases/release-notes-changelog.rst | 9 +- samples/cellular/nrf_provisioning/README.rst | 141 +++++++++++++++ 4 files changed, 316 insertions(+), 1 deletion(-) create mode 100644 doc/nrf/libraries/networking/nrf_provisioning.rst create mode 100644 samples/cellular/nrf_provisioning/README.rst diff --git a/doc/nrf/libraries/networking/nrf_provisioning.rst b/doc/nrf/libraries/networking/nrf_provisioning.rst new file mode 100644 index 000000000000..daa2de56bbf4 --- /dev/null +++ b/doc/nrf/libraries/networking/nrf_provisioning.rst @@ -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 `_, 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="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<>Server [label="Provision: cmd1, cmd2, cmd3, finished"]; + 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<>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: diff --git a/doc/nrf/links.txt b/doc/nrf/links.txt index 00b429c261f4..7d4fb9447866 100644 --- a/doc/nrf/links.txt +++ b/doc/nrf/links.txt @@ -959,6 +959,7 @@ .. _`nRF Cloud MQTT FOTA`: https://docs.nrfcloud.com/Devices/FirmwareUpdate/FOTAOverview.html#mqtt-job-execution-notifications .. _`nRF Cloud Getting Started FOTA documentation`: https://docs.nrfcloud.com/Devices/FirmwareUpdate/FOTATutorial.html .. _`Securely generating credentials on the nRF9160`: https://docs.nrfcloud.com/Devices/Security/Credentials.html +.. _`nRF Cloud provisioning configuration`: https://docs.nrfcloud.com/SecurityServices/ProvisioningService/ProvisioningConfiguration/ProvisioningConfigurationPortal.html .. _`nRF Cloud REST API`: .. _`nRF Connect for Cloud REST API`: https://docs.nrfcloud.com/APIs/REST/RESTOverview.html .. _`nRF Cloud Location Services documentation`: https://docs.nrfcloud.com/LocationServices/LSOverview.html diff --git a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst index 764a9ed68de9..b56448306b76 100644 --- a/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst +++ b/doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst @@ -297,7 +297,10 @@ Cellular samples (renamed from nRF9160 samples) * Renamed nRF9160 samples to cellular samples and are now found in the :file:`samples/cellular` folder. -* Added the :ref:`battery` sample to show how to use the :ref:`modem_battery_readme` library. +* Added: + + * The :ref:`battery` sample to show how to use the :ref:`modem_battery_readme` library. + * The :ref:`nrf_provisioning_sample` sample that demonstrates how to use the :ref:`lib_nrf_provisioning` service. * :ref:`nrf_cloud_mqtt_multi_service` sample: @@ -513,6 +516,10 @@ Modem libraries Libraries for networking ------------------------ +* Added + + * The :ref:`lib_nrf_provisioning` library for device provisioning. + * Multicell location library: * This library is now removed and relevant functionality is available through the :ref:`lib_location` library. diff --git a/samples/cellular/nrf_provisioning/README.rst b/samples/cellular/nrf_provisioning/README.rst new file mode 100644 index 000000000000..a671c5d15c01 --- /dev/null +++ b/samples/cellular/nrf_provisioning/README.rst @@ -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. + +User interface +************** + +Device side interaction is not required. +You must define the provisioning configuration at the server side. +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 + + nrf_provisioning_sample: Establishing LTE link ... + nrf_provisioning_http: Connected + 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 + + nrf_provisioning_sample: Establishing LTE link ... + nrf_provisioning_http: Connected + nrf_provisioning: Disconnected from network - provisioning paused + nrf_provisioning: Connected; home network - provisioning resumed + nrf_provisioning_sample: Modem connection restored + nrf_provisioning_sample: Waiting for modem to acquire network time... + nrf_provisioning_sample: Network time obtained + nrf_provisioning_http: Connected + 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`