/*
 * Copyright (c) 2020 Nordic Semiconductor ASA
 *
 * SPDX-License-Identifier: Apache-2.0
 */

#include <zephyr/types.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/zephyr.h>

#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/services/ots.h>
#include "ots_internal.h"
#include "ots_dir_list_internal.h"
#include "ots_obj_manager_internal.h"

#include <zephyr/logging/log.h>

LOG_MODULE_DECLARE(bt_ots, CONFIG_BT_OTS_LOG_LEVEL);

#define OACP_PROC_TYPE_SIZE	1
#define OACP_RES_MAX_SIZE	3

#if defined(CONFIG_BT_OTS_OACP_WRITE_SUPPORT)
static ssize_t oacp_write_proc_cb(struct bt_gatt_ots_l2cap *l2cap_ctx,
			struct bt_conn *conn, struct net_buf *buf);

static void oacp_l2cap_closed(struct bt_gatt_ots_l2cap *l2cap_ctx,
			struct bt_conn *conn)
{
	struct bt_ots *ots;

	ots = CONTAINER_OF(l2cap_ctx, struct bt_ots, l2cap);

	if (!ots->cur_obj) {
		return;
	}

	ots->cur_obj->state.type = BT_GATT_OTS_OBJECT_IDLE_STATE;
	l2cap_ctx->rx_done = NULL;
	l2cap_ctx->tx_done = NULL;
}
#endif

#if defined(CONFIG_BT_OTS_OACP_CREATE_SUPPORT)
static enum bt_gatt_ots_oacp_res_code oacp_create_proc_validate(
	struct bt_conn *conn,
	struct bt_ots *ots,
	struct bt_gatt_ots_oacp_proc *proc)
{
	char str[BT_UUID_STR_LEN];
	int err;
	struct bt_gatt_ots_object *obj;
	const struct bt_ots_obj_add_param param = {
		.size = proc->create_params.size,
		.type = proc->create_params.type,
	};

	bt_uuid_to_str(&param.type.uuid, str, BT_UUID_STR_LEN);
	LOG_DBG("Validating Create procedure with size: 0x%08X and "
		"type: %s", param.size, str);

	if (!BT_OTS_OACP_GET_FEAT_CREATE(ots->features.oacp)) {
		LOG_DBG("Create Procedure is not supported.");
		return BT_GATT_OTS_OACP_RES_OPCODE_NOT_SUP;
	}

	err = bt_ots_obj_add_internal(ots, conn, &param, &obj);
	if (err) {
		goto exit;
	}

	/* Verify Initialization Metadata */
	if (strlen(obj->metadata.name) > 0) {
		LOG_ERR("Object name shall be a zero length string after object creation.");
		(void)bt_ots_obj_delete(ots, obj->id);
		err = -ECANCELED;
		goto exit;
	}

	if (obj->metadata.size.cur > 0) {
		LOG_ERR("Object current size must be 0.");
		(void)bt_ots_obj_delete(ots, obj->id);
		err = -ECANCELED;
		goto exit;
	}

	if (!BT_OTS_OBJ_GET_PROP_WRITE(obj->metadata.props)) {
		LOG_ERR("Created object must have write property.");
		(void)bt_ots_obj_delete(ots, obj->id);
		err = -ECANCELED;
		goto exit;
	}

	ots->cur_obj = obj;
	ots->cur_obj->state.type = BT_GATT_OTS_OBJECT_IDLE_STATE;

	LOG_DBG("Create procedure is complete");

exit:
	switch (err) {
	case 0:
		return BT_GATT_OTS_OACP_RES_SUCCESS;
	case -ENOTSUP:
		return BT_GATT_OTS_OACP_RES_UNSUP_TYPE;
	case -ENOMEM:
		return BT_GATT_OTS_OACP_RES_INSUFF_RES;
	case -EINVAL:
		return BT_GATT_OTS_OACP_RES_INV_PARAM;
	case -ECANCELED:
	default:
		return BT_GATT_OTS_OACP_RES_OPER_FAILED;
	}
}
#endif

#if defined(CONFIG_BT_OTS_OACP_DELETE_SUPPORT)
static enum bt_gatt_ots_oacp_res_code oacp_delete_proc_validate(
	struct bt_conn *conn,
	struct bt_ots *ots,
	struct bt_gatt_ots_oacp_proc *proc)
{
	int err;

