Skip to content

Commit ebef25a

Browse files
committed
modules: cloud: integrate nRF Cloud CoAP connectivity module
Integrate and adapt cloud module from Asset Tracker Template v1.1.1 providing: - State machine-based nRF Cloud CoAP connectivity management - ZBUS communication with sensor and network modules - Automatic sensor data transmission to nRF Cloud - Connection management with exponential/linear backoff strategies - Device shadow support and shell commands for cloud interaction - Watchdog integration and comprehensive error handling - Replace app_fatal_error.h with app_common.h for enhanced error handling Includes all necessary nRF Cloud configuration, CoAP client setup, and integration with existing fire detection system architecture. Refs: #21 Signed-off-by: Natalia Pluta <pluta.natalia.m@gmail.com>
1 parent 37d0d86 commit ebef25a

13 files changed

Lines changed: 1382 additions & 51 deletions

app/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,11 @@ target_sources(app PRIVATE
1313
src/main.c
1414
)
1515

16-
# Add modules subdirectories
16+
# Include modules
1717
add_subdirectory(src/modules/controller)
1818
add_subdirectory(src/modules/sensor)
1919
add_subdirectory(src/modules/network)
20+
add_subdirectory(src/modules/cloud)
2021

2122
# Add include directories for modules
2223
target_include_directories(app PRIVATE src)

app/Kconfig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ rsource "src/modules/controller/Kconfig.controller"
2121
# Include network module configuration
2222
rsource "src/modules/network/Kconfig.network"
2323

24+
# Include cloud module configuration
25+
rsource "src/modules/cloud/Kconfig.cloud"
26+
2427
endmenu
2528

2629
module = APP

app/prj.conf

Lines changed: 58 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,14 @@
33
#
44
# This file contains selected Kconfig options for the application.
55

6+
# Enable logging with debug level
7+
# CONFIG_NET_LOG=y
8+
# CONFIG_NRF_CLOUD_LOG_LEVEL_DBG=y
9+
# CONFIG_CLOUD_MODULE_LOG_LEVEL_DBG=y
10+
# CONFIG_NRF_CLOUD_COAP_LOG_LEVEL_DBG=y
11+
# CONFIG_MODEM_KEY_MGMT_LOG_LEVEL_DBG=y
12+
# CONFIG_LOG_BUFFER_SIZE=10000
13+
614
CONFIG_LOG=y
715
CONFIG_BLINK=y
816
CONFIG_HEAP_MEM_POOL_SIZE=10240
@@ -45,7 +53,6 @@ CONFIG_LTE_LINK_CONTROL=y
4553
CONFIG_LTE_LC_PSM_MODULE=y
4654
CONFIG_LTE_LC_EDRX_MODULE=y
4755
CONFIG_LTE_LC_CONN_EVAL_MODULE=y
48-
CONFIG_MODEM_INFO=y
4956

5057
# Nordic Modem Library
5158
CONFIG_NRF_MODEM_LIB=y
@@ -67,13 +74,60 @@ CONFIG_NET_IPV6_MLD=n
6774
CONFIG_NET_CONNECTION_MANAGER=y
6875
CONFIG_NET_CONNECTION_MANAGER_MONITOR_STACK_SIZE=512
6976

77+
# Needed due to using connectivity manager
78+
CONFIG_NET_IF_MAX_IPV6_COUNT=2
79+
CONFIG_NET_IF_MAX_IPV4_COUNT=2
80+
7081
# Network statistics (useful for debugging)
7182
CONFIG_NET_STATISTICS=y
7283
CONFIG_NET_STATISTICS_USER_API=y
7384
CONFIG_NET_CONTEXT_SYNC_RECV=y
7485

