All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH obexd 1/6 v3] client: Remove buffer based transfer
@ 2012-04-24  9:20 Luiz Augusto von Dentz
  2012-04-24  9:20 ` [PATCH obexd 2/6 v3] client: remove unused field Luiz Augusto von Dentz
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2012-04-24  9:20 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

Simplify the code by using temporary files and eliminates reallocations.
---
v3: Remove unnecessary changes
 client/ftp.c      |    8 +-
 client/manager.c  |   18 +++-
 client/map.c      |   18 +++-
 client/pbap.c     |   39 +++++--
 client/session.c  |   34 +++---
 client/session.h  |    7 +-
 client/sync.c     |   36 +++++--
 client/transfer.c |  301 ++++++++++++++++++++++-------------------------------
 client/transfer.h |    8 +-
 9 files changed, 230 insertions(+), 239 deletions(-)

diff --git a/client/ftp.c b/client/ftp.c
index 9be5d69..f415f2f 100644
--- a/client/ftp.c
+++ b/client/ftp.c
@@ -196,13 +196,12 @@ static void list_folder_callback(struct obc_session *session,
 	GMarkupParseContext *ctxt;
 	DBusMessage *reply;
 	DBusMessageIter iter, array;
-	const char *buf;
+	char *contents;
 	size_t size;
 
 	reply = dbus_message_new_method_return(msg);
 
-	buf = obc_session_get_buffer(session, &size);
-	if (size == 0)
+	if (obc_session_get_contents(session, &contents, &size) < 0)
 		goto done;
 
 	dbus_message_iter_init_append(reply, &iter);
@@ -212,9 +211,10 @@ static void list_folder_callback(struct obc_session *session,
 			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
 			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &array);
 	ctxt = g_markup_parse_context_new(&parser, 0, &array, NULL);
-	g_markup_parse_context_parse(ctxt, buf, strlen(buf) - 1, NULL);
+	g_markup_parse_context_parse(ctxt, contents, size, NULL);
 	g_markup_parse_context_free(ctxt);
 	dbus_message_iter_close_container(&iter, &array);
+	g_free(contents);
 
 done:
 	g_dbus_send_message(conn, reply);
diff --git a/client/manager.c b/client/manager.c
index 2e01e54..4f0b750 100644
--- a/client/manager.c
+++ b/client/manager.c
@@ -442,8 +442,9 @@ static void capabilities_complete_callback(struct obc_session *session,
 						GError *err, void *user_data)
 {
 	struct send_data *data = user_data;
-	const char *capabilities;
+	char *contents;
 	size_t size;
+	int perr;
 
 	if (err != NULL) {
 		DBusMessage *error = g_dbus_create_error(data->message,
@@ -453,13 +454,20 @@ static void capabilities_complete_callback(struct obc_session *session,
 		goto done;
 	}
 
-	capabilities = obc_session_get_buffer(session, &size);
-	if (size == 0)
-		capabilities = "";
+	perr = obc_session_get_contents(session, &contents, &size);
+	if (perr < 0) {
+		DBusMessage *error = g_dbus_create_error(data->message,
+						"org.openobex.Error.Failed",
+						"Error reading contents: %s",
+						strerror(-perr));
+		g_dbus_send_message(data->connection, error);
+		goto done;
+	}
 
 	g_dbus_send_reply(data->connection, data->message,
-			DBUS_TYPE_STRING, &capabilities,
+			DBUS_TYPE_STRING, &contents,
 			DBUS_TYPE_INVALID);
+	g_free(contents);
 
 done:
 
diff --git a/client/map.c b/client/map.c
index 68b1fbc..3841299 100644
--- a/client/map.c
+++ b/client/map.c
@@ -25,6 +25,7 @@
 #endif
 
 #include <errno.h>
+#include <string.h>
 #include <glib.h>
 #include <gdbus.h>
 
@@ -98,8 +99,9 @@ static void buffer_cb(struct obc_session *session, GError *err,
 {
 	struct map_data *map = user_data;
 	DBusMessage *reply;
-	const char *buf;
+	char *contents;
 	size_t size;
+	int perr;
 
 	if (err != NULL) {
 		reply = g_dbus_create_error(map->msg,
@@ -108,13 +110,19 @@ static void buffer_cb(struct obc_session *session, GError *err,
 		goto done;
 	}
 
-	buf = obc_session_get_buffer(session, &size);
-	if (size == 0)
-		buf = "";
+	perr = obc_session_get_contents(session, &contents, &size);
+	if (perr < 0) {
+		reply = g_dbus_create_error(map->msg,
+						"org.openobex.Error.Failed",
+						"Error reading contents: %s",
+						strerror(-perr));
+		goto done;
+	}
 
-	reply = g_dbus_create_reply(map->msg, DBUS_TYPE_STRING, &buf,
+	reply = g_dbus_create_reply(map->msg, DBUS_TYPE_STRING, &contents,
 							DBUS_TYPE_INVALID);
 
+	g_free(contents);
 done:
 	g_dbus_send_message(conn, reply);
 	dbus_message_unref(map->msg);
diff --git a/client/pbap.c b/client/pbap.c
index bcbb39a..f8a72b0 100644
--- a/client/pbap.c
+++ b/client/pbap.c
@@ -343,8 +343,9 @@ static void pull_phonebook_callback(struct obc_session *session,
 {
 	struct pending_request *request = user_data;
 	DBusMessage *reply;
-	const char *buf;
+	char *contents;
 	size_t size;
+	int perr;
 
 	if (err) {
 		reply = g_dbus_create_error(request->msg,
@@ -353,16 +354,23 @@ static void pull_phonebook_callback(struct obc_session *session,
 		goto send;
 	}
 
-	reply = dbus_message_new_method_return(request->msg);
+	perr = obc_session_get_contents(session, &contents, &size);
+	if (perr < 0) {
+		reply = g_dbus_create_error(request->msg,
+						"org.openobex.Error.Failed",
+						"Error reading contents: %s",
+						strerror(-perr));
+		goto send;
+	}
 
-	buf = obc_session_get_buffer(session, &size);
-	if (size == 0)
-		buf = "";
+	reply = dbus_message_new_method_return(request->msg);
 
 	dbus_message_append_args(reply,
-			DBUS_TYPE_STRING, &buf,
+			DBUS_TYPE_STRING, &contents,
 			DBUS_TYPE_INVALID);
 
+	g_free(contents);
+
 send:
 	g_dbus_send_message(conn, reply);
 	pending_request_free(request);
@@ -403,8 +411,9 @@ static void pull_vcard_listing_callback(struct obc_session *session,
 	GMarkupParseContext *ctxt;
 	DBusMessage *reply;
 	DBusMessageIter iter, array;
-	const char *buf;
+	char *contents;
 	size_t size;
+	int perr;
 
 	if (err) {
 		reply = g_dbus_create_error(request->msg,
@@ -413,11 +422,16 @@ static void pull_vcard_listing_callback(struct obc_session *session,
 		goto send;
 	}
 
-	reply = dbus_message_new_method_return(request->msg);
+	perr = obc_session_get_contents(session, &contents, &size);
+	if (perr < 0) {
+		reply = g_dbus_create_error(request->msg,
+						"org.openobex.Error.Failed",
+						"Error reading contents: %s",
+						strerror(-perr));
+		goto send;
+	}
 
-	buf = obc_session_get_buffer(session, &size);
-	if (size == 0)
-		buf = "";
+	reply = dbus_message_new_method_return(request->msg);
 
 	dbus_message_iter_init_append(reply, &iter);
 	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
@@ -425,9 +439,10 @@ static void pull_vcard_listing_callback(struct obc_session *session,
 			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING
 			DBUS_STRUCT_END_CHAR_AS_STRING, &array);
 	ctxt = g_markup_parse_context_new(&listing_parser, 0, &array, NULL);
-	g_markup_parse_context_parse(ctxt, buf, strlen(buf) - 1, NULL);
+	g_markup_parse_context_parse(ctxt, contents, size, NULL);
 	g_markup_parse_context_free(ctxt);
 	dbus_message_iter_close_container(&iter, &array);
+	g_free(contents);
 
 send:
 	g_dbus_send_message(conn, reply);
diff --git a/client/session.c b/client/session.c
index 868eb9f..fe47f9d 100644
--- a/client/session.c
+++ b/client/session.c
@@ -25,6 +25,8 @@
 #include <config.h>
 #endif
 
+#include <stdlib.h>
+#include <stdio.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
@@ -991,7 +993,7 @@ int obc_session_send(struct obc_session *session, const char *filename,
 	if (transfer == NULL)
 		return -EINVAL;
 
-	err = obc_transfer_set_file(transfer);
+	err = obc_transfer_set_file(transfer, NULL, 0);
 	if (err < 0) {
 		obc_transfer_unregister(transfer);
 		return err;
@@ -1059,15 +1061,15 @@ static void session_prepare_put(gpointer data, gpointer user_data)
 	DBG("Transfer(%p) started", transfer);
 }
 
-int obc_session_put(struct obc_session *session, char *buf, const char *name)
+int obc_session_put(struct obc_session *session, const char *contents,
+					size_t size, const char *name)
 {
 	struct obc_transfer *transfer;
 	const char *agent;
+	int err;
 
-	if (session->obex == NULL) {
-		g_free(buf);
+	if (session->obex == NULL)
 		return -ENOTCONN;
-	}
 
 	agent = obc_agent_get_name(session->agent);
 
@@ -1075,12 +1077,14 @@ int obc_session_put(struct obc_session *session, char *buf, const char *name)
 							agent, NULL,
 							name, NULL,
 							NULL);
-	if (transfer == NULL) {
-		g_free(buf);
+	if (transfer == NULL)
 		return -EIO;
-	}
 
-	obc_transfer_set_buffer(transfer, buf);
+	err = obc_transfer_set_file(transfer, contents, size);
+	if (err < 0) {
+		obc_transfer_unregister(transfer);
+		return err;
+	}
 
 	return session_request(session, transfer, session_prepare_put,
 								NULL, NULL);
@@ -1156,24 +1160,20 @@ static struct obc_transfer *obc_session_get_transfer(
 	return session->p->transfer;
 }
 
-const char *obc_session_get_buffer(struct obc_session *session, size_t *size)
+int obc_session_get_contents(struct obc_session *session, char **contents,
+								size_t *size)
 {
 	struct obc_transfer *transfer;
-	const char *buf;
 
 	transfer = obc_session_get_transfer(session);
 	if (transfer == NULL) {
 		if (size != NULL)
 			*size = 0;
 
-		return NULL;
+		return -EINVAL;
 	}
 
-	buf = obc_transfer_get_buffer(transfer, size);
-
-	obc_transfer_clear_buffer(transfer);
-
-	return buf;
+	return obc_transfer_get_contents(transfer, contents, size);
 }
 
 void *obc_session_get_params(struct obc_session *session, size_t *size)
diff --git a/client/session.h b/client/session.h
index 4bfb41d..7e6f42b 100644
--- a/client/session.h
+++ b/client/session.h
@@ -52,7 +52,8 @@ const char *obc_session_get_agent(struct obc_session *session);
 
 const char *obc_session_get_path(struct obc_session *session);
 const char *obc_session_get_target(struct obc_session *session);
-const char *obc_session_get_buffer(struct obc_session *session, size_t *size);
+int obc_session_get_contents(struct obc_session *session, char **contents,
+								size_t *size);
 void *obc_session_get_params(struct obc_session *session, size_t *size);
 
 int obc_session_send(struct obc_session *session, const char *filename,
@@ -66,8 +67,8 @@ int obc_session_pull(struct obc_session *session,
 				session_callback_t function, void *user_data);
 const char *obc_session_register(struct obc_session *session,
 						GDBusDestroyFunction destroy);
-int obc_session_put(struct obc_session *session, char *buf,
-				const char *name);
+int obc_session_put(struct obc_session *session, const char *contents,
+					size_t size, const char *name);
 
 guint obc_session_setpath(struct obc_session *session, const char *path,
 				session_callback_t func, void *user_data,
diff --git a/client/sync.c b/client/sync.c
index 7d713a8..0dffab7 100644
--- a/client/sync.c
+++ b/client/sync.c
@@ -27,6 +27,7 @@
 #endif
 
 #include <errno.h>
+#include <string.h>
 
 #include <glib.h>
 #include <gdbus.h>
@@ -87,19 +88,34 @@ static void sync_getphonebook_callback(struct obc_session *session,
 {
 	struct sync_data *sync = user_data;
 	DBusMessage *reply;
-	const char *buf;
+	char *contents;
 	size_t size;
+	int perr;
+
+	if (err) {
+		reply = g_dbus_create_error(sync->msg,
+						"org.openobex.Error.Failed",
+						"%s", err->message);
+		goto send;
+	}
+
+	perr = obc_session_get_contents(session, &contents, &size);
+	if (perr < 0) {
+		reply = g_dbus_create_error(sync->msg,
+						"org.openobex.Error.Failed",
+						"Error reading contents: %s",
+						strerror(-perr));
+		goto send;
+	}
 
 	reply = dbus_message_new_method_return(sync->msg);
 
-	buf = obc_session_get_buffer(session, &size);
-	if (buf == NULL)
-		buf = "";
+	dbus_message_append_args(reply, DBUS_TYPE_STRING, &contents,
+							DBUS_TYPE_INVALID);
 
-	dbus_message_append_args(reply,
-		DBUS_TYPE_STRING, &buf,
-		DBUS_TYPE_INVALID);
+	g_free(contents);
 
+send:
 	g_dbus_send_message(conn, reply);
 	dbus_message_unref(sync->msg);
 	sync->msg = NULL;
@@ -133,7 +149,6 @@ static DBusMessage *sync_putphonebook(DBusConnection *connection,
 {
 	struct sync_data *sync = user_data;
 	const char *buf;
-	char *buffer;
 
 	if (dbus_message_get_args(message, NULL,
 			DBUS_TYPE_STRING, &buf,
@@ -145,9 +160,8 @@ static DBusMessage *sync_putphonebook(DBusConnection *connection,
 	if (!sync->phonebook_path)
 		sync->phonebook_path = g_strdup("telecom/pb.vcf");
 
-	buffer = g_strdup(buf);
-
-	if (obc_session_put(sync->session, buffer, sync->phonebook_path) < 0)
+	if (obc_session_put(sync->session, buf, strlen(buf),
+						sync->phonebook_path) < 0)
 		return g_dbus_create_error(message,
 				ERROR_INF ".Failed", "Failed");
 
diff --git a/client/transfer.c b/client/transfer.c
index f476680..f1cdbf0 100644
--- a/client/transfer.c
+++ b/client/transfer.c
@@ -25,6 +25,8 @@
 #include <config.h>
 #endif
 
+#include <stdlib.h>
+#include <stdio.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <unistd.h>
@@ -42,8 +44,6 @@
 #define TRANSFER_INTERFACE  "org.openobex.Transfer"
 #define TRANSFER_BASEPATH   "/org/openobex"
 
-#define DEFAULT_BUFFER_SIZE 4096
-
 #define OBC_TRANSFER_ERROR obc_transfer_error_quark()
 
 static guint64 counter = 0;
@@ -65,9 +65,6 @@ struct obc_transfer {
 	char *type;		/* Transfer object type */
 	int fd;
 	guint xfer;
-	char *buffer;
-	size_t buffer_len;
-	int filled;
 	gint64 size;
 	gint64 transferred;
 	int err;
@@ -219,7 +216,6 @@ static void obc_transfer_free(struct obc_transfer *transfer)
 	g_free(transfer->name);
 	g_free(transfer->type);
 	g_free(transfer->path);
-	g_free(transfer->buffer);
 	g_free(transfer);
 }
 
@@ -282,31 +278,35 @@ void obc_transfer_unregister(struct obc_transfer *transfer)
 	obc_transfer_free(transfer);
 }
 
-static void obc_transfer_read(struct obc_transfer *transfer,
-						const void *buf, gsize len)
+static gboolean get_xfer_progress(const void *buf, gsize len,
+							gpointer user_data)
 {
-	gsize bsize;
+	struct obc_transfer *transfer = user_data;
+	struct transfer_callback *callback = transfer->callback;
 
-	/* copy all buffered data */
-	bsize = transfer->buffer_len - transfer->filled;
+	if (transfer->fd > 0) {
+		gint w;
 
-	if (bsize < len) {
-		transfer->buffer_len += len - bsize;
-		transfer->buffer = g_realloc(transfer->buffer,
-							transfer->buffer_len);
+		w = write(transfer->fd, buf, len);
+		if (w < 0) {
+			transfer->err = -errno;
+			return FALSE;
+		}
+
+		transfer->transferred += w;
 	}
 
-	memcpy(transfer->buffer + transfer->filled, buf, len);
+	if (callback && transfer->transferred != transfer->size)
+		callback->func(transfer, transfer->transferred, NULL,
+							callback->data);
 
-	transfer->filled += len;
-	transfer->transferred += len;
+	return TRUE;
 }
 
-static void get_buf_xfer_complete(GObex *obex, GError *err, gpointer user_data)
+static void xfer_complete(GObex *obex, GError *err, gpointer user_data)
 {
 	struct obc_transfer *transfer = user_data;
 	struct transfer_callback *callback = transfer->callback;
-	gsize bsize;
 
 	transfer->xfer = 0;
 
@@ -315,30 +315,17 @@ static void get_buf_xfer_complete(GObex *obex, GError *err, gpointer user_data)
 		goto done;
 	}
 
-	if (transfer->filled > 0 &&
-			transfer->buffer[transfer->filled - 1] == '\0')
-		goto done;
-
-	bsize = transfer->buffer_len - transfer->filled;
-	if (bsize < 1) {
-		transfer->buffer_len += 1;
-		transfer->buffer = g_realloc(transfer->buffer,
-						transfer->buffer_len);
-	}
-
-	transfer->buffer[transfer->filled] = '\0';
-	transfer->size = strlen(transfer->buffer);
+	transfer->size = transfer->transferred;
 
 done:
 	if (callback)
 		callback->func(transfer, transfer->size, err, callback->data);
 }
 
-static void get_buf_xfer_progress(GObex *obex, GError *err, GObexPacket *rsp,
+static void get_xfer_progress_first(GObex *obex, GError *err, GObexPacket *rsp,
 							gpointer user_data)
 {
 	struct obc_transfer *transfer = user_data;
-	struct transfer_callback *callback = transfer->callback;
 	GObexPacket *req;
 	GObexHeader *hdr;
 	const guint8 *buf;
@@ -347,7 +334,7 @@ static void get_buf_xfer_progress(GObex *obex, GError *err, GObexPacket *rsp,
 	gboolean final;
 
 	if (err != NULL) {
-		get_buf_xfer_complete(obex, err, transfer);
+		xfer_complete(obex, err, transfer);
 		return;
 	}
 
@@ -355,7 +342,7 @@ static void get_buf_xfer_progress(GObex *obex, GError *err, GObexPacket *rsp,
 	if (rspcode != G_OBEX_RSP_SUCCESS && rspcode != G_OBEX_RSP_CONTINUE) {
 		err = g_error_new(OBC_TRANSFER_ERROR, rspcode,
 					"Transfer failed (0x%02x)", rspcode);
-		get_buf_xfer_complete(obex, err, transfer);
+		xfer_complete(obex, err, transfer);
 		g_error_free(err);
 		return;
 	}
@@ -379,96 +366,21 @@ static void get_buf_xfer_progress(GObex *obex, GError *err, GObexPacket *rsp,
 	if (hdr) {
 		g_obex_header_get_bytes(hdr, &buf, &len);
 		if (len != 0)
-			obc_transfer_read(transfer, buf, len);
+			get_xfer_progress(buf, len, transfer);
 	}
 
 	if (rspcode == G_OBEX_RSP_SUCCESS) {
-		get_buf_xfer_complete(obex, err, transfer);
+		xfer_complete(obex, err, transfer);
 		return;
 	}
 
 	if (!g_obex_srm_active(obex)) {
 		req = g_obex_packet_new(G_OBEX_OP_GET, TRUE, G_OBEX_HDR_INVALID);
 
-		transfer->xfer = g_obex_send_req(obex, req, -1,
-							get_buf_xfer_progress,
-							transfer, &err);
-	}
-
-	if (callback && transfer->transferred != transfer->size)
-		callback->func(transfer, transfer->transferred, err,
-							callback->data);
-}
-
-static void xfer_complete(GObex *obex, GError *err, gpointer user_data)
-{
-	struct obc_transfer *transfer = user_data;
-	struct transfer_callback *callback = transfer->callback;
-
-	transfer->xfer = 0;
-
-	if (err) {
-		transfer->err = err->code;
-		goto done;
-	}
-
-	transfer->size = transfer->transferred;
-
-done:
-	if (callback)
-		callback->func(transfer, transfer->size, err, callback->data);
-}
-
-static gboolean get_xfer_progress(const void *buf, gsize len,
-							gpointer user_data)
-{
-	struct obc_transfer *transfer = user_data;
-	struct transfer_callback *callback = transfer->callback;
-
-	obc_transfer_read(transfer, buf, len);
-
-	if (transfer->fd > 0) {
-		gint w;
-
-		w = write(transfer->fd, transfer->buffer, transfer->filled);
-		if (w < 0) {
-			transfer->err = -errno;
-			return FALSE;
-		}
-
-		transfer->filled -= w;
+		transfer->xfer = g_obex_get_req_pkt(obex, req, get_xfer_progress,
+						xfer_complete, transfer,
+						&err);
 	}
-
-	if (callback && transfer->transferred != transfer->size)
-		callback->func(transfer, transfer->transferred, NULL,
-							callback->data);
-
-	return TRUE;
-}
-
-static gssize put_buf_xfer_progress(void *buf, gsize len, gpointer user_data)
-{
-	struct obc_transfer *transfer = user_data;
-	struct transfer_callback *callback = transfer->callback;
-	gsize size;
-
-	if (transfer->transferred == transfer->size)
-		return 0;
-
-	size = transfer->size - transfer->transferred;
-	size = len > size ? len : size;
-	if (size == 0)
-		return 0;
-
-	memcpy(buf, transfer->buffer + transfer->transferred, size);
-
-	transfer->transferred += size;
-
-	if (callback)
-		callback->func(transfer, transfer->transferred, NULL,
-							callback->data);
-
-	return size;
 }
 
 static gssize put_xfer_progress(void *buf, gsize len, gpointer user_data)
@@ -510,33 +422,47 @@ gboolean obc_transfer_set_callback(struct obc_transfer *transfer,
 	return TRUE;
 }
 
-int obc_transfer_get(struct obc_transfer *transfer)
+static int transfer_open(struct obc_transfer *transfer, int flags, mode_t mode)
 {
 	GError *err = NULL;
-	GObexPacket *req;
-	GObexDataConsumer data_cb;
-	GObexFunc complete_cb;
-	GObexResponseFunc rsp_cb = NULL;
-
-	if (transfer->xfer != 0)
-		return -EALREADY;
+	int fd;
 
-	if (transfer->type != NULL &&
-			(strncmp(transfer->type, "x-obex/", 7) == 0 ||
-			strncmp(transfer->type, "x-bt/", 5) == 0)) {
-		rsp_cb = get_buf_xfer_progress;
-	} else {
-		int fd = open(transfer->filename ? : transfer->name,
-				O_WRONLY | O_CREAT, 0600);
+	if (transfer->filename != NULL) {
+		fd = open(transfer->filename, flags, mode);
 		if (fd < 0) {
 			error("open(): %s(%d)", strerror(errno), errno);
 			return -errno;
 		}
-		transfer->fd = fd;
-		data_cb = get_xfer_progress;
-		complete_cb = xfer_complete;
+		goto done;
 	}
 
+	fd = g_file_open_tmp("obex-clientXXXXXX", &transfer->filename, &err);
+	if (fd < 0) {
+		error("g_file_open_tmp(): %s", err->message);
+		g_error_free(err);
+		return -EFAULT;
+	}
+
+	remove(transfer->filename);
+
+done:
+	transfer->fd = fd;
+	return fd;
+}
+
+int obc_transfer_get(struct obc_transfer *transfer)
+{
+	GError *err = NULL;
+	GObexPacket *req;
+	int perr;
+
+	if (transfer->xfer != 0)
+		return -EALREADY;
+
+	perr = transfer_open(transfer, O_WRONLY | O_CREAT, 0600);
+	if (perr < 0)
+		return perr;
+
 	req = g_obex_packet_new(G_OBEX_OP_GET, TRUE, G_OBEX_HDR_INVALID);
 
 	if (transfer->name != NULL)
@@ -552,14 +478,9 @@ int obc_transfer_get(struct obc_transfer *transfer)
 						transfer->params->data,
 						transfer->params->size);
 
-	if (rsp_cb)
-		transfer->xfer = g_obex_send_req(transfer->obex, req, -1,
-						rsp_cb, transfer, &err);
-	else
-		transfer->xfer = g_obex_get_req_pkt(transfer->obex, req,
-						data_cb, complete_cb, transfer,
-						&err);
-
+	transfer->xfer = g_obex_send_req(transfer->obex, req, -1,
+						get_xfer_progress_first,
+						transfer, &err);
 	if (transfer->xfer == 0)
 		return -ENOTCONN;
 
@@ -570,19 +491,10 @@ int obc_transfer_put(struct obc_transfer *transfer)
 {
 	GError *err = NULL;
 	GObexPacket *req;
-	GObexDataProducer data_cb;
 
 	if (transfer->xfer != 0)
 		return -EALREADY;
 
-	if (transfer->buffer) {
-		data_cb = put_buf_xfer_progress;
-		goto done;
-	}
-
-	data_cb = put_xfer_progress;
-
-done:
 	req = g_obex_packet_new(G_OBEX_OP_PUT, FALSE, G_OBEX_HDR_INVALID);
 
 	if (transfer->name != NULL)
@@ -601,9 +513,9 @@ done:
 						transfer->params->data,
 						transfer->params->size);
 
-	transfer->xfer = g_obex_put_req_pkt(transfer->obex, req, data_cb,
-						xfer_complete, transfer,
-						&err);
+	transfer->xfer = g_obex_put_req_pkt(transfer->obex, req,
+					put_xfer_progress, xfer_complete,
+					transfer, &err);
 	if (transfer->xfer == 0)
 		return -ENOTCONN;
 
@@ -619,23 +531,40 @@ int obc_transfer_get_params(struct obc_transfer *transfer,
 	return 0;
 }
 
-void obc_transfer_clear_buffer(struct obc_transfer *transfer)
+int obc_transfer_get_contents(struct obc_transfer *transfer, char **contents,
+								size_t *size)
 {
-	transfer->filled = 0;
-}
+	struct stat st;
+	ssize_t ret;
 
-const char *obc_transfer_get_buffer(struct obc_transfer *transfer, size_t *size)
-{
-	if (size)
-		*size = transfer->filled;
+	if (contents == NULL)
+		return -EINVAL;
 
-	return transfer->buffer;
-}
+	if (fstat(transfer->fd, &st) < 0) {
+		error("fstat(): %s(%d)", strerror(errno), errno);
+		return -errno;
+	}
 
-void obc_transfer_set_buffer(struct obc_transfer *transfer, char *buffer)
-{
-	transfer->size = strlen(buffer);
-	transfer->buffer = buffer;
+	if (lseek(transfer->fd, 0, SEEK_SET) < 0) {
+		error("lseek(): %s(%d)", strerror(errno), errno);
+		return -errno;
+	}
+
+	*contents = g_malloc(st.st_size + 1);
+
+	ret = read(transfer->fd, *contents, st.st_size);
+	if (ret < 0) {
+		error("read(): %s(%d)", strerror(errno), errno);
+		g_free(*contents);
+		return -errno;
+	}
+
+	(*contents)[ret] = '\0';
+
+	if (size)
+		*size = ret;
+
+	return 0;
 }
 
 void obc_transfer_set_name(struct obc_transfer *transfer, const char *name)
@@ -661,25 +590,41 @@ gint64 obc_transfer_get_size(struct obc_transfer *transfer)
 	return transfer->size;
 }
 
-int obc_transfer_set_file(struct obc_transfer *transfer)
+int obc_transfer_set_file(struct obc_transfer *transfer, const char *contents,
+								size_t size)
 {
-	int fd;
+	int err;
 	struct stat st;
 
-	fd = open(transfer->filename, O_RDONLY);
-	if (fd < 0) {
-		error("open(): %s(%d)", strerror(errno), errno);
-		return -errno;
+	err = transfer_open(transfer, O_RDONLY, 0);
+	if (err < 0)
+		return err;
+
+	if (contents != NULL) {
+		ssize_t w = write(transfer->fd, contents, size);
+		if (w < 0) {
+			error("write(): %s(%d)", strerror(errno), errno);
+			err = -errno;
+			goto fail;
+		} else if ((size_t) w != size) {
+			error("Unable to write all contents to file");
+			err = -EFAULT;
+			goto fail;
+		}
 	}
 
-	if (fstat(fd, &st) < 0) {
+	err = fstat(transfer->fd, &st);
+	if (err < 0) {
 		error("fstat(): %s(%d)", strerror(errno), errno);
-		close(fd);
-		return -errno;
+		err = -errno;
+		goto fail;
 	}
 
-	transfer->fd = fd;
 	transfer->size = st.st_size;
 
 	return 0;
+fail:
+	close(transfer->fd);
+	transfer->fd = -1;
+	return err;
 }
diff --git a/client/transfer.h b/client/transfer.h
index da7d151..a65981c 100644
--- a/client/transfer.h
+++ b/client/transfer.h
@@ -51,13 +51,13 @@ int obc_transfer_put(struct obc_transfer *transfer);
 
 int obc_transfer_get_params(struct obc_transfer *transfer,
 					struct obc_transfer_params *params);
-const char *obc_transfer_get_buffer(struct obc_transfer *transfer, size_t *size);
-void obc_transfer_set_buffer(struct obc_transfer *transfer, char *buffer);
-void obc_transfer_clear_buffer(struct obc_transfer *transfer);
+int obc_transfer_get_contents(struct obc_transfer *transfer, char **contents,
+								size_t *size);
 
 void obc_transfer_set_name(struct obc_transfer *transfer, const char *name);
 void obc_transfer_set_filename(struct obc_transfer *transfer,
 					const char *filename);
 const char *obc_transfer_get_path(struct obc_transfer *transfer);
 gint64 obc_transfer_get_size(struct obc_transfer *transfer);
-int obc_transfer_set_file(struct obc_transfer *transfer);
+int obc_transfer_set_file(struct obc_transfer *transfer, const char *contents,
+								size_t size);
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH obexd 2/6 v3] client: remove unused field
  2012-04-24  9:20 [PATCH obexd 1/6 v3] client: Remove buffer based transfer Luiz Augusto von Dentz
@ 2012-04-24  9:20 ` Luiz Augusto von Dentz
  2012-04-24  9:20 ` [PATCH obexd 3/6 v3] client: transfer api merges put and get Luiz Augusto von Dentz
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2012-04-24  9:20 UTC (permalink / raw)
  To: linux-bluetooth

From: Mikel Astiz <mikel.astiz@bmw-carit.de>

The errorcode field is set but never used, so it can safely be removed.
In addition there is no need for such a field, because errors can be
propagated using the available callback.
---
 client/transfer.c |   13 +++----------
 1 files changed, 3 insertions(+), 10 deletions(-)

diff --git a/client/transfer.c b/client/transfer.c
index f1cdbf0..1fa23c3 100644
--- a/client/transfer.c
+++ b/client/transfer.c
@@ -67,7 +67,6 @@ struct obc_transfer {
 	guint xfer;
 	gint64 size;
 	gint64 transferred;
-	int err;
 };
 
 static GQuark obc_transfer_error_quark(void)
@@ -288,10 +287,8 @@ static gboolean get_xfer_progress(const void *buf, gsize len,
 		gint w;
 
 		w = write(transfer->fd, buf, len);
-		if (w < 0) {
-			transfer->err = -errno;
+		if (w < 0)
 			return FALSE;
-		}
 
 		transfer->transferred += w;
 	}
@@ -310,10 +307,8 @@ static void xfer_complete(GObex *obex, GError *err, gpointer user_data)
 
 	transfer->xfer = 0;
 
-	if (err) {
-		transfer->err = err->code;
+	if (err)
 		goto done;
-	}
 
 	transfer->size = transfer->transferred;
 
@@ -390,10 +385,8 @@ static gssize put_xfer_progress(void *buf, gsize len, gpointer user_data)
 	gssize size;
 
 	size = read(transfer->fd, buf, len);
-	if (size <= 0) {
-		transfer->err = -errno;
+	if (size <= 0)
 		return size;
-	}
 
 	if (callback)
 		callback->func(transfer, transfer->transferred, NULL,
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH obexd 3/6 v3] client: transfer api merges put and get
  2012-04-24  9:20 [PATCH obexd 1/6 v3] client: Remove buffer based transfer Luiz Augusto von Dentz
  2012-04-24  9:20 ` [PATCH obexd 2/6 v3] client: remove unused field Luiz Augusto von Dentz
