/*
 * Copyright (c) 2017 Linaro Limited
 * Copyright (c) 2017-2019 Foundries.io
 *
 * SPDX-License-Identifier: Apache-2.0
 */

/*
 * Copyright (c) 2015, Yanzi Networks AB.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * Original authors:
 *         Joakim Eriksson <joakime@sics.se>
 *         Niclas Finne <nfi@sics.se>
 *         Joel Hoglund <joel@sics.se>
 */

#define LOG_MODULE_NAME net_lwm2m_rd_client
#define LOG_LEVEL CONFIG_LWM2M_LOG_LEVEL

#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(LOG_MODULE_NAME);

#include <zephyr/types.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <zephyr/init.h>
#include <zephyr/sys/printk.h>
#include <zephyr/net/socket.h>

#include "lwm2m_object.h"
#include "lwm2m_engine.h"
#include "lwm2m_rd_client.h"
#include "lwm2m_rw_link_format.h"
#include "lwm2m_util.h"
#include "lwm2m_obj_server.h"

#define LWM2M_RD_CLIENT_URI "rd"
#define CLIENT_EP_LEN		CONFIG_LWM2M_RD_CLIENT_ENDPOINT_NAME_MAX_LENGTH
#define CLIENT_BINDING_LEN sizeof("UQ")
#define CLIENT_QUEUE_LEN sizeof("Q")
#define DELAY_BEFORE_CLOSING	(1 * MSEC_PER_SEC)
#define DELAY_FOR_ACK		100U
#define EXCHANGE_LIFETIME	247U
#define MINIMUM_PERIOD		15
#define DISABLE_TIMEOUT		(K_SECONDS(CONFIG_LWM2M_RD_CLIENT_MAX_RETRIES * EXCHANGE_LIFETIME))

static void sm_handle_registration_update_failure(void);
static int sm_send_registration_msg(void);
static bool sm_is_suspended(void);
static void lwm2m_rd_client_service(struct k_work *work);
static int64_t calc_next_event(void);
static void set_sm_state_delayed(uint8_t sm_state, int64_t delay_ms);
static void set_sm_state(uint8_t sm_state);
/** Try to fallback to bootstrap. Return true if we did. */
static bool fallback_to_bootstrap(void);

/* The states for the RD client state machine */
/*
 * When node is unregistered it ends up in UNREGISTERED
 * and this is going to be there until use X or Y kicks it
 * back into INIT again
 */
enum sm_engine_state {
	ENGINE_IDLE,
	ENGINE_INIT,
	ENGINE_DO_BOOTSTRAP_REG,
	ENGINE_BOOTSTRAP_REG_SENT,
	ENGINE_BOOTSTRAP_REG_DONE,
	ENGINE_BOOTSTRAP_TRANS_DONE,
	ENGINE_DO_REGISTRATION,
	ENGINE_SEND_REGISTRATION,
	ENGINE_REGISTRATION_SENT,
	ENGINE_REGISTRATION_DONE,
	ENGINE_REGISTRATION_DONE_RX_OFF,
	ENGINE_UPDATE_REGISTRATION,
	ENGINE_UPDATE_SENT,
	ENGINE_SERVER_DISABLED,
	ENGINE_SUSPENDED,
	ENGINE_DEREGISTER,
	ENGINE_DEREGISTER_SENT,
	ENGINE_DEREGISTERED,
	ENGINE_NETWORK_ERROR,
};

struct lwm2m_rd_client_info {
	struct k_mutex mutex;
	struct lwm2m_message rd_message;
	struct lwm2m_ctx *ctx;
	uint32_t lifetime;
	uint8_t engine_state;
	uint8_t retries;
	uint8_t retry_delay;

	int64_t last_update;
	int64_t last_tx;
	int64_t next_event;
	int64_t last_state_change;

	char ep_name[CLIENT_EP_LEN];
	char server_ep[CLIENT_EP_LEN];

	bool use_bootstrap  : 1;
	bool trigger_update : 1;
	bool update_objects : 1;
	bool close_socket   : 1;
	bool server_disabled: 1;
} client;

/* Allocate some data for queries and updates. Make sure it's large enough to
 * hold the largest query string, which in most cases will be the endpoint
 * string. In other case, 32 bytes are enough to encode any other query string
 * documented in the LwM2M specification.
 */
static char query_buffer[MAX(32, sizeof("ep=") + CLIENT_EP_LEN)];
static enum sm_engine_state suspended_client_state;

static struct lwm2m_message *rd_get_message(void)
{
	if (client.rd_message.ctx) {
		/* Free old message */
		lwm2m_reset_message(&client.rd_message, true);
	}

	client.rd_message.ctx = client.ctx;
	return &client.rd_message;

}

static void rd_client_message_free(void)
{
	lwm2m_reset_message(lwm2m_get_ongoing_rd_msg(), true);
}


struct lwm2m_message *lwm2m_get_ongoing_rd_msg(void)
{
	if (!client.ctx || !client.rd_message.ctx) {
		return NULL;
	}
	return &client.rd_message;
}

void engine_update_tx_time(void)
{
	client.last_tx = k_uptime_get();
}

static void next_event_at(int64_t timestamp)
{
	client.next_event = timestamp;
	(void)lwm2m_engine_call_at(lwm2m_rd_client_service, timestamp);
}

static void set_sm_state_delayed(uint8_t sm_state, int64_t delay_ms)
{
	k_mutex_lock(&client.mutex, K_FOREVER);
	enum lwm2m_rd_client_event event = LWM2M_RD_CLIENT_EVENT_NONE;

	/* Determine if a callback to the app is needed */
#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)
	if (sm_state == ENGINE_BOOTSTRAP_REG_DONE) {
		event = LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_COMPLETE;
	} else if (client.engine_state == ENGINE_BOOTSTRAP_TRANS_DONE &&
		   sm_state == ENGINE_DO_REGISTRATION) {
		event = LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_TRANSFER_COMPLETE;
	} else
#endif
	if (client.engine_state == ENGINE_UPDATE_SENT &&
	    (sm_state == ENGINE_REGISTRATION_DONE ||
	     sm_state == ENGINE_REGISTRATION_DONE_RX_OFF)) {
		lwm2m_push_queued_buffers(client.ctx);
		event = LWM2M_RD_CLIENT_EVENT_REG_UPDATE_COMPLETE;
	} else if (sm_state == ENGINE_REGISTRATION_DONE) {
		lwm2m_push_queued_buffers(client.ctx);
		event = LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE;
	} else if (sm_state == ENGINE_REGISTRATION_DONE_RX_OFF) {
		event = LWM2M_RD_CLIENT_EVENT_QUEUE_MODE_RX_OFF;
	} else if (sm_state == ENGINE_DEREGISTERED &&
		   (client.engine_state >= ENGINE_DO_REGISTRATION &&
		    client.engine_state <= ENGINE_DEREGISTER_SENT) && !client.server_disabled) {
		event = LWM2M_RD_CLIENT_EVENT_DISCONNECT;
	} else if (sm_state == ENGINE_UPDATE_REGISTRATION) {
		event = LWM2M_RD_CLIENT_EVENT_REG_UPDATE;
	} else if (sm_state == ENGINE_DEREGISTER) {
		if (client.server_disabled) {
			event = LWM2M_RD_CLIENT_EVENT_SERVER_DISABLED;
		} else {
			event = LWM2M_RD_CLIENT_EVENT_DEREGISTER;
		}
	}

	if (sm_is_suspended()) {
		/* Just change the state where we are going to resume next */
		suspended_client_state = sm_state;
	} else {
		client.engine_state = sm_state;
	}

	if (event > LWM2M_RD_CLIENT_EVENT_NONE && client.ctx->event_cb) {
		client.ctx->event_cb(client.ctx, event);
	}

	/* Suspend socket after Event callback */
	if (event == LWM2M_RD_CLIENT_EVENT_QUEUE_MODE_RX_OFF) {
		if (IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUSPEND_SOCKET_AT_IDLE) ||
		    IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_STOP_POLLING_AT_IDLE)) {
			lwm2m_socket_suspend(client.ctx);
		} else if (IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_CLOSE_SOCKET_AT_IDLE)) {
			lwm2m_close_socket(client.ctx);
		}
	}
	client.last_state_change = k_uptime_get();
	next_event_at(k_uptime_get() + delay_ms);
	k_mutex_unlock(&client.mutex);
}

