[Telepathy-commits] [telepathy-salut/master] Open a tube on the remote side when the initiator request it

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


20080516164750-a41c0-f2f3ad2cf579a1fa146dbdfe2b6db892f48ff603.gz
---
 src/salut-tubes-channel.c |   31 +++++++++++-
 src/salut-tubes-channel.h |    4 ++
 src/salut-tubes-manager.c |  126 +++++++++++++++++++++++++++++++++++++-------
 3 files changed, 140 insertions(+), 21 deletions(-)

diff --git a/src/salut-tubes-channel.c b/src/salut-tubes-channel.c
index ea9e303..8883c23 100644
--- a/src/salut-tubes-channel.c
+++ b/src/salut-tubes-channel.c
@@ -921,6 +921,28 @@ tubes_muc_message_received (SalutTubesChannel *self,
   g_hash_table_destroy (old_dbus_tubes);
 }
 
+/* 1-1 message */
+void
+tubes_message_received (SalutTubesChannel *self,
+                        const gchar *service,
+                        TpTubeType tube_type,
+                        TpHandle initiator_handle,
+                        GHashTable *parameters,
+                        guint tube_id)
+{
+  SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self);
+
+  SalutTubeIface *tube;
+
+  /* do we already know this tube? */
+  tube = g_hash_table_lookup (priv->tubes, GUINT_TO_POINTER (tube_id));
+  if (tube == NULL)
+    {
+      tube = create_new_tube (self, tube_type, initiator_handle, service,
+        parameters, tube_id, NULL);
+    }
+}
+
 static void
 muc_connection_new_senders_cb (GibberMucConnection *conn,
                                GArray *senders,
@@ -1761,6 +1783,8 @@ iq_reply_cb (GibberIqHelper *helper,
              gpointer user_data)
 {
   /*
+  SalutTubeIface *tube = (SalutTubeIface *) user_data;
+
   SalutTubesChannel *self = (SalutTubesChannel *) user_data;
   SalutTubesChannelPrivate *priv = SALUT_TUBES_CHANNEL_GET_PRIVATE (self);
   */
@@ -1812,6 +1836,8 @@ _send_channel_iq_tube (gpointer key,
       const gchar *jid_from, *jid_to;
       TpHandleRepoIface *contact_repo;
 
+      gchar *tube_id_str = g_strdup_printf ("%d", tube_id);
+
       contact_repo = tp_base_connection_get_handles (
          (TpBaseConnection*) priv->conn, TP_HANDLE_TYPE_CONTACT);
 
@@ -1825,6 +1851,7 @@ _send_channel_iq_tube (gpointer key,
             GIBBER_NODE_XMLNS, GIBBER_TELEPATHY_NS_TUBES,
             GIBBER_NODE_ATTRIBUTE, "type", "stream",
             GIBBER_NODE_ATTRIBUTE, "service", service,
+            GIBBER_NODE_ATTRIBUTE, "id", tube_id_str,
             GIBBER_NODE, "parameters",
               GIBBER_NODE, "parameter",
                 GIBBER_NODE_ATTRIBUTE, "name", "path",
@@ -1848,11 +1875,13 @@ _send_channel_iq_tube (gpointer key,
         }
 
       if (!gibber_iq_helper_send_with_reply (priv->iq_helper, stanza,
-          iq_reply_cb, G_OBJECT(self), self, &error))
+          iq_reply_cb, G_OBJECT(self), tube, &error))
         {
           DEBUG ("ERROR: '%s'", error->message);
           g_error_free (error);
         }
+
+      g_free (tube_id_str);
     }
 
   g_free (service);
diff --git a/src/salut-tubes-channel.h b/src/salut-tubes-channel.h
index 3d8e85f..932f6f7 100644
--- a/src/salut-tubes-channel.h
+++ b/src/salut-tubes-channel.h
@@ -71,6 +71,10 @@ void salut_tubes_channel_bytestream_offered (SalutTubesChannel *chanel,
 void tubes_muc_message_received (SalutTubesChannel *channel,
     const gchar *sender, GibberXmppStanza *stanza);
 
+void tubes_message_received (SalutTubesChannel *self,
+    const gchar *service, TpTubeType tube_type, TpHandle initiator_handle,
+    GHashTable *parameters, guint tube_id);
+
 G_END_DECLS
 
 #endif /* #ifndef __SALUT_TUBES_CHANNEL_H__*/
diff --git a/src/salut-tubes-manager.c b/src/salut-tubes-manager.c
index 2eba88a..e577700 100644
--- a/src/salut-tubes-manager.c
+++ b/src/salut-tubes-manager.c
@@ -36,6 +36,7 @@
 #include "salut-tubes-channel.h"
 #include "salut-muc-manager.h"
 #include "salut-muc-channel.h"
+#include "salut-util.h"
 #include <gibber/gibber-namespaces.h>
 #include <gibber/gibber-iq-helper.h>
 #include <telepathy-glib/interfaces.h>
@@ -121,36 +122,100 @@ iq_tube_request_filter (SalutXmppConnectionManager *xcm,
                  GIBBER_TELEPATHY_NS_TUBES) != NULL);
 }
 
+/* similar to the same function in salut-tubes-channel.c but extract
+ * information from a 1-1 <iq> message */
 static gboolean
