/*
 *
 *  OBEX library with GLib integration
 *
 *  Copyright (C) 2011  Intel Corporation. All rights reserved.
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include <unistd.h>
#include <string.h>
#include <errno.h>

#include "gobex.h"
#include "gobex-debug.h"

#define G_OBEX_DEFAULT_MTU	4096
#define G_OBEX_MINIMUM_MTU	255
#define G_OBEX_MAXIMUM_MTU	65535

#define G_OBEX_DEFAULT_TIMEOUT	10
#define G_OBEX_ABORT_TIMEOUT	5

#define G_OBEX_OP_NONE		0xff

#define FINAL_BIT		0x80

#define CONNID_INVALID		0xffffffff

/* Challenge request */
#define NONCE_TAG		0x00
#define NONCE_LEN		16

/* Challenge response */
#define DIGEST_TAG		0x00

guint gobex_debug = 0;

struct srm_config {
	guint8 op;
	gboolean enabled;
	guint8 srm;
	guint8 srmp;
	gboolean outgoing;
};

struct _GObex {
	int ref_count;
	GIOChannel *io;
	guint io_source;

	gboolean (*read) (GObex *obex, GError **err);
	gboolean (*write) (GObex *obex, GError **err);

	guint8 *rx_buf;
	size_t rx_data;
	guint16 rx_pkt_len;
	guint8 rx_last_op;

	guint8 *tx_buf;
	size_t tx_data;
	size_t tx_sent;

	gboolean suspended;
	gboolean use_srm;

	struct srm_config *srm;

	guint write_source;

	gssize io_rx_mtu;
	gssize io_tx_mtu;

	guint16 rx_mtu;
	guint16 tx_mtu;

	guint32 conn_id;
	GObexApparam *authchal;

	GQueue *tx_queue;

	GSList *req_handlers;

	GObexFunc disconn_func;
	gpointer disconn_func_data;

	struct pending_pkt *pending_req;
};

struct pending_pkt {
	guint id;
	GObex *obex;
	GObexPacket *pkt;
	guint timeout;
	guint timeout_id;
	GObexResponseFunc rsp_func;
	gpointer rsp_data;
	gboolean cancelled;
	gboolean suspended;
	gboolean authenticating;
};

struct req_handler {
	guint id;
	guint8 opcode;
	GObexRequestFunc func;
	gpointer user_data;
};

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

struct setpath_data {
	guint8 flags;
	guint8 constants;
} __attribute__ ((packed));

static struct error_code {
	guint8 code;
	const char *name;
} obex_errors[] = {
	{ 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 Authentication 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,	"Request Entity Too Large" },
	{ G_OBEX_RSP_REQ_URL_TOO_LARGE,		"Request 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" },
	{ 0x00,					NULL }
};

const char *g_obex_strerror(guint8 err_code)
{
	struct error_code *error;

	for (error = obex_errors; error->name != NULL; error++) {
		if (error->code == err_code)
			return error->name;
	}

	return "<unknown>";
}

static ssize_t req_header_offset(guint8 opcode)
{
	switch (opcode) {
	case G_OBEX_OP_CONNECT:
		return sizeof(struct connect_data);
	case G_OBEX_OP_SETPATH:
		return sizeof(struct setpath_data);
	case G_OBEX_OP_DISCONNECT:
	case G_OBEX_OP_PUT:
	case G_OBEX_OP_GET:
	case G_OBEX_OP_SESSION:
	case G_OBEX_OP_ABORT:
	case G_OBEX_OP_ACTION:
		return 0;
	default:
		return -1;
	}
}

static ssize_t rsp_header_offset(guint8 opcode)
{
	switch (opcode) {
	case G_OBEX_OP_CONNECT:
		return sizeof(struct connect_data);
	case G_OBEX_OP_SETPATH:
	case G_OBEX_OP_DISCONNECT:
	case G_OBEX_OP_PUT:
	case G_OBEX_OP_GET:
	case G_OBEX_OP_SESSION:
	case G_OBEX_OP_ABORT:
	case G_OBEX_OP_ACTION:
		return 0;
	default:
		return -1;
	}
}

static void pending_pkt_free(struct pending_pkt *p)
{
	if (p->obex != NULL)
		g_obex_unref(p->obex);

	if (p->timeout_id > 0)
		g_source_remove(p->timeout_id);

	g_obex_packet_free(p->pkt);

	g_free(p);
}

static gboolean req_timeout(gpointer user_data)
{
	GObex *obex = user_data;
	struct pending_pkt *p = obex->pending_req;
	GError *err;

	g_assert(p != NULL);

	obex->pending_req = NULL;

	err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_TIMEOUT,
					"Timed out waiting for response");

	g_obex_debug(G_OBEX_DEBUG_ERROR, "%s", err->message);

	if (p->rsp_func)
		p->rsp_func(obex, err, NULL, p->rsp_data);

	g_error_free(err);
	pending_pkt_free(p);

	p->timeout_id = 0;

	return FALSE;
}

static gboolean write_stream(GObex *obex, GError **err)
{
	GIOStatus status;
	gsize bytes_written;
	char *buf;

	buf = (char *) &obex->tx_buf[obex->tx_sent];
	status = g_io_channel_write_chars(obex->io, buf, obex->tx_data,
							&bytes_written, err);
	if (status != G_IO_STATUS_NORMAL)
		return FALSE;

	g_obex_dump(G_OBEX_DEBUG_DATA, "<", buf, bytes_written);

	obex->tx_sent += bytes_written;
	obex->tx_data -= bytes_written;

	return TRUE;
}

