Mercurial > pidgin
changeset 26304:7e24c04ab5c9
merge of '932de261b2c091dd834f54518d4c9df53b9ad7ac'
and 'ef1c8c06e832e807799e7e2785305b34f7a257b2'
author | Mike Ruprecht <maiku@soc.pidgin.im> |
---|---|
date | Thu, 19 Mar 2009 10:46:41 +0000 |
parents | 95794e9acf71 (diff) 3824cd706fa3 (current diff) |
children | 189ac8d13103 |
files | libpurple/protocols/jabber/jingle/session.c |
diffstat | 11 files changed, 273 insertions(+), 124 deletions(-) [+] |
line wrap: on
line diff
--- a/libpurple/media.c Thu Mar 19 10:46:34 2009 +0000 +++ b/libpurple/media.c Thu Mar 19 10:46:41 2009 +0000 @@ -126,6 +126,7 @@ enum { ERROR, ACCEPTED, + CANDIDATES_PREPARED, CODECS_CHANGED, NEW_CANDIDATE, READY_NEW, @@ -234,6 +235,11 @@ G_SIGNAL_RUN_LAST, 0, NULL, NULL, purple_smarshal_VOID__STRING_STRING, G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_STRING); + purple_media_signals[CANDIDATES_PREPARED] = g_signal_new("candidates-prepared", G_TYPE_FROM_CLASS(klass), + G_SIGNAL_RUN_LAST, 0, NULL, NULL, + purple_smarshal_VOID__STRING_STRING, + G_TYPE_NONE, 2, G_TYPE_STRING, + G_TYPE_STRING); purple_media_signals[CODECS_CHANGED] = g_signal_new("codecs-changed", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__STRING, @@ -260,7 +266,7 @@ purple_media_init (PurpleMedia *media) { media->priv = PURPLE_MEDIA_GET_PRIVATE(media); - memset(media->priv, 0, sizeof(media->priv)); + memset(media->priv, 0, sizeof(*media->priv)); } static void @@ -355,7 +361,7 @@ priv->manager = NULL; } - G_OBJECT_CLASS(parent_class)->finalize(media); + G_OBJECT_CLASS(parent_class)->dispose(media); } static void @@ -1724,6 +1730,10 @@ stream_data = purple_media_get_stream(session->media, session->id, name); stream_data->candidates_prepared = TRUE; + g_signal_emit(session->media, + purple_media_signals[CANDIDATES_PREPARED], + 0, session->id, name); + purple_media_emit_ready(session->media, session, name); g_free(name); }
--- a/libpurple/protocols/jabber/jingle/content.c Thu Mar 19 10:46:34 2009 +0000 +++ b/libpurple/protocols/jabber/jingle/content.c Thu Mar 19 10:46:41 2009 +0000 @@ -152,7 +152,7 @@ jingle_content_init (JingleContent *content) { content->priv = JINGLE_CONTENT_GET_PRIVATE(content); - memset(content->priv, 0, sizeof(content->priv)); + memset(content->priv, 0, sizeof(*content->priv)); } static void @@ -205,13 +205,11 @@ if (content->priv->transport) g_object_unref(content->priv->transport); content->priv->transport = g_value_get_object(value); - g_object_ref(content->priv->transport); break; case PROP_PENDING_TRANSPORT: if (content->priv->pending_transport) g_object_unref(content->priv->pending_transport); content->priv->pending_transport = g_value_get_object(value); - g_object_ref(content->priv->pending_transport); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -435,6 +433,7 @@ transport = jingle_content_get_transport(content); jingle_transport_to_xml(transport, node, action); + g_object_unref(transport); } return node;
--- a/libpurple/protocols/jabber/jingle/iceudp.c Thu Mar 19 10:46:34 2009 +0000 +++ b/libpurple/protocols/jabber/jingle/iceudp.c Thu Mar 19 10:46:41 2009 +0000 @@ -68,6 +68,8 @@ new_candidate->username = g_strdup(candidate->username); new_candidate->password = g_strdup(candidate->password); + new_candidate->rem_known = candidate->rem_known; + return new_candidate; } @@ -119,6 +121,8 @@ candidate->username = g_strdup(username); candidate->password = g_strdup(password); + + candidate->rem_known = FALSE; return candidate; } @@ -177,7 +181,8 @@ jingle_iceudp_init (JingleIceUdp *iceudp) { iceudp->priv = JINGLE_ICEUDP_GET_PRIVATE(iceudp); - memset(iceudp->priv, 0, sizeof(iceudp->priv)); + iceudp->priv->local_candidates = NULL; + iceudp->priv->remote_candidates = NULL; } static void @@ -185,6 +190,8 @@ { /* JingleIceUdpPrivate *priv = JINGLE_ICEUDP_GET_PRIVATE(iceudp); */ purple_debug_info("jingle","jingle_iceudp_finalize\n"); + + G_OBJECT_CLASS(parent_class)->finalize(iceudp); } static void @@ -321,6 +328,7 @@ xmlnode_get_attrib(candidate, "rel-addr")); iceudp_candidate->relport = relport != NULL ? atoi(relport) : 0; + iceudp_candidate->rem_known = TRUE; jingle_iceudp_add_remote_candidate(JINGLE_ICEUDP(transport), iceudp_candidate); } @@ -332,31 +340,34 @@ { xmlnode *node = parent_class->to_xml(transport, content, action); - if (action == JINGLE_SESSION_INITIATE || action == JINGLE_TRANSPORT_INFO || - action == JINGLE_CONTENT_ADD || action == JINGLE_TRANSPORT_REPLACE) { - JingleIceUdpPrivate *icetransport = - JINGLE_ICEUDP_GET_PRIVATE(transport); - if (icetransport && icetransport->local_candidates) { - JingleIceUdpCandidate *candidate = - icetransport->local_candidates->data; - xmlnode_set_attrib(node, "pwd", candidate->password); - xmlnode_set_attrib(node, "ufrag", candidate->username); - } - } - - if (action == JINGLE_TRANSPORT_INFO || action == JINGLE_SESSION_ACCEPT) { + if (action == JINGLE_SESSION_INITIATE || + action == JINGLE_SESSION_ACCEPT || + action == JINGLE_TRANSPORT_INFO || + action == JINGLE_CONTENT_ADD || + action == JINGLE_TRANSPORT_REPLACE) { JingleIceUdpPrivate *priv = JINGLE_ICEUDP_GET_PRIVATE(transport); GList *iter = priv->local_candidates; + gboolean used_candidate = FALSE; for (; iter; iter = g_list_next(iter)) { JingleIceUdpCandidate *candidate = iter->data; + xmlnode *xmltransport; + gchar *component, *generation, *network, + *port, *priority; - xmlnode *xmltransport = xmlnode_new_child(node, "candidate"); - gchar *component = g_strdup_printf("%d", candidate->component); - gchar *generation = g_strdup_printf("%d", candidate->generation); - gchar *network = g_strdup_printf("%d", candidate->network); - gchar *port = g_strdup_printf("%d", candidate->port); - gchar *priority = g_strdup_printf("%d", candidate->priority); + if (candidate->rem_known == TRUE) + continue; + + used_candidate = TRUE; + candidate->rem_known = TRUE; + + xmltransport = xmlnode_new_child(node, "candidate"); + component = g_strdup_printf("%d", candidate->component); + generation = g_strdup_printf("%d", + candidate->generation); + network = g_strdup_printf("%d", candidate->network); + port = g_strdup_printf("%d", candidate->port); + priority = g_strdup_printf("%d", candidate->priority); xmlnode_set_attrib(xmltransport, "component", component); xmlnode_set_attrib(xmltransport, "foundation", candidate->foundation); @@ -388,6 +399,13 @@ g_free(port); g_free(priority); } + + if (used_candidate == TRUE) { + JingleIceUdpCandidate *candidate = + priv->local_candidates->data; + xmlnode_set_attrib(node, "pwd", candidate->password); + xmlnode_set_attrib(node, "ufrag", candidate->username); + } } return node;
--- a/libpurple/protocols/jabber/jingle/iceudp.h Thu Mar 19 10:46:34 2009 +0000 +++ b/libpurple/protocols/jabber/jingle/iceudp.h Thu Mar 19 10:46:41 2009 +0000 @@ -78,6 +78,9 @@ gchar *username; gchar *password; + + gboolean rem_known; /* TRUE if the remote side knows + * about this candidate */ }; #ifdef __cplusplus
--- a/libpurple/protocols/jabber/jingle/jingle.h Thu Mar 19 10:46:34 2009 +0000 +++ b/libpurple/protocols/jabber/jingle/jingle.h Thu Mar 19 10:46:41 2009 +0000 @@ -42,7 +42,7 @@ #define JINGLE_DTMF "urn:xmpp:jingle:dtmf:0" #define JINGLE_TRANSPORT_S5B "urn:xmpp:jingle:transports:s5b:0" #define JINGLE_TRANSPORT_IBB "urn:xmpp:jingle:transports:ibb:0" -#define JINGLE_TRANSPORT_ICEUDP "urn:xmpp:jingle:transports:ice-udp:0" +#define JINGLE_TRANSPORT_ICEUDP "urn:xmpp:jingle:transports:ice-udp:1" #define JINGLE_TRANSPORT_RAWUDP "urn:xmpp:jingle:transports:raw-udp:1" typedef enum {
--- a/libpurple/protocols/jabber/jingle/rawudp.c Thu Mar 19 10:46:34 2009 +0000 +++ b/libpurple/protocols/jabber/jingle/rawudp.c Thu Mar 19 10:46:41 2009 +0000 @@ -59,6 +59,8 @@ new_candidate->id = g_strdup(candidate->id); new_candidate->ip = g_strdup(candidate->ip); new_candidate->port = candidate->port; + + new_candidate->rem_known = candidate->rem_known; return new_candidate; } @@ -91,6 +93,8 @@ candidate->id = g_strdup(id); candidate->ip = g_strdup(ip); candidate->port = port; + + candidate->rem_known = FALSE; return candidate; } @@ -149,7 +153,8 @@ jingle_rawudp_init (JingleRawUdp *rawudp) { rawudp->priv = JINGLE_RAWUDP_GET_PRIVATE(rawudp); - memset(rawudp->priv, 0, sizeof(rawudp->priv)); + rawudp->priv->local_candidates = NULL; + rawudp->priv->remote_candidates = NULL; } static void @@ -157,6 +162,8 @@ { /* JingleRawUdpPrivate *priv = JINGLE_RAWUDP_GET_PRIVATE(rawudp); */ purple_debug_info("jingle","jingle_rawudp_finalize\n"); + + G_OBJECT_CLASS(parent_class)->finalize(rawudp); } static void @@ -277,6 +284,7 @@ atoi(xmlnode_get_attrib(candidate, "component")), xmlnode_get_attrib(candidate, "ip"), atoi(xmlnode_get_attrib(candidate, "port"))); + rawudp_candidate->rem_known = TRUE; jingle_rawudp_add_remote_candidate(JINGLE_RAWUDP(transport), rawudp_candidate); } @@ -286,6 +294,7 @@ rawudp_candidate = g_boxed_copy(JINGLE_TYPE_RAWUDP_CANDIDATE, rawudp_candidate); rawudp_candidate->component = 2; rawudp_candidate->port = rawudp_candidate->port + 1; + rawudp_candidate->rem_known = TRUE; jingle_rawudp_add_remote_candidate(JINGLE_RAWUDP(transport), rawudp_candidate); } @@ -297,17 +306,25 @@ { xmlnode *node = parent_class->to_xml(transport, content, action); - if (action == JINGLE_SESSION_INITIATE || action == JINGLE_TRANSPORT_INFO) { + if (action == JINGLE_SESSION_INITIATE || + action == JINGLE_TRANSPORT_INFO || + action == JINGLE_SESSION_ACCEPT) { JingleRawUdpPrivate *priv = JINGLE_RAWUDP_GET_PRIVATE(transport); GList *iter = priv->local_candidates; for (; iter; iter = g_list_next(iter)) { JingleRawUdpCandidate *candidate = iter->data; + xmlnode *xmltransport; + gchar *generation, *component, *port; - xmlnode *xmltransport = xmlnode_new_child(node, "candidate"); - gchar *generation = g_strdup_printf("%d", candidate->generation); - gchar *component = g_strdup_printf("%d", candidate->component); - gchar *port = g_strdup_printf("%d", candidate->port); + if (candidate->rem_known == TRUE) + continue; + candidate->rem_known = TRUE; + + xmltransport = xmlnode_new_child(node, "candidate"); + generation = g_strdup_printf("%d", candidate->generation); + component = g_strdup_printf("%d", candidate->component); + port = g_strdup_printf("%d", candidate->port); xmlnode_set_attrib(xmltransport, "generation", generation); xmlnode_set_attrib(xmltransport, "component", component);
--- a/libpurple/protocols/jabber/jingle/rawudp.h Thu Mar 19 10:46:34 2009 +0000 +++ b/libpurple/protocols/jabber/jingle/rawudp.h Thu Mar 19 10:46:41 2009 +0000 @@ -68,6 +68,9 @@ gchar *id; gchar *ip; guint port; + + gboolean rem_known; /* TRUE if the remote side knows + * about this candidate */ }; #ifdef __cplusplus
--- a/libpurple/protocols/jabber/jingle/rtp.c Thu Mar 19 10:46:34 2009 +0000 +++ b/libpurple/protocols/jabber/jingle/rtp.c Thu Mar 19 10:46:41 2009 +0000 @@ -37,6 +37,7 @@ struct _JingleRtpPrivate { gchar *media_type; + gchar *ssrc; }; #define JINGLE_RTP_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), JINGLE_TYPE_RTP, JingleRtpPrivate)) @@ -63,6 +64,7 @@ enum { PROP_0, PROP_MEDIA_TYPE, + PROP_SSRC, }; GType @@ -108,6 +110,13 @@ "The media type (\"audio\" or \"video\") for this rtp session.", NULL, G_PARAM_READWRITE)); + g_object_class_install_property(gobject_class, PROP_SSRC, + g_param_spec_string("ssrc", + "ssrc", + "The ssrc for this rtp session.", + NULL, + G_PARAM_READWRITE)); + g_type_class_add_private(klass, sizeof(JingleRtpPrivate)); } @@ -115,7 +124,7 @@ jingle_rtp_init (JingleRtp *rtp) { rtp->priv = JINGLE_RTP_GET_PRIVATE(rtp); - memset(rtp->priv, 0, sizeof(rtp->priv)); + memset(rtp->priv, 0, sizeof(*rtp->priv)); } static void @@ -125,6 +134,9 @@ purple_debug_info("jingle-rtp","jingle_rtp_finalize\n"); g_free(priv->media_type); + g_free(priv->ssrc); + + G_OBJECT_CLASS(parent_class)->finalize(rtp); } static void @@ -140,6 +152,10 @@ g_free(rtp->priv->media_type); rtp->priv->media_type = g_value_dup_string(value); break; + case PROP_SSRC: + g_free(rtp->priv->ssrc); + rtp->priv->ssrc = g_value_dup_string(value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -158,6 +174,9 @@ case PROP_MEDIA_TYPE: g_value_set_string(value, rtp->priv->media_type); break; + case PROP_SSRC: + g_value_set_string(value, rtp->priv->ssrc); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -172,6 +191,14 @@ return media_type; } +gchar * +jingle_rtp_get_ssrc(JingleContent *content) +{ + gchar *ssrc; + g_object_get(content, "ssrc", &ssrc, NULL); + return ssrc; +} + static PurpleMedia * jingle_rtp_get_media(JingleSession *session) { @@ -194,6 +221,39 @@ return media; } +static JingleRawUdpCandidate * +jingle_rtp_candidate_to_rawudp(JingleSession *session, guint generation, + PurpleMediaCandidate *candidate) +{ + gchar *id = jabber_get_next_id(jingle_session_get_js(session)); + JingleRawUdpCandidate *rawudp_candidate = + jingle_rawudp_candidate_new(id, + generation, candidate->component_id, + candidate->ip, candidate->port); + g_free(id); + return rawudp_candidate; +} + +static JingleIceUdpCandidate * +jingle_rtp_candidate_to_iceudp(JingleSession *session, guint generation, + PurpleMediaCandidate *candidate) +{ + gchar *id = jabber_get_next_id(jingle_session_get_js(session)); + JingleIceUdpCandidate *iceudp_candidate = jingle_iceudp_candidate_new( + candidate->component_id, candidate->foundation, + generation, id, candidate->ip, 0, + candidate->port, candidate->priority, "udp", + candidate->type == PURPLE_MEDIA_CANDIDATE_TYPE_HOST ? "host" : + candidate->type == PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX ? "srflx" : + candidate->type == PURPLE_MEDIA_CANDIDATE_TYPE_PRFLX ? "prflx" : + candidate->type == PURPLE_MEDIA_CANDIDATE_TYPE_RELAY ? "relay" : "", + candidate->username, candidate->password); + iceudp_candidate->reladdr = g_strdup(candidate->base_ip); + iceudp_candidate->relport = candidate->base_port; + g_free(id); + return iceudp_candidate; +} + static JingleTransport * jingle_rtp_candidates_to_transport(JingleSession *session, GType type, guint generation, GList *candidates) { @@ -202,13 +262,11 @@ JingleRawUdpCandidate *rawudp_candidate; for (; candidates; candidates = g_list_next(candidates)) { PurpleMediaCandidate *candidate = candidates->data; - gchar *id = jabber_get_next_id( - jingle_session_get_js(session)); - rawudp_candidate = jingle_rawudp_candidate_new(id, - generation, candidate->component_id, - candidate->ip, candidate->port); - jingle_rawudp_add_local_candidate(JINGLE_RAWUDP(transport), rawudp_candidate); - g_free(id); + rawudp_candidate = jingle_rtp_candidate_to_rawudp( + session, generation, candidate); + jingle_rawudp_add_local_candidate( + JINGLE_RAWUDP(transport), + rawudp_candidate); } return transport; } else if (type == JINGLE_TYPE_ICEUDP) { @@ -216,20 +274,11 @@ JingleIceUdpCandidate *iceudp_candidate; for (; candidates; candidates = g_list_next(candidates)) { PurpleMediaCandidate *candidate = candidates->data; - gchar *id = jabber_get_next_id( - jingle_session_get_js(session)); - iceudp_candidate = jingle_iceudp_candidate_new(candidate->component_id, - candidate->foundation, generation, id, candidate->ip, - 0, candidate->port, candidate->priority, "udp", - candidate->type == PURPLE_MEDIA_CANDIDATE_TYPE_HOST ? "host" : - candidate->type == PURPLE_MEDIA_CANDIDATE_TYPE_SRFLX ? "srflx" : - candidate->type == PURPLE_MEDIA_CANDIDATE_TYPE_PRFLX ? "prflx" : - candidate->type == PURPLE_MEDIA_CANDIDATE_TYPE_RELAY ? "relay" : "", - candidate->username, candidate->password); - iceudp_candidate->reladdr = g_strdup(candidate->base_ip); - iceudp_candidate->relport = candidate->base_port; - jingle_iceudp_add_local_candidate(JINGLE_ICEUDP(transport), iceudp_candidate); - g_free(id); + iceudp_candidate = jingle_rtp_candidate_to_iceudp( + session, generation, candidate); + jingle_iceudp_add_local_candidate( + JINGLE_ICEUDP(transport), + iceudp_candidate); } return transport; } else { @@ -294,6 +343,38 @@ } static void +jingle_rtp_candidates_prepared_cb(PurpleMedia *media, + gchar *sid, gchar *name, JingleSession *session) +{ + JingleContent *content = jingle_session_find_content( + session, sid, NULL); + JingleTransport *oldtransport, *transport; + GList *candidates; + + purple_debug_info("jingle-rtp", "jingle_rtp_candidates_prepared_cb\n"); + + if (content == NULL) { + purple_debug_error("jingle-rtp", + "jingle_rtp_candidates_prepared_cb: " + "Can't find session %s\n", sid); + return; + } + + oldtransport = jingle_content_get_transport(content); + candidates = purple_media_get_local_candidates(media, sid, name); + transport = JINGLE_TRANSPORT(jingle_rtp_candidates_to_transport( + session, JINGLE_IS_RAWUDP(oldtransport) ? + JINGLE_TYPE_RAWUDP : JINGLE_TYPE_ICEUDP, + 0, candidates)); + + g_list_free(candidates); + g_object_unref(oldtransport); + + jingle_content_set_pending_transport(content, transport); + jingle_content_accept_transport(content); +} + +static void jingle_rtp_codecs_changed_cb(PurpleMedia *media, gchar *sid, JingleSession *session) { @@ -304,7 +385,34 @@ static void jingle_rtp_new_candidate_cb(PurpleMedia *media, gchar *sid, gchar *name, PurpleMediaCandidate *candidate, JingleSession *session) { + JingleContent *content = jingle_session_find_content( + session, sid, NULL); + JingleTransport *transport; + purple_debug_info("jingle-rtp", "jingle_rtp_new_candidate_cb\n"); + + if (content == NULL) { + purple_debug_error("jingle-rtp", + "jingle_rtp_new_candidate_cb: " + "Can't find session %s\n", sid); + return; + } + + transport = jingle_content_get_transport(content); + + if (JINGLE_IS_ICEUDP(transport)) + jingle_iceudp_add_local_candidate(JINGLE_ICEUDP(transport), + jingle_rtp_candidate_to_iceudp( + session, 1, candidate)); + else if (JINGLE_IS_RAWUDP(transport)) + jingle_rawudp_add_local_candidate(JINGLE_RAWUDP(transport), + jingle_rtp_candidate_to_rawudp( + session, 1, candidate)); + + g_object_unref(transport); + + jabber_iq_send(jingle_session_to_packet(session, + JINGLE_TRANSPORT_INFO)); } static void @@ -318,9 +426,6 @@ g_object_unref(session); return; } - - jabber_iq_send(jingle_session_to_packet(session, - JINGLE_TRANSPORT_INFO)); } static void @@ -330,36 +435,18 @@ if (sid == NULL && name == NULL) { if (jingle_session_is_initiator(session) == TRUE) { - GList *contents = jingle_session_get_contents(session); JabberIq *iq = jingle_session_to_packet( session, JINGLE_SESSION_INITIATE); - - if (contents->data) { - JingleTransport *transport = - jingle_content_get_transport(contents->data); - if (JINGLE_IS_ICEUDP(transport)) - jabber_iq_set_callback(iq, - jingle_rtp_initiate_ack_cb, session); - } - + jabber_iq_set_callback(iq, + jingle_rtp_initiate_ack_cb, session); jabber_iq_send(iq); + g_signal_connect(G_OBJECT(media), "new-candidate", + G_CALLBACK(jingle_rtp_new_candidate_cb), session); } else { - jabber_iq_send(jingle_session_to_packet(session, JINGLE_TRANSPORT_INFO)); jabber_iq_send(jingle_session_to_packet(session, JINGLE_SESSION_ACCEPT)); + g_signal_connect(G_OBJECT(media), "new-candidate", + G_CALLBACK(jingle_rtp_new_candidate_cb), session); } - } else if (sid != NULL && name != NULL) { - JingleContent *content = jingle_session_find_content(session, sid, "initiator"); - JingleTransport *oldtransport = jingle_content_get_transport(content); - GList *candidates = purple_media_get_local_candidates(media, sid, name); - JingleTransport *transport = - JINGLE_TRANSPORT(jingle_rtp_candidates_to_transport( - session, JINGLE_IS_RAWUDP(oldtransport) ? - JINGLE_TYPE_RAWUDP : JINGLE_TYPE_ICEUDP, - 0, candidates)); - g_list_free(candidates); - - jingle_content_set_pending_transport(content, transport); - jingle_content_accept_transport(content); } } @@ -400,10 +487,10 @@ /* connect callbacks */ g_signal_connect(G_OBJECT(media), "accepted", G_CALLBACK(jingle_rtp_accepted_cb), session); + g_signal_connect(G_OBJECT(media), "candidates-prepared", + G_CALLBACK(jingle_rtp_candidates_prepared_cb), session); g_signal_connect(G_OBJECT(media), "codecs-changed", G_CALLBACK(jingle_rtp_codecs_changed_cb), session); - g_signal_connect(G_OBJECT(media), "new-candidate", - G_CALLBACK(jingle_rtp_new_candidate_cb), session); g_signal_connect(G_OBJECT(media), "ready-new", G_CALLBACK(jingle_rtp_ready_cb), session); g_signal_connect(G_OBJECT(media), "state-changed", @@ -448,6 +535,7 @@ transmitter = "nice"; else transmitter = "notransmitter"; + g_object_unref(transport); is_audio = !strcmp(media_type, "audio"); @@ -525,8 +613,11 @@ JingleContent *content = parent_class->parse(rtp); xmlnode *description = xmlnode_get_child(rtp, "description"); const gchar *media_type = xmlnode_get_attrib(description, "media"); + const gchar *ssrc = xmlnode_get_attrib(description, "ssrc"); purple_debug_info("jingle-rtp", "rtp parse\n"); g_object_set(content, "media-type", media_type, NULL); + if (ssrc != NULL) + g_object_set(content, "ssrc", ssrc, NULL); return content; } @@ -571,11 +662,15 @@ JingleSession *session = jingle_content_get_session(rtp); PurpleMedia *media = jingle_rtp_get_media(session); gchar *media_type = jingle_rtp_get_media_type(rtp); + gchar *ssrc = jingle_rtp_get_ssrc(rtp); gchar *name = jingle_content_get_name(rtp); GList *codecs = purple_media_get_codecs(media, name); xmlnode_set_attrib(description, "media", media_type); + if (ssrc != NULL) + xmlnode_set_attrib(description, "ssrc", ssrc); + g_free(media_type); g_free(name); g_object_unref(session); @@ -589,23 +684,7 @@ jingle_rtp_handle_action_internal(JingleContent *content, xmlnode *xmlcontent, JingleActionType action) { switch (action) { - case JINGLE_SESSION_ACCEPT: { - JingleSession *session = jingle_content_get_session(content); - xmlnode *description = xmlnode_get_child(xmlcontent, "description"); - GList *codecs = jingle_rtp_parse_codecs(description); - - purple_media_set_remote_codecs(jingle_rtp_get_media(session), - jingle_content_get_name(content), - jingle_session_get_remote_jid(session), codecs); - - /* This needs to be for the entire session, not a single content */ - /* very hacky */ - if (xmlnode_get_next_twin(xmlcontent) == NULL) - purple_media_accept(jingle_rtp_get_media(session)); - - g_object_unref(session); - break; - } + case JINGLE_SESSION_ACCEPT: case JINGLE_SESSION_INITIATE: { JingleSession *session = jingle_content_get_session(content); JingleTransport *transport = jingle_transport_parse( @@ -613,8 +692,13 @@ xmlnode *description = xmlnode_get_child(xmlcontent, "description"); GList *candidates = jingle_rtp_transport_to_candidates(transport); GList *codecs = jingle_rtp_parse_codecs(description); + gchar *name = jingle_content_get_name(content); + gchar *remote_jid = + jingle_session_get_remote_jid(session); + PurpleMedia *media; - if (jingle_rtp_init_media(content) == FALSE) { + if (action == JINGLE_SESSION_INITIATE && + jingle_rtp_init_media(content) == FALSE) { /* XXX: send error */ jabber_iq_send(jingle_session_terminate_packet( session, "general-error")); @@ -622,17 +706,20 @@ break; } - purple_media_set_remote_codecs(jingle_rtp_get_media(session), - jingle_content_get_name(content), - jingle_session_get_remote_jid(session), codecs); + media = jingle_rtp_get_media(session); + purple_media_set_remote_codecs(media, + name, remote_jid, codecs); + purple_media_add_remote_candidates(media, + name, remote_jid, candidates); - if (JINGLE_IS_RAWUDP(transport)) { - purple_media_add_remote_candidates(jingle_rtp_get_media(session), - jingle_content_get_name(content), - jingle_session_get_remote_jid(session), - candidates); - } + /* This needs to be for the entire session, not a single content */ + /* very hacky */ + if (action == JINGLE_SESSION_ACCEPT && + xmlnode_get_next_twin(xmlcontent) == NULL) + purple_media_accept(media); + g_free(remote_jid); + g_free(name); g_object_unref(session); break; } @@ -652,11 +739,16 @@ JingleTransport *transport = jingle_transport_parse( xmlnode_get_child(xmlcontent, "transport")); GList *candidates = jingle_rtp_transport_to_candidates(transport); + gchar *name = jingle_content_get_name(content); + gchar *remote_jid = + jingle_session_get_remote_jid(session); - purple_media_add_remote_candidates(jingle_rtp_get_media(session), - jingle_content_get_name(content), - jingle_session_get_remote_jid(session), - candidates); + purple_media_add_remote_candidates( + jingle_rtp_get_media(session), + name, remote_jid, candidates); + + g_free(remote_jid); + g_free(name); g_object_unref(session); break; }
--- a/libpurple/protocols/jabber/jingle/rtp.h Thu Mar 19 10:46:34 2009 +0000 +++ b/libpurple/protocols/jabber/jingle/rtp.h Thu Mar 19 10:46:41 2009 +0000 @@ -73,6 +73,7 @@ GType jingle_rtp_get_type(void); gchar *jingle_rtp_get_media_type(JingleContent *content); +gchar *jingle_rtp_get_ssrc(JingleContent *content); PurpleMedia *jingle_rtp_initiate_media(JabberStream *js, const gchar *who,
--- a/libpurple/protocols/jabber/jingle/session.c Thu Mar 19 10:46:34 2009 +0000 +++ b/libpurple/protocols/jabber/jingle/session.c Thu Mar 19 10:46:41 2009 +0000 @@ -154,7 +154,7 @@ jingle_session_init (JingleSession *session) { session->priv = JINGLE_SESSION_GET_PRIVATE(session); - memset(session->priv, 0, sizeof(session->priv)); + memset(session->priv, 0, sizeof(*session->priv)); } static void @@ -500,11 +500,14 @@ for (; iter; iter = g_list_next(iter)) { JingleContent *content = iter->data; gchar *cname = jingle_content_get_name(content); - gchar *ccreator = jingle_content_get_creator(content); - gboolean result = (!strcmp(name, cname) && !strcmp(creator, ccreator)); + gboolean result = !strcmp(name, cname); + g_free(cname); - g_free(cname); - g_free(ccreator); + if (creator != NULL) { + gchar *ccreator = jingle_content_get_creator(content); + result = (result && !strcmp(creator, ccreator)); + g_free(ccreator); + } if (result == TRUE) return content; @@ -519,11 +522,14 @@ for (; iter; iter = g_list_next(iter)) { JingleContent *content = iter->data; gchar *cname = jingle_content_get_name(content); - gchar *ccreator = jingle_content_get_creator(content); - gboolean result = (!strcmp(name, cname) && !strcmp(creator, ccreator)); + gboolean result = !strcmp(name, cname); + g_free(cname); - g_free(cname); - g_free(ccreator); + if (creator != NULL) { + gchar *ccreator = jingle_content_get_creator(content); + result = (result && !strcmp(creator, ccreator)); + g_free(ccreator); + } if (result == TRUE) return content;
--- a/libpurple/protocols/jabber/jingle/transport.c Thu Mar 19 10:46:34 2009 +0000 +++ b/libpurple/protocols/jabber/jingle/transport.c Thu Mar 19 10:46:41 2009 +0000 @@ -89,7 +89,7 @@ jingle_transport_init (JingleTransport *transport) { transport->priv = JINGLE_TRANSPORT_GET_PRIVATE(transport); - memset(transport->priv, 0, sizeof(transport->priv)); + transport->priv->dummy = NULL; } static void