How to close down nrf9161 so that it reconnects COAP quickly

Hi,

I wonder if anybody could help me? What is the best way to close down the nrf9161 so that it reconnects quickly after powering back up again?

I'm running Zephyr 2.6 on a custom board we are developing.

I've seen a lot of chatter about the modem saving settings (e.g. by calling nrf_modem_lib_shutdown) - but it doesn't seem to work. If I shut the system down "mid-connection" it seems to reconnect quickly - although it does then seem to suffer from the , However, if I let it shut down "gracefully", it can take an age to reconnect.

Here is my "main" loop - the system connects, works for a while and then, when finished, powers down the modem and sleeps forever so that it can be powered off.

#include "main.h"

LOG_MODULE_REGISTER(nrf_whisper1, LOG_LEVEL_INF);

// Device details
static wcp_display_settings disp_settings;

int main(void)
{
	int err;
	bool modem_connected = false;

	LOG_INF("Stating nrf_whisper, version: %s", CONFIG_APP_VERSION);

	:

	nrf_modem_lib_dfu_handler();

	// Get hardware settings off modem
	update_imei (&disp_settings);
	set_default_coap_addresses (&disp_settings);

	LOG_INF("Configure Modem");
	err = modem_connect();
	if (err) {
		LOG_ERR("Failed to configure the modem");
		return 0;
	}

	LOG_INF("Resolve Server");
	int res = 1;
	while (res != 0) {
		res = server_resolve();
		if (res != 0) {
			LOG_INF("Failed to resolve server name - retry in 1 second");
			k_msleep(1000);
		}
	}

	// If we get here - LTE is already connected, so don't need to reconnect in toop.
	modem_connected = true;

	init_display ();

	disp_settings.poll_counter = 1;

	bool init_cmd_run = false;
	while (disp_settings.poll_counter != 0) {

		if (disp_settings.poll_counter > 0) {
			disp_settings.poll_counter--;
		}
		if (disp_settings.input_type != UART_INPUT_TYPE) {
			// If LTE isn't already connected - connect up
			if (!modem_connected) {
				LOG_INF("Connect to Modem");
				err = lte_lc_func_mode_set(LTE_LC_FUNC_MODE_NORMAL);
				if (err != 0){
					LOG_ERR("Failed to activate LTE");
					break;
				}

				LOG_INF("Waiting for LTE connection");
				// Wait until the modem is connected to the network until continuing
				wait_for_modem_connection ();
				modem_connected = true;
			}
		}

		// Update the current time
		update_time (&disp_settings);

		if ((disp_settings.input_type != UART_INPUT_TYPE) && (client_init(false)) != 0) {
			LOG_INF("Failed to initialize client");
		}
		else {

			if (!init_cmd_run) {
				run_template_from_file (&disp_settings, "init_cmd.tmp", 1);
				init_cmd_run = true;
			}
			
			handle_messages(&disp_settings);

			send_messages (&disp_settings);

			disconnect_coap_session (&disp_settings);

			update_pic ();

		}
		
		if (disp_settings.poll_counter != 0) {
			err = lte_lc_func_mode_set(LTE_LC_FUNC_MODE_DEACTIVATE_LTE);
			if (err != 0){
				LOG_ERR("Failed to decativate LTE and enable GNSS functional mode");
				break;
			}
			modem_connected = false;

			LOG_INF("Pause for %d seconds", disp_settings.polling_sleep_time);
			k_sleep(K_SECONDS(disp_settings.polling_sleep_time));
		}
	}

	if (disp_settings.poll_counter == 0) {
		LOG_INF("Polling disabled");
	}
	
	LOG_INF("Shutting down modem");

	lte_lc_offline();

	lte_lc_power_off();

	nrf_modem_lib_shutdown();

	while (true) {
		LOG_INF("Sleeping");
		k_sleep(K_FOREVER);
	}

	return 0;
}
 

I have various other things going on - but this about covers the functionality I'm talking about.

Here is the "COAP" functions I use: 

/*
 * Copyright (c) 2024: Infotec Limited
 *
 * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
 */

#include "main.h"
#include <nrf_socket.h>
#include <zephyr/device.h>
#include <zephyr/drivers/uart.h>

