]> sjero.net Git - linphone/blobdiff - coreapi/linphonecore.c
Merge remote-tracking branch 'private/srtp'
[linphone] / coreapi / linphonecore.c
index 715d0f2c7da7b30731ee5058098edf4e069e8fed..c4b5dbb6e91ea720f2a5234a7d3716b7495ff6be 100644 (file)
@@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #include "private.h"
 
 #include <ortp/telephonyevents.h>
+#include <ortp/zrtp.h>
 #include "mediastreamer2/mediastream.h"
 #include "mediastreamer2/mseventqueue.h"
 #include "mediastreamer2/msvolume.h"
@@ -41,6 +42,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 /*#define UNSTANDART_GSM_11K 1*/
 
+#define ROOT_CA_FILE PACKAGE_DATA_DIR "/linphone/rootca.pem"
+
 static const char *liblinphone_version=LIBLINPHONE_VERSION;
 static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t curtime);
 static void linphone_core_run_hooks(LinphoneCore *lc);
@@ -385,6 +388,8 @@ static void sound_config_read(LinphoneCore *lc)
                MSSndCard *card=ms_alsa_card_new_custom(devid,devid);
                ms_snd_card_manager_add_card(ms_snd_card_manager_get(),card);
        }
+       tmp=lp_config_get_int(lc->config,"sound","alsa_forced_rate",-1);
+       if (tmp>0) ms_alsa_card_set_forced_sample_rate(tmp);
 #endif
        /* retrieve all sound devices */
        build_sound_devices_table(lc);
@@ -435,10 +440,10 @@ static void sound_config_read(LinphoneCore *lc)
        linphone_core_set_play_file(lc,lp_config_get_string(lc->config,"sound","hold_music",PACKAGE_SOUND_DIR "/" HOLD_MUSIC));
        check_sound_device(lc);
        lc->sound_conf.latency=0;
-#if !defined(TARGET_OS_IPHONE) && !defined(ANDROID)
+#ifndef __ios 
     tmp=TRUE;
 #else
-    tmp=FALSE;
+    tmp=FALSE; /* on iOS we have builtin echo cancellation.*/
 #endif
     tmp=lp_config_get_int(lc->config,"sound","echocancellation",tmp);
        linphone_core_enable_echo_cancellation(lc,tmp);
@@ -518,7 +523,11 @@ static void sip_config_read(LinphoneCore *lc)
                ms_free(contact);
        }
 
+#ifdef __linux
        sal_root_ca(lc->sal, lp_config_get_string(lc->config,"sip","root_ca", "/etc/ssl/certs"));
+#else
+       sal_root_ca(lc->sal, lp_config_get_string(lc->config,"sip","root_ca", ROOT_CA_FILE));
+#endif
        
        tmp=lp_config_get_int(lc->config,"sip","guess_hostname",1);
        linphone_core_set_guess_hostname(lc,tmp);
