Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
BC
public
liblinphone
Commits
8647ec6a
Commit
8647ec6a
authored
Feb 03, 2011
by
Simon Morlat
Browse files
enhancements for proper pause/resume of calls
parent
e69c8b2b
Changes
7
Hide whitespace changes
Inline
Side-by-side
coreapi/callbacks.c
View file @
8647ec6a
...
...
@@ -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
,
LinphoneCallPaused
ByRemote
,
"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
(
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
);
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"
);
}
}
else
{
prevstate
=
call
->
state
;
linphone_call_set_state
(
call
,
LinphoneCallUpdatedByRemote
,
"Call updated by remote"
);
}
/*accept the modification (sends a 200Ok)*/
sal_call_accept
(
op
);
...
...
coreapi/linphonecore.c
View file @
8647ec6a
...
...
@@ -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
;
}
...
...
coreapi/offeranswer.c
View file @
8647ec6a
...
...
@@ -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
;
...
...
coreapi/sal.c
View file @
8647ec6a
...
...
@@ -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
;
}
/*
...
...
coreapi/sal.h
View file @
8647ec6a
...
...
@@ -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
);
...
...
coreapi/sal_eXosip2.c
View file @
8647ec6a
...
...
@@ -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"
);
...
...
mediastreamer2
@
0fc8db73
Subproject commit
5aab07bfaac18302a6af3b38fa7c62d466794941
Subproject commit
0fc8db73037bab398ece764874192d1d7df6af28
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment