/*  Bluetooth VCS Client - Volume Offset Control Client */

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

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

#include <sys/check.h>

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

#include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h>
#include <bluetooth/gatt.h>
#include <bluetooth/audio/vcs.h>

#include "vcs_internal.h"

#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_VCS_CLIENT)
#define LOG_MODULE_NAME bt_vcs_client
#include "common/log.h"

/* Callback functions */
static struct bt_vcs_cb *vcs_client_cb;

static struct bt_vcs vcs_insts[CONFIG_BT_MAX_CONN];
static int vcs_client_common_vcs_cp(struct bt_vcs *vcs, uint8_t opcode);

static struct bt_vcs *lookup_vcs_by_vocs(const struct bt_vocs *vocs)
{
	__ASSERT(vocs != NULL, "VOCS pointer cannot be NULL");

	for (int i = 0; i < ARRAY_SIZE(vcs_insts); i++) {
		for (int j = 0; j < ARRAY_SIZE(vcs_insts[i].cli.vocs); j++) {
			if (vcs_insts[i].cli.vocs[j] == vocs) {
				return &vcs_insts[i];
			}
		}
	}

	return NULL;
}

static struct bt_vcs *lookup_vcs_by_aics(const struct bt_aics *aics)
{
	__ASSERT(aics != NULL, "aics pointer cannot be NULL");

	for (int i = 0; i < ARRAY_SIZE(vcs_insts); i++) {
		for (int j = 0; j < ARRAY_SIZE(vcs_insts[i].cli.aics); j++) {
			if (vcs_insts[i].cli.aics[j] == aics) {
				return &vcs_insts[i];
			}
		}
	}

	return NULL;
}

bool bt_vcs_client_valid_vocs_inst(struct bt_vcs *vcs, struct bt_vocs *vocs)
{
	if (vcs == NULL) {
		return false;
	}

	if (!vcs->client_instance) {
		return false;
	}

	if (vcs->cli.conn == NULL) {
		return false;
	}

	if (vocs == NULL) {
		return false;
	}

	for (int i = 0; i < ARRAY_SIZE(vcs->cli.vocs); i++) {
		if (vcs->cli.vocs[i] == vocs) {
			return true;
		}
	}

	return false;
}

bool bt_vcs_client_valid_aics_inst(struct bt_vcs *vcs, struct bt_aics *aics)
{
	if (vcs == NULL) {
		return false;
	}

	if (!vcs->client_instance) {
		return false;
	}

	if (vcs->cli.conn == NULL) {
		return false;
	}

	if (aics == NULL) {
		return false;
	}

	for (int i = 0; i < ARRAY_SIZE(vcs->cli.aics); i++) {
		if (vcs->cli.aics[i] == aics) {
			return true;
		}
	}

	return false;
}

static uint8_t vcs_client_notify_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_vcs *vcs_inst = &vcs_insts[bt_conn_index(conn)];

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

	if (handle == vcs_inst->cli.state_handle &&
	    length == sizeof(vcs_inst->cli.state)) {
		memcpy(&vcs_inst->cli.state, data, length);
		BT_DBG("Volume %u, mute %u, counter %u",
			vcs_inst->cli.state.volume, vcs_inst->cli.state.mute,
			vcs_inst->cli.state.change_counter);
		if (vcs_client_cb && vcs_client_cb->state) {
			vcs_client_cb->state(vcs_inst, 0, vcs_inst->cli.state.volume,
					     vcs_inst->cli.state.mute);
		}
	} else if (handle == vcs_inst->cli.flag_handle &&
		   length == sizeof(vcs_inst->cli.flags)) {
		memcpy(&vcs_inst->cli.flags, data, length);
		BT_DBG("Flags %u", vcs_inst->cli.flags);
		if (vcs_client_cb && vcs_client_cb->flags) {
			vcs_client_cb->flags(vcs_inst, 0, vcs_inst->cli.flags);
		}
	}

	return BT_GATT_ITER_CONTINUE;
}

