/*
 *
 *  BlueZ - Bluetooth protocol stack for Linux
 *
 *  Copyright (C) 2006-2007  Nokia Corporation
 *  Copyright (C) 2004-2008  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 <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.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 <glib.h>

#include <dbus/dbus.h>

#include "dbus.h"
#include "dbus-helper.h"
#include "hcid.h"
#include "textfile.h"
#include "adapter.h"
#include "dbus-hci.h"
#include "dbus-common.h"
#include "dbus-error.h"
#include "error.h"
#include "dbus-sdp.h"
#include "sdp-xml.h"

#define SESSION_TIMEOUT 2000
#define DEFAULT_XML_BUF_SIZE	1024

struct transaction_context {
	DBusConnection	*conn;
	DBusMessage	*rq;
	sdp_session_t	*session;
	GIOChannel	*io;
	guint		io_id;
	uuid_t		uuid;
	GSList		*identifiers;
};

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;
};

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

struct cached_session {
	sdp_session_t *session;
	guint timeout_id;
	guint io_id;
};

static GSList *cached_sessions = NULL;

static gboolean session_timeout(gpointer user_data)
{
	struct cached_session *s = user_data;

	debug("sdp session timed out. closing");

	cached_sessions = g_slist_remove(cached_sessions, s);

	g_source_remove(s->io_id);
	sdp_close(s->session);
	g_free(s);

	return FALSE;
}

gboolean idle_callback(GIOChannel *io, GIOCondition cond, gpointer user_data)
{
	struct cached_session *s = user_data;

	if (cond & G_IO_NVAL)
		return FALSE;

	if (cond & (G_IO_ERR | G_IO_HUP))
		debug("idle_callback: session got disconnected");

	if (cond & G_IO_IN)
		debug("got unexpected input on idle SDP socket");

	cached_sessions = g_slist_remove(cached_sessions, s);

	g_source_remove(s->timeout_id);
	sdp_close(s->session);
	g_free(s);

	return FALSE;
}

static void cache_sdp_session(sdp_session_t *sess, GIOChannel *io)
{
	struct cached_session *s;

	s = g_new0(struct cached_session, 1);

	s->session = sess;
	s->timeout_id = g_timeout_add(SESSION_TIMEOUT, session_timeout, s);
	s->io_id = g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
					idle_callback, s);

	cached_sessions = g_slist_append(cached_sessions, s);

	debug("sdp session added to cache");
}

static int get_bdaddrs(int sock, bdaddr_t *sba, bdaddr_t *dba)
{
	struct sockaddr_l2 a;
	socklen_t len;

	len = sizeof(a);
	if (getsockname(sock, (struct sockaddr *) &a, &len) < 0) {
		error("getsockname: %s (%d)", strerror(errno), errno);
		return -1;
	}

	bacpy(sba, &a.l2_bdaddr);

	len = sizeof(a);
	if (getpeername(sock, (struct sockaddr *) &a, &len) < 0) {
		error("getpeername: %s (%d)", strerror(errno), errno);
		return -1;
	}

	bacpy(dba, &a.l2_bdaddr);

	return 0;
}

static struct cached_session *get_cached_session(bdaddr_t *src, bdaddr_t *dst)
{
	GSList *l;

	for (l = cached_sessions; l != NULL; l = l->next) {
		struct cached_session *s = l->data;
		int sock = sdp_get_socket(s->session);
		bdaddr_t sba, dba;

		if (get_bdaddrs(sock, &sba, &dba) < 0)
			continue;

		if (bacmp(&sba, src) || bacmp(&dba, dst))
			continue;

		debug("found matching session, removing from list");

		cached_sessions = g_slist_remove(cached_sessions, s);

		return s;
	}

	return NULL;
}

static sdp_session_t *get_sdp_session(bdaddr_t *src, bdaddr_t *dst)
{
	struct cached_session *s;
	sdp_session_t *session;

	s = get_cached_session(src, dst);
	if (!s) {
		debug("no matching session found. creating a new one");
		return sdp_connect(src, dst, SDP_NON_BLOCKING);
	}

	session = s->session;

	g_source_remove(s->timeout_id);
	g_source_remove(s->io_id);
	g_free(s);

	return session;
}

static void append_and_grow_string(void *data, const char *str)
{
	sdp_buf_t *buff = data;
	int len;

	len = strlen(str);

	if (!buff->data) {
		buff->data = malloc(DEFAULT_XML_BUF_SIZE);
		if (!buff->data)
			return;
		buff->buf_size = DEFAULT_XML_BUF_SIZE;
	}

	/* Grow string */
	while (buff->buf_size < (buff->data_size + len + 1)) {
		void *tmp;
		uint32_t new_size;

		/* Grow buffer by a factor of 2 */
		new_size = (buff->buf_size << 1);

		tmp = realloc(buff->data, new_size);
		if (!tmp)
			return;

		buff->data = tmp;
		buff->buf_size = new_size;
	}

	/* Include the NULL character */
	memcpy(buff->data + buff->data_size, str, len + 1);
	buff->data_size += len;
}

