This email list is read-only. Emails sent to this list will be discarded
----------------------------------
client/main.c | 6 +-
client/session.c | 326 +++++++++++++++++++++++++++++++++++++++++-----------
client/session.h | 8 +-
doc/client-api.txt | 7 +-
gwobex/obex-priv.c | 2 +-
5 files changed, 273 insertions(+), 76 deletions(-)
New commits:
commit fb3586f04163444e71f75d9a843793de49b15e9d
Author: Johan Hedberg <[EMAIL PROTECTED]>
Date: Fri Oct 31 08:45:35 2008 +0200
Improve the dc_cb/xfer callback workaround
It's in anycase not safe to call these two callbacks at the same time here,
but
in case some code does use the dc_cb for calling gw_obex_close (which is
quite
a rational thing to do in this case) give it a chance to work.
commit 69af00a3b4be37a4ca9f6cffd3fc9d26eac14bb9
Author: Vinicius Costa Gomes <[EMAIL PROTECTED]>
Date: Thu Oct 30 19:01:33 2008 -0300
Removes a memory leak
commit 5a8c40db8a2f42272a8a0269042784eb79b9e713
Author: Vinicius Costa Gomes <[EMAIL PROTECTED]>
Date: Thu Oct 30 17:11:08 2008 -0300
Stores the transfer object path in session_data too
commit 7dbf3689490a181ca61af409d5a0ff1cc76dc692
Merge: 4e8bdccf6cdbfe3d2e71f84e073d110a781fe8cc
aeaad6db3a940a46e4cfc75d52f6d8466509e686
Author: Marcel Holtmann <[EMAIL PROTECTED]>
Date: Fri Oct 31 00:36:21 2008 +0100
Merge branch 'devel' of git://git.infradead.org/users/cktakahasi/obexd
commit 4e8bdccf6cdbfe3d2e71f84e073d110a781fe8cc
Author: Johan Hedberg <[EMAIL PROTECTED]>
Date: Fri Oct 31 00:05:24 2008 +0200
Change xfer callback and dc_cb order in the event of a disconnection
This is mainly working around a bug in the gwobex API. Since it doesn't have
proper refcounting the xfer callback can free the gwobex ctx and so the
second
callback fails. It could of course happen in the other direction too (dc_cb
calls gw_obex_close) but since no known code is using dc_cb it's at least a
little safer this way.
commit aeaad6db3a940a46e4cfc75d52f6d8466509e686
Author: Claudio Takahasi <[EMAIL PROTECTED]>
Date: Thu Oct 30 18:19:06 2008 -0300
Return an array of dictionary for ListFolder
commit 9609bfce78af37ab36ebb13387cb81c4f46038f2
Author: Claudio Takahasi <[EMAIL PROTECTED]>
Date: Wed Oct 29 10:45:54 2008 -0300
Added ListFolder method skeleton
commit 3ec6df0774857b6b4dc9ec970367431e825198de
Author: Claudio Takahasi <[EMAIL PROTECTED]>
Date: Tue Oct 28 16:14:50 2008 -0300
Removed folder parameter from ListFolder method
commit 9d2f21e9a8ef81adc8a291a41677c7f89e4b0a48
Author: Vinicius Costa Gomes <[EMAIL PROTECTED]>
Date: Wed Oct 29 11:54:17 2008 -0300
Removes the agent watch if the agent is released
commit 040e85e23fe70612deb300f82b33e4abfdd7a004
Author: Vinicius Costa Gomes <[EMAIL PROTECTED]>
Date: Wed Oct 29 11:51:48 2008 -0300
Do not register the transfer interface if it was already registered
commit 1ffa8da5efc31bae16d8260be3dd25c3586c874b
Author: Vinicius Costa Gomes <[EMAIL PROTECTED]>
Date: Wed Oct 29 11:11:27 2008 -0300
Only try to send messages to the agent if there's one registered
commit fc73d2abe5b85145774d4ef8e94228866863137a
Author: Vinicius Costa Gomes <[EMAIL PROTECTED]>
Date: Wed Oct 29 10:36:45 2008 -0300
Removes the disconnect watch when the session is freed
commit 4329b1bee58626cc30bd1ab9f2c08faaf9510eca
Author: Vinicius Costa Gomes <[EMAIL PROTECTED]>
Date: Wed Oct 29 10:32:16 2008 -0300
Implements FTP PutFile
commit 05cd48181ed1e255e8eb9727172c5ce3f38f11e9
Author: Vinicius Costa Gomes <[EMAIL PROTECTED]>
Date: Tue Oct 28 19:43:24 2008 -0300
Support changing the filename that will be sent in the OBEX header
Diff in this email is a maximum of 400 lines.
diff --git a/client/main.c b/client/main.c
index ce55227..e20eafc 100644
--- a/client/main.c
+++ b/client/main.c
@@ -73,8 +73,10 @@ static void create_callback(struct session_data *session,
void *user_data)
session_set_agent(session, data->sender, data->agent);
for (i = 0; i < data->files->len; i++) {
- if (session_send(session,
- g_ptr_array_index(data->files, i)) < 0)
+ const gchar *filename = g_ptr_array_index(data->files, i);
+
+ if (session_send(session, filename,
+ g_path_get_basename(filename)) < 0)
break;
}
diff --git a/client/session.c b/client/session.c
index 47902fc..b7a059d 100644
--- a/client/session.c
+++ b/client/session.c
@@ -72,6 +72,9 @@ static void session_unref(struct session_data *session)
if (g_atomic_int_dec_and_test(&session->refcount) == FALSE)
return;
+ if (session->agent_watch)
+ g_dbus_remove_watch(session->conn, session->agent_watch);
+
if (session->agent_name != NULL) {
DBusMessage *message;
@@ -99,14 +102,15 @@ static void session_unref(struct session_data *session)
close(session->sock);
if (session->conn) {
- if (session->path)
+ if (session->transfer_path)
g_dbus_unregister_interface(session->conn,
- session->path, TRANSFER_INTERFACE);
+ session->transfer_path,
TRANSFER_INTERFACE);
dbus_connection_unref(session->conn);
}
g_free(session->path);
+ g_free(session->transfer_path);
g_free(session->name);
g_free(session->filename);
g_free(session->agent_name);
@@ -423,7 +427,7 @@ static void abort_transfer(struct session_data *session)
session->agent_path, AGENT_INTERFACE, "Complete");
dbus_message_append_args(message,
- DBUS_TYPE_OBJECT_PATH, &session->path,
+ DBUS_TYPE_OBJECT_PATH, &session->transfer_path,
DBUS_TYPE_INVALID);
g_dbus_send_message(session->conn, message);
@@ -439,20 +443,23 @@ static void abort_transfer(struct session_data *session)
g_free(session->name);
session->name = NULL;
- if (session->path) {
+ if (session->transfer_path) {
g_dbus_unregister_interface(session->conn,
- session->path, TRANSFER_INTERFACE);
- g_free(session->path);
- session->path = NULL;
+ session->transfer_path, TRANSFER_INTERFACE);
+ g_free(session->transfer_path);
+ session->transfer_path = NULL;
}
if (session->pending->len > 0) {
gchar *filename;
+ gchar *basename;
filename = g_ptr_array_index(session->pending, 0);
g_ptr_array_remove(session->pending, filename);
- session_send(session, filename);
+ basename = g_path_get_basename(filename);
+ session_send(session, filename, basename);
g_free(filename);
+ g_free(basename);
}
session_unref(session);
@@ -598,7 +605,7 @@ static DBusMessage *assign_agent(DBusConnection *connection,
session->agent_name = g_strdup(sender);
session->agent_path = g_strdup(path);
- g_dbus_add_disconnect_watch(connection, sender,
+ session->agent_watch = g_dbus_add_disconnect_watch(connection, sender,
agent_disconnected, session, NULL);
return dbus_message_new_method_return(message);
@@ -632,6 +639,11 @@ static DBusMessage *release_agent(DBusConnection
*connection,
g_free(session->agent_path);
session->agent_path = NULL;
+ if (session->agent_watch) {
+ g_dbus_remove_watch(session->conn, session->agent_watch);
+ session->agent_watch = 0;
+ }
+
return dbus_message_new_method_return(message);
}
@@ -642,6 +654,146 @@ static GDBusMethodTable session_methods[] = {
{ }
};
+static void append_variant(DBusMessageIter *iter, int type, void *val)
+{
+ DBusMessageIter value;
+ char sig[2] = { type, '\0' };
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, sig, &value);
+
+ dbus_message_iter_append_basic(&value, type, val);
+
+ dbus_message_iter_close_container(iter, &value);
+}
+
+static void dict_append_entry(DBusMessageIter *dict,
+ const char *key, int type, void *val)
+{
+ DBusMessageIter entry;
+
+ if (type == DBUS_TYPE_STRING) {
+ const char *str = *((const char **) val);
+ if (str == NULL)
+ return;
+ }
+
+ dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
+ NULL, &entry);
+
+ dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+
+ append_variant(&entry, type, val);
+
+ dbus_message_iter_close_container(dict, &entry);
+}
+
+static void xml_element(GMarkupParseContext *ctxt,
+ const gchar *element,
+ const gchar **names,
+ const gchar **values,
+ gpointer user_data,
+ GError **gerr)
+{
+ DBusMessageIter dict, *iter = user_data;
+ gchar *key;
+ gint i, dtype = DBUS_TYPE_STRING;
+
+ if (strcasecmp("folder", element) != 0 && strcasecmp("file", element)
!= 0)
+ return;
+
+ dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY,
+ DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+ DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
+ DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+
+ dict_append_entry(&dict, "Type", DBUS_TYPE_STRING, &element);
+
+ /* FIXME: User, Group, Other permission must be reviewed */
+
+ i = 0;
+ for (key = (gchar *) names[i]; key; key = (gchar *) names[++i]) {
+ key[0] = g_ascii_toupper(key[0]);
+ if (strcmp("Accessed", key) == 0 ||
+ strcmp("Created", key) == 0 ||
+ strcmp("Modified", key)== 0 ||
+ strcmp("Size", key)== 0)
+ dtype = DBUS_TYPE_UINT64;
+
+ dict_append_entry(&dict, key, dtype, &values[i]);
+ }
+
+ dbus_message_iter_close_container(iter, &dict);
+}
+
+static const GMarkupParser parser = {
+ xml_element,
+ NULL,
+ NULL,
+ NULL,
+ NULL
+};
+
+static void list_folder_callback(struct session_data *session,
+ void *user_data)
+{
+ GMarkupParseContext *ctxt;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+
+ reply = dbus_message_new_method_return(session->msg);
+
+ if (session->filled == 0)
+ goto done;
+
+ dbus_message_iter_init_append(reply, &iter);
+
+ ctxt = g_markup_parse_context_new(&parser, 0, &iter, NULL);
+ g_markup_parse_context_parse(ctxt, session->buffer,
+ session->filled, NULL);
+ g_markup_parse_context_free(ctxt);
+
+ session->filled = 0;
+
+done:
+ g_dbus_send_message(session->conn, reply);
+ dbus_message_unref(session->msg);
+ session->msg = NULL;
+}
+
+static void get_xfer_progress(GwObexXfer *xfer, gpointer user_data)
+{
+ struct callback_data *callback = user_data;
+ struct session_data *session = callback->session;
+ gint bsize, bread;
+ gboolean ret;
+
+ /* FIXME: Check buffer overflow */
+ bsize = sizeof(session->buffer) - session->filled;
+ ret = gw_obex_xfer_read(xfer, session->buffer + session->filled,
+ bsize, &bread, NULL);
+ session->filled += bread;
+ if (ret == FALSE)
+ goto complete;
+
+ if (bread == 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);
+}
+
static DBusMessage *change_folder(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
@@ -673,7 +825,48 @@ static DBusMessage *create_folder(DBusConnection
*connection,
static DBusMessage *list_folder(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
- return dbus_message_new_method_return(message);
+ struct session_data *session = user_data;
+ struct callback_data *callback;
+ GwObexXfer *xfer;
+ int err;
+
+ if (session->msg)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InProgress",
+ "Transfer in progress");
+
+ if (session->obex == NULL)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.Failed",
+ "Not connected");
+
+ session_ref(session);
+ xfer = gw_obex_get_async(session->obex,
+ NULL, "x-obex/folder-listing", &err);
+ if (xfer == NULL) {
+ session_unref(session);
+ return g_dbus_create_error(message,
+ "org.openobex.Error.Failed",
+ OBEX_ResponseToString(err));
+ }
+
+ callback = g_try_malloc0(sizeof(*callback));
+ if (callback == NULL) {
+ session_unref(session);
+ gw_obex_xfer_free(xfer);
+ return NULL;
+ }
+
+ session->msg = dbus_message_ref(message);
+ session->filled = 0;
+ callback->session = session;
+ callback->func = list_folder_callback;
+
+ gw_obex_xfer_set_callback(xfer, get_xfer_progress, callback);
+
+ session->xfer = xfer;
+
+ return NULL;
}
static DBusMessage *get_file(DBusConnection *connection,
@@ -685,6 +878,22 @@ static DBusMessage *get_file(DBusConnection *connection,
static DBusMessage *put_file(DBusConnection *connection,
DBusMessage *message, void *user_data)
{
+ struct session_data *session = user_data;
+ gchar *sourcefile, *targetfile;
+
+ if (dbus_message_get_args(message, NULL,
+ DBUS_TYPE_STRING, &sourcefile,
+ DBUS_TYPE_STRING, &targetfile,
+ DBUS_TYPE_INVALID) == FALSE)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.InvalidArguments",
+ "Invalid arguments in method call");
+
+ if (session_send(session, sourcefile, targetfile) < 0)
+ return g_dbus_create_error(message,
+ "org.openobex.Error.Failed",
+ "Failed");
+
return dbus_message_new_method_return(message);
}
@@ -709,7 +918,8 @@ static DBusMessage *delete(DBusConnection *connection,
static GDBusMethodTable ftp_methods[] = {
{ "ChangeFolder", "s", "", change_folder },
{ "CreateFolder", "s", "", create_folder },
- { "ListFolder", "s", "aa{sv}", list_folder },
+ { "ListFolder", "", "aa{sv}", list_folder,
+ G_DBUS_METHOD_FLAG_ASYNC },
{ "GetFile", "ss", "", get_file },
{ "PutFile", "ss", "", put_file },
{ "CopyFile", "ss", "", copy_file },
@@ -734,7 +944,8 @@ static void put_xfer_progress(GwObexXfer *xfer, gpointer
user_data)
&written, NULL) == FALSE)
goto complete;
- gw_obex_xfer_flush(xfer, NULL);
+ if (gw_obex_xfer_flush(xfer, NULL) == FALSE)
+ goto complete;
session->filled = (session->filled + len) - written;
@@ -742,12 +953,15 @@ static void put_xfer_progress(GwObexXfer *xfer, gpointer
user_data)
session->transferred += written;
+ if (session->agent_name == NULL || session->agent_path == NULL)
+ return;
+
message = dbus_message_new_method_call(session->agent_name,
session->agent_path, AGENT_INTERFACE, "Progress");
dbus_message_set_no_reply(message, TRUE);
- dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH, &session->path,
+ dbus_message_append_args(message, DBUS_TYPE_OBJECT_PATH,
&session->transfer_path,
DBUS_TYPE_UINT64, &session->transferred,
DBUS_TYPE_INVALID);
@@ -756,14 +970,16 @@ static void put_xfer_progress(GwObexXfer *xfer, gpointer
user_data)
return;
complete:
- message = dbus_message_new_method_call(session->agent_name,
+ if (session->agent_path && session->agent_name) {
+ message = dbus_message_new_method_call(session->agent_name,
session->agent_path, AGENT_INTERFACE, "Complete");
- dbus_message_append_args(message,
- DBUS_TYPE_OBJECT_PATH, &session->path,
+ dbus_message_append_args(message,
+ DBUS_TYPE_OBJECT_PATH, &session->transfer_path,
DBUS_TYPE_INVALID);
- g_dbus_send_message(session->conn, message);
+ g_dbus_send_message(session->conn, message);
+ }
if (session->pending->len > 0) {
gchar *filename;
@@ -780,21 +996,22 @@ complete:
g_free(session->name);
session->name = NULL;
- if (session->path) {
+ if (session->transfer_path) {
g_dbus_unregister_interface(session->conn,
- session->path, TRANSFER_INTERFACE);
- g_free(session->path);
- session->path = NULL;
+ session->transfer_path,
TRANSFER_INTERFACE);
+ g_free(session->transfer_path);
+ session->transfer_path = NULL;
}
_______________________________________________
Commits mailing list
[email protected]
https://lists.moblin.org/mailman/listinfo/commits