@@ -812,7 +821,11 @@ void linphone_core_enable_adaptive_rate_control(LinphoneCore *lc, bool_t enabled
  * See linphone_core_enable_adaptive_rate_control().
 **/
 bool_t linphone_core_adaptive_rate_control_enabled(const LinphoneCore *lc){
-       return lp_config_get_int(lc->config,"net","adaptive_rate_control",FALSE);
+       return lp_config_get_int(lc->config,"net","adaptive_rate_control",TRUE);
+}
+
+bool_t linphone_core_rtcp_enabled(const LinphoneCore *lc){
+       return lp_config_get_int(lc->config,"rtp","rtcp_enabled",TRUE);
 }
 
 /**
@@ -831,6 +844,7 @@ bool_t linphone_core_adaptive_rate_control_enabled(const LinphoneCore *lc){
  */
 void linphone_core_set_download_bandwidth(LinphoneCore *lc, int bw){
        lc->net_conf.download_bw=bw;
+       if (linphone_core_ready(lc)) lp_config_set_int(lc->config,"net","download_bw",bw);
 }
 
 /**
@@ -848,6 +862,7 @@ void linphone_core_set_download_bandwidth(LinphoneCore *lc, int bw){
  */
 void linphone_core_set_upload_bandwidth(LinphoneCore *lc, int bw){
        lc->net_conf.upload_bw=bw;
+       if (linphone_core_ready(lc)) lp_config_set_int(lc->config,"net","upload_bw",bw);
 }
 
 /**
@@ -965,6 +980,7 @@ void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const
 static void misc_config_read (LinphoneCore *lc) {
        LpConfig *config=lc->config;
     lc->max_call_logs=lp_config_get_int(config,"misc","history_max_size",15);
+    lc->max_calls=lp_config_get_int(config,"misc","max_calls",NB_MAX_CALLS);
 }
 
 static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vtable, const char *config_path,
@@ -1032,7 +1048,11 @@ static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vta
        linphone_core_assign_payload_type(lc,&payload_type_aal2_g726_24,-1,NULL);
        linphone_core_assign_payload_type(lc,&payload_type_aal2_g726_32,-1,NULL);
        linphone_core_assign_payload_type(lc,&payload_type_aal2_g726_40,-1,NULL);
-
+       linphone_core_assign_payload_type(lc,&payload_type_silk_nb,-1,NULL);
+       linphone_core_assign_payload_type(lc,&payload_type_silk_mb,-1,NULL);
+       linphone_core_assign_payload_type(lc,&payload_type_silk_wb,-1,NULL);
+       linphone_core_assign_payload_type(lc,&payload_type_silk_swb,-1,NULL);
+       
        ms_init();
        /* create a mediastreamer2 event queue and set it as global */
        /* This allows to run event's callback in linphone_core_iterate() */
@@ -1495,6 +1515,12 @@ int linphone_core_set_sip_transports(LinphoneCore *lc, const LCSipTransports * t
                return 0;
        memcpy(&lc->sip_conf.transports,tr,sizeof(*tr));
 
+       if (linphone_core_ready(lc)){
+               lp_config_set_int(lc->config,"sip","sip_port",tr->udp_port);
+               lp_config_set_int(lc->config,"sip","sip_tcp_port",tr->tcp_port);
+               lp_config_set_int(lc->config,"sip","sip_tls_port",tr->tls_port);
+       }
+
        if (lc->sal==NULL) return 0;
        return apply_transports(lc);
 }
@@ -2304,6 +2330,10 @@ int linphone_core_accept_call(LinphoneCore *lc, LinphoneCall *call)
                ms_message("ring stopped");
                lc->ringstream=NULL;
        }
+       if (call->ringing_beep){
+               linphone_core_stop_dtmf(lc);
+               call->ringing_beep=FALSE;
+       }
 
        linphone_core_get_default_proxy(lc,&cfg);
        dest_proxy=cfg;
@@ -2361,10 +2391,6 @@ static void terminate_call(LinphoneCore *lc, LinphoneCall *call){
                lc->ringstream=NULL;
        }
 
-       /*stop any dtmf tone still playing */
-       ms_message("test");
-       linphone_core_stop_dtmf(lc);
-
        linphone_call_stop_media_streams(call);
        if (lc->vtable.display_status!=NULL)
                lc->vtable.display_status(lc,_("Call ended") );
@@ -2548,8 +2574,10 @@ int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *the_call)
                linphone_core_preempt_sound_resources(lc);
                ms_message("Resuming call %p",call);
        }
+       update_local_media_description(lc,the_call,&call->localdesc);
+       sal_call_set_local_media_description(call->op,call->localdesc);
        sal_media_description_set_dir(call->localdesc,SalStreamSendRecv);
-       if (call->params.in_conference) subject="Resuming conference";
+       if (call->params.in_conference && !call->current_params.in_conference) subject="Conference";
        if(sal_call_update(call->op,subject) != 0){
                return -1;
        }
