[Telepathy-commits] [telepathy-salut/master] 1-1 tubes: do no reply to the iq offering the tube before the user accepts it.

Alban Crequy alban.crequy at collabora.co.uk
Tue Nov 25 03:59:26 PST 2008


---
 src/salut-tubes-channel.c |   19 +++--
 src/salut-tubes-channel.h |    4 +-
 src/salut-tubes-manager.c |   11 +---
 src/tube-stream.c         |  174 ++++++++++++++++++++++++++++++++++++++------
 src/tube-stream.h         |    3 +-
 5 files changed, 168 insertions(+), 43 deletions(-)

diff --git a/src/salut-tubes-channel.c b/src/salut-tubes-channel.c
index 6c0bce4..c68014b 100644
--- a/src/salut-tubes-channel.c
+++ b/src/salut-tubes-channel.c
@@ -169,7 +169,8 @@ static gboolean extract_tube_information (SalutTubesChannel *self,
     const gchar **service, GHashTable **parameters, guint *tube_id);
 static SalutTubeIface * create_new_tube (SalutTubesChannel *self,
     TpTubeType type, TpHandle initiator, const gchar *service,
-    GHashTable *parameters, guint tube_id, guint portnum);
+    GHashTable *parameters, guint tube_id, guint portnum,
+    GibberIqHelperRequestStanza *iq_req);
 
 static void
 salut_tubes_channel_init (SalutTubesChannel *self)
@@ -805,7 +806,7 @@ tubes_muc_message_received (SalutTubesChannel *self,
                 }
 
               tube = create_new_tube (self, type, initiator_handle,
-                  service, parameters, tube_id, 0);
+                  service, parameters, tube_id, 0, NULL);
 
               /* the tube has reffed its initiator, no need to keep a ref */
               tp_handle_unref (contact_repo, initiator_handle);
@@ -883,7 +884,8 @@ tubes_message_received (SalutTubesChannel *self,
                         TpHandle initiator_handle,
                         GHashTable *parameters,
                         guint tube_id,
-                        guint portnum)
+                        guint portnum,
+                        GibberIqHelperRequestStanza *iq_req)
 {
   SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self);
 
@@ -894,7 +896,7 @@ tubes_message_received (SalutTubesChannel *self,
   if (tube == NULL)
     {
       tube = create_new_tube (self, tube_type, initiator_handle, service,
-        parameters, tube_id, portnum);
+        parameters, tube_id, portnum, iq_req);
     }
 }
 
@@ -1102,7 +1104,8 @@ create_new_tube (SalutTubesChannel *self,
                  const gchar *service,
                  GHashTable *parameters,
                  guint tube_id,
-                 guint portnum)
+                 guint portnum,
+                 GibberIqHelperRequestStanza *iq_req)
 {
   SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self);
   SalutTubeIface *tube;
@@ -1123,7 +1126,7 @@ create_new_tube (SalutTubesChannel *self,
       tube = SALUT_TUBE_IFACE (salut_tube_stream_new (priv->conn,
           priv->xmpp_connection_manager, priv->handle, priv->handle_type,
           priv->self_handle, initiator, service, parameters, tube_id,
-          portnum));
+          portnum, iq_req));
       break;
     default:
       g_assert_not_reached ();
@@ -1479,7 +1482,7 @@ salut_tubes_channel_offer_d_bus_tube (TpSvcChannelTypeTubes *iface,
   tube_id = generate_tube_id ();
 
   tube = create_new_tube (self, TP_TUBE_TYPE_DBUS, priv->self_handle,
-      service, parameters_copied, tube_id, 0);
+      service, parameters_copied, tube_id, 0, NULL);
 
   tp_svc_channel_type_tubes_return_from_offer_d_bus_tube (context, tube_id);
 }