static uint8_t vcs_client_read_vol_state_cb(struct bt_conn *conn, uint8_t err,
					    struct bt_gatt_read_params *params,
					    const void *data, uint16_t length)
{
	int cb_err = err;
	struct bt_vcs *vcs_inst = &vcs_insts[bt_conn_index(conn)];

	vcs_inst->cli.busy = false;

	if (cb_err) {
		BT_DBG("err: %d", cb_err);
	} else if (data != NULL) {
		if (length == sizeof(vcs_inst->cli.state)) {
			memcpy(&vcs_inst->cli.state, data, length);
			BT_DBG("Volume %u, mute %u, counter %u",
			       vcs_inst->cli.state.volume,
			       vcs_inst->cli.state.mute,
			       vcs_inst->cli.state.change_counter);
		} else {
			BT_DBG("Invalid length %u (expected %zu)",
			       length, sizeof(vcs_inst->cli.state));
			cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
		}
	}

	if (vcs_client_cb && vcs_client_cb->state) {
		if (cb_err) {
			vcs_client_cb->state(vcs_inst, cb_err, 0, 0);
		} else {
			vcs_client_cb->state(vcs_inst, cb_err,
					     vcs_inst->cli.state.volume,
					     vcs_inst->cli.state.mute);
		}
	}

	return BT_GATT_ITER_STOP;
}

static uint8_t vcs_client_read_flag_cb(struct bt_conn *conn, uint8_t err,
				       struct bt_gatt_read_params *params,
				       const void *data, uint16_t length)
{
	int cb_err = err;
	struct bt_vcs *vcs_inst = &vcs_insts[bt_conn_index(conn)];

	vcs_inst->cli.busy = false;

	if (cb_err) {
		BT_DBG("err: %d", cb_err);
	} else if (data != NULL) {
		if (length == sizeof(vcs_inst->cli.flags)) {
			memcpy(&vcs_inst->cli.flags, data, length);
			BT_DBG("Flags %u", vcs_inst->cli.flags);
		} else {
			BT_DBG("Invalid length %u (expected %zu)",
			       length, sizeof(vcs_inst->cli.flags));
			cb_err = BT_ATT_ERR_INVALID_ATTRIBUTE_LEN;
		}
	}

	if (vcs_client_cb && vcs_client_cb->flags) {
		if (cb_err) {
			vcs_client_cb->flags(vcs_inst, cb_err, 0);
		} else {
			vcs_client_cb->flags(vcs_inst, cb_err, vcs_inst->cli.flags);
		}
	}

	return BT_GATT_ITER_STOP;
}

static void vcs_cp_notify_app(struct bt_vcs *vcs, uint8_t opcode, int err)
{
	if (vcs_client_cb == NULL) {
		return;
	}

	switch (opcode) {
	case BT_VCS_OPCODE_REL_VOL_DOWN:
		if (vcs_client_cb->vol_down) {
			vcs_client_cb->vol_down(vcs, err);
		}
		break;
	case BT_VCS_OPCODE_REL_VOL_UP:
		if (vcs_client_cb->vol_up) {
			vcs_client_cb->vol_up(vcs, err);
		}
		break;
	case BT_VCS_OPCODE_UNMUTE_REL_VOL_DOWN:
		if (vcs_client_cb->vol_down_unmute) {
			vcs_client_cb->vol_down_unmute(vcs, err);
		}
		break;
	case BT_VCS_OPCODE_UNMUTE_REL_VOL_UP:
		if (vcs_client_cb->vol_up_unmute) {
			vcs_client_cb->vol_up_unmute(vcs, err);
		}
		break;
	case BT_VCS_OPCODE_SET_ABS_VOL:
		if (vcs_client_cb->vol_set) {
			vcs_client_cb->vol_set(vcs, err);
		}
		break;
	case BT_VCS_OPCODE_UNMUTE:
		if (vcs_client_cb->unmute) {
			vcs_client_cb->unmute(vcs, err);
		}
		break;
	case BT_VCS_OPCODE_MUTE:
		if (vcs_client_cb->mute) {
			vcs_client_cb->mute(vcs, err);
		}
		break;
	default:
		BT_DBG("Unknown opcode 0x%02x", opcode);
		break;
	}
}