	if (!BT_OTS_OACP_GET_FEAT_DELETE(ots->features.oacp)) {
		LOG_DBG("Delete Procedure is not supported.");
		return BT_GATT_OTS_OACP_RES_OPCODE_NOT_SUP;
	}

	if (!ots->cur_obj) {
		LOG_DBG("No object is selected.");
		return BT_GATT_OTS_OACP_RES_INV_OBJ;
	}

	if (!BT_OTS_OBJ_GET_PROP_DELETE(ots->cur_obj->metadata.props)) {
		LOG_DBG("Object properties do not permit deletion.");
		return BT_GATT_OTS_OACP_RES_NOT_PERMITTED;
	}

	err = bt_ots_obj_delete(ots, ots->cur_obj->id);
	if (err) {
		LOG_ERR("Deleting object during Delete procedure failed: %d", err);
		goto exit;
	}

	LOG_DBG("Delete procedure is complete");

exit:
	switch (err) {
	case 0:
		return BT_GATT_OTS_OACP_RES_SUCCESS;
	case -EBUSY:
		return BT_GATT_OTS_OACP_RES_OBJ_LOCKED;
	default:
		return BT_GATT_OTS_OACP_RES_OPER_FAILED;
	}
}
#endif

static enum bt_gatt_ots_oacp_res_code oacp_read_proc_validate(
	struct bt_conn *conn,
	struct bt_ots *ots,
	struct bt_gatt_ots_oacp_proc *proc)
{
	struct bt_gatt_ots_oacp_read_params *params = &proc->read_params;

	LOG_DBG("Validating Read procedure with offset: 0x%08X and "
		"length: 0x%08X", params->offset, params->len);

	if (!ots->cur_obj) {
		return BT_GATT_OTS_OACP_RES_INV_OBJ;
	}

	if (!BT_OTS_OBJ_GET_PROP_READ(ots->cur_obj->metadata.props)) {
		return BT_GATT_OTS_OACP_RES_NOT_PERMITTED;
	}

	if (!bt_gatt_ots_l2cap_is_open(&ots->l2cap, conn)) {
		return BT_GATT_OTS_OACP_RES_CHAN_UNAVAIL;
	}

	if ((params->offset + (uint64_t) params->len) >
		ots->cur_obj->metadata.size.cur) {
		return BT_GATT_OTS_OACP_RES_INV_PARAM;
	}

	if (ots->cur_obj->state.type != BT_GATT_OTS_OBJECT_IDLE_STATE) {
		return BT_GATT_OTS_OACP_RES_OBJ_LOCKED;
	}

	ots->cur_obj->state.type = BT_GATT_OTS_OBJECT_READ_OP_STATE;
	ots->cur_obj->state.read_op.sent_len = 0;
	memcpy(&ots->cur_obj->state.read_op.oacp_params, &proc->read_params,
		sizeof(ots->cur_obj->state.read_op.oacp_params));

	LOG_DBG("Read procedure is accepted");

	return BT_GATT_OTS_OACP_RES_SUCCESS;
}

#if defined(CONFIG_BT_OTS_OACP_WRITE_SUPPORT)
static enum bt_gatt_ots_oacp_res_code oacp_write_proc_validate(
	struct bt_conn *conn,
	struct bt_ots *ots,
	struct bt_gatt_ots_oacp_proc *proc)
{
	struct bt_gatt_ots_oacp_write_params *params = &proc->write_params;

	LOG_DBG("Validating Write procedure with offset: 0x%08X and "
		"length: 0x%08X", params->offset, params->len);

	if (!ots->cur_obj) {
		return BT_GATT_OTS_OACP_RES_INV_OBJ;
	}

	if (!BT_OTS_OBJ_GET_PROP_WRITE(ots->cur_obj->metadata.props)) {
		return BT_GATT_OTS_OACP_RES_NOT_PERMITTED;
	}

	/* patching is attempted */
	if (params->offset < ots->cur_obj->metadata.size.cur) {
		if (!BT_OTS_OACP_GET_FEAT_PATCH(ots->features.oacp)) {
			return BT_GATT_OTS_OACP_RES_NOT_PERMITTED;
		}
		if (!BT_OTS_OBJ_GET_PROP_PATCH(ots->cur_obj->metadata.props)) {
			return BT_GATT_OTS_OACP_RES_NOT_PERMITTED;
		}
	}