static void set_sm_state(uint8_t sm_state)
{
	set_sm_state_delayed(sm_state, 0);
}

static bool sm_is_bootstrap(void)
{
#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)
	k_mutex_lock(&client.mutex, K_FOREVER);
	bool is_bootstrap = (client.engine_state >= ENGINE_DO_BOOTSTRAP_REG &&
		client.engine_state <= ENGINE_BOOTSTRAP_TRANS_DONE);
	k_mutex_unlock(&client.mutex);
	return is_bootstrap;
#else
	return false;
#endif
}

static bool sm_is_registered(void)
{
	k_mutex_lock(&client.mutex, K_FOREVER);
	bool registered = (client.engine_state >= ENGINE_REGISTRATION_DONE &&
			   client.engine_state <= ENGINE_DEREGISTER_SENT);

	k_mutex_unlock(&client.mutex);
	return registered;
}

static bool sm_is_suspended(void)
{
	k_mutex_lock(&client.mutex, K_FOREVER);
	bool suspended = (client.engine_state == ENGINE_SUSPENDED);

	k_mutex_unlock(&client.mutex);
	return suspended;
}


static uint8_t get_sm_state(void)
{
	k_mutex_lock(&client.mutex, K_FOREVER);
	uint8_t state = client.engine_state;

	k_mutex_unlock(&client.mutex);
	return state;
}

static void sm_handle_timeout_state(enum sm_engine_state sm_state)
{
	k_mutex_lock(&client.mutex, K_FOREVER);
	enum lwm2m_rd_client_event event = LWM2M_RD_CLIENT_EVENT_NONE;

	/* Don't send BOOTSTRAP_REG_FAILURE event, that is only emitted from
	 * do_network_error() once we are out of retries.
	 */
	if (client.engine_state == ENGINE_REGISTRATION_SENT) {
		event = LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT;
	} else if (client.engine_state == ENGINE_UPDATE_SENT) {
		event = LWM2M_RD_CLIENT_EVENT_REG_TIMEOUT;
	} else if (client.engine_state == ENGINE_DEREGISTER_SENT) {
		event = LWM2M_RD_CLIENT_EVENT_DEREGISTER_FAILURE;
	} else {
		/* TODO: unknown timeout state */
	}

	set_sm_state(sm_state);

	if (event > LWM2M_RD_CLIENT_EVENT_NONE && client.ctx->event_cb) {
		client.ctx->event_cb(client.ctx, event);
	}
	k_mutex_unlock(&client.mutex);
}

static void sm_handle_failure_state(enum sm_engine_state sm_state)
{
	k_mutex_lock(&client.mutex, K_FOREVER);
	enum lwm2m_rd_client_event event = LWM2M_RD_CLIENT_EVENT_NONE;

#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)
	if (client.engine_state == ENGINE_BOOTSTRAP_REG_SENT) {
		event = LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE;
	} else
#endif
	if (client.engine_state == ENGINE_REGISTRATION_SENT) {
		event = LWM2M_RD_CLIENT_EVENT_REGISTRATION_FAILURE;
	} else if (client.engine_state == ENGINE_UPDATE_SENT) {
		sm_handle_registration_update_failure();
		k_mutex_unlock(&client.mutex);
		return;
	} else if (client.engine_state == ENGINE_DEREGISTER_SENT) {
		event = LWM2M_RD_CLIENT_EVENT_DEREGISTER_FAILURE;
	}

	lwm2m_engine_stop(client.ctx);
	set_sm_state(sm_state);

	if (event > LWM2M_RD_CLIENT_EVENT_NONE && client.ctx->event_cb) {
		client.ctx->event_cb(client.ctx, event);
	}
	k_mutex_unlock(&client.mutex);
}

/* force state machine restart */
static void socket_fault_cb(int error)
{
	LOG_ERR("RD Client socket error: %d", error);
	lwm2m_socket_close(client.ctx);

	if (IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) && sm_is_bootstrap()) {
		client.ctx->sec_obj_inst = -1;
		/* force full registration */
		client.last_update = 0;

		if (get_sm_state() == ENGINE_BOOTSTRAP_TRANS_DONE) {
			/* Ignore the error, some servers close the connection immediately
			 * after receiving Ack to Bootstrap-Finish command.
			 */
			return;
		}
	}

	/* Network error state causes engine to re-register,
	 * so only trigger that state if we are not stopping the
	 * engine.
	 * Also when engine is going to be disabled, for a while, we might get spurious
	 * socket errors when closing, so ignore them.
	 */
	if (client.engine_state > ENGINE_IDLE &&
		client.engine_state < ENGINE_SERVER_DISABLED) {
		sm_handle_timeout_state(ENGINE_NETWORK_ERROR);
	} else if (client.engine_state != ENGINE_SUSPENDED &&
		   !client.server_disabled) {
		sm_handle_failure_state(ENGINE_IDLE);
	}
}

/* force re-update with remote peer */
void engine_trigger_update(bool update_objects)
{
	k_mutex_lock(&client.mutex, K_FOREVER);
	if (client.engine_state < ENGINE_REGISTRATION_SENT ||
	    client.engine_state > ENGINE_UPDATE_SENT) {
		k_mutex_unlock(&client.mutex);
		return;
	}

	client.trigger_update = true;
	/* short delay for Ack, then trigger an update */
	next_event_at(k_uptime_get() + DELAY_FOR_ACK);

	if (update_objects) {
		client.update_objects = true;
	}
	k_mutex_unlock(&client.mutex);
}

static inline const char *code2str(uint8_t code)
{
	switch (code) {
	case COAP_RESPONSE_CODE_BAD_REQUEST:
		return "Bad Request";
	case COAP_RESPONSE_CODE_FORBIDDEN:
		return "Forbidden";
	case COAP_RESPONSE_CODE_NOT_FOUND:
		return "Not Found";
	case COAP_RESPONSE_CODE_PRECONDITION_FAILED:
		return "Precondition Failed";
	default:
		break;
	}

	return "Unknown";
}

