[Telepathy-commits] [telepathy-salut/master] Connect to the contact to offer a tube

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


20080423185223-a41c0-bf516c544aabf4d264021d51bf7541c700a760ad.gz
---
 src/salut-connection.c    |    3 +-
 src/salut-tubes-channel.c |  398 +++++++++++++++++++++++++++++++++++++++++++++
 src/salut-tubes-manager.c |  133 +++++++++++++++-
 src/salut-tubes-manager.h |    8 +-
 4 files changed, 534 insertions(+), 8 deletions(-)

diff --git a/src/salut-connection.c b/src/salut-connection.c
index c946d2a..b2828ea 100644
--- a/src/salut-connection.c
+++ b/src/salut-connection.c
@@ -2632,7 +2632,8 @@ salut_connection_create_channel_factories(TpBaseConnection *base) {
   priv->muc_manager = salut_muc_manager_new (self,
       priv->xmpp_connection_manager);
 
-  priv->tubes_manager = salut_tubes_manager_new (self, priv->contact_manager);
+  priv->tubes_manager = salut_tubes_manager_new (self, priv->contact_manager,
+      priv->xmpp_connection_manager);
 
   g_ptr_array_add (factories, priv->contact_manager);
   g_ptr_array_add (factories, priv->im_manager);
diff --git a/src/salut-tubes-channel.c b/src/salut-tubes-channel.c
index 2a36c67..9fc4374 100644
--- a/src/salut-tubes-channel.c
+++ b/src/salut-tubes-channel.c
@@ -44,6 +44,7 @@
 #include "salut-connection.h"
 #include "salut-contact.h"
 #include "salut-muc-channel.h"
+#include "salut-xmpp-connection-manager.h"
 #include "tube-iface.h"
 #include "tube-dbus.h"
 #include "tube-stream.h"
@@ -75,6 +76,47 @@ G_DEFINE_TYPE_WITH_CODE (SalutTubesChannel, salut_tubes_channel, G_TYPE_OBJECT,
     G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL);
 );
 
+static void
+xmpp_connection_manager_new_connection_cb (SalutXmppConnectionManager *mgr,
+    GibberXmppConnection *conn,
+    SalutContact *contact,
+    gpointer user_data);
+
+static void
+xmpp_connection_manager_connection_closed_cb (SalutXmppConnectionManager *mgr,
+    GibberXmppConnection *conn,
+    SalutContact *contact,
+    gpointer user_data);
+
+static void
+xmpp_connection_manager_connection_closing_cb (SalutXmppConnectionManager *mgr,
+    GibberXmppConnection *conn,
+    SalutContact *contact,
+    gpointer user_data);
+
+static gboolean
+message_stanza_filter (SalutXmppConnectionManager *mgr,
+    GibberXmppConnection *conn, GibberXmppStanza *stanza,
+    SalutContact *contact, gpointer user_data);
+
+static void
+message_stanza_callback (SalutXmppConnectionManager *mgr,
+    GibberXmppConnection *conn, GibberXmppStanza *stanza,
+    SalutContact *contact, gpointer user_data);
+
+static void
+_send_channel_iq_tubes (SalutTubesChannel *self);
+
+/* Channel state */
+typedef enum
+{
+  CHANNEL_NOT_CONNECTED = 0,
+  CHANNEL_CONNECTING,
+  CHANNEL_CONNECTED,
+  CHANNEL_CLOSING,
+} ChannelState;
+
+/* properties */
 enum
 {
   PROP_OBJECT_PATH = 1,
@@ -83,6 +125,10 @@ enum
   PROP_HANDLE,
   PROP_CONNECTION,
   PROP_MUC,
+
+  /* only for 1-1 tubes */
+  PROP_CONTACT,
+  PROP_XMPP_CONNECTION_MANAGER,
   LAST_PROPERTY
 };
 
@@ -98,6 +144,13 @@ struct _SalutTubesChannelPrivate
   TpHandleType self_handle;
   GibberMucConnection *muc_connection;
 
