/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2014  Intel Corporation. All rights reserved.
 *  Copyright (C) 2010 GSyC/LibreSoft, Universidad Rey Juan Carlos.
 *
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library 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
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <stdint.h>
#include <stdbool.h>
#include <errno.h>
#include <unistd.h>
#include <glib.h>

#include "btio/btio.h"
#include "lib/bluetooth.h"
#include "lib/sdp.h"
#include "lib/sdp_lib.h"
#include "lib/uuid.h"
#include "lib/l2cap.h"
#include "src/log.h"
#include "src/shared/util.h"
#include "src/shared/queue.h"
#include "src/uuid-helper.h"
#include "src/sdp-client.h"
#include "profiles/health/mcap.h"

#include "hal-msg.h"
#include "ipc-common.h"
#include "ipc.h"
#include "utils.h"
#include "bluetooth.h"
#include "health.h"

#define SVC_HINT_HEALTH			0x00
#define HDP_VERSION			0x0101
#define DATA_EXCHANGE_SPEC_11073	0x01

#define CHANNEL_TYPE_ANY       0x00
#define CHANNEL_TYPE_RELIABLE  0x01
#define CHANNEL_TYPE_STREAM    0x02

#define MDEP_ECHO		0x00
#define MDEP_INITIAL		0x01
#define MDEP_FINAL		0x7F

static bdaddr_t adapter_addr;
static struct ipc *hal_ipc = NULL;
static struct queue *apps = NULL;
static struct mcap_instance *mcap = NULL;
static uint32_t record_id = 0;
static uint32_t record_state = 0;

struct mdep_cfg {
	uint8_t role;
	uint16_t data_type;
	uint8_t channel_type;
	char *descr;

	uint8_t id; /* mdep id */
};

struct health_device {
	bdaddr_t dst;
	uint16_t app_id;

	struct mcap_mcl *mcl;

	struct queue *channels;     /* data channels */

	uint16_t ccpsm;
	uint16_t dcpsm;
};

struct health_channel {
	uint8_t mdep_id;
	uint8_t type;

	struct health_device *dev;

	uint8_t remote_mdep;
	struct mcap_mdl *mdl;
	bool mdl_conn;
	uint16_t mdl_id; /* MDL ID */

	uint16_t id; /* channel id */
};

struct health_app {
	char *app_name;
	char *provider_name;
	char *service_name;
	char *service_descr;
	uint8_t num_of_mdep;
	struct queue *mdeps;

	uint16_t id; /* app id */
	struct queue *devices;
};

static void send_app_reg_notify(struct health_app *app, uint8_t state)
{
	struct hal_ev_health_app_reg_state ev;

	DBG("");

	ev.id = app->id;
	ev.state = state;

	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_HEALTH,
				HAL_EV_HEALTH_APP_REG_STATE, sizeof(ev), &ev);
}

static void send_channel_state_notify(struct health_channel *channel,
						uint8_t state, int fd)
{
	struct hal_ev_health_channel_state ev;

	DBG("");

	bdaddr2android(&channel->dev->dst, ev.bdaddr);
	ev.app_id = channel->dev->app_id;
	ev.mdep_index = channel->mdep_id - 1;
	ev.channel_id = channel->id;
	ev.channel_state = state;

	ipc_send_notif_with_fd(hal_ipc, HAL_SERVICE_ID_HEALTH,
					HAL_EV_HEALTH_CHANNEL_STATE,
					sizeof(ev), &ev, fd);
}

static void unref_mdl(struct health_channel *channel)
{
	if (!channel || !channel->mdl)
		return;

	mcap_mdl_unref(channel->mdl);
	channel->mdl = NULL;
	channel->mdl_conn = false;
}

static void free_health_channel(void *data)
{
	struct health_channel *channel = data;
	int fd;

	DBG("channel %p", channel);

	if (!channel)
		return;

	fd = mcap_mdl_get_fd(channel->mdl);
	if (fd >= 0)
		shutdown(fd, SHUT_RDWR);

	unref_mdl(channel);
	free(channel);
}

static void destroy_channel(void *data)
{
	struct health_channel *channel = data;

	if (!channel)
		return;

	send_channel_state_notify(channel, HAL_HEALTH_CHANNEL_DESTROYED, -1);
	queue_remove(channel->dev->channels, channel);
	free_health_channel(channel);
}

static void unref_mcl(struct health_device *dev)
{
	if (!dev || !dev->mcl)
		return;

	mcap_close_mcl(dev->mcl, FALSE);
	mcap_mcl_unref(dev->mcl);
	dev->mcl = NULL;
}

static void free_health_device(void *data)
{
	struct health_device *dev = data;

	if (!dev)
		return;

	unref_mcl(dev);
	queue_destroy(dev->channels, free_health_channel);
	free(dev);
}

static void free_mdep_cfg(void *data)
{
	struct mdep_cfg *cfg = data;

	if (!cfg)
		return;

	free(cfg->descr);
	free(cfg);
}

static void free_health_app(void *data)
{
	struct health_app *app = data;

	if (!app)
		return;

	free(app->app_name);
	free(app->provider_name);
	free(app->service_name);
	free(app->service_descr);
	queue_destroy(app->mdeps, free_mdep_cfg);
	queue_destroy(app->devices, free_health_device);
	free(app);
}

static bool match_channel_by_mdl(const void *data, const void *user_data)
{
	const struct health_channel *channel = data;
	const struct mcap_mdl *mdl = user_data;

	return channel->mdl == mdl;
}

static bool match_channel_by_id(const void *data, const void *user_data)
{
	const struct health_channel *channel = data;
	uint16_t channel_id = PTR_TO_INT(user_data);

	return channel->id == channel_id;
}

static bool match_dev_by_mcl(const void *data, const void *user_data)
{
	const struct health_device *dev = data;
	const struct mcap_mcl *mcl = user_data;

	return dev->mcl == mcl;
}

static bool match_dev_by_addr(const void *data, const void *user_data)
{
	const struct health_device *dev = data;
	const bdaddr_t *addr = user_data;

	return !bacmp(&dev->dst, addr);
}

static bool match_channel_by_mdep_id(const void *data, const void *user_data)
{
	const struct health_channel *channel = data;
	uint16_t mdep_id = PTR_TO_INT(user_data);

	return channel->mdep_id == mdep_id;
}

static bool match_mdep_by_role(const void *data, const void *user_data)
{
	const struct mdep_cfg *mdep = data;
	uint16_t role = PTR_TO_INT(user_data);

	return mdep->role == role;
}

static bool match_mdep_by_id(const void *data, const void *user_data)
{
	const struct mdep_cfg *mdep = data;
	uint16_t mdep_id = PTR_TO_INT(user_data);

	return mdep->id == mdep_id;
}

static bool match_app_by_id(const void *data, const void *user_data)
{
	const struct health_app *app = data;
	uint16_t app_id = PTR_TO_INT(user_data);

	return app->id == app_id;
}