86+
# nRF Cloud
87+
CONFIG_NRF_CLOUD=y
88+
CONFIG_NRF_CLOUD_COAP=y
89+
CONFIG_NRF_CLOUD_COAP_DISCONNECT_ON_FAILED_REQUEST=y
90+
CONFIG_NRF_CLOUD_PRINT_DETAILS=y
91+
CONFIG_NRF_CLOUD_SEND_DEVICE_STATUS=y
92+
CONFIG_NRF_CLOUD_SEND_DEVICE_STATUS_NETWORK=y
93+
CONFIG_NRF_CLOUD_SEND_DEVICE_STATUS_SIM=y
94+
CONFIG_NRF_CLOUD_SEND_SERVICE_INFO_FOTA=y
95+
96+
# Modem
97+
CONFIG_MODEM_JWT=y
98+
CONFIG_MODEM_INFO=y
99+
CONFIG_MODEM_INFO_ADD_DEVICE=y
100+
CONFIG_MODEM_KEY_MGMT=y
101+
102+
103+
# Credentials
104+
CONFIG_NRF_CLOUD_CLIENT_ID_SRC_IMEI=y # Use IMEI for Client ID as INTERNAL_UUID requires nRF91x1
105+
CONFIG_NRF_CLOUD_CHECK_CREDENTIALS=y
106+
CONFIG_NRF_CLOUD_CREDENTIALS_MGMT_MODEM=y
107+
108+
# COAP client
109+
CONFIG_COAP=y
110+
CONFIG_COAP_CLIENT=y
111+
CONFIG_COAP_MAX_RETRANSMIT=5
112+
CONFIG_COAP_INIT_ACK_TIMEOUT_MS=5000
113+
# Set CoAP therad to same priority as other modules
114+
CONFIG_COAP_CLIENT_THREAD_PRIORITY=14
115+
CONFIG_COAP_CLIENT_BLOCK_SIZE=1024
116+
CONFIG_COAP_CLIENT_MESSAGE_SIZE=1024
117+
CONFIG_COAP_CLIENT_STACK_SIZE=1280
118+
CONFIG_COAP_EXTENDED_OPTIONS_LEN_VALUE=192
119+
CONFIG_NRF_CLOUD_COAP_DOWNLOADS=y
120+
121+
# Downloader support (required by NRF_CLOUD_COAP_DOWNLOADS)
122+
CONFIG_DOWNLOADER=y
123+
124+
# needed for processing floats
125+
CONFIG_PICOLIBC=y
126+
CONFIG_FPU=y
127+
75128
# Date and time configuration
76129
CONFIG_DATE_TIME=y
130+
CONFIG_DATE_TIME_MODEM=y
77131
CONFIG_DATE_TIME_AUTO_UPDATE=y
78132

79133
# AT Monitor configuration to prevent heap exhaustion
@@ -90,4 +144,6 @@ CONFIG_SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE=2048
90144
CONFIG_AT_SHELL=y
91145

92146
# Task Watchdog
93-
CONFIG_TASK_WDT=y
147+
CONFIG_TASK_WDT=y
148+
CONFIG_TASK_WDT_CHANNELS=8
149+
CONFIG_TASK_WDT_MIN_TIMEOUT=10000

app/src/app_common.h

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
#ifndef _APP_COMMON_H_
8+
#define _APP_COMMON_H_
9+
10+
#include <zephyr/kernel.h>
11+
#include <zephyr/logging/log_ctrl.h>
12+
#include <zephyr/sys/util.h> /* For Zephyr's utility macros, including MAX */
13+
#if defined(CONFIG_MEMFAULT)
14+
#include <memfault/panics/assert.h>
15+
#endif
16+
17+
#ifdef __cplusplus
18+
extern "C" {
19+
#endif
20+
21+
/** @brief Handle fatal error.
22+
* @param is_watchdog_timeout Boolean indicating if the macro was called upon a watchdog timeout.
23+
*/
24+
#define FATAL_ERROR_HANDLE(is_watchdog_timeout) \
25+
do { \
26+
LOG_PANIC(); \
27+
if (is_watchdog_timeout) { \
28+
IF_ENABLED(CONFIG_MEMFAULT, (MEMFAULT_SOFTWARE_WATCHDOG())); \
29+
} \
30+
k_sleep(K_SECONDS(10)); \
31+
__ASSERT(false, "SEND_FATAL_ERROR() macro called"); \
32+
} while (0)
33+
34+
/** @brief Macro used to handle fatal errors. */
35+
#define SEND_FATAL_ERROR() FATAL_ERROR_HANDLE(0)
36+
37+
/** @brief Macro used to handle watchdog timeouts. */
38+
#define SEND_FATAL_ERROR_WATCHDOG_TIMEOUT() FATAL_ERROR_HANDLE(1)
39+
40+
/* Helper macros for computing MAX with different numbers of arguments */
41+
#define MAX_1(a1) (a1)
42+
#define MAX_2(a1, a2) MAX(a1, a2)
43+
#define MAX_3(a1, a2, a3) MAX(MAX_2(a1, a2), a3)
44+
#define MAX_4(a1, a2, a3, a4) MAX(MAX_3(a1, a2, a3), a4)
45+
#define MAX_5(a1, a2, a3, a4, a5) MAX(MAX_4(a1, a2, a3, a4), a5)
46+
#define MAX_6(a1, a2, a3, a4, a5, a6) MAX(MAX_5(a1, a2, a3, a4, a5), a6)
47+
#define MAX_7(a1, a2, a3, a4, a5, a6, a7) MAX(MAX_6(a1, a2, a3, a4, a5, a6), a7)
48+
#define MAX_8(a1, a2, a3, a4, a5, a6, a7, a8) MAX(MAX_7(a1, a2, a3, a4, a5, a6, a7), a8)
49+
#define MAX_9(a1, a2, a3, a4, a5, a6, a7, a8, a9) MAX(MAX_8(a1, a2, a3, a4, a5, a6, a7, a8), a9)
50+
#define MAX_10(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10) \
51+
MAX(MAX_9(a1, a2, a3, a4, a5, a6, a7, a8, a9), a10)
52+
53+
#define SELECT_MAX_N(N) CONCAT(MAX_, N)
54+
55+
/**
56+
* @brief Macro to compute the maximum of a list of numbers.
57+
*
58+
* @param ... List of numbers to compute the maximum of.
59+
*/
60+
#define MAX_N(...) SELECT_MAX_N(NUM_VA_ARGS(__VA_ARGS__))(__VA_ARGS__)
61+
62+
/**
63+
* @brief Helper macro for computing the size of a type.
64+
* The intended use is with X macros to generate a list of sizes for each type in a list of types.
65+
*
66+
* @param _chan Channel to compute the size of the type for.
67+
* @param _type Type to compute the size of.
68+
*
69+
* @return Size of the type.
70+
*/
71+
#define SIZE_OF_TYPE(_chan, _type) sizeof(_type),
72+
73+
/**
74+
* @brief Macro to compute the maximum message size from a list of channel date types.
75+
* The macro expands to a list of sizeof(type) for each channel's type, followed by a 0 to
76+
* account for the trailing comma when expanding SIZE_OF_TYPE
77+
* The MAX_N macro is used to find the maximum value in the list.
78+
* Example: MAX_N(sizeof(struct cloud_msg), sizeof(enum fota_msg_type), 0)
79+
80+
* @param _CHAN_LIST List of channels to compute the maximum message size from.
81+
* The list should be in the format: (CHANNEL_NAME, type)
82+
*
83+
* @return Maximum message size from the list of channels
84+
*/
85+
#define MAX_MSG_SIZE_FROM_LIST(_CHAN_LIST) MAX_N(_CHAN_LIST(SIZE_OF_TYPE) 0)
86+
87+
#ifdef __cplusplus
88+
}
89+
#endif
90+
91+
#endif /* _APP_COMMON_H_ */

app/src/app_fatal_error.h

