/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2004-2006  Marcel Holtmann <marcel@holtmann.org>
 *
 *
 *  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 <stdio.h>
#include <errno.h>
#include <unistd.h>

#include <fcntl.h>

#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/l2cap.h>
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>

#include <netinet/in.h>

#include <dbus/dbus.h>

#include "dbus.h"
#include "hcid.h"
#include "textfile.h"

#define MAX_IDENTIFIER_LEN	29	/* "XX:XX:XX:XX:XX:XX/0xYYYYYYYY\0" */

struct service_provider {
	char *owner;	/* null for remote services or unique name if local */
	char *prov;	/* remote Bluetooth address that provides the service */
	struct slist *lrec;
};

struct service_record {
	int ttl;	/* time to live */
	sdp_record_t *record;
};

struct transaction_context {
	DBusConnection *conn;
	DBusMessage *rq;
	sdp_session_t *session;

	/* Used for internal async get remote service record implementation */
	void *priv;
};

typedef int connect_cb_t(struct transaction_context *t);
struct pending_connect {
	DBusConnection *conn;
	DBusMessage *rq;

	char *dst;
	sdp_session_t *session;
	connect_cb_t *conn_cb;

	/* Used for internal async get remote service record implementation */
	void *priv;
};

/* FIXME:  move to a common file */
typedef struct {
	char            *name;
	uint16_t        class;
	char            *info_name;
} sdp_service_t;

/* FIXME:  move to a common file */
sdp_service_t sdp_service[] = {
	{ "vcp",	VIDEO_CONF_SVCLASS_ID,		"Video Conference"	},
	{ "map",	0,				NULL			},
	{ "pbap",	PBAP_SVCLASS_ID,		"Phone Book Access"	},
	{ "sap",	SAP_SVCLASS_ID,			"SIM Access"		},
	{ "ftp",	OBEX_FILETRANS_SVCLASS_ID,	"OBEX File Transfer"	},
	{ "bpp",	BASIC_PRINTING_SVCLASS_ID,	"Printing"		},
	{ "bip",	IMAGING_SVCLASS_ID,		"Imaging"		},
	{ "synch",	IRMC_SYNC_SVCLASS_ID,		"Synchronization"	},
	{ "dun",	DIALUP_NET_SVCLASS_ID,		"Dial-Up Networking"	},
	{ "opp",	OBEX_OBJPUSH_SVCLASS_ID,	"OBEX Object Push"	},
	{ "fax",	FAX_SVCLASS_ID,			"Fax"			},
	{ "spp",	SERIAL_PORT_SVCLASS_ID,		"Serial Port"		},
	{ NULL }
};

/* FIXME:  move to a common file */
uint16_t sdp_str2svclass(const char *str)
{
	sdp_service_t *s;

	for (s = sdp_service; s->name; s++) {
		if (strcasecmp(s->name, str) == 0)
			return s->class;
	}

	return 0;
}

/* FIXME:  move to a common file */
const char* sdp_svclass2str(uint16_t class)
{
	sdp_service_t *s;

	for (s = sdp_service; s->name; s++) {
		if (s->class == class)
			return s->name;
	}

	return NULL;
}

/* FIXME: stub for service registration. Shared with sdptool */
static inline sdp_record_t *sdp_service_register(const char *name, bdaddr_t *interface,
		                                   uint8_t channel, int *err)
{
	if (err)
		*err = ENOSYS;

	return NULL;
}

/* FIXME: stub for service registration. Shared with sdptool */
static inline int sdp_service_unregister(bdaddr_t *interface, sdp_record_t *rec, int *err)
{
	if (err)
		*err = ENOSYS;

	return -1;
}

/* list of remote and local service records */
static struct slist *sdp_cache = NULL;
static struct slist *pending_connects  = NULL;

static struct pending_connect *pending_connect_new(DBusConnection *conn, DBusMessage *msg,
							const char *dst, connect_cb_t *cb)
{
	struct pending_connect *c;

	if (!dst)
		return NULL;

	c = malloc(sizeof(*c));
	if (!c)
		return NULL;
	memset(c, 0, sizeof(*c));

	if (dst) {
		c->dst = strdup(dst);
		if (!c->dst) {
			free(c);
			return NULL;
		}
	}

	c->conn = dbus_connection_ref(conn);
	c->rq = dbus_message_ref(msg);
	c->conn_cb = cb;

	return c;
}

static void pending_connect_free(struct pending_connect *c)
{
	if (!c)
		return;

	if (c->dst)
		free(c->dst);

	if (c->rq)
		dbus_message_unref(c->rq);

	if (c->conn)
		dbus_connection_unref(c->conn);

	free(c);
}

static struct pending_connect *find_pending_connect(const char *dst)
{
	struct slist *l;

	for (l = pending_connects; l != NULL; l = l->next) {
		struct pending_connect *pending = l->data;
		if (!strcmp(dst, pending->dst))
			return pending;
	}

	return NULL;
}

static int str2identifier(const char *identifier, char *address,
			  uint32_t *handle)
{
	if (!identifier || !address)
		return -1;

	if (strlen(identifier) < 19)
		return -1;

	memset(address, 0, 18);
	snprintf(address, 18, "%s", identifier);

	return (sscanf(identifier + 18, "%x", handle) > 0 ? 0 : -1);
}

static struct service_record *service_record_new(sdp_record_t *rec)
{
	struct service_record *r;

	r = malloc(sizeof(*r));
	if (!r)
		return NULL;

	memset(r, 0, sizeof(*r));
	r->record = rec;

	return r;
}

static void service_record_free(void *data, void *udata)
{
	struct service_record *r = data;

	if (!r)
		return;

	if (r->record)
		sdp_record_free(r->record);

	free(r);
}

/*
 * This function doesn't check service record pattern
 */
static int service_record_cmp(const void *data, const void *udata)
{
	const struct service_record *a = data;
	const struct service_record *b = udata;

	if (b->record) {
		if (b->record->handle != 0xffffffff &&
		    b->record->handle != a->record->handle)
			return -1;
	}

	return 0;
}

