#include "mediastreamer2/mediastream.h"
#include "mediastreamer2/msvolume.h"
#include "mediastreamer2/msequalizer.h"
-#include <eXosip2/eXosip.h>
-#include "sdphandler.h"
#include <ortp/telephonyevents.h>
-#include "exevents.h"
#ifdef INET6
/* same for remote ring (ringback)*/
#define REMOTE_RING "ringback.wav"
-
-sdp_handler_t linphone_sdphandler={
- linphone_accept_audio_offer, /*from remote sdp */
- linphone_accept_video_offer, /*from remote sdp */
- linphone_set_audio_offer, /*to local sdp */
- linphone_set_video_offer, /*to local sdp */
- linphone_read_audio_answer, /*from incoming answer */
- linphone_read_video_answer /*from incoming answer */
-};
+extern SalCallbacks linphone_sal_callbacks;
void lc_callback_obj_init(LCCallbackObj *obj,LinphoneCoreCbFunc func,void* ud)
{
return 0;
}
-static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, LinphoneAddress *to){
+
+static MSList *make_codec_list(const MSList *codecs){
+ MSList *l=NULL;
+ const MSList *it;
+ for(it=codecs;it!=NULL;it=it->next){
+ PayloadType *pt=(PayloadType*)it->data;
+ if (pt->flags & PAYLOAD_TYPE_ENABLED){
+ l=ms_list_append(l,payload_type_clone(pt));
+ }
+ }
+ return l;
+}
+
+static SalMediaDescription *create_local_media_description(LinphoneCore *lc,
+ const char *localip, const char *username){
+ MSList *l;
+ PayloadType *pt;
+ SalMediaDescription *md=sal_media_description_new();
+ md->nstreams=1;
+ strncpy(md->addr,localip,sizeof(md->addr));
+ strncpy(md->username,username,sizeof(md->username));
+ /*set audio capabilities */
+ strncpy(md->streams[0].addr,localip,sizeof(md->streams[0].addr));
+ md->streams[0].port=linphone_core_get_audio_port(lc);
+ md->streams[0].proto=SalProtoRtpAvp;
+ md->streams[0].type=SalAudio;
+ l=make_codec_list(lc->codecs_conf.audio_codecs);
+ pt=payload_type_clone(rtp_profile_get_payload_from_mime(&av_profile,"telephone-event"));
+ l=ms_list_append(l,pt);
+ md->streams[0].payloads=l;
+
+ if (lc->dw_audio_bw>0)
+ md->streams[0].bandwidth=lc->dw_audio_bw;
+
+ if (linphone_core_video_enabled (lc)){
+ md->nstreams++;
+ md->streams[1].port=linphone_core_get_video_port(lc);
+ md->streams[1].proto=SalProtoRtpAvp;
+ md->streams[1].type=SalVideo;
+ l=make_codec_list(lc->codecs_conf.video_codecs);
+ md->streams[1].payloads=l;
+ if (lc->dw_video_bw)
+ md->streams[1].bandwidth=lc->dw_video_bw;
+ }
+ return md;
+}
+
+static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, LinphoneAddress *to){
call->state=LCStateInit;
call->start_time=time(NULL);
call->media_start_time=0;
linphone_core_notify_all_friends(call->core,LINPHONE_STATUS_ONTHEPHONE);
if (linphone_core_get_firewall_policy(call->core)==LINPHONE_POLICY_USE_STUN)
linphone_core_run_stun_tests(call->core,call);
- call->profile=rtp_profile_new("Call RTP profile");
-}
-
-void linphone_call_init_media_params(LinphoneCall *call){
- memset(&call->audio_params,0,sizeof(call->audio_params));
- memset(&call->video_params,0,sizeof(call->video_params));
}
static void discover_mtu(LinphoneCore *lc, const char *remote){
{
LinphoneCall *call=ms_new0(LinphoneCall,1);
call->dir=LinphoneCallOutgoing;
- call->cid=-1;
- call->did=-1;
- call->tid=-1;
+ call->op=sal_op_new(lc->sal);
+ sal_op_set_user_pointer(call->op,call);
call->core=lc;
linphone_core_get_local_ip(lc,linphone_address_get_domain(to),call->localip);
+ call->localdesc=create_local_media_description (lc,call->localip,
+ linphone_address_get_username(from));
linphone_call_init_common(call,from,to);
- call->sdpctx=sdp_handler_create_context(&linphone_sdphandler,
- call->audio_params.natd_port>0 ? call->audio_params.natd_addr : call->localip,
- linphone_address_get_username (from),NULL);
- sdp_context_set_user_pointer(call->sdpctx,(void*)call);
discover_mtu(lc,linphone_address_get_domain (to));
return call;
}
-
-LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, eXosip_event_t *ev){
+LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, SalOp *op){
LinphoneCall *call=ms_new0(LinphoneCall,1);
LinphoneAddress *me=linphone_core_get_primary_contact_parsed(lc);
- osip_header_t *h=NULL;
call->dir=LinphoneCallIncoming;
- call->cid=ev->cid;
- call->did=ev->did;
- call->tid=ev->tid;
+ sal_op_set_user_pointer(op,call);
+ call->op=op;
call->core=lc;
linphone_address_clean(from);
-
linphone_core_get_local_ip(lc,linphone_address_get_domain(from),call->localip);
+ call->localdesc=create_local_media_description (lc,call->localip,
+ linphone_address_get_username(me));
linphone_call_init_common(call, from, to);
- call->sdpctx=sdp_handler_create_context(&linphone_sdphandler,
- call->audio_params.natd_port>0 ? call->audio_params.natd_addr : call->localip,
- linphone_address_get_username (me),NULL);
- sdp_context_set_user_pointer(call->sdpctx,(void*)call);
discover_mtu(lc,linphone_address_get_domain(from));
linphone_address_destroy(me);
- osip_message_header_get_byname(ev->request,"Session-expires",0,&h);
- if (h) call->supports_session_timers=TRUE;
return call;
}
linphone_core_notify_all_friends(obj->core,obj->core->prev_mode);
linphone_call_log_completed(obj->log,obj);
linphone_core_update_allocated_audio_bandwidth(obj->core);
- if (obj->profile!=NULL) rtp_profile_destroy(obj->profile);
- if (obj->sdpctx!=NULL) sdp_context_free(obj->sdpctx);
+ if (obj->op!=NULL) sal_op_release(obj->op);
+ if (obj->resultdesc!=NULL) sal_media_description_unref(obj->resultdesc);
+ if (obj->localdesc!=NULL) sal_media_description_unref(obj->localdesc);
ms_free(obj);
}
return call->dir==LinphoneCallIncoming ? call->log->from : call->log->to;
}
-void _osip_trace_func(char *fi, int li, osip_trace_level_t level, char *chfr, va_list ap){
- int ortp_level=ORTP_DEBUG;
- switch(level){
- case OSIP_INFO1:
- case OSIP_INFO2:
- case OSIP_INFO3:
- case OSIP_INFO4:
- ortp_level=ORTP_MESSAGE;
- break;
- case OSIP_WARNING:
- ortp_level=ORTP_WARNING;
- break;
- case OSIP_ERROR:
- case OSIP_BUG:
- ortp_level=ORTP_ERROR;
- break;
- case OSIP_FATAL:
- ortp_level=ORTP_FATAL;
- break;
- case END_TRACE_LEVEL:
- break;
- }
- if (ortp_log_level_enabled(level)){
- int len=strlen(chfr);
- char *chfrdup=ortp_strdup(chfr);
- /*need to remove endline*/
- if (len>1){
- if (chfrdup[len-1]=='\n')
- chfrdup[len-1]='\0';
- if (chfrdup[len-2]=='\r')
- chfrdup[len-2]='\0';
- }
- ortp_logv(ortp_level,chfrdup,ap);
- ortp_free(chfrdup);
- }
-}
-
/**
* Enable logs in supplied FILE*.
*
if (file==NULL) file=stdout;
ortp_set_log_file(file);
ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL);
- osip_trace_initialize_func (OSIP_INFO4,&_osip_trace_func);
}
/**
**/
void linphone_core_enable_logs_with_cb(OrtpLogFunc logfunc){
ortp_set_log_level_mask(ORTP_MESSAGE|ORTP_WARNING|ORTP_ERROR|ORTP_FATAL);
- osip_trace_initialize_func (OSIP_INFO4,&_osip_trace_func);
ortp_set_log_handler(logfunc);
}
* @ingroup misc
**/
void linphone_core_disable_logs(){
- int tl;
- for (tl=0;tl<=OSIP_INFO4;tl++) osip_trace_disable_level(tl);
ortp_set_log_level_mask(ORTP_ERROR|ORTP_FATAL);
}
linphone_core_set_nortp_timeout(lc,nortp_timeout);
}
+static PayloadType * find_payload(RtpProfile *prof, const char *mime_type, int clock_rate, const char *recv_fmtp){
+ PayloadType *candidate=NULL;
+ int i;
+ PayloadType *it;
+ for(i=0;i<127;++i){
+ it=rtp_profile_get_payload(prof,i);
+ if (it!=NULL && strcasecmp(mime_type,it->mime_type)==0
+ && (clock_rate==it->clock_rate || clock_rate<=0) ){
+ if ( (recv_fmtp && it->recv_fmtp && strcasecmp(recv_fmtp,it->recv_fmtp)==0) ||
+ (recv_fmtp==NULL && it->recv_fmtp==NULL) ){
+ /*exact match*/
+ return it;
+ }else candidate=it;
+ }
+ }
+ return candidate;
+}
-static PayloadType * get_codec(LpConfig *config, char* type,int index){
+static bool_t get_codec(LpConfig *config, char* type, int index, PayloadType **ret){
char codeckey[50];
const char *mime,*fmtp;
int rate,enabled;
PayloadType *pt;
+ *ret=NULL;
snprintf(codeckey,50,"%s_%i",type,index);
mime=lp_config_get_string(config,codeckey,"mime",NULL);
- if (mime==NULL || strlen(mime)==0 ) return NULL;
-
- pt=payload_type_new();
- pt->mime_type=ms_strdup(mime);
+ if (mime==NULL || strlen(mime)==0 ) return FALSE;
rate=lp_config_get_int(config,codeckey,"rate",8000);
- pt->clock_rate=rate;
fmtp=lp_config_get_string(config,codeckey,"recv_fmtp",NULL);
- if (fmtp) pt->recv_fmtp=ms_strdup(fmtp);
enabled=lp_config_get_int(config,codeckey,"enabled",1);
- if (enabled ) pt->flags|=PAYLOAD_TYPE_ENABLED;
+ pt=find_payload(&av_profile,mime,rate,fmtp);
+ if (pt && enabled ) pt->flags|=PAYLOAD_TYPE_ENABLED;
//ms_message("Found codec %s/%i",pt->mime_type,pt->clock_rate);
- return pt;
+ if (pt==NULL) ms_warning("Ignoring codec config %s/%i with fmtp=%s because unsupported",
+ mime,rate,fmtp ? fmtp : "");
+ *ret=pt;
+ return TRUE;
+}
+
+static const char *codec_pref_order[]={
+ "speex",
+ "gsm",
+ "pcmu",
+ "pcma",
+ "H264",
+ "MP4V-ES",
+ "theora",
+ "H263-1998",
+ "H263",
+ NULL,
+};
+
+static int find_codec_rank(const char *mime){
+ int i;
+ for(i=0;codec_pref_order[i]!=NULL;++i){
+ if (strcasecmp(codec_pref_order[i],mime)==0)
+ break;
+ }
+ return i;
+}
+
+static int codec_compare(const PayloadType *a, const PayloadType *b){
+ int ra,rb;
+ ra=find_codec_rank(a->mime_type);
+ rb=find_codec_rank(b->mime_type);
+ if (ra>rb) return 1;
+ if (ra<rb) return -1;
+ return 0;
+}
+
+static MSList *add_missing_codecs(SalStreamType mtype, MSList *l){
+ int i;
+ for(i=0;i<127;++i){
+ PayloadType *pt=rtp_profile_get_payload(&av_profile,i);
+ if (pt){
+ if (mtype==SalVideo && pt->type!=PAYLOAD_VIDEO)
+ pt=NULL;
+ else if (mtype==SalAudio && (pt->type!=PAYLOAD_AUDIO_PACKETIZED
+ && pt->type!=PAYLOAD_AUDIO_CONTINUOUS)){
+ pt=NULL;
+ }
+ if (pt && ms_filter_codec_supported(pt->mime_type)){
+ if (ms_list_find(l,pt)==NULL){
+ payload_type_set_flag(pt,PAYLOAD_TYPE_ENABLED);
+ ms_message("Adding new codec %s/%i with fmtp %s",
+ pt->mime_type,pt->clock_rate,pt->recv_fmtp ? pt->recv_fmtp : "");
+ l=ms_list_insert_sorted(l,pt,(int (*)(const void *, const void *))codec_compare);
+ }
+ }
+ }
+ }
+ return l;
}
static void codecs_config_read(LinphoneCore *lc)
PayloadType *pt;
MSList *audio_codecs=NULL;
MSList *video_codecs=NULL;
- for (i=0;;i++){
- pt=get_codec(lc->config,"audio_codec",i);
- if (pt==NULL) break;
- audio_codecs=ms_list_append(audio_codecs,(void *)pt);
+ for (i=0;get_codec(lc->config,"audio_codec",i,&pt);i++){
+ if (pt){
+ if (!ms_filter_codec_supported(pt->mime_type)){
+ ms_warning("Codec %s is not supported by mediastreamer2, removed.",pt->mime_type);
+ }else audio_codecs=ms_list_append(audio_codecs,pt);
+ }
}
- for (i=0;;i++){
- pt=get_codec(lc->config,"video_codec",i);
- if (pt==NULL) break;
- video_codecs=ms_list_append(video_codecs,(void *)pt);
+ audio_codecs=add_missing_codecs(SalAudio,audio_codecs);
+ for (i=0;get_codec(lc->config,"video_codec",i,&pt);i++){
+ if (pt){
+ if (!ms_filter_codec_supported(pt->mime_type)){
+ ms_warning("Codec %s is not supported by mediastreamer2, removed.",pt->mime_type);
+ }else video_codecs=ms_list_append(video_codecs,(void *)pt);
+ }
}
+ video_codecs=add_missing_codecs(SalVideo,video_codecs);
linphone_core_set_audio_codecs(lc,audio_codecs);
linphone_core_set_video_codecs(lc,video_codecs);
- linphone_core_setup_local_rtp_profile(lc);
+ linphone_core_update_allocated_audio_bandwidth(lc);
}
-static void video_config_read(LinphoneCore *lc)
-{
+static void video_config_read(LinphoneCore *lc){
int capture, display, self_view;
int enabled;
const char *str;
static void linphone_core_assign_payload_type(PayloadType *const_pt, int number, const char *recv_fmtp){
PayloadType *pt;
pt=payload_type_clone(const_pt);
+ payload_type_set_number(pt,number);
if (recv_fmtp!=NULL) payload_type_set_recv_fmtp(pt,recv_fmtp);
rtp_profile_set_payload(&av_profile,number,pt);
linphone_payload_types=ms_list_append(linphone_payload_types,pt);
gstate_new_state(lc, GSTATE_POWER_STARTUP, NULL);
ortp_init();
+ linphone_core_assign_payload_type(&payload_type_pcmu8000,0,NULL);
+ linphone_core_assign_payload_type(&payload_type_gsm,3,NULL);
+ linphone_core_assign_payload_type(&payload_type_pcma8000,8,NULL);
linphone_core_assign_payload_type(&payload_type_lpc1015,115,NULL);
linphone_core_assign_payload_type(&payload_type_speex_nb,110,"vbr=on");
linphone_core_assign_payload_type(&payload_type_speex_wb,111,"vbr=on");
linphone_core_assign_payload_type(&payload_type_speex_uwb,112,"vbr=on");
- linphone_core_assign_payload_type(&payload_type_telephone_event,101,NULL);
+ linphone_core_assign_payload_type(&payload_type_telephone_event,101,"0-11");
linphone_core_assign_payload_type(&payload_type_ilbc,113,"mode=30");
#ifdef ENABLE_NONSTANDARD_GSM
if (factory_config_path)
lp_config_read_file(lc->config,factory_config_path);
-#ifdef VINCENT_MAURY_RSVP
- /* default qos parameters : rsvp on, rpc off */
- lc->rsvp_enable = 1;
- lc->rpc_enable = 0;
-#endif
+ lc->sal=sal_init();
+ sal_set_user_pointer(lc->sal,lc);
+ sal_set_callbacks(lc->sal,&linphone_sal_callbacks);
+ if (lp_config_get_int(lc->config,"sip","use_session_timers",0)==1){
+ sal_use_session_timers(lc->sal,200);
+ }
sip_setup_register_all();
sound_config_read(lc);
net_config_read(lc);
lc->presence_mode=LINPHONE_STATUS_ONLINE;
lc->max_call_logs=15;
ui_config_read(lc);
- ms_mutex_init(&lc->lock,NULL);
lc->vtable.display_status(lc,_("Ready"));
gstate_new_state(lc, GSTATE_POWER_ON, NULL);
lc->ready=TRUE;
**/
int linphone_core_set_primary_contact(LinphoneCore *lc, const char *contact)
{
- osip_from_t *ctt=NULL;
- osip_from_init(&ctt);
- if (osip_from_parse(ctt,contact)!=0){
+ LinphoneAddress *ctt;
+
+ if ((ctt=linphone_address_new(contact))==0) {
ms_error("Bad contact url: %s",contact);
- osip_from_free(ctt);
return -1;
}
if (lc->sip_conf.contact!=NULL) ms_free(lc->sip_conf.contact);
ms_free(lc->sip_conf.guessed_contact);
lc->sip_conf.guessed_contact=NULL;
}
- osip_from_free(ctt);
+ linphone_address_destroy(ctt);
return 0;
}
if (dest==NULL) dest="87.98.157.38"; /*a public IP address*/
if (linphone_core_get_local_ip_for(dest,result)==0)
return;
- /*else fallback to exosip routine that will attempt to find the most realistic interface */
- if (eXosip_guess_localip(lc->sip_conf.ipv6_enabled ? AF_INET6 : AF_INET,result,LINPHONE_IPADDR_SIZE)<0){
- /*default to something */
- strncpy(result,lc->sip_conf.ipv6_enabled ? "::1" : "127.0.0.1",LINPHONE_IPADDR_SIZE);
- ms_error("Could not find default routable ip address !");
- }
+ /*else fallback to SAL routine that will attempt to find the most realistic interface */
+ sal_get_default_local_ip(lc->sal,lc->sip_conf.ipv6_enabled ? AF_INET6 : AF_INET,result,LINPHONE_IPADDR_SIZE);
}
/**
*
* @ingroup proxies
**/
-const char *linphone_core_get_primary_contact(LinphoneCore *lc)
-{
+const char *linphone_core_get_primary_contact(LinphoneCore *lc){
char *identity;
char tmp[LINPHONE_IPADDR_SIZE];
+
if (lc->sip_conf.guess_hostname){
if (lc->sip_conf.guessed_contact==NULL || lc->sip_conf.loopback_only){
char *guessed=NULL;
- osip_from_t *url;
+ LinphoneAddress *url;
if (lc->sip_conf.guessed_contact!=NULL){
ms_free(lc->sip_conf.guessed_contact);
lc->sip_conf.guessed_contact=NULL;
}
-
- osip_from_init(&url);
- if (osip_from_parse(url,lc->sip_conf.contact)==0){
-
- }else ms_error("Could not parse identity contact !");
+ url=linphone_address_new(lc->sip_conf.contact);
+ if (!url){
+ ms_error("Could not parse identity contact !");
+ url=linphone_address_new("sip:unknown@unkwownhost");
+ }
linphone_core_get_local_ip(lc, NULL, tmp);
if (strcmp(tmp,"127.0.0.1")==0 || strcmp(tmp,"::1")==0 ){
ms_warning("Local loopback network only !");
lc->sip_conf.loopback_only=TRUE;
}else lc->sip_conf.loopback_only=FALSE;
- osip_free(url->url->host);
- url->url->host=osip_strdup(tmp);
- if (url->url->port!=NULL){
- osip_free(url->url->port);
- url->url->port=NULL;
- }
- if (lc->sip_conf.sip_port!=5060){
- url->url->port=ortp_strdup_printf("%i",lc->sip_conf.sip_port);
- }
- osip_from_to_str(url,&guessed);
+ linphone_address_set_domain(url,tmp);
+ linphone_address_set_port_int(url,lc->sip_conf.sip_port);
+ guessed=linphone_address_as_string(url);
lc->sip_conf.guessed_contact=guessed;
-
- osip_from_free(url);
-
+ linphone_address_destroy(url);
}
identity=lc->sip_conf.guessed_contact;
}else{
static char _ua_name[64]="Linphone";
static char _ua_version[64]=LINPHONE_VERSION;
-static void apply_user_agent(void){
+#ifdef HAVE_EXOSIP_GET_VERSION
+extern const char *eXosip_get_version();
+#endif
+
+static void apply_user_agent(LinphoneCore *lc){
char ua_string[256];
snprintf(ua_string,sizeof(ua_string),"%s/%s (eXosip2/%s)",_ua_name,_ua_version,
#ifdef HAVE_EXOSIP_GET_VERSION
"unknown"
#endif
);
- eXosip_set_user_agent(ua_string);
+ if (lc->sal) sal_set_user_agent(lc->sal,ua_string);
}
/**
int err=0;
if (port==lc->sip_conf.sip_port) return;
lc->sip_conf.sip_port=port;
- if (exosip_running) eXosip_quit();
- eXosip_init();
- err=0;
- eXosip_set_option(13,&err); /*13=EXOSIP_OPT_SRV_WITH_NAPTR, as it is an enum value, we can't use it unless we are sure of the
- version of eXosip, which is not the case*/
- eXosip_enable_ipv6(lc->sip_conf.ipv6_enabled);
+
+ if (lc->sal==NULL) return;
+
if (lc->sip_conf.ipv6_enabled)
anyaddr="::0";
else
anyaddr="0.0.0.0";
- err=eXosip_listen_addr (IPPROTO_UDP, anyaddr, port,
- lc->sip_conf.ipv6_enabled ? PF_INET6 : PF_INET, 0);
+ err=sal_listen_port (lc->sal,anyaddr,port, SalTransportDatagram,FALSE);
if (err<0){
char *msg=ortp_strdup_printf("UDP port %i seems already in use ! Cannot initialize.",port);
ms_warning(msg);
ms_free(msg);
return;
}
-#ifdef VINCENT_MAURY_RSVP
- /* tell exosip the qos settings according to default linphone parameters */
- eXosip_set_rsvp_mode (lc->rsvp_enable);
- eXosip_set_rpc_mode (lc->rpc_enable);
-#endif
- apply_user_agent();
- exosip_running=TRUE;
+ apply_user_agent(lc);
}
/**
void linphone_core_enable_ipv6(LinphoneCore *lc, bool_t val){
if (lc->sip_conf.ipv6_enabled!=val){
lc->sip_conf.ipv6_enabled=val;
- if (exosip_running){
+ if (lc->sal){
/* we need to restart eXosip */
linphone_core_set_sip_port(lc, lc->sip_conf.sip_port);
}
char result[LINPHONE_IPADDR_SIZE];
/* only do the network up checking every five seconds */
if (last_check==0 || (curtime-last_check)>=5){
- if (eXosip_guess_localip(lc->sip_conf.ipv6_enabled ? AF_INET6 : AF_INET,result,LINPHONE_IPADDR_SIZE)==0){
- if (strcmp(result,"::1")!=0 && strcmp(result,"127.0.0.1")!=0){
- last_status=TRUE;
- ms_message("Network is up, registering now (%s)",result);
- }else last_status=FALSE;
- }
+ sal_get_default_local_ip(lc->sal,
+ lc->sip_conf.ipv6_enabled ? AF_INET6 : AF_INET,
+ result,LINPHONE_IPADDR_SIZE);
+ if (strcmp(result,"::1")!=0 && strcmp(result,"127.0.0.1")!=0){
+ last_status=TRUE;
+ ms_message("Network is up, registering now (%s)",result);
+ }else last_status=FALSE;
last_check=curtime;
}
doit=last_status;
}
static void assign_buddy_info(LinphoneCore *lc, BuddyInfo *info){
- LinphoneFriend *lf=linphone_core_get_friend_by_uri(lc,info->sip_uri);
+ LinphoneFriend *lf=linphone_core_get_friend_by_address(lc,info->sip_uri);
if (lf!=NULL){
lf->info=info;
ms_message("%s has a BuddyInfo assigned with image %p",info->sip_uri, info->image_data);
* other liblinphone methods. In not the case make sure all liblinphone calls are
* serialized with a mutex.
**/
-void linphone_core_iterate(LinphoneCore *lc)
-{
- eXosip_event_t *ev;
- bool_t disconnected=FALSE;
+void linphone_core_iterate(LinphoneCore *lc){
int disconnect_timeout = linphone_core_get_nortp_timeout(lc);
time_t curtime=time(NULL);
int elapsed;
bool_t one_second_elapsed=FALSE;
+ bool_t disconnected=FALSE;
if (curtime-lc->prevtime>=1){
lc->prevtime=curtime;
lc_callback_obj_invoke(&lc->preview_finished_cb,lc);
}
- if (exosip_running){
- while((ev=eXosip_event_wait(0,0))!=NULL){
- linphone_core_process_event(lc,ev);
- }
- if (lc->automatic_action==0) {
- eXosip_lock();
- eXosip_automatic_action();
- eXosip_unlock();
- }
- }
-
+ sal_iterate(lc->sal);
proxy_update(lc,curtime);
if (lc->call!=NULL){
}
-bool_t linphone_core_is_in_main_thread(LinphoneCore *lc){
- return TRUE;
-}
-
-static char *guess_route_if_any(LinphoneCore *lc, osip_to_t *parsed_url){
- const MSList *elem=linphone_core_get_proxy_config_list(lc);
- for(;elem!=NULL;elem=elem->next){
- LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data;
- char prx[256];
- if (cfg->ssctx && sip_setup_context_get_proxy(cfg->ssctx,parsed_url->url->host,prx,sizeof(prx))==0){
- ms_message("We have a proxy for domain %s",parsed_url->url->host);
- if (strcmp(parsed_url->url->host,prx)!=0){
- char *route=NULL;
- osip_route_t *rt;
- osip_route_init(&rt);
- if (osip_route_parse(rt,prx)==0){
- char *rtstr;
- osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL);
- osip_route_to_str(rt,&rtstr);
- route=ms_strdup(rtstr);
- osip_free(rtstr);
- }
- osip_route_free(rt);
- ms_message("Adding a route: %s",route);
- return route;
- }
- }
- }
- return NULL;
-}
-
bool_t linphone_core_interpret_url(LinphoneCore *lc, const char *url, LinphoneAddress **real_parsed_url, char **route){
enum_lookup_res_t *enumres=NULL;
- osip_to_t *parsed_url=NULL;
+ LinphoneAddress *parsed_url=NULL;
char *enum_domain=NULL;
LinphoneProxyConfig *proxy=lc->default_proxy;;
char *tmpurl;
linphone_address_set_username(uri,normalized_username);
if (real_parsed_url!=NULL) *real_parsed_url=uri;
-#if 0
- /*if the prompted uri was auto-suffixed with proxy domain,
- then automatically set a route so that the request goes
- through the proxy*/
- if (tmproute==NULL){
- osip_route_t *rt=NULL;
- char *rtstr=NULL;
- osip_route_init(&rt);
- if (osip_route_parse(rt,linphone_proxy_config_get_addr(proxy))==0){
- osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL);
- osip_route_to_str(rt,&rtstr);
- *route=ms_strdup(rtstr);
- osip_free(rtstr);
- }
- ms_message("setting automatically a route to %s",*route);
- }
- else *route=ms_strdup(tmproute);
-#else
- if (tmproute==NULL) *route=guess_route_if_any(lc,*real_parsed_url);
if (tmproute) *route=ms_strdup(tmproute);
-#endif
return TRUE;
}else return FALSE;
}
if (real_parsed_url!=NULL) *real_parsed_url=parsed_url;
else linphone_address_destroy(parsed_url);
if (tmproute) *route=ms_strdup(tmproute);
- else *route=guess_route_if_any(lc,*real_parsed_url);
+
return TRUE;
}
/* else we could not do anything with url given by user, so display an error */
return route;
}
-void linphone_set_sdp(osip_message_t *sip, const char *sdpmesg){
- int sdplen=strlen(sdpmesg);
- char clen[10];
- snprintf(clen,sizeof(clen),"%i",sdplen);
- osip_message_set_body(sip,sdpmesg,sdplen);
- osip_message_set_content_type(sip,"application/sdp");
- osip_message_set_content_length(sip,clen);
-}
-
LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const LinphoneAddress *uri){
const MSList *elem;
LinphoneProxyConfig *found_cfg=NULL;
return found_cfg;
}
-static void fix_contact(LinphoneCore *lc, osip_message_t *msg, const char *localip, LinphoneProxyConfig *dest_proxy){
- osip_contact_t *ctt=NULL;
- const char *ip=NULL;
- int port=5060;
+static char *get_fixed_contact(LinphoneCore *lc, const char *localip, LinphoneProxyConfig *dest_proxy){
+ LinphoneAddress *ctt;
- osip_message_get_contact(msg,0,&ctt);
- if (ctt!=NULL){
- if (dest_proxy!=NULL){
- /* if we know the request will go to a known proxy for which we are registered,
- we can use the same contact address as in the register */
- linphone_proxy_config_get_contact(dest_proxy,&ip,&port);
- }else{
- ip=localip;
- port=linphone_core_get_sip_port(lc);
- }
- if (ip!=NULL){
- osip_free(ctt->url->host);
- ctt->url->host=osip_strdup(ip);
- }
- if (port!=0){
- char tmp[10]={0};
- char *str;
- snprintf(tmp,sizeof(tmp)-1,"%i",port);
- if (ctt->url->port!=NULL)
- osip_free(ctt->url->port);
- ctt->url->port=osip_strdup(tmp);
- osip_contact_to_str(ctt,&str);
- ms_message("Contact has been fixed to %s",str);
- osip_free(str);
+ if (dest_proxy && dest_proxy->op){
+ const char *fixed_contact=sal_op_get_contact(dest_proxy->op);
+ if (fixed_contact) {
+ ms_message("Contact has been fixed using proxy to %s",fixed_contact);
+ return ms_strdup(fixed_contact);
}
}
+ ctt=linphone_core_get_primary_contact_parsed(lc);
+
+ if (ctt!=NULL){
+ char *ret;
+ /*otherwise use supllied localip*/
+ linphone_address_set_domain(ctt,localip);
+ linphone_address_set_port_int(ctt,linphone_core_get_sip_port(lc));
+ ret=linphone_address_as_string_uri_only(ctt);
+ linphone_address_destroy(ctt);
+ ms_message("Contact has been fixed using local ip to %s",ret);
+ return ret;
+ }
+ return NULL;
}
/**
{
char *barmsg;
int err=0;
- char *sdpmesg=NULL;
char *route=NULL;
const char *from=NULL;
- osip_message_t *invite=NULL;
- sdp_context_t *ctx=NULL;
+ char *contact=NULL;
LinphoneProxyConfig *proxy=NULL;
LinphoneAddress *parsed_url2=NULL;
LinphoneAddress *real_parsed_url=NULL;
char *real_url=NULL;
LinphoneProxyConfig *dest_proxy=NULL;
-
+ LinphoneCall *call;
+
if (lc->call!=NULL){
lc->vtable.display_warning(lc,_("Sorry, having multiple simultaneous calls is not supported yet !"));
return -1;
/* if no proxy or no identity defined for this proxy, default to primary contact*/
if (from==NULL) from=linphone_core_get_primary_contact(lc);
- err=eXosip_call_build_initial_invite(&invite,real_url,from,
- route,"Phone call");
- if (err<0){
- ms_warning("Could not build initial invite cause [%i]",err);
- goto end;
- }
- if (lp_config_get_int(lc->config,"sip","use_session_timers",0)==1){
- osip_message_set_header(invite, "Session-expires", "200");
- osip_message_set_supported(invite, "timer");
- }
- /* make sdp message */
-
parsed_url2=linphone_address_new(from);
- lc->call=linphone_call_new_outgoing(lc,parsed_url2,real_parsed_url);
+ call=linphone_call_new_outgoing(lc,parsed_url2,real_parsed_url);
+ sal_op_set_route(call->op,route);
+
/*try to be best-effort in giving real local or routable contact address,
except when the user choosed to override the ipaddress */
if (linphone_core_get_firewall_policy(lc)!=LINPHONE_POLICY_USE_NAT_ADDRESS)
- fix_contact(lc,invite,lc->call->localip,dest_proxy);
+ contact=get_fixed_contact(lc,call->localip,dest_proxy);
+ if (contact){
+ sal_op_set_contact(call->op, contact);
+ ms_free(contact);
+ }
+
+ lc->call=call;
+
+ linphone_core_init_media_streams(lc,lc->call);
+ if (!lc->sip_conf.sdp_200_ack){
+ call->media_pending=TRUE;
+ sal_call_set_local_media_description(call->op,call->localdesc);
+ }
+ err=sal_call(call->op,from,real_url);
barmsg=ortp_strdup_printf("%s %s", _("Contacting"), real_url);
lc->vtable.display_status(lc,barmsg);
ms_free(barmsg);
- if (!lc->sip_conf.sdp_200_ack){
- ctx=lc->call->sdpctx;
- sdpmesg=sdp_context_get_offer(ctx);
- linphone_set_sdp(invite,sdpmesg);
- linphone_core_init_media_streams(lc);
- }
- eXosip_lock();
- err=eXosip_call_send_initial_invite(invite);
- lc->call->cid=err;
- eXosip_unlock();
if (err<0){
ms_warning("Could not initiate call.");
lc->vtable.display_status(lc,_("could not call"));
- linphone_call_destroy(lc->call);
+ linphone_core_stop_media_streams(lc,call);
+ linphone_call_destroy(call);
lc->call=NULL;
- linphone_core_stop_media_streams(lc);
}else gstate_new_state(lc, GSTATE_CALL_OUT_INVITE, url);
- goto end;
- end:
- if (real_url!=NULL) ms_free(real_url);
- if (route!=NULL) ms_free(route);
+ if (real_url!=NULL) ms_free(real_url);
+ if (route!=NULL) ms_free(route);
return (err<0) ? -1 : 0;
}
char *real_url=NULL;
LinphoneAddress *real_parsed_url=NULL;
LinphoneCall *call;
- osip_message_t *msg=NULL;
char *route;
if (!linphone_core_interpret_url(lc,url,&real_parsed_url, &route)){
/* bad url */
}
lc->call=NULL;
real_url=linphone_address_as_string (real_parsed_url);
- eXosip_call_build_refer(call->did, real_url, &msg);
+ sal_refer(call->op,real_url);
ms_free(real_url);
- eXosip_lock();
- eXosip_call_send_request(call->did, msg);
- eXosip_unlock();
return 0;
}
return FALSE;
}
-#ifdef VINCENT_MAURY_RSVP
-/* on=1 for RPC_ENABLE=1...*/
-int linphone_core_set_rpc_mode(LinphoneCore *lc, int on)
-{
- if (on==1)
- printf("RPC_ENABLE set on\n");
- else
- printf("RPC_ENABLE set off\n");
- lc->rpc_enable = (on==1);
- /* need to tell eXosip the new setting */
- if (eXosip_set_rpc_mode (lc->rpc_enable)!=0)
- return -1;
- return 0;
-}
-
-/* on=1 for RSVP_ENABLE=1...*/
-int linphone_core_set_rsvp_mode(LinphoneCore *lc, int on)
-{
- if (on==1)
- printf("RSVP_ENABLE set on\n");
- else
- printf("RSVP_ENABLE set off\n");
- lc->rsvp_enable = (on==1);
- /* need to tell eXosip the new setting */
- if (eXosip_set_rsvp_mode (lc->rsvp_enable)!=0)
- return -1;
- return 0;
-}
-
-/* answer : 1 for yes, 0 for no */
-int linphone_core_change_qos(LinphoneCore *lc, int answer)
-{
- char *sdpmesg;
- if (lc->call==NULL){
- return -1;
- }
-
- if (lc->rsvp_enable && answer==1)
- {
- /* answer is yes, local setting is with qos, so
- * the user chose to continue with no qos ! */
- /* so switch in normal mode : ring and 180 */
- lc->rsvp_enable = 0; /* no more rsvp */
- eXosip_set_rsvp_mode (lc->rsvp_enable);
- /* send 180 */
- eXosip_lock();
- eXosip_answer_call(lc->call->did,180,NULL);
- eXosip_unlock();
- /* play the ring */
- ms_message("Starting local ring...");
- lc->ringstream=ring_start(lc->sound_conf.local_ring,
- 2000,ms_snd_card_manager_get_card(ms_snd_card_manager_get(),lc->sound_conf.ring_sndcard));
- }
- else if (!lc->rsvp_enable && answer==1)
- {
- /* switch to QoS mode on : answer 183 session progress */
- lc->rsvp_enable = 1;
- eXosip_set_rsvp_mode (lc->rsvp_enable);
- /* take the sdp already computed, see osipuacb.c */
- sdpmesg=lc->call->sdpctx->answerstr;
- eXosip_lock();
- eXosip_answer_call_with_body(lc->call->did,183,"application/sdp",sdpmesg);
- eXosip_unlock();
- }
- else
- {
- /* decline offer (603) */
- linphone_core_terminate_call(lc, NULL);
- }
- return 0;
-}
-#endif
-
-void linphone_core_init_media_streams(LinphoneCore *lc){
- lc->audiostream=audio_stream_new(linphone_core_get_audio_port(lc),linphone_core_ipv6_enabled(lc));
+void linphone_core_init_media_streams(LinphoneCore *lc, LinphoneCall *call){
+ SalMediaDescription *md=call->localdesc;
+ lc->audiostream=audio_stream_new(md->streams[0].port,linphone_core_ipv6_enabled(lc));
if (linphone_core_echo_limiter_enabled(lc)){
const char *type=lp_config_get_string(lc->config,"sound","el_type","mic");
if (strcasecmp(type,"mic")==0)
rtp_session_set_transports(lc->audiostream->session,lc->a_rtp,lc->a_rtcp);
#ifdef VIDEO_ENABLED
- if (lc->video_conf.display || lc->video_conf.capture)
- lc->videostream=video_stream_new(linphone_core_get_video_port(lc),linphone_core_ipv6_enabled(lc));
+ if ((lc->video_conf.display || lc->video_conf.capture) && md->streams[1].port>0)
+ lc->videostream=video_stream_new(md->streams[1].port,linphone_core_ipv6_enabled(lc));
#else
lc->videostream=NULL;
#endif
}
}
+static RtpProfile *make_profile(LinphoneCore *lc, const SalStreamDescription *desc, int *used_pt){
+ int bw;
+ const MSList *elem;
+ RtpProfile *prof=rtp_profile_new("Call profile");
+ bool_t first=TRUE;
+ if (desc->type==SalAudio){
+ bw=get_min_bandwidth(lc->up_audio_bw,desc->bandwidth);
+ }
+ else bw=get_min_bandwidth(lc->up_video_bw,desc->bandwidth);
+ for(elem=desc->payloads;elem!=NULL;elem=elem->next){
+ PayloadType *pt=(PayloadType*)elem->data;
+ if (bw>0) pt->normal_bitrate=bw*1000;
+ else if (desc->type==SalAudio){
+ pt->normal_bitrate=-1;
+ }
+ if (first) {
+ *used_pt=payload_type_get_number(pt);
+ first=FALSE;
+ }
+ if (desc->ptime>0){
+ char tmp[40];
+ snprintf(tmp,sizeof(tmp),"ptime=%i",desc->ptime);
+ payload_type_append_send_fmtp(pt,tmp);
+ }
+ rtp_profile_set_payload(prof,payload_type_get_number(pt),pt);
+ }
+ return prof;
+}
+
void linphone_core_start_media_streams(LinphoneCore *lc, LinphoneCall *call){
LinphoneAddress *me=linphone_core_get_primary_contact_parsed(lc);
const char *tool="linphone-" LINPHONE_VERSION;
char *cname;
+ int used_pt=-1;
/* adjust rtp jitter compensation. It must be at least the latency of the sound card */
int jitt_comp=MAX(lc->sound_conf.latency,lc->rtp_conf.audio_jitt_comp);
if (call->media_start_time==0) call->media_start_time=time(NULL);
- cname=ortp_strdup_printf("%s@%s",me->url->username,me->url->host);
+ cname=linphone_address_as_string_uri_only(me);
{
- StreamParams *audio_params=&call->audio_params;
- if (!lc->use_files){
- MSSndCard *playcard=lc->sound_conf.play_sndcard;
- MSSndCard *captcard=lc->sound_conf.capt_sndcard;
- if (playcard==NULL) {
- ms_warning("No card defined for playback !");
- goto end;
- }
- if (captcard==NULL) {
- ms_warning("No card defined for capture !");
- goto end;
+ const SalStreamDescription *stream=sal_media_description_find_stream(call->resultdesc,
+ SalProtoRtpAvp,SalAudio);
+ if (stream){
+ call->audio_profile=make_profile(lc,stream,&used_pt);
+ if (!lc->use_files){
+ MSSndCard *playcard=lc->sound_conf.play_sndcard;
+ MSSndCard *captcard=lc->sound_conf.capt_sndcard;
+ if (playcard==NULL) {
+ ms_warning("No card defined for playback !");
+ goto end;
+ }
+ if (captcard==NULL) {
+ ms_warning("No card defined for capture !");
+ goto end;
+ }
+ audio_stream_start_now(
+ lc->audiostream,
+ call->audio_profile,
+ stream->addr[0]!='\0' ? stream->addr : call->resultdesc->addr,
+ stream->port,
+ stream->port+1,
+ used_pt,
+ jitt_comp,
+ playcard,
+ captcard,
+ linphone_core_echo_cancellation_enabled(lc));
+ }else{
+ audio_stream_start_with_files(
+ lc->audiostream,
+ call->audio_profile,
+ stream->addr[0]!='\0' ? stream->addr : call->resultdesc->addr,
+ stream->port,
+ stream->port+1,
+ used_pt,
+ 100,
+ lc->play_file,
+ lc->rec_file);
}
- if (audio_params->relay_session_id!=NULL)
- audio_stream_set_relay_session_id(lc->audiostream,audio_params->relay_session_id);
- audio_stream_start_now(
- lc->audiostream,
- call->profile,
- audio_params->remoteaddr,
- audio_params->remoteport,
- audio_params->remotertcpport,
- audio_params->pt,
- jitt_comp,
- playcard,
- captcard,
- linphone_core_echo_cancellation_enabled(lc));
- }else{
- audio_stream_start_with_files(
- lc->audiostream,
- call->profile,
- audio_params->remoteaddr,
- audio_params->remoteport,
- audio_params->remotertcpport,
- audio_params->pt,
- 100,
- lc->play_file,
- lc->rec_file);
- }
- post_configure_audio_streams(lc);
- audio_stream_set_rtcp_information(lc->audiostream, cname, tool);
+ post_configure_audio_streams(lc);
+ audio_stream_set_rtcp_information(lc->audiostream, cname, tool);
+ }else ms_warning("No audio stream defined ?");
}
#ifdef VIDEO_ENABLED
{
+ const SalStreamDescription *stream=sal_media_description_find_stream(call->resultdesc,
+ SalProtoRtpAvp,SalVideo);
/* shutdown preview */
if (lc->previewstream!=NULL) {
video_preview_stop(lc->previewstream);
lc->previewstream=NULL;
}
- if (lc->video_conf.display || lc->video_conf.capture) {
- StreamParams *video_params=&call->video_params;
-
- if (video_params->remoteport>0){
- if (video_params->relay_session_id!=NULL)
- video_stream_set_relay_session_id(lc->videostream,video_params->relay_session_id);
- video_stream_set_sent_video_size(lc->videostream,linphone_core_get_preferred_video_size(lc));
- video_stream_enable_self_view(lc->videostream,lc->video_conf.selfview);
- if (lc->video_conf.display && lc->video_conf.capture)
- video_stream_start(lc->videostream,
- call->profile, video_params->remoteaddr, video_params->remoteport,
- video_params->remotertcpport,
- video_params->pt, jitt_comp, lc->video_conf.device);
- else if (lc->video_conf.display)
- video_stream_recv_only_start(lc->videostream,
- call->profile, video_params->remoteaddr, video_params->remoteport,
- video_params->pt, jitt_comp);
- else if (lc->video_conf.capture)
- video_stream_send_only_start(lc->videostream,
- call->profile, video_params->remoteaddr, video_params->remoteport,
- video_params->remotertcpport,
- video_params->pt, jitt_comp, lc->video_conf.device);
- video_stream_set_rtcp_information(lc->videostream, cname,tool);
- }
+ if (stream && (lc->video_conf.display || lc->video_conf.capture)) {
+ const char *addr=stream->addr[0]!='\0' ? stream->addr : call->resultdesc->addr;
+ call->video_profile=make_profile(lc,stream,&used_pt);
+ video_stream_set_sent_video_size(lc->videostream,linphone_core_get_preferred_video_size(lc));
+ video_stream_enable_self_view(lc->videostream,lc->video_conf.selfview);
+ if (lc->video_conf.display && lc->video_conf.capture)
+ video_stream_start(lc->videostream,
+ call->video_profile, addr, stream->port,
+ stream->port+1,
+ used_pt, jitt_comp, lc->video_conf.device);
+ else if (lc->video_conf.display)
+ video_stream_recv_only_start(lc->videostream,
+ call->video_profile, addr, stream->port,
+ used_pt, jitt_comp);
+ else if (lc->video_conf.capture)
+ video_stream_send_only_start(lc->videostream,
+ call->video_profile, addr, stream->port,
+ stream->port+1,
+ used_pt, jitt_comp, lc->video_conf.device);
+ video_stream_set_rtcp_information(lc->videostream, cname,tool);
}
}
#endif
goto end;
end:
- ms_free(cname);
- linphone_address_destroy(me);
- lc->call->state=LCStateAVRunning;
+ ms_free(cname);
+ linphone_address_destroy(me);
+ lc->call->state=LCStateAVRunning;
}
-void linphone_core_stop_media_streams(LinphoneCore *lc){
+void linphone_core_stop_media_streams(LinphoneCore *lc, LinphoneCall *call){
if (lc->audiostream!=NULL) {
audio_stream_stop(lc->audiostream);
lc->audiostream=NULL;
}
}
#endif
+ if (call->audio_profile){
+ rtp_profile_clear_all(call->audio_profile);
+ rtp_profile_destroy(call->audio_profile);
+ call->audio_profile=NULL;
+ }
+ if (call->video_profile){
+ rtp_profile_clear_all(call->video_profile);
+ rtp_profile_destroy(call->video_profile);
+ call->video_profile=NULL;
+ }
}
/**
**/
int linphone_core_accept_call(LinphoneCore *lc, const char *url)
{
- char *sdpmesg;
- osip_message_t *msg=NULL;
LinphoneCall *call=lc->call;
- int err;
- bool_t offering=FALSE;
-
+ const char *contact=NULL;
+
if (call==NULL){
return -1;
}
- if (lc->call->state==LCStateAVRunning){
+ if (call->state==LCStateAVRunning){
/*call already accepted*/
return -1;
}
ms_message("ring stopped");
lc->ringstream=NULL;
}
- /* sends a 200 OK */
- err=eXosip_call_build_answer(call->tid,200,&msg);
- if (err<0 || msg==NULL){
- ms_error("Fail to build answer for call: err=%i",err);
- return -1;
- }
- if (lp_config_get_int(lc->config,"sip","use_session_timers",0)==1){
- if (call->supports_session_timers) osip_message_set_supported(msg, "timer");
- }
+
/*try to be best-effort in giving real local or routable contact address,
except when the user choosed to override the ipaddress */
if (linphone_core_get_firewall_policy(lc)!=LINPHONE_POLICY_USE_NAT_ADDRESS)
- fix_contact(lc,msg,call->localip,NULL);
- /*if a sdp answer is computed, send it, else send an offer */
- sdpmesg=call->sdpctx->answerstr;
- if (sdpmesg==NULL){
- offering=TRUE;
- ms_message("generating sdp offer");
- sdpmesg=sdp_context_get_offer(call->sdpctx);
-
- if (sdpmesg==NULL){
- ms_error("fail to generate sdp offer !");
- return -1;
- }
- linphone_set_sdp(msg,sdpmesg);
- linphone_core_init_media_streams(lc);
- }else{
- linphone_set_sdp(msg,sdpmesg);
- }
- eXosip_lock();
- eXosip_call_send_answer(call->tid,200,msg);
- eXosip_unlock();
+ contact=get_fixed_contact(lc,call->localip,NULL);
+ if (contact)
+ sal_op_set_contact(call->op,contact);
+
+ sal_call_accept(call->op);
lc->vtable.display_status(lc,_("Connected."));
gstate_new_state(lc, GSTATE_CALL_IN_CONNECTED, NULL);
-
- if (!offering) linphone_core_start_media_streams(lc, lc->call);
+ call->resultdesc=sal_call_get_final_media_description(call->op);
+ if (call->resultdesc){
+ sal_media_description_ref(call->resultdesc);
+ linphone_core_start_media_streams(lc, call);
+ }else call->media_pending=TRUE;
ms_message("call answered.");
return 0;
}
return -1;
}
lc->call=NULL;
-
- eXosip_lock();
- eXosip_call_terminate(call->cid,call->did);
- eXosip_unlock();
+ sal_call_terminate(call->op);
/*stop ringing*/
if (lc->ringstream!=NULL) {
ring_stop(lc->ringstream);
lc->ringstream=NULL;
}
- linphone_core_stop_media_streams(lc);
+ linphone_core_stop_media_streams(lc,call);
lc->vtable.display_status(lc,_("Call ended") );
gstate_new_state(lc, GSTATE_CALL_END, NULL);
linphone_call_destroy(call);
const char *contact,
LinphoneOnlineStatus presence_mode)
{
- int contactok=-1;
if (minutes_away>0) lc->minutes_away=minutes_away;
- if (contact!=NULL) {
- osip_from_t *url;
- osip_from_init(&url);
- contactok=osip_from_parse(url,contact);
- if (contactok>=0) {
- ms_message("contact url is correct.");
- }
- osip_from_free(url);
-
- }
- if (contactok>=0){
- if (lc->alt_contact!=NULL) ms_free(lc->alt_contact);
- lc->alt_contact=ms_strdup(contact);
+
+ if (lc->alt_contact!=NULL) {
+ ms_free(lc->alt_contact);
+ lc->alt_contact=NULL;
}
+ if (contact) lc->alt_contact=ms_strdup(contact);
if (lc->presence_mode!=presence_mode){
linphone_core_notify_all_friends(lc,presence_mode);
/*
}
lc->prev_mode=lc->presence_mode;
lc->presence_mode=presence_mode;
-
}
LinphoneOnlineStatus linphone_core_get_presence_info(const LinphoneCore *lc){
* @param dtmf The dtmf name specified as a char, such as '0', '#' etc...
*
**/
-void linphone_core_send_dtmf(LinphoneCore *lc,char dtmf)
+void linphone_core_send_dtmf(LinphoneCore *lc, char dtmf)
{
/*By default we send DTMF RFC2833 if we do not have enabled SIP_INFO but we can also send RFC2833 and SIP_INFO*/
if (linphone_core_get_use_rfc2833_for_dtmf(lc)!=0 || linphone_core_get_use_info_for_dtmf(lc)==0)
ms_error("we cannot send RFC2833 dtmf when we are not in communication");
}
}
- if (linphone_core_get_use_info_for_dtmf(lc)!=0)
- {
- char dtmf_body[1000];
- char clen[10];
- osip_message_t *msg=NULL;
+ if (linphone_core_get_use_info_for_dtmf(lc)!=0){
/* Out of Band DTMF (use INFO method) */
LinphoneCall *call=lc->call;
if (call==NULL){
return;
}
- eXosip_call_build_info(call->did,&msg);
- snprintf(dtmf_body, 999, "Signal=%c\r\nDuration=250\r\n", dtmf);
- osip_message_set_body(msg,dtmf_body,strlen(dtmf_body));
- osip_message_set_content_type(msg,"application/dtmf-relay");
- snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body));
- osip_message_set_content_length(msg,clen);
-
- eXosip_lock();
- eXosip_call_send_request(call->did,msg);
- eXosip_unlock();
+ sal_call_send_dtmf(call->op,dtmf);
}
}
if (err!=0){
wmsg=ortp_strdup_printf(_("Invalid nat address '%s' : %s"),
addr, gai_strerror(err));
- ms_warning(wmsg); // what is this for ?
+ ms_warning("%s",wmsg); // what is this for ?
lc->vtable.display_warning(lc, wmsg);
ms_free(wmsg);
ms_free(tmp);
if (lc->net_conf.firewall_policy==LINPHONE_POLICY_USE_NAT_ADDRESS){
if (tmp!=NULL){
if (!lc->net_conf.nat_sdp_only){
- eXosip_set_option(EXOSIP_OPT_SET_IPV4_FOR_GATEWAY,tmp);
- /* the following does not work in all cases */
- /*
- eXosip_masquerade_contact(tmp,lc->sip_conf.sip_port);
- */
+ sal_masquerade(lc->sal,tmp);
}
ms_free(tmp);
}
else{
- eXosip_set_option(EXOSIP_OPT_SET_IPV4_FOR_GATEWAY,NULL);
- eXosip_masquerade_contact("",0);
+ sal_masquerade(lc->sal,NULL);
}
}
else {
- eXosip_set_option(EXOSIP_OPT_SET_IPV4_FOR_GATEWAY,NULL);
- eXosip_masquerade_contact("",0);
+ sal_masquerade(lc->sal,NULL);
}
}
lp_config_set_int(lc->config,"sip","use_rfc2833",config->use_rfc2833);
lp_config_set_int(lc->config,"sip","use_ipv6",config->ipv6_enabled);
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 */
}
- if (exosip_running)
- {
+ if (lc->sal){
int i;
- for (i=0;i<20;i++)
- {
- eXosip_event_t *ev;
- while((ev=eXosip_event_wait(0,0))!=NULL){
- linphone_core_process_event(lc,ev);
- }
- eXosip_automatic_action();
+ for (i=0;i<20;i++){
+ sal_iterate(lc->sal);
#ifndef WIN32
- usleep(100000);
+ usleep(100000);
#else
- Sleep(100);
+ Sleep(100);
#endif
- }
- }
+ }
+ }
+ ms_list_for_each(config->proxies,(void (*)(void*)) linphone_proxy_config_destroy);
+ ms_list_free(config->proxies);
+ config->proxies=NULL;
+
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++){
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;
+ sal_uninit(lc->sal);
+ lc->sal=NULL;
}
void rtp_config_uninit(LinphoneCore *lc)
sprintf(key,"audio_codec_%i",index);
lp_config_set_string(lc->config,key,"mime",pt->mime_type);
lp_config_set_int(lc->config,key,"rate",pt->clock_rate);
- lp_config_set_int(lc->config,key,"enabled",payload_type_enabled(pt));
+ lp_config_set_int(lc->config,key,"enabled",linphone_core_payload_type_enabled(lc,pt));
index++;
}
index=0;
sprintf(key,"video_codec_%i",index);
lp_config_set_string(lc->config,key,"mime",pt->mime_type);
lp_config_set_int(lc->config,key,"rate",pt->clock_rate);
- lp_config_set_int(lc->config,key,"enabled",payload_type_enabled(pt));
+ lp_config_set_int(lc->config,key,"enabled",linphone_core_payload_type_enabled(lc,pt));
lp_config_set_string(lc->config,key,"recv_fmtp",pt->recv_fmtp);
index++;
}
- if (lc->local_profile){
- rtp_profile_destroy(lc->local_profile);
- lc->local_profile=NULL;
- }
}
void ui_config_uninit(LinphoneCore* lc)
/* save all config */
net_config_uninit(lc);
sip_config_uninit(lc);
- lp_config_set_int(lc->config,"sip","default_proxy",linphone_core_get_default_proxy(lc,NULL));
rtp_config_uninit(lc);
sound_config_uninit(lc);
video_config_uninit(lc);
linphone_core_free_payload_types();
ortp_exit();
- eXosip_quit();
exosip_running=FALSE;
gstate_new_state(lc, GSTATE_POWER_OFF, NULL);
}