/** @file
 *  @brief Bluetooth Object Transfer Client
 *
 * Copyright (c) 2020-2022 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/kernel.h>
#include <zephyr/types.h>

#include <zephyr/device.h>
#include <zephyr/init.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/check.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/l2cap.h>

#include <zephyr/bluetooth/services/ots.h>
#include "ots_internal.h"
#include "ots_client_internal.h"
#include "ots_l2cap_internal.h"
#include "ots_dir_list_internal.h"
#include "ots_oacp_internal.h"
#include "ots_olcp_internal.h"

#define LOG_LEVEL CONFIG_BT_OTS_CLIENT_LOG_LEVEL
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(bt_otc);

/* TODO: KConfig options */
#define OTS_CLIENT_INST_COUNT     1

#define OTS_CLIENT_MAX_WRITE_SIZE    23
/* 64-bit value, outside of 48-bit Object ID range */
#define OTS_CLIENT_UNKNOWN_ID      0x0001000000000000

struct dirlisting_record_t {
	uint16_t                      len;
	uint8_t                       flags;
	uint8_t                       name_len;
	struct bt_ots_obj_metadata    metadata;
};

/**@brief String literals for the OACP result codes. Used for logging output.*/
static const char * const lit_request[] = {
	"RFU",
	"Create",
	"Delete",
	"Calculate Checksum",
	"Execute",
	"Read",
	"Write",
	"Abort",
};

/**@brief String literals for the OACP result codes. Used for logging output.*/
static const char * const lit_result[] = {
	"RFU",
	"Success",
	"Op Code Not Supported",
	"Invalid Parameter",
	"Insufficient Resources",
	"Invalid Object",
	"Channel Unavailable",
	"Unsupported Type",
	"Procedure Not Permitted",
	"Object Locked",
	"Operation Failed"
};

/**@brief String literals for the OLCP request codes. Used for logging output.*/
static const char * const lit_olcp_request[] = {
	"RFU",
	"FIRST",
	"LAST",
	"PREV",
	"NEXT",
	"GOTO",
	"ORDER",
	"REQ_NUM_OBJS",
	"CLEAR_MARKING",
};

/**@brief String literals for the OLCP result codes. Used for logging output.*/
static const char * const lit_olcp_result[] = {
	"RFU",
	"Success",
	"Op Code Not Supported",
	"Invalid Parameter",
	"Operation Failed",
	"Out of Bonds",
	"Too Many Objects",
	"No Object",
	"Object ID not found",
};

struct bt_otc_internal_instance_t {
	struct bt_ots_client *otc_inst;
	struct bt_gatt_ots_l2cap l2cap_ctx;
	bool busy;
	/** Bitfield that is used to determine how much metadata to read */
	uint8_t metadata_to_read;
	/** Bitfield of how much metadata has been attempted to read */
	uint8_t metadata_read_attempted;
	/** Bitfield of how much metadata has been read */
	uint8_t metadata_read;
	int metadata_err;
	uint32_t rcvd_size;
	uint32_t sent_size;
};

/* The profile clients that uses the OTS are responsible for discovery and
 * will simply register any OTS instances as pointers, which is stored here.
 */
static struct bt_otc_internal_instance_t otc_insts[OTS_CLIENT_INST_COUNT];
NET_BUF_SIMPLE_DEFINE_STATIC(otc_tx_buf, OTS_CLIENT_MAX_WRITE_SIZE);
static struct bt_otc_internal_instance_t *cur_inst;

static int oacp_read(struct bt_conn *conn,
		     struct bt_otc_internal_instance_t *inst);
static int oacp_write(struct bt_conn *conn, struct bt_otc_internal_instance_t *inst,
		      const void *buf, uint32_t len, uint32_t offset,
		      enum bt_ots_oacp_write_op_mode mode);
static void read_next_metadata(struct bt_conn *conn,
			       struct bt_otc_internal_instance_t *inst);
static int read_attr(struct bt_conn *conn,
		     struct bt_otc_internal_instance_t *inst,
		     uint16_t handle, bt_gatt_read_func_t cb);

/* L2CAP callbacks */
static void tx_done(struct bt_gatt_ots_l2cap *l2cap_ctx,
		    struct bt_conn *conn)
{
	/* Not doing any writes yet */
	LOG_ERR("Unexpected call, context: %p, conn: %p", l2cap_ctx, (void *)conn);
}

static void write_obj_tx_done(struct bt_gatt_ots_l2cap *l2cap_ctx,
			      struct bt_conn *conn)
{
	int err;
	size_t written;

	if (cur_inst == NULL) {
		LOG_ERR("OTS instance invalid\n");
		return;
	}

	written = cur_inst->sent_size;
	LOG_DBG("ctx: %p, conn: %p, written: %d", l2cap_ctx, (void *)conn, written);

	err = bt_gatt_ots_l2cap_disconnect(l2cap_ctx);
	if (err < 0) {
		LOG_WRN("Disconnecting L2CAP returned error %d", err);
	}

	if ((cur_inst->otc_inst != NULL) && (cur_inst->otc_inst->cb != NULL)) {
		if (cur_inst->otc_inst->cb->obj_data_written) {
			cur_inst->otc_inst->cb->obj_data_written(0, conn, written);
		}
	}

	cur_inst = NULL;
}

static ssize_t rx_done(struct bt_gatt_ots_l2cap *l2cap_ctx,
		       struct bt_conn *conn, struct net_buf *buf)
{
	const uint32_t offset = cur_inst->rcvd_size;
	bool is_complete = false;
	const struct bt_ots_obj_metadata *cur_object =
		&cur_inst->otc_inst->cur_object;
	int cb_ret;

	LOG_DBG("Incoming L2CAP data, context: %p, conn: %p, len: %u, offset: %u", l2cap_ctx,
		(void *)conn, buf->len, offset);

	cur_inst->rcvd_size += buf->len;

	if (cur_inst->rcvd_size >= cur_object->size.cur) {
		is_complete = true;
	}

	if (cur_inst->rcvd_size > cur_object->size.cur) {
		LOG_WRN("Received %u but expected maximum %u", cur_inst->rcvd_size,
			cur_object->size.cur);
	}

	cb_ret = cur_inst->otc_inst->cb->obj_data_read(0, conn, offset,
						       buf->len, buf->data,
						       is_complete);

	if (is_complete) {
		const uint32_t rcv_size = cur_object->size.cur;
		int err;

		LOG_DBG("Received the whole object (%u bytes). "
		       "Disconnecting L2CAP CoC", rcv_size);
		err = bt_gatt_ots_l2cap_disconnect(l2cap_ctx);
		if (err < 0) {
			LOG_WRN("Disconnecting L2CAP returned error %d", err);
		}

		cur_inst = NULL;
	} else if (cb_ret == BT_OTS_STOP) {
		const uint32_t rcv_size = cur_object->size.cur;
		int err;

		LOG_DBG("Stopped receiving after%u bytes. "
		       "Disconnecting L2CAP CoC", rcv_size);
		err = bt_gatt_ots_l2cap_disconnect(l2cap_ctx);

		if (err < 0) {
			LOG_WRN("Disconnecting L2CAP returned error %d", err);
		}

		cur_inst = NULL;
	}

