[pidgin] Add TCP and encryption support

David Woodhouse dwmw2 at fedoraproject.org
Fri Mar 13 01:38:14 UTC 2015


commit 608705019b962e0501d57f33145739f61a3d9161
Author: David Woodhouse <David.Woodhouse at intel.com>
Date:   Fri Mar 13 01:37:53 2015 +0000

    Add TCP and encryption support

 pidgin-2.10.11-gstreamer1.patch     | 253 +++++++++++----------
 pidgin-2.10.11-rtp-encryption.patch | 429 ++++++++++++++++++++++++++++++++++++
 pidgin-2.10.11-rtp-tcp.patch        | 127 +++++++++++
 pidgin.spec                         |  17 +-
 4 files changed, 694 insertions(+), 132 deletions(-)
---
diff --git a/pidgin-2.10.11-gstreamer1.patch b/pidgin-2.10.11-gstreamer1.patch
index 1dd0cfa..f36c4f8 100644
--- a/pidgin-2.10.11-gstreamer1.patch
+++ b/pidgin-2.10.11-gstreamer1.patch
@@ -1,26 +1,15 @@
-From 7ecf837441edc3c5de774e26c64f1499d2059193 Mon Sep 17 00:00:00 2001
-From: David Woodhouse <David.Woodhouse at intel.com>
-Date: Wed, 11 Mar 2015 11:39:19 +0000
-Subject: [PATCH] Support GStreamer 1.x and resync with trunk
 
----
- configure.ac                  | 153 ++++++++++++++++++------
- finch/Makefile.am             |   1 +
- libpurple/Makefile.am         |   2 +
- libpurple/data/purple.pc.in   |   1 +
- libpurple/example/Makefile.am |   1 +
- libpurple/media/backend-fs2.c | 272 ++++++++++++++++++++++++++++++------------
- libpurple/mediamanager.c      |  76 +++++++++---
- pidgin/Makefile.am            |   1 +
- pidgin/gtkmedia.c             |   5 +
- pidgin/plugins/vvconfig.c     |  24 +++-
- 10 files changed, 407 insertions(+), 129 deletions(-)
+# HG changeset patch
+# User David Woodhouse <David.Woodhouse at intel.com>
+# Date 1426073959 0
+# Node ID 2415067473ba10a2090d6130b93204a3b537b05c
+# Parent  6b4576edf2a694ab55d0d06d3643c44601a75b15
+Support GStreamer 1.x and resync with trunk
 
 diff --git a/configure.ac b/configure.ac
-index e2b5290..e5be8bd 100644
 --- a/configure.ac
 +++ b/configure.ac
-@@ -741,42 +741,115 @@ AM_GCONF_SOURCE_2
+@@ -741,42 +741,115 @@
  dnl #######################################################################
  dnl # Check for GStreamer
  dnl #######################################################################
@@ -157,7 +146,7 @@ index e2b5290..e5be8bd 100644
  			AC_SUBST(GSTINTERFACES_CFLAGS)
  			AC_SUBST(GSTINTERFACES_LIBS)
  		], [
-@@ -791,32 +864,43 @@ dnl #######################################################################
+@@ -791,32 +864,43 @@
  dnl # Check for Farstream
  dnl #######################################################################
  AC_ARG_ENABLE(farstream,
@@ -213,7 +202,7 @@ index e2b5290..e5be8bd 100644
  		AC_DEFINE(USE_VV, 1, [Use voice and video])
  	else
  		enable_vv="no"
-@@ -829,7 +913,7 @@ Or use --disable-vv if you do not need voice/video support.
+@@ -829,7 +913,7 @@
  		fi
  	fi
  fi
@@ -222,7 +211,7 @@ index e2b5290..e5be8bd 100644
  
  dnl #######################################################################
  dnl # Check for Internationalized Domain Name support
-@@ -2605,6 +2689,7 @@ echo Protocols to build dynamically : $DYNAMIC_PRPLS
+@@ -2605,6 +2689,7 @@
  echo Protocols to link statically.. : $STATIC_PRPLS
  echo
  echo Build with GStreamer support.. : $enable_gst
@@ -231,10 +220,9 @@ index e2b5290..e5be8bd 100644
  echo Build with voice and video.... : $enable_vv
  if test "x$enable_dbus" = "xyes" ; then
 diff --git a/finch/Makefile.am b/finch/Makefile.am
-index 85502d3..95976e8 100644
 --- a/finch/Makefile.am
 +++ b/finch/Makefile.am
-@@ -73,6 +73,7 @@ finch_LDADD = \
+@@ -73,6 +73,7 @@
  	$(LIBXML_LIBS) \
  	$(GNT_LIBS) \
  	$(GSTREAMER_LIBS) \
@@ -243,10 +231,9 @@ index 85502d3..95976e8 100644
  	$(top_builddir)/libpurple/libpurple.la
  
 diff --git a/libpurple/Makefile.am b/libpurple/Makefile.am
-index e8b6d2d..2e99c86 100644
 --- a/libpurple/Makefile.am
 +++ b/libpurple/Makefile.am
-@@ -308,6 +308,7 @@ libpurple_la_LIBADD = \
+@@ -308,6 +308,7 @@
  	$(INTLLIBS) \
  	$(FARSTREAM_LIBS) \
  	$(GSTREAMER_LIBS) \
@@ -254,7 +241,7 @@ index e8b6d2d..2e99c86 100644
  	$(GSTINTERFACES_LIBS) \
  	$(IDN_LIBS) \
  	ciphers/libpurple-ciphers.la \
-@@ -324,6 +325,7 @@ AM_CPPFLAGS = \
+@@ -324,6 +325,7 @@
  	$(LIBXML_CFLAGS) \
  	$(FARSTREAM_CFLAGS) \
  	$(GSTREAMER_CFLAGS) \
@@ -263,10 +250,9 @@ index e8b6d2d..2e99c86 100644
  	$(IDN_CFLAGS) \
  	$(NETWORKMANAGER_CFLAGS)
 diff --git a/libpurple/data/purple.pc.in b/libpurple/data/purple.pc.in
-index c776f6f..4685080 100644
 --- a/libpurple/data/purple.pc.in
 +++ b/libpurple/data/purple.pc.in
-@@ -5,6 +5,7 @@ includedir=@includedir@
+@@ -5,6 +5,7 @@
  datarootdir=@datarootdir@
  datadir=@datadir@
  sysconfdir=@sysconfdir@
@@ -275,10 +261,9 @@ index c776f6f..4685080 100644
  plugindir=${libdir}/purple- at PURPLE_MAJOR_VERSION@
  
 diff --git a/libpurple/example/Makefile.am b/libpurple/example/Makefile.am
-index 5834209..f5e8bb9 100644
 --- a/libpurple/example/Makefile.am
 +++ b/libpurple/example/Makefile.am
-@@ -8,6 +8,7 @@ nullclient_LDADD = \
+@@ -8,6 +8,7 @@
  	$(INTLLIBS) \
  	$(GLIB_LIBS) \
  	$(LIBXML_LIBS) \
@@ -287,7 +272,6 @@ index 5834209..f5e8bb9 100644
  
  AM_CPPFLAGS = \
 diff --git a/libpurple/media/backend-fs2.c b/libpurple/media/backend-fs2.c
-index 8e6c28c..4932080 100644
 --- a/libpurple/media/backend-fs2.c
 +++ b/libpurple/media/backend-fs2.c
 @@ -41,6 +41,7 @@
@@ -298,7 +282,7 @@ index 8e6c28c..4932080 100644
  #endif
  
  /** @copydoc _PurpleMediaBackendFs2Class */
-@@ -242,9 +243,17 @@ purple_media_network_protocol_from_fs(FsNetworkProtocol protocol)
+@@ -242,9 +243,17 @@
  	g_return_val_if_reached(PURPLE_MEDIA_NETWORK_PROTOCOL_TCP);
  }
  
@@ -316,7 +300,7 @@ index 8e6c28c..4932080 100644
  	if (GST_EVENT_TYPE(event) == GST_EVENT_CUSTOM_DOWNSTREAM
  		&& gst_event_has_name(event, "purple-unlink-tee")) {
  
-@@ -252,22 +261,40 @@ event_probe_cb(GstPad *srcpad, GstEvent *event, gboolean release_pad)
+@@ -252,22 +261,40 @@
  
  		gst_pad_unlink(srcpad, gst_pad_get_peer(srcpad));
  
@@ -357,7 +341,7 @@ index 8e6c28c..4932080 100644
  
  	if (GST_IS_GHOST_PAD(srcpad))
  		srcpad = gst_ghost_pad_get_target(GST_GHOST_PAD(srcpad));
-@@ -276,7 +303,11 @@ unlink_teepad_dynamic(GstPad *srcpad, gboolean release_pad)
+@@ -276,7 +303,11 @@
  		gst_event_new_custom(GST_EVENT_CUSTOM_DOWNSTREAM,
  			gst_structure_new("purple-unlink-tee",
  				"release-pad", G_TYPE_BOOLEAN, release_pad,
@@ -369,7 +353,7 @@ index 8e6c28c..4932080 100644
  				NULL)));
  }
  
