/*
 *
 *  OBEX Client
 *
 *  Copyright (C) 2007-2010  Marcel Holtmann <marcel@holtmann.org>
 *  Copyright (C) 2011-2012  BMW Car IT GmbH. All rights reserved.
 *
 *
 *  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 <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <sys/stat.h>

#include <glib.h>
#include <gdbus/gdbus.h>
#include <gobex/gobex.h>

#include "dbus.h"
#include "log.h"
#include "transfer.h"
#include "session.h"
#include "driver.h"
#include "transport.h"

#define SESSION_INTERFACE "org.bluez.obex.Session1"
#define ERROR_INTERFACE "org.bluez.obex.Error"
#define SESSION_BASEPATH "/org/bluez/obex/client"

#define OBEX_IO_ERROR obex_io_error_quark()
#define OBEX_IO_ERROR_FIRST (0xff + 1)

enum {
	OBEX_IO_DISCONNECTED = OBEX_IO_ERROR_FIRST,
	OBEX_IO_BUSY,
};

static guint64 counter = 0;

struct callback_data {
	struct obc_session *session;
	session_callback_t func;
	void *data;
};

struct pending_request;
typedef int (*session_process_t) (struct pending_request *p, GError **err);
typedef void (*destroy_t) (void *data);

struct pending_request {
	guint id;
	guint req_id;
	struct obc_session *session;
	session_process_t process;
	struct obc_transfer *transfer;
	session_callback_t func;
	void *data;
	destroy_t destroy;
};

struct setpath_data {
	char **remaining;
	int index;
	session_callback_t func;
	void *user_data;
};

struct file_data {
	char *srcname;
	char *destname;
	session_callback_t func;
	void *user_data;
};

struct obc_session {
	guint id;
	int refcount;
	char *source;
	char *destination;
	uint8_t channel;
	struct obc_transport *transport;
	struct obc_driver *driver;
	char *path;		/* Session path */
	DBusConnection *conn;
	GObex *obex;
	struct pending_request *p;
	char *owner;		/* Session owner */
	guint watch;
	GQueue *queue;
	guint process_id;
	char *folder;
};

static GSList *sessions = NULL;

static void session_process_queue(struct obc_session *session);
static void session_terminate_transfer(struct obc_session *session,
					struct obc_transfer *transfer,
					GError *gerr);
static void transfer_complete(struct obc_transfer *transfer,
					GError *err, void *user_data);

static GQuark obex_io_error_quark(void)
{
	return g_quark_from_static_string("obex-io-error-quark");
}

struct obc_session *obc_session_ref(struct obc_session *session)
{
	int refs = __sync_add_and_fetch(&session->refcount, 1);

	DBG("%p: ref=%d", session, refs);

	return session;
}

static void session_unregistered(struct obc_session *session)
{
	char *path;

	if (session->driver && session->driver->remove)
		session->driver->remove(session);

	path = session->path;
	session->path = NULL;

	g_dbus_unregister_interface(session->conn, path, SESSION_INTERFACE);

	DBG("Session(%p) unregistered %s", session, path);

	g_free(path);
}

static struct pending_request *pending_request_new(struct obc_session *session,
						session_process_t process,
						struct obc_transfer *transfer,
						session_callback_t func,
						void *data,
						destroy_t destroy)
{
	struct pending_request *p;
	static guint id = 0;

	p = g_new0(struct pending_request, 1);
	p->id = ++id;
	p->session = obc_session_ref(session);
	p->process = process;
	p->destroy = destroy;
	p->transfer = transfer;
	p->func = func;
	p->data = data;

	return p;
}

static void pending_request_free(struct pending_request *p)
{
	if (p->req_id > 0)
		g_obex_cancel_req(p->session->obex, p->req_id, TRUE);

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

	if (p->transfer)
		obc_transfer_unregister(p->transfer);

	if (p->session)
		obc_session_unref(p->session);

	g_free(p);
}

static void setpath_data_free(void *process_data)
{
	struct setpath_data *data = process_data;

	g_strfreev(data->remaining);
	g_free(data);
}

static void file_data_free(void *process_data)
{
	struct file_data *data = process_data;

	g_free(data->srcname);
	g_free(data->destname);
	g_free(data);
}

static void session_free(struct obc_session *session)
{
	DBG("%p", session);

	if (session->process_id != 0)
		g_source_remove(session->process_id);

	if (session->queue) {
		g_queue_foreach(session->queue, (GFunc) pending_request_free,
									NULL);
		g_queue_free(session->queue);
	}

	if (session->watch)
		g_dbus_remove_watch(session->conn, session->watch);

	if (session->obex) {
		g_obex_set_disconnect_function(session->obex, NULL, NULL);
		g_obex_unref(session->obex);
	}

	if (session->id > 0 && session->transport != NULL)
		session->transport->disconnect(session->id);

	if (session->path)
		session_unregistered(session);

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

	if (session->p)
		pending_request_free(session->p);

	g_free(session->path);
	g_free(session->owner);
	g_free(session->source);
	g_free(session->destination);
	g_free(session->folder);
	g_free(session);
}

static void disconnect_complete(GObex *obex, GError *err, GObexPacket *rsp,
							void *user_data)
{
	struct obc_session *session = user_data;

	DBG("");

	if (err)
		error("%s", err->message);

	/* Disconnect transport */
	if (session->id > 0 && session->transport != NULL) {
		session->transport->disconnect(session->id);
		session->id = 0;
	}

	session_free(session);
}

void obc_session_unref(struct obc_session *session)
{
	int refs;

	refs = __sync_sub_and_fetch(&session->refcount, 1);

	DBG("%p: ref=%d", session, refs);

	if (refs > 0)
		return;

	sessions = g_slist_remove(sessions, session);

	if (!session->obex)
		goto disconnect;

	/* Wait OBEX Disconnect to complete if command succeed otherwise
	 * proceed with transport disconnection since there is nothing else to
	 * be done */
	if (g_obex_disconnect(session->obex, disconnect_complete, session,
									NULL))
		return;

disconnect:
	/* Disconnect transport */
	if (session->id > 0 && session->transport != NULL) {
		session->transport->disconnect(session->id);
		session->id = 0;
	}

	session_free(session);
}

static void connect_cb(GObex *obex, GError *err, GObexPacket *rsp,
							gpointer user_data)
{
	struct callback_data *callback = user_data;
	GError *gerr = NULL;
	uint8_t rsp_code;

	if (err != NULL) {
		error("connect_cb: %s", err->message);
		gerr = g_error_copy(err);
		goto done;
	}

	rsp_code = g_obex_packet_get_operation(rsp, NULL);
	if (rsp_code != G_OBEX_RSP_SUCCESS)
		gerr = g_error_new(OBEX_IO_ERROR, -EIO,
				"OBEX Connect failed with 0x%02x", rsp_code);

done:
	callback->func(callback->session, NULL, gerr, callback->data);
	if (gerr != NULL)
		g_error_free(gerr);
	obc_session_unref(callback->session);
	g_free(callback);
}

static void session_disconnected(GObex *obex, GError *err, gpointer user_data)
{
	struct obc_session *session = user_data;

	if (err)
		error("%s", err->message);

	obc_session_shutdown(session);
}