static gboolean write_packet(GObex *obex, GError **err)
{
	GIOStatus status;
	gsize bytes_written;
	char *buf;

	buf = (char *) &obex->tx_buf[obex->tx_sent];
	status = g_io_channel_write_chars(obex->io, buf, obex->tx_data,
							&bytes_written, err);
	if (status != G_IO_STATUS_NORMAL)
		return FALSE;

	if (bytes_written != obex->tx_data)
		return FALSE;

	g_obex_dump(G_OBEX_DEBUG_DATA, "<", buf, bytes_written);

	obex->tx_sent += bytes_written;
	obex->tx_data -= bytes_written;

	return TRUE;
}

static void set_srmp(GObex *obex, guint8 srmp, gboolean outgoing)
{
	struct srm_config *config = obex->srm;

	if (config == NULL)
		return;

	/* Dont't reset if direction doesn't match */
	if (srmp > G_OBEX_SRMP_NEXT_WAIT && config->outgoing != outgoing)
		return;

	config->srmp = srmp;
	config->outgoing = outgoing;
}

static void set_srm(GObex *obex, guint8 op, guint8 srm)
{
	struct srm_config *config = obex->srm;
	gboolean enable;

	if (config == NULL) {
		if (srm == G_OBEX_SRM_DISABLE)
			return;

		config = g_new0(struct srm_config, 1);
		config->op = op;
		config->srm = srm;
		obex->srm = config;
		return;
	}

	/* Indicate response, treat it as request */
	if (config->srm == G_OBEX_SRM_INDICATE) {
		if (srm != G_OBEX_SRM_ENABLE)
			goto done;
		config->srm = srm;
		return;
	}

	enable = (srm == G_OBEX_SRM_ENABLE);
	if (config->enabled == enable)
		goto done;

	config->enabled = enable;

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "SRM %s", config->enabled ?
						"Enabled" : "Disabled");

done:
	if (config->enabled)
		return;

	g_free(obex->srm);
	obex->srm = NULL;
}

static gboolean g_obex_srm_enabled(GObex *obex)
{
	if (!obex->use_srm)
		return FALSE;

	if (obex->srm == NULL)
		return FALSE;

	return obex->srm->enabled;
}

static void check_srm_final(GObex *obex, guint8 op)
{
	if (!g_obex_srm_enabled(obex))
		return;

	switch (obex->srm->op) {
	case G_OBEX_OP_CONNECT:
		return;
	default:
		if (op <= G_OBEX_RSP_CONTINUE)
			return;
	}

	set_srm(obex, op, G_OBEX_SRM_DISABLE);
}

static void setup_srm(GObex *obex, GObexPacket *pkt, gboolean outgoing)
{
	GObexHeader *hdr;
	guint8 op;
	gboolean final;

	if (!obex->use_srm)
		return;

	op = g_obex_packet_get_operation(pkt, &final);

	hdr = g_obex_packet_get_header(pkt, G_OBEX_HDR_SRM);
	if (hdr != NULL) {
		guint8 srm;
		g_obex_header_get_uint8(hdr, &srm);
		g_obex_debug(G_OBEX_DEBUG_COMMAND, "srm 0x%02x", srm);
		set_srm(obex, op, srm);
	} else if (!g_obex_srm_enabled(obex))
		set_srm(obex, op, G_OBEX_SRM_DISABLE);

	hdr = g_obex_packet_get_header(pkt, G_OBEX_HDR_SRMP);
	if (hdr != NULL) {
		guint8 srmp;
		g_obex_header_get_uint8(hdr, &srmp);
		g_obex_debug(G_OBEX_DEBUG_COMMAND, "srmp 0x%02x", srmp);
		set_srmp(obex, srmp, outgoing);
	} else if (obex->pending_req && obex->pending_req->suspended)
		g_obex_packet_add_uint8(pkt, G_OBEX_HDR_SRMP, G_OBEX_SRMP_WAIT);
	else
		set_srmp(obex, -1, outgoing);

	if (final)
		check_srm_final(obex, op);
}

static gboolean write_data(GIOChannel *io, GIOCondition cond,
							gpointer user_data)
{
	GObex *obex = user_data;

	if (cond & G_IO_NVAL)
		return FALSE;

	if (cond & (G_IO_HUP | G_IO_ERR))
		goto stop_tx;

	if (obex->tx_data == 0) {
		struct pending_pkt *p = g_queue_pop_head(obex->tx_queue);
		ssize_t len;

		if (p == NULL)
			goto stop_tx;

		setup_srm(obex, p->pkt, TRUE);

		if (g_obex_srm_enabled(obex))
			goto encode;

		/* Can't send a request while there's a pending one */
		if (obex->pending_req && p->id > 0) {
			g_queue_push_head(obex->tx_queue, p);
			goto stop_tx;
		}

encode:
		len = g_obex_packet_encode(p->pkt, obex->tx_buf, obex->tx_mtu);
		if (len == -EAGAIN) {
			g_queue_push_head(obex->tx_queue, p);
			g_obex_suspend(obex);
			goto stop_tx;
		}

		if (len < 0) {
			pending_pkt_free(p);
			goto done;
		}

		if (p->id > 0) {
			if (obex->pending_req != NULL)
				pending_pkt_free(obex->pending_req);
			obex->pending_req = p;
			p->timeout_id = g_timeout_add_seconds(p->timeout,
							req_timeout, obex);
		} else {
			/* During packet encode final bit can be set */
			if (obex->tx_buf[0] & FINAL_BIT)
				check_srm_final(obex,
						obex->tx_buf[0] & ~FINAL_BIT);
			pending_pkt_free(p);
		}

		obex->tx_data = len;
		obex->tx_sent = 0;
	}

	if (obex->suspended) {
		obex->write_source = 0;
		return FALSE;
	}

	if (!obex->write(obex, NULL))
		goto stop_tx;

done:
	if (obex->tx_data > 0 || g_queue_get_length(obex->tx_queue) > 0)
		return TRUE;

stop_tx:
	obex->rx_last_op = G_OBEX_OP_NONE;
	obex->tx_data = 0;
	obex->write_source = 0;
	return FALSE;
}