static void service_provider_free(void *data, void *udata)
{
	struct service_provider *p1 = data;
	struct service_provider *p2 = udata;

	if (!p1)
		return;

	/* Check if the provider match */
	if (p2) {
		if (p2->owner && strcmp(p2->owner, p1->owner))
			return;
		if (p2->prov && strcmp(p2->prov, p1->prov))
			return;
	}

	if (p1->owner)
		free(p1->owner);

	if (p1->prov)
		free(p1->prov);

	if (p1->lrec) {
		slist_foreach(p1->lrec, service_record_free, NULL);
		slist_free(p1->lrec);
	}

	free(p1);
}

static struct service_provider *service_provider_new(const char *owner, const char *prov)
{
	struct service_provider *p;

	if (!prov)
		return NULL;

	p = malloc(sizeof(struct service_provider));
	if (!p)
		return NULL;

	memset(p, 0, sizeof(*p));
	if (owner) {
		p->owner = strdup(owner);
		if (!p->owner)
			goto fail;
	}

	if (prov) {
		p->prov = strdup(prov);
		if (!p->prov)
			goto fail;
	}

	return p;

fail:
	service_provider_free(p, NULL);
	return NULL;
}

static int service_provider_cmp(const void *data, const void *udata)
{
	const struct service_provider *a = data;
	const struct service_provider *b = udata;
	int ret;

	if (b->owner) {
		if (!a->owner)
			return -1;
		ret = strcmp(a->owner, b->owner);
		if (ret)
			return ret;
	}

	if (b->prov) {
		if (!a->prov)
			return -1;
		ret = strcmp(a->prov, b->prov);
		if (ret)
			return ret;
	}

	return 0;
}

static int sdp_cache_append(const char *owner, const char *prov, sdp_record_t *rec)
{
	struct slist *lp, *lr;
	struct service_provider *p;
	struct service_provider psearch;
	struct service_record r, *sr;

	if (!prov || !rec)
		return -1;

	memset(&psearch, 0, sizeof(psearch));
	psearch.owner = (char *) owner;
	psearch.prov = (char *) prov;

	lp = slist_find(sdp_cache, &psearch, service_provider_cmp);
	if (!lp) {
		p = service_provider_new(owner, prov);
		sdp_cache = slist_append(sdp_cache, p);
	} else
		p = lp->data;

	/* check if the service record already belongs to the cache */
	r.record = sdp_record_alloc();
	r.record->handle = rec->handle;
	lr = slist_find(p->lrec, &r, service_record_cmp);
	sdp_record_free(r.record);

	if (lr) {
		/* overwrite the record instead of compare */
		sr = lr->data;
		sdp_record_free(sr->record);
		sr->record = rec;
	} else {
		/* create a new entry */
		sr = service_record_new(rec);
		p->lrec = slist_append(p->lrec, sr);
	}

	return 0;
}

static void transaction_context_free(void *udata)
{
	struct transaction_context *ctxt = udata;

	if (!ctxt)
		return;

	if (ctxt->conn)
		dbus_connection_unref(ctxt->conn);

	if (ctxt->rq)
		dbus_message_unref(ctxt->rq);

	if (ctxt->session)
		sdp_close(ctxt->session);

	free(ctxt);
}

typedef struct {
	uint16_t dev_id;
	char *dst;
	void *search_data;
	get_record_cb_t *cb;
	void *data;
} get_record_data_t;

static get_record_data_t *get_record_data_new(uint16_t dev_id, const char *dst,
					void *search_data,
					get_record_cb_t *cb, void *data)
{
	get_record_data_t *n;

	n = malloc(sizeof(*n));
	if (!n)
		return NULL;

	n->dst = strdup(dst);
	if (!n->dst) {
		free(n);
		return NULL;
	}

	n->dev_id = dev_id;
	n->search_data = search_data;
	n->cb = cb;
	n->data = data;

	return n;
}

static void get_record_data_free(get_record_data_t *d)
{
	free(d->search_data);
	free(d->dst);
	free(d);
}

static inline void get_record_data_call_cb(get_record_data_t *d,
						sdp_record_t *rec, int err)
{
	d->cb(rec, d->data, err);
}

static void owner_exited(const char *owner, struct hci_dbus_data *dbus_data)
{
	struct slist *lp, *next, *lr;
	struct service_provider *p;
	bdaddr_t sba;
	int err = 0;
	debug("SDP provider owner %s exited", owner);

	for (lp = sdp_cache; lp; lp = next) {

		next = lp->next;
		p = lp->data;

		if (!p->owner || strcmp(p->owner, owner))
			continue;

		/*
		 * Unregister all service records related to this owner.
		 * One owner can use multiple local adapter(provider)
		 */
		str2ba(dbus_data->address, &sba);
		for (lr = p->lrec; lr; lr = lr->next) {
			struct service_record *r = lr->data;
			if (sdp_service_unregister(&sba, r->record, &err) < 0)
				error("unregister error: %s (%d)", strerror(err), err);
			else
				/* free inside the library */
				r->record = NULL;
		}

		/* remove from the cache */
		sdp_cache = slist_remove(sdp_cache, p);

		service_provider_free(p, NULL);
	}
}

static gboolean search_process_cb(GIOChannel *chan,
				GIOCondition cond, void *udata)
{
	struct transaction_context *ctxt = udata;
	int err = 0;

	if (cond & G_IO_NVAL) {
		g_io_channel_unref(chan);
		return FALSE;
	}

	if (cond & (G_IO_ERR | G_IO_HUP)) {
		err = EIO;
		goto failed;
	}

	if (sdp_process(ctxt->session) < 0)
		goto failed;

	return TRUE;

failed:
	if (err) {
		if (ctxt->priv) {
			get_record_data_call_cb(ctxt->priv, NULL, err);
			get_record_data_free(ctxt->priv);
		} else
			error_failed(ctxt->conn, ctxt->rq, err);

		transaction_context_free(ctxt);
	}

	return TRUE;
}