static struct health_channel *search_channel_by_id(uint16_t id)
{
	const struct queue_entry *apps_entry, *devices_entry;
	struct health_app *app;
	struct health_channel *channel;
	struct health_device *dev;

	DBG("");

	apps_entry = queue_get_entries(apps);
	while (apps_entry) {
		app = apps_entry->data;
		devices_entry = queue_get_entries(app->devices);
		while (devices_entry) {
			dev = devices_entry->data;
			channel = queue_find(dev->channels, match_channel_by_id,
								INT_TO_PTR(id));

			if (channel)
				return channel;

			devices_entry = devices_entry->next;
		}

		apps_entry = apps_entry->next;
	}

	return NULL;
}

static struct health_channel *search_channel_by_mdl(struct mcap_mdl *mdl)
{
	const struct queue_entry *apps_entry, *devices_entry;
	struct health_app *app;
	struct health_channel *channel;
	struct health_device *dev;

	DBG("");

	apps_entry = queue_get_entries(apps);
	while (apps_entry) {
		app = apps_entry->data;
		devices_entry = queue_get_entries(app->devices);
		while (devices_entry) {
			dev = devices_entry->data;
			channel = queue_find(dev->channels,
						match_channel_by_mdl, mdl);

			if (channel)
				return channel;

			devices_entry = devices_entry->next;
		}

		apps_entry = apps_entry->next;
	}

	return NULL;
}

static struct health_device *search_dev_by_mcl(struct mcap_mcl *mcl)
{
	const struct queue_entry *apps_entry;
	struct health_app *app;
	struct health_device *dev;

	DBG("");

	apps_entry = queue_get_entries(apps);
	while (apps_entry) {
		app = apps_entry->data;

		dev = queue_find(app->devices, match_dev_by_mcl, mcl);

		if (dev)
			return dev;

		apps_entry = apps_entry->next;
	}

	return NULL;
}

static struct health_app *search_app_by_mdepid(uint8_t mdepid)
{
	const struct queue_entry *apps_entry;
	struct health_app *app;

	DBG("");

	apps_entry = queue_get_entries(apps);
	while (apps_entry) {
		app = apps_entry->data;

		if (queue_find(app->mdeps, match_mdep_by_id,
							INT_TO_PTR(mdepid)))
			return app;

		apps_entry = apps_entry->next;
	}

	return NULL;
}

static int register_service_protocols(sdp_record_t *rec,
					struct health_app *app)
{
	uuid_t l2cap_uuid, mcap_c_uuid;
	sdp_list_t *l2cap_list, *proto_list = NULL, *mcap_list = NULL;
	sdp_list_t *access_proto_list = NULL;
	sdp_data_t *psm = NULL, *mcap_ver = NULL;
	uint32_t ccpsm;
	uint16_t version = MCAP_VERSION;
	GError *err = NULL;
	int ret = -1;

	DBG("");

	/* set l2cap information */
	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
	l2cap_list = sdp_list_append(NULL, &l2cap_uuid);
	if (!l2cap_list)
		goto fail;

	ccpsm = mcap_get_ctrl_psm(mcap, &err);
	if (err)
		goto fail;

	psm = sdp_data_alloc(SDP_UINT16, &ccpsm);
	if (!psm)
		goto fail;

	if (!sdp_list_append(l2cap_list, psm))
		goto fail;

	proto_list = sdp_list_append(NULL, l2cap_list);
	if (!proto_list)
		goto fail;

	/* set mcap information */
	sdp_uuid16_create(&mcap_c_uuid, MCAP_CTRL_UUID);
	mcap_list = sdp_list_append(NULL, &mcap_c_uuid);
	if (!mcap_list)
		goto fail;

	mcap_ver = sdp_data_alloc(SDP_UINT16, &version);
	if (!mcap_ver)
		goto fail;

	if (!sdp_list_append(mcap_list, mcap_ver))
		goto fail;

	if (!sdp_list_append(proto_list, mcap_list))
		goto fail;

	/* attach protocol information to service record */
	access_proto_list = sdp_list_append(NULL, proto_list);
	if (!access_proto_list)
		goto fail;

	sdp_set_access_protos(rec, access_proto_list);
	ret = 0;

fail:
	sdp_list_free(l2cap_list, NULL);
	sdp_list_free(mcap_list, NULL);
	sdp_list_free(proto_list, NULL);
	sdp_list_free(access_proto_list, NULL);

	if (psm)
		sdp_data_free(psm);

	if (mcap_ver)
		sdp_data_free(mcap_ver);

	if (err)
		g_error_free(err);

	return ret;
}

static int register_service_profiles(sdp_record_t *rec)
{
	int ret;
	sdp_list_t *profile_list;
	sdp_profile_desc_t hdp_profile;

	DBG("");

	/* set hdp information */
	sdp_uuid16_create(&hdp_profile.uuid, HDP_SVCLASS_ID);
	hdp_profile.version = HDP_VERSION;
	profile_list = sdp_list_append(NULL, &hdp_profile);
	if (!profile_list)
		return -1;

	/* set profile descriptor list */
	ret = sdp_set_profile_descs(rec, profile_list);
	sdp_list_free(profile_list, NULL);

	return ret;
}

static int register_service_additional_protocols(sdp_record_t *rec,
						struct health_app *app)
{
	int ret = -1;
	uuid_t l2cap_uuid, mcap_d_uuid;
	sdp_list_t *l2cap_list, *proto_list = NULL, *mcap_list = NULL;
	sdp_list_t *access_proto_list = NULL;
	sdp_data_t *psm = NULL;
	uint32_t dcpsm;
	GError *err = NULL;

	DBG("");

	/* set l2cap information */
	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
	l2cap_list = sdp_list_append(NULL, &l2cap_uuid);
	if (!l2cap_list)
		goto fail;

	dcpsm = mcap_get_data_psm(mcap, &err);
	if (err)
		goto fail;

	psm = sdp_data_alloc(SDP_UINT16, &dcpsm);
	if (!psm)
		goto fail;

	if (!sdp_list_append(l2cap_list, psm))
		goto fail;

	proto_list = sdp_list_append(NULL, l2cap_list);
	if (!proto_list)
		goto fail;

	/* set mcap information */
	sdp_uuid16_create(&mcap_d_uuid, MCAP_DATA_UUID);
	mcap_list = sdp_list_append(NULL, &mcap_d_uuid);
	if (!mcap_list)
		goto fail;

	if (!sdp_list_append(proto_list, mcap_list))
		goto fail;

	/* attach protocol information to service record */
	access_proto_list = sdp_list_append(NULL, proto_list);
	if (!access_proto_list)
		goto fail;

	sdp_set_add_access_protos(rec, access_proto_list);
	ret = 0;

fail:
	sdp_list_free(l2cap_list, NULL);
	sdp_list_free(mcap_list, NULL);
	sdp_list_free(proto_list, NULL);
	sdp_list_free(access_proto_list, NULL);

