/*
 *
 *  OBEX Server
 *
 *  Copyright (C) 2007-2010  Nokia Corporation
 *  Copyright (C) 2007-2010  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 <stdlib.h>
#include <signal.h>
#include <time.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/statvfs.h>
#include <fcntl.h>
#include <inttypes.h>

#include <glib.h>

#include "gobex/gobex.h"

#include "btio/btio.h"
#include "obexd.h"
#include "log.h"
#include "obex.h"
#include "obex-priv.h"
#include "server.h"
#include "manager.h"
#include "mimetype.h"
#include "service.h"
#include "transport.h"

typedef struct {
	uint8_t  version;
	uint8_t  flags;
	uint16_t mtu;
} __attribute__ ((packed)) obex_connect_hdr_t;

struct auth_header {
	uint8_t tag;
	uint8_t len;
	uint8_t val[0];
} __attribute__ ((packed));

/* Possible commands */
static struct {
	int cmd;
	const char *name;
} obex_command[] = {
	{ G_OBEX_OP_CONNECT,	"CONNECT"	},
	{ G_OBEX_OP_DISCONNECT,	"DISCONNECT"	},
	{ G_OBEX_OP_PUT,	"PUT"		},
	{ G_OBEX_OP_GET,	"GET"		},
	{ G_OBEX_OP_SETPATH,	"SETPATH"	},
	{ G_OBEX_OP_SESSION,	"SESSION"	},
	{ G_OBEX_OP_ABORT,	"ABORT"		},
	{ G_OBEX_OP_ACTION,	"ACTION"	},
	{ 0xFF,			NULL		},
};

static gboolean handle_async_io(void *object, int flags, int err,
						void *user_data);

static void print_event(int cmd, uint8_t rsp)
{
	const char *cmdstr = NULL;
	int i;
	static int lastcmd;

	if (cmd < 0)
		cmd = lastcmd;
	else
		lastcmd = cmd;

	for (i = 0; obex_command[i].cmd != 0xFF; i++) {
		if (obex_command[i].cmd != cmd)
			continue;
		cmdstr = obex_command[i].name;
	}

	obex_debug("%s(0x%x), %s(0x%x)", cmdstr, cmd,
						g_obex_strerror(rsp), rsp);
}

static void os_set_response(struct obex_session *os, int err)
{
	uint8_t rsp;

	rsp = g_obex_errno_to_rsp(err);

	print_event(-1, rsp);

	g_obex_send_rsp(os->obex, rsp, NULL, G_OBEX_HDR_INVALID);
}

static void os_session_mark_aborted(struct obex_session *os)
{
	/* the session was already cancelled/aborted or size in unknown */
	if (os->aborted || os->size == OBJECT_SIZE_UNKNOWN)
		return;

	os->aborted = (os->size != os->offset);
}

static void os_reset_session(struct obex_session *os)
{
	os_session_mark_aborted(os);

	if (os->object) {
		os->driver->set_io_watch(os->object, NULL, NULL);
		os->driver->close(os->object);
		if (os->aborted && os->cmd == G_OBEX_OP_PUT && os->path &&
				os->driver->remove)
			os->driver->remove(os->path);
	}

	if (os->service && os->service->reset)
		os->service->reset(os, os->service_data);

	if (os->name) {
		g_free(os->name);
		os->name = NULL;
	}
	if (os->type) {
		g_free(os->type);
		os->type = NULL;
	}
	if (os->buf) {
		g_free(os->buf);
		os->buf = NULL;
	}
	if (os->path) {
		g_free(os->path);
		os->path = NULL;
	}
	if (os->apparam) {
		g_free(os->apparam);
		os->apparam = NULL;
		os->apparam_len = 0;
	}

	if (os->get_rsp > 0) {
		g_obex_remove_request_function(os->obex, os->get_rsp);
		os->get_rsp = 0;
	}

	os->object = NULL;
	os->driver = NULL;
	os->aborted = FALSE;
	os->pending = 0;
	os->offset = 0;
	os->size = OBJECT_SIZE_DELETE;
	os->headers_sent = FALSE;
	os->checked = FALSE;
}