	/* truncation is not supported */
	if (BT_GATT_OTS_OACP_PROC_WRITE_MODE_GET_TRUNC(params->mode)) {
		return BT_GATT_OTS_OACP_RES_NOT_PERMITTED;
	}

	if (!bt_gatt_ots_l2cap_is_open(&ots->l2cap, conn)) {
		return BT_GATT_OTS_OACP_RES_CHAN_UNAVAIL;
	}

	if (BT_GATT_OTS_OACP_PROC_WRITE_MODE_GET_RFU(params->mode)) {
		return BT_GATT_OTS_OACP_RES_INV_PARAM;
	}

	if (params->offset > ots->cur_obj->metadata.size.cur) {
		return BT_GATT_OTS_OACP_RES_INV_PARAM;
	}

	/* append is not supported */
	if ((params->offset + (uint64_t) params->len) > ots->cur_obj->metadata.size.alloc) {
		return BT_GATT_OTS_OACP_RES_INV_PARAM;
	}

	if (ots->cur_obj->state.type != BT_GATT_OTS_OBJECT_IDLE_STATE) {
		return BT_GATT_OTS_OACP_RES_OBJ_LOCKED;
	}

	ots->l2cap.rx_done = oacp_write_proc_cb;
	ots->l2cap.closed = oacp_l2cap_closed;
	ots->cur_obj->state.type = BT_GATT_OTS_OBJECT_WRITE_OP_STATE;
	ots->cur_obj->state.write_op.recv_len = 0;
	memcpy(&ots->cur_obj->state.write_op.oacp_params, params,
		sizeof(ots->cur_obj->state.write_op.oacp_params));

	LOG_DBG("Write procedure is accepted");

	return BT_GATT_OTS_OACP_RES_SUCCESS;
}
#endif

static enum bt_gatt_ots_oacp_res_code oacp_proc_validate(
	struct bt_conn *conn,
	struct bt_ots *ots,
	struct bt_gatt_ots_oacp_proc *proc)
{
	switch (proc->type) {
	case BT_GATT_OTS_OACP_PROC_READ:
		return oacp_read_proc_validate(conn, ots, proc);
#if defined(CONFIG_BT_OTS_OACP_WRITE_SUPPORT)
	case BT_GATT_OTS_OACP_PROC_WRITE:
		return oacp_write_proc_validate(conn, ots, proc);
#endif
#if defined(CONFIG_BT_OTS_OACP_CREATE_SUPPORT)
	case BT_GATT_OTS_OACP_PROC_CREATE:
		return oacp_create_proc_validate(conn, ots, proc);
#endif
#if defined(CONFIG_BT_OTS_OACP_DELETE_SUPPORT)
	case BT_GATT_OTS_OACP_PROC_DELETE:
		return oacp_delete_proc_validate(conn, ots, proc);
#endif
	case BT_GATT_OTS_OACP_PROC_CHECKSUM_CALC:
	case BT_GATT_OTS_OACP_PROC_EXECUTE:
	case BT_GATT_OTS_OACP_PROC_ABORT:
	default:
		return BT_GATT_OTS_OACP_RES_OPCODE_NOT_SUP;
	}
};

static int oacp_command_decode(const uint8_t *buf, uint16_t len,
			       struct bt_gatt_ots_oacp_proc *proc)
{
	struct net_buf_simple net_buf;

	if (len < OACP_PROC_TYPE_SIZE) {
		return -ENODATA;
	}

	net_buf_simple_init_with_data(&net_buf, (void *) buf, len);

