/*
 * Copyright (c) 2017 Linaro Limited
 * Copyright (c) 2018-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>
 */

/*
 * Zephyr Contribution by Michael Scott <michael.scott@linaro.org>
 * - Zephyr code style changes / code cleanup
 * - Move to Zephyr APIs where possible
 * - Convert to Zephyr int/uint types
 * - Remove engine dependency (replace with writer context)
 * - Add write int64 function
 */

/*
 * TODO:
 * - Lots of byte-order API clean up
 * - Var / parameter type cleanup
 * - Replace magic #'s with defines
 */

#define LOG_MODULE_NAME net_lwm2m_oma_tlv
#define LOG_LEVEL CONFIG_LWM2M_LOG_LEVEL

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

#include <string.h>
#include <stdint.h>
#include <sys/byteorder.h>

#include "lwm2m_rw_oma_tlv.h"
#include "lwm2m_engine.h"
#ifdef CONFIG_LWM2M_RD_CLIENT_SUPPORT
#include "lwm2m_rd_client.h"
#endif
#include "lwm2m_util.h"

enum {
	OMA_TLV_TYPE_OBJECT_INSTANCE   = 0,
	OMA_TLV_TYPE_RESOURCE_INSTANCE = 1,
	OMA_TLV_TYPE_MULTI_RESOURCE    = 2,
	OMA_TLV_TYPE_RESOURCE          = 3
};

struct oma_tlv {
	uint8_t  type;
	uint16_t id; /* can be 8-bit or 16-bit when serialized */
	uint32_t length;
};

static uint8_t get_len_type(const struct oma_tlv *tlv)
{
	if (tlv->length < 8) {
		return 0;
	} else if (tlv->length < 0x100) {
		return 1;
	} else if (tlv->length < 0x10000) {
		return 2;
	}

	return 3;
}

static uint8_t tlv_calc_type(uint8_t flags)
{
	return flags & WRITER_RESOURCE_INSTANCE ?
			OMA_TLV_TYPE_RESOURCE_INSTANCE : OMA_TLV_TYPE_RESOURCE;
}

static uint16_t tlv_calc_id(uint8_t flags, struct lwm2m_obj_path *path)
{
	return flags & WRITER_RESOURCE_INSTANCE ?
			path->res_inst_id : path->res_id;
}

static void tlv_setup(struct oma_tlv *tlv, uint8_t type, uint16_t id,
		      uint32_t buflen)
{
	if (tlv) {
		tlv->type = type;
		tlv->id = id;
		tlv->length = buflen;
	}
}

static int oma_tlv_put_u8(struct lwm2m_output_context *out,
			  uint8_t value, bool insert)
{
	struct tlv_out_formatter_data *fd;
	int ret;

	if (insert) {
		fd = engine_get_out_user_data(out);
		if (!fd) {
			return -EINVAL;
		}

		ret = buf_insert(CPKT_BUF_WRITE(out->out_cpkt),
				 fd->mark_pos, &value, 1);
		if (ret < 0) {
			return ret;
		}

		fd->mark_pos++;
	} else {
		ret = buf_append(CPKT_BUF_WRITE(out->out_cpkt), &value, 1);
		if (ret < 0) {
			return ret;
		}
	}

	return 0;
}

static int oma_tlv_put(const struct oma_tlv *tlv,
		       struct lwm2m_output_context *out, uint8_t *value,
		       bool insert)
{
	size_t pos;
	int ret, i;
	uint8_t len_type, tmp;

	/* len_type is the same as number of bytes required for length */
	len_type = get_len_type(tlv);

	/* first type byte in TLV header */
	tmp = (tlv->type << 6) |
	      (tlv->id > 255 ? (1 << 5) : 0) |
	      (len_type << 3) |
	      (len_type == 0U ? tlv->length : 0);

	ret = oma_tlv_put_u8(out, tmp, insert);
	if (ret < 0) {
		return ret;
	}

	pos = 1;

	/* The ID */
	if (tlv->id > 255) {
		ret = oma_tlv_put_u8(out, (tlv->id >> 8) & 0xff, insert);
		if (ret < 0) {
			return ret;
		}

		pos++;
	}

	ret = oma_tlv_put_u8(out, tlv->id & 0xff, insert);
	if (ret < 0) {
		return ret;
	}

	pos++;

	for (i = 2; i >= 0; i--) {
		if (len_type > i) {
			ret = oma_tlv_put_u8(out,
					     (tlv->length >> (i * 8)) & 0xff,
					     insert);
			if (ret < 0) {
				return ret;
			}

			pos++;
		}
	}

	/* finally add the value */
	if (value != NULL && tlv->length > 0 && !insert) {
		ret = buf_append(CPKT_BUF_WRITE(out->out_cpkt),
				 value, tlv->length);
		if (ret < 0) {
			return ret;
		}
	}

	return pos + tlv->length;
}

