/*
 *
 *  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
 *
 */

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

#include <stdint.h>
#include <stdbool.h>

#include <glib.h>

#include <gdbus/gdbus.h>

#include <adapter.h>
#include <device.h>

#include <sdpd.h>
#include <bluetooth/sdp_lib.h>
#include <sdp-client.h>
#include <glib-helper.h>

#include "lib/uuid.h"
#include "btio/btio.h"

#include "log.h"

#include "dbus-common.h"
#include "mcap.h"
#include "mcap_lib.h"
#include "hdp_types.h"
#include "hdp.h"
#include "hdp_util.h"

typedef gboolean (*parse_item_f)(DBusMessageIter *iter, gpointer user_data,
								GError **err);

struct dict_entry_func {
	char		*key;
	parse_item_f	func;
};

struct get_mdep_data {
	struct hdp_application	*app;
	gpointer		data;
	hdp_continue_mdep_f	func;
	GDestroyNotify		destroy;
};

struct conn_mcl_data {
	int			refs;
	gpointer		data;
	hdp_continue_proc_f	func;
	GDestroyNotify		destroy;
	struct hdp_device	*dev;
};

struct get_dcpsm_data {
	gpointer		data;
	hdp_continue_dcpsm_f	func;
	GDestroyNotify		destroy;
};

static gboolean parse_dict_entry(struct dict_entry_func dict_context[],
							DBusMessageIter *iter,
							GError **err,
							gpointer user_data)
{
	DBusMessageIter entry;
	char *key;
	int ctype, i;
	struct dict_entry_func df;

	dbus_message_iter_recurse(iter, &entry);
	ctype = dbus_message_iter_get_arg_type(&entry);
	if (ctype != DBUS_TYPE_STRING) {
		g_set_error(err, HDP_ERROR, HDP_DIC_ENTRY_PARSE_ERROR,
			"Dictionary entries should have a string as key");
		return FALSE;
	}

	dbus_message_iter_get_basic(&entry, &key);
	dbus_message_iter_next(&entry);
	/* Find function and call it */
	for (i = 0, df = dict_context[0]; df.key; i++, df = dict_context[i]) {
		if (g_ascii_strcasecmp(df.key, key) == 0)
			return df.func(&entry, user_data, err);
	}

	g_set_error(err, HDP_ERROR, HDP_DIC_ENTRY_PARSE_ERROR,
			"No function found for parsing value for key %s", key);
	return FALSE;
}

static gboolean parse_dict(struct dict_entry_func dict_context[],
							DBusMessageIter *iter,
							GError **err,
							gpointer user_data)
{
	int ctype;
	DBusMessageIter dict;

	ctype = dbus_message_iter_get_arg_type(iter);
	if (ctype != DBUS_TYPE_ARRAY) {
		g_set_error(err, HDP_ERROR, HDP_DIC_PARSE_ERROR,
					"Dictionary should be an array");
		return FALSE;
	}

	dbus_message_iter_recurse(iter, &dict);
	while ((ctype = dbus_message_iter_get_arg_type(&dict)) !=
							DBUS_TYPE_INVALID) {
		if (ctype != DBUS_TYPE_DICT_ENTRY) {
			g_set_error(err, HDP_ERROR, HDP_DIC_PARSE_ERROR,
						"Dictionary array should "
						"contain dict entries");
			return FALSE;
		}

		/* Start parsing entry */
		if (!parse_dict_entry(dict_context, &dict, err,
							user_data))
			return FALSE;
		/* Finish entry parsing */

		dbus_message_iter_next(&dict);
	}

	return TRUE;
}

