]> sjero.net Git - linphone/commitdiff
merge patch from aurel
authorSimon Morlat <simon.morlat@linphone.org>
Fri, 21 May 2010 12:58:03 +0000 (14:58 +0200)
committerSimon Morlat <simon.morlat@linphone.org>
Fri, 21 May 2010 12:58:03 +0000 (14:58 +0200)
console/linphonec.c
coreapi/callbacks.c
coreapi/linphonecore.c
coreapi/linphonecore.h
coreapi/sal_eXosip2.c
mediastreamer2
oRTP

index 86187ad7cceafc4ec65ddf00e9e885a93d0b9428..024075cf06843a0f3e9f288fc9bff4e390b6dcf3 100644 (file)
@@ -123,6 +123,8 @@ static void linphonec_display_url (LinphoneCore * lc, const char *something, con
 static void linphonec_display_warning (LinphoneCore * lc, const char *something);
 static void stub () {}
 static void linphonec_notify_received(LinphoneCore *lc,const char *from,const char *msg);
+static void linphonec_ack_paused_received(LinphoneCore *lc, LinphoneCall *call);
+static void linphonec_ack_resumed_received(LinphoneCore *lc, LinphoneCall *call);
 static void linphonec_notify_presence_received(LinphoneCore *lc,LinphoneFriend *fid);
 static void linphonec_new_unknown_subscriber(LinphoneCore *lc,
                LinphoneFriend *lf, const char *url);
@@ -185,6 +187,8 @@ LinphoneCoreVTable linphonec_vtable
        .paused_recv = linphonec_paused_received,
        .resumed_recv = linphonec_resumed_received,
        .notify_recv = linphonec_notify_received,
+       .ack_paused_recv = linphonec_ack_paused_received,
+       .ack_resumed_recv = linphonec_ack_resumed_received,
        .notify_presence_recv = linphonec_notify_presence_received,
        .new_unknown_subscriber = linphonec_new_unknown_subscriber,
        .auth_info_requested = linphonec_prompt_for_auth,
@@ -344,6 +348,34 @@ linphonec_notify_received(LinphoneCore *lc,const char *from,const char *msg)
        }
 }
 
+/*
+ * Linphone core callback
+ */
+static void
+linphonec_ack_paused_received(LinphoneCore *lc, LinphoneCall *call)
+{
+       char *from=linphone_call_get_remote_address_as_string(call);
+       if(from)
+       {
+               linphonec_out("the previous pause sent to %s has been acknowledged\n",from);
+               ms_free(from);
+       }
+}
+
+/*
+ * Linphone core callback
+ */
+static void
+linphonec_ack_resumed_received(LinphoneCore *lc, LinphoneCall *call)
+{
+       char *from=linphone_call_get_remote_address_as_string(call);
+       if(from)
+       {
+               linphonec_out("the previous resume sent to %s has been acknowledged\n",from);
+               ms_free(from);
+       }
+}
+
 /*
  * Linphone core callback
  */
index 67611e2e32ed4946b7cd8c9b1126efa8c8bc8d81..1af84c194131735b10daaffafb3df59e6e917ead 100644 (file)
@@ -37,6 +37,10 @@ static void linphone_connect_incoming(LinphoneCore *lc, LinphoneCall *call){
                ring_stop(lc->ringstream);
                lc->ringstream=NULL;
        }
+       if(!linphone_core_in_call(lc))
+       {
+               linphone_core_set_as_current_call(lc,call);
+       }
        if(call == linphone_core_get_current_call(lc))
                linphone_core_start_media_streams(lc,call);
 }