	if (psm)
		sdp_data_free(psm);

	if (err)
		g_error_free(err);

	return ret;
}

static sdp_list_t *mdeps_to_sdp_features(struct mdep_cfg *mdep)
{
	sdp_data_t *mdepid, *dtype = NULL, *role = NULL, *descr = NULL;
	sdp_list_t *f_list = NULL;

	DBG("");

	mdepid = sdp_data_alloc(SDP_UINT8, &mdep->id);
	if (!mdepid)
		return NULL;

	dtype = sdp_data_alloc(SDP_UINT16, &mdep->data_type);
	if (!dtype)
		goto fail;

	role = sdp_data_alloc(SDP_UINT8, &mdep->role);
	if (!role)
		goto fail;

	if (mdep->descr) {
		descr = sdp_data_alloc(SDP_TEXT_STR8, mdep->descr);
		if (!descr)
			goto fail;
	}

	f_list = sdp_list_append(NULL, mdepid);
	if (!f_list)
		goto fail;

	if (!sdp_list_append(f_list, dtype))
		goto fail;

	if (!sdp_list_append(f_list, role))
		goto fail;

	if (descr && !sdp_list_append(f_list, descr))
		goto fail;

	return f_list;

fail:
	sdp_list_free(f_list, NULL);

	if (mdepid)
		sdp_data_free(mdepid);

	if (dtype)
		sdp_data_free(dtype);

	if (role)
		sdp_data_free(role);

	if (descr)
		sdp_data_free(descr);

	return NULL;
}

static void free_hdp_list(void *list)
{
	sdp_list_t *hdp_list = list;

	sdp_list_free(hdp_list, (sdp_free_func_t)sdp_data_free);
}

static void register_features(void *data, void *user_data)
{
	struct mdep_cfg *mdep = data;
	sdp_list_t **sup_features = user_data;
	sdp_list_t *hdp_feature;

	DBG("");

	hdp_feature = mdeps_to_sdp_features(mdep);
	if (!hdp_feature)
		return;

	if (!*sup_features) {
		*sup_features = sdp_list_append(NULL, hdp_feature);
		if (!*sup_features)
			sdp_list_free(hdp_feature,
					(sdp_free_func_t)sdp_data_free);
	} else if (!sdp_list_append(*sup_features, hdp_feature)) {
		sdp_list_free(hdp_feature,
					(sdp_free_func_t)sdp_data_free);
	}
}

static int register_service_sup_features(sdp_record_t *rec,
						struct health_app *app)
{
	sdp_list_t *sup_features = NULL;

	DBG("");

	queue_foreach(app->mdeps, register_features, &sup_features);
	if (!sup_features)
		return -1;

	if (sdp_set_supp_feat(rec, sup_features) < 0) {
		sdp_list_free(sup_features, free_hdp_list);
		return -1;
	}

	sdp_list_free(sup_features, free_hdp_list);
	return 0;
}

static int register_data_exchange_spec(sdp_record_t *rec)
{
	sdp_data_t *spec;
	uint8_t data_spec = DATA_EXCHANGE_SPEC_11073;
	/* As of now only 11073 is supported, so we set it as default */

	DBG("");

	spec = sdp_data_alloc(SDP_UINT8, &data_spec);
	if (!spec)
		return -1;

	if (sdp_attr_add(rec, SDP_ATTR_DATA_EXCHANGE_SPEC, spec) < 0) {
		sdp_data_free(spec);
		return -1;
	}

	return 0;
}

static int register_mcap_features(sdp_record_t *rec)
{
	sdp_data_t *mcap_proc;
	uint8_t mcap_sup_proc = MCAP_SUP_PROC;

	DBG("");

	mcap_proc = sdp_data_alloc(SDP_UINT8, &mcap_sup_proc);
	if (!mcap_proc)
		return -1;

	if (sdp_attr_add(rec, SDP_ATTR_MCAP_SUPPORTED_PROCEDURES,
							mcap_proc) < 0) {
		sdp_data_free(mcap_proc);
		return -1;
	}

	return 0;
}

static int set_sdp_services_uuid(sdp_record_t *rec, uint8_t role)
{
	uuid_t source, sink;
	sdp_list_t *list = NULL;

	sdp_uuid16_create(&sink, HDP_SINK_SVCLASS_ID);
	sdp_uuid16_create(&source, HDP_SOURCE_SVCLASS_ID);
	sdp_get_service_classes(rec, &list);

	switch (role) {
	case HAL_HEALTH_MDEP_ROLE_SOURCE:
		if (!sdp_list_find(list, &source, sdp_uuid_cmp))
			list = sdp_list_append(list, &source);
		break;
	case HAL_HEALTH_MDEP_ROLE_SINK:
		if (!sdp_list_find(list, &sink, sdp_uuid_cmp))
			list = sdp_list_append(list, &sink);
		break;
	}

	if (sdp_set_service_classes(rec, list) < 0) {
		sdp_list_free(list, NULL);
		return -1;
	}

	sdp_list_free(list, NULL);

	return 0;
}

static int update_sdp_record(struct health_app *app)
{
	sdp_record_t *rec;
	uint8_t role;

	DBG("");

	if (record_id > 0) {
		bt_adapter_remove_record(record_id);
		record_id = 0;
	}

	rec = sdp_record_alloc();
	if (!rec)
		return -1;

	role = HAL_HEALTH_MDEP_ROLE_SOURCE;
	if (queue_find(app->mdeps, match_mdep_by_role, INT_TO_PTR(role)))
		set_sdp_services_uuid(rec, role);

	role = HAL_HEALTH_MDEP_ROLE_SINK;
	if (queue_find(app->mdeps, match_mdep_by_role, INT_TO_PTR(role)))
		set_sdp_services_uuid(rec, role);

	sdp_set_info_attr(rec, app->service_name, app->provider_name,
							app->service_descr);

	if (register_service_protocols(rec, app) < 0)
		goto fail;

	if (register_service_profiles(rec) < 0)
		goto fail;

	if (register_service_additional_protocols(rec, app) < 0)
		goto fail;

	if (register_service_sup_features(rec, app) < 0)
		goto fail;

	if (register_data_exchange_spec(rec) < 0)
		goto fail;

	if (register_mcap_features(rec) < 0)
		goto fail;

	if (sdp_set_record_state(rec, record_state++) < 0)
		goto fail;

	if (bt_adapter_add_record(rec, SVC_HINT_HEALTH) < 0) {
		error("health: Failed to register HEALTH record");
		goto fail;
	}

	record_id = rec->handle;

	return 0;

fail:
	sdp_record_free(rec);

	return -1;
}