static gboolean parse_data_type(DBusMessageIter *iter, gpointer data,
								GError **err)
{
	struct hdp_application *app = data;
	DBusMessageIter *value;
	DBusMessageIter variant;
	int ctype;

	ctype = dbus_message_iter_get_arg_type(iter);
	value = iter;
	if (ctype == DBUS_TYPE_VARIANT) {
		/* Get value inside the variable */
		dbus_message_iter_recurse(iter, &variant);
		ctype = dbus_message_iter_get_arg_type(&variant);
		value = &variant;
	}

	if (ctype != DBUS_TYPE_UINT16) {
		g_set_error(err, HDP_ERROR, HDP_DIC_ENTRY_PARSE_ERROR,
			"Final value for data type should be uint16");
		return FALSE;
	}

	dbus_message_iter_get_basic(value, &app->data_type);
	app->data_type_set = TRUE;
	return TRUE;
}

static gboolean parse_role(DBusMessageIter *iter, gpointer data, GError **err)
{
	struct hdp_application *app = data;
	DBusMessageIter *string;
	DBusMessageIter value;
	int ctype;
	const char *role;

	ctype = dbus_message_iter_get_arg_type(iter);
	if (ctype == DBUS_TYPE_VARIANT) {
		/* Get value inside the variable */
		dbus_message_iter_recurse(iter, &value);
		ctype = dbus_message_iter_get_arg_type(&value);
		string = &value;
	} else {
		string = iter;
	}

	if (ctype != DBUS_TYPE_STRING) {
		g_set_error(err, HDP_ERROR, HDP_UNSPECIFIED_ERROR,
				"Value data spec should be variable or string");
		return FALSE;
	}

	dbus_message_iter_get_basic(string, &role);
	if (g_ascii_strcasecmp(role, HDP_SINK_ROLE_AS_STRING) == 0) {
		app->role = HDP_SINK;
	} else if (g_ascii_strcasecmp(role, HDP_SOURCE_ROLE_AS_STRING) == 0) {
		app->role = HDP_SOURCE;
	} else {
		g_set_error(err, HDP_ERROR, HDP_UNSPECIFIED_ERROR,
			"Role value should be \"source\" or \"sink\"");
		return FALSE;
	}

	app->role_set = TRUE;

	return TRUE;
}

static gboolean parse_desc(DBusMessageIter *iter, gpointer data, GError **err)
{
	struct hdp_application *app = data;
	DBusMessageIter *string;
	DBusMessageIter variant;
	int ctype;
	const char *desc;

	ctype = dbus_message_iter_get_arg_type(iter);
	if (ctype == DBUS_TYPE_VARIANT) {
		/* Get value inside the variable */
		dbus_message_iter_recurse(iter, &variant);
		ctype = dbus_message_iter_get_arg_type(&variant);
		string = &variant;
	} else {
		string = iter;
	}

	if (ctype != DBUS_TYPE_STRING) {
		g_set_error(err, HDP_ERROR, HDP_DIC_ENTRY_PARSE_ERROR,
				"Value data spec should be variable or string");
		return FALSE;
	}

	dbus_message_iter_get_basic(string, &desc);
	app->description = g_strdup(desc);
	return TRUE;
}

static gboolean parse_chan_type(DBusMessageIter *iter, gpointer data,
								GError **err)
{
	struct hdp_application *app = data;
	DBusMessageIter *value;
	DBusMessageIter variant;
	char *chan_type;
	int ctype;

	ctype = dbus_message_iter_get_arg_type(iter);
	value = iter;
	if (ctype == DBUS_TYPE_VARIANT) {
		/* Get value inside the variable */
		dbus_message_iter_recurse(iter, &variant);
		ctype = dbus_message_iter_get_arg_type(&variant);
		value = &variant;
	}

	if (ctype != DBUS_TYPE_STRING) {
		g_set_error(err, HDP_ERROR, HDP_DIC_ENTRY_PARSE_ERROR,
			"Final value for channel type should be an string");
		return FALSE;
	}

	dbus_message_iter_get_basic(value, &chan_type);

	if (g_ascii_strcasecmp("reliable", chan_type) == 0)
		app->chan_type = HDP_RELIABLE_DC;
	else if (g_ascii_strcasecmp("streaming", chan_type) == 0)
		app->chan_type = HDP_STREAMING_DC;
	else {
		g_set_error(err, HDP_ERROR, HDP_DIC_ENTRY_PARSE_ERROR,
						"Invalid value for data type");
		return FALSE;
	}

	app->chan_type_set = TRUE;

	return TRUE;
}