@@ -114,8 +118,15 @@ static void call_received(SalOp *h){
 
        /* play the ring */
        if (lc->sound_conf.ring_sndcard!=NULL && !linphone_core_in_call(lc)){
-               ms_message("Starting local ring...");
-               lc->ringstream=ring_start(lc->sound_conf.local_ring,2000,lc->sound_conf.ring_sndcard);
+               if(lc->ringstream==NULL)
+               {
+                       ms_message("Starting local ring...");
+                       lc->ringstream=ring_start(lc->sound_conf.local_ring,2000,lc->sound_conf.ring_sndcard);
+               }
+               else
+               {
+                       ms_message("the local ring is already started");
+               }
        }
        call->state=LinphoneCallRinging;
        sal_call_notify_ringing(h);
@@ -166,6 +177,11 @@ static void call_ringing(SalOp *h){
        call->state=LinphoneCallRinging;
 }
 
+/*
+ * could be reach :
+ *  - when the call is accepted
+ *  - when a request is accepted (pause, resume)
+ */
 static void call_accepted(SalOp *op){
        LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
        LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
@@ -174,7 +190,10 @@ static void call_accepted(SalOp *op){
                return ;
        }
        if (call->state==LinphoneCallAVRunning){
-               return ; /*already accepted*/
+               ms_message("GET ACK of resume\n");
+               if(lc->vtable.ack_resumed_recv)
+                       lc->vtable.ack_resumed_recv(lc,call);
+               return ; //already accepted
        }
        if ((lc->audiostream!=NULL) && (lc->audiostream->ticker!=NULL)){
                /*case where we accepted early media */
@@ -192,8 +211,18 @@ static void call_accepted(SalOp *op){
                call->media_pending=FALSE;
        }
        if (call->resultdesc && !sal_media_description_empty(call->resultdesc)){
-               gstate_new_state(lc, GSTATE_CALL_OUT_CONNECTED, NULL);
-               linphone_connect_incoming(lc,call);
+               //if we initiate a pause
+               if(call->state == LinphoneCallPaused)
+               {
+                       ms_message("GET ACK of pause\n");
+                       if(lc->vtable.ack_paused_recv)
+                               lc->vtable.ack_paused_recv(lc,call);
+               }//if there is an accepted incoming call
+               else
+               {
+                       gstate_new_state(lc, GSTATE_CALL_OUT_CONNECTED, NULL);
+                       linphone_connect_incoming(lc,call);
+               }               
        }else{
                /*send a bye*/
                ms_error("Incompatible SDP offer received in 200Ok, need to abort the call");
@@ -289,7 +318,8 @@ static void call_terminated(SalOp *op, const char *from){
                return;
        }
        ms_message("Current call terminated...");
-       if (lc->ringstream!=NULL) {
+       //we stop the call only if we have this current call or if we are in call
+       if (lc->ringstream!=NULL && ( (ms_list_size(lc->calls)  == 1) || linphone_core_in_call(lc) )) {
                ring_stop(lc->ringstream);
                lc->ringstream=NULL;
        }
@@ -501,6 +531,10 @@ static void ping_reply(SalOp *op){
                        linphone_core_start_invite(call->core,call,NULL);
                }
        }
+       else
+       {
+               ms_warning("ping reply without call attached...");
+       }
 }
 
 SalCallbacks linphone_sal_callbacks={
index 5f7ae7afa7a5a61c8b800e9088226416f81073e1..e45a1213c832fa0de4edf517b5e2ae7a43a7c6e3 100644 (file)
@@ -1359,9 +1359,22 @@ static void display_bandwidth(RtpSession *as, RtpSession *vs){
        (vs!=NULL) ? (rtp_session_compute_send_bandwidth(vs)*1e-3) : 0);
 }
 
-static void linphone_core_disconnected(LinphoneCore *lc){
-       lc->vtable.display_warning(lc,_("Remote end seems to have disconnected, the call is going to be closed."));
-       linphone_core_terminate_call(lc,NULL);
+static void linphone_core_disconnected(LinphoneCore *lc, LinphoneCall *call){
+       char temp[256];
+       char *from;
+       if(call)
+               from = linphone_call_get_remote_address_as_string(call);
+       if(from)
+       {
+               snprintf(temp,sizeof(temp),"Remote end %s seems to have disconnected, the call is going to be closed.",from);
+               free(from);
+       }               
+       else
+       {
+               snprintf(temp,sizeof(temp),"Remote end seems to have disconnected, the call is going to be closed.");
+       }
+       lc->vtable.display_warning(lc,temp);
+       linphone_core_terminate_call(lc,call);//TODO failure ??
 }
 
 static void monitor_network_state(LinphoneCore *lc, time_t curtime){
@@ -1477,6 +1490,8 @@ static void linphone_core_do_plugin_tasks(LinphoneCore *lc){
  * serialized with a mutex.
 **/
 void linphone_core_iterate(LinphoneCore *lc){
+       MSList *the_call;
+       LinphoneCall *call;
        int disconnect_timeout = linphone_core_get_nortp_timeout(lc);
        time_t curtime=time(NULL);
        int elapsed;
@@ -1499,21 +1514,35 @@ void linphone_core_iterate(LinphoneCore *lc){
        if (lc->auto_net_state_mon) monitor_network_state(lc,curtime);
 
        proxy_update(lc);
-       LinphoneCall *call = linphone_core_get_current_call(lc);
-       if(call){
+
+       //we have to iterate for each call
+       the_call = lc->calls;
+       while(the_call != NULL)
+       {
+               call = (LinphoneCall *)the_call->data;
                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==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);
+                               /*start the call even if the OPTIONS reply did not arrive*/
+                               linphone_core_start_invite(lc,call,NULL);
                        }
-               }else if (call->state==LinphoneCallAVRunning){
-                       if (one_second_elapsed){
+                       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,call);
+                               }
+                       }
+
+               the_call = the_call->next;
+       }//end while
+       //and consider the current call
+       call = linphone_core_get_current_call(lc);
+       if(call)
+       {
+               if (call->state==LinphoneCallAVRunning)
+               {
+                       if (one_second_elapsed)
+                       {
                                RtpSession *as=NULL,*vs=NULL;
                                lc->prevtime=curtime;
                                if (lc->audiostream!=NULL)
@@ -1541,7 +1570,7 @@ void linphone_core_iterate(LinphoneCore *lc){
                        toggle_video_preview(lc,FALSE);
        }
        if (disconnected)
-               linphone_core_disconnected(lc);
+               linphone_core_disconnected(lc,call);
 
        linphone_core_do_plugin_tasks(lc);
 
@@ -1749,7 +1778,9 @@ int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, LinphonePro
                ms_free(contact);
        }
        call->state=LinphoneCallInit;
-       linphone_core_init_media_streams(lc,call);
+       //TODO : should probably not be done here
+       if(!    linphone_core_in_call(lc) )
+               linphone_core_init_media_streams(lc,call);
        if (!lc->sip_conf.sdp_200_ack){ 
                call->media_pending=TRUE;
                sal_call_set_local_media_description(call->op,call->localdesc);
@@ -1852,7 +1883,6 @@ LinphoneCall * linphone_core_invite_address(LinphoneCore *lc, const LinphoneAddr
                linphone_call_unref(call);
                return NULL;
        }
-       linphone_core_set_as_current_call(lc,call);
        if (dest_proxy!=NULL || lc->sip_conf.ping_with_options==FALSE){
                err=linphone_core_start_invite(lc,call,dest_proxy);
        }else{
@@ -1904,6 +1934,9 @@ bool_t linphone_core_inc_invite_pending(LinphoneCore*lc){
 }
 
 void linphone_core_init_media_streams(LinphoneCore *lc, LinphoneCall *call){
+#ifdef PRINTF_DEBUG
+       printf("%s(%d)\n",__FUNCTION__,__LINE__);
+#endif
        SalMediaDescription *md=call->localdesc;
        lc->audiostream=audio_stream_new(md->streams[0].port,linphone_core_ipv6_enabled(lc));
        if (linphone_core_echo_limiter_enabled(lc)){
@@ -2064,10 +2097,22 @@ static RtpProfile *make_profile(LinphoneCore *lc, const SalMediaDescription *md,
 }
 
 void linphone_core_start_media_streams(LinphoneCore *lc, LinphoneCall *call){
+#ifdef PRINTF_DEBUG
+       printf("%s(%d)\n",__FUNCTION__,__LINE__);
+#endif
        LinphoneAddress *me=linphone_core_get_primary_contact_parsed(lc);
        const char *tool="linphone-" LINPHONE_VERSION;
        char *cname;
        int used_pt=-1;
+       if(lc->audiostream == NULL)
+       {
+               ms_warning("init media stream is needed before starting");
+               linphone_core_init_media_streams(lc,call);
+               /*
+                * example of problem :
+                * 2 incomings calls, you answer and pause one, afterward if you try to answer the other call you will get SEGFAULT
+                */
+       }
        /* adjust rtp jitter compensation. It must be at least the latency of the sound card */
        int jitt_comp=MAX(lc->sound_conf.latency,lc->rtp_conf.audio_jitt_comp);
 
@@ -2157,6 +2202,9 @@ void linphone_core_start_media_streams(LinphoneCore *lc, LinphoneCall *call){
 }
 
 void linphone_core_stop_media_streams(LinphoneCore *lc, LinphoneCall *call){
+#ifdef PRINTF_DEBUG
+       printf("%s(%d)\n",__FUNCTION__,__LINE__);
+#endif
        if (lc->audiostream!=NULL) {
                audio_stream_stop(lc->audiostream);
                lc->audiostream=NULL;
@@ -2297,13 +2345,10 @@ int linphone_core_terminate_call(LinphoneCore *lc, LinphoneCall *the_call)
  * @param lc The LinphoneCore
 **/
 int linphone_core_terminate_all_calls(LinphoneCore *lc){
-       MSList *calls;
-
-       calls = lc->calls;
-       while(calls->next != NULL)
+       while(lc->calls)
        {
-               linphone_core_terminate_call(lc,(LinphoneCall *)calls->data);
-               calls = calls->next;
+               LinphoneCall *the_call = lc->calls->data;
+               linphone_core_terminate_call(lc,the_call);
        }
        ms_list_free(lc->calls);
        return -1;
@@ -2370,10 +2415,15 @@ int linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *the_call)
                ms_error("The call asked to be paused was not the current on\n");
                return -3;
        }
-       sal_call_hold(call->op,TRUE);
+       if(sal_call_hold(call->op,TRUE) != 0)
+       {
+               lc->vtable.display_warning(lc,_("Could not pause the call"));
+       }
        call->state = LinphoneCallPaused;
        linphone_core_unset_the_current_call(lc);
        linphone_core_stop_media_streams(lc,call);
+       //have to be done ... because if another call is incoming before this pause, you will get sound on the end point paused
+       linphone_core_init_media_streams(lc,call);
        lc->vtable.display_status(lc,_("Pause the current call"));
        return 0;
 }
@@ -2407,13 +2457,21 @@ int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *the_call)
                        return -2;
                }
        }
+       if(call->state ==  LinphoneCallInit || call->state ==  LinphoneCallPreEstablishing || call->state ==  LinphoneCallRinging )
+       {
+               ms_warning("we cannot resume a call when the communication is not established");
+               return -3;
+       }
        if(linphone_core_get_current_call(lc) != NULL)
        {
                ms_error("There is already a call in process pause or stop it first\n");
-               return -3;
+               return -4;
        }
        linphone_core_init_media_streams(lc,call);
-       sal_call_hold(call->op,FALSE);
+       if(sal_call_hold(call->op,FALSE) != 0)
+       {
+               lc->vtable.display_warning(lc,_("Could not resume the call"));
+       }
        call->state = LinphoneCallAVRunning;
        linphone_core_set_as_current_call(lc,call);
        linphone_core_start_media_streams(lc,call);
@@ -3544,18 +3602,18 @@ LpConfig *linphone_core_get_config(LinphoneCore *lc){
 
 static void linphone_core_uninit(LinphoneCore *lc)
 {
-       if(linphone_core_get_calls_nb(lc)){
-               int i;
-               linphone_core_terminate_all_calls(lc);
-               for(i=0;i<10;++i){
-#ifndef WIN32
-                       usleep(50000);
+       while(lc->calls)
+       {
+               LinphoneCall *the_call = lc->calls->data;
+               linphone_core_terminate_call(lc,the_call);
+               linphone_core_iterate(lc);
+#ifdef WIN32
+               Sleep(50000);
 #else
-                       Sleep(50);
+               usleep(50000);
 #endif
-                       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);
index 5c250731f2c2884ff23e253655b603e424ad7502..d7ac4abcc2c53c6e8c993810e93854c13598c7f9 100644 (file)
@@ -408,6 +408,10 @@ typedef void (*PausedReceivedCb)(struct _LinphoneCore *lc, LinphoneCall *call);
 /** Callback prototype */
 typedef void (*ResumedReceivedCb)(struct _LinphoneCore *lc, LinphoneCall *call);
 /** Callback prototype */
+typedef void (*AckPausedReceivedCb)(struct _LinphoneCore *lc, LinphoneCall *call);
+/** Callback prototype */
+typedef void (*AckResumedReceivedCb)(struct _LinphoneCore *lc, LinphoneCall *call);
+/** Callback prototype */
 typedef void (*DisplayStatusCb)(struct _LinphoneCore *lc, const char *message);
 /** Callback prototype */
 typedef void (*DisplayMessageCb)(struct _LinphoneCore *lc, const char *message);
@@ -450,8 +454,10 @@ typedef struct _LinphoneVTable
        RingingReceivedCb ringing_recv; /**< Notify that the distant phone is ringing*/
        ConnectedReceivedCb connected_recv; /**< Notify that the distant phone answered the call*/
        FailureReceivedCb failure_recv; /**< Notify that the call failed*/
-       PausedReceivedCb paused_recv; /**< Notify that the call failed*/
-       ResumedReceivedCb resumed_recv; /**< Notify that the call failed*/
+       PausedReceivedCb paused_recv; /**< Notify that the call has been paused*/
+       ResumedReceivedCb resumed_recv; /**< Notify that the call has been resumed*/
+       AckPausedReceivedCb ack_paused_recv;/**< Notify that the previous command pause sent to the call has been acknowledge*/
+       AckResumedReceivedCb ack_resumed_recv;/**< Notify that the previous command resumed sent to the call has been acknowledge*/     
        NotifyPresenceReceivedCb notify_presence_recv; /**< Notify received presence events*/
        NewUnknownSubscriberCb new_unknown_subscriber; /**< Notify about unknown subscriber */
        AuthInfoRequested auth_info_requested; /**< Ask the application some authentication information */
index 94a51fa2405458a5a53c5b4c442e0435a770a317..6091f18dbaa7ccd214751846eba1d40f4b31358a 100644 (file)
@@ -1427,6 +1427,9 @@ static void other_request_reply(Sal *sal,eXosip_event_t *ev){
 }
 
 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
+#ifdef PRINTF_DEBUG
+       printf("EVENT (%d)\n",ev->type);
+#endif
        ms_message("linphone process event get a message %d\n",ev->type);
        switch(ev->type){
                case EXOSIP_CALL_ANSWERED:
@@ -1716,7 +1719,10 @@ int sal_call_hold(SalOp *h, bool_t holdon)
        int err=0;
 
        osip_message_t *reinvite;
-       eXosip_call_build_request(h->did,"INVITE",&reinvite);
+       if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != OSIP_SUCCESS)
+               return -1;
+       if(reinvite==NULL)
+               return -2;
        osip_message_set_subject(reinvite,osip_strdup("Phone Call Hold"));
        osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
        if (h->base.root->session_expires!=0){
index d45f8e79e37c1754e8f09c1f299cef1a57db66f6..57896d513f6fbf41fde3c777931ebc744e53e366 160000 (submodule)
@@ -1 +1 @@
-Subproject commit d45f8e79e37c1754e8f09c1f299cef1a57db66f6
+Subproject commit 57896d513f6fbf41fde3c777931ebc744e53e366
diff --git a/oRTP b/oRTP
index ba73b8155b3a6aa64f8df95dee6b25ca9b95cbca..4ad63e9a106aee8d9dfb675aa0532962f322609c 160000 (submodule)
--- a/oRTP
+++ b/oRTP
@@ -1 +1 @@
-Subproject commit ba73b8155b3a6aa64f8df95dee6b25ca9b95cbca
+Subproject commit 4ad63e9a106aee8d9dfb675aa0532962f322609c