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

#include <zephyr/kernel.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/check.h>

#include <zephyr/device.h>
#include <zephyr/init.h>

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/audio/aics.h>

#include "aics_internal.h"
#include "audio_internal.h"

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_AICS)
#define LOG_MODULE_NAME bt_aics
#include "common/log.h"

#define VALID_AICS_OPCODE(opcode)                                              \
	((opcode) >= BT_AICS_OPCODE_SET_GAIN && (opcode) <= BT_AICS_OPCODE_SET_AUTO)

#define AICS_CP_LEN                 0x02
#define AICS_CP_SET_GAIN_LEN        0x03


static ssize_t write_description(struct bt_conn *conn,
				 const struct bt_gatt_attr *attr,
				 const void *buf, uint16_t len, uint16_t offset,
				 uint8_t flags);

static ssize_t write_aics_control(struct bt_conn *conn,
				  const struct bt_gatt_attr *attr,
				  const void *buf, uint16_t len,
				  uint16_t offset, uint8_t flags);

#if defined(CONFIG_BT_AICS)
static void aics_state_cfg_changed(const struct bt_gatt_attr *attr,
				   uint16_t value);
static ssize_t read_aics_state(struct bt_conn *conn,
			       const struct bt_gatt_attr *attr,
			       void *buf, uint16_t len, uint16_t offset);
static ssize_t read_aics_gain_settings(struct bt_conn *conn,
				       const struct bt_gatt_attr *attr,
				       void *buf, uint16_t len,
				       uint16_t offset);
static ssize_t read_type(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			 void *buf, uint16_t len, uint16_t offset);
static void aics_input_status_cfg_changed(const struct bt_gatt_attr *attr,
					  uint16_t value);
static ssize_t read_input_status(struct bt_conn *conn,
				 const struct bt_gatt_attr *attr,
				 void *buf, uint16_t len, uint16_t offset);
static void aics_description_cfg_changed(const struct bt_gatt_attr *attr,
					 uint16_t value);
static ssize_t read_description(struct bt_conn *conn,
				const struct bt_gatt_attr *attr, void *buf,
				uint16_t len, uint16_t offset);

#define BT_AICS_SERVICE_DEFINITION(_aics) {                                    \
	BT_GATT_SECONDARY_SERVICE(BT_UUID_AICS),                               \
	BT_AUDIO_CHRC(BT_UUID_AICS_STATE,                                      \
		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,                 \
		      BT_GATT_PERM_READ_ENCRYPT,                               \
		      read_aics_state, NULL, &_aics),                          \
	BT_AUDIO_CCC(aics_state_cfg_changed),                                  \
	BT_AUDIO_CHRC(BT_UUID_AICS_GAIN_SETTINGS,                              \
		      BT_GATT_CHRC_READ,                                       \
		      BT_GATT_PERM_READ_ENCRYPT,                               \
		      read_aics_gain_settings, NULL, &_aics),                  \
	BT_AUDIO_CHRC(BT_UUID_AICS_INPUT_TYPE,                                 \
		      BT_GATT_CHRC_READ,                                       \
		      BT_GATT_PERM_READ_ENCRYPT,                               \
		      read_type, NULL, &_aics),                                \
	BT_AUDIO_CHRC(BT_UUID_AICS_INPUT_STATUS,                               \
		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,                 \
		      BT_GATT_PERM_READ_ENCRYPT,                               \
		      read_input_status, NULL, &_aics),                        \
	BT_AUDIO_CCC(aics_input_status_cfg_changed),                           \
	BT_AUDIO_CHRC(BT_UUID_AICS_CONTROL,                                    \
		      BT_GATT_CHRC_WRITE,                                      \
		      BT_GATT_PERM_WRITE_ENCRYPT,                              \
		      NULL, write_aics_control, &_aics),                       \
	BT_AUDIO_CHRC(BT_UUID_AICS_DESCRIPTION,                                \
		      BT_GATT_CHRC_READ | BT_GATT_CHRC_NOTIFY,                 \
		      BT_GATT_PERM_READ_ENCRYPT,                               \
		      read_description, write_description, &_aics),            \
	BT_AUDIO_CCC(aics_description_cfg_changed)                             \
	}