static struct dict_entry_func dict_parser[] = {
	{"DataType",		parse_data_type},
	{"Role",		parse_role},
	{"Description",		parse_desc},
	{"ChannelType",		parse_chan_type},
	{NULL, NULL}
};

struct hdp_application *hdp_get_app_config(DBusMessageIter *iter, GError **err)
{
	struct hdp_application *app;

	app = g_new0(struct hdp_application, 1);
	app->ref = 1;
	if (!parse_dict(dict_parser, iter, err, app))
		goto fail;
	if (!app->data_type_set || !app->role_set) {
		g_set_error(err, HDP_ERROR, HDP_DIC_PARSE_ERROR,
						"Mandatory fields aren't set");
		goto fail;
	}
	return app;

fail:
	hdp_application_unref(app);
	return NULL;
}

static gboolean is_app_role(GSList *app_list, HdpRole role)
{
	GSList *l;

	for (l = app_list; l; l = l->next) {
		struct hdp_application *app = l->data;

		if (app->role == role)
			return TRUE;
	}

	return FALSE;
}

static gboolean set_sdp_services_uuid(sdp_record_t *record, HdpRole role)
{
	uuid_t svc_uuid_source, svc_uuid_sink;
	sdp_list_t *svc_list = NULL;

	sdp_uuid16_create(&svc_uuid_sink, HDP_SINK_SVCLASS_ID);
	sdp_uuid16_create(&svc_uuid_source, HDP_SOURCE_SVCLASS_ID);

	sdp_get_service_classes(record, &svc_list);

	if (role == HDP_SOURCE) {
		if (!sdp_list_find(svc_list, &svc_uuid_source, sdp_uuid_cmp))
			svc_list = sdp_list_append(svc_list, &svc_uuid_source);
	} else if (role == HDP_SINK) {
		if (!sdp_list_find(svc_list, &svc_uuid_sink, sdp_uuid_cmp))
			svc_list = sdp_list_append(svc_list, &svc_uuid_sink);
	}

	if (sdp_set_service_classes(record, svc_list) < 0) {
		sdp_list_free(svc_list, NULL);
		return FALSE;
	}

	sdp_list_free(svc_list, NULL);

	return TRUE;
}

static gboolean register_service_protocols(struct hdp_adapter *adapter,
						sdp_record_t *sdp_record)
{
	gboolean ret;
	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;
	uint16_t version = MCAP_VERSION;

	/* set l2cap information */
	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
	l2cap_list = sdp_list_append(NULL, &l2cap_uuid);
	if (l2cap_list == NULL) {
		ret = FALSE;
		goto end;
	}

	psm = sdp_data_alloc(SDP_UINT16, &adapter->ccpsm);
	if (psm == NULL) {
		ret = FALSE;
		goto end;
	}

	if (sdp_list_append(l2cap_list, psm) == NULL) {
		ret = FALSE;
		goto end;
	}

	proto_list = sdp_list_append(NULL, l2cap_list);
	if (proto_list == NULL) {
		ret = FALSE;
		goto end;
	}

	/* set mcap information */
	sdp_uuid16_create(&mcap_c_uuid, MCAP_CTRL_UUID);
	mcap_list = sdp_list_append(NULL, &mcap_c_uuid);
	if (mcap_list == NULL) {
		ret = FALSE;
		goto end;
	}

	mcap_ver = sdp_data_alloc(SDP_UINT16, &version);
	if (mcap_ver == NULL) {
		ret = FALSE;
		goto end;
	}

	if (sdp_list_append(mcap_list, mcap_ver) == NULL) {
		ret = FALSE;
		goto end;
	}

	if (sdp_list_append(proto_list, mcap_list) == NULL) {
		ret = FALSE;
		goto end;
	}

	/* attach protocol information to service record */
	access_proto_list = sdp_list_append(NULL, proto_list);
	if (access_proto_list == NULL) {
		ret = FALSE;
		goto end;
	}

	if (sdp_set_access_protos(sdp_record, access_proto_list) < 0) {
		ret = FALSE;
		goto end;
	}
	ret = TRUE;

end:
	if (l2cap_list != NULL)
		sdp_list_free(l2cap_list, NULL);
	if (mcap_list != NULL)
		sdp_list_free(mcap_list, NULL);
	if (proto_list != NULL)
		sdp_list_free(proto_list, NULL);
	if (access_proto_list != NULL)
		sdp_list_free(access_proto_list, NULL);
	if (psm != NULL)
		sdp_data_free(psm);
	if (mcap_ver != NULL)
		sdp_data_free(mcap_ver);

	return ret;
}

