/*
 *
 *  OBEX Server
 *
 *  Copyright (C) 2007-2008  Nokia Corporation
 *  Copyright (C) 2007-2008  Instituto Nokia de Tecnologia (INdT)
 *  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 <glib.h>

#include <openobex/obex.h>
#include <openobex/obex_const.h>

#include "logging.h"
#include "obex.h"
#include "dbus.h"
#include "mimetype.h"
#include "service.h"

/* Default MTU's */
#define DEFAULT_RX_MTU 32767
#define DEFAULT_TX_MTU 32767

/* Connection ID */
static guint32 cid = 0x0000;

static GSList *sessions = NULL;

typedef struct {
	guint8  version;
	guint8  flags;
	guint16 mtu;
} __attribute__ ((packed)) obex_connect_hdr_t;

static void os_reset_session(struct obex_session *os)
{
	if (os->object) {
		os->driver->close(os->object);
		os->object = NULL;
		if (os->aborted && os->cmd == OBEX_CMD_PUT && os->current_folder) {
			gchar *path;
			path = g_build_filename(os->current_folder, os->name, NULL);
			os->driver->remove(path);
			g_free(path);
		}
	}

	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;
	}
	os->driver = NULL;
	os->aborted = FALSE;
	os->offset = 0;
	os->size = OBJECT_SIZE_DELETE;
	os->finished = 0;
}

static void os_session_mark_aborted(struct obex_session *os)
{
	/* the session was alredy cancelled/aborted */
	if (os->aborted)
		return;

	os->aborted = os->size == OBJECT_SIZE_UNKNOWN ? FALSE :
							os->size != os->offset;
}

static void obex_session_free(struct obex_session *os)
{
	sessions = g_slist_remove(sessions, os);

	os_reset_session(os);

	if (os->current_folder)
		g_free(os->current_folder);

	if (os->io)
		g_io_channel_unref(os->io);

	g_free(os);
}

/* From Imendio's GnomeVFS OBEX module (om-utils.c) */
static time_t parse_iso8610(const gchar *val, int size)
{
	time_t time, tz_offset = 0;
	struct tm tm;
	gchar *date;
	gchar 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 cmd_connect(struct obex_session *os,
			obex_t *obex, obex_object_t *obj)
{
	obex_connect_hdr_t *nonhdr;
	obex_headerdata_t hd;
	uint8_t *buffer;
	guint hlen, newsize;
	guint16 mtu;
	guint8 hi;
	const guint8 *target = NULL, *who = NULL;
	guint target_size = 0, who_size = 0;

	if (OBEX_ObjectGetNonHdrData(obj, &buffer) != sizeof(*nonhdr)) {
		OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
		debug("Invalid OBEX CONNECT packet");
		return;
	}

	nonhdr = (obex_connect_hdr_t *) buffer;
	mtu = g_ntohs(nonhdr->mtu);
	debug("Version: 0x%02x. Flags: 0x%02x  OBEX packet length: %d",
			nonhdr->version, nonhdr->flags, mtu);
	/* Leave space for headers */
	newsize = mtu - 200;

	os->tx_mtu = newsize;

	debug("Resizing stream chunks to %d", newsize);

	/* connection id will be used to track the sessions, even for OPP */
	os->cid = ++cid;

	while (OBEX_ObjectGetNextHeader(obex, obj, &hi, &hd, &hlen)) {
		switch (hi) {
		case OBEX_HDR_WHO:
			who = hd.bs;
			who_size = hlen;
			break;
		case OBEX_HDR_TARGET:
			target = hd.bs;
			target_size = hlen;
			break;
		}
	}

	os->service = obex_service_driver_find(os->server->drivers,
						target, target_size,
						who, who_size);
	if (os->service == NULL) {
		error("Connect attempt to a non-supported target");
		OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);

		return;
	}

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

	if (os->service->connect)
		os->service->connect(obex, obj);
}

static gboolean chk_cid(obex_t *obex, obex_object_t *obj, guint32 cid)
{
	struct obex_session *os;
	obex_headerdata_t hd;
	guint hlen;
	guint8 hi;
	gboolean ret = FALSE;

	os = OBEX_GetUserData(obex);

	/* Object Push doesn't provide a connection id. */
	if (os->service->service == OBEX_OPP)
		return TRUE;

	while (OBEX_ObjectGetNextHeader(obex, obj, &hi, &hd, &hlen)) {
		if (hi == OBEX_HDR_CONNECTION && hlen == 4) {
			ret = (hd.bq4 == cid ? TRUE : FALSE);
			break;
		}
	}

	OBEX_ObjectReParseHeaders(obex, obj);

	if (ret == FALSE)
		OBEX_ObjectSetRsp(obj, OBEX_RSP_SERVICE_UNAVAILABLE,
				OBEX_RSP_SERVICE_UNAVAILABLE);

	return ret;
}

static void cmd_get(struct obex_session *os, obex_t *obex, obex_object_t *obj)
{
	obex_headerdata_t hd;
	guint hlen;
	guint8 hi;

	if (!os->service) {
		OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
		return;
	} else if (!os->service->get) {
		OBEX_ObjectSetRsp(obj, OBEX_RSP_NOT_IMPLEMENTED,
				OBEX_RSP_NOT_IMPLEMENTED);
		return;
	}

	g_return_if_fail(chk_cid(obex, obj, os->cid));

	while (OBEX_ObjectGetNextHeader(obex, obj, &hi, &hd, &hlen)) {
		switch (hi) {
		case OBEX_HDR_NAME:
			if (os->name) {
				debug("Ignoring multiple name headers");
				break;
			}

			if (hlen == 0)
				continue;

			os->name = g_convert((const gchar *) hd.bs, hlen,
					"UTF8", "UTF16BE", NULL, NULL, NULL);
			debug("OBEX_HDR_NAME: %s", os->name);
			break;
		case OBEX_HDR_TYPE:
			if (os->type) {
				debug("Ignoring multiple type headers");
				break;
			}

			if (hlen == 0)
				continue;

			/* Ensure null termination */
			if (hd.bs[hlen - 1] != '\0')
				break;

			if (!g_utf8_validate((const gchar *) hd.bs, -1, NULL)) {
				debug("Invalid type header: %s", hd.bs);
				break;
			}

			/* FIXME: x-obex/folder-listing - type is mandatory */

			os->type = g_strndup((const gchar *) hd.bs, hlen);
			debug("OBEX_HDR_TYPE: %s", os->type);
			os->driver = obex_mime_type_driver_find(os->service->target, os->type);
			break;
		}
	}

	if (!os->driver) {
		os->driver = obex_mime_type_driver_find(os->service->target, NULL);
		if (!os->driver) {
			error("No driver found");
			OBEX_ObjectSetRsp(obj, OBEX_RSP_NOT_IMPLEMENTED,
					OBEX_RSP_NOT_IMPLEMENTED);
			return;
		}
	}

	os->service->get(obex, obj);
}

static void cmd_setpath(struct obex_session *os,
			obex_t *obex, obex_object_t *obj)
{
	obex_headerdata_t hd;
	guint32 hlen;
	guint8 hi;

	if (!os->service) {
		OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
		return;
	} else if (!os->service->setpath) {
		OBEX_ObjectSetRsp(obj, OBEX_RSP_NOT_IMPLEMENTED,
				OBEX_RSP_NOT_IMPLEMENTED);
		return;
	}

	g_return_if_fail(chk_cid(obex, obj, os->cid));

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

	while (OBEX_ObjectGetNextHeader(obex, obj, &hi, &hd, &hlen)) {
		if (hi != OBEX_HDR_NAME)
			continue;

		if (os->name) {
			debug("Ignoring multiple name headers");
			break;
		}

		/* This is because OBEX_UnicodeToChar() accesses the string
		 * even if its size is zero */
		if (hlen == 0) {
			os->name = g_strdup("");
			break;
		}

		os->name = g_convert((const gchar *) hd.bs, hlen,
				"UTF8", "UTF16BE", NULL, NULL, NULL);

		debug("Set path name: %s", os->name);
		break;
	}

	os->service->setpath(obex, obj);
}

int os_prepare_get(struct obex_session *os, gchar *filename, size_t *size)
{
	gint err;
	gpointer object;

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

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

	if (*size > 0)
		os->buf = g_malloc0(os->tx_mtu);

	return 0;

fail:
	if (object)
		os->driver->close(object);
	return err;
}

static gint obex_write_stream(struct obex_session *os,
			obex_t *obex, obex_object_t *obj)
{
	obex_headerdata_t hd;
	gint32 len;
	guint8 *ptr;

	debug("obex_write_stream: name=%s type=%s tx_mtu=%d file=%p",
		os->name ? os->name : "", os->type ? os->type : "",
		os->tx_mtu, os->object);

	if (os->aborted)
		return -EPERM;

	if (os->object == NULL) {
		if (os->buf == NULL && os->finished == FALSE)
			return -EIO;

		len = MIN(os->size - os->offset, os->tx_mtu);
		ptr = os->buf + os->offset;
		goto add_header;
	}

	len = os->driver->read(os->object, os->buf, os->tx_mtu);
	if (len < 0) {
		gint err = errno;
		error("read(): %s (%d)", strerror(err), err);
		g_free(os->buf);
		os->buf = NULL;
		return -err;
	}

	ptr = os->buf;

add_header:

	hd.bs = ptr;

	if (len == 0) {
		OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_BODY, hd, 0,
					OBEX_FL_STREAM_DATAEND);
		g_free(os->buf);
		os->buf = NULL;
		return len;
	}

	os->offset += len;

	OBEX_ObjectAddHeader(obex, obj, OBEX_HDR_BODY, hd, len,
				OBEX_FL_STREAM_DATA);

	return len;
}