static struct health_app *create_health_app(const char *app_name,
				const char *provider, const char *srv_name,
				const char *srv_descr, uint8_t mdeps)
{
	struct health_app *app;
	static unsigned int app_id = 1;

	DBG("");

	app = new0(struct health_app, 1);
	if (!app)
		return NULL;

	app->id = app_id++;
	app->num_of_mdep = mdeps;
	app->app_name = strdup(app_name);

	if (provider) {
		app->provider_name = strdup(provider);
		if (!app->provider_name)
			goto fail;
	}

	if (srv_name) {
		app->service_name = strdup(srv_name);
		if (!app->service_name)
			goto fail;
	}

	if (srv_descr) {
		app->service_descr = strdup(srv_descr);
		if (!app->service_descr)
			goto fail;
	}

	app->mdeps = queue_new();
	if (!app->mdeps)
		goto fail;

	app->devices = queue_new();
	if (!app->devices)
		goto fail;

	return app;

fail:
	free_health_app(app);
	return NULL;
}

static void bt_health_register_app(const void *buf, uint16_t len)
{
	const struct hal_cmd_health_reg_app *cmd = buf;
	struct hal_rsp_health_reg_app rsp;
	struct health_app *app;
	uint16_t off;
	uint16_t app_name_len, provider_len, srv_name_len, srv_descr_len;
	char *app_name, *provider = NULL, *srv_name = NULL, *srv_descr = NULL;

	DBG("");

	if (len != sizeof(*cmd) + cmd->len ||
			cmd->app_name_off > cmd->provider_name_off ||
			cmd->provider_name_off > cmd->service_name_off ||
			cmd->service_name_off > cmd->service_descr_off ||
			cmd->service_descr_off > cmd->len) {
		error("health: Invalid register app command, terminating");
		raise(SIGTERM);
		return;
	}

	app_name = (char *) cmd->data;
	app_name_len = cmd->provider_name_off - cmd->app_name_off;

	off = app_name_len;
	provider_len = cmd->service_name_off - off;
	if (provider_len > 0)
		provider = (char *) cmd->data + off;

	off += provider_len;
	srv_name_len = cmd->service_descr_off - off;
	if (srv_name_len > 0)
		srv_name = (char *) cmd->data + off;

	off += srv_name_len;
	srv_descr_len = cmd->len - off;
	if (srv_descr_len > 0)
		srv_descr = (char *) cmd->data + off;

	app = create_health_app(app_name, provider, srv_name, srv_descr,
							cmd->num_of_mdep);
	if (!app)
		goto fail;

	if (!queue_push_tail(apps, app))
		goto fail;

	rsp.app_id = app->id;
	ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_REG_APP,
							sizeof(rsp), &rsp, -1);
	return;

fail:
	free_health_app(app);
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_MDEP,
							HAL_STATUS_FAILED);
}

static uint8_t android2channel_type(uint8_t type)
{
	switch (type) {
	case HAL_HEALTH_CHANNEL_TYPE_RELIABLE:
		return CHANNEL_TYPE_RELIABLE;
	case HAL_HEALTH_CHANNEL_TYPE_STREAMING:
		return CHANNEL_TYPE_STREAM;
	default:
		return CHANNEL_TYPE_ANY;
	}
}

static void bt_health_mdep_cfg_data(const void *buf, uint16_t len)
{
	const struct hal_cmd_health_mdep *cmd = buf;
	struct health_app *app;
	struct mdep_cfg *mdep = NULL;
	uint8_t status;

	DBG("");

	app = queue_find(apps, match_app_by_id, INT_TO_PTR(cmd->app_id));
	if (!app) {
		status = HAL_STATUS_INVALID;
		goto fail;
	}

	mdep = new0(struct mdep_cfg, 1);
	if (!mdep) {
		status = HAL_STATUS_INVALID;
		goto fail;
	}

	mdep->role = cmd->role;
	mdep->data_type = cmd->data_type;
	mdep->channel_type = android2channel_type(cmd->channel_type);
	mdep->id = queue_length(app->mdeps) + 1;

	if (cmd->descr_len > 0) {
		mdep->descr = malloc0(cmd->descr_len);
		memcpy(mdep->descr, cmd->descr, cmd->descr_len);
	}

	if (!queue_push_tail(app->mdeps, mdep)) {
		status = HAL_STATUS_FAILED;
		goto fail;
	}

	if (app->num_of_mdep != queue_length(app->mdeps))
		goto send_rsp;

	/* add sdp record from app configuration data */
	/*
	 * TODO: Check what to be done if mupltple applications are trying to
	 * register with different role and different configurations.
	 * 1) Does device supports SOURCE and SINK at the same time ?
	 * 2) Does it require different SDP records or one record with
	 *    multile MDEP configurations ?
	 */
	if (update_sdp_record(app) < 0) {
		error("health: HDP SDP record preparation failed");
		status = HAL_STATUS_FAILED;
		goto fail;
	}

	send_app_reg_notify(app, HAL_HEALTH_APP_REG_SUCCESS);

send_rsp:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_MDEP,
							HAL_STATUS_SUCCESS);
	return;

fail:
	if (status != HAL_STATUS_SUCCESS) {
		free_mdep_cfg(mdep);
		queue_remove(apps, app);
		free_health_app(app);
	}

	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH, HAL_OP_HEALTH_MDEP,
								status);
}

static void bt_health_unregister_app(const void *buf, uint16_t len)
{
	const struct hal_cmd_health_unreg_app *cmd = buf;
	struct health_app *app;

	DBG("");

	app = queue_remove_if(apps, match_app_by_id, INT_TO_PTR(cmd->app_id));
	if (!app) {
		ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH,
				HAL_OP_HEALTH_UNREG_APP, HAL_STATUS_INVALID);
		return;
	}

	send_app_reg_notify(app, HAL_HEALTH_APP_DEREG_SUCCESS);

	if (record_id > 0) {
		bt_adapter_remove_record(record_id);
		record_id = 0;
	}

	free_health_app(app);
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH,
				HAL_OP_HEALTH_UNREG_APP, HAL_STATUS_SUCCESS);
}

static int get_prot_desc_entry(sdp_data_t *entry, int type, guint16 *val)
{
	sdp_data_t *iter;
	int proto;

	if (!entry || !SDP_IS_SEQ(entry->dtd))
		return -1;

	iter = entry->val.dataseq;
	if (!(iter->dtd & SDP_UUID_UNSPEC))
		return -1;

	proto = sdp_uuid_to_proto(&iter->val.uuid);
	if (proto != type)
		return -1;

	if (!val)
		return 0;

	iter = iter->next;
	if (iter->dtd != SDP_UINT16)
		return -1;

	*val = iter->val.uint16;

	return 0;
}

static int get_prot_desc_list(const sdp_record_t *rec, uint16_t *psm,
							uint16_t *version)
{
	sdp_data_t *pdl, *p0, *p1;

	if (!psm && !version)
		return -1;

	pdl = sdp_data_get(rec, SDP_ATTR_PROTO_DESC_LIST);
	if (!pdl || !SDP_IS_SEQ(pdl->dtd))
		return -1;

	p0 = pdl->val.dataseq;
	if (get_prot_desc_entry(p0, L2CAP_UUID, psm) < 0)
		return -1;

	p1 = p0->next;
	if (get_prot_desc_entry(p1, MCAP_CTRL_UUID, version) < 0)
		return -1;

	return 0;
}

static int get_ccpsm(sdp_list_t *recs, uint16_t *ccpsm)
{
	sdp_list_t *l;

	for (l = recs; l; l = l->next) {
		sdp_record_t *rec = l->data;

		if (!get_prot_desc_list(rec, ccpsm, NULL))
			return 0;
	}

	return -1;
}

static int get_add_prot_desc_list(const sdp_record_t *rec, uint16_t *psm)
{
	sdp_data_t *pdl, *p0, *p1;

	if (!psm)
		return -1;

	pdl = sdp_data_get(rec, SDP_ATTR_ADD_PROTO_DESC_LIST);
	if (!pdl || pdl->dtd != SDP_SEQ8)
		return -1;

	pdl = pdl->val.dataseq;
	if (pdl->dtd != SDP_SEQ8)
		return -1;

	p0 = pdl->val.dataseq;

	if (get_prot_desc_entry(p0, L2CAP_UUID, psm) < 0)
		return -1;

	p1 = p0->next;
	if (get_prot_desc_entry(p1, MCAP_DATA_UUID, NULL) < 0)
		return -1;

	return 0;
}

static int get_dcpsm(sdp_list_t *recs, uint16_t *dcpsm)
{
	sdp_list_t *l;

	for (l = recs; l; l = l->next) {
		sdp_record_t *rec = l->data;

		if (!get_add_prot_desc_list(rec, dcpsm))
			return 0;
	}

	return -1;
}

static int send_echo_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 gboolean serve_echo(GIOChannel *io, GIOCondition cond, gpointer data)
{
	struct health_channel *channel = data;
	uint8_t buf[MCAP_DC_MTU];
	int fd, len, ret;

	DBG("channel %p", channel);

	if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL)) {
		DBG("Error condition on channel");
		return FALSE;
	}

	fd = g_io_channel_unix_get_fd(io);

	len = read(fd, buf, sizeof(buf));
	if (len < 0) {
		DBG("Error reading ECHO");
		return FALSE;
	}

	ret = send_echo_data(fd, buf, len);
	if (ret != len)
		DBG("Error sending ECHO back");

	return FALSE;
}

static void mcap_mdl_connected_cb(struct mcap_mdl *mdl, void *data)
{
	struct health_channel *channel = data;
	int fd;

	DBG("Data channel connected: mdl %p channel %p", mdl, channel);

	if (!channel) {
		channel = search_channel_by_mdl(mdl);
		if (!channel) {
			error("health: channel data does not exist");
			return;
		}
	}

	if (!channel->mdl)
		channel->mdl = mcap_mdl_ref(mdl);

	fd = mcap_mdl_get_fd(channel->mdl);
	if (fd < 0) {
		error("health: error retrieving fd");
		goto fail;
	}

	if (channel->mdep_id == MDEP_ECHO) {
		GIOChannel *io;

		io = g_io_channel_unix_new(fd);
		g_io_add_watch(io, G_IO_ERR | G_IO_HUP | G_IO_NVAL | G_IO_IN,
							serve_echo, channel);
		g_io_channel_unref(io);

		return;
	}

	info("health: MDL connected");
	send_channel_state_notify(channel, HAL_HEALTH_CHANNEL_CONNECTED, fd);

	return;
fail:
	/* TODO: mcap_mdl_abort */
	destroy_channel(channel);
}

static void mcap_mdl_closed_cb(struct mcap_mdl *mdl, void *data)
{
	struct health_channel *channel = data;

	info("health: MDL closed");

	if (!channel)
		return;

	channel->mdl_conn = false;
}

static void mcap_mdl_deleted_cb(struct mcap_mdl *mdl, void *data)
{
	struct health_channel *channel;

	info("health: MDL deleted");

	channel = search_channel_by_mdl(mdl);
	if (!channel)
		return;

	DBG("channel %p mdl %p", channel, mdl);
	destroy_channel(channel);
}

static void mcap_mdl_aborted_cb(struct mcap_mdl *mdl, void *data)
{
	DBG("Not Implemeneted");
}

static struct health_device *create_device(struct health_app *app,
							const uint8_t *addr)
{
	struct health_device *dev;

	if (!app)
		return NULL;

	/* create device and push it to devices queue */
	dev = new0(struct health_device, 1);
	if (!dev)
		return NULL;

	android2bdaddr(addr, &dev->dst);
	dev->channels = queue_new();
	if (!dev->channels) {
		free_health_device(dev);
		return NULL;
	}

	if (!queue_push_tail(app->devices, dev)) {
		free_health_device(dev);
		return NULL;
	}

	dev->app_id = app->id;

	return dev;
}

static struct health_device *get_device(struct health_app *app,
							const uint8_t *addr)
{
	struct health_device *dev;
	bdaddr_t bdaddr;

	android2bdaddr(addr, &bdaddr);
	dev = queue_find(app->devices, match_dev_by_addr, &bdaddr);
	if (dev)
		return dev;

	return create_device(app, addr);
}

static struct health_channel *create_channel(struct health_app *app,
						uint8_t mdep_index,
						struct health_device *dev)
{
	struct mdep_cfg *mdep;
	struct health_channel *channel;
	static unsigned int channel_id = 1;

	DBG("mdep %u", mdep_index);

	if (!dev || !app)
		return NULL;

	mdep = queue_find(app->mdeps, match_mdep_by_id, INT_TO_PTR(mdep_index));
	if (!mdep) {
		if (mdep_index == MDEP_ECHO) {
			mdep = new0(struct mdep_cfg, 1);
			if (!mdep)
				return NULL;

			/* Leave other configuration zeroes */
			mdep->id = MDEP_ECHO;

			if (!queue_push_tail(app->mdeps, mdep)) {
				free_mdep_cfg(mdep);
				return NULL;
			}
		} else
			return NULL;
	}

	/* create channel and push it to device */
	channel = new0(struct health_channel, 1);
	if (!channel)
		return NULL;

	channel->mdep_id = mdep->id;
	channel->type = mdep->channel_type;
	channel->id = channel_id++;
	channel->dev = dev;

	if (!queue_push_tail(dev->channels, channel)) {
		free_health_channel(channel);
		return NULL;
	}

	return channel;
}

static struct health_channel *connect_channel(struct health_app *app,
							struct mcap_mcl *mcl,
							uint8_t mdepid)
{
	struct health_device *device;
	struct health_channel *channel = NULL;
	bdaddr_t addr;

	DBG("app %p mdepid %u", app, mdepid);

	mcap_mcl_get_addr(mcl, &addr);

	if (!app) {
		DBG("No app found for mdepid %u", mdepid);
		return NULL;
	}

	device = get_device(app, (uint8_t *) &addr);
	if (!device)
		return NULL;

	channel = create_channel(app, mdepid, device);

	return channel;
}