	return 0;
}

static void chan_closed(struct bt_gatt_ots_l2cap *l2cap_ctx,
			struct bt_conn *conn)
{
	LOG_DBG("L2CAP closed, context: %p, conn: %p", l2cap_ctx, (void *)conn);
}
/* End L2CAP callbacks */

static void print_oacp_response(enum bt_gatt_ots_oacp_proc_type req_opcode,
				enum bt_gatt_ots_oacp_res_code result_code)
{
	LOG_DBG("Request OP Code: %s", lit_request[req_opcode]);
	LOG_DBG("Result Code    : %s", lit_result[result_code]);
}

static void print_olcp_response(enum bt_gatt_ots_olcp_proc_type req_opcode,
				enum bt_gatt_ots_olcp_res_code result_code)
{
	LOG_DBG("Request OP Code: %s", lit_olcp_request[req_opcode]);
	LOG_DBG("Result Code    : %s", lit_olcp_result[result_code]);
}

static void date_time_decode(struct net_buf_simple *buf,
			     struct bt_ots_date_time *p_date_time)
{
	p_date_time->year = net_buf_simple_pull_le16(buf);
	p_date_time->month = net_buf_simple_pull_u8(buf);
	p_date_time->day = net_buf_simple_pull_u8(buf);
	p_date_time->hours = net_buf_simple_pull_u8(buf);
	p_date_time->minutes = net_buf_simple_pull_u8(buf);
	p_date_time->seconds = net_buf_simple_pull_u8(buf);
}

static struct bt_otc_internal_instance_t *lookup_inst_by_handle(uint16_t handle)
{
	for (int i = 0; i < ARRAY_SIZE(otc_insts); i++) {
		if (otc_insts[i].otc_inst &&
		    otc_insts[i].otc_inst->start_handle <= handle &&
		    otc_insts[i].otc_inst->end_handle >= handle) {
			return &otc_insts[i];
		}
	}

	LOG_DBG("Could not find OTS instance with handle 0x%04x", handle);

	return NULL;
}

static void on_object_selected(struct bt_conn *conn,
			       enum bt_gatt_ots_olcp_res_code res,
			       struct bt_ots_client *otc_inst)
{
	memset(&otc_inst->cur_object, 0, sizeof(otc_inst->cur_object));
	otc_inst->cur_object.id = OTS_CLIENT_UNKNOWN_ID;

	if (otc_inst->cb->obj_selected) {
		otc_inst->cb->obj_selected(otc_inst, conn, res);
	}

	LOG_DBG("Object selected");
}

static void olcp_ind_handler(struct bt_conn *conn,
			     struct bt_ots_client *otc_inst,
			     const void *data, uint16_t length)
{
	enum bt_gatt_ots_olcp_proc_type op_code;
	struct net_buf_simple net_buf;

	net_buf_simple_init_with_data(&net_buf, (void *)data, length);

	op_code = net_buf_simple_pull_u8(&net_buf);

	LOG_DBG("OLCP indication");

	if (op_code == BT_GATT_OTS_OLCP_PROC_RESP) {
		enum bt_gatt_ots_olcp_proc_type req_opcode =
			net_buf_simple_pull_u8(&net_buf);
		enum bt_gatt_ots_olcp_res_code result_code =
			net_buf_simple_pull_u8(&net_buf);

		print_olcp_response(req_opcode, result_code);

		switch (req_opcode) {
		case BT_GATT_OTS_OLCP_PROC_FIRST:
			LOG_DBG("First");
			on_object_selected(conn, result_code, otc_inst);
			break;
		case BT_GATT_OTS_OLCP_PROC_LAST:
			LOG_DBG("Last");
			on_object_selected(conn, result_code, otc_inst);
			break;
		case BT_GATT_OTS_OLCP_PROC_PREV:
			LOG_DBG("Previous");
			on_object_selected(conn, result_code, otc_inst);
			break;
		case BT_GATT_OTS_OLCP_PROC_NEXT:
			LOG_DBG("Next");
			on_object_selected(conn, result_code, otc_inst);
			break;
		case BT_GATT_OTS_OLCP_PROC_GOTO:
			LOG_DBG("Goto");
			on_object_selected(conn, result_code, otc_inst);
			break;
		case BT_GATT_OTS_OLCP_PROC_ORDER:
			LOG_DBG("Order");
			on_object_selected(conn, result_code, otc_inst);
			break;
		case BT_GATT_OTS_OLCP_PROC_REQ_NUM_OBJS:
			LOG_DBG("Request number of objects");
			if (net_buf.len == sizeof(uint32_t)) {
				uint32_t obj_cnt =
					net_buf_simple_pull_le32(&net_buf);
				LOG_DBG("Number of objects %u", obj_cnt);
			}
			break;
		case BT_GATT_OTS_OLCP_PROC_CLEAR_MARKING:
			LOG_DBG("Clear marking");
			break;
		default:
			LOG_DBG("Invalid indication req opcode %u", req_opcode);
			break;
		}
	} else {
		LOG_DBG("Invalid indication opcode %u", op_code);
	}
}

static void oacp_ind_handler(struct bt_conn *conn,
			     struct bt_ots_client *otc_inst,
			     const void *data, uint16_t length)
{
	enum bt_gatt_ots_oacp_proc_type op_code;
	struct net_buf_simple net_buf;

	net_buf_simple_init_with_data(&net_buf, (void *)data, length);

	op_code = net_buf_simple_pull_u8(&net_buf);

	LOG_DBG("OACP indication");

	if (op_code == BT_GATT_OTS_OACP_PROC_RESP) {
		enum bt_gatt_ots_oacp_proc_type req_opcode  =
			net_buf_simple_pull_u8(&net_buf);
		enum bt_gatt_ots_oacp_res_code  result_code =
			net_buf_simple_pull_u8(&net_buf);
		print_oacp_response(req_opcode, result_code);
	} else {
		LOG_DBG("Invalid indication opcode %u", op_code);
	}
}

uint8_t bt_ots_client_indicate_handler(struct bt_conn *conn,
				       struct bt_gatt_subscribe_params *params,
				       const void *data, uint16_t length)
{
	uint16_t handle = params->value_handle;
	struct bt_otc_internal_instance_t *inst;

	if (conn == NULL) {
		return BT_GATT_ITER_CONTINUE;
	}

	inst = lookup_inst_by_handle(handle);

	/* TODO: Can we somehow avoid exposing this
	 * callback via the public API?
	 */

	if (!inst) {
		LOG_ERR("Instance not found");
		return BT_GATT_ITER_STOP;
	}

	inst->busy = false;

	if (data) {
		if (handle == inst->otc_inst->olcp_handle) {
			olcp_ind_handler(conn, inst->otc_inst, data, length);
		} else if (handle == inst->otc_inst->oacp_handle) {
			oacp_ind_handler(conn, inst->otc_inst, data, length);
		}
	}
	return BT_GATT_ITER_CONTINUE;
}