@@ -1974,7 +1977,7 @@ salut_tubes_channel_offer_stream_tube (TpSvcChannelTypeTubes *iface,
   tube_id = generate_tube_id ();
 
   tube = create_new_tube (self, TP_TUBE_TYPE_STREAM, priv->self_handle,
-      service, parameters_copied, tube_id, 0);
+      service, parameters_copied, tube_id, 0, NULL);
 
   g_object_set (tube,
       "address-type", address_type,
diff --git a/src/salut-tubes-channel.h b/src/salut-tubes-channel.h
index 4119d20..c3ddb16 100644
--- a/src/salut-tubes-channel.h
+++ b/src/salut-tubes-channel.h
@@ -24,6 +24,7 @@
 #include <gibber/gibber-xmpp-stanza.h>
 #include <gibber/gibber-xmpp-connection.h>
 #include <gibber/gibber-bytestream-iface.h>
+#include <gibber/gibber-iq-helper.h>
 
 #include "salut-muc-channel.h"
 
@@ -74,7 +75,8 @@ void tubes_muc_message_received (SalutTubesChannel *channel,
 
 void tubes_message_received (SalutTubesChannel *self,
     const gchar *service, TpTubeType tube_type, TpHandle initiator_handle,
-    GHashTable *parameters, guint tube_id, guint portnum);
+    GHashTable *parameters, guint tube_id, guint portnum,
+    GibberIqHelperRequestStanza *iq_req);
 
 void tubes_message_close_received (SalutTubesChannel *self,
     TpHandle initiator_handle, guint tube_id);
diff --git a/src/salut-tubes-manager.c b/src/salut-tubes-manager.c
index 4c67175..6e55dec 100644
--- a/src/salut-tubes-manager.c
+++ b/src/salut-tubes-manager.c
@@ -292,8 +292,6 @@ iq_tube_request_cb (SalutXmppConnectionManager *xcm,
   TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
       (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT);
 
-  GibberXmppStanza *reply;
-
   /* tube informations */
   const gchar *service;
   TpTubeType tube_type;
@@ -343,15 +341,10 @@ iq_tube_request_cb (SalutXmppConnectionManager *xcm,
       }
 
     tubes_message_received (chan, service, tube_type, initiator_handle,
-        parameters, tube_id, portnum);
+        parameters, tube_id, portnum,
+        gibber_iq_helper_get_request_stanza (stanza));
   }
 
-  reply = gibber_iq_helper_new_result_reply (
-      gibber_iq_helper_get_request_stanza (stanza));
-  gibber_xmpp_connection_send (conn, reply, NULL);
-
-  g_object_unref (reply);
-
   return;
 }
 
diff --git a/src/tube-stream.c b/src/tube-stream.c
index 48adde3..18047a1 100644
--- a/src/tube-stream.c
+++ b/src/tube-stream.c
@@ -107,6 +107,7 @@ enum
   PROP_ACCESS_CONTROL_PARAM,
   PROP_XMPP_CONNECTION_MANAGER,
   PROP_PORT,
+  PROP_IQ_REQ,
   LAST_PROPERTY
 };
 
@@ -119,6 +120,8 @@ struct _SalutTubeStreamPrivate
   TpHandle self_handle;
   guint id;
   guint port;