+  /* In case of 1-1 tube channel, we need to send <iq> stanza to the contact
+   * on a Xmpp connection */
+  SalutContact *contact;
+  GibberXmppConnection *xmpp_connection;
+  SalutXmppConnectionManager *xmpp_connection_manager;
+  ChannelState state;
+
   GHashTable *tubes;
 
   gboolean closed;
@@ -130,6 +183,11 @@ salut_tubes_channel_init (SalutTubesChannel *self)
   priv->tubes = g_hash_table_new_full (g_direct_hash, g_direct_equal,
       NULL, (GDestroyNotify) g_object_unref);
 
+  priv->contact = NULL;
+  priv->xmpp_connection = NULL;
+  priv->state = CHANNEL_NOT_CONNECTED;
+  priv->xmpp_connection_manager = NULL;
+
   priv->dispose_has_run = FALSE;
   priv->closed = FALSE;
 }
@@ -190,6 +248,9 @@ salut_tubes_channel_constructor (GType type,
 
   DEBUG ("Registering at '%s'", priv->object_path);
 
+  g_signal_connect (priv->xmpp_connection_manager, "new-connection",
+      G_CALLBACK (xmpp_connection_manager_new_connection_cb), obj);
+
   return obj;
 }
 
@@ -222,6 +283,12 @@ salut_tubes_channel_get_property (GObject *object,
       case PROP_MUC:
         g_value_set_object (value, chan->muc);
         break;
+      case PROP_CONTACT:
+        g_value_set_object (value, priv->contact);
+        break;
+      case PROP_XMPP_CONNECTION_MANAGER:
+        g_value_set_object (value, priv->xmpp_connection_manager);
+        break;
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
         break;
@@ -264,12 +331,223 @@ salut_tubes_channel_set_property (GObject *object,
       case PROP_MUC:
         chan->muc = g_value_get_object (value);
         break;
+      case PROP_CONTACT:
+        priv->contact = g_value_get_object (value);
+        g_object_ref (priv->contact);
+        break;
+      case PROP_XMPP_CONNECTION_MANAGER:
+        priv->xmpp_connection_manager = g_value_get_object (value);
+        g_object_ref (priv->xmpp_connection_manager);
+        break;
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
         break;
     }
 }
 