static gboolean register_service_profiles(sdp_record_t *sdp_record)
{
	gboolean ret;
	sdp_list_t *profile_list;
	sdp_profile_desc_t hdp_profile;

	/* 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 == NULL)
		return FALSE;

	/* set profile descriptor list */
	if (sdp_set_profile_descs(sdp_record, profile_list) < 0)
		ret = FALSE;
	else
		ret = TRUE;

	sdp_list_free(profile_list, NULL);

	return ret;
}

static gboolean register_service_additional_protocols(
						struct hdp_adapter *adapter,
						sdp_record_t *sdp_record)
{
	gboolean ret;
	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;

	/* set l2cap information */
	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
	l2cap_list = sdp_list_append(NULL, &l2cap_uuid);
	if (l2cap_list == NULL) {
		ret = FALSE;
		goto end;
	}

	psm = sdp_data_alloc(SDP_UINT16, &adapter->dcpsm);
	if (psm == NULL) {
		ret = FALSE;
		goto end;
	}

	if (sdp_list_append(l2cap_list, psm) == NULL) {
		ret = FALSE;
		goto end;
	}

	proto_list = sdp_list_append(NULL, l2cap_list);
	if (proto_list == NULL) {
		ret = FALSE;
		goto end;
	}

	/* set mcap information */
	sdp_uuid16_create(&mcap_d_uuid, MCAP_DATA_UUID);
	mcap_list = sdp_list_append(NULL, &mcap_d_uuid);
	if (mcap_list == NULL) {
		ret = FALSE;
		goto end;
	}

	if (sdp_list_append(proto_list, mcap_list) == NULL) {
		ret = FALSE;
		goto end;
	}

	/* attach protocol information to service record */
	access_proto_list = sdp_list_append(NULL, proto_list);
	if (access_proto_list == NULL) {
		ret = FALSE;
		goto end;
	}

	if (sdp_set_add_access_protos(sdp_record, access_proto_list) < 0)
		ret = FALSE;
	else
		ret = TRUE;

end:
	if (l2cap_list != NULL)
		sdp_list_free(l2cap_list, NULL);
	if (mcap_list != NULL)
		sdp_list_free(mcap_list, NULL);
	if (proto_list  != NULL)
		sdp_list_free(proto_list, NULL);
	if (access_proto_list != NULL)
		sdp_list_free(access_proto_list, NULL);
	if (psm != NULL)
		sdp_data_free(psm);

	return ret;
}

static sdp_list_t *app_to_sdplist(struct hdp_application *app)
{
	sdp_data_t *mdepid,
		*dtype = NULL,
		*role = NULL,
		*desc = NULL;
	sdp_list_t *f_list = NULL;

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

	dtype = sdp_data_alloc(SDP_UINT16, &app->data_type);
	if (dtype == NULL)
		goto fail;

	role = sdp_data_alloc(SDP_UINT8, &app->role);
	if (role == NULL)
		goto fail;

	if (app->description != NULL) {
		desc = sdp_data_alloc(SDP_TEXT_STR8, app->description);
		if (desc == NULL)
			goto fail;
	}

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

	if (sdp_list_append(f_list, dtype) == NULL)
		goto fail;

	if (sdp_list_append(f_list, role) == NULL)
		goto fail;

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

	return f_list;

fail:
	if (f_list != NULL)
		sdp_list_free(f_list, NULL);
	if (mdepid != NULL)
		sdp_data_free(mdepid);
	if (dtype != NULL)
		sdp_data_free(dtype);
	if (role != NULL)
		sdp_data_free(role);
	if (desc != NULL)
		sdp_data_free(desc);

	return NULL;
}