/* state machine reply callbacks */

#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)
static int do_bootstrap_reply_cb(const struct coap_packet *response,
				 struct coap_reply *reply,
				 const struct sockaddr *from)
{
	uint8_t code;

	code = coap_header_get_code(response);
	LOG_DBG("Bootstrap callback (code:%u.%u)",
		COAP_RESPONSE_CODE_CLASS(code),
		COAP_RESPONSE_CODE_DETAIL(code));

	if (code == COAP_RESPONSE_CODE_CHANGED) {
		LOG_INF("Bootstrap registration done!");
		set_sm_state(ENGINE_BOOTSTRAP_REG_DONE);
		return 0;
	}

	LOG_ERR("Failed with code %u.%u (%s). Not Retrying.",
		COAP_RESPONSE_CODE_CLASS(code), COAP_RESPONSE_CODE_DETAIL(code),
		code2str(code));

	sm_handle_failure_state(ENGINE_IDLE);

	return 0;
}

static void do_bootstrap_reg_timeout_cb(struct lwm2m_message *msg)
{
	LOG_WRN("Bootstrap Timeout");
	sm_handle_timeout_state(ENGINE_NETWORK_ERROR);
}
#endif

int engine_trigger_bootstrap(void)
{
#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)
	k_mutex_lock(&client.mutex, K_FOREVER);

	if (client.use_bootstrap) {
		/* Bootstrap is not possible to trig */
		LOG_WRN("Bootstrap process ongoing");
		k_mutex_unlock(&client.mutex);
		return -EPERM;
	}
	LOG_INF("Server Initiated Bootstrap");
	/* Free ongoing possible message */
	rd_client_message_free();
	client.use_bootstrap = true;
	client.trigger_update = false;
	set_sm_state_delayed(ENGINE_INIT, DELAY_BEFORE_CLOSING);
	k_mutex_unlock(&client.mutex);
	return 0;
#else
	return -EPERM;
#endif
}
static int do_registration_reply_cb(const struct coap_packet *response,
				    struct coap_reply *reply,
				    const struct sockaddr *from)
{
	struct coap_option options[2];
	uint8_t code;
	int ret = -EINVAL;

	code = coap_header_get_code(response);
	LOG_DBG("Registration callback (code:%u.%u)",
		COAP_RESPONSE_CODE_CLASS(code),
		COAP_RESPONSE_CODE_DETAIL(code));

	/* check state and possibly set registration to done */
	if (code == COAP_RESPONSE_CODE_CREATED) {
		ret = coap_find_options(response, COAP_OPTION_LOCATION_PATH,
					options, 2);
		if (ret < 2) {
			LOG_ERR("Unexpected endpoint data returned. ret = %d", ret);
			ret = -EINVAL;
			goto fail;
		}

		/* option[0] should be "rd" */

		if (options[1].len + 1 > sizeof(client.server_ep)) {
			LOG_ERR("Unexpected length of query: "
				    "%u (expected %zu)\n",
				    options[1].len,
				    sizeof(client.server_ep));
			ret = -EINVAL;
			goto fail;
		}

		/* remember the last reg time */
		client.last_update = k_uptime_get();
		client.server_disabled = false;
		client.retries = 0;

		memcpy(client.server_ep, options[1].value,
		       options[1].len);
		client.server_ep[options[1].len] = '\0';
		set_sm_state(ENGINE_REGISTRATION_DONE);
		LOG_INF("Registration Done (EP='%s')",
			client.server_ep);

		return 0;
	}

	LOG_ERR("Failed with code %u.%u (%s).",
		COAP_RESPONSE_CODE_CLASS(code), COAP_RESPONSE_CODE_DETAIL(code),
		code2str(code));
fail:
	lwm2m_server_disable(client.ctx->srv_obj_inst, DISABLE_TIMEOUT);
	sm_handle_failure_state(ENGINE_NETWORK_ERROR);

	return ret;
}

static void do_registration_timeout_cb(struct lwm2m_message *msg)
{
	LOG_WRN("Registration Timeout");

	sm_handle_timeout_state(ENGINE_NETWORK_ERROR);
}

static int do_update_reply_cb(const struct coap_packet *response,
			      struct coap_reply *reply,
			      const struct sockaddr *from)
{
	uint8_t code;

	code = coap_header_get_code(response);
	LOG_INF("Update callback (code:%u.%u)",
		COAP_RESPONSE_CODE_CLASS(code),
		COAP_RESPONSE_CODE_DETAIL(code));

	/* If NOT_FOUND just continue on */
	if ((code == COAP_RESPONSE_CODE_CHANGED) ||
	    (code == COAP_RESPONSE_CODE_CREATED)) {
		/* remember the last reg time */
		client.last_update = k_uptime_get();
		set_sm_state(ENGINE_REGISTRATION_DONE);
		LOG_INF("Update Done");
		return 0;
	}

	LOG_ERR("Failed with code %u.%u (%s). Retrying registration.",
		COAP_RESPONSE_CODE_CLASS(code), COAP_RESPONSE_CODE_DETAIL(code),
		code2str(code));

	sm_handle_failure_state(ENGINE_DO_REGISTRATION);

	return 0;
}

static void do_update_timeout_cb(struct lwm2m_message *msg)
{
	LOG_WRN("Registration Update Timeout");

	if (client.ctx->sock_fd > -1) {
		client.close_socket = true;
	}
	/* Re-do registration */
	sm_handle_timeout_state(ENGINE_DO_REGISTRATION);
}

static int do_deregister_reply_cb(const struct coap_packet *response,
				  struct coap_reply *reply,
				  const struct sockaddr *from)
{
	uint8_t code;

	code = coap_header_get_code(response);
	LOG_DBG("Deregister callback (code:%u.%u)",
		COAP_RESPONSE_CODE_CLASS(code),
		COAP_RESPONSE_CODE_DETAIL(code));

	if (code == COAP_RESPONSE_CODE_DELETED) {
		LOG_INF("Deregistration success");
		set_sm_state(ENGINE_DEREGISTERED);
		return 0;
	}

	LOG_ERR("Failed with code %u.%u (%s). Not Retrying",
		COAP_RESPONSE_CODE_CLASS(code), COAP_RESPONSE_CODE_DETAIL(code),
		code2str(code));

	sm_handle_failure_state(ENGINE_DEREGISTERED);

	return 0;
}

static void do_deregister_timeout_cb(struct lwm2m_message *msg)
{
	LOG_WRN("De-Registration Timeout");

	sm_handle_timeout_state(ENGINE_DEREGISTERED);
}

static bool is_bootsrap_server(int sec_obj_inst)
{
	bool bootstrap;
	int ret;

	ret = lwm2m_get_bool(&LWM2M_OBJ(0, sec_obj_inst, 1), &bootstrap);
	if (ret < 0) {
		LOG_WRN("Failed to check bootstrap, err %d", ret);
		return false;
	}
	return bootstrap;
}

