diff --git a/.gitignore b/.gitignore index 2adb3b20b..047ebb08c 100644 --- a/.gitignore +++ b/.gitignore @@ -70,3 +70,5 @@ tester/liblinphone_tester tools/lp-gen-wrappers tools/lpc2xml_test tools/xml2lpc_test +coreapi/help/filetransfer +tester/receive_file.dump diff --git a/build/android/Android.mk b/build/android/Android.mk index bac45a6f3..151d3543c 100755 --- a/build/android/Android.mk +++ b/build/android/Android.mk @@ -162,10 +162,31 @@ LOCAL_CFLAGS += -DHAVE_SILK LOCAL_STATIC_LIBRARIES += libmssilk endif -ifeq ($(BUILD_WEBRTC_ISAC),1) -LOCAL_CFLAGS += -DHAVE_ISAC -LOCAL_STATIC_LIBRARIES += libwebrtc_isacfix_neon -LOCAL_STATIC_LIBRARIES += libwebrtc_spl libwebrtc_isacfix libmsisac +ifneq ($(BUILD_WEBRTC_AECM)$(BUILD_WEBRTC_ISAC),00) +LOCAL_CFLAGS += -DHAVE_WEBRTC +LOCAL_STATIC_LIBRARIES += libmswebrtc +endif +ifneq ($(BUILD_WEBRTC_AECM),0) +LOCAL_STATIC_LIBRARIES += \ + libwebrtc_aecm \ + libwebrtc_apm_utility \ + libwebrtc_spl \ + libwebrtc_system_wrappers +ifeq ($(TARGET_ARCH_ABI), armeabi-v7a) +LOCAL_STATIC_LIBRARIES += \ + libwebrtc_aecm_neon \ + libwebrtc_spl_neon +endif +endif +ifneq ($(BUILD_WEBRTC_ISAC),0) +LOCAL_STATIC_LIBRARIES += \ + libwebrtc_isacfix \ + libwebrtc_spl +ifeq ($(TARGET_ARCH_ABI), armeabi-v7a) +LOCAL_STATIC_LIBRARIES += \ + libwebrtc_isacfix_neon \ + libwebrtc_spl_neon +endif endif ifeq ($(BUILD_G729),1) diff --git a/build/android/liblinphone_tester.mk b/build/android/liblinphone_tester.mk index 8e5221e20..e9a2c8718 100644 --- a/build/android/liblinphone_tester.mk +++ b/build/android/liblinphone_tester.mk @@ -12,21 +12,22 @@ common_SRC_FILES := \ stun_tester.c \ flexisip_tester.c \ tester.c \ - remote_provisioning_tester.c - + remote_provisioning_tester.c \ + quality_reporting_tester.c + common_C_INCLUDES += \ $(LOCAL_PATH) \ $(LOCAL_PATH)/../include \ $(LOCAL_PATH)/../coreapi \ $(LOCAL_PATH)/../oRTP/include \ - $(LOCAL_PATH)/../mediastreamer2/include + $(LOCAL_PATH)/../mediastreamer2/include include $(CLEAR_VARS) -LOCAL_MODULE := liblinphone_tester +LOCAL_MODULE := liblinphone_tester LOCAL_MODULE_FILENAME := liblinphone_tester-$(TARGET_ARCH_ABI) -LOCAL_SRC_FILES += $(common_SRC_FILES) +LOCAL_SRC_FILES += $(common_SRC_FILES) LOCAL_C_INCLUDES = $(common_C_INCLUDES) LOCAL_CFLAGS = -DIN_LINPHONE LOCAL_LDLIBS := -llog diff --git a/build/vsx/LibLinphone/LibLinphone.vcxproj b/build/vsx/LibLinphone/LibLinphone.vcxproj deleted file mode 100644 index bc1f56695..000000000 --- a/build/vsx/LibLinphone/LibLinphone.vcxproj +++ /dev/null @@ -1,279 +0,0 @@ - - - - - Debug - Win32 - - - Debug - ARM - - - Release - Win32 - - - Release - ARM - - - - {08dd0d38-d9b5-4626-b60d-b4d76b571142} - LibLinphone - en-US - 11.0 - - - - DynamicLibrary - true - v110 - false - - - DynamicLibrary - true - v110_wp80 - false - - - DynamicLibrary - false - true - v110 - false - - - DynamicLibrary - false - true - v110_wp80 - false - - - - - - - - $(SolutionDir)$(Platform)\$(Configuration)\ - $(SolutionDir)$(Platform)\$(Configuration)\$(TargetName)\ - - - false - - - - Level4 - $(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\..\oRTP\include;$(ProjectDir)..\..\..\..\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 - NotUsing - false - $(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories) - - - Console - false - false - true - belle-sip_dll.lib;mediastreamer2_dll.lib;ws2_32.lib;ortp_dll.lib;gsm_dll.lib;speex_dll.lib;speexdsp_dll.lib;%(AdditionalDependencies) - $(SolutionDir)$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) - $(TargetDir)$(TargetName)_dll.lib - - - $(TargetDir)$(TargetName)_dll.lib;%(Outputs) - - - - - Level4 - $(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\..\oRTP\include;$(ProjectDir)..\..\..\..\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 - Default - true - NotUsing - false - $(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories) - - - Console - false - false - false - belle-sip_dll.lib;mediastreamer2_dll.lib;ws2_32.lib;ortp_dll.lib;gsm_dll.lib;speex_dll.lib;speexdsp_dll.lib;%(AdditionalDependencies) - $(SolutionDir)$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) - $(TargetDir)$(TargetName)_dll.lib - - - $(TargetDir)$(TargetName)_dll.lib;%(Outputs) - - - - - Level4 - $(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\..\oRTP\include;$(ProjectDir)..\..\..\..\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 - NotUsing - false - $(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories) - false - false - SyncCThrow - - - Console - false - false - true - ws2_32.lib;%(AdditionalDependencies) - $(SolutionDir)$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) - $(TargetDir)$(TargetName)_dll.lib - ole32.lib;%(IgnoreSpecificDefaultLibraries) - - - - - $(TargetDir)$(TargetName)_dll.lib;%(Outputs) - - - - - Level4 - $(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\..\oRTP\include;$(ProjectDir)..\..\..\..\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 - Default - true - NotUsing - false - $(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories) - - - Console - false - false - false - belle-sip_dll.lib;mediastreamer2_dll.lib;ws2_32.lib;ortp_dll.lib;gsm_dll.lib;speex_dll.lib;speexdsp_dll.lib;%(AdditionalDependencies) - $(SolutionDir)$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) - $(TargetDir)$(TargetName)_dll.lib - - - $(TargetDir)$(TargetName)_dll.lib;%(Outputs) - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {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} - - - {5dfa07b4-0be9-46a9-ba32-fdf5a55c580b} - - - - - true - - - true - false - - - - - - - - - - diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8.sln b/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8.sln deleted file mode 100644 index cccf2645c..000000000 --- a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8.sln +++ /dev/null @@ -1,522 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Express 2012 for Windows Phone -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibLinphoneTester-wp8", "LibLinphoneTester-wp8\LibLinphoneTester-wp8.csproj", "{34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}" - ProjectSection(ProjectDependencies) = postProject - {5E94A00B-B14A-4E42-8284-8CB0EF099534} = {5E94A00B-B14A-4E42-8284-8CB0EF099534} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibLinphone", "..\LibLinphone\LibLinphone.vcxproj", "{08DD0D38-D9B5-4626-B60D-B4D76B571142}" - ProjectSection(ProjectDependencies) = postProject - {D22BD217-D0F8-4274-9B3A-F3F35F46482C} = {D22BD217-D0F8-4274-9B3A-F3F35F46482C} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibLinphoneTester", "..\LibLinphoneTester\LibLinphoneTester.vcxproj", "{5E94A00B-B14A-4E42-8284-8CB0EF099534}" - ProjectSection(ProjectDependencies) = postProject - {902DAF1D-EBF1-4D03-B598-143500A50AB4} = {902DAF1D-EBF1-4D03-B598-143500A50AB4} - {08DD0D38-D9B5-4626-B60D-B4D76B571142} = {08DD0D38-D9B5-4626-B60D-B4D76B571142} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "belle-sip", "..\..\..\..\belle-sip\build\windows\belle-sip\belle-sip.vcxproj", "{4C225A82-800B-427B-BA7B-61686A9B347F}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mediastreamer2", "..\..\..\..\mediastreamer2\build\vsx\mediastreamer2\mediastreamer2\mediastreamer2.vcxproj", "{027BAD0E-9179-48C1-9733-7AA7E2C2EC70}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "oRTP", "..\..\..\..\oRTP\build\vsx\oRTP\oRTP\oRTP.vcxproj", "{FFC7B532-0502-4D88-AC98-9E89071CBC97}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libantlr3c", "..\..\..\..\antlr3\runtime\C\build\vsx\libantlr3c\libantlr3c.vcxproj", "{8FA74260-151B-429B-83EF-3CF3EAC8CFD9}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gsm", "..\..\..\..\gsm\build\windows\gsm\gsm\gsm.vcxproj", "{746EA080-5BA9-42C5-9E52-EA421C3F3AFD}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "speex", "..\..\..\..\speex\build\windows\speex\speex\speex.vcxproj", "{D5EC8C11-C1D9-47E3-BB82-A93C300FD902}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "speexdsp", "..\..\..\..\speex\build\windows\speex\speexdsp\speexdsp.vcxproj", "{6BD78980-9C71-4341-8775-AD19E9EC7305}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cunit", "..\..\..\..\cunit\build\windows\cunit\cunit.vcxproj", "{902DAF1D-EBF1-4D03-B598-143500A50AB4}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmswasapi", "..\..\..\..\mswasapi\mswasapi\mswasapi\mswasapi.vcxproj", "{D22BD217-D0F8-4274-9B3A-F3F35F46482C}" - ProjectSection(ProjectDependencies) = postProject - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70} = {027BAD0E-9179-48C1-9733-7AA7E2C2EC70} - {FFC7B532-0502-4D88-AC98-9E89071CBC97} = {FFC7B532-0502-4D88-AC98-9E89071CBC97} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "webrtcaecm", "..\..\..\..\webrtc\build\windows\webrtcaecm\webrtcaecm\webrtcaecm.vcxproj", "{1C4E6DA0-B8C7-4A05-A58E-54A6ED07C8DF}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libilbc-rfc3951", "..\..\..\..\libilbc-rfc3951\build\windows\libilbc-rfc3951\libilbc-rfc3951\libilbc-rfc3951.vcxproj", "{8E216BF3-2DD8-4794-8E97-B1AED301ED4D}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmsilbc", "..\..\..\..\msilbc\build\windows\msilbc\msilbc\msilbc.vcxproj", "{072FAD20-7007-4DA2-B2E7-16CE2B219F67}" - ProjectSection(ProjectDependencies) = postProject - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70} = {027BAD0E-9179-48C1-9733-7AA7E2C2EC70} - {FFC7B532-0502-4D88-AC98-9E89071CBC97} = {FFC7B532-0502-4D88-AC98-9E89071CBC97} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmssilk", "..\..\..\..\mssilk\build\windows\mssilk\mssilk\mssilk.vcxproj", "{36B528F9-FB79-4078-A16B-0A7442581BB7}" - ProjectSection(ProjectDependencies) = postProject - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70} = {027BAD0E-9179-48C1-9733-7AA7E2C2EC70} - {FFC7B532-0502-4D88-AC98-9E89071CBC97} = {FFC7B532-0502-4D88-AC98-9E89071CBC97} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmsamr", "..\..\..\..\msamr\build\windows\msamr\msamr\msamr.vcxproj", "{9924AC72-F96C-4E56-94D9-2B025DA43C6B}" - ProjectSection(ProjectDependencies) = postProject - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70} = {027BAD0E-9179-48C1-9733-7AA7E2C2EC70} - {018A4428-535C-4566-9AE0-E93AFF0D3ED2} = {018A4428-535C-4566-9AE0-E93AFF0D3ED2} - {7AC65D2A-6981-4D17-856D-C37A522739D8} = {7AC65D2A-6981-4D17-856D-C37A522739D8} - {88191E75-2993-48D7-AA76-652F274EF0FE} = {88191E75-2993-48D7-AA76-652F274EF0FE} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vo-amrwbenc", "..\..\..\..\msamr\build\windows\msamr\vo-amrwbenc\vo-amrwbenc.vcxproj", "{018A4428-535C-4566-9AE0-E93AFF0D3ED2}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opencore_amrnb", "..\..\..\..\msamr\build\windows\msamr\opencore_amrnb\opencore_amrnb.vcxproj", "{88191E75-2993-48D7-AA76-652F274EF0FE}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opencore_amrwb", "..\..\..\..\msamr\build\windows\msamr\opencore_amrwb\opencore_amrwb.vcxproj", "{7AC65D2A-6981-4D17-856D-C37A522739D8}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "polarssl", "..\..\..\..\polarssl\build\windows\polarssl\polarssl\polarssl.vcxproj", "{E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tunnel", "..\..\..\..\tunnel\build\windows\tunnel\tunnel\tunnel.vcxproj", "{59500DD1-B192-4DDF-A402-8A8E3739E032}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxml2", "..\libxml2\libxml2\libxml2.vcxproj", "{5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Debug|ARM = Debug|ARM - Debug|Mixed Platforms = Debug|Mixed Platforms - Debug|Win32 = Debug|Win32 - Debug|x86 = Debug|x86 - Release|Any CPU = Release|Any CPU - Release|ARM = Release|ARM - Release|Mixed Platforms = Release|Mixed Platforms - Release|Win32 = Release|Win32 - Release|x86 = Release|x86 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|Any CPU.Build.0 = Debug|Any CPU - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|Any CPU.Deploy.0 = Debug|Any CPU - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|ARM.ActiveCfg = Debug|ARM - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|ARM.Build.0 = Debug|ARM - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|ARM.Deploy.0 = Debug|ARM - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|Mixed Platforms.ActiveCfg = Debug|ARM - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|Mixed Platforms.Build.0 = Debug|ARM - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|Mixed Platforms.Deploy.0 = Debug|ARM - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|Win32.ActiveCfg = Debug|x86 - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|Win32.Build.0 = Debug|x86 - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|Win32.Deploy.0 = Debug|x86 - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|x86.ActiveCfg = Debug|x86 - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|x86.Build.0 = Debug|x86 - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|x86.Deploy.0 = Debug|x86 - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|Any CPU.ActiveCfg = Release|Any CPU - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|Any CPU.Build.0 = Release|Any CPU - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|Any CPU.Deploy.0 = Release|Any CPU - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|ARM.ActiveCfg = Release|ARM - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|ARM.Build.0 = Release|ARM - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|ARM.Deploy.0 = Release|ARM - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|Mixed Platforms.ActiveCfg = Release|x86 - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|Mixed Platforms.Build.0 = Release|x86 - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|Mixed Platforms.Deploy.0 = Release|x86 - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|Win32.ActiveCfg = Release|x86 - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|Win32.Build.0 = Release|x86 - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|Win32.Deploy.0 = Release|x86 - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|x86.ActiveCfg = Release|x86 - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|x86.Build.0 = Release|x86 - {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|x86.Deploy.0 = Release|x86 - {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Debug|ARM.ActiveCfg = Debug|ARM - {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Debug|ARM.Build.0 = Debug|ARM - {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Debug|Mixed Platforms.ActiveCfg = Debug|ARM - {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Debug|Mixed Platforms.Build.0 = Debug|ARM - {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Debug|Win32.ActiveCfg = Debug|Win32 - {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Debug|Win32.Build.0 = Debug|Win32 - {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Debug|x86.ActiveCfg = Debug|Win32 - {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Debug|x86.Build.0 = Debug|Win32 - {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Release|Any CPU.ActiveCfg = Release|Win32 - {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Release|ARM.ActiveCfg = Release|ARM - {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Release|ARM.Build.0 = Release|ARM - {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Release|Mixed Platforms.Build.0 = Release|Win32 - {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Release|Win32.ActiveCfg = Release|Win32 - {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Release|Win32.Build.0 = Release|Win32 - {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Release|x86.ActiveCfg = Release|Win32 - {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Release|x86.Build.0 = Release|Win32 - {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Debug|ARM.ActiveCfg = Debug|ARM - {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Debug|ARM.Build.0 = Debug|ARM - {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Debug|Mixed Platforms.ActiveCfg = Debug|ARM - {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Debug|Mixed Platforms.Build.0 = Debug|ARM - {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Debug|Win32.ActiveCfg = Debug|Win32 - {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Debug|Win32.Build.0 = Debug|Win32 - {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Debug|x86.ActiveCfg = Debug|Win32 - {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Debug|x86.Build.0 = Debug|Win32 - {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Release|Any CPU.ActiveCfg = Release|Win32 - {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Release|ARM.ActiveCfg = Release|ARM - {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Release|ARM.Build.0 = Release|ARM - {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Release|Mixed Platforms.Build.0 = Release|Win32 - {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Release|Win32.ActiveCfg = Release|Win32 - {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Release|Win32.Build.0 = Release|Win32 - {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Release|x86.ActiveCfg = Release|Win32 - {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Release|x86.Build.0 = Release|Win32 - {4C225A82-800B-427B-BA7B-61686A9B347F}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {4C225A82-800B-427B-BA7B-61686A9B347F}.Debug|ARM.ActiveCfg = Debug|ARM - {4C225A82-800B-427B-BA7B-61686A9B347F}.Debug|ARM.Build.0 = Debug|ARM - {4C225A82-800B-427B-BA7B-61686A9B347F}.Debug|Mixed Platforms.ActiveCfg = Debug|ARM - {4C225A82-800B-427B-BA7B-61686A9B347F}.Debug|Mixed Platforms.Build.0 = Debug|ARM - {4C225A82-800B-427B-BA7B-61686A9B347F}.Debug|Win32.ActiveCfg = Debug|Win32 - {4C225A82-800B-427B-BA7B-61686A9B347F}.Debug|Win32.Build.0 = Debug|Win32 - {4C225A82-800B-427B-BA7B-61686A9B347F}.Debug|x86.ActiveCfg = Debug|Win32 - {4C225A82-800B-427B-BA7B-61686A9B347F}.Debug|x86.Build.0 = Debug|Win32 - {4C225A82-800B-427B-BA7B-61686A9B347F}.Release|Any CPU.ActiveCfg = Release|Win32 - {4C225A82-800B-427B-BA7B-61686A9B347F}.Release|ARM.ActiveCfg = Release|ARM - {4C225A82-800B-427B-BA7B-61686A9B347F}.Release|ARM.Build.0 = Release|ARM - {4C225A82-800B-427B-BA7B-61686A9B347F}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {4C225A82-800B-427B-BA7B-61686A9B347F}.Release|Mixed Platforms.Build.0 = Release|Win32 - {4C225A82-800B-427B-BA7B-61686A9B347F}.Release|Win32.ActiveCfg = Release|Win32 - {4C225A82-800B-427B-BA7B-61686A9B347F}.Release|Win32.Build.0 = Release|Win32 - {4C225A82-800B-427B-BA7B-61686A9B347F}.Release|x86.ActiveCfg = Release|Win32 - {4C225A82-800B-427B-BA7B-61686A9B347F}.Release|x86.Build.0 = Release|Win32 - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Debug|ARM.ActiveCfg = Debug|ARM - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Debug|ARM.Build.0 = Debug|ARM - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Debug|Mixed Platforms.ActiveCfg = Debug|ARM - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Debug|Mixed Platforms.Build.0 = Debug|ARM - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Debug|Win32.ActiveCfg = Debug|Win32 - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Debug|Win32.Build.0 = Debug|Win32 - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Debug|x86.ActiveCfg = Debug|Win32 - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Debug|x86.Build.0 = Debug|Win32 - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Release|Any CPU.ActiveCfg = Release|Win32 - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Release|ARM.ActiveCfg = Release|ARM - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Release|ARM.Build.0 = Release|ARM - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Release|Mixed Platforms.Build.0 = Release|Win32 - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Release|Win32.ActiveCfg = Release|Win32 - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Release|Win32.Build.0 = Release|Win32 - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Release|x86.ActiveCfg = Release|Win32 - {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Release|x86.Build.0 = Release|Win32 - {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Debug|ARM.ActiveCfg = Debug|ARM - {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Debug|ARM.Build.0 = Debug|ARM - {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Debug|Mixed Platforms.ActiveCfg = Debug|ARM - {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Debug|Mixed Platforms.Build.0 = Debug|ARM - {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Debug|Win32.ActiveCfg = Debug|Win32 - {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Debug|Win32.Build.0 = Debug|Win32 - {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Debug|x86.ActiveCfg = Debug|Win32 - {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Debug|x86.Build.0 = Debug|Win32 - {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Release|Any CPU.ActiveCfg = Release|Win32 - {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Release|ARM.ActiveCfg = Release|ARM - {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Release|ARM.Build.0 = Release|ARM - {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Release|Mixed Platforms.Build.0 = Release|Win32 - {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Release|Win32.ActiveCfg = Release|Win32 - {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Release|Win32.Build.0 = Release|Win32 - {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Release|x86.ActiveCfg = Release|Win32 - {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Release|x86.Build.0 = Release|Win32 - {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Debug|ARM.ActiveCfg = Debug|ARM - {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Debug|ARM.Build.0 = Debug|ARM - {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Debug|Mixed Platforms.ActiveCfg = Debug|ARM - {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Debug|Mixed Platforms.Build.0 = Debug|ARM - {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Debug|Win32.ActiveCfg = Debug|Win32 - {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Debug|Win32.Build.0 = Debug|Win32 - {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Debug|x86.ActiveCfg = Debug|Win32 - {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Debug|x86.Build.0 = Debug|Win32 - {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Release|Any CPU.ActiveCfg = Release|Win32 - {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Release|ARM.ActiveCfg = Release|ARM - {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Release|ARM.Build.0 = Release|ARM - {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Release|Mixed Platforms.Build.0 = Release|Win32 - {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Release|Win32.ActiveCfg = Release|Win32 - {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Release|Win32.Build.0 = Release|Win32 - {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Release|x86.ActiveCfg = Release|Win32 - {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Release|x86.Build.0 = Release|Win32 - {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Debug|ARM.ActiveCfg = Debug|ARM - {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Debug|ARM.Build.0 = Debug|ARM - {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Debug|Mixed Platforms.ActiveCfg = Debug|ARM - {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Debug|Mixed Platforms.Build.0 = Debug|ARM - {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Debug|Win32.ActiveCfg = Debug|Win32 - {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Debug|Win32.Build.0 = Debug|Win32 - {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Debug|x86.ActiveCfg = Debug|Win32 - {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Debug|x86.Build.0 = Debug|Win32 - {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Release|Any CPU.ActiveCfg = Release|Win32 - {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Release|ARM.ActiveCfg = Release|ARM - {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Release|ARM.Build.0 = Release|ARM - {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Release|Mixed Platforms.Build.0 = Release|Win32 - {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Release|Win32.ActiveCfg = Release|Win32 - {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Release|Win32.Build.0 = Release|Win32 - {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Release|x86.ActiveCfg = Release|Win32 - {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Release|x86.Build.0 = Release|Win32 - {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Debug|ARM.ActiveCfg = Debug|ARM - {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Debug|ARM.Build.0 = Debug|ARM - {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Debug|Mixed Platforms.ActiveCfg = Debug|ARM - {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Debug|Mixed Platforms.Build.0 = Debug|ARM - {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Debug|Win32.ActiveCfg = Debug|Win32 - {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Debug|Win32.Build.0 = Debug|Win32 - {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Debug|x86.ActiveCfg = Debug|Win32 - {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Debug|x86.Build.0 = Debug|Win32 - {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Release|Any CPU.ActiveCfg = Release|Win32 - {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Release|ARM.ActiveCfg = Release|ARM - {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Release|ARM.Build.0 = Release|ARM - {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Release|Mixed Platforms.Build.0 = Release|Win32 - {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Release|Win32.ActiveCfg = Release|Win32 - {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Release|Win32.Build.0 = Release|Win32 - {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Release|x86.ActiveCfg = Release|Win32 - {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Release|x86.Build.0 = Release|Win32 - {6BD78980-9C71-4341-8775-AD19E9EC7305}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {6BD78980-9C71-4341-8775-AD19E9EC7305}.Debug|ARM.ActiveCfg = Debug|ARM - {6BD78980-9C71-4341-8775-AD19E9EC7305}.Debug|ARM.Build.0 = Debug|ARM - {6BD78980-9C71-4341-8775-AD19E9EC7305}.Debug|Mixed Platforms.ActiveCfg = Debug|ARM - {6BD78980-9C71-4341-8775-AD19E9EC7305}.Debug|Mixed Platforms.Build.0 = Debug|ARM - {6BD78980-9C71-4341-8775-AD19E9EC7305}.Debug|Win32.ActiveCfg = Debug|Win32 - {6BD78980-9C71-4341-8775-AD19E9EC7305}.Debug|Win32.Build.0 = Debug|Win32 - {6BD78980-9C71-4341-8775-AD19E9EC7305}.Debug|x86.ActiveCfg = Debug|Win32 - {6BD78980-9C71-4341-8775-AD19E9EC7305}.Debug|x86.Build.0 = Debug|Win32 - {6BD78980-9C71-4341-8775-AD19E9EC7305}.Release|Any CPU.ActiveCfg = Release|Win32 - {6BD78980-9C71-4341-8775-AD19E9EC7305}.Release|ARM.ActiveCfg = Release|ARM - {6BD78980-9C71-4341-8775-AD19E9EC7305}.Release|ARM.Build.0 = Release|ARM - {6BD78980-9C71-4341-8775-AD19E9EC7305}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {6BD78980-9C71-4341-8775-AD19E9EC7305}.Release|Mixed Platforms.Build.0 = Release|Win32 - {6BD78980-9C71-4341-8775-AD19E9EC7305}.Release|Win32.ActiveCfg = Release|Win32 - {6BD78980-9C71-4341-8775-AD19E9EC7305}.Release|Win32.Build.0 = Release|Win32 - {6BD78980-9C71-4341-8775-AD19E9EC7305}.Release|x86.ActiveCfg = Release|Win32 - {6BD78980-9C71-4341-8775-AD19E9EC7305}.Release|x86.Build.0 = Release|Win32 - {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Debug|ARM.ActiveCfg = Debug|ARM - {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Debug|ARM.Build.0 = Debug|ARM - {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Debug|Mixed Platforms.ActiveCfg = Debug|ARM - {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Debug|Mixed Platforms.Build.0 = Debug|ARM - {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Debug|Win32.ActiveCfg = Debug|Win32 - {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Debug|Win32.Build.0 = Debug|Win32 - {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Debug|x86.ActiveCfg = Debug|Win32 - {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Debug|x86.Build.0 = Debug|Win32 - {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Release|Any CPU.ActiveCfg = Release|Win32 - {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Release|ARM.ActiveCfg = Release|ARM - {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Release|ARM.Build.0 = Release|ARM - {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Release|Mixed Platforms.Build.0 = Release|Win32 - {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Release|Win32.ActiveCfg = Release|Win32 - {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Release|Win32.Build.0 = Release|Win32 - {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Release|x86.ActiveCfg = Release|Win32 - {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Release|x86.Build.0 = Release|Win32 - {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Debug|ARM.ActiveCfg = Debug|ARM - {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Debug|ARM.Build.0 = Debug|ARM - {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Debug|Win32.ActiveCfg = Debug|Win32 - {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Debug|Win32.Build.0 = Debug|Win32 - {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Debug|x86.ActiveCfg = Debug|Win32 - {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Debug|x86.Build.0 = Debug|Win32 - {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Release|Any CPU.ActiveCfg = Release|Win32 - {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Release|ARM.ActiveCfg = Release|ARM - {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Release|ARM.Build.0 = Release|ARM - {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Release|Mixed Platforms.Build.0 = Release|Win32 - {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Release|Win32.ActiveCfg = Release|Win32 - {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Release|Win32.Build.0 = Release|Win32 - {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Release|x86.ActiveCfg = Release|Win32 - {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Release|x86.Build.0 = Release|Win32 - {1C4E6DA0-B8C7-4A05-A58E-54A6ED07C8DF}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {1C4E6DA0-B8C7-4A05-A58E-54A6ED07C8DF}.Debug|ARM.ActiveCfg = Debug|ARM - {1C4E6DA0-B8C7-4A05-A58E-54A6ED07C8DF}.Debug|ARM.Build.0 = Debug|ARM - {1C4E6DA0-B8C7-4A05-A58E-54A6ED07C8DF}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {1C4E6DA0-B8C7-4A05-A58E-54A6ED07C8DF}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {1C4E6DA0-B8C7-4A05-A58E-54A6ED07C8DF}.Debug|Win32.ActiveCfg = Debug|Win32 - {1C4E6DA0-B8C7-4A05-A58E-54A6ED07C8DF}.Debug|Win32.Build.0 = Debug|Win32 - {1C4E6DA0-B8C7-4A05-A58E-54A6ED07C8DF}.Debug|x86.ActiveCfg = Debug|Win32 - {1C4E6DA0-B8C7-4A05-A58E-54A6ED07C8DF}.Debug|x86.Build.0 = Debug|Win32 - {1C4E6DA0-B8C7-4A05-A58E-54A6ED07C8DF}.Release|Any CPU.ActiveCfg = Release|Win32 - {1C4E6DA0-B8C7-4A05-A58E-54A6ED07C8DF}.Release|ARM.ActiveCfg = Release|ARM - {1C4E6DA0-B8C7-4A05-A58E-54A6ED07C8DF}.Release|ARM.Build.0 = Release|ARM - {1C4E6DA0-B8C7-4A05-A58E-54A6ED07C8DF}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {1C4E6DA0-B8C7-4A05-A58E-54A6ED07C8DF}.Release|Mixed Platforms.Build.0 = Release|Win32 - {1C4E6DA0-B8C7-4A05-A58E-54A6ED07C8DF}.Release|Win32.ActiveCfg = Release|Win32 - {1C4E6DA0-B8C7-4A05-A58E-54A6ED07C8DF}.Release|Win32.Build.0 = Release|Win32 - {1C4E6DA0-B8C7-4A05-A58E-54A6ED07C8DF}.Release|x86.ActiveCfg = Release|Win32 - {1C4E6DA0-B8C7-4A05-A58E-54A6ED07C8DF}.Release|x86.Build.0 = Release|Win32 - {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Debug|ARM.ActiveCfg = Debug|ARM - {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Debug|ARM.Build.0 = Debug|ARM - {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Debug|Win32.ActiveCfg = Debug|Win32 - {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Debug|Win32.Build.0 = Debug|Win32 - {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Debug|x86.ActiveCfg = Debug|Win32 - {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Debug|x86.Build.0 = Debug|Win32 - {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Release|Any CPU.ActiveCfg = Release|Win32 - {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Release|ARM.ActiveCfg = Release|ARM - {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Release|ARM.Build.0 = Release|ARM - {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Release|Mixed Platforms.Build.0 = Release|Win32 - {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Release|Win32.ActiveCfg = Release|Win32 - {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Release|Win32.Build.0 = Release|Win32 - {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Release|x86.ActiveCfg = Release|Win32 - {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Release|x86.Build.0 = Release|Win32 - {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Debug|ARM.ActiveCfg = Debug|ARM - {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Debug|ARM.Build.0 = Debug|ARM - {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Debug|Win32.ActiveCfg = Debug|Win32 - {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Debug|Win32.Build.0 = Debug|Win32 - {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Debug|x86.ActiveCfg = Debug|Win32 - {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Debug|x86.Build.0 = Debug|Win32 - {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Release|Any CPU.ActiveCfg = Release|Win32 - {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Release|ARM.ActiveCfg = Release|ARM - {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Release|ARM.Build.0 = Release|ARM - {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Release|Mixed Platforms.Build.0 = Release|Win32 - {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Release|Win32.ActiveCfg = Release|Win32 - {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Release|Win32.Build.0 = Release|Win32 - {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Release|x86.ActiveCfg = Release|Win32 - {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Release|x86.Build.0 = Release|Win32 - {36B528F9-FB79-4078-A16B-0A7442581BB7}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {36B528F9-FB79-4078-A16B-0A7442581BB7}.Debug|ARM.ActiveCfg = Debug|ARM - {36B528F9-FB79-4078-A16B-0A7442581BB7}.Debug|ARM.Build.0 = Debug|ARM - {36B528F9-FB79-4078-A16B-0A7442581BB7}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {36B528F9-FB79-4078-A16B-0A7442581BB7}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {36B528F9-FB79-4078-A16B-0A7442581BB7}.Debug|Win32.ActiveCfg = Debug|Win32 - {36B528F9-FB79-4078-A16B-0A7442581BB7}.Debug|Win32.Build.0 = Debug|Win32 - {36B528F9-FB79-4078-A16B-0A7442581BB7}.Debug|x86.ActiveCfg = Debug|Win32 - {36B528F9-FB79-4078-A16B-0A7442581BB7}.Debug|x86.Build.0 = Debug|Win32 - {36B528F9-FB79-4078-A16B-0A7442581BB7}.Release|Any CPU.ActiveCfg = Release|Win32 - {36B528F9-FB79-4078-A16B-0A7442581BB7}.Release|ARM.ActiveCfg = Release|ARM - {36B528F9-FB79-4078-A16B-0A7442581BB7}.Release|ARM.Build.0 = Release|ARM - {36B528F9-FB79-4078-A16B-0A7442581BB7}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {36B528F9-FB79-4078-A16B-0A7442581BB7}.Release|Mixed Platforms.Build.0 = Release|Win32 - {36B528F9-FB79-4078-A16B-0A7442581BB7}.Release|Win32.ActiveCfg = Release|Win32 - {36B528F9-FB79-4078-A16B-0A7442581BB7}.Release|Win32.Build.0 = Release|Win32 - {36B528F9-FB79-4078-A16B-0A7442581BB7}.Release|x86.ActiveCfg = Release|Win32 - {36B528F9-FB79-4078-A16B-0A7442581BB7}.Release|x86.Build.0 = Release|Win32 - {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Debug|ARM.ActiveCfg = Debug|ARM - {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Debug|ARM.Build.0 = Debug|ARM - {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Debug|Win32.ActiveCfg = Debug|Win32 - {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Debug|Win32.Build.0 = Debug|Win32 - {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Debug|x86.ActiveCfg = Debug|Win32 - {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Debug|x86.Build.0 = Debug|Win32 - {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Release|Any CPU.ActiveCfg = Release|Win32 - {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Release|ARM.ActiveCfg = Release|ARM - {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Release|ARM.Build.0 = Release|ARM - {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Release|Mixed Platforms.Build.0 = Release|Win32 - {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Release|Win32.ActiveCfg = Release|Win32 - {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Release|Win32.Build.0 = Release|Win32 - {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Release|x86.ActiveCfg = Release|Win32 - {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Release|x86.Build.0 = Release|Win32 - {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Debug|ARM.ActiveCfg = Debug|ARM - {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Debug|ARM.Build.0 = Debug|ARM - {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Debug|Win32.ActiveCfg = Debug|Win32 - {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Debug|Win32.Build.0 = Debug|Win32 - {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Debug|x86.ActiveCfg = Debug|Win32 - {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Debug|x86.Build.0 = Debug|Win32 - {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Release|Any CPU.ActiveCfg = Release|Win32 - {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Release|ARM.ActiveCfg = Release|ARM - {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Release|ARM.Build.0 = Release|ARM - {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Release|Mixed Platforms.Build.0 = Release|Win32 - {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Release|Win32.ActiveCfg = Release|Win32 - {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Release|Win32.Build.0 = Release|Win32 - {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Release|x86.ActiveCfg = Release|Win32 - {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Release|x86.Build.0 = Release|Win32 - {88191E75-2993-48D7-AA76-652F274EF0FE}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {88191E75-2993-48D7-AA76-652F274EF0FE}.Debug|ARM.ActiveCfg = Debug|ARM - {88191E75-2993-48D7-AA76-652F274EF0FE}.Debug|ARM.Build.0 = Debug|ARM - {88191E75-2993-48D7-AA76-652F274EF0FE}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {88191E75-2993-48D7-AA76-652F274EF0FE}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {88191E75-2993-48D7-AA76-652F274EF0FE}.Debug|Win32.ActiveCfg = Debug|Win32 - {88191E75-2993-48D7-AA76-652F274EF0FE}.Debug|Win32.Build.0 = Debug|Win32 - {88191E75-2993-48D7-AA76-652F274EF0FE}.Debug|x86.ActiveCfg = Debug|Win32 - {88191E75-2993-48D7-AA76-652F274EF0FE}.Debug|x86.Build.0 = Debug|Win32 - {88191E75-2993-48D7-AA76-652F274EF0FE}.Release|Any CPU.ActiveCfg = Release|Win32 - {88191E75-2993-48D7-AA76-652F274EF0FE}.Release|ARM.ActiveCfg = Release|ARM - {88191E75-2993-48D7-AA76-652F274EF0FE}.Release|ARM.Build.0 = Release|ARM - {88191E75-2993-48D7-AA76-652F274EF0FE}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {88191E75-2993-48D7-AA76-652F274EF0FE}.Release|Mixed Platforms.Build.0 = Release|Win32 - {88191E75-2993-48D7-AA76-652F274EF0FE}.Release|Win32.ActiveCfg = Release|Win32 - {88191E75-2993-48D7-AA76-652F274EF0FE}.Release|Win32.Build.0 = Release|Win32 - {88191E75-2993-48D7-AA76-652F274EF0FE}.Release|x86.ActiveCfg = Release|Win32 - {88191E75-2993-48D7-AA76-652F274EF0FE}.Release|x86.Build.0 = Release|Win32 - {7AC65D2A-6981-4D17-856D-C37A522739D8}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {7AC65D2A-6981-4D17-856D-C37A522739D8}.Debug|ARM.ActiveCfg = Debug|ARM - {7AC65D2A-6981-4D17-856D-C37A522739D8}.Debug|ARM.Build.0 = Debug|ARM - {7AC65D2A-6981-4D17-856D-C37A522739D8}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {7AC65D2A-6981-4D17-856D-C37A522739D8}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {7AC65D2A-6981-4D17-856D-C37A522739D8}.Debug|Win32.ActiveCfg = Debug|Win32 - {7AC65D2A-6981-4D17-856D-C37A522739D8}.Debug|Win32.Build.0 = Debug|Win32 - {7AC65D2A-6981-4D17-856D-C37A522739D8}.Debug|x86.ActiveCfg = Debug|Win32 - {7AC65D2A-6981-4D17-856D-C37A522739D8}.Debug|x86.Build.0 = Debug|Win32 - {7AC65D2A-6981-4D17-856D-C37A522739D8}.Release|Any CPU.ActiveCfg = Release|Win32 - {7AC65D2A-6981-4D17-856D-C37A522739D8}.Release|ARM.ActiveCfg = Release|ARM - {7AC65D2A-6981-4D17-856D-C37A522739D8}.Release|ARM.Build.0 = Release|ARM - {7AC65D2A-6981-4D17-856D-C37A522739D8}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {7AC65D2A-6981-4D17-856D-C37A522739D8}.Release|Mixed Platforms.Build.0 = Release|Win32 - {7AC65D2A-6981-4D17-856D-C37A522739D8}.Release|Win32.ActiveCfg = Release|Win32 - {7AC65D2A-6981-4D17-856D-C37A522739D8}.Release|Win32.Build.0 = Release|Win32 - {7AC65D2A-6981-4D17-856D-C37A522739D8}.Release|x86.ActiveCfg = Release|Win32 - {7AC65D2A-6981-4D17-856D-C37A522739D8}.Release|x86.Build.0 = Release|Win32 - {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Debug|ARM.ActiveCfg = Debug|ARM - {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Debug|ARM.Build.0 = Debug|ARM - {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Debug|Win32.ActiveCfg = Debug|Win32 - {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Debug|Win32.Build.0 = Debug|Win32 - {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Debug|x86.ActiveCfg = Debug|Win32 - {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Debug|x86.Build.0 = Debug|Win32 - {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Release|Any CPU.ActiveCfg = Release|Win32 - {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Release|ARM.ActiveCfg = Release|ARM - {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Release|ARM.Build.0 = Release|ARM - {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Release|Mixed Platforms.Build.0 = Release|Win32 - {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Release|Win32.ActiveCfg = Release|Win32 - {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Release|Win32.Build.0 = Release|Win32 - {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Release|x86.ActiveCfg = Release|Win32 - {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Release|x86.Build.0 = Release|Win32 - {59500DD1-B192-4DDF-A402-8A8E3739E032}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {59500DD1-B192-4DDF-A402-8A8E3739E032}.Debug|ARM.ActiveCfg = Debug|ARM - {59500DD1-B192-4DDF-A402-8A8E3739E032}.Debug|ARM.Build.0 = Debug|ARM - {59500DD1-B192-4DDF-A402-8A8E3739E032}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {59500DD1-B192-4DDF-A402-8A8E3739E032}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {59500DD1-B192-4DDF-A402-8A8E3739E032}.Debug|Win32.ActiveCfg = Debug|Win32 - {59500DD1-B192-4DDF-A402-8A8E3739E032}.Debug|Win32.Build.0 = Debug|Win32 - {59500DD1-B192-4DDF-A402-8A8E3739E032}.Debug|x86.ActiveCfg = Debug|Win32 - {59500DD1-B192-4DDF-A402-8A8E3739E032}.Debug|x86.Build.0 = Debug|Win32 - {59500DD1-B192-4DDF-A402-8A8E3739E032}.Release|Any CPU.ActiveCfg = Release|Win32 - {59500DD1-B192-4DDF-A402-8A8E3739E032}.Release|ARM.ActiveCfg = Release|ARM - {59500DD1-B192-4DDF-A402-8A8E3739E032}.Release|ARM.Build.0 = Release|ARM - {59500DD1-B192-4DDF-A402-8A8E3739E032}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {59500DD1-B192-4DDF-A402-8A8E3739E032}.Release|Mixed Platforms.Build.0 = Release|Win32 - {59500DD1-B192-4DDF-A402-8A8E3739E032}.Release|Win32.ActiveCfg = Release|Win32 - {59500DD1-B192-4DDF-A402-8A8E3739E032}.Release|Win32.Build.0 = Release|Win32 - {59500DD1-B192-4DDF-A402-8A8E3739E032}.Release|x86.ActiveCfg = Release|Win32 - {59500DD1-B192-4DDF-A402-8A8E3739E032}.Release|x86.Build.0 = Release|Win32 - {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Debug|ARM.ActiveCfg = Debug|ARM - {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Debug|ARM.Build.0 = Debug|ARM - {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Debug|Win32.ActiveCfg = Debug|Win32 - {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Debug|Win32.Build.0 = Debug|Win32 - {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Debug|x86.ActiveCfg = Debug|Win32 - {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Debug|x86.Build.0 = Debug|Win32 - {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Release|Any CPU.ActiveCfg = Release|Win32 - {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Release|ARM.ActiveCfg = Release|ARM - {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Release|ARM.Build.0 = Release|ARM - {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Release|Mixed Platforms.Build.0 = Release|Win32 - {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Release|Win32.ActiveCfg = Release|Win32 - {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Release|Win32.Build.0 = Release|Win32 - {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Release|x86.ActiveCfg = Release|Win32 - {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Release|x86.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/marie_early_rc b/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/marie_early_rc deleted file mode 100644 index 65934c3f3..000000000 --- a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/marie_early_rc +++ /dev/null @@ -1,45 +0,0 @@ -[sip] -sip_port=5082 -sip_tcp_port=5082 -sip_tls_port=5083 -default_proxy=0 -ping_with_options=0 -register_only_when_network_is_up=0 -incoming_calls_early_media=1 - -[auth_info_0] -username=marie -userid=marie -passwd=secret -realm="sip.example.org" - - -[proxy_0] -reg_proxy=sip.example.org;transport=tcp -reg_route=sip.example.org;transport=tcp;lr -reg_identity=sip:marie@sip.example.org -reg_expires=3600 -reg_sendregister=1 -publish=0 -dial_escape_plus=0 - -[friend_0] -url="Paupoche" -pol=accept -subscribe=0 - - -[rtp] -audio_rtp_port=8070 -video_rtp_port=8072 - -[video] -display=0 -capture=0 -show_local=0 -size=vga -enabled=0 -self_view=0 -automatically_initiate=0 -automatically_accept=0 -device=StaticImage: Static picture \ No newline at end of file diff --git a/build/vsx/libxml2/libxml2/libxml2.vcxproj b/build/vsx/libxml2/libxml2/libxml2.vcxproj deleted file mode 100644 index fb873bf4e..000000000 --- a/build/vsx/libxml2/libxml2/libxml2.vcxproj +++ /dev/null @@ -1,249 +0,0 @@ - - - - - Debug - Win32 - - - Debug - ARM - - - Release - Win32 - - - Release - ARM - - - - {5dfa07b4-0be9-46a9-ba32-fdf5a55c580b} - libxml2 - en-US - 11.0 - - - - DynamicLibrary - true - v110 - false - - - DynamicLibrary - true - v110_wp80 - false - - - DynamicLibrary - false - true - v110 - false - - - DynamicLibrary - false - true - v110_wp80 - false - - - - - - - - $(SolutionDir)$(Platform)\$(Configuration)\ - $(SolutionDir)$(Platform)\$(Configuration)\$(TargetName)\ - - - false - - - - Level4 - $(SolutionDir)$(Platform)\$(Configuration)\include;$(ProjectDir)..\..\..\..\..\libxml2\include;$(ProjectDir)..\..\..\..\..\libxml2\win32\VC10;%(AdditionalIncludeDirectories) - _WIN32;_WINDLL;_USRDLL;_CRT_SECURE_NO_WARNINGS;HAVE_WIN32_THREADS;HAVE_COMPILER_TLS;UNICODE;%(PreprocessorDefinitions) - LIBXML_MODULES_ENABLED - false - Default - NotUsing - false - $(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories) - $(ProjectDir)libxml2_port.h - - - Console - false - false - true - $(TargetDir)$(TargetName)_dll.lib - Ws2_32.lib;%(AdditionalDependencies) - - - install_headers.bat $(SolutionDir)$(Platform)\$(Configuration)\include - - - $(TargetDir)$(TargetName)_dll.lib;%(Outputs) - - - - - Level4 - MaxSpeed - $(SolutionDir)$(Platform)\$(Configuration)\include;$(ProjectDir)..\..\..\..\..\libxml2\include;$(ProjectDir)..\..\..\..\..\libxml2\win32\VC10;%(AdditionalIncludeDirectories) - _WIN32;_WINDLL;_USRDLL;NDEBUG;_CRT_SECURE_NO_WARNINGS;HAVE_WIN32_THREADS;HAVE_COMPILER_TLS;UNICODE;%(PreprocessorDefinitions) - LIBXML_MODULES_ENABLED - true - true - Default - true - NotUsing - false - $(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories) - $(ProjectDir)libxml2_port.h - - - Console - false - false - false - $(TargetDir)$(TargetName)_dll.lib - Ws2_32.lib;%(AdditionalDependencies) - - - install_headers.bat $(SolutionDir)$(Platform)\$(Configuration)\include - - - $(TargetDir)$(TargetName)_dll.lib;%(Outputs) - - - - - Level4 - $(SolutionDir)$(Platform)\$(Configuration)\include;$(ProjectDir)..\..\..\..\..\libxml2\include;$(ProjectDir)..\..\..\..\..\libxml2\win32\VC10;%(AdditionalIncludeDirectories) - _WIN32;WIN32;_WINDLL;_USRDLL;_CRT_SECURE_NO_WARNINGS;HAVE_WIN32_THREADS;HAVE_COMPILER_TLS;UNICODE;%(PreprocessorDefinitions) - LIBXML_MODULES_ENABLED - false - Default - NotUsing - false - $(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories) - $(ProjectDir)libxml2_port.h - - - Console - false - false - true - $(TargetDir)$(TargetName)_dll.lib - Ws2_32.lib;%(AdditionalDependencies) - - - install_headers.bat $(SolutionDir)$(Platform)\$(Configuration)\include - - - $(TargetDir)$(TargetName)_dll.lib;%(Outputs) - - - - - Level4 - MaxSpeed - $(SolutionDir)$(Platform)\$(Configuration)\include;$(ProjectDir)..\..\..\..\..\libxml2\include;$(ProjectDir)..\..\..\..\..\libxml2\win32\VC10;%(AdditionalIncludeDirectories) - _WIN32;_WINDLL;_USRDLL;NDEBUG;_CRT_SECURE_NO_WARNINGS;HAVE_WIN32_THREADS;HAVE_COMPILER_TLS;UNICODE;%(PreprocessorDefinitions) - LIBXML_MODULES_ENABLED - true - true - Default - true - NotUsing - false - $(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories) - $(ProjectDir)libxml2_port.h - - - Console - false - false - false - $(TargetDir)$(TargetName)_dll.lib - Ws2_32.lib;%(AdditionalDependencies) - - - install_headers.bat $(SolutionDir)$(Platform)\$(Configuration)\include - - - $(TargetDir)$(TargetName)_dll.lib;%(Outputs) - - - - - true - - - true - false - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/build/wp8/LibLinphone.vcxproj b/build/wp8/LibLinphone.vcxproj new file mode 100644 index 000000000..ed1e7e847 --- /dev/null +++ b/build/wp8/LibLinphone.vcxproj @@ -0,0 +1,204 @@ + + + + + Debug + Win32 + + + Debug + ARM + + + Release + Win32 + + + Release + ARM + + + + {08dd0d38-d9b5-4626-b60d-b4d76b571142} + LibLinphone + en-US + 11.0 + + + + DynamicLibrary + true + v110_wp80 + false + + + DynamicLibrary + false + true + v110_wp80 + false + + + + + + + + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\$(TargetName)\ + + + false + + + + Level4 + $(ProjectDir)..\..\..\belle-sip\include;$(ProjectDir)..\..\oRTP\include;$(ProjectDir)..\..\mediastreamer2\include;$(ProjectDIr)..\..\..\tunnel\include;$(ProjectDir)..\..\coreapi;$(ProjectDir)..\..\include;$(SolutionDir)$(Platform)\$(Configuration)\include;%(AdditionalIncludeDirectories) + __STDC_CONSTANT_MACROS;_CRT_SECURE_NO_WARNINGS;WIN32;_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) + Default + NotUsing + false + $(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories) + + + Console + false + false + belle-sip.lib;mediastreamer2.lib;ws2_32.lib;ortp.lib;gsm.lib;speex.lib;speexdsp.lib;%(AdditionalDependencies) + $(SolutionDir)$(Platform)\$(Configuration);%(AdditionalLibraryDirectories) + $(TargetDir)$(TargetName).lib + + + $(TargetDir)$(TargetName)_dll.lib;%(Outputs) + + + + + _DEBUG;%(PreprocessorDefinitions) + + + true + + + + + NDEBUG;%(PreprocessorDefinitions) + MaxSpeed + true + true + true + + + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + true + false + + + + + + + + {1db09afe-fc9b-472e-a746-0e33f8ef8883} + + + {4c225a82-800b-427b-ba7b-61686a9b347f} + + + {9924ac72-f96c-4e56-94d9-2b025da43c6b} + + + {072fad20-7007-4da2-b2e7-16ce2b219f67} + + + {36b528f9-fb79-4078-a16b-0a7442581bb7} + + + {d22bd217-d0f8-4274-9b3a-f3f35f46482c} + + + {b16b81a9-bef2-44c9-b603-1065183ae844} + + + {0565952a-ea62-46a2-8261-f5b4b490da42} + + + {59500dd1-b192-4ddf-a402-8a8e3739e032} + + + {027bad0e-9179-48c1-9733-7aa7e2c2ec70} + + + {ffc7b532-0502-4d88-ac98-9e89071cbc97} + + + {5dfa07b4-0be9-46a9-ba32-fdf5a55c580b} + + + + + \ No newline at end of file diff --git a/build/vsx/LibLinphoneTester/LibLinphoneTester.vcxproj b/build/wp8/LibLinphoneTester-native/LibLinphoneTester-native.vcxproj similarity index 52% rename from build/vsx/LibLinphoneTester/LibLinphoneTester.vcxproj rename to build/wp8/LibLinphoneTester-native/LibLinphoneTester-native.vcxproj index 3b8e9bfc0..424044515 100644 --- a/build/vsx/LibLinphoneTester/LibLinphoneTester.vcxproj +++ b/build/wp8/LibLinphoneTester-native/LibLinphoneTester-native.vcxproj @@ -26,26 +26,13 @@ true - + DynamicLibrary true v110_wp80 false - - DynamicLibrary - true - v110_wp80 - true - - - DynamicLibrary - false - true - v110_wp80 - false - - + DynamicLibrary false true @@ -60,66 +47,42 @@ false - - - _USRDLL;%(PreprocessorDefinitions) - NotUsing - false - $(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories) - - - Console - false - false - true - - - - - _USRDLL;NDEBUG;%(PreprocessorDefinitions) - NotUsing - false - $(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories) - - - Console - false - false - false - - - + Level4 - WIN32;_DEBUG;_WINDOWS;_WINRT_DLL;_CRT_SECURE_NO_WARNINGS;HAVE_CU_GET_SUITE;IN_LINPHONE;%(PreprocessorDefinitions) - $(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\..\oRTP\include;$(ProjectDir)..\..\..\..\mediastreamer2\include;$(ProjectDir)..\..\..\tester;$(ProjectDir)..\..\..\coreapi;$(ProjectDir)..\..\..\include;$(ProjectDir)..\..\..\..\cunit\build\windows\cunit\$(Platform)\$(Configuration);%(AdditionalIncludeDirectories) + $(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\oRTP\include;$(ProjectDir)..\..\..\mediastreamer2\include;$(ProjectDir)..\..\..\tester;$(ProjectDir)..\..\..\coreapi;$(ProjectDir)..\..\..\include;$(ProjectDir)..\..\..\..\cunit\build\wp8\cunit\$(Platform)\$(Configuration);$(SolutionDir)$(Platform)\$(Configuration)\include;%(AdditionalIncludeDirectories) + WIN32;_WINDOWS;_WINRT_DLL;_CRT_SECURE_NO_WARNINGS;HAVE_CU_GET_SUITE;IN_LINPHONE;%(PreprocessorDefinitions) Default NotUsing - $(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories) false - Async + $(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories) Console false - ole32.lib;%(IgnoreSpecificDefaultLibraries) true + ole32.lib;%(IgnoreSpecificDefaultLibraries) WindowsPhoneCore.lib;RuntimeObject.lib;PhoneAppModelHost.lib;ws2_32.lib;%(AdditionalDependencies) $(SolutionDir)$(Platform)\$(Configuration) - + - _USRDLL;NDEBUG;%(PreprocessorDefinitions) - NotUsing - false - $(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories) - $(ProjectDir)..\..\..\..\belle-sip\include;$(ProjectDir)..\..\..\..\oRTP\include;$(ProjectDir)..\..\..\..\mediastreamer2\include;$(ProjectDir)..\..\..\tester;$(ProjectDir)..\..\..\coreapi;$(ProjectDir)..\..\..\include;$(ProjectDir)..\..\..\..\cunit\build\windows\cunit\$(Platform)\$(Configuration);%(AdditionalIncludeDirectories) + _DEBUG;%(PreprocessorDefinitions) + + + true + + + + + NDEBUG;%(PreprocessorDefinitions) + MaxSpeed + true + true + true - Console - false - false false @@ -132,13 +95,18 @@ + + + + + - true + true @@ -146,21 +114,43 @@ - + + {1db09afe-fc9b-472e-a746-0e33f8ef8883} + + + {4c225a82-800b-427b-ba7b-61686a9b347f} + + {902daf1d-ebf1-4d03-b598-143500a50ab4} - + + {9924ac72-f96c-4e56-94d9-2b025da43c6b} + + + {072fad20-7007-4da2-b2e7-16ce2b219f67} + + + {36b528f9-fb79-4078-a16b-0a7442581bb7} + + + {d22bd217-d0f8-4274-9b3a-f3f35f46482c} + + + {b16b81a9-bef2-44c9-b603-1065183ae844} + + + {0565952a-ea62-46a2-8261-f5b4b490da42} + + {027bad0e-9179-48c1-9733-7aa7e2c2ec70} - + {ffc7b532-0502-4d88-ac98-9e89071cbc97} - + {08dd0d38-d9b5-4626-b60d-b4d76b571142} - - \ No newline at end of file diff --git a/build/vsx/LibLinphoneTester/linphone-tester-native.cpp b/build/wp8/LibLinphoneTester-native/linphone-tester-native.cpp similarity index 100% rename from build/vsx/LibLinphoneTester/linphone-tester-native.cpp rename to build/wp8/LibLinphoneTester-native/linphone-tester-native.cpp diff --git a/build/vsx/LibLinphoneTester/linphone-tester-native.h b/build/wp8/LibLinphoneTester-native/linphone-tester-native.h similarity index 100% rename from build/vsx/LibLinphoneTester/linphone-tester-native.h rename to build/wp8/LibLinphoneTester-native/linphone-tester-native.h diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/App.xaml b/build/wp8/LibLinphoneTester-wp8/App.xaml similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/App.xaml rename to build/wp8/LibLinphoneTester-wp8/App.xaml diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/App.xaml.cs b/build/wp8/LibLinphoneTester-wp8/App.xaml.cs similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/App.xaml.cs rename to build/wp8/LibLinphoneTester-wp8/App.xaml.cs diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/AlignmentGrid.png b/build/wp8/LibLinphoneTester-wp8/Assets/AlignmentGrid.png similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/AlignmentGrid.png rename to build/wp8/LibLinphoneTester-wp8/Assets/AlignmentGrid.png diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/ApplicationIcon.png b/build/wp8/LibLinphoneTester-wp8/Assets/ApplicationIcon.png similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/ApplicationIcon.png rename to build/wp8/LibLinphoneTester-wp8/Assets/ApplicationIcon.png diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/Tiles/FlipCycleTileLarge.png b/build/wp8/LibLinphoneTester-wp8/Assets/Tiles/FlipCycleTileLarge.png similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/Tiles/FlipCycleTileLarge.png rename to build/wp8/LibLinphoneTester-wp8/Assets/Tiles/FlipCycleTileLarge.png diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/Tiles/FlipCycleTileMedium.png b/build/wp8/LibLinphoneTester-wp8/Assets/Tiles/FlipCycleTileMedium.png similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/Tiles/FlipCycleTileMedium.png rename to build/wp8/LibLinphoneTester-wp8/Assets/Tiles/FlipCycleTileMedium.png diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/Tiles/FlipCycleTileSmall.png b/build/wp8/LibLinphoneTester-wp8/Assets/Tiles/FlipCycleTileSmall.png similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/Tiles/FlipCycleTileSmall.png rename to build/wp8/LibLinphoneTester-wp8/Assets/Tiles/FlipCycleTileSmall.png diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/Tiles/IconicTileMediumLarge.png b/build/wp8/LibLinphoneTester-wp8/Assets/Tiles/IconicTileMediumLarge.png similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/Tiles/IconicTileMediumLarge.png rename to build/wp8/LibLinphoneTester-wp8/Assets/Tiles/IconicTileMediumLarge.png diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/Tiles/IconicTileSmall.png b/build/wp8/LibLinphoneTester-wp8/Assets/Tiles/IconicTileSmall.png similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/Tiles/IconicTileSmall.png rename to build/wp8/LibLinphoneTester-wp8/Assets/Tiles/IconicTileSmall.png diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/empty_rc b/build/wp8/LibLinphoneTester-wp8/Assets/empty_rc similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/empty_rc rename to build/wp8/LibLinphoneTester-wp8/Assets/empty_rc diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/laure_rc b/build/wp8/LibLinphoneTester-wp8/Assets/laure_rc similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/laure_rc rename to build/wp8/LibLinphoneTester-wp8/Assets/laure_rc diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/multi_account_lrc b/build/wp8/LibLinphoneTester-wp8/Assets/multi_account_lrc similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/multi_account_lrc rename to build/wp8/LibLinphoneTester-wp8/Assets/multi_account_lrc diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/oldphone.wav b/build/wp8/LibLinphoneTester-wp8/Assets/oldphone.wav similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/oldphone.wav rename to build/wp8/LibLinphoneTester-wp8/Assets/oldphone.wav diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/ringback.wav b/build/wp8/LibLinphoneTester-wp8/Assets/ringback.wav similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/ringback.wav rename to build/wp8/LibLinphoneTester-wp8/Assets/ringback.wav diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/LibLinphoneTester-wp8.csproj b/build/wp8/LibLinphoneTester-wp8/LibLinphoneTester-wp8.csproj similarity index 84% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/LibLinphoneTester-wp8.csproj rename to build/wp8/LibLinphoneTester-wp8/LibLinphoneTester-wp8.csproj index 6ab7c0d58..4a73fb3b2 100644 --- a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/LibLinphoneTester-wp8.csproj +++ b/build/wp8/LibLinphoneTester-wp8/LibLinphoneTester-wp8.csproj @@ -26,27 +26,6 @@ 11.0 true - - true - full - false - Bin\Debug - DEBUG;TRACE;SILVERLIGHT;WINDOWS_PHONE - true - true - prompt - 4 - - - pdbonly - true - Bin\Release - TRACE;SILVERLIGHT;WINDOWS_PHONE - true - true - prompt - 4 - true full @@ -171,12 +150,15 @@ - + + {0565952A-EA62-46A2-8261-F5B4B490DA42} + libmswp8vid + + {5E94A00B-B14A-4E42-8284-8CB0EF099534} - LibLinphoneTester + LibLinphoneTester-native - - Xcopy /I /Y $(ProjectDir)..\..\..\..\tester\*rc $(ProjectDir)Assets\ + Xcopy /I /Y $(ProjectDir)..\..\..\tester\rcfiles\*_rc $(ProjectDir)Assets\ \ No newline at end of file diff --git a/build/wp8/LibLinphoneTester-wp8/LibLinphoneTester-wp8.sln b/build/wp8/LibLinphoneTester-wp8/LibLinphoneTester-wp8.sln new file mode 100644 index 000000000..cf0d4a086 --- /dev/null +++ b/build/wp8/LibLinphoneTester-wp8/LibLinphoneTester-wp8.sln @@ -0,0 +1,336 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Express 2012 for Windows Phone +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LibLinphoneTester-wp8", "LibLinphoneTester-wp8.csproj", "{34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}" + ProjectSection(ProjectDependencies) = postProject + {5E94A00B-B14A-4E42-8284-8CB0EF099534} = {5E94A00B-B14A-4E42-8284-8CB0EF099534} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibLinphone", "..\LibLinphone.vcxproj", "{08DD0D38-D9B5-4626-B60D-B4D76B571142}" + ProjectSection(ProjectDependencies) = postProject + {027BAD0E-9179-48C1-9733-7AA7E2C2EC70} = {027BAD0E-9179-48C1-9733-7AA7E2C2EC70} + {59500DD1-B192-4DDF-A402-8A8E3739E032} = {59500DD1-B192-4DDF-A402-8A8E3739E032} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibLinphoneTester-native", "..\LibLinphoneTester-native\LibLinphoneTester-native.vcxproj", "{5E94A00B-B14A-4E42-8284-8CB0EF099534}" + ProjectSection(ProjectDependencies) = postProject + {D22BD217-D0F8-4274-9B3A-F3F35F46482C} = {D22BD217-D0F8-4274-9B3A-F3F35F46482C} + {902DAF1D-EBF1-4D03-B598-143500A50AB4} = {902DAF1D-EBF1-4D03-B598-143500A50AB4} + {072FAD20-7007-4DA2-B2E7-16CE2B219F67} = {072FAD20-7007-4DA2-B2E7-16CE2B219F67} + {0565952A-EA62-46A2-8261-F5B4B490DA42} = {0565952A-EA62-46A2-8261-F5B4B490DA42} + {08DD0D38-D9B5-4626-B60D-B4D76B571142} = {08DD0D38-D9B5-4626-B60D-B4D76B571142} + {9924AC72-F96C-4E56-94D9-2B025DA43C6B} = {9924AC72-F96C-4E56-94D9-2B025DA43C6B} + {B16B81A9-BEF2-44C9-B603-1065183AE844} = {B16B81A9-BEF2-44C9-B603-1065183AE844} + {36B528F9-FB79-4078-A16B-0A7442581BB7} = {36B528F9-FB79-4078-A16B-0A7442581BB7} + {1DB09AFE-FC9B-472E-A746-0E33F8EF8883} = {1DB09AFE-FC9B-472E-A746-0E33F8EF8883} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "belle-sip", "..\..\..\..\belle-sip\build\wp8\belle-sip\belle-sip.vcxproj", "{4C225A82-800B-427B-BA7B-61686A9B347F}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "mediastreamer2", "..\..\..\mediastreamer2\build\wp8\mediastreamer2\mediastreamer2.vcxproj", "{027BAD0E-9179-48C1-9733-7AA7E2C2EC70}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "oRTP", "..\..\..\oRTP\build\wp8\oRTP\oRTP.vcxproj", "{FFC7B532-0502-4D88-AC98-9E89071CBC97}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libantlr3c", "..\..\..\..\antlr3\runtime\C\build\wp8\libantlr3c\libantlr3c.vcxproj", "{8FA74260-151B-429B-83EF-3CF3EAC8CFD9}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gsm", "..\..\..\..\gsm\build\wp8\gsm\gsm.vcxproj", "{746EA080-5BA9-42C5-9E52-EA421C3F3AFD}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "speex", "..\..\..\..\speex\build\wp8\speex\speex.vcxproj", "{D5EC8C11-C1D9-47E3-BB82-A93C300FD902}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "speexdsp", "..\..\..\..\speex\build\wp8\speex\speexdsp.vcxproj", "{6BD78980-9C71-4341-8775-AD19E9EC7305}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cunit", "..\..\..\..\cunit\build\wp8\cunit\cunit.vcxproj", "{902DAF1D-EBF1-4D03-B598-143500A50AB4}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmswasapi", "..\..\..\..\mswasapi\mswasapi\mswasapi.vcxproj", "{D22BD217-D0F8-4274-9B3A-F3F35F46482C}" + ProjectSection(ProjectDependencies) = postProject + {027BAD0E-9179-48C1-9733-7AA7E2C2EC70} = {027BAD0E-9179-48C1-9733-7AA7E2C2EC70} + {FFC7B532-0502-4D88-AC98-9E89071CBC97} = {FFC7B532-0502-4D88-AC98-9E89071CBC97} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libilbc-rfc3951", "..\..\..\..\libilbc-rfc3951\build\wp8\libilbc-rfc3951\libilbc-rfc3951.vcxproj", "{8E216BF3-2DD8-4794-8E97-B1AED301ED4D}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmsilbc", "..\..\..\..\msilbc\build\wp8\msilbc\msilbc.vcxproj", "{072FAD20-7007-4DA2-B2E7-16CE2B219F67}" + ProjectSection(ProjectDependencies) = postProject + {027BAD0E-9179-48C1-9733-7AA7E2C2EC70} = {027BAD0E-9179-48C1-9733-7AA7E2C2EC70} + {FFC7B532-0502-4D88-AC98-9E89071CBC97} = {FFC7B532-0502-4D88-AC98-9E89071CBC97} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmssilk", "..\..\..\..\mssilk\build\wp8\mssilk\mssilk.vcxproj", "{36B528F9-FB79-4078-A16B-0A7442581BB7}" + ProjectSection(ProjectDependencies) = postProject + {027BAD0E-9179-48C1-9733-7AA7E2C2EC70} = {027BAD0E-9179-48C1-9733-7AA7E2C2EC70} + {FFC7B532-0502-4D88-AC98-9E89071CBC97} = {FFC7B532-0502-4D88-AC98-9E89071CBC97} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmsamr", "..\..\..\..\msamr\build\wp8\msamr\msamr.vcxproj", "{9924AC72-F96C-4E56-94D9-2B025DA43C6B}" + ProjectSection(ProjectDependencies) = postProject + {027BAD0E-9179-48C1-9733-7AA7E2C2EC70} = {027BAD0E-9179-48C1-9733-7AA7E2C2EC70} + {018A4428-535C-4566-9AE0-E93AFF0D3ED2} = {018A4428-535C-4566-9AE0-E93AFF0D3ED2} + {7AC65D2A-6981-4D17-856D-C37A522739D8} = {7AC65D2A-6981-4D17-856D-C37A522739D8} + {88191E75-2993-48D7-AA76-652F274EF0FE} = {88191E75-2993-48D7-AA76-652F274EF0FE} + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vo-amrwbenc", "..\..\..\..\msamr\build\wp8\msamr\vo-amrwbenc.vcxproj", "{018A4428-535C-4566-9AE0-E93AFF0D3ED2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opencore_amrnb", "..\..\..\..\msamr\build\wp8\msamr\opencore_amrnb.vcxproj", "{88191E75-2993-48D7-AA76-652F274EF0FE}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opencore_amrwb", "..\..\..\..\msamr\build\wp8\msamr\opencore_amrwb.vcxproj", "{7AC65D2A-6981-4D17-856D-C37A522739D8}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "polarssl", "..\..\..\..\polarssl\build\wp8\polarssl\polarssl.vcxproj", "{E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tunnel", "..\..\..\..\tunnel\build\wp8\tunnel\tunnel.vcxproj", "{59500DD1-B192-4DDF-A402-8A8E3739E032}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxml2", "..\libxml2\libxml2.vcxproj", "{5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "srtp", "..\..\..\..\srtp\build\wp8\srtp\srtp.vcxproj", "{B4B96BC4-2B72-4964-98E4-7FD048A43363}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmswp8vid", "..\..\..\..\mswp8vid\mswp8vid\mswp8vid.vcxproj", "{0565952A-EA62-46A2-8261-F5B4B490DA42}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmswebrtc", "..\..\..\..\mswebrtc\build\wp8\mswebrtc\mswebrtc.vcxproj", "{B16B81A9-BEF2-44C9-B603-1065183AE844}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "webrtc", "..\..\..\..\mswebrtc\webrtc\build\wp8\webrtc\webrtc.vcxproj", "{A5A719E5-FDD6-4DFD-AAF6-68C9534B5562}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libmsbcg729", "..\..\..\..\bcg729\build\wp8\bcg729\bcg729.vcxproj", "{1DB09AFE-FC9B-472E-A746-0E33F8EF8883}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "opus", "..\..\..\..\opus\build\wp8\opus\opus.vcxproj", "{D450EC75-DF02-48B0-A4FB-ACA79BD894AB}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Debug|x86 = Debug|x86 + Release|ARM = Release|ARM + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|ARM.ActiveCfg = Debug|ARM + {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|ARM.Build.0 = Debug|ARM + {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|ARM.Deploy.0 = Debug|ARM + {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|x86.ActiveCfg = Debug|x86 + {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|x86.Build.0 = Debug|x86 + {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Debug|x86.Deploy.0 = Debug|x86 + {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|ARM.ActiveCfg = Release|ARM + {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|ARM.Build.0 = Release|ARM + {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|ARM.Deploy.0 = Release|ARM + {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|x86.ActiveCfg = Release|x86 + {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|x86.Build.0 = Release|x86 + {34D6878F-6CAB-4AE3-9CCC-25E8D6734C90}.Release|x86.Deploy.0 = Release|x86 + {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Debug|ARM.ActiveCfg = Debug|ARM + {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Debug|ARM.Build.0 = Debug|ARM + {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Debug|x86.ActiveCfg = Debug|Win32 + {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Debug|x86.Build.0 = Debug|Win32 + {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Release|ARM.ActiveCfg = Release|ARM + {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Release|ARM.Build.0 = Release|ARM + {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Release|x86.ActiveCfg = Release|Win32 + {08DD0D38-D9B5-4626-B60D-B4D76B571142}.Release|x86.Build.0 = Release|Win32 + {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Debug|ARM.ActiveCfg = Debug|ARM + {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Debug|ARM.Build.0 = Debug|ARM + {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Debug|x86.ActiveCfg = Debug|Win32 + {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Debug|x86.Build.0 = Debug|Win32 + {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Release|ARM.ActiveCfg = Release|ARM + {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Release|ARM.Build.0 = Release|ARM + {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Release|x86.ActiveCfg = Release|Win32 + {5E94A00B-B14A-4E42-8284-8CB0EF099534}.Release|x86.Build.0 = Release|Win32 + {4C225A82-800B-427B-BA7B-61686A9B347F}.Debug|ARM.ActiveCfg = Debug|ARM + {4C225A82-800B-427B-BA7B-61686A9B347F}.Debug|ARM.Build.0 = Debug|ARM + {4C225A82-800B-427B-BA7B-61686A9B347F}.Debug|x86.ActiveCfg = Debug|Win32 + {4C225A82-800B-427B-BA7B-61686A9B347F}.Debug|x86.Build.0 = Debug|Win32 + {4C225A82-800B-427B-BA7B-61686A9B347F}.Release|ARM.ActiveCfg = Release|ARM + {4C225A82-800B-427B-BA7B-61686A9B347F}.Release|ARM.Build.0 = Release|ARM + {4C225A82-800B-427B-BA7B-61686A9B347F}.Release|x86.ActiveCfg = Release|Win32 + {4C225A82-800B-427B-BA7B-61686A9B347F}.Release|x86.Build.0 = Release|Win32 + {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Debug|ARM.ActiveCfg = Debug|ARM + {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Debug|ARM.Build.0 = Debug|ARM + {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Debug|x86.ActiveCfg = Debug|Win32 + {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Debug|x86.Build.0 = Debug|Win32 + {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Release|ARM.ActiveCfg = Release|ARM + {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Release|ARM.Build.0 = Release|ARM + {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Release|x86.ActiveCfg = Release|Win32 + {027BAD0E-9179-48C1-9733-7AA7E2C2EC70}.Release|x86.Build.0 = Release|Win32 + {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Debug|ARM.ActiveCfg = Debug|ARM + {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Debug|ARM.Build.0 = Debug|ARM + {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Debug|x86.ActiveCfg = Debug|Win32 + {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Debug|x86.Build.0 = Debug|Win32 + {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Release|ARM.ActiveCfg = Release|ARM + {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Release|ARM.Build.0 = Release|ARM + {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Release|x86.ActiveCfg = Release|Win32 + {FFC7B532-0502-4D88-AC98-9E89071CBC97}.Release|x86.Build.0 = Release|Win32 + {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Debug|ARM.ActiveCfg = Debug|ARM + {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Debug|ARM.Build.0 = Debug|ARM + {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Debug|x86.ActiveCfg = Debug|Win32 + {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Debug|x86.Build.0 = Debug|Win32 + {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Release|ARM.ActiveCfg = Release|ARM + {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Release|ARM.Build.0 = Release|ARM + {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Release|x86.ActiveCfg = Release|Win32 + {8FA74260-151B-429B-83EF-3CF3EAC8CFD9}.Release|x86.Build.0 = Release|Win32 + {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Debug|ARM.ActiveCfg = Debug|ARM + {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Debug|ARM.Build.0 = Debug|ARM + {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Debug|x86.ActiveCfg = Debug|Win32 + {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Debug|x86.Build.0 = Debug|Win32 + {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Release|ARM.ActiveCfg = Release|ARM + {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Release|ARM.Build.0 = Release|ARM + {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Release|x86.ActiveCfg = Release|Win32 + {746EA080-5BA9-42C5-9E52-EA421C3F3AFD}.Release|x86.Build.0 = Release|Win32 + {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Debug|ARM.ActiveCfg = Debug|ARM + {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Debug|ARM.Build.0 = Debug|ARM + {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Debug|x86.ActiveCfg = Debug|Win32 + {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Debug|x86.Build.0 = Debug|Win32 + {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Release|ARM.ActiveCfg = Release|ARM + {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Release|ARM.Build.0 = Release|ARM + {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Release|x86.ActiveCfg = Release|Win32 + {D5EC8C11-C1D9-47E3-BB82-A93C300FD902}.Release|x86.Build.0 = Release|Win32 + {6BD78980-9C71-4341-8775-AD19E9EC7305}.Debug|ARM.ActiveCfg = Debug|ARM + {6BD78980-9C71-4341-8775-AD19E9EC7305}.Debug|ARM.Build.0 = Debug|ARM + {6BD78980-9C71-4341-8775-AD19E9EC7305}.Debug|x86.ActiveCfg = Debug|Win32 + {6BD78980-9C71-4341-8775-AD19E9EC7305}.Debug|x86.Build.0 = Debug|Win32 + {6BD78980-9C71-4341-8775-AD19E9EC7305}.Release|ARM.ActiveCfg = Release|ARM + {6BD78980-9C71-4341-8775-AD19E9EC7305}.Release|ARM.Build.0 = Release|ARM + {6BD78980-9C71-4341-8775-AD19E9EC7305}.Release|x86.ActiveCfg = Release|Win32 + {6BD78980-9C71-4341-8775-AD19E9EC7305}.Release|x86.Build.0 = Release|Win32 + {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Debug|ARM.ActiveCfg = Debug|ARM + {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Debug|ARM.Build.0 = Debug|ARM + {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Debug|x86.ActiveCfg = Debug|Win32 + {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Debug|x86.Build.0 = Debug|Win32 + {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Release|ARM.ActiveCfg = Release|ARM + {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Release|ARM.Build.0 = Release|ARM + {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Release|x86.ActiveCfg = Release|Win32 + {902DAF1D-EBF1-4D03-B598-143500A50AB4}.Release|x86.Build.0 = Release|Win32 + {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Debug|ARM.ActiveCfg = Debug|ARM + {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Debug|ARM.Build.0 = Debug|ARM + {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Debug|x86.ActiveCfg = Debug|Win32 + {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Debug|x86.Build.0 = Debug|Win32 + {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Release|ARM.ActiveCfg = Release|ARM + {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Release|ARM.Build.0 = Release|ARM + {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Release|x86.ActiveCfg = Release|Win32 + {D22BD217-D0F8-4274-9B3A-F3F35F46482C}.Release|x86.Build.0 = Release|Win32 + {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Debug|ARM.ActiveCfg = Debug|ARM + {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Debug|ARM.Build.0 = Debug|ARM + {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Debug|x86.ActiveCfg = Debug|Win32 + {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Debug|x86.Build.0 = Debug|Win32 + {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Release|ARM.ActiveCfg = Release|ARM + {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Release|ARM.Build.0 = Release|ARM + {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Release|x86.ActiveCfg = Release|Win32 + {8E216BF3-2DD8-4794-8E97-B1AED301ED4D}.Release|x86.Build.0 = Release|Win32 + {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Debug|ARM.ActiveCfg = Debug|ARM + {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Debug|ARM.Build.0 = Debug|ARM + {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Debug|x86.ActiveCfg = Debug|Win32 + {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Debug|x86.Build.0 = Debug|Win32 + {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Release|ARM.ActiveCfg = Release|ARM + {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Release|ARM.Build.0 = Release|ARM + {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Release|x86.ActiveCfg = Release|Win32 + {072FAD20-7007-4DA2-B2E7-16CE2B219F67}.Release|x86.Build.0 = Release|Win32 + {36B528F9-FB79-4078-A16B-0A7442581BB7}.Debug|ARM.ActiveCfg = Debug|ARM + {36B528F9-FB79-4078-A16B-0A7442581BB7}.Debug|ARM.Build.0 = Debug|ARM + {36B528F9-FB79-4078-A16B-0A7442581BB7}.Debug|x86.ActiveCfg = Debug|Win32 + {36B528F9-FB79-4078-A16B-0A7442581BB7}.Debug|x86.Build.0 = Debug|Win32 + {36B528F9-FB79-4078-A16B-0A7442581BB7}.Release|ARM.ActiveCfg = Release|ARM + {36B528F9-FB79-4078-A16B-0A7442581BB7}.Release|ARM.Build.0 = Release|ARM + {36B528F9-FB79-4078-A16B-0A7442581BB7}.Release|x86.ActiveCfg = Release|Win32 + {36B528F9-FB79-4078-A16B-0A7442581BB7}.Release|x86.Build.0 = Release|Win32 + {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Debug|ARM.ActiveCfg = Debug|ARM + {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Debug|ARM.Build.0 = Debug|ARM + {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Debug|x86.ActiveCfg = Debug|Win32 + {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Debug|x86.Build.0 = Debug|Win32 + {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Release|ARM.ActiveCfg = Release|ARM + {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Release|ARM.Build.0 = Release|ARM + {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Release|x86.ActiveCfg = Release|Win32 + {9924AC72-F96C-4E56-94D9-2B025DA43C6B}.Release|x86.Build.0 = Release|Win32 + {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Debug|ARM.ActiveCfg = Debug|ARM + {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Debug|ARM.Build.0 = Debug|ARM + {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Debug|x86.ActiveCfg = Debug|Win32 + {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Debug|x86.Build.0 = Debug|Win32 + {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Release|ARM.ActiveCfg = Release|ARM + {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Release|ARM.Build.0 = Release|ARM + {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Release|x86.ActiveCfg = Release|Win32 + {018A4428-535C-4566-9AE0-E93AFF0D3ED2}.Release|x86.Build.0 = Release|Win32 + {88191E75-2993-48D7-AA76-652F274EF0FE}.Debug|ARM.ActiveCfg = Debug|ARM + {88191E75-2993-48D7-AA76-652F274EF0FE}.Debug|ARM.Build.0 = Debug|ARM + {88191E75-2993-48D7-AA76-652F274EF0FE}.Debug|x86.ActiveCfg = Debug|Win32 + {88191E75-2993-48D7-AA76-652F274EF0FE}.Debug|x86.Build.0 = Debug|Win32 + {88191E75-2993-48D7-AA76-652F274EF0FE}.Release|ARM.ActiveCfg = Release|ARM + {88191E75-2993-48D7-AA76-652F274EF0FE}.Release|ARM.Build.0 = Release|ARM + {88191E75-2993-48D7-AA76-652F274EF0FE}.Release|x86.ActiveCfg = Release|Win32 + {88191E75-2993-48D7-AA76-652F274EF0FE}.Release|x86.Build.0 = Release|Win32 + {7AC65D2A-6981-4D17-856D-C37A522739D8}.Debug|ARM.ActiveCfg = Debug|ARM + {7AC65D2A-6981-4D17-856D-C37A522739D8}.Debug|ARM.Build.0 = Debug|ARM + {7AC65D2A-6981-4D17-856D-C37A522739D8}.Debug|x86.ActiveCfg = Debug|Win32 + {7AC65D2A-6981-4D17-856D-C37A522739D8}.Debug|x86.Build.0 = Debug|Win32 + {7AC65D2A-6981-4D17-856D-C37A522739D8}.Release|ARM.ActiveCfg = Release|ARM + {7AC65D2A-6981-4D17-856D-C37A522739D8}.Release|ARM.Build.0 = Release|ARM + {7AC65D2A-6981-4D17-856D-C37A522739D8}.Release|x86.ActiveCfg = Release|Win32 + {7AC65D2A-6981-4D17-856D-C37A522739D8}.Release|x86.Build.0 = Release|Win32 + {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Debug|ARM.ActiveCfg = Debug|ARM + {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Debug|ARM.Build.0 = Debug|ARM + {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Debug|x86.ActiveCfg = Debug|Win32 + {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Debug|x86.Build.0 = Debug|Win32 + {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Release|ARM.ActiveCfg = Release|ARM + {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Release|ARM.Build.0 = Release|ARM + {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Release|x86.ActiveCfg = Release|Win32 + {E9F8C5D1-13A2-46B6-A9BC-878030D4BE09}.Release|x86.Build.0 = Release|Win32 + {59500DD1-B192-4DDF-A402-8A8E3739E032}.Debug|ARM.ActiveCfg = Debug|ARM + {59500DD1-B192-4DDF-A402-8A8E3739E032}.Debug|ARM.Build.0 = Debug|ARM + {59500DD1-B192-4DDF-A402-8A8E3739E032}.Debug|x86.ActiveCfg = Debug|Win32 + {59500DD1-B192-4DDF-A402-8A8E3739E032}.Debug|x86.Build.0 = Debug|Win32 + {59500DD1-B192-4DDF-A402-8A8E3739E032}.Release|ARM.ActiveCfg = Release|ARM + {59500DD1-B192-4DDF-A402-8A8E3739E032}.Release|ARM.Build.0 = Release|ARM + {59500DD1-B192-4DDF-A402-8A8E3739E032}.Release|x86.ActiveCfg = Release|Win32 + {59500DD1-B192-4DDF-A402-8A8E3739E032}.Release|x86.Build.0 = Release|Win32 + {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Debug|ARM.ActiveCfg = Debug|ARM + {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Debug|ARM.Build.0 = Debug|ARM + {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Debug|x86.ActiveCfg = Debug|Win32 + {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Debug|x86.Build.0 = Debug|Win32 + {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Release|ARM.ActiveCfg = Release|ARM + {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Release|ARM.Build.0 = Release|ARM + {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Release|x86.ActiveCfg = Release|Win32 + {5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}.Release|x86.Build.0 = Release|Win32 + {B4B96BC4-2B72-4964-98E4-7FD048A43363}.Debug|ARM.ActiveCfg = Debug|ARM + {B4B96BC4-2B72-4964-98E4-7FD048A43363}.Debug|ARM.Build.0 = Debug|ARM + {B4B96BC4-2B72-4964-98E4-7FD048A43363}.Debug|x86.ActiveCfg = Debug|Win32 + {B4B96BC4-2B72-4964-98E4-7FD048A43363}.Debug|x86.Build.0 = Debug|Win32 + {B4B96BC4-2B72-4964-98E4-7FD048A43363}.Release|ARM.ActiveCfg = Release|ARM + {B4B96BC4-2B72-4964-98E4-7FD048A43363}.Release|ARM.Build.0 = Release|ARM + {B4B96BC4-2B72-4964-98E4-7FD048A43363}.Release|x86.ActiveCfg = Release|Win32 + {B4B96BC4-2B72-4964-98E4-7FD048A43363}.Release|x86.Build.0 = Release|Win32 + {0565952A-EA62-46A2-8261-F5B4B490DA42}.Debug|ARM.ActiveCfg = Debug|ARM + {0565952A-EA62-46A2-8261-F5B4B490DA42}.Debug|ARM.Build.0 = Debug|ARM + {0565952A-EA62-46A2-8261-F5B4B490DA42}.Debug|x86.ActiveCfg = Debug|Win32 + {0565952A-EA62-46A2-8261-F5B4B490DA42}.Debug|x86.Build.0 = Debug|Win32 + {0565952A-EA62-46A2-8261-F5B4B490DA42}.Release|ARM.ActiveCfg = Release|ARM + {0565952A-EA62-46A2-8261-F5B4B490DA42}.Release|ARM.Build.0 = Release|ARM + {0565952A-EA62-46A2-8261-F5B4B490DA42}.Release|x86.ActiveCfg = Release|Win32 + {0565952A-EA62-46A2-8261-F5B4B490DA42}.Release|x86.Build.0 = Release|Win32 + {B16B81A9-BEF2-44C9-B603-1065183AE844}.Debug|ARM.ActiveCfg = Debug|ARM + {B16B81A9-BEF2-44C9-B603-1065183AE844}.Debug|ARM.Build.0 = Debug|ARM + {B16B81A9-BEF2-44C9-B603-1065183AE844}.Debug|x86.ActiveCfg = Debug|Win32 + {B16B81A9-BEF2-44C9-B603-1065183AE844}.Debug|x86.Build.0 = Debug|Win32 + {B16B81A9-BEF2-44C9-B603-1065183AE844}.Release|ARM.ActiveCfg = Release|ARM + {B16B81A9-BEF2-44C9-B603-1065183AE844}.Release|ARM.Build.0 = Release|ARM + {B16B81A9-BEF2-44C9-B603-1065183AE844}.Release|x86.ActiveCfg = Release|Win32 + {B16B81A9-BEF2-44C9-B603-1065183AE844}.Release|x86.Build.0 = Release|Win32 + {A5A719E5-FDD6-4DFD-AAF6-68C9534B5562}.Debug|ARM.ActiveCfg = Debug|ARM + {A5A719E5-FDD6-4DFD-AAF6-68C9534B5562}.Debug|ARM.Build.0 = Debug|ARM + {A5A719E5-FDD6-4DFD-AAF6-68C9534B5562}.Debug|x86.ActiveCfg = Debug|Win32 + {A5A719E5-FDD6-4DFD-AAF6-68C9534B5562}.Debug|x86.Build.0 = Debug|Win32 + {A5A719E5-FDD6-4DFD-AAF6-68C9534B5562}.Release|ARM.ActiveCfg = Release|ARM + {A5A719E5-FDD6-4DFD-AAF6-68C9534B5562}.Release|ARM.Build.0 = Release|ARM + {A5A719E5-FDD6-4DFD-AAF6-68C9534B5562}.Release|x86.ActiveCfg = Release|Win32 + {A5A719E5-FDD6-4DFD-AAF6-68C9534B5562}.Release|x86.Build.0 = Release|Win32 + {1DB09AFE-FC9B-472E-A746-0E33F8EF8883}.Debug|ARM.ActiveCfg = Debug|ARM + {1DB09AFE-FC9B-472E-A746-0E33F8EF8883}.Debug|ARM.Build.0 = Debug|ARM + {1DB09AFE-FC9B-472E-A746-0E33F8EF8883}.Debug|x86.ActiveCfg = Debug|Win32 + {1DB09AFE-FC9B-472E-A746-0E33F8EF8883}.Debug|x86.Build.0 = Debug|Win32 + {1DB09AFE-FC9B-472E-A746-0E33F8EF8883}.Release|ARM.ActiveCfg = Release|ARM + {1DB09AFE-FC9B-472E-A746-0E33F8EF8883}.Release|ARM.Build.0 = Release|ARM + {1DB09AFE-FC9B-472E-A746-0E33F8EF8883}.Release|x86.ActiveCfg = Release|Win32 + {1DB09AFE-FC9B-472E-A746-0E33F8EF8883}.Release|x86.Build.0 = Release|Win32 + {D450EC75-DF02-48B0-A4FB-ACA79BD894AB}.Debug|ARM.ActiveCfg = Debug|ARM + {D450EC75-DF02-48B0-A4FB-ACA79BD894AB}.Debug|ARM.Build.0 = Debug|ARM + {D450EC75-DF02-48B0-A4FB-ACA79BD894AB}.Debug|x86.ActiveCfg = Debug|Win32 + {D450EC75-DF02-48B0-A4FB-ACA79BD894AB}.Debug|x86.Build.0 = Debug|Win32 + {D450EC75-DF02-48B0-A4FB-ACA79BD894AB}.Release|ARM.ActiveCfg = Release|ARM + {D450EC75-DF02-48B0-A4FB-ACA79BD894AB}.Release|ARM.Build.0 = Release|ARM + {D450EC75-DF02-48B0-A4FB-ACA79BD894AB}.Release|x86.ActiveCfg = Release|Win32 + {D450EC75-DF02-48B0-A4FB-ACA79BD894AB}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/LocalizedStrings.cs b/build/wp8/LibLinphoneTester-wp8/LocalizedStrings.cs similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/LocalizedStrings.cs rename to build/wp8/LibLinphoneTester-wp8/LocalizedStrings.cs diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/MainPage.xaml b/build/wp8/LibLinphoneTester-wp8/MainPage.xaml similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/MainPage.xaml rename to build/wp8/LibLinphoneTester-wp8/MainPage.xaml diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/MainPage.xaml.cs b/build/wp8/LibLinphoneTester-wp8/MainPage.xaml.cs similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/MainPage.xaml.cs rename to build/wp8/LibLinphoneTester-wp8/MainPage.xaml.cs diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Properties/AppManifest.xml b/build/wp8/LibLinphoneTester-wp8/Properties/AppManifest.xml similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Properties/AppManifest.xml rename to build/wp8/LibLinphoneTester-wp8/Properties/AppManifest.xml diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Properties/AssemblyInfo.cs b/build/wp8/LibLinphoneTester-wp8/Properties/AssemblyInfo.cs similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Properties/AssemblyInfo.cs rename to build/wp8/LibLinphoneTester-wp8/Properties/AssemblyInfo.cs diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Properties/WMAppManifest.xml b/build/wp8/LibLinphoneTester-wp8/Properties/WMAppManifest.xml similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Properties/WMAppManifest.xml rename to build/wp8/LibLinphoneTester-wp8/Properties/WMAppManifest.xml diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Resources/AppResources.Designer.cs b/build/wp8/LibLinphoneTester-wp8/Resources/AppResources.Designer.cs similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Resources/AppResources.Designer.cs rename to build/wp8/LibLinphoneTester-wp8/Resources/AppResources.Designer.cs diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Resources/AppResources.resx b/build/wp8/LibLinphoneTester-wp8/Resources/AppResources.resx similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Resources/AppResources.resx rename to build/wp8/LibLinphoneTester-wp8/Resources/AppResources.resx diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/TestCasePage.xaml b/build/wp8/LibLinphoneTester-wp8/TestCasePage.xaml similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/TestCasePage.xaml rename to build/wp8/LibLinphoneTester-wp8/TestCasePage.xaml diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/TestCasePage.xaml.cs b/build/wp8/LibLinphoneTester-wp8/TestCasePage.xaml.cs similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/TestCasePage.xaml.cs rename to build/wp8/LibLinphoneTester-wp8/TestCasePage.xaml.cs diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/TestResultPage.xaml b/build/wp8/LibLinphoneTester-wp8/TestResultPage.xaml similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/TestResultPage.xaml rename to build/wp8/LibLinphoneTester-wp8/TestResultPage.xaml diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/TestResultPage.xaml.cs b/build/wp8/LibLinphoneTester-wp8/TestResultPage.xaml.cs similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/TestResultPage.xaml.cs rename to build/wp8/LibLinphoneTester-wp8/TestResultPage.xaml.cs diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/log.html b/build/wp8/LibLinphoneTester-wp8/log.html similarity index 100% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/log.html rename to build/wp8/LibLinphoneTester-wp8/log.html diff --git a/build/vsx/libxml2/libxml2/install_headers.bat b/build/wp8/libxml2/install_headers.bat similarity index 71% rename from build/vsx/libxml2/libxml2/install_headers.bat rename to build/wp8/libxml2/install_headers.bat index 8e97127d8..d33f20c04 100644 --- a/build/vsx/libxml2/libxml2/install_headers.bat +++ b/build/wp8/libxml2/install_headers.bat @@ -1,5 +1,5 @@ SET curdir=%CD% -SET incdir=..\..\..\..\..\libxml2\include\libxml +SET incdir=..\..\..\..\libxml2\include\libxml SET installdir=%1\libxml Xcopy /I /Y %incdir%\*.h %installdir%\ diff --git a/build/vsx/libxml2/libxml2.sln b/build/wp8/libxml2/libxml2.sln similarity index 94% rename from build/vsx/libxml2/libxml2.sln rename to build/wp8/libxml2/libxml2.sln index 62fad2d3f..b10b61b6b 100644 --- a/build/vsx/libxml2/libxml2.sln +++ b/build/wp8/libxml2/libxml2.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Express 2012 for Windows Phone -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxml2", "libxml2\libxml2.vcxproj", "{5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}" +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libxml2", "libxml2.vcxproj", "{5DFA07B4-0BE9-46A9-BA32-FDF5A55C580B}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/build/wp8/libxml2/libxml2.vcxproj b/build/wp8/libxml2/libxml2.vcxproj new file mode 100644 index 000000000..0e1f21c63 --- /dev/null +++ b/build/wp8/libxml2/libxml2.vcxproj @@ -0,0 +1,159 @@ + + + + + Debug + Win32 + + + Debug + ARM + + + Release + Win32 + + + Release + ARM + + + + {5dfa07b4-0be9-46a9-ba32-fdf5a55c580b} + libxml2 + en-US + 11.0 + + + + DynamicLibrary + true + v110_wp80 + false + + + DynamicLibrary + false + true + v110_wp80 + false + + + + + + + + $(SolutionDir)$(Platform)\$(Configuration)\ + $(SolutionDir)$(Platform)\$(Configuration)\$(TargetName)\ + + + false + + + + Level4 + $(SolutionDir)$(Platform)\$(Configuration)\include;$(ProjectDir)..\..\..\..\libxml2\include;$(ProjectDir)..\..\..\..\libxml2\win32\VC10;%(AdditionalIncludeDirectories) + _WIN32;_WINDLL;_USRDLL;_CRT_SECURE_NO_WARNINGS;HAVE_WIN32_THREADS;HAVE_COMPILER_TLS;UNICODE;%(PreprocessorDefinitions) + LIBXML_MODULES_ENABLED + Default + NotUsing + false + $(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories) + $(ProjectDir)libxml2_port.h + + + Console + false + false + $(TargetDir)$(TargetName).lib + Ws2_32.lib;%(AdditionalDependencies) + + + install_headers.bat $(SolutionDir)$(Platform)\$(Configuration)\include + + + + + _DEBUG;%(PreprocessorDefinitions) + + + true + + + + + NDEBUG;%(PreprocessorDefinitions) + MaxSpeed + true + true + true + + + false + + + + + true + + + true + false + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/build/vsx/libxml2/libxml2/libxml2_port.h b/build/wp8/libxml2/libxml2_port.h similarity index 100% rename from build/vsx/libxml2/libxml2/libxml2_port.h rename to build/wp8/libxml2/libxml2_port.h diff --git a/build/vsx/libxml2/libxml2/xmlversion.h b/build/wp8/libxml2/xmlversion.h similarity index 100% rename from build/vsx/libxml2/libxml2/xmlversion.h rename to build/wp8/libxml2/xmlversion.h diff --git a/console/commands.c b/console/commands.c index 725ce8e4b..c22c963b0 100644 --- a/console/commands.c +++ b/console/commands.c @@ -45,7 +45,7 @@ /*************************************************************************** * - * Forward declarations + * Forward declarations * ***************************************************************************/ @@ -190,19 +190,19 @@ static LPC_COMMAND commands[] = { "'conference add : join the call with id 'call id' into the audio conference." "'conference rm : remove the call with id 'call id' from the audio conference." }, - { "mute", lpc_cmd_mute_mic, + { "mute", lpc_cmd_mute_mic, "Mute microphone and suspend voice transmission."}, #ifdef VIDEO_ENABLED { "camera", lpc_cmd_camera, "Send camera output for current call.", "'camera on'\t: allow sending of local camera video to remote end.\n" "'camera off'\t: disable sending of local camera's video to remote end.\n"}, #endif - { "unmute", lpc_cmd_unmute_mic, + { "unmute", lpc_cmd_unmute_mic, "Unmute microphone and resume voice transmission."}, - { "playbackgain", lpc_cmd_playback_gain, + { "playbackgain", lpc_cmd_playback_gain, "Adjust playback gain."}, { "duration", lpc_cmd_duration, "Print duration in seconds of the last call.", NULL }, - + { "autoanswer", lpc_cmd_autoanswer, "Show/set auto-answer mode", "'autoanswer' \t: show current autoanswer mode\n" "'autoanswer enable'\t: enable autoanswer mode\n" @@ -291,7 +291,7 @@ static LPC_COMMAND advanced_commands[] = { { "nortp-on-audio-mute", lpc_cmd_rtp_no_xmit_on_audio_mute, "Set the rtp_no_xmit_on_audio_mute configuration parameter", " If set to 1 then rtp transmission will be muted when\n" - " audio is muted , otherwise rtp is always sent."}, + " audio is muted , otherwise rtp is always sent."}, #ifdef VIDEO_ENABLED { "vwindow", lpc_cmd_video_window, "Control video display window", "'vwindow show': shows video window\n" @@ -321,11 +321,11 @@ static LPC_COMMAND advanced_commands[] = { }, { "register", lpc_cmd_register, "Register in one line to a proxy" , "register "}, { "unregister", lpc_cmd_unregister, "Unregister from default proxy", NULL }, - { "status", lpc_cmd_status, "Print various status information", + { "status", lpc_cmd_status, "Print various status information", "'status register' \t: print status concerning registration\n" "'status autoanswer'\t: tell whether autoanswer mode is enabled\n" "'status hook' \t: print hook status\n" }, - { "ports", lpc_cmd_ports, "Network ports configuration", + { "ports", lpc_cmd_ports, "Network ports configuration", "'ports' \t: prints current used ports.\n" "'ports sip '\t: Sets the sip port.\n" }, { "param", lpc_cmd_param, "parameter set or read as normally given in .linphonerc", @@ -365,7 +365,7 @@ static LPC_COMMAND advanced_commands[] = { /*************************************************************************** * - * Public interface + * Public interface * ***************************************************************************/ @@ -476,7 +476,7 @@ linphonec_command_generator(const char *text, int state) /*************************************************************************** * - * Command handlers + * Command handlers * ***************************************************************************/ @@ -497,7 +497,7 @@ lpc_cmd_help(LinphoneCore *lc, char *arg) commands[i].help); i++; } - + linphonec_out("---------------------------\n"); linphonec_out("Type 'help ' for more details or\n"); linphonec_out(" 'help advanced' to list additional commands.\n"); @@ -515,13 +515,13 @@ lpc_cmd_help(LinphoneCore *lc, char *arg) advanced_commands[i].help); i++; } - + linphonec_out("---------------------------\n"); linphonec_out("Type 'help ' for more details.\n"); return 1; } - + cmd=lpc_find_command(arg); if ( !cmd ) { @@ -579,7 +579,7 @@ lpc_cmd_call(LinphoneCore *lc, char *args) return 1; } -static int +static int lpc_cmd_calls(LinphoneCore *lc, char *args){ const MSList *calls = linphone_core_get_calls(lc); if(calls) @@ -692,7 +692,7 @@ lpc_cmd_terminate(LinphoneCore *lc, char *args) } return 1; } - + if(strcmp(args,"all")==0){ linphonec_out("We are going to stop all the calls.\n"); linphone_core_terminate_all_calls(lc); @@ -709,7 +709,7 @@ lpc_cmd_terminate(LinphoneCore *lc, char *args) return 1; } return 0; - + } static int @@ -852,7 +852,7 @@ lpc_cmd_firewall(LinphoneCore *lc, char *args) { linphone_core_set_firewall_policy(lc,LinphonePolicyNoFirewall); } - else if (strcmp(args,"upnp")==0) + else if (strcmp(args,"upnp")==0) { linphone_core_set_firewall_policy(lc,LinphonePolicyUseUpnp); } @@ -930,7 +930,7 @@ lpc_friend_name(char **args, char **name) *args = ++end; } else { *name = strsep(args, " "); - + if (NULL == *args) { /* Means there was no separator */ fprintf(stderr, "Either name or address is missing\n"); return 0; @@ -960,7 +960,7 @@ lpc_cmd_friend(LinphoneCore *lc, char *args) args+=4; if ( ! *args ) return 0; friend_num = strtol(args, NULL, 10); -#ifndef _WIN32_WCE +#ifndef _WIN32_WCE if ( errno == ERANGE ) { linphonec_out("Invalid friend number\n"); return 0; @@ -978,11 +978,11 @@ lpc_cmd_friend(LinphoneCore *lc, char *args) if (!strncmp(args, "all", 3)) { friend_num = -1; - } + } else { friend_num = strtol(args, NULL, 10); -#ifndef _WIN32_WCE +#ifndef _WIN32_WCE if ( errno == ERANGE ) { linphonec_out("Invalid friend number\n"); return 0; @@ -1411,7 +1411,7 @@ static int lpc_cmd_pause(LinphoneCore *lc, char *args){ } static int lpc_cmd_resume(LinphoneCore *lc, char *args){ - + if(linphone_core_in_call(lc)) { linphonec_out("There is already a call in process pause or stop it first"); @@ -1450,7 +1450,7 @@ static int lpc_cmd_resume(LinphoneCore *lc, char *args){ } } return 0; - + } static int lpc_cmd_conference(LinphoneCore *lc, char *args){ @@ -1659,7 +1659,7 @@ linphonec_proxy_add(LinphoneCore *lc) } /* - * Final confirmation + * Final confirmation */ while (1) { @@ -1742,12 +1742,12 @@ linphonec_proxy_list(LinphoneCore *lc) const MSList *proxies; int n; int def=linphone_core_get_default_proxy(lc,NULL); - + proxies=linphone_core_get_proxy_config_list(lc); for(n=0;proxies!=NULL;proxies=ms_list_next(proxies),n++){ if (n==def) linphonec_out("****** Proxy %i - this is the default one - *******\n",n); - else + else linphonec_out("****** Proxy %i *******\n",n); linphonec_proxy_display((LinphoneProxyConfig*)proxies->data); } @@ -1789,7 +1789,7 @@ linphonec_friend_display(LinphoneFriend *fr) { LinphoneAddress *uri=linphone_address_clone(linphone_friend_get_address(fr)); char *str; - + linphonec_out("name: %s\n", linphone_address_get_display_name(uri)); linphone_address_set_display_name(uri,NULL); str=linphone_address_as_string(uri); @@ -1874,7 +1874,7 @@ linphonec_friend_delete(LinphoneCore *lc, int num) } } - if (-1 == num) + if (-1 == num) { unsigned int i; for (i = 0 ; i < n ; i++) @@ -1900,7 +1900,7 @@ static int lpc_cmd_register(LinphoneCore *lc, char *args){ char passwd[512]; LinphoneProxyConfig *cfg; const MSList *elem; - + if (!args) { /* it means that you want to register the default proxy */ @@ -1979,7 +1979,7 @@ static int lpc_cmd_duration(LinphoneCore *lc, char *args){ static int lpc_cmd_status(LinphoneCore *lc, char *args) { LinphoneProxyConfig *cfg; - + if ( ! args ) return 0; linphone_core_get_default_proxy(lc,&cfg); if (strstr(args,"register")) @@ -2042,7 +2042,7 @@ static int lpc_cmd_status(LinphoneCore *lc, char *args) default: break; } - + } else return 0; @@ -2101,19 +2101,23 @@ static int lpc_cmd_speak(LinphoneCore *lc, char *args){ char voice[64]; char *sentence; char cl[128]; - char *wavfile; + char wavfile[128]="/tmp/linphonec-espeak-XXXXXX"; int status; FILE *file; - + if (!args) return 0; memset(voice,0,sizeof(voice)); sscanf(args,"%63s",voice); sentence=args+strlen(voice); #ifdef __APPLE__ - wavfile=mktemp("/tmp/linphonec-espeak-XXXXXX"); + mktemp(wavfile); #else - wavfile=tempnam("/tmp/","linphonec-espeak-"); + if (mkstemp(wavfile)==-1){ + ms_error("Could not create temporary filename: %s", strerror(errno)); + linphonec_out("An error occured, please consult logs for details."); + return 1; + } #endif snprintf(cl,sizeof(cl),"espeak -v %s -s 100 -w %s --stdin",voice,wavfile); @@ -2200,7 +2204,7 @@ static void linphonec_codec_list(int type, LinphoneCore *lc){ for(;node!=NULL;node=ms_list_next(node)){ pt=(PayloadType*)(node->data); - linphonec_out("%2d: %s (%d) %s\n", index, pt->mime_type, pt->clock_rate, + linphonec_out("%2d: %s (%d) %s\n", index, pt->mime_type, pt->clock_rate, linphone_core_payload_type_enabled(lc,pt) ? "enabled" : "disabled"); index++; } @@ -2274,7 +2278,7 @@ static int lpc_cmd_echocancellation(LinphoneCore *lc, char *args){ if (arg2 != 0) { n = sscanf(arg2, "%d %d %d", &delay, &tail_len, &frame_size); - if (n == 1) { + if (n == 1) { lp_config_set_int(config,"sound","ec_delay",delay); } else if (n == 2) { @@ -2292,11 +2296,11 @@ static int lpc_cmd_echocancellation(LinphoneCore *lc, char *args){ linphone_core_enable_echo_cancellation(lc,0); } else if (strcmp(arg1,"show")==0){ - linphonec_out("echo cancellation is %s; delay %d, tail length %d, frame size %d\n", + linphonec_out("echo cancellation is %s; delay %d, tail length %d, frame size %d\n", linphone_core_echo_cancellation_enabled(lc) ? "on" : "off", lp_config_get_int(config,"sound","ec_delay",0), lp_config_get_int(config,"sound","ec_tail_len",0), - lp_config_get_int(config,"sound","ec_framesize",0)); + lp_config_get_int(config,"sound","ec_framesize",0)); } else { return 0; @@ -2346,7 +2350,7 @@ static int lpc_cmd_rtp_no_xmit_on_audio_mute(LinphoneCore *lc, char *args) if(strstr(args,"1"))rtp_xmit_off=TRUE; if(linphone_core_get_current_call (lc)==NULL) linphone_core_set_rtp_no_xmit_on_audio_mute(lc,rtp_xmit_off); - else + else linphonec_out("nortp-on-audio-mute: call in progress - cannot change state\n"); } rtp_xmit_off=linphone_core_get_rtp_no_xmit_on_audio_mute(lc); @@ -2487,7 +2491,7 @@ static int lpc_cmd_states(LinphoneCore *lc, char *args){ static int lpc_cmd_camera(LinphoneCore *lc, char *args){ LinphoneCall *call=linphone_core_get_current_call(lc); bool_t activated=FALSE; - + if (linphone_core_video_enabled (lc)==FALSE){ linphonec_out("Video is disabled, re-run linphonec with -V option."); return 1; 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); diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index 36ca474b1..957c720ae 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -92,7 +92,7 @@ if HAVE_LD_OUTPUT_DEF liblinphone_la_LDFLAGS += -Wl,--output-def,liblinphone-$(LIBLINPHONE_SO_CURRENT).def defexecdir = $(libdir) defexec_DATA = liblinphone-$(LIBLINPHONE_SO_CURRENT).def -CLEANFILES = $(defexec_DATA) +CLEANFILES += $(defexec_DATA) liblinphone-$(LIBLINPHONE_SO_CURRENT).def: liblinphone.la @@ -157,15 +157,21 @@ AM_CFLAGS+= -DUSE_BELLESIP AM_CXXFLAGS=$(AM_CFLAGS) +#Make sure that we are in linphone's git tree by doing git log $(top_srcdir)/configure.ac. +#if it is something known to git, then that will be ok to check the git describe number and make sure it is consistent with +#the PACKAGE_VERSION given in configure.ac + make_gitversion_h: - if test "$(GITDESCRIBE)" != "" ; then \ - if test "$(GIT_TAG)" != "$(PACKAGE_VERSION)" ; then \ - echo "*** PACKAGE_VERSION and git tag differ. Please put them identical."; \ - exit 1; \ + if test -d $(top_srcdir)/.git ; then \ + if test "$(GITDESCRIBE)" != "" ; then \ + if test "$(GIT_TAG)" != "$(PACKAGE_VERSION)" ; then \ + echo "*** PACKAGE_VERSION and git tag differ. Please put them identical."; \ + exit 1; \ + fi ; \ + $(ECHO) -n "#define LIBLINPHONE_GIT_VERSION \"$(GITDESCRIBE)\"" > $(GITVERSION_FILE_TMP) ; \ + elif test "$(GITREVISION)" != "" ; then \ + $(ECHO) -n "#define LIBLINPHONE_GIT_VERSION \"$(LINPHONE_VERSION)_$(GITREVISION)\"" > $(GITVERSION_FILE_TMP) ; \ fi ; \ - $(ECHO) -n "#define LIBLINPHONE_GIT_VERSION \"$(GITDESCRIBE)\"" > $(GITVERSION_FILE_TMP) ; \ - elif test "$(GITREVISION)" != "" ; then \ - $(ECHO) -n "#define LIBLINPHONE_GIT_VERSION \"$(LINPHONE_VERSION)_$(GITREVISION)\"" > $(GITVERSION_FILE_TMP) ; \ else \ $(ECHO) -n "" > $(GITVERSION_FILE_TMP) ; \ fi diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index 92017616d..9693226dd 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -97,14 +97,13 @@ void sal_disable_logs() { void sal_add_pending_auth(Sal *sal, SalOp *op){ if (ms_list_find(sal->pending_auths,op)==NULL){ - sal->pending_auths=ms_list_append(sal->pending_auths,sal_op_ref(op)); + sal->pending_auths=ms_list_append(sal->pending_auths,op); } } void sal_remove_pending_auth(Sal *sal, SalOp *op){ if (ms_list_find(sal->pending_auths,op)){ sal->pending_auths=ms_list_remove(sal->pending_auths,op); - sal_op_unref(op); } } @@ -157,7 +156,10 @@ void sal_process_authentication(SalOp *op) { } } /*always store auth info, for case of wrong credential*/ - if (op->auth_info) sal_auth_info_delete(op->auth_info); + if (op->auth_info) { + sal_auth_info_delete(op->auth_info); + op->auth_info=NULL; + } if (auth_list){ auth_event=(belle_sip_auth_event_t*)(auth_list->data); op->auth_info=sal_auth_info_create(auth_event); @@ -321,9 +323,8 @@ static void process_response_event(void *user_ctx, const belle_sip_response_even belle_sip_message("Op is terminated, nothing to do with this [%i]",response_code); return; } - if (!op->base.remote_ua) { - sal_op_set_remote_ua(op,BELLE_SIP_MESSAGE(response)); - } + /*do it all the time, since we can receive provisional responses from a different instance than the final one*/ + sal_op_set_remote_ua(op,BELLE_SIP_MESSAGE(response)); if(remote_contact) { __sal_op_set_remote_contact(op, belle_sip_header_get_unparsed_value(BELLE_SIP_HEADER(remote_contact))); @@ -375,8 +376,8 @@ static void process_response_event(void *user_ctx, const belle_sip_response_even ms_error("Unhandled event response [%p]",event); } } - } + static void process_timeout(void *user_ctx, const belle_sip_timeout_event_t *event) { belle_sip_client_transaction_t* client_transaction = belle_sip_timeout_event_get_client_transaction(event); SalOp* op = (SalOp*)belle_sip_transaction_get_application_data(BELLE_SIP_TRANSACTION(client_transaction)); @@ -386,6 +387,7 @@ static void process_timeout(void *user_ctx, const belle_sip_timeout_event_t *eve ms_error("Unhandled event timeout [%p]",event); } } + static void process_transaction_terminated(void *user_ctx, const belle_sip_transaction_terminated_event_t *event) { belle_sip_client_transaction_t* client_transaction = belle_sip_transaction_terminated_event_get_client_transaction(event); belle_sip_server_transaction_t* server_transaction = belle_sip_transaction_terminated_event_get_server_transaction(event); @@ -404,7 +406,6 @@ static void process_transaction_terminated(void *user_ctx, const belle_sip_trans ms_message("Unhandled transaction terminated [%p]",trans); } if (op) sal_op_unref(op); /*because every transaction ref op*/ - } @@ -422,21 +423,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)); @@ -615,6 +616,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/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 4d61feca9..26bbdb038 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -27,16 +27,11 @@ static void call_set_released(SalOp* op){ op->state=SalOpStateTerminated; op->base.root->callbacks.call_released(op); op->call_released=TRUE; + /*be aware that the following line may destroy the op*/ + set_or_update_dialog(op,NULL); } } -/*used when the SalOp was ref'd by the dialog, in which case we rely only on the dialog terminated notification*/ -static void call_set_released_and_unref(SalOp* op) { - call_set_released(op); - sal_op_unref(op); -} - - static void call_set_error(SalOp* op,belle_sip_response_t* response){ sal_op_set_error_info_from_response(op,response); op->base.root->callbacks.call_failure(op); @@ -62,7 +57,7 @@ static void sdp_process(SalOp *h){ strcpy(h->result->addr,h->base.remote_media->addr); h->result->bandwidth=h->base.remote_media->bandwidth; - for(i=0;iresult->n_active_streams;++i){ + for(i=0;iresult);++i){ strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr); h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime; h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth; @@ -142,7 +137,7 @@ static void process_dialog_terminated(void *ctx, const belle_sip_dialog_terminat break; } belle_sip_main_loop_do_later(belle_sip_stack_get_main_loop(op->base.root->stack) - ,(belle_sip_callback_t) call_set_released_and_unref + ,(belle_sip_callback_t) call_set_released , op); } else { ms_error("dialog unknown for op "); @@ -172,6 +167,7 @@ static void cancelling_invite(SalOp* op ){ sal_op_send_request(op,cancel); op->state=SalOpStateTerminating; } + static int vfu_retry (void *user_data, unsigned int events) { SalOp *op=(SalOp *)user_data; sal_call_send_vfu_request(op); @@ -373,7 +369,7 @@ static int extract_sdp(belle_sip_message_t* message,belle_sdp_session_descriptio } static int is_media_description_acceptable(SalMediaDescription *md){ - if (md->n_total_streams==0){ + if (md->nb_streams==0){ ms_warning("Media description does not define any stream."); return FALSE; } diff --git a/coreapi/bellesip_sal/sal_op_call_transfer.c b/coreapi/bellesip_sal/sal_op_call_transfer.c index 5958c8745..84e529091 100644 --- a/coreapi/bellesip_sal/sal_op_call_transfer.c +++ b/coreapi/bellesip_sal/sal_op_call_transfer.c @@ -208,7 +208,7 @@ void sal_op_process_refer(SalOp *op, const belle_sip_request_event_t *event, bel belle_sip_free(refer_to_uri_str); } else { ms_warning("cannot do anything with the refer without destination\n"); - resp = sal_op_create_response_from_request(op,req,501); + resp = sal_op_create_response_from_request(op,req,400); belle_sip_server_transaction_send_response(server_transaction,resp); } @@ -233,9 +233,9 @@ void sal_op_call_process_notify(SalOp *op, const belle_sip_request_event_t *even if (sipfrag){ int code=belle_sip_response_get_status_code(sipfrag); SalReferStatus status=SalReferFailed; - if (code==100){ + if (code<200){ status=SalReferTrying; - }else if (code==200){ + }else if (code<300){ status=SalReferSuccess; }else if (code>=400){ status=SalReferFailed; diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index e2678dde0..649a4e240 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -44,8 +44,8 @@ void sal_op_release(SalOp *op){ void sal_op_release_impl(SalOp *op){ ms_message("Destroying op [%p] of type [%s]",op,sal_op_type_to_string(op->type)); if (op->pending_auth_transaction) belle_sip_object_unref(op->pending_auth_transaction); + sal_remove_pending_auth(op->base.root,op); if (op->auth_info) { - sal_remove_pending_auth(op->base.root,op); sal_auth_info_delete(op->auth_info); } if (op->sdp_answer) belle_sip_object_unref(op->sdp_answer); @@ -573,16 +573,17 @@ static belle_sip_dialog_t *link_op_with_dialog(SalOp *op, belle_sip_dialog_t* di } void set_or_update_dialog(SalOp* op, belle_sip_dialog_t* dialog) { - if (dialog==NULL) return; ms_message("op [%p] : set_or_update_dialog() current=[%p] new=[%p]",op,op->dialog,dialog); - if (dialog && op->dialog!=dialog){ + sal_op_ref(op); + if (op->dialog!=dialog){ if (op->dialog){ /*FIXME: shouldn't we delete unconfirmed dialogs ?*/ unlink_op_with_dialog(op,op->dialog); op->dialog=NULL; } - op->dialog=link_op_with_dialog(op,dialog); + if (dialog) op->dialog=link_op_with_dialog(op,dialog); } + sal_op_unref(op); } /*return reffed op*/ SalOp* sal_op_ref(SalOp* op) { @@ -607,6 +608,13 @@ int sal_op_send_and_create_refresher(SalOp* op,belle_sip_request_t* req, int exp belle_sip_object_unref(op->refresher); } if ((op->refresher = belle_sip_client_transaction_create_refresher(op->pending_client_trans))) { + /*since refresher acquires the transaction, we should remove our context from the transaction, because we won't be notified + * that it is terminated anymore.*/ + sal_op_unref(op);/*loose the reference that was given to the transaction when creating it*/ + /* Note that the refresher will replace our data with belle_sip_transaction_set_application_data(). + Something in the design is not very good here, it makes things complicated to the belle-sip user. + Possible ideas to improve things: refresher shall not use belle_sip_transaction_set_application_data() internally, refresher should let the first transaction + notify the user as a normal transaction*/ belle_sip_refresher_set_listener(op->refresher,listener,op); belle_sip_refresher_set_retry_after(op->refresher,op->base.root->refresher_retry_after); belle_sip_refresher_enable_manual_mode(op->refresher,op->manual_refresher); 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/coreapi/bellesip_sal/sal_sdp.c b/coreapi/bellesip_sal/sal_sdp.c index 268fbc480..fe952bb56 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); @@ -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); + } } } @@ -344,7 +355,7 @@ belle_sdp_session_description_t * media_description_to_sdp ( const SalMediaDescr belle_sdp_session_description_add_attribute(session_desc, create_rtcp_xr_attribute(&desc->rtcp_xr)); } - for ( i=0; in_total_streams; i++ ) { + for ( i=0; inb_streams; i++ ) { stream_description_to_sdp(session_desc, desc, &desc->streams[i]); } return session_desc; @@ -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: @@ -616,7 +630,7 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md, const char* value; const char *mtype,*proto; - stream=&md->streams[md->n_total_streams]; + stream=&md->streams[md->nb_streams]; media=belle_sdp_media_description_get_media ( media_desc ); memset ( stream,0,sizeof ( *stream ) ); @@ -642,9 +656,6 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md, stream->rtp_port=belle_sdp_media_get_media_port ( media ); - if ( stream->rtp_port > 0 ) - md->n_active_streams++; - mtype = belle_sdp_media_get_media_type ( media ); if ( strcasecmp ( "audio", mtype ) == 0 ) { stream->type=SalAudio; @@ -708,7 +719,7 @@ static SalStreamDescription * sdp_to_stream_description(SalMediaDescription *md, stream->rtcp_xr = md->rtcp_xr; // Use session parameters if no stream parameters are defined sdp_parse_media_rtcp_xr_parameters(media_desc, &stream->rtcp_xr); - md->n_total_streams++; + md->nb_streams++; return stream; } @@ -720,8 +731,7 @@ int sdp_to_media_description ( belle_sdp_session_description_t *session_desc, S belle_sdp_session_name_t *sname; const char* value; - desc->n_active_streams = 0; - desc->n_total_streams = 0; + desc->nb_streams = 0; desc->dir = SalStreamSendRecv; if ( ( cnx=belle_sdp_session_description_get_connection ( session_desc ) ) && belle_sdp_connection_get_address ( cnx ) ) { @@ -762,8 +772,8 @@ int sdp_to_media_description ( belle_sdp_session_description_t *session_desc, S for ( media_desc_it=belle_sdp_session_description_get_media_descriptions ( session_desc ) ; media_desc_it!=NULL ; media_desc_it=media_desc_it->next ) { - if (desc->n_total_streams==SAL_MEDIA_DESCRIPTION_MAX_STREAMS){ - ms_warning("Cannot convert mline at position [%i] from SDP to SalMediaDescription",desc->n_total_streams); + if (desc->nb_streams==SAL_MEDIA_DESCRIPTION_MAX_STREAMS){ + ms_warning("Cannot convert mline at position [%i] from SDP to SalMediaDescription",desc->nb_streams); break; } media_desc=BELLE_SDP_MEDIA_DESCRIPTION ( media_desc_it->data ); diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 9b427506b..121291a00 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -47,7 +47,8 @@ void linphone_core_update_streams_destinations(LinphoneCore *lc, LinphoneCall *c char *rtp_addr, *rtcp_addr; int i; - for (i = 0; i < new_md->n_active_streams; i++) { + for (i = 0; i < new_md->nb_streams; i++) { + if (!sal_stream_description_active(&new_md->streams[i])) continue; if (new_md->streams[i].type == SalAudio) { new_audiodesc = &new_md->streams[i]; } else if (new_md->streams[i].type == SalVideo) { @@ -108,7 +109,7 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia ms_error("linphone_core_update_streams() called with null media description"); return; } - if (call->biggestdesc==NULL || new_md->n_total_streams>call->biggestdesc->n_total_streams){ + if (call->biggestdesc==NULL || new_md->nb_streams>call->biggestdesc->nb_streams){ /*we have been offered and now are ready to proceed, or we added a new stream*/ /*store the media description to remember the mapping of calls*/ if (call->biggestdesc){ @@ -312,7 +313,8 @@ static void try_early_media_forking(LinphoneCall *call, SalMediaDescription *md) SalStreamDescription *ref_stream,*new_stream; ms_message("Early media response received from another branch, checking if media can be forked to this new destination."); - for (i=0;in_active_streams;++i){ + for (i=0;inb_streams;++i){ + if (!sal_stream_description_active(&cur_md->streams[i])) continue; ref_stream=&cur_md->streams[i]; new_stream=&md->streams[i]; if (ref_stream->type==new_stream->type && ref_stream->payloads && new_stream->payloads){ @@ -738,7 +740,8 @@ static void call_failure(SalOp *op){ || (call->state == LinphoneCallOutgoingRinging) /* Push notification case */ || (call->state == LinphoneCallOutgoingEarlyMedia)) { int i; - for (i = 0; i < call->localdesc->n_active_streams; i++) { + for (i = 0; i < call->localdesc->nb_streams; i++) { + if (!sal_stream_description_active(&call->localdesc->streams[i])) continue; if (call->params.media_encryption == LinphoneMediaEncryptionSRTP) { if (call->params.avpf_enabled == TRUE) { if (i == 0) ms_message("Retrying call [%p] with SAVP", call); @@ -814,7 +817,11 @@ static void call_released(SalOp *op){ LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op); if (call!=NULL){ linphone_call_set_state(call,LinphoneCallReleased,"Call released"); - }else ms_error("call_released() for already destroyed call ?"); + }else{ + /*we can arrive here when the core manages call at Sal level without creating a LinphoneCall object. Typicially: + * - when declining an incoming call with busy because maximum number of calls is reached. + */ + } } static void auth_failure(SalOp *op, SalAuthInfo* info) { diff --git a/coreapi/chat.c b/coreapi/chat.c index b66334262..5172c359e 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -29,6 +29,9 @@ #include "lime.h" #include "ortp/b64.h" +#include +#include + #define COMPOSING_DEFAULT_IDLE_TIMEOUT 15 #define COMPOSING_DEFAULT_REFRESH_TIMEOUT 60 #define COMPOSING_DEFAULT_REMOTE_REFRESH_TIMEOUT 120 @@ -36,20 +39,19 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage* msg); #define MULTIPART_BOUNDARY "---------------------------14737809831466499882746641449" -#define MULTIPART_HEADER_1 "--" MULTIPART_BOUNDARY "\r\n" \ - "Content-Disposition: form-data; name=\"File\"; filename=\"" -#define MULTIPART_HEADER_2 "\"\r\n" \ +#define FILEPART_HEADER_1 "Content-Disposition: form-data; name=\"File\"; filename=\"" +#define FILEPART_HEADER_2 "\"\r\n" \ "Content-Type: " -#define MULTIPART_HEADER_3 "\r\n\r\n" -#define MULTIPART_END "\r\n--" MULTIPART_BOUNDARY "--\r\n" +#define FILEPART_HEADER_3 "\r\n\r\n" const char *multipart_boundary=MULTIPART_BOUNDARY; #define FILE_TRANSFER_KEY_SIZE 32 -static size_t linphone_chat_message_compute_multipart_header_size(const char *filename, const char *content_type) { - return strlen(MULTIPART_HEADER_1)+strlen(filename)+strlen(MULTIPART_HEADER_2)+strlen(content_type)+strlen(MULTIPART_HEADER_3); +static size_t linphone_chat_message_compute_filepart_header_size(const char *filename, const char *content_type) { + return strlen(FILEPART_HEADER_1)+strlen(filename)+strlen(FILEPART_HEADER_2)+strlen(content_type)+strlen(FILEPART_HEADER_3); } static void process_io_error(void *data, const belle_sip_io_error_event_t *event){ - printf("We have a response io error!\n"); + LinphoneChatMessage* msg=(LinphoneChatMessage *)data; + msg->cb(msg, LinphoneChatMessageStateNotDelivered, msg->chat_room->lc); } static void process_auth_requested(void *data, belle_sip_auth_event_t *event){ printf("We have a auth requested!\n"); @@ -80,24 +82,25 @@ 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; - + size_t end_of_file=linphone_chat_message_compute_filepart_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)); + int partlen=linphone_chat_message_compute_filepart_header_size(chatMsg->file_transfer_information->name, content_type); + memcpy(buf,FILEPART_HEADER_1,strlen(FILEPART_HEADER_1)); + buf += strlen(FILEPART_HEADER_1); + memcpy(buf,chatMsg->file_transfer_information->name,strlen(chatMsg->file_transfer_information->name)); + buf += strlen(chatMsg->file_transfer_information->name); + memcpy(buf,FILEPART_HEADER_2,strlen(FILEPART_HEADER_2)); + buf += strlen(FILEPART_HEADER_2); + memcpy(buf,content_type,strlen(content_type)); + buf += strlen(content_type); + memcpy(buf,FILEPART_HEADER_3,strlen(FILEPART_HEADER_3)); *size=partlen; }else if (offsetvtable.file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, plainBuffer, size); - lime_encryptFile(&(chatMsg->file_transfer_information->cryptoContext), chatMsg->file_transfer_information->key, *size, plainBuffer, buffer); + lime_encryptFile(&(chatMsg->file_transfer_information->cryptoContext), chatMsg->file_transfer_information->key, *size, plainBuffer, (char*)buffer); free(plainBuffer); } else { /* get data from call back directly to the output buffer */ - lc->vtable.file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, buffer, size); + lc->vtable.file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, (char*)buffer, size); } /* DEBUG DEBUG : THIS SHALL NEVER HAPPEND */ if (*size == 0) { @@ -124,9 +127,6 @@ static int linphone_chat_message_file_transfer_on_send_body(belle_sip_user_body_ if (chatMsg->file_transfer_information->key != NULL) { lime_encryptFile(&(chatMsg->file_transfer_information->cryptoContext), NULL, 0, NULL, NULL); } - - *size=strlen(MULTIPART_END); - strncpy(buffer,MULTIPART_END,*size); } belle_sip_free(content_type); @@ -160,17 +160,25 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co belle_generic_uri_t *uri; belle_http_request_t *req; char *content_type=belle_sip_strdup_printf("%s/%s", msg->file_transfer_information->type, msg->file_transfer_information->subtype); - belle_sip_user_body_handler_t *bh=belle_sip_user_body_handler_new(msg->file_transfer_information->size+linphone_chat_message_compute_multipart_header_size(msg->file_transfer_information->name, content_type)+strlen(MULTIPART_END), linphone_chat_message_file_transfer_on_progress, NULL, linphone_chat_message_file_transfer_on_send_body, msg); + + /* create a user body handler to take care of the file */ + belle_sip_user_body_handler_t *first_part_bh=belle_sip_user_body_handler_new(msg->file_transfer_information->size+linphone_chat_message_compute_filepart_header_size(msg->file_transfer_information->name, content_type), NULL, NULL, linphone_chat_message_file_transfer_on_send_body, msg); + /* insert it in a multipart body handler which will manage the boundaries of multipart message */ + belle_sip_multipart_body_handler_t *bh=belle_sip_multipart_body_handler_new(linphone_chat_message_file_transfer_on_progress, msg, (belle_sip_body_handler_t *)first_part_bh); + + char* ua = ms_strdup_printf("%s/%s", linphone_core_get_user_agent_name(), linphone_core_get_user_agent_version()); + belle_sip_free(content_type); content_type=belle_sip_strdup_printf("multipart/form-data; boundary=%s",multipart_boundary); - + uri=belle_generic_uri_parse(msg->chat_room->lc->file_transfer_server); - + req=belle_http_request_create("POST", - uri, - belle_sip_header_create("User-Agent","belle-sip/" PACKAGE_VERSION), - belle_sip_header_create("Content-type",content_type), - NULL); + uri, + belle_sip_header_create("User-Agent",ua), + belle_sip_header_create("Content-type",content_type), + NULL); + ms_free(ua); belle_sip_free(content_type); belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req),BELLE_SIP_BODY_HANDLER(bh)); cbs.process_response=linphone_chat_message_process_response_from_post_file; @@ -228,7 +236,7 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co _linphone_chat_room_send_message(msg->chat_room, msg); } } - + } @@ -385,9 +393,9 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM belle_http_request_listener_t *l; belle_generic_uri_t *uri; belle_http_request_t *req; - + uri=belle_generic_uri_parse(cr->lc->file_transfer_server); - + req=belle_http_request_create("POST", uri, NULL, @@ -521,16 +529,19 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag } 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); - - xmlNodePtr cur = xmlDocGetRootElement(xmlMessageBody); + xmlMessageBody = xmlParseDoc((const xmlChar *)sal_msg->text); + + cur = xmlDocGetRootElement(xmlMessageBody); if (cur != NULL) { cur = cur->xmlChildrenNode; while (cur!=NULL) { @@ -539,26 +550,26 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag if(!xmlStrcmp(typeAttribute, (const xmlChar *)"file")) { /* this is the node we are looking for */ cur = cur->xmlChildrenNode; /* now loop on the content of the file-info node */ while (cur!=NULL) { - if (!xmlStrcmp(cur->name, (const xmlChar *)"file-size")) { + if (!xmlStrcmp(cur->name, (const xmlChar *)"file-size")) { xmlChar *fileSizeString = xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1); msg->file_transfer_information->size = strtol((const char*)fileSizeString, NULL, 10); xmlFree(fileSizeString); } - if (!xmlStrcmp(cur->name, (const xmlChar *)"file-name")) { + if (!xmlStrcmp(cur->name, (const xmlChar *)"file-name")) { msg->file_transfer_information->name = (char *)xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1); } - if (!xmlStrcmp(cur->name, (const xmlChar *)"content-type")) { + if (!xmlStrcmp(cur->name, (const xmlChar *)"content-type")) { xmlChar *contentType = xmlNodeListGetString(xmlMessageBody, cur->xmlChildrenNode, 1); int contentTypeIndex = 0; while (contentType[contentTypeIndex]!='/' && contentType[contentTypeIndex]!='\0') { contentTypeIndex++; } - msg->file_transfer_information->type = strndup((char *)contentType, contentTypeIndex); - msg->file_transfer_information->subtype = strdup(((char *)contentType+contentTypeIndex+1)); + msg->file_transfer_information->type = ms_strndup((char *)contentType, contentTypeIndex); + msg->file_transfer_information->subtype = ms_strdup(((char *)contentType+contentTypeIndex+1)); xmlFree(contentType); } - if (!xmlStrcmp(cur->name, (const xmlChar *)"data")) { + if (!xmlStrcmp(cur->name, (const xmlChar *)"data")) { file_url = xmlGetProp(cur, (const xmlChar *)"url"); } @@ -1027,7 +1038,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 uint8_t *buffer, size_t size){ /* first call may be with a zero size, ignore it */ if (size == 0) { return; @@ -1047,7 +1058,7 @@ static void on_recv_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t } else { /* regular file, no deciphering */ /* 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; @@ -1061,7 +1072,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) @@ -1101,14 +1112,17 @@ 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); - + req=belle_http_request_create("GET", uri, - belle_sip_header_create("User-Agent","belle-sip/" PACKAGE_VERSION), + belle_sip_header_create("User-Agent",ua), NULL); + ms_free(ua); + cbs.process_response_headers=linphone_chat_process_response_headers_from_get_file; cbs.process_response=linphone_chat_process_response_from_get_file; cbs.process_io_error=process_io_error; diff --git a/coreapi/event.c b/coreapi/event.c index b1c7b110d..992d058ab 100644 --- a/coreapi/event.c +++ b/coreapi/event.c @@ -79,12 +79,15 @@ static LinphoneEvent *linphone_event_new_with_op_base(LinphoneCore *lc, SalOp *o lev->is_out_of_dialog_op=is_out_of_dialog; return lev; } + LinphoneEvent *linphone_event_new_with_op(LinphoneCore *lc, SalOp *op, LinphoneSubscriptionDir dir, const char *name) { return linphone_event_new_with_op_base(lc,op,dir,name,FALSE); } + LinphoneEvent *linphone_event_new_with_out_of_dialog_op(LinphoneCore *lc, SalOp *op, LinphoneSubscriptionDir dir, const char *name) { return linphone_event_new_with_op_base(lc,op,dir,name,TRUE); } + void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState state){ LinphoneCore *lc=lev->lc; if (lev->subscription_state!=state){ @@ -107,9 +110,22 @@ void linphone_event_set_publish_state(LinphoneEvent *lev, LinphonePublishState s if (lc->vtable.publish_state_changed){ lc->vtable.publish_state_changed(lev->lc,lev,state); } - if (state==LinphonePublishCleared){ - linphone_event_unref(lev); + switch(state){ + case LinphonePublishCleared: + linphone_event_unref(lev); + break; + case LinphonePublishOk: + case LinphonePublishError: + if (lev->expires==-1) + linphone_event_unref(lev); + break; + case LinphonePublishNone: + case LinphonePublishProgress: + case LinphonePublishExpiring: + /*nothing special to do*/ + break; } + } } diff --git a/coreapi/event.h b/coreapi/event.h index 4b3e26bd9..894f3e32a 100644 --- a/coreapi/event.h +++ b/coreapi/event.h @@ -37,9 +37,9 @@ typedef struct _LinphoneEvent LinphoneEvent; * Enum for subscription direction (incoming or outgoing). **/ enum _LinphoneSubscriptionDir{ - LinphoneSubscriptionIncoming, - LinphoneSubscriptionOutgoing, - LinphoneSubscriptionInvalidDir + LinphoneSubscriptionIncoming, /**< Incoming subscription. */ + LinphoneSubscriptionOutgoing, /**< Outgoing subscription. */ + LinphoneSubscriptionInvalidDir /**< Invalid subscription direction. */ }; /** @@ -210,7 +210,7 @@ LINPHONE_PUBLIC LinphoneReason linphone_event_get_reason(const LinphoneEvent *le /** * Get full details about an error occured. **/ -const LinphoneErrorInfo *linphone_event_get_error_info(const LinphoneEvent *lev); +LINPHONE_PUBLIC const LinphoneErrorInfo *linphone_event_get_error_info(const LinphoneEvent *lev); /** * Get subscription state. If the event object was not created by a subscription mechanism, #LinphoneSubscriptionNone is returned. diff --git a/coreapi/help/doxygen.dox b/coreapi/help/doxygen.dox index 656f25e09..8831758d6 100644 --- a/coreapi/help/doxygen.dox +++ b/coreapi/help/doxygen.dox @@ -61,7 +61,7 @@ *like \link linphone_proxy_config_set_server_addr() proxy address \endlink , \link linphone_proxy_config_set_identity() user id \endlink, \link linphone_proxy_config_expires() refresh period \endlink, and so on. *
A created proxy config using linphone_proxy_config_new(), once configured, must be added to #LinphoneCore using function linphone_core_add_proxy_config(). *
It is recommended to set a default \link #LinphoneProxyConfig proxy config \endlink using function linphone_core_set_default_proxy(). Once done, if \link #LinphoneProxyConfig a proxy config \endlink has been configured with attribute \link linphone_proxy_config_enable_register() enable register \endlink , next call to linphone_core_iterate() triggers a SIP register. - *
Registration status is reported by #LinphoneRegistrationStateCb. + *
Registration status is reported by LinphoneCoreRegistrationStateChangedCb. *
*
This pseudo code demonstrates basic registration operations: *
\code @@ -96,7 +96,7 @@ } \endcode *
Authentication: - *
Most of the time, registration requires \ref authentication "authentication" to succed. #LinphoneAuthInfo info must be either added to #LinphoneCore using function linphone_core_add_auth_info() before #LinphoneProxyConfig is added to Linphone core, or on demand from call back #AuthInfoRequested . + *
Most of the time, registration requires \ref authentication "authentication" to succeed. #LinphoneAuthInfo info must be either added to #LinphoneCore using function linphone_core_add_auth_info() before #LinphoneProxyConfig is added to Linphone core, or on demand from call back #LinphoneCoreAuthInfoRequestedCb. *
*
Unregistration: *
Unregistration or any changes to #LinphoneProxyConfig must be first started by a call to function linphone_proxy_config_edit() and validated by function linphone_proxy_config_done() @@ -203,7 +203,7 @@ void text_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddre * While initiating the second call, the first one is automatically paused. * Then, once the second call is established, the application has the possibility to merge the two calls to form a conference where each participant * (the local participant, the remote destination of the first call, the remote destination of the second call) can talk together. - * This must be done by adding the two calls to the conference using \link linphone_call_add_to_conference() \endlink + * This must be done by adding the two calls to the conference using \link linphone_core_add_to_conference() \endlink * * Once merged into a conference the LinphoneCall objects representing the calls that were established remain unchanged, except that * they are tagged as part of the conference (see \link linphone_call_is_in_conference() \endlink ). The calls in a conference are in the LinphoneCallStreamsRunning state. @@ -270,7 +270,7 @@ and register a keep-alive handler for periodically refreshing the registration. }]; \endcode
  • Incoming call notification while in background mode -
    Assuming application using liblinphone is well configured for multitasking, incoming calls arriving while liblinphone is in background mode will simply wakeup liblinphone thread but not resume GUI. To wakeup GUI, it is recommended to send a Local Notification to the user from the #LinphoneCallStateCb. Here under a speudo code for this operation: +
    Assuming application using liblinphone is well configured for multitasking, incoming calls arriving while liblinphone is in background mode will simply wakeup liblinphone thread but not resume GUI. To wakeup GUI, it is recommended to send a Local Notification to the user from the #LinphoneCoreCallStateChangedCb. Here under a speudo code for this operation: \code if ([UIApplication sharedApplication].applicationState != UIApplicationStateActive) { // Create a new notification diff --git a/coreapi/help/filetransfer.c b/coreapi/help/filetransfer.c index 4af168ee3..552137688 100644 --- a/coreapi/help/filetransfer.c +++ b/coreapi/help/filetransfer.c @@ -62,26 +62,30 @@ static void file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMess } /** * function invoked when a file transfer is received. - * */ + **/ static void file_transfer_received(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size){ - int file=-1; + FILE* file=NULL; if (!linphone_chat_message_get_user_data(message)) { /*first chunk, creating file*/ - file = open("receive_file.dump",O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); - linphone_chat_message_set_user_data(message,(void*)(long)(0x00000000FFFFFFFF&file)); /*store fd for next chunks*/ - } + file = fopen("receive_file.dump","wb"); + linphone_chat_message_set_user_data(message,(void*)file); /*store fd for next chunks*/ + } else { + /*next chunk*/ + file = (FILE*)linphone_chat_message_get_user_data(message); /*next chunk*/ file = (int)((long)(linphone_chat_message_get_user_data(message))&0x00000000FFFFFFFF); - if (size==0) { - printf("File transfert completed\n"); - linphone_chat_room_destroy(linphone_chat_message_get_chat_room(message)); - linphone_chat_message_destroy(message); - close(file); - running=FALSE; - } else { /* store content on a file*/ - write(file,buff,size); + printf("File transfert completed\n"); + linphone_chat_room_destroy(linphone_chat_message_get_chat_room(message)); + linphone_chat_message_destroy(message); + fclose(file); + running=FALSE; + } else { /* store content on a file*/ + if (fwrite(buff,size,1,file)==-1){ + ms_warning("file_transfer_received() write failed: %s",strerror(errno)); + } + } } } @@ -117,7 +121,7 @@ static void file_transfer_send(LinphoneCore *lc, LinphoneChatMessage *message, */ static void message_received(LinphoneCore *lc, LinphoneChatRoom *cr, LinphoneChatMessage *msg) { const LinphoneContent *file_transfer_info = linphone_chat_message_get_file_transfer_information(msg); - printf ("Do you really want to download %s (size %ld)?[Y/n]\nOk, let's go\n", file_transfer_info->name, file_transfer_info->size); + printf ("Do you really want to download %s (size %ld)?[Y/n]\nOk, let's go\n", file_transfer_info->name, (long int)file_transfer_info->size); linphone_chat_message_start_file_download(msg); diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 7e4cbd520..3255c118c 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; } @@ -254,11 +254,12 @@ static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandw static void update_media_description_from_stun(SalMediaDescription *md, const StunCandidate *ac, const StunCandidate *vc){ int i; - for (i = 0; i < md->n_active_streams; i++) { + for (i = 0; i < md->nb_streams; i++) { + if (!sal_stream_description_active(&md->streams[i])) continue; if ((md->streams[i].type == SalAudio) && (ac->port != 0)) { strcpy(md->streams[0].rtp_addr,ac->addr); md->streams[0].rtp_port=ac->port; - if ((ac->addr[0]!='\0' && vc->addr[0]!='\0' && strcmp(ac->addr,vc->addr)==0) || md->n_active_streams==1){ + if ((ac->addr[0]!='\0' && vc->addr[0]!='\0' && strcmp(ac->addr,vc->addr)==0) || sal_media_description_get_nb_active_streams(md)==1){ strcpy(md->addr,ac->addr); } } @@ -301,9 +302,10 @@ static void setup_encryption_keys(LinphoneCall *call, SalMediaDescription *md){ SalMediaDescription *old_md=call->localdesc; bool_t keep_srtp_keys=lp_config_get_int(lc->config,"sip","keep_srtp_keys",1); - for(i=0; in_active_streams; i++) { - if (stream_description_has_srtp(&md->streams[i]) == TRUE) { - if (keep_srtp_keys && old_md && stream_description_has_srtp(&old_md->streams[i]) == TRUE){ + for(i=0; inb_streams; i++) { + if (!sal_stream_description_active(&md->streams[i])) continue; + if (sal_stream_description_has_srtp(&md->streams[i]) == TRUE) { + if (keep_srtp_keys && old_md && sal_stream_description_has_srtp(&old_md->streams[i]) == TRUE){ int j; ms_message("Keeping same crypto keys."); for(j=0;jn_active_streams; i++) { + for (i = 0; i < md->nb_streams; i++) { + if (!sal_stream_description_active(&md->streams[i])) continue; for (pt_it = md->streams[i].payloads; pt_it != NULL; pt_it = pt_it->next) { pt = (PayloadType *)pt_it->data; if (call->params.avpf_enabled == TRUE) { 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)); @@ -363,7 +363,8 @@ static void setup_rtcp_xr(LinphoneCall *call, SalMediaDescription *md) { } md->rtcp_xr.voip_metrics_enabled = lp_config_get_int(lc->config, "rtp", "rtcp_xr_voip_metrics_enabled", 0); } - for (i = 0; i < md->n_active_streams; i++) { + for (i = 0; i < md->nb_streams; i++) { + if (!sal_stream_description_active(&md->streams[i])) continue; memcpy(&md->streams[i].rtcp_xr, &md->rtcp_xr, sizeof(md->streams[i].rtcp_xr)); } } @@ -385,6 +386,7 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall * PayloadType *pt; SalMediaDescription *old_md=call->localdesc; int i; + int nb_active_streams = 0; const char *me; SalMediaDescription *md=sal_media_description_new(); LinphoneAddress *addr; @@ -401,7 +403,7 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall * md->session_id=(old_md ? old_md->session_id : (rand() & 0xfff)); md->session_ver=(old_md ? (old_md->session_ver+1) : (rand() & 0xfff)); - md->n_total_streams=(call->biggestdesc ? call->biggestdesc->n_total_streams : 1); + md->nb_streams=(call->biggestdesc ? call->biggestdesc->nb_streams : 1); strncpy(md->addr,local_ip,sizeof(md->addr)); strncpy(md->username,linphone_address_get_username(addr),sizeof(md->username)); @@ -412,7 +414,6 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall * else md->bandwidth=linphone_core_get_download_bandwidth(lc); /*set audio capabilities */ - md->n_active_streams=1; strncpy(md->streams[0].rtp_addr,local_ip,sizeof(md->streams[0].rtp_addr)); strncpy(md->streams[0].rtcp_addr,local_ip,sizeof(md->streams[0].rtcp_addr)); strncpy(md->streams[0].name,"Audio",sizeof(md->streams[0].name)-1); @@ -428,22 +429,26 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall * pt=payload_type_clone(rtp_profile_get_payload_from_mime(lc->default_profile,"telephone-event")); l=ms_list_append(l,pt); md->streams[0].payloads=l; + nb_active_streams++; if (call->params.has_video){ - md->n_active_streams++; - strncpy(md->streams[0].name,"Video",sizeof(md->streams[0].name)-1); + strncpy(md->streams[1].rtp_addr,local_ip,sizeof(md->streams[1].rtp_addr)); + strncpy(md->streams[1].rtcp_addr,local_ip,sizeof(md->streams[1].rtcp_addr)); + strncpy(md->streams[1].name,"Video",sizeof(md->streams[1].name)-1); md->streams[1].rtp_port=call->media_ports[1].rtp_port; md->streams[1].rtcp_port=call->media_ports[1].rtcp_port; md->streams[1].proto=md->streams[0].proto; md->streams[1].type=SalVideo; l=make_codec_list(lc,lc->codecs_conf.video_codecs,0,NULL,-1); md->streams[1].payloads=l; + nb_active_streams++; } - if (md->n_total_streams < md->n_active_streams) - md->n_total_streams = md->n_active_streams; + + if (md->nb_streams < nb_active_streams) + md->nb_streams = nb_active_streams; /* Deactivate inactive streams. */ - for (i = md->n_active_streams; i < md->n_total_streams; i++) { + for (i = nb_active_streams; i < md->nb_streams; i++) { md->streams[i].rtp_port = 0; md->streams[i].rtcp_port = 0; md->streams[i].proto = call->biggestdesc->streams[i].proto; @@ -674,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; @@ -708,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); /* @@ -722,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 = media_description_has_avpf(md); - if ((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*/ @@ -811,6 +831,7 @@ static void linphone_call_set_terminated(LinphoneCall *call){ void linphone_call_fix_call_parameters(LinphoneCall *call){ call->params.has_video=call->current_params.has_video; + if (call->params.media_encryption != LinphoneMediaEncryptionZRTP) /*in case of ZRTP call parameter are handle after zrtp negociation*/ call->params.media_encryption=call->current_params.media_encryption; } @@ -898,17 +919,10 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const call->media_start_time=time(NULL); } - if (cstate == LinphoneCallStreamsRunning) { - linphone_reporting_update_ip(call); - } - if (lc->vtable.call_state_changed) lc->vtable.call_state_changed(lc,call,cstate,message); - if (cstate==LinphoneCallEnd){ - if (call->log->status == LinphoneCallSuccess) - linphone_reporting_publish_session_report(call); - } + linphone_reporting_call_state_updated(call); if (cstate==LinphoneCallReleased){ if (call->op!=NULL) { @@ -1062,12 +1076,12 @@ const LinphoneCallParams * linphone_call_get_remote_params(LinphoneCall *call){ for (i = 0; i < nb_video_streams; i++) { sd = sal_media_description_get_active_stream_of_type(md, SalVideo, i); - if (is_video_active(sd) == TRUE) cp->has_video = TRUE; - if (stream_description_has_srtp(sd) == TRUE) cp->media_encryption = LinphoneMediaEncryptionSRTP; + if (sal_stream_description_active(sd) == TRUE) cp->has_video = TRUE; + if (sal_stream_description_has_srtp(sd) == TRUE) cp->media_encryption = LinphoneMediaEncryptionSRTP; } for (i = 0; i < nb_audio_streams; i++) { sd = sal_media_description_get_active_stream_of_type(md, SalAudio, i); - if (stream_description_has_srtp(sd) == TRUE) cp->media_encryption = LinphoneMediaEncryptionSRTP; + if (sal_stream_description_has_srtp(sd) == TRUE) cp->media_encryption = LinphoneMediaEncryptionSRTP; } if (!cp->has_video){ if (md->bandwidth>0 && md->bandwidth<=linphone_core_get_edge_bw(call->core)){ @@ -1565,7 +1579,7 @@ static void _linphone_call_prepare_ice_for_stream(LinphoneCall *call, int stream cl=ice_session_check_list(call->ice_session, stream_index); if (cl == NULL && create_checklist) { cl=ice_check_list_new(); - ice_session_add_check_list(call->ice_session, cl); + ice_session_add_check_list(call->ice_session, cl, stream_index); ms_message("Created new ICE check list for stream [%i]",stream_index); } if (cl){ @@ -2044,7 +2058,7 @@ static void linphone_call_start_audio_stream(LinphoneCall *call, const char *cna call->current_params.record_file=ms_strdup(call->params.record_file); } /* valid local tags are > 0 */ - if (stream_description_has_srtp(stream) == TRUE) { + if (sal_stream_description_has_srtp(stream) == TRUE) { local_st_desc=sal_media_description_find_stream(call->localdesc,stream->proto,SalAudio); crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, stream->crypto_local_tag); @@ -2161,7 +2175,7 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna cam=get_nowebcam_device(); } if (!is_inactive){ - if (stream_description_has_srtp(vstream) == TRUE) { + if (sal_stream_description_has_srtp(vstream) == TRUE) { int crypto_idx = find_crypto_index_from_tag(local_st_desc->crypto, vstream->crypto_local_tag); if (crypto_idx >= 0) { media_stream_set_srtp_recv_key(&call->videostream->ms,vstream->crypto[0].algo,vstream->crypto[0].master_key); @@ -2175,6 +2189,7 @@ static void linphone_call_start_video_stream(LinphoneCall *call, const char *cna ms_message("%s lc rotation:%d\n", __FUNCTION__, lc->device_rotation); video_stream_set_device_rotation(call->videostream, lc->device_rotation); video_stream_set_rtcp_information(call->videostream, cname, rtcp_tool); + video_stream_set_freeze_on_error(call->videostream, lp_config_get_int(lc->config, "video", "freeze_on_error", 0)); video_stream_start(call->videostream, call->video_profile, rtp_addr, vstream->rtp_port, rtcp_addr, @@ -2884,7 +2899,7 @@ void linphone_call_notify_stats_updated(LinphoneCall *call, int stream_index){ LinphoneCallStats *stats=&call->stats[stream_index]; LinphoneCore *lc=call->core; if (stats->updated){ - linphone_reporting_on_rtcp_received(call, stream_index); + linphone_reporting_on_rtcp_update(call, stream_index); if (lc->vtable.call_stats_updated) lc->vtable.call_stats_updated(lc, call, stats); stats->updated = 0; @@ -3086,7 +3101,7 @@ static LinphoneAddress *get_fixed_contact(LinphoneCore *lc, LinphoneCall *call , } else { ctt=linphone_core_get_primary_contact_parsed(lc); if (ctt!=NULL){ - /*otherwise use supllied localip*/ + /*otherwise use supplied localip*/ linphone_address_set_domain(ctt,localip); linphone_address_set_port(ctt,linphone_core_get_sip_port(lc)); ms_message("Contact has been fixed using local ip"/* to %s",ret*/); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 234ee1324..b06e26a6b 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -129,8 +129,8 @@ LinphoneCallLog * linphone_call_log_new(LinphoneCall *call, LinphoneAddress *fro cl->status=LinphoneCallAborted; /*default status*/ cl->quality=-1; - cl->reports[LINPHONE_CALL_STATS_AUDIO]=linphone_reporting_new(); - cl->reports[LINPHONE_CALL_STATS_VIDEO]=linphone_reporting_new(); + cl->reporting.reports[LINPHONE_CALL_STATS_AUDIO]=linphone_reporting_new(); + cl->reporting.reports[LINPHONE_CALL_STATS_VIDEO]=linphone_reporting_new(); return cl; } @@ -394,8 +394,8 @@ void linphone_call_log_destroy(LinphoneCallLog *cl){ if (cl->to!=NULL) linphone_address_destroy(cl->to); if (cl->refkey!=NULL) ms_free(cl->refkey); if (cl->call_id) ms_free(cl->call_id); - if (cl->reports[LINPHONE_CALL_STATS_AUDIO]!=NULL) linphone_reporting_destroy(cl->reports[LINPHONE_CALL_STATS_AUDIO]); - if (cl->reports[LINPHONE_CALL_STATS_VIDEO]!=NULL) linphone_reporting_destroy(cl->reports[LINPHONE_CALL_STATS_VIDEO]); + if (cl->reporting.reports[LINPHONE_CALL_STATS_AUDIO]!=NULL) linphone_reporting_destroy(cl->reporting.reports[LINPHONE_CALL_STATS_AUDIO]); + if (cl->reporting.reports[LINPHONE_CALL_STATS_VIDEO]!=NULL) linphone_reporting_destroy(cl->reporting.reports[LINPHONE_CALL_STATS_VIDEO]); ms_free(cl); } @@ -719,7 +719,7 @@ static void sip_config_read(LinphoneCore *lc) /* get proxies config */ for(i=0;; i++){ - LinphoneProxyConfig *cfg=linphone_proxy_config_new_from_config_file(lc->config,i); + LinphoneProxyConfig *cfg=linphone_proxy_config_new_from_config_file(lc,i); if (cfg!=NULL){ linphone_core_add_proxy_config(lc,cfg); }else{ @@ -1925,6 +1925,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; @@ -2388,7 +2397,7 @@ void linphone_core_iterate(LinphoneCore *lc){ * * @ingroup call_control * - * A sip address should look like DisplayName . + * A sip address should look like DisplayName \ . * Basically this function performs the following tasks * - if a phone number is entered, prepend country prefix of the default proxy * configuration, eventually escape the '+' by 00. @@ -2572,6 +2581,7 @@ static MSList *make_routes_for_proxy(LinphoneProxyConfig *proxy, const LinphoneA LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const LinphoneAddress *uri){ const MSList *elem; LinphoneProxyConfig *found_cfg=NULL; + LinphoneProxyConfig *found_reg_cfg=NULL; LinphoneProxyConfig *found_noreg_cfg=NULL; LinphoneProxyConfig *default_cfg=lc->default_proxy; @@ -2584,21 +2594,25 @@ LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const L } } - /*otherwise return first registering matching, otherwise first matching */ + /*otherwise return first registered, then first registering matching, otherwise first matching */ for (elem=linphone_core_get_proxy_config_list(lc);elem!=NULL;elem=elem->next){ LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)elem->data; const char *domain=linphone_proxy_config_get_domain(cfg); if (domain!=NULL && strcmp(domain,linphone_address_get_domain(uri))==0){ - if (linphone_proxy_config_register_enabled(cfg)) { + if (linphone_proxy_config_get_state(cfg) == LinphoneRegistrationOk ){ found_cfg=cfg; - goto end; + break; + } else if (!found_reg_cfg && linphone_proxy_config_register_enabled(cfg)) { + found_reg_cfg=cfg; } else if (!found_noreg_cfg){ found_noreg_cfg=cfg; } } } end: - if (!found_cfg && found_noreg_cfg) found_cfg = found_noreg_cfg; + if ( !found_cfg && found_reg_cfg) found_cfg = found_reg_cfg; + else if( !found_cfg && found_noreg_cfg ) found_cfg = found_noreg_cfg; + if (found_cfg && found_cfg!=default_cfg){ ms_debug("Overriding default proxy setting for this call/message/subscribe operation."); }else if (!found_cfg) found_cfg=default_cfg; /*when no matching proxy config is found, use the default proxy config*/ @@ -2856,7 +2870,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*/ @@ -2968,7 +2982,7 @@ int linphone_core_transfer_call(LinphoneCore *lc, LinphoneCall *call, const char * * It is possible to follow the progress of the transfer provided that transferee sends notification about it. * In this case, the transfer_state_changed callback of the #LinphoneCoreVTable is invoked to notify of the state of the new call at the other party. - * The notified states are #LinphoneCallOutgoingInit , #LinphoneCallOutgoingProgress, #LinphoneCallOutgoingRinging and #LinphoneCallOutgoingConnected. + * The notified states are #LinphoneCallOutgoingInit , #LinphoneCallOutgoingProgress, #LinphoneCallOutgoingRinging and #LinphoneCallConnected. **/ int linphone_core_transfer_call_to_another(LinphoneCore *lc, LinphoneCall *call, LinphoneCall *dest){ int result = sal_call_refer_with_replaces (call->op,dest->op); @@ -2988,7 +3002,7 @@ bool_t linphone_core_inc_invite_pending(LinphoneCore*lc){ } bool_t linphone_core_incompatible_security(LinphoneCore *lc, SalMediaDescription *md){ - return linphone_core_is_media_encryption_mandatory(lc) && linphone_core_get_media_encryption(lc)==LinphoneMediaEncryptionSRTP && !media_description_has_srtp(md); + return linphone_core_is_media_encryption_mandatory(lc) && linphone_core_get_media_encryption(lc)==LinphoneMediaEncryptionSRTP && !sal_media_description_has_srtp(md); } void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){ @@ -3268,7 +3282,6 @@ int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call) linphone_core_update_streams (lc,call,md); linphone_call_fix_call_parameters(call); } - if (call->state != LinphoneCallOutgoingEarlyMedia) /*don't change the state in case of outgoing early (SIP UPDATE)*/ linphone_call_set_state(call,LinphoneCallStreamsRunning,"Connected (streams running)"); return 0; @@ -3440,12 +3453,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 = media_description_has_avpf(md); - if ((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); @@ -6575,11 +6583,6 @@ bool_t linphone_core_sdp_200_ack_enabled(const LinphoneCore *lc) { return lc->sip_conf.sdp_200_ack!=0; } -/** - * Globaly set an http file transfer server to be used for content type application/vnd.gsma.rcs-ft-http+xml. This value can also be set for a dedicated account using #linphone_proxy_config_set_file_transfer_server - * @param #LinphoneCore to be modified - * @param const char* url of the file server like https://file.linphone.org/upload.php - **/ void linphone_core_set_file_transfer_server(LinphoneCore *core, const char * server_url) { core->file_transfer_server=ms_strdup(server_url); } diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 55fa9f6a1..298f178ea 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -133,9 +133,9 @@ typedef struct belle_sip_dict LinphoneDictionary; struct _LinphoneContent{ char *type; /**vTable diff --git a/coreapi/misc.c b/coreapi/misc.c index 2a86db03a..43b3a3139 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -711,11 +711,11 @@ void linphone_core_update_local_media_description_from_ice(SalMediaDescription * } strncpy(desc->ice_pwd, ice_session_local_pwd(session), sizeof(desc->ice_pwd)); strncpy(desc->ice_ufrag, ice_session_local_ufrag(session), sizeof(desc->ice_ufrag)); - for (i = 0; i < desc->n_active_streams; i++) { + for (i = 0; i < desc->nb_streams; i++) { SalStreamDescription *stream = &desc->streams[i]; IceCheckList *cl = ice_session_check_list(session, i); nb_candidates = 0; - if (cl == NULL) continue; + if (!sal_stream_description_active(stream) || (cl == NULL)) continue; if (ice_check_list_state(cl) == ICL_Completed) { stream->ice_completed = TRUE; result = ice_check_list_selected_valid_local_candidate(ice_session_check_list(session, i), &rtp_addr, &stream->rtp_port, &rtcp_addr, &stream->rtcp_port); @@ -822,7 +822,7 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, ice_session_restart(call->ice_session); ice_restarted = TRUE; } else { - for (i = 0; i < md->n_total_streams; i++) { + for (i = 0; i < md->nb_streams; i++) { const SalStreamDescription *stream = &md->streams[i]; IceCheckList *cl = ice_session_check_list(call->ice_session, i); if (cl && (strcmp(stream->rtp_addr, "0.0.0.0") == 0)) { @@ -841,7 +841,7 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, } ice_session_set_remote_credentials(call->ice_session, md->ice_ufrag, md->ice_pwd); } - for (i = 0; i < md->n_total_streams; i++) { + for (i = 0; i < md->nb_streams; i++) { const SalStreamDescription *stream = &md->streams[i]; IceCheckList *cl = ice_session_check_list(call->ice_session, i); if (cl && (stream->ice_pwd[0] != '\0') && (stream->ice_ufrag[0] != '\0')) { @@ -857,7 +857,7 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, } /* Create ICE check lists if needed and parse ICE attributes. */ - for (i = 0; i < md->n_total_streams; i++) { + for (i = 0; i < md->nb_streams; i++) { const SalStreamDescription *stream = &md->streams[i]; IceCheckList *cl = ice_session_check_list(call->ice_session, i); /* @@ -918,10 +918,12 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, } } } - for (i = ice_session_nb_check_lists(call->ice_session); i > md->n_active_streams; i--) { - IceCheckList *removed=ice_session_check_list(call->ice_session, i - 1); - ice_session_remove_check_list(call->ice_session, removed); - clear_ice_check_list(call,removed); + for (i = 0; i < md->nb_streams; i++) { + IceCheckList * cl = ice_session_check_list(call->ice_session, i); + if (!sal_stream_description_active(&md->streams[i]) && (cl != NULL)) { + ice_session_remove_check_list_from_idx(call->ice_session, i); + clear_ice_check_list(call, cl); + } } ice_session_check_mismatch(call->ice_session); } else { @@ -937,7 +939,7 @@ void linphone_core_update_ice_from_remote_media_description(LinphoneCall *call, bool_t linphone_core_media_description_contains_video_stream(const SalMediaDescription *md){ int i; - for (i = 0; i < md->n_total_streams; i++) { + for (i = 0; i < md->nb_streams; i++) { if (md->streams[i].type == SalVideo && md->streams[i].rtp_port!=0) return TRUE; } @@ -1520,33 +1522,3 @@ const MSCryptoSuite * linphone_core_get_srtp_crypto_suites(LinphoneCore *lc){ lc->rtp_conf.srtp_suites=result; return result; } - -bool_t is_video_active(const SalStreamDescription *sd) { - return (sd->rtp_port != 0) && (sd->dir != SalStreamInactive); -} - -bool_t stream_description_has_avpf(const SalStreamDescription *sd) { - return ((sd->proto == SalProtoRtpAvpf) || (sd->proto == SalProtoRtpSavpf)); -} - -bool_t stream_description_has_srtp(const SalStreamDescription *sd) { - return ((sd->proto == SalProtoRtpSavp) || (sd->proto == SalProtoRtpSavpf)); -} - -bool_t media_description_has_avpf(const SalMediaDescription *md) { - int i; - if (md->n_active_streams == 0) return FALSE; - for (i = 0; i < md->n_active_streams; i++) { - if (stream_description_has_avpf(&md->streams[i]) != TRUE) return FALSE; - } - return TRUE; -} - -bool_t media_description_has_srtp(const SalMediaDescription *md) { - int i; - if (md->n_active_streams == 0) return FALSE; - for (i = 0; i < md->n_active_streams; i++) { - if (stream_description_has_srtp(&md->streams[i]) != TRUE) return FALSE; - } - return TRUE; -} diff --git a/coreapi/offeranswer.c b/coreapi/offeranswer.c index aef918b92..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 */ @@ -237,7 +241,7 @@ static void initiate_outgoing(const SalStreamDescription *local_offer, }else{ result->rtp_port=0; } - if (stream_description_has_srtp(result) == TRUE) { + if (sal_stream_description_has_srtp(result) == TRUE) { /* verify crypto algo */ memset(result->crypto, 0, sizeof(result->crypto)); if (!match_crypto_algo(local_offer->crypto, remote_answer->crypto, &result->crypto[0], &result->crypto_local_tag, FALSE)) @@ -263,7 +267,7 @@ static void initiate_incoming(const SalStreamDescription *local_cap, }else{ result->rtp_port=0; } - if (stream_description_has_srtp(result) == TRUE) { + if (sal_stream_description_has_srtp(result) == TRUE) { /* select crypto algo */ memset(result->crypto, 0, sizeof(result->crypto)); if (!match_crypto_algo(local_cap->crypto, remote_offer->crypto, &result->crypto[0], &result->crypto_local_tag, TRUE)) @@ -289,7 +293,7 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer, int i,j; const SalStreamDescription *ls,*rs; - for(i=0,j=0;in_total_streams;++i){ + for(i=0,j=0;inb_streams;++i){ ms_message("Processing for stream %i",i); ls=&local_offer->streams[i]; rs=sal_media_description_find_stream((SalMediaDescription*)remote_answer,ls->proto,ls->type); @@ -303,8 +307,7 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer, } else ms_warning("No matching stream for %i",i); } - result->n_active_streams=j; - result->n_total_streams=local_offer->n_total_streams; + result->nb_streams=local_offer->nb_streams; result->bandwidth=remote_answer->bandwidth; strcpy(result->addr,remote_answer->addr); memcpy(&result->rtcp_xr, &local_offer->rtcp_xr, sizeof(result->rtcp_xr)); @@ -317,7 +320,7 @@ int offer_answer_initiate_outgoing(const SalMediaDescription *local_offer, static bool_t local_stream_not_already_used(const SalMediaDescription *result, const SalStreamDescription *stream){ int i; - for(i=0;in_total_streams;++i){ + for(i=0;inb_streams;++i){ const SalStreamDescription *ss=&result->streams[i]; if (strcmp(ss->name,stream->name)==0){ ms_message("video stream already used in answer"); @@ -337,8 +340,9 @@ static bool_t proto_compatible(SalMediaProto local, SalMediaProto remote) { static const SalStreamDescription *find_local_matching_stream(const SalMediaDescription *result, const SalMediaDescription *local_capabilities, const SalStreamDescription *remote_stream){ int i; - for(i=0;in_active_streams;++i){ + for(i=0;inb_streams;++i){ const SalStreamDescription *ss=&local_capabilities->streams[i]; + if (!sal_stream_description_active(ss)) continue; if (ss->type==remote_stream->type && proto_compatible(ss->proto,remote_stream->proto) && local_stream_not_already_used(result,ss)) return ss; } @@ -356,15 +360,13 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities int i; const SalStreamDescription *ls=NULL,*rs; - result->n_active_streams=0; - for(i=0;in_total_streams;++i){ + for(i=0;inb_streams;++i){ rs=&remote_offer->streams[i]; if (rs->proto!=SalProtoOther){ ls=find_local_matching_stream(result,local_capabilities,rs); }else ms_warning("Unknown protocol for mline %i, declining",i); if (ls){ initiate_incoming(ls,rs,&result->streams[i],one_matching_codec); - if (result->streams[i].rtp_port!=0) result->n_active_streams++; // Handle media RTCP XR attribute memset(&result->streams[i].rtcp_xr, 0, sizeof(result->streams[i].rtcp_xr)); @@ -393,7 +395,7 @@ int offer_answer_initiate_incoming(const SalMediaDescription *local_capabilities } } } - result->n_total_streams=i; + result->nb_streams=i; strcpy(result->username, local_capabilities->username); strcpy(result->addr,local_capabilities->addr); result->bandwidth=local_capabilities->bandwidth; diff --git a/coreapi/presence.c b/coreapi/presence.c index df9271844..183002b86 100644 --- a/coreapi/presence.c +++ b/coreapi/presence.c @@ -81,15 +81,17 @@ static const char *person_prefix = "/pidf:presence/dm:person"; /***************************************************************************** * PRIVATE FUNCTIONS * ****************************************************************************/ - -static char presence_id_valid_characters[] = "0123456789abcdefghijklmnopqrstuvwxyz"; +/*defined in http://www.w3.org/TR/REC-xml/*/ +static char presence_id_valid_characters[] = "0123456789abcdefghijklmnopqrstuvwxyz-."; +/*NameStartChar (NameChar)**/ +static char presence_id_valid_start_characters[] = ":_abcdefghijklmnopqrstuvwxyz"; static char * generate_presence_id(void) { char id[7]; int i; - - for (i = 0; i < 6; i++) { - id[i] = presence_id_valid_characters[random() % sizeof(presence_id_valid_characters)]; + id[0] = presence_id_valid_start_characters[random() % (sizeof(presence_id_valid_start_characters)-1)]; + for (i = 1; i < 6; i++) { + id[i] = presence_id_valid_characters[random() % (sizeof(presence_id_valid_characters)-1)]; } id[6] = '\0'; diff --git a/coreapi/private.h b/coreapi/private.h index e9f3b5c3b..4dabfe4eb 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -100,7 +100,13 @@ 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{ + reporting_session_report_t * reports[2]; /**Store information on audio and video media streams (RFC 6035) */ + bool_t was_video_running; /*Keep video state since last check in order to detect its (de)activation*/ + LinphoneQualityReportingReportSendCb on_report_sent; }; struct _LinphoneCallLog{ @@ -119,10 +125,12 @@ struct _LinphoneCallLog{ time_t start_date_time; /**Start date of the call in seconds as expressed in a time_t */ char* call_id; /**unique id of a call*/ - reporting_session_report_t * reports[2]; /**=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; @@ -329,7 +338,7 @@ void linphone_subscription_closed(LinphoneCore *lc, SalOp *op); void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc); void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCall *call, const PayloadType *pt, int maxbw); -int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call); +LINPHONE_PUBLIC int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call); void linphone_core_resolve_stun_server(LinphoneCore *lc); const struct addrinfo *linphone_core_get_stun_server_addrinfo(LinphoneCore *lc); void linphone_core_adapt_to_network(LinphoneCore *lc, int ping_time_ms, LinphoneCallParams *params); @@ -351,7 +360,7 @@ LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const L const char *linphone_core_find_best_identity(LinphoneCore *lc, const LinphoneAddress *to); int linphone_core_get_local_ip_for(int type, const char *dest, char *result); -LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(struct _LpConfig *config, int index); +LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LinphoneCore *lc, int index); void linphone_proxy_config_write_to_config_file(struct _LpConfig* config,LinphoneProxyConfig *obj, int index); int linphone_proxy_config_normalize_number(LinphoneProxyConfig *cfg, const char *username, char *result, size_t result_len); @@ -393,17 +402,12 @@ bool_t linphone_core_rtcp_enabled(const LinphoneCore *lc); LinphoneCall * is_a_linphone_call(void *user_pointer); LinphoneProxyConfig * is_a_linphone_proxy_config(void *user_pointer); -bool_t is_video_active(const SalStreamDescription *sd); -bool_t stream_description_has_avpf(const SalStreamDescription *sd); -bool_t stream_description_has_srtp(const SalStreamDescription *sd); -bool_t media_description_has_avpf(const SalMediaDescription *md); -bool_t media_description_has_srtp(const SalMediaDescription *md); void linphone_core_queue_task(LinphoneCore *lc, belle_sip_source_func_t task_fun, void *data, const char *task_description); static const int linphone_proxy_config_magic=0x7979; -bool_t linphone_proxy_config_address_equal(const LinphoneAddress *a, const LinphoneAddress *b); -bool_t linphone_proxy_config_is_server_config_changed(const LinphoneProxyConfig* obj); +LINPHONE_PUBLIC bool_t linphone_proxy_config_address_equal(const LinphoneAddress *a, const LinphoneAddress *b); +LINPHONE_PUBLIC bool_t linphone_proxy_config_is_server_config_changed(const LinphoneProxyConfig* obj); void _linphone_proxy_config_unregister(LinphoneProxyConfig *obj); /*chat*/ @@ -859,7 +863,6 @@ LinphoneSubscriptionState linphone_subscription_state_from_sal(SalSubscribeStatu const LinphoneContent *linphone_content_from_sal_body(LinphoneContent *obj, const SalBody *ref); void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc); - /***************************************************************************** * REMOTE PROVISIONING FUNCTIONS * ****************************************************************************/ @@ -901,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); } diff --git a/coreapi/proxy.c b/coreapi/proxy.c index 6b23eebdd..ad7234a7b 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -307,6 +307,19 @@ void linphone_proxy_config_set_expires(LinphoneProxyConfig *obj, int val){ void linphone_proxy_config_enable_publish(LinphoneProxyConfig *obj, bool_t val){ obj->publish=val; } + +/** + * Prevent a proxy config from refreshing its registration. + * This is useful to let registrations to expire naturally (or) when the application wants to keep control on when + * refreshes are sent. + * However, linphone_core_set_network_reachable(lc,TRUE) will always request the proxy configs to refresh their registrations. + * The refreshing operations can be resumed with linphone_proxy_config_refresh_register(). + * @param obj the proxy config +**/ +void linphone_proxy_config_pause_register(LinphoneProxyConfig *obj){ + if (obj->op) sal_op_stop_refreshing(obj->op); +} + /** * Starts editing a proxy configuration. * @@ -327,7 +340,7 @@ void linphone_proxy_config_edit(LinphoneProxyConfig *obj){ linphone_proxy_config_store_server_config(obj); /*stop refresher in any case*/ - if (obj->op) sal_op_stop_refreshing(obj->op); + linphone_proxy_config_pause_register(obj); } void linphone_proxy_config_apply(LinphoneProxyConfig *obj,LinphoneCore *lc){ @@ -502,13 +515,15 @@ void linphone_proxy_config_set_quality_reporting_collector(LinphoneProxyConfig * if (collector!=NULL && strlen(collector)>0){ LinphoneAddress *addr=linphone_address_new(collector); if (!addr || linphone_address_get_username(addr)==NULL){ - ms_warning("Invalid sip collector identity: %s",collector); - if (addr) - linphone_address_destroy(addr); + ms_error("Invalid SIP collector URI: %s. Quality reporting will be DISABLED.",collector); } else { - if (cfg->quality_reporting_collector != NULL) + if (cfg->quality_reporting_collector != NULL){ ms_free(cfg->quality_reporting_collector); + } cfg->quality_reporting_collector = ms_strdup(collector); + } + + if (addr){ linphone_address_destroy(addr); } } @@ -1088,7 +1103,7 @@ int linphone_core_add_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *cfg){ void linphone_core_remove_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *cfg){ /* check this proxy config is in the list before doing more*/ if (ms_list_find(lc->sip_conf.proxies,cfg)==NULL){ - ms_error("linphone_core_remove_proxy_config: LinphoneProxyConfig %p is not known by LinphoneCore (programming error?)",cfg); + ms_error("linphone_core_remove_proxy_config: LinphoneProxyConfig [%p] is not known by LinphoneCore (programming error?)",cfg); return; } lc->sip_conf.proxies=ms_list_remove(lc->sip_conf.proxies,cfg); @@ -1100,6 +1115,7 @@ void linphone_core_remove_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *cf linphone_proxy_config_edit(cfg); linphone_proxy_config_enable_register(cfg,FALSE); linphone_proxy_config_done(cfg); + linphone_proxy_config_update(cfg); /*so that it has an effect*/ } if (lc->default_proxy==cfg){ lc->default_proxy=NULL; @@ -1209,7 +1225,7 @@ void linphone_proxy_config_write_to_config_file(LpConfig *config, LinphoneProxyC -LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LpConfig *config, int index) +LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LinphoneCore* lc, int index) { const char *tmp; const char *identity; @@ -1217,6 +1233,7 @@ LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LpConfig *config LinphoneProxyConfig *cfg; char key[50]; int interval; + LpConfig *config=lc->config; sprintf(key,"proxy_%i",index); @@ -1224,7 +1241,7 @@ LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LpConfig *config return NULL; } - cfg=linphone_proxy_config_new(); + cfg=linphone_core_create_proxy_config(lc); identity=lp_config_get_string(config,key,"reg_identity",NULL); proxy=lp_config_get_string(config,key,"reg_proxy",NULL); diff --git a/coreapi/quality_reporting.c b/coreapi/quality_reporting.c index 2fd4229c3..63944e55d 100644 --- a/coreapi/quality_reporting.c +++ b/coreapi/quality_reporting.c @@ -28,30 +28,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include -/*************************************************************************** - * TODO / REMINDER LIST - *************************************************************************** - For codecs that are able to change sample rates, the lowest and highest sample rates MUST be reported (e.g., 8000;16000). - - rlq value: need algo to compute it - - 3.4 overload avoidance? - a. Send only one report at the end of each call. (audio | video?) - b. Use interval reports only on "problem" calls that are being closely monitored. - - move "on_action_suggested" stuff in init - - - The Session report when - codec change - session fork - video enable/disable <-- what happens if doing stop/resume? - - - if BYE and continue received packet drop them - *************************************************************************** - * END OF TODO / REMINDER LIST - ****************************************************************************/ - #define STR_REASSIGN(dest, src) {\ if (dest != NULL) \ ms_free(dest); \ @@ -85,7 +61,7 @@ static void append_to_buffer_valist(char **buff, size_t *buff_size, size_t *offs /*if we are out of memory, we add some size to buffer*/ if (ret == BELLE_SIP_BUFFER_OVERFLOW) { /*some compilers complain that size_t cannot be formatted as unsigned long, hence forcing cast*/ - ms_warning("Buffer was too small to contain the whole report - increasing its size from %lu to %lu", + ms_warning("QualityReporting: Buffer was too small to contain the whole report - increasing its size from %lu to %lu", (unsigned long)*buff_size, (unsigned long)*buff_size + 2048); *buff_size += 2048; *buff = (char *) ms_realloc(*buff, *buff_size); @@ -109,13 +85,15 @@ static void reset_avg_metrics(reporting_session_report_t * report){ reporting_content_metrics_t * metrics[2] = {&report->local_metrics, &report->remote_metrics}; for (i = 0; i < 2; i++) { + metrics[i]->rtcp_sr_count = 0; metrics[i]->rtcp_xr_count = 0; metrics[i]->jitter_buffer.nominal = 0; metrics[i]->jitter_buffer.max = 0; - metrics[i]->delay.round_trip_delay = 0; + metrics[i]->quality_estimates.moslq = 0; + metrics[i]->quality_estimates.moscq = 0; - /*metrics[i]->delay.symm_one_way_delay = 0;*/ + metrics[i]->delay.round_trip_delay = 0; } report->last_report_date = ms_time(NULL); } @@ -139,38 +117,30 @@ static uint8_t are_metrics_filled(const reporting_content_metrics_t rm) { IF_NUM_IN_RANGE(rm.packet_loss.network_packet_loss_rate, 0, 255, ret|=METRICS_PACKET_LOSS); IF_NUM_IN_RANGE(rm.packet_loss.jitter_buffer_discard_rate, 0, 255, ret|=METRICS_PACKET_LOSS); - /*since these are same values than local ones, do not check them*/ - /*if (rm.session_description.payload_type != -1) ret|=METRICS_SESSION_DESCRIPTION;*/ - /*if (rm.session_description.payload_desc != NULL) ret|=METRICS_SESSION_DESCRIPTION;*/ - /*if (rm.session_description.sample_rate != -1) ret|=METRICS_SESSION_DESCRIPTION;*/ - /*if (rm.session_description.fmtp != NULL) ret|=METRICS_SESSION_DESCRIPTION;*/ - if (rm.session_description.frame_duration != -1) ret|=METRICS_SESSION_DESCRIPTION; - if (rm.session_description.packet_loss_concealment != -1) ret|=METRICS_SESSION_DESCRIPTION; + if (rm.session_description.payload_type != -1) ret|=METRICS_SESSION_DESCRIPTION; + if (rm.session_description.payload_desc != NULL) ret|=METRICS_SESSION_DESCRIPTION; + if (rm.session_description.sample_rate != -1) ret|=METRICS_SESSION_DESCRIPTION; + if (rm.session_description.fmtp != NULL) ret|=METRICS_SESSION_DESCRIPTION; IF_NUM_IN_RANGE(rm.jitter_buffer.adaptive, 0, 3, ret|=METRICS_JITTER_BUFFER); IF_NUM_IN_RANGE(rm.jitter_buffer.abs_max, 0, 65535, ret|=METRICS_JITTER_BUFFER); IF_NUM_IN_RANGE(rm.delay.end_system_delay, 0, 65535, ret|=METRICS_DELAY); - /*IF_NUM_IN_RANGE(rm.delay.symm_one_way_delay, 0, 65535, ret|=METRICS_DELAY);*/ IF_NUM_IN_RANGE(rm.delay.interarrival_jitter, 0, 65535, ret|=METRICS_DELAY); IF_NUM_IN_RANGE(rm.delay.mean_abs_jitter, 0, 65535, ret|=METRICS_DELAY); if (rm.signal.level != 127) ret|=METRICS_SIGNAL; if (rm.signal.noise_level != 127) ret|=METRICS_SIGNAL; - if (rm.qos_analyzer.input_leg!=NULL) ret|=METRICS_ADAPTIVE_ALGORITHM; - if (rm.qos_analyzer.input!=NULL) ret|=METRICS_ADAPTIVE_ALGORITHM; - if (rm.qos_analyzer.output_leg!=NULL) ret|=METRICS_ADAPTIVE_ALGORITHM; - if (rm.qos_analyzer.output!=NULL) ret|=METRICS_ADAPTIVE_ALGORITHM; + IF_NUM_IN_RANGE(rm.quality_estimates.moslq, 1, 5, ret|=METRICS_QUALITY_ESTIMATES); + IF_NUM_IN_RANGE(rm.quality_estimates.moscq, 1, 5, ret|=METRICS_QUALITY_ESTIMATES); if (rm.rtcp_xr_count>0){ IF_NUM_IN_RANGE(rm.jitter_buffer.nominal/rm.rtcp_xr_count, 0, 65535, ret|=METRICS_JITTER_BUFFER); IF_NUM_IN_RANGE(rm.jitter_buffer.max/rm.rtcp_xr_count, 0, 65535, ret|=METRICS_JITTER_BUFFER); - IF_NUM_IN_RANGE(rm.delay.round_trip_delay, 0, 65535, ret|=METRICS_DELAY); - IF_NUM_IN_RANGE(rm.quality_estimates.moslq/rm.rtcp_xr_count, 1, 5, ret|=METRICS_QUALITY_ESTIMATES); - IF_NUM_IN_RANGE(rm.quality_estimates.moscq/rm.rtcp_xr_count, 1, 5, ret|=METRICS_QUALITY_ESTIMATES); - IF_NUM_IN_RANGE(rm.quality_estimates.rlq/rm.rtcp_xr_count, 1, 120, ret|=METRICS_QUALITY_ESTIMATES); - IF_NUM_IN_RANGE(rm.quality_estimates.rcq/rm.rtcp_xr_count, 1, 120, ret|=METRICS_QUALITY_ESTIMATES); + } + if (rm.rtcp_sr_count+rm.rtcp_xr_count>0){ + IF_NUM_IN_RANGE(rm.delay.round_trip_delay/(rm.rtcp_sr_count+rm.rtcp_xr_count), 0, 65535, ret|=METRICS_DELAY); } return ret; @@ -187,7 +157,7 @@ static bool_t media_report_enabled(LinphoneCall * call, int stats_type){ if (stats_type == LINPHONE_CALL_STATS_VIDEO && !linphone_call_params_video_enabled(linphone_call_get_current_params(call))) return FALSE; - return (call->log->reports[stats_type] != NULL); + return (call->log->reporting.reports[stats_type] != NULL); } static void append_metrics_to_buffer(char ** buffer, size_t * size, size_t * offset, const reporting_content_metrics_t rm) { @@ -215,18 +185,13 @@ static void append_metrics_to_buffer(char ** buffer, size_t * size, size_t * off APPEND_IF_NOT_NULL_STR(buffer, size, offset, " PD=%s", rm.session_description.payload_desc); APPEND_IF(buffer, size, offset, " SR=%d", rm.session_description.sample_rate, rm.session_description.sample_rate != -1); APPEND_IF(buffer, size, offset, " FD=%d", rm.session_description.frame_duration, rm.session_description.frame_duration != -1); - /*append_to_buffer(buffer, size, offset, " FO=%d", rm.session_description.frame_ocets);*/ - /*append_to_buffer(buffer, size, offset, " FPP=%d", rm.session_description.frames_per_sec);*/ - /*append_to_buffer(buffer, size, offset, " PPS=%d", rm.session_description.packets_per_sec);*/ APPEND_IF_NOT_NULL_STR(buffer, size, offset, " FMTP=\"%s\"", rm.session_description.fmtp); APPEND_IF(buffer, size, offset, " PLC=%d", rm.session_description.packet_loss_concealment, rm.session_description.packet_loss_concealment != -1); - /*APPEND_IF_NOT_NULL_STR(buffer, size, offset, " SSUP=%s", rm.session_description.silence_suppression_state);*/ } if ((available_metrics & METRICS_JITTER_BUFFER) != 0){ append_to_buffer(buffer, size, offset, "\r\nJitterBuffer:"); APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " JBA=%d", rm.jitter_buffer.adaptive, 0, 3); - /*APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " JBR=%d", rm.jitter_buffer.rate, 0, 15);*/ if (rm.rtcp_xr_count){ APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " JBN=%d", rm.jitter_buffer.nominal/rm.rtcp_xr_count, 0, 65535); APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " JBM=%d", rm.jitter_buffer.max/rm.rtcp_xr_count, 0, 65535); @@ -251,12 +216,10 @@ static void append_metrics_to_buffer(char ** buffer, size_t * size, size_t * off if ((available_metrics & METRICS_DELAY) != 0){ append_to_buffer(buffer, size, offset, "\r\nDelay:"); - if (rm.rtcp_xr_count){ - APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " RTD=%d", rm.delay.round_trip_delay/rm.rtcp_xr_count, 0, 65535); + if (rm.rtcp_xr_count+rm.rtcp_sr_count){ + APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " RTD=%d", rm.delay.round_trip_delay/(rm.rtcp_xr_count+rm.rtcp_sr_count), 0, 65535); } APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " ESD=%d", rm.delay.end_system_delay, 0, 65535); - /*APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " OWD=%d", rm.delay.one_way_delay, 0, 65535);*/ - /*APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " SOWD=%d", rm.delay.symm_one_way_delay, 0, 65535);*/ APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " IAJ=%d", rm.delay.interarrival_jitter, 0, 65535); APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " MAJ=%d", rm.delay.mean_abs_jitter, 0, 65535); } @@ -265,36 +228,21 @@ static void append_metrics_to_buffer(char ** buffer, size_t * size, size_t * off append_to_buffer(buffer, size, offset, "\r\nSignal:"); APPEND_IF(buffer, size, offset, " SL=%d", rm.signal.level, rm.signal.level != 127); APPEND_IF(buffer, size, offset, " NL=%d", rm.signal.noise_level, rm.signal.noise_level != 127); - /*append_to_buffer(buffer, size, offset, " RERL=%d", rm.signal.residual_echo_return_loss);*/ } /*if quality estimates metrics are available, rtcp_xr_count should be always not null*/ if ((available_metrics & METRICS_QUALITY_ESTIMATES) != 0){ - IF_NUM_IN_RANGE(rm.quality_estimates.moslq/rm.rtcp_xr_count, 1, 5, moslq_str = float_to_one_decimal_string(rm.quality_estimates.moslq/rm.rtcp_xr_count)); - IF_NUM_IN_RANGE(rm.quality_estimates.moscq/rm.rtcp_xr_count, 1, 5, moscq_str = float_to_one_decimal_string(rm.quality_estimates.moscq/rm.rtcp_xr_count)); + IF_NUM_IN_RANGE(rm.quality_estimates.moslq, 1, 5, moslq_str = float_to_one_decimal_string(rm.quality_estimates.moslq)); + IF_NUM_IN_RANGE(rm.quality_estimates.moscq, 1, 5, moscq_str = float_to_one_decimal_string(rm.quality_estimates.moscq)); append_to_buffer(buffer, size, offset, "\r\nQualityEst:"); - APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " RLQ=%d", rm.quality_estimates.rlq/rm.rtcp_xr_count, 1, 120); - /*APPEND_IF_NOT_NULL_STR(buffer, size, offset, " RLQEstAlg=%s", rm.quality_estimates.rlqestalg);*/ - APPEND_IF_NUM_IN_RANGE(buffer, size, offset, " RCQ=%d", rm.quality_estimates.rcq/rm.rtcp_xr_count, 1, 120); - /*APPEND_IF_NOT_NULL_STR(buffer, size, offset, " RCQEstAlgo=%s", rm.quality_estimates.rcqestalg);*/ - /*append_to_buffer(buffer, size, offset, " EXTRI=%d", rm.quality_estimates.extri);*/ - /*APPEND_IF_NOT_NULL_STR(buffer, size, offset, " ExtRIEstAlg=%s", rm.quality_estimates.extriestalg);*/ - /*append_to_buffer(buffer, size, offset, " EXTRO=%d", rm.quality_estimates.extro);*/ - /*APPEND_IF_NOT_NULL_STR(buffer, size, offset, " ExtROEstAlg=%s", rm.quality_estimates.extroutestalg);*/ APPEND_IF_NOT_NULL_STR(buffer, size, offset, " MOSLQ=%s", moslq_str); - /*APPEND_IF_NOT_NULL_STR(buffer, size, offset, " MOSLQEstAlgo=%s", rm.quality_estimates.moslqestalg);*/ APPEND_IF_NOT_NULL_STR(buffer, size, offset, " MOSCQ=%s", moscq_str); - /*APPEND_IF_NOT_NULL_STR(buffer, size, offset, " MOSCQEstAlgo=%s", rm.quality_estimates.moscqestalg);*/ - /*APPEND_IF_NOT_NULL_STR(buffer, size, offset, " QoEEstAlg=%s", rm.quality_estimates.qoestalg);*/ } - if ((available_metrics & METRICS_ADAPTIVE_ALGORITHM) != 0){ - append_to_buffer(buffer, size, offset, "\r\nAdaptiveAlg:"); - APPEND_IF_NOT_NULL_STR(buffer, size, offset, " IN_LEG=%s", rm.qos_analyzer.input_leg); - APPEND_IF_NOT_NULL_STR(buffer, size, offset, " IN=%s", rm.qos_analyzer.input); - APPEND_IF_NOT_NULL_STR(buffer, size, offset, " OUT_LEG=%s", rm.qos_analyzer.output_leg); - APPEND_IF_NOT_NULL_STR(buffer, size, offset, " OUT=%s", rm.qos_analyzer.output); + 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"); @@ -308,28 +256,42 @@ static void append_metrics_to_buffer(char ** buffer, size_t * size, size_t * off ms_free(moscq_str); } -static void send_report(const LinphoneCall* call, reporting_session_report_t * report, const char * report_event) { +static int send_report(LinphoneCall* call, reporting_session_report_t * report, const char * report_event) { LinphoneContent content = {0}; LinphoneAddress *addr; int expires = -1; size_t offset = 0; size_t size = 2048; char * buffer; + int ret = 0; + + /*if we are on a low bandwidth network, do not send reports to not overload it*/ + if (linphone_call_params_low_bandwidth_enabled(linphone_call_get_current_params(call))){ + ms_warning("QualityReporting[%p]: Avoid sending reports on low bandwidth network", call); + ret = 1; + goto end; + } /*if the call was hung up too early, we might have invalid IPs information in that case, we abort the report since it's not useful data*/ if (report->info.local_addr.ip == NULL || strlen(report->info.local_addr.ip) == 0 || report->info.remote_addr.ip == NULL || strlen(report->info.remote_addr.ip) == 0) { - ms_warning("The call was hang up too early (duration: %d sec) and IP could " + ms_warning("QualityReporting[%p]: Trying to submit a %s too early (call duration: %d sec) but %s IP could " "not be retrieved so dropping this report" - , linphone_call_get_duration(call)); - return; + , call + , report_event + , linphone_call_get_duration(call) + , (report->info.local_addr.ip == NULL || strlen(report->info.local_addr.ip) == 0) ? "local" : "remote"); + ret = 2; + goto end; } addr = linphone_address_new(linphone_proxy_config_get_quality_reporting_collector(call->dest_proxy)); if (addr == NULL) { - ms_warning("Asked to submit reporting statistics but no collector address found"); - return; + ms_warning("QualityReporting[%p]: Asked to submit reporting statistics but no collector address found" + , call); + ret = 3; + goto end; } buffer = (char *) ms_malloc(size); @@ -338,16 +300,16 @@ static void send_report(const LinphoneCall* call, reporting_session_report_t * r append_to_buffer(&buffer, &size, &offset, "%s\r\n", report_event); append_to_buffer(&buffer, &size, &offset, "CallID: %s\r\n", report->info.call_id); - append_to_buffer(&buffer, &size, &offset, "LocalID: %s\r\n", report->info.local_id); - append_to_buffer(&buffer, &size, &offset, "RemoteID: %s\r\n", report->info.remote_id); + append_to_buffer(&buffer, &size, &offset, "LocalID: %s\r\n", report->info.local_addr.id); + append_to_buffer(&buffer, &size, &offset, "RemoteID: %s\r\n", report->info.remote_addr.id); append_to_buffer(&buffer, &size, &offset, "OrigID: %s\r\n", report->info.orig_id); - APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "LocalGroup: %s\r\n", report->info.local_group); - APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "RemoteGroup: %s\r\n", report->info.remote_group); - append_to_buffer(&buffer, &size, &offset, "LocalAddr: IP=%s PORT=%d SSRC=%d\r\n", report->info.local_addr.ip, report->info.local_addr.port, report->info.local_addr.ssrc); - APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "LocalMAC: %s\r\n", report->info.local_mac_addr); - append_to_buffer(&buffer, &size, &offset, "RemoteAddr: IP=%s PORT=%d SSRC=%d\r\n", report->info.remote_addr.ip, report->info.remote_addr.port, report->info.remote_addr.ssrc); - APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "RemoteMAC: %s\r\n", report->info.remote_mac_addr); + APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "LocalGroup: %s\r\n", report->info.local_addr.group); + APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "RemoteGroup: %s\r\n", report->info.remote_addr.group); + append_to_buffer(&buffer, &size, &offset, "LocalAddr: IP=%s PORT=%d SSRC=%u\r\n", report->info.local_addr.ip, report->info.local_addr.port, report->info.local_addr.ssrc); + APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "LocalMAC: %s\r\n", report->info.local_addr.mac); + append_to_buffer(&buffer, &size, &offset, "RemoteAddr: IP=%s PORT=%d SSRC=%u\r\n", report->info.remote_addr.ip, report->info.remote_addr.port, report->info.remote_addr.ssrc); + APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "RemoteMAC: %s\r\n", report->info.remote_addr.mac); append_to_buffer(&buffer, &size, &offset, "LocalMetrics:\r\n"); append_metrics_to_buffer(&buffer, &size, &offset, report->local_metrics); @@ -358,68 +320,137 @@ static void send_report(const LinphoneCall* call, reporting_session_report_t * r } APPEND_IF_NOT_NULL_STR(&buffer, &size, &offset, "DialogID: %s\r\n", report->dialog_id); + 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_to_buffer(&buffer, &size, &offset, "\r\n"); + } + content.data = buffer; content.size = strlen(buffer); - /*(WIP) Memory leak: PUBLISH message is never freed (issue 1283)*/ - linphone_core_publish(call->core, addr, "vq-rtcpxr", expires, &content); + if (call->log->reporting.on_report_sent != NULL){ + call->log->reporting.on_report_sent( + call, + (report==call->log->reporting.reports[0])?LINPHONE_CALL_STATS_AUDIO:LINPHONE_CALL_STATS_VIDEO, + &content); + } + + if (! linphone_core_publish(call->core, addr, "vq-rtcpxr", expires, &content)){ + ret=4; + } else { + reset_avg_metrics(report); + 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); + } + linphone_address_destroy(addr); - reset_avg_metrics(report); linphone_content_uninit(&content); + + end: + ms_message("QualityReporting[%p]: Send '%s' with status %d", + call, + report_event, + ret + ); + + return ret; } static const SalStreamDescription * get_media_stream_for_desc(const SalMediaDescription * smd, SalStreamType sal_stream_type) { int count; if (smd != NULL) { - for (count = 0; count < smd->n_total_streams; ++count) { + for (count = 0; count < smd->nb_streams; ++count) { if (smd->streams[count].type == sal_stream_type) { return &smd->streams[count]; } } } - - ms_warning("Could not find the associated stream of type %d", sal_stream_type); return NULL; } static void update_ip(LinphoneCall * call, int stats_type) { SalStreamType sal_stream_type = (stats_type == LINPHONE_CALL_STATS_AUDIO) ? SalAudio : SalVideo; - if (media_report_enabled(call,stats_type)) { - const SalStreamDescription * local_desc = get_media_stream_for_desc(call->localdesc, sal_stream_type); - const SalStreamDescription * remote_desc = get_media_stream_for_desc(sal_call_get_remote_media_description(call->op), sal_stream_type); + const SalStreamDescription * local_desc = get_media_stream_for_desc(call->localdesc, sal_stream_type); + const SalStreamDescription * remote_desc = get_media_stream_for_desc(sal_call_get_remote_media_description(call->op), sal_stream_type); - /*local info are always up-to-date and correct*/ - if (local_desc != NULL) { - call->log->reports[stats_type]->info.local_addr.port = local_desc->rtp_port; - STR_REASSIGN(call->log->reports[stats_type]->info.local_addr.ip, ms_strdup(local_desc->rtp_addr)); + if (local_desc != NULL) { + /*since this function might be called for video stream AFTER it has been uninitialized, local description might + be invalid. In any other case, IP/port should be always filled and valid*/ + if (local_desc->rtp_addr != NULL && strlen(local_desc->rtp_addr) > 0) { + call->log->reporting.reports[stats_type]->info.local_addr.port = local_desc->rtp_port; + STR_REASSIGN(call->log->reporting.reports[stats_type]->info.local_addr.ip, ms_strdup(local_desc->rtp_addr)); } + } - if (remote_desc != NULL) { - /*port is always stored in stream description struct*/ - call->log->reports[stats_type]->info.remote_addr.port = remote_desc->rtp_port; + if (remote_desc != NULL) { + /*port is always stored in stream description struct*/ + call->log->reporting.reports[stats_type]->info.remote_addr.port = remote_desc->rtp_port; - /*for IP it can be not set if we are using a direct route*/ - if (remote_desc->rtp_addr != NULL && strlen(remote_desc->rtp_addr) > 0) { - STR_REASSIGN(call->log->reports[stats_type]->info.remote_addr.ip, ms_strdup(remote_desc->rtp_addr)); - } else { - STR_REASSIGN(call->log->reports[stats_type]->info.remote_addr.ip, ms_strdup(sal_call_get_remote_media_description(call->op)->addr)); - } + /*for IP it can be not set if we are using a direct route*/ + if (remote_desc->rtp_addr != NULL && strlen(remote_desc->rtp_addr) > 0) { + STR_REASSIGN(call->log->reporting.reports[stats_type]->info.remote_addr.ip, ms_strdup(remote_desc->rtp_addr)); + } else { + STR_REASSIGN(call->log->reporting.reports[stats_type]->info.remote_addr.ip, ms_strdup(sal_call_get_remote_media_description(call->op)->addr)); } } } -static void qos_analyzer_on_action_suggested(void *user_data, int datac, const char** data){ - reporting_content_metrics_t *metrics = (reporting_content_metrics_t*) user_data; +typedef struct on_action_suggested_struct{ + LinphoneCall *call; + int stats_type; +}on_action_suggested_struct_t; + +static void qos_analyzer_on_action_suggested(void *user_data, int datac, const char** datav){ + on_action_suggested_struct_t * oass = (on_action_suggested_struct_t *)user_data; + LinphoneCall *call = oass->call; + reporting_session_report_t *report = call->log->reporting.reports[oass->stats_type]; char * appendbuf; + int i; + int ptime = -1; + int bitrate[2] = {-1, -1}; + int up_bw[2] = {-1, -1}; + int down_bw[2] = {-1, -1}; + MediaStream *streams[2] = {(MediaStream*) call->audiostream, (MediaStream *) call->videostream}; + for (i=0;i<2;i++){ + if (streams[i]!=NULL){ + if (streams[i]->encoder!=NULL){ + if (ms_filter_has_method(streams[i]->encoder,MS_FILTER_GET_BITRATE)){ + ms_filter_call_method(streams[i]->encoder,MS_FILTER_GET_BITRATE,&bitrate[i]); + bitrate[i] /= 1000.f; + } + } + up_bw[i] = media_stream_get_up_bw(streams[i])/1000.f; + down_bw[i] = media_stream_get_down_bw(streams[i])/1000.f; + } + } + if (call->audiostream!=NULL){ + if (call->audiostream->ms.encoder!=NULL){ + if(ms_filter_has_method(call->audiostream->ms.encoder,MS_AUDIO_ENCODER_GET_PTIME)){ + ms_filter_call_method(call->audiostream->ms.encoder,MS_AUDIO_ENCODER_GET_PTIME,&ptime); + } + } + } - STR_REASSIGN(metrics->qos_analyzer.input_leg, ms_strdup(data[0])); - appendbuf=ms_strdup_printf("%s%s;", metrics->qos_analyzer.input?metrics->qos_analyzer.input:"", data[1]); - STR_REASSIGN(metrics->qos_analyzer.input,appendbuf); + appendbuf=ms_strdup_printf("%s%d;", report->qos_analyzer.timestamp?report->qos_analyzer.timestamp:"", ms_time(0)); + STR_REASSIGN(report->qos_analyzer.timestamp,appendbuf); - STR_REASSIGN(metrics->qos_analyzer.output_leg, ms_strdup(data[2])); - appendbuf=ms_strdup_printf("%s%s;", metrics->qos_analyzer.output?metrics->qos_analyzer.output:"", data[3]); - STR_REASSIGN(metrics->qos_analyzer.output, appendbuf); + STR_REASSIGN(report->qos_analyzer.input_leg, ms_strdup_printf("%s aenc_ptime aenc_br a_dbw a_ubw venc_br v_dbw v_ubw", datav[0])); + appendbuf=ms_strdup_printf("%s%s %d %d %d %d %d %d %d;", report->qos_analyzer.input?report->qos_analyzer.input:"", datav[1], + ptime, bitrate[0], down_bw[0], up_bw[0], bitrate[1], down_bw[1], up_bw[1] ); + STR_REASSIGN(report->qos_analyzer.input,appendbuf); + STR_REASSIGN(report->qos_analyzer.output_leg, ms_strdup(datav[2])); + appendbuf=ms_strdup_printf("%s%s;", report->qos_analyzer.output?report->qos_analyzer.output:"", datav[3]); + STR_REASSIGN(report->qos_analyzer.output, appendbuf); } void linphone_reporting_update_ip(LinphoneCall * call) { @@ -432,28 +463,45 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { const PayloadType * local_payload = NULL; const PayloadType * remote_payload = NULL; const LinphoneCallParams * current_params = linphone_call_get_current_params(call); - reporting_session_report_t * report = call->log->reports[stats_type]; + 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_group, ms_strdup_printf("linphone-%s-%s-%s", (stats_type == LINPHONE_CALL_STATS_AUDIO ? "audio" : "video"), - linphone_core_get_user_agent_name(), report->info.call_id)); - STR_REASSIGN(report->info.remote_group, ms_strdup_printf("linphone-%s-%s-%s", (stats_type == LINPHONE_CALL_STATS_AUDIO ? "audio" : "video"), - linphone_call_get_remote_user_agent(call), report->info.call_id)); + + 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("%s-%s-%s" + , dialog_id + , "remote" + , report->remote_metrics.user_agent + ) + ); + if (call->dir == LinphoneCallIncoming) { - STR_REASSIGN(report->info.remote_id, linphone_address_as_string(call->log->from)); - STR_REASSIGN(report->info.local_id, linphone_address_as_string(call->log->to)); - STR_REASSIGN(report->info.orig_id, ms_strdup(report->info.remote_id)); + 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)); + STR_REASSIGN(report->info.orig_id, ms_strdup(report->info.remote_addr.id)); } else { - STR_REASSIGN(report->info.remote_id, linphone_address_as_string(call->log->to)); - STR_REASSIGN(report->info.local_id, linphone_address_as_string(call->log->from)); - STR_REASSIGN(report->info.orig_id, ms_strdup(report->info.local_id)); + STR_REASSIGN(report->info.remote_addr.id, linphone_address_as_string(call->log->to)); + STR_REASSIGN(report->info.local_addr.id, linphone_address_as_string(call->log->from)); + 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); @@ -462,6 +510,7 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { report->remote_metrics.timestamps.start = call->log->start_date_time; report->remote_metrics.timestamps.stop = call->log->start_date_time + linphone_call_get_duration(call); + /*yet we use the same payload config for local and remote, since this is the largest use case*/ if (stats_type == LINPHONE_CALL_STATS_AUDIO && call->audiostream != NULL) { stream = &call->audiostream->ms; @@ -478,13 +527,22 @@ void linphone_reporting_update_media_info(LinphoneCall * call, int stats_type) { report->info.local_addr.ssrc = rtp_session_get_send_ssrc(session); report->info.remote_addr.ssrc = rtp_session_get_recv_ssrc(session); + + if (stream->qi != NULL){ + report->local_metrics.quality_estimates.moslq = ms_quality_indicator_get_average_lq_rating(stream->qi) >= 0 ? + MAX(1, ms_quality_indicator_get_average_lq_rating(stream->qi)) : -1; + report->local_metrics.quality_estimates.moscq = ms_quality_indicator_get_average_rating(stream->qi) >= 0 ? + MAX(1, ms_quality_indicator_get_average_rating(stream->qi)) : -1; + } } + 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; - STR_REASSIGN(report->local_metrics.session_description.payload_desc, ms_strdup(local_payload->mime_type)); + if (local_payload->mime_type!=NULL) STR_REASSIGN(report->local_metrics.session_description.payload_desc, ms_strdup(local_payload->mime_type)); report->local_metrics.session_description.sample_rate = local_payload->clock_rate; - STR_REASSIGN(report->local_metrics.session_description.fmtp, ms_strdup(local_payload->recv_fmtp)); + if (local_payload->recv_fmtp!=NULL) STR_REASSIGN(report->local_metrics.session_description.fmtp, ms_strdup(local_payload->recv_fmtp)); } if (remote_payload != NULL) { @@ -493,20 +551,27 @@ 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); } -void linphone_reporting_on_rtcp_received(LinphoneCall *call, int stats_type) { - reporting_session_report_t * report = call->log->reports[stats_type]; +/* generate random float in interval ] 0.9 t ; 1.1 t [*/ +static float reporting_rand(float t){ + return t * (.2f * (rand() / (RAND_MAX * 1.0f)) + 0.9f); +} + +void linphone_reporting_on_rtcp_update(LinphoneCall *call, int stats_type) { + reporting_session_report_t * report = call->log->reporting.reports[stats_type]; reporting_content_metrics_t * metrics = NULL; - MSQosAnalyzer *analyzer=NULL; LinphoneCallStats stats = call->stats[stats_type]; mblk_t *block = NULL; - - int report_interval = linphone_proxy_config_get_quality_reporting_interval(call->dest_proxy); + int report_interval; if (! media_report_enabled(call,stats_type)) return; + report_interval = linphone_proxy_config_get_quality_reporting_interval(call->dest_proxy); + if (stats.updated == LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE) { metrics = &report->remote_metrics; block = stats.received_rtcp; @@ -514,16 +579,6 @@ void linphone_reporting_on_rtcp_received(LinphoneCall *call, int stats_type) { metrics = &report->local_metrics; block = stats.sent_rtcp; } - /*should not be done there*/ - if (call->audiostream->ms.use_rc&&call->audiostream->ms.rc){ - analyzer=ms_bitrate_controller_get_qos_analyzer(call->audiostream->ms.rc); - if (analyzer){ - ms_qos_analyzer_set_on_action_suggested(analyzer, - qos_analyzer_on_action_suggested, - &report->local_metrics); - } - } - do{ if (rtcp_is_XR(block) && (rtcp_XR_get_block_type(block) == RTCP_XR_VOIP_METRICS)){ @@ -531,9 +586,14 @@ void linphone_reporting_on_rtcp_received(LinphoneCall *call, int stats_type) { metrics->rtcp_xr_count++; - metrics->quality_estimates.rcq += rtcp_XR_voip_metrics_get_r_factor(block); - metrics->quality_estimates.moslq += rtcp_XR_voip_metrics_get_mos_lq(block) / 10.f; - metrics->quality_estimates.moscq += rtcp_XR_voip_metrics_get_mos_cq(block) / 10.f; + // for local mos rating, we'll use the quality indicator directly + // because rtcp XR might not be enabled + if (stats.updated == LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE){ + metrics->quality_estimates.moslq = (rtcp_XR_voip_metrics_get_mos_lq(block)==127) ? + 127 : rtcp_XR_voip_metrics_get_mos_lq(block) / 10.f; + metrics->quality_estimates.moscq = (rtcp_XR_voip_metrics_get_mos_cq(block)==127) ? + 127 : 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); @@ -545,30 +605,101 @@ void linphone_reporting_on_rtcp_received(LinphoneCall *call, int stats_type) { metrics->session_description.packet_loss_concealment = (config >> 6) & 0x3; metrics->delay.round_trip_delay += rtcp_XR_voip_metrics_get_round_trip_delay(block); + }else if (rtcp_is_SR(block)){ + MediaStream *ms=(stats_type==0 ? &call->audiostream->ms : &call->videostream->ms); + float rtt = rtp_session_get_round_trip_propagation(ms->sessions.rtp_session); + + if (rtt > 1e-6){ + metrics->rtcp_sr_count++; + metrics->delay.round_trip_delay += 1000*rtt; + } } }while(rtcp_next_packet(block)); - /* check if we should send an interval report */ - if (report_interval>0 && ms_time(NULL)-report->last_report_date>report_interval){ - linphone_reporting_publish_interval_report(call); + /* check if we should send an interval report - use a random sending time to + dispatch reports and avoid sending them too close from each other */ + if (report_interval>0 && ms_time(NULL)-report->last_report_date>reporting_rand(report_interval)){ + linphone_reporting_update_media_info(call, stats_type); + send_report(call, report, "VQIntervalReport"); } } -static void publish_report(LinphoneCall *call, const char *event_type){ +static int publish_report(LinphoneCall *call, const char *event_type){ + int ret = 0; int i; for (i = 0; i < 2; i++){ if (media_report_enabled(call, i)){ + int sndret; linphone_reporting_update_media_info(call, i); - send_report(call, call->log->reports[i], event_type); + sndret=send_report(call, call->log->reporting.reports[i], event_type); + if (sndret>0){ + ret += 10+(i+1)*sndret; + } + } else{ + ret += i+1; } } -} -void linphone_reporting_publish_session_report(LinphoneCall* call) { - publish_report(call, "VQSessionReport: CallTerm"); + return ret; } -void linphone_reporting_publish_interval_report(LinphoneCall* call) { - publish_report(call, "VQIntervalReport"); +int linphone_reporting_publish_session_report(LinphoneCall* call, bool_t call_term) { + char * session_type = call_term?"VQSessionReport: CallTerm":"VQSessionReport"; + return publish_report(call, session_type); +} + +int linphone_reporting_publish_interval_report(LinphoneCall* call) { + return publish_report(call, "VQIntervalReport"); +} + +void linphone_reporting_call_state_updated(LinphoneCall *call){ + LinphoneCallState state=linphone_call_get_state(call); + + if (! quality_reporting_enabled(call)){ + return; + } + switch (state){ + case LinphoneCallStreamsRunning:{ + bool_t video_enabled=media_report_enabled(call, LINPHONE_CALL_STATS_VIDEO); + int i; + MediaStream *streams[2] = {(MediaStream*) call->audiostream, (MediaStream *) call->videostream}; + MSQosAnalyzer *analyzer; + for (i=0;i<2;i++){ + + if (streams[i]==NULL||streams[i]->rc==NULL){ + ms_message("QualityReporting[%p] Cannot set on_action_suggested" + " callback for %s stream because something is null", call, i?"video":"audio"); + continue; + } + + analyzer=ms_bitrate_controller_get_qos_analyzer(streams[i]->rc); + if (analyzer){ + on_action_suggested_struct_t * oass = ms_new0(on_action_suggested_struct_t, 1); + oass->call = call; + oass->stats_type = i; + STR_REASSIGN(call->log->reporting.reports[i]->qos_analyzer.name, ms_strdup(ms_qos_analyzer_get_name(analyzer))); + + ms_qos_analyzer_set_on_action_suggested(analyzer, + qos_analyzer_on_action_suggested, + oass); + } + } + linphone_reporting_update_ip(call); + if (!video_enabled && call->log->reporting.was_video_running){ + send_report(call, call->log->reporting.reports[LINPHONE_CALL_STATS_VIDEO], "VQSessionReport"); + } + call->log->reporting.was_video_running=video_enabled; + break; + } + case LinphoneCallEnd:{ + if (call->log->status==LinphoneCallSuccess || call->log->status==LinphoneCallAborted){ + linphone_reporting_publish_session_report(call, TRUE); + } + break; + } + default:{ + break; + } + } } reporting_session_report_t * linphone_reporting_new() { @@ -582,18 +713,16 @@ 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.rate = -1;*/ metrics[i]->jitter_buffer.abs_max = -1; metrics[i]->delay.end_system_delay = -1; - /*metrics[i]->delay.one_way_delay = -1;*/ metrics[i]->delay.interarrival_jitter = -1; metrics[i]->delay.mean_abs_jitter = -1; @@ -606,25 +735,34 @@ 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_id != NULL) ms_free(report->info.local_id); - if (report->info.remote_id != NULL) ms_free(report->info.remote_id); - if (report->info.orig_id != NULL) ms_free(report->info.orig_id); - if (report->info.local_addr.ip != NULL) ms_free(report->info.local_addr.ip); - if (report->info.remote_addr.ip != NULL) ms_free(report->info.remote_addr.ip); - if (report->info.local_group != NULL) ms_free(report->info.local_group); - if (report->info.remote_group != NULL) ms_free(report->info.remote_group); - if (report->info.local_mac_addr != NULL) ms_free(report->info.local_mac_addr); - if (report->info.remote_mac_addr != NULL) ms_free(report->info.remote_mac_addr); - if (report->dialog_id != NULL) ms_free(report->dialog_id); - if (report->local_metrics.session_description.fmtp != NULL) ms_free(report->local_metrics.session_description.fmtp); - if (report->local_metrics.session_description.payload_desc != NULL) ms_free(report->local_metrics.session_description.payload_desc); - if (report->remote_metrics.session_description.fmtp != NULL) ms_free(report->remote_metrics.session_description.fmtp); - if (report->remote_metrics.session_description.payload_desc != NULL) ms_free(report->remote_metrics.session_description.payload_desc); - if (report->local_metrics.qos_analyzer.input_leg != NULL) ms_free(report->local_metrics.qos_analyzer.input_leg); - if (report->local_metrics.qos_analyzer.input != NULL) ms_free(report->local_metrics.qos_analyzer.input); - if (report->local_metrics.qos_analyzer.output_leg != NULL) ms_free(report->local_metrics.qos_analyzer.output_leg); - if (report->local_metrics.qos_analyzer.output != NULL) ms_free(report->local_metrics.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); } + + +void linphone_reporting_set_on_report_send(LinphoneCall *call, LinphoneQualityReportingReportSendCb cb){ + call->log->reporting.on_report_sent = cb; +} diff --git a/coreapi/quality_reporting.h b/coreapi/quality_reporting.h index c909baecc..319353fc0 100644 --- a/coreapi/quality_reporting.h +++ b/coreapi/quality_reporting.h @@ -28,12 +28,16 @@ extern "C"{ /** - * Linphone quality report sub object storing address related information (IP/port/MAC). + * Linphone quality report sub object storing address related information. */ typedef struct reporting_addr { + char * id; char * ip; int port; uint32_t ssrc; + + char * group; + char * mac; // optional } reporting_addr_t; /** @@ -50,62 +54,54 @@ 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 { - int rlq; // linked to moslq - in [0..120] - int rcq; //voip metrics R factor - no - vary or avg in [0..120] - float moslq; // no - vary or avg - voip metrics - in [0..4.9] - float moscq; // no - vary or avg - voip metrics - in [0..4.9] + float moslq; + float moscq; } quality_estimates; - // Quality of Service analyzer - custom extension - /* This should allow us to analysis bad network conditions and quality adaptation - on server side*/ - struct { - char* input_leg; - char* input; - char* output_leg; - char* output; - } qos_analyzer; + // 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 } reporting_content_metrics_t; @@ -117,16 +113,9 @@ typedef struct reporting_content_metrics { typedef struct reporting_session_report { struct { char * call_id; - char * local_id; - char * remote_id; char * orig_id; reporting_addr_t local_addr; reporting_addr_t remote_addr; - char * local_group; - char * remote_group; - - char * local_mac_addr; // optional - char * remote_mac_addr; // optional } info; reporting_content_metrics_t local_metrics; @@ -134,10 +123,25 @@ typedef struct reporting_session_report { char * dialog_id; // optional + // Quality of Service analyzer - custom extension + /* This should allow us to analysis bad network conditions and quality adaptation + on server side*/ + struct { + 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 semicolon separated decision*/ + char* output_leg; /*output parameters' name*/ + char* output; /*set of outputs for each semicolon separated decision*/ + } qos_analyzer; + // for internal processing time_t last_report_date; } reporting_session_report_t; + +typedef void (*LinphoneQualityReportingReportSendCb)(const LinphoneCall *call, int stream_type, const LinphoneContent *content); + reporting_session_report_t * linphone_reporting_new(); void linphone_reporting_destroy(reporting_session_report_t * report); @@ -164,24 +168,44 @@ void linphone_reporting_update_ip(LinphoneCall * call); * Publish a session report. This function should be called when session terminates, * media change (codec change or session fork), session terminates due to no media packets being received. * @param call #LinphoneCall object to consider + * @param call_term whether the call has ended or is continuing * + * @return error code. 0 for success, positive value otherwise. */ -void linphone_reporting_publish_session_report(LinphoneCall* call); +int linphone_reporting_publish_session_report(LinphoneCall* call, bool_t call_term); /** * Publish an interval report. This function should be used for periodic interval * @param call #LinphoneCall object to consider + * @return error code. 0 for success, positive value otherwise. * */ -void linphone_reporting_publish_interval_report(LinphoneCall* call); +int linphone_reporting_publish_interval_report(LinphoneCall* call); /** - * Update publish report data with fresh RTCP stats, if needed. + * Update publish reports with newly sent/received RTCP-XR packets (if available). * @param call #LinphoneCall object to consider * @param stats_type the media type (LINPHONE_CALL_STATS_AUDIO or LINPHONE_CALL_STATS_VIDEO) * */ -void linphone_reporting_on_rtcp_received(LinphoneCall *call, int stats_type); +void linphone_reporting_on_rtcp_update(LinphoneCall *call, int stats_type); + +/** + * Update publish reports on call state change. + * @param call #LinphoneCall object to consider + * + */ +void linphone_reporting_call_state_updated(LinphoneCall *call); + +/** + * Setter of the #LinphoneQualityReportingReportSendCb callback method which is + * notified each time a report will be submitted to the collector, if quality + * reporting is enabled + * @param call #LinphoneCall object to consider + * @param cb #LinphoneQualityReportingReportSendCb callback function to notify + * + */ +LINPHONE_PUBLIC void linphone_reporting_set_on_report_send(LinphoneCall *call, LinphoneQualityReportingReportSendCb cb); #ifdef __cplusplus } diff --git a/coreapi/sal.c b/coreapi/sal.c index 74d087139..24da751b6 100644 --- a/coreapi/sal.c +++ b/coreapi/sal.c @@ -84,8 +84,9 @@ void sal_media_description_unref(SalMediaDescription *md){ SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md, SalMediaProto proto, SalStreamType type){ int i; - for(i=0;in_active_streams;++i){ + for(i=0;inb_streams;++i){ SalStreamDescription *ss=&md->streams[i]; + if (!sal_stream_description_active(ss)) continue; if (ss->proto==proto && ss->type==type) return ss; } return NULL; @@ -94,7 +95,8 @@ SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md, unsigned int sal_media_description_nb_active_streams_of_type(SalMediaDescription *md, SalStreamType type) { unsigned int i; unsigned int nb = 0; - for (i = 0; i < md->n_active_streams; ++i) { + for (i = 0; i < md->nb_streams; ++i) { + if (!sal_stream_description_active(&md->streams[i])) continue; if (md->streams[i].type == type) nb++; } return nb; @@ -102,7 +104,8 @@ unsigned int sal_media_description_nb_active_streams_of_type(SalMediaDescription SalStreamDescription * sal_media_description_get_active_stream_of_type(SalMediaDescription *md, SalStreamType type, unsigned int idx) { unsigned int i; - for (i = 0; i < md->n_active_streams; ++i) { + for (i = 0; i < md->nb_streams; ++i) { + if (!sal_stream_description_active(&md->streams[i])) continue; if (md->streams[i].type == type) { if (idx-- == 0) return &md->streams[i]; } @@ -125,18 +128,28 @@ SalStreamDescription * sal_media_description_find_best_stream(SalMediaDescriptio } bool_t sal_media_description_empty(const SalMediaDescription *md){ - if (md->n_active_streams > 0) return FALSE; + if (sal_media_description_get_nb_active_streams(md) > 0) return FALSE; return TRUE; } void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_dir){ int i; - for(i=0;in_active_streams;++i){ + for(i=0;inb_streams;++i){ SalStreamDescription *ss=&md->streams[i]; + if (!sal_stream_description_active(ss)) continue; ss->dir=stream_dir; } } +int sal_media_description_get_nb_active_streams(const SalMediaDescription *md) { + int i; + int nb = 0; + for (i = 0; i < md->nb_streams; i++) { + if (sal_stream_description_active(&md->streams[i])) nb++; + } + return nb; +} + static bool_t is_null_address(const char *addr){ return strcmp(addr,"0.0.0.0")==0 || strcmp(addr,"::0")==0; @@ -147,8 +160,9 @@ static bool_t has_dir(const SalMediaDescription *md, SalStreamDir stream_dir){ int i; /* we are looking for at least one stream with requested direction, inactive streams are ignored*/ - for(i=0;in_active_streams;++i){ + for(i=0;inb_streams;++i){ const SalStreamDescription *ss=&md->streams[i]; + if (!sal_stream_description_active(ss)) continue; if (ss->dir==stream_dir) return TRUE; /*compatibility check for phones that only used the null address and no attributes */ if (ss->dir==SalStreamSendRecv && stream_dir==SalStreamSendOnly && (is_null_address(md->addr) || is_null_address(ss->rtp_addr))) @@ -175,6 +189,38 @@ bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir return FALSE; } +bool_t sal_stream_description_active(const SalStreamDescription *sd) { + return (sd->rtp_port > 0); +} + +bool_t sal_stream_description_has_avpf(const SalStreamDescription *sd) { + return ((sd->proto == SalProtoRtpAvpf) || (sd->proto == SalProtoRtpSavpf)); +} + +bool_t sal_stream_description_has_srtp(const SalStreamDescription *sd) { + return ((sd->proto == SalProtoRtpSavp) || (sd->proto == SalProtoRtpSavpf)); +} + +bool_t sal_media_description_has_avpf(const SalMediaDescription *md) { + int i; + if (md->nb_streams == 0) return FALSE; + for (i = 0; i < md->nb_streams; i++) { + if (!sal_stream_description_active(&md->streams[i])) continue; + if (sal_stream_description_has_avpf(&md->streams[i]) != TRUE) return FALSE; + } + return TRUE; +} + +bool_t sal_media_description_has_srtp(const SalMediaDescription *md) { + int i; + if (md->nb_streams == 0) return FALSE; + for (i = 0; i < md->nb_streams; i++) { + if (!sal_stream_description_active(&md->streams[i])) continue; + if (sal_stream_description_has_srtp(&md->streams[i]) != TRUE) return FALSE; + } + return TRUE; +} + /* static bool_t fmtp_equals(const char *p1, const char *p2){ if (p1 && p2 && strcmp(p1,p2)==0) return TRUE; @@ -261,9 +307,9 @@ int sal_media_description_equals(const SalMediaDescription *md1, const SalMediaD int i; if (strcmp(md1->addr, md2->addr) != 0) result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED; - if (md1->n_total_streams != md2->n_total_streams) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED; + if (md1->nb_streams != md2->nb_streams) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED; if (md1->bandwidth != md2->bandwidth) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED; - for(i = 0; i < md1->n_total_streams; ++i){ + for(i = 0; i < md1->nb_streams; ++i){ result |= sal_stream_description_equals(&md1->streams[i], &md2->streams[i]); } return result; diff --git a/coreapi/upnp.c b/coreapi/upnp.c index 7feaaa30c..5fcbbe065 100644 --- a/coreapi/upnp.c +++ b/coreapi/upnp.c @@ -731,7 +731,7 @@ int linphone_core_update_upnp_from_remote_media_description(LinphoneCall *call, int i; const SalStreamDescription *stream; - for (i = 0; i < md->n_total_streams; i++) { + for (i = 0; i < md->nb_streams; i++) { stream = &md->streams[i]; if(stream->type == SalAudio) { audio = TRUE; @@ -1058,8 +1058,9 @@ int linphone_core_update_local_media_description_from_upnp(SalMediaDescription * SalStreamDescription *stream; UpnpStream *upnpStream; - for (i = 0; i < desc->n_active_streams; i++) { + for (i = 0; i < desc->nb_streams; i++) { stream = &desc->streams[i]; + if (!sal_stream_description_active(stream)) continue; upnpStream = NULL; if(stream->type == SalAudio) { upnpStream = session->audio; diff --git a/gtk/incall_view.c b/gtk/incall_view.c index 382e27746..0450f374c 100644 --- a/gtk/incall_view.c +++ b/gtk/incall_view.c @@ -84,13 +84,13 @@ void linphone_gtk_call_update_tab_header(LinphoneCall *call,gboolean pause){ GtkWidget *i=NULL; GtkWidget *l; gchar *text; - + if(pause){ i=gtk_image_new_from_stock(GTK_STOCK_MEDIA_PAUSE,GTK_ICON_SIZE_SMALL_TOOLBAR); } else { i=create_pixmap ("startcall-small.png"); } - + text=g_strdup_printf(_("Call #%i"),call_index); l=gtk_label_new (text); gtk_box_pack_start (GTK_BOX(new_label),i,FALSE,FALSE,0); @@ -98,6 +98,7 @@ void linphone_gtk_call_update_tab_header(LinphoneCall *call,gboolean pause){ gtk_notebook_set_tab_label(notebook,w,new_label); gtk_widget_show_all(new_label); + g_free(text); } static void linphone_gtk_in_call_set_animation_image(GtkWidget *callview, const char *image_name, gboolean is_stock){ @@ -181,7 +182,7 @@ static void conference_button_clicked(GtkWidget *button, gpointer call_ref){ gtk_widget_set_sensitive(button,FALSE); g_object_set_data(G_OBJECT(linphone_gtk_get_main_window()),"conf_frame",NULL); linphone_core_add_all_to_conference(linphone_gtk_get_core()); - + } void linphone_gtk_enable_conference_button(LinphoneCore *lc, gboolean value){ @@ -271,7 +272,7 @@ static void _refresh_call_stats(GtkWidget *callstats, LinphoneCall *call){ gchar *size_s=g_strdup_printf(_("%ix%i"),size_sent.width,size_sent.height); gtk_label_set_markup(GTK_LABEL(linphone_gtk_get_widget(callstats,"video_size_recv")),size_r); gtk_label_set_markup(GTK_LABEL(linphone_gtk_get_widget(callstats,"video_size_sent")),size_s); - + tmp=g_strdup_printf(_("download: %f\nupload: %f (kbit/s)"),vs->download_bandwidth,vs->upload_bandwidth); g_free(size_r); g_free(size_s); @@ -286,7 +287,7 @@ static void _refresh_call_stats(GtkWidget *callstats, LinphoneCall *call){ audio_media_connectivity = ice_state_to_string(as->ice_state); } gtk_label_set_text(GTK_LABEL(linphone_gtk_get_widget(callstats,"audio_media_connectivity")),audio_media_connectivity); - + if (has_video){ if(vs->upnp_state != LinphoneUpnpStateNotAvailable && vs->upnp_state != LinphoneUpnpStateIdle) { video_media_connectivity = upnp_state_to_string(vs->upnp_state); @@ -295,7 +296,7 @@ static void _refresh_call_stats(GtkWidget *callstats, LinphoneCall *call){ } }else video_media_connectivity=NULL; gtk_label_set_text(GTK_LABEL(linphone_gtk_get_widget(callstats,"video_media_connectivity")),video_media_connectivity); - + if (as->round_trip_delay>0){ tmp=g_strdup_printf(_("%.3f seconds"),as->round_trip_delay); gtk_label_set_text(GTK_LABEL(linphone_gtk_get_widget(callstats,"round_trip_time")),tmp); @@ -467,7 +468,7 @@ void linphone_gtk_remove_in_call_view(LinphoneCall *call){ static void display_peer_name_in_label(GtkWidget *label, const LinphoneAddress *from){ const char *displayname=NULL; - const char *id; + char *id; char *uri_label; displayname=linphone_address_get_display_name(from); id=linphone_address_as_string_uri_only(from); @@ -479,6 +480,7 @@ static void display_peer_name_in_label(GtkWidget *label, const LinphoneAddress * uri_label=g_markup_printf_escaped("%s\n",id); gtk_label_set_markup(GTK_LABEL(label),uri_label); g_free(uri_label); + g_free(id); } void linphone_gtk_in_call_view_set_calling(LinphoneCall *call){ @@ -686,10 +688,10 @@ void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call){ GtkWidget *call_stats=(GtkWidget*)g_object_get_data(G_OBJECT(callview),"call_stats"); display_peer_name_in_label(callee,linphone_call_get_remote_address (call)); - + gtk_widget_hide(linphone_gtk_get_widget(callview,"answer_decline_panel")); gtk_label_set_markup(GTK_LABEL(status),in_conf ? _("In conference") : _("In call")); - + gtk_widget_set_sensitive(linphone_gtk_get_widget(callview,"conference_button"),!in_conf); gtk_widget_set_sensitive(linphone_gtk_get_widget(callview,"transfer_button"),!in_conf); @@ -698,7 +700,7 @@ void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call){ linphone_gtk_call_update_tab_header(call,FALSE); linphone_gtk_enable_mute_button( GTK_BUTTON(linphone_gtk_get_widget(callview,"incall_mute")),TRUE); - + if (taskid==0){ taskid=g_timeout_add(250,(GSourceFunc)linphone_gtk_in_call_view_refresh,call); g_object_set_data(G_OBJECT(callview),"taskid",GINT_TO_POINTER(taskid)); @@ -772,7 +774,7 @@ void linphone_gtk_in_call_view_terminate(LinphoneCall *call, const char *error_m linphone_gtk_enable_mute_button( GTK_BUTTON(linphone_gtk_get_widget(callview,"incall_mute")),FALSE); linphone_gtk_enable_hold_button(call,FALSE,TRUE); - + if (taskid!=0) g_source_remove(taskid); g_timeout_add_seconds(2,(GSourceFunc)in_call_view_terminated,call); if (in_conf) @@ -909,7 +911,7 @@ void linphone_gtk_record_call_toggled(GtkWidget *button){ return; } message=g_strdup_printf(_("Recording into\n%s %s"),filepath,active ? "" : _("(Paused)")); - + if (active){ if (call) linphone_call_start_recording(call); @@ -920,7 +922,7 @@ void linphone_gtk_record_call_toggled(GtkWidget *button){ linphone_call_stop_recording(call); else linphone_core_stop_conference_recording(lc); - + } gtk_label_set_markup(GTK_LABEL(label),message); g_free(message); 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; diff --git a/gtk/main.ui b/gtk/main.ui index 44750d572..06909d6c6 100644 --- a/gtk/main.ui +++ b/gtk/main.ui @@ -1772,7 +1772,7 @@ False model4 0 - + diff --git a/include/sal/sal.h b/include/sal/sal.h index aebfa47c1..22feb58d3 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -215,8 +215,7 @@ typedef struct SalMediaDescription{ char name[64]; char addr[64]; char username[64]; - int n_active_streams; - int n_total_streams; + int nb_streams; int bandwidth; unsigned int session_ver; unsigned int session_id; @@ -259,6 +258,12 @@ SalStreamDescription * sal_media_description_get_active_stream_of_type(SalMediaD SalStreamDescription * sal_media_description_find_secure_stream_of_type(SalMediaDescription *md, SalStreamType type); SalStreamDescription * sal_media_description_find_best_stream(SalMediaDescription *md, SalStreamType type); void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_dir); +bool_t sal_stream_description_active(const SalStreamDescription *sd); +bool_t sal_stream_description_has_avpf(const SalStreamDescription *sd); +bool_t sal_stream_description_has_srtp(const SalStreamDescription *sd); +bool_t sal_media_description_has_avpf(const SalMediaDescription *md); +bool_t sal_media_description_has_srtp(const SalMediaDescription *md); +int sal_media_description_get_nb_active_streams(const SalMediaDescription *md); /*this structure must be at the first byte of the SalOp structure defined by implementors*/ @@ -514,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); @@ -539,7 +545,7 @@ void sal_verify_server_certificates(Sal *ctx, bool_t verify); void sal_verify_server_cn(Sal *ctx, bool_t verify); void sal_set_uuid(Sal*ctx, const char *uuid); int sal_create_uuid(Sal*ctx, char *uuid, size_t len); -void sal_enable_test_features(Sal*ctx, bool_t enabled); +LINPHONE_PUBLIC void sal_enable_test_features(Sal*ctx, bool_t enabled); void sal_use_no_initial_route(Sal *ctx, bool_t enabled); int sal_iterate(Sal *sal); diff --git a/mediastreamer2 b/mediastreamer2 index 24ad96b27..d9c06ebeb 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 24ad96b27ef4d4ae6028ee37f75dfeaf7a4bba42 +Subproject commit d9c06ebebb3a0a37736c83e9f40aead90326d1f6 diff --git a/oRTP b/oRTP index 9d85ca0e1..9d03c3aa1 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 9d85ca0e1a117a2fbfb02de8df3b19bd5eb5db81 +Subproject commit 9d03c3aa1643f1cfae32de4abf04dc84ff3ad175 diff --git a/tester/Makefile.am b/tester/Makefile.am index 46ffb12cd..348306bca 100644 --- a/tester/Makefile.am +++ b/tester/Makefile.am @@ -20,7 +20,8 @@ liblinphonetester_la_SOURCES = tester.c \ eventapi_tester.c \ flexisip_tester.c \ stun_tester.c \ - remote_provisioning_tester.c + remote_provisioning_tester.c \ + quality_reporting_tester.c liblinphonetester_la_LDFLAGS= -no-undefined liblinphonetester_la_LIBADD= ../coreapi/liblinphone.la $(CUNIT_LIBS) @@ -32,14 +33,14 @@ if !BUILD_IOS noinst_PROGRAMS = liblinphone_tester -liblinphone_tester_SOURCES = liblinphone_tester.c -liblinphone_tester_LDADD = $(top_builddir)/coreapi/liblinphone.la liblinphonetester.la +liblinphone_tester_SOURCES = liblinphone_tester.c +liblinphone_tester_LDADD = $(top_builddir)/coreapi/liblinphone.la liblinphonetester.la -lm endif test: liblinphone_tester - ./liblinphone_tester --config $(abs_srcdir) + ./liblinphone_tester --config $(abs_srcdir) else !BUILD_CUNIT_TESTS diff --git a/tester/call_tester.c b/tester/call_tester.c index 7418cbba0..7e3780279 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -1,19 +1,19 @@ /* - liblinphone_tester - liblinphone test suite - Copyright (C) 2013 Belledonne Communications SARL + liblinphone_tester - liblinphone test suite + Copyright (C) 2013 Belledonne Communications SARL - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see . + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ @@ -239,15 +239,176 @@ bool_t call(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr){ return call_with_params(caller_mgr,callee_mgr,NULL,NULL); } -static void simple_call(void) { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); +static void end_call(LinphoneCoreManager *m1, LinphoneCoreManager *m2){ + linphone_core_terminate_all_calls(m1->lc); + CU_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m1->stat.number_of_LinphoneCallEnd,1)); + CU_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m2->stat.number_of_LinphoneCallEnd,1)); +} +static void simple_call(void) { + int begin; + int leaked_objects; + LinphoneCoreManager* marie; + LinphoneCoreManager* pauline; + + belle_sip_object_enable_leak_detector(TRUE); + begin=belle_sip_object_get_object_count(); + + marie = linphone_core_manager_new( "marie_rc"); + pauline = linphone_core_manager_new( "pauline_rc"); CU_ASSERT_TRUE(call(pauline,marie)); liblinphone_tester_check_rtcp(marie,pauline); - + end_call(marie,pauline); linphone_core_manager_destroy(marie); linphone_core_manager_destroy(pauline); + + leaked_objects=belle_sip_object_get_object_count()-begin; + CU_ASSERT_TRUE(leaked_objects==0); + if (leaked_objects>0){ + belle_sip_object_dump_active_objects(); + } +} + +static void call_outbound_with_multiple_proxy() { + LinphoneCoreManager* pauline = linphone_core_manager_new2( "pauline_rc", FALSE); + LinphoneCoreManager* marie = linphone_core_manager_new2( "marie_rc", FALSE); + + LinphoneProxyConfig* lpc = NULL; + LinphoneProxyConfig* registered_lpc = linphone_proxy_config_new(); + + linphone_core_get_default_proxy(marie->lc, &lpc); + linphone_core_set_default_proxy(marie->lc,NULL); + + CU_ASSERT_FATAL(lpc != NULL); + CU_ASSERT_FATAL(registered_lpc != NULL); + + // create new LPC that will successfully register + linphone_proxy_config_set_identity(registered_lpc, linphone_proxy_config_get_identity(lpc)); + linphone_proxy_config_set_server_addr(registered_lpc, linphone_proxy_config_get_addr(lpc)); + linphone_proxy_config_set_route(registered_lpc, linphone_proxy_config_get_route(lpc)); + linphone_proxy_config_enable_register(registered_lpc, TRUE); + + linphone_core_add_proxy_config(marie->lc, registered_lpc); + + // set first LPC to unreacheable proxy addr + linphone_proxy_config_edit(lpc); + linphone_proxy_config_set_server_addr(lpc,"12.13.14.15:5223;transport=udp"); + linphone_proxy_config_set_route(lpc, "12.13.14.15:5223;transport=udp;lr"); + linphone_proxy_config_done(lpc); + + CU_ASSERT_TRUE(wait_for_until(pauline->lc, NULL, &pauline->stat.number_of_LinphoneRegistrationOk, 1, 2000)); + + CU_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneRegistrationProgress, 2, 200)); + CU_ASSERT_TRUE(wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneRegistrationOk, 1, 2000)); + + // calling marie should go through the second proxy config + CU_ASSERT_TRUE(call(marie, pauline)); + +} + +#if 0 /* TODO: activate test when the implementation is ready */ +static void multiple_answers_call() { + /* Scenario is this: pauline calls marie, which is registered 2 times. + Both linphones answer at the same time, and only one should get the + call running, the other should be terminated */ + char ringbackpath[256]; + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc" ); + LinphoneCoreManager* marie1 = linphone_core_manager_new( "marie_rc" ); + LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc" ); + + LinphoneCall* call1, *call2; + + MSList* lcs = ms_list_append(NULL,pauline->lc); + lcs = ms_list_append(lcs,marie1->lc); + lcs = ms_list_append(lcs,marie2->lc); + + linphone_core_use_files(pauline->lc, TRUE); + linphone_core_use_files(marie1->lc, TRUE); + linphone_core_use_files(marie2->lc, TRUE); + + snprintf(ringbackpath,sizeof(ringbackpath), "%s/sounds/hello8000.wav" /*use hello because rinback is too short*/, liblinphone_tester_file_prefix); + + CU_ASSERT_TRUE(wait_for_until(pauline->lc, NULL, &pauline->stat.number_of_LinphoneRegistrationOk, 1, 2000)); + + CU_ASSERT_PTR_NOT_NULL( linphone_core_invite_address(pauline->lc, marie1->identity ) ); + + CU_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneCallIncomingReceived, 1, 2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived, 1, 2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingProgress, 1, 2000)); + + // marie 1 and 2 answer at the same time + call1 = linphone_core_get_current_call(marie1->lc); + call2 = linphone_core_get_current_call(marie2->lc); + + CU_ASSERT_PTR_NOT_NULL_FATAL(call1); + CU_ASSERT_PTR_NOT_NULL_FATAL(call2); + + CU_ASSERT_EQUAL( linphone_core_accept_call(marie1->lc, call1), 0); + CU_ASSERT_EQUAL( linphone_core_accept_call(marie2->lc, call2), 0); + + CU_ASSERT_TRUE( wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1, 2000) ); + CU_ASSERT_TRUE( wait_for_list(lcs, &marie1->stat.number_of_LinphoneCallStreamsRunning, 1, 2000) ); + CU_ASSERT_TRUE( wait_for_list(lcs, &marie2->stat.number_of_LinphoneCallEnd, 1, 2000) ); + + + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie1); + linphone_core_manager_destroy(marie2); +} +#endif + +static void multiple_answers_call_with_media_relay() { + + /* Scenario is this: pauline calls marie, which is registered 2 times. + * Both linphones answer at the same time, and only one should get the + * call running, the other should be terminated */ + char ringbackpath[256]; + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc" ); + LinphoneCoreManager* marie1 = linphone_core_manager_new( "marie_rc" ); + LinphoneCoreManager* marie2 = linphone_core_manager_new( "marie_rc" ); + + LinphoneCall* call1, *call2; + + MSList* lcs = ms_list_append(NULL,pauline->lc); + lcs = ms_list_append(lcs,marie1->lc); + lcs = ms_list_append(lcs,marie2->lc); + + linphone_core_use_files(pauline->lc, TRUE); + linphone_core_use_files(marie1->lc, TRUE); + linphone_core_use_files(marie2->lc, TRUE); + + linphone_core_set_user_agent(pauline->lc, "Natted Linphone", NULL); + linphone_core_set_user_agent(marie1->lc, "Natted Linphone", NULL); + linphone_core_set_user_agent(marie2->lc, "Natted Linphone", NULL); + + snprintf(ringbackpath,sizeof(ringbackpath), "%s/sounds/hello8000.wav" /*use hello because rinback is too short*/, liblinphone_tester_file_prefix); + + CU_ASSERT_TRUE(wait_for_until(pauline->lc, NULL, &pauline->stat.number_of_LinphoneRegistrationOk, 1, 2000)); + + CU_ASSERT_PTR_NOT_NULL( linphone_core_invite_address(pauline->lc, marie1->identity ) ); + + CU_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneCallIncomingReceived, 1, 2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&marie2->stat.number_of_LinphoneCallIncomingReceived, 1, 2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingProgress, 1, 2000)); + + // marie 1 and 2 answer at the same time + call1 = linphone_core_get_current_call(marie1->lc); + call2 = linphone_core_get_current_call(marie2->lc); + + CU_ASSERT_PTR_NOT_NULL_FATAL(call1); + CU_ASSERT_PTR_NOT_NULL_FATAL(call2); + + CU_ASSERT_EQUAL( linphone_core_accept_call(marie1->lc, call1), 0); + CU_ASSERT_EQUAL( linphone_core_accept_call(marie2->lc, call2), 0); + + CU_ASSERT_TRUE( wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1, 2000) ); + CU_ASSERT_TRUE( wait_for_list(lcs, &marie1->stat.number_of_LinphoneCallStreamsRunning, 1, 2000) ); + CU_ASSERT_TRUE( wait_for_list(lcs, &marie2->stat.number_of_LinphoneCallEnd, 1, 2000) ); + + + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie1); + linphone_core_manager_destroy(marie2); } static void call_with_specified_codec_bitrate(void) { @@ -695,11 +856,11 @@ static void call_with_custom_headers(void) { *pauline_remote_contact, *marie_remote_contact, *marie_remote_contact_header; - + LinphoneAddress* marie_identity; char* tmp=linphone_address_as_string_uri_only(marie->identity); char tmp2[256]; snprintf(tmp2,sizeof(tmp2),"%s?uriHeader=myUriHeader",tmp); - LinphoneAddress* marie_identity=linphone_address_new(tmp2); + marie_identity=linphone_address_new(tmp2); ms_free(tmp); linphone_address_destroy(marie->identity); marie->identity=marie_identity; @@ -1051,6 +1212,32 @@ static void call_with_ice_video_added(void) { linphone_core_manager_destroy(pauline); } +static void video_call_with_ice_no_matching_audio_codecs(void) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc"); + LinphoneCall *out_call; + + linphone_core_enable_payload_type(marie->lc, linphone_core_find_payload_type(marie->lc, "PCMU", 8000, 1), FALSE); /* Disable PCMU */ + linphone_core_enable_payload_type(marie->lc, linphone_core_find_payload_type(marie->lc, "PCMA", 8000, 1), TRUE); /* Enable PCMA */ + linphone_core_set_firewall_policy(marie->lc, LinphonePolicyUseIce); + linphone_core_set_stun_server(marie->lc, "stun.linphone.org"); + linphone_core_set_firewall_policy(pauline->lc, LinphonePolicyUseIce); + linphone_core_set_stun_server(pauline->lc, "stun.linphone.org"); + + out_call = linphone_core_invite(marie->lc, "pauline"); + linphone_call_ref(out_call); + CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallOutgoingInit, 1)); + + /* flexisip will retain the 488 until the "urgent reply" timeout arrives. */ + CU_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallError, 1, 6000)); + CU_ASSERT_EQUAL(linphone_call_get_reason(out_call), LinphoneReasonNotAcceptable); + CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallIncomingReceived, 0); + + linphone_call_unref(out_call); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + #endif /*VIDEO_ENABLED*/ static void _call_with_media_relay(bool_t random_ports) { @@ -1211,6 +1398,7 @@ static void call_waiting_indication_with_param(bool_t enable_caller_privacy) { LinphoneCoreManager* laure = linphone_core_manager_new( "laure_rc"); char hellopath[256]; MSList *iterator; + MSList* lcs; LinphoneCall* pauline_called_by_marie; LinphoneCall* pauline_called_by_laure=NULL; LinphoneCallParams *laure_params=linphone_core_create_default_call_parameters(laure->lc); @@ -1219,7 +1407,7 @@ static void call_waiting_indication_with_param(bool_t enable_caller_privacy) { if (enable_caller_privacy) linphone_call_params_set_privacy(marie_params,LinphonePrivacyId); - MSList* lcs=ms_list_append(NULL,marie->lc); + lcs=ms_list_append(NULL,marie->lc); lcs=ms_list_append(lcs,pauline->lc); lcs=ms_list_append(lcs,laure->lc); @@ -2139,120 +2327,6 @@ static void call_rejected_without_403_because_wrong_credentials_no_auth_req_cb() call_rejected_because_wrong_credentials_with_params("tester-no-403",FALSE); } -void create_call_for_quality_reporting_tests( - LinphoneCoreManager* marie, - LinphoneCoreManager* pauline, - LinphoneCall** call_marie, - LinphoneCall** call_pauline) { - CU_ASSERT_TRUE(call(pauline,marie)); - *call_marie = linphone_core_get_current_call(marie->lc); - *call_pauline = linphone_core_get_current_call(pauline->lc); - CU_ASSERT_PTR_NOT_NULL(*call_marie); - CU_ASSERT_PTR_NOT_NULL(*call_pauline); -} - -static void quality_reporting_not_used_without_config() { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - LinphoneCall* call_marie = NULL; - LinphoneCall* call_pauline = NULL; - - create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline); - - // marie has stats collection enabled since pauline has not - CU_ASSERT_TRUE(linphone_proxy_config_quality_reporting_enabled(call_marie->dest_proxy)); - CU_ASSERT_FALSE(linphone_proxy_config_quality_reporting_enabled(call_pauline->dest_proxy)); - - CU_ASSERT_EQUAL(strcmp("sip:collector@sip.example.org", - linphone_proxy_config_get_quality_reporting_collector(call_marie->dest_proxy)), 0); - - // this field should be already filled - CU_ASSERT_PTR_NOT_NULL(call_marie->log->reports[0]->info.local_addr.ip); - CU_ASSERT_PTR_NULL(call_pauline->log->reports[0]->info.local_addr.ip); - - // but not this one since it is updated at the end of call - CU_ASSERT_PTR_NULL(call_marie->log->reports[0]->dialog_id); - - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); -} -static void quality_reporting_not_sent_if_call_not_started() { - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); - LinphoneCallLog* out_call_log; - LinphoneCall* out_call; - - linphone_core_set_max_calls(pauline->lc,0); - out_call = linphone_core_invite(marie->lc,"pauline"); - linphone_call_ref(out_call); - - CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallError,1, 10000)); - CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallError,1); - - if (ms_list_size(linphone_core_get_call_logs(marie->lc))>0) { - CU_ASSERT_PTR_NOT_NULL(out_call_log=(LinphoneCallLog*)(linphone_core_get_call_logs(marie->lc)->data)); - CU_ASSERT_EQUAL(linphone_call_log_get_status(out_call_log),LinphoneCallAborted); - } - linphone_call_unref(out_call); - - // wait a few time... - wait_for(marie->lc,NULL,NULL,0); - // since the callee was busy, there should be no publish to do - CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,0); - CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0); - - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); -} -static void quality_reporting_at_call_termination() { - 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_core_terminate_all_calls(marie->lc); - - // now dialog id should be filled - CU_ASSERT_PTR_NOT_NULL(call_marie->log->reports[0]->dialog_id); - - CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallReleased,1, 10000)); - CU_ASSERT_TRUE(wait_for_until(pauline->lc,NULL,&pauline->stat.number_of_LinphoneCallReleased,1, 10000)); - - CU_ASSERT_PTR_NULL(linphone_core_get_current_call(marie->lc)); - CU_ASSERT_PTR_NULL(linphone_core_get_current_call(pauline->lc)); - - - // PUBLISH submission to the collector should be ok - CU_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishProgress,1)); - CU_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishOk,1)); - - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); -} - -static void quality_reporting_interval_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_proxy_config_set_quality_reporting_interval(call_marie->dest_proxy, 3); - - CU_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(marie->lc)); - CU_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(pauline->lc)); - - // PUBLISH submission to the collector should be ok - CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,3,25000)); - CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,3,25000)); - - linphone_core_manager_destroy(marie); - linphone_core_manager_destroy(pauline); -} - - #ifdef VIDEO_ENABLED /*this is call forking with early media managed at client side (not by flexisip server)*/ static void multiple_early_media(void) { @@ -2330,7 +2404,7 @@ static void multiple_early_media(void) { info=linphone_core_create_info_message(marie1->lc); linphone_call_send_info_message(marie1_call,info); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_inforeceived,1,2000)); - + linphone_core_terminate_all_calls(pauline->lc); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,2000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie1->stat.number_of_LinphoneCallEnd,1,2000)); @@ -2342,6 +2416,115 @@ static void multiple_early_media(void) { } #endif +static void profile_call(bool_t avpf1, bool_t srtp1, bool_t avpf2, bool_t srtp2, const char *expected_profile) { + LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc"); + LinphoneProxyConfig *lpc; + const LinphoneCallParams *params; + + if (avpf1) { + linphone_core_get_default_proxy(marie->lc, &lpc); + linphone_proxy_config_enable_avpf(lpc, TRUE); + linphone_proxy_config_set_avpf_rr_interval(lpc, 3); + } + if (avpf2) { + linphone_core_get_default_proxy(pauline->lc, &lpc); + linphone_proxy_config_enable_avpf(lpc, TRUE); + linphone_proxy_config_set_avpf_rr_interval(lpc, 3); + } + if (srtp1) { + if (linphone_core_media_encryption_supported(marie->lc, LinphoneMediaEncryptionSRTP)) { + linphone_core_set_media_encryption(marie->lc, LinphoneMediaEncryptionSRTP); + } + } + if (srtp2) { + if (linphone_core_media_encryption_supported(pauline->lc, LinphoneMediaEncryptionSRTP)) { + linphone_core_set_media_encryption(pauline->lc, LinphoneMediaEncryptionSRTP); + } + } + + CU_ASSERT_TRUE(call(marie, pauline)); + CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1)); + CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1)); + params = linphone_call_get_current_params(linphone_core_get_current_call(marie->lc)); + CU_ASSERT_STRING_EQUAL(linphone_call_params_get_rtp_profile(params), expected_profile); + params = linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc)); + CU_ASSERT_STRING_EQUAL(linphone_call_params_get_rtp_profile(params), expected_profile); + + linphone_core_terminate_all_calls(marie->lc); + CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1)); + CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1)); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallConnected, 1); + CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallConnected, 1); + + linphone_core_manager_destroy(pauline); + linphone_core_manager_destroy(marie); +} + +static void avp_to_avp_call(void) { + profile_call(FALSE, FALSE, FALSE, FALSE, "RTP/AVP"); +} + +static void avp_to_avpf_call(void) { + profile_call(FALSE, FALSE, TRUE, FALSE, "RTP/AVP"); +} + +static void avp_to_savp_call(void) { + profile_call(FALSE, FALSE, FALSE, TRUE, "RTP/AVP"); +} + +static void avp_to_savpf_call(void) { + profile_call(FALSE, FALSE, TRUE, TRUE, "RTP/AVP"); +} + +static void avpf_to_avp_call(void) { + profile_call(TRUE, FALSE, FALSE, FALSE, "RTP/AVPF"); +} + +static void avpf_to_avpf_call(void) { + profile_call(TRUE, FALSE, TRUE, FALSE, "RTP/AVPF"); +} + +static void avpf_to_savp_call(void) { + profile_call(TRUE, FALSE, FALSE, TRUE, "RTP/AVPF"); +} + +static void avpf_to_savpf_call(void) { + profile_call(TRUE, FALSE, TRUE, TRUE, "RTP/AVPF"); +} + +static void savp_to_avp_call(void) { + profile_call(FALSE, TRUE, FALSE, FALSE, "RTP/SAVP"); +} + +static void savp_to_avpf_call(void) { + profile_call(FALSE, TRUE, TRUE, FALSE, "RTP/SAVP"); +} + +static void savp_to_savp_call(void) { + profile_call(FALSE, TRUE, FALSE, TRUE, "RTP/SAVP"); +} + +static void savp_to_savpf_call(void) { + profile_call(FALSE, TRUE, TRUE, TRUE, "RTP/SAVP"); +} + +static void savpf_to_avp_call(void) { + profile_call(TRUE, TRUE, FALSE, FALSE, "RTP/SAVPF"); +} + +static void savpf_to_avpf_call(void) { + profile_call(TRUE, TRUE, TRUE, FALSE, "RTP/SAVPF"); +} + +static void savpf_to_savp_call(void) { + profile_call(TRUE, TRUE, FALSE, TRUE, "RTP/SAVPF"); +} + +static void savpf_to_savpf_call(void) { + profile_call(TRUE, TRUE, TRUE, TRUE, "RTP/SAVPF"); +} + test_t call_tests[] = { { "Early declined call", early_declined_call }, { "Call declined", call_declined }, @@ -2351,6 +2534,11 @@ test_t call_tests[] = { { "Cancelled ringing call", cancelled_ringing_call }, { "Call failed because of codecs", call_failed_because_of_codecs }, { "Simple call", simple_call }, + { "Outbound call with multiple proxy possible", call_outbound_with_multiple_proxy }, +#if 0 /* not yet activated because not implemented */ + { "Multiple answers to a call", multiple_answers_call }, +#endif + { "Multiple answers to a call with media relay", multiple_answers_call_with_media_relay }, { "Call with media relay", call_with_media_relay}, { "Call with media relay (random ports)", call_with_media_relay_random_ports}, { "Simple call compatibility mode", simple_call_compatibility_mode }, @@ -2377,6 +2565,7 @@ test_t call_tests[] = { { "Call with multiple early media", multiple_early_media }, { "Call with ICE from video to non-video", call_with_ice_video_to_novideo}, { "Call with ICE and video added", call_with_ice_video_added }, + { "Video call with ICE no matching audio codecs", video_call_with_ice_no_matching_audio_codecs }, #endif { "SRTP ice call", srtp_ice_call }, { "ZRTP ice call", zrtp_ice_call }, @@ -2405,11 +2594,23 @@ test_t call_tests[] = { { "Call established with rejected incoming RE-INVITE", call_established_with_rejected_incoming_reinvite }, { "Call established with rejected RE-INVITE in error", call_established_with_rejected_reinvite_with_error}, { "Call redirected by callee", call_redirect}, - { "Quality reporting not used if no config", quality_reporting_not_used_without_config}, - { "Quality reporting session report not sent if call did not start", quality_reporting_not_sent_if_call_not_started}, - { "Quality reporting session report sent if call ended normally", quality_reporting_at_call_termination}, - { "Quality reporting interval report if interval is configured", quality_reporting_interval_report}, - { "Call with specified codec bitrate", call_with_specified_codec_bitrate} + { "Call with specified codec bitrate", call_with_specified_codec_bitrate}, + { "AVP to AVP call", avp_to_avp_call }, + { "AVP to AVPF call", avp_to_avpf_call }, + { "AVP to SAVP call", avp_to_savp_call }, + { "AVP to SAVPF call", avp_to_savpf_call }, + { "AVPF to AVP call", avpf_to_avp_call }, + { "AVPF to AVPF call", avpf_to_avpf_call }, + { "AVPF to SAVP call", avpf_to_savp_call }, + { "AVPF to SAVPF call", avpf_to_savpf_call }, + { "SAVP to AVP call", savp_to_avp_call }, + { "SAVP to AVPF call", savp_to_avpf_call }, + { "SAVP to SAVP call", savp_to_savp_call }, + { "SAVP to SAVPF call", savp_to_savpf_call }, + { "SAVPF to AVP call", savpf_to_avp_call }, + { "SAVPF to AVPF call", savpf_to_avpf_call }, + { "SAVPF to SAVP call", savpf_to_savp_call }, + { "SAVPF to SAVPF call", savpf_to_savpf_call } }; test_suite_t call_test_suite = { diff --git a/tester/eventapi_tester.c b/tester/eventapi_tester.c index e5c459489..1d4b07e59 100644 --- a/tester/eventapi_tester.c +++ b/tester/eventapi_tester.c @@ -38,9 +38,10 @@ const char *liblinphone_tester_get_notify_content(void){ } void linphone_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *eventname, const LinphoneContent *content){ + LinphoneCoreManager *mgr; CU_ASSERT_PTR_NOT_NULL_FATAL(content); CU_ASSERT_TRUE(strcmp(notify_content,(const char*)content->data)==0); - LinphoneCoreManager *mgr=get_manager(lc); + mgr=get_manager(lc); mgr->stat.number_of_NotifyReceived++; } diff --git a/tester/flexisip.conf b/tester/flexisip.conf index 48f4a054b..c4b2a5894 100755 --- a/tester/flexisip.conf +++ b/tester/flexisip.conf @@ -432,6 +432,10 @@ sdp-port-range-max=65535 # Default value: 1 #h264-iframe-decim=1 +# Sends a ACK and BYE to 200 Ok for INVITEs not belonging to any established call. +bye-orphan-dialogs=true + + ## ## The purpose of the Transcoder module is to transparently transcode ## from one audio codec to another to make the communication possible diff --git a/tester/flexisip_tester.c b/tester/flexisip_tester.c index 89c2dfe4b..a91811538 100644 --- a/tester/flexisip_tester.c +++ b/tester/flexisip_tester.c @@ -376,13 +376,14 @@ static void call_forking_declined_localy(void){ static void call_forking_with_push_notification_single(void){ char hellopath[256]; + MSList* lcs; LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); linphone_core_set_user_agent(marie->lc,"Natted Linphone",NULL); linphone_core_set_user_agent(pauline->lc,"Natted Linphone",NULL); - MSList* lcs=ms_list_append(NULL,pauline->lc); + lcs=ms_list_append(NULL,pauline->lc); lcs=ms_list_append(lcs,marie->lc); diff --git a/tester/liblinphone_tester.c b/tester/liblinphone_tester.c index 825e16727..b11cbefaf 100644 --- a/tester/liblinphone_tester.c +++ b/tester/liblinphone_tester.c @@ -147,7 +147,7 @@ return -1; \ int main (int argc, char *argv[]) { - int i,j; + int i; int ret; const char *suite_name=NULL; const char *test_name=NULL; @@ -189,10 +189,7 @@ int main (int argc, char *argv[]) CHECK_ARG("--suite", ++i, argc); suite_name=argv[i]; } else if (strcmp(argv[i],"--list-suites")==0){ - for(j=0;jnumber_of_LinphoneMessageExtBodyReceived++; - CU_ASSERT_STRING_EQUAL(linphone_chat_message_get_external_body_url(message),message_external_body_url); + if (message_external_body_url) + CU_ASSERT_STRING_EQUAL(linphone_chat_message_get_external_body_url(message),message_external_body_url); } } @@ -61,23 +62,29 @@ void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMess * function invoked when a file transfer is received. * */ void file_transfer_received(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size){ - int file=-1; - /* first chunk, creating file */ + FILE* file=NULL; + char receive_file[256]; + snprintf(receive_file,sizeof(receive_file), "%s/receive_file.dump", liblinphone_tester_writable_dir_prefix); + if (!linphone_chat_message_get_user_data(message)) { - file = open("receive_file.dump",O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); - linphone_chat_message_set_user_data(message,(void*)(long)(0x00000000FFFFFFFF&file)); /*store fd for next chunks*/ - } + /*first chunk, creating file*/ + file = fopen("receive_file.dump","wb"); + linphone_chat_message_set_user_data(message,(void*)file); /*store fd for next chunks*/ + } else { + /*next chunk*/ + file = (FILE*)linphone_chat_message_get_user_data(message); - file = (int)((long)(linphone_chat_message_get_user_data(message))&0x00000000FFFFFFFF); - - if (size==0) { /* tranfer complete */ - linphone_chat_room_destroy(linphone_chat_message_get_chat_room(message)); - linphone_chat_message_destroy(message); - stats* counters = get_stats(lc); - counters->number_of_LinphoneMessageExtBodyReceived++; - close(file); - } else { /* store content on a file*/ - write(file,buff,size); + if (size==0) { /* tranfer complerte */ + stats* counters = get_stats(lc); + linphone_chat_room_destroy(linphone_chat_message_get_chat_room(message)); + linphone_chat_message_destroy(message); + counters->number_of_LinphoneMessageExtBodyReceived++; + fclose(file); + } else { /* store content on a file*/ + if (fwrite(buff,size,1,file)==-1){ + ms_error("file_transfer_received(): write() failed: %s",strerror(errno)); + } + } } } @@ -115,12 +122,14 @@ void file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMessage *me const LinphoneAddress* from_address = linphone_chat_message_get_from(message); const LinphoneAddress* to_address = linphone_chat_message_get_to(message); char *address = linphone_chat_message_is_outgoing(message)?linphone_address_as_string(to_address):linphone_address_as_string(from_address); + stats* counters = get_stats(lc); printf(" File transfer [%d%%] %s of type [%s/%s] %s [%s] \n", (int)progress ,(linphone_chat_message_is_outgoing(message)?"sent":"received") , content->type , content->subtype ,(linphone_chat_message_is_outgoing(message)?"to":"from") , address); + counters->progress_of_LinphoneFileTransfer = progress; free(address); } @@ -176,6 +185,8 @@ static void text_message(void) { } static void text_message_within_dialog(void) { + char* to; + LinphoneChatRoom* chat_room; LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); @@ -185,8 +196,8 @@ static void text_message_within_dialog(void) { lp_config_set_int(pauline->lc->config,"sip","chat_use_call_dialogs",1); - char* to = linphone_address_as_string(marie->identity); - LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to); + to = linphone_address_as_string(marie->identity); + chat_room = linphone_core_create_chat_room(pauline->lc,to); ms_free(to); CU_ASSERT_TRUE(call(marie,pauline)); @@ -213,6 +224,8 @@ static void text_message_with_credential_from_auth_cb_auth_info_requested(Linpho static void text_message_with_credential_from_auth_cb(void) { + char* to; + LinphoneChatRoom* chat_room; LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); text_message_with_credential_from_auth_cb_auth_info=linphone_auth_info_clone((LinphoneAuthInfo*)(linphone_core_get_auth_info_list(marie->lc)->data)); @@ -225,8 +238,8 @@ static void text_message_with_credential_from_auth_cb(void) { linphone_core_clear_all_auth_info(marie->lc); marie->lc->vtable.auth_info_requested=text_message_with_credential_from_auth_cb_auth_info_requested; - char* to = linphone_address_as_string(marie->identity); - LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to); + to = linphone_address_as_string(marie->identity); + chat_room = linphone_core_create_chat_room(pauline->lc,to); ms_free(to); @@ -361,6 +374,10 @@ static void text_message_with_external_body(void) { static void file_transfer_message(void) { int i; + LinphoneCoreManager *marie, *pauline; + LinphoneChatRoom *chat_room; + LinphoneContent content; + LinphoneChatMessage *message; /* setting dummy file content to something */ const char* big_file_content="big file"; for (i=0;i<=sizeof(big_file)-strlen(big_file_content);i+=strlen(big_file_content)) @@ -373,8 +390,8 @@ static void file_transfer_message(void) { big_file[0]=*"S"; big_file[sizeof(big_file)-1]=*"E"; - LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); - LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + marie = linphone_core_manager_new( "marie_rc"); + pauline = linphone_core_manager_new( "pauline_rc"); /* make sure lime is not enabled */ linphone_core_set_lime(marie->lc, 0); @@ -385,16 +402,15 @@ static void file_transfer_message(void) { /* create a chatroom on pauline's side */ char* to = linphone_address_as_string(marie->identity); - LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to); + chat_room = linphone_core_create_chat_room(pauline->lc,to); /* create a file transfer message */ - LinphoneContent content; memset(&content,0,sizeof(content)); content.type="text"; content.subtype="plain"; content.size=sizeof(big_file); /*total size to be transfered*/ content.name = "bigfile.txt"; - LinphoneChatMessage* message = linphone_chat_room_create_file_transfer_message(chat_room, &content); + message = linphone_chat_room_create_file_transfer_message(chat_room, &content); linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageExtBodyReceived,1)); @@ -409,6 +425,12 @@ static void file_transfer_message(void) { static void lime_file_transfer_message(void) { int i; + char *to; + LinphoneCoreManager *marie, *pauline; + LinphoneChatRoom *chat_room; + LinphoneContent content; + LinphoneChatMessage *message; + /* setting dummy file content to something */ const char* big_file_content="big file"; for (i=0;ilc, 1); @@ -432,17 +454,16 @@ static void lime_file_transfer_message(void) { linphone_core_set_file_transfer_server(pauline->lc,"https://www.linphone.org:444/lft.php"); /* create a chatroom on pauline's side */ - char* to = linphone_address_as_string(marie->identity); - LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to); + to = linphone_address_as_string(marie->identity); + chat_room = linphone_core_create_chat_room(pauline->lc,to); /* create a file transfer message */ - LinphoneContent content; memset(&content,0,sizeof(content)); content.type="text"; content.subtype="plain"; content.size=sizeof(big_file); /*total size to be transfered*/ content.name = "bigfile.txt"; - LinphoneChatMessage* message = linphone_chat_room_create_file_transfer_message(chat_room, &content); + message = linphone_chat_room_create_file_transfer_message(chat_room, &content); linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageExtBodyReceived,1)); @@ -455,6 +476,53 @@ static void lime_file_transfer_message(void) { linphone_core_manager_destroy(pauline); } +static void file_transfer_message_io_error(void) { + int i; + char* to; + LinphoneChatRoom* chat_room; + LinphoneChatMessage* message; + LinphoneContent content; + const char* big_file_content="big file"; /* setting dummy file content to something */ + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + + /* setting dummy file content to something */ + for (i=0;ilc,"https://www.linphone.org:444/lft.php"); + + /* create a chatroom on pauline's side */ + to = linphone_address_as_string(marie->identity); + chat_room = linphone_core_create_chat_room(pauline->lc,to); + + /* create a file transfer message */ + memset(&content,0,sizeof(content)); + content.type="text"; + content.subtype="plain"; + content.size=sizeof(big_file); /*total size to be transfered*/ + content.name = "bigfile.txt"; + message = linphone_chat_room_create_file_transfer_message(chat_room, &content); + + linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc); + + /*wait for file to be 25% uploaded and simultate a network error*/ + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.progress_of_LinphoneFileTransfer,25)); + sal_set_send_error(pauline->lc->sal, -1); + + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageNotDelivered,1)); + + CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageNotDelivered,1); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneMessageExtBodyReceived,0); + + sal_set_send_error(pauline->lc->sal, 0); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} static void text_message_with_send_error(void) { LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); @@ -894,6 +962,7 @@ test_t message_tests[] = { { "Text message with external body", text_message_with_external_body }, { "File transfer message", file_transfer_message }, { "Lime File transfer message", lime_file_transfer_message }, + { "File transfer message with io error", file_transfer_message_io_error }, { "Text message denied", text_message_denied }, { "Info message", info_message }, { "Info message with body", info_message_with_body }, diff --git a/tester/quality_reporting_tester.c b/tester/quality_reporting_tester.c new file mode 100644 index 000000000..b6b449b91 --- /dev/null +++ b/tester/quality_reporting_tester.c @@ -0,0 +1,336 @@ +/* + liblinphone_tester - liblinphone test suite + Copyright (C) 2013 Belledonne Communications SARL + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#include +#include "CUnit/Basic.h" +#include "linphonecore.h" +#include "private.h" +#include "liblinphone_tester.h" + +/*avoid crash if x is NULL on libc versions <4.5.26 */ +#define __strstr(x, y) ((x==NULL)?NULL:strstr(x,y)) + +void on_report_send_mandatory(const LinphoneCall *call, int stream_type, const LinphoneContent *content){ + char * body = (char *)content->data; + char * remote_metrics_start = __strstr(body, "RemoteMetrics:"); + reporting_session_report_t * report = call->log->reporting.reports[stream_type]; + MediaStream * ms; + if (stream_type == LINPHONE_CALL_STATS_AUDIO){ + ms = (MediaStream*)call->audiostream; + }else{ + ms = (MediaStream*)call->videostream; + } + CU_ASSERT_TRUE( + __strstr(body, "VQIntervalReport\r\n") == body || + __strstr(body, "VQSessionReport\r\n") == body || + __strstr(body, "VQSessionReport: CallTerm\r\n") == body + ); + + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "CallID:")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalID:")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "RemoteID:")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "OrigID:")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalGroup:")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "RemoteGroup:")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalAddr:")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "IP=")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PORT=")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SSRC=")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "RemoteAddr:")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "IP=")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PORT=")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SSRC=")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalMetrics:")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "Timestamps:")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "START=")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "STOP=")); + + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SessionDesc:")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PT=")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PD=")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SR=")); + + /* We should have not reached RemoteMetrics section yet */ + CU_ASSERT_TRUE(!remote_metrics_start || body < remote_metrics_start); + + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "DialogID:")); + + if (report->remote_metrics.rtcp_sr_count&&ms!=NULL&&ms->rc!=NULL){ + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "AdaptiveAlg:")); + } +} + +char * on_report_send_verify_metrics(const reporting_content_metrics_t *metrics, char * body){ + if (metrics->rtcp_xr_count){ + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "SessionDesc:")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "JitterBuffer:")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "PacketLoss:")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "QualityEst:")); + } + if (metrics->rtcp_sr_count+metrics->rtcp_xr_count>0){ + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "Delay:")); + } + + return body; +} + +void on_report_send_with_rtcp_xr_local(const LinphoneCall *call, int stream_type, const LinphoneContent *content){ + char * body = (char*)content->data; + char * remote_metrics_start = __strstr(body, "RemoteMetrics:"); + reporting_session_report_t * report = call->log->reporting.reports[stream_type]; + on_report_send_mandatory(call,stream_type,content); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "LocalMetrics:")); + CU_ASSERT_TRUE(!remote_metrics_start || on_report_send_verify_metrics(&report->local_metrics,body) < remote_metrics_start); +} +void on_report_send_with_rtcp_xr_remote(const LinphoneCall *call, int stream_type, const LinphoneContent *content){ + char * body = (char*)content->data; + reporting_session_report_t * report = call->log->reporting.reports[stream_type]; + + on_report_send_mandatory(call,stream_type,content); + if (report->remote_metrics.rtcp_sr_count+report->remote_metrics.rtcp_xr_count>0){ + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "RemoteMetrics:")); + CU_ASSERT_PTR_NOT_NULL(body=__strstr(body, "Timestamps:")); + on_report_send_verify_metrics(&report->remote_metrics,body); + } +} +void on_report_send_with_rtcp_xr_both(const LinphoneCall *call, int stream_type, const LinphoneContent *content){ + on_report_send_with_rtcp_xr_local(call,stream_type,content); + on_report_send_with_rtcp_xr_remote(call,stream_type,content); +} + +void create_call_for_quality_reporting_tests( + LinphoneCoreManager* marie, + LinphoneCoreManager* pauline, + LinphoneCall** call_marie, + LinphoneCall** call_pauline) { + CU_ASSERT_TRUE(call(pauline,marie)); + *call_marie = linphone_core_get_current_call(marie->lc); + *call_pauline = linphone_core_get_current_call(pauline->lc); + CU_ASSERT_PTR_NOT_NULL(*call_marie); + CU_ASSERT_PTR_NOT_NULL(*call_pauline); +} + +static void quality_reporting_not_used_without_config() { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCall* call_marie = NULL; + LinphoneCall* call_pauline = NULL; + + create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline); + + // marie has stats collection enabled but pauline has not + CU_ASSERT_TRUE(linphone_proxy_config_quality_reporting_enabled(call_marie->dest_proxy)); + CU_ASSERT_FALSE(linphone_proxy_config_quality_reporting_enabled(call_pauline->dest_proxy)); + + CU_ASSERT_EQUAL(strcmp("sip:collector@sip.example.org", + linphone_proxy_config_get_quality_reporting_collector(call_marie->dest_proxy)), 0); + + // this field should be already filled + CU_ASSERT_PTR_NOT_NULL(call_marie->log->reporting.reports[0]->info.local_addr.ip); + + // but not this one since it is updated at the end of call + CU_ASSERT_PTR_NULL(call_marie->log->reporting.reports[0]->dialog_id); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void quality_reporting_not_sent_if_call_not_started() { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCallLog* out_call_log; + LinphoneCall* out_call; + + linphone_core_set_max_calls(pauline->lc,0); + out_call = linphone_core_invite(marie->lc,"pauline"); + linphone_call_ref(out_call); + + CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallError,1, 10000)); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallError,1); + + if (ms_list_size(linphone_core_get_call_logs(marie->lc))>0) { + out_call_log=(LinphoneCallLog*)(linphone_core_get_call_logs(marie->lc)->data); + CU_ASSERT_PTR_NOT_NULL(out_call_log); + CU_ASSERT_EQUAL(linphone_call_log_get_status(out_call_log),LinphoneCallAborted); + } + linphone_call_unref(out_call); + + // wait a few time... + wait_for_until(marie->lc,NULL,NULL,0,1000); + + // since the callee was busy, there should be no publish to do + CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,0); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void quality_reporting_not_sent_if_low_bandwidth() { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCallParams* marie_params; + + marie_params=linphone_core_create_default_call_parameters(marie->lc); + linphone_call_params_enable_low_bandwidth(marie_params,TRUE); + + CU_ASSERT_TRUE(call_with_params(marie,pauline,marie_params,NULL)); + + linphone_core_terminate_all_calls(marie->lc); + + CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,0); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +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"); + LinphoneCall* call_marie = NULL; + LinphoneCall* call_pauline = NULL; + + create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline); + linphone_reporting_set_on_report_send(call_marie, on_report_send_with_rtcp_xr_remote); + + linphone_core_terminate_all_calls(marie->lc); + + // now dialog id should be filled + CU_ASSERT_PTR_NOT_NULL(call_marie->log->reporting.reports[0]->dialog_id); + + CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallReleased,1, 10000)); + CU_ASSERT_TRUE(wait_for_until(pauline->lc,NULL,&pauline->stat.number_of_LinphoneCallReleased,1, 10000)); + + CU_ASSERT_PTR_NULL(linphone_core_get_current_call(marie->lc)); + CU_ASSERT_PTR_NULL(linphone_core_get_current_call(pauline->lc)); + + // PUBLISH submission to the collector should be ok + CU_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishProgress,1)); + CU_ASSERT_TRUE(wait_for(marie->lc,NULL,&marie->stat.number_of_LinphonePublishOk,1)); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void quality_reporting_interval_report() { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc_rtcp_xr"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc_rtcp_xr"); + LinphoneCall* call_marie = NULL; + LinphoneCall* call_pauline = NULL; + + create_call_for_quality_reporting_tests(marie, pauline, &call_marie, &call_pauline); + linphone_reporting_set_on_report_send(call_marie, on_report_send_mandatory); + linphone_proxy_config_set_quality_reporting_interval(call_marie->dest_proxy, 3); + + CU_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(marie->lc)); + CU_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call(pauline->lc)); + + // PUBLISH submission to the collector should be ok + CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,3,25000)); + CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,3,25000)); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +static void quality_reporting_session_report_if_video_stopped() { + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc_rtcp_xr"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc"); + LinphoneCall* call_pauline = NULL; + LinphoneCallParams* pauline_params; + LinphoneCallParams* marie_params; + + linphone_core_enable_video_capture(marie->lc, TRUE); + linphone_core_enable_video_display(marie->lc, FALSE); + linphone_core_enable_video_capture(pauline->lc, TRUE); + linphone_core_enable_video_display(pauline->lc, FALSE); + marie_params=linphone_core_create_default_call_parameters(marie->lc); + linphone_call_params_enable_video(marie_params,TRUE); + pauline_params=linphone_core_create_default_call_parameters(pauline->lc); + linphone_call_params_enable_video(pauline_params,TRUE); + CU_ASSERT_TRUE(call_with_params(pauline,marie,pauline_params,marie_params)); + call_pauline=linphone_core_get_current_call(pauline->lc); + linphone_reporting_set_on_report_send(linphone_core_get_current_call(marie->lc), on_report_send_with_rtcp_xr_local); + + CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishProgress,0); + CU_ASSERT_EQUAL(marie->stat.number_of_LinphonePublishOk,0); + + CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,NULL,0,3000)); + CU_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(call_pauline))); + + /*remove video*/ + linphone_call_params_enable_video(pauline_params,FALSE); + linphone_core_update_call(pauline->lc,call_pauline,pauline_params); + + CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,1,5000)); + CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,1,5000)); + + CU_ASSERT_FALSE(linphone_call_params_video_enabled(linphone_call_get_current_params(call_pauline))); + + linphone_core_terminate_all_calls(marie->lc); + + CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishProgress,2,5000)); + CU_ASSERT_TRUE(wait_for_until(marie->lc,pauline->lc,&marie->stat.number_of_LinphonePublishOk,2,5000)); + + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); +} + +test_t quality_reporting_tests[] = { + { "Not used if no config", quality_reporting_not_used_without_config}, + { "Call term session report not sent if call did not start", quality_reporting_not_sent_if_call_not_started}, + { "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}, +}; + +test_suite_t quality_reporting_test_suite = { + "QualityReporting", + NULL, + NULL, + sizeof(quality_reporting_tests) / sizeof(quality_reporting_tests[0]), + quality_reporting_tests +}; diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/marie_rc b/tester/rcfiles/marie_rc_rtcp_xr similarity index 60% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/marie_rc rename to tester/rcfiles/marie_rc_rtcp_xr index 56c96bc98..93f8e5bd0 100644 --- a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/marie_rc +++ b/tester/rcfiles/marie_rc_rtcp_xr @@ -1,16 +1,17 @@ [sip] -sip_port=5082 -sip_tcp_port=5082 -sip_tls_port=5083 +sip_port=-1 +sip_tcp_port=-1 +sip_tls_port=-1 default_proxy=0 ping_with_options=0 register_only_when_network_is_up=0 +composing_idle_timeout=1 [auth_info_0] username=marie userid=marie passwd=secret -realm="sip.example.org" +realm=sip.example.org [proxy_0] @@ -21,6 +22,8 @@ reg_expires=3600 reg_sendregister=1 publish=0 dial_escape_plus=0 +quality_reporting_collector=sip:collector@sip.example.org +quality_reporting_enabled=1 [friend_0] url="Paupoche" @@ -30,7 +33,12 @@ subscribe=0 [rtp] audio_rtp_port=8070 -video_rtp_port=8072 +video_rtp_port=9072 +rtcp_xr_enabled=1 +rtcp_xr_rcvr_rtt_mode=all +rtcp_xr_rcvr_rtt_max_size=10000 +rtcp_xr_stat_summary_enabled=1 +rtcp_xr_voip_metrics_enabled=1 [video] display=0 @@ -44,4 +52,4 @@ automatically_accept=0 device=StaticImage: Static picture [sound] -echocancellation=0 #to not overload cpu in case of VG \ No newline at end of file +echocancellation=0 #to not overload cpu in case of VG diff --git a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/pauline_rc b/tester/rcfiles/pauline_rc_rtcp_xr similarity index 66% rename from build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/pauline_rc rename to tester/rcfiles/pauline_rc_rtcp_xr index 4ff876cf7..331f942ef 100644 --- a/build/vsx/LibLinphoneTester-wp8/LibLinphoneTester-wp8/Assets/pauline_rc +++ b/tester/rcfiles/pauline_rc_rtcp_xr @@ -1,16 +1,17 @@ [sip] -sip_port=5072 -sip_tcp_port=5072 -sip_tls_port=5073 +sip_port=-1 +sip_tcp_port=-1 +sip_tls_port=-1 default_proxy=0 ping_with_options=0 register_only_when_network_is_up=0 +composing_idle_timeout=1 [auth_info_0] username=pauline userid=pauline passwd=secret -realm="sip.example.org" +realm=sip.example.org [proxy_0] @@ -29,7 +30,12 @@ dial_escape_plus=0 [rtp] audio_rtp_port=8090 -video_rtp_port=8092 +video_rtp_port=9092 +rtcp_xr_enabled=1 +rtcp_xr_rcvr_rtt_mode=all +rtcp_xr_rcvr_rtt_max_size=10000 +rtcp_xr_stat_summary_enabled=1 +rtcp_xr_voip_metrics_enabled=1 [video] display=0 @@ -43,4 +49,4 @@ automatically_accept=0 device=StaticImage: Static picture [sound] -echocancellation=0 #to not overload cpu in case of VG \ No newline at end of file +echocancellation=0 #to not overload cpu in case of VG diff --git a/tester/remote_provisioning_tester.c b/tester/remote_provisioning_tester.c index 365673ff6..d81df94d4 100644 --- a/tester/remote_provisioning_tester.c +++ b/tester/remote_provisioning_tester.c @@ -23,9 +23,10 @@ #include "liblinphone_tester.h" void linphone_configuration_status(LinphoneCore *lc, LinphoneConfiguringState status, const char *message) { + stats* counters; ms_message("Configuring state = %i with message %s", status, message?message:""); - stats* counters = get_stats(lc); + counters = get_stats(lc); if (status == LinphoneConfiguringSkipped) { counters->number_of_LinphoneConfiguringSkipped++; } else if (status == LinphoneConfiguringFailed) { diff --git a/tester/stun_tester.c b/tester/stun_tester.c index d19650f06..99b1190ed 100644 --- a/tester/stun_tester.c +++ b/tester/stun_tester.c @@ -61,7 +61,7 @@ static void linphone_stun_test_encode() len = test_stun_encode(bigBuff, bigLen, TRUE); CU_ASSERT(len > 0); - ms_message("STUN message encoded in %zu bytes", len); + ms_message("STUN message encoded in %i bytes", (int)len); } diff --git a/tester/tester.c b/tester/tester.c index 1f1c8d725..268a0f302 100644 --- a/tester/tester.c +++ b/tester/tester.c @@ -291,6 +291,13 @@ int liblinphone_tester_test_suite_index(const char *suite_name) { return -1; } +void liblinphone_tester_list_suites() { + int j; + for(j=0;jpName); + return -2; + } else { + CU_ErrorCode err= CU_basic_run_test(suite, test); + if (err != CUE_SUCCESS) ms_error("CU_basic_run_test error %d", err); + } + } else { CU_basic_run_suite(suite); + } } else { #if HAVE_CU_CURSES