]> sjero.net Git - linphone/commitdiff
Merge branch 'upnp'
authorYann Diorcet <yann.diorcet@belledonne-communications.com>
Fri, 25 Jan 2013 11:01:50 +0000 (12:01 +0100)
committerYann Diorcet <yann.diorcet@belledonne-communications.com>
Fri, 25 Jan 2013 11:01:50 +0000 (12:01 +0100)
Conflicts:
coreapi/callbacks.c
coreapi/linphonecore.c
gtk/Makefile.am
mediastreamer2

19 files changed:
configure.ac
console/Makefile.am
coreapi/TunnelManager.cc
coreapi/callbacks.c
coreapi/linphonecall.c
coreapi/linphonecore.c
coreapi/linphonecore.h
coreapi/lpconfig.c
coreapi/misc.c
coreapi/offeranswer.c
coreapi/private.h
coreapi/sal.c
coreapi/sal.h
coreapi/sal_eXosip2.c
coreapi/sal_eXosip2.h
coreapi/sal_eXosip2_sdp.c
gtk/Makefile.am
java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java
mediastreamer2

index 9e6364c37e6d8bf4453b30177be8a97092eb6572..3526920fc9070615f5722c97149e25845f094974 100644 (file)
@@ -84,6 +84,19 @@ IT_PROG_INTLTOOL([0.40], [no-xml])
 AM_CONDITIONAL(BUILD_TESTS,test x$build_tests != xno)
 dnl Initialize libtool
 LT_INIT([win32-dll shared disable-static])
+dnl Enable library dependencies linking
+AC_ARG_ENABLE(deplibs-link,
+      [AS_HELP_STRING([--disable-deplibs-link ], [Disable library dependencies linking (might break builds)])],
+      [enable_deplibs_linking="$enableval"],
+      [enable_deplibs_linking="yes"])
+AC_MSG_NOTICE([Enable library dependencies linking: $enable_interlib_deps])
+if test "${enable_deplibs_linking}" == "yes"; then
+      link_all_deplibs=yes
+      link_all_deplibs_CXX=yes
+else
+      link_all_deplibs=no
+      link_all_deplibs_CXX=no
+fi
 
 AC_CONFIG_COMMANDS([libtool-hacking],[
 if test "$mingw_found" = "yes" ; then
index 23a7635d1713109b23aea8fc625ec42519fe953c..82ce998e50dc671d08ad56547a8dbbf70cd1817a 100644 (file)
@@ -26,11 +26,8 @@ endif
 
 linphonec_SOURCES=linphonec.c linphonec.h commands.c
 linphonec_CFLAGS=$(COMMON_CFLAGS) $(CONSOLE_FLAGS)
-linphonec_LDADD=$(top_builddir)/coreapi/liblinphone.la $(READLINE_LIBS)  \
-               $(MEDIASTREAMER_LIBS) \
-               $(ORTP_LIBS) \
-               $(SPEEX_LIBS) \
-               $(OSIP_LIBS) \
+linphonec_LDADD=$(top_builddir)/coreapi/liblinphone.la \
+               $(READLINE_LIBS)  \
                $(X11_LIBS)
 
 if BUILD_WIN32
index 5b1b6dddb23e60c6ac4afe23e0ee52906cd02f9e..4828bf114fbfc1b474ddaa09ba27203bebda6a8f 100644 (file)
@@ -257,7 +257,7 @@ void TunnelManager::processTunnelEvent(const Event &ev){
                //force transport to udp
                LCSipTransports lTransport;
                
-               lTransport.udp_port=15060;
+               lTransport.udp_port=(0xDFFF&random())+1024;
                lTransport.tcp_port=0;
                lTransport.tls_port=0;
                lTransport.dtls_port=0;
index ab5fb780bb27617f82189935ddeab3740173d624..948fc720b37fa65fcd0cdb1c16749d6130e7a862 100644 (file)
@@ -41,14 +41,14 @@ void linphone_core_update_streams_destinations(LinphoneCore *lc, LinphoneCall *c
        char *rtp_addr, *rtcp_addr;
        int i;
 
-       for (i = 0; i < old_md->nstreams; i++) {
+       for (i = 0; i < old_md->n_active_streams; i++) {
                if (old_md->streams[i].type == SalAudio) {
                        old_audiodesc = &old_md->streams[i];
                } else if (old_md->streams[i].type == SalVideo) {
                        old_videodesc = &old_md->streams[i];
                }
        }
-       for (i = 0; i < new_md->nstreams; i++) {
+       for (i = 0; i < new_md->n_active_streams; i++) {
                if (new_md->streams[i].type == SalAudio) {
                        new_audiodesc = &new_md->streams[i];
                } else if (new_md->streams[i].type == SalVideo) {
@@ -357,6 +357,7 @@ static void call_accepted(SalOp *op){
                if (call->referer) linphone_core_notify_refer_state(lc,call->referer,call);
        }
        if (md && !sal_media_description_empty(md) && !linphone_core_incompatible_security(lc,md)){
+               linphone_call_update_remote_session_id_and_ver(call);
                if (sal_media_description_has_dir(md,SalStreamSendOnly) ||
                    sal_media_description_has_dir(md,SalStreamInactive)){
                        if (lc->vtable.display_status){
@@ -443,6 +444,7 @@ static void call_accept_update(LinphoneCore *lc, LinphoneCall *call){
                linphone_core_update_local_media_description_from_upnp(call->localdesc,call->upnp_session);
        }
 #endif //BUILD_UPNP
+       linphone_call_update_remote_session_id_and_ver(call);
        sal_call_accept(call->op);
        md=sal_call_get_final_media_description(call->op);
        if (md && !sal_media_description_empty(md))
@@ -611,7 +613,7 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de
                                        if (call->state==LinphoneCallOutgoingInit || call->state==LinphoneCallOutgoingProgress){
                                                /* clear SRTP local params */
                                                call->params.media_encryption = LinphoneMediaEncryptionNone;
-                                               for(i=0; i<call->localdesc->nstreams; i++) {
+                                               for(i=0; i<call->localdesc->n_active_streams; i++) {
                                                        call->localdesc->streams[i].proto = SalProtoRtpAvp;
                                                        memset(call->localdesc->streams[i].crypto, 0, sizeof(call->localdesc->streams[i].crypto));
                                                }
index eece911b49f5788314640d6bdbe64e5885fd074c..11be247c237bd5a5bf7f8576e8f6b1616e80d239 100644 (file)
@@ -173,9 +173,10 @@ void linphone_call_set_authentication_token_verified(LinphoneCall *call, bool_t
        propagate_encryption_changed(call);
 }
 
-static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandwidth_limit,int* max_sample_rate){
+static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandwidth_limit,int* max_sample_rate, int nb_codecs_limit){
        MSList *l=NULL;
        const MSList *it;
+       int nb = 0;
        if (max_sample_rate) *max_sample_rate=0;
        for(it=codecs;it!=NULL;it=it->next){
                PayloadType *pt=(PayloadType*)it->data;
@@ -186,26 +187,30 @@ static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandw
                        }
                        if (linphone_core_check_payload_type_usability(lc,pt)){
                                l=ms_list_append(l,payload_type_clone(pt));
+                               nb++;
                                if (max_sample_rate && payload_type_get_rate(pt)>*max_sample_rate) *max_sample_rate=payload_type_get_rate(pt);
                        }
                }
+               if ((nb_codecs_limit > 0) && (nb >= nb_codecs_limit)) break;
        }
        return l;
 }
 
 static void update_media_description_from_stun(SalMediaDescription *md, const StunCandidate *ac, const StunCandidate *vc){
-       if (ac->port!=0){
-               strcpy(md->streams[0].rtp_addr,ac->addr);
-               md->streams[0].rtp_port=ac->port;
-               if ((ac->addr[0]!='\0' && vc->addr[0]!='\0' && strcmp(ac->addr,vc->addr)==0) || md->nstreams==1){
-                       strcpy(md->addr,ac->addr);
+       int i;
+       for (i = 0; i < md->n_active_streams; i++) {
+               if ((md->streams[i].type == SalAudio) && (ac->port != 0)) {
+                       strcpy(md->streams[0].rtp_addr,ac->addr);
+                       md->streams[0].rtp_port=ac->port;
+                       if ((ac->addr[0]!='\0' && vc->addr[0]!='\0' && strcmp(ac->addr,vc->addr)==0) || md->n_active_streams==1){
+                               strcpy(md->addr,ac->addr);
+                       }
+               }
+               if ((md->streams[i].type == SalVideo) && (vc->port != 0)) {
+                       strcpy(md->streams[1].rtp_addr,vc->addr);
+                       md->streams[1].rtp_port=vc->port;
                }
        }
-       if (vc->port!=0){
-               strcpy(md->streams[1].rtp_addr,vc->addr);
-               md->streams[1].rtp_port=vc->port;
-       }
-       
 }
 
 void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *call){
@@ -218,12 +223,13 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
        const char *username=linphone_address_get_username (addr);
        SalMediaDescription *md=sal_media_description_new();
        bool_t keep_srtp_keys=lp_config_get_int(lc->config,"sip","keep_srtp_keys",0);
-       
+
        linphone_core_adapt_to_network(lc,call->ping_time,&call->params);
 
        md->session_id=(old_md ? old_md->session_id : (rand() & 0xfff));
        md->session_ver=(old_md ? (old_md->session_ver+1) : (rand() & 0xfff));
-       md->nstreams=1;
+       md->n_total_streams=(old_md ? old_md->n_total_streams : 1);
+       md->n_active_streams=1;
        strncpy(md->addr,call->localip,sizeof(md->addr));
        strncpy(md->username,username,sizeof(md->username));
        
@@ -243,22 +249,35 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
                md->streams[0].ptime=call->params.down_ptime;
        else
                md->streams[0].ptime=linphone_core_get_download_ptime(lc);
-       l=make_codec_list(lc,lc->codecs_conf.audio_codecs,call->params.audio_bw,&md->streams[0].max_rate);
+       l=make_codec_list(lc,lc->codecs_conf.audio_codecs,call->params.audio_bw,&md->streams[0].max_rate,-1);
        pt=payload_type_clone(rtp_profile_get_payload_from_mime(lc->default_profile,"telephone-event"));
        l=ms_list_append(l,pt);
        md->streams[0].payloads=l;
 
        if (call->params.has_video){
-               md->nstreams++;
+               md->n_active_streams++;
                md->streams[1].rtp_port=call->video_port;
                md->streams[1].rtcp_port=call->video_port+1;
                md->streams[1].proto=md->streams[0].proto;
                md->streams[1].type=SalVideo;
-               l=make_codec_list(lc,lc->codecs_conf.video_codecs,0,NULL);
+               l=make_codec_list(lc,lc->codecs_conf.video_codecs,0,NULL,-1);
                md->streams[1].payloads=l;
        }
-       
-       for(i=0; i<md->nstreams; i++) {
+       if (md->n_total_streams < md->n_active_streams)
+               md->n_total_streams = md->n_active_streams;
+
+       /* Deactivate inactive streams. */
+       for (i = md->n_active_streams; i < md->n_total_streams; i++) {
+               md->streams[i].rtp_port = 0;
+               md->streams[i].rtcp_port = 0;
+               md->streams[i].proto = SalProtoRtpAvp;
+               md->streams[i].type = old_md->streams[i].type;
+               md->streams[i].dir = SalStreamInactive;
+               l = make_codec_list(lc, lc->codecs_conf.video_codecs, 0, NULL, 1);
+               md->streams[i].payloads = l;
+       }
+
+       for(i=0; i<md->n_active_streams; i++) {
                if (md->streams[i].proto == SalProtoRtpSavp) {
                        if (keep_srtp_keys && old_md && old_md->streams[i].proto==SalProtoRtpSavp){
                                int j;
@@ -1699,18 +1718,20 @@ void linphone_call_update_crypto_parameters(LinphoneCall *call, SalMediaDescript
        new_stream = sal_media_description_find_stream(new_md, SalProtoRtpSavp, SalAudio);
        if (old_stream && new_stream) {
                const SalStreamDescription *local_st_desc = sal_media_description_find_stream(call->localdesc, SalProtoRtpSavp, SalAudio);
-               int crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, new_stream->crypto_local_tag);
-               if (crypto_idx >= 0) {
-                       audio_stream_enable_srtp(call->audiostream, new_stream->crypto[0].algo, local_st_desc->crypto[crypto_idx].master_key, new_stream->crypto[0].master_key);
-                       call->audiostream_encrypted = TRUE;
-               } else {
-                       ms_warning("Failed to find local crypto algo with tag: %d", new_stream->crypto_local_tag);
-                       call->audiostream_encrypted = FALSE;
-               }
-               for (i = 0; i < SAL_CRYPTO_ALGO_MAX; i++) {
-                       old_stream->crypto[i].tag = new_stream->crypto[i].tag;
-                       old_stream->crypto[i].algo = new_stream->crypto[i].algo;
-                       strncpy(old_stream->crypto[i].master_key, new_stream->crypto[i].master_key, sizeof(old_stream->crypto[i].master_key) - 1);
+               if (local_st_desc) {
+                       int crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, new_stream->crypto_local_tag);
+                       if (crypto_idx >= 0) {
+                               audio_stream_enable_srtp(call->audiostream, new_stream->crypto[0].algo, local_st_desc->crypto[crypto_idx].master_key, new_stream->crypto[0].master_key);
+                               call->audiostream_encrypted = TRUE;
+                       } else {
+                               ms_warning("Failed to find local crypto algo with tag: %d", new_stream->crypto_local_tag);
+                               call->audiostream_encrypted = FALSE;
+                       }
+                       for (i = 0; i < SAL_CRYPTO_ALGO_MAX; i++) {
+                               old_stream->crypto[i].tag = new_stream->crypto[i].tag;
+                               old_stream->crypto[i].algo = new_stream->crypto[i].algo;
+                               strncpy(old_stream->crypto[i].master_key, new_stream->crypto[i].master_key, sizeof(old_stream->crypto[i].master_key) - 1);
+                       }
                }
        }
 
@@ -1719,23 +1740,33 @@ void linphone_call_update_crypto_parameters(LinphoneCall *call, SalMediaDescript
        new_stream = sal_media_description_find_stream(new_md, SalProtoRtpSavp, SalVideo);
        if (old_stream && new_stream) {
                const SalStreamDescription *local_st_desc = sal_media_description_find_stream(call->localdesc, SalProtoRtpSavp, SalVideo);
-               int crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, new_stream->crypto_local_tag);
-               if (crypto_idx >= 0) {
-                       video_stream_enable_strp(call->videostream, new_stream->crypto[0].algo, local_st_desc->crypto[crypto_idx].master_key, new_stream->crypto[0].master_key);
-                       call->videostream_encrypted = TRUE;
-               } else {
-                       ms_warning("Failed to find local crypto algo with tag: %d", new_stream->crypto_local_tag);
-                       call->videostream_encrypted = FALSE;
-               }
-               for (i = 0; i < SAL_CRYPTO_ALGO_MAX; i++) {
-                       old_stream->crypto[i].tag = new_stream->crypto[i].tag;
-                       old_stream->crypto[i].algo = new_stream->crypto[i].algo;
-                       strncpy(old_stream->crypto[i].master_key, new_stream->crypto[i].master_key, sizeof(old_stream->crypto[i].master_key) - 1);
+               if (local_st_desc) {
+                       int crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, new_stream->crypto_local_tag);
+                       if (crypto_idx >= 0) {
+                               video_stream_enable_strp(call->videostream, new_stream->crypto[0].algo, local_st_desc->crypto[crypto_idx].master_key, new_stream->crypto[0].master_key);
+                               call->videostream_encrypted = TRUE;
+                       } else {
+                               ms_warning("Failed to find local crypto algo with tag: %d", new_stream->crypto_local_tag);
+                               call->videostream_encrypted = FALSE;
+                       }
+                       for (i = 0; i < SAL_CRYPTO_ALGO_MAX; i++) {
+                               old_stream->crypto[i].tag = new_stream->crypto[i].tag;
+                               old_stream->crypto[i].algo = new_stream->crypto[i].algo;
+                               strncpy(old_stream->crypto[i].master_key, new_stream->crypto[i].master_key, sizeof(old_stream->crypto[i].master_key) - 1);
+                       }
                }
        }
 #endif
 }
 
+void linphone_call_update_remote_session_id_and_ver(LinphoneCall *call) {
+       SalMediaDescription *remote_desc = sal_call_get_remote_media_description(call->op);
+       if (remote_desc) {
+               call->remote_session_id = remote_desc->session_id;
+               call->remote_session_ver = remote_desc->session_ver;
+       }
+}
+
 void linphone_call_delete_ice_session(LinphoneCall *call){
        if (call->ice_session != NULL) {
                ice_session_destroy(call->ice_session);
index 9545af23ffc2cdfec817f7769838e70c1360133d..c6a2857fcc48eadc74c8838d44b78be9c5ae3cf6 100644 (file)
@@ -634,7 +634,8 @@ static void sip_config_read(LinphoneCore *lc)
        lc->sip_conf.ping_with_options=lp_config_get_int(lc->config,"sip","ping_with_options",1);
        lc->sip_conf.auto_net_state_mon=lp_config_get_int(lc->config,"sip","auto_net_state_mon",1);
        lc->sip_conf.keepalive_period=lp_config_get_int(lc->config,"sip","keepalive_period",10000);
-       sal_set_keepalive_period(lc->sal,lc->sip_conf.keepalive_period);
+       lc->sip_conf.tcp_tls_keepalive=lp_config_get_int(lc->config,"sip","tcp_tls_keepalive",0);
+       linphone_core_enable_keep_alive(lc, (lc->sip_conf.keepalive_period > 0));
        sal_use_one_matching_codec_policy(lc->sal,lp_config_get_int(lc->config,"sip","only_one_codec",0));
        sal_use_double_registrations(lc->sal,lp_config_get_int(lc->config,"sip","use_double_registrations",1));
        sal_use_dates(lc->sal,lp_config_get_int(lc->config,"sip","put_date",0));
@@ -920,11 +921,14 @@ bool_t linphone_core_tunnel_available(void){
 }
 
 /**
- * Enable adaptive rate control (experimental feature, audio-only).
+ * Enable adaptive rate control.
+ * 
+ * @ingroup media_parameters
  *
  * Adaptive rate control consists in using RTCP feedback provided information to dynamically
- * control the output bitrate of the encoders, so that we can adapt to the network conditions and
- * available bandwidth.
+ * control the output bitrate of the audio and video encoders, so that we can adapt to the network conditions and
+ * available bandwidth. Control of the audio encoder is done in case of audio-only call, and control of the video encoder is done for audio & video calls.
+ * Adaptive rate control feature is enabled by default.
 **/
 void linphone_core_enable_adaptive_rate_control(LinphoneCore *lc, bool_t enabled){
        lp_config_set_int(lc->config,"net","adaptive_rate_control",(int)enabled);
@@ -932,6 +936,8 @@ void linphone_core_enable_adaptive_rate_control(LinphoneCore *lc, bool_t enabled
 
 /**
  * Returns whether adaptive rate control is enabled.
+ * 
+ * @ingroup media_parameters
  *
  * See linphone_core_enable_adaptive_rate_control().
 **/
@@ -1004,14 +1010,18 @@ int linphone_core_get_upload_bandwidth(const LinphoneCore *lc){
        return lc->net_conf.upload_bw;
 }
 /**
- * Set audio packetization time linphone expects to receive from peer
+ * Set audio packetization time linphone expects to receive from peer.
+ * A value of zero means that ptime is not specified.
+ * @ingroup media_parameters
  */
 void linphone_core_set_download_ptime(LinphoneCore *lc, int ptime) {
        lp_config_set_int(lc->config,"rtp","download_ptime",ptime);
 }
 
 /**
- * Get audio packetization time linphone expects to receive from peer
+ * Get audio packetization time linphone expects to receive from peer.
+ * A value of zero means that ptime is not specified.
+ * @ingroup media_parameters
  */
 int linphone_core_get_download_ptime(LinphoneCore *lc) {
        return lp_config_get_int(lc->config,"rtp","download_ptime",0);
@@ -1021,6 +1031,7 @@ int linphone_core_get_download_ptime(LinphoneCore *lc) {
  * Set audio packetization time linphone will send (in absence of requirement from peer)
  * A value of 0 stands for the current codec default packetization time.
  *
+ * @ingroup media_parameters
 **/
 void linphone_core_set_upload_ptime(LinphoneCore *lc, int ptime){
        lp_config_set_int(lc->config,"rtp","upload_ptime",ptime);
@@ -1030,6 +1041,8 @@ void linphone_core_set_upload_ptime(LinphoneCore *lc, int ptime){
  * Set audio packetization time linphone will send (in absence of requirement from peer)
  * A value of 0 stands for the current codec default packetization time.
  *
+ * 
+ * @ingroup media_parameters
 **/
 int linphone_core_get_upload_ptime(LinphoneCore *lc){
        return lp_config_get_int(lc->config,"rtp","upload_ptime",0);
@@ -1266,6 +1279,7 @@ LinphoneCore *linphone_core_new(const LinphoneCoreVTable *vtable,
  * structure holding the codec information.
  * It is possible to make copy of the list with ms_list_copy() in order to modify it
  * (such as the order of codecs).
+ * @ingroup media_parameters
 **/
 const MSList *linphone_core_get_audio_codecs(const LinphoneCore *lc)
 {
@@ -1279,6 +1293,7 @@ const MSList *linphone_core_get_audio_codecs(const LinphoneCore *lc)
  * structure holding the codec information.
  * It is possible to make copy of the list with ms_list_copy() in order to modify it
  * (such as the order of codecs).
+ * @ingroup media_parameters
 **/
 const MSList *linphone_core_get_video_codecs(const LinphoneCore *lc)
 {
@@ -1576,6 +1591,7 @@ void linphone_core_set_audio_port(LinphoneCore *lc, int port)
 
 /**
  * Sets the UDP port range from which to randomly select the port used for audio streaming.
+ * @ingroup media_parameters
  */
 void linphone_core_set_audio_port_range(LinphoneCore *lc, int min_port, int max_port)
 {
@@ -1594,6 +1610,7 @@ void linphone_core_set_video_port(LinphoneCore *lc, int port){
 
 /**
  * Sets the UDP port range from which to randomly select the port used for video streaming.
+ * @ingroup media_parameters
  */
 void linphone_core_set_video_port_range(LinphoneCore *lc, int min_port, int max_port)
 {
@@ -2069,6 +2086,8 @@ void linphone_core_iterate(LinphoneCore *lc){
 /**
  * Interpret a call destination as supplied by the user, and returns a fully qualified
  * LinphoneAddress.
+ * 
+ * @ingroup call_control
  *
  * A sip address should look like DisplayName <sip:username@domain:port> .
  * Basically this function performs the following tasks
@@ -2533,6 +2552,7 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
 /**
  * Performs a simple call transfer to the specified destination.
  *
+ * @ingroup call_control
  * The remote endpoint is expected to issue a new call to the specified destination.
  * The current call remains active and thus can be later paused or terminated.
 **/
@@ -2563,6 +2583,8 @@ int linphone_core_transfer_call(LinphoneCore *lc, LinphoneCall *call, const char
  * @param lc linphone core object
  * @param call a running call you want to transfer
  * @param dest a running call whose remote person will receive the transfer
+ * 
+ * @ingroup call_control
  *
  * The transfered call is supposed to be in paused state, so that it is able to accept the transfer immediately.
  * The destination call is a call previously established to introduce the transfered person.
@@ -2590,7 +2612,7 @@ bool_t linphone_core_inc_invite_pending(LinphoneCore*lc){
 bool_t linphone_core_incompatible_security(LinphoneCore *lc, SalMediaDescription *md){
        if (linphone_core_is_media_encryption_mandatory(lc) && linphone_core_get_media_encryption(lc)==LinphoneMediaEncryptionSRTP){
                int i;
-               for(i=0;i<md->nstreams;i++){
+               for(i=0;i<md->n_active_streams;i++){
                        SalStreamDescription *sd=&md->streams[i];
                        if (sd->proto!=SalProtoRtpSavp){
                                return TRUE;
@@ -2817,6 +2839,7 @@ int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call)
                linphone_core_update_local_media_description_from_upnp(call->localdesc, call->upnp_session);
        }
 #endif //BUILD_UPNP
+       linphone_call_update_remote_session_id_and_ver(call);
        sal_call_set_local_media_description(call->op,call->localdesc);
        sal_call_accept(call->op);
        md=sal_call_get_final_media_description(call->op);
@@ -2846,6 +2869,8 @@ int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call)
  * @return 0 if sucessful, -1 otherwise (actually when this function call is performed outside ot #LinphoneCallUpdatedByRemote state).
 **/
 int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){
+       SalMediaDescription *remote_desc;
+       bool_t keep_sdp_version;
 #ifdef VIDEO_ENABLED
        bool_t old_has_video = call->params.has_video;
 #endif
@@ -2854,6 +2879,15 @@ int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const
                         linphone_call_state_to_string(call->state));
                return -1;
        }
+       remote_desc = sal_call_get_remote_media_description(call->op);
+       keep_sdp_version = lp_config_get_int(lc->config, "sip", "keep_sdp_version", 0);
+       if (keep_sdp_version &&(remote_desc->session_id == call->remote_session_id) && (remote_desc->session_ver == call->remote_session_ver)) {
+               /* Remote has sent an INVITE with the same SDP as before, so send a 200 OK with the same SDP as before. */
+               ms_warning("SDP version has not changed, send same SDP as before.");
+               sal_call_accept(call->op);
+               linphone_call_set_state(call,LinphoneCallStreamsRunning,"Connected (streams running)");
+               return 0;
+       }
        if (params==NULL){
                call->params.has_video=lc->video_policy.automatically_accept || call->current_params.has_video;
        }else
@@ -2867,11 +2901,11 @@ int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const
                ms_warning("Video isn't supported in conference");
                call->params.has_video = FALSE;
        }
-       call->params.has_video &= linphone_core_media_description_contains_video_stream(sal_call_get_remote_media_description(call->op));
+       call->params.has_video &= linphone_core_media_description_contains_video_stream(remote_desc);
        call->camera_active=call->params.has_video;
        linphone_call_make_local_media_description(lc,call);
        if (call->ice_session != NULL) {
-               linphone_core_update_ice_from_remote_media_description(call, sal_call_get_remote_media_description(call->op));
+               linphone_core_update_ice_from_remote_media_description(call, remote_desc);
 #ifdef VIDEO_ENABLED
                if ((call->ice_session != NULL) &&!ice_session_candidates_gathered(call->ice_session)) {
                        if ((call->params.has_video) && (call->params.has_video != old_has_video)) {
@@ -3015,6 +3049,7 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call,
                audio_stream_prepare_sound(call->audiostream,lc->sound_conf.play_sndcard,lc->sound_conf.capt_sndcard);
        }
 
+       linphone_call_update_remote_session_id_and_ver(call);
        sal_call_accept(call->op);
        if (lc->vtable.display_status!=NULL)
                lc->vtable.display_status(lc,_("Connected."));
@@ -3115,6 +3150,9 @@ int linphone_core_terminate_call(LinphoneCore *lc, LinphoneCall *the_call)
 
 /**
  * Decline a pending incoming call, with a reason.
+ * 
+ * @ingroup call_control
+ * 
  * @param lc the linphone core
  * @param call the LinphoneCall, must be in the IncomingReceived state.
  * @param reason the reason for rejecting the call: LinphoneReasonDeclined or LinphoneReasonBusy
@@ -3240,6 +3278,7 @@ int linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call)
 
 /**
  * Pause all currently running calls.
+ * @ingroup call_control
 **/
 int linphone_core_pause_all_calls(LinphoneCore *lc){
        const MSList *elem;
@@ -3322,6 +3361,8 @@ static int remote_address_compare(LinphoneCall *call, const LinphoneAddress *rad
  * @param lc
  * @param remote_address
  * @return the LinphoneCall of the call if found
+ * 
+ * @ingroup call_control
  */
 LinphoneCall *linphone_core_get_call_by_remote_address(LinphoneCore *lc, const char *remote_address){
        LinphoneAddress *raddr=linphone_address_new(remote_address);
@@ -3795,18 +3836,18 @@ const char *linphone_core_get_ring(const LinphoneCore *lc){
  * @param path
  * @param lc The LinphoneCore object
  *
- * @ingroup media_parameters
+ * @ingroup initializing
 **/
 void linphone_core_set_root_ca(LinphoneCore *lc,const char *path){
        sal_set_root_ca(lc->sal, path);
 }
 
 /**
- * Gets the path to a file or folder containing trusted root CAs (PEM format)
+ * Gets the path to a file or folder containing the trusted root CAs (PEM format)
  *
  * @param lc The LinphoneCore object
  *
- * @ingroup media_parameters
+ * @ingroup initializing
 **/
 const char *linphone_core_get_root_ca(LinphoneCore *lc){
        return sal_get_root_ca(lc->sal);
@@ -3814,6 +3855,8 @@ const char *linphone_core_get_root_ca(LinphoneCore *lc){
 
 /**
  * Specify whether the tls server certificate must be verified when connecting to a SIP/TLS server.
+ * 
+ * @ingroup initializing
 **/
 void linphone_core_verify_server_certificates(LinphoneCore *lc, bool_t yesno){
        sal_verify_server_certificates(lc->sal,yesno);
@@ -3821,6 +3864,7 @@ void linphone_core_verify_server_certificates(LinphoneCore *lc, bool_t yesno){
 
 /**
  * Specify whether the tls server certificate common name must be verified when connecting to a SIP/TLS server.
+ * @ingroup initializing
 **/
 void linphone_core_verify_server_cn(LinphoneCore *lc, bool_t yesno){
        sal_verify_server_cn(lc->sal,yesno);
@@ -4744,6 +4788,12 @@ void *linphone_core_get_user_data(LinphoneCore *lc){
        return lc->data;
 }
 
+
+/**
+ * Associate a user pointer to the linphone core.
+ *
+ * @ingroup initializing
+**/
 void linphone_core_set_user_data(LinphoneCore *lc, void *userdata){
        lc->data=userdata;
 }
@@ -4752,6 +4802,13 @@ int linphone_core_get_mtu(const LinphoneCore *lc){
        return lc->net_conf.mtu;
 }
 
+/**
+ * Sets the maximum transmission unit size in bytes.
+ * This information is useful for sending RTP packets.
+ * Default value is 1500.
+ * 
+ * @ingroup media_parameters
+**/
 void linphone_core_set_mtu(LinphoneCore *lc, int mtu){
        lc->net_conf.mtu=mtu;
        if (mtu>0){
@@ -5280,6 +5337,7 @@ const char *linphone_error_to_string(LinphoneReason err){
  */
 void linphone_core_enable_keep_alive(LinphoneCore* lc,bool_t enable) {
        if (enable > 0) {
+               sal_use_tcp_tls_keepalive(lc->sal,lc->sip_conf.tcp_tls_keepalive);
                sal_set_keepalive_period(lc->sal,lc->sip_conf.keepalive_period);
        } else {
                sal_set_keepalive_period(lc->sal,0);
index 6af0bad346bb1517b04955d1a00bf6fe7fb8f204..1f49cce46909fd8a5ea2eb37910f47dbc3a14f77 100644 (file)
@@ -1029,16 +1029,8 @@ int linphone_core_get_upload_bandwidth(const LinphoneCore *lc);
 
 void linphone_core_enable_adaptive_rate_control(LinphoneCore *lc, bool_t enabled);
 bool_t linphone_core_adaptive_rate_control_enabled(const LinphoneCore *lc);
-/**
- * set audio packetization time linphone expect to receive from peer
- * @ingroup media_parameters
- *
- */
+
 void linphone_core_set_download_ptime(LinphoneCore *lc, int ptime);
-/**
- * get audio packetization time linphone expect to receive from peer, 0 means unspecified
- * @ingroup media_parameters
- */
 int  linphone_core_get_download_ptime(LinphoneCore *lc);
 
 void linphone_core_set_upload_ptime(LinphoneCore *lc, int ptime);
@@ -1069,7 +1061,7 @@ int linphone_core_enable_payload_type(LinphoneCore *lc, PayloadType *pt, bool_t
  */
 #define LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS -1
 /**
- * Get payload type  from mime type and clock rate
+ * Get payload type from mime type and clock rate
  * @ingroup media_parameters
  * This function searches in audio and video codecs for the given payload type name and clockrate.
  * @param lc #LinphoneCore object
index 8457cf65051d704ce57763665ef144b4accd2c0a..4608beecfff09cde860a8d0d3b4b19ec477ab8f4 100644 (file)
@@ -215,14 +215,17 @@ LpConfig * lp_config_new(const char *filename){
                lpconfig->filename=ortp_strdup(filename);
                lpconfig->file=fopen(filename,"rw");
                if (lpconfig->file!=NULL){
+                       struct stat fileStat;
                        lp_config_parse(lpconfig,lpconfig->file);
-                       fclose(lpconfig->file);                 
+                       fclose(lpconfig->file);
 #if !defined(_WIN32_WCE)
-                       /* make existing configuration files non-group/world-accessible */
-                       if (chmod(filename, S_IRUSR | S_IWUSR) == -1)
-                               ms_warning("unable to correct permissions on "
-                                         "configuration file: %s",
-                                          strerror(errno));
+                       if ((stat(filename,&fileStat) == 0) && (S_ISREG(fileStat.st_mode))) {
+                               /* make existing configuration files non-group/world-accessible */
+                               if (chmod(filename, S_IRUSR | S_IWUSR) == -1) {
+                                       ms_warning("unable to correct permissions on "
+                                       "configuration file: %s", strerror(errno));
+                               }
+                       }
 #endif /*_WIN32_WCE*/
                        lpconfig->file=NULL;
                        lpconfig->modified=0;
index 68d467599ce0e6e6934da913cf9236b0ed3bea80..897300c61767f873d3781fc3a67e4ed381b7b0bf 100644 (file)
@@ -734,7 +734,7 @@ void linphone_core_update_local_media_description_from_ice(SalMediaDescription *
        }
        strncpy(desc->ice_pwd, ice_session_local_pwd(session), sizeof(desc->ice_pwd));
        strncpy(desc->ice_ufrag, ice_session_local_ufrag(session), sizeof(desc->ice_ufrag));
-       for (i = 0; i < desc->nstreams; i++) {
+       for (i = 0; i < desc->n_active_streams; i++) {
                SalStreamDescription *stream = &desc->streams[i];
                IceCheckList *cl = ice_session_check_list(session, i);
                nb_candidates = 0;
@@ -838,7 +838,7 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call,
                        ice_session_restart(call->ice_session);
                        ice_restarted = TRUE;
                } else {
-                       for (i = 0; i < md->nstreams; i++) {
+                       for (i = 0; i < md->n_total_streams; i++) {
                                const SalStreamDescription *stream = &md->streams[i];
                                IceCheckList *cl = ice_session_check_list(call->ice_session, i);
                                if (cl && (strcmp(stream->rtp_addr, "0.0.0.0") == 0)) {
@@ -857,7 +857,7 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call,
                        }
                        ice_session_set_remote_credentials(call->ice_session, md->ice_ufrag, md->ice_pwd);
                }
-               for (i = 0; i < md->nstreams; i++) {
+               for (i = 0; i < md->n_total_streams; i++) {
                        const SalStreamDescription *stream = &md->streams[i];
                        IceCheckList *cl = ice_session_check_list(call->ice_session, i);
                        if (cl && (stream->ice_pwd[0] != '\0') && (stream->ice_ufrag[0] != '\0')) {
@@ -873,7 +873,7 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call,
                }
 
                /* Create ICE check lists if needed and parse ICE attributes. */
-               for (i = 0; i < md->nstreams; i++) {
+               for (i = 0; i < md->n_total_streams; i++) {
                        const SalStreamDescription *stream = &md->streams[i];
                        IceCheckList *cl = ice_session_check_list(call->ice_session, i);
                        if (cl == NULL) {
@@ -930,7 +930,7 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call,
                                }
                        }
                }
-               for (i = ice_session_nb_check_lists(call->ice_session); i > md->nstreams; i--) {
+               for (i = ice_session_nb_check_lists(call->ice_session); i > md->n_active_streams; i--) {
                        ice_session_remove_check_list(call->ice_session, ice_session_check_list(call->ice_session, i - 1));
                }
                ice_session_check_mismatch(call->ice_session);
@@ -948,8 +948,8 @@ bool_t linphone_core_media_description_contains_video_stream(const SalMediaDescr
 {
        int i;
 
-       for (i = 0; i < md->nstreams; i++) {
-               if ((md->streams[i].type == SalVideo) && (md->streams[i].rtp_port != 0))
+       for (i = 0; i < md->n_active_streams; i++) {
+               if (md->streams[i].type == SalVideo)
                        return TRUE;
        }
        return FALSE;
index 541a1eee3623b252b47d6a5438553d72e83226f1..ab38f76366997f3665fd59dbc4fdb2c90208529e 100644 (file)
@@ -19,6 +19,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 #include "sal.h"
 #include "offeranswer.h"
+#include "private.h"
 
 static bool_t only_telephone_event(const MSList *l){
        for(;l!=NULL;l=l->next){
@@ -267,22 +268,23 @@ static void initiate_incoming(const SalStreamDescription *local_cap,
  * and the returned response (remote).
 **/
 int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
-                                                                       const SalMediaDescription *remote_answer,
-                                                       SalMediaDescription *result){
-       int i,j;
-    
+                                       const SalMediaDescription *remote_answer,
+                                       SalMediaDescription *result){
+       int i,j;
+
        const SalStreamDescription *ls,*rs;
-       for(i=0,j=0;i<local_offer->nstreams;++i){
+       for(i=0,j=0;i<local_offer->n_total_streams;++i){
                ms_message("Processing for stream %i",i);
                ls=&local_offer->streams[i];
                rs=sal_media_description_find_stream((SalMediaDescription*)remote_answer,ls->proto,ls->type);
-       if (rs) {
+               if (rs) {
                        initiate_outgoing(ls,rs,&result->streams[j]);
                        ++j;
                }
                else ms_warning("No matching stream for %i",i);
        }
-       result->nstreams=j;
+       result->n_active_streams=j;
+       result->n_total_streams=local_offer->n_total_streams;
        result->bandwidth=remote_answer->bandwidth;
        strcpy(result->addr,remote_answer->addr);
        return 0;
@@ -294,12 +296,13 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer,
  * The returned media description is an answer and should be sent to the offerer.
 **/
 int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities,
-                                               const SalMediaDescription *remote_offer,
-                                       SalMediaDescription *result, bool_t one_matching_codec){
+                                       const SalMediaDescription *remote_offer,
+                                       SalMediaDescription *result, bool_t one_matching_codec){
        int i;
        const SalStreamDescription *ls=NULL,*rs;
-                                                       
-       for(i=0;i<remote_offer->nstreams;++i){
+
+       result->n_active_streams=0;
+       for(i=0;i<remote_offer->n_total_streams;++i){
                rs=&remote_offer->streams[i];
                if (rs->proto!=SalProtoUnknown){
                        ls=sal_media_description_find_stream((SalMediaDescription*)local_capabilities,rs->proto,rs->type);
@@ -310,6 +313,7 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities
                }else ms_warning("Unknown protocol for mline %i, declining",i);
                if (ls){
                        initiate_incoming(ls,rs,&result->streams[i],one_matching_codec);
+                       result->n_active_streams++;
                }
                else {
                        /* create an inactive stream for the answer, as there where no matching stream a local capability */
@@ -322,7 +326,7 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities
                        }
                }
        }
-       result->nstreams=i;
+       result->n_total_streams=i;
        strcpy(result->username, local_capabilities->username);
        strcpy(result->addr,local_capabilities->addr);
        result->bandwidth=local_capabilities->bandwidth;
index 41449dc9e062ef1ba8fc93d255848f90fe68cea7..c421b2bc6f1ef6acc8b4b831c6bc704dac852fb0 100644 (file)
@@ -156,6 +156,8 @@ struct _LinphoneCall
        IceSession *ice_session;
        LinphoneChatMessage* pending_message;
        int ping_time;
+       unsigned int remote_session_id;
+       unsigned int remote_session_ver;
        bool_t refer_pending;
        bool_t media_pending;
        bool_t audio_muted;
@@ -295,6 +297,7 @@ void linphone_call_delete_ice_session(LinphoneCall *call);
 void linphone_call_delete_upnp_session(LinphoneCall *call);
 void linphone_call_stop_media_streams_for_ice_gathering(LinphoneCall *call);
 void linphone_call_update_crypto_parameters(LinphoneCall *call, SalMediaDescription *old_md, SalMediaDescription *new_md);
+void linphone_call_update_remote_session_id_and_ver(LinphoneCall *call);
 
 const char * linphone_core_get_identity(LinphoneCore *lc);
 const char * linphone_core_get_route(LinphoneCore *lc);
@@ -405,6 +408,7 @@ typedef struct sip_config
        bool_t register_only_when_network_is_up;
        bool_t ping_with_options;
        bool_t auto_net_state_mon;
+       bool_t tcp_tls_keepalive;
 } sip_config_t;
 
 typedef struct rtp_config
index 2b09212aa02e79f3468aa54d8f6bbcbfaff90484..05d03499d85e327a6dc813bca746757815c193b5 100644 (file)
@@ -76,7 +76,7 @@ void sal_media_description_unref(SalMediaDescription *md){
 SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md,
     SalMediaProto proto, SalStreamType type){
        int i;
-       for(i=0;i<md->nstreams;++i){
+       for(i=0;i<md->n_active_streams;++i){
                SalStreamDescription *ss=&md->streams[i];
                if (ss->proto==proto && ss->type==type) return ss;
        }
@@ -84,17 +84,13 @@ SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md,
 }
 
 bool_t sal_media_description_empty(const SalMediaDescription *md){
-       int i;
-       for(i=0;i<md->nstreams;++i){
-               const SalStreamDescription *ss=&md->streams[i];
-               if (ss->rtp_port!=0) return FALSE;
-       }
+       if (md->n_active_streams > 0) return FALSE;
        return TRUE;
 }
 
 void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_dir){
        int i;
-       for(i=0;i<md->nstreams;++i){
+       for(i=0;i<md->n_active_streams;++i){
                SalStreamDescription *ss=&md->streams[i];
                ss->dir=stream_dir;
        }
@@ -110,7 +106,7 @@ static bool_t has_dir(const SalMediaDescription *md, SalStreamDir stream_dir){
        int i;
 
        /* we are looking for at least one stream with requested direction, inactive streams are ignored*/
-       for(i=0;i<md->nstreams;++i){
+       for(i=0;i<md->n_active_streams;++i){
                const SalStreamDescription *ss=&md->streams[i];
                if (ss->dir==stream_dir) return TRUE;
                /*compatibility check for phones that only used the null address and no attributes */
@@ -224,9 +220,9 @@ int sal_media_description_equals(const SalMediaDescription *md1, const SalMediaD
        int i;
 
        if (strcmp(md1->addr, md2->addr) != 0) result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED;
-       if (md1->nstreams != md2->nstreams) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
+       if (md1->n_total_streams != md2->n_total_streams) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
        if (md1->bandwidth != md2->bandwidth) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
-       for(i = 0; i < md1->nstreams; ++i){
+       for(i = 0; i < md1->n_total_streams; ++i){
                result |= sal_stream_description_equals(&md1->streams[i], &md2->streams[i]);
        }
        return result;
index 9c0ceca76900097b9a60b293d2440cbd8f95d620..6baae97ae8b20fb6941e3245077232fb5bc2b46b 100644 (file)
@@ -178,7 +178,8 @@ typedef struct SalMediaDescription{
        int refcount;
        char addr[64];
        char username[64];
-       int nstreams;
+       int n_active_streams;
+       int n_total_streams;
        int bandwidth;
        unsigned int session_ver;
        unsigned int session_id;
@@ -343,6 +344,7 @@ ortp_socket_t sal_get_socket(Sal *ctx);
 void sal_set_user_agent(Sal *ctx, const char *user_agent);
 /*keepalive period in ms*/
 void sal_set_keepalive_period(Sal *ctx,unsigned int value);
+void sal_use_tcp_tls_keepalive(Sal *ctx, bool_t enabled);
 /**
  * returns keepalive period in ms
  * 0 desactiaved
index 93686a75e538985ac16385236072540fe4d50435..1cbecb638c8452677d82e88c39509b072c398401 100644 (file)
@@ -397,7 +397,8 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i
        bool_t ipv6;
        int proto=IPPROTO_UDP;
        int keepalive = ctx->keepalive_period;
-       
+
+       ctx->transport = tr;
        switch (tr) {
        case SalTransportUDP:
                proto=IPPROTO_UDP;
@@ -406,7 +407,7 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i
        case SalTransportTCP:
        case SalTransportTLS:
                proto= IPPROTO_TCP;
-               keepalive=-1;
+               if (!ctx->tcp_tls_keepalive) keepalive=-1;
                eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive);
                set_tls_options(ctx);
                break;
@@ -588,18 +589,15 @@ static void sdp_process(SalOp *h){
                strcpy(h->result->addr,h->base.remote_media->addr);
                h->result->bandwidth=h->base.remote_media->bandwidth;
                
-               for(i=0;i<h->result->nstreams;++i){
-                       if (h->result->streams[i].rtp_port>0){
-                               strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
-                               strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
-                               h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
-                               h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
-                               h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
-                               h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
-                               
-                               if (h->result->streams[i].proto == SalProtoRtpSavp) {
-                                       h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0]; 
-                               }
+               for(i=0;i<h->result->n_active_streams;++i){
+                       strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
+                       strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
+                       h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
+                       h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
+                       h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
+                       h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
+                       if (h->result->streams[i].proto == SalProtoRtpSavp) {
+                               h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
                        }
                }
        }
@@ -2512,9 +2510,24 @@ void sal_address_destroy(SalAddress *u){
        osip_from_free((osip_from_t*)u);
 }
 
+void sal_use_tcp_tls_keepalive(Sal *ctx, bool_t enabled) {
+       ctx->tcp_tls_keepalive = enabled;
+}
+
 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
-       ctx->keepalive_period=value;
-       eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
+       switch (ctx->transport) {
+               case SalTransportUDP:
+                       ctx->keepalive_period = value;
+                       break;
+               case SalTransportTCP:
+               case SalTransportTLS:
+                       if (ctx->tcp_tls_keepalive) ctx->keepalive_period = value;
+                       else ctx->keepalive_period = -1;
+                       break;
+               default:
+                       break;
+       }
+       eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &ctx->keepalive_period);
 }
 unsigned int sal_get_keepalive_period(Sal *ctx) {
        return ctx->keepalive_period;
index 89ac93abf1132b97ef0064331e541c47d91c869e..81e3ed9a7902b10ad01cf4d9a8446ef1ba5d9efe 100644 (file)
@@ -30,6 +30,7 @@ int sdp_to_media_description(sdp_message_t *sdp, SalMediaDescription *desc);
 
 struct Sal{
        SalCallbacks callbacks;
+       SalTransport transport;
        MSList *calls; /*MSList of SalOp */
        MSList *registers;/*MSList of SalOp */
        MSList *out_subscribes;/*MSList of SalOp */
@@ -51,6 +52,7 @@ struct Sal{
        bool_t verify_server_cn;
        bool_t expire_old_contact;
        bool_t add_dates;
+       bool_t tcp_tls_keepalive;
 };
 
 struct SalOp{
index 050a53a764dd6c58cddbdffeee1cbe3fc62fd245..9297077e66dafc25cefa4826fe94c7aaa02c23be 100644 (file)
@@ -394,7 +394,7 @@ static void add_line(sdp_message_t *msg, int lineno, const SalStreamDescription
 sdp_message_t *media_description_to_sdp(const SalMediaDescription *desc){
        int i;
        sdp_message_t *msg=create_generic_sdp(desc);
-       for(i=0;i<desc->nstreams;++i){
+       for(i=0;i<desc->n_total_streams;++i){
                add_line(msg,i,&desc->streams[i]);
        }
        return msg;
@@ -434,10 +434,17 @@ static int payload_type_fill_from_rtpmap(PayloadType *pt, const char *rtpmap){
 int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){
        int i,j;
        const char *mtype,*proto,*rtp_port,*rtp_addr,*number;
+       const char *sess;
        sdp_bandwidth_t *sbw=NULL;
        sdp_attribute_t *attr;
        int nb_ice_candidates;
 
+       /* Get session information. */
+       sess = sdp_message_o_sess_id_get(msg);
+       if (sess) desc->session_id = strtoul(sess, NULL, 10);
+       sess = sdp_message_o_sess_version_get(msg);
+       if (sess) desc->session_ver = strtoul(sess, NULL, 10);
+
        rtp_addr=sdp_message_c_addr_get (msg, -1, 0);
        if (rtp_addr)
                strncpy(desc->addr,rtp_addr,sizeof(desc->addr));
@@ -456,6 +463,8 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){
                }
        }
 
+       desc->n_active_streams = 0;
+
        /* for each m= line */
        for (i=0; !sdp_message_endof_media (msg, i) && i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS; i++)
        {
@@ -479,6 +488,8 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){
                        strncpy(stream->rtp_addr,rtp_addr,sizeof(stream->rtp_addr));
                if (rtp_port)
                        stream->rtp_port=atoi(rtp_port);
+               if (stream->rtp_port > 0)
+                       desc->n_active_streams++;
                
                stream->ptime=_sdp_message_get_a_ptime(msg,i);
                if (strcasecmp("audio", mtype) == 0){
@@ -602,6 +613,6 @@ int sdp_to_media_description(sdp_message_t *msg, SalMediaDescription *desc){
                        }
                }
        }
-       desc->nstreams=i;
+       desc->n_total_streams=i;
        return 0;
 }
index f89ea151f017cb393aea669107fd69e10441daf1..1caded7c6c4537df3a53feeac4426178bbe45fbc 100644 (file)
@@ -53,11 +53,8 @@ linphone_SOURCES+=   \
                        setupwizard.c
 endif
 
-linphone_LDADD=\
-               $(top_builddir)/coreapi/liblinphone.la \
-               $(ORTP_LIBS) \
-               $(MEDIASTREAMER_LIBS) \
-               $(LIBGTK_LIBS) $(NOTIFY1_LIBS) $(NOTIFY4_LIBS) $(LIBGTKMAC_LIBS) $(INTLLIBS) 
+linphone_LDADD=        $(top_builddir)/coreapi/liblinphone.la \
+               $(LIBGTK_LIBS) $(NOTIFY1_LIBS) $(NOTIFY4_LIBS) $(LIBGTKMAC_LIBS) $(INTLLIBS)
 
 
 if BUILD_WIN32
index b719f0f7060cc02c975eb95d3a541809db9608cc..04b6af1cf78471675e311fefb7c27c4471152487 100644 (file)
@@ -20,8 +20,8 @@ package org.linphone.core;
 
 import java.io.File;
 import java.io.IOException;
-import java.io.InputStream;
 
+import org.linphone.CpuUtils;
 import org.linphone.mediastream.Version;
 
 import android.util.Log;
@@ -43,6 +43,8 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory {
                loadOptionalLibrary("avutil");
                loadOptionalLibrary("swscale");
                loadOptionalLibrary("avcore");
+
+               System.loadLibrary("neon");
                
                if (!hasNeonInCpuFeatures()) {
                        boolean noNeonLibrariesLoaded = loadOptionalLibrary("avcodecnoneon");
@@ -151,28 +153,8 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory {
 
        public static boolean hasNeonInCpuFeatures()
        {
-               ProcessBuilder cmd;
-               boolean result = false;
-               
-               try {
-                       String[] args = {"/system/bin/cat", "/proc/cpuinfo"};
-                       cmd = new ProcessBuilder(args);
-       
-                  Process process = cmd.start();
-                  InputStream in = process.getInputStream();
-                  byte[] re = new byte[1024];
-                  while(in.read(re) != -1){
-                          String line = new String(re);
-                          if (line.contains("Features")) {
-                                  result = line.contains("neon");
-                                  break;
-                          }
-                  }
-                  in.close();
-               } catch(IOException ex){
-                       ex.printStackTrace();
-               }
-               return result;
+               CpuUtils cpu = new CpuUtils();
+               return cpu.isCpuNeon();
        }
        
        public static boolean isArmv7()
index b21f304297319e15fbe0beb3509592022eb8e88a..2e0ef7e31e919b524cfbe1ff4ffbc409fce3599c 160000 (submodule)
@@ -1 +1 @@
-Subproject commit b21f304297319e15fbe0beb3509592022eb8e88a
+Subproject commit 2e0ef7e31e919b524cfbe1ff4ffbc409fce3599c