static bool sm_update_lifetime(int srv_obj_inst, uint32_t *lifetime)
{
	uint32_t new_lifetime;

	if (lwm2m_get_u32(&LWM2M_OBJ(1, srv_obj_inst, 1), &new_lifetime) < 0) {
		new_lifetime = CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME;
		LOG_INF("Using default lifetime: %u", new_lifetime);
	}

	if (new_lifetime < CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME) {
		new_lifetime = CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME;
		lwm2m_set_u32(&LWM2M_OBJ(1, srv_obj_inst, 1), new_lifetime);
		LOG_INF("Overwrite a server lifetime with default");
	}

	if (new_lifetime != *lifetime) {
		*lifetime = new_lifetime;
		return true;
	}

	return false;
}

/**
 * @brief Find the next security instance for bootstrapping.
 *
 * Search for the next security instance that has the bootstrap flag set and
 * is not the same as current security instance.
 *
 * @param sec_obj_inst current security instance or -1.
 * @return zero on success, negative on error.
 */
static int sm_next_bootstrap_inst(int *sec_obj_inst)
{
	int i, obj_inst_id = -1;

	if (*sec_obj_inst >= 0 && !is_bootsrap_server(*sec_obj_inst)) {
		*sec_obj_inst = -1;
	}

	/* Iterate over all instances to find the correct one. */
	for (i = 0; i < CONFIG_LWM2M_SECURITY_INSTANCE_COUNT; i++) {
		obj_inst_id = lwm2m_security_index_to_inst_id(i);
		if (obj_inst_id < 0) {
			continue;
		}
		if (obj_inst_id == *sec_obj_inst) {
			continue;
		}

		if (is_bootsrap_server(obj_inst_id)) {
			*sec_obj_inst = obj_inst_id;
			return 0;
		}
	}

	LOG_WRN("No Bootstrap servers found.");

	return -ENOENT;
}

/* state machine step functions */

static int sm_do_init(void)
{
	lwm2m_engine_stop(client.ctx);
	client.trigger_update = false;
	client.lifetime = 0U;
	client.last_update = 0U;
	client.close_socket = false;

	/* Do bootstrap or registration */
	if (client.use_bootstrap && IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)) {
		set_sm_state(ENGINE_DO_BOOTSTRAP_REG);
	} else {
		set_sm_state(ENGINE_DO_REGISTRATION);
	}
	return 0;
}

#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)
static int sm_send_bootstrap_registration(void)
{
	struct lwm2m_message *msg;
	int ret;

	msg = rd_get_message();
	if (!msg) {
		LOG_ERR("Unable to get a lwm2m message!");
		return -ENOMEM;
	}

	msg->type = COAP_TYPE_CON;
	msg->code = COAP_METHOD_POST;
	msg->mid = coap_next_id();
	msg->tkl = LWM2M_MSG_TOKEN_GENERATE_NEW;
	msg->reply_cb = do_bootstrap_reply_cb;
	msg->message_timeout_cb = do_bootstrap_reg_timeout_cb;

	ret = lwm2m_init_message(msg);
	if (ret) {
		goto cleanup;
	}

	ret = coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_PATH,
					"bs", strlen("bs"));
	if (ret < 0) {
		goto cleanup;
	}

	snprintk(query_buffer, sizeof(query_buffer) - 1, "ep=%s",
		 client.ep_name);

	ret = coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_QUERY,
					query_buffer, strlen(query_buffer));
	if (ret < 0) {
		goto cleanup;
	}

	if (IS_ENABLED(CONFIG_LWM2M_VERSION_1_1)) {
		int pct = LWM2M_FORMAT_OMA_TLV;

		if (IS_ENABLED(CONFIG_LWM2M_RW_SENML_CBOR_SUPPORT)) {
			pct = LWM2M_FORMAT_APP_SENML_CBOR;
		} else if (IS_ENABLED(CONFIG_LWM2M_RW_SENML_JSON_SUPPORT)) {
			pct = LWM2M_FORMAT_APP_SEML_JSON;
		}

		snprintk(query_buffer, sizeof(query_buffer) - 1, "pct=%d", pct);

		coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_QUERY,
				  query_buffer, strlen(query_buffer));
	}

	/* log the bootstrap attempt */
	LOG_DBG("Register ID with bootstrap server as '%s'",
		query_buffer);

	lwm2m_send_message_async(msg);

	return 0;

cleanup:
	lwm2m_reset_message(msg, true);
	return ret;
}

static void sm_do_bootstrap_reg(void)
{
	int ret;

	/* clear out existing connection data */
	if (client.ctx->sock_fd > -1) {
		lwm2m_engine_stop(client.ctx);
	}

	client.ctx->bootstrap_mode = true;
	ret = sm_next_bootstrap_inst(&client.ctx->sec_obj_inst);
	if (ret < 0) {
		set_sm_state(ENGINE_NETWORK_ERROR);
		return;
	}

	LOG_INF("Bootstrap started with endpoint '%s' using security object %d",
		client.ep_name, client.ctx->sec_obj_inst);

	ret = lwm2m_engine_start(client.ctx);
	if (ret < 0) {
		LOG_ERR("Cannot init LWM2M engine (%d)", ret);
		set_sm_state(ENGINE_NETWORK_ERROR);
		return;
	}

	ret = sm_send_bootstrap_registration();
	if (!ret) {
		set_sm_state(ENGINE_BOOTSTRAP_REG_SENT);
	} else {
		LOG_ERR("Bootstrap registration err: %d", ret);
		set_sm_state(ENGINE_NETWORK_ERROR);
	}

	return;
}

void engine_bootstrap_finish(void)
{
	LOG_INF("Bootstrap data transfer done!");
	/* Delay the state transition, so engine have some time to send ACK
	 * before we close the socket
	 */
	set_sm_state_delayed(ENGINE_BOOTSTRAP_TRANS_DONE, DELAY_BEFORE_CLOSING);
}

static int sm_bootstrap_trans_done(void)
{
	/* close down context resources */
	lwm2m_engine_stop(client.ctx);

	/* reset security object instance */
	client.ctx->sec_obj_inst = -1;
	client.use_bootstrap = false;

	set_sm_state(ENGINE_DO_REGISTRATION);

	return 0;
}
#endif

