Mercurial > pidgin
diff libpurple/protocols/jabber/jabber.c @ 23816:e73b03097664
Moved Jingle message handlers from jabber.c to jingle.c.
author | Mike Ruprecht <maiku@soc.pidgin.im> |
---|---|
date | Mon, 02 Jun 2008 20:59:20 +0000 |
parents | 1f085713c281 |
children | 41d6d4217d21 |
line wrap: on
line diff
--- a/libpurple/protocols/jabber/jabber.c Mon Jun 02 18:18:58 2008 +0000 +++ b/libpurple/protocols/jabber/jabber.c Mon Jun 02 20:59:20 2008 +0000 @@ -2382,264 +2382,11 @@ #ifdef USE_VV -static void -jabber_session_send_accept(JingleSession *session) -{ - JabberIq *result = jabber_iq_new(jabber_jingle_session_get_js(session), - JABBER_IQ_SET); - xmlnode *jingle = jabber_jingle_session_create_session_accept(session); - xmlnode_set_attrib(result->node, "to", - jabber_jingle_session_get_remote_jid(session)); - - xmlnode_insert_child(result->node, jingle); - jabber_iq_send(result); - purple_debug_info("jabber", "Sent session accept, starting stream\n"); - gst_element_set_state(purple_media_get_audio_pipeline(session->media), GST_STATE_PLAYING); - - session->session_started = TRUE; -} - -static void -jabber_session_send_content_accept(JingleSession *session) -{ - JabberIq *result = jabber_iq_new(jabber_jingle_session_get_js(session), - JABBER_IQ_SET); - xmlnode *jingle = jabber_jingle_session_create_content_accept(session); - xmlnode_set_attrib(result->node, "to", - jabber_jingle_session_get_remote_jid(session)); - - xmlnode_insert_child(result->node, jingle); - jabber_iq_send(result); -} - -static void -jabber_session_send_reject(JingleSession *session) -{ - JabberIq *result = jabber_iq_new(jabber_jingle_session_get_js(session), - JABBER_IQ_SET); - xmlnode *jingle = jabber_jingle_session_create_terminate(session, - "decline", NULL); - xmlnode_set_attrib(result->node, "to", - jabber_jingle_session_get_remote_jid(session)); - xmlnode_insert_child(result->node, jingle); - jabber_iq_send(result); - jabber_jingle_session_destroy(session); -} - -static void -jabber_session_send_terminate(JingleSession *session) -{ - JabberIq *result = jabber_iq_new(jabber_jingle_session_get_js(session), - JABBER_IQ_SET); - xmlnode *jingle = jabber_jingle_session_create_terminate(session, - "no-error", NULL); - xmlnode_set_attrib(result->node, "to", - jabber_jingle_session_get_remote_jid(session)); - xmlnode_insert_child(result->node, jingle); - jabber_iq_send(result); - jabber_jingle_session_destroy(session); -} - -/* callback called when new local transport candidate(s) are available on the - Farsight stream */ -static void -jabber_session_candidates_prepared(PurpleMedia *media, JingleSession *session) -{ - if (!jabber_jingle_session_is_initiator(session)) { - /* create transport-info package */ - JabberIq *result = jabber_iq_new(jabber_jingle_session_get_js(session), - JABBER_IQ_SET); - xmlnode *jingle = jabber_jingle_session_create_transport_info(session); - purple_debug_info("jabber", "jabber_session_candidates_prepared: %d candidates\n", - g_list_length(purple_media_get_local_audio_candidates(session->media))); - xmlnode_set_attrib(result->node, "to", - jabber_jingle_session_get_remote_jid(session)); - - xmlnode_insert_child(result->node, jingle); - jabber_iq_send(result); - } -} - -/* callback called when a pair of transport candidates (local and remote) - has been established */ -static void -jabber_session_candidate_pair_established(PurpleMedia *media, - FsCandidate *native_candidate, - FsCandidate *remote_candidate, - JingleSession *session) -{ - purple_debug_info("jabber", "jabber_candidate_pair_established called\n"); - /* if we are the initiator, we should send a content-modify message */ - if (jabber_jingle_session_is_initiator(session)) { - JabberIq *result; - xmlnode *jingle; - - purple_debug_info("jabber", "we are the initiator, let's send content-modify\n"); - - result = jabber_iq_new(jabber_jingle_session_get_js(session), JABBER_IQ_SET); - - /* shall change this to a "content-replace" */ - jingle = - jabber_jingle_session_create_content_replace(session, - native_candidate, - remote_candidate); - xmlnode_set_attrib(result->node, "to", - jabber_jingle_session_get_remote_jid(session)); - xmlnode_insert_child(result->node, jingle); - jabber_iq_send(result); - } -} - -static gboolean -jabber_initiate_media_internal(JingleSession *session, const char *initiator, const char *remote_jid) -{ - PurpleMedia *media = NULL; - - media = purple_media_manager_create_media(purple_media_manager_get(), - session->js->gc, "fsrtpconference", remote_jid); - - if (!media) { - purple_debug_error("jabber", "Couldn't create fsrtpconference\n"); - return FALSE; - } - - /* this will need to be changed to "nice" once the libnice transmitter is finished */ - if (!purple_media_add_stream(media, remote_jid, PURPLE_MEDIA_AUDIO, "rawudp")) { - purple_debug_error("jabber", "Couldn't create audio stream\n"); - purple_media_reject(media); - return FALSE; - } - - jabber_jingle_session_set_remote_jid(session, remote_jid); - jabber_jingle_session_set_initiator(session, initiator); - jabber_jingle_session_set_media(session, media); - - /* connect callbacks */ - g_signal_connect_swapped(G_OBJECT(media), "accepted", - G_CALLBACK(jabber_session_send_accept), session); - g_signal_connect_swapped(G_OBJECT(media), "reject", - G_CALLBACK(jabber_session_send_reject), session); - g_signal_connect_swapped(G_OBJECT(media), "hangup", - G_CALLBACK(jabber_session_send_terminate), session); - g_signal_connect(G_OBJECT(media), "candidates-prepared", - G_CALLBACK(jabber_session_candidates_prepared), session); - g_signal_connect(G_OBJECT(media), "candidate-pair", - G_CALLBACK(jabber_session_candidate_pair_established), session); - - purple_media_ready(media); - - return TRUE; -} - -static void -jabber_session_initiate_result_cb(JabberStream *js, xmlnode *packet, gpointer data) -{ - const char *from = xmlnode_get_attrib(packet, "from"); - JingleSession *session = jabber_jingle_session_find_by_jid(js, from); - PurpleMedia *media = session->media; - JabberIq *result; - xmlnode *jingle; - - if (!strcmp(xmlnode_get_attrib(packet, "type"), "error")) { - purple_media_got_hangup(media); - return; - } - - /* catch errors */ - if (xmlnode_get_child(packet, "error")) { - purple_media_got_hangup(media); - return; - } - - /* create transport-info package */ - result = jabber_iq_new(jabber_jingle_session_get_js(session), JABBER_IQ_SET); - jingle = jabber_jingle_session_create_transport_info(session); - purple_debug_info("jabber", "jabber_session_candidates_prepared: %d candidates\n", - g_list_length(purple_media_get_local_audio_candidates(session->media))); - xmlnode_set_attrib(result->node, "to", - jabber_jingle_session_get_remote_jid(session)); - - xmlnode_insert_child(result->node, jingle); - jabber_iq_send(result); -} - PurpleMedia * jabber_initiate_media(PurpleConnection *gc, const char *who, - PurpleMediaStreamType type) + PurpleMediaStreamType type) { - /* create content negotiation */ - JabberStream *js = gc->proto_data; - JabberIq *request = jabber_iq_new(js, JABBER_IQ_SET); - xmlnode *jingle, *content, *description, *transport; - GList *codecs; - JingleSession *session; - JabberBuddy *jb; - JabberBuddyResource *jbr; - - char *jid = NULL, *me = NULL; - - /* construct JID to send to */ - jb = jabber_buddy_find(js, who, FALSE); - if (!jb) { - purple_debug_error("jabber", "Could not find Jabber buddy\n"); - return NULL; - } - jbr = jabber_buddy_find_resource(jb, NULL); - if (!jbr) { - purple_debug_error("jabber", "Could not find buddy's resource\n"); - } - - if ((strchr(who, '/') == NULL) && jbr && (jbr->name != NULL)) { - jid = g_strdup_printf("%s/%s", who, jbr->name); - } else { - jid = g_strdup(who); - } - - session = jabber_jingle_session_create(js); - /* set ourselves as initiator */ - me = g_strdup_printf("%s@%s/%s", js->user->node, js->user->domain, js->user->resource); - - if (!jabber_initiate_media_internal(session, me, jid)) { - g_free(jid); - g_free(me); - jabber_jingle_session_destroy(session); - return NULL; - } - - g_free(jid); - g_free(me); - - codecs = purple_media_get_local_audio_codecs(session->media); - - /* create request */ - - xmlnode_set_attrib(request->node, "to", - jabber_jingle_session_get_remote_jid(session)); - jingle = xmlnode_new_child(request->node, "jingle"); - xmlnode_set_namespace(jingle, "urn:xmpp:tmp:jingle"); - xmlnode_set_attrib(jingle, "action", "session-initiate"); - /* get our JID and a session id... */ - xmlnode_set_attrib(jingle, "initiator", jabber_jingle_session_get_initiator(session)); - xmlnode_set_attrib(jingle, "sid", jabber_jingle_session_get_id(session)); - - content = xmlnode_new_child(jingle, "content"); - xmlnode_set_attrib(content, "name", "audio-content"); - xmlnode_set_attrib(content, "profile", "RTP/AVP"); - - description = jabber_jingle_session_create_description(session); - xmlnode_insert_child(content, description); - - transport = xmlnode_new_child(content, "transport"); - xmlnode_set_namespace(transport, "urn:xmpp:tmp:jingle:transports:ice-udp"); - - jabber_iq_set_callback(request, jabber_session_initiate_result_cb, NULL); - - /* send request to other part */ - jabber_iq_send(request); - - fs_codec_list_destroy(codecs); - - return session->media; + return jabber_jingle_session_initiate_media(gc, who, type); } gboolean jabber_can_do_media(PurpleConnection *gc, const char *who, @@ -2685,234 +2432,6 @@ return FALSE; } - -void -jabber_handle_session_accept(JabberStream *js, xmlnode *packet) -{ - JabberIq *result = jabber_iq_new(js, JABBER_IQ_RESULT); - xmlnode *jingle = xmlnode_get_child(packet, "jingle"); - xmlnode *content = xmlnode_get_child(jingle, "content"); - const char *sid = xmlnode_get_attrib(jingle, "sid"); - const char *action = xmlnode_get_attrib(jingle, "action"); - JingleSession *session = jabber_jingle_session_find_by_id(js, sid); - GList *remote_codecs = NULL; - GList *remote_transports = NULL; - GList *codec_intersection; - FsCodec *top = NULL; - xmlnode *description = NULL; - xmlnode *transport = NULL; - - /* We should probably check validity of the incoming XML... */ - - xmlnode_set_attrib(result->node, "to", - jabber_jingle_session_get_remote_jid(session)); - jabber_iq_set_id(result, xmlnode_get_attrib(packet, "id")); - - description = xmlnode_get_child(content, "description"); - transport = xmlnode_get_child(content, "transport"); - - /* fetch codecs from remote party */ - purple_debug_info("jabber", "get codecs from session-accept\n"); - remote_codecs = jabber_jingle_get_codecs(description); - purple_debug_info("jabber", "get transport candidates from session accept\n"); - remote_transports = jabber_jingle_get_candidates(transport); - - purple_debug_info("jabber", "Got %d codecs from responder\n", - g_list_length(remote_codecs)); - purple_debug_info("jabber", "Got %d transport candidates from responder\n", - g_list_length(remote_transports)); - - purple_debug_info("jabber", "Setting remote codecs on stream\n"); - - purple_media_set_remote_audio_codecs(session->media, - jabber_jingle_session_get_remote_jid(session), - remote_codecs); - - codec_intersection = purple_media_get_negotiated_audio_codecs(session->media); - purple_debug_info("jabber", "codec_intersection contains %d elems\n", - g_list_length(codec_intersection)); - /* get the top codec */ - if (g_list_length(codec_intersection) > 0) { - top = (FsCodec *) codec_intersection->data; - purple_debug_info("jabber", "Found a suitable codec on stream = %d\n", - top->id); - - /* we have found a suitable codec, but we will not start the stream - just yet, wait for transport negotiation to complete... */ - } - /* if we also got transport candidates, add them to our streams - list of known remote candidates */ - if (g_list_length(remote_transports) > 0) { - purple_media_add_remote_audio_candidates(session->media, - jabber_jingle_session_get_remote_jid(session), - remote_transports); - fs_candidate_list_destroy(remote_transports); - } - if (g_list_length(codec_intersection) == 0 && - g_list_length(remote_transports)) { - /* we didn't get any candidates and the codec intersection is empty, - this means this was not a content-accept message and we couldn't - find any suitable codecs, should return error and hang up */ - - } - - g_list_free(codec_intersection); - - if (!strcmp(action, "session-accept")) { - purple_media_got_accept(jabber_jingle_session_get_media(session)); - purple_debug_info("jabber", "Got session-accept, starting stream\n"); - gst_element_set_state(purple_media_get_audio_pipeline(session->media), GST_STATE_PLAYING); - } - - jabber_iq_send(result); - - session->session_started = TRUE; -} - -void -jabber_handle_session_terminate(JabberStream *js, xmlnode *packet) -{ - JabberIq *result = jabber_iq_new(js, JABBER_IQ_SET); - xmlnode *jingle = xmlnode_get_child(packet, "jingle"); - const char *sid = xmlnode_get_attrib(jingle, "sid"); - JingleSession *session = jabber_jingle_session_find_by_id(js, sid); - - if(!session) { - purple_debug_error("jabber", "jabber_handle_session_terminate couldn't find session\n"); - return; - } - - xmlnode_set_attrib(result->node, "to", - jabber_jingle_session_get_remote_jid(session)); - xmlnode_set_attrib(result->node, "id", xmlnode_get_attrib(packet, "id")); - - - - /* maybe we should look at the reasoncode to determine if it was - a hangup or a reject, and call different callbacks to purple_media */ - gst_element_set_state(purple_media_get_audio_pipeline(session->media), GST_STATE_NULL); - - purple_media_got_hangup(jabber_jingle_session_get_media(session)); - jabber_iq_send(result); - jabber_jingle_session_destroy(session); -} - -void -jabber_handle_session_candidates(JabberStream *js, xmlnode *packet) -{ - JabberIq *result = jabber_iq_new(js, JABBER_IQ_RESULT); - xmlnode *jingle = xmlnode_get_child(packet, "jingle"); - xmlnode *content = xmlnode_get_child(jingle, "content"); - xmlnode *transport = xmlnode_get_child(content, "transport"); - GList *remote_candidates = jabber_jingle_get_candidates(transport); - const char *sid = xmlnode_get_attrib(jingle, "sid"); - JingleSession *session = jabber_jingle_session_find_by_id(js, sid); - - if(!session) - purple_debug_error("jabber", "jabber_handle_session_candidates couldn't find session\n"); - - /* send acknowledement */ - xmlnode_set_attrib(result->node, "id", xmlnode_get_attrib(packet, "id")); - xmlnode_set_attrib(result->node, "to", xmlnode_get_attrib(packet, "from")); - jabber_iq_send(result); - - /* add candidates to our list of remote candidates */ - if (g_list_length(remote_candidates) > 0) { - purple_media_add_remote_audio_candidates(session->media, - xmlnode_get_attrib(packet, "from"), - remote_candidates); - fs_candidate_list_destroy(remote_candidates); - } -} - -/* change this to content-replace */ -void -jabber_handle_session_content_replace(JabberStream *js, xmlnode *packet) -{ - xmlnode *jingle = xmlnode_get_child(packet, "jingle"); - const char *sid = xmlnode_get_attrib(jingle, "sid"); - JingleSession *session = jabber_jingle_session_find_by_id(js, sid); - - if (!jabber_jingle_session_is_initiator(session) && session->session_started) { - JabberIq *result = jabber_iq_new(js, JABBER_IQ_RESULT); - JabberIq *accept = jabber_iq_new(js, JABBER_IQ_SET); - xmlnode *content_accept = NULL; - - /* send acknowledement */ - xmlnode_set_attrib(result->node, "id", xmlnode_get_attrib(packet, "id")); - xmlnode_set_attrib(result->node, "to", xmlnode_get_attrib(packet, "from")); - jabber_iq_send(result); - - /* send content-accept */ - content_accept = jabber_jingle_session_create_content_accept(session); - xmlnode_set_attrib(accept->node, "id", xmlnode_get_attrib(packet, "id")); - xmlnode_set_attrib(accept->node, "to", xmlnode_get_attrib(packet, "from")); - xmlnode_insert_child(accept->node, content_accept); - - jabber_iq_send(accept); - } -} - -void -jabber_handle_session_initiate(JabberStream *js, xmlnode *packet) -{ - JingleSession *session = NULL; - xmlnode *jingle = xmlnode_get_child(packet, "jingle"); - xmlnode *content = NULL; - xmlnode *description = NULL; - const char *sid = NULL; - const char *initiator = NULL; - GList *codecs = NULL; - JabberIq *result = NULL; - - if (!jingle) { - purple_debug_error("jabber", "Malformed request"); - return; - } - - sid = xmlnode_get_attrib(jingle, "sid"); - initiator = xmlnode_get_attrib(jingle, "initiator"); - - if (jabber_jingle_session_find_by_id(js, sid)) { - /* This should only happen if you start a session with yourself */ - purple_debug_error("jabber", "Jingle session with id={%s} already exists\n", sid); - return; - } - session = jabber_jingle_session_create_by_id(js, sid); - - /* init media */ - content = xmlnode_get_child(jingle, "content"); - if (!content) { - purple_debug_error("jabber", "jingle tag must contain content tag\n"); - /* should send error here */ - return; - } - - description = xmlnode_get_child(content, "description"); - - if (!description) { - purple_debug_error("jabber", "content tag must contain description tag\n"); - /* we should create an error iq here */ - return; - } - - if (!jabber_initiate_media_internal(session, initiator, initiator)) { - purple_debug_error("jabber", "Couldn't start media session with %s\n", initiator); - jabber_jingle_session_destroy(session); - /* we should create an error iq here */ - return; - } - - codecs = jabber_jingle_get_codecs(description); - - purple_media_set_remote_audio_codecs(session->media, initiator, codecs); - - result = jabber_iq_new(js, JABBER_IQ_RESULT); - jabber_iq_set_id(result, xmlnode_get_attrib(packet, "id")); - xmlnode_set_attrib(result->node, "to", xmlnode_get_attrib(packet, "from")); - jabber_iq_send(result); -} - #endif void jabber_register_commands(void)