static void transport_func(GIOChannel *io, GError *err, gpointer user_data)
{
	struct callback_data *callback = user_data;
	struct obc_session *session = callback->session;
	struct obc_driver *driver = session->driver;
	struct obc_transport *transport = session->transport;
	GObex *obex;
	GObexApparam *apparam;
	GObexTransportType type;
	int tx_mtu = -1;
	int rx_mtu = -1;

	DBG("");

	if (err != NULL) {
		error("%s", err->message);
		goto done;
	}

	g_io_channel_set_close_on_unref(io, FALSE);

	if (transport->getpacketopt &&
			transport->getpacketopt(io, &tx_mtu, &rx_mtu) == 0)
		type = G_OBEX_TRANSPORT_PACKET;
	else
		type = G_OBEX_TRANSPORT_STREAM;

	obex = g_obex_new(io, type, tx_mtu, rx_mtu);
	if (obex == NULL)
		goto done;

	g_io_channel_set_close_on_unref(io, TRUE);

	apparam = NULL;

	if (driver->supported_features)
		apparam = driver->supported_features(session);

	if (apparam) {
		uint8_t buf[1024];
		ssize_t len;

		len = g_obex_apparam_encode(apparam, buf, sizeof(buf));
		if (driver->target)
			g_obex_connect(obex, connect_cb, callback, &err,
					G_OBEX_HDR_TARGET,
					driver->target, driver->target_len,
					G_OBEX_HDR_APPARAM,
					buf, len,
					G_OBEX_HDR_INVALID);
		else
			g_obex_connect(obex, connect_cb, callback, &err,
					G_OBEX_HDR_APPARAM, buf, len,
					G_OBEX_HDR_INVALID);
		g_obex_apparam_free(apparam);
	} else if (driver->target)
		g_obex_connect(obex, connect_cb, callback, &err,
			G_OBEX_HDR_TARGET, driver->target, driver->target_len,
			G_OBEX_HDR_INVALID);
	else
		g_obex_connect(obex, connect_cb, callback, &err,
							G_OBEX_HDR_INVALID);

	if (err != NULL) {
		error("%s", err->message);
		g_obex_unref(obex);
		goto done;
	}

	session->obex = obex;
	sessions = g_slist_prepend(sessions, session);

	g_obex_set_disconnect_function(obex, session_disconnected, session);

	return;
done:
	callback->func(callback->session, NULL, err, callback->data);
	obc_session_unref(callback->session);
	g_free(callback);
}

static void owner_disconnected(DBusConnection *connection, void *user_data)
{
	struct obc_session *session = user_data;

	DBG("");

	obc_session_shutdown(session);
}

int obc_session_set_owner(struct obc_session *session, const char *name,
			GDBusWatchFunction func)
{
	if (session == NULL)
		return -EINVAL;

	if (session->watch)
		g_dbus_remove_watch(session->conn, session->watch);

	session->watch = g_dbus_add_disconnect_watch(session->conn, name, func,
							session, NULL);
	if (session->watch == 0)
		return -EINVAL;

	session->owner = g_strdup(name);

	return 0;
}


static struct obc_session *session_find(const char *source,
						const char *destination,
						const char *service,
						uint8_t channel,
						const char *owner)
{
	GSList *l;

	for (l = sessions; l; l = l->next) {
		struct obc_session *session = l->data;

		if (g_strcmp0(session->destination, destination))
			continue;

		if (g_strcmp0(service, session->driver->service))
			continue;

		if (source && g_strcmp0(session->source, source))
			continue;

		if (channel && session->channel != channel)
			continue;

		if (g_strcmp0(owner, session->owner))
			continue;

		return session;
	}

	return NULL;
}

static gboolean connection_complete(gpointer data)
{
	struct callback_data *cb = data;

	cb->func(cb->session, NULL, NULL, cb->data);

	obc_session_unref(cb->session);

	g_free(cb);

	return FALSE;
}

static int session_connect(struct obc_session *session,
				session_callback_t function, void *user_data)
{
	struct callback_data *callback;
	struct obc_transport *transport = session->transport;
	struct obc_driver *driver = session->driver;

	callback = g_try_malloc0(sizeof(*callback));
	if (callback == NULL)
		return -ENOMEM;

	callback->func = function;
	callback->data = user_data;
	callback->session = obc_session_ref(session);

	/* Connection completed */
	if (session->obex) {
		g_idle_add(connection_complete, callback);
		return 0;
	}

	/* Ongoing connection */
	if (session->id > 0) {
		obc_session_unref(callback->session);
		g_free(callback);
		return 0;
	}

	session->id = transport->connect(session->source, session->destination,
					driver->uuid, session->channel,
					transport_func, callback);
	if (session->id == 0) {
		obc_session_unref(callback->session);
		g_free(callback);
		return -EINVAL;
	}

	return 0;
}

