# HG changeset patch # User Mike Ruprecht # Date 1233829528 0 # Node ID dcff28a0415c835be274504b9212768fae450e0d # Parent 4a245ffb4051586fa329e6daa09755ac911e2400 Handle having multiple active candidates. diff -r 4a245ffb4051 -r dcff28a0415c libpurple/media.c --- 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; } diff -r 4a245ffb4051 -r dcff28a0415c libpurple/media.h --- 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); /**