LOG_MODULE_REGISTER(wcp_coap, LOG_LEVEL_INF);

/* Include the header file for the CoAP library */
#include <zephyr/net/coap.h>
#include <zephyr/net/tls_credentials.h>

/* Define the macros for the CoAP version and message length */
#define APP_COAP_VERSION 1
#define APP_COAP_MAX_MSG_LEN 4000
#define APP_COAP_MAX_PACKET_SIZE 150

#define STILL_RECEIVING_COAP 1

/* Declare the buffer coap_buf to receive the response. */
static uint8_t coap_io_buff[APP_COAP_MAX_MSG_LEN];
static uint8_t coap_packet_buff[APP_COAP_MAX_PACKET_SIZE];
static int coap_io_offset=0;

#define COAP_SERVER_DEFAUT_BASE "asset"
#define COAP_SERVER_DEFAUT_COMMAND "command"
#define COAP_SERVER_DEFAUT_STATUS_COMMAND "status"
static char coap_command_uri[100];
static char coap_status_uri[100];

/* Define the CoAP message token next_token */
static uint16_t next_token;

static int sock;
static struct sockaddr_storage server;
static struct coap_block_context blk_ctx;
static int bulk_payload = false;

K_SEM_DEFINE(wcp_lte_connected, 0, 1);

// <<<< UART INPUT FOR HANDLING 
#define UART_DEVICE_NODE DT_CHOSEN(zephyr_shell_uart)
static const struct device *const uart_dev = DEVICE_DT_GET(UART_DEVICE_NODE);
static int rx_buf_pos = 0;
// >>>>


static void coap_lte_handler(const struct lte_lc_evt *const evt)
{
	switch (evt->type) {
	case LTE_LC_EVT_NW_REG_STATUS:
		LOG_INF("Network registration status: %d", evt->nw_reg_status);
		if ((evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_HOME) &&
		     (evt->nw_reg_status != LTE_LC_NW_REG_REGISTERED_ROAMING)) {

				break;
		}

		LOG_INF("Network registration status: %s",
			evt->nw_reg_status == LTE_LC_NW_REG_REGISTERED_HOME ?
			"Connected - home network" : "Connected - roaming");
		k_sem_give(&wcp_lte_connected);
		break;
	case LTE_LC_EVT_PSM_UPDATE:
		LOG_INF("PSM parameter update: TAU: %d, Active time: %d",
			evt->psm_cfg.tau, evt->psm_cfg.active_time);
		break;
	case LTE_LC_EVT_EDRX_UPDATE: {
		char log_buf[60];
		ssize_t len;

		len = snprintf(log_buf, sizeof(log_buf),
			       "eDRX parameter update: eDRX: %f, PTW: %f",
			       evt->edrx_cfg.edrx, evt->edrx_cfg.ptw);
		if (len > 0) {
			LOG_INF("%s", log_buf);
		}
		break;
	}
	case LTE_LC_EVT_RRC_UPDATE:
		LOG_INF("RRC mode: %s",
			evt->rrc_mode == LTE_LC_RRC_MODE_CONNECTED ?
			"Connected" : "Idle");
		break;
	case LTE_LC_EVT_CELL_UPDATE:
		LOG_INF("LTE cell changed: Cell ID: %d, Tracking area: %d",
		       evt->cell.id, evt->cell.tac);
		break;
	default:
		break;
	}
}

static int client_get_send(wcp_display_settings *disp_settings, bool initialise_get, bool get_bulk_payload)
{
	/* Create the CoAP message*/
	struct coap_packet request;

	if (initialise_get) {
		bulk_payload = get_bulk_payload;

		if (bulk_payload) {
			coap_block_transfer_init(&blk_ctx, COAP_BLOCK_64, 0);
		}
	}

	next_token = sys_rand32_get();

	int err = coap_packet_init(&request, coap_packet_buff, sizeof(coap_packet_buff),
				APP_COAP_VERSION, COAP_TYPE_CON,
				sizeof(next_token), (uint8_t *)&next_token,
				COAP_METHOD_GET, coap_next_id());
	if (err < 0) {
		LOG_ERR("Failed to create CoAP request, %d", err);
		return err;
	}

	/* Add an option specifying the resource path */
	err = coap_packet_append_option(&request, COAP_OPTION_URI_PATH,
					(uint8_t *)coap_command_uri,
					strlen(coap_command_uri));
	if (err < 0) {
		LOG_ERR("Failed to encode CoAP option, %d", err);
		return err;
	}

	if (bulk_payload) {
		err = coap_append_block2_option(&request, &blk_ctx);
		if (err < 0) {
			LOG_ERR("Unable to add block2 option.");
			return err;
		}
	}
	
	/* Send the configured CoAP packet */
	err = send(sock, request.data, request.offset, 0);
	if (err < 0) {
		LOG_ERR("Failed to send CoAP request, %d", errno);
		return -errno;
	}

	LOG_DBG("CoAP GET request sent: Token 0x%04x", next_token);

	return 0;
}