struct obc_session *obc_session_create(const char *source,
						const char *destination,
						const char *service,
						uint8_t channel,
						const char *owner,
						session_callback_t function,
						void *user_data)
{
	DBusConnection *conn;
	struct obc_session *session;
	struct obc_transport *transport;
	struct obc_driver *driver;

	if (destination == NULL)
		return NULL;

	session = session_find(source, destination, service, channel, owner);
	if (session != NULL)
		goto proceed;

	/* FIXME: Do proper transport lookup when the API supports it */
	transport = obc_transport_find("Bluetooth");
	if (transport == NULL)
		return NULL;

	driver = obc_driver_find(service);
	if (driver == NULL)
		return NULL;

	conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
	if (conn == NULL)
		return NULL;

	session = g_try_malloc0(sizeof(*session));
	if (session == NULL)
		return NULL;

	session->refcount = 1;
	session->transport = transport;
	session->driver = driver;
	session->conn = conn;
	session->source = g_strdup(source);
	session->destination = g_strdup(destination);
	session->channel = channel;
	session->queue = g_queue_new();
	session->folder = g_strdup("/");

	if (owner)
		obc_session_set_owner(session, owner, owner_disconnected);

proceed:
	if (session_connect(session, function, user_data) < 0) {
		obc_session_unref(session);
		return NULL;
	}

	DBG("session %p transport %s driver %s", session,
			session->transport->name, session->driver->service);

	return session;
}

void obc_session_shutdown(struct obc_session *session)
{
	struct pending_request *p;
	GError *err;

	DBG("%p", session);

	obc_session_ref(session);

	/* Unregister any pending transfer */
	err = g_error_new(OBEX_IO_ERROR, OBEX_IO_DISCONNECTED,
						"Session closed by user");

	if (session->p != NULL && session->p->id != 0) {
		p = session->p;
		session->p = NULL;

		if (p->func)
			p->func(session, p->transfer, err, p->data);

		pending_request_free(p);
	}

	while ((p = g_queue_pop_head(session->queue))) {
		if (p->func)
			p->func(session, p->transfer, err, p->data);

		pending_request_free(p);
	}

	g_error_free(err);

	/* Unregister interfaces */
	if (session->path)
		session_unregistered(session);

	obc_session_unref(session);
}

static void capabilities_complete_callback(struct obc_session *session,
						struct obc_transfer *transfer,
						GError *err, void *user_data)
{
	DBusMessage *message = user_data;
	char *contents;
	size_t size;
	int perr;

	if (err != NULL) {
		DBusMessage *error = g_dbus_create_error(message,
					ERROR_INTERFACE ".Failed",
					"%s", err->message);
		g_dbus_send_message(session->conn, error);
		goto done;
	}

	perr = obc_transfer_get_contents(transfer, &contents, &size);
	if (perr < 0) {
		DBusMessage *error = g_dbus_create_error(message,
						ERROR_INTERFACE ".Failed",
						"Error reading contents: %s",
						strerror(-perr));
		g_dbus_send_message(session->conn, error);
		goto done;
	}

	g_dbus_send_reply(session->conn, message,
						DBUS_TYPE_STRING, &contents,
						DBUS_TYPE_INVALID);
	g_free(contents);

done:
	dbus_message_unref(message);
}

static DBusMessage *get_capabilities(DBusConnection *connection,
					DBusMessage *message, void *user_data)
{
	struct obc_session *session = user_data;
	struct obc_transfer *pull;
	DBusMessage *reply;
	GError *gerr = NULL;

	pull = obc_transfer_get("x-obex/capability", NULL, NULL, &gerr);
	if (pull == NULL)
		goto fail;

	if (!obc_session_queue(session, pull, capabilities_complete_callback,
								message, &gerr))
		goto fail;

	dbus_message_ref(message);

	return NULL;

fail:
	reply = g_dbus_create_error(message, ERROR_INTERFACE ".Failed", "%s",
								gerr->message);
	g_error_free(gerr);
	return reply;

}

