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