static int oma_tlv_get(struct oma_tlv *tlv, struct lwm2m_input_context *in,
		       bool dont_advance)
{
	uint8_t len_type;
	uint8_t len_pos = 1U;
	size_t tlv_len;
	uint16_t tmp_offset;
	uint8_t buf[2];
	int ret;

	tmp_offset = in->offset;
	ret = buf_read_u8(&buf[0], CPKT_BUF_READ(in->in_cpkt), &tmp_offset);
	if (ret < 0) {
		goto error;
	}

	tlv->type = (buf[0] >> 6) & 3;
	len_type = (buf[0] >> 3) & 3;
	len_pos = 1 + (((buf[0] & (1 << 5)) != 0U) ? 2 : 1);

	ret = buf_read_u8(&buf[1], CPKT_BUF_READ(in->in_cpkt), &tmp_offset);
	if (ret < 0) {
		goto error;
	}

	tlv->id = buf[1];

	/* if len_pos > 2 it means that there are more ID to read */
	if (len_pos > 2) {
		ret = buf_read_u8(&buf[1], CPKT_BUF_READ(in->in_cpkt),
				  &tmp_offset);
		if (ret < 0) {
			goto error;
		}

		tlv->id = (tlv->id << 8) + buf[1];
	}

	if (len_type == 0U) {
		tlv_len = buf[0] & 7;
	} else {
		/* read the length */
		tlv_len = 0;
		while (len_type > 0) {
			ret = buf_read_u8(&buf[1], CPKT_BUF_READ(in->in_cpkt),
					  &tmp_offset);
			if (ret < 0) {
				goto error;
			}

			len_pos++;
			tlv_len = tlv_len << 8 | buf[1];
			len_type--;
		}
	}

	/* and read out the data??? */
	tlv->length = tlv_len;

	if (!dont_advance) {
		in->offset = tmp_offset;
	}

	return len_pos + tlv_len;

error:
	if (!dont_advance) {
		in->offset = tmp_offset;
	}

	return ret;
}

static int put_begin_tlv(struct lwm2m_output_context *out, uint16_t *mark_pos,
			 uint8_t *writer_flags, int writer_flag)
{
	/* set flags */
	*writer_flags |= writer_flag;

	/*
	 * store position for inserting TLV when we know the length
	 */
	*mark_pos = out->out_cpkt->offset;

	return 0;
}

static int put_end_tlv(struct lwm2m_output_context *out, uint16_t mark_pos,
		       uint8_t *writer_flags, uint8_t writer_flag, int tlv_type,
		       int tlv_id)
{
	struct tlv_out_formatter_data *fd;
	struct oma_tlv tlv;
	int len;

	fd = engine_get_out_user_data(out);
	if (!fd) {
		return -EINVAL;
	}

	*writer_flags &= ~writer_flag;

	len = out->out_cpkt->offset - mark_pos;

	/* use stored location */
	fd->mark_pos = mark_pos;

	/* set instance length */
	tlv_setup(&tlv, tlv_type, tlv_id, len);
	len = oma_tlv_put(&tlv, out, NULL, true) - tlv.length;

	return len;
}

static int put_begin_oi(struct lwm2m_output_context *out,
			struct lwm2m_obj_path *path)
{
	struct tlv_out_formatter_data *fd;

	/* No need for oi level TLV constructs */
	if (path->level > LWM2M_PATH_LEVEL_OBJECT) {
		return 0;
	}

