[telepathy-gabble/master] ft-manager: implement ContactCapability
Guillaume Desmottes
guillaume.desmottes at collabora.co.uk
Fri Apr 17 07:00:33 PDT 2009
---
src/ft-manager.c | 131 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 130 insertions(+), 1 deletions(-)
diff --git a/src/ft-manager.c b/src/ft-manager.c
index 327b360..4bfd17d 100644
--- a/src/ft-manager.c
+++ b/src/ft-manager.c
@@ -34,6 +34,7 @@
#include "error.h"
#include "gabble-signals-marshal.h"
#include "namespaces.h"
+#include "presence-cache.h"
#include "util.h"
#include "ft-channel.h"
@@ -41,6 +42,7 @@
#include <telepathy-glib/base-connection.h>
#include <telepathy-glib/channel-factory-iface.h>
#include <telepathy-glib/channel-manager.h>
+#include <telepathy-glib/gtypes.h>
#include <telepathy-glib/interfaces.h>
#include <telepathy-glib/dbus.h>
#include <telepathy-glib/util.h>
@@ -54,10 +56,14 @@ channel_manager_iface_init (gpointer, gpointer);
static void gabble_ft_manager_channel_created (GabbleFtManager *mgr,
GabbleFileTransferChannel *chan, gpointer request_token);
+static void caps_channel_manager_iface_init (gpointer g_iface,
+ gpointer iface_data);
+
G_DEFINE_TYPE_WITH_CODE (GabbleFtManager, gabble_ft_manager, G_TYPE_OBJECT,
G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_MANAGER,
channel_manager_iface_init);
- G_IMPLEMENT_INTERFACE (GABBLE_TYPE_CAPS_CHANNEL_MANAGER, NULL));
+ G_IMPLEMENT_INTERFACE (GABBLE_TYPE_CAPS_CHANNEL_MANAGER,
+ caps_channel_manager_iface_init));
/* properties */
enum
@@ -591,3 +597,126 @@ gabble_ft_manager_get_tmp_dir (GabbleFtManager *self)
return self->priv->tmp_dir;
}
+
+static void
+add_file_transfer_channel_class (GPtrArray *arr,
+ TpHandle handle)
+{
+ GValue monster = {0, };
+ GHashTable *fixed_properties;
+ GValue *channel_type_value;
+ GValue *target_handle_type_value;
+
+ g_assert (handle != 0);
+
+ g_value_init (&monster, TP_STRUCT_TYPE_REQUESTABLE_CHANNEL_CLASS);
+ g_value_take_boxed (&monster,
+ dbus_g_type_specialized_construct (
+ TP_STRUCT_TYPE_REQUESTABLE_CHANNEL_CLASS));
+
+ fixed_properties = g_hash_table_new_full (g_str_hash, g_str_equal, NULL,
+ (GDestroyNotify) tp_g_value_slice_free);
+
+ channel_type_value = tp_g_value_slice_new (G_TYPE_STRING);
+ g_value_set_static_string (channel_type_value,
+ TP_IFACE_CHANNEL_TYPE_FILE_TRANSFER);
+ g_hash_table_insert (fixed_properties, TP_IFACE_CHANNEL ".ChannelType",
+ channel_type_value);
+
+ target_handle_type_value = tp_g_value_slice_new (G_TYPE_UINT);
+ g_value_set_uint (target_handle_type_value, TP_HANDLE_TYPE_CONTACT);
+ g_hash_table_insert (fixed_properties, TP_IFACE_CHANNEL ".TargetHandleType",
+ target_handle_type_value);
+
+ dbus_g_type_struct_set (&monster,
+ 0, fixed_properties,
+ 1, file_transfer_channel_allowed_properties,
+ G_MAXUINT);
+
+ g_hash_table_destroy (fixed_properties);
+
+ g_ptr_array_add (arr, g_value_get_boxed (&monster));
+}
+
+static void
+gabble_ft_manager_get_contact_caps (GabbleCapsChannelManager *manager,
+ GabbleConnection *conn,
+ TpHandle handle,
+ GPtrArray *arr)
+{
+ TpBaseConnection *base = (TpBaseConnection *) conn;
+ GabblePresence *presence;
+
+ g_assert (handle != 0);
+
+ if (handle == base->self_handle)
+ {
+ /* We support file transfer */
+ add_file_transfer_channel_class (arr, handle);
+ return;
+ }
+
+ presence = gabble_presence_cache_get (conn->presence_cache, handle);
+ if (presence == NULL)
+ return;
+
+ if (g_hash_table_lookup (presence->per_channel_manager_caps, manager) == NULL)
+ return;
+
+ /* FT is supported */
+ add_file_transfer_channel_class (arr, handle);
+}
+
+static gpointer
+gabble_ft_manager_parse_caps (GabbleCapsChannelManager *manager,
+ LmMessageNode *children)
+{
+ LmMessageNode *child;
+
+ for (child = children; NULL != child; child = child->next)
+ {
+ const gchar *var;
+
+ if (0 != strcmp (child->name, "feature"))
+ continue;
+
+ var = lm_message_node_get_attribute (child, "var");
+
+ if (NULL == var)
+ continue;
+
+ if (!tp_strdiff (var, NS_FILE_TRANSFER))
+ return GUINT_TO_POINTER (TRUE);
+ }
+
+ return NULL;
+}
+
+static void
+gabble_ft_manager_copy_caps (GabbleCapsChannelManager *manager,
+ gpointer *specific_caps_out,
+ gpointer specific_caps_in)
+{
+ *specific_caps_out = specific_caps_in;
+}
+
+static gboolean
+gabble_ft_manager_caps_diff (GabbleCapsChannelManager *manager,
+ TpHandle handle,
+ gpointer specific_old_caps,
+ gpointer specific_new_caps)
+{
+ return specific_old_caps != specific_new_caps;
+}
+
+static void
+caps_channel_manager_iface_init (gpointer g_iface,
+ gpointer iface_data)
+{
+ GabbleCapsChannelManagerIface *iface = g_iface;
+
+ iface->get_contact_caps = gabble_ft_manager_get_contact_caps;
+ iface->parse_caps = gabble_ft_manager_parse_caps;
+ iface->copy_caps = gabble_ft_manager_copy_caps;
+ iface->caps_diff = gabble_ft_manager_caps_diff;
+}
--
1.5.6.5
More information about the telepathy-commits
mailing list