static uint8_t conf_to_l2cap(uint8_t conf)
{
	return conf == CHANNEL_TYPE_STREAM ? L2CAP_MODE_STREAMING :
								L2CAP_MODE_ERTM;
}

static uint8_t mcap_mdl_conn_req_cb(struct mcap_mcl *mcl, uint8_t mdepid,
				uint16_t mdlid, uint8_t *conf, void *data)
{
	GError *gerr = NULL;
	struct health_channel *channel;
	struct health_app *app;
	struct mdep_cfg *mdep;

	DBG("Data channel request: mdepid %u mdlid %u conf %u",
							mdepid, mdlid, *conf);

	if (mdepid == MDEP_ECHO)
		/* For echo service take last app */
		app = queue_peek_tail(apps);
	else
		app = search_app_by_mdepid(mdepid);

	if (!app)
		return MCAP_MDL_BUSY;

	channel = connect_channel(app, mcl, mdepid);
	if (!channel)
		return MCAP_MDL_BUSY;

	/* Channel is assigned here after creation */
	mcl->cb->user_data = channel;

	if (mdepid == MDEP_ECHO) {
		switch (*conf) {
		case CHANNEL_TYPE_ANY:
			*conf = CHANNEL_TYPE_RELIABLE;
			break;
		case CHANNEL_TYPE_RELIABLE:
			break;
		case CHANNEL_TYPE_STREAM:
			return MCAP_CONFIGURATION_REJECTED;
		default:
			/*
			 * Special case defined in HDP spec 3.4.
			 * When an invalid configuration is received we shall
			 * close the MCL when we are still processing the
			 * callback.
			 */
			/* TODO close device */
			return MCAP_CONFIGURATION_REJECTED; /* not processed */
		}

		if (!mcap_set_data_chan_mode(mcap, L2CAP_MODE_ERTM, &gerr)) {
			error("Error: %s", gerr->message);
			g_error_free(gerr);
			return MCAP_MDL_BUSY;
		}

		/* TODO: Create channel */

		return MCAP_SUCCESS;
	}

	mdep = queue_find(app->mdeps, match_mdep_by_id, INT_TO_PTR(mdepid));
	if (!mdep)
		return MCAP_MDL_BUSY;

	switch (*conf) {
	case CHANNEL_TYPE_ANY:
		if (mdep->role == HAL_HEALTH_MDEP_ROLE_SINK) {
			return MCAP_CONFIGURATION_REJECTED;
		} else {
			if (queue_length(channel->dev->channels) <= 1)
				*conf = CHANNEL_TYPE_RELIABLE;
			else
				*conf = CHANNEL_TYPE_STREAM;
		}
		break;
	case CHANNEL_TYPE_STREAM:
		if (mdep->role == HAL_HEALTH_MDEP_ROLE_SOURCE)
			return MCAP_CONFIGURATION_REJECTED;
		break;
	case CHANNEL_TYPE_RELIABLE:
		if (mdep->role == HAL_HEALTH_MDEP_ROLE_SOURCE)
			return MCAP_CONFIGURATION_REJECTED;
		break;
	default:
		/*
		 * Special case defined in HDP spec 3.4. When an invalid
		 * configuration is received we shall close the MCL when
		 * we are still processing the callback.
		 */
		/* TODO: close device */
		return MCAP_CONFIGURATION_REJECTED; /* not processed */
	}

	if (!mcap_set_data_chan_mode(mcap, conf_to_l2cap(*conf), &gerr)) {
		error("health: error setting L2CAP mode: %s", gerr->message);
		g_error_free(gerr);
		return MCAP_MDL_BUSY;
	}

	return MCAP_SUCCESS;
}

static uint8_t mcap_mdl_reconn_req_cb(struct mcap_mdl *mdl, void *data)
{
	struct health_channel *channel;
	GError *err = NULL;

	DBG("");

	channel = search_channel_by_mdl(mdl);
	if (!channel) {
		error("health: channel data does not exist");
		return MCAP_UNSPECIFIED_ERROR;
	}

	if (!mcap_set_data_chan_mode(mcap,
			conf_to_l2cap(channel->type), &err)) {
		error("health: %s", err->message);
		g_error_free(err);
		return MCAP_MDL_BUSY;
	}

	return MCAP_SUCCESS;
}

static void connect_mdl_cb(struct mcap_mdl *mdl, GError *gerr, gpointer data)
{
	struct health_channel *channel = data;
	int fd;

	DBG("");

	if (gerr) {
		error("health: error connecting to MDL %s", gerr->message);
		goto fail;
	}

	fd = mcap_mdl_get_fd(channel->mdl);
	if (fd < 0) {
		error("health: error retrieving fd");
		goto fail;
	}

	info("health: MDL connected");
	channel->mdl_conn = true;

	/* first data channel should be reliable data channel */
	if (!queue_length(channel->dev->channels))
		if (channel->type != CHANNEL_TYPE_RELIABLE)
			goto fail;

	send_channel_state_notify(channel, HAL_HEALTH_CHANNEL_CONNECTED, fd);

	return;

fail:
	/* TODO: mcap_mdl_abort */
	destroy_channel(channel);
}

static void reconnect_mdl_cb(struct mcap_mdl *mdl, GError *gerr, gpointer data)
{
	struct health_channel *channel = data;
	uint8_t mode;
	GError *err = NULL;

	DBG("");

	if (gerr) {
		error("health: error reconnecting to MDL %s", gerr->message);
		goto fail;
	}

	channel->mdl_id = mcap_mdl_get_mdlid(mdl);

	if (channel->type == CHANNEL_TYPE_RELIABLE)
		mode = L2CAP_MODE_ERTM;
	else
		mode = L2CAP_MODE_STREAMING;

	if (!mcap_connect_mdl(channel->mdl, mode, channel->dev->dcpsm,
						connect_mdl_cb, channel,
						NULL, &err)) {
		error("health: error connecting to mdl");
		g_error_free(err);
		goto fail;
	}

	return;

fail:
	/* TODO: mcap_mdl_abort */
	destroy_channel(channel);
}

static int reconnect_mdl(struct health_channel *channel)
{
	GError *gerr = NULL;

	DBG("");

	if (!channel)
		return -1;

	if (!mcap_reconnect_mdl(channel->mdl, reconnect_mdl_cb, channel,
								NULL, &gerr)){
		error("health: reconnect failed %s", gerr->message);
		destroy_channel(channel);
	}

	return 0;
}