	proc->type = net_buf_simple_pull_u8(&net_buf);
	switch (proc->type) {
#if defined(CONFIG_BT_OTS_OACP_CREATE_SUPPORT)
	case BT_GATT_OTS_OACP_PROC_CREATE:
		if (net_buf.len < BT_GATT_OTS_OACP_CREATE_GENERIC_PARAMS_SIZE) {
			return -EBADMSG;
		}
		proc->create_params.size = net_buf_simple_pull_le32(&net_buf);
		if (!bt_uuid_create(&proc->create_params.type.uuid, net_buf.data,
				    net_buf.len)) {
			return -EBADMSG;
		}
		net_buf_simple_pull_mem(&net_buf, net_buf.len);

		/* Only 16-bit and 128-bit UUIDs are supported */
		switch (proc->create_params.type.uuid.type) {
		case BT_UUID_TYPE_16:
		case BT_UUID_TYPE_128:
			return 0;
		default:
			break;
		}

		return -EBADMSG;
#endif
#if defined(CONFIG_BT_OTS_OACP_DELETE_SUPPORT)
	case BT_GATT_OTS_OACP_PROC_DELETE:
		if (net_buf.len != 0) {
			return -EBADMSG;
		}

		return 0;
#endif
	case BT_GATT_OTS_OACP_PROC_CHECKSUM_CALC:
		if (net_buf.len != BT_GATT_OTS_OACP_CS_CALC_PARAMS_SIZE) {
			return -EBADMSG;
		}
		proc->cs_calc_params.offset =
			net_buf_simple_pull_le32(&net_buf);
		proc->cs_calc_params.len =
			net_buf_simple_pull_le32(&net_buf);

		return 0;
	case BT_GATT_OTS_OACP_PROC_EXECUTE:
		if (net_buf.len != 0) {
			return -EBADMSG;
		}

		return 0;
	case BT_GATT_OTS_OACP_PROC_READ:
		if (net_buf.len != BT_GATT_OTS_OACP_READ_PARAMS_SIZE) {
			return -EBADMSG;
		}
		proc->read_params.offset =
			net_buf_simple_pull_le32(&net_buf);
		proc->read_params.len =
			net_buf_simple_pull_le32(&net_buf);

		return 0;
#if defined(CONFIG_BT_OTS_OACP_WRITE_SUPPORT)
	case BT_GATT_OTS_OACP_PROC_WRITE:
		if (net_buf.len != BT_GATT_OTS_OACP_WRITE_PARAMS_SIZE) {
			return -EBADMSG;
		}
		proc->write_params.offset =
			net_buf_simple_pull_le32(&net_buf);
		proc->write_params.len =
			net_buf_simple_pull_le32(&net_buf);
		proc->write_params.mode =
			net_buf_simple_pull_u8(&net_buf);

		return 0;
#endif
	case BT_GATT_OTS_OACP_PROC_ABORT:
	default:
		break;
	}

	return -ENOTSUP;
}

static void oacp_read_proc_cb(struct bt_gatt_ots_l2cap *l2cap_ctx,
			      struct bt_conn *conn)
{
	int err;
	void *obj_chunk;
	off_t offset;
	ssize_t len;
	struct bt_ots *ots;
	struct bt_gatt_ots_object_read_op *read_op;

	ots     = CONTAINER_OF(l2cap_ctx, struct bt_ots, l2cap);
	read_op = &ots->cur_obj->state.read_op;
	offset  = read_op->oacp_params.offset + read_op->sent_len;

	if (read_op->sent_len >= read_op->oacp_params.len) {
		LOG_DBG("OACP Read Op over L2CAP is completed");

		if (read_op->sent_len > read_op->oacp_params.len) {
			LOG_WRN("More bytes sent that the client requested");
		}

		ots->cur_obj->state.type = BT_GATT_OTS_OBJECT_IDLE_STATE;

		if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ) &&
		    ots->cur_obj->id == OTS_OBJ_ID_DIR_LIST) {
			return;
		}

		ots->cb->obj_read(ots, conn, ots->cur_obj->id, NULL, 0,
				  offset);
		return;
	}

	len = read_op->oacp_params.len - read_op->sent_len;
	if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ) &&
	    ots->cur_obj->id == OTS_OBJ_ID_DIR_LIST) {
		len = bt_ots_dir_list_content_get(ots->dir_list, ots->obj_manager,
						  &obj_chunk, len, offset);
	} else {
		len = ots->cb->obj_read(ots, conn, ots->cur_obj->id, &obj_chunk,
					len, offset);
	}

	if (len < 0) {
		LOG_ERR("OCAP Read Op failed with error: %zd", len);

		bt_gatt_ots_l2cap_disconnect(&ots->l2cap);
		ots->cur_obj->state.type = BT_GATT_OTS_OBJECT_IDLE_STATE;

		return;
	}

	ots->l2cap.tx_done = oacp_read_proc_cb;
	err = bt_gatt_ots_l2cap_send(&ots->l2cap, obj_chunk, len);
	if (err) {
		LOG_ERR("L2CAP CoC error: %d while trying to execute OACP "
			"Read procedure", err);
		ots->cur_obj->state.type = BT_GATT_OTS_OBJECT_IDLE_STATE;
	} else {
		read_op->sent_len += len;
	}
}