static int sm_send_registration(bool send_obj_support_data,
				coap_reply_t reply_cb,
				lwm2m_message_timeout_cb_t timeout_cb)
{
	struct lwm2m_message *msg;
	int ret;
	char binding[CLIENT_BINDING_LEN];
	char queue[CLIENT_QUEUE_LEN];

	msg = rd_get_message();
	if (!msg) {
		LOG_ERR("Unable to get a lwm2m message!");
		return -ENOMEM;
	}

	msg->type = COAP_TYPE_CON;
	msg->code = COAP_METHOD_POST;
	msg->mid = coap_next_id();
	msg->tkl = LWM2M_MSG_TOKEN_GENERATE_NEW;
	msg->reply_cb = reply_cb;
	msg->message_timeout_cb = timeout_cb;

	ret = lwm2m_init_message(msg);
	if (ret) {
		goto cleanup;
	}

	ret = coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_PATH,
					LWM2M_RD_CLIENT_URI,
					strlen(LWM2M_RD_CLIENT_URI));
	if (ret < 0) {
		goto cleanup;
	}

	if (sm_is_registered()) {
		ret = coap_packet_append_option(
			&msg->cpkt, COAP_OPTION_URI_PATH,
			client.server_ep, strlen(client.server_ep));
		if (ret < 0) {
			goto cleanup;
		}
	}

	if (send_obj_support_data) {
		ret = coap_append_option_int(
			&msg->cpkt, COAP_OPTION_CONTENT_FORMAT,
			LWM2M_FORMAT_APP_LINK_FORMAT);
		if (ret < 0) {
			goto cleanup;
		}
	}

	if (!sm_is_registered()) {
		snprintk(query_buffer, sizeof(query_buffer) - 1,
			"lwm2m=%s", LWM2M_PROTOCOL_VERSION_STRING);
		ret = coap_packet_append_option(
			&msg->cpkt, COAP_OPTION_URI_QUERY,
			query_buffer, strlen(query_buffer));
		if (ret < 0) {
			goto cleanup;
		}

		snprintk(query_buffer, sizeof(query_buffer) - 1,
			 "ep=%s", client.ep_name);
		ret = coap_packet_append_option(
			&msg->cpkt, COAP_OPTION_URI_QUERY,
			query_buffer, strlen(query_buffer));
		if (ret < 0) {
			goto cleanup;
		}
	}

	/* Send lifetime only if changed or on initial registration.*/
	if (sm_update_lifetime(client.ctx->srv_obj_inst, &client.lifetime) ||
	    !sm_is_registered()) {
		snprintk(query_buffer, sizeof(query_buffer) - 1,
			 "lt=%d", client.lifetime);
		ret = coap_packet_append_option(
			&msg->cpkt, COAP_OPTION_URI_QUERY,
			query_buffer, strlen(query_buffer));
		if (ret < 0) {
			goto cleanup;
		}
	}

	lwm2m_engine_get_binding(binding);
	lwm2m_engine_get_queue_mode(queue);
	/* UDP is a default binding, no need to add option if UDP without queue is used. */
	if ((!sm_is_registered() && (strcmp(binding, "U") != 0 || strcmp(queue, "Q") == 0))) {
		snprintk(query_buffer, sizeof(query_buffer) - 1,
			 "b=%s", binding);

		ret = coap_packet_append_option(
			&msg->cpkt, COAP_OPTION_URI_QUERY,
			query_buffer, strlen(query_buffer));
		if (ret < 0) {
			goto cleanup;
		}

#if CONFIG_LWM2M_VERSION_1_1
		/* In LwM2M 1.1, queue mode is a separate parameter */
		uint16_t len = strlen(queue);

		if (len) {
			ret = coap_packet_append_option(
				&msg->cpkt, COAP_OPTION_URI_QUERY,
				queue, len);
			if (ret < 0) {
				goto cleanup;
			}
		}
#endif
	}

	if (send_obj_support_data) {
		ret = coap_packet_append_payload_marker(&msg->cpkt);
		if (ret < 0) {
			goto cleanup;
		}

		msg->out.out_cpkt = &msg->cpkt;
		msg->out.writer = &link_format_writer;

		ret = do_register_op_link_format(msg);
		if (ret < 0) {
			goto cleanup;
		}
	}

	lwm2m_send_message_async(msg);

	/* log the registration attempt */
	LOG_DBG("registration sent [%s]",
		lwm2m_sprint_ip_addr(&client.ctx->remote_addr));

	return 0;

cleanup:
	LOG_ERR("error %d when sending registration message", ret);
	lwm2m_reset_message(msg, true);
	return ret;
}

static void sm_handle_registration_update_failure(void)
{
	k_mutex_lock(&client.mutex, K_FOREVER);
	LOG_WRN("Registration Update fail -> trigger full registration");
	lwm2m_engine_context_close(client.ctx);
	set_sm_state(ENGINE_SEND_REGISTRATION);
	k_mutex_unlock(&client.mutex);
}

static int sm_send_registration_msg(void)
{
	int ret;

	ret = sm_send_registration(true,
				   do_registration_reply_cb,
				   do_registration_timeout_cb);
	if (!ret) {
		set_sm_state(ENGINE_REGISTRATION_SENT);
	} else {
		LOG_ERR("Registration err: %d", ret);
		set_sm_state(ENGINE_NETWORK_ERROR);
	}

	return ret;
}

static void sm_do_registration(void)
{
	uint16_t ssid;
	int ret = 0;

	if (client.ctx->connection_suspended) {
		if (lwm2m_engine_connection_resume(client.ctx)) {
			lwm2m_engine_context_close(client.ctx);
			/* perform full registration */
			set_sm_state(ENGINE_DO_REGISTRATION);
			return;
		}

	} else {
		bool select_srv = true;
		uint16_t srv = (uint16_t) client.ctx->srv_obj_inst;

		client.last_update = 0;
		client.ctx->bootstrap_mode = false;

		/* clear out existing connection data */
		if (client.ctx->sock_fd > -1) {
			if (client.close_socket) {
				/* Clear old socket connection */
				client.close_socket = false;
				lwm2m_engine_stop(client.ctx);
			} else {
				lwm2m_engine_context_close(client.ctx);
				/* Keep current connection, retry registration with same server */
				select_srv = false;
			}
		}

		if (select_srv) {
			/* Select next one from the list, or fail */
			if (!lwm2m_server_select(&srv)) {
				LOG_ERR("Unable to find a valid server instance.");
				goto bootstrap_or_retry;
			}

			client.ctx->srv_obj_inst = srv;
			sm_update_lifetime(srv, &client.lifetime);

			ret = lwm2m_get_u16(&LWM2M_OBJ(1, client.ctx->srv_obj_inst, 0), &ssid);
			if (ret < 0) {
				LOG_ERR("Failed to read SSID");
				lwm2m_server_disable(srv, K_FOREVER);
				goto bootstrap_or_retry;
			}

			ret = lwm2m_security_short_id_to_inst(ssid);
			if (ret < 0) {
				LOG_ERR("Unable to find a valid security instance.");
				lwm2m_server_disable(srv, K_FOREVER);
				goto bootstrap_or_retry;
			}
			client.ctx->sec_obj_inst = (uint16_t) ret;
		}

		LOG_INF("RD Client started with endpoint '%s' with client lifetime %d using server "
			"object %d",
			client.ep_name, client.lifetime, client.ctx->srv_obj_inst);

		ret = lwm2m_engine_start(client.ctx);
		if (ret < 0) {
			LOG_ERR("Cannot init LWM2M engine (%d)", ret);
			goto retry;
		}
	}

	sm_send_registration_msg();
	return;

bootstrap_or_retry:
	if (!client.server_disabled && fallback_to_bootstrap()) {
		lwm2m_engine_stop(client.ctx);
		return;
	}
retry:
	lwm2m_engine_stop(client.ctx);
	set_sm_state(ENGINE_NETWORK_ERROR);
}

static int64_t next_update(void)
{
	int64_t next;
	int64_t period = CONFIG_LWM2M_UPDATE_PERIOD;
	int64_t early = CONFIG_LWM2M_SECONDS_TO_UPDATE_EARLY;

	if (period == 0) {
		period = client.lifetime;
	}
	if (early > client.lifetime) {
		early = client.lifetime;
	}

	next = MIN(period, client.lifetime - early);
	next = MAX(next, MINIMUM_PERIOD);

	return client.last_update + next * MSEC_PER_SEC;
}