static gboolean register_features(struct hdp_application *app,
						sdp_list_t **sup_features)
{
	sdp_list_t *hdp_feature;

	hdp_feature = app_to_sdplist(app);
	if (hdp_feature == NULL)
		goto fail;

	if (*sup_features == NULL) {
		*sup_features = sdp_list_append(NULL, hdp_feature);
		if (*sup_features == NULL)
			goto fail;
	} else if (sdp_list_append(*sup_features, hdp_feature) == NULL) {
		goto fail;
	}

	return TRUE;

fail:
	if (hdp_feature != NULL)
		sdp_list_free(hdp_feature, (sdp_free_func_t)sdp_data_free);
	return FALSE;
}

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 gboolean register_service_sup_features(GSList *app_list,
						sdp_record_t *sdp_record)
{
	GSList *l;
	sdp_list_t *sup_features = NULL;

	for (l = app_list; l; l = l->next) {
		if (!register_features(l->data, &sup_features))
			return FALSE;
	}

	if (sdp_set_supp_feat(sdp_record, sup_features) < 0) {
		sdp_list_free(sup_features, free_hdp_list);
		return FALSE;
	}

	return TRUE;
}

static gboolean register_data_exchange_spec(sdp_record_t *record)
{
	sdp_data_t *spec;
	uint8_t data_spec = DATA_EXCHANGE_SPEC_11073;
	/* As by now 11073 is the only supported we set it by default */

	spec = sdp_data_alloc(SDP_UINT8, &data_spec);
	if (spec == NULL)
		return FALSE;

	if (sdp_attr_add(record, SDP_ATTR_DATA_EXCHANGE_SPEC, spec) < 0) {
		sdp_data_free(spec);
		return FALSE;
	}

	return TRUE;
}

static gboolean register_mcap_features(sdp_record_t *sdp_record)
{
	sdp_data_t *mcap_proc;
	uint8_t mcap_sup_proc = MCAP_SUP_PROC;

	mcap_proc = sdp_data_alloc(SDP_UINT8, &mcap_sup_proc);
	if (mcap_proc == NULL)
		return FALSE;

	if (sdp_attr_add(sdp_record, SDP_ATTR_MCAP_SUPPORTED_PROCEDURES,
							mcap_proc) < 0) {
		sdp_data_free(mcap_proc);
		return FALSE;
	}

	return TRUE;
}

gboolean hdp_update_sdp_record(struct hdp_adapter *adapter, GSList *app_list)
{
	sdp_record_t *sdp_record;

	if (adapter->sdp_handler > 0)
		adapter_service_remove(adapter->btd_adapter,
					adapter->sdp_handler);

	if (app_list == NULL) {
		adapter->sdp_handler = 0;
		return TRUE;
	}

	sdp_record = sdp_record_alloc();
	if (sdp_record == NULL)
		return FALSE;

	if (adapter->sdp_handler > 0)
		sdp_record->handle = adapter->sdp_handler;
	else
		sdp_record->handle = 0xffffffff; /* Set automatically */

	if (is_app_role(app_list, HDP_SINK))
		set_sdp_services_uuid(sdp_record, HDP_SINK);
	if (is_app_role(app_list, HDP_SOURCE))
		set_sdp_services_uuid(sdp_record, HDP_SOURCE);

	if (!register_service_protocols(adapter, sdp_record))
		goto fail;
	if (!register_service_profiles(sdp_record))
		goto fail;
	if (!register_service_additional_protocols(adapter, sdp_record))
		goto fail;

	sdp_set_info_attr(sdp_record, HDP_SERVICE_NAME, HDP_SERVICE_PROVIDER,
							HDP_SERVICE_DSC);
	if (!register_service_sup_features(app_list, sdp_record))
		goto fail;
	if (!register_data_exchange_spec(sdp_record))
		goto fail;

	register_mcap_features(sdp_record);

	if (sdp_set_record_state(sdp_record, adapter->record_state++) < 0)
		goto fail;

	if (adapter_service_add(adapter->btd_adapter, sdp_record) < 0)
		goto fail;
	adapter->sdp_handler = sdp_record->handle;
	return TRUE;

fail:
	if (sdp_record != NULL)
		sdp_record_free(sdp_record);
	return FALSE;
}