static void obex_session_free(struct obex_session *os)
{
	if (os->io) {
		g_io_channel_shutdown(os->io, TRUE, NULL);
		g_io_channel_unref(os->io);
	}

	if (os->obex)
		g_obex_unref(os->obex);

	g_free(os->src);
	g_free(os->dst);

	g_free(os);
}

/* From Imendio's GnomeVFS OBEX module (om-utils.c) */
static time_t parse_iso8610(const char *val, int size)
{
	time_t time, tz_offset = 0;
	struct tm tm;
	char *date;
	char tz;
	int nr;

	memset(&tm, 0, sizeof(tm));
	/* According to spec the time doesn't have to be null terminated */
	date = g_strndup(val, size);
	nr = sscanf(date, "%04u%02u%02uT%02u%02u%02u%c",
			&tm.tm_year, &tm.tm_mon, &tm.tm_mday,
			&tm.tm_hour, &tm.tm_min, &tm.tm_sec,
			&tz);
	g_free(date);
	if (nr < 6) {
		/* Invalid time format */
		return -1;
	}

	tm.tm_year -= 1900;	/* Year since 1900 */
	tm.tm_mon--;		/* Months since January, values 0-11 */
	tm.tm_isdst = -1;	/* Daylight savings information not avail */

#if defined(HAVE_TM_GMTOFF)
	tz_offset = tm.tm_gmtoff;
#elif defined(HAVE_TIMEZONE)
	tz_offset = -timezone;
	if (tm.tm_isdst > 0)
		tz_offset += 3600;
#endif

	time = mktime(&tm);
	if (nr == 7) {
		/*
		 * Date/Time was in localtime (to remote device)
		 * already. Since we don't know anything about the
		 * timezone on that one we won't try to apply UTC offset
		 */
		time += tz_offset;
	}

	return time;
}

static void parse_service(struct obex_session *os, GObexPacket *req)
{
	GObexHeader *hdr;
	const guint8 *target = NULL, *who = NULL;
	gsize target_size = 0, who_size = 0;

	hdr = g_obex_packet_get_header(req, G_OBEX_HDR_WHO);
	if (hdr == NULL)
		goto target;

	g_obex_header_get_bytes(hdr, &who, &who_size);

target:
	hdr = g_obex_packet_get_header(req, G_OBEX_HDR_TARGET);
	if (hdr == NULL)
		goto probe;

	g_obex_header_get_bytes(hdr, &target, &target_size);

probe:
	os->service = obex_service_driver_find(os->server->drivers,
						target, target_size,
						who, who_size);
}

static void cmd_connect(GObex *obex, GObexPacket *req, void *user_data)
{
	struct obex_session *os = user_data;
	GObexPacket *rsp;
	GObexHeader *hdr;
	int err;

	DBG("");

	print_event(G_OBEX_OP_CONNECT, -1);

	parse_service(os, req);

	if (os->service == NULL || os->service->connect == NULL) {
		error("Connect attempt to a non-supported target");
		os_set_response(os, -EPERM);
		return;
	}

	DBG("Selected driver: %s", os->service->name);

	os->service_data = os->service->connect(os, &err);
	if (err < 0) {
		os_set_response(os, err);
		return;
	}

	os->cmd = G_OBEX_OP_CONNECT;

	rsp = g_obex_packet_new(G_OBEX_RSP_SUCCESS, TRUE, G_OBEX_HDR_INVALID);

	if (os->service->target) {
		hdr = g_obex_header_new_bytes(G_OBEX_HDR_WHO,
						os->service->target,
						os->service->target_size);
		g_obex_packet_add_header(rsp, hdr);
	}

	g_obex_send(obex, rsp, NULL);

	print_event(-1, 0);
}

static void cmd_disconnect(GObex *obex, GObexPacket *req, void *user_data)
{
	struct obex_session *os = user_data;

	DBG("session %p", os);

	print_event(G_OBEX_OP_DISCONNECT, -1);

	os->cmd = G_OBEX_OP_DISCONNECT;

	os_set_response(os, 0);
}