	fd = engine_get_out_user_data(out);
	if (!fd) {
		return -EINVAL;
	}

	return put_begin_tlv(out, &fd->mark_pos_oi, &fd->writer_flags, 0);
}

static int put_end_oi(struct lwm2m_output_context *out,
		      struct lwm2m_obj_path *path)
{
	struct tlv_out_formatter_data *fd;

	if (path->level > LWM2M_PATH_LEVEL_OBJECT) {
		return 0;
	}

	fd = engine_get_out_user_data(out);
	if (!fd) {
		return -EINVAL;
	}

	return put_end_tlv(out, fd->mark_pos_oi, &fd->writer_flags, 0,
			   OMA_TLV_TYPE_OBJECT_INSTANCE, path->obj_inst_id);
}

static int put_begin_ri(struct lwm2m_output_context *out,
			struct lwm2m_obj_path *path)
{
	struct tlv_out_formatter_data *fd;

	fd = engine_get_out_user_data(out);
	if (!fd) {
		return -EINVAL;
	}

	return put_begin_tlv(out, &fd->mark_pos_ri, &fd->writer_flags,
			     WRITER_RESOURCE_INSTANCE);
}

static int put_end_ri(struct lwm2m_output_context *out,
		      struct lwm2m_obj_path *path)
{
	struct tlv_out_formatter_data *fd;

	fd = engine_get_out_user_data(out);
	if (!fd) {
		return -EINVAL;
	}

	/* Skip writing Multiple Resource TLV if path level is 4 */
	if (IS_ENABLED(CONFIG_LWM2M_VERSION_1_1) &&
		path->level == LWM2M_PATH_LEVEL_RESOURCE_INST) {
		return 0;
	}

	return put_end_tlv(out, fd->mark_pos_ri, &fd->writer_flags,
			   WRITER_RESOURCE_INSTANCE,
			   OMA_TLV_TYPE_MULTI_RESOURCE, path->res_id);
}

static int put_s8(struct lwm2m_output_context *out, struct lwm2m_obj_path *path,
		  int8_t value)
{
	struct tlv_out_formatter_data *fd;
	int len;
	struct oma_tlv tlv;

	fd = engine_get_out_user_data(out);
	if (!fd) {
		return -EINVAL;
	}

	tlv_setup(&tlv, tlv_calc_type(fd->writer_flags),
		  tlv_calc_id(fd->writer_flags, path), sizeof(value));

	len = oma_tlv_put(&tlv, out, (uint8_t *)&value, false);
	return len;
}

static int put_s16(struct lwm2m_output_context *out,
		   struct lwm2m_obj_path *path, int16_t value)
{
	struct tlv_out_formatter_data *fd;
	int len;
	struct oma_tlv tlv;
	int16_t net_value;

	if (INT8_MIN <= value && value <= INT8_MAX) {
		return put_s8(out, path, (int8_t)value);
	}

	fd = engine_get_out_user_data(out);
	if (!fd) {
		return -EINVAL;
	}

	net_value = sys_cpu_to_be16(value);
	tlv_setup(&tlv, tlv_calc_type(fd->writer_flags),
		  tlv_calc_id(fd->writer_flags, path), sizeof(net_value));

	len = oma_tlv_put(&tlv, out, (uint8_t *)&net_value, false);
	return len;
}

static int put_s32(struct lwm2m_output_context *out,
		   struct lwm2m_obj_path *path, int32_t value)
{
	struct tlv_out_formatter_data *fd;
	int len;
	struct oma_tlv tlv;
	int32_t net_value;

	if (INT16_MIN <= value && value <= INT16_MAX) {
		return put_s16(out, path, (int16_t)value);
	}

	fd = engine_get_out_user_data(out);
	if (!fd) {
		return -EINVAL;
	}

	net_value = sys_cpu_to_be32(value);
	tlv_setup(&tlv, tlv_calc_type(fd->writer_flags),
		  tlv_calc_id(fd->writer_flags, path), sizeof(net_value));

	len = oma_tlv_put(&tlv, out, (uint8_t *)&net_value, false);

	return len;
}

static int put_s64(struct lwm2m_output_context *out,
		   struct lwm2m_obj_path *path, int64_t value)
{
	struct tlv_out_formatter_data *fd;
	int len;
	struct oma_tlv tlv;
	int64_t net_value;

	if (INT32_MIN <= value && value <= INT32_MAX) {
		return put_s32(out, path, (int32_t)value);
	}

	fd = engine_get_out_user_data(out);
	if (!fd) {
		return -EINVAL;
	}

	net_value = sys_cpu_to_be64(value);
	tlv_setup(&tlv, tlv_calc_type(fd->writer_flags),
		  tlv_calc_id(fd->writer_flags, path), sizeof(net_value));

	len = oma_tlv_put(&tlv, out, (uint8_t *)&net_value, false);
	return len;
}

static int put_string(struct lwm2m_output_context *out,
		      struct lwm2m_obj_path *path, char *buf, size_t buflen)
{
	struct tlv_out_formatter_data *fd;
	int len;
	struct oma_tlv tlv;

	fd = engine_get_out_user_data(out);
	if (!fd) {
		return -EINVAL;
	}

	tlv_setup(&tlv, tlv_calc_type(fd->writer_flags),
		  tlv_calc_id(fd->writer_flags, path), (uint32_t)buflen);
	len = oma_tlv_put(&tlv, out, (uint8_t *)buf, false);
	return len;
}

static int put_float(struct lwm2m_output_context *out,
		     struct lwm2m_obj_path *path, double *value)
{
	struct tlv_out_formatter_data *fd;
	int len;
	struct oma_tlv tlv;
	int ret;
	uint8_t b64[8];

	fd = engine_get_out_user_data(out);
	if (!fd) {
		return -EINVAL;
	}

	ret = lwm2m_float_to_b64(value, b64, sizeof(b64));
	if (ret < 0) {
		LOG_ERR("float32 conversion error: %d", ret);
		return ret;
	}

	tlv_setup(&tlv, tlv_calc_type(fd->writer_flags),
		  tlv_calc_id(fd->writer_flags, path), sizeof(b64));
	len = oma_tlv_put(&tlv, out, b64, false);
	return len;
}

static int put_bool(struct lwm2m_output_context *out,
		    struct lwm2m_obj_path *path, bool value)
{
	int8_t value_s8 = (value != 0 ? 1 : 0);

	return put_s8(out, path, value_s8);
}

static int put_opaque(struct lwm2m_output_context *out,
		      struct lwm2m_obj_path *path, char *buf, size_t buflen)
{
	return put_string(out, path, buf, buflen);
}

static int put_objlnk(struct lwm2m_output_context *out,
		      struct lwm2m_obj_path *path, struct lwm2m_objlnk *value)
{
	struct tlv_out_formatter_data *fd;
	struct oma_tlv tlv;
	int32_t net_value = sys_cpu_to_be32(
				((value->obj_id) << 16) | value->obj_inst);

	fd = engine_get_out_user_data(out);
	if (!fd) {
		return -EINVAL;
	}

	tlv_setup(&tlv, tlv_calc_type(fd->writer_flags),
		  tlv_calc_id(fd->writer_flags, path), sizeof(net_value));

	return oma_tlv_put(&tlv, out, (uint8_t *)&net_value, false);
}

static int get_number(struct lwm2m_input_context *in, int64_t *value,
		      uint8_t max_len)
{
	struct oma_tlv tlv;
	int size;
	int64_t temp;
	int ret;

	size = oma_tlv_get(&tlv, in, false);
	if (size < 0) {
		return size;
	}

	if (tlv.length > max_len) {
		LOG_ERR("invalid length: %u", tlv.length);
		return -ENOMEM;
	}

	ret = buf_read((uint8_t *)&temp, tlv.length,
		       CPKT_BUF_READ(in->in_cpkt), &in->offset);
	if (ret < 0) {
		return ret;
	}

	switch (tlv.length) {
	case 1:
		*value = (int8_t)temp;
		break;
	case 2:
		*value = sys_cpu_to_be16((int16_t)temp);
		break;
	case 4:
		*value = sys_cpu_to_be32((int32_t)temp);
		break;
	case 8:
		*value = sys_cpu_to_be64(temp);
		break;
	default:
		LOG_ERR("invalid length: %u", tlv.length);
		return -EBADMSG;
	}

	return size;
}