static gboolean check_role(uint8_t rec_role, uint8_t app_role)
{
	if ((rec_role == HDP_SINK && app_role == HDP_SOURCE) ||
			(rec_role == HDP_SOURCE && app_role == HDP_SINK))
		return TRUE;

	return FALSE;
}

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

	if (desc == NULL && mdep == NULL)
		return TRUE;

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

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

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

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

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

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

		desc_t = role_t->next;

		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;

		if (mdep != NULL)
			*mdep = mdepid->val.uint8;

		if (desc != NULL && desc_t != NULL &&
						SDP_IS_TEXT_STR(desc_t->dtd))
			*desc = g_strdup(desc_t->val.str);

		return TRUE;
	}

	return FALSE;
}

static void get_mdep_cb(sdp_list_t *recs, int err, gpointer user_data)
{
	struct get_mdep_data *mdep_data = user_data;
	GError *gerr = NULL;
	uint8_t mdep;

	if (err < 0 || recs == NULL) {
		g_set_error(&gerr, HDP_ERROR, HDP_CONNECTION_ERROR,
					"Error getting remote SDP records");
		mdep_data->func(0, mdep_data->data, gerr);
		g_error_free(gerr);
		return;
	}

	if (!get_mdep_from_rec(recs->data, mdep_data->app->role,
				mdep_data->app->data_type, &mdep, NULL)) {
		g_set_error(&gerr, HDP_ERROR, HDP_CONNECTION_ERROR,
					"No matching MDEP found");
		mdep_data->func(0, mdep_data->data, gerr);
		g_error_free(gerr);
		return;
	}

	mdep_data->func(mdep, mdep_data->data, NULL);
}

static void free_mdep_data(gpointer data)
{
	struct get_mdep_data *mdep_data = data;

	if (mdep_data->destroy)
		mdep_data->destroy(mdep_data->data);
	hdp_application_unref(mdep_data->app);

	g_free(mdep_data);
}

gboolean hdp_get_mdep(struct hdp_device *device, struct hdp_application *app,
				hdp_continue_mdep_f func, gpointer data,
				GDestroyNotify destroy, GError **err)
{
	struct get_mdep_data *mdep_data;
	const bdaddr_t *src;
	const bdaddr_t *dst;
	uuid_t uuid;

	src = btd_adapter_get_address(device_get_adapter(device->dev));
	dst = device_get_address(device->dev);

	mdep_data = g_new0(struct get_mdep_data, 1);
	mdep_data->app = hdp_application_ref(app);
	mdep_data->func = func;
	mdep_data->data = data;
	mdep_data->destroy = destroy;

	bt_string2uuid(&uuid, HDP_UUID);
	if (bt_search_service(src, dst, &uuid, get_mdep_cb, mdep_data,
						free_mdep_data, 0) < 0) {
		g_set_error(err, HDP_ERROR, HDP_CONNECTION_ERROR,
						"Can't get remote SDP record");
		g_free(mdep_data);
		return FALSE;
	}

	return TRUE;
}

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

	if (entry == NULL || !SDP_IS_SEQ(entry->dtd))
		return FALSE;

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

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

	if (val == NULL)
		return TRUE;

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

	*val = iter->val.uint16;

	return TRUE;
}

