/*
 * 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 <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 <init.h>
#include <misc/printk.h>

#include "lwm2m_object.h"
#include "lwm2m_engine.h"

#define LWM2M_RD_CLIENT_URI "rd"

#define SECONDS_TO_UPDATE_EARLY	6
#define STATE_MACHINE_UPDATE_INTERVAL K_MSEC(500)

/* Leave room for 32 hexadeciaml digits (UUID) + NULL */
#define CLIENT_EP_LEN		33

/* 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_INIT,
#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)
	ENGINE_DO_BOOTSTRAP_REG,
	ENGINE_BOOTSTRAP_REG_SENT,
	ENGINE_BOOTSTRAP_REG_DONE,
	ENGINE_BOOTSTRAP_TRANS_DONE,
#endif
	ENGINE_DO_REGISTRATION,
	ENGINE_REGISTRATION_SENT,
	ENGINE_REGISTRATION_DONE,
	ENGINE_UPDATE_SENT,
	ENGINE_DEREGISTER,
	ENGINE_DEREGISTER_SENT,
	ENGINE_DEREGISTER_FAILED,
	ENGINE_DEREGISTERED
};

struct lwm2m_rd_client_info {
	u32_t lifetime;
	struct lwm2m_ctx *ctx;
	u8_t engine_state;
	u8_t use_bootstrap;
	u8_t trigger_update;

	s64_t last_update;

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

	lwm2m_ctx_event_cb_t event_cb;
} client;

/* buffers */
static char query_buffer[64]; /* allocate some data for queries and updates */
static u8_t client_data[256]; /* allocate some data for the RD */

static void set_sm_state(u8_t sm_state)
{
	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 (sm_state == ENGINE_BOOTSTRAP_TRANS_DONE) {
		event = LWM2M_RD_CLIENT_EVENT_BOOTSTRAP_TRANSFER_COMPLETE;
	} else
#endif
	if (client.engine_state == ENGINE_UPDATE_SENT &&
	    sm_state == ENGINE_REGISTRATION_DONE) {
		event = LWM2M_RD_CLIENT_EVENT_REG_UPDATE_COMPLETE;
	} else if (sm_state == ENGINE_REGISTRATION_DONE) {
		event = LWM2M_RD_CLIENT_EVENT_REGISTRATION_COMPLETE;
	} else if ((sm_state == ENGINE_INIT ||
		    sm_state == ENGINE_DEREGISTERED) &&
		   (client.engine_state >= ENGINE_DO_REGISTRATION &&
		    client.engine_state < ENGINE_DEREGISTER)) {
		event = LWM2M_RD_CLIENT_EVENT_DISCONNECT;
	}

	/* TODO: add locking? */
	client.engine_state = sm_state;

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

static bool sm_is_registered(void)
{
	return (client.engine_state >= ENGINE_REGISTRATION_DONE &&
		client.engine_state <= ENGINE_DEREGISTER_FAILED);
}

static u8_t get_sm_state(void)
{
	/* TODO: add locking? */
	return client.engine_state;
}

static void sm_handle_timeout_state(struct lwm2m_message *msg,
				    enum sm_engine_state sm_state)
{
	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) {
		event = LWM2M_RD_CLIENT_EVENT_REG_UPDATE_FAILURE;
	} 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.event_cb) {
		client.event_cb(client.ctx, event);
	}
}

/* force re-update with remote peer */
void engine_trigger_update(void)
{
	/* TODO: add locking? */
	client.trigger_update = 1U;
}

/* 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)
{
	u8_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);
	} else if (code == COAP_RESPONSE_CODE_NOT_FOUND) {
		/* TODO: try and find another bootstrap server entry? */
		LOG_ERR("Failed: NOT_FOUND.  Not Retrying.");
		set_sm_state(ENGINE_DO_REGISTRATION);
	} else if (code == COAP_RESPONSE_CODE_FORBIDDEN) {
		/* TODO: try and find another bootstrap server entry? */
		LOG_ERR("Failed: 4.03 - Forbidden.  Not Retrying.");
		set_sm_state(ENGINE_DO_REGISTRATION);
	} else {
		/* TODO: Read payload for error message? */
		LOG_ERR("Failed with code %u.%u. Retrying ...",
			COAP_RESPONSE_CODE_CLASS(code),
			COAP_RESPONSE_CODE_DETAIL(code));
		set_sm_state(ENGINE_INIT);
	}

	return 0;
}

