/*
 *
 *  MCAP for BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#include <netinet/in.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>

#include <glib.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/l2cap.h>

#include <btio.h>
#include <log.h>
#include <error.h>

#include "mcap.h"
#include "mcap_lib.h"
#include "mcap_internal.h"

#define RESPONSE_TIMER	6	/* seconds */
#define MAX_CACHED	10	/* 10 devices */

#define MCAP_ERROR g_quark_from_static_string("mcap-error-quark")

#define RELEASE_TIMER(__mcl) do {		\
	if (__mcl->tid) {			\
		g_source_remove(__mcl->tid);	\
		__mcl->tid = 0;			\
	}					\
} while(0)

struct connect_mcl {
	struct mcap_mcl		*mcl;		/* MCL for this operation */
	mcap_mcl_connect_cb	connect_cb;	/* Connect callback */
	GDestroyNotify		destroy;	/* Destroy callback */
	gpointer		user_data;	/* Callback user data */
};

typedef union {
	mcap_mdl_operation_cb		op;
	mcap_mdl_operation_conf_cb	op_conf;
	mcap_mdl_notify_cb		notify;
} mcap_cb_type;

struct mcap_mdl_op_cb {
	struct mcap_mdl		*mdl;		/* MDL for this operation */
	mcap_cb_type		cb;		/* Operation callback */
	GDestroyNotify		destroy;	/* Destroy callback */
	gpointer		user_data;	/* Callback user data */
};

/* MCAP finite state machine functions */
static void proc_req_connected(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t l);
static void proc_req_pending(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t l);
static void proc_req_active(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t l);

static void (*proc_req[])(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len) = {
	proc_req_connected,
	proc_req_pending,
	proc_req_active
};

static void mcap_cache_mcl(struct mcap_mcl *mcl);

static void default_mdl_connected_cb(struct mcap_mdl *mdl, gpointer data)
{
	DBG("MCAP Unmanaged mdl connection");
}

static void default_mdl_closed_cb(struct mcap_mdl *mdl, gpointer data)
{
	DBG("MCAP Unmanaged mdl closed");
}

static void default_mdl_deleted_cb(struct mcap_mdl *mdl, gpointer data)
{
	DBG("MCAP Unmanaged mdl deleted");
}

static void default_mdl_aborted_cb(struct mcap_mdl *mdl, gpointer data)
{
	DBG("MCAP Unmanaged mdl aborted");
}

static uint8_t default_mdl_conn_req_cb(struct mcap_mcl *mcl,
						uint8_t mdepid, uint16_t mdlid,
						uint8_t *conf, gpointer data)
{
	DBG("MCAP mdl remote connection aborted");
	/* Due to this callback isn't managed this request won't be supported */
	return MCAP_REQUEST_NOT_SUPPORTED;
}

static uint8_t default_mdl_reconn_req_cb(struct mcap_mdl *mdl,
						gpointer data)
{
	DBG("MCAP mdl remote reconnection aborted");
	/* Due to this callback isn't managed this request won't be supported */
	return MCAP_REQUEST_NOT_SUPPORTED;
}

static void set_default_cb(struct mcap_mcl *mcl)
{
	if (!mcl->cb)
		mcl->cb = g_new0(struct mcap_mdl_cb, 1);

	mcl->cb->mdl_connected = default_mdl_connected_cb;
	mcl->cb->mdl_closed = default_mdl_closed_cb;
	mcl->cb->mdl_deleted = default_mdl_deleted_cb;
	mcl->cb->mdl_aborted = default_mdl_aborted_cb;
	mcl->cb->mdl_conn_req = default_mdl_conn_req_cb;
	mcl->cb->mdl_reconn_req = default_mdl_reconn_req_cb;
}

static char *error2str(uint8_t rc)
{
	switch (rc) {
	case MCAP_SUCCESS:
		return "Success";
	case MCAP_INVALID_OP_CODE:
		return "Invalid Op Code";
	case MCAP_INVALID_PARAM_VALUE:
		return "Invalid Parameter Value";
	case MCAP_INVALID_MDEP:
		return "Invalid MDEP";
	case MCAP_MDEP_BUSY:
		return "MDEP Busy";
	case MCAP_INVALID_MDL:
		return "Invalid MDL";
	case MCAP_MDL_BUSY:
		return "MDL Busy";
	case MCAP_INVALID_OPERATION:
		return "Invalid Operation";
	case MCAP_RESOURCE_UNAVAILABLE:
		return "Resource Unavailable";
	case MCAP_UNSPECIFIED_ERROR:
		return "Unspecified Error";
	case MCAP_REQUEST_NOT_SUPPORTED:
		return "Request Not Supported";
	case MCAP_CONFIGURATION_REJECTED:
		return "Configuration Rejected";
	default:
		return "Unknown Response Code";
	}
}

static gboolean mcap_send_std_opcode(struct mcap_mcl *mcl, void *cmd,
						uint32_t size, GError **err)
{
	if (mcl->state == MCL_IDLE) {
		g_set_error(err, MCAP_ERROR, MCAP_ERROR_FAILED,
							"MCL is not connected");
		return FALSE;
	}

	if (mcl->req != MCL_AVAILABLE) {
		g_set_error(err, MCAP_ERROR, MCAP_ERROR_RESOURCE_UNAVAILABLE,
							"Pending request");
		return FALSE;
	}

	if (!(mcl->ctrl & MCAP_CTRL_STD_OP)) {
		g_set_error(err, MCAP_ERROR, MCAP_ERROR_REQUEST_NOT_SUPPORTED,
				"Remote does not support standard opcodes");
		return FALSE;
	}

	if (mcl->state == MCL_PENDING) {
		g_set_error(err, MCAP_ERROR, MCAP_ERROR_INVALID_OPERATION,
			"Not Std Op. Codes can be sent in PENDING State");
		return FALSE;
	}

	if (mcap_send_data(g_io_channel_unix_get_fd(mcl->cc), cmd, size) < 0) {
		g_set_error(err, MCAP_ERROR, MCAP_ERROR_FAILED,
					"Command can't be sent, write error");
		return FALSE;
	}

	mcl->lcmd = cmd;
	mcl->req = MCL_WAITING_RSP;

	return TRUE;
}

static void update_mcl_state(struct mcap_mcl *mcl)
{
	GSList *l;
	struct mcap_mdl *mdl;

	if (mcl->state == MCL_PENDING)
		return;

	for (l = mcl->mdls; l; l = l->next) {
		mdl = l->data;

		if (mdl->state == MDL_CONNECTED) {
			mcl->state = MCL_ACTIVE;
			return;
		}
	}

	mcl->state = MCL_CONNECTED;
}

static void shutdown_mdl(struct mcap_mdl *mdl)
{
	mdl->state = MDL_CLOSED;

	if (mdl->wid) {
		g_source_remove(mdl->wid);
		mdl->wid = 0;
	}

	if (mdl->dc) {
		g_io_channel_shutdown(mdl->dc, TRUE, NULL);
		g_io_channel_unref(mdl->dc);
		mdl->dc = NULL;
	}
}

static void free_mdl(struct mcap_mdl *mdl)
{
	if (!mdl)
		return;

	mcap_mcl_unref(mdl->mcl);
	g_free(mdl);
}

static gint cmp_mdl_state(gconstpointer a, gconstpointer b)
{
	const struct mcap_mdl *mdl = a;
	const MDLState *st = b;

	if (mdl->state == *st)
		return 0;
	else if (mdl->state < *st)
		return -1;
	else
		return 1;
}

static void free_mcap_mdl_op(struct mcap_mdl_op_cb *op)
{
	if (op->destroy)
		op->destroy(op->user_data);

	if (op->mdl)
		mcap_mdl_unref(op->mdl);

	g_free(op);
}

static void free_mcl_priv_data(struct mcap_mcl *mcl)
{
	free_mcap_mdl_op(mcl->priv_data);
	mcl->priv_data = NULL;
}

static void mcap_notify_error(struct mcap_mcl *mcl, GError *err)
{
	struct mcap_mdl_op_cb *con = mcl->priv_data;
	struct mcap_mdl *mdl;
	MDLState st;
	GSList *l;

	if (!con || !mcl->lcmd)
		return;

	switch (mcl->lcmd[0]) {
	case MCAP_MD_CREATE_MDL_REQ:
		st = MDL_WAITING;
		l = g_slist_find_custom(mcl->mdls, &st, cmp_mdl_state);
		mdl = l->data;
		mcl->mdls = g_slist_remove(mcl->mdls, mdl);
		mcap_mdl_unref(mdl);
		update_mcl_state(mcl);
		con->cb.op_conf(NULL, 0, err, con->user_data);
		break;
	case MCAP_MD_ABORT_MDL_REQ:
		st = MDL_WAITING;
		l = g_slist_find_custom(mcl->mdls, &st, cmp_mdl_state);
		shutdown_mdl(l->data);
		update_mcl_state(mcl);
		con->cb.notify(err, con->user_data);
		break;
	case MCAP_MD_DELETE_MDL_REQ:
		for (l = mcl->mdls; l; l = l->next) {
			mdl = l->data;
			if (mdl->state == MDL_DELETING)
				mdl->state = (mdl->dc) ? MDL_CONNECTED :
								MDL_CLOSED;
		}
		update_mcl_state(mcl);
		con->cb.notify(err, con->user_data);
		break;
	case MCAP_MD_RECONNECT_MDL_REQ:
		st = MDL_WAITING;
		l = g_slist_find_custom(mcl->mdls, &st, cmp_mdl_state);
		shutdown_mdl(l->data);
		update_mcl_state(mcl);
		con->cb.op(NULL, err, con->user_data);
		break;
	}

	free_mcl_priv_data(mcl);
	g_free(mcl->lcmd);
	mcl->lcmd = NULL;
}