static void remote_svc_rec_completed_cb(uint8_t type, uint16_t err, uint8_t *rsp, size_t size, void *udata)
{
	struct transaction_context *ctxt = udata;
	char identifier[MAX_IDENTIFIER_LEN];
	sdp_record_t *rec = NULL;
	DBusMessage *reply;
	DBusMessageIter iter, array_iter;
	const char *dst;
	int i, scanned;

	if (!ctxt)
		return;

	if (err == 0xffff) {
		/* Check for protocol error or I/O error */
		int sdp_err = sdp_get_error(ctxt->session);
		if (sdp_err < 0) {
			error("search failed: Invalid session!");
			error_failed(ctxt->conn, ctxt->rq, EINVAL);
			goto failed;
		}

		error("search failed: %s (%d)", strerror(sdp_err), sdp_err);
		error_failed(ctxt->conn, ctxt->rq, sdp_err);
		goto failed;
	}

	if (type == SDP_ERROR_RSP) {
		error_sdp_failed(ctxt->conn, ctxt->rq, err);
		goto failed;
	}

	/* check response PDU ID */
	if (type != SDP_SVC_ATTR_RSP) {
		error("SDP error: %s (%d)", strerror(EPROTO), EPROTO);
		error_failed(ctxt->conn, ctxt->rq, EPROTO);
		goto failed;
	}

	dbus_message_get_args(ctxt->rq, NULL,
			DBUS_TYPE_STRING, &dst,
			DBUS_TYPE_INVALID);

	reply = dbus_message_new_method_return(ctxt->rq);
	dbus_message_iter_init_append(reply, &iter);
	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
			DBUS_TYPE_BYTE_AS_STRING, &array_iter);

	rec = sdp_extract_pdu(rsp, &scanned);
	if (rec == NULL) {
		error("SVC REC is null");
		goto done;
	}

	sdp_cache_append(NULL, dst, rec);
	snprintf(identifier, MAX_IDENTIFIER_LEN, "%s/0x%x", dst, rec->handle);

	/* FIXME: avoid seg fault / out of bound */
	for (i = 0; i < size; i++)
		dbus_message_iter_append_basic(&array_iter,
				DBUS_TYPE_BYTE, &rsp[i]);

done:
	dbus_message_iter_close_container(&iter, &array_iter);
	send_reply_and_unref(ctxt->conn, reply);
failed:
	transaction_context_free(ctxt);
}

static void remote_svc_handles_completed_cb(uint8_t type, uint16_t err, uint8_t *rsp, size_t size, void *udata)
{
	struct transaction_context *ctxt = udata;
	DBusMessage *reply;
	DBusMessageIter iter, array_iter;
	uint8_t *pdata;
	int scanned, csrc, tsrc;

	if (!ctxt)
		return;

	if (err == 0xffff) {
		/* Check for protocol error or I/O error */
		int sdp_err = sdp_get_error(ctxt->session);
		if (sdp_err < 0) {
			error("search failed: Invalid session!");
			error_failed(ctxt->conn, ctxt->rq, EINVAL);
			goto failed;
		}

		error("search failed: %s (%d)", strerror(sdp_err), sdp_err);
		error_failed(ctxt->conn, ctxt->rq, sdp_err);
		goto failed;
	}

	if (type == SDP_ERROR_RSP) {
		error_sdp_failed(ctxt->conn, ctxt->rq, err);
		goto failed;
	}

	/* check response PDU ID */
	if (type != SDP_SVC_SEARCH_RSP) {
		error("SDP error: %s (%d)", strerror(EPROTO), EPROTO);
		error_failed(ctxt->conn, ctxt->rq, EPROTO);
		goto failed;
	}

	reply = dbus_message_new_method_return(ctxt->rq);
	dbus_message_iter_init_append(reply, &iter);
	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
			DBUS_TYPE_UINT32_AS_STRING, &array_iter);

	pdata = rsp;

	tsrc = ntohs(bt_get_unaligned((uint16_t *) pdata));
	if (tsrc <= 0)
		goto done;

	pdata += sizeof(uint16_t);
	scanned = sizeof(uint16_t);

	csrc = ntohs(bt_get_unaligned((uint16_t *) pdata));
	if (csrc <= 0)
		goto done;

	pdata += sizeof(uint16_t);
	scanned += sizeof(uint16_t);

	do {
		uint32_t handle = ntohl(bt_get_unaligned((uint32_t*)pdata));
		scanned += sizeof(uint32_t);
		pdata += sizeof(uint32_t);

		dbus_message_iter_append_basic(&array_iter,
				DBUS_TYPE_UINT32, &handle);
	} while (--tsrc);


done:
	dbus_message_iter_close_container(&iter, &array_iter);
	send_reply_and_unref(ctxt->conn, reply);
failed:
	transaction_context_free(ctxt);
}