static int64_t next_rx_off(void)
{
	if (IS_ENABLED(CONFIG_LWM2M_QUEUE_MODE_ENABLED)) {
		return client.last_tx + CONFIG_LWM2M_QUEUE_MODE_UPTIME * MSEC_PER_SEC;
	} else {
		return next_update();
	}
}

/** Return timestamp to next even whether it is RX_OFF or update event */
static int64_t calc_next_event(void)
{
	return Z_MIN(next_update(), next_rx_off());
}

static void sm_registration_done(void)
{
	k_mutex_lock(&client.mutex, K_FOREVER);

	int64_t now = k_uptime_get();

	if (sm_is_registered() &&
	    (client.trigger_update ||
	     now >= next_update())) {
		set_sm_state_delayed(ENGINE_UPDATE_REGISTRATION, DELAY_FOR_ACK);
	} else if (IS_ENABLED(CONFIG_LWM2M_QUEUE_MODE_ENABLED) &&
	    (client.engine_state != ENGINE_REGISTRATION_DONE_RX_OFF) &&
	    (now >= next_rx_off())) {
		set_sm_state(ENGINE_REGISTRATION_DONE_RX_OFF);
		next_event_at(next_update());
	} else {
		next_event_at(calc_next_event());
	}
	k_mutex_unlock(&client.mutex);
}

static int update_registration(void)
{
	int ret;
	bool update_objects;

	update_objects = client.update_objects;
	client.trigger_update = false;
	client.update_objects = false;

	ret = lwm2m_engine_connection_resume(client.ctx);
	if (ret) {
		return ret;
	}

	ret = sm_send_registration(update_objects,
				   do_update_reply_cb,
				   do_update_timeout_cb);
	if (ret) {
		LOG_ERR("Registration update err: %d", ret);
		return ret;
	}

	return 0;
}

static int sm_update_registration(void)
{
	int ret;

	ret = update_registration();
	if (ret) {
		LOG_ERR("Failed to update registration. Falling back to full registration");

		lwm2m_engine_stop(client.ctx);
		/* perform full registration */
		set_sm_state(ENGINE_DO_REGISTRATION);
		return ret;
	}

	set_sm_state(ENGINE_UPDATE_SENT);

	return 0;
}

static int sm_do_deregister(void)
{
	struct lwm2m_message *msg;
	int ret;

	if (lwm2m_engine_connection_resume(client.ctx)) {
		lwm2m_engine_context_close(client.ctx);
		/* Connection failed, enter directly to deregistered state */
		set_sm_state(ENGINE_DEREGISTERED);
		return 0;
	}

	msg = rd_get_message();
	if (!msg) {
		LOG_ERR("Unable to get a lwm2m message!");
		ret = -ENOMEM;
		goto close_ctx;
	}

	msg->type = COAP_TYPE_CON;
	msg->code = COAP_METHOD_DELETE;
	msg->mid = coap_next_id();
	msg->tkl = LWM2M_MSG_TOKEN_GENERATE_NEW;
	msg->reply_cb = do_deregister_reply_cb;
	msg->message_timeout_cb = do_deregister_timeout_cb;

	ret = lwm2m_init_message(msg);
	if (ret) {
		goto cleanup;
	}

	ret = coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_PATH,
					LWM2M_RD_CLIENT_URI,
					strlen(LWM2M_RD_CLIENT_URI));
	if (ret < 0) {
		LOG_ERR("Failed to encode URI path option (err:%d).", ret);
		goto cleanup;
	}

	/* include server endpoint in URI PATH */
	ret = coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_PATH,
					client.server_ep,
					strlen(client.server_ep));
	if (ret < 0) {
		LOG_ERR("Failed to encode URI path option (err:%d).", ret);
		goto cleanup;
	}

	LOG_INF("Deregister from '%s'", client.server_ep);

	lwm2m_send_message_async(msg);

	set_sm_state(ENGINE_DEREGISTER_SENT);
	return 0;

cleanup:
	lwm2m_reset_message(msg, true);
close_ctx:
	lwm2m_engine_stop(client.ctx);
	set_sm_state(ENGINE_DEREGISTERED);
	return ret;
}

static bool fallback_to_bootstrap(void)
{
	if (IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)) {
		bool fallback = true;

		(void)lwm2m_get_bool(&LWM2M_OBJ(LWM2M_OBJECT_SERVER_ID, client.ctx->srv_obj_inst,
						SERVER_BOOTSTRAP_ON_REGISTRATION_FAILURE_ID),
				     &fallback);
		if (fallback) {
			client.use_bootstrap = true;
			set_sm_state(ENGINE_INIT);
			return true;
		}
	}
	return false;
}

static void sm_do_network_error(void)
{
	int err;

	LOG_ERR("sm_do_network_error, retries %d", client.retries);

	lwm2m_socket_close(client.ctx);

	if (client.retry_delay) {
		next_event_at(k_uptime_get() + client.retry_delay * MSEC_PER_SEC);
		client.retry_delay = 0;
		return;
	}
	client.retry_delay = 1 << client.retries;
	client.retries++;

	/* Stop retrying and try fallback */
	if (client.retries > CONFIG_LWM2M_RD_CLIENT_MAX_RETRIES) {
		LOG_ERR("Network error, max retries reached (%d)", client.retries);

		/* Disable current server for a period so lwm2m_server_select() does not pick it */
		if (client.ctx->srv_obj_inst > -1) {
			lwm2m_server_disable(client.ctx->srv_obj_inst, DISABLE_TIMEOUT);
		}

		/* Are we in bootstrap? Try if we can fallback to some other BS server */
		if (client.ctx->bootstrap_mode &&
		    IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)) {
			LOG_DBG("In bootstrap, try fallback srv");
			/* Do we have any other bootstrap server to back off to? */
			if (sm_next_bootstrap_inst(&client.ctx->sec_obj_inst) < 0) {
				/* No, we are out of options, stop engine */
				goto stop_engine;
			}
			set_sm_state(ENGINE_INIT);
			return;
		}

		/* Try if there are other server to fall back to,
		 * Only allow fallback to higher priority server (lower value, or lower id)
		 * if we have successfully registered before.
		 * This should block us from looping the same list again.
		 * Instead we should fallback to bootstrap.
		 */
		uint16_t srv;

		if (lwm2m_server_select(&srv)) {
			uint8_t p1, p2;

			p1 = lwm2m_server_get_prio(client.ctx->srv_obj_inst);
			p2 = lwm2m_server_get_prio(srv);
			if (p1 < p2 || client.last_update != 0) {
				set_sm_state(ENGINE_INIT);
				return;
			}
		}

		/* If we have been disabled by some server, don't fall back to bootstrap */
		if (client.server_disabled) {
			set_sm_state(ENGINE_SERVER_DISABLED);
			return;
		}

		if (fallback_to_bootstrap()) {
			return;
		}
		goto stop_engine;
	}

	/* Retry bootstrap */
	if (IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)) {
		if (client.ctx->bootstrap_mode) {
			lwm2m_engine_context_close(client.ctx);
			/* If we don't have fallback BS server, retry with current one */
			if (sm_next_bootstrap_inst(&client.ctx->sec_obj_inst) < 0) {
				client.ctx->sec_obj_inst = -1;
			}
			set_sm_state(ENGINE_DO_BOOTSTRAP_REG);
			return;
		}
	}

	if (!client.last_update ||
	    (k_uptime_get() - client.last_update) / MSEC_PER_SEC > client.lifetime) {
		/* do full registration as there is no active registration or lifetime exceeded */
		/* Keep the same server until out of retry */
		set_sm_state(ENGINE_DO_REGISTRATION);
		return;
	}

	/* Try if we can recover the DTLS session and try Update.
	 * This might fallback into full registration on sm_handle_registration_update_failure().
	 */
	err = lwm2m_socket_start(client.ctx);
	if (err) {
		LOG_ERR("Failed to start socket %d", err);
		/*
		 * keep this state until lifetime/retry count exceeds. Renew
		 * sm state to set retry_delay etc ...
		 */
		set_sm_state(ENGINE_NETWORK_ERROR);
		return;
	}
	set_sm_state(ENGINE_UPDATE_REGISTRATION);
	return;