int mcap_send_data(int sock, const void *buf, uint32_t size)
{
	const uint8_t *buf_b = buf;
	uint32_t sent = 0;

	while (sent < size) {
		int n = write(sock, buf_b + sent, size - sent);
		if (n < 0)
			return -1;
		sent += n;
	}

	return 0;
}

static int mcap_send_cmd(struct mcap_mcl *mcl, uint8_t oc, uint8_t rc,
					uint16_t mdl, uint8_t *data, size_t len)
{
	mcap_rsp *cmd;
	int sock, sent;

	if (mcl->cc == NULL)
		return -1;

	sock = g_io_channel_unix_get_fd(mcl->cc);

	cmd = g_malloc(sizeof(mcap_rsp) + len);
	cmd->op = oc;
	cmd->rc = rc;
	cmd->mdl = htons(mdl);

	if (data && len > 0)
		memcpy(cmd->data, data, len);

	sent = mcap_send_data(sock, cmd, sizeof(mcap_rsp) + len);
	g_free(cmd);

	return sent;
}

static struct mcap_mdl *get_mdl(struct mcap_mcl *mcl, uint16_t mdlid)
{
	GSList *l;
	struct mcap_mdl *mdl;

	for (l = mcl->mdls; l; l = l->next) {
		mdl = l->data;
		if (mdlid == mdl->mdlid)
			return mdl;
	}

	return NULL;
}

static uint16_t generate_mdlid(struct mcap_mcl *mcl)
{
	uint16_t mdlid = mcl->next_mdl;
	struct mcap_mdl *mdl;

	do {
		mdl = get_mdl(mcl, mdlid);
		if (!mdl) {
			mcl->next_mdl = (mdlid % MCAP_MDLID_FINAL) + 1;
			return mdlid;
		} else
			mdlid = (mdlid % MCAP_MDLID_FINAL) + 1;
	} while (mdlid != mcl->next_mdl);

	/* No more mdlids availables */
	return 0;
}

static mcap_md_req *create_req(uint8_t op, uint16_t mdl_id)
{
	mcap_md_req *req_cmd;

	req_cmd = g_new0(mcap_md_req, 1);

	req_cmd->op = op;
	req_cmd->mdl = htons(mdl_id);

	return req_cmd;
}

static mcap_md_create_mdl_req *create_mdl_req(uint16_t mdl_id, uint8_t mdep,
								uint8_t conf)
{
	mcap_md_create_mdl_req *req_mdl;

	req_mdl = g_new0(mcap_md_create_mdl_req, 1);

	req_mdl->op = MCAP_MD_CREATE_MDL_REQ;
	req_mdl->mdl = htons(mdl_id);
	req_mdl->mdep = mdep;
	req_mdl->conf = conf;

	return req_mdl;
}

static gint compare_mdl(gconstpointer a, gconstpointer b)
{
	const struct mcap_mdl *mdla = a;
	const struct mcap_mdl *mdlb = b;

	if (mdla->mdlid == mdlb->mdlid)
		return 0;
	else if (mdla->mdlid < mdlb->mdlid)
		return -1;
	else
		return 1;
}

static gboolean wait_response_timer(gpointer data)
{
	struct mcap_mcl *mcl = data;

	GError *gerr = NULL;

	RELEASE_TIMER(mcl);

	g_set_error(&gerr, MCAP_ERROR, MCAP_ERROR_FAILED,
					"Timeout waiting response");

	mcap_notify_error(mcl, gerr);

	g_error_free(gerr);
	mcl->mi->mcl_disconnected_cb(mcl, mcl->mi->user_data);
	mcap_cache_mcl(mcl);

	return FALSE;
}

gboolean mcap_create_mdl(struct mcap_mcl *mcl,
				uint8_t mdepid,
				uint8_t conf,
				mcap_mdl_operation_conf_cb connect_cb,
				gpointer user_data,
				GDestroyNotify destroy,
				GError **err)
{
	struct mcap_mdl *mdl;
	struct mcap_mdl_op_cb *con;
	mcap_md_create_mdl_req *cmd;
	uint16_t id;

	id = generate_mdlid(mcl);
	if (!id) {
		g_set_error(err, MCAP_ERROR, MCAP_ERROR_FAILED,
					"Not more mdlids available");
		return FALSE;
	}

	mdl = g_new0(struct mcap_mdl, 1);
	mdl->mcl = mcap_mcl_ref(mcl);
	mdl->mdlid = id;
	mdl->mdep_id = mdepid;
	mdl->state = MDL_WAITING;

	con = g_new0(struct mcap_mdl_op_cb, 1);
	con->mdl = mcap_mdl_ref(mdl);
	con->cb.op_conf = connect_cb;
	con->destroy = destroy;
	con->user_data = user_data;

	cmd = create_mdl_req(id, mdepid, conf);
	if (!mcap_send_std_opcode(mcl, cmd, sizeof(mcap_md_create_mdl_req),
									err)) {
		mcap_mdl_unref(con->mdl);
		g_free(con);
		g_free(cmd);
		return FALSE;
	}

	mcl->state = MCL_ACTIVE;
	mcl->priv_data = con;

	mcl->mdls = g_slist_insert_sorted(mcl->mdls, mcap_mdl_ref(mdl),
								compare_mdl);
	mcl->tid = g_timeout_add_seconds(RESPONSE_TIMER, wait_response_timer,
									mcl);
	return TRUE;
}

gboolean mcap_reconnect_mdl(struct mcap_mdl *mdl,
				mcap_mdl_operation_cb reconnect_cb,
				gpointer user_data,
				GDestroyNotify destroy,
				GError **err)
{
	struct mcap_mdl_op_cb *con;
	struct mcap_mcl *mcl = mdl->mcl;
	mcap_md_req *cmd;

	if (mdl->state != MDL_CLOSED) {
		g_set_error(err, MCAP_ERROR, MCAP_ERROR_FAILED,
					"MDL is not closed");
		return FALSE;
	}

	cmd = create_req(MCAP_MD_RECONNECT_MDL_REQ, mdl->mdlid);
	if (!mcap_send_std_opcode(mcl, cmd, sizeof(mcap_md_req), err)) {
		g_free(cmd);
		return FALSE;
	}

	mdl->state = MDL_WAITING;

	con = g_new0(struct mcap_mdl_op_cb, 1);
	con->mdl = mcap_mdl_ref(mdl);
	con->cb.op = reconnect_cb;
	con->destroy = destroy;
	con->user_data = user_data;

	mcl->state = MCL_ACTIVE;
	mcl->priv_data = con;

	mcl->tid = g_timeout_add_seconds(RESPONSE_TIMER, wait_response_timer,
									mcl);
	return TRUE;
}

static gboolean send_delete_req(struct mcap_mcl *mcl,
						struct mcap_mdl_op_cb *con,
						uint16_t mdlid,
						GError **err)
{
	mcap_md_req *cmd;

	cmd = create_req(MCAP_MD_DELETE_MDL_REQ, mdlid);
	if (!mcap_send_std_opcode(mcl, cmd, sizeof(mcap_md_req), err)) {
		g_free(cmd);
		return FALSE;
	}

	mcl->priv_data = con;

	mcl->tid = g_timeout_add_seconds(RESPONSE_TIMER, wait_response_timer,
									mcl);
	return TRUE;
}

gboolean mcap_delete_all_mdls(struct mcap_mcl *mcl,
					mcap_mdl_notify_cb delete_cb,
					gpointer user_data,
					GDestroyNotify destroy,
					GError **err)
{
	GSList *l;
	struct mcap_mdl *mdl;
	struct mcap_mdl_op_cb *con;

	DBG("MCL in state: %d", mcl->state);
	if (!mcl->mdls) {
		g_set_error(err, MCAP_ERROR, MCAP_ERROR_FAILED,
				"There are not MDLs created");
		return FALSE;
	}

	for (l = mcl->mdls; l; l = l->next) {
		mdl = l->data;
		if (mdl->state != MDL_WAITING)
			mdl->state = MDL_DELETING;
	}

	con = g_new0(struct mcap_mdl_op_cb, 1);
	con->mdl = NULL;
	con->cb.notify = delete_cb;
	con->destroy = destroy;
	con->user_data = user_data;


	if (!send_delete_req(mcl, con, MCAP_ALL_MDLIDS, err)) {
		g_free(con);
		return FALSE;
	}

	return TRUE;
}

