Mercurial > pidgin
changeset 30523:ee3226c6092f
propagate from branch 'im.pidgin.pidgin' (head 267f28808ab6eeda6b5d68f6433f2b3fcf230d4f)
to branch 'im.pidgin.cpw.malu.xmpp.google_relay' (head c60e85b2ab0b13ecca98ff251d5c5fef3604c70c)
author | Marcus Lundblad <ml@update.uu.se> |
---|---|
date | Thu, 18 Feb 2010 21:53:35 +0000 |
parents | bc2760c74a79 (current diff) 0f6ef3b21e17 (diff) |
children | 6d69151fa99b |
files | libpurple/media.c libpurple/protocols/jabber/google.c libpurple/protocols/jabber/jabber.c libpurple/protocols/jabber/jabber.h libpurple/protocols/jabber/jingle/rtp.c pidgin/gtkcelllayout.c pidgin/gtkcelllayout.h pidgin/gtkcellrendererprogress.c pidgin/gtkcellrendererprogress.h pidgin/gtkcellview.c pidgin/gtkcellview.h pidgin/gtkcellviewmenuitem.c pidgin/gtkcellviewmenuitem.h pidgin/gtkexpander.c pidgin/gtkexpander.h pidgin/pidgincombobox.c pidgin/pidgincombobox.h pidgin/pixmaps/tray/16/tray-away.png pidgin/pixmaps/tray/16/tray-busy.png pidgin/pixmaps/tray/16/tray-connecting.png pidgin/pixmaps/tray/16/tray-extended-away.png pidgin/pixmaps/tray/16/tray-invisible.png pidgin/pixmaps/tray/16/tray-message.png pidgin/pixmaps/tray/16/tray-new-im.png pidgin/pixmaps/tray/16/tray-offline.png pidgin/pixmaps/tray/16/tray-online.png pidgin/pixmaps/tray/22/tray-away.png pidgin/pixmaps/tray/22/tray-busy.png pidgin/pixmaps/tray/22/tray-connecting.png pidgin/pixmaps/tray/22/tray-extended-away.png pidgin/pixmaps/tray/22/tray-invisible.png pidgin/pixmaps/tray/22/tray-message.png pidgin/pixmaps/tray/22/tray-new-im.png pidgin/pixmaps/tray/22/tray-offline.png pidgin/pixmaps/tray/22/tray-online.png pidgin/pixmaps/tray/32/tray-away.png pidgin/pixmaps/tray/32/tray-busy.png pidgin/pixmaps/tray/32/tray-connecting.png pidgin/pixmaps/tray/32/tray-extended-away.png pidgin/pixmaps/tray/32/tray-invisible.png pidgin/pixmaps/tray/32/tray-message.png pidgin/pixmaps/tray/32/tray-new-im.png pidgin/pixmaps/tray/32/tray-offline.png pidgin/pixmaps/tray/32/tray-online.png pidgin/pixmaps/tray/48/tray-away.png pidgin/pixmaps/tray/48/tray-busy.png pidgin/pixmaps/tray/48/tray-connecting.png pidgin/pixmaps/tray/48/tray-extended-away.png pidgin/pixmaps/tray/48/tray-invisible.png pidgin/pixmaps/tray/48/tray-message.png pidgin/pixmaps/tray/48/tray-new-im.png pidgin/pixmaps/tray/48/tray-offline.png pidgin/pixmaps/tray/48/tray-online.png |
diffstat | 8 files changed, 402 insertions(+), 106 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/media.c Thu Feb 18 19:29:11 2010 +0000 +++ b/libpurple/media.c Thu Feb 18 21:53:35 2010 +0000 @@ -29,6 +29,7 @@ #include "media.h" #include "media/backend-iface.h" #include "mediamanager.h" +#include "network.h" #include "debug.h" @@ -545,7 +546,19 @@ session->media->priv->streams = g_list_append(session->media->priv->streams, media_stream); - return media_stream; +static GList * +purple_media_candidate_list_from_fs(GList *candidates) +{ + GList *new_list = NULL; + + for (; candidates; candidates = g_list_next(candidates)) { + new_list = g_list_prepend(new_list, + purple_media_candidate_from_fs( + candidates->data)); + } + + new_list = g_list_reverse(new_list); + return new_list; } static void
--- a/libpurple/protocols/jabber/Makefile.am Thu Feb 18 19:29:11 2010 +0000 +++ b/libpurple/protocols/jabber/Makefile.am Thu Feb 18 21:53:35 2010 +0000 @@ -98,7 +98,10 @@ st = pkg_LTLIBRARIES = libjabber.la libxmpp.la libjabber_la_SOURCES = $(JABBERSOURCES) -libjabber_la_LIBADD = $(GLIB_LIBS) $(SASL_LIBS) $(LIBXML_LIBS) $(IDN_LIBS) +libjabber_la_LIBADD = $(GLIB_LIBS) $(SASL_LIBS) $(LIBXML_LIBS) $(IDN_LIBS)\ + $(FARSIGHT_LIBS) \ + $(GSTREAMER_LIBS) \ + $(GSTINTERFACES_LIBS) libxmpp_la_SOURCES = libxmpp.c libxmpp_la_LIBADD = libjabber.la @@ -111,4 +114,7 @@ $(DEBUG_CFLAGS) \ $(GLIB_CFLAGS) \ $(IDN_CFLAGS) \ - $(LIBXML_CFLAGS) + $(LIBXML_CFLAGS) \ + $(FARSIGHT_CFLAGS) \ + $(GSTREAMER_CFLAGS) \ + $(GSTINTERFACES_CFLAGS)
--- a/libpurple/protocols/jabber/google.c Thu Feb 18 19:29:11 2010 +0000 +++ b/libpurple/protocols/jabber/google.c Thu Feb 18 21:53:35 2010 +0000 @@ -58,6 +58,7 @@ JabberStream *js; char *remote_jid; gboolean video; + char *iq_id; } GoogleSession; static gboolean @@ -75,6 +76,7 @@ g_free(session->id.id); g_free(session->id.initiator); g_free(session->remote_jid); + g_free(session->iq_id); g_free(session); } @@ -322,10 +324,14 @@ } static GParameter * -jabber_google_session_get_params(JabberStream *js, guint *num) +jabber_google_session_get_params(JabberStream *js, const gchar *relay_ip, + guint16 relay_udp, guint16 relay_tcp, guint16 relay_ssltcp, + const gchar *relay_username, const gchar *relay_password, guint *num) { guint num_params; - GParameter *params = jingle_get_params(js, &num_params); + GParameter *params = + jingle_get_params(js, relay_ip, relay_udp, relay_tcp, relay_ssltcp, + relay_username, relay_password, &num_params); GParameter *new_params = g_new0(GParameter, num_params + 1); memcpy(new_params, params, sizeof(GParameter) * num_params); @@ -340,6 +346,149 @@ return new_params; } +static void +jabber_google_relay_parse_response(const gchar *response, gchar **ip, + guint *udp, guint *tcp, guint *ssltcp, gchar **username, gchar **password) +{ + gchar **lines = g_strsplit(response, "\n", -1); + int i = 0; + + for (; lines[i] ; i++) { + gchar *line = lines[i]; + gchar **parts = g_strsplit(line, "=", 2); + + if (parts[0] && parts[1]) { + if (purple_strequal(parts[0], "relay.ip")) { + *ip = g_strdup(parts[1]); + } else if (purple_strequal(parts[0], "relay.udp_port")) { + *udp = atoi(parts[1]); + } else if (purple_strequal(parts[0], "relay.tcp_port")) { + *tcp = atoi(parts[1]); + } else if (purple_strequal(parts[0], "relay.ssltcp_port")) { + *ssltcp = atoi(parts[1]); + } else if (purple_strequal(parts[0], "username")) { + *username = g_strdup(parts[1]); + } else if (purple_strequal(parts[0], "password")) { + *password = g_strdup(parts[1]); + } + } + g_strfreev(parts); + } + + g_strfreev(lines); +} + +static void +jabber_google_relay_remove_url_data(JabberStream *js, + PurpleUtilFetchUrlData *url_data) +{ + GList *iter = js->google_relay_requests; + + while (iter) { + if (iter->data == url_data) { + js->google_relay_requests = + g_list_delete_link(js->google_relay_requests, iter); + break; + } + } +} + +static void +jabber_google_relay_response_session_initiate_cb(PurpleUtilFetchUrlData *url_data, + gpointer user_data, const gchar *url_text, gsize len, + const gchar *error_message) +{ + GoogleSession *session = (GoogleSession *) user_data; + GParameter *params; + guint num_params; + JabberStream *js = session->js; + gchar *relay_ip = NULL; + guint relay_udp = 0; + guint relay_tcp = 0; + guint relay_ssltcp = 0; + gchar *relay_username = NULL; + gchar *relay_password = NULL; + + if (url_data) { + jabber_google_relay_remove_url_data(js, url_data); + } + + purple_debug_info("jabber", "got response on HTTP request to relay server\n"); + + if (url_text && len > 0) { + purple_debug_info("jabber", "got Google relay request response:\n%s\n", + url_text); + jabber_google_relay_parse_response(url_text, &relay_ip, &relay_udp, + &relay_tcp, &relay_ssltcp, &relay_username, &relay_password); + } + + session->media = purple_media_manager_create_media( + purple_media_manager_get(), + purple_connection_get_account(js->gc), + "fsrtpconference", session->remote_jid, TRUE); + + purple_media_set_prpl_data(session->media, session); + + g_signal_connect_swapped(G_OBJECT(session->media), + "candidates-prepared", + G_CALLBACK(google_session_ready), session); + g_signal_connect_swapped(G_OBJECT(session->media), "codecs-changed", + G_CALLBACK(google_session_ready), session); + g_signal_connect(G_OBJECT(session->media), "state-changed", + G_CALLBACK(google_session_state_changed_cb), session); + g_signal_connect(G_OBJECT(session->media), "stream-info", + G_CALLBACK(google_session_stream_info_cb), session); + + params = + jabber_google_session_get_params(js, relay_ip, relay_udp, relay_tcp, + relay_ssltcp, relay_username, relay_password, &num_params); + + g_free(relay_ip); + g_free(relay_username); + g_free(relay_password); + + if (purple_media_add_stream(session->media, "google-voice", + session->remote_jid, PURPLE_MEDIA_AUDIO, + TRUE, "nice", num_params, params) == FALSE || + (session->video && purple_media_add_stream( + session->media, "google-video", + session->remote_jid, PURPLE_MEDIA_VIDEO, + TRUE, "nice", num_params, params) == FALSE)) { + purple_media_error(session->media, "Error adding stream."); + purple_media_end(session->media, NULL, NULL); + g_free(params); + } + + g_free(params); +} + +static void +jabber_google_do_relay_request(JabberStream *js, GoogleSession *session, + PurpleUtilFetchUrlCallback cb) +{ + PurpleUtilFetchUrlData *url_data = NULL; + gchar *url = g_strdup_printf("http://%s", js->google_relay_host); + gchar *request = + g_strdup_printf("GET /create_session HTTP/1.0\r\n" + "Host: %s\r\n" + "X-Talk-Google-Relay-Auth: %s\r\n" + "X-Google-Relay-Auth: %s\r\n\r\n", + js->google_relay_host, js->google_relay_token, js->google_relay_token); + purple_debug_info("jabber", + "sending Google relay request %s to %s\n", request, url); + url_data = + purple_util_fetch_url_request(url, FALSE, NULL, FALSE, request, FALSE, + cb, session); + if (url_data) { + js->google_relay_requests = + g_list_prepend(js->google_relay_requests, url_data); + } else { + purple_debug_error("jabber", "unable to create Google relay request\n"); + cb(NULL, session, NULL, 0, NULL); + } + g_free(url); + g_free(request); +} gboolean jabber_google_session_initiate(JabberStream *js, const gchar *who, PurpleMediaSessionType type) @@ -348,8 +497,6 @@ JabberBuddy *jb; JabberBuddyResource *jbr; gchar *jid; - GParameter *params; - guint num_params; /* construct JID to send to */ jb = jabber_buddy_find(js, who, FALSE); @@ -381,90 +528,59 @@ if (type & PURPLE_MEDIA_VIDEO) session->video = TRUE; - session->media = purple_media_manager_create_media( - purple_media_manager_get(), - purple_connection_get_account(js->gc), - "fsrtpconference", session->remote_jid, TRUE); - - purple_media_set_prpl_data(session->media, session); - - g_signal_connect_swapped(G_OBJECT(session->media), - "candidates-prepared", - G_CALLBACK(google_session_ready), session); - g_signal_connect_swapped(G_OBJECT(session->media), "codecs-changed", - G_CALLBACK(google_session_ready), session); - g_signal_connect(G_OBJECT(session->media), "state-changed", - G_CALLBACK(google_session_state_changed_cb), session); - g_signal_connect(G_OBJECT(session->media), "stream-info", - G_CALLBACK(google_session_stream_info_cb), session); - - params = jabber_google_session_get_params(js, &num_params); - - if (purple_media_add_stream(session->media, "google-voice", - session->remote_jid, PURPLE_MEDIA_AUDIO, - TRUE, "nice", num_params, params) == FALSE || - (session->video && purple_media_add_stream( - session->media, "google-video", - session->remote_jid, PURPLE_MEDIA_VIDEO, - TRUE, "nice", num_params, params) == FALSE)) { - purple_media_error(session->media, "Error adding stream."); - purple_media_end(session->media, NULL, NULL); - g_free(params); - return FALSE; + /* if we got a relay token and relay host in google:jingleinfo, issue an + HTTP request to get that data */ + if (js->google_relay_host && js->google_relay_token) { + jabber_google_do_relay_request(js, session, + jabber_google_relay_response_session_initiate_cb); + } else { + jabber_google_relay_response_session_initiate_cb(NULL, session, NULL, 0, + NULL); } - - g_free(params); - - return (session->media != NULL) ? TRUE : FALSE; + + /* we don't actually know yet wether it succeeded... maybe this is very + wrong... */ + return TRUE; } -static gboolean -google_session_handle_initiate(JabberStream *js, GoogleSession *session, xmlnode *sess, const char *iq_id) +static void +jabber_google_relay_response_session_handle_initiate_cb( + PurpleUtilFetchUrlData *url_data, + gpointer user_data, const gchar *url_text, gsize len, + const gchar *error_message) { - JabberIq *result; - GList *codecs = NULL, *video_codecs = NULL; - xmlnode *desc_element, *codec_element; - PurpleMediaCodec *codec; - const char *xmlns; + GoogleSession *session = (GoogleSession *) user_data; GParameter *params; guint num_params; + JabberStream *js = session->js; + gchar *relay_ip = NULL; + guint relay_udp = 0; + guint relay_tcp = 0; + guint relay_ssltcp = 0; + gchar *relay_username = NULL; + gchar *relay_password = NULL; + xmlnode *codec_element; + xmlnode *desc_element; + const gchar *xmlns; + PurpleMediaCodec *codec; + GList *video_codecs = NULL; + GList *codecs = NULL; + JabberIq *result; - if (session->state != UNINIT) { - purple_debug_error("jabber", "Received initiate for active session.\n"); - return FALSE; + if (url_data) { + jabber_google_relay_remove_url_data(js, url_data); } - desc_element = xmlnode_get_child(sess, "description"); - xmlns = xmlnode_get_namespace(desc_element); - - if (purple_strequal(xmlns, NS_GOOGLE_SESSION_PHONE)) - session->video = FALSE; - else if (purple_strequal(xmlns, NS_GOOGLE_SESSION_VIDEO)) - session->video = TRUE; - else { - purple_debug_error("jabber", "Received initiate with " - "invalid namespace %s.\n", xmlns); - return FALSE; + if (url_text && len > 0) { + purple_debug_info("jabber", "got Google relay request response:\n%s\n", + url_text); + jabber_google_relay_parse_response(url_text, &relay_ip, &relay_udp, + &relay_tcp, &relay_ssltcp, &relay_username, &relay_password); } - session->media = purple_media_manager_create_media( - purple_media_manager_get(), - purple_connection_get_account(js->gc), - "fsrtpconference", session->remote_jid, FALSE); - - purple_media_set_prpl_data(session->media, session); - - g_signal_connect_swapped(G_OBJECT(session->media), - "candidates-prepared", - G_CALLBACK(google_session_ready), session); - g_signal_connect_swapped(G_OBJECT(session->media), "codecs-changed", - G_CALLBACK(google_session_ready), session); - g_signal_connect(G_OBJECT(session->media), "state-changed", - G_CALLBACK(google_session_state_changed_cb), session); - g_signal_connect(G_OBJECT(session->media), "stream-info", - G_CALLBACK(google_session_stream_info_cb), session); - - params = jabber_google_session_get_params(js, &num_params); + params = + jabber_google_session_get_params(js, relay_ip, relay_udp, relay_tcp, + relay_ssltcp, relay_username, relay_password, &num_params); if (purple_media_add_stream(session->media, "google-voice", session->remote_jid, PURPLE_MEDIA_AUDIO, FALSE, @@ -477,7 +593,6 @@ purple_media_stream_info(session->media, PURPLE_MEDIA_INFO_REJECT, NULL, NULL, TRUE); g_free(params); - return FALSE; } g_free(params); @@ -533,9 +648,61 @@ purple_media_codec_list_free(video_codecs); result = jabber_iq_new(js, JABBER_IQ_RESULT); - jabber_iq_set_id(result, iq_id); + jabber_iq_set_id(result, session->iq_id); xmlnode_set_attrib(result->node, "to", session->remote_jid); jabber_iq_send(result); +} + +static gboolean +google_session_handle_initiate(JabberStream *js, GoogleSession *session, xmlnode *sess, const char *iq_id) +{ + xmlnode *desc_element; + const gchar *xmlns; + + if (session->state != UNINIT) { + purple_debug_error("jabber", "Received initiate for active session.\n"); + return FALSE; + } + + desc_element = xmlnode_get_child(sess, "description"); + xmlns = xmlnode_get_namespace(desc_element); + + if (purple_strequal(xmlns, NS_GOOGLE_SESSION_PHONE)) + session->video = FALSE; + else if (purple_strequal(xmlns, NS_GOOGLE_SESSION_VIDEO)) + session->video = TRUE; + else { + purple_debug_error("jabber", "Received initiate with " + "invalid namespace %s.\n", xmlns); + return FALSE; + } + + session->media = purple_media_manager_create_media( + purple_media_manager_get(), + purple_connection_get_account(js->gc), + "fsrtpconference", session->remote_jid, FALSE); + + purple_media_set_prpl_data(session->media, session); + + g_signal_connect_swapped(G_OBJECT(session->media), + "candidates-prepared", + G_CALLBACK(google_session_ready), session); + g_signal_connect_swapped(G_OBJECT(session->media), "codecs-changed", + G_CALLBACK(google_session_ready), session); + g_signal_connect(G_OBJECT(session->media), "state-changed", + G_CALLBACK(google_session_state_changed_cb), session); + g_signal_connect(G_OBJECT(session->media), "stream-info", + G_CALLBACK(google_session_stream_info_cb), session); + + session->iq_id = g_strdup(iq_id); + + if (js->google_relay_host && js->google_relay_token) { + jabber_google_do_relay_request(js, session, + jabber_google_relay_response_session_handle_initiate_cb); + } else { + jabber_google_relay_response_session_handle_initiate_cb(NULL, session, + NULL, 0, NULL); + } return TRUE; } @@ -1319,6 +1486,7 @@ JabberIqType type, xmlnode *query) { const xmlnode *stun = xmlnode_get_child(query, "stun"); + const xmlnode *relay = xmlnode_get_child(query, "relay"); gchar *my_bare_jid; /* @@ -1362,8 +1530,23 @@ } } } - /* should perhaps handle relays later on, or maybe wait until - Google supports a common standard... */ + + if (relay) { + xmlnode *token = xmlnode_get_child(relay, "token"); + xmlnode *server = xmlnode_get_child(relay, "server"); + + if (token) { + gchar *relay_token = xmlnode_get_data(token); + + /* we let js own the string returned from xmlnode_get_data */ + js->google_relay_token = relay_token; + } + + if (server) { + js->google_relay_host = + g_strdup(xmlnode_get_attrib(server, "host")); + } + } } static void
--- a/libpurple/protocols/jabber/jabber.c Thu Feb 18 19:29:11 2010 +0000 +++ b/libpurple/protocols/jabber/jabber.c Thu Feb 18 21:53:35 2010 +0000 @@ -866,6 +866,9 @@ js->stun_ip = NULL; js->stun_port = 0; js->stun_query = NULL; + js->google_relay_token = NULL; + js->google_relay_host = NULL; + js->google_relay_requests = NULL; /* if we are idle, set idle-ness on the stream (this could happen if we get disconnected and the reconnects while being idle. I don't think it makes @@ -1565,6 +1568,21 @@ js->stun_query = NULL; } + /* remove Google relay-related stuff */ + g_free(js->google_relay_token); + g_free(js->google_relay_host); + if (js->google_relay_requests) { + while (js->google_relay_requests) { + PurpleUtilFetchUrlData *url_data = + (PurpleUtilFetchUrlData *) js->google_relay_requests->data; + purple_util_fetch_url_cancel(url_data); + g_free(url_data); + js->google_relay_requests = + g_list_delete_link(js->google_relay_requests, + js->google_relay_requests); + } + } + g_free(js); gc->proto_data = NULL; @@ -3021,10 +3039,14 @@ jbr = jabber_buddy_find_resource(jb, resource); g_free(resource); - if (type & PURPLE_MEDIA_AUDIO && - !jabber_resource_has_capability(jbr, - JINGLE_APP_RTP_SUPPORT_AUDIO) && - jabber_resource_has_capability(jbr, NS_GOOGLE_VOICE)) + /* if we are on a Google Talk connection and the remote supports + Google Jingle, we will go with that */ + if (((js->googletalk && js->google_relay_token) || + !jabber_resource_has_capability(jbr, JINGLE_APP_RTP_SUPPORT_AUDIO)) + && (((type & PURPLE_MEDIA_AUDIO) && + jabber_resource_has_capability(jbr, NS_GOOGLE_VOICE)) + || ((type & PURPLE_MEDIA_VIDEO) && + jabber_resource_has_capability(jbr, NS_GOOGLE_VIDEO)))) return jabber_google_session_initiate(js, who, type); else return jingle_rtp_initiate_media(js, who, type);
--- a/libpurple/protocols/jabber/jabber.h Thu Feb 18 19:29:11 2010 +0000 +++ b/libpurple/protocols/jabber/jabber.h Thu Feb 18 21:53:35 2010 +0000 @@ -264,7 +264,12 @@ gchar *stun_ip; int stun_port; PurpleDnsQueryData *stun_query; - /* later add stuff to handle TURN relays... */ + + /* stuff for Google's relay handling */ + gchar *google_relay_token; + gchar *google_relay_host; + GList *google_relay_requests; /* the HTTP requests to get */ + /* relay info */ }; typedef gboolean (JabberFeatureEnabled)(JabberStream *js, const gchar *namespace);
--- a/libpurple/protocols/jabber/jingle/jingle.c Thu Feb 18 19:29:11 2010 +0000 +++ b/libpurple/protocols/jabber/jingle/jingle.c Thu Feb 18 21:53:35 2010 +0000 @@ -35,6 +35,9 @@ #include "rtp.h" #include <string.h> +#ifdef USE_VV +#include <gst/gst.h> +#endif GType jingle_get_type(const gchar *type) @@ -431,32 +434,91 @@ jingle_terminate_sessions_gh, NULL); } +#ifdef USE_VV +static GValueArray * +jingle_create_relay_info(const gchar *ip, guint port, const gchar *username, + const gchar *password, const gchar *relay_type, GValueArray *relay_info) +{ + GValue value; + GstStructure *turn_setup = gst_structure_new("relay-info", + "ip", G_TYPE_STRING, ip, + "port", G_TYPE_UINT, port, + "username", G_TYPE_STRING, username, + "password", G_TYPE_STRING, password, + "relay-type", G_TYPE_STRING, relay_type, + NULL); + purple_debug_info("jabber", "created gst_structure %" GST_PTR_FORMAT "\n", + turn_setup); + if (turn_setup) { + memset(&value, 0, sizeof(GValue)); + g_value_init(&value, GST_TYPE_STRUCTURE); + gst_value_set_structure(&value, turn_setup); + relay_info = g_value_array_append(relay_info, &value); + gst_structure_free(turn_setup); + } + return relay_info; +} + GParameter * -jingle_get_params(JabberStream *js, guint *num) +jingle_get_params(JabberStream *js, const gchar *relay_ip, guint relay_udp, + guint relay_tcp, guint relay_ssltcp, const gchar *relay_username, + const gchar *relay_password, guint *num) { /* don't set a STUN server if one is set globally in prefs, in that case this will be handled in media.c */ gboolean has_account_stun = js->stun_ip && !purple_network_get_stun_ip(); - guint num_params = has_account_stun ? 2 : 0; + guint num_params = has_account_stun ? + (relay_ip ? 3 : 2) : (relay_ip ? 1 : 0); GParameter *params = NULL; - + int next_index = 0; + if (num_params > 0) { params = g_new0(GParameter, num_params); - purple_debug_info("jabber", - "setting param stun-ip for stream using auto-discovered IP: %s\n", - js->stun_ip); - params[0].name = "stun-ip"; - g_value_init(¶ms[0].value, G_TYPE_STRING); - g_value_set_string(¶ms[0].value, js->stun_ip); - purple_debug_info("jabber", - "setting param stun-port for stream using auto-discovered port: %d\n", - js->stun_port); - params[1].name = "stun-port"; - g_value_init(¶ms[1].value, G_TYPE_UINT); - g_value_set_uint(¶ms[1].value, js->stun_port); + if (has_account_stun) { + purple_debug_info("jabber", + "setting param stun-ip for stream using Google auto-config: %s\n", + js->stun_ip); + params[next_index].name = "stun-ip"; + g_value_init(¶ms[next_index].value, G_TYPE_STRING); + g_value_set_string(¶ms[next_index].value, js->stun_ip); + purple_debug_info("jabber", + "setting param stun-port for stream using Google auto-config: %d\n", + js->stun_port); + next_index++; + params[next_index].name = "stun-port"; + g_value_init(¶ms[next_index].value, G_TYPE_UINT); + g_value_set_uint(¶ms[next_index].value, js->stun_port); + next_index++; + } + + if (relay_ip) { + GValueArray *relay_info = g_value_array_new(0); + + if (relay_udp) { + relay_info = + jingle_create_relay_info(relay_ip, relay_udp, relay_username, + relay_password, "udp", relay_info); + } + if (relay_tcp) { + relay_info = + jingle_create_relay_info(relay_ip, relay_tcp, relay_username, + relay_password, "tcp", relay_info); + } + if (relay_ssltcp) { + relay_info = + jingle_create_relay_info(relay_ip, relay_ssltcp, relay_username, + relay_password, "tls", relay_info); + } + params[next_index].name = "relay-info"; + g_value_init(¶ms[next_index].value, G_TYPE_VALUE_ARRAY); + g_value_set_boxed(¶ms[next_index].value, relay_info); + g_value_array_free(relay_info); + } } *num = num_params; return params; } +#endif +
--- a/libpurple/protocols/jabber/jingle/jingle.h Thu Feb 18 19:29:11 2010 +0000 +++ b/libpurple/protocols/jabber/jingle/jingle.h Thu Feb 18 21:53:35 2010 +0000 @@ -78,9 +78,13 @@ void jingle_terminate_sessions(JabberStream *js); +#ifdef USE_VV /* create a GParam array given autoconfigured STUN (and later perhaps TURN). if google_talk is TRUE, set compatability mode to GOOGLE_TALK */ -GParameter *jingle_get_params(JabberStream *js, guint *num_params); +GParameter *jingle_get_params(JabberStream *js, const gchar *relay_ip, + guint relay_udp, guint relay_tcp, guint relay_ssltcp, + const gchar *relay_username, const gchar *relay_password, guint *num_params); +#endif #ifdef __cplusplus }
--- a/libpurple/protocols/jabber/jingle/rtp.c Thu Feb 18 19:29:11 2010 +0000 +++ b/libpurple/protocols/jabber/jingle/rtp.c Thu Feb 18 21:53:35 2010 +0000 @@ -611,7 +611,8 @@ : PURPLE_MEDIA_RECV_VIDEO; params = - jingle_get_params(jingle_session_get_js(session), &num_params); + jingle_get_params(jingle_session_get_js(session), NULL, 0, 0, 0, + NULL, NULL, &num_params); creator = jingle_content_get_creator(content); if (!strcmp(creator, "initiator"))