+  GibberXmppConnection *xmpp_connection;
+  GibberIqHelperRequestStanza *iq_req;
 
   /* Bytestreams for MUC tubes (using stream initiation) or 1-1 tubes (using
    * direct TCP connections). One tube can have several bytestreams. The
@@ -162,6 +165,16 @@ struct _SalutTubeStreamPrivate
 static void data_received_cb (GibberBytestreamIface *ibb, TpHandle sender,
     GString *data, gpointer user_data);
 
+static void xmpp_connection_manager_new_connection_cb (
+    SalutXmppConnectionManager *mgr, GibberXmppConnection *conn,
+    SalutContact *new_contact, gpointer user_data);
+
+static void xmpp_connection_manager_connection_closed_cb (
+    SalutXmppConnectionManager *mgr, GibberXmppConnection *conn,
+    SalutContact *old_contact, gpointer user_data);
+
+static void ensure_iq_helper (SalutTubeStream *tube);
+
 static void
 generate_ascii_string (guint len,
                        gchar *buf)
@@ -1188,6 +1201,9 @@ salut_tube_stream_get_property (GObject *object,
       case PROP_PORT:
         g_value_set_uint (value, priv->port);
         break;
+      case PROP_IQ_REQ:
+        g_value_set_pointer (value, priv->iq_req);
+        break;
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
         break;
@@ -1267,12 +1283,87 @@ salut_tube_stream_set_property (GObject *object,
       case PROP_PORT:
         priv->port = g_value_get_uint (value);
         break;
+      case PROP_IQ_REQ:
+        priv->iq_req = g_value_get_pointer (value);
+        break;
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
         break;
     }
 }
 
+static void
+xmpp_connection_manager_connection_closed_cb (SalutXmppConnectionManager *mgr,
+                                              GibberXmppConnection *conn,
+                                              SalutContact *old_contact,
+                                              gpointer user_data)
+{
+  SalutTubeStream *self = SALUT_TUBE_STREAM (user_data);
+  SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self);
+  SalutContactManager *contact_mgr;
+  SalutContact *contact;
+
+  g_object_get (priv->conn, "contact-manager", &contact_mgr, NULL);
+  g_assert (contact_mgr != NULL);
+
+  contact = salut_contact_manager_get_contact (contact_mgr,
+      priv->handle);
+
+  if (contact != old_contact)
+    {
+      /* This connection is not for this tube */
+      g_object_unref (contact);
+      g_object_unref (contact_mgr);
+      return;
+    }
+
+  g_assert (priv->xmpp_connection == conn);
+  priv->xmpp_connection = NULL;
+
+  g_signal_handlers_disconnect_matched (priv->xmpp_connection_manager,
+      G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
+
+  g_signal_connect (priv->xmpp_connection_manager, "new-connection",
+      G_CALLBACK (xmpp_connection_manager_new_connection_cb), self);
+}
+
+static void
+xmpp_connection_manager_new_connection_cb (SalutXmppConnectionManager *mgr,
+                                           GibberXmppConnection *conn,
+                                           SalutContact *new_contact,
+                                           gpointer user_data)
+{
+  SalutTubeStream *self = SALUT_TUBE_STREAM (user_data);
+  SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self);
+  SalutContactManager *contact_mgr;
+  SalutContact *contact;
+
+  g_object_get (priv->conn, "contact-manager", &contact_mgr, NULL);
+  g_assert (contact_mgr != NULL);
+
+  contact = salut_contact_manager_get_contact (contact_mgr,
+      priv->handle);
+
+  if (contact != new_contact)
+    {
+      /* This new connection is not for this tube */
+      g_object_unref (contact);
+      g_object_unref (contact_mgr);
+      return;
+    }
+
+  DEBUG ("pending connection fully open");
+
+  g_assert (conn != NULL);
+  priv->xmpp_connection = conn;
+
+  g_signal_connect (priv->xmpp_connection_manager, "connection-closed",
+      G_CALLBACK (xmpp_connection_manager_connection_closed_cb), self);
+
+  g_object_unref (contact);
+  g_object_unref (contact_mgr);
+}
+
 static GObject *
 salut_tube_stream_constructor (GType type,
                                 guint n_props,
@@ -1315,6 +1406,10 @@ salut_tube_stream_constructor (GType type,
       priv->state = TP_TUBE_STATE_LOCAL_PENDING;
     }
 
+  g_signal_connect (priv->xmpp_connection_manager, "new-connection",
+      G_CALLBACK (xmpp_connection_manager_new_connection_cb), obj);
+  ensure_iq_helper (SALUT_TUBE_STREAM (obj));
+
   return obj;
 }
 
@@ -1433,6 +1528,17 @@ salut_tube_stream_class_init (SalutTubeStreamClass *salut_tube_stream_class)
       G_PARAM_STATIC_BLURB);
   g_object_class_install_property (object_class, PROP_PORT, param_spec);
 