gboolean mcap_delete_mdl(struct mcap_mdl *mdl, mcap_mdl_notify_cb delete_cb,
							gpointer user_data,
							GDestroyNotify destroy,
							GError **err)
{
	struct mcap_mcl *mcl= mdl->mcl;
	struct mcap_mdl_op_cb *con;
	GSList *l;

	l = g_slist_find(mcl->mdls, mdl);

	if (!l) {
		g_set_error(err, MCAP_ERROR, MCAP_ERROR_INVALID_MDL,
					"%s" , error2str(MCAP_INVALID_MDEP));
		return FALSE;
	}

	if (mdl->state == MDL_WAITING) {
		g_set_error(err, MCAP_ERROR, MCAP_ERROR_FAILED,
							"Mdl is not created");
		return FALSE;
	}

	mdl->state = MDL_DELETING;

	con = g_new0(struct mcap_mdl_op_cb, 1);
	con->mdl = mcap_mdl_ref(mdl);
	con->cb.notify = delete_cb;
	con->destroy = destroy;
	con->user_data = user_data;

	if (!send_delete_req(mcl, con, mdl->mdlid, err)) {
		mcap_mdl_unref(con->mdl);
		g_free(con);
		return FALSE;
	}

	return TRUE;
}

gboolean mcap_mdl_abort(struct mcap_mdl *mdl, mcap_mdl_notify_cb abort_cb,
							gpointer user_data,
							GDestroyNotify destroy,
							GError **err)
{
	struct mcap_mdl_op_cb *con;
	struct mcap_mcl *mcl = mdl->mcl;
	mcap_md_req *cmd;

	if (mdl->state != MDL_WAITING) {
		g_set_error(err, MCAP_ERROR, MCAP_ERROR_FAILED,
							"Mdl in invalid state");
		return FALSE;
	}

	cmd = create_req(MCAP_MD_ABORT_MDL_REQ, mdl->mdlid);
	if (!mcap_send_std_opcode(mcl, cmd, sizeof(mcap_md_req), err)) {
		g_free(cmd);
		return FALSE;
	}

	con = g_new0(struct mcap_mdl_op_cb, 1);
	con->mdl = mcap_mdl_ref(mdl);
	con->cb.notify = abort_cb;
	con->destroy = destroy;
	con->user_data = user_data;

	mcl->priv_data = con;
	mcl->tid = g_timeout_add_seconds(RESPONSE_TIMER, wait_response_timer,
									mcl);
	return TRUE;
}

static struct mcap_mcl *find_mcl(GSList *list, const bdaddr_t *addr)
{
	struct mcap_mcl *mcl;

	for (; list; list = list->next) {
		mcl = list->data;

		if (!bacmp(&mcl->addr, addr))
			return mcl;
	}

	return NULL;
}

int mcap_mdl_get_fd(struct mcap_mdl *mdl)
{
	if (!mdl || mdl->state != MDL_CONNECTED)
		return -ENOTCONN;

	return g_io_channel_unix_get_fd(mdl->dc);
}

uint16_t mcap_mdl_get_mdlid(struct mcap_mdl *mdl)
{
	if (!mdl)
		return MCAP_MDLID_RESERVED;

	return mdl->mdlid;
}

static void close_mcl(struct mcap_mcl *mcl, gboolean cache_requested)
{
	gboolean save = ((!(mcl->ctrl & MCAP_CTRL_FREE)) && cache_requested);

	RELEASE_TIMER(mcl);

	if (mcl->cc) {
		g_io_channel_shutdown(mcl->cc, TRUE, NULL);
		g_io_channel_unref(mcl->cc);
		mcl->cc = NULL;
	}

	if (mcl->wid) {
		g_source_remove(mcl->wid);
		mcl->wid = 0;
	}

	if (mcl->lcmd) {
		g_free(mcl->lcmd);
		mcl->lcmd = NULL;
	}

	if (mcl->priv_data)
		free_mcl_priv_data(mcl);

	g_slist_foreach(mcl->mdls, (GFunc) shutdown_mdl, NULL);

	mcap_sync_stop(mcl);

	mcl->state = MCL_IDLE;

	if (save)
		return;

	g_slist_foreach(mcl->mdls, (GFunc) mcap_mdl_unref, NULL);
	g_slist_free(mcl->mdls);
	mcl->mdls = NULL;
}

static void mcap_mcl_shutdown(struct mcap_mcl *mcl)
{
	close_mcl(mcl, TRUE);
}

static void mcap_mcl_release(struct mcap_mcl *mcl)
{
	close_mcl(mcl, FALSE);
}

static void mcap_cache_mcl(struct mcap_mcl *mcl)
{
	GSList *l;
	struct mcap_mcl *last;
	int len;

	if (mcl->ctrl & MCAP_CTRL_CACHED)
		return;

	mcl->mi->mcls = g_slist_remove(mcl->mi->mcls, mcl);

	if (mcl->ctrl & MCAP_CTRL_NOCACHE) {
		mcl->mi->cached = g_slist_remove(mcl->mi->cached, mcl);
		mcap_mcl_release(mcl);
		mcap_mcl_unref(mcl);
		return;
	}

	DBG("Caching MCL");

	len = g_slist_length(mcl->mi->cached);
	if (len == MAX_CACHED) {
		/* Remove the latest cached mcl */
		l = g_slist_last(mcl->mi->cached);
		last = l->data;
		mcl->mi->cached = g_slist_remove(mcl->mi->cached, last);
		last->ctrl &= ~MCAP_CTRL_CACHED;
		if (last->ctrl & MCAP_CTRL_CONN) {
			/* We have to release this MCL if */
			/* connection is not successful    */
			last->ctrl |= MCAP_CTRL_FREE;
		} else {
			mcap_mcl_release(last);
			last->mi->mcl_uncached_cb(last, last->mi->user_data);
		}
		mcap_mcl_unref(last);
	}

	mcl->mi->cached = g_slist_prepend(mcl->mi->cached, mcl);
	mcl->ctrl |= MCAP_CTRL_CACHED;
	mcap_mcl_shutdown(mcl);
}

static void mcap_uncache_mcl(struct mcap_mcl *mcl)
{
	if (!(mcl->ctrl & MCAP_CTRL_CACHED))
		return;

	DBG("Got MCL from cache");

	mcl->mi->cached = g_slist_remove(mcl->mi->cached, mcl);
	mcl->mi->mcls = g_slist_prepend(mcl->mi->mcls, mcl);
	mcl->ctrl &= ~MCAP_CTRL_CACHED;
	mcl->ctrl &= ~MCAP_CTRL_FREE;
}

void mcap_close_mcl(struct mcap_mcl *mcl, gboolean cache)
{
	if (!mcl)
		return;

	if (mcl->ctrl & MCAP_CTRL_FREE) {
		mcap_mcl_release(mcl);
		return;
	}

	if (!cache)
		mcl->ctrl |= MCAP_CTRL_NOCACHE;

	if (mcl->cc) {
		g_io_channel_shutdown(mcl->cc, TRUE, NULL);
		g_io_channel_unref(mcl->cc);
		mcl->cc = NULL;
		mcl->state = MCL_IDLE;
	} else if ((mcl->ctrl & MCAP_CTRL_CACHED) &&
					(mcl->ctrl & MCAP_CTRL_NOCACHE)) {
		mcl->ctrl &= ~MCAP_CTRL_CACHED;
		mcl->mi->cached = g_slist_remove(mcl->mi->cached, mcl);
		mcap_mcl_release(mcl);
		mcap_mcl_unref(mcl);
	}
}

struct mcap_mcl *mcap_mcl_ref(struct mcap_mcl *mcl)
{
	mcl->ref++;

	DBG("mcap_mcl_ref(%p): ref=%d", mcl, mcl->ref);

	return mcl;
}

void mcap_mcl_unref(struct mcap_mcl *mcl)
{
	mcl->ref--;

	DBG("mcap_mcl_unref(%p): ref=%d", mcl, mcl->ref);

	if (mcl->ref > 0)
		return;

	mcap_mcl_release(mcl);
	mcap_instance_unref(mcl->mi);
	g_free(mcl->cb);
	g_free(mcl);
}

