/*
 *
 *  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 <btio/btio.h>
#include <gobex/gobex.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"

/* Challenge request */
#define NONCE_TAG 0x00
#define OPTIONS_TAG 0x01 /* Optional */
#define REALM_TAG 0x02 /* Optional */

#define NONCE_LEN 16

/* Challenge response */
#define DIGEST_TAG 0x00
#define USER_ID_TAG 0x01 /* Optional */
#define DIGEST_NONCE_TAG 0x02 /* Optional */

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

/* 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 uint8_t *extract_nonce(const uint8_t *buffer, unsigned int hlen)
{
	struct auth_header *hdr;
	uint8_t *nonce = NULL;
	uint32_t len = 0;

	while (len < hlen) {
		hdr = (void *) buffer + len;

		switch (hdr->tag) {
		case NONCE_TAG:
			if (hdr->len != NONCE_LEN)
				return NULL;

			nonce = hdr->val;
			break;
		}

		len += hdr->len + sizeof(struct auth_header);
	}

	return nonce;
}

static uint8_t *challenge_response(const uint8_t *nonce)
{
	GChecksum *md5;
	uint8_t *result;
	size_t size;

	result = g_new0(uint8_t, NONCE_LEN);

	md5 = g_checksum_new(G_CHECKSUM_MD5);
	if (md5 == NULL)
		return result;

	g_checksum_update(md5, nonce, NONCE_LEN);
	g_checksum_update(md5, (uint8_t *) ":BlueZ", 6);

	size = NONCE_LEN;
	g_checksum_get_digest(md5, result, &size);

	g_checksum_free(md5);

	return result;
}

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 parse_authchal(struct obex_session *session, GObexPacket *req,
							GObexPacket *rsp)
{
	GObexHeader *hdr;
	const guint8 *data, *nonce = NULL;
	gsize len;
	uint8_t challenge[18];
	struct auth_header *auth = (struct auth_header *) challenge;
	uint8_t *response;

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

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

	nonce = extract_nonce(data, len);
	DBG("AUTH CHALLENGE REQUEST");

	response = challenge_response(nonce);
	auth->tag = DIGEST_TAG;
	auth->len = NONCE_LEN;
	memcpy(auth->val, response, NONCE_LEN);

	hdr = g_obex_header_new_bytes(G_OBEX_HDR_AUTHRESP, challenge,
							sizeof(challenge));
	g_obex_packet_add_header(rsp, hdr);
}

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

	parse_authchal(os, req, rsp);

	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;

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

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