Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
What's new
10
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Open sidebar
BC
public
liblinphone
Commits
260e7e1d
Commit
260e7e1d
authored
Mar 18, 2014
by
jehan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
minimal SIP UPDATE support
parent
36a124d2
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
209 additions
and
46 deletions
+209
-46
.cproject
.cproject
+18
-0
coreapi/bellesip_sal/sal_impl.c
coreapi/bellesip_sal/sal_impl.c
+3
-1
coreapi/bellesip_sal/sal_impl.h
coreapi/bellesip_sal/sal_impl.h
+1
-0
coreapi/bellesip_sal/sal_op_call.c
coreapi/bellesip_sal/sal_op_call.c
+60
-23
coreapi/bellesip_sal/sal_op_impl.c
coreapi/bellesip_sal/sal_op_impl.c
+1
-0
coreapi/callbacks.c
coreapi/callbacks.c
+21
-11
coreapi/linphonecore.c
coreapi/linphonecore.c
+15
-9
coreapi/private.h
coreapi/private.h
+1
-1
include/sal/sal.h
include/sal/sal.h
+1
-1
tester/call_tester.c
tester/call_tester.c
+88
-0
No files found.
.cproject
View file @
260e7e1d
...
...
@@ -28,6 +28,9 @@
<inputType
id=
"org.eclipse.cdt.build.core.settings.holder.inType.306286573"
languageId=
"org.eclipse.cdt.core.g++"
languageName=
"GNU C++"
sourceContentType=
"org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader"
superClass=
"org.eclipse.cdt.build.core.settings.holder.inType"
/>
</tool>
<tool
id=
"org.eclipse.cdt.build.core.settings.holder.391709798"
name=
"GNU C"
superClass=
"org.eclipse.cdt.build.core.settings.holder"
>
<option
id=
"org.eclipse.cdt.build.core.settings.holder.incpaths.295320884"
name=
"Include Paths"
superClass=
"org.eclipse.cdt.build.core.settings.holder.incpaths"
valueType=
"includePath"
>
<listOptionValue
builtIn=
"false"
value=
"/Users/jehanmonnier/workspaces/workspace-macosx/opt/include"
/>
</option>
<inputType
id=
"org.eclipse.cdt.build.core.settings.holder.inType.1702094818"
languageId=
"org.eclipse.cdt.core.gcc"
languageName=
"GNU C"
sourceContentType=
"org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader"
superClass=
"org.eclipse.cdt.build.core.settings.holder.inType"
/>
</tool>
<tool
id=
"org.eclipse.cdt.build.core.settings.holder.754828354"
name=
"Assembly"
superClass=
"org.eclipse.cdt.build.core.settings.holder"
>
...
...
@@ -36,9 +39,24 @@
</toolChain>
</folderInfo>
<fileInfo
id=
"0.2079208171.2090246372"
name=
"ringback.wav"
rcbsApplicability=
"disable"
resourcePath=
"tester/sounds/ringback.wav"
toolsToInvoke=
""
/>
<folderInfo
id=
"0.2079208171.1778481546"
name=
"/"
resourcePath=
"include"
>
<toolChain
id=
"org.eclipse.cdt.build.core.prefbase.toolchain.1238844827"
name=
"No ToolChain"
superClass=
"org.eclipse.cdt.build.core.prefbase.toolchain"
unusedChildren=
""
>
<tool
id=
"org.eclipse.cdt.build.core.settings.holder.libs.58439860"
name=
"holder for library settings"
superClass=
"org.eclipse.cdt.build.core.settings.holder.libs.1252970003"
/>
<tool
id=
"org.eclipse.cdt.build.core.settings.holder.899998629"
name=
"GNU C++"
superClass=
"org.eclipse.cdt.build.core.settings.holder.1371414073"
>
<inputType
id=
"org.eclipse.cdt.build.core.settings.holder.inType.1829150855"
languageId=
"org.eclipse.cdt.core.g++"
languageName=
"GNU C++"
sourceContentType=
"org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader"
superClass=
"org.eclipse.cdt.build.core.settings.holder.inType"
/>
</tool>
<tool
id=
"org.eclipse.cdt.build.core.settings.holder.252709365"
name=
"GNU C"
superClass=
"org.eclipse.cdt.build.core.settings.holder.391709798"
>
<inputType
id=
"org.eclipse.cdt.build.core.settings.holder.inType.551083583"
languageId=
"org.eclipse.cdt.core.gcc"
languageName=
"GNU C"
sourceContentType=
"org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader"
superClass=
"org.eclipse.cdt.build.core.settings.holder.inType"
/>
</tool>
<tool
id=
"org.eclipse.cdt.build.core.settings.holder.1236597953"
name=
"Assembly"
superClass=
"org.eclipse.cdt.build.core.settings.holder.754828354"
>
<inputType
id=
"org.eclipse.cdt.build.core.settings.holder.inType.714781911"
languageId=
"org.eclipse.cdt.core.assembly"
languageName=
"Assembly"
sourceContentType=
"org.eclipse.cdt.core.asmSource"
superClass=
"org.eclipse.cdt.build.core.settings.holder.inType"
/>
</tool>
</toolChain>
</folderInfo>
<sourceEntries>
<entry
flags=
"VALUE_WORKSPACE_PATH"
kind=
"sourcePath"
name=
"coreapi"
/>
<entry
flags=
"VALUE_WORKSPACE_PATH"
kind=
"sourcePath"
name=
"gtk"
/>
<entry
flags=
"VALUE_WORKSPACE_PATH"
kind=
"sourcePath"
name=
"include"
/>
<entry
flags=
"VALUE_WORKSPACE_PATH"
kind=
"sourcePath"
name=
"tester"
/>
</sourceEntries>
</configuration>
...
...
coreapi/bellesip_sal/sal_impl.c
View file @
260e7e1d
...
...
@@ -246,7 +246,9 @@ static void process_request_event(void *ud, const belle_sip_request_event_t *eve
return
;
}
else
{
ms_error
(
"sal process_request_event not implemented yet for method [%s]"
,
belle_sip_request_get_method
(
req
));
resp
=
belle_sip_response_create_from_request
(
req
,
501
);
resp
=
belle_sip_response_create_from_request
(
req
,
405
);
belle_sip_message_add_header
(
BELLE_SIP_MESSAGE
(
resp
)
,
BELLE_SIP_HEADER
(
belle_sip_header_allow_create
(
"INVITE, CANCEL, ACK, BYE, SUBSCRIBE, NOTIFY, MESSAGE, OPTIONS, INFO"
)));
belle_sip_provider_send_response
(
sal
->
prov
,
resp
);
return
;
}
...
...
coreapi/bellesip_sal/sal_impl.h
View file @
260e7e1d
...
...
@@ -79,6 +79,7 @@ struct SalOp{
belle_sip_listener_callbacks_t
callbacks
;
belle_sip_client_transaction_t
*
pending_auth_transaction
;
belle_sip_server_transaction_t
*
pending_server_trans
;
belle_sip_server_transaction_t
*
pending_update_server_trans
;
belle_sip_client_transaction_t
*
pending_client_trans
;
SalAuthInfo
*
auth_info
;
belle_sip_dialog_t
*
dialog
;
...
...
coreapi/bellesip_sal/sal_op_call.c
View file @
260e7e1d
...
...
@@ -226,6 +226,11 @@ static void call_process_response(void *op_base, const belle_sip_response_event_
call_set_error
(
op
,
response
);
if
(
op
->
dialog
==
NULL
)
call_set_released
(
op
);
}
}
else
if
(
code
>=
200
&&
code
<
300
&&
strcmp
(
"UPDATE"
,
belle_sip_request_get_method
(
req
))
==
0
)
{
handle_sdp_from_response
(
op
,
response
);
op
->
base
.
root
->
callbacks
.
call_accepted
(
op
);
}
}
break
;
...
...
@@ -384,6 +389,16 @@ static int process_sdp_for_invite(SalOp* op,belle_sip_request_t* invite) {
return
err
;
}
static
void
sal_op_reset_descriptions
(
SalOp
*
op
)
{
if
(
op
->
base
.
remote_media
){
sal_media_description_unref
(
op
->
base
.
remote_media
);
op
->
base
.
remote_media
=
NULL
;
}
if
(
op
->
result
){
sal_media_description_unref
(
op
->
result
);
op
->
result
=
NULL
;
}
}
static
void
process_request_event
(
void
*
op_base
,
const
belle_sip_request_event_t
*
event
)
{
SalOp
*
op
=
(
SalOp
*
)
op_base
;
belle_sip_server_transaction_t
*
server_transaction
=
NULL
;
...
...
@@ -408,6 +423,13 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
belle_sip_object_ref
(
op
->
pending_server_trans
);
}
if
(
strcmp
(
"UPDATE"
,
method
)
==
0
)
{
if
(
op
->
pending_update_server_trans
)
belle_sip_object_unref
(
op
->
pending_update_server_trans
);
/*updating pending update transaction*/
op
->
pending_update_server_trans
=
server_transaction
;
belle_sip_object_ref
(
op
->
pending_update_server_trans
);
}
if
(
!
op
->
dialog
)
{
set_or_update_dialog
(
op
,
belle_sip_provider_create_dialog
(
op
->
base
.
root
->
prov
,
BELLE_SIP_TRANSACTION
(
op
->
pending_server_trans
)));
ms_message
(
"new incoming call from [%s] to [%s]"
,
sal_op_get_from
(
op
),
sal_op_get_to
(
op
));
...
...
@@ -455,6 +477,10 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
}
else
if
(
strcmp
(
"PRACK"
,
method
)
==
0
)
{
resp
=
sal_op_create_response_from_request
(
op
,
req
,
200
);
belle_sip_server_transaction_send_response
(
server_transaction
,
resp
);
}
else
if
(
strcmp
(
"UPDATE"
,
method
)
==
0
)
{
sal_op_reset_descriptions
(
op
);
if
(
process_sdp_for_invite
(
op
,
req
)
==
0
)
op
->
base
.
root
->
callbacks
.
call_updating
(
op
);
}
else
{
belle_sip_error
(
"Unexpected method [%s] for dialog state BELLE_SIP_DIALOG_EARLY"
,
belle_sip_request_get_method
(
req
));
unsupported_method
(
server_transaction
,
req
);
...
...
@@ -479,10 +505,6 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
}
}
}
/*FIXME
if (op->reinvite){
op->reinvite=FALSE;
}*/
op
->
base
.
root
->
callbacks
.
call_ack
(
op
);
}
else
if
(
strcmp
(
"BYE"
,
method
)
==
0
)
{
resp
=
sal_op_create_response_from_request
(
op
,
req
,
200
);
...
...
@@ -492,14 +514,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
/*call end not notified by dialog deletion because transaction can end before dialog*/
}
else
if
(
strcmp
(
"INVITE"
,
method
)
==
0
)
{
/*re-invite*/
if
(
op
->
base
.
remote_media
){
sal_media_description_unref
(
op
->
base
.
remote_media
);
op
->
base
.
remote_media
=
NULL
;
}
if
(
op
->
result
){
sal_media_description_unref
(
op
->
result
);
op
->
result
=
NULL
;
}
sal_op_reset_descriptions
(
op
);
if
(
process_sdp_for_invite
(
op
,
req
)
==
0
)
op
->
base
.
root
->
callbacks
.
call_updating
(
op
);
}
else
if
(
strcmp
(
"INFO"
,
method
)
==
0
){
...
...
@@ -576,7 +591,7 @@ int sal_call_set_local_media_description(SalOp *op, SalMediaDescription *desc){
static
belle_sip_header_allow_t
*
create_allow
(){
belle_sip_header_allow_t
*
header_allow
;
header_allow
=
belle_sip_header_allow_create
(
"INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO"
);
header_allow
=
belle_sip_header_allow_create
(
"INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO
, UPDATE
"
);
return
header_allow
;
}
...
...
@@ -684,14 +699,21 @@ int sal_call_notify_ringing(SalOp *op, bool_t early_media){
int
sal_call_accept
(
SalOp
*
h
){
belle_sip_response_t
*
response
;
belle_sip_header_contact_t
*
contact_header
;
if
(
!
h
->
pending_server_trans
)
{
belle_sip_server_transaction_t
*
transaction
;
/*first check if an UPDATE transaction need to be accepted*/
if
(
h
->
pending_update_server_trans
)
{
transaction
=
h
->
pending_update_server_trans
;
}
else
if
(
h
->
pending_server_trans
)
{
/*so it must be an invite/re-invite*/
transaction
=
h
->
pending_server_trans
;
}
else
{
ms_error
(
"No transaction to accept for op [%p]"
,
h
);
return
-
1
;
}
ms_message
(
"Accepting server transaction [%p] on op [%p]"
,
transaction
,
h
);
/* sends a 200 OK */
response
=
sal_op_create_response_from_request
(
h
,
belle_sip_transaction_get_request
(
BELLE_SIP_TRANSACTION
(
h
->
pending_server_trans
)),
200
);
response
=
sal_op_create_response_from_request
(
h
,
belle_sip_transaction_get_request
(
BELLE_SIP_TRANSACTION
(
transaction
)),
200
);
if
(
response
==
NULL
){
ms_error
(
"Fail to build answer for call"
);
...
...
@@ -712,7 +734,11 @@ int sal_call_accept(SalOp*h){
handle_offer_answer_response
(
h
,
response
);
belle_sip_server_transaction_send_response
(
h
->
pending_server_trans
,
response
);
belle_sip_server_transaction_send_response
(
transaction
,
response
);
if
(
h
->
pending_update_server_trans
)
{
belle_sip_object_unref
(
h
->
pending_update_server_trans
);
h
->
pending_update_server_trans
=
NULL
;
}
return
0
;
}
...
...
@@ -738,11 +764,22 @@ int sal_call_decline(SalOp *op, SalReason reason, const char *redirection /*opti
}
int
sal_call_update
(
SalOp
*
op
,
const
char
*
subject
){
belle_sip_request_t
*
reinvite
=
belle_sip_dialog_create_request
(
op
->
dialog
,
"INVITE"
);
if
(
reinvite
){
belle_sip_message_add_header
(
BELLE_SIP_MESSAGE
(
reinvite
),
belle_sip_header_create
(
"Subject"
,
subject
));
sal_op_fill_invite
(
op
,
reinvite
);
return
sal_op_send_request
(
op
,
reinvite
);
belle_sip_request_t
*
update
;
belle_sip_dialog_state_t
state
=
belle_sip_dialog_get_state
(
op
->
dialog
);
/*check for dialog state*/
if
(
state
==
BELLE_SIP_DIALOG_CONFIRMED
)
{
update
=
belle_sip_dialog_create_request
(
op
->
dialog
,
"INVITE"
);
}
else
if
(
state
==
BELLE_SIP_DIALOG_EARLY
)
{
update
=
belle_sip_dialog_create_request
(
op
->
dialog
,
"UPDATE"
);
}
else
{
ms_error
(
"Cannot update op [%p] with dialog [%p] in state [%s]"
,
op
,
op
->
dialog
,
belle_sip_dialog_state_to_string
(
state
));
return
-
1
;
}
if
(
update
){
belle_sip_message_add_header
(
BELLE_SIP_MESSAGE
(
update
),
belle_sip_header_create
(
"Subject"
,
subject
));
sal_op_fill_invite
(
op
,
update
);
return
sal_op_send_request
(
op
,
update
);
}
return
-
1
;
}
...
...
coreapi/bellesip_sal/sal_op_impl.c
View file @
260e7e1d
...
...
@@ -60,6 +60,7 @@ void sal_op_release_impl(SalOp *op){
if
(
op
->
pending_client_trans
)
belle_sip_object_unref
(
op
->
pending_client_trans
);
if
(
op
->
pending_server_trans
)
belle_sip_object_unref
(
op
->
pending_server_trans
);
if
(
op
->
pending_update_server_trans
)
belle_sip_object_unref
(
op
->
pending_update_server_trans
);
if
(
op
->
event
)
belle_sip_object_unref
(
op
->
event
);
__sal_op_free
(
op
);
return
;
...
...
coreapi/callbacks.c
View file @
260e7e1d
...
...
@@ -116,7 +116,7 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
video_stream_change_camera
(
call
->
videostream
,
lc
->
video_conf
.
device
);
#endif
}
/*FIXME ZRTP might be restarted in any cases ? */
/*FIXME ZRTP
,
might be restarted in any cases ? */
ms_message
(
"No need to restart streams, SDP is unchanged."
);
goto
end
;
}
else
{
...
...
@@ -407,7 +407,8 @@ static void call_accepted(SalOp *op){
linphone_call_fix_call_parameters
(
call
);
if
(
!
call
->
current_params
.
in_conference
)
lc
->
current_call
=
call
;
linphone_call_set_state
(
call
,
LinphoneCallStreamsRunning
,
"Streams running"
);
if
(
call
->
prevstate
!=
LinphoneCallIncomingEarlyMedia
)
/*don't change state in aswer to a SIP UPDATE in early media*/
linphone_call_set_state
(
call
,
LinphoneCallStreamsRunning
,
"Streams running"
);
}
}
else
{
/*send a bye*/
...
...
@@ -473,7 +474,7 @@ static void call_paused_by_remote(LinphoneCore *lc, LinphoneCall *call){
linphone_call_set_state
(
call
,
LinphoneCallPausedByRemote
,
"Call paused by remote"
);
}
static
void
call_updated_by_remote
(
LinphoneCore
*
lc
,
LinphoneCall
*
call
){
static
void
call_updated_by_remote
(
LinphoneCore
*
lc
,
LinphoneCall
*
call
,
bool_t
notify_application
){
/*first check if media capabilities are compatible*/
SalMediaDescription
*
md
;
linphone_call_make_local_media_description
(
lc
,
call
);
...
...
@@ -484,16 +485,21 @@ static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call){
return
;
}
if
(
lc
->
vtable
.
display_status
)
lc
->
vtable
.
display_status
(
lc
,
_
(
"Call is updated by remote."
));
call
->
defer_update
=
FALSE
;
linphone_call_set_state
(
call
,
LinphoneCallUpdatedByRemote
,
"Call updated by remote"
);
if
(
call
->
defer_update
==
FALSE
){
linphone_core_accept_call_update
(
lc
,
call
,
NULL
);
if
(
notify_application
)
{
if
(
lc
->
vtable
.
display_status
)
lc
->
vtable
.
display_status
(
lc
,
_
(
"Call is updated by remote."
));
call
->
defer_update
=
FALSE
;
linphone_call_set_state
(
call
,
LinphoneCallUpdatedByRemote
,
"Call updated by remote"
);
if
(
call
->
defer_update
==
FALSE
){
linphone_core_accept_call_update
(
lc
,
call
,
NULL
);
}
}
else
{
/*SIP UPDATE case*/
/*can be call from any state*/
_linphone_core_accept_call_update
(
lc
,
call
,
NULL
);
}
}
/* this callback is called when an incoming re-INVITE modifies the session*/
/* this callback is called when an incoming re-INVITE
/ SIP UPDATE
modifies the session*/
static
void
call_updating
(
SalOp
*
op
){
LinphoneCore
*
lc
=
(
LinphoneCore
*
)
sal_get_user_pointer
(
sal_op_get_sal
(
op
));
LinphoneCall
*
call
=
(
LinphoneCall
*
)
sal_op_get_user_pointer
(
op
);
...
...
@@ -512,12 +518,16 @@ static void call_updating(SalOp *op){
call_resumed
(
lc
,
call
);
}
else
call_paused_by_remote
(
lc
,
call
);
break
;
/*SIP UPDATE CASE*/
case
LinphoneCallOutgoingEarlyMedia
:
call_updated_by_remote
(
lc
,
call
,
FALSE
);
break
;
case
LinphoneCallStreamsRunning
:
case
LinphoneCallConnected
:
if
(
sal_media_description_has_dir
(
rmd
,
SalStreamSendOnly
)
||
sal_media_description_has_dir
(
rmd
,
SalStreamInactive
)){
call_paused_by_remote
(
lc
,
call
);
}
else
{
call_updated_by_remote
(
lc
,
call
);
call_updated_by_remote
(
lc
,
call
,
TRUE
);
}
break
;
default:
...
...
coreapi/linphonecore.c
View file @
260e7e1d
...
...
@@ -3231,23 +3231,25 @@ int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call)
linphone_core_update_streams
(
lc
,
call
,
md
);
linphone_call_fix_call_parameters
(
call
);
}
linphone_call_set_state
(
call
,
LinphoneCallStreamsRunning
,
"Connected (streams running)"
);
if
(
call
->
state
!=
LinphoneCallOutgoingEarlyMedia
)
/*don't change the state in case of outgoing early (SIP UPDATE)*/
linphone_call_set_state
(
call
,
LinphoneCallStreamsRunning
,
"Connected (streams running)"
);
return
0
;
}
/**
* @ingroup call_control
* Accept call modifications initiated by other end.
*
*
* This call may be performed in response to a #LinphoneCallUpdatedByRemote state notification.
* When such notification arrives, the application can decide to call linphone_core_defer_update_call() so that it can
* have the time to prompt the user. linphone_call_get_remote_params() can be used to get information about the call parameters
* requested by the other party, such as whether a video stream is requested.
*
*
* When the user accepts or refuse the change, linphone_core_accept_call_update() can be done to answer to the other party.
* If params is NULL, then the same call parameters established before the update request will continue to be used (no change).
* If params is not NULL, then the update will be accepted according to the parameters passed.
* Typical example is when a user accepts to start video, then params should indicate that video stream should be used
* Typical example is when a user accepts to start video, then params should indicate that video stream should be used
* (see linphone_call_params_enable_video()).
* @param lc the linphone core object.
* @param call the LinphoneCall object
...
...
@@ -3255,16 +3257,20 @@ int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call)
* @return 0 if successful, -1 otherwise (actually when this function call is performed outside ot #LinphoneCallUpdatedByRemote state).
**/
int
linphone_core_accept_call_update
(
LinphoneCore
*
lc
,
LinphoneCall
*
call
,
const
LinphoneCallParams
*
params
){
SalMediaDescription
*
remote_desc
;
bool_t
keep_sdp_version
;
#ifdef VIDEO_ENABLED
bool_t
old_has_video
=
call
->
params
.
has_video
;
#endif
if
(
call
->
state
!=
LinphoneCallUpdatedByRemote
){
ms_error
(
"linphone_core_accept_update(): invalid state %s to call this function."
,
linphone_call_state_to_string
(
call
->
state
));
return
-
1
;
}
return
_linphone_core_accept_call_update
(
lc
,
call
,
params
);
}
int
_linphone_core_accept_call_update
(
LinphoneCore
*
lc
,
LinphoneCall
*
call
,
const
LinphoneCallParams
*
params
){
SalMediaDescription
*
remote_desc
;
bool_t
keep_sdp_version
;
#ifdef VIDEO_ENABLED
bool_t
old_has_video
=
call
->
params
.
has_video
;
#endif
remote_desc
=
sal_call_get_remote_media_description
(
call
->
op
);
keep_sdp_version
=
lp_config_get_int
(
lc
->
config
,
"sip"
,
"keep_sdp_version"
,
0
);
if
(
keep_sdp_version
&&
(
remote_desc
->
session_id
==
call
->
remote_session_id
)
&&
(
remote_desc
->
session_ver
==
call
->
remote_session_ver
))
{
...
...
coreapi/private.h
View file @
260e7e1d
...
...
@@ -605,7 +605,7 @@ void linphone_tone_description_destroy(LinphoneToneDescription *obj);
LinphoneToneDescription
*
linphone_core_get_call_error_tone
(
const
LinphoneCore
*
lc
,
LinphoneReason
reason
);
void
linphone_core_play_call_error_tone
(
LinphoneCore
*
lc
,
LinphoneReason
reason
);
void
_linphone_core_set_call_error_tone
(
LinphoneCore
*
lc
,
LinphoneReason
reason
,
LinphoneToneID
id
,
const
char
*
audiofile
);
int
_linphone_core_accept_call_update
(
LinphoneCore
*
lc
,
LinphoneCall
*
call
,
const
LinphoneCallParams
*
params
);
typedef
struct
_LinphoneConference
LinphoneConference
;
struct
_LinphoneCore
...
...
include/sal/sal.h
View file @
260e7e1d
...
...
@@ -420,7 +420,7 @@ typedef void (*SalOnCallReceived)(SalOp *op);
typedef
void
(
*
SalOnCallRinging
)(
SalOp
*
op
);
typedef
void
(
*
SalOnCallAccepted
)(
SalOp
*
op
);
typedef
void
(
*
SalOnCallAck
)(
SalOp
*
op
);
typedef
void
(
*
SalOnCallUpdating
)(
SalOp
*
op
);
/*< Called when a reINVITE is received*/
typedef
void
(
*
SalOnCallUpdating
)(
SalOp
*
op
);
/*< Called when a reINVITE
/UPDATE
is received*/
typedef
void
(
*
SalOnCallTerminated
)(
SalOp
*
op
,
const
char
*
from
);
typedef
void
(
*
SalOnCallFailure
)(
SalOp
*
op
,
SalError
error
,
SalReason
reason
,
const
char
*
details
,
int
code
);
typedef
void
(
*
SalOnCallReleased
)(
SalOp
*
salop
);
...
...
tester/call_tester.c
View file @
260e7e1d
...
...
@@ -1133,6 +1133,92 @@ static void early_media_call_with_ringing(void){
linphone_core_manager_destroy
(
pauline
);
}
static
void
early_media_call_with_update_base
(
bool_t
media_change
){
char
hellopath
[
256
];
LinphoneCoreManager
*
marie
=
linphone_core_manager_new
(
"marie_rc"
);
LinphoneCoreManager
*
pauline
=
linphone_core_manager_new
(
"pauline_rc"
);
MSList
*
lcs
=
NULL
;
LinphoneCall
*
marie_call
,
*
pauline_call
;
LinphoneCallParams
*
pauline_params
;
lcs
=
ms_list_append
(
lcs
,
marie
->
lc
);
lcs
=
ms_list_append
(
lcs
,
pauline
->
lc
);
if
(
media_change
)
{
disable_all_codecs_except_one
(
marie
->
lc
,
"pcmu"
);
disable_all_codecs_except_one
(
pauline
->
lc
,
"pcmu"
);
}
/*
Marie calls Pauline, and after the call has rung, transitions to an early_media session
*/
/*use playfile for callee to avoid locking on capture card*/
linphone_core_use_files
(
pauline
->
lc
,
TRUE
);
snprintf
(
hellopath
,
sizeof
(
hellopath
),
"%s/sounds/hello8000.wav"
,
liblinphone_tester_file_prefix
);
linphone_core_set_play_file
(
pauline
->
lc
,
hellopath
);
marie_call
=
linphone_core_invite_address
(
marie
->
lc
,
pauline
->
identity
);
CU_ASSERT_TRUE
(
wait_for_list
(
lcs
,
&
pauline
->
stat
.
number_of_LinphoneCallIncomingReceived
,
1
,
1000
));
CU_ASSERT_TRUE
(
wait_for_list
(
lcs
,
&
marie
->
stat
.
number_of_LinphoneCallOutgoingRinging
,
1
,
1000
));
/* send a 183 to initiate the early media */
linphone_core_accept_early_media
(
pauline
->
lc
,
linphone_core_get_current_call
(
pauline
->
lc
));
CU_ASSERT_TRUE
(
wait_for_list
(
lcs
,
&
pauline
->
stat
.
number_of_LinphoneCallIncomingEarlyMedia
,
1
,
2000
)
);
CU_ASSERT_TRUE
(
wait_for_list
(
lcs
,
&
marie
->
stat
.
number_of_LinphoneCallOutgoingEarlyMedia
,
1
,
2000
)
);
pauline_call
=
linphone_core_get_current_call
(
pauline
->
lc
);
pauline_params
=
linphone_call_params_copy
(
linphone_call_get_current_params
(
pauline_call
));
if
(
media_change
)
{
disable_all_codecs_except_one
(
marie
->
lc
,
"pcma"
);
disable_all_codecs_except_one
(
pauline
->
lc
,
"pcma"
);
}
#define UPDATED_SESSION_NAME "nouveau nom de session"
linphone_call_params_set_session_name
(
pauline_params
,
UPDATED_SESSION_NAME
);
linphone_core_update_call
(
pauline
->
lc
,
pauline_call
,
pauline_params
);
/*just to wait 2s*/
liblinphone_tester_check_rtcp
(
marie
,
pauline
);
wait_for_list
(
lcs
,
&
marie
->
stat
.
number_of_LinphoneCallUpdatedByRemote
,
100000
,
2000
);
CU_ASSERT_STRING_EQUAL
(
linphone_call_params_get_session_name
(
linphone_call_get_remote_params
(
marie_call
))
,
UPDATED_SESSION_NAME
);
linphone_core_accept_call
(
pauline
->
lc
,
linphone_core_get_current_call
(
pauline
->
lc
));
CU_ASSERT_TRUE
(
wait_for_list
(
lcs
,
&
marie
->
stat
.
number_of_LinphoneCallStreamsRunning
,
1
,
1000
));
CU_ASSERT_EQUAL
(
marie
->
stat
.
number_of_LinphoneCallOutgoingEarlyMedia
,
1
);
CU_ASSERT_EQUAL
(
marie
->
stat
.
number_of_LinphoneCallStreamsRunning
,
1
);
CU_ASSERT_EQUAL
(
marie
->
stat
.
number_of_LinphoneCallConnected
,
1
);
CU_ASSERT_EQUAL
(
pauline
->
stat
.
number_of_LinphoneCallIncomingEarlyMedia
,
1
);
CU_ASSERT_EQUAL
(
pauline
->
stat
.
number_of_LinphoneCallStreamsRunning
,
1
);
CU_ASSERT_EQUAL
(
pauline
->
stat
.
number_of_LinphoneCallConnected
,
1
);
CU_ASSERT_EQUAL
(
pauline
->
stat
.
number_of_LinphoneCallUpdating
,
1
);
liblinphone_tester_check_rtcp
(
marie
,
pauline
);
linphone_core_terminate_all_calls
(
pauline
->
lc
);
CU_ASSERT_TRUE
(
wait_for_list
(
lcs
,
&
pauline
->
stat
.
number_of_LinphoneCallEnd
,
1
,
1000
));
CU_ASSERT_TRUE
(
wait_for_list
(
lcs
,
&
marie
->
stat
.
number_of_LinphoneCallEnd
,
1
,
1000
));
ms_list_free
(
lcs
);
linphone_core_manager_destroy
(
marie
);
linphone_core_manager_destroy
(
pauline
);
}
static
void
early_media_call_with_session_update
(
void
){
early_media_call_with_update_base
(
FALSE
);
}
static
void
early_media_call_with_codec_update
(
void
){
early_media_call_with_update_base
(
TRUE
);
}
static
void
simple_call_transfer
(
void
)
{
LinphoneCoreManager
*
marie
=
linphone_core_manager_new
(
"marie_rc"
);
...
...
@@ -1612,6 +1698,8 @@ test_t call_tests[] = {
{
"Simple call compatibility mode"
,
simple_call_compatibility_mode
},
{
"Early-media call"
,
early_media_call
},
{
"Early-media call with ringing"
,
early_media_call_with_ringing
},
{
"Early-media call with updated media session"
,
early_media_call_with_session_update
},
{
"Early-media call with updated codec"
,
early_media_call_with_codec_update
},
{
"Call terminated by caller"
,
call_terminated_by_caller
},
{
"Call without SDP"
,
call_with_no_sdp
},
{
"Call paused resumed"
,
call_paused_resumed
},
...
...
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