static void create_mdl_cb(struct mcap_mdl *mdl, uint8_t type, GError *gerr,
								gpointer data)
{
	struct health_channel *channel = data;
	uint8_t mode;
	GError *err = NULL;

	DBG("");
	if (gerr) {
		error("health: error creating MDL %s", gerr->message);
		goto fail;
	}

	if (channel->type == CHANNEL_TYPE_ANY && type != CHANNEL_TYPE_ANY)
		channel->type = type;

	/*
	 * if requested channel type is not same as preferred
	 * channel type from remote device, then abort the connection.
	 */
	if (channel->type != type) {
		/* TODO: abort mdl */
		error("health: channel type requested %d preferred %d not same",
							channel->type, type);
		goto fail;
	}

	if (!channel->mdl)
		channel->mdl = mcap_mdl_ref(mdl);

	channel->type = type;
	channel->mdl_id = mcap_mdl_get_mdlid(mdl);

	if (channel->type == CHANNEL_TYPE_RELIABLE)
		mode = L2CAP_MODE_ERTM;
	else
		mode = L2CAP_MODE_STREAMING;

	if (!mcap_connect_mdl(channel->mdl, mode, channel->dev->dcpsm,
						connect_mdl_cb, channel,
						NULL, &err)) {
		error("health: error connecting to mdl");
		g_error_free(err);
		goto fail;
	}

	return;

fail:
	destroy_channel(channel);
}

static bool check_role(uint8_t rec_role, uint8_t app_role)
{
	if ((rec_role == HAL_HEALTH_MDEP_ROLE_SINK &&
			app_role == HAL_HEALTH_MDEP_ROLE_SOURCE) ||
			(rec_role == HAL_HEALTH_MDEP_ROLE_SOURCE &&
			app_role == HAL_HEALTH_MDEP_ROLE_SINK))
		return true;

	return false;
}

static bool get_mdep_from_rec(const sdp_record_t *rec, uint8_t role,
						uint16_t d_type, uint8_t *mdep)
{
	sdp_data_t *list, *feat;

	if (!mdep)
		return false;

	list = sdp_data_get(rec, SDP_ATTR_SUPPORTED_FEATURES_LIST);
	if (!list || !SDP_IS_SEQ(list->dtd))
		return false;

	for (feat = list->val.dataseq; feat; feat = feat->next) {
		sdp_data_t *data_type, *mdepid, *role_t;

		if (!SDP_IS_SEQ(feat->dtd))
			continue;

		mdepid = feat->val.dataseq;
		if (!mdepid)
			continue;

		data_type = mdepid->next;
		if (!data_type)
			continue;

		role_t = data_type->next;
		if (!role_t)
			continue;

		if (data_type->dtd != SDP_UINT16 || mdepid->dtd != SDP_UINT8 ||
						role_t->dtd != SDP_UINT8)
			continue;

		if (data_type->val.uint16 != d_type ||
					!check_role(role_t->val.uint8, role))
			continue;

		*mdep = mdepid->val.uint8;

		return true;
	}

	return false;
}

static bool get_remote_mdep(sdp_list_t *recs, struct health_channel *channel)
{
	struct health_app *app;
	struct mdep_cfg *mdep;
	uint8_t mdep_id;

	app = queue_find(apps, match_app_by_id,
					INT_TO_PTR(channel->dev->app_id));
	if (!app)
		return false;

	mdep = queue_find(app->mdeps, match_mdep_by_id,
						INT_TO_PTR(channel->mdep_id));
	if (!mdep)
		return false;

	if (!get_mdep_from_rec(recs->data, mdep->role, mdep->data_type,
								&mdep_id)) {
		error("health: no matching MDEP: %u", channel->mdep_id);
		return false;
	}

	channel->remote_mdep = mdep_id;
	return true;
}

static bool create_mdl(struct health_channel *channel)
{
	struct health_app *app;
	struct mdep_cfg *mdep;
	uint8_t type;
	GError *gerr = NULL;

	app = queue_find(apps, match_app_by_id,
					INT_TO_PTR(channel->dev->app_id));
	if (!app)
		return false;

	mdep = queue_find(app->mdeps, match_mdep_by_id,
						INT_TO_PTR(channel->mdep_id));
	if (!mdep)
		return false;

	if (mdep->role == HAL_HEALTH_MDEP_ROLE_SOURCE)
		type = channel->type;
	else
		type = CHANNEL_TYPE_ANY;

	if (!mcap_create_mdl(channel->dev->mcl, channel->remote_mdep,
				type, create_mdl_cb, channel, NULL, &gerr)) {
		error("health: error creating mdl %s", gerr->message);
		g_error_free(gerr);
		return false;
	}

	return true;
}

static bool set_mcl_cb(struct mcap_mcl *mcl, gpointer user_data, GError **err)
{
	return mcap_mcl_set_cb(mcl, user_data, err,
			MCAP_MDL_CB_CONNECTED, mcap_mdl_connected_cb,
			MCAP_MDL_CB_CLOSED, mcap_mdl_closed_cb,
			MCAP_MDL_CB_DELETED, mcap_mdl_deleted_cb,
			MCAP_MDL_CB_ABORTED, mcap_mdl_aborted_cb,
			MCAP_MDL_CB_REMOTE_CONN_REQ, mcap_mdl_conn_req_cb,
			MCAP_MDL_CB_REMOTE_RECONN_REQ, mcap_mdl_reconn_req_cb,
			MCAP_MDL_CB_INVALID);
}

static void create_mcl_cb(struct mcap_mcl *mcl, GError *err, gpointer data)
{
	struct health_channel *channel = data;
	gboolean ret;
	GError *gerr = NULL;

	DBG("");

	if (err) {
		error("health: error creating MCL : %s", err->message);
		goto fail;
	}

	if (!channel->dev->mcl)
		channel->dev->mcl = mcap_mcl_ref(mcl);

	info("health: MCL connected");

	ret = set_mcl_cb(channel->dev->mcl, channel, &gerr);
	if (!ret) {
		error("health: error setting mdl callbacks: %s", gerr->message);
		g_error_free(gerr);
		goto fail;
	}

	if (!create_mdl(channel))
		goto fail;

	return;

fail:
	destroy_channel(channel);
}

static void search_cb(sdp_list_t *recs, int err, gpointer data)
{
	struct health_channel *channel = data;
	GError *gerr = NULL;

	DBG("");

	if (err < 0 || !recs) {
		error("health: Error getting remote SDP records");
		goto fail;
	}

	if (get_ccpsm(recs, &channel->dev->ccpsm) < 0) {
		error("health: Can't get remote PSM for control channel");
		goto fail;
	}

	if (get_dcpsm(recs, &channel->dev->dcpsm) < 0) {
		error("health: Can't get remote PSM for data channel");
		goto fail;
	}

	if (!get_remote_mdep(recs, channel)) {
		error("health: Can't get remote MDEP data");
		goto fail;
	}

	if (!mcap_create_mcl(mcap, &channel->dev->dst, channel->dev->ccpsm,
					create_mcl_cb, channel, NULL, &gerr)) {
		error("health: error creating mcl %s", gerr->message);
		g_error_free(gerr);
		goto fail;
	}

	return;

fail:
	destroy_channel(channel);
}