static gboolean parse_set_opts(struct mcap_mdl_cb *mdl_cb, GError **err,
						McapMclCb cb1, va_list args)
{
	McapMclCb cb = cb1;
	struct mcap_mdl_cb *c;

	c = g_new0(struct mcap_mdl_cb, 1);

	while (cb != MCAP_MDL_CB_INVALID) {
		switch (cb) {
		case MCAP_MDL_CB_CONNECTED:
			c->mdl_connected = va_arg(args, mcap_mdl_event_cb);
			break;
		case MCAP_MDL_CB_CLOSED:
			c->mdl_closed = va_arg(args, mcap_mdl_event_cb);
			break;
		case MCAP_MDL_CB_DELETED:
			c->mdl_deleted = va_arg(args, mcap_mdl_event_cb);
			break;
		case MCAP_MDL_CB_ABORTED:
			c->mdl_aborted = va_arg(args, mcap_mdl_event_cb);
			break;
		case MCAP_MDL_CB_REMOTE_CONN_REQ:
			c->mdl_conn_req = va_arg(args,
						mcap_remote_mdl_conn_req_cb);
			break;
		case MCAP_MDL_CB_REMOTE_RECONN_REQ:
			c->mdl_reconn_req = va_arg(args,
						mcap_remote_mdl_reconn_req_cb);
			break;
		default:
			g_set_error(err, MCAP_ERROR, MCAP_ERROR_INVALID_ARGS,
						"Unknown option %d", cb);
			return FALSE;
		}
		cb = va_arg(args, int);
	}

	/* Set new callbacks */
	if (c->mdl_connected)
		mdl_cb->mdl_connected = c->mdl_connected;
	if (c->mdl_closed)
		mdl_cb->mdl_closed = c->mdl_closed;
	if (c->mdl_deleted)
		mdl_cb->mdl_deleted = c->mdl_deleted;
	if (c->mdl_aborted)
		mdl_cb->mdl_aborted = c->mdl_aborted;
	if (c->mdl_conn_req)
		mdl_cb->mdl_conn_req = c->mdl_conn_req;
	if (c->mdl_reconn_req)
		mdl_cb->mdl_reconn_req = c->mdl_reconn_req;

	g_free(c);

	return TRUE;
}

gboolean mcap_mcl_set_cb(struct mcap_mcl *mcl, gpointer user_data,
					GError **gerr, McapMclCb cb1, ...)
{
	va_list args;
	gboolean ret;

	va_start(args, cb1);
	ret = parse_set_opts(mcl->cb, gerr, cb1, args);
	va_end(args);

	if (!ret)
		return FALSE;

	mcl->cb->user_data = user_data;
	return TRUE;
}

void mcap_mcl_get_addr(struct mcap_mcl *mcl, bdaddr_t *addr)
{
	bacpy(addr, &mcl->addr);
}

static void mcap_del_mdl(gpointer elem, gpointer user_data)
{
	struct mcap_mdl *mdl = elem;
	gboolean notify = *(gboolean *) user_data;

	shutdown_mdl(mdl);
	if (notify)
		mdl->mcl->cb->mdl_deleted(mdl, mdl->mcl->cb->user_data);

	mcap_mdl_unref(mdl);
}

static gboolean check_cmd_req_length(struct mcap_mcl *mcl, void *cmd,
				uint32_t rlen, uint32_t explen, uint8_t rspcod)
{
	mcap_md_req *req;
	uint16_t mdl_id;

	if (rlen != explen) {
		if (rlen >= sizeof(mcap_md_req)) {
			req = cmd;
			mdl_id = ntohs(req->mdl);
		} else {
			/* We can't get mdlid */
			mdl_id = MCAP_MDLID_RESERVED;
		}
		mcap_send_cmd(mcl, rspcod, MCAP_INVALID_PARAM_VALUE, mdl_id,
								NULL, 0);
		return FALSE;
	}
	return TRUE;
}

static void process_md_create_mdl_req(struct mcap_mcl *mcl, void *cmd,
								uint32_t len)
{
	mcap_md_create_mdl_req *req;
	struct mcap_mdl *mdl;
	uint16_t mdl_id;
	uint8_t mdep_id;
	uint8_t cfga, conf;
	uint8_t rsp;

	if (!check_cmd_req_length(mcl, cmd, len, sizeof(mcap_md_create_mdl_req),
							MCAP_MD_CREATE_MDL_RSP))
		return;

	req = cmd;
	mdl_id = ntohs(req->mdl);
	if (mdl_id < MCAP_MDLID_INITIAL || mdl_id > MCAP_MDLID_FINAL) {
		mcap_send_cmd(mcl, MCAP_MD_CREATE_MDL_RSP, MCAP_INVALID_MDL,
							mdl_id, NULL, 0);
		return;
	}

	mdep_id = req->mdep;
	if (mdep_id > MCAP_MDEPID_FINAL) {
		mcap_send_cmd(mcl, MCAP_MD_CREATE_MDL_RSP, MCAP_INVALID_MDEP,
							mdl_id, NULL, 0);
		return;
	}

	mdl = get_mdl(mcl, mdl_id);
	if (mdl && (mdl->state == MDL_WAITING || mdl->state == MDL_DELETING )) {
		/* Creation request arrives for a MDL that is being managed
		* at current moment */
		mcap_send_cmd(mcl, MCAP_MD_CREATE_MDL_RSP, MCAP_MDL_BUSY,
							mdl_id, NULL, 0);
		return;
	}

	cfga = conf = req->conf;
	/* Callback to upper layer */
	rsp = mcl->cb->mdl_conn_req(mcl, mdep_id, mdl_id, &conf,
							mcl->cb->user_data);
	if (mcl->state == MCL_IDLE) {
		/* MCL has been closed int the callback */
		return;
	}

	if (cfga != 0 && cfga != conf) {
		/* Remote device set default configuration but upper profile */
		/* has changed it. Protocol Error: force closing the MCL by */
		/* remote device using UNSPECIFIED_ERROR response */
		mcap_send_cmd(mcl, MCAP_MD_CREATE_MDL_RSP,
				MCAP_UNSPECIFIED_ERROR, mdl_id, NULL, 0);
		return;
	}
	if (rsp != MCAP_SUCCESS) {
		mcap_send_cmd(mcl, MCAP_MD_CREATE_MDL_RSP, rsp, mdl_id,
								NULL, 0);
		return;
	}

	if (!mdl) {
		mdl = g_new0(struct mcap_mdl, 1);
		mdl->mcl = mcap_mcl_ref(mcl);
		mdl->mdlid = mdl_id;
		mcl->mdls = g_slist_insert_sorted(mcl->mdls, mcap_mdl_ref(mdl),
								compare_mdl);
	} else if (mdl->state == MDL_CONNECTED) {
		/* MCAP specification says that we should close the MCL if
		 * it is open when we receive a MD_CREATE_MDL_REQ */
		shutdown_mdl(mdl);
	}

	mdl->mdep_id = mdep_id;
	mdl->state = MDL_WAITING;

	mcl->state = MCL_PENDING;
	mcap_send_cmd(mcl, MCAP_MD_CREATE_MDL_RSP, MCAP_SUCCESS, mdl_id,
								&conf, 1);
}

static void process_md_reconnect_mdl_req(struct mcap_mcl *mcl, void *cmd,
								uint32_t len)
{
	mcap_md_req *req;
	struct mcap_mdl *mdl;
	uint16_t mdl_id;
	uint8_t rsp;

	if (!check_cmd_req_length(mcl, cmd, len, sizeof(mcap_md_req),
						MCAP_MD_RECONNECT_MDL_RSP))
		return;

	req = cmd;
	mdl_id = ntohs(req->mdl);

	mdl = get_mdl(mcl, mdl_id);
	if (!mdl) {
		mcap_send_cmd(mcl, MCAP_MD_RECONNECT_MDL_RSP, MCAP_INVALID_MDL,
							mdl_id, NULL, 0);
		return;
	} else if (mdl->state == MDL_WAITING || mdl->state == MDL_DELETING ) {
		/* Creation request arrives for a MDL that is being managed
		* at current moment */
		mcap_send_cmd(mcl, MCAP_MD_RECONNECT_MDL_RSP, MCAP_MDL_BUSY,
							mdl_id, NULL, 0);
		return;
	}

	/* Callback to upper layer */
	rsp = mcl->cb->mdl_reconn_req(mdl, mcl->cb->user_data);
	if (mcl->state == MCL_IDLE)
		return;

	if (rsp != MCAP_SUCCESS) {
		mcap_send_cmd(mcl, MCAP_MD_RECONNECT_MDL_RSP, rsp, mdl_id,
								NULL, 0);
		return;
	}

	if (mdl->state == MDL_CONNECTED)
		shutdown_mdl(mdl);

	mdl->state = MDL_WAITING;
	mcl->state = MCL_PENDING;
	mcap_send_cmd(mcl, MCAP_MD_RECONNECT_MDL_RSP, MCAP_SUCCESS, mdl_id,
								NULL, 0);
}

static void process_md_abort_mdl_req(struct mcap_mcl *mcl, void *cmd,
								uint32_t len)
{
	mcap_md_req *req;
	GSList *l;
	struct mcap_mdl *mdl, *abrt;
	uint16_t mdl_id;

	if (!check_cmd_req_length(mcl, cmd, len, sizeof(mcap_md_req),
							MCAP_MD_ABORT_MDL_RSP))
		return;

	req = cmd;
	mdl_id = ntohs(req->mdl);
	mcl->state = MCL_CONNECTED;
	abrt = NULL;
	for (l = mcl->mdls; l; l = l->next) {
		mdl = l->data;
		if (mdl_id == mdl->mdlid && mdl->state == MDL_WAITING) {
			abrt = mdl;
			if (mcl->state != MCL_CONNECTED)
				break;
			continue;
		}
		if (mdl->state == MDL_CONNECTED && mcl->state != MCL_ACTIVE)
			mcl->state = MCL_ACTIVE;

		if (abrt && mcl->state == MCL_ACTIVE)
			break;
	}

	if (!abrt) {
		mcap_send_cmd(mcl, MCAP_MD_ABORT_MDL_RSP, MCAP_INVALID_MDL,
							mdl_id, NULL, 0);
		return;
	}

	mcl->cb->mdl_aborted(abrt, mcl->cb->user_data);
	abrt->state = MDL_CLOSED;
	mcap_send_cmd(mcl, MCAP_MD_ABORT_MDL_RSP, MCAP_SUCCESS, mdl_id,
								NULL, 0);
}