static void oacp_read_proc_execute(struct bt_ots *ots,
				   struct bt_conn *conn)
{
	struct bt_gatt_ots_oacp_read_params *params =
		&ots->cur_obj->state.read_op.oacp_params;

	if (!ots->cur_obj) {
		LOG_ERR("Invalid Current Object on OACP Read procedure");
		return;
	}

	LOG_DBG("Executing Read procedure with offset: 0x%08X and "
		"length: 0x%08X", params->offset, params->len);

	if (IS_ENABLED(CONFIG_BT_OTS_DIR_LIST_OBJ) &&
	    ots->cur_obj->id == OTS_OBJ_ID_DIR_LIST) {
		oacp_read_proc_cb(&ots->l2cap, conn);
	} else if (ots->cb->obj_read) {
		oacp_read_proc_cb(&ots->l2cap, conn);
	} else {
		ots->cur_obj->state.type = BT_GATT_OTS_OBJECT_IDLE_STATE;
		LOG_ERR("OTS Read operation failed: "
			"there is no OTS Read callback");
	}
}

#if defined(CONFIG_BT_OTS_OACP_WRITE_SUPPORT)
static ssize_t oacp_write_proc_cb(struct bt_gatt_ots_l2cap *l2cap_ctx,
			struct bt_conn *conn, struct net_buf *buf)
{
	struct bt_gatt_ots_object_write_op *write_op;
	struct bt_ots *ots;
	off_t offset;
	size_t rem;
	size_t len;
	ssize_t rc;

	ots = CONTAINER_OF(l2cap_ctx, struct bt_ots, l2cap);

	if (!ots->cur_obj) {
		LOG_ERR("Invalid Current Object on OACP Write procedure");
		return -ENODEV;
	}

	if (!ots->cb->obj_write) {
		LOG_ERR("OTS Write operation failed: "
			"there is no OTS Write callback");
		ots->cur_obj->state.type = BT_GATT_OTS_OBJECT_IDLE_STATE;
		return -ENODEV;
	}

	write_op = &ots->cur_obj->state.write_op;
	offset = write_op->oacp_params.offset + write_op->recv_len;
	len = buf->len;
	if (write_op->recv_len + len > write_op->oacp_params.len) {
		LOG_WRN("More bytes received than the client indicated");
		len = write_op->oacp_params.len - write_op->recv_len;
	}
	rem = write_op->oacp_params.len - (write_op->recv_len + len);

	rc = ots->cb->obj_write(ots, conn, ots->cur_obj->id, buf->data, len,
				  offset, rem);

	if (rc < 0) {
		len = 0;

		/*
		 * Returning an EINPROGRESS return code results in the write buffer not being
		 * released by the l2cap layer. This is an unsupported use case at the moment.
		 */
		if (rc == -EINPROGRESS) {
			LOG_ERR("Unsupported error code %zd returned by object write callback", rc);
		}

		LOG_ERR("OTS Write operation failed with error: %zd", rc);
		ots->cur_obj->state.type = BT_GATT_OTS_OBJECT_IDLE_STATE;
	} else {
		/* Return -EIO as an error if all of data was not written */
		if (rc != len) {
			len = rc;
			rc = -EIO;
		}
	}

	write_op->recv_len += len;
	if (write_op->recv_len == write_op->oacp_params.len) {
		LOG_DBG("OACP Write Op over L2CAP is completed");
		ots->cur_obj->state.type = BT_GATT_OTS_OBJECT_IDLE_STATE;
	}

	if (offset + len > ots->cur_obj->metadata.size.cur) {
		ots->cur_obj->metadata.size.cur = offset + len;
	}

	return rc;
}
#endif

static void oacp_ind_cb(struct bt_conn *conn,
			struct bt_gatt_indicate_params *params,
			uint8_t err)
{
	struct bt_ots *ots = (struct bt_ots *) params->attr->user_data;

	LOG_DBG("Received OACP Indication ACK with status: 0x%04X", err);

	if (!ots->cur_obj) {
		LOG_DBG("There is no object associated with this ACK");
		return;
	}

	switch (ots->cur_obj->state.type) {
	case BT_GATT_OTS_OBJECT_READ_OP_STATE:
		oacp_read_proc_execute(ots, conn);
		break;
	case BT_GATT_OTS_OBJECT_WRITE_OP_STATE:
		/* procedure execution is driven by L2CAP socket receive */
		break;
	case BT_GATT_OTS_OBJECT_IDLE_STATE:
		/* procedure is not in progress and was already completed */
		break;
	default:
		LOG_ERR("Unsupported OTS state: %d", ots->cur_obj->state.type);
		break;
	}
}