static gboolean get_source(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct obc_session *session = data;

	if (session->source == NULL)
		return FALSE;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
							&session->source);

	return TRUE;
}

static gboolean source_exists(const GDBusPropertyTable *property, void *data)
{
	struct obc_session *session = data;

	return session->source != NULL;
}

static gboolean get_destination(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct obc_session *session = data;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
							&session->destination);

	return TRUE;
}

static gboolean get_channel(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct obc_session *session = data;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_BYTE,
							&session->channel);

	return TRUE;
}

static const GDBusMethodTable session_methods[] = {
	{ GDBUS_ASYNC_METHOD("GetCapabilities",
				NULL, GDBUS_ARGS({ "capabilities", "s" }),
				get_capabilities) },
	{ }
};

static gboolean get_target(const GDBusPropertyTable *property,
					DBusMessageIter *iter, void *data)
{
	struct obc_session *session = data;

	if (session->driver->uuid == NULL)
		return FALSE;

	dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
						&session->driver->uuid);

	return TRUE;
}

static gboolean target_exists(const GDBusPropertyTable *property, void *data)
{
	struct obc_session *session = data;

	return session->driver->uuid != NULL;
}

static const GDBusPropertyTable session_properties[] = {
	{ "Source", "s", get_source, NULL, source_exists },
	{ "Destination", "s", get_destination },
	{ "Channel", "y", get_channel },
	{ "Target", "s", get_target, NULL, target_exists },
	{ }
};

static gboolean session_process(gpointer data)
{
	struct obc_session *session = data;

	session->process_id = 0;

	session_process_queue(session);

	return FALSE;
}

static void session_queue(struct pending_request *p)
{
	g_queue_push_tail(p->session->queue, p);

	if (p->session->process_id == 0)
		p->session->process_id = g_idle_add(session_process,
								p->session);
}

static int session_process_transfer(struct pending_request *p, GError **err)
{
	if (!obc_transfer_start(p->transfer, p->session->obex, err))
		return -1;

	DBG("Tranfer(%p) started", p->transfer);
	p->session->p = p;
	return 0;
}

guint obc_session_queue(struct obc_session *session,
				struct obc_transfer *transfer,
				session_callback_t func, void *user_data,
				GError **err)
{
	struct pending_request *p;

	if (session->obex == NULL) {
		obc_transfer_unregister(transfer);
		g_set_error(err, OBEX_IO_ERROR, -ENOTCONN,
						"Session not connected");
		return 0;
	}

	if (!obc_transfer_register(transfer, session->conn, session->path,
							session->owner, err)) {
		obc_transfer_unregister(transfer);
		return 0;
	}

	obc_transfer_set_callback(transfer, transfer_complete, session);

	p = pending_request_new(session, session_process_transfer, transfer,
							func, user_data, NULL);
	session_queue(p);
	return p->id;
}

static void session_process_queue(struct obc_session *session)
{
	struct pending_request *p;

	if (session->p != NULL)
		return;

	if (session->queue == NULL || g_queue_is_empty(session->queue))
		return;

	obc_session_ref(session);

	while ((p = g_queue_pop_head(session->queue))) {
		GError *gerr = NULL;

		if (p->process(p, &gerr) == 0)
			break;

		if (p->func)
			p->func(session, p->transfer, gerr, p->data);

		g_clear_error(&gerr);

		pending_request_free(p);
	}

	obc_session_unref(session);
}

static int pending_transfer_cmptransfer(gconstpointer a, gconstpointer b)
{
	const struct pending_request *p = a;
	const struct obc_transfer *transfer = b;

	if (p->transfer == transfer)
		return 0;

	return -1;
}

static void session_terminate_transfer(struct obc_session *session,
					struct obc_transfer *transfer,
					GError *gerr)
{
	struct pending_request *p = session->p;

	if (p == NULL || p->transfer != transfer) {
		GList *match;

		match = g_list_find_custom(session->queue->head, transfer,
						pending_transfer_cmptransfer);
		if (match == NULL)
			return;

		p = match->data;
		g_queue_delete_link(session->queue, match);
	} else
		session->p = NULL;

	obc_session_ref(session);

	if (p->func)
		p->func(session, p->transfer, gerr, p->data);

	pending_request_free(p);

	if (session->p == NULL)
		session_process_queue(session);

	obc_session_unref(session);
}