static ssize_t driver_write(struct obex_session *os)
{
	ssize_t len = 0;

	while (os->pending > 0) {
		ssize_t w;

		w = os->driver->write(os->object, os->buf + len, os->pending);
		if (w < 0) {
			error("write(): %s (%zd)", strerror(-w), -w);
			if (w == -EINTR)
				continue;
			else if (w == -EINVAL)
				memmove(os->buf, os->buf + len, os->pending);

			return w;
		}

		len += w;
		os->offset += w;
		os->pending -= w;
	}

	DBG("%zd written", len);

	if (os->service->progress != NULL)
		os->service->progress(os, os->service_data);

	return len;
}

static gssize driver_read(struct obex_session *os, void *buf, gsize size)
{
	gssize len;

	if (os->object == NULL)
		return -EIO;

	if (os->service->progress != NULL)
		os->service->progress(os, os->service_data);

	len = os->driver->read(os->object, buf, size);
	if (len < 0) {
		error("read(): %s (%zd)", strerror(-len), -len);
		if (len == -ENOSTR)
			return 0;
		if (len == -EAGAIN)
			os->driver->set_io_watch(os->object, handle_async_io,
									os);
	}

	os->offset += len;

	DBG("%zd read", len);

	return len;
}

static gssize send_data(void *buf, gsize size, gpointer user_data)
{
	struct obex_session *os = user_data;

	DBG("name=%s type=%s file=%p size=%zu", os->name, os->type, os->object,
									size);

	if (os->aborted)
		return os->err < 0 ? os->err : -EPERM;

	return driver_read(os, buf, size);
}

static void transfer_complete(GObex *obex, GError *err, gpointer user_data)
{
	struct obex_session *os = user_data;

	DBG("");

	if (err != NULL) {
		error("transfer failed: %s\n", err->message);
		goto reset;
	}

	if (os->object && os->driver && os->driver->flush) {
		if (os->driver->flush(os->object) == -EAGAIN) {
			g_obex_suspend(os->obex);
			os->driver->set_io_watch(os->object, handle_async_io,
									os);
			return;
		}
	}

reset:
	os_reset_session(os);
}

static int driver_get_headers(struct obex_session *os)
{
	GObexPacket *rsp;
	gssize len;
	guint8 data[255];
	guint8 id;
	GObexHeader *hdr;

	DBG("name=%s type=%s object=%p", os->name, os->type, os->object);

	if (os->aborted)
		return os->err < 0 ? os->err : -EPERM;

	if (os->object == NULL)
		return -EIO;

	if (os->headers_sent)
		return 0;

	rsp = g_obex_packet_new(G_OBEX_RSP_CONTINUE, TRUE, G_OBEX_HDR_INVALID);

	if (os->driver->get_next_header == NULL)
		goto done;

	while ((len = os->driver->get_next_header(os->object, &data,
							sizeof(data), &id))) {
		if (len < 0) {
			error("get_next_header(): %s (%zd)", strerror(-len),
								-len);

			g_obex_packet_free(rsp);

			if (len == -EAGAIN)
				return len;

			g_free(os->buf);
			os->buf = NULL;

			return len;
		}

		hdr = g_obex_header_new_bytes(id, data, len);
		g_obex_packet_add_header(rsp, hdr);
	}

done:
	if (os->size != OBJECT_SIZE_UNKNOWN && os->size < UINT32_MAX) {
		hdr = g_obex_header_new_uint32(G_OBEX_HDR_LENGTH, os->size);
		g_obex_packet_add_header(rsp, hdr);
	}

	g_obex_get_rsp_pkt(os->obex, rsp, send_data, transfer_complete, os,
									NULL);

	os->headers_sent = TRUE;

	print_event(-1, G_OBEX_RSP_CONTINUE);

	return 0;
}