static int get_s64(struct lwm2m_input_context *in, int64_t *value)
{
	return get_number(in, value, 8);
}

static int get_s32(struct lwm2m_input_context *in, int32_t *value)
{
	int64_t temp;
	int size;

	size = get_number(in, &temp, 4);
	if (size < 0) {
		return size;
	}

	*value = (int32_t)temp;

	return size;
}

static int get_string(struct lwm2m_input_context *in, uint8_t *buf,
		      size_t buflen)
{
	struct oma_tlv tlv;
	int size;
	int ret;

	size = oma_tlv_get(&tlv, in, false);
	if (size < 0) {
		return size;
	}

	if (buflen <= tlv.length) {
		return -ENOMEM;
	}

	ret = buf_read(buf, tlv.length, CPKT_BUF_READ(in->in_cpkt),
		       &in->offset);
	if (ret < 0) {
		return ret;
	}

	buf[tlv.length] = '\0';

	return size;
}

/* convert float to fixpoint */
static int get_float(struct lwm2m_input_context *in, double *value)
{
	struct oma_tlv tlv;
	int size;
	uint8_t buf[8];
	int ret;

	size = oma_tlv_get(&tlv, in, false);
	if (size < 0) {
		return size;
	}

	if (tlv.length != 4U && tlv.length != 8U) {
		LOG_ERR("Invalid float length: %d", tlv.length);
		return -EBADMSG;
	}

	/* read float in network byte order */
	ret = buf_read(buf, tlv.length, CPKT_BUF_READ(in->in_cpkt),
		       &in->offset);
	if (ret < 0) {
		return ret;
	}

	if (tlv.length == 4U) {
		ret = lwm2m_b32_to_float(buf, 4, value);
	} else {
		ret = lwm2m_b64_to_float(buf, 8, value);
	}

	if (ret < 0) {
		LOG_ERR("binary%s conversion error: %d",
			tlv.length == 4U ? "32" : "64", ret);
		return ret;
	}

	return size;
}

static int get_bool(struct lwm2m_input_context *in, bool *value)
{
	int64_t temp;
	int size;

	size = get_number(in, &temp, 2);
	if (size < 0) {
		return size;

	}

	*value = (temp != 0);

	return size;
}

static int get_opaque(struct lwm2m_input_context *in, uint8_t *value,
		      size_t buflen, struct lwm2m_opaque_context *opaque,
		      bool *last_block)
{
	struct oma_tlv tlv;
	int size;

	/* Get the TLV header only on first read. */
	if (opaque->remaining == 0) {
		size = oma_tlv_get(&tlv, in, false);
		if (size < 0) {
			return size;
		}

		opaque->len = tlv.length;
		opaque->remaining = tlv.length;
	}

	return lwm2m_engine_get_opaque_more(in, value, buflen,
					    opaque, last_block);
}

static int get_objlnk(struct lwm2m_input_context *in,
		      struct lwm2m_objlnk *value)
{
	int32_t value_s32;
	int size;

	size = get_s32(in, &value_s32);
	if (size < 0) {
		return size;
	}

	value->obj_id = (value_s32 >> 16) & 0xFFFF;
	value->obj_inst = value_s32 & 0xFFFF;

	return size;
}

const struct lwm2m_writer oma_tlv_writer = {
	.put_begin_oi = put_begin_oi,
	.put_end_oi = put_end_oi,
	.put_begin_ri = put_begin_ri,
	.put_end_ri = put_end_ri,
	.put_s8 = put_s8,
	.put_s16 = put_s16,
	.put_s32 = put_s32,
	.put_s64 = put_s64,
	.put_string = put_string,
	.put_float = put_float,
	.put_time = put_s64,
	.put_bool = put_bool,
	.put_opaque = put_opaque,
	.put_objlnk = put_objlnk,
};

