diff --git a/console/commands.c b/console/commands.c index d52a0e8402024fe4b3850a3d466cd974d1f248b0..3de69279ba8f2205db411f8789299138f24246bf 100644 --- a/console/commands.c +++ b/console/commands.c @@ -381,7 +381,7 @@ lpc_cmd_call(LinphoneCore *lc, char *args) } else { - if ( -1 == linphone_core_invite(lc, args) ) + if ( NULL == linphone_core_invite(lc, args) ) { linphonec_out("Error from linphone_core_invite.\n"); } @@ -438,7 +438,7 @@ static int lpc_cmd_refer(LinphoneCore *lc, char *args) { if (args) - linphone_core_refer(lc, args); + linphone_core_refer(lc, linphone_core_get_current_call(lc), args); else{ linphonec_out("refer needs an argument\n"); } diff --git a/console/linphonec.c b/console/linphonec.c index 2d1ce98b31640c079acac2d24c5b4973fd20973b..c4ca4484074185ccf5dedac1b39fa08fb5439380 100644 --- a/console/linphonec.c +++ b/console/linphonec.c @@ -112,7 +112,7 @@ static char **linephonec_readline_completion(const char *text, #endif /* These are callback for linphone core */ -static void linphonec_call_received(LinphoneCore *lc, const char *from); +static void linphonec_call_received(LinphoneCore *lc, LinphoneCall *call); static void linphonec_prompt_for_auth(LinphoneCore *lc, const char *realm, const char *username); static void linphonec_display_refer (LinphoneCore * lc,const char *refer_to); @@ -124,7 +124,7 @@ static void linphonec_notify_received(LinphoneCore *lc,const char *from,const ch static void linphonec_notify_presence_received(LinphoneCore *lc,LinphoneFriend *fid); static void linphonec_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url); -static void linphonec_bye_received(LinphoneCore *lc, const char *from); +static void linphonec_bye_received(LinphoneCore *lc, LinphoneCall *call); static void linphonec_text_received(LinphoneCore *lc, LinphoneChatRoom *cr, const char *from, const char *msg); static void linphonec_display_status (LinphoneCore * lc, const char *something); @@ -259,9 +259,11 @@ linphonec_display_url (LinphoneCore * lc, const char *something, const char *url * Linphone core callback */ static void -linphonec_call_received(LinphoneCore *lc, const char *from) +linphonec_call_received(LinphoneCore *lc, LinphoneCall *call) { + char *from=linphone_call_get_remote_address_as_string(call); linphonec_set_caller(from); + ms_free(from); if ( auto_answer) { answer_call=TRUE; } @@ -336,7 +338,7 @@ linphonec_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, * Linphone core callback */ static void -linphonec_bye_received(LinphoneCore *lc, const char *from) +linphonec_bye_received(LinphoneCore *lc, LinphoneCall *call) { // Should change prompt back to original maybe diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index 014ae308e0398d154b22e3feabb51b6b1e7c6901..b497c1ea1817bca30c99393cd1ca72b6715a9151 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -33,6 +33,7 @@ liblinphone_la_SOURCES=\ lpconfig.c lpconfig.h \ chat.c \ general_state.c \ + linphonecall.c \ sipsetup.c sipsetup.h \ siplogin.c diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index cdb18042875508d214f1f1b46e0fe0eb29e5b00e..044469d2d885deee57fdb32bf442577d81cbdf71 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -30,7 +30,7 @@ static void linphone_connect_incoming(LinphoneCore *lc, LinphoneCall *call){ lc->vtable.show(lc); if (lc->vtable.display_status) lc->vtable.display_status(lc,_("Connected.")); - call->state=LCStateAVRunning; + call->state=LinphoneCallAVRunning; if (lc->ringstream!=NULL){ ring_stop(lc->ringstream); lc->ringstream=NULL; @@ -82,7 +82,7 @@ static void call_received(SalOp *h){ sal_media_description_ref(call->resultdesc); if (call->resultdesc && sal_media_description_empty(call->resultdesc)){ sal_call_decline(h,SalReasonMedia,NULL); - linphone_call_destroy(call); + linphone_call_unref(call); lc->call=NULL; return; } @@ -103,10 +103,10 @@ static void call_received(SalOp *h){ ms_message("Starting local ring..."); lc->ringstream=ring_start(lc->sound_conf.local_ring,2000,lc->sound_conf.ring_sndcard); } - linphone_call_set_state(call,LCStateRinging); + call->state=LinphoneCallRinging; sal_call_notify_ringing(h); linphone_core_init_media_streams(lc,lc->call); - if (lc->vtable.inv_recv) lc->vtable.inv_recv(lc,tmp); + if (lc->vtable.inv_recv) lc->vtable.inv_recv(lc,call); ms_free(barmesg); ms_free(tmp); } @@ -146,7 +146,7 @@ static void call_ringing(SalOp *h){ linphone_core_start_media_streams(lc,call); call->media_pending=TRUE; } - call->state=LCStateRinging; + call->state=LinphoneCallRinging; } static void call_accepted(SalOp *op){ @@ -160,7 +160,7 @@ static void call_accepted(SalOp *op){ ms_warning("call_accepted: ignoring."); return; } - if (call->state==LCStateAVRunning){ + if (call->state==LinphoneCallAVRunning){ return ; /*already accepted*/ } if (lc->audiostream->ticker!=NULL){ @@ -234,7 +234,8 @@ static void call_updated(SalOp *op){ static void call_terminated(SalOp *op, const char *from){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); - if (sal_op_get_user_pointer(op)!=lc->call){ + LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op); + if (linphone_call_get_state(call)==LinphoneCallTerminated){ ms_warning("call_terminated: ignoring."); return; } @@ -246,17 +247,18 @@ static void call_terminated(SalOp *op, const char *from){ linphone_core_stop_media_streams(lc,lc->call); lc->vtable.show(lc); lc->vtable.display_status(lc,_("Call terminated.")); + linphone_call_set_terminated(call); gstate_new_state(lc, GSTATE_CALL_END, NULL); if (lc->vtable.bye_recv!=NULL){ LinphoneAddress *addr=linphone_address_new(from); char *tmp; linphone_address_clean(addr); tmp=linphone_address_as_string(addr); - lc->vtable.bye_recv(lc,tmp); + lc->vtable.bye_recv(lc,call); ms_free(tmp); linphone_address_destroy(addr); } - linphone_call_destroy(lc->call); + linphone_call_unref(call); lc->call=NULL; } @@ -330,7 +332,7 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de } linphone_core_stop_media_streams(lc,call); if (call!=NULL) { - linphone_call_destroy(call); + linphone_call_set_terminated(call); if (sr!=SalReasonDeclined) gstate_new_state(lc, GSTATE_CALL_ERROR, msg); else gstate_new_state(lc, GSTATE_CALL_END, NULL); lc->call=NULL; @@ -446,7 +448,7 @@ 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){ + if (call->state==LinphoneCallPreEstablishing){ linphone_core_start_invite(call->core,call,NULL); } } diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c new file mode 100644 index 0000000000000000000000000000000000000000..6df039221705fe9a25a9b4aaf224ca2293d71453 --- /dev/null +++ b/coreapi/linphonecall.c @@ -0,0 +1,208 @@ + +/* +linphone +Copyright (C) 2010 Belledonne Communications SARL + (simon.morlat@linphone.org) + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +*/ + +#include "linphonecore.h" +#include "sipsetup.h" +#include "lpconfig.h" +#include "private.h" + + + + +static MSList *make_codec_list(LinphoneCore *lc, 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) && linphone_core_check_payload_type_usability(lc,pt)){ + 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, bool_t only_one_codec){ + 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)); + md->bandwidth=linphone_core_get_download_bandwidth(lc); + /*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; + md->streams[0].ptime=lc->net_conf.down_ptime; + l=make_codec_list(lc,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; + + 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,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; + } + return md; +} + +static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, LinphoneAddress *to){ + call->refcnt=1; + call->state=LinphoneCallInit; + call->start_time=time(NULL); + call->media_start_time=0; + call->log=linphone_call_log_new(call, from, to); + linphone_core_notify_all_friends(call->core,LINPHONE_STATUS_ONTHEPHONE); + if (linphone_core_get_firewall_policy(call->core)==LINPHONE_POLICY_USE_STUN) + linphone_core_run_stun_tests(call->core,call); +} + +static void discover_mtu(LinphoneCore *lc, const char *remote){ + int mtu; + if (lc->net_conf.mtu==0 ){ + /*attempt to discover mtu*/ + mtu=ms_discover_mtu(remote); + if (mtu>0){ + ms_set_mtu(mtu); + ms_message("Discovered mtu is %i, RTP payload max size is %i", + mtu, ms_get_payload_max_size()); + } + } +} + +LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to) +{ + LinphoneCall *call=ms_new0(LinphoneCall,1); + call->dir=LinphoneCallOutgoing; + call->op=sal_op_new(lc->sal); + sal_op_set_user_pointer(call->op,call); + call->core=lc; + linphone_core_get_local_ip(lc,linphone_address_get_domain(to),call->localip); + call->localdesc=create_local_media_description (lc,call->localip, + linphone_address_get_username(from),FALSE); + linphone_call_init_common(call,from,to); + discover_mtu(lc,linphone_address_get_domain (to)); + return call; +} + +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),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); + return call; +} + +void linphone_call_set_terminated(LinphoneCall *call){ + LinphoneCallStatus status=LinphoneCallAborted; + if (call->state==LinphoneCallAVRunning){ + status=LinphoneCallSuccess; + } + linphone_call_log_completed(call->log,call, status); + call->state=LinphoneCallTerminated; +} + +static void linphone_call_destroy(LinphoneCall *obj) +{ + linphone_core_notify_all_friends(obj->core,obj->core->prev_mode); + + linphone_core_update_allocated_audio_bandwidth(obj->core); + 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); +} + +void linphone_call_ref(LinphoneCall *obj){ + obj->refcnt++; +} + +void linphone_call_unref(LinphoneCall *obj){ + obj->refcnt--; + if (obj->refcnt==0) + linphone_call_destroy(obj); +} + +bool_t linphone_call_paused(LinphoneCall *call){ + return call->state==LinphoneCallPaused; +} + +const LinphoneAddress * linphone_call_get_remote_address(const LinphoneCall *call){ + return call->dir==LinphoneCallIncoming ? call->log->from : call->log->to; +} + +char *linphone_call_get_remote_address_as_string(const LinphoneCall *call){ + return linphone_address_as_string(linphone_call_get_remote_address(call)); +} + +LinphoneCallState linphone_call_get_state(const LinphoneCall *call){ + return call->state; +} + diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index eb2a58f935d0a4d493715bb346d793417236734e..2c084433a64241a8bf728b826d6573646c227e9b 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -62,150 +62,6 @@ int lc_callback_obj_invoke(LCCallbackObj *obj, LinphoneCore *lc){ return 0; } - -static MSList *make_codec_list(LinphoneCore *lc, 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) && linphone_core_check_payload_type_usability(lc,pt)){ - 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, bool_t only_one_codec){ - 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)); - md->bandwidth=linphone_core_get_download_bandwidth(lc); - /*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; - md->streams[0].ptime=lc->net_conf.down_ptime; - l=make_codec_list(lc,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; - - 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,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; - } - 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; - call->log=linphone_call_log_new(call, from, to); - linphone_core_notify_all_friends(call->core,LINPHONE_STATUS_ONTHEPHONE); - if (linphone_core_get_firewall_policy(call->core)==LINPHONE_POLICY_USE_STUN) - linphone_core_run_stun_tests(call->core,call); -} - -static void discover_mtu(LinphoneCore *lc, const char *remote){ - int mtu; - if (lc->net_conf.mtu==0 ){ - /*attempt to discover mtu*/ - mtu=ms_discover_mtu(remote); - if (mtu>0){ - ms_set_mtu(mtu); - ms_message("Discovered mtu is %i, RTP payload max size is %i", - mtu, ms_get_payload_max_size()); - } - } -} - -LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to) -{ - LinphoneCall *call=ms_new0(LinphoneCall,1); - call->dir=LinphoneCallOutgoing; - call->op=sal_op_new(lc->sal); - sal_op_set_user_pointer(call->op,call); - call->core=lc; - linphone_core_get_local_ip(lc,linphone_address_get_domain(to),call->localip); - call->localdesc=create_local_media_description (lc,call->localip, - linphone_address_get_username(from),FALSE); - linphone_call_init_common(call,from,to); - discover_mtu(lc,linphone_address_get_domain (to)); - return call; -} - -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),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); - return call; -} - -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); - 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); -} - /*prevent a gcc bug with %c*/ static size_t my_strftime(char *s, size_t max, const char *fmt, const struct tm *tm){ #if !defined(_WIN32_WCE) @@ -294,32 +150,20 @@ static void call_logs_read_from_config_file(LinphoneCore *lc){ } -void linphone_call_log_completed(LinphoneCallLog *calllog, LinphoneCall *call){ +void linphone_call_log_completed(LinphoneCallLog *calllog, LinphoneCall *call, LinphoneCallStatus status){ LinphoneCore *lc=call->core; calllog->duration=time(NULL)-call->start_time; - switch(call->state){ - case LCStateInit: - case LCStatePreEstablishing: - calllog->status=LinphoneCallAborted; - break; - case LCStateRinging: - if (calllog->dir==LinphoneCallIncoming){ - char *info; - calllog->status=LinphoneCallMissed; - lc->missed_calls++; - info=ortp_strdup_printf(ngettext("You have missed %i call.", - "You have missed %i calls.", lc->missed_calls), - lc->missed_calls); - lc->vtable.display_status(lc,info); - ms_free(info); - } - else calllog->status=LinphoneCallAborted; - break; - case LCStateAVRunning: - calllog->status=LinphoneCallSuccess; - break; - } + + if (status==LinphoneCallMissed){ + char *info; + lc->missed_calls++; + info=ortp_strdup_printf(ngettext("You have missed %i call.", + "You have missed %i calls.", lc->missed_calls), + lc->missed_calls); + lc->vtable.display_status(lc,info); + ms_free(info); + }else calllog->status=status; lc->call_logs=ms_list_prepend(lc->call_logs,(void *)calllog); if (ms_list_size(lc->call_logs)>lc->max_call_logs){ MSList *elem,*prevelem=NULL; @@ -443,10 +287,10 @@ int linphone_core_get_current_call_duration(const LinphoneCore *lc){ return time(NULL)-call->media_start_time; } -const LinphoneAddress *linphone_core_get_remote_uri(LinphoneCore *lc){ +const LinphoneAddress *linphone_core_get_remote_address(LinphoneCore *lc){ LinphoneCall *call=lc->call; if (call==NULL) return 0; - return call->dir==LinphoneCallIncoming ? call->log->from : call->log->to; + return linphone_call_get_remote_address(call); } /** @@ -1652,17 +1496,18 @@ void linphone_core_iterate(LinphoneCore *lc){ if (lc->call!=NULL){ LinphoneCall *call=lc->call; - if (call->state==LCStatePreEstablishing && (curtime-call->start_time>=2)){ + if (call->state==LinphoneCallPreEstablishing && (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){ + if (call->dir==LinphoneCallIncoming && call->state==LinphoneCallRinging){ elapsed=curtime-call->start_time; ms_message("incoming call ringing for %i seconds",elapsed); if (elapsed>lc->sip_conf.inc_timeout){ + call->log->status=LinphoneCallMissed; linphone_core_terminate_call(lc,NULL); } - }else if (call->state==LCStateAVRunning){ + }else if (call->state==LinphoneCallAVRunning){ if (one_second_elapsed){ RtpSession *as=NULL,*vs=NULL; lc->prevtime=curtime; @@ -1807,7 +1652,7 @@ bool_t linphone_core_is_in_communication_with(LinphoneCore *lc, const char *to) { char *tmp; bool_t returned; - const LinphoneAddress *la=linphone_core_get_remote_uri(lc); + const LinphoneAddress *la=linphone_core_get_remote_address(lc); if(la == NULL) { return FALSE; @@ -1897,7 +1742,7 @@ int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, LinphonePro sal_op_set_contact(call->op, contact); ms_free(contact); } - call->state=LCStateInit; + call->state=LinphoneCallInit; linphone_core_init_media_streams(lc,lc->call); if (!lc->sip_conf.sdp_200_ack){ call->media_pending=TRUE; @@ -1919,7 +1764,7 @@ int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, LinphonePro 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); + linphone_call_unref(call); lc->call=NULL; }else gstate_new_state(lc, GSTATE_CALL_OUT_INVITE, real_url); ms_free(real_url); @@ -1934,15 +1779,15 @@ int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, LinphonePro * @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){ +LinphoneCall * linphone_core_invite(LinphoneCore *lc, const char *url){ LinphoneAddress *addr=linphone_core_interpret_url(lc,url); if (addr){ - int err; - err=linphone_core_invite_address(lc,addr); + LinphoneCall *call; + call=linphone_core_invite_address(lc,addr); linphone_address_destroy(addr); - return err; + return call; } - return -1; + return NULL; } /** @@ -1952,7 +1797,7 @@ int linphone_core_invite(LinphoneCore *lc, const char *url){ * @param lc the LinphoneCore object * @param url the destination of the call (sip address). **/ -int linphone_core_invite_address(LinphoneCore *lc, const LinphoneAddress *real_parsed_url) +LinphoneCall * linphone_core_invite_address(LinphoneCore *lc, const LinphoneAddress *real_parsed_url) { int err=0; const char *route=NULL; @@ -1965,7 +1810,7 @@ int linphone_core_invite_address(LinphoneCore *lc, const LinphoneAddress *real_p if (lc->call!=NULL){ lc->vtable.display_warning(lc,_("Sorry, having multiple simultaneous calls is not supported yet !")); - return -1; + return NULL; } linphone_core_get_default_proxy(lc,&proxy); @@ -1997,27 +1842,25 @@ int linphone_core_invite_address(LinphoneCore *lc, const LinphoneAddress *real_p err=linphone_core_start_invite(lc,call,dest_proxy); }else{ /*defer the start of the call after the OPTIONS ping*/ - call->state=LCStatePreEstablishing; + call->state=LinphoneCallPreEstablishing; 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); - return err; + return call; } -int linphone_core_refer(LinphoneCore *lc, const char *url) +int linphone_core_refer(LinphoneCore *lc, LinphoneCall *call, const char *url) { char *real_url=NULL; LinphoneAddress *real_parsed_url=linphone_core_interpret_url(lc,url); - LinphoneCall *call; if (!real_parsed_url){ /* bad url */ return -1; } - call=lc->call; if (call==NULL){ ms_warning("No established call to refer."); return -1; @@ -2291,7 +2134,7 @@ void linphone_core_start_media_streams(LinphoneCore *lc, LinphoneCall *call){ end: ms_free(cname); linphone_address_destroy(me); - lc->call->state=LCStateAVRunning; + lc->call->state=LinphoneCallAVRunning; } void linphone_core_stop_media_streams(LinphoneCore *lc, LinphoneCall *call){ @@ -2341,9 +2184,8 @@ void linphone_core_stop_media_streams(LinphoneCore *lc, LinphoneCall *call){ * however this feature is not supported yet. * Using NULL will accept the unique incoming call in progress. **/ -int linphone_core_accept_call(LinphoneCore *lc, const char *url) +int linphone_core_accept_call(LinphoneCore *lc, LinphoneCall *call) { - LinphoneCall *call=lc->call; LinphoneProxyConfig *cfg=NULL; const char *contact=NULL; @@ -2351,7 +2193,7 @@ int linphone_core_accept_call(LinphoneCore *lc, const char *url) return -1; } - if (call->state==LCStateAVRunning){ + if (call->state==LinphoneCallAVRunning){ /*call already accepted*/ return -1; } @@ -2390,9 +2232,8 @@ int linphone_core_accept_call(LinphoneCore *lc, const char *url) * @param url the destination of the call to be terminated, use NULL if there is * only one call (which is case in this version of liblinphone). **/ -int linphone_core_terminate_call(LinphoneCore *lc, const char *url) +int linphone_core_terminate_call(LinphoneCore *lc, LinphoneCall *call) { - LinphoneCall *call=lc->call; if (call==NULL){ return -1; } @@ -2407,10 +2248,17 @@ int linphone_core_terminate_call(LinphoneCore *lc, const char *url) linphone_core_stop_media_streams(lc,call); lc->vtable.display_status(lc,_("Call ended") ); gstate_new_state(lc, GSTATE_CALL_END, NULL); - linphone_call_destroy(call); + linphone_call_set_terminated(call); + linphone_call_unref(call); return 0; } + +int linphone_core_terminate_all_calls(LinphoneCore *lc){ + /* TODO */ + return -1; +} + /** * Returns TRUE if there is a call running or pending. * @@ -2433,6 +2281,21 @@ struct _LinphoneCall *linphone_core_get_current_call(LinphoneCore *lc) return NULL; } +int linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call){ + /* TODO */ + return -1; +} + +int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *call){ + /* TODO */ + return -1; +} + +LinphoneCall *linphone_core_get_call_by_remote_address(LinphoneCore *lc){ + /* TODO */ + return NULL; +} + int linphone_core_send_publish(LinphoneCore *lc, LinphoneOnlineStatus presence_mode) { diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 945ea25eaa321191d2678d0b65c69b48dc27538a..81d82627b2d49e34dcaa03fcd7c4ad379fa3ed6e 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -85,8 +85,24 @@ struct _SipSetupContext; struct _LinphoneCall; typedef struct _LinphoneCall LinphoneCall; -bool_t linphone_call_asked_to_autoanswer(struct _LinphoneCall *call); - +typedef enum _LinphoneCallState{ + LinphoneCallInit, + LinphoneCallPreEstablishing, + LinphoneCallRinging, + LinphoneCallAVRunning, + LinphoneCallPaused, + LinphoneCallTerminated +}LinphoneCallState; + +LinphoneCallState linphone_call_get_state(const LinphoneCall *call); +bool_t linphone_call_asked_to_autoanswer(LinphoneCall *call); +bool_t linphone_call_paused(LinphoneCall *call); +const LinphoneAddress * linphone_call_get_remote_address(const LinphoneCall *call); +char *linphone_call_get_remote_address_as_string(const LinphoneCall *call); +void linphone_call_ref(LinphoneCall *call); +void linphone_call_unref(LinphoneCall *call); + + /** * Enum representing the direction of a call. * @ingroup call_logs @@ -377,9 +393,9 @@ void gstate_initialize(struct _LinphoneCore *lc) ; /** Callback prototype */ typedef void (*ShowInterfaceCb)(struct _LinphoneCore *lc); /** Callback prototype */ -typedef void (*InviteReceivedCb)(struct _LinphoneCore *lc, const char *from); +typedef void (*InviteReceivedCb)(struct _LinphoneCore *lc, LinphoneCall *call); /** Callback prototype */ -typedef void (*ByeReceivedCb)(struct _LinphoneCore *lc, const char *from); +typedef void (*ByeReceivedCb)(struct _LinphoneCore *lc, LinphoneCall *call); /** Callback prototype */ typedef void (*DisplayStatusCb)(struct _LinphoneCore *lc, const char *message); /** Callback prototype */ @@ -481,11 +497,11 @@ 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); +LinphoneCall * linphone_core_invite(LinphoneCore *lc, const char *url); -int linphone_core_invite_address(LinphoneCore *lc, const LinphoneAddress *addr); +LinphoneCall * linphone_core_invite_address(LinphoneCore *lc, const LinphoneAddress *addr); -int linphone_core_refer(LinphoneCore *lc, const char *url); +int linphone_core_refer(LinphoneCore *lc, LinphoneCall *call, const char *url); bool_t linphone_core_inc_invite_pending(LinphoneCore*lc); @@ -493,9 +509,17 @@ bool_t linphone_core_in_call(const LinphoneCore *lc); LinphoneCall *linphone_core_get_current_call(LinphoneCore *lc); -int linphone_core_accept_call(LinphoneCore *lc, const char *url); +int linphone_core_accept_call(LinphoneCore *lc, LinphoneCall *call); + +int linphone_core_terminate_call(LinphoneCore *lc, LinphoneCall *call); + +int linphone_core_terminate_all_calls(LinphoneCore *lc); + +int linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call); + +int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *call); -int linphone_core_terminate_call(LinphoneCore *lc, const char *url); +LinphoneCall *linphone_core_get_call_by_remote_address(LinphoneCore *lc); void linphone_core_send_dtmf(LinphoneCore *lc,char dtmf); @@ -741,7 +765,7 @@ void linphone_core_set_record_file(LinphoneCore *lc, const char *file); gstate_t linphone_core_get_state(const LinphoneCore *lc, gstate_group_t group); int linphone_core_get_current_call_duration(const LinphoneCore *lc); -const LinphoneAddress *linphone_core_get_remote_uri(LinphoneCore *lc); +const LinphoneAddress *linphone_core_get_remote_address(LinphoneCore *lc); int linphone_core_get_mtu(const LinphoneCore *lc); void linphone_core_set_mtu(LinphoneCore *lc, int mtu); diff --git a/coreapi/private.h b/coreapi/private.h index 4a3c1dbaa3bd33ce0c818b14a5da5a4901f19b51..b672f46785fa2824d00cd92d7e1115b34f4a446d 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -54,12 +54,7 @@ #endif #endif -typedef enum _LCState{ - LCStateInit, - LCStatePreEstablishing, - LCStateRinging, - LCStateAVRunning -}LCState; + struct _LinphoneCall @@ -76,18 +71,18 @@ struct _LinphoneCall 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*/ - LCState state; + LinphoneCallState state; + int refcnt; bool_t media_pending; }; LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to); 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); +void linphone_call_set_terminated(LinphoneCall *call); /* private: */ LinphoneCallLog * linphone_call_log_new(LinphoneCall *call, LinphoneAddress *local, LinphoneAddress * remote); -void linphone_call_log_completed(LinphoneCallLog *calllog, LinphoneCall *call); +void linphone_call_log_completed(LinphoneCallLog *calllog, LinphoneCall *call, LinphoneCallStatus status); void linphone_call_log_destroy(LinphoneCallLog *cl); diff --git a/gtk-glade/incall_view.c b/gtk-glade/incall_view.c index c3c95eabebb2984a202414dd94c4b5a9bdb8661c..0dcc5506c20f5c8429ad3be69349665be8019eb6 100644 --- a/gtk-glade/incall_view.c +++ b/gtk-glade/incall_view.c @@ -128,7 +128,7 @@ 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"); - const LinphoneAddress *uri=linphone_core_get_remote_uri(lc); + const LinphoneAddress *uri=linphone_core_get_remote_address(lc); char *tmp=linphone_address_as_string(uri); display_peer_name_in_label(callee,tmp); ms_free(tmp); diff --git a/gtk-glade/main.c b/gtk-glade/main.c index 364accbb34141dc21b6a564348238836efea4f0e..d4b0876daeeffecb149807eeec02edb7373458e4 100644 --- a/gtk-glade/main.c +++ b/gtk-glade/main.c @@ -42,8 +42,8 @@ static LinphoneCore *the_core=NULL; static GtkWidget *the_ui=NULL; static void linphone_gtk_show(LinphoneCore *lc); -static void linphone_gtk_inv_recv(LinphoneCore *lc, const char *from); -static void linphone_gtk_bye_recv(LinphoneCore *lc, const char *from); +static void linphone_gtk_inv_recv(LinphoneCore *lc, LinphoneCall *call); +static void linphone_gtk_bye_recv(LinphoneCore *lc, LinphoneCall *call); static void linphone_gtk_notify_recv(LinphoneCore *lc, LinphoneFriend * fid); static void linphone_gtk_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url); static void linphone_gtk_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username); @@ -390,7 +390,7 @@ static void set_video_window_decorations(GdkWindow *w){ gdk_window_set_keep_above(w, FALSE); }else{ LinphoneAddress *uri = - linphone_address_clone(linphone_core_get_remote_uri(linphone_gtk_get_core())); + linphone_address_clone(linphone_core_get_remote_address(linphone_gtk_get_core())); char *display_name; linphone_address_clean(uri); @@ -704,10 +704,11 @@ static void linphone_gtk_show(LinphoneCore *lc){ linphone_gtk_show_main_window(); } -static void linphone_gtk_inv_recv(LinphoneCore *lc, const char *from){ +static void linphone_gtk_inv_recv(LinphoneCore *lc, LinphoneCall *call){ GtkWidget *w=linphone_gtk_create_window("incoming_call"); GtkWidget *label; gchar *msg; + char *from=linphone_call_get_remote_address_as_string(call); if (auto_answer){ g_timeout_add(2000,(GSourceFunc)linphone_gtk_auto_answer,w); @@ -727,9 +728,10 @@ static void linphone_gtk_inv_recv(LinphoneCore *lc, const char *from){ g_object_set_data(G_OBJECT(linphone_gtk_get_main_window()),"incoming_call",w); gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar")), from); + ms_free(from); } -static void linphone_gtk_bye_recv(LinphoneCore *lc, const char *from){ +static void linphone_gtk_bye_recv(LinphoneCore *lc, LinphoneCall *call){ }