static void do_bootstrap_reg_timeout_cb(struct lwm2m_message *msg)
{
	LOG_WRN("Bootstrap Timeout");

	/* TODO:
	 * Look for the "next" BOOTSTRAP server entry in our security info
	 */

	/* Restart from scratch */
	sm_handle_timeout_state(msg, ENGINE_INIT);
}
#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];
	u8_t code;
	int ret;

	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.");
			return -EINVAL;
		}

		/* 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));
			return -EINVAL;
		}

		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;
	} else if (code == COAP_RESPONSE_CODE_NOT_FOUND) {
		LOG_ERR("Failed: NOT_FOUND.  Not Retrying.");
		set_sm_state(ENGINE_REGISTRATION_DONE);
		return 0;
	} else if (code == COAP_RESPONSE_CODE_FORBIDDEN) {
		LOG_ERR("Failed: 4.03 - Forbidden.  Not Retrying.");
		set_sm_state(ENGINE_REGISTRATION_DONE);
		return 0;
	}

	/* TODO: Read payload for error message? */
	/* Possible error response codes: 4.00 Bad request */
	LOG_ERR("failed with code %u.%u. Re-init network",
		COAP_RESPONSE_CODE_CLASS(code),
		COAP_RESPONSE_CODE_DETAIL(code));

	set_sm_state(ENGINE_INIT);
	return 0;
}

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

	/* Restart from scratch */
	sm_handle_timeout_state(msg, ENGINE_INIT);
}

static int do_update_reply_cb(const struct coap_packet *response,
			      struct coap_reply *reply,
			      const struct sockaddr *from)
{
	u8_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)) {
		set_sm_state(ENGINE_REGISTRATION_DONE);
		LOG_INF("Update Done");
		return 0;
	}

	/* TODO: Read payload for error message? */
	/* Possible error response codes: 4.00 Bad request & 4.04 Not Found */
	LOG_ERR("Failed with code %u.%u. Retrying registration",
		COAP_RESPONSE_CODE_CLASS(code),
		COAP_RESPONSE_CODE_DETAIL(code));
	set_sm_state(ENGINE_DO_REGISTRATION);

	return 0;
}

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

	/* Re-do registration */
	sm_handle_timeout_state(msg, ENGINE_DO_REGISTRATION);
}

static int do_deregister_reply_cb(const struct coap_packet *response,
				  struct coap_reply *reply,
				  const struct sockaddr *from)
{
	u8_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_DBG("Deregistration success");
		set_sm_state(ENGINE_DEREGISTERED);
	} else {
		LOG_ERR("failed with code %u.%u",
			COAP_RESPONSE_CODE_CLASS(code),
			COAP_RESPONSE_CODE_DETAIL(code));
		if (get_sm_state() == ENGINE_DEREGISTER_SENT) {
			set_sm_state(ENGINE_DEREGISTER_FAILED);
		}
	}

	return 0;
}

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

	/* Abort de-registration and start from scratch */
	sm_handle_timeout_state(msg, ENGINE_INIT);
}

