mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-25 15:18:11 +00:00
Merge branch 'quality_reporting'
Conflicts: coreapi/linphonecall.c mediastreamer2 tester/call_tester.c
This commit is contained in:
commit
ceb8533cf9
16 changed files with 1069 additions and 197 deletions
|
|
@ -64,7 +64,8 @@ LOCAL_SRC_FILES := \
|
|||
xml.c \
|
||||
xml2lpc.c \
|
||||
lpc2xml.c \
|
||||
remote_provisioning.c
|
||||
remote_provisioning.c \
|
||||
quality_reporting.c
|
||||
|
||||
ifndef LINPHONE_VERSION
|
||||
LINPHONE_VERSION = "Devel"
|
||||
|
|
|
|||
|
|
@ -203,6 +203,7 @@
|
|||
<ClCompile Include="..\..\..\coreapi\offeranswer.c" />
|
||||
<ClCompile Include="..\..\..\coreapi\presence.c" />
|
||||
<ClCompile Include="..\..\..\coreapi\proxy.c" />
|
||||
<ClCompile Include="..\..\..\coreapi\quality_reporting.c" />
|
||||
<ClCompile Include="..\..\..\coreapi\sal.c" />
|
||||
<ClCompile Include="..\..\..\coreapi\siplogin.c" />
|
||||
<ClCompile Include="..\..\..\coreapi\sipsetup.c" />
|
||||
|
|
@ -275,4 +276,4 @@
|
|||
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsPhone\v$(TargetPlatformVersion)\Microsoft.Cpp.WindowsPhone.$(TargetPlatformVersion).targets" Condition="'$(Platform)'=='ARM'" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
|
|
|||
|
|
@ -74,6 +74,7 @@ set(SOURCE_FILES
|
|||
offeranswer.c
|
||||
presence.c
|
||||
proxy.c
|
||||
quality_reporting.c
|
||||
remote_provisioning.c
|
||||
sal.c
|
||||
siplogin.c
|
||||
|
|
|
|||
|
|
@ -56,6 +56,7 @@ liblinphone_la_SOURCES=\
|
|||
xml2lpc.c \
|
||||
lpc2xml.c \
|
||||
remote_provisioning.c \
|
||||
quality_reporting.c \
|
||||
$(GITVERSION_FILE)
|
||||
|
||||
if BUILD_UPNP
|
||||
|
|
|
|||
|
|
@ -393,7 +393,7 @@ static int find_port_offset(LinphoneCore *lc, int stream_index, int base_port){
|
|||
int tried_port;
|
||||
int existing_port;
|
||||
bool_t already_used=FALSE;
|
||||
|
||||
|
||||
for(offset=0;offset<100;offset+=2){
|
||||
tried_port=base_port+offset;
|
||||
already_used=FALSE;
|
||||
|
|
@ -480,10 +480,10 @@ static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from,
|
|||
|
||||
linphone_core_get_audio_port_range(call->core, &min_port, &max_port);
|
||||
port_config_set(call,0,min_port,max_port);
|
||||
|
||||
|
||||
linphone_core_get_video_port_range(call->core, &min_port, &max_port);
|
||||
port_config_set(call,1,min_port,max_port);
|
||||
|
||||
|
||||
linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_AUDIO], LINPHONE_CALL_STATS_AUDIO);
|
||||
linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_VIDEO], LINPHONE_CALL_STATS_VIDEO);
|
||||
}
|
||||
|
|
@ -768,7 +768,6 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ms_message("Call %p: moving from state %s to %s",call,linphone_call_state_to_string(call->state),
|
||||
linphone_call_state_to_string(cstate));
|
||||
|
||||
|
|
@ -777,6 +776,7 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const
|
|||
Indeed it does not change the state of the call (still paused or running)*/
|
||||
call->state=cstate;
|
||||
}
|
||||
|
||||
if (cstate==LinphoneCallEnd || cstate==LinphoneCallError){
|
||||
switch(call->non_op_error.reason){
|
||||
case SalReasonDeclined:
|
||||
|
|
@ -795,9 +795,17 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const
|
|||
call->media_start_time=time(NULL);
|
||||
}
|
||||
|
||||
if (cstate == LinphoneCallStreamsRunning) {
|
||||
linphone_reporting_update_ip(call);
|
||||
}
|
||||
|
||||
if (lc->vtable.call_state_changed)
|
||||
lc->vtable.call_state_changed(lc,call,cstate,message);
|
||||
if (cstate==LinphoneCallReleased){
|
||||
|
||||
if (call->log->status == LinphoneCallSuccess)
|
||||
linphone_reporting_publish(call);
|
||||
|
||||
if (call->op!=NULL) {
|
||||
/*transfer the last error so that it can be obtained even in Released state*/
|
||||
if (call->non_op_error.reason==SalReasonNone){
|
||||
|
|
@ -1301,7 +1309,7 @@ const char *linphone_call_params_get_session_name(const LinphoneCallParams *cp){
|
|||
/**
|
||||
* Set the session name of the media session (ie in SDP). Subject from the SIP message (which is different) can be set using linphone_call_params_set_custom_header().
|
||||
* @param cp the call parameters.
|
||||
* @param name the session name
|
||||
* @param name the session name
|
||||
**/
|
||||
void linphone_call_params_set_session_name(LinphoneCallParams *cp, const char *name){
|
||||
if (cp->session_name){
|
||||
|
|
@ -1451,17 +1459,17 @@ static void _linphone_call_prepare_ice_for_stream(LinphoneCall *call, int stream
|
|||
int linphone_call_prepare_ice(LinphoneCall *call, bool_t incoming_offer){
|
||||
SalMediaDescription *remote;
|
||||
bool_t has_video=FALSE;
|
||||
|
||||
|
||||
if ((linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseIce) && (call->ice_session != NULL)){
|
||||
if (incoming_offer){
|
||||
remote=sal_call_get_remote_media_description(call->op);
|
||||
has_video=linphone_core_media_description_contains_video_stream(remote);
|
||||
}else has_video=call->params.has_video;
|
||||
|
||||
|
||||
_linphone_call_prepare_ice_for_stream(call,0,TRUE);
|
||||
if (has_video) _linphone_call_prepare_ice_for_stream(call,1,TRUE);
|
||||
/*start ICE gathering*/
|
||||
if (incoming_offer)
|
||||
if (incoming_offer)
|
||||
linphone_core_update_ice_from_remote_media_description(call,remote); /*this may delete the ice session*/
|
||||
if (call->ice_session && !ice_session_candidates_gathered(call->ice_session)){
|
||||
if (call->audiostream->ms.state==MSStreamInitialized)
|
||||
|
|
@ -1536,7 +1544,7 @@ void linphone_call_init_audio_stream(LinphoneCall *call){
|
|||
|
||||
call->audiostream_app_evq = ortp_ev_queue_new();
|
||||
rtp_session_register_event_queue(audiostream->ms.sessions.rtp_session,call->audiostream_app_evq);
|
||||
|
||||
|
||||
_linphone_call_prepare_ice_for_stream(call,0,FALSE);
|
||||
}
|
||||
|
||||
|
|
@ -1548,7 +1556,7 @@ void linphone_call_init_video_stream(LinphoneCall *call){
|
|||
int video_recv_buf_size=lp_config_get_int(lc->config,"video","recv_buf_size",0);
|
||||
int dscp=linphone_core_get_video_dscp(lc);
|
||||
const char *display_filter=linphone_core_get_video_display_filter(lc);
|
||||
|
||||
|
||||
if (call->sessions[1].rtp_session==NULL){
|
||||
call->videostream=video_stream_new(call->media_ports[1].rtp_port,call->media_ports[1].rtcp_port, call->af==AF_INET6);
|
||||
}else{
|
||||
|
|
@ -1956,7 +1964,7 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna
|
|||
#ifdef VIDEO_ENABLED
|
||||
LinphoneCore *lc=call->core;
|
||||
int used_pt=-1;
|
||||
|
||||
|
||||
/* look for savp stream first */
|
||||
const SalStreamDescription *vstream=sal_media_description_find_stream(call->resultdesc,
|
||||
SalProtoRtpSavp,SalVideo);
|
||||
|
|
@ -1978,8 +1986,9 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna
|
|||
const char *rtp_addr=vstream->rtp_addr[0]!='\0' ? vstream->rtp_addr : call->resultdesc->addr;
|
||||
const char *rtcp_addr=vstream->rtcp_addr[0]!='\0' ? vstream->rtcp_addr : call->resultdesc->addr;
|
||||
const SalStreamDescription *local_st_desc=sal_media_description_find_stream(call->localdesc,vstream->proto,SalVideo);
|
||||
|
||||
|
||||
call->video_profile=make_profile(call,call->resultdesc,vstream,&used_pt);
|
||||
|
||||
if (used_pt!=-1){
|
||||
VideoStreamDir dir=VideoStreamSendRecv;
|
||||
MSWebCam *cam=lc->video_conf.device;
|
||||
|
|
@ -2143,7 +2152,7 @@ void linphone_call_update_crypto_parameters(LinphoneCall *call, SalMediaDescript
|
|||
SalStreamDescription *old_stream;
|
||||
SalStreamDescription *new_stream;
|
||||
const SalStreamDescription *local_st_desc;
|
||||
|
||||
|
||||
local_st_desc = sal_media_description_find_stream(call->localdesc, SalProtoRtpSavp, SalAudio);
|
||||
old_stream = sal_media_description_find_stream(old_md, SalProtoRtpSavp, SalAudio);
|
||||
new_stream = sal_media_description_find_stream(new_md, SalProtoRtpSavp, SalAudio);
|
||||
|
|
@ -2202,6 +2211,7 @@ static void linphone_call_log_fill_stats(LinphoneCallLog *log, MediaStream *st){
|
|||
|
||||
void linphone_call_stop_audio_stream(LinphoneCall *call) {
|
||||
if (call->audiostream!=NULL) {
|
||||
linphone_reporting_update(call, LINPHONE_CALL_STATS_AUDIO);
|
||||
media_stream_reclaim_sessions(&call->audiostream->ms,&call->sessions[0]);
|
||||
rtp_session_unregister_event_queue(call->audiostream->ms.sessions.rtp_session,call->audiostream_app_evq);
|
||||
ortp_ev_queue_flush(call->audiostream_app_evq);
|
||||
|
|
@ -2230,6 +2240,7 @@ void linphone_call_stop_audio_stream(LinphoneCall *call) {
|
|||
void linphone_call_stop_video_stream(LinphoneCall *call) {
|
||||
#ifdef VIDEO_ENABLED
|
||||
if (call->videostream!=NULL){
|
||||
linphone_reporting_update(call, LINPHONE_CALL_STATS_VIDEO);
|
||||
media_stream_reclaim_sessions(&call->videostream->ms,&call->sessions[1]);
|
||||
rtp_session_unregister_event_queue(call->videostream->ms.sessions.rtp_session,call->videostream_app_evq);
|
||||
ortp_ev_queue_flush(call->videostream_app_evq);
|
||||
|
|
@ -2756,6 +2767,8 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse
|
|||
evd->packet = NULL;
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].updated = LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE;
|
||||
update_local_stats(&call->stats[LINPHONE_CALL_STATS_VIDEO],(MediaStream*)call->videostream);
|
||||
if (linphone_call_params_video_enabled(linphone_call_get_current_params(call)))
|
||||
linphone_reporting_call_stats_updated(call, LINPHONE_CALL_STATS_VIDEO);
|
||||
if (lc->vtable.call_stats_updated)
|
||||
lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_VIDEO]);
|
||||
} else if (evt == ORTP_EVENT_RTCP_PACKET_EMITTED) {
|
||||
|
|
@ -2766,6 +2779,8 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse
|
|||
evd->packet = NULL;
|
||||
call->stats[LINPHONE_CALL_STATS_VIDEO].updated = LINPHONE_CALL_STATS_SENT_RTCP_UPDATE;
|
||||
update_local_stats(&call->stats[LINPHONE_CALL_STATS_VIDEO],(MediaStream*)call->videostream);
|
||||
if (linphone_call_params_video_enabled(linphone_call_get_current_params(call)))
|
||||
linphone_reporting_call_stats_updated(call, LINPHONE_CALL_STATS_VIDEO);
|
||||
if (lc->vtable.call_stats_updated)
|
||||
lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_VIDEO]);
|
||||
} else if ((evt == ORTP_EVENT_ICE_SESSION_PROCESSING_FINISHED) || (evt == ORTP_EVENT_ICE_GATHERING_FINISHED)
|
||||
|
|
@ -2801,6 +2816,7 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse
|
|||
evd->packet = NULL;
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].updated = LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE;
|
||||
update_local_stats(&call->stats[LINPHONE_CALL_STATS_AUDIO],(MediaStream*)call->audiostream);
|
||||
linphone_reporting_call_stats_updated(call, LINPHONE_CALL_STATS_AUDIO);
|
||||
if (lc->vtable.call_stats_updated)
|
||||
lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_AUDIO]);
|
||||
} else if (evt == ORTP_EVENT_RTCP_PACKET_EMITTED) {
|
||||
|
|
@ -2811,6 +2827,7 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse
|
|||
evd->packet = NULL;
|
||||
call->stats[LINPHONE_CALL_STATS_AUDIO].updated = LINPHONE_CALL_STATS_SENT_RTCP_UPDATE;
|
||||
update_local_stats(&call->stats[LINPHONE_CALL_STATS_AUDIO],(MediaStream*)call->audiostream);
|
||||
linphone_reporting_call_stats_updated(call, LINPHONE_CALL_STATS_AUDIO);
|
||||
if (lc->vtable.call_stats_updated)
|
||||
lc->vtable.call_stats_updated(lc, call, &call->stats[LINPHONE_CALL_STATS_AUDIO]);
|
||||
} else if ((evt == ORTP_EVENT_ICE_SESSION_PROCESSING_FINISHED) || (evt == ORTP_EVENT_ICE_GATHERING_FINISHED)
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
#include "sipsetup.h"
|
||||
#include "lpconfig.h"
|
||||
#include "private.h"
|
||||
#include "quality_reporting.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <ortp/telephonyevents.h>
|
||||
|
|
@ -127,6 +128,9 @@ LinphoneCallLog * linphone_call_log_new(LinphoneCall *call, LinphoneAddress *fro
|
|||
cl->to=to;
|
||||
cl->status=LinphoneCallAborted; /*default status*/
|
||||
cl->quality=-1;
|
||||
|
||||
cl->reports[LINPHONE_CALL_STATS_AUDIO]=linphone_reporting_new();
|
||||
cl->reports[LINPHONE_CALL_STATS_VIDEO]=linphone_reporting_new();
|
||||
return cl;
|
||||
}
|
||||
|
||||
|
|
@ -390,6 +394,9 @@ void linphone_call_log_destroy(LinphoneCallLog *cl){
|
|||
if (cl->to!=NULL) linphone_address_destroy(cl->to);
|
||||
if (cl->refkey!=NULL) ms_free(cl->refkey);
|
||||
if (cl->call_id) ms_free(cl->call_id);
|
||||
if (cl->reports[LINPHONE_CALL_STATS_AUDIO]!=NULL) linphone_reporting_destroy(cl->reports[LINPHONE_CALL_STATS_AUDIO]);
|
||||
if (cl->reports[LINPHONE_CALL_STATS_VIDEO]!=NULL) linphone_reporting_destroy(cl->reports[LINPHONE_CALL_STATS_VIDEO]);
|
||||
|
||||
ms_free(cl);
|
||||
}
|
||||
|
||||
|
|
@ -607,7 +614,7 @@ static void sound_config_read(LinphoneCore *lc)
|
|||
|
||||
linphone_core_set_play_file(lc,lp_config_get_string(lc->config,"sound","hold_music",PACKAGE_SOUND_DIR "/" HOLD_MUSIC));
|
||||
lc->sound_conf.latency=0;
|
||||
#ifndef __ios
|
||||
#ifndef __ios
|
||||
tmp=TRUE;
|
||||
#else
|
||||
tmp=FALSE; /* on iOS we have builtin echo cancellation.*/
|
||||
|
|
@ -626,7 +633,7 @@ static void sound_config_read(LinphoneCore *lc)
|
|||
|
||||
/*just parse requested stream feature once at start to print out eventual errors*/
|
||||
linphone_core_get_audio_features(lc);
|
||||
|
||||
|
||||
_linphone_core_set_tone(lc,LinphoneReasonBusy,LinphoneToneBusy,NULL);
|
||||
}
|
||||
|
||||
|
|
@ -640,7 +647,7 @@ static void certificates_config_read(LinphoneCore *lc)
|
|||
#endif
|
||||
linphone_core_set_root_ca(lc,rootca);
|
||||
linphone_core_verify_server_certificates(lc,lp_config_get_int(lc->config,"sip","verify_server_certs",TRUE));
|
||||
linphone_core_verify_server_cn(lc,lp_config_get_int(lc->config,"sip","verify_server_cn",TRUE));
|
||||
linphone_core_verify_server_cn(lc,lp_config_get_int(lc->config,"sip","verify_server_cn",TRUE));
|
||||
}
|
||||
|
||||
static void sip_config_read(LinphoneCore *lc)
|
||||
|
|
@ -663,12 +670,12 @@ static void sip_config_read(LinphoneCore *lc)
|
|||
}
|
||||
linphone_core_enable_ipv6(lc,ipv6);
|
||||
memset(&tr,0,sizeof(tr));
|
||||
|
||||
|
||||
tr.udp_port=lp_config_get_int(lc->config,"sip","sip_port",5060);
|
||||
tr.tcp_port=lp_config_get_int(lc->config,"sip","sip_tcp_port",5060);
|
||||
/*we are not listening inbound connection for tls, port has no meaning*/
|
||||
tr.tls_port=lp_config_get_int(lc->config,"sip","sip_tls_port",LC_SIP_TRANSPORT_RANDOM);
|
||||
|
||||
|
||||
certificates_config_read(lc);
|
||||
/*setting the dscp must be done before starting the transports, otherwise it is not taken into effect*/
|
||||
sal_set_dscp(lc->sal,linphone_core_get_sip_dscp(lc));
|
||||
|
|
@ -703,7 +710,7 @@ static void sip_config_read(LinphoneCore *lc)
|
|||
|
||||
tmp=lp_config_get_int(lc->config,"sip","in_call_timeout",0);
|
||||
linphone_core_set_in_call_timeout(lc,tmp);
|
||||
|
||||
|
||||
tmp=lp_config_get_int(lc->config,"sip","delayed_timeout",4);
|
||||
linphone_core_set_delayed_timeout(lc,tmp);
|
||||
|
||||
|
|
@ -975,8 +982,8 @@ static void video_config_read(LinphoneCore *lc){
|
|||
int capture, display, self_view;
|
||||
int automatic_video=1;
|
||||
#endif
|
||||
const char *str;
|
||||
#ifdef VIDEO_ENABLED
|
||||
const char *str;
|
||||
#ifdef VIDEO_ENABLED
|
||||
LinphoneVideoPolicy vpol;
|
||||
memset(&vpol, 0, sizeof(LinphoneVideoPolicy));
|
||||
#endif
|
||||
|
|
@ -1039,7 +1046,7 @@ bool_t linphone_core_tunnel_available(void){
|
|||
|
||||
/**
|
||||
* Enable adaptive rate control.
|
||||
*
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
*
|
||||
* Adaptive rate control consists in using RTCP feedback provided information to dynamically
|
||||
|
|
@ -1053,7 +1060,7 @@ void linphone_core_enable_adaptive_rate_control(LinphoneCore *lc, bool_t enabled
|
|||
|
||||
/**
|
||||
* Returns whether adaptive rate control is enabled.
|
||||
*
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
*
|
||||
* See linphone_core_enable_adaptive_rate_control().
|
||||
|
|
@ -1073,7 +1080,7 @@ bool_t linphone_core_rtcp_enabled(const LinphoneCore *lc){
|
|||
* calls (within SDP messages) so that the remote end can have
|
||||
* sufficient knowledge to properly configure its audio & video
|
||||
* codec output bitrate to not overflow available bandwidth.
|
||||
*
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
*
|
||||
* @param lc the LinphoneCore object
|
||||
|
|
@ -1159,7 +1166,7 @@ void linphone_core_set_upload_ptime(LinphoneCore *lc, int ptime){
|
|||
* Set audio packetization time linphone will send (in absence of requirement from peer)
|
||||
* A value of 0 stands for the current codec default packetization time.
|
||||
*
|
||||
*
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
int linphone_core_get_upload_ptime(LinphoneCore *lc){
|
||||
|
|
@ -1180,14 +1187,14 @@ const char * linphone_core_get_version(void){
|
|||
|
||||
static void linphone_core_assign_payload_type(LinphoneCore *lc, PayloadType *const_pt, int number, const char *recv_fmtp){
|
||||
PayloadType *pt;
|
||||
|
||||
|
||||
#ifdef ANDROID
|
||||
if (const_pt->channels==2){
|
||||
ms_message("Stereo %s codec not supported on this platform.",const_pt->mime_type);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
pt=payload_type_clone(const_pt);
|
||||
if (number==-1){
|
||||
/*look for a free number */
|
||||
|
|
@ -1251,10 +1258,10 @@ void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const
|
|||
static void misc_config_read(LinphoneCore *lc) {
|
||||
LpConfig *config=lc->config;
|
||||
const char *uuid;
|
||||
|
||||
|
||||
lc->max_call_logs=lp_config_get_int(config,"misc","history_max_size",15);
|
||||
lc->max_calls=lp_config_get_int(config,"misc","max_calls",NB_MAX_CALLS);
|
||||
|
||||
|
||||
uuid=lp_config_get_string(config,"misc","uuid",NULL);
|
||||
if (!uuid){
|
||||
char tmp[64];
|
||||
|
|
@ -1290,12 +1297,12 @@ static void linphone_core_start(LinphoneCore * lc) {
|
|||
void linphone_configuring_terminated(LinphoneCore *lc, LinphoneConfiguringState state, const char *message) {
|
||||
if (lc->vtable.configuring_status)
|
||||
lc->vtable.configuring_status(lc, state, message);
|
||||
|
||||
|
||||
if (state == LinphoneConfiguringSuccessful) {
|
||||
if (linphone_core_is_provisioning_transient(lc) == TRUE)
|
||||
linphone_core_set_provisioning_uri(lc, NULL);
|
||||
}
|
||||
|
||||
|
||||
linphone_core_start(lc);
|
||||
}
|
||||
|
||||
|
|
@ -1342,7 +1349,7 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab
|
|||
linphone_core_assign_payload_type(lc,&payload_type_mp4v,99,"profile-level-id=3");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_h264,102,"profile-level-id=42801F");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_vp8,103,NULL);
|
||||
|
||||
|
||||
linphone_core_assign_payload_type(lc,&payload_type_theora,97,NULL);
|
||||
linphone_core_assign_payload_type(lc,&payload_type_x_snow,-1,NULL);
|
||||
/* due to limited space in SDP, we have to disable this h264 line which is normally no more necessary */
|
||||
|
|
@ -1372,7 +1379,7 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab
|
|||
linphone_core_assign_payload_type(lc,&payload_type_opus,-1,"useinbandfec=1; usedtx=0; cbr=1");
|
||||
linphone_core_assign_payload_type(lc,&payload_type_isac,-1,NULL);
|
||||
linphone_core_handle_static_payloads(lc);
|
||||
|
||||
|
||||
ms_init();
|
||||
/* create a mediastreamer2 event queue and set it as global */
|
||||
/* This allows to run event's callback in linphone_core_iterate() */
|
||||
|
|
@ -1386,13 +1393,13 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab
|
|||
|
||||
lc->network_last_check = 0;
|
||||
lc->network_last_status = FALSE;
|
||||
|
||||
|
||||
lc->http_provider = belle_sip_stack_create_http_provider(sal_get_belle_sip_stack(lc->sal), "0.0.0.0");
|
||||
lc->http_verify_policy = belle_tls_verify_policy_new();
|
||||
belle_http_provider_set_tls_verify_policy(lc->http_provider,lc->http_verify_policy);
|
||||
|
||||
|
||||
certificates_config_read(lc);
|
||||
|
||||
|
||||
remote_provisioning_uri = linphone_core_get_provisioning_uri(lc);
|
||||
if (remote_provisioning_uri == NULL) {
|
||||
linphone_configuring_terminated(lc, LinphoneConfiguringSkipped, NULL);
|
||||
|
|
@ -1940,7 +1947,7 @@ static int apply_transports(LinphoneCore *lc){
|
|||
|
||||
/*first of all invalidate all current registrations so that we can register again with new transports*/
|
||||
__linphone_core_invalidate_registers(lc);
|
||||
|
||||
|
||||
if (lc->sip_conf.ipv6_enabled)
|
||||
anyaddr="::0";
|
||||
else
|
||||
|
|
@ -2212,7 +2219,7 @@ void linphone_core_iterate(LinphoneCore *lc){
|
|||
int elapsed;
|
||||
bool_t one_second_elapsed=FALSE;
|
||||
const char *remote_provisioning_uri = NULL;
|
||||
|
||||
|
||||
if (linphone_core_get_global_state(lc) == LinphoneGlobalStartup) {
|
||||
if (sal_get_root_ca(lc->sal)) {
|
||||
belle_tls_verify_policy_t *tls_policy = belle_tls_verify_policy_new();
|
||||
|
|
@ -2223,7 +2230,7 @@ void linphone_core_iterate(LinphoneCore *lc){
|
|||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc, _("Configuring"));
|
||||
linphone_core_set_state(lc, LinphoneGlobalConfiguring, "Configuring");
|
||||
|
||||
|
||||
remote_provisioning_uri = linphone_core_get_provisioning_uri(lc);
|
||||
if (remote_provisioning_uri) {
|
||||
int err = linphone_remote_provisioning_download_and_apply(lc, remote_provisioning_uri);
|
||||
|
|
@ -2246,7 +2253,7 @@ void linphone_core_iterate(LinphoneCore *lc){
|
|||
if (ecs==LinphoneEcCalibratorDone){
|
||||
int len=lp_config_get_int(lc->config,"sound","ec_tail_len",0);
|
||||
int margin=len/2;
|
||||
|
||||
|
||||
lp_config_set_int(lc->config, "sound", "ec_delay",MAX(lc->ecc->delay-margin,0));
|
||||
} else if (ecs == LinphoneEcCalibratorFailed) {
|
||||
lp_config_set_int(lc->config, "sound", "ec_delay", -1);/*use default value from soundcard*/
|
||||
|
|
@ -2359,7 +2366,7 @@ void linphone_core_iterate(LinphoneCore *lc){
|
|||
/**
|
||||
* Interpret a call destination as supplied by the user, and returns a fully qualified
|
||||
* LinphoneAddress.
|
||||
*
|
||||
*
|
||||
* @ingroup call_control
|
||||
*
|
||||
* A sip address should look like DisplayName <sip:username@domain:port> .
|
||||
|
|
@ -2378,7 +2385,7 @@ LinphoneAddress * linphone_core_interpret_url(LinphoneCore *lc, const char *url)
|
|||
LinphoneProxyConfig *proxy=lc->default_proxy;
|
||||
char *tmpurl;
|
||||
LinphoneAddress *uri;
|
||||
|
||||
|
||||
if (*url=='\0') return NULL;
|
||||
|
||||
if (is_enum(url,&enum_domain)){
|
||||
|
|
@ -2428,7 +2435,7 @@ LinphoneAddress * linphone_core_interpret_url(LinphoneCore *lc, const char *url)
|
|||
if (uri!=NULL){
|
||||
return uri;
|
||||
}
|
||||
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -2466,7 +2473,7 @@ const char * linphone_core_get_route(LinphoneCore *lc){
|
|||
* Start a new call as a consequence of a transfer request received from a call.
|
||||
* This function is for advanced usage: the execution of transfers is automatically managed by the LinphoneCore. However if an application
|
||||
* wants to have control over the call parameters for the new call, it should call this function immediately during the LinphoneCallRefered notification.
|
||||
* @see LinphoneCoreVTable::call_state_changed
|
||||
* @see LinphoneCoreVTable::call_state_changed
|
||||
* @param lc the LinphoneCore
|
||||
* @param call a call that has just been notified about LinphoneCallRefered state event.
|
||||
* @param params the call parameters to be applied to the new call.
|
||||
|
|
@ -2475,13 +2482,13 @@ const char * linphone_core_get_route(LinphoneCore *lc){
|
|||
LinphoneCall * linphone_core_start_refered_call(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){
|
||||
LinphoneCallParams *cp=params ? linphone_call_params_copy(params) : linphone_core_create_default_call_parameters(lc);
|
||||
LinphoneCall *newcall;
|
||||
|
||||
|
||||
if (call->state!=LinphoneCallPaused){
|
||||
ms_message("Automatically pausing current call to accept transfer.");
|
||||
_linphone_core_pause_call(lc,call);
|
||||
call->was_automatically_paused=TRUE;
|
||||
}
|
||||
|
||||
|
||||
if (!params){
|
||||
cp->has_video = call->current_params.has_video; /*start the call to refer-target with video enabled if original call had video*/
|
||||
}
|
||||
|
|
@ -2521,7 +2528,7 @@ void linphone_core_notify_refer_state(LinphoneCore *lc, LinphoneCall *referer, L
|
|||
nodes with the basic SIP routing policy in order to get a workable
|
||||
system.
|
||||
*/
|
||||
|
||||
|
||||
static MSList *make_routes_for_proxy(LinphoneProxyConfig *proxy, const LinphoneAddress *dest){
|
||||
MSList *ret=NULL;
|
||||
const char *local_route=linphone_proxy_config_get_route(proxy);
|
||||
|
|
@ -2816,7 +2823,7 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
|
|||
bool_t defer = FALSE;
|
||||
|
||||
linphone_core_preempt_sound_resources(lc);
|
||||
|
||||
|
||||
if(!linphone_core_can_we_add_call(lc)){
|
||||
if (lc->vtable.display_warning)
|
||||
lc->vtable.display_warning(lc,_("Sorry, we have reached the maximum number of simultaneous calls"));
|
||||
|
|
@ -2848,7 +2855,7 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
|
|||
linphone_call_set_state (call,LinphoneCallOutgoingInit,"Starting outgoing call");
|
||||
call->log->start_date_time=time(NULL);
|
||||
linphone_call_init_media_streams(call);
|
||||
|
||||
|
||||
if (linphone_core_get_firewall_policy(call->core) == LinphonePolicyUseIce) {
|
||||
/* Defer the start of the call after the ICE gathering process. */
|
||||
if (linphone_call_prepare_ice(call,FALSE)==1)
|
||||
|
|
@ -2880,7 +2887,7 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
|
|||
defer = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (defer==FALSE) linphone_core_start_invite(lc,call,NULL);
|
||||
|
||||
if (real_url!=NULL) ms_free(real_url);
|
||||
|
|
@ -2893,7 +2900,7 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
|
|||
* @ingroup call_control
|
||||
* The remote endpoint is expected to issue a new call to the specified destination.
|
||||
* The current call remains active and thus can be later paused or terminated.
|
||||
*
|
||||
*
|
||||
* It is possible to follow the progress of the transfer provided that transferee sends notification about it.
|
||||
* In this case, the transfer_state_changed callback of the #LinphoneCoreVTable is invoked to notify of the state of the new call at the other party.
|
||||
* The notified states are #LinphoneCallOutgoingInit , #LinphoneCallOutgoingProgress, #LinphoneCallOutgoingRinging and #LinphoneCallOutgoingConnected.
|
||||
|
|
@ -2925,7 +2932,7 @@ int linphone_core_transfer_call(LinphoneCore *lc, LinphoneCall *call, const char
|
|||
* @param lc linphone core object
|
||||
* @param call a running call you want to transfer
|
||||
* @param dest a running call whose remote person will receive the transfer
|
||||
*
|
||||
*
|
||||
* @ingroup call_control
|
||||
*
|
||||
* The transfered call is supposed to be in paused state, so that it is able to accept the transfer immediately.
|
||||
|
|
@ -2933,7 +2940,7 @@ int linphone_core_transfer_call(LinphoneCore *lc, LinphoneCall *call, const char
|
|||
* This method will send a transfer request to the transfered person. The phone of the transfered is then
|
||||
* expected to automatically call to the destination of the transfer. The receiver of the transfer will then automatically
|
||||
* close the call with us (the 'dest' call).
|
||||
*
|
||||
*
|
||||
* It is possible to follow the progress of the transfer provided that transferee sends notification about it.
|
||||
* In this case, the transfer_state_changed callback of the #LinphoneCoreVTable is invoked to notify of the state of the new call at the other party.
|
||||
* The notified states are #LinphoneCallOutgoingInit , #LinphoneCallOutgoingProgress, #LinphoneCallOutgoingRinging and #LinphoneCallOutgoingConnected.
|
||||
|
|
@ -2958,7 +2965,7 @@ bool_t linphone_core_inc_invite_pending(LinphoneCore*lc){
|
|||
bool_t linphone_core_media_description_has_srtp(const SalMediaDescription *md){
|
||||
int i;
|
||||
if (md->n_active_streams==0) return FALSE;
|
||||
|
||||
|
||||
for(i=0;i<md->n_active_streams;i++){
|
||||
const SalStreamDescription *sd=&md->streams[i];
|
||||
if (sd->proto!=SalProtoRtpSavp){
|
||||
|
|
@ -3031,11 +3038,11 @@ void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){
|
|||
if (call->state==LinphoneCallIncomingReceived){
|
||||
/*try to be best-effort in giving real local or routable contact address for 100Rel case*/
|
||||
linphone_call_set_contact_op(call);
|
||||
|
||||
|
||||
if (propose_early_media || ringback_tone!=NULL){
|
||||
linphone_core_accept_early_media(lc,call);
|
||||
}else sal_call_notify_ringing(call->op,FALSE);
|
||||
|
||||
|
||||
if (sal_call_get_replaces(call->op)!=NULL && lp_config_get_int(lc->config,"sip","auto_answer_replacing_calls",1)){
|
||||
linphone_core_accept_call(lc,call);
|
||||
}
|
||||
|
|
@ -3061,7 +3068,7 @@ void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){
|
|||
int linphone_core_accept_early_media_with_params(LinphoneCore* lc, LinphoneCall* call, const LinphoneCallParams* params) {
|
||||
if (call->state==LinphoneCallIncomingReceived){
|
||||
SalMediaDescription* md;
|
||||
|
||||
|
||||
/*try to be best-effort in giving real local or routable contact address for 100Rel case*/
|
||||
linphone_call_set_contact_op(call);
|
||||
|
||||
|
|
@ -3072,7 +3079,7 @@ int linphone_core_accept_early_media_with_params(LinphoneCore* lc, LinphoneCall*
|
|||
sal_call_set_local_media_description ( call->op,call->localdesc );
|
||||
sal_op_set_sent_custom_header ( call->op,params->custom_headers );
|
||||
}
|
||||
|
||||
|
||||
sal_call_notify_ringing(call->op,TRUE);
|
||||
|
||||
linphone_call_set_state(call,LinphoneCallIncomingEarlyMedia,"Incoming call early media");
|
||||
|
|
@ -3202,15 +3209,15 @@ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const Linpho
|
|||
/**
|
||||
* @ingroup call_control
|
||||
* When receiving a #LinphoneCallUpdatedByRemote state notification, prevent LinphoneCore from performing an automatic answer.
|
||||
*
|
||||
*
|
||||
* When receiving a #LinphoneCallUpdatedByRemote state notification (ie an incoming reINVITE), the default behaviour of
|
||||
* LinphoneCore is to automatically answer the reINIVTE with call parameters unchanged.
|
||||
* However when for example when the remote party updated the call to propose a video stream, it can be useful
|
||||
* to prompt the user before answering. This can be achieved by calling linphone_core_defer_call_update() during
|
||||
* to prompt the user before answering. This can be achieved by calling linphone_core_defer_call_update() during
|
||||
* the call state notifiacation, to deactivate the automatic answer that would just confirm the audio but reject the video.
|
||||
* Then, when the user responds to dialog prompt, it becomes possible to call linphone_core_accept_call_update() to answer
|
||||
* the reINVITE, with eventually video enabled in the LinphoneCallParams argument.
|
||||
*
|
||||
*
|
||||
* @return 0 if successful, -1 if the linphone_core_defer_call_update() was done outside a #LinphoneCallUpdatedByRemote notification, which is illegal.
|
||||
**/
|
||||
int linphone_core_defer_call_update(LinphoneCore *lc, LinphoneCall *call){
|
||||
|
|
@ -3416,7 +3423,7 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call,
|
|||
sal_call_set_local_media_description(call->op,call->localdesc);
|
||||
sal_op_set_sent_custom_header(call->op,params->custom_headers);
|
||||
}
|
||||
|
||||
|
||||
/*give a chance a set card prefered sampling frequency*/
|
||||
if (call->localdesc->streams[0].max_rate>0) {
|
||||
ms_message ("configuring prefered card sampling rate to [%i]",call->localdesc->streams[0].max_rate);
|
||||
|
|
@ -3425,7 +3432,7 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call,
|
|||
if (lc->sound_conf.capt_sndcard)
|
||||
ms_snd_card_set_preferred_sample_rate(lc->sound_conf.capt_sndcard, call->localdesc->streams[0].max_rate);
|
||||
}
|
||||
|
||||
|
||||
if (!was_ringing && call->audiostream->ms.state==MSStreamInitialized){
|
||||
audio_stream_prepare_sound(call->audiostream,lc->sound_conf.play_sndcard,lc->sound_conf.capt_sndcard);
|
||||
}
|
||||
|
|
@ -3543,9 +3550,9 @@ int linphone_core_terminate_call(LinphoneCore *lc, LinphoneCall *the_call)
|
|||
|
||||
/**
|
||||
* Decline a pending incoming call, with a reason.
|
||||
*
|
||||
*
|
||||
* @ingroup call_control
|
||||
*
|
||||
*
|
||||
* @param lc the linphone core
|
||||
* @param call the LinphoneCall, must be in the IncomingReceived state.
|
||||
* @param reason the reason for rejecting the call: LinphoneReasonDeclined or LinphoneReasonBusy
|
||||
|
|
@ -3679,12 +3686,12 @@ int linphone_core_pause_all_calls(LinphoneCore *lc){
|
|||
|
||||
void linphone_core_preempt_sound_resources(LinphoneCore *lc){
|
||||
LinphoneCall *current_call;
|
||||
|
||||
|
||||
if (linphone_core_is_in_conference(lc)){
|
||||
linphone_core_leave_conference(lc);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
current_call=linphone_core_get_current_call(lc);
|
||||
if(current_call != NULL){
|
||||
ms_message("Pausing automatically the current call.");
|
||||
|
|
@ -3703,7 +3710,7 @@ void linphone_core_preempt_sound_resources(LinphoneCore *lc){
|
|||
int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *call){
|
||||
char temp[255]={0};
|
||||
const char *subject="Call resuming";
|
||||
|
||||
|
||||
if(call->state!=LinphoneCallPaused ){
|
||||
ms_warning("we cannot resume a call that has not been established and paused before");
|
||||
return -1;
|
||||
|
|
@ -3718,7 +3725,7 @@ int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *call){
|
|||
}
|
||||
|
||||
call->was_automatically_paused=FALSE;
|
||||
|
||||
|
||||
/* Stop playing music immediately. If remote side is a conference it
|
||||
prevents the participants to hear it while the 200OK comes back.*/
|
||||
if (call->audiostream) audio_stream_play(call->audiostream, NULL);
|
||||
|
|
@ -3754,7 +3761,7 @@ static int remote_address_compare(LinphoneCall *call, const LinphoneAddress *rad
|
|||
* @param lc
|
||||
* @param remote_address
|
||||
* @return the LinphoneCall of the call if found
|
||||
*
|
||||
*
|
||||
* @ingroup call_control
|
||||
*/
|
||||
LinphoneCall *linphone_core_get_call_by_remote_address(LinphoneCore *lc, const char *remote_address){
|
||||
|
|
@ -4357,7 +4364,7 @@ const char *linphone_core_get_root_ca(LinphoneCore *lc){
|
|||
|
||||
/**
|
||||
* Specify whether the tls server certificate must be verified when connecting to a SIP/TLS server.
|
||||
*
|
||||
*
|
||||
* @ingroup initializing
|
||||
**/
|
||||
void linphone_core_verify_server_certificates(LinphoneCore *lc, bool_t yesno){
|
||||
|
|
@ -4474,7 +4481,7 @@ void linphone_core_mute_mic(LinphoneCore *lc, bool_t val){
|
|||
if ( linphone_core_get_rtp_no_xmit_on_audio_mute(lc) ){
|
||||
audio_stream_mute_rtp(st,val);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4560,7 +4567,7 @@ void linphone_core_set_stun_server(LinphoneCore *lc, const char *server){
|
|||
if (server)
|
||||
lc->net_conf.stun_server=ms_strdup(server);
|
||||
else lc->net_conf.stun_server=NULL;
|
||||
|
||||
|
||||
/* each time the stun server is changed, we must clean the resolved cached addrinfo*/
|
||||
if (lc->net_conf.stun_addrinfo){
|
||||
freeaddrinfo(lc->net_conf.stun_addrinfo);
|
||||
|
|
@ -4570,7 +4577,7 @@ void linphone_core_set_stun_server(LinphoneCore *lc, const char *server){
|
|||
if (lc->net_conf.stun_server){
|
||||
linphone_core_resolve_stun_server(lc);
|
||||
}
|
||||
|
||||
|
||||
if (linphone_core_ready(lc))
|
||||
lp_config_set_string(lc->config,"net","stun_server",lc->net_conf.stun_server);
|
||||
}
|
||||
|
|
@ -4627,7 +4634,7 @@ const char *linphone_core_get_nat_address_resolved(LinphoneCore *lc)
|
|||
char ipstring [INET6_ADDRSTRLEN];
|
||||
|
||||
if (lc->net_conf.nat_address==NULL) return NULL;
|
||||
|
||||
|
||||
if (parse_hostname_to_addr (lc->net_conf.nat_address, &ss, &ss_len, 5060)<0) {
|
||||
return lc->net_conf.nat_address;
|
||||
}
|
||||
|
|
@ -4996,7 +5003,7 @@ int linphone_core_set_static_picture(LinphoneCore *lc, const char *path) {
|
|||
const char *linphone_core_get_static_picture(LinphoneCore *lc) {
|
||||
const char *path=NULL;
|
||||
#ifdef VIDEO_ENABLED
|
||||
path=ms_static_image_get_default_image();
|
||||
path=ms_static_image_get_default_image();
|
||||
#else
|
||||
ms_warning("Video support not compiled.");
|
||||
#endif
|
||||
|
|
@ -5071,7 +5078,7 @@ static void unset_video_window_id(LinphoneCore *lc, bool_t preview, unsigned lon
|
|||
LinphoneCall *call;
|
||||
MSList *elem;
|
||||
#endif
|
||||
|
||||
|
||||
if (id!=0 && id!=-1) {
|
||||
ms_error("Invalid use of unset_video_window_id()");
|
||||
return;
|
||||
|
|
@ -5235,7 +5242,7 @@ static MSVideoSizeDef supported_resolutions[]={
|
|||
#if !TARGET_OS_MAC || TARGET_OS_IPHONE /* OS_MAC is 1 for iPhone, but we need QVGA */
|
||||
{ { MS_VIDEO_SIZE_QVGA_W, MS_VIDEO_SIZE_QVGA_H } , "qvga" },
|
||||
#endif
|
||||
{ { MS_VIDEO_SIZE_QCIF_W, MS_VIDEO_SIZE_QCIF_H } , "qcif" },
|
||||
{ { MS_VIDEO_SIZE_QCIF_W, MS_VIDEO_SIZE_QCIF_H } , "qcif" },
|
||||
{ { 0,0 } , NULL }
|
||||
};
|
||||
|
||||
|
|
@ -5480,7 +5487,7 @@ void linphone_core_play_named_tone(LinphoneCore *lc, LinphoneToneID toneid){
|
|||
def.frequencies[0]=620;
|
||||
def.interval=250;
|
||||
def.repeat_count=3;
|
||||
|
||||
|
||||
break;
|
||||
default:
|
||||
ms_warning("Unhandled tone id.");
|
||||
|
|
@ -5546,7 +5553,7 @@ int linphone_core_get_mtu(const LinphoneCore *lc){
|
|||
* Sets the maximum transmission unit size in bytes.
|
||||
* This information is useful for sending RTP packets.
|
||||
* Default value is 1500.
|
||||
*
|
||||
*
|
||||
* @ingroup media_parameters
|
||||
**/
|
||||
void linphone_core_set_mtu(LinphoneCore *lc, int mtu){
|
||||
|
|
@ -5640,7 +5647,7 @@ void sip_config_uninit(LinphoneCore *lc)
|
|||
int i;
|
||||
sip_config_t *config=&lc->sip_conf;
|
||||
bool_t still_registered=TRUE;
|
||||
|
||||
|
||||
lp_config_set_int(lc->config,"sip","guess_hostname",config->guess_hostname);
|
||||
lp_config_set_string(lc->config,"sip","contact",config->contact);
|
||||
lp_config_set_int(lc->config,"sip","inc_timeout",config->inc_timeout);
|
||||
|
|
@ -5655,7 +5662,7 @@ void sip_config_uninit(LinphoneCore *lc)
|
|||
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)(elem->data);
|
||||
linphone_proxy_config_edit(cfg); /* to unregister */
|
||||
}
|
||||
|
||||
|
||||
ms_message("Unregistration started.");
|
||||
|
||||
for (i=0;i<20&&still_registered;i++){
|
||||
|
|
@ -5687,7 +5694,7 @@ void sip_config_uninit(LinphoneCore *lc)
|
|||
ms_message("Tunnel destroyed.");
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
sal_reset_transports(lc->sal);
|
||||
sal_unlisten_ports(lc->sal); /*to make sure no new messages are received*/
|
||||
if (lc->http_provider) {
|
||||
|
|
@ -5893,7 +5900,7 @@ static void linphone_core_uninit(LinphoneCore *lc)
|
|||
linphone_presence_model_unref(lc->presence_model);
|
||||
}
|
||||
linphone_core_free_payload_types(lc);
|
||||
|
||||
|
||||
linphone_core_message_storage_close(lc);
|
||||
ms_exit();
|
||||
linphone_core_set_state(lc,LinphoneGlobalOff,"Off");
|
||||
|
|
@ -5902,7 +5909,7 @@ static void linphone_core_uninit(LinphoneCore *lc)
|
|||
static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t curtime){
|
||||
// second get the list of available proxies
|
||||
const MSList *elem=linphone_core_get_proxy_config_list(lc);
|
||||
|
||||
|
||||
if (lc->network_reachable==isReachable) return; // no change, ignore.
|
||||
|
||||
ms_message("Network state is now [%s]",isReachable?"UP":"DOWN");
|
||||
|
|
@ -5919,7 +5926,7 @@ static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t cu
|
|||
}
|
||||
lc->netup_time=curtime;
|
||||
lc->network_reachable=isReachable;
|
||||
|
||||
|
||||
if (!lc->network_reachable){
|
||||
linphone_core_invalidate_friend_subscriptions(lc);
|
||||
sal_reset_transports(lc->sal);
|
||||
|
|
@ -6393,7 +6400,7 @@ int linphone_core_set_media_encryption(LinphoneCore *lc, LinphoneMediaEncryption
|
|||
|
||||
LinphoneMediaEncryption linphone_core_get_media_encryption(LinphoneCore *lc) {
|
||||
const char* menc = lp_config_get_string(lc->config, "sip", "media_encryption", NULL);
|
||||
|
||||
|
||||
if (menc == NULL)
|
||||
return LinphoneMediaEncryptionNone;
|
||||
else if (strcmp(menc, "srtp")==0)
|
||||
|
|
@ -6429,10 +6436,10 @@ const char* linphone_core_get_device_identifier(const LinphoneCore *lc) {
|
|||
|
||||
/**
|
||||
* Set the DSCP field for SIP signaling channel.
|
||||
*
|
||||
*
|
||||
* @ingroup network_parameters
|
||||
* * The DSCP defines the quality of service in IP packets.
|
||||
*
|
||||
*
|
||||
**/
|
||||
void linphone_core_set_sip_dscp(LinphoneCore *lc, int dscp){
|
||||
sal_set_dscp(lc->sal,dscp);
|
||||
|
|
@ -6444,10 +6451,10 @@ void linphone_core_set_sip_dscp(LinphoneCore *lc, int dscp){
|
|||
|
||||
/**
|
||||
* Get the DSCP field for SIP signaling channel.
|
||||
*
|
||||
*
|
||||
* @ingroup network_parameters
|
||||
* * The DSCP defines the quality of service in IP packets.
|
||||
*
|
||||
*
|
||||
**/
|
||||
int linphone_core_get_sip_dscp(const LinphoneCore *lc){
|
||||
return lp_config_get_int(lc->config,"sip","dscp",0x1a);
|
||||
|
|
@ -6458,7 +6465,7 @@ int linphone_core_get_sip_dscp(const LinphoneCore *lc){
|
|||
*
|
||||
* @ingroup network_parameters
|
||||
* The DSCP defines the quality of service in IP packets.
|
||||
*
|
||||
*
|
||||
**/
|
||||
void linphone_core_set_audio_dscp(LinphoneCore *lc, int dscp){
|
||||
if (linphone_core_ready(lc))
|
||||
|
|
@ -6470,7 +6477,7 @@ void linphone_core_set_audio_dscp(LinphoneCore *lc, int dscp){
|
|||
*
|
||||
* @ingroup network_parameters
|
||||
* The DSCP defines the quality of service in IP packets.
|
||||
*
|
||||
*
|
||||
**/
|
||||
int linphone_core_get_audio_dscp(const LinphoneCore *lc){
|
||||
return lp_config_get_int(lc->config,"rtp","audio_dscp",0x2e);
|
||||
|
|
@ -6481,12 +6488,12 @@ int linphone_core_get_audio_dscp(const LinphoneCore *lc){
|
|||
*
|
||||
* @ingroup network_parameters
|
||||
* The DSCP defines the quality of service in IP packets.
|
||||
*
|
||||
*
|
||||
**/
|
||||
void linphone_core_set_video_dscp(LinphoneCore *lc, int dscp){
|
||||
if (linphone_core_ready(lc))
|
||||
lp_config_set_int_hex(lc->config,"rtp","video_dscp",dscp);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -6494,7 +6501,7 @@ void linphone_core_set_video_dscp(LinphoneCore *lc, int dscp){
|
|||
*
|
||||
* @ingroup network_parameters
|
||||
* The DSCP defines the quality of service in IP packets.
|
||||
*
|
||||
*
|
||||
**/
|
||||
int linphone_core_get_video_dscp(const LinphoneCore *lc){
|
||||
return lp_config_get_int(lc->config,"rtp","video_dscp",0);
|
||||
|
|
|
|||
|
|
@ -812,6 +812,17 @@ LINPHONE_PUBLIC void linphone_proxy_config_enable_publish(LinphoneProxyConfig *o
|
|||
LINPHONE_PUBLIC void linphone_proxy_config_set_dial_escape_plus(LinphoneProxyConfig *cfg, bool_t val);
|
||||
LINPHONE_PUBLIC void linphone_proxy_config_set_dial_prefix(LinphoneProxyConfig *cfg, const char *prefix);
|
||||
|
||||
/**
|
||||
* Indicates either or not, quality statistics during call should be stored and sent to a collector at termination.
|
||||
* @param cfg #LinphoneProxyConfig object
|
||||
* @param val if true, quality statistics publish will be stored and sent to the collector
|
||||
*
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_proxy_config_enable_statistics(LinphoneProxyConfig *cfg, bool_t val);
|
||||
LINPHONE_PUBLIC bool_t linphone_proxy_config_send_statistics_enabled(LinphoneProxyConfig *cfg);
|
||||
LINPHONE_PUBLIC void linphone_proxy_config_set_statistics_collector(LinphoneProxyConfig *cfg, const char *collector);
|
||||
LINPHONE_PUBLIC const char *linphone_proxy_config_get_statistics_collector(const LinphoneProxyConfig *obj);
|
||||
|
||||
/**
|
||||
* Get the registration state of the given proxy config.
|
||||
* @param[in] obj #LinphoneProxyConfig object.
|
||||
|
|
|
|||
|
|
@ -170,7 +170,7 @@ static time_t parse_timestamp(const char *timestamp) {
|
|||
return seconds - timezone;
|
||||
}
|
||||
|
||||
static char * timestamp_to_string(time_t timestamp) {
|
||||
char * linphone_timestamp_to_rfc3339_string(time_t timestamp) {
|
||||
char timestamp_str[22];
|
||||
struct tm *ret;
|
||||
#ifndef WIN32
|
||||
|
|
@ -1467,7 +1467,7 @@ void linphone_subscription_new(LinphoneCore *lc, SalOp *op, const char *from){
|
|||
char *tmp;
|
||||
LinphoneAddress *uri;
|
||||
LinphoneProxyConfig *cfg;
|
||||
|
||||
|
||||
uri=linphone_address_new(from);
|
||||
linphone_address_clean(uri);
|
||||
tmp=linphone_address_as_string(uri);
|
||||
|
|
@ -1482,7 +1482,7 @@ void linphone_subscription_new(LinphoneCore *lc, SalOp *op, const char *from){
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* check if we answer to this subscription */
|
||||
if (linphone_find_friend_by_address(lc->friends,uri,&lf)!=NULL){
|
||||
lf->insub=op;
|
||||
|
|
@ -1604,7 +1604,7 @@ static void write_xml_presence_note_obj(LinphonePresenceNote *note, struct _pres
|
|||
|
||||
static int write_xml_presence_timestamp(xmlTextWriterPtr writer, time_t timestamp) {
|
||||
int err;
|
||||
char *timestamp_str = timestamp_to_string(timestamp);
|
||||
char *timestamp_str = linphone_timestamp_to_rfc3339_string(timestamp);
|
||||
err = xmlTextWriterWriteElement(writer, (const xmlChar *)"timestamp", (const xmlChar *)timestamp_str);
|
||||
if (timestamp_str) ms_free(timestamp_str);
|
||||
return err;
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ extern "C" {
|
|||
#include "linphonecore_utils.h"
|
||||
#include "sal/sal.h"
|
||||
#include "sipsetup.h"
|
||||
#include "quality_reporting.h"
|
||||
|
||||
#include <belle-sip/object.h>
|
||||
#include <belle-sip/dict.h>
|
||||
|
|
@ -115,6 +116,8 @@ struct _LinphoneCallLog{
|
|||
float quality;
|
||||
time_t start_date_time; /**Start date of the call in seconds as expressed in a time_t */
|
||||
char* call_id; /**unique id of a call*/
|
||||
|
||||
reporting_session_report_t * reports[2]; /**<Quality statistics of the call (rfc6035) */
|
||||
bool_t video_enabled;
|
||||
};
|
||||
|
||||
|
|
@ -191,6 +194,7 @@ struct _LinphoneCall
|
|||
StunCandidate ac,vc; /*audio video ip/port discovered by STUN*/
|
||||
struct _AudioStream *audiostream; /**/
|
||||
struct _VideoStream *videostream;
|
||||
|
||||
MSAudioEndpoint *endpoint; /*used for conferencing*/
|
||||
char *refer_to;
|
||||
LinphoneCallParams params;
|
||||
|
|
@ -399,6 +403,7 @@ struct _LinphoneProxyConfig
|
|||
char *reg_proxy;
|
||||
char *reg_identity;
|
||||
char *reg_route;
|
||||
char *reg_statistics_collector;
|
||||
char *realm;
|
||||
char *contact_params;
|
||||
char *contact_uri_params;
|
||||
|
|
@ -415,6 +420,7 @@ struct _LinphoneProxyConfig
|
|||
bool_t publish;
|
||||
bool_t dial_escape_plus;
|
||||
bool_t send_publish;
|
||||
bool_t send_statistics;
|
||||
bool_t pad[3];
|
||||
void* user_data;
|
||||
time_t deletion_date;
|
||||
|
|
@ -669,7 +675,7 @@ struct _LinphoneCore
|
|||
bool_t use_preview_window;
|
||||
|
||||
time_t network_last_check;
|
||||
|
||||
|
||||
bool_t network_last_status;
|
||||
bool_t ringstream_autorelease;
|
||||
bool_t pad[2];
|
||||
|
|
@ -804,6 +810,7 @@ void linphone_configure_op(LinphoneCore *lc, SalOp *op, const LinphoneAddress *d
|
|||
void linphone_call_create_op(LinphoneCall *call);
|
||||
int linphone_call_prepare_ice(LinphoneCall *call, bool_t incoming_offer);
|
||||
void linphone_core_notify_info_message(LinphoneCore* lc,SalOp *op, const SalBody *body);
|
||||
void linphone_content_uninit(LinphoneContent * obj);
|
||||
LinphoneContent *linphone_content_copy_from_sal_body(LinphoneContent *obj, const SalBody *ref);
|
||||
SalBody *sal_body_from_content(SalBody *body, const LinphoneContent *lc);
|
||||
SalReason linphone_reason_to_sal(LinphoneReason reason);
|
||||
|
|
@ -852,11 +859,18 @@ char * linphone_get_xml_text_content(xmlparsing_context_t *xml_ctx, const char *
|
|||
void linphone_free_xml_text_content(const char *text);
|
||||
xmlXPathObjectPtr linphone_get_xml_xpath_object_for_node_list(xmlparsing_context_t *xml_ctx, const char *xpath_expression);
|
||||
|
||||
/*****************************************************************************
|
||||
* OTHER UTILITY FUNCTIONS *
|
||||
****************************************************************************/
|
||||
char * linphone_timestamp_to_rfc3339_string(time_t timestamp);
|
||||
|
||||
|
||||
static inline const LinphoneErrorInfo *linphone_error_info_from_sal_op(const SalOp *op){
|
||||
if (op==NULL) return (LinphoneErrorInfo*)sal_error_info_none();
|
||||
return (const LinphoneErrorInfo*)sal_op_get_error_info(op);
|
||||
}
|
||||
|
||||
|
||||
/** Belle Sip-based objects need unique ids
|
||||
*/
|
||||
|
||||
|
|
|
|||
105
coreapi/proxy.c
105
coreapi/proxy.c
|
|
@ -17,7 +17,7 @@ Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org)
|
|||
* 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"
|
||||
|
|
@ -31,7 +31,7 @@ void linphone_proxy_config_write_all_to_config_file(LinphoneCore *lc){
|
|||
MSList *elem;
|
||||
int i;
|
||||
if (!linphone_core_ready(lc)) return;
|
||||
|
||||
|
||||
for(elem=lc->sip_conf.proxies,i=0;elem!=NULL;elem=ms_list_next(elem),i++){
|
||||
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data;
|
||||
linphone_proxy_config_write_to_config_file(lc->config,cfg,i);
|
||||
|
|
@ -46,9 +46,10 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *ob
|
|||
const char *identity = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_identity", NULL) : NULL;
|
||||
const char *proxy = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_proxy", NULL) : NULL;
|
||||
const char *route = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_route", NULL) : NULL;
|
||||
const char *statistics_collector = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_statistics_collector", NULL) : NULL;
|
||||
const char *contact_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_parameters", NULL) : NULL;
|
||||
const char *contact_uri_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_uri_parameters", NULL) : NULL;
|
||||
|
||||
|
||||
memset(obj, 0, sizeof(LinphoneProxyConfig));
|
||||
obj->magic = linphone_proxy_config_magic;
|
||||
obj->expires = lc ? lp_config_get_default_int(lc->config, "proxy", "reg_expires", 3600) : 3600;
|
||||
|
|
@ -59,6 +60,8 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *ob
|
|||
obj->reg_identity = identity ? ms_strdup(identity) : NULL;
|
||||
obj->reg_proxy = proxy ? ms_strdup(proxy) : NULL;
|
||||
obj->reg_route = route ? ms_strdup(route) : NULL;
|
||||
obj->reg_statistics_collector = statistics_collector ? ms_strdup(statistics_collector) : NULL;
|
||||
obj->send_statistics = lc ? lp_config_get_default_int(lc->config, "proxy", "send_statistics", 0) : 0;
|
||||
obj->contact_params = contact_params ? ms_strdup(contact_params) : NULL;
|
||||
obj->contact_uri_params = contact_uri_params ? ms_strdup(contact_uri_params) : NULL;
|
||||
}
|
||||
|
|
@ -85,7 +88,7 @@ LinphoneProxyConfig * linphone_core_create_proxy_config(LinphoneCore *lc) {
|
|||
|
||||
/**
|
||||
* Destroys a proxy config.
|
||||
*
|
||||
*
|
||||
* @note: LinphoneProxyConfig that have been removed from LinphoneCore with
|
||||
* linphone_core_remove_proxy_config() must not be freed.
|
||||
**/
|
||||
|
|
@ -93,6 +96,7 @@ void linphone_proxy_config_destroy(LinphoneProxyConfig *obj){
|
|||
if (obj->reg_proxy!=NULL) ms_free(obj->reg_proxy);
|
||||
if (obj->reg_identity!=NULL) ms_free(obj->reg_identity);
|
||||
if (obj->reg_route!=NULL) ms_free(obj->reg_route);
|
||||
if (obj->reg_statistics_collector!=NULL) ms_free(obj->reg_statistics_collector);
|
||||
if (obj->ssctx!=NULL) sip_setup_context_free(obj->ssctx);
|
||||
if (obj->realm!=NULL) ms_free(obj->realm);
|
||||
if (obj->type!=NULL) ms_free(obj->type);
|
||||
|
|
@ -123,10 +127,10 @@ bool_t linphone_proxy_config_is_registered(const LinphoneProxyConfig *obj){
|
|||
int linphone_proxy_config_set_server_addr(LinphoneProxyConfig *obj, const char *server_addr){
|
||||
LinphoneAddress *addr=NULL;
|
||||
char *modified=NULL;
|
||||
|
||||
|
||||
if (obj->reg_proxy!=NULL) ms_free(obj->reg_proxy);
|
||||
obj->reg_proxy=NULL;
|
||||
|
||||
|
||||
if (server_addr!=NULL && strlen(server_addr)>0){
|
||||
if (strstr(server_addr,"sip:")==NULL && strstr(server_addr,"sips:")==NULL){
|
||||
modified=ms_strdup_printf("sip:%s",server_addr);
|
||||
|
|
@ -149,7 +153,7 @@ int linphone_proxy_config_set_server_addr(LinphoneProxyConfig *obj, const char *
|
|||
/**
|
||||
* Sets the user identity as a SIP address.
|
||||
*
|
||||
* This identity is normally formed with display name, username and domain, such
|
||||
* This identity is normally formed with display name, username and domain, such
|
||||
* as:
|
||||
* Alice <sip:alice@example.net>
|
||||
* The REGISTER messages will have from and to set to this identity.
|
||||
|
|
@ -297,14 +301,14 @@ LinphoneAddress *guess_contact_for_register(LinphoneProxyConfig *obj){
|
|||
LinphoneAddress *ret=NULL;
|
||||
LinphoneAddress *proxy=linphone_address_new(obj->reg_proxy);
|
||||
const char *host;
|
||||
|
||||
|
||||
if (proxy==NULL) return NULL;
|
||||
host=linphone_address_get_domain(proxy);
|
||||
if (host!=NULL){
|
||||
int localport = -1;
|
||||
const char *localip = NULL;
|
||||
LinphoneAddress *contact=linphone_address_new(obj->reg_identity);
|
||||
|
||||
|
||||
linphone_address_clean(contact);
|
||||
|
||||
if (obj->contact_params) {
|
||||
|
|
@ -374,7 +378,7 @@ void linphone_proxy_config_refresh_register(LinphoneProxyConfig *obj){
|
|||
|
||||
|
||||
/**
|
||||
* Sets a dialing prefix to be automatically prepended when inviting a number with
|
||||
* Sets a dialing prefix to be automatically prepended when inviting a number with
|
||||
* linphone_core_invite();
|
||||
* This dialing prefix shall usually be the country code of the country where the user is living.
|
||||
*
|
||||
|
|
@ -390,7 +394,7 @@ void linphone_proxy_config_set_dial_prefix(LinphoneProxyConfig *cfg, const char
|
|||
/**
|
||||
* Returns dialing prefix.
|
||||
*
|
||||
*
|
||||
*
|
||||
**/
|
||||
const char *linphone_proxy_config_get_dial_prefix(const LinphoneProxyConfig *cfg){
|
||||
return cfg->dial_prefix;
|
||||
|
|
@ -413,6 +417,37 @@ void linphone_proxy_config_set_dial_escape_plus(LinphoneProxyConfig *cfg, bool_t
|
|||
bool_t linphone_proxy_config_get_dial_escape_plus(const LinphoneProxyConfig *cfg){
|
||||
return cfg->dial_escape_plus;
|
||||
}
|
||||
|
||||
void linphone_proxy_config_enable_statistics(LinphoneProxyConfig *cfg, bool_t val){
|
||||
cfg->send_statistics = val;
|
||||
}
|
||||
|
||||
bool_t linphone_proxy_config_send_statistics_enabled(LinphoneProxyConfig *cfg){
|
||||
// ensure that collector address is set too!
|
||||
return cfg->send_statistics && cfg->reg_statistics_collector != NULL;
|
||||
}
|
||||
|
||||
void linphone_proxy_config_set_statistics_collector(LinphoneProxyConfig *cfg, const char *collector){
|
||||
if (collector!=NULL && strlen(collector)>0){
|
||||
LinphoneAddress *addr=linphone_address_new(collector);
|
||||
if (!addr || linphone_address_get_username(addr)==NULL){
|
||||
ms_warning("Invalid sip collector identity: %s",collector);
|
||||
if (addr)
|
||||
linphone_address_destroy(addr);
|
||||
} else {
|
||||
if (cfg->reg_statistics_collector != NULL)
|
||||
ms_free(cfg->reg_statistics_collector);
|
||||
cfg->reg_statistics_collector = ms_strdup(collector);
|
||||
linphone_address_destroy(addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const char *linphone_proxy_config_get_statistics_collector(const LinphoneProxyConfig *cfg){
|
||||
return cfg->reg_statistics_collector;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* http://en.wikipedia.org/wiki/Telephone_numbering_plan
|
||||
* http://en.wikipedia.org/wiki/Telephone_numbers_in_Europe
|
||||
|
|
@ -423,7 +458,7 @@ typedef struct dial_plan{
|
|||
char ccc[8]; /*country calling code*/
|
||||
int nnl; /*maximum national number length*/
|
||||
const char * icp; /*international call prefix, ex: 00 in europe*/
|
||||
|
||||
|
||||
}dial_plan_t;
|
||||
|
||||
/* TODO: fill with information for all countries over the world*/
|
||||
|
|
@ -708,7 +743,7 @@ static void lookup_dial_plan(const char *ccc, dial_plan_t *plan){
|
|||
static bool_t is_a_phone_number(const char *username){
|
||||
const char *p;
|
||||
for(p=username;*p!='\0';++p){
|
||||
if (isdigit(*p) ||
|
||||
if (isdigit(*p) ||
|
||||
*p==' ' ||
|
||||
*p=='.' ||
|
||||
*p=='-' ||
|
||||
|
|
@ -736,12 +771,12 @@ static char *flatten_number(const char *number){
|
|||
|
||||
static void replace_plus(const char *src, char *dest, size_t destlen, const char *icp){
|
||||
int i=0;
|
||||
|
||||
|
||||
if (icp && src[0]=='+' && (destlen>(i=strlen(icp))) ){
|
||||
src++;
|
||||
strcpy(dest,icp);
|
||||
}
|
||||
|
||||
|
||||
for(;(i<destlen-1) && *src!='\0';++i){
|
||||
dest[i]=*src;
|
||||
src++;
|
||||
|
|
@ -756,7 +791,7 @@ int linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const cha
|
|||
char *flatten;
|
||||
flatten=flatten_number(username);
|
||||
ms_message("Flattened number is '%s'",flatten);
|
||||
|
||||
|
||||
if (proxy->dial_prefix==NULL || proxy->dial_prefix[0]=='\0'){
|
||||
/*no prefix configured, nothing else to do*/
|
||||
strncpy(result,flatten,result_len);
|
||||
|
|
@ -824,7 +859,7 @@ void linphone_proxy_config_set_realm(LinphoneProxyConfig *cfg, const char *realm
|
|||
|
||||
int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy, LinphonePresenceModel *presence){
|
||||
int err=0;
|
||||
|
||||
|
||||
if (proxy->state==LinphoneRegistrationOk || proxy->state==LinphoneRegistrationCleared){
|
||||
if (proxy->publish_op==NULL){
|
||||
proxy->publish_op=sal_op_new(proxy->lc->sal);
|
||||
|
|
@ -1015,7 +1050,7 @@ void linphone_core_set_default_proxy(LinphoneCore *lc, LinphoneProxyConfig *conf
|
|||
lc->default_proxy=config;
|
||||
if (linphone_core_ready(lc))
|
||||
lp_config_set_int(lc->config,"sip","default_proxy",linphone_core_get_default_proxy(lc,NULL));
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_core_set_default_proxy_index(LinphoneCore *lc, int index){
|
||||
if (index<0) linphone_core_set_default_proxy(lc,NULL);
|
||||
|
|
@ -1059,6 +1094,9 @@ void linphone_proxy_config_write_to_config_file(LpConfig *config, LinphoneProxyC
|
|||
if (obj->reg_route!=NULL){
|
||||
lp_config_set_string(config,key,"reg_route",obj->reg_route);
|
||||
}
|
||||
if (obj->reg_statistics_collector!=NULL){
|
||||
lp_config_set_string(config,key,"reg_statistics_collector",obj->reg_statistics_collector);
|
||||
}
|
||||
if (obj->reg_identity!=NULL){
|
||||
lp_config_set_string(config,key,"reg_identity",obj->reg_identity);
|
||||
}
|
||||
|
|
@ -1072,6 +1110,7 @@ void linphone_proxy_config_write_to_config_file(LpConfig *config, LinphoneProxyC
|
|||
lp_config_set_int(config,key,"reg_sendregister",obj->reg_sendregister);
|
||||
lp_config_set_int(config,key,"publish",obj->publish);
|
||||
lp_config_set_int(config,key,"dial_escape_plus",obj->dial_escape_plus);
|
||||
lp_config_set_int(config,key,"send_statistics",obj->send_statistics);
|
||||
lp_config_set_string(config,key,"dial_prefix",obj->dial_prefix);
|
||||
lp_config_set_int(config,key,"privacy",obj->privacy);
|
||||
}
|
||||
|
|
@ -1085,7 +1124,7 @@ LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LpConfig *config
|
|||
const char *proxy;
|
||||
LinphoneProxyConfig *cfg;
|
||||
char key[50];
|
||||
|
||||
|
||||
sprintf(key,"proxy_%i",index);
|
||||
|
||||
if (!lp_config_has_section(config,key)){
|
||||
|
|
@ -1094,29 +1133,33 @@ LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LpConfig *config
|
|||
|
||||
cfg=linphone_proxy_config_new();
|
||||
|
||||
identity=lp_config_get_string(config,key,"reg_identity",NULL);
|
||||
identity=lp_config_get_string(config,key,"reg_identity",NULL);
|
||||
proxy=lp_config_get_string(config,key,"reg_proxy",NULL);
|
||||
|
||||
|
||||
linphone_proxy_config_set_identity(cfg,identity);
|
||||
linphone_proxy_config_set_server_addr(cfg,proxy);
|
||||
|
||||
|
||||
tmp=lp_config_get_string(config,key,"reg_route",NULL);
|
||||
if (tmp!=NULL) linphone_proxy_config_set_route(cfg,tmp);
|
||||
|
||||
tmp=lp_config_get_string(config,key,"reg_statistics_collector",NULL);
|
||||
if (tmp!=NULL) linphone_proxy_config_set_statistics_collector(cfg,tmp);
|
||||
linphone_proxy_config_enable_statistics(cfg,lp_config_get_int(config,key,"send_statistics",0));
|
||||
|
||||
linphone_proxy_config_set_contact_parameters(cfg,lp_config_get_string(config,key,"contact_parameters",NULL));
|
||||
|
||||
|
||||
linphone_proxy_config_set_contact_uri_parameters(cfg,lp_config_get_string(config,key,"contact_uri_parameters",NULL));
|
||||
|
||||
|
||||
linphone_proxy_config_expires(cfg,lp_config_get_int(config,key,"reg_expires",lp_config_get_default_int(config,"proxy","reg_expires",600)));
|
||||
linphone_proxy_config_enableregister(cfg,lp_config_get_int(config,key,"reg_sendregister",0));
|
||||
|
||||
|
||||
linphone_proxy_config_enable_publish(cfg,lp_config_get_int(config,key,"publish",0));
|
||||
|
||||
linphone_proxy_config_set_dial_escape_plus(cfg,lp_config_get_int(config,key,"dial_escape_plus",lp_config_get_default_int(config,"proxy","dial_escape_plus",0)));
|
||||
linphone_proxy_config_set_dial_prefix(cfg,lp_config_get_string(config,key,"dial_prefix",lp_config_get_default_string(config,"proxy","dial_prefix",NULL)));
|
||||
|
||||
|
||||
tmp=lp_config_get_string(config,key,"type",NULL);
|
||||
if (tmp!=NULL && strlen(tmp)>0)
|
||||
if (tmp!=NULL && strlen(tmp)>0)
|
||||
linphone_proxy_config_set_sip_setup(cfg,tmp);
|
||||
|
||||
linphone_proxy_config_set_privacy(cfg,lp_config_get_int(config,key,"privacy",lp_config_get_default_int(config,"proxy","privacy",LinphonePrivacyDefault)));
|
||||
|
|
@ -1155,7 +1198,7 @@ static void linphone_proxy_config_activate_sip_setup(LinphoneProxyConfig *cfg){
|
|||
ms_error("Could not retrieve proxy uri !");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
SipSetup *linphone_proxy_config_get_sip_setup(LinphoneProxyConfig *cfg){
|
||||
|
|
@ -1170,7 +1213,7 @@ static bool_t can_register(LinphoneProxyConfig *cfg){
|
|||
LinphoneCore *lc=cfg->lc;
|
||||
#ifdef BUILD_UPNP
|
||||
if (linphone_core_get_firewall_policy(lc)==LinphonePolicyUseUpnp){
|
||||
if(lc->sip_conf.register_only_when_upnp_is_ok &&
|
||||
if(lc->sip_conf.register_only_when_upnp_is_ok &&
|
||||
(lc->upnp == NULL || !linphone_upnp_context_is_ready_for_register(lc->upnp))) {
|
||||
return FALSE;
|
||||
}
|
||||
|
|
@ -1326,7 +1369,7 @@ void * linphone_proxy_config_get_user_data(LinphoneProxyConfig *cr) {
|
|||
void linphone_proxy_config_set_state(LinphoneProxyConfig *cfg, LinphoneRegistrationState state, const char *message){
|
||||
LinphoneCore *lc=cfg->lc;
|
||||
bool_t update_friends=FALSE;
|
||||
|
||||
|
||||
if (cfg->state!=state || state==LinphoneRegistrationOk) { /*allow multiple notification of LinphoneRegistrationOk for refreshing*/
|
||||
ms_message("Proxy config [%p] for identity [%s] moving from state [%s] to [%s]" , cfg,
|
||||
linphone_proxy_config_get_identity(cfg),
|
||||
|
|
@ -1337,7 +1380,7 @@ void linphone_proxy_config_set_state(LinphoneProxyConfig *cfg, LinphoneRegistrat
|
|||
|| (state!=LinphoneRegistrationOk && cfg->state==LinphoneRegistrationOk);
|
||||
}
|
||||
cfg->state=state;
|
||||
|
||||
|
||||
if (update_friends){
|
||||
linphone_core_update_friends_subscriptions(lc,cfg,TRUE);
|
||||
}
|
||||
|
|
|
|||
524
coreapi/quality_reporting.c
Normal file
524
coreapi/quality_reporting.c
Normal file
|
|
@ -0,0 +1,524 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2014 - Belledonne Communications, Grenoble, France
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "../config.h"
|
||||
#endif
|
||||
|
||||
#include "linphonecore.h"
|
||||
#include "private.h"
|
||||
#include "sal/sal.h"
|
||||
#include "ortp/rtpsession.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
/***************************************************************************
|
||||
* TODO / REMINDER LIST
|
||||
****************************************************************************/
|
||||
// to discuss
|
||||
// For codecs that are able to change sample rates, the lowest and highest sample rates MUST be reported (e.g., 8000;16000).
|
||||
// moslq == moscq
|
||||
// video: what happens if doing stop/resume?
|
||||
// one time value: average? worst value?
|
||||
// rlq value: need algo to compute it
|
||||
/***************************************************************************
|
||||
* END OF TODO / REMINDER LIST
|
||||
****************************************************************************/
|
||||
|
||||
#define STR_REASSIGN(dest, src) {\
|
||||
if (dest != NULL) \
|
||||
ms_free(dest); \
|
||||
dest = src; \
|
||||
}
|
||||
|
||||
// since printf family functions are LOCALE dependent, float separator may differ
|
||||
// depending on the user's locale (LC_NUMERIC env var).
|
||||
static char * float_to_one_decimal_string(float f) {
|
||||
float rounded_f = floorf(f * 10 + .5f) / 10;
|
||||
|
||||
int floor_part = (int) rounded_f;
|
||||
int one_decimal_part = floorf (10 * (rounded_f - floor_part) + .5f);
|
||||
|
||||
return ms_strdup_printf(_("%d.%d"), floor_part, one_decimal_part);
|
||||
}
|
||||
|
||||
static void append_to_buffer_valist(char **buff, size_t *buff_size, size_t *offset, const char *fmt, va_list args) {
|
||||
belle_sip_error_code ret;
|
||||
size_t prevoffset = *offset;
|
||||
|
||||
#ifndef WIN32
|
||||
va_list cap;/*copy of our argument list: a va_list cannot be re-used (SIGSEGV on linux 64 bits)*/
|
||||
va_copy(cap,args);
|
||||
ret = belle_sip_snprintf_valist(*buff, *buff_size, offset, fmt, cap);
|
||||
va_end(cap);
|
||||
#else
|
||||
ret = belle_sip_snprintf_valist(*buff, *buff_size, offset, fmt, args);
|
||||
#endif
|
||||
|
||||
// if we are out of memory, we add some size to buffer
|
||||
if (ret == BELLE_SIP_BUFFER_OVERFLOW) {
|
||||
ms_warning("Buffer was too small to contain the whole report - doubling its size from %lu to %lu", *buff_size, 2 * *buff_size);
|
||||
*buff_size += 2048;
|
||||
*buff = (char *) ms_realloc(*buff, *buff_size);
|
||||
|
||||
*offset = prevoffset;
|
||||
// recall myself since we did not write all things into the buffer but
|
||||
// only a part of it
|
||||
append_to_buffer_valist(buff, buff_size, offset, fmt, args);
|
||||
}
|
||||
}
|
||||
|
||||
static void append_to_buffer(char **buff, size_t *buff_size, size_t *offset, const char *fmt, ...) {
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
append_to_buffer_valist(buff, buff_size, offset, fmt, args);
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
|
||||
#define APPEND_IF_NOT_NULL_STR(buffer, size, offset, fmt, arg) if (arg != NULL) append_to_buffer(buffer, size, offset, fmt, arg)
|
||||
#define APPEND_IF_NUM_IN_RANGE(buffer, size, offset, fmt, arg, inf, sup) if (inf <= arg && arg <= sup) append_to_buffer(buffer, size, offset, fmt, arg)
|
||||
#define APPEND_IF(buffer, size, offset, fmt, arg, cond) if (cond) append_to_buffer(buffer, size, offset, fmt, arg)
|
||||
#define IF_NUM_IN_RANGE(num, inf, sup, statement) if (inf <= num && num <= sup) statement
|
||||
|
||||
static bool_t are_metrics_filled(const reporting_content_metrics_t rm) {
|
||||
IF_NUM_IN_RANGE(rm.packet_loss.network_packet_loss_rate, 0, 255, return TRUE);
|
||||
IF_NUM_IN_RANGE(rm.packet_loss.jitter_buffer_discard_rate, 0, 255, return TRUE);
|
||||
IF_NUM_IN_RANGE(rm.quality_estimates.moslq, 1, 5, return TRUE);
|
||||
IF_NUM_IN_RANGE(rm.quality_estimates.moscq, 1, 5, return TRUE);
|
||||
|
||||
// since these are same values than local ones, do not check them
|
||||
// if (rm.session_description.payload_type != -1) return TRUE;
|
||||
// if (rm.session_description.payload_desc != NULL) return TRUE;
|
||||
// if (rm.session_description.sample_rate != -1) return TRUE;
|
||||
if (rm.session_description.frame_duration != -1) return TRUE;
|
||||
// if (rm.session_description.fmtp != NULL) return TRUE;
|
||||
if (rm.session_description.packet_loss_concealment != -1) return TRUE;
|
||||
|
||||
IF_NUM_IN_RANGE(rm.jitter_buffer.adaptive, 0, 3, return TRUE);
|
||||
IF_NUM_IN_RANGE(rm.jitter_buffer.nominal, 0, 65535, return TRUE);
|
||||
IF_NUM_IN_RANGE(rm.jitter_buffer.max, 0, 65535, return TRUE);
|
||||
IF_NUM_IN_RANGE(rm.jitter_buffer.abs_max, 0, 65535, return TRUE);
|
||||
|
||||
IF_NUM_IN_RANGE(rm.delay.round_trip_delay, 0, 65535, return TRUE);
|
||||
IF_NUM_IN_RANGE(rm.delay.end_system_delay, 0, 65535, return TRUE);
|
||||
IF_NUM_IN_RANGE(rm.delay.symm_one_way_delay, 0, 65535, return TRUE);
|
||||
IF_NUM_IN_RANGE(rm.delay.interarrival_jitter, 0, 65535, return TRUE);
|
||||
IF_NUM_IN_RANGE(rm.delay.mean_abs_jitter, 0, 65535, return TRUE);
|
||||
|
||||
if (rm.signal.level != 127) return TRUE;
|
||||
if (rm.signal.noise_level != 127) return TRUE;
|
||||
|
||||
IF_NUM_IN_RANGE(rm.quality_estimates.rlq, 1, 120, return TRUE);
|
||||
IF_NUM_IN_RANGE(rm.quality_estimates.rcq, 1, 120, return TRUE);
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void append_metrics_to_buffer(char ** buffer, size_t * size, size_t * offset, const reporting_content_metrics_t rm) {
|
||||
char * timestamps_start_str = NULL;
|
||||
char * timestamps_stop_str = NULL;
|
||||
char * network_packet_loss_rate_str = NULL;
|
||||
char * jitter_buffer_discard_rate_str = NULL;
|
||||
// char * gap_loss_density_str = NULL;
|
||||
char * moslq_str = NULL;
|
||||
char * moscq_str = NULL;
|
||||
|
||||
if (rm.timestamps.start > 0)
|
||||
timestamps_start_str = linphone_timestamp_to_rfc3339_string(rm.timestamps.start);
|
||||
if (rm.timestamps.stop > 0)
|
||||
timestamps_stop_str = linphone_timestamp_to_rfc3339_string(rm.timestamps.stop);
|
||||
|
||||
IF_NUM_IN_RANGE(rm.packet_loss.network_packet_loss_rate, 0, 255, network_packet_loss_rate_str = float_to_one_decimal_string(rm.packet_loss.network_packet_loss_rate / 256));
|
||||
IF_NUM_IN_RANGE(rm.packet_loss.jitter_buffer_discard_rate, 0, 255, jitter_buffer_discard_rate_str = float_to_one_decimal_string(rm.packet_loss.jitter_buffer_discard_rate / 256));
|
||||
// IF_NUM_IN_RANGE(rm.burst_gap_loss.gap_loss_density, 0, 10, gap_loss_density_str = float_to_one_decimal_string(rm.burst_gap_loss.gap_loss_density));
|
||||
IF_NUM_IN_RANGE(rm.quality_estimates.moslq, 1, 5, moslq_str = float_to_one_decimal_string(rm.quality_estimates.moslq));
|
||||
IF_NUM_IN_RANGE(rm.quality_estimates.moscq, 1, 5, moscq_str = float_to_one_decimal_string(rm.quality_estimates.moscq));
|
||||
|
||||
append_to_buffer(buffer, size, offset, "Timestamps:");
|
||||
APPEND_IF_NOT_NULL_STR(buffer, size, offset, " START=%s", timestamps_start_str);
|
||||
APPEND_IF_NOT_NULL_STR(buffer, size, offset, " STOP=%s", timestamps_stop_str);
|
||||
|
||||
append_to_buffer(buffer, size, offset, "\r\nSessionDesc:");
|
||||
APPEND_IF(buffer, size, offset, " PT=%d", rm.session_description.payload_type, rm.session_description.payload_type != -1);
|
||||
APPEND_IF_NOT_NULL_STR(buffer, size, offset, " PD=%s", rm.session_description.payload_desc);
|
||||
APPEND_IF(buffer, size, offset, " SR=%d", rm.session_description.sample_rate, rm.session_description.sample_rate != -1);
|
||||
APPEND_IF(buffer, size, offset, " FD=%d", rm.session_description.frame_duration, rm.session_description.frame_duration != -1);
|
||||
// append_to_buffer(buffer, size, offset, " FO=%d", rm.session_description.frame_ocets);
|
||||
// append_to_buffer(buffer, size, offset, " FPP=%d", rm.session_description.frames_per_sec);
|
||||
// append_to_buffer(buffer, size, offset, " PPS=%d", rm.session_description.packets_per_sec);
|
||||
APPEND_IF_NOT_NULL_STR(buffer, size, offset, " FMTP=\"%s\"", rm.session_description.fmtp);
|
||||
APPEND_IF(buffer, size, offset, " PLC=%d", rm.session_description.packet_loss_concealment, rm.session_description.packet_loss_concealment != -1);
|
||||
// APPEND_IF_NOT_NULL_STR(buffer, size, offset, " SSUP=%s", rm.session_description.silence_suppression_state);
|
||||
|
||||
append_to_buffer(buffer, size, offset, "\r\nJitterBuffer:");
|
||||
APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " JBA=%d", rm.jitter_buffer.adaptive, 0, 3);
|
||||
// APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " JBR=%d", rm.jitter_buffer.rate, 0, 15);
|
||||
APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " JBN=%d", rm.jitter_buffer.nominal, 0, 65535);
|
||||
APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " JBM=%d", rm.jitter_buffer.max, 0, 65535);
|
||||
APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " JBX=%d", rm.jitter_buffer.abs_max, 0, 65535);
|
||||
|
||||
append_to_buffer(buffer, size, offset, "\r\nPacketLoss:");
|
||||
APPEND_IF_NOT_NULL_STR(buffer, size, offset, " NLR=%s", network_packet_loss_rate_str);
|
||||
APPEND_IF_NOT_NULL_STR(buffer, size, offset, " JDR=%s", jitter_buffer_discard_rate_str);
|
||||
|
||||
// append_to_buffer(buffer, size, offset, "\r\nBurstGapLoss:");
|
||||
// append_to_buffer(buffer, size, offset, " BLD=%d", rm.burst_gap_loss.burst_loss_density);
|
||||
// append_to_buffer(buffer, size, offset, " BD=%d", rm.burst_gap_loss.burst_duration);
|
||||
// APPEND_IF_NOT_NULL_STR(buffer, size, offset, " GLD=%s", gap_loss_density_str);
|
||||
// append_to_buffer(buffer, size, offset, " GD=%d", rm.burst_gap_loss.gap_duration);
|
||||
// append_to_buffer(buffer, size, offset, " GMIN=%d", rm.burst_gap_loss.min_gap_threshold);
|
||||
|
||||
append_to_buffer(buffer, size, offset, "\r\nDelay:");
|
||||
APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " RTD=%d", rm.delay.round_trip_delay, 0, 65535);
|
||||
APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " ESD=%d", rm.delay.end_system_delay, 0, 65535);
|
||||
// APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " OWD=%d", rm.delay.one_way_delay, 0, 65535);
|
||||
APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " SOWD=%d", rm.delay.symm_one_way_delay, 0, 65535);
|
||||
APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " IAJ=%d", rm.delay.interarrival_jitter, 0, 65535);
|
||||
APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " MAJ=%d", rm.delay.mean_abs_jitter, 0, 65535);
|
||||
|
||||
append_to_buffer(buffer, size, offset, "\r\nSignal:");
|
||||
APPEND_IF(buffer, size, offset, " SL=%d", rm.signal.level, rm.signal.level != 127);
|
||||
APPEND_IF(buffer, size, offset, " NL=%d", rm.signal.noise_level, rm.signal.noise_level != 127);
|
||||
// append_to_buffer(buffer, size, offset, " RERL=%d", rm.signal.residual_echo_return_loss);
|
||||
|
||||
append_to_buffer(buffer, size, offset, "\r\nQualityEst:");
|
||||
APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " RLQ=%d", rm.quality_estimates.rlq, 1, 120);
|
||||
// APPEND_IF_NOT_NULL_STR(buffer, size, offset, " RLQEstAlg=%s", rm.quality_estimates.rlqestalg);
|
||||
APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " RCQ=%d", rm.quality_estimates.rcq, 1, 120);
|
||||
// APPEND_IF_NOT_NULL_STR(buffer, size, offset, " RCQEstAlgo=%s", rm.quality_estimates.rcqestalg);
|
||||
// append_to_buffer(buffer, size, offset, " EXTRI=%d", rm.quality_estimates.extri);
|
||||
// APPEND_IF_NOT_NULL_STR(buffer, size, offset, " ExtRIEstAlg=%s", rm.quality_estimates.extriestalg);
|
||||
// append_to_buffer(buffer, size, offset, " EXTRO=%d", rm.quality_estimates.extro);
|
||||
// APPEND_IF_NOT_NULL_STR(buffer, size, offset, " ExtROEstAlg=%s", rm.quality_estimates.extroutestalg);
|
||||
APPEND_IF_NOT_NULL_STR(buffer, size, offset, " MOSLQ=%s", moslq_str);
|
||||
// APPEND_IF_NOT_NULL_STR(buffer, size, offset, " MOSLQEstAlgo=%s", rm.quality_estimates.moslqestalg);
|
||||
APPEND_IF_NOT_NULL_STR(buffer, size, offset, " MOSCQ=%s", moscq_str);
|
||||
// APPEND_IF_NOT_NULL_STR(buffer, size, offset, " MOSCQEstAlgo=%s", rm.quality_estimates.moscqestalg);
|
||||
// APPEND_IF_NOT_NULL_STR(buffer, size, offset, " QoEEstAlg=%s", rm.quality_estimates.qoestalg);
|
||||
append_to_buffer(buffer, size, offset, "\r\n");
|
||||
|
||||
ms_free(timestamps_start_str);
|
||||
ms_free(timestamps_stop_str);
|
||||
ms_free(network_packet_loss_rate_str);
|
||||
ms_free(jitter_buffer_discard_rate_str);
|
||||
// ms_free(gap_loss_density_str);
|
||||
ms_free(moslq_str);
|
||||
ms_free(moscq_str);
|
||||
}
|
||||
|
||||
static void reporting_publish(const LinphoneCall* call, const reporting_session_report_t * report) {
|
||||
LinphoneContent content = {0};
|
||||
LinphoneAddress *addr;
|
||||
int expires = -1;
|
||||
size_t offset = 0;
|
||||
size_t size = 2048;
|
||||
char * buffer;
|
||||
|
||||
// if the call was hungup too early, we might have invalid IPs information
|
||||
// in that case, we abort the report since it's not useful data
|
||||
if (strlen(report->info.local_addr.ip) == 0 || strlen(report->info.remote_addr.ip) == 0) {
|
||||
ms_warning("The call was hang up too early (duration: %d sec) and IP could "
|
||||
"not be retrieved so dropping this report", linphone_call_get_duration(call));
|
||||
return;
|
||||
}
|
||||
|
||||
buffer = (char *) ms_malloc(size);
|
||||
content.type = ms_strdup("application");
|
||||
content.subtype = ms_strdup("vq-rtcpxr");
|
||||
|
||||
append_to_buffer(&buffer, &size, &offset, "VQSessionReport: CallTerm\r\n");
|
||||
append_to_buffer(&buffer, &size, &offset, "CallID: %s\r\n", report->info.call_id);
|
||||
append_to_buffer(&buffer, &size, &offset, "LocalID: %s\r\n", report->info.local_id);
|
||||
append_to_buffer(&buffer, &size, &offset, "RemoteID: %s\r\n", report->info.remote_id);
|
||||
append_to_buffer(&buffer, &size, &offset, "OrigID: %s\r\n", report->info.orig_id);
|
||||
|
||||
APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "LocalGroup: %s\r\n", report->info.local_group);
|
||||
APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "RemoteGroup: %s\r\n", report->info.remote_group);
|
||||
append_to_buffer(&buffer, &size, &offset, "LocalAddr: IP=%s PORT=%d SSRC=%d\r\n", report->info.local_addr.ip, report->info.local_addr.port, report->info.local_addr.ssrc);
|
||||
APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "LocalMAC: %s\r\n", report->info.local_mac_addr);
|
||||
append_to_buffer(&buffer, &size, &offset, "RemoteAddr: IP=%s PORT=%d SSRC=%d\r\n", report->info.remote_addr.ip, report->info.remote_addr.port, report->info.remote_addr.ssrc);
|
||||
APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "RemoteMAC: %s\r\n", report->info.remote_mac_addr);
|
||||
|
||||
append_to_buffer(&buffer, &size, &offset, "LocalMetrics:\r\n");
|
||||
append_metrics_to_buffer(&buffer, &size, &offset, report->local_metrics);
|
||||
|
||||
if (are_metrics_filled(report->remote_metrics)) {
|
||||
append_to_buffer(&buffer, &size, &offset, "RemoteMetrics:\r\n");
|
||||
append_metrics_to_buffer(&buffer, &size, &offset, report->remote_metrics);
|
||||
}
|
||||
APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "DialogID: %s\r\n", report->dialog_id);
|
||||
|
||||
content.data = buffer;
|
||||
content.size = strlen((char*)content.data);
|
||||
|
||||
|
||||
addr = linphone_address_new(call->dest_proxy->reg_statistics_collector);
|
||||
if (addr != NULL) {
|
||||
linphone_core_publish(call->core, addr, "vq-rtcpxr", expires, &content);
|
||||
linphone_address_destroy(addr);
|
||||
} else {
|
||||
ms_warning("Asked to submit reporting statistics but no collector address found");
|
||||
}
|
||||
|
||||
linphone_content_uninit(&content);
|
||||
}
|
||||
|
||||
static const SalStreamDescription * get_media_stream_for_desc(const SalMediaDescription * smd, SalStreamType sal_stream_type) {
|
||||
int count;
|
||||
if (smd != NULL) {
|
||||
for (count = 0; count < smd->n_total_streams; ++count) {
|
||||
if (smd->streams[count].type == sal_stream_type) {
|
||||
return &smd->streams[count];
|
||||
}
|
||||
}
|
||||
}
|
||||
if (smd == NULL || count == smd->n_total_streams) {
|
||||
ms_warning("Could not find the associated stream of type %d", sal_stream_type);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void reporting_update_ip(LinphoneCall * call, int stats_type) {
|
||||
SalStreamType sal_stream_type = (stats_type == LINPHONE_CALL_STATS_AUDIO) ? SalAudio : SalVideo;
|
||||
if (call->log->reports[stats_type] != NULL) {
|
||||
const SalStreamDescription * local_desc = get_media_stream_for_desc(call->localdesc, sal_stream_type);
|
||||
const SalStreamDescription * remote_desc = get_media_stream_for_desc(sal_call_get_remote_media_description(call->op), sal_stream_type);
|
||||
|
||||
// local info are always up-to-date and correct
|
||||
if (local_desc != NULL) {
|
||||
call->log->reports[stats_type]->info.local_addr.port = local_desc->rtp_port;
|
||||
STR_REASSIGN(call->log->reports[stats_type]->info.local_addr.ip, ms_strdup(local_desc->rtp_addr));
|
||||
}
|
||||
|
||||
if (remote_desc != NULL) {
|
||||
// port is always stored in stream description struct
|
||||
call->log->reports[stats_type]->info.remote_addr.port = remote_desc->rtp_port;
|
||||
|
||||
// for IP it can be not set if we are using a direct route
|
||||
if (remote_desc->rtp_addr != NULL && strlen(remote_desc->rtp_addr) > 0) {
|
||||
STR_REASSIGN(call->log->reports[stats_type]->info.remote_addr.ip, ms_strdup(remote_desc->rtp_addr));
|
||||
} else {
|
||||
STR_REASSIGN(call->log->reports[stats_type]->info.remote_addr.ip, ms_strdup(sal_call_get_remote_media_description(call->op)->addr));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bool_t reporting_enabled(const LinphoneCall * call) {
|
||||
return (call->dest_proxy != NULL && linphone_proxy_config_send_statistics_enabled(call->dest_proxy));
|
||||
}
|
||||
|
||||
void linphone_reporting_update_ip(LinphoneCall * call) {
|
||||
// This function can be called in two different cases:
|
||||
// - 1) at start when call is starting, remote ip/port info might be the proxy ones to which callee is registered
|
||||
// - 2) later, if we found a direct route between caller and callee with ICE/Stun, ip/port are updated for the direct route access
|
||||
|
||||
if (! reporting_enabled(call))
|
||||
return;
|
||||
|
||||
reporting_update_ip(call, LINPHONE_CALL_STATS_AUDIO);
|
||||
|
||||
if (linphone_call_params_video_enabled(linphone_call_get_current_params(call))) {
|
||||
reporting_update_ip(call, LINPHONE_CALL_STATS_VIDEO);
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_reporting_update(LinphoneCall * call, int stats_type) {
|
||||
reporting_session_report_t * report = call->log->reports[stats_type];
|
||||
MediaStream * stream = NULL;
|
||||
const PayloadType * local_payload = NULL;
|
||||
const PayloadType * remote_payload = NULL;
|
||||
const LinphoneCallParams * current_params = linphone_call_get_current_params(call);
|
||||
|
||||
if (! reporting_enabled(call))
|
||||
return;
|
||||
|
||||
STR_REASSIGN(report->info.call_id, ms_strdup(call->log->call_id));
|
||||
STR_REASSIGN(report->info.local_group, ms_strdup_printf(_("linphone-%s-%s-%s"), (stats_type == LINPHONE_CALL_STATS_AUDIO ? "audio" : "video"),
|
||||
linphone_core_get_user_agent_name(), report->info.call_id));
|
||||
STR_REASSIGN(report->info.remote_group, ms_strdup_printf(_("linphone-%s-%s-%s"), (stats_type == LINPHONE_CALL_STATS_AUDIO ? "audio" : "video"),
|
||||
linphone_call_get_remote_user_agent(call), report->info.call_id));
|
||||
|
||||
if (call->dir == LinphoneCallIncoming) {
|
||||
STR_REASSIGN(report->info.remote_id, linphone_address_as_string(call->log->from));
|
||||
STR_REASSIGN(report->info.local_id, linphone_address_as_string(call->log->to));
|
||||
STR_REASSIGN(report->info.orig_id, ms_strdup(report->info.remote_id));
|
||||
} else {
|
||||
STR_REASSIGN(report->info.remote_id, linphone_address_as_string(call->log->to));
|
||||
STR_REASSIGN(report->info.local_id, linphone_address_as_string(call->log->from));
|
||||
STR_REASSIGN(report->info.orig_id, ms_strdup(report->info.local_id));
|
||||
}
|
||||
|
||||
STR_REASSIGN(report->dialog_id, sal_op_get_dialog_id(call->op));
|
||||
|
||||
report->local_metrics.timestamps.start = call->log->start_date_time;
|
||||
report->local_metrics.timestamps.stop = call->log->start_date_time + linphone_call_get_duration(call);
|
||||
|
||||
//we use same timestamps for remote too
|
||||
report->remote_metrics.timestamps.start = call->log->start_date_time;
|
||||
report->remote_metrics.timestamps.stop = call->log->start_date_time + linphone_call_get_duration(call);
|
||||
|
||||
// yet we use the same payload config for local and remote, since this is the largest use case
|
||||
if (stats_type == LINPHONE_CALL_STATS_AUDIO && call->audiostream != NULL) {
|
||||
stream = &call->audiostream->ms;
|
||||
local_payload = linphone_call_params_get_used_audio_codec(current_params);
|
||||
remote_payload = local_payload;
|
||||
} else if (stats_type == LINPHONE_CALL_STATS_VIDEO && call->videostream != NULL) {
|
||||
stream = &call->videostream->ms;
|
||||
local_payload = linphone_call_params_get_used_video_codec(current_params);
|
||||
remote_payload = local_payload;
|
||||
}
|
||||
|
||||
if (stream != NULL) {
|
||||
RtpSession * session = stream->sessions.rtp_session;
|
||||
|
||||
report->info.local_addr.ssrc = rtp_session_get_send_ssrc(session);
|
||||
report->info.remote_addr.ssrc = rtp_session_get_recv_ssrc(session);
|
||||
}
|
||||
|
||||
if (local_payload != NULL) {
|
||||
report->local_metrics.session_description.payload_type = local_payload->type;
|
||||
STR_REASSIGN(report->local_metrics.session_description.payload_desc, ms_strdup(local_payload->mime_type));
|
||||
report->local_metrics.session_description.sample_rate = local_payload->clock_rate;
|
||||
STR_REASSIGN(report->local_metrics.session_description.fmtp, ms_strdup(local_payload->recv_fmtp));
|
||||
}
|
||||
|
||||
if (remote_payload != NULL) {
|
||||
report->remote_metrics.session_description.payload_type = remote_payload->type;
|
||||
STR_REASSIGN(report->remote_metrics.session_description.payload_desc, ms_strdup(remote_payload->mime_type));
|
||||
report->remote_metrics.session_description.sample_rate = remote_payload->clock_rate;
|
||||
STR_REASSIGN(report->remote_metrics.session_description.fmtp, ms_strdup(remote_payload->recv_fmtp));
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_reporting_call_stats_updated(LinphoneCall *call, int stats_type) {
|
||||
reporting_session_report_t * report = call->log->reports[stats_type];
|
||||
reporting_content_metrics_t * metrics = NULL;
|
||||
|
||||
LinphoneCallStats stats = call->stats[stats_type];
|
||||
mblk_t *block = NULL;
|
||||
|
||||
if (! reporting_enabled(call))
|
||||
return;
|
||||
|
||||
if (stats.updated == LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE) {
|
||||
metrics = &report->remote_metrics;
|
||||
if (rtcp_is_XR(stats.received_rtcp) == TRUE) {
|
||||
block = stats.received_rtcp;
|
||||
}
|
||||
} else if (stats.updated == LINPHONE_CALL_STATS_SENT_RTCP_UPDATE) {
|
||||
metrics = &report->local_metrics;
|
||||
if (rtcp_is_XR(stats.sent_rtcp) == TRUE) {
|
||||
block = stats.sent_rtcp;
|
||||
}
|
||||
}
|
||||
if (block != NULL) {
|
||||
switch (rtcp_XR_get_block_type(block)) {
|
||||
case RTCP_XR_VOIP_METRICS: {
|
||||
metrics->quality_estimates.rcq = rtcp_XR_voip_metrics_get_r_factor(block);
|
||||
metrics->quality_estimates.moslq = rtcp_XR_voip_metrics_get_mos_lq(block) / 10.f;
|
||||
metrics->quality_estimates.moscq = rtcp_XR_voip_metrics_get_mos_cq(block) / 10.f;
|
||||
|
||||
metrics->jitter_buffer.nominal = rtcp_XR_voip_metrics_get_jb_nominal(block);
|
||||
metrics->jitter_buffer.max = rtcp_XR_voip_metrics_get_jb_maximum(block);
|
||||
metrics->jitter_buffer.abs_max = rtcp_XR_voip_metrics_get_jb_abs_max(block);
|
||||
metrics->packet_loss.network_packet_loss_rate = rtcp_XR_voip_metrics_get_loss_rate(block);
|
||||
metrics->packet_loss.jitter_buffer_discard_rate = rtcp_XR_voip_metrics_get_discard_rate(block);
|
||||
|
||||
uint8_t config = rtcp_XR_voip_metrics_get_rx_config(block);
|
||||
metrics->session_description.packet_loss_concealment = (config >> 6) & 0x3;
|
||||
metrics->jitter_buffer.adaptive = (config >> 4) & 0x3;
|
||||
break;
|
||||
} default: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_reporting_publish(LinphoneCall* call) {
|
||||
if (! reporting_enabled(call))
|
||||
return;
|
||||
|
||||
|
||||
if (call->log->reports[LINPHONE_CALL_STATS_AUDIO] != NULL) {
|
||||
reporting_publish(call, call->log->reports[LINPHONE_CALL_STATS_AUDIO]);
|
||||
}
|
||||
|
||||
if (call->log->reports[LINPHONE_CALL_STATS_VIDEO] != NULL
|
||||
&& linphone_call_params_video_enabled(linphone_call_get_current_params(call))) {
|
||||
reporting_publish(call, call->log->reports[LINPHONE_CALL_STATS_VIDEO]);
|
||||
}
|
||||
}
|
||||
|
||||
reporting_session_report_t * linphone_reporting_new() {
|
||||
int i;
|
||||
reporting_session_report_t * rm = ms_new0(reporting_session_report_t,1);
|
||||
|
||||
reporting_content_metrics_t * metrics[2] = {&rm->local_metrics, &rm->remote_metrics};
|
||||
for (i = 0; i < 2; i++) {
|
||||
metrics[i]->session_description.payload_type = -1;
|
||||
metrics[i]->session_description.sample_rate = -1;
|
||||
metrics[i]->session_description.frame_duration = -1;
|
||||
|
||||
metrics[i]->packet_loss.network_packet_loss_rate = -1;
|
||||
metrics[i]->packet_loss.jitter_buffer_discard_rate = -1;
|
||||
|
||||
metrics[i]->session_description.packet_loss_concealment = -1;
|
||||
|
||||
metrics[i]->jitter_buffer.adaptive = -1;
|
||||
// metrics[i]->jitter_buffer.rate = -1;
|
||||
metrics[i]->jitter_buffer.nominal = -1;
|
||||
metrics[i]->jitter_buffer.max = -1;
|
||||
metrics[i]->jitter_buffer.abs_max = -1;
|
||||
|
||||
metrics[i]->delay.round_trip_delay = -1;
|
||||
metrics[i]->delay.end_system_delay = -1;
|
||||
// metrics[i]->delay.one_way_delay = -1;
|
||||
metrics[i]->delay.symm_one_way_delay = -1;
|
||||
metrics[i]->delay.interarrival_jitter = -1;
|
||||
metrics[i]->delay.mean_abs_jitter = -1;
|
||||
|
||||
metrics[i]->signal.level = 127;
|
||||
metrics[i]->signal.noise_level = 127;
|
||||
}
|
||||
return rm;
|
||||
}
|
||||
|
||||
void linphone_reporting_destroy(reporting_session_report_t * report) {
|
||||
if (report->info.call_id != NULL) ms_free(report->info.call_id);
|
||||
if (report->info.local_id != NULL) ms_free(report->info.local_id);
|
||||
if (report->info.remote_id != NULL) ms_free(report->info.remote_id);
|
||||
if (report->info.orig_id != NULL) ms_free(report->info.orig_id);
|
||||
if (report->info.local_addr.ip != NULL) ms_free(report->info.local_addr.ip);
|
||||
if (report->info.remote_addr.ip != NULL) ms_free(report->info.remote_addr.ip);
|
||||
if (report->info.local_group != NULL) ms_free(report->info.local_group);
|
||||
if (report->info.remote_group != NULL) ms_free(report->info.remote_group);
|
||||
if (report->info.local_mac_addr != NULL) ms_free(report->info.local_mac_addr);
|
||||
if (report->info.remote_mac_addr != NULL) ms_free(report->info.remote_mac_addr);
|
||||
if (report->dialog_id != NULL) ms_free(report->dialog_id);
|
||||
if (report->local_metrics.session_description.fmtp != NULL) ms_free(report->local_metrics.session_description.fmtp);
|
||||
if (report->local_metrics.session_description.payload_desc != NULL) ms_free(report->local_metrics.session_description.payload_desc);
|
||||
if (report->remote_metrics.session_description.fmtp != NULL) ms_free(report->remote_metrics.session_description.fmtp);
|
||||
if (report->remote_metrics.session_description.payload_desc != NULL) ms_free(report->remote_metrics.session_description.payload_desc);
|
||||
|
||||
ms_free(report);
|
||||
}
|
||||
149
coreapi/quality_reporting.h
Normal file
149
coreapi/quality_reporting.h
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
/*
|
||||
linphone
|
||||
Copyright (C) 2014 - Belledonne Communications, Grenoble, France
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
#ifndef quality_reporting_h
|
||||
#define quality_reporting_h
|
||||
|
||||
#include "linphonecore.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"{
|
||||
#endif
|
||||
|
||||
typedef struct reporting_addr {
|
||||
char * ip;
|
||||
int port;
|
||||
uint32_t ssrc;
|
||||
} reporting_addr_t;
|
||||
|
||||
typedef struct reporting_content_metrics {
|
||||
// timestamps - mandatory
|
||||
struct {
|
||||
time_t start;
|
||||
time_t stop;
|
||||
} timestamps;
|
||||
|
||||
// session description - optional
|
||||
struct {
|
||||
int payload_type;
|
||||
char * payload_desc; // mime type
|
||||
int sample_rate; // clock rate
|
||||
int frame_duration; // to check (ptime?) - audio only
|
||||
// int frame_ocets;
|
||||
// int frames_per_sec;
|
||||
// int packets_per_sec;
|
||||
char * fmtp;
|
||||
int packet_loss_concealment; // in voip metrics - audio only
|
||||
// char * silence_suppression_state;
|
||||
} session_description;
|
||||
|
||||
// jitter buffet - optional
|
||||
struct {
|
||||
int adaptive; // constant
|
||||
// int rate; // constant
|
||||
int nominal; // no may vary during the call <- average? worst score?
|
||||
int max; // no may vary during the call <- average?
|
||||
int abs_max; // constant
|
||||
} jitter_buffer;
|
||||
|
||||
// packet loss - optional
|
||||
struct {
|
||||
float network_packet_loss_rate; // voip metrics (loss rate) + conversion
|
||||
float jitter_buffer_discard_rate; //idem
|
||||
} packet_loss;
|
||||
|
||||
// burst gap loss - optional
|
||||
// (no) currently not implemented
|
||||
// struct {
|
||||
// int burst_loss_density;
|
||||
// int burst_duration;
|
||||
// float gap_loss_density;
|
||||
// int gap_duration;
|
||||
// int min_gap_threshold;
|
||||
// } burst_gap_loss;
|
||||
|
||||
// delay - optional
|
||||
struct {
|
||||
int round_trip_delay; // no - vary
|
||||
int end_system_delay; // no - not implemented yet
|
||||
// int one_way_delay;
|
||||
int symm_one_way_delay; // no - vary (depends on round_trip_delay) + not implemented (depends on end_system_delay)
|
||||
int interarrival_jitter; // no - not implemented yet
|
||||
int mean_abs_jitter; // to check
|
||||
} delay;
|
||||
|
||||
// signal - optional
|
||||
struct {
|
||||
int level; // no - vary
|
||||
int noise_level; // no - vary
|
||||
// int residual_echo_return_loss;
|
||||
} signal;
|
||||
|
||||
// quality estimates - optional
|
||||
struct {
|
||||
int rlq; // linked to moslq - in [0..120]
|
||||
int rcq; //voip metrics R factor - no - vary or avg in [0..120]
|
||||
float moslq; // no - vary or avg - voip metrics - in [0..4.9]
|
||||
float moscq; // no - vary or avg - voip metrics - in [0..4.9]
|
||||
|
||||
|
||||
// int extri;
|
||||
// int extro;
|
||||
// char * rlqestalg;
|
||||
// char * rcqestalg;
|
||||
// char * moslqestalg;
|
||||
// char * moscqestalg;
|
||||
// char * extriestalg;
|
||||
// char * extroutestalg;
|
||||
// char * qoestalg;
|
||||
} quality_estimates;
|
||||
} reporting_content_metrics_t;
|
||||
|
||||
typedef struct reporting_session_report {
|
||||
struct {
|
||||
char * call_id;
|
||||
char * local_id;
|
||||
char * remote_id;
|
||||
char * orig_id;
|
||||
reporting_addr_t local_addr;
|
||||
reporting_addr_t remote_addr;
|
||||
char * local_group;
|
||||
char * remote_group;
|
||||
|
||||
char * local_mac_addr; // optional
|
||||
char * remote_mac_addr; // optional
|
||||
} info;
|
||||
|
||||
reporting_content_metrics_t local_metrics;
|
||||
reporting_content_metrics_t remote_metrics; // optional
|
||||
|
||||
char * dialog_id; // optional
|
||||
} reporting_session_report_t;
|
||||
|
||||
reporting_session_report_t * linphone_reporting_new();
|
||||
void linphone_reporting_destroy(reporting_session_report_t * report);
|
||||
void linphone_reporting_update(LinphoneCall * call, int stats_type);
|
||||
void linphone_reporting_update_ip(LinphoneCall * call);
|
||||
void linphone_reporting_publish(LinphoneCall* call);
|
||||
void linphone_reporting_call_stats_updated(LinphoneCall *call, int stats_type);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
@ -17,9 +17,9 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
/**
|
||||
This header files defines the Signaling Abstraction Layer.
|
||||
The purpose of this layer is too allow experiment different call signaling
|
||||
The purpose of this layer is too allow experiment different call signaling
|
||||
protocols and implementations under linphone, for example SIP, JINGLE...
|
||||
**/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
|
@ -39,7 +39,7 @@ const char* sal_transport_to_string(SalTransport transport) {
|
|||
default: {
|
||||
ms_fatal("Unexpected transport [%i]",transport);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -372,6 +372,14 @@ const char *sal_op_get_network_origin(const SalOp *op){
|
|||
const char* sal_op_get_call_id(const SalOp *op) {
|
||||
return ((SalOpBase*)op)->call_id;
|
||||
}
|
||||
char* sal_op_get_dialog_id(const SalOp *op) {
|
||||
if (op->dialog != NULL) {
|
||||
return ms_strdup_printf("%s;to-tag=%s;from-tag=%s", ((SalOpBase*)op)->call_id,
|
||||
belle_sip_dialog_get_remote_tag(op->dialog), belle_sip_dialog_get_local_tag(op->dialog));
|
||||
}
|
||||
return NULL;
|
||||
|
||||
}
|
||||
void __sal_op_init(SalOp *b, Sal *sal){
|
||||
memset(b,0,sizeof(SalOpBase));
|
||||
((SalOpBase*)b)->root=sal;
|
||||
|
|
@ -401,17 +409,17 @@ void __sal_op_free(SalOp *op){
|
|||
sal_address_destroy(b->to_address);
|
||||
b->to_address=NULL;
|
||||
}
|
||||
|
||||
|
||||
if (b->service_route){
|
||||
sal_address_destroy(b->service_route);
|
||||
b->service_route=NULL;
|
||||
}
|
||||
|
||||
|
||||
if (b->origin_address){
|
||||
sal_address_destroy(b->origin_address);
|
||||
b->origin_address=NULL;
|
||||
}
|
||||
|
||||
|
||||
if (b->from) {
|
||||
ms_free(b->from);
|
||||
b->from=NULL;
|
||||
|
|
@ -616,7 +624,7 @@ static int line_get_value(const char *input, const char *key, char *value, size_
|
|||
|
||||
int sal_lines_get_value(const char *data, const char *key, char *value, size_t value_size){
|
||||
int read=0;
|
||||
|
||||
|
||||
do{
|
||||
if (line_get_value(data,key,value,value_size,&read))
|
||||
return TRUE;
|
||||
|
|
@ -626,7 +634,7 @@ int sal_lines_get_value(const char *data, const char *key, char *value, size_t v
|
|||
}
|
||||
|
||||
int sal_body_has_type(const SalBody *body, const char *type, const char *subtype){
|
||||
return body->type && body->subtype
|
||||
return body->type && body->subtype
|
||||
&& strcmp(body->type,type)==0
|
||||
&& strcmp(body->subtype,subtype)==0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ along with this program; if not, write to the Free Software
|
|||
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
/**
|
||||
/**
|
||||
This header files defines the Signaling Abstraction Layer.
|
||||
The purpose of this layer is too allow experiment different call signaling
|
||||
The purpose of this layer is too allow experiment different call signaling
|
||||
protocols and implementations under linphone, for example SIP, JINGLE...
|
||||
**/
|
||||
|
||||
|
|
@ -571,6 +571,7 @@ const SalAddress *sal_op_get_network_origin_address(const SalOp *op);
|
|||
const char *sal_op_get_remote_ua(const SalOp *op);
|
||||
void *sal_op_get_user_pointer(const SalOp *op);
|
||||
const char* sal_op_get_call_id(const SalOp *op);
|
||||
char* sal_op_get_dialog_id(const SalOp *op);
|
||||
|
||||
const SalAddress* sal_op_get_service_route(const SalOp *op);
|
||||
void sal_op_set_service_route(SalOp *op,const SalAddress* service_route);
|
||||
|
|
|
|||
|
|
@ -119,10 +119,10 @@ void liblinphone_tester_check_rtcp(LinphoneCoreManager* caller, LinphoneCoreMana
|
|||
|
||||
c1=linphone_core_get_current_call(caller->lc);
|
||||
c2=linphone_core_get_current_call(callee->lc);
|
||||
|
||||
|
||||
CU_ASSERT_PTR_NOT_NULL(c1);
|
||||
CU_ASSERT_PTR_NOT_NULL(c2);
|
||||
|
||||
|
||||
if (!c1 || !c2) return;
|
||||
|
||||
for (i=0; i<24 /*=12s need at least one exchange of SR to maybe 10s*/; i++) {
|
||||
|
|
@ -339,7 +339,7 @@ static void cancelled_call(void) {
|
|||
static void disable_all_codecs_except_one(LinphoneCore *lc, const char *mime){
|
||||
const MSList *elem=linphone_core_get_audio_codecs(lc);
|
||||
PayloadType *pt;
|
||||
|
||||
|
||||
for(;elem!=NULL;elem=elem->next){
|
||||
pt=(PayloadType*)elem->data;
|
||||
linphone_core_enable_payload_type(lc,pt,FALSE);
|
||||
|
|
@ -374,7 +374,7 @@ static void call_with_dns_time_out(void) {
|
|||
LinphoneCoreManager* marie = linphone_core_manager_new2( "empty_rc", FALSE);
|
||||
LCSipTransports transport = {9773,0,0,0};
|
||||
int i;
|
||||
|
||||
|
||||
linphone_core_set_sip_transports(marie->lc,&transport);
|
||||
linphone_core_iterate(marie->lc);
|
||||
sal_set_dns_timeout(marie->lc->sal,0);
|
||||
|
|
@ -382,7 +382,7 @@ static void call_with_dns_time_out(void) {
|
|||
for(i=0;i<10;i++){
|
||||
ms_usleep(200000);
|
||||
linphone_core_iterate(marie->lc);
|
||||
}
|
||||
}
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallOutgoingInit,1);
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallOutgoingProgress,1);
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallError,1);
|
||||
|
|
@ -395,21 +395,21 @@ static void early_cancelled_call(void) {
|
|||
LinphoneCoreManager* pauline = linphone_core_manager_new2( "empty_rc",FALSE);
|
||||
|
||||
LinphoneCall* out_call = linphone_core_invite_address(pauline->lc,marie->identity);
|
||||
|
||||
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallOutgoingInit,1));
|
||||
linphone_core_terminate_call(pauline->lc,out_call);
|
||||
|
||||
|
||||
/*since everything is executed in a row, no response can be received from the server, thus the CANCEL cannot be sent.
|
||||
It will ring at Marie's side.*/
|
||||
|
||||
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1));
|
||||
|
||||
|
||||
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallEnd,1);
|
||||
|
||||
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallIncomingReceived,1));
|
||||
/* now the CANCEL should have been sent and the the call at marie's side should terminate*/
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1));
|
||||
|
||||
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallReleased,1));
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
|
|
@ -449,7 +449,7 @@ static void early_declined_call(void) {
|
|||
CU_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallError,1,33000));
|
||||
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallError,1);
|
||||
/* FIXME http://git.linphone.org/mantis/view.php?id=757
|
||||
|
||||
|
||||
CU_ASSERT_EQUAL(linphone_call_get_reason(out_call),LinphoneReasonBusy);
|
||||
*/
|
||||
if (ms_list_size(linphone_core_get_call_logs(pauline->lc))>0) {
|
||||
|
|
@ -489,7 +489,7 @@ static void call_declined(void) {
|
|||
static void call_terminated_by_caller(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
||||
|
||||
CU_ASSERT_TRUE(call(pauline,marie));
|
||||
/*just to sleep*/
|
||||
linphone_core_terminate_all_calls(pauline->lc);
|
||||
|
|
@ -503,7 +503,7 @@ static void call_terminated_by_caller(void) {
|
|||
static void call_with_no_sdp(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
||||
|
||||
linphone_core_enable_sdp_200_ack(marie->lc,TRUE);
|
||||
|
||||
CU_ASSERT_TRUE(call(marie,pauline));
|
||||
|
|
@ -523,7 +523,7 @@ static bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee
|
|||
|
||||
c1=linphone_core_get_current_call(caller->lc);
|
||||
c2=linphone_core_get_current_call(callee->lc);
|
||||
|
||||
|
||||
CU_ASSERT_PTR_NOT_NULL(c1);
|
||||
CU_ASSERT_PTR_NOT_NULL(c2);
|
||||
|
||||
|
|
@ -556,7 +556,7 @@ static bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee
|
|||
static void _call_with_ice(bool_t caller_with_ice, bool_t callee_with_ice, bool_t random_ports) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
||||
|
||||
if (callee_with_ice){
|
||||
linphone_core_set_firewall_policy(marie->lc,LinphonePolicyUseIce);
|
||||
linphone_core_set_stun_server(marie->lc,"stun.linphone.org");
|
||||
|
|
@ -565,7 +565,7 @@ static void _call_with_ice(bool_t caller_with_ice, bool_t callee_with_ice, bool_
|
|||
linphone_core_set_firewall_policy(pauline->lc,LinphonePolicyUseIce);
|
||||
linphone_core_set_stun_server(pauline->lc,"stun.linphone.org");
|
||||
}
|
||||
|
||||
|
||||
if (random_ports){
|
||||
linphone_core_set_audio_port(marie->lc,-1);
|
||||
linphone_core_set_video_port(marie->lc,-1);
|
||||
|
|
@ -580,10 +580,10 @@ static void _call_with_ice(bool_t caller_with_ice, bool_t callee_with_ice, bool_
|
|||
/*wait for the ICE reINVITE to complete*/
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2));
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2));
|
||||
|
||||
|
||||
CU_ASSERT_TRUE(check_ice(pauline,marie,LinphoneIceStateHostConnection));
|
||||
}
|
||||
|
||||
|
||||
liblinphone_tester_check_rtcp(marie,pauline);
|
||||
/*then close the call*/
|
||||
linphone_core_terminate_all_calls(pauline->lc);
|
||||
|
|
@ -629,17 +629,17 @@ static void call_with_custom_headers(void) {
|
|||
ms_free(tmp);
|
||||
linphone_address_destroy(marie->identity);
|
||||
marie->identity=marie_identity;
|
||||
|
||||
|
||||
params=linphone_core_create_default_call_parameters(marie->lc);
|
||||
linphone_call_params_add_custom_header(params,"Weather","bad");
|
||||
linphone_call_params_add_custom_header(params,"Working","yes");
|
||||
|
||||
|
||||
CU_ASSERT_TRUE(call_with_caller_params(pauline,marie,params));
|
||||
linphone_call_params_destroy(params);
|
||||
|
||||
|
||||
call_marie=linphone_core_get_current_call(marie->lc);
|
||||
call_pauline=linphone_core_get_current_call(pauline->lc);
|
||||
|
||||
|
||||
CU_ASSERT_PTR_NOT_NULL(call_marie);
|
||||
CU_ASSERT_PTR_NOT_NULL(call_pauline);
|
||||
|
||||
|
|
@ -824,12 +824,12 @@ static void call_with_video_added(void) {
|
|||
static void call_with_video_added_random_ports(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
||||
|
||||
linphone_core_set_audio_port(marie->lc,-1);
|
||||
linphone_core_set_video_port(marie->lc,-1);
|
||||
linphone_core_set_audio_port(pauline->lc,-1);
|
||||
linphone_core_set_video_port(pauline->lc,-1);
|
||||
|
||||
|
||||
CU_ASSERT_TRUE(call(pauline,marie));
|
||||
|
||||
CU_ASSERT_TRUE(add_video(pauline,marie));
|
||||
|
|
@ -922,17 +922,17 @@ static void _call_with_media_relay(bool_t random_ports) {
|
|||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL);
|
||||
linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL);
|
||||
|
||||
|
||||
if (random_ports){
|
||||
linphone_core_set_audio_port(marie->lc,-1);
|
||||
linphone_core_set_video_port(marie->lc,-1);
|
||||
linphone_core_set_audio_port(pauline->lc,-1);
|
||||
linphone_core_set_video_port(pauline->lc,-1);
|
||||
}
|
||||
|
||||
|
||||
CU_ASSERT_TRUE(call(pauline,marie));
|
||||
liblinphone_tester_check_rtcp(pauline,marie);
|
||||
|
||||
|
||||
#ifdef VIDEO_ENABLED
|
||||
CU_ASSERT_TRUE(add_video(pauline,marie));
|
||||
liblinphone_tester_check_rtcp(pauline,marie);
|
||||
|
|
@ -1018,7 +1018,7 @@ static void call_with_privacy2(void) {
|
|||
LinphoneProxyConfig* pauline_proxy;
|
||||
params=linphone_core_create_default_call_parameters(pauline->lc);
|
||||
linphone_call_params_set_privacy(params,LinphonePrivacyId);
|
||||
|
||||
|
||||
linphone_core_get_default_proxy(pauline->lc,&pauline_proxy);
|
||||
linphone_proxy_config_edit(pauline_proxy);
|
||||
linphone_proxy_config_enable_register(pauline_proxy,FALSE);
|
||||
|
|
@ -1212,8 +1212,6 @@ static void simple_conference(void) {
|
|||
ms_list_free(lcs);
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void srtp_call() {
|
||||
call_base(LinphoneMediaEncryptionSRTP,FALSE,FALSE,LinphonePolicyNoFirewall);
|
||||
}
|
||||
|
|
@ -1349,19 +1347,19 @@ static void early_media_call(void) {
|
|||
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallIncomingEarlyMedia,1);
|
||||
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallOutgoingEarlyMedia,1);
|
||||
|
||||
|
||||
wait_for_until(pauline->lc,marie->lc,NULL,0,1000);
|
||||
|
||||
|
||||
/*added because a bug related to early-media caused the Connected state to be reached two times*/
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallConnected,1);
|
||||
|
||||
|
||||
/*just to sleep*/
|
||||
linphone_core_terminate_all_calls(marie->lc);
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1));
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1));
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
|
@ -1378,7 +1376,7 @@ static void early_media_call_with_ringing(void){
|
|||
/*
|
||||
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);
|
||||
|
|
@ -1414,7 +1412,7 @@ static void early_media_call_with_ringing(void){
|
|||
|
||||
|
||||
ms_list_free(lcs);
|
||||
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
|
@ -1537,9 +1535,9 @@ static void simple_call_transfer(void) {
|
|||
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallPaused,1,2000));
|
||||
/*marie calling laure*/
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingProgress,1,2000));
|
||||
|
||||
|
||||
CU_ASSERT_PTR_NOT_NULL(linphone_call_get_transfer_target_call(marie_calling_pauline));
|
||||
|
||||
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallOutgoingInit,1,2000));
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallIncomingReceived,1,2000));
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallOutgoingRinging,1,2000));
|
||||
|
|
@ -1549,11 +1547,11 @@ static void simple_call_transfer(void) {
|
|||
CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,1,2000));
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallConnected,1,2000));
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,2000));
|
||||
|
||||
|
||||
marie_calling_laure=linphone_core_get_current_call(marie->lc);
|
||||
CU_ASSERT_PTR_NOT_NULL_FATAL(marie_calling_laure);
|
||||
CU_ASSERT_TRUE(linphone_call_get_transferer_call(marie_calling_laure)==marie_calling_pauline);
|
||||
|
||||
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneTransferCallConnected,1,2000));
|
||||
|
||||
/*terminate marie to pauline call*/
|
||||
|
|
@ -1587,11 +1585,11 @@ static void unattended_call_transfer(void) {
|
|||
|
||||
linphone_core_transfer_call(marie->lc,pauline_called_by_marie,laure_identity);
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallRefered,1,2000));
|
||||
|
||||
|
||||
/*marie ends the call */
|
||||
linphone_core_terminate_call(marie->lc,pauline_called_by_marie);
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000));
|
||||
|
||||
|
||||
/*Pauline starts the transfer*/
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingInit,1,2000));
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingProgress,1,2000));
|
||||
|
|
@ -1628,21 +1626,21 @@ static void unattended_call_transfer_with_error(void) {
|
|||
|
||||
linphone_core_transfer_call(marie->lc,pauline_called_by_marie,"unknown_user");
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallRefered,1,2000));
|
||||
|
||||
|
||||
/*Pauline starts the transfer*/
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingInit,1,2000));
|
||||
/* and immediately get an error*/
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallError,1,2000));
|
||||
|
||||
|
||||
/*the error must be reported back to marie*/
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallError,1,2000));
|
||||
|
||||
/*and pauline should resume the call automatically*/
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallResuming,1,2000));
|
||||
|
||||
|
||||
/*and call should be resumed*/
|
||||
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,2000));
|
||||
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
ms_list_free(lcs);
|
||||
|
|
@ -1796,7 +1794,7 @@ static void call_established_with_rejected_incoming_reinvite(void) {
|
|||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
||||
CU_ASSERT_TRUE(call(pauline,marie));
|
||||
|
||||
|
||||
/*wait for ACK to be transmitted before going to reINVITE*/
|
||||
wait_for_until(marie->lc,pauline->lc,NULL,0,1000);
|
||||
|
||||
|
|
@ -1841,7 +1839,7 @@ static void call_redirect(void){
|
|||
/*
|
||||
Marie calls Pauline, which will redirect the call to Laure via a 302
|
||||
*/
|
||||
|
||||
|
||||
/*use playfile for callee to avoid locking on capture card*/
|
||||
linphone_core_use_files (pauline->lc,TRUE);
|
||||
linphone_core_use_files (laure->lc,TRUE);
|
||||
|
|
@ -1879,7 +1877,7 @@ static void call_redirect(void){
|
|||
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);
|
||||
linphone_core_manager_destroy(laure);
|
||||
|
|
@ -1968,6 +1966,98 @@ static void call_rejected_without_403_because_wrong_credentials_no_auth_req_cb()
|
|||
call_rejected_because_wrong_credentials_with_params("tester-no-403",FALSE);
|
||||
}
|
||||
|
||||
void create_call_for_statistics_tests(
|
||||
LinphoneCoreManager* marie,
|
||||
LinphoneCoreManager* pauline,
|
||||
LinphoneCall** call_marie,
|
||||
LinphoneCall** call_pauline) {
|
||||
CU_ASSERT_TRUE(call(pauline,marie));
|
||||
*call_marie = linphone_core_get_current_call(marie->lc);
|
||||
*call_pauline = linphone_core_get_current_call(pauline->lc);
|
||||
CU_ASSERT_PTR_NOT_NULL(*call_marie);
|
||||
CU_ASSERT_PTR_NOT_NULL(*call_pauline);
|
||||
}
|
||||
|
||||
static void statistics_not_used_without_config() {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
LinphoneCall* call_marie = NULL;
|
||||
LinphoneCall* call_pauline = NULL;
|
||||
|
||||
create_call_for_statistics_tests(marie, pauline, &call_marie, &call_pauline);
|
||||
|
||||
// marie has stats collection enabled since pauline has not
|
||||
CU_ASSERT_TRUE(linphone_proxy_config_send_statistics_enabled(call_marie->dest_proxy));
|
||||
CU_ASSERT_FALSE(linphone_proxy_config_send_statistics_enabled(call_pauline->dest_proxy));
|
||||
|
||||
CU_ASSERT_EQUAL(strcmp("sip:collector@sip.example.org",
|
||||
linphone_proxy_config_get_statistics_collector(call_marie->dest_proxy)), 0);
|
||||
|
||||
// this field should be already filled
|
||||
CU_ASSERT_PTR_NOT_NULL(call_marie->log->reports[0]->info.local_addr.ip);
|
||||
CU_ASSERT_PTR_NULL(call_pauline->log->reports[0]->info.local_addr.ip);
|
||||
|
||||
// but not this one since it is updated at the end of call
|
||||
CU_ASSERT_PTR_NULL(call_marie->log->reports[0]->dialog_id);
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
static void statistics_not_sent_if_call_not_started() {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
LinphoneCallLog* out_call_log;
|
||||
LinphoneCall* out_call;
|
||||
|
||||
linphone_core_set_max_calls(pauline->lc,0);
|
||||
out_call = linphone_core_invite(marie->lc,"pauline");
|
||||
linphone_call_ref(out_call);
|
||||
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallError,1));
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallError,1);
|
||||
|
||||
if (ms_list_size(linphone_core_get_call_logs(marie->lc))>0) {
|
||||
CU_ASSERT_PTR_NOT_NULL(out_call_log=(LinphoneCallLog*)(linphone_core_get_call_logs(marie->lc)->data));
|
||||
CU_ASSERT_EQUAL(linphone_call_log_get_status(out_call_log),LinphoneCallAborted);
|
||||
}
|
||||
linphone_call_unref(out_call);
|
||||
|
||||
// wait a few time...
|
||||
wait_for(marie->lc,NULL,NULL,0);
|
||||
// since the callee was busy, there should be no publish to do
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,0);
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0);
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
static void statistics_sent_at_call_termination() {
|
||||
// int return_code = -1;
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
LinphoneCall* call_marie = NULL;
|
||||
LinphoneCall* call_pauline = NULL;
|
||||
|
||||
create_call_for_statistics_tests(marie, pauline, &call_marie, &call_pauline);
|
||||
|
||||
linphone_core_terminate_all_calls(marie->lc);
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallReleased,1));
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,NULL,&pauline->stat.number_of_LinphoneCallReleased,1));
|
||||
|
||||
CU_ASSERT_PTR_NULL(linphone_core_get_current_call(marie->lc));
|
||||
CU_ASSERT_PTR_NULL(linphone_core_get_current_call(pauline->lc));
|
||||
|
||||
// now dialog id should be filled
|
||||
CU_ASSERT_PTR_NOT_NULL(call_marie->log->reports[0]->dialog_id);
|
||||
|
||||
// PUBLISH submission to the collector should be ok
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishProgress,1));
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishOk,1));
|
||||
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
#ifdef VIDEO_ENABLED
|
||||
#endif
|
||||
|
||||
|
|
@ -2027,7 +2117,10 @@ test_t call_tests[] = {
|
|||
{ "Call established with rejected RE-INVITE",call_established_with_rejected_reinvite},
|
||||
{ "Call established with rejected incoming RE-INVITE", call_established_with_rejected_incoming_reinvite },
|
||||
{ "Call established with rejected RE-INVITE in error", call_established_with_rejected_reinvite_with_error},
|
||||
{ "Call redirected by callee", call_redirect}
|
||||
{ "Call redirected by callee", call_redirect},
|
||||
{ "Call statistics not used if no config", statistics_not_used_without_config},
|
||||
{ "Call statistics not sent if call did not start", statistics_not_sent_if_call_not_started},
|
||||
{ "Call statistics sent if call ended normally", statistics_sent_at_call_termination},
|
||||
};
|
||||
|
||||
test_suite_t call_test_suite = {
|
||||
|
|
@ -2037,4 +2130,3 @@ test_suite_t call_test_suite = {
|
|||
sizeof(call_tests) / sizeof(call_tests[0]),
|
||||
call_tests
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,8 @@ reg_expires=3600
|
|||
reg_sendregister=1
|
||||
publish=0
|
||||
dial_escape_plus=0
|
||||
reg_statistics_collector=sip:collector@sip.example.org
|
||||
send_statistics=1
|
||||
|
||||
[friend_0]
|
||||
url="Paupoche" <sip:pauline@sip.example.org>
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue