diff --git a/samples/cellular/nrf_cloud_mqtt_multi_service/Kconfig b/samples/cellular/nrf_cloud_mqtt_multi_service/Kconfig index f32698fd9c4..52edbcabbb4 100644 --- a/samples/cellular/nrf_cloud_mqtt_multi_service/Kconfig +++ b/samples/cellular/nrf_cloud_mqtt_multi_service/Kconfig @@ -15,13 +15,6 @@ config POWER_SAVING_MODE_ENABLE help Enable to request Power Saving Mode from cellular network. -config LTE_INIT_RETRY_TIMEOUT_SECONDS - int "LTE initialization retry timeout (seconds)" - default 30 - help - Sets the number of seconds between each LTE modem initialization - retry. - config CLOUD_CONNECTION_RETRY_TIMEOUT_SECONDS int "Cloud connection retry timeout (seconds)" default 30 @@ -66,7 +59,7 @@ config MESSAGE_THREAD_STACK_SIZE config LED_THREAD_STACK_SIZE int "LED Thread Stack Size (bytes)" - default 512 + default 1024 help Sets the stack size (in bytes) for the LED thread. diff --git a/samples/cellular/nrf_cloud_mqtt_multi_service/overlay-nrf7002ek-wifi-scan-only.conf b/samples/cellular/nrf_cloud_mqtt_multi_service/overlay-nrf7002ek-wifi-scan-only.conf index 23e4fcb9299..fd47a6b7860 100644 --- a/samples/cellular/nrf_cloud_mqtt_multi_service/overlay-nrf7002ek-wifi-scan-only.conf +++ b/samples/cellular/nrf_cloud_mqtt_multi_service/overlay-nrf7002ek-wifi-scan-only.conf @@ -14,23 +14,17 @@ CONFIG_LOCATION_METHOD_WIFI=y CONFIG_LOCATION_METHOD_WIFI_SCANNING_RESULTS_MAX_CNT=60 CONFIG_LOCATION_WORKQUEUE_STACK_SIZE=8192 -# Enable Wi-Fi drivers, (and the native NET stack so that the location library can access them) +# Enable Wi-Fi drivers CONFIG_WIFI=y CONFIG_WIFI_NRF700X=y # Align this with CONFIG_LOCATION_METHOD_WIFI_SCANNING_RESULTS_MAX_CNT. # Also see comments for CONFIG_HEAP_MEM_POOL_SIZE. CONFIG_NRF700X_SCAN_LIMIT=60 CONFIG_NET_L2_ETHERNET=y -CONFIG_NET_NATIVE=y -# But disable the supplicant and local networking features, since we don't need connectivity +# But disable the supplicant, since we don't need connectivity CONFIG_WPA_SUPP=n CONFIG_MBEDTLS=n -CONFIG_NET_IPV4=n -CONFIG_NET_IPV6=n -CONFIG_NET_UDP=n -CONFIG_NET_TCP=n -CONFIG_NORDIC_SECURITY_BACKEND=n # Stack/heap tweaks needed to support Wi-Fi. # Wi-Fi shell sample has 25000 heap size. We need a bit more for location request purposes. diff --git a/samples/cellular/nrf_cloud_mqtt_multi_service/prj.conf b/samples/cellular/nrf_cloud_mqtt_multi_service/prj.conf index 22a3ed8b9c7..136f862a56f 100644 --- a/samples/cellular/nrf_cloud_mqtt_multi_service/prj.conf +++ b/samples/cellular/nrf_cloud_mqtt_multi_service/prj.conf @@ -16,7 +16,7 @@ CONFIG_NEWLIB_LIBC_FLOAT_PRINTF=y CONFIG_RESET_ON_FATAL_ERROR=y CONFIG_NCS_SAMPLES_DEFAULTS=y -#LED indication +# LED indication # Uncomment these to minimize LED state indication when power savings are necessary # CONFIG_LED_VERBOSE_INDICATION=n # CONFIG_LED_CONTINUOUS_INDICATION=n @@ -34,15 +34,27 @@ CONFIG_LOG_MODE_DEFERRED=y CONFIG_LOG_BUFFER_SIZE=4096 # Heap and stacks +CONFIG_AT_MONITOR_HEAP_SIZE=1024 # Extended memory heap size needed both for PGPS and for encoding JSON-based nRF Cloud Device Messages. CONFIG_HEAP_MEM_POOL_SIZE=24576 CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=3072 -# Network +# Enable Networking and Connection Manager. CONFIG_NETWORKING=y -CONFIG_NET_NATIVE=n CONFIG_NET_SOCKETS=y CONFIG_NET_SOCKETS_OFFLOAD=y +CONFIG_NET_MGMT_EVENT_STACK_SIZE=2048 +CONFIG_NET_CONNECTION_MANAGER_STACK_SIZE=1024 +CONFIG_MAIN_STACK_SIZE=2048 + +# Enable LTE Connectivity using Connection Manager +CONFIG_NET_IPV4=y +CONFIG_NET_IPV6=y +CONFIG_NET_IPV6_NBR_CACHE=n +CONFIG_NET_IPV6_MLD=n +CONFIG_NET_CONNECTION_MANAGER=y +CONFIG_LTE_CONNECTIVITY=y +CONFIG_NRF_MODEM_LIB_ON_FAULT_APPLICATION_SPECIFIC=y # Modem library CONFIG_NRF_MODEM_LIB=y diff --git a/samples/cellular/nrf_cloud_mqtt_multi_service/src/application.c b/samples/cellular/nrf_cloud_mqtt_multi_service/src/application.c index ba9c07f0fb1..d5a0ae219d3 100644 --- a/samples/cellular/nrf_cloud_mqtt_multi_service/src/application.c +++ b/samples/cellular/nrf_cloud_mqtt_multi_service/src/application.c @@ -14,14 +14,15 @@ #include #include "application.h" + #include "temperature.h" #include "cloud_connection.h" #include "message_queue.h" - #include "location_tracking.h" #include "led_control.h" #include "at_commands.h" + LOG_MODULE_REGISTER(application, CONFIG_MQTT_MULTI_SERVICE_LOG_LEVEL); /* Timer used to time the sensor sampling rate. */ diff --git a/samples/cellular/nrf_cloud_mqtt_multi_service/src/cloud_connection.c b/samples/cellular/nrf_cloud_mqtt_multi_service/src/cloud_connection.c index 986d9483615..20afc6b50df 100644 --- a/samples/cellular/nrf_cloud_mqtt_multi_service/src/cloud_connection.c +++ b/samples/cellular/nrf_cloud_mqtt_multi_service/src/cloud_connection.c @@ -218,104 +218,35 @@ static void update_shadow(void) /* External event handlers */ -/** - * @brief Handler for LTE events coming from modem. - * - * @param evt Events from modem. +/* Handler for L4/connectivity events + * This allows the cloud module to react to network gain and loss. + * The conn_mgr subsystem is responsible for seeking / maintaining network connectivity and + * firing these events. */ -static void lte_event_handler(const struct lte_lc_evt *const evt) +struct net_mgmt_event_callback l4_callback; +static void l4_event_handler(struct net_mgmt_event_callback *cb, + uint32_t event, struct net_if *iface) { - switch (evt->type) { - case LTE_LC_EVT_NW_REG_STATUS: - LOG_DBG("LTE_EVENT: Network registration status %d, %s", evt->nw_reg_status, - evt->nw_reg_status == LTE_LC_NW_REG_NOT_REGISTERED ? "Not Registered" : - evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_HOME ? "Registered Home" : - evt->nw_reg_status == LTE_LC_NW_REG_SEARCHING ? "Searching" : - evt->nw_reg_status == LTE_LC_NW_REG_REGISTRATION_DENIED ? - "Registration Denied" : - evt->nw_reg_status == LTE_LC_NW_REG_UNKNOWN ? "Unknown" : - evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_ROAMING ? - "Registered Roaming" : - evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_EMERGENCY ? - "Registered Emergency" : - evt->nw_reg_status == LTE_LC_NW_REG_UICC_FAIL ? "UICC Fail" : - "Invalid"); - - if ((evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_HOME) && - (evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_ROAMING)) { - LOG_INF("Network connectivity lost!"); - - /* Clear the network ready flag */ - k_event_clear(&cloud_events, NETWORK_READY); - - /* Disconnect from cloud as well. */ - disconnect_cloud(); - } else { - LOG_INF("Network connectivity gained!"); + if (event == NET_EVENT_L4_CONNECTED) { + LOG_INF("Network connectivity gained!"); - /* Set the network ready flag */ - k_event_post(&cloud_events, NETWORK_READY); - } + /* Set the network ready flag */ + k_event_post(&cloud_events, NETWORK_READY); - break; - case LTE_LC_EVT_PSM_UPDATE: - LOG_DBG("LTE_EVENT: PSM parameter update: TAU: %d, Active time: %d", - evt->psm_cfg.tau, evt->psm_cfg.active_time); - break; - case LTE_LC_EVT_EDRX_UPDATE: { - /* This check is necessary to silence compiler warnings by - * sprintf when debug logs are not enabled. - */ - if (IS_ENABLED(CONFIG_MQTT_MULTI_SERVICE_LOG_LEVEL_DBG)) { - char log_buf[60]; - ssize_t len; - - len = snprintf(log_buf, sizeof(log_buf), - "LTE_EVENT: eDRX parameter update: eDRX: %f, PTW: %f", - evt->edrx_cfg.edrx, evt->edrx_cfg.ptw); - if (len > 0) { - LOG_DBG("%s", log_buf); - } - } - break; - } - case LTE_LC_EVT_RRC_UPDATE: - LOG_DBG("LTE_EVENT: RRC mode: %s", - evt->rrc_mode == LTE_LC_RRC_MODE_CONNECTED ? - "Connected" : "Idle"); - break; - case LTE_LC_EVT_CELL_UPDATE: - LOG_DBG("LTE_EVENT: LTE cell changed: Cell ID: %d, Tracking area: %d", - evt->cell.id, evt->cell.tac); - break; - case LTE_LC_EVT_LTE_MODE_UPDATE: - LOG_DBG("LTE_EVENT: Active LTE mode changed: %s", - evt->lte_mode == LTE_LC_LTE_MODE_NONE ? "None" : - evt->lte_mode == LTE_LC_LTE_MODE_LTEM ? "LTE-M" : - evt->lte_mode == LTE_LC_LTE_MODE_NBIOT ? "NB-IoT" : - "Unknown"); - break; - case LTE_LC_EVT_MODEM_EVENT: - LOG_DBG("LTE_EVENT: Modem domain event, type: %s", - evt->modem_evt == LTE_LC_MODEM_EVT_LIGHT_SEARCH_DONE ? - "Light search done" : - evt->modem_evt == LTE_LC_MODEM_EVT_SEARCH_DONE ? - "Search done" : - evt->modem_evt == LTE_LC_MODEM_EVT_RESET_LOOP ? - "Reset loop detected" : - evt->modem_evt == LTE_LC_MODEM_EVT_BATTERY_LOW ? - "Low battery" : - evt->modem_evt == LTE_LC_MODEM_EVT_OVERHEATED ? - "Modem is overheated" : - "Unknown"); - break; - default: - break; + + } else if (event == NET_EVENT_L4_DISCONNECTED) { + LOG_INF("Network connectivity lost!"); + + /* Clear the network ready flag */ + k_event_clear(&cloud_events, NETWORK_READY); + + /* Disconnect from cloud as well. */ + disconnect_cloud(); } } /* Handler for date_time library events, used to keep track of whether the current time is known */ -static void date_time_evt_handler(const struct date_time_evt *date_time_evt) +static void date_time_event_handler(const struct date_time_evt *date_time_evt) { if (date_time_is_valid()) { k_event_post(&cloud_events, DATE_TIME_KNOWN); @@ -448,52 +379,35 @@ static void cloud_event_handler(const struct nrf_cloud_evt *nrf_cloud_evt) } /** - * @brief Set up the modem library. + * @brief Set up for the nRF Cloud connection (without connecting) + * + * Sets up required event hooks and initializes the nrf_cloud library. * - * @return int - 0 on success, otherwise a negative error code. + * @return int - 0 on success, otherwise negative error code. */ -static int setup_modem(void) +static int setup_cloud(void) { - int ret; - - /* - * If there is a pending modem delta firmware update stored, nrf_modem_lib_init will - * attempt to install it before initializing the modem library, and return a - * positive value to indicate that this occurred. This code can be used to - * determine whether the update was successful. + /* Register to be notified of network availability changes. + * + * If the chosen connectivity layer becomes ready instantaneously, it is possible that + * L4_CONNECTED will be fired before reaching this function, in which case we will miss + * the notification. + * + * If that is a serious concern, use SYS_INIT with priority 0 (less than + * CONFIG_NET_CONNECTION_MANAGER_PRIORITY) to register this hook before conn_mgr + * initializes. + * + * In reality, connectivity layers such as LTE take some time to go online, so registering + * the hook here is fine. */ - ret = nrf_modem_lib_init(); - - if (ret < 0) { - LOG_ERR("Modem library initialization failed, error: %d", ret); - return ret; - } else if (ret == NRF_MODEM_DFU_RESULT_OK) { - LOG_DBG("Modem library initialized after " - "successful modem firmware update."); - } else if (ret > 0) { - LOG_ERR("Modem library initialized after " - "failed modem firmware update, error: %d", ret); - } else { - LOG_DBG("Modem library initialized."); - } + net_mgmt_init_event_callback( + &l4_callback, l4_event_handler, NET_EVENT_L4_CONNECTED | NET_EVENT_L4_DISCONNECTED + ); + net_mgmt_add_event_callback(&l4_callback); /* Register to be notified when the modem has figured out the current time. */ - date_time_register_handler(date_time_evt_handler); + date_time_register_handler(date_time_event_handler); - return 0; -} - - -/** - * @brief Set up the nRF Cloud library - * - * Call this before setup_network so that any pending FOTA job is handled first. - * This avoids calling setup_network pointlessly right before a FOTA-initiated reboot. - * - * @return int - 0 on success, otherwise negative error code. - */ -static int setup_cloud(void) -{ /* Initialize nrf_cloud library. */ struct nrf_cloud_init_param params = { .event_handler = cloud_event_handler, @@ -511,70 +425,10 @@ static int setup_cloud(void) return 0; } -/** - * @brief Set up network and start trying to connect. - * - * @return int - 0 on success, otherwise a negative error code. - */ -static int setup_network(void) -{ - int err; - - /* Perform Configuration */ - if (IS_ENABLED(CONFIG_POWER_SAVING_MODE_ENABLE)) { - /* Requesting PSM before connecting allows the modem to inform - * the network about our wish for certain PSM configuration - * already in the connection procedure instead of in a separate - * request after the connection is in place, which may be - * rejected in some networks. - */ - LOG_INF("Requesting PSM mode"); - - err = lte_lc_psm_req(true); - if (err) { - LOG_ERR("Failed to set PSM parameters, error: %d", err); - return err; - } else { - LOG_INF("PSM mode requested"); - } - } - - /* Modem events must be enabled before we can receive them. */ - err = lte_lc_modem_events_enable(); - if (err) { - LOG_ERR("lte_lc_modem_events_enable failed, error: %d", err); - return err; - } - - /* Init the modem, and start keeping an active connection. - * Note that if connection is lost, the modem will automatically attempt to - * re-establish it after this call. - */ - LOG_INF("Starting connection to LTE network..."); - err = lte_lc_init_and_connect_async(lte_event_handler); - if (err) { - LOG_ERR("Modem could not be configured, error: %d", err); - return err; - } - - return 0; -} - void cloud_connection_thread_fn(void) { long_led_pattern(LED_WAITING); - /* Enable the modem */ - LOG_INF("Setting up modem..."); - if (setup_modem()) { - LOG_ERR("Fatal: Modem setup failed"); - long_led_pattern(LED_FAILURE); - return; - } - - /* The nRF Cloud library need only be initialized once, and does not need to be reset - * under any circumstances, even error conditions. - */ LOG_INF("Setting up nRF Cloud library..."); if (setup_cloud()) { LOG_ERR("Fatal: nRF Cloud library setup failed"); @@ -582,18 +436,6 @@ void cloud_connection_thread_fn(void) return; } - /* Set up network and start trying to connect. - * This is done once only, since the network implementation should handle network - * persistence then after. (Once we request connection, it will automatically try to - * reconnect whenever connection is lost). - */ - LOG_INF("Setting up network..."); - if (setup_network()) { - LOG_ERR("Fatal: Network setup failed"); - long_led_pattern(LED_FAILURE); - return; - } - /* Indefinitely maintain a connection to nRF Cloud whenever the network is reachable. */ while (true) { LOG_INF("Waiting for network ready..."); diff --git a/samples/cellular/nrf_cloud_mqtt_multi_service/src/location_tracking.c b/samples/cellular/nrf_cloud_mqtt_multi_service/src/location_tracking.c index 4323c20177c..37ff8955e48 100644 --- a/samples/cellular/nrf_cloud_mqtt_multi_service/src/location_tracking.c +++ b/samples/cellular/nrf_cloud_mqtt_multi_service/src/location_tracking.c @@ -9,6 +9,7 @@ #include #include #include +#include #include "location_tracking.h" @@ -50,10 +51,18 @@ int start_location_tracking(location_update_cb_t handler_cb, int interval) { int err; + LOG_DBG("Starting location tracking"); + if (!date_time_is_valid()) { LOG_WRN("Date and time unknown. Location Services results may suffer"); } + /* Enable GNSS on the modem */ + err = lte_lc_func_mode_set(LTE_LC_FUNC_MODE_ACTIVATE_GNSS); + if (err) { + LOG_ERR("Activating GNSS failed, error: %d. Continuing without GNSS", err); + } + /* Update the location update handler. */ location_update_handler = handler_cb; diff --git a/samples/cellular/nrf_cloud_mqtt_multi_service/src/message_queue.c b/samples/cellular/nrf_cloud_mqtt_multi_service/src/message_queue.c index 495fd029a87..a4184d1749d 100644 --- a/samples/cellular/nrf_cloud_mqtt_multi_service/src/message_queue.c +++ b/samples/cellular/nrf_cloud_mqtt_multi_service/src/message_queue.c @@ -4,7 +4,6 @@ */ #include -#include #include #include #include @@ -81,9 +80,9 @@ static void free_queued_dev_msg_message(struct nrf_cloud_obj *msg_obj) } /** - * @brief Consume (attempt to send) a single device message from the device message queue. Will wait - * until connection to nRF Cloud is established before actually sending. If message fails - * to send, it will be dropped. + * @brief Consume (attempt to send) a single device message from the device message queue. + * Waits for nRF Cloud readiness before sending each message. + * If the message fails to send, it will be reenqueued. * * @return int - 0 on success, otherwise negative error code. */