Merge remote-tracking branch 'origin/master' into dev_recorder

Conflicts:
	gtk/main.c
	mediastreamer2
This commit is contained in:
Simon Morlat 2014-06-25 17:11:34 +02:00
commit f0c07e2fe0
18 changed files with 288 additions and 176 deletions

View file

@ -66,7 +66,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\..\oRTP\include;$(ProjectDir)..\..\..\..\mediastreamer2\include;$(ProjectDIr)..\..\..\..\tunnel\include;$(ProjectDir)..\..\..\coreapi;$(ProjectDir)..\..\..\include;$(SolutionDir)$(Platform)\$(Configuration)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<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)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__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)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
@ -90,7 +90,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\..\oRTP\include;$(ProjectDir)..\..\..\..\mediastreamer2\include;$(ProjectDIr)..\..\..\..\tunnel\include;$(ProjectDir)..\..\..\coreapi;$(ProjectDir)..\..\..\include;$(SolutionDir)$(Platform)\$(Configuration)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<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)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__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)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<FunctionLevelLinking>true</FunctionLevelLinking>
@ -116,7 +116,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\..\oRTP\include;$(ProjectDir)..\..\..\..\mediastreamer2\include;$(ProjectDIr)..\..\..\..\tunnel\include;$(ProjectDir)..\..\..\coreapi;$(ProjectDir)..\..\..\include;$(SolutionDir)$(Platform)\$(Configuration)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<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)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__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)</PreprocessorDefinitions>
<MinimalRebuild>false</MinimalRebuild>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
@ -146,7 +146,7 @@
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\..\oRTP\include;$(ProjectDir)..\..\..\..\mediastreamer2\include;$(ProjectDIr)..\..\..\..\tunnel\include;$(ProjectDir)..\..\..\coreapi;$(ProjectDir)..\..\..\include;$(SolutionDir)$(Platform)\$(Configuration)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<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)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__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)</PreprocessorDefinitions>
<StringPooling>true</StringPooling>
<FunctionLevelLinking>true</FunctionLevelLinking>
@ -204,11 +204,13 @@
<ClCompile Include="..\..\..\coreapi\presence.c" />
<ClCompile Include="..\..\..\coreapi\proxy.c" />
<ClCompile Include="..\..\..\coreapi\quality_reporting.c" />
<ClCompile Include="..\..\..\coreapi\remote_provisioning.c" />
<ClCompile Include="..\..\..\coreapi\sal.c" />
<ClCompile Include="..\..\..\coreapi\siplogin.c" />
<ClCompile Include="..\..\..\coreapi\sipsetup.c" />
<ClCompile Include="..\..\..\coreapi\TunnelManager.cc" />
<ClCompile Include="..\..\..\coreapi\xml.c" />
<ClCompile Include="..\..\..\coreapi\xml2lpc.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\coreapi\bellesip_sal\sal_impl.h" />
@ -222,40 +224,33 @@
<ClInclude Include="..\..\..\coreapi\offeranswer.h" />
<ClInclude Include="..\..\..\coreapi\private.h" />
<ClInclude Include="..\..\..\coreapi\sipsetup.h" />
<ClInclude Include="..\..\..\coreapi\xml2lpc.h" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\belle-sip\build\windows\belle-sip\belle-sip.vcxproj">
<Project>{4c225a82-800b-427b-ba7b-61686a9b347f}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\..\mediastreamer2\build\vsx\mediastreamer2\mediastreamer2\mediastreamer2.vcxproj">
<Project>{027bad0e-9179-48c1-9733-7aa7e2c2ec70}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\..\msamr\build\windows\msamr\msamr\msamr.vcxproj">
<Project>{9924ac72-f96c-4e56-94d9-2b025da43c6b}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\..\msilbc\build\windows\msilbc\msilbc\msilbc.vcxproj">
<Project>{072fad20-7007-4da2-b2e7-16ce2b219f67}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\..\msisac\build\windows\msisac\msisac\msisac.vcxproj">
<Project>{b16b81a9-bef2-44c9-b603-1065183ae844}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\..\mssilk\build\windows\mssilk\mssilk\mssilk.vcxproj">
<Project>{36b528f9-fb79-4078-a16b-0a7442581bb7}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\..\mswasapi\mswasapi\mswasapi\mswasapi.vcxproj">
<Project>{d22bd217-d0f8-4274-9b3a-f3f35f46482c}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\..\oRTP\build\vsx\oRTP\oRTP\oRTP.vcxproj">
<Project>{ffc7b532-0502-4d88-ac98-9e89071cbc97}</Project>
<Private>false</Private>
<ReferenceOutputAssembly>true</ReferenceOutputAssembly>
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
<LinkLibraryDependencies>true</LinkLibraryDependencies>
<UseLibraryDependencyInputs>false</UseLibraryDependencyInputs>
</ProjectReference>
<ProjectReference Include="..\..\..\..\tunnel\build\windows\tunnel\tunnel\tunnel.vcxproj">
<Project>{59500dd1-b192-4ddf-a402-8a8e3739e032}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\mediastreamer2\build\vsx\mediastreamer2\mediastreamer2\mediastreamer2.vcxproj">
<Project>{027bad0e-9179-48c1-9733-7aa7e2c2ec70}</Project>
</ProjectReference>
<ProjectReference Include="..\..\..\oRTP\build\vsx\oRTP\oRTP\oRTP.vcxproj">
<Project>{ffc7b532-0502-4d88-ac98-9e89071cbc97}</Project>
</ProjectReference>
<ProjectReference Include="..\libxml2\libxml2\libxml2.vcxproj">
<Project>{5dfa07b4-0be9-46a9-ba32-fdf5a55c580b}</Project>
</ProjectReference>
@ -276,4 +271,4 @@
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsPhone\v$(TargetPlatformVersion)\Microsoft.Cpp.WindowsPhone.$(TargetPlatformVersion).targets" Condition="'$(Platform)'=='ARM'" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>
</Project>