stop_engine:

	/* We are out of options, stop engine */
	if (client.ctx->event_cb) {
		if (client.ctx->bootstrap_mode) {
			client.ctx->event_cb(client.ctx,
					     LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_REG_FAILURE);
		} else {
			client.ctx->event_cb(client.ctx, LWM2M_RD_CLIENT_EVENT_NETWORK_ERROR);
		}
	}
	set_sm_state(ENGINE_IDLE);
}

static void lwm2m_rd_client_service(struct k_work *work)
{
	k_mutex_lock(&client.mutex, K_FOREVER);

	int64_t timeout = 0;

	if (client.ctx) {
		LOG_DBG("State: %d", get_sm_state());
		client.next_event = INT64_MAX;
		switch (get_sm_state()) {
		case ENGINE_IDLE:
			if (client.ctx->sock_fd > -1) {
				lwm2m_engine_stop(client.ctx);
			}
			rd_client_message_free();
			break;

		case ENGINE_INIT:
			sm_do_init();
			break;

		case ENGINE_SUSPENDED:
			break;

#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)
		case ENGINE_DO_BOOTSTRAP_REG:
			sm_do_bootstrap_reg();
			break;

		case ENGINE_BOOTSTRAP_REG_SENT:
			/* wait for bootstrap registration done */
			timeout = EXCHANGE_LIFETIME;
			break;

		case ENGINE_BOOTSTRAP_REG_DONE:
			/* wait for transfer done */
			timeout = EXCHANGE_LIFETIME;
			break;

		case ENGINE_BOOTSTRAP_TRANS_DONE:
			sm_bootstrap_trans_done();
			break;
#endif

		case ENGINE_DO_REGISTRATION:
			sm_do_registration();
			break;

		case ENGINE_SEND_REGISTRATION:
			sm_send_registration_msg();
			break;

		case ENGINE_REGISTRATION_SENT:
			/* wait registration to be done or timeout */
			timeout = EXCHANGE_LIFETIME;
			break;

		case ENGINE_REGISTRATION_DONE:
		case ENGINE_REGISTRATION_DONE_RX_OFF:
			sm_registration_done();
			break;

		case ENGINE_UPDATE_REGISTRATION:
			sm_update_registration();
			break;

		case ENGINE_UPDATE_SENT:
			/* wait update to be done or abort */
			timeout = EXCHANGE_LIFETIME;
			break;

		case ENGINE_SERVER_DISABLED:
			if (lwm2m_server_select(NULL)) {
				set_sm_state(ENGINE_INIT);
			} else {
				/* wait for server to be enabled. */
				/*
				 * TODO: Once engine is converted to use timepoint_t
				 * this should calculate the next event from the previous server.
				 */
				next_event_at(k_uptime_get() + SEC_PER_MIN * MSEC_PER_SEC);
			}
			break;

		case ENGINE_DEREGISTER:
			sm_do_deregister();
			break;

		case ENGINE_DEREGISTER_SENT:
			/* wait for deregister to be done or reset */
			timeout = EXCHANGE_LIFETIME;
			break;

		case ENGINE_DEREGISTERED:
			lwm2m_engine_stop(client.ctx);
			if (client.server_disabled) {
				set_sm_state(ENGINE_SERVER_DISABLED);
			} else {
				set_sm_state(ENGINE_IDLE);
			}
			break;

		case ENGINE_NETWORK_ERROR:
			sm_do_network_error();
			break;

		default:
			LOG_ERR("Unhandled state: %d", get_sm_state());

		}

		if (timeout) {
			int64_t end = client.last_state_change + timeout * MSEC_PER_SEC;

			if (end < k_uptime_get()) {
				LOG_DBG("State machine have timed out");
				sm_handle_timeout_state(ENGINE_INIT);
			} else if (client.next_event > end) {
				next_event_at(end);
			}
		}
	}

	k_mutex_unlock(&client.mutex);
}

int lwm2m_rd_client_start(struct lwm2m_ctx *client_ctx, const char *ep_name,
			   uint32_t flags, lwm2m_ctx_event_cb_t event_cb,
			   lwm2m_observe_cb_t observe_cb)
{
	k_mutex_lock(&client.mutex, K_FOREVER);

	if (!IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP) &&
	    (flags & LWM2M_RD_CLIENT_FLAG_BOOTSTRAP)) {
		LOG_ERR("Bootstrap support is disabled. Please enable "
			"CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP.");

		k_mutex_unlock(&client.mutex);
		return -ENOTSUP;
	}

	/* Check client idle state or socket is still active */

	if (client.ctx && (client.engine_state != ENGINE_IDLE || client.ctx->sock_fd != -1)) {
		LOG_WRN("Client is already running. state %d ", client.engine_state);
		k_mutex_unlock(&client.mutex);
		return -EINPROGRESS;
	}

	/* Init Context */
	lwm2m_server_reset_timestamps();
	lwm2m_engine_context_init(client_ctx);

	client.ctx = client_ctx;
	client.ctx->sock_fd = -1;
	client.ctx->fault_cb = socket_fault_cb;
	client.ctx->observe_cb = observe_cb;
	client.ctx->event_cb = event_cb;
	client.use_bootstrap = flags & LWM2M_RD_CLIENT_FLAG_BOOTSTRAP;
	client.ctx->srv_obj_inst = -1;
	client.ctx->sec_obj_inst = -1;
	client.retries = 0;

	strncpy(client.ep_name, ep_name, CLIENT_EP_LEN - 1);
	client.ep_name[CLIENT_EP_LEN - 1] = '\0';
	LOG_INF("Start LWM2M Client: %s", client.ep_name);

	set_sm_state(ENGINE_INIT);

	k_mutex_unlock(&client.mutex);

	return 0;
}