static struct bt_aics aics_insts[CONFIG_BT_AICS_MAX_INSTANCE_COUNT];
static uint32_t instance_cnt;
BT_GATT_SERVICE_INSTANCE_DEFINE(aics_service_list, aics_insts,
				CONFIG_BT_AICS_MAX_INSTANCE_COUNT,
				BT_AICS_SERVICE_DEFINITION);

static void aics_state_cfg_changed(const struct bt_gatt_attr *attr,
				   uint16_t value)
{
	BT_DBG("value 0x%04x", value);
}

static ssize_t read_aics_state(struct bt_conn *conn,
			       const struct bt_gatt_attr *attr, void *buf,
			       uint16_t len, uint16_t offset)
{
	struct bt_aics *inst = BT_AUDIO_CHRC_USER_DATA(attr);

	BT_DBG("gain %d, mute %u, gain_mode %u, counter %u",
	       inst->srv.state.gain, inst->srv.state.mute,
	       inst->srv.state.gain_mode, inst->srv.state.change_counter);

	return bt_gatt_attr_read(conn, attr, buf, len, offset, &inst->srv.state,
				 sizeof(inst->srv.state));
}

static ssize_t read_aics_gain_settings(struct bt_conn *conn,
				       const struct bt_gatt_attr *attr,
				       void *buf, uint16_t len, uint16_t offset)
{
	struct bt_aics *inst = BT_AUDIO_CHRC_USER_DATA(attr);

	BT_DBG("units %u, min %d, max %d",
	       inst->srv.gain_settings.units, inst->srv.gain_settings.minimum,
	       inst->srv.gain_settings.maximum);

	return bt_gatt_attr_read(conn, attr, buf, len, offset,
				 &inst->srv.gain_settings,
				 sizeof(inst->srv.gain_settings));
}

static ssize_t read_type(struct bt_conn *conn, const struct bt_gatt_attr *attr,
			 void *buf, uint16_t len, uint16_t offset)
{
	struct bt_aics *inst = BT_AUDIO_CHRC_USER_DATA(attr);

	BT_DBG("%u", inst->srv.type);

	return bt_gatt_attr_read(conn, attr, buf, len, offset, &inst->srv.type,
				 sizeof(inst->srv.type));
}

static void aics_input_status_cfg_changed(const struct bt_gatt_attr *attr,
					  uint16_t value)
{
	BT_DBG("value 0x%04x", value);
}

static ssize_t read_input_status(struct bt_conn *conn,
				 const struct bt_gatt_attr *attr, void *buf,
				 uint16_t len, uint16_t offset)
{
	struct bt_aics *inst = BT_AUDIO_CHRC_USER_DATA(attr);

	BT_DBG("%u", inst->srv.status);

	return bt_gatt_attr_read(conn, attr, buf, len, offset, &inst->srv.status,
				 sizeof(inst->srv.status));
}

#endif /* CONFIG_BT_AICS */