static uint8_t internal_read_vol_state_cb(struct bt_conn *conn, uint8_t err,
					  struct bt_gatt_read_params *params,
					  const void *data, uint16_t length)
{
	int cb_err = 0;
	struct bt_vcs *vcs_inst = &vcs_insts[bt_conn_index(conn)];
	uint8_t opcode = vcs_inst->cli.cp_val.cp.opcode;


	memset(params, 0, sizeof(*params));

	if (err > 0) {
		BT_WARN("Volume state read failed: %d", err);
		cb_err = BT_ATT_ERR_UNLIKELY;
	} else if (data != NULL) {
		if (length == sizeof(vcs_inst->cli.state)) {
			int write_err;

			memcpy(&vcs_inst->cli.state, data, length);
			BT_DBG("Volume %u, mute %u, counter %u",
			       vcs_inst->cli.state.volume,
			       vcs_inst->cli.state.mute,
			       vcs_inst->cli.state.change_counter);

			/* clear busy flag to reuse function */
			vcs_inst->cli.busy = false;
			if (opcode == BT_VCS_OPCODE_SET_ABS_VOL) {
				write_err = bt_vcs_client_set_volume(vcs_inst,
								     vcs_inst->cli.cp_val.volume);
			} else {
				write_err = vcs_client_common_vcs_cp(vcs_inst,
								     opcode);
			}
			if (write_err) {
				cb_err = BT_ATT_ERR_UNLIKELY;
			}
		} else {
			BT_DBG("Invalid length %u (expected %zu)",
			       length, sizeof(vcs_inst->cli.state));
			cb_err = BT_ATT_ERR_UNLIKELY;
		}
	}

	if (cb_err) {
		vcs_inst->cli.busy = false;
		vcs_cp_notify_app(vcs_inst, opcode, cb_err);
	}

	return BT_GATT_ITER_STOP;
}

static void vcs_client_write_vcs_cp_cb(struct bt_conn *conn, uint8_t err,
				       struct bt_gatt_write_params *params)
{
	struct bt_vcs *vcs_inst = &vcs_insts[bt_conn_index(conn)];
	uint8_t opcode = vcs_inst->cli.cp_val.cp.opcode;
	int cb_err = err;

	BT_DBG("err: 0x%02X", err);
	memset(params, 0, sizeof(*params));

	/* If the change counter is out of data when a write was attempted from
	 * the application, we automatically initiate a read to get the newest
	 * state and try again. Once the change counter has been read, we
	 * restart the applications write request. If it fails
	 * the second time, we return an error to the application.
	 */
	if (cb_err == BT_VCS_ERR_INVALID_COUNTER && vcs_inst->cli.cp_retried) {
		cb_err = BT_ATT_ERR_UNLIKELY;
	} else if (err == BT_VCS_ERR_INVALID_COUNTER &&
		   vcs_inst->cli.state_handle) {
		vcs_inst->cli.read_params.func = internal_read_vol_state_cb;
		vcs_inst->cli.read_params.handle_count = 1;
		vcs_inst->cli.read_params.single.handle = vcs_inst->cli.state_handle;
		vcs_inst->cli.read_params.single.offset = 0U;

		cb_err = bt_gatt_read(conn, &vcs_inst->cli.read_params);
		if (cb_err) {
			BT_WARN("Could not read Volume state: %d", cb_err);
		} else {
			vcs_inst->cli.cp_retried = true;
			/* Wait for read callback */
			return;
		}
	}

	vcs_inst->cli.busy = false;
	vcs_inst->cli.cp_retried = false;

	vcs_cp_notify_app(vcs_inst, opcode, err);
}

#if (CONFIG_BT_VCS_CLIENT_MAX_AICS_INST > 0 || CONFIG_BT_VCS_CLIENT_MAX_VOCS_INST > 0)
static uint8_t vcs_discover_include_func(struct bt_conn *conn,
					 const struct bt_gatt_attr *attr,
					 struct bt_gatt_discover_params *params)
{
	struct bt_gatt_include *include;
	uint8_t inst_idx;
	int err;
	struct bt_vcs *vcs_inst = &vcs_insts[bt_conn_index(conn)];

	if (attr == NULL) {
		BT_DBG("Discover include complete for VCS: %u AICS and %u VOCS",
		       vcs_inst->cli.aics_inst_cnt, vcs_inst->cli.vocs_inst_cnt);
		(void)memset(params, 0, sizeof(*params));

		if (vcs_client_cb && vcs_client_cb->discover) {
			/*
			 * TODO: Validate that all mandatory handles were found
			 */
			vcs_client_cb->discover(vcs_inst, 0,
						vcs_inst->cli.vocs_inst_cnt,
						vcs_inst->cli.aics_inst_cnt);
		}

		return BT_GATT_ITER_STOP;
	}

	BT_DBG("[ATTRIBUTE] handle 0x%04X", attr->handle);