int lwm2m_rd_client_stop(struct lwm2m_ctx *client_ctx,
			   lwm2m_ctx_event_cb_t event_cb, bool deregister)
{
	k_mutex_lock(&client.mutex, K_FOREVER);

	if (client.ctx != client_ctx) {
		k_mutex_unlock(&client.mutex);
		LOG_WRN("Cannot stop. Wrong context");
		return -EPERM;
	}

	client.ctx->event_cb = event_cb;
	rd_client_message_free();

	if (sm_is_registered() && deregister && !client.server_disabled) {
		set_sm_state(ENGINE_DEREGISTER);
	} else {
		client.server_disabled = false;
		set_sm_state(ENGINE_DEREGISTERED);
	}

	LOG_INF("Stop LWM2M Client: %s", client.ep_name);

	k_mutex_unlock(&client.mutex);


	return 0;
}

int lwm2m_rd_client_pause(void)
{
	enum lwm2m_rd_client_event event = LWM2M_RD_CLIENT_EVENT_ENGINE_SUSPENDED;
	LOG_DBG("lwm2m_rd_client_pause()");

	k_mutex_lock(&client.mutex, K_FOREVER);

	if (!client.ctx) {
		k_mutex_unlock(&client.mutex);
		LOG_ERR("Cannot pause. No context");
		return -EPERM;
	} else if (sm_is_suspended()) {
		k_mutex_unlock(&client.mutex);
		LOG_ERR("LwM2M client already suspended");
		return 0;
	}

	LOG_INF("Suspend client");
	if (client.ctx->event_cb) {
		client.ctx->event_cb(client.ctx, event);
	}

	/* Suspend or close the socket */
	if (IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_CLOSE_SOCKET_AT_IDLE)) {
		lwm2m_close_socket(client.ctx);
	} else {
		lwm2m_socket_suspend(client.ctx);
	}

	suspended_client_state = get_sm_state();
	set_sm_state(ENGINE_SUSPENDED);

	k_mutex_unlock(&client.mutex);

	return 0;
}

int lwm2m_rd_client_resume(void)
{
	k_mutex_lock(&client.mutex, K_FOREVER);

	if (!client.ctx || !lwm2m_rd_client_is_suspended(client.ctx)) {
		k_mutex_unlock(&client.mutex);
		LOG_WRN("Cannot resume, state is not suspended");
		return -EPERM;
	}

	LOG_INF("Resume Client state");

	if (suspended_client_state == ENGINE_UPDATE_SENT) {
		/* Set back to Registration done and trigger an update */
		suspended_client_state = ENGINE_REGISTRATION_DONE;
	}
	/* Clear Possible pending RD Client message */
	rd_client_message_free();

	client.engine_state = suspended_client_state;

	/* Do we need to resume the bootstrap? */
#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)
	if (sm_is_bootstrap()) {
		client.engine_state = ENGINE_DO_BOOTSTRAP_REG;
	}
#endif
	/* Or do we resume into registration state */
	if (client.engine_state >= ENGINE_DO_REGISTRATION &&
		client.engine_state <= ENGINE_SERVER_DISABLED) {
		if (!client.last_update ||
			(client.lifetime <= (k_uptime_get() - client.last_update) / MSEC_PER_SEC)) {
			/* No lifetime left, register again */
			client.engine_state = ENGINE_DO_REGISTRATION;
		} else {
			/* Resume similarly like from QUEUE mode */
			client.engine_state = ENGINE_REGISTRATION_DONE_RX_OFF;
			lwm2m_rd_client_connection_resume(client.ctx);
		}
	}

	next_event_at(0);
	k_mutex_unlock(&client.mutex);

	return 0;
}

int lwm2m_rd_client_server_disabled(uint16_t inst_id)
{
	if (client.ctx->srv_obj_inst != inst_id) {
		return -EPERM;
	}

	k_mutex_lock(&client.mutex, K_FOREVER);

	client.server_disabled = true;

	if (sm_is_registered()) {
		LOG_INF("Server disabled, deregister");
		set_sm_state_delayed(ENGINE_DEREGISTER, DELAY_BEFORE_CLOSING);
	} else {
		LOG_INF("Server disabled");
		set_sm_state(ENGINE_DEREGISTERED);
	}

	k_mutex_unlock(&client.mutex);

	return 0;
}

void lwm2m_rd_client_update(void)
{
	engine_trigger_update(false);
}

struct lwm2m_ctx *lwm2m_rd_client_ctx(void)
{
	return client.ctx;
}

void lwm2m_rd_client_set_ctx(struct lwm2m_ctx *ctx)
{
	client.ctx = ctx;
}

int lwm2m_rd_client_connection_resume(struct lwm2m_ctx *client_ctx)
{
	if (client.ctx != client_ctx) {
		return -EPERM;
	}

	if (client.engine_state == ENGINE_REGISTRATION_DONE_RX_OFF) {
		/*
		 * Switch state to triggering a proper registration message
		 * If the socket stays open (Connection ID or no-sec), or we have TLS session cache,
		 * we can trigger the update, otherwise fall back to full registration.
		 */
		if ((IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_SUSPEND_SOCKET_AT_IDLE) &&
		     IS_ENABLED(CONFIG_LWM2M_TLS_SESSION_CACHING)) ||
		    (IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_STOP_POLLING_AT_IDLE) ||
		     IS_ENABLED(CONFIG_LWM2M_RD_CLIENT_LISTEN_AT_IDLE)) ||
		    !IS_ENABLED(CONFIG_LWM2M_DTLS_SUPPORT)) {
			client.engine_state = ENGINE_REGISTRATION_DONE;
			if (IS_ENABLED(CONFIG_LWM2M_QUEUE_MODE_NO_MSG_BUFFERING)) {
				/* Force online for a short period */
				engine_update_tx_time();
			} else {
				client.trigger_update = true;
			}
		} else {
			client.engine_state = ENGINE_DO_REGISTRATION;
		}
		next_event_at(0);
	}

	return 0;
}

int lwm2m_rd_client_timeout(struct lwm2m_ctx *client_ctx)
{
	if (client.ctx != client_ctx) {
		return -EPERM;
	}

	if (!sm_is_registered()) {
		return 0;
	}
	k_mutex_lock(&client.mutex, K_FOREVER);
	LOG_WRN("Confirmable Timeout -> Re-connect and register");
	set_sm_state(ENGINE_DO_REGISTRATION);
	next_event_at(0);
	k_mutex_unlock(&client.mutex);
	return 0;
}

bool lwm2m_rd_client_is_registred(struct lwm2m_ctx *client_ctx)
{
	if (client.ctx != client_ctx || !sm_is_registered()) {
		return false;
	}

	return true;
}
bool lwm2m_rd_client_is_suspended(struct lwm2m_ctx *client_ctx)
{
	if (client.ctx != client_ctx || !sm_is_suspended()) {
		return false;
	}

	return true;
}


int lwm2m_rd_client_init(void)
{
	client.ctx = NULL;
	client.rd_message.ctx = NULL;
	client.engine_state = ENGINE_IDLE;
	k_mutex_init(&client.mutex);

	return 0;
}

static int sys_lwm2m_rd_client_init(void)
{
	return lwm2m_rd_client_init();
}

LWM2M_ENGINE_INIT(sys_lwm2m_rd_client_init);