static ssize_t write_aics_control(struct bt_conn *conn,
				  const struct bt_gatt_attr *attr,
				  const void *buf, uint16_t len,
				  uint16_t offset, uint8_t flags)
{
	struct bt_aics *inst = BT_AUDIO_CHRC_USER_DATA(attr);
	const struct bt_aics_gain_control *cp = buf;
	bool notify = false;

	if (offset) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_OFFSET);
	}

	if (!len || !buf) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

	/* Check opcode before length */
	if (!VALID_AICS_OPCODE(cp->cp.opcode)) {
		BT_DBG("Invalid opcode %u", cp->cp.opcode);
		return BT_GATT_ERR(BT_AICS_ERR_OP_NOT_SUPPORTED);
	}

	if ((len < AICS_CP_LEN) ||
	    (len == AICS_CP_SET_GAIN_LEN && cp->cp.opcode != BT_AICS_OPCODE_SET_GAIN) ||
	    (len > AICS_CP_SET_GAIN_LEN)) {
		return BT_GATT_ERR(BT_ATT_ERR_INVALID_ATTRIBUTE_LEN);
	}

	BT_DBG("Opcode %u, counter %u", cp->cp.opcode, cp->cp.counter);
	if (cp->cp.counter != inst->srv.state.change_counter) {
		return BT_GATT_ERR(BT_AICS_ERR_INVALID_COUNTER);
	}

	switch (cp->cp.opcode) {
	case BT_AICS_OPCODE_SET_GAIN:
		BT_DBG("Set gain %d", cp->gain_setting);
		if (cp->gain_setting < inst->srv.gain_settings.minimum ||
		    cp->gain_setting > inst->srv.gain_settings.maximum) {
			return BT_GATT_ERR(BT_AICS_ERR_OUT_OF_RANGE);
		}
		if (BT_AICS_INPUT_MODE_SETTABLE(inst->srv.state.gain_mode) &&
		    inst->srv.state.gain != cp->gain_setting) {
			inst->srv.state.gain = cp->gain_setting;
			notify = true;
		}
		break;
	case BT_AICS_OPCODE_UNMUTE:
		BT_DBG("Unmute");
		if (inst->srv.state.mute == BT_AICS_STATE_MUTE_DISABLED) {
			return BT_GATT_ERR(BT_AICS_ERR_MUTE_DISABLED);
		}
		if (inst->srv.state.mute != BT_AICS_STATE_UNMUTED) {
			inst->srv.state.mute = BT_AICS_STATE_UNMUTED;
			notify = true;
		}
		break;
	case BT_AICS_OPCODE_MUTE:
		BT_DBG("Mute");
		if (inst->srv.state.mute == BT_AICS_STATE_MUTE_DISABLED) {
			return BT_GATT_ERR(BT_AICS_ERR_MUTE_DISABLED);
		}
		if (inst->srv.state.mute != BT_AICS_STATE_MUTED) {
			inst->srv.state.mute = BT_AICS_STATE_MUTED;
			notify = true;
		}
		break;
	case BT_AICS_OPCODE_SET_MANUAL:
		BT_DBG("Set manual mode");
		if (BT_AICS_INPUT_MODE_IMMUTABLE(inst->srv.state.gain_mode)) {
			return BT_GATT_ERR(BT_AICS_ERR_GAIN_MODE_NOT_ALLOWED);
		}
		if (inst->srv.state.gain_mode != BT_AICS_MODE_MANUAL) {
			inst->srv.state.gain_mode = BT_AICS_MODE_MANUAL;
			notify = true;
		}
		break;
	case BT_AICS_OPCODE_SET_AUTO:
		BT_DBG("Set automatic mode");
		if (BT_AICS_INPUT_MODE_IMMUTABLE(inst->srv.state.gain_mode)) {
			return BT_GATT_ERR(BT_AICS_ERR_GAIN_MODE_NOT_ALLOWED);
		}
		if (inst->srv.state.gain_mode != BT_AICS_MODE_AUTO) {
			inst->srv.state.gain_mode = BT_AICS_MODE_AUTO;
			notify = true;
		}
		break;
	default:
		return BT_GATT_ERR(BT_AICS_ERR_OP_NOT_SUPPORTED);
	}

	if (notify) {
		inst->srv.state.change_counter++;

		BT_DBG("New state: gain %d, mute %u, gain_mode %u, counter %u",
		       inst->srv.state.gain, inst->srv.state.mute,
		       inst->srv.state.gain_mode, inst->srv.state.change_counter);

		bt_gatt_notify_uuid(NULL, BT_UUID_AICS_STATE,
				    inst->srv.service_p->attrs, &inst->srv.state,
				    sizeof(inst->srv.state));

		if (inst->srv.cb && inst->srv.cb->state) {
			inst->srv.cb->state(inst, 0, inst->srv.state.gain,
					inst->srv.state.mute,
					inst->srv.state.gain_mode);
		} else {
			BT_DBG("Callback not registered for instance %p", inst);
		}
	}

	return len;
}