	if (params->type == BT_GATT_DISCOVER_INCLUDE) {
		uint8_t conn_index = bt_conn_index(conn);

		include = (struct bt_gatt_include *)attr->user_data;
		BT_DBG("Include UUID %s", bt_uuid_str(include->uuid));

#if CONFIG_BT_VCS_CLIENT_MAX_AICS_INST > 0
		if (bt_uuid_cmp(include->uuid, BT_UUID_AICS) == 0 &&
		    vcs_inst->cli.aics_inst_cnt < CONFIG_BT_VCS_CLIENT_MAX_AICS_INST) {
			struct bt_aics_discover_param param = {
				.start_handle = include->start_handle,
				.end_handle = include->end_handle,
			};

			/* Update discover params so we can continue where we
			 * left off after bt_aics_discover
			 */
			vcs_inst->cli.discover_params.start_handle = attr->handle + 1;

			inst_idx = vcs_inst->cli.aics_inst_cnt++;
			err = bt_aics_discover(conn,
					       vcs_insts[conn_index].cli.aics[inst_idx],
					       &param);
			if (err != 0) {
				BT_DBG("AICS Discover failed (err %d)", err);
				if (vcs_client_cb && vcs_client_cb->discover) {
					vcs_client_cb->discover(vcs_inst, err,
								0, 0);
				}
			}

			return BT_GATT_ITER_STOP;
		}
#endif /* CONFIG_BT_VCS_CLIENT_MAX_AICS_INST */
#if CONFIG_BT_VCS_CLIENT_MAX_VOCS_INST > 0
		if (bt_uuid_cmp(include->uuid, BT_UUID_VOCS) == 0 &&
		    vcs_inst->cli.vocs_inst_cnt < CONFIG_BT_VCS_CLIENT_MAX_VOCS_INST) {
			struct bt_vocs_discover_param param = {
				.start_handle = include->start_handle,
				.end_handle = include->end_handle,
			};

			/* Update discover params so we can continue where we
			 * left off after bt_vocs_discover
			 */
			vcs_inst->cli.discover_params.start_handle = attr->handle + 1;

			inst_idx = vcs_inst->cli.vocs_inst_cnt++;
			err = bt_vocs_discover(conn,
					       vcs_insts[conn_index].cli.vocs[inst_idx],
					       &param);
			if (err != 0) {
				BT_DBG("VOCS Discover failed (err %d)", err);
				if (vcs_client_cb && vcs_client_cb->discover) {
					vcs_client_cb->discover(vcs_inst, err,
								0, 0);
				}
			}

			return BT_GATT_ITER_STOP;
		}
#endif /* CONFIG_BT_VCS_CLIENT_MAX_VOCS_INST */
	}

	return BT_GATT_ITER_CONTINUE;
}
#endif /* (CONFIG_BT_VCS_CLIENT_MAX_AICS_INST > 0 || CONFIG_BT_VCS_CLIENT_MAX_VOCS_INST > 0) */

/**
 * @brief This will discover all characteristics on the server, retrieving the
 * handles of the writeable characteristics and subscribing to all notify and
 * indicate characteristics.
 */
static uint8_t vcs_discover_func(struct bt_conn *conn,
				 const struct bt_gatt_attr *attr,
				 struct bt_gatt_discover_params *params)
{
	int err = 0;
	struct bt_gatt_chrc *chrc;
	struct bt_gatt_subscribe_params *sub_params = NULL;
	struct bt_vcs *vcs_inst = &vcs_insts[bt_conn_index(conn)];

	if (attr == NULL) {
		BT_DBG("Setup complete for VCS");
		(void)memset(params, 0, sizeof(*params));
#if (CONFIG_BT_VCS_CLIENT_MAX_AICS_INST > 0 || CONFIG_BT_VCS_CLIENT_MAX_VOCS_INST > 0)
		/* Discover included services */
		vcs_inst->cli.discover_params.start_handle = vcs_inst->cli.start_handle;
		vcs_inst->cli.discover_params.end_handle = vcs_inst->cli.end_handle;
		vcs_inst->cli.discover_params.type = BT_GATT_DISCOVER_INCLUDE;
		vcs_inst->cli.discover_params.func = vcs_discover_include_func;

		err = bt_gatt_discover(conn, &vcs_inst->cli.discover_params);
		if (err != 0) {
			BT_DBG("Discover failed (err %d)", err);
			if (vcs_client_cb && vcs_client_cb->discover) {
				vcs_client_cb->discover(vcs_inst, err, 0, 0);
			}
		}
#else
		if (vcs_client_cb && vcs_client_cb->discover) {
			vcs_client_cb->discover(vcs_inst, err, 0, 0);
		}
#endif /* (CONFIG_BT_VCS_CLIENT_MAX_AICS_INST > 0 || CONFIG_BT_VCS_CLIENT_MAX_VOCS_INST > 0) */

		return BT_GATT_ITER_STOP;
	}