static gboolean hdp_get_prot_desc_list(const sdp_record_t *rec, guint16 *psm,
							guint16 *version)
{
	sdp_data_t *pdl, *p0, *p1;

	if (psm == NULL && version == NULL)
		return TRUE;

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

	p0 = pdl->val.dataseq;
	if (!get_prot_desc_entry(p0, L2CAP_UUID, psm))
		return FALSE;

	p1 = p0->next;
	if (!get_prot_desc_entry(p1, MCAP_CTRL_UUID, version))
		return FALSE;

	return TRUE;
}

static gboolean hdp_get_add_prot_desc_list(const sdp_record_t *rec,
								guint16 *psm)
{
	sdp_data_t *pdl, *p0, *p1;

	if (psm == NULL)
		return TRUE;

	pdl = sdp_data_get(rec, SDP_ATTR_ADD_PROTO_DESC_LIST);
	if (pdl == NULL || pdl->dtd != SDP_SEQ8)
		return FALSE;
	pdl = pdl->val.dataseq;
	if (pdl->dtd != SDP_SEQ8)
		return FALSE;

	p0 = pdl->val.dataseq;

	if (!get_prot_desc_entry(p0, L2CAP_UUID, psm))
		return FALSE;
	p1 = p0->next;
	if (!get_prot_desc_entry(p1, MCAP_DATA_UUID, NULL))
		return FALSE;

	return TRUE;
}

static gboolean 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 (hdp_get_prot_desc_list(rec, ccpsm, NULL))
			return TRUE;
	}

	return FALSE;
}

static gboolean 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 (hdp_get_add_prot_desc_list(rec, dcpsm))
			return TRUE;
	}

	return FALSE;
}

static void con_mcl_data_unref(struct conn_mcl_data *conn_data)
{
	if (conn_data == NULL)
		return;

	if (--conn_data->refs > 0)
		return;

	if (conn_data->destroy)
		conn_data->destroy(conn_data->data);

	health_device_unref(conn_data->dev);
	g_free(conn_data);
}

static void destroy_con_mcl_data(gpointer data)
{
	con_mcl_data_unref(data);
}

static struct conn_mcl_data *con_mcl_data_ref(struct conn_mcl_data *conn_data)
{
	if (conn_data == NULL)
		return NULL;

	conn_data->refs++;
	return conn_data;
}

static void create_mcl_cb(struct mcap_mcl *mcl, GError *err, gpointer data)
{
	struct conn_mcl_data *conn_data = data;
	struct hdp_device *device = conn_data->dev;
	GError *gerr = NULL;

	if (err != NULL) {
		conn_data->func(conn_data->data, err);
		return;
	}

	if (device->mcl == NULL)
		device->mcl = mcap_mcl_ref(mcl);
	device->mcl_conn = TRUE;

	hdp_set_mcl_cb(device, &gerr);

	conn_data->func(conn_data->data, gerr);
	if (gerr != NULL)
		g_error_free(gerr);
}

static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
{
	struct conn_mcl_data *conn_data = user_data;
	GError *gerr = NULL;
	uint16_t ccpsm;

	if (conn_data->dev->hdp_adapter->mi == NULL) {
		g_set_error(&gerr, HDP_ERROR, HDP_CONNECTION_ERROR,
						"Mcap instance released");
		goto fail;
	}

	if (err < 0 || recs == NULL) {
		g_set_error(&gerr, HDP_ERROR, HDP_CONNECTION_ERROR,
					"Error getting remote SDP records");
		goto fail;
	}

	if (!get_ccpsm(recs, &ccpsm)) {
		g_set_error(&gerr, HDP_ERROR, HDP_CONNECTION_ERROR,
				"Can't get remote PSM for control channel");
		goto fail;
	}

	conn_data = con_mcl_data_ref(conn_data);

	if (!mcap_create_mcl(conn_data->dev->hdp_adapter->mi,
					device_get_address(conn_data->dev->dev),
					ccpsm, create_mcl_cb, conn_data,
					destroy_con_mcl_data, &gerr)) {
		con_mcl_data_unref(conn_data);
		goto fail;
	}
	return;
fail:
	conn_data->func(conn_data->data, gerr);
	g_error_free(gerr);
}