static void process_md_delete_mdl_req(struct mcap_mcl *mcl, void *cmd,
								uint32_t len)
{
	mcap_md_req *req;
	struct mcap_mdl *mdl, *aux;
	uint16_t mdlid;
	gboolean notify;
	GSList *l;

	if (!check_cmd_req_length(mcl, cmd, len, sizeof(mcap_md_req),
							MCAP_MD_DELETE_MDL_RSP))
		return;

	req = cmd;
	mdlid = ntohs(req->mdl);
	if (mdlid == MCAP_ALL_MDLIDS) {
		notify = FALSE;
		g_slist_foreach(mcl->mdls, mcap_del_mdl, &notify);
		g_slist_free(mcl->mdls);
		mcl->mdls = NULL;
		mcl->state = MCL_CONNECTED;
		/* NULL mdl means ALL_MDLS */
		mcl->cb->mdl_deleted(NULL, mcl->cb->user_data);
		goto resp;
	}

	if (mdlid < MCAP_MDLID_INITIAL || mdlid > MCAP_MDLID_FINAL) {
		mcap_send_cmd(mcl, MCAP_MD_DELETE_MDL_RSP, MCAP_INVALID_MDL,
								mdlid, NULL, 0);
		return;
	}

	for (l = mcl->mdls, mdl = NULL; l; l = l->next) {
		aux = l->data;
		if (aux->mdlid == mdlid) {
			mdl = aux;
			break;
		}
	}

	if (!mdl || mdl->state == MDL_WAITING) {
		mcap_send_cmd(mcl, MCAP_MD_DELETE_MDL_RSP, MCAP_INVALID_MDL,
								mdlid, NULL, 0);
		return;
	}

	mcl->mdls = g_slist_remove(mcl->mdls, mdl);
	update_mcl_state(mcl);
	notify = TRUE;
	mcap_del_mdl(mdl, &notify);

resp:
	mcap_send_cmd(mcl, MCAP_MD_DELETE_MDL_RSP, MCAP_SUCCESS, mdlid,
								NULL, 0);
}

static void invalid_req_state(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len)
{
	uint16_t mdlr;

	error("Invalid cmd received (op code = %d) in state %d", cmd[0],
								mcl->state);
	/* Get previously mdlid sent to generate an appropriate
	 * response if it is possible */
	mdlr = len < sizeof(mcap_md_req) ? MCAP_MDLID_RESERVED :
					ntohs(((mcap_md_req *) cmd)->mdl);
	mcap_send_cmd(mcl, cmd[0]+1, MCAP_INVALID_OPERATION, mdlr, NULL, 0);
}

/* Function used to process commands depending of MCL state */
static void proc_req_connected(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len)
{
	switch (cmd[0]) {
	case MCAP_MD_CREATE_MDL_REQ:
		process_md_create_mdl_req(mcl, cmd, len);
		break;
	case MCAP_MD_RECONNECT_MDL_REQ:
		process_md_reconnect_mdl_req(mcl, cmd, len);
		break;
	case MCAP_MD_DELETE_MDL_REQ:
		process_md_delete_mdl_req(mcl, cmd, len);
		break;
	default:
		invalid_req_state(mcl, cmd, len);
	}
}

static void proc_req_pending(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len)
{
	if (cmd[0] == MCAP_MD_ABORT_MDL_REQ)
		process_md_abort_mdl_req(mcl, cmd, len);
	else
		invalid_req_state(mcl, cmd, len);
}

static void proc_req_active(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len)
{
	switch (cmd[0]) {
	case MCAP_MD_CREATE_MDL_REQ:
		process_md_create_mdl_req(mcl, cmd, len);
		break;
	case MCAP_MD_RECONNECT_MDL_REQ:
		process_md_reconnect_mdl_req(mcl, cmd, len);
		break;
	case MCAP_MD_DELETE_MDL_REQ:
		process_md_delete_mdl_req(mcl, cmd, len);
		break;
	default:
		invalid_req_state(mcl, cmd, len);
	}
}

/* Function used to process replies */
static gboolean check_err_rsp(struct mcap_mcl *mcl, mcap_rsp *rsp,
				uint32_t rlen, uint32_t len, GError **gerr)
{
	mcap_md_req *cmdlast = (mcap_md_req *) mcl->lcmd;
	gint err = MCAP_ERROR_FAILED;
	gboolean close = FALSE;
	char *msg;

	if (rsp->op == MCAP_ERROR_RSP) {
		msg = "MCAP_ERROR_RSP received";
		close = FALSE;
		goto fail;
	}

	/* Check if the response matches with the last request */
	if (rlen < sizeof(mcap_rsp) || (mcl->lcmd[0] + 1) != rsp->op) {
		msg = "Protocol error";
		close = FALSE;
		goto fail;
	}

	if (rlen < len) {
		msg = "Protocol error";
		close = FALSE;
		goto fail;
	}

	if (rsp->mdl != cmdlast->mdl) {
		msg = "MDLID received doesn't match with MDLID sent";
		close = TRUE;
		goto fail;
	}

	if (rsp->rc == MCAP_REQUEST_NOT_SUPPORTED) {
		msg = "Remote does not support opcodes";
		mcl->ctrl &= ~MCAP_CTRL_STD_OP;
		goto fail;
	}

	if (rsp->rc == MCAP_UNSPECIFIED_ERROR) {
		msg = "Unspecified error";
		close = TRUE;
		goto fail;
	}

	if (rsp->rc != MCAP_SUCCESS) {
		msg = error2str(rsp->rc);
		err = rsp->rc;
		goto fail;
	}

	return FALSE;

fail:
	g_set_error(gerr, MCAP_ERROR, err, "%s", msg);
	return close;
}

static gboolean process_md_create_mdl_rsp(struct mcap_mcl *mcl,
						mcap_rsp *rsp, uint32_t len)
{
	mcap_md_create_mdl_req *cmdlast = (mcap_md_create_mdl_req *) mcl->lcmd;
	struct mcap_mdl_op_cb *conn = mcl->priv_data;
	mcap_mdl_operation_conf_cb connect_cb = conn->cb.op_conf;
	gpointer user_data = conn->user_data;
	struct mcap_mdl *mdl = conn->mdl;
	uint8_t conf = cmdlast->conf;
	gboolean close;
	GError *gerr = NULL;

	close = check_err_rsp(mcl, rsp, len, sizeof(mcap_rsp) + 1, &gerr);
	g_free(mcl->lcmd);
	mcl->lcmd = NULL;
	mcl->req = MCL_AVAILABLE;

	if (gerr)
		goto fail;

	/* Check if preferences changed */
	if (conf != 0x00 && rsp->data[0] != conf) {
		g_set_error(&gerr, MCAP_ERROR, MCAP_ERROR_FAILED,
						"Configuration changed");
		close = TRUE;
		goto fail;
	}

	connect_cb(mdl, rsp->data[0], gerr, user_data);
	return close;

fail:
	connect_cb(NULL, 0, gerr, user_data);
	mcl->mdls = g_slist_remove(mcl->mdls, mdl);
	mcap_mdl_unref(mdl);
	g_error_free(gerr);
	update_mcl_state(mcl);
	return close;
}

static gboolean process_md_reconnect_mdl_rsp(struct mcap_mcl *mcl,
						mcap_rsp *rsp, uint32_t len)
{
	struct mcap_mdl_op_cb *reconn = mcl->priv_data;
	mcap_mdl_operation_cb reconn_cb = reconn->cb.op;
	gpointer user_data = reconn->user_data;
	struct mcap_mdl *mdl = reconn->mdl;
	GError *gerr = NULL;
	gboolean close;

	close = check_err_rsp(mcl, rsp, len, sizeof(mcap_rsp), &gerr);

	g_free(mcl->lcmd);
	mcl->lcmd = NULL;
	mcl->req = MCL_AVAILABLE;

	reconn_cb(mdl, gerr, user_data);
	if (!gerr)
		return close;

	g_error_free(gerr);
	shutdown_mdl(mdl);
	update_mcl_state(mcl);

	if (rsp->rc != MCAP_INVALID_MDL)
		return close;

	/* Remove cached mdlid */
	mcl->mdls = g_slist_remove(mcl->mdls, mdl);
	mcl->cb->mdl_deleted(mdl, mcl->cb->user_data);
	mcap_mdl_unref(mdl);

	return close;
}

