work in progress to use SAL in coreapi

This commit is contained in:
Simon Morlat 2010-01-29 23:57:46 +01:00
parent f5c4c989ad
commit 80e14f6a90
9 changed files with 588 additions and 632 deletions

View file

@ -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 <eXosip2/eXosip.h>
/**
* @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);
}

View file

@ -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
};

View file

@ -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 <eXosip2/eXosip.h>
#include "sdphandler.h"
#include <ortp/telephonyevents.h>
#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

View file

@ -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

View file

@ -26,7 +26,7 @@
#define _PRIVATE_H
#include "linphonecore.h"
#include <eXosip2/eXosip.h>
#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 */

View file

@ -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;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;i++){
ms_list_for_each(md->streams[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;i<md->nstreams;++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);
}

View file

@ -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);

View file

@ -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();

2
oRTP

@ -1 +1 @@
Subproject commit 7283d835734d07773ea9e37f89215c123322b48d
Subproject commit 5c64cbd803f83047e7c4d111a31b5d1726079423