static uint8_t read_feature_cb(struct bt_conn *conn, uint8_t err,
			       struct bt_gatt_read_params *params,
			       const void *data, uint16_t length)
{
	uint8_t cb_err = err;
	struct bt_otc_internal_instance_t *inst =
		lookup_inst_by_handle(params->single.handle);
	struct net_buf_simple net_buf;

	net_buf_simple_init_with_data(&net_buf, (void *)data, length);

	if (!inst) {
		LOG_ERR("Instance not found");
		return BT_GATT_ITER_STOP;
	}

	inst->busy = false;

	if (err) {
		LOG_DBG("err: 0x%02X", err);
	} else if (data) {
		if (length == OTS_FEATURE_LEN) {
			inst->otc_inst->features.oacp =
				net_buf_simple_pull_le32(&net_buf);

			inst->otc_inst->features.olcp =
				net_buf_simple_pull_le32(&net_buf);

			LOG_DBG("features : oacp 0x%x, olcp 0x%x", inst->otc_inst->features.oacp,
				inst->otc_inst->features.olcp);
		} else {
			LOG_DBG("Invalid length %u (expected %u)", length, OTS_FEATURE_LEN);
			cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
		}
	}

	return BT_GATT_ITER_STOP;
}

int bt_ots_client_register(struct bt_ots_client *otc_inst)
{
	for (int i = 0; i < ARRAY_SIZE(otc_insts); i++) {
		int err;

		if (otc_insts[i].otc_inst) {
			continue;
		}

		LOG_DBG("%u", i);
		err = bt_gatt_ots_l2cap_register(&otc_insts[i].l2cap_ctx);
		if (err) {
			LOG_WRN("Could not register L2CAP context %d", err);
			return err;
		}

		otc_insts[i].otc_inst = otc_inst;
		return 0;
	}

	return -ENOMEM;
}

int bt_ots_client_unregister(uint8_t index)
{
	if (index < ARRAY_SIZE(otc_insts)) {
		memset(&otc_insts[index], 0, sizeof(otc_insts[index]));
	} else {
		return -EINVAL;
	}

	return 0;
}

int bt_ots_client_read_feature(struct bt_ots_client *otc_inst,
			       struct bt_conn *conn)
{
	if (OTS_CLIENT_INST_COUNT > 0) {
		struct bt_otc_internal_instance_t *inst;
		int err;

		if (!conn) {
			LOG_WRN("Invalid Connection");
			return -ENOTCONN;
		} else if (!otc_inst) {
			LOG_ERR("Invalid OTC instance");
			return -EINVAL;
		} else if (!otc_inst->feature_handle) {
			LOG_DBG("Handle not set");
			return -EINVAL;
		}

		inst = lookup_inst_by_handle(otc_inst->start_handle);

		if (!inst) {
			LOG_ERR("Invalid OTC instance");
			return -EINVAL;
		} else if (inst->busy) {
			return -EBUSY;
		}

		otc_inst->read_proc.func = read_feature_cb;
		otc_inst->read_proc.handle_count = 1;
		otc_inst->read_proc.single.handle = otc_inst->feature_handle;
		otc_inst->read_proc.single.offset = 0U;

		err = bt_gatt_read(conn, &otc_inst->read_proc);
		if (!err) {
			inst->busy = true;
		}
		return err;
	}

	LOG_DBG("Not supported");
	return -EOPNOTSUPP;
}

static void write_olcp_cb(struct bt_conn *conn, uint8_t err,
			  struct bt_gatt_write_params *params)
{
	struct bt_otc_internal_instance_t *inst =
		lookup_inst_by_handle(params->handle);

	LOG_DBG("Write %s (0x%02X)", err ? "failed" : "successful", err);

	if (!inst) {
		LOG_ERR("Instance not found");
		return;
	}

	inst->busy = false;
}

static int write_olcp(struct bt_otc_internal_instance_t *inst,
		      struct bt_conn *conn, enum bt_gatt_ots_olcp_proc_type opcode,
		      uint8_t *params, uint8_t param_len)
{
	int err;

	net_buf_simple_reset(&otc_tx_buf);

	net_buf_simple_add_u8(&otc_tx_buf, opcode);

	if (param_len && params) {
		net_buf_simple_add_mem(&otc_tx_buf, params, param_len);
	}

	inst->otc_inst->write_params.offset = 0;
	inst->otc_inst->write_params.data = otc_tx_buf.data;
	inst->otc_inst->write_params.length = otc_tx_buf.len;
	inst->otc_inst->write_params.handle = inst->otc_inst->olcp_handle;
	inst->otc_inst->write_params.func = write_olcp_cb;

	err = bt_gatt_write(conn, &inst->otc_inst->write_params);

	if (!err) {
		inst->busy = true;
	}
	return err;
}

int bt_ots_client_select_id(struct bt_ots_client *otc_inst,
			    struct bt_conn *conn,
			    uint64_t obj_id)
{
	if (OTS_CLIENT_INST_COUNT > 0) {
		struct bt_otc_internal_instance_t *inst;
		uint8_t param[BT_OTS_OBJ_ID_SIZE];

		if (!conn) {
			LOG_WRN("Invalid Connection");
			return -ENOTCONN;
		} else if (!otc_inst) {
			LOG_ERR("Invalid OTC instance");
			return -EINVAL;
		} else if (!otc_inst->olcp_handle) {
			LOG_DBG("Handle not set");
			return -EINVAL;
		}

		inst = lookup_inst_by_handle(otc_inst->start_handle);

		if (!inst) {
			LOG_ERR("Invalid OTC instance");
			return -EINVAL;
		} else if (inst->busy) {
			return -EBUSY;
		}

		/* TODO: Should not update this before ID is read */
		otc_inst->cur_object.id = obj_id;
		sys_put_le48(obj_id, param);

		return write_olcp(inst, conn, BT_GATT_OTS_OLCP_PROC_GOTO,
				  param, BT_OTS_OBJ_ID_SIZE);
	}

	LOG_DBG("Not supported");
	return -EOPNOTSUPP;
}

int bt_ots_client_select_first(struct bt_ots_client *otc_inst,
			       struct bt_conn *conn)
{
	if (OTS_CLIENT_INST_COUNT > 0) {
		struct bt_otc_internal_instance_t *inst;

		if (!conn) {
			LOG_WRN("Invalid Connection");
			return -ENOTCONN;
		} else if (!otc_inst) {
			LOG_ERR("Invalid OTC instance");
			return -EINVAL;
		} else if (!otc_inst->olcp_handle) {
			LOG_DBG("Handle not set");
			return -EINVAL;
		}

		inst = lookup_inst_by_handle(otc_inst->start_handle);

		if (!inst) {
			LOG_ERR("Invalid OTC instance");
			return -EINVAL;
		} else if (inst->busy) {
			return -EBUSY;
		}

		return write_olcp(inst, conn, BT_GATT_OTS_OLCP_PROC_FIRST,
				  NULL, 0);
	}

	LOG_DBG("Not supported");
	return -EOPNOTSUPP;
}