+  param_spec = g_param_spec_pointer (
+      "iq-req",
+      "A GibberIqHelper reference on the request stanza",
+      "A GibberIqHelper reference on the request stanza used to reply to "
+      "the iq request later",
+      G_PARAM_CONSTRUCT_ONLY |
+      G_PARAM_READWRITE |
+      G_PARAM_STATIC_NICK |
+      G_PARAM_STATIC_BLURB);
+  g_object_class_install_property (object_class, PROP_IQ_REQ, param_spec);
+
   signals[OPENED] =
     g_signal_new ("opened",
                   G_OBJECT_CLASS_TYPE (salut_tube_stream_class),
@@ -1517,7 +1623,8 @@ salut_tube_stream_new (SalutConnection *conn,
                         const gchar *service,
                         GHashTable *parameters,
                         guint id,
-                        guint portnum)
+                        guint portnum,
+                        GibberIqHelperRequestStanza *iq_req)
 {
   return g_object_new (SALUT_TYPE_TUBE_STREAM,
       "connection", conn,
@@ -1530,9 +1637,39 @@ salut_tube_stream_new (SalutConnection *conn,
       "parameters", parameters,
       "id", id,
       "port", portnum,
+      "iq-req", iq_req,
       NULL);
 }
 
+static void
+ensure_iq_helper (SalutTubeStream *tube)
+{
+  SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (tube);
+
+  if (priv->iq_helper == NULL)
+    {
+      SalutXmppConnectionManagerRequestConnectionResult result;
+      SalutContactManager *contact_mgr;
+      SalutContact *contact;
+
+      g_object_get (priv->conn, "contact-manager", &contact_mgr, NULL);
+      g_assert (contact_mgr != NULL);
+
+      contact = salut_contact_manager_get_contact (contact_mgr,
+          priv->handle);
+
+      result = salut_xmpp_connection_manager_request_connection (
+          priv->xmpp_connection_manager, contact, &priv->xmpp_connection, NULL);
+
+      if (result ==
+          SALUT_XMPP_CONNECTION_MANAGER_REQUEST_CONNECTION_RESULT_DONE)
+        {
+          priv->iq_helper = gibber_iq_helper_new (priv->xmpp_connection);
+          g_assert (priv->iq_helper);
+        }
+    }
+}
+
 /**
  * salut_tube_stream_accept
  *
@@ -1544,6 +1681,7 @@ salut_tube_stream_accept (SalutTubeIface *tube,
 {
   SalutTubeStream *self = SALUT_TUBE_STREAM (tube);
   SalutTubeStreamPrivate *priv = SALUT_TUBE_STREAM_GET_PRIVATE (self);
+  GibberXmppStanza *reply;
 
   if (priv->state != TP_TUBE_STATE_LOCAL_PENDING)
     return TRUE;
@@ -1554,6 +1692,16 @@ salut_tube_stream_accept (SalutTubeIface *tube,
       return FALSE;
     }
 
+  ensure_iq_helper (self);
+
+  if (priv->xmpp_connection && priv->iq_helper)
+    {
+      reply = gibber_iq_helper_new_result_reply (priv->iq_req);
+      gibber_xmpp_connection_send (priv->xmpp_connection, reply, NULL);
+
+      g_object_unref (reply);
+    }
+
   priv->state = TP_TUBE_STATE_OPEN;
   g_signal_emit (G_OBJECT (self), signals[OPENED], 0);
   return TRUE;
@@ -1622,29 +1770,7 @@ salut_tube_stream_close (SalutTubeIface *tube)
           GIBBER_NODE_END,
           GIBBER_STANZA_END);
 
-      if (priv->iq_helper == NULL)
-        {
-          SalutXmppConnectionManagerRequestConnectionResult result;
-          SalutContactManager *contact_mgr;
-          SalutContact *contact;
-          GibberXmppConnection *xmpp_connection = NULL;
-
-          g_object_get (priv->conn, "contact-manager", &contact_mgr, NULL);
-          g_assert (contact_mgr != NULL);
-
-          contact = salut_contact_manager_get_contact (contact_mgr,
-              priv->handle);
-
-          result = salut_xmpp_connection_manager_request_connection (
-              priv->xmpp_connection_manager, contact, &xmpp_connection, NULL);
-
-          if (result ==
-              SALUT_XMPP_CONNECTION_MANAGER_REQUEST_CONNECTION_RESULT_DONE)
-            {
-              priv->iq_helper = gibber_iq_helper_new (xmpp_connection);
-              g_assert (priv->iq_helper);
-            }
-        }
+      ensure_iq_helper (self);
 
       if (priv->iq_helper != NULL)
         {
diff --git a/src/tube-stream.h b/src/tube-stream.h
index 70d5567..343cf55 100644
--- a/src/tube-stream.h
+++ b/src/tube-stream.h
@@ -63,7 +63,8 @@ GType salut_tube_stream_get_type (void);
 SalutTubeStream *salut_tube_stream_new (SalutConnection *conn,
     SalutXmppConnectionManager *xmpp_connection_manager, TpHandle handle,
     TpHandleType handle_type, TpHandle self_handle, TpHandle initiator,
-    const gchar *service, GHashTable *parameters, guint id, guint portnum);
+    const gchar *service, GHashTable *parameters, guint id, guint portnum,
+    GibberIqHelperRequestStanza *iq_req);
 
 gboolean salut_tube_stream_check_params (TpSocketAddressType address_type,
     const GValue *address, TpSocketAccessControl access_control,
-- 
1.5.6.5




More information about the Telepathy-commits mailing list