static void enable_tx(GObex *obex)
{
	GIOCondition cond;

	if (obex->suspended)
		return;

	if (obex->write_source > 0)
		return;

	cond = G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
	obex->write_source = g_io_add_watch(obex->io, cond, write_data, obex);
}

static gboolean g_obex_send_internal(GObex *obex, struct pending_pkt *p,
								GError **err)
{

	if (obex->io == NULL) {
		g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_DISCONNECTED,
					"The transport is not connected");
		g_obex_debug(G_OBEX_DEBUG_ERROR, "%s", (*err)->message);
		return FALSE;
	}

	if (g_obex_packet_get_operation(p->pkt, NULL) == G_OBEX_OP_ABORT)
		g_queue_push_head(obex->tx_queue, p);
	else
		g_queue_push_tail(obex->tx_queue, p);

	if (obex->pending_req == NULL || p->id == 0)
		enable_tx(obex);

	return TRUE;
}

static void init_connect_data(GObex *obex, struct connect_data *data)
{
	guint16 u16;

	memset(data, 0, sizeof(*data));

	data->version = 0x10;
	data->flags = 0;

	u16 = g_htons(obex->rx_mtu);
	memcpy(&data->mtu, &u16, sizeof(u16));
}

static guint8 *digest_response(const guint8 *nonce)
{
	GChecksum *md5;
	guint8 *result;
	gsize size;

	result = g_new0(guint8, 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, (guint8 *) ":BlueZ", 6);

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

	g_checksum_free(md5);

	return result;
}

static void prepare_auth_rsp(GObex *obex, GObexPacket *rsp)
{
	GObexHeader *hdr;
	GObexApparam *authrsp;
	const guint8 *nonce;
	guint8 *result;
	gsize len;

	/* Check if client is already responding to authentication challenge */
	hdr = g_obex_packet_get_header(rsp, G_OBEX_HDR_AUTHRESP);
	if (hdr)
		goto done;

	if (!g_obex_apparam_get_bytes(obex->authchal, NONCE_TAG, &nonce, &len))
		goto done;

	if (len != NONCE_LEN)
		goto done;

	result = digest_response(nonce);
	authrsp = g_obex_apparam_set_bytes(NULL, DIGEST_TAG, result, NONCE_LEN);

	hdr = g_obex_header_new_tag(G_OBEX_HDR_AUTHRESP, authrsp);
	g_obex_packet_add_header(rsp, hdr);

	g_obex_apparam_free(authrsp);
	g_free(result);

done:
	g_obex_apparam_free(obex->authchal);
	obex->authchal = NULL;
}

static void prepare_connect_rsp(GObex *obex, GObexPacket *rsp)
{
	GObexHeader *hdr;
	struct connect_data data;
	static guint32 next_connid = 1;

	init_connect_data(obex, &data);
	g_obex_packet_set_data(rsp, &data, sizeof(data), G_OBEX_DATA_COPY);

	hdr = g_obex_packet_get_header(rsp, G_OBEX_HDR_CONNECTION);
	if (hdr) {
		g_obex_header_get_uint32(hdr, &obex->conn_id);
		goto done;
	}

	obex->conn_id = next_connid++;

	hdr = g_obex_header_new_uint32(G_OBEX_HDR_CONNECTION, obex->conn_id);
	g_obex_packet_prepend_header(rsp, hdr);

done:
	if (obex->authchal)
		prepare_auth_rsp(obex, rsp);
}

static void prepare_srm_rsp(GObex *obex, GObexPacket *pkt)
{
	GObexHeader *hdr;

	if (!obex->use_srm || obex->srm == NULL)
		return;

	if (obex->srm->enabled)
		return;

	hdr = g_obex_packet_get_header(pkt, G_OBEX_HDR_SRM);
	if (hdr != NULL)
		return;

	hdr = g_obex_header_new_uint8(G_OBEX_HDR_SRM, G_OBEX_SRM_ENABLE);
	g_obex_packet_prepend_header(pkt, hdr);
}

gboolean g_obex_send(GObex *obex, GObexPacket *pkt, GError **err)
{
	struct pending_pkt *p;
	gboolean ret;

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "conn %u", obex->conn_id);

	if (obex == NULL || pkt == NULL) {
		g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_INVALID_ARGS,
				"Invalid arguments");
		g_obex_debug(G_OBEX_DEBUG_ERROR, "%s", (*err)->message);
		return FALSE;
	}

	switch (obex->rx_last_op) {
	case G_OBEX_OP_CONNECT:
		prepare_connect_rsp(obex, pkt);
		break;
	case G_OBEX_OP_GET:
	case G_OBEX_OP_PUT:
		prepare_srm_rsp(obex, pkt);
		break;
	}

	p = g_new0(struct pending_pkt, 1);
	p->pkt = pkt;

	ret = g_obex_send_internal(obex, p, err);
	if (ret == FALSE)
		pending_pkt_free(p);

	return ret;
}

static void prepare_srm_req(GObex *obex, GObexPacket *pkt)
{
	GObexHeader *hdr;

	if (!obex->use_srm)
		return;

	if (obex->srm != NULL && obex->srm->enabled)
		return;

	hdr = g_obex_packet_get_header(pkt, G_OBEX_HDR_SRM);
	if (hdr != NULL)
		return;

	hdr = g_obex_header_new_uint8(G_OBEX_HDR_SRM, G_OBEX_SRM_ENABLE);
	g_obex_packet_prepend_header(pkt, hdr);
}