+static gboolean
+message_stanza_filter (SalutXmppConnectionManager *mgr,
+                       GibberXmppConnection *conn,
+                       GibberXmppStanza *stanza,
+                       SalutContact *contact,
+                       gpointer user_data)
+{
+  SalutTubesChannel *self = SALUT_TUBES_CHANNEL (user_data);
+  SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self);
+  GibberStanzaType type;
+  GibberStanzaSubType sub_type;
+
+  if (priv->contact != contact)
+    return FALSE;
+
+  gibber_xmpp_stanza_get_type_info (stanza, &type, &sub_type);
+  if (type != GIBBER_STANZA_TYPE_IQ)
+    return FALSE;
+
+  if (sub_type != GIBBER_STANZA_SUB_TYPE_SET)
+    return FALSE;
+
+  if (gibber_xmpp_node_get_child_ns (stanza->node, "tube",
+        GIBBER_TELEPATHY_NS_TUBES) != NULL)
+    return TRUE;
+
+  if (gibber_xmpp_node_get_child_ns (stanza->node, "close",
+        GIBBER_TELEPATHY_NS_TUBES) != NULL)
+    return TRUE;
+
+  return FALSE;
+}
+
+static void
+message_stanza_callback (SalutXmppConnectionManager *mgr,
+                         GibberXmppConnection *conn,
+                         GibberXmppStanza *stanza,
+                         SalutContact *contact,
+                         gpointer user_data)
+{
+  printf("Message stanza received, but the code to handle it is not written "
+         "yet !!\n"); /* TODO */
+}
+
+static void
+_initialise_connection (SalutTubesChannel *self)
+{
+  SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self);
+
+  DEBUG ("called.");
+
+  g_assert (priv->xmpp_connection != NULL);
+  g_assert (
+     (priv->xmpp_connection->stream_flags &
+       ~(GIBBER_XMPP_CONNECTION_STREAM_FULLY_OPEN
+         |GIBBER_XMPP_CONNECTION_CLOSE_SENT)) == 0);
+
+
+  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, "connection-closed",
+      G_CALLBACK (xmpp_connection_manager_connection_closed_cb), self);
+  g_signal_connect (priv->xmpp_connection_manager, "connection-closing",
+      G_CALLBACK (xmpp_connection_manager_connection_closing_cb), self);
+
+  salut_xmpp_connection_manager_add_stanza_filter (
+      priv->xmpp_connection_manager, priv->xmpp_connection,
+      message_stanza_filter, message_stanza_callback, self);
+
+  if (priv->xmpp_connection->stream_flags
+        & GIBBER_XMPP_CONNECTION_CLOSE_SENT) {
+    priv->state = CHANNEL_CLOSING;
+    DEBUG ("priv->state = CHANNEL_CLOSING");
+  } else {
+    priv->state = CHANNEL_CONNECTED;
+    DEBUG ("priv->state = CHANNEL_CONNECTED");
+    _send_channel_iq_tubes (self);
+  }
+}
+
+static void
+xmpp_connection_manager_new_connection_cb (SalutXmppConnectionManager *mgr,
+                                           GibberXmppConnection *conn,
+                                           SalutContact *contact,
+                                           gpointer user_data)
+{
+  SalutTubesChannel *self = SALUT_TUBES_CHANNEL (user_data);
+  SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self);
+
+  if (contact != priv->contact)
+    /* This new connection is not for this channel */
+    return;
+
+  DEBUG ("pending connection fully open");
+
+  priv->xmpp_connection = conn;
+  g_object_ref (priv->xmpp_connection);
+  _initialise_connection (self);
+}
+
+static void
+connection_disconnected (SalutTubesChannel *self)
+{
+  SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self);
+
+  if (priv->xmpp_connection != NULL)
+    {
+      DEBUG ("connection closed. Remove filters");
+
+      salut_xmpp_connection_manager_remove_stanza_filter (
+          priv->xmpp_connection_manager, priv->xmpp_connection,
+          message_stanza_filter, message_stanza_callback, self);
+
+      g_object_unref (priv->xmpp_connection);
+      priv->xmpp_connection = NULL;
+    }
+
+  g_signal_handlers_disconnect_matched (priv->xmpp_connection_manager,
+      G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, self);
+
+  priv->state = CHANNEL_NOT_CONNECTED;
+
+  g_signal_connect (priv->xmpp_connection_manager, "new-connection",
+      G_CALLBACK (xmpp_connection_manager_new_connection_cb), self);
+
+  /* If some tubes in remote-pending state, reopen the xmpp connection?
+  if (g_queue_get_length(priv->out_queue) > 0) {
+    _setup_connection(self);
+  }
+  */
+}
+
+static void
+xmpp_connection_manager_connection_closed_cb (SalutXmppConnectionManager *mgr,
+                                              GibberXmppConnection *conn,
+                                              SalutContact *contact,
+                                              gpointer user_data)
+{
+  SalutTubesChannel *self = SALUT_TUBES_CHANNEL (user_data);
+  SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self);
+
+  if (priv->contact != contact)
+    return;
+
+  g_assert (priv->xmpp_connection == conn);
+  connection_disconnected (self);
+}
+
+static void
+xmpp_connection_manager_connection_closing_cb (SalutXmppConnectionManager *mgr,
+                                               GibberXmppConnection *conn,
+                                               SalutContact *contact,
+                                               gpointer user_data)
+{
+  SalutTubesChannel *self = SALUT_TUBES_CHANNEL (user_data);
+  SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self);
+
+  if (priv->contact != contact)
+    return;
+
+  DEBUG ("connection closing");
+  g_assert (priv->xmpp_connection == conn);
+  priv->state = CHANNEL_CLOSING;
+}
+
+static void
+_setup_connection (SalutTubesChannel *self)
+{
+  SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self);
+  SalutXmppConnectionManagerRequestConnectionResult result;
+  GibberXmppConnection *conn = NULL;
+
+  DEBUG ("called. state=%d", priv->state);
+
+  if (priv->state == CHANNEL_CONNECTING)
+    return;
+
+  g_assert (priv->xmpp_connection == NULL);
+
+  result = salut_xmpp_connection_manager_request_connection (
+      priv->xmpp_connection_manager, priv->contact, &conn, NULL);
+
+  if (result == SALUT_XMPP_CONNECTION_MANAGER_REQUEST_CONNECTION_RESULT_DONE)
+    {
+      DEBUG ("connection done.");
+      priv->xmpp_connection = conn;
+      g_object_ref (priv->xmpp_connection);
+      _initialise_connection (self);
+    }
+  else if (result ==
+      SALUT_XMPP_CONNECTION_MANAGER_REQUEST_CONNECTION_RESULT_PENDING)
+    {
+      DEBUG ("Requested connection pending");
+      priv->state = CHANNEL_CONNECTING;
+      return;
+    }
+  else
+    {
+      priv->state = CHANNEL_NOT_CONNECTED;
+      return;
+    }
+}
+
 static void
 d_bus_names_changed_added (SalutTubesChannel *self,
                            guint tube_id,
@@ -1471,6 +1749,97 @@ stream_tube_new_connection_cb (SalutTubeIface *tube,
       tube_id, contact);
 }
 