static void session_notify_complete(struct obc_session *session,
				struct obc_transfer *transfer)
{
	DBG("Transfer(%p) complete", transfer);

	session_terminate_transfer(session, transfer, NULL);
}

static void session_notify_error(struct obc_session *session,
				struct obc_transfer *transfer,
				GError *err)
{
	error("Transfer(%p) Error: %s", transfer, err->message);

	session_terminate_transfer(session, transfer, err);
}

static void transfer_complete(struct obc_transfer *transfer,
					GError *err, void *user_data)
{
	struct obc_session *session = user_data;

	if (err != 0)
		goto fail;

	session_notify_complete(session, transfer);

	return;

fail:
	session_notify_error(session, transfer, err);
}

const char *obc_session_register(struct obc_session *session,
						GDBusDestroyFunction destroy)
{
	if (session->path)
		return session->path;

	session->path = g_strdup_printf("%s/session%ju",
						SESSION_BASEPATH, counter++);

	if (g_dbus_register_interface(session->conn, session->path,
					SESSION_INTERFACE, session_methods,
					NULL, session_properties, session,
					destroy) == FALSE)
		goto fail;

	if (session->driver->probe && session->driver->probe(session) < 0) {
		g_dbus_unregister_interface(session->conn, session->path,
							SESSION_INTERFACE);
		goto fail;
	}

	DBG("Session(%p) registered %s", session, session->path);

	return session->path;

fail:
	g_free(session->path);
	session->path = NULL;
	return NULL;
}

const void *obc_session_get_attribute(struct obc_session *session,
							int attribute_id)
{
	if (session == NULL || session->id == 0)
		return NULL;

	return session->transport->getattribute(session->id, attribute_id);
}

const char *obc_session_get_owner(struct obc_session *session)
{
	if (session == NULL)
		return NULL;

	return session->owner;
}

const char *obc_session_get_destination(struct obc_session *session)
{
	return session->destination;
}

const char *obc_session_get_path(struct obc_session *session)
{
	return session->path;
}

const char *obc_session_get_target(struct obc_session *session)
{
	return session->driver->target;
}

const char *obc_session_get_folder(struct obc_session *session)
{
	return session->folder;
}

static void setpath_complete(struct obc_session *session,
						struct obc_transfer *transfer,
						GError *err, void *user_data)
{
	struct pending_request *p = user_data;

	if (p->func)
		p->func(session, NULL, err, p->data);

	if (session->p == p)
		session->p = NULL;

	pending_request_free(p);

	session_process_queue(session);
}

static void setpath_op_complete(struct obc_session *session,
						struct obc_transfer *transfer,
						GError *err, void *user_data)
{
	struct setpath_data *data = user_data;

	if (data->func)
		data->func(session, NULL, err, data->user_data);
}

static void setpath_set_folder(struct obc_session *session, const char *cur)
{
	char *folder = NULL;
	const char *delim;

	delim = strrchr(session->folder, '/');
	if (strlen(cur) == 0 || delim == NULL ||
			(strcmp(cur, "..") == 0 && delim == session->folder)) {
		folder = g_strdup("/");
	} else {
		if (strcmp(cur, "..") == 0) {
			folder = g_strndup(session->folder,
						delim - session->folder);
		} else {
			if (g_str_has_suffix(session->folder, "/"))
				folder = g_strconcat(session->folder,
								cur, NULL);
			else
				folder = g_strconcat(session->folder, "/",
								cur, NULL);
		}
	}
	g_free(session->folder);
	session->folder = folder;
}

