diff options
author | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2011-09-28 18:58:10 +0100 |
---|---|---|
committer | Jonny Lamb <jonny.lamb@collabora.co.uk> | 2011-09-28 18:58:10 +0100 |
commit | a64cd72472d48ad8e88bfebe5e6046f02d4b5c93 (patch) | |
tree | 3a6c29cc5719c0b20f86fc15732d11b3e39556f1 /src | |
parent | 5f1ad2c76f43842856fb01a2dc51648a42f24284 (diff) | |
parent | 9c86f446c6a00142c373aae1fa357f5c00f0f2c6 (diff) |
Merge branch 'moar-caps'
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/auth-manager.c | 2 | ||||
-rw-r--r-- | src/capabilities.c | 2 | ||||
-rw-r--r-- | src/capabilities.h | 74 | ||||
-rw-r--r-- | src/caps-channel-manager.c | 8 | ||||
-rw-r--r-- | src/caps-channel-manager.h | 105 | ||||
-rw-r--r-- | src/caps-hash.c | 7 | ||||
-rw-r--r-- | src/connection.c | 329 | ||||
-rw-r--r-- | src/connection.h | 4 | ||||
-rw-r--r-- | src/ft-manager.c | 5 | ||||
-rw-r--r-- | src/im-factory.c | 2 | ||||
-rw-r--r-- | src/jingle-session.c | 2 | ||||
-rw-r--r-- | src/legacy-caps.h | 2 | ||||
-rw-r--r-- | src/media-factory.c | 5 | ||||
-rw-r--r-- | src/muc-factory.c | 2 | ||||
-rw-r--r-- | src/presence-cache.c | 94 | ||||
-rw-r--r-- | src/presence-cache.h | 9 | ||||
-rw-r--r-- | src/presence.c | 67 | ||||
-rw-r--r-- | src/presence.h | 4 | ||||
-rw-r--r-- | src/private-tubes-factory.c | 6 | ||||
-rw-r--r-- | src/roomlist-manager.c | 2 | ||||
-rw-r--r-- | src/roster.c | 2 | ||||
-rw-r--r-- | src/search-manager.c | 2 | ||||
-rw-r--r-- | src/server-tls-manager.c | 2 |
24 files changed, 500 insertions, 241 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index c94cfaa0..0d5355ff 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -44,12 +44,12 @@ libgabble_convenience_la_SOURCES = \ call-stream.h \ call-stream.c \ $(top_srcdir)/gabble/capabilities-set.h \ - capabilities.h \ + $(top_srcdir)/gabble/capabilities.h \ capabilities.c \ $(top_srcdir)/gabble/caps-hash.h \ caps-hash.h \ caps-hash.c \ - caps-channel-manager.h \ + $(top_srcdir)/gabble/caps-channel-manager.h \ caps-channel-manager.c \ conn-aliasing.h \ conn-aliasing.c \ diff --git a/src/auth-manager.c b/src/auth-manager.c index a9424854..d9638eed 100644 --- a/src/auth-manager.c +++ b/src/auth-manager.c @@ -28,7 +28,7 @@ #define DEBUG_FLAG GABBLE_DEBUG_AUTH -#include "caps-channel-manager.h" +#include "gabble/caps-channel-manager.h" #include "server-sasl-channel.h" #include "connection.h" #include "debug.h" diff --git a/src/capabilities.c b/src/capabilities.c index b3ef11e8..d0b36e78 100644 --- a/src/capabilities.c +++ b/src/capabilities.c @@ -19,7 +19,7 @@ */ #include "config.h" -#include "capabilities.h" +#include "gabble/capabilities.h" #include <stdlib.h> #include <string.h> diff --git a/src/capabilities.h b/src/capabilities.h deleted file mode 100644 index 8e7d1a03..00000000 --- a/src/capabilities.h +++ /dev/null @@ -1,74 +0,0 @@ -/* - * capabilities.h - Connection.Interface.Capabilities constants and utilities - * Copyright (C) 2005 Collabora Ltd. - * Copyright (C) 2005 Nokia Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef __GABBLE_CAPABILITIES__H__ -#define __GABBLE_CAPABILITIES__H__ - -#include <glib-object.h> - -#include "gabble/capabilities-set.h" - -/* Pseudo-capabilities for buggy or strange implementations, represented as - * strings starting with a character not allowed in XML (the ASCII beep :-) */ -#define QUIRK_PREFIX_CHAR '\x07' -#define QUIRK_PREFIX "\x07" -/* Gabble 0.7.x with 16 <= x < 29 omits @creator on <content/> */ -#define QUIRK_OMITS_CONTENT_CREATORS "\x07omits-content-creators" -/* The Google Webmail client doesn't support some features */ -#define QUIRK_GOOGLE_WEBMAIL_CLIENT "\x07google-webmail-client" - -/* Some useful capability sets for Jingle etc. */ -const GabbleCapabilitySet *gabble_capabilities_get_legacy (void); -const GabbleCapabilitySet *gabble_capabilities_get_any_audio (void); -const GabbleCapabilitySet *gabble_capabilities_get_any_video (void); -const GabbleCapabilitySet *gabble_capabilities_get_any_audio_video (void); -const GabbleCapabilitySet *gabble_capabilities_get_any_google_av (void); -const GabbleCapabilitySet *gabble_capabilities_get_any_jingle_av (void); -const GabbleCapabilitySet *gabble_capabilities_get_any_transport (void); -const GabbleCapabilitySet *gabble_capabilities_get_geoloc_notify (void); -const GabbleCapabilitySet *gabble_capabilities_get_olpc_notify (void); - -/* XEP-0115 version 1.3: - * - * "The names of the feature bundles MUST NOT be used for semantic purposes: - * they are merely opaque identifiers" - * - * However, some old Jabber clients (e.g. Gabble 0.2) and various Google - * clients require the bundle names "voice-v1" and "video-v1". We keep these - * names for compatibility. - */ -#define BUNDLE_SHARE_V1 "share-v1" -#define BUNDLE_VOICE_V1 "voice-v1" -#define BUNDLE_VIDEO_V1 "video-v1" -#define BUNDLE_CAMERA_V1 "camera-v1" -#define BUNDLE_PMUC_V1 "pmuc-v1" - -const GabbleCapabilitySet *gabble_capabilities_get_bundle_share_v1 (void); -const GabbleCapabilitySet *gabble_capabilities_get_bundle_voice_v1 (void); -const GabbleCapabilitySet *gabble_capabilities_get_bundle_video_v1 (void); - -/* Return the capabilities we always have */ -const GabbleCapabilitySet *gabble_capabilities_get_fixed_caps (void); - -void gabble_capabilities_init (gpointer conn); -void gabble_capabilities_finalize (gpointer conn); - -#endif /* __GABBLE_CAPABILITIES__H__ */ - diff --git a/src/caps-channel-manager.c b/src/caps-channel-manager.c index 73b3e222..dea13a65 100644 --- a/src/caps-channel-manager.c +++ b/src/caps-channel-manager.c @@ -21,7 +21,7 @@ */ #include "config.h" -#include "caps-channel-manager.h" +#include "gabble/caps-channel-manager.h" #include <telepathy-glib/dbus.h> #include <telepathy-glib/channel-manager.h> @@ -82,6 +82,7 @@ gabble_caps_channel_manager_get_contact_capabilities ( * GHashTable with string keys and GValue values * @cap_tokens: the handler capability tokens supported by the client * @cap_set: a set into which to merge additional XMPP capabilities + * @data_forms: a #GPtrArray of #WockyDataForm objects * * Convert the capabilities of a Telepathy client into XMPP capabilities to be * advertised. @@ -95,7 +96,8 @@ gabble_caps_channel_manager_represent_client ( const gchar *client_name, const GPtrArray *filters, const gchar * const *cap_tokens, - GabbleCapabilitySet *cap_set) + GabbleCapabilitySet *cap_set, + GPtrArray *data_forms) { GabbleCapsChannelManagerInterface *iface = GABBLE_CAPS_CHANNEL_MANAGER_GET_INTERFACE (caps_manager); @@ -103,6 +105,6 @@ gabble_caps_channel_manager_represent_client ( if (method != NULL) { - method (caps_manager, client_name, filters, cap_tokens, cap_set); + method (caps_manager, client_name, filters, cap_tokens, cap_set, data_forms); } } diff --git a/src/caps-channel-manager.h b/src/caps-channel-manager.h deleted file mode 100644 index 05947b75..00000000 --- a/src/caps-channel-manager.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * caps-channel-manager.h - interface holding capabilities functions for - * channel managers - * - * Copyright (C) 2008 Collabora Ltd. - * Copyright (C) 2008 Nokia Corporation - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA - */ - -#ifndef GABBLE_CAPS_CHANNEL_MANAGER_H -#define GABBLE_CAPS_CHANNEL_MANAGER_H - -#include <glib-object.h> -#include <telepathy-glib/exportable-channel.h> -#include <telepathy-glib/handle.h> - -#include "capabilities.h" - -G_BEGIN_DECLS - -#define GABBLE_TYPE_CAPS_CHANNEL_MANAGER \ - (gabble_caps_channel_manager_get_type ()) - -#define GABBLE_CAPS_CHANNEL_MANAGER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), \ - GABBLE_TYPE_CAPS_CHANNEL_MANAGER, GabbleCapsChannelManager)) - -#define GABBLE_IS_CAPS_CHANNEL_MANAGER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \ - GABBLE_TYPE_CAPS_CHANNEL_MANAGER)) - -#define GABBLE_CAPS_CHANNEL_MANAGER_GET_INTERFACE(obj) \ - (G_TYPE_INSTANCE_GET_INTERFACE ((obj), \ - GABBLE_TYPE_CAPS_CHANNEL_MANAGER, GabbleCapsChannelManagerInterface)) - -typedef struct _GabbleCapsChannelManager GabbleCapsChannelManager; -typedef struct _GabbleCapsChannelManagerInterface GabbleCapsChannelManagerInterface; - -/* virtual methods */ - -typedef void (*GabbleCapsChannelManagerGetContactCapsFunc) ( - GabbleCapsChannelManager *manager, - TpHandle handle, - const GabbleCapabilitySet *caps, - GPtrArray *arr); - -typedef void (*GabbleCapsChannelManagerResetCapsFunc) ( - GabbleCapsChannelManager *manager); - -typedef void (*GabbleCapsChannelManagerAddCapFunc) ( - GabbleCapsChannelManager *manager, - GHashTable *cap, - GabbleCapabilitySet *cap_set); - -typedef void (*GabbleCapsChannelManagerRepresentClientFunc) ( - GabbleCapsChannelManager *manager, - const gchar *client_name, - const GPtrArray *filters, - const gchar * const *cap_tokens, - GabbleCapabilitySet *cap_set); - -void gabble_caps_channel_manager_reset_capabilities ( - GabbleCapsChannelManager *caps_manager); - -void gabble_caps_channel_manager_get_contact_capabilities ( - GabbleCapsChannelManager *caps_manager, - TpHandle handle, - const GabbleCapabilitySet *caps, - GPtrArray *arr); - -void gabble_caps_channel_manager_represent_client ( - GabbleCapsChannelManager *caps_manager, - const gchar *client_name, - const GPtrArray *filters, - const gchar * const *cap_tokens, - GabbleCapabilitySet *cap_set); - -struct _GabbleCapsChannelManagerInterface { - GTypeInterface parent; - - GabbleCapsChannelManagerResetCapsFunc reset_caps; - GabbleCapsChannelManagerGetContactCapsFunc get_contact_caps; - GabbleCapsChannelManagerRepresentClientFunc represent_client; - - gpointer priv; -}; - -GType gabble_caps_channel_manager_get_type (void); - -G_END_DECLS - -#endif diff --git a/src/caps-hash.c b/src/caps-hash.c index bf8a2a08..1518748e 100644 --- a/src/caps-hash.c +++ b/src/caps-hash.c @@ -35,7 +35,7 @@ #define DEBUG_FLAG GABBLE_DEBUG_PRESENCE #include "base64.h" -#include "capabilities.h" +#include "gabble/capabilities.h" #include "debug.h" #include "namespaces.h" #include "presence-cache.h" @@ -61,6 +61,7 @@ caps_hash_compute_from_self_presence (GabbleConnection *self) const GabbleCapabilitySet *cap_set; GPtrArray *features = g_ptr_array_new (); GPtrArray *identities = wocky_disco_identity_array_new (); + GPtrArray *data_forms; gchar *str; /* XEP-0030 requires at least 1 identity. We don't need more. */ @@ -71,7 +72,9 @@ caps_hash_compute_from_self_presence (GabbleConnection *self) cap_set = gabble_presence_peek_caps (presence); gabble_capability_set_foreach (cap_set, ptr_array_add_str, features); - str = wocky_caps_hash_compute_from_lists (features, identities, NULL); + data_forms = gabble_presence_peek_data_forms (presence); + + str = wocky_caps_hash_compute_from_lists (features, identities, data_forms); g_ptr_array_free (features, TRUE); wocky_disco_identity_array_free (identities); diff --git a/src/connection.c b/src/connection.c index b06cbc10..1ea7d655 100644 --- a/src/connection.c +++ b/src/connection.c @@ -36,6 +36,7 @@ #include <wocky/wocky-tls-handler.h> #include <wocky/wocky-ping.h> #include <wocky/wocky-xmpp-error.h> +#include <wocky/wocky-data-form.h> #include <telepathy-glib/channel-manager.h> #include <telepathy-glib/dbus.h> #include <telepathy-glib/enums.h> @@ -50,8 +51,8 @@ #define DEBUG_FLAG GABBLE_DEBUG_CONNECTION #include "bytestream-factory.h" -#include "capabilities.h" -#include "caps-channel-manager.h" +#include "gabble/capabilities.h" +#include "gabble/caps-channel-manager.h" #include "caps-hash.h" #include "auth-manager.h" #include "conn-aliasing.h" @@ -258,6 +259,10 @@ struct _GabbleConnectionPrivate /* the union of the above */ GabbleCapabilitySet *all_caps; + /* data forms provided via UpdateCapabilities() + * gchar * (client name) => GPtrArray<owned WockyDataForm> */ + GHashTable *client_data_forms; + /* auth manager */ GabbleAuthManager *auth_manager; @@ -444,6 +449,9 @@ gabble_connection_constructor (GType type, priv->client_caps = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, (GDestroyNotify) gabble_capability_set_free); + priv->client_data_forms = g_hash_table_new_full (g_str_hash, g_str_equal, + g_free, (GDestroyNotify) g_ptr_array_unref); + /* Historically, the optional Jingle transports were in our initial * presence, but could be removed by AdvertiseCapabilities(). Emulate * that here for now. */ @@ -1222,6 +1230,8 @@ gabble_connection_dispose (GObject *object) gabble_capability_set_free (priv->sidecar_caps); gabble_capability_set_free (priv->bonus_caps); + g_hash_table_destroy (priv->client_data_forms); + if (priv->disconnect_timer != 0) { g_source_remove (priv->disconnect_timer); @@ -1362,6 +1372,14 @@ WockyPorter *gabble_connection_dup_porter (GabbleConnection *conn) return NULL; } +WockySession * +gabble_connection_get_session (GabbleConnection *connection) +{ + g_return_val_if_fail (GABBLE_IS_CONNECTION (connection), NULL); + + return connection->session; +} + /** * _gabble_connection_send * @@ -2303,7 +2321,8 @@ gabble_connection_fill_in_caps (GabbleConnection *self, /* Ensure this set of capabilities is in the cache. */ gabble_presence_cache_add_own_caps (self->presence_cache, caps_hash, - gabble_presence_peek_caps (presence), NULL); + gabble_presence_peek_caps (presence), NULL, + gabble_presence_peek_data_forms (presence)); /* XEP-0115 deprecates 'ext' feature bundles. But we still need * BUNDLE_VOICE_V1 it for backward-compatibility with Gabble 0.2 */ @@ -2401,10 +2420,13 @@ gabble_connection_refresh_capabilities (GabbleConnection *self, GHashTableIter iter; gpointer k, v; GabbleCapabilitySet *save_set; + GPtrArray *data_forms; save_set = self->priv->all_caps; self->priv->all_caps = gabble_capability_set_new (); + data_forms = g_ptr_array_new (); + gabble_capability_set_update (self->priv->all_caps, gabble_capabilities_get_fixed_caps ()); gabble_capability_set_update (self->priv->all_caps, self->priv->notify_caps); @@ -2412,6 +2434,7 @@ gabble_connection_refresh_capabilities (GabbleConnection *self, gabble_capability_set_update (self->priv->all_caps, self->priv->sidecar_caps); gabble_capability_set_update (self->priv->all_caps, self->priv->bonus_caps); + /* first, normal caps */ g_hash_table_iter_init (&iter, self->priv->client_caps); while (g_hash_table_iter_next (&iter, &k, &v)) @@ -2427,13 +2450,22 @@ gabble_connection_refresh_capabilities (GabbleConnection *self, gabble_capability_set_update (self->priv->all_caps, v); } + /* now data forms */ + g_hash_table_iter_init (&iter, self->priv->client_data_forms); + + /* just borrow the ref, data_forms doesn't have a free func */ + while (g_hash_table_iter_next (&iter, &k, &v)) + tp_g_ptr_array_extend (data_forms, v); + if (self->self_presence != NULL) gabble_presence_set_capabilities (self->self_presence, - self->priv->resource, self->priv->all_caps, self->priv->caps_serial++); + self->priv->resource, self->priv->all_caps, data_forms, + self->priv->caps_serial++); if (gabble_capability_set_equals (self->priv->all_caps, save_set)) { gabble_capability_set_free (save_set); + g_ptr_array_unref (data_forms); DEBUG ("nothing to do"); return FALSE; } @@ -2442,6 +2474,7 @@ gabble_connection_refresh_capabilities (GabbleConnection *self, if (base->status != TP_CONNECTION_STATUS_CONNECTED) { gabble_capability_set_free (save_set); + g_ptr_array_unref (data_forms); DEBUG ("not emitting self-presence stanza: not connected yet"); return FALSE; } @@ -2449,6 +2482,7 @@ gabble_connection_refresh_capabilities (GabbleConnection *self, if (!conn_presence_signal_own_presence (self, NULL, &error)) { gabble_capability_set_free (save_set); + g_ptr_array_unref (data_forms); DEBUG ("error sending presence: %s", error->message); g_error_free (error); return FALSE; @@ -2459,6 +2493,8 @@ gabble_connection_refresh_capabilities (GabbleConnection *self, else *old_out = save_set; + g_ptr_array_unref (data_forms); + return TRUE; } @@ -2570,6 +2606,7 @@ iq_disco_cb (WockyPorter *porter, const GabbleCapabilityInfo *info = NULL; const GabbleCapabilitySet *features = NULL; const GPtrArray *identities = NULL; + const GPtrArray *data_forms = NULL; /* query's existence is checked by WockyPorter before this function is called */ query = wocky_node_get_child (wocky_stanza_get_top_node (stanza), "query"); @@ -2599,19 +2636,25 @@ iq_disco_cb (WockyPorter *porter, wocky_node_set_attribute (result_query, "node", node); if (node == NULL) - features = gabble_presence_peek_caps (self->self_presence); - /* If node is not NULL, it can be either a caps bundle as defined in the - * legacy XEP-0115 version 1.3 or an hash as defined in XEP-0115 version - * 1.5. Let's see if it's a verification string we've told the cache about. - */ + { + features = gabble_presence_peek_caps (self->self_presence); + data_forms = gabble_presence_peek_data_forms (self->self_presence); + } else - info = gabble_presence_cache_peek_own_caps (self->presence_cache, - suffix); + { + /* If node is not NULL, it can be either a caps bundle as defined in the + * legacy XEP-0115 version 1.3 or an hash as defined in XEP-0115 version + * 1.5. Let's see if it's a verification string we've told the cache about. + */ + info = gabble_presence_cache_peek_own_caps (self->presence_cache, + suffix); + } if (info) { features = info->cap_set; identities = info->identities; + data_forms = info->data_forms; } if (identities && identities->len != 0) @@ -2650,6 +2693,18 @@ iq_disco_cb (WockyPorter *porter, features = gabble_capabilities_get_bundle_video_v1 (); } + if (data_forms != NULL) + { + guint i; + + for (i = 0; i < data_forms->len; i++) + { + WockyDataForm *form = g_ptr_array_index (data_forms, i); + + wocky_data_form_add_to_node (form, result_query); + } + } + if (features == NULL && tp_strdiff (suffix, BUNDLE_PMUC_V1)) { _gabble_connection_send_iq_error (self, stanza, @@ -3193,6 +3248,111 @@ gabble_connection_advertise_capabilities (TpSvcConnectionInterfaceCapabilities * g_ptr_array_free (ret, TRUE); } +static const gchar * +get_form_type (WockyDataForm *form) +{ + WockyDataFormField *field; + + field = g_hash_table_lookup (form->fields, + "FORM_TYPE"); + g_assert (field != NULL); + + return field->raw_value_contents[0]; +} + +static const gchar * +check_form_is_unique (GabbleConnection *self, + const gchar *form_type) +{ + GHashTableIter iter; + gpointer key, value; + + g_hash_table_iter_init (&iter, self->priv->client_data_forms); + while (g_hash_table_iter_next (&iter, &key, &value)) + { + const gchar *manager = key; + GPtrArray *data_forms = value; + guint i; + + if (data_forms == NULL || data_forms->len == 0) + continue; + + for (i = 0; i < data_forms->len; i++) + { + WockyDataForm *form = g_ptr_array_index (data_forms, i); + + if (!tp_strdiff (get_form_type (form), form_type)) + return manager; + } + } + + return NULL; +} + +static gboolean +check_data_form_in_list (GPtrArray *array, + const gchar *form_type) +{ + guint i; + + for (i = 0; i < array->len; i++) + { + WockyDataForm *form = g_ptr_array_index (array, i); + + if (!tp_strdiff (get_form_type (form), form_type)) + return TRUE; + } + + return FALSE; +} + +static gboolean +check_data_form_is_valid (GabbleConnection *self, + WockyDataForm *form, + GPtrArray *existing_forms) +{ + WockyDataFormField *field; + const gchar *form_type, *other_client; + + /* We want rid of forms with no FORM_TYPE quickly. */ + field = g_hash_table_lookup (form->fields, "FORM_TYPE"); + + if (field == NULL || tp_str_empty (field->raw_value_contents[0])) + { + WARNING ("data form with no FORM_TYPE field; ignoring"); + return FALSE; + } + + form_type = field->raw_value_contents[0]; + + /* We'll get warnings (potentially bad) if two clients cause a + * channel manager to create two data forms with the same FORM_TYPE, + * or if multiple channel managers create two data forms with the + * same FORM_TYPE, for the same client. This is probably not a + * problem in practice given hardly anyone uses data forms in entity + * capabilities anyway. */ + + /* We don't want the same data form from another caps channel + * manager for this client either */ + if (check_data_form_in_list (existing_forms, form_type)) + { + WARNING ("duplicate data form '%s' from another channel " + "manager; ignoring", form_type); + return FALSE; + } + + /* And lastly we don't want a form we're already advertising. */ + other_client = check_form_is_unique (self, form_type); + if (other_client != NULL) + { + WARNING ("Data form '%s' already provided by client " + "%s; ignoring", form_type, other_client); + return FALSE; + } + + return TRUE; +} + /** * gabble_connection_update_capabilities * @@ -3239,10 +3399,12 @@ gabble_connection_update_capabilities ( const GPtrArray *filters = g_value_get_boxed (va->values + 1); const gchar * const * cap_tokens = g_value_get_boxed (va->values + 2); GabbleCapabilitySet *cap_set; + GPtrArray *data_forms; g_hash_table_remove (self->priv->client_caps, client_name); + g_hash_table_remove (self->priv->client_data_forms, client_name); - if ((cap_tokens == NULL || cap_tokens[0] != NULL) && + if ((cap_tokens == NULL || cap_tokens[0] == NULL) && filters->len == 0) { /* no capabilities */ @@ -3251,6 +3413,8 @@ gabble_connection_update_capabilities ( } cap_set = gabble_capability_set_new (); + data_forms = g_ptr_array_new_with_free_func ( + (GDestroyNotify) g_object_unref); tp_base_connection_channel_manager_iter_init (&iter, base); @@ -3258,18 +3422,30 @@ gabble_connection_update_capabilities ( { if (GABBLE_IS_CAPS_CHANNEL_MANAGER (manager)) { + GPtrArray *forms = g_ptr_array_new_with_free_func ( + (GDestroyNotify) g_object_unref); + guint j; + + /* First, represent the client... */ gabble_caps_channel_manager_represent_client ( GABBLE_CAPS_CHANNEL_MANAGER (manager), client_name, filters, - cap_tokens, cap_set); + cap_tokens, cap_set, forms); + + /* Now check the forms... */ + for (j = 0; j < forms->len; j++) + { + WockyDataForm *form = g_ptr_array_index (forms, j); + + if (check_data_form_is_valid (self, form, data_forms)) + g_ptr_array_add (data_forms, g_object_ref (form)); + } + + g_ptr_array_unref (forms); } } - if (gabble_capability_set_size (cap_set) == 0) - { - DEBUG ("client %s has no interesting capabilities", client_name); - gabble_capability_set_free (cap_set); - } - else + /* first deal with normal caps */ + if (gabble_capability_set_size (cap_set) > 0) { if (DEBUGGING) { @@ -3282,6 +3458,33 @@ gabble_connection_update_capabilities ( g_hash_table_insert (self->priv->client_caps, g_strdup (client_name), cap_set); } + else + { + DEBUG ("client %s has no interesting capabilities", client_name); + gabble_capability_set_free (cap_set); + } + + /* now data forms */ + if (data_forms->len > 0) + { + guint j; + + /* now print out what forms we have here */ + DEBUG ("client %s contributes %u data form%s:", client_name, + data_forms->len, + data_forms->len > 1 ? "s" : ""); + + for (j = 0; j < data_forms->len; j++) + DEBUG (" - %s", get_form_type (g_ptr_array_index (data_forms, i))); + + g_hash_table_insert (self->priv->client_data_forms, + g_strdup (client_name), data_forms); + } + else + { + DEBUG ("client %s has no interesting data forms", client_name); + g_ptr_array_unref (data_forms); + } } if (gabble_connection_refresh_capabilities (self, &old_caps)) @@ -3711,9 +3914,95 @@ gabble_connection_add_sidecar_own_caps (GabbleConnection *self, ver = gabble_caps_hash_compute (cap_set, identities_copy); gabble_presence_cache_add_own_caps (self->presence_cache, ver, - cap_set, identities_copy); + cap_set, identities_copy, NULL); wocky_disco_identity_array_free (identities_copy); return ver; } + +const gchar * +gabble_connection_get_jid_for_caps (GabbleConnection *conn, + WockyXep0115Capabilities *caps) +{ + TpHandle handle; + TpBaseConnection *base; + TpHandleRepoIface *contact_handles; + + g_return_val_if_fail (GABBLE_IS_CONNECTION (conn), NULL); + g_return_val_if_fail (GABBLE_IS_PRESENCE (caps), NULL); + + base = (TpBaseConnection *) conn; + + if ((GabblePresence *) caps == conn->self_presence) + { + handle = tp_base_connection_get_self_handle (base); + } + else + { + handle = gabble_presence_cache_get_handle (conn->presence_cache, + (GabblePresence *) caps); + } + + contact_handles = tp_base_connection_get_handles (base, + TP_HANDLE_TYPE_CONTACT); + + return tp_handle_inspect (contact_handles, handle); +} + +const gchar * +gabble_connection_pick_best_resource_for_caps (GabbleConnection *connection, + const gchar *jid, + GabbleCapabilitySetPredicate predicate, + gconstpointer user_data) +{ + TpBaseConnection *base; + TpHandleRepoIface *contact_handles; + TpHandle handle; + GabblePresence *presence; + + g_return_val_if_fail (GABBLE_IS_CONNECTION (connection), NULL); + g_return_val_if_fail (!tp_str_empty (jid), NULL); + + base = (TpBaseConnection *) connection; + contact_handles = tp_base_connection_get_handles (base, + TP_HANDLE_TYPE_CONTACT); + + handle = tp_handle_ensure (contact_handles, jid, + NULL, NULL); + + if (handle == 0) + return NULL; + + presence = gabble_presence_cache_get (connection->presence_cache, + handle); + + if (presence == NULL) + return NULL; + + return gabble_presence_pick_resource_by_caps (presence, 0, + predicate, user_data); +} + +TpBaseContactList * +gabble_connection_get_contact_list (GabbleConnection *connection) +{ + g_return_val_if_fail (GABBLE_IS_CONNECTION (connection), NULL); + + return (TpBaseContactList *) connection->roster; +} + +WockyXep0115Capabilities * +gabble_connection_get_caps (GabbleConnection *connection, + TpHandle handle) +{ + GabblePresence *presence; + + g_return_val_if_fail (GABBLE_IS_CONNECTION (connection), NULL); + g_return_val_if_fail (handle > 0, NULL); + + presence = gabble_presence_cache_get (connection->presence_cache, + handle); + + return (WockyXep0115Capabilities *) presence; +} diff --git a/src/connection.h b/src/connection.h index 586b648c..d1dc73a5 100644 --- a/src/connection.h +++ b/src/connection.h @@ -34,7 +34,7 @@ #include <wocky/wocky-pep-service.h> #include "gabble/connection.h" -#include "capabilities.h" +#include "gabble/capabilities.h" #include "error.h" #include "ft-manager.h" #include "jingle-factory.h" @@ -204,8 +204,6 @@ typedef enum { GABBLE_CONNECTION_ALIAS_FROM_ROSTER } GabbleConnectionAliasSource; -gchar *gabble_connection_get_full_jid (GabbleConnection *conn); - WockyPorter *gabble_connection_dup_porter (GabbleConnection *conn); gboolean _gabble_connection_set_properties_from_account ( diff --git a/src/ft-manager.c b/src/ft-manager.c index 9c3128df..b79881ac 100644 --- a/src/ft-manager.c +++ b/src/ft-manager.c @@ -30,7 +30,7 @@ #include "jingle-session.h" #include "jingle-share.h" -#include "caps-channel-manager.h" +#include "gabble/caps-channel-manager.h" #include "connection.h" #include "ft-manager.h" #include "error.h" @@ -824,7 +824,8 @@ gabble_ft_manager_represent_client ( const gchar *client_name, const GPtrArray *filters, const gchar * const *cap_tokens G_GNUC_UNUSED, - GabbleCapabilitySet *cap_set) + GabbleCapabilitySet *cap_set, + GPtrArray *data_forms G_GNUC_UNUSED) { guint i; diff --git a/src/im-factory.c b/src/im-factory.c index 08f19f6c..be518b27 100644 --- a/src/im-factory.c +++ b/src/im-factory.c @@ -36,7 +36,7 @@ #include "extensions/extensions.h" -#include "caps-channel-manager.h" +#include "gabble/caps-channel-manager.h" #include "connection.h" #include "debug.h" #include "disco.h" diff --git a/src/jingle-session.c b/src/jingle-session.c index f20c2d63..2981e3e8 100644 --- a/src/jingle-session.c +++ b/src/jingle-session.c @@ -30,7 +30,7 @@ #define DEBUG_FLAG GABBLE_DEBUG_MEDIA -#include "capabilities.h" +#include "gabble/capabilities.h" #include "connection.h" #include "conn-presence.h" #include "debug.h" diff --git a/src/legacy-caps.h b/src/legacy-caps.h index 080ac3b0..e2de46c3 100644 --- a/src/legacy-caps.h +++ b/src/legacy-caps.h @@ -23,7 +23,7 @@ #include <glib-object.h> -#include "capabilities.h" +#include "gabble/capabilities.h" typedef void (*TypeFlagsToCapsFunc) (guint typeflags, GabbleCapabilitySet *caps); typedef guint (*CapsToTypeFlagsFunc) (const GabbleCapabilitySet *caps); diff --git a/src/media-factory.c b/src/media-factory.c index 4a2c7c70..e8ec9908 100644 --- a/src/media-factory.c +++ b/src/media-factory.c @@ -36,7 +36,7 @@ #define DEBUG_FLAG GABBLE_DEBUG_MEDIA -#include "caps-channel-manager.h" +#include "gabble/caps-channel-manager.h" #include "connection.h" #include "debug.h" #include "jingle-factory.h" @@ -1208,7 +1208,8 @@ gabble_media_factory_represent_client (GabbleCapsChannelManager *manager, const gchar *client_name, const GPtrArray *filters, const gchar * const *cap_tokens, - GabbleCapabilitySet *cap_set) + GabbleCapabilitySet *cap_set, + GPtrArray *data_forms) { static GQuark q_gtalk_p2p = 0, q_ice_udp = 0, q_h264 = 0; static GQuark qc_gtalk_p2p = 0, qc_ice_udp = 0, qc_h264 = 0; diff --git a/src/muc-factory.c b/src/muc-factory.c index 1feb21a1..554b1504 100644 --- a/src/muc-factory.c +++ b/src/muc-factory.c @@ -36,7 +36,7 @@ #define DEBUG_FLAG GABBLE_DEBUG_MUC -#include "caps-channel-manager.h" +#include "gabble/caps-channel-manager.h" #include "connection.h" #include "conn-olpc.h" #include "debug.h" diff --git a/src/presence-cache.c b/src/presence-cache.c index 05556f8b..89a6534e 100644 --- a/src/presence-cache.c +++ b/src/presence-cache.c @@ -41,11 +41,13 @@ #include <wocky/wocky-caps-hash.h> #include <wocky/wocky-disco-identity.h> #include <wocky/wocky-utils.h> +#include <wocky/wocky-namespaces.h> +#include <wocky/wocky-data-form.h> #define DEBUG_FLAG GABBLE_DEBUG_PRESENCE -#include "capabilities.h" -#include "caps-channel-manager.h" +#include "gabble/capabilities.h" +#include "gabble/caps-channel-manager.h" #include "conn-presence.h" #include "debug.h" #include "disco.h" @@ -251,18 +253,36 @@ capability_info_free (GabbleCapabilityInfo *info) wocky_disco_identity_array_free (info->identities); info->identities = NULL; + if (info->data_forms != NULL) + g_ptr_array_unref (info->data_forms); + info->data_forms = NULL; + tp_intset_destroy (info->guys); g_slice_free (GabbleCapabilityInfo, info); } +static void +replace_data_forms (GabbleCapabilityInfo *info, + GPtrArray *data_forms) +{ + if (data_forms == info->data_forms) + return; + + tp_clear_pointer (&info->data_forms, g_ptr_array_unref); + + if (data_forms != NULL) + info->data_forms = g_ptr_array_ref (data_forms); +} + static guint capability_info_recvd (GabblePresenceCache *cache, const gchar *node, TpHandle handle, GabbleCapabilitySet *cap_set, guint trust_inc, - guint client_types) + guint client_types, + GPtrArray *data_forms) { GabbleCapabilityInfo *info = capability_info_get (cache, node); @@ -293,6 +313,8 @@ capability_info_recvd (GabblePresenceCache *cache, info->client_types = client_types; + replace_data_forms (info, data_forms); + return info->trust; } @@ -1012,7 +1034,7 @@ _parse_node (GabblePresence *presence, gabble_capability_set_add (cap_set, QUIRK_GOOGLE_WEBMAIL_CLIENT); gabble_capability_set_add (cap_set, QUIRK_OMITS_CONTENT_CREATORS); - gabble_presence_set_capabilities (presence, resource, cap_set, serial); + gabble_presence_set_capabilities (presence, resource, cap_set, NULL, serial); gabble_capability_set_free (cap_set); } } @@ -1142,6 +1164,7 @@ set_caps_for (DiscoWaiter *waiter, GabblePresenceCache *cache, GabbleCapabilitySet *cap_set, guint client_types, + GPtrArray *data_forms, TpHandle responder_handle, const gchar *responder_jid) { @@ -1158,7 +1181,7 @@ set_caps_for (DiscoWaiter *waiter, waiter->handle, responder_handle, responder_jid); gabble_presence_set_capabilities (presence, waiter->resource, cap_set, - waiter->serial); + data_forms, waiter->serial); new_cap_set = gabble_presence_peek_caps (presence); emit_capabilities_update (cache, waiter->handle, old_cap_set, new_cap_set); gabble_capability_set_free (old_cap_set); @@ -1222,6 +1245,29 @@ client_types_from_message (TpHandle handle, return client_types; } +static GPtrArray * +data_forms_from_message (WockyNode *node) +{ + GPtrArray *out = g_ptr_array_new_with_free_func (g_object_unref); + + WockyNodeIter iter; + WockyNode *x_node = NULL; + + wocky_node_iter_init (&iter, node, "x", WOCKY_XMPP_NS_DATA); + while (wocky_node_iter_next (&iter, &x_node)) + { + WockyDataForm *form = wocky_data_form_new_from_node (x_node, NULL); + + /* we've already parsed the reply to check the hash matches, so + * we can already guarantee these data forms will be parsed + * fine */ + if (G_LIKELY (form != NULL)) + g_ptr_array_add (out, form); + } + + return out; +} + static void _signal_presences_updated (GabblePresenceCache *cache, TpHandle handle) @@ -1257,6 +1303,7 @@ _caps_disco_cb (GabbleDisco *disco, gboolean jid_is_valid; gpointer key; guint client_types = 0; + GPtrArray *data_forms = NULL; cache = GABBLE_PRESENCE_CACHE (user_data); priv = cache->priv; @@ -1305,6 +1352,7 @@ _caps_disco_cb (GabbleDisco *disco, cap_set = gabble_capability_set_new_from_stanza (query_result); client_types = client_types_from_message (handle, query_result, waiter_self->resource); + data_forms = data_forms_from_message (query_result); /* Only 'sha-1' is mandatory to implement by XEP-0115. If the remote contact * uses another hash algorithm, don't check the hash and fallback to the old @@ -1326,7 +1374,7 @@ _caps_disco_cb (GabbleDisco *disco, else if (g_str_equal (waiter_self->ver, computed_hash)) { trust = capability_info_recvd (cache, node, handle, cap_set, - CAPABILITY_BUNDLE_ENOUGH_TRUST, client_types); + CAPABILITY_BUNDLE_ENOUGH_TRUST, client_types, data_forms); } else { @@ -1341,7 +1389,8 @@ _caps_disco_cb (GabbleDisco *disco, } else { - trust = capability_info_recvd (cache, node, handle, cap_set, 1, client_types); + trust = capability_info_recvd (cache, node, handle, cap_set, 1, + client_types, data_forms); } /* Remove the node from the hash table without freeing the key or list of @@ -1381,7 +1430,8 @@ _caps_disco_cb (GabbleDisco *disco, { DiscoWaiter *waiter = (DiscoWaiter *) i->data; - set_caps_for (waiter, cache, cap_set, client_types, handle, jid); + set_caps_for (waiter, cache, cap_set, client_types, + data_forms, handle, jid); emit_capabilities_discovered (cache, waiter->handle); } @@ -1409,7 +1459,8 @@ _caps_disco_cb (GabbleDisco *disco, g_free (tmp); } - set_caps_for (waiter_self, cache, cap_set, client_types, handle, jid); + set_caps_for (waiter_self, cache, cap_set, client_types, + data_forms, handle, jid); } waiters = g_slist_remove (waiters, waiter_self); @@ -1435,6 +1486,7 @@ _caps_disco_cb (GabbleDisco *disco, } gabble_capability_set_free (cap_set); + g_ptr_array_unref (data_forms); OUT: if (handle) @@ -1501,7 +1553,7 @@ _process_caps_uri (GabblePresenceCache *cache, guint types; gabble_presence_set_capabilities ( - presence, resource, cap_set, serial); + presence, resource, cap_set, info->data_forms, serial); /* We can only get this information from actual disco replies, * so we depend on having this information from the caps cache. */ @@ -2100,7 +2152,8 @@ gabble_presence_cache_add_own_caps ( GabblePresenceCache *cache, const gchar *ver, const GabbleCapabilitySet *cap_set, - const GPtrArray *identities) + const GPtrArray *identities, + GPtrArray *data_forms) { gchar *uri = g_strdup_printf ("%s#%s", NS_GABBLE_CAPS, ver); GabbleCapabilityInfo *info = capability_info_get (cache, uri); @@ -2135,6 +2188,8 @@ gabble_presence_cache_add_own_caps ( info->trust = CAPABILITY_BUNDLE_ENOUGH_TRUST; tp_intset_add (info->guys, cache->priv->conn->parent.self_handle); + replace_data_forms (info, data_forms); + /* FIXME: we should satisfy any waiters for this node now. fd.o bug #24619. */ out: @@ -2497,3 +2552,20 @@ gabble_presence_cache_disco_in_progress (GabblePresenceCache *cache, return in_progress; } + +TpHandle +gabble_presence_cache_get_handle (GabblePresenceCache *cache, + GabblePresence *presence) +{ + GHashTableIter iter; + gpointer key, val; + + g_hash_table_iter_init (&iter, cache->priv->presence); + while (g_hash_table_iter_next (&iter, &key, &val)) + { + if (presence == val) + return GPOINTER_TO_UINT (key); + } + + return 0; +} diff --git a/src/presence-cache.h b/src/presence-cache.h index 44af23fb..0e528396 100644 --- a/src/presence-cache.h +++ b/src/presence-cache.h @@ -65,6 +65,9 @@ struct _GabbleCapabilityInfo /* array of GabbleDiscoIdentity or NULL */ GPtrArray *identities; + /* array of WockyDataForm or NULL */ + GPtrArray *data_forms; + TpIntSet *guys; guint trust; @@ -107,7 +110,8 @@ void gabble_presence_cache_maybe_remove (GabblePresenceCache *cache, void gabble_presence_cache_add_own_caps (GabblePresenceCache *cache, const gchar *ver, const GabbleCapabilitySet *cap_set, - const GPtrArray *identities); + const GPtrArray *identities, + GPtrArray *data_forms); const GabbleCapabilityInfo *gabble_presence_cache_peek_own_caps ( GabblePresenceCache *cache, const gchar *ver); @@ -140,6 +144,9 @@ GHashTable* gabble_presence_cache_get_location (GabblePresenceCache *cache, gboolean gabble_presence_cache_disco_in_progress (GabblePresenceCache *cache, TpHandle handle, const gchar *resource); +TpHandle gabble_presence_cache_get_handle (GabblePresenceCache *cache, + GabblePresence *presence); + G_END_DECLS #endif /* __GABBLE_PRESENCE_CACHE_H__ */ diff --git a/src/presence.c b/src/presence.c index a707822a..1ddaedf6 100644 --- a/src/presence.c +++ b/src/presence.c @@ -24,8 +24,9 @@ #include <string.h> #include <telepathy-glib/channel-manager.h> #include <wocky/wocky-utils.h> +#include <wocky/wocky-xep-0115-capabilities.h> -#include "capabilities.h" +#include "gabble/capabilities.h" #include "conn-presence.h" #include "presence-cache.h" #include "namespaces.h" @@ -36,7 +37,12 @@ #include "debug.h" -G_DEFINE_TYPE (GabblePresence, gabble_presence, G_TYPE_OBJECT); +static void xep_0115_capabilities_iface_init (gpointer, gpointer); + +G_DEFINE_TYPE_WITH_CODE (GabblePresence, gabble_presence, G_TYPE_OBJECT, + G_IMPLEMENT_INTERFACE (WOCKY_TYPE_XEP_0115_CAPABILITIES, + xep_0115_capabilities_iface_init); +) typedef struct _Resource Resource; @@ -44,6 +50,7 @@ struct _Resource { gchar *name; guint client_type; GabbleCapabilitySet *cap_set; + GPtrArray *data_forms; guint caps_serial; GabblePresenceId status; gchar *status_message; @@ -58,6 +65,9 @@ struct _GabblePresencePrivate { /* The aggregated caps of all the contacts' resources. */ GabbleCapabilitySet *cap_set; + /* The aggregated data forms of all the contacts' resources */ + GPtrArray *data_forms; + gchar *no_resource_status_message; GSList *resources; guint olpc_views; @@ -72,6 +82,8 @@ _resource_new (gchar *name) new->name = name; new->client_type = 0; new->cap_set = gabble_capability_set_new (); + new->data_forms = g_ptr_array_new_with_free_func ( + (GDestroyNotify) g_object_unref); new->status = GABBLE_PRESENCE_OFFLINE; new->status_message = NULL; new->priority = 0; @@ -87,6 +99,7 @@ _resource_free (Resource *resource) g_free (resource->name); g_free (resource->status_message); gabble_capability_set_free (resource->cap_set); + g_ptr_array_unref (resource->data_forms); g_slice_free (Resource, resource); } @@ -103,6 +116,7 @@ gabble_presence_finalize (GObject *object) g_slist_free (priv->resources); gabble_capability_set_free (priv->cap_set); + g_ptr_array_unref (priv->data_forms); g_free (presence->nickname); g_free (presence->avatar_sha1); @@ -128,6 +142,8 @@ gabble_presence_init (GabblePresence *self) priv = self->priv; priv->cap_set = gabble_capability_set_new (); + priv->data_forms = g_ptr_array_new_with_free_func ( + (GDestroyNotify) g_object_unref); priv->resources = NULL; self->status = GABBLE_PRESENCE_UNKNOWN; @@ -198,6 +214,13 @@ gabble_presence_peek_caps (GabblePresence *presence) return presence->priv->cap_set; } +GPtrArray * +gabble_presence_peek_data_forms (GabblePresence *presence) +{ + g_return_val_if_fail (presence != NULL, NULL); + return presence->priv->data_forms; +} + gboolean gabble_presence_has_resources (GabblePresence *self) { @@ -266,10 +289,22 @@ gabble_presence_resource_has_caps (GabblePresence *presence, return FALSE; } +static void +extend_and_dup (GPtrArray *target, + GPtrArray *source) +{ + if (source == NULL) + return; + + g_ptr_array_foreach (source, (GFunc) g_object_ref, NULL); + tp_g_ptr_array_extend (target, source); +} + void gabble_presence_set_capabilities (GabblePresence *presence, const gchar *resource, const GabbleCapabilitySet *cap_set, + const GPtrArray *data_forms, guint serial) { GabblePresencePrivate *priv = presence->priv; @@ -288,11 +323,13 @@ gabble_presence_set_capabilities (GabblePresence *presence, } gabble_capability_set_clear (priv->cap_set); + g_ptr_array_set_size (priv->data_forms, 0); if (resource == NULL) { DEBUG ("Setting capabilities for bare JID"); gabble_capability_set_update (priv->cap_set, cap_set); + extend_and_dup (priv->data_forms, (GPtrArray *) data_forms); return; } @@ -315,6 +352,7 @@ gabble_presence_set_capabilities (GabblePresence *presence, tmp->caps_serial); tmp->caps_serial = serial; gabble_capability_set_clear (tmp->cap_set); + g_ptr_array_set_size (tmp->data_forms, 0); } if (serial >= tmp->caps_serial) @@ -322,11 +360,19 @@ gabble_presence_set_capabilities (GabblePresence *presence, DEBUG ("updating caps for resource %s", resource); gabble_capability_set_update (tmp->cap_set, cap_set); + + /* TODO: deal with duplicates */ + extend_and_dup (tmp->data_forms, (GPtrArray *) data_forms); } } gabble_capability_set_update (priv->cap_set, tmp->cap_set); + + /* TODO: deal with duplicates */ + extend_and_dup (priv->data_forms, tmp->data_forms); } + + g_signal_emit_by_name (presence, "capabilities-changed"); } static Resource * @@ -855,3 +901,20 @@ gabble_presence_get_client_types_array (GabblePresence *presence, return (gchar **) g_ptr_array_free (array, FALSE); } + +static const GPtrArray * +gabble_presence_get_data_forms (WockyXep0115Capabilities *caps) +{ + GabblePresence *presence = GABBLE_PRESENCE (caps); + + return presence->priv->data_forms; +} + +static void +xep_0115_capabilities_iface_init (gpointer g_iface, + gpointer iface_data) +{ + WockyXep0115CapabilitiesInterface *iface = g_iface; + + iface->get_data_forms = gabble_presence_get_data_forms; +} diff --git a/src/presence.h b/src/presence.h index 4f9126d0..50d6945a 100644 --- a/src/presence.h +++ b/src/presence.h @@ -24,7 +24,7 @@ #include <glib-object.h> -#include "capabilities.h" +#include "gabble/capabilities.h" #include "connection.h" #include "types.h" @@ -96,11 +96,13 @@ gboolean gabble_presence_update (GabblePresence *presence, void gabble_presence_set_capabilities (GabblePresence *presence, const gchar *resource, const GabbleCapabilitySet *cap_set, + const GPtrArray *data_forms, guint serial); gboolean gabble_presence_has_cap (GabblePresence *presence, const gchar *ns); GabbleCapabilitySet *gabble_presence_dup_caps (GabblePresence *presence); const GabbleCapabilitySet *gabble_presence_peek_caps (GabblePresence *presence); +GPtrArray *gabble_presence_peek_data_forms (GabblePresence *presence); gboolean gabble_presence_has_resources (GabblePresence *self); diff --git a/src/private-tubes-factory.c b/src/private-tubes-factory.c index 4ec36fd1..52c10a84 100644 --- a/src/private-tubes-factory.c +++ b/src/private-tubes-factory.c @@ -36,8 +36,7 @@ #define DEBUG_FLAG GABBLE_DEBUG_TUBES -#include "caps-channel-manager.h" -#include "capabilities.h" +#include "gabble/caps-channel-manager.h" #include "connection.h" #include "debug.h" #include "muc-channel.h" @@ -612,7 +611,8 @@ gabble_private_tubes_factory_represent_client ( const gchar *client_name, const GPtrArray *filters, const gchar * const *cap_tokens, - GabbleCapabilitySet *cap_set) + GabbleCapabilitySet *cap_set, + GPtrArray *data_forms) { guint i; diff --git a/src/roomlist-manager.c b/src/roomlist-manager.c index 76abee68..5f38a102 100644 --- a/src/roomlist-manager.c +++ b/src/roomlist-manager.c @@ -33,7 +33,7 @@ #define DEBUG_FLAG GABBLE_DEBUG_MUC -#include "caps-channel-manager.h" +#include "gabble/caps-channel-manager.h" #include "connection.h" #include "debug.h" #include "namespaces.h" diff --git a/src/roster.c b/src/roster.c index 798b83c6..8d8c3b7b 100644 --- a/src/roster.c +++ b/src/roster.c @@ -37,7 +37,7 @@ #define DEBUG_FLAG GABBLE_DEBUG_ROSTER -#include "caps-channel-manager.h" +#include "gabble/caps-channel-manager.h" #include "conn-aliasing.h" #include "conn-presence.h" #include "conn-util.h" diff --git a/src/search-manager.c b/src/search-manager.c index d3c1fa57..fec4b74d 100644 --- a/src/search-manager.c +++ b/src/search-manager.c @@ -29,7 +29,7 @@ #define DEBUG_FLAG GABBLE_DEBUG_SEARCH -#include "caps-channel-manager.h" +#include "gabble/caps-channel-manager.h" #include "connection.h" #include "debug.h" #include "disco.h" diff --git a/src/server-tls-manager.c b/src/server-tls-manager.c index 62ab8865..48364512 100644 --- a/src/server-tls-manager.c +++ b/src/server-tls-manager.c @@ -23,7 +23,7 @@ #define DEBUG_FLAG GABBLE_DEBUG_TLS #include "debug.h" -#include "caps-channel-manager.h" +#include "gabble/caps-channel-manager.h" #include "connection.h" #include "server-tls-channel.h" #include "util.h" |