guint g_obex_send_req(GObex *obex, GObexPacket *req, int timeout,
			GObexResponseFunc func, gpointer user_data,
			GError **err)
{
	GObexHeader *hdr;
	struct pending_pkt *p;
	static guint id = 1;
	guint8 op;

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "conn %u", obex->conn_id);

	op = g_obex_packet_get_operation(req, NULL);
	if (op == G_OBEX_OP_PUT || op == G_OBEX_OP_GET) {
		/* Only enable SRM automatically for GET and PUT */
		prepare_srm_req(obex, req);
	}

	if (obex->conn_id == CONNID_INVALID)
		goto create_pending;

	if (obex->rx_last_op == G_OBEX_RSP_CONTINUE)
		goto create_pending;

	if (g_obex_srm_enabled(obex) && obex->pending_req != NULL)
		goto create_pending;

	hdr = g_obex_packet_get_header(req, G_OBEX_HDR_CONNECTION);
	if (hdr != NULL)
		goto create_pending;

	hdr = g_obex_header_new_uint32(G_OBEX_HDR_CONNECTION, obex->conn_id);
	g_obex_packet_prepend_header(req, hdr);

create_pending:
	p = g_new0(struct pending_pkt, 1);

	p->pkt = req;
	p->id = id++;
	p->rsp_func = func;
	p->rsp_data = user_data;

	if (timeout < 0)
		p->timeout = G_OBEX_DEFAULT_TIMEOUT;
	else
		p->timeout = timeout;

	if (!g_obex_send_internal(obex, p, err)) {
		pending_pkt_free(p);
		return 0;
	}

	return p->id;
}

static int pending_pkt_cmp(gconstpointer a, gconstpointer b)
{
	const struct pending_pkt *p = a;
	guint id = GPOINTER_TO_UINT(b);

	return (p->id - id);
}

static gboolean pending_req_abort(GObex *obex, GError **err)
{
	struct pending_pkt *p = obex->pending_req;
	GObexPacket *req;

	if (p->cancelled)
		return TRUE;

	p->cancelled = TRUE;

	if (p->timeout_id > 0)
		g_source_remove(p->timeout_id);

	p->timeout = G_OBEX_ABORT_TIMEOUT;
	p->timeout_id = g_timeout_add_seconds(p->timeout, req_timeout, obex);

	req = g_obex_packet_new(G_OBEX_OP_ABORT, TRUE, G_OBEX_HDR_INVALID);

	return g_obex_send(obex, req, err);
}

static gboolean cancel_complete(gpointer user_data)
{
	struct pending_pkt *p = user_data;
	GObex *obex = p->obex;
	GError *err;

	g_assert(p->rsp_func != NULL);

	err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_CANCELLED,
					"The request was cancelled");
	p->rsp_func(obex, err, NULL, p->rsp_data);

	g_error_free(err);

	pending_pkt_free(p);

	return FALSE;
}

gboolean g_obex_cancel_req(GObex *obex, guint req_id, gboolean remove_callback)
{
	GList *match;
	struct pending_pkt *p;

	if (obex->pending_req && obex->pending_req->id == req_id) {
		if (!pending_req_abort(obex, NULL)) {
			p = obex->pending_req;
			obex->pending_req = NULL;
			goto immediate_completion;
		}

		if (remove_callback)
			obex->pending_req->rsp_func = NULL;

		return TRUE;
	}

	match = g_queue_find_custom(obex->tx_queue, GUINT_TO_POINTER(req_id),
							pending_pkt_cmp);
	if (match == NULL)
		return FALSE;

	p = match->data;

	g_queue_delete_link(obex->tx_queue, match);

immediate_completion:
	p->cancelled = TRUE;
	p->obex = g_obex_ref(obex);

	if (remove_callback || p->rsp_func == NULL)
		pending_pkt_free(p);
	else
		g_idle_add(cancel_complete, p);

	return TRUE;
}

gboolean g_obex_send_rsp(GObex *obex, guint8 rspcode, GError **err,
						guint8 first_hdr_type, ...)
{
	GObexPacket *rsp;
	va_list args;

	va_start(args, first_hdr_type);
	rsp = g_obex_packet_new_valist(rspcode, TRUE, first_hdr_type, args);
	va_end(args);

	return g_obex_send(obex, rsp, err);
}

void g_obex_set_disconnect_function(GObex *obex, GObexFunc func,
							gpointer user_data)
{
	obex->disconn_func = func;
	obex->disconn_func_data = user_data;
}

static int req_handler_cmpop(gconstpointer a, gconstpointer b)
{
	const struct req_handler *handler = a;
	guint opcode = GPOINTER_TO_UINT(b);

	return (int) handler->opcode - (int) opcode;
}

static int req_handler_cmpid(gconstpointer a, gconstpointer b)
{
	const struct req_handler *handler = a;
	guint id = GPOINTER_TO_UINT(b);

	return (int) handler->id - (int) id;
}

guint g_obex_add_request_function(GObex *obex, guint8 opcode,
						GObexRequestFunc func,
						gpointer user_data)
{
	struct req_handler *handler;
	static guint next_id = 1;

	handler = g_new0(struct req_handler, 1);
	handler->id = next_id++;
	handler->opcode = opcode;
	handler->func = func;
	handler->user_data = user_data;

	obex->req_handlers = g_slist_prepend(obex->req_handlers, handler);

	return handler->id;
}

gboolean g_obex_remove_request_function(GObex *obex, guint id)
{
	struct req_handler *handler;
	GSList *match;

	match = g_slist_find_custom(obex->req_handlers, GUINT_TO_POINTER(id),
							req_handler_cmpid);
	if (match == NULL)
		return FALSE;

	handler = match->data;

	obex->req_handlers = g_slist_delete_link(obex->req_handlers, match);
	g_free(handler);

	return TRUE;
}

