|
1 | 1 | # Cloud module |
2 | 2 |
|
3 | | -What does this module do |
| 3 | +This module connects and manages communication with [nRF Cloud](https://www.nrfcloud.com/) over CoAP using [nRF Cloud CoAP library](https://docs.nordicsemi.com/bundle/ncs-latest/page/nrf/libraries/networking/nrf_cloud_coap.html) in nRF Connect SDK. It controls the cloud connection, sends data to nRF Cloud, and processes incoming data such as device shadow document. The cloud module uses Zephyr’s state machine framework (SMF) and zbus for messaging with other modules. |
| 4 | + |
| 5 | +The module's responsibilities include: |
| 6 | + |
| 7 | +- Establishing and maintaining a connection to nRF Cloud, using CoAP with DTLS connection ID for secure and low-power communication. |
| 8 | +- Managing backoff and retries when connecting to the cloud. See the [Configurations](#configurations) section for more details on how to configure backoff behavior. |
| 9 | +- Publishing sensor data (temperature, pressure, connection quality, etc.) to nRF Cloud. The data is received on the `ENVIRONMENTAL_CHAN` channel when the environmental module publishes it. |
| 10 | +- Requesting and handling shadow updates. Polling the device shadow is triggered by the main module by sending a `CLOUD_POLL_SHADOW` message. |
| 11 | +- Handling network events and transitioning between connection states as described in the [State diagram](#state-diagram) section. |
| 12 | + |
| 13 | +nRF Cloud over CoAP utilizes DTLS connection ID which allows the device to quickly re-establish a secure connection with the cloud after a network disconnection without the need for a full DTLS handshake. The module uses the nRF Cloud CoAP library to handle the CoAP communication and DTLS connection management. |
| 14 | + |
| 15 | +Below, the module’s main messages, configurations, and state machine are covered. Refer to the source files (`cloud_module.c`, `cloud_module.h`, and `Kconfig.cloud`) for implementation details. |
4 | 16 |
|
5 | 17 | ## Messages |
6 | 18 |
|
| 19 | +The cloud module publishes and receives messages over the zbus channel `CLOUD_CHAN`. All module message types are defined in `cloud_module.h` and used within `cloud_module.c`. |
| 20 | + |
| 21 | +### Input Messages |
| 22 | + |
| 23 | +- **CLOUD_POLL_SHADOW** |
| 24 | + Instructs the module to poll the device shadow on nRF Cloud. The device shadow may contain configuration updates for the device. |
| 25 | + |
| 26 | +- **CLOUD_PAYLOAD_JSON** |
| 27 | + Sends raw JSON data to nRF Cloud. |
| 28 | + |
| 29 | +### Output Messages |
| 30 | + |
| 31 | +- **CLOUD_DISCONNECTED** |
| 32 | + Indicates that the cloud connection is not established (or has been lost). |
| 33 | + |
| 34 | +- **CLOUD_CONNECTED** |
| 35 | + Indicates that the module is connected to nRF Cloud and ready to send data. |
| 36 | + |
| 37 | +- **CLOUD_SHADOW_RESPONSE** |
| 38 | + Returns shadow data or a shadow delta received from nRF Cloud. |
| 39 | + |
| 40 | +The message structure used by the cloud module is defined in `cloud_module.h`: |
| 41 | + |
| 42 | +```c |
| 43 | +struct cloud_msg { |
| 44 | + enum cloud_msg_type type; |
| 45 | + union { |
| 46 | + struct cloud_payload payload; |
| 47 | + struct cloud_shadow_response response; |
| 48 | + }; |
| 49 | +}; |
| 50 | +``` |
| 51 | + |
7 | 52 | ## Configurations |
8 | 53 |
|
9 | | -Kconfig and device tree |
| 54 | +Several Kconfig options in `Kconfig.cloud` control this module’s behavior. Below are some notable ones: |
| 55 | + |
| 56 | +- **CONFIG_APP_CLOUD_SHELL** |
| 57 | + Enables shell support for cloud operations. |
| 58 | + |
| 59 | +- **CONFIG_APP_CLOUD_PAYLOAD_BUFFER_MAX_SIZE** |
| 60 | + Defines the maximum size for JSON payloads sent to the cloud. |
| 61 | + |
| 62 | +- **CONFIG_APP_CLOUD_SHADOW_RESPONSE_BUFFER_MAX_SIZE** |
| 63 | + Sets the maximum buffer size for receiving shadow data. |
| 64 | + |
| 65 | +- **CONFIG_APP_CLOUD_CONFIRMABLE_MESSAGES** |
| 66 | + Uses confirmable CoAP messages for reliability. |
| 67 | + |
| 68 | +- **CONFIG_APP_CLOUD_BACKOFF_INITIAL_SECONDS** |
| 69 | + Starting delay (in seconds) before reconnect attempts. |
| 70 | + |
| 71 | +- **CONFIG_APP_CLOUD_BACKOFF_TYPE** |
| 72 | + Specifies backoff strategy (none, linear, or exponential). |
| 73 | + |
| 74 | +- **CONFIG_APP_CLOUD_BACKOFF_TYPE_EXPONENTIAL** |
| 75 | + Use exponential backoff time. The backoff time is doubled after each failed attempt until the |
| 76 | + maximum backoff time is reached. |
| 77 | + |
| 78 | +- **CONFIG_APP_CLOUD_BACKOFF_TYPE_LINEAR** |
| 79 | + Use linear backoff time. The backoff time is incremented by a fixed amount after each failed attempt until |
| 80 | + the maximum backoff time is reached. |
| 81 | + |
| 82 | +- **CONFIG_APP_CLOUD_BACKOFF_LINEAR_INCREMENT_SECONDS** |
| 83 | + If using linear backoff, defines how much time to add after each failed attempt. |
| 84 | + |
| 85 | +- **CONFIG_APP_CLOUD_BACKOFF_MAX_SECONDS** |
| 86 | + Maximum reconnect backoff limit. |
| 87 | + |
| 88 | +- **CONFIG_APP_CLOUD_THREAD_STACK_SIZE** |
| 89 | + Stack size for the cloud module’s main thread. |
| 90 | + |
| 91 | +- **CONFIG_APP_CLOUD_MESSAGE_QUEUE_SIZE** |
| 92 | + Zbus message queue size. |
| 93 | + |
| 94 | +- **CONFIG_APP_CLOUD_WATCHDOG_TIMEOUT_SECONDS** |
| 95 | + Watchdog timeout for the module’s thread. Must be larger than the message processing timeout. |
| 96 | + |
| 97 | +- **CONFIG_APP_CLOUD_MSG_PROCESSING_TIMEOUT_SECONDS** |
| 98 | + Maximum time allowed for processing a single incoming message. |
| 99 | + |
| 100 | +For more details on these and other configurations, refer to `Kconfig.cloud`. |
10 | 101 |
|
11 | 102 | ## State diagram |
| 103 | + |
| 104 | +Below is a simplified representation of the state machine implemented in `cloud_module.c`. The module starts in the **STATE_RUNNING** context, which immediately transitions to **STATE_DISCONNECTED** upon initialization. From there, network events and internal conditions drive state transitions. |
| 105 | + |
| 106 | +```mermaid |
| 107 | +stateDiagram-v2 |
| 108 | + [*] --> STATE_RUNNING |
| 109 | +
|
| 110 | + STATE_RUNNING --> STATE_DISCONNECTED: NETWORK_DISCONNECTED |
| 111 | +
|
| 112 | + state STATE_RUNNING { |
| 113 | + [*] --> STATE_DISCONNECTED |
| 114 | +
|
| 115 | + STATE_DISCONNECTED --> STATE_CONNECTING: NETWORK_CONNECTED |
| 116 | +
|
| 117 | + STATE_CONNECTING --> STATE_CONNECTED: CLOUD_CONN_SUCCESS |
| 118 | +
|
| 119 | + state STATE_CONNECTING { |
| 120 | + [*] --> STATE_CONNECTING_ATTEMPT |
| 121 | +
|
| 122 | + STATE_CONNECTING_ATTEMPT --> STATE_CONNECTING_BACKOFF: CLOUD_CONN_FAILED |
| 123 | + STATE_CONNECTING_BACKOFF --> STATE_CONNECTING_ATTEMPT: CLOUD_BACKOFF_EXPIRED |
| 124 | + } |
| 125 | +
|
| 126 | + state STATE_CONNECTED { |
| 127 | + [*] --> STATE_CONNECTED_READY_TO_SEND |
| 128 | +
|
| 129 | + STATE_CONNECTED_READY_TO_SEND --> STATE_CONNECTED_PAUSED: NETWORK_DISCONNECTED |
| 130 | + STATE_CONNECTED_PAUSED --> STATE_CONNECTED_READY_TO_SEND: NETWORK_CONNECTED |
| 131 | + } |
| 132 | + } |
| 133 | +``` |
0 commit comments