diff --git a/gvfs-obexftp-updated-apis.patch b/gvfs-obexftp-updated-apis.patch new file mode 100644 index 0000000..878b818 --- /dev/null +++ b/gvfs-obexftp-updated-apis.patch @@ -0,0 +1,289 @@ +Index: daemon/obexftp-marshal.list +=================================================================== +--- daemon/obexftp-marshal.list (revision 1964) ++++ daemon/obexftp-marshal.list (working copy) +@@ -1,2 +1,4 @@ ++VOID:STRING + VOID:STRING,STRING ++VOID:STRING,STRING,STRING + VOID:STRING,STRING,UINT64 +Index: daemon/gvfsbackendobexftp.c +=================================================================== +--- daemon/gvfsbackendobexftp.c (revision 1964) ++++ daemon/gvfsbackendobexftp.c (working copy) +@@ -96,6 +96,15 @@ + + G_DEFINE_TYPE (GVfsBackendObexftp, g_vfs_backend_obexftp, G_VFS_TYPE_BACKEND); + ++static void session_connect_error_cb (DBusGProxy *proxy, ++ const char *session_object, ++ const gchar *error_name, ++ const gchar *error_message, ++ gpointer user_data); ++static void session_connected_cb (DBusGProxy *proxy, ++ const char *session_object, ++ gpointer user_data); ++ + /* This should all live in bluez-gnome, and we + * should depend on it */ + enum { +@@ -207,66 +216,86 @@ + return g_str_has_prefix(bdaddr, "00:60:57"); + } + ++static char * ++get_name_and_class (DBusGProxy *device, guint32 *type) ++{ ++ GHashTable *hash; ++ ++ if (dbus_g_proxy_call (device, "GetProperties", NULL, ++ G_TYPE_INVALID, dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_VALUE), ++ &hash, G_TYPE_INVALID) != FALSE) ++ { ++ GValue *value; ++ char *name; ++ ++ value = g_hash_table_lookup (hash, "Name"); ++ name = value ? g_value_dup_string(value) : NULL; ++ ++ value = g_hash_table_lookup (hash, "Class"); ++ if (value) ++ { ++ *type = _get_type_from_class (g_value_get_uint (value)); ++ } ++ else ++ { ++ *type = BLUETOOTH_TYPE_ANY; ++ } ++ return name; ++ } ++ ++ return NULL; ++} ++ + static gchar * + _get_device_properties (const char *bdaddr, guint32 *type) + { + DBusGConnection *connection; + DBusGProxy *manager; +- gchar *name, **adapters; ++ GPtrArray *adapters; ++ gchar *name; + guint i; + + name = NULL; + + connection = dbus_g_bus_get (DBUS_BUS_SYSTEM, NULL); + if (connection == NULL) +- return NULL; ++ return name; + + manager = dbus_g_proxy_new_for_name (connection, "org.bluez", +- "/org/bluez", "org.bluez.Manager"); ++ "/", "org.bluez.Manager"); + if (manager == NULL) + { + dbus_g_connection_unref (connection); +- return NULL; ++ return name; + } + +- if (dbus_g_proxy_call (manager, "ListAdapters", NULL, G_TYPE_INVALID, G_TYPE_STRV, &adapters, G_TYPE_INVALID) == FALSE) ++ if (dbus_g_proxy_call (manager, "ListAdapters", NULL, G_TYPE_INVALID, dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &adapters, G_TYPE_INVALID) == FALSE) + { + g_object_unref (manager); + dbus_g_connection_unref (connection); +- return NULL; ++ return name; + } + +- for (i = 0; adapters[i] != NULL; i++) ++ for (i = 0; i < adapters->len && name == NULL; i++) + { + DBusGProxy *adapter; ++ char *device_path; + + adapter = dbus_g_proxy_new_for_name (connection, "org.bluez", +- adapters[i], "org.bluez.Adapter"); +- if (dbus_g_proxy_call (adapter, "GetRemoteName", NULL, ++ g_ptr_array_index (adapters, i), "org.bluez.Adapter"); ++ if (dbus_g_proxy_call (adapter, "FindDevice", NULL, + G_TYPE_STRING, bdaddr, G_TYPE_INVALID, +- G_TYPE_STRING, &name, G_TYPE_INVALID) != FALSE) ++ DBUS_TYPE_G_OBJECT_PATH, &device_path, G_TYPE_INVALID) != FALSE) + { +- if (name != NULL && name[0] != '\0') +- { +- guint32 class; +- +- if (dbus_g_proxy_call(adapter, "GetRemoteClass", NULL, +- G_TYPE_STRING, bdaddr, G_TYPE_INVALID, +- G_TYPE_UINT, &class, G_TYPE_INVALID) != FALSE) +- { +- *type = _get_type_from_class (class); +- } +- else +- { +- *type = BLUETOOTH_TYPE_ANY; +- } +- g_object_unref (adapter); +- break; +- } ++ DBusGProxy *device; ++ device = dbus_g_proxy_new_for_name (connection, "org.bluez", device_path, "org.bluez.Device"); ++ name = get_name_and_class (device, type); ++ g_object_unref (device); + } + g_object_unref (adapter); + } + ++ g_ptr_array_free (adapters, TRUE); + g_object_unref (manager); + dbus_g_connection_unref (connection); + +@@ -312,6 +341,15 @@ + "org.openobex", + "/org/openobex", + "org.openobex.Manager"); ++ ++ dbus_g_proxy_add_signal(backend->manager_proxy, "SessionConnectError", ++ DBUS_TYPE_G_OBJECT_PATH, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); ++ dbus_g_proxy_connect_signal(backend->manager_proxy, "SessionConnectError", ++ G_CALLBACK(session_connect_error_cb), backend, NULL); ++ dbus_g_proxy_add_signal(backend->manager_proxy, "SessionConnected", ++ DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); ++ dbus_g_proxy_connect_signal(backend->manager_proxy, "SessionConnected", ++ G_CALLBACK(session_connected_cb), backend, NULL); + } + + static gboolean +@@ -531,6 +569,37 @@ + } + + static void ++session_connect_error_cb (DBusGProxy *proxy, ++ const char *session_object, ++ const gchar *error_name, ++ const gchar *error_message, ++ gpointer user_data) ++{ ++ GVfsBackendObexftp *op_backend = G_VFS_BACKEND_OBEXFTP (user_data); ++ ++ g_mutex_lock (op_backend->mutex); ++ op_backend->status = ASYNC_ERROR; ++ op_backend->error = g_error_new_literal (DBUS_GERROR, ++ DBUS_GERROR_REMOTE_EXCEPTION, ++ error_message); ++ g_cond_signal (op_backend->cond); ++ g_mutex_unlock (op_backend->mutex); ++} ++ ++static void ++session_connected_cb (DBusGProxy *proxy, ++ const char *session_object, ++ gpointer user_data) ++{ ++ GVfsBackendObexftp *op_backend = G_VFS_BACKEND_OBEXFTP (user_data); ++ ++ g_mutex_lock (op_backend->mutex); ++ op_backend->status = ASYNC_SUCCESS; ++ g_cond_signal (op_backend->cond); ++ g_mutex_unlock (op_backend->mutex); ++} ++ ++static void + cancelled_cb (DBusGProxy *proxy, gpointer user_data) + { + GVfsBackendObexftp *op_backend = G_VFS_BACKEND_OBEXFTP (user_data); +@@ -559,24 +628,6 @@ + _exit (1); + } + +-static int +-is_connected (DBusGProxy *session_proxy, GVfsJob *job) +-{ +- GError *error = NULL; +- gboolean connected; +- +- if (dbus_g_proxy_call (session_proxy, "IsConnected", &error, +- G_TYPE_INVALID, +- G_TYPE_BOOLEAN, &connected, G_TYPE_INVALID) == FALSE) +- { +- g_vfs_job_failed_from_error (job, error); +- g_error_free (error); +- return -1; +- } +- +- return connected; +-} +- + static void + do_mount (GVfsBackend *backend, + GVfsJobMount *job, +@@ -590,7 +641,6 @@ + const gchar *path = NULL; + char *server; + GMountSpec *obexftp_mount_spec; +- gboolean connected; + + g_print ("+ do_mount\n"); + +@@ -616,10 +666,11 @@ + } + + /* FIXME, Have a way for the mount to be cancelled, see: +- * http://bugs.muiline.com/view.php?id=51 */ ++ * Use CancelSessionConnect */ ++ op_backend->status = ASYNC_PENDING; + + if (dbus_g_proxy_call (op_backend->manager_proxy, "CreateBluetoothSession", &error, +- G_TYPE_STRING, op_backend->bdaddr, G_TYPE_STRING, "ftp", G_TYPE_INVALID, ++ G_TYPE_STRING, op_backend->bdaddr, G_TYPE_STRING, "00:00:00:00:00:00", G_TYPE_STRING, "ftp", G_TYPE_INVALID, + DBUS_TYPE_G_OBJECT_PATH, &path, G_TYPE_INVALID) == FALSE) + { + g_free (op_backend->bdaddr); +@@ -676,14 +727,10 @@ + G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT64, G_TYPE_INVALID); + + /* Now wait until the device is connected */ +- connected = is_connected (op_backend->session_proxy, G_VFS_JOB (job)); +- while (connected == FALSE) +- { +- g_usleep (G_USEC_PER_SEC / 100); +- connected = is_connected (op_backend->session_proxy, G_VFS_JOB (job)); +- } ++ while (op_backend->status == ASYNC_PENDING) ++ g_cond_wait (op_backend->cond, op_backend->mutex); + +- if (connected < 0) ++ if (op_backend->status == ASYNC_ERROR) + { + g_message ("mount failed, didn't connect"); + +@@ -694,11 +741,10 @@ + g_object_unref (op_backend->session_proxy); + op_backend->session_proxy = NULL; + +- g_vfs_job_failed (G_VFS_JOB (job), +- G_IO_ERROR, G_IO_ERROR_BUSY, +- _("Connection to the device lost")); ++ g_vfs_job_failed_from_error (G_VFS_JOB (job), op_backend->error); + return; + } ++ op_backend->status = ASYNC_PENDING; + + g_vfs_job_succeeded (G_VFS_JOB (job)); + +@@ -1482,6 +1528,12 @@ + /* TransferStarted */ + dbus_g_object_register_marshaller(obexftp_marshal_VOID__STRING_STRING_UINT64, + G_TYPE_NONE, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT64, G_TYPE_INVALID); ++ /* SessionConnected */ ++ dbus_g_object_register_marshaller(obexftp_marshal_VOID__STRING, ++ G_TYPE_NONE, DBUS_TYPE_G_OBJECT_PATH, G_TYPE_INVALID); ++ /* SessionConnectError */ ++ dbus_g_object_register_marshaller (obexftp_marshal_VOID__STRING_STRING_STRING, ++ G_TYPE_NONE, DBUS_TYPE_G_OBJECT_PATH, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID); + } + + /* diff --git a/gvfs.spec b/gvfs.spec index 5a2caad..b949380 100644 --- a/gvfs.spec +++ b/gvfs.spec @@ -85,6 +85,7 @@ as well as ISO images, to applications using gvfs. Summary: ObexFTP support for gvfs Group: System Environment/Libraries Requires: %{name} = %{version}-%{release} +Requires: obex-data-server >= 0.3.4-6 BuildRequires: bluez-libs-devel >= 3.12 BuildRequires: expat-devel