cpw.malu.xmpp.google_ft: b06c4ed4: cache remote candidates until gathering ...

malu at pidgin.im malu at pidgin.im
Sat Sep 18 16:55:41 EDT 2010


----------------------------------------------------------------------
Revision: b06c4ed49f9dc58fabc28129333a3e89b6c731f9
Parent:   99ea19f591116be7fb6e5c0ac3be63f5674f98d8
Author:   malu at pidgin.im
Date:     09/18/10 16:53:43
Branch:   im.pidgin.cpw.malu.xmpp.google_ft
URL: http://d.pidgin.im/viewmtn/revision/info/b06c4ed49f9dc58fabc28129333a3e89b6c731f9

Changelog: 

cache remote candidates until gathering local candidates is done

Changes against parent 99ea19f591116be7fb6e5c0ac3be63f5674f98d8

  patched  libpurple/protocols/jabber/google/google_session.c
  patched  libpurple/protocols/jabber/google/google_session.h
  patched  libpurple/protocols/jabber/google/google_share.c

-------------- next part --------------
============================================================
--- libpurple/protocols/jabber/google/google_session.c	27a96dbf91e538b91c5042983cbd2bb94b3b2c9b
+++ libpurple/protocols/jabber/google/google_session.c	3a9c554d7b8e6a22c4234bbbb9ffe8b02b48dd63
@@ -119,7 +119,15 @@ google_session_handle_terminate(JabberSt
 		session->handle_terminate_cb(js, session, sess);
 }
 
+static void
+google_session_handle_transport_info(JabberStream *js, GoogleSession *session, xmlnode *sess)
+{
+	if (session->handle_transport_info_cb) {
+		session->handle_transport_info_cb(js, session, sess);
+	}
+}
 
+
 static void
 google_session_parse_iq(JabberStream *js, GoogleSession *session, xmlnode *sess, const char *iq_id)
 {
@@ -135,6 +143,8 @@ google_session_parse_iq(JabberStream *js
 		google_session_handle_terminate(js, session, sess);
 	} else if (!strcmp(type, "candidates")) {
 		google_session_handle_candidates(js, session, sess, iq_id);
+	} else if (!strcmp(type, "transport-info")) {
+		google_session_handle_transport_info(js, session, sess);
 	}
 }
 