-iq_tube_request_parse (GibberXmppStanza *stanza,
-                       const gchar **from,
-                       const gchar **tube_type,
-                       const gchar **id)
+extract_tube_information (TpHandleRepoIface *contact_repo,
+                          GibberXmppStanza *stanza,
+                          TpTubeType *type,
+                          TpHandle *initiator_handle,
+                          const gchar **service,
+                          GHashTable **parameters,
+                          guint *tube_id)
 {
   GibberXmppNode *iq;
-  GibberXmppNode *tube;
+  GibberXmppNode *tube_node;
 
   iq = stanza->node;
 
-  *from = gibber_xmpp_node_get_attribute (stanza->node, "from");
-  if (*from == NULL)
+  if (initiator_handle != NULL)
     {
-      DEBUG ("got a message without a from field");
-      return FALSE;
+      const gchar *from;
+      from = gibber_xmpp_node_get_attribute (stanza->node, "from");
+      if (from == NULL)
+        {
+          DEBUG ("got a message without a from field");
+          return FALSE;
+        }
+      *initiator_handle = tp_handle_ensure (contact_repo, from, NULL,
+          NULL);
+
+      if (*initiator_handle == 0)
+        {
+          DEBUG ("invalid initiator ID %s", from);
+          return FALSE;
+        }
     }
 
-  tube = gibber_xmpp_node_get_child_ns (iq, "tube",
+  tube_node = gibber_xmpp_node_get_child_ns (iq, "tube",
       GIBBER_TELEPATHY_NS_TUBES);
-  if (tube == NULL)
+  if (tube_node == NULL)
     {
       DEBUG ("The <iq> does not have a <tube>");
       return FALSE;
     }
 
-  *id = gibber_xmpp_node_get_attribute (iq, "id");
+  if (type != NULL)
+    {
+      const gchar *tube_type;
+
+      tube_type = gibber_xmpp_node_get_attribute (tube_node, "type");
+      if (g_str_equal (tube_type, "stream"))
+        *type = TP_TUBE_TYPE_STREAM;
+      else if (g_str_equal (tube_type, "dbus"))
+        *type = TP_TUBE_TYPE_DBUS;
+      else
+        {
+          DEBUG ("The <iq><tube> does not have a correct type=.");
+          return FALSE;
+        }
+    }
 
-  *tube_type = "";
+  if (service != NULL)
+    {
+      *service = gibber_xmpp_node_get_attribute (tube_node, "service");
+    }
+
+  if (parameters != NULL)
+    {
+      GibberXmppNode *node;
 
+      node = gibber_xmpp_node_get_child (tube_node, "parameters");
+      *parameters = salut_gibber_xmpp_node_extract_properties (node,
+          "parameter");
+    }
+
+  if (tube_id != NULL)
+    {
+      const gchar *str;
+      gchar *endptr;
+      long int tmp;
+
+      str = gibber_xmpp_node_get_attribute (tube_node, "id");
+      if (str == NULL)
+        {
+          DEBUG ("no tube id in SI request");
+          return FALSE;
+        }
+
+      tmp = strtol (str, &endptr, 10);
+      if (!endptr || *endptr)
+        {
+          DEBUG ("tube id is not numeric: %s", str);
+          return FALSE;
+        }
+      *tube_id = (int) tmp;
+    }
   return TRUE;
 }
 
@@ -161,14 +226,22 @@ iq_tube_request_cb (SalutXmppConnectionManager *xcm,
                     SalutContact *contact,
                     gpointer user_data)
 {
-  /*
   SalutTubesManager *self = SALUT_TUBES_MANAGER (user_data);
-  SalutTubesManagerPrivate *priv =
-    SALUT_TUBES_MANAGER_GET_PRIVATE (self);
-  */
+  SalutTubesManagerPrivate *priv = SALUT_TUBES_MANAGER_GET_PRIVATE (self);
+  TpHandleRepoIface *contact_repo = tp_base_connection_get_handles (
+      (TpBaseConnection *) priv->conn, TP_HANDLE_TYPE_CONTACT);
+
   GibberXmppNode *close;
   GibberXmppStanza *reply;
-  const gchar *from, *tube_type, *id;
+
+  /* tube informations */
+  const gchar *service;
+  TpTubeType tube_type;
+  TpHandle initiator_handle;
+  GHashTable *parameters;
+  guint tube_id;
+
+  SalutTubesChannel *chan;
 
   /* after this point, the message is for us, so in all cases we either handle
    * it or send an error reply */
@@ -181,7 +254,8 @@ iq_tube_request_cb (SalutXmppConnectionManager *xcm,
       return;
     }
 
-  if (!iq_tube_request_parse (stanza, &from, &tube_type, &id))
+  if (!extract_tube_information (contact_repo, stanza, &tube_type,
+          &initiator_handle, &service, &parameters, &tube_id))
     {
       GibberXmppStanza *reply;
 
@@ -193,7 +267,19 @@ iq_tube_request_cb (SalutXmppConnectionManager *xcm,
       return;
     }
 
-  DEBUG ("received a tube request of type %s, id %s", tube_type, id);
+  DEBUG ("received a tube request of type %d, tube_id %d", tube_type, tube_id);
+
+  chan = g_hash_table_lookup (priv->channels,
+      GUINT_TO_POINTER (initiator_handle));
+  if (chan == NULL)
+    {
+      chan = new_tubes_channel (self, initiator_handle);
+      tp_channel_factory_iface_emit_new_channel (self,
+          (TpChannelIface *) chan, NULL);
+    }
+
+  tubes_message_received (chan, service, tube_type, initiator_handle,
+      parameters, tube_id);
 
   reply = gibber_iq_helper_new_result_reply (stanza);
   gibber_xmpp_connection_send (conn, reply, NULL);
-- 
1.5.6.5




More information about the Telepathy-commits mailing list