static int oacp_ind_send(const struct bt_gatt_attr *oacp_attr,
			 enum bt_gatt_ots_oacp_proc_type req_op_code,
			 enum bt_gatt_ots_oacp_res_code oacp_status)
{
	uint8_t oacp_res[OACP_RES_MAX_SIZE];
	uint16_t oacp_res_len = 0;
	struct bt_ots *ots = (struct bt_ots *) oacp_attr->user_data;

	/* Encode OACP Response */
	oacp_res[oacp_res_len++] = BT_GATT_OTS_OACP_PROC_RESP;
	oacp_res[oacp_res_len++] = req_op_code;
	oacp_res[oacp_res_len++] = oacp_status;

	/* Prepare indication parameters */
	memset(&ots->oacp_ind.params, 0, sizeof(ots->oacp_ind.params));
	memcpy(&ots->oacp_ind.attr, oacp_attr, sizeof(ots->oacp_ind.attr));
	ots->oacp_ind.params.attr = &ots->oacp_ind.attr;
	ots->oacp_ind.params.func = oacp_ind_cb;
	ots->oacp_ind.params.data = oacp_res;
	ots->oacp_ind.params.len  = oacp_res_len;

	LOG_DBG("Sending OACP indication");

	return bt_gatt_indicate(NULL, &ots->oacp_ind.params);
}

ssize_t bt_gatt_ots_oacp_write(struct bt_conn *conn,
				   const struct bt_gatt_attr *attr,
				   const void *buf, uint16_t len,
				   uint16_t offset, uint8_t flags)
{
	enum bt_gatt_ots_oacp_res_code oacp_status;
	int decode_status;
	struct bt_gatt_ots_oacp_proc oacp_proc;
	struct bt_ots *ots = (struct bt_ots *) attr->user_data;

	LOG_DBG("Object Action Control Point GATT Write Operation");

	if (!ots->oacp_ind.is_enabled) {
		LOG_WRN("OACP indications not enabled");
		return BT_GATT_ERR(BT_ATT_ERR_CCC_IMPROPER_CONF);
	}

	if (offset != 0) {
		LOG_ERR("Invalid offset of OACP Write Request");
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
	}

	decode_status = oacp_command_decode(buf, len, &oacp_proc);
	switch (decode_status) {
	case 0:
		oacp_status = oacp_proc_validate(conn, ots, &oacp_proc);
		if (oacp_status != BT_GATT_OTS_OACP_RES_SUCCESS) {
			LOG_WRN("OACP Write error status: 0x%02X", oacp_status);
		}
		break;
	case -ENOTSUP:
		oacp_status = BT_GATT_OTS_OACP_RES_OPCODE_NOT_SUP;
		LOG_WRN("OACP unsupported procedure type: 0x%02X", oacp_proc.type);
		break;
	case -EBADMSG:
		LOG_ERR("Invalid length of OACP Write Request for 0x%02X "
			"Op Code", oacp_proc.type);
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	case -ENODATA:
		LOG_ERR("Invalid length of OACP Write Request");
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	default:
		LOG_ERR("Invalid return code from oacp_command_decode: %d", decode_status);
		return BT_GATT_ERR(BT_ATT_ERR_UNLIKELY);
	}

	oacp_ind_send(attr, oacp_proc.type, oacp_status);
	return len;
}

void bt_gatt_ots_oacp_cfg_changed(const struct bt_gatt_attr *attr,
				      uint16_t value)
{
	struct bt_gatt_ots_indicate *oacp_ind =
	    CONTAINER_OF((struct _bt_gatt_ccc *) attr->user_data,
			 struct bt_gatt_ots_indicate, ccc);

	LOG_DBG("Object Action Control Point CCCD value: 0x%04X", value);

	oacp_ind->is_enabled = false;
	if (value == BT_GATT_CCC_INDICATE) {
		oacp_ind->is_enabled = true;
	}
}
