From 34cce12c239a468ef675a8f83c3e6bb5f49d72e8 Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Wed, 18 Jun 2014 14:32:14 +0200 Subject: [PATCH 01/16] Quality reporting: quote adaptive algo data and add unit test for bad formatted reports --- coreapi/quality_reporting.c | 14 +++++++------- tester/quality_reporting_tester.c | 26 ++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 7 deletions(-) diff --git a/coreapi/quality_reporting.c b/coreapi/quality_reporting.c index dc36f7a25..e16dd8f81 100644 --- a/coreapi/quality_reporting.c +++ b/coreapi/quality_reporting.c @@ -313,12 +313,12 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report, if (report->qos_analyzer.timestamp!=NULL){ append_to_buffer(&buffer, &size, &offset, "AdaptiveAlg:"); - APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " NAME=%s", report->qos_analyzer.name); - APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " TS=%s", report->qos_analyzer.timestamp); - APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " IN_LEG=%s", report->qos_analyzer.input_leg); - APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " IN=%s", report->qos_analyzer.input); - APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " OUT_LEG=%s", report->qos_analyzer.output_leg); - APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " OUT=%s", report->qos_analyzer.output); + APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " NAME=\"%s\"", report->qos_analyzer.name); + APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " TS=\"%s\"", report->qos_analyzer.timestamp); + APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " IN_LEG=\"%s\"", report->qos_analyzer.input_leg); + APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " IN=\"%s\"", report->qos_analyzer.input); + APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " OUT_LEG=\"%s\"", report->qos_analyzer.output_leg); + APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, " OUT=\"%s\"", report->qos_analyzer.output); append_to_buffer(&buffer, &size, &offset, "\r\n"); } @@ -641,11 +641,11 @@ reporting_session_report_t * linphone_reporting_new() { metrics[i]->session_description.payload_type = -1; metrics[i]->session_description.sample_rate = -1; metrics[i]->session_description.frame_duration = -1; + metrics[i]->session_description.packet_loss_concealment = -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.abs_max = -1; diff --git a/tester/quality_reporting_tester.c b/tester/quality_reporting_tester.c index 438f1ba46..b6b449b91 100644 --- a/tester/quality_reporting_tester.c +++ b/tester/quality_reporting_tester.c @@ -200,6 +200,31 @@ static void quality_reporting_not_sent_if_low_bandwidth() { linphone_core_manager_destroy(pauline); } +void on_report_send_remove_fields(const LinphoneCall *call, int stream_type, const LinphoneContent *content){ + char *body = (char*)content->data; + /*corrupt start of the report*/ + strncpy(body, "corrupted report is corrupted", strlen("corrupted report is corrupted")); +} + +static void quality_reporting_invalid_report() { + 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_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline); + linphone_reporting_set_on_report_send(call_marie, on_report_send_remove_fields); + + linphone_core_terminate_all_calls(marie->lc); + + CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,1)); + CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishError,1,3000)); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + static void quality_reporting_at_call_termination() { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc_rtcp_xr"); @@ -296,6 +321,7 @@ 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}, { "Call term session report not sent if low bandwidth", quality_reporting_not_sent_if_low_bandwidth}, + { "Call term session report invalid if missing mandatory fields", quality_reporting_invalid_report}, { "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}, From e8bd526f74b235d20bff1d4bf774a6a744c2746e Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 18 Jun 2014 15:46:51 +0200 Subject: [PATCH 02/16] Update ms2 submodule for speexec fix. --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index df42f0d73..d09fd38aa 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit df42f0d73d930079c43ef92808529a4716e72d99 +Subproject commit d09fd38aa00d38a99eb9470c0f9e117027f4dc50 From 94105aaa1f5cfb43badc5b8fa5f520d1e87bb5ba Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Thu, 19 Jun 2014 09:55:19 +0200 Subject: [PATCH 03/16] Handle AVPF RR interval in milliseconds + fix negotiation of rtcp-fb trr-int parameter. --- coreapi/bellesip_sal/sal_sdp.c | 9 ++++----- coreapi/linphonecall.c | 37 ++++++++++++++++++++++++---------- coreapi/linphonecore.c | 9 ++------- coreapi/offeranswer.c | 6 +++++- coreapi/private.h | 3 ++- mediastreamer2 | 2 +- oRTP | 2 +- 7 files changed, 41 insertions(+), 27 deletions(-) diff --git a/coreapi/bellesip_sal/sal_sdp.c b/coreapi/bellesip_sal/sal_sdp.c index 90f38af19..5f71dba0e 100644 --- a/coreapi/bellesip_sal/sal_sdp.c +++ b/coreapi/bellesip_sal/sal_sdp.c @@ -68,7 +68,7 @@ static void add_ice_remote_candidates(belle_sdp_media_description_t *md, const S if (buffer[0] != '\0') belle_sdp_media_description_add_attribute(md,belle_sdp_attribute_create("remote-candidates",buffer)); } -static bool_t is_rtcp_fb_trr_int_the_same_for_all_payloads(const SalStreamDescription *stream, uint8_t *trr_int) { +static bool_t is_rtcp_fb_trr_int_the_same_for_all_payloads(const SalStreamDescription *stream, uint16_t *trr_int) { MSList *pt_it; bool_t first = TRUE; for (pt_it = stream->payloads; pt_it != NULL; pt_it = pt_it->next) { @@ -85,7 +85,7 @@ static bool_t is_rtcp_fb_trr_int_the_same_for_all_payloads(const SalStreamDescri return TRUE; } -static void add_rtcp_fb_trr_int_attribute(belle_sdp_media_description_t *media_desc, int8_t id, uint8_t trr_int) { +static void add_rtcp_fb_trr_int_attribute(belle_sdp_media_description_t *media_desc, int8_t id, uint16_t trr_int) { belle_sdp_rtcp_fb_attribute_t *attribute = belle_sdp_rtcp_fb_attribute_new(); belle_sdp_rtcp_fb_attribute_set_id(attribute, id); belle_sdp_rtcp_fb_attribute_set_type(attribute, BELLE_SDP_RTCP_FB_TRR_INT); @@ -106,7 +106,7 @@ static void add_rtcp_fb_attributes(belle_sdp_media_description_t *media_desc, co PayloadType *pt; PayloadTypeAvpfParams avpf_params; bool_t general_trr_int; - uint8_t trr_int = 0; + uint16_t trr_int = 0; general_trr_int = is_rtcp_fb_trr_int_the_same_for_all_payloads(stream, &trr_int); if (general_trr_int == TRUE) { @@ -485,7 +485,6 @@ static void enable_avpf_for_stream(SalStreamDescription *stream) { if (stream->type == SalVideo) { avpf_params.features |= PAYLOAD_TYPE_AVPF_FIR; } - avpf_params.trr_interval = 0; payload_type_set_avpf_params(pt, avpf_params); } } @@ -509,7 +508,7 @@ static void apply_rtcp_fb_attribute_to_payload(belle_sdp_rtcp_fb_attribute_t *fb } break; case BELLE_SDP_RTCP_FB_TRR_INT: - avpf_params.trr_interval = (unsigned char)belle_sdp_rtcp_fb_attribute_get_trr_int(fb_attribute); + avpf_params.trr_interval = belle_sdp_rtcp_fb_attribute_get_trr_int(fb_attribute); break; case BELLE_SDP_RTCP_FB_ACK: default: diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 2a98afef1..218bf86fd 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -132,9 +132,9 @@ static bool_t linphone_call_all_streams_avpf_enabled(const LinphoneCall *call) { return ((nb_active_streams > 0) && (nb_active_streams == nb_avpf_enabled_streams)); } -static uint8_t linphone_call_get_avpf_rr_interval(const LinphoneCall *call) { - uint8_t rr_interval = 0; - uint8_t stream_rr_interval; +static uint16_t linphone_call_get_avpf_rr_interval(const LinphoneCall *call) { + uint16_t rr_interval = 0; + uint16_t stream_rr_interval; if (call) { if (call->audiostream && media_stream_get_state((MediaStream *)call->audiostream) == MSStreamStarted) { stream_rr_interval = media_stream_get_avpf_rr_interval((MediaStream *)call->audiostream); @@ -145,7 +145,7 @@ static uint8_t linphone_call_get_avpf_rr_interval(const LinphoneCall *call) { if (stream_rr_interval > rr_interval) rr_interval = stream_rr_interval; } } else { - rr_interval = 5; + rr_interval = 5000; } return rr_interval; } @@ -682,6 +682,26 @@ static void linphone_call_incoming_select_ip_version(LinphoneCall *call){ }else call->af=AF_INET; } +/** + * Fix call parameters on incoming call to eg. enable AVPF if the incoming call propose it and it is not enabled locally. + */ +void linphone_call_set_compatible_incoming_call_parameters(LinphoneCall *call, const SalMediaDescription *md) { + call->params.has_video &= linphone_core_media_description_contains_video_stream(md); + + /* Handle AVPF and SRTP. */ + call->params.avpf_enabled = sal_media_description_has_avpf(md); + if (call->params.avpf_enabled == TRUE) { + if (call->dest_proxy != NULL) { + call->params.avpf_rr_interval = linphone_proxy_config_get_avpf_rr_interval(call->dest_proxy) * 1000; + } else { + call->params.avpf_rr_interval = 5000; + } + } + if ((sal_media_description_has_srtp(md) == TRUE) && (media_stream_srtp_supported() == TRUE)) { + call->params.media_encryption = LinphoneMediaEncryptionSRTP; + } +} + LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, SalOp *op){ LinphoneCall *call=ms_new0(LinphoneCall,1); char *from_str; @@ -716,6 +736,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro linphone_core_get_local_ip(lc,call->af,call->localip); linphone_call_init_common(call, from, to); call->log->call_id=ms_strdup(sal_op_get_call_id(op)); /*must be known at that time*/ + call->dest_proxy = linphone_core_lookup_known_proxy(call->core, to); linphone_core_init_default_params(lc, &call->params); /* @@ -730,13 +751,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro if (md) { // It is licit to receive an INVITE without SDP // In this case WE chose the media parameters according to policy. - call->params.has_video &= linphone_core_media_description_contains_video_stream(md); - - /* Handle AVPF and SRTP. */ - call->params.avpf_enabled = sal_media_description_has_avpf(md); - if ((sal_media_description_has_srtp(md) == TRUE) && (media_stream_srtp_supported() == TRUE)) { - call->params.media_encryption = LinphoneMediaEncryptionSRTP; - } + linphone_call_set_compatible_incoming_call_parameters(call, md); } fpol=linphone_core_get_firewall_policy(call->core); /*create the ice session now if ICE is required*/ diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 452447232..9f4cfbd9c 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2845,7 +2845,7 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const if (proxy!=NULL) { from=linphone_proxy_config_get_identity(proxy); cp->avpf_enabled = linphone_proxy_config_avpf_enabled(proxy); - cp->avpf_rr_interval = linphone_proxy_config_get_avpf_rr_interval(proxy); + cp->avpf_rr_interval = linphone_proxy_config_get_avpf_rr_interval(proxy) * 1000; } /* if no proxy or no identity defined for this proxy, default to primary contact*/ @@ -3428,12 +3428,7 @@ int linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call, // There might not be a md if the INVITE was lacking an SDP // In this case we use the parameters as is. if (md) { - call->params.has_video &= linphone_core_media_description_contains_video_stream(md); - /* Handle AVPF and SRTP. */ - call->params.avpf_enabled = sal_media_description_has_avpf(md); - if ((sal_media_description_has_srtp(md) == TRUE) && (media_stream_srtp_supported() == TRUE)) { - call->params.media_encryption = LinphoneMediaEncryptionSRTP; - } + linphone_call_set_compatible_incoming_call_parameters(call, md); } linphone_call_prepare_ice(call,TRUE); linphone_call_make_local_media_description(lc,call); diff --git a/coreapi/offeranswer.c b/coreapi/offeranswer.c index 779e7ae65..d7d2e6e84 100644 --- a/coreapi/offeranswer.c +++ b/coreapi/offeranswer.c @@ -101,7 +101,11 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t newp->flags|=PAYLOAD_TYPE_FLAG_CAN_RECV|PAYLOAD_TYPE_FLAG_CAN_SEND; if (p2->flags & PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED) { newp->flags |= PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED; - newp->avpf = payload_type_get_avpf_params(p2); + newp->avpf = payload_type_get_avpf_params(p2); /* Take remote AVPF features */ + /* Take bigger AVPF trr interval */ + if (p2->avpf.trr_interval < matched->avpf.trr_interval) { + newp->avpf.trr_interval = matched->avpf.trr_interval; + } } res=ms_list_append(res,newp); /* we should use the remote numbering even when parsing a response */ diff --git a/coreapi/private.h b/coreapi/private.h index b59ccd906..9cb1b45da 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -100,7 +100,7 @@ struct _LinphoneCallParams{ bool_t in_conference; /*in conference mode */ bool_t low_bandwidth; LinphonePrivacyMask privacy; - uint8_t avpf_rr_interval; + uint16_t avpf_rr_interval; }; struct _LinphoneQualityReporting{ @@ -255,6 +255,7 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr LinphoneCall * linphone_call_new_incoming(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, SalOp *op); void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const char *message); void linphone_call_set_contact_op(LinphoneCall* call); +void linphone_call_set_compatible_incoming_call_parameters(LinphoneCall *call, const SalMediaDescription *md); /* private: */ LinphoneCallLog * linphone_call_log_new(LinphoneCall *call, LinphoneAddress *local, LinphoneAddress * remote); void linphone_call_log_completed(LinphoneCall *call); diff --git a/mediastreamer2 b/mediastreamer2 index d09fd38aa..e4ee08232 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit d09fd38aa00d38a99eb9470c0f9e117027f4dc50 +Subproject commit e4ee08232c70023bf772b6499752bd682671b99c diff --git a/oRTP b/oRTP index 8d9a4ac29..e4a235076 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 8d9a4ac29b80f6dbb16ef6ca9ed68727a0c7d759 +Subproject commit e4a235076787acef6e97eb7a15b400f91fd4f481 From 0e3039d5072ae374590c3cb36c740550303dc462 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 23 Jun 2014 12:08:28 +0200 Subject: [PATCH 04/16] Update ms2 submodule. --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index e4ee08232..999768a69 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit e4ee08232c70023bf772b6499752bd682671b99c +Subproject commit 999768a69bd0b6ead9de0930c6d6ebd4a020ffcf From 136d8379fe708a2cc9e7248556e5c3a296078c49 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 23 Jun 2014 15:31:16 +0200 Subject: [PATCH 05/16] Fix compilation for Windows Phone 8. --- build/vsx/LibLinphone/LibLinphone.vcxproj | 33 ++++++++++------------- coreapi/chat.c | 18 +++++++------ coreapi/private.h | 10 +++---- mediastreamer2 | 2 +- oRTP | 2 +- 5 files changed, 31 insertions(+), 34 deletions(-) diff --git a/build/vsx/LibLinphone/LibLinphone.vcxproj b/build/vsx/LibLinphone/LibLinphone.vcxproj index bc1f56695..814314f15 100644 --- a/build/vsx/LibLinphone/LibLinphone.vcxproj +++ b/build/vsx/LibLinphone/LibLinphone.vcxproj @@ -66,7 +66,7 @@ Level4 - $(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\..\oRTP\include;$(ProjectDir)..\..\..\..\mediastreamer2\include;$(ProjectDIr)..\..\..\..\tunnel\include;$(ProjectDir)..\..\..\coreapi;$(ProjectDir)..\..\..\include;$(SolutionDir)$(Platform)\$(Configuration)\include;%(AdditionalIncludeDirectories) + $(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\..\linphone\oRTP\include;$(ProjectDir)..\..\..\..\linphone\mediastreamer2\include;$(ProjectDIr)..\..\..\..\tunnel\include;$(ProjectDir)..\..\..\coreapi;$(ProjectDir)..\..\..\include;$(SolutionDir)$(Platform)\$(Configuration)\include;%(AdditionalIncludeDirectories) __STDC_CONSTANT_MACROS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;_USRDLL;WINDOW_NATIVE;_TRUE_TIME;IN_LINPHONE;USE_BELLESIP;TUNNEL_ENABLED;VIDEO_ENABLED;LINPHONE_PACKAGE_NAME="linphone";LINPHONE_VERSION="Devel";LIBLINPHONE_EXPORTS;LINPHONE_PLUGINS_DIR="";UNICODE;%(PreprocessorDefinitions) false Default @@ -90,7 +90,7 @@ Level4 - $(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\..\oRTP\include;$(ProjectDir)..\..\..\..\mediastreamer2\include;$(ProjectDIr)..\..\..\..\tunnel\include;$(ProjectDir)..\..\..\coreapi;$(ProjectDir)..\..\..\include;$(SolutionDir)$(Platform)\$(Configuration)\include;%(AdditionalIncludeDirectories) + $(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\..\linphone\oRTP\include;$(ProjectDir)..\..\..\..\linphone\mediastreamer2\include;$(ProjectDIr)..\..\..\..\tunnel\include;$(ProjectDir)..\..\..\coreapi;$(ProjectDir)..\..\..\include;$(SolutionDir)$(Platform)\$(Configuration)\include;%(AdditionalIncludeDirectories) __STDC_CONSTANT_MACROS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;WINDOW_NATIVE;_TRUE_TIME;IN_LINPHONE;USE_BELLESIP;TUNNEL_ENABLED;VIDEO_ENABLED;LINPHONE_PACKAGE_NAME="linphone";LINPHONE_VERSION="Devel";LIBLINPHONE_EXPORTS;LINPHONE_PLUGINS_DIR="";UNICODE;%(PreprocessorDefinitions) true true @@ -116,7 +116,7 @@ Level4 - $(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\..\oRTP\include;$(ProjectDir)..\..\..\..\mediastreamer2\include;$(ProjectDIr)..\..\..\..\tunnel\include;$(ProjectDir)..\..\..\coreapi;$(ProjectDir)..\..\..\include;$(SolutionDir)$(Platform)\$(Configuration)\include;%(AdditionalIncludeDirectories) + $(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\..\linphone\oRTP\include;$(ProjectDir)..\..\..\..\linphone\mediastreamer2\include;$(ProjectDIr)..\..\..\..\tunnel\include;$(ProjectDir)..\..\..\coreapi;$(ProjectDir)..\..\..\include;$(SolutionDir)$(Platform)\$(Configuration)\include;%(AdditionalIncludeDirectories) __STDC_CONSTANT_MACROS;_CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;_USRDLL;WINDOW_NATIVE;_TRUE_TIME;IN_LINPHONE;USE_BELLESIP;TUNNEL_ENABLED;VIDEO_ENABLED;LINPHONE_PACKAGE_NAME="linphone";LINPHONE_VERSION="Devel";LIBLINPHONE_EXPORTS;LINPHONE_PLUGINS_DIR="";UNICODE;_XKEYCHECK_H;%(PreprocessorDefinitions) false Default @@ -146,7 +146,7 @@ Level4 - $(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\..\oRTP\include;$(ProjectDir)..\..\..\..\mediastreamer2\include;$(ProjectDIr)..\..\..\..\tunnel\include;$(ProjectDir)..\..\..\coreapi;$(ProjectDir)..\..\..\include;$(SolutionDir)$(Platform)\$(Configuration)\include;%(AdditionalIncludeDirectories) + $(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\..\linphone\oRTP\include;$(ProjectDir)..\..\..\..\linphone\mediastreamer2\include;$(ProjectDIr)..\..\..\..\tunnel\include;$(ProjectDir)..\..\..\coreapi;$(ProjectDir)..\..\..\include;$(SolutionDir)$(Platform)\$(Configuration)\include;%(AdditionalIncludeDirectories) __STDC_CONSTANT_MACROS;_CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;WINDOW_NATIVE;_TRUE_TIME;IN_LINPHONE;USE_BELLESIP;TUNNEL_ENABLED;VIDEO_ENABLED;LINPHONE_PACKAGE_NAME="linphone";LINPHONE_VERSION="Devel";LIBLINPHONE_EXPORTS;LINPHONE_PLUGINS_DIR="";UNICODE;_XKEYCHECK_H;%(PreprocessorDefinitions) true true @@ -204,11 +204,13 @@ + + @@ -222,40 +224,33 @@ + {4c225a82-800b-427b-ba7b-61686a9b347f} - - {027bad0e-9179-48c1-9733-7aa7e2c2ec70} - {9924ac72-f96c-4e56-94d9-2b025da43c6b} {072fad20-7007-4da2-b2e7-16ce2b219f67} - - {b16b81a9-bef2-44c9-b603-1065183ae844} - {36b528f9-fb79-4078-a16b-0a7442581bb7} {d22bd217-d0f8-4274-9b3a-f3f35f46482c} - - {ffc7b532-0502-4d88-ac98-9e89071cbc97} - false - true - false - true - false - {59500dd1-b192-4ddf-a402-8a8e3739e032} + + {027bad0e-9179-48c1-9733-7aa7e2c2ec70} + + + {ffc7b532-0502-4d88-ac98-9e89071cbc97} + {5dfa07b4-0be9-46a9-ba32-fdf5a55c580b} @@ -276,4 +271,4 @@ - + \ No newline at end of file diff --git a/coreapi/chat.c b/coreapi/chat.c index 280c4353b..39fe39a8c 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -80,7 +80,7 @@ static void linphone_chat_message_file_transfer_on_progress(belle_sip_body_handl * @param size size in byte of the data requested, as output it will contain the effective copied size * */ -static int linphone_chat_message_file_transfer_on_send_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t *msg, void *data, size_t offset, void *buffer, size_t *size){ +static int linphone_chat_message_file_transfer_on_send_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t *msg, void *data, size_t offset, char *buffer, size_t *size){ LinphoneChatMessage* chatMsg=(LinphoneChatMessage *)data; LinphoneCore *lc = chatMsg->chat_room->lc; @@ -445,16 +445,19 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag cr=linphone_core_create_chat_room(lc,cleanfrom); } if (sal_msg->content_type != NULL) { /* content_type field is, for now, used only for rcs file transfer bu twe shall strcmp it with "application/vnd.gsma.rcs-ft-http+xml" */ + xmlChar *file_url = NULL; + xmlDocPtr xmlMessageBody; + xmlNodePtr cur; + msg = linphone_chat_room_create_message(cr, NULL); /* create a message with empty body */ msg->content_type = ms_strdup(sal_msg->content_type); /* add the content_type "application/vnd.gsma.rcs-ft-http+xml" */ msg->file_transfer_information = (LinphoneContent *)malloc(sizeof(LinphoneContent)); memset(msg->file_transfer_information, 0, sizeof(*(msg->file_transfer_information))); - xmlChar *file_url = NULL; /* parse the message body to get all informations from it */ - xmlDocPtr xmlMessageBody = xmlParseDoc((const xmlChar *)sal_msg->text); + xmlMessageBody = xmlParseDoc((const xmlChar *)sal_msg->text); - xmlNodePtr cur = xmlDocGetRootElement(xmlMessageBody); + cur = xmlDocGetRootElement(xmlMessageBody); if (cur != NULL) { cur = cur->xmlChildrenNode; while (cur!=NULL) { @@ -943,7 +946,7 @@ const LinphoneContent *linphone_chat_message_get_file_transfer_information(const return message->file_transfer_information; } -static void on_recv_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t *msg, void *data, size_t offset, const void *buffer, size_t size){ +static void on_recv_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t *msg, void *data, size_t offset, const char *buffer, size_t size){ //printf("Receive %ld bytes\n\n%s\n\n", size, (char *)buffer); LinphoneChatMessage* chatMsg=(LinphoneChatMessage *)data; LinphoneCore *lc = chatMsg->chat_room->lc; @@ -962,7 +965,7 @@ static void linphone_chat_process_response_headers_from_get_file(void *data, con if (event->response){ /*we are receiving a response, set a specific body handler to acquire the response. * if not done, belle-sip will create a memory body handler, the default*/ - LinphoneChatMessage *message=belle_sip_object_data_get(BELLE_SIP_OBJECT(event->request),"message"); + LinphoneChatMessage *message=(LinphoneChatMessage *)belle_sip_object_data_get(BELLE_SIP_OBJECT(event->request),"message"); belle_sip_message_set_body_handler( (belle_sip_message_t*)event->response, (belle_sip_body_handler_t*)belle_sip_user_body_handler_new(message->file_transfer_information->size, linphone_chat_message_file_transfer_on_progress,on_recv_body,NULL,message) @@ -998,11 +1001,10 @@ void linphone_chat_message_start_file_download(const LinphoneChatMessage *messag belle_generic_uri_t *uri; belle_http_request_t *req; const char *url=message->external_body_url; + char* ua = ms_strdup_printf("%s/%s", linphone_core_get_user_agent_name(), linphone_core_get_user_agent_version()); uri=belle_generic_uri_parse(url); - char* ua = ms_strdup_printf("%s/%s", linphone_core_get_user_agent_name(), linphone_core_get_user_agent_version()); - req=belle_http_request_create("GET", uri, belle_sip_header_create("User-Agent",ua), diff --git a/coreapi/private.h b/coreapi/private.h index 9cb1b45da..5c174fb64 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -294,24 +294,24 @@ void linphone_core_get_local_ip(LinphoneCore *lc, int af, char *result); bool_t host_has_ipv6_network(); bool_t lp_spawn_command_line_sync(const char *command, char **result,int *command_ret); -static inline int get_min_bandwidth(int dbw, int ubw){ +static MS2_INLINE int get_min_bandwidth(int dbw, int ubw){ if (dbw<=0) return ubw; if (ubw<=0) return dbw; return MIN(dbw,ubw); } -static inline bool_t bandwidth_is_greater(int bw1, int bw2){ +static MS2_INLINE bool_t bandwidth_is_greater(int bw1, int bw2){ if (bw1<0) return TRUE; else if (bw2<0) return FALSE; else return bw1>=bw2; } -static inline int get_remaining_bandwidth_for_video(int total, int audio){ +static MS2_INLINE int get_remaining_bandwidth_for_video(int total, int audio){ if (total<=0) return 0; return total-audio-10; } -static inline void set_string(char **dest, const char *src){ +static MS2_INLINE void set_string(char **dest, const char *src){ if (*dest){ ms_free(*dest); *dest=NULL; @@ -903,7 +903,7 @@ xmlXPathObjectPtr linphone_get_xml_xpath_object_for_node_list(xmlparsing_context char * linphone_timestamp_to_rfc3339_string(time_t timestamp); -static inline const LinphoneErrorInfo *linphone_error_info_from_sal_op(const SalOp *op){ +static MS2_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); } diff --git a/mediastreamer2 b/mediastreamer2 index 999768a69..fdf4db8e0 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 999768a69bd0b6ead9de0930c6d6ebd4a020ffcf +Subproject commit fdf4db8e0c2a5aa9b7c054f22df6fdb31a21fa46 diff --git a/oRTP b/oRTP index e4a235076..d0e9c7c3d 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit e4a235076787acef6e97eb7a15b400f91fd4f481 +Subproject commit d0e9c7c3d961ac1a400bf2796b03ebefab77541d From 02914901f5d8aa646af21361528a60f22167c6d2 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Mon, 23 Jun 2014 18:18:13 +0200 Subject: [PATCH 06/16] Fix compilation on Linux. --- coreapi/chat.c | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/coreapi/chat.c b/coreapi/chat.c index 39fe39a8c..addc400fc 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -80,32 +80,33 @@ static void linphone_chat_message_file_transfer_on_progress(belle_sip_body_handl * @param size size in byte of the data requested, as output it will contain the effective copied size * */ -static int linphone_chat_message_file_transfer_on_send_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t *msg, void *data, size_t offset, char *buffer, size_t *size){ +static int linphone_chat_message_file_transfer_on_send_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t *msg, void *data, size_t offset, uint8_t *buffer, size_t *size){ LinphoneChatMessage* chatMsg=(LinphoneChatMessage *)data; LinphoneCore *lc = chatMsg->chat_room->lc; + char *buf = (char *)buffer; char *content_type=belle_sip_strdup_printf("%s/%s", chatMsg->file_transfer_information->type, chatMsg->file_transfer_information->subtype); size_t end_of_file=linphone_chat_message_compute_multipart_header_size(chatMsg->file_transfer_information->name, content_type)+chatMsg->file_transfer_information->size; if (offset==0){ int partlen=linphone_chat_message_compute_multipart_header_size(chatMsg->file_transfer_information->name, content_type); - memcpy(buffer,MULTIPART_HEADER_1,strlen(MULTIPART_HEADER_1)); - buffer += strlen(MULTIPART_HEADER_1); - memcpy(buffer,chatMsg->file_transfer_information->name,strlen(chatMsg->file_transfer_information->name)); - buffer += strlen(chatMsg->file_transfer_information->name); - memcpy(buffer,MULTIPART_HEADER_2,strlen(MULTIPART_HEADER_2)); - buffer += strlen(MULTIPART_HEADER_2); - memcpy(buffer,content_type,strlen(content_type)); - buffer += strlen(content_type); - memcpy(buffer,MULTIPART_HEADER_3,strlen(MULTIPART_HEADER_3)); + memcpy(buf,MULTIPART_HEADER_1,strlen(MULTIPART_HEADER_1)); + buf += strlen(MULTIPART_HEADER_1); + memcpy(buf,chatMsg->file_transfer_information->name,strlen(chatMsg->file_transfer_information->name)); + buf += strlen(chatMsg->file_transfer_information->name); + memcpy(buf,MULTIPART_HEADER_2,strlen(MULTIPART_HEADER_2)); + buf += strlen(MULTIPART_HEADER_2); + memcpy(buf,content_type,strlen(content_type)); + buf += strlen(content_type); + memcpy(buf,MULTIPART_HEADER_3,strlen(MULTIPART_HEADER_3)); *size=partlen; }else if (offsetvtable.file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, buffer, size); + lc->vtable.file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, buf, size); }else{ *size=strlen(MULTIPART_END); - strncpy(buffer,MULTIPART_END,*size); + strncpy(buf,MULTIPART_END,*size); } belle_sip_free(content_type); return BELLE_SIP_CONTINUE; @@ -946,13 +947,13 @@ const LinphoneContent *linphone_chat_message_get_file_transfer_information(const return message->file_transfer_information; } -static void on_recv_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t *msg, void *data, size_t offset, const char *buffer, size_t size){ +static void on_recv_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t *msg, void *data, size_t offset, const uint8_t *buffer, size_t size){ //printf("Receive %ld bytes\n\n%s\n\n", size, (char *)buffer); LinphoneChatMessage* chatMsg=(LinphoneChatMessage *)data; LinphoneCore *lc = chatMsg->chat_room->lc; /* call back given by application level */ if (lc->vtable.file_transfer_received != NULL) { - lc->vtable.file_transfer_received(lc, chatMsg, chatMsg->file_transfer_information, buffer, size); + lc->vtable.file_transfer_received(lc, chatMsg, chatMsg->file_transfer_information, (char *)buffer, size); } return; From 85bf7d9a97cfd476cc6a38792002fbf75c4a1716 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 23 Jun 2014 18:52:53 +0200 Subject: [PATCH 07/16] fix possible use of freed object --- coreapi/bellesip_sal/sal_op_registration.c | 4 +++- mediastreamer2 | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/coreapi/bellesip_sal/sal_op_registration.c b/coreapi/bellesip_sal/sal_op_registration.c index 0f011d308..b51435a4f 100644 --- a/coreapi/bellesip_sal/sal_op_registration.c +++ b/coreapi/bellesip_sal/sal_op_registration.c @@ -56,13 +56,15 @@ static void register_refresher_listener (belle_sip_refresher_t* refresher chooses not to re-register, the UA SHOULD discard any stored service route for that address-of-record. */ sal_op_set_service_route(op,NULL); + sal_op_ref(op); /*take a ref while invoking the callback to make sure the operations done after are valid*/ op->base.root->callbacks.register_failure(op); - if (op->auth_info) { + if (op->state!=SalOpStateTerminated && op->auth_info) { /*add pending auth*/ sal_add_pending_auth(op->base.root,op); if (status_code==403 || status_code==401 || status_code==407 ) op->base.root->callbacks.auth_failure(op,op->auth_info); } + sal_op_unref(op); } } diff --git a/mediastreamer2 b/mediastreamer2 index fdf4db8e0..be7b962af 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit fdf4db8e0c2a5aa9b7c054f22df6fdb31a21fa46 +Subproject commit be7b962af74afcfbabe3d99bd0cea447c8fb8fae From bd779601b8add0510b4db98ba5198f52afad80c1 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 24 Jun 2014 10:50:52 +0200 Subject: [PATCH 08/16] Update ms2 submodule. --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index be7b962af..8bb88345e 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit be7b962af74afcfbabe3d99bd0cea447c8fb8fae +Subproject commit 8bb88345ec1788e9c4f6a1a732cddff4f4167d34 From 3e13527bb310c58d8187bf5450d2e7f0e6f37c7a Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 24 Jun 2014 10:51:10 +0200 Subject: [PATCH 09/16] Activate PLI, SLI and RPSI when receiving rtcp-fb nack attribute. --- coreapi/bellesip_sal/sal_sdp.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/coreapi/bellesip_sal/sal_sdp.c b/coreapi/bellesip_sal/sal_sdp.c index 5f71dba0e..4bfed5cf1 100644 --- a/coreapi/bellesip_sal/sal_sdp.c +++ b/coreapi/bellesip_sal/sal_sdp.c @@ -494,6 +494,9 @@ static void apply_rtcp_fb_attribute_to_payload(belle_sdp_rtcp_fb_attribute_t *fb switch (belle_sdp_rtcp_fb_attribute_get_type(fb_attribute)) { case BELLE_SDP_RTCP_FB_NACK: switch (belle_sdp_rtcp_fb_attribute_get_param(fb_attribute)) { + case BELLE_SDP_RTCP_FB_NONE: + avpf_params.features |= PAYLOAD_TYPE_AVPF_PLI | PAYLOAD_TYPE_AVPF_SLI | PAYLOAD_TYPE_AVPF_RPSI; + break; case BELLE_SDP_RTCP_FB_PLI: avpf_params.features |= PAYLOAD_TYPE_AVPF_PLI; break; From 704e2cd0801473fd7219f903fbac34ca11f86b50 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 24 Jun 2014 13:58:49 +0200 Subject: [PATCH 10/16] Update ms2 submodule. --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 8bb88345e..d4095e659 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 8bb88345ec1788e9c4f6a1a732cddff4f4167d34 +Subproject commit d4095e65985501aa3b0b676602b62d2e5e63b5d8 From 2f6136009c0be20c8a75371e4397577d6b6ce2ed Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 24 Jun 2014 13:59:11 +0200 Subject: [PATCH 11/16] Handle "rtcp-fb ccm fir" attribute in SDP. --- coreapi/bellesip_sal/sal_sdp.c | 30 +++++++++++++++++++++--------- coreapi/linphonecall.c | 3 --- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/coreapi/bellesip_sal/sal_sdp.c b/coreapi/bellesip_sal/sal_sdp.c index 4bfed5cf1..fe952bb56 100644 --- a/coreapi/bellesip_sal/sal_sdp.c +++ b/coreapi/bellesip_sal/sal_sdp.c @@ -101,6 +101,14 @@ static void add_rtcp_fb_nack_attribute(belle_sdp_media_description_t *media_desc belle_sdp_media_description_add_attribute(media_desc, BELLE_SDP_ATTRIBUTE(attribute)); } +static void add_rtcp_fb_ccm_attribute(belle_sdp_media_description_t *media_desc, int8_t id, belle_sdp_rtcp_fb_val_param_t param) { + belle_sdp_rtcp_fb_attribute_t *attribute = belle_sdp_rtcp_fb_attribute_new(); + belle_sdp_rtcp_fb_attribute_set_id(attribute, id); + belle_sdp_rtcp_fb_attribute_set_type(attribute, BELLE_SDP_RTCP_FB_CCM); + belle_sdp_rtcp_fb_attribute_set_param(attribute, param); + belle_sdp_media_description_add_attribute(media_desc, BELLE_SDP_ATTRIBUTE(attribute)); +} + static void add_rtcp_fb_attributes(belle_sdp_media_description_t *media_desc, const SalMediaDescription *md, const SalStreamDescription *stream) { MSList *pt_it; PayloadType *pt; @@ -130,6 +138,9 @@ static void add_rtcp_fb_attributes(belle_sdp_media_description_t *media_desc, co if (avpf_params.features & PAYLOAD_TYPE_AVPF_RPSI) { add_rtcp_fb_nack_attribute(media_desc, payload_type_get_number(pt), BELLE_SDP_RTCP_FB_RPSI); } + if (avpf_params.features & PAYLOAD_TYPE_AVPF_FIR) { + add_rtcp_fb_ccm_attribute(media_desc, payload_type_get_number(pt), BELLE_SDP_RTCP_FB_FIR); + } } } @@ -475,17 +486,9 @@ static void sdp_parse_media_ice_parameters(belle_sdp_media_description_t *media_ static void enable_avpf_for_stream(SalStreamDescription *stream) { MSList *pt_it; - PayloadType *pt; - PayloadTypeAvpfParams avpf_params; - for (pt_it = stream->payloads; pt_it != NULL; pt_it = pt_it->next) { - pt = (PayloadType *)pt_it->data; - avpf_params = payload_type_get_avpf_params(pt); + PayloadType *pt = (PayloadType *)pt_it->data; payload_type_set_flag(pt, PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED); - if (stream->type == SalVideo) { - avpf_params.features |= PAYLOAD_TYPE_AVPF_FIR; - } - payload_type_set_avpf_params(pt, avpf_params); } } @@ -513,6 +516,15 @@ static void apply_rtcp_fb_attribute_to_payload(belle_sdp_rtcp_fb_attribute_t *fb case BELLE_SDP_RTCP_FB_TRR_INT: avpf_params.trr_interval = belle_sdp_rtcp_fb_attribute_get_trr_int(fb_attribute); break; + case BELLE_SDP_RTCP_FB_CCM: + switch (belle_sdp_rtcp_fb_attribute_get_param(fb_attribute)) { + case BELLE_SDP_RTCP_FB_FIR: + avpf_params.features |= PAYLOAD_TYPE_AVPF_FIR; + break; + default: + break; + } + break; case BELLE_SDP_RTCP_FB_ACK: default: break; diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 218bf86fd..4e4babcbc 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -335,9 +335,6 @@ static void setup_rtcp_fb(LinphoneCall *call, SalMediaDescription *md) { payload_type_set_flag(pt, PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED); avpf_params = payload_type_get_avpf_params(pt); avpf_params.trr_interval = call->params.avpf_rr_interval; - if (md->streams[i].type == SalVideo) { - avpf_params.features |= PAYLOAD_TYPE_AVPF_FIR; - } } else { payload_type_unset_flag(pt, PAYLOAD_TYPE_RTCP_FEEDBACK_ENABLED); memset(&avpf_params, 0, sizeof(avpf_params)); From 5cf381b667d77a52381155a5b64dfa0a2c75da2b Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Tue, 24 Jun 2014 09:43:32 +0200 Subject: [PATCH 12/16] add linphone_core_get_user_agent to retrieve local user agent --- coreapi/bellesip_sal/sal_impl.c | 14 ++++-- coreapi/linphonecore.c | 9 ++++ coreapi/linphonecore.h | 7 +++ coreapi/quality_reporting.c | 76 ++++++++++++++++++++------------- coreapi/quality_reporting.h | 45 ++++++++++--------- include/sal/sal.h | 1 + 6 files changed, 97 insertions(+), 55 deletions(-) diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index c4809ecc6..daf746c79 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -424,21 +424,21 @@ static void process_auth_requested(void *sal, belle_sip_auth_event_t *event) { Sal * sal_init(){ belle_sip_listener_callbacks_t listener_callbacks; Sal * sal=ms_new0(Sal,1); - + /*belle_sip_object_enable_marshal_check(TRUE);*/ sal->auto_contacts=TRUE; - + /*first create the stack, which initializes the belle-sip object's pool for this thread*/ belle_sip_set_log_handler(_belle_sip_log); sal->stack = belle_sip_stack_new(NULL); - + sal->user_agent=belle_sip_header_user_agent_new(); #if defined(PACKAGE_NAME) && defined(LINPHONE_VERSION) belle_sip_header_user_agent_add_product(sal->user_agent, PACKAGE_NAME "/" LINPHONE_VERSION); #endif sal_append_stack_string_to_user_agent(sal); belle_sip_object_ref(sal->user_agent); - + sal->prov = belle_sip_stack_create_provider(sal->stack,NULL); sal_nat_helper_enable(sal,TRUE); memset(&listener_callbacks,0,sizeof(listener_callbacks)); @@ -617,6 +617,12 @@ void sal_set_user_agent(Sal *ctx, const char *user_agent){ return ; } +const char* sal_get_user_agent(Sal *ctx){ + static char user_agent[255]; + belle_sip_header_user_agent_get_products_as_string(ctx->user_agent, user_agent, 254); + return user_agent; +} + void sal_append_stack_string_to_user_agent(Sal *ctx) { char stack_string[64]; snprintf(stack_string, sizeof(stack_string) - 1, "(belle-sip/%s)", belle_sip_version_to_string()); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 9f4cfbd9c..65db5a709 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1914,6 +1914,15 @@ void linphone_core_set_user_agent(LinphoneCore *lc, const char *name, const char apply_user_agent(lc); #endif } +const char *linphone_core_get_user_agent(LinphoneCore *lc){ +#if USE_BELLESIP + return sal_get_user_agent(lc->sal); +#else + static char ua_buffer[255] = {0}; + snprintf(ua_buffer, "%s/%s", _ua_name, _ua_version, 254); + return ua_buffer; +#endif +} const char *linphone_core_get_user_agent_name(void){ return _ua_name; diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index dd0ff311a..0cabc434f 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -1542,7 +1542,14 @@ LINPHONE_PUBLIC void linphone_core_enable_logs(FILE *file); LINPHONE_PUBLIC void linphone_core_enable_logs_with_cb(OrtpLogFunc logfunc); LINPHONE_PUBLIC void linphone_core_disable_logs(void); LINPHONE_PUBLIC const char *linphone_core_get_version(void); +LINPHONE_PUBLIC const char *linphone_core_get_user_agent(LinphoneCore *lc); +/** + * @deprecated Use #linphone_core_get_user_agent instead. +**/ LINPHONE_PUBLIC const char *linphone_core_get_user_agent_name(void); +/** + * @deprecated Use #linphone_core_get_user_agent instead. +**/ LINPHONE_PUBLIC const char *linphone_core_get_user_agent_version(void); LINPHONE_PUBLIC LinphoneCore *linphone_core_new(const LinphoneCoreVTable *vtable, diff --git a/coreapi/quality_reporting.c b/coreapi/quality_reporting.c index e16dd8f81..528ec5208 100644 --- a/coreapi/quality_reporting.c +++ b/coreapi/quality_reporting.c @@ -236,6 +236,11 @@ static void append_metrics_to_buffer(char ** buffer, size_t * size, size_t * off APPEND_IF_NOT_NULL_STR(buffer, size, offset, " MOSCQ=%s", moscq_str); } + if (rm.user_agent!=NULL){ + append_to_buffer(buffer, size, offset, "\r\nLinphoneExt:"); + APPEND_IF_NOT_NULL_STR(buffer, size, offset, " UA=\"%s\"", rm.user_agent); + } + append_to_buffer(buffer, size, offset, "\r\n"); ms_free(timestamps_start_str); @@ -430,17 +435,27 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { STR_REASSIGN(report->info.call_id, ms_strdup(call->log->call_id)); - STR_REASSIGN(report->info.local_addr.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->dialog_id, sal_op_get_dialog_id(call->op)); + + STR_REASSIGN(report->local_metrics.user_agent, ms_strdup(linphone_core_get_user_agent(call->core))); + STR_REASSIGN(report->remote_metrics.user_agent, ms_strdup(linphone_call_get_remote_user_agent(call))); + + // RFC states: "LocalGroupID provides the identification for the purposes + // of aggregation for the local endpoint.". + STR_REASSIGN(report->info.local_addr.group, ms_strdup_printf("%s-%s-%s" + , report->dialog_id + , "local" + , report->local_metrics.user_agent + ) ); - STR_REASSIGN(report->info.remote_addr.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) + STR_REASSIGN(report->info.remote_addr.group, ms_strdup_printf("%s-%s-%s" + , report->dialog_id + , "remote" + , report->remote_metrics.user_agent + ) ); + if (call->dir == LinphoneCallIncoming) { STR_REASSIGN(report->info.remote_addr.id, linphone_address_as_string(call->log->from)); STR_REASSIGN(report->info.local_addr.id, linphone_address_as_string(call->log->to)); @@ -451,7 +466,6 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { STR_REASSIGN(report->info.orig_id, ms_strdup(report->info.local_addr.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); @@ -663,27 +677,29 @@ reporting_session_report_t * linphone_reporting_new() { } 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_addr.id != NULL) ms_free(report->info.local_addr.id); - if (report->info.remote_addr.id != NULL) ms_free(report->info.remote_addr.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_addr.group != NULL) ms_free(report->info.local_addr.group); - if (report->info.remote_addr.group != NULL) ms_free(report->info.remote_addr.group); - if (report->info.local_addr.mac != NULL) ms_free(report->info.local_addr.mac); - if (report->info.remote_addr.mac != NULL) ms_free(report->info.remote_addr.mac); - 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); - if (report->qos_analyzer.name != NULL) ms_free(report->qos_analyzer.name); - if (report->qos_analyzer.timestamp != NULL) ms_free(report->qos_analyzer.timestamp); - if (report->qos_analyzer.input_leg != NULL) ms_free(report->qos_analyzer.input_leg); - if (report->qos_analyzer.input != NULL) ms_free(report->qos_analyzer.input); - if (report->qos_analyzer.output_leg != NULL) ms_free(report->qos_analyzer.output_leg); - if (report->qos_analyzer.output != NULL) ms_free(report->qos_analyzer.output); + STR_REASSIGN(report->info.call_id, NULL); + STR_REASSIGN(report->info.local_addr.id, NULL); + STR_REASSIGN(report->info.remote_addr.id, NULL); + STR_REASSIGN(report->info.orig_id, NULL); + STR_REASSIGN(report->info.local_addr.ip, NULL); + STR_REASSIGN(report->info.remote_addr.ip, NULL); + STR_REASSIGN(report->info.local_addr.group, NULL); + STR_REASSIGN(report->info.remote_addr.group, NULL); + STR_REASSIGN(report->info.local_addr.mac, NULL); + STR_REASSIGN(report->info.remote_addr.mac, NULL); + STR_REASSIGN(report->dialog_id, NULL); + STR_REASSIGN(report->local_metrics.session_description.fmtp, NULL); + STR_REASSIGN(report->local_metrics.session_description.payload_desc, NULL); + STR_REASSIGN(report->local_metrics.user_agent, NULL); + STR_REASSIGN(report->remote_metrics.session_description.fmtp, NULL); + STR_REASSIGN(report->remote_metrics.session_description.payload_desc, NULL); + STR_REASSIGN(report->remote_metrics.user_agent, NULL); + STR_REASSIGN(report->qos_analyzer.name, NULL); + STR_REASSIGN(report->qos_analyzer.timestamp, NULL); + STR_REASSIGN(report->qos_analyzer.input_leg, NULL); + STR_REASSIGN(report->qos_analyzer.input, NULL); + STR_REASSIGN(report->qos_analyzer.output_leg, NULL); + STR_REASSIGN(report->qos_analyzer.output, NULL); ms_free(report); } diff --git a/coreapi/quality_reporting.h b/coreapi/quality_reporting.h index 3c387a903..acc898924 100644 --- a/coreapi/quality_reporting.h +++ b/coreapi/quality_reporting.h @@ -54,48 +54,51 @@ typedef struct reporting_content_metrics { // 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 + char * payload_desc; + int sample_rate; + int frame_duration; char * fmtp; - int packet_loss_concealment; // in voip metrics - audio only + int packet_loss_concealment; } session_description; // jitter buffet - optional struct { - int adaptive; // constant - int nominal; // average - int max; // average - int abs_max; // constant + int adaptive; + int nominal; + int max; + int abs_max; } jitter_buffer; // packet loss - optional struct { - float network_packet_loss_rate; // average - float jitter_buffer_discard_rate; // average + float network_packet_loss_rate; + float jitter_buffer_discard_rate; } packet_loss; // delay - optional struct { - int round_trip_delay; // no - vary - int end_system_delay; // no - not implemented yet - int symm_one_way_delay; // no - not implemented (depends on end_system_delay) - int interarrival_jitter; // no - not implemented yet - int mean_abs_jitter; // to check + int round_trip_delay; + int end_system_delay; + int symm_one_way_delay; + int interarrival_jitter; + int mean_abs_jitter; } delay; // signal - optional struct { - int level; // no - vary - int noise_level; // no - vary + int level; + int noise_level; } signal; // quality estimates - optional struct { - float moslq; // no - vary or avg - voip metrics - in [0..4.9] - float moscq; // no - vary or avg - voip metrics - in [0..4.9] + float moslq; + float moscq; } quality_estimates; + // custom extension + char * user_agent; + // for internal processing uint8_t rtcp_xr_count; // number of RTCP XR packets received since last report, used to compute average of instantaneous parameters as stated in the RFC 6035 (4.5) uint8_t rtcp_sr_count; // number of RTCP SR packets received since last report, used to compute RTT average values in case RTCP XR voip metrics is not enabled @@ -127,9 +130,9 @@ typedef struct reporting_session_report { char * name; /*type of the QoS analyzer used*/ char* timestamp; /*time of each decision in seconds*/ char* input_leg; /*input parameters' name*/ - char* input; /*set of inputs for each decision, semicolon separated*/ + char* input; /*set of inputs for each semicolon separated decision*/ char* output_leg; /*output parameters' name*/ - char* output; /*set of outputs for each decision, semicolon separated*/ + char* output; /*set of outputs for each semicolon separated decision*/ } qos_analyzer; // for internal processing diff --git a/include/sal/sal.h b/include/sal/sal.h index e9719fc7b..642cfdd2a 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -519,6 +519,7 @@ void sal_set_dscp(Sal *ctx, int dscp); int sal_reset_transports(Sal *ctx); ortp_socket_t sal_get_socket(Sal *ctx); void sal_set_user_agent(Sal *ctx, const char *user_agent); +const char* sal_get_user_agent(Sal *ctx); void sal_append_stack_string_to_user_agent(Sal *ctx); /*keepalive period in ms*/ void sal_set_keepalive_period(Sal *ctx,unsigned int value); From d472ac0bef88f3405cd87e8b685ca04f74bf3d0a Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Tue, 24 Jun 2014 11:51:36 +0200 Subject: [PATCH 13/16] set linphonec as user-agent for linphonec --- console/linphonec.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/console/linphonec.c b/console/linphonec.c index ca7d6cafa..b8072e325 100644 --- a/console/linphonec.c +++ b/console/linphonec.c @@ -551,7 +551,7 @@ char *linphonec_readline(char *prompt){ should. Maybe should we only have this on when the option -V or -D is on? */ MSG msg; - + if (PeekMessage(&msg, NULL, 0, 0,1)) { TranslateMessage(&msg); DispatchMessage(&msg); @@ -648,7 +648,7 @@ main (int argc, char *argv[]) { linphonec_vtable.refer_received=linphonec_display_refer; linphonec_vtable.transfer_state_changed=linphonec_transfer_state_changed; linphonec_vtable.call_encryption_changed=linphonec_call_encryption_changed; - + if (! linphonec_init(argc, argv) ) exit(EXIT_FAILURE); linphonec_main_loop (linphonec); @@ -671,8 +671,8 @@ linphonec_init(int argc, char **argv) * Set initial values for global variables */ mylogfile = NULL; - - + + #ifndef _WIN32 snprintf(configfile_name, PATH_MAX, "%s/.linphonerc", getenv("HOME")); @@ -701,7 +701,6 @@ linphonec_init(int argc, char **argv) default: break; } - #ifdef ENABLE_NLS if (NULL == bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR)) perror ("bindtextdomain failed"); @@ -741,10 +740,12 @@ linphonec_init(int argc, char **argv) * Initialize linphone core */ linphonec=linphone_core_new (&linphonec_vtable, configfile_name, factory_configfile_name, NULL); + + linphone_core_set_user_agent(linphonec,"Linphonec", LINPHONE_VERSION); linphone_core_set_zrtp_secrets_file(linphonec,zrtpsecrets); linphone_core_enable_video_capture(linphonec, vcap_enabled); linphone_core_enable_video_display(linphonec, display_enabled); - if (display_enabled && window_id != 0) + if (display_enabled && window_id != 0) { printf ("Setting window_id: 0x%x\n", window_id); linphone_core_set_native_video_window_id(linphonec,window_id); @@ -782,7 +783,7 @@ linphonec_finish(int exit_status) { // Do not allow concurrent destroying to prevent glibc errors static bool_t terminating=FALSE; - if (terminating) return; + if (terminating) return; terminating=TRUE; linphonec_out("Terminating...\n"); @@ -829,9 +830,9 @@ linphonec_prompt_for_auth_final(LinphoneCore *lc) #endif if (reentrancy!=0) return 0; - + reentrancy++; - + LinphoneAuthInfo *pending_auth=auth_stack.elem[auth_stack.nitems-1]; snprintf(auth_prompt, 256, "Password for %s on %s: ", @@ -1159,7 +1160,6 @@ linphonec_main_loop (LinphoneCore * opm) add_history(iptr); } #endif - linphonec_parse_command_line(linphonec, iptr); linphonec_command_finished(); free(input); From ef7bf6a96bd974c0152c02465268b6e14cfd88f6 Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Tue, 24 Jun 2014 12:20:38 +0200 Subject: [PATCH 14/16] QosAnalyser: change dialog_id and reset avg values --- coreapi/quality_reporting.c | 24 ++++++++++++++++-------- mediastreamer2 | 2 +- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/coreapi/quality_reporting.c b/coreapi/quality_reporting.c index 528ec5208..f4ba1260f 100644 --- a/coreapi/quality_reporting.c +++ b/coreapi/quality_reporting.c @@ -90,6 +90,9 @@ static void reset_avg_metrics(reporting_session_report_t * report){ metrics[i]->jitter_buffer.nominal = 0; metrics[i]->jitter_buffer.max = 0; + metrics[i]->quality_estimates.moslq = 0; + metrics[i]->quality_estimates.moscq = 0; + metrics[i]->delay.round_trip_delay = 0; } report->last_report_date = ms_time(NULL); @@ -353,10 +356,9 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report, linphone_content_uninit(&content); end: - ms_message("QualityReporting[%p]: Send '%s' for '%s' stream with status %d", + ms_message("QualityReporting[%p]: Send '%s' with status %d", call, report_event, - report->info.local_addr.group, ret ); @@ -429,13 +431,14 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { const PayloadType * remote_payload = NULL; const LinphoneCallParams * current_params = linphone_call_get_current_params(call); reporting_session_report_t * report = call->log->reporting.reports[stats_type]; + char * dialog_id; if (!media_report_enabled(call, stats_type)) return; + dialog_id = sal_op_get_dialog_id(call->op); STR_REASSIGN(report->info.call_id, ms_strdup(call->log->call_id)); - STR_REASSIGN(report->dialog_id, sal_op_get_dialog_id(call->op)); STR_REASSIGN(report->local_metrics.user_agent, ms_strdup(linphone_core_get_user_agent(call->core))); STR_REASSIGN(report->remote_metrics.user_agent, ms_strdup(linphone_call_get_remote_user_agent(call))); @@ -443,13 +446,13 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { // RFC states: "LocalGroupID provides the identification for the purposes // of aggregation for the local endpoint.". STR_REASSIGN(report->info.local_addr.group, ms_strdup_printf("%s-%s-%s" - , report->dialog_id + , dialog_id , "local" , report->local_metrics.user_agent ) ); STR_REASSIGN(report->info.remote_addr.group, ms_strdup_printf("%s-%s-%s" - , report->dialog_id + , dialog_id , "remote" , report->remote_metrics.user_agent ) @@ -492,6 +495,8 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { report->info.remote_addr.ssrc = rtp_session_get_recv_ssrc(session); } + STR_REASSIGN(report->dialog_id, ms_strdup_printf("%s;%u", dialog_id, report->info.local_addr.ssrc)); + if (local_payload != NULL) { report->local_metrics.session_description.payload_type = local_payload->type; if (local_payload->mime_type!=NULL) STR_REASSIGN(report->local_metrics.session_description.payload_desc, ms_strdup(local_payload->mime_type)); @@ -505,6 +510,8 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_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)); } + + ms_free(dialog_id); } /* generate random float in interval ] 0.9 t ; 1.1 t [*/ @@ -531,7 +538,6 @@ void linphone_reporting_on_rtcp_update(LinphoneCall *call, int stats_type) { metrics = &report->local_metrics; block = stats.sent_rtcp; } - do{ if (rtcp_is_XR(block) && (rtcp_XR_get_block_type(block) == RTCP_XR_VOIP_METRICS)){ @@ -539,8 +545,10 @@ void linphone_reporting_on_rtcp_update(LinphoneCall *call, int stats_type) { metrics->rtcp_xr_count++; - 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->quality_estimates.moslq = (rtcp_XR_voip_metrics_get_mos_lq(block)==127) ? + 127 : 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)==127) ? + 127 : 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); diff --git a/mediastreamer2 b/mediastreamer2 index d4095e659..5fbe23460 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit d4095e65985501aa3b0b676602b62d2e5e63b5d8 +Subproject commit 5fbe23460f99743eb0df9c479e0832cc41703988 From 6cb4ab91610f6c2900344582a682cdeb7454960e Mon Sep 17 00:00:00 2001 From: Gautier Pelloux-Prayer Date: Tue, 24 Jun 2014 16:30:22 +0200 Subject: [PATCH 15/16] display error if invalid arguments are passed to linphone GTK before quitting --- gtk/main.c | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/gtk/main.c b/gtk/main.c index c1a52cda4..538bb11a2 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -418,9 +418,9 @@ GtkWidget *linphone_gtk_create_widget(const char *filename, const char *widget_n object_ids[1]=NULL; if (get_ui_file(filename,path,sizeof(path))==-1) return NULL; - + gtk_builder_set_translation_domain(builder,GETTEXT_PACKAGE); - + if (!gtk_builder_add_objects_from_file(builder,path,object_ids,&error)){ g_error("Couldn't load %s from builder file %s: %s", widget_name,path,error->message); g_error_free (error); @@ -983,14 +983,14 @@ gchar *linphone_gtk_get_record_path(const LinphoneAddress *address, gboolean is_ char date[64]={0}; time_t curtime=time(NULL); struct tm loctime; - + #ifdef WIN32 loctime=*localtime(&curtime); #else localtime_r(&curtime,&loctime); #endif snprintf(date,sizeof(date)-1,"%i%02i%02i-%02i%02i",loctime.tm_year+1900,loctime.tm_mon+1,loctime.tm_mday, loctime.tm_hour, loctime.tm_min); - + if (address){ id=linphone_address_get_username(address); if (id==NULL) id=linphone_address_get_domain(address); @@ -1015,7 +1015,7 @@ static gboolean linphone_gtk_start_call_do(GtkWidget *uri_bar){ const char *entered=gtk_entry_get_text(GTK_ENTRY(uri_bar)); LinphoneCore *lc=linphone_gtk_get_core(); LinphoneAddress *addr=linphone_core_interpret_url(lc,entered); - + if (addr!=NULL){ LinphoneCallParams *params=linphone_core_create_default_call_parameters(lc); gchar *record_file=linphone_gtk_get_record_path(addr,FALSE); @@ -1632,13 +1632,13 @@ static GtkWidget *create_icon_menu(){ } void linphone_gtk_save_main_window_position(GtkWindow* mw, GdkEvent *event, gpointer data){ - gtk_window_get_position(GTK_WINDOW(mw), &main_window_x, &main_window_y); + gtk_window_get_position(GTK_WINDOW(mw), &main_window_x, &main_window_y); } static void handle_icon_click() { GtkWidget *mw=linphone_gtk_get_main_window(); if (!gtk_window_is_active((GtkWindow*)mw)) { - if(!gtk_widget_is_drawable(mw)){ + if(!gtk_widget_is_drawable(mw)){ //we only move if window was hidden. If it was simply behind the window stack, ie, drawable, we keep it as it was gtk_window_move (GTK_WINDOW(mw), main_window_x, main_window_y); } @@ -2180,6 +2180,7 @@ int main(int argc, char *argv[]){ const char *app_name="Linphone"; LpConfig *factory; const char *db_file; + GError *error=NULL; #if !GLIB_CHECK_VERSION(2, 31, 0) g_thread_init(NULL); @@ -2234,8 +2235,9 @@ int main(int argc, char *argv[]){ gdk_threads_enter(); if (!gtk_init_with_args(&argc,&argv,_("A free SIP video-phone"), - linphone_options,NULL,NULL)){ + linphone_options,NULL,&error)){ gdk_threads_leave(); + g_critical("%s", error->message); return -1; } if (config_file) free(config_file); @@ -2261,7 +2263,7 @@ int main(int argc, char *argv[]){ g_error("Could not change directory to %s : %s",workingdir,strerror(errno)); } } - + #if defined(__APPLE__) && defined(ENABLE_NLS) /*workaround for bundles. GTK is unable to find translations in the bundle (obscure bug again). So we help it:*/ @@ -2312,18 +2314,18 @@ core_start: linphone_gtk_create_log_window(); linphone_core_enable_logs_with_cb(linphone_gtk_log_handler); - + db_file=linphone_gtk_message_storage_get_db_file(NULL); linphone_gtk_init_liblinphone(config_file, factory_config_file, db_file); - + /* do not lower timeouts under 30 ms because it exhibits a bug on gtk+/win32, with cpu running 20% all the time...*/ gtk_timeout_add(30,(GtkFunction)linphone_gtk_iterate,(gpointer)linphone_gtk_get_core()); gtk_timeout_add(30,(GtkFunction)linphone_gtk_check_logs,(gpointer)linphone_gtk_get_core()); - + gtk_main(); linphone_gtk_quit(); - + if (restart){ quit_done=FALSE; restart=FALSE; From 779e0fc3821ece403b9dcb232f1b7bd789f605ba Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Tue, 24 Jun 2014 18:09:01 +0200 Subject: [PATCH 16/16] update ms2 --- mediastreamer2 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediastreamer2 b/mediastreamer2 index 5fbe23460..2a8a13ab6 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 5fbe23460f99743eb0df9c479e0832cc41703988 +Subproject commit 2a8a13ab6a83fe4b63778886b4b9ef844dd51e87