summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimon McVittie <simon.mcvittie@collabora.co.uk>2010-11-01 13:16:32 +0000
committerSimon McVittie <simon.mcvittie@collabora.co.uk>2010-11-05 12:28:30 +0000
commitc26759d1cda55c8212c9f3c4700f62c646fdd837 (patch)
tree2241b874887972ba693cbc58b060b54b213de297
parent2cb3acc20fcf252517a6b94f66f37f09756ba2b9 (diff)
downloadtelepathy-salut-c26759d1cda55c8212c9f3c4700f62c646fdd837.tar.gz
Import GabbleCapsChannelManager and related classes
From Gabble, with minimal modifications: - put gabble/namespaces.h in gabble_namespaces.h - include capabilities-set.h instead of gabble/capabilities-set.h - use DEBUG_PRESENCE instead of GABBLE_DEBUG_PRESENCE
-rw-r--r--src/Makefile.am7
-rw-r--r--src/capabilities-set.h86
-rw-r--r--src/capabilities.c752
-rw-r--r--src/capabilities.h73
-rw-r--r--src/caps-channel-manager.c126
-rw-r--r--src/caps-channel-manager.h106
-rw-r--r--src/gabble_namespaces.h27
-rw-r--r--src/namespaces.h118
8 files changed, 1295 insertions, 0 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index 8e3d0264..294fb23d 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -15,6 +15,13 @@ libexec_PROGRAMS=telepathy-salut
noinst_PROGRAMS = write-mgr-file
CORE_SOURCES = \
+ capabilities.c \
+ capabilities.h \
+ capabilities-set.h \
+ caps-channel-manager.c \
+ caps-channel-manager.h \
+ gabble_namespaces.h \
+ namespaces.h \
salut-capabilities.c \
salut-capabilities.h \
salut-caps-channel-manager.c \
diff --git a/src/capabilities-set.h b/src/capabilities-set.h
new file mode 100644
index 00000000..3f215259
--- /dev/null
+++ b/src/capabilities-set.h
@@ -0,0 +1,86 @@
+/*
+ * capabilities-set.h - capabilities set API available to telepathy-gabble plugins
+ * Copyright (C) 2005-2010 Collabora Ltd.
+ * Copyright (C) 2005-2010 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_PLUGINS_CAPABILITIES_SET_H
+#define GABBLE_PLUGINS_CAPABILITIES_SET_H
+
+#include <glib-object.h>
+
+#include <wocky/wocky-node.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GabbleCapabilitySet:
+ *
+ * A set of capabilities.
+ */
+typedef struct _GabbleCapabilitySet GabbleCapabilitySet;
+
+GabbleCapabilitySet *gabble_capability_set_new (void);
+GabbleCapabilitySet *gabble_capability_set_new_from_stanza (
+ WockyNode *query_result);
+GabbleCapabilitySet *gabble_capability_set_copy (
+ const GabbleCapabilitySet *caps);
+void gabble_capability_set_update (GabbleCapabilitySet *target,
+ const GabbleCapabilitySet *source);
+void gabble_capability_set_add (GabbleCapabilitySet *caps,
+ const gchar *cap);
+gboolean gabble_capability_set_remove (GabbleCapabilitySet *caps,
+ const gchar *cap);
+void gabble_capability_set_exclude (GabbleCapabilitySet *caps,
+ const GabbleCapabilitySet *removed);
+void gabble_capability_set_intersect (GabbleCapabilitySet *target,
+ const GabbleCapabilitySet *source);
+gint gabble_capability_set_size (const GabbleCapabilitySet *caps);
+gboolean gabble_capability_set_has (const GabbleCapabilitySet *caps,
+ const gchar *cap);
+gboolean gabble_capability_set_has_one (const GabbleCapabilitySet *caps,
+ const GabbleCapabilitySet *alternatives);
+gboolean gabble_capability_set_at_least (const GabbleCapabilitySet *caps,
+ const GabbleCapabilitySet *query);
+gboolean gabble_capability_set_equals (const GabbleCapabilitySet *a,
+ const GabbleCapabilitySet *b);
+void gabble_capability_set_clear (GabbleCapabilitySet *caps);
+void gabble_capability_set_free (GabbleCapabilitySet *caps);
+void gabble_capability_set_foreach (const GabbleCapabilitySet *caps,
+ GFunc func, gpointer user_data);
+gchar *gabble_capability_set_dump (const GabbleCapabilitySet *caps,
+ const gchar *indent);
+gchar *gabble_capability_set_dump_diff (const GabbleCapabilitySet *old_caps,
+ const GabbleCapabilitySet *new_caps,
+ const gchar *indent);
+
+typedef gboolean (*GabbleCapabilitySetPredicate) (
+ const GabbleCapabilitySet *set, gconstpointer user_data);
+/* These functions are compatible with GabbleCapabilitySetPredicate;
+ * pass in the desired capabilities as the user_data */
+#define gabble_capability_set_predicate_equals \
+ ((GabbleCapabilitySetPredicate) gabble_capability_set_equals)
+#define gabble_capability_set_predicate_has \
+ ((GabbleCapabilitySetPredicate) gabble_capability_set_has)
+#define gabble_capability_set_predicate_has_one \
+ ((GabbleCapabilitySetPredicate) gabble_capability_set_has_one)
+#define gabble_capability_set_predicate_at_least \
+ ((GabbleCapabilitySetPredicate) gabble_capability_set_at_least)
+
+G_END_DECLS
+
+#endif
diff --git a/src/capabilities.c b/src/capabilities.c
new file mode 100644
index 00000000..07e76d82
--- /dev/null
+++ b/src/capabilities.c
@@ -0,0 +1,752 @@
+/*
+ * capabilities.c - 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
+ */
+
+#include "config.h"
+#include "capabilities.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <telepathy-glib/interfaces.h>
+#include <telepathy-glib/channel-manager.h>
+#include <telepathy-glib/handle-repo.h>
+#include <telepathy-glib/handle-repo-dynamic.h>
+#include <telepathy-glib/util.h>
+
+#define DEBUG_FLAG DEBUG_PRESENCE
+#include "debug.h"
+#include "namespaces.h"
+
+typedef struct _Feature Feature;
+
+struct _Feature
+{
+ enum {
+ FEATURE_FIXED,
+ FEATURE_OPTIONAL,
+ FEATURE_OLPC
+ } feature_type;
+ gchar *ns;
+};
+
+static const Feature self_advertised_features[] =
+{
+ { FEATURE_FIXED, NS_GOOGLE_FEAT_SESSION },
+ { FEATURE_FIXED, NS_JINGLE_TRANSPORT_RAWUDP },
+ { FEATURE_FIXED, NS_JINGLE015 },
+ { FEATURE_FIXED, NS_JINGLE032 },
+ { FEATURE_FIXED, NS_CHAT_STATES },
+ { FEATURE_FIXED, NS_NICK },
+ { FEATURE_FIXED, NS_NICK "+notify" },
+ { FEATURE_FIXED, NS_SI },
+ { FEATURE_FIXED, NS_IBB },
+ { FEATURE_FIXED, NS_TUBES },
+ { FEATURE_FIXED, NS_BYTESTREAMS },
+ { FEATURE_OPTIONAL, NS_FILE_TRANSFER },
+
+ { FEATURE_OPTIONAL, NS_GOOGLE_TRANSPORT_P2P },
+ { FEATURE_OPTIONAL, NS_JINGLE_TRANSPORT_ICEUDP },
+
+ { FEATURE_OPTIONAL, NS_GOOGLE_FEAT_SHARE },
+ { FEATURE_OPTIONAL, NS_GOOGLE_FEAT_VOICE },
+ { FEATURE_OPTIONAL, NS_GOOGLE_FEAT_VIDEO },
+ { FEATURE_OPTIONAL, NS_JINGLE_DESCRIPTION_AUDIO },
+ { FEATURE_OPTIONAL, NS_JINGLE_DESCRIPTION_VIDEO },
+ { FEATURE_OPTIONAL, NS_JINGLE_RTP },
+ { FEATURE_OPTIONAL, NS_JINGLE_RTP_AUDIO },
+ { FEATURE_OPTIONAL, NS_JINGLE_RTP_VIDEO },
+
+ { FEATURE_OLPC, NS_OLPC_BUDDY_PROPS "+notify" },
+ { FEATURE_OLPC, NS_OLPC_ACTIVITIES "+notify" },
+ { FEATURE_OLPC, NS_OLPC_CURRENT_ACTIVITY "+notify" },
+ { FEATURE_OLPC, NS_OLPC_ACTIVITY_PROPS "+notify" },
+
+ { FEATURE_OPTIONAL, NS_GEOLOC "+notify" },
+
+ { 0, NULL }
+};
+
+static const Feature quirks[] = {
+ { 0, QUIRK_OMITS_CONTENT_CREATORS },
+ { 0, NULL }
+};
+
+static GabbleCapabilitySet *legacy_caps = NULL;
+static GabbleCapabilitySet *share_v1_caps = NULL;
+static GabbleCapabilitySet *voice_v1_caps = NULL;
+static GabbleCapabilitySet *video_v1_caps = NULL;
+static GabbleCapabilitySet *any_audio_caps = NULL;
+static GabbleCapabilitySet *any_video_caps = NULL;
+static GabbleCapabilitySet *any_audio_video_caps = NULL;
+static GabbleCapabilitySet *any_google_av_caps = NULL;
+static GabbleCapabilitySet *any_jingle_av_caps = NULL;
+static GabbleCapabilitySet *any_transport_caps = NULL;
+static GabbleCapabilitySet *fixed_caps = NULL;
+static GabbleCapabilitySet *geoloc_caps = NULL;
+static GabbleCapabilitySet *olpc_caps = NULL;
+
+const GabbleCapabilitySet *
+gabble_capabilities_get_legacy (void)
+{
+ return legacy_caps;
+}
+
+const GabbleCapabilitySet *
+gabble_capabilities_get_bundle_share_v1 (void)
+{
+ return share_v1_caps;
+}
+
+const GabbleCapabilitySet *
+gabble_capabilities_get_bundle_voice_v1 (void)
+{
+ return voice_v1_caps;
+}
+
+const GabbleCapabilitySet *
+gabble_capabilities_get_bundle_video_v1 (void)
+{
+ return video_v1_caps;
+}
+
+const GabbleCapabilitySet *
+gabble_capabilities_get_any_audio (void)
+{
+ return any_audio_caps;
+}
+
+const GabbleCapabilitySet *
+gabble_capabilities_get_any_video (void)
+{
+ return any_video_caps;
+}
+
+const GabbleCapabilitySet *
+gabble_capabilities_get_any_audio_video (void)
+{
+ return any_audio_video_caps;
+}
+
+const GabbleCapabilitySet *
+gabble_capabilities_get_any_google_av (void)
+{
+ return any_google_av_caps;
+}
+
+const GabbleCapabilitySet *
+gabble_capabilities_get_any_jingle_av (void)
+{
+ return any_jingle_av_caps;
+}
+
+const GabbleCapabilitySet *
+gabble_capabilities_get_any_transport (void)
+{
+ return any_transport_caps;
+}
+
+const GabbleCapabilitySet *
+gabble_capabilities_get_fixed_caps (void)
+{
+ return fixed_caps;
+}
+
+const GabbleCapabilitySet *
+gabble_capabilities_get_geoloc_notify (void)
+{
+ return geoloc_caps;
+}
+
+const GabbleCapabilitySet *
+gabble_capabilities_get_olpc_notify (void)
+{
+ return olpc_caps;
+}
+
+static gboolean
+omits_content_creators (WockyNode *identity)
+{
+ const gchar *name, *suffix;
+ gchar *end;
+ int ver;
+
+ name = wocky_node_get_attribute (identity, "name");
+
+ if (name == NULL)
+ return FALSE;
+
+#define PREFIX "Telepathy Gabble 0.7."
+
+ if (!g_str_has_prefix (name, PREFIX))
+ return FALSE;
+
+ suffix = name + strlen (PREFIX);
+ ver = strtol (suffix, &end, 10);
+
+ if (*end != '\0')
+ return FALSE;
+
+ /* Gabble versions since 0.7.16 did not send the creator='' attribute for
+ * contents. The bug is fixed in 0.7.29.
+ */
+ if (ver >= 16 && ver < 29)
+ {
+ DEBUG ("contact is using '%s' which omits 'creator'", name);
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+
+static gsize feature_handles_refcount = 0;
+/* The handles in this repository are not really handles in the tp-spec sense
+ * of the word; we're just using it as a convenient implementation of a
+ * refcounted string pool. Their string values are either XMPP namespaces,
+ * or "quirk" pseudo-namespaces starting with QUIRK_PREFIX_CHAR (like
+ * QUIRK_OMITS_CONTENT_CREATORS). */
+static TpHandleRepoIface *feature_handles = NULL;
+
+void
+gabble_capabilities_init (gpointer conn)
+{
+ DEBUG ("%p", conn);
+
+ if (feature_handles_refcount++ == 0)
+ {
+ const Feature *feat;
+
+ g_assert (feature_handles == NULL);
+ /* TpDynamicHandleRepo wants a handle type, which isn't relevant here
+ * (we're just using it as a string pool). Use an arbitrary handle type
+ * to shut it up. */
+ feature_handles = tp_dynamic_handle_repo_new (TP_HANDLE_TYPE_CONTACT,
+ NULL, NULL);
+
+ /* make the pre-cooked bundles */
+
+ legacy_caps = gabble_capability_set_new ();
+
+ for (feat = self_advertised_features; feat->ns != NULL; feat++)
+ {
+ gabble_capability_set_add (legacy_caps, feat->ns);
+ }
+
+ share_v1_caps = gabble_capability_set_new ();
+ gabble_capability_set_add (share_v1_caps, NS_GOOGLE_FEAT_SHARE);
+
+ voice_v1_caps = gabble_capability_set_new ();
+ gabble_capability_set_add (voice_v1_caps, NS_GOOGLE_FEAT_VOICE);
+
+ video_v1_caps = gabble_capability_set_new ();
+ gabble_capability_set_add (video_v1_caps, NS_GOOGLE_FEAT_VIDEO);
+
+ any_audio_caps = gabble_capability_set_new ();
+ gabble_capability_set_add (any_audio_caps, NS_JINGLE_RTP_AUDIO);
+ gabble_capability_set_add (any_audio_caps, NS_JINGLE_DESCRIPTION_AUDIO);
+ gabble_capability_set_add (any_audio_caps, NS_GOOGLE_FEAT_VOICE);
+
+ any_video_caps = gabble_capability_set_new ();
+ gabble_capability_set_add (any_video_caps, NS_JINGLE_RTP_VIDEO);
+ gabble_capability_set_add (any_video_caps, NS_JINGLE_DESCRIPTION_VIDEO);
+ gabble_capability_set_add (any_video_caps, NS_GOOGLE_FEAT_VIDEO);
+
+ any_audio_video_caps = gabble_capability_set_copy (any_audio_caps);
+ gabble_capability_set_update (any_audio_video_caps, any_video_caps);
+
+ any_google_av_caps = gabble_capability_set_new ();
+ gabble_capability_set_add (any_google_av_caps, NS_GOOGLE_FEAT_VOICE);
+ gabble_capability_set_add (any_google_av_caps, NS_GOOGLE_FEAT_VIDEO);
+
+ any_jingle_av_caps = gabble_capability_set_copy (any_audio_caps);
+ gabble_capability_set_update (any_jingle_av_caps, any_video_caps);
+ gabble_capability_set_exclude (any_jingle_av_caps, any_google_av_caps);
+
+ any_transport_caps = gabble_capability_set_new ();
+ gabble_capability_set_add (any_transport_caps, NS_GOOGLE_TRANSPORT_P2P);
+ gabble_capability_set_add (any_transport_caps, NS_JINGLE_TRANSPORT_ICEUDP);
+ gabble_capability_set_add (any_transport_caps, NS_JINGLE_TRANSPORT_RAWUDP);
+
+ fixed_caps = gabble_capability_set_new ();
+
+ for (feat = self_advertised_features; feat->ns != NULL; feat++)
+ {
+ if (feat->feature_type == FEATURE_FIXED)
+ gabble_capability_set_add (fixed_caps, feat->ns);
+ }
+
+ geoloc_caps = gabble_capability_set_new ();
+ gabble_capability_set_add (geoloc_caps, NS_GEOLOC "+notify");
+
+ olpc_caps = gabble_capability_set_new ();
+
+ for (feat = self_advertised_features; feat->ns != NULL; feat++)
+ {
+ if (feat->feature_type == FEATURE_OLPC)
+ gabble_capability_set_add (olpc_caps, feat->ns);
+ }
+ }
+
+ g_assert (feature_handles != NULL);
+}
+
+void
+gabble_capabilities_finalize (gpointer conn)
+{
+ DEBUG ("%p", conn);
+
+ g_assert (feature_handles_refcount > 0);
+
+ if (--feature_handles_refcount == 0)
+ {
+ gabble_capability_set_free (legacy_caps);
+ gabble_capability_set_free (share_v1_caps);
+ gabble_capability_set_free (voice_v1_caps);
+ gabble_capability_set_free (video_v1_caps);
+ gabble_capability_set_free (any_audio_caps);
+ gabble_capability_set_free (any_video_caps);
+ gabble_capability_set_free (any_audio_video_caps);
+ gabble_capability_set_free (any_google_av_caps);
+ gabble_capability_set_free (any_jingle_av_caps);
+ gabble_capability_set_free (any_transport_caps);
+ gabble_capability_set_free (fixed_caps);
+ gabble_capability_set_free (geoloc_caps);
+ gabble_capability_set_free (olpc_caps);
+
+ legacy_caps = NULL;
+ share_v1_caps = NULL;
+ voice_v1_caps = NULL;
+ video_v1_caps = NULL;
+ any_audio_caps = NULL;
+ any_video_caps = NULL;
+ any_audio_video_caps = NULL;
+ any_google_av_caps = NULL;
+ any_jingle_av_caps = NULL;
+ any_transport_caps = NULL;
+ fixed_caps = NULL;
+ geoloc_caps = NULL;
+ olpc_caps = NULL;
+
+ tp_clear_object (&feature_handles);
+ }
+}
+
+struct _GabbleCapabilitySet {
+ TpHandleSet *handles;
+};
+
+GabbleCapabilitySet *
+gabble_capability_set_new (void)
+{
+ GabbleCapabilitySet *ret = g_slice_new0 (GabbleCapabilitySet);
+
+ g_assert (feature_handles != NULL);
+ ret->handles = tp_handle_set_new (feature_handles);
+ return ret;
+}
+
+GabbleCapabilitySet *
+gabble_capability_set_new_from_stanza (WockyNode *query_result)
+{
+ GabbleCapabilitySet *ret;
+ const gchar *var;
+ GSList *ni;
+
+ g_return_val_if_fail (query_result != NULL, NULL);
+
+ ret = gabble_capability_set_new ();
+
+ for (ni = query_result->children; ni != NULL; ni = g_slist_next (ni))
+ {
+ WockyNode *child = ni->data;
+
+ if (!tp_strdiff (child->name, "identity"))
+ {
+ if (omits_content_creators (child))
+ gabble_capability_set_add (ret, QUIRK_OMITS_CONTENT_CREATORS);
+
+ continue;
+ }
+
+ if (tp_strdiff (child->name, "feature"))
+ continue;
+
+ var = wocky_node_get_attribute (child, "var");
+
+ if (NULL == var)
+ continue;
+
+ if (G_UNLIKELY (var[0] == QUIRK_PREFIX_CHAR))
+ {
+ /* I think not! (It's not allowed in XML...) */
+ continue;
+ }
+
+ /* TODO: only store namespaces we understand. */
+ gabble_capability_set_add (ret, var);
+ }
+
+ return ret;
+}
+
+GabbleCapabilitySet *
+gabble_capability_set_copy (const GabbleCapabilitySet *caps)
+{
+ GabbleCapabilitySet *ret;
+
+ g_return_val_if_fail (caps != NULL, NULL);
+
+ ret = gabble_capability_set_new ();
+
+ gabble_capability_set_update (ret, caps);
+
+ return ret;
+}
+
+void
+gabble_capability_set_update (GabbleCapabilitySet *target,
+ const GabbleCapabilitySet *source)
+{
+ TpIntSet *ret;
+ g_return_if_fail (target != NULL);
+ g_return_if_fail (source != NULL);
+
+ ret = tp_handle_set_update (target->handles,
+ tp_handle_set_peek (source->handles));
+
+ tp_intset_destroy (ret);
+}
+
+typedef struct {
+ GSList *deleted;
+ TpHandleSet *intersect_with;
+} IntersectHelper;
+
+static void
+intersect_helper (TpHandleSet *unused G_GNUC_UNUSED,
+ TpHandle handle,
+ gpointer p)
+{
+ IntersectHelper *data = p;
+
+ if (!tp_handle_set_is_member (data->intersect_with, handle))
+ data->deleted = g_slist_prepend (data->deleted, GUINT_TO_POINTER (handle));
+}
+
+void
+gabble_capability_set_intersect (GabbleCapabilitySet *target,
+ const GabbleCapabilitySet *source)
+{
+ IntersectHelper data = { NULL, NULL };
+
+ g_return_if_fail (target != NULL);
+ g_return_if_fail (source != NULL);
+
+ if (target == source)
+ return;
+
+ data.intersect_with = source->handles;
+
+ tp_handle_set_foreach (target->handles, intersect_helper, &data);
+
+ while (data.deleted != NULL)
+ {
+ DEBUG ("dropping %s", tp_handle_inspect (feature_handles,
+ GPOINTER_TO_UINT (data.deleted->data)));
+ tp_handle_set_remove (target->handles,
+ GPOINTER_TO_UINT (data.deleted->data));
+ data.deleted = g_slist_delete_link (data.deleted, data.deleted);
+ }
+}
+
+static void
+remove_from_set (TpHandleSet *unused G_GNUC_UNUSED,
+ TpHandle handle,
+ gpointer handles)
+{
+ tp_handle_set_remove (handles, handle);
+}
+
+void
+gabble_capability_set_exclude (GabbleCapabilitySet *caps,
+ const GabbleCapabilitySet *removed)
+{
+ g_return_if_fail (caps != NULL);
+ g_return_if_fail (removed != NULL);
+
+ if (caps == removed)
+ {
+ gabble_capability_set_clear (caps);
+ return;
+ }
+
+ tp_handle_set_foreach (removed->handles, remove_from_set, caps->handles);
+}
+
+void
+gabble_capability_set_add (GabbleCapabilitySet *caps,
+ const gchar *cap)
+{
+ TpHandle handle;
+
+ g_return_if_fail (caps != NULL);
+ g_return_if_fail (cap != NULL);
+
+ handle = tp_handle_ensure (feature_handles, cap, NULL, NULL);
+
+ tp_handle_set_add (caps->handles, handle);
+ tp_handle_unref (feature_handles, handle);
+}
+
+gboolean
+gabble_capability_set_remove (GabbleCapabilitySet *caps,
+ const gchar *cap)
+{
+ TpHandle handle;
+
+ g_return_val_if_fail (caps != NULL, FALSE);
+ g_return_val_if_fail (cap != NULL, FALSE);
+
+ handle = tp_handle_lookup (feature_handles, cap, NULL, NULL);
+
+ if (handle == 0)
+ return FALSE;
+
+ return tp_handle_set_remove (caps->handles, handle);
+}
+
+void
+gabble_capability_set_clear (GabbleCapabilitySet *caps)
+{
+ g_return_if_fail (caps != NULL);
+
+ /* There is no tp_handle_set_clear, so do the next best thing */
+ tp_handle_set_destroy (caps->handles);
+ caps->handles = tp_handle_set_new (feature_handles);
+}
+
+void
+gabble_capability_set_free (GabbleCapabilitySet *caps)
+{
+ g_return_if_fail (caps != NULL);
+
+ tp_handle_set_destroy (caps->handles);
+ g_slice_free (GabbleCapabilitySet, caps);
+}
+
+gint
+gabble_capability_set_size (const GabbleCapabilitySet *caps)
+{
+ g_return_val_if_fail (caps != NULL, 0);
+ return tp_handle_set_size (caps->handles);
+}
+
+/* By design, this function can be used as a GabbleCapabilitySetPredicate */
+gboolean
+gabble_capability_set_has (const GabbleCapabilitySet *caps,
+ const gchar *cap)
+{
+ TpHandle handle;
+
+ g_return_val_if_fail (caps != NULL, FALSE);
+ g_return_val_if_fail (cap != NULL, FALSE);
+
+ handle = tp_handle_lookup (feature_handles, cap, NULL, NULL);
+
+ if (handle == 0)
+ {
+ /* nobody in the whole CM has this capability */
+ return FALSE;
+ }
+
+ return tp_handle_set_is_member (caps->handles, handle);
+}
+
+/* By design, this function can be used as a GabbleCapabilitySetPredicate */
+gboolean
+gabble_capability_set_has_one (const GabbleCapabilitySet *caps,
+ const GabbleCapabilitySet *alternatives)
+{
+ TpIntSetIter iter;
+
+ g_return_val_if_fail (caps != NULL, FALSE);
+ g_return_val_if_fail (alternatives != NULL, FALSE);
+
+ tp_intset_iter_init (&iter, tp_handle_set_peek (alternatives->handles));
+
+ while (tp_intset_iter_next (&iter))
+ {
+ if (tp_handle_set_is_member (caps->handles, iter.element))
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+/* By design, this function can be used as a GabbleCapabilitySetPredicate */
+gboolean
+gabble_capability_set_at_least (const GabbleCapabilitySet *caps,
+ const GabbleCapabilitySet *query)
+{
+ TpIntSetIter iter;
+
+ g_return_val_if_fail (caps != NULL, FALSE);
+ g_return_val_if_fail (query != NULL, FALSE);
+
+ tp_intset_iter_init (&iter, tp_handle_set_peek (query->handles));
+
+ while (tp_intset_iter_next (&iter))
+ {
+ if (!tp_handle_set_is_member (caps->handles, iter.element))
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+gboolean
+gabble_capability_set_equals (const GabbleCapabilitySet *a,
+ const GabbleCapabilitySet *b)
+{
+ g_return_val_if_fail (a != NULL, FALSE);
+ g_return_val_if_fail (b != NULL, FALSE);
+
+ return tp_intset_is_equal (tp_handle_set_peek (a->handles),
+ tp_handle_set_peek (b->handles));
+}
+
+/* Does not iterate over quirks, only real features. */
+void
+gabble_capability_set_foreach (const GabbleCapabilitySet *caps,
+ GFunc func, gpointer user_data)
+{
+ TpIntSetIter iter;
+
+ g_return_if_fail (caps != NULL);
+ g_return_if_fail (func != NULL);
+
+ tp_intset_iter_init (&iter, tp_handle_set_peek (caps->handles));
+
+ while (tp_intset_iter_next (&iter))
+ {
+ const gchar *var = tp_handle_inspect (feature_handles, iter.element);
+
+ g_return_if_fail (var != NULL);
+
+ if (var[0] != QUIRK_PREFIX_CHAR)
+ func ((gchar *) var, user_data);
+ }
+}
+
+static void
+append_intset (GString *ret,
+ const TpIntSet *cap_ints,
+ const gchar *indent)
+{
+ TpIntSetFastIter iter;
+ guint element;
+
+ tp_intset_fast_iter_init (&iter, cap_ints);
+
+ while (tp_intset_fast_iter_next (&iter, &element))
+ {
+ const gchar *var = tp_handle_inspect (feature_handles, element);
+
+ g_return_if_fail (var != NULL);
+
+ if (var[0] == QUIRK_PREFIX_CHAR)
+ {
+ g_string_append_printf (ret, "%sQuirk: %s\n", indent, var + 1);
+ }
+ else
+ {
+ g_string_append_printf (ret, "%sFeature: %s\n", indent, var);
+ }
+ }
+}
+
+gchar *
+gabble_capability_set_dump (const GabbleCapabilitySet *caps,
+ const gchar *indent)
+{
+ GString *ret;
+
+ g_return_val_if_fail (caps != NULL, NULL);
+
+ if (indent == NULL)
+ indent = "";
+
+ ret = g_string_new (indent);
+ g_string_append (ret, "--begin--\n");
+ append_intset (ret, tp_handle_set_peek (caps->handles), indent);
+ g_string_append (ret, indent);
+ g_string_append (ret, "--end--\n");
+ return g_string_free (ret, FALSE);
+}
+
+gchar *
+gabble_capability_set_dump_diff (const GabbleCapabilitySet *old_caps,
+ const GabbleCapabilitySet *new_caps,
+ const gchar *indent)
+{
+ TpIntSet *old_ints, *new_ints, *rem, *add;
+ GString *ret;
+
+ g_return_val_if_fail (old_caps != NULL, NULL);
+ g_return_val_if_fail (new_caps != NULL, NULL);
+
+ old_ints = tp_handle_set_peek (old_caps->handles);
+ new_ints = tp_handle_set_peek (new_caps->handles);
+
+ if (tp_intset_is_equal (old_ints, new_ints))
+ return g_strdup_printf ("%s--no change--", indent);
+
+ rem = tp_intset_difference (old_ints, new_ints);
+ add = tp_intset_difference (new_ints, old_ints);
+
+ ret = g_string_new ("");
+
+ if (!tp_intset_is_empty (rem))
+ {
+ g_string_append (ret, indent);
+ g_string_append (ret, "--removed--\n");
+ append_intset (ret, rem, indent);
+ }
+
+ if (!tp_intset_is_empty (add))
+ {
+ g_string_append (ret, indent);
+ g_string_append (ret, "--added--\n");
+ append_intset (ret, add, indent);
+ }
+
+ g_string_append (ret, indent);
+ g_string_append (ret, "--end--");
+
+ tp_intset_destroy (add);
+ tp_intset_destroy (rem);
+
+ return g_string_free (ret, FALSE);
+}
diff --git a/src/capabilities.h b/src/capabilities.h
new file mode 100644
index 00000000..52b4b0f6
--- /dev/null
+++ b/src/capabilities.h
@@ -0,0 +1,73 @@
+/*
+ * 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 "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_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
new file mode 100644
index 00000000..746a828f
--- /dev/null
+++ b/src/caps-channel-manager.c
@@ -0,0 +1,126 @@
+/*
+ * caps-channel-manager.c - 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
+ */
+
+#include "config.h"
+#include "caps-channel-manager.h"
+
+#include <telepathy-glib/dbus.h>
+#include <telepathy-glib/channel-manager.h>
+
+
+#define DEBUG_FLAG DEBUG_PRESENCE
+#include "debug.h"
+
+GType
+gabble_caps_channel_manager_get_type (void)
+{
+ static GType type = 0;
+
+ if (G_UNLIKELY (type == 0))
+ {
+ static const GTypeInfo info = {
+ sizeof (GabbleCapsChannelManagerIface),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ NULL, /* class_init */
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ 0,
+ 0, /* n_preallocs */
+ NULL /* instance_init */
+ };
+
+ type = g_type_register_static (G_TYPE_INTERFACE,
+ "GabbleCapsChannelManager", &info, 0);
+
+ g_type_interface_add_prerequisite (type, TP_TYPE_CHANNEL_MANAGER);
+ }
+
+ return type;
+}
+
+/* Virtual-method wrappers */
+void
+gabble_caps_channel_manager_reset_capabilities (
+ GabbleCapsChannelManager *caps_manager)
+{
+ GabbleCapsChannelManagerIface *iface =
+ GABBLE_CAPS_CHANNEL_MANAGER_GET_INTERFACE (caps_manager);
+ GabbleCapsChannelManagerResetCapsFunc method = iface->reset_caps;
+
+ if (method != NULL)
+ {
+ method (caps_manager);
+ }
+ /* ... else assume there is no need to reset the caps */
+}
+
+void
+gabble_caps_channel_manager_get_contact_capabilities (
+ GabbleCapsChannelManager *caps_manager,
+ TpHandle handle,
+ const GabbleCapabilitySet *caps,
+ GPtrArray *arr)
+{
+ GabbleCapsChannelManagerIface *iface =
+ GABBLE_CAPS_CHANNEL_MANAGER_GET_INTERFACE (caps_manager);
+ GabbleCapsChannelManagerGetContactCapsFunc method = iface->get_contact_caps;
+
+ if (method != NULL)
+ {
+ method (caps_manager, handle, caps, arr);
+ }
+ /* ... else assume there is not caps for this kind of channels */
+}
+
+/**
+ * gabble_caps_channel_manager_represent_client:
+ * @self: a channel manager
+ * @client_name: the name of the client, for any debug messages
+ * @filters: the channel classes accepted by the client, as an array of
+ * 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
+ *
+ * Convert the capabilities of a Telepathy client into XMPP capabilities to be
+ * advertised.
+ *
+ * (The actual XMPP capabilities advertised will be the union of the XMPP
+ * capabilities of every installed client.)
+ */
+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)
+{
+ GabbleCapsChannelManagerIface *iface =
+ GABBLE_CAPS_CHANNEL_MANAGER_GET_INTERFACE (caps_manager);
+ GabbleCapsChannelManagerRepresentClientFunc method = iface->represent_client;
+
+ if (method != NULL)
+ {
+ method (caps_manager, client_name, filters, cap_tokens, cap_set);
+ }
+}
diff --git a/src/caps-channel-manager.h b/src/caps-channel-manager.h
new file mode 100644
index 00000000..e5623bbf
--- /dev/null
+++ b/src/caps-channel-manager.h
@@ -0,0 +1,106 @@
+/*
+ * 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, GabbleCapsChannelManagerIface))
+
+typedef struct _GabbleCapsChannelManager GabbleCapsChannelManager;
+typedef struct _GabbleCapsChannelManagerIface GabbleCapsChannelManagerIface;
+
+
+/* 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 _GabbleCapsChannelManagerIface {
+ 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/gabble_namespaces.h b/src/gabble_namespaces.h
new file mode 100644
index 00000000..d8e145f2
--- /dev/null
+++ b/src/gabble_namespaces.h
@@ -0,0 +1,27 @@
+/*
+ * namespaces.h — namespace constants definitions that can be used by telepathy-gabble plugins
+ * Copyright © 2009 Collabora Ltd.
+ * Copyright © 2009 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_PLUGINS_NAMESPACES_H
+#define GABBLE_PLUGINS_NAMESPACES_H
+
+#define NS_CAPS "http://jabber.org/protocol/caps"
+#define NS_GABBLE_CAPS "http://telepathy.freedesktop.org/caps"
+
+#endif
diff --git a/src/namespaces.h b/src/namespaces.h
new file mode 100644
index 00000000..e0d2834b
--- /dev/null
+++ b/src/namespaces.h
@@ -0,0 +1,118 @@
+/*
+ * namespaces.h - XMPP namespace constants
+ * 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_NAMESPACES__H__
+#define __GABBLE_NAMESPACES__H__
+
+#include "gabble_namespaces.h"
+#include <wocky/wocky-namespaces.h>
+
+#define NS_AMP WOCKY_XMPP_NS_AMP
+#define NS_BYTESTREAMS "http://jabber.org/protocol/bytestreams"
+#define NS_CHAT_STATES WOCKY_NS_CHATSTATE
+#define NS_FEATURENEG WOCKY_XMPP_NS_FEATURENEG
+#define NS_FILE_TRANSFER "http://jabber.org/protocol/si/profile/file-transfer"
+#define NS_GOOGLE_CAPS "http://www.google.com/xmpp/client/caps"
+#define NS_GOOGLE_FEAT_SESSION "http://www.google.com/xmpp/protocol/session"
+#define NS_GOOGLE_FEAT_SHARE "http://google.com/xmpp/protocol/share/v1"
+#define NS_GOOGLE_FEAT_VOICE "http://www.google.com/xmpp/protocol/voice/v1"
+#define NS_GOOGLE_FEAT_VIDEO "http://www.google.com/xmpp/protocol/video/v1"
+#define NS_GOOGLE_JINGLE_INFO "google:jingleinfo"
+#define NS_GOOGLE_ROSTER "google:roster"
+#define NS_GOOGLE_QUEUE "google:queue"
+#define NS_IBB WOCKY_XMPP_NS_IBB
+
+/* Namespaces for XEP-0166 draft v0.15, the most capable Jingle dialect
+ * supported by telepathy-gabble < 0.7.16, including the versions shipped with
+ * Maemo Chinook and Diablo.
+ */
+#define NS_JINGLE015 "http://jabber.org/protocol/jingle"
+
+/* RTP audio capability in Jingle v0.15 (obsoleted by NS_JINGLE_RTP) */
+#define NS_JINGLE_DESCRIPTION_AUDIO \
+ "http://jabber.org/protocol/jingle/description/audio"
+/* RTP video capability in Jingle v0.15 (obsoleted by NS_JINGLE_RTP) */
+#define NS_JINGLE_DESCRIPTION_VIDEO \
+ "http://jabber.org/protocol/jingle/description/video"
+
+/* XEP-0166 draft */
+#define NS_JINGLE032 "urn:xmpp:jingle:1"
+#define NS_JINGLE_ERRORS "urn:xmpp:jingle:errors:1"
+
+/* XEP-0167 (Jingle RTP) */
+#define NS_JINGLE_RTP "urn:xmpp:jingle:apps:rtp:1"
+#define NS_JINGLE_RTP_ERRORS "urn:xmpp:jingle:apps:rtp:errors:1"
+#define NS_JINGLE_RTP_INFO "urn:xmpp:jingle:apps:rtp:info:1"
+#define NS_JINGLE_RTP_AUDIO "urn:xmpp:jingle:apps:rtp:audio"
+#define NS_JINGLE_RTP_VIDEO "urn:xmpp:jingle:apps:rtp:video"
+
+/* Google's Jingle dialect */
+#define NS_GOOGLE_SESSION "http://www.google.com/session"
+/* Audio capability in Google Jingle dialect */
+#define NS_GOOGLE_SESSION_PHONE "http://www.google.com/session/phone"
+/* Video capability in Google's Jingle dialect */
+#define NS_GOOGLE_SESSION_VIDEO "http://www.google.com/session/video"
+/* File transfer capability in Google's Jingle dialect */
+#define NS_GOOGLE_SESSION_SHARE "http://www.google.com/session/share"
+
+/* google-p2p transport */
+#define NS_GOOGLE_TRANSPORT_P2P "http://www.google.com/transport/p2p"
+/* Jingle RAW-UDP transport */
+#define NS_JINGLE_TRANSPORT_RAWUDP "urn:xmpp:jingle:transports:raw-udp:1"
+/* Jingle ICE-UDP transport */
+#define NS_JINGLE_TRANSPORT_ICEUDP "urn:xmpp:jingle:transports:ice-udp:1"
+
+#define NS_MUC "http://jabber.org/protocol/muc"
+#define NS_MUC_BYTESTREAM "http://telepathy.freedesktop.org/xmpp/protocol/muc-bytestream"
+#define NS_MUC_USER "http://jabber.org/protocol/muc#user"
+#define NS_MUC_ADMIN "http://jabber.org/protocol/muc#admin"
+#define NS_MUC_OWNER "http://jabber.org/protocol/muc#owner"
+#define NS_NICK "http://jabber.org/protocol/nick"
+#define NS_OOB "jabber:iq:oob"
+#define NS_OLPC_BUDDY_PROPS "http://laptop.org/xmpp/buddy-properties"
+#define NS_OLPC_ACTIVITIES "http://laptop.org/xmpp/activities"
+#define NS_OLPC_CURRENT_ACTIVITY "http://laptop.org/xmpp/current-activity"
+#define NS_OLPC_ACTIVITY_PROPS "http://laptop.org/xmpp/activity-properties"
+#define NS_OLPC_BUDDY "http://laptop.org/xmpp/buddy"
+#define NS_OLPC_ACTIVITY "http://laptop.org/xmpp/activity"
+#define NS_PUBSUB "http://jabber.org/protocol/pubsub"
+#define NS_PRESENCE_INVISIBLE "presence-invisible"
+#define NS_PRIVACY "jabber:iq:privacy"
+#define NS_INVISIBLE "urn:xmpp:invisible:0"
+#define NS_REGISTER "jabber:iq:register"
+#define NS_ROSTER "jabber:iq:roster"
+#define NS_SEARCH "jabber:iq:search"
+#define NS_SI "http://jabber.org/protocol/si"
+#define NS_SI_MULTIPLE "http://telepathy.freedesktop.org/xmpp/si-multiple"
+#define NS_TUBES "http://telepathy.freedesktop.org/xmpp/tubes"
+#define NS_MUJI "http://telepathy.freedesktop.org/xmpp/muji"
+#define NS_VCARD_TEMP "vcard-temp"
+#define NS_VCARD_TEMP_UPDATE "vcard-temp:x:update"
+#define NS_X_DATA "jabber:x:data"
+#define NS_X_DELAY "jabber:x:delay"
+#define NS_X_CONFERENCE "jabber:x:conference"
+#define NS_XMPP_STANZAS "urn:ietf:params:xml:ns:xmpp-stanzas"
+#define NS_GEOLOC "http://jabber.org/protocol/geoloc"
+#define NS_GOOGLE_MAIL_NOTIFY "google:mail:notify"
+
+#define NS_TEMPPRES "urn:xmpp:temppres:0"
+#define NS_GOOGLE_SHARED_STATUS "google:shared-status"
+
+#endif /* __GABBLE_NAMESPACES__H__ */