const struct lwm2m_reader oma_tlv_reader = {
	.get_s32 = get_s32,
	.get_s64 = get_s64,
	.get_string = get_string,
	.get_time = get_s64,
	.get_float = get_float,
	.get_bool = get_bool,
	.get_opaque = get_opaque,
	.get_objlnk = get_objlnk,
};

int do_read_op_tlv(struct lwm2m_message *msg, int content_format)
{
	struct tlv_out_formatter_data fd;
	int ret;

	(void)memset(&fd, 0, sizeof(fd));
	engine_set_out_user_data(&msg->out, &fd);
	ret = lwm2m_perform_read_op(msg, content_format);
	engine_clear_out_user_data(&msg->out);
	return ret;
}

static int do_write_op_tlv_dummy_read(struct lwm2m_message *msg)
{
	struct oma_tlv tlv;
	uint8_t read_char;

	oma_tlv_get(&tlv, &msg->in, false);
	while (tlv.length--) {
		if (buf_read_u8(&read_char, CPKT_BUF_READ(msg->in.in_cpkt),
				&msg->in.offset) < 0) {
			break;
		}
	}

	return 0;
}

static int do_write_op_tlv_item(struct lwm2m_message *msg)
{
	struct lwm2m_engine_obj_inst *obj_inst = NULL;
	struct lwm2m_engine_res *res = NULL;
	struct lwm2m_engine_res_inst *res_inst = NULL;
	struct lwm2m_engine_obj_field *obj_field = NULL;
	uint8_t created = 0U;
	int ret;

	ret = lwm2m_get_or_create_engine_obj(msg, &obj_inst, &created);
	if (ret < 0) {
		goto error;
	}

	ret = lwm2m_engine_validate_write_access(msg, obj_inst, &obj_field);
	if (ret < 0) {
		goto error;
	}

	ret = lwm2m_engine_get_create_res_inst(&msg->path, &res, &res_inst);

	if (ret < 0) {
		/* if OPTIONAL and BOOTSTRAP-WRITE or CREATE use ENOTSUP */
		if ((msg->ctx->bootstrap_mode ||
		     msg->operation == LWM2M_OP_CREATE) &&
		    LWM2M_HAS_PERM(obj_field, BIT(LWM2M_FLAG_OPTIONAL))) {
			ret = -ENOTSUP;
			goto error;
		}

		ret = -ENOENT;
		goto error;
	}

	ret = lwm2m_write_handler(obj_inst, res, res_inst, obj_field, msg);
	if (ret == -EACCES || ret == -ENOENT) {
		/* if read-only or non-existent data buffer move on */
		do_write_op_tlv_dummy_read(msg);
		ret = 0;
	}

	return ret;

error:
	do_write_op_tlv_dummy_read(msg);
	return ret;
}

static int write_tlv_resource(struct lwm2m_message *msg, struct oma_tlv *tlv)
{
	int ret;

	if (msg->in.block_ctx) {
		msg->in.block_ctx->res_id = tlv->id;
	}

	msg->path.res_id = tlv->id;
	msg->path.level = 3U;
	ret = do_write_op_tlv_item(msg);

	/*
	 * ignore errors for CREATE op
	 * for OP_CREATE and BOOTSTRAP WRITE: errors on
	 * optional resources are ignored (ENOTSUP)
	 */
	if (ret < 0 &&
	    !((ret == -ENOTSUP) &&
	      (msg->ctx->bootstrap_mode ||
	       msg->operation == LWM2M_OP_CREATE))) {
		return ret;
	}

	return 0;
}

static int lwm2m_multi_resource_tlv_parse(struct lwm2m_message *msg,
					  struct oma_tlv *multi_resource_tlv)
{
	struct oma_tlv tlv_resource_instance;
	int len2;
	int pos = 0;
	int ret;

	if (msg->in.block_ctx) {
		msg->in.block_ctx->res_id = multi_resource_tlv->id;
	}

	if (multi_resource_tlv->length == 0U) {
		/* No data for resource instances, so create only a resource */
		return write_tlv_resource(msg, multi_resource_tlv);
	}

