From 59c9380b9186411c8882291d5a01cb91b5470f71 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Thu, 11 Mar 2010 14:34:25 +0100 Subject: [PATCH 1/8] add support for download ptime --- coreapi/exevents.c | 4 ++++ coreapi/linphonecore.c | 16 ++++++++++++++++ coreapi/linphonecore.h | 13 ++++++++++++- coreapi/sdphandler.c | 5 +++++ 4 files changed, 37 insertions(+), 1 deletion(-) diff --git a/coreapi/exevents.c b/coreapi/exevents.c index 36ed2b6d7..4dcee01a6 100644 --- a/coreapi/exevents.c +++ b/coreapi/exevents.c @@ -481,6 +481,10 @@ int linphone_set_audio_offer(sdp_context_t *ctx) payload.a_rtpmap="telephone-event/8000"; payload.a_fmtp="0-11"; if (lc->dw_audio_bw>0) payload.b_as_bandwidth=lc->dw_audio_bw; + if (lc->down_ptime>0) { + payload.a_ptime=lc->down_ptime; + ms_message("ptime [%i]",payload.a_ptime); + } sdp_context_add_audio_payload(ctx,&payload); return 0; } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 5f94e634e..284a6e56d 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -487,6 +487,9 @@ net_config_read (LinphoneCore *lc) lc->net_conf.nat_sdp_only=tmp; tmp=lp_config_get_int(lc->config,"net","mtu",0); linphone_core_set_mtu(lc,tmp); + tmp=lp_config_get_int(lc->config,"net","download_ptime",0); + linphone_core_set_download_ptime(lc,tmp); + } static void build_sound_devices_table(LinphoneCore *lc){ @@ -854,6 +857,18 @@ int linphone_core_get_download_bandwidth(const LinphoneCore *lc){ int linphone_core_get_upload_bandwidth(const LinphoneCore *lc){ return lc->net_conf.upload_bw; } +/** + * set audio packetization time linphone expect to received from peer + */ +void linphone_core_set_download_ptime(LinphoneCore *lc, int ptime); + +void linphone_core_set_download_ptime(LinphoneCore *lc, int ptime) { + lc->down_ptime=ptime; +} +int linphone_core_get_download_ptime(LinphoneCore *lc) { + return lc->down_ptime; +} + /** * Returns liblinphone's version as a string. @@ -952,6 +967,7 @@ static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vta lc->vtable.display_status(lc,_("Ready")); gstate_new_state(lc, GSTATE_POWER_ON, NULL); lc->auto_net_state_mon=TRUE; + lc->ready=TRUE; } diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 0796a6d05..4561250a0 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -661,6 +661,7 @@ typedef struct _LinphoneCore * In case of false, network state must be communicate to linphone core with method linphone_core_ */ bool_t auto_net_state_mon; + int down_ptime; } LinphoneCore; @@ -712,7 +713,17 @@ void linphone_core_set_upload_bandwidth(LinphoneCore *lc, int bw); int linphone_core_get_download_bandwidth(const LinphoneCore *lc); int linphone_core_get_upload_bandwidth(const LinphoneCore *lc); - +/** + * set audio packetization time linphone expect to received from peer + * @ingroup media_parameters + * + */ +void linphone_core_set_download_ptime(LinphoneCore *lc, int ptime); +/** + * get audio packetization time linphone expect to received from peer, 0 means unspecified + * @ingroup media_parameters + */ +int linphone_core_get_download_ptime(LinphoneCore *lc); #ifdef VINCENT_MAURY_RSVP /* QoS functions */ diff --git a/coreapi/sdphandler.c b/coreapi/sdphandler.c index 890217289..bf622a92e 100644 --- a/coreapi/sdphandler.c +++ b/coreapi/sdphandler.c @@ -238,6 +238,11 @@ sdp_context_add_payload (sdp_context_t * ctx, sdp_payload_t * payload, char *med attr_field); } } + if (payload->a_ptime !=0) { + attr_field = sstrdup_sprintf ("%i", payload->a_ptime); + sdp_message_a_attribute_add(offer, payload->line,osip_strdup ("ptime"),attr_field); + ms_message("adding ptime [%s]",attr_field); + } } void From 64514608ee6db62fc38304000b75ba4d7bc971ce Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 12 Mar 2010 18:49:44 +0100 Subject: [PATCH 2/8] use OPTIONS message to try to discover local contact. - before outgoing INVITES - just after receiving an INVITE --- coreapi/callbacks.c | 13 +++- coreapi/linphonecore.c | 158 ++++++++++++++++++++++++++++------------- coreapi/private.h | 4 ++ coreapi/sal.c | 13 ++++ coreapi/sal.h | 11 ++- coreapi/sal_eXosip2.c | 137 +++++++++++++++++++++++++++++------ coreapi/sal_eXosip2.h | 3 + 7 files changed, 269 insertions(+), 70 deletions(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index edce2c4e3..4e8f75028 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -421,6 +421,16 @@ static void internal_message(Sal *sal, const char *msg){ lc->vtable.show(lc); } +static void ping_reply(SalOp *op){ + LinphoneCall *call=(LinphoneCall*) sal_op_get_user_pointer(op); + ms_message("ping reply !"); + if (call){ + if (call->state==LCStatePreEstablishing){ + linphone_core_start_invite(call->core,call,NULL); + } + } +} + SalCallbacks linphone_sal_callbacks={ call_received, call_ringing, @@ -440,7 +450,8 @@ SalCallbacks linphone_sal_callbacks={ notify, subscribe_received, subscribe_closed, - internal_message + internal_message, + ping_reply }; diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 2c163d490..e269f4611 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -63,20 +63,21 @@ int lc_callback_obj_invoke(LCCallbackObj *obj, LinphoneCore *lc){ } -static MSList *make_codec_list(const MSList *codecs){ +static MSList *make_codec_list(const MSList *codecs, bool_t only_one_codec){ 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)); + if (only_one_codec) break; } } return l; } static SalMediaDescription *create_local_media_description(LinphoneCore *lc, - const char *localip, const char *username){ + const char *localip, const char *username, bool_t only_one_codec){ MSList *l; PayloadType *pt; SalMediaDescription *md=sal_media_description_new(); @@ -88,7 +89,7 @@ static SalMediaDescription *create_local_media_description(LinphoneCore *lc, 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); + l=make_codec_list(lc->codecs_conf.audio_codecs,only_one_codec); 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; @@ -101,7 +102,7 @@ static SalMediaDescription *create_local_media_description(LinphoneCore *lc, 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); + l=make_codec_list(lc->codecs_conf.video_codecs,only_one_codec); md->streams[1].payloads=l; if (lc->dw_video_bw) md->streams[1].bandwidth=lc->dw_video_bw; @@ -141,7 +142,7 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr 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_address_get_username(from),FALSE); linphone_call_init_common(call,from,to); discover_mtu(lc,linphone_address_get_domain (to)); return call; @@ -150,16 +151,30 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr 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); + char *to_str; + char *from_str; call->dir=LinphoneCallIncoming; sal_op_set_user_pointer(op,call); call->op=op; call->core=lc; + + if (lc->sip_conf.ping_with_options){ + /*the following sends an option request back to the caller so that + we get a chance to discover our nat'd address before answering.*/ + call->ping_op=sal_op_new(lc->sal); + to_str=linphone_address_as_string(to); + from_str=linphone_address_as_string(from); + sal_op_set_route(call->ping_op,sal_op_get_network_origin(call->op)); + sal_ping(call->ping_op,to_str,from_str); + ms_free(to_str); + ms_free(from_str); + } 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_address_get_username(me),lc->sip_conf.only_one_codec); linphone_call_init_common(call, from, to); discover_mtu(lc,linphone_address_get_domain(from)); linphone_address_destroy(me); @@ -171,9 +186,21 @@ void linphone_call_destroy(LinphoneCall *obj) linphone_core_notify_all_friends(obj->core,obj->core->prev_mode); linphone_call_log_completed(obj->log,obj); linphone_core_update_allocated_audio_bandwidth(obj->core); - if (obj->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); + if (obj->op!=NULL) { + sal_op_release(obj->op); + obj->op=NULL; + } + if (obj->resultdesc!=NULL) { + sal_media_description_unref(obj->resultdesc); + obj->resultdesc=NULL; + } + if (obj->localdesc!=NULL) { + sal_media_description_unref(obj->localdesc); + obj->localdesc=NULL; + } + if (obj->ping_op) { + sal_op_release(obj->ping_op); + } ms_free(obj); } @@ -271,6 +298,7 @@ void linphone_call_log_completed(LinphoneCallLog *calllog, LinphoneCall *call){ calllog->duration=time(NULL)-call->start_time; switch(call->state){ case LCStateInit: + case LCStatePreEstablishing: calllog->status=LinphoneCallAborted; break; case LCStateRinging: @@ -630,11 +658,12 @@ static void sip_config_read(LinphoneCore *lc) } } - /*for test*/ + /*for tuning or test*/ lc->sip_conf.sdp_200_ack=lp_config_get_int(lc->config,"sip","sdp_200_ack",0); lc->sip_conf.only_one_codec=lp_config_get_int(lc->config,"sip","only_one_codec",0); lc->sip_conf.register_only_when_network_is_up= lp_config_get_int(lc->config,"sip","register_only_when_network_is_up",1); + lc->sip_conf.ping_with_options=lp_config_get_int(lc->config,"sip","ping_with_options",1); } static void rtp_config_read(LinphoneCore *lc) @@ -1581,7 +1610,10 @@ void linphone_core_iterate(LinphoneCore *lc){ if (lc->call!=NULL){ LinphoneCall *call=lc->call; - + if (call->state==LCStatePreEstablishing && (curtime-call->start_time>=2)){ + /*start the call even if the OPTIONS reply did not arrive*/ + linphone_core_start_invite(lc,call,NULL); + } if (call->dir==LinphoneCallIncoming && call->state==LCStateRinging){ elapsed=curtime-call->start_time; ms_message("incoming call ringing for %i seconds",elapsed); @@ -1749,16 +1781,18 @@ static char *get_fixed_contact(LinphoneCore *lc, LinphoneCall *call , LinphonePr LinphoneAddress *ctt; const char *localip=call->localip; + /* first use user's supplied ip address if asked*/ if (linphone_core_get_firewall_policy(lc)==LINPHONE_POLICY_USE_NAT_ADDRESS){ ctt=linphone_core_get_primary_contact_parsed(lc); return ms_strdup_printf("sip:%s@%s",linphone_address_get_username(ctt), linphone_core_get_nat_address(lc)); } - + + /* if already choosed, don't change it */ if (call->op && sal_op_get_contact(call->op)!=NULL){ return NULL; } - + /*if using a proxy, use the contact address as guessed with the REGISTERs*/ if (dest_proxy && dest_proxy->op){ const char *fixed_contact=sal_op_get_contact(dest_proxy->op); if (fixed_contact) { @@ -1766,6 +1800,16 @@ static char *get_fixed_contact(LinphoneCore *lc, LinphoneCall *call , LinphonePr return ms_strdup(fixed_contact); } } + /* if the ping OPTIONS request succeeded use the contact guessed from the + received, rport*/ + if (call->ping_op){ + const char *guessed=sal_op_get_contact(call->ping_op); + if (guessed){ + ms_message("Contact has been fixed using OPTIONS to %s",guessed); + return ms_strdup(guessed); + } + } + ctt=linphone_core_get_primary_contact_parsed(lc); if (ctt!=NULL){ @@ -1781,6 +1825,47 @@ static char *get_fixed_contact(LinphoneCore *lc, LinphoneCall *call , LinphonePr return NULL; } +int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, LinphoneProxyConfig *dest_proxy){ + int err; + char *contact; + char *real_url,*barmsg; + char *from; + /*try to be best-effort in giving real local or routable contact address */ + contact=get_fixed_contact(lc,call,dest_proxy); + if (contact){ + sal_op_set_contact(call->op, contact); + ms_free(contact); + } + call->state=LCStateInit; + linphone_core_init_media_streams(lc,lc->call); + if (!lc->sip_conf.sdp_200_ack){ + call->media_pending=TRUE; + sal_call_set_local_media_description(call->op,call->localdesc); + } + real_url=linphone_address_as_string(call->log->to); + from=linphone_address_as_string(call->log->from); + err=sal_call(call->op,from,real_url); + + if (lc->sip_conf.sdp_200_ack){ + call->media_pending=TRUE; + sal_call_set_local_media_description(call->op,call->localdesc); + } + barmsg=ortp_strdup_printf("%s %s", _("Contacting"), real_url); + lc->vtable.display_status(lc,barmsg); + ms_free(barmsg); + + if (err<0){ + ms_warning("Could not initiate call."); + lc->vtable.display_status(lc,_("could not call")); + linphone_core_stop_media_streams(lc,call); + linphone_call_destroy(call); + lc->call=NULL; + }else gstate_new_state(lc, GSTATE_CALL_OUT_INVITE, real_url); + ms_free(real_url); + ms_free(from); + return err; +} + /** * Initiates an outgoing call * @@ -1790,11 +1875,9 @@ static char *get_fixed_contact(LinphoneCore *lc, LinphoneCall *call , LinphonePr **/ int linphone_core_invite(LinphoneCore *lc, const char *url) { - char *barmsg; int err=0; char *route=NULL; const char *from=NULL; - char *contact=NULL; LinphoneProxyConfig *proxy=NULL; LinphoneAddress *parsed_url2=NULL; LinphoneAddress *real_parsed_url=NULL; @@ -1831,42 +1914,21 @@ int linphone_core_invite(LinphoneCore *lc, const char *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 */ - contact=get_fixed_contact(lc,call,dest_proxy); - if (contact){ - sal_op_set_contact(call->op, contact); - ms_free(contact); - } - - lc->call=call; - - linphone_core_init_media_streams(lc,lc->call); - if (!lc->sip_conf.sdp_200_ack){ - call->media_pending=TRUE; - sal_call_set_local_media_description(call->op,call->localdesc); - } - err=sal_call(call->op,from,real_url); - - if (lc->sip_conf.sdp_200_ack){ - call->media_pending=TRUE; - sal_call_set_local_media_description(call->op,call->localdesc); - } - barmsg=ortp_strdup_printf("%s %s", _("Contacting"), real_url); - lc->vtable.display_status(lc,barmsg); - ms_free(barmsg); - if (err<0){ - ms_warning("Could not initiate call."); - lc->vtable.display_status(lc,_("could not call")); - linphone_core_stop_media_streams(lc,call); - linphone_call_destroy(call); - lc->call=NULL; - }else gstate_new_state(lc, GSTATE_CALL_OUT_INVITE, url); - + lc->call=call; + if (dest_proxy!=NULL || lc->sip_conf.ping_with_options==FALSE){ + err=linphone_core_start_invite(lc,call,dest_proxy); + }else{ + /*defer the start of the call after the OPTIONS ping*/ + call->state=LCStatePreEstablishing; + call->ping_op=sal_op_new(lc->sal); + sal_ping(call->ping_op,from,real_url); + call->start_time=time(NULL); + } + if (real_url!=NULL) ms_free(real_url); if (route!=NULL) ms_free(route); - return (err<0) ? -1 : 0; + return err; } int linphone_core_refer(LinphoneCore *lc, const char *url) diff --git a/coreapi/private.h b/coreapi/private.h index 546b83dc2..b23dff67d 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -56,6 +56,7 @@ typedef enum _LCState{ LCStateInit, + LCStatePreEstablishing, LCStateRinging, LCStateAVRunning }LCState; @@ -71,6 +72,7 @@ typedef struct _LinphoneCall struct _RtpProfile *video_profile; struct _LinphoneCallLog *log; SalOp *op; + SalOp *ping_op; char localip[LINPHONE_IPADDR_SIZE]; /* our best guess for local ipaddress for this call */ 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*/ @@ -180,6 +182,7 @@ 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); +int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, LinphoneProxyConfig *dest_proxy); extern SalCallbacks linphone_sal_callbacks; @@ -253,6 +256,7 @@ typedef struct sip_config bool_t sdp_200_ack; bool_t only_one_codec; /*in SDP answers*/ bool_t register_only_when_network_is_up; + bool_t ping_with_options; } sip_config_t; typedef struct rtp_config diff --git a/coreapi/sal.c b/coreapi/sal.c index ae432d565..750555016 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -128,11 +128,20 @@ const char *sal_op_get_proxy(const SalOp *op){ return ((SalOpBase*)op)->route; } +const char *sal_op_get_network_origin(const SalOp *op){ + return ((SalOpBase*)op)->origin; +} + void __sal_op_init(SalOp *b, Sal *sal){ memset(b,0,sizeof(SalOpBase)); ((SalOpBase*)b)->root=sal; } +void __sal_op_set_network_origin(SalOp *op, const char *origin){ + assign_string(&((SalOpBase*)op)->origin,origin); +} + + void __sal_op_free(SalOp *op){ SalOpBase *b=(SalOpBase *)op; if (b->from) { @@ -151,6 +160,10 @@ void __sal_op_free(SalOp *op){ ms_free(b->contact); b->contact=NULL; } + if (b->origin){ + ms_free(b->origin); + b->origin=NULL; + } if (b->local_media) sal_media_description_unref(b->local_media); if (b->remote_media) diff --git a/coreapi/sal.h b/coreapi/sal.h index eb8042361..e672216c9 100644 --- a/coreapi/sal.h +++ b/coreapi/sal.h @@ -124,6 +124,7 @@ typedef struct SalOpBase{ char *contact; char *from; char *to; + char *origin; SalMediaDescription *local_media; SalMediaDescription *remote_media; void *user_pointer; @@ -186,6 +187,7 @@ typedef void (*SalOnNotify)(SalOp *op, SalSubscribeState ss, SalPresenceStatus s typedef void (*SalOnSubscribeReceived)(SalOp *salop, const char *from); typedef void (*SalOnSubscribeClosed)(SalOp *salop, const char *from); typedef void (*SalOnInternalMsg)(Sal *sal, const char *msg); +typedef void (*SalOnPingReply)(SalOp *salop); typedef struct SalCallbacks{ SalOnCallReceived call_received; @@ -207,6 +209,7 @@ typedef struct SalCallbacks{ SalOnSubscribeReceived subscribe_received; SalOnSubscribeClosed subscribe_closed; SalOnInternalMsg internal_message; + SalOnPingReply ping_reply; }SalCallbacks; typedef struct SalAuthInfo{ @@ -219,7 +222,6 @@ typedef struct SalAuthInfo{ void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs); int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure); void sal_set_user_agent(Sal *ctx, const char *user_agent); -void sal_masquerade(Sal *ctx, const char *ip); void sal_use_session_timers(Sal *ctx, int expires); int sal_iterate(Sal *sal); MSList * sal_get_pending_auths(Sal *sal); @@ -242,6 +244,8 @@ const char *sal_op_get_to(const SalOp *op); const char *sal_op_get_contact(const SalOp *op); const char *sal_op_get_route(const SalOp *op); const char *sal_op_get_proxy(const SalOp *op); +/*for incoming requests, returns the origin of the packet as a sip uri*/ +const char *sal_op_get_network_origin(const SalOp *op); void *sal_op_get_user_pointer(const SalOp *op); /*Call API*/ @@ -273,6 +277,10 @@ int sal_notify_close(SalOp *op); /*presence publish */ int sal_publish(SalOp *op, const char *from, const char *to, SalPresenceStatus status); + +/*ping: main purpose is to obtain its own contact address behind firewalls*/ +int sal_ping(SalOp *op, const char *from, const char *to); + #define payload_type_set_number(pt,n) (pt)->user_data=(void*)((long)n); #define payload_type_get_number(pt) ((int)(long)(pt)->user_data) @@ -282,6 +290,7 @@ void sal_get_default_local_ip(Sal *sal, int address_family, char *ip, size_t ipl /*internal API */ void __sal_op_init(SalOp *b, Sal *sal); +void __sal_op_set_network_origin(SalOp *op, const char *origin /*a sip uri*/); void __sal_op_free(SalOp *b); diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index daae709db..cf6074db5 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -64,6 +64,36 @@ static void sal_remove_register(Sal *sal, int rid){ } } +static SalOp * sal_find_other(Sal *sal, osip_message_t *response){ + const MSList *elem; + SalOp *op; + osip_call_id_t *callid=osip_message_get_call_id(response); + if (callid==NULL) { + ms_error("There is no call-id in this response !"); + return NULL; + } + for(elem=sal->other_transactions;elem!=NULL;elem=elem->next){ + op=(SalOp*)elem->data; + if (osip_call_id_match(callid,op->call_id)==0) return op; + } + return NULL; +} + +static void sal_add_other(Sal *sal, SalOp *op, osip_message_t *request){ + osip_call_id_t *callid=osip_message_get_call_id(request); + if (callid==NULL) { + ms_error("There is no call id in the request !"); + return; + } + osip_call_id_clone(callid,&op->call_id); + sal->other_transactions=ms_list_append(sal->other_transactions,op); +} + +static void sal_remove_other(Sal *sal, SalOp *op){ + sal->other_transactions=ms_list_remove(sal->other_transactions,op); +} + + static void sal_add_pending_auth(Sal *sal, SalOp *op){ sal->pending_auths=ms_list_append(sal->pending_auths,op); } @@ -107,6 +137,7 @@ SalOp * sal_op_new(Sal *sal){ op->pending_auth=NULL; op->sdp_answer=NULL; op->reinvite=FALSE; + op->call_id=NULL; return op; } @@ -127,6 +158,10 @@ void sal_op_release(SalOp *op){ } if (op->result) sal_media_description_unref(op->result); + if (op->call_id){ + sal_remove_other(op->base.root,op); + osip_call_id_free(op->call_id); + } __sal_op_free(op); } @@ -191,11 +226,6 @@ void *sal_get_user_pointer(const Sal *sal){ return sal->up; } -void sal_masquerade(Sal *ctx, const char *ip){ - ms_message("Masquerading SIP with %s",ip); - eXosip_set_option(EXOSIP_OPT_SET_IPV4_FOR_GATEWAY,ip); -} - static void unimplemented_stub(){ ms_warning("Unimplemented SAL callback"); } @@ -232,6 +262,8 @@ void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){ ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub; if (ctx->callbacks.internal_message==NULL) ctx->callbacks.internal_message=(SalOnInternalMsg)unimplemented_stub; + if (ctx->callbacks.ping_reply==NULL) + ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub; } int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){ @@ -461,6 +493,24 @@ SalMediaDescription * sal_call_get_final_media_description(SalOp *h){ return h->result; } +int sal_ping(SalOp *op, const char *from, const char *to){ + osip_message_t *options=NULL; + + sal_op_set_from(op,from); + sal_op_set_to(op,to); + eXosip_options_build_request (&options, sal_op_get_to(op), + sal_op_get_from(op),sal_op_get_route(op)); + if (options){ + if (op->base.root->session_expires!=0){ + osip_message_set_header(options, "Session-expires", "200"); + osip_message_set_supported(options, "timer"); + } + sal_add_other(sal_op_get_sal(op),op,options); + return eXosip_options_send_request(options); + } + return -1; +} + int sal_refer(SalOp *h, const char *refer_to){ osip_message_t *msg=NULL; int err=0; @@ -518,11 +568,30 @@ void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){ } } +static void set_network_origin(SalOp *op, osip_message_t *req){ + const char *received=NULL; + int rport=5060; + char origin[64]; + if (extract_received_rport(req,&received,&rport)!=0){ + osip_via_t *via=NULL; + char *tmp; + osip_message_get_via(req,0,&via); + received=osip_via_get_host(via); + tmp=osip_via_get_port(via); + if (tmp) rport=atoi(tmp); + } + snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport); + __sal_op_set_network_origin(op,origin); +} + static void inc_new_call(Sal *sal, eXosip_event_t *ev){ SalOp *op=sal_op_new(sal); osip_from_t *from,*to; char *tmp; sdp_message_t *sdp=eXosip_get_sdp_info(ev->request); + + set_network_origin(op,ev->request); + if (sdp){ op->sdp_offering=FALSE; op->base.remote_media=sal_media_description_new(); @@ -613,22 +682,10 @@ static void handle_ack(Sal *sal, eXosip_event_t *ev){ } } -static int call_proceeding(Sal *sal, eXosip_event_t *ev){ - SalOp *op=(SalOp*)ev->external_reference; +static void update_contact_from_response(SalOp *op, osip_message_t *response){ const char *received; int rport; - - if (op==NULL) { - ms_warning("This call has been canceled."); - eXosip_lock(); - eXosip_call_terminate(ev->cid,ev->did); - eXosip_unlock(); - return -1; - } - op->did=ev->did; - op->tid=ev->tid; - /* update contact if received and rport are set by the server */ - if (extract_received_rport(ev->response,&received,&rport)==0){ + if (extract_received_rport(response,&received,&rport)==0){ const char *contact=sal_op_get_contact(op); if (!contact){ /*no contact given yet, use from instead*/ @@ -640,11 +697,29 @@ static int call_proceeding(Sal *sal, eXosip_event_t *ev){ sal_address_set_domain(addr,received); sal_address_set_port_int(addr,rport); tmp=sal_address_as_string(addr); - ms_message("Contact address automatically updated to %s for this call",tmp); + ms_message("Contact address updated to %s for this dialog",tmp); sal_op_set_contact(op,tmp); ms_free(tmp); } } +} + +static int call_proceeding(Sal *sal, eXosip_event_t *ev){ + SalOp *op=(SalOp*)ev->external_reference; + + if (op==NULL) { + ms_warning("This call has been canceled."); + eXosip_lock(); + eXosip_call_terminate(ev->cid,ev->did); + eXosip_unlock(); + return -1; + } + op->did=ev->did; + op->tid=ev->tid; + + /* update contact if received and rport are set by the server + note: will only be used by remote for next INVITE, if any...*/ + update_contact_from_response(op,ev->response); return 0; } @@ -668,6 +743,7 @@ static void call_accepted(Sal *sal, eXosip_event_t *ev){ osip_message_t *msg=NULL; SalOp *op; const char *contact; + op=(SalOp*)ev->external_reference; if (op==NULL){ ms_error("A closed call is accepted ?"); @@ -778,6 +854,7 @@ static SalOp *find_op(Sal *sal, eXosip_event_t *ev){ if (ev->rid>0){ return sal_find_register(sal,ev->rid); } + if (ev->response) return sal_find_other(sal,ev->response); return NULL; } @@ -1152,6 +1229,19 @@ static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){ return TRUE; } +static void other_request_reply(Sal *sal,eXosip_event_t *ev){ + SalOp *op=find_op(sal,ev); + + if (op==NULL){ + ms_warning("other_request_reply(): Receiving response to unknown request."); + return; + } + if (ev->response){ + update_contact_from_response(op,ev->response); + sal->callbacks.ping_reply(op); + } +} + static bool_t process_event(Sal *sal, eXosip_event_t *ev){ switch(ev->type){ case EXOSIP_CALL_ANSWERED: @@ -1242,6 +1332,13 @@ static bool_t process_event(Sal *sal, eXosip_event_t *ev){ case EXOSIP_MESSAGE_NEW: other_request(sal,ev); break; + case EXOSIP_MESSAGE_PROCEEDING: + case EXOSIP_MESSAGE_ANSWERED: + case EXOSIP_MESSAGE_REDIRECTED: + case EXOSIP_MESSAGE_SERVERFAILURE: + case EXOSIP_MESSAGE_GLOBALFAILURE: + other_request_reply(sal,ev); + break; case EXOSIP_MESSAGE_REQUESTFAILURE: if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){ return process_authentication(sal,ev); diff --git a/coreapi/sal_eXosip2.h b/coreapi/sal_eXosip2.h index 4e5d81240..226948134 100644 --- a/coreapi/sal_eXosip2.h +++ b/coreapi/sal_eXosip2.h @@ -34,6 +34,7 @@ struct Sal{ MSList *out_subscribes;/*MSList of SalOp */ MSList *in_subscribes;/*MSList of SalOp */ MSList *pending_auths;/*MSList of SalOp */ + MSList *other_transactions; /*MSList of SalOp */ int running; int session_expires; void *up; @@ -51,6 +52,8 @@ struct SalOp{ SalMediaDescription *result; sdp_message_t *sdp_answer; eXosip_event_t *pending_auth; + osip_call_id_t *call_id; /*used for out of calls transaction in order + to retrieve the operation when receiving a response*/ bool_t supports_session_timers; bool_t sdp_offering; bool_t reinvite; From 5346dfccb65f1b6f96ea620ec4d640436ed877e2 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 12 Mar 2010 18:57:23 +0100 Subject: [PATCH 3/8] up to date mediastreamer2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 2e18cdfe5..5bcbcae29 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 2e18cdfe53230763907f3f9b55adeb4c16d396a7 +Subproject commit 5bcbcae29d9cf6d22b4f6880489eafa98e100008 From 2097e06808d135a3b2cb01f93a3b6dcfeb921d36 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 15 Mar 2010 12:18:20 +0100 Subject: [PATCH 4/8] fix crash when calling set_play_file() while the call isn't yet established. --- coreapi/linphonecore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 3c3eb3598..1ed8b9428 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -3133,7 +3133,7 @@ void linphone_core_set_play_file(LinphoneCore *lc, const char *file){ } if (file!=NULL) { lc->play_file=ms_strdup(file); - if (lc->audiostream) + if (lc->audiostream->ticker) audio_stream_play(lc->audiostream,file); } } From a2f7044f34eb5ac085eccd801883e8c9a892be8e Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 15 Mar 2010 15:01:22 +0100 Subject: [PATCH 5/8] merge "Tabbed UI" patch from Emmanuel --- gtk-glade/incall_view.c | 45 +- gtk-glade/main.c | 13 +- gtk-glade/main.glade | 938 ++++++++++++++++++---------------------- mediastreamer2 | 2 +- 4 files changed, 462 insertions(+), 536 deletions(-) diff --git a/gtk-glade/incall_view.c b/gtk-glade/incall_view.c index 4d38dc988..1167c5ccd 100644 --- a/gtk-glade/incall_view.c +++ b/gtk-glade/incall_view.c @@ -38,18 +38,36 @@ gboolean linphone_gtk_use_in_call_view(){ void linphone_gtk_show_in_call_view(void){ GtkWidget *main_window=linphone_gtk_get_main_window(); - GtkWidget *idle_frame=linphone_gtk_get_widget(main_window,"idle_frame"); + GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(main_window,"viewswitch"); GtkWidget *in_call_frame=linphone_gtk_get_widget(main_window,"in_call_frame"); - gtk_widget_hide(idle_frame); + gint idx; + + /* Make the in call frame visible and arrange for the notebook to + show that page */ gtk_widget_show(in_call_frame); + idx = gtk_notebook_page_num(notebook, in_call_frame); + if (idx >= 0) { + gtk_notebook_set_current_page(notebook, idx); + } } void linphone_gtk_show_idle_view(void){ GtkWidget *main_window=linphone_gtk_get_main_window(); + GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(main_window,"viewswitch"); GtkWidget *idle_frame=linphone_gtk_get_widget(main_window,"idle_frame"); GtkWidget *in_call_frame=linphone_gtk_get_widget(main_window,"in_call_frame"); - gtk_widget_show(idle_frame); - gtk_widget_hide(in_call_frame); + gint idx; + + /* Switch back to the idle frame page, maybe we should have + remembered where we were in gtk_show_in_call_view() to switch + back to that page of the notebook, but this should do in most + cases. */ + gtk_widget_show(idle_frame); /* Make sure it is visible... */ + idx = gtk_notebook_page_num(notebook, idle_frame); + if (idx >= 0) { + gtk_notebook_set_current_page(notebook, idx); + gtk_widget_hide(in_call_frame); + } } void display_peer_name_in_label(GtkWidget *label, const char *uri){ @@ -91,13 +109,11 @@ void linphone_gtk_in_call_view_set_calling(const char *uri){ GtkWidget *duration=linphone_gtk_get_widget(main_window,"in_call_duration"); GtkWidget *animation=linphone_gtk_get_widget(main_window,"in_call_animation"); GdkPixbufAnimation *pbuf=create_pixbuf_animation("calling_anim.gif"); - GtkWidget *terminate_button=linphone_gtk_get_widget(main_window,"in_call_terminate"); - gtk_widget_set_sensitive(terminate_button,TRUE); gtk_label_set_markup(GTK_LABEL(status),_("Calling...")); display_peer_name_in_label(callee,uri); - gtk_label_set_text(GTK_LABEL(duration),"00:00:00"); + gtk_label_set_text(GTK_LABEL(duration),_("00::00::00")); if (pbuf!=NULL){ gtk_image_set_from_animation(GTK_IMAGE(animation),pbuf); g_object_unref(G_OBJECT(pbuf)); @@ -112,13 +128,11 @@ void linphone_gtk_in_call_view_set_in_call(){ GtkWidget *duration=linphone_gtk_get_widget(main_window,"in_call_duration"); GtkWidget *animation=linphone_gtk_get_widget(main_window,"in_call_animation"); GdkPixbufAnimation *pbuf=create_pixbuf_animation("incall_anim.gif"); - GtkWidget *terminate_button=linphone_gtk_get_widget(main_window,"in_call_terminate"); const LinphoneAddress *uri=linphone_core_get_remote_uri(lc); char *tmp=linphone_address_as_string(uri); display_peer_name_in_label(callee,tmp); ms_free(tmp); - gtk_widget_set_sensitive(terminate_button,TRUE); gtk_label_set_markup(GTK_LABEL(status),_("In call with")); gtk_label_set_text(GTK_LABEL(duration),_("00::00::00")); @@ -150,10 +164,8 @@ void linphone_gtk_in_call_view_terminate(const char *error_msg){ GtkWidget *main_window=linphone_gtk_get_main_window(); GtkWidget *status=linphone_gtk_get_widget(main_window,"in_call_status"); GtkWidget *animation=linphone_gtk_get_widget(main_window,"in_call_animation"); - GtkWidget *terminate_button=linphone_gtk_get_widget(main_window,"in_call_terminate"); GdkPixbuf *pbuf=create_pixbuf(linphone_gtk_get_ui_config("stop_call_icon","red.png")); - gtk_widget_set_sensitive(terminate_button,FALSE); if (error_msg==NULL) gtk_label_set_markup(GTK_LABEL(status),_("Call ended.")); else{ @@ -174,11 +186,17 @@ void linphone_gtk_draw_mute_button(GtkToggleButton *button, gboolean active){ if (active){ GtkWidget *image=create_pixmap("mic_muted.png"); gtk_button_set_label(GTK_BUTTON(button),_("Unmute")); - if (image!=NULL) gtk_button_set_image(GTK_BUTTON(button),image); + if (image!=NULL) { + gtk_button_set_image(GTK_BUTTON(button),image); + gtk_widget_show(image); + } }else{ GtkWidget *image=create_pixmap("mic_active.png"); gtk_button_set_label(GTK_BUTTON(button),_("Mute")); - if (image!=NULL) gtk_button_set_image(GTK_BUTTON(button),image); + if (image!=NULL) { + gtk_button_set_image(GTK_BUTTON(button),image); + gtk_widget_show(image); + } } } @@ -190,5 +208,6 @@ void linphone_gtk_mute_toggled(GtkToggleButton *button){ void linphone_gtk_enable_mute_button(GtkToggleButton *button, gboolean sensitive){ gtk_widget_set_sensitive(GTK_WIDGET(button),sensitive); + gtk_object_set(GTK_OBJECT(button),"gtk-button-images",TRUE,NULL); linphone_gtk_draw_mute_button(button,FALSE); } diff --git a/gtk-glade/main.c b/gtk-glade/main.c index 22062fac0..918be5545 100644 --- a/gtk-glade/main.c +++ b/gtk-glade/main.c @@ -552,7 +552,6 @@ void linphone_gtk_call_terminated(const char *error){ GtkWidget *icw; gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"terminate_call"),FALSE); gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"start_call"),TRUE); - gtk_widget_hide_all(linphone_gtk_get_widget(mw,"go_to_call_view_box")); linphone_gtk_enable_mute_button(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(mw,"main_mute")),FALSE); if (linphone_gtk_use_in_call_view()) linphone_gtk_in_call_view_terminate(error); @@ -576,7 +575,6 @@ static gboolean in_call_timer(){ static void linphone_gtk_call_started(GtkWidget *mw){ gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"start_call"),FALSE); gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"terminate_call"),TRUE); - gtk_widget_show_all(linphone_gtk_get_widget(mw,"go_to_call_view_box")); update_video_title(); if (linphone_gtk_use_in_call_view()) g_timeout_add(250,(GSourceFunc)in_call_timer,NULL); @@ -1062,7 +1060,6 @@ static void linphone_gtk_configure_main_window(){ if (stop_call_icon){ GdkPixbuf *pbuf=create_pixbuf(stop_call_icon); gtk_image_set_from_pixbuf(GTK_IMAGE(linphone_gtk_get_widget(w,"terminate_call_icon")),pbuf); - gtk_image_set_from_pixbuf(GTK_IMAGE(linphone_gtk_get_widget(w,"in_call_terminate_icon")),pbuf); g_object_unref(G_OBJECT(pbuf)); } if (search_icon){ @@ -1096,6 +1093,8 @@ void linphone_gtk_manage_login(void){ } static void linphone_gtk_init_main_window(){ + GtkWidget *main_window; + linphone_gtk_configure_main_window(); linphone_gtk_manage_login(); load_uri_history(); @@ -1104,10 +1103,14 @@ static void linphone_gtk_init_main_window(){ linphone_gtk_show_friends(); linphone_gtk_connect_digits(); linphone_gtk_check_menu_items(); - linphone_gtk_enable_mute_button(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(linphone_gtk_get_main_window(), + main_window=linphone_gtk_get_main_window(); + linphone_gtk_enable_mute_button(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(main_window, "main_mute")),FALSE); - linphone_gtk_enable_mute_button(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(linphone_gtk_get_main_window(), + linphone_gtk_enable_mute_button(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(main_window, "incall_mute")),FALSE); + if (!linphone_gtk_use_in_call_view()) { + gtk_widget_show(linphone_gtk_get_widget(main_window, "main_mute")); + } if (linphone_core_in_call(linphone_gtk_get_core())) linphone_gtk_call_started( linphone_gtk_get_main_window());/*hide the call button, show terminate button*/ } diff --git a/gtk-glade/main.glade b/gtk-glade/main.glade index 62d730f31..55fa4fb61 100644 --- a/gtk-glade/main.glade +++ b/gtk-glade/main.glade @@ -10,6 +10,7 @@ True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + vertical True @@ -219,12 +220,11 @@ True - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK vertical - + True @@ -365,281 +365,373 @@ - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + True - + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK vertical - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 12 - 12 + vertical - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - vertical + 0 - + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + 12 - + True GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Lookup: - - - 12 - 0 - - - - - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - - - 4 - 1 - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - in - - - 8 - 2 - - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - All users -Online users - - - - 4 - 3 - - - - - False - 0 - - - - - True - True - automatic - automatic - - - 120 - True - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - - - - - - - - - 1 - - - - - True - 0 - none - - - True + vertical - + True - True - - - - - + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + Lookup: + + + 12 + 0 + + + + + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + + 4 + 1 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + in + + + 8 + 2 + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + All users +Online users + + + + 4 + 3 + + + False 0 - + True True - True - none - + automatic + automatic - + + 120 + True + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + + + + + + + + + 1 + + + + + True + 0 + none + + True - + True - gtk-find + True + + + + + 0 - + True - Search + True + True + none + + + + True + + + True + gtk-find + + + 0 + + + + + True + Search + + + 1 + + + + + False 1 + + + True + <b>Add contacts from directory</b> + True + + + label_item + + False - 1 + False + 5 + 2 - - - True - <b>Add contacts from directory</b> - True - - - label_item - - + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + <b>Contact list</b> + True - False - False - 5 - 2 + label_item + + 8 + 0 + + + + + True + + + Mute + False + True + True + + + + False + 0 + + + + + False + False + 1 + + + + + + + True + Internet connection: + + + 0 + + + + + True + 0 + ADSL +Fiber Channel + + + + 1 + + + + + False + 2 + - - - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - <b>Contact list</b> - True - - label_item + 8 + 0 - 8 0 - + True - - Mute - False - True - True - + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + + + True + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 12 + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + Default + + + + + + 0 + + + + + True + True + True + + + + False + 1 + + + + + + + True + GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + My current identity: + True + + + label_item + + - False 0 False - False 1 - - - - - True - Internet connection: - - - 0 - - - - - True - 0 - ADSL -Fiber Channel - - - - 1 - - - - - False - 2 - - + + + + + True + Contacts - 8 - 0 + False + tab - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK vertical - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 + 0.5 + none True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK + 0 + 0 True @@ -647,6 +739,8 @@ Fiber Channel 4 4 4 + 20 + 10 True @@ -661,7 +755,7 @@ Fiber Channel 4 3 4 - + GTK_FILL @@ -678,7 +772,7 @@ Fiber Channel 3 3 4 - + GTK_FILL @@ -695,7 +789,7 @@ Fiber Channel 2 3 4 - + GTK_FILL @@ -710,7 +804,7 @@ Fiber Channel 3 4 - + GTK_FILL @@ -727,7 +821,7 @@ Fiber Channel 4 2 3 - + GTK_FILL @@ -744,7 +838,7 @@ Fiber Channel 3 2 3 - + GTK_FILL @@ -761,7 +855,7 @@ Fiber Channel 2 2 3 - + GTK_FILL @@ -776,7 +870,7 @@ Fiber Channel 2 3 - + GTK_FILL @@ -793,7 +887,7 @@ Fiber Channel 4 1 2 - + GTK_FILL @@ -810,7 +904,7 @@ Fiber Channel 3 1 2 - + GTK_FILL @@ -827,7 +921,7 @@ Fiber Channel 2 1 2 - + GTK_FILL @@ -842,7 +936,7 @@ Fiber Channel 1 2 - + GTK_FILL @@ -857,7 +951,7 @@ Fiber Channel 3 4 - + GTK_FILL @@ -872,7 +966,7 @@ Fiber Channel 2 3 - + GTK_FILL @@ -887,7 +981,7 @@ Fiber Channel 1 2 - + GTK_FILL @@ -900,7 +994,7 @@ Fiber Channel GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - + GTK_FILL @@ -909,85 +1003,154 @@ Fiber Channel - - True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - Digits - True - + label_item - False - False 0 + + + - False - False 1 - - - 1 - - - - - True - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 + Keypad + + + 1 + False + tab + + + + + 0.5 + none - + True + 12 + 12 - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 12 + vertical - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - 0 - Default - + gtk-info + 5 + + 0 + + + + + True + 0 + + + True + label + center + + + + + True + True + + + label_item + + + + + 1 + + + + + True + 0 + + + True + vertical + + + True + Duration + center + + + 0 + + + + + + + True + Duration: + True + + + label_item + + + + + False + 2 + + + + + True + + + Mute + True + False + True + True + + + + False + False + 0 + + + + + False + False + 3 + - - 0 - - - - - True - True - True - - - - False - 1 - - + True - GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK - My current identity: + In call True + center label_item @@ -995,57 +1158,23 @@ Fiber Channel - 0 + 2 - - - False - 2 - - - - - - True - True - - - - True - - - True - gtk-go-forward - - - 0 - - - - - True - Show current call - - - 1 - - - - + + True + Call Details - False - False - 8 - end - 0 + 2 + False + tab - 3 + 1 @@ -1053,231 +1182,6 @@ Fiber Channel 0 - - - 0.5 - - - True - 12 - 12 - - - True - vertical - - - True - gtk-info - 5 - - - 0 - - - - - True - 0 - - - True - label - center - - - - - True - True - - - label_item - - - - - 1 - - - - - True - 0 - - - True - vertical - - - True - Duration - center - - - 0 - - - - - - - True - Duration: - True - - - label_item - - - - - False - 2 - - - - - True - - - Mute - True - False - True - True - - - - False - False - 0 - - - - - False - False - 3 - - - - - True - center - - - True - True - True - - - - True - - - True - gtk-close - 3 - - - 0 - - - - - True - <b>Terminate call</b> - True - - - 1 - - - - - - - False - False - 0 - - - - - 8 - 4 - - - - - True - center - - - True - True - True - - - - True - - - True - gtk-go-back - 1 - - - 0 - - - - - True - Main view - - - 1 - - - - - - - False - False - end - 0 - - - - - False - False - 5 - - - - - - - - - True - In call - True - center - - - label_item - - - - - 1 - - 0 @@ -1445,7 +1349,7 @@ Fiber Channel - 2 + 1 diff --git a/mediastreamer2 b/mediastreamer2 index 2e18cdfe5..5bcbcae29 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 2e18cdfe53230763907f3f9b55adeb4c16d396a7 +Subproject commit 5bcbcae29d9cf6d22b4f6880489eafa98e100008 From 52fe995acb9c07e6e5632dffa438c18ebab37f4c Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 16 Mar 2010 10:50:54 +0100 Subject: [PATCH 6/8] start to fix bugs for presence support. --- coreapi/friend.c | 2 ++ coreapi/sal_eXosip2.c | 2 +- coreapi/sal_eXosip2_presence.c | 11 ++++++----- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index 080dffb4e..a4ca54840 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -141,8 +141,10 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){ if (fr->outsub==NULL){ /* people for which we don't have yet an answer should appear as offline */ fr->status=LINPHONE_STATUS_OFFLINE; + /* if (fr->lc->vtable.notify_recv) fr->lc->vtable.notify_recv(fr->lc,(LinphoneFriend*)fr); + */ }else{ sal_op_release(fr->outsub); fr->outsub=NULL; diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index cf6074db5..f8a45edb9 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -1310,7 +1310,7 @@ static bool_t process_event(Sal *sal, eXosip_event_t *ev){ sal_exosip_notify_recv(sal,ev); break; case EXOSIP_SUBSCRIPTION_ANSWERED: - ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i\n",ev->sid); + ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did); sal_exosip_subscription_answered(sal,ev); break; case EXOSIP_SUBSCRIPTION_CLOSED: diff --git a/coreapi/sal_eXosip2_presence.c b/coreapi/sal_eXosip2_presence.c index d4ab7ba41..f6c85b5f2 100644 --- a/coreapi/sal_eXosip2_presence.c +++ b/coreapi/sal_eXosip2_presence.c @@ -122,7 +122,8 @@ int sal_unsubscribe(SalOp *op){ if (msg){ osip_message_set_expires(msg,"0"); eXosip_subscribe_send_refresh_request(op->did,msg); - }else ms_error("Could not build subscribe refresh request !"); + }else ms_error("Could not build subscribe refresh request ! op->sid=%i, op->did=%i", + op->sid,op->did); eXosip_unlock(); return 0; } @@ -130,8 +131,8 @@ int sal_unsubscribe(SalOp *op){ int sal_subscribe_accept(SalOp *op){ osip_message_t *msg; eXosip_lock(); - eXosip_insubscription_build_answer(op->tid,202,&msg); - eXosip_insubscription_send_answer(op->tid,202,msg); + eXosip_insubscription_build_answer(op->tid,200,&msg); + eXosip_insubscription_send_answer(op->tid,200,msg); eXosip_unlock(); return 0; } @@ -636,8 +637,6 @@ void sal_exosip_notify_recv(Sal *sal, eXosip_event_t *ev){ osip_from_to_str(from,&tmp); if (strstr(body->body,"pending")!=NULL){ estatus=SalPresenceOffline; - }else if ((strstr(body->body,"online")!=NULL) || (strstr(body->body,"open")!=NULL)) { - estatus=SalPresenceOnline; }else if (strstr(body->body,"busy")!=NULL){ estatus=SalPresenceBusy; }else if (strstr(body->body,"berightback")!=NULL @@ -653,6 +652,8 @@ void sal_exosip_notify_recv(Sal *sal, eXosip_event_t *ev){ estatus=SalPresenceOuttolunch; }else if (strstr(body->body,"closed")!=NULL){ estatus=SalPresenceOffline; + }else if ((strstr(body->body,"online")!=NULL) || (strstr(body->body,"open")!=NULL)) { + estatus=SalPresenceOnline; }else{ estatus=SalPresenceOffline; } From 7593b0073c01a188fb94b149c4d9afe746ac26bc Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 16 Mar 2010 11:55:30 +0100 Subject: [PATCH 7/8] fix several bug in presence support again. --- coreapi/friend.c | 7 ++++++- coreapi/linphonecore.c | 4 ++-- coreapi/private.h | 2 +- coreapi/sal_eXosip2.c | 6 ++++++ coreapi/sal_eXosip2.h | 3 +++ coreapi/sal_eXosip2_presence.c | 30 +++++++----------------------- 6 files changed, 25 insertions(+), 27 deletions(-) diff --git a/coreapi/friend.c b/coreapi/friend.c index a4ca54840..68f43e659 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -299,13 +299,18 @@ static void linphone_friend_unsubscribe(LinphoneFriend *lf){ } } -void linphone_friend_destroy(LinphoneFriend *lf){ +void linphone_friend_close_subscriptions(LinphoneFriend *lf){ linphone_friend_notify(lf,LINPHONE_STATUS_OFFLINE); linphone_friend_unsubscribe(lf); if (lf->insub){ sal_notify_close(lf->insub); sal_op_release(lf->insub); + lf->insub=NULL; } +} + +void linphone_friend_destroy(LinphoneFriend *lf){ + if (lf->uri!=NULL) linphone_address_destroy(lf->uri); if (lf->info!=NULL) buddy_info_free(lf->info); ms_free(lf); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index ddb09892c..f699a2a3e 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1392,7 +1392,6 @@ int linphone_core_get_sip_port(LinphoneCore *lc) return lc->sip_conf.sip_port; } -static bool_t exosip_running=FALSE; static char _ua_name[64]="Linphone"; static char _ua_version[64]=LINPHONE_VERSION; @@ -3389,6 +3388,8 @@ static void linphone_core_uninit(LinphoneCore *lc) linphone_core_iterate(lc); } } + if (lc->friends) + ms_list_for_each(lc->friends,(void (*)(void *))linphone_friend_close_subscriptions); gstate_new_state(lc, GSTATE_POWER_SHUTDOWN, NULL); #ifdef VIDEO_ENABLED if (lc->previewstream!=NULL){ @@ -3412,7 +3413,6 @@ static void linphone_core_uninit(LinphoneCore *lc) linphone_core_free_payload_types(); ortp_exit(); - exosip_running=FALSE; gstate_new_state(lc, GSTATE_POWER_OFF, NULL); } diff --git a/coreapi/private.h b/coreapi/private.h index 84b4d0778..cbb767207 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -101,7 +101,7 @@ void linphone_core_refresh_subscribes(LinphoneCore *lc); int linphone_proxy_config_send_publish(LinphoneProxyConfig *cfg, LinphoneOnlineStatus os); int linphone_online_status_to_eXosip(LinphoneOnlineStatus os); - +void linphone_friend_close_subscriptions(LinphoneFriend *lf); void linphone_friend_notify(LinphoneFriend *lf, LinphoneOnlineStatus os); LinphoneFriend *linphone_find_friend_by_inc_subscribe(MSList *l, SalOp *op); LinphoneFriend *linphone_find_friend_by_out_subscribe(MSList *l, SalOp *op); diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index f8a45edb9..5f337b3fa 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -153,6 +153,12 @@ void sal_op_release(SalOp *op){ ms_message("Cleaning cid %i",op->cid); eXosip_call_set_reference(op->cid,NULL); } + if (op->sid!=-1){ + sal_remove_out_subscribe(op->base.root,op); + } + if (op->nid!=-1){ + sal_remove_in_subscribe(op->base.root,op); + } if (op->pending_auth){ sal_remove_pending_auth(op->base.root,op); } diff --git a/coreapi/sal_eXosip2.h b/coreapi/sal_eXosip2.h index 226948134..6539dcae8 100644 --- a/coreapi/sal_eXosip2.h +++ b/coreapi/sal_eXosip2.h @@ -59,6 +59,9 @@ struct SalOp{ bool_t reinvite; }; +void sal_remove_out_subscribe(Sal *sal, SalOp *op); +void sal_remove_in_subscribe(Sal *sal, SalOp *op); + void sal_exosip_subscription_recv(Sal *sal, eXosip_event_t *ev); void sal_exosip_subscription_answered(Sal *sal,eXosip_event_t *ev); void sal_exosip_notify_recv(Sal *sal,eXosip_event_t *ev); diff --git a/coreapi/sal_eXosip2_presence.c b/coreapi/sal_eXosip2_presence.c index f6c85b5f2..11104b8d1 100644 --- a/coreapi/sal_eXosip2_presence.c +++ b/coreapi/sal_eXosip2_presence.c @@ -35,16 +35,8 @@ static void sal_add_out_subscribe(Sal *sal, SalOp *op){ sal->out_subscribes=ms_list_append(sal->out_subscribes,op); } -static void sal_remove_out_subscribe(Sal *sal, int sid){ - MSList *elem; - SalOp *op; - for(elem=sal->out_subscribes;elem!=NULL;elem=elem->next){ - op=(SalOp*)elem->data; - if (op->sid==sid) { - sal->out_subscribes=ms_list_remove_link(sal->out_subscribes,elem); - return; - } - } +void sal_remove_out_subscribe(Sal *sal, SalOp *op){ + sal->out_subscribes=ms_list_remove(sal->out_subscribes,op); } static SalOp * sal_find_in_subscribe(Sal *sal, int nid){ @@ -61,16 +53,8 @@ static void sal_add_in_subscribe(Sal *sal, SalOp *op){ sal->in_subscribes=ms_list_append(sal->in_subscribes,op); } -static void sal_remove_in_subscribe(Sal *sal, int nid){ - MSList *elem; - SalOp *op; - for(elem=sal->in_subscribes;elem!=NULL;elem=elem->next){ - op=(SalOp*)elem->data; - if (op->nid==nid) { - sal->in_subscribes=ms_list_remove_link(sal->in_subscribes,elem); - return; - } - } +void sal_remove_in_subscribe(Sal *sal, SalOp *op){ + sal->in_subscribes=ms_list_remove(sal->in_subscribes,op); } int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg){ @@ -659,7 +643,7 @@ void sal_exosip_notify_recv(Sal *sal, eXosip_event_t *ev){ } ms_message("We are notified that %s has online status %i",tmp,estatus); if (ev->ss_status==EXOSIP_SUBCRSTATE_TERMINATED) { - sal_remove_out_subscribe(sal,op->sid); + sal_remove_out_subscribe(sal,op); op->sid=-1; op->did=-1; ms_message("And outgoing subscription terminated by remote."); @@ -683,9 +667,9 @@ void sal_exosip_subscription_closed(Sal *sal,eXosip_event_t *ev){ ms_error("Subscription closed but no associated op !"); return; } - sal_remove_in_subscribe(sal,op->nid); + sal_remove_in_subscribe(sal,op); op->nid=-1; - op->did=0; + op->did=-1; } From 308b63c9ce5d1e32c94ae64b25dc7e25ce24d3b7 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 16 Mar 2010 12:35:40 +0100 Subject: [PATCH 8/8] add new api "linphone_core_interpret_url" --- coreapi/chat.c | 6 +-- coreapi/linphonecore.c | 76 +++++++++++++++++----------------- coreapi/linphonecore.h | 4 ++ coreapi/private.h | 1 - coreapi/sal_eXosip2_presence.c | 2 +- 5 files changed, 45 insertions(+), 44 deletions(-) diff --git a/coreapi/chat.c b/coreapi/chat.c index 11c3c978f..c1a884964 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -27,13 +27,13 @@ LinphoneChatRoom * linphone_core_create_chat_room(LinphoneCore *lc, const char *to){ LinphoneAddress *parsed_url=NULL; - char *route; - if (linphone_core_interpret_url(lc,to,&parsed_url,&route)){ + + if ((parsed_url=linphone_core_interpret_url(lc,to))!=NULL){ LinphoneChatRoom *cr=ms_new0(LinphoneChatRoom,1); cr->lc=lc; cr->peer=linphone_address_as_string(parsed_url); cr->peer_url=parsed_url; - cr->route=route; + cr->route=ms_strdup(linphone_core_get_route(lc)); lc->chatrooms=ms_list_append(lc->chatrooms,(void *)cr); return cr; } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index f699a2a3e..230776bda 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1678,32 +1678,25 @@ void linphone_core_iterate(LinphoneCore *lc){ } -bool_t linphone_core_interpret_url(LinphoneCore *lc, const char *url, LinphoneAddress **real_parsed_url, char **route){ +LinphoneAddress * linphone_core_interpret_url(LinphoneCore *lc, const char *url){ enum_lookup_res_t *enumres=NULL; - LinphoneAddress *parsed_url=NULL; char *enum_domain=NULL; LinphoneProxyConfig *proxy=lc->default_proxy;; char *tmpurl; - const char *tmproute; LinphoneAddress *uri; - if (real_parsed_url!=NULL) *real_parsed_url=NULL; - *route=NULL; - tmproute=linphone_core_get_route(lc); - if (is_enum(url,&enum_domain)){ lc->vtable.display_status(lc,_("Looking for telephone number destination...")); if (enum_lookup(enum_domain,&enumres)<0){ lc->vtable.display_status(lc,_("Could not resolve this number.")); ms_free(enum_domain); - return FALSE; + return NULL; } ms_free(enum_domain); tmpurl=enumres->sip_address[0]; - if (real_parsed_url!=NULL) *real_parsed_url=linphone_address_new(tmpurl); + uri=linphone_address_new(tmpurl); enum_lookup_res_free(enumres); - if (tmproute) *route=ms_strdup(tmproute); - return TRUE; + return uri; } /* check if we have a "sip:" */ if (strstr(url,"sip:")==NULL){ @@ -1714,8 +1707,7 @@ bool_t linphone_core_interpret_url(LinphoneCore *lc, const char *url, LinphoneAd uri=linphone_address_new(tmpurl); ms_free(tmpurl); if (uri){ - if (real_parsed_url!=NULL) *real_parsed_url=uri; - return TRUE; + return uri; } } @@ -1725,31 +1717,24 @@ bool_t linphone_core_interpret_url(LinphoneCore *lc, const char *url, LinphoneAd char normalized_username[128]; uri=linphone_address_new(identity); if (uri==NULL){ - return FALSE; + return NULL; } linphone_address_set_display_name(uri,NULL); linphone_proxy_config_normalize_number(proxy,url,normalized_username, sizeof(normalized_username)); linphone_address_set_username(uri,normalized_username); - - if (real_parsed_url!=NULL) *real_parsed_url=uri; - if (tmproute) *route=ms_strdup(tmproute); - return TRUE; - }else return FALSE; + return uri; + }else return NULL; } - parsed_url=linphone_address_new(url); - if (parsed_url!=NULL){ - if (real_parsed_url!=NULL) *real_parsed_url=parsed_url; - else linphone_address_destroy(parsed_url); - if (tmproute) *route=ms_strdup(tmproute); - - return TRUE; + uri=linphone_address_new(url); + if (uri!=NULL){ + return uri; } /* else we could not do anything with url given by user, so display an error */ if (lc->vtable.display_warning!=NULL){ lc->vtable.display_warning(lc,_("Could not parse given sip address. A sip url usually looks like sip:user@domain")); } - return FALSE; + return NULL; } /** @@ -1890,16 +1875,32 @@ int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, LinphonePro * * @ingroup call_control * @param lc the LinphoneCore object + * @param url the destination of the call (sip address, or phone number). +**/ +int linphone_core_invite(LinphoneCore *lc, const char *url){ + LinphoneAddress *addr=linphone_core_interpret_url(lc,url); + if (addr){ + int err=linphone_core_invite_address(lc,addr); + linphone_address_destroy(addr); + return err; + } + return -1; +} + +/** + * Initiates an outgoing call given a destination LinphoneAddress + * + * @ingroup call_control + * @param lc the LinphoneCore object * @param url the destination of the call (sip address). **/ -int linphone_core_invite(LinphoneCore *lc, const char *url) +int linphone_core_invite_address(LinphoneCore *lc, const LinphoneAddress *real_parsed_url) { int err=0; - char *route=NULL; + const char *route=NULL; const char *from=NULL; LinphoneProxyConfig *proxy=NULL; LinphoneAddress *parsed_url2=NULL; - LinphoneAddress *real_parsed_url=NULL; char *real_url=NULL; LinphoneProxyConfig *dest_proxy=NULL; LinphoneCall *call; @@ -1910,9 +1911,8 @@ int linphone_core_invite(LinphoneCore *lc, const char *url) } linphone_core_get_default_proxy(lc,&proxy); - if (!linphone_core_interpret_url(lc,url,&real_parsed_url,&route)){ - return -1; - } + route=linphone_core_get_route(lc); + real_url=linphone_address_as_string(real_parsed_url); dest_proxy=linphone_core_lookup_known_proxy(lc,real_parsed_url); @@ -1931,7 +1931,7 @@ int linphone_core_invite(LinphoneCore *lc, const char *url) parsed_url2=linphone_address_new(from); - call=linphone_call_new_outgoing(lc,parsed_url2,real_parsed_url); + call=linphone_call_new_outgoing(lc,parsed_url2,linphone_address_clone(real_parsed_url)); sal_op_set_route(call->op,route); lc->call=call; @@ -1946,21 +1946,19 @@ int linphone_core_invite(LinphoneCore *lc, const char *url) } if (real_url!=NULL) ms_free(real_url); - if (route!=NULL) ms_free(route); return err; } int linphone_core_refer(LinphoneCore *lc, const char *url) { char *real_url=NULL; - LinphoneAddress *real_parsed_url=NULL; + LinphoneAddress *real_parsed_url=linphone_core_interpret_url(lc,url); LinphoneCall *call; - char *route; - if (!linphone_core_interpret_url(lc,url,&real_parsed_url, &route)){ + + if (!real_parsed_url){ /* bad url */ return -1; } - if (route!=NULL) ms_free(route); call=lc->call; if (call==NULL){ ms_warning("No established call to refer."); diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 56c34c0a2..2006453b3 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -467,8 +467,12 @@ LinphoneCore *linphone_core_new(const LinphoneCoreVTable *vtable, /* function to be periodically called in a main loop */ void linphone_core_iterate(LinphoneCore *lc); +LinphoneAddress * linphone_core_interpret_url(LinphoneCore *lc, const char *url); + int linphone_core_invite(LinphoneCore *lc, const char *url); +int linphone_core_invite_address(LinphoneCore *lc, const LinphoneAddress *addr); + int linphone_core_refer(LinphoneCore *lc, const char *url); bool_t linphone_core_inc_invite_pending(LinphoneCore*lc); diff --git a/coreapi/private.h b/coreapi/private.h index cbb767207..4125936ff 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -177,7 +177,6 @@ void linphone_core_start_media_streams(LinphoneCore *lc, struct _LinphoneCall *c void linphone_core_stop_media_streams(LinphoneCore *lc, struct _LinphoneCall *call); 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); diff --git a/coreapi/sal_eXosip2_presence.c b/coreapi/sal_eXosip2_presence.c index 11104b8d1..760d8fd8d 100644 --- a/coreapi/sal_eXosip2_presence.c +++ b/coreapi/sal_eXosip2_presence.c @@ -424,7 +424,7 @@ int sal_notify_close(SalOp *op){ if (identity==NULL) identity=sal_op_get_to(op); osip_message_set_contact(msg,identity); eXosip_insubscription_send_request(op->did,msg); - }else ms_error("could not create notify for incoming subscription."); + }else ms_error("sal_notify_close(): could not create notify for incoming subscription."); eXosip_unlock(); return 0; }