int bt_ots_client_select_last(struct bt_ots_client *otc_inst,
			      struct bt_conn *conn)
{
	if (OTS_CLIENT_INST_COUNT > 0) {
		struct bt_otc_internal_instance_t *inst;

		if (!conn) {
			LOG_WRN("Invalid Connection");
			return -ENOTCONN;
		} else if (!otc_inst) {
			LOG_ERR("Invalid OTC instance");
			return -EINVAL;
		} else if (!otc_inst->olcp_handle) {
			LOG_DBG("Handle not set");
			return -EINVAL;
		}

		inst = lookup_inst_by_handle(otc_inst->start_handle);

		if (!inst) {
			LOG_ERR("Invalid OTC instance");
			return -EINVAL;
		} else if (inst->busy) {
			return -EBUSY;
		}

		return write_olcp(inst, conn, BT_GATT_OTS_OLCP_PROC_LAST,
				  NULL, 0);

	}

	LOG_DBG("Not supported");
	return -EOPNOTSUPP;
}

int bt_ots_client_select_next(struct bt_ots_client *otc_inst,
			      struct bt_conn *conn)
{
	if (OTS_CLIENT_INST_COUNT > 0) {
		struct bt_otc_internal_instance_t *inst;

		if (!conn) {
			LOG_WRN("Invalid Connection");
			return -ENOTCONN;
		} else if (!otc_inst) {
			LOG_ERR("Invalid OTC instance");
			return -EINVAL;
		} else if (!otc_inst->olcp_handle) {
			LOG_DBG("Handle not set");
			return -EINVAL;
		}

		inst = lookup_inst_by_handle(otc_inst->start_handle);

		if (!inst) {
			LOG_ERR("Invalid OTC instance");
			return -EINVAL;
		} else if (inst->busy) {
			return -EBUSY;
		}

		return write_olcp(inst, conn, BT_GATT_OTS_OLCP_PROC_NEXT,
				  NULL, 0);
	}

	LOG_DBG("Not supported");
	return -EOPNOTSUPP;
}

int bt_ots_client_select_prev(struct bt_ots_client *otc_inst,
			      struct bt_conn *conn)
{
	if (OTS_CLIENT_INST_COUNT > 0) {
		struct bt_otc_internal_instance_t *inst;

		if (!conn) {
			LOG_WRN("Invalid Connection");
			return -ENOTCONN;
		} else if (!otc_inst) {
			LOG_ERR("Invalid OTC instance");
			return -EINVAL;
		} else if (!otc_inst->olcp_handle) {
			LOG_DBG("Handle not set");
			return -EINVAL;
		}

		inst = lookup_inst_by_handle(otc_inst->start_handle);

		if (!inst) {
			LOG_ERR("Invalid OTC instance");
			return -EINVAL;
		} else if (inst->busy) {
			return -EBUSY;
		}

		return write_olcp(inst, conn, BT_GATT_OTS_OLCP_PROC_PREV,
				  NULL, 0);
	}

	LOG_DBG("Not supported");
	return -EOPNOTSUPP;
}

static uint8_t read_object_size_cb(struct bt_conn *conn, uint8_t err,
				   struct bt_gatt_read_params *params,
				   const void *data, uint16_t length)
{
	struct bt_otc_internal_instance_t *inst =
		lookup_inst_by_handle(params->single.handle);
	struct net_buf_simple net_buf;

	net_buf_simple_init_with_data(&net_buf, (void *)data, length);

	LOG_DBG("handle %d, length %u", params->single.handle, length);

	if (!inst) {
		LOG_ERR("Instance not found");
		return BT_GATT_ITER_STOP;
	}

	if (err) {
		LOG_DBG("err: 0x%02X", err);
	} else if (data) {
		if (length != OTS_SIZE_LEN) {
			LOG_DBG("Invalid length %u (expected %u)", length, OTS_SIZE_LEN);
			err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
		} else {
			struct bt_ots_obj_metadata *cur_object =
				&inst->otc_inst->cur_object;
			cur_object->size.cur =
				net_buf_simple_pull_le32(&net_buf);
			cur_object->size.alloc =
				net_buf_simple_pull_le32(&net_buf);

			LOG_DBG("Object Size : current size %u, "
			       "allocated size %u",
			       cur_object->size.cur,
			       cur_object->size.alloc);

			if (cur_object->size.cur == 0) {
				LOG_WRN("Obj size read returned a current "
					"size of 0");
			} else if (cur_object->size.cur >
					cur_object->size.alloc &&
				   cur_object->size.alloc != 0) {
				LOG_WRN("Allocated size %u is smaller than "
					"current size %u",
					cur_object->size.alloc,
					cur_object->size.cur);
			}

			BT_OTS_SET_METADATA_REQ_SIZE(inst->metadata_read);
		}
	}

	if (err) {
		LOG_WRN("err: 0x%02X", err);
		if (!inst->metadata_err) {
			inst->metadata_err = err;
		}
	}

	read_next_metadata(conn, inst);

	return BT_GATT_ITER_STOP;
}

static uint8_t read_obj_id_cb(struct bt_conn *conn, uint8_t err,
			      struct bt_gatt_read_params *params,
			      const void *data, uint16_t length)
{
	struct bt_otc_internal_instance_t *inst =
		lookup_inst_by_handle(params->single.handle);
	struct net_buf_simple net_buf;

	net_buf_simple_init_with_data(&net_buf, (void *)data, length);

	LOG_DBG("handle %d, length %u", params->single.handle, length);

	if (!inst) {
		LOG_ERR("Instance not found");
		return BT_GATT_ITER_STOP;
	}

	if (err) {
		LOG_DBG("err: 0x%02X", err);
	} else if (data) {
		if (length == BT_OTS_OBJ_ID_SIZE) {
			uint64_t obj_id = net_buf_simple_pull_le48(&net_buf);
			char t[BT_OTS_OBJ_ID_STR_LEN];
			struct bt_ots_obj_metadata *cur_object =
				&inst->otc_inst->cur_object;

			(void)bt_ots_obj_id_to_str(obj_id, t, sizeof(t));
			LOG_DBG("Object Id : %s", t);

			if (cur_object->id != OTS_CLIENT_UNKNOWN_ID &&
			    cur_object->id != obj_id) {
				char str[BT_OTS_OBJ_ID_STR_LEN];

				(void)bt_ots_obj_id_to_str(cur_object->id, str,
							   sizeof(str));
				LOG_INF("Read Obj Id %s not selected obj Id %s", t, str);
			} else {
				LOG_INF("Read Obj Id confirmed correct Obj Id");
				cur_object->id = obj_id;

				BT_OTS_SET_METADATA_REQ_ID(inst->metadata_read);
			}
		} else {
			LOG_DBG("Invalid length %u (expected %u)", length, BT_OTS_OBJ_ID_SIZE);
			err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
		}
	}

	if (err) {
		LOG_WRN("err: 0x%02X", err);
		if (!inst->metadata_err) {
			inst->metadata_err = err;
		}
	}

	read_next_metadata(conn, inst);

	return BT_GATT_ITER_STOP;
}

static uint8_t read_obj_name_cb(struct bt_conn *conn, uint8_t err,
				struct bt_gatt_read_params *params,
				const void *data, uint16_t length)
{
	struct bt_otc_internal_instance_t *inst =
		lookup_inst_by_handle(params->single.handle);

	LOG_DBG("handle %d, length %u", params->single.handle, length);

	if (!inst) {
		LOG_ERR("Instance not found");
		return BT_GATT_ITER_STOP;
	}

	if (data) {
		if (length <= CONFIG_BT_OTS_OBJ_MAX_NAME_LEN) {
			memcpy(inst->otc_inst->cur_object.name_c, data, length);
			inst->otc_inst->cur_object.name_c[length] = '\0';
		} else {
			LOG_WRN("Invalid length %u (expected max %u)", length,
				CONFIG_BT_OTS_OBJ_MAX_NAME_LEN);
			err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
		}
	}

	if (err) {
		LOG_WRN("err: 0x%02X", err);
		if (!inst->metadata_err) {
			inst->metadata_err = err;
		}
	}

	read_next_metadata(conn, inst);

	return BT_GATT_ITER_STOP;
}

static uint8_t read_obj_type_cb(struct bt_conn *conn, uint8_t err,
				struct bt_gatt_read_params *params,
				const void *data, uint16_t length)
{
	struct bt_otc_internal_instance_t *inst =
		lookup_inst_by_handle(params->single.handle);

	LOG_DBG("handle %d, length %u", params->single.handle, length);

	if (!inst) {
		LOG_ERR("Instance not found");
		return BT_GATT_ITER_STOP;
	}

	if (data) {
		if (length == BT_UUID_SIZE_128 || length == BT_UUID_SIZE_16) {
			char uuid_str[BT_UUID_STR_LEN];
			struct bt_uuid *uuid =
				&inst->otc_inst->cur_object.type.uuid;

			bt_uuid_create(uuid, data, length);

			bt_uuid_to_str(uuid, uuid_str, sizeof(uuid_str));
			LOG_DBG("UUID type read: %s", uuid_str);

			BT_OTS_SET_METADATA_REQ_TYPE(inst->metadata_read);
		} else {
			LOG_WRN("Invalid length %u (expected max %u)", length, OTS_TYPE_MAX_LEN);
			err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
		}
	}

	if (err) {
		LOG_WRN("err: 0x%02X", err);
		if (!inst->metadata_err) {
			inst->metadata_err = err;
		}
	}

	read_next_metadata(conn, inst);

	return BT_GATT_ITER_STOP;
}


static uint8_t read_obj_created_cb(struct bt_conn *conn, uint8_t err,
				   struct bt_gatt_read_params *params,
				   const void *data, uint16_t length)
{
	struct bt_otc_internal_instance_t *inst =
		lookup_inst_by_handle(params->single.handle);
	struct net_buf_simple net_buf;

	net_buf_simple_init_with_data(&net_buf, (void *)data, length);

	LOG_DBG("handle %d, length %u", params->single.handle, length);

	if (!inst) {
		LOG_ERR("Instance not found");
		return BT_GATT_ITER_STOP;
	}

	if (data) {
		if (length <= BT_OTS_DATE_TIME_FIELD_SIZE) {
			date_time_decode(
				&net_buf,
				&inst->otc_inst->cur_object.first_created);
		} else {
			LOG_WRN("Invalid length %u (expected max %u)", length,
				BT_OTS_DATE_TIME_FIELD_SIZE);
			err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
		}
	}

	if (err) {
		LOG_WRN("err: 0x%02X", err);
		if (!inst->metadata_err) {
			inst->metadata_err = err;
		}
	}

	read_next_metadata(conn, inst);

	return BT_GATT_ITER_STOP;
}

static uint8_t read_obj_modified_cb(struct bt_conn *conn, uint8_t err,
				    struct bt_gatt_read_params *params,
				    const void *data, uint16_t length)
{
	struct bt_otc_internal_instance_t *inst =
		lookup_inst_by_handle(params->single.handle);
	struct net_buf_simple net_buf;

	net_buf_simple_init_with_data(&net_buf, (void *)data, length);

	LOG_DBG("handle %d, length %u", params->single.handle, length);

	if (!inst) {
		LOG_ERR("Instance not found");
		return BT_GATT_ITER_STOP;
	}

	if (data) {
		if (length <= BT_OTS_DATE_TIME_FIELD_SIZE) {
			date_time_decode(&net_buf,
					 &inst->otc_inst->cur_object.modified);
		} else {
			LOG_WRN("Invalid length %u (expected max %u)", length,
				BT_OTS_DATE_TIME_FIELD_SIZE);
			err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
		}
	}

	if (err) {
		LOG_WRN("err: 0x%02X", err);
		if (!inst->metadata_err) {
			inst->metadata_err = err;
		}
	}

	read_next_metadata(conn, inst);

	return BT_GATT_ITER_STOP;
}

static int read_attr(struct bt_conn *conn,
		     struct bt_otc_internal_instance_t *inst,
		     uint16_t handle, bt_gatt_read_func_t cb)
{
	if (!handle) {
		LOG_DBG("Handle not set");
		return -EINVAL;
	} else if (cb == NULL) {
		LOG_ERR("No callback set");
		return -EINVAL;
	}

	/* TODO: With EATT we can request multiple metadata to be read at once*/
	inst->otc_inst->read_proc.func = cb;
	inst->otc_inst->read_proc.handle_count = 1;
	inst->otc_inst->read_proc.single.handle = handle;
	inst->otc_inst->read_proc.single.offset = 0;

	return bt_gatt_read(conn, &inst->otc_inst->read_proc);
}

static uint8_t read_obj_properties_cb(struct bt_conn *conn, uint8_t err,
				      struct bt_gatt_read_params *params,
				      const void *data, uint16_t length)
{
	uint8_t cb_err = err;
	struct bt_otc_internal_instance_t *inst =
		lookup_inst_by_handle(params->single.handle);
	struct net_buf_simple net_buf;

	net_buf_simple_init_with_data(&net_buf, (void *)data, length);

	LOG_INF("handle %d, length %u", params->single.handle, length);

	if (!inst) {
		LOG_ERR("Instance not found");
		return BT_GATT_ITER_STOP;
	}

	if (err) {
		LOG_WRN("err: 0x%02X", err);
	} else if (data && length <= OTS_PROPERTIES_LEN) {
		struct bt_ots_obj_metadata *cur_object =
			&inst->otc_inst->cur_object;

		cur_object->props = net_buf_simple_pull_le32(&net_buf);

		LOG_INF("Object properties (raw) : 0x%x", cur_object->props);

		if (!BT_OTS_OBJ_GET_PROP_READ(cur_object->props)) {
			LOG_WRN("Obj properties: Obj read not supported");
		}

		BT_OTS_SET_METADATA_REQ_PROPS(inst->metadata_read);
	} else {
		LOG_WRN("Invalid length %u (expected %u)", length, OTS_PROPERTIES_LEN);
		cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
	}

	if (err) {
		LOG_WRN("err: 0x%02X", err);
		if (!inst->metadata_err) {
			inst->metadata_err = err;
		}
	}

	read_next_metadata(conn, inst);

	return BT_GATT_ITER_STOP;
}

static void write_oacp_cp_cb(struct bt_conn *conn, uint8_t err,
			     struct bt_gatt_write_params *params)
{
	struct bt_otc_internal_instance_t *inst =
		lookup_inst_by_handle(params->handle);

	LOG_DBG("Write %s (0x%02X)", err ? "failed" : "successful", err);

	if (!inst) {
		LOG_ERR("Instance not found");
		return;
	}

	inst->busy = false;
}

