[Telepathy-commits] [telepathy-gabble/master] Parse the caps stanza for tubes in the tube factory, using the channel manager uinterface
Alban Crequy
alban.crequy at collabora.co.uk
Fri Dec 5 09:42:33 PST 2008
---
src/channel-manager.c | 4 +-
src/channel-manager.h | 5 +-
src/connection.c | 6 +-
src/presence-cache.c | 77 +++---------
src/presence-cache.h | 2 +-
src/presence.c | 69 ++---------
src/presence.h | 3 -
src/private-tubes-factory.c | 288 ++++++++++++++++++++++++++++++++-----------
tests/test-presence.c | 4 +-
9 files changed, 255 insertions(+), 203 deletions(-)
diff --git a/src/channel-manager.c b/src/channel-manager.c
index fd6808f..f155485 100644
--- a/src/channel-manager.c
+++ b/src/channel-manager.c
@@ -365,7 +365,7 @@ void gabble_channel_manager_get_contact_capabilities (
gpointer gabble_channel_manager_parse_capabilities (
GabbleChannelManager *manager,
- GabbleConnection *conn)
+ LmMessageNode *child)
{
GabbleChannelManagerIface *iface = GABBLE_CHANNEL_MANAGER_GET_INTERFACE (
manager);
@@ -373,7 +373,7 @@ gpointer gabble_channel_manager_parse_capabilities (
if (method != NULL)
{
- return method (manager, conn);
+ return method (manager, child);
}
/* ... else assume there is not caps for this kind of channels */
return NULL;
diff --git a/src/channel-manager.h b/src/channel-manager.h
index 7fcff10..fbc7960 100644
--- a/src/channel-manager.h
+++ b/src/channel-manager.h
@@ -24,6 +24,7 @@
#define GABBLE_CHANNEL_MANAGER_H
#include <glib-object.h>
+#include <loudmouth/loudmouth.h>
#include <telepathy-glib/handle.h>
#include "exportable-channel.h"
@@ -56,7 +57,7 @@ typedef void (*GabbleChannelManagerGetContactCapsFunc) (
GPtrArray *arr);
typedef gpointer (*GabbleChannelManagerParseCapsFunc) (
- GabbleChannelManager *manager, GabbleConnection *conn);
+ GabbleChannelManager *manager, LmMessageNode *children);
typedef void (*GabbleChannelManagerFreeCapsFunc) (
GabbleChannelManager *manager, gpointer *specific_caps);
@@ -73,7 +74,7 @@ void gabble_channel_manager_get_contact_capabilities (
GPtrArray *arr);
gpointer gabble_channel_manager_parse_capabilities (
- GabbleChannelManager *manager, GabbleConnection *conn);
+ GabbleChannelManager *manager, LmMessageNode *children);
void gabble_channel_manager_free_capabilities (GabbleChannelManager *manager,
gpointer *specific_caps);
diff --git a/src/connection.c b/src/connection.c
index 9c926c9..d5bbec6 100644
--- a/src/connection.c
+++ b/src/connection.c
@@ -1927,7 +1927,7 @@ connection_auth_cb (LmConnection *lmconn,
/* set initial capabilities */
gabble_presence_set_capabilities (conn->self_presence, priv->resource,
- capabilities_get_initial_caps (), NULL, NULL, NULL, priv->caps_serial++);
+ capabilities_get_initial_caps (), NULL, priv->caps_serial++);
if (!gabble_disco_request_with_timeout (conn->disco, GABBLE_DISCO_TYPE_INFO,
priv->stream_server, NULL,
@@ -2214,7 +2214,7 @@ gabble_connection_advertise_capabilities (TpSvcConnectionInterfaceCapabilities *
{
DEBUG ("before != after, changing");
gabble_presence_set_capabilities (pres, priv->resource, caps, NULL,
- NULL, NULL, priv->caps_serial++);
+ priv->caps_serial++);
DEBUG ("set caps: %x", pres->caps);
}
@@ -2961,7 +2961,7 @@ gabble_connection_ensure_capabilities (GabbleConnection *self,
GError *error = NULL;
gabble_presence_set_capabilities (self->self_presence,
- priv->resource, new_caps, NULL, NULL, NULL, priv->caps_serial++);
+ priv->resource, new_caps, NULL, priv->caps_serial++);
if (!_gabble_connection_signal_own_presence (self, &error))
DEBUG ("error sending presence: %s", error->message);
diff --git a/src/presence-cache.c b/src/presence-cache.c
index 4670936..978e9c1 100644
--- a/src/presence-cache.c
+++ b/src/presence-cache.c
@@ -200,8 +200,6 @@ struct _CapabilityInfo
* received */
gboolean caps_set;
GabblePresenceCapabilities caps;
- GHashTable *stream_tube_caps;
- GHashTable *dbus_tube_caps;
/* channel factory -> specific caps */
GHashTable *per_channel_factory_caps;
@@ -237,7 +235,6 @@ capability_info_free (CapabilityInfo *info)
static guint
capability_info_recvd (GabblePresenceCache *cache, const gchar *node,
TpHandle handle, GabblePresenceCapabilities caps,
- GHashTable *stream_tube_caps, GHashTable *dbus_tube_caps,
GHashTable *per_channel_factory_caps, guint trust_inc)
{
CapabilityInfo *info = capability_info_get (cache, node);
@@ -251,8 +248,6 @@ capability_info_recvd (GabblePresenceCache *cache, const gchar *node,
*/
tp_intset_clear (info->guys);
info->caps = caps;
- info->stream_tube_caps = stream_tube_caps;
- info->dbus_tube_caps = dbus_tube_caps;
info->per_channel_factory_caps = per_channel_factory_caps;
info->trust = 0;
info->caps_set = TRUE;
@@ -752,15 +747,23 @@ update_specific_caps_helper (gpointer key, gpointer value, gpointer user_data)
GHashTable *table_out = user_data;
GabbleChannelManager *manager = GABBLE_CHANNEL_MANAGER (key);
gpointer out;
- gabble_channel_manager_copy_capabilities (manager, &out, value);
- g_hash_table_insert (table_out, key, out);
+
+ out = g_hash_table_lookup (table_out, key);
+ if (out == NULL)
+ {
+ gabble_channel_manager_copy_capabilities (manager, &out, value);
+ g_hash_table_insert (table_out, key, out);
+ }
+ else
+ {
+ gabble_channel_manager_update_capabilities (manager, out, value);
+ }
}
void
gabble_presence_cache_update_specific_cache (
- GHashTable **out, GHashTable *in)
+ GHashTable *out, GHashTable *in)
{
- *out = g_hash_table_new (NULL, NULL);
g_hash_table_foreach (in, update_specific_caps_helper,
out);
}
@@ -782,8 +785,6 @@ _caps_disco_cb (GabbleDisco *disco,
TpHandleRepoIface *contact_repo;
gchar *full_jid = NULL;
GabblePresenceCapabilities caps = 0;
- GHashTable *stream_tube_caps;
- GHashTable *dbus_tube_caps;
GHashTable *per_channel_factory_caps;
guint trust, trust_inc;
TpHandle handle = 0;
@@ -846,10 +847,6 @@ _caps_disco_cb (GabbleDisco *disco,
goto OUT;
}
- stream_tube_caps = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
- NULL);
- dbus_tube_caps = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
- NULL);
per_channel_factory_caps = g_hash_table_new (NULL, NULL);
/* parsing for Connection.Interface.ContactCapabilities.DRAFT */
@@ -860,7 +857,7 @@ _caps_disco_cb (GabbleDisco *disco,
g_ptr_array_index (priv->conn->channel_managers, j));
factory_caps = gabble_channel_manager_parse_capabilities
- (manager, priv->conn);
+ (manager, query_result->children);
if (factory_caps != NULL)
g_hash_table_insert (per_channel_factory_caps, manager, factory_caps);
}
@@ -904,36 +901,13 @@ _caps_disco_cb (GabbleDisco *disco,
!tp_strdiff (var, NS_OLPC_CURRENT_ACTIVITY "+notify") ||
!tp_strdiff (var, NS_OLPC_ACTIVITY_PROPS "+notify"))
caps |= PRESENCE_CAP_OLPC_1;
- else if (g_str_has_prefix (var, NS_TUBES "/"))
- {
- /* http://telepathy.freedesktop.org/xmpp/tubes/$type/$service */
- var += strlen (NS_TUBES "/");
- if (g_str_has_prefix (var, "stream/"))
- {
- gchar *service;
- var += strlen ("stream/");
- service = g_strdup (var);
- g_hash_table_insert (stream_tube_caps, service, NULL);
- }
- else if (g_str_has_prefix (var, "dbus/"))
- {
- gchar *service;
- var += strlen ("dbus/");
- service = g_strdup (var);
- g_hash_table_insert (dbus_tube_caps, service, NULL);
- }
- }
}
handle = tp_handle_ensure (contact_repo, jid, NULL, NULL);
if (handle == 0)
{
DEBUG ("Ignoring presence from invalid JID %s", jid);
- g_hash_table_destroy (stream_tube_caps);
- g_hash_table_destroy (dbus_tube_caps);
gabble_presence_cache_free_specific_cache (per_channel_factory_caps);
- stream_tube_caps = NULL;
- dbus_tube_caps = NULL;
per_channel_factory_caps = NULL;
goto OUT;
}
@@ -953,11 +927,7 @@ _caps_disco_cb (GabbleDisco *disco,
if (NULL == waiter_self)
{
DEBUG ("Ignoring non requested disco reply");
- g_hash_table_destroy (stream_tube_caps);
- g_hash_table_destroy (dbus_tube_caps);
gabble_presence_cache_free_specific_cache (per_channel_factory_caps);
- stream_tube_caps = NULL;
- dbus_tube_caps = NULL;
per_channel_factory_caps = NULL;
goto OUT;
}
@@ -977,8 +947,7 @@ _caps_disco_cb (GabbleDisco *disco,
if (g_str_equal (waiter_self->ver, computed_hash))
{
trust = capability_info_recvd (cache, node, handle, caps,
- stream_tube_caps, dbus_tube_caps, per_channel_factory_caps,
- trust_inc);
+ per_channel_factory_caps, trust_inc);
}
else
{
@@ -987,28 +956,20 @@ _caps_disco_cb (GabbleDisco *disco,
"our hash '%s'.", waiter_self->ver, computed_hash);
trust = 0;
bad_hash = TRUE;
- g_hash_table_destroy (stream_tube_caps);
- g_hash_table_destroy (dbus_tube_caps);
gabble_presence_cache_free_specific_cache (per_channel_factory_caps);
- stream_tube_caps = NULL;
- dbus_tube_caps = NULL;
per_channel_factory_caps = NULL;
}
}
else
{
trust_inc = 1;
- trust = capability_info_recvd (cache, node, handle, caps, NULL, NULL,
- NULL, trust_inc);
+ trust = capability_info_recvd (cache, node, handle, caps, NULL,
+ trust_inc);
/* Do not allow tubes caps if the contact does not observe XEP-0115
* version 1.5: we don't need to bother being compatible with both version
* 1.3 and tubes caps */
- g_hash_table_destroy (stream_tube_caps);
- g_hash_table_destroy (dbus_tube_caps);
gabble_presence_cache_free_specific_cache (per_channel_factory_caps);
- stream_tube_caps = NULL;
- dbus_tube_caps = NULL;
per_channel_factory_caps = NULL;
}
@@ -1037,8 +998,7 @@ _caps_disco_cb (GabbleDisco *disco,
"%d (save_caps %d)",
waiter->handle, handle, jid, caps, save_caps);
gabble_presence_set_capabilities (presence, waiter->resource,
- caps, stream_tube_caps, dbus_tube_caps,
- per_channel_factory_caps, waiter->serial);
+ caps, per_channel_factory_caps, waiter->serial);
DEBUG ("caps for %d (thanks to %d %s) now %d", waiter->handle,
handle, jid, presence->caps);
g_signal_emit (cache, signals[CAPABILITIES_UPDATE], 0,
@@ -1134,8 +1094,7 @@ _process_caps_uri (GabblePresenceCache *cache,
if (presence)
{
gabble_presence_set_capabilities (presence, resource,
- info->caps, info->stream_tube_caps, info->dbus_tube_caps,
- info->per_channel_factory_caps, serial);
+ info->caps, info->per_channel_factory_caps, serial);
DEBUG ("caps for %d (%s) now %d", handle, from, presence->caps);
}
else
diff --git a/src/presence-cache.h b/src/presence-cache.h
index 82ce987..618ab57 100644
--- a/src/presence-cache.h
+++ b/src/presence-cache.h
@@ -88,7 +88,7 @@ void gabble_presence_cache_free_specific_cache (
GHashTable *per_channel_factory_caps);
void gabble_presence_cache_copy_specific_cache (GHashTable **out,
GHashTable *in);
-void gabble_presence_cache_update_specific_cache (GHashTable **out,
+void gabble_presence_cache_update_specific_cache (GHashTable *out,
GHashTable *in);
G_END_DECLS
diff --git a/src/presence.c b/src/presence.c
index ef6d52c..bd9630f 100644
--- a/src/presence.c
+++ b/src/presence.c
@@ -41,8 +41,6 @@ typedef struct _Resource Resource;
struct _Resource {
gchar *name;
GabblePresenceCapabilities caps;
- GHashTable *stream_tube_caps;
- GHashTable *dbus_tube_caps;
GHashTable *per_channel_factory_caps;
guint caps_serial;
GabblePresenceId status;
@@ -62,8 +60,6 @@ _resource_new (gchar *name)
Resource *new = g_slice_new0 (Resource);
new->name = name;
new->caps = PRESENCE_CAP_NONE;
- new->stream_tube_caps = NULL;
- new->dbus_tube_caps = NULL;
new->per_channel_factory_caps = NULL;
new->status = GABBLE_PRESENCE_OFFLINE;
new->status_message = NULL;
@@ -79,10 +75,13 @@ _resource_free (Resource *resource)
{
g_free (resource->name);
g_free (resource->status_message);
- if (resource->stream_tube_caps != NULL)
- g_hash_table_destroy (resource->stream_tube_caps);
- if (resource->dbus_tube_caps != NULL)
- g_hash_table_destroy (resource->dbus_tube_caps);
+ if (resource->per_channel_factory_caps != NULL)
+ {
+ gabble_presence_cache_free_specific_cache
+ (resource->per_channel_factory_caps);
+ resource->per_channel_factory_caps = NULL;
+ }
+
g_slice_free (Resource, resource);
}
@@ -96,10 +95,12 @@ gabble_presence_finalize (GObject *object)
for (i = priv->resources; NULL != i; i = i->next)
_resource_free (i->data);
- if (presence->stream_tube_caps != NULL)
- g_hash_table_destroy (presence->stream_tube_caps);
- if (presence->dbus_tube_caps != NULL)
- g_hash_table_destroy (presence->dbus_tube_caps);
+ if (presence->per_channel_factory_caps != NULL)
+ {
+ gabble_presence_cache_free_specific_cache
+ (presence->per_channel_factory_caps);
+ presence->per_channel_factory_caps = NULL;
+ }
g_slist_free (priv->resources);
g_free (presence->nickname);
@@ -198,8 +199,6 @@ void
gabble_presence_set_capabilities (GabblePresence *presence,
const gchar *resource,
GabblePresenceCapabilities caps,
- GHashTable *stream_tube_caps,
- GHashTable *dbus_tube_caps,
GHashTable *per_channel_factory_caps,
guint serial)
{
@@ -207,26 +206,12 @@ gabble_presence_set_capabilities (GabblePresence *presence,
GSList *i;
presence->caps = 0;
- if (presence->stream_tube_caps != NULL)
- {
- g_hash_table_destroy (presence->stream_tube_caps);
- presence->per_channel_factory_caps = NULL;
- }
- if (presence->dbus_tube_caps != NULL)
- {
- g_hash_table_destroy (presence->dbus_tube_caps);
- presence->per_channel_factory_caps = NULL;
- }
if (presence->per_channel_factory_caps != NULL)
{
gabble_presence_cache_free_specific_cache
(presence->per_channel_factory_caps);
presence->per_channel_factory_caps = NULL;
}
- presence->stream_tube_caps = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, NULL);
- presence->dbus_tube_caps = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, NULL);
presence->per_channel_factory_caps = g_hash_table_new (NULL, NULL);
DEBUG ("about to add caps %u to resource %s with serial %u", caps, resource,
@@ -254,32 +239,12 @@ gabble_presence_set_capabilities (GabblePresence *presence,
tmp->caps |= caps;
DEBUG ("resource %s caps now %u", resource, tmp->caps);
- if (tmp->stream_tube_caps != NULL)
- {
- g_hash_table_destroy (tmp->stream_tube_caps);
- tmp->stream_tube_caps = NULL;
- }
- if (tmp->dbus_tube_caps != NULL)
- {
- g_hash_table_destroy (tmp->dbus_tube_caps);
- tmp->dbus_tube_caps = NULL;
- }
if (tmp->per_channel_factory_caps != NULL)
{
gabble_presence_cache_free_specific_cache
(tmp->per_channel_factory_caps);
tmp->per_channel_factory_caps = NULL;
}
- tmp->stream_tube_caps = g_hash_table_new_full (g_str_hash,
- g_str_equal, g_free, NULL);
- tmp->dbus_tube_caps = g_hash_table_new_full (g_str_hash,
- g_str_equal, g_free, NULL);
- if (stream_tube_caps != NULL)
- tp_g_hash_table_update (tmp->stream_tube_caps,
- stream_tube_caps, g_strdup, NULL);
- if (dbus_tube_caps != NULL)
- tp_g_hash_table_update (tmp->dbus_tube_caps,
- dbus_tube_caps, g_strdup, NULL);
if (per_channel_factory_caps != NULL)
gabble_presence_cache_copy_specific_cache
(&tmp->per_channel_factory_caps, per_channel_factory_caps);
@@ -288,14 +253,6 @@ gabble_presence_set_capabilities (GabblePresence *presence,
presence->caps |= tmp->caps;
- if (tmp->stream_tube_caps != NULL)
- tp_g_hash_table_update (presence->stream_tube_caps,
- tmp->stream_tube_caps, g_strdup, NULL);
-
- if (tmp->dbus_tube_caps != NULL)
- tp_g_hash_table_update (presence->dbus_tube_caps,
- tmp->dbus_tube_caps, g_strdup, NULL);
-
if (tmp->per_channel_factory_caps != NULL)
gabble_presence_cache_update_specific_cache
(presence->per_channel_factory_caps,
diff --git a/src/presence.h b/src/presence.h
index 417571e..331b029 100644
--- a/src/presence.h
+++ b/src/presence.h
@@ -56,8 +56,6 @@ typedef struct _GabblePresencePrivate GabblePresencePrivate;
struct _GabblePresence {
GObject parent;
GabblePresenceCapabilities caps;
- GHashTable *stream_tube_caps;
- GHashTable *dbus_tube_caps;
GHashTable *per_channel_factory_caps;
GabblePresenceId status;
gchar *status_message;
@@ -83,7 +81,6 @@ gboolean gabble_presence_update (GabblePresence *presence,
void gabble_presence_set_capabilities (GabblePresence *presence,
const gchar *resource, GabblePresenceCapabilities caps,
- GHashTable *stream_tube_caps, GHashTable *dbus_tube_caps,
GHashTable *per_channel_factory_caps, guint serial);
const gchar *gabble_presence_pick_resource_by_caps (GabblePresence *presence,
diff --git a/src/private-tubes-factory.c b/src/private-tubes-factory.c
index 4ba1fca..e60077e 100644
--- a/src/private-tubes-factory.c
+++ b/src/private-tubes-factory.c
@@ -87,6 +87,14 @@ struct _GabblePrivateTubesFactoryPrivate
#define GABBLE_PRIVATE_TUBES_FACTORY_GET_PRIVATE(obj) ((obj)->priv)
+typedef struct _TubesCapabilities TubesCapabilities;
+struct _TubesCapabilities
+{
+ GHashTable *stream_tube_caps;
+ GHashTable *dbus_tube_caps;
+};
+
+
static void
gabble_private_tubes_factory_init (GabblePrivateTubesFactory *self)
{
@@ -370,6 +378,9 @@ gabble_private_tubes_factory_get_contact_caps (GabbleChannelManager *manager,
TpHandle handle,
GPtrArray *arr)
{
+ TubesCapabilities *caps;
+ GHashTable *stream_tube_caps;
+ GHashTable *dbus_tube_caps;
GHashTable *fixed_properties;
GValue *channel_type_value;
GValue *target_handle_type_value;
@@ -390,91 +401,212 @@ gabble_private_tubes_factory_get_contact_caps (GabbleChannelManager *manager,
if (presence == NULL)
return;
- if (presence->stream_tube_caps == NULL)
+ if (presence->per_channel_factory_caps == NULL)
return;
- g_hash_table_iter_init (&tube_caps_iter, presence->stream_tube_caps);
- while (g_hash_table_iter_next (&tube_caps_iter, &service, &dummy))
+ caps = g_hash_table_lookup (presence->per_channel_factory_caps, manager);
+ if (caps == NULL)
+ return;
+
+ stream_tube_caps = caps->stream_tube_caps;
+ dbus_tube_caps = caps->dbus_tube_caps;
+
+ if (stream_tube_caps != NULL)
{
- GValue monster = {0, };
- g_value_init (&monster, GABBLE_STRUCT_TYPE_ENHANCED_CONTACT_CAPABILITY);
- g_value_take_boxed (&monster,
- dbus_g_type_specialized_construct (
- GABBLE_STRUCT_TYPE_ENHANCED_CONTACT_CAPABILITY));
-
- 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,
- GABBLE_IFACE_CHANNEL_TYPE_STREAM_TUBE);
- 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);
-
- target_handle_type_value = tp_g_value_slice_new (G_TYPE_STRING);
- g_value_set_string (target_handle_type_value, service);
- g_hash_table_insert (fixed_properties,
- GABBLE_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service",
- target_handle_type_value);
-
- dbus_g_type_struct_set (&monster,
- 0, handle,
- 1, fixed_properties,
- 2, tube_allowed_properties,
- G_MAXUINT);
-
- g_hash_table_destroy (fixed_properties);
-
- g_ptr_array_add (arr, g_value_get_boxed (&monster));
+ g_hash_table_iter_init (&tube_caps_iter, stream_tube_caps);
+ while (g_hash_table_iter_next (&tube_caps_iter, &service, &dummy))
+ {
+ GValue monster = {0, };
+ g_value_init (&monster, GABBLE_STRUCT_TYPE_ENHANCED_CONTACT_CAPABILITY);
+ g_value_take_boxed (&monster,
+ dbus_g_type_specialized_construct (
+ GABBLE_STRUCT_TYPE_ENHANCED_CONTACT_CAPABILITY));
+
+ 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,
+ GABBLE_IFACE_CHANNEL_TYPE_STREAM_TUBE);
+ 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);
+
+ target_handle_type_value = tp_g_value_slice_new (G_TYPE_STRING);
+ g_value_set_string (target_handle_type_value, service);
+ g_hash_table_insert (fixed_properties,
+ GABBLE_IFACE_CHANNEL_TYPE_STREAM_TUBE ".Service",
+ target_handle_type_value);
+
+ dbus_g_type_struct_set (&monster,
+ 0, handle,
+ 1, fixed_properties,
+ 2, tube_allowed_properties,
+ G_MAXUINT);
+
+ g_hash_table_destroy (fixed_properties);
+
+ g_ptr_array_add (arr, g_value_get_boxed (&monster));
+ }
}
- g_hash_table_iter_init (&tube_caps_iter, presence->dbus_tube_caps);
- while (g_hash_table_iter_next (&tube_caps_iter, &service, &dummy))
+ if (dbus_tube_caps != NULL)
{
- GValue monster = {0, };
- g_value_init (&monster, GABBLE_STRUCT_TYPE_ENHANCED_CONTACT_CAPABILITY);
- g_value_take_boxed (&monster,
- dbus_g_type_specialized_construct (
- GABBLE_STRUCT_TYPE_ENHANCED_CONTACT_CAPABILITY));
-
- 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,
- GABBLE_IFACE_CHANNEL_TYPE_DBUS_TUBE);
- 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);
-
- target_handle_type_value = tp_g_value_slice_new (G_TYPE_STRING);
- g_value_set_string (target_handle_type_value, service);
- g_hash_table_insert (fixed_properties,
- GABBLE_IFACE_CHANNEL_TYPE_DBUS_TUBE ".ServiceName",
- target_handle_type_value);
-
- dbus_g_type_struct_set (&monster,
- 0, handle,
- 1, fixed_properties,
- 2, tube_allowed_properties,
- G_MAXUINT);
-
- g_hash_table_destroy (fixed_properties);
-
- g_ptr_array_add (arr, g_value_get_boxed (&monster));
+ g_hash_table_iter_init (&tube_caps_iter, dbus_tube_caps);
+ while (g_hash_table_iter_next (&tube_caps_iter, &service, &dummy))
+ {
+ GValue monster = {0, };
+ g_value_init (&monster, GABBLE_STRUCT_TYPE_ENHANCED_CONTACT_CAPABILITY);
+ g_value_take_boxed (&monster,
+ dbus_g_type_specialized_construct (
+ GABBLE_STRUCT_TYPE_ENHANCED_CONTACT_CAPABILITY));
+
+ 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,
+ GABBLE_IFACE_CHANNEL_TYPE_DBUS_TUBE);
+ 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);
+
+ target_handle_type_value = tp_g_value_slice_new (G_TYPE_STRING);
+ g_value_set_string (target_handle_type_value, service);
+ g_hash_table_insert (fixed_properties,
+ GABBLE_IFACE_CHANNEL_TYPE_DBUS_TUBE ".ServiceName",
+ target_handle_type_value);
+
+ dbus_g_type_struct_set (&monster,
+ 0, handle,
+ 1, fixed_properties,
+ 2, tube_allowed_properties,
+ G_MAXUINT);
+
+ g_hash_table_destroy (fixed_properties);
+
+ g_ptr_array_add (arr, g_value_get_boxed (&monster));
+ }
}
}
+static gpointer
+gabble_private_tubes_factory_parse_caps (
+ GabbleChannelManager *manager,
+ LmMessageNode *children)
+{
+ LmMessageNode *child;
+ TubesCapabilities *caps;
+
+ caps = g_new0 (TubesCapabilities, 1);
+ caps->stream_tube_caps = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
+ caps->dbus_tube_caps = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
+
+ 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 (g_str_has_prefix (var, NS_TUBES "/"))
+ {
+ /* http://telepathy.freedesktop.org/xmpp/tubes/$type/$service */
+ var += strlen (NS_TUBES "/");
+ if (g_str_has_prefix (var, "stream/"))
+ {
+ gchar *service;
+ var += strlen ("stream/");
+ service = g_strdup (var);
+ g_hash_table_insert (caps->stream_tube_caps, service, NULL);
+ }
+ else if (g_str_has_prefix (var, "dbus/"))
+ {
+ gchar *service;
+ var += strlen ("dbus/");
+ service = g_strdup (var);
+ g_hash_table_insert (caps->dbus_tube_caps, service, NULL);
+ }
+ }
+ }
+
+ return caps;
+}
+
+static gpointer
+gabble_private_tubes_factory_free_caps (
+ GabbleChannelManager *manager,
+ gpointer data)
+{
+ TubesCapabilities *caps = data;
+ g_hash_table_destroy (caps->stream_tube_caps);
+ g_hash_table_destroy (caps->dbus_tube_caps);
+ g_free (caps);
+}
+
+static void
+copy_caps_helper (gpointer key, gpointer value, gpointer user_data)
+{
+ GHashTable *out = user_data;
+ gchar *str = key;
+
+ g_hash_table_insert (out, g_strdup (str), NULL);
+}
+
+static void
+gabble_private_tubes_factory_copy_caps (
+ GabbleChannelManager *manager,
+ gpointer *specific_caps_out,
+ gpointer specific_caps_in)
+{
+ TubesCapabilities *caps_in = specific_caps_in;
+ TubesCapabilities *caps_out = g_new0 (TubesCapabilities, 1);
+
+ caps_out->stream_tube_caps = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
+ g_hash_table_foreach (caps_in->stream_tube_caps, copy_caps_helper,
+ caps_out->stream_tube_caps);
+
+ caps_out->dbus_tube_caps = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, NULL);
+ g_hash_table_foreach (caps_in->dbus_tube_caps, copy_caps_helper,
+ caps_out->dbus_tube_caps);
+
+ *specific_caps_out = caps_out;
+}
+
+static void
+gabble_private_tubes_factory_update_caps (
+ GabbleChannelManager *manager,
+ gpointer *specific_caps_out,
+ gpointer specific_caps_in)
+{
+ TubesCapabilities *caps_out = specific_caps_out;
+ TubesCapabilities *caps_in = specific_caps_in;
+
+ if (caps_in == NULL)
+ return;
+
+ tp_g_hash_table_update (caps_out->stream_tube_caps,
+ caps_out->stream_tube_caps, g_strdup, NULL);
+ tp_g_hash_table_update (caps_out->dbus_tube_caps,
+ caps_out->dbus_tube_caps, g_strdup, NULL);
+}
struct _ForeachData
{
@@ -897,6 +1029,12 @@ channel_manager_iface_init (gpointer g_iface,
GabbleChannelManagerIface *iface = g_iface;
iface->get_contact_caps = gabble_private_tubes_factory_get_contact_caps;
+ iface->parse_caps = gabble_private_tubes_factory_parse_caps;
+ iface->free_caps = gabble_private_tubes_factory_free_caps;
+ iface->copy_caps = gabble_private_tubes_factory_copy_caps;
+ iface->update_caps = gabble_private_tubes_factory_update_caps;
+
+
iface->foreach_channel = gabble_private_tubes_factory_foreach_channel;
iface->foreach_channel_class =
gabble_private_tubes_factory_foreach_channel_class;
diff --git a/tests/test-presence.c b/tests/test-presence.c
index 819e900..115c2c0 100644
--- a/tests/test-presence.c
+++ b/tests/test-presence.c
@@ -109,7 +109,7 @@ int main (int argc, char **argv)
g_assert (FALSE == gabble_presence_update (presence, "bar",
GABBLE_PRESENCE_AVAILABLE, "dingoes", -1));
gabble_presence_set_capabilities (presence, "bar",
- PRESENCE_CAP_GOOGLE_VOICE, NULL, NULL, NULL, 0);
+ PRESENCE_CAP_GOOGLE_VOICE, NULL, 0);
dump = gabble_presence_dump (presence);
g_assert (0 == strcmp (dump,
@@ -138,7 +138,7 @@ int main (int argc, char **argv)
/* give voice cap to first resource */
gabble_presence_set_capabilities (presence, "foo",
- PRESENCE_CAP_GOOGLE_VOICE, NULL, NULL, NULL, 0);
+ PRESENCE_CAP_GOOGLE_VOICE, NULL, 0);
/* resource has voice cap */
resource = gabble_presence_pick_resource_by_caps (presence,
--
1.5.6.5
More information about the Telepathy-commits
mailing list