static int send_client_status_update(wcp_display_settings *disp_settings)
{
	int err,ret;
	struct coap_packet request;
	int messageId = coap_next_id();

	next_token++;

	err = coap_packet_init(&request, coap_packet_buff, sizeof(coap_packet_buff),
			       APP_COAP_VERSION, COAP_TYPE_NON_CON,
			       sizeof(next_token), (uint8_t *)&next_token,
			       COAP_METHOD_PUT, messageId);
	if (err < 0) {
		LOG_ERR("Failed to create CoAP request, %d", err);
		return err;
	}

	err = coap_packet_append_option(&request, COAP_OPTION_URI_PATH,
					(uint8_t *)coap_status_uri,
					strlen(coap_status_uri));
	if (err < 0) {
		LOG_ERR("Failed to encode CoAP option, %d", err);
		return err;
	}

   err = coap_append_option_int(&request, COAP_OPTION_CONTENT_FORMAT,
                                COAP_CONTENT_FORMAT_TEXT_PLAIN);
   if (err < 0) {
      LOG_ERR("Failed to encode CoAP CONTENT_FORMAT option, %d", err);
      return err;
   }

	err = coap_packet_append_payload_marker(&request);
	if (err < 0) {
		LOG_ERR("Failed to append payload marker, %d", err);
		return err;
	}

	get_time(disp_settings);
	time_t uptime = k_uptime_get () / 1000;
	ret = snprintf (coap_io_buff, sizeof(coap_io_buff), "I,%d\ni,%s\nT,%s\nU,%d", messageId,disp_settings->imei,disp_settings->current_time,(int)uptime);
	if (err < 0) {
		LOG_ERR("snprintf failed to format string, %d", err);
		return err;
	}
	err = coap_packet_append_payload(&request, (uint8_t *)coap_io_buff, ret);
	if (err < 0) {
		LOG_ERR("Failed to append payload, %d", err);
		return err;
	}

	err = send(sock, request.data, request.offset, 0);
	if (err < 0) {
		LOG_ERR("Failed to send CoAP request, %d", errno);
		return -errno;
	}

	LOG_INF("CoAP status message sent: token 0x%04x", next_token);

	return 0;
}