static gboolean handle_async_io(void *object, int flags, int err,
						void *user_data)
{
	struct obex_session *os = user_data;

	if (err < 0)
		goto done;

	if (flags & G_IO_OUT)
		err = driver_write(os);
	if ((flags & G_IO_IN) && !os->headers_sent)
		err = driver_get_headers(os);

	if (err == -EAGAIN)
		return TRUE;

done:
	if (err < 0) {
		os->err = err;
		os->aborted = TRUE;
	}

	g_obex_resume(os->obex);

	return FALSE;
}

static gboolean recv_data(const void *buf, gsize size, gpointer user_data)
{
	struct obex_session *os = user_data;
	ssize_t ret;

	DBG("name=%s type=%s file=%p size=%zu", os->name, os->type, os->object,
									size);

	if (os->aborted)
		return FALSE;

	/* workaround: client didn't send the object length */
	if (os->size == OBJECT_SIZE_DELETE)
		os->size = OBJECT_SIZE_UNKNOWN;

	os->buf = g_realloc(os->buf, os->pending + size);
	memcpy(os->buf + os->pending, buf, size);
	os->pending += size;

	/* only write if both object and driver are valid */
	if (os->object == NULL || os->driver == NULL) {
		DBG("Stored %" PRIu64 " bytes into temporary buffer",
								os->pending);
		return TRUE;
	}

	ret = driver_write(os);
	if (ret >= 0)
		return TRUE;

	if (ret == -EAGAIN) {
		g_obex_suspend(os->obex);
		os->driver->set_io_watch(os->object, handle_async_io, os);
		return TRUE;
	}

	return FALSE;
}

static void parse_type(struct obex_session *os, GObexPacket *req)
{
	GObexHeader *hdr;
	const guint8 *type;
	gsize len;

	g_free(os->type);
	os->type = NULL;

	hdr = g_obex_packet_get_header(req, G_OBEX_HDR_TYPE);
	if (hdr == NULL)
		goto probe;

	if (!g_obex_header_get_bytes(hdr, &type, &len))
		goto probe;

	/* Ensure null termination */
	if (type[len - 1] != '\0')
		goto probe;

	os->type = g_strndup((const char *) type, len);
	DBG("TYPE: %s", os->type);

probe:
	os->driver = obex_mime_type_driver_find(os->service->target,
						os->service->target_size,
						os->type,
						os->service->who,
						os->service->who_size);
}

static void parse_name(struct obex_session *os, GObexPacket *req)
{
	GObexHeader *hdr;
	const char *name;

	g_free(os->name);
	os->name = NULL;

	hdr = g_obex_packet_get_header(req, G_OBEX_HDR_NAME);
	if (hdr == NULL)
		return;

	if (!g_obex_header_get_unicode(hdr, &name))
		return;

	os->name = g_strdup(name);
	DBG("NAME: %s", os->name);
}

static void parse_apparam(struct obex_session *os, GObexPacket *req)
{
	GObexHeader *hdr;
	const guint8 *apparam;
	gsize len;

	hdr = g_obex_packet_get_header(req, G_OBEX_HDR_APPARAM);
	if (hdr == NULL)
		return;

	if (!g_obex_header_get_bytes(hdr, &apparam, &len))
		return;

	os->apparam = g_memdup(apparam, len);
	os->apparam_len = len;
	DBG("APPARAM");
}

static void cmd_get(GObex *obex, GObexPacket *req, gpointer user_data)
{
	struct obex_session *os = user_data;
	int err;

	DBG("session %p", os);

	print_event(G_OBEX_OP_GET, -1);

	if (os->service == NULL) {
		os_set_response(os, -EPERM);
		return;
	}

	if (os->service->get == NULL) {
		os_set_response(os, -ENOSYS);
		return;
	}

	os->headers_sent = FALSE;

	if (os->type) {
		g_free(os->type);
		os->type = NULL;
	}

	parse_type(os, req);

	if (!os->driver) {
		error("No driver found");
		os_set_response(os, -ENOSYS);
		return;
	}

	os->cmd = G_OBEX_OP_GET;

	parse_name(os, req);

	parse_apparam(os, req);

	err = os->service->get(os, os->service_data);
	if (err == 0)
		return;

	os_set_response(os, err);
}