gint os_prepare_put(struct obex_session *os)
{
	gchar *path;
	gint len;

	path = g_build_filename(os->current_folder, os->name, NULL);
	os->object = os->driver->open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600,
					os->size != OBJECT_SIZE_UNKNOWN ?
					(size_t *) &os->size : NULL);
	if (os->object == NULL) {
		error("open(%s): %s (%d)", path, strerror(errno), errno);
		g_free(path);
		return -EPERM;
	}

	g_free(path);

	if (!os->buf) {
		debug("PUT request checked, no buffered data");
		return 0;
	}

	len = 0;
	while (len < os->offset) {
		gint w;

		w = os->driver->write(os->object, os->buf + len, os->offset - len);
		if (w < 0) {
			gint err = errno;
			error("write(%s): %s (%d)", path, strerror(errno),
									errno);
			if (err == EINTR)
				continue;
			else
				return -err;
		}

		len += w;
	}

	return 0;
}

static gint obex_read_stream(struct obex_session *os, obex_t *obex,
				obex_object_t *obj)
{
	gint size;
	gint32 len = 0;
	const guint8 *buffer;

	if (os->aborted)
		return -EPERM;

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

	size = OBEX_ObjectReadStream(obex, obj, &buffer);
	if (size < 0) {
		error("Error on OBEX stream");
		return -EIO;
	}

	if (size > os->rx_mtu) {
		error("Received more data than RX_MAX");
		return -EIO;
	}

	if (os->object == NULL && size > 0) {
		os->buf = g_realloc(os->buf, os->offset + size);
		memcpy(os->buf + os->offset, buffer, size);
		os->offset += size;

		debug("Stored %u bytes into temporary buffer", size);

		return 0;
	}

	while (len < size) {
		gint w;

		w = os->driver->write(os->object, buffer + len, size - len);
		if (w < 0) {
			gint err = errno;
			if (err == EINTR)
				continue;
			else
				return -err;
		}

		len += w;
	}

	os->offset += len;

	return 0;
}

static gboolean check_put(obex_t *obex, obex_object_t *obj)
{
	struct obex_session *os;
	obex_headerdata_t hd;
	guint hlen;
	guint8 hi;
	int ret;

	os = OBEX_GetUserData(obex);

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

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

	while (OBEX_ObjectGetNextHeader(obex, obj, &hi, &hd, &hlen)) {
		switch (hi) {
		case OBEX_HDR_NAME:
			if (os->name) {
				debug("Ignoring multiple name headers");
				break;
			}

			if (hlen == 0)
				continue;

			os->name = g_convert((const gchar *) hd.bs, hlen,
					"UTF8", "UTF16BE", NULL, NULL, NULL);
			debug("OBEX_HDR_NAME: %s", os->name);
			break;

		case OBEX_HDR_TYPE:
			if (os->type) {
				debug("Ignoring multiple type headers");
				break;
			}

			if (hlen == 0)
				continue;

			/* Ensure null termination */
			if (hd.bs[hlen - 1] != '\0')
				break;

			if (!g_utf8_validate((const gchar *) hd.bs, -1, NULL)) {
				debug("Invalid type header: %s", hd.bs);
				break;
			}

			os->type = g_strndup((const gchar *) hd.bs, hlen);
			debug("OBEX_HDR_TYPE: %s", os->type);
			os->driver = obex_mime_type_driver_find(os->service->target, os->type);
			break;

		case OBEX_HDR_BODY:
			if (os->size < 0)
				os->size = OBJECT_SIZE_UNKNOWN;
			break;

		case OBEX_HDR_LENGTH:
			os->size = hd.bq4;
			debug("OBEX_HDR_LENGTH: %d", os->size);
			break;
		case OBEX_HDR_TIME:
			os->time = parse_iso8610((const gchar *) hd.bs, hlen);
			break;
		}
	}

	OBEX_ObjectReParseHeaders(obex, obj);

	if (!os->driver) {
		os->driver = obex_mime_type_driver_find(os->service->target, NULL);
		if (!os->driver) {
			error("No driver found");
			OBEX_ObjectSetRsp(obj, OBEX_RSP_NOT_IMPLEMENTED,
					OBEX_RSP_NOT_IMPLEMENTED);
			return FALSE;
		}
	}

	if (!os->service || !os->service->chkput)
		goto done;

	ret = os->service->chkput(obex, obj);
	switch (ret) {
	case 0:
		break;
	case -EINVAL:
		OBEX_ObjectSetRsp(obj, OBEX_RSP_BAD_REQUEST,
				OBEX_RSP_BAD_REQUEST);
		return FALSE;
	case -EPERM:
		OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
		return FALSE;
	default:
		debug("Unhandled chkput error: %d", ret);
		OBEX_ObjectSetRsp(obj, OBEX_RSP_INTERNAL_SERVER_ERROR,
				OBEX_RSP_INTERNAL_SERVER_ERROR);
		return FALSE;
	}

	if (os->size == OBJECT_SIZE_DELETE || os->size == OBJECT_SIZE_UNKNOWN) {
		debug("Got a PUT without a Length");
		goto done;
	}

done:
	os->checked = TRUE;

	return TRUE;
}