	BT_DBG("[ATTRIBUTE] handle 0x%04X", attr->handle);

	if (params->type == BT_GATT_DISCOVER_CHARACTERISTIC) {
		chrc = (struct bt_gatt_chrc *)attr->user_data;

		if (bt_uuid_cmp(chrc->uuid, BT_UUID_VCS_STATE) == 0) {
			BT_DBG("Volume state");
			vcs_inst->cli.state_handle = chrc->value_handle;
			sub_params = &vcs_inst->cli.state_sub_params;
		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_VCS_CONTROL) == 0) {
			BT_DBG("Control Point");
			vcs_inst->cli.control_handle = chrc->value_handle;
		} else if (bt_uuid_cmp(chrc->uuid, BT_UUID_VCS_FLAGS) == 0) {
			BT_DBG("Flags");
			vcs_inst->cli.flag_handle = chrc->value_handle;
			sub_params = &vcs_inst->cli.flag_sub_params;
		}

		if (sub_params != NULL) {
			int err;

			sub_params->value = BT_GATT_CCC_NOTIFY;
			sub_params->value_handle = chrc->value_handle;
			/*
			 * TODO: Don't assume that CCC is at handle + 2;
			 * do proper discovery;
			 */
			sub_params->ccc_handle = attr->handle + 2;
			sub_params->notify = vcs_client_notify_handler;
			err = bt_gatt_subscribe(conn, sub_params);
			if (err == 0) {
				BT_DBG("Subscribed to handle 0x%04X",
				       attr->handle);
			} else {
				BT_DBG("Could not subscribe to handle 0x%04X",
				       attr->handle);
			}
		}
	}

	return BT_GATT_ITER_CONTINUE;
}

/**
 * @brief This will discover all characteristics on the server, retrieving the
 * handles of the writeable characteristics and subscribing to all notify and
 * indicate characteristics.
 */
static uint8_t primary_discover_func(struct bt_conn *conn,
				     const struct bt_gatt_attr *attr,
				     struct bt_gatt_discover_params *params)
{
	struct bt_gatt_service_val *prim_service;
	struct bt_vcs *vcs_inst = &vcs_insts[bt_conn_index(conn)];

	if (attr == NULL) {
		BT_DBG("Could not find a VCS instance on the server");
		if (vcs_client_cb && vcs_client_cb->discover) {
			vcs_client_cb->discover(vcs_inst, -ENODATA, 0, 0);
		}
		return BT_GATT_ITER_STOP;
	}

	BT_DBG("[ATTRIBUTE] handle 0x%04X", attr->handle);

	if (params->type == BT_GATT_DISCOVER_PRIMARY) {
		int err;

		BT_DBG("Primary discover complete");
		prim_service = (struct bt_gatt_service_val *)attr->user_data;

		vcs_inst->cli.start_handle = attr->handle + 1;
		vcs_inst->cli.end_handle = prim_service->end_handle;

		/* Discover characteristics */
		vcs_inst->cli.discover_params.uuid = NULL;
		vcs_inst->cli.discover_params.start_handle = vcs_inst->cli.start_handle;
		vcs_inst->cli.discover_params.end_handle = vcs_inst->cli.end_handle;
		vcs_inst->cli.discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
		vcs_inst->cli.discover_params.func = vcs_discover_func;

		err = bt_gatt_discover(conn, &vcs_inst->cli.discover_params);
		if (err != 0) {
			BT_DBG("Discover failed (err %d)", err);
			if (vcs_client_cb && vcs_client_cb->discover) {
				vcs_client_cb->discover(vcs_inst, err, 0, 0);
			}
		}

		return BT_GATT_ITER_STOP;
	}

	return BT_GATT_ITER_CONTINUE;
}