static void write_oacp_cp_write_req_cb(struct bt_conn *conn, uint8_t err,
				       struct bt_gatt_write_params *params)
{
	struct bt_otc_internal_instance_t *inst =
		lookup_inst_by_handle(params->handle);
	uint32_t len;

	LOG_DBG("Write Object request %s (0x%02X)", err ? "failed" : "successful", err);
	if (!inst) {
		LOG_ERR("Instance not found");
		return;
	}

	len = inst->l2cap_ctx.tx.len;
	inst->l2cap_ctx.tx.len = 0;
	err = bt_gatt_ots_l2cap_send(&inst->l2cap_ctx, inst->l2cap_ctx.tx.data, len);
	if (err) {
		LOG_WRN("L2CAP CoC error: %d while trying to execute OACP "
			"Read procedure", err);
	}

	inst->busy = false;
}

static int oacp_read(struct bt_conn *conn,
		     struct bt_otc_internal_instance_t *inst)
{
	int err;
	uint32_t offset = 0;
	uint32_t length;
	struct bt_gatt_ots_l2cap *l2cap;

	if (!inst->otc_inst->oacp_handle) {
		LOG_DBG("Handle not set");
		return -EINVAL;
	} else if (inst->busy) {
		return -EBUSY;
	} else if (cur_inst) {
		return -EBUSY;
	}

	/* TODO: How do we ensure that the L2CAP is connected in time for the
	 * transfer?
	 */

	err = bt_gatt_ots_l2cap_connect(conn, &l2cap);
	if (err) {
		LOG_DBG("Could not connect l2cap: %d", err);
		return err;
	}

	l2cap->tx_done = tx_done;
	l2cap->rx_done = rx_done;
	l2cap->closed  = chan_closed;

	net_buf_simple_reset(&otc_tx_buf);

	/* OP Code */
	net_buf_simple_add_u8(&otc_tx_buf, BT_GATT_OTS_OACP_PROC_READ);

	/* Offset */
	net_buf_simple_add_le32(&otc_tx_buf, offset);

	/* Len */
	length = inst->otc_inst->cur_object.size.cur - offset;
	net_buf_simple_add_le32(&otc_tx_buf, length);

	inst->otc_inst->write_params.offset = 0;
	inst->otc_inst->write_params.data = otc_tx_buf.data;
	inst->otc_inst->write_params.length = otc_tx_buf.len;
	inst->otc_inst->write_params.handle = inst->otc_inst->oacp_handle;
	inst->otc_inst->write_params.func = write_oacp_cp_cb;

	err = bt_gatt_write(conn, &inst->otc_inst->write_params);

	if (!err) {
		inst->busy = true;
	}

	cur_inst = inst;
	inst->rcvd_size = 0;

	return err;
}

static int oacp_write(struct bt_conn *conn, struct bt_otc_internal_instance_t *inst,
		      const void *buf, uint32_t len, uint32_t offset,
		      enum bt_ots_oacp_write_op_mode mode)
{
	int err;
	struct bt_gatt_ots_l2cap *l2cap;

	if (!inst->otc_inst->oacp_handle) {
		LOG_DBG("Handle not set");
		return -EINVAL;
	} else if (inst->busy) {
		return -EBUSY;
	} else if (cur_inst) {
		return -EBUSY;
	}

	err = bt_gatt_ots_l2cap_connect(conn, &l2cap);
	if (err) {
		LOG_DBG("Could not connect l2cap: %d", err);
		return err;
	}

	l2cap->tx_done = write_obj_tx_done;
	l2cap->rx_done = rx_done;
	l2cap->closed  = chan_closed;
	l2cap->tx.data = (uint8_t *)buf;
	l2cap->tx.len = len;
	net_buf_simple_reset(&otc_tx_buf);

	/* OP Code */
	net_buf_simple_add_u8(&otc_tx_buf, BT_GATT_OTS_OACP_PROC_WRITE);

	/* Offset */
	net_buf_simple_add_le32(&otc_tx_buf, offset);

	/* Len */
	net_buf_simple_add_le32(&otc_tx_buf, len);

	/* Mode, truncate or not */
	net_buf_simple_add_u8(&otc_tx_buf, mode);

	inst->otc_inst->write_params.offset = 0;
	inst->otc_inst->write_params.data = otc_tx_buf.data;
	inst->otc_inst->write_params.length = otc_tx_buf.len;
	inst->otc_inst->write_params.handle = inst->otc_inst->oacp_handle;
	inst->otc_inst->write_params.func = write_oacp_cp_write_req_cb;
	inst->sent_size = len;
	err = bt_gatt_write(conn, &inst->otc_inst->write_params);

	if (!err) {
		inst->busy = true;
		cur_inst = inst;
	}

	inst->rcvd_size = 0;

	return err;
}
int bt_ots_client_read_object_data(struct bt_ots_client *otc_inst,
				   struct bt_conn *conn)
{
	struct bt_otc_internal_instance_t *inst;

	if (!conn) {
		LOG_WRN("Invalid Connection");
		return -ENOTCONN;
	} else if (!otc_inst) {
		LOG_ERR("Invalid OTC instance");
		return -EINVAL;
	}

	inst = lookup_inst_by_handle(otc_inst->start_handle);

	if (!inst) {
		LOG_ERR("Invalid OTC instance");
		return -EINVAL;
	}

	if (otc_inst->cur_object.size.cur == 0) {
		LOG_WRN("Unknown object size");
		return -EINVAL;
	}

	return oacp_read(conn, inst);
}

int bt_ots_client_write_object_data(struct bt_ots_client *otc_inst,
				    struct bt_conn *conn, const void *buf, size_t len,
				    off_t offset, enum bt_ots_oacp_write_op_mode mode)
{
	struct bt_otc_internal_instance_t *inst;

	CHECKIF(!conn) {
		LOG_WRN("Invalid Connection");
		return -ENOTCONN;
	}

	CHECKIF(!otc_inst) {
		LOG_ERR("Invalid OTC instance");
		return -EINVAL;
	}

	CHECKIF((mode != BT_OTS_OACP_WRITE_OP_MODE_NONE) &&
		(mode != BT_OTS_OACP_WRITE_OP_MODE_TRUNCATE)) {
		LOG_ERR("Invalid write object mode parameter %d", mode);
		return -EINVAL;
	}

	/* OTS_v10.pdf Table 3.9: Object Action Control Point Procedure Requirements
	 *	Offset and Length field are UINT32 Length
	 */
	CHECKIF(len > UINT32_MAX) {
		LOG_ERR("length exceeds UINT32");
		return -EINVAL;
	}

	CHECKIF(len == 0) {
		LOG_ERR("length equals zero");
		return -EINVAL;
	}

	CHECKIF((offset > UINT32_MAX) || (offset < 0)) {
		LOG_ERR("offset exceeds UINT32");
		return -EINVAL;
	}

	CHECKIF(offset > otc_inst->cur_object.size.cur) {
		LOG_ERR("offset %ld exceeds cur size %zu", offset, otc_inst->cur_object.size.cur);
		return -EINVAL;
	}

	CHECKIF((offset < otc_inst->cur_object.size.cur) &&
		!BT_OTS_OBJ_GET_PROP_PATCH(otc_inst->cur_object.props)) {
		LOG_ERR("Patch is not supported");
		return -EACCES;
	}

	CHECKIF(((len + offset) > otc_inst->cur_object.size.alloc) &&
		!BT_OTS_OBJ_GET_PROP_APPEND(otc_inst->cur_object.props)) {
		LOG_ERR("APPEND is not supported. Invalid new end of object %lu alloc %zu."
		, (len + offset), otc_inst->cur_object.size.alloc);
		return -EINVAL;
	}

	inst = lookup_inst_by_handle(otc_inst->start_handle);

	if (!inst) {
		LOG_ERR("Invalid OTC instance");
		return -EINVAL;
	}

	return oacp_write(conn, inst, buf, (uint32_t)len, (uint32_t)offset, mode);
}