static void cmd_put(struct obex_session *os, obex_t *obex, obex_object_t *obj)
{
	if (!os->service) {
		OBEX_ObjectSetRsp(obj, OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
		return;
	} else if (!os->service->put) {
		OBEX_ObjectSetRsp(obj, OBEX_RSP_NOT_IMPLEMENTED,
				OBEX_RSP_NOT_IMPLEMENTED);
		return;
	}

	g_return_if_fail(chk_cid(obex, obj, os->cid));

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

	os->service->put(obex, obj);
}

static void obex_event(obex_t *obex, obex_object_t *obj, gint mode,
					gint evt, gint cmd, gint rsp)
{
	struct obex_session *os;

	obex_debug(evt, cmd, rsp);

	os = OBEX_GetUserData(obex);

	switch (evt) {
	case OBEX_EV_PROGRESS:
		if (os->service->progress)
			os->service->progress(obex, obj);
		break;
	case OBEX_EV_ABORT:
		os->aborted = TRUE;
		if (os->service->reset)
			os->service->reset(obex);
		os_reset_session(os);
		OBEX_ObjectSetRsp(obj, OBEX_RSP_SUCCESS, OBEX_RSP_SUCCESS);
		break;
	case OBEX_EV_REQDONE:
		switch (cmd) {
		case OBEX_CMD_DISCONNECT:
			OBEX_TransportDisconnect(obex);
			break;
		case OBEX_CMD_PUT:
		case OBEX_CMD_GET:
		case OBEX_CMD_SETPATH:
			os_session_mark_aborted(os);
			if (os->service->reset)
				os->service->reset(obex);
			os_reset_session(os);
			break;
		default:
			break;
		}
		break;
	case OBEX_EV_REQHINT:
		os->cmd = cmd;
		switch (cmd) {
		case OBEX_CMD_PUT:
			os->checked = FALSE;
			OBEX_ObjectReadStream(obex, obj, NULL);
		case OBEX_CMD_GET:
		case OBEX_CMD_SETPATH:
		case OBEX_CMD_CONNECT:
		case OBEX_CMD_DISCONNECT:
			OBEX_ObjectSetRsp(obj, OBEX_RSP_CONTINUE,
					OBEX_RSP_SUCCESS);
			break;
		default:
			OBEX_ObjectSetRsp(obj, OBEX_RSP_NOT_IMPLEMENTED,
					OBEX_RSP_NOT_IMPLEMENTED);
			break;
		}
		break;
	case OBEX_EV_REQCHECK:
		switch (cmd) {
		case OBEX_CMD_PUT:
			if (os->service && os->service->put)
				check_put(obex, obj);
			break;
		default:
			break;
		}
		break;
	case OBEX_EV_REQ:
		switch (cmd) {
		case OBEX_CMD_DISCONNECT:
			break;
		case OBEX_CMD_CONNECT:
			cmd_connect(os, obex, obj);
			break;
		case OBEX_CMD_SETPATH:
			cmd_setpath(os, obex, obj);
			break;
		case OBEX_CMD_GET:
			cmd_get(os, obex, obj);
			break;
		case OBEX_CMD_PUT:
			cmd_put(os, obex, obj);
			break;
		default:
			debug("Unknown request: 0x%X", cmd);
			OBEX_ObjectSetRsp(obj,
				OBEX_RSP_NOT_IMPLEMENTED, OBEX_RSP_NOT_IMPLEMENTED);
			break;
		}
		break;
	case OBEX_EV_STREAMAVAIL:
		switch (obex_read_stream(os, obex, obj)) {
		case 0:
			break;
		case -EPERM:
			OBEX_ObjectSetRsp(obj,
				OBEX_RSP_FORBIDDEN, OBEX_RSP_FORBIDDEN);
			break;
		default:
			OBEX_ObjectSetRsp(obj,
				OBEX_RSP_INTERNAL_SERVER_ERROR,
				OBEX_RSP_INTERNAL_SERVER_ERROR);
			break;
		}

		break;
	case OBEX_EV_STREAMEMPTY:
		obex_write_stream(os, obex, obj);
		break;
	case OBEX_EV_LINKERR:
		break;
	case OBEX_EV_PARSEERR:
		break;
	case OBEX_EV_UNEXPECTED:
		break;

	default:
		debug("Unknown evt %d", evt);
		break;
	}
}

void server_free(struct server *server)
{
	g_free(server->folder);
	g_free(server->capability);
	g_free(server->devnode);
	g_free(server);
}

static void obex_handle_destroy(gpointer user_data)
{
	struct obex_session *os;
	obex_t *obex = user_data;

	os = OBEX_GetUserData(obex);

	if (os->service && os->service->disconnect)
		os->service->disconnect(obex);

	obex_session_free(os);

	OBEX_Cleanup(obex);
}

static gboolean tty_reinit(gpointer data)
{
	struct server *server = data;
	GSList *l;
	guint services = 0;

	for (l = server->drivers; l; l = l->next) {
		struct obex_service_driver *driver = l->data;

		services |= driver->service;
	}

	tty_init(services, server->folder, server->capability,
			server->symlinks, server->devnode);

	server_free(server);

	return FALSE;
}

static gboolean obex_handle_input(GIOChannel *io,
				GIOCondition cond, gpointer user_data)
{
	obex_t *obex = user_data;
	struct obex_session *os = OBEX_GetUserData(obex);

	if (cond & (G_IO_HUP | G_IO_ERR | G_IO_NVAL)) {
		error("obex_handle_input: poll event %s%s%s",
				(cond & G_IO_HUP) ? "HUP " : "",
				(cond & G_IO_ERR) ? "ERR " : "",
				(cond & G_IO_NVAL) ? "NVAL " : "");
		goto failed;
	}

	if (OBEX_HandleInput(obex, 1) < 0) {
		error("Handle input error");
		goto failed;
	}

	return TRUE;

failed:
	if (os->server->devnode) {
		if (cond & G_IO_NVAL)
			tty_closed();
		else
			g_idle_add(tty_reinit, os->server);
	}

	return FALSE;
}

gint obex_session_start(GIOChannel *io, struct server *server)
{
	struct obex_session *os;
	obex_t *obex;
	gint ret, fd;

	os = g_new0(struct obex_session, 1);

	os->service = obex_service_driver_find(server->drivers, NULL, 0,
						NULL, 0);
	os->current_folder = g_strdup(server->folder);
	os->server = server;
	os->rx_mtu = server->rx_mtu ? server->rx_mtu : DEFAULT_RX_MTU;
	os->tx_mtu = server->tx_mtu ? server->tx_mtu : DEFAULT_TX_MTU;
	os->size = OBJECT_SIZE_DELETE;

	obex = OBEX_Init(OBEX_TRANS_FD, obex_event, 0);
	if (!obex) {
		obex_session_free(os);
		return -EIO;
	}

	OBEX_SetUserData(obex, os);
	os->obex = obex;

	OBEX_SetTransportMTU(obex, os->rx_mtu, os->tx_mtu);

	fd = g_io_channel_unix_get_fd(io);

	ret = FdOBEX_TransportSetup(obex, fd, fd, 0);
	if (ret < 0) {
		obex_session_free(os);
		OBEX_Cleanup(obex);
		return ret;
	}

	g_io_add_watch_full(io, G_PRIORITY_DEFAULT,
			G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
			obex_handle_input, obex, obex_handle_destroy);
	os->io = g_io_channel_ref(io);

	sessions = g_slist_prepend(sessions, os);

	return 0;
}

gint obex_tty_session_stop(void)
{
	GSList *l;

	for (l = sessions; l != NULL; l = l->next) {
		struct obex_session *os = l->data;

		if (os->server->devnode && os->io)
			g_io_channel_shutdown(os->io, TRUE, NULL);
	}

	return 0;
}

struct obex_session *obex_get_session(gpointer object)
{
	GSList *l;

	for (l = sessions; l; l = l->next) {
		struct obex_session *os = l->data;

		if (os->object == object)
			return os;
	}

	return NULL;
}
