diff --git a/coreapi/address.c b/coreapi/address.c index 36f6de903..51e3a1eee 100644 --- a/coreapi/address.c +++ b/coreapi/address.c @@ -20,7 +20,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphonecore.h" #include "lpconfig.h" #include "private.h" -#include /** * @addtogroup linphone_address @@ -31,122 +30,85 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * Constructs a LinphoneAddress object by parsing the user supplied address, * given as a string. **/ -LinphoneAddress * linphone_address_new(const char *uri){ - osip_from_t *from; - osip_from_init(&from); - if (osip_from_parse(from,uri)!=0){ - osip_from_free(from); - return NULL; - } - return from; +LinphoneAddress * linphone_address_new(const char *addr){ + return sal_address_new(addr); } /** * Clones a LinphoneAddress object. **/ -LinphoneAddress * linphone_address_clone(const LinphoneAddress *uri){ - osip_from_t *ret=NULL; - osip_from_clone(uri,&ret); - return ret; +LinphoneAddress * linphone_address_clone(const LinphoneAddress *addr){ + return sal_address_clone(addr); } -#define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL ) - /** * Returns the address scheme, normally "sip". **/ const char *linphone_address_get_scheme(const LinphoneAddress *u){ - return null_if_empty(u->url->scheme); + return sal_address_get_scheme(u); } /** * Returns the display name. **/ const char *linphone_address_get_display_name(const LinphoneAddress* u){ - return null_if_empty(u->displayname); + return sal_address_get_display_name(u); } /** * Returns the username. **/ const char *linphone_address_get_username(const LinphoneAddress *u){ - return null_if_empty(u->url->username); + return sal_address_get_username(u); } /** * Returns the domain name. **/ const char *linphone_address_get_domain(const LinphoneAddress *u){ - return null_if_empty(u->url->host); + return sal_address_get_domain(u); } /** * Sets the display name. **/ void linphone_address_set_display_name(LinphoneAddress *u, const char *display_name){ - if (u->displayname!=NULL){ - osip_free(u->displayname); - u->displayname=NULL; - } - if (display_name!=NULL) - u->displayname=osip_strdup(display_name); + sal_address_set_display_name(u,display_name); } /** * Sets the username. **/ void linphone_address_set_username(LinphoneAddress *uri, const char *username){ - if (uri->url->username!=NULL){ - osip_free(uri->url->username); - uri->url->username=NULL; - } - if (username) - uri->url->username=osip_strdup(username); + sal_address_set_username(uri,username); } /** * Sets the domain. **/ void linphone_address_set_domain(LinphoneAddress *uri, const char *host){ - if (uri->url->host!=NULL){ - osip_free(uri->url->host); - uri->url->host=NULL; - } - if (host) - uri->url->host=osip_strdup(host); + sal_address_set_domain(uri,host); } /** * Sets the port number. **/ void linphone_address_set_port(LinphoneAddress *uri, const char *port){ - if (uri->url->port!=NULL){ - osip_free(uri->url->port); - uri->url->port=NULL; - } - if (port) - uri->url->port=osip_strdup(port); + sal_address_set_port(uri,port); } /** * Sets the port number. **/ void linphone_address_set_port_int(LinphoneAddress *uri, int port){ - char tmp[12]; - if (port==5060){ - /*this is the default, special case to leave the port field blank*/ - linphone_address_set_port(uri,NULL); - return; - } - snprintf(tmp,sizeof(tmp),"%i",port); - linphone_address_set_port(uri,tmp); + sal_address_set_port_int(uri,port); } /** * Removes address's tags and uri headers so that it is displayable to the user. **/ void linphone_address_clean(LinphoneAddress *uri){ - osip_generic_param_freelist(&uri->gen_params); + sal_address_clean(uri); } /** @@ -154,11 +116,7 @@ void linphone_address_clean(LinphoneAddress *uri){ * The returned char * must be freed by the application. Use ms_free(). **/ char *linphone_address_as_string(const LinphoneAddress *u){ - char *tmp,*ret; - osip_from_to_str(u,&tmp); - ret=ms_strdup(tmp); - osip_free(tmp); - return ret; + return sal_address_as_string(u); } /** @@ -166,18 +124,14 @@ char *linphone_address_as_string(const LinphoneAddress *u){ * The returned char * must be freed by the application. Use ms_free(). **/ char *linphone_address_as_string_uri_only(const LinphoneAddress *u){ - char *tmp=NULL,*ret; - osip_uri_to_str(u->url,&tmp); - ret=ms_strdup(tmp); - osip_free(tmp); - return ret; + return sal_address_as_string_uri_only(u); } /** * Destroys a LinphoneAddress object. **/ void linphone_address_destroy(LinphoneAddress *u){ - osip_from_free(u); + sal_address_destroy(u); } diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index f4d2bc466..73eeca56e 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -23,3 +23,81 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphonecore.h" #include "private.h" +static void call_received(SalOp *h){ +} + +static void call_ringing(SalOp *h){ +} + +static void call_accepted(SalOp *h){ +} + +static void call_ack(SalOp *h){ +} + +static void call_updated(SalOp *){ +} + +static void call_terminated(SalOp *h){ +} + +static void call_failure(SalOp *h, SalError error, SalReason reason, const char *details){ +} + +static void auth_requested(SalOp *h, const char *realm, const char *username){ +} + +static void auth_success(SalOp *h, const char *realm, const char *username){ +} + +static void register_success(SalOp *op, bool_t registered){ +} + +static void register_failure(SalOp *op, SalError error, SalReason reason, const char *details){ +} + +static void vfu_request(SalOp *op){ +} + +static void dtmf_received(SalOp *op, char dtmf){ +} + +static void refer_received(SalOp *op, SalOp *op, const char *referto){ +} + +static void text_received(Sal *sal, const char *from, const char *msg){ +} + +static void presence_changed(SalOp *op, SalPresenceStatus status, const char *msg){ +} + +static void subscribe_received(SalOp *op, const char *from){ +} + +static void internal_message(SalOp *op, const char *msg){ +} + + + +SalCallbacks linphone_sal_callbacks={ + call_received, + call_ringing, + call_accepted, + call_ack, + call_updated, + call_terminated, + call_failure, + auth_requested, + auth_success, + register_success, + register_failure, + vfu_request, + dtmf_received, + refer_received, + text_received, + presence_changed, + subscribe_received, + internal_message +}; + + diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 19b4db9cf..f9f47c9e4 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -24,11 +24,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "mediastreamer2/mediastream.h" #include "mediastreamer2/msvolume.h" #include "mediastreamer2/msequalizer.h" -#include -#include "sdphandler.h" #include -#include "exevents.h" #ifdef INET6 @@ -52,16 +49,6 @@ static void toggle_video_preview(LinphoneCore *lc, bool_t val); /* 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 */ -}; - void lc_callback_obj_init(LCCallbackObj *obj,LinphoneCoreCbFunc func,void* ud) { obj->_func=func; @@ -73,7 +60,54 @@ int lc_callback_obj_invoke(LCCallbackObj *obj, LinphoneCore *lc){ 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; @@ -84,11 +118,6 @@ static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from 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){ int mtu; if (lc->net_conf.mtu==0 ){ @@ -106,44 +135,31 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr { 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); 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; + 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; } @@ -153,7 +169,9 @@ void linphone_call_destroy(LinphoneCall *obj) 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); } @@ -383,43 +401,6 @@ const LinphoneAddress *linphone_core_get_remote_uri(LinphoneCore *lc){ 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*. * @@ -432,7 +413,6 @@ void linphone_core_enable_logs(FILE *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); } /** @@ -446,7 +426,6 @@ void linphone_core_enable_logs(FILE *file){ **/ 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); } @@ -456,8 +435,6 @@ void linphone_core_enable_logs_with_cb(OrtpLogFunc 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); } @@ -866,6 +843,7 @@ static MSList *linphone_payload_types=NULL; 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); @@ -931,6 +909,10 @@ static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vta lc->rsvp_enable = 1; lc->rpc_enable = 0; #endif + lc->sal=sal_init(); + 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); @@ -943,7 +925,6 @@ static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vta 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; @@ -1009,11 +990,11 @@ const MSList *linphone_core_get_video_codecs(const LinphoneCore *lc) **/ 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); + linphone_address_destroy(ctt); return -1; } if (lc->sip_conf.contact!=NULL) ms_free(lc->sip_conf.contact); @@ -1022,7 +1003,7 @@ int linphone_core_set_primary_contact(LinphoneCore *lc, const char *contact) ms_free(lc->sip_conf.guessed_contact); lc->sip_conf.guessed_contact=NULL; } - osip_from_free(ctt); + linphone_address_destroy(ctt); return 0; } @@ -1040,12 +1021,8 @@ void linphone_core_get_local_ip(LinphoneCore *lc, const char *dest, char *result 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); } /** @@ -1053,42 +1030,32 @@ void linphone_core_get_local_ip(LinphoneCore *lc, const char *dest, char *result * * @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){ - + url=linphone_address_new(lc->sip_conf.contact); + if (!url){ + url=linphone_address_new("sip:unknown@unkwownhost"); }else ms_error("Could not parse identity contact !"); 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{ @@ -1294,7 +1261,11 @@ static bool_t exosip_running=FALSE; 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 @@ -1303,7 +1274,7 @@ static void apply_user_agent(void){ "unknown" #endif ); - eXosip_set_user_agent(ua_string); + if (lc->sal) sal_set_user_agent(lc->sal,ua_string); } /** @@ -1327,18 +1298,14 @@ void linphone_core_set_sip_port(LinphoneCore *lc,int port) 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); @@ -1346,13 +1313,7 @@ void linphone_core_set_sip_port(LinphoneCore *lc,int port) 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->sal); } /** @@ -1377,7 +1338,7 @@ bool_t linphone_core_ipv6_enabled(LinphoneCore *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); } @@ -1405,12 +1366,13 @@ static void proxy_update(LinphoneCore *lc, time_t curtime){ 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; @@ -1524,17 +1486,7 @@ void linphone_core_iterate(LinphoneCore *lc) 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){ @@ -1585,37 +1537,6 @@ void linphone_core_iterate(LinphoneCore *lc) } -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; @@ -1660,27 +1581,7 @@ bool_t linphone_core_interpret_url(LinphoneCore *lc, const char *url, LinphoneAd 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; } } @@ -1729,15 +1630,6 @@ const char * linphone_core_get_route(LinphoneCore *lc){ 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; @@ -1752,37 +1644,29 @@ LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const L 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){ + 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; } /** @@ -1796,17 +1680,16 @@ int linphone_core_invite(LinphoneCore *lc, const char *url) { 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; + const 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; @@ -1832,44 +1715,34 @@ int linphone_core_invite(LinphoneCore *lc, const char *url) /* 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"); - 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); + + lc->call=call; + + linphone_core_init_media_streams(lc,lc->call); + if (!lc->sip_conf.sdp_200_ack){ + 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_call_destroy(call); lc->call=NULL; linphone_core_stop_media_streams(lc); }else gstate_new_state(lc, GSTATE_CALL_OUT_INVITE, url); @@ -1993,8 +1866,9 @@ int linphone_core_change_qos(LinphoneCore *lc, int answer) } #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) @@ -2019,8 +1893,8 @@ void linphone_core_init_media_streams(LinphoneCore *lc){ 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 diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 140822f87..e277fc0df 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -39,105 +39,10 @@ extern "C" { struct _MSSndCard; struct _LinphoneCore; +struct SalOp; struct _LpConfig; -typedef struct sip_config -{ - char *contact; - char *guessed_contact; - int sip_port; - MSList *proxies; - MSList *deleted_proxies; - int inc_timeout; /*timeout after an un-answered incoming call is rejected*/ - bool_t use_info; - bool_t use_rfc2833; /*force RFC2833 to be sent*/ - bool_t guess_hostname; - bool_t loopback_only; - bool_t ipv6_enabled; - bool_t sdp_200_ack; - bool_t only_one_codec; /*in SDP answers*/ - bool_t register_only_when_network_is_up; -} sip_config_t; - -typedef struct rtp_config -{ - int audio_rtp_port; - int video_rtp_port; - int audio_jitt_comp; /*jitter compensation*/ - int video_jitt_comp; /*jitter compensation*/ - int nortp_timeout; -}rtp_config_t; - - - -typedef struct net_config -{ - char *nat_address; - char *stun_server; - char *relay; - int download_bw; - int upload_bw; - int firewall_policy; - int mtu; - bool_t nat_sdp_only; -}net_config_t; - - -typedef struct sound_config -{ - struct _MSSndCard * ring_sndcard; /* the playback sndcard currently used */ - struct _MSSndCard * play_sndcard; /* the playback sndcard currently used */ - struct _MSSndCard * capt_sndcard; /* the capture sndcard currently used */ - const char **cards; - int latency; /* latency in samples of the current used sound device */ - char rec_lev; - char play_lev; - char ring_lev; - char source; - char *local_ring; - char *remote_ring; - bool_t ec; - bool_t ea; - bool_t agc; -} sound_config_t; - -typedef struct codecs_config -{ - MSList *audio_codecs; /* list of audio codecs in order of preference*/ - MSList *video_codecs; /* for later use*/ -}codecs_config_t; - -typedef struct video_config{ - struct _MSWebCam *device; - const char **cams; - MSVideoSize vsize; - bool_t capture; - bool_t show_local; - bool_t display; - bool_t selfview; /*during calls*/ -}video_config_t; - -typedef struct ui_config -{ - int is_daemon; - int is_applet; - unsigned int timer_id; /* the timer id for registration */ -}ui_config_t; - - - -typedef struct autoreplier_config -{ - int enabled; - int after_seconds; /* accept the call after x seconds*/ - int max_users; /* maximum number of user that can call simultaneously */ - int max_rec_time; /* the max time of incoming voice recorded */ - int max_rec_msg; /* maximum number of recorded messages */ - const char *message; /* the path of the file to be played */ -}autoreplier_config_t; - -struct osip_from; /** * Object that represents a SIP address. @@ -153,7 +58,7 @@ struct osip_from; * @ingroup linphone_address * @var LinphoneAddress */ -typedef struct osip_from LinphoneAddress; +typedef struct SalAddress LinphoneAddress; LinphoneAddress * linphone_address_new(const char *uri); LinphoneAddress * linphone_address_clone(const LinphoneAddress *uri); @@ -172,8 +77,6 @@ char *linphone_address_as_string(const LinphoneAddress *u); char *linphone_address_as_string_uri_only(const LinphoneAddress *u); void linphone_address_destroy(LinphoneAddress *u); -struct _LinphoneCore; -struct _sdp_context; struct _SipSetupContext; struct _LinphoneCall; @@ -254,21 +157,9 @@ typedef enum _LinphoneOnlineStatus{ const char *linphone_online_status_to_string(LinphoneOnlineStatus ss); -typedef struct _LinphoneFriend{ - LinphoneAddress *uri; - int in_did; - int out_did; - int sid; - int nid; - LinphoneSubscribePolicy pol; - LinphoneOnlineStatus status; - struct _LinphoneProxyConfig *proxy; - struct _LinphoneCore *lc; - BuddyInfo *info; - char *refkey; - bool_t subscribe; - bool_t inc_subscribe_pending; -}LinphoneFriend; +struct _LinphoneFriend; + +typedef struct _LinphoneFriend LinphoneFriend; LinphoneFriend * linphone_friend_new(); LinphoneFriend *linphone_friend_new_with_addr(const char *addr); @@ -291,6 +182,8 @@ const char *linphone_friend_get_ref_key(const LinphoneFriend *lf); #define linphone_friend_url(lf) ((lf)->url) +struct LinphoneProxyConfig; + /** * @addtogroup proxies * @{ @@ -311,28 +204,7 @@ const char *linphone_friend_get_ref_key(const LinphoneFriend *lf); * The default proxy (see linphone_core_set_default_proxy() ) is the one of the list * that is used by default for calls. **/ -typedef struct _LinphoneProxyConfig -{ - struct _LinphoneCore *lc; - char *reg_proxy; - char *reg_identity; - char *reg_route; - char *realm; - int expires; - int reg_time; - int rid; - char *type; - struct _SipSetupContext *ssctx; - int auth_failures; - char *contact_addr; /* our IP address as seen by the proxy, read from via 's received= parameter*/ - int contact_port; /*our IP port as seen by the proxy, read from via's rport= parameter */ - char *dial_prefix; - bool_t commit; - bool_t reg_sendregister; - bool_t registered; - bool_t publish; - bool_t dial_escape_plus; -} LinphoneProxyConfig; +typedef struct _LinphoneProxyConfig LinphoneProxyConfig; LinphoneProxyConfig *linphone_proxy_config_new(void); int linphone_proxy_config_set_server_addr(LinphoneProxyConfig *obj, const char *server_addr); @@ -393,6 +265,8 @@ int linphone_account_creator_test_existence(LinphoneAccountCreator *obj); LinphoneProxyConfig * linphone_account_creator_validate(LinphoneAccountCreator *obj); void linphone_account_creator_destroy(LinphoneAccountCreator *obj); +struct _LinphoneAuthInfo; + /** * @ingroup authentication * Object holding authentication information. @@ -417,16 +291,7 @@ void linphone_account_creator_destroy(LinphoneAccountCreator *obj); * transactions and retry them with authentication headers. * **/ -typedef struct _LinphoneAuthInfo -{ - char *username; - char *realm; - char *userid; - char *passwd; - char *ha1; - bool_t works; - bool_t first_time; -}LinphoneAuthInfo; +typedef struct _LinphoneAuthInfo LinphoneAuthInfo; LinphoneAuthInfo *linphone_auth_info_new(const char *username, const char *userid, const char *passwd, const char *ha1,const char *realm); @@ -437,13 +302,7 @@ void linphone_auth_info_set_userid(LinphoneAuthInfo *info, const char *userid); void linphone_auth_info_destroy(LinphoneAuthInfo *info); LinphoneAuthInfo * linphone_auth_info_new_from_config_file(struct _LpConfig *config, int pos); -struct _LinphoneChatRoom{ - struct _LinphoneCore *lc; - char *peer; - char *route; - LinphoneAddress *peer_url; - void * user_data; -}; +struct _LinphoneChatRoom; typedef struct _LinphoneChatRoom LinphoneChatRoom; LinphoneChatRoom * linphone_core_create_chat_room(struct _LinphoneCore *lc, const char *to); @@ -547,10 +406,6 @@ typedef struct _LinphoneVTable AuthInfoRequested auth_info_requested; /**< Ask the application some authentication information */ DisplayStatusCb display_status; /**< Callback that notifies various events with human readable text.*/ DisplayMessageCb display_message;/**< Callback to display a message to the user */ -#ifdef VINCENT_MAURY_RSVP - /* the yes/no dialog box */ - DisplayMessageCb display_yes_no; -#endif DisplayMessageCb display_warning;/** Callback to display a warning to the user */ DisplayUrlCb display_url; DisplayQuestionCb display_question; @@ -587,71 +442,7 @@ typedef enum _LinphoneWaitingState{ } LinphoneWaitingState; typedef void * (*LinphoneWaitingCallback)(struct _LinphoneCore *lc, void *context, LinphoneWaitingState ws, const char *purpose, float progress); - -typedef struct _LinphoneCore -{ - LinphoneCoreVTable vtable; - struct _LpConfig *config; - net_config_t net_conf; - sip_config_t sip_conf; - rtp_config_t rtp_conf; - sound_config_t sound_conf; - video_config_t video_conf; - codecs_config_t codecs_conf; - ui_config_t ui_conf; - autoreplier_config_t autoreplier_conf; - LinphoneProxyConfig *default_proxy; - MSList *friends; - MSList *auth_info; - struct _RingStream *ringstream; - LCCallbackObj preview_finished_cb; - bool_t preview_finished; - struct _LinphoneCall *call; /* the current call, in the future it will be a list of calls (conferencing)*/ - int rid; /*registration id*/ - MSList *queued_calls; /* used by the autoreplier */ - MSList *call_logs; - MSList *chatrooms; - int max_call_logs; - int missed_calls; - struct _AudioStream *audiostream; /**/ - struct _VideoStream *videostream; - struct _VideoStream *previewstream; - RtpTransport *a_rtp,*a_rtcp; - struct _RtpProfile *local_profile; - MSList *bl_reqs; - MSList *subscribers; /* unknown subscribers */ - int minutes_away; - LinphoneOnlineStatus presence_mode; - LinphoneOnlineStatus prev_mode; - char *alt_contact; - void *data; - ms_mutex_t lock; - char *play_file; - char *rec_file; - time_t prevtime; - int dw_audio_bw; - int up_audio_bw; - int dw_video_bw; - int up_video_bw; - int audio_bw; - int automatic_action; - gstate_t gstate_power; - gstate_t gstate_reg; - gstate_t gstate_call; - LinphoneWaitingCallback wait_cb; - void *wait_ctx; - bool_t use_files; - bool_t apply_nat_settings; - bool_t ready; - bool_t bl_refresh; -#ifdef VINCENT_MAURY_RSVP - /* QoS parameters*/ - int rsvp_enable; - int rpc_enable; -#endif -} LinphoneCore; - - +typedef struct _LinphoneCore LinphoneCore; /* THE main API */ @@ -896,8 +687,6 @@ const LinphoneAddress *linphone_core_get_remote_uri(LinphoneCore *lc); int linphone_core_get_mtu(const LinphoneCore *lc); void linphone_core_set_mtu(LinphoneCore *lc, int mtu); -bool_t linphone_core_is_in_main_thread(LinphoneCore *lc); - void *linphone_core_get_user_data(LinphoneCore *lc); /* returns LpConfig object to read/write to the config file: usefull if you wish to extend @@ -923,21 +712,6 @@ void linphone_core_destroy(LinphoneCore *lc); /*for advanced users:*/ void linphone_core_set_audio_transports(LinphoneCore *lc, RtpTransport *rtp, RtpTransport *rtcp); -/* end of lecacy api */ - -/*internal use only */ -#define linphone_core_lock(lc) ms_mutex_lock(&(lc)->lock) -#define linphone_core_unlock(lc) ms_mutex_unlock((&lc)->lock) -void linphone_core_start_media_streams(LinphoneCore *lc, struct _LinphoneCall *call); -void linphone_core_stop_media_streams(LinphoneCore *lc); -const char * linphone_core_get_identity(LinphoneCore *lc); -const char * linphone_core_get_route(LinphoneCore *lc); -bool_t linphone_core_interpret_url(LinphoneCore *lc, const char *url, LinphoneAddress **real_parsed_url, char **route); -void linphone_core_start_waiting(LinphoneCore *lc, const char *purpose); -void linphone_core_update_progress(LinphoneCore *lc, const char *purpose, float progresses); -void linphone_core_stop_waiting(LinphoneCore *lc); - - #ifdef __cplusplus } #endif diff --git a/coreapi/private.h b/coreapi/private.h index e9809dc83..93832080c 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -26,7 +26,7 @@ #define _PRIVATE_H #include "linphonecore.h" -#include +#include "sal.h" #ifdef HAVE_CONFIG_H #include "config.h" @@ -54,21 +54,6 @@ #endif #endif - -typedef struct _StreamParams -{ - int initialized; - int line; - int localport; - int remoteport; - int remotertcpport; - int pt; - char *relay_session_id; - int natd_port; - char remoteaddr[LINPHONE_HOSTNAME_SIZE]; - char natd_addr[LINPHONE_HOSTNAME_SIZE]; -} StreamParams; - typedef enum _LCState{ LCStateInit, LCStateRinging, @@ -79,25 +64,20 @@ typedef enum _LCState{ typedef struct _LinphoneCall { struct _LinphoneCore *core; - StreamParams audio_params; - StreamParams video_params; + SalMediaDescription *localdesc; + SalMediaDescription *resultdesc; LinphoneCallDir dir; struct _RtpProfile *profile; /*points to the local_profile or to the remote "guessed" profile*/ struct _LinphoneCallLog *log; - int cid; /*call id */ - int did; /*dialog id */ - int tid; /*last transaction id*/ + SalOp *op; char localip[LINPHONE_IPADDR_SIZE]; /* our best guess for local ipaddress for this call */ - struct _sdp_context *sdpctx; time_t start_time; /*time at which the call was initiated*/ time_t media_start_time; /*time at which it was accepted, media streams established*/ LCState state; - bool_t auth_pending; - bool_t supports_session_timers; } LinphoneCall; LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to); -LinphoneCall * linphone_call_new_incoming(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, eXosip_event_t *ev); +LinphoneCall * linphone_call_new_incoming(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, SalOp *op); #define linphone_call_set_state(lcall,st) (lcall)->state=(st) void linphone_call_destroy(struct _LinphoneCall *obj); @@ -118,8 +98,6 @@ int linphone_proxy_config_send_publish(LinphoneProxyConfig *cfg, LinphoneOnlineS int linphone_online_status_to_eXosip(LinphoneOnlineStatus os); -void linphone_friend_set_sid(LinphoneFriend *lf, int sid); -void linphone_friend_set_nid(LinphoneFriend *lf, int nid); void linphone_friend_notify(LinphoneFriend *lf, int ss, LinphoneOnlineStatus os); int set_lock_file(); @@ -127,8 +105,6 @@ int get_lock_file(); int remove_lock_file(); int do_registration(LinphoneCore *lc, bool_t doit); void check_for_registration(LinphoneCore *lc); -char *int2str(int number); -int from_2char_without_params(osip_from_t *from,char **str); void check_sound_device(LinphoneCore *lc); void linphone_core_setup_local_rtp_profile(LinphoneCore *lc); void linphone_core_get_local_ip(LinphoneCore *lc, const char *to, char *result); @@ -157,24 +133,17 @@ static inline void set_string(char **dest, const char *src){ } #define PAYLOAD_TYPE_ENABLED PAYLOAD_TYPE_USER_FLAG_0 -bool_t linphone_proxy_config_register_again_with_updated_contact(LinphoneProxyConfig *obj, osip_message_t *orig_request, osip_message_t *last_answer); -void linphone_process_authentication(LinphoneCore* lc, eXosip_event_t *ev); -void linphone_authentication_ok(LinphoneCore *lc, eXosip_event_t *ev); -void linphone_subscription_new(LinphoneCore *lc, eXosip_event_t *ev); -void linphone_notify_recv(LinphoneCore *lc,eXosip_event_t *ev); -LinphoneProxyConfig *linphone_core_get_proxy_config_from_rid(LinphoneCore *lc, int rid); -void linphone_proxy_config_process_authentication_failure(LinphoneCore *lc, eXosip_event_t *ev); -void linphone_subscription_answered(LinphoneCore *lc, eXosip_event_t *ev); -void linphone_subscription_closed(LinphoneCore *lc, eXosip_event_t *ev); +void linphone_process_authentication(LinphoneCore* lc, SalOp *op); +void linphone_authentication_ok(LinphoneCore *lc, SalOp *op); +void linphone_subscription_new(LinphoneCore *lc, SalOp *op); +void linphone_notify_recv(LinphoneCore *lc, SalOp *op); +void linphone_proxy_config_process_authentication_failure(LinphoneCore *lc, SalOp *op); -void linphone_call_init_media_params(LinphoneCall *call); - -void linphone_set_sdp(osip_message_t *sip, const char *sdp); +void linphone_subscription_answered(LinphoneCore *lc, SalOp *op); +void linphone_subscription_closed(LinphoneCore *lc, SalOp *op); MSList *linphone_find_friend(MSList *fl, const LinphoneAddress *fri, LinphoneFriend **lf); -LinphoneFriend *linphone_find_friend_by_nid(MSList *l, int nid); -LinphoneFriend *linphone_find_friend_by_sid(MSList *l, int sid); void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc); void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCore *lc, const PayloadType *pt); @@ -194,4 +163,224 @@ void linphone_proxy_config_write_to_config_file(struct _LpConfig* config,Linphon int linphone_proxy_config_normalize_number(LinphoneProxyConfig *cfg, const char *username, char *result, size_t result_len); +/*internal use only */ +void linphone_core_start_media_streams(LinphoneCore *lc, struct _LinphoneCall *call); +void linphone_core_stop_media_streams(LinphoneCore *lc); +const char * linphone_core_get_identity(LinphoneCore *lc); +const char * linphone_core_get_route(LinphoneCore *lc); +bool_t linphone_core_interpret_url(LinphoneCore *lc, const char *url, LinphoneAddress **real_parsed_url, char **route); +void linphone_core_start_waiting(LinphoneCore *lc, const char *purpose); +void linphone_core_update_progress(LinphoneCore *lc, const char *purpose, float progresses); +void linphone_core_stop_waiting(LinphoneCore *lc); + + +extern SalCallbacks linphone_sal_callbacks; + + +struct _LinphoneProxyConfig +{ + struct _LinphoneCore *lc; + char *reg_proxy; + char *reg_identity; + char *reg_route; + char *realm; + int expires; + int reg_time; + SalOp *op; + char *type; + struct _SipSetupContext *ssctx; + int auth_failures; + char *dial_prefix; + bool_t commit; + bool_t reg_sendregister; + bool_t registered; + bool_t publish; + bool_t dial_escape_plus; +}; + +struct _LinphoneAuthInfo +{ + char *username; + char *realm; + char *userid; + char *passwd; + char *ha1; + bool_t works; + bool_t first_time; +}; + +struct _LinphoneChatRoom{ + struct _LinphoneCore *lc; + char *peer; + char *route; + LinphoneAddress *peer_url; + void * user_data; +}; + +struct _LinphoneFriend{ + LinphoneAddress *uri; + SalOp *insub; + SalOp *outsub; + LinphoneSubscribePolicy pol; + LinphoneOnlineStatus status; + struct _LinphoneProxyConfig *proxy; + struct _LinphoneCore *lc; + BuddyInfo *info; + char *refkey; + bool_t subscribe; + bool_t inc_subscribe_pending; +}; + +typedef struct sip_config +{ + char *contact; + char *guessed_contact; + int sip_port; + MSList *proxies; + MSList *deleted_proxies; + int inc_timeout; /*timeout after an un-answered incoming call is rejected*/ + bool_t use_info; + bool_t use_rfc2833; /*force RFC2833 to be sent*/ + bool_t guess_hostname; + bool_t loopback_only; + bool_t ipv6_enabled; + bool_t sdp_200_ack; + bool_t only_one_codec; /*in SDP answers*/ + bool_t register_only_when_network_is_up; +} sip_config_t; + +typedef struct rtp_config +{ + int audio_rtp_port; + int video_rtp_port; + int audio_jitt_comp; /*jitter compensation*/ + int video_jitt_comp; /*jitter compensation*/ + int nortp_timeout; +}rtp_config_t; + + + +typedef struct net_config +{ + char *nat_address; + char *stun_server; + char *relay; + int download_bw; + int upload_bw; + int firewall_policy; + int mtu; + bool_t nat_sdp_only; +}net_config_t; + + +typedef struct sound_config +{ + struct _MSSndCard * ring_sndcard; /* the playback sndcard currently used */ + struct _MSSndCard * play_sndcard; /* the playback sndcard currently used */ + struct _MSSndCard * capt_sndcard; /* the capture sndcard currently used */ + const char **cards; + int latency; /* latency in samples of the current used sound device */ + char rec_lev; + char play_lev; + char ring_lev; + char source; + char *local_ring; + char *remote_ring; + bool_t ec; + bool_t ea; + bool_t agc; +} sound_config_t; + +typedef struct codecs_config +{ + MSList *audio_codecs; /* list of audio codecs in order of preference*/ + MSList *video_codecs; /* for later use*/ +}codecs_config_t; + +typedef struct video_config{ + struct _MSWebCam *device; + const char **cams; + MSVideoSize vsize; + bool_t capture; + bool_t show_local; + bool_t display; + bool_t selfview; /*during calls*/ +}video_config_t; + +typedef struct ui_config +{ + int is_daemon; + int is_applet; + unsigned int timer_id; /* the timer id for registration */ +}ui_config_t; + + + +typedef struct autoreplier_config +{ + int enabled; + int after_seconds; /* accept the call after x seconds*/ + int max_users; /* maximum number of user that can call simultaneously */ + int max_rec_time; /* the max time of incoming voice recorded */ + int max_rec_msg; /* maximum number of recorded messages */ + const char *message; /* the path of the file to be played */ +}autoreplier_config_t; + + +struct _LinphoneCore +{ + LinphoneCoreVTable vtable; + Sal *sal; + struct _LpConfig *config; + net_config_t net_conf; + sip_config_t sip_conf; + rtp_config_t rtp_conf; + sound_config_t sound_conf; + video_config_t video_conf; + codecs_config_t codecs_conf; + ui_config_t ui_conf; + autoreplier_config_t autoreplier_conf; + LinphoneProxyConfig *default_proxy; + MSList *friends; + MSList *auth_info; + struct _RingStream *ringstream; + LCCallbackObj preview_finished_cb; + struct _LinphoneCall *call; /* the current call, in the future it will be a list of calls (conferencing)*/ + MSList *queued_calls; /* used by the autoreplier */ + MSList *call_logs; + MSList *chatrooms; + int max_call_logs; + int missed_calls; + struct _AudioStream *audiostream; /**/ + struct _VideoStream *videostream; + struct _VideoStream *previewstream; + RtpTransport *a_rtp,*a_rtcp; + struct _RtpProfile *local_profile; + MSList *bl_reqs; + MSList *subscribers; /* unknown subscribers */ + int minutes_away; + LinphoneOnlineStatus presence_mode; + LinphoneOnlineStatus prev_mode; + char *alt_contact; + void *data; + char *play_file; + char *rec_file; + time_t prevtime; + int dw_audio_bw; + int up_audio_bw; + int dw_video_bw; + int up_video_bw; + int audio_bw; + gstate_t gstate_power; + gstate_t gstate_reg; + gstate_t gstate_call; + LinphoneWaitingCallback wait_cb; + void *wait_ctx; + bool_t use_files; + bool_t apply_nat_settings; + bool_t ready; + bool_t bl_refresh; + bool_t preview_finished; +}; + #endif /* _PRIVATE_H */ diff --git a/coreapi/sal.c b/coreapi/sal.c index 7351d9277..150d7d94a 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -26,10 +26,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "sal.h" SalMediaDescription *sal_media_description_new(){ - return ms_new0(SalMediaDescription,1); + SalMediaDescription *md=ms_new0(SalMediaDescription,1); + md->refcount=1; } -void sal_media_description_destroy(SalMediaDescription *md){ +static void sal_media_description_destroy(SalMediaDescription *md){ int i; for(i=0;istreams[i].payloads,(void (*)(void *))payload_type_destroy); @@ -38,6 +39,28 @@ void sal_media_description_destroy(SalMediaDescription *md){ ms_free(md); } +void sal_media_description_ref(SalMediaDescription *md){ + md->refcount++; +} + +void sal_media_description_unref(SalMediaDescription *md){ + md->refcount--; + if (md->refcount==0){ + sal_media_description_destroy (md); + } +} + +SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md, + SalMediaProto proto, SalStreamType type){ + int i; + for(i=0;instreams;++i){ + SalStreamDescription *ss=&md->streams[i]; + if (ss->proto==proto && ss->type==type) return ss; + } + return NULL; +} + + static void assign_string(char **str, const char *arg){ if (*str){ ms_free(*str); @@ -111,8 +134,8 @@ void __sal_op_free(SalOp *op){ b->contact=NULL; } if (b->local_media) - sal_media_description_destroy(b->local_media); + sal_media_description_unref(b->local_media); if (b->remote_media) - sal_media_description_destroy(b->remote_media); + sal_media_description_unref(b->remote_media); ms_free(op); } diff --git a/coreapi/sal.h b/coreapi/sal.h index ba1778e04..37b28c189 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -64,20 +64,20 @@ Sal * sal_init(); void sal_uninit(Sal* sal); typedef enum { - SAL_TRANSPORT_DATAGRAM, - SAL_TRANSPORT_STREAM + SalTransportDatagram, + SalTransportStream }SalTransport; typedef enum { - SAL_AUDIO, - SAL_VIDEO, - SAL_OTHER + SalAudio, + SalVideo, + SalOther } SalStreamType; typedef enum{ - SAL_PROTO_UNKNOWN, - SAL_PROTO_RTP_AVP, - SAL_PROTO_RTP_SAVP + SalProtoUnknown, + SalProtoRtpAvp, + SalProtoRtpSavp }SalMediaProto; typedef struct SalStreamDescription{ @@ -93,6 +93,7 @@ typedef struct SalStreamDescription{ #define SAL_MEDIA_DESCRIPTION_MAX_STREAMS 4 typedef struct SalMediaDescription{ + int refcount; char addr[64]; char username[64]; int nstreams; @@ -100,7 +101,10 @@ typedef struct SalMediaDescription{ } SalMediaDescription; SalMediaDescription *sal_media_description_new(); -void sal_media_description_destroy(SalMediaDescription *md); +void sal_media_description_ref(SalMediaDescription *md); +void sal_media_description_unref(SalMediaDescription *md); +SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md, + SalMediaProto proto, SalStreamType type); /*this structure must be at the first byte of the SalOp structure defined by implementors*/ typedef struct SalOpBase{ @@ -240,6 +244,9 @@ int sal_notify_presence(SalOp *op, SalPresenceStatus status, const char *status_ #define payload_type_set_number(pt,n) (pt)->user_data=(void*)((long)n); #define payload_type_get_number(pt) ((int)(long)(pt)->user_data) +/*misc*/ +void sal_get_default_local_ip(Sal *sal, int address_family, char *ip, size_t iplen); + /*internal API */ void __sal_op_init(SalOp *b, Sal *sal); diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index 393e9ee83..5af843c9f 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -21,6 +21,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "offeranswer.h" +void sal_get_default_local_ip(Sal *sal, int address_family,char *ip, size_t iplen){ + if (eXosip_guess_localip(address_family,ip,iplen)<0){ + /*default to something */ + strncpy(ip,address_family==AF_INET6 ? "::1" : "127.0.0.1",iplen); + ms_error("Could not find default routable ip address !"); + } +} static SalOp * sal_find_register(Sal *sal, int rid){ const MSList *elem; @@ -65,13 +72,59 @@ void sal_op_release(SalOp *op){ sdp_message_free(op->sdp_answer); if (op->pending_auth) eXosip_event_free(op->pending_auth); - if( op->rid!=-1){ + if (op->rid!=-1){ sal_remove_register(op->base.root,op->rid); } + if (op->cid!=-1){ + eXosip_call_set_reference(op->cid,NULL); + } __sal_op_free(op); } +static 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); + } +} + + Sal * sal_init(){ + static bool_t firsttime=TRUE; + if (firsttime){ + osip_trace_initialize_func (OSIP_INFO4,&_osip_trace_func); + firsttime=FALSE; + } eXosip_init(); return ms_new0(Sal,1); } @@ -133,7 +186,7 @@ int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int i ipv6=strchr(addr,':')!=NULL; eXosip_enable_ipv6(ipv6); - if (tr!=SAL_TRANSPORT_DATAGRAM || is_secure){ + if (tr!=SalTransportDatagram || is_secure){ ms_fatal("SIP over TCP or TLS or DTLS is not supported yet."); return -1; } @@ -176,7 +229,7 @@ static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *de static void sdp_process(SalOp *h){ if (h->result){ - sal_media_description_destroy(h->result); + sal_media_description_unref(h->result); } h->result=sal_media_description_new(); if (h->sdp_offering){ @@ -199,6 +252,10 @@ static void sdp_process(SalOp *h){ } int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){ + if (desc) + sal_media_description_ref(desc); + if (h->base.local_media) + sal_media_description_unref(h->base.local_media); h->base.local_media=desc; return 0; } @@ -334,7 +391,7 @@ static void handle_reinvite(Sal *sal, eXosip_event_t *ev){ op->tid=ev->tid; sdp=eXosip_get_sdp_info(ev->request); if (op->base.remote_media){ - sal_media_description_destroy(op->base.remote_media); + sal_media_description_unref(op->base.remote_media); op->base.remote_media=NULL; } eXosip_lock(); diff --git a/oRTP b/oRTP index 7283d8357..5c64cbd80 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 7283d835734d07773ea9e37f89215c123322b48d +Subproject commit 5c64cbd803f83047e7c4d111a31b5d1726079423