Lines changed: 0 additions & 45 deletions
This file was deleted.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#
2+
# Copyright (c) 2024 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
target_sources(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/cloud_module.c)
8+
target_sources(app PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/cloud_shell.c)
9+
target_include_directories(app PRIVATE .)
10+
11+
if (CONFIG_NRF_CLOUD_COAP_SEC_TAG GREATER_EQUAL 2147483648 AND CONFIG_NRF_CLOUD_COAP_SEC_TAG LESS_EQUAL 2147483667)
12+
message(WARNING "CONFIG_NRF_CLOUD_COAP_SEC_TAG is set to a developer security tag. "
13+
"TLS traffic can now be decrypted with Nordic tools. "
14+
"This should only be used during development and testing.")
15+
endif()
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#
2+
# Copyright (c) 2024 Nordic Semiconductor
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
menuconfig CLOUD_MODULE
8+
bool "Cloud module"
9+
default y if NRF_CLOUD_COAP
10+
11+
if CLOUD_MODULE
12+
13+
config CLOUD_MODULE_SHELL
14+
bool "Enable cloud shell"
15+
default y if SHELL
16+
help
17+
Enable cloud shell commands.
18+
19+
config CLOUD_MODULE_PAYLOAD_BUFFER_MAX_SIZE
20+
int "Payload maximum buffer size"
21+
default 128
22+
help
23+
Maximum size of the buffer sent over the payload channel when sending RAW JSON messages
24+
to the cloud.
25+
26+
config CLOUD_MODULE_SHADOW_RESPONSE_BUFFER_MAX_SIZE
27+
int "Payload maximum buffer size"
28+
default 512
29+
help
30+
Maximum size of the buffer used to receive shadow responses from the cloud.
31+
32+
config CLOUD_MODULE_CONFIRMABLE_MESSAGES
33+
bool "Use confirmable messages"
34+
help
35+
Use confirmable messages for CoAP communications with nRF Cloud.
36+
Confirmable messages are retransmitted COAP_MAX_RETRANSMIT times
37+
until an acknowledgment is received.
38+
39+
config CLOUD_MODULE_BACKOFF_INITIAL_SECONDS
40+
int "Reconnection backoff time in seconds"
41+
default 60
42+
help
43+
Time in between reconnection attempts to the nRF Cloud CoAP server.
44+
The timer starts after the last failed attempt.
45+
46+
choice CLOUD_MODULE_BACKOFF_TYPE
47+
prompt "Reconnection backoff type"
48+
default CLOUD_MODULE_BACKOFF_TYPE_LINEAR
49+
50+
config CLOUD_MODULE_BACKOFF_TYPE_EXPONENTIAL
51+
bool "Exponential backoff"
52+
help
53+
Exponential backoff doubles the reconnection timeout after each failed attempt.
54+
The maximum reconnection timeout is defined by CLOUD_MODULE_BACKOFF_MAX_SECONDS.
55+
56+
config CLOUD_MODULE_BACKOFF_TYPE_LINEAR
57+
bool "Linear backoff"
58+
help
59+
Linear backoff adds a fixed amount of time to the reconnection timeout after each failed attempt,
60+
as defined by CLOUD_MODULE_BACKOFF_LINEAR_INCREMENT_SECONDS.
61+
62+
config CLOUD_MODULE_BACKOFF_TYPE_NONE
63+
bool "No backoff"
64+
help
65+
No backoff means that the reconnection timeout is constant at the value defined by
66+
CLOUD_MODULE_BACKOFF_INITIAL_SECONDS.
67+
68+
endchoice
69+
70+
config CLOUD_MODULE_BACKOFF_LINEAR_INCREMENT_SECONDS
71+
int "Reconnection backoff time increment"
72+
default 60
73+
help
74+
Time added to the reconnection timeout after each failed attempt in seconds.
75+
The maximum reconnection timeout is defined by CLOUD_MODULE_BACKOFF_MAX_SECONDS.
76+
77+
config CLOUD_MODULE_BACKOFF_MAX_SECONDS
78+
int "Maximum reconnection timeout"
79+
default 3600
80+
help
81+
Maximum reconnection backoff value in seconds.
82+
83+
config CLOUD_MODULE_THREAD_STACK_SIZE
84+
int "Thread stack size"
85+
default 6144
86+
87+
config CLOUD_MODULE_MESSAGE_QUEUE_SIZE
88+
int "Message queue size"
89+
default 5
90+
help
91+
ZBus subscriber message queue size.
92+
93+
config CLOUD_MODULE_WATCHDOG_TIMEOUT_SECONDS
94+
int "Watchdog timeout"
95+
default 180
96+
help
97+
Timeout in seconds for the cloud module watchdog.
98+
The timeout given in this option covers both:
99+
* Waiting for an incoming message in zbus_sub_wait_msg().
100+
* Time spent processing the message, defined by
101+
CONFIG_CLOUD_MODULE_MSG_PROCESSING_TIMEOUT_SECONDS.
102+
Ensure that this value exceeds CONFIG_CLOUD_MODULE_MSG_PROCESSING_TIMEOUT_SECONDS.
103+
A small difference between the two can mean more frequent watchdog feeds, which increases
104+
power consumption.
105+
106+
107+
config CLOUD_MODULE_MSG_PROCESSING_TIMEOUT_SECONDS
108+
int "Maximum message processing time"
109+
default 120
110+
help
111+
Maximum time allowed for processing a single message in the module's state machine.
112+
The value must be smaller than CONFIG_CLOUD_MODULE_WATCHDOG_TIMEOUT_SECONDS.
113+
114+
module = CLOUD_MODULE
115+
module-str = Cloud
116+
source "subsys/logging/Kconfig.template.log_config"
117+
118+
endif # CLOUD_MODULE

0 commit comments

Comments
 (0)