static int vcs_client_common_vcs_cp(struct bt_vcs *vcs, uint8_t opcode)
{
	int err;

	CHECKIF(vcs->cli.conn == NULL) {
		BT_DBG("NULL conn");
		return -EINVAL;
	}

	if (vcs->cli.control_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	} else if (vcs->cli.busy) {
		return -EBUSY;
	}

	vcs->cli.busy = true;
	vcs->cli.cp_val.cp.opcode = opcode;
	vcs->cli.cp_val.cp.counter = vcs->cli.state.change_counter;
	vcs->cli.write_params.offset = 0;
	vcs->cli.write_params.data = &vcs->cli.cp_val.cp;
	vcs->cli.write_params.length = sizeof(vcs->cli.cp_val.cp);
	vcs->cli.write_params.handle = vcs->cli.control_handle;
	vcs->cli.write_params.func = vcs_client_write_vcs_cp_cb;

	err = bt_gatt_write(vcs->cli.conn, &vcs->cli.write_params);
	if (err == 0) {
		vcs->cli.busy = true;
	}
	return err;
}

static void aics_discover_cb(struct bt_aics *inst, int err)
{
	struct bt_vcs *vcs_inst = lookup_vcs_by_aics(inst);

	if (err == 0) {
		/* Continue discovery of included services */
		err = bt_gatt_discover(vcs_inst->cli.conn,
				       &vcs_inst->cli.discover_params);
	}

	if (err != 0) {
		BT_DBG("Discover failed (err %d)", err);
		if (vcs_client_cb && vcs_client_cb->discover) {
			vcs_client_cb->discover(vcs_inst, err, 0, 0);
		}
	}
}

static void vocs_discover_cb(struct bt_vocs *inst, int err)
{
	struct bt_vcs *vcs_inst = lookup_vcs_by_vocs(inst);

	if (vcs_inst == NULL) {
		BT_ERR("Could not lookup vcs_inst from vocs");

		if (vcs_client_cb && vcs_client_cb->discover) {
			vcs_client_cb->discover(vcs_inst,
						BT_GATT_ERR(BT_ATT_ERR_UNLIKELY),
						0, 0);
		}

		return;
	}

	if (err == 0) {
		/* Continue discovery of included services */
		err = bt_gatt_discover(vcs_inst->cli.conn,
				       &vcs_inst->cli.discover_params);
	}

	if (err != 0) {
		BT_DBG("Discover failed (err %d)", err);
		if (vcs_client_cb && vcs_client_cb->discover) {
			vcs_client_cb->discover(vcs_inst, err, 0, 0);
		}
	}
}

static void vcs_client_reset(struct bt_conn *conn)
{
	struct bt_vcs *vcs_inst = &vcs_insts[bt_conn_index(conn)];

	memset(&vcs_inst->cli.state, 0, sizeof(vcs_inst->cli.state));
	vcs_inst->cli.flags = 0;
	vcs_inst->cli.start_handle = 0;
	vcs_inst->cli.end_handle = 0;
	vcs_inst->cli.state_handle = 0;
	vcs_inst->cli.control_handle = 0;
	vcs_inst->cli.flag_handle = 0;
	vcs_inst->cli.vocs_inst_cnt = 0;
	vcs_inst->cli.aics_inst_cnt = 0;

	memset(&vcs_inst->cli.discover_params, 0, sizeof(vcs_inst->cli.discover_params));

	/* It's okay if these fail */
	(void)bt_gatt_unsubscribe(conn, &vcs_inst->cli.state_sub_params);
	(void)bt_gatt_unsubscribe(conn, &vcs_inst->cli.flag_sub_params);
}

static void bt_vcs_client_init(void)
{
	int i, j;

	if (IS_ENABLED(CONFIG_BT_VOCS_CLIENT) &&
	    CONFIG_BT_VCS_CLIENT_MAX_VOCS_INST > 0) {
		for (i = 0; i < ARRAY_SIZE(vcs_insts); i++) {
			for (j = 0; j < ARRAY_SIZE(vcs_insts[i].cli.vocs); j++) {
				vcs_insts[i].cli.vocs[j] = bt_vocs_client_free_instance_get();

				__ASSERT(vcs_insts[i].cli.vocs[j],
					 "Could not allocate VOCS client instance");

				bt_vocs_client_cb_register(vcs_insts[i].cli.vocs[j],
							   &vcs_client_cb->vocs_cb);
			}
		}
	}

	if (IS_ENABLED(CONFIG_BT_AICS_CLIENT) &&
	    CONFIG_BT_VCS_CLIENT_MAX_AICS_INST > 0) {
		for (i = 0; i < ARRAY_SIZE(vcs_insts); i++) {
			for (j = 0; j < ARRAY_SIZE(vcs_insts[i].cli.aics); j++) {
				vcs_insts[i].cli.aics[j] = bt_aics_client_free_instance_get();

				__ASSERT(vcs_insts[i].cli.aics[j],
					"Could not allocate AICS client instance");

				bt_aics_client_cb_register(vcs_insts[i].cli.aics[j],
							   &vcs_client_cb->aics_cb);
			}
		}
	}
}

