]> sjero.net Git - linphone/commitdiff
Merge branch 'dev_bt_session_version'
authorGhislain MARY <ghislain.mary@belledonne-communications.com>
Fri, 18 Jan 2013 10:59:52 +0000 (11:59 +0100)
committerGhislain MARY <ghislain.mary@belledonne-communications.com>
Fri, 18 Jan 2013 10:59:52 +0000 (11:59 +0100)
1  2 
coreapi/callbacks.c
coreapi/linphonecall.c
coreapi/linphonecore.c
coreapi/private.h

diff --combined coreapi/callbacks.c
index 1f7ff42fd19636c1c02678b74f7bc70e0cdaca41,032218a2ef561ac320c6dd803b4e64a913729ecc..7985f36588295d2f4d5ea4cd8e974f60a2899f3c
@@@ -344,7 -344,8 +344,8 @@@ static void call_accepted(SalOp *op)
                linphone_call_set_state(call,LinphoneCallConnected,"Connected");
                if (call->referer) linphone_core_notify_refer_state(lc,call->referer,call);
        }
 -      if (md && !sal_media_description_empty(md)){
 +      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){
        }else{
                /*send a bye*/
                ms_error("Incompatible SDP offer received in 200Ok, need to abort the call");
 -              linphone_core_abort_call(lc,call,_("Incompatible, check codecs..."));
 +              linphone_core_abort_call(lc,call,_("Incompatible, check codecs or security settings..."));
        }
  }
  
@@@ -425,6 -426,7 +426,7 @@@ static void call_accept_update(Linphone
                linphone_core_update_ice_from_remote_media_description(call,rmd);
                linphone_core_update_local_media_description_from_ice(call->localdesc,call->ice_session);
        }
+       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))
diff --combined coreapi/linphonecall.c
index 4465d6f8e429d791f053d0ca921329e0b5abce0f,285678f3ab4b8adb5ed7e206fbb9d48078b0c257..6ef8e0c553a4a188f4096827238b9d4279ca5f30
@@@ -1667,20 -1667,18 +1667,20 @@@ void linphone_call_update_crypto_parame
        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);
 +                      }
                }
        }
  
        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);
diff --combined coreapi/linphonecore.c
index ee0be33be22e2cfe0e59c2c9b17fcdad1d111b76,d38b681c10f7d89033e18914e565ba7e9e4282fa..28488e1dd1bc4cdf12b5bf58d5725877d5b60f14
@@@ -65,7 -65,6 +65,7 @@@ static void linphone_core_run_hooks(Lin
  static void linphone_core_free_hooks(LinphoneCore *lc);
  
  #include "enum.h"
 +
  const char *linphone_core_get_nat_address_resolved(LinphoneCore *lc);
  void linphone_core_get_local_ip(LinphoneCore *lc, const char *dest, char *result);
  static void toggle_video_preview(LinphoneCore *lc, bool_t val);
@@@ -567,7 -566,6 +567,7 @@@ static void sip_config_read(LinphoneCor
        sal_set_root_ca(lc->sal, lp_config_get_string(lc->config,"sip","root_ca", ROOT_CA_FILE));
  #endif
        linphone_core_verify_server_certificates(lc,lp_config_get_int(lc->config,"sip","verify_server_certs",TRUE));
 +      linphone_core_verify_server_cn(lc,lp_config_get_int(lc->config,"sip","verify_server_cn",TRUE));
        /*setting the dscp must be done before starting the transports, otherwise it is not taken into effect*/
        sal_set_dscp(lc->sal,linphone_core_get_sip_dscp(lc));
        /*start listening on ports*/
@@@ -2551,19 -2549,6 +2551,19 @@@ bool_t linphone_core_inc_invite_pending
        return FALSE;
  }
  
 +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++){
 +                      SalStreamDescription *sd=&md->streams[i];
 +                      if (sd->proto!=SalProtoRtpSavp){
 +                              return TRUE;
 +                      }
 +              }
 +      }
 +      return FALSE;
 +}
 +
  void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){
        char *barmesg;
        char *tmp;
        linphone_call_make_local_media_description(lc,call);
        sal_call_set_local_media_description(call->op,call->localdesc);
        md=sal_call_get_final_media_description(call->op);
 -      if (md && sal_media_description_empty(md)){
 -              sal_call_decline(call->op,SalReasonMedia,NULL);
 -              linphone_call_unref(call);
 -              return;
 +      if (md){
 +              if (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md)){
 +                      sal_call_decline(call->op,SalReasonMedia,NULL);
 +                      linphone_call_unref(call);
 +                      return;
 +              }
        }
  
        from_parsed=linphone_address_new(sal_op_get_from(call->op));
@@@ -2739,6 -2722,7 +2739,7 @@@ int linphone_core_start_accept_call_upd
                }
                linphone_core_update_local_media_description_from_ice(call->localdesc, call->ice_session);
        }
+       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);
   * @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
                         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
                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)) {
@@@ -2920,6 -2915,7 +2932,7 @@@ int linphone_core_accept_call_with_para
                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."));
@@@ -3702,13 -3698,6 +3715,13 @@@ void linphone_core_verify_server_certif
        sal_verify_server_certificates(lc->sal,yesno);
  }
  
 +/**
 + * Specify whether the tls server certificate common name must be verified when connecting to a SIP/TLS server.
 +**/
 +void linphone_core_verify_server_cn(LinphoneCore *lc, bool_t yesno){
 +      sal_verify_server_cn(lc->sal,yesno);
 +}
 +
  static void notify_end_of_ring(void *ud, MSFilter *f, unsigned int event, void *arg){
        LinphoneCore *lc=(LinphoneCore*)ud;
        lc->preview_finished=1;
diff --combined coreapi/private.h
index 29d31b7c6f62260c5534df2c34d238a17f11e7da,93baf7e44ac73128fdc69d5caec65a8e8180abe5..5c09974b7e7a9f666ffb8b4ed4def9ad6545fc2a
@@@ -148,6 -148,8 +148,8 @@@ struct _LinphoneCal
        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;
@@@ -286,6 -288,7 +288,7 @@@ void linphone_call_stop_media_streams(L
  void linphone_call_delete_ice_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);
@@@ -299,7 -302,6 +302,7 @@@ int linphone_core_start_update_call(Lin
  int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call);
  void linphone_core_start_refered_call(LinphoneCore *lc, LinphoneCall *call);
  void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call);
 +bool_t linphone_core_incompatible_security(LinphoneCore *lc, SalMediaDescription *md);
  extern SalCallbacks linphone_sal_callbacks;
  void linphone_proxy_config_set_error(LinphoneProxyConfig *cfg, LinphoneReason error);
  bool_t linphone_core_rtcp_enabled(const LinphoneCore *lc);