]> sjero.net Git - linphone/commitdiff
Gather ICE server reflexive candidates when starting an outgoing call.
authorGhislain MARY <ghislain.mary@belledonne-communications.com>
Tue, 17 Jul 2012 14:46:36 +0000 (16:46 +0200)
committerGhislain MARY <ghislain.mary@belledonne-communications.com>
Thu, 19 Jul 2012 13:03:27 +0000 (15:03 +0200)
coreapi/linphonecall.c
coreapi/misc.c
coreapi/private.h

index f533711cf7de3630413bb7c8a5b3c176e15aafb0..0be2c960865731b3674527cfe35577f6f4e2f3c5 100644 (file)
@@ -350,7 +350,7 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr
                        linphone_core_run_stun_tests(call->core,call);
                        break;
                case LinphonePolicyUseIce:
-                       ms_error("Gather ICE candidates");
+                       linphone_core_gather_ice_candidates(call->core,call);
                        break;
                default:
                        break;
index a749bf2793ba5f2a54867d0d4bed878073980b44..632ddfe754915f714b41b12aeb1c42e0575da5e8 100644 (file)
@@ -562,6 +562,107 @@ void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){
        }
 }
 
+void linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call)
+{
+       char addr[64];
+       int port;
+       int id;
+       ortp_socket_t audio_socks[2];
+       ortp_socket_t video_socks[2];
+       bool_t audio_responses[2];
+       bool_t video_responses[2];
+       struct sockaddr_storage ss;
+       socklen_t ss_len;
+       struct timeval init, cur;
+       double elapsed;
+       int loops = 0;
+       const LinphoneCallParams *params = linphone_call_get_current_params(call);
+       const char *server = linphone_core_get_stun_server(lc);
+
+       if (server == NULL) return;
+       if (lc->sip_conf.ipv6_enabled){
+               ms_warning("stun support is not implemented for ipv6");
+               return;
+       }
+
+       if (parse_hostname_to_addr(server, &ss, &ss_len) < 0) {
+               ms_error("Fail to parser stun server address: %s", server);
+               return;
+       }
+       if (lc->vtable.display_status != NULL)
+               lc->vtable.display_status(lc, _("ICE local candidates gathering in progress..."));
+
+       audio_responses[0] = audio_responses[1] = FALSE;
+       video_responses[0] = video_responses[1] = FALSE;
+       audio_socks[0] = create_socket(call->audio_port);
+       if (audio_socks[0] == -1) return;
+       audio_socks[1] = create_socket(call->audio_port + 1);
+       if (audio_socks[1] == -1) return;
+       if (params->has_video) {
+               video_socks[0] = create_socket(call->video_port);
+               if (video_socks[0] == -1) return;
+               video_socks[1] = create_socket(call->video_port + 1);
+               if (video_socks[1] == -1) return;
+       } else {
+               video_socks[0] = video_socks[1] = -1;
+       }
+
+       gettimeofday(&init, NULL);
+       do {
+               if (loops % 20 == 0) {
+                       ms_message("Sending stun requests...");
+                       if (audio_responses[0] == FALSE) sendStunRequest(audio_socks[0], (struct sockaddr*)&ss, ss_len, 1, FALSE);
+                       if (audio_responses[1] == FALSE) sendStunRequest(audio_socks[1], (struct sockaddr*)&ss, ss_len, 1, FALSE);
+                       if (params->has_video) {
+                               if (video_responses[0] == FALSE) sendStunRequest(video_socks[0], (struct sockaddr*)&ss, ss_len, 2, FALSE);
+                               if (video_responses[1] == FALSE) sendStunRequest(video_socks[1], (struct sockaddr*)&ss, ss_len, 2, FALSE);
+                       }
+               }
+#ifdef WIN32
+               Sleep(10);
+#else
+               usleep(10000);
+#endif
+
+               if (recvStunResponse(audio_socks[0], addr, &port, &id) > 0) {
+                       ice_add_local_candidate(call->localdesc->streams[0].ice_check_list, "srflx", addr, port, 1, NULL);
+                       audio_responses[0] = TRUE;
+               }
+               if (recvStunResponse(audio_socks[1], addr, &port, &id) > 0) {
+                       ice_add_local_candidate(call->localdesc->streams[0].ice_check_list, "srflx", addr, port, 2, NULL);
+                       audio_responses[1] = TRUE;
+               }
+               if (params->has_video) {
+                       if (recvStunResponse(video_socks[0], addr, &port, &id) > 0) {
+                               ice_add_local_candidate(call->localdesc->streams[1].ice_check_list, "srflx", addr, port, 1, NULL);
+                               video_responses[0] = TRUE;
+                       }
+                       if (recvStunResponse(video_socks[1], addr, &port, &id) > 0) {
+                               ice_add_local_candidate(call->localdesc->streams[1].ice_check_list, "srflx", addr, port, 2, NULL);
+                               video_responses[1] = TRUE;
+                       }
+               }
+
+               gettimeofday(&cur, NULL);
+               elapsed = ((cur.tv_sec - init.tv_sec) * 1000.0) +  ((cur.tv_usec - init.tv_usec) / 1000.0);
+               if (elapsed > 2000)  {
+                       ms_message("Stun responses timeout, going ahead.");
+                       break;
+               }
+               loops++;
+       } while (!((audio_responses[0] == TRUE) && (audio_responses[1] == TRUE)
+               && (!params->has_video || ((video_responses[0] == TRUE) && (video_responses[1] == TRUE)))));
+
+       close_socket(audio_socks[0]);
+       close_socket(audio_socks[1]);
+       ice_dump_candidates(call->localdesc->streams[0].ice_check_list);
+       if (params->has_video) {
+               if (video_socks[0] != -1) close_socket(video_socks[0]);
+               if (video_socks[1] != -1) close_socket(video_socks[1]);
+               ice_dump_candidates(call->localdesc->streams[1].ice_check_list);
+       }
+}
+
 LinphoneCall * is_a_linphone_call(void *user_pointer){
        LinphoneCall *call=(LinphoneCall*)user_pointer;
        if (call==NULL) return NULL;
index dd8b2b3bd3b1cf9ea450c406f4e8d2936490a464..2a2cd78161f3ea69c6ab210b3ae7949dff6bf952 100644 (file)
@@ -220,6 +220,7 @@ MSList *linphone_find_friend(MSList *fl, const LinphoneAddress *fri, LinphoneFri
 void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc);
 void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCall *call, const PayloadType *pt);
 void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call);
+void linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call);
 
 void linphone_core_send_initial_subscribes(LinphoneCore *lc);
 void linphone_core_write_friends_config(LinphoneCore* lc);