Mercurial > pidgin.yaz
comparison libpurple/protocols/jabber/jingle.c @ 25671:12a16471f94e
Refactored PurpleMedia to make creating audio or video sessions virtually identical. Audio, video, and audio/video sessions now work. Also added videotestsrc to the video plugin preference.
author | Mike Ruprecht <maiku@soc.pidgin.im> |
---|---|
date | Fri, 06 Jun 2008 07:43:03 +0000 |
parents | 42e17cc5b6d2 |
children | 9983353706b8 |
comparison
equal
deleted
inserted
replaced
25670:42e17cc5b6d2 | 25671:12a16471f94e |
---|---|
276 g_list_free(values); | 276 g_list_free(values); |
277 return NULL; | 277 return NULL; |
278 } | 278 } |
279 | 279 |
280 static GList * | 280 static GList * |
281 jabber_jingle_get_codecs(const xmlnode *description) | 281 jabber_jingle_get_codecs(xmlnode *description) |
282 { | 282 { |
283 GList *codecs = NULL; | 283 GList *codecs = NULL; |
284 xmlnode *codec_element = NULL; | 284 xmlnode *codec_element = NULL; |
285 const char *encoding_name,*id, *clock_rate; | 285 const char *encoding_name,*id, *clock_rate; |
286 FsCodec *codec; | 286 FsCodec *codec; |
287 | 287 FsMediaType type = !strcmp(xmlnode_get_namespace(description), JINGLE_VIDEO) ? |
288 FS_MEDIA_TYPE_VIDEO : FS_MEDIA_TYPE_AUDIO; | |
289 | |
288 for (codec_element = xmlnode_get_child(description, "payload-type") ; | 290 for (codec_element = xmlnode_get_child(description, "payload-type") ; |
289 codec_element ; | 291 codec_element ; |
290 codec_element = xmlnode_get_next_twin(codec_element)) { | 292 codec_element = xmlnode_get_next_twin(codec_element)) { |
291 encoding_name = xmlnode_get_attrib(codec_element, "name"); | 293 encoding_name = xmlnode_get_attrib(codec_element, "name"); |
294 | |
292 id = xmlnode_get_attrib(codec_element, "id"); | 295 id = xmlnode_get_attrib(codec_element, "id"); |
293 clock_rate = xmlnode_get_attrib(codec_element, "clockrate"); | 296 clock_rate = xmlnode_get_attrib(codec_element, "clockrate"); |
294 | 297 |
295 codec = fs_codec_new(atoi(id), encoding_name, | 298 codec = fs_codec_new(atoi(id), encoding_name, |
296 FS_MEDIA_TYPE_AUDIO, | 299 type, |
297 clock_rate ? atoi(clock_rate) : 0); | 300 clock_rate ? atoi(clock_rate) : 0); |
298 codecs = g_list_append(codecs, codec); | 301 purple_debug_info("jingle", "codec: %i, %s, %s, %i\n", codec->id, |
302 codec->encoding_name, codec->media_type == FS_MEDIA_TYPE_AUDIO ? | |
303 "FS_MEDIA_TYPE_AUDIO" : codec->media_type == FS_MEDIA_TYPE_VIDEO ? | |
304 "FS_MEDIA_TYPE_VIDEO" : "FS_MEDIA_TYPE_NONE", codec->clock_rate); | |
305 codecs = g_list_append(codecs, codec); | |
299 } | 306 } |
300 return codecs; | 307 return codecs; |
301 } | 308 } |
302 | 309 |
303 static GList * | 310 static GList * |
395 jabber_jingle_session_add_payload_types(const JingleSessionContent *jsc, | 402 jabber_jingle_session_add_payload_types(const JingleSessionContent *jsc, |
396 xmlnode *description) | 403 xmlnode *description) |
397 { | 404 { |
398 JingleSession *session = jabber_jingle_session_content_get_session(jsc); | 405 JingleSession *session = jabber_jingle_session_content_get_session(jsc); |
399 PurpleMedia *media = jabber_jingle_session_get_media(session); | 406 PurpleMedia *media = jabber_jingle_session_get_media(session); |
400 /* change this to the generic function when PurpleMedia supports video */ | 407 /* should this be local_codecs or negotiated-codecs? */ |
401 GList *codecs = purple_media_get_local_audio_codecs(media); | 408 GList *codecs = purple_media_get_local_codecs(media, |
409 jabber_jingle_session_content_get_name(jsc)); | |
402 | 410 |
403 for (; codecs ; codecs = codecs->next) { | 411 for (; codecs ; codecs = codecs->next) { |
404 FsCodec *codec = (FsCodec*)codecs->data; | 412 FsCodec *codec = (FsCodec*)codecs->data; |
405 char id[8], clockrate[10], channels[10]; | 413 char id[8], clockrate[10], channels[10]; |
406 xmlnode *payload = xmlnode_new_child(description, "payload-type"); | 414 xmlnode *payload = xmlnode_new_child(description, "payload-type"); |
407 | 415 |
408 g_snprintf(id, sizeof(id), "%d", codec->id); | 416 g_snprintf(id, sizeof(id), "%d", codec->id); |
409 g_snprintf(clockrate, sizeof(clockrate), "%d", codec->clock_rate); | 417 g_snprintf(clockrate, sizeof(clockrate), "%d", codec->clock_rate); |
410 g_snprintf(channels, sizeof(channels), "%d", | 418 g_snprintf(channels, sizeof(channels), "%d", codec->channels); |
411 codec->channels == 0 ? 1 : codec->channels); | |
412 | 419 |
413 xmlnode_set_attrib(payload, "name", codec->encoding_name); | 420 xmlnode_set_attrib(payload, "name", codec->encoding_name); |
414 xmlnode_set_attrib(payload, "id", id); | 421 xmlnode_set_attrib(payload, "id", id); |
415 xmlnode_set_attrib(payload, "clockrate", clockrate); | 422 xmlnode_set_attrib(payload, "clockrate", clockrate); |
416 xmlnode_set_attrib(payload, "channels", channels); | 423 xmlnode_set_attrib(payload, "channels", channels); |
567 g_free(from); | 574 g_free(from); |
568 xmlnode_set_attrib(result->node, "to", | 575 xmlnode_set_attrib(result->node, "to", |
569 jabber_jingle_session_get_remote_jid(session)); | 576 jabber_jingle_session_get_remote_jid(session)); |
570 return result; | 577 return result; |
571 } | 578 } |
572 | 579 #if 0 |
573 static xmlnode * | |
574 jabber_jingle_session_create_description(const JingleSession *sess) | |
575 { | |
576 GList *codecs = purple_media_get_local_audio_codecs(sess->media); | |
577 xmlnode *description = xmlnode_new("description"); | |
578 | |
579 xmlnode_set_namespace(description, JINGLE_AUDIO); | |
580 | |
581 /* get codecs */ | |
582 for (; codecs ; codecs = codecs->next) { | |
583 FsCodec *codec = (FsCodec*)codecs->data; | |
584 char id[8], clockrate[10], channels[10]; | |
585 xmlnode *payload = xmlnode_new_child(description, "payload-type"); | |
586 | |
587 g_snprintf(id, sizeof(id), "%d", codec->id); | |
588 g_snprintf(clockrate, sizeof(clockrate), "%d", codec->clock_rate); | |
589 g_snprintf(channels, sizeof(channels), "%d", codec->channels); | |
590 | |
591 xmlnode_set_attrib(payload, "name", codec->encoding_name); | |
592 xmlnode_set_attrib(payload, "id", id); | |
593 xmlnode_set_attrib(payload, "clockrate", clockrate); | |
594 xmlnode_set_attrib(payload, "channels", channels); | |
595 } | |
596 | |
597 fs_codec_list_destroy(codecs); | |
598 return description; | |
599 } | |
600 | |
601 static xmlnode * | 580 static xmlnode * |
602 jabber_jingle_session_create_content_accept(const JingleSession *sess) | 581 jabber_jingle_session_create_content_accept(const JingleSession *sess) |
603 { | 582 { |
604 xmlnode *jingle = | 583 xmlnode *jingle = |
605 jabber_jingle_session_add_jingle(sess, NULL, "content-accept"); | 584 jabber_jingle_session_add_jingle(sess, NULL, "content-accept"); |
647 | 626 |
648 purple_debug_info("jingle", "End create content modify\n"); | 627 purple_debug_info("jingle", "End create content modify\n"); |
649 | 628 |
650 return jingle; | 629 return jingle; |
651 } | 630 } |
631 #endif | |
652 | 632 |
653 static JabberIq * | 633 static JabberIq * |
654 jabber_jingle_session_create_session_accept(const JingleSession *session, | 634 jabber_jingle_session_create_session_accept(const JingleSession *session, |
655 FsCandidate *local, | 635 FsCandidate *local, |
656 FsCandidate *remote) | 636 FsCandidate *remote) |
742 xmlnode *content = jabber_jingle_session_add_content(jsc, jingle); | 722 xmlnode *content = jabber_jingle_session_add_content(jsc, jingle); |
743 xmlnode *transport = jabber_jingle_session_add_transport(jsc, content); | 723 xmlnode *transport = jabber_jingle_session_add_transport(jsc, content); |
744 jabber_jingle_session_add_candidate_iceudp(transport, candidate, NULL); | 724 jabber_jingle_session_add_candidate_iceudp(transport, candidate, NULL); |
745 return request; | 725 return request; |
746 } | 726 } |
747 | 727 #if 0 |
748 static void | 728 static void |
749 jabber_jingle_session_send_content_accept(JingleSession *session) | 729 jabber_jingle_session_send_content_accept(JingleSession *session) |
750 { | 730 { |
751 JabberIq *result = jabber_iq_new(jabber_jingle_session_get_js(session), | 731 JabberIq *result = jabber_iq_new(jabber_jingle_session_get_js(session), |
752 JABBER_IQ_SET); | 732 JABBER_IQ_SET); |
755 jabber_jingle_session_get_remote_jid(session)); | 735 jabber_jingle_session_get_remote_jid(session)); |
756 | 736 |
757 xmlnode_insert_child(result->node, jingle); | 737 xmlnode_insert_child(result->node, jingle); |
758 jabber_iq_send(result); | 738 jabber_iq_send(result); |
759 } | 739 } |
760 | 740 #endif |
761 static void | 741 static void |
762 jabber_jingle_session_send_session_accept(JingleSession *session) | 742 jabber_jingle_session_send_session_accept(JingleSession *session) |
763 { | 743 { |
764 /* create transport-info packages */ | 744 /* create transport-info packages */ |
765 PurpleMedia *media = jabber_jingle_session_get_media(session); | 745 PurpleMedia *media = jabber_jingle_session_get_media(session); |
766 GList *contents = jabber_jingle_session_get_contents(session); | 746 GList *contents = jabber_jingle_session_get_contents(session); |
767 for (; contents; contents = contents->next) { | 747 for (; contents; contents = contents->next) { |
768 JingleSessionContent *jsc = contents->data; | 748 JingleSessionContent *jsc = contents->data; |
769 GList *candidates = purple_media_get_local_audio_candidates( | 749 GList *candidates = purple_media_get_local_candidates( |
770 jabber_jingle_session_get_media(session)); | 750 media, |
751 jabber_jingle_session_content_get_name(jsc), | |
752 jabber_jingle_session_get_remote_jid(session)); | |
771 purple_debug_info("jabber", | 753 purple_debug_info("jabber", |
772 "jabber_session_candidates_prepared: %d candidates\n", | 754 "jabber_session_candidates_prepared: %d candidates\n", |
773 g_list_length(candidates)); | 755 g_list_length(candidates)); |
774 for (; candidates; candidates = candidates->next) { | 756 for (; candidates; candidates = candidates->next) { |
775 FsCandidate *candidate = candidates->data; | 757 FsCandidate *candidate = candidates->data; |
776 JabberIq *result = jabber_jingle_session_create_transport_info(jsc, | 758 JabberIq *result = jabber_jingle_session_create_transport_info(jsc, |
777 candidate); | 759 candidate); |
778 jabber_iq_send(result); | 760 jabber_iq_send(result); |
779 } | 761 } |
780 fs_candidate_list_destroy(candidates); | 762 fs_candidate_list_destroy(candidates); |
781 } | 763 purple_debug_info("jingle", "codec intersection: %i\n", |
782 | 764 g_list_length(purple_media_get_negotiated_codecs(media, |
783 jabber_iq_send(jabber_jingle_session_create_session_accept(session, | 765 jabber_jingle_session_content_get_name(jsc)))); |
784 purple_media_get_local_candidate(media), | 766 jabber_iq_send(jabber_jingle_session_create_session_accept(session, |
785 purple_media_get_remote_candidate(media))); | 767 purple_media_get_local_candidate(media, |
768 jabber_jingle_session_content_get_name(jsc), | |
769 jabber_jingle_session_get_remote_jid(session)), | |
770 purple_media_get_remote_candidate(media, | |
771 jabber_jingle_session_content_get_name(jsc), | |
772 jabber_jingle_session_get_remote_jid(session)))); | |
773 } | |
774 | |
786 | 775 |
787 purple_debug_info("jabber", "Sent session accept, starting stream\n"); | 776 purple_debug_info("jabber", "Sent session accept, starting stream\n"); |
788 gst_element_set_state(purple_media_get_audio_pipeline(session->media), GST_STATE_PLAYING); | 777 gst_element_set_state(purple_media_get_pipeline(session->media), GST_STATE_PLAYING); |
789 | 778 |
790 session->session_started = TRUE; | 779 session->session_started = TRUE; |
791 } | 780 } |
792 | 781 |
793 static void | 782 static void |
820 else | 809 else |
821 strcpy(sender, "both"); | 810 strcpy(sender, "both"); |
822 jabber_jingle_session_content_create_internal(session, | 811 jabber_jingle_session_content_create_internal(session, |
823 "audio-content", "initiator", sender, | 812 "audio-content", "initiator", sender, |
824 TRANSPORT_ICEUDP, JINGLE_AUDIO); | 813 TRANSPORT_ICEUDP, JINGLE_AUDIO); |
825 } else if (type & PURPLE_MEDIA_VIDEO) { | 814 } |
815 if (type & PURPLE_MEDIA_VIDEO) { | |
826 if (type == PURPLE_MEDIA_SEND_VIDEO) | 816 if (type == PURPLE_MEDIA_SEND_VIDEO) |
827 strcpy(sender, "initiator"); | 817 strcpy(sender, "initiator"); |
828 else if (type == PURPLE_MEDIA_RECV_VIDEO) | 818 else if (type == PURPLE_MEDIA_RECV_VIDEO) |
829 strcpy(sender, "responder"); | 819 strcpy(sender, "responder"); |
830 else | 820 else |
835 } | 825 } |
836 } | 826 } |
837 | 827 |
838 static void | 828 static void |
839 jabber_jingle_session_content_create_parse(JingleSession *session, | 829 jabber_jingle_session_content_create_parse(JingleSession *session, |
840 xmlnode *jingle) | 830 xmlnode *content) |
841 { | 831 { |
842 xmlnode *content = xmlnode_get_child(jingle, "content"); | |
843 xmlnode *description = xmlnode_get_child(content, "description"); | 832 xmlnode *description = xmlnode_get_child(content, "description"); |
844 xmlnode *transport = xmlnode_get_child(content, "transport"); | 833 xmlnode *transport = xmlnode_get_child(content, "transport"); |
845 | 834 |
846 const gchar *creator = xmlnode_get_attrib(content, "creator"); | 835 const gchar *creator = xmlnode_get_attrib(content, "creator"); |
847 const gchar *sender = xmlnode_get_attrib(content, "sender"); | 836 const gchar *sender = xmlnode_get_attrib(content, "sender"); |
905 jabber_jingle_session_initiate_media_internal(JingleSession *session, | 894 jabber_jingle_session_initiate_media_internal(JingleSession *session, |
906 const char *initiator, | 895 const char *initiator, |
907 const char *remote_jid) | 896 const char *remote_jid) |
908 { | 897 { |
909 PurpleMedia *media = NULL; | 898 PurpleMedia *media = NULL; |
899 GList *contents = jabber_jingle_session_get_contents(session); | |
910 | 900 |
911 media = purple_media_manager_create_media(purple_media_manager_get(), | 901 media = purple_media_manager_create_media(purple_media_manager_get(), |
912 session->js->gc, "fsrtpconference", remote_jid); | 902 session->js->gc, "fsrtpconference", remote_jid); |
913 | 903 |
914 if (!media) { | 904 if (!media) { |
915 purple_debug_error("jabber", "Couldn't create fsrtpconference\n"); | 905 purple_debug_error("jabber", "Couldn't create fsrtpconference\n"); |
916 return FALSE; | 906 return FALSE; |
917 } | 907 } |
918 | 908 |
919 /* this will need to be changed to "nice" once the libnice transmitter is finished */ | 909 for (; contents; contents = contents->next) { |
920 if (!purple_media_add_stream(media, remote_jid, PURPLE_MEDIA_AUDIO, "rawudp")) { | 910 JingleSessionContent *jsc = contents->data; |
921 purple_debug_error("jabber", "Couldn't create audio stream\n"); | 911 gboolean result = FALSE; |
922 purple_media_reject(media); | 912 |
923 return FALSE; | 913 /* these will need to be changed to "nice" once the libnice transmitter is finished */ |
924 } | 914 if (jabber_jingle_session_content_is_type(jsc, JINGLE_AUDIO)) { |
915 result = purple_media_add_stream(media, "audio-content", remote_jid, | |
916 PURPLE_MEDIA_AUDIO, "rawudp"); | |
917 purple_debug_info("jingle", "Created Jingle audio session\n"); | |
918 } | |
919 else if (jabber_jingle_session_content_is_type(jsc, JINGLE_VIDEO)) { | |
920 result = purple_media_add_stream(media, "video-content", remote_jid, | |
921 PURPLE_MEDIA_VIDEO, "rawudp"); | |
922 purple_debug_info("jingle", "Created Jingle video session\n"); | |
923 } | |
924 | |
925 if (!result) { | |
926 purple_debug_error("jabber", "Couldn't create stream\n"); | |
927 purple_media_reject(media); | |
928 return FALSE; | |
929 } | |
930 } | |
931 g_list_free(contents); | |
925 | 932 |
926 jabber_jingle_session_set_remote_jid(session, remote_jid); | 933 jabber_jingle_session_set_remote_jid(session, remote_jid); |
927 jabber_jingle_session_set_initiator(session, initiator); | 934 jabber_jingle_session_set_initiator(session, initiator); |
928 jabber_jingle_session_set_media(session, media); | 935 jabber_jingle_session_set_media(session, media); |
929 | 936 |
965 | 972 |
966 /* create transport-info packages */ | 973 /* create transport-info packages */ |
967 contents = jabber_jingle_session_get_contents(session); | 974 contents = jabber_jingle_session_get_contents(session); |
968 for (; contents; contents = contents->next) { | 975 for (; contents; contents = contents->next) { |
969 JingleSessionContent *jsc = contents->data; | 976 JingleSessionContent *jsc = contents->data; |
970 GList *candidates = purple_media_get_local_audio_candidates( | 977 GList *candidates = purple_media_get_local_candidates( |
971 jabber_jingle_session_get_media(session)); | 978 jabber_jingle_session_get_media(session), |
979 jabber_jingle_session_content_get_name(jsc), | |
980 jabber_jingle_session_get_remote_jid(session)); | |
972 purple_debug_info("jabber", | 981 purple_debug_info("jabber", |
973 "jabber_session_candidates_prepared: %d candidates\n", | 982 "jabber_session_candidates_prepared: %d candidates\n", |
974 g_list_length(candidates)); | 983 g_list_length(candidates)); |
975 for (; candidates; candidates = candidates->next) { | 984 for (; candidates; candidates = candidates->next) { |
976 FsCandidate *candidate = candidates->data; | 985 FsCandidate *candidate = candidates->data; |
1010 } else { | 1019 } else { |
1011 jid = g_strdup(who); | 1020 jid = g_strdup(who); |
1012 } | 1021 } |
1013 | 1022 |
1014 session = jabber_jingle_session_create(js); | 1023 session = jabber_jingle_session_create(js); |
1024 jabber_jingle_session_content_create_media(session, type); | |
1025 | |
1015 /* set ourselves as initiator */ | 1026 /* set ourselves as initiator */ |
1016 me = g_strdup_printf("%s@%s/%s", js->user->node, js->user->domain, js->user->resource); | 1027 me = g_strdup_printf("%s@%s/%s", js->user->node, js->user->domain, js->user->resource); |
1017 | 1028 |
1018 if (!jabber_jingle_session_initiate_media_internal(session, me, jid)) { | 1029 if (!jabber_jingle_session_initiate_media_internal(session, me, jid)) { |
1019 g_free(jid); | 1030 g_free(jid); |
1023 } | 1034 } |
1024 | 1035 |
1025 g_free(jid); | 1036 g_free(jid); |
1026 g_free(me); | 1037 g_free(me); |
1027 | 1038 |
1028 jabber_jingle_session_content_create_media(session, type); | |
1029 | |
1030 /* create request */ | 1039 /* create request */ |
1031 request = jabber_jingle_session_create_session_initiate(session); | 1040 request = jabber_jingle_session_create_session_initiate(session); |
1032 jabber_iq_set_callback(request, jabber_jingle_session_initiate_result_cb, NULL); | 1041 jabber_iq_set_callback(request, jabber_jingle_session_initiate_result_cb, NULL); |
1033 | 1042 |
1034 /* send request to other part */ | 1043 /* send request to other part */ |
1062 } | 1071 } |
1063 | 1072 |
1064 void | 1073 void |
1065 jabber_jingle_session_handle_content_replace(JabberStream *js, xmlnode *packet) | 1074 jabber_jingle_session_handle_content_replace(JabberStream *js, xmlnode *packet) |
1066 { | 1075 { |
1076 #if 0 | |
1067 xmlnode *jingle = xmlnode_get_child(packet, "jingle"); | 1077 xmlnode *jingle = xmlnode_get_child(packet, "jingle"); |
1068 const char *sid = xmlnode_get_attrib(jingle, "sid"); | 1078 const char *sid = xmlnode_get_attrib(jingle, "sid"); |
1069 JingleSession *session = jabber_jingle_session_find_by_id(js, sid); | 1079 JingleSession *session = jabber_jingle_session_find_by_id(js, sid); |
1070 | 1080 |
1071 if (!jabber_jingle_session_is_initiator(session) && session->session_started) { | 1081 if (!jabber_jingle_session_is_initiator(session) && session->session_started) { |
1084 xmlnode_set_attrib(accept->node, "to", xmlnode_get_attrib(packet, "from")); | 1094 xmlnode_set_attrib(accept->node, "to", xmlnode_get_attrib(packet, "from")); |
1085 xmlnode_insert_child(accept->node, content_accept); | 1095 xmlnode_insert_child(accept->node, content_accept); |
1086 | 1096 |
1087 jabber_iq_send(accept); | 1097 jabber_iq_send(accept); |
1088 } | 1098 } |
1099 #endif | |
1089 } | 1100 } |
1090 | 1101 |
1091 void | 1102 void |
1092 jabber_jingle_session_handle_session_accept(JabberStream *js, xmlnode *packet) | 1103 jabber_jingle_session_handle_session_accept(JabberStream *js, xmlnode *packet) |
1093 { | 1104 { |
1108 | 1119 |
1109 xmlnode_set_attrib(result->node, "to", | 1120 xmlnode_set_attrib(result->node, "to", |
1110 jabber_jingle_session_get_remote_jid(session)); | 1121 jabber_jingle_session_get_remote_jid(session)); |
1111 jabber_iq_set_id(result, xmlnode_get_attrib(packet, "id")); | 1122 jabber_iq_set_id(result, xmlnode_get_attrib(packet, "id")); |
1112 | 1123 |
1113 description = xmlnode_get_child(content, "description"); | 1124 for (content = xmlnode_get_child(jingle, "content"); content; |
1114 transport = xmlnode_get_child(content, "transport"); | 1125 content = xmlnode_get_next_twin(content)) { |
1115 | 1126 description = xmlnode_get_child(content, "description"); |
1116 /* fetch codecs from remote party */ | 1127 transport = xmlnode_get_child(content, "transport"); |
1117 purple_debug_info("jabber", "get codecs from session-accept\n"); | 1128 |
1118 remote_codecs = jabber_jingle_get_codecs(description); | 1129 /* fetch codecs from remote party */ |
1119 purple_debug_info("jabber", "get transport candidates from session accept\n"); | 1130 purple_debug_info("jabber", "get codecs from session-accept\n"); |
1120 remote_transports = jabber_jingle_get_candidates(transport); | 1131 remote_codecs = jabber_jingle_get_codecs(description); |
1121 | 1132 purple_debug_info("jabber", "get transport candidates from session accept\n"); |
1122 purple_debug_info("jabber", "Got %d codecs from responder\n", | 1133 remote_transports = jabber_jingle_get_candidates(transport); |
1123 g_list_length(remote_codecs)); | 1134 |
1124 purple_debug_info("jabber", "Got %d transport candidates from responder\n", | 1135 purple_debug_info("jabber", "Got %d codecs from responder\n", |
1125 g_list_length(remote_transports)); | 1136 g_list_length(remote_codecs)); |
1126 | 1137 purple_debug_info("jabber", "Got %d transport candidates from responder\n", |
1127 purple_debug_info("jabber", "Setting remote codecs on stream\n"); | 1138 g_list_length(remote_transports)); |
1128 | 1139 |
1129 purple_media_set_remote_audio_codecs(session->media, | 1140 purple_debug_info("jabber", "Setting remote codecs on stream\n"); |
1130 jabber_jingle_session_get_remote_jid(session), | 1141 |
1131 remote_codecs); | 1142 purple_media_set_remote_codecs(session->media, |
1132 | 1143 xmlnode_get_attrib(content, "name"), |
1133 codec_intersection = purple_media_get_negotiated_audio_codecs(session->media); | 1144 jabber_jingle_session_get_remote_jid(session), |
1134 purple_debug_info("jabber", "codec_intersection contains %d elems\n", | 1145 remote_codecs); |
1135 g_list_length(codec_intersection)); | 1146 |
1136 /* get the top codec */ | 1147 codec_intersection = purple_media_get_negotiated_codecs(session->media, |
1137 if (g_list_length(codec_intersection) > 0) { | 1148 xmlnode_get_attrib(content, "name")); |
1138 top = (FsCodec *) codec_intersection->data; | 1149 purple_debug_info("jabber", "codec_intersection contains %d elems\n", |
1139 purple_debug_info("jabber", "Found a suitable codec on stream = %d\n", | 1150 g_list_length(codec_intersection)); |
1140 top->id); | 1151 /* get the top codec */ |
1141 | 1152 if (g_list_length(codec_intersection) > 0) { |
1142 /* we have found a suitable codec, but we will not start the stream | 1153 top = (FsCodec *) codec_intersection->data; |
1143 just yet, wait for transport negotiation to complete... */ | 1154 purple_debug_info("jabber", "Found a suitable codec on stream = %d\n", |
1144 } | 1155 top->id); |
1145 /* if we also got transport candidates, add them to our streams | 1156 |
1146 list of known remote candidates */ | 1157 /* we have found a suitable codec, but we will not start the stream |
1147 if (g_list_length(remote_transports) > 0) { | 1158 just yet, wait for transport negotiation to complete... */ |
1148 purple_media_add_remote_audio_candidates(session->media, | 1159 } |
1149 jabber_jingle_session_get_remote_jid(session), | 1160 /* if we also got transport candidates, add them to our streams |
1150 remote_transports); | 1161 list of known remote candidates */ |
1151 fs_candidate_list_destroy(remote_transports); | 1162 if (g_list_length(remote_transports) > 0) { |
1152 } | 1163 purple_media_add_remote_candidates(session->media, |
1153 if (g_list_length(codec_intersection) == 0 && | 1164 xmlnode_get_attrib(content, "name"), |
1154 g_list_length(remote_transports)) { | 1165 jabber_jingle_session_get_remote_jid(session), |
1155 /* we didn't get any candidates and the codec intersection is empty, | 1166 remote_transports); |
1156 this means this was not a content-accept message and we couldn't | 1167 fs_candidate_list_destroy(remote_transports); |
1157 find any suitable codecs, should return error and hang up */ | 1168 } |
1158 | 1169 if (g_list_length(codec_intersection) == 0 && |
1159 } | 1170 g_list_length(remote_transports)) { |
1160 | 1171 /* we didn't get any candidates and the codec intersection is empty, |
1161 g_list_free(codec_intersection); | 1172 this means this was not a content-accept message and we couldn't |
1173 find any suitable codecs, should return error and hang up */ | |
1174 | |
1175 } | |
1176 | |
1177 fs_codec_list_destroy(codec_intersection); | |
1178 | |
1179 } | |
1162 | 1180 |
1163 if (!strcmp(action, "session-accept")) { | 1181 if (!strcmp(action, "session-accept")) { |
1164 purple_media_got_accept(jabber_jingle_session_get_media(session)); | 1182 purple_media_got_accept(jabber_jingle_session_get_media(session)); |
1165 purple_debug_info("jabber", "Got session-accept, starting stream\n"); | 1183 purple_debug_info("jabber", "Got session-accept, starting stream\n"); |
1166 gst_element_set_state(purple_media_get_audio_pipeline(session->media), | 1184 gst_element_set_state(purple_media_get_pipeline(session->media), |
1167 GST_STATE_PLAYING); | 1185 GST_STATE_PLAYING); |
1168 } | 1186 } |
1169 | 1187 |
1170 jabber_iq_send(result); | 1188 jabber_iq_send(result); |
1171 | 1189 |
1202 if (jabber_jingle_session_find_by_id(js, sid)) { | 1220 if (jabber_jingle_session_find_by_id(js, sid)) { |
1203 /* This should only happen if you start a session with yourself */ | 1221 /* This should only happen if you start a session with yourself */ |
1204 purple_debug_error("jabber", "Jingle session with id={%s} already exists\n", sid); | 1222 purple_debug_error("jabber", "Jingle session with id={%s} already exists\n", sid); |
1205 return; | 1223 return; |
1206 } | 1224 } |
1225 | |
1207 session = jabber_jingle_session_create_by_id(js, sid); | 1226 session = jabber_jingle_session_create_by_id(js, sid); |
1208 | 1227 |
1209 /* init media */ | 1228 for (content = xmlnode_get_child(jingle, "content"); content; |
1210 content = xmlnode_get_child(jingle, "content"); | 1229 content = xmlnode_get_next_twin(content)) { |
1211 if (!content) { | 1230 /* init media */ |
1212 purple_debug_error("jabber", "jingle tag must contain content tag\n"); | 1231 if (!content) { |
1213 /* should send error here */ | 1232 purple_debug_error("jabber", "jingle tag must contain content tag\n"); |
1214 return; | 1233 /* should send error here */ |
1215 } | 1234 return; |
1216 | 1235 } |
1217 description = xmlnode_get_child(content, "description"); | 1236 |
1218 | 1237 description = xmlnode_get_child(content, "description"); |
1219 if (!description) { | 1238 |
1220 purple_debug_error("jabber", "content tag must contain description tag\n"); | 1239 if (!description) { |
1221 /* we should create an error iq here */ | 1240 purple_debug_error("jabber", "content tag must contain description tag\n"); |
1222 return; | 1241 /* we should create an error iq here */ |
1223 } | 1242 return; |
1224 | 1243 } |
1225 transport = xmlnode_get_child(content, "transport"); | 1244 |
1226 | 1245 transport = xmlnode_get_child(content, "transport"); |
1227 if (!transport) { | 1246 |
1228 purple_debug_error("jingle", "content tag must contain transport tag\n"); | 1247 if (!transport) { |
1229 /* we should create an error iq here */ | 1248 purple_debug_error("jingle", "content tag must contain transport tag\n"); |
1230 return; | 1249 /* we should create an error iq here */ |
1250 return; | |
1251 } | |
1252 | |
1253 jabber_jingle_session_content_create_parse(session, content); | |
1231 } | 1254 } |
1232 | 1255 |
1233 if (!jabber_jingle_session_initiate_media_internal(session, initiator, initiator)) { | 1256 if (!jabber_jingle_session_initiate_media_internal(session, initiator, initiator)) { |
1234 purple_debug_error("jabber", "Couldn't start media session with %s\n", initiator); | 1257 purple_debug_error("jabber", "Couldn't start media session with %s\n", initiator); |
1235 jabber_jingle_session_destroy(session); | 1258 jabber_jingle_session_destroy(session); |
1236 /* we should create an error iq here */ | 1259 /* we should create an error iq here */ |
1237 return; | 1260 return; |
1238 } | 1261 } |
1239 | 1262 |
1240 jabber_jingle_session_content_create_parse(session, jingle); | 1263 for (content = xmlnode_get_child(jingle, "content"); content; |
1241 | 1264 content = xmlnode_get_next_twin(content)) { |
1242 codecs = jabber_jingle_get_codecs(description); | 1265 /* init media */ |
1243 | 1266 if (!content) { |
1244 purple_media_set_remote_audio_codecs(session->media, initiator, codecs); | 1267 purple_debug_error("jabber", "jingle tag must contain content tag\n"); |
1245 | 1268 /* should send error here */ |
1269 return; | |
1270 } | |
1271 | |
1272 description = xmlnode_get_child(content, "description"); | |
1273 | |
1274 if (!description) { | |
1275 purple_debug_error("jabber", "content tag must contain description tag\n"); | |
1276 /* we should create an error iq here */ | |
1277 return; | |
1278 } | |
1279 codecs = jabber_jingle_get_codecs(description); | |
1280 | |
1281 purple_media_set_remote_codecs(session->media, | |
1282 xmlnode_get_attrib(content, "name"), | |
1283 initiator, codecs); | |
1284 purple_debug_info("jingle", "codec intersection: %i\n", | |
1285 g_list_length(purple_media_get_negotiated_codecs(session->media, | |
1286 xmlnode_get_attrib(content, "name")))); | |
1287 } | |
1246 jabber_iq_send(jabber_jingle_session_create_ack(js, packet)); | 1288 jabber_iq_send(jabber_jingle_session_create_ack(js, packet)); |
1247 jabber_iq_send(jabber_jingle_session_create_session_info(session, "ringing")); | 1289 jabber_iq_send(jabber_jingle_session_create_session_info(session, "ringing")); |
1248 } | 1290 } |
1249 | 1291 |
1250 void | 1292 void |
1259 return; | 1301 return; |
1260 } | 1302 } |
1261 | 1303 |
1262 /* maybe we should look at the reasoncode to determine if it was | 1304 /* maybe we should look at the reasoncode to determine if it was |
1263 a hangup or a reject, and call different callbacks to purple_media */ | 1305 a hangup or a reject, and call different callbacks to purple_media */ |
1264 gst_element_set_state(purple_media_get_audio_pipeline(session->media), GST_STATE_NULL); | 1306 gst_element_set_state(purple_media_get_pipeline(session->media), GST_STATE_NULL); |
1265 | 1307 |
1266 purple_media_got_hangup(jabber_jingle_session_get_media(session)); | 1308 purple_media_got_hangup(jabber_jingle_session_get_media(session)); |
1267 jabber_iq_send(jabber_jingle_session_create_ack(js, packet)); | 1309 jabber_iq_send(jabber_jingle_session_create_ack(js, packet)); |
1268 jabber_jingle_session_destroy(session); | 1310 jabber_jingle_session_destroy(session); |
1269 } | 1311 } |
1287 xmlnode_set_attrib(result->node, "to", xmlnode_get_attrib(packet, "from")); | 1329 xmlnode_set_attrib(result->node, "to", xmlnode_get_attrib(packet, "from")); |
1288 jabber_iq_send(result); | 1330 jabber_iq_send(result); |
1289 | 1331 |
1290 /* add candidates to our list of remote candidates */ | 1332 /* add candidates to our list of remote candidates */ |
1291 if (g_list_length(remote_candidates) > 0) { | 1333 if (g_list_length(remote_candidates) > 0) { |
1292 purple_media_add_remote_audio_candidates(session->media, | 1334 purple_media_add_remote_candidates(session->media, |
1293 xmlnode_get_attrib(packet, "from"), | 1335 xmlnode_get_attrib(content, "name"), |
1294 remote_candidates); | 1336 xmlnode_get_attrib(packet, "from"), |
1337 remote_candidates); | |
1295 fs_candidate_list_destroy(remote_candidates); | 1338 fs_candidate_list_destroy(remote_candidates); |
1296 } | 1339 } |
1297 } | 1340 } |
1298 | 1341 |
1299 #endif /* USE_VV */ | 1342 #endif /* USE_VV */ |