static void read_next_metadata(struct bt_conn *conn,
			       struct bt_otc_internal_instance_t *inst)
{
	uint8_t metadata_remaining =
		inst->metadata_to_read ^ inst->metadata_read_attempted;
	int err = 0;

	LOG_DBG("Attempting to read metadata 0x%02X", metadata_remaining);

	if (BT_OTS_GET_METADATA_REQ_NAME(metadata_remaining)) {
		BT_OTS_SET_METADATA_REQ_NAME(inst->metadata_read_attempted);
		err = read_attr(conn, inst, inst->otc_inst->obj_name_handle,
				read_obj_name_cb);
	} else if (BT_OTS_GET_METADATA_REQ_TYPE(metadata_remaining)) {
		BT_OTS_SET_METADATA_REQ_TYPE(inst->metadata_read_attempted);
		err = read_attr(conn, inst, inst->otc_inst->obj_type_handle,
				read_obj_type_cb);
	} else if (BT_OTS_GET_METADATA_REQ_SIZE(metadata_remaining)) {
		BT_OTS_SET_METADATA_REQ_SIZE(inst->metadata_read_attempted);
		err = read_attr(conn, inst, inst->otc_inst->obj_size_handle,
				read_object_size_cb);
	} else if (BT_OTS_GET_METADATA_REQ_CREATED(metadata_remaining)) {
		BT_OTS_SET_METADATA_REQ_CREATED(inst->metadata_read_attempted);
		err = read_attr(conn, inst, inst->otc_inst->obj_created_handle,
				read_obj_created_cb);
	} else if (BT_OTS_GET_METADATA_REQ_MODIFIED(metadata_remaining)) {
		BT_OTS_SET_METADATA_REQ_MODIFIED(inst->metadata_read_attempted);
		err = read_attr(conn, inst, inst->otc_inst->obj_modified_handle,
				read_obj_modified_cb);
	} else if (BT_OTS_GET_METADATA_REQ_ID(metadata_remaining)) {
		BT_OTS_SET_METADATA_REQ_ID(inst->metadata_read_attempted);
		err = read_attr(conn, inst, inst->otc_inst->obj_id_handle,
				read_obj_id_cb);
	} else if (BT_OTS_GET_METADATA_REQ_PROPS(metadata_remaining)) {
		BT_OTS_SET_METADATA_REQ_PROPS(inst->metadata_read_attempted);
		err = read_attr(conn, inst,
				inst->otc_inst->obj_properties_handle,
				read_obj_properties_cb);
	} else {
		inst->busy = false;
		if (inst->otc_inst->cb->obj_metadata_read) {
			inst->otc_inst->cb->obj_metadata_read(
				inst->otc_inst, conn, inst->metadata_err,
				inst->metadata_read);
		}
		return;
	}

	if (err) {
		LOG_DBG("Metadata read failed (%d), trying next", err);
		read_next_metadata(conn, inst);
	}
}

int bt_ots_client_read_object_metadata(struct bt_ots_client *otc_inst,
				       struct bt_conn *conn,
				       uint8_t metadata)
{
	struct bt_otc_internal_instance_t *inst;

	if (!conn) {
		LOG_WRN("Invalid Connection");
		return -ENOTCONN;
	} else if (!otc_inst) {
		LOG_ERR("Invalid OTC instance");
		return -EINVAL;
	} else if (!metadata) {
		LOG_WRN("No metadata to read");
		return -ENOEXEC;
	}

	inst = lookup_inst_by_handle(otc_inst->start_handle);

	if (!inst) {
		LOG_ERR("Invalid OTC instance");
		return -EINVAL;
	} else if (inst->busy) {
		return -EBUSY;
	}

	inst->metadata_read = 0;
	inst->metadata_to_read = metadata & BT_OTS_METADATA_REQ_ALL;
	inst->metadata_read_attempted = 0;

	inst->busy = true;
	read_next_metadata(conn, inst);

	return 0;
}

static int decode_record(struct net_buf_simple *buf,
			 struct dirlisting_record_t *rec)
{
	uint16_t start_len = buf->len;

	rec->len = net_buf_simple_pull_le16(buf);

	if (rec->len > buf->len) {
		LOG_WRN("incorrect DirListing record length %u, "
			"longer than remaining size %u",
			rec->len, buf->len);
		return -EINVAL;
	}

	if ((start_len - buf->len) + BT_OTS_OBJ_ID_SIZE > rec->len) {
		LOG_WRN("incorrect DirListing record, reclen %u too short, "
			"includes only record length",
			rec->len);
		return -EINVAL;
	}

	rec->metadata.id = net_buf_simple_pull_le48(buf);

	if (IS_ENABLED(CONFIG_BT_OTS_CLIENT_LOG_LEVEL_DBG)) {
		char t[BT_OTS_OBJ_ID_STR_LEN];

		(void)bt_ots_obj_id_to_str(rec->metadata.id, t, sizeof(t));
		LOG_DBG("Object ID 0x%s", t);
	}

	if ((start_len - buf->len) + sizeof(uint8_t) > rec->len) {
		LOG_WRN("incorrect DirListing record, reclen %u too short, "
			"includes only record length + ObjId",
			rec->len);
		return -EINVAL;
	}

	rec->name_len = net_buf_simple_pull_u8(buf);

	if (rec->name_len > 0) {
		uint8_t *name;

		if ((start_len - buf->len) + rec->name_len > rec->len) {
			LOG_WRN("incorrect DirListing record, remaining length "
				"%u shorter than name length %u",
				rec->len - (start_len - buf->len),
				rec->name_len);
			return -EINVAL;
		}

		if (rec->name_len >= sizeof(rec->metadata.name_c)) {
			LOG_WRN("Name length %u too long, invalid record", rec->name_len);
			return -EINVAL;
		}

		name = net_buf_simple_pull_mem(buf, rec->name_len);
		memcpy(rec->metadata.name_c, name, rec->name_len);
	}

	rec->metadata.name_c[rec->name_len] = '\0';
	rec->flags = 0;

	if ((start_len - buf->len) + sizeof(uint8_t) > rec->len) {
		LOG_WRN("incorrect DirListing record, reclen %u too short, "
			"does not include flags", rec->len);
		return -EINVAL;
	}

	rec->flags = net_buf_simple_pull_u8(buf);
	LOG_DBG("flags 0x%x", rec->flags);