static void g_obex_srm_suspend(GObex *obex)
{
	struct pending_pkt *p = obex->pending_req;
	GObexPacket *req;

	if (p->timeout_id > 0) {
		g_source_remove(p->timeout_id);
		p->timeout_id = 0;
	}

	p->suspended = TRUE;

	req = g_obex_packet_new(G_OBEX_OP_GET, TRUE,
					G_OBEX_HDR_SRMP, G_OBEX_SRMP_WAIT,
					G_OBEX_HDR_INVALID);

	g_obex_send(obex, req, NULL);
}

void g_obex_suspend(GObex *obex)
{
	struct pending_pkt *req = obex->pending_req;

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "conn %u", obex->conn_id);

	if (!g_obex_srm_active(obex) || !req)
		goto done;

	/* Send SRMP wait in case of GET */
	if (g_obex_packet_get_operation(req->pkt, NULL) == G_OBEX_OP_GET) {
		g_obex_srm_suspend(obex);
		return;
	}

done:
	obex->suspended = TRUE;

	if (obex->write_source > 0) {
		g_source_remove(obex->write_source);
		obex->write_source = 0;
	}
}

static void g_obex_srm_resume(GObex *obex)
{
	struct pending_pkt *p = obex->pending_req;
	GObexPacket *req;

	p->timeout_id = g_timeout_add_seconds(p->timeout, req_timeout, obex);
	p->suspended = FALSE;

	req = g_obex_packet_new(G_OBEX_OP_GET, TRUE, G_OBEX_HDR_INVALID);

	g_obex_send(obex, req, NULL);
}

void g_obex_resume(GObex *obex)
{
	struct pending_pkt *req = obex->pending_req;

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "conn %u", obex->conn_id);

	obex->suspended = FALSE;

	if (g_obex_srm_active(obex) || !req)
		goto done;

	if (g_obex_packet_get_operation(req->pkt, NULL) == G_OBEX_OP_GET)
		g_obex_srm_resume(obex);

done:
	if (g_queue_get_length(obex->tx_queue) > 0 || obex->tx_data > 0)
		enable_tx(obex);
}

gboolean g_obex_srm_active(GObex *obex)
{
	gboolean ret = FALSE;

	if (!g_obex_srm_enabled(obex))
		goto done;

	if (obex->srm->srmp <= G_OBEX_SRMP_NEXT_WAIT)
		goto done;

	ret = TRUE;
done:
	g_obex_debug(G_OBEX_DEBUG_COMMAND, "%s", ret ? "yes" : "no");
	return ret;
}

static void auth_challenge(GObex *obex)
{
	struct pending_pkt *p = obex->pending_req;

	if (p->authenticating)
		return;

	p->authenticating = TRUE;

	prepare_auth_rsp(obex, p->pkt);

	/* Remove it as pending and add it back to the queue so it gets sent
	 * again */
	if (p->timeout_id > 0) {
		g_source_remove(p->timeout_id);
		p->timeout_id = 0;
	}
	obex->pending_req = NULL;
	g_obex_send_internal(obex, p, NULL);
}

static void parse_connect_data(GObex *obex, GObexPacket *pkt)
{
	const struct connect_data *data;
	GObexHeader *hdr;
	guint16 u16;
	size_t data_len;

	data = g_obex_packet_get_data(pkt, &data_len);
	if (data == NULL || data_len != sizeof(*data))
		return;

	memcpy(&u16, &data->mtu, sizeof(u16));

	obex->tx_mtu = g_ntohs(u16);
	if (obex->io_tx_mtu > 0 && obex->tx_mtu > obex->io_tx_mtu)
		obex->tx_mtu = obex->io_tx_mtu;
	obex->tx_buf = g_realloc(obex->tx_buf, obex->tx_mtu);

	hdr = g_obex_packet_get_header(pkt, G_OBEX_HDR_CONNECTION);
	if (hdr)
		g_obex_header_get_uint32(hdr, &obex->conn_id);

	hdr = g_obex_packet_get_header(pkt, G_OBEX_HDR_AUTHCHAL);
	if (hdr)
		obex->authchal = g_obex_header_get_apparam(hdr);
}

static gboolean parse_response(GObex *obex, GObexPacket *rsp)
{
	struct pending_pkt *p = obex->pending_req;
	guint8 opcode, rspcode;
	gboolean final;

	rspcode = g_obex_packet_get_operation(rsp, &final);

	opcode = g_obex_packet_get_operation(p->pkt, NULL);
	if (opcode == G_OBEX_OP_CONNECT) {
		parse_connect_data(obex, rsp);
		if (rspcode == G_OBEX_RSP_UNAUTHORIZED && obex->authchal)
			auth_challenge(obex);
	}

	setup_srm(obex, rsp, FALSE);

	if (!g_obex_srm_enabled(obex))
		return final;

	/*
	 * Resposes have final bit set but in case of GET with SRM
	 * we should not remove the request since the remote side will
	 * continue sending responses until the transfer is finished
	 */
	if (opcode == G_OBEX_OP_GET && rspcode == G_OBEX_RSP_CONTINUE) {
		if (p->timeout_id > 0)
			g_source_remove(p->timeout_id);

		p->timeout_id = g_timeout_add_seconds(p->timeout, req_timeout,
									obex);
		return FALSE;
	}

	return final;
}

static void handle_response(GObex *obex, GError *err, GObexPacket *rsp)
{
	struct pending_pkt *p;
	gboolean disconn = err ? TRUE : FALSE, final_rsp = TRUE;

	if (rsp != NULL)
		final_rsp = parse_response(obex, rsp);

	if (!obex->pending_req)
		return;

	p = obex->pending_req;

	/* Reset if final so it can no longer be cancelled */
	if (final_rsp)
		obex->pending_req = NULL;

	if (p->cancelled)
		err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_CANCELLED,
					"The operation was cancelled");

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

	if (p->rsp_func) {
		p->rsp_func(obex, err, rsp, p->rsp_data);

		/* Check if user callback removed the request */
		if (!final_rsp && p != obex->pending_req)
			return;
	}

	if (p->cancelled)
		g_error_free(err);

	if (final_rsp)
		pending_pkt_free(p);

	if (!disconn && g_queue_get_length(obex->tx_queue) > 0)
		enable_tx(obex);
}