/* 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"		},
	{ "hsp",	HEADSET_SVCLASS_ID,		"Headset"		},
	{ "hfp",	HANDSFREE_SVCLASS_ID,		"Handsfree"		},
	{ 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;
}

/* list of remote and local service records */
static GSList *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 = g_new0(struct pending_connect, 1);

	if (dst)
		c->dst = g_strdup(dst);

	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;

	g_free(c->dst);

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

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

	g_free(c);
}

static struct pending_connect *find_pending_connect(const char *dst)
{
	GSList *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 const char *get_address_from_message(DBusConnection *conn, DBusMessage *msg)
{
	struct adapter *adapter;
	const char *path;

	path = dbus_message_get_path(msg);
	if (!path)
		return NULL;

	if (dbus_connection_get_object_user_data(conn, path, (void *) &adapter) == FALSE)
		return NULL;

	return adapter->address;
}

static int sdp_store_record(const char *src, const char *dst, uint32_t handle, uint8_t *buf, size_t size)
{
	char filename[PATH_MAX + 1], key[28], *value;
	int i, err;

	create_name(filename, PATH_MAX, STORAGEDIR, src, "sdp");

	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);

	snprintf(key, sizeof(key), "%17s#%08X", dst, handle);

	value = g_malloc0(size * 2 + 1);

	for (i = 0; i < size; i++)
		sprintf(value + (i * 2), "%02X", buf[i]);

	err = textfile_put(filename, key, value);

	g_free(value);

	return err;
}

static void transaction_context_free(void *udata, gboolean cache)
{
	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 && !ctxt->io)
		sdp_close(ctxt->session);

	if (ctxt->session && ctxt->io) {
		g_source_remove(ctxt->io_id);

		if (cache)
			cache_sdp_session(ctxt->session, ctxt->io);
		else
			sdp_close(ctxt->session);

		g_io_channel_unref(ctxt->io);
	}

	if (ctxt->identifiers) {
		g_slist_foreach(ctxt->identifiers, (GFunc) g_free, NULL);
		g_slist_free(ctxt->identifiers);
	}

	g_free(ctxt);
}

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) {
		error_failed_errno(ctxt->conn, ctxt->rq, err);
		transaction_context_free(ctxt, FALSE);
	}

	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;
	sdp_record_t *rec;
	DBusMessage *reply;
	DBusMessageIter iter, array_iter;
	const char *src, *dst;
	int 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_errno(ctxt->conn, ctxt->rq, EINVAL);
			goto failed;
		}

		error("search failed: %s (%d)", strerror(sdp_err), sdp_err);
		error_failed_errno(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_errno(ctxt->conn, ctxt->rq, EPROTO);
		goto failed;
	}

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

	src = get_address_from_message(ctxt->conn, ctxt->rq);

	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 || size != scanned) {
		error("Invalid service record!");
		goto done;
	}

	sdp_store_record(src, dst, rec->handle, rsp, size);

	sdp_record_free(rec);

	dbus_message_iter_append_fixed_array(&array_iter,
			DBUS_TYPE_BYTE, &rsp, size);

done:
	dbus_message_iter_close_container(&iter, &array_iter);
	send_message_and_unref(ctxt->conn, reply);

failed:
	transaction_context_free(ctxt, TRUE);
}

static void remote_svc_rec_completed_xml_cb(uint8_t type, uint16_t err,
						uint8_t *rsp, size_t size,
						void *udata)
{
	struct transaction_context *ctxt = udata;
	sdp_record_t *rec;
	DBusMessage *reply;
	const char *src, *dst;
	int scanned;
	sdp_buf_t result;

	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_errno(ctxt->conn, ctxt->rq, EINVAL);
			goto failed;
		}

		error("search failed: %s (%d)", strerror(sdp_err), sdp_err);
		error_failed_errno(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_errno(ctxt->conn, ctxt->rq, EPROTO);
		goto failed;
	}

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

	src = get_address_from_message(ctxt->conn, ctxt->rq);

	reply = dbus_message_new_method_return(ctxt->rq);

	rec = sdp_extract_pdu(rsp, &scanned);
	if (rec == NULL || size != scanned) {
		error("Invalid service record!");
		goto done;
	}

	sdp_store_record(src, dst, rec->handle, rsp, size);

	memset(&result, 0, sizeof(sdp_buf_t));

	convert_sdp_record_to_xml(rec, &result, append_and_grow_string);

	sdp_record_free(rec);

	if (result.data) {
		dbus_message_append_args(reply,
				DBUS_TYPE_STRING, &result.data,
				DBUS_TYPE_INVALID);

		free(result.data);
	}