static int connect_mcl(struct health_channel *channel)
{
	uuid_t uuid;
	int err;

	DBG("");

	bt_string2uuid(&uuid, HDP_UUID);

	err = bt_search_service(&adapter_addr, &channel->dev->dst, &uuid,
						search_cb, channel, NULL, 0);
	if (!err)
		send_channel_state_notify(channel,
					HAL_HEALTH_CHANNEL_CONNECTING, -1);

	return err;
}

static struct health_app *get_app(uint16_t app_id)
{
	return queue_find(apps, match_app_by_id, INT_TO_PTR(app_id));
}

static struct health_channel *get_channel(struct health_app *app,
						uint8_t mdep_index,
						struct health_device *dev)
{
	struct health_channel *channel;
	uint8_t index;

	if (!dev)
		return NULL;

	index = mdep_index + 1;
	channel = queue_find(dev->channels, match_channel_by_mdep_id,
							INT_TO_PTR(index));
	if (channel)
		return channel;

	return create_channel(app, index, dev);
}

static void bt_health_connect_channel(const void *buf, uint16_t len)
{
	const struct hal_cmd_health_connect_channel *cmd = buf;
	struct hal_rsp_health_connect_channel rsp;
	struct health_device *dev = NULL;
	struct health_channel *channel = NULL;
	struct health_app *app;

	DBG("");

	app = get_app(cmd->app_id);
	if (!app)
		goto send_rsp;

	dev = get_device(app, cmd->bdaddr);
	if (!dev)
		goto send_rsp;

	channel = get_channel(app, cmd->mdep_index, dev);
	if (!channel)
		goto send_rsp;

	if (!queue_length(dev->channels)) {
		if (channel->type != CHANNEL_TYPE_RELIABLE) {
			error("health: first data shannel should be reliable");
			goto fail;
		}
	}

	if (!dev->mcl) {
		if (connect_mcl(channel) < 0) {
			error("health: error retrieving HDP SDP record");
			goto fail;
		}
	} else {
		/* data channel is already connected */
		if (channel->mdl && channel->mdl_conn)
			goto fail;

		/* create mdl if it does not exists */
		if (!channel->mdl && !create_mdl(channel))
			goto fail;

		/* reconnect mdl if it exists */
		if (channel->mdl && !channel->mdl_conn) {
			if (reconnect_mdl(channel) < 0)
				goto fail;
		}

	}

	rsp.channel_id = channel->id;
	ipc_send_rsp_full(hal_ipc, HAL_SERVICE_ID_HEALTH,
				HAL_OP_HEALTH_CONNECT_CHANNEL,
				sizeof(rsp), &rsp, -1);
	return;

fail:
	queue_remove(channel->dev->channels, channel);
	free_health_channel(channel);

send_rsp:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH,
			HAL_OP_HEALTH_CONNECT_CHANNEL, HAL_STATUS_FAILED);
}

static void channel_delete_cb(GError *gerr, gpointer data)
{
	struct health_channel *channel = data;

	DBG("");

	if (gerr) {
		error("health: channel delete failed %s", gerr->message);
		return;
	}

	destroy_channel(channel);
}

static void bt_health_destroy_channel(const void *buf, uint16_t len)
{
	const struct hal_cmd_health_destroy_channel *cmd = buf;
	struct health_channel *channel;
	GError *gerr = NULL;

	DBG("");

	channel = search_channel_by_id(cmd->channel_id);
	if (!channel)
		goto fail;

	if (!mcap_delete_mdl(channel->mdl, channel_delete_cb, channel,
							NULL, &gerr)) {
		error("health: channel delete failed %s", gerr->message);
		goto fail;
	}

	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH,
			HAL_OP_HEALTH_DESTROY_CHANNEL, HAL_STATUS_SUCCESS);

	return;

fail:
	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_HEALTH,
			HAL_OP_HEALTH_DESTROY_CHANNEL, HAL_STATUS_INVALID);
}

static const struct ipc_handler cmd_handlers[] = {
	/* HAL_OP_HEALTH_REG_APP */
	{ bt_health_register_app, true,
				sizeof(struct hal_cmd_health_reg_app) },
	/* HAL_OP_HEALTH_MDEP */
	{ bt_health_mdep_cfg_data, true,
				sizeof(struct hal_cmd_health_mdep) },
	/* HAL_OP_HEALTH_UNREG_APP */
	{ bt_health_unregister_app, false,
				sizeof(struct hal_cmd_health_unreg_app) },
	/* HAL_OP_HEALTH_CONNECT_CHANNEL */
	{ bt_health_connect_channel, false,
				sizeof(struct hal_cmd_health_connect_channel) },
	/* HAL_OP_HEALTH_DESTROY_CHANNEL */
	{ bt_health_destroy_channel, false,
				sizeof(struct hal_cmd_health_destroy_channel) },
};

static void mcl_connected(struct mcap_mcl *mcl, gpointer data)
{
	GError *gerr = NULL;
	bool ret;

	DBG("");

	info("health: MCL connected");
	ret = set_mcl_cb(mcl, NULL, &gerr);
	if (!ret) {
		error("health: error setting mcl callbacks: %s", gerr->message);
		g_error_free(gerr);
	}
}

static void mcl_reconnected(struct mcap_mcl *mcl, gpointer data)
{
	struct health_device *dev;

	DBG("");

	info("health: MCL reconnected");
	dev = search_dev_by_mcl(mcl);
	if (!dev) {
		error("device data does not exists");
		return;
	}
}

static void mcl_disconnected(struct mcap_mcl *mcl, gpointer data)
{
	struct health_device *dev;

	DBG("");

	info("health: MCL disconnected");
	dev = search_dev_by_mcl(mcl);
	unref_mcl(dev);
}

static void mcl_uncached(struct mcap_mcl *mcl, gpointer data)
{
	/* mcap library maintains cache of mcls, not required here */
}

bool bt_health_register(struct ipc *ipc, const bdaddr_t *addr, uint8_t mode)
{
	GError *err = NULL;

	DBG("");

	bacpy(&adapter_addr, addr);

	mcap = mcap_create_instance(&adapter_addr, BT_IO_SEC_MEDIUM, 0, 0,
					mcl_connected, mcl_reconnected,
					mcl_disconnected, mcl_uncached,
					NULL, /* CSP is not used right now */
					NULL, &err);
	if (!mcap) {
		error("health: MCAP instance creation failed %s", err->message);
		g_error_free(err);
		return false;
	}

	hal_ipc = ipc;
	apps = queue_new();
	if (!apps)
		return false;

	ipc_register(hal_ipc, HAL_SERVICE_ID_HEALTH, cmd_handlers,
						G_N_ELEMENTS(cmd_handlers));

	return true;
}

void bt_health_unregister(void)
{
	DBG("");

	mcap_instance_unref(mcap);
	queue_destroy(apps, free_health_app);
	ipc_unregister(hal_ipc, HAL_SERVICE_ID_HEALTH);
	hal_ipc = NULL;
}