static void cmd_setpath(GObex *obex, GObexPacket *req, gpointer user_data)
{
	struct obex_session *os = user_data;
	int err;

	DBG("");

	print_event(G_OBEX_OP_SETPATH, -1);

	if (os->service == NULL) {
		err = -EPERM;
		goto done;
	}

	if (os->service->setpath == NULL) {
		err = -ENOSYS;
		goto done;
	}

	os->cmd = G_OBEX_OP_SETPATH;

	parse_name(os, req);

	os->nonhdr = g_obex_packet_get_data(req, &os->nonhdr_len);

	err = os->service->setpath(os, os->service_data);
done:
	os_set_response(os, err);
}

int obex_get_stream_start(struct obex_session *os, const char *filename)
{
	int err;
	void *object;
	size_t size = OBJECT_SIZE_UNKNOWN;

	object = os->driver->open(filename, O_RDONLY, 0, os->service_data,
								&size, &err);
	if (object == NULL) {
		error("open(%s): %s (%d)", filename, strerror(-err), -err);
		return err;
	}

	os->object = object;
	os->offset = 0;
	os->size = size;

	err = driver_get_headers(os);
	if (err != -EAGAIN)
		return err;

	g_obex_suspend(os->obex);
	os->driver->set_io_watch(os->object, handle_async_io, os);
	return 0;
}

int obex_put_stream_start(struct obex_session *os, const char *filename)
{
	int err;

	os->object = os->driver->open(filename, O_WRONLY | O_CREAT | O_TRUNC,
					0600, os->service_data,
					os->size != OBJECT_SIZE_UNKNOWN ?
					(size_t *) &os->size : NULL, &err);
	if (os->object == NULL) {
		error("open(%s): %s (%d)", filename, strerror(-err), -err);
		return err;
	}

	if (os->size != OBJECT_SIZE_DELETE && os->size != OBJECT_SIZE_UNKNOWN)
		manager_emit_transfer_property(os->service_data, "Size");

	os->path = g_strdup(filename);

	return 0;
}

static void parse_length(struct obex_session *os, GObexPacket *req)
{
	GObexHeader *hdr;
	guint32 size;

	hdr = g_obex_packet_get_header(req, G_OBEX_HDR_LENGTH);
	if (hdr == NULL)
		return;

	if (!g_obex_header_get_uint32(hdr, &size))
		return;

	os->size = size;
	DBG("LENGTH: %" PRIu64, os->size);
}

static void parse_time(struct obex_session *os, GObexPacket *req)
{
	GObexHeader *hdr;
	const guint8 *time;
	gsize len;

	hdr = g_obex_packet_get_header(req, G_OBEX_HDR_TIME);
	if (hdr == NULL)
		return;


	if (!g_obex_header_get_bytes(hdr, &time, &len))
		return;

	os->time = parse_iso8610((const char *) time, len);
	DBG("TIME: %s", ctime(&os->time));
}

static gboolean check_put(GObex *obex, GObexPacket *req, void *user_data)
{
	struct obex_session *os = user_data;
	int ret;

	if (os->service->chkput == NULL)
		goto done;

	ret = os->service->chkput(os, os->service_data);
	switch (ret) {
	case 0:
		break;
	case -EAGAIN:
		g_obex_suspend(os->obex);
		os->driver->set_io_watch(os->object, handle_async_io, os);
		return TRUE;
	default:
		os_set_response(os, ret);
		return FALSE;
	}

	if (os->size == OBJECT_SIZE_DELETE || os->size == OBJECT_SIZE_UNKNOWN)
		DBG("Got a PUT without a Length");

done:
	os->checked = TRUE;

	return TRUE;
}