static gboolean check_connid(GObex *obex, GObexPacket *pkt)
{
	GObexHeader *hdr;
	guint32 id;

	if (obex->conn_id == CONNID_INVALID)
		return TRUE;

	hdr = g_obex_packet_get_header(pkt, G_OBEX_HDR_CONNECTION);
	if (hdr == NULL)
		return TRUE;

	g_obex_header_get_uint32(hdr, &id);

	return obex->conn_id == id;
}

static int parse_request(GObex *obex, GObexPacket *req)
{
	guint8 op;
	gboolean final;

	op = g_obex_packet_get_operation(req, &final);
	switch (op) {
	case G_OBEX_OP_CONNECT:
		parse_connect_data(obex, req);
		break;
	case G_OBEX_OP_ABORT:
		break;
	default:
		if (check_connid(obex, req))
			break;

		return -G_OBEX_RSP_SERVICE_UNAVAILABLE;
	}

	setup_srm(obex, req, FALSE);

	return op;
}

static void handle_request(GObex *obex, GObexPacket *req)
{
	GSList *match;
	int op;

	op = parse_request(obex, req);
	if (op < 0)
		goto fail;

	match = g_slist_find_custom(obex->req_handlers, GUINT_TO_POINTER(op),
							req_handler_cmpop);
	if (match) {
		struct req_handler *handler = match->data;
		handler->func(obex, req, handler->user_data);
		return;
	}

	op = -G_OBEX_RSP_NOT_IMPLEMENTED;

fail:
	g_obex_debug(G_OBEX_DEBUG_ERROR, "%s", g_obex_strerror(-op));
	g_obex_send_rsp(obex, -op, NULL, G_OBEX_HDR_INVALID);
}

static gboolean read_stream(GObex *obex, GError **err)
{
	GIOChannel *io = obex->io;
	GIOStatus status;
	gsize rbytes, toread;
	guint16 u16;
	char *buf;

	if (obex->rx_data >= 3)
		goto read_body;

	rbytes = 0;
	toread = 3 - obex->rx_data;
	buf = (char *) &obex->rx_buf[obex->rx_data];

	status = g_io_channel_read_chars(io, buf, toread, &rbytes, NULL);
	if (status != G_IO_STATUS_NORMAL)
		return TRUE;

	obex->rx_data += rbytes;
	if (obex->rx_data < 3)
		goto done;

	memcpy(&u16, &buf[1], sizeof(u16));
	obex->rx_pkt_len = g_ntohs(u16);

	if (obex->rx_pkt_len > obex->rx_mtu) {
		g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_PARSE_ERROR,
				"Too big incoming packet");
		g_obex_debug(G_OBEX_DEBUG_ERROR, "%s", (*err)->message);
		return FALSE;
	}

read_body:
	if (obex->rx_data >= obex->rx_pkt_len)
		goto done;

	do {
		toread = obex->rx_pkt_len - obex->rx_data;
		buf = (char *) &obex->rx_buf[obex->rx_data];

		status = g_io_channel_read_chars(io, buf, toread, &rbytes, NULL);
		if (status != G_IO_STATUS_NORMAL)
			goto done;

		obex->rx_data += rbytes;
	} while (rbytes > 0 && obex->rx_data < obex->rx_pkt_len);

done:
	g_obex_dump(G_OBEX_DEBUG_DATA, ">", obex->rx_buf, obex->rx_data);

	return TRUE;
}

static gboolean read_packet(GObex *obex, GError **err)
{
	GIOChannel *io = obex->io;
	GError *read_err = NULL;
	GIOStatus status;
	gsize rbytes;
	guint16 u16;

	if (obex->rx_data > 0) {
		g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_PARSE_ERROR,
				"RX buffer not empty before reading packet");
		goto fail;
	}

	status = g_io_channel_read_chars(io, (char *) obex->rx_buf,
					obex->rx_mtu, &rbytes, &read_err);
	if (status != G_IO_STATUS_NORMAL) {
		g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_PARSE_ERROR,
				"Unable to read data: %s", read_err->message);
		g_error_free(read_err);
		goto fail;
	}

	obex->rx_data += rbytes;

	if (rbytes < 3) {
		g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_PARSE_ERROR,
				"Incomplete packet received");
		goto fail;
	}

	memcpy(&u16, &obex->rx_buf[1], sizeof(u16));
	obex->rx_pkt_len = g_ntohs(u16);

	if (obex->rx_pkt_len != rbytes) {
		g_set_error(err, G_OBEX_ERROR, G_OBEX_ERROR_PARSE_ERROR,
			"Data size doesn't match packet size (%zu != %u)",
			rbytes, obex->rx_pkt_len);
		return FALSE;
	}

	g_obex_dump(G_OBEX_DEBUG_DATA, ">", obex->rx_buf, obex->rx_data);

	return TRUE;
fail:
	g_obex_debug(G_OBEX_DEBUG_ERROR, "%s", (*err)->message);
	return FALSE;
}