static gboolean process_md_abort_mdl_rsp(struct mcap_mcl *mcl,
						mcap_rsp *rsp, uint32_t len)
{
	struct mcap_mdl_op_cb *abrt = mcl->priv_data;
	mcap_mdl_notify_cb abrt_cb = abrt->cb.notify;
	gpointer user_data = abrt->user_data;
	struct mcap_mdl *mdl = abrt->mdl;
	GError *gerr = NULL;
	gboolean close;

	close = check_err_rsp(mcl, rsp, len, sizeof(mcap_rsp), &gerr);

	g_free(mcl->lcmd);
	mcl->lcmd = NULL;
	mcl->req = MCL_AVAILABLE;

	abrt_cb(gerr, user_data);
	shutdown_mdl(mdl);

	if (len >= sizeof(mcap_rsp) && rsp->rc == MCAP_INVALID_MDL) {
		mcl->mdls = g_slist_remove(mcl->mdls, mdl);
		mcl->cb->mdl_deleted(mdl, mcl->cb->user_data);
		mcap_mdl_unref(mdl);
	}

	if (gerr)
		g_error_free(gerr);

	update_mcl_state(mcl);

	return close;
}

static void restore_mdl(gpointer elem, gpointer data)
{
	struct mcap_mdl *mdl = elem;

	if (mdl->state == MDL_DELETING) {
		if (mdl->dc)
			mdl->state = MDL_CONNECTED;
		else
			mdl->state = MDL_CLOSED;
	} else if (mdl->state == MDL_CLOSED)
		mdl->mcl->cb->mdl_closed(mdl, mdl->mcl->cb->user_data);
}

static void check_mdl_del_err(struct mcap_mdl *mdl, mcap_rsp *rsp)
{
	if (rsp->rc != MCAP_ERROR_INVALID_MDL) {
		restore_mdl(mdl, NULL);
		return;
	}

	/* MDL does not exist in remote side, we can delete it */
	mdl->mcl->mdls = g_slist_remove(mdl->mcl->mdls, mdl);
	mcap_mdl_unref(mdl);
}

static gboolean process_md_delete_mdl_rsp(struct mcap_mcl *mcl, mcap_rsp *rsp,
								uint32_t len)
{
	struct mcap_mdl_op_cb *del = mcl->priv_data;
	struct mcap_mdl *mdl = del->mdl;
	mcap_mdl_notify_cb deleted_cb = del->cb.notify;
	gpointer user_data = del->user_data;
	mcap_md_req *cmdlast = (mcap_md_req *) mcl->lcmd;
	uint16_t mdlid = ntohs(cmdlast->mdl);
	GError *gerr = NULL;
	gboolean close;
	gboolean notify = FALSE;

	close = check_err_rsp(mcl, rsp, len, sizeof(mcap_rsp), &gerr);

	g_free(mcl->lcmd);
	mcl->lcmd = NULL;
	mcl->req = MCL_AVAILABLE;

	if (gerr) {
		if (mdl)
			check_mdl_del_err(mdl, rsp);
		else
			g_slist_foreach(mcl->mdls, restore_mdl, NULL);
		deleted_cb(gerr, user_data);
		g_error_free(gerr);
		return close;
	}

	if (mdlid == MCAP_ALL_MDLIDS) {
		g_slist_foreach(mcl->mdls, mcap_del_mdl, &notify);
		g_slist_free(mcl->mdls);
		mcl->mdls = NULL;
		mcl->state = MCL_CONNECTED;
	} else {
		mcl->mdls = g_slist_remove(mcl->mdls, mdl);
		update_mcl_state(mcl);
		mcap_del_mdl(mdl, &notify);
	}

	deleted_cb(gerr, user_data);

	return close;
}

static void post_process_rsp(struct mcap_mcl *mcl, struct mcap_mdl_op_cb *op)
{
	if (mcl->priv_data != op) {
		/* Queued MCAP request in some callback. */
		/* We should not delete the mcl private data */
		free_mcap_mdl_op(op);
	} else {
		/* This is not a queued request. It's safe */
		/* delete the mcl private data here. */
		free_mcl_priv_data(mcl);
	}
}

static void proc_response(struct mcap_mcl *mcl, void *buf, uint32_t len)
{
	struct mcap_mdl_op_cb *op = mcl->priv_data;
	mcap_rsp *rsp = buf;
	gboolean close;

	RELEASE_TIMER(mcl);

	switch (mcl->lcmd[0] + 1) {
	case MCAP_MD_CREATE_MDL_RSP:
		close = process_md_create_mdl_rsp(mcl, rsp, len);
		post_process_rsp(mcl, op);
		break;
	case MCAP_MD_RECONNECT_MDL_RSP:
		close = process_md_reconnect_mdl_rsp(mcl, rsp, len);
		post_process_rsp(mcl, op);
		break;
	case MCAP_MD_ABORT_MDL_RSP:
		close = process_md_abort_mdl_rsp(mcl, rsp, len);
		post_process_rsp(mcl, op);
		break;
	case MCAP_MD_DELETE_MDL_RSP:
		close = process_md_delete_mdl_rsp(mcl, rsp, len);
		post_process_rsp(mcl, op);
		break;
	default:
		DBG("Unknown cmd response received (op code = %d)", rsp->op);
		close = TRUE;
		break;
	}

	if (close) {
		mcl->mi->mcl_disconnected_cb(mcl, mcl->mi->user_data);
		mcap_cache_mcl(mcl);
	}
}

static void proc_cmd(struct mcap_mcl *mcl, uint8_t *cmd, uint32_t len)
{
	GError *gerr = NULL;

	if (cmd[0] > MCAP_MD_SYNC_INFO_IND ||
					(cmd[0] > MCAP_MD_DELETE_MDL_RSP &&
					cmd[0] < MCAP_MD_SYNC_CAP_REQ)) {
		error("Unknown cmd received (op code = %d)", cmd[0]);
		mcap_send_cmd(mcl, MCAP_ERROR_RSP, MCAP_INVALID_OP_CODE,
						MCAP_MDLID_RESERVED, NULL, 0);
		return;
	}

	if (cmd[0] >= MCAP_MD_SYNC_CAP_REQ &&
					cmd[0] <= MCAP_MD_SYNC_INFO_IND) {
		proc_sync_cmd(mcl, cmd, len);
		return;
	}

	if (!(mcl->ctrl & MCAP_CTRL_STD_OP)) {
		/* In case the remote device doesn't work correctly */
		error("Remote device does not support opcodes, cmd ignored");
		return;
	}

	if (mcl->req == MCL_WAITING_RSP) {
		if (cmd[0] & 0x01) {
			/* Request arrived when a response is expected */
			if (mcl->role == MCL_INITIATOR)
				/* ignore */
				return;
			/* Initiator will ignore our last request */
			RELEASE_TIMER(mcl);
			mcl->req = MCL_AVAILABLE;
			g_set_error(&gerr, MCAP_ERROR, MCAP_ERROR_REQ_IGNORED,
				"Initiator sent a request with more priority");
			mcap_notify_error(mcl, gerr);
			proc_req[mcl->state](mcl, cmd, len);
			return;
		}
		proc_response(mcl, cmd, len);
	} else if (cmd[0] & 0x01)
		proc_req[mcl->state](mcl, cmd, len);
}

static gboolean mdl_event_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
{

	struct mcap_mdl *mdl = data;
	gboolean notify;

	DBG("Close MDL %d", mdl->mdlid);

	notify = (mdl->state == MDL_CONNECTED);
	shutdown_mdl(mdl);

	update_mcl_state(mdl->mcl);

	if (notify) {
		/*Callback to upper layer */
		mdl->mcl->cb->mdl_closed(mdl, mdl->mcl->cb->user_data);
	}

	return FALSE;
}

static void mcap_connect_mdl_cb(GIOChannel *chan, GError *conn_err,
								gpointer data)
{
	struct mcap_mdl_op_cb *con = data;
	struct mcap_mdl *mdl = con->mdl;
	mcap_mdl_operation_cb cb = con->cb.op;
	gpointer user_data = con->user_data;

	DBG("mdl connect callback");

	if (conn_err) {
		DBG("ERROR: mdl connect callback");
		mdl->state = MDL_CLOSED;
		g_io_channel_unref(mdl->dc);
		mdl->dc = NULL;
		cb(mdl, conn_err, user_data);
		return;
	}

	mdl->state = MDL_CONNECTED;
	mdl->wid = g_io_add_watch_full(mdl->dc, G_PRIORITY_DEFAULT,
					G_IO_ERR | G_IO_HUP | G_IO_NVAL,
					(GIOFunc) mdl_event_cb,
					mcap_mdl_ref(mdl),
					(GDestroyNotify) mcap_mdl_unref);

	cb(mdl, conn_err, user_data);
}