	while (pos < multi_resource_tlv->length &&
	       (len2 = oma_tlv_get(&tlv_resource_instance, &msg->in, true))) {
		if (tlv_resource_instance.type != OMA_TLV_TYPE_RESOURCE_INSTANCE) {
			LOG_ERR("Multi resource id not supported %u %d", tlv_resource_instance.id,
				tlv_resource_instance.length);
			return -ENOTSUP;
		}

		msg->path.res_id = multi_resource_tlv->id;
		msg->path.res_inst_id = tlv_resource_instance.id;
		msg->path.level = LWM2M_PATH_LEVEL_RESOURCE_INST;
		ret = do_write_op_tlv_item(msg);

		/*
		 * Ignore errors on optional resources when doing
		 * BOOTSTRAP WRITE or CREATE operation.
		 */
		if (ret < 0 && !((ret == -ENOTSUP) &&
				 (msg->ctx->bootstrap_mode || msg->operation == LWM2M_OP_CREATE))) {
			return ret;
		}

		pos += len2;
	}

	return 0;
}

int do_write_op_tlv(struct lwm2m_message *msg)
{
	struct lwm2m_engine_obj_inst *obj_inst = NULL;
	int len;
	struct oma_tlv tlv;
	int ret;

	/* In case of block transfer go directly to the
	 * message processing - consecutive blocks will not carry the TLV
	 * header.
	 */
	if (msg->in.block_ctx != NULL && msg->in.block_ctx->ctx.current > 0) {
		msg->path.res_id = msg->in.block_ctx->res_id;
		msg->path.level = 3U;
		ret = do_write_op_tlv_item(msg);
		if (ret < 0) {
			return ret;
		}

		return 0;
	}

	while (true) {
		/*
		 * This initial read of TLV data won't advance frag/offset.
		 * We need tlv.type to determine how to proceed.
		 */
		len = oma_tlv_get(&tlv, &msg->in, true);
		if (len < 0) {
			break;
		}

		if (tlv.type == OMA_TLV_TYPE_OBJECT_INSTANCE) {
			struct oma_tlv tlv2;
			int len2;
			int pos = 0;

			oma_tlv_get(&tlv, &msg->in, false);
			msg->path.obj_inst_id = tlv.id;
			if (tlv.length == 0U) {
				/* Create only - no data */
				ret = lwm2m_create_obj_inst(
						msg->path.obj_id,
						msg->path.obj_inst_id,
						&obj_inst);
				if (ret < 0) {
					return ret;
				}

#ifdef CONFIG_LWM2M_RD_CLIENT_SUPPORT
				if (!msg->ctx->bootstrap_mode) {
					engine_trigger_update(true);
				}
#endif
			}

			while (pos < tlv.length &&
			       (len2 = oma_tlv_get(&tlv2, &msg->in, true))) {
				if (tlv2.type == OMA_TLV_TYPE_RESOURCE) {
					ret = write_tlv_resource(msg, &tlv2);
					if (ret) {
						return ret;
					}
				} else if (tlv2.type == OMA_TLV_TYPE_MULTI_RESOURCE) {
					oma_tlv_get(&tlv2, &msg->in, false);
					ret = lwm2m_multi_resource_tlv_parse(msg, &tlv2);
					if (ret) {
						return ret;
					}
				} else {
					/* Skip Unsupported TLV type */
					return -ENOTSUP;
				}

				pos += len2;
			}
		} else if (tlv.type == OMA_TLV_TYPE_RESOURCE) {
			if (msg->path.level < LWM2M_PATH_LEVEL_OBJECT_INST) {
				return -ENOTSUP;
			}
			ret = write_tlv_resource(msg, &tlv);
			if (ret) {
				return ret;
			}
		} else if (tlv.type == OMA_TLV_TYPE_MULTI_RESOURCE) {
			if (msg->path.level < LWM2M_PATH_LEVEL_OBJECT_INST) {
				return -ENOTSUP;
			}
			oma_tlv_get(&tlv, &msg->in, false);
			ret = lwm2m_multi_resource_tlv_parse(msg, &tlv);
			if (ret) {
				return ret;
			}
		} else {
			return -ENOTSUP;
		}
	}

	return 0;
}