@ 2012-04-24  9:20 ` Luiz Augusto von Dentz
  2012-04-24  9:20 ` [PATCH obexd 4/6 v3] client: transfers take gobex when starting Luiz Augusto von Dentz
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2012-04-24  9:20 UTC (permalink / raw)
  To: linux-bluetooth

From: Mikel Astiz <mikel.astiz@bmw-carit.de>

A new enum type is used to distinguish put and get transfers.

This is more convenient since it is done when registering the transfer,
and not when it is actually started. The main benefits would be:
    - Some actions can be taken during creation, such as opening files.
    - session.c gets simplified.
    - The size of a put transfer can be exposed in D-Bus, while queued.
    - The transfer operation (put or get) can be exposed in D-Bus.

None of these D-Bus changes are included in this patch.
---
 client/session.c  |   67 ++++++++++++++++------------------------------------
 client/transfer.c |   54 +++++++++++++++++++++++++++++++-----------
 client/transfer.h |    5 ++-
 3 files changed, 64 insertions(+), 62 deletions(-)

diff --git a/client/session.c b/client/session.c
index fe47f9d..ab20b88 100644
--- a/client/session.c
+++ b/client/session.c
@@ -100,7 +100,7 @@ struct obc_session {
 
 static GSList *sessions = NULL;
 
-static void session_prepare_put(gpointer data, gpointer user_data);
+static void session_start_transfer(gpointer data, gpointer user_data);
 static void session_terminate_transfer(struct obc_session *session,
 					struct obc_transfer *transfer,
 					GError *gerr);
@@ -686,7 +686,7 @@ static void session_request_reply(DBusPendingCall *call, gpointer user_data)
 	DBG("Agent.Request() reply: %s", name);
 
 	if (strlen(name)) {
-		if (p->auth_complete == session_prepare_put)
+		if (obc_transfer_get_operation(transfer) == G_OBEX_OP_PUT)
 			obc_transfer_set_name(transfer, name);
 		else
 			obc_transfer_set_filename(transfer, name);
@@ -731,7 +731,6 @@ static int pending_request_auth(struct pending_request *p)
 
 static int session_request(struct obc_session *session,
 					struct obc_transfer *transfer,
-					GFunc auth_complete,
 					session_callback_t func,
 					void *data)
 {
@@ -740,7 +739,8 @@ static int session_request(struct obc_session *session,
 
 	obc_transfer_set_callback(transfer, transfer_progress, session);
 
-	p = pending_request_new(session, transfer, auth_complete, func, data);
+	p = pending_request_new(session, transfer, session_start_transfer,
+								func, data);
 
 	if (session->p) {
 		g_queue_push_tail(session->queue, p);
@@ -917,19 +917,15 @@ fail:
 	session_notify_error(session, transfer, err);
 }
 
-static void session_prepare_get(gpointer data, gpointer user_data)
+static void session_start_transfer(gpointer data, gpointer user_data)
 {
 	struct obc_session *session = data;
 	struct obc_transfer *transfer = user_data;
-	int ret;
+	GError *err = NULL;
 
-	ret = obc_transfer_get(transfer);
-	if (ret < 0) {
-		GError *gerr = NULL;
-
-		g_set_error(&gerr, OBEX_IO_ERROR, ret, "%s", strerror(-ret));
-		session_notify_error(session, transfer, gerr);
-		g_clear_error(&gerr);
+	if (!obc_transfer_start(transfer, &err)) {
+		session_notify_error(session, transfer, err);
+		g_clear_error(&err);
 		return;
 	}
 
@@ -961,8 +957,9 @@ int obc_session_get(struct obc_session *session, const char *type,
 		agent = NULL;
 
 	transfer = obc_transfer_register(session->conn, session->obex,
-							agent, targetfile,
-							name, type, params);
+						agent, G_OBEX_OP_GET,
+						targetfile, name,
+						type, params);
 	if (transfer == NULL) {
 		if (params != NULL) {
 			g_free(params->data);
@@ -971,8 +968,7 @@ int obc_session_get(struct obc_session *session, const char *type,
 		return -EIO;
 	}
 
-	return session_request(session, transfer, session_prepare_get,
-							func, user_data);
+	return session_request(session, transfer, func, user_data);
 }
 
 int obc_session_send(struct obc_session *session, const char *filename,
@@ -988,8 +984,9 @@ int obc_session_send(struct obc_session *session, const char *filename,
 	agent = obc_agent_get_name(session->agent);
 
 	transfer = obc_transfer_register(session->conn, session->obex,
-							agent, filename,
-							name, NULL, NULL);
+						agent, G_OBEX_OP_PUT,
+						filename, name,
+						NULL, NULL);
 	if (transfer == NULL)
 		return -EINVAL;
 
@@ -999,8 +996,7 @@ int obc_session_send(struct obc_session *session, const char *filename,
 		return err;
 	}
 
-	return session_request(session, transfer, session_prepare_put,
-								NULL, NULL);
+	return session_request(session, transfer, NULL, NULL);
 }
 
 int obc_session_pull(struct obc_session *session,
@@ -1041,26 +1037,6 @@ fail:
 	return NULL;
 }
 
-static void session_prepare_put(gpointer data, gpointer user_data)
-{
-	struct obc_session *session = data;
-	struct obc_transfer *transfer = user_data;
-	int ret;
-
-	ret = obc_transfer_put(transfer);
-	if (ret < 0) {
-		GError *gerr = NULL;
-
-		g_set_error(&gerr, OBEX_IO_ERROR, ret, "%s (%d)",
-							strerror(-ret), -ret);
-		session_notify_error(session, transfer, gerr);
-		g_clear_error(&gerr);
-		return;
-	}
-
-	DBG("Transfer(%p) started", transfer);
-}
-
 int obc_session_put(struct obc_session *session, const char *contents,
 					size_t size, const char *name)
 {
@@ -1074,9 +1050,9 @@ int obc_session_put(struct obc_session *session, const char *contents,
 	agent = obc_agent_get_name(session->agent);
 
 	transfer = obc_transfer_register(session->conn, session->obex,
-							agent, NULL,
-							name, NULL,
-							NULL);
+							agent, G_OBEX_OP_PUT,
+							NULL, name,
+							NULL, NULL);
 	if (transfer == NULL)
 		return -EIO;
 
@@ -1086,8 +1062,7 @@ int obc_session_put(struct obc_session *session, const char *contents,
 		return err;
 	}
 
-	return session_request(session, transfer, session_prepare_put,
-								NULL, NULL);
+	return session_request(session, transfer, NULL, NULL);
 }
 
 static void agent_destroy(gpointer data, gpointer user_data)
diff --git a/client/transfer.c b/client/transfer.c
index 1fa23c3..259d3aa 100644
--- a/client/transfer.c
+++ b/client/transfer.c
@@ -55,6 +55,7 @@ struct transfer_callback {
 
 struct obc_transfer {
 	GObex *obex;
+	guint8 op;
 	struct obc_transfer_params *params;
 	struct transfer_callback *callback;
 	DBusConnection *conn;
@@ -221,6 +222,7 @@ static void obc_transfer_free(struct obc_transfer *transfer)
 struct obc_transfer *obc_transfer_register(DBusConnection *conn,
 						GObex *obex,
 						const char *agent,
+						guint8 op,
 						const char *filename,
 						const char *name,
 						const char *type,
@@ -230,6 +232,7 @@ struct obc_transfer *obc_transfer_register(DBusConnection *conn,
 
 	transfer = g_new0(struct obc_transfer, 1);
 	transfer->obex = g_obex_ref(obex);
+	transfer->op = op;
 	transfer->agent = g_strdup(agent);
 	transfer->filename = g_strdup(filename);
 	transfer->name = g_strdup(name);
@@ -443,14 +446,16 @@ done:
 	return fd;
 }
 
-int obc_transfer_get(struct obc_transfer *transfer)
+static gboolean transfer_start_get(struct obc_transfer *transfer, GError **err)
 {
-	GError *err = NULL;
 	GObexPacket *req;
 	int perr;
 
-	if (transfer->xfer != 0)
-		return -EALREADY;
+	if (transfer->xfer > 0) {
+		g_set_error(err, OBC_TRANSFER_ERROR, -EALREADY,
+						"Transfer already started");
+		return FALSE;
+	}
 
 	perr = transfer_open(transfer, O_WRONLY | O_CREAT, 0600);
 	if (perr < 0)
@@ -473,20 +478,22 @@ int obc_transfer_get(struct obc_transfer *transfer)
 
 	transfer->xfer = g_obex_send_req(transfer->obex, req, -1,
 						get_xfer_progress_first,
-						transfer, &err);
+						transfer, err);
 	if (transfer->xfer == 0)
-		return -ENOTCONN;
+		return FALSE;
 
-	return 0;
+	return TRUE;
 }
 
-int obc_transfer_put(struct obc_transfer *transfer)
+static gboolean transfer_start_put(struct obc_transfer *transfer, GError **err)
 {
-	GError *err = NULL;
 	GObexPacket *req;
 
-	if (transfer->xfer != 0)
-		return -EALREADY;
+	if (transfer->xfer > 0) {
+		g_set_error(err, OBC_TRANSFER_ERROR, -EALREADY,
+						"Transfer already started");
+		return FALSE;
+	}
 
 	req = g_obex_packet_new(G_OBEX_OP_PUT, FALSE, G_OBEX_HDR_INVALID);
 
@@ -508,11 +515,30 @@ int obc_transfer_put(struct obc_transfer *transfer)
 
 	transfer->xfer = g_obex_put_req_pkt(transfer->obex, req,
 					put_xfer_progress, xfer_complete,
-					transfer, &err);
+					transfer, err);
 	if (transfer->xfer == 0)
-		return -ENOTCONN;
+		return FALSE;
 
-	return 0;
+	return TRUE;
+}
+
+gboolean obc_transfer_start(struct obc_transfer *transfer, GObex *obex,
+								GError **err)
+{
+	switch (transfer->op) {
+	case G_OBEX_OP_GET:
+		return transfer_start_get(transfer, err);
+	case G_OBEX_OP_PUT:
+		return transfer_start_put(transfer, err);
+	}
+
+	g_set_error(err, OBC_TRANSFER_ERROR, -ENOTSUP, "Not supported");
+	return FALSE;
+}
+
+guint8 obc_transfer_get_operation(struct obc_transfer *transfer)
+{
+	return transfer->op;
 }
 
 int obc_transfer_get_params(struct obc_transfer *transfer,
diff --git a/client/transfer.h b/client/transfer.h
index a65981c..7858423 100644
--- a/client/transfer.h
+++ b/client/transfer.h
@@ -35,6 +35,7 @@ typedef void (*transfer_callback_t) (struct obc_transfer *transfer,
 struct obc_transfer *obc_transfer_register(DBusConnection *conn,
 					GObex *obex,
 					const char *agent,
+					guint8 op,
 					const char *filename,
 					const char *name,
 					const char *type,
@@ -46,8 +47,8 @@ gboolean obc_transfer_set_callback(struct obc_transfer *transfer,
 					transfer_callback_t func,
 					void *user_data);
 
-int obc_transfer_get(struct obc_transfer *transfer);
-int obc_transfer_put(struct obc_transfer *transfer);
+gboolean obc_transfer_start(struct obc_transfer *transfer, GError **err);
+guint8 obc_transfer_get_operation(struct obc_transfer *transfer);
 
 int obc_transfer_get_params(struct obc_transfer *transfer,
 					struct obc_transfer_params *params);
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH obexd 4/6 v3] client: transfers take gobex when starting
  2012-04-24  9:20 [PATCH obexd 1/6 v3] client: Remove buffer based transfer Luiz Augusto von Dentz
  2012-04-24  9:20 ` [PATCH obexd 2/6 v3] client: remove unused field Luiz Augusto von Dentz
  2012-04-24  9:20 ` [PATCH obexd 3/6 v3] client: transfer api merges put and get Luiz Augusto von Dentz
@ 2012-04-24  9:20 ` Luiz Augusto von Dentz
  2012-04-24  9:20 ` [PATCH obexd 5/6 v3] client: open file during transfer creation Luiz Augusto von Dentz
  2012-04-24  9:20 ` [PATCH obexd 6/6 v3] client: Remove file in case of error Luiz Augusto von Dentz
  4 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2012-04-24  9:20 UTC (permalink / raw)
  To: linux-bluetooth

From: Mikel Astiz <mikel.astiz@bmw-carit.de>

gobex api should not be used by a transfer until it is started. This
seems more explicit if the pointer is not passed during creation.
---
v3: Fix code style

 client/session.c  |   20 +++++++-------------
 client/transfer.c |    4 ++--
 client/transfer.h |    4 ++--
 3 files changed, 11 insertions(+), 17 deletions(-)

diff --git a/client/session.c b/client/session.c
index ab20b88..306e2ba 100644
--- a/client/session.c
+++ b/client/session.c
@@ -923,7 +923,7 @@ static void session_start_transfer(gpointer data, gpointer user_data)
 	struct obc_transfer *transfer = user_data;
 	GError *err = NULL;
 
-	if (!obc_transfer_start(transfer, &err)) {
+	if (!obc_transfer_start(transfer, session->obex, &err)) {
 		session_notify_error(session, transfer, err);
 		g_clear_error(&err);
 		return;
@@ -956,10 +956,8 @@ int obc_session_get(struct obc_session *session, const char *type,
 	else
 		agent = NULL;
 
-	transfer = obc_transfer_register(session->conn, session->obex,
-						agent, G_OBEX_OP_GET,
-						targetfile, name,
-						type, params);
+	transfer = obc_transfer_register(session->conn, agent, G_OBEX_OP_GET,
+					targetfile, name, type, params);
 	if (transfer == NULL) {
 		if (params != NULL) {
 			g_free(params->data);
@@ -983,10 +981,8 @@ int obc_session_send(struct obc_session *session, const char *filename,
 
 	agent = obc_agent_get_name(session->agent);
 
-	transfer = obc_transfer_register(session->conn, session->obex,
-						agent, G_OBEX_OP_PUT,
-						filename, name,
-						NULL, NULL);
+	transfer = obc_transfer_register(session->conn, agent, G_OBEX_OP_PUT,
+						filename, name, NULL, NULL);
 	if (transfer == NULL)
 		return -EINVAL;
 
@@ -1049,10 +1045,8 @@ int obc_session_put(struct obc_session *session, const char *contents,
 
 	agent = obc_agent_get_name(session->agent);
 
-	transfer = obc_transfer_register(session->conn, session->obex,
-							agent, G_OBEX_OP_PUT,
-							NULL, name,
-							NULL, NULL);
+	transfer = obc_transfer_register(session->conn, agent, G_OBEX_OP_PUT,
+						NULL, name, NULL, NULL);
 	if (transfer == NULL)
 		return -EIO;
 
diff --git a/client/transfer.c b/client/transfer.c
index 259d3aa..999b08b 100644
--- a/client/transfer.c
+++ b/client/transfer.c
@@ -220,7 +220,6 @@ static void obc_transfer_free(struct obc_transfer *transfer)
 }
 
 struct obc_transfer *obc_transfer_register(DBusConnection *conn,
-						GObex *obex,
 						const char *agent,
 						guint8 op,
 						const char *filename,
@@ -231,7 +230,6 @@ struct obc_transfer *obc_transfer_register(DBusConnection *conn,
 	struct obc_transfer *transfer;
 
 	transfer = g_new0(struct obc_transfer, 1);
-	transfer->obex = g_obex_ref(obex);
 	transfer->op = op;
 	transfer->agent = g_strdup(agent);
 	transfer->filename = g_strdup(filename);
@@ -525,6 +523,8 @@ static gboolean transfer_start_put(struct obc_transfer *transfer, GError **err)
 gboolean obc_transfer_start(struct obc_transfer *transfer, GObex *obex,
 								GError **err)
 {
+	transfer->obex = g_obex_ref(obex);
+
 	switch (transfer->op) {
 	case G_OBEX_OP_GET:
 		return transfer_start_get(transfer, err);
diff --git a/client/transfer.h b/client/transfer.h
index 7858423..b044ce1 100644
--- a/client/transfer.h
+++ b/client/transfer.h
@@ -33,7 +33,6 @@ typedef void (*transfer_callback_t) (struct obc_transfer *transfer,
 					void *user_data);
 
 struct obc_transfer *obc_transfer_register(DBusConnection *conn,
-					GObex *obex,
 					const char *agent,
 					guint8 op,
 					const char *filename,
@@ -47,7 +46,8 @@ gboolean obc_transfer_set_callback(struct obc_transfer *transfer,
 					transfer_callback_t func,
 					void *user_data);
 
-gboolean obc_transfer_start(struct obc_transfer *transfer, GError **err);
+gboolean obc_transfer_start(struct obc_transfer *transfer, GObex *obex,
+								GError **err);
 guint8 obc_transfer_get_operation(struct obc_transfer *transfer);
 
 int obc_transfer_get_params(struct obc_transfer *transfer,
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH obexd 5/6 v3] client: open file during transfer creation
  2012-04-24  9:20 [PATCH obexd 1/6 v3] client: Remove buffer based transfer Luiz Augusto von Dentz
                   ` (2 preceding siblings ...)
  2012-04-24  9:20 ` [PATCH obexd 4/6 v3] client: transfers take gobex when starting Luiz Augusto von Dentz
@ 2012-04-24  9:20 ` Luiz Augusto von Dentz
  2012-04-24  9:20 ` [PATCH obexd 6/6 v3] client: Remove file in case of error Luiz Augusto von Dentz
  4 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2012-04-24  9:20 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This simplify the API a bit by not having to call obc_transfer_set_file
to open the file.

In addition to that split transfer creation/registration function so
GET/PUT can have more specific logic and different paramenters.
---
 client/session.c  |   50 +++++++-------
 client/transfer.c |  208 ++++++++++++++++++++++++++++++++---------------------
 client/transfer.h |   15 +++--
 3 files changed, 162 insertions(+), 111 deletions(-)

diff --git a/client/session.c b/client/session.c
index 306e2ba..7515ff0 100644
--- a/client/session.c
+++ b/client/session.c
@@ -661,6 +661,7 @@ static void session_request_reply(DBusPendingCall *call, gpointer user_data)
 	DBusMessage *reply = dbus_pending_call_steal_reply(call);
 	const char *name;
 	DBusError derr;
+	int err;
 
 	dbus_error_init(&derr);
 	if (dbus_set_error_from_message(&derr, reply)) {
@@ -685,13 +686,26 @@ static void session_request_reply(DBusPendingCall *call, gpointer user_data)
 
 	DBG("Agent.Request() reply: %s", name);
 
-	if (strlen(name)) {
-		if (obc_transfer_get_operation(transfer) == G_OBEX_OP_PUT)
-			obc_transfer_set_name(transfer, name);
-		else
-			obc_transfer_set_filename(transfer, name);
+	if (strlen(name) == 0)
+		goto done;
+
+	if (obc_transfer_get_operation(transfer) == G_OBEX_OP_PUT) {
+		obc_transfer_set_name(transfer, name);
+		goto done;
+	}
+
+	err = obc_transfer_set_filename(transfer, name);
+	if (err < 0) {
+		GError *gerr = NULL;
+
+		g_set_error(&gerr, OBEX_IO_ERROR, err,
+						"Unable to set filename");
+		session_terminate_transfer(session, transfer, gerr);
+		g_clear_error(&gerr);
+		return;
 	}
 
+done:
 	if (p->auth_complete)
 		p->auth_complete(session, transfer);
 
@@ -956,8 +970,8 @@ int obc_session_get(struct obc_session *session, const char *type,
 	else
 		agent = NULL;
 
-	transfer = obc_transfer_register(session->conn, agent, G_OBEX_OP_GET,
-					targetfile, name, type, params);
+	transfer = obc_transfer_get(session->conn, agent, targetfile, name,
+								type, params);
 	if (transfer == NULL) {
 		if (params != NULL) {
 			g_free(params->data);
@@ -974,24 +988,17 @@ int obc_session_send(struct obc_session *session, const char *filename,
 {
 	struct obc_transfer *transfer;
 	const char *agent;
-	int err;
 
 	if (session->obex == NULL)
 		return -ENOTCONN;
 
 	agent = obc_agent_get_name(session->agent);
 
-	transfer = obc_transfer_register(session->conn, agent, G_OBEX_OP_PUT,
-						filename, name, NULL, NULL);
+	transfer = obc_transfer_put(session->conn, agent, filename, name,
+					NULL, NULL, 0, NULL);
 	if (transfer == NULL)
 		return -EINVAL;
 
-	err = obc_transfer_set_file(transfer, NULL, 0);
-	if (err < 0) {
-		obc_transfer_unregister(transfer);
-		return err;
-	}
-
 	return session_request(session, transfer, NULL, NULL);
 }
 
@@ -1038,24 +1045,17 @@ int obc_session_put(struct obc_session *session, const char *contents,
 {
 	struct obc_transfer *transfer;
 	const char *agent;
-	int err;
 
 	if (session->obex == NULL)
 		return -ENOTCONN;
 
 	agent = obc_agent_get_name(session->agent);
 
-	transfer = obc_transfer_register(session->conn, agent, G_OBEX_OP_PUT,
-						NULL, name, NULL, NULL);
+	transfer = obc_transfer_put(session->conn, agent, NULL, name, NULL,
+							contents, size, NULL);
 	if (transfer == NULL)
 		return -EIO;
 
-	err = obc_transfer_set_file(transfer, contents, size);
-	if (err < 0) {
-		obc_transfer_unregister(transfer);
-		return err;
-	}
-
 	return session_request(session, transfer, NULL, NULL);
 }
 
diff --git a/client/transfer.c b/client/transfer.c
index 999b08b..5fcc35d 100644
--- a/client/transfer.c
+++ b/client/transfer.c
@@ -219,7 +219,7 @@ static void obc_transfer_free(struct obc_transfer *transfer)
 	g_free(transfer);
 }
 
-struct obc_transfer *obc_transfer_register(DBusConnection *conn,
+static struct obc_transfer *obc_transfer_register(DBusConnection *conn,
 						const char *agent,
 						guint8 op,
 						const char *filename,
@@ -247,23 +247,131 @@ struct obc_transfer *obc_transfer_register(DBusConnection *conn,
 			TRANSFER_BASEPATH, counter++);
 
 	transfer->conn = dbus_bus_get(DBUS_BUS_SESSION, NULL);
-	if (transfer->conn == NULL) {
-		obc_transfer_free(transfer);
-		return NULL;
-	}
+	if (transfer->conn == NULL)
+		goto fail;
 
 	if (g_dbus_register_interface(transfer->conn, transfer->path,
 				TRANSFER_INTERFACE,
 				obc_transfer_methods, NULL, NULL,
-				transfer, NULL) == FALSE) {
+				transfer, NULL) == FALSE)
+		goto fail;
+
+done:
+	DBG("%p registered %s", transfer, transfer->path);
+
+	return transfer;
+
+fail:
+	obc_transfer_free(transfer);
+
+	return NULL;
+}
+
+static int transfer_open(struct obc_transfer *transfer, int flags, mode_t mode)
+{
+	GError *err = NULL;
+	int fd;
+
+	if (transfer->filename != NULL) {
+		fd = open(transfer->filename, flags, mode);
+		if (fd < 0) {
+			error("open(): %s(%d)", strerror(errno), errno);
+			return -errno;
+		}
+		goto done;
+	}
+
+	fd = g_file_open_tmp("obex-clientXXXXXX", &transfer->filename, &err);
+	if (fd < 0) {
+		error("g_file_open_tmp(): %s", err->message);
+		g_error_free(err);
+		return -EFAULT;
+	}
+
+	remove(transfer->filename);
+
+done:
+	transfer->fd = fd;
+	return fd;
+}
+
+struct obc_transfer *obc_transfer_get(DBusConnection *conn,
+					const char *agent,
+					const char *filename,
+					const char *name,
+					const char *type,
+					struct obc_transfer_params *params)
+{
+	struct obc_transfer *transfer;
+
+	transfer = obc_transfer_register(conn, agent, G_OBEX_OP_GET, filename,
+							name, type, params);
+	if (transfer == NULL)
+		return NULL;
+
+	if (transfer_open(transfer, O_WRONLY | O_CREAT | O_TRUNC, 0600) < 0) {
 		obc_transfer_free(transfer);
 		return NULL;
 	}
 
-done:
-	DBG("%p registered %s", transfer, transfer->path);
+	return transfer;
+}
+
+struct obc_transfer *obc_transfer_put(DBusConnection *conn,
+					const char *agent,
+					const char *filename,
+					const char *name,
+					const char *type,
+					const char *contents,
+					size_t size,
+					struct obc_transfer_params *params)
+{
+	struct obc_transfer *transfer;
+	struct stat st;
+	int perr;
+
+	transfer = obc_transfer_register(conn, agent, G_OBEX_OP_PUT, filename,
+							name, type, params);
+	if (transfer == NULL)
+		return NULL;
+
+	if (contents != NULL) {
+		ssize_t w;
+
+		perr = transfer_open(transfer, O_RDWR, 0);
+		if (perr < 0)
+			goto fail;
+
+		w = write(transfer->fd, contents, size);
+		if (w < 0) {
+			error("write(): %s(%d)", strerror(errno), errno);
+			perr = -errno;
+			goto fail;
+		} else if ((size_t) w != size) {
+			error("Unable to write all contents to file");
+			perr = -EFAULT;
+			goto fail;
+		}
+	} else {
+		perr = transfer_open(transfer, O_RDONLY, 0);
+		if (perr < 0)
+			goto fail;
+	}
+
+	perr = fstat(transfer->fd, &st);
+	if (perr < 0) {
+		error("fstat(): %s(%d)", strerror(errno), errno);
+		perr = -errno;
+		goto fail;
+	}
+
+	transfer->size = st.st_size;
 
 	return transfer;
+
+fail:
+	obc_transfer_free(transfer);
+	return NULL;
 }
 
 void obc_transfer_unregister(struct obc_transfer *transfer)
@@ -416,38 +524,9 @@ gboolean obc_transfer_set_callback(struct obc_transfer *transfer,
 	return TRUE;
 }
 
-static int transfer_open(struct obc_transfer *transfer, int flags, mode_t mode)
-{
-	GError *err = NULL;
-	int fd;
-
-	if (transfer->filename != NULL) {
-		fd = open(transfer->filename, flags, mode);
-		if (fd < 0) {
-			error("open(): %s(%d)", strerror(errno), errno);
-			return -errno;
-		}
-		goto done;
-	}
-
-	fd = g_file_open_tmp("obex-clientXXXXXX", &transfer->filename, &err);
-	if (fd < 0) {
-		error("g_file_open_tmp(): %s", err->message);
-		g_error_free(err);
-		return -EFAULT;
-	}
-
-	remove(transfer->filename);
-
-done:
-	transfer->fd = fd;
-	return fd;
-}
-
 static gboolean transfer_start_get(struct obc_transfer *transfer, GError **err)
 {
 	GObexPacket *req;
-	int perr;
 
 	if (transfer->xfer > 0) {
 		g_set_error(err, OBC_TRANSFER_ERROR, -EALREADY,
@@ -455,10 +534,6 @@ static gboolean transfer_start_get(struct obc_transfer *transfer, GError **err)
 		return FALSE;
 	}
 
-	perr = transfer_open(transfer, O_WRONLY | O_CREAT, 0600);
-	if (perr < 0)
-		return perr;
-
 	req = g_obex_packet_new(G_OBEX_OP_GET, TRUE, G_OBEX_HDR_INVALID);
 
 	if (transfer->name != NULL)
@@ -592,11 +667,21 @@ void obc_transfer_set_name(struct obc_transfer *transfer, const char *name)
 	transfer->name = g_strdup(name);
 }
 
-void obc_transfer_set_filename(struct obc_transfer *transfer,
+int obc_transfer_set_filename(struct obc_transfer *transfer,
 					const char *filename)
 {
+	int err;
+
+	err = rename(transfer->filename, filename);
+	if (err < 0) {
+		error("rename(): %s (%d)", strerror(errno), errno);
+		return -errno;
+	}
+
 	g_free(transfer->filename);
 	transfer->filename = g_strdup(filename);
+
+	return 0;
 }
 
 const char *obc_transfer_get_path(struct obc_transfer *transfer)
@@ -608,42 +693,3 @@ gint64 obc_transfer_get_size(struct obc_transfer *transfer)
 {
 	return transfer->size;
 }
-
-int obc_transfer_set_file(struct obc_transfer *transfer, const char *contents,
-								size_t size)
-{
-	int err;
-	struct stat st;
-
-	err = transfer_open(transfer, O_RDONLY, 0);
-	if (err < 0)
-		return err;
-
-	if (contents != NULL) {
-		ssize_t w = write(transfer->fd, contents, size);
-		if (w < 0) {
-			error("write(): %s(%d)", strerror(errno), errno);
-			err = -errno;
-			goto fail;
-		} else if ((size_t) w != size) {
-			error("Unable to write all contents to file");
-			err = -EFAULT;
-			goto fail;
-		}
-	}
-
-	err = fstat(transfer->fd, &st);
-	if (err < 0) {
-		error("fstat(): %s(%d)", strerror(errno), errno);
-		err = -errno;
-		goto fail;
-	}
-
-	transfer->size = st.st_size;
-
-	return 0;
-fail:
-	close(transfer->fd);
-	transfer->fd = -1;
-	return err;
-}
diff --git a/client/transfer.h b/client/transfer.h
index b044ce1..a84e415 100644
--- a/client/transfer.h
+++ b/client/transfer.h
@@ -32,13 +32,20 @@ typedef void (*transfer_callback_t) (struct obc_transfer *transfer,
 					gint64 transferred, GError *err,
 					void *user_data);
 
-struct obc_transfer *obc_transfer_register(DBusConnection *conn,
+struct obc_transfer *obc_transfer_get(DBusConnection *conn,
 					const char *agent,
-					guint8 op,
 					const char *filename,
 					const char *name,
 					const char *type,
 					struct obc_transfer_params *params);
+struct obc_transfer *obc_transfer_put(DBusConnection *conn,
+					const char *agent,
+					const char *filename,
+					const char *name,
+					const char *type,
+					const char *contents,
+					size_t size,
+					struct obc_transfer_params *params);
 
 void obc_transfer_unregister(struct obc_transfer *transfer);
 
@@ -56,9 +63,7 @@ int obc_transfer_get_contents(struct obc_transfer *transfer, char **contents,
 								size_t *size);
 
 void obc_transfer_set_name(struct obc_transfer *transfer, const char *name);
-void obc_transfer_set_filename(struct obc_transfer *transfer,
+int obc_transfer_set_filename(struct obc_transfer *transfer,
 					const char *filename);
 const char *obc_transfer_get_path(struct obc_transfer *transfer);
 gint64 obc_transfer_get_size(struct obc_transfer *transfer);
-int obc_transfer_set_file(struct obc_transfer *transfer, const char *contents,
-								size_t size);
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH obexd 6/6 v3] client: Remove file in case of error
  2012-04-24  9:20 [PATCH obexd 1/6 v3] client: Remove buffer based transfer Luiz Augusto von Dentz
                   ` (3 preceding siblings ...)
  2012-04-24  9:20 ` [PATCH obexd 5/6 v3] client: open file during transfer creation Luiz Augusto von Dentz
@ 2012-04-24  9:20 ` Luiz Augusto von Dentz
  4 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2012-04-24  9:20 UTC (permalink / raw)
  To: linux-bluetooth

From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

If the transfer operation is GET and it has not complete by the time its
freed remove the file as its contents maybe corrupted/incomplete.
---
 client/transfer.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

diff --git a/client/transfer.c b/client/transfer.c
index 5fcc35d..230f3ae 100644
--- a/client/transfer.c
+++ b/client/transfer.c
@@ -196,6 +196,10 @@ static void obc_transfer_free(struct obc_transfer *transfer)
 	if (transfer->xfer)
 		g_obex_cancel_transfer(transfer->xfer);
 
+	if (transfer->op == G_OBEX_OP_GET &&
+					transfer->transferred != transfer->size)
+		remove(transfer->filename);
+
 	if (transfer->fd > 0)
 		close(transfer->fd);
 
-- 
1.7.7.6


^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2012-04-24  9:20 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-04-24  9:20 [PATCH obexd 1/6 v3] client: Remove buffer based transfer Luiz Augusto von Dentz
2012-04-24  9:20 ` [PATCH obexd 2/6 v3] client: remove unused field Luiz Augusto von Dentz
2012-04-24  9:20 ` [PATCH obexd 3/6 v3] client: transfer api merges put and get Luiz Augusto von Dentz
2012-04-24  9:20 ` [PATCH obexd 4/6 v3] client: transfers take gobex when starting Luiz Augusto von Dentz
2012-04-24  9:20 ` [PATCH obexd 5/6 v3] client: open file during transfer creation Luiz Augusto von Dentz
2012-04-24  9:20 ` [PATCH obexd 6/6 v3] client: Remove file in case of error Luiz Augusto von Dentz

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.