static void cmd_put(GObex *obex, GObexPacket *req, gpointer user_data)
{
	struct obex_session *os = user_data;
	int err;

	DBG("");

	print_event(G_OBEX_OP_PUT, -1);

	if (os->service == NULL) {
		os_set_response(os, -EPERM);
		return;
	}

	/* OPP session don't require CONNECT, in which case just call connect
	 * callback to register the transfer.
	 */
	if (!os->service_data && os->service->service == OBEX_OPP) {
		os->service_data = os->service->connect(os, &err);
		if (err < 0) {
			os_set_response(os, err);
			return;
		}
	}

	parse_type(os, req);

	if (os->driver == NULL) {
		error("No driver found");
		os_set_response(os, -ENOSYS);
		return;
	}

	os->cmd = G_OBEX_OP_PUT;

	/* Set size to unknown if a body header exists */
	if (g_obex_packet_get_body(req))
		os->size = OBJECT_SIZE_UNKNOWN;

	parse_name(os, req);
	parse_length(os, req);
	parse_time(os, req);
	parse_apparam(os, req);

	if (!os->checked) {
		if (!check_put(obex, req, user_data))
			return;
	}

	if (os->service->put == NULL) {
		os_set_response(os, -ENOSYS);
		return;
	}

	err = os->service->put(os, os->service_data);
	if (err == 0) {
		g_obex_put_rsp(obex, req, recv_data, transfer_complete, os,
						NULL, G_OBEX_HDR_INVALID);
		print_event(G_OBEX_OP_PUT, G_OBEX_RSP_CONTINUE);
		return;
	}

	os_set_response(os, err);
}

static void parse_destname(struct obex_session *os, GObexPacket *req)
{
	GObexHeader *hdr;
	const char *destname;

	g_free(os->destname);
	os->destname = NULL;

	hdr = g_obex_packet_get_header(req, G_OBEX_HDR_DESTNAME);
	if (hdr == NULL)
		return;

	if (!g_obex_header_get_unicode(hdr, &destname))
		return;

	os->destname = g_strdup(destname);
	DBG("DESTNAME: %s", os->destname);
}

static void parse_action(struct obex_session *os, GObexPacket *req)
{
	GObexHeader *hdr;
	guint8 id;

	hdr = g_obex_packet_get_header(req, G_OBEX_HDR_ACTION);
	if (hdr == NULL)
		return;

	if (!g_obex_header_get_uint8(hdr, &id))
		return;

	os->action_id = id;
	DBG("ACTION: 0x%02x", os->action_id);
}

static void cmd_action(GObex *obex, GObexPacket *req, gpointer user_data)
{
	struct obex_session *os = user_data;
	int err;

	DBG("");

	print_event(G_OBEX_OP_ACTION, -1);

	if (os->service == NULL) {
		err = -EPERM;
		goto done;
	}

	if (os->service->action == NULL) {
		err = -ENOSYS;
		goto done;
	}

	os->cmd = G_OBEX_OP_ACTION;

	parse_name(os, req);
	parse_destname(os, req);
	parse_action(os, req);

	os->driver = obex_mime_type_driver_find(os->service->target,
						os->service->target_size,
						NULL,
						os->service->who,
						os->service->who_size);
	if (os->driver == NULL) {
		err = -ENOSYS;
		goto done;
	}

	err = os->service->action(os, os->service_data);
done:
	os_set_response(os, err);
}

static void cmd_abort(GObex *obex, GObexPacket *req, gpointer user_data)
{
	struct obex_session *os = user_data;

	DBG("");

	print_event(G_OBEX_OP_ABORT, -1);

	os_reset_session(os);

	os_set_response(os, 0);
}

static void obex_session_destroy(struct obex_session *os)
{
	DBG("");

	os_reset_session(os);

	if (os->service && os->service->disconnect)
		os->service->disconnect(os, os->service_data);

	obex_session_free(os);
}

static void disconn_func(GObex *obex, GError *err, gpointer user_data)
{
	struct obex_session *os = user_data;

	error("disconnected: %s\n", err ? err->message : "<no err>");
	obex_session_destroy(os);
}