/**@brief Handles responses from the remote CoAP server. */
static int client_handle_response(wcp_display_settings *disp_settings, uint8_t *buf, int received)
{
	struct coap_packet reply;
	uint8_t token[8];
	uint16_t token_len;
	const uint8_t *payload;
	uint16_t payload_len;
	uint8_t temp_buf[512];
	int ret = 0;

	/* Parse the received CoAP packet */
	int err = coap_packet_parse(&reply, buf, received, NULL, 0);
	if (err < 0) {
		LOG_ERR("Malformed response received: %d", err);
		return err;
	}

	/* Confirm the token in the response matches the token sent */
	token_len = coap_header_get_token(&reply, token);
	if ((token_len != sizeof(next_token)) ||
		(memcmp(&next_token, token, sizeof(next_token)) != 0)) {
		LOG_ERR("Invalid token received: 0x%02x%02x",
			token[1], token[0]);
		return 0;
	}

	/* Retrieve the payload and confirm it's nonzero */
	payload = coap_packet_get_payload(&reply, &payload_len);
	if (payload_len > 0) {
		snprintf(temp_buf, MIN(payload_len+1, sizeof(temp_buf)), "%s", payload);

		uint16_t copy_len = payload_len;
		if (payload_len >= APP_COAP_MAX_MSG_LEN - coap_io_offset) {
			// Overflowing boffer - so handle it and then carry on
			copy_len = APP_COAP_MAX_MSG_LEN - coap_io_offset - 1;
		}
		memcpy(coap_io_buff + coap_io_offset, payload, copy_len);
		coap_io_offset += copy_len;
		coap_io_buff[coap_io_offset] = '\0';
		if (payload_len > copy_len) {
			uint16_t partial_line_br = 0;
			for (int i = 1; i <= coap_io_offset; i++) {
				if (coap_io_buff[coap_io_offset - i] == '\n') {
					coap_io_buff[coap_io_offset - i] = '\0';
					partial_line_br = i-1;
					break;
				}
			}
			LOG_INF ("OVERFLOWING BUFFER - Handle partial Commands (%d bytes loaded, %d bytes to process)", coap_io_offset, coap_io_offset - partial_line_br);
			handle_cmd_block (coap_io_buff, 0, disp_settings);
			LOG_INF ("OVERFLOWING BUFFER - Load up unused portion (%d + %d bytes) and carry on", partial_line_br, payload_len - copy_len);
			// Shift the remaining characters to the beginning of the buffer
			for (int i = 1; i <= partial_line_br; i++) {
				coap_io_buff[partial_line_br - i] = coap_io_buff[coap_io_offset - i];
			}
			// Copy over the rest of the block and then carry on
			memcpy(coap_io_buff + partial_line_br, payload + copy_len, payload_len - copy_len);
			coap_io_offset = partial_line_br + payload_len - copy_len;
			coap_io_buff[coap_io_offset] = '\0';
		}
	} else {
		strcpy(temp_buf, "EMPTY");
	}

	if (bulk_payload) {
		err = coap_update_from_block(&reply, &blk_ctx);
		if (err < 0) {
			LOG_ERR("Bulk load Error: %d", ret);
			return err;
		}
		else {
			if (!coap_next_block(&reply, &blk_ctx)) {
				LOG_DBG("Bulk load complete");
			}
			else {
				client_get_send(disp_settings, false, true);
				ret = STILL_RECEIVING_COAP;
			}
		}		
	}

	/* Log the header code, token and payload of the response */
	LOG_DBG("CoAP response: Code 0x%x, Token 0x%02x%02x, Payload: %s",
	coap_header_get_code(&reply), token[1], token[0], (char *)temp_buf);

	return ret;
}

static int handle_CoAP_response (wcp_display_settings *disp_settings) {
	int received;
	int ret = 1;

	coap_io_offset = 0;
	coap_io_buff[0] = '\0';
	while (ret > 0) {
		/* Receive response from the CoAP server */
		received = recv(sock, coap_packet_buff, sizeof(coap_packet_buff), 0);
		if (received < 0) {
			LOG_ERR("Socket error: %d, exit", errno);
			ret = errno;
		}
		else if (received == 0) {
			LOG_INF("Empty datagram");
			ret = 0;
		}
		else {
			/* Parse the received CoAP packet */
			ret = client_handle_response(disp_settings, coap_packet_buff, received);
			if (ret < 0) {
				LOG_ERR("Invalid response: %d, exit", ret);
			}
		}
	}

	return ret;
}

char *set_coap_uri_default (char *command, char *default_command) {

	if ((command == NULL) || (*command == '\0') || (*command == '#')) {
		return default_command;
	}
	else if (*command == '-') {
		return "";
	}
	else {
		return command;
	}
}

#define LEVEL_DIVIDER(x) (x[0] == '\0' ? "" : "/")

static void __set_coap_uri (char *uri_name, char *uri, char *l1, char *l2, char *l3, char *default_l3) {

	l3 = set_coap_uri_default (l3, default_l3);
	sprintf (uri, "%s%s%s%s%s", l1, LEVEL_DIVIDER(l2), l2, LEVEL_DIVIDER(l3), l3);
	LOG_INF("%s URI set to: %s", uri_name, uri);
}