-@@ -859,15 +890,31 @@ gst_msg_db_to_percent(GstMessage *msg, gchar *value_name)
+@@ -859,15 +890,31 @@
  	gdouble value_db;
  	gdouble percent;
  
@@ -403,7 +387,7 @@ index 8e6c28c..4932080 100644
  gst_handle_message_element(GstBus *bus, GstMessage *msg,
  		PurpleMediaBackendFs2 *self)
  {
-@@ -875,11 +922,12 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
+@@ -875,11 +922,12 @@
  			PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self);
  	GstElement *src = GST_ELEMENT(GST_MESSAGE_SRC(msg));
  	static guint level_id = 0;
@@ -417,7 +401,7 @@ index 8e6c28c..4932080 100644
  		GstElement *src = GST_ELEMENT(GST_MESSAGE_SRC(msg));
  		gchar *name;
  		gchar *participant = NULL;
-@@ -934,31 +982,63 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
+@@ -934,31 +982,63 @@
  		return;
  
  #ifdef HAVE_FARSIGHT
@@ -494,7 +478,7 @@ index 8e6c28c..4932080 100644
  			case FS_ERROR_UNKNOWN_CNAME:
  				/*
  				 * Unknown CName is only a problem for the
-@@ -975,22 +1055,22 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
+@@ -975,22 +1055,22 @@
  						"farstream-error: %i: %s\n",
  #endif
  						error_no,
@@ -524,7 +508,7 @@ index 8e6c28c..4932080 100644
  #ifdef HAVE_FARSIGHT
  			"farsight-new-local-candidate")) {
  #else
-@@ -1005,9 +1085,9 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
+@@ -1005,9 +1085,9 @@
  		PurpleMediaBackendFs2Stream *media_stream;
  		gchar *name;
  
@@ -536,7 +520,7 @@ index 8e6c28c..4932080 100644
  		local_candidate = g_value_get_boxed(value);
  
  		session = get_session_from_fs_stream(self, stream);
-@@ -1029,7 +1109,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
+@@ -1029,7 +1109,7 @@
  		g_signal_emit_by_name(self, "new-candidate",
  				session->id, name, candidate);
  		g_object_unref(candidate);
@@ -545,7 +529,7 @@ index 8e6c28c..4932080 100644
  #ifdef HAVE_FARSIGHT
  			"farsight-local-candidates-prepared")) {
  #else
-@@ -1041,7 +1121,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
+@@ -1041,7 +1121,7 @@
  		PurpleMediaBackendFs2Session *session;
  		gchar *name;
  
@@ -554,7 +538,7 @@ index 8e6c28c..4932080 100644
  		stream = g_value_get_object(value);
  		session = get_session_from_fs_stream(self, stream);
  
-@@ -1051,7 +1131,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
+@@ -1051,7 +1131,7 @@
  
  		g_signal_emit_by_name(self, "candidates-prepared",
  				session->id, name);
@@ -563,7 +547,7 @@ index 8e6c28c..4932080 100644
  #ifdef HAVE_FARSIGHT
  			"farsight-new-active-candidate-pair")) {
  #else
-@@ -1066,13 +1146,11 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
+@@ -1066,13 +1146,11 @@
  		PurpleMediaCandidate *lcandidate, *rcandidate;
  		gchar *name;
  
@@ -580,7 +564,7 @@ index 8e6c28c..4932080 100644
  		remote_candidate = g_value_get_boxed(value);
  
  		g_object_get(stream, "participant", &participant, NULL);
-@@ -1089,7 +1167,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
+@@ -1089,7 +1167,7 @@
  
  		g_object_unref(lcandidate);
  		g_object_unref(rcandidate);
@@ -589,7 +573,7 @@ index 8e6c28c..4932080 100644
  #ifdef HAVE_FARSIGHT
  			"farsight-recv-codecs-changed")) {
  #else
-@@ -1099,7 +1177,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
+@@ -1099,7 +1177,7 @@
  		GList *codecs;
  		FsCodec *codec;
  
@@ -598,7 +582,7 @@ index 8e6c28c..4932080 100644
  		codecs = g_value_get_boxed(value);
  		codec = codecs->data;
  
-@@ -1110,7 +1188,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
+@@ -1110,7 +1188,7 @@
  				"farstream-recv-codecs-changed: %s\n",
  #endif
  				codec->encoding_name);
@@ -607,7 +591,7 @@ index 8e6c28c..4932080 100644
  #ifdef HAVE_FARSIGHT
  			"farsight-component-state-changed")) {
  #else
-@@ -1121,9 +1199,9 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
+@@ -1121,9 +1199,9 @@
  		guint component;
  		const gchar *state;
  
@@ -619,7 +603,7 @@ index 8e6c28c..4932080 100644
  		component = g_value_get_uint(value);
  
  		switch (fsstate) {
-@@ -1158,7 +1236,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
+@@ -1158,7 +1236,7 @@
  #endif
  				"component: %u state: %s\n",
  				component, state);
@@ -628,7 +612,7 @@ index 8e6c28c..4932080 100644
  #ifdef HAVE_FARSIGHT
  			"farsight-send-codec-changed")) {
  #else
-@@ -1168,7 +1246,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
+@@ -1168,7 +1246,7 @@
  		FsCodec *codec;
  		gchar *codec_str;
  
@@ -637,7 +621,7 @@ index 8e6c28c..4932080 100644
  		codec = g_value_get_boxed(value);
  		codec_str = fs_codec_to_string(codec);
  
-@@ -1181,7 +1259,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
+@@ -1181,7 +1259,7 @@
  				codec_str);
  
  		g_free(codec_str);
@@ -646,7 +630,7 @@ index 8e6c28c..4932080 100644
  #ifdef HAVE_FARSIGHT
  			"farsight-codecs-changed")) {
  #else
-@@ -1191,7 +1269,7 @@ gst_handle_message_element(GstBus *bus, GstMessage *msg,
+@@ -1191,7 +1269,7 @@
  		FsSession *fssession;
  		GList *sessions;
  
@@ -655,7 +639,7 @@ index 8e6c28c..4932080 100644
  		fssession = g_value_get_object(value);
  		sessions = g_hash_table_get_values(priv->sessions);
  
-@@ -1635,7 +1713,11 @@ create_src(PurpleMediaBackendFs2 *self, const gchar *sess_id,
+@@ -1635,7 +1713,11 @@
  		srcpad = gst_element_get_static_pad(session->srcvalve, "src");
  		g_object_set(volume, "volume", input_volume, NULL);
  	} else {
@@ -667,7 +651,7 @@ index 8e6c28c..4932080 100644
  	}
  
  	purple_debug_info("backend-fs2", "connecting pad: %s\n",
-@@ -1645,11 +1727,14 @@ create_src(PurpleMediaBackendFs2 *self, const gchar *sess_id,
+@@ -1645,11 +1727,14 @@
  	gst_object_unref(session->src);
  	gst_object_unref(sinkpad);
  
@@ -684,7 +668,7 @@ index 8e6c28c..4932080 100644
  	return TRUE;
  }
  
-@@ -1853,14 +1938,10 @@ src_pad_added_cb(FsStream *fsstream, GstPad *srcpad,
+@@ -1853,14 +1938,10 @@
  			 *   audioresample ! audioconvert ! realsink
  			 */
  			stream->queue = gst_element_factory_make("queue", NULL);
