mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-19 20:18:09 +00:00
enhancements for proper pause/resume of calls
This commit is contained in:
parent
e69c8b2b44
commit
8647ec6aa0
7 changed files with 94 additions and 81 deletions
|
|
@ -303,7 +303,7 @@ static void call_accepted(SalOp *op){
|
|||
ms_free(msg);
|
||||
}
|
||||
linphone_core_update_streams (lc,call,md);
|
||||
linphone_call_set_state(call,LinphoneCallPaused,"Call paused");
|
||||
linphone_call_set_state(call,LinphoneCallPausedByRemote,"Call paused by remote");
|
||||
}else{
|
||||
if (lc->vtable.display_status){
|
||||
lc->vtable.display_status(lc,_("Call answered - connected."));
|
||||
|
|
@ -349,6 +349,7 @@ static void call_ack(SalOp *op){
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* this callback is called when an incoming re-INVITE modifies the session*/
|
||||
static void call_updating(SalOp *op){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
|
|
@ -360,32 +361,21 @@ static void call_updating(SalOp *op){
|
|||
|
||||
if (md && !sal_media_description_empty(md))
|
||||
{
|
||||
if ((call->state==LinphoneCallPausedByRemote || call->state==LinphoneCallPaused) &&
|
||||
sal_media_description_has_dir(md,SalStreamSendRecv) && strcmp(md->addr,"0.0.0.0")!=0){
|
||||
/*make sure we can be resumed */
|
||||
if (lc->current_call!=NULL && lc->current_call!=call){
|
||||
ms_warning("Attempt to be resumed but already in call with somebody else!");
|
||||
/*we are actively running another call, reject with a busy*/
|
||||
sal_call_decline (op,SalReasonBusy,NULL);
|
||||
return;
|
||||
if (sal_media_description_has_dir(call->localdesc,SalStreamSendRecv)){
|
||||
if (sal_media_description_has_dir (md,SalStreamRecvOnly) || sal_media_description_has_dir(md,SalStreamInactive)){
|
||||
/* we are being paused */
|
||||
if(lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("We are being paused..."));
|
||||
linphone_call_set_state (call,LinphoneCallPausedByRemote,"Call paused by remote");
|
||||
}else if (!sal_media_description_has_dir(call->resultdesc,SalStreamSendRecv) && sal_media_description_has_dir(md,SalStreamSendRecv)){
|
||||
if(lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("We have been resumed..."));
|
||||
linphone_call_set_state (call,LinphoneCallStreamsRunning,"Connected (streams running)");
|
||||
lc->current_call=call;
|
||||
}else{
|
||||
prevstate=call->state;
|
||||
linphone_call_set_state(call, LinphoneCallUpdatedByRemote,"Call updated by remote");
|
||||
}
|
||||
if(lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("We have been resumed..."));
|
||||
linphone_call_set_state (call,LinphoneCallStreamsRunning,"Connected (streams running)");
|
||||
}
|
||||
else if(call->state==LinphoneCallStreamsRunning &&
|
||||
( sal_media_description_has_dir(md,SalStreamRecvOnly)
|
||||
|| sal_media_description_has_dir(md,SalStreamInactive)
|
||||
|| strcmp(md->addr,"0.0.0.0")==0)){
|
||||
if(lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("We are being paused..."));
|
||||
linphone_call_set_state (call,LinphoneCallPausedByRemote,"Call paused by remote");
|
||||
if (lc->current_call!=call){
|
||||
ms_error("Inconsitency detected: current call is %p but call %p is being paused !",lc->current_call,call);
|
||||
}
|
||||
}else{
|
||||
prevstate=call->state;
|
||||
linphone_call_set_state(call, LinphoneCallUpdatedByRemote,"Call updated by remote");
|
||||
}
|
||||
/*accept the modification (sends a 200Ok)*/
|
||||
sal_call_accept(op);
|
||||
|
|
|
|||
|
|
@ -2204,7 +2204,7 @@ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const Linpho
|
|||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("Modifying call parameters..."));
|
||||
sal_call_set_local_media_description (call->op,call->localdesc);
|
||||
err=sal_call_update(call->op);
|
||||
err=sal_call_update(call->op,"Media parameters update");
|
||||
}else{
|
||||
#ifdef VIDEO_ENABLED
|
||||
if (call->videostream!=NULL){
|
||||
|
|
@ -2431,13 +2431,23 @@ LinphoneCall *linphone_core_get_current_call(const LinphoneCore *lc)
|
|||
int linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *the_call)
|
||||
{
|
||||
LinphoneCall *call = the_call;
|
||||
const char *subject=NULL;
|
||||
|
||||
if (call->state!=LinphoneCallStreamsRunning && call->state!=LinphoneCallPausedByRemote){
|
||||
ms_warning("Cannot pause this call, it is not active.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (sal_call_hold(call->op,TRUE) != 0)
|
||||
if (sal_media_description_has_dir(call->resultdesc,SalStreamSendRecv)){
|
||||
sal_media_description_set_dir(call->localdesc,SalStreamSendOnly);
|
||||
subject="Call on hold";
|
||||
}else if (sal_media_description_has_dir(call->resultdesc,SalStreamRecvOnly)){
|
||||
sal_media_description_set_dir(call->localdesc,SalStreamInactive);
|
||||
subject="Call inactive";
|
||||
}else{
|
||||
ms_error("No reason to pause this call, it is already paused or inactive.");
|
||||
return -1;
|
||||
}
|
||||
if (sal_call_update(call->op,subject) != 0)
|
||||
{
|
||||
if (lc->vtable.display_warning)
|
||||
lc->vtable.display_warning(lc,_("Could not pause the call"));
|
||||
|
|
@ -2487,14 +2497,14 @@ int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *the_call)
|
|||
return -1;
|
||||
}
|
||||
ms_message("Resuming call %p",call);
|
||||
if(sal_call_hold(call->op,FALSE) != 0){
|
||||
sal_media_description_set_dir(call->localdesc,SalStreamSendRecv);
|
||||
if(sal_call_update(call->op,"Call resuming") != 0){
|
||||
return -1;
|
||||
}
|
||||
linphone_call_set_state (call,LinphoneCallResuming,"Resuming");
|
||||
snprintf(temp,sizeof(temp)-1,"Resuming the call with %s",linphone_call_get_remote_address_as_string(call));
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,temp);
|
||||
lc->current_call=call;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -109,7 +109,7 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
|
|||
|
||||
|
||||
|
||||
static SalStreamDir compute_dir(SalStreamDir local, SalStreamDir answered){
|
||||
static SalStreamDir compute_dir_outgoing(SalStreamDir local, SalStreamDir answered){
|
||||
SalStreamDir res=local;
|
||||
if (local==SalStreamSendRecv){
|
||||
if (answered==SalStreamRecvOnly){
|
||||
|
|
@ -124,6 +124,33 @@ static SalStreamDir compute_dir(SalStreamDir local, SalStreamDir answered){
|
|||
return res;
|
||||
}
|
||||
|
||||
static SalStreamDir compute_dir_incoming(SalStreamDir local, SalStreamDir offered){
|
||||
SalStreamDir res=SalStreamSendRecv;
|
||||
if (local==SalStreamSendRecv){
|
||||
if (offered==SalStreamSendOnly)
|
||||
res=SalStreamRecvOnly;
|
||||
if (offered==SalStreamRecvOnly)
|
||||
res=SalStreamSendOnly;
|
||||
if (offered==SalStreamInactive)
|
||||
res=SalStreamInactive;
|
||||
}else if (local==SalStreamSendOnly){
|
||||
if (offered==SalStreamSendOnly)
|
||||
res=SalStreamInactive;
|
||||
if (offered==SalStreamRecvOnly)
|
||||
res=SalStreamSendOnly;
|
||||
if (offered==SalStreamInactive)
|
||||
res=SalStreamInactive;
|
||||
}else if (local==SalStreamRecvOnly){
|
||||
if (offered==SalStreamSendOnly)
|
||||
res=SalStreamRecvOnly;
|
||||
if (offered==SalStreamRecvOnly)
|
||||
res=SalStreamInactive;
|
||||
if (offered==SalStreamInactive)
|
||||
res=SalStreamInactive;
|
||||
}else res=SalStreamInactive;
|
||||
return res;
|
||||
}
|
||||
|
||||
static void initiate_outgoing(const SalStreamDescription *local_offer,
|
||||
const SalStreamDescription *remote_answer,
|
||||
SalStreamDescription *result){
|
||||
|
|
@ -131,7 +158,7 @@ static void initiate_outgoing(const SalStreamDescription *local_offer,
|
|||
result->payloads=match_payloads(local_offer->payloads,remote_answer->payloads,TRUE,FALSE);
|
||||
result->proto=local_offer->proto;
|
||||
result->type=local_offer->type;
|
||||
result->dir=compute_dir(local_offer->dir,remote_answer->dir);
|
||||
result->dir=compute_dir_outgoing(local_offer->dir,remote_answer->dir);
|
||||
|
||||
if (result->payloads && !only_telephone_event(result->payloads)){
|
||||
strcpy(result->addr,remote_answer->addr);
|
||||
|
|
@ -150,13 +177,7 @@ static void initiate_incoming(const SalStreamDescription *local_cap,
|
|||
result->payloads=match_payloads(local_cap->payloads,remote_offer->payloads, FALSE, one_matching_codec);
|
||||
result->proto=local_cap->proto;
|
||||
result->type=local_cap->type;
|
||||
if (remote_offer->dir==SalStreamSendOnly)
|
||||
result->dir=SalStreamRecvOnly;
|
||||
else if (remote_offer->dir==SalStreamRecvOnly){
|
||||
result->dir=SalStreamSendOnly;
|
||||
}else if (remote_offer->dir==SalStreamInactive){
|
||||
result->dir=SalStreamInactive;
|
||||
}else result->dir=SalStreamSendRecv;
|
||||
result->dir=compute_dir_incoming(result->dir,remote_offer->dir);
|
||||
if (result->payloads && !only_telephone_event(result->payloads)){
|
||||
strcpy(result->addr,local_cap->addr);
|
||||
result->port=local_cap->port;
|
||||
|
|
|
|||
|
|
@ -79,19 +79,41 @@ void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_
|
|||
}
|
||||
}
|
||||
|
||||
bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir stream_dir){
|
||||
|
||||
static bool_t is_null_address(const char *addr){
|
||||
return strcmp(addr,"0.0.0.0")==0 || strcmp(addr,"::0")==0;
|
||||
}
|
||||
|
||||
/*check for the presence of at least one stream with requested direction */
|
||||
static bool_t has_dir(const SalMediaDescription *md, SalStreamDir stream_dir){
|
||||
int i;
|
||||
bool_t found=FALSE;
|
||||
|
||||
/* we are looking for at least one stream with requested direction, inactive streams are ignored*/
|
||||
for(i=0;i<md->nstreams;++i){
|
||||
const SalStreamDescription *ss=&md->streams[i];
|
||||
if (ss->dir==stream_dir) found=TRUE;
|
||||
else{
|
||||
if (ss->dir!=SalStreamInactive) return FALSE;
|
||||
}
|
||||
if (ss->dir==stream_dir) return TRUE;
|
||||
if (stream_dir==SalStreamSendOnly && (is_null_address(md->addr) || is_null_address(ss->addr)))
|
||||
return TRUE;
|
||||
}
|
||||
return found;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir stream_dir){
|
||||
if (stream_dir==SalStreamRecvOnly){
|
||||
if (has_dir(md,SalStreamSendOnly) || has_dir(md,SalStreamSendRecv)) return FALSE;
|
||||
else return TRUE;
|
||||
}else if (stream_dir==SalStreamSendOnly){
|
||||
if (has_dir(md,SalStreamRecvOnly) || has_dir(md,SalStreamSendRecv)) return FALSE;
|
||||
else return TRUE;
|
||||
}else if (stream_dir==SalStreamSendRecv){
|
||||
return has_dir(md,SalStreamSendRecv);
|
||||
}else{
|
||||
/*SalStreamInactive*/
|
||||
if (has_dir(md,SalStreamSendOnly) || has_dir(md,SalStreamSendRecv) || has_dir(md,SalStreamRecvOnly))
|
||||
return FALSE;
|
||||
else return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -293,8 +293,7 @@ int sal_call_notify_ringing(SalOp *h, bool_t early_media);
|
|||
/*accept an incoming call or, during a call accept a reINVITE*/
|
||||
int sal_call_accept(SalOp*h);
|
||||
int sal_call_decline(SalOp *h, SalReason reason, const char *redirection /*optional*/);
|
||||
int sal_call_hold(SalOp *h, bool_t holdon);
|
||||
int sal_call_update(SalOp *h);
|
||||
int sal_call_update(SalOp *h, const char *subject);
|
||||
SalMediaDescription * sal_call_get_final_media_description(SalOp *h);
|
||||
int sal_call_refer(SalOp *h, const char *refer_to);
|
||||
int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h);
|
||||
|
|
|
|||
|
|
@ -2011,37 +2011,8 @@ int sal_address_get_port_int(const SalAddress *uri) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a re-Invite used to hold the current call
|
||||
*/
|
||||
int sal_call_hold(SalOp *h, bool_t holdon)
|
||||
{
|
||||
int err=0;
|
||||
|
||||
osip_message_t *reinvite=NULL;
|
||||
if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != OSIP_SUCCESS || reinvite==NULL)
|
||||
return -1;
|
||||
osip_message_set_subject(reinvite,holdon ? "Phone call hold" : "Phone call resume" );
|
||||
osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
|
||||
if (h->base.root->session_expires!=0){
|
||||
osip_message_set_header(reinvite, "Session-expires", "200");
|
||||
osip_message_set_supported(reinvite, "timer");
|
||||
}
|
||||
//add something to say that the distant sip phone will be in sendonly/sendrecv mode
|
||||
if (h->base.local_media){
|
||||
h->sdp_offering=TRUE;
|
||||
sal_media_description_set_dir(h->base.local_media, holdon ? SalStreamSendOnly : SalStreamSendRecv);
|
||||
set_sdp_from_desc(reinvite,h->base.local_media);
|
||||
}else h->sdp_offering=FALSE;
|
||||
eXosip_lock();
|
||||
err = eXosip_call_send_request(h->did, reinvite);
|
||||
eXosip_unlock();
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
/* sends a reinvite. Local media description may have changed by application since call establishment*/
|
||||
int sal_call_update(SalOp *h){
|
||||
int sal_call_update(SalOp *h, const char *subject){
|
||||
int err=0;
|
||||
osip_message_t *reinvite=NULL;
|
||||
|
||||
|
|
@ -2051,7 +2022,7 @@ int sal_call_update(SalOp *h){
|
|||
return -1;
|
||||
}
|
||||
eXosip_unlock();
|
||||
osip_message_set_subject(reinvite,osip_strdup("Phone call parameters updated"));
|
||||
osip_message_set_subject(reinvite,subject);
|
||||
osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
|
||||
if (h->base.root->session_expires!=0){
|
||||
osip_message_set_header(reinvite, "Session-expires", "200");
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 5aab07bfaac18302a6af3b38fa7c62d466794941
|
||||
Subproject commit 0fc8db73037bab398ece764874192d1d7df6af28
|
||||
Loading…
Add table
Reference in a new issue