	if (BT_OTS_DIR_LIST_GET_FLAG_TYPE_128(rec->flags)) {
		uint8_t *uuid;

		if ((start_len - buf->len) + BT_UUID_SIZE_128 > rec->len) {
			LOG_WRN("incorrect DirListing record, reclen %u "
				"flags indicates uuid128, too short",
				rec->len);
			LOG_INF("flags 0x%x", rec->flags);
			return -EINVAL;
		}

		uuid = net_buf_simple_pull_mem(buf, BT_UUID_SIZE_128);
		bt_uuid_create(&rec->metadata.type.uuid,
			       uuid, BT_UUID_SIZE_128);
	} else {
		if ((start_len - buf->len) + BT_UUID_SIZE_16 > rec->len) {
			LOG_WRN("incorrect DirListing record, reclen %u "
				"flags indicates uuid16, too short",
				rec->len);
			LOG_INF("flags 0x%x", rec->flags);
			return -EINVAL;
		}

		rec->metadata.type.uuid_16.val =
			net_buf_simple_pull_le16(buf);
	}

	if (BT_OTS_DIR_LIST_GET_FLAG_CUR_SIZE(rec->flags)) {
		if ((start_len - buf->len) + sizeof(uint32_t) > rec->len) {
			LOG_WRN("incorrect DirListing record, reclen %u "
				"flags indicates cur_size, too short",
				rec->len);
			LOG_INF("flags 0x%x", rec->flags);
			return -EINVAL;
		}

		rec->metadata.size.cur = net_buf_simple_pull_le32(buf);
	}

	if (BT_OTS_DIR_LIST_GET_FLAG_ALLOC_SIZE(rec->flags)) {
		if ((start_len - buf->len) + sizeof(uint32_t) > rec->len) {
			LOG_WRN("incorrect DirListing record, reclen %u "
				"flags indicates allocated size, too short",
				rec->len);
			LOG_INF("flags 0x%x", rec->flags);
			return -EINVAL;
		}

		rec->metadata.size.alloc = net_buf_simple_pull_le32(buf);
	}

	if (BT_OTS_DIR_LIST_GET_FLAG_FIRST_CREATED(rec->flags)) {
		if ((start_len - buf->len) + BT_OTS_DATE_TIME_FIELD_SIZE > rec->len) {
			LOG_WRN("incorrect DirListing record, reclen %u "
				"too short flags indicates first_created",
				rec->len);
			LOG_INF("flags 0x%x", rec->flags);
			return -EINVAL;
		}

		date_time_decode(buf, &rec->metadata.first_created);
	}

	if (BT_OTS_DIR_LIST_GET_FLAG_LAST_MODIFIED(rec->flags)) {
		if ((start_len - buf->len) + BT_OTS_DATE_TIME_FIELD_SIZE > rec->len) {
			LOG_WRN("incorrect DirListing record, reclen %u "
				"flags indicates las_mod, too short",
				rec->len);
			LOG_INF("flags 0x%x", rec->flags);
			return -EINVAL;
		}

		date_time_decode(buf, &rec->metadata.modified);
	}

	if (BT_OTS_DIR_LIST_GET_FLAG_PROPERTIES(rec->flags)) {
		if ((start_len - buf->len) + sizeof(uint32_t) > rec->len) {
			LOG_WRN("incorrect DirListing record, reclen %u "
				"flags indicates properties, too short",
				rec->len);
			LOG_INF("flags 0x%x", rec->flags);
			return -EINVAL;
		}

		rec->metadata.props = net_buf_simple_pull_le32(buf);
	}

	return rec->len;
}

int bt_ots_client_decode_dirlisting(uint8_t *data, uint16_t length,
				    bt_ots_client_dirlisting_cb cb)
{
	struct net_buf_simple net_buf;
	uint8_t count = 0;
	struct dirlisting_record_t record;

	net_buf_simple_init_with_data(&net_buf, (void *)data, length);

	if (!data || length == 0) {
		return -EINVAL;
	}

	while (net_buf.len) {
		int ret;

		count++;

		if (net_buf.len < sizeof(uint16_t)) {
			LOG_WRN("incorrect DirListing record, len %u too short", net_buf.len);
			return -EINVAL;
		}

		LOG_DBG("Decoding record %u", count);
		ret = decode_record(&net_buf, &record);

		if (ret < 0) {
			LOG_WRN("DirListing, record %u invalid", count);
			return ret;
		}

		ret = cb(&record.metadata);

		if (ret == BT_OTS_STOP) {
			break;
		}
	}

	return count;
}

void bt_ots_metadata_display(struct bt_ots_obj_metadata *metadata,
			     uint16_t count)
{
	LOG_INF("--- Displaying %u metadata records ---", count);

	for (int i = 0; i < count; i++) {
		char t[BT_OTS_OBJ_ID_STR_LEN];

		(void)bt_ots_obj_id_to_str(metadata->id, t, sizeof(t));
		LOG_INF("Object ID: 0x%s", t);
		LOG_INF("Object name: %s", metadata->name_c);
		LOG_INF("Object Current Size: %u", metadata->size.cur);
		LOG_INF("Object Allocate Size: %u", metadata->size.alloc);

		if (!bt_uuid_cmp(&metadata->type.uuid,
				 BT_UUID_OTS_TYPE_MPL_ICON)) {
			LOG_INF("Type: Icon Obj Type");
		} else if (!bt_uuid_cmp(&metadata->type.uuid,
					BT_UUID_OTS_TYPE_TRACK_SEGMENT)) {
			LOG_INF("Type: Track Segment Obj Type");
		} else if (!bt_uuid_cmp(&metadata->type.uuid,
					BT_UUID_OTS_TYPE_TRACK)) {
			LOG_INF("Type: Track Obj Type");
		} else if (!bt_uuid_cmp(&metadata->type.uuid,
					BT_UUID_OTS_TYPE_GROUP)) {
			LOG_INF("Type: Group Obj Type");
		} else if (!bt_uuid_cmp(&metadata->type.uuid,
					BT_UUID_OTS_DIRECTORY_LISTING)) {
			LOG_INF("Type: Directory Listing");
		}


		LOG_INF("Properties:0x%x", metadata->props);

		if (BT_OTS_OBJ_GET_PROP_APPEND(metadata->props)) {
			LOG_INF(" - append permitted");
		}

		if (BT_OTS_OBJ_GET_PROP_DELETE(metadata->props)) {
			LOG_INF(" - delete permitted");
		}

		if (BT_OTS_OBJ_GET_PROP_EXECUTE(metadata->props)) {
			LOG_INF(" - execute permitted");
		}

		if (BT_OTS_OBJ_GET_PROP_MARKED(metadata->props)) {
			LOG_INF(" - marked");
		}

		if (BT_OTS_OBJ_GET_PROP_PATCH(metadata->props)) {
			LOG_INF(" - patch permitted");
		}

		if (BT_OTS_OBJ_GET_PROP_READ(metadata->props)) {
			LOG_INF(" - read permitted");
		}

		if (BT_OTS_OBJ_GET_PROP_TRUNCATE(metadata->props)) {
			LOG_INF(" - truncate permitted");
		}

		if (BT_OTS_OBJ_GET_PROP_WRITE(metadata->props)) {
			LOG_INF(" - write permitted");
		}
	}
}
