From 592bacce4a8d835aa48ade5eb12b8f17604b2c57 Mon Sep 17 00:00:00 2001
From: Thibaut GIRKA <thib@sitedethib.com>
Date: Tue, 1 Dec 2009 22:15:50 +0100
Subject: [PATCH] [Jingle] Fix make_bin_from_config, improve
 JingleSession.__parse_contents

---
 src/common/jingle_content.py |  6 ++++
 src/common/jingle_rtp.py     |  4 ++-
 src/common/jingle_session.py | 55 +++++++++++++++++++-----------------
 3 files changed, 38 insertions(+), 27 deletions(-)

diff --git a/src/common/jingle_content.py b/src/common/jingle_content.py
index 03c5895a24..0dd0136601 100644
--- a/src/common/jingle_content.py
+++ b/src/common/jingle_content.py
@@ -23,6 +23,12 @@ def get_jingle_content(node):
 		return contents[namespace](node)
 
 
+class FailedApplication(Exception):
+	"""
+	Exception that should be raised when a content fails to setup.
+	"""
+
+
 class JingleContent(object):
 	"""
 	An abstraction of content in Jingle sessions
diff --git a/src/common/jingle_rtp.py b/src/common/jingle_rtp.py
index 980e3c16a8..2795e32ad3 100644
--- a/src/common/jingle_rtp.py
+++ b/src/common/jingle_rtp.py
@@ -24,7 +24,7 @@ from glib import GError
 import gajim
 
 from jingle_transport import JingleTransportICEUDP
-from jingle_content import contents, JingleContent
+from jingle_content import contents, JingleContent, FailedApplication
 
 
 class JingleRTPContent(JingleContent):
@@ -92,11 +92,13 @@ class JingleRTPContent(JingleContent):
 		try:
 			bin = gst.parse_bin_from_description(pipeline
 				% gajim.config.get(config_key), True)
+			return bin
 		except GError, error_str:
 			self.session.connection.dispatch('ERROR',
 				(_("%s configuration error") % text.capitalize(),
 				_("Couldn't setup %s. Check your configuration.\n\nError was:\n%s")
 					% (text, error_str)))
+			raise FailedApplication
 
 	def add_remote_candidates(self, candidates):
 		JingleContent.add_remote_candidates(self, candidates)
diff --git a/src/common/jingle_session.py b/src/common/jingle_session.py
index f1129a79cc..8062071574 100644
--- a/src/common/jingle_session.py
+++ b/src/common/jingle_session.py
@@ -29,7 +29,7 @@ Handles Jingle sessions (XEP 0166)
 import gajim #Get rid of that?
 import xmpp
 from jingle_transport import get_jingle_transport
-from jingle_content import get_jingle_content
+from jingle_content import get_jingle_content, FailedApplication
 
 # FIXME: Move it to JingleSession.States?
 class JingleStates(object):
@@ -394,8 +394,8 @@ class JingleSession(object):
 			raise OutOfOrder
 
 		parse_result = self.__parse_contents(jingle)
-		contents = parse_result[2]
-		rejected_contents = parse_result[3]
+		contents = parse_result[0]
+		rejected_contents = parse_result[1]
 
 		for name, creator in rejected_contents:
 			# TODO
@@ -426,21 +426,13 @@ class JingleSession(object):
 		# error.
 
 		# Lets check what kind of jingle session does the peer want
-		contents_ok, transports_ok, contents, pouet = self.__parse_contents(jingle)
+		contents, contents_rejected, reason = self.__parse_contents(jingle)
 
 		# If there's no content we understand...
-		if not contents_ok:
+		if not contents:
 			# TODO: http://xmpp.org/extensions/xep-0166.html#session-terminate
 			reason = xmpp.Node('reason')
-			reason.setTag('unsupported-applications')
-			self.__ack(stanza, jingle, error, action)
-			self._session_terminate(reason)
-			raise xmpp.NodeProcessed
-
-		if not transports_ok:
-			# TODO: http://xmpp.org/extensions/xep-0166.html#session-terminate
-			reason = xmpp.Node('reason')
-			reason.setTag('unsupported-transports')
+			reason.setTag(reason)
 			self.__ack(stanza, jingle, error, action)
 			self._session_terminate(reason)
 			raise xmpp.NodeProcessed
@@ -485,26 +477,37 @@ class JingleSession(object):
 		# TODO: Needs some reworking
 		contents = []
 		contents_rejected = []
-		contents_ok = False
-		transports_ok = False
+		reasons = set()
 
 		for element in jingle.iterTags('content'):
 			transport = get_jingle_transport(element.getTag('transport'))
 			content_type = get_jingle_content(element.getTag('description'))
 			if content_type:
-				contents_ok = True
-				if transport:
-					content = content_type(self, transport)
-					self.add_content(element['name'],
-						content, 'peer')
-					contents.append((content.media,))
-					transports_ok = True
-				else:
-					contents_rejected.append((element['name'], 'peer'))
+				try:
+					if transport:
+						content = content_type(self, transport)
+						self.add_content(element['name'],
+							content, 'peer')
+						contents.append((content.media,))
+					else:
+						reasons.add('unsupported-transports')
+						contents_rejected.append((element['name'], 'peer'))
+				except FailedApplication:
+					reasons.add('failed-application')
 			else:
 				contents_rejected.append((element['name'], 'peer'))
+				failed.add('unsupported-applications')
+
+		failure_reason = None
+
+		# Store the first reason of failure
+		for reason in ('failed-application', 'unsupported-transports',
+			'unsupported-applications'):
+			if reason in reasons:
+				failure_reason = reason
+				break
 
-		return (contents_ok, transports_ok, contents, contents_rejected)
+		return (contents, contents_rejected, failure_reason)
 
 	def __dispatch_error(self, error, jingle_error=None, text=None):
 		if jingle_error:
-- 
GitLab