static void search_completed_cb(uint8_t type, uint16_t err, uint8_t *rsp, size_t size, void *udata)
{
	struct transaction_context *ctxt = udata;
	char identifier[MAX_IDENTIFIER_LEN];
	const char *ptr = identifier;
	DBusMessage *reply;
	DBusMessageIter iter, array_iter;
	const char *dst;
	uint8_t *pdata;
	int scanned, csrc, tsrc;

	if (!ctxt)
		return;

	if (err == 0xffff) {
		/* Check for protocol error or I/O error */
		int sdp_err = sdp_get_error(ctxt->session);
		if (sdp_err < 0) {
			error("search failed: Invalid session!");
			error_failed(ctxt->conn, ctxt->rq, EINVAL);
			goto failed;
		}

		error("search failed: %s (%d)", strerror(sdp_err), sdp_err);
		error_failed(ctxt->conn, ctxt->rq, sdp_err);
		goto failed;
	}

	if (type == SDP_ERROR_RSP) {
		error_sdp_failed(ctxt->conn, ctxt->rq, err);
		goto failed;
	}

	/* check response PDU ID */
	if (type != SDP_SVC_SEARCH_RSP) {
		error("SDP error: %s (%d)", strerror(EPROTO), EPROTO);
		error_failed(ctxt->conn, ctxt->rq, EPROTO);
		goto failed;
	}

	dbus_message_get_args(ctxt->rq, NULL,
			DBUS_TYPE_STRING, &dst,
			DBUS_TYPE_INVALID);

	reply = dbus_message_new_method_return(ctxt->rq);
	dbus_message_iter_init_append(reply, &iter);
	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
			DBUS_TYPE_STRING_AS_STRING, &array_iter);

	pdata = rsp;

	tsrc = ntohs(bt_get_unaligned((uint16_t *) pdata));
	if (tsrc <= 0)
		goto done;

	pdata += sizeof(uint16_t);
	scanned = sizeof(uint16_t);

	csrc = ntohs(bt_get_unaligned((uint16_t *) pdata));
	if (csrc <= 0)
		goto done;

	pdata += sizeof(uint16_t);
	scanned += sizeof(uint16_t);

	do {
		uint32_t handle = ntohl(bt_get_unaligned((uint32_t*)pdata));
		scanned += sizeof(uint32_t);
		pdata += sizeof(uint32_t);

		snprintf(identifier, MAX_IDENTIFIER_LEN, "%s/0x%x", dst, handle);

		dbus_message_iter_append_basic(&array_iter,
				DBUS_TYPE_STRING, &ptr);
	} while (--tsrc);

done:
	dbus_message_iter_close_container(&iter, &array_iter);
	send_reply_and_unref(ctxt->conn, reply);
failed:
	transaction_context_free(ctxt);
}

static gboolean sdp_client_connect_cb(GIOChannel *chan,
					GIOCondition cond, void *udata)
{
	struct pending_connect *c = udata;
	struct transaction_context *ctxt = NULL;
	int sdp_err, err = 0, sk;
	socklen_t len;

	sk = g_io_channel_unix_get_fd(chan);

	len = sizeof(err);
	if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &err, &len) < 0) {
		error("getsockopt(): %s (%d)", strerror(errno), errno);
		err = errno;
		goto failed;
	}
	if (err != 0) {
		error("connect(): %s (%d)", strerror(err), err);
		goto failed;
	}

	ctxt = malloc(sizeof(*ctxt));
	if (!ctxt) {
		err = ENOMEM;
		goto failed;
	}
	memset(ctxt, 0, sizeof(*ctxt));

	ctxt->conn = dbus_connection_ref(c->conn);
	ctxt->rq = dbus_message_ref(c->rq);
	ctxt->session = c->session;
	if (c->priv)
		ctxt->priv = c->priv;

	/* set the complete transaction callback and send the search request */
	sdp_err = c->conn_cb(ctxt);
	if (sdp_err < 0) {
		err = -sdp_err;
		error("search failed: %s (%d)", strerror(err), err);
		goto failed;
	}

	/* set the callback responsible for update the transaction data */
	g_io_add_watch(chan, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
			search_process_cb, ctxt);
	goto done;

failed:
	if (c->priv)
		get_record_data_call_cb(c->priv, NULL, err);
	else
		error_connection_attempt_failed(c->conn, c->rq, err);

	if (c->priv)
		get_record_data_free(c->priv);

	if (ctxt)
		transaction_context_free(ctxt);
	else
		sdp_close(c->session);

	g_io_channel_unref(chan);

done:
	pending_connects = slist_remove(pending_connects, c);
	pending_connect_free(c);

	return FALSE;
}

static struct pending_connect *connect_request(DBusConnection *conn,
					DBusMessage *msg,
					uint16_t dev_id,
					const char *dst,
					connect_cb_t *cb, int *err)
{
	struct pending_connect *c;
	bdaddr_t srcba, dstba;
	GIOChannel *chan;

	c = pending_connect_new(conn, msg, dst, cb);
	if (!c) {
		if (err)
			*err = ENOMEM;
		return NULL;
	}

	hci_devba(dev_id, &srcba);
	str2ba(dst, &dstba);

	c->session = sdp_connect(&srcba, &dstba, SDP_NON_BLOCKING);
	if (!c->session) {
		if (err)
			*err = errno;
		error("sdp_connect() failed: %s (%d)", strerror(errno), errno);
		pending_connect_free(c);
		return NULL;
	}

	chan = g_io_channel_unix_new(sdp_get_socket(c->session));
	g_io_add_watch(chan, G_IO_OUT, sdp_client_connect_cb, c);
	pending_connects = slist_append(pending_connects, c);

	return c;
}

static int remote_svc_rec_conn_cb(struct transaction_context *ctxt)
{
	sdp_list_t *attrids = NULL;
	uint32_t range = 0x0000ffff;
	const char *dst;
	uint32_t handle;
	int err = 0;

	if (sdp_set_notify(ctxt->session, remote_svc_rec_completed_cb, ctxt) < 0) {
		err = -EINVAL;
		goto fail;
	}

	dbus_message_get_args(ctxt->rq, NULL,
			DBUS_TYPE_STRING, &dst,
			DBUS_TYPE_UINT32, &handle,
			DBUS_TYPE_INVALID);

	attrids = sdp_list_append(NULL, &range);
	/* Create/send the search request and set the callback to indicate the request completion */
	if (sdp_service_attr_async(ctxt->session, handle, SDP_ATTR_REQ_RANGE, attrids) < 0) {
		err = -sdp_get_error(ctxt->session);
		goto fail;
	}

fail:
	if (attrids)
		sdp_list_free(attrids, NULL);

	return err;
}

