Diff between 5ce1a692e28682fad22538c2491ed34494cb3bc2 and bcc1b03424951f3b9aea03db7f9c541f11ec5aea

Changed Files

File Additions Deletions Status
obexd/client/main.c +83 -6 modified
obexd/client/session.c +63 -2 modified
obexd/client/session.h +3 -0 modified

Full Patch

diff --git a/obexd/client/main.c b/obexd/client/main.c
index 3cf8e78..021c3c6 100644
--- a/obexd/client/main.c
+++ b/obexd/client/main.c
@@ -70,7 +70,6 @@ static void create_callback(struct session_data *session, void *user_data)
 
 	g_dbus_send_reply(data->connection, data->message, DBUS_TYPE_INVALID);
 
-
 	session_set_agent(session, data->sender, data->agent);
 
 	for (i = 0; i < data->files->len; i++) {
@@ -186,8 +185,83 @@ static DBusMessage *send_files(DBusConnection *connection,
 	return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);
 }
 
+static void pull_complete_callback(struct session_data *session,
+							void *user_data)
+{
+	struct send_data *data = user_data;
+
+	g_dbus_send_reply(data->connection, data->message, DBUS_TYPE_INVALID);
+
+	dbus_message_unref(data->message);
+	dbus_connection_unref(data->connection);
+	g_free(data->sender);
+	g_free(data);
+}
+
+static void pull_session_callback(struct session_data *session,
+							void *user_data)
+{
+	struct send_data *data = user_data;
+
+	if (session->obex == NULL) {
+		DBusMessage *error = g_dbus_create_error(data->message,
+					"org.openobex.Error.Failed", NULL);
+		g_dbus_send_message(data->connection, error);
+		goto done;
+	}
+
+	g_dbus_send_reply(data->connection, data->message, DBUS_TYPE_INVALID);
+
+	session_pull(session, "text/x-vcard", "/tmp/x.vcf",
+						pull_complete_callback, data);
+
+	return;
+
+done:
+	dbus_message_unref(data->message);
+	dbus_connection_unref(data->connection);
+	g_free(data->sender);
+	g_free(data);
+}
+
+static DBusMessage *pull_business_card(DBusConnection *connection,
+					DBusMessage *message, void *user_data)
+{
+	DBusMessageIter iter, dict;
+	struct send_data *data;
+	const char *source = NULL, *dest = NULL, *target = NULL;
+
+	dbus_message_iter_init(message, &iter);
+	dbus_message_iter_recurse(&iter, &dict);
+
+	parse_device_dict(&dict, &source, &dest, &target);
+	if (dest == NULL)
+		return g_dbus_create_error(message,
+				"org.openobex.Error.InvalidArguments", NULL);
+
+	data = g_try_malloc0(sizeof(*data));
+	if (data == NULL)
+		return g_dbus_create_error(message,
+					"org.openobex.Error.NoMemory", NULL);
+
+	data->connection = dbus_connection_ref(connection);
+	data->message = dbus_message_ref(message);
+	data->sender = g_strdup(dbus_message_get_sender(message));
+
+	if (session_create(source, dest, NULL,
+					pull_session_callback, data) == 0)
+		return NULL;
+
+	dbus_message_unref(data->message);
+	dbus_connection_unref(data->connection);
+	g_free(data->sender);
+	g_free(data);
+
+	return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);
+}
+
 static DBusMessage *create_session(DBusConnection *connection,
-				DBusMessage *message, void *user_data)
+					DBusMessage *message, void *user_data)
 {
 	DBusMessageIter iter, dict;
 	struct send_data *data;
@@ -218,13 +292,16 @@ static DBusMessage *create_session(DBusConnection *connection,
 	g_free(data->sender);
 	g_free(data);
 
-	return g_dbus_create_error(message,
-			"org.openobex.Error.Failed", NULL);
+	return g_dbus_create_error(message, "org.openobex.Error.Failed", NULL);
 }
 
 static GDBusMethodTable client_methods[] = {
-	{ "SendFiles", "a{sv}aso", "", send_files, G_DBUS_METHOD_FLAG_ASYNC },
-	{ "CreateSession", "a{sv}", "", create_session, G_DBUS_METHOD_FLAG_ASYNC },
+	{ "SendFiles",        "a{sv}aso", "", send_files,
+						G_DBUS_METHOD_FLAG_ASYNC },
+	{ "PullBusinessCard", "a{sv}s",   "", pull_business_card,
+						G_DBUS_METHOD_FLAG_ASYNC },
+	{ "CreateSession",    "a{sv}",    "", create_session,
+						G_DBUS_METHOD_FLAG_ASYNC },
 	{ }
 };
 
diff --git a/obexd/client/session.c b/obexd/client/session.c
index e73ab25..e39f5b1 100644
--- a/obexd/client/session.c
+++ b/obexd/client/session.c
@@ -640,7 +640,7 @@ static GDBusMethodTable ftp_methods[] = {
 	{ }
 };
 
-static void xfer_progress(GwObexXfer *xfer, gpointer user_data)
+static void put_xfer_progress(GwObexXfer *xfer, gpointer user_data)
 {
 	struct session_data *session = user_data;
 	DBusMessage *message;
@@ -782,7 +782,68 @@ int session_send(struct session_data *session, const char *filename)
 
 	g_dbus_send_message(session->conn, message);
 
-	gw_obex_xfer_set_callback(xfer, xfer_progress, session);
+	gw_obex_xfer_set_callback(xfer, put_xfer_progress, session);
+
+	session->xfer = xfer;
+
+	return 0;
+}
+
+static void get_xfer_progress(GwObexXfer *xfer, gpointer user_data)
+{
+	struct callback_data *callback = user_data;
+	char buf[1024];
+	gint len;
+
+	if (gw_obex_xfer_read(xfer, buf, sizeof(buf), &len, NULL) == FALSE)
+		goto complete;
+
+	if (len == gw_obex_xfer_object_size(xfer))
+		goto complete;
+
+	gw_obex_xfer_flush(xfer, NULL);
+
+	return;
+
+complete:
+	gw_obex_xfer_close(xfer, NULL);
+	gw_obex_xfer_free(xfer);
+	callback->session->xfer = NULL;
+
+	callback->func(callback->session, callback->data);
+
+	session_unref(callback->session);
+
+	g_free(callback);
+}
+
+int session_pull(struct session_data *session,
+				const char *type, const char *filename,
+				session_callback_t function, void *user_data)
+{
+	struct callback_data *callback;
+	GwObexXfer *xfer;
+
+	if (session->obex == NULL)
+		return -ENOTCONN;
+
+	session_ref(session);
+
+	callback = g_try_malloc0(sizeof(*callback));
+	if (callback == NULL) {
+		session_unref(session);
+		return -ENOMEM;
+	}
+
+	callback->session = session;
+	callback->func = function;
+	callback->data = user_data;
+
+	xfer = gw_obex_get_async(session->obex, NULL, type, NULL);
+	if (xfer == NULL)
+		return -ENOTCONN;
+
+	gw_obex_xfer_set_callback(xfer, get_xfer_progress, callback);
 
 	session->xfer = xfer;
 
diff --git a/obexd/client/session.h b/obexd/client/session.h
index e5f4889..aea62a2 100644
--- a/obexd/client/session.h
+++ b/obexd/client/session.h
@@ -60,4 +60,7 @@ int session_create(const char *source,
 int session_set_agent(struct session_data *session, const char *name,
 							const char *path);
 int session_send(struct session_data *session, const char *filename);
+int session_pull(struct session_data *session,
+				const char *type, const char *filename,
+				session_callback_t function, void *user_data);
 int session_register(struct session_data *session);