int obex_session_start(GIOChannel *io, uint16_t tx_mtu, uint16_t rx_mtu,
				gboolean stream, struct obex_server *server)
{
	struct obex_session *os;
	GObex *obex;
	GObexTransportType type;
	static uint32_t id = 0;

	DBG("");

	os = g_new0(struct obex_session, 1);
	os->id = ++id;

	os->service = obex_service_driver_find(server->drivers, NULL,
							0, NULL, 0);
	os->server = server;
	os->size = OBJECT_SIZE_DELETE;

	type = stream ? G_OBEX_TRANSPORT_STREAM : G_OBEX_TRANSPORT_PACKET;

	obex = g_obex_new(io, type, rx_mtu, tx_mtu);
	if (!obex) {
		obex_session_free(os);
		return -EIO;
	}

	g_obex_set_disconnect_function(obex, disconn_func, os);
	g_obex_add_request_function(obex, G_OBEX_OP_CONNECT, cmd_connect, os);
	g_obex_add_request_function(obex, G_OBEX_OP_DISCONNECT, cmd_disconnect,
									os);
	g_obex_add_request_function(obex, G_OBEX_OP_PUT, cmd_put, os);
	g_obex_add_request_function(obex, G_OBEX_OP_GET, cmd_get, os);
	g_obex_add_request_function(obex, G_OBEX_OP_SETPATH, cmd_setpath, os);
	g_obex_add_request_function(obex, G_OBEX_OP_ACTION, cmd_action, os);
	g_obex_add_request_function(obex, G_OBEX_OP_ABORT, cmd_abort, os);

	os->obex = obex;
	os->io = g_io_channel_ref(io);

	obex_getsockname(os, &os->src);
	obex_getpeername(os, &os->dst);

	return 0;
}

const char *obex_get_name(struct obex_session *os)
{
	return os->name;
}

const char *obex_get_destname(struct obex_session *os)
{
	return os->destname;
}

void obex_set_name(struct obex_session *os, const char *name)
{
	g_free(os->name);
	os->name = g_strdup(name);
	DBG("Name changed: %s", os->name);
}

ssize_t obex_get_size(struct obex_session *os)
{
	return os->size;
}

const char *obex_get_type(struct obex_session *os)
{
	return os->type;
}

int obex_remove(struct obex_session *os, const char *path)
{
	if (os->driver == NULL)
		return -ENOSYS;

	return os->driver->remove(path);
}

int obex_copy(struct obex_session *os, const char *source,
						const char *destination)
{
	if (os->driver == NULL || os->driver->copy == NULL)
		return -ENOSYS;

	DBG("%s %s", source, destination);

	return os->driver->copy(source, destination);
}

int obex_move(struct obex_session *os, const char *source,
						const char *destination)
{
	if (os->driver == NULL || os->driver->move == NULL)
		return -ENOSYS;

	DBG("%s %s", source, destination);

	return os->driver->move(source, destination);
}

uint8_t obex_get_action_id(struct obex_session *os)
{
	return os->action_id;
}

ssize_t obex_get_apparam(struct obex_session *os, const uint8_t **buffer)
{
	*buffer = os->apparam;

	return os->apparam_len;
}

ssize_t obex_get_non_header_data(struct obex_session *os,
							const uint8_t **data)
{
	*data = os->nonhdr;

	return os->nonhdr_len;
}

int obex_getpeername(struct obex_session *os, char **name)
{
	struct obex_transport_driver *transport = os->server->transport;

	if (transport == NULL || transport->getpeername == NULL)
		return -ENOTSUP;

	return transport->getpeername(os->io, name);
}

int obex_getsockname(struct obex_session *os, char **name)
{
	struct obex_transport_driver *transport = os->server->transport;

	if (transport == NULL || transport->getsockname == NULL)
		return -ENOTSUP;

	return transport->getsockname(os->io, name);
}

int memncmp0(const void *a, size_t na, const void *b, size_t nb)
{
	if (na != nb)
		return na - nb;

	if (a == NULL)
		return -(a != b);

	if (b == NULL)
		return a != b;

	return memcmp(a, b, na);
}