#if defined(CONFIG_BT_AICS)
static void aics_description_cfg_changed(const struct bt_gatt_attr *attr,
					 uint16_t value)
{
	BT_DBG("value 0x%04x", value);
}
#endif /* CONFIG_BT_AICS */

static ssize_t write_description(struct bt_conn *conn,
				 const struct bt_gatt_attr *attr,
				 const void *buf, uint16_t len, uint16_t offset,
				 uint8_t flags)
{
	struct bt_aics *inst = BT_AUDIO_CHRC_USER_DATA(attr);

	if (len >= sizeof(inst->srv.description)) {
		BT_DBG("Output desc was clipped from length %u to %zu",
		       len, sizeof(inst->srv.description) - 1);
		/* We just clip the string value if it's too long */
		len = (uint16_t)sizeof(inst->srv.description) - 1;
	}

	if (memcmp(buf, inst->srv.description, len)) {
		memcpy(inst->srv.description, buf, len);
		inst->srv.description[len] = '\0';

		bt_gatt_notify_uuid(NULL, BT_UUID_AICS_DESCRIPTION,
				    inst->srv.service_p->attrs, &inst->srv.description,
				    strlen(inst->srv.description));

		if (inst->srv.cb && inst->srv.cb->description) {
			inst->srv.cb->description(inst, 0,
						  inst->srv.description);
		} else {
			BT_DBG("Callback not registered for instance %p", inst);
		}
	}

	BT_DBG("%s", inst->srv.description);

	return len;
}

static int aics_write(struct bt_aics *inst,
		      ssize_t (*write)(struct bt_conn *conn,
				       const struct bt_gatt_attr *attr,
				       const void *buf, uint16_t len,
				       uint16_t offset, uint8_t flags),
		      const void *buf, uint16_t len)
{
	struct bt_audio_attr_user_data user_data = {
		.user_data = inst,
	};
	struct bt_gatt_attr attr = {
		.user_data = &user_data,
	};
	int err;

	err = write(NULL, &attr, buf, len, 0, 0);
	if (err < 0) {
		return err;
	}

	return 0;
}

#if defined(CONFIG_BT_AICS)
static ssize_t read_description(struct bt_conn *conn,
				const struct bt_gatt_attr *attr, void *buf,
				uint16_t len, uint16_t offset)
{
	struct bt_aics *inst = BT_AUDIO_CHRC_USER_DATA(attr);

	BT_DBG("%s", inst->srv.description);

	return bt_gatt_attr_read(conn, attr, buf, len, offset,
				 &inst->srv.description, strlen(inst->srv.description));
}

/************************ PUBLIC API ************************/
void *bt_aics_svc_decl_get(struct bt_aics *aics)
{
	CHECKIF(!aics) {
		BT_DBG("NULL instance");
		return NULL;
	}

	return aics->srv.service_p->attrs;
}

static void prepare_aics_instances(void)
{
	for (int i = 0; i < ARRAY_SIZE(aics_insts); i++) {
		aics_insts[i].srv.service_p = &aics_service_list[i];
	}
}