void set_coap_uri (wcp_display_settings *disp_settings, char command_type, char *base, char *assetId, char *command) {

	base = set_coap_uri_default (base, COAP_SERVER_DEFAUT_BASE);
	assetId = set_coap_uri_default (assetId, disp_settings->displayId);

	if (command_type == 'S') {
		__set_coap_uri ("Status", coap_status_uri, base, assetId, command, COAP_SERVER_DEFAUT_STATUS_COMMAND);
	}
	else {
		__set_coap_uri ("Command", coap_command_uri, base, assetId, command, COAP_SERVER_DEFAUT_COMMAND);
	}
}

int server_resolve(void)
{
	int err;
	struct addrinfo *result;
	struct addrinfo hints = {
		.ai_family = AF_INET,
		.ai_socktype = SOCK_DGRAM
	};
	char ipv4_addr[NET_IPV4_ADDR_LEN];

	err = getaddrinfo(CONFIG_COAP_SERVER_HOSTNAME, NULL, &hints, &result);
	if (err != 0) {
		LOG_ERR("ERROR: getaddrinfo failed %d", err);
		return -EIO;
	}

	if (result == NULL) {
		LOG_ERR("ERROR: Address not found");
		return -ENOENT;
	}

	/* IPv4 Address. */
	struct sockaddr_in *server4 = ((struct sockaddr_in *)&server);

	server4->sin_addr.s_addr =
		((struct sockaddr_in *)result->ai_addr)->sin_addr.s_addr;
	server4->sin_family = AF_INET;
	server4->sin_port = htons(CONFIG_COAP_SERVER_PORT);

	inet_ntop(AF_INET, &server4->sin_addr.s_addr, ipv4_addr,
		  sizeof(ipv4_addr));
	LOG_INF("IPv4 Address found %s", ipv4_addr);

	/* Free the address. */
	freeaddrinfo(result);

	return 0;
}

/**@brief Initialize the CoAP client */
int client_init(bool useTLS)
{
	int err;

	if (useTLS) {
		sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_DTLS_1_2);
	}
	else {
		sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
	}
	if (sock < 0) {
		LOG_ERR("Failed to create CoAP socket: %d.", errno);
		return -errno;
	}

	if (useTLS) {
		int verify;
		sec_tag_t sec_tag_list[] = { 12 };

		enum {
			NONE = 0,
			OPTIONAL = 1,
			REQUIRED = 2,
		};

		verify = REQUIRED;

		err = setsockopt(sock, SOL_TLS, TLS_PEER_VERIFY, &verify, sizeof(verify));
		if (err) {
			LOG_ERR("Failed to setup peer verification, errno %d", errno);
			return -errno;
		}

		err = setsockopt(sock, SOL_TLS, TLS_HOSTNAME, CONFIG_COAP_SERVER_HOSTNAME,
			strlen(CONFIG_COAP_SERVER_HOSTNAME));
		if (err) {
			LOG_ERR("Failed to setup TLS hostname (%s), errno %d",
				CONFIG_COAP_SERVER_HOSTNAME, errno);
			return -errno;
		}
		err = setsockopt(sock, SOL_TLS, TLS_SEC_TAG_LIST, sec_tag_list,
				sizeof(sec_tag_t) * ARRAY_SIZE(sec_tag_list));
		if (err) {
			LOG_ERR("Failed to setup socket security tag, errno %d", errno);
			return -errno;
		}
	}

	err = connect(sock, (struct sockaddr *)&server,
		      sizeof(struct sockaddr_in));
	if (err < 0) {
		LOG_ERR("Connect failed : %d", errno);
		return -errno;
	}

	/* Randomize token. */
	next_token = sys_rand32_get();

	return 0;
}

int modem_connect(void)
{
	int err;

	LOG_INF("Set DNS server to Google");
	struct nrf_in_addr dns;
	dns.s_addr = 134744072; // Google DNS, 8.8.8.8
	err = nrf_setdnsaddr(NRF_AF_INET, &dns, sizeof(dns));
	if (err) {
		LOG_INF("DNS set error: %d", err);
	}
	else {
		LOG_INF("DNS set to Google");
		LOG_INF("Connect to LTE network");
		err = lte_lc_connect_async(coap_lte_handler);
		LOG_INF("lte_lc_connect_async - returned: %d", err);
		if (err) {
			LOG_ERR("Error in lte_lc_connect_async, error: %d", err);
			return err;
		}
	}
	
	return 0;
}

