changeset 26181:dcff28a0415c

Handle having multiple active candidates.
author Mike Ruprecht <maiku@soc.pidgin.im>
date Thu, 05 Feb 2009 10:25:28 +0000
parents 4a245ffb4051
children f06eb6e7d907
files libpurple/media.c libpurple/media.h
diffstat 2 files changed, 66 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/media.c	Thu Feb 05 09:41:07 2009 +0000
+++ b/libpurple/media.c	Thu Feb 05 10:25:28 2009 +0000
@@ -75,8 +75,8 @@
 
 	gboolean candidates_prepared;
 
-	FsCandidate *local_candidate;
-	FsCandidate *remote_candidate;
+	GList *active_local_candidates;
+	GList *active_remote_candidates;
 
 	gulong window_id;
 };
@@ -250,10 +250,10 @@
 	if (stream->remote_candidates)
 		fs_candidate_list_destroy(stream->remote_candidates);
 
-	if (stream->local_candidate)
-		fs_candidate_destroy(stream->local_candidate);
-	if (stream->remote_candidate)
-		fs_candidate_destroy(stream->remote_candidate);
+	if (stream->active_local_candidates)
+		fs_candidate_list_destroy(stream->active_local_candidates);
+	if (stream->active_remote_candidates)
+		fs_candidate_list_destroy(stream->active_remote_candidates);
 
 	g_free(stream);
 }
@@ -1670,6 +1670,7 @@
 	gchar *name;
 	FsParticipant *participant;
 	PurpleMediaStream *stream;
+	GList *iter;
 
 	g_return_if_fail(FS_IS_STREAM(fsstream));
 	g_return_if_fail(session != NULL);
@@ -1680,8 +1681,41 @@
 
 	stream = purple_media_get_stream(session->media, session->id, name);
 
-	stream->local_candidate = fs_candidate_copy(native_candidate);
-	stream->remote_candidate = fs_candidate_copy(remote_candidate);
+	iter = stream->active_local_candidates;
+	for(; iter; iter = g_list_next(iter)) {
+		FsCandidate *c = iter->data;
+		if (native_candidate->component_id == c->component_id) {
+			fs_candidate_destroy(c);
+			stream->active_local_candidates =
+					g_list_delete_link(iter, iter);
+			stream->active_local_candidates = g_list_prepend(
+					stream->active_local_candidates,
+					fs_candidate_copy(native_candidate));
+			break;
+		}
+	}
+	if (iter == NULL)
+		stream->active_local_candidates = g_list_prepend(
+				stream->active_local_candidates,
+				fs_candidate_copy(native_candidate));
+
+	iter = stream->active_remote_candidates;
+	for(; iter; iter = g_list_next(iter)) {
+		FsCandidate *c = iter->data;
+		if (native_candidate->component_id == c->component_id) {
+			fs_candidate_destroy(c);
+			stream->active_remote_candidates =
+					g_list_delete_link(iter, iter);
+			stream->active_remote_candidates = g_list_prepend(
+					stream->active_remote_candidates,
+					fs_candidate_copy(remote_candidate));
+			break;
+		}
+	}
+	if (iter == NULL)
+		stream->active_remote_candidates = g_list_prepend(
+				stream->active_remote_candidates,
+				fs_candidate_copy(remote_candidate));
 
 	purple_debug_info("media", "candidate pair established\n");
 }
@@ -2023,22 +2057,26 @@
 	}
 }
 
-PurpleMediaCandidate *
-purple_media_get_local_candidate(PurpleMedia *media, const gchar *sess_id, const gchar *name)
+GList *
+purple_media_get_active_local_candidates(PurpleMedia *media,
+		const gchar *sess_id, const gchar *name)
 {
 	PurpleMediaStream *stream;
 	g_return_val_if_fail(PURPLE_IS_MEDIA(media), NULL);
 	stream = purple_media_get_stream(media, sess_id, name);
-	return purple_media_candidate_from_fs(stream->local_candidate);
+	return purple_media_candidate_list_from_fs(
+			stream->active_local_candidates);
 }
 
-PurpleMediaCandidate *
-purple_media_get_remote_candidate(PurpleMedia *media, const gchar *sess_id, const gchar *name)
+GList *
+purple_media_get_active_remote_candidates(PurpleMedia *media,
+		const gchar *sess_id, const gchar *name)
 {
 	PurpleMediaStream *stream;
 	g_return_val_if_fail(PURPLE_IS_MEDIA(media), NULL);
 	stream = purple_media_get_stream(media, sess_id, name);
-	return purple_media_candidate_from_fs(stream->remote_candidate);
+	return purple_media_candidate_list_from_fs(
+			stream->active_remote_candidates);
 }
 
 gboolean
@@ -2080,8 +2118,14 @@
 
 	for (; sessions; sessions = sessions->next) {
 		const gchar *session = sessions->data;
-		if (!purple_media_get_local_candidate(media, session, name) ||
-				!purple_media_get_remote_candidate(media, session, name))
+		GList *local = purple_media_get_active_local_candidates(
+				media, session, name);
+		GList *remote = purple_media_get_active_remote_candidates(
+				media, session, name);
+		gboolean result = (local == NULL || remote == NULL);
+		purple_media_candidate_list_free(local);
+		purple_media_candidate_list_free(remote);
+		if (!result)
 			return FALSE;
 	}
 
--- a/libpurple/media.h	Thu Feb 05 09:41:07 2009 +0000
+++ b/libpurple/media.h	Thu Feb 05 10:25:28 2009 +0000
@@ -533,27 +533,27 @@
 					 const gchar *name);
 
 /**
- * Gets the active local candidate for the stream.
+ * Gets the active local candidates for the stream.
  *
  * @param media The media object to find the session in.
  * @param sess_id The session id of the session to find the stream in.
  * @param name The name of the remote user to get the active candidate from.
  *
- * @return The active candidate retrieved.
+ * @return The active candidates retrieved.
  */
-PurpleMediaCandidate *purple_media_get_local_candidate(PurpleMedia *media,
+GList *purple_media_get_active_local_candidates(PurpleMedia *media,
 		const gchar *sess_id, const gchar *name);
 
 /**
- * Gets the active remote candidate for the stream.
+ * Gets the active remote candidates for the stream.
  *
  * @param media The media object to find the session in.
  * @param sess_id The session id of the session to find the stream in.
  * @param name The name of the remote user to get the remote candidate from.
  *
- * @return The remote candidate retrieved.
+ * @return The remote candidates retrieved.
  */
-PurpleMediaCandidate *purple_media_get_remote_candidate(PurpleMedia *media,
+GList *purple_media_get_active_remote_candidates(PurpleMedia *media,
 		const gchar *sess_id, const gchar *name);
 
 /**