done:
	send_message_and_unref(ctxt->conn, reply);

failed:
	transaction_context_free(ctxt, TRUE);
}

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 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_errno(ctxt->conn, ctxt->rq, EINVAL);
			goto failed;
		}

		error("search failed: %s (%d)", strerror(sdp_err), sdp_err);
		error_failed_errno(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_errno(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);

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

	pdata += sizeof(uint16_t);

	do {
		uint32_t handle = ntohl(bt_get_unaligned((uint32_t*)pdata));
		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_message_and_unref(ctxt->conn, reply);

failed:
	transaction_context_free(ctxt, TRUE);
}

static const char *extract_service_class(sdp_data_t *d)
{
	sdp_data_t *seq;
	uuid_t *uuid;
	static char uuid_str[37];

	/* Expected sequence of UUID16 */
	if (d->attrId != SDP_ATTR_SVCLASS_ID_LIST)
		return NULL;

	if (d->dtd != SDP_SEQ8 && d->dtd != SDP_SEQ16 && d->dtd != SDP_SEQ32)
		return NULL;

	if (!d->val.dataseq)
		return NULL;

	seq = d->val.dataseq;
	if (!SDP_IS_UUID(seq->dtd))
		return NULL;

	uuid = &seq->val.uuid;
	if (uuid->type != SDP_UUID16)
		return NULL;

	sprintf(uuid_str, "0000%04x-0000-1000-8000-00805f9b34fb",
							uuid->value.uuid16);

	return uuid_str;
}

static int service_search_attr(struct transaction_context *ctxt, uint16_t uuid)
{
	sdp_list_t *attrids, *search;
	uint32_t range = 0x0000ffff;
	int ret = 0;

	sdp_uuid16_create(&ctxt->uuid, uuid);

	search = sdp_list_append(0, &ctxt->uuid);
	attrids = sdp_list_append(NULL, &range);

	/*
	 * Create/send the search request and set the
	 * callback to indicate the request completion
	 */
	if (sdp_service_search_attr_async(ctxt->session, search,
				SDP_ATTR_REQ_RANGE, attrids) < 0)
		ret = -sdp_get_error(ctxt->session);

	sdp_list_free(search, NULL);
	sdp_list_free(attrids, NULL);

	return ret;
}

static void remote_svc_identifiers_completed_cb(uint8_t type, uint16_t err,
			uint8_t *rsp, size_t size, void *udata)
{
	struct transaction_context *ctxt = udata;
	const char *src, *dst, *puuid;
	const char *devid_uuid = "00001200-0000-1000-8000-00805f9b34fb";
	char **identifiers;
	DBusMessage *reply;
	GSList *l = NULL;
	int scanned, extracted = 0, len = 0, recsize = 0;
	uint8_t dtd = 0;

	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_errno(ctxt->conn, ctxt->rq, EINVAL);
			goto failed;
		}

		error("search failed: %s (%d)", strerror(sdp_err), sdp_err);
		error_failed_errno(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_ATTR_RSP) {
		error("SDP error: %s (%d)", strerror(EPROTO), EPROTO);
		error_failed_errno(ctxt->conn, ctxt->rq, EPROTO);
		goto failed;
	}

	src = get_address_from_message(ctxt->conn, ctxt->rq);
	dbus_message_get_args(ctxt->rq, NULL,
			DBUS_TYPE_STRING, &dst,
			DBUS_TYPE_INVALID);

	scanned = sdp_extract_seqtype(rsp, &dtd, &len);
	rsp += scanned;
	for (; extracted < len; rsp += recsize, extracted += recsize) {
		sdp_record_t *rec;
		sdp_data_t *d;

		recsize = 0;
		rec = sdp_extract_pdu(rsp, &recsize);
		if (!rec)
			break;

		sdp_store_record(src, dst, rec->handle, rsp, recsize);

		d = sdp_data_get(rec, SDP_ATTR_SVCLASS_ID_LIST);
		if (!d) {
			sdp_record_free(rec);
			continue;
		}

		puuid = extract_service_class(d);
		sdp_record_free(rec);
		if (!puuid)
			continue;

		/* Ignore repeated identifiers */
		l = g_slist_find_custom(ctxt->identifiers,
				puuid, (GCompareFunc) strcmp);
		if (l)
			continue;

		ctxt->identifiers = g_slist_append(ctxt->identifiers,
							g_strdup(puuid));
	}

	/* If public browse response is empty: search for L2CAP */
	if (!ctxt->identifiers && ctxt->uuid.value.uuid16 == PUBLIC_BROWSE_GROUP)
		if (service_search_attr(ctxt, L2CAP_UUID) == 0)
			return; /* Wait the response */

	/* Request DeviceID if it was not returned previously */
	l = g_slist_find_custom(ctxt->identifiers,
			devid_uuid, (GCompareFunc) strcmp);
	if (!l && ctxt->uuid.value.uuid16 != PNP_INFO_SVCLASS_ID)
		if (service_search_attr(ctxt, PNP_INFO_SVCLASS_ID) == 0)
			return; /* Wait the response */

	reply = dbus_message_new_method_return(ctxt->rq);

	identifiers = g_new(char *, g_slist_length(ctxt->identifiers));

	for (l = ctxt->identifiers, len = 0; l; l = l->next, len++)
		identifiers[len] = l->data;

	dbus_message_append_args(reply,
			DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
			&identifiers, len,
			DBUS_TYPE_INVALID);
	send_message_and_unref(ctxt->conn, reply);

	if (len)
		dbus_connection_emit_signal(ctxt->conn,
				dbus_message_get_path(ctxt->rq),
				ADAPTER_INTERFACE,
				"RemoteIdentifiersUpdated",
				DBUS_TYPE_STRING, &dst,
				DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
				&identifiers, len,
				DBUS_TYPE_INVALID);

	if (identifiers)
		g_free(identifiers);

failed:
	transaction_context_free(ctxt, TRUE);
}

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 = g_new0(struct transaction_context, 1);

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

	/* 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 */
	ctxt->io_id = g_io_add_watch(chan,
				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
				search_process_cb, ctxt);
	ctxt->io = g_io_channel_ref(chan);

	goto done;