static void setpath_cb(GObex *obex, GError *err, GObexPacket *rsp,
							gpointer user_data)
{
	struct pending_request *p = user_data;
	struct setpath_data *data = p->data;
	char *next;
	char *current;
	guint8 code;

	p->req_id = 0;

	if (err != NULL) {
		setpath_complete(p->session, NULL, err, user_data);
		return;
	}

	code = g_obex_packet_get_operation(rsp, NULL);
	if (code != G_OBEX_RSP_SUCCESS) {
		GError *gerr = NULL;
		g_set_error(&gerr, OBEX_IO_ERROR, code, "%s",
							g_obex_strerror(code));
		setpath_complete(p->session, NULL, gerr, user_data);
		g_clear_error(&gerr);
		return;
	}

	current = data->remaining[data->index - 1];
	setpath_set_folder(p->session, current);

	/* Ignore empty folder names to avoid resetting the current path */
	while ((next = data->remaining[data->index]) && strlen(next) == 0)
		data->index++;

	if (next == NULL) {
		setpath_complete(p->session, NULL, NULL, user_data);
		return;
	}

	data->index++;

	p->req_id = g_obex_setpath(obex, next, setpath_cb, p, &err);
	if (err != NULL) {
		setpath_complete(p->session, NULL, err, user_data);
		g_error_free(err);
	}
}

static int session_process_setpath(struct pending_request *p, GError **err)
{
	struct setpath_data *req = p->data;
	const char *first = "";

	/* Relative path */
	if (req->remaining[0][0] != '/')
		first = req->remaining[req->index];
	req->index++;

	p->req_id = g_obex_setpath(p->session->obex, first, setpath_cb, p, err);
	if (*err != NULL)
		goto fail;

	p->session->p = p;

	return 0;

fail:
	pending_request_free(p);
	return (*err)->code;
}

guint obc_session_setpath(struct obc_session *session, const char *path,
				session_callback_t func, void *user_data,
				GError **err)
{
	struct setpath_data *data;
	struct pending_request *p;

	if (session->obex == NULL) {
		g_set_error(err, OBEX_IO_ERROR, OBEX_IO_DISCONNECTED,
						"Session disconnected");
		return 0;
	}

	data = g_new0(struct setpath_data, 1);
	data->func = func;
	data->user_data = user_data;
	data->remaining = g_strsplit(strlen(path) ? path : "/", "/", 0);

	p = pending_request_new(session, session_process_setpath, NULL,
				setpath_op_complete, data, setpath_data_free);
	session_queue(p);
	return p->id;
}

static void async_cb(GObex *obex, GError *err, GObexPacket *rsp,
							gpointer user_data)
{
	struct pending_request *p = user_data;
	struct obc_session *session = p->session;
	GError *gerr = NULL;
	uint8_t code;

	p->req_id = 0;

	if (err != NULL) {
		if (p->func)
			p->func(p->session, NULL, err, p->data);
		goto done;
	}

	code = g_obex_packet_get_operation(rsp, NULL);
	if (code != G_OBEX_RSP_SUCCESS)
		g_set_error(&gerr, OBEX_IO_ERROR, code, "%s",
							g_obex_strerror(code));

	if (p->func)
		p->func(p->session, NULL, gerr, p->data);

	if (gerr != NULL)
		g_clear_error(&gerr);

done:
	pending_request_free(p);
	session->p = NULL;

	session_process_queue(session);
}

static void file_op_complete(struct obc_session *session,
						struct obc_transfer *transfer,
						GError *err, void *user_data)
{
	struct file_data *data = user_data;

	if (data->func)
		data->func(session, NULL, err, data->user_data);
}

static int session_process_mkdir(struct pending_request *p, GError **err)
{
	struct file_data *req = p->data;

	p->req_id = g_obex_mkdir(p->session->obex, req->srcname, async_cb, p,
									err);
	if (*err != NULL)
		goto fail;

	p->session->p = p;

	return 0;

fail:
	pending_request_free(p);
	return (*err)->code;
}

