mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-05-07 05:53:06 +00:00
Quality reporting: add on_report_send callback to check reports content in unit tests
This commit is contained in:
parent
dda79c7bc4
commit
929bc9744d
6 changed files with 233 additions and 18 deletions
|
|
@ -106,6 +106,7 @@ struct _LinphoneCallParams{
|
|||
struct _LinphoneQualityReporting{
|
||||
reporting_session_report_t * reports[2]; /**Store information on audio and video media streams (RFC 6035) */
|
||||
bool_t was_video_running; /*Keep video state since last check in order to detect its (de)activation*/
|
||||
LinphoneQualityReportingReportSendCb on_report_sent;
|
||||
};
|
||||
|
||||
struct _LinphoneCallLog{
|
||||
|
|
@ -860,7 +861,6 @@ LinphoneSubscriptionState linphone_subscription_state_from_sal(SalSubscribeStatu
|
|||
const LinphoneContent *linphone_content_from_sal_body(LinphoneContent *obj, const SalBody *ref);
|
||||
void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc);
|
||||
|
||||
|
||||
/*****************************************************************************
|
||||
* REMOTE PROVISIONING FUNCTIONS *
|
||||
****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|||
/***************************************************************************
|
||||
* TODO / REMINDER LIST
|
||||
***************************************************************************
|
||||
- move qos data at report's end? <-- unit test recup publish body
|
||||
bug ms_debug
|
||||
***************************************************************************
|
||||
* END OF TODO / REMINDER LIST
|
||||
****************************************************************************/
|
||||
|
|
@ -122,19 +122,15 @@ static uint8_t are_metrics_filled(const reporting_content_metrics_t rm) {
|
|||
IF_NUM_IN_RANGE(rm.packet_loss.network_packet_loss_rate, 0, 255, ret|=METRICS_PACKET_LOSS);
|
||||
IF_NUM_IN_RANGE(rm.packet_loss.jitter_buffer_discard_rate, 0, 255, ret|=METRICS_PACKET_LOSS);
|
||||
|
||||
/*since these are same values than local ones, do not check them*/
|
||||
/*if (rm.session_description.payload_type != -1) ret|=METRICS_SESSION_DESCRIPTION;*/
|
||||
/*if (rm.session_description.payload_desc != NULL) ret|=METRICS_SESSION_DESCRIPTION;*/
|
||||
/*if (rm.session_description.sample_rate != -1) ret|=METRICS_SESSION_DESCRIPTION;*/
|
||||
/*if (rm.session_description.fmtp != NULL) ret|=METRICS_SESSION_DESCRIPTION;*/
|
||||
if (rm.session_description.frame_duration != -1) ret|=METRICS_SESSION_DESCRIPTION;
|
||||
if (rm.session_description.packet_loss_concealment != -1) ret|=METRICS_SESSION_DESCRIPTION;
|
||||
if (rm.session_description.payload_type != -1) ret|=METRICS_SESSION_DESCRIPTION;
|
||||
if (rm.session_description.payload_desc != NULL) ret|=METRICS_SESSION_DESCRIPTION;
|
||||
if (rm.session_description.sample_rate != -1) ret|=METRICS_SESSION_DESCRIPTION;
|
||||
if (rm.session_description.fmtp != NULL) ret|=METRICS_SESSION_DESCRIPTION;
|
||||
|
||||
IF_NUM_IN_RANGE(rm.jitter_buffer.adaptive, 0, 3, ret|=METRICS_JITTER_BUFFER);
|
||||
IF_NUM_IN_RANGE(rm.jitter_buffer.abs_max, 0, 65535, ret|=METRICS_JITTER_BUFFER);
|
||||
|
||||
IF_NUM_IN_RANGE(rm.delay.end_system_delay, 0, 65535, ret|=METRICS_DELAY);
|
||||
/*IF_NUM_IN_RANGE(rm.delay.symm_one_way_delay, 0, 65535, ret|=METRICS_DELAY);*/
|
||||
IF_NUM_IN_RANGE(rm.delay.interarrival_jitter, 0, 65535, ret|=METRICS_DELAY);
|
||||
IF_NUM_IN_RANGE(rm.delay.mean_abs_jitter, 0, 65535, ret|=METRICS_DELAY);
|
||||
|
||||
|
|
@ -337,6 +333,13 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report,
|
|||
content.data = buffer;
|
||||
content.size = strlen(buffer);
|
||||
|
||||
if (call->log->reporting.on_report_sent != NULL){
|
||||
call->log->reporting.on_report_sent(
|
||||
call,
|
||||
(report==call->log->reporting.reports[0])?LINPHONE_CALL_STATS_AUDIO:LINPHONE_CALL_STATS_VIDEO,
|
||||
&content);
|
||||
}
|
||||
|
||||
if (! linphone_core_publish(call->core, addr, "vq-rtcpxr", expires, &content)){
|
||||
ret=4;
|
||||
} else {
|
||||
|
|
@ -485,9 +488,9 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) {
|
|||
|
||||
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));
|
||||
if (local_payload->mime_type!=NULL) 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 (local_payload->recv_fmtp!=NULL) STR_REASSIGN(report->local_metrics.session_description.fmtp, ms_strdup(local_payload->recv_fmtp));
|
||||
}
|
||||
|
||||
if (remote_payload != NULL) {
|
||||
|
|
@ -694,3 +697,6 @@ void linphone_reporting_destroy(reporting_session_report_t * report) {
|
|||
}
|
||||
|
||||
|
||||
void linphone_reporting_set_on_report_send(LinphoneCall *call, LinphoneQualityReportingReportSendCb cb){
|
||||
call->log->reporting.on_report_sent = cb;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -139,6 +139,9 @@ typedef struct reporting_session_report {
|
|||
time_t last_report_date;
|
||||
} reporting_session_report_t;
|
||||
|
||||
|
||||
typedef void (*LinphoneQualityReportingReportSendCb)(const LinphoneCall *call, int stream_type, const LinphoneContent *content);
|
||||
|
||||
reporting_session_report_t * linphone_reporting_new();
|
||||
void linphone_reporting_destroy(reporting_session_report_t * report);
|
||||
|
||||
|
|
@ -194,6 +197,16 @@ void linphone_reporting_on_rtcp_update(LinphoneCall *call, int stats_type);
|
|||
*/
|
||||
void linphone_reporting_call_state_updated(LinphoneCall *call);
|
||||
|
||||
/**
|
||||
* Setter of the #LinphoneQualityReportingReportSendCb callback method which is
|
||||
* notified each time a report will be submitted to the collector, if quality
|
||||
* reporting is enabled
|
||||
* @param call #LinphoneCall object to consider
|
||||
* @param cb #LinphoneQualityReportingReportSendCb callback function to notify
|
||||
*
|
||||
*/
|
||||
void linphone_reporting_set_on_report_send(LinphoneCall *call, LinphoneQualityReportingReportSendCb cb);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -22,6 +22,93 @@
|
|||
#include "private.h"
|
||||
#include "liblinphone_tester.h"
|
||||
|
||||
/*avoid crash if x is NULL on libc versions <4.5.26 */
|
||||
#define __strstr(x, y) ((x==NULL)?NULL:strstr(x,y))
|
||||
|
||||
void on_report_send_mandatory(const LinphoneCall *call, int stream_type, const LinphoneContent *content){
|
||||
const MediaStream * ms = ((stream_type == LINPHONE_CALL_STATS_AUDIO)?&call->audiostream->ms:&call->videostream->ms);
|
||||
char * body = (char *)content->data;
|
||||
char * remote_metrics_start = __strstr(body, "RemoteMetrics:");
|
||||
reporting_session_report_t * report = call->log->reporting.reports[stream_type];
|
||||
|
||||
CU_ASSERT_TRUE(
|
||||
__strstr(body, "VQIntervalReport\r\n") == body ||
|
||||
__strstr(body, "VQSessionReport\r\n") == body ||
|
||||
__strstr(body, "VQSessionReport: CallTerm\r\n") == body
|
||||
);
|
||||
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "CallID:"));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalID:"));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "RemoteID:"));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "OrigID:"));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalGroup:"));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "RemoteGroup:"));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalAddr:"));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "IP="));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PORT="));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SSRC="));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "RemoteAddr:"));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "IP="));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PORT="));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SSRC="));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalMetrics:"));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "Timestamps:"));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "START="));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "STOP="));
|
||||
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SessionDesc:"));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PT="));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PD="));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SR="));
|
||||
|
||||
/* We should have not reached RemoteMetrics section yet */
|
||||
CU_ASSERT_TRUE(!remote_metrics_start || body < remote_metrics_start);
|
||||
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "DialogID:"));
|
||||
|
||||
if (report->remote_metrics.rtcp_sr_count&&ms->rc!=NULL){
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "AdaptiveAlg:"));
|
||||
}
|
||||
}
|
||||
|
||||
char * on_report_send_verify_metrics(const reporting_content_metrics_t *metrics, char * body){
|
||||
if (metrics->rtcp_xr_count){
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SessionDesc:"));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "JitterBuffer:"));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PacketLoss:"));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "QualityEst:"));
|
||||
}
|
||||
if (metrics->rtcp_sr_count){
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "Delay:"));
|
||||
}
|
||||
|
||||
return body;
|
||||
}
|
||||
|
||||
void on_report_send_with_rtcp_xr_local(const LinphoneCall *call, int stream_type, const LinphoneContent *content){
|
||||
char * body = (char*)content->data;
|
||||
char * remote_metrics_start = __strstr(body, "RemoteMetrics:");
|
||||
reporting_session_report_t * report = call->log->reporting.reports[stream_type];
|
||||
on_report_send_mandatory(call,stream_type,content);
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalMetrics:"));
|
||||
CU_ASSERT_TRUE(!remote_metrics_start || on_report_send_verify_metrics(&report->local_metrics,body) < remote_metrics_start);
|
||||
}
|
||||
void on_report_send_with_rtcp_xr_remote(const LinphoneCall *call, int stream_type, const LinphoneContent *content){
|
||||
char * body = (char*)content->data;
|
||||
reporting_session_report_t * report = call->log->reporting.reports[stream_type];
|
||||
|
||||
on_report_send_mandatory(call,stream_type,content);
|
||||
if (report->remote_metrics.rtcp_sr_count+report->remote_metrics.rtcp_xr_count>0){
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "RemoteMetrics:"));
|
||||
CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "Timestamps:"));
|
||||
on_report_send_verify_metrics(&report->remote_metrics,body);
|
||||
}
|
||||
}
|
||||
void on_report_send_with_rtcp_xr_both(const LinphoneCall *call, int stream_type, const LinphoneContent *content){
|
||||
on_report_send_with_rtcp_xr_local(call,stream_type,content);
|
||||
on_report_send_with_rtcp_xr_remote(call,stream_type,content);
|
||||
}
|
||||
|
||||
void create_call_for_quality_reporting_tests(
|
||||
LinphoneCoreManager* marie,
|
||||
LinphoneCoreManager* pauline,
|
||||
|
|
@ -42,7 +129,7 @@ static void quality_reporting_not_used_without_config() {
|
|||
|
||||
create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline);
|
||||
|
||||
// marie has stats collection enabled since pauline has not
|
||||
// marie has stats collection enabled but pauline has not
|
||||
CU_ASSERT_TRUE(linphone_proxy_config_quality_reporting_enabled(call_marie->dest_proxy));
|
||||
CU_ASSERT_FALSE(linphone_proxy_config_quality_reporting_enabled(call_pauline->dest_proxy));
|
||||
|
||||
|
|
@ -111,11 +198,12 @@ static void quality_reporting_not_sent_if_low_bandwidth() {
|
|||
|
||||
static void quality_reporting_at_call_termination() {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc_rtcp_xr");
|
||||
LinphoneCall* call_marie = NULL;
|
||||
LinphoneCall* call_pauline = NULL;
|
||||
|
||||
create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline);
|
||||
linphone_reporting_set_on_report_send(call_marie, on_report_send_with_rtcp_xr_remote);
|
||||
|
||||
linphone_core_terminate_all_calls(marie->lc);
|
||||
|
||||
|
|
@ -128,7 +216,6 @@ static void quality_reporting_at_call_termination() {
|
|||
CU_ASSERT_PTR_NULL(linphone_core_get_current_call(marie->lc));
|
||||
CU_ASSERT_PTR_NULL(linphone_core_get_current_call(pauline->lc));
|
||||
|
||||
|
||||
// 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));
|
||||
|
|
@ -138,12 +225,13 @@ static void quality_reporting_at_call_termination() {
|
|||
}
|
||||
|
||||
static void quality_reporting_interval_report() {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc_rtcp_xr");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc_rtcp_xr");
|
||||
LinphoneCall* call_marie = NULL;
|
||||
LinphoneCall* call_pauline = NULL;
|
||||
|
||||
create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline);
|
||||
linphone_reporting_set_on_report_send(call_marie, on_report_send_mandatory);
|
||||
linphone_proxy_config_set_quality_reporting_interval(call_marie->dest_proxy, 3);
|
||||
|
||||
CU_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(marie->lc));
|
||||
|
|
@ -158,7 +246,7 @@ static void quality_reporting_interval_report() {
|
|||
}
|
||||
|
||||
static void quality_reporting_session_report_if_video_stopped() {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc_rtcp_xr");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
LinphoneCall* call_pauline = NULL;
|
||||
LinphoneCallParams* pauline_params;
|
||||
|
|
@ -174,6 +262,7 @@ static void quality_reporting_session_report_if_video_stopped() {
|
|||
linphone_call_params_enable_video(pauline_params,TRUE);
|
||||
CU_ASSERT_TRUE(call_with_params(pauline,marie,pauline_params,marie_params));
|
||||
call_pauline=linphone_core_get_current_call(pauline->lc);
|
||||
linphone_reporting_set_on_report_send(linphone_core_get_current_call(marie->lc), on_report_send_with_rtcp_xr_local);
|
||||
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,0);
|
||||
CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0);
|
||||
|
|
|
|||
55
tester/rcfiles/marie_rc_rtcp_xr
Normal file
55
tester/rcfiles/marie_rc_rtcp_xr
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
[sip]
|
||||
sip_port=-1
|
||||
sip_tcp_port=-1
|
||||
sip_tls_port=-1
|
||||
default_proxy=0
|
||||
ping_with_options=0
|
||||
register_only_when_network_is_up=0
|
||||
composing_idle_timeout=1
|
||||
|
||||
[auth_info_0]
|
||||
username=marie
|
||||
userid=marie
|
||||
passwd=secret
|
||||
realm=sip.example.org
|
||||
|
||||
|
||||
[proxy_0]
|
||||
reg_proxy=sip.example.org;transport=tcp
|
||||
reg_route=sip.example.org;transport=tcp;lr
|
||||
reg_identity=sip:marie@sip.example.org
|
||||
reg_expires=3600
|
||||
reg_sendregister=1
|
||||
publish=0
|
||||
dial_escape_plus=0
|
||||
quality_reporting_collector=sip:collector@sip.example.org
|
||||
quality_reporting_enabled=1
|
||||
|
||||
[friend_0]
|
||||
url="Paupoche" <sip:pauline@sip.example.org>
|
||||
pol=accept
|
||||
subscribe=0
|
||||
|
||||
|
||||
[rtp]
|
||||
audio_rtp_port=8070
|
||||
video_rtp_port=9072
|
||||
rtcp_xr_enabled=1
|
||||
rtcp_xr_rcvr_rtt_mode=all
|
||||
rtcp_xr_rcvr_rtt_max_size=10000
|
||||
rtcp_xr_stat_summary_enabled=1
|
||||
rtcp_xr_voip_metrics_enabled=1
|
||||
|
||||
[video]
|
||||
display=0
|
||||
capture=0
|
||||
show_local=0
|
||||
size=vga
|
||||
enabled=0
|
||||
self_view=0
|
||||
automatically_initiate=0
|
||||
automatically_accept=0
|
||||
device=StaticImage: Static picture
|
||||
|
||||
[sound]
|
||||
echocancellation=0 #to not overload cpu in case of VG
|
||||
52
tester/rcfiles/pauline_rc_rtcp_xr
Normal file
52
tester/rcfiles/pauline_rc_rtcp_xr
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
[sip]
|
||||
sip_port=-1
|
||||
sip_tcp_port=-1
|
||||
sip_tls_port=-1
|
||||
default_proxy=0
|
||||
ping_with_options=0
|
||||
register_only_when_network_is_up=0
|
||||
composing_idle_timeout=1
|
||||
|
||||
[auth_info_0]
|
||||
username=pauline
|
||||
userid=pauline
|
||||
passwd=secret
|
||||
realm=sip.example.org
|
||||
|
||||
|
||||
[proxy_0]
|
||||
reg_proxy=sip2.linphone.org;transport=tls
|
||||
reg_route=sip2.linphone.org;transport=tls
|
||||
reg_identity=sip:pauline@sip.example.org
|
||||
reg_expires=3600
|
||||
reg_sendregister=1
|
||||
publish=0
|
||||
dial_escape_plus=0
|
||||
|
||||
#[friend_0]
|
||||
#url="Mariette" <sip:marie@sip.example.org>
|
||||
#pol=accept
|
||||
#subscribe=0
|
||||
|
||||
[rtp]
|
||||
audio_rtp_port=8090
|
||||
video_rtp_port=9092
|
||||
rtcp_xr_enabled=1
|
||||
rtcp_xr_rcvr_rtt_mode=all
|
||||
rtcp_xr_rcvr_rtt_max_size=10000
|
||||
rtcp_xr_stat_summary_enabled=1
|
||||
rtcp_xr_voip_metrics_enabled=1
|
||||
|
||||
[video]
|
||||
display=0
|
||||
capture=0
|
||||
show_local=0
|
||||
size=vga
|
||||
enabled=0
|
||||
self_view=0
|
||||
automatically_initiate=0
|
||||
automatically_accept=0
|
||||
device=StaticImage: Static picture
|
||||
|
||||
[sound]
|
||||
echocancellation=0 #to not overload cpu in case of VG
|
||||
Loading…
Add table
Reference in a new issue