diff --git a/coreapi/event.c b/coreapi/event.c index ac2a8db3d..836b929a7 100644 --- a/coreapi/event.c +++ b/coreapi/event.c @@ -120,7 +120,7 @@ void linphone_event_set_publish_state(LinphoneEvent *lev, LinphonePublishState s /*nothing special to do*/ break; } - + } } @@ -153,7 +153,7 @@ LinphoneEvent *linphone_core_subscribe(LinphoneCore *lc, const LinphoneAddress * int linphone_event_send_subscribe(LinphoneEvent *lev, const LinphoneContent *body){ SalBody salbody; int err; - + if (lev->dir!=LinphoneSubscriptionOutgoing){ ms_error("linphone_event_send_subscribe(): cannot send or update something that is not an outgoing subscription."); return -1; @@ -173,12 +173,12 @@ int linphone_event_send_subscribe(LinphoneEvent *lev, const LinphoneContent *bod /*those states are ok*/ break; } - + if (lev->send_custom_headers){ sal_op_set_sent_custom_header(lev->op,lev->send_custom_headers); lev->send_custom_headers=NULL; }else sal_op_set_sent_custom_header(lev->op,NULL); - + err=sal_subscribe(lev->op,NULL,NULL,lev->name,lev->expires,sal_body_from_content(&salbody,body)); if (err==0){ if (lev->subscription_state==LinphoneSubscriptionNone) @@ -238,7 +238,7 @@ LinphoneEvent *linphone_core_create_publish(LinphoneCore *lc, const LinphoneAddr static int _linphone_event_send_publish(LinphoneEvent *lev, const LinphoneContent *body, bool_t notify_err){ SalBody salbody; int err; - + if (lev->dir!=LinphoneSubscriptionInvalidDir){ ms_error("linphone_event_update_publish(): this is not a PUBLISH event."); return -1; @@ -276,7 +276,6 @@ int linphone_event_update_publish(LinphoneEvent* lev, const LinphoneContent* bod return linphone_event_send_publish(lev,body); } - void linphone_event_set_user_data(LinphoneEvent *ev, void *up){ ev->userdata=up; } @@ -302,7 +301,7 @@ void linphone_event_terminate(LinphoneEvent *lev){ }else if (lev->dir==LinphoneSubscriptionOutgoing){ sal_unsubscribe(lev->op); } - + if (lev->publish_state!=LinphonePublishNone){ if (lev->publish_state==LinphonePublishOk && lev->expires!=-1){ sal_publish(lev->op,NULL,NULL,NULL,0,NULL); @@ -310,7 +309,7 @@ void linphone_event_terminate(LinphoneEvent *lev){ linphone_event_set_publish_state(lev,LinphonePublishCleared); return; } - + if (lev->subscription_state!=LinphoneSubscriptionNone){ linphone_event_set_state(lev,LinphoneSubscriptionTerminated); return; diff --git a/coreapi/proxy.c b/coreapi/proxy.c index b644db353..d0dc792f6 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -550,8 +550,7 @@ void linphone_proxy_config_enable_quality_reporting(LinphoneProxyConfig *cfg, bo } bool_t linphone_proxy_config_quality_reporting_enabled(LinphoneProxyConfig *cfg){ - // ensure that collector address is set too! - return cfg->quality_reporting_enabled && cfg->quality_reporting_collector != NULL; + return cfg->quality_reporting_enabled; } void linphone_proxy_config_set_quality_reporting_interval(LinphoneProxyConfig *cfg, uint8_t interval) { diff --git a/coreapi/quality_reporting.c b/coreapi/quality_reporting.c index 0147f9a08..b476aca93 100644 --- a/coreapi/quality_reporting.c +++ b/coreapi/quality_reporting.c @@ -266,6 +266,7 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report, LinphoneEvent *lev; LinphoneAddress *request_uri; char * domain; + const char* route; /*if we are on a low bandwidth network, do not send reports to not overload it*/ if (linphone_call_params_low_bandwidth_enabled(linphone_call_get_current_params(call))){ @@ -336,15 +337,17 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report, } + route = linphone_proxy_config_get_quality_reporting_collector(call->dest_proxy); domain = ms_strdup_printf("sip:%s", linphone_proxy_config_get_domain(call->dest_proxy)); - request_uri = linphone_address_new(domain); + request_uri = linphone_address_new(route ? route : domain); ms_free(domain); lev=linphone_core_create_publish(call->core, request_uri, "vq-rtcpxr", expires); - if (linphone_proxy_config_get_quality_reporting_collector(call->dest_proxy) != NULL) { - sal_op_set_route(lev->op, linphone_proxy_config_get_quality_reporting_collector(call->dest_proxy)); + if (route) { + ms_message("Publishing report with custom route %s", route); + sal_op_set_route(lev->op, route); } - if (! linphone_event_send_publish(lev, content)){ + if (linphone_event_send_publish(lev, content) != 0){ linphone_event_unref(lev); lev=NULL; ret=4; diff --git a/tester/flexisip/flexisip.conf b/tester/flexisip/flexisip.conf index d3c699cf9..96e70b90a 100644 --- a/tester/flexisip/flexisip.conf +++ b/tester/flexisip/flexisip.conf @@ -38,7 +38,7 @@ aliases=localhost sip2.linphone.org sipopen.example.org sip.example.org auth.exa # Default value: sip:* #transports=sip:192.168.56.101:5060 sips:192.168.56.101:5061 -#note: the ip addresses are explicitely specified here because the machine has several interfaces. In a simple case, using '*' instead of the explicit ip address is sufficient, +#note: the ip addresses are explicitely specified here because the machine has several interfaces. In a simple case, using '*' instead of the explicit ip address is sufficient, #and there is no need to specify the ipv6 transport addresses. transports=sip:94.23.19.176:5060 sips:94.23.19.176:5061;tls-certificates-dir=/etc/flexisip/tls/certificates/cn sips:94.23.19.176:5062;tls-certificates-dir=/etc/flexisip/tls/certificates/altname sips:94.23.19.176:5063;require-peer-certificate=1 sip:94.23.19.176:5064 sip:[2001:41d0:2:14b0::1]:5060 sips:[2001:41d0:2:14b0::1]:5061;tls-certificates-dir=/etc/flexisip/tls/certificates/cn sips:[2001:41d0:2:14b0::1]:5062;tls-certificates-dir=/etc/flexisip/tls/certificates/altname sips:[2001:41d0:2:14b0::1]:5063;require-peer-certificate=1 sip:[2001:41d0:2:14b0::1]:5064 @@ -83,7 +83,7 @@ enabled=true # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (user-agent == 'Linphone v2') -# Default value: +# Default value: filter= # Internal URI parameter added to response contact by first proxy @@ -107,19 +107,19 @@ no-403=user-agent contains 'tester-no-403' # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (user-agent == 'Linphone v2') -# Default value: -filter= from.uri.domain contains 'sip.example.org' || from.uri.domain contains 'auth.example.org' || from.uri.domain contains 'auth1.example.org' || from.uri.domain contains 'auth2.example.org' || from.uri.domain contains 'anonymous.invalid' +# Default value: +filter= from.uri.domain contains 'sip.example.org' || from.uri.domain contains 'auth.example.org' || from.uri.domain contains 'auth1.example.org' || from.uri.domain contains 'auth2.example.org' || from.uri.domain contains 'anonymous.invalid' # List of whitespace separated domain names to challenge. Others # are denied. -# Default value: +# Default value: auth-domains= sip.example.org auth.example.org auth1.example.org auth2.example.org client-certificates-domains=client.example.org # List of whitespace separated IP which will not be challenged. -# Default value: +# Default value: trusted-hosts= # Database backend implementation [odbc, file]. @@ -130,10 +130,10 @@ db-implementation=file # DSN=myodbc3; where 'myodbc3' is the datasource name. ex2: DRIVER={MySQL};SERVER=host;DATABASE=db;USER=user;PASSWORD=pass;OPTION=3; # for a DSN-less connection. ex3: /etc/flexisip/passwd; for a file # containing one 'user@domain password' by line. -# Default value: +# Default value: datasource=/etc/flexisip/userdb.conf -# Odbc SQL request to execute to obtain the password +# Odbc SQL request to execute to obtain the password # . Named parameters are :id (the user found in the from header), # :domain (the authorization realm) and :authid (the authorization # username). The use of the :id parameter is mandatory. @@ -176,15 +176,15 @@ enabled=false # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (user-agent == 'Linphone v2') -# Default value: +# Default value: filter= # A gateway uri where to send all requests, as a SIP url (eg 'sip:gateway.example.net') -# Default value: +# Default value: gateway= # Modify the from and to domains of incoming register -# Default value: +# Default value: gateway-domain= # The gateway will be added to the incoming register contacts. @@ -246,7 +246,7 @@ enabled=true # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (user-agent == 'Linphone v2') -# Default value: +# Default value: filter= # List of whitelist separated domain names to be managed by the @@ -259,7 +259,7 @@ reg-domains=localhost sip.example.org sipopen.example.org auth1.example.org sip2 max-contacts-by-aor=15 # List of contact uri parameters that can be used to identify a -# user's device. +# user's device. # Default value: +sip.instance #unique-id-parameters= @@ -274,7 +274,7 @@ min-expires=1 # File containing the static records to add to database at startup. # Format: one 'sip_uri contact_header' by line. Example: # , -# Default value: +# Default value: static-records-file= # Timeout in seconds after which the static records file is re-read @@ -296,12 +296,12 @@ db-implementation=internal # Generate a contact from the TO header and route it to the above # destination. [sip:host:port] -# Default value: +# Default value: generated-contact-route= # Require presence of authorization header for specified realm. # [Realm] -# Default value: +# Default value: generated-contact-expected-realm= @@ -314,7 +314,7 @@ enabled=false # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (user-agent == 'Linphone v2') -# Default value: +# Default value: filter= # Hack for workarounding Nortel CS2k gateways bug. @@ -334,12 +334,12 @@ enabled=false # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (user-agent == 'Linphone v2') -# Default value: +# Default value: filter= # Whitespace separated list of sip routes to balance the requests. # Example: -# Default value: +# Default value: routes= ## @@ -358,7 +358,7 @@ enabled=true # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (:q -# Default value: +# Default value: filter= (user-agent contains 'Natted Linphone') # SDP attribute set by the first proxy to forbid subsequent proxies @@ -417,7 +417,7 @@ enabled=false # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (user-agent == 'Linphone v2') -# Default value: +# Default value: filter= # Nominal size of RTP jitter buffer, in milliseconds. A value of @@ -427,7 +427,7 @@ jb-nom-size=0 # Whitespace separated list of user-agent strings for which audio # rate control is performed. -# Default value: +# Default value: rc-user-agents= # Whitespace seprated list of audio codecs, in order of preference. @@ -453,11 +453,11 @@ enabled=true # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (user-agent == 'Linphone v2') -# Default value: +# Default value: filter= # A sip uri where to send all requests -# Default value: +# Default value: route= # Rewrite request-uri's host and port according to above route @@ -489,7 +489,7 @@ filter= # to this address will be deleted by this module and thus not be # delivered. # Default value: -collector-address=sip:collector@sip.example.org +collector-address=sip:sip.example.org ## ## This module performs push notifications to mobile phone notification @@ -512,7 +512,7 @@ enabled=true # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (user-agent == 'Linphone v2') -# Default value: +# Default value: filter= # Number of second to wait before sending a push notification to @@ -542,7 +542,7 @@ google=false # List of couples projectId:ApiKey for each android project that # supports push notifications -# Default value: +# Default value: google-projects-api-keys= # Enable push notification for windows phone 8 devices @@ -563,17 +563,17 @@ no-badge=false # - $event : call, message # - $from-name : the display name in the from header # - $from-uri : the sip uri of the from header -# - $from-tag : the tag of the from header +# - $from-tag : the tag of the from header # - $call-id : the call-id of the INVITE or MESSAGE request # - $to-uri : the sip uri of the to header # - $api-key : the api key to use (google only) # - $msgid : the message id to put in the notification # - $sound : the sound file to play with the notification -# +# The content of the text message is put in the body of the http # request as text/plain, if any. # Example: http://192.168.0.2/$type/$event?from-uri=$from-uri&tag=$from-tag&callid=$callid&to=$to-uri -# Default value: +# Default value: external-push-uri=http://127.0.0.1:80/$type/$event?from-uri=$from-uri&tag=$from-tag&callid=$callid&to=$to-uri # Method for reaching external-push-uri, typically GET or POST @@ -596,7 +596,7 @@ enabled=true # to true. Ex: from.uri.domain contains 'sip.linphone.org', from.uri.domain # in 'a.org b.org c.org', (to.uri.domain in 'a.org b.org c.org') # && (user-agent == 'Linphone v2') -# Default value: +# Default value: filter= # Number of milliseconds to consider to compute the packet rate diff --git a/tester/quality_reporting_tester.c b/tester/quality_reporting_tester.c index 9fce7be2b..81040e438 100644 --- a/tester/quality_reporting_tester.c +++ b/tester/quality_reporting_tester.c @@ -335,6 +335,54 @@ static void quality_reporting_session_report_if_video_stopped() { linphone_core_manager_destroy(pauline); } +void publish_report_with_route_state_changed(LinphoneCore *lc, LinphoneEvent *ev, LinphonePublishState state){ + stats* counters = get_stats(lc); + const LinphoneAddress* from_addr = linphone_event_get_from(ev); + char* from = linphone_address_as_string(from_addr); + ms_message("Publish state [%s] from [%s]",linphone_publish_state_to_string(state),from); + ms_free(from); + switch(state){ + case LinphonePublishProgress: + BC_ASSERT_STRING_EQUAL(linphone_address_as_string(linphone_event_get_resource(ev)), linphone_proxy_config_get_quality_reporting_collector(linphone_core_get_default_proxy_config(lc))); + counters->number_of_LinphonePublishProgress++; + break; + case LinphonePublishOk: + counters->number_of_LinphonePublishOk++; + break; + case LinphonePublishError: counters->number_of_LinphonePublishError++; break; + case LinphonePublishExpiring: counters->number_of_LinphonePublishExpiring++; break; + case LinphonePublishCleared: counters->number_of_LinphonePublishCleared++;break; + default: + break; + } + +} + +static void quality_reporting_sent_using_custom_route() { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_quality_reporting_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + LinphoneCall* call_marie = NULL; + LinphoneCall* call_pauline = NULL; + + marie->lc->current_vtable->publish_state_changed = publish_report_with_route_state_changed; + //INVALID collector: sip.linphone.org do not collect reports, so it will throw a 404 Not Found error + linphone_proxy_config_set_quality_reporting_collector(linphone_core_get_default_proxy_config(marie->lc), "sip:sip.linphone.org"); + + if (create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline, NULL, NULL)) { + linphone_core_terminate_all_calls(marie->lc); + BC_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallReleased,1, 10000)); + BC_ASSERT_TRUE(wait_for_until(pauline->lc,NULL,&pauline->stat.number_of_LinphoneCallReleased,1, 10000)); + + // PUBLISH submission to the collector should be ERROR since route is not valid + BC_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishProgress,1)); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,1, int, "%d"); + BC_ASSERT_TRUE(wait_for_until(marie->lc,NULL,&marie->stat.number_of_LinphonePublishError,1,10000)); + BC_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0,int, "%d"); + } + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + test_t quality_reporting_tests[] = { { "Not used if no config", quality_reporting_not_used_without_config}, { "Call term session report not sent if call did not start", quality_reporting_not_sent_if_call_not_started}, @@ -343,6 +391,7 @@ test_t quality_reporting_tests[] = { { "Call term session report sent if call ended normally", quality_reporting_at_call_termination}, { "Interval report if interval is configured", quality_reporting_interval_report}, { "Session report sent if video stopped during call", quality_reporting_session_report_if_video_stopped}, + { "Sent using custom route", quality_reporting_sent_using_custom_route}, }; test_suite_t quality_reporting_test_suite = { diff --git a/tester/rcfiles/marie_quality_reporting_rc b/tester/rcfiles/marie_quality_reporting_rc index 78068923c..10cacfc7d 100644 --- a/tester/rcfiles/marie_quality_reporting_rc +++ b/tester/rcfiles/marie_quality_reporting_rc @@ -22,7 +22,6 @@ 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] diff --git a/tester/rcfiles/marie_rc_rtcp_xr b/tester/rcfiles/marie_rc_rtcp_xr index 06f0b5b63..801ef0ebd 100644 --- a/tester/rcfiles/marie_rc_rtcp_xr +++ b/tester/rcfiles/marie_rc_rtcp_xr @@ -22,7 +22,6 @@ 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]