+static void
+_send_channel_iq_tube (gpointer key,
+                       gpointer value,
+                       gpointer user_data)
+{
+  SalutTubeIface *tube = (SalutTubeIface *) value;
+  guint tube_id = GPOINTER_TO_UINT(key);
+  TpHandle initiator;
+  gchar *service;
+  GHashTable *parameters;
+  TpTubeState state;
+  TpTubeType type;
+
+  g_object_get (tube,
+                "type", &type,
+                "initiator", &initiator,
+                "service", &service,
+                "parameters", &parameters,
+                "state", &state,
+                NULL);
+
+  DEBUG ("called for tube id %d", tube_id);
+  if (state == TP_TUBE_STATE_REMOTE_PENDING)
+    {
+      DEBUG ("Tube in remote pending state");
+
+      /*
+      GibberXmppStanza *stanza, *reply;
+      const gchar *jid_from, *jid_to;
+      TpHandleRepoIface *contact_repo;
+
+      contact_repo = tp_base_connection_get_handles (
+         (TpBaseConnection*) priv->conn, TP_HANDLE_TYPE_CONTACT);
+
+      jid_from = tp_handle_inspect (contact_repo, priv->self_handle);
+      jid_to = tp_handle_inspect (contact_repo, priv->handle);
+
+      stanza = gibber_xmpp_stanza_build (GIBBER_STANZA_TYPE_IQ,
+          GIBBER_STANZA_SUB_TYPE_SET,
+          jid_from, jid_to,
+          GIBBER_NODE, "tube",
+            GIBBER_NODE_XMLNS, GIBBER_TELEPATHY_NS_TUBES,
+            GIBBER_NODE_ATTRIBUTE, "type", "stream",
+            GIBBER_NODE_ATTRIBUTE, "service", service,
+            GIBBER_NODE, "parameters",
+              GIBBER_NODE, "parameter",
+                GIBBER_NODE_ATTRIBUTE, "name", "path",
+                GIBBER_NODE_ATTRIBUTE, "type", "str",
+                GIBBER_NODE_TEXT, "/poetry/for-juliet/",
+              GIBBER_NODE_END,
+            GIBBER_NODE_END,
+            GIBBER_NODE, "transport",
+              GIBBER_NODE, "candidate",
+                GIBBER_NODE_ATTRIBUTE, "ip", "127.0.0.1",
+                GIBBER_NODE_ATTRIBUTE, "port", "13540",
+              GIBBER_NODE_END,
+            GIBBER_NODE_END,
+          GIBBER_NODE_END,
+          GIBBER_STANZA_END);
+
+      if (!gibber_iq_helper_send_with_reply (iq_helper, stanza, reply_func,
+          NULL, NULL, NULL))
+        {
+          printf("ERROR\n");
+        }
+    */
+    }
+
+  g_free (service);
+  g_hash_table_unref (parameters);
+}
+
+static void
+_send_channel_iq_tubes (SalutTubesChannel *self)
+{
+  SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self);
+
+  DEBUG ("called. state=%d", priv->state);
+
+  if (priv->state != CHANNEL_CONNECTED)
+    {
+      /* TODO: do not connect if nothing to send... */
+      _setup_connection (self);
+      return;
+    }
+
+  g_hash_table_foreach (priv->tubes, _send_channel_iq_tube, NULL);
+
+}
+
+
 /**
  * salut_tubes_channel_offer_stream_tube
  *
@@ -1533,6 +1902,11 @@ salut_tubes_channel_offer_stream_tube (TpSvcChannelTypeTubes *iface,
       "access-control-param", access_control_param,
       NULL);
 
+  if (priv->handle_type == TP_HANDLE_TYPE_CONTACT)
+    {
+      _send_channel_iq_tubes (self);
+    }
+
   g_signal_connect (tube, "new-connection",
       G_CALLBACK (stream_tube_new_connection_cb), self);
 
@@ -1808,6 +2182,30 @@ salut_tubes_channel_class_init (
       G_PARAM_STATIC_NICK |
       G_PARAM_STATIC_BLURB);
   g_object_class_install_property (object_class, PROP_MUC, param_spec);
+
+  param_spec = g_param_spec_object (
+      "contact",
+      "SalutContact object",
+      "Salut Contact to which this channel is dedicated in case of 1-1 tube",
+      SALUT_TYPE_CONTACT,
+      G_PARAM_CONSTRUCT_ONLY |
+      G_PARAM_READWRITE |
+      G_PARAM_STATIC_NICK |
+      G_PARAM_STATIC_BLURB);
+  g_object_class_install_property (object_class, PROP_CONTACT, param_spec);
+
+  param_spec = g_param_spec_object (
+      "xmpp-connection-manager",
+      "SalutXmppConnectionManager object",
+      "Salut XMPP Connection manager used for this tube channel in case of "
+          "1-1 tube",
+      SALUT_TYPE_XMPP_CONNECTION_MANAGER,
+      G_PARAM_CONSTRUCT_ONLY |
+      G_PARAM_READWRITE |
+      G_PARAM_STATIC_NICK |
+      G_PARAM_STATIC_BLURB);
+  g_object_class_install_property (object_class, PROP_XMPP_CONNECTION_MANAGER,
+      param_spec);
 }
 
 void
diff --git a/src/salut-tubes-manager.c b/src/salut-tubes-manager.c
index 0ba83d1..7901f83 100644
--- a/src/salut-tubes-manager.c
+++ b/src/salut-tubes-manager.c
@@ -37,6 +37,7 @@
 #include "salut-muc-manager.h"
 #include "salut-muc-channel.h"
 #include <gibber/gibber-namespaces.h>
+#include <gibber/gibber-iq-helper.h>
 #include <telepathy-glib/interfaces.h>
 #include <telepathy-glib/channel-factory-iface.h>
 
@@ -59,6 +60,8 @@ G_DEFINE_TYPE_WITH_CODE (SalutTubesManager,
 enum
 {
   PROP_CONNECTION = 1,
+  PROP_CONTACT_MANAGER = 2,
+  PROP_XMPP_CONNECTION_MANAGER = 3,
   LAST_PROPERTY
 };
 
@@ -67,6 +70,8 @@ typedef struct _SalutTubesManagerPrivate \
 struct _SalutTubesManagerPrivate
 {
   SalutConnection *conn;
+  SalutContactManager *contact_manager;
+  SalutXmppConnectionManager *xmpp_connection_manager;
 
   GHashTable *channels;
 
@@ -91,6 +96,63 @@ salut_tubes_manager_init (SalutTubesManager *self)
   priv->dispose_has_run = FALSE;
 }
 
+/* Filter for 1-1 tube request (XEP-proto-tubes)
+ * http://telepathy.freedesktop.org/xmpp/tubes.html */
+static gboolean
+iq_tube_request_filter (SalutXmppConnectionManager *xcm,
+                        GibberXmppConnection *conn,
+                        GibberXmppStanza *stanza,
+                        SalutContact *contact,
+                        gpointer user_data)
+{
+  GibberStanzaType type;
+  GibberStanzaSubType sub_type;
+
+  gibber_xmpp_stanza_get_type_info (stanza, &type, &sub_type);
+  if (type != GIBBER_STANZA_TYPE_IQ)
+    return FALSE;
+
+  if (sub_type != GIBBER_STANZA_SUB_TYPE_SET)
+    return FALSE;
+
+  return (gibber_xmpp_node_get_child_ns (stanza->node, "tube",
+        GIBBER_TELEPATHY_NS_TUBES) != NULL) ||
+         (gibber_xmpp_node_get_child_ns (stanza->node, "close",
+                 GIBBER_TELEPATHY_NS_TUBES) != NULL);
+}
+
+static void
+iq_tube_request_cb (SalutXmppConnectionManager *xcm,
+                    GibberXmppConnection *conn,
+                    GibberXmppStanza *stanza,
+                    SalutContact *contact,
+                    gpointer user_data)
+{
+  /*
+  SalutTubesManager *self = SALUT_TUBES_MANAGER (user_data);
+  SalutTubesManagerPrivate *priv =
+    SALUT_TUBES_MANAGER_GET_PRIVATE (self);
+  */
+  GibberXmppNode *tube, *close;
+  GibberXmppStanza *reply;
+
+  /* after this point, the message is for us, so in all cases we either handle
+   * it or send an error reply */
+
+  tube = gibber_xmpp_node_get_child_ns (stanza->node, "tube", GIBBER_TELEPATHY_NS_TUBES);
+  close = gibber_xmpp_node_get_child_ns (stanza->node, "close", GIBBER_TELEPATHY_NS_TUBES);
+
+  DEBUG ("received a tube request: tube=%p close=%p", tube, close);
+
+  reply = gibber_iq_helper_new_error_reply (stanza, XMPP_ERROR_FEATURE_NOT_IMPLEMENTED,
+      "Implementation not finished yet...");
+  gibber_xmpp_connection_send (conn, reply, NULL);
+
+  g_object_unref (reply);
+
+  return;
+}
+
 static GObject *
 salut_tubes_manager_constructor (GType type,
                                   guint n_props,
@@ -145,6 +207,12 @@ salut_tubes_manager_get_property (GObject *object,
       case PROP_CONNECTION:
         g_value_set_object (value, priv->conn);
         break;
+      case PROP_CONTACT_MANAGER:
+        g_value_set_object (value, priv->contact_manager);
+        break;
+      case PROP_XMPP_CONNECTION_MANAGER:
+        g_value_set_object (value, priv->xmpp_connection_manager);
+        break;
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
         break;
@@ -166,6 +234,14 @@ salut_tubes_manager_set_property (GObject *object,
       case PROP_CONNECTION:
         priv->conn = g_value_get_object (value);
         break;
+      case PROP_CONTACT_MANAGER:
+        priv->contact_manager = g_value_get_object (value);
+        g_object_ref (priv->contact_manager);
+        break;
+      case PROP_XMPP_CONNECTION_MANAGER:
+        priv->xmpp_connection_manager = g_value_get_object (value);
+        g_object_ref (priv->xmpp_connection_manager);
+        break;
       default:
         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
         break;
@@ -201,6 +277,33 @@ salut_tubes_manager_class_init (
       G_PARAM_STATIC_BLURB);
   g_object_class_install_property (object_class, PROP_CONNECTION, param_spec);
 
+  param_spec = g_param_spec_object (
+      "contact-manager",
+      "SalutContactManager object",
+      "Salut Contact Manager associated with the Salut Connection of this "
+      "manager",
+      SALUT_TYPE_CONTACT_MANAGER,
+      G_PARAM_CONSTRUCT_ONLY |
+      G_PARAM_READWRITE |
+      G_PARAM_STATIC_NAME |
+      G_PARAM_STATIC_NICK |
+      G_PARAM_STATIC_BLURB);
+  g_object_class_install_property (object_class, PROP_CONTACT_MANAGER,
+      param_spec);
+
+  param_spec = g_param_spec_object (
+      "xmpp-connection-manager",
+      "SalutXmppConnectionManager object",
+      "Salut Xmpp Connection Manager associated with the Salut Connection of this "
+      "manager",
+      SALUT_TYPE_XMPP_CONNECTION_MANAGER,
+      G_PARAM_CONSTRUCT_ONLY |
+      G_PARAM_READWRITE |
+      G_PARAM_STATIC_NAME |
+      G_PARAM_STATIC_NICK |
+      G_PARAM_STATIC_BLURB);
+  g_object_class_install_property (object_class, PROP_XMPP_CONNECTION_MANAGER,
+      param_spec);
 }
 
 
@@ -242,12 +345,17 @@ new_tubes_channel (SalutTubesManager *fac,
   TpBaseConnection *conn;
   SalutTubesChannel *chan;
   char *object_path;
+  SalutContact *contact;
 
   g_assert (SALUT_IS_TUBES_MANAGER (fac));
 
   priv = SALUT_TUBES_MANAGER_GET_PRIVATE (fac);
   conn = (TpBaseConnection *) priv->conn;
 
+  contact = salut_contact_manager_get_contact (priv->contact_manager, handle);
+  if (contact == NULL)
+    return NULL;
+
   object_path = g_strdup_printf ("%s/TubesChannel%u", conn->object_path,
       handle);
 
@@ -256,6 +364,8 @@ new_tubes_channel (SalutTubesManager *fac,
                        "object-path", object_path,
                        "handle", handle,
                        "handle-type", TP_HANDLE_TYPE_CONTACT,
+                       "contact", contact,
+                       "xmpp-connection-manager", priv->xmpp_connection_manager,
                        NULL);
 
   DEBUG ("object path %s", object_path);
@@ -422,14 +532,33 @@ salut_tubes_manager_handle_tube_request (
 SalutTubesManager *
 salut_tubes_manager_new (
     SalutConnection *conn,
-    SalutContactManager *contact_manager)
+    SalutContactManager *contact_manager,
+    SalutXmppConnectionManager *xmpp_connection_manager)
 {
+  SalutTubesManager *ret = NULL;
+  SalutTubesManagerPrivate *priv;
+
   g_return_val_if_fail (SALUT_IS_CONNECTION (conn), NULL);
+  g_return_val_if_fail (SALUT_IS_CONTACT_MANAGER (contact_manager), NULL);
+  g_return_val_if_fail (
+      SALUT_IS_XMPP_CONNECTION_MANAGER (xmpp_connection_manager), NULL);
 
-  return g_object_new (
+  ret = g_object_new (
       SALUT_TYPE_TUBES_MANAGER,
       "connection", conn,
+      "contact-manager", contact_manager,
+      "xmpp-connection-manager", xmpp_connection_manager,
       NULL);
+
+  priv = SALUT_TUBES_MANAGER_GET_PRIVATE (ret);
+
+  salut_xmpp_connection_manager_add_stanza_filter (
+      priv->xmpp_connection_manager, NULL,
+      iq_tube_request_filter, iq_tube_request_cb, ret);
+
+  priv->conn = conn;
+
+  return ret;
 }
 
 static void
diff --git a/src/salut-tubes-manager.h b/src/salut-tubes-manager.h
index 1bf0ce1..462e213 100644
--- a/src/salut-tubes-manager.h
+++ b/src/salut-tubes-manager.h
@@ -25,6 +25,7 @@
 #include <telepathy-glib/base-connection.h>
 #include "salut-connection.h"
 #include "salut-contact-manager.h"
+#include "salut-xmpp-connection-manager.h"
 #include "salut-tubes-channel.h"
 
 G_BEGIN_DECLS
@@ -63,11 +64,8 @@ GType salut_tubes_manager_get_type (void);
 
 SalutTubesManager * salut_tubes_manager_new (
     SalutConnection *conn,
-    SalutContactManager *contact_manager);
-
-void salut_tubes_manager_handle_tube_request (
-    SalutTubesManager *self, GibberBytestreamIface *bytestream,
-    TpHandle handle, const gchar *stream_id, GibberXmppStanza *msg);
+    SalutContactManager *contact_manager,
+    SalutXmppConnectionManager *xmpp_connection_manager);
 
 G_END_DECLS
 
-- 
1.5.6.5




More information about the Telepathy-commits mailing list