failed:
	error_connection_attempt_failed(c->conn, c->rq, err);

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

done:
	pending_connects = g_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 = get_sdp_session(&srcba, &dstba);
	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);
	g_io_channel_unref(chan);
	pending_connects = g_slist_append(pending_connects, c);

	return c;
}

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

	if (sdp_set_notify(ctxt->session, remote_svc_rec_completed_cb, ctxt) < 0)
		return -EINVAL;

	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) {
		sdp_list_free(attrids, NULL);
		return -sdp_get_error(ctxt->session);
	}

	sdp_list_free(attrids, NULL);

	return 0;
}

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

	if (sdp_set_notify(ctxt->session, remote_svc_rec_completed_xml_cb, ctxt) < 0)
		return -EINVAL;

	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) {
		sdp_list_free(attrids, NULL);
		return -sdp_get_error(ctxt->session);
	}

	sdp_list_free(attrids, NULL);

	return 0;
}

DBusHandlerResult get_remote_svc_rec(DBusConnection *conn, DBusMessage *msg,
				void *data, sdp_format_t format)
{
	struct adapter *adapter = data;
	const char *dst;
	uint32_t handle;
	int err;
	connect_cb_t *cb;

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

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

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

	cb = remote_svc_rec_conn_cb;
	if (format == SDP_FORMAT_XML)
		cb = remote_svc_rec_conn_xml_cb;

	if (!connect_request(conn, msg, adapter->dev_id,
				dst, cb, &err)) {
		error("Search request failed: %s (%d)", strerror(err), err);
		return error_failed_errno(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;

	if (sdp_set_notify(ctxt->session, remote_svc_handles_completed_cb, ctxt) < 0)
		return -EINVAL;

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

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

	search = sdp_list_append(0, &ctxt->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);
		sdp_list_free(search, NULL);
		return -sdp_get_error(ctxt->session);
	}

	sdp_list_free(search, NULL);

	return 0;
}

static int remote_svc_identifiers_conn_cb(struct transaction_context *ctxt)
{
	if (sdp_set_notify(ctxt->session,
			remote_svc_identifiers_completed_cb, ctxt) < 0)
		return -EINVAL;

	return service_search_attr(ctxt, PUBLIC_BROWSE_GROUP);
}

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

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

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

	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, NULL);
		}
	}

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

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

	return DBUS_HANDLER_RESULT_HANDLED;
}

DBusHandlerResult get_remote_svc_identifiers(DBusConnection *conn, DBusMessage *msg, void *data)
{
	struct adapter *adapter = data;
	const char *dst;
	int err;

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

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

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

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

	return DBUS_HANDLER_RESULT_HANDLED;
}

DBusHandlerResult finish_remote_svc_transact(DBusConnection *conn,
						DBusMessage *msg, void *data)
{
	struct cached_session *s;
	const char *address;
	struct adapter *adapter = data;
	DBusMessage *reply;
	bdaddr_t sba, dba;

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

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

	str2ba(adapter->address, &sba);
	str2ba(address, &dba);

	while ((s = get_cached_session(&sba, &dba))) {
		sdp_close(s->session);
		g_source_remove(s->timeout_id);
		g_source_remove(s->io_id);
		g_free(s);
	}

	return send_message_and_unref(conn, reply);
}