static int sm_select_next_sec_inst(bool bootstrap_server,
				   int *sec_obj_inst, u32_t *lifetime)
{
	char pathstr[MAX_RESOURCE_LEN];
	int ret, end, i, obj_inst_id, found = -1;
	bool temp;

	/* lookup existing index */
	i = lwm2m_security_inst_id_to_index(*sec_obj_inst);
	if (i < 0) {
		*sec_obj_inst = -1;
		i = -1;
	}

	/* store end marker, due to looping */
	end = (i == -1 ? CONFIG_LWM2M_SECURITY_INSTANCE_COUNT : i);

	/* loop through servers starting from the index after the current one */
	for (i++; i < end; i++) {
		if (i >= CONFIG_LWM2M_SECURITY_INSTANCE_COUNT) {
			i = 0;
		}

		obj_inst_id = lwm2m_security_index_to_inst_id(i);
		if (obj_inst_id < 0) {
			continue;
		}

		/* Query for bootstrap support */
		snprintk(pathstr, sizeof(pathstr), "0/%d/1",
			 obj_inst_id);
		ret = lwm2m_engine_get_bool(pathstr, &temp);
		if (ret < 0) {
			continue;
		}

#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)
		if (temp == bootstrap_server) {
#else
		if (temp == false) {
#endif
			found = obj_inst_id;
			break;
		}
	}

	if (found > -1) {
		*sec_obj_inst = found;

		/* query the lifetime */
		/* TODO: use Short Server ID to link to server info */
		snprintk(pathstr, sizeof(pathstr), "1/%d/1",
			 obj_inst_id);
		if (lwm2m_engine_get_u32(pathstr, lifetime) < 0) {
			*lifetime = CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME;
			LOG_DBG("Using default lifetime: %u", *lifetime);
		}
	}

	if (*sec_obj_inst < 0) {
		/* no servers found */
		LOG_WRN("sec_obj_inst: No matching servers found.");
		return -ENOENT;
	}

	return 0;
}

/* state machine step functions */

static int sm_do_init(void)
{
	client.ctx->sec_obj_inst = -1;
	client.trigger_update = 0U;
	client.lifetime = 0U;

	/* Do bootstrap or registration */
#if defined(CONFIG_LWM2M_RD_CLIENT_SUPPORT_BOOTSTRAP)
	set_sm_state(ENGINE_DO_BOOTSTRAP_REG);
#else
	set_sm_state(ENGINE_DO_REGISTRATION);
#endif
	return 0;
}

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

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

	client.ctx->bootstrap_mode = true;
	ret = sm_select_next_sec_inst(client.ctx->bootstrap_mode,
				      &client.ctx->sec_obj_inst,
				      &client.lifetime);
	if (ret < 0) {
		/* no bootstrap server found, let's move to registration */
		LOG_WRN("Bootstrap server not found! Try normal registration.");
		set_sm_state(ENGINE_DO_REGISTRATION);
		return ret;
	}

	if (client.lifetime == 0U) {
		client.lifetime = CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME;
	}

	LOG_INF("Bootstrap started with endpoint '%s' with client lifetime %d",
		client.ep_name, client.lifetime);

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

	msg = lwm2m_get_message(client.ctx);
	if (!msg) {
		LOG_ERR("Unable to get a lwm2m message!");
		ret = -ENOMEM;
		goto cleanup_engine;
	}

	msg->type = COAP_TYPE_CON;
	msg->code = COAP_METHOD_POST;
	msg->mid = 0U;
	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;
	}

	/* TODO: handle return error */
	coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_PATH,
				  "bs", strlen("bs"));

	snprintk(query_buffer, sizeof(query_buffer) - 1, "ep=%s",
		 client.ep_name);
	/* TODO: handle return error */
	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);

	ret = lwm2m_send_message(msg);
	if (ret < 0) {
		LOG_ERR("Error sending LWM2M packet (err:%d).",
			    ret);
		goto cleanup;
	}

	set_sm_state(ENGINE_BOOTSTRAP_REG_SENT);
	return 0;

cleanup:
	lwm2m_reset_message(msg, true);
cleanup_engine:
	lwm2m_engine_context_close(client.ctx);
	return ret;
}

static int sm_bootstrap_reg_done(void)
{
	LOG_INF("Bootstrap registration done.");
	return 0;
}

void engine_bootstrap_finish(void)
{
	LOG_INF("Bootstrap data transfer done!");
	set_sm_state(ENGINE_BOOTSTRAP_TRANS_DONE);
}

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

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

	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;
	u16_t client_data_len;
	int ret;

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

	/* remember the last reg time */
	client.last_update = k_uptime_get();

	msg->type = COAP_TYPE_CON;
	msg->code = COAP_METHOD_POST;
	msg->mid = 0U;
	msg->reply_cb = reply_cb;
	msg->message_timeout_cb = timeout_cb;

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

	/* TODO: handle return error */
	coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_PATH,
				  LWM2M_RD_CLIENT_URI,
				  strlen(LWM2M_RD_CLIENT_URI));

	if (!sm_is_registered()) {
		/* include client endpoint in URI QUERY on 1st registration */
		coap_append_option_int(&msg->cpkt, COAP_OPTION_CONTENT_FORMAT,
				       LWM2M_FORMAT_APP_LINK_FORMAT);
		snprintk(query_buffer, sizeof(query_buffer) - 1,
			 "lwm2m=%s", LWM2M_PROTOCOL_VERSION);
		/* TODO: handle return error */
		coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_QUERY,
					  query_buffer, strlen(query_buffer));
		snprintk(query_buffer, sizeof(query_buffer) - 1,
			 "ep=%s", client.ep_name);
		/* TODO: handle return error */
		coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_QUERY,
					  query_buffer, strlen(query_buffer));
	} else {
		/* include server endpoint in URI PATH otherwise */
		/* TODO: handle return error */
		coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_PATH,
					  client.server_ep,
					  strlen(client.server_ep));
	}

	snprintk(query_buffer, sizeof(query_buffer) - 1,
		 "lt=%d", client.lifetime);
	/* TODO: handle return error */
	coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_QUERY,
				  query_buffer, strlen(query_buffer));

	/* TODO: add supported binding query string */

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

		/* generate the rd data */
		client_data_len = lwm2m_get_rd_data(client_data,
						    sizeof(client_data));
		ret = buf_append(CPKT_BUF_WRITE(&msg->cpkt), client_data,
				 client_data_len);
		if (ret < 0) {
			goto cleanup;
		}
	}

	ret = lwm2m_send_message(msg);
	if (ret < 0) {
		LOG_ERR("Error sending LWM2M packet (err:%d).", ret);
		goto cleanup;
	}

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

	return 0;

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

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

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

	client.ctx->bootstrap_mode = false;
	ret = sm_select_next_sec_inst(client.ctx->bootstrap_mode,
				      &client.ctx->sec_obj_inst,
				      &client.lifetime);
	if (ret < 0) {
		LOG_ERR("Unable to find a valid security instance.");
		set_sm_state(ENGINE_INIT);
		return -EINVAL;
	}

	if (client.lifetime == 0U) {
		client.lifetime = CONFIG_LWM2M_ENGINE_DEFAULT_LIFETIME;
	}

	LOG_INF("RD Client started with endpoint '%s' with client lifetime %d",
		client.ep_name, client.lifetime);

	ret = lwm2m_engine_start(client.ctx);
	if (ret < 0) {
		LOG_ERR("Cannot init LWM2M engine (%d)", ret);
		return 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);
		lwm2m_engine_context_close(client.ctx);
		/* exit and try again */
	}

	return ret;
}