DBusHandlerResult get_remote_svc_rec(DBusConnection *conn, DBusMessage *msg, void *data)
{
	struct hci_dbus_data *dbus_data = data;
	const char *dst;
	uint32_t handle;
	int err = 0;

	if (!dbus_message_get_args(msg, NULL,
			DBUS_TYPE_STRING, &dst,
			DBUS_TYPE_UINT32, &handle,
			DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	if (find_pending_connect(dst))
		return error_service_search_in_progress(conn, msg);

	if (!connect_request(conn, msg, dbus_data->dev_id,
				dst, remote_svc_rec_conn_cb, &err)) {
		error("Search request failed: %s (%d)", strerror(err), err);
		return error_failed(conn, msg, err);
	}

	return DBUS_HANDLER_RESULT_HANDLED;
}

static int remote_svc_handles_conn_cb(struct transaction_context *ctxt)
{
	sdp_list_t *search = NULL;
	const char *dst, *svc;
	uuid_t uuid;
	int err = 0;

	if (sdp_set_notify(ctxt->session, remote_svc_handles_completed_cb, ctxt) < 0) {
		err = -EINVAL;
		goto fail;
	}

	dbus_message_get_args(ctxt->rq, NULL,
			DBUS_TYPE_STRING, &dst,
			DBUS_TYPE_STRING, &svc,
			DBUS_TYPE_INVALID);

	if (strlen(svc) > 0)
		str2uuid(&uuid, svc);
	else
		sdp_uuid16_create(&uuid, PUBLIC_BROWSE_GROUP);

	search = sdp_list_append(0, &uuid);

	/* Create/send the search request and set the callback to indicate the request completion */
	if (sdp_service_search_async(ctxt->session, search, 64) < 0) {
		error("send request failed: %s (%d)", strerror(errno), errno);
		err = -sdp_get_error(ctxt->session);
		goto fail;
	}

fail:
	if (search)
		sdp_list_free(search, NULL);

	return err;
}

DBusHandlerResult get_remote_svc_handles(DBusConnection *conn, DBusMessage *msg, void *data)
{
	struct hci_dbus_data *dbus_data = data;
	const char *dst, *svc;
	int err = 0;
	uuid_t uuid;

	if (!dbus_message_get_args(msg, NULL,
			DBUS_TYPE_STRING, &dst,
			DBUS_TYPE_STRING, &svc,
			DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	if (strlen(svc) > 0) {
		/* Check if it is a service name string */
		if (str2uuid(&uuid, svc) < 0) {
			error("Invalid service class name");
			return error_invalid_arguments(conn, msg);
		}
	}

	if (find_pending_connect(dst))
		return error_service_search_in_progress(conn, msg);

	if (!connect_request(conn, msg, dbus_data->dev_id,
				dst, remote_svc_handles_conn_cb, &err)) {
		error("Search request failed: %s (%d)", strerror(err), err);
		return error_failed(conn, msg, err);
	}

	return DBUS_HANDLER_RESULT_HANDLED;
}

static int get_identifiers_conn_cb(struct transaction_context *ctxt)
{
	sdp_list_t *search = NULL;
	uuid_t uuid;
	int err = 0;

	if (sdp_set_notify(ctxt->session, search_completed_cb, ctxt) < 0) {
		err = -EINVAL;
		goto fail;
	}

	sdp_uuid16_create(&uuid, PUBLIC_BROWSE_GROUP);
	search = sdp_list_append(0, &uuid);

	/* Create/send the search request and set the callback to indicate the request completion */
	if (sdp_service_search_async(ctxt->session, search, 64) < 0) {
		err = -sdp_get_error(ctxt->session);
		goto fail;
	}

fail:
	if (search)
		sdp_list_free(search, NULL);

	return err;
}

static DBusHandlerResult get_identifiers(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct hci_dbus_data *dbus_data = data;
	const char *dst;
	int err = 0;

	if (!dbus_message_get_args(msg, NULL,
			DBUS_TYPE_STRING, &dst,
			DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	/* in progress is not working properly */
	if (find_pending_connect(dst))
		return error_service_search_in_progress(conn, msg);

	if (!connect_request(conn, msg, dbus_data->dev_id,
				dst, get_identifiers_conn_cb, &err)) {
		error("Search request failed: %s (%d)", strerror(err), err);
		return error_failed(conn, msg, err);
	}

	return DBUS_HANDLER_RESULT_HANDLED;
}

static int get_identifiers_by_service_conn_cb(struct transaction_context *ctxt)
{
	sdp_list_t *search = NULL;
	const char *dst, *svc;
	uuid_t uuid;
	uint16_t class;
	int err = 0;

	if (sdp_set_notify(ctxt->session, search_completed_cb, ctxt) < 0) {
		err = -EINVAL;
		goto fail;
	}

	dbus_message_get_args(ctxt->rq, NULL,
				DBUS_TYPE_STRING, &dst,
				DBUS_TYPE_STRING, &svc,
				DBUS_TYPE_INVALID);

	class = sdp_str2svclass(svc);
	sdp_uuid16_create(&uuid, class);
	search = sdp_list_append(0, &uuid);

	/* Create/send the search request and set the callback to indicate the request completion */
	if (sdp_service_search_async(ctxt->session, search, 64) < 0) {
		err = -sdp_get_error(ctxt->session);
		goto fail;
	}

fail:
	if (search)
		sdp_list_free(search, NULL);

	return err;
}

static DBusHandlerResult get_identifiers_by_service(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct hci_dbus_data *dbus_data = data;
	DBusMessage *reply;
	DBusMessageIter iter, array_iter;
	struct slist *lp;
	struct slist *lr;
	struct service_provider *p;
	struct service_record *r;
	char identifier[MAX_IDENTIFIER_LEN];
	const char *ptr = identifier;
	const char *dst, *svc;
	int err = 0, nrec = 0;
	uint32_t class;
	uuid_t uuid;

	if (!dbus_message_get_args(msg, NULL,
			DBUS_TYPE_STRING, &dst,
			DBUS_TYPE_STRING, &svc,
			DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	class = sdp_str2svclass(svc);
	if (!class) {
		error("Invalid service class name");
		return error_invalid_arguments(conn, msg);
	}

	sdp_uuid16_create(&uuid, class);

	p = service_provider_new(NULL, dst);
	if (!p)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	/* FIXME: return cache entry or query again? */
	lp = slist_find(sdp_cache, p, service_provider_cmp);
	service_provider_free(p, NULL);

	if (!lp)
		goto search_request;

	reply = dbus_message_new_method_return(msg);
	dbus_message_iter_init_append(reply, &iter);
	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
			DBUS_TYPE_STRING_AS_STRING, &array_iter);

	p = lp->data;
	for (lr = p->lrec; lr; lr = lr->next) {
		sdp_list_t *ls;
		uuid_t *puuid;
		r = lr->data;
		/* check if the pattern match */
		if (sdp_get_service_classes(r->record, &ls))
			continue;

		puuid = (uuid_t *) ls->data;

		if (sdp_uuid16_cmp(puuid, &uuid) == 0) {
			snprintf(identifier, MAX_IDENTIFIER_LEN, "%s/0x%x", p->prov, r->record->handle);
			dbus_message_iter_append_basic(&array_iter,
					DBUS_TYPE_STRING, &ptr);
			nrec++;
		}

		sdp_list_free(ls, free);

	}

	dbus_message_iter_close_container(&iter, &array_iter);

	if (nrec > 0)
		return send_reply_and_unref(conn, reply);

	/* no record found: request search */
	dbus_message_unref(reply);

search_request:
	if (find_pending_connect(dst))
		return error_service_search_in_progress(conn, msg);

	if (!connect_request(conn, msg, dbus_data->dev_id,
			dst, get_identifiers_by_service_conn_cb, &err)) {
		error("Search request failed: %s (%d)", strerror(err), err);
		return error_failed(conn, msg, err);
	}

	return DBUS_HANDLER_RESULT_HANDLED;

}

#if 0
static int uuid_cmp(const void *key1, const void *key2)
{
	uuid_t *a, *b;
	int ret_val;

	/* converting to uuid128 */
	a = sdp_uuid_to_uuid128((uuid_t *) key1);
	b = sdp_uuid_to_uuid128((uuid_t *) key2);

	ret_val = sdp_uuid128_cmp(a, b);

	bt_free(a);
	bt_free(b);

	return ret_val;
}

static sdp_record_t *find_record_by_uuid(const char *address, uuid_t *uuid)
{
	struct slist *lp, *lr;
	struct service_provider *p;
	struct service_record *r;
	sdp_list_t *list = NULL;

	for (lp = sdp_cache; lp; lp = lp->next) {
		p = lp->data;
		if (strcmp(p->prov, address))
			continue;

		for (lr = p->lrec; lr; lr = lr->next) {
			r = lr->data;
			/* Check whether the record has the correct uuid */
			if (sdp_get_service_classes(r->record, &list) != 0)
				continue;

			if (sdp_list_find(list, uuid, uuid_cmp))
				return r->record;
		}
	}

	return NULL;
}
#endif

static sdp_record_t *find_record_by_handle(const char *address,
						uint32_t handle)
{
	struct slist *lp, *lr;
	struct service_provider *p;
	struct service_record *r;

	for (lp = sdp_cache; lp; lp = lp->next) {
		p = lp->data;
		if (strcmp(p->prov, address))
			continue;

		for (lr = p->lrec; lr; lr = lr->next) {
			r = lr->data;
			if (r->record->handle == handle)
				return r->record;
		}
	}

	return NULL;
}

static DBusHandlerResult get_uuid(DBusConnection *conn,
					 DBusMessage *msg, void *data)
{
	char uuid_str[MAX_LEN_UUID_STR];
	char address[18];
	sdp_list_t *ls;
	DBusMessage *reply;
	sdp_record_t *rec;
	char *ptr = uuid_str;
	const char *identifier;
	uint32_t handle;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &identifier,
				DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	if (str2identifier(identifier, address, &handle) != 0)
		return error_invalid_arguments(conn, msg);

	rec = find_record_by_handle(address, handle);
	if (!rec)
		return error_record_does_not_exist(conn, msg);

	memset(uuid_str, 0, MAX_LEN_UUID_STR);

	reply = dbus_message_new_method_return(msg);

	if (sdp_get_service_classes(rec, &ls) == 0) {
		char tmp_str[MAX_LEN_UUID_STR];
		uuid_t *uuid = (uuid_t *) ls->data;

		if (sdp_uuid2strn(uuid, tmp_str, MAX_LEN_UUID_STR) != 0)
			error("Can't convert UUID to string!");
		else
			snprintf(uuid_str, MAX_LEN_UUID_STR, "0x%s", tmp_str);

		sdp_list_free(ls, free);
	}

	dbus_message_append_args(reply,
			DBUS_TYPE_STRING, &ptr,
			DBUS_TYPE_INVALID);

	return send_reply_and_unref(conn, reply);
}

static DBusHandlerResult get_name(DBusConnection *conn,
		DBusMessage *msg, void *data)
{
	char address[18];
	DBusMessage *reply;
	sdp_record_t *rec;
	sdp_list_t *ls;
	char name[] = "";
	const char *ptr = name;
	const char *identifier;
	uuid_t *puuid;
	uint32_t handle;

	if (!dbus_message_get_args(msg, NULL,
				DBUS_TYPE_STRING, &identifier,
				DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	if (str2identifier(identifier, address, &handle) != 0)
		return error_invalid_arguments(conn, msg);

	rec = find_record_by_handle(address, handle);
	if (!rec)
		return error_record_does_not_exist(conn, msg);

	if ((sdp_get_service_classes(rec, &ls)) < 0) {
		return error_failed(conn, msg, errno);
	}

	puuid = (uuid_t *) ls->data;

	ptr = sdp_svclass2str(puuid->value.uuid16);
	sdp_list_free(ls, free);

	/* return empty string for non supported services */
	if (!ptr)
		ptr = name;

	/* FIXME: it should return the service name attribute instead of the short service name */
	reply = dbus_message_new_method_return(msg);
	dbus_message_append_args(reply,
			DBUS_TYPE_STRING, &ptr,
			DBUS_TYPE_INVALID);

	return send_reply_and_unref(conn, reply);
}

static DBusHandlerResult register_rfcomm(DBusConnection *conn,
		DBusMessage *msg, void *data)
{
	struct hci_dbus_data *dbus_data = data;
	struct service_provider psearch;
	DBusMessage *reply;
	sdp_record_t *rec;
	const char *owner, *name;
	char identifier[MAX_IDENTIFIER_LEN];
	const char *ptr = identifier;
	bdaddr_t sba;
	int err = 0;
	uint8_t channel;

	owner = dbus_message_get_sender(msg);

	if (!dbus_message_get_args(msg, NULL,
			DBUS_TYPE_STRING, &name,
			DBUS_TYPE_BYTE, &channel,
			DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	str2ba(dbus_data->address, &sba);
	/* register service */
	if (!(rec = sdp_service_register(name, &sba, channel, &err))) {
		dbus_message_unref(reply);
		error("service register error: %s (%d)", strerror(err), err);
		if (err == EINVAL)
			return error_invalid_arguments(conn, msg);
		else
			return error_failed(conn, msg, err);
	}

	/* Only add a D-Bus unique name listener if there isn't one already registered */
	memset(&psearch, 0, sizeof(psearch));
	psearch.owner = (char *) owner;

	if (!slist_find(sdp_cache, &psearch, service_provider_cmp))
		name_listener_add(conn, owner, (name_cb_t) owner_exited, dbus_data);

	/* add record in the cache */
	sdp_cache_append(owner, dbus_data->address, rec);
	snprintf(identifier, MAX_IDENTIFIER_LEN, "%s/0x%x", dbus_data->address, rec->handle);
	dbus_message_append_args(reply,
			DBUS_TYPE_STRING, &ptr,
			DBUS_TYPE_INVALID);

	return send_reply_and_unref(conn, reply);
}

static DBusHandlerResult unregister_rfcomm(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	char address[18];
	struct hci_dbus_data *dbus_data = data;
	struct service_provider *p, psearch;
	struct service_record rsearch, *r;
	sdp_record_t record;
	struct slist *lp, *lr;
	DBusMessage *reply;
	const char *owner, *identifier;
	bdaddr_t sba;
	int err = 0;
	uint32_t handle;

	owner = dbus_message_get_sender(msg);

	if (!dbus_message_get_args(msg, NULL,
			DBUS_TYPE_STRING, &identifier,
			DBUS_TYPE_INVALID))
		return error_invalid_arguments(conn, msg);

	if (str2identifier(identifier, address, &handle) != 0)
		return error_invalid_arguments(conn, msg);

	/* check if the local adapter match */
	if (strcmp(address, dbus_data->address))
		return error_not_authorized(conn, msg);

	memset(&psearch, 0, sizeof(psearch));

	psearch.prov = address;
	psearch.owner = (char *) owner;

	lp = slist_find(sdp_cache, &psearch, service_provider_cmp);
	if (!lp)
		return error_service_does_not_exist(conn, msg);

	p = lp->data;

	rsearch.record = &record;
	record.handle = handle;
	lr = slist_find(p->lrec, &rsearch, service_record_cmp);
	if (!lr)
		return error_service_does_not_exist(conn, msg);

	reply = dbus_message_new_method_return(msg);
	if (!reply)
		return DBUS_HANDLER_RESULT_NEED_MEMORY;

	r = lr->data;
	str2ba(dbus_data->address, &sba);
	if (sdp_service_unregister(&sba, r->record, &err) < 0)
		error("service unregister error: %s (%d)", strerror(err), err);
	else
		r->record = NULL;

	/* Remove the service record */
	service_record_free(r, NULL);
	p->lrec = slist_remove(p->lrec, r);

	/* if the service record is empty remove the provider */
	if (!p->lrec) {
		sdp_cache = slist_remove(sdp_cache, p);
		service_provider_free(p, NULL);
	}

	psearch.prov = NULL;

	/* Only remove the D-Bus unique name listener if there are no more record using this name */
	if (!slist_find(sdp_cache, &psearch, service_provider_cmp))
		name_listener_remove(conn, owner, (name_cb_t) owner_exited, dbus_data);

	return send_reply_and_unref(conn, reply);
}

static struct service_data sdp_services[] = {
	{ "GetIdentifiers",		get_identifiers			},
	{ "GetIdentifiersByService",	get_identifiers_by_service	},
	{ "GetUUID",			get_uuid			},
	{ "GetName",			get_name			},
	{ "RegisterRFCOMM",		register_rfcomm			},
	{ "UnregisterRFCOMM",		unregister_rfcomm		},
	{ NULL, NULL }
};

DBusHandlerResult handle_sdp_method(DBusConnection *conn, DBusMessage *msg, void *data)
{
	const struct hci_dbus_data *pdata = data;
	service_handler_func_t handler;

	if (!hcid_dbus_use_experimental())
		return error_unknown_method(conn, msg);

	if (!pdata->up)
		return error_not_ready(conn, msg);

	handler = find_service_handler(sdp_services, msg);

	if (handler)
		return handler(conn, msg, data);

	return error_unknown_method(conn, msg);
}

void dbus_sdp_cache_free()
{
	slist_foreach(sdp_cache, service_provider_free, NULL);
}

/*
 * Internal async get remote service record implementation
 */

static void get_rec_with_handle_comp_cb(uint8_t type, uint16_t err,
					uint8_t *rsp, size_t size, void *udata)
{
	struct transaction_context *ctxt = udata;
	int scanned, cb_err = 0;
	sdp_record_t *rec = NULL;

	if (err == 0xffff) {
		int sdp_err = sdp_get_error(ctxt->session);
		if (sdp_err < 0) {
			error("search failed: Invalid session!");
			cb_err = EINVAL;
			goto failed;
		}
		error("search failed :%s (%d)", strerror(sdp_err), sdp_err);
		cb_err = sdp_err;
		goto failed;
	}

	if (type == SDP_ERROR_RSP || type != SDP_SVC_ATTR_RSP) {
		error("SDP error: %s(%d)", strerror(EPROTO), EPROTO);
		cb_err = EPROTO;
		goto failed;
	}

	rec = sdp_extract_pdu(rsp, &scanned);
	if (!rec) {
		error("Service record is NULL");
		cb_err = EPROTO;
		goto failed;
	}

	/* FIXME: add record to the cache! */

failed:
	get_record_data_call_cb(ctxt->priv, rec, cb_err);

	/* FIXME: when start using cache don't free the service record */
	if (rec)
		sdp_record_free(rec);
	get_record_data_free(ctxt->priv);
	transaction_context_free(ctxt);
}

static int get_rec_with_handle_conn_cb(struct transaction_context *ctxt)
{
	get_record_data_t *d = ctxt->priv;
	uint32_t range = 0x0000ffff;
	sdp_list_t *attrids = NULL;
	uint32_t handle;
	int err = 0;

	if (sdp_set_notify(ctxt->session,
				get_rec_with_handle_comp_cb, ctxt) < 0) {
		error("Invalid session data!");
		err = -EINVAL;
		goto failed;
	}

	handle = *((uint32_t *)d->search_data);
	attrids = sdp_list_append(NULL, &range);

	if (sdp_service_attr_async(ctxt->session, handle,
					SDP_ATTR_REQ_RANGE, attrids) < 0) {
		error("send request failed: %s (%d)", strerror(errno), errno);
		err = -errno;
		goto failed;
	}

failed:
	if (attrids)
		sdp_list_free(attrids, NULL);

	return err;
}

int get_record_with_handle(DBusConnection *conn, DBusMessage *msg,
			uint16_t dev_id, const char *dst,
			uint32_t handle, get_record_cb_t *cb, void *data)
{
	struct pending_connect *c;
	get_record_data_t *d;
	uint32_t *rec_handle;
	int err;

	/* FIXME: search the cache first! */

	if (find_pending_connect(dst)) {
		error("SDP search in progress!");
		return -EINPROGRESS;
	}

	rec_handle = malloc(sizeof(uint32_t));
	if (!rec_handle)
		return -ENOMEM;

	*rec_handle = handle;

	d = get_record_data_new(dev_id, dst, rec_handle, cb, data);
	if (!d) {
		free(rec_handle);
		return -ENOMEM;
	}

	if (!(c = connect_request(conn, msg, dev_id, dst,
				get_rec_with_handle_conn_cb, &err))) {
		error("Search request failed: %s (%d)", strerror(err), err);
		get_record_data_free(d);
		return -err;
	}

	c->priv = d;

	return 0;
}

static void get_rec_with_uuid_comp_cb(uint8_t type, uint16_t err,
					uint8_t *rsp, size_t size, void *udata)
{
	struct transaction_context *ctxt = udata;
	get_record_data_t *d = ctxt->priv;
	int csrc, tsrc, cb_err = 0;
	uint32_t *handle;
	uint8_t *pdata;

	if (err == 0xffff) {
		int sdp_err = sdp_get_error(ctxt->session);
		if (sdp_err < 0) {
			error("search failed: Invalid session!");
			cb_err = EINVAL;
			goto failed;
		}
		error("search failed: %s (%d)", strerror(sdp_err), sdp_err);
		cb_err = sdp_err;
		goto failed;
	}

	if (type == SDP_ERROR_RSP || type != SDP_SVC_SEARCH_RSP) {
		error("SDP error: %s (%d)", strerror(EPROTO), EPROTO);
		cb_err = EPROTO;
		goto failed;
	}

	pdata = rsp;
	tsrc = ntohs(bt_get_unaligned((uint16_t *) pdata));
	if (tsrc <= 0)
		goto failed;
	pdata += sizeof(uint16_t);

	csrc = ntohs(bt_get_unaligned((uint16_t *) pdata));
	if (csrc <= 0)
		goto failed;
	pdata += sizeof(uint16_t);

	handle = malloc(sizeof(*handle));
	if (!handle) {
		cb_err = ENOMEM;
		goto failed;
	}
	*handle = ntohl(bt_get_unaligned((uint32_t*)pdata));

	free(d->search_data);
	d->search_data = handle;

	cb_err = get_rec_with_handle_conn_cb(ctxt);
	if (cb_err)
		goto failed;

	return;

failed:
	get_record_data_call_cb(d, NULL, cb_err);
	get_record_data_free(d);
	transaction_context_free(ctxt);
}

static int get_rec_with_uuid_conn_cb(struct transaction_context *ctxt)
{
	get_record_data_t *d = ctxt->priv;
	sdp_list_t *search = NULL;
	uuid_t *uuid;
	int err = 0;

	if (sdp_set_notify(ctxt->session,
			get_rec_with_uuid_comp_cb, ctxt) < 0) {
		err = -EINVAL;
		goto failed;
	}

	uuid = (uuid_t *)d->search_data;
	search = sdp_list_append(NULL, uuid);

	if (sdp_service_search_async(ctxt->session, search, 64) < 0) {
		error("send request failed: %s (%d)", strerror(errno), errno);
		err = -sdp_get_error(ctxt->session);
		goto failed;
	}

failed:
	if (search)
		sdp_list_free(search, NULL);

	return err;
}

int get_record_with_uuid(DBusConnection *conn, DBusMessage *msg,
			uint16_t dev_id, const char *dst,
			const uuid_t *uuid, get_record_cb_t *cb, void *data)
{
	struct pending_connect *c;
	get_record_data_t *d;
	int err;
	uuid_t *sdp_uuid;

	/* FIXME: search the cache first! */

	if (find_pending_connect(dst)) {
		error("SDP search in progress!");
		return -EINPROGRESS;
	}

	sdp_uuid = malloc(sizeof(uuid_t));
	if (!sdp_uuid)
		return -ENOMEM;

	memcpy(sdp_uuid, uuid, sizeof(uuid_t));

	d = get_record_data_new(dev_id, dst, sdp_uuid, cb, data);
	if (!d) {
		free(sdp_uuid);
		return -ENOMEM;
	}

	if (!(c = connect_request(conn, msg, dev_id, dst,
				get_rec_with_uuid_conn_cb, &err))) {
		error("Search request failed: %s (%d)", strerror(err), err);
		get_record_data_free(d);
		return -err;
	}

	c->priv = d;

	return 0;
}