int bt_vcs_discover(struct bt_conn *conn, struct bt_vcs **vcs)
{
	static bool initialized;
	struct bt_vcs *vcs_inst;
	int err;

	/*
	 * This will initiate a discover procedure. The procedure will do the
	 * following sequence:
	 * 1) Primary discover for the VCS
	 * 2) Characteristic discover of the VCS
	 * 3) Discover services included in VCS (VOCS and AICS)
	 * 4) For each included service found; discovery of the characteristics
	 * 5) When everything above have been discovered, the callback is called
	 */

	CHECKIF(conn == NULL) {
		BT_DBG("NULL conn");
		return -EINVAL;
	}

	vcs_inst = &vcs_insts[bt_conn_index(conn)];

	if (vcs_inst->cli.busy) {
		return -EBUSY;
	}

	if (!initialized) {
		bt_vcs_client_init();
		initialized = true;
	}

	vcs_client_reset(conn);

	memcpy(&vcs_inst->cli.uuid, BT_UUID_VCS, sizeof(vcs_inst->cli.uuid));

	vcs_inst->client_instance = true;
	vcs_inst->cli.conn = conn;
	vcs_inst->cli.discover_params.func = primary_discover_func;
	vcs_inst->cli.discover_params.uuid = &vcs_inst->cli.uuid.uuid;
	vcs_inst->cli.discover_params.type = BT_GATT_DISCOVER_PRIMARY;
	vcs_inst->cli.discover_params.start_handle = BT_ATT_FIRST_ATTTRIBUTE_HANDLE;
	vcs_inst->cli.discover_params.end_handle = BT_ATT_LAST_ATTTRIBUTE_HANDLE;

	err = bt_gatt_discover(conn, &vcs_inst->cli.discover_params);
	if (err == 0) {
		*vcs = vcs_inst;
	}
	return err;
}

int bt_vcs_client_cb_register(struct bt_vcs_cb *cb)
{
	int i, j;

	if (IS_ENABLED(CONFIG_BT_VOCS_CLIENT)) {
		struct bt_vocs_cb *vocs_cb = NULL;

		if (cb != NULL) {
			CHECKIF(cb->vocs_cb.discover) {
				BT_ERR("VOCS discover callback shall not be set");
				return -EINVAL;
			}
			cb->vocs_cb.discover = vocs_discover_cb;

			vocs_cb = &cb->vocs_cb;
		}

		for (i = 0; i < ARRAY_SIZE(vcs_insts); i++) {
			for (j = 0; j < ARRAY_SIZE(vcs_insts[i].cli.vocs); j++) {
				if (vcs_insts[i].cli.vocs[j]) {
					bt_vocs_client_cb_register(vcs_insts[i].cli.vocs[j],
								   vocs_cb);
				}
			}
		}
	}

	if (IS_ENABLED(CONFIG_BT_AICS_CLIENT)) {
		struct bt_aics_cb *aics_cb = NULL;

		if (cb != NULL) {
			CHECKIF(cb->aics_cb.discover) {
				BT_ERR("AICS discover callback shall not be set");
				return -EINVAL;
			}
			cb->aics_cb.discover = aics_discover_cb;

			aics_cb = &cb->aics_cb;
		}

		for (i = 0; i < ARRAY_SIZE(vcs_insts); i++) {
			for (j = 0; j < ARRAY_SIZE(vcs_insts[i].cli.aics); j++) {
				if (vcs_insts[i].cli.aics[j]) {
					bt_aics_client_cb_register(vcs_insts[i].cli.aics[j],
								   aics_cb);
				}
			}
		}
	}

	vcs_client_cb = cb;

	return 0;
}

int bt_vcs_client_included_get(struct bt_vcs *vcs,
			       struct bt_vcs_included *included)
{
	CHECKIF(!included || vcs == NULL) {
		return -EINVAL;
	}

	included->vocs_cnt = vcs->cli.vocs_inst_cnt;
	included->vocs = vcs->cli.vocs;

	included->aics_cnt = vcs->cli.aics_inst_cnt;
	included->aics = vcs->cli.aics;

	return 0;
}