View file

@ -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);

View file

@ -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());

View file

@ -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);
}
}

View file

@ -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);
@ -101,12 +101,20 @@ 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;
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) {
@ -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,18 +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;
}
avpf_params.trr_interval = 0;
payload_type_set_avpf_params(pt, avpf_params);
}
}
@ -495,6 +497,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;
@ -509,7 +514,16 @@ 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_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:

View file

@ -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, 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, 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 (offset<end_of_file){
/* get data from call back */
lc->vtable.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;
@ -445,16 +446,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,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 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 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;
@ -962,7 +966,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 +1002,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),

View file

@ -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;
}
@ -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));
@ -682,6 +679,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 +733,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 +748,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*/
@ -1873,6 +1885,7 @@ static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *m
const LinphoneCallParams *params=&call->params;
*used_pt=-1;
if (desc->type==SalAudio)
bw=get_ideal_audio_bw(call,md,desc);
else if (desc->type==SalVideo)
@ -1899,6 +1912,7 @@ static RtpProfile *make_profile(LinphoneCall *call, const SalMediaDescription *m
first=FALSE;
}
if (pt->flags & PAYLOAD_TYPE_BITRATE_OVERRIDE){
ms_message("Payload type [%s/%i] has explicit bitrate [%i] kbit/s", pt->mime_type, pt->clock_rate, pt->normal_bitrate/1000);
pt->normal_bitrate=get_min_bandwidth(pt->normal_bitrate,bw*1000);
} else pt->normal_bitrate=bw*1000;
if (desc->ptime>0){
@ -2215,12 +2229,16 @@ void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_mut
use_arc=FALSE;
}
#endif
ms_message("linphone_call_start_media_streams() call=[%p] local upload_bandwidth=[%i] kbit/s; local download_bandwidth=[%i] kbit/s",
call, linphone_core_get_upload_bandwidth(lc),linphone_core_get_download_bandwidth(lc));
if (call->audiostream!=NULL) {
linphone_call_start_audio_stream(call,cname,all_inputs_muted,send_ringbacktone,use_arc);
}
call->current_params.has_video=FALSE;
if (call->videostream!=NULL) {
linphone_call_start_video_stream(call,cname,all_inputs_muted);
if (call->audiostream) audio_stream_link_video(call->audiostream,call->videostream);
}
call->all_muted=all_inputs_muted;
@ -2340,7 +2358,7 @@ static void linphone_call_log_fill_stats(LinphoneCallLog *log, MediaStream *st){
}
}
void linphone_call_stop_audio_stream(LinphoneCall *call) {
static void linphone_call_stop_audio_stream(LinphoneCall *call) {
if (call->audiostream!=NULL) {
linphone_reporting_update_media_info(call, LINPHONE_CALL_STATS_AUDIO);
media_stream_reclaim_sessions(&call->audiostream->ms,&call->sessions[0]);
@ -2368,7 +2386,7 @@ void linphone_call_stop_audio_stream(LinphoneCall *call) {
}
}
void linphone_call_stop_video_stream(LinphoneCall *call) {
static void linphone_call_stop_video_stream(LinphoneCall *call) {
#ifdef VIDEO_ENABLED
if (call->videostream!=NULL){
linphone_reporting_update_media_info(call, LINPHONE_CALL_STATS_VIDEO);
@ -2392,6 +2410,8 @@ static void unset_rtp_profile(LinphoneCall *call, int i){
void linphone_call_stop_media_streams(LinphoneCall *call){
if (call->audiostream || call->videostream) {
if (call->audiostream && call->videostream)
audio_stream_unlink_video(call->audiostream, call->videostream);
linphone_call_stop_audio_stream(call);
linphone_call_stop_video_stream(call);

View file

@ -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;
@ -2845,7 +2854,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 +3437,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);

View file

@ -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,

View file

@ -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 */

View file

@ -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);
@ -293,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 +904,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);
}

View file

@ -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);
@ -236,6 +239,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);
@ -313,12 +321,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");
}
@ -348,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
);
@ -424,23 +431,34 @@ 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->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->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"
, 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"
, 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 +469,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);
@ -478,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));
@ -491,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 [*/
@ -517,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)){
@ -525,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);
@ -641,11 +663,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;
@ -663,27 +685,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);
}

View file

@ -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

View file

@ -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);
@ -986,14 +986,14 @@ gchar *linphone_gtk_get_record_path(const LinphoneAddress *address, gboolean is_
const char **fmts=linphone_core_get_supported_file_formats(linphone_gtk_get_core());
int i;
const char *ext="wav";
#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);
for (i=0;fmts[i]!=NULL;++i){
if (strcmp(fmts[i],"mkv")==0){
ext="mkv";
@ -1025,7 +1025,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);
@ -1642,13 +1642,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);
}
@ -2190,6 +2190,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);
@ -2244,8 +2245,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);
@ -2271,7 +2273,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:*/
@ -2322,18 +2324,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;

View file

@ -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);

@ -1 +1 @@
Subproject commit c9c8032530fd21361cfbe03953fcb20d002dcad5
Subproject commit 964c468de35f6f864967ed23c0d9fc9f5d95b521

2
oRTP

@ -1 +1 @@
Subproject commit 8d9a4ac29b80f6dbb16ef6ca9ed68727a0c7d759
Subproject commit 43a9185fe6baab7a009f730f123f1de07555f5fe

View file

@ -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},