gboolean mcap_connect_mdl(struct mcap_mdl *mdl, uint8_t mode,
					uint16_t dcpsm,
					mcap_mdl_operation_cb connect_cb,
					gpointer user_data,
					GDestroyNotify destroy,
					GError **err)
{
	struct mcap_mdl_op_cb *con;

	if (mdl->state != MDL_WAITING) {
		g_set_error(err, MCAP_ERROR, MCAP_ERROR_INVALID_MDL,
					"%s", error2str(MCAP_INVALID_MDL));
		return FALSE;
	}

	if ((mode != L2CAP_MODE_ERTM) && (mode != L2CAP_MODE_STREAMING)) {
		g_set_error(err, MCAP_ERROR, MCAP_ERROR_INVALID_ARGS,
						"Invalid MDL configuration");
		return FALSE;
	}

	con = g_new0(struct mcap_mdl_op_cb, 1);
	con->mdl = mcap_mdl_ref(mdl);
	con->cb.op = connect_cb;
	con->destroy = destroy;
	con->user_data = user_data;

	mdl->dc = bt_io_connect(BT_IO_L2CAP, mcap_connect_mdl_cb, con,
				(GDestroyNotify) free_mcap_mdl_op, err,
				BT_IO_OPT_SOURCE_BDADDR, &mdl->mcl->mi->src,
				BT_IO_OPT_DEST_BDADDR, &mdl->mcl->addr,
				BT_IO_OPT_PSM, dcpsm,
				BT_IO_OPT_MTU, MCAP_DC_MTU,
				BT_IO_OPT_SEC_LEVEL, mdl->mcl->mi->sec,
				BT_IO_OPT_MODE, mode,
				BT_IO_OPT_INVALID);
	if (!mdl->dc) {
		DBG("MDL Connection error");
		mdl->state = MDL_CLOSED;
		mcap_mdl_unref(con->mdl);
		g_free(con);
		return FALSE;
	}

	return TRUE;
}

static gboolean mcl_control_cb(GIOChannel *chan, GIOCondition cond,
								gpointer data)
{
	GError *gerr = NULL;
	struct mcap_mcl *mcl = data;
	int sk, len;
	uint8_t buf[MCAP_CC_MTU];

	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
		goto fail;

	sk = g_io_channel_unix_get_fd(chan);
	len = read(sk, buf, sizeof(buf));
	if (len < 0)
		goto fail;

	proc_cmd(mcl, buf, (uint32_t) len);
	return TRUE;

fail:
	if (mcl->state != MCL_IDLE) {
		if (mcl->req == MCL_WAITING_RSP) {
			/* notify error in pending callback */
			g_set_error(&gerr, MCAP_ERROR, MCAP_ERROR_MCL_CLOSED,
								"MCL closed");
			mcap_notify_error(mcl, gerr);
			g_error_free(gerr);
		}
		mcl->mi->mcl_disconnected_cb(mcl, mcl->mi->user_data);
	}
	mcap_cache_mcl(mcl);
	return FALSE;
}

static void mcap_connect_mcl_cb(GIOChannel *chan, GError *conn_err,
							gpointer user_data)
{
	char dstaddr[18];
	struct connect_mcl *con = user_data;
	struct mcap_mcl *aux, *mcl = con->mcl;
	mcap_mcl_connect_cb connect_cb = con->connect_cb;
	gpointer data = con->user_data;
	GError *gerr = NULL;

	mcl->ctrl &= ~MCAP_CTRL_CONN;

	if (conn_err) {
		if (mcl->ctrl & MCAP_CTRL_FREE) {
			mcap_mcl_release(mcl);
			mcl->mi->mcl_uncached_cb(mcl, mcl->mi->user_data);
		}
		connect_cb(NULL, conn_err, data);
		return;
	}

	ba2str(&mcl->addr, dstaddr);

	aux = find_mcl(mcl->mi->mcls, &mcl->addr);
	if (aux) {
		/* Double MCL connection case */
		error("MCL error: Device %s is already connected", dstaddr);
		g_set_error(&gerr, MCAP_ERROR, MCAP_ERROR_ALREADY_EXISTS,
					"MCL %s is already connected", dstaddr);
		connect_cb(NULL, gerr, data);
		g_error_free(gerr);
		return;
	}

	mcl->state = MCL_CONNECTED;
	mcl->role = MCL_INITIATOR;
	mcl->req = MCL_AVAILABLE;
	mcl->ctrl |= MCAP_CTRL_STD_OP;

	mcap_sync_init(mcl);

	if (mcl->ctrl & MCAP_CTRL_CACHED)
		mcap_uncache_mcl(mcl);
	else {
		mcl->ctrl &= ~MCAP_CTRL_FREE;
		mcl->mi->mcls = g_slist_prepend(mcl->mi->mcls,
							mcap_mcl_ref(mcl));
	}

	mcl->wid = g_io_add_watch_full(mcl->cc, G_PRIORITY_DEFAULT,
				G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
				(GIOFunc) mcl_control_cb,
				mcap_mcl_ref(mcl),
				(GDestroyNotify) mcap_mcl_unref);
	connect_cb(mcl, gerr, data);
}

static void set_mdl_properties(GIOChannel *chan, struct mcap_mdl *mdl)
{
	struct mcap_mcl *mcl = mdl->mcl;

	mdl->state = MDL_CONNECTED;
	mdl->dc = g_io_channel_ref(chan);
	mdl->wid = g_io_add_watch_full(mdl->dc, G_PRIORITY_DEFAULT,
					G_IO_ERR | G_IO_HUP | G_IO_NVAL,
					(GIOFunc) mdl_event_cb,
					mcap_mdl_ref(mdl),
					(GDestroyNotify) mcap_mdl_unref);

	mcl->state = MCL_ACTIVE;
	mcl->cb->mdl_connected(mdl, mcl->cb->user_data);
}

static void mcl_io_destroy(gpointer data)
{
	struct connect_mcl *con = data;

	mcap_mcl_unref(con->mcl);
	if (con->destroy)
		con->destroy(con->user_data);
	g_free(con);
}

gboolean mcap_create_mcl(struct mcap_instance *mi,
				const bdaddr_t *addr,
				uint16_t ccpsm,
				mcap_mcl_connect_cb connect_cb,
				gpointer user_data,
				GDestroyNotify destroy,
				GError **err)
{
	struct mcap_mcl *mcl;
	struct connect_mcl *con;

	mcl = find_mcl(mi->mcls, addr);
	if (mcl) {
		g_set_error(err, MCAP_ERROR, MCAP_ERROR_ALREADY_EXISTS,
					"MCL is already connected.");
		return FALSE;
	}

	mcl = find_mcl(mi->cached, addr);
	if (!mcl) {
		mcl = g_new0(struct mcap_mcl, 1);
		mcl->mi = mcap_instance_ref(mi);
		mcl->state = MCL_IDLE;
		bacpy(&mcl->addr, addr);
		set_default_cb(mcl);
		mcl->next_mdl = (rand() % MCAP_MDLID_FINAL) + 1;
	}

	mcl->ctrl |= MCAP_CTRL_CONN;

	con = g_new0(struct connect_mcl, 1);
	con->mcl = mcap_mcl_ref(mcl);
	con->connect_cb = connect_cb;
	con->destroy = destroy;
	con->user_data = user_data;

	mcl->cc = bt_io_connect(BT_IO_L2CAP, mcap_connect_mcl_cb, con,
				mcl_io_destroy, err,
				BT_IO_OPT_SOURCE_BDADDR, &mi->src,
				BT_IO_OPT_DEST_BDADDR, addr,
				BT_IO_OPT_PSM, ccpsm,
				BT_IO_OPT_MTU, MCAP_CC_MTU,
				BT_IO_OPT_SEC_LEVEL, mi->sec,
				BT_IO_OPT_MODE, L2CAP_MODE_ERTM,
				BT_IO_OPT_INVALID);
	if (!mcl->cc) {
		mcl->ctrl &= ~MCAP_CTRL_CONN;
		if (mcl->ctrl & MCAP_CTRL_FREE) {
			mcap_mcl_release(mcl);
			mcl->mi->mcl_uncached_cb(mcl, mcl->mi->user_data);
		}
		mcap_mcl_unref(con->mcl);
		g_free(con);
		return FALSE;
	}

	return TRUE;
}

static void connect_dc_event_cb(GIOChannel *chan, GError *gerr,
							gpointer user_data)
{
	struct mcap_instance *mi = user_data;
	struct mcap_mcl *mcl;
	struct mcap_mdl *mdl;
	GError *err = NULL;
	bdaddr_t dst;
	GSList *l;

	if (gerr)
		return;

	bt_io_get(chan, BT_IO_L2CAP, &err,
			BT_IO_OPT_DEST_BDADDR, &dst,
			BT_IO_OPT_INVALID);
	if (err) {
		error("%s", err->message);
		g_error_free(err);
		goto drop;
	}

	mcl = find_mcl(mi->mcls, &dst);
	if (!mcl || mcl->state != MCL_PENDING)
		goto drop;

	for (l = mcl->mdls; l; l = l->next) {
		mdl = l->data;
		if (mdl->state == MDL_WAITING) {
			set_mdl_properties(chan, mdl);
			return;
		}
	}

drop:
	g_io_channel_shutdown(chan, TRUE, NULL);
}