int bt_vcs_client_conn_get(const struct bt_vcs *vcs, struct bt_conn **conn)
{
	CHECKIF(vcs == NULL) {
		BT_DBG("NULL vcs pointer");
		return -EINVAL;
	}

	if (!vcs->client_instance) {
		BT_DBG("vcs pointer shall be client instance");
		return -EINVAL;
	}

	if (vcs->cli.conn == NULL) {
		BT_DBG("vcs pointer not associated with a connection. "
		       "Do discovery first");
		return -ENOTCONN;
	}

	*conn = vcs->cli.conn;
	return 0;
}

int bt_vcs_client_read_vol_state(struct bt_vcs *vcs)
{
	int err;

	CHECKIF(vcs->cli.conn == NULL) {
		BT_DBG("NULL conn");
		return -EINVAL;
	}

	if (vcs->cli.state_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	} else if (vcs->cli.busy) {
		return -EBUSY;
	}

	vcs->cli.read_params.func = vcs_client_read_vol_state_cb;
	vcs->cli.read_params.handle_count = 1;
	vcs->cli.read_params.single.handle = vcs->cli.state_handle;
	vcs->cli.read_params.single.offset = 0U;

	err = bt_gatt_read(vcs->cli.conn, &vcs->cli.read_params);
	if (err == 0) {
		vcs->cli.busy = true;
	}

	return err;
}

int bt_vcs_client_read_flags(struct bt_vcs *vcs)
{
	int err;

	CHECKIF(vcs->cli.conn == NULL) {
		BT_DBG("NULL conn");
		return -EINVAL;
	}

	if (vcs->cli.flag_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	} else if (vcs->cli.busy) {
		return -EBUSY;
	}

	vcs->cli.read_params.func = vcs_client_read_flag_cb;
	vcs->cli.read_params.handle_count = 1;
	vcs->cli.read_params.single.handle = vcs->cli.flag_handle;
	vcs->cli.read_params.single.offset = 0U;

	err = bt_gatt_read(vcs->cli.conn, &vcs->cli.read_params);
	if (err == 0) {
		vcs->cli.busy = true;
	}

	return err;
}

int bt_vcs_client_vol_down(struct bt_vcs *vcs)
{
	return vcs_client_common_vcs_cp(vcs, BT_VCS_OPCODE_REL_VOL_DOWN);
}

int bt_vcs_client_vol_up(struct bt_vcs *vcs)
{
	return vcs_client_common_vcs_cp(vcs, BT_VCS_OPCODE_REL_VOL_UP);
}

int bt_vcs_client_unmute_vol_down(struct bt_vcs *vcs)
{
	return vcs_client_common_vcs_cp(vcs, BT_VCS_OPCODE_UNMUTE_REL_VOL_DOWN);
}

int bt_vcs_client_unmute_vol_up(struct bt_vcs *vcs)
{
	return vcs_client_common_vcs_cp(vcs, BT_VCS_OPCODE_UNMUTE_REL_VOL_UP);
}

int bt_vcs_client_set_volume(struct bt_vcs *vcs, uint8_t volume)
{
	int err;

	CHECKIF(vcs->cli.conn == NULL) {
		BT_DBG("NULL conn");
		return -EINVAL;
	}

	if (vcs->cli.control_handle == 0) {
		BT_DBG("Handle not set");
		return -EINVAL;
	} else if (vcs->cli.busy) {
		return -EBUSY;
	}

	vcs->cli.cp_val.cp.opcode = BT_VCS_OPCODE_SET_ABS_VOL;
	vcs->cli.cp_val.cp.counter = vcs->cli.state.change_counter;
	vcs->cli.cp_val.volume = volume;

	vcs->cli.busy = true;
	vcs->cli.write_params.offset = 0;
	vcs->cli.write_params.data = &vcs->cli.cp_val;
	vcs->cli.write_params.length = sizeof(vcs->cli.cp_val);
	vcs->cli.write_params.handle = vcs->cli.control_handle;
	vcs->cli.write_params.func = vcs_client_write_vcs_cp_cb;

	err = bt_gatt_write(vcs->cli.conn, &vcs->cli.write_params);
	if (err == 0) {
		vcs->cli.busy = true;
	}

	return err;
}

int bt_vcs_client_unmute(struct bt_vcs *vcs)
{
	return vcs_client_common_vcs_cp(vcs, BT_VCS_OPCODE_UNMUTE);
}

int bt_vcs_client_mute(struct bt_vcs *vcs)
{
	return vcs_client_common_vcs_cp(vcs, BT_VCS_OPCODE_MUTE);
}