@@ -703,7 +687,7 @@ index 8e6c28c..4932080 100644
  			sink = purple_media_manager_get_element(
  					purple_media_get_manager(priv->media),
  					PURPLE_MEDIA_RECV_AUDIO, priv->media,
-@@ -1879,10 +1960,12 @@ src_pad_added_cb(FsStream *fsstream, GstPad *srcpad,
+@@ -1879,10 +1960,12 @@
  			gst_element_link(stream->queue, stream->volume);
  			sink = stream->queue;
  		} else if (codec->media_type == FS_MEDIA_TYPE_VIDEO) {
@@ -720,7 +704,7 @@ index 8e6c28c..4932080 100644
  			g_object_set(G_OBJECT(sink), "async", FALSE, NULL);
  			gst_bin_add(GST_BIN(priv->confbin), sink);
  			gst_element_set_state(sink, GST_STATE_PLAYING);
-@@ -1896,7 +1979,11 @@ src_pad_added_cb(FsStream *fsstream, GstPad *srcpad,
+@@ -1896,7 +1979,11 @@
  		gst_element_link_many(stream->src, stream->tee, sink, NULL);
  	}
  
@@ -732,7 +716,7 @@ index 8e6c28c..4932080 100644
  	gst_pad_link(srcpad, sinkpad);
  	gst_object_unref(sinkpad);
  
-@@ -2078,8 +2165,8 @@ G_GNUC_END_IGNORE_DEPRECATIONS
+@@ -2078,8 +2165,8 @@
  	if (!fs_stream_set_transmitter(fsstream, transmitter,
  			_params, _num_params, &err)) {
  		purple_debug_error("backend-fs2",
@@ -743,20 +727,49 @@ index 8e6c28c..4932080 100644
  		g_clear_error(&err);
  		g_free(_params);
  		return FALSE;
-@@ -2398,14 +2485,44 @@ purple_media_backend_fs2_set_send_codec(PurpleMediaBackend *self,
+@@ -2398,38 +2485,6 @@
  	return TRUE;
  }
  
-+static const gchar **
-+purple_media_backend_fs2_get_available_params(void)
-+{
-+	static const gchar *supported_params[] = {
-+		"sdes-cname", "sdes-email", "sdes-location", "sdes-name", "sdes-note",
-+		"sdes-phone", "sdes-tool", NULL
-+	};
-+
-+	return supported_params;
-+}
+-static void
+-purple_media_backend_fs2_set_params(PurpleMediaBackend *self,
+-		guint num_params, GParameter *params)
+-{
+-	PurpleMediaBackendFs2Private *priv;
+-	const gchar **supported = purple_media_backend_fs2_get_available_params();
+-	const gchar **p;
+-	guint i;
+-
+-	g_return_if_fail(PURPLE_IS_MEDIA_BACKEND_FS2(self));
+-
+-	priv = PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self);
+-
+-	if (priv->conference == NULL &&
+-		!init_conference(PURPLE_MEDIA_BACKEND_FS2(self))) {
+-		purple_debug_error("backend-fs2",
+-				"Error initializing the conference.\n");
+-		return;
+-	}
+-
+-	for (i = 0; i != num_params; ++i) {
+-		for (p = supported; *p != NULL; ++p) {
+-			if (!strcmp(params[i].name, *p)) {
+-				g_object_set(priv->conference,
+-						params[i].name, g_value_get_string(&params[i].value),
+-						NULL);
+-				break;
+-			}
+-		}
+-	}
+-}
+-
+ static const gchar **
+ purple_media_backend_fs2_get_available_params(void)
+ {
+@@ -2440,6 +2495,71 @@
+ 
+ 	return supported_params;
+ }
 +
 +static const gchar*
 +param_to_sdes_type(const gchar *param)
@@ -776,56 +789,43 @@ index 8e6c28c..4932080 100644
 +	return NULL;
 +}
 +
- static void
- purple_media_backend_fs2_set_params(PurpleMediaBackend *self,
- 		guint num_params, GParameter *params)
- {
- 	PurpleMediaBackendFs2Private *priv;
--	const gchar **supported = purple_media_backend_fs2_get_available_params();
--	const gchar **p;
- 	guint i;
++static void
++purple_media_backend_fs2_set_params(PurpleMediaBackend *self,
++		guint num_params, GParameter *params)
++{
++	PurpleMediaBackendFs2Private *priv;
++	guint i;
 +#ifndef HAVE_FARSIGHT
 +	GstStructure *sdes;
 +#endif
- 
- 	g_return_if_fail(PURPLE_IS_MEDIA_BACKEND_FS2(self));
- 
-@@ -2418,27 +2535,30 @@ purple_media_backend_fs2_set_params(PurpleMediaBackend *self,
- 		return;
- 	}
- 
++
++	g_return_if_fail(PURPLE_IS_MEDIA_BACKEND_FS2(self));
++
++	priv = PURPLE_MEDIA_BACKEND_FS2_GET_PRIVATE(self);
++
++	if (priv->conference == NULL &&
++		!init_conference(PURPLE_MEDIA_BACKEND_FS2(self))) {
++		purple_debug_error("backend-fs2",
++				"Error initializing the conference.\n");
++		return;
++	}
++
 +#ifdef HAVE_FARSIGHT
- 	for (i = 0; i != num_params; ++i) {
--		for (p = supported; *p != NULL; ++p) {
--			if (!strcmp(params[i].name, *p)) {
--				g_object_set(priv->conference,
--						params[i].name, g_value_get_string(&params[i].value),
--						NULL);
--				break;
--			}
++	for (i = 0; i != num_params; ++i) {
 +		if (param_to_sdes_type(params[i].name)) {
 +			g_object_set(priv->conference,
 +			             params[i].name, g_value_get_string(&params[i].value),
 +			             NULL);
- 		}
- 	}
--}
++		}
++	}
 +#else
 +	g_object_get(G_OBJECT(priv->conference), "sdes", &sdes, NULL);
- 
--static const gchar **
--purple_media_backend_fs2_get_available_params(void)
--{
--	static const gchar *supported_params[] = {
--		"sdes-cname", "sdes-email", "sdes-location", "sdes-name", "sdes-note",
--		"sdes-phone", "sdes-tool", NULL
--	};
++
 +	for (i = 0; i != num_params; ++i) {
 +		const gchar *sdes_type = param_to_sdes_type(params[i].name);
 +		if (!sdes_type)
 +			continue;
- 
--	return supported_params;
++
 +		gst_structure_set(sdes, sdes_type,
 +		                  G_TYPE_STRING, g_value_get_string(&params[i].value),
 +		                  NULL);
@@ -834,11 +834,11 @@ index 8e6c28c..4932080 100644
 +	g_object_set(G_OBJECT(priv->conference), "sdes", sdes, NULL);
 +	gst_structure_free(sdes);
 +#endif /* HAVE_FARSIGHT */
- }
++}
  static gboolean
  send_dtmf_callback(gpointer userdata)
+ {
 diff --git a/libpurple/mediamanager.c b/libpurple/mediamanager.c
-index c79b1b9..abaf910 100644
 --- a/libpurple/mediamanager.c
 +++ b/libpurple/mediamanager.c
 @@ -44,7 +44,12 @@
@@ -854,7 +854,7 @@ index c79b1b9..abaf910 100644
  
  /** @copydoc _PurpleMediaManagerPrivate */
  typedef struct _PurpleMediaManagerPrivate PurpleMediaManagerPrivate;
-@@ -270,8 +275,11 @@ purple_media_manager_get_pipeline(PurpleMediaManager *manager)
+@@ -270,8 +275,11 @@
  		gst_bus_add_signal_watch(GST_BUS(bus));
  		g_signal_connect(G_OBJECT(bus), "message",
  				G_CALLBACK(pipeline_bus_call), manager);
@@ -868,7 +868,7 @@ index c79b1b9..abaf910 100644
  		gst_object_unref(bus);
  
  		filename = g_build_filename(purple_user_dir(),
-@@ -405,20 +413,31 @@ request_pad_unlinked_cb(GstPad *pad, GstPad *peer, gpointer user_data)
+@@ -405,20 +413,31 @@
  {
  	GstElement *parent = GST_ELEMENT_PARENT(pad);
  	GstIterator *iter;
@@ -901,7 +901,7 @@ index c79b1b9..abaf910 100644
  		gst_object_unref(remaining_pad);
  	}
  
-@@ -460,7 +479,11 @@ purple_media_manager_get_video_caps(PurpleMediaManager *manager)
+@@ -460,7 +479,11 @@
  {
  #ifdef USE_VV
  	if (manager->priv->video_caps == NULL)
@@ -913,7 +913,7 @@ index c79b1b9..abaf910 100644
  			"width=[250,352], height=[200,288], framerate=[1/1,20/1]");
  	return manager->priv->video_caps;
  #else
-@@ -543,7 +566,11 @@ purple_media_manager_get_element(PurpleMediaManager *manager,
+@@ -543,7 +566,11 @@
  		g_free(id);
  
  		tee = gst_bin_get_by_name(GST_BIN(ret), "tee");
@@ -925,7 +925,7 @@ index c79b1b9..abaf910 100644
  		gst_object_unref(tee);
  		ghost = gst_ghost_pad_new(NULL, pad);
  		gst_object_unref(pad);
-@@ -739,9 +766,12 @@ window_id_cb(GstBus *bus, GstMessage *msg, PurpleMediaOutputWindow *ow)
+@@ -739,9 +766,12 @@
  {
  	GstElement *sink;
  
@@ -941,7 +941,7 @@ index c79b1b9..abaf910 100644
  		return;
  
  	sink = GST_ELEMENT(GST_MESSAGE_SRC(msg));
-@@ -755,8 +785,16 @@ window_id_cb(GstBus *bus, GstMessage *msg, PurpleMediaOutputWindow *ow)
+@@ -755,8 +785,16 @@
  			| G_SIGNAL_MATCH_DATA, 0, 0, NULL,
  			window_id_cb, ow);
  
@@ -960,7 +960,7 @@ index c79b1b9..abaf910 100644
  }
  #endif
  
-@@ -781,17 +819,19 @@ purple_media_manager_create_output_window(PurpleMediaManager *manager,
+@@ -781,17 +819,19 @@
  				(participant == ow->participant)) &&
  				!strcmp(session_id, ow->session_id)) {
  			GstBus *bus;
@@ -985,7 +985,7 @@ index c79b1b9..abaf910 100644
  			ow->sink = purple_media_manager_get_element(
  					manager, PURPLE_MEDIA_RECV_VIDEO,
  					ow->media, ow->session_id,
-@@ -804,7 +844,7 @@ purple_media_manager_create_output_window(PurpleMediaManager *manager,
+@@ -804,7 +844,7 @@
  				if (g_object_class_find_property(klass,
  						"sync"))
  					g_object_set(G_OBJECT(ow->sink),
@@ -994,7 +994,7 @@ index c79b1b9..abaf910 100644
  				if (g_object_class_find_property(klass,
  						"async"))
  					g_object_set(G_OBJECT(ow->sink),
-@@ -812,7 +852,7 @@ purple_media_manager_create_output_window(PurpleMediaManager *manager,
+@@ -812,7 +852,7 @@
  			}
  
  			gst_bin_add_many(GST_BIN(GST_ELEMENT_PARENT(tee)),
@@ -1003,7 +1003,7 @@ index c79b1b9..abaf910 100644
  
  			bus = gst_pipeline_get_bus(GST_PIPELINE(
  					manager->priv->pipeline));
-@@ -821,10 +861,10 @@ purple_media_manager_create_output_window(PurpleMediaManager *manager,
+@@ -821,10 +861,10 @@
  			gst_object_unref(bus);
  
  			gst_element_set_state(ow->sink, GST_STATE_PLAYING);
@@ -1018,10 +1018,9 @@ index c79b1b9..abaf910 100644
  		}
  	}
 diff --git a/pidgin/Makefile.am b/pidgin/Makefile.am
-index 0d19e14..84d927b 100644
 --- a/pidgin/Makefile.am
 +++ b/pidgin/Makefile.am
-@@ -151,6 +151,7 @@ pidgin_LDADD = \
+@@ -151,6 +151,7 @@
  	$(GLIB_LIBS) \
  	$(DBUS_LIBS) \
  	$(GSTREAMER_LIBS) \
@@ -1030,7 +1029,6 @@ index 0d19e14..84d927b 100644
  	$(SM_LIBS) \
  	$(INTLLIBS) \
 diff --git a/pidgin/gtkmedia.c b/pidgin/gtkmedia.c
-index 9a09b80..7ae82e4 100644
 --- a/pidgin/gtkmedia.c
 +++ b/pidgin/gtkmedia.c
 @@ -43,7 +43,9 @@
@@ -1043,7 +1041,7 @@ index 9a09b80..7ae82e4 100644
  
  #define PIDGIN_TYPE_MEDIA            (pidgin_media_get_type())
  #define PIDGIN_MEDIA(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), PIDGIN_TYPE_MEDIA, PidginMedia))
-@@ -590,6 +592,9 @@ pidgin_media_error_cb(PidginMedia *media, const char *error, PidginMedia *gtkmed
+@@ -590,6 +592,9 @@
  	if (conv != NULL)
  		purple_conversation_write(conv, NULL, error,
  				PURPLE_MESSAGE_ERROR, time(NULL));
@@ -1054,7 +1052,6 @@ index 9a09b80..7ae82e4 100644
  			0, error);
  }
 diff --git a/pidgin/plugins/vvconfig.c b/pidgin/plugins/vvconfig.c
-index 1c50fab..968355f 100644
 --- a/pidgin/plugins/vvconfig.c
 +++ b/pidgin/plugins/vvconfig.c
 @@ -26,7 +26,11 @@
@@ -1069,7 +1066,7 @@ index 1c50fab..968355f 100644
  
  /* container window for showing a stand-alone configurator */
  static GtkWidget *window = NULL;
-@@ -81,8 +85,10 @@ get_element_devices(const gchar *element_name)
+@@ -81,8 +85,10 @@
  	GList *ret = NULL;
  	GstElement *element;
  	GObjectClass *klass;
@@ -1080,7 +1077,7 @@ index 1c50fab..968355f 100644
  
  	ret = g_list_prepend(ret, (gpointer)_("Default"));
  	ret = g_list_prepend(ret, "");
-@@ -103,6 +109,10 @@ get_element_devices(const gchar *element_name)
+@@ -103,6 +109,10 @@
  		return g_list_reverse(ret);
  	}
  
@@ -1091,7 +1088,7 @@ index 1c50fab..968355f 100644
  	if (!g_object_class_find_property(klass, "device") ||
  			!GST_IS_PROPERTY_PROBE(element) ||
  			!(probe = GST_PROPERTY_PROBE(element)) ||
-@@ -155,6 +165,7 @@ G_GNUC_END_IGNORE_DEPRECATIONS
+@@ -155,6 +165,7 @@
  			gst_element_set_state(element, GST_STATE_NULL);
  		}
  	}
@@ -1099,7 +1096,7 @@ index 1c50fab..968355f 100644
  	gst_object_unref(element);
  
  	return g_list_reverse(ret);
-@@ -168,8 +179,13 @@ get_element_plugins(const gchar **plugins)
+@@ -168,8 +179,13 @@
  	ret = g_list_prepend(ret, "Default");
  	ret = g_list_prepend(ret, "");
  	for (; plugins[0] && plugins[1]; plugins += 2) {
@@ -1113,7 +1110,7 @@ index 1c50fab..968355f 100644
  			ret = g_list_prepend(ret, (gpointer)plugins[1]);
  			ret = g_list_prepend(ret, (gpointer)plugins[0]);
  		}
-@@ -588,7 +604,13 @@ gst_msg_db_to_percent(GstMessage *msg, gchar *value_name)
+@@ -588,7 +604,13 @@
  
  	list = gst_structure_get_value(
  				gst_message_get_structure(msg), value_name);
@@ -1127,7 +1124,7 @@ index 1c50fab..968355f 100644
  	value_db = g_value_get_double(value);
  	percent = pow(10, value_db / 20);
  	return (percent > 1.0) ? 1.0 : percent;
-@@ -604,7 +626,7 @@ static gboolean
+@@ -604,7 +626,7 @@
  gst_bus_cb(GstBus *bus, GstMessage *msg, BusCbCtx *ctx)
  {
  	if (GST_MESSAGE_TYPE(msg) == GST_MESSAGE_ELEMENT &&
@@ -1136,6 +1133,4 @@ index 1c50fab..968355f 100644
  
  		GstElement *src = GST_ELEMENT(GST_MESSAGE_SRC(msg));
  		gchar *name = gst_element_get_name(src);
--- 
-2.1.0
 
diff --git a/pidgin-2.10.11-rtp-encryption.patch b/pidgin-2.10.11-rtp-encryption.patch
new file mode 100644
index 0000000..9fab8d6
--- /dev/null
+++ b/pidgin-2.10.11-rtp-encryption.patch
@@ -0,0 +1,429 @@
+
+# HG changeset patch
+# User Jakub Adam <jakub.adam at ktknet.cz>
+# Date 1426122329 0
+# Node ID a0906e7a6bae86f1251d8369b30ba82a9daf1836
+# Parent  fcecf7f838e266dc2c3bfd306df58ade3fc3ac93
+Implement media encryption
+
+diff --git a/libpurple/media.c b/libpurple/media.c
+--- a/libpurple/media.c
++++ b/libpurple/media.c
+@@ -1276,6 +1276,34 @@
+ }
+ 
+ gboolean
++purple_media_set_encryption_parameters(PurpleMedia *media, const gchar *sess_id,
++		const gchar *cipher, const gchar *auth,
++		const gchar *key, gsize key_len)
++{
++#ifdef USE_VV
++	g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE);
++	return purple_media_backend_set_encryption_parameters(media->priv->backend,
++			sess_id, cipher, auth, key, key_len);
++#else
++	return FALSE;
++#endif
++}
++
++gboolean
++purple_media_set_decryption_parameters(PurpleMedia *media, const gchar *sess_id,
++		const gchar *participant, const gchar *cipher,
++		const gchar *auth, const gchar *key, gsize key_len)
++{
++#ifdef USE_VV
++	g_return_val_if_fail(PURPLE_IS_MEDIA(media), FALSE);
++	return purple_media_backend_set_decryption_parameters(media->priv->backend,
++			sess_id, participant, cipher, auth, key, key_len);
++#else
++	return FALSE;
++#endif
++}
++
++gboolean
+ purple_media_codecs_ready(PurpleMedia *media, const gchar *sess_id)
+ {
+ #ifdef USE_VV
+diff --git a/libpurple/media.h b/libpurple/media.h
+--- a/libpurple/media.h
++++ b/libpurple/media.h
+@@ -349,6 +349,43 @@
+ gboolean purple_media_set_send_codec(PurpleMedia *media, const gchar *sess_id, PurpleMediaCodec *codec);
+ 
+ /**
++ * Sets the encryption parameters of our media in the session.
++ *
++ * @param media The media object to find the session in.
++ * @param sess_id The session id of the session to set parameters of.
++ * @param cipher The cipher to use to encrypt our media in the session.
++ * @param auth The algorithm to use to compute authentication codes for our
++ *        media frames.
++ * @param key The encryption key.
++ * @param key_len Byte length of the encryption key.
++ *
++ * @since 2.11.0
++ */
++gboolean purple_media_set_encryption_parameters(PurpleMedia *media,
++		const gchar *sess_id, const gchar *cipher,
++		const gchar *auth, const gchar *key, gsize key_len);
++
++/**
++ * Sets the decryption parameters for a session participant's media.
++ *
++ * @param media The media object to find the session in.
++ * @param sess_id The session id of the session to set parameters of.
++ * @param participant The participant of the session to set parameters of.
++ * @param cipher The cipher to use to decrypt media coming from this session's
++ *          participant.
++ * @param auth The algorithm to use for authentication of the media coming
++ *        from the session's participant.
++ * @param key The decryption key.
++ * @param key_len Byte length of the decryption key.
++ *
++ * @since 2.11.0
++ */
++gboolean purple_media_set_decryption_parameters(PurpleMedia *media,
++		const gchar *sess_id, const gchar *participant,
++		const gchar *cipher, const gchar *auth,
++		const gchar *key, gsize key_len);
++
++/**
+  * Gets whether a session's codecs are ready to be used.
+  *
+  * @param media The media object to find the session in.
+diff --git a/libpurple/media/backend-fs2.c b/libpurple/media/backend-fs2.c
+--- a/libpurple/media/backend-fs2.c
++++ b/libpurple/media/backend-fs2.c
+@@ -85,6 +85,15 @@
+ static GList *purple_media_backend_fs2_get_local_candidates(
+ 		PurpleMediaBackend *self,
+ 		const gchar *sess_id, const gchar *participant);
++#if GST_CHECK_VERSION(1,0,0)
++static gboolean purple_media_backend_fs2_set_encryption_parameters (
++	PurpleMediaBackend *self, const gchar *sess_id, const gchar *cipher,
++	const gchar *auth, const gchar *key, gsize key_len);
++static gboolean purple_media_backend_fs2_set_decryption_parameters(
++		PurpleMediaBackend *self, const gchar *sess_id,
++		const gchar *participant, const gchar *cipher,
++		const gchar *auth, const gchar *key, gsize key_len);
++#endif
+ static gboolean purple_media_backend_fs2_set_remote_codecs(
+ 		PurpleMediaBackend *self,
+ 		const gchar *sess_id, const gchar *participant,
+@@ -545,6 +554,12 @@
+ 			purple_media_backend_fs2_get_local_candidates;
+ 	iface->set_remote_codecs = purple_media_backend_fs2_set_remote_codecs;
+ 	iface->set_send_codec = purple_media_backend_fs2_set_send_codec;
++#if GST_CHECK_VERSION(1,0,0)
++	iface->set_encryption_parameters =
++			purple_media_backend_fs2_set_encryption_parameters;
++	iface->set_decryption_parameters =
++			purple_media_backend_fs2_set_decryption_parameters;
++#endif
+ 	iface->set_params = purple_media_backend_fs2_set_params;
+ 	iface->get_available_params = purple_media_backend_fs2_get_available_params;
+ 	iface->send_dtmf = purple_media_backend_fs2_send_dtmf;
+@@ -2471,6 +2486,97 @@
+ 	return TRUE;
+ }
+ 
++#if GST_CHECK_VERSION(1,0,0)
++static GstStructure *
++create_fs2_srtp_structure(const gchar *cipher, const gchar *auth,
++	const gchar *key, gsize key_len)
++{
++	GstStructure *result;
++	GstBuffer *buffer;
++	GstMapInfo info;
++
++	buffer = gst_buffer_new_allocate(NULL, key_len, NULL);
++	gst_buffer_map(buffer, &info, GST_MAP_WRITE);
++	memcpy(info.data, key, key_len);
++	gst_buffer_unmap(buffer, &info);
++
++	result = gst_structure_new("FarstreamSRTP",
++			"cipher", G_TYPE_STRING, cipher,
++			"auth", G_TYPE_STRING, auth,
++			"key", GST_TYPE_BUFFER, buffer,
++			NULL);
++	gst_buffer_unref(buffer);
++
++	return result;
++}
++
++static gboolean
++purple_media_backend_fs2_set_encryption_parameters (PurpleMediaBackend *self,
++		const gchar *sess_id, const gchar *cipher, const gchar *auth,
++		const gchar *key, gsize key_len)
++{
++	PurpleMediaBackendFs2Session *session;
++	GstStructure *srtp;
++	GError *err = NULL;
++	gboolean result;
++
++	g_return_val_if_fail(PURPLE_IS_MEDIA_BACKEND_FS2(self), FALSE);
++
++	session = get_session(PURPLE_MEDIA_BACKEND_FS2(self), sess_id);
++	if (!session)
++		return FALSE;
++
++	srtp = create_fs2_srtp_structure(cipher, auth, key, key_len);
++	if (!srtp)
++		return FALSE;
++
++	result = fs_session_set_encryption_parameters(session->session, srtp,
++						&err);
++	if (!result) {
++		purple_debug_error("backend-fs2",
++				"Error setting encryption parameters: %s\n", err->message);
++		g_error_free(err);
++	}
++
++	gst_structure_free(srtp);
++	return result;
++}
++
++static gboolean
++purple_media_backend_fs2_set_decryption_parameters (PurpleMediaBackend *self,
++		const gchar *sess_id, const gchar *participant,
++		const gchar *cipher, const gchar *auth,
++		const gchar *key, gsize key_len)
++{
++	PurpleMediaBackendFs2Stream *stream;
++	GstStructure *srtp;
++	GError *err = NULL;
++	gboolean result;
++
++	g_return_val_if_fail(PURPLE_IS_MEDIA_BACKEND_FS2(self), FALSE);
++
++	stream = get_stream(PURPLE_MEDIA_BACKEND_FS2(self), sess_id,
++			participant);
++	if (!stream)
++		return FALSE;
++
++	srtp = create_fs2_srtp_structure(cipher, auth, key, key_len);
++	if (!srtp)
++		return FALSE;
++
++	result = fs_stream_set_decryption_parameters(stream->stream, srtp,
++						&err);
++	if (!result) {
++		purple_debug_error("backend-fs2",
++				"Error setting decryption parameters: %s\n", err->message);
++		g_error_free(err);
++	}
++
++	gst_structure_free(srtp);
++	return result;
++}
++#endif /* GST 1.0+ */
++
+ static gboolean
+ purple_media_backend_fs2_set_send_codec(PurpleMediaBackend *self,
+ 		const gchar *sess_id, PurpleMediaCodec *codec)
+diff --git a/libpurple/media/backend-iface.c b/libpurple/media/backend-iface.c
+--- a/libpurple/media/backend-iface.c
++++ b/libpurple/media/backend-iface.c
+@@ -193,6 +193,35 @@
+ 			sess_id, codec);
+ }
+ 
++gboolean
++purple_media_backend_set_encryption_parameters(PurpleMediaBackend *self,
++		const gchar *sess_id, const gchar *cipher,
++		const gchar *auth, const gchar *key, gsize key_len)
++{
++	PurpleMediaBackendIface *backend_iface;
++
++	g_return_val_if_fail(PURPLE_IS_MEDIA_BACKEND(self), FALSE);
++	backend_iface = PURPLE_MEDIA_BACKEND_GET_INTERFACE(self);
++	g_return_val_if_fail(backend_iface->set_encryption_parameters, FALSE);
++	return backend_iface->set_encryption_parameters(self,
++			sess_id, cipher, auth, key, key_len);
++}
++
++gboolean
++purple_media_backend_set_decryption_parameters(PurpleMediaBackend *self,
++		const gchar *sess_id, const gchar *participant,
++		const gchar *cipher, const gchar *auth,
++		const gchar *key, gsize key_len)
++{
++	PurpleMediaBackendIface *backend_iface;
++
++	g_return_val_if_fail(PURPLE_IS_MEDIA_BACKEND(self), FALSE);
++	backend_iface = PURPLE_MEDIA_BACKEND_GET_INTERFACE(self);
++	g_return_val_if_fail(backend_iface->set_decryption_parameters, FALSE);
++	return backend_iface->set_decryption_parameters(self,
++			sess_id, participant, cipher, auth, key, key_len);
++}
++
+ void
+ purple_media_backend_set_params(PurpleMediaBackend *self,
+ 		guint num_params, GParameter *params)
+diff --git a/libpurple/media/backend-iface.h b/libpurple/media/backend-iface.h
+--- a/libpurple/media/backend-iface.h
++++ b/libpurple/media/backend-iface.h
+@@ -68,6 +68,13 @@
+ 		GList *codecs);
+ 	gboolean (*set_send_codec) (PurpleMediaBackend *self,
+ 		const gchar *sess_id, PurpleMediaCodec *codec);
++	gboolean (*set_encryption_parameters) (PurpleMediaBackend *self,
++		const gchar *sess_id, const gchar *cipher,
++		const gchar *auth, const gchar *key, gsize key_len);
++	gboolean (*set_decryption_parameters) (PurpleMediaBackend *self,
++		const gchar *sess_id, const gchar *participant,
++		const gchar *cipher, const gchar *auth,
++		const gchar *key, gsize key_len);
+ 	void (*set_params) (PurpleMediaBackend *self,
+ 		guint num_params, GParameter *params);
+ 	const gchar **(*get_available_params) (void);
+@@ -198,6 +205,43 @@
+ 		const gchar *sess_id, PurpleMediaCodec *codec);
+ 
+ /**
++ * Sets the encryption parameters of our media in the session.
++ *
++ * @param self The media backend the session is in.
++ * @param sess_id The session id of the session to set parameters of.
++ * @param cipher The cipher to use to encrypt our media in the session.
++ * @param auth The algorithm to use to compute authentication codes for our
++ *        media frames.
++ * @param key The encryption key.
++ * @param key_len Byte length of the encryption key.
++ *
++ * @since 2.11.0
++ */
++gboolean purple_media_backend_set_encryption_parameters(PurpleMediaBackend *self,
++		const gchar *sess_id, const gchar *cipher,
++		const gchar *auth, const gchar *key, gsize key_len);
++
++/**
++ * Sets the decryption parameters for a session participant's media.
++ *
++ * @param self The media backend the session is in.
++ * @param sess_id The session id of the session to set parameters of.
++ * @param participant The participant of the session to set parameters of.
++ * @param cipher The cipher to use to decrypt media coming from this session's
++ *          participant.
++ * @param auth The algorithm to use for authentication of the media coming
++ *        from the session's participant.
++ * @param key The decryption key.
++ * @param key_len Byte length of the decryption key.
++ *
++ * @since 2.11.0
++ */
++gboolean purple_media_backend_set_decryption_parameters(PurpleMediaBackend *self,
++		const gchar *sess_id, const gchar *participant,
++		const gchar *cipher, const gchar *auth,
++		const gchar *key, gsize key_len);
++
++/**
+  * Sets various optional parameters of the media backend.
+  *
+  * @param self The media backend to set the parameters on.
+diff --git a/libpurple/media/enum-types.c b/libpurple/media/enum-types.c
+--- a/libpurple/media/enum-types.c
++++ b/libpurple/media/enum-types.c
+@@ -217,3 +217,44 @@
+ 	return type;
+ }
+ 
++/*
++ * PurpleMediaCipher
++ */
++
++GType
++purple_media_cipher_get_type()
++{
++	static GType type = 0;
++	if (type == 0) {
++		static const GEnumValue values[] = {
++			{ PURPLE_MEDIA_CIPHER_NULL,
++				"PURPLE_MEDIA_CIPHER_NULL", "null" },
++			{ PURPLE_MEDIA_CIPHER_AES_128_ICM,
++				"PURPLE_MEDIA_CIPHER_AES_128_ICM", "AES-128-ICM" },
++			{ PURPLE_MEDIA_CIPHER_AES_256_ICM,
++				"PURPLE_MEDIA_CIPHER_AES_256_ICM", "AES-256-ICM" },
++			{ 0, NULL, NULL }
++		};
++		type = g_enum_register_static("PurpleMediaCipher", values);
++	}
++	return type;
++}
++
++GType
++purple_media_authentication_get_type(void)
++{
++	static GType type = 0;
++	if (type == 0) {
++		static const GEnumValue values[] = {
++			{ PURPLE_MEDIA_AUTHENTICATION_NULL,
++				"PURPLE_MEDIA_AUTHENTICATION_NULL", "null" },
++			{ PURPLE_MEDIA_AUTHENTICATION_HMAC_SHA1_32,
++				"PURPLE_MEDIA_AUTHENTICATION_HMAC_SHA1_32", "HMAC_SHA1_32" },
++			{ PURPLE_MEDIA_AUTHENTICATION_HMAC_SHA1_80,
++				"PURPLE_MEDIA_AUTHENTICATION_HMAC_SHA1_80", "HMAC_SHA1_80" },
++			{ 0, NULL, NULL }
++		};
++		type = g_enum_register_static("PurpleMediaAuthentication", values);
++	}
++	return type;
++}
+diff --git a/libpurple/media/enum-types.h b/libpurple/media/enum-types.h
+--- a/libpurple/media/enum-types.h
++++ b/libpurple/media/enum-types.h
+@@ -106,6 +106,28 @@
+ } PurpleMediaState;
+ 
+ /**
++ * PurpleMediaCipher:
++ *
++ * Media ciphers
++ */
++typedef enum {
++	PURPLE_MEDIA_CIPHER_NULL,
++	PURPLE_MEDIA_CIPHER_AES_128_ICM,
++	PURPLE_MEDIA_CIPHER_AES_256_ICM
++} PurpleMediaCipher;
++
++/**
++ * PurpleMediaAuthentication:
++ *
++ * Media message authentication algorithms
++ */
++typedef enum {
++	PURPLE_MEDIA_AUTHENTICATION_NULL,
++	PURPLE_MEDIA_AUTHENTICATION_HMAC_SHA1_32,
++	PURPLE_MEDIA_AUTHENTICATION_HMAC_SHA1_80
++} PurpleMediaAuthentication;
++
++/**
+  * Gets the media candidate type's GType
+  *
+  * @return The media candidate type's GType.
+@@ -159,6 +181,24 @@
+  */
+ GType purple_media_state_changed_get_type(void);
+ 
++/**
++ * purple_media_cipher_get_type:
++ *
++ * Gets the type of the cipher enum
++ *
++ * Returns: The cipher enum's GType
++ */
++GType purple_media_cipher_get_type(void);
++
++/**
++ * purple_media_authentication_get_type:
++ *
++ * Gets the type of the authentication enum
++ *
++ * Returns: The authentication enum's GType
++ */
++GType purple_media_authentication_get_type(void);
++
+ G_END_DECLS
+ 
+ #endif  /* _PURPLE_MEDIA_ENUM_TYPES_ */
+
diff --git a/pidgin-2.10.11-rtp-tcp.patch b/pidgin-2.10.11-rtp-tcp.patch
new file mode 100644
index 0000000..87fb0f8
--- /dev/null
+++ b/pidgin-2.10.11-rtp-tcp.patch
@@ -0,0 +1,127 @@
+
+# HG changeset patch
+# User Jakub Adam <jakub.adam at ktknet.cz>
+# Date 1398231090 -7200
+# Node ID fcecf7f838e266dc2c3bfd306df58ade3fc3ac93
+# Parent  2415067473ba10a2090d6130b93204a3b537b05c
+Add MS-TURN TCP support
+
+The old TCP support never worked. Older versions of farstream defined
+FS_NETWORK_PROTOCOL_TCP but there were even *tests* to ensure that any
+attempt to use it would result in FS_ERROR_INVALID_ARGUMENTS.
+
+This adds the three variants of TCP support that are now supported in
+farstream 0.2.6 onwards, and bumps the requirement in configure.ac
+accordingly.
+
+Olivier says the Google ones should probably be passive. Since they
+never worked anyway, I'm not going to lose too much sleep over them.
+
+[dwmw2: reworked to remain compatible with the farstream 0.1 build]
+
+diff --git a/configure.ac b/configure.ac
+--- a/configure.ac
++++ b/configure.ac
+@@ -868,7 +868,7 @@
+ 	enable_farstream="$enableval", enable_farstream="yes")
+ if test "x$enable_farstream" != "xno"; then
+ 	if test "x$with_gstreamer" == "x1.0"; then
+-		PKG_CHECK_MODULES(FARSTREAM, [farstream-0.2], [
++		PKG_CHECK_MODULES(FARSTREAM, [farstream-0.2 >= 0.2.6], [
+ 			AC_SUBST(FARSTREAM_CFLAGS)
+ 			AC_SUBST(FARSTREAM_LIBS)
+ 		], [
+diff --git a/libpurple/media/backend-fs2.c b/libpurple/media/backend-fs2.c
+--- a/libpurple/media/backend-fs2.c
++++ b/libpurple/media/backend-fs2.c
+@@ -225,10 +225,17 @@
+ 	switch (protocol) {
+ 		case PURPLE_MEDIA_NETWORK_PROTOCOL_UDP:
+ 			return FS_NETWORK_PROTOCOL_UDP;
+-		case PURPLE_MEDIA_NETWORK_PROTOCOL_TCP:
+-			return FS_NETWORK_PROTOCOL_TCP;
++#if GST_CHECK_VERSION(1,0,0)
++		case PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_PASSIVE:
++			return FS_NETWORK_PROTOCOL_TCP_PASSIVE;
++		case PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_ACTIVE:
++			return FS_NETWORK_PROTOCOL_TCP_ACTIVE;
++		case PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_SO:
++			return FS_NETWORK_PROTOCOL_TCP_SO;
++#endif
++		default:
++			g_return_val_if_reached(FS_NETWORK_PROTOCOL_TCP);
+ 	}
+-	g_return_val_if_reached(FS_NETWORK_PROTOCOL_TCP);
+ }
+ 
+ static PurpleMediaNetworkProtocol
+@@ -237,10 +244,17 @@
+ 	switch (protocol) {
+ 		case FS_NETWORK_PROTOCOL_UDP:
+ 			return PURPLE_MEDIA_NETWORK_PROTOCOL_UDP;
+-		case FS_NETWORK_PROTOCOL_TCP:
+-			return PURPLE_MEDIA_NETWORK_PROTOCOL_TCP;
++#if GST_CHECK_VERSION(1,0,0)
++		case FS_NETWORK_PROTOCOL_TCP_PASSIVE:
++			return PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_PASSIVE;
++		case FS_NETWORK_PROTOCOL_TCP_ACTIVE:
++			return PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_ACTIVE;
++		case FS_NETWORK_PROTOCOL_TCP_SO:
++			return PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_SO;
++#endif
++		default:
++			g_return_val_if_reached(PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_PASSIVE);
+ 	}
+-	g_return_val_if_reached(PURPLE_MEDIA_NETWORK_PROTOCOL_TCP);
+ }
+ 
+ #if GST_CHECK_VERSION(1,0,0)
+diff --git a/libpurple/media/enum-types.c b/libpurple/media/enum-types.c
+--- a/libpurple/media/enum-types.c
++++ b/libpurple/media/enum-types.c
+@@ -145,9 +145,15 @@
+ 			{ PURPLE_MEDIA_NETWORK_PROTOCOL_UDP,
+ 					"PURPLE_MEDIA_NETWORK_PROTOCOL_UDP",
+ 					"udp" },
+-			{ PURPLE_MEDIA_NETWORK_PROTOCOL_TCP,
+-					"PURPLE_MEDIA_NETWORK_PROTOCOL_TCP",
+-					"tcp" },
++			{ PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_PASSIVE,
++					"PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_PASSIVE",
++					"tcp passive" },
++			{ PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_ACTIVE,
++					"PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_ACTIVE",
++					"tcp active" },
++			{ PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_SO,
++					"PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_SO",
++					"tcp so" },
+ 			{ 0, NULL, NULL }
+ 		};
+ 		type = g_enum_register_static("PurpleMediaNetworkProtocol",
+diff --git a/libpurple/media/enum-types.h b/libpurple/media/enum-types.h
+--- a/libpurple/media/enum-types.h
++++ b/libpurple/media/enum-types.h
+@@ -82,7 +82,9 @@
+ /** Media network protocols */
+ typedef enum {
+ 	PURPLE_MEDIA_NETWORK_PROTOCOL_UDP,
+-	PURPLE_MEDIA_NETWORK_PROTOCOL_TCP
++	PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_PASSIVE,
++	PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_ACTIVE,
++	PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_SO,
+ } PurpleMediaNetworkProtocol;
+ 
+ /** Media session types */
+diff --git a/libpurple/protocols/jabber/google/google_session.c b/libpurple/protocols/jabber/google/google_session.c
+--- a/libpurple/protocols/jabber/google/google_session.c
++++ b/libpurple/protocols/jabber/google/google_session.c
+@@ -657,7 +657,7 @@
+ 					candidate_type,
+ 					purple_strequal(protocol, "udp") ?
+ 							PURPLE_MEDIA_NETWORK_PROTOCOL_UDP :
+-							PURPLE_MEDIA_NETWORK_PROTOCOL_TCP,
++							PURPLE_MEDIA_NETWORK_PROTOCOL_TCP_PASSIVE,
+ 					address,
+ 					atoi(port));
+ 			g_object_set(info, "username", xmlnode_get_attrib(cand, "username"),
+
diff --git a/pidgin.spec b/pidgin.spec
index a030809..b4682b9 100644
--- a/pidgin.spec
+++ b/pidgin.spec
@@ -131,7 +131,7 @@
 
 Name:           pidgin
 Version:        2.10.11
-Release:        8%{?dist}
+Release:        9%{?dist}
 License:        GPLv2+ and GPLv2 and MIT
 # GPLv2+ - libpurple, gnt, finch, pidgin, most prpls
 # GPLv2 - silc & novell prpls
@@ -175,8 +175,12 @@ Patch100:       pidgin-2.10.1-fix-msn-ft-crashes.patch
 Patch102:         pidgin-2.10.11-do-not-disable-wall.patch
 # https://hg.pidgin.im/pidgin/main/rev/6b4576edf2a6
 Patch103:       pidgin-2.10.11-add-dtmf-support.patch
-# https://pidgin.im/pipermail/devel/2015-March/023645.html
+# http://hg.pidgin.im/pidgin/main/rev/2415067473ba
 Patch104:       pidgin-2.10.11-gstreamer1.patch
+# http://hg.pidgin.im/pidgin/main/rev/fcecf7f838e2
+Patch105:       pidgin-2.10.11-rtp-tcp.patch
+# http://hg.pidgin.im/pidgin/main/rev/a0906e7a6bae
+Patch106:       pidgin-2.10.11-rtp-encryption.patch
 
 BuildRoot:      %{_tmppath}/%{name}-%{version}-root
 Summary:        A Gtk+ based multiprotocol instant messaging client
@@ -494,8 +498,12 @@ echo "FEDORA=%{fedora} RHEL=%{rhel}"
 %patch102 -p1
 # https://hg.pidgin.im/pidgin/main/rev/6b4576edf2a6
 %patch103 -p1
-# https://pidgin.im/pipermail/devel/2015-March/023645.html
+# http://hg.pidgin.im/pidgin/main/rev/2415067473ba
 %patch104 -p1
+# http://hg.pidgin.im/pidgin/main/rev/fcecf7f838e2
+%patch105 -p1
+# http://hg.pidgin.im/pidgin/main/rev/a0906e7a6bae
+%patch106 -p1
 
 # Our preferences
 cp %{SOURCE1} prefs.xml
@@ -790,6 +798,9 @@ rm -rf $RPM_BUILD_ROOT
 %endif
 
 %changelog
+* Fri Mar 13 2015 David Woodhouse <dwmw2 at infradead.org> - 2.10.11-9
+- Add TCP and media encryption support
+
 * Thu Mar 12 2015 David Woodhouse <dwmw2 at infradead.org> - 2.10.11-8
 - Update to final upstream version of GStreamer 1.0 patch
 


More information about the scm-commits mailing list