int bt_aics_register(struct bt_aics *aics, struct bt_aics_register_param *param)
{
	int err;
	static bool instance_prepared;

	CHECKIF(!aics) {
		BT_DBG("NULL aics pointer");
		return -ENOTCONN;
	}

	CHECKIF(!param) {
		BT_DBG("NULL param");
		return -EINVAL;
	}

	if (!instance_prepared) {
		prepare_aics_instances();
		instance_prepared = true;
	}

	CHECKIF(aics->srv.initialized) {
		return -EALREADY;
	}

	CHECKIF(param->mute > BT_AICS_STATE_MUTE_DISABLED) {
		BT_DBG("Invalid AICS mute value: %u", param->mute);
		return -EINVAL;
	}

	CHECKIF(param->gain_mode > BT_AICS_MODE_AUTO) {
		BT_DBG("Invalid AICS mode value: %u", param->gain_mode);
		return -EINVAL;
	}

	CHECKIF(param->type > BT_AICS_INPUT_TYPE_STREAMING) {
		BT_DBG("Invalid AICS input type value: %u", param->type);
		return -EINVAL;
	}

	CHECKIF(param->units == 0) {
		BT_DBG("AICS units value shall not be 0");
		return -EINVAL;
	}

	CHECKIF(!(param->min_gain <= param->max_gain)) {
		BT_DBG("AICS min gain (%d) shall be lower than or equal to max gain (%d)",
		       param->min_gain, param->max_gain);
		return -EINVAL;
	}

	CHECKIF(param->gain < param->min_gain || param->gain > param->max_gain) {
		BT_DBG("AICS gain (%d) shall be not lower than min gain (%d) "
		       "or higher than max gain (%d)",
		       param->gain, param->min_gain, param->max_gain);
		return -EINVAL;
	}

	aics->srv.state.gain = param->gain;
	aics->srv.state.mute = param->mute;
	aics->srv.state.gain_mode = param->gain_mode;
	aics->srv.gain_settings.units = param->units;
	aics->srv.gain_settings.minimum = param->min_gain;
	aics->srv.gain_settings.maximum = param->max_gain;
	aics->srv.type = param->type;
	aics->srv.status = param->status ? BT_AICS_STATUS_ACTIVE : BT_AICS_STATUS_INACTIVE;
	aics->srv.cb = param->cb;

	if (param->description) {
		strncpy(aics->srv.description, param->description,
			sizeof(aics->srv.description) - 1);
		/* strncpy may not always null-terminate */
		aics->srv.description[sizeof(aics->srv.description) - 1] = '\0';
		if (IS_ENABLED(CONFIG_BT_DEBUG_AICS) &&
		    strcmp(aics->srv.description, param->description)) {
			BT_DBG("Input desc clipped to %s",
			       aics->srv.description);
		}
	}

	/* Iterate over the attributes in AICS (starting from i = 1 to skip the
	 * service declaration) to find the BT_UUID_AICS_DESCRIPTION and update
	 * the characteristic value (at [i]), update that with the write
	 * permission and callback, and also update the characteristic
	 * declaration (always found at [i - 1]) with the
	 * BT_GATT_CHRC_WRITE_WITHOUT_RESP property.
	 */
	if (param->desc_writable) {
		for (int i = 1; i < aics->srv.service_p->attr_count; i++) {
			struct bt_gatt_attr *attr;

			attr = &aics->srv.service_p->attrs[i];

			if (!bt_uuid_cmp(attr->uuid, BT_UUID_AICS_DESCRIPTION)) {
				/* Update attr and chrc to be writable */
				struct bt_gatt_chrc *chrc;

				chrc = aics->srv.service_p->attrs[i - 1].user_data;
				attr->perm |= BT_GATT_PERM_WRITE_ENCRYPT;
				chrc->properties |= BT_GATT_CHRC_WRITE_WITHOUT_RESP;

				break;
			}
		}
	}

	err = bt_gatt_service_register(aics->srv.service_p);
	if (err) {
		BT_DBG("Could not register AICS service");
		return err;
	}

	aics->srv.initialized = true;

	return 0;
}

struct bt_aics *bt_aics_free_instance_get(void)
{
	if (instance_cnt >= CONFIG_BT_AICS_MAX_INSTANCE_COUNT) {
		return NULL;
	}

	return (struct bt_aics *)&aics_insts[instance_cnt++];
}

/****************************** PUBLIC API ******************************/
int bt_aics_deactivate(struct bt_aics *inst)
{
	CHECKIF(!inst) {
		BT_DBG("NULL instance");
		return -EINVAL;
	}

	if (inst->srv.status == BT_AICS_STATUS_ACTIVE) {
		inst->srv.status = BT_AICS_STATUS_INACTIVE;
		BT_DBG("Instance %p: Status was set to inactive", inst);

		bt_gatt_notify_uuid(NULL, BT_UUID_AICS_INPUT_STATUS,
				    inst->srv.service_p->attrs,
				    &inst->srv.status,
				    sizeof(inst->srv.status));

		if (inst->srv.cb && inst->srv.cb->status) {
			inst->srv.cb->status(inst, 0, inst->srv.status);
		} else {
			BT_DBG("Callback not registered for instance %p", inst);
		}
	}

	return 0;
}

