[Telepathy-commits] [telepathy-glib/master] TpConnection: add the client side of ConnectionError

Simon McVittie simon.mcvittie at collabora.co.uk
Wed Jan 28 04:40:58 PST 2009


This includes a behaviour change which affects the regression
tests. Previously, all disconnections were mapped to
the TP_ERROR_DISCONNECTED domain; now, they use the errors
introduced in telepathy-spec 0.17.19 whenever possible.
---
 telepathy-glib/connection-internal.h          |    1 +
 telepathy-glib/connection.c                   |  124 ++++++++++++++++++++++++-
 tests/dbus/channel-introspect.c               |    8 +-
 tests/dbus/finalized-in-invalidated-handler.c |    4 +-
 4 files changed, 126 insertions(+), 11 deletions(-)

diff --git a/telepathy-glib/connection-internal.h b/telepathy-glib/connection-internal.h
index e51b8b1..87e1f63 100644
--- a/telepathy-glib/connection-internal.h
+++ b/telepathy-glib/connection-internal.h
@@ -35,6 +35,7 @@ struct _TpConnectionPrivate {
 
     TpConnectionStatus status;
     TpConnectionStatusReason status_reason;
+    GError *connection_error /* initialized statically */;
 
     TpConnectionAliasFlags alias_flags;
 
diff --git a/telepathy-glib/connection.c b/telepathy-glib/connection.c
index 581a795..17384d7 100644
--- a/telepathy-glib/connection.c
+++ b/telepathy-glib/connection.c
@@ -372,6 +372,107 @@ tp_connection_status_changed (TpConnection *self,
 }
 
 static void
+tp_connection_connection_error_cb (TpConnection *self,
+                                   const gchar *error_name,
+                                   GHashTable *details,
+                                   gpointer user_data,
+                                   GObject *weak_object)
+{
+  if (self->priv->connection_error != NULL)
+    {
+      g_error_free (self->priv->connection_error);
+      self->priv->connection_error = NULL;
+    }
+
+  tp_proxy_dbus_error_to_gerror (self, error_name,
+        tp_asv_get_string (details, "debug-message"),
+        &(self->priv->connection_error));
+}
+
+static void
+tp_connection_status_reason_to_gerror (TpConnectionStatusReason reason,
+                                       GError **error)
+{
+  TpError code;
+  const gchar *message;
+
+  switch (reason)
+    {
+    case TP_CONNECTION_STATUS_REASON_NONE_SPECIFIED:
+      code = TP_ERROR_DISCONNECTED;
+      message = "Disconnected for unspecified reason";
+      break;
+
+    case TP_CONNECTION_STATUS_REASON_REQUESTED:
+      code = TP_ERROR_CANCELLED;
+      message = "User requested disconnection";
+      break;
+
+    case TP_CONNECTION_STATUS_REASON_NETWORK_ERROR:
+      code = TP_ERROR_NETWORK_ERROR;
+      message = "Network error";
+      break;
+
+    case TP_CONNECTION_STATUS_REASON_ENCRYPTION_ERROR:
+      code = TP_ERROR_ENCRYPTION_ERROR;
+      message = "Encryption error";
+      break;
+
+    case TP_CONNECTION_STATUS_REASON_NAME_IN_USE:
+      code = TP_ERROR_NOT_YOURS;
+      message = "Name in use";
+      break;
+
+    case TP_CONNECTION_STATUS_REASON_CERT_NOT_PROVIDED:
+      code = TP_ERROR_CERT_NOT_PROVIDED;
+      message = "Server certificate not provided";
+      break;
+
+    case TP_CONNECTION_STATUS_REASON_CERT_UNTRUSTED:
+      code = TP_ERROR_CERT_UNTRUSTED;
+      message = "Server certificate CA not trusted";
+      break;
+
+    case TP_CONNECTION_STATUS_REASON_CERT_EXPIRED:
+      code = TP_ERROR_CERT_EXPIRED;
+      message = "Server certificate expired";
+      break;
+
+    case TP_CONNECTION_STATUS_REASON_CERT_NOT_ACTIVATED:
+      code = TP_ERROR_CERT_NOT_ACTIVATED;
+      message = "Server certificate not valid yet";
+      break;
+
+    case TP_CONNECTION_STATUS_REASON_CERT_HOSTNAME_MISMATCH:
+      code = TP_ERROR_CERT_HOSTNAME_MISMATCH;
+      message = "Server certificate has wrong hostname";
+      break;
+
+    case TP_CONNECTION_STATUS_REASON_CERT_FINGERPRINT_MISMATCH:
+      code = TP_ERROR_CERT_FINGERPRINT_MISMATCH;
+      message = "Server certificate fingerprint mismatch";
+      break;
+
+    case TP_CONNECTION_STATUS_REASON_CERT_SELF_SIGNED:
+      code = TP_ERROR_CERT_SELF_SIGNED;
+      message = "Server certificate is self-signed";
+      break;
+
+    case TP_CONNECTION_STATUS_REASON_CERT_OTHER_ERROR:
+      code = TP_ERROR_CERT_INVALID;
+      message = "Unspecified server certificate error";
+      break;
+
+    default:
+      g_set_error (error, TP_ERRORS_DISCONNECTED, reason,
+          "Unknown disconnection reason");
+      return;
+    }
+
+  g_set_error (error, TP_ERRORS, code, "%s", message);
+}
+
+static void
 tp_connection_status_changed_cb (TpConnection *self,
                                  guint status,
                                  guint reason,
@@ -392,11 +493,16 @@ tp_connection_status_changed_cb (TpConnection *self,
 
   if (status == TP_CONNECTION_STATUS_DISCONNECTED)
     {
-      GError *error = g_error_new (TP_ERRORS_DISCONNECTED, reason,
-          "Disconnected: reason %d", reason);
+      if (self->priv->connection_error == NULL)
+        {
+          tp_connection_status_reason_to_gerror (reason,
+              &(self->priv->connection_error));
+        }
+
+      tp_proxy_invalidate ((TpProxy *) self, self->priv->connection_error);
 
-      tp_proxy_invalidate ((TpProxy *) self, error);
-      g_error_free (error);
+      g_error_free (self->priv->connection_error);
+      self->priv->connection_error = NULL;
     }
 }
 
@@ -435,9 +541,11 @@ tp_connection_constructor (GType type,
   /* Connect to my own StatusChanged signal.
    * The connection hasn't had a chance to become invalid yet, so we can
    * assume that this signal connection will work */
-  DEBUG ("Connecting to StatusChanged");
+  DEBUG ("Connecting to StatusChanged and ConnectionError");
   tp_cli_connection_connect_to_status_changed (self,
       tp_connection_status_changed_cb, NULL, NULL, NULL, NULL);
+  tp_cli_connection_connect_to_connection_error (self,
+      tp_connection_connection_error_cb, NULL, NULL, NULL, NULL);
 
   /* get my initial status */
   DEBUG ("Calling GetStatus");
@@ -486,6 +594,12 @@ tp_connection_finalize (GObject *object)
       self->priv->contact_attribute_interfaces = NULL;
     }
 
+  if (self->priv->connection_error != NULL)
+    {
+      g_error_free (self->priv->connection_error);
+      self->priv->connection_error = NULL;
+    }
+
   ((GObjectClass *) tp_connection_parent_class)->finalize (object);
 }
 
diff --git a/tests/dbus/channel-introspect.c b/tests/dbus/channel-introspect.c
index 8cf1f21..39ff283 100644
--- a/tests/dbus/channel-introspect.c
+++ b/tests/dbus/channel-introspect.c
@@ -462,10 +462,10 @@ main (int argc,
   tp_channel_call_when_ready (chan, channel_ready, &was_ready);
   MYASSERT (was_ready == TRUE, "");
   MYASSERT (invalidated != NULL, "");
-  MYASSERT (invalidated->domain == TP_ERRORS_DISCONNECTED,
-      "%s", g_quark_to_string (invalidated->domain));
-  MYASSERT (invalidated->code == TP_CONNECTION_STATUS_REASON_REQUESTED,
-      "%u", invalidated->code);
+  MYASSERT (invalidated->domain == TP_ERRORS,
+      ": %s", g_quark_to_string (invalidated->domain));
+  MYASSERT (invalidated->code == TP_ERROR_CANCELLED,
+      ": %u", invalidated->code);
   g_error_free (invalidated);
   invalidated = NULL;
 
diff --git a/tests/dbus/finalized-in-invalidated-handler.c b/tests/dbus/finalized-in-invalidated-handler.c
index 0ee16e5..dfd3650 100644
--- a/tests/dbus/finalized-in-invalidated-handler.c
+++ b/tests/dbus/finalized-in-invalidated-handler.c
@@ -36,9 +36,9 @@ on_invalidated (TpChannel *chan,
 {
   TpChannel **client = user_data;
 
-  MYASSERT (domain == TP_ERRORS_DISCONNECTED, ": domain \"%s\"",
+  MYASSERT (domain == TP_ERRORS, ": domain \"%s\"",
       g_quark_to_string (domain));
-  MYASSERT (code == TP_CONNECTION_STATUS_REASON_REQUESTED, ": code %u", code);
+  MYASSERT (code == TP_ERROR_CANCELLED, ": code %u", code);
 
   MYASSERT (*client == chan, "%p vs %p", *client, chan);
   g_object_unref (*client);
-- 
1.5.6.5




More information about the telepathy-commits mailing list