guint obc_session_mkdir(struct obc_session *session, const char *folder,
				session_callback_t func, void *user_data,
				GError **err)
{
	struct file_data *data;
	struct pending_request *p;

	if (session->obex == NULL) {
		g_set_error(err, OBEX_IO_ERROR, OBEX_IO_DISCONNECTED,
						"Session disconnected");
		return 0;
	}

	data = g_new0(struct file_data, 1);
	data->srcname = g_strdup(folder);
	data->func = func;
	data->user_data = user_data;

	p = pending_request_new(session, session_process_mkdir, NULL,
					file_op_complete, data, file_data_free);
	session_queue(p);
	return p->id;
}

static int session_process_copy(struct pending_request *p, GError **err)
{
	struct file_data *req = p->data;

	p->req_id = g_obex_copy(p->session->obex, req->srcname, req->destname,
							async_cb, p, err);
	if (*err != NULL)
		goto fail;

	p->session->p = p;

	return 0;

fail:
	pending_request_free(p);
	return (*err)->code;
}

guint obc_session_copy(struct obc_session *session, const char *srcname,
				const char *destname, session_callback_t func,
				void *user_data, GError **err)
{
	struct file_data *data;
	struct pending_request *p;

	if (session->obex == NULL) {
		g_set_error(err, OBEX_IO_ERROR, OBEX_IO_DISCONNECTED,
						"Session disconnected");
		return 0;
	}

	data = g_new0(struct file_data, 1);
	data->srcname = g_strdup(srcname);
	data->destname = g_strdup(destname);
	data->func = func;
	data->user_data = user_data;

	p = pending_request_new(session, session_process_copy, NULL,
				file_op_complete, data, file_data_free);
	session_queue(p);
	return p->id;
}

static int session_process_move(struct pending_request *p, GError **err)
{
	struct file_data *req = p->data;

	p->req_id = g_obex_move(p->session->obex, req->srcname, req->destname,
							async_cb, p, err);
	if (*err != NULL)
		goto fail;

	p->session->p = p;

	return 0;

fail:
	pending_request_free(p);
	return (*err)->code;
}

guint obc_session_move(struct obc_session *session, const char *srcname,
				const char *destname, session_callback_t func,
				void *user_data, GError **err)
{
	struct file_data *data;
	struct pending_request *p;

	if (session->obex == NULL) {
		g_set_error(err, OBEX_IO_ERROR, OBEX_IO_DISCONNECTED,
						"Session disconnected");
		return 0;
	}

	data = g_new0(struct file_data, 1);
	data->srcname = g_strdup(srcname);
	data->destname = g_strdup(destname);
	data->func = func;
	data->user_data = user_data;

	p = pending_request_new(session, session_process_move, NULL,
				file_op_complete, data, file_data_free);
	session_queue(p);
	return p->id;
}

static int session_process_delete(struct pending_request *p, GError **err)
{
	struct file_data *req = p->data;

	p->req_id = g_obex_delete(p->session->obex, req->srcname, async_cb, p,
									err);
	if (*err != NULL)
		goto fail;

	p->session->p = p;

	return 0;

fail:
	pending_request_free(p);
	return (*err)->code;
}

guint obc_session_delete(struct obc_session *session, const char *file,
				session_callback_t func, void *user_data,
				GError **err)
{
	struct file_data *data;
	struct pending_request *p;

	if (session->obex == NULL) {
		g_set_error(err, OBEX_IO_ERROR, OBEX_IO_DISCONNECTED,
						"Session disconnected");
		return 0;
	}

	data = g_new0(struct file_data, 1);
	data->srcname = g_strdup(file);
	data->func = func;
	data->user_data = user_data;

	p = pending_request_new(session, session_process_delete, NULL,
				file_op_complete, data, file_data_free);
	session_queue(p);
	return p->id;
}

void obc_session_cancel(struct obc_session *session, guint id,
							gboolean remove)
{
	struct pending_request *p = session->p;

	if (p == NULL || p->id != id)
		return;

	if (p->req_id == 0)
		return;

	g_obex_cancel_req(session->obex, p->req_id, remove);
	p->req_id = 0;

	if (!remove)
		return;

	pending_request_free(p);
	session->p = NULL;

	session_process_queue(session);
}