void wait_for_modem_connection ()
{
	// Wait until the modem is connected to the network until continuing
	k_sem_take(&wcp_lte_connected, K_FOREVER);
}

// <<<< UART INPUT FOR HANDLING
/*
 * Read characters from UART until line end is detected. Afterwards push the
 * data to the message queue.
 */
static void serial_cb(const struct device *dev, void *user_data)
{
	uint8_t c;

	if (!uart_irq_update(uart_dev)) {
		return;
	}

	if (!uart_irq_rx_ready(uart_dev)) {
		return;
	}

	/* read until FIFO empty */
	while (uart_fifo_read(uart_dev, &c, 1) == 1) {
		uart_poll_out(uart_dev, c);
		if ((rx_buf_pos < 0) || (rx_buf_pos == 0 && c == '\n')) {
			// Ignore leading newlines and any input coming in when we haven't handles the previous commmand
			continue;
		}
		if ((c == '\n' || c == '\r') && rx_buf_pos > 0) {
			uart_poll_out(uart_dev, '\n');
			/* terminate string */
			coap_io_buff[rx_buf_pos] = '\0';

			// Set rx_buf_pos to negative so that any more messages are ignored until this one has been processed
			rx_buf_pos = -1;
		} else if (rx_buf_pos < (APP_COAP_MAX_MSG_LEN - 1)) {
			coap_io_buff[rx_buf_pos++] = c;
		}
		/* else: characters beyond buffer size are dropped */
	}
}

static int handle_uart_input (wcp_display_settings *disp_settings) {

	if (!device_is_ready(uart_dev)) {
		LOG_ERR("UART device not found!");
		return 0;
	}

	/* configure interrupt and callback to receive data */
	int ret = uart_irq_callback_user_data_set(uart_dev, serial_cb, NULL);

	if (ret < 0) {
		if (ret == -ENOTSUP) {
			LOG_ERR("Interrupt-driven UART API support not enabled\n");
		} else if (ret == -ENOSYS) {
			LOG_ERR("UART device does not support interrupt-driven API\n");
		} else {
			LOG_ERR("Error setting UART callback: %d\n", ret);
		}
		return 0;
	}

	rx_buf_pos = -1;
	uart_irq_rx_enable(uart_dev);

	bool getting_UART_data = true;
	/* indefinitely wait for input from the user */
	while (getting_UART_data) {
		LOG_INF("UART >>>>");
		rx_buf_pos = 0;
		while (rx_buf_pos >= 0) {
			k_sleep(K_MSEC(100));
		}
		if (strcmp(coap_io_buff, "#END") == 0) {
			getting_UART_data = false;
		}
		else {
			LOG_INF("UART 1");
			handle_cmd_block (coap_io_buff, 0, disp_settings);
			LOG_INF("UART 2");
		}
	}
	return 0;
}

int handle_messages (wcp_display_settings *disp_settings) {

	if (disp_settings->input_type == UART_INPUT_TYPE) {
		return handle_uart_input (disp_settings);
	}
	else {
		int err = 0;

		LOG_INF("Get COAP Messages");
		
		// Get a bulk message from the server
		err = client_get_send(disp_settings, true, true);
		if (err) {
			LOG_ERR("Failed to send CoAP GET request, %d", err);
		}
		if (err == 0) {
			err = handle_CoAP_response (disp_settings);
		}

		if (err == 0) {
			/** Successfully connected to COAP Server - so mark boot image as
			 *  working to avoid reverting to the former image upon reboot.
			 *  Possible that we wil no-longer be able to connect to the AWS server
			 *  but as we don't want to do that very often this will have to do!
			 */
			boot_write_img_confirmed();
			// Process the command block that has been loaded
			handle_cmd_block (coap_io_buff, 0, disp_settings);
			return 0;
		}
		else {
			return -1;
		}
	}
}

int	send_messages (wcp_display_settings *disp_settings) {
	int err;

	// Update Device status here
	LOG_INF("Send COAP Messages");

	if (disp_settings->input_type == UART_INPUT_TYPE) {
		LOG_INF("send_messages not suported for UART");
		return 1;
	}
	else {
		/* Send POST request */
		err = send_client_status_update(disp_settings); 
		if (err) {
			LOG_ERR("Failed to send CoAP POST request, %d", err);
			return err;
		}

		return handle_CoAP_response (disp_settings);
	}
}

