summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Thompson <will.thompson@collabora.co.uk>2012-12-12 16:08:34 +0000
committerWill Thompson <will.thompson@collabora.co.uk>2012-12-13 11:08:11 +0000
commite9cc205c266f628e74c47b4a1bb949be8cc4b8c3 (patch)
treead4d5e34ef9682cec153b237a9143714f5a535cb
parentf91a1063b57b8b50bd3301633e8620051be2e906 (diff)
Delete all the Jingle code which moved to Wocky
The astute reader will notice that I added a call to jingle_share_register() to jingle-mint.c.
-rw-r--r--src/Makefile.am24
-rw-r--r--src/google-relay.c325
-rw-r--r--src/google-relay.h45
-rw-r--r--src/jingle-content.c1407
-rw-r--r--src/jingle-content.h163
-rw-r--r--src/jingle-factory.c604
-rw-r--r--src/jingle-factory.h90
-rw-r--r--src/jingle-info-internal.h29
-rw-r--r--src/jingle-info.c730
-rw-r--r--src/jingle-info.h121
-rw-r--r--src/jingle-media-rtp.c1517
-rw-r--r--src/jingle-media-rtp.h124
-rw-r--r--src/jingle-mint.c3
-rw-r--r--src/jingle-session.c2447
-rw-r--r--src/jingle-session.h139
-rw-r--r--src/jingle-transport-google.c644
-rw-r--r--src/jingle-transport-google.h68
-rw-r--r--src/jingle-transport-iceudp.c617
-rw-r--r--src/jingle-transport-iceudp.h64
-rw-r--r--src/jingle-transport-iface.c283
-rw-r--r--src/jingle-transport-iface.h109
-rw-r--r--src/jingle-transport-rawudp.c404
-rw-r--r--src/jingle-transport-rawudp.h64
-rw-r--r--src/jingle-types.h125
24 files changed, 3 insertions, 10143 deletions
diff --git a/src/Makefile.am b/src/Makefile.am
index bb88ed6f9..22a0278db 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -157,34 +157,12 @@ libgabble_convenience_la_SOURCES += \
call-member-content.c \
call-stream.h \
call-stream.c \
- google-relay.c \
- google-relay.h \
- jingle-content.h \
- jingle-content.c \
- jingle-factory.h \
- jingle-factory.c \
- jingle-info-internal.h \
- jingle-info.c \
- jingle-info.h \
jingle-share.h \
jingle-share.c \
- jingle-media-rtp.h \
- jingle-media-rtp.c \
jingle-mint.h \
jingle-mint.c \
- jingle-session.h \
- jingle-session.c \
jingle-tp-util.h \
jingle-tp-util.c \
- jingle-transport-google.h \
- jingle-transport-google.c \
- jingle-transport-rawudp.h \
- jingle-transport-rawudp.c \
- jingle-transport-iceudp.h \
- jingle-transport-iceudp.c \
- jingle-transport-iface.h \
- jingle-transport-iface.c \
- jingle-types.h \
media-channel.h \
media-channel-internal.h \
media-channel.c \
@@ -203,8 +181,6 @@ endif
enumtype_sources = \
$(top_srcdir)/src/connection.h \
- $(top_srcdir)/src/jingle-types.h \
- $(top_srcdir)/src/jingle-info-internal.h \
$(top_srcdir)/src/room-config.h \
$(top_srcdir)/src/presence.h
diff --git a/src/google-relay.c b/src/google-relay.c
deleted file mode 100644
index 000deaa86..000000000
--- a/src/google-relay.c
+++ /dev/null
@@ -1,325 +0,0 @@
-/*
- * google-relay.c - Support for Google relays for Jingle
- *
- * Copyright (C) 2006-2008 Collabora Ltd.
- *
- * 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 "google-relay.h"
-
-#include <string.h>
-
-#ifdef ENABLE_GOOGLE_RELAY
-#include <libsoup/soup.h>
-#endif
-
-#define DEBUG_FLAG GABBLE_DEBUG_MEDIA
-
-#ifdef G_OS_WIN32
-#undef ERROR
-#endif
-
-#include "debug.h"
-
-#define RELAY_HTTP_TIMEOUT 5
-
-struct _WockyGoogleRelayResolver {
-#ifdef ENABLE_GOOGLE_RELAY
- SoupSession *soup;
-#else
- GObject *soup;
-#endif
-};
-
-typedef struct
-{
- GPtrArray *relays;
- guint component;
- guint requests_to_do;
- WockyJingleInfoRelaySessionCb callback;
- gpointer user_data;
-} RelaySessionData;
-
-static RelaySessionData *
-relay_session_data_new (guint requests_to_do,
- WockyJingleInfoRelaySessionCb callback,
- gpointer user_data)
-{
- RelaySessionData *rsd = g_slice_new0 (RelaySessionData);
-
- rsd->relays = g_ptr_array_sized_new (requests_to_do);
- g_ptr_array_set_free_func (rsd->relays, (GDestroyNotify) wocky_jingle_relay_free);
- rsd->component = 1;
- rsd->requests_to_do = requests_to_do;
- rsd->callback = callback;
- rsd->user_data = user_data;
-
- return rsd;
-}
-
-/* This is a GSourceFunc */
-static gboolean
-relay_session_data_call (gpointer p)
-{
- RelaySessionData *rsd = p;
-
- g_assert (rsd->callback != NULL);
-
- rsd->callback (rsd->relays, rsd->user_data);
-
- return FALSE;
-}
-
-/* This is a GDestroyNotify */
-static void
-relay_session_data_destroy (gpointer p)
-{
- RelaySessionData *rsd = p;
-
- g_ptr_array_unref (rsd->relays);
-
- g_slice_free (RelaySessionData, rsd);
-}
-
-#ifdef ENABLE_GOOGLE_RELAY
-
-static void
-translate_relay_info (GPtrArray *relays,
- const gchar *relay_ip,
- const gchar *username,
- const gchar *password,
- WockyJingleRelayType relay_type,
- const gchar *port_string,
- guint component)
-{
- guint64 portll;
- guint port;
-
- if (port_string == NULL)
- {
- DEBUG ("no relay port for %u found", relay_type);
- return;
- }
-
- portll = g_ascii_strtoull (port_string, NULL, 10);
-
- if (portll == 0 || portll > G_MAXUINT16)
- {
- DEBUG ("failed to parse relay port '%s' for %u", port_string,
- relay_type);
- return;
- }
- port = (guint) portll;
-
- DEBUG ("type=%u ip=%s port=%u username=%s password=%s component=%u",
- relay_type, relay_ip, port, username, password, component);
-
- g_ptr_array_add (relays,
- wocky_jingle_relay_new (relay_type, relay_ip, port, username, password,
- component));
-}
-
-static void
-on_http_response (SoupSession *soup,
- SoupMessage *msg,
- gpointer user_data)
-{
- RelaySessionData *rsd = user_data;
-
- if (msg->status_code != 200)
- {
- DEBUG ("Google session creation failed, relaying not used: %d %s",
- msg->status_code, msg->reason_phrase);
- }
- else
- {
- /* parse a=b lines into GHashTable
- * (key, value both borrowed from items of the strv 'lines') */
- GHashTable *map = g_hash_table_new (g_str_hash, g_str_equal);
- gchar **lines;
- guint i;
- const gchar *relay_ip;
- const gchar *relay_udp_port;
- const gchar *relay_tcp_port;
- const gchar *relay_ssltcp_port;
- const gchar *username;
- const gchar *password;
- gchar *escaped_str;
-
- escaped_str = g_strescape (msg->response_body->data, "\r\n");
- DEBUG ("Response from Google:\n====\n%s\n====", escaped_str);
- g_free (escaped_str);
-
- lines = g_strsplit (msg->response_body->data, "\n", 0);
-
- if (lines != NULL)
- {
- for (i = 0; lines[i] != NULL; i++)
- {
- gchar *delim = strchr (lines[i], '=');
- size_t len;
-
- if (delim == NULL || delim == lines[i])
- {
- /* ignore empty keys or lines without '=' */
- continue;
- }
-
- len = strlen (lines[i]);
-
- if (lines[i][len - 1] == '\r')
- {
- lines[i][len - 1] = '\0';
- }
-
- *delim = '\0';
- g_hash_table_insert (map, lines[i], delim + 1);
- }
- }
-
- relay_ip = g_hash_table_lookup (map, "relay.ip");
- relay_udp_port = g_hash_table_lookup (map, "relay.udp_port");
- relay_tcp_port = g_hash_table_lookup (map, "relay.tcp_port");
- relay_ssltcp_port = g_hash_table_lookup (map, "relay.ssltcp_port");
- username = g_hash_table_lookup (map, "username");
- password = g_hash_table_lookup (map, "password");
-
- if (relay_ip == NULL)
- {
- DEBUG ("No relay.ip found");
- }
- else if (username == NULL)
- {
- DEBUG ("No username found");
- }
- else if (password == NULL)
- {
- DEBUG ("No password found");
- }
- else
- {
- translate_relay_info (rsd->relays, relay_ip, username, password,
- WOCKY_JINGLE_RELAY_TYPE_UDP, relay_udp_port, rsd->component);
- translate_relay_info (rsd->relays, relay_ip, username, password,
- WOCKY_JINGLE_RELAY_TYPE_TCP, relay_tcp_port, rsd->component);
- translate_relay_info (rsd->relays, relay_ip, username, password,
- WOCKY_JINGLE_RELAY_TYPE_TLS, relay_ssltcp_port, rsd->component);
- }
-
- g_strfreev (lines);
- g_hash_table_unref (map);
- }
-
- rsd->component++;
-
- if ((--rsd->requests_to_do) == 0)
- {
- relay_session_data_call (rsd);
- relay_session_data_destroy (rsd);
- }
-}
-
-#endif /* ENABLE_GOOGLE_RELAY */
-
-WockyGoogleRelayResolver *
-wocky_google_relay_resolver_new (void)
-{
- WockyGoogleRelayResolver *resolver =
- g_slice_new0 (WockyGoogleRelayResolver);
-
-#ifdef ENABLE_GOOGLE_RELAY
-
- resolver->soup = soup_session_async_new ();
-
- /* If we don't get answer in a few seconds, relay won't do
- * us much help anyways. */
- g_object_set (resolver->soup, "timeout", RELAY_HTTP_TIMEOUT, NULL);
-
-#endif
-
- return resolver;
-}
-
-void
-wocky_google_relay_resolver_destroy (WockyGoogleRelayResolver *self)
-{
- g_clear_object (&self->soup);
-
- g_slice_free (WockyGoogleRelayResolver, self);
-}
-
-void
-wocky_google_relay_resolver_resolve (WockyGoogleRelayResolver *self,
- guint components,
- const gchar *server,
- guint16 port,
- const gchar *token,
- WockyJingleInfoRelaySessionCb callback,
- gpointer user_data)
-{
- RelaySessionData *rsd =
- relay_session_data_new (components, callback, user_data);
-
-#ifdef ENABLE_GOOGLE_RELAY
-
- gchar *url;
- guint i;
-
- if (server == NULL)
- {
- DEBUG ("No relay server provided, not creating google relay session");
- g_idle_add_full (G_PRIORITY_DEFAULT, relay_session_data_call, rsd,
- relay_session_data_destroy);
- return;
- }
-
- if (token == NULL)
- {
- DEBUG ("No relay token provided, not creating google relay session");
- g_idle_add_full (G_PRIORITY_DEFAULT, relay_session_data_call, rsd,
- relay_session_data_destroy);
- return;
- }
-
- url = g_strdup_printf ("http://%s:%u/create_session", server, (guint) port);
-
- for (i = 0; i < components; i++)
- {
- SoupMessage *msg = soup_message_new ("GET", url);
-
- DEBUG ("Trying to create a new relay session on %s", url);
-
- /* libjingle sets both headers, so shall we */
- soup_message_headers_append (msg->request_headers,
- "X-Talk-Google-Relay-Auth", token);
- soup_message_headers_append (msg->request_headers,
- "X-Google-Relay-Auth", token);
-
- soup_session_queue_message (self->soup, msg, on_http_response, rsd);
- }
-
- g_free (url);
-
-#else /* !ENABLE_GOOGLE_RELAY */
-
- DEBUG ("Google relay service is not supported");
-
- g_idle_add_full (G_PRIORITY_DEFAULT, relay_session_data_call, rsd,
- relay_session_data_destroy);
-
-#endif
-}
diff --git a/src/google-relay.h b/src/google-relay.h
deleted file mode 100644
index d8a5fe05a..000000000
--- a/src/google-relay.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * google-relay.h - Header for WockyGoogleRelaySession
- *
- * Copyright (C) 2006-2008 Collabora Ltd.
- * Copyright (C) 2011 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_GOOGLE_RELAY_H__
-#define __GABBLE_GOOGLE_RELAY_H__
-
-#include <glib.h>
-
-#include "jingle-info.h"
-
-G_BEGIN_DECLS
-
-typedef struct _WockyGoogleRelayResolver WockyGoogleRelayResolver;
-
-WockyGoogleRelayResolver * wocky_google_relay_resolver_new (void);
-void wocky_google_relay_resolver_destroy (WockyGoogleRelayResolver *self);
-void wocky_google_relay_resolver_resolve (WockyGoogleRelayResolver *self,
- guint requests_to_do,
- const gchar *server,
- guint16 port,
- const gchar *token,
- WockyJingleInfoRelaySessionCb callback,
- gpointer user_data);
-
-G_END_DECLS
-
-#endif /* __GABBLE_GOOGLE_RELAY_H__ */
diff --git a/src/jingle-content.c b/src/jingle-content.c
deleted file mode 100644
index eb6f2f100..000000000
--- a/src/jingle-content.c
+++ /dev/null
@@ -1,1407 +0,0 @@
-/*
- * gabble-jingle-content.c - Source for WockyJingleContent
- * Copyright (C) 2008 Collabora Ltd.
- *
- * 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 "jingle-content.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-
-#define DEBUG_FLAG GABBLE_DEBUG_MEDIA
-
-#include "connection.h"
-#include "debug.h"
-#include "jingle-factory.h"
-#include "jingle-session.h"
-#include "jingle-transport-iface.h"
-#include "jingle-transport-google.h"
-#include "jingle-media-rtp.h"
-#include "namespaces.h"
-#include "gabble-signals-marshal.h"
-
-/* signal enum */
-enum
-{
- READY,
- NEW_CANDIDATES,
- REMOVED,
- NEW_SHARE_CHANNEL,
- COMPLETED,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = {0};
-
-/* properties */
-enum
-{
- PROP_SESSION = 1,
- PROP_CONTENT_NS,
- PROP_TRANSPORT_NS,
- PROP_NAME,
- PROP_SENDERS,
- PROP_STATE,
- PROP_DISPOSITION,
- PROP_LOCALLY_CREATED,
- LAST_PROPERTY
-};
-
-struct _WockyJingleContentPrivate
-{
- gchar *name;
- gchar *creator;
- gboolean created_by_us;
- WockyJingleContentState state;
- WockyJingleContentSenders senders;
-
- gchar *content_ns;
- gchar *transport_ns;
- gchar *disposition;
-
- WockyJingleTransportIface *transport;
-
- /* Whether we've got the codecs (intersection) ready. */
- gboolean media_ready;
-
- /* Whether we have at least one local candidate. */
- gboolean have_local_candidates;
-
- guint gtalk4_event_id;
- guint last_share_channel_component_id;
-
- gboolean dispose_has_run;
-};
-
-#define DEFAULT_CONTENT_TIMEOUT 60000
-
-/* lookup tables */
-
-G_DEFINE_TYPE(WockyJingleContent, wocky_jingle_content, G_TYPE_OBJECT);
-
-static void new_transport_candidates_cb (WockyJingleTransportIface *trans,
- GList *candidates, WockyJingleContent *content);
-static void _maybe_ready (WockyJingleContent *self);
-static void transport_created (WockyJingleContent *c);
-
-static void
-wocky_jingle_content_init (WockyJingleContent *obj)
-{
- WockyJingleContentPrivate *priv =
- G_TYPE_INSTANCE_GET_PRIVATE (obj, WOCKY_TYPE_JINGLE_CONTENT,
- WockyJingleContentPrivate);
- obj->priv = priv;
-
- DEBUG ("%p", obj);
-
- priv->state = WOCKY_JINGLE_CONTENT_STATE_EMPTY;
- priv->created_by_us = TRUE;
- priv->media_ready = FALSE;
- priv->have_local_candidates = FALSE;
- priv->gtalk4_event_id = 0;
- priv->dispose_has_run = FALSE;
-
- obj->session = NULL;
-}
-
-static void
-wocky_jingle_content_dispose (GObject *object)
-{
- WockyJingleContent *content = WOCKY_JINGLE_CONTENT (object);
- WockyJingleContentPrivate *priv = content->priv;
-
- if (priv->dispose_has_run)
- return;
-
- DEBUG ("%p", object);
- priv->dispose_has_run = TRUE;
-
- if (priv->gtalk4_event_id != 0)
- {
- g_source_remove (priv->gtalk4_event_id);
- priv->gtalk4_event_id = 0;
- }
-
- g_free (priv->name);
- priv->name = NULL;
-
- g_free (priv->creator);
- priv->creator = NULL;
-
- g_free (priv->content_ns);
- priv->content_ns = NULL;
-
- g_free (priv->transport_ns);
- priv->transport_ns = NULL;
-
- g_free (priv->disposition);
- priv->disposition = NULL;
-
- if (G_OBJECT_CLASS (wocky_jingle_content_parent_class)->dispose)
- G_OBJECT_CLASS (wocky_jingle_content_parent_class)->dispose (object);
-}
-
-static void
-wocky_jingle_content_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- WockyJingleContent *self = WOCKY_JINGLE_CONTENT (object);
- WockyJingleContentPrivate *priv = self->priv;
-
- switch (property_id) {
- case PROP_SESSION:
- g_value_set_object (value, self->session);
- break;
- case PROP_NAME:
- g_value_set_string (value, priv->name);
- break;
- case PROP_SENDERS:
- g_value_set_uint (value, priv->senders);
- break;
- case PROP_STATE:
- g_value_set_uint (value, priv->state);
- break;
- case PROP_CONTENT_NS:
- g_value_set_string (value, priv->content_ns);
- break;
- case PROP_TRANSPORT_NS:
- g_value_set_string (value, priv->transport_ns);
- break;
- case PROP_DISPOSITION:
- g_value_set_string (value, priv->disposition);
- break;
- case PROP_LOCALLY_CREATED:
- g_value_set_boolean (value, priv->created_by_us);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-wocky_jingle_content_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- WockyJingleContent *self = WOCKY_JINGLE_CONTENT (object);
- WockyJingleContentPrivate *priv = self->priv;
-
- switch (property_id) {
- case PROP_SESSION:
- self->session = g_value_get_object (value);
- break;
- case PROP_CONTENT_NS:
- g_free (priv->content_ns);
- priv->content_ns = g_value_dup_string (value);
- break;
- case PROP_TRANSPORT_NS:
- g_free (priv->transport_ns);
- priv->transport_ns = g_value_dup_string (value);
-
- /* We can't switch transports. */
- g_assert (priv->transport == NULL);
-
- if (priv->transport_ns != NULL)
- {
- GType transport_type = wocky_jingle_factory_lookup_transport (
- wocky_jingle_session_get_factory (self->session),
- priv->transport_ns);
-
- g_assert (transport_type != 0);
-
- priv->transport = wocky_jingle_transport_iface_new (transport_type,
- self, priv->transport_ns);
-
- g_signal_connect (priv->transport, "new-candidates",
- (GCallback) new_transport_candidates_cb, self);
-
- transport_created (self);
- }
- break;
- case PROP_NAME:
- /* can't rename */
- g_assert (priv->name == NULL);
-
- priv->name = g_value_dup_string (value);
- break;
- case PROP_SENDERS:
- priv->senders = g_value_get_uint (value);
- break;
- case PROP_STATE:
- priv->state = g_value_get_uint (value);
- break;
- case PROP_DISPOSITION:
- g_assert (priv->disposition == NULL);
- priv->disposition = g_value_dup_string (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static WockyJingleContentSenders
-get_default_senders_real (WockyJingleContent *c)
-{
- return WOCKY_JINGLE_CONTENT_SENDERS_BOTH;
-}
-
-
-static void
-wocky_jingle_content_class_init (WockyJingleContentClass *cls)
-{
- GParamSpec *param_spec;
- GObjectClass *object_class = G_OBJECT_CLASS (cls);
-
- g_type_class_add_private (cls, sizeof (WockyJingleContentPrivate));
-
- object_class->get_property = wocky_jingle_content_get_property;
- object_class->set_property = wocky_jingle_content_set_property;
- object_class->dispose = wocky_jingle_content_dispose;
-
- cls->get_default_senders = get_default_senders_real;
-
- /* property definitions */
- param_spec = g_param_spec_object ("session", "WockyJingleSession object",
- "Jingle session object that owns this content.",
- WOCKY_TYPE_JINGLE_SESSION,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_SESSION, param_spec);
-
- param_spec = g_param_spec_string ("name", "Content name",
- "A unique content name in the session.",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_NAME, param_spec);
-
- param_spec = g_param_spec_string ("content-ns", "Content namespace",
- "Namespace identifying the content type.",
- NULL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_CONTENT_NS, param_spec);
-
- param_spec = g_param_spec_string ("transport-ns", "Transport namespace",
- "Namespace identifying the transport type.",
- NULL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_TRANSPORT_NS, param_spec);
-
- param_spec = g_param_spec_uint ("senders", "Stream senders",
- "Valid senders for the stream.",
- 0, G_MAXUINT32, WOCKY_JINGLE_CONTENT_SENDERS_NONE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_SENDERS, param_spec);
-
- param_spec = g_param_spec_uint ("state", "Content state",
- "The current state that the content is in.",
- 0, G_MAXUINT32, WOCKY_JINGLE_CONTENT_STATE_EMPTY,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_STATE, param_spec);
-
- param_spec = g_param_spec_string ("disposition", "Content disposition",
- "Distinguishes between 'session' and other contents.",
- NULL,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_DISPOSITION, param_spec);
-
- param_spec = g_param_spec_boolean ("locally-created", "Locally created",
- "True if the content was created by the local client.",
- FALSE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_LOCALLY_CREATED, param_spec);
-
- /* signal definitions */
-
- signals[READY] = g_signal_new ("ready",
- G_OBJECT_CLASS_TYPE (cls),
- G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- signals[NEW_CANDIDATES] = g_signal_new (
- "new-candidates",
- G_TYPE_FROM_CLASS (cls),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);
-
- signals[NEW_SHARE_CHANNEL] = g_signal_new (
- "new-share-channel",
- G_TYPE_FROM_CLASS (cls),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- gabble_marshal_VOID__STRING_UINT,
- G_TYPE_NONE,
- 2,
- G_TYPE_STRING, G_TYPE_UINT);
-
- signals[COMPLETED] = g_signal_new (
- "completed",
- G_TYPE_FROM_CLASS (cls),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE,
- 0);
-
- /* This signal serves as notification that the WockyJingleContent is now
- * meaningless; everything holding a reference should drop it after receiving
- * 'removed'.
- */
- signals[REMOVED] = g_signal_new ("removed",
- G_OBJECT_CLASS_TYPE (cls),
- G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-}
-
-
-static WockyJingleContentSenders
-get_default_senders (WockyJingleContent *c)
-{
- WockyJingleContentSenders (*virtual_method)(WockyJingleContent *) = \
- WOCKY_JINGLE_CONTENT_GET_CLASS (c)->get_default_senders;
-
- g_assert (virtual_method != NULL);
- return virtual_method (c);
-}
-
-
-static WockyJingleContentSenders
-parse_senders (const gchar *txt)
-{
- if (txt == NULL)
- return WOCKY_JINGLE_CONTENT_SENDERS_NONE;
-
- if (!wocky_strdiff (txt, "initiator"))
- return WOCKY_JINGLE_CONTENT_SENDERS_INITIATOR;
- else if (!wocky_strdiff (txt, "responder"))
- return WOCKY_JINGLE_CONTENT_SENDERS_RESPONDER;
- else if (!wocky_strdiff (txt, "both"))
- return WOCKY_JINGLE_CONTENT_SENDERS_BOTH;
-
- return WOCKY_JINGLE_CONTENT_SENDERS_NONE;
-}
-
-static const gchar *
-produce_senders (WockyJingleContentSenders senders)
-{
- switch (senders) {
- case WOCKY_JINGLE_CONTENT_SENDERS_INITIATOR:
- return "initiator";
- case WOCKY_JINGLE_CONTENT_SENDERS_RESPONDER:
- return "responder";
- case WOCKY_JINGLE_CONTENT_SENDERS_BOTH:
- return "both";
- default:
- DEBUG ("invalid content senders %u", senders);
- g_assert_not_reached ();
- }
-
- /* to make gcc not complain */
- return NULL;
-}
-
-
-#define SET_BAD_REQ(txt) \
- g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST, txt)
-
-static void
-new_transport_candidates_cb (WockyJingleTransportIface *trans,
- GList *candidates, WockyJingleContent *content)
-{
- /* just pass the signal on */
- g_signal_emit (content, signals[NEW_CANDIDATES], 0, candidates);
-}
-
-static void
-transport_created (WockyJingleContent *c)
-{
- void (*virtual_method)(WockyJingleContent *, WockyJingleTransportIface *) = \
- WOCKY_JINGLE_CONTENT_GET_CLASS (c)->transport_created;
-
- if (virtual_method != NULL)
- virtual_method (c, c->priv->transport);
-}
-
-
-static void
-parse_description (WockyJingleContent *c, WockyNode *desc_node,
- GError **error)
-{
- void (*virtual_method)(WockyJingleContent *, WockyNode *,
- GError **) = WOCKY_JINGLE_CONTENT_GET_CLASS (c)->parse_description;
-
- g_assert (virtual_method != NULL);
- virtual_method (c, desc_node, error);
-}
-
-static gboolean
-send_gtalk4_transport_accept (gpointer user_data)
-{
- WockyJingleContent *c = WOCKY_JINGLE_CONTENT (user_data);
- WockyJingleContentPrivate *priv = c->priv;
- WockyNode *sess_node;
- WockyStanza *msg = wocky_jingle_session_new_message (c->session,
- WOCKY_JINGLE_ACTION_TRANSPORT_ACCEPT, &sess_node);
-
- DEBUG ("Sending Gtalk4 'transport-accept' message to peer");
- wocky_node_add_child_ns (sess_node, "transport", priv->transport_ns);
-
- wocky_jingle_session_send (c->session, msg);
-
- return FALSE;
-}
-
-void
-wocky_jingle_content_parse_add (WockyJingleContent *c,
- WockyNode *content_node, gboolean google_mode, GError **error)
-{
- WockyJingleContentPrivate *priv = c->priv;
- const gchar *name, *creator, *senders, *disposition;
- WockyNode *trans_node, *desc_node;
- GType transport_type = 0;
- WockyJingleTransportIface *trans = NULL;
- WockyJingleDialect dialect = wocky_jingle_session_get_dialect (c->session);
-
- priv->created_by_us = FALSE;
-
- desc_node = wocky_node_get_child (content_node, "description");
- trans_node = wocky_node_get_child (content_node, "transport");
- creator = wocky_node_get_attribute (content_node, "creator");
- name = wocky_node_get_attribute (content_node, "name");
- senders = wocky_node_get_attribute (content_node, "senders");
-
- g_assert (priv->transport_ns == NULL);
-
- if (google_mode)
- {
- if (creator == NULL)
- creator = "initiator";
-
- /* the google protocols don't give the contents names, so put in a dummy
- * value if none was set by the session*/
- if (priv->name == NULL)
- name = priv->name = g_strdup ("gtalk");
- else
- name = priv->name;
-
- if (trans_node == NULL)
- {
- /* gtalk lj0.3 assumes google-p2p transport */
- DEBUG ("detected GTalk3 dialect");
-
- dialect = WOCKY_JINGLE_DIALECT_GTALK3;
- g_object_set (c->session, "dialect", WOCKY_JINGLE_DIALECT_GTALK3, NULL);
- transport_type = wocky_jingle_factory_lookup_transport (
- wocky_jingle_session_get_factory (c->session),
- "");
-
- /* in practice we do support gtalk-p2p, so this can't happen */
- if (G_UNLIKELY (transport_type == 0))
- {
- SET_BAD_REQ ("gtalk-p2p transport unsupported");
- return;
- }
-
- priv->transport_ns = g_strdup ("");
- }
- }
- else
- {
- if (creator == NULL &&
- wocky_jingle_session_peer_has_cap (c->session,
- QUIRK_GOOGLE_WEBMAIL_CLIENT))
- {
- if (wocky_jingle_content_creator_is_initiator (c))
- creator = "initiator";
- else
- creator = "responder";
-
- DEBUG ("Working around GMail omitting creator=''; assuming '%s'",
- creator);
- }
-
- if ((trans_node == NULL) || (creator == NULL) || (name == NULL))
- {
- SET_BAD_REQ ("missing required content attributes or elements");
- return;
- }
-
- /* In proper protocols the name comes from the stanza */
- g_assert (priv->name == NULL);
- priv->name = g_strdup (name);
- }
-
- /* if we didn't set it to google-p2p implicitly already, detect it */
- if (transport_type == 0)
- {
- const gchar *ns = wocky_node_get_ns (trans_node);
-
- transport_type = wocky_jingle_factory_lookup_transport (
- wocky_jingle_session_get_factory (c->session), ns);
-
- if (transport_type == 0)
- {
- SET_BAD_REQ ("unsupported content transport");
- return;
- }
-
- priv->transport_ns = g_strdup (ns);
- }
-
- if (senders == NULL)
- priv->senders = get_default_senders (c);
- else
- priv->senders = parse_senders (senders);
-
- if (priv->senders == WOCKY_JINGLE_CONTENT_SENDERS_NONE)
- {
- SET_BAD_REQ ("invalid content senders");
- return;
- }
-
- parse_description (c, desc_node, error);
- if (*error != NULL)
- return;
-
- disposition = wocky_node_get_attribute (content_node, "disposition");
- if (disposition == NULL)
- disposition = "session";
-
- if (wocky_strdiff (disposition, priv->disposition))
- {
- g_free (priv->disposition);
- priv->disposition = g_strdup (disposition);
- }
-
- DEBUG ("content creating new transport type %s", g_type_name (transport_type));
-
- trans = wocky_jingle_transport_iface_new (transport_type,
- c, priv->transport_ns);
-
- g_signal_connect (trans, "new-candidates",
- (GCallback) new_transport_candidates_cb, c);
-
- /* Depending on transport, there may be initial candidates specified here */
- if (trans_node != NULL)
- {
- wocky_jingle_transport_iface_parse_candidates (trans, trans_node, error);
- if (*error)
- {
- g_object_unref (trans);
- return;
- }
- }
-
- g_assert (priv->transport == NULL);
- priv->transport = trans;
- transport_created (c);
-
- g_assert (priv->creator == NULL);
- priv->creator = g_strdup (creator);
-
- priv->state = WOCKY_JINGLE_CONTENT_STATE_NEW;
-
- /* GTalk4 seems to require "transport-accept" for acknowledging
- * the transport type. wjt confirms that this is apparently necessary for
- * incoming calls to work.
- */
- if (dialect == WOCKY_JINGLE_DIALECT_GTALK4)
- priv->gtalk4_event_id = g_idle_add (send_gtalk4_transport_accept, c);
-
- return;
-}
-
-static guint
-new_share_channel (WockyJingleContent *c, const gchar *name)
-{
- WockyJingleContentPrivate *priv = c->priv;
- WockyJingleTransportGoogle *gtrans = NULL;
-
- if (priv->transport &&
- WOCKY_IS_JINGLE_TRANSPORT_GOOGLE (priv->transport))
- {
- guint id = priv->last_share_channel_component_id + 1;
-
- gtrans = WOCKY_JINGLE_TRANSPORT_GOOGLE (priv->transport);
-
- if (!jingle_transport_google_set_component_name (gtrans, name, id))
- return 0;
-
- priv->last_share_channel_component_id++;
-
- DEBUG ("New Share channel '%s' with id : %d", name, id);
-
- g_signal_emit (c, signals[NEW_SHARE_CHANNEL], 0, name, id);
-
- return priv->last_share_channel_component_id;
- }
- return 0;
-}
-
-guint
-wocky_jingle_content_create_share_channel (WockyJingleContent *self,
- const gchar *name)
-{
- WockyJingleContentPrivate *priv = self->priv;
- WockyNode *sess_node, *channel_node;
- WockyStanza *msg = NULL;
-
- /* Send the info action before creating the channel, in case candidates need
- to be sent on the signal emit. It doesn't matter if the channel already
- exists anyways... */
- msg = wocky_jingle_session_new_message (self->session,
- WOCKY_JINGLE_ACTION_INFO, &sess_node);
-
- DEBUG ("Sending 'info' message to peer : channel %s", name);
- channel_node = wocky_node_add_child_ns (sess_node, "channel",
- priv->content_ns);
- wocky_node_set_attribute (channel_node, "name", name);
-
- wocky_jingle_session_send (self->session, msg);
-
- return new_share_channel (self, name);
-}
-
-void
-wocky_jingle_content_send_complete (WockyJingleContent *self)
-{
- WockyJingleContentPrivate *priv = self->priv;
- WockyNode *sess_node;
- WockyStanza *msg = NULL;
-
- msg = wocky_jingle_session_new_message (self->session,
- WOCKY_JINGLE_ACTION_INFO, &sess_node);
-
- DEBUG ("Sending 'info' message to peer : complete");
- wocky_node_add_child_ns (sess_node, "complete", priv->content_ns);
-
- wocky_jingle_session_send (self->session, msg);
-
-}
-
-void
-wocky_jingle_content_parse_info (WockyJingleContent *c,
- WockyNode *content_node, GError **error)
-{
- WockyNode *channel_node;
- WockyNode *complete_node;
-
- channel_node = wocky_node_get_child (content_node, "channel");
- complete_node = wocky_node_get_child (content_node, "complete");
-
- DEBUG ("parsing info message : %p - %p", channel_node, complete_node);
- if (channel_node)
- {
- const gchar *name;
- name = wocky_node_get_attribute (channel_node, "name");
- if (name != NULL)
- new_share_channel (c, name);
- }
- else if (complete_node)
- {
- g_signal_emit (c, signals[COMPLETED], 0);
- }
-
-}
-
-void
-wocky_jingle_content_parse_accept (WockyJingleContent *c,
- WockyNode *content_node, gboolean google_mode, GError **error)
-{
- WockyJingleContentPrivate *priv = c->priv;
- const gchar *senders;
- WockyNode *trans_node, *desc_node;
- WockyJingleDialect dialect = wocky_jingle_session_get_dialect (c->session);
- WockyJingleContentSenders newsenders;
-
- desc_node = wocky_node_get_child (content_node, "description");
- trans_node = wocky_node_get_child (content_node, "transport");
- senders = wocky_node_get_attribute (content_node, "senders");
-
- if (WOCKY_IS_JINGLE_MEDIA_RTP (c) &&
- WOCKY_JINGLE_DIALECT_IS_GOOGLE (dialect) && trans_node == NULL)
- {
- DEBUG ("no transport node, assuming GTalk3 dialect");
- /* gtalk lj0.3 assumes google-p2p transport */
- g_object_set (c->session, "dialect", WOCKY_JINGLE_DIALECT_GTALK3, NULL);
- }
-
- if (senders == NULL)
- newsenders = get_default_senders (c);
- else
- newsenders = parse_senders (senders);
-
- if (newsenders == WOCKY_JINGLE_CONTENT_SENDERS_NONE)
- {
- SET_BAD_REQ ("invalid content senders");
- return;
- }
-
- if (newsenders != priv->senders)
- {
- DEBUG ("changing senders from %s to %s", produce_senders (priv->senders),
- produce_senders (newsenders));
- priv->senders = newsenders;
- g_object_notify ((GObject *) c, "senders");
- }
-
- parse_description (c, desc_node, error);
- if (*error != NULL)
- return;
-
- priv->state = WOCKY_JINGLE_CONTENT_STATE_ACKNOWLEDGED;
- g_object_notify ((GObject *) c, "state");
-
- if (trans_node != NULL)
- {
- wocky_jingle_transport_iface_parse_candidates (priv->transport,
- trans_node, NULL);
- }
-}
-
-void
-wocky_jingle_content_parse_description_info (WockyJingleContent *c,
- WockyNode *content_node, GError **error)
-{
- WockyJingleContentPrivate *priv = c->priv;
- WockyNode *desc_node;
- desc_node = wocky_node_get_child (content_node, "description");
- if (desc_node == NULL)
- {
- SET_BAD_REQ ("invalid description-info action");
- return;
- }
-
- if (priv->created_by_us && priv->state < WOCKY_JINGLE_CONTENT_STATE_ACKNOWLEDGED)
- {
- /* The stream was created by us and the other side didn't acknowledge it
- * yet, thus we don't have their codec information, thus the
- * description-info isn't meaningful and can be ignored */
- DEBUG ("Ignoring description-info as we didn't receive the codecs yet");
- return;
- }
-
- parse_description (c, desc_node, error);
-}
-
-
-void
-wocky_jingle_content_produce_node (WockyJingleContent *c,
- WockyNode *parent,
- gboolean include_description,
- gboolean include_transport,
- WockyNode **trans_node_out)
-{
- WockyJingleContentPrivate *priv = c->priv;
- WockyNode *content_node, *trans_node;
- WockyJingleDialect dialect = wocky_jingle_session_get_dialect (c->session);
- void (*produce_desc)(WockyJingleContent *, WockyNode *) =
- WOCKY_JINGLE_CONTENT_GET_CLASS (c)->produce_description;
-
- if ((dialect == WOCKY_JINGLE_DIALECT_GTALK3) ||
- (dialect == WOCKY_JINGLE_DIALECT_GTALK4))
- {
- content_node = parent;
- }
- else
- {
- content_node = wocky_node_add_child (parent, "content");
- wocky_node_set_attributes (content_node,
- "name", priv->name,
- "senders", produce_senders (priv->senders),
- NULL);
-
- if (wocky_jingle_content_creator_is_initiator (c))
- wocky_node_set_attribute (content_node, "creator", "initiator");
- else
- wocky_node_set_attribute (content_node, "creator", "responder");
- }
-
- if (include_description)
- produce_desc (c, content_node);
-
- if (include_transport)
- {
- if (dialect == WOCKY_JINGLE_DIALECT_GTALK3)
- {
- /* GTalk 03 doesn't use a transport, but assumes gtalk-p2p */
- trans_node = parent;
- }
- else
- {
- trans_node = wocky_node_add_child_ns (content_node, "transport",
- priv->transport_ns);
- }
-
- if (trans_node_out != NULL)
- *trans_node_out = trans_node;
- }
-}
-
-void
-wocky_jingle_content_update_senders (WockyJingleContent *c,
- WockyNode *content_node, GError **error)
-{
- WockyJingleContentPrivate *priv = c->priv;
- WockyJingleContentSenders senders;
-
- senders = parse_senders (wocky_node_get_attribute (content_node, "senders"));
-
- if (senders == WOCKY_JINGLE_CONTENT_SENDERS_NONE)
- {
- SET_BAD_REQ ("invalid content senders in stream");
- return;
- }
-
- priv->senders = senders;
- g_object_notify ((GObject *) c, "senders");
-}
-
-void
-wocky_jingle_content_parse_transport_info (WockyJingleContent *self,
- WockyNode *trans_node, GError **error)
-{
- WockyJingleContentPrivate *priv = self->priv;
-
- wocky_jingle_transport_iface_parse_candidates (priv->transport, trans_node, error);
-}
-
-/* Takes in a list of slice-allocated WockyJingleCandidate structs */
-void
-wocky_jingle_content_add_candidates (WockyJingleContent *self, GList *li)
-{
- WockyJingleContentPrivate *priv = self->priv;
-
- DEBUG ("called content: %s created_by_us: %d", priv->name,
- priv->created_by_us);
-
- if (li == NULL)
- return;
-
- wocky_jingle_transport_iface_new_local_candidates (priv->transport, li);
-
- if (!priv->have_local_candidates)
- {
- priv->have_local_candidates = TRUE;
- /* Maybe we were waiting for at least one candidate? */
- _maybe_ready (self);
- }
-
- /* If the content exists on the wire, let the transport send this candidate
- * if it wants to.
- */
- if (priv->state > WOCKY_JINGLE_CONTENT_STATE_EMPTY)
- wocky_jingle_transport_iface_send_candidates (priv->transport, FALSE);
-}
-
-/* Returns whether the content is ready to be signalled (initiated, for local
- * streams, or acknowledged, for remote streams. */
-gboolean
-wocky_jingle_content_is_ready (WockyJingleContent *self)
-{
- WockyJingleContentPrivate *priv = self->priv;
-
- if (priv->created_by_us)
- {
- /* If it's created by us, media ready, not signalled, and we have
- * at least one local candidate, it's ready to be added. */
- if (priv->media_ready && priv->state == WOCKY_JINGLE_CONTENT_STATE_EMPTY &&
- (!WOCKY_IS_JINGLE_MEDIA_RTP (self) || priv->have_local_candidates))
- return TRUE;
- }
- else
- {
- /* If it's created by peer, media and transports ready,
- * and not acknowledged yet, it's ready for acceptance. */
- if (priv->media_ready && priv->state == WOCKY_JINGLE_CONTENT_STATE_NEW &&
- (!WOCKY_IS_JINGLE_MEDIA_RTP (self) ||
- wocky_jingle_transport_iface_can_accept (priv->transport)))
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-send_content_add_or_accept (WockyJingleContent *self)
-{
- WockyJingleContentPrivate *priv = self->priv;
- WockyStanza *msg;
- WockyNode *sess_node, *transport_node;
- WockyJingleAction action;
- WockyJingleContentState new_state = WOCKY_JINGLE_CONTENT_STATE_EMPTY;
-
- g_assert (wocky_jingle_content_is_ready (self));
-
- if (priv->created_by_us)
- {
- /* TODO: set a timer for acknowledgement */
- action = WOCKY_JINGLE_ACTION_CONTENT_ADD;
- new_state = WOCKY_JINGLE_CONTENT_STATE_SENT;
- }
- else
- {
- action = WOCKY_JINGLE_ACTION_CONTENT_ACCEPT;
- new_state = WOCKY_JINGLE_CONTENT_STATE_ACKNOWLEDGED;
- }
-
- msg = wocky_jingle_session_new_message (self->session,
- action, &sess_node);
- wocky_jingle_content_produce_node (self, sess_node, TRUE, TRUE,
- &transport_node);
- wocky_jingle_transport_iface_inject_candidates (priv->transport,
- transport_node);
- wocky_jingle_session_send (self->session, msg);
-
- priv->state = new_state;
- g_object_notify (G_OBJECT (self), "state");
-}
-
-static void
-_maybe_ready (WockyJingleContent *self)
-{
- WockyJingleContentPrivate *priv = self->priv;
- WockyJingleState state;
-
- if (!wocky_jingle_content_is_ready (self))
- return;
-
- /* If content disposition is session and session
- * is not yet acknowledged/active, we signall
- * the readiness to the session and let it take
- * care of it. Otherwise, we can deal with it
- * ourselves. */
-
- g_object_get (self->session, "state", &state, NULL);
-
- if (!wocky_strdiff (priv->disposition, "session") &&
- (state < WOCKY_JINGLE_STATE_PENDING_ACCEPT_SENT))
- {
- /* Notify the session that we're ready for
- * session-initiate/session-accept */
- g_signal_emit (self, signals[READY], 0);
- }
- else
- {
- if (state >= WOCKY_JINGLE_STATE_PENDING_INITIATE_SENT)
- {
- send_content_add_or_accept (self);
-
- /* if neccessary, transmit the candidates */
- wocky_jingle_transport_iface_send_candidates (priv->transport,
- FALSE);
- }
- else
- {
- /* non session-disposition content ready without session
- * being initiated at all? */
- DEBUG ("session not initiated yet, ignoring non-session ready content");
- return;
- }
- }
-}
-
-void
-wocky_jingle_content_maybe_send_description (WockyJingleContent *self)
-{
- WockyJingleContentPrivate *priv = self->priv;
-
- /* If we didn't send the content yet there is no reason to send a
- * description-info to update it */
- if (priv->state < WOCKY_JINGLE_CONTENT_STATE_SENT)
- return;
-
- if (wocky_jingle_session_defines_action (self->session,
- WOCKY_JINGLE_ACTION_DESCRIPTION_INFO))
- {
- WockyNode *sess_node;
- WockyStanza *msg = wocky_jingle_session_new_message (self->session,
- WOCKY_JINGLE_ACTION_DESCRIPTION_INFO, &sess_node);
-
- wocky_jingle_content_produce_node (self, sess_node, TRUE, FALSE, NULL);
- wocky_jingle_session_send (self->session, msg);
- }
- else
- {
- DEBUG ("not sending description-info, speaking an old dialect");
- }
-}
-
-
-/* Used when session-initiate is sent (so all initial contents transmit their
- * candidates), and when we detect gtalk3 after we've transmitted some
- * candidates. */
-void
-wocky_jingle_content_retransmit_candidates (WockyJingleContent *self,
- gboolean all)
-{
- wocky_jingle_transport_iface_send_candidates (self->priv->transport, all);
-}
-
-void
-wocky_jingle_content_inject_candidates (WockyJingleContent *self,
- WockyNode *transport_node)
-{
- wocky_jingle_transport_iface_inject_candidates (self->priv->transport,
- transport_node);
-}
-
-
-/* Called by a subclass when the media is ready (e.g. we got local codecs) */
-void
-_wocky_jingle_content_set_media_ready (WockyJingleContent *self)
-{
- WockyJingleContentPrivate *priv = self->priv;
-
- DEBUG ("media ready on content: %s created_by_us: %d", priv->name,
- priv->created_by_us);
-
- priv->media_ready = TRUE;
-
- _maybe_ready (self);
-}
-
-void
-wocky_jingle_content_set_transport_state (WockyJingleContent *self,
- WockyJingleTransportState state)
-{
- WockyJingleContentPrivate *priv = self->priv;
-
- g_object_set (priv->transport, "state", state, NULL);
-
- _maybe_ready (self);
-}
-
-GList *
-wocky_jingle_content_get_remote_candidates (WockyJingleContent *c)
-{
- WockyJingleContentPrivate *priv = c->priv;
-
- return wocky_jingle_transport_iface_get_remote_candidates (priv->transport);
-}
-
-GList *
-wocky_jingle_content_get_local_candidates (WockyJingleContent *c)
-{
- WockyJingleContentPrivate *priv = c->priv;
-
- return wocky_jingle_transport_iface_get_local_candidates (priv->transport);
-}
-
-gboolean
-wocky_jingle_content_get_credentials (WockyJingleContent *c,
- gchar **ufrag, gchar **pwd)
-{
- WockyJingleContentPrivate *priv = c->priv;
-
- return jingle_transport_get_credentials (priv->transport, ufrag, pwd);
-}
-
-gboolean
-wocky_jingle_content_change_direction (WockyJingleContent *c,
- WockyJingleContentSenders senders)
-{
- WockyJingleContentPrivate *priv = c->priv;
- WockyStanza *msg;
- WockyNode *sess_node;
- WockyJingleDialect dialect = wocky_jingle_session_get_dialect (c->session);
-
- if (senders == priv->senders)
- return TRUE;
-
- priv->senders = senders;
- g_object_notify (G_OBJECT (c), "senders");
-
- if (WOCKY_JINGLE_DIALECT_IS_GOOGLE (dialect))
- {
- DEBUG ("ignoring direction change request for GTalk stream");
- return FALSE;
- }
-
- if (priv->state >= WOCKY_JINGLE_CONTENT_STATE_SENT)
- {
- msg = wocky_jingle_session_new_message (c->session,
- WOCKY_JINGLE_ACTION_CONTENT_MODIFY, &sess_node);
- wocky_jingle_content_produce_node (c, sess_node, FALSE, FALSE, NULL);
- wocky_jingle_session_send (c->session, msg);
- }
-
- /* FIXME: actually check whether remote end accepts our content-modify */
- return TRUE;
-}
-
-static void
-_on_remove_reply (
- GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- WockyJingleContent *c = WOCKY_JINGLE_CONTENT (user_data);
- WockyJingleContentPrivate *priv = c->priv;
-
- g_assert (priv->state == WOCKY_JINGLE_CONTENT_STATE_REMOVING);
-
- DEBUG ("%p", c);
-
- /* Everything holding a reference to a content should drop it after receiving
- * 'removed'.
- */
- g_signal_emit (c, signals[REMOVED], 0);
- g_object_unref (c);
-}
-
-static void
-_content_remove (WockyJingleContent *c,
- gboolean signal_peer,
- WockyJingleReason reason)
-{
- WockyJingleContentPrivate *priv = c->priv;
- WockyStanza *msg;
- WockyNode *sess_node;
-
- DEBUG ("called for %p (%s)", c, priv->name);
-
- /* If we were already signalled and removal is not a side-effect of
- * something else (sesssion termination, or removal by peer),
- * we have to signal removal to the peer. */
- if (signal_peer && (priv->state != WOCKY_JINGLE_CONTENT_STATE_EMPTY))
- {
- if (priv->state == WOCKY_JINGLE_CONTENT_STATE_REMOVING)
- {
- DEBUG ("ignoring request to remove content which is already being removed");
- return;
- }
-
- priv->state = WOCKY_JINGLE_CONTENT_STATE_REMOVING;
- g_object_notify ((GObject *) c, "state");
-
- msg = wocky_jingle_session_new_message (c->session,
- reason == WOCKY_JINGLE_REASON_UNKNOWN ?
- WOCKY_JINGLE_ACTION_CONTENT_REMOVE : WOCKY_JINGLE_ACTION_CONTENT_REJECT,
- &sess_node);
-
- if (reason != WOCKY_JINGLE_REASON_UNKNOWN)
- {
- WockyNode *reason_node = wocky_node_add_child_with_content (sess_node,
- "reason", NULL);
- wocky_node_add_child_with_content (reason_node,
- wocky_jingle_session_get_reason_name (reason), NULL);
- }
-
- wocky_jingle_content_produce_node (c, sess_node, FALSE, FALSE, NULL);
- wocky_porter_send_iq_async (wocky_jingle_session_get_porter (c->session),
- msg, NULL, _on_remove_reply, g_object_ref (c));
- g_object_unref (msg);
- }
- else
- {
- DEBUG ("signalling removed with %u refs", G_OBJECT (c)->ref_count);
- /* Everything holding a reference to a content should drop it after receiving
- * 'removed'.
- */
- g_signal_emit (c, signals[REMOVED], 0);
- }
-}
-
-void
-wocky_jingle_content_remove (WockyJingleContent *c,
- gboolean signal_peer)
-{
- _content_remove (c, signal_peer, WOCKY_JINGLE_REASON_UNKNOWN);
-}
-
-void
-wocky_jingle_content_reject (WockyJingleContent *c,
- WockyJingleReason reason)
-{
- _content_remove (c, TRUE, reason);
-}
-
-gboolean
-wocky_jingle_content_is_created_by_us (WockyJingleContent *c)
-{
- return c->priv->created_by_us;
-}
-
-gboolean
-wocky_jingle_content_creator_is_initiator (WockyJingleContent *c)
-{
- gboolean session_created_by_us;
-
- g_object_get (c->session, "local-initiator", &session_created_by_us, NULL);
-
- return (c->priv->created_by_us == session_created_by_us);
-}
-
-const gchar *
-wocky_jingle_content_get_name (WockyJingleContent *self)
-{
- return self->priv->name;
-}
-
-const gchar *
-wocky_jingle_content_get_ns (WockyJingleContent *self)
-{
- return self->priv->content_ns;
-}
-
-const gchar *
-wocky_jingle_content_get_transport_ns (WockyJingleContent *self)
-{
- return self->priv->transport_ns;
-}
-
-const gchar *
-wocky_jingle_content_get_disposition (WockyJingleContent *self)
-{
- return self->priv->disposition;
-}
-
-WockyJingleTransportType
-wocky_jingle_content_get_transport_type (WockyJingleContent *c)
-{
- return wocky_jingle_transport_iface_get_transport_type (c->priv->transport);
-}
-
-static gboolean
-jingle_content_has_direction (WockyJingleContent *self,
- gboolean sending)
-{
- WockyJingleContentPrivate *priv = self->priv;
- gboolean initiated_by_us;
-
- g_object_get (self->session, "local-initiator",
- &initiated_by_us, NULL);
-
- switch (priv->senders)
- {
- case WOCKY_JINGLE_CONTENT_SENDERS_BOTH:
- return TRUE;
- case WOCKY_JINGLE_CONTENT_SENDERS_NONE:
- return FALSE;
- case WOCKY_JINGLE_CONTENT_SENDERS_INITIATOR:
- return sending ? initiated_by_us : !initiated_by_us;
- case WOCKY_JINGLE_CONTENT_SENDERS_RESPONDER:
- return sending ? !initiated_by_us : initiated_by_us;
- }
-
- return FALSE;
-}
-
-gboolean
-wocky_jingle_content_sending (WockyJingleContent *self)
-{
- return jingle_content_has_direction (self, TRUE);
-}
-
-gboolean
-wocky_jingle_content_receiving (WockyJingleContent *self)
-{
- return jingle_content_has_direction (self, FALSE);
-}
-
-void
-wocky_jingle_content_set_sending (WockyJingleContent *self,
- gboolean send)
-{
- WockyJingleContentPrivate *priv = self->priv;
- WockyJingleContentSenders senders;
- gboolean initiated_by_us;
-
- if (send == wocky_jingle_content_sending (self))
- return;
-
- g_object_get (self->session, "local-initiator",
- &initiated_by_us, NULL);
-
- if (send)
- {
- if (priv->senders == WOCKY_JINGLE_CONTENT_SENDERS_NONE)
- senders = (initiated_by_us ? WOCKY_JINGLE_CONTENT_SENDERS_INITIATOR :
- WOCKY_JINGLE_CONTENT_SENDERS_RESPONDER);
- else
- senders = WOCKY_JINGLE_CONTENT_SENDERS_BOTH;
- }
- else
- {
- if (priv->senders == WOCKY_JINGLE_CONTENT_SENDERS_BOTH)
- senders = (initiated_by_us ? WOCKY_JINGLE_CONTENT_SENDERS_RESPONDER :
- WOCKY_JINGLE_CONTENT_SENDERS_INITIATOR);
- else
- senders = WOCKY_JINGLE_CONTENT_SENDERS_NONE;
- }
-
- if (senders == WOCKY_JINGLE_CONTENT_SENDERS_NONE)
- wocky_jingle_content_remove (self, TRUE);
- else
- wocky_jingle_content_change_direction (self, senders);
-}
-
-
-void
-wocky_jingle_content_request_receiving (WockyJingleContent *self,
- gboolean receive)
-{
- WockyJingleContentPrivate *priv = self->priv;
- WockyJingleContentSenders senders;
- gboolean initiated_by_us;
-
- if (receive == wocky_jingle_content_receiving (self))
- return;
-
- g_object_get (self->session, "local-initiator",
- &initiated_by_us, NULL);
-
- if (receive)
- {
- if (priv->senders == WOCKY_JINGLE_CONTENT_SENDERS_NONE)
- senders = (initiated_by_us ? WOCKY_JINGLE_CONTENT_SENDERS_RESPONDER :
- WOCKY_JINGLE_CONTENT_SENDERS_INITIATOR);
- else
- senders = WOCKY_JINGLE_CONTENT_SENDERS_BOTH;
- }
- else
- {
- if (priv->senders == WOCKY_JINGLE_CONTENT_SENDERS_BOTH)
- senders = (initiated_by_us ? WOCKY_JINGLE_CONTENT_SENDERS_INITIATOR :
- WOCKY_JINGLE_CONTENT_SENDERS_RESPONDER);
- else
- senders = WOCKY_JINGLE_CONTENT_SENDERS_NONE;
- }
-
-
- if (senders == WOCKY_JINGLE_CONTENT_SENDERS_NONE)
- wocky_jingle_content_remove (self, TRUE);
- else
- wocky_jingle_content_change_direction (self, senders);
-}
diff --git a/src/jingle-content.h b/src/jingle-content.h
deleted file mode 100644
index f702c1190..000000000
--- a/src/jingle-content.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * jingle-content.h - Header for WockyJingleContent
- * Copyright (C) 2008 Collabora Ltd.
- *
- * 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 __JINGLE_CONTENT_H__
-#define __JINGLE_CONTENT_H__
-
-#include <glib-object.h>
-
-#include "jingle-factory.h"
-#include "jingle-transport-iface.h"
-#include "jingle-types.h"
-
-G_BEGIN_DECLS
-
-typedef enum {
- WOCKY_JINGLE_MEDIA_TYPE_NONE = 0,
- WOCKY_JINGLE_MEDIA_TYPE_AUDIO,
- WOCKY_JINGLE_MEDIA_TYPE_VIDEO,
-} WockyJingleMediaType;
-
-typedef enum {
- WOCKY_JINGLE_CONTENT_STATE_EMPTY = 0,
- WOCKY_JINGLE_CONTENT_STATE_NEW,
- WOCKY_JINGLE_CONTENT_STATE_SENT,
- WOCKY_JINGLE_CONTENT_STATE_ACKNOWLEDGED,
- WOCKY_JINGLE_CONTENT_STATE_REMOVING
-} WockyJingleContentState;
-
-struct _WockyJingleCandidate {
- WockyJingleTransportProtocol protocol;
- WockyJingleCandidateType type;
-
- gchar *id;
- gchar *address;
- int port;
- int component;
- int generation;
-
- int preference;
- gchar *username;
- gchar *password;
- int network;
-};
-
-typedef struct _WockyJingleContentClass WockyJingleContentClass;
-
-GType wocky_jingle_content_get_type (void);
-
-/* TYPE MACROS */
-#define WOCKY_TYPE_JINGLE_CONTENT \
- (wocky_jingle_content_get_type ())
-#define WOCKY_JINGLE_CONTENT(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), WOCKY_TYPE_JINGLE_CONTENT, \
- WockyJingleContent))
-#define WOCKY_JINGLE_CONTENT_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), WOCKY_TYPE_JINGLE_CONTENT, \
- WockyJingleContentClass))
-#define WOCKY_IS_JINGLE_CONTENT(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), WOCKY_TYPE_JINGLE_CONTENT))
-#define WOCKY_IS_JINGLE_CONTENT_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), WOCKY_TYPE_JINGLE_CONTENT))
-#define WOCKY_JINGLE_CONTENT_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), WOCKY_TYPE_JINGLE_CONTENT, \
- WockyJingleContentClass))
-
-struct _WockyJingleContentClass {
- GObjectClass parent_class;
-
- void (*parse_description) (WockyJingleContent *, WockyNode *,
- GError **);
- void (*produce_description) (WockyJingleContent *, WockyNode *);
- void (*transport_created) (WockyJingleContent *,
- WockyJingleTransportIface *);
- WockyJingleContentSenders (*get_default_senders) (WockyJingleContent *);
-};
-
-typedef struct _WockyJingleContentPrivate WockyJingleContentPrivate;
-
-struct _WockyJingleContent {
- GObject parent;
- WockyJingleContentPrivate *priv;
-
- WockyJingleSession *session;
-};
-
-void wocky_jingle_content_parse_add (WockyJingleContent *c,
- WockyNode *content_node, gboolean google_mode, GError **error);
-void wocky_jingle_content_update_senders (WockyJingleContent *c,
- WockyNode *content_node, GError **error);
-void wocky_jingle_content_produce_node (WockyJingleContent *c,
- WockyNode *parent,
- gboolean include_description,
- gboolean include_transport,
- WockyNode **trans_node_out);
-void wocky_jingle_content_parse_accept (WockyJingleContent *c,
- WockyNode *content_node, gboolean google_mode, GError **error);
-
-void wocky_jingle_content_parse_info (WockyJingleContent *c,
- WockyNode *content_node, GError **error);
-void wocky_jingle_content_parse_transport_info (WockyJingleContent *self,
- WockyNode *trans_node, GError **error);
-void wocky_jingle_content_parse_description_info (WockyJingleContent *self,
- WockyNode *trans_node, GError **error);
-guint wocky_jingle_content_create_share_channel (WockyJingleContent *self,
- const gchar *name);
-void wocky_jingle_content_add_candidates (WockyJingleContent *self, GList *li);
-void _wocky_jingle_content_set_media_ready (WockyJingleContent *self);
-gboolean wocky_jingle_content_is_ready (WockyJingleContent *self);
-void wocky_jingle_content_set_transport_state (WockyJingleContent *content,
- WockyJingleTransportState state);
-void wocky_jingle_content_remove (WockyJingleContent *c, gboolean signal_peer);
-void wocky_jingle_content_reject (WockyJingleContent *c,
- WockyJingleReason reason);
-
-GList *wocky_jingle_content_get_remote_candidates (WockyJingleContent *c);
-GList *wocky_jingle_content_get_local_candidates (WockyJingleContent *c);
-gboolean wocky_jingle_content_get_credentials (WockyJingleContent *c,
- gchar **ufrag, gchar **pwd);
-gboolean wocky_jingle_content_change_direction (WockyJingleContent *c,
- WockyJingleContentSenders senders);
-void wocky_jingle_content_retransmit_candidates (WockyJingleContent *self,
- gboolean all);
-void wocky_jingle_content_inject_candidates (WockyJingleContent *self,
- WockyNode *transport_node);
-gboolean wocky_jingle_content_is_created_by_us (WockyJingleContent *c);
-gboolean wocky_jingle_content_creator_is_initiator (WockyJingleContent *c);
-
-const gchar *wocky_jingle_content_get_name (WockyJingleContent *self);
-const gchar *wocky_jingle_content_get_ns (WockyJingleContent *self);
-const gchar *wocky_jingle_content_get_disposition (WockyJingleContent *self);
-WockyJingleTransportType wocky_jingle_content_get_transport_type (WockyJingleContent *c);
-const gchar *wocky_jingle_content_get_transport_ns (WockyJingleContent *self);
-
-void wocky_jingle_content_maybe_send_description (WockyJingleContent *self);
-
-gboolean wocky_jingle_content_sending (WockyJingleContent *self);
-gboolean wocky_jingle_content_receiving (WockyJingleContent *self);
-
-void wocky_jingle_content_set_sending (WockyJingleContent *self,
- gboolean send);
-void wocky_jingle_content_request_receiving (WockyJingleContent *self,
- gboolean receive);
-
-void wocky_jingle_content_send_complete (WockyJingleContent *self);
-
-#endif /* __JINGLE_CONTENT_H__ */
-
diff --git a/src/jingle-factory.c b/src/jingle-factory.c
deleted file mode 100644
index f3ad394f7..000000000
--- a/src/jingle-factory.c
+++ /dev/null
@@ -1,604 +0,0 @@
-/*
- * jingle-factory.c - Support for XEP-0166 (Jingle)
- *
- * Copyright (C) 2006-2008 Collabora Ltd.
- *
- * 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 "jingle-factory.h"
-
-#include <stdio.h>
-#include <string.h>
-#include <glib.h>
-
-#include <wocky/wocky.h>
-
-#define DEBUG_FLAG GABBLE_DEBUG_MEDIA
-
-#include "debug.h"
-#include "gabble-signals-marshal.h"
-#include "jingle-share.h"
-#include "jingle-media-rtp.h"
-#include "jingle-session.h"
-#include "jingle-transport-google.h"
-#include "jingle-transport-rawudp.h"
-#include "jingle-transport-iceudp.h"
-#include "namespaces.h"
-
-#include "google-relay.h"
-
-G_DEFINE_TYPE(WockyJingleFactory, wocky_jingle_factory, G_TYPE_OBJECT);
-
-/* signal enum */
-enum
-{
- NEW_SESSION,
- QUERY_CAP,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = {0};
-
-/* properties */
-enum
-{
- PROP_SESSION = 1,
- LAST_PROPERTY
-};
-
-struct _WockyJingleFactoryPrivate
-{
- WockySession *session;
- WockyPorter *porter;
- guint jingle_handler_id;
- GHashTable *content_types;
- GHashTable *transports;
-
- /* instances of SESSION_MAP_KEY_FORMAT => WockyJingleSession. */
- GHashTable *sessions;
-
- WockyJingleInfo *jingle_info;
-
- gboolean dispose_has_run;
-};
-
-static gboolean jingle_cb (
- WockyPorter *porter,
- WockyStanza *msg,
- gpointer user_data);
-static WockyJingleSession *create_session (WockyJingleFactory *fac,
- const gchar *sid,
- const gchar *jid,
- WockyJingleDialect dialect,
- gboolean local_hold);
-
-static gboolean session_query_cap_cb (
- WockyJingleSession *session,
- WockyContact *contact,
- const gchar *cap_or_quirk,
- gpointer user_data);
-static void session_terminated_cb (WockyJingleSession *sess,
- gboolean local_terminator,
- WockyJingleReason reason,
- const gchar *text,
- WockyJingleFactory *fac);
-
-static void attach_to_wocky_session (WockyJingleFactory *self);
-
-static void
-wocky_jingle_factory_init (WockyJingleFactory *obj)
-{
- WockyJingleFactoryPrivate *priv =
- G_TYPE_INSTANCE_GET_PRIVATE (obj, WOCKY_TYPE_JINGLE_FACTORY,
- WockyJingleFactoryPrivate);
- obj->priv = priv;
-
- priv->sessions = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, g_object_unref);
-
- priv->transports = g_hash_table_new_full (g_str_hash, g_str_equal,
- NULL, NULL);
-
- priv->content_types = g_hash_table_new_full (g_str_hash, g_str_equal,
- NULL, NULL);
-
- priv->dispose_has_run = FALSE;
-}
-
-static void
-wocky_jingle_factory_dispose (GObject *object)
-{
- WockyJingleFactory *fac = WOCKY_JINGLE_FACTORY (object);
- WockyJingleFactoryPrivate *priv = fac->priv;
- GHashTableIter iter;
- gpointer val;
-
- if (priv->dispose_has_run)
- return;
-
- DEBUG ("dispose called");
- priv->dispose_has_run = TRUE;
-
- wocky_jingle_factory_stop (fac);
- g_clear_object (&priv->session);
- g_clear_object (&priv->porter);
-
- g_hash_table_iter_init (&iter, priv->sessions);
- while (g_hash_table_iter_next (&iter, NULL, &val))
- g_signal_handlers_disconnect_by_func (val, session_query_cap_cb, fac);
- g_hash_table_unref (priv->sessions);
- priv->sessions = NULL;
-
- g_hash_table_unref (priv->content_types);
- priv->content_types = NULL;
- g_hash_table_unref (priv->transports);
- priv->transports = NULL;
- g_clear_object (&priv->jingle_info);
-
- if (G_OBJECT_CLASS (wocky_jingle_factory_parent_class)->dispose)
- G_OBJECT_CLASS (wocky_jingle_factory_parent_class)->dispose (object);
-}
-
-static void
-wocky_jingle_factory_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- WockyJingleFactory *chan = WOCKY_JINGLE_FACTORY (object);
- WockyJingleFactoryPrivate *priv = chan->priv;
-
- switch (property_id) {
- case PROP_SESSION:
- g_value_set_object (value, priv->session);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-wocky_jingle_factory_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- WockyJingleFactory *chan = WOCKY_JINGLE_FACTORY (object);
- WockyJingleFactoryPrivate *priv = chan->priv;
-
- switch (property_id) {
- case PROP_SESSION:
- priv->session = g_value_dup_object (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-wocky_jingle_factory_constructed (GObject *obj)
-{
- WockyJingleFactory *self = WOCKY_JINGLE_FACTORY (obj);
- GObjectClass *parent = G_OBJECT_CLASS (wocky_jingle_factory_parent_class);
-
- if (parent->constructed != NULL)
- parent->constructed (obj);
-
- attach_to_wocky_session (self);
-
- jingle_share_register (self);
- jingle_media_rtp_register (self);
- jingle_transport_google_register (self);
- jingle_transport_rawudp_register (self);
- jingle_transport_iceudp_register (self);
-}
-
-static void
-wocky_jingle_factory_class_init (WockyJingleFactoryClass *cls)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (cls);
- GParamSpec *param_spec;
-
- g_type_class_add_private (cls, sizeof (WockyJingleFactoryPrivate));
-
- object_class->constructed = wocky_jingle_factory_constructed;
- object_class->get_property = wocky_jingle_factory_get_property;
- object_class->set_property = wocky_jingle_factory_set_property;
- object_class->dispose = wocky_jingle_factory_dispose;
-
- param_spec = g_param_spec_object ("session", "WockySession object",
- "WockySession to listen for Jingle sessions on",
- WOCKY_TYPE_SESSION,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_SESSION, param_spec);
-
- /* signal definitions */
-
- /*
- * @session: a fresh new Jingle session for your listening pleasure
- * @initiated_locally: %TRUE if this is a new outgoing session; %FALSE if it
- * is a new incoming session
- */
- signals[NEW_SESSION] = g_signal_new ("new-session",
- G_TYPE_FROM_CLASS (cls), G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, gabble_marshal_VOID__OBJECT_BOOL,
- G_TYPE_NONE, 2, WOCKY_TYPE_JINGLE_SESSION, G_TYPE_BOOLEAN);
-
- /*
- * @contact: the peer in a call
- * @cap: the XEP-0115 feature string the session is interested in.
- *
- * Emitted when a Jingle session wants to check whether the peer has a
- * particular capability. The handler should return %TRUE if @contact has
- * @cap.
- */
- signals[QUERY_CAP] = g_signal_new ("query-cap",
- G_TYPE_FROM_CLASS (cls), G_SIGNAL_RUN_LAST,
- 0, g_signal_accumulator_first_wins, NULL,
- gabble_marshal_BOOLEAN__OBJECT_STRING,
- G_TYPE_BOOLEAN, 2, WOCKY_TYPE_CONTACT, G_TYPE_STRING);
-}
-
-WockyJingleFactory *
-wocky_jingle_factory_new (
- WockySession *session)
-{
- return g_object_new (WOCKY_TYPE_JINGLE_FACTORY,
- "session", session,
- NULL);
-}
-
-static void
-attach_to_wocky_session (WockyJingleFactory *self)
-{
- WockyJingleFactoryPrivate *priv = self->priv;
-
- g_assert (priv->session != NULL);
-
- g_assert (priv->porter == NULL);
- priv->porter = g_object_ref (wocky_session_get_porter (priv->session));
-
- /* TODO: we could match different dialects here maybe? */
- priv->jingle_handler_id = wocky_porter_register_handler_from_anyone (
- priv->porter,
- WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET,
- WOCKY_PORTER_HANDLER_PRIORITY_NORMAL, jingle_cb, self,
- NULL);
-
- priv->jingle_info = wocky_jingle_info_new (priv->porter);
-}
-
-void
-wocky_jingle_factory_stop (WockyJingleFactory *self)
-{
- WockyJingleFactoryPrivate *priv = self->priv;
-
- if (priv->porter != NULL &&
- priv->jingle_handler_id != 0)
- {
- wocky_porter_unregister_handler (priv->porter, priv->jingle_handler_id);
- priv->jingle_handler_id = 0;
- }
-}
-
-/* The 'session' map is keyed by:
- * "<peer's jid>\n<session id>"
- */
-#define SESSION_MAP_KEY_FORMAT "%s\n%s"
-
-static gchar *
-make_session_map_key (
- const gchar *jid,
- const gchar *sid)
-{
- return g_strdup_printf (SESSION_MAP_KEY_FORMAT, jid, sid);
-}
-
-static gchar *
-get_unique_sid_for (WockyJingleFactory *factory,
- const gchar *jid,
- gchar **key)
-{
- guint32 val;
- gchar *sid = NULL;
- gchar *key_ = NULL;
-
- do
- {
- val = g_random_int_range (1000000, G_MAXINT);
-
- g_free (sid);
- g_free (key_);
- sid = g_strdup_printf ("%u", val);
- key_ = make_session_map_key (jid, sid);
- }
- while (g_hash_table_lookup (factory->priv->sessions, key_) != NULL);
-
- *key = key_;
- return sid;
-}
-
-static WockyJingleSession *
-ensure_session (WockyJingleFactory *self,
- const gchar *sid,
- const gchar *from,
- WockyJingleAction action,
- WockyJingleDialect dialect,
- gboolean *new_session,
- GError **error)
-{
- WockyJingleFactoryPrivate *priv = self->priv;
- gchar *key;
- WockyJingleSession *sess;
-
- if (!wocky_decode_jid (from, NULL, NULL, NULL))
- {
- g_prefix_error (error, "Couldn't parse sender '%s': ", from);
- return NULL;
- }
-
- /* If we can ensure the handle, we can decode the jid */
- key = make_session_map_key (from, sid);
- sess = g_hash_table_lookup (priv->sessions, key);
- g_free (key);
-
- if (sess == NULL)
- {
- if (action == WOCKY_JINGLE_ACTION_SESSION_INITIATE)
- {
- sess = create_session (self, sid, from, dialect, FALSE);
- *new_session = TRUE;
- }
- else
- {
- g_set_error (error, WOCKY_JINGLE_ERROR,
- WOCKY_JINGLE_ERROR_UNKNOWN_SESSION,
- "session %s is unknown", sid);
- return NULL;
- }
- }
- else
- {
- *new_session = FALSE;
- }
-
- return sess;
-}
-
-static gboolean
-jingle_cb (
- WockyPorter *porter,
- WockyStanza *msg,
- gpointer user_data)
-{
- WockyJingleFactory *self = WOCKY_JINGLE_FACTORY (user_data);
- GError *error = NULL;
- const gchar *sid, *from;
- WockyJingleSession *sess;
- gboolean new_session = FALSE;
- WockyJingleAction action;
- WockyJingleDialect dialect;
-
- /* see if it's a jingle message and detect dialect */
- sid = wocky_jingle_session_detect (msg, &action, &dialect);
- from = wocky_stanza_get_from (msg);
-
- if (sid == NULL || from == NULL)
- return FALSE;
-
- sess = ensure_session (self, sid, from, action, dialect, &new_session,
- &error);
-
- if (sess == NULL)
- goto REQUEST_ERROR;
-
- /* now act on the message */
- if (!wocky_jingle_session_parse (sess, action, msg, &error))
- goto REQUEST_ERROR;
-
- /* This has to be after the call to parse(), not inside create_session():
- * until the session has parsed the session-initiate stanza, it does not know
- * about its own contents, and we don't even know if the content types are
- * something we understand. So it's essentially half-alive and useless to
- * signal listeners.
- */
- if (new_session)
- g_signal_emit (self, signals[NEW_SESSION], 0, sess, FALSE);
-
- /* all went well, we can acknowledge the IQ */
- wocky_porter_acknowledge_iq (porter, msg, NULL);
-
- return TRUE;
-
-REQUEST_ERROR:
- g_assert (error != NULL);
- DEBUG ("NAKing with error: %s", error->message);
- wocky_porter_send_iq_gerror (porter, msg, error);
- g_error_free (error);
-
- if (sess != NULL && new_session)
- wocky_jingle_session_terminate (sess, WOCKY_JINGLE_REASON_UNKNOWN, NULL, NULL);
-
- return TRUE;
-}
-
-static gboolean
-session_query_cap_cb (
- WockyJingleSession *session,
- WockyContact *contact,
- const gchar *cap_or_quirk,
- gpointer user_data)
-{
- WockyJingleFactory *self = WOCKY_JINGLE_FACTORY (user_data);
- gboolean ret;
-
- /* Propagate the query out to the application. We can't depend on the
- * application connecting to ::query-cap on the session because caps queries
- * may happen while parsing the session-initiate stanza, which must happen
- * before the session is announced to the application.
- */
- g_signal_emit (self, signals[QUERY_CAP], 0, contact, cap_or_quirk, &ret);
- return ret;
-}
-
-/*
- * If sid is set to NULL a unique sid is generated and
- * the "local-initiator" property of the newly created
- * WockyJingleSession is set to true.
- */
-static WockyJingleSession *
-create_session (WockyJingleFactory *fac,
- const gchar *sid,
- const gchar *jid,
- WockyJingleDialect dialect,
- gboolean local_hold)
-{
- WockyJingleFactoryPrivate *priv = fac->priv;
- WockyJingleSession *sess;
- gboolean local_initiator;
- gchar *sid_, *key;
- gpointer contact;
- WockyContactFactory *factory;
-
- factory = wocky_session_get_contact_factory (priv->session);
- g_assert (jid != NULL);
-
- if (strchr (jid, '/') != NULL)
- contact = wocky_contact_factory_ensure_resource_contact (factory, jid);
- else
- contact = wocky_contact_factory_ensure_bare_contact (factory, jid);
-
- g_return_val_if_fail (contact != NULL, NULL);
- g_return_val_if_fail (WOCKY_IS_CONTACT (contact), NULL);
-
- if (sid != NULL)
- {
- key = make_session_map_key (jid, sid);
- sid_ = g_strdup (sid);
-
- local_initiator = FALSE;
- }
- else
- {
- sid_ = get_unique_sid_for (fac, jid, &key);
-
- local_initiator = TRUE;
- }
-
- /* Either we should have found the existing session when the IQ arrived, or
- * get_unique_sid_for should have ensured the key is fresh. */
- g_assert (NULL == g_hash_table_lookup (priv->sessions, key));
-
- sess = wocky_jingle_session_new (
- fac,
- priv->porter,
- sid_, local_initiator, contact, dialect, local_hold);
- g_signal_connect (sess, "terminated",
- (GCallback) session_terminated_cb, fac);
-
- /* Takes ownership of key */
- g_hash_table_insert (priv->sessions, key, sess);
-
- DEBUG ("new session (%s, %s) @ %p", jid, sid_, sess);
-
- g_free (sid_);
- g_object_unref (contact);
-
- g_signal_connect (sess, "query-cap",
- (GCallback) session_query_cap_cb, (GObject *) fac);
-
- return sess;
-}
-
-WockyJingleSession *
-wocky_jingle_factory_create_session (WockyJingleFactory *fac,
- const gchar *jid,
- WockyJingleDialect dialect,
- gboolean local_hold)
-{
- WockyJingleSession *session = create_session (fac, NULL, jid, dialect, local_hold);
-
- g_signal_emit (fac, signals[NEW_SESSION], 0, session, TRUE);
- return session;
-}
-
-void
-wocky_jingle_factory_register_transport (WockyJingleFactory *self,
- gchar *xmlns,
- GType transport_type)
-{
- g_return_if_fail (g_type_is_a (transport_type,
- WOCKY_TYPE_JINGLE_TRANSPORT_IFACE));
-
- g_hash_table_insert (self->priv->transports, xmlns,
- GSIZE_TO_POINTER (transport_type));
-}
-
-GType
-wocky_jingle_factory_lookup_transport (WockyJingleFactory *self,
- const gchar *xmlns)
-{
- return GPOINTER_TO_SIZE (g_hash_table_lookup (self->priv->transports,
- xmlns));
-}
-
-void
-wocky_jingle_factory_register_content_type (WockyJingleFactory *self,
- gchar *xmlns,
- GType content_type)
-{
- g_return_if_fail (g_type_is_a (content_type, WOCKY_TYPE_JINGLE_CONTENT));
-
- g_hash_table_insert (self->priv->content_types, xmlns,
- GSIZE_TO_POINTER (content_type));
-}
-
-GType
-wocky_jingle_factory_lookup_content_type (WockyJingleFactory *self,
- const gchar *xmlns)
-{
- return GPOINTER_TO_SIZE (g_hash_table_lookup (self->priv->content_types,
- xmlns));
-}
-
-static void
-session_terminated_cb (WockyJingleSession *session,
- gboolean local_terminator G_GNUC_UNUSED,
- WockyJingleReason reason G_GNUC_UNUSED,
- const gchar *text G_GNUC_UNUSED,
- WockyJingleFactory *factory)
-{
- gchar *key = make_session_map_key (
- wocky_jingle_session_get_peer_jid (session),
- wocky_jingle_session_get_sid (session));
-
- DEBUG ("removing terminated session with key %s", key);
-
- g_signal_handlers_disconnect_by_func (session, session_query_cap_cb, factory);
- g_warn_if_fail (g_hash_table_remove (factory->priv->sessions, key));
-
- g_free (key);
-}
-
-WockyJingleInfo *
-wocky_jingle_factory_get_jingle_info (
- WockyJingleFactory *self)
-{
- return self->priv->jingle_info;
-}
diff --git a/src/jingle-factory.h b/src/jingle-factory.h
deleted file mode 100644
index b715d1637..000000000
--- a/src/jingle-factory.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * jingle-factory.h - Header for WockyJingleFactory
- * Copyright (C) 2008 Collabora Ltd.
- *
- * 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 __JINGLE_FACTORY_H__
-#define __JINGLE_FACTORY_H__
-
-#include <glib-object.h>
-
-#include "jingle-info.h"
-#include "jingle-types.h"
-
-G_BEGIN_DECLS
-
-typedef struct _WockyJingleFactoryClass WockyJingleFactoryClass;
-
-GType wocky_jingle_factory_get_type (void);
-
-/* TYPE MACROS */
-#define WOCKY_TYPE_JINGLE_FACTORY \
- (wocky_jingle_factory_get_type ())
-#define WOCKY_JINGLE_FACTORY(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), WOCKY_TYPE_JINGLE_FACTORY, \
- WockyJingleFactory))
-#define WOCKY_JINGLE_FACTORY_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), WOCKY_TYPE_JINGLE_FACTORY, \
- WockyJingleFactoryClass))
-#define WOCKY_IS_JINGLE_FACTORY(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), WOCKY_TYPE_JINGLE_FACTORY))
-#define WOCKY_IS_JINGLE_FACTORY_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), WOCKY_TYPE_JINGLE_FACTORY))
-#define WOCKY_JINGLE_FACTORY_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), WOCKY_TYPE_JINGLE_FACTORY, \
- WockyJingleFactoryClass))
-
-struct _WockyJingleFactoryClass {
- GObjectClass parent_class;
-};
-
-typedef struct _WockyJingleFactoryPrivate WockyJingleFactoryPrivate;
-
-struct _WockyJingleFactory {
- GObject parent;
-
- WockyJingleFactoryPrivate *priv;
-};
-
-WockyJingleFactory *wocky_jingle_factory_new (
- WockySession *session);
-
-void wocky_jingle_factory_stop (WockyJingleFactory *self);
-
-void wocky_jingle_factory_register_content_type (WockyJingleFactory *self,
- gchar *xmlns, GType content_type);
-GType wocky_jingle_factory_lookup_content_type (WockyJingleFactory *self,
- const gchar *xmlns);
-
-void wocky_jingle_factory_register_transport (WockyJingleFactory *self,
- gchar *xmlns, GType transport_type);
-GType wocky_jingle_factory_lookup_transport (WockyJingleFactory *self,
- const gchar *xmlns);
-
-WockyJingleSession *wocky_jingle_factory_create_session (
- WockyJingleFactory *fac,
- const gchar *jid,
- WockyJingleDialect dialect,
- gboolean local_hold);
-
-WockyJingleInfo *wocky_jingle_factory_get_jingle_info (
- WockyJingleFactory *fac);
-
-G_END_DECLS;
-
-#endif /* __JINGLE_FACTORY_H__ */
-
diff --git a/src/jingle-info-internal.h b/src/jingle-info-internal.h
deleted file mode 100644
index fa0707bc7..000000000
--- a/src/jingle-info-internal.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * jingle-info-internal.h - internal types for WockyJingleInfo
- * Copyright © 2012 Collabora Ltd.
- *
- * 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 WOCKY_JINGLE_INFO_INTERNAL_H
-#define WOCKY_JINGLE_INFO_INTERNAL_H
-
-typedef enum {
- WOCKY_STUN_SERVER_USER_SPECIFIED,
- WOCKY_STUN_SERVER_DISCOVERED,
- WOCKY_STUN_SERVER_FALLBACK
-} WockyStunServerSource;
-
-#endif /* WOCKY_JINGLE_INFO_INTERNAL_H */
diff --git a/src/jingle-info.c b/src/jingle-info.c
deleted file mode 100644
index 8855f1257..000000000
--- a/src/jingle-info.c
+++ /dev/null
@@ -1,730 +0,0 @@
-/*
- * jingle-info.c - exciting times with Google's jingleinfo extension
- * Copyright © 2008–2012 Collabora Ltd.
- *
- * 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 "jingle-info.h"
-#include "jingle-info-internal.h"
-
-#include <stdlib.h>
-#include <telepathy-glib/telepathy-glib.h>
-
-#define DEBUG_FLAG GABBLE_DEBUG_MEDIA
-#include "debug.h"
-#include "google-relay.h"
-#include "gabble-enumtypes.h"
-#include "gabble-signals-marshal.h"
-#include "namespaces.h"
-
-static gboolean jingle_info_cb (
- WockyPorter *porter,
- WockyStanza *stanza,
- gpointer user_data);
-
-struct _WockyJingleInfoPrivate {
- WockyPorter *porter;
- guint jingle_info_handler_id;
- gchar *jid_domain;
-
- WockyGoogleRelayResolver *google_resolver;
-
- WockyStunServer *stun_server;
- WockyStunServer *fallback_stun_server;
-
- gchar *relay_token;
-
- /* TRUE if the user has not explicitly specified a STUN server, and hence
- * we should ask the XMPP server for one; FALSE if not.
- */
- gboolean get_stun_from_jingle;
-
- gchar *relay_server;
- guint16 relay_http_port;
- guint16 relay_udp;
- guint16 relay_tcp;
- guint16 relay_ssltcp;
-
-};
-
-enum {
- PROP_PORTER = 1,
-};
-
-enum {
- STUN_SERVER_CHANGED = 0,
- N_SIGNALS
-};
-
-static guint signals[N_SIGNALS];
-
-static gboolean test_mode = FALSE;
-
-void
-wocky_jingle_info_set_test_mode (void)
-{
- test_mode = TRUE;
-}
-
-static WockyStunServer *
-wocky_stun_server_new (
- gchar *address,
- guint16 port)
-{
- WockyStunServer stun_server = { address, port };
-
- return g_slice_dup (WockyStunServer, &stun_server);
-}
-
-static void
-wocky_stun_server_free (WockyStunServer *stun_server)
-{
- if (stun_server != NULL)
- {
- g_free (stun_server->address);
- g_slice_free (WockyStunServer, stun_server);
- }
-}
-
-G_DEFINE_TYPE (WockyJingleInfo, wocky_jingle_info, G_TYPE_OBJECT)
-
-static void
-wocky_jingle_info_init (WockyJingleInfo *self)
-{
- self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, WOCKY_TYPE_JINGLE_INFO,
- WockyJingleInfoPrivate);
-
- self->priv->relay_http_port = 80;
- self->priv->get_stun_from_jingle = TRUE;
-}
-
-static void
-wocky_jingle_info_get_property (
- GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- WockyJingleInfo *self = WOCKY_JINGLE_INFO (object);
- WockyJingleInfoPrivate *priv = self->priv;
-
- switch (property_id)
- {
- case PROP_PORTER:
- g_value_set_object (value, priv->porter);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-static void
-wocky_jingle_info_set_property (
- GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- WockyJingleInfo *self = WOCKY_JINGLE_INFO (object);
- WockyJingleInfoPrivate *priv = self->priv;
-
- switch (property_id)
- {
- case PROP_PORTER:
- g_assert (priv->porter == NULL);
- priv->porter = g_value_dup_object (value);
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- }
-}
-
-static void
-wocky_jingle_info_constructed (GObject *object)
-{
- WockyJingleInfo *self = WOCKY_JINGLE_INFO (object);
- WockyJingleInfoPrivate *priv = self->priv;
- GObjectClass *parent_class = wocky_jingle_info_parent_class;
-
- if (parent_class->constructed != NULL)
- parent_class->constructed (object);
-
- g_assert (priv->porter != NULL);
-
- if (!wocky_decode_jid (wocky_porter_get_bare_jid (priv->porter), NULL,
- &priv->jid_domain, NULL))
- g_assert_not_reached ();
-}
-
-static void
-wocky_jingle_info_dispose (GObject *object)
-{
- WockyJingleInfo *self = WOCKY_JINGLE_INFO (object);
- WockyJingleInfoPrivate *priv = self->priv;
- GObjectClass *parent_class = wocky_jingle_info_parent_class;
-
- if (priv->porter != NULL)
- {
- if (priv->jingle_info_handler_id != 0)
- wocky_porter_unregister_handler (priv->porter,
- priv->jingle_info_handler_id);
-
- g_clear_object (&priv->porter);
- }
-
- if (priv->google_resolver != NULL)
- {
- wocky_google_relay_resolver_destroy (priv->google_resolver);
- priv->google_resolver = NULL;
- }
-
- g_free (priv->jid_domain);
- priv->jid_domain = NULL;
- wocky_stun_server_free (priv->stun_server);
- priv->stun_server = NULL;
- wocky_stun_server_free (priv->fallback_stun_server);
- priv->fallback_stun_server = NULL;
- g_free (priv->relay_token);
- priv->relay_token = NULL;
- g_free (priv->relay_server);
- priv->relay_server = NULL;
-
- if (parent_class->dispose != NULL)
- parent_class->dispose (object);
-}
-
-static void
-wocky_jingle_info_class_init (WockyJingleInfoClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GParamSpec *param_spec;
-
- object_class->get_property = wocky_jingle_info_get_property;
- object_class->set_property = wocky_jingle_info_set_property;
- object_class->constructed = wocky_jingle_info_constructed;
- object_class->dispose = wocky_jingle_info_dispose;
-
- g_type_class_add_private (klass, sizeof (WockyJingleInfoPrivate));
-
- param_spec = g_param_spec_object ("porter", "WockyC2SPorter",
- "Porter for the current connection",
- WOCKY_TYPE_C2S_PORTER,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_PORTER, param_spec);
-
- signals[STUN_SERVER_CHANGED] = g_signal_new ("stun-server-changed",
- G_OBJECT_CLASS_TYPE (object_class), G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, gabble_marshal_VOID__STRING_UINT,
- G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_UINT);
-}
-
-WockyJingleInfo *
-wocky_jingle_info_new (
- WockyPorter *porter)
-{
- return g_object_new (WOCKY_TYPE_JINGLE_INFO,
- "porter", porter,
- NULL);
-}
-
-typedef struct {
- WockyJingleInfo *factory;
- gchar *stun_server;
- guint16 stun_port;
- WockyStunServerSource source;
- GCancellable *cancellable;
-} PendingStunServer;
-
-static void
-pending_stun_server_free (gpointer p)
-{
- PendingStunServer *data = p;
-
- if (data->factory != NULL)
- g_object_remove_weak_pointer (G_OBJECT (data->factory),
- (gpointer)&data->factory);
-
- g_object_unref (data->cancellable);
- g_free (data->stun_server);
- g_slice_free (PendingStunServer, p);
-}
-
-static void
-stun_server_resolved_cb (GObject *resolver,
- GAsyncResult *result,
- gpointer user_data)
-{
- PendingStunServer *data = user_data;
- WockyJingleInfo *self = data->factory;
- WockyJingleInfoPrivate *priv = self->priv;
- GError *e = NULL;
- WockyStunServer *stun_server;
- gchar *address;
- GList *entries;
-
- if (self != NULL)
- g_object_weak_unref (G_OBJECT (self),
- (GWeakNotify)g_cancellable_cancel, data->cancellable);
-
- entries = g_resolver_lookup_by_name_finish (
- G_RESOLVER (resolver), result, &e);
-
- if (entries == NULL)
- {
- DEBUG ("Failed to resolve STUN server %s:%u: %s",
- data->stun_server, data->stun_port, e->message);
- g_error_free (e);
- goto out;
- }
-
- address = g_inet_address_to_string (entries->data);
- g_resolver_free_addresses (entries);
-
- DEBUG ("Resolved STUN server %s:%u to %s:%u", data->stun_server,
- data->stun_port, address, data->stun_port);
-
- if (self == NULL)
- {
- g_free (address);
- goto out;
- }
-
- stun_server = wocky_stun_server_new (address, data->stun_port);
-
- if (data->source == WOCKY_STUN_SERVER_FALLBACK)
- {
- wocky_stun_server_free (priv->fallback_stun_server);
- priv->fallback_stun_server = stun_server;
- }
- else
- {
- wocky_stun_server_free (priv->stun_server);
- priv->stun_server = stun_server;
-
- g_signal_emit (self, signals[STUN_SERVER_CHANGED], 0,
- stun_server, data->stun_port);
- }
-
-out:
- pending_stun_server_free (data);
- g_object_unref (resolver);
-}
-
-static void
-wocky_jingle_info_take_stun_server_internal (
- WockyJingleInfo *self,
- gchar *stun_server,
- guint16 stun_port,
- WockyStunServerSource source)
-{
- GResolver *resolver;
- PendingStunServer *data;
-
- if (stun_server == NULL)
- return;
-
- if (source == WOCKY_STUN_SERVER_USER_SPECIFIED)
- self->priv->get_stun_from_jingle = FALSE;
-
- resolver = g_resolver_get_default ();
- data = g_slice_new0 (PendingStunServer);
-
- DEBUG ("Resolving %s STUN server %s:%u",
- wocky_enum_to_nick (GABBLE_TYPE_STUN_SERVER_SOURCE, data->source),
- stun_server, stun_port);
- data->factory = self;
- g_object_add_weak_pointer (G_OBJECT (self), (gpointer *) &data->factory);
- data->stun_server = stun_server;
- data->stun_port = stun_port;
- data->source = source;
-
- data->cancellable = g_cancellable_new ();
- g_object_weak_ref (G_OBJECT (self), (GWeakNotify)g_cancellable_cancel,
- data->cancellable);
-
- g_resolver_lookup_by_name_async (resolver, stun_server,
- data->cancellable, stun_server_resolved_cb, data);
-}
-
-/*
- * wocky_jingle_info_take_stun_server:
- * @self: a #WockyJingleInfo object
- * @stun_server: (transfer full): the STUN server's address
- * @stun_port: the STUN server's port
- * @is_fallback: %TRUE if this is a last resort; %FALSE if this STUN server was
- * provided by the user (whether by explicitly setting one, or by asking the
- * user's XMPP server).
- */
-void
-wocky_jingle_info_take_stun_server (
- WockyJingleInfo *self,
- gchar *stun_server,
- guint16 stun_port,
- gboolean is_fallback)
-{
- WockyStunServerSource source = is_fallback
- ? WOCKY_STUN_SERVER_FALLBACK
- : WOCKY_STUN_SERVER_USER_SPECIFIED;
-
- wocky_jingle_info_take_stun_server_internal (self, stun_server, stun_port,
- source);
-}
-
-static void
-got_jingle_info_stanza (
- WockyJingleInfo *self,
- WockyStanza *stanza)
-{
- WockyNode *node, *query_node;
-
- query_node = wocky_node_get_child_ns (
- wocky_stanza_get_top_node (stanza), "query", NS_GOOGLE_JINGLE_INFO);
-
- if (query_node == NULL)
- return;
-
- if (self->priv->get_stun_from_jingle)
- node = wocky_node_get_child (query_node, "stun");
- else
- node = NULL;
-
- if (node != NULL)
- {
- WockyNodeIter iter;
-
- /* TODO: use more than just the first stun server returned. */
- wocky_node_iter_init (&iter, node, "server", NULL);
- if (wocky_node_iter_next (&iter, &node))
- {
- const gchar *server;
- const gchar *port_attr;
- guint port = 0;
-
- server = wocky_node_get_attribute (node, "host");
- port_attr = wocky_node_get_attribute (node, "udp");
-
- if (port_attr != NULL)
- port = atoi (port_attr);
-
- if (server != NULL &&
- port_attr != NULL && port > 0 && port <= G_MAXUINT16)
- {
- DEBUG ("jingle info: got stun server %s, port %u", server,
- port);
- wocky_jingle_info_take_stun_server_internal (self,
- g_strdup (server), port, WOCKY_STUN_SERVER_DISCOVERED);
- }
- }
- }
-
-#ifdef ENABLE_GOOGLE_RELAY
- node = wocky_node_get_child (query_node, "relay");
-
- if (node != NULL)
- {
- WockyNode *subnode = wocky_node_get_child (node, "token");
-
- if (subnode != NULL)
- {
- const gchar *token = subnode->content;
-
- if (token != NULL)
- {
- DEBUG ("jingle info: got Google relay token %s", token);
- g_free (self->priv->relay_token);
- self->priv->relay_token = g_strdup (token);
- }
- }
-
- subnode = wocky_node_get_child (node, "server");
-
- if (subnode != NULL)
- {
- const gchar *server;
- const gchar *port;
-
- server = wocky_node_get_attribute (subnode, "host");
-
- if (server != NULL)
- {
- DEBUG ("jingle info: got relay server %s", server);
- g_free (self->priv->relay_server);
- self->priv->relay_server = g_strdup (server);
- }
-
- if (test_mode)
- {
- /* this is not part of the real protocol, but we can't listen on
- * port 80 in an unprivileged regression test */
- port = wocky_node_get_attribute (subnode,
- "gabble-test-http-port");
-
- if (port != NULL)
- {
- DEBUG ("jingle info: diverting 'Google' HTTP requests to "
- "port %s", port);
- self->priv->relay_http_port = atoi (port);
- }
- }
-
- /* FIXME: these are not really actually used anywhere at
- * the moment, because we get the same info when creating
- * relay session. */
- port = wocky_node_get_attribute (subnode, "udp");
-
- if (port != NULL)
- {
- DEBUG ("jingle info: got relay udp port %s", port);
- self->priv->relay_udp = atoi (port);
- }
-
- port = wocky_node_get_attribute (subnode, "tcp");
-
- if (port != NULL)
- {
- DEBUG ("jingle info: got relay tcp port %s", port);
- self->priv->relay_tcp = atoi (port);
- }
-
- port = wocky_node_get_attribute (subnode, "tcpssl");
-
- if (port != NULL)
- {
- DEBUG ("jingle info: got relay tcpssl port %s", port);
- self->priv->relay_ssltcp = atoi (port);
- }
-
- }
-
- }
-#endif /* ENABLE_GOOGLE_RELAY */
-}
-
-static gboolean
-jingle_info_cb (
- WockyPorter *porter,
- WockyStanza *stanza,
- gpointer user_data)
-{
- WockyJingleInfo *self = WOCKY_JINGLE_INFO (user_data);
-
- got_jingle_info_stanza (self, stanza);
- wocky_porter_acknowledge_iq (porter, stanza, NULL);
-
- return TRUE;
-}
-
-static void
-jingle_info_reply_cb (
- GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- WockyPorter *porter = WOCKY_PORTER (source);
- WockyJingleInfo *self = WOCKY_JINGLE_INFO (user_data);
- WockyStanza *reply = NULL;
- GError *error = NULL;
-
- reply = wocky_porter_send_iq_finish (porter, result, &error);
- if (reply != NULL &&
- !wocky_stanza_extract_errors (reply, NULL, &error, NULL, NULL))
- {
- got_jingle_info_stanza (self, reply);
- }
- else
- {
- DEBUG ("jingle info request failed: %s", error->message);
- g_clear_error (&error);
- }
-
- g_clear_object (&reply);
- g_object_unref (self);
-}
-
-static void
-wocky_jingle_info_send_google_request (
- WockyJingleInfo *self)
-{
- WockyJingleInfoPrivate *priv = self->priv;
- WockyStanza *stanza = wocky_stanza_build (
- WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_GET, NULL,
- wocky_porter_get_bare_jid (priv->porter),
- '(', "query", ':', NS_GOOGLE_JINGLE_INFO, ')', NULL);
-
- wocky_porter_send_iq_async (priv->porter, stanza, NULL, jingle_info_reply_cb,
- g_object_ref (self));
- g_object_unref (stanza);
-
- priv->jingle_info_handler_id = wocky_c2s_porter_register_handler_from_server (
- WOCKY_C2S_PORTER (priv->porter),
- WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET,
- WOCKY_PORTER_HANDLER_PRIORITY_NORMAL, jingle_info_cb, self,
- '(', "query", ':', NS_GOOGLE_JINGLE_INFO, ')', NULL);
-}
-
-static void
-discover_stun_servers_cb (GObject *resolver,
- GAsyncResult *result,
- gpointer user_data)
-{
- WockyJingleInfo *self = WOCKY_JINGLE_INFO (user_data);
- WockyJingleInfoPrivate *priv = self->priv;
- GError *error = NULL;
- GList *targets;
-
- targets = g_resolver_lookup_service_finish (G_RESOLVER (resolver),
- result, &error);
-
- if (error != NULL)
- {
- DEBUG ("Failed to discover STUN servers on %s: %s",
- priv->jid_domain, error->message);
- g_clear_error (&error);
- }
- else
- {
- DEBUG ("Discovered %d STUN servers on %s", g_list_length (targets),
- priv->jid_domain);
-
- /* TODO: use more than just the first. */
- if (targets != NULL)
- {
- GSrvTarget *target = targets->data;
- const gchar *hostname = g_srv_target_get_hostname (target);
- guint16 port = g_srv_target_get_port (target);
-
- DEBUG ("Found STUN server: %s:%d", hostname, port);
-
- wocky_jingle_info_take_stun_server (self, g_strdup (hostname), port,
- FALSE);
- }
-
- g_resolver_free_targets (targets);
- }
-
- g_object_unref (resolver);
- g_object_unref (self);
-}
-
-static void
-wocky_jingle_info_lookup_srv (
- WockyJingleInfo *self)
-{
- WockyJingleInfoPrivate *priv = self->priv;
- GResolver *resolver;
-
- g_assert (priv->jid_domain != NULL);
- DEBUG ("Discovering STUN servers on %s", priv->jid_domain);
-
- resolver = g_resolver_get_default ();
- g_resolver_lookup_service_async (resolver, "stun", "udp", priv->jid_domain,
- NULL, discover_stun_servers_cb, g_object_ref (self));
-}
-
-void
-wocky_jingle_info_send_request (
- WockyJingleInfo *self,
- gboolean google_jingleinfo_supported)
-{
- /* FIXME: we probably don't want to send either query if the user specified a
- * stun server (that is, get_stun_from_jingle is FALSE).
- */
- if (google_jingleinfo_supported)
- wocky_jingle_info_send_google_request (self);
- else
- wocky_jingle_info_lookup_srv (self);
-}
-
-/*
- * wocky_jingle_info_get_stun_servers:
- *
- * Grabs the currently known and resolved stun servers.
- *
- * Returns: (transfer container): a list of WockyJingleInfo structs
- */
-GList *
-wocky_jingle_info_get_stun_servers (
- WockyJingleInfo *self)
-{
- WockyJingleInfoPrivate *priv = self->priv;
- GQueue stun_servers = G_QUEUE_INIT;
-
- if (priv->stun_server != NULL)
- g_queue_push_head (&stun_servers, priv->stun_server);
-
- /* Only add the fallback server as a last resort. */
- if (stun_servers.length == 0 &&
- priv->fallback_stun_server != NULL)
- g_queue_push_tail (&stun_servers, priv->fallback_stun_server);
-
- return stun_servers.head;
-}
-
-const gchar *
-wocky_jingle_info_get_google_relay_token (
- WockyJingleInfo *self)
-{
- return self->priv->relay_token;
-}
-
-WockyJingleRelay *
-wocky_jingle_relay_new (
- WockyJingleRelayType type,
- const gchar *ip,
- guint port,
- const gchar *username,
- const gchar *password,
- guint component)
-{
- WockyJingleRelay ret = { type, g_strdup (ip), port, g_strdup (username),
- g_strdup (password), component };
-
- return g_slice_dup (WockyJingleRelay, &ret);
-}
-
-void
-wocky_jingle_relay_free (WockyJingleRelay *relay)
-{
- g_free (relay->ip);
- g_free (relay->username);
- g_free (relay->password);
- g_slice_free (WockyJingleRelay, relay);
-}
-
-void
-wocky_jingle_info_create_google_relay_session (
- WockyJingleInfo *self,
- guint components,
- WockyJingleInfoRelaySessionCb callback,
- gpointer user_data)
-{
- WockyJingleInfoPrivate *priv = self->priv;
-
- g_return_if_fail (callback != NULL);
-
- if (priv->google_resolver == NULL)
- {
- priv->google_resolver = wocky_google_relay_resolver_new ();
- }
-
- wocky_google_relay_resolver_resolve (priv->google_resolver,
- components, priv->relay_server, priv->relay_http_port, priv->relay_token,
- callback, user_data);
-}
diff --git a/src/jingle-info.h b/src/jingle-info.h
deleted file mode 100644
index d006da44e..000000000
--- a/src/jingle-info.h
+++ /dev/null
@@ -1,121 +0,0 @@
-/*
- * jingle-info.h - exciting times with Google's jingleinfo extension
- * Copyright © 2008–2012 Collabora Ltd.
- *
- * 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 WOCKY_JINGLE_INFO_H
-#define WOCKY_JINGLE_INFO_H
-
-#include <glib-object.h>
-#include <wocky/wocky.h>
-
-typedef struct _WockyJingleInfo WockyJingleInfo;
-typedef struct _WockyJingleInfoClass WockyJingleInfoClass;
-typedef struct _WockyJingleInfoPrivate WockyJingleInfoPrivate;
-
-struct _WockyJingleInfoClass {
- GObjectClass parent_class;
-};
-
-struct _WockyJingleInfo {
- GObject parent;
-
- WockyJingleInfoPrivate *priv;
-};
-
-GType wocky_jingle_info_get_type (void);
-
-WockyJingleInfo *wocky_jingle_info_new (
- WockyPorter *porter);
-
-void wocky_jingle_info_take_stun_server (
- WockyJingleInfo *self,
- gchar *stun_server,
- guint16 stun_port,
- gboolean is_fallback);
-void wocky_jingle_info_send_request (
- WockyJingleInfo *self,
- gboolean google_jingleinfo_supported);
-
-typedef struct {
- gchar *address;
- guint16 port;
-} WockyStunServer;
-
-GList *wocky_jingle_info_get_stun_servers (
- WockyJingleInfo *self);
-
-const gchar *wocky_jingle_info_get_google_relay_token (
- WockyJingleInfo *self);
-
-typedef enum {
- WOCKY_JINGLE_RELAY_TYPE_UDP,
- WOCKY_JINGLE_RELAY_TYPE_TCP,
- WOCKY_JINGLE_RELAY_TYPE_TLS
-} WockyJingleRelayType;
-#define WOCKY_N_JINGLE_RELAY_TYPES 3
-
-typedef struct {
- WockyJingleRelayType type;
- gchar *ip;
- guint port;
- gchar *username;
- gchar *password;
- guint component;
-} WockyJingleRelay;
-
-WockyJingleRelay *wocky_jingle_relay_new (
- WockyJingleRelayType type,
- const gchar *ip,
- guint port,
- const gchar *username,
- const gchar *password,
- guint component);
-void wocky_jingle_relay_free (WockyJingleRelay *relay);
-
-/*
- * @relays: (element-type WockyJingleRelay) (transfer none): a possibly-empty
- * array of WockyJingleRelay structs.
- */
-typedef void (*WockyJingleInfoRelaySessionCb) (
- GPtrArray *relays,
- gpointer user_data);
-void wocky_jingle_info_create_google_relay_session (
- WockyJingleInfo *self,
- guint components,
- WockyJingleInfoRelaySessionCb callback,
- gpointer user_data);
-
-void wocky_jingle_info_set_test_mode (void);
-
-/* TYPE MACROS */
-#define WOCKY_TYPE_JINGLE_INFO \
- (wocky_jingle_info_get_type ())
-#define WOCKY_JINGLE_INFO(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), WOCKY_TYPE_JINGLE_INFO, WockyJingleInfo))
-#define WOCKY_JINGLE_INFO_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), WOCKY_TYPE_JINGLE_INFO,\
- WockyJingleInfoClass))
-#define WOCKY_IS_JINGLE_INFO(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), WOCKY_TYPE_JINGLE_INFO))
-#define WOCKY_IS_JINGLE_INFO_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), WOCKY_TYPE_JINGLE_INFO))
-#define WOCKY_JINGLE_INFO_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), WOCKY_TYPE_JINGLE_INFO, \
- WockyJingleInfoClass))
-
-#endif /* WOCKY_JINGLE_INFO_H */
diff --git a/src/jingle-media-rtp.c b/src/jingle-media-rtp.c
deleted file mode 100644
index 7bf80c6f8..000000000
--- a/src/jingle-media-rtp.c
+++ /dev/null
@@ -1,1517 +0,0 @@
-/*
- * jingle-media-rtp.c - Source for WockyJingleMediaRtp
- *
- * Copyright (C) 2008 Collabora Ltd.
- *
- * 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
- */
-
-/* Media/RTP content type deals with audio/video content, ie. jingle calls. It
- * supports standard Jingle drafts (v0.15, v0.26) and Google's jingle variants
- * (libjingle 0.3/0.4). */
-
-#include "config.h"
-#include "jingle-media-rtp.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-
-#define DEBUG_FLAG GABBLE_DEBUG_MEDIA
-
-#include "connection.h"
-#include "debug.h"
-#include "jingle-content.h"
-#include "jingle-factory.h"
-#include "jingle-session.h"
-#include "namespaces.h"
-#include "presence-cache.h"
-#include "jingle-transport-google.h"
-
-G_DEFINE_TYPE (WockyJingleMediaRtp,
- wocky_jingle_media_rtp, WOCKY_TYPE_JINGLE_CONTENT);
-
-/* signal enum */
-enum
-{
- REMOTE_MEDIA_DESCRIPTION,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = {0};
-
-/* properties */
-enum
-{
- PROP_MEDIA_TYPE = 1,
- PROP_REMOTE_MUTE,
- LAST_PROPERTY
-};
-
-typedef enum {
- WOCKY_JINGLE_MEDIA_PROFILE_RTP_AVP,
-} WockyJingleMediaProfile;
-
-struct _WockyJingleMediaRtpPrivate
-{
- WockyJingleMediaDescription *local_media_description;
-
- /* Holds (WockyJingleCodec *)'s borrowed from local_media_description,
- * namely codecs which have changed from local_media_description's
- * previous value. Since the contents are borrowed, this must be
- * freed with g_list_free, not jingle_media_rtp_free_codecs().
- */
- GList *local_codec_updates;
-
- WockyJingleMediaDescription *remote_media_description;
- WockyJingleMediaType media_type;
- gboolean remote_mute;
-
- gboolean has_rtcp_fb;
- gboolean has_rtp_hdrext;
-
- gboolean dispose_has_run;
-};
-
-static void
-wocky_jingle_media_rtp_init (WockyJingleMediaRtp *obj)
-{
- WockyJingleMediaRtpPrivate *priv =
- G_TYPE_INSTANCE_GET_PRIVATE (obj, WOCKY_TYPE_JINGLE_MEDIA_RTP,
- WockyJingleMediaRtpPrivate);
- obj->priv = priv;
- priv->dispose_has_run = FALSE;
-}
-
-WockyJingleCodec *
-jingle_media_rtp_codec_new (guint id, const gchar *name,
- guint clockrate, guint channels, GHashTable *params)
-{
- WockyJingleCodec *p = g_slice_new0 (WockyJingleCodec);
-
- p->id = id;
- p->name = g_strdup (name);
- p->clockrate = clockrate;
- p->channels = channels;
- p->trr_int = G_MAXUINT;
-
- if (params != NULL)
- {
- g_hash_table_ref (params);
- p->params = params;
- }
- else
- {
- p->params = g_hash_table_new_full (g_str_hash, g_str_equal, g_free,
- g_free);
- }
-
- return p;
-}
-
-
-static GList *
-wocky_jingle_feedback_message_list_copy (GList *fbs)
-{
- GQueue new = G_QUEUE_INIT;
- GList *li;
-
- for (li = fbs; li; li = li->next)
- {
- WockyJingleFeedbackMessage *fb = li->data;
-
- g_queue_push_tail (&new, wocky_jingle_feedback_message_new (fb->type,
- fb->subtype));
- }
-
- return new.head;
-}
-
-static void
-wocky_jingle_feedback_message_list_free (GList *fbs)
-{
- while (fbs != NULL)
- {
- wocky_jingle_feedback_message_free (fbs->data);
- fbs = g_list_delete_link (fbs, fbs);
- }
-}
-
-void
-jingle_media_rtp_codec_free (WockyJingleCodec *p)
-{
- g_hash_table_unref (p->params);
- g_free (p->name);
- wocky_jingle_feedback_message_list_free (p->feedback_msgs);
- g_slice_free (WockyJingleCodec, p);
-}
-
-static void
-add_codec_to_table (WockyJingleCodec *codec,
- GHashTable *table)
-{
- g_hash_table_insert (table, GUINT_TO_POINTER ((guint) codec->id), codec);
-}
-
-static GHashTable *
-build_codec_table (GList *codecs)
-{
- GHashTable *table = g_hash_table_new (NULL, NULL);
-
- g_list_foreach (codecs, (GFunc) add_codec_to_table, table);
- return table;
-}
-
-GList *
-jingle_media_rtp_copy_codecs (GList *codecs)
-{
- GList *ret = NULL, *l;
-
- for (l = codecs; l != NULL; l = g_list_next (l))
- {
- WockyJingleCodec *c = l->data;
- WockyJingleCodec *newc = jingle_media_rtp_codec_new (c->id,
- c->name, c->clockrate, c->channels, c->params);
- newc->trr_int = c->trr_int;
- ret = g_list_append (ret, newc);
- }
-
- return ret;
-}
-
-void
-jingle_media_rtp_free_codecs (GList *codecs)
-{
- while (codecs != NULL)
- {
- jingle_media_rtp_codec_free (codecs->data);
- codecs = g_list_delete_link (codecs, codecs);
- }
-}
-
-static void
-wocky_jingle_media_rtp_dispose (GObject *object)
-{
- WockyJingleMediaRtp *trans = WOCKY_JINGLE_MEDIA_RTP (object);
- WockyJingleMediaRtpPrivate *priv = trans->priv;
-
- if (priv->dispose_has_run)
- return;
-
- DEBUG ("dispose called");
- priv->dispose_has_run = TRUE;
-
- if (priv->remote_media_description != NULL)
- wocky_jingle_media_description_free (priv->remote_media_description);
- priv->remote_media_description = NULL;
-
- if (priv->local_media_description != NULL)
- wocky_jingle_media_description_free (priv->local_media_description);
- priv->local_media_description = NULL;
-
- if (priv->local_codec_updates != NULL)
- {
- DEBUG ("We have an unsent codec parameter update! Weird.");
-
- g_list_free (priv->local_codec_updates);
- priv->local_codec_updates = NULL;
- }
-
- if (G_OBJECT_CLASS (wocky_jingle_media_rtp_parent_class)->dispose)
- G_OBJECT_CLASS (wocky_jingle_media_rtp_parent_class)->dispose (object);
-}
-
-static void
-wocky_jingle_media_rtp_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- WockyJingleMediaRtp *trans = WOCKY_JINGLE_MEDIA_RTP (object);
- WockyJingleMediaRtpPrivate *priv = trans->priv;
-
- switch (property_id) {
- case PROP_MEDIA_TYPE:
- g_value_set_uint (value, priv->media_type);
- break;
- case PROP_REMOTE_MUTE:
- g_value_set_boolean (value, priv->remote_mute);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-wocky_jingle_media_rtp_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- WockyJingleMediaRtp *trans = WOCKY_JINGLE_MEDIA_RTP (object);
- WockyJingleMediaRtpPrivate *priv = trans->priv;
-
- switch (property_id) {
- case PROP_MEDIA_TYPE:
- priv->media_type = g_value_get_uint (value);
- break;
- case PROP_REMOTE_MUTE:
- priv->remote_mute = g_value_get_boolean (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void parse_description (WockyJingleContent *content,
- WockyNode *desc_node, GError **error);
-static void produce_description (WockyJingleContent *obj,
- WockyNode *content_node);
-static void transport_created (WockyJingleContent *obj,
- WockyJingleTransportIface *transport);
-
-static void
-wocky_jingle_media_rtp_class_init (WockyJingleMediaRtpClass *cls)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (cls);
- WockyJingleContentClass *content_class = WOCKY_JINGLE_CONTENT_CLASS (cls);
- GParamSpec *param_spec;
-
- g_type_class_add_private (cls, sizeof (WockyJingleMediaRtpPrivate));
-
- object_class->get_property = wocky_jingle_media_rtp_get_property;
- object_class->set_property = wocky_jingle_media_rtp_set_property;
- object_class->dispose = wocky_jingle_media_rtp_dispose;
-
- content_class->parse_description = parse_description;
- content_class->produce_description = produce_description;
- content_class->transport_created = transport_created;
-
- param_spec = g_param_spec_uint ("media-type", "RTP media type",
- "Media type.",
- WOCKY_JINGLE_MEDIA_TYPE_NONE, G_MAXUINT32, WOCKY_JINGLE_MEDIA_TYPE_NONE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_MEDIA_TYPE, param_spec);
-
- param_spec = g_param_spec_boolean ("remote-mute", "Remote mute",
- "TRUE if the peer has muted this stream", FALSE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_REMOTE_MUTE, param_spec);
-
- /* signal definitions */
-
- signals[REMOTE_MEDIA_DESCRIPTION] = g_signal_new ("remote-media-description",
- G_TYPE_FROM_CLASS (cls), G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, g_cclosure_marshal_VOID__POINTER,
- G_TYPE_NONE, 1, G_TYPE_POINTER);
-}
-
-static void transport_created (WockyJingleContent *content,
- WockyJingleTransportIface *transport)
-{
- WockyJingleMediaRtp *self = WOCKY_JINGLE_MEDIA_RTP (content);
- WockyJingleMediaRtpPrivate *priv = self->priv;
- WockyJingleTransportGoogle *gtrans = NULL;
- WockyJingleDialect dialect;
-
- if (WOCKY_IS_JINGLE_TRANSPORT_GOOGLE (transport))
- {
- gtrans = WOCKY_JINGLE_TRANSPORT_GOOGLE (transport);
- dialect = wocky_jingle_session_get_dialect (content->session);
-
- if (priv->media_type == WOCKY_JINGLE_MEDIA_TYPE_VIDEO &&
- (WOCKY_JINGLE_DIALECT_IS_GOOGLE (dialect) ||
- wocky_jingle_session_peer_has_cap (content->session,
- QUIRK_GOOGLE_WEBMAIL_CLIENT) ||
- wocky_jingle_session_peer_has_cap (content->session,
- QUIRK_ANDROID_GTALK_CLIENT)))
- {
- jingle_transport_google_set_component_name (gtrans, "video_rtp", 1);
- jingle_transport_google_set_component_name (gtrans, "video_rtcp", 2);
- }
- else
- {
- jingle_transport_google_set_component_name (gtrans, "rtp", 1);
- jingle_transport_google_set_component_name (gtrans, "rtcp", 2);
- }
- }
-}
-
-
-static WockyJingleMediaType
-extract_media_type (WockyNode *desc_node,
- GError **error)
-{
- if (wocky_node_has_ns (desc_node, NS_JINGLE_RTP))
- {
- const gchar *type = wocky_node_get_attribute (desc_node, "media");
-
- if (type == NULL)
- {
- g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST,
- "missing required media type attribute");
- return WOCKY_JINGLE_MEDIA_TYPE_NONE;
- }
-
- if (!wocky_strdiff (type, "audio"))
- return WOCKY_JINGLE_MEDIA_TYPE_AUDIO;
-
- if (!wocky_strdiff (type, "video"))
- return WOCKY_JINGLE_MEDIA_TYPE_VIDEO;
-
- g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST,
- "unknown media type %s", type);
- return WOCKY_JINGLE_MEDIA_TYPE_NONE;
- }
-
- if (wocky_node_has_ns (desc_node, NS_JINGLE_DESCRIPTION_AUDIO))
- return WOCKY_JINGLE_MEDIA_TYPE_AUDIO;
-
- if (wocky_node_has_ns (desc_node, NS_JINGLE_DESCRIPTION_VIDEO))
- return WOCKY_JINGLE_MEDIA_TYPE_VIDEO;
-
- if (wocky_node_has_ns (desc_node, NS_GOOGLE_SESSION_PHONE))
- return WOCKY_JINGLE_MEDIA_TYPE_AUDIO;
-
- if (wocky_node_has_ns (desc_node, NS_GOOGLE_SESSION_VIDEO))
- return WOCKY_JINGLE_MEDIA_TYPE_VIDEO;
-
- /* If we get here, namespace in use is not one of namespaces we signed up
- * with, so obviously a bug somewhere.
- */
- g_assert_not_reached ();
-}
-
-static WockyJingleFeedbackMessage *
-parse_rtcp_fb (WockyJingleContent *content, WockyNode *node)
-{
- const gchar *pt_ns = wocky_node_get_ns (node);
- const gchar *type;
- const gchar *subtype;
-
- if (wocky_strdiff (pt_ns, NS_JINGLE_RTCP_FB))
- return NULL;
-
- type = wocky_node_get_attribute (node, "type");
- if (type == NULL)
- return NULL;
-
- subtype = wocky_node_get_attribute (node, "subtype");
-
- /* This is optional, defaults to "" */
- if (subtype == NULL)
- subtype = "";
-
- return wocky_jingle_feedback_message_new (type, subtype);
-}
-
-
-/*
- * Returns G_MAXUINT on error
- */
-static guint
-parse_rtcp_fb_trr_int (WockyJingleContent *content, WockyNode *node)
-{
- const gchar *pt_ns = wocky_node_get_ns (node);
- const gchar *txt;
- guint trr_int;
- gchar *endptr = NULL;
-
- if (wocky_strdiff (pt_ns, NS_JINGLE_RTCP_FB))
- return G_MAXUINT;
-
- txt = wocky_node_get_attribute (node, "value");
- if (txt == NULL)
- return G_MAXUINT;
-
- trr_int = strtol (txt, &endptr, 10);
- if (endptr == NULL || endptr == txt)
- return G_MAXUINT;
-
- return trr_int;
-}
-
-
-/**
- * parse_payload_type:
- * @node: a <payload-type> node.
- *
- * Returns: a newly-allocated WockyJingleCodec if parsing succeeds, or %NULL
- * otherwise.
- */
-static WockyJingleCodec *
-parse_payload_type (WockyJingleContent *content,
- WockyNode *node)
-{
- WockyJingleMediaRtp *self = WOCKY_JINGLE_MEDIA_RTP (content);
- WockyJingleMediaRtpPrivate *priv = self->priv;
- WockyJingleCodec *p;
- const char *txt;
- guint8 id;
- const gchar *name;
- guint clockrate = 0;
- guint channels = 0;
- WockyNode *param;
- WockyNodeIter i;
-
- txt = wocky_node_get_attribute (node, "id");
- if (txt == NULL)
- return NULL;
-
- id = atoi (txt);
-
- name = wocky_node_get_attribute (node, "name");
- if (name == NULL)
- name = "";
-
- /* xep-0167 v0.22, gtalk libjingle 0.3/0.4 use "clockrate" */
- txt = wocky_node_get_attribute (node, "clockrate");
- /* older jingle rtp used "rate" ? */
- if (txt == NULL)
- txt = wocky_node_get_attribute (node, "rate");
-
- if (txt != NULL)
- clockrate = atoi (txt);
-
- txt = wocky_node_get_attribute (node, "channels");
- if (txt != NULL)
- channels = atoi (txt);
-
- p = jingle_media_rtp_codec_new (id, name, clockrate, channels, NULL);
-
- wocky_node_iter_init (&i, node, NULL, NULL);
- while (wocky_node_iter_next (&i, &param))
- {
- if (!wocky_strdiff (param->name, "parameter"))
- {
- const gchar *param_name, *param_value;
-
- param_name = wocky_node_get_attribute (param, "name");
- param_value = wocky_node_get_attribute (param, "value");
-
- if (param_name == NULL || param_value == NULL)
- continue;
-
- g_hash_table_insert (p->params, g_strdup (param_name),
- g_strdup (param_value));
- }
- else if (!wocky_strdiff (param->name, "rtcp-fb"))
- {
- WockyJingleFeedbackMessage *fb = parse_rtcp_fb (content, param);
-
- if (fb != NULL)
- {
- p->feedback_msgs = g_list_append (p->feedback_msgs, fb);
- priv->has_rtcp_fb = TRUE;
- }
- }
- else if (!wocky_strdiff (param->name,
- "rtcp-fb-trr-int"))
- {
- guint trr_int = parse_rtcp_fb_trr_int (content, param);
-
- if (trr_int != G_MAXUINT)
- {
- p->trr_int = trr_int;
- priv->has_rtcp_fb = TRUE;
- }
- }
- }
-
- DEBUG ("new remote codec: id = %u, name = %s, clockrate = %u, channels = %u",
- p->id, p->name, p->clockrate, p->channels);
-
- return p;
-}
-
-static WockyJingleRtpHeaderExtension *
-parse_rtp_header_extension (WockyNode *node)
-{
- guint id;
- WockyJingleContentSenders senders;
- const gchar *uri;
- const char *txt;
-
- txt = wocky_node_get_attribute (node, "id");
- if (txt == NULL)
- return NULL;
-
- id = atoi (txt);
-
- /* Only valid ranges are 1-256 and 4096-4351 */
- if ((id < 1 || id > 256) && (id < 4096 || id > 4351))
- return NULL;
-
- txt = wocky_node_get_attribute (node, "senders");
-
- if (txt == NULL || !g_ascii_strcasecmp (txt, "both"))
- senders = WOCKY_JINGLE_CONTENT_SENDERS_BOTH;
- else if (!g_ascii_strcasecmp (txt, "initiator"))
- senders = WOCKY_JINGLE_CONTENT_SENDERS_INITIATOR;
- else if (!g_ascii_strcasecmp (txt, "responder"))
- senders = WOCKY_JINGLE_CONTENT_SENDERS_RESPONDER;
- else
- return NULL;
-
- uri = wocky_node_get_attribute (node, "uri");
-
- if (uri == NULL)
- return NULL;
-
- return wocky_jingle_rtp_header_extension_new (id, senders, uri);
-}
-
-
-/**
- * codec_update_coherent:
- * @old_c: Gabble's old cache of the codec, or %NULL if it hasn't heard of it.
- * @new_c: the proposed update, whose id must equal that of @old_c if the
- * latter is non-NULL.
- * @domain: the error domain to set @e to if necessary
- * @code: the error code to set @e to if necessary
- * @e: location to hold an error
- *
- * Compares @old_c and @new_c, which are assumed to have the same id, to check
- * that the name, clockrate and number of channels hasn't changed. If they
- * have, returns %FALSE and sets @e.
- */
-static gboolean
-codec_update_coherent (const WockyJingleCodec *old_c,
- const WockyJingleCodec *new_c,
- GError **e)
-{
- const GQuark domain = WOCKY_XMPP_ERROR;
- const gint code = WOCKY_XMPP_ERROR_BAD_REQUEST;
-
- if (old_c == NULL)
- {
- g_set_error (e, domain, code, "Codec with id %u ('%s') unknown",
- new_c->id, new_c->name);
- return FALSE;
- }
-
- if (g_ascii_strcasecmp (new_c->name, old_c->name))
- {
- g_set_error (e, domain, code,
- "tried to change codec %u's name from %s to %s",
- new_c->id, old_c->name, new_c->name);
- return FALSE;
- }
-
- if (new_c->clockrate != old_c->clockrate)
- {
- g_set_error (e, domain, code,
- "tried to change codec %u (%s)'s clockrate from %u to %u",
- new_c->id, new_c->name, old_c->clockrate, new_c->clockrate);
- return FALSE;
- }
-
- if (old_c->channels != 0 &&
- new_c->channels != old_c->channels)
- {
- g_set_error (e, domain, code,
- "tried to change codec %u (%s)'s channels from %u to %u",
- new_c->id, new_c->name, new_c->channels, old_c->channels);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-update_remote_media_description (WockyJingleMediaRtp *self,
- WockyJingleMediaDescription *new_media_description,
- GError **error)
-{
- WockyJingleMediaRtpPrivate *priv = self->priv;
- GHashTable *rc = NULL;
- WockyJingleCodec *old_c, *new_c;
- GList *l;
- GError *e = NULL;
-
- if (priv->remote_media_description == NULL)
- {
- priv->remote_media_description = new_media_description;
- new_media_description = NULL;
- goto out;
- }
-
- rc = build_codec_table (priv->remote_media_description->codecs);
-
- /* We already know some remote codecs, so this is just the other end updating
- * some parameters.
- */
- for (l = new_media_description->codecs; l != NULL; l = l->next)
- {
- new_c = l->data;
- old_c = g_hash_table_lookup (rc, GUINT_TO_POINTER ((guint) new_c->id));
-
- if (!codec_update_coherent (old_c, new_c, &e))
- goto out;
- }
-
- /* Okay, all the updates are cool. Let's switch the parameters around. */
- for (l = new_media_description->codecs; l != NULL; l = l->next)
- {
- GHashTable *params;
-
- new_c = l->data;
- old_c = g_hash_table_lookup (rc, GUINT_TO_POINTER ((guint) new_c->id));
-
- params = old_c->params;
- old_c->params = new_c->params;
- new_c->params = params;
- }
-
-out:
- if (new_media_description != NULL)
- wocky_jingle_media_description_free (new_media_description);
-
- if (rc != NULL)
- g_hash_table_unref (rc);
-
- if (e != NULL)
- {
- DEBUG ("Rejecting codec update: %s", e->message);
- g_propagate_error (error, e);
- }
- else
- {
- DEBUG ("Emitting remote-media-description signal");
- g_signal_emit (self, signals[REMOTE_MEDIA_DESCRIPTION], 0,
- priv->remote_media_description);
- }
-}
-
-static void
-parse_description (WockyJingleContent *content,
- WockyNode *desc_node, GError **error)
-{
- WockyJingleMediaRtp *self = WOCKY_JINGLE_MEDIA_RTP (content);
- WockyJingleMediaRtpPrivate *priv = self->priv;
- WockyJingleMediaType mtype;
- WockyJingleMediaDescription *md;
- WockyJingleCodec *p;
- WockyJingleDialect dialect = wocky_jingle_session_get_dialect (content->session);
- gboolean video_session = FALSE;
- WockyNodeIter i;
- WockyNode *node;
- gboolean description_error = FALSE;
- gboolean is_avpf = FALSE;
-
- DEBUG ("node: %s", desc_node->name);
-
- if (priv->media_type == WOCKY_JINGLE_MEDIA_TYPE_NONE)
- mtype = extract_media_type (desc_node, error);
- else
- mtype = priv->media_type;
-
- if (mtype == WOCKY_JINGLE_MEDIA_TYPE_NONE)
- return;
-
- DEBUG ("detected media type %u", mtype);
-
- if (dialect == WOCKY_JINGLE_DIALECT_GTALK3)
- {
- const gchar *desc_ns =
- wocky_node_get_ns (desc_node);
- video_session = !wocky_strdiff (desc_ns, NS_GOOGLE_SESSION_VIDEO);
- }
-
- md = wocky_jingle_media_description_new ();
-
- wocky_node_iter_init (&i, desc_node, NULL, NULL);
- while (wocky_node_iter_next (&i, &node) && !description_error)
- {
- if (!wocky_strdiff (node->name, "payload-type"))
- {
- if (dialect == WOCKY_JINGLE_DIALECT_GTALK3)
- {
- const gchar *pt_ns = wocky_node_get_ns (node);
-
- if (priv->media_type == WOCKY_JINGLE_MEDIA_TYPE_AUDIO)
- {
- if (video_session &&
- wocky_strdiff (pt_ns, NS_GOOGLE_SESSION_PHONE))
- continue;
- }
- else if (priv->media_type == WOCKY_JINGLE_MEDIA_TYPE_VIDEO)
- {
- if (!(video_session && pt_ns == NULL)
- && wocky_strdiff (pt_ns, NS_GOOGLE_SESSION_VIDEO))
- continue;
- }
- }
-
- p = parse_payload_type (content, node);
-
- if (p == NULL)
- {
- description_error = TRUE;
- }
- else
- {
- md->codecs = g_list_append (md->codecs, p);
- if (p->trr_int != G_MAXUINT || p->feedback_msgs)
- is_avpf = TRUE;
- }
- }
- else if (!wocky_strdiff (node->name, "rtp-hdrext"))
- {
- const gchar *pt_ns = wocky_node_get_ns (node);
- WockyJingleRtpHeaderExtension *hdrext;
-
- if (wocky_strdiff (pt_ns, NS_JINGLE_RTP_HDREXT))
- continue;
-
- hdrext = parse_rtp_header_extension (node);
-
- if (hdrext == NULL)
- {
- description_error = TRUE;
- }
- else
- {
- md->hdrexts = g_list_append (md->hdrexts, hdrext);
- priv->has_rtp_hdrext = TRUE;
- }
-
- }
- else if (!wocky_strdiff (node->name, "rtcp-fb"))
- {
- WockyJingleFeedbackMessage *fb = parse_rtcp_fb (content, node);
-
- if (fb == NULL)
- {
- description_error = TRUE;
- }
- else
- {
- md->feedback_msgs = g_list_append (md->feedback_msgs, fb);
- is_avpf = TRUE;
- priv->has_rtcp_fb = TRUE;
- }
- }
- else if (!wocky_strdiff (node->name, "rtcp-fb-trr-int"))
- {
- guint trr_int = parse_rtcp_fb_trr_int (content, node);
-
- if (trr_int == G_MAXUINT)
- {
- description_error = TRUE;
- }
- else
- {
- md->trr_int = trr_int;
- is_avpf = TRUE;
- priv->has_rtcp_fb = TRUE;
- }
- }
- }
-
- if (description_error)
- {
- /* rollback these */
- wocky_jingle_media_description_free (md);
- g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST,
- "invalid description");
- return;
- }
-
- /* If the profile is AVPF, the trr-int default to 0 */
- if (is_avpf && md->trr_int == G_MAXUINT)
- md->trr_int = 0;
-
- priv->media_type = mtype;
-
- update_remote_media_description (self, md, error);
-}
-
-/* The Google Talk desktop client is picky about the case of codec names, even
- * though SDP defines them to be case-insensitive. The particular case that was
- * causing problems was ILBC vs iLBC, but it seems safer to special-case the
- * lot. This list is taken from the initiate sent by the desktop client on
- * 2009-07-01.
- */
-static const gchar * const codec_cases[] = {
- "CN",
- "EG711A",
- "EG711U",
- "G723",
- "IPCMWB",
- "ISAC",
- "PCMA",
- "PCMU",
- "iLBC",
- "speex",
- "telephone-event",
- NULL
-};
-
-static const gchar *
-gtalk_case (const gchar *codec)
-{
- const gchar * const *ret = codec_cases;
-
- for (; *ret != NULL; ret++)
- if (g_ascii_strcasecmp (*ret, codec) == 0)
- return *ret;
-
- return codec;
-}
-
-static void
-_produce_extra_param (gpointer key, gpointer value, gpointer user_data)
-{
- WockyNode *pt_node = user_data;
- WockyNode *param;
- gchar *param_name = key;
- gchar *param_value = value;
-
- param = wocky_node_add_child (pt_node, "parameter");
- wocky_node_set_attribute (param, "name", param_name);
- wocky_node_set_attribute (param, "value", param_value);
-}
-
-static void
-produce_rtcp_fb_trr_int (WockyNode *node,
- guint trr_int)
-{
- WockyNode *trr_int_node;
- gchar tmp[10];
-
- if (trr_int == G_MAXUINT || trr_int == 0)
- return;
-
- trr_int_node = wocky_node_add_child_ns (node, "rtcp-fb-trr-int",
- NS_JINGLE_RTCP_FB);
- snprintf (tmp, 9, "%d", trr_int);
- wocky_node_set_attribute (trr_int_node, "value", tmp);
-}
-
-
-static void
-produce_rtcp_fb (WockyJingleFeedbackMessage *fb, WockyNode *node)
-{
- WockyNode *fb_node;
-
- fb_node = wocky_node_add_child (node, "rtcp-fb");
-
- wocky_node_set_attribute (fb_node, "xmlns", NS_JINGLE_RTCP_FB);
- wocky_node_set_attribute (fb_node, "type", fb->type);
-
- if (fb->subtype != NULL && fb->subtype[0] != 0)
- wocky_node_set_attribute (fb_node, "subtype", fb->subtype);
-}
-
-static void
-produce_payload_type (WockyJingleContent *content,
- WockyNode *desc_node,
- WockyJingleMediaType type,
- WockyJingleCodec *p,
- WockyJingleDialect dialect)
-{
- WockyJingleMediaRtp *self = WOCKY_JINGLE_MEDIA_RTP (content);
- WockyJingleMediaRtpPrivate *priv = self->priv;
- WockyNode *pt_node;
- gchar buf[16];
-
- pt_node = wocky_node_add_child (desc_node, "payload-type");
-
- /* id: required */
- sprintf (buf, "%d", p->id);
- wocky_node_set_attribute (pt_node, "id", buf);
-
- if (dialect == WOCKY_JINGLE_DIALECT_GTALK3)
- {
- if (type == WOCKY_JINGLE_MEDIA_TYPE_AUDIO)
- {
- /* Gtalk 03 has either an audio or a video session, in case of a
- * video session the audio codecs need to set their namespace to
- * NS_GOOGLE_SESSION_PHONE. In the case of an audio session it
- * doesn't matter, so just always set the namespace on audio
- * payloads.
- */
- pt_node->ns = g_quark_from_static_string (
- NS_GOOGLE_SESSION_PHONE);
- }
- else
- {
- /* If width, height and framerate aren't set the google server ignore
- * our initiate.. These are a recv parameters, to it doesn't matter
- * for what we're sending, just for what we're getting.. 320x240
- * seems a sane enough default */
- wocky_node_set_attributes (pt_node,
- "width", "320",
- "height", "240",
- "framerate", "30",
- NULL);
- }
-
- }
-
- /* name: optional */
- if (*p->name != '\0')
- {
- if (WOCKY_JINGLE_DIALECT_IS_GOOGLE (dialect))
- wocky_node_set_attribute (pt_node, "name", gtalk_case (p->name));
- else
- wocky_node_set_attribute (pt_node, "name", p->name);
- }
-
- /* clock rate: optional */
- if (p->clockrate != 0)
- {
- const gchar *attname = "clockrate";
-
- if (dialect == WOCKY_JINGLE_DIALECT_V015)
- attname = "rate";
-
- sprintf (buf, "%u", p->clockrate);
- wocky_node_set_attribute (pt_node, attname, buf);
- }
-
- if (p->channels != 0)
- {
- sprintf (buf, "%u", p->channels);
- wocky_node_set_attribute (pt_node, "channels", buf);
- }
-
- if (p->params != NULL)
- g_hash_table_foreach (p->params, _produce_extra_param, pt_node);
-
-
- if (priv->has_rtcp_fb)
- {
- g_list_foreach (p->feedback_msgs, (GFunc) produce_rtcp_fb, pt_node);
- produce_rtcp_fb_trr_int (pt_node, p->trr_int);
- }
-}
-
-static WockyNode *
-produce_description_node (WockyJingleDialect dialect, WockyJingleMediaType media_type,
- WockyNode *content_node)
-{
- WockyNode *desc_node;
- const gchar *xmlns = NULL, *media_attr = NULL;
-
- if (dialect == WOCKY_JINGLE_DIALECT_GTALK3)
- return NULL;
-
- switch (dialect)
- {
- case WOCKY_JINGLE_DIALECT_GTALK4:
- g_assert (media_type == WOCKY_JINGLE_MEDIA_TYPE_AUDIO);
- xmlns = NS_GOOGLE_SESSION_PHONE;
- break;
- case WOCKY_JINGLE_DIALECT_V015:
- if (media_type == WOCKY_JINGLE_MEDIA_TYPE_AUDIO)
- xmlns = NS_JINGLE_DESCRIPTION_AUDIO;
- else if (media_type == WOCKY_JINGLE_MEDIA_TYPE_VIDEO)
- xmlns = NS_JINGLE_DESCRIPTION_VIDEO;
- else
- {
- DEBUG ("unknown media type %u", media_type);
- xmlns = "";
- }
- break;
- default:
- xmlns = NS_JINGLE_RTP;
- if (media_type == WOCKY_JINGLE_MEDIA_TYPE_AUDIO)
- media_attr = "audio";
- else if (media_type == WOCKY_JINGLE_MEDIA_TYPE_VIDEO)
- media_attr = "video";
- else
- g_assert_not_reached ();
- break;
- }
-
- desc_node = wocky_node_add_child_ns (content_node, "description", xmlns);
-
- if (media_attr != NULL)
- wocky_node_set_attribute (desc_node, "media", media_attr);
-
- return desc_node;
-}
-
-static void
-produce_hdrext (gpointer data, gpointer user_data)
-{
- WockyJingleRtpHeaderExtension *hdrext = data;
- WockyNode *desc_node = user_data;
- WockyNode *hdrext_node;
- gchar buf[16];
-
- hdrext_node = wocky_node_add_child (desc_node, "rtp-hdrext");
-
- /* id: required */
- sprintf (buf, "%d", hdrext->id);
- wocky_node_set_attribute (hdrext_node, "id", buf);
- wocky_node_set_attribute (hdrext_node, "uri", hdrext->uri);
-
- if (hdrext->senders == WOCKY_JINGLE_CONTENT_SENDERS_INITIATOR)
- wocky_node_set_attribute (hdrext_node, "senders", "initiator");
- else if (hdrext->senders == WOCKY_JINGLE_CONTENT_SENDERS_RESPONDER)
- wocky_node_set_attribute (hdrext_node, "senders", "responder");
-
- wocky_node_set_attribute (hdrext_node, "xmlns", NS_JINGLE_RTP_HDREXT);
-}
-
-static void
-produce_description (WockyJingleContent *content, WockyNode *content_node)
-{
- WockyJingleMediaRtp *self = WOCKY_JINGLE_MEDIA_RTP (content);
- WockyJingleMediaRtpPrivate *priv = self->priv;
- GList *li;
- WockyJingleDialect dialect = wocky_jingle_session_get_dialect (content->session);
- WockyNode *desc_node;
-
- if (wocky_jingle_session_peer_has_cap (content->session, NS_JINGLE_RTCP_FB))
- priv->has_rtcp_fb = TRUE;
-
- if (wocky_jingle_session_peer_has_cap (content->session, NS_JINGLE_RTP_HDREXT))
- priv->has_rtp_hdrext = TRUE;
-
- desc_node = produce_description_node (dialect, priv->media_type,
- content_node);
-
- /* For GTalk3 the description is added by the session */
- if (desc_node == NULL)
- desc_node = content_node;
-
- /* If we're only updating our codec parameters, only generate payload-types
- * for those.
- */
- if (priv->local_codec_updates != NULL)
- li = priv->local_codec_updates;
- else
- li = priv->local_media_description->codecs;
-
- for (; li != NULL; li = li->next)
- produce_payload_type (content, desc_node, priv->media_type, li->data,
- dialect);
-
- if (priv->has_rtp_hdrext && priv->local_media_description->hdrexts)
- g_list_foreach (priv->local_media_description->hdrexts, produce_hdrext,
- desc_node);
-
- if (priv->has_rtcp_fb)
- {
- g_list_foreach (priv->local_media_description->feedback_msgs,
- (GFunc) produce_rtcp_fb, desc_node);
- produce_rtcp_fb_trr_int (desc_node,
- priv->local_media_description->trr_int);
- }
-}
-
-/**
- * string_string_maps_equal:
- *
- * Returns: TRUE iff @a and @b contain exactly the same keys and values when
- * compared as strings.
- */
-static gboolean
-string_string_maps_equal (GHashTable *a,
- GHashTable *b)
-{
- GHashTableIter iter;
- gpointer a_key, a_value, b_value;
-
- if (g_hash_table_size (a) != g_hash_table_size (b))
- return FALSE;
-
- g_hash_table_iter_init (&iter, a);
-
- while (g_hash_table_iter_next (&iter, &a_key, &a_value))
- {
- if (!g_hash_table_lookup_extended (b, a_key, NULL, &b_value))
- return FALSE;
-
- if (wocky_strdiff (a_value, b_value))
- return FALSE;
- }
-
- return TRUE;
-}
-
-/**
- * compare_codecs:
- * @old: previous local codecs
- * @new: new local codecs supplied by streaming implementation
- * @changed: location at which to store the changed codecs
- * @error: location at which to store an error if the update was invalid
- *
- * Returns: %TRUE if the update made sense, %FALSE with @error set otherwise
- */
-gboolean
-jingle_media_rtp_compare_codecs (GList *old,
- GList *new,
- GList **changed,
- GError **e)
-{
- gboolean ret = FALSE;
- GHashTable *old_table = build_codec_table (old);
- GList *l;
- WockyJingleCodec *old_c, *new_c;
-
- g_assert (changed != NULL && *changed == NULL);
-
- for (l = new; l != NULL; l = l->next)
- {
- new_c = l->data;
- old_c = g_hash_table_lookup (old_table, GUINT_TO_POINTER (
- (guint) new_c->id));
-
- if (!codec_update_coherent (old_c, new_c, e))
- goto out;
-
- if (!string_string_maps_equal (old_c->params, new_c->params))
- *changed = g_list_prepend (*changed, new_c);
- }
-
- ret = TRUE;
-
-out:
- if (!ret)
- {
- g_list_free (*changed);
- *changed = NULL;
- }
-
- g_hash_table_unref (old_table);
- return ret;
-}
-
-/*
- * @self: a content in an RTP session
- * @md: (transfer full): new media description for this content
- * @ready: whether the codecs can regarded as ready to sent from now on
- * @error: used to return a %WOCKY_XMPP_ERROR if the codec update is illegal.
- *
- * Sets or updates the media description (codecs, feedback messages, etc) for
- * @self.
- *
- * Returns: %TRUE if no description was previously set, or if the update is
- * compatible with the existing description; %FALSE if the update is illegal
- * (due to adding previously-unknown codecs or renaming an existing codec, for
- * example)
- */
-gboolean
-jingle_media_rtp_set_local_media_description (WockyJingleMediaRtp *self,
- WockyJingleMediaDescription *md,
- gboolean ready,
- GError **error)
-{
- WockyJingleMediaRtpPrivate *priv = self->priv;
-
- DEBUG ("setting new local media description");
-
- if (priv->local_media_description != NULL)
- {
- GList *changed = NULL;
- GError *err = NULL;
-
- g_assert (priv->local_codec_updates == NULL);
-
- if (!jingle_media_rtp_compare_codecs (
- priv->local_media_description->codecs,
- md->codecs, &changed, &err))
- {
- DEBUG ("codec update was illegal: %s", err->message);
- wocky_jingle_media_description_free (md);
- g_propagate_error (error, err);
- return FALSE;
- }
-
- if (changed == NULL)
- {
- DEBUG ("codec update changed nothing!");
- wocky_jingle_media_description_free (md);
- goto out;
- }
-
- DEBUG ("%u codecs changed", g_list_length (changed));
- priv->local_codec_updates = changed;
-
- wocky_jingle_media_description_free (priv->local_media_description);
- }
-
- priv->local_media_description = md;
-
- /* Codecs have changed, sending a fresh description might be necessary */
- wocky_jingle_content_maybe_send_description (WOCKY_JINGLE_CONTENT (self));
-
- /* Update done if any, free the changed codecs if any */
- g_list_free (priv->local_codec_updates);
- priv->local_codec_updates = NULL;
-
-out:
- if (ready)
- _wocky_jingle_content_set_media_ready (WOCKY_JINGLE_CONTENT (self));
-
- return TRUE;
-}
-
-void
-jingle_media_rtp_register (WockyJingleFactory *factory)
-{
- /* Current (v0.25) Jingle draft URI */
- wocky_jingle_factory_register_content_type (factory,
- NS_JINGLE_RTP, WOCKY_TYPE_JINGLE_MEDIA_RTP);
-
- /* Old Jingle audio/video namespaces */
- wocky_jingle_factory_register_content_type (factory,
- NS_JINGLE_DESCRIPTION_AUDIO,
- WOCKY_TYPE_JINGLE_MEDIA_RTP);
-
- wocky_jingle_factory_register_content_type (factory,
- NS_JINGLE_DESCRIPTION_VIDEO,
- WOCKY_TYPE_JINGLE_MEDIA_RTP);
-
- /* GTalk audio call namespace */
- wocky_jingle_factory_register_content_type (factory,
- NS_GOOGLE_SESSION_PHONE,
- WOCKY_TYPE_JINGLE_MEDIA_RTP);
-
- /* GTalk video call namespace */
- wocky_jingle_factory_register_content_type (factory,
- NS_GOOGLE_SESSION_VIDEO,
- WOCKY_TYPE_JINGLE_MEDIA_RTP);
-}
-
-/* We can't get remote media description when they're signalled, because
- * the signal is emitted immediately upon JingleContent creation,
- * and parsing, which is before a corresponding MediaStream is
- * created. */
-WockyJingleMediaDescription *
-wocky_jingle_media_rtp_get_remote_media_description (
- WockyJingleMediaRtp *self)
-{
- WockyJingleMediaRtpPrivate *priv = self->priv;
-
- return priv->remote_media_description;
-}
-
-WockyJingleMediaDescription *
-wocky_jingle_media_description_new (void)
-{
- WockyJingleMediaDescription *md = g_slice_new0 (WockyJingleMediaDescription);
-
- md->trr_int = G_MAXUINT;
-
- return md;
-}
-
-void
-wocky_jingle_media_description_free (WockyJingleMediaDescription *md)
-{
- jingle_media_rtp_free_codecs (md->codecs);
-
- while (md->hdrexts != NULL)
- {
- wocky_jingle_rtp_header_extension_free (md->hdrexts->data);
- md->hdrexts = g_list_delete_link (md->hdrexts, md->hdrexts);
- }
-
- g_slice_free (WockyJingleMediaDescription, md);
-}
-
-WockyJingleMediaDescription *
-wocky_jingle_media_description_copy (WockyJingleMediaDescription *md)
-{
- WockyJingleMediaDescription *newmd = g_slice_new0 (WockyJingleMediaDescription);
- GList *li;
-
- newmd->codecs = jingle_media_rtp_copy_codecs (md->codecs);
- newmd->feedback_msgs = wocky_jingle_feedback_message_list_copy (md->feedback_msgs);
- newmd->trr_int = md->trr_int;
-
- for (li = md->hdrexts; li; li = li->next)
- {
- WockyJingleRtpHeaderExtension *h = li->data;
-
- newmd->hdrexts = g_list_append (newmd->hdrexts,
- wocky_jingle_rtp_header_extension_new (h->id, h->senders, h->uri));
- }
-
- return newmd;
-}
-
-WockyJingleRtpHeaderExtension *
-wocky_jingle_rtp_header_extension_new (guint id, WockyJingleContentSenders senders,
- const gchar *uri)
-{
- WockyJingleRtpHeaderExtension *hdrext = g_slice_new (WockyJingleRtpHeaderExtension);
-
- hdrext->id = id;
- hdrext->senders = senders;
- hdrext->uri = g_strdup (uri);
-
- return hdrext;
-}
-
-void
-wocky_jingle_rtp_header_extension_free (WockyJingleRtpHeaderExtension *hdrext)
-{
- g_free (hdrext->uri);
- g_slice_free (WockyJingleRtpHeaderExtension, hdrext);
-}
-
-WockyJingleFeedbackMessage *
-wocky_jingle_feedback_message_new (const gchar *type, const gchar *subtype)
-{
- WockyJingleFeedbackMessage *fb = g_slice_new0 (WockyJingleFeedbackMessage);
-
- fb->type = g_strdup (type);
- fb->subtype = g_strdup (subtype);
-
- return fb;
-}
-
-void
-wocky_jingle_feedback_message_free (WockyJingleFeedbackMessage *fb)
-{
- g_free (fb->type);
- g_free (fb->subtype);
- g_slice_free (WockyJingleFeedbackMessage, fb);
-}
-
-
-static gint
-wocky_jingle_feedback_message_compare (const WockyJingleFeedbackMessage *fb1,
- const WockyJingleFeedbackMessage *fb2)
-{
- if (!g_ascii_strcasecmp (fb1->type, fb2->type) &&
- !g_ascii_strcasecmp (fb1->subtype, fb2->subtype))
- return 0;
- else
- return 1;
-}
-
-/**
- * wocky_jingle_media_description_simplify:
- *
- * Removes duplicated Feedback message and put them in the global structure
- *
- * This function will iterate over every codec in a description and look for
- * feedback messages that are exactly the same in every codec and will instead
- * put the in the list in the description and remove them from the childs.
- * This limits the amount of duplication in the resulting XML.
- */
-
-void
-wocky_jingle_media_description_simplify (WockyJingleMediaDescription *md)
-{
- GList *item;
- guint trr_int = 0;
- gboolean trr_int_all_same = TRUE;
- gboolean init = FALSE;
- GList *identical_fbs = NULL;
-
- for (item = md->codecs; item; item = item->next)
- {
- WockyJingleCodec *c = item->data;
-
- if (!init)
- {
- /* For the first codec, it stores the trr_int and the list
- * of feedback messages */
- trr_int = c->trr_int;
- identical_fbs = g_list_copy (c->feedback_msgs);
- init = TRUE;
- }
- else
- {
- GList *item2;
-
- /* For every subsequent codec, we check if the trr_int is the same */
-
- if (trr_int != c->trr_int)
- trr_int_all_same = FALSE;
-
- /* We also intersect the remembered list of feedback messages with
- * the list for that codec and remove any feedback message that isn't
- * in both
- */
-
- for (item2 = identical_fbs; item2;)
- {
- WockyJingleFeedbackMessage *fb = identical_fbs->data;
- GList *next = item2->next;
-
- if (!g_list_find_custom (c->feedback_msgs, fb,
- (GCompareFunc) wocky_jingle_feedback_message_compare))
- identical_fbs = g_list_delete_link (identical_fbs, item2);
-
- item2 = next;
- }
-
- /* If the trr_int is not the same everywhere and there are not common
- * feedback messages, then stop
- */
- if (!trr_int_all_same && identical_fbs == NULL)
- break;
- }
- }
-
- if (trr_int_all_same && trr_int == G_MAXUINT)
- trr_int_all_same = FALSE;
-
- /* if the trr_int is the same everywhere, lets set it globally */
- if (trr_int_all_same)
- md->trr_int = trr_int;
-
- /* If there are feedback messages that are in every codec, put a copy of them
- * in the global structure
- */
- if (identical_fbs)
- {
- md->feedback_msgs = wocky_jingle_feedback_message_list_copy (identical_fbs);
- g_list_free (identical_fbs);
- }
-
- if (trr_int_all_same || md->feedback_msgs != NULL)
- for (item = md->codecs; item; item = item->next)
- {
- WockyJingleCodec *c = item->data;
- GList *item2;
-
- /* If the trr_int is the same everywhere, lets put the default on
- * each codec, we have it in the main structure
- */
- if (trr_int_all_same)
- c->trr_int = G_MAXUINT;
-
- /* Find the feedback messages that were put in the main structure and
- * remove them from each codec
- */
- for (item2 = md->feedback_msgs; item2; item2 = item2->next)
- {
- GList *duplicated;
- WockyJingleFeedbackMessage *fb = item2->data;
-
- while ((duplicated = g_list_find_custom (c->feedback_msgs, fb,
- (GCompareFunc) wocky_jingle_feedback_message_compare)) != NULL)
- {
- wocky_jingle_feedback_message_free (duplicated->data);
- c->feedback_msgs = g_list_delete_link (c->feedback_msgs,
- duplicated);
- }
- }
- }
-}
diff --git a/src/jingle-media-rtp.h b/src/jingle-media-rtp.h
deleted file mode 100644
index 4854b790f..000000000
--- a/src/jingle-media-rtp.h
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * jingle-media-rtp.h - Header for WockyJingleMediaRtp
- * Copyright (C) 2008 Collabora Ltd.
- *
- * 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 __JINGLE_MEDIA_RTP_H__
-#define __JINGLE_MEDIA_RTP_H__
-
-#include <glib-object.h>
-
-#include "jingle-content.h"
-#include "jingle-types.h"
-
-G_BEGIN_DECLS
-
-typedef struct _WockyJingleMediaRtpClass WockyJingleMediaRtpClass;
-
-GType wocky_jingle_media_rtp_get_type (void);
-
-/* TYPE MACROS */
-#define WOCKY_TYPE_JINGLE_MEDIA_RTP \
- (wocky_jingle_media_rtp_get_type ())
-#define WOCKY_JINGLE_MEDIA_RTP(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), WOCKY_TYPE_JINGLE_MEDIA_RTP, \
- WockyJingleMediaRtp))
-#define WOCKY_JINGLE_MEDIA_RTP_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), WOCKY_TYPE_JINGLE_MEDIA_RTP, \
- WockyJingleMediaRtpClass))
-#define WOCKY_IS_JINGLE_MEDIA_RTP(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), WOCKY_TYPE_JINGLE_MEDIA_RTP))
-#define WOCKY_IS_JINGLE_MEDIA_RTP_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), WOCKY_TYPE_JINGLE_MEDIA_RTP))
-#define WOCKY_JINGLE_MEDIA_RTP_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), WOCKY_TYPE_JINGLE_MEDIA_RTP, \
- WockyJingleMediaRtpClass))
-
-struct _WockyJingleMediaRtpClass {
- WockyJingleContentClass parent_class;
-};
-
-typedef struct _WockyJingleMediaRtpPrivate WockyJingleMediaRtpPrivate;
-
-struct _WockyJingleMediaRtp {
- WockyJingleContent parent;
- WockyJingleMediaRtpPrivate *priv;
-};
-
-typedef struct {
- guint id;
- gchar *name;
- guint clockrate;
- guint channels;
- GHashTable *params;
- guint trr_int;
- GList *feedback_msgs;
-} WockyJingleCodec;
-
-typedef struct {
- gchar *type;
- gchar *subtype;
-} WockyJingleFeedbackMessage;
-
-typedef struct {
- guint id;
- WockyJingleContentSenders senders;
- gchar *uri;
-} WockyJingleRtpHeaderExtension;
-
-typedef struct {
- GList *codecs;
- GList *hdrexts;
- guint trr_int;
- GList *feedback_msgs;
-} WockyJingleMediaDescription;
-
-void jingle_media_rtp_register (WockyJingleFactory *factory);
-gboolean jingle_media_rtp_set_local_media_description (
- WockyJingleMediaRtp *self, WockyJingleMediaDescription *md, gboolean ready,
- GError **error);
-WockyJingleMediaDescription *wocky_jingle_media_rtp_get_remote_media_description (
- WockyJingleMediaRtp *self);
-
-WockyJingleCodec * jingle_media_rtp_codec_new (guint id, const gchar *name,
- guint clockrate, guint channels, GHashTable *params);
-void jingle_media_rtp_codec_free (WockyJingleCodec *p);
-void jingle_media_rtp_free_codecs (GList *codecs);
-GList * jingle_media_rtp_copy_codecs (GList *codecs);
-
-gboolean jingle_media_rtp_compare_codecs (GList *old,
- GList *new,
- GList **changed,
- GError **e);
-
-WockyJingleMediaDescription *wocky_jingle_media_description_new (void);
-void wocky_jingle_media_description_free (WockyJingleMediaDescription *md);
-WockyJingleMediaDescription *wocky_jingle_media_description_copy (
- WockyJingleMediaDescription *md);
-
-WockyJingleRtpHeaderExtension *wocky_jingle_rtp_header_extension_new (guint id,
- WockyJingleContentSenders senders, const gchar *uri);
-void wocky_jingle_rtp_header_extension_free (WockyJingleRtpHeaderExtension *hdrext);
-
-
-WockyJingleFeedbackMessage *wocky_jingle_feedback_message_new (const gchar *type,
- const gchar *subtype);
-void wocky_jingle_feedback_message_free (WockyJingleFeedbackMessage *fb);
-void wocky_jingle_media_description_simplify (WockyJingleMediaDescription *md);
-
-#endif /* __JINGLE_MEDIA_RTP_H__ */
-
diff --git a/src/jingle-mint.c b/src/jingle-mint.c
index b45992efc..2362cdec0 100644
--- a/src/jingle-mint.c
+++ b/src/jingle-mint.c
@@ -34,6 +34,7 @@
#include "conn-presence.h"
#include "jingle-factory.h"
#include "jingle-session.h"
+#include "jingle-share.h"
#include "presence-cache.h"
struct _GabbleJingleMintPrivate {
@@ -260,6 +261,8 @@ connection_porter_available_cb (
g_assert (priv->factory == NULL);
priv->factory = wocky_jingle_factory_new (conn->session);
+ jingle_share_register (priv->factory);
+
tp_g_signal_connect_object (priv->factory, "new-session",
(GCallback) factory_new_session_cb, self, 0);
tp_g_signal_connect_object (priv->factory, "query-cap",
diff --git a/src/jingle-session.c b/src/jingle-session.c
deleted file mode 100644
index e8fea568a..000000000
--- a/src/jingle-session.c
+++ /dev/null
@@ -1,2447 +0,0 @@
-/*
- * gabble-jingle-session.c - Source for WockyJingleSession
- * Copyright (C) 2008 Collabora Ltd.
- *
- * 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 "jingle-session.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-
-#include <wocky/wocky.h>
-
-#define DEBUG_FLAG GABBLE_DEBUG_MEDIA
-
-#include "gabble/capabilities.h"
-#include "debug.h"
-#include "gabble-signals-marshal.h"
-#include "gabble-enumtypes.h"
-#include "jingle-content.h"
-#include "jingle-factory.h"
-/* FIXME: the RTP-specific bits of this file should be separated from the
- * generic Jingle code.
- */
-#include "jingle-media-rtp.h"
-#include "namespaces.h"
-
-G_DEFINE_TYPE(WockyJingleSession, wocky_jingle_session, G_TYPE_OBJECT);
-
-/* signal enum */
-enum
-{
- NEW_CONTENT,
- REMOTE_STATE_CHANGED,
- TERMINATED,
- CONTENT_REJECTED,
- QUERY_CAP,
- ABOUT_TO_INITIATE,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = {0};
-
-/* properties */
-enum
-{
- PROP_JINGLE_FACTORY = 1,
- PROP_PORTER,
- PROP_SESSION_ID,
- PROP_PEER_CONTACT,
- PROP_LOCAL_INITIATOR,
- PROP_STATE,
- PROP_DIALECT,
- PROP_LOCAL_HOLD,
- PROP_REMOTE_HOLD,
- PROP_REMOTE_RINGING,
- LAST_PROPERTY
-};
-
-struct _WockyJingleSessionPrivate
-{
- /* Borrowed; the factory owns us. */
- WockyJingleFactory *jingle_factory;
- WockyPorter *porter;
-
- WockyContact *peer_contact;
- /* Borrowed from peer_contact if it's a WockyResourceContact. */
- const gchar *peer_resource;
- gchar *peer_jid;
- /* Either borrowed from 'porter' or equal to peer_jid. */
- const gchar *initiator;
- gboolean local_initiator;
-
- /* WockyJingleContent objects keyed by content name.
- * Table owns references to these objects. */
- GHashTable *initiator_contents;
- GHashTable *responder_contents;
-
- WockyJingleDialect dialect;
- WockyJingleState state;
- gchar *sid;
-
- gboolean locally_accepted;
- gboolean locally_terminated;
-
- gboolean local_hold;
-
- gboolean remote_hold;
- gboolean remote_ringing;
-
- gboolean dispose_has_run;
-};
-
-typedef struct {
- WockyJingleState state;
- WockyJingleAction *actions;
-} WockyJingleStateActions;
-
-/* gcc should be able to figure this out from the table below, but.. */
-#define MAX_ACTIONS_PER_STATE 12
-
-/* NB: WOCKY_JINGLE_ACTION_UNKNOWN is used as a terminator here. */
-static WockyJingleAction allowed_actions[WOCKY_N_JINGLE_STATES][MAX_ACTIONS_PER_STATE] = {
- /* WOCKY_JINGLE_STATE_PENDING_CREATED */
- { WOCKY_JINGLE_ACTION_SESSION_INITIATE, WOCKY_JINGLE_ACTION_UNKNOWN },
- /* WOCKY_JINGLE_STATE_PENDING_INITIATE_SENT */
- { WOCKY_JINGLE_ACTION_SESSION_TERMINATE, WOCKY_JINGLE_ACTION_SESSION_ACCEPT,
- WOCKY_JINGLE_ACTION_TRANSPORT_ACCEPT, /* required for GTalk4 */
- WOCKY_JINGLE_ACTION_DESCRIPTION_INFO, WOCKY_JINGLE_ACTION_SESSION_INFO,
- WOCKY_JINGLE_ACTION_TRANSPORT_INFO, WOCKY_JINGLE_ACTION_INFO,
- WOCKY_JINGLE_ACTION_UNKNOWN },
- /* WOCKY_JINGLE_STATE_PENDING_INITIATED */
- { WOCKY_JINGLE_ACTION_SESSION_ACCEPT, WOCKY_JINGLE_ACTION_SESSION_TERMINATE,
- WOCKY_JINGLE_ACTION_TRANSPORT_INFO, WOCKY_JINGLE_ACTION_CONTENT_REJECT,
- WOCKY_JINGLE_ACTION_CONTENT_MODIFY, WOCKY_JINGLE_ACTION_CONTENT_ACCEPT,
- WOCKY_JINGLE_ACTION_CONTENT_REMOVE, WOCKY_JINGLE_ACTION_DESCRIPTION_INFO,
- WOCKY_JINGLE_ACTION_TRANSPORT_ACCEPT, WOCKY_JINGLE_ACTION_SESSION_INFO,
- WOCKY_JINGLE_ACTION_INFO,
- WOCKY_JINGLE_ACTION_UNKNOWN },
- /* WOCKY_JINGLE_STATE_PENDING_ACCEPT_SENT */
- { WOCKY_JINGLE_ACTION_TRANSPORT_INFO, WOCKY_JINGLE_ACTION_DESCRIPTION_INFO,
- WOCKY_JINGLE_ACTION_SESSION_TERMINATE, WOCKY_JINGLE_ACTION_SESSION_INFO,
- WOCKY_JINGLE_ACTION_INFO,
- WOCKY_JINGLE_ACTION_UNKNOWN },
- /* WOCKY_JINGLE_STATE_ACTIVE */
- { WOCKY_JINGLE_ACTION_CONTENT_MODIFY, WOCKY_JINGLE_ACTION_CONTENT_ADD,
- WOCKY_JINGLE_ACTION_CONTENT_REMOVE, WOCKY_JINGLE_ACTION_CONTENT_REPLACE,
- WOCKY_JINGLE_ACTION_CONTENT_ACCEPT, WOCKY_JINGLE_ACTION_CONTENT_REJECT,
- WOCKY_JINGLE_ACTION_SESSION_INFO, WOCKY_JINGLE_ACTION_TRANSPORT_INFO,
- WOCKY_JINGLE_ACTION_DESCRIPTION_INFO, WOCKY_JINGLE_ACTION_INFO,
- WOCKY_JINGLE_ACTION_SESSION_TERMINATE, WOCKY_JINGLE_ACTION_UNKNOWN },
- /* WOCKY_JINGLE_STATE_ENDED */
- { WOCKY_JINGLE_ACTION_UNKNOWN }
-};
-
-gboolean
-wocky_jingle_session_defines_action (WockyJingleSession *sess,
- WockyJingleAction a)
-{
- WockyJingleDialect d = sess->priv->dialect;
-
- if (a == WOCKY_JINGLE_ACTION_UNKNOWN)
- return FALSE;
-
- switch (d)
- {
- case WOCKY_JINGLE_DIALECT_V032:
- return TRUE;
- case WOCKY_JINGLE_DIALECT_V015:
- return (a != WOCKY_JINGLE_ACTION_DESCRIPTION_INFO &&
- a != WOCKY_JINGLE_ACTION_SESSION_INFO);
- case WOCKY_JINGLE_DIALECT_GTALK4:
- if (a == WOCKY_JINGLE_ACTION_TRANSPORT_ACCEPT ||
- a == WOCKY_JINGLE_ACTION_INFO )
- return TRUE;
- case WOCKY_JINGLE_DIALECT_GTALK3:
- return (a == WOCKY_JINGLE_ACTION_SESSION_ACCEPT ||
- a == WOCKY_JINGLE_ACTION_SESSION_INITIATE ||
- a == WOCKY_JINGLE_ACTION_SESSION_TERMINATE ||
- a == WOCKY_JINGLE_ACTION_TRANSPORT_INFO ||
- a == WOCKY_JINGLE_ACTION_INFO);
- default:
- return FALSE;
- }
-}
-
-static void wocky_jingle_session_send_held (WockyJingleSession *sess);
-static void content_ready_cb (WockyJingleContent *c, gpointer user_data);
-static void content_removed_cb (WockyJingleContent *c, gpointer user_data);
-
-static void
-wocky_jingle_session_init (WockyJingleSession *obj)
-{
- WockyJingleSessionPrivate *priv =
- G_TYPE_INSTANCE_GET_PRIVATE (obj, WOCKY_TYPE_JINGLE_SESSION,
- WockyJingleSessionPrivate);
- obj->priv = priv;
-
- DEBUG ("Initializing the jingle session %p", obj);
-
- priv->initiator_contents = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, g_object_unref);
- priv->responder_contents = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, g_object_unref);
-
- priv->state = WOCKY_JINGLE_STATE_PENDING_CREATED;
- priv->locally_accepted = FALSE;
- priv->locally_terminated = FALSE;
- priv->dispose_has_run = FALSE;
-}
-
-static void
-dispose_content_hash (
- WockyJingleSession *sess,
- GHashTable **contents)
-{
- GHashTableIter iter;
- gpointer content;
-
- g_hash_table_iter_init (&iter, *contents);
- while (g_hash_table_iter_next (&iter, NULL, &content))
- {
- g_signal_handlers_disconnect_by_func (content, content_ready_cb, sess);
- g_signal_handlers_disconnect_by_func (content, content_removed_cb, sess);
- g_hash_table_iter_remove (&iter);
- }
-
- g_hash_table_unref (*contents);
- *contents = NULL;
-}
-
-static void
-wocky_jingle_session_dispose (GObject *object)
-{
- WockyJingleSession *sess = WOCKY_JINGLE_SESSION (object);
- WockyJingleSessionPrivate *priv = sess->priv;
-
- if (priv->dispose_has_run)
- return;
-
- DEBUG ("called");
- priv->dispose_has_run = TRUE;
-
- g_assert ((priv->state == WOCKY_JINGLE_STATE_PENDING_CREATED) ||
- (priv->state == WOCKY_JINGLE_STATE_ENDED));
-
- dispose_content_hash (sess, &priv->initiator_contents);
- dispose_content_hash (sess, &priv->responder_contents);
-
- g_clear_object (&priv->peer_contact);
- g_clear_object (&priv->porter);
-
- g_free (priv->sid);
- priv->sid = NULL;
-
- g_free (priv->peer_jid);
- priv->peer_jid = NULL;
-
- if (G_OBJECT_CLASS (wocky_jingle_session_parent_class)->dispose)
- G_OBJECT_CLASS (wocky_jingle_session_parent_class)->dispose (object);
-}
-
-static void
-wocky_jingle_session_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- WockyJingleSession *sess = WOCKY_JINGLE_SESSION (object);
- WockyJingleSessionPrivate *priv = sess->priv;
-
- switch (property_id) {
- case PROP_JINGLE_FACTORY:
- g_value_set_object (value, priv->jingle_factory);
- break;
- case PROP_PORTER:
- g_value_set_object (value, priv->porter);
- break;
- case PROP_SESSION_ID:
- g_value_set_string (value, priv->sid);
- break;
- case PROP_LOCAL_INITIATOR:
- g_value_set_boolean (value, priv->local_initiator);
- break;
- case PROP_PEER_CONTACT:
- g_value_set_object (value, priv->peer_contact);
- break;
- case PROP_STATE:
- g_value_set_uint (value, priv->state);
- break;
- case PROP_DIALECT:
- g_value_set_uint (value, priv->dialect);
- break;
- case PROP_LOCAL_HOLD:
- g_value_set_boolean (value, priv->local_hold);
- break;
- case PROP_REMOTE_HOLD:
- g_value_set_boolean (value, priv->remote_hold);
- break;
- case PROP_REMOTE_RINGING:
- g_value_set_boolean (value, priv->remote_ringing);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-wocky_jingle_session_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- WockyJingleSession *sess = WOCKY_JINGLE_SESSION (object);
- WockyJingleSessionPrivate *priv = sess->priv;
-
- switch (property_id) {
- case PROP_JINGLE_FACTORY:
- priv->jingle_factory = g_value_get_object (value);
- g_assert (priv->jingle_factory != NULL);
- break;
- case PROP_PORTER:
- priv->porter = g_value_dup_object (value);
- g_assert (priv->porter != NULL);
- break;
- case PROP_SESSION_ID:
- g_free (priv->sid);
- priv->sid = g_value_dup_string (value);
- break;
- case PROP_LOCAL_INITIATOR:
- priv->local_initiator = g_value_get_boolean (value);
- break;
- case PROP_DIALECT:
- priv->dialect = g_value_get_uint (value);
- break;
- case PROP_PEER_CONTACT:
- priv->peer_contact = g_value_dup_object (value);
- break;
- case PROP_LOCAL_HOLD:
- {
- gboolean local_hold = g_value_get_boolean (value);
-
- if (priv->local_hold != local_hold)
- {
- priv->local_hold = local_hold;
-
- if (priv->state >= WOCKY_JINGLE_STATE_PENDING_INITIATED &&
- priv->state < WOCKY_JINGLE_STATE_ENDED)
- wocky_jingle_session_send_held (sess);
-
- /* else, we'll send this in set_state when we move to PENDING_INITIATED or
- * better.
- */
- }
- break;
- }
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- g_assert_not_reached ();
- break;
- }
-}
-
-static void
-wocky_jingle_session_constructed (GObject *object)
-{
- void (*chain_up) (GObject *) =
- G_OBJECT_CLASS (wocky_jingle_session_parent_class)->constructed;
- WockyJingleSession *self = WOCKY_JINGLE_SESSION (object);
- WockyJingleSessionPrivate *priv = self->priv;
-
- if (chain_up != NULL)
- chain_up (object);
-
- g_assert (priv->jingle_factory != NULL);
- g_assert (priv->porter != NULL);
- g_assert (priv->peer_contact != NULL);
- g_assert (priv->sid != NULL);
-
- priv->peer_jid = wocky_contact_dup_jid (priv->peer_contact);
-
- if (priv->local_initiator)
- priv->initiator = wocky_porter_get_full_jid (priv->porter);
- else
- priv->initiator = priv->peer_jid;
-
- if (WOCKY_IS_RESOURCE_CONTACT (priv->peer_contact))
- priv->peer_resource = wocky_resource_contact_get_resource (
- WOCKY_RESOURCE_CONTACT (priv->peer_contact));
-}
-
-WockyJingleSession *
-wocky_jingle_session_new (
- WockyJingleFactory *factory,
- WockyPorter *porter,
- const gchar *session_id,
- gboolean local_initiator,
- WockyContact *peer,
- WockyJingleDialect dialect,
- gboolean local_hold)
-{
- return g_object_new (WOCKY_TYPE_JINGLE_SESSION,
- "session-id", session_id,
- "jingle-factory", factory,
- "porter", porter,
- "local-initiator", local_initiator,
- "peer-contact", peer,
- "dialect", dialect,
- "local-hold", local_hold,
- NULL);
-}
-
-static void
-wocky_jingle_session_class_init (WockyJingleSessionClass *cls)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (cls);
- GParamSpec *param_spec;
-
- g_type_class_add_private (cls, sizeof (WockyJingleSessionPrivate));
-
- object_class->constructed = wocky_jingle_session_constructed;
- object_class->get_property = wocky_jingle_session_get_property;
- object_class->set_property = wocky_jingle_session_set_property;
- object_class->dispose = wocky_jingle_session_dispose;
-
- /* property definitions */
- param_spec = g_param_spec_object ("jingle-factory",
- "WockyJingleFactory object",
- "The Jingle factory which created this session",
- WOCKY_TYPE_JINGLE_FACTORY,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_JINGLE_FACTORY, param_spec);
-
- param_spec = g_param_spec_object ("porter", "WockyPorter",
- "The WockyPorter for the current connection",
- WOCKY_TYPE_PORTER,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_PORTER, param_spec);
-
- param_spec = g_param_spec_string ("session-id", "Session ID",
- "A unique session identifier used throughout all communication.",
- NULL,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_SESSION_ID, param_spec);
-
- param_spec = g_param_spec_boolean ("local-initiator", "Session initiator",
- "Specifies if local end initiated the session.",
- TRUE,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_LOCAL_INITIATOR,
- param_spec);
-
- /**
- * WockyJingleSession:peer-contact:
- *
- * The #WockyContact representing the other party in the session. Note that
- * if this is a #WockyBareContact (as opposed to a #WockyResourceContact) the
- * session is with the contact's bare JID.
- */
- param_spec = g_param_spec_object ("peer-contact", "Session peer",
- "The WockyContact representing the other party in the session.",
- WOCKY_TYPE_CONTACT,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_PEER_CONTACT, param_spec);
-
- param_spec = g_param_spec_uint ("state", "Session state",
- "The current state that the session is in.",
- 0, G_MAXUINT32, WOCKY_JINGLE_STATE_PENDING_CREATED,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_STATE, param_spec);
-
- param_spec = g_param_spec_uint ("dialect", "Jingle dialect",
- "Jingle dialect used for this session.",
- 0, G_MAXUINT32, WOCKY_JINGLE_DIALECT_ERROR,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_DIALECT, param_spec);
-
- param_spec = g_param_spec_boolean ("local-hold", "Local hold",
- "TRUE if we've placed the peer on hold", FALSE,
- G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_LOCAL_HOLD, param_spec);
-
- param_spec = g_param_spec_boolean ("remote-hold", "Remote hold",
- "TRUE if the peer has placed us on hold", FALSE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_REMOTE_HOLD, param_spec);
-
- param_spec = g_param_spec_boolean ("remote-ringing", "Remote ringing",
- "TRUE if the peer's client is ringing", FALSE,
- G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
- g_object_class_install_property (object_class, PROP_REMOTE_RINGING,
- param_spec);
-
- /* signal definitions */
-
- signals[NEW_CONTENT] = g_signal_new ("new-content",
- G_TYPE_FROM_CLASS (cls), G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, g_cclosure_marshal_VOID__OBJECT,
- G_TYPE_NONE, 1, G_TYPE_OBJECT);
-
- signals[TERMINATED] = g_signal_new ("terminated",
- G_TYPE_FROM_CLASS (cls), G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, gabble_marshal_VOID__BOOLEAN_UINT_STRING,
- G_TYPE_NONE, 3, G_TYPE_BOOLEAN, G_TYPE_UINT, G_TYPE_STRING);
-
- signals[REMOTE_STATE_CHANGED] = g_signal_new ("remote-state-changed",
- G_TYPE_FROM_CLASS (cls), G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
- signals[CONTENT_REJECTED] = g_signal_new ("content-rejected",
- G_TYPE_FROM_CLASS (cls), G_SIGNAL_RUN_LAST,
- 0, NULL, NULL, gabble_marshal_VOID__OBJECT_UINT_STRING,
- G_TYPE_NONE, 3, G_TYPE_OBJECT, G_TYPE_UINT, G_TYPE_STRING);
-
- /*
- * @contact: this call's peer (the artist commonly known as
- * wocky_jingle_session_get_peer_contact())
- * @cap: the XEP-0115 feature string the session is interested in.
- *
- * Emitted when the session wants to check whether the peer has a particular
- * capability. The handler should return %TRUE if @contact has @cap.
- */
- signals[QUERY_CAP] = g_signal_new ("query-cap",
- G_TYPE_FROM_CLASS (cls), G_SIGNAL_RUN_LAST,
- 0, g_signal_accumulator_first_wins, NULL,
- gabble_marshal_BOOLEAN__OBJECT_STRING,
- G_TYPE_BOOLEAN, 2, WOCKY_TYPE_CONTACT, G_TYPE_STRING);
-
- signals[ABOUT_TO_INITIATE] = g_signal_new ("about-to-initiate",
- G_TYPE_FROM_CLASS (cls), G_SIGNAL_RUN_LAST,
- 0, NULL, NULL,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-}
-
-typedef void (*HandlerFunc)(WockyJingleSession *sess,
- WockyNode *node, GError **error);
-typedef void (*ContentHandlerFunc)(WockyJingleSession *sess,
- WockyJingleContent *c, WockyNode *content_node, gpointer user_data,
- GError **error);
-
-static gboolean
-extract_reason (WockyNode *node, WockyJingleReason *reason, gchar **message)
-{
- WockyJingleReason _reason = WOCKY_JINGLE_REASON_UNKNOWN;
- WockyNode *child;
- WockyNodeIter iter;
-
- g_return_val_if_fail (node != NULL, FALSE);
-
- if (message != NULL)
- *message = g_strdup (wocky_node_get_content_from_child (node, "text"));
-
- wocky_node_iter_init (&iter, node, NULL, NULL);
-
- while (wocky_node_iter_next (&iter, &child))
- {
- if (wocky_enum_from_nick (
- wocky_jingle_reason_get_type (), child->name, (gint *) &_reason))
- {
- if (reason != NULL)
- *reason = _reason;
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-static WockyJingleAction
-parse_action (const gchar *txt)
-{
- if (txt == NULL)
- return WOCKY_JINGLE_ACTION_UNKNOWN;
-
- /* synonyms, best deal with them right now */
- if (!wocky_strdiff (txt, "initiate") ||
- !wocky_strdiff (txt, "session-initiate"))
- return WOCKY_JINGLE_ACTION_SESSION_INITIATE;
- else if (!wocky_strdiff (txt, "terminate") ||
- !wocky_strdiff (txt, "session-terminate") ||
- !wocky_strdiff (txt, "reject"))
- return WOCKY_JINGLE_ACTION_SESSION_TERMINATE;
- else if (!wocky_strdiff (txt, "accept") ||
- !wocky_strdiff (txt, "session-accept"))
- return WOCKY_JINGLE_ACTION_SESSION_ACCEPT;
- else if (!wocky_strdiff (txt, "candidates") ||
- !wocky_strdiff (txt, "transport-info"))
- return WOCKY_JINGLE_ACTION_TRANSPORT_INFO;
- else if (!wocky_strdiff (txt, "content-accept"))
- return WOCKY_JINGLE_ACTION_CONTENT_ACCEPT;
- else if (!wocky_strdiff (txt, "content-add"))
- return WOCKY_JINGLE_ACTION_CONTENT_ADD;
- else if (!wocky_strdiff (txt, "content-modify"))
- return WOCKY_JINGLE_ACTION_CONTENT_MODIFY;
- else if (!wocky_strdiff (txt, "content-replace"))
- return WOCKY_JINGLE_ACTION_CONTENT_REPLACE;
- else if (!wocky_strdiff (txt, "content-reject"))
- return WOCKY_JINGLE_ACTION_CONTENT_REJECT;
- else if (!wocky_strdiff (txt, "content-remove"))
- return WOCKY_JINGLE_ACTION_CONTENT_REMOVE;
- else if (!wocky_strdiff (txt, "session-info"))
- return WOCKY_JINGLE_ACTION_SESSION_INFO;
- else if (!wocky_strdiff (txt, "transport-accept"))
- return WOCKY_JINGLE_ACTION_TRANSPORT_ACCEPT;
- else if (!wocky_strdiff (txt, "description-info"))
- return WOCKY_JINGLE_ACTION_DESCRIPTION_INFO;
- else if (!wocky_strdiff (txt, "info"))
- return WOCKY_JINGLE_ACTION_INFO;
-
- return WOCKY_JINGLE_ACTION_UNKNOWN;
-}
-
-static const gchar *
-produce_action (WockyJingleAction action, WockyJingleDialect dialect)
-{
- gboolean gmode = (dialect == WOCKY_JINGLE_DIALECT_GTALK3) ||
- (dialect == WOCKY_JINGLE_DIALECT_GTALK4);
-
- g_return_val_if_fail (action != WOCKY_JINGLE_ACTION_UNKNOWN, NULL);
-
- switch (action) {
- case WOCKY_JINGLE_ACTION_SESSION_INITIATE:
- return (gmode) ? "initiate" : "session-initiate";
- case WOCKY_JINGLE_ACTION_SESSION_TERMINATE:
- return (gmode) ? "terminate" : "session-terminate";
- case WOCKY_JINGLE_ACTION_SESSION_ACCEPT:
- return (gmode) ? "accept" : "session-accept";
- case WOCKY_JINGLE_ACTION_TRANSPORT_INFO:
- return (dialect == WOCKY_JINGLE_DIALECT_GTALK3) ?
- "candidates" : "transport-info";
- case WOCKY_JINGLE_ACTION_CONTENT_ACCEPT:
- return "content-accept";
- case WOCKY_JINGLE_ACTION_CONTENT_ADD:
- return "content-add";
- case WOCKY_JINGLE_ACTION_CONTENT_MODIFY:
- return "content-modify";
- case WOCKY_JINGLE_ACTION_CONTENT_REMOVE:
- return "content-remove";
- case WOCKY_JINGLE_ACTION_CONTENT_REPLACE:
- return "content-replace";
- case WOCKY_JINGLE_ACTION_CONTENT_REJECT:
- return "content-reject";
- case WOCKY_JINGLE_ACTION_SESSION_INFO:
- return "session-info";
- case WOCKY_JINGLE_ACTION_TRANSPORT_ACCEPT:
- return "transport-accept";
- case WOCKY_JINGLE_ACTION_DESCRIPTION_INFO:
- return "description-info";
- case WOCKY_JINGLE_ACTION_INFO:
- return "info";
- default:
- /* only reached if g_return_val_if_fail is disabled */
- DEBUG ("unknown action %u", action);
- return NULL;
- }
-}
-
-static gboolean
-action_is_allowed (WockyJingleAction action, WockyJingleState state)
-{
- guint i;
-
- for (i = 0; allowed_actions[state][i] != WOCKY_JINGLE_ACTION_UNKNOWN; i++)
- {
- if (allowed_actions[state][i] == action)
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void wocky_jingle_session_send_rtp_info (WockyJingleSession *sess,
- const gchar *name);
-static void set_state (WockyJingleSession *sess,
- WockyJingleState state, WockyJingleReason termination_reason, const gchar *text);
-static WockyJingleContent *_get_any_content (WockyJingleSession *session);
-
-gboolean
-wocky_jingle_session_peer_has_cap (
- WockyJingleSession *self,
- const gchar *cap_or_quirk)
-{
- WockyJingleSessionPrivate *priv = self->priv;
- gboolean ret;
-
- g_signal_emit (self, signals[QUERY_CAP], 0,
- priv->peer_contact, cap_or_quirk,
- &ret);
- return ret;
-}
-
-static gboolean
-lookup_content (WockyJingleSession *sess,
- const gchar *name,
- const gchar *creator,
- gboolean fail_if_missing,
- WockyJingleContent **c,
- GError **error)
-{
- WockyJingleSessionPrivate *priv = sess->priv;
-
- if (name == NULL)
- {
- g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST,
- "'name' attribute unset");
- return FALSE;
- }
-
- if (WOCKY_JINGLE_DIALECT_IS_GOOGLE (priv->dialect))
- {
- /* Only the initiator can create contents on GTalk. */
- *c = g_hash_table_lookup (priv->initiator_contents, name);
- }
- else
- {
- /* Versions of Gabble between 0.7.16 and 0.7.28 (inclusive) omitted the
- * 'creator' attribute from transport-info (and possibly other) stanzas.
- * We try to detect contacts using such a version of Gabble from their
- * caps; if 'creator' is missing and the peer has that caps flag, we look
- * up the content in both hashes.
- *
- * While this doesn't deal with the case where the content is found in
- * both hashes, this isn't a problem in practice: the versions of Gabble
- * we're working around didn't allow this to happen (they'd either reject
- * the second stream, or let it replace the first, depending on the phase
- * of the moon, and get kind of confused in the process), and we try to
- * pick globally-unique content names.
- */
- if (creator == NULL &&
- wocky_jingle_session_peer_has_cap (sess,
- QUIRK_OMITS_CONTENT_CREATORS))
- {
- DEBUG ("working around missing 'creator' attribute");
-
- *c = g_hash_table_lookup (priv->initiator_contents, name);
-
- if (*c == NULL)
- *c = g_hash_table_lookup (priv->responder_contents, name);
- }
- else if (!wocky_strdiff (creator, "initiator"))
- {
- *c = g_hash_table_lookup (priv->initiator_contents, name);
- }
- else if (!wocky_strdiff (creator, "responder"))
- {
- *c = g_hash_table_lookup (priv->responder_contents, name);
- }
- else
- {
- g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST,
- "'creator' attribute %s",
- (creator == NULL ? "missing" : "invalid"));
- return FALSE;
- }
- }
-
- if (fail_if_missing && *c == NULL)
- {
- g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST,
- "Content '%s' (created by %s) does not exist", name, creator);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-_foreach_content (WockyJingleSession *sess,
- WockyNode *node,
- gboolean fail_if_missing,
- ContentHandlerFunc func,
- gpointer user_data,
- GError **error)
-{
- WockyJingleContent *c;
- WockyNode *content_node;
- WockyNodeIter iter;
-
- wocky_node_iter_init (&iter, node, "content", NULL);
- while (wocky_node_iter_next (&iter, &content_node))
- {
- if (!lookup_content (sess,
- wocky_node_get_attribute (content_node, "name"),
- wocky_node_get_attribute (content_node, "creator"),
- fail_if_missing, &c, error))
- return;
-
- func (sess, c, content_node, user_data, error);
- if (*error != NULL)
- return;
- }
-}
-
-struct idle_content_reject_ctx {
- WockyJingleSession *session;
- WockyStanza *msg;
-};
-
-static gboolean
-idle_content_reject (gpointer data)
-{
- struct idle_content_reject_ctx *ctx = data;
-
- wocky_jingle_session_send (ctx->session, ctx->msg);
-
- g_object_unref (ctx->session);
- g_free (ctx);
-
- return FALSE;
-}
-
-static void
-fire_idle_content_reject (WockyJingleSession *sess, const gchar *name,
- const gchar *creator)
-{
- struct idle_content_reject_ctx *ctx = g_new0 (struct idle_content_reject_ctx, 1);
- WockyNode *sess_node, *node;
-
- if (creator == NULL)
- creator = "";
-
- ctx->session = g_object_ref (sess);
- ctx->msg = wocky_jingle_session_new_message (ctx->session,
- WOCKY_JINGLE_ACTION_CONTENT_REJECT, &sess_node);
-
- g_debug ("name = %s, initiator = %s", name, creator);
-
- node = wocky_node_add_child (sess_node, "content");
- wocky_node_set_attributes (node,
- "name", name, "creator", creator, NULL);
-
- /* FIXME: add API for ordering IQs rather than using g_idle_add. */
- g_idle_add (idle_content_reject, ctx);
-}
-
-static WockyJingleContent *
-create_content (WockyJingleSession *sess, GType content_type,
- WockyJingleMediaType type, WockyJingleContentSenders senders,
- const gchar *content_ns, const gchar *transport_ns,
- const gchar *name, WockyNode *content_node, GError **error)
-{
- WockyJingleSessionPrivate *priv = sess->priv;
- WockyJingleContent *c;
- GHashTable *contents;
-
- DEBUG ("session creating new content name %s, type %d", name, type);
-
- /* FIXME: media-type is introduced by GabbleJingleMediaRTP, not by the
- * superclass, so this call is unsafe in the general case */
- c = g_object_new (content_type,
- "session", sess,
- "content-ns", content_ns,
- "transport-ns", transport_ns,
- "media-type", type,
- "name", name,
- "disposition", "session",
- "senders", senders,
- NULL);
-
- g_signal_connect (c, "ready",
- (GCallback) content_ready_cb, sess);
- g_signal_connect (c, "removed",
- (GCallback) content_removed_cb, sess);
-
- /* if we are called by parser, parse content add */
- if (content_node != NULL)
- {
- wocky_jingle_content_parse_add (c, content_node,
- WOCKY_JINGLE_DIALECT_IS_GOOGLE (priv->dialect), error);
-
- if (*error != NULL)
- {
- g_object_unref (c);
- return NULL;
- }
-
- /* gtalk streams don't have name, so use whatever Content came up with */
- if (name == NULL)
- name = wocky_jingle_content_get_name (c);
- }
-
- if (priv->local_initiator == wocky_jingle_content_is_created_by_us (c))
- {
- DEBUG ("inserting content %s into initiator_contents", name);
- contents = priv->initiator_contents;
- }
- else
- {
- DEBUG ("inserting content %s into responder_contents", name);
- contents = priv->responder_contents;
- }
-
- /* If the content already existed, either we shouldn't have picked the name
- * we did (if we're creating it) or _each_content_add should have already
- * said no.
- */
- g_assert (g_hash_table_lookup (contents, name) == NULL);
- g_hash_table_insert (contents, g_strdup (name), c);
- g_signal_emit (sess, signals[NEW_CONTENT], 0, c);
- return c;
-}
-
-
-static void
-_each_content_add (WockyJingleSession *sess, WockyJingleContent *c,
- WockyNode *content_node, gpointer user_data, GError **error)
-{
- WockyJingleSessionPrivate *priv = sess->priv;
- const gchar *name = wocky_node_get_attribute (content_node, "name");
- WockyNode *desc_node = wocky_node_get_child (content_node,
- "description");
- GType content_type = 0;
- const gchar *content_ns = NULL;
-
- if (desc_node != NULL)
- {
- content_ns = wocky_node_get_ns (desc_node);
- DEBUG ("namespace: %s", content_ns);
- content_type = wocky_jingle_factory_lookup_content_type (
- wocky_jingle_session_get_factory (sess),
- content_ns);
- }
-
- if (content_type == 0)
- {
- /* if this is session-initiate, we should return error, otherwise,
- * we should respond with content-reject */
- if (priv->state < WOCKY_JINGLE_STATE_PENDING_INITIATED)
- g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST,
- "unsupported content type with ns %s", content_ns);
- else
- fire_idle_content_reject (sess, name,
- wocky_node_get_attribute (content_node, "creator"));
-
- return;
- }
-
- if (c != NULL)
- {
- g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST,
- "content '%s' already exists", name);
- return;
- }
-
- create_content (sess, content_type, WOCKY_JINGLE_MEDIA_TYPE_NONE,
- WOCKY_JINGLE_CONTENT_SENDERS_BOTH, content_ns, NULL, NULL, content_node,
- error);
-}
-
-static void
-_each_content_remove (WockyJingleSession *sess, WockyJingleContent *c,
- WockyNode *content_node, gpointer user_data, GError **error)
-{
- g_assert (c != NULL);
-
- wocky_jingle_content_remove (c, FALSE);
-}
-
-static void
-_each_content_rejected (WockyJingleSession *sess, WockyJingleContent *c,
- WockyNode *content_node, gpointer user_data, GError **error)
-{
- WockyJingleReason reason = GPOINTER_TO_UINT (user_data);
- g_assert (c != NULL);
-
- g_signal_emit (sess, signals[CONTENT_REJECTED], 0, c, reason, "");
-
- wocky_jingle_content_remove (c, FALSE);
-}
-
-static void
-_each_content_modify (WockyJingleSession *sess, WockyJingleContent *c,
- WockyNode *content_node, gpointer user_data, GError **error)
-{
- g_assert (c != NULL);
-
- wocky_jingle_content_update_senders (c, content_node, error);
-
- if (*error != NULL)
- return;
-}
-
-static void
-_each_content_replace (WockyJingleSession *sess, WockyJingleContent *c,
- WockyNode *content_node, gpointer user_data, GError **error)
-{
- _each_content_remove (sess, c, content_node, NULL, error);
-
- if (*error != NULL)
- return;
-
- _each_content_add (sess, c, content_node, NULL, error);
-}
-
-static void
-_each_content_accept (WockyJingleSession *sess, WockyJingleContent *c,
- WockyNode *content_node, gpointer user_data, GError **error)
-{
- WockyJingleSessionPrivate *priv = sess->priv;
- WockyJingleContentState state;
-
- g_assert (c != NULL);
-
- g_object_get (c, "state", &state, NULL);
- if (state != WOCKY_JINGLE_CONTENT_STATE_SENT)
- {
-#ifdef ENABLE_DEBUG
- const gchar *name = wocky_node_get_attribute (content_node, "name");
- DEBUG ("ignoring content \"%s\"s acceptance for content not in SENT state", name);
-#endif
- return;
- }
-
- wocky_jingle_content_parse_accept (c, content_node,
- WOCKY_JINGLE_DIALECT_IS_GOOGLE (priv->dialect), error);
-}
-
-static void
-_each_description_info (WockyJingleSession *sess, WockyJingleContent *c,
- WockyNode *content_node, gpointer user_data, GError **error)
-{
- wocky_jingle_content_parse_description_info (c, content_node, error);
-}
-
-static void
-on_session_initiate (WockyJingleSession *sess, WockyNode *node,
- GError **error)
-{
- WockyJingleSessionPrivate *priv = sess->priv;
-
- /* we can't call ourselves at the moment */
- if (priv->local_initiator)
- {
- /* We ignore initiate from us, and terminate the session immediately
- * afterwards */
- wocky_jingle_session_terminate (sess, WOCKY_JINGLE_REASON_BUSY, NULL, NULL);
- return;
- }
-
- if ((priv->dialect == WOCKY_JINGLE_DIALECT_GTALK3))
- {
- const gchar *content_ns = NULL;
- WockyNode *desc_node =
- wocky_node_get_child (node, "description");
- content_ns = wocky_node_get_ns (desc_node);
-
- if (!wocky_strdiff (content_ns, NS_GOOGLE_SESSION_VIDEO))
- {
- WockyJingleFactory *factory =
- wocky_jingle_session_get_factory (sess);
- GType content_type = 0;
-
- DEBUG ("GTalk v3 session with audio and video");
-
- /* audio and video content */
- content_type = wocky_jingle_factory_lookup_content_type (
- factory, content_ns);
- create_content (sess, content_type, WOCKY_JINGLE_MEDIA_TYPE_VIDEO,
- WOCKY_JINGLE_CONTENT_SENDERS_BOTH, NS_GOOGLE_SESSION_VIDEO, NULL,
- "video", node, error);
-
- content_type = wocky_jingle_factory_lookup_content_type (
- factory, NS_GOOGLE_SESSION_PHONE);
- create_content (sess, content_type, WOCKY_JINGLE_MEDIA_TYPE_AUDIO,
- WOCKY_JINGLE_CONTENT_SENDERS_BOTH, NS_GOOGLE_SESSION_PHONE, NULL,
- "audio", node, error);
- }
- else
- {
- _each_content_add (sess, NULL, node, NULL, error);
- }
- }
- else if (priv->dialect == WOCKY_JINGLE_DIALECT_GTALK4)
- {
- /* in this case we implicitly have just one content */
- _each_content_add (sess, NULL, node, NULL, error);
- }
- else
- {
- _foreach_content (sess, node, FALSE, _each_content_add, NULL, error);
- }
-
- if (*error == NULL)
- {
- /* FIXME: contents defined here should always have "session" content
- * disposition; resolve this as soon as the proper procedure is defined
- * in XEP-0166. */
-
- set_state (sess, WOCKY_JINGLE_STATE_PENDING_INITIATED, WOCKY_JINGLE_REASON_UNKNOWN,
- NULL);
-
- wocky_jingle_session_send_rtp_info (sess, "ringing");
- }
-}
-
-static void
-on_content_add (WockyJingleSession *sess, WockyNode *node,
- GError **error)
-{
- _foreach_content (sess, node, FALSE, _each_content_add, NULL, error);
-}
-
-static void
-on_content_modify (WockyJingleSession *sess, WockyNode *node,
- GError **error)
-{
- _foreach_content (sess, node, TRUE, _each_content_modify, NULL, error);
-}
-
-static void
-on_content_remove (WockyJingleSession *sess, WockyNode *node,
- GError **error)
-{
- _foreach_content (sess, node, TRUE, _each_content_remove, NULL, error);
-}
-
-static void
-on_content_replace (WockyJingleSession *sess, WockyNode *node,
- GError **error)
-{
- _foreach_content (sess, node, TRUE, _each_content_replace, NULL, error);
-}
-
-static void
-on_content_reject (WockyJingleSession *sess, WockyNode *node,
- GError **error)
-{
- WockyNode *n = wocky_node_get_child (node, "reason");
- WockyJingleReason reason = WOCKY_JINGLE_REASON_UNKNOWN;
-
- DEBUG (" ");
-
- if (n != NULL)
- extract_reason (n, &reason, NULL);
-
- if (reason == WOCKY_JINGLE_REASON_UNKNOWN)
- reason = WOCKY_JINGLE_REASON_GENERAL_ERROR;
-
- _foreach_content (sess, node, TRUE, _each_content_rejected,
- GUINT_TO_POINTER (reason), error);
-}
-
-static void
-on_content_accept (WockyJingleSession *sess, WockyNode *node,
- GError **error)
-{
- _foreach_content (sess, node, TRUE, _each_content_accept, NULL, error);
-}
-
-static void
-on_session_accept (WockyJingleSession *sess, WockyNode *node,
- GError **error)
-{
- WockyJingleSessionPrivate *priv = sess->priv;
-
- DEBUG ("called");
-
- if ((priv->dialect == WOCKY_JINGLE_DIALECT_GTALK3) ||
- (priv->dialect == WOCKY_JINGLE_DIALECT_GTALK4))
- {
- /* Google Talk calls don't have contents per se; they just have
- * <payload-type>s in different namespaces for audio and video, in the
- * same <description> stanza. So we need to feed the whole stanza to each
- * content in turn.
- */
- GList *cs = wocky_jingle_session_get_contents (sess);
- GList *l;
-
- for (l = cs; l != NULL; l = l->next)
- _each_content_accept (sess, l->data, node, NULL, error);
-
- g_list_free (cs);
- }
- else
- {
- _foreach_content (sess, node, TRUE, _each_content_accept, NULL, error);
- }
-
- if (*error != NULL)
- return;
-
- set_state (sess, WOCKY_JINGLE_STATE_ACTIVE, WOCKY_JINGLE_REASON_UNKNOWN, NULL);
-
- /* Make sure each content knows the session is active */
- g_list_foreach (wocky_jingle_session_get_contents (sess),
- (GFunc) g_object_notify, "state");
-
-
- if (priv->dialect != WOCKY_JINGLE_DIALECT_V032)
- {
- /* If this is a dialect that doesn't support <active/>, we treat
- * session-accept as the cue to remove the ringing flag.
- */
- priv->remote_ringing = FALSE;
- g_signal_emit (sess, signals[REMOTE_STATE_CHANGED], 0);
- }
-}
-
-static void
-mute_all_foreach (gpointer key,
- gpointer value,
- gpointer mute)
-{
- if (G_OBJECT_TYPE (value) == WOCKY_TYPE_JINGLE_MEDIA_RTP)
- g_object_set (value, "remote-mute", GPOINTER_TO_INT (mute), NULL);
-}
-
-static void
-mute_all (WockyJingleSession *sess,
- gboolean mute)
-{
- g_hash_table_foreach (sess->priv->initiator_contents, mute_all_foreach,
- GINT_TO_POINTER (mute));
- g_hash_table_foreach (sess->priv->responder_contents, mute_all_foreach,
- GINT_TO_POINTER (mute));
-}
-
-static gboolean
-set_mute (WockyJingleSession *sess,
- const gchar *name,
- const gchar *creator,
- gboolean mute,
- GError **error)
-{
- WockyJingleContent *c;
-
- if (name == NULL)
- {
- mute_all (sess, mute);
- return TRUE;
- }
-
- if (!lookup_content (sess, name, creator, TRUE /* fail if missing */, &c,
- error))
- return FALSE;
-
- if (G_OBJECT_TYPE (c) != WOCKY_TYPE_JINGLE_MEDIA_RTP)
- {
- g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST,
- "content '%s' isn't an RTP session", name);
- return FALSE;
- }
-
- g_object_set (c, "remote-mute", mute, NULL);
- return TRUE;
-}
-
-static void
-set_hold (WockyJingleSession *sess,
- gboolean hold)
-{
- sess->priv->remote_hold = hold;
-}
-
-static void
-set_ringing (WockyJingleSession *sess,
- gboolean ringing)
-{
- sess->priv->remote_ringing = ringing;
-}
-
-static gboolean
-handle_payload (WockyJingleSession *sess,
- WockyNode *payload,
- gboolean *handled,
- GError **error)
-{
- const gchar *ns = wocky_node_get_ns (payload);
- const gchar *elt = payload->name;
- const gchar *name = wocky_node_get_attribute (payload, "name");
- const gchar *creator = wocky_node_get_attribute (payload, "creator");
-
- if (wocky_strdiff (ns, NS_JINGLE_RTP_INFO))
- {
- *handled = FALSE;
- return TRUE;
- }
-
- *handled = TRUE;
-
- if (!wocky_strdiff (elt, "active"))
- {
- /* Clear all states, we're active */
- mute_all (sess, FALSE);
- set_ringing (sess, FALSE);
- set_hold (sess, FALSE);
- }
- else if (!wocky_strdiff (elt, "ringing"))
- {
- set_ringing (sess, TRUE);
- }
- else if (!wocky_strdiff (elt, "hold"))
- {
- set_hold (sess, TRUE);
- }
- else if (!wocky_strdiff (elt, "unhold"))
- {
- set_hold (sess, FALSE);
- }
- /* XEP-0178 says that only <mute/> and <unmute/> can have a name=''
- * attribute.
- */
- else if (!wocky_strdiff (elt, "mute"))
- {
- return set_mute (sess, name, creator, TRUE, error);
- }
- else if (!wocky_strdiff (elt, "unmute"))
- {
- return set_mute (sess, name, creator, FALSE, error);
- }
- else
- {
- g_set_error (error, WOCKY_JINGLE_ERROR,
- WOCKY_JINGLE_ERROR_UNSUPPORTED_INFO,
- "<%s> is not known in namespace %s", elt, ns);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void
-on_session_info (WockyJingleSession *sess,
- WockyNode *node,
- GError **error)
-{
- gboolean understood_a_payload = FALSE;
- gboolean hit_an_error = FALSE;
- WockyNodeIter i;
- WockyNode *n;
-
- /* if this is a ping, just ack it. */
- if (wocky_node_get_first_child (node) == NULL)
- return;
-
- wocky_node_iter_init (&i, node, NULL, NULL);
- while (wocky_node_iter_next (&i, &n))
- {
- gboolean handled;
- GError *e = NULL;
-
- if (handle_payload (sess, n, &handled, &e))
- {
- understood_a_payload = understood_a_payload || handled;
- }
- else if (hit_an_error)
- {
- DEBUG ("already got another error; ignoring %s", e->message);
- g_error_free (e);
- }
- else
- {
- DEBUG ("hit an error: %s", e->message);
- hit_an_error = TRUE;
- g_propagate_error (error, e);
- }
- }
-
- /* If we understood something, the remote state (may have) changed. Else,
- * return an error to the peer.
- */
- if (understood_a_payload)
- g_signal_emit (sess, signals[REMOTE_STATE_CHANGED], 0);
- else if (!hit_an_error)
- g_set_error (error, WOCKY_JINGLE_ERROR, WOCKY_JINGLE_ERROR_UNSUPPORTED_INFO,
- "no recognized session-info payloads");
-}
-
-static void
-on_session_terminate (WockyJingleSession *sess, WockyNode *node,
- GError **error)
-{
- gchar *text = NULL;
- WockyNode *n = wocky_node_get_child (node, "reason");
- WockyJingleReason wocky_jingle_reason = WOCKY_JINGLE_REASON_UNKNOWN;
-
- if (n != NULL)
- extract_reason (n, &wocky_jingle_reason, &text);
-
- DEBUG ("remote end terminated the session with reason %s and text '%s'",
- wocky_jingle_session_get_reason_name (wocky_jingle_reason),
- (text != NULL ? text : "(none)"));
-
- set_state (sess, WOCKY_JINGLE_STATE_ENDED, wocky_jingle_reason, text);
-
- g_free (text);
-}
-
-static void
-on_transport_info (WockyJingleSession *sess, WockyNode *node,
- GError **error)
-{
- WockyJingleSessionPrivate *priv = sess->priv;
- WockyJingleContent *c = NULL;
-
- if (WOCKY_JINGLE_DIALECT_IS_GOOGLE (priv->dialect))
- {
- GHashTableIter iter;
- gpointer value;
-
- if (priv->dialect == WOCKY_JINGLE_DIALECT_GTALK4)
- {
- if (!wocky_strdiff (wocky_node_get_attribute (node, "type"),
- "candidates"))
- {
- GList *contents = wocky_jingle_session_get_contents (sess);
- GList *l;
-
- DEBUG ("switching to gtalk3 dialect and retransmiting our candidates");
- priv->dialect = WOCKY_JINGLE_DIALECT_GTALK3;
-
- for (l = contents; l != NULL; l = l->next)
- wocky_jingle_content_retransmit_candidates (l->data, TRUE);
-
- g_list_free (contents);
- }
- else
- {
- node = wocky_node_get_child (node, "transport");
-
- if (node == NULL)
- {
- g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST,
- "transport-info stanza without a <transport/>");
- return;
- }
- }
- }
-
- g_hash_table_iter_init (&iter, priv->initiator_contents);
- while (g_hash_table_iter_next (&iter, NULL, &value))
- {
- c = value;
- wocky_jingle_content_parse_transport_info (c, node, error);
- if (error != NULL && *error != NULL)
- break;
- }
- }
- else
- {
- WockyNodeIter i;
- WockyNode *content_node;
- GError *e = NULL;
-
- wocky_node_iter_init (&i, node, "content", NULL);
-
- while (wocky_node_iter_next (&i, &content_node))
- {
- WockyNode *transport_node;
-
- if (lookup_content (sess,
- wocky_node_get_attribute (content_node, "name"),
- wocky_node_get_attribute (content_node, "creator"),
- TRUE /* fail_if_missing */, &c, &e))
- {
- /* we need transport child of content node */
- transport_node = wocky_node_get_child (
- content_node, "transport");
- wocky_jingle_content_parse_transport_info (c,
- transport_node, &e);
- }
-
- /* Save the first error we encounter, but go through all remaining
- * contents anyway to try and recover as much info as we can */
- if (e != NULL && error != NULL && *error == NULL)
- {
- *error = e;
- e = NULL;
- }
- g_clear_error (&e);
- }
- }
-
-}
-
-static void
-on_transport_accept (WockyJingleSession *sess, WockyNode *node,
- GError **error)
-{
- DEBUG ("Ignoring 'transport-accept' action from peer");
-}
-
-static void
-on_description_info (WockyJingleSession *sess, WockyNode *node,
- GError **error)
-{
- _foreach_content (sess, node, TRUE, _each_description_info, NULL, error);
-}
-
-static void
-on_info (WockyJingleSession *sess, WockyNode *node,
- GError **error)
-{
- WockyJingleSessionPrivate *priv = sess->priv;
- WockyJingleContent *c = NULL;
-
- DEBUG ("received info ");
- if (WOCKY_JINGLE_DIALECT_IS_GOOGLE (priv->dialect))
- {
- GHashTableIter iter;
- g_hash_table_iter_init (&iter, priv->initiator_contents);
- while (g_hash_table_iter_next (&iter, NULL, (gpointer) &c))
- {
- wocky_jingle_content_parse_info (c, node, error);
- if (error != NULL && *error != NULL)
- break;
- }
- }
-}
-
-static HandlerFunc handlers[] = {
- NULL, /* for unknown action */
- on_content_accept,
- on_content_add,
- on_content_modify,
- on_content_remove,
- on_content_replace,
- on_content_reject,
- on_session_accept, /* jingle_on_session_accept */
- on_session_info,
- on_session_initiate,
- on_session_terminate, /* jingle_on_session_terminate */
- on_transport_info, /* jingle_on_transport_info */
- on_transport_accept,
- on_description_info,
- on_info
-};
-
-static void
-wocky_jingle_state_machine_dance (WockyJingleSession *sess,
- WockyJingleAction action,
- WockyNode *node,
- GError **error)
-{
- WockyJingleSessionPrivate *priv = sess->priv;
-
- /* parser should've checked this already */
- g_assert (action_is_allowed (action, priv->state));
- g_assert (handlers[action] != NULL);
-
- handlers[action] (sess, node, error);
-}
-
-static WockyJingleDialect
-detect_google_dialect (WockyNode *session_node)
-{
- /* The GTALK3 dialect is the only one that supports video at this time */
- if (wocky_node_get_child_ns (session_node,
- "description", NS_GOOGLE_SESSION_VIDEO) != NULL)
- return WOCKY_JINGLE_DIALECT_GTALK3;
-
- /* GTalk4 has a transport item, GTalk3 doesn't */
- if (wocky_node_get_child_ns (session_node,
- "transport", NS_GOOGLE_TRANSPORT_P2P) == NULL)
- return WOCKY_JINGLE_DIALECT_GTALK3;
-
- return WOCKY_JINGLE_DIALECT_GTALK4;
-}
-
-const gchar *
-wocky_jingle_session_detect (
- WockyStanza *stanza,
- WockyJingleAction *action,
- WockyJingleDialect *dialect)
-{
- const gchar *actxt, *sid;
- WockyNode *iq_node, *session_node;
- WockyStanzaSubType sub_type;
- gboolean google_mode = FALSE;
-
- /* all jingle actions are sets */
- wocky_stanza_get_type_info (stanza, NULL, &sub_type);
- if (sub_type != WOCKY_STANZA_SUB_TYPE_SET)
- return NULL;
-
- iq_node = wocky_stanza_get_top_node (stanza);
-
- if ((NULL == wocky_stanza_get_from (stanza)) ||
- (NULL == wocky_stanza_get_to (stanza)))
- return NULL;
-
- /* first, we try standard jingle */
- session_node = wocky_node_get_child_ns (iq_node, "jingle", NS_JINGLE032);
-
- if (session_node != NULL)
- {
- *dialect = WOCKY_JINGLE_DIALECT_V032;
- }
- else
- {
- /* then, we try a bit older jingle version */
- session_node = wocky_node_get_child_ns (iq_node, "jingle", NS_JINGLE015);
-
- if (session_node != NULL)
- {
- *dialect = WOCKY_JINGLE_DIALECT_V015;
- }
- else
- {
- /* next, we try googletalk */
- session_node = wocky_node_get_child_ns (iq_node,
- "session", NS_GOOGLE_SESSION);
-
- if (session_node != NULL)
- {
- *dialect = detect_google_dialect (session_node);
- google_mode = TRUE;
- }
- else
- {
- return NULL;
- }
- }
- }
-
- if (google_mode)
- {
- actxt = wocky_node_get_attribute (session_node, "type");
- sid = wocky_node_get_attribute (session_node, "id");
- }
- else
- {
- actxt = wocky_node_get_attribute (session_node, "action");
- sid = wocky_node_get_attribute (session_node, "sid");
- }
-
- *action = parse_action (actxt);
-
- return sid;
-}
-
-gboolean
-wocky_jingle_session_parse (
- WockyJingleSession *sess,
- WockyJingleAction action,
- WockyStanza *stanza,
- GError **error)
-{
- WockyJingleSessionPrivate *priv = sess->priv;
- WockyNode *iq_node, *session_node;
- const gchar *from, *action_name;
-
- /* IQ from/to can come in handy */
- from = wocky_stanza_get_from (stanza);
- iq_node = wocky_stanza_get_top_node (stanza);
-
- if (action == WOCKY_JINGLE_ACTION_UNKNOWN)
- {
- g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST,
- "unknown session action");
- return FALSE;
- }
-
- action_name = produce_action (action, priv->dialect);
-
- DEBUG ("jingle action '%s' from '%s' in session '%s' dialect %u state %u",
- action_name, from, priv->sid, priv->dialect, priv->state);
-
- switch (priv->dialect) {
- case WOCKY_JINGLE_DIALECT_V032:
- session_node = wocky_node_get_child_ns (iq_node,
- "jingle", NS_JINGLE032);
- break;
- case WOCKY_JINGLE_DIALECT_V015:
- session_node = wocky_node_get_child_ns (iq_node,
- "jingle", NS_JINGLE015);
- break;
- case WOCKY_JINGLE_DIALECT_GTALK3:
- case WOCKY_JINGLE_DIALECT_GTALK4:
- session_node = wocky_node_get_child_ns (iq_node,
- "session", NS_GOOGLE_SESSION);
- break;
- default:
- /* just to make gcc happy about dealing with default case */
- session_node = NULL;
- }
-
- if (session_node == NULL)
- {
- g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST,
- "malformed jingle stanza");
- return FALSE;
- }
-
- if (!wocky_jingle_session_defines_action (sess, action))
- {
- g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST,
- "action '%s' unknown (using dialect %u)", action_name, priv->dialect);
- return FALSE;
- }
-
- if (!action_is_allowed (action, priv->state))
- {
- g_set_error (error, WOCKY_JINGLE_ERROR, WOCKY_JINGLE_ERROR_OUT_OF_ORDER,
- "action '%s' not allowed in current state", action_name);
- return FALSE;
- }
-
- wocky_jingle_state_machine_dance (sess, action, session_node, error);
-
- if (*error != NULL)
- return FALSE;
-
- return TRUE;
-}
-
-WockyStanza *
-wocky_jingle_session_new_message (WockyJingleSession *sess,
- WockyJingleAction action, WockyNode **sess_node)
-{
- WockyJingleSessionPrivate *priv = sess->priv;
- WockyStanza *stanza;
- WockyNode *session_node;
- gchar *el = NULL, *ns = NULL;
- gboolean gtalk_mode = FALSE;
-
- g_return_val_if_fail (action != WOCKY_JINGLE_ACTION_UNKNOWN, NULL);
-
- g_assert ((action == WOCKY_JINGLE_ACTION_SESSION_INITIATE) ||
- (priv->state > WOCKY_JINGLE_STATE_PENDING_CREATED));
- g_assert (WOCKY_IS_JINGLE_SESSION (sess));
-
- switch (priv->dialect)
- {
- case WOCKY_JINGLE_DIALECT_V032:
- el = "jingle";
- ns = NS_JINGLE032;
- break;
- case WOCKY_JINGLE_DIALECT_V015:
- el = "jingle";
- ns = NS_JINGLE015;
- break;
- case WOCKY_JINGLE_DIALECT_GTALK3:
- case WOCKY_JINGLE_DIALECT_GTALK4:
- el = "session";
- ns = NS_GOOGLE_SESSION;
- gtalk_mode = TRUE;
- break;
- case WOCKY_JINGLE_DIALECT_ERROR:
- g_assert_not_reached ();
- }
-
- stanza = wocky_stanza_build (
- WOCKY_STANZA_TYPE_IQ, WOCKY_STANZA_SUB_TYPE_SET,
- NULL, priv->peer_jid,
- '(', el, ':', ns,
- '*', &session_node,
- ')', NULL);
-
- wocky_node_set_attributes (session_node,
- "initiator", priv->initiator,
- (gtalk_mode) ? "id" : "sid", priv->sid,
- (gtalk_mode) ? "type" : "action",
- produce_action (action, priv->dialect),
- NULL);
-
- if (sess_node != NULL)
- *sess_node = session_node;
-
- return stanza;
-}
-
-typedef void (*ContentMapperFunc) (WockyJingleSession *sess,
- WockyJingleContent *c, gpointer user_data);
-
-static void
-_map_initial_contents (WockyJingleSession *sess, ContentMapperFunc mapper,
- gpointer user_data)
-{
- GList *li;
- GList *contents = wocky_jingle_session_get_contents (sess);
-
- for (li = contents; li; li = li->next)
- {
- WockyJingleContent *c = WOCKY_JINGLE_CONTENT (li->data);
- const gchar *disposition = wocky_jingle_content_get_disposition (c);
-
- if (!wocky_strdiff (disposition, "session"))
- mapper (sess, c, user_data);
- }
-
- g_list_free (contents);
-}
-
-static void
-_check_content_ready (WockyJingleSession *sess,
- WockyJingleContent *c, gpointer user_data)
-{
- gboolean *ready = (gboolean *) user_data;
-
- if (!wocky_jingle_content_is_ready (c))
- {
- *ready = FALSE;
- }
-}
-
-static void
-_transmit_candidates (WockyJingleSession *sess,
- WockyJingleContent *c,
- gpointer user_data)
-{
- wocky_jingle_content_retransmit_candidates (c, FALSE);
-}
-
-static void
-_fill_content (WockyJingleSession *sess,
- WockyJingleContent *c, gpointer user_data)
-{
- WockyNode *sess_node = user_data;
- WockyNode *transport_node;
- WockyJingleContentState state;
-
- wocky_jingle_content_produce_node (c, sess_node, TRUE, TRUE,
- &transport_node);
- wocky_jingle_content_inject_candidates (c, transport_node);
-
- g_object_get (c, "state", &state, NULL);
-
- if (state == WOCKY_JINGLE_CONTENT_STATE_EMPTY)
- {
- g_object_set (c, "state", WOCKY_JINGLE_CONTENT_STATE_SENT, NULL);
- }
- else if (state == WOCKY_JINGLE_CONTENT_STATE_NEW)
- {
- g_object_set (c, "state", WOCKY_JINGLE_CONTENT_STATE_ACKNOWLEDGED, NULL);
- }
- else
- {
- DEBUG ("content %p is in state %u", c, state);
- g_assert_not_reached ();
- }
-}
-
-/**
- * wocky_jingle_session_send:
- * @sess: a session
- * @stanza: (transfer full): a stanza, of which this function will take ownership
- *
- * A shorthand for sending a Jingle IQ without waiting for the reply.
- */
-void
-wocky_jingle_session_send (WockyJingleSession *sess,
- WockyStanza *stanza)
-{
- wocky_porter_send_iq_async (sess->priv->porter,
- stanza, NULL, NULL, NULL);
- g_object_unref (stanza);
-}
-
-static void
-_on_initiate_reply (
- GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- WockyPorter *porter = WOCKY_PORTER (source);
- WockyJingleSession *sess = WOCKY_JINGLE_SESSION (user_data);
- WockyJingleSessionPrivate *priv = sess->priv;
- WockyStanza *reply;
-
- if (priv->state != WOCKY_JINGLE_STATE_PENDING_INITIATE_SENT)
- {
- DEBUG ("Ignoring session-initiate reply; session %p is in state %u.",
- sess, priv->state);
- g_object_unref (sess);
- return;
- }
-
- reply = wocky_porter_send_iq_finish (porter, result, NULL);
- if (reply != NULL &&
- !wocky_stanza_extract_errors (reply, NULL, NULL, NULL, NULL))
- {
- set_state (sess, WOCKY_JINGLE_STATE_PENDING_INITIATED, 0, NULL);
-
- if (priv->dialect != WOCKY_JINGLE_DIALECT_V032)
- {
- /* If this is a dialect that doesn't support <ringing/>, we treat the
- * session-initiate being acked as the cue to say we're ringing.
- */
- priv->remote_ringing = TRUE;
- g_signal_emit (sess, signals[REMOTE_STATE_CHANGED], 0);
- }
- }
- else
- {
- set_state (sess, WOCKY_JINGLE_STATE_ENDED, WOCKY_JINGLE_REASON_UNKNOWN,
- NULL);
- }
-
- g_clear_object (&reply);
- g_object_unref (sess);
-}
-
-static void
-_on_accept_reply (
- GObject *source,
- GAsyncResult *result,
- gpointer user_data)
-{
- WockyPorter *porter = WOCKY_PORTER (source);
- WockyJingleSession *sess = WOCKY_JINGLE_SESSION (user_data);
- WockyJingleSessionPrivate *priv = sess->priv;
- WockyStanza *reply;
-
- if (priv->state != WOCKY_JINGLE_STATE_PENDING_ACCEPT_SENT)
- {
- DEBUG ("Ignoring session-accept reply; session %p is in state %u.",
- sess, priv->state);
- g_object_unref (sess);
- return;
- }
-
- reply = wocky_porter_send_iq_finish (porter, result, NULL);
- if (reply != NULL &&
- !wocky_stanza_extract_errors (reply, NULL, NULL, NULL, NULL))
- {
- set_state (sess, WOCKY_JINGLE_STATE_ACTIVE, 0, NULL);
- wocky_jingle_session_send_rtp_info (sess, "active");
- }
- else
- {
- set_state (sess, WOCKY_JINGLE_STATE_ENDED, WOCKY_JINGLE_REASON_UNKNOWN,
- NULL);
- }
-
- g_clear_object (&reply);
- g_object_unref (sess);
-}
-
-static void
-try_session_initiate_or_accept (WockyJingleSession *sess)
-{
- WockyJingleSessionPrivate *priv = sess->priv;
- WockyStanza *msg;
- WockyNode *sess_node;
- gboolean contents_ready = TRUE;
- WockyJingleAction action;
- WockyJingleState new_state;
- GAsyncReadyCallback handler;
-
- DEBUG ("Trying initiate or accept");
-
- /* If there are no contents yet, we shouldn't have been called at all. */
- g_assert (g_hash_table_size (priv->initiator_contents) +
- g_hash_table_size (priv->responder_contents) > 0);
-
- if (priv->local_initiator)
- {
- if (priv->state != WOCKY_JINGLE_STATE_PENDING_CREATED)
- {
- DEBUG ("session is in state %u, won't try to initiate", priv->state);
- return;
- }
-
- if (!priv->locally_accepted)
- {
- DEBUG ("session not locally accepted yet, not initiating");
- return;
- }
-
- g_signal_emit (sess, signals[ABOUT_TO_INITIATE], 0);
-
- action = WOCKY_JINGLE_ACTION_SESSION_INITIATE;
- new_state = WOCKY_JINGLE_STATE_PENDING_INITIATE_SENT;
- handler = _on_initiate_reply;
- }
- else
- {
- if (priv->state != WOCKY_JINGLE_STATE_PENDING_INITIATED)
- {
- DEBUG ("session is in state %u, won't try to accept", priv->state);
- return;
- }
-
- if (!priv->locally_accepted)
- {
- DEBUG ("session not locally accepted yet, not accepting");
- return;
- }
-
- action = WOCKY_JINGLE_ACTION_SESSION_ACCEPT;
- new_state = WOCKY_JINGLE_STATE_PENDING_ACCEPT_SENT;
- handler = _on_accept_reply;
- }
-
- _map_initial_contents (sess, _check_content_ready, &contents_ready);
-
- DEBUG ("Contents are ready: %s", contents_ready ? "yes" : "no");
-
- if (!contents_ready)
- {
- DEBUG ("Contents not yet ready, not initiating/accepting now..");
- return;
- }
-
- msg = wocky_jingle_session_new_message (sess, action, &sess_node);
-
- if (priv->dialect == WOCKY_JINGLE_DIALECT_GTALK3)
- {
- gboolean has_video = FALSE;
- gboolean has_audio = FALSE;
- GHashTableIter iter;
- gpointer value;
-
- g_hash_table_iter_init (&iter, priv->initiator_contents);
- while (g_hash_table_iter_next (&iter, NULL, &value))
- {
- WockyJingleMediaType type;
-
- g_object_get (value, "media-type", &type, NULL);
-
- if (type == WOCKY_JINGLE_MEDIA_TYPE_VIDEO)
- {
- has_video = TRUE;
- }
- else if (type == WOCKY_JINGLE_MEDIA_TYPE_AUDIO)
- {
- has_audio = TRUE;
- }
- }
-
- if (has_video || has_audio)
- {
- sess_node = wocky_node_add_child_ns_q (sess_node, "description",
- g_quark_from_static_string (has_video
- ? NS_GOOGLE_SESSION_VIDEO : NS_GOOGLE_SESSION_PHONE));
- }
- }
-
-
- _map_initial_contents (sess, _fill_content, sess_node);
- wocky_porter_send_iq_async (priv->porter,
- msg, NULL, handler, g_object_ref (sess));
- g_object_unref (msg);
- set_state (sess, new_state, 0, NULL);
-
- /* now all initial contents can transmit their candidates */
- _map_initial_contents (sess, _transmit_candidates, NULL);
-}
-
-/**
- * set_state:
- * @sess: a jingle session
- * @state: the new state for the session
- * @termination_reason: if @state is WOCKY_JINGLE_STATE_ENDED, the reason the session
- * ended. Otherwise, must be WOCKY_JINGLE_REASON_UNKNOWN.
- * @text: if @state is WOCKY_JINGLE_STATE_ENDED, the human-readable reason the session
- * ended.
- */
-static void
-set_state (WockyJingleSession *sess,
- WockyJingleState state,
- WockyJingleReason termination_reason,
- const gchar *text)
-{
- WockyJingleSessionPrivate *priv = sess->priv;
-
- if (state <= priv->state)
- {
- DEBUG ("ignoring request to set state from %u back to %u", priv->state, state);
- return;
- }
-
- if (state != WOCKY_JINGLE_STATE_ENDED)
- g_assert (termination_reason == WOCKY_JINGLE_REASON_UNKNOWN);
-
- DEBUG ("Setting state of JingleSession: %p (priv = %p) from %u to %u", sess, priv, priv->state, state);
-
- priv->state = state;
- g_object_notify (G_OBJECT (sess), "state");
-
- /* If we have an outstanding "you're on hold notification", send it */
- if (priv->local_hold &&
- state >= WOCKY_JINGLE_STATE_PENDING_INITIATED &&
- state < WOCKY_JINGLE_STATE_ENDED)
- wocky_jingle_session_send_held (sess);
-
- if (state == WOCKY_JINGLE_STATE_ENDED)
- g_signal_emit (sess, signals[TERMINATED], 0, priv->locally_terminated,
- termination_reason, text);
-}
-
-void
-wocky_jingle_session_accept (WockyJingleSession *sess)
-{
- WockyJingleSessionPrivate *priv = sess->priv;
-
- priv->locally_accepted = TRUE;
-
- try_session_initiate_or_accept (sess);
-}
-
-const gchar *
-wocky_jingle_session_get_reason_name (WockyJingleReason reason)
-{
- GEnumClass *klass = g_type_class_ref (wocky_jingle_reason_get_type ());
- GEnumValue *enum_value = g_enum_get_value (klass, (gint) reason);
-
- g_return_val_if_fail (enum_value != NULL, NULL);
-
- return enum_value->value_nick;
-}
-
-gboolean
-wocky_jingle_session_terminate (WockyJingleSession *sess,
- WockyJingleReason reason,
- const gchar *text,
- GError **error)
-{
- WockyJingleSessionPrivate *priv = sess->priv;
- const gchar *reason_elt;
-
- if (priv->state == WOCKY_JINGLE_STATE_ENDED)
- {
- DEBUG ("session already terminated, ignoring terminate request");
- return TRUE;
- }
-
- if (reason == WOCKY_JINGLE_REASON_UNKNOWN)
- reason = (priv->state == WOCKY_JINGLE_STATE_ACTIVE) ?
- WOCKY_JINGLE_REASON_SUCCESS : WOCKY_JINGLE_REASON_CANCEL;
-
- reason_elt = wocky_jingle_session_get_reason_name (reason);
-
- if (priv->state != WOCKY_JINGLE_STATE_PENDING_CREATED)
- {
- WockyNode *session_node;
- WockyStanza *msg = wocky_jingle_session_new_message (sess,
- WOCKY_JINGLE_ACTION_SESSION_TERMINATE, &session_node);
-
- if (priv->dialect == WOCKY_JINGLE_DIALECT_V032 && reason_elt != NULL)
- {
- WockyNode *r = wocky_node_add_child_with_content (session_node, "reason",
- NULL);
-
- wocky_node_add_child (r, reason_elt);
-
- if (text != NULL && *text != '\0')
- wocky_node_add_child_with_content (r, "text", text);
- }
-
- wocky_jingle_session_send (sess, msg);
- }
-
- /* NOTE: on "terminated", jingle factory and media channel will unref
- * it, bringing refcount to 0, so dispose will be called, and it
- * takes care of cleanup */
-
- DEBUG ("we are terminating this session");
- priv->locally_terminated = TRUE;
- set_state (sess, WOCKY_JINGLE_STATE_ENDED, reason, text);
-
- return TRUE;
-}
-
-static void
-_foreach_count_active_contents (gpointer key, gpointer value, gpointer user_data)
-{
- WockyJingleContent *c = value;
- guint *n_contents = user_data;
- WockyJingleContentState state;
-
- g_object_get (c, "state", &state, NULL);
- if ((state >= WOCKY_JINGLE_CONTENT_STATE_NEW) &&
- (state < WOCKY_JINGLE_CONTENT_STATE_REMOVING))
- {
- *n_contents = *n_contents + 1;
- }
-}
-
-static gboolean
-count_active_contents (WockyJingleSession *sess)
-{
- WockyJingleSessionPrivate *priv = sess->priv;
- guint n_contents = 0;
-
- g_hash_table_foreach (priv->initiator_contents, _foreach_count_active_contents,
- &n_contents);
- g_hash_table_foreach (priv->responder_contents, _foreach_count_active_contents,
- &n_contents);
-
- return n_contents;
-}
-
-static void
-content_removed_cb (WockyJingleContent *c, gpointer user_data)
-{
- WockyJingleSession *sess = WOCKY_JINGLE_SESSION (user_data);
- WockyJingleSessionPrivate *priv = sess->priv;
- const gchar *name = wocky_jingle_content_get_name (c);
-
- if (wocky_jingle_content_creator_is_initiator (c))
- g_hash_table_remove (priv->initiator_contents, name);
- else
- g_hash_table_remove (priv->responder_contents, name);
-
- if (priv->state == WOCKY_JINGLE_STATE_ENDED)
- return;
-
- if (count_active_contents (sess) == 0)
- {
- wocky_jingle_session_terminate (sess,
- WOCKY_JINGLE_REASON_UNKNOWN, NULL, NULL);
- }
- else
- {
- /* It's possible the content now removed was
- * blocking us from creating or accepting the
- * session, so we might as well try now. */
- try_session_initiate_or_accept (sess);
- }
-}
-
-
-void
-wocky_jingle_session_remove_content (WockyJingleSession *sess,
- WockyJingleContent *c)
-{
- if (count_active_contents (sess) > 1)
- {
- wocky_jingle_content_remove (c, TRUE);
- }
- else
- {
- /* session will be terminated when the content gets marked as removed */
- DEBUG ("called for last active content, doing session-terminate instead");
- wocky_jingle_content_remove (c, FALSE);
- }
-}
-
-WockyJingleContent *
-wocky_jingle_session_add_content (WockyJingleSession *sess,
- WockyJingleMediaType mtype,
- WockyJingleContentSenders senders,
- const gchar *name,
- const gchar *content_ns,
- const gchar *transport_ns)
-{
- WockyJingleSessionPrivate *priv = sess->priv;
- WockyJingleContent *c;
- GType content_type;
- GHashTable *contents = priv->local_initiator ? priv->initiator_contents
- : priv->responder_contents;
- guint id = g_hash_table_size (contents) + 1;
- gchar *cname = NULL;
-
- if (name == NULL || *name == '\0')
- name = (mtype == WOCKY_JINGLE_MEDIA_TYPE_AUDIO ? "Audio" : "Video");
-
- cname = g_strdup (name);
-
- while (g_hash_table_lookup (priv->initiator_contents, cname) != NULL
- || g_hash_table_lookup (priv->responder_contents, cname) != NULL)
- {
- g_free (cname);
- cname = g_strdup_printf ("%s_%d", name, id++);
- }
-
- content_type = wocky_jingle_factory_lookup_content_type (
- wocky_jingle_session_get_factory (sess),
- content_ns);
-
- g_assert (content_type != 0);
-
- c = create_content (sess, content_type, mtype, senders,
- content_ns, transport_ns, cname, NULL, NULL);
-
- /* The new content better have ended up in the set we thought it would... */
- g_assert (g_hash_table_lookup (contents, cname) != NULL);
-
- g_free (cname);
-
- return c;
-}
-
-/* Get any content. Either we're in google mode (so we only have one content
- * anyways), or we just need any content type to figure out what use case
- * we're in (media, ft, etc). */
-static WockyJingleContent *
-_get_any_content (WockyJingleSession *session)
-{
- WockyJingleContent *c;
-
- GList *li = wocky_jingle_session_get_contents (session);
-
- if (li == NULL)
- return NULL;
-
- c = li->data;
- g_list_free (li);
-
- return c;
-}
-
-/* Note: if there are multiple content types, not guaranteed which one will
- * be returned. Typically, the same GType will know how to handle related
- * contents found in a session (e.g. media-rtp for audio/video), so that
- * should not be a problem. Returns 0 if there are no contents yet. */
-GType
-wocky_jingle_session_get_content_type (WockyJingleSession *sess)
-{
- WockyJingleContent *c = _get_any_content (sess);
-
- if (c == NULL)
- return 0;
-
- return G_OBJECT_TYPE (c);
-}
-
-/* FIXME: probably should make this into a property */
-GList *
-wocky_jingle_session_get_contents (WockyJingleSession *sess)
-{
- WockyJingleSessionPrivate *priv = sess->priv;
-
- return g_list_concat (g_hash_table_get_values (priv->initiator_contents),
- g_hash_table_get_values (priv->responder_contents));
-}
-
-const gchar *
-wocky_jingle_session_get_peer_resource (WockyJingleSession *sess)
-{
- return sess->priv->peer_resource;
-}
-
-const gchar *
-wocky_jingle_session_get_initiator (WockyJingleSession *sess)
-{
- return sess->priv->initiator;
-}
-
-const gchar *
-wocky_jingle_session_get_sid (WockyJingleSession *sess)
-{
- return sess->priv->sid;
-}
-
-static void
-content_ready_cb (WockyJingleContent *c, gpointer user_data)
-{
- WockyJingleSession *sess = WOCKY_JINGLE_SESSION (user_data);
- const gchar *disposition;
-
- DEBUG ("called");
-
- disposition = wocky_jingle_content_get_disposition (c);
- /* This assertion is actually safe, because 'ready' is only emitted by
- * contents with disposition "session". But this is crazy.
- */
- g_assert (!wocky_strdiff (disposition, "session"));
-
- try_session_initiate_or_accept (sess);
-}
-
-static void
-wocky_jingle_session_send_rtp_info (WockyJingleSession *sess,
- const gchar *name)
-{
- WockyStanza *message;
- WockyNode *jingle;
-
- if (!wocky_jingle_session_defines_action (sess, WOCKY_JINGLE_ACTION_SESSION_INFO))
- {
- DEBUG ("Not sending <%s/>; not using modern Jingle", name);
- return;
- }
-
- message = wocky_jingle_session_new_message (sess,
- WOCKY_JINGLE_ACTION_SESSION_INFO, &jingle);
- wocky_node_add_child_ns_q (jingle, name,
- g_quark_from_static_string (NS_JINGLE_RTP_INFO));
-
- /* This is just informational, so ignoring the reply. */
- wocky_jingle_session_send (sess, message);
-}
-
-static void
-wocky_jingle_session_send_held (WockyJingleSession *sess)
-{
- const gchar *s = (sess->priv->local_hold ? "hold" : "unhold");
-
- wocky_jingle_session_send_rtp_info (sess, s);
-}
-
-void
-wocky_jingle_session_set_local_hold (WockyJingleSession *sess,
- gboolean held)
-{
- g_object_set (sess, "local-hold", held, NULL);
-}
-
-gboolean
-wocky_jingle_session_get_remote_hold (WockyJingleSession *sess)
-{
- g_assert (WOCKY_IS_JINGLE_SESSION (sess));
-
- return sess->priv->remote_hold;
-}
-
-gboolean
-wocky_jingle_session_get_remote_ringing (WockyJingleSession *sess)
-{
- g_assert (WOCKY_IS_JINGLE_SESSION (sess));
-
- return sess->priv->remote_ringing;
-}
-
-gboolean
-wocky_jingle_session_can_modify_contents (WockyJingleSession *sess)
-{
- return !WOCKY_JINGLE_DIALECT_IS_GOOGLE (sess->priv->dialect) &&
- !wocky_jingle_session_peer_has_cap (sess, QUIRK_GOOGLE_WEBMAIL_CLIENT);
-}
-
-WockyJingleDialect
-wocky_jingle_session_get_dialect (WockyJingleSession *sess)
-{
- return sess->priv->dialect;
-}
-
-WockyContact *
-wocky_jingle_session_get_peer_contact (WockyJingleSession *self)
-{
- return self->priv->peer_contact;
-}
-
-/*
- * wocky_jingle_session_get_peer_jid:
- * @sess: a jingle session
- *
- * Returns: the full JID of the remote contact.
- */
-const gchar *
-wocky_jingle_session_get_peer_jid (WockyJingleSession *sess)
-{
- return sess->priv->peer_jid;
-}
-
-WockyJingleFactory *
-wocky_jingle_session_get_factory (WockyJingleSession *self)
-{
- return self->priv->jingle_factory;
-}
-
-WockyPorter *
-wocky_jingle_session_get_porter (WockyJingleSession *self)
-{
- return self->priv->porter;
-}
diff --git a/src/jingle-session.h b/src/jingle-session.h
deleted file mode 100644
index c49ede2f7..000000000
--- a/src/jingle-session.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * jingle-session.h - Header for WockyJingleSession
- * Copyright (C) 2008 Collabora Ltd.
- *
- * 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 __JINGLE_SESSION_H__
-#define __JINGLE_SESSION_H__
-
-#include <glib-object.h>
-#include <wocky/wocky.h>
-
-#include "jingle-content.h"
-#include "jingle-factory.h"
-#include "jingle-types.h"
-
-G_BEGIN_DECLS
-
-typedef enum
-{
- MODE_GOOGLE,
- MODE_JINGLE
-} GabbleMediaSessionMode;
-
-typedef struct _WockyJingleSessionClass WockyJingleSessionClass;
-
-GType wocky_jingle_session_get_type (void);
-
-/* TYPE MACROS */
-#define WOCKY_TYPE_JINGLE_SESSION \
- (wocky_jingle_session_get_type ())
-#define WOCKY_JINGLE_SESSION(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), WOCKY_TYPE_JINGLE_SESSION, \
- WockyJingleSession))
-#define WOCKY_JINGLE_SESSION_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), WOCKY_TYPE_JINGLE_SESSION, \
- WockyJingleSessionClass))
-#define WOCKY_IS_JINGLE_SESSION(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), WOCKY_TYPE_JINGLE_SESSION))
-#define WOCKY_IS_JINGLE_SESSION_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), WOCKY_TYPE_JINGLE_SESSION))
-#define WOCKY_JINGLE_SESSION_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), WOCKY_TYPE_JINGLE_SESSION, \
- WockyJingleSessionClass))
-
-struct _WockyJingleSessionClass {
- GObjectClass parent_class;
-};
-
-typedef struct _WockyJingleSessionPrivate WockyJingleSessionPrivate;
-
-struct _WockyJingleSession {
- GObject parent;
- WockyJingleSessionPrivate *priv;
-};
-
-WockyJingleSession *wocky_jingle_session_new (
- WockyJingleFactory *factory,
- WockyPorter *porter,
- const gchar *session_id,
- gboolean local_initiator,
- WockyContact *peer,
- WockyJingleDialect dialect,
- gboolean local_hold);
-
-const gchar * wocky_jingle_session_detect (WockyStanza *stanza,
- WockyJingleAction *action, WockyJingleDialect *dialect);
-gboolean wocky_jingle_session_parse (WockyJingleSession *sess,
- WockyJingleAction action, WockyStanza *stanza, GError **error);
-WockyStanza *wocky_jingle_session_new_message (WockyJingleSession *sess,
- WockyJingleAction action, WockyNode **sess_node);
-
-void wocky_jingle_session_accept (WockyJingleSession *sess);
-gboolean wocky_jingle_session_terminate (WockyJingleSession *sess,
- WockyJingleReason reason,
- const gchar *text,
- GError **error);
-void wocky_jingle_session_remove_content (WockyJingleSession *sess,
- WockyJingleContent *c);
-
-WockyJingleContent *
-wocky_jingle_session_add_content (WockyJingleSession *sess,
- WockyJingleMediaType mtype,
- WockyJingleContentSenders senders,
- const char *name,
- const gchar *content_ns,
- const gchar *transport_ns);
-
-GType wocky_jingle_session_get_content_type (WockyJingleSession *);
-GList *wocky_jingle_session_get_contents (WockyJingleSession *sess);
-const gchar *wocky_jingle_session_get_peer_resource (
- WockyJingleSession *sess);
-const gchar *wocky_jingle_session_get_initiator (
- WockyJingleSession *sess);
-const gchar *wocky_jingle_session_get_sid (WockyJingleSession *sess);
-WockyJingleDialect wocky_jingle_session_get_dialect (WockyJingleSession *sess);
-
-gboolean wocky_jingle_session_can_modify_contents (WockyJingleSession *sess);
-gboolean wocky_jingle_session_peer_has_cap (
- WockyJingleSession *self,
- const gchar *cap_or_quirk);
-
-void wocky_jingle_session_send (
- WockyJingleSession *sess,
- WockyStanza *stanza);
-
-void wocky_jingle_session_set_local_hold (WockyJingleSession *sess,
- gboolean held);
-
-gboolean wocky_jingle_session_get_remote_hold (WockyJingleSession *sess);
-
-gboolean wocky_jingle_session_get_remote_ringing (WockyJingleSession *sess);
-
-gboolean wocky_jingle_session_defines_action (WockyJingleSession *sess,
- WockyJingleAction action);
-
-WockyContact *wocky_jingle_session_get_peer_contact (WockyJingleSession *self);
-const gchar *wocky_jingle_session_get_peer_jid (WockyJingleSession *sess);
-
-const gchar *wocky_jingle_session_get_reason_name (WockyJingleReason reason);
-
-WockyJingleFactory *wocky_jingle_session_get_factory (WockyJingleSession *self);
-WockyPorter *wocky_jingle_session_get_porter (WockyJingleSession *self);
-
-#endif /* __JINGLE_SESSION_H__ */
-
diff --git a/src/jingle-transport-google.c b/src/jingle-transport-google.c
deleted file mode 100644
index 59e166d53..000000000
--- a/src/jingle-transport-google.c
+++ /dev/null
@@ -1,644 +0,0 @@
-/*
- * jingle-transport-google.c - Source for WockyJingleTransportGoogle
- *
- * Copyright (C) 2008 Collabora Ltd.
- *
- * 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 "jingle-transport-google.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-
-#define DEBUG_FLAG GABBLE_DEBUG_MEDIA
-
-#include "debug.h"
-#include "jingle-content.h"
-#include "jingle-factory.h"
-#include "jingle-session.h"
-#include "namespaces.h"
-
-static void
-transport_iface_init (gpointer g_iface, gpointer iface_data);
-
-G_DEFINE_TYPE_WITH_CODE (WockyJingleTransportGoogle,
- wocky_jingle_transport_google, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (WOCKY_TYPE_JINGLE_TRANSPORT_IFACE,
- transport_iface_init));
-
-/* signal enum */
-enum
-{
- NEW_CANDIDATES,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = {0};
-
-/* properties */
-enum
-{
- PROP_CONTENT = 1,
- PROP_TRANSPORT_NS,
- PROP_STATE,
- LAST_PROPERTY
-};
-
-struct _WockyJingleTransportGooglePrivate
-{
- WockyJingleContent *content;
- WockyJingleTransportState state;
- gchar *transport_ns;
-
- /* Component names or jingle-share transport 'channels'
- g_strdup'd component name => GINT_TO_POINTER (component id) */
- GHashTable *component_names;
-
- GList *local_candidates;
-
- /* A pointer into "local_candidates" list to mark the
- * candidates that are still not transmitted, or NULL
- * if all of them are transmitted. */
-
- GList *pending_candidates;
- GList *remote_candidates;
- gboolean dispose_has_run;
-};
-
-static void
-wocky_jingle_transport_google_init (WockyJingleTransportGoogle *obj)
-{
- WockyJingleTransportGooglePrivate *priv =
- G_TYPE_INSTANCE_GET_PRIVATE (obj, WOCKY_TYPE_JINGLE_TRANSPORT_GOOGLE,
- WockyJingleTransportGooglePrivate);
- obj->priv = priv;
-
- priv->component_names = g_hash_table_new_full (g_str_hash, g_str_equal,
- g_free, NULL);
-
- priv->dispose_has_run = FALSE;
-}
-
-static void
-wocky_jingle_transport_google_dispose (GObject *object)
-{
- WockyJingleTransportGoogle *trans = WOCKY_JINGLE_TRANSPORT_GOOGLE (object);
- WockyJingleTransportGooglePrivate *priv = trans->priv;
-
- if (priv->dispose_has_run)
- return;
-
- DEBUG ("dispose called");
- priv->dispose_has_run = TRUE;
-
- g_hash_table_unref (priv->component_names);
- priv->component_names = NULL;
-
- jingle_transport_free_candidates (priv->remote_candidates);
- priv->remote_candidates = NULL;
-
- jingle_transport_free_candidates (priv->local_candidates);
- priv->local_candidates = NULL;
-
- g_free (priv->transport_ns);
- priv->transport_ns = NULL;
-
- if (G_OBJECT_CLASS (wocky_jingle_transport_google_parent_class)->dispose)
- G_OBJECT_CLASS (wocky_jingle_transport_google_parent_class)->dispose (object);
-}
-
-static void
-wocky_jingle_transport_google_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- WockyJingleTransportGoogle *trans = WOCKY_JINGLE_TRANSPORT_GOOGLE (object);
- WockyJingleTransportGooglePrivate *priv = trans->priv;
-
- switch (property_id) {
- case PROP_CONTENT:
- g_value_set_object (value, priv->content);
- break;
- case PROP_TRANSPORT_NS:
- g_value_set_string (value, priv->transport_ns);
- break;
- case PROP_STATE:
- g_value_set_uint (value, priv->state);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-wocky_jingle_transport_google_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- WockyJingleTransportGoogle *trans = WOCKY_JINGLE_TRANSPORT_GOOGLE (object);
- WockyJingleTransportGooglePrivate *priv = trans->priv;
-
- switch (property_id) {
- case PROP_CONTENT:
- priv->content = g_value_get_object (value);
- break;
- case PROP_TRANSPORT_NS:
- g_free (priv->transport_ns);
- priv->transport_ns = g_value_dup_string (value);
- break;
- case PROP_STATE:
- priv->state = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-wocky_jingle_transport_google_class_init (WockyJingleTransportGoogleClass *cls)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (cls);
- GParamSpec *param_spec;
-
- g_type_class_add_private (cls, sizeof (WockyJingleTransportGooglePrivate));
-
- object_class->get_property = wocky_jingle_transport_google_get_property;
- object_class->set_property = wocky_jingle_transport_google_set_property;
- object_class->dispose = wocky_jingle_transport_google_dispose;
-
- /* property definitions */
- param_spec = g_param_spec_object ("content", "WockyJingleContent object",
- "Jingle content object using this transport.",
- WOCKY_TYPE_JINGLE_CONTENT,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_CONTENT, param_spec);
-
- param_spec = g_param_spec_string ("transport-ns", "Transport namespace",
- "Namespace identifying the transport type.",
- NULL,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_TRANSPORT_NS, param_spec);
-
- param_spec = g_param_spec_uint ("state",
- "Connection state for the transport.",
- "Enum specifying the connection state of the transport.",
- WOCKY_JINGLE_TRANSPORT_STATE_DISCONNECTED,
- WOCKY_JINGLE_TRANSPORT_STATE_CONNECTED,
- WOCKY_JINGLE_TRANSPORT_STATE_DISCONNECTED,
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_STATE, param_spec);
-
- /* signal definitions */
- signals[NEW_CANDIDATES] = g_signal_new (
- "new-candidates",
- G_TYPE_FROM_CLASS (cls),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);
-
-}
-
-static void
-parse_candidates (WockyJingleTransportIface *obj,
- WockyNode *transport_node, GError **error)
-{
- WockyJingleTransportGoogle *t = WOCKY_JINGLE_TRANSPORT_GOOGLE (obj);
- WockyJingleTransportGooglePrivate *priv = t->priv;
- GList *candidates = NULL;
- WockyNodeIter i;
- WockyNode *node;
-
- wocky_node_iter_init (&i, transport_node, "candidate", NULL);
- while (wocky_node_iter_next (&i, &node))
- {
- const gchar *name, *address, *user, *pass, *str;
- guint port, net, gen, component;
- int pref;
- WockyJingleTransportProtocol proto;
- WockyJingleCandidateType ctype;
- WockyJingleCandidate *c;
-
- name = wocky_node_get_attribute (node, "name");
- if (name == NULL)
- break;
-
- if (!g_hash_table_lookup_extended (priv->component_names, name,
- NULL, NULL))
- {
- DEBUG ("component name %s unknown to this transport", name);
- continue;
- }
-
- component = GPOINTER_TO_INT (g_hash_table_lookup (priv->component_names,
- name));
- address = wocky_node_get_attribute (node, "address");
- if (address == NULL)
- break;
-
- str = wocky_node_get_attribute (node, "port");
- if (str == NULL)
- break;
- port = atoi (str);
-
- str = wocky_node_get_attribute (node, "protocol");
- if (str == NULL)
- break;
-
- if (!wocky_strdiff (str, "udp"))
- {
- proto = WOCKY_JINGLE_TRANSPORT_PROTOCOL_UDP;
- }
- else if (!wocky_strdiff (str, "tcp"))
- {
- /* candiates on port 443 must be "ssltcp" */
- if (port == 443)
- break;
-
- proto = WOCKY_JINGLE_TRANSPORT_PROTOCOL_TCP;
- }
- else if (!wocky_strdiff (str, "ssltcp"))
- {
- /* "ssltcp" must use port 443 */
- if (port != 443)
- break;
-
- /* we really don't care about "ssltcp" otherwise */
- proto = WOCKY_JINGLE_TRANSPORT_PROTOCOL_TCP;
- }
- else
- {
- /* unknown protocol */
- DEBUG ("unknown protocol: %s", str);
- break;
- }
-
- str = wocky_node_get_attribute (node, "preference");
- if (str == NULL)
- break;
-
- pref = g_ascii_strtod (str, NULL) * 65536;
-
- str = wocky_node_get_attribute (node, "type");
- if (str == NULL)
- break;
-
- if (!wocky_strdiff (str, "local"))
- {
- ctype = WOCKY_JINGLE_CANDIDATE_TYPE_LOCAL;
- }
- else if (!wocky_strdiff (str, "stun"))
- {
- ctype = WOCKY_JINGLE_CANDIDATE_TYPE_STUN;
- }
- else if (!wocky_strdiff (str, "relay"))
- {
- ctype = WOCKY_JINGLE_CANDIDATE_TYPE_RELAY;
- }
- else
- {
- /* unknown candidate type */
- DEBUG ("unknown candidate type: %s", str);
- break;
- }
-
- user = wocky_node_get_attribute (node, "username");
- if (user == NULL)
- break;
-
- pass = wocky_node_get_attribute (node, "password");
- if (pass == NULL)
- break;
-
- str = wocky_node_get_attribute (node, "network");
- if (str == NULL)
- break;
- net = atoi (str);
-
- str = wocky_node_get_attribute (node, "generation");
- if (str == NULL)
- break;
- gen = atoi (str);
-
- str = wocky_node_get_attribute (node, "component");
- if (str != NULL)
- component = atoi (str);
-
- c = wocky_jingle_candidate_new (proto, ctype, NULL, component,
- address, port, gen, pref, user, pass, net);
-
- candidates = g_list_append (candidates, c);
- }
-
- if (wocky_node_iter_next (&i, NULL))
- {
- DEBUG ("not all nodes were processed, reporting error");
- /* rollback these */
- jingle_transport_free_candidates (candidates);
- g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST,
- "invalid candidate");
- return;
- }
-
- DEBUG ("emitting %d new remote candidates", g_list_length (candidates));
-
- g_signal_emit (obj, signals[NEW_CANDIDATES], 0, candidates);
-
- /* append them to the known remote candidates */
- priv->remote_candidates = g_list_concat (priv->remote_candidates, candidates);
-}
-
-static void
-transmit_candidates (WockyJingleTransportGoogle *transport,
- const gchar *name,
- GList *candidates)
-{
- WockyJingleTransportGooglePrivate *priv = transport->priv;
- GList *li;
- WockyStanza *msg;
- WockyNode *trans_node, *sess_node;
-
- if (candidates == NULL)
- return;
-
- msg = wocky_jingle_session_new_message (priv->content->session,
- WOCKY_JINGLE_ACTION_TRANSPORT_INFO, &sess_node);
-
- wocky_jingle_content_produce_node (priv->content, sess_node, FALSE, TRUE,
- &trans_node);
-
- for (li = candidates; li; li = li->next)
- {
- WockyJingleCandidate *c = (WockyJingleCandidate *) li->data;
- gchar port_str[16], pref_str[16], comp_str[16], *type_str, *proto_str;
- WockyNode *cnode;
-
- sprintf (port_str, "%d", c->port);
- sprintf (pref_str, "%lf", c->preference / 65536.0);
- sprintf (comp_str, "%d", c->component);
-
- switch (c->type) {
- case WOCKY_JINGLE_CANDIDATE_TYPE_LOCAL:
- type_str = "local";
- break;
- case WOCKY_JINGLE_CANDIDATE_TYPE_STUN:
- type_str = "stun";
- break;
- case WOCKY_JINGLE_CANDIDATE_TYPE_RELAY:
- type_str = "relay";
- break;
- default:
- g_assert_not_reached ();
- }
-
- switch (c->protocol) {
- case WOCKY_JINGLE_TRANSPORT_PROTOCOL_UDP:
- proto_str = "udp";
- break;
- case WOCKY_JINGLE_TRANSPORT_PROTOCOL_TCP:
- if ((c->port == 443) && (c->type == WOCKY_JINGLE_CANDIDATE_TYPE_RELAY))
- proto_str = "ssltcp";
- else
- proto_str = "tcp";
- break;
- default:
- g_assert_not_reached ();
- }
-
- cnode = wocky_node_add_child (trans_node, "candidate");
- wocky_node_set_attributes (cnode,
- "address", c->address,
- "port", port_str,
- "username", c->username,
- "password", c->password != NULL ? c->password : "",
- "preference", pref_str,
- "protocol", proto_str,
- "type", type_str,
- "component", comp_str,
- "network", "0",
- "generation", "0",
- NULL);
-
- wocky_node_set_attribute (cnode, "name", name);
- }
-
- wocky_porter_send_iq_async (
- wocky_jingle_session_get_porter (priv->content->session), msg,
- NULL, NULL, NULL);
- g_object_unref (msg);
-}
-
-/* Groups @candidates into rtp and rtcp and sends each group in its own
- * transport-info. This works around old Gabble, which rejected transport-info
- * stanzas containing non-rtp candidates.
- */
-static void
-group_and_transmit_candidates (WockyJingleTransportGoogle *transport,
- GList *candidates)
-{
- WockyJingleTransportGooglePrivate *priv = transport->priv;
- GList *all_candidates = NULL;
- WockyJingleMediaType media;
- GList *li;
- GList *cands;
-
- for (li = candidates; li != NULL; li = g_list_next (li))
- {
- WockyJingleCandidate *c = li->data;
-
- for (cands = all_candidates; cands != NULL; cands = g_list_next (cands))
- {
- WockyJingleCandidate *c2 = ((GList *) cands->data)->data;
-
- if (c->component == c2->component)
- {
- break;
- }
- }
- if (cands == NULL)
- {
- all_candidates = g_list_prepend (all_candidates, NULL);
- cands = all_candidates;
- }
-
- cands->data = g_list_prepend (cands->data, c);
- }
-
- g_object_get (priv->content, "media-type", &media, NULL);
-
- for (cands = all_candidates; cands != NULL; cands = g_list_next (cands))
- {
- GHashTableIter iter;
- gpointer key, value;
- gchar *name = NULL;
- WockyJingleCandidate *c = ((GList *) cands->data)->data;
-
- g_hash_table_iter_init (&iter, priv->component_names);
- while (g_hash_table_iter_next (&iter, &key, &value))
- {
- if (GPOINTER_TO_INT (value) == c->component)
- {
- name = key;
- break;
- }
- }
- if (name)
- {
- transmit_candidates (transport, name, cands->data);
- }
- else
- {
- DEBUG ("Ignoring unknown component %d", c->component);
- }
- g_list_free (cands->data);
- }
-
- g_list_free (all_candidates);
-}
-
-/* Takes in a list of slice-allocated WockyJingleCandidate structs */
-static void
-new_local_candidates (WockyJingleTransportIface *obj, GList *new_candidates)
-{
- WockyJingleTransportGoogle *transport =
- WOCKY_JINGLE_TRANSPORT_GOOGLE (obj);
- WockyJingleTransportGooglePrivate *priv = transport->priv;
-
- priv->local_candidates = g_list_concat (priv->local_candidates,
- new_candidates);
-
- /* If all previous candidates have been signalled, set the new
- * ones as pending. If there are existing pending candidates,
- * the new ones will just be appended to that list. */
- if (priv->pending_candidates == NULL)
- priv->pending_candidates = new_candidates;
-}
-
-static void
-send_candidates (WockyJingleTransportIface *obj, gboolean all)
-{
- WockyJingleTransportGoogle *transport =
- WOCKY_JINGLE_TRANSPORT_GOOGLE (obj);
- WockyJingleTransportGooglePrivate *priv = transport->priv;
-
- if (all)
- {
- /* for gtalk3, we might have to retransmit everything */
- group_and_transmit_candidates (transport, priv->local_candidates);
- priv->pending_candidates = NULL;
- }
- else
- {
- /* If the content became ready after we wanted to transmit
- * these originally, we are called to transmit when it them */
- if (priv->pending_candidates != NULL)
- {
- group_and_transmit_candidates (transport, priv->pending_candidates);
- priv->pending_candidates = NULL;
- }
- }
-}
-
-static GList *
-get_local_candidates (WockyJingleTransportIface *iface)
-{
- WockyJingleTransportGoogle *transport =
- WOCKY_JINGLE_TRANSPORT_GOOGLE (iface);
- WockyJingleTransportGooglePrivate *priv = transport->priv;
-
- return priv->local_candidates;
-}
-
-static GList *
-get_remote_candidates (WockyJingleTransportIface *iface)
-{
- WockyJingleTransportGoogle *transport =
- WOCKY_JINGLE_TRANSPORT_GOOGLE (iface);
- WockyJingleTransportGooglePrivate *priv = transport->priv;
-
- return priv->remote_candidates;
-}
-
-static WockyJingleTransportType
-get_transport_type (void)
-{
- return JINGLE_TRANSPORT_GOOGLE_P2P;
-}
-
-static void
-transport_iface_init (gpointer g_iface, gpointer iface_data)
-{
- WockyJingleTransportIfaceClass *klass = (WockyJingleTransportIfaceClass *) g_iface;
-
- klass->parse_candidates = parse_candidates;
-
- klass->new_local_candidates = new_local_candidates;
- /* Not implementing inject_candidates: gtalk-p2p candidates are always sent
- * in transport-info or equivalent.
- */
- klass->send_candidates = send_candidates;
-
- klass->get_remote_candidates = get_remote_candidates;
- klass->get_local_candidates = get_local_candidates;
- klass->get_transport_type = get_transport_type;
-}
-
-/* Returns FALSE if the component name already exists */
-gboolean
-jingle_transport_google_set_component_name (
- WockyJingleTransportGoogle *transport,
- const gchar *name, guint component_id)
-{
- WockyJingleTransportGooglePrivate *priv = transport->priv;
-
- if (g_hash_table_lookup_extended (priv->component_names, name, NULL, NULL))
- return FALSE;
-
- g_hash_table_insert (priv->component_names, g_strdup (name),
- GINT_TO_POINTER (component_id));
-
- return TRUE;
-}
-
-void
-jingle_transport_google_register (WockyJingleFactory *factory)
-{
- /* GTalk libjingle0.3 dialect */
- wocky_jingle_factory_register_transport (factory, "",
- WOCKY_TYPE_JINGLE_TRANSPORT_GOOGLE);
-
- /* GTalk libjingle0.4 dialect */
- wocky_jingle_factory_register_transport (factory,
- NS_GOOGLE_TRANSPORT_P2P,
- WOCKY_TYPE_JINGLE_TRANSPORT_GOOGLE);
-}
-
diff --git a/src/jingle-transport-google.h b/src/jingle-transport-google.h
deleted file mode 100644
index ee2313969..000000000
--- a/src/jingle-transport-google.h
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * jingle-transport-google.h - Header for WockyJingleTransportGoogle
- * Copyright (C) 2008 Collabora Ltd.
- *
- * 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 __JINGLE_TRANSPORT_GOOGLE_H__
-#define __JINGLE_TRANSPORT_GOOGLE_H__
-
-#include <glib-object.h>
-
-#include "jingle-types.h"
-
-G_BEGIN_DECLS
-
-typedef struct _WockyJingleTransportGoogleClass WockyJingleTransportGoogleClass;
-
-GType wocky_jingle_transport_google_get_type (void);
-
-/* TYPE MACROS */
-#define WOCKY_TYPE_JINGLE_TRANSPORT_GOOGLE \
- (wocky_jingle_transport_google_get_type ())
-#define WOCKY_JINGLE_TRANSPORT_GOOGLE(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), WOCKY_TYPE_JINGLE_TRANSPORT_GOOGLE, \
- WockyJingleTransportGoogle))
-#define WOCKY_JINGLE_TRANSPORT_GOOGLE_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), WOCKY_TYPE_JINGLE_TRANSPORT_GOOGLE, \
- WockyJingleTransportGoogleClass))
-#define WOCKY_IS_JINGLE_TRANSPORT_GOOGLE(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), WOCKY_TYPE_JINGLE_TRANSPORT_GOOGLE))
-#define WOCKY_IS_JINGLE_TRANSPORT_GOOGLE_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), WOCKY_TYPE_JINGLE_TRANSPORT_GOOGLE))
-#define WOCKY_JINGLE_TRANSPORT_GOOGLE_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), WOCKY_TYPE_JINGLE_TRANSPORT_GOOGLE, \
- WockyJingleTransportGoogleClass))
-
-struct _WockyJingleTransportGoogleClass {
- GObjectClass parent_class;
-};
-
-typedef struct _WockyJingleTransportGooglePrivate WockyJingleTransportGooglePrivate;
-
-struct _WockyJingleTransportGoogle {
- GObject parent;
- WockyJingleTransportGooglePrivate *priv;
-};
-
-void jingle_transport_google_register (WockyJingleFactory *factory);
-
-gboolean jingle_transport_google_set_component_name (
- WockyJingleTransportGoogle *transport,
- const gchar *name, guint component_id);
-
-#endif /* __JINGLE_TRANSPORT_GOOGLE_H__ */
-
diff --git a/src/jingle-transport-iceudp.c b/src/jingle-transport-iceudp.c
deleted file mode 100644
index 55b3f396c..000000000
--- a/src/jingle-transport-iceudp.c
+++ /dev/null
@@ -1,617 +0,0 @@
-/*
- * jingle-transport-iceudp.c - Source for WockyJingleTransportIceUdp
- *
- * Copyright (C) 2008 Collabora Ltd.
- *
- * 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 "jingle-transport-iceudp.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-
-#define DEBUG_FLAG GABBLE_DEBUG_MEDIA
-
-#include "debug.h"
-#include "jingle-content.h"
-#include "jingle-factory.h"
-#include "jingle-session.h"
-#include "namespaces.h"
-
-static void
-transport_iface_init (gpointer g_iface, gpointer iface_data);
-
-G_DEFINE_TYPE_WITH_CODE (WockyJingleTransportIceUdp,
- wocky_jingle_transport_iceudp, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (WOCKY_TYPE_JINGLE_TRANSPORT_IFACE,
- transport_iface_init));
-
-/* signal enum */
-enum
-{
- NEW_CANDIDATES,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = {0};
-
-/* properties */
-enum
-{
- PROP_CONTENT = 1,
- PROP_TRANSPORT_NS,
- PROP_STATE,
- LAST_PROPERTY
-};
-
-struct _WockyJingleTransportIceUdpPrivate
-{
- WockyJingleContent *content;
- WockyJingleTransportState state;
- gchar *transport_ns;
-
- GList *local_candidates;
-
- /* A pointer into "local_candidates" list to mark the
- * candidates that are still not transmitted, or NULL
- * if all of them are transmitted. */
-
- GList *pending_candidates;
- GList *remote_candidates;
-
- gchar *ufrag;
- gchar *pwd;
-
- /* next ID to send with a candidate */
- int id_sequence;
-
- gboolean dispose_has_run;
-};
-
-static void
-wocky_jingle_transport_iceudp_init (WockyJingleTransportIceUdp *obj)
-{
- WockyJingleTransportIceUdpPrivate *priv =
- G_TYPE_INSTANCE_GET_PRIVATE (obj, WOCKY_TYPE_JINGLE_TRANSPORT_ICEUDP,
- WockyJingleTransportIceUdpPrivate);
- obj->priv = priv;
-
- priv->id_sequence = 1;
- priv->dispose_has_run = FALSE;
-}
-
-static void
-wocky_jingle_transport_iceudp_dispose (GObject *object)
-{
- WockyJingleTransportIceUdp *trans = WOCKY_JINGLE_TRANSPORT_ICEUDP (object);
- WockyJingleTransportIceUdpPrivate *priv = trans->priv;
-
- if (priv->dispose_has_run)
- return;
-
- DEBUG ("dispose called");
- priv->dispose_has_run = TRUE;
-
- jingle_transport_free_candidates (priv->remote_candidates);
- priv->remote_candidates = NULL;
-
- jingle_transport_free_candidates (priv->local_candidates);
- priv->local_candidates = NULL;
-
- g_free (priv->transport_ns);
- priv->transport_ns = NULL;
-
- g_free (priv->ufrag);
- priv->ufrag = NULL;
-
- g_free (priv->pwd);
- priv->pwd = NULL;
-
- if (G_OBJECT_CLASS (wocky_jingle_transport_iceudp_parent_class)->dispose)
- G_OBJECT_CLASS (wocky_jingle_transport_iceudp_parent_class)->dispose (object);
-}
-
-static void
-wocky_jingle_transport_iceudp_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- WockyJingleTransportIceUdp *trans = WOCKY_JINGLE_TRANSPORT_ICEUDP (object);
- WockyJingleTransportIceUdpPrivate *priv = trans->priv;
-
- switch (property_id) {
- case PROP_CONTENT:
- g_value_set_object (value, priv->content);
- break;
- case PROP_TRANSPORT_NS:
- g_value_set_string (value, priv->transport_ns);
- break;
- case PROP_STATE:
- g_value_set_uint (value, priv->state);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-wocky_jingle_transport_iceudp_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- WockyJingleTransportIceUdp *trans = WOCKY_JINGLE_TRANSPORT_ICEUDP (object);
- WockyJingleTransportIceUdpPrivate *priv = trans->priv;
-
- switch (property_id) {
- case PROP_CONTENT:
- priv->content = g_value_get_object (value);
- break;
- case PROP_TRANSPORT_NS:
- g_free (priv->transport_ns);
- priv->transport_ns = g_value_dup_string (value);
- break;
- case PROP_STATE:
- priv->state = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-wocky_jingle_transport_iceudp_class_init (WockyJingleTransportIceUdpClass *cls)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (cls);
- GParamSpec *param_spec;
-
- g_type_class_add_private (cls, sizeof (WockyJingleTransportIceUdpPrivate));
-
- object_class->get_property = wocky_jingle_transport_iceudp_get_property;
- object_class->set_property = wocky_jingle_transport_iceudp_set_property;
- object_class->dispose = wocky_jingle_transport_iceudp_dispose;
-
- /* property definitions */
- param_spec = g_param_spec_object ("content", "WockyJingleContent object",
- "Jingle content object using this transport.",
- WOCKY_TYPE_JINGLE_CONTENT,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_CONTENT, param_spec);
-
- param_spec = g_param_spec_string ("transport-ns", "Transport namespace",
- "Namespace identifying the transport type.",
- NULL,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_TRANSPORT_NS, param_spec);
-
- param_spec = g_param_spec_uint ("state",
- "Connection state for the transport.",
- "Enum specifying the connection state of the transport.",
- WOCKY_JINGLE_TRANSPORT_STATE_DISCONNECTED,
- WOCKY_JINGLE_TRANSPORT_STATE_CONNECTED,
- WOCKY_JINGLE_TRANSPORT_STATE_DISCONNECTED,
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_STATE, param_spec);
-
- /* signal definitions */
- signals[NEW_CANDIDATES] = g_signal_new (
- "new-candidates",
- G_TYPE_FROM_CLASS (cls),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);
-
-}
-
-static void
-parse_candidates (WockyJingleTransportIface *obj,
- WockyNode *transport_node, GError **error)
-{
- WockyJingleTransportIceUdp *t = WOCKY_JINGLE_TRANSPORT_ICEUDP (obj);
- WockyJingleTransportIceUdpPrivate *priv = t->priv;
- gboolean node_contains_a_candidate = FALSE;
- GList *candidates = NULL;
- WockyNodeIter i;
- WockyNode *node;
-
- DEBUG ("called");
-
- wocky_node_iter_init (&i, transport_node, "candidate", NULL);
- while (wocky_node_iter_next (&i, &node))
- {
- const gchar *id, *address, *user, *pass, *str;
- guint port, net, gen, component = 1;
- gdouble pref;
- WockyJingleTransportProtocol proto;
- WockyJingleCandidateType ctype;
- WockyJingleCandidate *c;
-
- node_contains_a_candidate = TRUE;
-
- id = wocky_node_get_attribute (node, "foundation");
- if (id == NULL)
- {
- DEBUG ("candidate doesn't contain foundation");
- continue;
- }
-
- address = wocky_node_get_attribute (node, "ip");
- if (address == NULL)
- {
- DEBUG ("candidate doesn't contain ip");
- continue;
- }
-
- str = wocky_node_get_attribute (node, "port");
- if (str == NULL)
- {
- DEBUG ("candidate doesn't contain port");
- continue;
- }
- port = atoi (str);
-
- str = wocky_node_get_attribute (node, "protocol");
- if (str == NULL)
- {
- DEBUG ("candidate doesn't contain protocol");
- continue;
- }
-
- if (!wocky_strdiff (str, "udp"))
- {
- proto = WOCKY_JINGLE_TRANSPORT_PROTOCOL_UDP;
- }
- else
- {
- /* unknown protocol */
- DEBUG ("unknown protocol: %s", str);
- continue;
- }
-
- str = wocky_node_get_attribute (node, "priority");
- if (str == NULL)
- {
- DEBUG ("candidate doesn't contain priority");
- continue;
- }
- pref = g_ascii_strtod (str, NULL);
-
- str = wocky_node_get_attribute (node, "type");
- if (str == NULL)
- {
- DEBUG ("candidate doesn't contain type");
- continue;
- }
-
- if (!wocky_strdiff (str, "host"))
- {
- ctype = WOCKY_JINGLE_CANDIDATE_TYPE_LOCAL;
- }
- else if (!wocky_strdiff (str, "srflx") || !wocky_strdiff (str, "prflx"))
- {
- /* FIXME Strictly speaking a prflx candidate should be a different
- * type, but the TP spec has now way to distinguish and it doesn't
- * matter much anyway.. */
- ctype = WOCKY_JINGLE_CANDIDATE_TYPE_STUN;
- }
- else if (!wocky_strdiff (str, "relay"))
- {
- ctype = WOCKY_JINGLE_CANDIDATE_TYPE_RELAY;
- }
- else
- {
- /* unknown candidate type */
- DEBUG ("unknown candidate type: %s", str);
- continue;
- }
-
- user = wocky_node_get_attribute (transport_node, "ufrag");
- if (user == NULL)
- {
- DEBUG ("transport doesn't contain ufrag");
- continue;
- }
-
- pass = wocky_node_get_attribute (transport_node, "pwd");
- if (pass == NULL)
- {
- DEBUG ("transport doesn't contain pwd");
- continue;
- }
-
- str = wocky_node_get_attribute (node, "network");
- if (str == NULL)
- {
- DEBUG ("candidate doesn't contain network");
- continue;
- }
- net = atoi (str);
-
- str = wocky_node_get_attribute (node, "generation");
- if (str == NULL)
- {
- DEBUG ("candidate doesn't contain generation");
- continue;
- }
- gen = atoi (str);
-
- str = wocky_node_get_attribute (node, "component");
- if (str == NULL)
- {
- DEBUG ("candidate doesn't contain component");
- continue;
- }
- component = atoi (str);
-
- if (priv->ufrag == NULL || strcmp (priv->ufrag, user))
- {
- g_free (priv->ufrag);
- priv->ufrag = g_strdup (user);
- }
-
- if (priv->pwd == NULL || strcmp (priv->pwd, pass))
- {
- g_free (priv->pwd);
- priv->pwd = g_strdup (pass);
- }
-
- c = wocky_jingle_candidate_new (proto, ctype, id, component,
- address, port, gen, pref, user, pass, net);
-
- candidates = g_list_append (candidates, c);
- }
-
- if (candidates == NULL)
- {
- if (node_contains_a_candidate)
- {
- NODE_DEBUG (transport_node,
- "couldn't parse any of the given candidates");
- g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST,
- "could not parse any of the given candidates");
- }
- else
- {
- DEBUG ("no candidates in this stanza");
- }
- }
- else
- {
- DEBUG ("emitting %d new remote candidates", g_list_length (candidates));
-
- g_signal_emit (obj, signals[NEW_CANDIDATES], 0, candidates);
-
- priv->remote_candidates = g_list_concat (priv->remote_candidates,
- candidates);
- }
-}
-
-static void
-inject_candidates (WockyJingleTransportIface *obj,
- WockyNode *transport_node)
-{
- WockyJingleTransportIceUdp *self = WOCKY_JINGLE_TRANSPORT_ICEUDP (obj);
- WockyJingleTransportIceUdpPrivate *priv = self->priv;
- const gchar *username = NULL;
-
- for (; priv->pending_candidates != NULL;
- priv->pending_candidates = priv->pending_candidates->next)
- {
- WockyJingleCandidate *c = (WockyJingleCandidate *) priv->pending_candidates->data;
- gchar port_str[16], pref_str[16], comp_str[16], id_str[16],
- *type_str, *proto_str;
- WockyNode *cnode;
-
- if (username == NULL)
- {
- username = c->username;
- }
- else if (wocky_strdiff (username, c->username))
- {
- DEBUG ("found a candidate with a different username (%s not %s); "
- "will send in a separate batch", c->username, username);
- break;
- }
-
- sprintf (pref_str, "%d", c->preference);
- sprintf (port_str, "%d", c->port);
- sprintf (comp_str, "%d", c->component);
- sprintf (id_str, "%d", priv->id_sequence++);
-
- switch (c->type) {
- case WOCKY_JINGLE_CANDIDATE_TYPE_LOCAL:
- type_str = "host";
- break;
- case WOCKY_JINGLE_CANDIDATE_TYPE_STUN:
- type_str = "srflx";
- break;
- case WOCKY_JINGLE_CANDIDATE_TYPE_RELAY:
- type_str = "relay";
- break;
- default:
- DEBUG ("skipping candidate with unknown type %u", c->type);
- continue;
- }
-
- switch (c->protocol) {
- case WOCKY_JINGLE_TRANSPORT_PROTOCOL_UDP:
- proto_str = "udp";
- break;
- case WOCKY_JINGLE_TRANSPORT_PROTOCOL_TCP:
- DEBUG ("ignoring TCP candidate");
- continue;
- default:
- DEBUG ("skipping candidate with unknown protocol %u", c->protocol);
- continue;
- }
-
- wocky_node_set_attributes (transport_node,
- "ufrag", c->username,
- "pwd", c->password,
- NULL);
-
- cnode = wocky_node_add_child (transport_node, "candidate");
- wocky_node_set_attributes (cnode,
- "ip", c->address,
- "port", port_str,
- "priority", pref_str,
- "protocol", proto_str,
- "type", type_str,
- "component", comp_str,
- "foundation", c->id,
- "id", id_str,
- "network", "0",
- "generation", "0",
- NULL);
- }
-}
-
-/* We never have to retransmit candidates we've already sent, so we ignore
- * @all.
- */
-static void
-send_candidates (WockyJingleTransportIface *iface,
- gboolean all G_GNUC_UNUSED)
-{
- WockyJingleTransportIceUdp *self = WOCKY_JINGLE_TRANSPORT_ICEUDP (iface);
- WockyJingleTransportIceUdpPrivate *priv = self->priv;
-
- while (priv->pending_candidates != NULL)
- {
- WockyNode *trans_node, *sess_node;
- WockyStanza *msg;
-
- msg = wocky_jingle_session_new_message (priv->content->session,
- WOCKY_JINGLE_ACTION_TRANSPORT_INFO, &sess_node);
-
- wocky_jingle_content_produce_node (priv->content, sess_node, FALSE,
- TRUE, &trans_node);
- inject_candidates (iface, trans_node);
-
- wocky_porter_send_iq_async (
- wocky_jingle_session_get_porter (priv->content->session), msg,
- NULL, NULL, NULL);
- g_object_unref (msg);
- }
-
- DEBUG ("sent all pending candidates");
-}
-
-/* Takes in a list of slice-allocated WockyJingleCandidate structs */
-static void
-new_local_candidates (WockyJingleTransportIface *obj, GList *new_candidates)
-{
- WockyJingleTransportIceUdp *transport =
- WOCKY_JINGLE_TRANSPORT_ICEUDP (obj);
- WockyJingleTransportIceUdpPrivate *priv = transport->priv;
-
- priv->local_candidates = g_list_concat (priv->local_candidates,
- new_candidates);
-
- /* If all previous candidates have been signalled, set the new
- * ones as pending. If there are existing pending candidates,
- * the new ones will just be appended to that list. */
- if (priv->pending_candidates == NULL)
- priv->pending_candidates = new_candidates;
-}
-
-static GList *
-get_remote_candidates (WockyJingleTransportIface *iface)
-{
- WockyJingleTransportIceUdp *transport =
- WOCKY_JINGLE_TRANSPORT_ICEUDP (iface);
- WockyJingleTransportIceUdpPrivate *priv = transport->priv;
-
- return priv->remote_candidates;
-}
-
-static GList *
-get_local_candidates (WockyJingleTransportIface *iface)
-{
- WockyJingleTransportIceUdp *transport =
- WOCKY_JINGLE_TRANSPORT_ICEUDP (iface);
- WockyJingleTransportIceUdpPrivate *priv = transport->priv;
-
- return priv->local_candidates;
-}
-
-static WockyJingleTransportType
-get_transport_type (void)
-{
- return JINGLE_TRANSPORT_ICE_UDP;
-}
-
-static gboolean
-get_credentials (WockyJingleTransportIface *iface,
- gchar **ufrag, gchar **pwd)
-{
- WockyJingleTransportIceUdp *transport =
- WOCKY_JINGLE_TRANSPORT_ICEUDP (iface);
- WockyJingleTransportIceUdpPrivate *priv = transport->priv;
-
- if (!priv->ufrag || !priv->pwd)
- return FALSE;
-
- if (ufrag)
- *ufrag = priv->ufrag;
- if (pwd)
- *pwd = priv->pwd;
-
- return TRUE;
-}
-
-
-static void
-transport_iface_init (gpointer g_iface, gpointer iface_data)
-{
- WockyJingleTransportIfaceClass *klass = (WockyJingleTransportIfaceClass *) g_iface;
-
- klass->parse_candidates = parse_candidates;
-
- klass->new_local_candidates = new_local_candidates;
- klass->inject_candidates = inject_candidates;
- klass->send_candidates = send_candidates;
-
- klass->get_remote_candidates = get_remote_candidates;
- klass->get_local_candidates = get_local_candidates;
- klass->get_transport_type = get_transport_type;
- klass->get_credentials = get_credentials;
-}
-
-void
-jingle_transport_iceudp_register (WockyJingleFactory *factory)
-{
- wocky_jingle_factory_register_transport (factory,
- NS_JINGLE_TRANSPORT_ICEUDP,
- WOCKY_TYPE_JINGLE_TRANSPORT_ICEUDP);
-}
-
diff --git a/src/jingle-transport-iceudp.h b/src/jingle-transport-iceudp.h
deleted file mode 100644
index 35540a0fe..000000000
--- a/src/jingle-transport-iceudp.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * jingle-transport-iceudp.h - Header for WockyJingleTransportIceUdp
- * Copyright (C) 2008 Collabora Ltd.
- *
- * 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 __JINGLE_TRANSPORT_ICEUDP_H__
-#define __JINGLE_TRANSPORT_ICEUDP_H__
-
-#include <glib-object.h>
-
-#include "jingle-types.h"
-
-G_BEGIN_DECLS
-
-typedef struct _WockyJingleTransportIceUdpClass WockyJingleTransportIceUdpClass;
-
-GType wocky_jingle_transport_iceudp_get_type (void);
-
-/* TYPE MACROS */
-#define WOCKY_TYPE_JINGLE_TRANSPORT_ICEUDP \
- (wocky_jingle_transport_iceudp_get_type ())
-#define WOCKY_JINGLE_TRANSPORT_ICEUDP(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), WOCKY_TYPE_JINGLE_TRANSPORT_ICEUDP, \
- WockyJingleTransportIceUdp))
-#define WOCKY_JINGLE_TRANSPORT_ICEUDP_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), WOCKY_TYPE_JINGLE_TRANSPORT_ICEUDP, \
- WockyJingleTransportIceUdpClass))
-#define WOCKY_IS_JINGLE_TRANSPORT_ICEUDP(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), WOCKY_TYPE_JINGLE_TRANSPORT_ICEUDP))
-#define WOCKY_IS_JINGLE_TRANSPORT_ICEUDP_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), WOCKY_TYPE_JINGLE_TRANSPORT_ICEUDP))
-#define WOCKY_JINGLE_TRANSPORT_ICEUDP_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), WOCKY_TYPE_JINGLE_TRANSPORT_ICEUDP, \
- WockyJingleTransportIceUdpClass))
-
-struct _WockyJingleTransportIceUdpClass {
- GObjectClass parent_class;
-};
-
-typedef struct _WockyJingleTransportIceUdpPrivate WockyJingleTransportIceUdpPrivate;
-
-struct _WockyJingleTransportIceUdp {
- GObject parent;
- WockyJingleTransportIceUdpPrivate *priv;
-};
-
-void jingle_transport_iceudp_register (WockyJingleFactory *factory);
-
-#endif /* __JINGLE_TRANSPORT_ICEUDP_H__ */
-
diff --git a/src/jingle-transport-iface.c b/src/jingle-transport-iface.c
deleted file mode 100644
index 58ca76924..000000000
--- a/src/jingle-transport-iface.c
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * jingle-transport-iface.c - Source for WockyJingleTransportIface
- * Copyright (C) 2007-2008 Collabora Ltd.
- *
- * 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 "jingle-transport-iface.h"
-
-#include <glib.h>
-
-#include "connection.h"
-#include "jingle-content.h"
-#include "jingle-session.h"
-
-WockyJingleTransportIface *
-wocky_jingle_transport_iface_new (GType type,
- WockyJingleContent *content,
- const gchar *transport_ns)
-{
- g_return_val_if_fail (g_type_is_a (type, WOCKY_TYPE_JINGLE_TRANSPORT_IFACE),
- NULL);
-
- return g_object_new (type,
- "content", content,
- "transport-ns", transport_ns,
- NULL);
-}
-
-void
-wocky_jingle_transport_iface_parse_candidates (WockyJingleTransportIface *self,
- WockyNode *node, GError **error)
-{
- void (*virtual_method)(WockyJingleTransportIface *,
- WockyNode *, GError **) =
- WOCKY_JINGLE_TRANSPORT_IFACE_GET_CLASS (self)->parse_candidates;
-
- g_assert (virtual_method != NULL);
- return virtual_method (self, node, error);
-}
-
-/* Takes in a list of slice-allocated WockyJingleCandidate structs */
-void
-wocky_jingle_transport_iface_new_local_candidates (WockyJingleTransportIface *self,
- GList *candidates)
-{
- void (*virtual_method)(WockyJingleTransportIface *,
- GList *) =
- WOCKY_JINGLE_TRANSPORT_IFACE_GET_CLASS (self)->new_local_candidates;
-
- g_assert (virtual_method != NULL);
- virtual_method (self, candidates);
-}
-
-/* Inserts candidates into the given <transport/> node, or equivalent, of a
- * session-initiate, session-accept, content-add or content-accept action.
- */
-void
-wocky_jingle_transport_iface_inject_candidates (
- WockyJingleTransportIface *self,
- WockyNode *transport_node)
-{
- void (*virtual_method)(WockyJingleTransportIface *, WockyNode *) =
- WOCKY_JINGLE_TRANSPORT_IFACE_GET_CLASS (self)->inject_candidates;
-
- if (virtual_method != NULL)
- virtual_method (self, transport_node);
-}
-
-/* Transmits outstanding or all candidates (if applicable and @all is set). */
-void
-wocky_jingle_transport_iface_send_candidates (
- WockyJingleTransportIface *self,
- gboolean all)
-{
- void (*virtual_method) (WockyJingleTransportIface *, gboolean) =
- WOCKY_JINGLE_TRANSPORT_IFACE_GET_CLASS (self)->send_candidates;
-
- if (virtual_method != NULL)
- virtual_method (self, all);
-}
-
-/* Returns TRUE if and only if @self has enough candidates to inject into a
- * {session,content}-accept, and is connected.
- */
-gboolean
-wocky_jingle_transport_iface_can_accept (WockyJingleTransportIface *self)
-{
- WockyJingleTransportState state;
- gboolean (*m) (WockyJingleTransportIface *) =
- WOCKY_JINGLE_TRANSPORT_IFACE_GET_CLASS (self)->can_accept;
-
- g_object_get (self, "state", &state, NULL);
-
- if (state != WOCKY_JINGLE_TRANSPORT_STATE_CONNECTED)
- return FALSE;
-
- /* Only Raw UDP *needs* candidates in order to accept. */
- if (m != NULL)
- return m (self);
- else
- return TRUE;
-}
-
-GList *
-wocky_jingle_transport_iface_get_remote_candidates (
- WockyJingleTransportIface *self)
-{
- GList * (*virtual_method)(WockyJingleTransportIface *) =
- WOCKY_JINGLE_TRANSPORT_IFACE_GET_CLASS (self)->get_remote_candidates;
-
- g_assert (virtual_method != NULL);
- return virtual_method (self);
-}
-
-GList *
-wocky_jingle_transport_iface_get_local_candidates (
- WockyJingleTransportIface *self)
-{
- GList * (*virtual_method)(WockyJingleTransportIface *) =
- WOCKY_JINGLE_TRANSPORT_IFACE_GET_CLASS (self)->get_local_candidates;
-
- g_assert (virtual_method != NULL);
- return virtual_method (self);
-}
-
-gboolean
-jingle_transport_get_credentials (WockyJingleTransportIface *self,
- gchar **ufrag, gchar **pwd)
-{
- WockyJingleTransportIfaceClass *klass =
- WOCKY_JINGLE_TRANSPORT_IFACE_GET_CLASS (self);
-
- if (klass->get_credentials)
- return klass->get_credentials (self, ufrag, pwd);
- else
- return FALSE;
-}
-
-WockyJingleTransportType
-wocky_jingle_transport_iface_get_transport_type (WockyJingleTransportIface *self)
-{
- WockyJingleTransportType (*virtual_method)(void) =
- WOCKY_JINGLE_TRANSPORT_IFACE_GET_CLASS (self)->get_transport_type;
-
- g_assert (virtual_method != NULL);
- return virtual_method ();
-}
-
-static void
-wocky_jingle_transport_iface_base_init (gpointer klass)
-{
- static gboolean initialized = FALSE;
-
- if (!initialized)
- {
- GParamSpec *param_spec;
-
- param_spec = g_param_spec_object (
- "content",
- "WockyJingleContent object",
- "Jingle content that's using this jingle transport object.",
- WOCKY_TYPE_JINGLE_CONTENT,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
- g_object_interface_install_property (klass, param_spec);
-
- param_spec = g_param_spec_string (
- "transport-ns",
- "Transport namespace",
- "Namespace identifying the transport type.",
- NULL,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
- g_object_interface_install_property (klass, param_spec);
-
- param_spec = g_param_spec_uint (
- "state",
- "Connection state for the transport.",
- "Enum specifying the connection state of the transport.",
- WOCKY_JINGLE_TRANSPORT_STATE_DISCONNECTED,
- WOCKY_JINGLE_TRANSPORT_STATE_CONNECTED,
- WOCKY_JINGLE_TRANSPORT_STATE_DISCONNECTED,
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
-
- g_object_interface_install_property (klass, param_spec);
-
- initialized = TRUE;
- }
-}
-
-GType
-wocky_jingle_transport_iface_get_type (void)
-{
- static GType type = 0;
-
- if (type == 0) {
- static const GTypeInfo info = {
- sizeof (WockyJingleTransportIfaceClass),
- wocky_jingle_transport_iface_base_init, /* 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, "WockyJingleTransportIface",
- &info, 0);
- }
-
- return type;
-}
-
-WockyJingleCandidate *
-wocky_jingle_candidate_new (WockyJingleTransportProtocol protocol,
- WockyJingleCandidateType type, const gchar *id, int component,
- const gchar *address, int port, int generation, int preference,
- const gchar *username, const gchar *password, int network)
-{
- WockyJingleCandidate *c = g_slice_new0 (WockyJingleCandidate);
-
- c->protocol = protocol;
- c->type = type;
- c->id = g_strdup (id);
- c->address = g_strdup (address);
- c->component = component;
- c->port = port;
- c->generation = generation;
- c->preference = preference;
- c->username = g_strdup (username);
- c->password = g_strdup (password);
- c->network = network;
-
- return c;
-}
-
-void
-wocky_jingle_candidate_free (WockyJingleCandidate *c)
-{
- g_free (c->id);
- g_free (c->address);
- g_free (c->username);
- g_free (c->password);
-
- g_slice_free (WockyJingleCandidate, c);
-}
-
-void
-jingle_transport_free_candidates (GList *candidates)
-{
- while (candidates != NULL)
- {
- WockyJingleCandidate *c = (WockyJingleCandidate *) candidates->data;
- wocky_jingle_candidate_free (c);
- candidates = g_list_remove (candidates, c);
- }
-}
-
diff --git a/src/jingle-transport-iface.h b/src/jingle-transport-iface.h
deleted file mode 100644
index 0801e28ce..000000000
--- a/src/jingle-transport-iface.h
+++ /dev/null
@@ -1,109 +0,0 @@
-/*
- * jingle-transport-iface.h - Header for WockyJingleTransportIface
- * Copyright (C) 2007-2008 Collabora Ltd.
- *
- * 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 __WOCKY_JINGLE_TRANSPORT_IFACE_H__
-#define __WOCKY_JINGLE_TRANSPORT_IFACE_H__
-
-#include <glib-object.h>
-#include <wocky/wocky.h>
-
-#include "jingle-factory.h"
-#include "jingle-types.h"
-
-G_BEGIN_DECLS
-
-typedef enum
-{
- WOCKY_JINGLE_TRANSPORT_STATE_DISCONNECTED,
- WOCKY_JINGLE_TRANSPORT_STATE_CONNECTING,
- WOCKY_JINGLE_TRANSPORT_STATE_CONNECTED
-} WockyJingleTransportState;
-
-typedef struct _WockyJingleTransportIface WockyJingleTransportIface;
-typedef struct _WockyJingleTransportIfaceClass WockyJingleTransportIfaceClass;
-
-struct _WockyJingleTransportIfaceClass {
- GTypeInterface parent;
-
- void (*parse_candidates) (WockyJingleTransportIface *,
- WockyNode *, GError **);
-
- void (*new_local_candidates) (WockyJingleTransportIface *, GList *);
- void (*inject_candidates) (WockyJingleTransportIface *,
- WockyNode *transport_node);
- void (*send_candidates) (WockyJingleTransportIface *, gboolean all);
- gboolean (*can_accept) (WockyJingleTransportIface *);
-
- GList * (*get_remote_candidates) (WockyJingleTransportIface *);
- GList * (*get_local_candidates) (WockyJingleTransportIface *);
- gboolean (*get_credentials) (WockyJingleTransportIface *,
- gchar **ufrag, gchar **pwd);
-
- WockyJingleTransportType (*get_transport_type) (void);
-};
-
-GType wocky_jingle_transport_iface_get_type (void);
-
-/* TYPE MACROS */
-#define WOCKY_TYPE_JINGLE_TRANSPORT_IFACE \
- (wocky_jingle_transport_iface_get_type ())
-#define WOCKY_JINGLE_TRANSPORT_IFACE(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), WOCKY_TYPE_JINGLE_TRANSPORT_IFACE, WockyJingleTransportIface))
-#define WOCKY_IS_JINGLE_TRANSPORT_IFACE(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), WOCKY_TYPE_JINGLE_TRANSPORT_IFACE))
-#define WOCKY_JINGLE_TRANSPORT_IFACE_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_INTERFACE ((obj), WOCKY_TYPE_JINGLE_TRANSPORT_IFACE,\
- WockyJingleTransportIfaceClass))
-
-void wocky_jingle_transport_iface_parse_candidates (WockyJingleTransportIface *,
- WockyNode *, GError **);
-
-void wocky_jingle_transport_iface_new_local_candidates (
- WockyJingleTransportIface *self,
- GList *candidates);
-void wocky_jingle_transport_iface_inject_candidates (
- WockyJingleTransportIface *self,
- WockyNode *transport_node);
-void wocky_jingle_transport_iface_send_candidates (
- WockyJingleTransportIface *self,
- gboolean all);
-gboolean wocky_jingle_transport_iface_can_accept (
- WockyJingleTransportIface *self);
-
-GList *wocky_jingle_transport_iface_get_remote_candidates (WockyJingleTransportIface *);
-GList *wocky_jingle_transport_iface_get_local_candidates (WockyJingleTransportIface *);
-WockyJingleTransportType wocky_jingle_transport_iface_get_transport_type (WockyJingleTransportIface *);
-gboolean jingle_transport_get_credentials (WockyJingleTransportIface *,
- gchar **ufrag, gchar **pwd);
-
-WockyJingleTransportIface *wocky_jingle_transport_iface_new (
- GType type, WockyJingleContent *content, const gchar *transport_ns);
-
-WockyJingleCandidate *wocky_jingle_candidate_new (WockyJingleTransportProtocol protocol,
- WockyJingleCandidateType type, const gchar *id, int component,
- const gchar *address, int port, int generation, int preference,
- const gchar *username, const gchar *password, int network);
-
-void wocky_jingle_candidate_free (WockyJingleCandidate *c);
-void jingle_transport_free_candidates (GList *candidates);
-
-
-G_END_DECLS
-
-#endif /* #ifndef __WOCKY_JINGLE_TRANSPORT_IFACE_H__ */
diff --git a/src/jingle-transport-rawudp.c b/src/jingle-transport-rawudp.c
deleted file mode 100644
index 668a8afd9..000000000
--- a/src/jingle-transport-rawudp.c
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
- * jingle-transport-rawudp.c - Source for WockyJingleTransportRawUdp
- *
- * Copyright (C) 2008 Collabora Ltd.
- *
- * 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 "jingle-transport-rawudp.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <glib.h>
-
-#define DEBUG_FLAG GABBLE_DEBUG_MEDIA
-
-#include "connection.h"
-#include "debug.h"
-#include "jingle-content.h"
-#include "jingle-factory.h"
-#include "jingle-session.h"
-#include "namespaces.h"
-
-static void
-transport_iface_init (gpointer g_iface, gpointer iface_data);
-
-G_DEFINE_TYPE_WITH_CODE (WockyJingleTransportRawUdp,
- wocky_jingle_transport_rawudp, G_TYPE_OBJECT,
- G_IMPLEMENT_INTERFACE (WOCKY_TYPE_JINGLE_TRANSPORT_IFACE,
- transport_iface_init));
-
-/* signal enum */
-enum
-{
- NEW_CANDIDATES,
- LAST_SIGNAL
-};
-
-static guint signals[LAST_SIGNAL] = {0};
-
-/* properties */
-enum
-{
- PROP_CONTENT = 1,
- PROP_TRANSPORT_NS,
- PROP_STATE,
- LAST_PROPERTY
-};
-
-struct _WockyJingleTransportRawUdpPrivate
-{
- WockyJingleContent *content;
- WockyJingleTransportState state;
- gchar *transport_ns;
-
- GList *local_candidates;
- GList *remote_candidates;
- gboolean dispose_has_run;
-};
-
-static void
-wocky_jingle_transport_rawudp_init (WockyJingleTransportRawUdp *obj)
-{
- WockyJingleTransportRawUdpPrivate *priv =
- G_TYPE_INSTANCE_GET_PRIVATE (obj, WOCKY_TYPE_JINGLE_TRANSPORT_RAWUDP,
- WockyJingleTransportRawUdpPrivate);
- obj->priv = priv;
-
- priv->dispose_has_run = FALSE;
-}
-
-static void
-wocky_jingle_transport_rawudp_dispose (GObject *object)
-{
- WockyJingleTransportRawUdp *trans = WOCKY_JINGLE_TRANSPORT_RAWUDP (object);
- WockyJingleTransportRawUdpPrivate *priv = trans->priv;
-
- if (priv->dispose_has_run)
- return;
-
- DEBUG ("dispose called");
- priv->dispose_has_run = TRUE;
-
- jingle_transport_free_candidates (priv->remote_candidates);
- priv->remote_candidates = NULL;
-
- jingle_transport_free_candidates (priv->local_candidates);
- priv->local_candidates = NULL;
-
- g_free (priv->transport_ns);
- priv->transport_ns = NULL;
-
- if (G_OBJECT_CLASS (wocky_jingle_transport_rawudp_parent_class)->dispose)
- G_OBJECT_CLASS (wocky_jingle_transport_rawudp_parent_class)->dispose (object);
-}
-
-static void
-wocky_jingle_transport_rawudp_get_property (GObject *object,
- guint property_id,
- GValue *value,
- GParamSpec *pspec)
-{
- WockyJingleTransportRawUdp *trans = WOCKY_JINGLE_TRANSPORT_RAWUDP (object);
- WockyJingleTransportRawUdpPrivate *priv = trans->priv;
-
- switch (property_id) {
- case PROP_CONTENT:
- g_value_set_object (value, priv->content);
- break;
- case PROP_TRANSPORT_NS:
- g_value_set_string (value, priv->transport_ns);
- break;
- case PROP_STATE:
- g_value_set_uint (value, priv->state);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-wocky_jingle_transport_rawudp_set_property (GObject *object,
- guint property_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- WockyJingleTransportRawUdp *trans = WOCKY_JINGLE_TRANSPORT_RAWUDP (object);
- WockyJingleTransportRawUdpPrivate *priv = trans->priv;
-
- switch (property_id) {
- case PROP_CONTENT:
- priv->content = g_value_get_object (value);
- break;
- case PROP_TRANSPORT_NS:
- g_free (priv->transport_ns);
- priv->transport_ns = g_value_dup_string (value);
- break;
- case PROP_STATE:
- priv->state = g_value_get_uint (value);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
- break;
- }
-}
-
-static void
-wocky_jingle_transport_rawudp_class_init (WockyJingleTransportRawUdpClass *cls)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (cls);
- GParamSpec *param_spec;
-
- g_type_class_add_private (cls, sizeof (WockyJingleTransportRawUdpPrivate));
-
- object_class->get_property = wocky_jingle_transport_rawudp_get_property;
- object_class->set_property = wocky_jingle_transport_rawudp_set_property;
- object_class->dispose = wocky_jingle_transport_rawudp_dispose;
-
- /* property definitions */
- param_spec = g_param_spec_object ("content", "WockyJingleContent object",
- "Jingle content object using this transport.",
- WOCKY_TYPE_JINGLE_CONTENT,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_CONTENT, param_spec);
-
- param_spec = g_param_spec_string ("transport-ns", "Transport namespace",
- "Namespace identifying the transport type.",
- NULL,
- G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_TRANSPORT_NS, param_spec);
-
- param_spec = g_param_spec_uint ("state",
- "Connection state for the transport.",
- "Enum specifying the connection state of the transport.",
- WOCKY_JINGLE_TRANSPORT_STATE_DISCONNECTED,
- WOCKY_JINGLE_TRANSPORT_STATE_CONNECTED,
- WOCKY_JINGLE_TRANSPORT_STATE_DISCONNECTED,
- G_PARAM_READWRITE |
- G_PARAM_STATIC_NAME |
- G_PARAM_STATIC_NICK |
- G_PARAM_STATIC_BLURB);
- g_object_class_install_property (object_class, PROP_STATE, param_spec);
-
- /* signal definitions */
- signals[NEW_CANDIDATES] = g_signal_new (
- "new-candidates",
- G_TYPE_FROM_CLASS (cls),
- G_SIGNAL_RUN_LAST,
- 0,
- NULL, NULL,
- g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);
-
-}
-
-static void
-parse_candidates (WockyJingleTransportIface *obj,
- WockyNode *transport_node, GError **error)
-{
- WockyJingleTransportRawUdp *t = WOCKY_JINGLE_TRANSPORT_RAWUDP (obj);
- WockyJingleTransportRawUdpPrivate *priv = t->priv;
- GList *candidates = NULL;
- WockyNodeIter i;
- WockyNode *node;
-
- DEBUG ("called");
-
- if (priv->remote_candidates != NULL)
- {
- DEBUG ("already have raw udp candidates, ignoring extra ones");
- return;
- }
-
- wocky_node_iter_init (&i, transport_node, "candidate", NULL);
- while (wocky_node_iter_next (&i, &node))
- {
- const gchar *id, *ip, *str;
- guint port, gen, component = 1;
- WockyJingleCandidate *c;
-
- str = wocky_node_get_attribute (node, "component");
- if (str != NULL)
- component = atoi (str);
-
- if ((component != 1) && (component != 2))
- {
- DEBUG ("Ignoring non-RTP/RTCP component %d", component);
- continue;
- }
-
- id = wocky_node_get_attribute (node, "id");
- if (id == NULL)
- break;
-
- ip = wocky_node_get_attribute (node, "ip");
- if (ip == NULL)
- break;
-
- str = wocky_node_get_attribute (node, "port");
- if (str == NULL)
- break;
- port = atoi (str);
-
- str = wocky_node_get_attribute (node, "generation");
- if (str == NULL)
- break;
- gen = atoi (str);
-
- c = wocky_jingle_candidate_new (WOCKY_JINGLE_TRANSPORT_PROTOCOL_UDP,
- WOCKY_JINGLE_CANDIDATE_TYPE_LOCAL, id, component, ip, port,
- gen, 1.0, NULL, NULL, 0);
-
- candidates = g_list_append (candidates, c);
- }
-
- if (wocky_node_iter_next (&i, NULL))
- {
- DEBUG ("not all nodes were processed, reporting error");
- /* rollback these */
- jingle_transport_free_candidates (candidates);
- g_set_error (error, WOCKY_XMPP_ERROR, WOCKY_XMPP_ERROR_BAD_REQUEST,
- "invalid candidate");
- return;
- }
-
- DEBUG ("emitting %d new remote candidates", g_list_length (candidates));
- g_signal_emit (obj, signals[NEW_CANDIDATES], 0, candidates);
- priv->remote_candidates = candidates;
-}
-
-static void
-inject_candidates (WockyJingleTransportIface *obj,
- WockyNode *transport_node)
-{
- WockyJingleTransportRawUdp *self = WOCKY_JINGLE_TRANSPORT_RAWUDP (obj);
- WockyJingleTransportRawUdpPrivate *priv = self->priv;
- WockyJingleCandidate *c;
- GList *li;
- gchar port_str[16], comp_str[16];
- WockyNode *cnode;
-
- /* If we don't have the local candidates yet, we should've waited with
- * the session initiation, or can_accept would have returned FALSE.
- */
- g_assert (priv->local_candidates != NULL);
-
- for (li = priv->local_candidates; li != NULL; li = li->next)
- {
- c = (WockyJingleCandidate *) li->data;
- sprintf (port_str, "%d", c->port);
- sprintf (comp_str, "%d", c->component);
-
- cnode = wocky_node_add_child (transport_node, "candidate");
- wocky_node_set_attributes (cnode,
- "ip", c->address,
- "port", port_str,
- "generation", "0",
- "id", c->id,
- "component", comp_str,
- NULL);
- }
-}
-
-/* Takes in a list of slice-allocated WockyJingleCandidate structs */
-static void
-new_local_candidates (WockyJingleTransportIface *obj, GList *new_candidates)
-{
- WockyJingleTransportRawUdp *transport =
- WOCKY_JINGLE_TRANSPORT_RAWUDP (obj);
- WockyJingleTransportRawUdpPrivate *priv = transport->priv;
-
- if (priv->local_candidates != NULL)
- {
- DEBUG ("ignoring new local candidates for RAW UDP");
- jingle_transport_free_candidates (new_candidates);
- return;
- }
-
- priv->local_candidates = new_candidates;
-}
-
-static gboolean
-can_accept (WockyJingleTransportIface *iface)
-{
- WockyJingleTransportRawUdp *self = WOCKY_JINGLE_TRANSPORT_RAWUDP (iface);
-
- return (self->priv->local_candidates != NULL);
-}
-
-static GList *
-get_local_candidates (WockyJingleTransportIface *iface)
-{
- WockyJingleTransportRawUdp *transport =
- WOCKY_JINGLE_TRANSPORT_RAWUDP (iface);
- WockyJingleTransportRawUdpPrivate *priv = transport->priv;
-
- return priv->local_candidates;
-}
-
-static GList *
-get_remote_candidates (WockyJingleTransportIface *iface)
-{
- WockyJingleTransportRawUdp *transport =
- WOCKY_JINGLE_TRANSPORT_RAWUDP (iface);
- WockyJingleTransportRawUdpPrivate *priv = transport->priv;
-
- return priv->remote_candidates;
-}
-
-static WockyJingleTransportType
-get_transport_type (void)
-{
- DEBUG ("called");
-
- return JINGLE_TRANSPORT_RAW_UDP;
-}
-
-static void
-transport_iface_init (gpointer g_iface, gpointer iface_data)
-{
- WockyJingleTransportIfaceClass *klass = (WockyJingleTransportIfaceClass *) g_iface;
-
- klass->parse_candidates = parse_candidates;
-
- klass->new_local_candidates = new_local_candidates;
- klass->inject_candidates = inject_candidates;
- /* Not implementing _send: XEP-0177 says that the candidates live in
- * content-{add,accept}, not in transport-info.
- */
- klass->can_accept = can_accept;
-
- klass->get_remote_candidates = get_remote_candidates;
- klass->get_local_candidates = get_local_candidates;
- klass->get_transport_type = get_transport_type;
-}
-
-void
-jingle_transport_rawudp_register (WockyJingleFactory *factory)
-{
- wocky_jingle_factory_register_transport (factory,
- NS_JINGLE_TRANSPORT_RAWUDP,
- WOCKY_TYPE_JINGLE_TRANSPORT_RAWUDP);
-}
-
diff --git a/src/jingle-transport-rawudp.h b/src/jingle-transport-rawudp.h
deleted file mode 100644
index ff10815a1..000000000
--- a/src/jingle-transport-rawudp.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * jingle-transport-rawudp.h - Header for WockyJingleTransportRawUdp
- * Copyright (C) 2008 Collabora Ltd.
- *
- * 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 __JINGLE_TRANSPORT_RAWUDP_H__
-#define __JINGLE_TRANSPORT_RAWUDP_H__
-
-#include <glib-object.h>
-
-#include "jingle-types.h"
-
-G_BEGIN_DECLS
-
-typedef struct _WockyJingleTransportRawUdpClass WockyJingleTransportRawUdpClass;
-
-GType wocky_jingle_transport_rawudp_get_type (void);
-
-/* TYPE MACROS */
-#define WOCKY_TYPE_JINGLE_TRANSPORT_RAWUDP \
- (wocky_jingle_transport_rawudp_get_type ())
-#define WOCKY_JINGLE_TRANSPORT_RAWUDP(obj) \
- (G_TYPE_CHECK_INSTANCE_CAST((obj), WOCKY_TYPE_JINGLE_TRANSPORT_RAWUDP, \
- WockyJingleTransportRawUdp))
-#define WOCKY_JINGLE_TRANSPORT_RAWUDP_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_CAST((klass), WOCKY_TYPE_JINGLE_TRANSPORT_RAWUDP, \
- WockyJingleTransportRawUdpClass))
-#define WOCKY_IS_JINGLE_TRANSPORT_RAWUDP(obj) \
- (G_TYPE_CHECK_INSTANCE_TYPE((obj), WOCKY_TYPE_JINGLE_TRANSPORT_RAWUDP))
-#define WOCKY_IS_JINGLE_TRANSPORT_RAWUDP_CLASS(klass) \
- (G_TYPE_CHECK_CLASS_TYPE((klass), WOCKY_TYPE_JINGLE_TRANSPORT_RAWUDP))
-#define WOCKY_JINGLE_TRANSPORT_RAWUDP_GET_CLASS(obj) \
- (G_TYPE_INSTANCE_GET_CLASS ((obj), WOCKY_TYPE_JINGLE_TRANSPORT_RAWUDP, \
- WockyJingleTransportRawUdpClass))
-
-struct _WockyJingleTransportRawUdpClass {
- GObjectClass parent_class;
-};
-
-typedef struct _WockyJingleTransportRawUdpPrivate WockyJingleTransportRawUdpPrivate;
-
-struct _WockyJingleTransportRawUdp {
- GObject parent;
- WockyJingleTransportRawUdpPrivate *priv;
-};
-
-void jingle_transport_rawudp_register (WockyJingleFactory *factory);
-
-#endif /* __JINGLE_TRANSPORT_RAWUDP_H__ */
-
diff --git a/src/jingle-types.h b/src/jingle-types.h
deleted file mode 100644
index 50f4ef7f0..000000000
--- a/src/jingle-types.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- * jingle-types.h - Header for Jingle-related enums and typedefs
- * Copyright © 2008–2012 Collabora Ltd.
- *
- * 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_JINGLE_ENUMS_H
-#define GABBLE_JINGLE_ENUMS_H
-
-typedef struct _WockyJingleFactory WockyJingleFactory;
-typedef struct _WockyJingleSession WockyJingleSession;
-typedef struct _WockyJingleContent WockyJingleContent;
-typedef struct _WockyJingleTransportGoogle WockyJingleTransportGoogle;
-typedef struct _WockyJingleTransportRawUdp WockyJingleTransportRawUdp;
-typedef struct _WockyJingleTransportIceUdp WockyJingleTransportIceUdp;
-typedef struct _WockyJingleMediaRtp WockyJingleMediaRtp;
-typedef struct _WockyJingleCandidate WockyJingleCandidate;
-
-typedef enum { /*< skip >*/
- /* not a jingle message */
- WOCKY_JINGLE_DIALECT_ERROR,
- /* old libjingle3 gtalk variant */
- WOCKY_JINGLE_DIALECT_GTALK3,
- /* new gtalk variant */
- WOCKY_JINGLE_DIALECT_GTALK4,
- /* jingle in the old 0.15 version days */
- WOCKY_JINGLE_DIALECT_V015,
- /* current jingle standard */
- WOCKY_JINGLE_DIALECT_V032
-} WockyJingleDialect;
-
-#define WOCKY_JINGLE_DIALECT_IS_GOOGLE(d)\
- ((d == WOCKY_JINGLE_DIALECT_GTALK3) || (d == WOCKY_JINGLE_DIALECT_GTALK4))
-
-typedef enum { /*< skip >*/
- WOCKY_JINGLE_STATE_INVALID = -1,
- WOCKY_JINGLE_STATE_PENDING_CREATED = 0,
- WOCKY_JINGLE_STATE_PENDING_INITIATE_SENT,
- WOCKY_JINGLE_STATE_PENDING_INITIATED,
- WOCKY_JINGLE_STATE_PENDING_ACCEPT_SENT,
- WOCKY_JINGLE_STATE_ACTIVE,
- WOCKY_JINGLE_STATE_ENDED,
- WOCKY_N_JINGLE_STATES
-} WockyJingleState;
-
-typedef enum { /*< skip >*/
- WOCKY_JINGLE_ACTION_UNKNOWN,
- WOCKY_JINGLE_ACTION_CONTENT_ACCEPT,
- WOCKY_JINGLE_ACTION_CONTENT_ADD,
- WOCKY_JINGLE_ACTION_CONTENT_MODIFY,
- WOCKY_JINGLE_ACTION_CONTENT_REMOVE,
- WOCKY_JINGLE_ACTION_CONTENT_REPLACE,
- WOCKY_JINGLE_ACTION_CONTENT_REJECT,
- WOCKY_JINGLE_ACTION_SESSION_ACCEPT,
- WOCKY_JINGLE_ACTION_SESSION_INFO,
- WOCKY_JINGLE_ACTION_SESSION_INITIATE,
- WOCKY_JINGLE_ACTION_SESSION_TERMINATE,
- WOCKY_JINGLE_ACTION_TRANSPORT_INFO,
- WOCKY_JINGLE_ACTION_TRANSPORT_ACCEPT,
- WOCKY_JINGLE_ACTION_DESCRIPTION_INFO,
- WOCKY_JINGLE_ACTION_INFO
-} WockyJingleAction;
-
-typedef enum { /*< skip >*/
- WOCKY_JINGLE_CONTENT_SENDERS_NONE,
- WOCKY_JINGLE_CONTENT_SENDERS_INITIATOR,
- WOCKY_JINGLE_CONTENT_SENDERS_RESPONDER,
- WOCKY_JINGLE_CONTENT_SENDERS_BOTH
-} WockyJingleContentSenders;
-
-typedef enum { /*< skip >*/
- JINGLE_TRANSPORT_UNKNOWN,
- JINGLE_TRANSPORT_GOOGLE_P2P,
- JINGLE_TRANSPORT_RAW_UDP,
- JINGLE_TRANSPORT_ICE_UDP,
-} WockyJingleTransportType;
-
-typedef enum { /*< skip >*/
- WOCKY_JINGLE_TRANSPORT_PROTOCOL_UDP,
- WOCKY_JINGLE_TRANSPORT_PROTOCOL_TCP
-} WockyJingleTransportProtocol;
-
-typedef enum { /*< skip >*/
- WOCKY_JINGLE_CANDIDATE_TYPE_LOCAL,
- WOCKY_JINGLE_CANDIDATE_TYPE_STUN,
- WOCKY_JINGLE_CANDIDATE_TYPE_RELAY
-} WockyJingleCandidateType;
-
-typedef enum
-{
- WOCKY_JINGLE_REASON_UNKNOWN,
- WOCKY_JINGLE_REASON_ALTERNATIVE_SESSION,
- WOCKY_JINGLE_REASON_BUSY,
- WOCKY_JINGLE_REASON_CANCEL,
- WOCKY_JINGLE_REASON_CONNECTIVITY_ERROR,
- WOCKY_JINGLE_REASON_DECLINE,
- WOCKY_JINGLE_REASON_EXPIRED,
- WOCKY_JINGLE_REASON_FAILED_APPLICATION,
- WOCKY_JINGLE_REASON_FAILED_TRANSPORT,
- WOCKY_JINGLE_REASON_GENERAL_ERROR,
- WOCKY_JINGLE_REASON_GONE,
- WOCKY_JINGLE_REASON_INCOMPATIBLE_PARAMETERS,
- WOCKY_JINGLE_REASON_MEDIA_ERROR,
- WOCKY_JINGLE_REASON_SECURITY_ERROR,
- WOCKY_JINGLE_REASON_SUCCESS,
- WOCKY_JINGLE_REASON_TIMEOUT,
- WOCKY_JINGLE_REASON_UNSUPPORTED_APPLICATIONS,
- WOCKY_JINGLE_REASON_UNSUPPORTED_TRANSPORTS
-} WockyJingleReason;
-
-
-#endif /* GABBLE_JINGLE_ENUMS_H */