static void set_mcl_conf(GIOChannel *chan, struct mcap_mcl *mcl)
{
	gboolean reconn;

	mcl->state = MCL_CONNECTED;
	mcl->role = MCL_ACCEPTOR;
	mcl->req = MCL_AVAILABLE;
	mcl->cc = g_io_channel_ref(chan);
	mcl->ctrl |= MCAP_CTRL_STD_OP;

	mcap_sync_init(mcl);

	reconn = (mcl->ctrl & MCAP_CTRL_CACHED);
	if (reconn)
		mcap_uncache_mcl(mcl);
	else
		mcl->mi->mcls = g_slist_prepend(mcl->mi->mcls,
							mcap_mcl_ref(mcl));

	mcl->wid = g_io_add_watch_full(mcl->cc, G_PRIORITY_DEFAULT,
				G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
				(GIOFunc) mcl_control_cb,
				mcap_mcl_ref(mcl),
				(GDestroyNotify) mcap_mcl_unref);

	/* Callback to report new MCL */
	if (reconn)
		mcl->mi->mcl_reconnected_cb(mcl, mcl->mi->user_data);
	else
		mcl->mi->mcl_connected_cb(mcl, mcl->mi->user_data);
}

static void connect_mcl_event_cb(GIOChannel *chan, GError *gerr,
							gpointer user_data)
{
	struct mcap_instance *mi = user_data;
	struct mcap_mcl *mcl;
	bdaddr_t dst;
	char address[18], srcstr[18];
	GError *err = NULL;

	if (gerr)
		return;

	bt_io_get(chan, BT_IO_L2CAP, &err,
			BT_IO_OPT_DEST_BDADDR, &dst,
			BT_IO_OPT_DEST, address,
			BT_IO_OPT_INVALID);
	if (err) {
		error("%s", err->message);
		g_error_free(err);
		goto drop;
	}

	ba2str(&mi->src, srcstr);
	mcl = find_mcl(mi->mcls, &dst);
	if (mcl) {
		error("Control channel already created with %s on adapter %s",
				address, srcstr);
		goto drop;
	}

	mcl = find_mcl(mi->cached, &dst);
	if (!mcl) {
		mcl = g_new0(struct mcap_mcl, 1);
		mcl->mi = mcap_instance_ref(mi);
		bacpy(&mcl->addr, &dst);
		set_default_cb(mcl);
		mcl->next_mdl = (rand() % MCAP_MDLID_FINAL) + 1;
	}

	set_mcl_conf(chan, mcl);

	return;
drop:
	g_io_channel_shutdown(chan, TRUE, NULL);
}

struct mcap_instance *mcap_create_instance(bdaddr_t *src,
					BtIOSecLevel sec,
					uint16_t ccpsm,
					uint16_t dcpsm,
					mcap_mcl_event_cb mcl_connected,
					mcap_mcl_event_cb mcl_reconnected,
					mcap_mcl_event_cb mcl_disconnected,
					mcap_mcl_event_cb mcl_uncached,
					mcap_info_ind_event_cb mcl_sync_info_ind,
					gpointer user_data,
					GError **gerr)
{
	struct mcap_instance *mi;

	if (sec < BT_IO_SEC_MEDIUM) {
		g_set_error(gerr, MCAP_ERROR, MCAP_ERROR_INVALID_ARGS,
				"Security level can't be minor of %d",
				BT_IO_SEC_MEDIUM);
		return NULL;
	}

	if (!(mcl_connected && mcl_reconnected &&
			mcl_disconnected && mcl_uncached)) {
		g_set_error(gerr, MCAP_ERROR, MCAP_ERROR_INVALID_ARGS,
				"The callbacks can't be null");
		return NULL;
	}

	mi = g_new0(struct mcap_instance, 1);

	bacpy(&mi->src, src);

	mi->sec = sec;
	mi->mcl_connected_cb = mcl_connected;
	mi->mcl_reconnected_cb = mcl_reconnected;
	mi->mcl_disconnected_cb = mcl_disconnected;
	mi->mcl_uncached_cb = mcl_uncached;
	mi->mcl_sync_infoind_cb = mcl_sync_info_ind;
	mi->user_data = user_data;
	mi->csp_enabled = FALSE;

	/* Listen incoming connections in control channel */
	mi->ccio = bt_io_listen(BT_IO_L2CAP, connect_mcl_event_cb, NULL, mi,
				NULL, gerr,
				BT_IO_OPT_SOURCE_BDADDR, &mi->src,
				BT_IO_OPT_PSM, ccpsm,
				BT_IO_OPT_MTU, MCAP_CC_MTU,
				BT_IO_OPT_SEC_LEVEL, sec,
				BT_IO_OPT_MODE, L2CAP_MODE_ERTM,
				BT_IO_OPT_INVALID);
	if (!mi->ccio) {
		error("%s", (*gerr)->message);
		g_free(mi);
		return NULL;
	}

	/* Listen incoming connections in data channels */
	mi->dcio = bt_io_listen(BT_IO_L2CAP, connect_dc_event_cb, NULL, mi,
				NULL, gerr,
				BT_IO_OPT_SOURCE_BDADDR, &mi->src,
				BT_IO_OPT_PSM, dcpsm,
				BT_IO_OPT_MTU, MCAP_DC_MTU,
				BT_IO_OPT_SEC_LEVEL, sec,
				BT_IO_OPT_INVALID);
	if (!mi->dcio) {
		g_io_channel_shutdown(mi->ccio, TRUE, NULL);
		g_io_channel_unref(mi->ccio);
		mi->ccio = NULL;
		error("%s", (*gerr)->message);
		g_free(mi);
		return NULL;
	}

	/* Initialize random seed to generate mdlids for this instance */
	srand(time(NULL));

	return mcap_instance_ref(mi);
}

void mcap_release_instance(struct mcap_instance *mi)
{
	GSList *l;

	if (!mi)
		return;

	if (mi->ccio) {
		g_io_channel_shutdown(mi->ccio, TRUE, NULL);
		g_io_channel_unref(mi->ccio);
		mi->ccio = NULL;
	}

	if (mi->dcio) {
		g_io_channel_shutdown(mi->dcio, TRUE, NULL);
		g_io_channel_unref(mi->dcio);
		mi->dcio = NULL;
	}

	for (l = mi->mcls; l; l = l->next) {
		mcap_mcl_release(l->data);
		mcap_mcl_unref(l->data);
	}

	g_slist_free(mi->mcls);
	mi->mcls = NULL;

	for (l = mi->cached; l; l = l->next) {
		mcap_mcl_release(l->data);
		mcap_mcl_unref(l->data);
	}

	g_slist_free(mi->cached);
	mi->cached = NULL;
}

struct mcap_instance *mcap_instance_ref(struct mcap_instance *mi)
{
	mi->ref++;

	DBG("mcap_instance_ref(%p): ref=%d", mi, mi->ref);

	return mi;
}

void mcap_instance_unref(struct mcap_instance *mi)
{
	mi->ref--;

	DBG("mcap_instance_unref(%p): ref=%d", mi, mi->ref);

	if (mi->ref > 0)
		return;

	mcap_release_instance(mi);
	g_free(mi);
}

uint16_t mcap_get_ctrl_psm(struct mcap_instance *mi, GError **err)
{
	uint16_t lpsm;

	if (!(mi && mi->ccio)) {
		g_set_error(err, MCAP_ERROR, MCAP_ERROR_INVALID_ARGS,
			"Invalid MCAP instance");
		return 0;
	}

	if (!bt_io_get(mi->ccio, BT_IO_L2CAP, err,
			BT_IO_OPT_PSM, &lpsm,
			BT_IO_OPT_INVALID))
		return 0;

	return lpsm;
}

uint16_t mcap_get_data_psm(struct mcap_instance *mi, GError **err)
{
	uint16_t lpsm;

	if (!(mi && mi->dcio)) {
		g_set_error(err, MCAP_ERROR, MCAP_ERROR_INVALID_ARGS,
			"Invalid MCAP instance");
		return 0;
	}

	if (!bt_io_get(mi->dcio, BT_IO_L2CAP, err,
			BT_IO_OPT_PSM, &lpsm,
			BT_IO_OPT_INVALID))
		return 0;

	return lpsm;
}

gboolean mcap_set_data_chan_mode(struct mcap_instance *mi, uint8_t mode,
								GError **err)
{
	if (!(mi && mi->dcio)) {
		g_set_error(err, MCAP_ERROR, MCAP_ERROR_INVALID_ARGS,
						"Invalid MCAP instance");
		return FALSE;
	}

	return bt_io_set(mi->dcio, BT_IO_L2CAP, err, BT_IO_OPT_MODE, mode,
							BT_IO_OPT_INVALID);
}

struct mcap_mdl *mcap_mdl_ref(struct mcap_mdl *mdl)
{
	mdl->ref++;

	DBG("mcap_mdl_ref(%p): ref=%d", mdl, mdl->ref);

	return mdl;
}

void mcap_mdl_unref(struct mcap_mdl *mdl)
{
	mdl->ref--;

	DBG("mcap_mdl_unref(%p): ref=%d", mdl, mdl->ref);

	if (mdl->ref > 0)
		return;

	free_mdl(mdl);
}