static gboolean incoming_data(GIOChannel *io, GIOCondition cond,
							gpointer user_data)
{
	GObex *obex = user_data;
	GObexPacket *pkt;
	ssize_t header_offset;
	GError *err = NULL;
	guint8 opcode;

	if (cond & G_IO_NVAL)
		return FALSE;

	if (cond & (G_IO_HUP | G_IO_ERR)) {
		err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_DISCONNECTED,
					"Transport got disconnected");
		goto failed;
	}

	if (!obex->read(obex, &err))
		goto failed;

	if (obex->rx_data < 3 || obex->rx_data < obex->rx_pkt_len)
		return TRUE;

	obex->rx_last_op = obex->rx_buf[0] & ~FINAL_BIT;

	if (obex->pending_req) {
		struct pending_pkt *p = obex->pending_req;
		opcode = g_obex_packet_get_operation(p->pkt, NULL);
		header_offset = rsp_header_offset(opcode);
	} else {
		opcode = obex->rx_last_op;
		/* Unexpected response -- fail silently */
		if (opcode > 0x1f && opcode != G_OBEX_OP_ABORT) {
			obex->rx_data = 0;
			return TRUE;
		}
		header_offset = req_header_offset(opcode);
	}

	if (header_offset < 0) {
		err = g_error_new(G_OBEX_ERROR, G_OBEX_ERROR_PARSE_ERROR,
				"Unknown header offset for opcode 0x%02x",
				opcode);
		goto failed;
	}

	pkt = g_obex_packet_decode(obex->rx_buf, obex->rx_data, header_offset,
							G_OBEX_DATA_REF, &err);
	if (pkt == NULL)
		goto failed;

	/* Protect against user callback freeing the object */
	g_obex_ref(obex);

	if (obex->pending_req)
		handle_response(obex, NULL, pkt);
	else
		handle_request(obex, pkt);

	obex->rx_data = 0;

	g_obex_unref(obex);

	if (err != NULL)
		g_error_free(err);

	if (pkt != NULL)
		g_obex_packet_free(pkt);

	return TRUE;

failed:
	if (err)
		g_obex_debug(G_OBEX_DEBUG_ERROR, "%s", err->message);

	g_io_channel_unref(obex->io);
	obex->io = NULL;
	obex->io_source = 0;
	obex->rx_data = 0;

	/* Protect against user callback freeing the object */
	g_obex_ref(obex);

	if (obex->pending_req)
		handle_response(obex, err, NULL);

	if (obex->disconn_func)
		obex->disconn_func(obex, err, obex->disconn_func_data);

	g_obex_unref(obex);

	g_error_free(err);

	return FALSE;
}

static GDebugKey keys[] = {
	{ "error",	G_OBEX_DEBUG_ERROR },
	{ "command",	G_OBEX_DEBUG_COMMAND },
	{ "transfer",	G_OBEX_DEBUG_TRANSFER },
	{ "header",	G_OBEX_DEBUG_HEADER },
	{ "packet",	G_OBEX_DEBUG_PACKET },
	{ "data",	G_OBEX_DEBUG_DATA },
	{ "apparam",	G_OBEX_DEBUG_APPARAM },
};

GObex *g_obex_new(GIOChannel *io, GObexTransportType transport_type,
					gssize io_rx_mtu, gssize io_tx_mtu)
{
	GObex *obex;
	GIOCondition cond;

	if (gobex_debug == 0) {
		const char *env = g_getenv("GOBEX_DEBUG");

		if (env) {
			gobex_debug = g_parse_debug_string(env, keys, 7);
			g_setenv("G_MESSAGES_DEBUG", "gobex", FALSE);
		} else
			gobex_debug = G_OBEX_DEBUG_NONE;
	}

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "");

	if (io == NULL)
		return NULL;

	if (io_rx_mtu >= 0 && io_rx_mtu < G_OBEX_MINIMUM_MTU)
		return NULL;

	if (io_tx_mtu >= 0 && io_tx_mtu < G_OBEX_MINIMUM_MTU)
		return NULL;

	obex = g_new0(GObex, 1);

	obex->io = g_io_channel_ref(io);
	obex->ref_count = 1;
	obex->conn_id = CONNID_INVALID;
	obex->rx_last_op = G_OBEX_OP_NONE;

	obex->io_rx_mtu = io_rx_mtu;
	obex->io_tx_mtu = io_tx_mtu;

	if (io_rx_mtu > G_OBEX_MAXIMUM_MTU)
		obex->rx_mtu = G_OBEX_MAXIMUM_MTU;
	else if (io_rx_mtu < G_OBEX_MINIMUM_MTU)
		obex->rx_mtu = G_OBEX_DEFAULT_MTU;
	else
		obex->rx_mtu = io_rx_mtu;

	obex->tx_mtu = G_OBEX_MINIMUM_MTU;

	obex->tx_queue = g_queue_new();
	obex->rx_buf = g_malloc(obex->rx_mtu);
	obex->tx_buf = g_malloc(obex->tx_mtu);

	switch (transport_type) {
	case G_OBEX_TRANSPORT_STREAM:
		obex->read = read_stream;
		obex->write = write_stream;
		break;
	case G_OBEX_TRANSPORT_PACKET:
		obex->use_srm = TRUE;
		obex->read = read_packet;
		obex->write = write_packet;
		break;
	default:
		g_obex_unref(obex);
		return NULL;
	}

	g_io_channel_set_encoding(io, NULL, NULL);
	g_io_channel_set_buffered(io, FALSE);
	cond = G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL;
	obex->io_source = g_io_add_watch(io, cond, incoming_data, obex);

	return obex;
}

GObex *g_obex_ref(GObex *obex)
{
	int refs;

	if (obex == NULL)
		return NULL;

	refs = __sync_add_and_fetch(&obex->ref_count, 1);

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "ref %u", refs);

	return obex;
}