@@ -3038,23 +3066,34 @@ bool_t linphone_core_echo_limiter_enabled(const LinphoneCore *lc){
 **/
 void linphone_core_mute_mic(LinphoneCore *lc, bool_t val){
        LinphoneCall *call=linphone_core_get_current_call(lc);
-       if (call==NULL){
+       AudioStream *st=NULL;
+       if (linphone_core_is_in_conference(lc)){
+               lc->conf_ctx.local_muted=val;
+               st=lc->conf_ctx.local_participant;
+       }else if (call==NULL){
                ms_warning("linphone_core_mute_mic(): No current call !");
                return;
+       }else{
+               st=call->audiostream;
+               call->audio_muted=val;
        }
-       if (call->audiostream!=NULL){
-               audio_stream_set_mic_gain(call->audiostream,
+       if (st!=NULL){
+               audio_stream_set_mic_gain(st,
                        (val==TRUE) ? 0 : lp_config_get_float(lc->config,"sound","mic_gain",1));
                if ( linphone_core_get_rtp_no_xmit_on_audio_mute(lc) ){
-                       audio_stream_mute_rtp(call->audiostream,val);
+                       audio_stream_mute_rtp(st,val);
                }
-               call->audio_muted=val;
+               
        }
 }
-
+/**
+ * Returns whether microphone is muted.
+**/
 bool_t linphone_core_is_mic_muted(LinphoneCore *lc) {
        LinphoneCall *call=linphone_core_get_current_call(lc);
-       if (call==NULL){
+       if (linphone_core_is_in_conference(lc)){
+               return lc->conf_ctx.local_muted;
+       }else if (call==NULL){
                ms_warning("linphone_core_is_mic_muted(): No current call !");
                return FALSE;
        }
@@ -3676,11 +3715,14 @@ void linphone_core_set_record_file(LinphoneCore *lc, const char *file){
 
 static MSFilter *get_dtmf_gen(LinphoneCore *lc){
        LinphoneCall *call=linphone_core_get_current_call (lc);
+       AudioStream *stream=NULL;
        if (call){
-               AudioStream *stream=call->audiostream;
-               if (stream){
-                       return stream->dtmfgen;
-               }
+               stream=call->audiostream;
+       }else if (linphone_core_is_in_conference(lc)){
+               stream=lc->conf_ctx.local_participant;
+       }
+       if (stream){
+               return stream->dtmfgen;
        }
        if (lc->ringstream==NULL){
                float amp=0.1;
@@ -3729,7 +3771,7 @@ void linphone_core_play_tone(LinphoneCore *lc){
        def.duration=300;
        def.frequency=500;
        def.amplitude=1;
-       def.interval=800;
+       def.interval=2000;
        ms_filter_call_method(f, MS_DTMF_GEN_PLAY_CUSTOM,&def);
 }
 
@@ -3835,8 +3877,6 @@ int linphone_core_get_current_call_stats(LinphoneCore *lc, rtp_stats_t *local, r
 void net_config_uninit(LinphoneCore *lc)
 {
        net_config_t *config=&lc->net_conf;
-       lp_config_set_int(lc->config,"net","download_bw",config->download_bw);
-       lp_config_set_int(lc->config,"net","upload_bw",config->upload_bw);
 
        if (config->stun_server!=NULL){
                lp_config_set_string(lc->config,"net","stun_server",config->stun_server);
@@ -3859,9 +3899,7 @@ void sip_config_uninit(LinphoneCore *lc)
        MSList *elem;
        int i;
        sip_config_t *config=&lc->sip_conf;
-       lp_config_set_int(lc->config,"sip","sip_port",config->transports.udp_port);
-       lp_config_set_int(lc->config,"sip","sip_tcp_port",config->transports.tcp_port);
-       lp_config_set_int(lc->config,"sip","sip_tls_port",config->transports.tls_port);
+       
        lp_config_set_int(lc->config,"sip","guess_hostname",config->guess_hostname);
        lp_config_set_string(lc->config,"sip","contact",config->contact);
        lp_config_set_int(lc->config,"sip","inc_timeout",config->inc_timeout);
@@ -3871,15 +3909,12 @@ void sip_config_uninit(LinphoneCore *lc)
        lp_config_set_int(lc->config,"sip","register_only_when_network_is_up",config->register_only_when_network_is_up);
 
 
-       lp_config_set_int(lc->config,"sip","default_proxy",linphone_core_get_default_proxy(lc,NULL));
+       
 
        for(elem=config->proxies,i=0;elem!=NULL;elem=ms_list_next(elem),i++){
                LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)(elem->data);
-               linphone_proxy_config_write_to_config_file(lc->config,cfg,i);
                linphone_proxy_config_edit(cfg);        /* to unregister */
        }
-       /*to ensure remove configs are erased:*/
-       linphone_proxy_config_write_to_config_file(lc->config,NULL,i);
 
        for (i=0;i<20;i++){
                sal_iterate(lc->sal);
@@ -3896,11 +3931,6 @@ void sip_config_uninit(LinphoneCore *lc)
 
        linphone_proxy_config_write_to_config_file(lc->config,NULL,i);  /*mark the end */
 
-       for(elem=lc->auth_info,i=0;elem!=NULL;elem=ms_list_next(elem),i++){
-               LinphoneAuthInfo *ai=(LinphoneAuthInfo*)(elem->data);
-               linphone_auth_info_write_config(lc->config,ai,i);
-       }
-       linphone_auth_info_write_config(lc->config,NULL,i); /* mark the end */
        ms_list_for_each(lc->auth_info,(void (*)(void*))linphone_auth_info_destroy);
        ms_list_free(lc->auth_info);
        lc->auth_info=NULL;
@@ -4125,9 +4155,9 @@ int linphone_core_get_calls_nb(const LinphoneCore *lc){
 **/
 bool_t linphone_core_can_we_add_call(LinphoneCore *lc)
 {
-       if(linphone_core_get_calls_nb(lc) < NB_MAX_CALLS)
+       if(linphone_core_get_calls_nb(lc) < lc->max_calls)
                return TRUE;
-       ms_error("Maximum amount of simultaneous calls reached !");
+       ms_message("Maximum amount of simultaneous calls reached !");
        return FALSE;
 }
 
@@ -4283,6 +4313,11 @@ void linphone_core_stop_dtmf_stream(LinphoneCore* lc) {
        lc->ringstream=NULL;
 }
 
+int linphone_core_get_max_calls(LinphoneCore *lc) {
+       return lc->max_calls;
+}
+
+
 typedef struct Hook{
        LinphoneCoreIterateHook fun;
        void *data;
@@ -4333,7 +4368,6 @@ void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){
        lc->zrtp_secrets_cache=file ? ms_strdup(file) : NULL;
 }
 
-//                             if (stringUri.equals(call.getRemoteAddress().asStringUriOnly())) {
 const LinphoneCall* linphone_core_find_call_from_uri(LinphoneCore *lc, const char *uri) {
        if (uri == NULL) return NULL;
        MSList *calls=lc->calls;
@@ -4352,10 +4386,54 @@ const LinphoneCall* linphone_core_find_call_from_uri(LinphoneCore *lc, const cha
        return NULL;
 }
 
+
+/**
+ * Check if a call will need the sound resources.
+ *
+ * @ingroup call_control
+ * @param lc The LinphoneCore
+**/
+bool_t linphone_core_sound_resources_locked(LinphoneCore *lc){
+       MSList *calls=lc->calls;
+       while(calls) {
+               LinphoneCall *c=(LinphoneCall*)calls->data;
+               calls=calls->next;
+               switch (c->state) {
+                       case LinphoneCallOutgoingInit:
+                       case LinphoneCallOutgoingProgress:
+                       case LinphoneCallOutgoingRinging:
+                       case LinphoneCallOutgoingEarlyMedia:
+                       case LinphoneCallConnected:
+                       case LinphoneCallRefered:
+                       case LinphoneCallIncomingEarlyMedia:
+                       case LinphoneCallUpdated:
+                               return TRUE;
+                       default:
+                               break;
+               }
+       }
+       return FALSE;
+}
+
 void linphone_core_set_srtp_enabled(LinphoneCore *lc, bool_t enabled) {
        lp_config_set_int(lc->config,"sip","srtp",(int)enabled);
 }
 
+/**
+ * Returns whether a media encryption scheme is supported by the LinphoneCore engine
+**/
+bool_t linphone_core_media_encryption_supported(const LinphoneCore *lc, LinphoneMediaEncryption menc){
+       switch(menc){
+               case LinphoneMediaEncryptionSRTP:
+                       return ortp_srtp_supported();
+               case LinphoneMediaEncryptionZRTP:
+                       return ortp_zrtp_available();
+               case LinphoneMediaEncryptionNone:
+                       return TRUE;
+       }
+       return FALSE;
+}
+
 void linphone_core_set_media_encryption(LinphoneCore *lc, enum LinphoneMediaEncryption menc) {
        if (menc == LinphoneMediaEncryptionSRTP)
                lp_config_set_string(lc->config,"sip","media_encryption","srtp");
@@ -4365,7 +4443,7 @@ void linphone_core_set_media_encryption(LinphoneCore *lc, enum LinphoneMediaEncr
                lp_config_set_string(lc->config,"sip","media_encryption","none");
 }
 
-enum LinphoneMediaEncryption linphone_core_get_media_encryption(LinphoneCore *lc) {
+LinphoneMediaEncryption linphone_core_get_media_encryption(LinphoneCore *lc) {
        const char* menc = lp_config_get_string(lc->config, "sip", "media_encryption", NULL);
        
        if (menc == NULL)
@@ -4391,3 +4469,4 @@ void linphone_core_init_default_params(LinphoneCore*lc, LinphoneCallParams *para
        params->media_encryption=linphone_core_get_media_encryption(lc);        
        params->in_conference=FALSE;
 }
+