void disconnect_coap_session (wcp_display_settings *disp_settings)
{
	if (disp_settings->input_type != UART_INPUT_TYPE) {
		// Disconnect from LTE
		close(sock);
	}
}


// >>>>

Here is the PRJ file:0358.prj.conf

Anybody got any ideas?

Many thanks,

Ed.

  • Sample Output:

    *** Booting nRF Connect SDK v3.5.99-ncs1-1 ***
    I: Starting bootloader
    I: Primary image: magic=good, swap_type=0x2, copy_done=0x1, image_ok=0x1
    I: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    I: Boot source: none
    I: Image index: 0, Swap type: none
    I: Bootloader chainload address offset: 0x10000
    [00:00:00.752,471] <inf> display_it8951: Could not connect to display - HW Busy
    *** Booting nRF Connect SDK v3.5.99-ncs1-1 ***
    [00:00:00.753,112] <inf> nrf_whisper1: Stating nrf_whisper, version: v1.0.3
    [00:00:01.664,581] <inf> wcp_time: Update IMEI
    [00:00:01.665,191] <inf> wcp_time: IMEI Number: 358299840119099
    [00:00:01.685,302] <inf> nrf_whisper1: Configure Modem
    [00:00:01.685,302] <inf> wcp_coap: Set DNS server to Google
    [00:00:01.691,864] <inf> wcp_coap: DNS set to Google
    [00:00:01.691,864] <inf> wcp_coap: Connect to LTE network
    [00:00:01.743,713] <inf> wcp_coap: lte_lc_connect_async - returned: 0
    [00:00:01.743,713] <inf> nrf_whisper1: Resolve Server
    [00:00:01.743,927] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:01.743,957] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:02.744,293] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:02.744,323] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:03.744,689] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:03.744,689] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:04.745,025] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:04.745,056] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:05.745,391] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:05.745,391] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:06.745,727] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:06.745,758] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:07.746,093] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:07.746,093] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:08.746,429] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:08.746,459] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:09.746,795] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:09.746,795] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:10.747,131] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:10.747,161] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:11.747,497] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:11.747,497] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:12.747,833] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:12.747,863] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:13.748,504] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:13.748,504] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:14.748,840] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:14.748,870] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:15.749,206] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:15.749,237] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:16.749,542] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:16.749,572] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:17.749,908] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:17.749,908] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:18.750,305] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:18.750,335] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:19.750,701] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:19.750,701] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:20.751,037] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:20.751,068] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:21.751,403] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:21.751,403] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:22.751,739] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:22.751,770] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:23.752,258] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:23.752,258] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:24.752,563] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:24.752,593] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:25.752,929] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:25.752,929] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:26.753,265] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:26.753,295] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:27.753,631] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:27.753,631] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:28.753,967] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:28.753,997] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:29.754,333] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:29.754,333] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:30.754,669] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:30.754,699] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:31.755,065] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:31.755,065] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:32.755,371] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:32.755,401] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:33.755,767] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:33.755,767] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:34.756,103] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:34.756,134] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:35.756,469] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:35.756,469] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:36.756,805] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:36.756,805] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:37.757,171] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:37.757,171] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:38.757,507] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:38.757,537] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:39.758,331] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:39.758,361] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:40.758,666] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:40.758,697] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:41.759,185] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:41.759,185] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:42.759,490] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:42.759,521] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:43.759,857] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:43.759,857] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:44.760,192] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:44.760,223] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:45.760,559] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:45.760,559] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:46.760,894] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:46.760,925] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:47.761,260] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:47.761,260] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:48.761,718] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:48.761,749] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:49.762,115] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:49.762,115] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:50.762,573] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:50.762,603] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:51.762,969] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:51.762,969] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:52.763,305] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:52.763,336] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:53.763,671] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:53.763,671] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:54.764,007] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:54.764,007] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:55.764,373] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:55.764,373] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:56.764,709] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:56.764,739] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:57.765,075] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:57.765,075] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:58.765,533] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:58.765,563] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:00:59.765,930] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:00:59.765,930] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:01:00.766,387] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:01:00.766,418] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:01:01.766,784] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:01:01.766,784] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:01:02.767,120] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:01:02.767,150] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:01:03.767,486] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:01:03.767,486] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:01:04.768,188] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:01:04.768,218] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:01:05.768,554] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:01:05.768,585] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:01:06.768,890] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:01:06.768,890] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:01:07.769,256] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:01:07.769,256] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:01:08.769,897] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:01:08.769,927] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:01:09.770,294] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:01:09.770,294] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:01:10.770,751] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:01:10.770,782] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:01:11.771,148] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:01:11.771,148] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:01:12.771,606] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:01:12.771,636] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:01:13.780,761] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:01:13.780,761] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    +CEREG: 2,"2437","07D5BA1F",9
    [00:01:14.191,009] <inf> wcp_coap: Network registration status: 2
    [00:01:14.191,009] <inf> wcp_coap: LTE cell changed: Cell ID: 131447327, Tracking area: 9271
    [00:01:14.781,280] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:01:14.781,280] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    +CSCON: 1
    [00:01:14.932,861] <inf> wcp_coap: RRC mode: Connected
    [00:01:15.781,585] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:01:15.781,616] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    [00:01:16.781,951] <err> wcp_coap: ERROR: getaddrinfo failed -11
    [00:01:16.781,951] <inf> nrf_whisper1: Failed to resolve server name - retry in 1 second
    +CEREG: 5,"2437","07D5BA1F",9,,,"11100000","00101000"
    [00:01:17.554,534] <inf> wcp_coap: Network registration status: 5
    [00:01:17.554,565] <inf> wcp_coap: Network registration status: Connected - roaming
    [00:01:17.555,541] <inf> wcp_coap: PSM parameter update: TAU: 28800, Active time: -1
    %XTIME: ,"52401080210580","01"
    	:
    	:

  • In my experience, calling "lte_lc_power_off()" saves the current state and allows the modem to startup again fast. As you already detected, "lte_lc_power_off()" takes in some case a lot of time to deregister from the network (see nRF9160 - CFUN=0 - order of operations? it's also not possible to start it and then short the timeout, because that will not save the current state to the NVM). So, there will be the one or the other pain.

    Anyway, I'm not sure, why you want to power it off all. PSM is usually wide supported and that obsoletes such power downs. So do you have any special requirements, why you don't want to use PSM?

     

  • Hi Achim,

    Thanks for your answer. I'll have more of a look at the code.

    As for why - we are looking at having our system turned right off apart from a very low power PIC device, which will result even lower power usage - especially overnight when the system could be turned off for number of hours.

    Do you know if I have the correct sequence of calls?

    When initially turning on, I call:

    nrf_modem_lib_dfu_handler();

    lte_lc_connect_async();

    getaddrinfo() (looping until an address is found - this is where it can get "stuck" for minutes)

    I then have a possible loop polling (say) once every 15 seconds:

    lte_lc_func_mode_set(LTE_LC_FUNC_MODE_NORMAL) 

    wait for modem connection being marked by a semaphore

    Set up socket to COAP server

    Handle receiving / sending of COAP messages

    Close socket to COAP server

    lte_lc_func_mode_set(LTE_LC_FUNC_MODE_DEACTIVATE_LTE);

    sleep for (say) 15 seconds before looping

    When turning off, I call:

    lte_lc_offline();

    lte_lc_power_off();

    nrf_modem_lib_shutdown();

    Many thanks,


    Ed.

  • nrf_modem_lib_dfu_handler();

    Do you mean "nrf_modem_lib_init()"?

    The time "getaddrinfo()" requires is mainly to wait for the successful network registration. If you put a "wait for modem connection being marked by a semaphore" before that loop, the loop itself will require less time (but the overall will be the same).

    I don't close the UDP socket, but I also don't deactive LTE. In a loop with an interval of 15s, I'm not sure, if that off/on pays-off.

    In my experience, it's not required to call "lte_lc_offline()" before "lte_lc_power_off()".

    As for why - we are looking at having our system turned right off apart from a very low power PIC device, which will result even lower power usage - especially overnight when the system could be turned off for number of hours.

    A nRF9160/61/51 has quiescent current of 3-4µA. I'm not sure, if switching it off over night really save that much energy. But it's your decision.

Related