int bt_aics_activate(struct bt_aics *inst)
{
	CHECKIF(!inst) {
		BT_DBG("NULL instance");
		return -EINVAL;
	}

	if (inst->srv.status == BT_AICS_STATUS_INACTIVE) {
		inst->srv.status = BT_AICS_STATUS_ACTIVE;
		BT_DBG("Instance %p: Status was set to active", inst);

		bt_gatt_notify_uuid(NULL, BT_UUID_AICS_INPUT_STATUS,
				    inst->srv.service_p->attrs,
				    &inst->srv.status,
				    sizeof(inst->srv.status));

		if (inst->srv.cb && inst->srv.cb->status) {
			inst->srv.cb->status(inst, 0, inst->srv.status);
		} else {
			BT_DBG("Callback not registered for instance %p", inst);
		}
	}

	return 0;
}

#endif /* CONFIG_BT_AICS */

int bt_aics_state_get(struct bt_aics *inst)
{
	CHECKIF(!inst) {
		BT_DBG("NULL instance");
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_BT_AICS_CLIENT) && inst->client_instance) {
		return bt_aics_client_state_get(inst);
	} else if (IS_ENABLED(CONFIG_BT_AICS) && !inst->client_instance) {
		if (inst->srv.cb && inst->srv.cb->state) {
			inst->srv.cb->state(inst, 0, inst->srv.state.gain,
					    inst->srv.state.mute,
					    inst->srv.state.gain_mode);
		} else {
			BT_DBG("Callback not registered for instance %p", inst);
		}
		return 0;
	}

	return -ENOTSUP;
}

int bt_aics_gain_setting_get(struct bt_aics *inst)
{
	CHECKIF(!inst) {
		BT_DBG("NULL instance");
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_BT_AICS_CLIENT) && inst->client_instance) {
		return bt_aics_client_gain_setting_get(inst);
	} else if (IS_ENABLED(CONFIG_BT_AICS) && !inst->client_instance) {
		if (inst->srv.cb && inst->srv.cb->gain_setting) {
			inst->srv.cb->gain_setting(inst, 0,
						   inst->srv.gain_settings.units,
						   inst->srv.gain_settings.minimum,
						   inst->srv.gain_settings.maximum);
		} else {
			BT_DBG("Callback not registered for instance %p", inst);
		}
		return 0;
	}

	return -ENOTSUP;
}

int bt_aics_type_get(struct bt_aics *inst)
{
	CHECKIF(!inst) {
		BT_DBG("NULL instance");
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_BT_AICS_CLIENT) && inst->client_instance) {
		return bt_aics_client_type_get(inst);
	} else if (IS_ENABLED(CONFIG_BT_AICS) && !inst->client_instance) {
		if (inst->srv.cb && inst->srv.cb->type) {
			inst->srv.cb->type(inst, 0, inst->srv.type);
		} else {
			BT_DBG("Callback not registered for instance %p", inst);
		}
		return 0;
	}

	return -ENOTSUP;
}

int bt_aics_status_get(struct bt_aics *inst)
{
	CHECKIF(!inst) {
		BT_DBG("NULL instance");
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_BT_AICS_CLIENT) && inst->client_instance) {
		return bt_aics_client_status_get(inst);
	} else if (IS_ENABLED(CONFIG_BT_AICS) && !inst->client_instance) {
		if (inst->srv.cb && inst->srv.cb->status) {
			inst->srv.cb->status(inst, 0, inst->srv.status);
		} else {
			BT_DBG("Callback not registered for instance %p", inst);
		}
		return 0;
	}

	return -ENOTSUP;
}

int bt_aics_unmute(struct bt_aics *inst)
{
	CHECKIF(!inst) {
		BT_DBG("NULL instance");
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_BT_AICS_CLIENT) && inst->client_instance) {
		return bt_aics_client_unmute(inst);
	} else if (IS_ENABLED(CONFIG_BT_AICS) && !inst->client_instance) {
		struct bt_aics_control cp;

		cp.opcode = BT_AICS_OPCODE_UNMUTE;
		cp.counter = inst->srv.state.change_counter;

		return aics_write(inst, write_aics_control, &cp, sizeof(cp));
	}

	return -ENOTSUP;
}

