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

static GSList *sessions = NULL;

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

/* Possible Response */
static struct {
	int rsp;
	const char *name;
} obex_response[] = {
	{ G_OBEX_RSP_CONTINUE,			"CONTINUE"		},
	{ G_OBEX_RSP_SUCCESS,			"SUCCESS"		},
	{ G_OBEX_RSP_CREATED,			"CREATED"		},
	{ G_OBEX_RSP_ACCEPTED,			"ACCEPTED"		},
	{ G_OBEX_RSP_NON_AUTHORITATIVE,		"NON_AUTHORITATIVE"	},
	{ G_OBEX_RSP_NO_CONTENT,		"NO_CONTENT"		},
	{ G_OBEX_RSP_RESET_CONTENT,		"RESET_CONTENT"		},
	{ G_OBEX_RSP_PARTIAL_CONTENT,		"PARTIAL_CONTENT"	},
	{ G_OBEX_RSP_MULTIPLE_CHOICES,		"MULTIPLE_CHOICES"	},
	{ G_OBEX_RSP_MOVED_PERMANENTLY,		"MOVED_PERMANENTLY"	},
	{ G_OBEX_RSP_MOVED_TEMPORARILY,		"MOVED_TEMPORARILY"	},
	{ G_OBEX_RSP_SEE_OTHER,			"SEE_OTHER"		},
	{ G_OBEX_RSP_NOT_MODIFIED,		"NOT_MODIFIED"		},
	{ G_OBEX_RSP_USE_PROXY,			"USE_PROXY"		},
	{ G_OBEX_RSP_BAD_REQUEST,		"BAD_REQUEST"		},
	{ G_OBEX_RSP_UNAUTHORIZED,		"UNAUTHORIZED"		},
	{ G_OBEX_RSP_PAYMENT_REQUIRED,		"PAYMENT_REQUIRED"	},
	{ G_OBEX_RSP_FORBIDDEN,			"FORBIDDEN"		},
	{ G_OBEX_RSP_NOT_FOUND,			"NOT_FOUND"		},
	{ G_OBEX_RSP_METHOD_NOT_ALLOWED,	"METHOD_NOT_ALLOWED"	},
	{ G_OBEX_RSP_NOT_ACCEPTABLE,		"NOT_ACCEPTABLE"	},
	{ G_OBEX_RSP_PROXY_AUTH_REQUIRED,	"PROXY_AUTH_REQUIRED"	},
	{ G_OBEX_RSP_REQUEST_TIME_OUT,		"REQUEST_TIME_OUT"	},
	{ G_OBEX_RSP_CONFLICT,			"CONFLICT"		},
	{ G_OBEX_RSP_GONE,			"GONE"			},
	{ G_OBEX_RSP_LENGTH_REQUIRED,		"LENGTH_REQUIRED"	},
	{ G_OBEX_RSP_PRECONDITION_FAILED,	"PRECONDITION_FAILED"	},
	{ G_OBEX_RSP_REQ_ENTITY_TOO_LARGE,	"REQ_ENTITY_TOO_LARGE"	},
	{ G_OBEX_RSP_REQ_URL_TOO_LARGE,		"REQ_URL_TOO_LARGE"	},
	{ G_OBEX_RSP_UNSUPPORTED_MEDIA_TYPE,	"UNSUPPORTED_MEDIA_TYPE"},
	{ G_OBEX_RSP_INTERNAL_SERVER_ERROR,	"INTERNAL_SERVER_ERROR"	},
	{ G_OBEX_RSP_NOT_IMPLEMENTED,		"NOT_IMPLEMENTED"	},
	{ G_OBEX_RSP_BAD_GATEWAY,		"BAD_GATEWAY"		},
	{ G_OBEX_RSP_SERVICE_UNAVAILABLE,	"SERVICE_UNAVAILABLE"	},
	{ G_OBEX_RSP_GATEWAY_TIMEOUT,		"GATEWAY_TIMEOUT"	},
	{ G_OBEX_RSP_VERSION_NOT_SUPPORTED,	"VERSION_NOT_SUPPORTED"	},
	{ G_OBEX_RSP_DATABASE_FULL,		"DATABASE_FULL"		},
	{ G_OBEX_RSP_DATABASE_LOCKED,		"DATABASE_LOCKED"	},
	{ 0xFF,					NULL			},
};

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

static void print_event(int cmd, int rsp)
{
	const char *cmdstr = NULL, *rspstr = 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;
	}

	for (i = 0; obex_response[i].rsp != 0xFF; i++) {
		if (obex_response[i].rsp != rsp)
			continue;
		rspstr = obex_response[i].name;
	}

	obex_debug("%s(0x%x), %s(0x%x)", cmdstr, cmd, rspstr, 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)
{
	sessions = g_slist_remove(sessions, os);

	if (os->io)
		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;
	}

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

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

	sessions = g_slist_prepend(sessions, os);

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