gboolean hdp_establish_mcl(struct hdp_device *device,
						hdp_continue_proc_f func,
						gpointer data,
						GDestroyNotify destroy,
						GError **err)
{
	struct conn_mcl_data *conn_data;
	const bdaddr_t *src;
	const bdaddr_t *dst;
	uuid_t uuid;

	src = btd_adapter_get_address(device_get_adapter(device->dev));
	dst = device_get_address(device->dev);

	conn_data = g_new0(struct conn_mcl_data, 1);
	conn_data->refs = 1;
	conn_data->func = func;
	conn_data->data = data;
	conn_data->destroy = destroy;
	conn_data->dev = health_device_ref(device);

	bt_string2uuid(&uuid, HDP_UUID);
	if (bt_search_service(src, dst, &uuid, search_cb, conn_data,
					destroy_con_mcl_data, 0) < 0) {
		g_set_error(err, HDP_ERROR, HDP_CONNECTION_ERROR,
						"Can't get remote SDP record");
		g_free(conn_data);
		return FALSE;
	}

	return TRUE;
}

static void get_dcpsm_cb(sdp_list_t *recs, int err, gpointer data)
{
	struct get_dcpsm_data *dcpsm_data = data;
	GError *gerr = NULL;
	uint16_t dcpsm;

	if (err < 0 || recs == NULL) {
		g_set_error(&gerr, HDP_ERROR, HDP_CONNECTION_ERROR,
					"Error getting remote SDP records");
		goto fail;
	}

	if (!get_dcpsm(recs, &dcpsm)) {
		g_set_error(&gerr, HDP_ERROR, HDP_CONNECTION_ERROR,
				"Can't get remote PSM for data channel");
		goto fail;
	}

	dcpsm_data->func(dcpsm, dcpsm_data->data, NULL);
	return;

fail:
	dcpsm_data->func(0, dcpsm_data->data, gerr);
	g_error_free(gerr);
}

static void free_dcpsm_data(gpointer data)
{
	struct get_dcpsm_data *dcpsm_data = data;

	if (dcpsm_data == NULL)
		return;

	if (dcpsm_data->destroy)
		dcpsm_data->destroy(dcpsm_data->data);

	g_free(dcpsm_data);
}

gboolean hdp_get_dcpsm(struct hdp_device *device, hdp_continue_dcpsm_f func,
							gpointer data,
							GDestroyNotify destroy,
							GError **err)
{
	struct get_dcpsm_data *dcpsm_data;
	const bdaddr_t *src;
	const bdaddr_t *dst;
	uuid_t uuid;

	src = btd_adapter_get_address(device_get_adapter(device->dev));
	dst = device_get_address(device->dev);

	dcpsm_data = g_new0(struct get_dcpsm_data, 1);
	dcpsm_data->func = func;
	dcpsm_data->data = data;
	dcpsm_data->destroy = destroy;

	bt_string2uuid(&uuid, HDP_UUID);
	if (bt_search_service(src, dst, &uuid, get_dcpsm_cb, dcpsm_data,
						free_dcpsm_data, 0) < 0) {
		g_set_error(err, HDP_ERROR, HDP_CONNECTION_ERROR,
						"Can't get remote SDP record");
		g_free(dcpsm_data);
		return FALSE;
	}

	return TRUE;
}

static void hdp_free_application(struct hdp_application *app)
{
	if (app->dbus_watcher > 0)
		g_dbus_remove_watch(btd_get_dbus_connection(),
							app->dbus_watcher);

	g_free(app->oname);
	g_free(app->description);
	g_free(app->path);
	g_free(app);
}

struct hdp_application *hdp_application_ref(struct hdp_application *app)
{
	if (app == NULL)
		return NULL;

	app->ref++;

	DBG("health_application_ref(%p): ref=%d", app, app->ref);
	return app;
}

void hdp_application_unref(struct hdp_application *app)
{
	if (app == NULL)
		return;

	app->ref--;

	DBG("health_application_unref(%p): ref=%d", app, app->ref);
	if (app->ref > 0)
		return;

	hdp_free_application(app);
}