void g_obex_unref(GObex *obex)
{
	int refs;

	refs = __sync_sub_and_fetch(&obex->ref_count, 1);

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "ref %u", refs);

	if (refs > 0)
		return;

	g_slist_free_full(obex->req_handlers, g_free);

	g_queue_foreach(obex->tx_queue, (GFunc) pending_pkt_free, NULL);
	g_queue_free(obex->tx_queue);

	if (obex->io != NULL)
		g_io_channel_unref(obex->io);

	if (obex->io_source > 0)
		g_source_remove(obex->io_source);

	if (obex->write_source > 0)
		g_source_remove(obex->write_source);

	g_free(obex->rx_buf);
	g_free(obex->tx_buf);
	g_free(obex->srm);

	if (obex->pending_req)
		pending_pkt_free(obex->pending_req);

	if (obex->authchal)
		g_obex_apparam_free(obex->authchal);

	g_free(obex);
}

/* Higher level functions */

guint g_obex_connect(GObex *obex, GObexResponseFunc func, gpointer user_data,
					GError **err, guint8 first_hdr_id, ...)
{
	GObexPacket *req;
	struct connect_data data;
	va_list args;

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "");

	va_start(args, first_hdr_id);
	req = g_obex_packet_new_valist(G_OBEX_OP_CONNECT, TRUE,
							first_hdr_id, args);
	va_end(args);

	init_connect_data(obex, &data);
	g_obex_packet_set_data(req, &data, sizeof(data), G_OBEX_DATA_COPY);

	return g_obex_send_req(obex, req, -1, func, user_data, err);
}

guint g_obex_disconnect(GObex *obex, GObexResponseFunc func, gpointer user_data,
								GError **err)
{
	GObexPacket *req;

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "");

	req = g_obex_packet_new(G_OBEX_OP_DISCONNECT, TRUE, G_OBEX_HDR_INVALID);

	return g_obex_send_req(obex, req, -1, func, user_data, err);
}

guint g_obex_setpath(GObex *obex, const char *path, GObexResponseFunc func,
					gpointer user_data, GError **err)
{
	GObexPacket *req;
	struct setpath_data data;
	const char *folder;

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "conn %u", obex->conn_id);

	req = g_obex_packet_new(G_OBEX_OP_SETPATH, TRUE, G_OBEX_HDR_INVALID);

	memset(&data, 0, sizeof(data));

	if (path != NULL && strncmp("..", path, 2) == 0) {
		data.flags = 0x03;
		folder = (path[2] == '/') ? &path[3] : NULL;
	} else {
		data.flags = 0x02;
		folder = path;
	}

	if (folder != NULL) {
		GObexHeader *hdr;
		hdr = g_obex_header_new_unicode(G_OBEX_HDR_NAME, folder);
		g_obex_packet_add_header(req, hdr);
	}

	g_obex_packet_set_data(req, &data, sizeof(data), G_OBEX_DATA_COPY);

	return g_obex_send_req(obex, req, -1, func, user_data, err);
}

guint g_obex_mkdir(GObex *obex, const char *path, GObexResponseFunc func,
					gpointer user_data, GError **err)
{
	GObexPacket *req;
	struct setpath_data data;

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "conn %u", obex->conn_id);

	req = g_obex_packet_new(G_OBEX_OP_SETPATH, TRUE, G_OBEX_HDR_NAME, path,
							G_OBEX_HDR_INVALID);

	memset(&data, 0, sizeof(data));
	g_obex_packet_set_data(req, &data, sizeof(data), G_OBEX_DATA_COPY);

	return g_obex_send_req(obex, req, -1, func, user_data, err);
}

guint g_obex_delete(GObex *obex, const char *name, GObexResponseFunc func,
					gpointer user_data, GError **err)
{
	GObexPacket *req;

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "conn %u", obex->conn_id);

	req = g_obex_packet_new(G_OBEX_OP_PUT, TRUE, G_OBEX_HDR_NAME, name,
							G_OBEX_HDR_INVALID);

	return g_obex_send_req(obex, req, -1, func, user_data, err);
}

guint g_obex_copy(GObex *obex, const char *name, const char *dest,
			GObexResponseFunc func, gpointer user_data,
			GError **err)
{
	GObexPacket *req;

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "conn %u", obex->conn_id);

	req = g_obex_packet_new(G_OBEX_OP_ACTION, TRUE,
					G_OBEX_HDR_ACTION, G_OBEX_ACTION_COPY,
					G_OBEX_HDR_NAME, name,
					G_OBEX_HDR_DESTNAME, dest,
					G_OBEX_HDR_INVALID);

	return g_obex_send_req(obex, req, -1, func, user_data, err);
}

guint g_obex_move(GObex *obex, const char *name, const char *dest,
			GObexResponseFunc func, gpointer user_data,
			GError **err)
{
	GObexPacket *req;

	g_obex_debug(G_OBEX_DEBUG_COMMAND, "conn %u", obex->conn_id);

	req = g_obex_packet_new(G_OBEX_OP_ACTION, TRUE,
					G_OBEX_HDR_ACTION, G_OBEX_ACTION_MOVE,
					G_OBEX_HDR_NAME, name,
					G_OBEX_HDR_DESTNAME, dest,
					G_OBEX_HDR_INVALID);

	return g_obex_send_req(obex, req, -1, func, user_data, err);
}

guint8 g_obex_errno_to_rsp(int err)
{
	switch (err) {
	case 0:
		return G_OBEX_RSP_SUCCESS;
	case -EPERM:
	case -EACCES:
		return G_OBEX_RSP_FORBIDDEN;
	case -ENOENT:
		return G_OBEX_RSP_NOT_FOUND;
	case -EINVAL:
	case -EBADR:
		return G_OBEX_RSP_BAD_REQUEST;
	case -EFAULT:
		return G_OBEX_RSP_SERVICE_UNAVAILABLE;
	case -ENOSYS:
		return G_OBEX_RSP_NOT_IMPLEMENTED;
	case -ENOTEMPTY:
	case -EEXIST:
		return G_OBEX_RSP_PRECONDITION_FAILED;
	default:
		return G_OBEX_RSP_INTERNAL_SERVER_ERROR;
	}
}