int bt_aics_mute(struct bt_aics *inst)
{
	CHECKIF(!inst) {
		BT_DBG("NULL instance");
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_BT_AICS_CLIENT) && inst->client_instance) {
		return bt_aics_client_mute(inst);
	} else if (IS_ENABLED(CONFIG_BT_AICS) && !inst->client_instance) {
		struct bt_aics_control cp;

		cp.opcode = BT_AICS_OPCODE_MUTE;
		cp.counter = inst->srv.state.change_counter;

		return aics_write(inst, write_aics_control, &cp, sizeof(cp));
	}

	return -ENOTSUP;
}

int bt_aics_manual_gain_set(struct bt_aics *inst)
{
	CHECKIF(!inst) {
		BT_DBG("NULL instance");
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_BT_AICS_CLIENT) && inst->client_instance) {
		return bt_aics_client_manual_gain_set(inst);
	} else if (IS_ENABLED(CONFIG_BT_AICS) && !inst->client_instance) {
		struct bt_aics_control cp;

		cp.opcode = BT_AICS_OPCODE_SET_MANUAL;
		cp.counter = inst->srv.state.change_counter;

		return aics_write(inst, write_aics_control, &cp, sizeof(cp));
	}

	return -ENOTSUP;
}

int bt_aics_automatic_gain_set(struct bt_aics *inst)
{
	CHECKIF(!inst) {
		BT_DBG("NULL instance");
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_BT_AICS_CLIENT) && inst->client_instance) {
		return bt_aics_client_automatic_gain_set(inst);
	} else if (IS_ENABLED(CONFIG_BT_AICS) && !inst->client_instance) {
		struct bt_aics_control cp;

		cp.opcode = BT_AICS_OPCODE_SET_AUTO;
		cp.counter = inst->srv.state.change_counter;

		return aics_write(inst, write_aics_control, &cp, sizeof(cp));
	}

	return -ENOTSUP;
}

int bt_aics_gain_set(struct bt_aics *inst, int8_t gain)
{
	CHECKIF(!inst) {
		BT_DBG("NULL instance");
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_BT_AICS_CLIENT) && inst->client_instance) {
		return bt_aics_client_gain_set(inst, gain);
	} else if (IS_ENABLED(CONFIG_BT_AICS) && !inst->client_instance) {
		struct bt_aics_gain_control cp;

		cp.cp.opcode = BT_AICS_OPCODE_SET_GAIN;
		cp.cp.counter = inst->srv.state.change_counter;
		cp.gain_setting = gain;

		return aics_write(inst, write_aics_control, &cp, sizeof(cp));
	}

	return -ENOTSUP;
}

int bt_aics_description_get(struct bt_aics *inst)
{
	CHECKIF(!inst) {
		BT_DBG("NULL instance");
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_BT_AICS_CLIENT) && inst->client_instance) {
		return bt_aics_client_description_get(inst);
	} else if (IS_ENABLED(CONFIG_BT_AICS) && !inst->client_instance) {
		if (inst->srv.cb && inst->srv.cb->description) {
			inst->srv.cb->description(inst, 0,
						  inst->srv.description);
		} else {
			BT_DBG("Callback not registered for instance %p", inst);
		}
		return 0;
	}

	return -ENOTSUP;
}

int bt_aics_description_set(struct bt_aics *inst, const char *description)
{
	CHECKIF(!inst) {
		BT_DBG("NULL instance");
		return -EINVAL;
	}

	CHECKIF(!description) {
		BT_DBG("NULL description");
		return -EINVAL;
	}

	if (IS_ENABLED(CONFIG_BT_AICS_CLIENT) && inst->client_instance) {
		return bt_aics_client_description_set(inst, description);
	} else if (IS_ENABLED(CONFIG_BT_AICS) && !inst->client_instance) {
		return aics_write(inst, write_description, description, strlen(description));
	}

	return -ENOTSUP;
}