static int sm_registration_done(void)
{
	int ret = 0;
	bool forced_update;

	/*
	 * check for lifetime seconds - SECONDS_TO_UPDATE_EARLY
	 * so that we can update early and avoid lifetime timeout
	 */
	if (sm_is_registered() &&
	    (client.trigger_update ||
	     ((client.lifetime - SECONDS_TO_UPDATE_EARLY) <=
	      (k_uptime_get() - client.last_update) / 1000))) {
		forced_update = client.trigger_update;
		client.trigger_update = 0U;
		ret = sm_send_registration(forced_update,
					   do_update_reply_cb,
					   do_update_timeout_cb);
		if (!ret) {
			set_sm_state(ENGINE_UPDATE_SENT);
		} else {
			LOG_ERR("Registration update err: %d", ret);
			lwm2m_engine_context_close(client.ctx);
			/* perform full registration */
			set_sm_state(ENGINE_DO_REGISTRATION);
		}
	}

	return ret;
}

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

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

	msg->type = COAP_TYPE_CON;
	msg->code = COAP_METHOD_DELETE;
	msg->mid = 0U;
	msg->reply_cb = do_deregister_reply_cb;
	msg->message_timeout_cb = do_deregister_timeout_cb;

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

	/* TODO: handle return error */
	coap_packet_append_option(&msg->cpkt, COAP_OPTION_URI_PATH,
				  client.server_ep,
				  strlen(client.server_ep));

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

	ret = lwm2m_send_message(msg);
	if (ret < 0) {
		LOG_ERR("Error sending LWM2M packet (err:%d).", ret);
		goto cleanup;
	}

	set_sm_state(ENGINE_DEREGISTER_SENT);
	return 0;

cleanup:
	lwm2m_reset_message(msg, true);
	lwm2m_engine_context_close(client.ctx);
	return ret;
}

static void lwm2m_rd_client_service(struct k_work *work)
{
	if (client.ctx) {
		switch (get_sm_state()) {

		case ENGINE_INIT:
			sm_do_init();
			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 */
			break;

		case ENGINE_BOOTSTRAP_REG_DONE:
			sm_bootstrap_reg_done();
			/* wait for transfer done */
			break;

		case ENGINE_BOOTSTRAP_TRANS_DONE:
			sm_bootstrap_trans_done();
			break;
#endif

		case ENGINE_DO_REGISTRATION:
			sm_do_registration();
			break;

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

		case ENGINE_REGISTRATION_DONE:
			sm_registration_done();
			break;

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

		case ENGINE_DEREGISTER:
			sm_do_deregister();
			break;

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

		case ENGINE_DEREGISTER_FAILED:
			break;

		case ENGINE_DEREGISTERED:
			break;

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

		}
	}
}

void lwm2m_rd_client_start(struct lwm2m_ctx *client_ctx, const char *ep_name,
			   lwm2m_ctx_event_cb_t event_cb)
{
	client.ctx = client_ctx;
	client.event_cb = event_cb;

	set_sm_state(ENGINE_INIT);
	strncpy(client.ep_name, ep_name, CLIENT_EP_LEN - 1);
	LOG_INF("LWM2M Client: %s", client.ep_name);
}

static int lwm2m_rd_client_init(struct device *dev)
{
	return lwm2m_engine_add_service(lwm2m_rd_client_service,
					STATE_MACHINE_UPDATE_INTERVAL);
}

SYS_INIT(lwm2m_rd_client_init, APPLICATION,
	 CONFIG_KERNEL_INIT_PRIORITY_DEFAULT);