============================================================
--- libpurple/protocols/jabber/google/google_session.h	71be0f1a2ac2c6645530017dc7c3dfb61869f47b
+++ libpurple/protocols/jabber/google/google_session.h	ca0693d368f690df983b90e2233fd93512683539
@@ -50,6 +50,10 @@ typedef void (GoogleSessionHandleTermina
 typedef void (GoogleSessionHandleTerminateCallback)
     (JabberStream *js, GoogleSession *session, xmlnode *sess);
 
+typedef void (GoogleSessionHandleTransportInfoCallback)
+    (JabberStream *js, GoogleSession *session, xmlnode *sess);
+
+
 struct _GoogleSession {
 	GoogleSessionId id;
 	GoogleSessionState state;
@@ -63,6 +67,7 @@ struct _GoogleSession {
 	GoogleSessionHandleAcceptCallback *handle_accept_cb;
 	GoogleSessionHandleRejectCallback *handle_reject_cb;
 	GoogleSessionHandleTerminateCallback *handle_terminate_cb;
+	GoogleSessionHandleTransportInfoCallback *handle_transport_info_cb;
 };
 
 void jabber_google_session_destroy(GoogleSession *session);
============================================================
--- libpurple/protocols/jabber/google/google_share.c	4a58e1b09220595ee7b110487f0ee5e8f2b55d0f
+++ libpurple/protocols/jabber/google/google_share.c	6ea43e9476207afe8b54a037fc8a3e208fae7cfe
@@ -33,9 +33,10 @@ typedef struct {
 	NiceAgent *agent;
 	guint stream_id;
 	gchar *channel_name;
-	GList *remote_candidates; /* list of PurpleMediaCandidate */
+	GSList *remote_candidates; /* list of PurpleMediaCandidate */
 	gboolean got_relay;		/* this indicates if gotten relay credentials */
 	gboolean old_protocol;
+	gboolean candidate_gathering_done;
 } GoogleShareSessionData;
 
 static void
@@ -51,6 +52,86 @@ google_share_writable_cb(NiceAgent *agen
 	purple_debug_info("google-share", "tranport writable!\n");
 }
 
+static NiceCandidate *
+google_share_get_nice_candidate_from_xml(const xmlnode *candidate,
+	guint stream_id)
+{
+	NiceCandidate *cand = NULL;
+	const gchar *name = xmlnode_get_attrib(candidate, "name");
+	const gchar *type = xmlnode_get_attrib(candidate, "type");
+	const gchar *address = xmlnode_get_attrib(candidate, "address");
+	const gchar *port = xmlnode_get_attrib(candidate, "port");
+	const gchar *protocol = xmlnode_get_attrib(candidate, "protocol");
+	const gchar *preference = xmlnode_get_attrib(candidate, "preference");
+	
+	if (name && type && address && port) {
+		guint prio = preference ? atof(preference) * 1000 : 0;
+		cand = nice_candidate_new(purple_strequal(type, "host") ?
+			NICE_CANDIDATE_TYPE_HOST :
+			purple_strequal(type, "stun") ? NICE_CANDIDATE_TYPE_SERVER_REFLEXIVE :
+			purple_strequal(type, "relay") ? NICE_CANDIDATE_TYPE_RELAYED :
+			NICE_CANDIDATE_TYPE_HOST);
+
+		cand->priority = prio;
+		cand->stream_id = stream_id;
+		cand->username = g_strdup(xmlnode_get_attrib(candidate, "username"));
+		cand->password = g_strdup(xmlnode_get_attrib(candidate, "password"));
+	} else {
+		purple_debug_error("google-share", "received invalid candidate!\n");
+	}
+
+	return cand;
+}
+
+static void
+google_share_candidate_list_free(GSList *candidates)
+{
+	while (candidates) {
+		NiceCandidate *cand = (NiceCandidate *) candidates->data;
+
+		nice_candidate_free(cand);
+		candidates = g_slist_delete_link(candidates, candidates);
+	}
+}
+
+static void
+google_share_handle_transport_info(JabberStream *js, GoogleSession *session,
+	xmlnode *sess)
+{
+	GoogleShareSessionData *session_data =
+		(GoogleShareSessionData *) session->session_data;
+	NiceAgent *agent = session_data->agent;
+	xmlnode *transport =
+		xmlnode_get_child_with_namespace(sess, "transport", NS_GOOGLE_TRANSPORT_P2P);
+
+	purple_debug_info("google-share", "got transport-info\n");
+
+	if (transport) {
+		GSList *candidates = NULL;
+		xmlnode *candidate;
+
+		for (candidate = xmlnode_get_child(transport, "candidate") ;
+		     candidate ; candidate = xmlnode_get_next_twin(candidate)) {
+			NiceCandidate *cand =
+				google_share_get_nice_candidate_from_xml(candidate,
+					session_data->stream_id);
+
+			if (cand) {
+				candidates = g_slist_append(candidates, cand);
+			}
+		}
+
+		if (session_data->candidate_gathering_done) {
+			nice_agent_set_remote_candidates(agent, session_data->stream_id,
+				NICE_COMPONENT_TYPE_RTP, candidates);
+			google_share_candidate_list_free(candidates);
+		} else {
+			session_data->remote_candidates =
+				g_slist_concat(session_data->remote_candidates, candidates);
+		}
+	}
+}
+
 static xmlnode *
 google_share_nice_candidate_to_xml(const NiceCandidate *cand,
 	const gchar *channel_name)
@@ -119,7 +200,14 @@ google_share_candidate_gathering_done_cb
 		session_data->stream_id, NICE_COMPONENT_TYPE_RTP);
 
 	purple_debug_info("google-share", "candidate gathering done!\n");
+	session_data->candidate_gathering_done = TRUE;
 
+	/* add remote candidates received while gathering local candidates */
+	nice_agent_set_remote_candidates(agent, session_data->stream_id,
+		NICE_COMPONENT_TYPE_RTP, session_data->remote_candidates);
+	google_share_candidate_list_free(session_data->remote_candidates);
+
+	/* send local candidates */
 	while (candidates) {
 		NiceCandidate *candidate = (NiceCandidate *) candidates->data;
 		JabberIq *iq = jabber_iq_new(session->js, JABBER_IQ_SET);
@@ -341,6 +429,7 @@ void google_share_handle_initiate(Jabber
 		google_share_request_denied);
 	session_data->xfer->data = session;
 	session->session_data = session_data;
+	session->handle_transport_info_cb = google_share_handle_transport_info;
 	
 	if (js->google_relay_host && js->google_relay_token) {
 		jabber_google_do_relay_request(js, session, 


More information about the Commits mailing list