Merge remote-tracking branch 'linphone/master'

This commit is contained in:
Simon Morlat 2014-10-10 08:39:02 +02:00
commit 052f1dc476
165 changed files with 14403 additions and 8128 deletions

View file

@ -20,7 +20,7 @@
#
############################################################################
cmake_minimum_required(VERSION 2.6)
cmake_minimum_required(VERSION 2.8.12)
project(LINPHONE C CXX)
@ -61,6 +61,13 @@ endif()
find_package(BelleSIP REQUIRED)
find_package(MS2 REQUIRED)
find_package(XML2 REQUIRED)
if(ENABLE_TUNNEL)
find_package(Tunnel)
if(NOT TUNNEL_FOUND)
message(WARNING "Could not find the tunnel library!")
set(ENABLE_TUNNEL OFF CACHE BOOL "Enable tunnel support" FORCE)
endif()
endif()
include_directories(
@ -72,6 +79,9 @@ include_directories(
${MS2_INCLUDE_DIRS}
${XML2_INCLUDE_DIRS}
)
if(ENABLE_TUNNEL)
include_directories(${TUNNEL_INCLUDE_DIRS})
endif()
if(MSVC)
include_directories(${CMAKE_PREFIX_PATH}/include/MSVC)
@ -94,6 +104,9 @@ add_definitions(-DHAVE_CONFIG_H)
add_subdirectory(coreapi)
add_subdirectory(share)
if(ENABLE_TOOLS)
add_subdirectory(tools)
endif()
install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/FindLinphone.cmake

View file

@ -26,6 +26,7 @@
# LINPHONE_INCLUDE_DIRS - the linphone include directory
# LINPHONE_LIBRARIES - The libraries needed to use linphone
# LINPHONE_CPPFLAGS - The compilation flags needed to use linphone
# LINPHONE_LDFLAGS - The linking flags needed to use linphone
find_package(ORTP REQUIRED)
find_package(MS2 REQUIRED)
@ -55,15 +56,19 @@ find_library(LINPHONE_LIBRARIES
list(APPEND LINPHONE_INCLUDE_DIRS ${ORTP_INCLUDE_DIRS} ${MS2_INCLUDE_DIRS} ${XML2_INCLUDE_DIRS} ${BELLESIP_INCLUDE_DIRS})
list(APPEND LINPHONE_LIBRARIES ${ORTP_LIBRARIES} ${MS2_LIBRARIES} ${XML2_LIBRARIES} ${BELLESIP_LIBRARIES})
if(WIN32)
list(APPEND LINPHONE_LIBRARIES shlwapi)
endif(WIN32)
list(REMOVE_DUPLICATES LINPHONE_INCLUDE_DIRS)
list(REMOVE_DUPLICATES LINPHONE_LIBRARIES)
set(LINPHONE_CPPFLAGS ${MS2_CPPFLAGS})
set(LINPHONE_CPPFLAGS "${MS2_CPPFLAGS}")
set(LINPHONE_LDFLAGS "${MS2_LDFLAGS} ${BELLESIP_LDFLAGS}")
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Linphone
DEFAULT_MSG
LINPHONE_INCLUDE_DIRS LINPHONE_LIBRARIES LINPHONE_CPPFLAGS
LINPHONE_INCLUDE_DIRS LINPHONE_LIBRARIES
)
mark_as_advanced(LINPHONE_INCLUDE_DIRS LINPHONE_LIBRARIES LINPHONE_CPPFLAGS)
mark_as_advanced(LINPHONE_INCLUDE_DIRS LINPHONE_LIBRARIES LINPHONE_CPPFLAGS LINPHONE_LDFLAGS)

7
README
View file

@ -33,10 +33,13 @@ This is Linphone, a free (GPL) video softphone based on the SIP protocol.
Here is the command line to get these dependencies installed for Ubuntu && Debian
$ sudo apt-get install libtool intltool libgtk2.0-dev libspeexdsp-dev libavcodec-dev libswscale-dev libx11-dev libxv-dev libgl1-mesa-dev libglew1.6-dev libv4l-dev libxml2-dev
$ sudo apt-get install libtool intltool libgtk2.0-dev libspeexdsp-dev \
libavcodec-dev libswscale-dev libx11-dev libxv-dev libgl1-mesa-dev \
libglew1.6-dev libv4l-dev libxml2-dev
+ for optional library
$ sudo apt-get install libreadline-dev libgsm1-dev libtheora-dev libsoup2.4-dev libsqlite3-dev libupnp4-dev
$ sudo apt-get install libreadline-dev libgsm1-dev libtheora-dev \
libsoup2.4-dev libsqlite3-dev libupnp4-dev
+ Install srtp (optional) for call encryption :
$ git clone git://git.linphone.org/srtp.git

View file

@ -4,6 +4,7 @@
You need:
- Xcode (download from apple or using appstore application)
- Java SE
- Macports: http://www.macports.org/
Download and install macports using its user friendly installer.
@ -17,7 +18,7 @@ You need:
$ sudo port install automake autoconf libtool intltool wget cunit
- Install some linphone dependencies with macports
$ sudo port install antlr3 speex libvpx readline sqlite3 libsoup openldap
$ sudo port install antlr3 speex libvpx readline sqlite3 libsoup openldap libupnp
$ sudo port install ffmpeg-devel -gpl2
- Install gtk. It is recommended to use the quartz backend for better integration.

View file

@ -29,7 +29,7 @@ Download lastest linphone-deps-win32 zip from
http://download.savannah.gnu.org/releases-noredirect/linphone/misc
using your browser.
Download lastest gtk+-2.24.10 win32 _bundle_ from http://www.gtk.org
Download gtk+-2.24.10 win32 _bundle_ from http://www.gtk.org, direct link: http://ftp.gnome.org/pub/gnome/binaries/win32/gtk+/2.24/gtk+-bundle_2.24.10-20120208_win32.zip
Install all these three package in /:
@ -60,9 +60,12 @@ General rules for compilation
- all other commands (configure, autogen.sh, make) must be done within the mingw shell (msys).
In both msys and msys-git windows, change into the directory you created for sources:
cd /c/sources
- make sure pkg-config works by adding this env variable to your terminal:
export PKG_CONFIG_PATH=/usr/lib/pkgconfig
Building belle-sip
******************
* make sure that java version 1.6 is available in the PATH. java-1.7 will not work with antlr generator.
* download the sources with msys-git shell using the following command:
$ git clone git://git.linphone.org/belle-sip.git
* compile and install

View file

@ -65,10 +65,14 @@ LOCAL_SRC_FILES := \
xml2lpc.c \
lpc2xml.c \
remote_provisioning.c \
quality_reporting.c
quality_reporting.c \
call_log.c \
call_params.c \
player.c \
fileplayer.c
ifndef LINPHONE_VERSION
LINPHONE_VERSION = "Devel"
ifndef LIBLINPHONE_VERSION
LIBLINPHONE_VERSION = "Devel"
endif
LOCAL_CFLAGS += \
@ -77,7 +81,7 @@ LOCAL_CFLAGS += \
-DINET6 \
-DENABLE_TRACE \
-DHAVE_CONFIG_H \
-DLINPHONE_VERSION=\"$(LINPHONE_VERSION)\" \
-DLIBLINPHONE_VERSION=\"$(LIBLINPHONE_VERSION)\" \
-DLINPHONE_PLUGINS_DIR=\"\\tmp\" \
-DUSE_BELLESIP

View file

@ -1 +0,0 @@
#define LIBLINPHONE_GIT_VERSION "unknown"

View file

@ -13,7 +13,9 @@ common_SRC_FILES := \
flexisip_tester.c \
tester.c \
remote_provisioning_tester.c \
quality_reporting_tester.c
quality_reporting_tester.c \
transport_tester.c \
player_tester.c
common_C_INCLUDES += \
$(LOCAL_PATH) \

View file

@ -53,8 +53,8 @@
<ItemDefinitionGroup>
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\belle-sip\include;$(ProjectDir)..\..\oRTP\include;$(ProjectDir)..\..\mediastreamer2\include;$(ProjectDIr)..\..\..\tunnel\include;$(ProjectDir)..\..\coreapi;$(ProjectDir)..\..\include;$(SolutionDir)$(Platform)\$(Configuration)\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__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)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>$(ProjectDir)..\..\..\belle-sip\include;$(ProjectDir)..\..\oRTP\include;$(ProjectDir)..\..\mediastreamer2\include;$(ProjectDir)..\..\..\tunnel\include;$(ProjectDir)..\..\coreapi;$(ProjectDir)..\..\include;$(SolutionDir)$(Platform)\$(Configuration)\include;$(ProjectDir)..\..\..\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>__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;HAVE_ZLIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<CompileAsWinRT>false</CompileAsWinRT>
@ -107,6 +107,8 @@
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_op_publish.c" />
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_op_registration.c" />
<ClCompile Include="..\..\coreapi\bellesip_sal\sal_sdp.c" />
<ClCompile Include="..\..\coreapi\call_log.c" />
<ClCompile Include="..\..\coreapi\call_params.c" />
<ClCompile Include="..\..\coreapi\callbacks.c" />
<ClCompile Include="..\..\coreapi\chat.c" />
<ClCompile Include="..\..\coreapi\conference.c" />
@ -124,6 +126,7 @@
<ClCompile Include="..\..\coreapi\message_storage.c" />
<ClCompile Include="..\..\coreapi\misc.c" />
<ClCompile Include="..\..\coreapi\offeranswer.c" />
<ClCompile Include="..\..\coreapi\player.c" />
<ClCompile Include="..\..\coreapi\presence.c" />
<ClCompile Include="..\..\coreapi\proxy.c" />
<ClCompile Include="..\..\coreapi\quality_reporting.c" />
@ -198,6 +201,9 @@
<ProjectReference Include="libxml2\libxml2.vcxproj">
<Project>{5dfa07b4-0be9-46a9-ba32-fdf5a55c580b}</Project>
</ProjectReference>
<ProjectReference Include="zlib\zlib.vcxproj">
<Project>{7afac3bb-d97b-4578-b9fe-5e1d2b94ea2f}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsPhone\v$(TargetPlatformVersion)\Microsoft.Cpp.WindowsPhone.$(TargetPlatformVersion).targets" />

View file

@ -105,6 +105,7 @@
<ClCompile Include="..\..\..\tester\setup_tester.c" />
<ClCompile Include="..\..\..\tester\stun_tester.c" />
<ClCompile Include="..\..\..\tester\tester.c" />
<ClCompile Include="..\..\..\tester\transport_tester.c" />
<ClCompile Include="linphone-tester-native.cpp">
<CompileAsWinRT>true</CompileAsWinRT>
</ClCompile>
@ -153,4 +154,4 @@
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsPhone\v$(TargetPlatformVersion)\Microsoft.Cpp.WindowsPhone.$(TargetPlatformVersion).targets" />
</Project>
</Project>

513
build/wp8/zlib/zconf.h Normal file
View file

@ -0,0 +1,513 @@
/* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-2013 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#ifndef ZCONF_H
#define ZCONF_H
/* #undef Z_PREFIX */
#define Z_HAVE_UNISTD_H
/*
* If you *really* need a unique prefix for all types and library functions,
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
* Even better than compiling with -DZ_PREFIX would be to use configure to set
* this permanently in zconf.h using "./configure --zprefix".
*/
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
# define Z_PREFIX_SET
/* all linked symbols */
# define _dist_code z__dist_code
# define _length_code z__length_code
# define _tr_align z__tr_align
# define _tr_flush_bits z__tr_flush_bits
# define _tr_flush_block z__tr_flush_block
# define _tr_init z__tr_init
# define _tr_stored_block z__tr_stored_block
# define _tr_tally z__tr_tally
# define adler32 z_adler32
# define adler32_combine z_adler32_combine
# define adler32_combine64 z_adler32_combine64
# ifndef Z_SOLO
# define compress z_compress
# define compress2 z_compress2
# define compressBound z_compressBound
# endif
# define crc32 z_crc32
# define crc32_combine z_crc32_combine
# define crc32_combine64 z_crc32_combine64
# define deflate z_deflate
# define deflateBound z_deflateBound
# define deflateCopy z_deflateCopy
# define deflateEnd z_deflateEnd
# define deflateInit2_ z_deflateInit2_
# define deflateInit_ z_deflateInit_
# define deflateParams z_deflateParams
# define deflatePending z_deflatePending
# define deflatePrime z_deflatePrime
# define deflateReset z_deflateReset
# define deflateResetKeep z_deflateResetKeep
# define deflateSetDictionary z_deflateSetDictionary
# define deflateSetHeader z_deflateSetHeader
# define deflateTune z_deflateTune
# define deflate_copyright z_deflate_copyright
# define get_crc_table z_get_crc_table
# ifndef Z_SOLO
# define gz_error z_gz_error
# define gz_intmax z_gz_intmax
# define gz_strwinerror z_gz_strwinerror
# define gzbuffer z_gzbuffer
# define gzclearerr z_gzclearerr
# define gzclose z_gzclose
# define gzclose_r z_gzclose_r
# define gzclose_w z_gzclose_w
# define gzdirect z_gzdirect
# define gzdopen z_gzdopen
# define gzeof z_gzeof
# define gzerror z_gzerror
# define gzflush z_gzflush
# define gzgetc z_gzgetc
# define gzgetc_ z_gzgetc_
# define gzgets z_gzgets
# define gzoffset z_gzoffset
# define gzoffset64 z_gzoffset64
# define gzopen z_gzopen
# define gzopen64 z_gzopen64
# ifdef _WIN32
# define gzopen_w z_gzopen_w
# endif
# define gzprintf z_gzprintf
# define gzvprintf z_gzvprintf
# define gzputc z_gzputc
# define gzputs z_gzputs
# define gzread z_gzread
# define gzrewind z_gzrewind
# define gzseek z_gzseek
# define gzseek64 z_gzseek64
# define gzsetparams z_gzsetparams
# define gztell z_gztell
# define gztell64 z_gztell64
# define gzungetc z_gzungetc
# define gzwrite z_gzwrite
# endif
# define inflate z_inflate
# define inflateBack z_inflateBack
# define inflateBackEnd z_inflateBackEnd
# define inflateBackInit_ z_inflateBackInit_
# define inflateCopy z_inflateCopy
# define inflateEnd z_inflateEnd
# define inflateGetHeader z_inflateGetHeader
# define inflateInit2_ z_inflateInit2_
# define inflateInit_ z_inflateInit_
# define inflateMark z_inflateMark
# define inflatePrime z_inflatePrime
# define inflateReset z_inflateReset
# define inflateReset2 z_inflateReset2
# define inflateSetDictionary z_inflateSetDictionary
# define inflateGetDictionary z_inflateGetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateUndermine z_inflateUndermine
# define inflateResetKeep z_inflateResetKeep
# define inflate_copyright z_inflate_copyright
# define inflate_fast z_inflate_fast
# define inflate_table z_inflate_table
# ifndef Z_SOLO
# define uncompress z_uncompress
# endif
# define zError z_zError
# ifndef Z_SOLO
# define zcalloc z_zcalloc
# define zcfree z_zcfree
# endif
# define zlibCompileFlags z_zlibCompileFlags
# define zlibVersion z_zlibVersion
/* all zlib typedefs in zlib.h and zconf.h */
# define Byte z_Byte
# define Bytef z_Bytef
# define alloc_func z_alloc_func
# define charf z_charf
# define free_func z_free_func
# ifndef Z_SOLO
# define gzFile z_gzFile
# endif
# define gz_header z_gz_header
# define gz_headerp z_gz_headerp
# define in_func z_in_func
# define intf z_intf
# define out_func z_out_func
# define uInt z_uInt
# define uIntf z_uIntf
# define uLong z_uLong
# define uLongf z_uLongf
# define voidp z_voidp
# define voidpc z_voidpc
# define voidpf z_voidpf
/* all zlib structs in zlib.h and zconf.h */
# define gz_header_s z_gz_header_s
# define internal_state z_internal_state
#endif
#if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS
#endif
#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
# define OS2
#endif
#if defined(_WINDOWS) && !defined(WINDOWS)
# define WINDOWS
#endif
#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
# ifndef WIN32
# define WIN32
# endif
#endif
#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
# ifndef SYS16BIT
# define SYS16BIT
# endif
# endif
#endif
/*
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
* than 64k bytes at a time (needed on systems with 16-bit int).
*/
#ifdef SYS16BIT
# define MAXSEG_64K
#endif
#ifdef MSDOS
# define UNALIGNED_OK
#endif
#ifdef __STDC_VERSION__
# ifndef STDC
# define STDC
# endif
# if __STDC_VERSION__ >= 199901L
# ifndef STDC99
# define STDC99
# endif
# endif
#endif
#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
# define STDC
#endif
#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
# define STDC
#endif
#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
# define STDC
#endif
#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
# define STDC
#endif
#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
# define STDC
#endif
#ifndef STDC
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
# define const /* note: need a more gentle solution here */
# endif
#endif
#if defined(ZLIB_CONST) && !defined(z_const)
# define z_const const
#else
# define z_const
#endif
/* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
# define NO_DUMMY_DECL
#endif
/* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL
# ifdef MAXSEG_64K
# define MAX_MEM_LEVEL 8
# else
# define MAX_MEM_LEVEL 9
# endif
#endif
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
* created by gzip. (Files created by minigzip can still be extracted by
* gzip.)
*/
#ifndef MAX_WBITS
# define MAX_WBITS 15 /* 32K LZ77 window */
#endif
/* The memory requirements for deflate are (in bytes):
(1 << (windowBits+2)) + (1 << (memLevel+9))
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
plus a few kilobytes for small objects. For example, if you want to reduce
the default memory requirements from 256K to 128K, compile with
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
Of course this will generally degrade compression (there's no free lunch).
The memory requirements for inflate are (in bytes) 1 << windowBits
that is, 32K for windowBits=15 (default value) plus a few kilobytes
for small objects.
*/
/* Type declarations */
#ifndef OF /* function prototypes */
# ifdef STDC
# define OF(args) args
# else
# define OF(args) ()
# endif
#endif
#ifndef Z_ARG /* function prototypes for stdarg */
# if defined(STDC) || defined(Z_HAVE_STDARG_H)
# define Z_ARG(args) args
# else
# define Z_ARG(args) ()
# endif
#endif
/* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations).
* This was tested only with MSC; for other MSDOS compilers you may have
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
* just define FAR to be empty.
*/
#ifdef SYS16BIT
# if defined(M_I86SM) || defined(M_I86MM)
/* MSC small or medium model */
# define SMALL_MEDIUM
# ifdef _MSC_VER
# define FAR _far
# else
# define FAR far
# endif
# endif
# if (defined(__SMALL__) || defined(__MEDIUM__))
/* Turbo C small or medium model */
# define SMALL_MEDIUM
# ifdef __BORLANDC__
# define FAR _far
# else
# define FAR far
# endif
# endif
#endif
#if defined(WINDOWS) || defined(WIN32)
/* If building or using zlib as a DLL, define ZLIB_DLL.
* This is not mandatory, but it offers a little performance increase.
*/
# ifdef ZLIB_DLL
# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
# ifdef ZLIB_INTERNAL
# define ZEXTERN extern __declspec(dllexport)
# else
# define ZEXTERN extern __declspec(dllimport)
# endif
# endif
# endif /* ZLIB_DLL */
/* If building or using zlib with the WINAPI/WINAPIV calling convention,
* define ZLIB_WINAPI.
* Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
*/
# ifdef ZLIB_WINAPI
# ifdef FAR
# undef FAR
# endif
# include <windows.h>
/* No need for _export, use ZLIB.DEF instead. */
/* For complete Windows compatibility, use WINAPI, not __stdcall. */
# define ZEXPORT WINAPI
# ifdef WIN32
# define ZEXPORTVA WINAPIV
# else
# define ZEXPORTVA FAR CDECL
# endif
# endif
#endif
#if defined (__BEOS__)
# ifdef ZLIB_DLL
# ifdef ZLIB_INTERNAL
# define ZEXPORT __declspec(dllexport)
# define ZEXPORTVA __declspec(dllexport)
# else
# define ZEXPORT __declspec(dllimport)
# define ZEXPORTVA __declspec(dllimport)
# endif
# endif
#endif
#ifndef ZEXTERN
# define ZEXTERN extern
#endif
#ifndef ZEXPORT
# define ZEXPORT
#endif
#ifndef ZEXPORTVA
# define ZEXPORTVA
#endif
#ifndef FAR
# define FAR
#endif
#if !defined(__MACTYPES__)
typedef unsigned char Byte; /* 8 bits */
#endif
typedef unsigned int uInt; /* 16 bits or more */
typedef unsigned long uLong; /* 32 bits or more */
#ifdef SMALL_MEDIUM
/* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
# define Bytef Byte FAR
#else
typedef Byte FAR Bytef;
#endif
typedef char FAR charf;
typedef int FAR intf;
typedef uInt FAR uIntf;
typedef uLong FAR uLongf;
#ifdef STDC
typedef void const *voidpc;
typedef void FAR *voidpf;
typedef void *voidp;
#else
typedef Byte const *voidpc;
typedef Byte FAR *voidpf;
typedef Byte *voidp;
#endif
#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
# include <limits.h>
# if (UINT_MAX == 0xffffffffUL)
# define Z_U4 unsigned
# elif (ULONG_MAX == 0xffffffffUL)
# define Z_U4 unsigned long
# elif (USHRT_MAX == 0xffffffffUL)
# define Z_U4 unsigned short
# endif
#endif
#ifdef Z_U4
typedef Z_U4 z_crc_t;
#else
typedef unsigned long z_crc_t;
#endif
#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
# define Z_HAVE_UNISTD_H
#endif
#ifdef HAVE_STDARG_H /* may be set to #if 1 by ./configure */
# define Z_HAVE_STDARG_H
#endif
#ifdef STDC
# ifndef Z_SOLO
# include <sys/types.h> /* for off_t */
# endif
#endif
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
# ifndef Z_SOLO
# include <stdarg.h> /* for va_list */
# endif
#endif
#ifdef _WIN32
# ifndef Z_SOLO
# include <stddef.h> /* for wchar_t */
# endif
#endif
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
* "#define _LARGEFILE64_SOURCE 1" as requesting 64-bit operations, (even
* though the former does not conform to the LFS document), but considering
* both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
* equivalently requesting no 64-bit operations
*/
#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
# undef _LARGEFILE64_SOURCE
#endif
#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
# define Z_HAVE_UNISTD_H
#endif
#ifndef Z_SOLO
# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
# ifdef VMS
# include <unixio.h> /* for off_t */
# endif
# ifndef z_off_t
# define z_off_t off_t
# endif
# endif
#endif
#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
# define Z_LFS64
#endif
#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
# define Z_LARGE64
#endif
#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
# define Z_WANT64
#endif
#if !defined(SEEK_SET) && !defined(Z_SOLO)
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
#endif
#ifndef z_off_t
# define z_off_t long
#endif
#if !defined(_WIN32) && defined(Z_LARGE64)
# define z_off64_t off64_t
#else
# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
# define z_off64_t __int64
# else
# define z_off64_t z_off_t
# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */
#if defined(__MVS__)
#pragma map(deflateInit_,"DEIN")
#pragma map(deflateInit2_,"DEIN2")
#pragma map(deflateEnd,"DEEND")
#pragma map(deflateBound,"DEBND")
#pragma map(inflateInit_,"ININ")
#pragma map(inflateInit2_,"ININ2")
#pragma map(inflateEnd,"INEND")
#pragma map(inflateSync,"INSY")
#pragma map(inflateSetDictionary,"INSEDI")
#pragma map(compressBound,"CMBND")
#pragma map(inflate_table,"INTABL")
#pragma map(inflate_fast,"INFA")
#pragma map(inflate_copyright,"INCOPY")
#endif
#endif /* ZCONF_H */

26
build/wp8/zlib/zlib.sln Normal file
View file

@ -0,0 +1,26 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Express 2012 for Windows Phone
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "zlib", "zlib.vcxproj", "{7AFAC3BB-D97B-4578-B9FE-5E1D2B94EA2F}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM = Debug|ARM
Debug|Win32 = Debug|Win32
Release|ARM = Release|ARM
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{7AFAC3BB-D97B-4578-B9FE-5E1D2B94EA2F}.Debug|ARM.ActiveCfg = Debug|ARM
{7AFAC3BB-D97B-4578-B9FE-5E1D2B94EA2F}.Debug|ARM.Build.0 = Debug|ARM
{7AFAC3BB-D97B-4578-B9FE-5E1D2B94EA2F}.Debug|Win32.ActiveCfg = Debug|Win32
{7AFAC3BB-D97B-4578-B9FE-5E1D2B94EA2F}.Debug|Win32.Build.0 = Debug|Win32
{7AFAC3BB-D97B-4578-B9FE-5E1D2B94EA2F}.Release|ARM.ActiveCfg = Release|ARM
{7AFAC3BB-D97B-4578-B9FE-5E1D2B94EA2F}.Release|ARM.Build.0 = Release|ARM
{7AFAC3BB-D97B-4578-B9FE-5E1D2B94EA2F}.Release|Win32.ActiveCfg = Release|Win32
{7AFAC3BB-D97B-4578-B9FE-5E1D2B94EA2F}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal

135
build/wp8/zlib/zlib.vcxproj Normal file
View file

@ -0,0 +1,135 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|ARM">
<Configuration>Debug</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|ARM">
<Configuration>Release</Configuration>
<Platform>ARM</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{7afac3bb-d97b-4578-b9fe-5e1d2b94ea2f}</ProjectGuid>
<RootNamespace>zlib</RootNamespace>
<DefaultLanguage>en-US</DefaultLanguage>
<MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v110_wp80</PlatformToolset>
<IgnoreImportLibrary>false</IgnoreImportLibrary>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<WholeProgramOptimization>true</WholeProgramOptimization>
<PlatformToolset>v110_wp80</PlatformToolset>
<IgnoreImportLibrary>false</IgnoreImportLibrary>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="PropertySheets">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup>
<OutDir>$(SolutionDir)$(Platform)\$(Configuration)\</OutDir>
<IntDir>$(SolutionDir)$(Platform)\$(Configuration)\$(TargetName)\</IntDir>
</PropertyGroup>
<PropertyGroup>
<GenerateManifest>false</GenerateManifest>
</PropertyGroup>
<ItemDefinitionGroup>
<ClCompile>
<WarningLevel>Level4</WarningLevel>
<AdditionalIncludeDirectories>$(ProjectDir);$(ProjectDir)..\..\..\..\zlib;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_WIN32;_WINDLL;_USRDLL;_CRT_SECURE_NO_WARNINGS;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<BasicRuntimeChecks>Default</BasicRuntimeChecks>
<PrecompiledHeader>NotUsing</PrecompiledHeader>
<CompileAsWinRT>false</CompileAsWinRT>
<AdditionalUsingDirectories>$(WindowsSDK_MetadataPath);$(AdditionalUsingDirectories)</AdditionalUsingDirectories>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<IgnoreAllDefaultLibraries>false</IgnoreAllDefaultLibraries>
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
<ImportLibrary>$(TargetDir)$(TargetName).lib</ImportLibrary>
<AdditionalDependencies>Ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
<ModuleDefinitionFile>$(ProjectDir)..\..\..\..\zlib\win32\zlib.def</ModuleDefinitionFile>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
<ClCompile>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
<ClCompile>
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<Optimization>MaxSpeed</Optimization>
<StringPooling>true</StringPooling>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
</ClCompile>
<Link>
<GenerateDebugInformation>false</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<Reference Include="Windows">
<IsWinMDFile>true</IsWinMDFile>
</Reference>
<Reference Include="platform.winmd">
<IsWinMDFile>true</IsWinMDFile>
<Private>false</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\..\..\zlib\crc32.h" />
<ClInclude Include="..\..\..\..\zlib\deflate.h" />
<ClInclude Include="..\..\..\..\zlib\gzguts.h" />
<ClInclude Include="..\..\..\..\zlib\inffast.h" />
<ClInclude Include="..\..\..\..\zlib\inffixed.h" />
<ClInclude Include="..\..\..\..\zlib\inflate.h" />
<ClInclude Include="..\..\..\..\zlib\inftrees.h" />
<ClInclude Include="..\..\..\..\zlib\trees.h" />
<ClInclude Include="..\..\..\..\zlib\zlib.h" />
<ClInclude Include="..\..\..\..\zlib\zutil.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\..\..\zlib\adler32.c" />
<ClCompile Include="..\..\..\..\zlib\compress.c" />
<ClCompile Include="..\..\..\..\zlib\crc32.c" />
<ClCompile Include="..\..\..\..\zlib\deflate.c" />
<ClCompile Include="..\..\..\..\zlib\gzclose.c" />
<ClCompile Include="..\..\..\..\zlib\gzlib.c" />
<ClCompile Include="..\..\..\..\zlib\gzread.c" />
<ClCompile Include="..\..\..\..\zlib\gzwrite.c" />
<ClCompile Include="..\..\..\..\zlib\infback.c" />
<ClCompile Include="..\..\..\..\zlib\inffast.c" />
<ClCompile Include="..\..\..\..\zlib\inflate.c" />
<ClCompile Include="..\..\..\..\zlib\inftrees.c" />
<ClCompile Include="..\..\..\..\zlib\trees.c" />
<ClCompile Include="..\..\..\..\zlib\uncompr.c" />
<ClCompile Include="..\..\..\..\zlib\zutil.c" />
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\..\..\zlib\win32\zlib1.rc" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\WindowsPhone\v$(TargetPlatformVersion)\Microsoft.Cpp.WindowsPhone.$(TargetPlatformVersion).targets" />
</Project>

View file

@ -36,7 +36,7 @@ m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],)
AC_SUBST([docdir], [${datadir}/doc])
AC_CONFIG_HEADERS(config.h)
AC_CONFIG_MACRO_DIR([m4])
dnl don't put anythingelse before AC_PROG_CC unless checking if macro still work for clang
dnl do not put anythingelse before AC_PROG_CC unless checking if macro still work for clang
AC_PROG_CXX(["xcrun clang++" g++])
AC_PROG_CC(["xcrun clang" gcc])
@ -135,7 +135,7 @@ AC_DEFINE_UNQUOTED(LINPHONE_ALL_LANGS, "$ALL_LINGUAS", [All supported languages]
if test "$mingw_found" != "yes" ; then
dnl gettext macro does not work properly under mingw. And we want to use the one provided by GTK.
dnl AM_GNU_GETTEXT pollutes CPPFLAGS: workaround this.
CPPFLAGS_save=$CPPFLAGS
AM_GNU_GETTEXT([external])
@ -185,29 +185,29 @@ if test "$enable_ldap" = "true"; then
[AC_MSG_ERROR([You need libldap for LDAP support])]
)
AC_CHECK_HEADERS(ldap.h, [foo=bar], [AC_MSG_ERROR( [ldap.h not found] ) ] )
found_ldap=yes
found_ldap=yes
fi
PKG_CHECK_MODULES(SASL, [libsasl2],[found_sasl=yes],[found_sasl=no] )
if test "$found_sasl" = "no"; then
AC_CHECK_LIB(sasl2, sasl_client_init , [SASL_LIBS="-lsasl2"],
[AC_MSG_ERROR([You need SASL for LDAP support] ) ]
)
AC_CHECK_HEADERS(sasl/sasl.h,foo=bar, [AC_MSG_ERROR([sasl/sasl.h not found])])
found_sasl=yes
found_sasl=yes
fi
AC_SUBST(LDAP_CFLAGS)
AC_SUBST(LDAP_LIBS)
AC_SUBST(SASL_CFLAGS)
AC_SUBST(SASL_LIBS)
if test "$found_ldap$found_sasl" = "yesyes"; then
AC_DEFINE(BUILD_LDAP,1,[Defined if LDAP build option enabled])
else
AC_MSG_ERROR([Can't use LDAP due to previous errors])
AC_MSG_ERROR([Cannot use LDAP due to previous errors])
fi
fi
@ -248,7 +248,7 @@ AC_ARG_ENABLE(upnp,
)
if test "$build_upnp" != "false" ; then
PKG_CHECK_MODULES([LIBUPNP], [libupnp],
PKG_CHECK_MODULES([LIBUPNP], [libupnp],
[if pkg-config --atleast-version=1.6 "libupnp < 1.7"; then
build_upnp=true
else
@ -277,7 +277,7 @@ fi
AM_CONDITIONAL(BUILD_TOOLS, test x$build_tools != xfalse)
if test "$build_tools" != "false" ; then
build_tools=true
AC_DEFINE(BUILD_TOOLS, 1, [Define if tools enabled] )
AC_DEFINE(BUILD_TOOLS, 1, [Define if tools enabled] )
fi
dnl conditionnal build of gtk interface.
@ -553,10 +553,10 @@ AC_ARG_WITH(ffmpeg,
)
if test "$video" = "true"; then
if test "$enable_x11" = "true"; then
AC_CHECK_HEADERS(X11/Xlib.h)
if test "$build_macos" = "yes"; then
if test "$build_macos" = "yes"; then
X11_LIBS="-L/usr/X11/lib -lX11"
else
AC_CHECK_LIB(X11,XUnmapWindow, X11_LIBS="-lX11")
@ -644,7 +644,7 @@ AC_SUBST(LIBSOUP_LIBS)
AM_CONDITIONAL(BUILD_WIZARD, test x$build_wizard != xfalse)
if test "$build_wizard" != "false" ; then
build_wizard=true
AC_DEFINE(BUILD_WIZARD, 1, [Define if wizard enabled] )
AC_DEFINE(BUILD_WIZARD, 1, [Define if wizard enabled] )
fi
AC_CHECK_HEADERS(libudev.h)
@ -656,27 +656,42 @@ AC_CHECK_LIB(udev,udev_new)
AC_ARG_ENABLE(strict,
AC_HELP_STRING([--enable-strict], [Build with stricter options (gcc only) @<:@yes@:>@]),
AC_HELP_STRING([--enable-strict], [Build with stricter options @<:@yes@:>@]),
[strictness="${enableval}"],
[strictness=yes]
)
STRICT_OPTIONS="-Wall"
STRICT_OPTIONS="-Wall -Wuninitialized"
STRICT_OPTIONS_CC="-Wdeclaration-after-statement "
STRICT_OPTIONS_CXX=""
#for clang
case $CC in
case $CC in
*clang*)
STRICT_OPTIONS="$STRICT_OPTIONS -Qunused-arguments"
STRICT_OPTIONS="$STRICT_OPTIONS -Qunused-arguments "
#disabled due to wrong optimization false positive with small string
#(cf. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=35903)
STRICT_OPTIONS="$STRICT_OPTIONS -Wno-array-bounds "
;;
esac
# because Darwin's gcc is actually clang, we need to check it...
case "$target_os" in
*darwin*)
STRICT_OPTIONS="$STRICT_OPTIONS -Wno-error=unknown-warning-option -Qunused-arguments -Wno-tautological-compare -Wno-unused-function "
#disabled due to wrong optimization false positive with small string
#(cf. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=35903)
STRICT_OPTIONS="$STRICT_OPTIONS -Wno-array-bounds "
;;
esac
if test "$strictness" = "yes" ; then
STRICT_OPTIONS="$STRICT_OPTIONS -Werror"
CFLAGS="$CFLAGS -fno-strict-aliasing"
fi
AC_SUBST(STRICT_OPTIONS)
AC_SUBST(STRICT_OPTIONS_CC)
AC_SUBST(STRICT_OPTIONS_CXX)
top_srcdir=`dirname $0`
@ -783,13 +798,13 @@ if test x$enable_msg_storage != xfalse; then
fi
enable_msg_storage=false
fi
AC_SUBST(SQLITE3_CFLAGS)
AC_SUBST(SQLITE3_LIBS)
fi
PKG_CHECK_MODULES(BELLESIP, [belle-sip >= 1.3.1])
SIPSTACK_CFLAGS="$BELLESIP_CFLAGS"
@ -883,11 +898,11 @@ dnl ##################################################
dnl # Check for doxygen
dnl ##################################################
AC_PATH_PROG(DOXYGEN,doxygen,false)
AM_CONDITIONAL(HAVE_DOXYGEN, test $DOXYGEN != false)
AC_CHECK_PROG(DOXYGEN,doxygen,doxygen,false)
AM_CONDITIONAL(HAVE_DOXYGEN, test "$DOXYGEN" != "false")
AC_CONFIG_FILES([
AC_CONFIG_FILES([
Makefile
build/Makefile
build/macos/Makefile

View file

@ -3,12 +3,13 @@
AM_CPPFLAGS=\
-I$(top_srcdir) \
-I$(top_srcdir)/coreapi \
-I$(top_srcdir)/include
-I$(top_srcdir)/include
COMMON_CFLAGS=\
-DIN_LINPHONE \
-D_ORTP_SOURCE \
$(STRICT_OPTIONS) \
$(STRICT_OPTIONS_CC) \
$(ORTP_CFLAGS) \
$(MEDIASTREAMER_CFLAGS) \
$(VIDEO_CFLAGS) \

View file

@ -603,6 +603,7 @@ lpc_cmd_chat(LinphoneCore *lc, char *args)
char *arg1 = args;
char *arg2 = NULL;
char *ptr = args;
LinphoneChatRoom *cr;
if (!args) return 0;
@ -619,7 +620,7 @@ lpc_cmd_chat(LinphoneCore *lc, char *args)
/* missing one parameter */
return 0;
}
LinphoneChatRoom *cr = linphone_core_create_chat_room(lc,arg1);
cr = linphone_core_create_chat_room(lc,arg1);
linphone_chat_room_send_message(cr,arg2);
return 1;
}
@ -1600,7 +1601,7 @@ linphonec_proxy_add(LinphoneCore *lc)
*/
if ( enable_register==TRUE )
{
long int expires=0;
int expires=0;
while (1)
{
char *input=linphonec_readline("Specify register expiration time"
@ -1612,13 +1613,8 @@ linphonec_proxy_add(LinphoneCore *lc)
return;
}
expires=strtol(input, (char **)NULL, 10);
if ( expires == LONG_MIN || expires == LONG_MAX )
{
linphonec_out("Invalid value: %s\n", strerror(errno));
free(input);
continue;
}
expires=atoi(input);
if (expires==0) expires=600;
linphone_proxy_config_set_expires(cfg, expires);
linphonec_out("Expiration: %d seconds\n", linphone_proxy_config_get_expires (cfg));
@ -2441,8 +2437,9 @@ static void lpc_display_call_states(LinphoneCore *lc){
}else{
for(;elem!=NULL;elem=elem->next){
const char *flag;
bool_t in_conference;
call=(LinphoneCall*)elem->data;
bool_t in_conference=linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(call));
in_conference=linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(call));
tmp=linphone_call_get_remote_address_as_string (call);
flag=in_conference ? "conferencing" : "";
flag=linphone_call_has_transfer_pending(call) ? "transfer pending" : flag;

View file

@ -367,8 +367,8 @@ static void linphonec_call_state_changed(LinphoneCore *lc, LinphoneCall *call, L
if ( auto_answer) {
answer_call=TRUE;
} else if (real_early_media_sending) {
linphonec_out("Sending early media using real hardware\n");
LinphoneCallParams* callparams = linphone_core_create_default_call_parameters(lc);
linphonec_out("Sending early media using real hardware\n");
linphone_call_params_enable_early_media_sending(callparams, TRUE);
if (vcap_enabled) linphone_call_params_enable_video(callparams, TRUE);
linphone_core_accept_early_media_with_params(lc, call, callparams);
@ -500,7 +500,6 @@ static void *pipe_thread(void*p){
}
static void start_pipe_reader(void){
ms_mutex_init(&prompt_mutex,NULL);
pipe_reader_run=TRUE;
ortp_thread_create(&pipe_reader_th,NULL,pipe_thread,NULL);
}
@ -536,6 +535,7 @@ char *linphonec_readline(char *prompt){
fprintf(stdout,"%s",prompt);
fflush(stdout);
while(1){
ms_mutex_lock(&prompt_mutex);
if (have_prompt){
char *ret=strdup(received_prompt);
@ -546,15 +546,17 @@ char *linphonec_readline(char *prompt){
ms_mutex_unlock(&prompt_mutex);
linphonec_idle_call();
#ifdef WIN32
Sleep(20);
/* Following is to get the video window going as it
should. Maybe should we only have this on when the option -V
or -D is on? */
MSG msg;
{
MSG msg;
Sleep(20);
/* Following is to get the video window going as it
should. Maybe should we only have this on when the option -V
or -D is on? */
if (PeekMessage(&msg, NULL, 0, 0,1)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
if (PeekMessage(&msg, NULL, 0, 0,1)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
#else
usleep(20000);
@ -802,6 +804,7 @@ linphonec_finish(int exit_status)
if (mylogfile != NULL && mylogfile != stdout)
{
fclose (mylogfile);
mylogfile=stdout;
}
printf("\n");
exit(exit_status);
@ -828,12 +831,13 @@ linphonec_prompt_for_auth_final(LinphoneCore *lc)
#ifdef HAVE_READLINE
rl_hook_func_t *old_event_hook;
#endif
LinphoneAuthInfo *pending_auth;
if (reentrancy!=0) return 0;
reentrancy++;
LinphoneAuthInfo *pending_auth=auth_stack.elem[auth_stack.nitems-1];
pending_auth=auth_stack.elem[auth_stack.nitems-1];
snprintf(auth_prompt, 256, "Password for %s on %s: ",
pending_auth->username, pending_auth->realm);

View file

@ -177,12 +177,14 @@ static void spawn_linphonec(int argc, char *argv[]){
static void spawn_linphonec(int argc, char *argv[]){
PROCESS_INFORMATION pinfo;
STARTUPINFO si;
BOOL ret;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pinfo, sizeof(pinfo) );
BOOL ret=CreateProcess(NULL,"linphoned.exe --pipe -c NUL",
ret=CreateProcess(NULL,"linphoned.exe --pipe -c NUL",
NULL,
NULL,
FALSE,

View file

@ -42,6 +42,8 @@ set(SOURCE_FILES
bellesip_sal/sal_op_registration.c
bellesip_sal/sal_sdp.c
callbacks.c
call_log.c
call_params.c
chat.c
conference.c
ec-calibrator.c
@ -51,13 +53,13 @@ set(SOURCE_FILES
info.c
linphonecall.c
linphonecore.c
linphone_tunnel_stubs.c
linphone_tunnel_config.c
lpconfig.c
lsd.c
message_storage.c
misc.c
offeranswer.c
player.c
presence.c
proxy.c
quality_reporting.c
@ -86,6 +88,8 @@ if(ENABLE_TUNNEL)
TunnelManager.cc
)
add_definitions(-DTUNNEL_ENABLED)
else()
list(APPEND SOURCE_FILES linphone_tunnel_stubs.c)
endif()
set(GENERATED_SOURCE_FILES
@ -113,6 +117,12 @@ set(LIBS
${MS2_LIBRARIES}
${XML2_LIBRARIES}
)
if(ENABLE_TUNNEL)
list(APPEND LIBS ${TUNNEL_LIBRARIES})
endif()
if(WIN32)
list(APPEND LIBS shlwapi)
endif()
if(ENABLE_STATIC)
add_library(linphone STATIC ${SOURCE_FILES} ${GENERATED_SOURCE_FILES})
@ -139,7 +149,20 @@ install(TARGETS linphone
)
file(GLOB HEADER_FILES "*.h")
set(HEADER_FILES
call_log.h
call_params.h
event.h
linphonecore.h
linphonecore_utils.h
linphonefriend.h
linphonepresence.h
linphone_tunnel.h
lpc2xml.h
lpconfig.h
sipsetup.h
xml2lpc.h
)
install(FILES ${HEADER_FILES}
DESTINATION include/linphone

View file

@ -6,10 +6,10 @@ GIT_TAG=`cd $(top_srcdir) && git describe --abbrev=0`
GITREVISION=`cd $(top_srcdir) && git rev-parse HEAD`
## This command is used to check if the sources are cloned in a git repo.
## We can't only depend on the presence of the .git/ directory anymore,
## We can't only depend on the presence of the .git/ directory anymore,
## because of gits submodule handling.
## We now simply issue a git log on configure.ac and if the output is empty (error or file not tracked), then we are not in git.
GITLOG=$(shell git log -1 $(top_srcdir)/configure.ac)
GITLOG=$(shell git log -1 --pretty=format:%H $(top_srcdir)/configure.ac)
ECHO=/bin/echo
@ -24,7 +24,7 @@ CLEANFILES=$(GITVERSION_FILE)
## Process this file with automake to produce Makefile.in
linphone_includedir=$(includedir)/linphone
linphone_include_HEADERS=linphonecore.h linphonefriend.h linphonepresence.h linphonecore_utils.h lpconfig.h sipsetup.h event.h xml2lpc.h lpc2xml.h linphone_tunnel.h
linphone_include_HEADERS=linphonecore.h linphonefriend.h linphonepresence.h linphonecore_utils.h lpconfig.h sipsetup.h event.h xml2lpc.h lpc2xml.h linphone_tunnel.h call_log.h call_params.h
lib_LTLIBRARIES=liblinphone.la
@ -59,12 +59,16 @@ liblinphone_la_SOURCES=\
lpc2xml.c \
remote_provisioning.c \
quality_reporting.c quality_reporting.h\
call_log.c \
call_params.c \
player.c \
fileplayer.c \
$(GITVERSION_FILE)
if BUILD_UPNP
liblinphone_la_SOURCES+=upnp.c upnp.h
endif
liblinphone_la_SOURCES+= bellesip_sal/sal_address_impl.c \
bellesip_sal/sal_impl.c bellesip_sal/sal_impl.h \
bellesip_sal/sal_op_impl.c \
@ -79,7 +83,7 @@ liblinphone_la_SOURCES+= bellesip_sal/sal_address_impl.c \
bellesip_sal/sal_op_events.c
if BUILD_WIZARD
liblinphone_la_SOURCES+=sipwizard.c
liblinphone_la_SOURCES+=sipwizard.c
endif
liblinphone_la_SOURCES+=linphone_tunnel_config.c
@ -138,8 +142,9 @@ endif
AM_CPPFLAGS=\
-I$(top_srcdir) -I$(top_srcdir)/include -I$(builddir)
AM_CFLAGS=\
$(STRICT_OPTIONS) -DIN_LINPHONE \
COMMON_CFLAGS=\
$(STRICT_OPTIONS) \
-DIN_LINPHONE \
$(ORTP_CFLAGS) \
$(MEDIASTREAMER_CFLAGS) \
$(SIPSTACK_CFLAGS) \
@ -155,15 +160,16 @@ AM_CFLAGS=\
$(LDAP_CFLAGS) $(SASL_CFLAGS)
if BUILD_WIZARD
AM_CFLAGS+= -DBUILD_WIZARD
COMMON_CFLAGS+= -DBUILD_WIZARD
endif
AM_CFLAGS+= -DUSE_BELLESIP
COMMON_CFLAGS+= -DUSE_BELLESIP
AM_CXXFLAGS=$(AM_CFLAGS)
AM_CFLAGS=$(COMMON_CFLAGS) $(STRICT_OPTIONS_CC)
AM_CXXFLAGS=$(COMMON_CFLAGS) $(STRICT_OPTIONS_CXX)
#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
#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:

View file

@ -1,7 +1,7 @@
/*
* C Implementation: tunnel
*
* Description:
* Description:
*
*
* Author: Simon Morlat <simon.morlat@linphone.org>, (C) 2009
@ -19,18 +19,17 @@
#ifndef USE_BELLESIP
#include "eXosip2/eXosip_transport_hook.h"
#endif
#include "tunnel/udp_mirror.hh"
#include "private.h"
#ifdef ANDROID
#include <android/log.h>
#endif
belledonnecomm::TunnelManager *bcTunnel(const LinphoneTunnel *tunnel);
using namespace belledonnecomm;
using namespace ::std;
void TunnelManager::addServer(const char *ip, int port,unsigned int udpMirrorPort,unsigned int delay) {
if (ip == NULL) {
ip = "";
@ -53,7 +52,6 @@ void TunnelManager::cleanServers() {
mServerAddrs.clear();
UdpMirrorClientList::iterator it;
mAutoDetectStarted=false;
for (it = mUdpMirrorClients.begin(); it != mUdpMirrorClients.end();) {
UdpMirrorClient& s=*it++;
s.stop();
@ -67,11 +65,6 @@ void TunnelManager::reconnect(){
mTunnelClient->reconnect();
}
void TunnelManager::setCallback(StateCallback cb, void *userdata) {
mCallback=cb;
mCallbackData=userdata;
}
static void sCloseRtpTransport(RtpTransport *t, void *userData){
TunnelSocket *s=(TunnelSocket*)userData;
TunnelManager *manager=(TunnelManager*)s->getUserPointer();
@ -79,13 +72,16 @@ static void sCloseRtpTransport(RtpTransport *t, void *userData){
}
void TunnelManager::closeRtpTransport(RtpTransport *t, TunnelSocket *s){
mTunnelClient->closeSocket(s);
ms_free(t);
}
static RtpTransport *sCreateRtpTransport(void* userData, int port){
return ((TunnelManager *) userData)->createRtpTransport(port);
}
void sDestroyRtpTransport(RtpTransport *t){
ms_free(t);
}
RtpTransport *TunnelManager::createRtpTransport(int port){
TunnelSocket *socket=mTunnelClient->createSocket(port);
socket->setUserPointer(this);
@ -94,14 +90,16 @@ RtpTransport *TunnelManager::createRtpTransport(int port){
t->t_recvfrom=customRecvfrom;
t->t_sendto=customSendto;
t->t_close=sCloseRtpTransport;
t->t_destroy=sDestroyRtpTransport;
t->data=socket;
return t;
}
void TunnelManager::start() {
if (!mTunnelClient) {
void TunnelManager::startClient() {
ms_message("TunnelManager: Starting tunnel client");
if (mTunnelClient == NULL) {
mTunnelClient = new TunnelClient();
mTunnelClient->setCallback((StateCallback)tunnelCallback,this);
mTunnelClient->setCallback((TunnelClientController::StateCallback)tunnelCallback,this);
list<ServerAddr>::iterator it;
for(it=mServerAddrs.begin();it!=mServerAddrs.end();++it){
const ServerAddr &addr=*it;
@ -110,14 +108,25 @@ void TunnelManager::start() {
mTunnelClient->setHttpProxy(mHttpProxyHost.c_str(), mHttpProxyPort, mHttpUserName.c_str(), mHttpPasswd.c_str());
}
mTunnelClient->start();
linphone_core_set_rtp_transport_factories(mCore,&mTransportFactories);
if(mTunnelizeSipPackets) {
sal_enable_tunnel(mCore->sal, mTunnelClient);
}
mConnecting = true;
}
bool TunnelManager::isStarted() {
return mTunnelClient != 0 && mTunnelClient->isStarted();
void TunnelManager::stopClient(){
ms_message("TunnelManager: Stopping tunnel client");
linphone_core_set_rtp_transport_factories(mCore,NULL);
sal_disable_tunnel(mCore->sal);
if (mTunnelClient){
delete mTunnelClient;
mTunnelClient=NULL;
}
}
bool TunnelManager::isReady() const {
return mTunnelClient && mTunnelClient->isReady() && mReady;
bool TunnelManager::isConnected() const {
return mTunnelClient != NULL && mTunnelClient->isReady();
}
int TunnelManager::customSendto(struct _RtpTransport *t, mblk_t *msg , int flags, const struct sockaddr *to, socklen_t tolen){
@ -135,15 +144,21 @@ int TunnelManager::customRecvfrom(struct _RtpTransport *t, mblk_t *msg, int flag
}
TunnelManager::TunnelManager(LinphoneCore* lc) :TunnelClientController()
,mCore(lc)
,mCallback(NULL)
,mEnabled(false)
,mTunnelClient(NULL)
,mAutoDetectStarted(false)
,mReady(false)
,mHttpProxyPort(0){
TunnelManager::TunnelManager(LinphoneCore* lc) :
mCore(lc),
#ifndef USE_BELLESIP
mSipSocket(NULL),
mExosipTransport(NULL),
#endif
mMode(LinphoneTunnelModeDisable),
mAutoDetecting(false),
mConnecting(false),
mScheduledRegistration(false),
mTunnelizeSipPackets(true),
mTunnelClient(NULL),
mHttpProxyPort(0),
mVTable(NULL)
{
linphone_core_add_iterate_hook(mCore,(LinphoneCoreIterateHook)sOnIterate,this);
mTransportFactories.audio_rtcp_func=sCreateRtpTransport;
mTransportFactories.audio_rtcp_func_data=this;
@ -153,104 +168,71 @@ TunnelManager::TunnelManager(LinphoneCore* lc) :TunnelClientController()
mTransportFactories.video_rtcp_func_data=this;
mTransportFactories.video_rtp_func=sCreateRtpTransport;
mTransportFactories.video_rtp_func_data=this;
mVTable = linphone_vtable_new();
mVTable->network_reachable = networkReachableCb;
linphone_core_add_listener(mCore, mVTable);
}
TunnelManager::~TunnelManager(){
for(UdpMirrorClientList::iterator udpMirror = mUdpMirrorClients.begin(); udpMirror != mUdpMirrorClients.end(); udpMirror++) {
udpMirror->stop();
}
stopClient();
linphone_core_remove_listener(mCore, mVTable);
linphone_vtable_destroy(mVTable);
}
void TunnelManager::stopClient(){
sal_disable_tunnel(mCore->sal);
if (mTunnelClient){
delete mTunnelClient;
mTunnelClient=NULL;
void TunnelManager::doRegistration(){
if(mTunnelizeSipPackets) {
LinphoneProxyConfig* lProxy;
linphone_core_get_default_proxy(mCore, &lProxy);
if (lProxy) {
ms_message("TunnelManager: need to register");
if(linphone_proxy_config_get_state(lProxy) != LinphoneRegistrationProgress) {
linphone_proxy_config_refresh_register(lProxy);
mScheduledRegistration = false;
} else {
ms_warning("TunnelManager: register difered. There is already a registration in progress");
mScheduledRegistration = true;
}
} else {
mScheduledRegistration = false;
}
}
}
void TunnelManager::processTunnelEvent(const Event &ev){
LinphoneProxyConfig* lProxy;
linphone_core_get_default_proxy(mCore, &lProxy);
if (mEnabled && mTunnelClient->isReady()){
ms_message("Tunnel is up, registering now");
linphone_core_set_firewall_policy(mCore,LinphonePolicyNoFirewall);
linphone_core_set_rtp_transport_factories(mCore,&mTransportFactories);
sal_enable_tunnel(mCore->sal, mTunnelClient);
//register
if (lProxy) {
linphone_proxy_config_refresh_register(lProxy);
}
mReady=true;
}else if (mEnabled && !mTunnelClient->isReady()){
/* we got disconnected from the tunnel */
mReady=false;
if (ev.mData.mConnected){
ms_message("Tunnel is connected");
doRegistration();
} else {
ms_error("Tunnel has been disconnected");
}
mConnecting = false;
}
void TunnelManager::waitUnRegistration(){
LinphoneProxyConfig* lProxy;
linphone_core_get_default_proxy(mCore, &lProxy);
if (lProxy && linphone_proxy_config_get_state(lProxy)==LinphoneRegistrationOk) {
int i=0;
linphone_proxy_config_edit(lProxy);
linphone_proxy_config_enable_register(lProxy,FALSE);
linphone_proxy_config_done(lProxy);
//make sure unregister is sent and authenticated
do{
linphone_core_iterate(mCore);
ms_usleep(20000);
if (i>100){
ms_message("tunnel: timeout for unregistration expired, giving up");
break;
}
i++;
}while(linphone_proxy_config_get_state(lProxy)!=LinphoneRegistrationCleared);
}
}
void TunnelManager::enable(bool isEnable) {
ms_message("Turning tunnel [%s]",(isEnable?"on":"off"));
if (isEnable && !mEnabled){
mEnabled=true;
//1 save transport and firewall policy
linphone_core_get_sip_transports(mCore, &mRegularTransport);
mPreviousFirewallPolicy=linphone_core_get_firewall_policy(mCore);
//2 unregister
waitUnRegistration();
//3 insert tunnel
start();
}else if (!isEnable && mEnabled){
//1 unregister
waitUnRegistration();
mEnabled=false;
stopClient();
mReady=false;
linphone_core_set_rtp_transport_factories(mCore,NULL);
sal_disable_tunnel(mCore->sal);
// Set empty transports to force the setting of regular transport, otherwise it is not applied
LCSipTransports lTransport;
lTransport.udp_port = 0;
lTransport.tcp_port = 0;
lTransport.tls_port = 0;
lTransport.dtls_port = 0;
linphone_core_set_sip_transports(mCore, &lTransport);
//Restore transport and firewall policy
linphone_core_set_sip_transports(mCore, &mRegularTransport);
linphone_core_set_firewall_policy(mCore, mPreviousFirewallPolicy);
//register
LinphoneProxyConfig* lProxy;
linphone_core_get_default_proxy(mCore, &lProxy);
if (lProxy) {
linphone_proxy_config_edit(lProxy);
linphone_proxy_config_enable_register(lProxy,TRUE);
linphone_proxy_config_done(lProxy);
void TunnelManager::setMode(LinphoneTunnelMode mode) {
if(mMode != mode) {
ms_message("TunnelManager: Switching mode from %s to %s",
tunnel_mode_to_string(mMode),
tunnel_mode_to_string(mode));
switch(mode) {
case LinphoneTunnelModeEnable:
mMode = mode;
startClient();
break;
case LinphoneTunnelModeDisable:
mMode = mode;
stopClient();
doRegistration();
break;
case LinphoneTunnelModeAuto:
mMode = mode;
autoDetect();
break;
default:
ms_error("TunnelManager::setMode(): invalid mode (%d)", mode);
}
}
}
@ -262,6 +244,10 @@ void TunnelManager::tunnelCallback(bool connected, TunnelManager *zis){
}
void TunnelManager::onIterate(){
if(mScheduledRegistration) {
ms_message("Apply difered registration");
doRegistration();
}
mMutex.lock();
while(!mEvq.empty()){
Event ev=mEvq.front();
@ -320,30 +306,30 @@ void TunnelManager::enableLogs(bool isEnabled,LogHandler logHandler) {
SetLogLevel(TUNNEL_ERROR|TUNNEL_WARN);
}
}
bool TunnelManager::isEnabled() {
return mEnabled;
LinphoneTunnelMode TunnelManager::getMode() const {
return mMode;
}
void TunnelManager::processUdpMirrorEvent(const Event &ev){
if (ev.mData.mHaveUdp) {
LOGI("Tunnel is not required, disabling");
enable(false);
mAutoDetectStarted = false;
ms_message("TunnelManager: auto detection test succeed");
stopClient();
doRegistration();
mAutoDetecting = false;
} else {
ms_message("TunnelManager: auto detection test failed");
mCurrentUdpMirrorClient++;
if (mCurrentUdpMirrorClient !=mUdpMirrorClients.end()) {
// enable tunnel but also try backup server
LOGI("Tunnel is required, enabling; Trying backup udp mirror");
ms_message("TunnelManager: trying another udp mirror");
UdpMirrorClient &lUdpMirrorClient=*mCurrentUdpMirrorClient;
lUdpMirrorClient.start(TunnelManager::sUdpMirrorClientCallback,(void*)this);
} else {
LOGI("Tunnel is required, enabling; no backup udp mirror available");
mAutoDetectStarted = false;
ms_message("TunnelManager: all auto detection failed. Need ti enable tunnel");
startClient();
mAutoDetecting = false;
}
enable(true);
}
}
@ -361,21 +347,26 @@ void TunnelManager::sUdpMirrorClientCallback(bool isUdpAvailable, void* data) {
thiz->postEvent(ev);
}
void TunnelManager::networkReachableCb(LinphoneCore *lc, bool_t reachable) {
TunnelManager *tunnel = bcTunnel(linphone_core_get_tunnel(lc));
if(reachable && tunnel->getMode() == LinphoneTunnelModeAuto) {
tunnel->autoDetect();
}
}
void TunnelManager::autoDetect() {
// first check if udp mirrors was provisionned
if (mUdpMirrorClients.empty()) {
LOGE("No UDP mirror server configured aborting auto detection");
if(mAutoDetecting) {
ms_error("TunnelManager: Cannot start auto detection. One auto detection is going on");
return;
}
if (mAutoDetectStarted) {
LOGE("auto detection already in progress, restarting");
(*mCurrentUdpMirrorClient).stop();
if (mUdpMirrorClients.empty()) {
ms_error("TunnelManager: No UDP mirror server configured aborting auto detection");
return;
}
mAutoDetectStarted=true;
mCurrentUdpMirrorClient =mUdpMirrorClients.begin();
mCurrentUdpMirrorClient = mUdpMirrorClients.begin();
UdpMirrorClient &lUdpMirrorClient=*mCurrentUdpMirrorClient;
lUdpMirrorClient.start(TunnelManager::sUdpMirrorClientCallback,(void*)this);
mAutoDetecting = true;
}
void TunnelManager::setHttpProxyAuthInfo(const char* username,const char* passwd) {
@ -384,6 +375,14 @@ void TunnelManager::setHttpProxyAuthInfo(const char* username,const char* passwd
if (mTunnelClient) mTunnelClient->setHttpProxyAuthInfo(username,passwd);
}
void TunnelManager::tunnelizeSipPackets(bool enable){
mTunnelizeSipPackets = enable;
}
bool TunnelManager::tunnelizeSipPacketsEnabled() const {
return mTunnelizeSipPackets;
}
void TunnelManager::setHttpProxy(const char *host,int port, const char *username, const char *passwd){
mHttpUserName=username?username:"";
mHttpPasswd=passwd?passwd:"";
@ -392,6 +391,6 @@ void TunnelManager::setHttpProxy(const char *host,int port, const char *username
if (mTunnelClient) mTunnelClient->setHttpProxy(host, port, username, passwd);
}
LinphoneCore *TunnelManager::getLinphoneCore(){
LinphoneCore *TunnelManager::getLinphoneCore() const{
return mCore;
}

View file

@ -1,7 +1,7 @@
/*
* C Implementation: tunnel
*
* Description:
* Description:
*
*
*
@ -12,35 +12,35 @@
#define __TUNNEL_CLIENT_MANAGER_H__
#include <list>
#include <string>
#include "tunnel/client.hh"
#include <tunnel/client.hh>
#include <tunnel/udp_mirror.hh>
#include "linphonecore.h"
#include "linphone_tunnel.h"
#ifndef USE_BELLESIP
extern "C" {
#include "eXosip2/eXosip_transport_hook.h"
#include <eXosip2/eXosip_transport_hook.h>
}
#endif
namespace belledonnecomm {
class TunnelClient;
class UdpMirrorClient;
/**
* @addtogroup tunnel_client
* @addtogroup tunnel_client
* @{
**/
/**
* The TunnelManager class extends the LinphoneCore functionnality in order to provide an easy to use API to
* The TunnelManager class extends the LinphoneCore functionnality in order to provide an easy to use API to
* - provision tunnel servers ip addresses and ports
* - start/stop the tunneling service
* - be informed of of connection and disconnection events to the tunnel server
* - be informed of connection and disconnection events to the tunnel server
* - perform auto-detection whether tunneling is required, based on a test of sending/receiving a flow of UDP packets.
*
*
* It takes in charge automatically the SIP registration procedure when connecting or disconnecting to a tunnel server.
* No other action on LinphoneCore is required to enable full operation in tunnel mode.
**/
class TunnelManager : public TunnelClientController{
class TunnelManager {
public:
/**
* Add a tunnel server. At least one should be provided to be able to connect.
@ -61,20 +61,8 @@ class UdpMirrorClient;
void addServer(const char *ip, int port,unsigned int udpMirrorPort,unsigned int delay);
/**
* Removes all tunnel server address previously entered with addServer()
**/
void cleanServers();
/**
* Register a state callback to be notified whenever the tunnel client is connected or disconnected to the tunnel server.
* @param cb application callback function to use for notifying of connection/disconnection events.
* @param userdata An opaque pointer passed to the callback, used optionally by the application to retrieve a context.
**/
void setCallback(StateCallback cb, void *userdata);
/**
* Start connecting to a tunnel server.
* At this step, nothing is tunneled yet. The enable() method must be used to state whether SIP and RTP traffic
* need to be tunneled or not.
**/
void start();
void cleanServers();
/**
* Forces reconnection to the tunnel server.
* This method is useful when the device switches from wifi to Edge/3G or vice versa. In most cases the tunnel client socket
@ -83,22 +71,15 @@ class UdpMirrorClient;
**/
void reconnect();
/**
* Sets whether tunneling of SIP and RTP is required.
* @param isEnabled If true enter in tunneled mode, if false exits from tunneled mode.
* The TunnelManager takes care of refreshing SIP registration when switching on or off the tunneled mode.
*
**/
void enable(bool isEnabled);
/**
* In auto detect mode, the tunnel manager try to establish a real time rtp cummunication with the tunnel server on specified port.
*<br>In case of success, the tunnel is automatically turned off. Otherwise, if no udp commmunication is feasible, tunnel mode is turned on.
*<br> Call this method each time to run the auto detection algorithm
* @brief setMode
* @param mode
*/
void autoDetect();
void setMode(LinphoneTunnelMode mode);
/**
* Returns a boolean indicating whether tunneled operation is enabled.
**/
bool isEnabled();
* @brief Return the tunnel mode
* @return #LinphoneTunnelMode
*/
LinphoneTunnelMode getMode() const;
/**
* Enables debug logs of the Tunnel subsystem.
**/
@ -115,24 +96,52 @@ class UdpMirrorClient;
* @param passwd The password.
**/
void setHttpProxyAuthInfo(const char* username,const char* passwd);
~TunnelManager();
void setHttpProxy(const char *host,int port, const char *username, const char *passwd);
/**
* Indicate to the tunnel manager whether SIP packets must pass
* through the tunnel. That featurte is automatically enabled at
* the creation of the TunnelManager instance.
* @param enable If set to TRUE, SIP packets will pass through the tunnel.
* If set to FALSE, SIP packets will pass by the configured proxies.
*/
void tunnelizeSipPackets(bool enable);
/**
* @brief Check whether the tunnel manager is set to tunnelize SIP packets
* @return True, SIP packets pass through the tunnel
*/
bool tunnelizeSipPacketsEnabled() const;
/**
* @brief Constructor
* @param lc The LinphoneCore instance of which the TunnelManager will be associated to.
*/
TunnelManager(LinphoneCore* lc);
/**
* Destroy the given RtpTransport.
* @brief Destructor
*/
void closeRtpTransport(RtpTransport *t, TunnelSocket *s);
~TunnelManager();
/**
* Create an RtpTransport.
* @brief Create an RtpTransport
* @param port
* @return
*/
RtpTransport *createRtpTransport(int port);
/**
* Get associated Linphone Core.
* @brief Destroy the given RtpTransport
* @param t
* @param s
*/
LinphoneCore *getLinphoneCore();
virtual void setHttpProxy(const char *host,int port, const char *username, const char *passwd);
virtual bool isReady() const;
void closeRtpTransport(RtpTransport *t, TunnelSocket *s);
/**
* @brief Get associated Linphone Core
* @return pointer on the associated LinphoneCore
*/
LinphoneCore *getLinphoneCore() const;
/**
* @brief Check wehter the tunnel is connected
* @return True whether the tunnel is connected
*/
bool isConnected() const;
private:
enum EventType{
UdpMirrorClientEvent,
@ -146,8 +155,6 @@ class UdpMirrorClient;
}mData;
};
typedef std::list<UdpMirrorClient> UdpMirrorClientList;
virtual bool isStarted();
void onIterate();
static int customSendto(struct _RtpTransport *t, mblk_t *msg , int flags, const struct sockaddr *to, socklen_t tolen);
static int customRecvfrom(struct _RtpTransport *t, mblk_t *msg, int flags, struct sockaddr *from, socklen_t *fromlen);
static int eXosipSendto(int fd,const void *buf, size_t len, int flags, const struct sockaddr *to, socklen_t tolen,void* userdata);
@ -156,35 +163,41 @@ class UdpMirrorClient;
static void tunnelCallback(bool connected, TunnelManager *zis);
static void sOnIterate(TunnelManager *zis);
static void sUdpMirrorClientCallback(bool result, void* data);
void waitUnRegistration();
static void networkReachableCb(LinphoneCore *lc, bool_t reachable);
private:
void onIterate();
void doRegistration();
void startClient();
void stopClient();
void autoDetect();
void processTunnelEvent(const Event &ev);
void processUdpMirrorEvent(const Event &ev);
void postEvent(const Event &ev);
private:
LinphoneCore* mCore;
LCSipTransports mRegularTransport;
#ifndef USE_BELLESIP
TunnelSocket *mSipSocket;
eXosip_transport_hooks_t mExosipTransport;
#endif
StateCallback mCallback;
void * mCallbackData;
bool mEnabled;
std::queue<Event> mEvq;
std::list <ServerAddr> mServerAddrs;
UdpMirrorClientList mUdpMirrorClients;
UdpMirrorClientList::iterator mCurrentUdpMirrorClient;
LinphoneTunnelMode mMode;
bool mAutoDetecting;
bool mConnecting;
bool mScheduledRegistration;
bool mTunnelizeSipPackets;
TunnelClient* mTunnelClient;
void stopClient();
Mutex mMutex;
static Mutex sMutex;
bool mAutoDetectStarted;
bool mReady;
LinphoneRtpTransportFactories mTransportFactories;
std::string mHttpUserName;
std::string mHttpPasswd;
std::string mHttpProxyHost;
int mHttpProxyPort;
LinphoneFirewallPolicy mPreviousFirewallPolicy;
LinphoneCoreVTable *mVTable;
std::list <ServerAddr> mServerAddrs;
UdpMirrorClientList mUdpMirrorClients;
UdpMirrorClientList::iterator mCurrentUdpMirrorClient;
LinphoneRtpTransportFactories mTransportFactories;
Mutex mMutex;
std::queue<Event> mEvq;
#ifndef USE_BELLESIP
TunnelSocket *mSipSocket;
eXosip_transport_hooks_t mExosipTransport;
#endif
};
/**

View file

@ -98,12 +98,16 @@ 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,op);
op->has_auth_pending=TRUE;
}
}
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);
if (op->has_auth_pending){
op->has_auth_pending=FALSE;
if (ms_list_find(sal->pending_auths,op)){
sal->pending_auths=ms_list_remove(sal->pending_auths,op);
}
}
}
@ -432,8 +436,8 @@ Sal * sal_init(){
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);
#if defined(PACKAGE_NAME) && defined(LIBLINPHONE_VERSION)
belle_sip_header_user_agent_add_product(sal->user_agent, PACKAGE_NAME "/" LIBLINPHONE_VERSION);
#endif
sal_append_stack_string_to_user_agent(sal);
belle_sip_object_ref(sal->user_agent);
@ -530,6 +534,8 @@ void sal_uninit(Sal* sal){
belle_sip_object_unref(sal->prov);
belle_sip_object_unref(sal->stack);
belle_sip_object_unref(sal->listener);
if (sal->supported) belle_sip_object_unref(sal->supported);
ms_list_free_with_data(sal->supported_tags,ms_free);
if (sal->uuid) ms_free(sal->uuid);
if (sal->root_ca) ms_free(sal->root_ca);
ms_free(sal);
@ -555,7 +561,7 @@ int sal_add_listen_port(Sal *ctx, SalAddress* addr){
sal_address_get_port(addr),
sal_transport_to_string(sal_address_get_transport(addr)));
if (sal_address_get_port(addr)==-1 && lp==NULL){
int random_port=(0xDFFF&random())+1024;
int random_port=(0xDFFF&ortp_random())+1024;
ms_warning("This version of belle-sip doesn't support random port, choosing one here.");
lp = belle_sip_stack_create_listening_point(ctx->stack,
sal_address_get_domain(addr),
@ -639,28 +645,42 @@ void sal_set_keepalive_period(Sal *ctx,unsigned int value){
belle_sip_listening_point_set_keep_alive(lp,ctx->keep_alive);
}
}
return ;
}
int sal_enable_tunnel(Sal *ctx, void *tunnelclient) {
#ifdef TUNNEL_ENABLED
belle_sip_listening_point_t *lp;
int result;
sal_unlisten_ports(ctx);
lp = belle_sip_tunnel_listening_point_new(ctx->stack, tunnelclient);
if (lp == NULL) return -1;
belle_sip_listening_point_set_keep_alive(lp, ctx->keep_alive);
result = belle_sip_provider_add_listening_point(ctx->prov, lp);
set_tls_properties(ctx);
return result;
belle_sip_listening_point_t *lp_udp = NULL;
if(ctx->lp_tunnel != NULL) {
ortp_error("sal_enable_tunnel(): tunnel is already enabled");
return -1;
}
while((lp_udp = belle_sip_provider_get_listening_point(ctx->prov, "udp")) != NULL) {
belle_sip_object_ref(lp_udp);
belle_sip_provider_remove_listening_point(ctx->prov, lp_udp);
ctx->udp_listening_points = ms_list_append(ctx->udp_listening_points, lp_udp);
}
ctx->lp_tunnel = belle_sip_tunnel_listening_point_new(ctx->stack, tunnelclient);
if(ctx->lp_tunnel == NULL) return -1;
belle_sip_listening_point_set_keep_alive(ctx->lp_tunnel, ctx->keep_alive);
belle_sip_provider_add_listening_point(ctx->prov, ctx->lp_tunnel);
belle_sip_object_ref(ctx->lp_tunnel);
return 0;
#else
return 0;
#endif
}
void sal_disable_tunnel(Sal *ctx) {
#ifdef TUNNEL_ENABLED
sal_unlisten_ports(ctx);
MSList *it;
if(ctx->lp_tunnel) {
belle_sip_provider_remove_listening_point(ctx->prov, ctx->lp_tunnel);
belle_sip_object_unref(ctx->lp_tunnel);
ctx->lp_tunnel = NULL;
for(it=ctx->udp_listening_points; it!=NULL; it=it->next) {
belle_sip_provider_add_listening_point(ctx->prov, (belle_sip_listening_point_t *)it->data);
}
ms_list_free_with_data(ctx->udp_listening_points, belle_sip_object_unref);
ctx->udp_listening_points = NULL;
}
#endif
}
/**
@ -928,10 +948,79 @@ int sal_create_uuid(Sal*ctx, char *uuid, size_t len){
return 0;
}
static void make_supported_header(Sal *sal){
MSList *it;
char *alltags=NULL;
size_t buflen=64;
size_t written=0;
if (sal->supported){
belle_sip_object_unref(sal->supported);
sal->supported=NULL;
}
for(it=sal->supported_tags;it!=NULL;it=it->next){
const char *tag=(const char*)it->data;
size_t taglen=strlen(tag);
if (alltags==NULL || (written+taglen+1>=buflen)) alltags=ms_realloc(alltags,(buflen=buflen*2));
snprintf(alltags+written,buflen-written,it->next ? "%s, " : "%s",tag);
}
if (alltags){
sal->supported=belle_sip_header_create("Supported",alltags);
if (sal->supported){
belle_sip_object_ref(sal->supported);
}
ms_free(alltags);
}
}
void sal_set_supported_tags(Sal *ctx, const char* tags){
ctx->supported_tags=ms_list_free_with_data(ctx->supported_tags,ms_free);
if (tags){
char *iter;
char *buffer=ms_strdup(tags);
char *tag;
char *context=NULL;
iter=buffer;
while((tag=strtok_r(iter,", ",&context))!=NULL){
iter=NULL;
ctx->supported_tags=ms_list_append(ctx->supported_tags,ms_strdup(tag));
}
ms_free(buffer);
}
make_supported_header(ctx);
}
const char *sal_get_supported_tags(Sal *ctx){
if (ctx->supported){
return belle_sip_header_get_unparsed_value(ctx->supported);
}
return NULL;
}
void sal_add_supported_tag(Sal *ctx, const char* tag){
MSList *elem=ms_list_find_custom(ctx->supported_tags,(MSCompareFunc)strcasecmp,tag);
if (!elem){
ctx->supported_tags=ms_list_append(ctx->supported_tags,ms_strdup(tag));
make_supported_header(ctx);
}
}
void sal_remove_supported_tag(Sal *ctx, const char* tag){
MSList *elem=ms_list_find_custom(ctx->supported_tags,(MSCompareFunc)strcasecmp,tag);
if (elem){
ms_free(elem->data);
ctx->supported_tags=ms_list_remove_link(ctx->supported_tags,elem);
make_supported_header(ctx);
}
}
belle_sip_response_t* sal_create_response_from_request ( Sal* sal, belle_sip_request_t* req, int code ) {
belle_sip_response_t *resp=belle_sip_response_create_from_request(req,code);
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(sal->user_agent));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),sal_make_supported_header(sal));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),sal->supported);
return resp;
}

View file

@ -33,12 +33,16 @@ struct Sal{
belle_sip_provider_t *prov;
belle_sip_header_user_agent_t* user_agent;
belle_sip_listener_t *listener;
belle_sip_listening_point_t *lp_tunnel;
MSList *udp_listening_points;
void *up; /*user pointer*/
int session_expires;
unsigned int keep_alive;
char *root_ca;
char *uuid;
int refresher_retry_after; /*retry after value for refresher*/
MSList *supported_tags;/*list of char * */
belle_sip_header_t *supported;
bool_t one_matching_codec;
bool_t use_tcp_tls_keep_alive;
bool_t nat_helper_enabled;
@ -102,6 +106,7 @@ struct SalOp{
bool_t sdp_offering;
bool_t call_released;
bool_t manual_refresher;
bool_t has_auth_pending;
int auth_requests; /*number of auth requested for this op*/
};
@ -164,8 +169,6 @@ bool_t sal_op_get_body(SalOp *op, belle_sip_message_t *msg, SalBody *salbody);
SalReason sal_reason_to_sip_code(SalReason r);
belle_sip_header_t * sal_make_supported_header(Sal *sal);
void _sal_op_add_custom_headers(SalOp *op, belle_sip_message_t *msg);
#endif /* SAL_IMPL_H_ */

View file

@ -185,6 +185,7 @@ static void call_process_response(void *op_base, const belle_sip_response_event_
int code = belle_sip_response_get_status_code(response);
belle_sip_header_content_type_t *header_content_type=NULL;
belle_sip_dialog_t *dialog=belle_sip_response_event_get_dialog(event);
const char *method;
if (!client_transaction) {
ms_warning("Discarding stateless response [%i] on op [%p]",code,op);
@ -193,13 +194,13 @@ static void call_process_response(void *op_base, const belle_sip_response_event_
req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction));
set_or_update_dialog(op,dialog);
dialog_state=dialog ? belle_sip_dialog_get_state(dialog) : BELLE_SIP_DIALOG_NULL;
method=belle_sip_request_get_method(req);
ms_message("Op [%p] receiving call response [%i], dialog is [%p] in state [%s]",op,code,dialog,belle_sip_dialog_state_to_string(dialog_state));
switch(dialog_state) {
case BELLE_SIP_DIALOG_NULL:
case BELLE_SIP_DIALOG_EARLY: {
if (strcmp("INVITE",belle_sip_request_get_method(req))==0 ) {
if (strcmp("INVITE",method)==0 ) {
if (op->state == SalOpStateTerminating) {
/*check if CANCEL was sent before*/
if (strcmp("CANCEL",belle_sip_request_get_method(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_client_trans))))!=0) {
@ -238,28 +239,28 @@ static void call_process_response(void *op_base, const belle_sip_response_event_
case BELLE_SIP_DIALOG_CONFIRMED: {
switch (op->state) {
case SalOpStateEarly:/*invite case*/
case SalOpStateActive: /*re-invite case*/
if (code >=200
&& code<300
&& strcmp("INVITE",belle_sip_request_get_method(req))==0) {
handle_sdp_from_response(op,response);
ack=belle_sip_dialog_create_ack(op->dialog,belle_sip_dialog_get_local_seq_number(op->dialog));
if (ack==NULL) {
ms_error("This call has been already terminated.");
return ;
case SalOpStateActive: /*re-invite, INFO, UPDATE case*/
if (strcmp("INVITE",method)==0){
if (code >=200 && code<300) {
handle_sdp_from_response(op,response);
ack=belle_sip_dialog_create_ack(op->dialog,belle_sip_dialog_get_local_seq_number(op->dialog));
if (ack==NULL) {
ms_error("This call has been already terminated.");
return ;
}
if (op->sdp_answer){
set_sdp(BELLE_SIP_MESSAGE(ack),op->sdp_answer);
belle_sip_object_unref(op->sdp_answer);
op->sdp_answer=NULL;
}
belle_sip_dialog_send_ack(op->dialog,ack);
op->base.root->callbacks.call_accepted(op); /*INVITE*/
op->state=SalOpStateActive;
}else if (code >= 300){
call_set_error(op,response);
}
if (op->sdp_answer){
set_sdp(BELLE_SIP_MESSAGE(ack),op->sdp_answer);
belle_sip_object_unref(op->sdp_answer);
op->sdp_answer=NULL;
}
belle_sip_dialog_send_ack(op->dialog,ack);
op->base.root->callbacks.call_accepted(op); /*INVITE*/
op->state=SalOpStateActive;
} else if (code >= 300 && strcmp("INVITE",belle_sip_request_get_method(req))==0){
call_set_error(op,response);
} else if (code == 491
&& strcmp("INFO",belle_sip_request_get_method(req)) == 0
}else if (strcmp("INFO",method)==0){
if (code == 491
&& (header_content_type = belle_sip_message_get_header_by_type(req,belle_sip_header_content_type_t))
&& strcmp("application",belle_sip_header_content_type_get_type(header_content_type))==0
&& strcmp("media_control+xml",belle_sip_header_content_type_get_subtype(header_content_type))==0) {
@ -267,8 +268,11 @@ static void call_process_response(void *op_base, const belle_sip_response_event_
belle_sip_source_t *s=sal_create_timer(op->base.root,vfu_retry,sal_op_ref(op), retry_in, "vfu request retry");
ms_message("Rejected vfu request on op [%p], just retry in [%ui] ms",op,retry_in);
belle_sip_object_unref(s);
}else {
/*ignoring*/
}else {
/*ignoring*/
}
}else if (strcmp("UPDATE",method)==0){
op->base.root->callbacks.call_accepted(op); /*INVITE*/
}
break;
case SalOpStateTerminating:
@ -314,6 +318,8 @@ static void call_process_transaction_terminated(void *user_ctx, const belle_sip_
belle_sip_server_transaction_t *server_transaction=belle_sip_transaction_terminated_event_get_server_transaction(event);
belle_sip_request_t* req;
belle_sip_response_t* resp;
bool_t release_call=FALSE;
if (client_transaction) {
req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction));
resp=belle_sip_transaction_get_response(BELLE_SIP_TRANSACTION(client_transaction));
@ -324,9 +330,21 @@ static void call_process_transaction_terminated(void *user_ctx, const belle_sip_
if (op->state ==SalOpStateTerminating
&& strcmp("BYE",belle_sip_request_get_method(req))==0
&& (!resp || (belle_sip_response_get_status_code(resp) !=401
&& belle_sip_response_get_status_code(resp) !=407))) {
if (op->dialog==NULL) call_set_released(op);
&& belle_sip_response_get_status_code(resp) !=407))
&& op->dialog==NULL) {
release_call=TRUE;
}
if (server_transaction){
if (op->pending_server_trans==server_transaction){
belle_sip_object_unref(op->pending_server_trans);
op->pending_server_trans=NULL;
}
if (op->pending_update_server_trans==server_transaction){
belle_sip_object_unref(op->pending_update_server_trans);
op->pending_update_server_trans=NULL;
}
}
if (release_call) call_set_released(op);
}
static void call_terminated(SalOp* op,belle_sip_server_transaction_t* server_transaction, belle_sip_request_t* request,int status_code) {
@ -419,6 +437,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
belle_sip_response_t* resp;
belle_sip_header_t* call_info;
const char *method=belle_sip_request_get_method(req);
bool_t is_update=FALSE;
if (strcmp("ACK",method)!=0){ /*ACK does'nt create srv transaction*/
server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,belle_sip_request_event_get_request(event));
@ -490,7 +509,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
} else if (strcmp("UPDATE",method)==0) {
sal_op_reset_descriptions(op);
if (process_sdp_for_invite(op,req)==0)
op->base.root->callbacks.call_updating(op);
op->base.root->callbacks.call_updating(op,TRUE);
} else {
belle_sip_error("Unexpected method [%s] for dialog state BELLE_SIP_DIALOG_EARLY",belle_sip_request_get_method(req));
unsupported_method(server_transaction,req);
@ -522,11 +541,20 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op));
op->state=SalOpStateTerminating;
/*call end not notified by dialog deletion because transaction can end before dialog*/
} else if(strcmp("INVITE",method)==0) {
/*re-invite*/
sal_op_reset_descriptions(op);
if (process_sdp_for_invite(op,req)==0)
op->base.root->callbacks.call_updating(op);
} else if(strcmp("INVITE",method)==0 || (is_update=(strcmp("UPDATE",method)==0)) ) {
if (is_update && !belle_sip_message_get_body(BELLE_SIP_MESSAGE(req))) {
/*session timer case*/
/*session expire should be handled. to be done when real session timer (rfc4028) will be implemented*/
resp=sal_op_create_response_from_request(op,req,200);
belle_sip_server_transaction_send_response(server_transaction,resp);
belle_sip_object_unref(op->pending_update_server_trans);
op->pending_update_server_trans=NULL;
} else {
/*re-invite*/
sal_op_reset_descriptions(op);
if (process_sdp_for_invite(op,req)==0)
op->base.root->callbacks.call_updating(op,is_update);
}
} else if (strcmp("INFO",method)==0){
if (belle_sip_message_get_body(BELLE_SIP_MESSAGE(req))
&& strstr(belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)),"picture_fast_update")) {
@ -564,22 +592,6 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
belle_sip_server_transaction_send_response(server_transaction,sal_op_create_response_from_request(op,req,481));
} else if (strcmp("MESSAGE",method)==0){
sal_process_incoming_message(op,event);
} else if (strcmp("UPDATE",method)==0) {
/*FIXME jehan: It might be better to silently accept UPDATE which do not modify either the number or the nature of streams*/
/*rfc 3311
* 5.2 Receiving an UPDATE
* ...
* If the UAS cannot change the session parameters without prompting the user, it SHOULD reject
* the request with a 504 response.
*/
resp=sal_op_create_response_from_request(op,req,504);
belle_sip_response_set_reason_phrase(resp,"Cannot change the session parameters without prompting the user");
/*belle_sip_message_add_header( BELLE_SIP_MESSAGE(resp)
,belle_sip_header_create( "Warning", "Cannot change the session parameters without prompting the user"));*/
belle_sip_server_transaction_send_response(server_transaction,resp);
return;
}else{
ms_error("unexpected method [%s] for dialog [%p]",belle_sip_request_get_method(req),op->dialog);
unsupported_method(server_transaction,req);
@ -779,6 +791,7 @@ int sal_call_decline(SalOp *op, SalReason reason, const char *redirection /*opti
belle_sip_response_t* response;
belle_sip_header_contact_t* contact=NULL;
int status=sal_reason_to_sip_code(reason);
belle_sip_transaction_t *trans;
if (reason==SalReasonRedirect){
if (redirection!=NULL) {
@ -790,19 +803,27 @@ int sal_call_decline(SalOp *op, SalReason reason, const char *redirection /*opti
ms_error("Cannot redirect to null");
}
}
response = sal_op_create_response_from_request(op,belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_server_trans)),status);
trans=(belle_sip_transaction_t*)op->pending_server_trans;
if (!trans) trans=(belle_sip_transaction_t*)op->pending_update_server_trans;
if (!trans){
ms_error("sal_call_decline(): no pending transaction to decline.");
return -1;
}
response = sal_op_create_response_from_request(op,belle_sip_transaction_get_request(trans),status);
if (contact) belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_HEADER(contact));
belle_sip_server_transaction_send_response(op->pending_server_trans,response);
belle_sip_server_transaction_send_response(BELLE_SIP_SERVER_TRANSACTION(trans),response);
return 0;
}
int sal_call_update(SalOp *op, const char *subject){
int sal_call_update(SalOp *op, const char *subject, bool_t no_user_consent){
belle_sip_request_t *update;
belle_sip_dialog_state_t state=belle_sip_dialog_get_state(op->dialog);
/*check for dialog state*/
if ( state == BELLE_SIP_DIALOG_CONFIRMED) {
update=belle_sip_dialog_create_request(op->dialog,"INVITE");
if (no_user_consent)
update=belle_sip_dialog_create_request(op->dialog,"UPDATE");
else
update=belle_sip_dialog_create_request(op->dialog,"INVITE");
} else if (state == BELLE_SIP_DIALOG_EARLY) {
update=belle_sip_dialog_create_request(op->dialog,"UPDATE");
} else {

View file

@ -118,9 +118,7 @@ belle_sip_header_contact_t* sal_op_create_contact(SalOp *op){
return contact_header;
}
belle_sip_header_t * sal_make_supported_header(Sal *sal){
return belle_sip_header_create("Supported","replaces, outbound");
}
static void add_initial_route_set(belle_sip_request_t *request, const MSList *list){
const MSList *elem;
@ -201,7 +199,7 @@ belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method) {
belle_sip_header_privacy_add_privacy(privacy_header,sal_privacy_to_string(SalPrivacyUser));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(privacy_header));
}
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),sal_make_supported_header(op->base.root));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),op->base.root->supported);
return req;
}

299
coreapi/call_log.c Normal file
View file

@ -0,0 +1,299 @@
/*
linphone
Copyright (C) 2010-2014 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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#define _XOPEN_SOURCE 700 /*required for strptime of GNU libc*/
#include <time.h>
#include "private.h"
/*******************************************************************************
* Internal functions *
******************************************************************************/
/*prevent a gcc bug with %c*/
static size_t my_strftime(char *s, size_t max, const char *fmt, const struct tm *tm){
return strftime(s, max, fmt, tm);
}
static time_t string_to_time(const char *date){
#ifndef WIN32
struct tm tmtime={0};
strptime(date,"%c",&tmtime);
return mktime(&tmtime);
#else
return 0;
#endif
}
static void set_call_log_date(LinphoneCallLog *cl, time_t start_time){
struct tm loctime;
#ifdef WIN32
#if !defined(_WIN32_WCE)
loctime=*localtime(&start_time);
/*FIXME*/
#endif /*_WIN32_WCE*/
#else
localtime_r(&start_time,&loctime);
#endif
my_strftime(cl->start_date,sizeof(cl->start_date),"%c",&loctime);
}
/*******************************************************************************
* Private functions *
******************************************************************************/
void call_logs_write_to_config_file(LinphoneCore *lc){
MSList *elem;
char logsection[32];
int i;
char *tmp;
LpConfig *cfg=lc->config;
if (linphone_core_get_global_state (lc)==LinphoneGlobalStartup) return;
for(i=0,elem=lc->call_logs;elem!=NULL;elem=elem->next,++i){
LinphoneCallLog *cl=(LinphoneCallLog*)elem->data;
snprintf(logsection,sizeof(logsection),"call_log_%i",i);
lp_config_clean_section(cfg,logsection);
lp_config_set_int(cfg,logsection,"dir",cl->dir);
lp_config_set_int(cfg,logsection,"status",cl->status);
tmp=linphone_address_as_string(cl->from);
lp_config_set_string(cfg,logsection,"from",tmp);
ms_free(tmp);
tmp=linphone_address_as_string(cl->to);
lp_config_set_string(cfg,logsection,"to",tmp);
ms_free(tmp);
if (cl->start_date_time)
lp_config_set_int64(cfg,logsection,"start_date_time",(int64_t)cl->start_date_time);
else lp_config_set_string(cfg,logsection,"start_date",cl->start_date);
lp_config_set_int(cfg,logsection,"duration",cl->duration);
if (cl->refkey) lp_config_set_string(cfg,logsection,"refkey",cl->refkey);
lp_config_set_float(cfg,logsection,"quality",cl->quality);
lp_config_set_int(cfg,logsection,"video_enabled", cl->video_enabled);
lp_config_set_string(cfg,logsection,"call_id",cl->call_id);
}
for(;i<lc->max_call_logs;++i){
snprintf(logsection,sizeof(logsection),"call_log_%i",i);
lp_config_clean_section(cfg,logsection);
}
}
void call_logs_read_from_config_file(LinphoneCore *lc){
char logsection[32];
int i;
const char *tmp;
uint64_t sec;
LpConfig *cfg=lc->config;
for(i=0;;++i){
snprintf(logsection,sizeof(logsection),"call_log_%i",i);
if (lp_config_has_section(cfg,logsection)){
LinphoneCallLog *cl;
LinphoneAddress *from=NULL,*to=NULL;
tmp=lp_config_get_string(cfg,logsection,"from",NULL);
if (tmp) from=linphone_address_new(tmp);
tmp=lp_config_get_string(cfg,logsection,"to",NULL);
if (tmp) to=linphone_address_new(tmp);
if (!from || !to)
continue;
cl=linphone_call_log_new(lp_config_get_int(cfg,logsection,"dir",0),from,to);
cl->status=lp_config_get_int(cfg,logsection,"status",0);
sec=lp_config_get_int64(cfg,logsection,"start_date_time",0);
if (sec) {
/*new call log format with date expressed in seconds */
cl->start_date_time=(time_t)sec;
set_call_log_date(cl,cl->start_date_time);
}else{
tmp=lp_config_get_string(cfg,logsection,"start_date",NULL);
if (tmp) {
strncpy(cl->start_date,tmp,sizeof(cl->start_date));
cl->start_date_time=string_to_time(cl->start_date);
}
}
cl->duration=lp_config_get_int(cfg,logsection,"duration",0);
tmp=lp_config_get_string(cfg,logsection,"refkey",NULL);
if (tmp) cl->refkey=ms_strdup(tmp);
cl->quality=lp_config_get_float(cfg,logsection,"quality",-1);
cl->video_enabled=lp_config_get_int(cfg,logsection,"video_enabled",0);
tmp=lp_config_get_string(cfg,logsection,"call_id",NULL);
if (tmp) cl->call_id=ms_strdup(tmp);
lc->call_logs=ms_list_append(lc->call_logs,cl);
}else break;
}
}
/*******************************************************************************
* Public functions *
******************************************************************************/
const char *linphone_call_log_get_call_id(const LinphoneCallLog *cl){
return cl->call_id;
}
LinphoneCallDir linphone_call_log_get_dir(LinphoneCallLog *cl){
return cl->dir;
}
int linphone_call_log_get_duration(LinphoneCallLog *cl){
return cl->duration;
}
LinphoneAddress *linphone_call_log_get_from_address(LinphoneCallLog *cl){
return cl->from;
}
const rtp_stats_t *linphone_call_log_get_local_stats(const LinphoneCallLog *cl){
return &cl->local_stats;
}
float linphone_call_log_get_quality(LinphoneCallLog *cl){
return cl->quality;
}
const char *linphone_call_log_get_ref_key(const LinphoneCallLog *cl){
return cl->refkey;
}
LinphoneAddress *linphone_call_log_get_remote_address(LinphoneCallLog *cl){
return (cl->dir == LinphoneCallIncoming) ? cl->from : cl->to;
}
const rtp_stats_t *linphone_call_log_get_remote_stats(const LinphoneCallLog *cl){
return &cl->remote_stats;
}
time_t linphone_call_log_get_start_date(LinphoneCallLog *cl){
return cl->start_date_time;
}
LinphoneCallStatus linphone_call_log_get_status(LinphoneCallLog *cl){
return cl->status;
}
LinphoneAddress *linphone_call_log_get_to_address(LinphoneCallLog *cl){
return cl->to;
}
void linphone_call_log_set_ref_key(LinphoneCallLog *cl, const char *refkey){
if (cl->refkey!=NULL){
ms_free(cl->refkey);
cl->refkey=NULL;
}
if (refkey) cl->refkey=ms_strdup(refkey);
}
char * linphone_call_log_to_str(LinphoneCallLog *cl){
char *status;
char *tmp;
char *from=linphone_address_as_string (cl->from);
char *to=linphone_address_as_string (cl->to);
switch(cl->status){
case LinphoneCallAborted:
status=_("aborted");
break;
case LinphoneCallSuccess:
status=_("completed");
break;
case LinphoneCallMissed:
status=_("missed");
break;
default:
status="unknown";
}
tmp=ortp_strdup_printf(_("%s at %s\nFrom: %s\nTo: %s\nStatus: %s\nDuration: %i mn %i sec\n"),
(cl->dir==LinphoneCallIncoming) ? _("Incoming call") : _("Outgoing call"),
cl->start_date,
from,
to,
status,
cl->duration/60,
cl->duration%60);
ms_free(from);
ms_free(to);
return tmp;
}
bool_t linphone_call_log_video_enabled(LinphoneCallLog *cl) {
return cl->video_enabled;
}
/*******************************************************************************
* Reference and user data handling functions *
******************************************************************************/
void *linphone_call_log_get_user_data(const LinphoneCallLog *cl) {
return cl->user_data;
}
void linphone_call_log_set_user_data(LinphoneCallLog *cl, void *ud) {
cl->user_data = ud;
}
LinphoneCallLog * linphone_call_log_ref(LinphoneCallLog *cl) {
belle_sip_object_ref(cl);
return cl;
}
void linphone_call_log_unref(LinphoneCallLog *cl) {
belle_sip_object_unref(cl);
}
/*******************************************************************************
* Constructor and destructor functions *
******************************************************************************/
static void _linphone_call_log_destroy(LinphoneCallLog *cl){
if (cl->from!=NULL) linphone_address_destroy(cl->from);
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->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]);
}
LinphoneCallLog * linphone_call_log_new(LinphoneCallDir dir, LinphoneAddress *from, LinphoneAddress *to){
LinphoneCallLog *cl=belle_sip_object_new(LinphoneCallLog);
cl->dir=dir;
cl->start_date_time=time(NULL);
set_call_log_date(cl,cl->start_date_time);
cl->from=from;
cl->to=to;
cl->status=LinphoneCallAborted; /*default status*/
cl->quality=-1;
cl->reporting.reports[LINPHONE_CALL_STATS_AUDIO]=linphone_reporting_new();
cl->reporting.reports[LINPHONE_CALL_STATS_VIDEO]=linphone_reporting_new();
return cl;
}
/* DEPRECATED */
void linphone_call_log_destroy(LinphoneCallLog *cl) {
belle_sip_object_unref(cl);
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneCallLog);
BELLE_SIP_INSTANCIATE_VPTR(LinphoneCallLog, belle_sip_object_t,
(belle_sip_object_destroy_t)_linphone_call_log_destroy,
NULL, // clone
NULL, // marshal
FALSE
);

244
coreapi/call_log.h Normal file
View file

@ -0,0 +1,244 @@
/*
linphone
Copyright (C) 2010-2014 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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __LINPHONE_CALL_LOG_H__
#define __LINPHONE_CALL_LOG_H__
/**
* @addtogroup call_logs
* @{
**/
/*******************************************************************************
* Structures and enums *
******************************************************************************/
/**
* Enum representing the direction of a call.
**/
enum _LinphoneCallDir {
LinphoneCallOutgoing, /**< outgoing calls*/
LinphoneCallIncoming /**< incoming calls*/
};
/**
* Typedef for enum
**/
typedef enum _LinphoneCallDir LinphoneCallDir;
/**
* Enum representing the status of a call
**/
typedef enum _LinphoneCallStatus {
LinphoneCallSuccess, /**< The call was sucessful */
LinphoneCallAborted, /**< The call was aborted */
LinphoneCallMissed, /**< The call was missed (unanswered) */
LinphoneCallDeclined /**< The call was declined, either locally or by remote end */
} LinphoneCallStatus;
/**
* Structure representing a call log.
**/
typedef struct _LinphoneCallLog LinphoneCallLog;
/*******************************************************************************
* Public functions *
******************************************************************************/
/**
* Get the call ID used by the call.
* @param[in] cl LinphoneCallLog object
* @return The call ID used by the call as a string.
**/
LINPHONE_PUBLIC const char * linphone_call_log_get_call_id(const LinphoneCallLog *cl);
/**
* Get the direction of the call.
* @param[in] cl LinphoneCallLog object
* @return The direction of the call.
**/
LINPHONE_PUBLIC LinphoneCallDir linphone_call_log_get_dir(LinphoneCallLog *cl);
/**
* Get the duration of the call.
* @param[in] cl LinphoneCallLog object
* @return The duration of the call in seconds.
**/
LINPHONE_PUBLIC int linphone_call_log_get_duration(LinphoneCallLog *cl);
/**
* Get the origin address (ie from) of the call.
* @param[in] cl LinphoneCallLog object
* @return The origin address (ie from) of the call.
**/
LINPHONE_PUBLIC LinphoneAddress * linphone_call_log_get_from_address(LinphoneCallLog *cl);
/**
* Get the RTP statistics computed locally regarding the call.
* @param[in] cl LinphoneCallLog object
* @return The RTP statistics that have been computed locally for the call.
**/
LINPHONE_PUBLIC const rtp_stats_t * linphone_call_log_get_local_stats(const LinphoneCallLog *cl);
/**
* Get the overall quality indication of the call.
* @param[in] cl LinphoneCallLog object
* @return The overall quality indication of the call.
**/
LINPHONE_PUBLIC float linphone_call_log_get_quality(LinphoneCallLog *cl);
/**
* Get the persistent reference key associated to the call log.
*
* The reference key can be for example an id to an external database.
* It is stored in the config file, thus can survive to process exits/restarts.
*
* @param[in] cl LinphoneCallLog object
* @return The reference key string that has been associated to the call log, or NULL if none has been associated.
**/
LINPHONE_PUBLIC const char * linphone_call_log_get_ref_key(const LinphoneCallLog *cl);
/**
* Get the remote address (that is from or to depending on call direction).
* @param[in] cl LinphoneCallLog object
* @return The remote address of the call.
**/
LINPHONE_PUBLIC LinphoneAddress * linphone_call_log_get_remote_address(LinphoneCallLog *cl);
/**
* Get the RTP statistics computed by the remote end and sent back via RTCP.
* @note Not implemented yet.
* @param[in] cl LinphoneCallLog object
* @return The RTP statistics that have been computed by the remote end for the call.
**/
LINPHONE_PUBLIC const rtp_stats_t * linphone_call_log_get_remote_stats(const LinphoneCallLog *cl);
/**
* Get the start date of the call.
* @param[in] cl LinphoneCallLog object
* @return The date of the beginning of the call.
**/
LINPHONE_PUBLIC time_t linphone_call_log_get_start_date(LinphoneCallLog *cl);
/**
* Get the status of the call.
* @param[in] cl LinphoneCallLog object
* @return The status of the call.
**/
LINPHONE_PUBLIC LinphoneCallStatus linphone_call_log_get_status(LinphoneCallLog *cl);
/**
* Get the destination address (ie to) of the call.
* @param[in] cl LinphoneCallLog object
* @return The destination address (ie to) of the call.
**/
LINPHONE_PUBLIC LinphoneAddress * linphone_call_log_get_to_address(LinphoneCallLog *cl);
/**
* Associate a persistent reference key to the call log.
*
* The reference key can be for example an id to an external database.
* It is stored in the config file, thus can survive to process exits/restarts.
*
* @param[in] cl LinphoneCallLog object
* @param[in] refkey The reference key string to associate to the call log.
**/
LINPHONE_PUBLIC void linphone_call_log_set_ref_key(LinphoneCallLog *cl, const char *refkey);
/**
* Tell whether video was enabled at the end of the call or not.
* @param[in] cl LinphoneCallLog object
* @return A boolean value telling whether video was enabled at the end of the call.
**/
LINPHONE_PUBLIC bool_t linphone_call_log_video_enabled(LinphoneCallLog *cl);
/**
* Get a human readable string describing the call.
* @note: the returned string must be freed by the application (use ms_free()).
* @param[in] cl LinphoneCallLog object
* @return A human readable string describing the call.
**/
LINPHONE_PUBLIC char * linphone_call_log_to_str(LinphoneCallLog *cl);
/*******************************************************************************
* Reference and user data handling functions *
******************************************************************************/
/**
* Get the user data associated with the call log.
* @param[in] cl LinphoneCallLog object
* @return The user data associated with the call log.
**/
LINPHONE_PUBLIC void *linphone_call_log_get_user_data(const LinphoneCallLog *cl);
/**
* Assign a user data to the call log.
* @param[in] cl LinphoneCallLog object
* @param[in] ud The user data to associate with the call log.
**/
LINPHONE_PUBLIC void linphone_call_log_set_user_data(LinphoneCallLog *cl, void *ud);
/**
* Acquire a reference to the call log.
* @param[in] cl LinphoneCallLog object
* @return The same LinphoneCallLog object
**/
LINPHONE_PUBLIC LinphoneCallLog * linphone_call_log_ref(LinphoneCallLog *cl);
/**
* Release a reference to the call log.
* @param[in] cl LinphoneCallLog object
**/
LINPHONE_PUBLIC void linphone_call_log_unref(LinphoneCallLog *cl);
/*******************************************************************************
* DEPRECATED *
******************************************************************************/
/** @deprecated Use linphone_call_log_get_from_address() instead. */
#define linphone_call_log_get_from(cl) linphone_call_log_get_from_address(cl)
/** @deprecated Use linphone_call_log_get_to_address() instead. */
#define linphone_call_log_get_to(cl) linphone_call_log_get_to_address(cl)
/** @deprecated Use linphone_call_log_set_user_data() instead. */
#define linphone_call_log_set_user_pointer(cl, ud) linphone_call_log_set_user_data(cl, ud)
/** @deprecated Use linphone_call_log_get_user_data() instead. */
#define linphone_call_log_get_user_pointer(cl) linphone_call_log_get_user_data(cl)
/**
* Destroy a LinphoneCallLog.
* @param cl LinphoneCallLog object
* @deprecated Use linphone_call_log_unref() instead.
*/
LINPHONE_PUBLIC void linphone_call_log_destroy(LinphoneCallLog *cl);
/**
* @}
**/
#endif /* __LINPHONE_CALL_LOG_H__ */

207
coreapi/call_params.c Normal file
View file

@ -0,0 +1,207 @@
/*
linphone
Copyright (C) 2010-2014 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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "private.h"
/*******************************************************************************
* Internal functions *
******************************************************************************/
SalMediaProto get_proto_from_call_params(const LinphoneCallParams *params) {
if ((params->media_encryption == LinphoneMediaEncryptionSRTP) && params->avpf_enabled) return SalProtoRtpSavpf;
if (params->media_encryption == LinphoneMediaEncryptionSRTP) return SalProtoRtpSavp;
if (params->avpf_enabled) return SalProtoRtpAvpf;
return SalProtoRtpAvp;
}
/*******************************************************************************
* Public functions *
******************************************************************************/
void linphone_call_params_add_custom_header(LinphoneCallParams *params, const char *header_name, const char *header_value){
params->custom_headers=sal_custom_header_append(params->custom_headers,header_name,header_value);
}
LinphoneCallParams * linphone_call_params_copy(const LinphoneCallParams *cp){
LinphoneCallParams *ncp=linphone_call_params_new();
memcpy(ncp,cp,sizeof(LinphoneCallParams));
if (cp->record_file) ncp->record_file=ms_strdup(cp->record_file);
if (cp->session_name) ncp->session_name=ms_strdup(cp->session_name);
/*
* The management of the custom headers is not optimal. We copy everything while ref counting would be more efficient.
*/
if (cp->custom_headers) ncp->custom_headers=sal_custom_header_clone(cp->custom_headers);
return ncp;
}
bool_t linphone_call_params_early_media_sending_enabled(const LinphoneCallParams *cp){
return cp->real_early_media;
}
void linphone_call_params_enable_early_media_sending(LinphoneCallParams *cp, bool_t enabled){
cp->real_early_media=enabled;
}
void linphone_call_params_enable_low_bandwidth(LinphoneCallParams *cp, bool_t enabled){
cp->low_bandwidth=enabled;
}
void linphone_call_params_enable_video(LinphoneCallParams *cp, bool_t enabled){
cp->has_video=enabled;
}
const char *linphone_call_params_get_custom_header(const LinphoneCallParams *params, const char *header_name){
return sal_custom_header_find(params->custom_headers,header_name);
}
bool_t linphone_call_params_get_local_conference_mode(const LinphoneCallParams *cp){
return cp->in_conference;
}
LinphoneMediaEncryption linphone_call_params_get_media_encryption(const LinphoneCallParams *cp) {
return cp->media_encryption;
}
LinphonePrivacyMask linphone_call_params_get_privacy(const LinphoneCallParams *params) {
return params->privacy;
}
float linphone_call_params_get_received_framerate(const LinphoneCallParams *cp){
return cp->received_fps;
}
MSVideoSize linphone_call_params_get_received_video_size(const LinphoneCallParams *cp) {
return cp->recv_vsize;
}
const char *linphone_call_params_get_record_file(const LinphoneCallParams *cp){
return cp->record_file;
}
const char * linphone_call_params_get_rtp_profile(const LinphoneCallParams *cp) {
return sal_media_proto_to_string(get_proto_from_call_params(cp));
}
float linphone_call_params_get_sent_framerate(const LinphoneCallParams *cp){
return cp->sent_fps;
}
MSVideoSize linphone_call_params_get_sent_video_size(const LinphoneCallParams *cp) {
return cp->sent_vsize;
}
const char *linphone_call_params_get_session_name(const LinphoneCallParams *cp){
return cp->session_name;
}
const LinphonePayloadType* linphone_call_params_get_used_audio_codec(const LinphoneCallParams *cp) {
return cp->audio_codec;
}
const LinphonePayloadType* linphone_call_params_get_used_video_codec(const LinphoneCallParams *cp) {
return cp->video_codec;
}
bool_t linphone_call_params_low_bandwidth_enabled(const LinphoneCallParams *cp) {
return cp->low_bandwidth;
}
void linphone_call_params_set_audio_bandwidth_limit(LinphoneCallParams *cp, int bandwidth){
cp->audio_bw=bandwidth;
}
void linphone_call_params_set_media_encryption(LinphoneCallParams *cp, LinphoneMediaEncryption e) {
cp->media_encryption = e;
}
void linphone_call_params_set_privacy(LinphoneCallParams *params, LinphonePrivacyMask privacy) {
params->privacy=privacy;
}
void linphone_call_params_set_record_file(LinphoneCallParams *cp, const char *path){
if (cp->record_file){
ms_free(cp->record_file);
cp->record_file=NULL;
}
if (path) cp->record_file=ms_strdup(path);
}
void linphone_call_params_set_session_name(LinphoneCallParams *cp, const char *name){
if (cp->session_name){
ms_free(cp->session_name);
cp->session_name=NULL;
}
if (name) cp->session_name=ms_strdup(name);
}
bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp){
return cp->has_video;
}
/*******************************************************************************
* Reference and user data handling functions *
******************************************************************************/
void *linphone_call_params_get_user_data(const LinphoneCallParams *cp) {
return cp->user_data;
}
void linphone_call_params_set_user_data(LinphoneCallParams *cp, void *ud) {
cp->user_data = ud;
}
LinphoneCallParams * linphone_call_params_ref(LinphoneCallParams *cp) {
belle_sip_object_ref(cp);
return cp;
}
void linphone_call_params_unref(LinphoneCallParams *cp) {
belle_sip_object_unref(cp);
}
/*******************************************************************************
* Constructor and destructor functions *
******************************************************************************/
static void _linphone_call_params_destroy(LinphoneCallParams *cp){
if (cp->record_file) ms_free(cp->record_file);
if (cp->custom_headers) sal_custom_header_free(cp->custom_headers);
}
LinphoneCallParams * linphone_call_params_new(void) {
return belle_sip_object_new(LinphoneCallParams);
}
/* DEPRECATED */
void linphone_call_params_destroy(LinphoneCallParams *cp) {
linphone_call_params_unref(cp);
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneCallParams);
BELLE_SIP_INSTANCIATE_VPTR(LinphoneCallParams, belle_sip_object_t,
(belle_sip_object_destroy_t)_linphone_call_params_destroy,
NULL, // clone
NULL, // marshal
FALSE
);

303
coreapi/call_params.h Normal file
View file

@ -0,0 +1,303 @@
/*
linphone
Copyright (C) 2010-2014 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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef __LINPHONE_CALL_PARAMS_H__
#define __LINPHONE_CALL_PARAMS_H__
/**
* @addtogroup call_control
* @{
**/
/*******************************************************************************
* Structures and enums *
******************************************************************************/
/**
* Private structure definition for LinphoneCallParams.
**/
struct _LinphoneCallParams;
/**
* The LinphoneCallParams is an object containing various call related parameters.
* It can be used to retrieve parameters from a currently running call or modify
* the call's characteristics dynamically.
**/
typedef struct _LinphoneCallParams LinphoneCallParams;
/*******************************************************************************
* Public functions *
******************************************************************************/
/**
* Add a custom SIP header in the INVITE for a call.
* @param[in] cp The #LinphoneCallParams to add a custom SIP header to.
* @param[in] header_name The name of the header to add.
* @param[in] header_value The content of the header to add.
**/
LINPHONE_PUBLIC void linphone_call_params_add_custom_header(LinphoneCallParams *cp, const char *header_name, const char *header_value);
/**
* Copy an existing LinphoneCallParams object to a new LinphoneCallParams object.
* @param[in] cp The LinphoneCallParams object to copy.
* @return A copy of the LinphoneCallParams object.
**/
LINPHONE_PUBLIC LinphoneCallParams * linphone_call_params_copy(const LinphoneCallParams *cp);
/**
* Indicate whether sending of early media was enabled.
* @param[in] cp LinphoneCallParams object
* @return A boolean value telling whether sending of early media was enabled.
**/
LINPHONE_PUBLIC bool_t linphone_call_params_early_media_sending_enabled(const LinphoneCallParams *cp);
/**
* Enable sending of real early media (during outgoing calls).
* @param[in] cp LinphoneCallParams object
* @param[in] enabled A boolean value telling whether to enable early media sending or not.
**/
LINPHONE_PUBLIC void linphone_call_params_enable_early_media_sending(LinphoneCallParams *cp, bool_t enabled);
/**
* Indicate low bandwith mode.
* Configuring a call to low bandwidth mode will result in the core to activate several settings for the call in order to ensure that bitrate usage
* is lowered to the minimum possible. Typically, ptime (packetization time) will be increased, audio codec's output bitrate will be targetted to 20kbit/s provided
* that it is achievable by the codec selected after SDP handshake. Video is automatically disabled.
* @param[in] cp LinphoneCallParams object
* @param[in] enabled A boolean value telling whether to activate the low bandwidth mode or not.
**/
LINPHONE_PUBLIC void linphone_call_params_enable_low_bandwidth(LinphoneCallParams *cp, bool_t enabled);
/**
* Enable video stream.
* @param[in] cp LinphoneCallParams object
* @param[in] enabled A boolean value telling whether to enable video or not.
**/
LINPHONE_PUBLIC void linphone_call_params_enable_video(LinphoneCallParams *cp, bool_t enabled);
/**
* Get a custom SIP header.
* @param[in] cp The #LinphoneCallParams to get the custom SIP header from.
* @param[in] header_name The name of the header to get.
* @return The content of the header or NULL if not found.
**/
LINPHONE_PUBLIC const char *linphone_call_params_get_custom_header(const LinphoneCallParams *cp, const char *header_name);
/**
* Tell whether the call is part of the locally managed conference.
* @param[in] cp LinphoneCallParams object
* @return A boolean value telling whether the call is part of the locally managed conference.
**/
LINPHONE_PUBLIC bool_t linphone_call_params_get_local_conference_mode(const LinphoneCallParams *cp);
/**
* Get the kind of media encryption selected for the call.
* @param[in] cp LinphoneCallParams object
* @return The kind of media encryption selected for the call.
**/
LINPHONE_PUBLIC LinphoneMediaEncryption linphone_call_params_get_media_encryption(const LinphoneCallParams *cp);
/**
* Get requested level of privacy for the call.
* @param[in] cp LinphoneCallParams object
* @return The privacy mode used for the call.
**/
LINPHONE_PUBLIC LinphonePrivacyMask linphone_call_params_get_privacy(const LinphoneCallParams *cp);
/**
* Get the framerate of the video that is received.
* @param[in] cp LinphoneCallParams object
* @return The actual received framerate in frames per seconds, 0 if not available.
*/
LINPHONE_PUBLIC float linphone_call_params_get_received_framerate(const LinphoneCallParams *cp);
/**
* Get the size of the video that is received.
* @param[in] cp LinphoneCallParams object
* @return The received video size or MS_VIDEO_SIZE_UNKNOWN if not available.
*/
LINPHONE_PUBLIC MSVideoSize linphone_call_params_get_received_video_size(const LinphoneCallParams *cp);
/**
* Get the path for the audio recording of the call.
* @param[in] cp LinphoneCallParams object
* @return The path to the audio recording of the call.
**/
LINPHONE_PUBLIC const char *linphone_call_params_get_record_file(const LinphoneCallParams *cp);
/**
* Get the RTP profile being used.
* @param[in] cp #LinphoneCallParams object
* @return The RTP profile.
*/
LINPHONE_PUBLIC const char * linphone_call_params_get_rtp_profile(const LinphoneCallParams *cp);
/**
* Get the framerate of the video that is sent.
* @param[in] cp LinphoneCallParams object
* @return The actual sent framerate in frames per seconds, 0 if not available.
*/
LINPHONE_PUBLIC float linphone_call_params_get_sent_framerate(const LinphoneCallParams *cp);
/**
* Gets the size of the video that is sent.
* @param[in] cp LinphoneCalParams object
* @return The sent video size or MS_VIDEO_SIZE_UNKNOWN if not available.
*/
LINPHONE_PUBLIC MSVideoSize linphone_call_params_get_sent_video_size(const LinphoneCallParams *cp);
/**
* Get the session name of the media session (ie in SDP).
* Subject from the SIP message can be retrieved using linphone_call_params_get_custom_header() and is different.
* @param[in] cp LinphoneCallParams object
* @return The session name of the media session.
**/
LINPHONE_PUBLIC const char *linphone_call_params_get_session_name(const LinphoneCallParams *cp);
/**
* Get the audio codec used in the call, described as a LinphonePayloadType object.
* @param[in] cp LinphoneCallParams object
* @return The LinphonePayloadType object corresponding to the audio codec being used in the call.
**/
LINPHONE_PUBLIC const LinphonePayloadType* linphone_call_params_get_used_audio_codec(const LinphoneCallParams *cp);
/**
* Get the video codec used in the call, described as a LinphonePayloadType structure.
* @param[in] cp LinphoneCallParams object
* @return The LinphonePayloadType object corresponding to the video codec being used in the call.
**/
LINPHONE_PUBLIC const LinphonePayloadType* linphone_call_params_get_used_video_codec(const LinphoneCallParams *cp);
/**
* Tell whether the call has been configured in low bandwidth mode or not.
* This mode can be automatically discovered thanks to a stun server when activate_edge_workarounds=1 in section [net] of configuration file.
* An application that would have reliable way to know network capacity may not use activate_edge_workarounds=1 but instead manually configure
* low bandwidth mode with linphone_call_params_enable_low_bandwidth().
* When enabled, this param may transform a call request with video in audio only mode.
* @param[in] cp LinphoneCallParams object
* @return A boolean value telling whether the low bandwidth mode has been configured/detected.
*/
LINPHONE_PUBLIC bool_t linphone_call_params_low_bandwidth_enabled(const LinphoneCallParams *cp);
/**
* Refine bandwidth settings for this call by setting a bandwidth limit for audio streams.
* As a consequence, codecs whose bitrates are not compatible with this limit won't be used.
* @param[in] cp LinphoneCallParams object
* @param[in] bw The audio bandwidth limit to set in kbit/s.
**/
LINPHONE_PUBLIC void linphone_call_params_set_audio_bandwidth_limit(LinphoneCallParams *cp, int bw);
/**
* Set requested media encryption for a call.
* @param[in] cp LinphoneCallParams object
* @param[in] enc The media encryption to use for the call.
**/
LINPHONE_PUBLIC void linphone_call_params_set_media_encryption(LinphoneCallParams *cp, LinphoneMediaEncryption enc);
/**
* Set requested level of privacy for the call.
* \xmlonly <language-tags>javascript</language-tags> \endxmlonly
* @param[in] cp LinphoneCallParams object
* @param[in] privacy The privacy mode to used for the call.
**/
LINPHONE_PUBLIC void linphone_call_params_set_privacy(LinphoneCallParams *params, LinphonePrivacyMask privacy);
/**
* Enable recording of the call.
* This function must be used before the call parameters are assigned to the call.
* The call recording can be started and paused after the call is established with
* linphone_call_start_recording() and linphone_call_pause_recording().
* @param[in] cp LinphoneCallParams object
* @param[in] path A string containing the path and filename of the file where audio/video streams are to be written.
* The filename must have either .mkv or .wav extention. The video stream will be written only if a MKV file is given.
**/
LINPHONE_PUBLIC void linphone_call_params_set_record_file(LinphoneCallParams *cp, const char *path);
/**
* Set the session name of the media session (ie in SDP).
* Subject from the SIP message (which is different) can be set using linphone_call_params_set_custom_header().
* @param[in] cp LinphoneCallParams object
* @param[in] name The session name to be used.
**/
LINPHONE_PUBLIC void linphone_call_params_set_session_name(LinphoneCallParams *cp, const char *name);
/**
* Tell whether video is enabled or not.
* @param[in] cp LinphoneCallParams object
* @return A boolean value telling whether video is enabled or not.
**/
LINPHONE_PUBLIC bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp);
/*******************************************************************************
* Reference and user data handling functions *
******************************************************************************/
/**
* Get the user data associated with the call params.
* @param[in] cl LinphoneCallParams object
* @return The user data associated with the call params.
**/
LINPHONE_PUBLIC void *linphone_call_params_get_user_data(const LinphoneCallParams *cp);
/**
* Assign a user data to the call params.
* @param[in] cl LinphoneCallParams object
* @param[in] ud The user data to associate with the call params.
**/
LINPHONE_PUBLIC void linphone_call_params_set_user_data(LinphoneCallParams *cp, void *ud);
/**
* Acquire a reference to the call params.
* @param[in] cl LinphoneCallParams object
* @return The same LinphoneCallParams object
**/
LINPHONE_PUBLIC LinphoneCallParams * linphone_call_params_ref(LinphoneCallParams *cp);
/**
* Release a reference to the call params.
* @param[in] cl LinphoneCallParams object
**/
LINPHONE_PUBLIC void linphone_call_params_unref(LinphoneCallParams *cp);
/*******************************************************************************
* DEPRECATED *
******************************************************************************/
/** @deprecated Use linphone_call_params_get_local_conference_mode() instead. */
#define linphone_call_params_local_conference_mode linphone_call_params_get_local_conference_mode
/**
* Destroy a LinphoneCallParams object.
* @param[in] cp LinphoneCallParams object
* @deprecated Use linphone_call_params_unref() instead.
**/
LINPHONE_PUBLIC void linphone_call_params_destroy(LinphoneCallParams *cp);
/**
* @}
**/
#endif /* __LINPHONE_CALL_PARAMS_H__ */

View file

@ -35,7 +35,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
static void register_failure(SalOp *op);
static int media_parameters_changed(LinphoneCall *call, SalMediaDescription *oldmd, SalMediaDescription *newmd) {
if (call->params.in_conference != call->current_params.in_conference) return SAL_MEDIA_DESCRIPTION_CHANGED;
if (call->params->in_conference != call->current_params->in_conference) return SAL_MEDIA_DESCRIPTION_CHANGED;
if (call->up_bw != linphone_core_get_upload_bandwidth(call->core)) return SAL_MEDIA_DESCRIPTION_CHANGED;
if (call->localdesc_changed) ms_message("Local description has changed: %i", call->localdesc_changed);
return call->localdesc_changed | sal_media_description_equals(oldmd, newmd);
@ -96,7 +96,7 @@ static void prepare_early_media_forking(LinphoneCall *call){
if (call->videostream){
rtp_session_set_symmetric_rtp(call->videostream->ms.sessions.rtp_session,FALSE);
}
}
void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md){
@ -152,7 +152,7 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
ms_message("Network parameters have changed, update them.");
linphone_core_update_streams_destinations(lc, call, oldmd, new_md);
}
if (md_changed & SAL_MEDIA_DESCRIPTION_CRYPTO_CHANGED) {
if (md_changed & SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED) {
ms_message("Crypto parameters have changed, update them.");
linphone_call_update_crypto_parameters(call, oldmd, new_md);
}
@ -163,7 +163,7 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
linphone_call_stop_media_streams (call);
linphone_call_init_media_streams (call);
}
if (call->audiostream==NULL){
/*this happens after pausing the call locally. The streams are destroyed and then we wait the 200Ok to recreate them*/
linphone_call_init_media_streams (call);
@ -171,10 +171,10 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
if (call->state==LinphoneCallIncomingEarlyMedia && linphone_core_get_remote_ringback_tone (lc)!=NULL){
send_ringbacktone=TRUE;
}
if ((call->state==LinphoneCallIncomingEarlyMedia || call->state==LinphoneCallOutgoingEarlyMedia) && !call->params.real_early_media){
if ((call->state==LinphoneCallIncomingEarlyMedia || call->state==LinphoneCallOutgoingEarlyMedia) && !call->params->real_early_media){
all_muted=TRUE;
}
if (call->params.real_early_media && call->state==LinphoneCallOutgoingEarlyMedia){
if (call->params->real_early_media && call->state==LinphoneCallOutgoingEarlyMedia){
prepare_early_media_forking(call);
}
linphone_call_start_media_streams(call,all_muted,send_ringbacktone);
@ -182,9 +182,9 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
linphone_core_play_named_tone(lc,LinphoneToneCallOnHold);
}
end:
if (oldmd)
if (oldmd)
sal_media_description_unref(oldmd);
}
#if 0
static bool_t is_duplicate_call(LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to){
@ -192,7 +192,7 @@ static bool_t is_duplicate_call(LinphoneCore *lc, const LinphoneAddress *from, c
for(elem=lc->calls;elem!=NULL;elem=elem->next){
LinphoneCall *call=(LinphoneCall*)elem->data;
if (linphone_address_weak_equal(call->log->from,from) &&
linphone_address_weak_equal(call->log->to, to)){
linphone_address_weak_equal(call->log->to, to)){
return TRUE;
}
}
@ -220,11 +220,11 @@ static bool_t already_a_call_pending(LinphoneCore *lc){
for(elem=lc->calls;elem!=NULL;elem=elem->next){
LinphoneCall *call=(LinphoneCall*)elem->data;
if (call->state==LinphoneCallIncomingReceived
|| call->state==LinphoneCallIncomingEarlyMedia
|| call->state==LinphoneCallOutgoingInit
|| call->state==LinphoneCallOutgoingProgress
|| call->state==LinphoneCallOutgoingEarlyMedia
|| call->state==LinphoneCallOutgoingRinging){
|| call->state==LinphoneCallIncomingEarlyMedia
|| call->state==LinphoneCallOutgoingInit
|| call->state==LinphoneCallOutgoingProgress
|| call->state==LinphoneCallOutgoingEarlyMedia
|| call->state==LinphoneCallOutgoingRinging){
return TRUE;
}
}
@ -239,7 +239,7 @@ static void call_received(SalOp *h){
LinphoneAddress *from_addr, *to_addr;
/*this mode is deprcated because probably useless*/
bool_t prevent_colliding_calls=lp_config_get_int(lc->config,"sip","prevent_colliding_calls",FALSE);
/* first check if we can answer successfully to this invite */
if (linphone_presence_model_get_basic_status(lc->presence_model) == LinphonePresenceBasicStatusClosed) {
LinphonePresenceActivity *activity = linphone_presence_model_get_activity(lc->presence_model);
@ -285,14 +285,14 @@ static void call_received(SalOp *h){
linphone_address_destroy(to_addr);
return;
}
call=linphone_call_new_incoming(lc,from_addr,to_addr,h);
/* the call is acceptable so we can now add it to our list */
linphone_core_add_call(lc,call);
linphone_call_ref(call); /*prevent the call from being destroyed while we are notifying, if the user declines within the state callback */
if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && (call->ice_session != NULL)) {
if ((_linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && (call->ice_session != NULL)) {
/* Defer ringing until the end of the ICE candidates gathering process. */
ms_message("Defer ringing to gather ICE candidates");
return;
@ -313,7 +313,7 @@ static void try_early_media_forking(LinphoneCall *call, SalMediaDescription *md)
int i;
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;i<cur_md->nb_streams;++i){
if (!sal_stream_description_active(&cur_md->streams[i])) continue;
ref_stream=&cur_md->streams[i];
@ -345,15 +345,14 @@ static void call_ringing(SalOp *h){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h));
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(h);
SalMediaDescription *md;
if (call==NULL) return;
/*set privacy*/
call->current_params.privacy=(LinphonePrivacyMask)sal_op_get_privacy(call->op);
if (lc->vtable.display_status)
lc->vtable.display_status(lc,_("Remote ringing."));
if (call==NULL) return;
/*set privacy*/
call->current_params->privacy=(LinphonePrivacyMask)sal_op_get_privacy(call->op);
linphone_core_notify_display_status(lc,_("Remote ringing."));
md=sal_call_get_final_media_description(h);
if (md==NULL){
linphone_core_stop_dtmf_stream(lc);
@ -364,11 +363,12 @@ static void call_ringing(SalOp *h){
/*we release sound before playing ringback tone*/
if (call->audiostream)
audio_stream_unprepare_sound(call->audiostream);
lc->ringstream=ring_start(lc->sound_conf.remote_ring,2000,ringcard);
if( lc->sound_conf.remote_ring ){
lc->ringstream=ring_start(lc->sound_conf.remote_ring,2000,ringcard);
}
}
ms_message("Remote ringing...");
if (lc->vtable.display_status)
lc->vtable.display_status(lc,_("Remote ringing..."));
linphone_core_notify_display_status(lc,_("Remote ringing..."));
linphone_call_set_state(call,LinphoneCallOutgoingRinging,"Remote ringing");
}else{
/*accept early media */
@ -377,9 +377,8 @@ static void call_ringing(SalOp *h){
try_early_media_forking(call,md);
return;
}
if (lc->vtable.show) lc->vtable.show(lc);
if (lc->vtable.display_status)
lc->vtable.display_status(lc,_("Early media."));
linphone_core_notify_show_interface(lc);
linphone_core_notify_display_status(lc,_("Early media."));
linphone_call_set_state(call,LinphoneCallOutgoingEarlyMedia,"Early media");
linphone_core_stop_ringing(lc);
ms_message("Doing early media...");
@ -396,13 +395,13 @@ static void call_accepted(SalOp *op){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
SalMediaDescription *md;
if (call==NULL){
ms_warning("No call to accept.");
return ;
}
/*set privacy*/
call->current_params.privacy=(LinphonePrivacyMask)sal_op_get_privacy(call->op);
call->current_params->privacy=(LinphonePrivacyMask)sal_op_get_privacy(call->op);
/* Handle remote ICE attributes if any. */
if (call->ice_session != NULL) {
@ -416,22 +415,22 @@ static void call_accepted(SalOp *op){
md=sal_call_get_final_media_description(op);
if (md) /*make sure re-invite will not propose video again*/
call->params.has_video &= linphone_core_media_description_contains_video_stream(md);
call->params->has_video &= linphone_core_media_description_contains_video_stream(md);
if (call->state==LinphoneCallOutgoingProgress ||
call->state==LinphoneCallOutgoingRinging ||
call->state==LinphoneCallOutgoingEarlyMedia){
call->state==LinphoneCallOutgoingRinging ||
call->state==LinphoneCallOutgoingEarlyMedia){
linphone_call_set_state(call,LinphoneCallConnected,"Connected");
if (call->referer) linphone_core_notify_refer_state(lc,call->referer,call);
}
if (md && !sal_media_description_empty(md) && !linphone_core_incompatible_security(lc,md)){
linphone_call_update_remote_session_id_and_ver(call);
if (sal_media_description_has_dir(md,SalStreamSendOnly) ||
sal_media_description_has_dir(md,SalStreamInactive)){
if (lc->vtable.display_status){
sal_media_description_has_dir(md,SalStreamInactive)){
{
char *tmp=linphone_call_get_remote_address_as_string (call);
char *msg=ms_strdup_printf(_("Call with %s is paused."),tmp);
lc->vtable.display_status(lc,msg);
linphone_core_notify_display_status(lc,msg);
ms_free(tmp);
ms_free(msg);
}
@ -441,10 +440,10 @@ static void call_accepted(SalOp *op){
linphone_core_start_refered_call(lc,call,NULL);
}else if (sal_media_description_has_dir(md,SalStreamRecvOnly)){
/*we are put on hold when the call is initially accepted */
if (lc->vtable.display_status){
{
char *tmp=linphone_call_get_remote_address_as_string (call);
char *msg=ms_strdup_printf(_("Call answered by %s - on hold."),tmp);
lc->vtable.display_status(lc,msg);
linphone_core_notify_display_status(lc,msg);
ms_free(tmp);
ms_free(msg);
}
@ -453,14 +452,12 @@ static void call_accepted(SalOp *op){
}else{
if (call->state!=LinphoneCallUpdating){
if (call->state==LinphoneCallResuming){
if (lc->vtable.display_status){
lc->vtable.display_status(lc,_("Call resumed."));
}
linphone_core_notify_display_status(lc,_("Call resumed."));
}else{
if (lc->vtable.display_status){
{
char *tmp=linphone_call_get_remote_address_as_string (call);
char *msg=ms_strdup_printf(_("Call answered by %s."),tmp);
lc->vtable.display_status(lc,msg);
linphone_core_notify_display_status(lc,msg);
ms_free(tmp);
ms_free(msg);
}
@ -470,7 +467,7 @@ static void call_accepted(SalOp *op){
/*also reflect the change if the "wished" params, in order to avoid to propose SAVP or video again
* further in the call, for example during pause,resume, conferencing reINVITEs*/
linphone_call_fix_call_parameters(call);
if (!call->current_params.in_conference)
if (!call->current_params->in_conference)
lc->current_call=call;
if (call->prevstate != LinphoneCallIncomingEarlyMedia) /*don't change state in aswer to a SIP UPDATE in early media*/
linphone_call_set_state(call, LinphoneCallStreamsRunning, "Streams running");
@ -503,81 +500,73 @@ static void call_ack(SalOp *op){
}
}
static void call_accept_update(LinphoneCore *lc, LinphoneCall *call){
SalMediaDescription *md;
SalMediaDescription *rmd=sal_call_get_remote_media_description(call->op);
if (rmd!=NULL && call->ice_session!=NULL) {
linphone_core_update_ice_from_remote_media_description(call,rmd);
linphone_core_update_local_media_description_from_ice(call->localdesc,call->ice_session);
}
#ifdef BUILD_UPNP
if(call->upnp_session != NULL) {
linphone_core_update_upnp_from_remote_media_description(call, rmd);
linphone_core_update_local_media_description_from_upnp(call->localdesc,call->upnp_session);
}
#endif //BUILD_UPNP
linphone_call_update_remote_session_id_and_ver(call);
sal_call_accept(call->op);
md=sal_call_get_final_media_description(call->op);
if (md && !sal_media_description_empty(md)){
linphone_core_update_streams(lc,call,md);
}
}
static void call_resumed(LinphoneCore *lc, LinphoneCall *call){
/*when we are resumed, increment session id, because sdp is changed (a=recvonly disapears)*/
linphone_call_increment_local_media_description(call);
call_accept_update(lc,call);
if(lc->vtable.display_status)
lc->vtable.display_status(lc,_("We have been resumed."));
linphone_call_set_state(call,LinphoneCallStreamsRunning,"Connected (streams running)");
linphone_core_notify_display_status(lc,_("We have been resumed."));
_linphone_core_accept_call_update(lc,call,NULL,LinphoneCallStreamsRunning,"Connected (streams running)");
}
static void call_paused_by_remote(LinphoneCore *lc, LinphoneCall *call){
/*when we are resumed, increment session id, because sdp is changed (a=recvonly appears)*/
/*when we are paused, increment session id, because sdp is changed (a=recvonly appears)*/
linphone_call_increment_local_media_description(call);
call_accept_update(lc,call);
/* we are being paused */
if(lc->vtable.display_status)
lc->vtable.display_status(lc,_("We are paused by other party."));
linphone_call_set_state (call,LinphoneCallPausedByRemote,"Call paused by remote");
linphone_core_notify_display_status(lc,_("We are paused by other party."));
_linphone_core_accept_call_update(lc,call,NULL,LinphoneCallPausedByRemote,"Call paused by remote");
}
static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call,bool_t notify_application){
static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call, bool_t is_update){
/*first check if media capabilities are compatible*/
SalMediaDescription* md;
linphone_call_make_local_media_description(lc,call);
sal_call_set_local_media_description(call->op,call->localdesc);
md=sal_call_get_final_media_description(call->op);
if (md && (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md))){
sal_call_decline(call->op,SalReasonNotAcceptable,NULL);
return;
SalMediaDescription *md;
SalMediaDescription *rmd=sal_call_get_remote_media_description(call->op);
SalMediaDescription *prev_result_desc=call->resultdesc;
if (rmd!=NULL){
if (call->state!=LinphoneCallPaused){
/*in paused state, we must stay in paused state.*/
linphone_call_make_local_media_description(lc,call);
sal_call_set_local_media_description(call->op,call->localdesc);
}
md=sal_call_get_final_media_description(call->op);
if (md && (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md))){
sal_call_decline(call->op,SalReasonNotAcceptable,NULL);
return;
}
if (is_update && prev_result_desc && md){
int diff=sal_media_description_equals(prev_result_desc,md);
if (diff & (SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED|SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED)){
ms_warning("Cannot accept this update, it is changing parameters that require user approval");
sal_call_decline(call->op,SalReasonNotAcceptable,NULL); /*FIXME should send 504 Cannot change the session parameters without prompting the user"*/
return;
}
}
}
if (notify_application) {
if(lc->vtable.display_status)
lc->vtable.display_status(lc,_("Call is updated by remote."));
if (call->state==LinphoneCallStreamsRunning) {
/*reINVITE and in-dialogs UPDATE go here*/
linphone_core_notify_display_status(lc,_("Call is updated by remote."));
call->defer_update=FALSE;
linphone_call_set_state(call, LinphoneCallUpdatedByRemote,"Call updated by remote");
if (call->defer_update==FALSE){
linphone_core_accept_call_update(lc,call,NULL);
}
} else { /*SIP UPDATE case*/
/*can be call from any state*/
_linphone_core_accept_call_update(lc,call,NULL);
if (rmd==NULL)
call->expect_media_in_ack=TRUE;
} else if (is_update){ /*SIP UPDATE case, can occur in early states*/
_linphone_core_accept_call_update(lc,call,NULL,call->state,linphone_call_state_to_string(call->state));
}
}
/* this callback is called when an incoming re-INVITE/ SIP UPDATE modifies the session*/
static void call_updating(SalOp *op){
static void call_updating(SalOp *op, bool_t is_update){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
SalMediaDescription *rmd=sal_call_get_remote_media_description(op);
if (rmd==NULL){
/* case of a reINVITE without SDP */
call_accept_update(lc,call);
call->expect_media_in_ack=TRUE;
/* case of a reINVITE or UPDATE without SDP */
call_updated_by_remote(lc,call,is_update);
return;
}
@ -585,22 +574,45 @@ static void call_updating(SalOp *op){
case LinphoneCallPausedByRemote:
if (sal_media_description_has_dir(rmd,SalStreamSendRecv) || sal_media_description_has_dir(rmd,SalStreamRecvOnly)){
call_resumed(lc,call);
}else call_paused_by_remote(lc,call);
}else call_updated_by_remote(lc,call,is_update);
break;
/*SIP UPDATE CASE*/
case LinphoneCallOutgoingRinging:
case LinphoneCallOutgoingEarlyMedia:
call_updated_by_remote(lc,call,FALSE);
case LinphoneCallIncomingEarlyMedia:
if (is_update) call_updated_by_remote(lc,call,is_update);
break;
case LinphoneCallStreamsRunning:
case LinphoneCallConnected:
if (sal_media_description_has_dir(rmd,SalStreamSendOnly) || sal_media_description_has_dir(rmd,SalStreamInactive)){
call_paused_by_remote(lc,call);
}else{
call_updated_by_remote(lc,call,TRUE);
call_updated_by_remote(lc,call,is_update);
}
break;
default:
call_accept_update(lc,call);
case LinphoneCallPaused:
if (sal_media_description_has_dir(rmd,SalStreamSendOnly) || sal_media_description_has_dir(rmd,SalStreamInactive)){
call_paused_by_remote(lc,call);
}else{
call_updated_by_remote(lc,call,is_update);
}
break;
case LinphoneCallUpdating:
case LinphoneCallPausing:
case LinphoneCallResuming:
case LinphoneCallUpdatedByRemote:
sal_call_decline(call->op,SalReasonNotImplemented,NULL);
/*no break*/
case LinphoneCallIdle:
case LinphoneCallOutgoingInit:
case LinphoneCallEnd:
case LinphoneCallIncomingReceived:
case LinphoneCallOutgoingProgress:
case LinphoneCallRefered:
case LinphoneCallError:
case LinphoneCallReleased:
ms_warning("Receiving reINVITE or UPDATE while in state [%s], should not happen.",linphone_call_state_to_string(call->state));
break;
}
}
@ -609,7 +621,7 @@ static void call_terminated(SalOp *op, const char *from){
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
if (call==NULL) return;
switch(linphone_call_get_state(call)){
case LinphoneCallEnd:
case LinphoneCallError:
@ -632,10 +644,8 @@ static void call_terminated(SalOp *op, const char *from){
linphone_core_stop_ringing(lc);
}
linphone_call_stop_media_streams(call);
if (lc->vtable.show!=NULL)
lc->vtable.show(lc);
if (lc->vtable.display_status!=NULL)
lc->vtable.display_status(lc,_("Call terminated."));
linphone_core_notify_show_interface(lc);
linphone_core_notify_display_status(lc,_("Call terminated."));
#ifdef BUILD_UPNP
linphone_call_delete_upnp_session(call);
@ -645,15 +655,14 @@ static void call_terminated(SalOp *op, const char *from){
}
static int resume_call_after_failed_transfer(LinphoneCall *call){
ms_message("!!!!!!!!!!resume_call_after_failed_transfer");
if (call->was_automatically_paused && call->state==LinphoneCallPausing)
return BELLE_SIP_CONTINUE; /*was still in pausing state*/
if (call->was_automatically_paused && call->state==LinphoneCallPaused){
if (sal_op_is_idle(call->op)){
linphone_core_resume_call(call->core,call);
}else {
ms_message("!!!!!!!!!!resume_call_after_failed_transfer, salop was busy");
ms_message("resume_call_after_failed_transfer(), salop was busy");
return BELLE_SIP_CONTINUE;
}
}
@ -677,25 +686,22 @@ static void call_failure(SalOp *op){
ms_warning("Call faillure reported on already terminated call.");
return ;
}
if (lc->vtable.show) lc->vtable.show(lc);
linphone_core_notify_show_interface(lc);
switch(ei->reason){
case SalReasonNone:
break;
case SalReasonRequestTimeout:
msg=_("Request timeout.");
if (lc->vtable.display_status)
lc->vtable.display_status(lc,msg);
linphone_core_notify_display_status(lc,msg);
break;
case SalReasonDeclined:
msg=msg603;
if (lc->vtable.display_status)
lc->vtable.display_status(lc,msg603);
linphone_core_notify_display_status(lc,msg603);
break;
case SalReasonBusy:
msg=msg486;
if (lc->vtable.display_status)
lc->vtable.display_status(lc,msg486);
linphone_core_notify_display_status(lc,msg486);
break;
case SalReasonRedirect:
{
@ -715,23 +721,19 @@ static void call_failure(SalOp *op){
}
}
msg=_("Redirected");
if (lc->vtable.display_status)
lc->vtable.display_status(lc,msg);
linphone_core_notify_display_status(lc,msg);
}
break;
case SalReasonTemporarilyUnavailable:
msg=msg480;
if (lc->vtable.display_status)
lc->vtable.display_status(lc,msg480);
linphone_core_notify_display_status(lc,msg480);
break;
case SalReasonNotFound:
if (lc->vtable.display_status)
lc->vtable.display_status(lc,msg);
linphone_core_notify_display_status(lc,msg);
break;
case SalReasonDoNotDisturb:
msg=msg600;
if (lc->vtable.display_status)
lc->vtable.display_status(lc,msg600);
linphone_core_notify_display_status(lc,msg600);
break;
case SalReasonUnsupportedContent: /*<this is for compatibility: linphone sent 415 because of SDP offer answer failure*/
case SalReasonNotAcceptable:
@ -743,30 +745,29 @@ static void call_failure(SalOp *op){
int 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 (call->params->media_encryption == LinphoneMediaEncryptionSRTP) {
if (call->params->avpf_enabled == TRUE) {
if (i == 0) ms_message("Retrying call [%p] with SAVP", call);
call->params.avpf_enabled = FALSE;
call->params->avpf_enabled = FALSE;
linphone_core_restart_invite(lc, call);
return;
} else if (!linphone_core_is_media_encryption_mandatory(lc)) {
if (i == 0) ms_message("Retrying call [%p] with AVP", call);
call->params.media_encryption = LinphoneMediaEncryptionNone;
call->params->media_encryption = LinphoneMediaEncryptionNone;
memset(call->localdesc->streams[i].crypto, 0, sizeof(call->localdesc->streams[i].crypto));
linphone_core_restart_invite(lc, call);
return;
}
} else if (call->params.avpf_enabled == TRUE) {
} else if (call->params->avpf_enabled == TRUE) {
if (i == 0) ms_message("Retrying call [%p] with AVP", call);
call->params.avpf_enabled = FALSE;
call->params->avpf_enabled = FALSE;
linphone_core_restart_invite(lc, call);
return;
}
}
}
msg=_("Incompatible media parameters.");
if (lc->vtable.display_status)
lc->vtable.display_status(lc,msg);
linphone_core_notify_display_status(lc,msg);
break;
case SalReasonRequestPending:
/*restore previous state, the application will decide to resubmit the action if relevant*/
@ -774,8 +775,7 @@ static void call_failure(SalOp *op){
return;
break;
default:
if (lc->vtable.display_status)
lc->vtable.display_status(lc,_("Call failed."));
linphone_core_notify_display_status(lc,_("Call failed."));
}
/*some call error are not fatal*/
@ -796,7 +796,7 @@ static void call_failure(SalOp *op){
#ifdef BUILD_UPNP
linphone_call_delete_upnp_session(call);
#endif //BUILD_UPNP
if (call->state!=LinphoneCallEnd && call->state!=LinphoneCallError){
if (ei->reason==SalReasonDeclined){
linphone_call_set_state(call,LinphoneCallEnd,"Call declined.");
@ -805,7 +805,7 @@ static void call_failure(SalOp *op){
}
if (ei->reason!=SalReasonNone) linphone_core_play_call_error_tone(lc,linphone_reason_from_sal(ei->reason));
}
if (referer){
/*notify referer of the failure*/
linphone_core_notify_refer_state(lc,referer,call);
@ -827,35 +827,38 @@ static void call_released(SalOp *op){
static void auth_failure(SalOp *op, SalAuthInfo* info) {
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneAuthInfo *ai=(LinphoneAuthInfo*)linphone_core_find_auth_info(lc,info->realm,info->username,info->domain);
if (ai){
ms_message("%s/%s/%s authentication fails.",info->realm,info->username,info->domain);
/*ask again for password if auth info was already supplied but apparently not working*/
if (lc->vtable.auth_info_requested) {
lc->vtable.auth_info_requested(lc,info->realm,info->username,info->domain);
LinphoneAuthInfo *ai=NULL;
if( info != NULL ){
ai = (LinphoneAuthInfo*)linphone_core_find_auth_info(lc,info->realm,info->username,info->domain);
if (ai){
ms_message("%s/%s/%s authentication fails.",info->realm,info->username,info->domain);
/*ask again for password if auth info was already supplied but apparently not working*/
linphone_core_notify_auth_info_requested(lc,info->realm,info->username,info->domain);
}
}
}
static void register_success(SalOp *op, bool_t registered){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)sal_op_get_user_pointer(op);
char *msg;
if (!cfg || cfg->deletion_date!=0){
ms_message("Registration success for removed proxy config, ignored");
if (!cfg){
ms_message("Registration success for deleted proxy config, ignored");
return;
}
linphone_proxy_config_set_state(cfg, registered ? LinphoneRegistrationOk : LinphoneRegistrationCleared ,
registered ? "Registration successful" : "Unregistration done");
if (lc->vtable.display_status){
registered ? "Registration successful" : "Unregistration done");
{
if (registered) msg=ms_strdup_printf(_("Registration on %s successful."),sal_op_get_proxy(op));
else msg=ms_strdup_printf(_("Unregistration on %s done."),sal_op_get_proxy(op));
lc->vtable.display_status(lc,msg);
linphone_core_notify_display_status(lc,msg);
ms_free(msg);
}
}
static void register_failure(SalOp *op){
@ -868,16 +871,12 @@ static void register_failure(SalOp *op){
ms_warning("Registration failed for unknown proxy config.");
return ;
}
if (cfg->deletion_date!=0){
ms_message("Registration failed for removed proxy config, ignored");
return;
}
if (details==NULL)
details=_("no response timeout");
if (lc->vtable.display_status) {
{
char *msg=ortp_strdup_printf(_("Registration on %s failed: %s"),sal_op_get_proxy(op), details);
lc->vtable.display_status(lc,msg);
linphone_core_notify_display_status(lc,msg);
ms_free(msg);
}
@ -910,8 +909,7 @@ static void vfu_request(SalOp *op){
static void dtmf_received(SalOp *op, char dtmf){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
if (lc->vtable.dtmf_received != NULL)
lc->vtable.dtmf_received(lc, call, dtmf);
linphone_core_notify_dtmf_received(lc, call, dtmf);
}
static void refer_received(Sal *sal, SalOp *op, const char *referto){
@ -924,14 +922,14 @@ static void refer_received(Sal *sal, SalOp *op, const char *referto){
call->refer_to=ms_strdup(referto);
call->refer_pending=TRUE;
linphone_call_set_state(call,LinphoneCallRefered,"Refered");
if (lc->vtable.display_status){
{
char *msg=ms_strdup_printf(_("We are transferred to %s"),referto);
lc->vtable.display_status(lc,msg);
linphone_core_notify_display_status(lc,msg);
ms_free(msg);
}
if (call->refer_pending) linphone_core_start_refered_call(lc,call,NULL);
}else if (lc->vtable.refer_received){
lc->vtable.refer_received(lc,referto);
}else {
linphone_core_notify_refer_received(lc,referto);
}
}
@ -1051,8 +1049,8 @@ static bool_t auth_requested(Sal* sal, SalAuthInfo* sai) {
if (fill_auth_info(lc,sai)) {
return TRUE;
} else {
if (lc->vtable.auth_info_requested) {
lc->vtable.auth_info_requested(lc,sai->realm,sai->username,sai->domain);
{
linphone_core_notify_auth_info_requested(lc,sai->realm,sai->username,sai->domain);
if (fill_auth_info(lc,sai)) {
return TRUE;
}
@ -1135,9 +1133,9 @@ static void info_received(SalOp *op, const SalBody *body){
static void subscribe_response(SalOp *op, SalSubscribeStatus status){
LinphoneEvent *lev=(LinphoneEvent*)sal_op_get_user_pointer(op);
const SalErrorInfo *ei=sal_op_get_error_info(op);
if (lev==NULL) return;
if (status==SalSubscribeActive){
linphone_event_set_state(lev,LinphoneSubscriptionActive);
}else if (status==SalSubscribePending){
@ -1153,15 +1151,15 @@ static void subscribe_response(SalOp *op, SalSubscribeStatus status){
static void notify(SalOp *op, SalSubscribeStatus st, const char *eventname, const SalBody *body){
LinphoneEvent *lev=(LinphoneEvent*)sal_op_get_user_pointer(op);
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneContent content;
LinphoneContent content={0};
if (lev==NULL) {
/*out of subscribe notify */
lev=linphone_event_new_with_out_of_dialog_op(lc,op,LinphoneSubscriptionOutgoing,eventname);
}
if (lc->vtable.notify_received){
{
const LinphoneContent *ct=linphone_content_from_sal_body(&content,body);
if (ct) lc->vtable.notify_received(lc,lev,eventname,ct);
if (ct) linphone_core_notify_notify_received(lc,lev,eventname,ct);
}
if (st!=SalSubscribeNone){
linphone_event_set_state(lev,linphone_subscription_state_from_sal(st));
@ -1171,31 +1169,31 @@ static void notify(SalOp *op, SalSubscribeStatus st, const char *eventname, cons
static void subscribe_received(SalOp *op, const char *eventname, const SalBody *body){
LinphoneEvent *lev=(LinphoneEvent*)sal_op_get_user_pointer(op);
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
if (lev==NULL) {
lev=linphone_event_new_with_op(lc,op,LinphoneSubscriptionIncoming,eventname);
linphone_event_set_state(lev,LinphoneSubscriptionIncomingReceived);
}else{
/*subscribe refresh, unhandled*/
}
}
static void subscribe_closed(SalOp *op){
LinphoneEvent *lev=(LinphoneEvent*)sal_op_get_user_pointer(op);
linphone_event_set_state(lev,LinphoneSubscriptionTerminated);
}
static void on_publish_response(SalOp* op){
LinphoneEvent *lev=(LinphoneEvent*)sal_op_get_user_pointer(op);
const SalErrorInfo *ei=sal_op_get_error_info(op);
if (lev==NULL) return;
if (ei->reason==SalReasonNone){
if (!lev->terminating)
linphone_event_set_publish_state(lev,LinphonePublishOk);
else
else
linphone_event_set_publish_state(lev,LinphonePublishCleared);
}else{
if (lev->publish_state==LinphonePublishOk){
@ -1208,9 +1206,9 @@ static void on_publish_response(SalOp* op){
static void on_expire(SalOp *op){
LinphoneEvent *lev=(LinphoneEvent*)sal_op_get_user_pointer(op);
if (lev==NULL) return;
if (linphone_event_get_publish_state(lev)==LinphonePublishOk){
linphone_event_set_publish_state(lev,LinphonePublishExpiring);
}else if (linphone_event_get_subscription_state(lev)==LinphoneSubscriptionActive){

View file

@ -37,26 +37,18 @@
static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage* msg);
#define MULTIPART_BOUNDARY "---------------------------14737809831466499882746641449"
#define FILEPART_HEADER_1 "Content-Disposition: form-data; name=\"File\"; filename=\""
#define FILEPART_HEADER_2 "\"\r\n" \
"Content-Type: "
#define FILEPART_HEADER_3 "\r\n\r\n"
const char *multipart_boundary=MULTIPART_BOUNDARY;
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_upload(void *data, const belle_sip_io_error_event_t *event){
LinphoneChatMessage* msg=(LinphoneChatMessage *)data;
ms_error("I/O Error during file upload to %s - msg [%p] chat room[%p]", msg->chat_room->lc->file_transfer_server, msg, msg->chat_room);
ms_error("I/O Error during file upload to %s - msg [%p] chat room[%p]", linphone_core_get_file_transfer_server(msg->chat_room->lc), msg, msg->chat_room);
if (msg->cb) {
msg->cb(msg, LinphoneChatMessageStateNotDelivered, msg->chat_room->lc);
}
}
static void process_auth_requested_upload(void *data, belle_sip_auth_event_t *event){
LinphoneChatMessage* msg=(LinphoneChatMessage *)data;
ms_error("Error during file upload : auth requested to connect %s - msg [%p] chat room[%p]", msg->chat_room->lc->file_transfer_server, msg, msg->chat_room);
ms_error("Error during file upload : auth requested to connect %s - msg [%p] chat room[%p]", linphone_core_get_file_transfer_server(msg->chat_room->lc), msg, msg->chat_room);
if (msg->cb) {
msg->cb(msg, LinphoneChatMessageStateNotDelivered, msg->chat_room->lc);
}
@ -85,9 +77,7 @@ static void linphone_chat_message_file_transfer_on_progress(belle_sip_body_handl
LinphoneChatMessage* chatMsg=(LinphoneChatMessage *)data;
LinphoneCore *lc = chatMsg->chat_room->lc;
/* call back given by application level */
if (lc->vtable.file_transfer_progress_indication != NULL) {
lc->vtable.file_transfer_progress_indication(lc, chatMsg, chatMsg->file_transfer_information, (size_t)(((double)offset/(double)total)*100.0));
}
linphone_core_notify_file_transfer_progress_indication(lc, chatMsg, chatMsg->file_transfer_information, (size_t)(((double)offset/(double)total)*100.0));
return;
}
@ -107,28 +97,12 @@ static int linphone_chat_message_file_transfer_on_send_body(belle_sip_user_body_
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_filepart_header_size(chatMsg->file_transfer_information->name, content_type)+chatMsg->file_transfer_information->size;
if (offset==0){
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 (offset<end_of_file){
/* if we've not reach the end of file yet, ask for more data*/
if (offset<chatMsg->file_transfer_information->size){
/* get data from call back */
lc->vtable.file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, buf, size);
linphone_core_notify_file_transfer_send(lc, chatMsg, chatMsg->file_transfer_information, buf, size);
}
belle_sip_free(content_type);
return BELLE_SIP_CONTINUE;
}
@ -152,21 +126,29 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co
belle_http_request_listener_t *l;
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_multipart_body_handler_t *bh;
char* ua;
char *content_type;
char *first_part_header;
belle_sip_user_body_handler_t *first_part_bh;
/* create a user body handler to take care of the file */
size_t body_size = msg->file_transfer_information->size+linphone_chat_message_compute_filepart_header_size(msg->file_transfer_information->name, content_type);
/* temporary storage for the Content-disposition header value */
first_part_header = belle_sip_strdup_printf("form-data; name=\"File\"; filename=\"%s\"", msg->file_transfer_information->name);
/* create a user body handler to take care of the file and add the content disposition and content-type headers */
first_part_bh=belle_sip_user_body_handler_new(msg->file_transfer_information->size,NULL,NULL,linphone_chat_message_file_transfer_on_send_body,msg);
belle_sip_body_handler_add_header((belle_sip_body_handler_t *)first_part_bh, belle_sip_header_create("Content-disposition", first_part_header));
belle_sip_free(first_part_header);
belle_sip_body_handler_add_header((belle_sip_body_handler_t *)first_part_bh, (belle_sip_header_t *)belle_sip_header_content_type_create(msg->file_transfer_information->type, msg->file_transfer_information->subtype));
belle_sip_user_body_handler_t *first_part_bh=belle_sip_user_body_handler_new(body_size,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);
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());
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);
uri=belle_generic_uri_parse(linphone_core_get_file_transfer_server(msg->chat_room->lc));
req=belle_http_request_create("POST",
uri,
@ -191,9 +173,6 @@ static void linphone_chat_message_process_response_from_post_file(void *data, co
}
body = belle_sip_message_get_body((belle_sip_message_t *)event->response);
msg->message = ms_strdup(body);
linphone_content_uninit(msg->file_transfer_information);
ms_free(msg->file_transfer_information);
msg->file_transfer_information = NULL;
msg->content_type = ms_strdup("application/vnd.gsma.rcs-ft-http+xml");
_linphone_chat_room_send_message(msg->chat_room, msg);
}
@ -253,37 +232,52 @@ MSList* linphone_core_get_chat_rooms(LinphoneCore *lc) {
return lc->chatrooms;
}
/**
* Create a new chat room for messaging from a sip uri like sip:joe@sip.linphone.org
* @param lc #LinphoneCore object
* @param to destination address for messages
* @return #LinphoneChatRoom where messaging can take place.
*/
LinphoneChatRoom * linphone_core_create_chat_room(LinphoneCore *lc, const char *to){
LinphoneAddress *parsed_url=NULL;
static bool_t linphone_chat_room_matches(LinphoneChatRoom *cr, const LinphoneAddress *from){
return linphone_address_weak_equal(cr->peer_url,from);
}
if ((parsed_url=linphone_core_interpret_url(lc,to))!=NULL){
LinphoneChatRoom *cr=ms_new0(LinphoneChatRoom,1);
cr->lc=lc;
cr->peer=linphone_address_as_string(parsed_url);
cr->peer_url=parsed_url;
lc->chatrooms=ms_list_append(lc->chatrooms,(void *)cr);
return cr;
static void _linphone_chat_room_destroy(LinphoneChatRoom *obj);
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneChatRoom);
BELLE_SIP_INSTANCIATE_VPTR(LinphoneChatRoom, belle_sip_object_t,
(belle_sip_object_destroy_t)_linphone_chat_room_destroy,
NULL, // clone
NULL, // marshal
FALSE
);
static LinphoneChatRoom * _linphone_core_create_chat_room(LinphoneCore *lc, LinphoneAddress *addr) {
LinphoneChatRoom *cr = belle_sip_object_new(LinphoneChatRoom);
cr->lc = lc;
cr->peer = linphone_address_as_string(addr);
cr->peer_url = addr;
lc->chatrooms = ms_list_append(lc->chatrooms, (void *)cr);
return cr;
}
static LinphoneChatRoom * _linphone_core_create_chat_room_from_url(LinphoneCore *lc, const char *to) {
LinphoneAddress *parsed_url = NULL;
if ((parsed_url = linphone_core_interpret_url(lc, to)) != NULL) {
return _linphone_core_create_chat_room(lc, parsed_url);
}
return NULL;
}
bool_t linphone_chat_room_matches(LinphoneChatRoom *cr, const LinphoneAddress *from){
return linphone_address_weak_equal(cr->peer_url,from);
LinphoneChatRoom * _linphone_core_get_chat_room(LinphoneCore *lc, const LinphoneAddress *addr){
LinphoneChatRoom *cr=NULL;
MSList *elem;
for(elem=lc->chatrooms;elem!=NULL;elem=ms_list_next(elem)){
cr=(LinphoneChatRoom*)elem->data;
if (linphone_chat_room_matches(cr,addr)){
break;
}
cr=NULL;
}
return cr;
}
/**
* Create a new chat room for messaging from a sip uri like sip:joe@sip.linphone.org if not already existing, else return exisiting one
* @param lc #LinphoneCore object
* @param to destination address for messages
* @return #LinphoneChatRoom where messaging can take place.
*/
LinphoneChatRoom* linphone_core_get_or_create_chat_room(LinphoneCore* lc, const char* to) {
static LinphoneChatRoom * _linphone_core_get_or_create_chat_room(LinphoneCore* lc, const char* to) {
LinphoneAddress *to_addr=linphone_core_interpret_url(lc,to);
LinphoneChatRoom *ret;
@ -291,17 +285,63 @@ LinphoneChatRoom* linphone_core_get_or_create_chat_room(LinphoneCore* lc, const
ms_error("linphone_core_get_or_create_chat_room(): Cannot make a valid address with %s",to);
return NULL;
}
ret=linphone_core_get_chat_room(lc,to_addr);
ret=_linphone_core_get_chat_room(lc,to_addr);
linphone_address_destroy(to_addr);
if (!ret){
ret=linphone_core_create_chat_room(lc,to);
ret=_linphone_core_create_chat_room_from_url(lc,to);
}
return ret;
}
/**
* Create a new chat room for messaging from a sip uri like sip:joe@sip.linphone.org if not already existing, else return exisiting one
* @param lc #LinphoneCore object
* @param to destination address for messages
* @return #LinphoneChatRoom where messaging can take place.
* @deprecated Use linphone_core_get_chat_room() or linphone_core_get_chat_room_from_uri() instead.
*/
LinphoneChatRoom* linphone_core_get_or_create_chat_room(LinphoneCore* lc, const char* to) {
return _linphone_core_get_or_create_chat_room(lc, to);
}
/**
* Create a new chat room for messaging from a sip uri like sip:joe@sip.linphone.org
* @param lc #LinphoneCore object
* @param to destination address for messages
* @return #LinphoneChatRoom where messaging can take place.
* @deprecated Use linphone_core_get_chat_room() or linphone_core_get_chat_room_from_uri() instead.
*/
LinphoneChatRoom * linphone_core_create_chat_room(LinphoneCore *lc, const char *to) {
return _linphone_core_get_or_create_chat_room(lc, to);
}
/**
* Get a chat room whose peer is the supplied address. If it does not exist yet, it will be created.
* @param lc the linphone core
* @param addr a linphone address.
* @returns #LinphoneChatRoom where messaging can take place.
**/
LinphoneChatRoom *linphone_core_get_chat_room(LinphoneCore *lc, const LinphoneAddress *addr){
LinphoneChatRoom *ret = _linphone_core_get_chat_room(lc, addr);
if (!ret) {
ret = _linphone_core_create_chat_room(lc, linphone_address_clone(addr));
}
return ret;
}
/**
* Get a chat room for messaging from a sip uri like sip:joe@sip.linphone.org. If it does not exist yet, it will be created.
* @param lc The linphone core
* @param to The destination address for messages.
* @returns #LinphoneChatRoom where messaging can take place.
**/
LinphoneChatRoom * linphone_core_get_chat_room_from_uri(LinphoneCore *lc, const char *to) {
return _linphone_core_get_or_create_chat_room(lc, to);
}
static void linphone_chat_room_delete_composing_idle_timer(LinphoneChatRoom *cr) {
if (cr->composing_idle_timer) {
if(cr->lc->sal)
if(cr-> lc && cr->lc->sal)
sal_cancel_timer(cr->lc->sal, cr->composing_idle_timer);
belle_sip_object_unref(cr->composing_idle_timer);
cr->composing_idle_timer = NULL;
@ -310,7 +350,7 @@ static void linphone_chat_room_delete_composing_idle_timer(LinphoneChatRoom *cr)
static void linphone_chat_room_delete_composing_refresh_timer(LinphoneChatRoom *cr) {
if (cr->composing_refresh_timer) {
if(cr->lc->sal)
if(cr->lc && cr->lc->sal)
sal_cancel_timer(cr->lc->sal, cr->composing_refresh_timer);
belle_sip_object_unref(cr->composing_refresh_timer);
cr->composing_refresh_timer = NULL;
@ -319,29 +359,55 @@ static void linphone_chat_room_delete_composing_refresh_timer(LinphoneChatRoom *
static void linphone_chat_room_delete_remote_composing_refresh_timer(LinphoneChatRoom *cr) {
if (cr->remote_composing_refresh_timer) {
if(cr->lc->sal)
if(cr->lc && cr->lc->sal)
sal_cancel_timer(cr->lc->sal, cr->remote_composing_refresh_timer);
belle_sip_object_unref(cr->remote_composing_refresh_timer);
cr->remote_composing_refresh_timer = NULL;
}
}
/**
* Destroy a LinphoneChatRoom.
* @param cr #LinphoneChatRoom object
*/
void linphone_chat_room_destroy(LinphoneChatRoom *cr){
LinphoneCore *lc=cr->lc;
static void _linphone_chat_room_destroy(LinphoneChatRoom *cr){
ms_list_free_with_data(cr->transient_messages, (void (*)(void*))linphone_chat_message_unref);
linphone_chat_room_delete_composing_idle_timer(cr);
linphone_chat_room_delete_composing_refresh_timer(cr);
linphone_chat_room_delete_remote_composing_refresh_timer(cr);
lc->chatrooms=ms_list_remove(lc->chatrooms,(void *) cr);
if (cr->lc != NULL) {
cr->lc->chatrooms=ms_list_remove(cr->lc->chatrooms,(void *) cr);
}
linphone_address_destroy(cr->peer_url);
ms_free(cr->peer);
ms_free(cr);
}
/**
* Destroy a LinphoneChatRoom.
* @param cr #LinphoneChatRoom object
* @deprecated Use linphone_chat_room_unref() instead.
*/
void linphone_chat_room_destroy(LinphoneChatRoom *cr) {
linphone_chat_room_unref(cr);
}
void linphone_chat_room_release(LinphoneChatRoom *cr) {
cr->lc = NULL;
linphone_chat_room_unref(cr);
}
LinphoneChatRoom * linphone_chat_room_ref(LinphoneChatRoom *cr) {
belle_sip_object_ref(cr);
return cr;
}
void linphone_chat_room_unref(LinphoneChatRoom *cr) {
belle_sip_object_unref(cr);
}
void * linphone_chat_room_get_user_data(const LinphoneChatRoom *cr) {
return cr->user_data;
}
void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void *ud) {
cr->user_data = ud;
}
static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage* msg){
@ -352,14 +418,14 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM
time_t t=time(NULL);
linphone_chat_message_ref(msg);
/* Check if we shall upload a file to a server */
if (msg->file_transfer_information != NULL) {
if (msg->file_transfer_information != NULL && msg->content_type == NULL) {
/* open a transaction with the server and send an empty request(RCS5.1 section 3.5.4.8.3.1) */
belle_http_request_listener_callbacks_t cbs={0};
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);
uri=belle_generic_uri_parse(linphone_core_get_file_transfer_server(cr->lc));
req=belle_http_request_create("POST",
uri,
@ -409,6 +475,9 @@ static void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatM
sal_text_send(op, identity, cr->peer,msg->message);
} else {
sal_message_send(op, identity, cr->peer, msg->content_type, msg->message);
// Remove the message to prevent the xml from the file uplaod to be stored in the database
ms_free(msg->message);
msg->message = NULL;
}
}
msg->dir=LinphoneChatMessageOutgoing;
@ -439,31 +508,10 @@ void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg) {
void linphone_chat_room_message_received(LinphoneChatRoom *cr, LinphoneCore *lc, LinphoneChatMessage *msg){
if (msg->message)
//legacy API
if (lc->vtable.text_received!=NULL) lc->vtable.text_received(lc, cr, msg->from, msg->message);
if (lc->vtable.message_received!=NULL) lc->vtable.message_received(lc, cr,msg);
if (cr->lc->vtable.is_composing_received != NULL) {
cr->remote_is_composing = LinphoneIsComposingIdle;
cr->lc->vtable.is_composing_received(cr->lc, cr);
}
}
/**
* Retrieve an existing chat room whose peer is the supplied address, if exists.
* @param lc the linphone core
* @param addr a linphone address.
* @returns the matching chatroom, or NULL if no such chatroom exists.
**/
LinphoneChatRoom *linphone_core_get_chat_room(LinphoneCore *lc, const LinphoneAddress *addr){
LinphoneChatRoom *cr=NULL;
MSList *elem;
for(elem=lc->chatrooms;elem!=NULL;elem=ms_list_next(elem)){
cr=(LinphoneChatRoom*)elem->data;
if (linphone_chat_room_matches(cr,addr)){
break;
}
cr=NULL;
}
return cr;
linphone_core_notify_text_message_received(lc, cr, msg->from, msg->message);
linphone_core_notify_message_received(lc, cr,msg);
cr->remote_is_composing = LinphoneIsComposingIdle;
linphone_core_notify_is_composing_received(cr->lc, cr);
}
void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessage *sal_msg){
@ -567,6 +615,7 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag
linphone_address_destroy(addr);
msg->storage_id=linphone_chat_message_store(msg);
linphone_chat_room_message_received(cr,lc,msg);
linphone_chat_message_unref(msg);
ms_free(cleanfrom);
ms_free(from);
}
@ -576,8 +625,7 @@ static int linphone_chat_room_remote_refresh_composing_expired(void *data, unsig
belle_sip_object_unref(cr->remote_composing_refresh_timer);
cr->remote_composing_refresh_timer = NULL;
cr->remote_is_composing = LinphoneIsComposingIdle;
if (cr->lc->vtable.is_composing_received != NULL)
cr->lc->vtable.is_composing_received(cr->lc, cr);
linphone_core_notify_is_composing_received(cr->lc, cr);
return BELLE_SIP_STOP;
}
@ -622,8 +670,7 @@ static void process_im_is_composing_notification(LinphoneChatRoom *cr, xmlparsin
}
cr->remote_is_composing = state;
if (cr->lc->vtable.is_composing_received != NULL)
cr->lc->vtable.is_composing_received(cr->lc, cr);
linphone_core_notify_is_composing_received(cr->lc, cr);
}
}
@ -665,20 +712,6 @@ LinphoneCore* linphone_chat_room_get_core(LinphoneChatRoom *cr){
return cr->lc;
}
/**
* Assign a user pointer to the chat room.
**/
void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void * ud){
cr->user_data=ud;
}
/**
* Retrieve the user pointer associated with the chat room.
**/
void * linphone_chat_room_get_user_data(LinphoneChatRoom *cr){
return cr->user_data;
}
/**
* get peer address \link linphone_core_create_chat_room() associated to \endlink this #LinphoneChatRoom
* @param cr #LinphoneChatRoom object
@ -995,9 +1028,7 @@ static void on_recv_body(belle_sip_user_body_handler_t *bh, belle_sip_message_t
return;
}
/* call back given by application level */
if (lc->vtable.file_transfer_recv != NULL) {
lc->vtable.file_transfer_recv(lc, chatMsg, chatMsg->file_transfer_information, (char *)buffer, size);
}
linphone_core_notify_file_transfer_recv(lc, chatMsg, chatMsg->file_transfer_information, (char *)buffer, size);
return;
}
@ -1062,9 +1093,7 @@ static void linphone_chat_process_response_from_get_file(void *data, const belle
LinphoneChatMessage* chatMsg=(LinphoneChatMessage *)data;
LinphoneCore *lc = chatMsg->chat_room->lc;
/* file downloaded succesfully, call again the callback with size at zero */
if (lc->vtable.file_transfer_recv != NULL) {
lc->vtable.file_transfer_recv(lc, chatMsg, chatMsg->file_transfer_information, NULL, 0);
}
linphone_core_notify_file_transfer_recv(lc, chatMsg, chatMsg->file_transfer_information, NULL, 0);
}
}
}
@ -1109,7 +1138,7 @@ void linphone_chat_message_start_file_download(LinphoneChatMessage *message, Lin
* @param msg #LinphoneChatMessage
*/
void linphone_chat_room_cancel_file_transfer(LinphoneChatMessage *msg) {
ms_message("Cancelled file transfer %s - msg [%p] chat room[%p]", (msg->external_body_url==NULL)?msg->chat_room->lc->file_transfer_server:msg->external_body_url, msg, msg->chat_room);
ms_message("Cancelled file transfer %s - msg [%p] chat room[%p]", (msg->external_body_url==NULL)?linphone_core_get_file_transfer_server(msg->chat_room->lc):msg->external_body_url, msg, msg->chat_room);
/* TODO: here we shall call the cancel http request from bellesip API when it is available passing msg->http_request */
/* waiting for this API, just set to NULL the reference to the request in the message and any request */
msg->http_request = NULL;
@ -1121,39 +1150,39 @@ void linphone_chat_room_cancel_file_transfer(LinphoneChatMessage *msg) {
/**
* Set origin of the message
*@param message #LinphoneChatMessage obj
*@param from #LinphoneAddress origin of this message (copied)
* @param[in] message #LinphoneChatMessage obj
* @param[in] from #LinphoneAddress origin of this message (copied)
*/
void linphone_chat_message_set_from(LinphoneChatMessage* message, const LinphoneAddress* from) {
void linphone_chat_message_set_from_address(LinphoneChatMessage* message, const LinphoneAddress* from) {
if(message->from) linphone_address_destroy(message->from);
message->from=linphone_address_clone(from);
}
/**
* Get origin of the message
*@param message #LinphoneChatMessage obj
*@return #LinphoneAddress
* @param[in] message #LinphoneChatMessage obj
* @return #LinphoneAddress
*/
const LinphoneAddress* linphone_chat_message_get_from(const LinphoneChatMessage* message) {
const LinphoneAddress* linphone_chat_message_get_from_address(const LinphoneChatMessage* message) {
return message->from;
}
/**
* Set destination of the message
*@param message #LinphoneChatMessage obj
*@param to #LinphoneAddress destination of this message (copied)
* @param[in] message #LinphoneChatMessage obj
* @param[in] to #LinphoneAddress destination of this message (copied)
*/
void linphone_chat_message_set_to(LinphoneChatMessage* message, const LinphoneAddress* to) {
void linphone_chat_message_set_to_address(LinphoneChatMessage* message, const LinphoneAddress* to) {
if(message->to) linphone_address_destroy(message->to);
message->to=linphone_address_clone(to);
}
/**
* Get destination of the message
*@param message #LinphoneChatMessage obj
*@return #LinphoneAddress
* @param[in] message #LinphoneChatMessage obj
* @return #LinphoneAddress
*/
const LinphoneAddress* linphone_chat_message_get_to(const LinphoneChatMessage* message){
const LinphoneAddress* linphone_chat_message_get_to_address(const LinphoneChatMessage* message){
if (message->to) return message->to;
if (message->dir==LinphoneChatMessageOutgoing){
return message->chat_room->peer_url;
@ -1292,6 +1321,7 @@ static void _linphone_chat_message_destroy(LinphoneChatMessage* msg) {
linphone_content_uninit(msg->file_transfer_information);
ms_free(msg->file_transfer_information);
}
ms_message("LinphoneChatMessage [%p] destroyed.",msg);
}
@ -1347,7 +1377,6 @@ LinphoneChatMessage* linphone_chat_room_create_file_transfer_message(LinphoneCha
linphone_chat_message_set_from(msg, linphone_address_new(linphone_core_get_identity(cr->lc)));
msg->content_type=NULL; /* this will be set to application/vnd.gsma.rcs-ft-http+xml when we will transfer the xml reply from server to the peers */
msg->http_request=NULL; /* this will store the http request during file upload to the server */
return msg;
}

View file

@ -41,6 +41,7 @@ static void conference_check_init(LinphoneConference *ctx, int samplerate){
MSAudioConferenceParams params;
params.samplerate=samplerate;
ctx->conf=ms_audio_conference_new(&params);
ctx->terminated=FALSE;
}
}
@ -74,7 +75,7 @@ void linphone_core_conference_check_uninit(LinphoneCore *lc){
if (ctx->conf){
int remote_count=remote_participants_count(ctx);
ms_message("conference_check_uninit(): size=%i",linphone_conference_get_size(ctx));
if (remote_count==1){
if (remote_count==1 && !ctx->terminated){
convert_conference_to_call(lc);
}
if (remote_count==0){
@ -98,7 +99,7 @@ void linphone_call_add_to_conf(LinphoneCall *call, bool_t muted){
LinphoneCore *lc=call->core;
LinphoneConference *conf=&lc->conf_ctx;
MSAudioEndpoint *ep;
call->params.has_video = FALSE;
call->params->has_video = FALSE;
call->camera_enabled = FALSE;
ep=ms_audio_endpoint_get_from_stream(call->audiostream,TRUE);
ms_audio_conference_add_member(conf->conf,ep);
@ -184,15 +185,15 @@ float linphone_core_get_conference_local_input_volume(LinphoneCore *lc){
int linphone_core_add_to_conference(LinphoneCore *lc, LinphoneCall *call){
LinphoneConference *conf=&lc->conf_ctx;
if (call->current_params.in_conference){
if (call->current_params->in_conference){
ms_error("Already in conference");
return -1;
}
conference_check_init(&lc->conf_ctx, lp_config_get_int(lc->config, "sound","conference_rate",16000));
if (call->state==LinphoneCallPaused){
call->params.in_conference=TRUE;
call->params.has_video=FALSE;
call->params->in_conference=TRUE;
call->params->has_video=FALSE;
linphone_core_resume_call(lc,call);
}else if (call->state==LinphoneCallStreamsRunning){
LinphoneCallParams *params=linphone_call_params_copy(linphone_call_get_current_params(call));
@ -222,8 +223,8 @@ static int remove_from_conference(LinphoneCore *lc, LinphoneCall *call, bool_t a
int err=0;
char *str;
if (!call->current_params.in_conference){
if (call->params.in_conference){
if (!call->current_params->in_conference){
if (call->params->in_conference){
ms_warning("Not (yet) in conference, be patient");
return -1;
}else{
@ -231,7 +232,7 @@ static int remove_from_conference(LinphoneCore *lc, LinphoneCall *call, bool_t a
return -1;
}
}
call->params.in_conference=FALSE;
call->params->in_conference=FALSE;
str=linphone_call_get_remote_address_as_string(call);
ms_message("%s will be removed from conference", str);
@ -251,7 +252,6 @@ static int remove_from_conference(LinphoneCore *lc, LinphoneCall *call, bool_t a
ms_message("Pausing call to actually remove from conference");
err=_linphone_core_pause_call(lc,call);
}
return err;
}
@ -267,7 +267,7 @@ static int convert_conference_to_call(LinphoneCore *lc){
while (calls) {
LinphoneCall *rc=(LinphoneCall*)calls->data;
calls=calls->next;
if (rc->params.in_conference) { // not using current_param
if (rc->params->in_conference) { // not using current_param
bool_t active_after_removed=linphone_core_is_in_conference(lc);
err=remove_from_conference(lc, rc, active_after_removed);
break;
@ -370,7 +370,7 @@ int linphone_core_add_all_to_conference(LinphoneCore *lc) {
while (calls) {
LinphoneCall *call=(LinphoneCall*)calls->data;
calls=calls->next;
if (!call->current_params.in_conference) {
if (!call->current_params->in_conference) {
linphone_core_add_to_conference(lc, call);
}
}
@ -388,10 +388,13 @@ int linphone_core_add_all_to_conference(LinphoneCore *lc) {
**/
int linphone_core_terminate_conference(LinphoneCore *lc) {
MSList *calls=lc->calls;
LinphoneConference *conf=&lc->conf_ctx;
conf->terminated=TRUE;
while (calls) {
LinphoneCall *call=(LinphoneCall*)calls->data;
calls=calls->next;
if (call->current_params.in_conference) {
if (call->current_params->in_conference) {
linphone_core_terminate_call(lc, call);
}
}

View file

@ -89,13 +89,10 @@ LinphoneEvent *linphone_event_new_with_out_of_dialog_op(LinphoneCore *lc, SalOp
}
void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState state){
LinphoneCore *lc=lev->lc;
if (lev->subscription_state!=state){
ms_message("LinphoneEvent [%p] moving to subscription state %s",lev,linphone_subscription_state_to_string(state));
lev->subscription_state=state;
if (lc->vtable.subscription_state_changed){
lc->vtable.subscription_state_changed(lev->lc,lev,state);
}
linphone_core_notify_subscription_state_changed(lev->lc,lev,state);
if (state==LinphoneSubscriptionTerminated){
linphone_event_unref(lev);
}
@ -103,13 +100,10 @@ void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState stat
}
void linphone_event_set_publish_state(LinphoneEvent *lev, LinphonePublishState state){
LinphoneCore *lc=lev->lc;
if (lev->publish_state!=state){
ms_message("LinphoneEvent [%p] moving to publish state %s",lev,linphone_publish_state_to_string(state));
lev->publish_state=state;
if (lc->vtable.publish_state_changed){
lc->vtable.publish_state_changed(lev->lc,lev,state);
}
linphone_core_notify_publish_state_changed(lev->lc,lev,state);
switch(state){
case LinphonePublishCleared:
linphone_event_unref(lev);

77
coreapi/fileplayer.c Normal file
View file

@ -0,0 +1,77 @@
#include "private.h"
#include <mediastreamer2/fileplayer.h>
#include <mediastreamer2/mssndcard.h>
static int file_player_open(LinphonePlayer *obj, const char *filename);
static int file_player_start(LinphonePlayer *obj);
static int file_player_pause(LinphonePlayer *obj);
static int file_player_seek(LinphonePlayer *obj, int time_ms);
static MSPlayerState file_player_get_state(LinphonePlayer *obj);
static int file_player_get_duration(LinphonePlayer *obj);
static int file_player_get_current_position(LinphonePlayer *obj);
static void file_player_close(LinphonePlayer *obj);
static void file_player_eof_callback(void *user_data);
LinphonePlayer *linphone_core_create_file_player(LinphoneCore *lc, MSSndCard *snd_card, const char *video_out) {
LinphonePlayer *obj = ms_new0(LinphonePlayer, 1);
if(snd_card == NULL) snd_card = lc->sound_conf.play_sndcard;
if(video_out == NULL) video_out = linphone_core_get_video_display_filter(lc);
obj->impl = ms_file_player_new(snd_card, video_out);
obj->open = file_player_open;
obj->start = file_player_start;
obj->pause = file_player_pause;
obj->seek = file_player_seek;
obj->get_state = file_player_get_state;
obj->get_duration = file_player_get_duration;
obj->get_position = file_player_get_current_position;
obj->close = file_player_close;
ms_file_player_set_eof_callback((MSFilePlayer *)obj->impl, file_player_eof_callback, obj);
return obj;
}
void linphone_file_player_destroy(LinphonePlayer *obj) {
ms_file_player_free((MSFilePlayer *)obj->impl);
ms_free(obj);
}
bool_t linphone_file_player_matroska_supported(void) {
return ms_file_player_matroska_supported();
}
static int file_player_open(LinphonePlayer *obj, const char *filename) {
return ms_file_player_open((MSFilePlayer *)obj->impl, filename) ? 0 : -1;
}
static int file_player_start(LinphonePlayer *obj) {
return ms_file_player_start((MSFilePlayer *)obj->impl) ? 0 : -1;
}
static int file_player_pause(LinphonePlayer *obj) {
ms_file_player_pause((MSFilePlayer *)obj->impl);
return 0;
}
static int file_player_seek(LinphonePlayer *obj, int time_ms) {
return ms_file_player_seek((MSFilePlayer *)obj->impl, time_ms) ? 0 : -1;
}
static MSPlayerState file_player_get_state(LinphonePlayer *obj) {
return ms_file_player_get_state((MSFilePlayer *)obj->impl);
}
static int file_player_get_duration(LinphonePlayer *obj) {
return ms_file_player_get_duration((MSFilePlayer *)obj->impl);
}
static int file_player_get_current_position(LinphonePlayer *obj) {
return ms_file_player_get_current_position((MSFilePlayer *)obj->impl);
}
static void file_player_close(LinphonePlayer *obj) {
ms_file_player_close((MSFilePlayer *)obj->impl);
}
static void file_player_eof_callback(void *user_data) {
LinphonePlayer *obj = (LinphonePlayer *)user_data;
obj->cb(obj, obj->user_data);
}

View file

@ -253,8 +253,7 @@ static void linphone_friend_invalidate_subscription(LinphoneFriend *lf){
linphone_presence_model_unref(lf->presence);
}
lf->presence = linphone_presence_model_new_with_activity(LinphonePresenceActivityOffline,"unknown activity");
if (lc->vtable.notify_presence_received)
lc->vtable.notify_presence_received(lc,lf);
linphone_core_notify_notify_presence_received(lc,lf);
}
lf->initial_subscribes_sent=FALSE;
}

View file

@ -26,9 +26,17 @@ if(DOXYGEN_FOUND)
if(DOXYGEN_DOT_FOUND)
set(top_srcdir ${CMAKE_SOURCE_DIR})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
add_custom_target(doc ALL
${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
file(GLOB DOC_INPUT_FILES
[^.]*.c
[^.]*.dox
../[^.]*.h
../[^.]*.c
)
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/doc/html/index.html"
COMMAND ${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile ${DOC_INPUT_FILES}
)
add_custom_target(doc ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/doc/html/index.html")
install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/doc/html" "${CMAKE_CURRENT_BINARY_DIR}/doc/xml"
DESTINATION "${CMAKE_INSTALL_PREFIX}/share/doc/linphone-${LINPHONE_VERSION}")
else()

View file

@ -1,7 +1,7 @@
EXTRA_DIST=Doxyfile.in doxygen.dox
SOURCES=doxygen.dox $(top_srcdir)/coreapi/help/*.c $(top_srcdir)/coreapi/*.c $(top_srcdir)/coreapi/*.h
SOURCES=doxygen.dox $(top_srcdir)/coreapi/help/*.c $(top_srcdir)/coreapi/*.c $(top_srcdir)/coreapi/*.h
# html doc
@ -84,6 +84,7 @@ filetransfer_LDADD=$(helloworld_LDADD)
AM_CFLAGS=\
-I$(top_srcdir)/coreapi \
$(STRICT_OPTIONS) \
$(STRICT_OPTIONS_CC) \
-DIN_LINPHONE \
$(ORTP_CFLAGS) \
$(MEDIASTREAMER_CFLAGS) \
@ -98,4 +99,4 @@ AM_CFLAGS=\
tutodir=$(datadir)/tutorials/linphone
tuto_DATA=$(LINPHONE_TUTOS)
endif
endif

View file

@ -1,7 +1,7 @@
/*
buddy_status
Copyright (C) 2010 Belledonne Communications SARL
Copyright (C) 2010 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
@ -73,7 +73,7 @@ static void new_subscription_requested (LinphoneCore *lc, LinphoneFriend *frien
* Registration state notification callback
*/
static void registration_state_changed(struct _LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const char *message){
printf("New registration state %s for user id [%s] at proxy [%s]\n"
printf("New registration state %s for user id [%s] at proxy [%s]"
,linphone_registration_state_to_string(cstate)
,linphone_proxy_config_get_identity(cfg)
,linphone_proxy_config_get_addr(cfg));
@ -87,6 +87,8 @@ int main(int argc, char *argv[]){
char* identity=NULL;
char* password=NULL;
LinphoneFriend* my_friend=NULL;
/* takes sip uri identity from the command line arguments */
if (argc>1){
dest_friend=argv[1];
@ -104,7 +106,7 @@ int main(int argc, char *argv[]){
#ifdef DEBUG
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
#endif
/*
/*
Fill the LinphoneCoreVTable with application callbacks.
All are optional. Here we only use the both notify_presence_received and new_subscription_requested callbacks
in order to get notifications about friend status.
@ -123,11 +125,11 @@ int main(int argc, char *argv[]){
LinphoneProxyConfig* proxy_cfg = linphone_proxy_config_new();
/*parse identity*/
LinphoneAddress *from = linphone_address_new(identity);
LinphoneAuthInfo *info;
if (from==NULL){
printf("%s not a valid sip uri, must be like sip:toto@sip.linphone.org \n",identity);
goto end;
}
LinphoneAuthInfo *info;
if (password!=NULL){
info=linphone_auth_info_new(linphone_address_get_username(from),NULL,password,NULL,NULL,NULL); /*create authentication structure from identity*/
linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/
@ -152,7 +154,6 @@ int main(int argc, char *argv[]){
while( running && linphone_proxy_config_get_state(proxy_cfg) == LinphoneRegistrationProgress);
}
LinphoneFriend* my_friend=NULL;
if (dest_friend) {
my_friend = linphone_friend_new_with_address(dest_friend); /*creates friend object from dest*/

View file

@ -1,7 +1,7 @@
/*
linphone
Copyright (C) 2010 Belledonne Communications SARL
Copyright (C) 2010 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
@ -55,7 +55,7 @@ int main(int argc, char *argv[]){
LinphoneCoreVTable vtable={0};
char* dest_friend=NULL;
LinphoneChatRoom* chat_room;
/* takes sip uri identity from the command line arguments */
if (argc>1){
@ -67,7 +67,7 @@ int main(int argc, char *argv[]){
#ifdef DEBUG
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
#endif
/*
/*
Fill the LinphoneCoreVTable with application callbacks.
All are optional. Here we only use the text_received callback
in order to get notifications about incoming message.
@ -81,7 +81,7 @@ int main(int argc, char *argv[]){
/*Next step is to create a chat root*/
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(lc,dest_friend);
chat_room = linphone_core_create_chat_room(lc,dest_friend);
linphone_chat_room_send_message(chat_room,"Hello world"); /*sending message*/

View file

@ -1,7 +1,7 @@
/*
linphone
Copyright (C) 2010 Belledonne Communications SARL
Copyright (C) 2010 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
@ -144,6 +144,10 @@ int main(int argc, char *argv[]){
const char* dest_friend=NULL;
int i;
const char* big_file_content="big file";
LinphoneChatRoom* chat_room;
LinphoneContent content;
LinphoneChatMessage* chat_message;
/*seting dummy file content to something*/
for (i=0;i<sizeof(big_file);i+=strlen(big_file_content))
memcpy(big_file+i, big_file_content, strlen(big_file_content));
@ -156,7 +160,7 @@ int main(int argc, char *argv[]){
#ifdef DEBUG
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
#endif
/*
/*
Fill the LinphoneCoreVTable with application callbacks.
All are optional. Here we only use the file_transfer_received callback
in order to get notifications about incoming file receive, file_transfer_send to feed file to be transfered
@ -183,9 +187,8 @@ int main(int argc, char *argv[]){
/*Next step is to create a chat room*/
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(lc,dest_friend);
chat_room = linphone_core_create_chat_room(lc,dest_friend);
LinphoneContent content;
memset(&content,0,sizeof(content));
content.type="text";
content.subtype="plain";
@ -193,7 +196,7 @@ int main(int argc, char *argv[]){
content.name = "bigfile.txt";
/*now create a chat message with custom content*/
LinphoneChatMessage* chat_message = linphone_chat_room_create_file_transfer_message(chat_room,&content);
chat_message = linphone_chat_room_create_file_transfer_message(chat_room,&content);
if (chat_message == NULL) {
printf("returned message is null\n");
}

View file

@ -18,6 +18,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.linphone.core.tutorials;
import java.nio.ByteBuffer;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneCall.State;
@ -165,7 +167,7 @@ public class TutorialBuddyStatus implements LinphoneCoreListener {
}
// create proxy config
LinphoneProxyConfig proxyCfg = lcFactory.createProxyConfig(mySipAddress, domain, null, true);
LinphoneProxyConfig proxyCfg = lc.createProxyConfig(mySipAddress, domain, null, true);
proxyCfg.enablePublish(true);
lc.addProxyConfig(proxyCfg); // add it to linphone
lc.setDefaultProxyConfig(proxyCfg);
@ -300,5 +302,24 @@ public class TutorialBuddyStatus implements LinphoneCoreListener {
}
@Override
public void fileTransferProgressIndication(LinphoneCore lc,
LinphoneChatMessage message, LinphoneContent content, int progress) {
// TODO Auto-generated method stub
}
@Override
public void fileTransferRecv(LinphoneCore lc, LinphoneChatMessage message,
LinphoneContent content, byte[] buffer, int size) {
// TODO Auto-generated method stub
}
@Override
public int fileTransferSend(LinphoneCore lc, LinphoneChatMessage message,
LinphoneContent content, ByteBuffer buffer, int size) {
// TODO Auto-generated method stub
return 0;
}
}

View file

@ -18,6 +18,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.linphone.core.tutorials;
import java.nio.ByteBuffer;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneCall.State;
@ -218,5 +220,26 @@ public class TutorialChatRoom implements LinphoneCoreListener, LinphoneChatMessa
}
@Override
public void fileTransferProgressIndication(LinphoneCore lc,
LinphoneChatMessage message, LinphoneContent content, int progress) {
// TODO Auto-generated method stub
}
@Override
public void fileTransferRecv(LinphoneCore lc, LinphoneChatMessage message,
LinphoneContent content, byte[] buffer, int size) {
// TODO Auto-generated method stub
}
@Override
public int fileTransferSend(LinphoneCore lc, LinphoneChatMessage message,
LinphoneContent content, ByteBuffer buffer, int size) {
// TODO Auto-generated method stub
return 0;
}
}

View file

@ -18,6 +18,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.linphone.core.tutorials;
import java.nio.ByteBuffer;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneCallStats;
@ -220,5 +222,26 @@ public class TutorialHelloWorld implements LinphoneCoreListener {
}
@Override
public void fileTransferProgressIndication(LinphoneCore lc,
LinphoneChatMessage message, LinphoneContent content, int progress) {
// TODO Auto-generated method stub
}
@Override
public void fileTransferRecv(LinphoneCore lc, LinphoneChatMessage message,
LinphoneContent content, byte[] buffer, int size) {
// TODO Auto-generated method stub
}
@Override
public int fileTransferSend(LinphoneCore lc, LinphoneChatMessage message,
LinphoneContent content, ByteBuffer buffer, int size) {
// TODO Auto-generated method stub
return 0;
}
}

View file

@ -18,14 +18,19 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.linphone.core.tutorials;
import java.nio.ByteBuffer;
import org.linphone.core.LinphoneAddress;
import org.linphone.core.LinphoneCall;
import org.linphone.core.LinphoneCall.State;
import org.linphone.core.LinphoneCallStats;
import org.linphone.core.LinphoneChatMessage;
import org.linphone.core.LinphoneChatRoom;
import org.linphone.core.LinphoneContent;
import org.linphone.core.LinphoneCore;
import org.linphone.core.LinphoneCore.EcCalibratorStatus;
import org.linphone.core.LinphoneCore.GlobalState;
import org.linphone.core.LinphoneCore.RegistrationState;
import org.linphone.core.LinphoneCore.RemoteProvisioningState;
import org.linphone.core.LinphoneCoreException;
import org.linphone.core.LinphoneCoreFactory;
@ -34,9 +39,6 @@ import org.linphone.core.LinphoneEvent;
import org.linphone.core.LinphoneFriend;
import org.linphone.core.LinphoneInfoMessage;
import org.linphone.core.LinphoneProxyConfig;
import org.linphone.core.LinphoneCall.State;
import org.linphone.core.LinphoneCore.GlobalState;
import org.linphone.core.LinphoneCore.RegistrationState;
import org.linphone.core.PublishState;
import org.linphone.core.SubscriptionState;
@ -136,7 +138,7 @@ public class TutorialRegistration implements LinphoneCoreListener {
}
// create proxy config
LinphoneProxyConfig proxyCfg = lcFactory.createProxyConfig(sipAddress, domain, null, true);
LinphoneProxyConfig proxyCfg = lc.createProxyConfig(sipAddress, domain, null, true);
proxyCfg.setExpires(2000);
lc.addProxyConfig(proxyCfg); // add it to linphone
lc.setDefaultProxyConfig(proxyCfg);
@ -251,6 +253,27 @@ public class TutorialRegistration implements LinphoneCoreListener {
}
@Override
public void fileTransferProgressIndication(LinphoneCore lc,
LinphoneChatMessage message, LinphoneContent content, int progress) {
// TODO Auto-generated method stub
}
@Override
public void fileTransferRecv(LinphoneCore lc, LinphoneChatMessage message,
LinphoneContent content, byte[] buffer, int size) {
// TODO Auto-generated method stub
}
@Override
public int fileTransferSend(LinphoneCore lc, LinphoneChatMessage message,
LinphoneContent content, ByteBuffer buffer, int size) {
// TODO Auto-generated method stub
return 0;
}
}

View file

@ -1,7 +1,7 @@
/*
linphone
Copyright (C) 2013 Belledonne Communications SARL
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
@ -89,6 +89,10 @@ int main(int argc, char *argv[]){
char* identity=NULL;
char* password=NULL;
int i;
LinphoneProxyConfig* proxy_cfg;
LinphoneAddress *from;
LinphoneAuthInfo *info;
const char* server_addr;
/* takes sip uri identity from the command line arguments */
if (argc>1){
@ -105,7 +109,7 @@ int main(int argc, char *argv[]){
#ifdef DEBUG
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
#endif
/*
/*
Fill the LinphoneCoreVTable with application callbacks.
All are optional. Here we only use the registration_state_changed callbacks
in order to get notifications about the progress of the registration.
@ -118,30 +122,28 @@ int main(int argc, char *argv[]){
*/
lc=linphone_core_new(&vtable,NULL,NULL,data);
LinphoneProxyConfig* proxy_cfg;
/*create proxy config*/
proxy_cfg = linphone_proxy_config_new();
/*parse identity*/
LinphoneAddress *from = linphone_address_new(identity);
from = linphone_address_new(identity);
if (from==NULL){
printf("%s not a valid sip uri, must be like sip:toto@sip.linphone.org \n",identity);
goto end;
}
LinphoneAuthInfo *info;
if (password!=NULL){
info=linphone_auth_info_new(linphone_address_get_username(from),NULL,password,NULL,NULL,NULL); /*create authentication structure from identity*/
linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/
}
if (password!=NULL){
info=linphone_auth_info_new(linphone_address_get_username(from),NULL,password,NULL,NULL,NULL); /*create authentication structure from identity*/
linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/
}
// configure proxy entries
linphone_proxy_config_set_identity(proxy_cfg,identity); /*set identity with user name and domain*/
const char* server_addr = linphone_address_get_domain(from); /*extract domain address from identity*/
linphone_proxy_config_set_server_addr(proxy_cfg,server_addr); /* we assume domain = proxy server address*/
linphone_proxy_config_enable_register(proxy_cfg,TRUE); /*activate registration for this proxy config*/
linphone_address_destroy(from); /*release resource*/
// configure proxy entries
linphone_proxy_config_set_identity(proxy_cfg,identity); /*set identity with user name and domain*/
server_addr = linphone_address_get_domain(from); /*extract domain address from identity*/
linphone_proxy_config_set_server_addr(proxy_cfg,server_addr); /* we assume domain = proxy server address*/
linphone_proxy_config_enable_register(proxy_cfg,TRUE); /*activate registration for this proxy config*/
linphone_address_destroy(from); /*release resource*/
linphone_core_add_proxy_config(lc,proxy_cfg); /*add proxy config to linphone core*/
linphone_core_set_default_proxy(lc,proxy_cfg); /*set to default proxy*/
linphone_core_add_proxy_config(lc,proxy_cfg); /*add proxy config to linphone core*/
linphone_core_set_default_proxy(lc,proxy_cfg); /*set to default proxy*/
i=0;
/* main loop for receiving notifications and doing background linphonecore work: */
@ -163,7 +165,7 @@ int main(int argc, char *argv[]){
linphone_proxy_config_edit(proxy_cfg); /*start editing proxy configuration*/
linphone_proxy_config_enable_register(proxy_cfg,FALSE); /*de-activate registration for this proxy config*/
linphone_proxy_config_done(proxy_cfg); /*initiate REGISTER with expire = 0*/
if (data->ev){
linphone_event_terminate(data->ev);
}

View file

@ -1,7 +1,7 @@
/*
linphone
Copyright (C) 2010 Belledonne Communications SARL
Copyright (C) 2010 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
@ -60,9 +60,13 @@ static void registration_state_changed(struct _LinphoneCore *lc, LinphoneProxyCo
LinphoneCore *lc;
int main(int argc, char *argv[]){
LinphoneCoreVTable vtable={0};
LinphoneProxyConfig* proxy_cfg;
LinphoneAddress *from;
LinphoneAuthInfo *info;
char* identity=NULL;
char* password=NULL;
const char* server_addr;
/* takes sip uri identity from the command line arguments */
if (argc>1){
@ -79,7 +83,7 @@ int main(int argc, char *argv[]){
#ifdef DEBUG
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
#endif
/*
/*
Fill the LinphoneCoreVTable with application callbacks.
All are optional. Here we only use the registration_state_changed callbacks
in order to get notifications about the progress of the registration.
@ -91,30 +95,28 @@ int main(int argc, char *argv[]){
*/
lc=linphone_core_new(&vtable,NULL,NULL,NULL);
LinphoneProxyConfig* proxy_cfg;
/*create proxy config*/
proxy_cfg = linphone_proxy_config_new();
/*parse identity*/
LinphoneAddress *from = linphone_address_new(identity);
from = linphone_address_new(identity);
if (from==NULL){
printf("%s not a valid sip uri, must be like sip:toto@sip.linphone.org \n",identity);
goto end;
}
LinphoneAuthInfo *info;
if (password!=NULL){
info=linphone_auth_info_new(linphone_address_get_username(from),NULL,password,NULL,NULL,NULL); /*create authentication structure from identity*/
linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/
}
if (password!=NULL){
info=linphone_auth_info_new(linphone_address_get_username(from),NULL,password,NULL,NULL,NULL); /*create authentication structure from identity*/
linphone_core_add_auth_info(lc,info); /*add authentication info to LinphoneCore*/
}
// configure proxy entries
linphone_proxy_config_set_identity(proxy_cfg,identity); /*set identity with user name and domain*/
const char* server_addr = linphone_address_get_domain(from); /*extract domain address from identity*/
linphone_proxy_config_set_server_addr(proxy_cfg,server_addr); /* we assume domain = proxy server address*/
linphone_proxy_config_enable_register(proxy_cfg,TRUE); /*activate registration for this proxy config*/
linphone_address_destroy(from); /*release resource*/
// configure proxy entries
linphone_proxy_config_set_identity(proxy_cfg,identity); /*set identity with user name and domain*/
server_addr = linphone_address_get_domain(from); /*extract domain address from identity*/
linphone_proxy_config_set_server_addr(proxy_cfg,server_addr); /* we assume domain = proxy server address*/
linphone_proxy_config_enable_register(proxy_cfg,TRUE); /*activate registration for this proxy config*/
linphone_address_destroy(from); /*release resource*/
linphone_core_add_proxy_config(lc,proxy_cfg); /*add proxy config to linphone core*/
linphone_core_set_default_proxy(lc,proxy_cfg); /*set to default proxy*/
linphone_core_add_proxy_config(lc,proxy_cfg); /*add proxy config to linphone core*/
linphone_core_set_default_proxy(lc,proxy_cfg); /*set to default proxy*/
/* main loop for receiving notifications and doing background linphonecore work: */

View file

@ -192,8 +192,7 @@ void linphone_core_notify_info_message(LinphoneCore* lc,SalOp *op, const SalBody
LinphoneInfoMessage *info=ms_new0(LinphoneInfoMessage,1);
info->headers=sal_custom_header_clone(sal_op_get_recv_custom_header(op));
if (body) linphone_content_copy_from_sal_body(&info->content,body);
if (lc->vtable.info_received)
lc->vtable.info_received(lc,call,info);
linphone_core_notify_info_received(lc,call,info);
linphone_info_message_destroy(info);
}
}

View file

@ -567,10 +567,11 @@ LinphoneLDAPContactProvider*linphone_ldap_contact_provider_create(LinphoneCore*
belle_sip_object_unref(obj);
obj = NULL;
} else {
int ret;
linphone_dictionary_foreach( config, linphone_ldap_contact_provider_config_dump_cb, 0 );
linphone_ldap_contact_provider_loadconfig(obj, config);
int ret = ldap_initialize(&(obj->ld),obj->server);
ret = ldap_initialize(&(obj->ld),obj->server);
if( ret != LDAP_SUCCESS ){
ms_error( "Problem initializing ldap on url '%s': %s", obj->server, ldap_err2string(ret));
@ -617,9 +618,10 @@ static int linphone_ldap_request_entry_compare_strong(const void*a, const void*
static inline LinphoneLDAPContactSearch* linphone_ldap_contact_provider_request_search( LinphoneLDAPContactProvider* obj, int msgid )
{
LinphoneLDAPContactSearch dummy = {};
MSList* list_entry;
dummy.msgid = msgid;
MSList* list_entry = ms_list_find_custom(obj->requests, linphone_ldap_request_entry_compare_weak, &dummy);
list_entry = ms_list_find_custom(obj->requests, linphone_ldap_request_entry_compare_weak, &dummy);
if( list_entry ) return list_entry->data;
else return NULL;
}
@ -680,13 +682,14 @@ static LinphoneLDAPContactSearch* linphone_ldap_contact_provider_begin_search (
void* cb_data )
{
bool_t connected = obj->connected;
LinphoneLDAPContactSearch* request;
// if we're not yet connected, bind
if( !connected ) {
if( !obj->bind_thread ) linphone_ldap_contact_provider_bind(obj);
}
LinphoneLDAPContactSearch* request = linphone_ldap_contact_search_create( obj, predicate, cb, cb_data );
request = linphone_ldap_contact_search_create( obj, predicate, cb, cb_data );
if( connected ){
int ret = linphone_ldap_contact_provider_perform_search(obj, request);
@ -711,6 +714,7 @@ static LinphoneLDAPContactSearch* linphone_ldap_contact_provider_begin_search (
static int linphone_ldap_contact_provider_marshal(LinphoneLDAPContactProvider* obj, char* buff, size_t buff_size, size_t *offset)
{
belle_sip_error_code error = BELLE_SIP_OK;
char **attr;
error = belle_sip_snprintf(buff, buff_size, offset, "ld:%p,\n", obj->ld);
if(error!= BELLE_SIP_OK) return error;
@ -741,7 +745,7 @@ static int linphone_ldap_contact_provider_marshal(LinphoneLDAPContactProvider* o
obj->sip_attr, obj->name_attr);
if(error!= BELLE_SIP_OK) return error;
char **attr = obj->attributes;
attr = obj->attributes;
while( *attr ){
error = belle_sip_snprintf(buff, buff_size, offset, "- %s\n", *attr);
if(error!= BELLE_SIP_OK) return error;

View file

@ -29,14 +29,15 @@
#include "private.h"
#include "lpconfig.h"
LinphoneTunnel* linphone_core_get_tunnel(LinphoneCore *lc){
static const char *_tunnel_mode_str[3] = { "disable", "enable", "auto" };
LinphoneTunnel* linphone_core_get_tunnel(const LinphoneCore *lc){
return lc->tunnel;
}
struct _LinphoneTunnel {
belledonnecomm::TunnelManager *manager;
MSList *config_list;
bool_t auto_detect_enabled;
};
extern "C" LinphoneTunnel* linphone_core_tunnel_new(LinphoneCore *lc){
@ -45,16 +46,19 @@ extern "C" LinphoneTunnel* linphone_core_tunnel_new(LinphoneCore *lc){
return tunnel;
}
static inline belledonnecomm::TunnelManager *bcTunnel(LinphoneTunnel *tunnel){
belledonnecomm::TunnelManager *bcTunnel(const LinphoneTunnel *tunnel){
return tunnel->manager;
}
static inline _LpConfig *config(LinphoneTunnel *tunnel){
static inline _LpConfig *config(const LinphoneTunnel *tunnel){
return tunnel->manager->getLinphoneCore()->config;
}
void linphone_tunnel_destroy(LinphoneTunnel *tunnel){
delete tunnel->manager;
ms_list_free_with_data(tunnel->config_list, (void (*)(void *))linphone_tunnel_config_destroy);
ms_free(tunnel);
}
@ -100,12 +104,12 @@ static LinphoneTunnelConfig *linphone_tunnel_config_from_string(const char *str)
break;
case 3:
delay = atoi(pch);
break;
break;
default:
// Abort
pos = 0;
break;
}
++pos;
pch = strtok(NULL, ":");
@ -121,12 +125,12 @@ static LinphoneTunnelConfig *linphone_tunnel_config_from_string(const char *str)
if(pos == 4) {
linphone_tunnel_config_set_delay(tunnel_config, delay);
}
ms_free(dstr);
ms_free(dstr);
return tunnel_config;
}
static void linphone_tunnel_save_config(LinphoneTunnel *tunnel) {
static void linphone_tunnel_save_config(const LinphoneTunnel *tunnel) {
MSList *elem = NULL;
char *tmp = NULL, *old_tmp = NULL, *tc_str = NULL;
for(elem = tunnel->config_list; elem != NULL; elem = elem->next) {
@ -152,12 +156,12 @@ static void linphone_tunnel_save_config(LinphoneTunnel *tunnel) {
static void linphone_tunnel_add_server_intern(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config) {
if(linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config) == -1) {
bcTunnel(tunnel)->addServer(linphone_tunnel_config_get_host(tunnel_config),
bcTunnel(tunnel)->addServer(linphone_tunnel_config_get_host(tunnel_config),
linphone_tunnel_config_get_port(tunnel_config));
} else {
bcTunnel(tunnel)->addServer(linphone_tunnel_config_get_host(tunnel_config),
linphone_tunnel_config_get_port(tunnel_config),
linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config),
bcTunnel(tunnel)->addServer(linphone_tunnel_config_get_host(tunnel_config),
linphone_tunnel_config_get_port(tunnel_config),
linphone_tunnel_config_get_remote_udp_mirror_port(tunnel_config),
linphone_tunnel_config_get_delay(tunnel_config));
}
tunnel->config_list = ms_list_append(tunnel->config_list, tunnel_config);
@ -209,38 +213,37 @@ void linphone_tunnel_remove_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig
MSList *elem = ms_list_find(tunnel->config_list, tunnel_config);
if(elem != NULL) {
tunnel->config_list = ms_list_remove(tunnel->config_list, tunnel_config);
linphone_tunnel_config_destroy(tunnel_config);
linphone_tunnel_config_destroy(tunnel_config);
linphone_tunnel_refresh_config(tunnel);
linphone_tunnel_save_config(tunnel);
}
}
}
const MSList *linphone_tunnel_get_servers(LinphoneTunnel *tunnel){
const MSList *linphone_tunnel_get_servers(const LinphoneTunnel *tunnel){
return tunnel->config_list;
}
void linphone_tunnel_clean_servers(LinphoneTunnel *tunnel){
bcTunnel(tunnel)->cleanServers();
/* Free the list */
ms_list_for_each(tunnel->config_list, (void (*)(void *))linphone_tunnel_config_destroy);
tunnel->config_list = ms_list_free(tunnel->config_list);
ms_list_free_with_data(tunnel->config_list, (void (*)(void *))linphone_tunnel_config_destroy);
tunnel->config_list = NULL;
linphone_tunnel_save_config(tunnel);
}
void linphone_tunnel_enable(LinphoneTunnel *tunnel, bool_t enabled){
tunnel->auto_detect_enabled = FALSE;
lp_config_set_int(config(tunnel),"tunnel","enabled",(int)enabled);
bcTunnel(tunnel)->enable(enabled);
void linphone_tunnel_set_mode(LinphoneTunnel *tunnel, LinphoneTunnelMode mode){
lp_config_set_string(config(tunnel),"tunnel","mode", tunnel_mode_to_string(mode));
bcTunnel(tunnel)->setMode(mode);
}
bool_t linphone_tunnel_enabled(LinphoneTunnel *tunnel){
return bcTunnel(tunnel)->isEnabled();
LinphoneTunnelMode linphone_tunnel_get_mode(const LinphoneTunnel *tunnel){
return bcTunnel(tunnel)->getMode();
}
bool_t linphone_tunnel_connected(LinphoneTunnel *tunnel){
return bcTunnel(tunnel)->isReady();
bool_t linphone_tunnel_connected(const LinphoneTunnel *tunnel){
return bcTunnel(tunnel)->isConnected();
}
static OrtpLogFunc tunnelOrtpLogHandler=NULL;
@ -316,27 +319,65 @@ void linphone_tunnel_reconnect(LinphoneTunnel *tunnel){
bcTunnel(tunnel)->reconnect();
}
void linphone_tunnel_auto_detect(LinphoneTunnel *tunnel){
tunnel->auto_detect_enabled = TRUE;
bcTunnel(tunnel)->autoDetect();
void linphone_tunnel_enable_sip(LinphoneTunnel *tunnel, bool_t enable) {
bcTunnel(tunnel)->tunnelizeSipPackets(enable);
lp_config_set_int(config(tunnel), "tunnel", "sip", (enable ? TRUE : FALSE));
}
bool_t linphone_tunnel_auto_detect_enabled(LinphoneTunnel *tunnel) {
return tunnel->auto_detect_enabled;
bool_t linphone_tunnel_sip_enabled(const LinphoneTunnel *tunnel) {
return bcTunnel(tunnel)->tunnelizeSipPacketsEnabled() ? TRUE : FALSE;
}
static void my_ortp_logv(OrtpLogLevel level, const char *fmt, va_list args){
ortp_logv(level,fmt,args);
}
LinphoneTunnelMode string_to_tunnel_mode(const char *string) {
if(string != NULL) {
int i;
for(i=0; i<3 && strcmp(string, _tunnel_mode_str[i]) != 0; i++);
if(i<3) {
return (LinphoneTunnelMode)i;
} else {
ms_error("Invalid tunnel mode '%s'", string);
return LinphoneTunnelModeDisable;
}
} else {
return LinphoneTunnelModeDisable;
}
}
const char *tunnel_mode_to_string(LinphoneTunnelMode mode) {
return _tunnel_mode_str[mode];
}
/**
* Startup tunnel using configuration.
* Called internally from linphonecore at startup.
*/
void linphone_tunnel_configure(LinphoneTunnel *tunnel){
bool_t enabled=(bool_t)lp_config_get_int(config(tunnel),"tunnel","enabled",FALSE);
LinphoneTunnelMode mode = string_to_tunnel_mode(lp_config_get_string(config(tunnel), "tunnel", "mode", NULL));
bool_t tunnelizeSIPPackets = (bool_t)lp_config_get_int(config(tunnel), "tunnel", "sip", TRUE);
linphone_tunnel_enable_logs_with_handler(tunnel,TRUE,my_ortp_logv);
linphone_tunnel_load_config(tunnel);
linphone_tunnel_enable(tunnel, enabled);
linphone_tunnel_enable_sip(tunnel, tunnelizeSIPPackets);
linphone_tunnel_set_mode(tunnel, mode);
}
/* Deprecated functions */
void linphone_tunnel_enable(LinphoneTunnel *tunnel, bool_t enabled) {
if(enabled) linphone_tunnel_set_mode(tunnel, LinphoneTunnelModeEnable);
else linphone_tunnel_set_mode(tunnel, LinphoneTunnelModeDisable);
}
bool_t linphone_tunnel_enabled(const LinphoneTunnel *tunnel) {
return linphone_tunnel_get_mode(tunnel) == LinphoneTunnelModeEnable;
}
void linphone_tunnel_auto_detect(LinphoneTunnel *tunnel) {
linphone_tunnel_set_mode(tunnel, LinphoneTunnelModeAuto);
}
bool_t linphone_tunnel_auto_detect_enabled(LinphoneTunnel *tunnel) {
return linphone_tunnel_get_mode(tunnel) == LinphoneTunnelModeAuto;
}

View file

@ -50,6 +50,30 @@ extern "C"
typedef struct _LinphoneTunnelConfig LinphoneTunnelConfig;
/**
* Enum describing the tunnel modes.
**/
typedef enum _LinphoneTunnelMode {
LinphoneTunnelModeDisable, /**< The tunnel is disabled. */
LinphoneTunnelModeEnable, /**< The tunnel is enabled. */
LinphoneTunnelModeAuto /**< The tunnel is enabled automatically if it is required. */
} LinphoneTunnelMode;
/**
* @brief Convert a string into LinphoneTunnelMode enum
* @param string String to convert
* @return An LinphoneTunnelMode enum. If the passed string is NULL or
* does not match with any mode, the LinphoneTunnelModeDisable is returned.
*/
LINPHONE_PUBLIC LinphoneTunnelMode string_to_tunnel_mode(const char *string);
/**
* @brief Convert a tunnel mode enum into string
* @param mode Enum to convert
* @return "disable", "enable" or "auto"
*/
LINPHONE_PUBLIC const char *tunnel_mode_to_string(LinphoneTunnelMode mode);
/**
* Create a new tunnel configuration
*/
@ -131,51 +155,49 @@ LINPHONE_PUBLIC void linphone_tunnel_config_destroy(LinphoneTunnelConfig *tunnel
LINPHONE_PUBLIC void linphone_tunnel_add_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config);
/**
* Remove tunnel server configuration
*
* @brief Remove tunnel server configuration
* @param tunnel object
* @param tunnel_config object
*/
LINPHONE_PUBLIC void linphone_tunnel_remove_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config);
/**
* @param tunnel object
* returns a string of space separated list of host:port of tunnel server addresses
* */
LINPHONE_PUBLIC const MSList *linphone_tunnel_get_servers(LinphoneTunnel *tunnel);
* @brief Get added servers
* @param tunnel A LinphoneTunnel object
* @return A list of LinphoneTunnelConfig objects
*/
LINPHONE_PUBLIC const MSList *linphone_tunnel_get_servers(const LinphoneTunnel *tunnel);
/**
* @param tunnel object
* Removes all tunnel server address previously entered with addServer()
* @brief Removes all tunnel server address previously entered with addServer()
* @param tunnel A LinphoneTunnel object
**/
LINPHONE_PUBLIC void linphone_tunnel_clean_servers(LinphoneTunnel *tunnel);
/**
* Sets whether tunneling of SIP and RTP is required.
* @brief Set tunnel mode
* The tunnel mode can be 'enable', 'disable' or 'auto'
* If the mode is set to 'auto', the tunnel manager will try to established an RTP session
* with the tunnel server on the UdpMirrorPort. If the connection fail, the tunnel is automatically
* activated whereas the tunnel is automatically disabled if the connection succeed.
* @param tunnel object
* @param enabled If true enter in tunneled mode, if false exits from tunneled mode.
* The TunnelManager takes care of refreshing SIP registration when switching on or off the tunneled mode.
*
* @param mode See #LinphoneTunnelMode
**/
LINPHONE_PUBLIC void linphone_tunnel_enable(LinphoneTunnel *tunnel, bool_t enabled);
LINPHONE_PUBLIC void linphone_tunnel_set_mode(LinphoneTunnel *tunnel, LinphoneTunnelMode mode);
/**
* @param tunnel object
* Returns a boolean indicating whether tunneled operation is enabled.
* @brief Get the tunnel mode
* @param tunnel A LinphoneTunnel object
* @return Return a #LinphoneTunnelMode enumeration
**/
LINPHONE_PUBLIC bool_t linphone_tunnel_enabled(LinphoneTunnel *tunnel);
LINPHONE_PUBLIC LinphoneTunnelMode linphone_tunnel_get_mode(const LinphoneTunnel *tunnel);
/**
* @param tunnel object
* Returns a boolean indicating whether tunnel is connected successfully.
* @brief Check whether the tunnel is connected
* @param tunnel LinphoneTunnel object
* @return True if the tunnel is connected
**/
bool_t linphone_tunnel_connected(LinphoneTunnel *tunnel);
/**
* @param tunnel object
* Returns a boolean indicating whether tunnel is connected successfully.
**/
bool_t linphone_tunnel_connected(LinphoneTunnel *tunnel);
LINPHONE_PUBLIC bool_t linphone_tunnel_connected(const LinphoneTunnel *tunnel);
/**
* @param tunnel object
@ -187,20 +209,18 @@ bool_t linphone_tunnel_connected(LinphoneTunnel *tunnel);
LINPHONE_PUBLIC void linphone_tunnel_reconnect(LinphoneTunnel *tunnel);
/**
* Start tunnel need detection.
* @param tunnel object
* In auto detect mode, the tunnel manager try to establish a real time rtp cummunication with the tunnel server on specified port.
*<br>In case of success, the tunnel is automatically turned off. Otherwise, if no udp commmunication is feasible, tunnel mode is turned on.
*<br> Call this method each time to run the auto detection algorithm
* @brief Set whether SIP packets must be directly sent to a UA or pass through the tunnel
* @param tunnel Tunnel to configure
* @param enable If true, SIP packets shall pass through the tunnel
*/
LINPHONE_PUBLIC void linphone_tunnel_auto_detect(LinphoneTunnel *tunnel);
LINPHONE_PUBLIC void linphone_tunnel_enable_sip(LinphoneTunnel *tunnel, bool_t enable);
/**
* Tells whether tunnel auto detection is enabled.
* @param[in] tunnel LinphoneTunnel object.
* @return TRUE if auto detection is enabled, FALSE otherwise.
* @brief Check whether tunnel is set to transport SIP packets
* @param tunnel Tunnel to check
* @return True, SIP packets shall pass through through tunnel
*/
LINPHONE_PUBLIC bool_t linphone_tunnel_auto_detect_enabled(LinphoneTunnel *tunnel);
LINPHONE_PUBLIC bool_t linphone_tunnel_sip_enabled(const LinphoneTunnel *tunnel);
/**
* Set an optional http proxy to go through when connecting to tunnel server.
@ -222,8 +242,49 @@ LINPHONE_PUBLIC void linphone_tunnel_set_http_proxy(LinphoneTunnel *tunnel, cons
**/
LINPHONE_PUBLIC void linphone_tunnel_get_http_proxy(LinphoneTunnel*tunnel,const char **host, int *port, const char **username, const char **passwd);
/**
* @brief Set authentication info for the http proxy
* @param tunnel LinphoneTunnel object
* @param username User name
* @param passwd Password
*/
LINPHONE_PUBLIC void linphone_tunnel_set_http_proxy_auth_info(LinphoneTunnel*tunnel, const char* username,const char* passwd);
/**
* @deprecated Replaced by linphone_tunnel_set_mode()
* @brief Sets whether tunneling of SIP and RTP is required.
* @param tunnel object
* @param enabled If true enter in tunneled mode, if false exits from tunneled mode.
* The TunnelManager takes care of refreshing SIP registration when switching on or off the tunneled mode.
*
**/
LINPHONE_PUBLIC void linphone_tunnel_enable(LinphoneTunnel *tunnel, bool_t enabled);
/**
* @deprecated Replaced by linphone_tunnel_get_mode()
* @brief Check whether tunnel is enabled
* @param tunnel Tunnel object
* @return Returns a boolean indicating whether tunneled operation is enabled.
**/
LINPHONE_PUBLIC bool_t linphone_tunnel_enabled(const LinphoneTunnel *tunnel);
/**
* @deprecated Replaced by linphone_tunnel_set_mode(LinphoneTunnelModeAuto)
* @brief Start tunnel need detection.
* @param tunnel object
* In auto detect mode, the tunnel manager try to establish a real time rtp cummunication with the tunnel server on specified port.
* <br>In case of success, the tunnel is automatically turned off. Otherwise, if no udp commmunication is feasible, tunnel mode is turned on.
* <br> Call this method each time to run the auto detection algorithm
*/
LINPHONE_PUBLIC void linphone_tunnel_auto_detect(LinphoneTunnel *tunnel);
/**
* @deprecated Replaced by linphone_tunnel_get_mode()
* @brief Tells whether tunnel auto detection is enabled.
* @param[in] tunnel LinphoneTunnel object.
* @return TRUE if auto detection is enabled, FALSE otherwise.
*/
LINPHONE_PUBLIC bool_t linphone_tunnel_auto_detect_enabled(LinphoneTunnel *tunnel);
/**
* @}

View file

@ -29,7 +29,7 @@
#include "lpconfig.h"
LinphoneTunnel* linphone_core_get_tunnel(LinphoneCore *lc){
LinphoneTunnel* linphone_core_get_tunnel(const LinphoneCore *lc){
return lc->tunnel;
}
@ -45,21 +45,21 @@ void linphone_tunnel_add_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tu
void linphone_tunnel_remove_server(LinphoneTunnel *tunnel, LinphoneTunnelConfig *tunnel_config){
}
const MSList *linphone_tunnel_get_servers(LinphoneTunnel *tunnel){
const MSList *linphone_tunnel_get_servers(const LinphoneTunnel *tunnel){
return NULL;
}
void linphone_tunnel_clean_servers(LinphoneTunnel *tunnel){
}
void linphone_tunnel_enable(LinphoneTunnel *tunnel, bool_t enabled){
void linphone_tunnel_set_mode(LinphoneTunnel *tunnel, LinphoneTunnelMode mode) {
}
bool_t linphone_tunnel_enabled(LinphoneTunnel *tunnel){
return FALSE;
LinphoneTunnelMode linphone_tunnel_get_mode(const LinphoneTunnel *tunnel){
return LinphoneTunnelModeDisable;
}
bool_t linphone_tunnel_connected(LinphoneTunnel *tunnel){
bool_t linphone_tunnel_connected(const LinphoneTunnel *tunnel){
return FALSE;
}
@ -79,9 +79,14 @@ void linphone_tunnel_get_http_proxy(LinphoneTunnel*tunnel,const char **host, int
void linphone_tunnel_reconnect(LinphoneTunnel *tunnel){
}
void linphone_tunnel_auto_detect(LinphoneTunnel *tunnel){
}
void linphone_tunnel_configure(LinphoneTunnel *tunnel){
}
void linphone_tunnel_enable_sip(LinphoneTunnel *tunnel, bool_t enable) {}
bool_t linphone_tunnel_sip_enabled(const LinphoneTunnel *tunnel) { return FALSE; }
/* Deprecated functions */
void linphone_tunnel_enable(LinphoneTunnel *tunnel, bool_t enabled) {}
bool_t linphone_tunnel_enabled(const LinphoneTunnel *tunnel) { return FALSE; }
void linphone_tunnel_auto_detect(LinphoneTunnel *tunnel) {}
bool_t linphone_tunnel_auto_detect_enabled(LinphoneTunnel *tunnel) { return FALSE; }

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/mscommon.h"
#include "mediastreamer2/msvideo.h"
#include "mediastreamer2/mediastream.h"
#include "mediastreamer2/bitratecontrol.h"
#ifdef IN_LINPHONE
#include "sipsetup.h"
@ -285,90 +286,23 @@ LINPHONE_PUBLIC char * linphone_payload_type_get_mime_type(const LinphonePayload
*/
LINPHONE_PUBLIC int linphone_payload_type_get_channels(const LinphonePayloadType *pt);
/**
* @}
* Enum describing RTP AVPF activation modes.
**/
#ifdef IN_LINPHONE
#include "linphonefriend.h"
#include "event.h"
#else
#include "linphone/linphonefriend.h"
#include "linphone/event.h"
#endif
LINPHONE_PUBLIC LinphoneAddress * linphone_address_new(const char *addr);
LINPHONE_PUBLIC LinphoneAddress * linphone_address_clone(const LinphoneAddress *addr);
LINPHONE_PUBLIC LinphoneAddress * linphone_address_ref(LinphoneAddress *addr);
LINPHONE_PUBLIC void linphone_address_unref(LinphoneAddress *addr);
LINPHONE_PUBLIC const char *linphone_address_get_scheme(const LinphoneAddress *u);
LINPHONE_PUBLIC const char *linphone_address_get_display_name(const LinphoneAddress* u);
LINPHONE_PUBLIC const char *linphone_address_get_username(const LinphoneAddress *u);
LINPHONE_PUBLIC const char *linphone_address_get_domain(const LinphoneAddress *u);
LINPHONE_PUBLIC int linphone_address_get_port(const LinphoneAddress *u);
LINPHONE_PUBLIC void linphone_address_set_display_name(LinphoneAddress *u, const char *display_name);
LINPHONE_PUBLIC void linphone_address_set_username(LinphoneAddress *uri, const char *username);
LINPHONE_PUBLIC void linphone_address_set_domain(LinphoneAddress *uri, const char *host);
LINPHONE_PUBLIC void linphone_address_set_port(LinphoneAddress *uri, int port);
/*remove tags, params etc... so that it is displayable to the user*/
LINPHONE_PUBLIC void linphone_address_clean(LinphoneAddress *uri);
LINPHONE_PUBLIC bool_t linphone_address_is_secure(const LinphoneAddress *uri);
LINPHONE_PUBLIC LinphoneTransportType linphone_address_get_transport(const LinphoneAddress *uri);
LINPHONE_PUBLIC void linphone_address_set_transport(LinphoneAddress *uri,LinphoneTransportType type);
LINPHONE_PUBLIC char *linphone_address_as_string(const LinphoneAddress *u);
LINPHONE_PUBLIC char *linphone_address_as_string_uri_only(const LinphoneAddress *u);
LINPHONE_PUBLIC bool_t linphone_address_weak_equal(const LinphoneAddress *a1, const LinphoneAddress *a2);
LINPHONE_PUBLIC void linphone_address_destroy(LinphoneAddress *u);
/**
* Create a #LinphoneAddress object by parsing the user supplied address, given as a string.
* @param[in] lc #LinphoneCore object
* @param[in] address String containing the user supplied address
* @return The create #LinphoneAddress object
* @ingroup linphone_address
*/
LINPHONE_PUBLIC LinphoneAddress * linphone_core_create_address(LinphoneCore *lc, const char *address);
struct _SipSetupContext;
/**
* Enum representing the direction of a call.
* @ingroup call_logs
**/
enum _LinphoneCallDir {
LinphoneCallOutgoing, /**< outgoing calls*/
LinphoneCallIncoming /**< incoming calls*/
enum _LinphoneAVPFMode{
LinphoneAVPFDefault=-1, /**<Use default value defined at upper level*/
LinphoneAVPFDisabled, /**<AVPF is disabled*/
LinphoneAVPFEnabled /**<AVPF is enabled */
};
/**
* Typedef for enum
* @ingroup call_logs
* Enum describing RTP AVPF activation modes.
**/
typedef enum _LinphoneCallDir LinphoneCallDir;
/**
* Enum representing the status of a call
* @ingroup call_logs
**/
typedef enum _LinphoneCallStatus {
LinphoneCallSuccess, /**< The call was sucessful*/
LinphoneCallAborted, /**< The call was aborted */
LinphoneCallMissed, /**< The call was missed (unanswered)*/
LinphoneCallDeclined /**< The call was declined, either locally or by remote end*/
} LinphoneCallStatus;
/**
* Structure representing a call log.
*
* @ingroup call_logs
*
**/
typedef struct _LinphoneCallLog LinphoneCallLog;
typedef enum _LinphoneAVPFMode LinphoneAVPFMode;
/**
* Enum describing type of media encryption types.
* @ingroup media_parameters
**/
enum _LinphoneMediaEncryption {
LinphoneMediaEncryptionNone, /**< No media encryption is used */
@ -378,126 +312,17 @@ enum _LinphoneMediaEncryption {
/**
* Enum describing type of media encryption types.
* @ingroup media_parameters
**/
typedef enum _LinphoneMediaEncryption LinphoneMediaEncryption;
/**
* Convert enum member to string.
* @ingroup media_parameters
**/
LINPHONE_PUBLIC const char *linphone_media_encryption_to_string(LinphoneMediaEncryption menc);
/*public: */
LINPHONE_PUBLIC LinphoneAddress *linphone_call_log_get_from(LinphoneCallLog *cl);
LINPHONE_PUBLIC LinphoneAddress *linphone_call_log_get_to(LinphoneCallLog *cl);
LINPHONE_PUBLIC LinphoneAddress *linphone_call_log_get_remote_address(LinphoneCallLog *cl);
LINPHONE_PUBLIC LinphoneCallDir linphone_call_log_get_dir(LinphoneCallLog *cl);
LINPHONE_PUBLIC LinphoneCallStatus linphone_call_log_get_status(LinphoneCallLog *cl);
LINPHONE_PUBLIC bool_t linphone_call_log_video_enabled(LinphoneCallLog *cl);
LINPHONE_PUBLIC time_t linphone_call_log_get_start_date(LinphoneCallLog *cl);
LINPHONE_PUBLIC int linphone_call_log_get_duration(LinphoneCallLog *cl);
LINPHONE_PUBLIC float linphone_call_log_get_quality(LinphoneCallLog *cl);
/** @deprecated Use linphone_call_log_set_user_data() instead. */
#define linphone_call_log_set_user_pointer(cl, ud) linphone_call_log_set_user_data(cl, ud)
LINPHONE_PUBLIC void linphone_call_log_set_user_data(LinphoneCallLog *cl, void *up);
/** @deprecated Use linphone_call_log_get_user_data() instead. */
#define linphone_call_log_get_user_pointer(cl) linphone_call_log_get_user_data(cl)
LINPHONE_PUBLIC void *linphone_call_log_get_user_data(const LinphoneCallLog *cl);
void linphone_call_log_set_ref_key(LinphoneCallLog *cl, const char *refkey);
const char *linphone_call_log_get_ref_key(const LinphoneCallLog *cl);
LINPHONE_PUBLIC const rtp_stats_t *linphone_call_log_get_local_stats(const LinphoneCallLog *cl);
LINPHONE_PUBLIC const rtp_stats_t *linphone_call_log_get_remote_stats(const LinphoneCallLog *cl);
LINPHONE_PUBLIC const char *linphone_call_log_get_call_id(const LinphoneCallLog *cl);
LINPHONE_PUBLIC char * linphone_call_log_to_str(LinphoneCallLog *cl);
/**
* Private structure definition for LinphoneCallParams.
* @ingroup call_control
* @}
**/
struct _LinphoneCallParams;
/**
* The LinphoneCallParams is an object containing various call related parameters.
* It can be used to retrieve parameters from a currently running call or modify the call's characteristics
* dynamically.
* @ingroup call_control
**/
typedef struct _LinphoneCallParams LinphoneCallParams;
LINPHONE_PUBLIC const LinphonePayloadType* linphone_call_params_get_used_audio_codec(const LinphoneCallParams *cp);
LINPHONE_PUBLIC const LinphonePayloadType* linphone_call_params_get_used_video_codec(const LinphoneCallParams *cp);
LINPHONE_PUBLIC LinphoneCallParams * linphone_call_params_copy(const LinphoneCallParams *cp);
LINPHONE_PUBLIC void linphone_call_params_enable_video(LinphoneCallParams *cp, bool_t enabled);
LINPHONE_PUBLIC bool_t linphone_call_params_video_enabled(const LinphoneCallParams *cp);
LINPHONE_PUBLIC LinphoneMediaEncryption linphone_call_params_get_media_encryption(const LinphoneCallParams *cp);
LINPHONE_PUBLIC void linphone_call_params_set_media_encryption(LinphoneCallParams *cp, LinphoneMediaEncryption e);
LINPHONE_PUBLIC void linphone_call_params_enable_early_media_sending(LinphoneCallParams *cp, bool_t enabled);
LINPHONE_PUBLIC bool_t linphone_call_params_early_media_sending_enabled(const LinphoneCallParams *cp);
#define linphone_call_params_local_conference_mode linphone_call_params_get_local_conference_mode /* Deprecated */
LINPHONE_PUBLIC bool_t linphone_call_params_get_local_conference_mode(const LinphoneCallParams *cp);
LINPHONE_PUBLIC void linphone_call_params_set_audio_bandwidth_limit(LinphoneCallParams *cp, int bw);
LINPHONE_PUBLIC void linphone_call_params_destroy(LinphoneCallParams *cp);
LINPHONE_PUBLIC bool_t linphone_call_params_low_bandwidth_enabled(const LinphoneCallParams *cp);
LINPHONE_PUBLIC void linphone_call_params_enable_low_bandwidth(LinphoneCallParams *cp, bool_t enabled);
LINPHONE_PUBLIC void linphone_call_params_set_record_file(LinphoneCallParams *cp, const char *path);
LINPHONE_PUBLIC const char *linphone_call_params_get_record_file(const LinphoneCallParams *cp);
LINPHONE_PUBLIC const char *linphone_call_params_get_session_name(const LinphoneCallParams *cp);
LINPHONE_PUBLIC void linphone_call_params_set_session_name(LinphoneCallParams *cp, const char *subject);
/**
* Add a custom SIP header in the INVITE for a call.
* @param[in] params The #LinphoneCallParams to add a custom SIP header to.
* @param[in] header_name The name of the header to add.
* @param[in] header_value The content of the header to add.
* @ingroup call_control
**/
LINPHONE_PUBLIC void linphone_call_params_add_custom_header(LinphoneCallParams *params, const char *header_name, const char *header_value);
/**
* Get a custom SIP header.
* @param[in] params The #LinphoneCallParams to get the custom SIP header from.
* @param[in] header_name The name of the header to get.
* @returns The content of the header or NULL if not found.
* @ingroup call_control
**/
LINPHONE_PUBLIC const char *linphone_call_params_get_custom_header(const LinphoneCallParams *params, const char *header_name);
/**
* Gets the size of the video that is sent.
* @param[in] cp The call parameters for which to get the sent video size.
* @return The sent video size or MS_VIDEO_SIZE_UNKNOWN if not available.
*/
LINPHONE_PUBLIC MSVideoSize linphone_call_params_get_sent_video_size(const LinphoneCallParams *cp);
/**
* Gets the size of the video that is received.
* @param[in] cp The call paramaters for which to get the received video size.
* @return The received video size or MS_VIDEO_SIZE_UNKNOWN if not available.
*/
LINPHONE_PUBLIC MSVideoSize linphone_call_params_get_received_video_size(const LinphoneCallParams *cp);
/**
* Gets the framerate of the video that is sent.
* @param[in] cp The call parameters.
* @return the actual sent framerate in frames per seconds, 0 if not available.
*/
LINPHONE_PUBLIC float linphone_call_params_get_sent_framerate(const LinphoneCallParams *cp);
/**
* Gets the framerate of the video that is received.
* @param[in] cp The call paramaters for which to get the received framerate.
* @return the actual received framerate in frames per seconds, 0 if not available.
*/
LINPHONE_PUBLIC float linphone_call_params_get_received_framerate(const LinphoneCallParams *cp);
/**
* Gets the RTP profile being used.
* @param[in] cp #LinphoneCallParams object
* @returns The RTP profile.
*/
LINPHONE_PUBLIC const char * linphone_call_params_get_rtp_profile(const LinphoneCallParams *cp);
/*
@ -558,8 +383,53 @@ typedef unsigned int LinphonePrivacyMask;
LINPHONE_PUBLIC const char* linphone_privacy_to_string(LinphonePrivacy privacy);
LINPHONE_PUBLIC void linphone_call_params_set_privacy(LinphoneCallParams *params, LinphonePrivacyMask privacy);
LINPHONE_PUBLIC LinphonePrivacyMask linphone_call_params_get_privacy(const LinphoneCallParams *params);
#ifdef IN_LINPHONE
#include "linphonefriend.h"
#include "event.h"
#include "call_log.h"
#include "call_params.h"
#else
#include "linphone/linphonefriend.h"
#include "linphone/event.h"
#include "linphone/call_log.h"
#include "linphone/call_params.h"
#endif
LINPHONE_PUBLIC LinphoneAddress * linphone_address_new(const char *addr);
LINPHONE_PUBLIC LinphoneAddress * linphone_address_clone(const LinphoneAddress *addr);
LINPHONE_PUBLIC LinphoneAddress * linphone_address_ref(LinphoneAddress *addr);
LINPHONE_PUBLIC void linphone_address_unref(LinphoneAddress *addr);
LINPHONE_PUBLIC const char *linphone_address_get_scheme(const LinphoneAddress *u);
LINPHONE_PUBLIC const char *linphone_address_get_display_name(const LinphoneAddress* u);
LINPHONE_PUBLIC const char *linphone_address_get_username(const LinphoneAddress *u);
LINPHONE_PUBLIC const char *linphone_address_get_domain(const LinphoneAddress *u);
LINPHONE_PUBLIC int linphone_address_get_port(const LinphoneAddress *u);
LINPHONE_PUBLIC void linphone_address_set_display_name(LinphoneAddress *u, const char *display_name);
LINPHONE_PUBLIC void linphone_address_set_username(LinphoneAddress *uri, const char *username);
LINPHONE_PUBLIC void linphone_address_set_domain(LinphoneAddress *uri, const char *host);
LINPHONE_PUBLIC void linphone_address_set_port(LinphoneAddress *uri, int port);
/*remove tags, params etc... so that it is displayable to the user*/
LINPHONE_PUBLIC void linphone_address_clean(LinphoneAddress *uri);
LINPHONE_PUBLIC bool_t linphone_address_is_secure(const LinphoneAddress *uri);
LINPHONE_PUBLIC LinphoneTransportType linphone_address_get_transport(const LinphoneAddress *uri);
LINPHONE_PUBLIC void linphone_address_set_transport(LinphoneAddress *uri,LinphoneTransportType type);
LINPHONE_PUBLIC char *linphone_address_as_string(const LinphoneAddress *u);
LINPHONE_PUBLIC char *linphone_address_as_string_uri_only(const LinphoneAddress *u);
LINPHONE_PUBLIC bool_t linphone_address_weak_equal(const LinphoneAddress *a1, const LinphoneAddress *a2);
LINPHONE_PUBLIC void linphone_address_destroy(LinphoneAddress *u);
/**
* Create a #LinphoneAddress object by parsing the user supplied address, given as a string.
* @param[in] lc #LinphoneCore object
* @param[in] address String containing the user supplied address
* @return The create #LinphoneAddress object
* @ingroup linphone_address
*/
LINPHONE_PUBLIC LinphoneAddress * linphone_core_create_address(LinphoneCore *lc, const char *address);
struct _SipSetupContext;
struct _LinphoneInfoMessage;
@ -574,7 +444,6 @@ LINPHONE_PUBLIC void linphone_info_message_add_header(LinphoneInfoMessage *im, c
LINPHONE_PUBLIC const char *linphone_info_message_get_header(const LinphoneInfoMessage *im, const char *name);
LINPHONE_PUBLIC void linphone_info_message_set_content(LinphoneInfoMessage *im, const LinphoneContent *content);
LINPHONE_PUBLIC const LinphoneContent * linphone_info_message_get_content(const LinphoneInfoMessage *im);
LINPHONE_PUBLIC const char *linphone_info_message_get_from(const LinphoneInfoMessage *im);
LINPHONE_PUBLIC void linphone_info_message_destroy(LinphoneInfoMessage *im);
LINPHONE_PUBLIC LinphoneInfoMessage *linphone_info_message_copy(const LinphoneInfoMessage *orig);
@ -696,10 +565,59 @@ LINPHONE_PUBLIC float linphone_call_stats_get_receiver_loss_rate(const LinphoneC
LINPHONE_PUBLIC float linphone_call_stats_get_sender_interarrival_jitter(const LinphoneCallStats *stats, LinphoneCall *call);
LINPHONE_PUBLIC float linphone_call_stats_get_receiver_interarrival_jitter(const LinphoneCallStats *stats, LinphoneCall *call);
LINPHONE_PUBLIC uint64_t linphone_call_stats_get_late_packets_cumulative_number(const LinphoneCallStats *stats, LinphoneCall *call);
LINPHONE_PUBLIC float linphone_call_stats_get_download_bandwidth(const LinphoneCallStats *stats);
LINPHONE_PUBLIC float linphone_call_stats_get_upload_bandwidth(const LinphoneCallStats *stats);
LINPHONE_PUBLIC LinphoneIceState linphone_call_stats_get_ice_state(const LinphoneCallStats *stats);
LINPHONE_PUBLIC LinphoneUpnpState linphone_call_stats_get_upnp_state(const LinphoneCallStats *stats);
/** Callback prototype */
typedef void (*LinphoneCallCbFunc)(LinphoneCall *call,void * user_data);
/**
* Player interface.
* @ingroup call_control
**/
typedef struct _LinphonePlayer LinphonePlayer;
/**
* Callback for notifying end of play (file).
* @param obj the LinphonePlayer
* @param user_data the user_data provided when calling linphone_player_open().
* @ingroup call_control
**/
typedef void (*LinphonePlayerEofCallback)(struct _LinphonePlayer *obj, void *user_data);
int linphone_player_open(LinphonePlayer *obj, const char *filename, LinphonePlayerEofCallback, void *user_data);
int linphone_player_start(LinphonePlayer *obj);
int linphone_player_pause(LinphonePlayer *obj);
int linphone_player_seek(LinphonePlayer *obj, int time_ms);
MSPlayerState linphone_player_get_state(LinphonePlayer *obj);
int linphone_player_get_duration(LinphonePlayer *obj);
int linphone_player_get_current_position(LinphonePlayer *obj);
void linphone_player_close(LinphonePlayer *obj);
/**
* @brief Create an independent media file player.
* This player support WAVE and MATROSKA formats.
* @param lc A LinphoneCore
* @param snd_card Playback sound card. If NULL, the sound card set in LinphoneCore will be used
* @param video_out Video display. If NULL, the video display set in LinphoneCore will be used
* @return A pointer on the new instance. NULL if faild.
*/
LINPHONE_PUBLIC LinphonePlayer *linphone_core_create_file_player(LinphoneCore *lc, MSSndCard *snd_card, const char *video_out);
/**
* @brief Destroy a file player
* @param obj File player to destroy
*/
LINPHONE_PUBLIC void linphone_file_player_destroy(LinphonePlayer *obj);
/**
* @brief Check whether Matroksa format is supported by the player
* @return TRUE if it is supported
*/
LINPHONE_PUBLIC bool_t linphone_file_player_matroska_supported(void);
/**
* LinphoneCallState enum represents the different state a call can reach into.
* The application is notified of state changes through the LinphoneCoreVTable::call_state_changed callback.
@ -729,15 +647,56 @@ typedef enum _LinphoneCallState{
LINPHONE_PUBLIC const char *linphone_call_state_to_string(LinphoneCallState cs);
/**
* Acquire a reference to the call.
* An application that wishes to retain a pointer to call object
* must use this function to unsure the pointer remains
* valid. Once the application no more needs this pointer,
* it must call linphone_call_unref().
* @param[in] call The call.
* @return The same call.
* @ingroup call_control
**/
LINPHONE_PUBLIC LinphoneCall *linphone_call_ref(LinphoneCall *call);
/**
* Release reference to the call.
* @param[in] call The call.
* @ingroup call_control
**/
LINPHONE_PUBLIC void linphone_call_unref(LinphoneCall *call);
/**
* Retrieve the user pointer associated with the call.
* @param[in] call The call.
* @return The user pointer associated with the call.
* @ingroup call_control
**/
LINPHONE_PUBLIC void *linphone_call_get_user_data(const LinphoneCall *call);
/**
* Assign a user pointer to the call.
* @param[in] cfg The call.
* @param[in] ud The user pointer to associate with the call.
* @ingroup call_control
**/
LINPHONE_PUBLIC void linphone_call_set_user_data(LinphoneCall *call, void *ud);
LINPHONE_PUBLIC LinphoneCore *linphone_call_get_core(const LinphoneCall *call);
LINPHONE_PUBLIC LinphoneCallState linphone_call_get_state(const LinphoneCall *call);
LINPHONE_PUBLIC bool_t linphone_call_asked_to_autoanswer(LinphoneCall *call);
/**
* Get the remote address of the current call.
* @param[in] lc LinphoneCore object.
* @return The remote address of the current call or NULL if there is no current call.
* @ingroup call_control
*/
LINPHONE_PUBLIC const LinphoneAddress * linphone_core_get_current_call_remote_address(LinphoneCore *lc);
LINPHONE_PUBLIC const LinphoneAddress * linphone_call_get_remote_address(const LinphoneCall *call);
LINPHONE_PUBLIC char *linphone_call_get_remote_address_as_string(const LinphoneCall *call);
LINPHONE_PUBLIC LinphoneCallDir linphone_call_get_dir(const LinphoneCall *call);
LINPHONE_PUBLIC LinphoneCall * linphone_call_ref(LinphoneCall *call);
LINPHONE_PUBLIC void linphone_call_unref(LinphoneCall *call);
LINPHONE_PUBLIC LinphoneCallLog *linphone_call_get_call_log(const LinphoneCall *call);
LINPHONE_PUBLIC const char *linphone_call_get_refer_to(const LinphoneCall *call);
LINPHONE_PUBLIC bool_t linphone_call_has_transfer_pending(const LinphoneCall *call);
@ -765,15 +724,14 @@ LINPHONE_PUBLIC void linphone_call_set_authentication_token_verified(LinphoneCal
LINPHONE_PUBLIC void linphone_call_send_vfu_request(LinphoneCall *call);
/** @deprecated Use linphone_call_get_user_data() instead. */
#define linphone_call_get_user_pointer(call) linphone_call_get_user_data(call)
LINPHONE_PUBLIC void *linphone_call_get_user_data(LinphoneCall *call);
/** @deprecated Use linphone_call_set_user_data() instead. */
#define linphone_call_set_user_pointer(call, ud) linphone_call_set_user_data(call, ud)
LINPHONE_PUBLIC void linphone_call_set_user_data(LinphoneCall *call, void *user_data);
LINPHONE_PUBLIC void linphone_call_set_next_video_frame_decoded_callback(LinphoneCall *call, LinphoneCallCbFunc cb, void* user_data);
LINPHONE_PUBLIC LinphoneCallState linphone_call_get_transfer_state(LinphoneCall *call);
LINPHONE_PUBLIC void linphone_call_zoom_video(LinphoneCall* call, float zoom_factor, float* cx, float* cy);
LINPHONE_PUBLIC void linphone_call_start_recording(LinphoneCall *call);
LINPHONE_PUBLIC void linphone_call_stop_recording(LinphoneCall *call);
LINPHONE_PUBLIC LinphonePlayer * linphone_call_get_player(LinphoneCall *call);
/**
* Return TRUE if this call is currently part of a conference
@ -860,6 +818,34 @@ typedef enum _LinphoneRegistrationState{
*/
LINPHONE_PUBLIC const char *linphone_registration_state_to_string(LinphoneRegistrationState cs);
LINPHONE_PUBLIC LinphoneProxyConfig *linphone_proxy_config_new(void);
/**
* Acquire a reference to the proxy config.
* @param[in] cfg The proxy config.
* @return The same proxy config.
**/
LINPHONE_PUBLIC LinphoneProxyConfig *linphone_proxy_config_ref(LinphoneProxyConfig *cfg);
/**
* Release reference to the proxy config.
* @param[in] cfg The proxy config.
**/
LINPHONE_PUBLIC void linphone_proxy_config_unref(LinphoneProxyConfig *cfg);
/**
* Retrieve the user pointer associated with the proxy config.
* @param[in] cfg The proxy config.
* @return The user pointer associated with the proxy config.
**/
LINPHONE_PUBLIC void *linphone_proxy_config_get_user_data(const LinphoneProxyConfig *cfg);
/**
* Assign a user pointer to the proxy config.
* @param[in] cfg The proxy config.
* @param[in] ud The user pointer to associate with the proxy config.
**/
LINPHONE_PUBLIC void linphone_proxy_config_set_user_data(LinphoneProxyConfig *cfg, void *ud);
LINPHONE_PUBLIC int linphone_proxy_config_set_server_addr(LinphoneProxyConfig *obj, const char *server_addr);
LINPHONE_PUBLIC int linphone_proxy_config_set_identity(LinphoneProxyConfig *obj, const char *identity);
LINPHONE_PUBLIC int linphone_proxy_config_set_route(LinphoneProxyConfig *obj, const char *route);
@ -1036,14 +1022,6 @@ LINPHONE_PUBLIC SipSetup *linphone_proxy_config_get_sip_setup(LinphoneProxyConfi
* normalize a human readable phone number into a basic string. 888-444-222 becomes 888444222
*/
LINPHONE_PUBLIC int linphone_proxy_config_normalize_number(LinphoneProxyConfig *proxy, const char *username, char *result, size_t result_len);
/*
* attached a user data to a proxy config
*/
LINPHONE_PUBLIC void linphone_proxy_config_set_user_data(LinphoneProxyConfig *cr, void * ud);
/*
* get user data to a proxy config. return null if any
*/
LINPHONE_PUBLIC void * linphone_proxy_config_get_user_data(LinphoneProxyConfig *cr);
/**
* Set default privacy policy for all calls routed through this proxy.
@ -1074,6 +1052,7 @@ LINPHONE_PUBLIC const char* linphone_proxy_config_get_file_transfer_server(const
* Indicates whether AVPF/SAVPF must be used for calls using this proxy config.
* @param[in] cfg #LinphoneProxyConfig object
* @param[in] enable True to enable AVPF/SAVF, false to disable it.
* @deprecated use linphone_proxy_config_set_avpf_mode()
*/
LINPHONE_PUBLIC void linphone_proxy_config_enable_avpf(LinphoneProxyConfig *cfg, bool_t enable);
@ -1081,6 +1060,7 @@ LINPHONE_PUBLIC void linphone_proxy_config_enable_avpf(LinphoneProxyConfig *cfg,
* Indicates whether AVPF/SAVPF is being used for calls using this proxy config.
* @param[in] cfg #LinphoneProxyConfig object
* @return True if AVPF/SAVPF is enabled, false otherwise.
* @deprecated use linphone_proxy_config_set_avpf_mode()
*/
LINPHONE_PUBLIC bool_t linphone_proxy_config_avpf_enabled(LinphoneProxyConfig *cfg);
@ -1098,6 +1078,20 @@ LINPHONE_PUBLIC void linphone_proxy_config_set_avpf_rr_interval(LinphoneProxyCon
*/
LINPHONE_PUBLIC uint8_t linphone_proxy_config_get_avpf_rr_interval(const LinphoneProxyConfig *cfg);
/**
* Get enablement status of RTCP feedback (also known as AVPF profile).
* @param[in] cfg the proxy config
* @return the enablement mode, which can be LinphoneAVPFDefault (use LinphoneCore's mode), LinphoneAVPFEnabled (avpf is enabled), or LinphoneAVPFDisabled (disabled).
**/
LINPHONE_PUBLIC LinphoneAVPFMode linphone_proxy_config_get_avpf_mode(const LinphoneProxyConfig *cfg);
/**
* Enable the use of RTCP feedback (also known as AVPF profile).
* @param[in] cfg the proxy config
* @param[in] mode the enablement mode, which can be LinphoneAVPFDefault (use LinphoneCore's mode), LinphoneAVPFEnabled (avpf is enabled), or LinphoneAVPFDisabled (disabled).
**/
LINPHONE_PUBLIC void linphone_proxy_config_set_avpf_mode(LinphoneProxyConfig *cfg, LinphoneAVPFMode mode);
/**
* @}
**/
@ -1324,6 +1318,7 @@ LINPHONE_PUBLIC void linphone_core_set_chat_database_path(LinphoneCore *lc, cons
LINPHONE_PUBLIC LinphoneChatRoom * linphone_core_create_chat_room(LinphoneCore *lc, const char *to);
LINPHONE_PUBLIC LinphoneChatRoom * linphone_core_get_or_create_chat_room(LinphoneCore *lc, const char *to);
LINPHONE_PUBLIC LinphoneChatRoom *linphone_core_get_chat_room(LinphoneCore *lc, const LinphoneAddress *addr);
LINPHONE_PUBLIC LinphoneChatRoom *linphone_core_get_chat_room_from_uri(LinphoneCore *lc, const char *to);
LINPHONE_PUBLIC void linphone_core_disable_chat(LinphoneCore *lc, LinphoneReason deny_reason);
LINPHONE_PUBLIC void linphone_core_enable_chat(LinphoneCore *lc);
LINPHONE_PUBLIC bool_t linphone_core_chat_enabled(const LinphoneCore *lc);
@ -1331,6 +1326,33 @@ LINPHONE_PUBLIC void linphone_chat_room_destroy(LinphoneChatRoom *cr);
LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_message(LinphoneChatRoom *cr,const char* message);
LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_room_create_message_2(LinphoneChatRoom *cr, const char* message, const char* external_body_url, LinphoneChatMessageState state, time_t time, bool_t is_read, bool_t is_incoming);
/**
* Acquire a reference to the chat room.
* @param[in] cr The chat room.
* @return The same chat room.
**/
LINPHONE_PUBLIC LinphoneChatRoom *linphone_chat_room_ref(LinphoneChatRoom *cr);
/**
* Release reference to the chat room.
* @param[in] cr The chat room.
**/
LINPHONE_PUBLIC void linphone_chat_room_unref(LinphoneChatRoom *cr);
/**
* Retrieve the user pointer associated with the chat room.
* @param[in] cr The chat room.
* @return The user pointer associated with the chat room.
**/
LINPHONE_PUBLIC void *linphone_chat_room_get_user_data(const LinphoneChatRoom *cr);
/**
* Assign a user pointer to the chat room.
* @param[in] cr The chat room.
* @param[in] ud The user pointer to associate with the chat room.
**/
LINPHONE_PUBLIC void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void *ud);
/**
* Create a message attached to a dedicated chat room with a particular content. Use #linphone_chat_room_file_transfer_send to initiate the transfer
* @param[in] cr the chat room.
@ -1379,8 +1401,6 @@ LINPHONE_PUBLIC bool_t linphone_chat_room_is_remote_composing(const LinphoneChat
LINPHONE_PUBLIC int linphone_chat_room_get_unread_messages_count(LinphoneChatRoom *cr);
LINPHONE_PUBLIC LinphoneCore* linphone_chat_room_get_lc(LinphoneChatRoom *cr);
LINPHONE_PUBLIC LinphoneCore* linphone_chat_room_get_core(LinphoneChatRoom *cr);
LINPHONE_PUBLIC void linphone_chat_room_set_user_data(LinphoneChatRoom *cr, void * ud);
LINPHONE_PUBLIC void * linphone_chat_room_get_user_data(LinphoneChatRoom *cr);
LINPHONE_PUBLIC MSList* linphone_core_get_chat_rooms(LinphoneCore *lc);
LINPHONE_PUBLIC unsigned int linphone_chat_message_store(LinphoneChatMessage *msg);
@ -1390,10 +1410,17 @@ LINPHONE_PUBLIC LinphoneChatMessage* linphone_chat_message_clone(const LinphoneC
LINPHONE_PUBLIC LinphoneChatMessage * linphone_chat_message_ref(LinphoneChatMessage *msg);
LINPHONE_PUBLIC void linphone_chat_message_unref(LinphoneChatMessage *msg);
LINPHONE_PUBLIC void linphone_chat_message_destroy(LinphoneChatMessage* msg);
LINPHONE_PUBLIC void linphone_chat_message_set_from(LinphoneChatMessage* message, const LinphoneAddress* from);
LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_from(const LinphoneChatMessage* message);
LINPHONE_PUBLIC void linphone_chat_message_set_to(LinphoneChatMessage* message, const LinphoneAddress* from);
LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_to(const LinphoneChatMessage* message);
/** @deprecated Use linphone_chat_message_set_from_address() instead. */
#define linphone_chat_message_set_from(msg, addr) linphone_chat_message_set_from_address(msg, addr)
LINPHONE_PUBLIC void linphone_chat_message_set_from_address(LinphoneChatMessage* message, const LinphoneAddress* addr);
/** @deprecated Use linphone_chat_message_get_from_address() instead. */
#define linphone_chat_message_get_from(msg) linphone_chat_message_get_from_address(msg)
LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_from_address(const LinphoneChatMessage* message);
#define linphone_chat_message_set_to(msg, addr) linphone_chat_message_set_to_address(msg, addr)
LINPHONE_PUBLIC void linphone_chat_message_set_to_address(LinphoneChatMessage* message, const LinphoneAddress* addr);
/** @deprecated Use linphone_chat_message_get_to_address() instead. */
#define linphone_chat_message_get_to(msg) linphone_chat_message_get_to_address(msg)
LINPHONE_PUBLIC const LinphoneAddress* linphone_chat_message_get_to_address(const LinphoneChatMessage* message);
LINPHONE_PUBLIC const char* linphone_chat_message_get_external_body_url(const LinphoneChatMessage* message);
LINPHONE_PUBLIC void linphone_chat_message_set_external_body_url(LinphoneChatMessage* message,const char* url);
LINPHONE_PUBLIC const LinphoneContent* linphone_chat_message_get_file_transfer_information(const LinphoneChatMessage* message);
@ -1439,6 +1466,14 @@ typedef enum _LinphoneGlobalState{
const char *linphone_global_state_to_string(LinphoneGlobalState gs);
/**
* LinphoneCoreLogCollectionUploadState is used to notify if log collection upload have been succesfully delivered or not.
*/
typedef enum _LinphoneCoreLogCollectionUploadState {
LinphoneCoreLogCollectionUploadStateInProgress, /**< Delivery in progress */
LinphoneCoreLogCollectionUploadStateDelivered, /**< Log collection upload successfully delivered and acknowledged by remote end point */
LinphoneCoreLogCollectionUploadStateNotDelivered, /**< Log collection upload was not delivered */
} LinphoneCoreLogCollectionUploadState;
/**
* Global state notification callback.
@ -1638,6 +1673,28 @@ typedef enum _LinphoneConfiguringState {
*/
typedef void (*LinphoneCoreConfiguringStatusCb)(LinphoneCore *lc, LinphoneConfiguringState status, const char *message);
/**
* Callback prototype for reporting network change either automatically detected or notified by #linphone_core_set_network_reachable.
* @param lc the LinphoneCore
* @param reachable true if network is reachable.
*/
typedef void (*LinphoneCoreNetworkReachableCb)(LinphoneCore *lc, bool_t reachable);
/**
* Callback prototype for reporting log collection upload state change.
* @param[in] lc LinphoneCore object
* @param[in] state The state of the log collection upload
* @param[in] info Additional information: error message in case of error state, URL of uploaded file in case of success.
*/
typedef void (*LinphoneCoreLogCollectionUploadStateChangedCb)(LinphoneCore *lc, LinphoneCoreLogCollectionUploadState state, const char *info);
/**
* Callback prototype for reporting log collection upload progress indication.
* @param[in] lc LinphoneCore object
* @param[in] progress Percentage of the file size of the log collection already uploaded.
*/
typedef void (*LinphoneCoreLogCollectionUploadProgressIndicationCb)(LinphoneCore *lc, size_t progress);
/**
* This structure holds all callbacks that the application should implement.
* None is mandatory.
@ -1668,12 +1725,27 @@ typedef struct _LinphoneCoreVTable{
DisplayMessageCb display_warning;/**< @deprecated Callback to display a warning to the user */
DisplayUrlCb display_url; /**< @deprecated */
ShowInterfaceCb show; /**< @deprecated Notifies the application that it should show up*/
LinphoneCoreTextMessageReceivedCb text_received; /** @deprecated, use #message_received instead <br> A text message has been received */
LinphoneCoreFileTransferRecvCb file_transfer_recv; /** Callback to store file received attached to a #LinphoneChatMessage */
LinphoneCoreFileTransferSendCb file_transfer_send; /** Callback to collect file chunk to be sent for a #LinphoneChatMessage */
LinphoneCoreFileTransferProgressIndicationCb file_transfer_progress_indication; /**Callback to indicate file transfer progress*/
LinphoneCoreTextMessageReceivedCb text_received; /**< @deprecated, use #message_received instead <br> A text message has been received */
LinphoneCoreFileTransferRecvCb file_transfer_recv; /**< Callback to store file received attached to a #LinphoneChatMessage */
LinphoneCoreFileTransferSendCb file_transfer_send; /**< Callback to collect file chunk to be sent for a #LinphoneChatMessage */
LinphoneCoreFileTransferProgressIndicationCb file_transfer_progress_indication; /**< Callback to indicate file transfer progress */
LinphoneCoreNetworkReachableCb network_reachable; /**< Callback to report IP network status (I.E up/down )*/
LinphoneCoreLogCollectionUploadStateChangedCb log_collection_upload_state_changed; /**< Callback to upload collected logs */
LinphoneCoreLogCollectionUploadProgressIndicationCb log_collection_upload_progress_indication; /**< Callback to indicate log collection upload progress */
} LinphoneCoreVTable;
/**
* Instantiate a vtable with all argument set to NULL
* @returns newly allocated vtable
*/
LINPHONE_PUBLIC LinphoneCoreVTable *linphone_vtable_new();
/**
* destroy a vtable.
* @param vtable to be destroyed
*/
LINPHONE_PUBLIC void linphone_vtable_destroy(LinphoneCoreVTable* table);
/**
* @}
**/
@ -1707,6 +1779,35 @@ typedef void * (*LinphoneCoreWaitingCallback)(LinphoneCore *lc, void *context, L
/* THE main API */
/**
* Enable the linphone core log collection to upload logs on a server.
* @ingroup misc
* @param[in] enable Boolean value telling whether to enable log collection or not.
*/
LINPHONE_PUBLIC void linphone_core_enable_log_collection(bool_t enable);
/**
* Set the path where the log files will be written for log collection.
* @ingroup misc
* @param[in] path The path where the log files will be written.
*/
LINPHONE_PUBLIC void linphone_core_set_log_collection_path(const char *path);
/**
* Set the url of the server where to upload the collected log files.
* @ingroup misc
* @param[in] core LinphoneCore object
* @param[in] server_url The url of the server where to upload the collected log files.
*/
LINPHONE_PUBLIC void linphone_core_set_log_collection_upload_server_url(LinphoneCore *core, const char *server_url);
/**
* Upload the log collection to the configured server url.
* @ingroup misc
* @param[in] core LinphoneCore object
*/
LINPHONE_PUBLIC void linphone_core_upload_log_collection(LinphoneCore *core);
/**
* Define a log handler.
*
@ -1778,24 +1879,26 @@ LINPHONE_PUBLIC LinphoneCore *linphone_core_new_with_config(const LinphoneCoreVT
/* function to be periodically called in a main loop */
/* For ICE to work properly it should be called every 20ms */
LINPHONE_PUBLIC void linphone_core_iterate(LinphoneCore *lc);
#if 0 /*not implemented yet*/
/**
* @ingroup initializing
* Provide Linphone Core with an unique identifier. This be later used to identified contact address coming from this device.
* Value is not saved.
* add a listener to be notified of linphone core events. Once events are received, registered vtable are invoked in order.
* @param vtable a LinphoneCoreVTable structure holding your application callbacks. Object is owned by linphone core until linphone_core_remove_listener.
* @param lc object
* @param string identifying the device, can be EMEI or UDID
*
*/
void linphone_core_set_device_identifier(LinphoneCore *lc,const char* device_id);
LINPHONE_PUBLIC void linphone_core_add_listener(LinphoneCore *lc, LinphoneCoreVTable *vtable);
/**
* @ingroup initializing
* get Linphone unique identifier
* remove a listener registred by linphone_core_add_listener.
* @param vtable a LinphoneCoreVTable structure holding your application callbacks
* @param lc object
* @param string identifying the device, can be EMEI or UDID
*
*/
const char* linphone_core_get_device_identifier(const LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_core_remove_listener(LinphoneCore *lc, const LinphoneCoreVTable *vtable);
#endif
/*sets the user-agent string in sip messages, ideally called just after linphone_core_new() or linphone_core_init() */
LINPHONE_PUBLIC void linphone_core_set_user_agent(LinphoneCore *lc, const char *ua_name, const char *version);
@ -1816,7 +1919,16 @@ LINPHONE_PUBLIC int linphone_core_transfer_call_to_another(LinphoneCore *lc, Lin
LINPHONE_PUBLIC LinphoneCall * linphone_core_start_refered_call(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params);
LINPHONE_PUBLIC bool_t linphone_core_inc_invite_pending(LinphoneCore*lc);
/** @deprecated Use linphone_core_is_incoming_invite_pending() instead. */
#define linphone_core_inc_invite_pending(lc) linphone_core_is_incoming_invite_pending(lc)
/**
* Tells whether there is an incoming invite pending.
* @ingroup call_control
* @param[in] lc LinphoneCore object
* @return A boolean telling whether an incoming invite is pending or not.
*/
LINPHONE_PUBLIC bool_t linphone_core_is_incoming_invite_pending(LinphoneCore*lc);
LINPHONE_PUBLIC bool_t linphone_core_in_call(const LinphoneCore *lc);
@ -1862,9 +1974,12 @@ LINPHONE_PUBLIC int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneC
* Get default call parameters reflecting current linphone core configuration
* @param lc LinphoneCore object
* @return LinphoneCallParams
* @deprecated use linphone_core_create_call_params()
*/
LINPHONE_PUBLIC LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *lc);
LINPHONE_PUBLIC LinphoneCallParams *linphone_core_create_call_params(LinphoneCore *lc, LinphoneCall *call);
LINPHONE_PUBLIC LinphoneCall *linphone_core_get_call_by_remote_address(LinphoneCore *lc, const char *remote_address);
LINPHONE_PUBLIC void linphone_core_send_dtmf(LinphoneCore *lc,char dtmf);
@ -1893,6 +2008,9 @@ LINPHONE_PUBLIC int linphone_core_get_upload_bandwidth(const LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_core_enable_adaptive_rate_control(LinphoneCore *lc, bool_t enabled);
LINPHONE_PUBLIC bool_t linphone_core_adaptive_rate_control_enabled(const LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_core_set_adaptive_rate_algorithm(LinphoneCore *lc, const char *algorithm);
LINPHONE_PUBLIC const char* linphone_core_get_adaptive_rate_algorithm(const LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_core_set_download_ptime(LinphoneCore *lc, int ptime);
LINPHONE_PUBLIC int linphone_core_get_download_ptime(LinphoneCore *lc);
@ -2031,12 +2149,17 @@ LINPHONE_PUBLIC void linphone_core_remove_proxy_config(LinphoneCore *lc, Linphon
LINPHONE_PUBLIC const MSList *linphone_core_get_proxy_config_list(const LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_core_set_default_proxy(LinphoneCore *lc, LinphoneProxyConfig *config);
/** @deprecated Use linphone_core_set_default_proxy_config() instead. */
#define linphone_core_set_default_proxy(lc, config) linphone_core_set_default_proxy_config(lc, config)
void linphone_core_set_default_proxy_index(LinphoneCore *lc, int index);
LINPHONE_PUBLIC int linphone_core_get_default_proxy(LinphoneCore *lc, LinphoneProxyConfig **config);
LINPHONE_PUBLIC LinphoneProxyConfig * linphone_core_get_default_proxy_config(LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_core_set_default_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *config);
/**
* Create an authentication information with default values from Linphone core.
* @param[in] lc #LinphoneCore object
@ -2345,34 +2468,54 @@ bool_t linphone_core_get_rtp_no_xmit_on_audio_mute(const LinphoneCore *lc);
void linphone_core_set_rtp_no_xmit_on_audio_mute(LinphoneCore *lc, bool_t val);
/* returns a list of LinphoneCallLog */
LINPHONE_PUBLIC const MSList * linphone_core_get_call_logs(LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_core_clear_call_logs(LinphoneCore *lc);
/*******************************************************************************
* Call log related functions *
******************************************************************************/
/**
* @addtogroup call_logs
* @{
**/
/**
* Get the list of call logs (past calls).
* @param[in] lc LinphoneCore object
* @return \mslist{LinphoneCallLog}
**/
LINPHONE_PUBLIC const MSList * linphone_core_get_call_logs(LinphoneCore *lc);
/**
* Erase the call log.
* @param[in] lc LinphoneCore object
**/
LINPHONE_PUBLIC void linphone_core_clear_call_logs(LinphoneCore *lc);
/**
* Get the number of missed calls.
* Once checked, this counter can be reset with linphone_core_reset_missed_calls_count().
* @param[in] lc #LinphoneCore object.
* @returns The number of missed calls.
* @ingroup call_logs
**/
LINPHONE_PUBLIC int linphone_core_get_missed_calls_count(LinphoneCore *lc);
LINPHONE_PUBLIC int linphone_core_get_missed_calls_count(LinphoneCore *lc);
/**
* Reset the counter of missed calls.
* @param[in] lc #LinphoneCore object.
* @ingroup call_logs
**/
LINPHONE_PUBLIC void linphone_core_reset_missed_calls_count(LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_core_reset_missed_calls_count(LinphoneCore *lc);
/**
* Remove a specific call log from call history list.
* This function destroys the call log object. It must not be accessed anymore by the application after calling this function.
* @param[in] lc #LinphoneCore object
* @param[in] call_log #LinphoneCallLog object to remove.
* @ingroup call_logs
**/
LINPHONE_PUBLIC void linphone_core_remove_call_log(LinphoneCore *lc, LinphoneCallLog *call_log);
LINPHONE_PUBLIC void linphone_core_remove_call_log(LinphoneCore *lc, LinphoneCallLog *call_log);
/**
* @}
**/
/* video support */
LINPHONE_PUBLIC bool_t linphone_core_video_supported(LinphoneCore *lc);
@ -2421,6 +2564,24 @@ LINPHONE_PUBLIC void linphone_core_enable_video_capture(LinphoneCore *lc, bool_t
**/
LINPHONE_PUBLIC void linphone_core_enable_video_display(LinphoneCore *lc, bool_t enable);
/**
* Enable or disable video source reuse when switching from preview to actual video call.
*
* This source reuse is useful when you always display the preview, even before calls are initiated.
* By keeping the video source for the transition to a real video call, you will smooth out the
* source close/reopen cycle.
*
* This function does not have any effect durfing calls. It just indicates the #LinphoneCore to
* initiate future calls with video source reuse or not.
* Also, at the end of a video call, the source will be closed whatsoever for now.
* @param[in] lc #LinphoneCore object
* @param[in] enable TRUE to enable video source reuse. FALSE to disable it for subsequent calls.
* @ingroup media_parameters
*
*/
LINPHONE_PUBLIC void linphone_core_enable_video_source_reuse(LinphoneCore* lc, bool_t enable);
/**
* Tells whether video capture is enabled.
* @param[in] lc #LinphoneCore object.
@ -2449,6 +2610,7 @@ LINPHONE_PUBLIC const MSVideoSizeDef *linphone_core_get_supported_video_sizes(Li
LINPHONE_PUBLIC void linphone_core_set_preferred_video_size(LinphoneCore *lc, MSVideoSize vsize);
LINPHONE_PUBLIC void linphone_core_set_preview_video_size(LinphoneCore *lc, MSVideoSize vsize);
LINPHONE_PUBLIC void linphone_core_set_preview_video_size_by_name(LinphoneCore *lc, const char *name);
LINPHONE_PUBLIC MSVideoSize linphone_core_get_preview_video_size(const LinphoneCore *lc);
LINPHONE_PUBLIC MSVideoSize linphone_core_get_preferred_video_size(LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_core_set_preferred_video_size_by_name(LinphoneCore *lc, const char *name);
LINPHONE_PUBLIC void linphone_core_set_preferred_framerate(LinphoneCore *lc, float fps);
@ -2525,7 +2687,7 @@ LINPHONE_PUBLIC void linphone_core_set_native_preview_window_id(LinphoneCore *lc
LINPHONE_PUBLIC void linphone_core_use_preview_window(LinphoneCore *lc, bool_t yesno);
int linphone_core_get_device_rotation(LinphoneCore *lc );
void linphone_core_set_device_rotation(LinphoneCore *lc, int rotation);
LINPHONE_PUBLIC void linphone_core_set_device_rotation(LinphoneCore *lc, int rotation);
/**
* Get the camera sensor rotation.
@ -2541,8 +2703,10 @@ LINPHONE_PUBLIC int linphone_core_get_camera_sensor_rotation(LinphoneCore *lc);
/* start or stop streaming video in case of embedded window */
void linphone_core_show_video(LinphoneCore *lc, bool_t show);
/** @deprecated Use linphone_core_set_use_files() instead. */
#define linphone_core_use_files(lc, yesno) linphone_core_set_use_files(lc, yesno)
/*play/record support: use files instead of soundcard*/
LINPHONE_PUBLIC void linphone_core_use_files(LinphoneCore *lc, bool_t yesno);
LINPHONE_PUBLIC void linphone_core_set_use_files(LinphoneCore *lc, bool_t yesno);
LINPHONE_PUBLIC void linphone_core_set_play_file(LinphoneCore *lc, const char *file);
LINPHONE_PUBLIC void linphone_core_set_record_file(LinphoneCore *lc, const char *file);
@ -2579,7 +2743,7 @@ LINPHONE_PUBLIC void linphone_core_enable_keep_alive(LinphoneCore* lc,bool_t ena
*/
LINPHONE_PUBLIC bool_t linphone_core_keep_alive_enabled(LinphoneCore* lc);
LINPHONE_PUBLIC void *linphone_core_get_user_data(LinphoneCore *lc);
LINPHONE_PUBLIC void *linphone_core_get_user_data(const LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_core_set_user_data(LinphoneCore *lc, void *userdata);
/* returns LpConfig object to read/write to the config file: usefull if you wish to extend
@ -2739,7 +2903,7 @@ typedef struct _LinphoneTunnel LinphoneTunnel;
/**
* get tunnel instance if available
*/
LINPHONE_PUBLIC LinphoneTunnel *linphone_core_get_tunnel(LinphoneCore *lc);
LINPHONE_PUBLIC LinphoneTunnel *linphone_core_get_tunnel(const LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_core_set_sip_dscp(LinphoneCore *lc, int dscp);
LINPHONE_PUBLIC int linphone_core_get_sip_dscp(const LinphoneCore *lc);
@ -2839,6 +3003,13 @@ LINPHONE_PUBLIC void linphone_core_set_tone(LinphoneCore *lc, LinphoneToneID id,
* */
LINPHONE_PUBLIC void linphone_core_set_file_transfer_server(LinphoneCore *core, const char * server_url);
/**
* Get the globaly set http file transfer server to be used for content type application/vnd.gsma.rcs-ft-http+xml.
* @param[in] core #LinphoneCore from which to get the server_url
* @return URL of the file server like https://file.linphone.org/upload.php
* */
LINPHONE_PUBLIC const char * linphone_core_get_file_transfer_server(LinphoneCore *core);
/**
* Returns a null terminated table of strings containing the file format extension supported for call recording.
* @param core the core
@ -2847,6 +3018,16 @@ LINPHONE_PUBLIC void linphone_core_set_file_transfer_server(LinphoneCore *core,
**/
LINPHONE_PUBLIC const char ** linphone_core_get_supported_file_formats(LinphoneCore *core);
LINPHONE_PUBLIC void linphone_core_add_supported_tag(LinphoneCore *core, const char *tag);
LINPHONE_PUBLIC void linphone_core_remove_supported_tag(LinphoneCore *core, const char *tag);
LINPHONE_PUBLIC void linphone_core_set_avpf_mode(LinphoneCore *lc, LinphoneAVPFMode mode);
LINPHONE_PUBLIC LinphoneAVPFMode linphone_core_get_avpf_mode(const LinphoneCore *lc);
LINPHONE_PUBLIC int linphone_core_get_avpf_rr_interval(const LinphoneCore *lc);
#ifdef __cplusplus
}
#endif

View file

@ -27,6 +27,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
extern "C" {
#include "mediastreamer2/mediastream.h"
#include "mediastreamer2/mscommon.h"
#include "mediastreamer2/dsptools.h"
}
#include "mediastreamer2/msjava.h"
#include "private.h"
@ -55,9 +56,11 @@ extern "C" void libmsbcg729_init();
#ifdef HAVE_WEBRTC
extern "C" void libmswebrtc_init();
#endif
#include <belle-sip/wakelock.h>
#endif /*ANDROID*/
/*force linking of ms_audio_diff symbol because the tester requires it.*/
static void *audiodiff=(void*)&ms_audio_diff;
#define RETURN_USER_DATA_OBJECT(javaclass, funcprefix, cobj) \
{ \
@ -76,25 +79,6 @@ extern "C" void libmswebrtc_init();
return jUserDataObj; \
}
#define RETURN_PROXY_CONFIG_USER_DATA_OBJECT(javaclass, funcprefix, cobj) \
{ \
jclass jUserDataObjectClass; \
jmethodID jUserDataObjectCtor; \
jobject jUserDataObj; \
jUserDataObj = (jobject)funcprefix ## _get_user_data(cobj); \
if (jUserDataObj == NULL) { \
jUserDataObjectClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/" javaclass)); \
jUserDataObjectCtor = env->GetMethodID(jUserDataObjectClass,"<init>", "(J)V"); \
jUserDataObj = env->NewObject(jUserDataObjectClass, jUserDataObjectCtor,(jlong) cobj); \
jUserDataObj = env->NewGlobalRef(jUserDataObj); \
funcprefix ## _set_user_data(cobj, jUserDataObj); \
env->DeleteGlobalRef(jUserDataObjectClass); \
} \
return jUserDataObj; \
}
static JavaVM *jvm=0;
static const char* LogDomain = "Linphone";
static jclass handler_class;
@ -208,6 +192,9 @@ public:
vTable.notify_received=notifyReceived;
vTable.publish_state_changed=publishStateChanged;
vTable.configuring_status=configuringStatus;
vTable.file_transfer_progress_indication=fileTransferProgressIndication;
vTable.file_transfer_send=fileTransferSend;
vTable.file_transfer_recv=fileTransferRecv;
listenerClass = (jclass)env->NewGlobalRef(env->GetObjectClass( alistener));
@ -310,6 +297,10 @@ public:
configuringStateId = env->GetMethodID(listenerClass,"configuringStatus","(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneCore$RemoteProvisioningState;Ljava/lang/String;)V");
configuringStateClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneCore$RemoteProvisioningState"));
configuringStateFromIntId = env->GetStaticMethodID(configuringStateClass,"fromInt","(I)Lorg/linphone/core/LinphoneCore$RemoteProvisioningState;");
fileTransferProgressIndicationId = env->GetMethodID(listenerClass, "fileTransferProgressIndication", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;I)V");
fileTransferSendId = env->GetMethodID(listenerClass, "fileTransferSend", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;Ljava/nio/ByteBuffer;I)I");
fileTransferRecvId = env->GetMethodID(listenerClass, "fileTransferRecv", "(Lorg/linphone/core/LinphoneCore;Lorg/linphone/core/LinphoneChatMessage;Lorg/linphone/core/LinphoneContent;[BI)V");
}
~LinphoneCoreData() {
@ -417,6 +408,10 @@ public:
jclass subscriptionDirClass;
jmethodID subscriptionDirFromIntId;
jmethodID fileTransferProgressIndicationId;
jmethodID fileTransferSendId;
jmethodID fileTransferRecvId;
LinphoneCoreVTable vTable;
static void showInterfaceCb(LinphoneCore *lc) {
@ -467,9 +462,35 @@ public:
,env->CallStaticObjectMethod(lcData->globalStateClass,lcData->globalStateFromIntId,(jint)gstate),
message ? env->NewStringUTF(message) : NULL);
}
/*
* returns the java LinphoneProxyConfig associated with a C LinphoneProxyConfig.
**/
jobject getProxy(JNIEnv *env , LinphoneProxyConfig *proxy, jobject core){
jobject jobj=0;
if (proxy!=NULL){
void *up=linphone_proxy_config_get_user_data(proxy);
if (up==NULL){
jobj=env->NewObject(proxyClass,proxyCtrId,core,(jlong)proxy);
linphone_proxy_config_set_user_data(proxy,(void*)env->NewWeakGlobalRef(jobj));
linphone_proxy_config_ref(proxy);
}else{
//promote the weak ref to local ref
jobj=env->NewLocalRef((jobject)up);
if (jobj == NULL){
//the weak ref was dead
jobj=env->NewObject(proxyClass,proxyCtrId,core,(jlong)proxy);
linphone_proxy_config_set_user_data(proxy,(void*)env->NewWeakGlobalRef(jobj));
}
}
}
return jobj;
}
static void registrationStateChange(LinphoneCore *lc, LinphoneProxyConfig* proxy,LinphoneRegistrationState state,const char* message) {
JNIEnv *env = 0;
jint result = jvm->AttachCurrentThread(&env,NULL);
jobject jproxy;
if (result != 0) {
ms_error("cannot attach VM");
return;
@ -478,7 +499,7 @@ public:
env->CallVoidMethod(lcData->listener
,lcData->registrationStateId
,lcData->core
,env->NewObject(lcData->proxyClass,lcData->proxyCtrId,lcData->core,(jlong)proxy)
,(jproxy=lcData->getProxy(env,proxy,lcData->core))
,env->CallStaticObjectMethod(lcData->registrationStateClass,lcData->registrationStateFromIntId,(jint)state),
message ? env->NewStringUTF(message) : NULL);
}
@ -591,19 +612,37 @@ public:
,env->NewObject(lcData->addressClass,lcData->addressCtrId,(jlong)from)
,message ? env->NewStringUTF(message) : NULL);
}
jobject getChatMessage(JNIEnv *env , LinphoneChatMessage *msg){
jobject jobj = 0;
if (msg != NULL){
void *up = linphone_chat_message_get_user_data(msg);
if (up == NULL) {
jobj = env->NewObject(chatMessageClass,chatMessageCtrId,(jlong)linphone_chat_message_ref(msg));
jobj = env->NewGlobalRef(jobj);
linphone_chat_message_set_user_data(msg,(void*)jobj);
} else {
jobj = (jobject)up;
}
}
return jobj;
}
static void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *msg) {
JNIEnv *env = 0;
jobject jmsg;
jint result = jvm->AttachCurrentThread(&env,NULL);
if (result != 0) {
ms_error("cannot attach VM");
return;
}
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc);
/*note: we call linphone_chat_message_ref() because the application does not acquire the object when invoked from a callback*/
env->CallVoidMethod(lcData->listener
,lcData->messageReceivedId
,lcData->core
,env->NewObject(lcData->chatRoomClass,lcData->chatRoomCtrId,(jlong)room)
,env->NewObject(lcData->chatMessageClass,lcData->chatMessageCtrId,(jlong)msg));
,(jmsg = lcData->getChatMessage(env, msg)));
}
static void is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) {
JNIEnv *env = 0;
@ -771,6 +810,64 @@ public:
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc);
env->CallVoidMethod(lcData->listener, lcData->configuringStateId, lcData->core, env->CallStaticObjectMethod(lcData->configuringStateClass,lcData->configuringStateFromIntId,(jint)status), message ? env->NewStringUTF(message) : NULL);
}
static void fileTransferProgressIndication(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, size_t progress) {
JNIEnv *env = 0;
jobject jmsg;
jint result = jvm->AttachCurrentThread(&env,NULL);
if (result != 0) {
ms_error("cannot attach VM");
return;
}
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc);
env->CallVoidMethod(lcData->listener,
lcData->fileTransferProgressIndicationId,
lcData->core,
(jmsg = lcData->getChatMessage(env, message)),
content ? create_java_linphone_content(env, content) : NULL,
progress);
}
static void fileTransferSend(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, char* buff, size_t* size) {
JNIEnv *env = 0;
jobject jmsg;
size_t asking = *size;
jint result = jvm->AttachCurrentThread(&env,NULL);
if (result != 0) {
ms_error("cannot attach VM");
return;
}
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc);
*size = env->CallIntMethod(lcData->listener,
lcData->fileTransferSendId,
lcData->core,
(jmsg = lcData->getChatMessage(env, message)),
content ? create_java_linphone_content(env, content) : NULL,
buff ? env->NewDirectByteBuffer(buff, asking) : NULL,
asking);
}
static void fileTransferRecv(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size) {
JNIEnv *env = 0;
jobject jmsg;
jint result = jvm->AttachCurrentThread(&env,NULL);
if (result != 0) {
ms_error("cannot attach VM");
return;
}
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data(lc);
jbyteArray jbytes = env->NewByteArray(size);
env->SetByteArrayRegion(jbytes, 0, size, (jbyte*)buff);
env->CallVoidMethod(lcData->listener,
lcData->fileTransferRecvId,
lcData->core,
(jmsg = lcData->getChatMessage(env, message)),
content ? create_java_linphone_content(env, content) : NULL,
jbytes,
size);
}
};
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_newLinphoneCore(JNIEnv* env
@ -894,35 +991,37 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setDefaultProxyConfig( J
,jlong pc) {
linphone_core_set_default_proxy((LinphoneCore*)lc,(LinphoneProxyConfig*)pc);
}
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_getDefaultProxyConfig( JNIEnv* env
extern "C" jobject Java_org_linphone_core_LinphoneCoreImpl_getDefaultProxyConfig(JNIEnv* env
,jobject thiz
,jlong lc) {
LinphoneProxyConfig *config=0;
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data((LinphoneCore*)lc);
linphone_core_get_default_proxy((LinphoneCore*)lc,&config);
return (jlong)config;
}
static jobject getOrCreateProxy(JNIEnv* env,LinphoneProxyConfig* proxy){
RETURN_PROXY_CONFIG_USER_DATA_OBJECT("LinphoneProxyConfigImpl", linphone_proxy_config, proxy);
if(config != 0) {
jobject jproxy = lcData->getProxy(env,config,lcData->core);
return jproxy;
} else {
return NULL;
}
}
extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_getProxyConfigList(JNIEnv* env, jobject thiz, jlong lc) {
const MSList* proxies = linphone_core_get_proxy_config_list((LinphoneCore*)lc);
int proxyCount = ms_list_size(proxies);
jclass cls = env->FindClass("org/linphone/core/LinphoneProxyConfigImpl");
jclass cls = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneProxyConfigImpl"));
jobjectArray jProxies = env->NewObjectArray(proxyCount,cls,NULL);
LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_get_user_data((LinphoneCore*)lc);
for (int i = 0; i < proxyCount; i++ ) {
LinphoneProxyConfig* proxy = (LinphoneProxyConfig*)proxies->data;
jobject jproxy = getOrCreateProxy(env,proxy);
jobject jproxy = lcData->getProxy(env,proxy,lcData->core);
if(jproxy != NULL){
env->SetObjectArrayElement(jProxies, i, jproxy);
} else {
return NULL;
}
proxies = proxies->next;
}
env->DeleteGlobalRef(cls);
return jProxies;
}
@ -932,9 +1031,7 @@ extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_addProxyConfig( JNIEnv*
,jlong lc
,jlong pc) {
LinphoneProxyConfig* proxy = (LinphoneProxyConfig*)pc;
linphone_proxy_config_set_user_data(proxy, env->NewGlobalRef(jproxyCfg));
return (jint)linphone_core_add_proxy_config((LinphoneCore*)lc,(LinphoneProxyConfig*)pc);
return (jint)linphone_core_add_proxy_config((LinphoneCore*)lc,proxy);
}
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_removeProxyConfig(JNIEnv* env, jobject thiz, jlong lc, jlong proxy) {
@ -1307,6 +1404,28 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_isAdaptiveRateContro
) {
return (jboolean)linphone_core_adaptive_rate_control_enabled((LinphoneCore*)lc);
}
extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getAdaptiveRateAlgorithm(JNIEnv* env
,jobject thiz
,jlong lc
) {
const char* alg = linphone_core_get_adaptive_rate_algorithm((LinphoneCore*)lc);
if (alg) {
return env->NewStringUTF(alg);
} else {
return NULL;
}
}
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setAdaptiveRateAlgorithm(JNIEnv* env
,jobject thiz
,jlong lc
,jstring jalg) {
const char* alg = jalg?env->GetStringUTFChars(jalg, NULL):NULL;
linphone_core_set_adaptive_rate_algorithm((LinphoneCore*)lc,alg);
if (alg) env->ReleaseStringUTFChars(jalg, alg);
}
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_enableEchoCancellation(JNIEnv* env
,jobject thiz
@ -1546,11 +1665,6 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setMediaEncryptionMandat
linphone_core_set_media_encryption_mandatory((LinphoneCore*)lc, yesno);
}
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_createProxyConfig(JNIEnv* env, jobject thiz, jlong lc) {
LinphoneProxyConfig* proxy = linphone_core_create_proxy_config((LinphoneCore *)lc);
return (jlong) proxy;
}
/*
* Class: org_linphone_core_LinphoneCoreImpl
* Method: disableChat
@ -1581,14 +1695,20 @@ extern "C" JNIEXPORT jboolean JNICALL Java_org_linphone_core_LinphoneCoreImpl_ch
//ProxyConfig
extern "C" jlong Java_org_linphone_core_LinphoneProxyConfigImpl_newLinphoneProxyConfig(JNIEnv* env,jobject thiz) {
LinphoneProxyConfig* proxy = linphone_proxy_config_new();
return (jlong) proxy;
extern "C" jlong Java_org_linphone_core_LinphoneProxyConfigImpl_createProxyConfig(JNIEnv* env, jobject thiz, jlong lc) {
LinphoneProxyConfig* proxy = linphone_core_create_proxy_config((LinphoneCore *)lc);
linphone_proxy_config_set_user_data(proxy,env->NewWeakGlobalRef(thiz));
return (jlong) proxy;
}
extern "C" void Java_org_linphone_core_LinphoneProxyConfigImpl_delete(JNIEnv* env,jobject thiz,jlong ptr) {
linphone_proxy_config_destroy((LinphoneProxyConfig*)ptr);
extern "C" void Java_org_linphone_core_LinphoneProxyConfigImpl_finalize(JNIEnv* env
,jobject thiz
,jlong ptr) {
LinphoneProxyConfig *proxy=(LinphoneProxyConfig*)ptr;
linphone_proxy_config_set_user_data(proxy,NULL);
linphone_proxy_config_unref(proxy);
}
extern "C" void Java_org_linphone_core_LinphoneProxyConfigImpl_setIdentity(JNIEnv* env,jobject thiz,jlong proxyCfg,jstring jidentity) {
const char* identity = env->GetStringUTFChars(jidentity, NULL);
linphone_proxy_config_set_identity((LinphoneProxyConfig*)proxyCfg,identity);
@ -2544,6 +2664,57 @@ extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_destroy(JNIEnv* env
linphone_chat_room_destroy((LinphoneChatRoom*)ptr);
}
extern "C" jlong Java_org_linphone_core_LinphoneChatRoomImpl_createFileTransferMessage(JNIEnv* env, jobject thiz, jlong ptr, jstring jname, jstring jtype, jstring jsubtype, jint data_size) {
LinphoneContent content = {0};
LinphoneChatMessage *message = NULL;
content.type = (char*)env->GetStringUTFChars(jtype, NULL);
content.subtype = (char*)env->GetStringUTFChars(jsubtype, NULL);
content.name = (char*)env->GetStringUTFChars(jname, NULL);
content.size = data_size;
message = linphone_chat_room_create_file_transfer_message((LinphoneChatRoom *)ptr, &content);
env->ReleaseStringUTFChars(jtype, content.type);
env->ReleaseStringUTFChars(jsubtype, content.subtype);
env->ReleaseStringUTFChars(jname, content.name);
return (jlong) message;
}
extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_cancelFileTransfer(JNIEnv* env, jobject thiz, jlong ptr, jlong message) {
linphone_chat_room_cancel_file_transfer((LinphoneChatMessage *)message);
}
extern "C" jobject Java_org_linphone_core_LinphoneChatMessageImpl_getFileTransferInformation(JNIEnv* env, jobject thiz, jlong ptr) {
const LinphoneContent *content = linphone_chat_message_get_file_transfer_information((LinphoneChatMessage *)ptr);
if (content)
return create_java_linphone_content(env, content);
return NULL;
}
extern "C" jstring Java_org_linphone_core_LinphoneChatMessageImpl_getAppData(JNIEnv* env, jobject thiz, jlong ptr) {
const char * app_data = linphone_chat_message_get_appdata((LinphoneChatMessage *)ptr);
return app_data ? env->NewStringUTF(app_data) : NULL;
}
extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_setAppData(JNIEnv* env, jobject thiz, jlong ptr, jstring appdata) {
const char * data = appdata ? env->GetStringUTFChars(appdata, NULL) : NULL;
linphone_chat_message_set_appdata((LinphoneChatMessage *)ptr, data);
if (appdata)
env->ReleaseStringUTFChars(appdata, data);
}
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setFileTransferServer(JNIEnv* env, jobject thiz, jlong ptr, jstring server_url) {
const char * url = server_url ? env->GetStringUTFChars(server_url, NULL) : NULL;
linphone_core_set_file_transfer_server((LinphoneCore *)ptr, url);
if (server_url)
env->ReleaseStringUTFChars(server_url, url);
}
extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getFileTransferServer(JNIEnv* env, jobject thiz, jlong ptr) {
const char * server_url = linphone_core_get_file_transfer_server((LinphoneCore *)ptr);
return server_url ? env->NewStringUTF(server_url) : NULL;
}
extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_store(JNIEnv* env
,jobject thiz
,jlong ptr) {
@ -2731,6 +2902,13 @@ extern "C" void Java_org_linphone_core_LinphoneChatRoomImpl_sendMessage2(JNIEnv*
linphone_chat_room_send_message2((LinphoneChatRoom*)chatroom_ptr, (LinphoneChatMessage*)messagePtr, chat_room_impl_callback, (void*)listener);
}
extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_startFileDownload(JNIEnv* env, jobject thiz, jlong ptr, jobject jlistener) {
jobject listener = env->NewGlobalRef(jlistener);
LinphoneChatMessage * message = (LinphoneChatMessage *)ptr;
message->cb_ud = listener;
linphone_chat_message_start_file_download(message, chat_room_impl_callback);
}
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setVideoWindowId(JNIEnv* env
,jobject thiz
,jlong lc
@ -3361,6 +3539,60 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_tunnelAddServerAndMirror
env->ReleaseStringUTFChars(jHost, cHost);
}
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_tunnelAddServer(JNIEnv *env, jobject thiz, jlong pCore, jobject config) {
LinphoneTunnel *tunnel = linphone_core_get_tunnel((LinphoneCore *)pCore);
if(tunnel != NULL) {
jclass TunnelConfigClass = env->FindClass("org/linphone/core/TunnelConfig");
jmethodID getHostMethod = env->GetMethodID(TunnelConfigClass, "getHost", "()Ljava/lang/String;");
jmethodID getPortMethod = env->GetMethodID(TunnelConfigClass, "getPort", "()I");
jmethodID getRemoteUdpMirrorPortMethod = env->GetMethodID(TunnelConfigClass, "getRemoteUdpMirrorPort", "()I");
jmethodID getDelayMethod = env->GetMethodID(TunnelConfigClass, "getDelay", "()I");
jstring hostString = (jstring)env->CallObjectMethod(config, getHostMethod);
const char *host = env->GetStringUTFChars(hostString, NULL);
if(host == NULL || strlen(host)==0) {
ms_error("LinphoneCore.tunnelAddServer(): no tunnel host defined");
}
LinphoneTunnelConfig *tunnelConfig = linphone_tunnel_config_new();
linphone_tunnel_config_set_host(tunnelConfig, host);
linphone_tunnel_config_set_port(tunnelConfig, env->CallIntMethod(config, getPortMethod));
linphone_tunnel_config_set_remote_udp_mirror_port(tunnelConfig, env->CallIntMethod(config, getRemoteUdpMirrorPortMethod));
linphone_tunnel_config_set_delay(tunnelConfig, env->CallIntMethod(config, getDelayMethod));
linphone_tunnel_add_server(tunnel, tunnelConfig);
env->ReleaseStringUTFChars(hostString, host);
} else {
ms_error("LinphoneCore.tunnelAddServer(): tunnel feature is not enabled");
}
}
extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreImpl_tunnelGetServers(JNIEnv *env, jobject thiz, jlong pCore) {
LinphoneTunnel *tunnel = linphone_core_get_tunnel((LinphoneCore *)pCore);
jclass TunnelConfigClass = env->FindClass("org/linphone/core/TunnelConfig");
jmethodID setHostMethod = env->GetMethodID(TunnelConfigClass, "setHost", "(Ljava/lang/String;)V");
jmethodID setPortMethod = env->GetMethodID(TunnelConfigClass, "setPort", "(I)V");
jmethodID setRemoteUdpMirrorPortMethod = env->GetMethodID(TunnelConfigClass, "setRemoteUdpMirrorPort", "(I)V");
jmethodID setDelayMethod = env->GetMethodID(TunnelConfigClass, "setDelay", "(I)V");
jobjectArray tunnelConfigArray = NULL;
if(tunnel != NULL) {
const MSList *servers = linphone_tunnel_get_servers(tunnel);
const MSList *it;
int i;
ms_message("servers=%p", (void *)servers);
ms_message("taille=%i", ms_list_size(servers));
tunnelConfigArray = env->NewObjectArray(ms_list_size(servers), TunnelConfigClass, NULL);
for(it = servers, i=0; it != NULL; it = it->next, i++) {
const LinphoneTunnelConfig *conf = (const LinphoneTunnelConfig *)it->data;
jobject elt = env->AllocObject(TunnelConfigClass);
env->CallVoidMethod(elt, setHostMethod, env->NewStringUTF(linphone_tunnel_config_get_host(conf)));
env->CallVoidMethod(elt, setPortMethod, linphone_tunnel_config_get_port(conf));
env->CallVoidMethod(elt, setRemoteUdpMirrorPortMethod, linphone_tunnel_config_get_remote_udp_mirror_port(conf));
env->CallVoidMethod(elt, setDelayMethod, linphone_tunnel_config_get_delay(conf));
env->SetObjectArrayElement(tunnelConfigArray, i, elt);
}
}
return tunnelConfigArray;
}
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_tunnelSetHttpProxy(JNIEnv *env,jobject thiz,jlong pCore,
jstring jHost, jint port, jstring username, jstring password) {
@ -3391,6 +3623,37 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_tunnelEnable(JNIEnv *env
linphone_tunnel_enable(tunnel, enable);
}
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_tunnelSetMode(JNIEnv *env, jobject thiz, jlong pCore, jint mode) {
LinphoneTunnel *tunnel = ((LinphoneCore *)pCore)->tunnel;
if(tunnel != NULL) {
linphone_tunnel_set_mode(tunnel, (LinphoneTunnelMode)mode);
}
}
extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_tunnelGetMode(JNIEnv *env, jobject thiz, jlong pCore) {
LinphoneTunnel *tunnel = ((LinphoneCore *)pCore)->tunnel;
if(tunnel != NULL) {
return (jint)linphone_tunnel_get_mode(tunnel);
} else {
return 0;
}
}
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_tunnelEnableSip(JNIEnv *env, jobject thiz, jlong pCore, jboolean enable) {
LinphoneTunnel *tunnel = ((LinphoneCore *)pCore)->tunnel;
if(tunnel != NULL) {
linphone_tunnel_enable_sip(tunnel, (bool_t)enable);
}
}
extern "C" jboolean Java_org_linphone_core_LinphoneCoreImpl_tunnelSipEnabled(JNIEnv *env, jobject thiz, jlong pCore) {
LinphoneTunnel *tunnel = ((LinphoneCore *)pCore)->tunnel;
if(tunnel != NULL) {
return (jboolean)linphone_tunnel_sip_enabled(tunnel);
} else {
return JNI_FALSE;
}
}
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setUserAgent(JNIEnv *env,jobject thiz,jlong pCore, jstring name, jstring version){
const char* cname=env->GetStringUTFChars(name, NULL);
@ -3459,6 +3722,13 @@ extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setAudioDscp(JNIEnv* env
linphone_core_set_audio_dscp((LinphoneCore*)ptr,dscp);
}
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_setAndroidPowerManager(JNIEnv *env, jclass cls, jobject pm) {
#ifdef ANDROID
if(pm != NULL) bellesip_wake_lock_init(env, pm);
else bellesip_wake_lock_uninit(env);
#endif
}
extern "C" jint Java_org_linphone_core_LinphoneCoreImpl_getAudioDscp(JNIEnv* env,jobject thiz,jlong ptr){
return linphone_core_get_audio_dscp((LinphoneCore*)ptr);
}
@ -3705,22 +3975,25 @@ extern "C" jintArray Java_org_linphone_core_LpConfigImpl_getIntRange(JNIEnv *env
static jobject create_java_linphone_content(JNIEnv *env, const LinphoneContent *content){
jclass contentClass;
jmethodID ctor;
jstring jtype, jsubtype, jencoding;
jbyteArray jdata=NULL;
jstring jtype, jsubtype, jencoding, jname;
jbyteArray jdata = NULL;
jint jsize = 0;
contentClass = (jclass)env->NewGlobalRef(env->FindClass("org/linphone/core/LinphoneContentImpl"));
ctor = env->GetMethodID(contentClass,"<init>", "(Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;)V");
ctor = env->GetMethodID(contentClass,"<init>", "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;[BLjava/lang/String;I)V");
jtype=env->NewStringUTF(content->type);
jsubtype=env->NewStringUTF(content->subtype);
jencoding=content->encoding ? env->NewStringUTF(content->encoding) : NULL;
jtype = env->NewStringUTF(content->type);
jsubtype = env->NewStringUTF(content->subtype);
jencoding = content->encoding ? env->NewStringUTF(content->encoding) : NULL;
jname = content->name ? env->NewStringUTF(content->name) : NULL;
jsize = (jint) content->size;
if (content->data){
jdata=env->NewByteArray(content->size);
env->SetByteArrayRegion(jdata,0,content->size,(jbyte*)content->data);
jdata = env->NewByteArray(content->size);
env->SetByteArrayRegion(jdata, 0, content->size, (jbyte*)content->data);
}
jobject jobj=env->NewObject(contentClass,ctor,jtype, jsubtype, jdata,jencoding);
jobject jobj = env->NewObject(contentClass, ctor, jname, jtype, jsubtype, jdata, jencoding, jsize);
env->DeleteGlobalRef(contentClass);
return jobj;
}
@ -4937,3 +5210,109 @@ JNIEXPORT jstring JNICALL Java_org_linphone_core_ErrorInfoImpl_getDetails(JNIEnv
}
#endif
/* Linphone Player */
struct LinphonePlayerData {
LinphonePlayerData(JNIEnv *env, jobject listener, jobject jLinphonePlayer) :
mListener(env->NewGlobalRef(listener)),
mJLinphonePlayer(env->NewGlobalRef(jLinphonePlayer))
{
mListenerClass = (jclass)env->NewGlobalRef(env->GetObjectClass(listener));
mEndOfFileMethodID = env->GetMethodID(mListenerClass, "endOfFile", "(Lorg/linphone/core/LinphonePlayer;)V");
if(mEndOfFileMethodID == NULL) {
ms_error("Could not get endOfFile method ID");
env->ExceptionClear();
}
}
~LinphonePlayerData() {
JNIEnv *env;
jvm->AttachCurrentThread(&env, NULL);
env->DeleteGlobalRef(mListener);
env->DeleteGlobalRef(mListenerClass);
env->DeleteGlobalRef(mJLinphonePlayer);
}
jobject mListener;
jclass mListenerClass;
jobject mJLinphonePlayer;
jmethodID mEndOfFileMethodID;
};
static void _eof_callback(LinphonePlayer *player, void *user_data) {
JNIEnv *env;
LinphonePlayerData *player_data = (LinphonePlayerData *)user_data;
jvm->AttachCurrentThread(&env, NULL);
env->CallVoidMethod(player_data->mListener, player_data->mEndOfFileMethodID, player_data->mJLinphonePlayer);
}
extern "C" jint Java_org_linphone_core_LinphonePlayerImpl_open(JNIEnv *env, jobject jPlayer, jlong ptr, jstring filename, jobject listener) {
LinphonePlayerData *data = NULL;
LinphonePlayerEofCallback cb = NULL;
if(listener) {
data = new LinphonePlayerData(env, listener, jPlayer);
cb = _eof_callback;
}
if(linphone_player_open((LinphonePlayer *)ptr, env->GetStringUTFChars(filename, NULL), cb, data) == -1) {
if(data) delete data;
return -1;
}
return 0;
}
extern "C" jint Java_org_linphone_core_LinphonePlayerImpl_start(JNIEnv *env, jobject jobj, jlong ptr) {
LinphonePlayerData *player_data = (LinphonePlayerData *)((LinphonePlayer *)ptr)->user_data;
return (jint)linphone_player_start((LinphonePlayer *)ptr);
}
extern "C" jint Java_org_linphone_core_LinphonePlayerImpl_pause(JNIEnv *env, jobject jobj, jlong ptr) {
return (jint)linphone_player_pause((LinphonePlayer *)ptr);
}
extern "C" jint Java_org_linphone_core_LinphonePlayerImpl_seek(JNIEnv *env, jobject jobj, jlong ptr, jint timeMs) {
return (jint)linphone_player_seek((LinphonePlayer *)ptr, timeMs);
}
extern "C" jint Java_org_linphone_core_LinphonePlayerImpl_getState(JNIEnv *env, jobject jobj, jlong ptr) {
return (jint)linphone_player_get_state((LinphonePlayer *)ptr);
}
extern "C" jint Java_org_linphone_core_LinphonePlayerImpl_getDuration(JNIEnv *env, jobject jobj, jlong ptr) {
return (jint)linphone_player_get_duration((LinphonePlayer *)ptr);
}
extern "C" jint Java_org_linphone_core_LinphonePlayerImpl_getCurrentPosition(JNIEnv *env, jobject jobj, jlong ptr) {
return (jint)linphone_player_get_current_position((LinphonePlayer *)ptr);
}
extern "C" void Java_org_linphone_core_LinphonePlayerImpl_close(JNIEnv *env, jobject playerPtr, jlong ptr) {
LinphonePlayer *player = (LinphonePlayer *)ptr;
if(player->user_data) {
LinphonePlayerData *data = (LinphonePlayerData *)player->user_data;
if(data) delete data;
player->user_data = NULL;
}
linphone_player_close(player);
}
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_createPlayer(JNIEnv *env, jobject jobj, jlong ptr) {
MSSndCard *snd_card = ms_snd_card_manager_get_default_playback_card(ms_snd_card_manager_get());
if(snd_card == NULL) {
ms_error("No default playback sound card found");
return 0;
}
LinphonePlayer *player = linphone_core_create_file_player((LinphoneCore *)ptr, snd_card, "MSAndroidDisplay");
if(player == NULL) {
ms_error("Fails to create a player");
return 0;
} else {
return (jlong)player;
}
}
extern "C" void Java_org_linphone_core_LinphoneCoreImpl_destroyPlayer(JNIEnv *env, jobject jobj, jlong playerPtr) {
LinphonePlayer *player = (LinphonePlayer *)playerPtr;
if(player->user_data) {
delete (LinphonePlayerData *)player->user_data;;
}
linphone_file_player_destroy(player);
}

View file

@ -29,7 +29,7 @@ struct _lpc2xml_context {
const LpConfig *lpc;
lpc2xml_function cbf;
void *ctx;
xmlDoc *doc;
char errorBuffer[LPC2XML_BZ];
char warningBuffer[LPC2XML_BZ];
@ -42,7 +42,7 @@ lpc2xml_context* lpc2xml_context_new(lpc2xml_function cbf, void *ctx) {
xmlCtx->lpc = NULL;
xmlCtx->cbf = cbf;
xmlCtx->ctx = ctx;
xmlCtx->doc = NULL;
xmlCtx->errorBuffer[0]='\0';
xmlCtx->warningBuffer[0]='\0';
@ -64,8 +64,8 @@ static void lpc2xml_context_clear_logs(lpc2xml_context *ctx) {
}
static void lpc2xml_log(lpc2xml_context *xmlCtx, int level, const char *fmt, ...) {
va_list args;
va_start(args, fmt);
va_list args;
va_start(args, fmt);
if(xmlCtx->cbf != NULL) {
xmlCtx->cbf((xmlCtx)->ctx, level, fmt, args);
}
@ -75,8 +75,8 @@ static void lpc2xml_log(lpc2xml_context *xmlCtx, int level, const char *fmt, ...
static void lpc2xml_genericxml_error(void *ctx, const char *fmt, ...) {
lpc2xml_context *xmlCtx = (lpc2xml_context *)ctx;
int sl = strlen(xmlCtx->errorBuffer);
va_list args;
va_start(args, fmt);
va_list args;
va_start(args, fmt);
vsnprintf(xmlCtx->errorBuffer + sl, LPC2XML_BZ-sl, fmt, args);
va_end(args);
}
@ -85,8 +85,8 @@ static void lpc2xml_genericxml_error(void *ctx, const char *fmt, ...) {
static void lpc2xml_genericxml_warning(void *ctx, const char *fmt, ...) {
lpc2xml_context *xmlCtx = (lpc2xml_context *)ctx;
int sl = strlen(xmlCtx->warningBuffer);
va_list args;
va_start(args, fmt);
va_list args;
va_start(args, fmt);
vsnprintf(xmlCtx->warningBuffer + sl, LPC2XML_BZ-sl, fmt, args);
va_end(args);
}
@ -114,25 +114,27 @@ struct __processSectionCtx {
static void processSection_cb(const char *entry, struct __processSectionCtx *ctx) {
if(ctx->ret == 0) {
const char *comment = "#";
xmlNode *node;
xmlAttr *name_attr;
if (strncmp(comment, entry, strlen(comment)) == 0) {
lpc2xml_log(ctx->ctx, LPC2XML_WARNING, "Skipped commented entry %s", entry);
ctx->ret = 0;
return;
}
xmlNode *node = xmlNewChild(ctx->node, NULL, (const xmlChar *)"entry", NULL);
node = xmlNewChild(ctx->node, NULL, (const xmlChar *)"entry", NULL);
if(node == NULL) {
lpc2xml_log(ctx->ctx, LPC2XML_ERROR, "Can't create \"entry\" element");
ctx->ret = -1;
return;
}
xmlAttr *name_attr = xmlSetProp(node, (const xmlChar *)"name", (const xmlChar *)entry);
name_attr = xmlSetProp(node, (const xmlChar *)"name", (const xmlChar *)entry);
if(name_attr == NULL) {
lpc2xml_log(ctx->ctx, LPC2XML_ERROR, "Can't create name attribute for \"entry\" element");
ctx->ret = -1;
return;
}
ctx->ret = processEntry(ctx->section, entry, node, ctx->ctx);
}
}
@ -154,12 +156,13 @@ struct __processConfigCtx {
static void processConfig_cb(const char *section, struct __processConfigCtx *ctx) {
if(ctx->ret == 0) {
xmlNode *node = xmlNewChild(ctx->node, NULL, (const xmlChar *)"section", NULL);
xmlAttr *name_attr;
if(node == NULL) {
lpc2xml_log(ctx->ctx, LPC2XML_ERROR, "Can't create \"section\" element");
ctx->ret = -1;
return;
}
xmlAttr *name_attr = xmlSetProp(node, (const xmlChar *)"name", (const xmlChar *)section);
name_attr = xmlSetProp(node, (const xmlChar *)"name", (const xmlChar *)section);
if(name_attr == NULL) {
lpc2xml_log(ctx->ctx, LPC2XML_ERROR, "Can't create name attribute for \"section\" element");
ctx->ret = -1;
@ -177,22 +180,25 @@ static int processConfig(xmlNode *node, lpc2xml_context *ctx) {
static int processDoc(xmlDoc *doc, lpc2xml_context *ctx) {
int ret = 0;
xmlNs *xsi_ns;
xmlNs *lpc_ns;
xmlAttr *schemaLocation;
xmlNode *root_node = xmlNewNode(NULL, (const xmlChar *)"config");
if(root_node == NULL) {
lpc2xml_log(ctx, LPC2XML_ERROR, "Can't create \"config\" element");
return -1;
}
xmlNs *lpc_ns = xmlNewNs(root_node, (const xmlChar *)"http://www.linphone.org/xsds/lpconfig.xsd", NULL);
lpc_ns = xmlNewNs(root_node, (const xmlChar *)"http://www.linphone.org/xsds/lpconfig.xsd", NULL);
if(lpc_ns == NULL) {
lpc2xml_log(ctx, LPC2XML_WARNING, "Can't create lpc namespace");
} else {
xmlSetNs(root_node, lpc_ns);
}
xmlNs *xsi_ns = xmlNewNs(root_node, (const xmlChar *)"http://www.w3.org/2001/XMLSchema-instance", (const xmlChar *)"xsi");
xsi_ns = xmlNewNs(root_node, (const xmlChar *)"http://www.w3.org/2001/XMLSchema-instance", (const xmlChar *)"xsi");
if(lpc_ns == NULL) {
lpc2xml_log(ctx, LPC2XML_WARNING, "Can't create xsi namespace");
}
xmlAttr *schemaLocation = xmlNewNsProp(root_node, xsi_ns, (const xmlChar *)"schemaLocation", (const xmlChar *)"http://www.linphone.org/xsds/lpconfig.xsd lpconfig.xsd");
schemaLocation = xmlNewNsProp(root_node, xsi_ns, (const xmlChar *)"schemaLocation", (const xmlChar *)"http://www.linphone.org/xsds/lpconfig.xsd lpconfig.xsd");
if(schemaLocation == NULL) {
lpc2xml_log(ctx, LPC2XML_WARNING, "Can't create schemaLocation");
}
@ -203,12 +209,13 @@ static int processDoc(xmlDoc *doc, lpc2xml_context *ctx) {
static int internal_convert_lpc2xml(lpc2xml_context *ctx) {
int ret = 0;
xmlDoc *doc;
lpc2xml_log(ctx, LPC2XML_DEBUG, "Generation started");
if(ctx->doc != NULL) {
xmlFreeDoc(ctx->doc);
ctx->doc = NULL;
}
xmlDoc *doc = xmlNewDoc((const xmlChar *)"1.0");
doc = xmlNewDoc((const xmlChar *)"1.0");
ret = processDoc(doc, ctx);
if(ret == 0) {
ctx->doc = doc;
@ -226,9 +233,10 @@ int lpc2xml_set_lpc(lpc2xml_context* context, const LpConfig *lpc) {
int lpc2xml_convert_file(lpc2xml_context* context, const char *filename) {
int ret = -1;
xmlSaveCtxtPtr save_ctx;
lpc2xml_context_clear_logs(context);
xmlSetGenericErrorFunc(context, lpc2xml_genericxml_error);
xmlSaveCtxtPtr save_ctx = xmlSaveToFilename(filename, "UTF-8", XML_SAVE_FORMAT);
save_ctx = xmlSaveToFilename(filename, "UTF-8", XML_SAVE_FORMAT);
if(save_ctx != NULL) {
ret = internal_convert_lpc2xml(context);
if(ret == 0) {
@ -248,9 +256,10 @@ int lpc2xml_convert_file(lpc2xml_context* context, const char *filename) {
int lpc2xml_convert_fd(lpc2xml_context* context, int fd) {
int ret = -1;
xmlSaveCtxtPtr save_ctx;
lpc2xml_context_clear_logs(context);
xmlSetGenericErrorFunc(context, lpc2xml_genericxml_error);
xmlSaveCtxtPtr save_ctx = xmlSaveToFd(fd, "UTF-8", XML_SAVE_FORMAT);
save_ctx = xmlSaveToFd(fd, "UTF-8", XML_SAVE_FORMAT);
if(save_ctx != NULL) {
ret = internal_convert_lpc2xml(context);
if(ret == 0) {
@ -271,9 +280,10 @@ int lpc2xml_convert_fd(lpc2xml_context* context, int fd) {
int lpc2xml_convert_string(lpc2xml_context* context, char **content) {
int ret = -1;
xmlBufferPtr buffer = xmlBufferCreate();
xmlSaveCtxtPtr save_ctx;
lpc2xml_context_clear_logs(context);
xmlSetGenericErrorFunc(context, lpc2xml_genericxml_error);
xmlSaveCtxtPtr save_ctx = xmlSaveToBuffer(buffer, "UTF-8", XML_SAVE_FORMAT);
save_ctx = xmlSaveToBuffer(buffer, "UTF-8", XML_SAVE_FORMAT);
if(save_ctx != NULL) {
ret = internal_convert_lpc2xml(context);
if(ret == 0) {

View file

@ -39,6 +39,16 @@
#endif
#endif /*_WIN32_WCE*/
#ifdef _MSC_VER
#ifdef WINAPI_FAMILY_PHONE_APP
#include <stdlib.h>
#else
#include <Shlwapi.h>
#endif
#else
#include <libgen.h>
#endif
#define lp_new0(type,n) (type*)calloc(sizeof(type),n)
@ -271,7 +281,7 @@ static LpSection* lp_config_parse_line(LpConfig* lpconfig, const char* line, LpS
/* remove ending white spaces */
for (; pos2>pos1 && pos2[-1]==' ';pos2--) pos2[-1]='\0';
if (pos2-pos1>=0){
if (pos2-pos1>0){
/* found a pair key,value */
if (cur!=NULL){
@ -457,10 +467,10 @@ int lp_config_get_int(const LpConfig *lpconfig,const char *section, const char *
const char *str=lp_config_get_string(lpconfig,section,key,NULL);
if (str!=NULL) {
int ret=0;
if (strstr(str,"0x")==str){
sscanf(str,"%x",&ret);
}else
}else
sscanf(str,"%i",&ret);
return ret;
}
@ -493,14 +503,14 @@ void lp_config_set_string(LpConfig *lpconfig,const char *section, const char *ke
if (sec!=NULL){
item=lp_section_find_item(sec,key);
if (item!=NULL){
if (value!=NULL)
if (value!=NULL && value[0] != '\0')
lp_item_set_value(item,value);
else lp_section_remove_item(sec,item);
}else{
if (value!=NULL)
if (value!=NULL && value[0] != '\0')
lp_section_add_item(sec,lp_item_new(key,value));
}
}else if (value!=NULL){
}else if (value!=NULL && value[0] != '\0'){
sec=lp_section_new(section);
lp_config_add_section(lpconfig,sec);
lp_section_add_item(sec,lp_item_new(key,value));
@ -542,12 +552,19 @@ void lp_config_set_float(LpConfig *lpconfig,const char *section, const char *key
void lp_item_write(LpItem *item, FILE *file){
if (item->is_comment)
fprintf(file,"%s",item->value);
else
else if (item->value && item->value[0] != '\0' )
fprintf(file,"%s=%s\n",item->key,item->value);
else {
ms_warning("Not writing item %s to file, it is empty", item->key);
}
}
void lp_section_param_write(LpSectionParam *param, FILE *file){
fprintf(file, " %s=%s", param->key, param->value);
if( param->value && param->value[0] != '\0') {
fprintf(file, " %s=%s", param->key, param->value);
} else {
ms_warning("Not writing param %s to file, it is empty", param->key);
}
}
void lp_section_write(LpSection *sec, FILE *file){
@ -650,3 +667,66 @@ const char* lp_config_get_default_string(const LpConfig *lpconfig, const char *s
return lp_config_get_string(lpconfig, default_section, key, default_value);
}
static char *_lp_config_dirname(char *path) {
#ifdef _MSC_VER
#ifdef WINAPI_FAMILY_PHONE_APP
char drive[_MAX_DRIVE];
char dir[_MAX_DIR];
char fname[_MAX_FNAME];
char ext[_MAX_EXT];
_splitpath(path, drive, dir, fname, ext);
return ms_strdup_printf("%s%s", drive, dir);
#else
char *dir = ms_strdup(path);
PathRemoveFileSpec(dir);
return dir;
#endif
#else
char *tmp = ms_strdup(path);
char *dir = ms_strdup(dirname(tmp));
ms_free(tmp);
return dir;
#endif
}
void lp_config_write_relative_file(const LpConfig *lpconfig, const char *filename, const char *data) {
if(strlen(data) > 0) {
char *dir = _lp_config_dirname(lpconfig->filename);
char *filepath = ms_strdup_printf("%s/%s", dir, filename);
FILE *file = fopen(filepath, "w");
if(file != NULL) {
fprintf(file, "%s", data);
fclose(file);
} else {
ms_error("Could not open %s for write", filepath);
}
ms_free(dir);
ms_free(filepath);
} else {
ms_warning("%s has not been created because there is no data to write", filename);
}
}
char *lp_config_read_relative_file(const LpConfig *lpconfig, const char *filename) {
char *dir = _lp_config_dirname(lpconfig->filename);
char *filepath = ms_strdup_printf("%s/%s", dir, filename);
char *result = NULL;
if(ortp_file_exist(filepath) == 0) {
FILE *file = fopen(filepath, "r");
if(file != NULL) {
result = ms_new0(char, MAX_LEN);
if(fgets(result, MAX_LEN, file) == NULL) {
ms_error("%s could not be loaded", filepath);
}
fclose(file);
} else {
ms_error("Could not open %s for read", filepath);
}
} else {
ms_message("%s does not exist", filepath);
}
ms_free(dir);
ms_free(filepath);
return result;
}

View file

@ -272,6 +272,22 @@ LINPHONE_PUBLIC LpConfig *lp_config_ref(LpConfig *lpconfig);
**/
LINPHONE_PUBLIC void lp_config_unref(LpConfig *lpconfig);
/**
* @brief Write a string in a file placed relatively with the Linphone configuration file.
* @param lpconfig LpConfig instance used as a reference
* @param filename Name of the file where to write data. The name is relative to the place of the config file
* @param data String to write
*/
LINPHONE_PUBLIC void lp_config_write_relative_file(const LpConfig *lpconfig, const char *filename, const char *data);
/**
* @brief Read a string from a file placed relatively with the Linphone configuration file
* @param lpconfig LpConfig instance used as a reference
* @param filename Name of the file where data will be read from. The name is relative to the place of the config file
* @return The read string
*/
LINPHONE_PUBLIC char *lp_config_read_relative_file(const LpConfig *lpconfig, const char *filename);
#ifdef __cplusplus
}
#endif

View file

@ -37,6 +37,49 @@ static inline LinphoneChatMessage* get_transient_message(LinphoneChatRoom* cr, u
return NULL;
}
/* DB layout:
* | 0 | storage_id
* | 1 | type
* | 2 | subtype
* | 3 | name
* | 4 | encoding
* | 5 | size
* | 6 | data
*/
// Callback for sql request when getting linphone content
static int callback_content(void *data, int argc, char **argv, char **colName) {
LinphoneChatMessage *message = (LinphoneChatMessage *)data;
if (message->file_transfer_information) {
linphone_content_uninit(message->file_transfer_information);
ms_free(message->file_transfer_information);
message->file_transfer_information = NULL;
}
message->file_transfer_information = (LinphoneContent *)malloc(sizeof(LinphoneContent));
memset(message->file_transfer_information, 0, sizeof(*(message->file_transfer_information)));
message->file_transfer_information->type = argv[1] ? ms_strdup(argv[1]) : NULL;
message->file_transfer_information->subtype = argv[2] ? ms_strdup(argv[2]) : NULL;
message->file_transfer_information->name = argv[3] ? ms_strdup(argv[3]) : NULL;
message->file_transfer_information->encoding = argv[4] ? ms_strdup(argv[4]) : NULL;
message->file_transfer_information->size = (size_t) atoi(argv[5]);
return 0;
}
static void fetch_content_from_database(sqlite3 *db, LinphoneChatMessage *message, int content_id) {
char* errmsg = NULL;
int ret;
char * buf;
buf = sqlite3_mprintf("SELECT * FROM content WHERE id = %i", content_id);
ret = sqlite3_exec(db, buf, callback_content, message, &errmsg);
if (ret != SQLITE_OK) {
ms_error("Error in creation: %s.", errmsg);
sqlite3_free(errmsg);
}
sqlite3_free(buf);
}
/* DB layout:
* | 0 | storage_id
@ -50,6 +93,7 @@ static inline LinphoneChatMessage* get_transient_message(LinphoneChatRoom* cr, u
* | 8 | external body url
* | 9 | utc timestamp
* | 10 | app data text
* | 11 | linphone content
*/
static void create_chat_message(char **argv, void *data){
LinphoneChatRoom *cr = (LinphoneChatRoom *)data;
@ -90,6 +134,13 @@ static void create_chat_message(char **argv, void *data){
new_message->storage_id=storage_id;
new_message->external_body_url= argv[8] ? ms_strdup(argv[8]) : NULL;
new_message->appdata = argv[10]? ms_strdup(argv[10]) : NULL;
if (argv[11] != NULL) {
int id = atoi(argv[11]);
if (id >= 0) {
fetch_content_from_database(cr->lc->db, new_message, id);
}
}
}
cr->messages_hist=ms_list_prepend(cr->messages_hist,new_message);
}
@ -139,24 +190,54 @@ void linphone_sql_request_all(sqlite3* db,const char *stmt, LinphoneCore* lc){
}
}
static int linphone_chat_message_store_content(LinphoneChatMessage *msg) {
LinphoneCore *lc = linphone_chat_room_get_lc(msg->chat_room);
int id = -1;
if (lc->db) {
LinphoneContent *content = msg->file_transfer_information;
char *buf = sqlite3_mprintf("INSERT INTO content VALUES(NULL,%Q,%Q,%Q,%Q,%i,%Q);",
content->type,
content->subtype,
content->name,
content->encoding,
content->size,
NULL
);
linphone_sql_request(lc->db, buf);
sqlite3_free(buf);
id = (unsigned int) sqlite3_last_insert_rowid (lc->db);
}
return id;
}
unsigned int linphone_chat_message_store(LinphoneChatMessage *msg){
LinphoneCore *lc=linphone_chat_room_get_lc(msg->chat_room);
int id=0;
int id = 0;
if (lc->db){
char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(msg->chat_room));
char *local_contact=linphone_address_as_string_uri_only(linphone_chat_message_get_local_address(msg));
char *buf=sqlite3_mprintf("INSERT INTO history VALUES(NULL,%Q,%Q,%i,%Q,%Q,%i,%i,%Q,%i,%Q);",
int content_id = -1;
char *peer;
char *local_contact;
char *buf;
if (msg->file_transfer_information) {
content_id = linphone_chat_message_store_content(msg);
}
peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(msg->chat_room));
local_contact=linphone_address_as_string_uri_only(linphone_chat_message_get_local_address(msg));
buf=sqlite3_mprintf("INSERT INTO history VALUES(NULL,%Q,%Q,%i,%Q,%Q,%i,%i,%Q,%i,%Q,%i);",
local_contact,
peer,
msg->dir,
msg->message,
"-1", /* use UTC field now */
msg->is_read,
msg->state,
msg->external_body_url,
msg->time,
msg->appdata);
peer,
msg->dir,
msg->message,
"-1", /* use UTC field now */
msg->is_read,
msg->state,
msg->external_body_url,
msg->time,
msg->appdata,
content_id
);
linphone_sql_request(lc->db,buf);
sqlite3_free(buf);
ms_free(local_contact);
@ -169,8 +250,8 @@ unsigned int linphone_chat_message_store(LinphoneChatMessage *msg){
void linphone_chat_message_store_state(LinphoneChatMessage *msg){
LinphoneCore *lc=msg->chat_room->lc;
if (lc->db){
char *buf=sqlite3_mprintf("UPDATE history SET status=%i WHERE (message = %Q OR url = %Q) AND utc = %i;",
msg->state,msg->message,msg->external_body_url,msg->time);
char *buf=sqlite3_mprintf("UPDATE history SET status=%i WHERE (id = %i) AND utc = %i;",
msg->state,msg->storage_id,msg->time);
linphone_sql_request(lc->db,buf);
sqlite3_free(buf);
}
@ -196,11 +277,13 @@ void linphone_chat_message_store_appdata(LinphoneChatMessage* msg){
void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr){
LinphoneCore *lc=linphone_chat_room_get_lc(cr);
int read=1;
char *peer;
char *buf;
if (lc->db==NULL) return ;
char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr));
char *buf=sqlite3_mprintf("UPDATE history SET read=%i WHERE remoteContact = %Q;",
peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr));
buf=sqlite3_mprintf("UPDATE history SET read=%i WHERE remoteContact = %Q;",
read,peer);
linphone_sql_request(lc->db,buf);
sqlite3_free(buf);
@ -209,10 +292,11 @@ void linphone_chat_room_mark_as_read(LinphoneChatRoom *cr){
void linphone_chat_room_update_url(LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
LinphoneCore *lc=linphone_chat_room_get_lc(cr);
char *buf;
if (lc->db==NULL) return ;
char *buf=sqlite3_mprintf("UPDATE history SET url=%Q WHERE id=%i;",msg->external_body_url,msg->storage_id);
buf=sqlite3_mprintf("UPDATE history SET url=%Q WHERE id=%i;",msg->external_body_url,msg->storage_id);
linphone_sql_request(lc->db,buf);
sqlite3_free(buf);
}
@ -220,13 +304,16 @@ void linphone_chat_room_update_url(LinphoneChatRoom *cr, LinphoneChatMessage *ms
static int linphone_chat_room_get_messages_count(LinphoneChatRoom *cr, bool_t unread_only){
LinphoneCore *lc=linphone_chat_room_get_lc(cr);
int numrows=0;
char *peer;
char *buf;
sqlite3_stmt *selectStatement;
int returnValue;
if (lc->db==NULL) return 0;
char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr));
char *buf=sqlite3_mprintf("SELECT count(*) FROM history WHERE remoteContact = %Q %s;",peer,unread_only?"AND read = 0":"");
sqlite3_stmt *selectStatement;
int returnValue = sqlite3_prepare_v2(lc->db,buf,-1,&selectStatement,NULL);
peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr));
buf=sqlite3_mprintf("SELECT count(*) FROM history WHERE remoteContact = %Q %s;",peer,unread_only?"AND read = 0":"");
returnValue = sqlite3_prepare_v2(lc->db,buf,-1,&selectStatement,NULL);
if (returnValue == SQLITE_OK){
if(sqlite3_step(selectStatement) == SQLITE_ROW){
numrows= sqlite3_column_int(selectStatement, 0);
@ -248,21 +335,24 @@ int linphone_chat_room_get_history_size(LinphoneChatRoom *cr){
void linphone_chat_room_delete_message(LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
LinphoneCore *lc=cr->lc;
char *buf;
if (lc->db==NULL) return ;
char *buf=sqlite3_mprintf("DELETE FROM history WHERE id = %i;", msg->storage_id);
buf=sqlite3_mprintf("DELETE FROM history WHERE id = %i;", msg->storage_id);
linphone_sql_request(lc->db,buf);
sqlite3_free(buf);
}
void linphone_chat_room_delete_history(LinphoneChatRoom *cr){
LinphoneCore *lc=cr->lc;
char *peer;
char *buf;
if (lc->db==NULL) return ;
char *peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr));
char *buf=sqlite3_mprintf("DELETE FROM history WHERE remoteContact = %Q;",peer);
peer=linphone_address_as_string_uri_only(linphone_chat_room_get_peer_address(cr));
buf=sqlite3_mprintf("DELETE FROM history WHERE remoteContact = %Q;",peer);
linphone_sql_request(lc->db,buf);
sqlite3_free(buf);
ms_free(peer);
@ -393,8 +483,9 @@ static void linphone_migrate_timestamps(sqlite3* db){
sqlite3_free(errmsg);
linphone_sql_request(db, "ROLLBACK");
} else {
uint64_t end;
linphone_sql_request(db, "COMMIT");
uint64_t end=ortp_get_cur_time_ms();
end=ortp_get_cur_time_ms();
ms_message("Migrated message timestamps to UTC in %i ms",(int)(end-begin));
}
}
@ -409,7 +500,7 @@ void linphone_update_table(sqlite3* db) {
ms_message("Table already up to date: %s.", errmsg);
sqlite3_free(errmsg);
} else {
ms_debug("Table updated successfully for URL.");
ms_debug("Table history updated successfully for URL.");
}
// for UTC timestamp storage
@ -418,7 +509,7 @@ void linphone_update_table(sqlite3* db) {
ms_message("Table already up to date: %s.", errmsg);
sqlite3_free(errmsg);
} else {
ms_debug("Table updated successfully for UTC.");
ms_debug("Table history updated successfully for UTC.");
// migrate from old text-based timestamps to unix time-based timestamps
linphone_migrate_timestamps(db);
}
@ -429,7 +520,32 @@ void linphone_update_table(sqlite3* db) {
ms_message("Table already up to date: %s.", errmsg);
sqlite3_free(errmsg);
} else {
ms_debug("Table updated successfully for app-specific data.");
ms_debug("Table history updated successfully for app-specific data.");
}
// new field for linphone content storage
ret=sqlite3_exec(db,"ALTER TABLE history ADD COLUMN content INTEGER;",NULL,NULL,&errmsg);
if(ret != SQLITE_OK) {
ms_message("Table already up to date: %s.", errmsg);
sqlite3_free(errmsg);
} else {
ms_debug("Table history updated successfully for content data.");
ret = sqlite3_exec(db,"CREATE TABLE IF NOT EXISTS content ("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
"type TEXT,"
"subtype TEXT,"
"name TEXT,"
"encoding TEXT,"
"size INTEGER,"
"data BLOB"
");",
0,0,&errmsg);
if(ret != SQLITE_OK) {
ms_error("Error in creation: %s.\n", errmsg);
sqlite3_free(errmsg);
} else {
ms_debug("Table content successfully created.");
}
}
}

View file

@ -131,7 +131,7 @@ static double get_audio_payload_bandwidth_from_codec_bitrate(const PayloadType *
double npacket=50;
double packet_size;
int bitrate;
if (strcmp(payload_type_get_mime(&payload_type_aaceld_44k), payload_type_get_mime(pt))==0) {
/*special case of aac 44K because ptime= 10ms*/
npacket=100;
@ -209,7 +209,7 @@ void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc){
int maxbw=get_min_bandwidth(linphone_core_get_download_bandwidth(lc),
linphone_core_get_upload_bandwidth(lc));
int max_codec_bitrate=0;
for(elem=linphone_core_get_audio_codecs(lc);elem!=NULL;elem=elem->next){
PayloadType *pt=(PayloadType*)elem->data;
if (payload_type_enabled(pt)){
@ -421,8 +421,7 @@ int linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call){
ms_error("Could not obtain stun server addrinfo.");
return -1;
}
if (lc->vtable.display_status!=NULL)
lc->vtable.display_status(lc,_("Stun lookup in progress..."));
linphone_core_notify_display_status(lc,_("Stun lookup in progress..."));
/*create the two audio and video RTP sockets, and send STUN message to our stun server */
sock1=create_socket(call->media_ports[0].rtp_port);
@ -603,8 +602,7 @@ int linphone_core_gather_ice_candidates(LinphoneCore *lc, LinphoneCall *call)
ms_warning("Fail to resolve STUN server for ICE gathering.");
return -1;
}
if (lc->vtable.display_status != NULL)
lc->vtable.display_status(lc, _("ICE local candidates gathering in progress..."));
linphone_core_notify_display_status(lc, _("ICE local candidates gathering in progress..."));
/* Gather local host candidates. */
if (linphone_core_get_local_ip_for(AF_INET, NULL, local_addr) < 0) {
@ -658,7 +656,7 @@ void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call)
} else {
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateFailed;
}
if (call->params.has_video && (video_check_list != NULL)) {
if (call->params->has_video && (video_check_list != NULL)) {
if (ice_check_list_state(video_check_list) == ICL_Completed) {
switch (ice_check_list_selected_valid_candidate_type(video_check_list)) {
case ICT_HostCandidate:
@ -678,12 +676,12 @@ void linphone_core_update_ice_state_in_call_stats(LinphoneCall *call)
}
} else if (session_state == IS_Running) {
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateInProgress;
if (call->params.has_video && (video_check_list != NULL)) {
if (call->params->has_video && (video_check_list != NULL)) {
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateInProgress;
}
} else {
call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateFailed;
if (call->params.has_video && (video_check_list != NULL)) {
if (call->params->has_video && (video_check_list != NULL)) {
call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateFailed;
}
}
@ -939,25 +937,13 @@ 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->nb_streams; i++) {
for (i = 0; md && i < md->nb_streams; i++) {
if (md->streams[i].type == SalVideo && md->streams[i].rtp_port!=0)
return TRUE;
}
return FALSE;
}
LinphoneCall * is_a_linphone_call(void *user_pointer){
LinphoneCall *call=(LinphoneCall*)user_pointer;
if (call==NULL) return NULL;
return call->magic==linphone_call_magic ? call : NULL;
}
LinphoneProxyConfig * is_a_linphone_proxy_config(void *user_pointer){
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)user_pointer;
if (cfg==NULL) return NULL;
return cfg->magic==linphone_proxy_config_magic ? cfg : NULL;
}
unsigned int linphone_core_get_audio_features(LinphoneCore *lc){
unsigned int ret=0;
const char *features=lp_config_get_string(lc->config,"sound","features",NULL);
@ -1008,7 +994,7 @@ static int get_local_ip_with_getifaddrs(int type, char *address, int size){
struct ifaddrs *ifpstart;
char retaddr[LINPHONE_IPADDR_SIZE]={0};
bool_t found=FALSE;
if (getifaddrs(&ifpstart) < 0) {
return -1;
}
@ -1109,6 +1095,9 @@ static int get_local_ip_for_with_connect(int type, const char *dest, char *resul
int linphone_core_get_local_ip_for(int type, const char *dest, char *result){
int err;
#ifdef HAVE_GETIFADDRS
int found_ifs;
#endif
strcpy(result,type==AF_INET ? "127.0.0.1" : "::1");
if (dest==NULL){
@ -1124,8 +1113,6 @@ int linphone_core_get_local_ip_for(int type, const char *dest, char *result){
#ifdef HAVE_GETIFADDRS
/*we use getifaddrs for lookup of default interface */
int found_ifs;
found_ifs=get_local_ip_with_getifaddrs(type,result,LINPHONE_IPADDR_SIZE);
if (found_ifs==1){
return 0;
@ -1137,6 +1124,26 @@ int linphone_core_get_local_ip_for(int type, const char *dest, char *result){
return 0;
}
void linphone_core_get_local_ip(LinphoneCore *lc, int af, const char *dest, char *result) {
if (af == AF_UNSPEC) {
if (linphone_core_ipv6_enabled(lc)) {
bool_t has_ipv6 = linphone_core_get_local_ip_for(AF_INET6, dest, result) == 0;
if (strcmp(result, "::1") != 0)
return; /*this machine has real ipv6 connectivity*/
if ((linphone_core_get_local_ip_for(AF_INET, dest, result) == 0) && (strcmp(result, "127.0.0.1") != 0))
return; /*this machine has only ipv4 connectivity*/
if (has_ipv6) {
/*this machine has only local loopback for both ipv4 and ipv6, so prefer ipv6*/
strncpy(result, "::1", LINPHONE_IPADDR_SIZE);
return;
}
}
/*in all other cases use IPv4*/
af = AF_INET;
}
linphone_core_get_local_ip_for(af, dest, result);
}
SalReason linphone_reason_to_sal(LinphoneReason reason){
switch(reason){
case LinphoneReasonNone:

186
coreapi/player.c Normal file
View file

@ -0,0 +1,186 @@
/*
linphone
Copyright (C) 2014 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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "private.h"
/**
* Open a new source on this player.
* @param obj the player
* @param filename file to open.
* @param cb a callback used to notify end of play.
* @param user_data a user-data provided in the callback to help the application to retrieve its context.
* @return 0 if successful, -1 otherwise
**/
int linphone_player_open(LinphonePlayer *obj, const char *filename, LinphonePlayerEofCallback cb, void *user_data){
obj->user_data=user_data;
obj->cb=cb;
return obj->open(obj,filename);
}
/**
* Start a play operation. The player must have been open previously with linphone_player_open().
* @param obj the player.
* @return 0 if successful, -1 otherwise
**/
int linphone_player_start(LinphonePlayer *obj){
return obj->start(obj);
}
/**
* Suspend a play operation. The player must have been started previously with linphone_player_start().
* @param obj the player.
* @return 0 if successful, -1 otherwise
**/
int linphone_player_pause(LinphonePlayer *obj){
return obj->pause(obj);
}
/**
* Seek at a given position given in milliseconds. The player must be in the paused state.
* @param obj the player.
* @param time_ms the position to seek to.
* @return 0 if successful, -1 otherwise
**/
int linphone_player_seek(LinphonePlayer *obj, int time_ms){
return obj->seek(obj,time_ms);
}
/**
* Get the state of play operation.
* @param obj the player.
* @return the state of the player within MSPlayerClosed, MSPlayerStarted, MSPlayerPaused.
**/
MSPlayerState linphone_player_get_state(LinphonePlayer *obj){
return obj->get_state(obj);
}
/**
* Get the duration of the media
* @param obj the player
* @return The duration in milliseconds
*/
int linphone_player_get_duration(LinphonePlayer *obj) {
return obj->get_duration(obj);
}
/**
* Get the position of the playback
* @param obj the player
* @return Position of the playback in milliseconds
*/
int linphone_player_get_current_position(LinphonePlayer *obj) {
return obj->get_position(obj);
}
/**
* Close the player.
* @param obj the player.
**/
void linphone_player_close(LinphonePlayer *obj){
return obj->close(obj);
}
/*
* Call player implementation below.
*/
static bool_t call_player_check_state(LinphonePlayer *player, bool_t check_player){
LinphoneCall *call=(LinphoneCall*)player->impl;
if (call->state!=LinphoneCallStreamsRunning){
ms_warning("Call [%p]: in-call player not usable in state [%s]",call,linphone_call_state_to_string(call->state));
return FALSE;
}
if (call->audiostream==NULL) {
ms_error("call_player_check_state(): no audiostream.");
return FALSE;
}
if (check_player && call->audiostream->av_player.player==NULL){
ms_error("call_player_check_state(): no player.");
return FALSE;
}
return TRUE;
}
static void on_eof(void *user_data, MSFilter *f, unsigned int event_id, void *arg){
LinphonePlayer *player=(LinphonePlayer *)user_data;
if (player->cb) player->cb(player,player->user_data);
}
static int call_player_open(LinphonePlayer* player, const char *filename){
LinphoneCall *call=(LinphoneCall*)player->impl;
MSFilter *filter;
if (!call_player_check_state(player,FALSE)) return -1;
filter=audio_stream_open_remote_play(call->audiostream,filename);
if (!filter) return -1;
ms_filter_add_notify_callback(filter,&on_eof,player,FALSE);
return 0;
}
static int call_player_start(LinphonePlayer *player){
LinphoneCall *call=(LinphoneCall*)player->impl;
if (!call_player_check_state(player,TRUE)) return -1;
return ms_filter_call_method_noarg(call->audiostream->av_player.player,MS_PLAYER_START);
}
static int call_player_pause(LinphonePlayer *player){
LinphoneCall *call=(LinphoneCall*)player->impl;
if (!call_player_check_state(player,TRUE)) return -1;
return ms_filter_call_method_noarg(call->audiostream->av_player.player,MS_PLAYER_PAUSE);
}
static MSPlayerState call_player_get_state(LinphonePlayer *player){
LinphoneCall *call=(LinphoneCall*)player->impl;
MSPlayerState state=MSPlayerClosed;
if (!call_player_check_state(player,TRUE)) return MSPlayerClosed;
ms_filter_call_method(call->audiostream->av_player.player,MS_PLAYER_GET_STATE,&state);
return state;
}
static int call_player_seek(LinphonePlayer *player, int time_ms){
LinphoneCall *call=(LinphoneCall*)player->impl;
if (!call_player_check_state(player,TRUE)) return -1;
return ms_filter_call_method(call->audiostream->av_player.player,MS_PLAYER_SEEK_MS,&time_ms);
}
static void call_player_close(LinphonePlayer *player){
LinphoneCall *call=(LinphoneCall*)player->impl;
if (!call_player_check_state(player,TRUE)) return;
audio_stream_close_remote_play(call->audiostream);
}
static void on_call_destroy(void *obj, belle_sip_object_t *call_being_destroyed){
ms_free(obj);
}
LinphonePlayer *linphone_call_build_player(LinphoneCall *call){
LinphonePlayer *obj=ms_new0(LinphonePlayer,1);
obj->open=call_player_open;
obj->close=call_player_close;
obj->start=call_player_start;
obj->seek=call_player_seek;
obj->pause=call_player_pause;
obj->get_state=call_player_get_state;
obj->impl=call;
belle_sip_object_weak_ref(call,on_call_destroy,obj);
return obj;
}

View file

@ -89,9 +89,9 @@ static char presence_id_valid_start_characters[] = ":_abcdefghijklmnopqrstuvwxyz
static char * generate_presence_id(void) {
char id[7];
int i;
id[0] = presence_id_valid_start_characters[random() % (sizeof(presence_id_valid_start_characters)-1)];
id[0] = presence_id_valid_start_characters[ortp_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[i] = presence_id_valid_characters[ortp_random() % (sizeof(presence_id_valid_characters)-1)];
}
id[6] = '\0';
@ -1443,9 +1443,9 @@ void linphone_core_add_subscriber(LinphoneCore *lc, const char *subscriber, SalO
linphone_friend_set_inc_subscribe_policy(fl,LinphoneSPAccept);
fl->inc_subscribe_pending=TRUE;
lc->subscribers=ms_list_append(lc->subscribers,(void *)fl);
if (lc->vtable.new_subscription_requested!=NULL) {
{
char *tmp=linphone_address_as_string(fl->uri);
lc->vtable.new_subscription_requested(lc,fl,tmp);
linphone_core_notify_new_subscription_requested(lc,fl,tmp);
ms_free(tmp);
}
}
@ -1876,8 +1876,7 @@ void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, Sa
}
lf->presence = presence;
lf->subscribe_active=TRUE;
if (lc->vtable.notify_presence_received)
lc->vtable.notify_presence_received(lc,(LinphoneFriend*)lf);
linphone_core_notify_notify_presence_received(lc,(LinphoneFriend*)lf);
ms_free(tmp);
}else{
ms_message("But this person is not part of our friend list, so we don't care.");

View file

@ -80,6 +80,8 @@ extern "C" {
#endif
struct _LinphoneCallParams{
belle_sip_object_t base;
void *user_data;
LinphoneCall *referer; /*in case this call creation is consecutive to an incoming transfer, this points to the original call */
int audio_bw; /* bandwidth limit for audio stream */
LinphoneMediaEncryption media_encryption;
@ -100,10 +102,14 @@ struct _LinphoneCallParams{
bool_t real_early_media; /*send real media even during early media (for outgoing calls)*/
bool_t in_conference; /*in conference mode */
bool_t low_bandwidth;
bool_t no_user_consent;/*when set to TRUE an UPDATE request will be used instead of reINVITE*/
uint16_t avpf_rr_interval; /*in milliseconds*/
LinphonePrivacyMask privacy;
uint16_t avpf_rr_interval;
};
BELLE_SIP_DECLARE_VPTR(LinphoneCallParams);
struct _LinphoneQualityReporting{
reporting_session_report_t * reports[2]; /**Store information on audio and video media streams (RFC 6035) */
bool_t was_video_running; /*Keep video state since last check in order to detect its (de)activation*/
@ -111,6 +117,8 @@ struct _LinphoneQualityReporting{
};
struct _LinphoneCallLog{
belle_sip_object_t base;
void *user_data;
struct _LinphoneCore *lc;
LinphoneCallDir dir; /**< The direction of the call*/
LinphoneCallStatus status; /**< The status of the call*/
@ -119,18 +127,17 @@ struct _LinphoneCallLog{
char start_date[128]; /**<Human readable string containing the start date*/
int duration; /**<Duration of the call in seconds*/
char *refkey;
void *user_pointer;
rtp_stats_t local_stats;
rtp_stats_t remote_stats;
float quality;
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*/
struct _LinphoneQualityReporting reporting;
bool_t video_enabled;
};
BELLE_SIP_DECLARE_VPTR(LinphoneCallLog);
typedef struct _CallCallbackObj
{
@ -138,8 +145,6 @@ typedef struct _CallCallbackObj
void * _user_data;
}CallCallbackObj;
static const int linphone_call_magic=0x3343;
typedef enum _LinphoneChatMessageDir{
LinphoneChatMessageIncoming,
LinphoneChatMessageOutgoing
@ -183,7 +188,8 @@ typedef struct _PortConfig{
struct _LinphoneCall
{
int magic; /*used to distinguish from proxy config*/
belle_sip_object_t base;
void *user_data;
struct _LinphoneCore *core;
SalErrorInfo non_op_error;
int af; /*the address family to prefer for RTP path, guessed from signaling path*/
@ -202,8 +208,6 @@ struct _LinphoneCall
LinphoneCallState prevstate;
LinphoneCallState transfer_state; /*idle if no transfer*/
LinphoneProxyConfig *dest_proxy;
int refcnt;
void * user_pointer;
PortConfig media_ports[2];
MSMediaStreamSessions sessions[2]; /*the rtp, srtp, zrtp contexts for each stream*/
StunCandidate ac,vc; /*audio video ip/port discovered by STUN*/
@ -212,9 +216,9 @@ struct _LinphoneCall
MSAudioEndpoint *endpoint; /*used for conferencing*/
char *refer_to;
LinphoneCallParams params;
LinphoneCallParams current_params;
LinphoneCallParams remote_params;
LinphoneCallParams *params;
LinphoneCallParams *current_params;
LinphoneCallParams *remote_params;
int up_bw; /*upload bandwidth setting at the time the call is started. Used to detect if it changes during a call */
int audio_bw; /*upload bandwidth used by audio */
OrtpEvQueue *audiostream_app_evq;
@ -232,6 +236,7 @@ struct _LinphoneCall
LinphoneCall *referer; /*when this call is the result of a transfer, referer is set to the original call that caused the transfer*/
LinphoneCall *transfer_target;/*if this call received a transfer request, then transfer_target points to the new call created to the refer target */
int localdesc_changed;/*not a boolean, contains a mask representing changes*/
LinphonePlayer *player;
bool_t refer_pending;
bool_t expect_media_in_ack;
@ -240,29 +245,35 @@ struct _LinphoneCall
bool_t all_muted; /*this flag is set during early medias*/
bool_t playing_ringbacktone;
bool_t owns_call_log;
bool_t ringing_beep; /* whether this call is ringing through an already existent current call*/
bool_t auth_token_verified;
bool_t defer_update;
bool_t defer_update;
bool_t was_automatically_paused;
bool_t ping_replied;
bool_t record_active;
bool_t paused_by_app;
};
BELLE_SIP_DECLARE_VPTR(LinphoneCall);
LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, const LinphoneCallParams *params, LinphoneProxyConfig *cfg);
LinphoneCall * linphone_call_new_incoming(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, SalOp *op);
void linphone_call_set_new_params(LinphoneCall *call, const LinphoneCallParams *params);
void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const char *message);
void linphone_call_set_contact_op(LinphoneCall* call);
void linphone_call_set_compatible_incoming_call_parameters(LinphoneCall *call, const SalMediaDescription *md);
/* private: */
LinphoneCallLog * linphone_call_log_new(LinphoneCall *call, LinphoneAddress *local, LinphoneAddress * remote);
LinphoneCallLog * linphone_call_log_new(LinphoneCallDir dir, LinphoneAddress *local, LinphoneAddress * remote);
void linphone_call_log_completed(LinphoneCall *call);
void linphone_call_log_destroy(LinphoneCallLog *cl);
void linphone_call_set_transfer_state(LinphoneCall* call, LinphoneCallState state);
LinphonePlayer *linphone_call_build_player(LinphoneCall*call);
LinphoneCallParams * linphone_call_params_new(void);
SalMediaProto get_proto_from_call_params(const LinphoneCallParams *params);
void linphone_auth_info_write_config(struct _LpConfig *config, LinphoneAuthInfo *obj, int pos);
@ -270,16 +281,32 @@ void linphone_core_update_proxy_register(LinphoneCore *lc);
void linphone_core_refresh_subscribes(LinphoneCore *lc);
int linphone_core_abort_call(LinphoneCore *lc, LinphoneCall *call, const char *error);
const char *linphone_core_get_nat_address_resolved(LinphoneCore *lc);
/**
* @brief Equivalent to _linphone_core_get_firewall_policy_with_lie(lc, TRUE)
* @param lc LinphoneCore instance
* @return Fairewall policy
*/
LinphoneFirewallPolicy _linphone_core_get_firewall_policy(const LinphoneCore *lc);
/**
* @brief Get the firwall policy which has been set.
* @param lc Instance of LinphoneCore
* @param lie If true, the configured firewall policy will be returned only if no tunnel are enabled.
* Otherwise, NoFirewallPolicy value will be returned.
* @return The firewall policy
*/
LinphoneFirewallPolicy _linphone_core_get_firewall_policy_with_lie(const LinphoneCore *lc, bool_t lie);
int linphone_proxy_config_send_publish(LinphoneProxyConfig *cfg, LinphonePresenceModel *presence);
void linphone_proxy_config_set_state(LinphoneProxyConfig *cfg, LinphoneRegistrationState rstate, const char *message);
void linphone_proxy_config_stop_refreshing(LinphoneProxyConfig *obj);
void linphone_proxy_config_write_all_to_config_file(LinphoneCore *lc);
void _linphone_proxy_config_release(LinphoneProxyConfig *cfg);
/*
* returns service route as defined in as defined by rfc3608, might be a list instead of just one.
* Can be NULL
* */
const LinphoneAddress* linphone_proxy_config_get_service_route(const LinphoneProxyConfig* cfg);
char* linphone_proxy_config_get_contact(const LinphoneProxyConfig *cfg);
void linphone_friend_close_subscriptions(LinphoneFriend *lf);
void linphone_friend_update_subscribes(LinphoneFriend *fr, LinphoneProxyConfig *cfg, bool_t only_when_registered);
@ -292,7 +319,6 @@ void linphone_core_update_friends_subscriptions(LinphoneCore *lc, LinphoneProxyC
int parse_hostname_to_addr(const char *server, struct sockaddr_storage *ss, socklen_t *socklen, int default_port);
void linphone_core_get_local_ip(LinphoneCore *lc, int af, char *result);
bool_t host_has_ipv6_network();
bool_t lp_spawn_command_line_sync(const char *command, char **result,int *command_ret);
@ -357,10 +383,10 @@ void linphone_friend_write_to_config_file(struct _LpConfig *config, LinphoneFrie
LinphoneFriend * linphone_friend_new_from_config_file(struct _LinphoneCore *lc, int index);
void linphone_proxy_config_update(LinphoneProxyConfig *cfg);
void linphone_proxy_config_get_contact(LinphoneProxyConfig *cfg, const char **ip, int *port);
LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const LinphoneAddress *uri);
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);
void linphone_core_get_local_ip(LinphoneCore *lc, int af, const char *dest, char *result);
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);
@ -383,7 +409,7 @@ void linphone_call_delete_upnp_session(LinphoneCall *call);
void linphone_call_stop_media_streams_for_ice_gathering(LinphoneCall *call);
void linphone_call_update_crypto_parameters(LinphoneCall *call, SalMediaDescription *old_md, SalMediaDescription *new_md);
void linphone_call_update_remote_session_id_and_ver(LinphoneCall *call);
void linphone_call_set_state_base(LinphoneCall *call, LinphoneCallState cstate, const char *message,bool_t silently);
const char * linphone_core_get_identity(LinphoneCore *lc);
@ -395,30 +421,29 @@ int linphone_core_proceed_with_invite_if_ready(LinphoneCore *lc, LinphoneCall *c
int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, const LinphoneAddress* destination/* = NULL if to be taken from the call log */);
int linphone_core_restart_invite(LinphoneCore *lc, LinphoneCall *call);
int linphone_core_start_update_call(LinphoneCore *lc, LinphoneCall *call);
int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call);
int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState next_state, const char *state_info);
void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call);
bool_t linphone_core_incompatible_security(LinphoneCore *lc, SalMediaDescription *md);
extern SalCallbacks linphone_sal_callbacks;
bool_t linphone_core_rtcp_enabled(const LinphoneCore *lc);
bool_t linphone_core_symmetric_rtp_enabled(LinphoneCore*lc);
LinphoneCall * is_a_linphone_call(void *user_pointer);
LinphoneProxyConfig * is_a_linphone_proxy_config(void *user_pointer);
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;
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);
void _linphone_proxy_config_release_ops(LinphoneProxyConfig *obj);
/*chat*/
void linphone_chat_room_release(LinphoneChatRoom *cr);
void linphone_chat_message_destroy(LinphoneChatMessage* msg);
/**/
struct _LinphoneProxyConfig
{
int magic;
belle_sip_object_t base;
void *user_data;
struct _LinphoneCore *lc;
char *reg_proxy;
char *reg_identity;
@ -437,17 +462,18 @@ struct _LinphoneProxyConfig
char *dial_prefix;
LinphoneRegistrationState state;
SalOp *publish_op;
LinphoneAVPFMode avpf_mode;
bool_t commit;
bool_t reg_sendregister;
bool_t publish;
bool_t dial_escape_plus;
bool_t send_publish;
bool_t quality_reporting_enabled;
bool_t avpf_enabled;
bool_t pad;
uint8_t avpf_rr_interval;
uint8_t quality_reporting_interval;
void* user_data;
time_t deletion_date;
LinphonePrivacyMask privacy;
/*use to check if server config has changed between edit() and done()*/
@ -457,6 +483,8 @@ struct _LinphoneProxyConfig
};
BELLE_SIP_DECLARE_VPTR(LinphoneProxyConfig);
struct _LinphoneAuthInfo
{
char *username;
@ -473,10 +501,11 @@ typedef enum _LinphoneIsComposingState {
} LinphoneIsComposingState;
struct _LinphoneChatRoom{
belle_sip_object_t base;
void *user_data;
struct _LinphoneCore *lc;
char *peer;
LinphoneAddress *peer_url;
void * user_data;
MSList *messages_hist;
MSList *transient_messages;
LinphoneIsComposingState remote_is_composing;
@ -486,6 +515,7 @@ struct _LinphoneChatRoom{
belle_sip_source_t *composing_refresh_timer;
};
BELLE_SIP_DECLARE_VPTR(LinphoneChatRoom);
struct _LinphoneFriend{
@ -540,6 +570,7 @@ typedef struct rtp_config
int nortp_timeout;
int disable_upnp;
MSCryptoSuite *srtp_suites;
LinphoneAVPFMode avpf_mode;
bool_t rtp_no_xmit_on_audio_mute;
/* stop rtp xmit when audio muted */
bool_t audio_adaptive_jitt_comp_enabled;
@ -601,6 +632,7 @@ typedef struct video_config{
bool_t show_local;
bool_t display;
bool_t selfview; /*during calls*/
bool_t reuse_preview_source;
}video_config_t;
typedef struct ui_config
@ -629,6 +661,7 @@ struct _LinphoneConference{
MSAudioEndpoint *record_endpoint;
RtpProfile *local_dummy_profile;
bool_t local_muted;
bool_t terminated;
};
@ -644,12 +677,12 @@ LinphoneToneDescription *linphone_core_get_call_error_tone(const LinphoneCore *l
void linphone_core_play_call_error_tone(LinphoneCore *lc, LinphoneReason reason);
void _linphone_core_set_tone(LinphoneCore *lc, LinphoneReason reason, LinphoneToneID id, const char *audiofile);
const char *linphone_core_get_tone_file(const LinphoneCore *lc, LinphoneToneID id);
int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params);
int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params, LinphoneCallState next_state, const char *state_info);
typedef struct _LinphoneConference LinphoneConference;
struct _LinphoneCore
{
LinphoneCoreVTable vtable;
MSList* vtables;
Sal *sal;
LinphoneGlobalState state;
struct _LpConfig *config;
@ -707,6 +740,7 @@ struct _LinphoneCore
bool_t preview_finished;
bool_t auto_net_state_mon;
bool_t network_reachable;
bool_t network_reachable_to_be_notified; /*set to true when state must be notified in next iterate*/
bool_t use_preview_window;
time_t network_last_check;
@ -732,8 +766,8 @@ struct _LinphoneCore
belle_tls_verify_policy_t *http_verify_policy;
MSList *tones;
LinphoneReason chat_deny_code;
char *file_transfer_server;
const char **supported_formats;
LinphoneContent *log_collection_upload_information;
};
@ -824,12 +858,11 @@ void _linphone_core_codec_config_write(LinphoneCore *lc);
#ifndef NB_MAX_CALLS
#define NB_MAX_CALLS (10)
#endif
void call_logs_read_from_config_file(LinphoneCore *lc);
void call_logs_write_to_config_file(LinphoneCore *lc);
int linphone_core_get_edge_bw(LinphoneCore *lc);
int linphone_core_get_edge_ptime(LinphoneCore *lc);
void _linphone_call_params_copy(LinphoneCallParams *params, const LinphoneCallParams *refparams);
void linphone_call_params_uninit(LinphoneCallParams *params);
int linphone_upnp_init(LinphoneCore *lc);
void linphone_upnp_destroy(LinphoneCore *lc);
@ -875,6 +908,25 @@ void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc);
void linphone_configuring_terminated(LinphoneCore *lc, LinphoneConfiguringState state, const char *message);
int linphone_remote_provisioning_download_and_apply(LinphoneCore *lc, const char *remote_provisioning_uri);
int linphone_remote_provisioning_load_file( LinphoneCore* lc, const char* file_path);
/*****************************************************************************
* Player interface
****************************************************************************/
struct _LinphonePlayer{
int (*open)(struct _LinphonePlayer* player, const char *filename);
int (*start)(struct _LinphonePlayer* player);
int (*pause)(struct _LinphonePlayer* player);
int (*seek)(struct _LinphonePlayer* player, int time_ms);
MSPlayerState (*get_state)(struct _LinphonePlayer* player);
int (*get_duration)(struct _LinphonePlayer *player);
int (*get_position)(struct _LinphonePlayer *player);
void (*close)(struct _LinphonePlayer* player);
LinphonePlayerEofCallback cb;
void *user_data;
void *impl;
};
/*****************************************************************************
@ -921,14 +973,60 @@ const MSCryptoSuite * linphone_core_get_srtp_crypto_suites(LinphoneCore *lc);
*/
BELLE_SIP_DECLARE_TYPES_BEGIN(linphone,10000)
BELLE_SIP_TYPE_ID(LinphoneContactSearch),
BELLE_SIP_TYPE_ID(LinphoneContactProvider),
BELLE_SIP_TYPE_ID(LinphoneContactSearch),
BELLE_SIP_TYPE_ID(LinphoneCall),
BELLE_SIP_TYPE_ID(LinphoneCallLog),
BELLE_SIP_TYPE_ID(LinphoneCallParams),
BELLE_SIP_TYPE_ID(LinphoneChatMessage),
BELLE_SIP_TYPE_ID(LinphoneChatRoom),
BELLE_SIP_TYPE_ID(LinphoneLDAPContactProvider),
BELLE_SIP_TYPE_ID(LinphoneLDAPContactSearch),
BELLE_SIP_TYPE_ID(LinphoneChatMessage)
BELLE_SIP_TYPE_ID(LinphoneProxyConfig)
BELLE_SIP_DECLARE_TYPES_END
void linphone_core_notify_global_state_changed(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message);
void linphone_core_notify_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *message);
void linphone_core_notify_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t on, const char *authentication_token);
void linphone_core_notify_registration_state_changed(LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const char *message);
void linphone_core_notify_show_interface(LinphoneCore *lc);
void linphone_core_notify_display_status(LinphoneCore *lc, const char *message);
void linphone_core_notify_display_message(LinphoneCore *lc, const char *message);
void linphone_core_notify_display_warning(LinphoneCore *lc, const char *message);
void linphone_core_notify_display_url(LinphoneCore *lc, const char *message, const char *url);
void linphone_core_notify_notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf);
void linphone_core_notify_new_subscription_requested(LinphoneCore *lc, LinphoneFriend *lf, const char *url);
void linphone_core_notify_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username, const char *domain);
void linphone_core_notify_call_log_updated(LinphoneCore *lc, LinphoneCallLog *newcl);
void linphone_core_notify_text_message_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message);
void linphone_core_notify_message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *message);
void linphone_core_notify_file_transfer_recv(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, const char* buff, size_t size);
void linphone_core_notify_file_transfer_send(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, char* buff, size_t* size);
void linphone_core_notify_file_transfer_progress_indication(LinphoneCore *lc, LinphoneChatMessage *message, const LinphoneContent* content, size_t progress);
void linphone_core_notify_is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room);
void linphone_core_notify_dtmf_received(LinphoneCore* lc, LinphoneCall *call, int dtmf);
/*
* return true if at least a registered vtable has a cb for dtmf received*/
bool_t linphone_core_dtmf_received_has_listener(const LinphoneCore* lc);
void linphone_core_notify_refer_received(LinphoneCore *lc, const char *refer_to);
void linphone_core_notify_buddy_info_updated(LinphoneCore *lc, LinphoneFriend *lf);
void linphone_core_notify_transfer_state_changed(LinphoneCore *lc, LinphoneCall *transfered, LinphoneCallState new_call_state);
void linphone_core_notify_call_stats_updated(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallStats *stats);
void linphone_core_notify_info_received(LinphoneCore *lc, LinphoneCall *call, const LinphoneInfoMessage *msg);
void linphone_core_notify_configuring_status(LinphoneCore *lc, LinphoneConfiguringState status, const char *message);
void linphone_core_notify_network_reachable(LinphoneCore *lc, bool_t reachable);
void linphone_core_notify_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *notified_event, const LinphoneContent *body);
void linphone_core_notify_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state);
void linphone_core_notify_publish_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphonePublishState state);
void linphone_core_notify_log_collection_upload_state_changed(LinphoneCore *lc, LinphoneCoreLogCollectionUploadState state, const char *info);
void linphone_core_notify_log_collection_upload_progress_indication(LinphoneCore *lc, size_t progress);
void set_mic_gain_db(AudioStream *st, float gain);
void set_playback_gain_db(AudioStream *st, float gain);
#ifdef __cplusplus
}
#endif

View file

@ -99,23 +99,22 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *ob
const char *contact_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_parameters", NULL) : NULL;
const char *contact_uri_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_uri_parameters", NULL) : NULL;
memset(obj, 0, sizeof(LinphoneProxyConfig));
obj->magic = linphone_proxy_config_magic;
obj->expires = lc ? lp_config_get_default_int(lc->config, "proxy", "reg_expires", 3600) : 3600;
obj->reg_sendregister = lc ? lp_config_get_default_int(lc->config, "proxy", "reg_sendregister", 0) : 0;
obj->reg_sendregister = lc ? lp_config_get_default_int(lc->config, "proxy", "reg_sendregister", 1) : 1;
obj->dial_prefix = dial_prefix ? ms_strdup(dial_prefix) : NULL;
obj->dial_escape_plus = lc ? lp_config_get_default_int(lc->config, "proxy", "dial_escape_plus", 0) : 0;
obj->privacy = lc ? lp_config_get_default_int(lc->config, "proxy", "privacy", LinphonePrivacyDefault) : LinphonePrivacyDefault;
obj->reg_identity = identity ? ms_strdup(identity) : NULL;
obj->reg_proxy = proxy ? ms_strdup(proxy) : NULL;
obj->reg_route = route ? ms_strdup(route) : NULL;
obj->domain = NULL;
obj->realm = realm ? ms_strdup(realm) : NULL;
obj->quality_reporting_enabled = lc ? lp_config_get_default_int(lc->config, "proxy", "quality_reporting_enabled", 0) : 0;
obj->quality_reporting_collector = quality_reporting_collector ? ms_strdup(quality_reporting_collector) : NULL;
obj->quality_reporting_interval = lc ? lp_config_get_default_int(lc->config, "proxy", "quality_reporting_interval", 0) : 0;
obj->contact_params = contact_params ? ms_strdup(contact_params) : NULL;
obj->contact_uri_params = contact_uri_params ? ms_strdup(contact_uri_params) : NULL;
obj->avpf_enabled = lc ? lp_config_get_default_int(lc->config, "proxy", "avpf", 0) : 0;
obj->avpf_mode = lc ? lp_config_get_default_int(lc->config, "proxy", "avpf", LinphoneAVPFDefault) : LinphoneAVPFDefault;
obj->avpf_rr_interval = lc ? lp_config_get_default_int(lc->config, "proxy", "avpf_rr_interval", 5) : 5;
obj->publish_expires=-1;
}
@ -133,20 +132,35 @@ LinphoneProxyConfig *linphone_proxy_config_new() {
return linphone_core_create_proxy_config(NULL);
}
static void _linphone_proxy_config_destroy(LinphoneProxyConfig *obj);
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneProxyConfig);
BELLE_SIP_INSTANCIATE_VPTR(LinphoneProxyConfig, belle_sip_object_t,
(belle_sip_object_destroy_t)_linphone_proxy_config_destroy,
NULL, // clone
NULL, // marshal
FALSE
);
LinphoneProxyConfig * linphone_core_create_proxy_config(LinphoneCore *lc) {
LinphoneProxyConfig *obj=NULL;
obj=ms_new(LinphoneProxyConfig,1);
LinphoneProxyConfig *obj = belle_sip_object_new(LinphoneProxyConfig);
linphone_proxy_config_init(lc,obj);
return obj;
}
/**
* Destroys a proxy config.
*
* @note: LinphoneProxyConfig that have been removed from LinphoneCore with
* linphone_core_remove_proxy_config() must not be freed.
**/
void linphone_proxy_config_destroy(LinphoneProxyConfig *obj){
void _linphone_proxy_config_release_ops(LinphoneProxyConfig *obj){
if (obj->op) {
sal_op_release(obj->op);
obj->op=NULL;
}
if (obj->publish_op){
sal_op_release(obj->publish_op);
obj->publish_op=NULL;
}
}
void _linphone_proxy_config_destroy(LinphoneProxyConfig *obj){
if (obj->reg_proxy!=NULL) ms_free(obj->reg_proxy);
if (obj->reg_identity!=NULL) ms_free(obj->reg_identity);
if (obj->reg_route!=NULL) ms_free(obj->reg_route);
@ -156,13 +170,36 @@ void linphone_proxy_config_destroy(LinphoneProxyConfig *obj){
if (obj->realm!=NULL) ms_free(obj->realm);
if (obj->type!=NULL) ms_free(obj->type);
if (obj->dial_prefix!=NULL) ms_free(obj->dial_prefix);
if (obj->op) sal_op_release(obj->op);
if (obj->publish_op) sal_op_release(obj->publish_op);
if (obj->contact_params) ms_free(obj->contact_params);
if (obj->contact_uri_params) ms_free(obj->contact_uri_params);
if (obj->saved_proxy!=NULL) linphone_address_destroy(obj->saved_proxy);
if (obj->saved_identity!=NULL) linphone_address_destroy(obj->saved_identity);
ms_free(obj);
_linphone_proxy_config_release_ops(obj);
}
/**
* Destroys a proxy config.
* @deprecated
*
* @note: LinphoneProxyConfig that have been removed from LinphoneCore with
* linphone_core_remove_proxy_config() must not be freed.
**/
void linphone_proxy_config_destroy(LinphoneProxyConfig *cfg) {
belle_sip_object_unref(cfg);
}
void _linphone_proxy_config_release(LinphoneProxyConfig *cfg) {
_linphone_proxy_config_release_ops(cfg);
belle_sip_object_unref(cfg);
}
LinphoneProxyConfig *linphone_proxy_config_ref(LinphoneProxyConfig *cfg) {
belle_sip_object_ref(cfg);
return cfg;
}
void linphone_proxy_config_unref(LinphoneProxyConfig *cfg) {
belle_sip_object_unref(cfg);
}
/**
@ -278,14 +315,14 @@ int linphone_proxy_config_set_route(LinphoneProxyConfig *obj, const char *route)
bool_t linphone_proxy_config_check(LinphoneCore *lc, LinphoneProxyConfig *obj){
if (obj->reg_proxy==NULL){
if (lc && lc->vtable.display_warning)
lc->vtable.display_warning(lc,_("The sip proxy address you entered is invalid, it must start with \"sip:\""
if (lc)
linphone_core_notify_display_warning(lc,_("The sip proxy address you entered is invalid, it must start with \"sip:\""
" followed by a hostname."));
return FALSE;
}
if (obj->reg_identity==NULL){
if (lc && lc->vtable.display_warning)
lc->vtable.display_warning(lc,_("The sip identity you entered is invalid.\nIt should look like "
if (lc)
linphone_core_notify_display_warning(lc,_("The sip identity you entered is invalid.\nIt should look like "
"sip:username@proxydomain, such as sip:alice@example.net"));
return FALSE;
}
@ -445,9 +482,6 @@ static void linphone_proxy_config_register(LinphoneProxyConfig *obj){
linphone_proxy_config_set_state(obj,LinphoneRegistrationCleared,"Registration cleared");
}
_linphone_proxy_config_unregister(obj);
}
}
@ -1108,7 +1142,7 @@ int linphone_core_add_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *cfg){
ms_warning("ProxyConfig already entered, ignored.");
return 0;
}
lc->sip_conf.proxies=ms_list_append(lc->sip_conf.proxies,(void *)cfg);
lc->sip_conf.proxies=ms_list_append(lc->sip_conf.proxies,(void *)linphone_proxy_config_ref(cfg));
linphone_proxy_config_apply(cfg,lc);
return 0;
}
@ -1134,10 +1168,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*/
/*as cfg no longer in proxies, unregister will never be issued*/
_linphone_proxy_config_unregister(cfg);
linphone_proxy_config_update(cfg);
}
if (lc->default_proxy==cfg){
lc->default_proxy=NULL;
@ -1158,14 +1189,25 @@ void linphone_core_clear_proxy_config(LinphoneCore *lc){
ms_list_free(copy);
linphone_proxy_config_write_all_to_config_file(lc);
}
static int linphone_core_get_default_proxy_config_index(LinphoneCore *lc) {
int pos = -1;
if (lc->default_proxy != NULL) {
pos = ms_list_position(lc->sip_conf.proxies, ms_list_find(lc->sip_conf.proxies, (void *)lc->default_proxy));
}
return pos;
}
/**
* Sets the default proxy.
*
* This default proxy must be part of the list of already entered LinphoneProxyConfig.
* Toggling it as default will make LinphoneCore use the identity associated with
* the proxy configuration in all incoming and outgoing calls.
* @param[in] lc LinphoneCore object
* @param[in] config The proxy configuration to use as the default one.
**/
void linphone_core_set_default_proxy(LinphoneCore *lc, LinphoneProxyConfig *config){
void linphone_core_set_default_proxy_config(LinphoneCore *lc, LinphoneProxyConfig *config){
/* check if this proxy is in our list */
if (config!=NULL){
if (ms_list_find(lc->sip_conf.proxies,config)==NULL){
@ -1176,7 +1218,7 @@ void linphone_core_set_default_proxy(LinphoneCore *lc, LinphoneProxyConfig *conf
}
lc->default_proxy=config;
if (linphone_core_ready(lc))
lp_config_set_int(lc->config,"sip","default_proxy",linphone_core_get_default_proxy(lc,NULL));
lp_config_set_int(lc->config,"sip","default_proxy",linphone_core_get_default_proxy_config_index(lc));
}
void linphone_core_set_default_proxy_index(LinphoneCore *lc, int index){
@ -1186,14 +1228,20 @@ void linphone_core_set_default_proxy_index(LinphoneCore *lc, int index){
/**
* Returns the default proxy configuration, that is the one used to determine the current identity.
* @deprecated Use linphone_core_get_default_proxy_config() instead.
**/
int linphone_core_get_default_proxy(LinphoneCore *lc, LinphoneProxyConfig **config){
int pos=-1;
if (config!=NULL) *config=lc->default_proxy;
if (lc->default_proxy!=NULL){
pos=ms_list_position(lc->sip_conf.proxies,ms_list_find(lc->sip_conf.proxies,(void *)lc->default_proxy));
}
return pos;
return linphone_core_get_default_proxy_config_index(lc);
}
/**
* Returns the default proxy configuration, that is the one used to determine the current identity.
* @param[in] lc LinphoneCore object
* @return The default proxy configuration.
**/
LinphoneProxyConfig * linphone_core_get_default_proxy_config(LinphoneCore *lc) {
return lc->default_proxy;
}
/**
@ -1243,7 +1291,7 @@ void linphone_proxy_config_write_to_config_file(LpConfig *config, LinphoneProxyC
lp_config_set_int(config,key,"reg_expires",obj->expires);
lp_config_set_int(config,key,"reg_sendregister",obj->reg_sendregister);
lp_config_set_int(config,key,"publish",obj->publish);
lp_config_set_int(config, key, "avpf", obj->avpf_enabled);
lp_config_set_int(config, key, "avpf", obj->avpf_mode);
lp_config_set_int(config, key, "avpf_rr_interval", obj->avpf_rr_interval);
lp_config_set_int(config,key,"dial_escape_plus",obj->dial_escape_plus);
lp_config_set_string(config,key,"dial_prefix",obj->dial_prefix);
@ -1295,7 +1343,7 @@ LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LinphoneCore* lc
CONFIGURE_INT_VALUE(cfg,config,key,expires,"reg_expires")
CONFIGURE_BOOL_VALUE(cfg,config,key,register,"reg_sendregister")
CONFIGURE_BOOL_VALUE(cfg,config,key,publish,"publish")
CONFIGURE_BOOL_VALUE(cfg,config,key,avpf,"avpf")
CONFIGURE_INT_VALUE(cfg,config,key,avpf_mode,"avpf")
CONFIGURE_INT_VALUE(cfg,config,key,avpf_rr_interval,"avpf_rr_interval")
CONFIGURE_INT_VALUE(cfg,config,key,dial_escape_plus,"dial_escape_plus")
CONFIGURE_STRING_VALUE(cfg,config,key,dial_prefix,"dial_prefix")
@ -1322,9 +1370,9 @@ static void linphone_proxy_config_activate_sip_setup(LinphoneProxyConfig *cfg){
caps=sip_setup_context_get_capabilities(ssc);
if (caps & SIP_SETUP_CAP_ACCOUNT_MANAGER){
if (sip_setup_context_login_account(ssc,cfg->reg_identity,NULL,NULL)!=0){
if (lc->vtable.display_warning){
{
char *tmp=ms_strdup_printf(_("Could not login as %s"),cfg->reg_identity);
lc->vtable.display_warning(lc,tmp);
linphone_core_notify_display_warning(lc,tmp);
ms_free(tmp);
}
return;
@ -1360,12 +1408,7 @@ static bool_t can_register(LinphoneProxyConfig *cfg){
}
#endif //BUILD_UPNP
if (lc->sip_conf.register_only_when_network_is_up){
LinphoneTunnel *tunnel=linphone_core_get_tunnel(lc);
if (tunnel && linphone_tunnel_enabled(tunnel)){
return linphone_tunnel_connected(tunnel);
}else{
return lc->network_reachable;
}
return lc->network_reachable;
}
return TRUE;
}
@ -1498,12 +1541,12 @@ void linphone_account_creator_destroy(LinphoneAccountCreator *obj){
}
}
void linphone_proxy_config_set_user_data(LinphoneProxyConfig *cr, void * ud) {
cr->user_data=ud;
void linphone_proxy_config_set_user_data(LinphoneProxyConfig *cfg, void *ud) {
cfg->user_data = ud;
}
void * linphone_proxy_config_get_user_data(LinphoneProxyConfig *cr) {
return cr->user_data;
void * linphone_proxy_config_get_user_data(const LinphoneProxyConfig *cfg) {
return cfg->user_data;
}
void linphone_proxy_config_set_state(LinphoneProxyConfig *cfg, LinphoneRegistrationState state, const char *message){
@ -1524,9 +1567,8 @@ void linphone_proxy_config_set_state(LinphoneProxyConfig *cfg, LinphoneRegistrat
if (update_friends){
linphone_core_update_friends_subscriptions(lc,cfg,TRUE);
}
if (lc && lc->vtable.registration_state_changed){
lc->vtable.registration_state_changed(lc,cfg,state,message);
}
if (lc)
linphone_core_notify_registration_state_changed(lc,cfg,state,message);
} else {
/*state already reported*/
}
@ -1609,11 +1651,22 @@ int linphone_proxy_config_get_publish_expires(const LinphoneProxyConfig *obj) {
}
void linphone_proxy_config_enable_avpf(LinphoneProxyConfig *cfg, bool_t enable) {
cfg->avpf_enabled = enable;
cfg->avpf_mode=enable ? LinphoneAVPFEnabled : LinphoneAVPFDisabled;
}
bool_t linphone_proxy_config_avpf_enabled(LinphoneProxyConfig *cfg) {
return cfg->avpf_enabled;
if (cfg->avpf_mode==LinphoneAVPFDefault && cfg->lc){
return linphone_core_get_avpf_mode(cfg->lc)==LinphoneAVPFEnabled;
}
return cfg->avpf_mode == LinphoneAVPFEnabled;
}
LinphoneAVPFMode linphone_proxy_config_get_avpf_mode(const LinphoneProxyConfig *cfg){
return cfg->avpf_mode;
}
void linphone_proxy_config_set_avpf_mode(LinphoneProxyConfig *cfg, LinphoneAVPFMode mode){
cfg->avpf_mode=mode;
}
void linphone_proxy_config_set_avpf_rr_interval(LinphoneProxyConfig *cfg, uint8_t interval) {
@ -1624,3 +1677,7 @@ void linphone_proxy_config_set_avpf_rr_interval(LinphoneProxyConfig *cfg, uint8_
uint8_t linphone_proxy_config_get_avpf_rr_interval(const LinphoneProxyConfig *cfg) {
return cfg->avpf_rr_interval;
}
char* linphone_proxy_config_get_contact(const LinphoneProxyConfig *cfg) {
return sal_op_get_public_uri(cfg->op);
}

View file

@ -405,15 +405,9 @@ static void update_ip(LinphoneCall * call, int stats_type) {
}
}
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];
reporting_session_report_t *report = (reporting_session_report_t*)user_data;
LinphoneCall *call = report->call;
char * appendbuf;
int i;
int ptime = -1;
@ -653,16 +647,16 @@ int linphone_reporting_publish_interval_report(LinphoneCall* call) {
void linphone_reporting_call_state_updated(LinphoneCall *call){
LinphoneCallState state=linphone_call_get_state(call);
MSQosAnalyzer *analyzer;
int i;
if (! quality_reporting_enabled(call)){
if (state == LinphoneCallReleased||!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){
@ -673,14 +667,12 @@ void linphone_reporting_call_state_updated(LinphoneCall *call){
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;
call->log->reporting.reports[i]->call=call;
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);
call->log->reporting.reports[i]);
}
}
linphone_reporting_update_ip(call);
@ -691,6 +683,16 @@ void linphone_reporting_call_state_updated(LinphoneCall *call){
break;
}
case LinphoneCallEnd:{
MediaStream *streams[2] = {(MediaStream*) call->audiostream, (MediaStream *) call->videostream};
for (i=0;i<2;i++){
if (streams[i]==NULL||streams[i]->rc==NULL){
continue;
}
analyzer=ms_bitrate_controller_get_qos_analyzer(streams[i]->rc);
if (analyzer){
ms_qos_analyzer_set_on_action_suggested(analyzer, NULL, NULL);
}
}
if (call->log->status==LinphoneCallSuccess || call->log->status==LinphoneCallAborted){
linphone_reporting_publish_session_report(call, TRUE);
}

View file

@ -137,6 +137,7 @@ typedef struct reporting_session_report {
// for internal processing
time_t last_report_date;
LinphoneCall *call;
} reporting_session_report_t;

View file

@ -60,7 +60,7 @@ static void linphone_remote_provisioning_apply(LinphoneCore *lc, const char *xml
, error_msg);
}
static int linphone_remote_provisioning_load_file( LinphoneCore* lc, const char* file_path){
int linphone_remote_provisioning_load_file( LinphoneCore* lc, const char* file_path){
int status = -1;
FILE* f = fopen(file_path, "r");

View file

@ -280,9 +280,11 @@ int sal_stream_description_equals(const SalStreamDescription *sd1, const SalStre
if (sd1->proto != sd2->proto) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
for (i = 0; i < SAL_CRYPTO_ALGO_MAX; i++) {
if ((sd1->crypto[i].tag != sd2->crypto[i].tag)
|| (sd1->crypto[i].algo != sd2->crypto[i].algo)
|| (strncmp(sd1->crypto[i].master_key, sd2->crypto[i].master_key, sizeof(sd1->crypto[i].master_key) - 1))) {
result |= SAL_MEDIA_DESCRIPTION_CRYPTO_CHANGED;
|| (sd1->crypto[i].algo != sd2->crypto[i].algo)){
result|=SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED;
}
if ((strncmp(sd1->crypto[i].master_key, sd2->crypto[i].master_key, sizeof(sd1->crypto[i].master_key) - 1))) {
result |= SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED;
}
}
@ -307,7 +309,7 @@ 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->nb_streams != md2->nb_streams) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
if (md1->nb_streams != md2->nb_streams) result |= SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED;
if (md1->bandwidth != md2->bandwidth) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
for(i = 0; i < md1->nb_streams; ++i){
result |= sal_stream_description_equals(&md1->streams[i], &md2->streams[i]);
@ -735,3 +737,9 @@ belle_sip_stack_t *sal_get_belle_sip_stack(Sal *sal) {
return sal->stack;
}
char* sal_op_get_public_uri(SalOp *op) {
if (op && op->refresher) {
return belle_sip_refresher_get_public_uri(op->refresher);
}
return NULL;
}

View file

@ -834,7 +834,7 @@ int linphone_upnp_call_process(LinphoneCall *call) {
linphone_core_start_update_call(lc, call);
break;
case LinphoneCallUpdatedByRemote:
linphone_core_start_accept_call_update(lc, call);
linphone_core_start_accept_call_update(lc, call,call->prevstate,linphone_call_state_to_string(call->prevstate));
break;
case LinphoneCallOutgoingInit:
linphone_core_proceed_with_invite_if_ready(lc, call, NULL);

View file

@ -18,7 +18,7 @@ UI_FILES= about.ui \
audio_assistant.ui
PIXMAPS= \
stock_people.png
stock_people.png
LINPHONE_ICO_RC_FILE=linphone.rc
LINPHONE_ICO_FILE=linphone.ico
@ -54,7 +54,8 @@ linphone_SOURCES= \
conference.c \
config-fetching.c \
audio_assistant.c \
linphone.h
videowindow.c \
linphone.h
if BUILD_WIZARD
linphone_SOURCES+= \
setupwizard.c
@ -84,7 +85,7 @@ endif
AM_CFLAGS= -DIN_LINPHONE -I$(top_srcdir)/coreapi/ \
$(MEDIASTREAMER_CFLAGS) \
$(ORTP_CFLAGS) $(BELLESIP_CFLAGS) \
$(STRICT_OPTIONS) $(LIBGTK_CFLAGS) $(LIBGTKMAC_CFLAGS) $(IPV6_CFLAGS) \
$(STRICT_OPTIONS) $(STRICT_OPTIONS_CC) $(LIBGTK_CFLAGS) $(LIBGTKMAC_CFLAGS) $(IPV6_CFLAGS) \
$(TUNNEL_CFLAGS) \
$(SQLITE3_CFLAGS)

View file

@ -168,11 +168,12 @@ static void dialog_click(GtkWidget *dialog, guint response_id, GtkWidget *page){
}
static void calibration_finished(LinphoneCore *lc, LinphoneEcCalibratorStatus status, int delay, void *data){
GtkWidget * dialog;
GtkWidget *speaker_page;
ms_message("echo calibration finished %s.",status==LinphoneEcCalibratorDone ? "successfully" : "with faillure");
if (status==LinphoneEcCalibratorDone) ms_message("Measured delay is %i",delay);
GtkWidget * dialog;
GtkWidget *speaker_page = get_widget_from_assistant("speaker_page");
speaker_page = get_widget_from_assistant("speaker_page");
dialog = gtk_message_dialog_new (
GTK_WINDOW(audio_assistant),
@ -208,6 +209,7 @@ void linphone_gtk_start_record_sound(GtkWidget *w, gpointer data){
AudioStream *stream = NULL;
MSSndCardManager *manager = ms_snd_card_manager_get();
gboolean active=gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(w));
gint timeout_id;
if(active){
gchar *path = get_record_file();
@ -217,12 +219,12 @@ void linphone_gtk_start_record_sound(GtkWidget *w, gpointer data){
path,NULL,ms_snd_card_manager_get_card(manager,linphone_core_get_capture_device(lc)),FALSE);
g_object_set_data(G_OBJECT(audio_assistant),"record_stream",stream);
}
gint timeout_id = gtk_timeout_add(6000,(GtkFunction)linphone_gtk_stop_record,NULL);
timeout_id = gtk_timeout_add(6000,(GtkFunction)linphone_gtk_stop_record,NULL);
g_object_set_data(G_OBJECT(audio_assistant),"timeout_id",GINT_TO_POINTER(timeout_id));
g_object_set_data(G_OBJECT(audio_assistant),"path",path);
} else {
stream = (AudioStream *)g_object_get_data(G_OBJECT(audio_assistant),"record_stream");
gint timeout_id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(audio_assistant),"timeout_id"));
timeout_id = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(audio_assistant),"timeout_id"));
gtk_timeout_remove(timeout_id);
if(stream != NULL){
audio_stream_stop(stream);
@ -322,7 +324,7 @@ static GtkWidget *create_intro(){
static GtkWidget *create_mic_page(){
GtkWidget *vbox=gtk_table_new(3,2,FALSE);
LinphoneCore *lc=linphone_gtk_get_core();
const char **sound_devices;
GtkWidget *labelMicChoice=gtk_label_new(_("Capture device"));
GtkWidget *labelMicLevel=gtk_label_new(_("Recorded volume"));
GtkWidget *mic_audiolevel=gtk_progress_bar_new();
@ -348,8 +350,8 @@ static GtkWidget *create_mic_page(){
set_widget_to_assistant("mic_audiolevel",mic_audiolevel);
set_widget_to_assistant("label_audiolevel",label_audiolevel);
const char **sound_devices=linphone_core_get_sound_devices(lc);
sound_devices=linphone_core_get_sound_devices(lc);
linphone_gtk_fill_combo_box(capture_device, sound_devices,
linphone_core_get_capture_device(lc), CAP_CAPTURE);
gtk_widget_show_all(vbox);
@ -370,6 +372,7 @@ static GtkWidget *create_speaker_page(){
GtkWidget *playback_device=gtk_combo_box_new();
GtkWidget *mixer_button=gtk_button_new_with_label("System sound preferences");
GtkWidget *image;
const char **sound_devices;
image=gtk_image_new_from_stock(GTK_STOCK_PREFERENCES,GTK_ICON_SIZE_MENU);
gtk_button_set_image(GTK_BUTTON(mixer_button),image);
@ -382,7 +385,7 @@ static GtkWidget *create_speaker_page(){
gtk_table_set_row_spacings(GTK_TABLE(vbox),10);
const char **sound_devices=linphone_core_get_sound_devices(lc);
sound_devices=linphone_core_get_sound_devices(lc);
linphone_gtk_fill_combo_box(playback_device, sound_devices,
linphone_core_get_playback_device(lc),CAP_PLAYBACK);
gtk_widget_show_all(vbox);
@ -414,9 +417,9 @@ static GtkWidget *create_play_record_page(){
gtk_table_attach(GTK_TABLE(vbox), rec_button, 1, 2, 0, 1, GTK_SHRINK, GTK_SHRINK, 0,0);
gtk_table_attach_defaults(GTK_TABLE(vbox), labelPlay, 0, 1, 1, 2);
gtk_table_attach(GTK_TABLE(vbox), play_button, 1, 2, 1, 2, GTK_SHRINK, GTK_SHRINK, 0,0);
gtk_widget_show_all(vbox);
set_widget_to_assistant("rec_button",rec_button);
set_widget_to_assistant("play_button",play_button);
g_signal_connect(G_OBJECT(rec_button),"toggled",(GCallback)linphone_gtk_start_record_sound,vbox);
@ -480,18 +483,23 @@ void linphone_gtk_audio_assistant_apply(GtkWidget *w){
void linphone_gtk_show_audio_assistant(void){
GtkWidget *w;
GtkWidget *welcome;
GtkWidget *mic_page;
GtkWidget *speaker_page;
GtkWidget *play_record_page;
GtkWidget *end_page;
if(audio_assistant!=NULL)
return;
w=audio_assistant=linphone_gtk_create_window("audio_assistant");
gtk_window_set_resizable (GTK_WINDOW(w), FALSE);
gtk_window_set_title(GTK_WINDOW(w),_("Audio Assistant"));
GtkWidget *welcome=create_intro();
GtkWidget *mic_page=create_mic_page();
GtkWidget *speaker_page=create_speaker_page();
GtkWidget *play_record_page=create_play_record_page();
GtkWidget *end_page=create_end_page();
welcome=create_intro();
mic_page=create_mic_page();
speaker_page=create_speaker_page();
play_record_page=create_play_record_page();
end_page=create_end_page();
gtk_assistant_append_page(GTK_ASSISTANT(w),welcome);
gtk_assistant_set_page_type(GTK_ASSISTANT(w),welcome,GTK_ASSISTANT_PAGE_INTRO);

View file

@ -36,7 +36,7 @@ void call_log_selection_changed(GtkTreeView *v){
GtkTreeSelection *select;
GtkTreeIter iter;
GtkTreeModel *model=NULL;
select = gtk_tree_view_get_selection(v);
if (select!=NULL){
if (gtk_tree_selection_get_selected (select, &model, &iter)){
@ -51,7 +51,7 @@ void call_log_selection_changed(GtkTreeView *v){
void linphone_gtk_call_log_chat_selected(GtkWidget *w){
GtkTreeSelection *select;
GtkTreeIter iter;
select=gtk_tree_view_get_selection(GTK_TREE_VIEW(w));
if (select!=NULL){
GtkTreeModel *model=NULL;
@ -72,7 +72,7 @@ void linphone_gtk_call_log_chat_selected(GtkWidget *w){
void linphone_gtk_call_log_add_contact(GtkWidget *w){
GtkTreeSelection *select;
GtkTreeIter iter;
select=gtk_tree_view_get_selection(GTK_TREE_VIEW(w));
if (select!=NULL){
GtkTreeModel *model=NULL;
@ -109,7 +109,7 @@ static bool_t put_selection_to_uribar(GtkWidget *treeview){
cl = (LinphoneCallLog *)pcl;
la = linphone_call_log_get_dir(cl)==LinphoneCallIncoming ? linphone_call_log_get_from(cl) : linphone_call_log_get_to(cl);
tmp = linphone_address_as_string(la);
if(tmp!=NULL)
if(tmp!=NULL)
gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(linphone_gtk_get_main_window(),"uribar")),tmp);
ms_free(tmp);
return TRUE;
@ -133,7 +133,7 @@ static GtkWidget *linphone_gtk_create_call_log_menu(GtkWidget *call_log){
GtkWidget *image;
GtkTreeSelection *select;
GtkTreeIter iter;
select=gtk_tree_view_get_selection(GTK_TREE_VIEW(call_log));
if (select!=NULL){
GtkTreeModel *model=NULL;
@ -202,7 +202,7 @@ void linphone_gtk_call_log_clear_missed_call(){
GtkWidget *image=gtk_image_new_from_stock(GTK_STOCK_REFRESH,GTK_ICON_SIZE_MENU);
GtkWidget *l;
const gchar*text=gtk_label_get_text(GTK_LABEL(linphone_gtk_get_widget(mw,"label3")));
l=gtk_label_new(text);
gtk_box_pack_start(GTK_BOX(box),image,FALSE,FALSE,0);
gtk_box_pack_start(GTK_BOX(box),l,FALSE,FALSE,0);
@ -228,7 +228,7 @@ void linphone_gtk_call_log_display_missed_call(int nb){
GtkWidget *image=gtk_image_new_from_stock(GTK_STOCK_REFRESH,GTK_ICON_SIZE_MENU);
GtkWidget *l;
gchar *buf;
buf=g_markup_printf_escaped(_("<b>Recent calls (%i)</b>"),nb);
l=gtk_label_new(NULL);
gtk_label_set_markup(GTK_LABEL(l),buf);
@ -281,7 +281,9 @@ void linphone_gtk_call_log_update(GtkWidget *w){
LinphoneFriend *lf=NULL;
int duration=linphone_call_log_get_duration(cl);
time_t start_date_time=linphone_call_log_get_start_date(cl);
GdkPixbuf *incoming;
GdkPixbuf *outgoing;
#if GLIB_CHECK_VERSION(2,26,0)
if (start_date_time){
GDateTime *dt=g_date_time_new_from_unix_local(start_date_time);
@ -332,7 +334,7 @@ void linphone_gtk_call_log_update(GtkWidget *w){
if (status==NULL) {
headtxt=g_markup_printf_escaped(_("<big><b>%s</b></big>\t%s"),display,start_date ? start_date : "");
logtxt=g_markup_printf_escaped(
_("<small><i>%s</i>\t"
_("<small><i>%s</i>\t"
"<i>Quality: %s</i></small>\n%s\t%s\t"),
addr, quality, minutes, seconds);
} else {
@ -346,8 +348,8 @@ void linphone_gtk_call_log_update(GtkWidget *w){
if (start_date) g_free(start_date);
gtk_tree_store_append (store,&iter,NULL);
GdkPixbuf *incoming = create_pixbuf("call_status_incoming.png");
GdkPixbuf *outgoing = create_pixbuf("call_status_outgoing.png");
incoming = create_pixbuf("call_status_incoming.png");
outgoing = create_pixbuf("call_status_outgoing.png");
gtk_tree_store_set (store,&iter,
0, linphone_call_log_get_dir(cl)==LinphoneCallOutgoing ? outgoing : incoming,
1, headtxt,2,cl,-1);

View file

@ -30,9 +30,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
const char *linphone_gtk_message_storage_get_db_file(const char *filename){
const int path_max=1024;
static char *db_file=NULL;
if (db_file) return db_file;
db_file=(char *)malloc(path_max*sizeof(char));
if (filename==NULL) filename=CONFIG_FILE;
/*try accessing a local file first if exists*/
@ -63,7 +63,7 @@ void linphone_gtk_quit_chatroom(LinphoneChatRoom *cr) {
GtkWidget *w=g_object_get_data(G_OBJECT(friendlist),"chatview");
gchar *from;
GHashTable *table=g_object_get_data(G_OBJECT(w),"table");
g_return_if_fail(w!=NULL);
gtk_notebook_remove_page(GTK_NOTEBOOK(nb),gtk_notebook_page_num(GTK_NOTEBOOK(nb),w));
linphone_chat_room_mark_as_read(cr);
@ -95,7 +95,7 @@ GtkWidget *create_tab_chat_header(LinphoneChatRoom *cr,const LinphoneAddress *ur
GtkWidget *l;
GtkWidget *image=gtk_image_new_from_stock(GTK_STOCK_CLOSE,GTK_ICON_SIZE_MENU);
GtkWidget *b=gtk_button_new();
gtk_button_set_image(GTK_BUTTON(b),image);
gtk_button_set_relief(GTK_BUTTON(b),GTK_RELIEF_NONE);
gtk_widget_set_size_request(b,25,20);
@ -131,14 +131,15 @@ void udpate_tab_chat_header(GtkWidget *chat_view,const LinphoneAddress *uri,Linp
static gboolean scroll_to_end(GtkTextView *w){
GtkTextBuffer *buffer=gtk_text_view_get_buffer(w);
GtkTextMark *mark;
GtkTextIter iter;
gtk_text_buffer_get_end_iter(buffer,&iter);
GtkTextMark *mark=gtk_text_buffer_create_mark(buffer,NULL,&iter,FALSE);
gtk_text_view_scroll_mark_onscreen(w,mark);
mark=gtk_text_buffer_create_mark(buffer,NULL,&iter,FALSE);
gtk_text_view_scroll_mark_onscreen(w,mark);
return FALSE;
}
void linphone_gtk_push_text(GtkWidget *w, const LinphoneAddress *from,
void linphone_gtk_push_text(GtkWidget *w, const LinphoneAddress *from,
gboolean me,LinphoneChatRoom *cr,LinphoneChatMessage *msg, gboolean hist){
GtkTextView *text=GTK_TEXT_VIEW(linphone_gtk_get_widget(w,"textview"));
GtkTextBuffer *buffer=gtk_text_view_get_buffer(text);
@ -153,7 +154,7 @@ void linphone_gtk_push_text(GtkWidget *w, const LinphoneAddress *from,
struct tm *tm;
int tnow_day;
int tnow_year;
gtk_text_buffer_get_start_iter(buffer,&begin);
gtk_text_buffer_get_end_iter(buffer,&iter);
off=gtk_text_iter_get_offset(&iter);
@ -178,7 +179,7 @@ void linphone_gtk_push_text(GtkWidget *w, const LinphoneAddress *from,
case LinphoneChatMessageStateInProgress:
{
g_hash_table_insert(table,(gpointer)msg,GINT_TO_POINTER(gtk_text_iter_get_line(&iter)));
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,"Sending ..",-1,
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,"Sending ..",-1,
"right","small","italic","font_grey","bg",NULL);
g_object_set_data(G_OBJECT(w),"table",table);
break;
@ -195,15 +196,15 @@ void linphone_gtk_push_text(GtkWidget *w, const LinphoneAddress *from,
} else {
strftime(buf,80,"%H:%M",tm);
}
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,buf,-1,
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,buf,-1,
"right","small","italic","font_grey",me ? "bg":NULL,NULL);
break;
}
case LinphoneChatMessageStateNotDelivered:
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,"Message not sent",-1,
gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,"Message not sent",-1,
"right","small","italic","font_grey",me ? "bg":NULL,NULL);
break;
default : gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,"Sending ..",-1,
default : gtk_text_buffer_insert_with_tags_by_name(buffer,&iter,"Sending ..",-1,
"right","small","italic","font_grey",me ? "bg":NULL,NULL);
}
gtk_text_buffer_get_end_iter(buffer,&iter);
@ -225,7 +226,7 @@ void update_chat_state_message(LinphoneChatMessageState state,LinphoneChatMessag
GtkWidget *friendlist=linphone_gtk_get_widget(main_window,"contact_list");
GtkWidget *page=(GtkWidget*)g_object_get_data(G_OBJECT(friendlist),"chatview");
GHashTable *table=(GHashTable*)g_object_get_data(G_OBJECT(page),"table");
if(page!=NULL){
GtkTextView *text=GTK_TEXT_VIEW(linphone_gtk_get_widget(page,"textview"));
GtkTextBuffer *b=gtk_text_view_get_buffer(text);
@ -272,7 +273,7 @@ void update_chat_state_message(LinphoneChatMessageState state,LinphoneChatMessag
gtk_text_buffer_insert_with_tags_by_name(b,&iter,result,-1,
"right","small","italic","font_grey","bg",NULL);
g_object_set_data(G_OBJECT(page),"table",table);
}
}
}
static void on_chat_state_changed(LinphoneChatMessage *msg, LinphoneChatMessageState state, void *user_pointer){
@ -330,8 +331,8 @@ void display_history_message(GtkWidget *chat_view,MSList *messages,const Linphon
LinphoneChatMessage *msg=(LinphoneChatMessage *)it->data;
from_str=linphone_address_as_string_uri_only(linphone_chat_message_get_from(msg));
with_str=linphone_address_as_string_uri_only(with);
linphone_gtk_push_text(chat_view,strcmp(from_str,with_str)==0? with :
linphone_chat_message_get_from(msg),
linphone_gtk_push_text(chat_view,strcmp(from_str,with_str)==0? with :
linphone_chat_message_get_from(msg),
strcmp(from_str,with_str)==0? FALSE : TRUE,
linphone_chat_message_get_chat_room(msg),msg,TRUE);
}
@ -343,7 +344,7 @@ void display_history_message(GtkWidget *chat_view,MSList *messages,const Linphon
ms_free(from_str);
ms_free(with_str);
linphone_gtk_free_list(messages);
}
}
}
void linphone_gtk_chat_add_contact(const LinphoneAddress *addr){
@ -378,7 +379,7 @@ GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddres
GdkColor colorb;
int idx;
GtkWidget *button;
GtkWidget *entry;
GtkWidget *entry = linphone_gtk_get_widget(chat_view,"text_entry");
MSList *messages;
GHashTable *table;
char *with_str;
@ -422,7 +423,7 @@ GtkWidget* linphone_gtk_init_chatroom(LinphoneChatRoom *cr, const LinphoneAddres
display_history_message(chat_view,messages,with);
button = linphone_gtk_get_widget(chat_view,"send");
g_signal_connect_swapped(G_OBJECT(button),"clicked",(GCallback)linphone_gtk_send_text,NULL);
entry = linphone_gtk_get_widget(chat_view,"text_entry");
g_signal_connect_swapped(G_OBJECT(entry),"activate",(GCallback)linphone_gtk_send_text,NULL);
g_signal_connect_swapped(G_OBJECT(entry),"changed",(GCallback)linphone_gtk_compose_text,NULL);
g_signal_connect(G_OBJECT(notebook),"switch_page",(GCallback)linphone_gtk_notebook_tab_select,NULL);
@ -445,7 +446,7 @@ void linphone_gtk_load_chatroom(LinphoneChatRoom *cr,const LinphoneAddress *uri,
char *uri_str=linphone_address_as_string(uri);
char *uri_only=linphone_address_as_string_uri_only(uri);
MSList *messages=NULL;
if(g_strcmp0(from_str,uri_only)!=0){
GtkTextView *text_view=GTK_TEXT_VIEW(linphone_gtk_get_widget(chat_view,"textview"));
GtkTextIter start;
@ -483,7 +484,7 @@ void linphone_gtk_text_received ( LinphoneCore *lc, LinphoneChatRoom *room,
gboolean send=TRUE;
/*GtkNotebook *notebook= ( GtkNotebook * ) linphone_gtk_get_widget ( main_window,"viewswitch" );*/
const LinphoneAddress *from= linphone_chat_message_get_from ( msg );
w= ( GtkWidget* ) g_object_get_data ( G_OBJECT ( friendlist ),"chatview" );
if ( w!=NULL ) {
/* Chat window opened */
@ -496,7 +497,7 @@ void linphone_gtk_text_received ( LinphoneCore *lc, LinphoneChatRoom *room,
}
send=FALSE;
}
} else {
} else {
/* Chat window closed */
#ifdef MSG_STORAGE_ENABLED
send=FALSE;
@ -530,7 +531,7 @@ void linphone_gtk_text_received ( LinphoneCore *lc, LinphoneChatRoom *room,
}
linphone_core_play_local(lc,linphone_gtk_get_sound_path("incoming_chat.wav"));
linphone_gtk_show_friends();
}
void linphone_gtk_is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) {

View file

@ -61,9 +61,9 @@ static GtkWidget *find_conferencee_from_call(LinphoneCall *call){
GtkWidget *conferencee_box=get_conferencee_box(mw);
GList *elem;
GtkWidget *ret=NULL;
if (conferencee_box==NULL) return NULL;
if (call!=NULL){
GList *l=gtk_container_get_children(GTK_CONTAINER(conferencee_box));
for(elem=l;elem!=NULL;elem=elem->next){
@ -87,13 +87,14 @@ static GtkWidget * create_conference_panel(void){
GtkWidget *image=create_pixmap("stopcall-small.png");
GtkWidget *box;
GtkWidget *viewswitch=linphone_gtk_get_widget(mw,"viewswitch");
GtkWidget *participant;
gtk_button_set_image(GTK_BUTTON(button_conf),image);
g_signal_connect_swapped(G_OBJECT(button_conf),"clicked",(GCallback)linphone_gtk_terminate_call,NULL);
g_object_set_data(G_OBJECT(mw),"conf_frame",(gpointer)conf_frame);
box=gtk_vbox_new(FALSE,0);
GtkWidget *participant=linphone_gtk_create_widget("main","callee_frame");
participant=linphone_gtk_create_widget("main","callee_frame");
gtk_widget_show(participant);
gtk_box_set_homogeneous(GTK_BOX(box),TRUE);
init_local_participant(participant);
@ -101,7 +102,7 @@ static GtkWidget * create_conference_panel(void){
gtk_widget_show(box);
g_object_set_data(G_OBJECT(mw),"conferencee_box",box);
gtk_box_pack_start(GTK_BOX(conf_box),box,FALSE,FALSE,PADDING_PIXELS);
gtk_notebook_append_page(GTK_NOTEBOOK(viewswitch),conf_frame,
create_conference_label());
return conf_frame;
@ -111,19 +112,20 @@ void linphone_gtk_set_in_conference(LinphoneCall *call){
GtkWidget *mw=linphone_gtk_get_main_window();
GtkWidget *conf_frame=(GtkWidget *)g_object_get_data(G_OBJECT(mw),"conf_frame");
GtkWidget *viewswitch=linphone_gtk_get_widget(mw,"viewswitch");
GtkWidget *participant;
if(conf_frame==NULL){
conf_frame=create_conference_panel();
}
GtkWidget *participant=find_conferencee_from_call(call);
participant=find_conferencee_from_call(call);
if (participant==NULL){
/*create and add it */
GtkWidget *conferencee_box=get_conferencee_box(mw);
GtkWidget *sound_meter;
const LinphoneAddress *addr=linphone_call_get_remote_address(call);
gchar *markup;
participant=linphone_gtk_create_widget("main","callee_frame");
gtk_widget_show(participant);
if (linphone_address_get_display_name(addr)!=NULL){
@ -140,7 +142,7 @@ void linphone_gtk_set_in_conference(LinphoneCall *call){
gtk_box_pack_start(GTK_BOX(conferencee_box),participant,FALSE,FALSE,PADDING_PIXELS);
g_object_set_data_full(G_OBJECT(participant),"call",linphone_call_ref(call),(GDestroyNotify)linphone_call_unref);
gtk_notebook_set_current_page(GTK_NOTEBOOK(viewswitch),
gtk_notebook_page_num(GTK_NOTEBOOK(viewswitch),conf_frame));
gtk_notebook_page_num(GTK_NOTEBOOK(viewswitch),conf_frame));
}
}
@ -153,13 +155,13 @@ void linphone_gtk_terminate_conference_participant(LinphoneCall *call){
void linphone_gtk_unset_from_conference(LinphoneCall *call){
GtkWidget *frame=find_conferencee_from_call(call);
if (frame){
GtkWidget *mw=linphone_gtk_get_main_window();
GtkWidget *conf_frame=(GtkWidget *)g_object_get_data(G_OBJECT(mw),"conf_frame");
GtkWidget *conferencee_box=g_object_get_data(G_OBJECT(mw),"conferencee_box");
GList *children;
g_message("Removing a participant from conference");
gtk_widget_destroy(frame);
children=gtk_container_get_children(GTK_CONTAINER(conferencee_box));

View file

@ -198,7 +198,7 @@ void linphone_gtk_delete_history(GtkWidget *button){
GtkWidget *chat_view;
LinphoneFriend *lf=NULL;
GtkWidget *friendlist;
friendlist=linphone_gtk_get_widget(w,"contact_list");
chat_view=(GtkWidget *)g_object_get_data(G_OBJECT(friendlist),"chatview");
select = gtk_tree_view_get_selection(GTK_TREE_VIEW(friendlist));
@ -216,7 +216,7 @@ void linphone_gtk_delete_history(GtkWidget *button){
GtkTextIter start;
GtkTextIter end;
GtkTextBuffer *text_buffer;
text_buffer=gtk_text_view_get_buffer(text_view);
gtk_text_buffer_get_bounds(text_buffer, &start, &end);
gtk_text_buffer_delete (text_buffer, &start, &end);
@ -290,7 +290,7 @@ void linphone_gtk_friend_list_set_chat_conversation(const LinphoneAddress *la){
LinphoneFriend *lf=NULL;
LinphoneChatRoom *cr=NULL;
GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(w,"viewswitch");
lf=linphone_core_find_friend(linphone_gtk_get_core(),la);
if(lf==NULL){
cr=linphone_gtk_create_chatroom(la);
@ -331,7 +331,7 @@ void linphone_gtk_friend_list_set_chat_conversation(const LinphoneAddress *la){
}
}while(gtk_tree_model_iter_next(model,&iter));
}
}
}
}
void linphone_gtk_notebook_tab_select(GtkNotebook *notebook,GtkWidget *page,guint page_num, gpointer data){
@ -595,11 +595,11 @@ static int get_friend_weight(const LinphoneFriend *lf){
int w=0;
LinphoneCore *lc=linphone_gtk_get_core();
LinphoneChatRoom *cr=linphone_core_get_chat_room(lc,linphone_friend_get_address(lf));
if (cr && linphone_chat_room_get_unread_messages_count(cr)>0){
w+=2000;
}
switch(linphone_friend_get_status(lf)){
case LinphoneStatusOnline:
w+=1000;
@ -685,7 +685,7 @@ static void linphone_gtk_friend_list_init(GtkWidget *friendlist){
gtk_tree_view_set_search_equal_func(GTK_TREE_VIEW(friendlist),friend_search_func,NULL,NULL);
gtk_tree_view_set_search_column(GTK_TREE_VIEW(friendlist),FRIEND_NAME);
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store),FRIEND_NAME,friend_sort,NULL,NULL);
/*Name and presence column*/
renderer = gtk_cell_renderer_text_new ();
column = gtk_tree_view_column_new_with_attributes (_("Presence status"),
@ -781,8 +781,9 @@ gboolean linphone_gtk_directory_search_focus_in(GtkWidget *entry){
void linphone_gtk_directory_search_activate(GtkWidget *entry){
LinphoneProxyConfig *cfg;
GtkWidget *w;
linphone_core_get_default_proxy(linphone_gtk_get_core(),&cfg);
GtkWidget *w=linphone_gtk_show_buddy_lookup_window(linphone_proxy_config_get_sip_setup_context(cfg));
w=linphone_gtk_show_buddy_lookup_window(linphone_proxy_config_get_sip_setup_context(cfg));
if (GPOINTER_TO_INT(g_object_get_data(G_OBJECT(entry),"active"))==1)
linphone_gtk_buddy_lookup_set_keyword(w,gtk_entry_get_text(GTK_ENTRY(entry)));
}
@ -809,7 +810,7 @@ void linphone_gtk_show_friends(void){
if (gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist))==NULL){
linphone_gtk_friend_list_init(friendlist);
}
store=GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(friendlist)));
gtk_list_store_clear(store);
@ -1076,7 +1077,7 @@ static gint tree_view_get_cell_from_pos(GtkTreeView *view, guint x, guint y){
gint colx = 0;
GtkTreePath *path;
GtkTreeViewDropPosition pos;
g_return_val_if_fail ( view != NULL, 0 );
columns = gtk_tree_view_get_columns(view);
@ -1086,8 +1087,7 @@ static gint tree_view_get_cell_from_pos(GtkTreeView *view, guint x, guint y){
GtkTreeViewColumn *checkcol = (GtkTreeViewColumn*) node->data;
if (x >= colx && x < (colx + checkcol->width)){
col = checkcol;
gint num = get_col_number_from_tree_view_column(col);
return num;
return get_col_number_from_tree_view_column(col);
} else {
colx += checkcol->width;
}

View file

@ -269,7 +269,7 @@ static void _refresh_call_stats(GtkWidget *callstats, LinphoneCall *call){
gtk_label_set_markup(GTK_LABEL(linphone_gtk_get_widget(callstats,"audio_bandwidth_usage")),tmp);
g_free(tmp);
if (has_video){
gchar *size_r=g_strdup_printf(_("%ix%i @ %f fps"),size_received.width,size_received.height,
gchar *size_r=g_strdup_printf(_("%ix%i @ %f fps"),size_received.width,size_received.height,
linphone_call_params_get_received_framerate(curparams));
gchar *size_s=g_strdup_printf(_("%ix%i @ %f fps"),size_sent.width,size_sent.height,
linphone_call_params_get_sent_framerate(curparams));
@ -366,6 +366,11 @@ void linphone_gtk_create_in_call_view(LinphoneCall *call){
GtkNotebook *notebook=(GtkNotebook *)linphone_gtk_get_widget(main_window,"viewswitch");
static int call_index=1;
int idx;
GtkWidget *transfer;
GtkWidget *conf;
GtkWidget *button;
GtkWidget *image;
if (ms_list_size(linphone_core_get_calls(linphone_gtk_get_core()))==1){
/*this is the only call at this time */
@ -386,19 +391,19 @@ void linphone_gtk_create_in_call_view(LinphoneCall *call){
linphone_gtk_enable_mute_button(
GTK_BUTTON(linphone_gtk_get_widget(call_view,"incall_mute")),FALSE);
GtkWidget *transfer = linphone_gtk_get_widget(call_view,"transfer_button");
transfer = linphone_gtk_get_widget(call_view,"transfer_button");
gtk_button_set_image(GTK_BUTTON(transfer),gtk_image_new_from_stock
(GTK_STOCK_GO_FORWARD,GTK_ICON_SIZE_BUTTON));
g_signal_connect(G_OBJECT(transfer),"clicked",(GCallback)transfer_button_clicked,call);
gtk_widget_hide(transfer);
GtkWidget *conf = linphone_gtk_get_widget(call_view,"conference_button");
conf = linphone_gtk_get_widget(call_view,"conference_button");
gtk_button_set_image(GTK_BUTTON(conf),gtk_image_new_from_stock (GTK_STOCK_ADD,GTK_ICON_SIZE_BUTTON));
g_signal_connect(G_OBJECT(conf),"clicked",(GCallback)conference_button_clicked,call);
gtk_widget_hide(conf);
GtkWidget *button=linphone_gtk_get_widget(call_view,"terminate_call");
GtkWidget *image=create_pixmap("stopcall-small.png");
button=linphone_gtk_get_widget(call_view,"terminate_call");
image=create_pixmap (linphone_gtk_get_ui_config("stop_call_icon","stopcall-small.png"));
gtk_button_set_label(GTK_BUTTON(button),_("Hang up"));
gtk_button_set_image(GTK_BUTTON(button),image);
gtk_widget_show(image);
@ -418,6 +423,7 @@ static void video_button_clicked(GtkWidget *button, LinphoneCall *call){
void linphone_gtk_update_video_button(LinphoneCall *call){
GtkWidget *call_view=(GtkWidget*)linphone_call_get_user_pointer(call);
GtkWidget *button;
GtkWidget *conf_frame;
const LinphoneCallParams *params=linphone_call_get_current_params(call);
gboolean has_video=linphone_call_params_video_enabled(params);
if (call_view==NULL) return;
@ -434,7 +440,7 @@ void linphone_gtk_update_video_button(LinphoneCall *call){
g_signal_connect(G_OBJECT(button),"clicked",(GCallback)video_button_clicked,call);
g_object_set_data(G_OBJECT(button),"signal_connected",GINT_TO_POINTER(1));
}
GtkWidget *conf_frame=(GtkWidget *)g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"conf_frame");
conf_frame=(GtkWidget *)g_object_get_data(G_OBJECT(linphone_gtk_get_main_window()),"conf_frame");
gtk_widget_set_sensitive(button,linphone_call_get_state(call)==LinphoneCallStreamsRunning);
if(conf_frame!=NULL){
gtk_widget_set_sensitive(button,FALSE);
@ -681,6 +687,14 @@ void linphone_gtk_in_call_view_show_encryption(LinphoneCall *call){
}
}
char *linphone_gtk_address(const LinphoneAddress *addr){
const char *displayname=linphone_address_get_display_name(addr);
if (!displayname) return linphone_address_as_string_uri_only(addr);
return ms_strdup(displayname);
}
void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call){
GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call);
GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status");
@ -690,6 +704,8 @@ void linphone_gtk_in_call_view_set_in_call(LinphoneCall *call){
gboolean in_conf=linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(call));
GtkWidget *call_stats=(GtkWidget*)g_object_get_data(G_OBJECT(callview),"call_stats");
linphone_gtk_in_call_show_video(call);
display_peer_name_in_label(callee,linphone_call_get_remote_address (call));
gtk_widget_hide(linphone_gtk_get_widget(callview,"answer_decline_panel"));
@ -730,7 +746,7 @@ void linphone_gtk_in_call_view_set_paused(LinphoneCall *call){
GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status");
gtk_widget_hide(linphone_gtk_get_widget(callview,"answer_decline_panel"));
gtk_label_set_markup(GTK_LABEL(status),_("<b>Paused call</b>"));
linphone_gtk_in_call_show_video(call);
linphone_gtk_in_call_set_animation_image(callview,GTK_STOCK_MEDIA_PAUSE,TRUE);
}
@ -753,11 +769,16 @@ static gboolean in_call_view_terminated(LinphoneCall *call){
void linphone_gtk_in_call_view_terminate(LinphoneCall *call, const char *error_msg){
GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call);
GtkWidget *status;
GtkWidget *video_window;
gboolean in_conf;
guint taskid;
if(callview==NULL) return;
GtkWidget *status=linphone_gtk_get_widget(callview,"in_call_status");
guint taskid=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(callview),"taskid"));
gboolean in_conf=linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(call));
video_window=(GtkWidget*)g_object_get_data(G_OBJECT(callview),"video_window");
status=linphone_gtk_get_widget(callview,"in_call_status");
taskid=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(callview),"taskid"));
in_conf=linphone_call_params_get_local_conference_mode(linphone_call_get_current_params(call));
if (video_window) gtk_widget_destroy(video_window);
if (status==NULL) return;
if (error_msg==NULL)
gtk_label_set_markup(GTK_LABEL(status),_("<b>Call ended.</b>"));
@ -896,8 +917,9 @@ void linphone_gtk_record_call_toggled(GtkWidget *button){
GtkWidget *callview;
GtkWidget *label;
if (call){
const LinphoneCallParams *params;
callview=(GtkWidget*)linphone_call_get_user_pointer (call);
const LinphoneCallParams *params=linphone_call_get_current_params(call);
params=linphone_call_get_current_params(call);
filepath=linphone_call_params_get_record_file(params);
label=linphone_gtk_get_widget(callview,"record_status");
}else if (is_conf){

View file

@ -48,6 +48,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define LINPHONE_VERSION LINPHONE_VERSION_DATE
#endif
#define LINPHONE_ICON "linphone.png"
enum {
COMPLETION_HISTORY,
COMPLETION_LDAP
@ -195,4 +197,6 @@ void linphone_gtk_set_configuration_uri(void);
GtkWidget * linphone_gtk_show_config_fetching(void);
void linphone_gtk_close_config_fetching(GtkWidget *w, LinphoneConfiguringState state);
const char *linphone_gtk_get_sound_path(const char *file);
void linphone_gtk_in_call_show_video(LinphoneCall *call);
char *linphone_gtk_address(const LinphoneAddress *addr);/*return human readable identifier for a LinphoneAddress */

View file

@ -48,7 +48,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef ENABLE_NLS
#include <locale.h>
#endif
#define LINPHONE_ICON "linphone.png"
const char *this_program_ident_string="linphone_ident_string=" LINPHONE_VERSION;
@ -318,6 +318,7 @@ static void linphone_gtk_init_liblinphone(const char *config_file,
g_free(secrets_file);
linphone_core_enable_video_capture(the_core, TRUE);
linphone_core_enable_video_display(the_core, TRUE);
linphone_core_set_native_video_window_id(the_core,-1);/*don't create the window*/
if (no_video) {
_linphone_gtk_enable_video(FALSE);
linphone_gtk_set_ui_config_int("videoselfview",0);
@ -439,9 +440,9 @@ GtkWidget *linphone_gtk_create_widget(const char *filename, const char *widget_n
return w;
}
static void entry_unmapped(GtkWidget *entry){
g_message("Entry is unmapped, calling unrealize to workaround chinese bug.");
gtk_widget_unrealize(entry);
static void entry_unmapped(GtkWidget *widget){
ms_message("%s is unmapped, calling unrealize to workaround chinese bug.",G_OBJECT_TYPE_NAME(widget));
gtk_widget_unrealize(widget);
}
GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name){
@ -458,10 +459,10 @@ GtkWidget *linphone_gtk_get_widget(GtkWidget *window, const char *name){
g_error("No widget named %s found in xml interface.",name);
}
if (workaround_gtk_entry_chinese_bug){
if (strcmp(G_OBJECT_TYPE_NAME(w),"GtkEntry")==0){
if (strcmp(G_OBJECT_TYPE_NAME(w),"GtkEntry")==0 || strcmp(G_OBJECT_TYPE_NAME(w),"GtkTextView")==0){
if (g_object_get_data(G_OBJECT(w),"entry_bug_workaround")==NULL){
g_object_set_data(G_OBJECT(w),"entry_bug_workaround",GINT_TO_POINTER(1));
g_message("%s is a GtkEntry",name);
ms_message("%s is a %s",name,G_OBJECT_TYPE_NAME(w));
g_signal_connect(G_OBJECT(w),"unmap",(GCallback)entry_unmapped,NULL);
}
}
@ -566,102 +567,6 @@ void linphone_gtk_show_about(){
gtk_widget_show(about);
}
static void set_video_window_decorations(GdkWindow *w){
const char *title=linphone_gtk_get_ui_config("title","Linphone");
const char *icon_path=linphone_gtk_get_ui_config("icon",LINPHONE_ICON);
char video_title[256];
GdkPixbuf *pbuf=create_pixbuf(icon_path);
if (!linphone_core_in_call(linphone_gtk_get_core())){
snprintf(video_title,sizeof(video_title),"%s video",title);
/* When not in call, treat the video as a normal window */
gdk_window_set_keep_above(w, FALSE);
}else{
LinphoneAddress *uri =
linphone_address_clone(linphone_core_get_current_call_remote_address(linphone_gtk_get_core()));
char *display_name;
linphone_address_clean(uri);
if (linphone_address_get_display_name(uri)!=NULL){
display_name=ms_strdup(linphone_address_get_display_name(uri));
}else{
display_name=linphone_address_as_string(uri);
}
snprintf(video_title,sizeof(video_title),_("Call with %s"),display_name);
linphone_address_destroy(uri);
ms_free(display_name);
/* During calls, bring up the video window, arrange so that
it is above all the other windows */
gdk_window_deiconify(w);
gdk_window_set_keep_above(w,TRUE);
/* Maybe we should have the following, but then we want to
have a timer that turns it off after a little while. */
/* gdk_window_set_urgency_hint(w,TRUE); */
}
gdk_window_set_title(w,video_title);
/* Refrain the video window to be closed at all times. */
gdk_window_set_functions(w,
GDK_FUNC_RESIZE|GDK_FUNC_MOVE|
GDK_FUNC_MINIMIZE|GDK_FUNC_MAXIMIZE);
if (pbuf){
GList *l=NULL;
l=g_list_append(l,pbuf);
gdk_window_set_icon_list(w,l);
g_list_free(l);
g_object_unref(G_OBJECT(pbuf));
}
}
static gboolean video_needs_update=FALSE;
static void update_video_title(){
video_needs_update=TRUE;
}
static void update_video_titles(LinphoneCore *lc){
unsigned long id;
static unsigned long previd=0;
static unsigned long preview_previd=0;
id=linphone_core_get_native_video_window_id(lc);
if (id!=previd || video_needs_update){
GdkWindow *w;
previd=id;
if (id!=0){
ms_message("Updating window decorations");
#ifndef WIN32
w=gdk_window_foreign_new((GdkNativeWindow)id);
#else
w=gdk_window_foreign_new((HANDLE)id);
#endif
if (w) {
set_video_window_decorations(w);
g_object_unref(G_OBJECT(w));
}
else ms_error("gdk_window_foreign_new() failed");
if (video_needs_update) video_needs_update=FALSE;
}
}
id=linphone_core_get_native_preview_window_id (lc);
if (id!=preview_previd ){
GdkWindow *w;
preview_previd=id;
if (id!=0){
ms_message("Updating window decorations for preview");
#ifndef WIN32
w=gdk_window_foreign_new((GdkNativeWindow)id);
#else
w=gdk_window_foreign_new((HANDLE)id);
#endif
if (w) {
set_video_window_decorations(w);
g_object_unref(G_OBJECT(w));
}
else ms_error("gdk_window_foreign_new() failed");
if (video_needs_update) video_needs_update=FALSE;
}
}
}
static gboolean linphone_gtk_iterate(LinphoneCore *lc){
static gboolean first_time=TRUE;
@ -677,7 +582,6 @@ static gboolean linphone_gtk_iterate(LinphoneCore *lc){
first_time=FALSE;
}
update_video_titles(lc);
if (addr_to_call!=NULL){
/*make sure we are not showing the login screen*/
GtkWidget *mw=linphone_gtk_get_main_window();
@ -864,7 +768,7 @@ static gboolean launch_contact_provider_search(void *userdata)
if( ldap && strlen(predicate) >= 3 ){ // don't search too small predicates
unsigned int max_res_count = linphone_ldap_contact_provider_get_max_result(ldap);
LinphoneContactSearch* search;
if( previous_search &&
(strstr(predicate, previous_search) == predicate) && // last search contained results from this one
(prev_res_count != max_res_count) ){ // and we didn't reach the max result limit
@ -879,7 +783,7 @@ static gboolean launch_contact_provider_search(void *userdata)
gtk_object_set_data(GTK_OBJECT(uribar), "previous_search", ms_strdup(predicate));
ms_message("launch_contact_provider_search");
LinphoneContactSearch* search =linphone_contact_provider_begin_search(
search =linphone_contact_provider_begin_search(
linphone_contact_provider_cast(ldap_provider),
predicate, on_contact_provider_search_results, uribar
);
@ -928,7 +832,6 @@ void linphone_gtk_call_terminated(LinphoneCall *call, const char *error){
}
if (linphone_gtk_use_in_call_view() && call)
linphone_gtk_in_call_view_terminate(call,error);
update_video_title();
}
static void linphone_gtk_update_call_buttons(LinphoneCall *call){
@ -940,6 +843,7 @@ static void linphone_gtk_update_call_buttons(LinphoneCall *call){
//bool_t stop_active=FALSE;
bool_t add_call=FALSE;
int call_list_size=ms_list_size(calls);
GtkWidget *conf_frame;
if (calls==NULL){
start_active=TRUE;
@ -962,7 +866,7 @@ static void linphone_gtk_update_call_buttons(LinphoneCall *call){
gtk_widget_set_visible(button,add_call);
//gtk_widget_set_sensitive(linphone_gtk_get_widget(mw,"terminate_call"),stop_active);
GtkWidget *conf_frame=(GtkWidget *)g_object_get_data(G_OBJECT(mw),"conf_frame");
conf_frame=(GtkWidget *)g_object_get_data(G_OBJECT(mw),"conf_frame");
if(conf_frame==NULL){
linphone_gtk_enable_transfer_button(lc,call_list_size>1);
linphone_gtk_enable_conference_button(lc,call_list_size>1);
@ -970,7 +874,6 @@ static void linphone_gtk_update_call_buttons(LinphoneCall *call){
linphone_gtk_enable_transfer_button(lc,FALSE);
linphone_gtk_enable_conference_button(lc,FALSE);
}
update_video_title();
if (call) {
linphone_gtk_update_video_button(call);
}
@ -1000,7 +903,7 @@ gchar *linphone_gtk_get_record_path(const LinphoneAddress *address, gboolean is_
break;
}
}
if (address){
id=linphone_address_get_username(address);
if (id==NULL) id=linphone_address_get_domain(address);
@ -1172,13 +1075,14 @@ static void linphone_gtk_new_subscriber_response(GtkWidget *dialog, guint respon
static void linphone_gtk_new_unknown_subscriber(LinphoneCore *lc, LinphoneFriend *lf, const char *url){
GtkWidget *dialog;
gchar *message;
if (linphone_gtk_get_ui_config_int("subscribe_deny_all",0)){
linphone_core_reject_subscriber(linphone_gtk_get_core(),lf);
return;
}
gchar *message=g_strdup_printf(_("%s would like to add you to his contact list.\nWould you allow him to see your presence status or add him to your contact list ?\nIf you answer no, this person will be temporarily blacklisted."),url);
message=g_strdup_printf(_("%s would like to add you to his contact list.\nWould you allow him to see your presence status or add him to your contact list ?\nIf you answer no, this person will be temporarily blacklisted."),url);
dialog = gtk_message_dialog_new (
GTK_WINDOW(linphone_gtk_get_main_window()),
GTK_DIALOG_DESTROY_WITH_PARENT,
@ -1540,7 +1444,7 @@ static void update_registration_status(LinphoneProxyConfig *cfg, LinphoneRegistr
}while(gtk_tree_model_iter_next(model,&iter));
}
if (!found) {
g_warning("Could not find proxy config in combo box of identities.");
/*ignored, this is a notification for a removed proxy config.*/
return;
}
switch (rs){
@ -2001,10 +1905,11 @@ void linphone_gtk_keypad_key_released(GtkWidget *w, GdkEvent *event, gpointer us
void linphone_gtk_create_keypad(GtkWidget *button){
GtkWidget *mw=linphone_gtk_get_main_window();
GtkWidget *k=(GtkWidget *)g_object_get_data(G_OBJECT(mw),"keypad");
GtkWidget *keypad;
if(k!=NULL){
gtk_widget_destroy(k);
}
GtkWidget *keypad=linphone_gtk_create_window("keypad");
keypad=linphone_gtk_create_window("keypad");
linphone_gtk_connect_digits(keypad);
linphone_gtk_init_dtmf_table(keypad);
g_object_set_data(G_OBJECT(mw),"keypad",(gpointer)keypad);

View file

@ -179,6 +179,7 @@ void linphone_gtk_ldap_save(GtkWidget *button)
GtkEntry* entry;
GtkToggleButton* toggle;
GtkSpinButton* spin;
GtkComboBox* cbox;
ms_message("SAVE LDAP");
@ -204,7 +205,7 @@ void linphone_gtk_ldap_save(GtkWidget *button)
linphone_dictionary_set_string(dict, "sasl_realm", gtk_entry_get_text(entry));
GtkComboBox* cbox = GTK_COMBO_BOX(linphone_gtk_get_widget(ldap_widget,"ldap_auth_method"));
cbox = GTK_COMBO_BOX(linphone_gtk_get_widget(ldap_widget,"ldap_auth_method"));
linphone_dictionary_set_string(dict, "auth_method", gtk_combo_box_get_active_text(cbox));
entry = GTK_ENTRY(linphone_gtk_get_widget(ldap_widget,"ldap_base_object"));
@ -245,10 +246,11 @@ void linphone_gtk_ldap_save(GtkWidget *button)
}
void linphone_gtk_fill_video_sizes(GtkWidget *combo){
const MSVideoSizeDef *def=linphone_core_get_supported_video_sizes(linphone_gtk_get_core());;
int i,active=0;
int i;
int active=0;
char vsize_def[256];
MSVideoSize cur=linphone_core_get_preferred_video_size(linphone_gtk_get_core());
const MSVideoSizeDef *def=linphone_core_get_supported_video_sizes(linphone_gtk_get_core());;
/* glade creates a combo box without list model and text renderer,
unless we fill it with a dummy text.
This dummy text needs to be removed first*/
@ -828,8 +830,11 @@ void linphone_gtk_show_sip_accounts(GtkWidget *w){
static void linphone_gtk_proxy_closed(GtkWidget *w){
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)g_object_get_data(G_OBJECT(w),"config");
gboolean was_editing=! GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"is_new"));
if (cfg){
linphone_proxy_config_done(cfg);
if (was_editing){
linphone_proxy_config_done(cfg);
}else linphone_proxy_config_destroy(cfg);
}
}
@ -907,7 +912,15 @@ void linphone_gtk_proxy_address_changed(GtkEditable *editable){
void linphone_gtk_show_proxy_config(GtkWidget *pb, LinphoneProxyConfig *cfg){
GtkWidget *w=linphone_gtk_create_window("sip_account");
const char *tmp;
if (cfg){
gboolean is_new=FALSE;
if (!cfg) {
cfg=linphone_core_create_proxy_config(linphone_gtk_get_core());
is_new=TRUE;
g_object_set_data(G_OBJECT(w),"is_new",GINT_TO_POINTER(TRUE));
}
if (!is_new){
linphone_proxy_config_edit(cfg);
gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"identity")),
linphone_proxy_config_get_identity(cfg));
@ -916,17 +929,19 @@ void linphone_gtk_show_proxy_config(GtkWidget *pb, LinphoneProxyConfig *cfg){
if (tmp) gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"route")),tmp);
tmp=linphone_proxy_config_get_contact_parameters(cfg);
if (tmp) gtk_entry_set_text(GTK_ENTRY(linphone_gtk_get_widget(w,"params")),tmp);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"regperiod")),
linphone_proxy_config_get_expires(cfg));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"register")),
linphone_proxy_config_register_enabled(cfg));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"publish")),
linphone_proxy_config_publish_enabled(cfg));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"avpf")),
linphone_proxy_config_avpf_enabled(cfg));
gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"avpf_rr_interval")),
linphone_proxy_config_get_avpf_rr_interval(cfg));
}
gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"regperiod")),
linphone_proxy_config_get_expires(cfg));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"register")),
linphone_proxy_config_register_enabled(cfg));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"publish")),
linphone_proxy_config_publish_enabled(cfg));
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"avpf")),
linphone_proxy_config_avpf_enabled(cfg));
gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"avpf_rr_interval")),
linphone_proxy_config_get_avpf_rr_interval(cfg));
g_object_set_data(G_OBJECT(w),"config",(gpointer)cfg);
g_object_set_data(G_OBJECT(w),"parameters",(gpointer)pb);
g_object_weak_ref(G_OBJECT(w),(GWeakNotify)linphone_gtk_proxy_closed,w);
@ -944,12 +959,8 @@ void linphone_gtk_proxy_ok(GtkButton *button){
LinphoneProxyConfig *cfg=(LinphoneProxyConfig*)g_object_get_data(G_OBJECT(w),"config");
int index=gtk_combo_box_get_active(GTK_COMBO_BOX(linphone_gtk_get_widget(w,"transport")));
LinphoneTransportType tport=(LinphoneTransportType)index;
gboolean was_editing=TRUE;
gboolean was_editing=! GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"is_new"));
if (!cfg){
was_editing=FALSE;
cfg=linphone_proxy_config_new();
}
linphone_proxy_config_set_identity(cfg,
gtk_entry_get_text(GTK_ENTRY(linphone_gtk_get_widget(w,"identity"))));
if (linphone_proxy_config_set_server_addr(cfg,
@ -1098,14 +1109,14 @@ static void linphone_gtk_fill_langs(GtkWidget *pb){
const char *all_langs="C " LINPHONE_ALL_LANGS;
const char *name;
int i=0,index=0;
int cur_lang_index=-1;
char text[256]={0};
const char *cur_lang;
#if defined(WIN32) || defined(__APPLE__)
cur_lang=getenv("LANG");
#else
cur_lang=getenv("LANGUAGE");
#endif
int cur_lang_index=-1;
char text[256]={0};
if (cur_lang==NULL) cur_lang="C";
/* glade creates a combo box without list model and text renderer,
unless we fill it with a dummy text.
@ -1581,7 +1592,7 @@ void linphone_gtk_edit_tunnel(GtkButton *button){
if (port==0) port=443;
gtk_spin_button_set_value(GTK_SPIN_BUTTON(linphone_gtk_get_widget(w,"port")), port);
if (linphone_tunnel_enabled(tunnel)){
if (linphone_tunnel_get_mode(tunnel)){
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"radio_enable")),1);
} else{
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(linphone_gtk_get_widget(w,"radio_disable")),1);
@ -1625,7 +1636,7 @@ void linphone_gtk_tunnel_ok(GtkButton *button){
linphone_tunnel_config_set_host(config, host);
linphone_tunnel_config_set_port(config, port);
linphone_tunnel_add_server(tunnel, config);
linphone_tunnel_enable(tunnel,enabled);
linphone_tunnel_set_mode(tunnel, (enabled ? LinphoneTunnelModeEnable : LinphoneTunnelModeDisable));
linphone_tunnel_set_http_proxy(tunnel,http_host,http_port,username,password);
gtk_widget_destroy(w);

View file

@ -44,7 +44,7 @@ static GtkWidget *create_setup_signin_choice(){
GtkWidget *t2=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(t1),_("I have already a linphone.org account and I just want to use it"));
GtkWidget *t3=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(t1),_("I have already a sip account and I just want to use it"));
GtkWidget *t4=gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(t1),_("I want to specify a remote configuration URI"));
gtk_box_pack_start (GTK_BOX (vbox), t1, TRUE, TRUE, 2);
gtk_box_pack_start (GTK_BOX (vbox), t2, TRUE, TRUE, 2);
gtk_box_pack_start (GTK_BOX (vbox), t3, TRUE, TRUE, 2);
@ -89,14 +89,20 @@ static GtkWidget *create_linphone_account_informations_page() {
GtkWidget *label=gtk_label_new(_("Enter your linphone.org username"));
GdkColor color;
GtkWidget *labelEmpty;
GtkWidget *labelUsername;
GtkWidget *entryUsername;
GtkWidget *labelPassword;
GtkWidget *entryPassword;
gdk_color_parse ("red", &color);
GtkWidget *labelEmpty=gtk_label_new(NULL);
labelEmpty=gtk_label_new(NULL);
gtk_widget_modify_fg(labelEmpty, GTK_STATE_NORMAL, &color);
GtkWidget *labelUsername=gtk_label_new(_("Username:"));
GtkWidget *entryUsername=gtk_entry_new();
GtkWidget *labelPassword=gtk_label_new(_("Password:"));
GtkWidget *entryPassword=gtk_entry_new();
labelUsername=gtk_label_new(_("Username:"));
entryUsername=gtk_entry_new();
labelPassword=gtk_label_new(_("Password:"));
entryPassword=gtk_entry_new();
gtk_entry_set_visibility(GTK_ENTRY(entryPassword), FALSE);
gtk_table_attach_defaults(GTK_TABLE(vbox), label, 0, 2, 0, 1);
@ -118,19 +124,28 @@ static GtkWidget *create_account_informations_page() {
GtkWidget *label=gtk_label_new(_("Enter your account informations"));
GdkColor color;
GtkWidget *labelEmpty;
GtkWidget *labelUsername;
GtkWidget *labelPassword;
GtkWidget *entryPassword;
GtkWidget *labelDomain;
GtkWidget *labelProxy;
GtkWidget *entryUsername;
GtkWidget *entryDomain;
GtkWidget *entryRoute;
gdk_color_parse ("red", &color);
GtkWidget *labelEmpty=gtk_label_new(NULL);
labelEmpty=gtk_label_new(NULL);
gtk_widget_modify_fg(labelEmpty, GTK_STATE_NORMAL, &color);
GtkWidget *labelUsername=gtk_label_new(_("Username*"));
GtkWidget *labelPassword=gtk_label_new(_("Password*"));
GtkWidget *entryPassword=gtk_entry_new();
labelUsername=gtk_label_new(_("Username*"));
labelPassword=gtk_label_new(_("Password*"));
entryPassword=gtk_entry_new();
gtk_entry_set_visibility(GTK_ENTRY(entryPassword), FALSE);
GtkWidget *labelDomain=gtk_label_new(_("Domain*"));
GtkWidget *labelProxy=gtk_label_new(_("Proxy"));
GtkWidget *entryUsername=gtk_entry_new();
GtkWidget *entryDomain=gtk_entry_new();
GtkWidget *entryRoute=gtk_entry_new();
labelDomain=gtk_label_new(_("Domain*"));
labelProxy=gtk_label_new(_("Proxy"));
entryUsername=gtk_entry_new();
entryDomain=gtk_entry_new();
entryRoute=gtk_entry_new();
gtk_table_attach_defaults(GTK_TABLE(vbox), label, 0, 2, 0, 1);
gtk_table_attach_defaults(GTK_TABLE(vbox), labelUsername, 0, 1, 1, 2);
@ -309,19 +324,25 @@ static GtkWidget *create_account_information_page() {
GtkWidget *labelPassword2=gtk_label_new(_("Confirm your password: (*)"));
GtkWidget *entryUsername=gtk_entry_new();
GtkWidget *entryPassword=gtk_entry_new();
gtk_entry_set_visibility(GTK_ENTRY(entryPassword), FALSE);
GtkWidget *entryEmail=gtk_entry_new();
GtkWidget *entryPassword2=gtk_entry_new();
gtk_entry_set_visibility(GTK_ENTRY(entryPassword2), FALSE);
GtkWidget *checkNewsletter=gtk_check_button_new_with_label("Keep me informed with linphone updates");
GtkWidget *entryEmail;
GtkWidget *entryPassword2;
GtkWidget *checkNewsletter;
GtkWidget *labelError;
GtkWidget *passwordVbox1;
GtkWidget *passwordVbox2;
GdkColor color;
gtk_entry_set_visibility(GTK_ENTRY(entryPassword), FALSE);
entryEmail=gtk_entry_new();
entryPassword2=gtk_entry_new();
gtk_entry_set_visibility(GTK_ENTRY(entryPassword2), FALSE);
checkNewsletter=gtk_check_button_new_with_label(_("Keep me informed with linphone updates"));
gdk_color_parse ("red", &color);
GtkWidget *labelError=gtk_label_new(NULL);
labelError=gtk_label_new(NULL);
gtk_widget_modify_fg(labelError, GTK_STATE_NORMAL, &color);
GtkWidget *passwordVbox1=gtk_vbox_new(FALSE,2);
GtkWidget *passwordVbox2=gtk_vbox_new(FALSE,2);
passwordVbox1=gtk_vbox_new(FALSE,2);
passwordVbox2=gtk_vbox_new(FALSE,2);
gtk_box_pack_start (GTK_BOX (passwordVbox1), labelPassword, TRUE, FALSE, 2);
gtk_box_pack_start (GTK_BOX (passwordVbox1), labelPassword2, TRUE, FALSE, 2);
gtk_box_pack_start (GTK_BOX (passwordVbox2), entryPassword, TRUE, FALSE, 2);
@ -414,6 +435,8 @@ static void linphone_gtk_assistant_prepare(GtkWidget *assistant, GtkWidget *page
if (pagenum == 5) {
gtk_assistant_commit(GTK_ASSISTANT(assistant));
} else if (pagenum == gtk_assistant_get_n_pages(GTK_ASSISTANT(assistant)) - 1) {
LinphoneAddress *identity;
LinphoneAuthInfo *info;
// Saving the account and making it default
LinphoneAccountCreator *creator=linphone_gtk_assistant_get_creator(assistant);
LinphoneProxyConfig *cfg=linphone_proxy_config_new();
@ -424,30 +447,33 @@ static void linphone_gtk_assistant_prepare(GtkWidget *assistant, GtkWidget *page
linphone_proxy_config_enable_publish(cfg, FALSE);
linphone_proxy_config_enable_register(cfg, TRUE);
LinphoneAddress *identity = linphone_address_new(creator->username);
LinphoneAuthInfo *info=linphone_auth_info_new(linphone_address_get_username(identity), NULL, creator->password, NULL, NULL, linphone_address_get_domain(identity));
identity = linphone_address_new(creator->username);
info=linphone_auth_info_new(linphone_address_get_username(identity), NULL, creator->password, NULL, NULL, linphone_address_get_domain(identity));
linphone_core_add_auth_info(linphone_gtk_get_core(),info);
linphone_address_destroy(identity);
// If account created on sip.linphone.org, we configure linphone to use TLS by default
if (strcmp(creator->domain, "sip:sip.linphone.org") == 0 && linphone_core_sip_transport_supported(linphone_gtk_get_core(),LinphoneTransportTls)) {
LinphoneAddress *addr=linphone_address_new(creator->domain);
char *tmp;
linphone_address_set_transport(addr, LinphoneTransportTls);
tmp=linphone_address_as_string(addr);
linphone_proxy_config_set_server_addr(cfg,tmp);
linphone_proxy_config_set_route(cfg,tmp);
ms_free(tmp);
linphone_address_destroy(addr);
if (strcmp(creator->domain, "sip:sip.linphone.org") == 0 ){
linphone_proxy_config_enable_avpf(cfg,TRUE);
// If account created on sip.linphone.org, we configure linphone to use TLS by default
if (linphone_core_sip_transport_supported(linphone_gtk_get_core(),LinphoneTransportTls)) {
LinphoneAddress *addr=linphone_address_new(creator->domain);
char *tmp;
linphone_address_set_transport(addr, LinphoneTransportTls);
tmp=linphone_address_as_string(addr);
linphone_proxy_config_set_server_addr(cfg,tmp);
linphone_proxy_config_set_route(cfg,tmp);
ms_free(tmp);
linphone_address_destroy(addr);
}
}
if (linphone_core_add_proxy_config(linphone_gtk_get_core(),cfg)==-1)
return;
linphone_core_set_default_proxy(linphone_gtk_get_core(),cfg);
linphone_gtk_load_identities();
}
}
@ -486,9 +512,9 @@ static int linphone_gtk_assistant_forward(int curpage, gpointer data){
else if (curpage == 2) { // Account's informations entered
LinphoneAccountCreator *c=linphone_gtk_assistant_get_creator(w);
gchar identity[128];
gchar proxy[128];
g_snprintf(identity, sizeof(identity), "sip:%s@%s", gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"username"))), gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"domain"))));
gchar proxy[128];
g_snprintf(proxy, sizeof(proxy), "sip:%s", gtk_entry_get_text(GTK_ENTRY(g_object_get_data(G_OBJECT(box),"domain"))));
linphone_account_creator_set_username(c, identity);
@ -557,25 +583,35 @@ void linphone_gtk_close_assistant(void){
}
void linphone_gtk_show_assistant(void){
GtkWidget *w;
GtkWidget *p1;
GtkWidget *p2;
GtkWidget *p31;
GtkWidget *p32;
GtkWidget *p33;
//GtkWidget *confirm;
GtkWidget *validate;
GtkWidget *error;
GtkWidget *end;
if(the_assistant!=NULL)
return;
GtkWidget *w=the_assistant=gtk_assistant_new();
w=the_assistant=gtk_assistant_new();
gtk_window_set_resizable (GTK_WINDOW(w), FALSE);
gtk_window_set_title(GTK_WINDOW(w),_("SIP account configuration assistant"));
ok = create_pixbuf(linphone_gtk_get_ui_config("ok","ok.png"));
notok = create_pixbuf(linphone_gtk_get_ui_config("notok","notok.png"));
GtkWidget *p1=create_intro();
GtkWidget *p2=create_setup_signin_choice();
GtkWidget *p31=create_account_informations_page();
GtkWidget *p32=create_linphone_account_informations_page();
GtkWidget *p33=create_account_information_page();
//GtkWidget *confirm=create_confirmation_page();
GtkWidget *validate=wait_for_activation();
GtkWidget *error=create_error_page();
GtkWidget *end=create_finish_page();
p1=create_intro();
p2=create_setup_signin_choice();
p31=create_account_informations_page();
p32=create_linphone_account_informations_page();
p33=create_account_information_page();
//confirm=create_confirmation_page();
validate=wait_for_activation();
error=create_error_page();
end=create_finish_page();
linphone_gtk_assistant_init(w);
gtk_assistant_append_page(GTK_ASSISTANT(w),p1);
gtk_assistant_set_page_type(GTK_ASSISTANT(w),p1,GTK_ASSISTANT_PAGE_INTRO);

View file

@ -58,7 +58,7 @@ static gboolean execute_wakeup(char *buf){
static void * server_pipe_thread(void *pointer){
ortp_pipe_t child;
do{
child=ortp_server_pipe_accept_client(server_pipe);
if (server_pipe_running && child!=(ortp_pipe_t)-1){
@ -87,8 +87,9 @@ static void linphone_gtk_init_pipe(const char *name){
}
bool_t linphone_gtk_init_instance(const char *app_name, int option, const char *addr_to_call){
ortp_pipe_t p;
pipe_name=make_name(app_name);
ortp_pipe_t p=ortp_client_pipe_connect(pipe_name);
p=ortp_client_pipe_connect(pipe_name);
if (p!=(ortp_pipe_t)-1){
uint8_t buf[256]={0};
g_message("There is already a running instance.");

View file

@ -92,17 +92,17 @@ create_pixbuf_animation(const gchar *filename)
gchar *pathname = NULL;
GdkPixbufAnimation *pixbuf;
GError *error = NULL;
if (!filename || !filename[0])
return NULL;
pathname = find_pixmap_file (filename);
if (!pathname){
g_warning (_("Couldn't find pixmap file: %s"), filename);
return NULL;
}
pixbuf = gdk_pixbuf_animation_new_from_file (pathname, &error);
if (!pixbuf){
fprintf (stderr, "Failed to load pixbuf file: %s: %s\n",
@ -156,6 +156,11 @@ const char *linphone_gtk_get_lang(const char *config_file){
void linphone_gtk_set_lang(const char *code){
LpConfig *cfg=linphone_core_get_config(linphone_gtk_get_core());
const char *curlang;
#ifdef WIN32
char tmp[128];
#endif
#if defined(WIN32) || defined(__APPLE__)
curlang=getenv("LANG");
#else
@ -167,12 +172,11 @@ void linphone_gtk_set_lang(const char *code){
}
lp_config_set_string(cfg,"GtkUi","lang",code);
#ifdef WIN32
char tmp[128];
snprintf(tmp,sizeof(tmp),"LANG=%s",code);
_putenv(tmp);
#elif __APPLE__
setenv("LANG",code,1);
#else
#else
setenv("LANGUAGE",code,1);
#endif
}

310
gtk/videowindow.c Normal file
View file

@ -0,0 +1,310 @@
/*
linphone, gtk interface.
Copyright (C) 2014 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, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include "linphone.h"
#ifdef __linux
#include <gdk/gdkx.h>
#elif defined(WIN32)
#include <gdk/gdkwin32.h>
#elif defined(__APPLE__)
extern void *gdk_quartz_window_get_nswindow(GdkWindow *window);
extern void *gdk_quartz_window_get_nsview(GdkWindow *window);
#endif
#include <gdk/gdkkeysyms.h>
enum {
TARGET_STRING,
TARGET_TEXT,
TARGET_URILIST
};
static GtkTargetEntry targets[] = {
{ "text/uri-list", GTK_TARGET_OTHER_APP, TARGET_URILIST },
};
static void set_video_controls_position(GtkWidget *video_window);
static void on_end_of_play(LinphonePlayer *player, void *user_data){
linphone_player_close(player);
}
static void drag_data_received(GtkWidget *widget, GdkDragContext *context, gint x, gint y,
GtkSelectionData *selection_data, guint target_type, guint time, gpointer user_data){
int datalen=gtk_selection_data_get_length(selection_data) >= 0;
const void *data=gtk_selection_data_get_data(selection_data);
LinphoneCall *call=g_object_get_data(G_OBJECT(widget),"call");
ms_message("target_type=%i, datalen=%i, data=%p",target_type,datalen,data);
if (target_type==TARGET_URILIST && data){
LinphonePlayer *player=linphone_call_get_player(call);
const char *path=(const char*)data;
if (player){
if (strstr(path,"file://")==path) path+=strlen("file://");
if (linphone_player_open(player,path,on_end_of_play,NULL)==0){
linphone_player_start(player);
}else{
GtkWidget *warn=gtk_message_dialog_new(GTK_WINDOW(widget),GTK_DIALOG_MODAL|GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_MESSAGE_ERROR,GTK_BUTTONS_CLOSE,
_("Cannot play %s."),path);
g_signal_connect(warn,"response",(GCallback)gtk_widget_destroy,NULL);
gtk_widget_show(warn);
}
}
}
gtk_drag_finish (context, TRUE, FALSE, time);
}
static gboolean drag_drop(GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, guint time, gpointer user_data){
#if GTK_CHECK_VERSION(2,20,0)
GList *l=gdk_drag_context_list_targets(drag_context);
GList *elem;
if (l){
ms_message("drag_drop");
/* Choose the best target type */
for(elem=l;elem!=NULL;elem=g_list_next(elem)){
char *name=gdk_atom_name(GDK_POINTER_TO_ATOM(elem->data));
ms_message("target: %s",name);
g_free(name);
}
}else{
ms_warning("drag_drop no targets");
return FALSE;
}
#endif
return TRUE;
}
unsigned long get_native_handle(GdkWindow *gdkw){
#ifdef __linux
return (unsigned long)GDK_WINDOW_XID(gdkw);
#elif defined(WIN32)
return (unsigned long)GDK_WINDOW_HWND(gdkw);
#elif defined(__APPLE__)
return (unsigned long)gdk_quartz_window_get_nsview(gdkw);
#endif
g_warning("No way to get the native handle from gdk window");
return 0;
}
static gint resize_video_window(LinphoneCall *call){
const LinphoneCallParams *params=linphone_call_get_current_params(call);
if (params){
MSVideoSize vsize=linphone_call_params_get_received_video_size(params);
if (vsize.width>0 && vsize.height>0){
GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call);
GtkWidget *video_window=(GtkWidget*)g_object_get_data(G_OBJECT(callview),"video_window");
if (video_window){
MSVideoSize cur;
gtk_window_get_size(GTK_WINDOW(video_window),&cur.width,&cur.height);
if (vsize.width*vsize.height > cur.width*cur.height ||
ms_video_size_get_orientation(vsize)!=ms_video_size_get_orientation(cur) ){
g_message("Resized to %ix%i",vsize.width,vsize.height);
gtk_window_resize(GTK_WINDOW(video_window),vsize.width,vsize.height);
}
}
}
}
return TRUE;
}
static void on_video_window_destroy(GtkWidget *w, guint timeout){
g_source_remove(timeout);
linphone_core_set_native_video_window_id(linphone_gtk_get_core(),(unsigned long)-1);
}
static void video_window_set_fullscreen(GtkWidget *w, gboolean val){
if (val){
g_object_set_data(G_OBJECT(w),"fullscreen",GINT_TO_POINTER(1));
gtk_window_fullscreen(GTK_WINDOW(w));
}else{
g_object_set_data(G_OBJECT(w),"fullscreen",GINT_TO_POINTER(0));
gtk_window_unfullscreen(GTK_WINDOW(w));
}
}
/*old names in old version of gdk*/
#ifndef GDK_KEY_Escape
#define GDK_KEY_Escape GDK_Escape
#define GDK_KEY_F GDK_F
#define GDK_KEY_f GDK_f
#endif
static void on_video_window_key_press(GtkWidget *w, GdkEvent *ev, gpointer up){
g_message("Key press event");
switch(ev->key.keyval){
case GDK_KEY_f:
case GDK_KEY_F:
video_window_set_fullscreen(w,TRUE);
break;
case GDK_KEY_Escape:
video_window_set_fullscreen(w,FALSE);
break;
}
}
static void on_controls_response(GtkWidget *dialog, int response_id, GtkWidget *video_window){
gtk_widget_destroy(dialog);
switch(response_id){
case GTK_RESPONSE_YES:
video_window_set_fullscreen(video_window,TRUE);
break;
case GTK_RESPONSE_NO:
video_window_set_fullscreen(video_window,FALSE);
break;
case GTK_RESPONSE_REJECT:
{
LinphoneCall *call=(LinphoneCall*)g_object_get_data(G_OBJECT(video_window),"call");
linphone_core_terminate_call(linphone_gtk_get_core(),call);
}
break;
}
}
static void on_controls_destroy(GtkWidget *w){
GtkWidget *video_window=(GtkWidget*)g_object_get_data(G_OBJECT(w),"video_window");
gint timeout=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"timeout"));
if (timeout!=0){
g_source_remove(timeout);
g_object_set_data(G_OBJECT(w),"timeout",GINT_TO_POINTER(0));
}
g_object_set_data(G_OBJECT(video_window),"controls",NULL);
}
static gboolean _set_video_controls_position(GtkWidget *video_window){
GtkWidget *w=(GtkWidget*)g_object_get_data(G_OBJECT(video_window),"controls");
if (w){
gint vw,vh;
gint cw,ch;
gint x,y;
gtk_window_get_size(GTK_WINDOW(video_window),&vw,&vh);
gtk_window_get_position(GTK_WINDOW(video_window),&x,&y);
gtk_window_get_size(GTK_WINDOW(w),&cw,&ch);
gtk_window_move(GTK_WINDOW(w),x+vw/2 - cw/2, y + vh - ch);
}
return FALSE;
}
static void set_video_controls_position(GtkWidget *video_window){
/*do it a first time*/
_set_video_controls_position(video_window);
/*and schedule to do it a second time in order to workaround a bug in fullscreen mode, where poistion is not taken into account the first time*/
g_timeout_add(0,(GSourceFunc)_set_video_controls_position,video_window);
}
static gboolean video_window_moved(GtkWidget *widget, GdkEvent *event, gpointer user_data){
set_video_controls_position(widget);
return FALSE;
}
static GtkWidget *show_video_controls(GtkWidget *video_window){
GtkWidget *w;
w=(GtkWidget*)g_object_get_data(G_OBJECT(video_window),"controls");
if (!w){
gboolean isfullscreen=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(video_window),"fullscreen"));
const char *stock_button=isfullscreen ? GTK_STOCK_LEAVE_FULLSCREEN : GTK_STOCK_FULLSCREEN;
gint response_id=isfullscreen ? GTK_RESPONSE_NO : GTK_RESPONSE_YES ;
gint timeout;
GtkWidget *button;
w=gtk_dialog_new_with_buttons("",GTK_WINDOW(video_window),GTK_DIALOG_DESTROY_WITH_PARENT,stock_button,response_id,NULL);
gtk_window_set_opacity(GTK_WINDOW(w),0.5);
gtk_window_set_decorated(GTK_WINDOW(w),FALSE);
button=gtk_button_new_with_label(_("Hang up"));
gtk_button_set_image(GTK_BUTTON(button),create_pixmap (linphone_gtk_get_ui_config("stop_call_icon","stopcall-small.png")));
gtk_widget_show(button);
gtk_dialog_add_action_widget(GTK_DIALOG(w),button,GTK_RESPONSE_REJECT);
g_signal_connect(w,"response",(GCallback)on_controls_response,video_window);
timeout=g_timeout_add(3000,(GSourceFunc)gtk_widget_destroy,w);
g_object_set_data(G_OBJECT(w),"timeout",GINT_TO_POINTER(timeout));
g_signal_connect(w,"destroy",(GCallback)on_controls_destroy,NULL);
g_object_set_data(G_OBJECT(w),"video_window",video_window);
g_object_set_data(G_OBJECT(video_window),"controls",w);
set_video_controls_position(video_window);
gtk_widget_show(w);
}else{
gint timeout=GPOINTER_TO_INT(g_object_get_data(G_OBJECT(w),"timeout"));
g_source_remove(timeout);
timeout=g_timeout_add(3000,(GSourceFunc)gtk_widget_destroy,w);
g_object_set_data(G_OBJECT(w),"timeout",GINT_TO_POINTER(timeout));
}
return w;
}
static GtkWidget *create_video_window(LinphoneCall *call){
char *remote,*title;
GtkWidget *video_window;
const LinphoneAddress *addr;
const char *icon_path=linphone_gtk_get_ui_config("icon",LINPHONE_ICON);
GdkPixbuf *pbuf=create_pixbuf(icon_path);
guint timeout;
MSVideoSize vsize=MS_VIDEO_SIZE_CIF;
GdkColor color;
addr=linphone_call_get_remote_address(call);
remote=linphone_gtk_address(addr);
video_window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
title=g_strdup_printf("%s - Video call with %s",linphone_gtk_get_ui_config("title","Linphone"),remote);
ms_free(remote);
gtk_window_set_title(GTK_WINDOW(video_window),title);
g_free(title);
if (pbuf){
gtk_window_set_icon(GTK_WINDOW(video_window),pbuf);
}
gtk_window_resize(GTK_WINDOW(video_window),vsize.width,vsize.height);
gdk_color_parse("black",&color);
gtk_widget_modify_bg(video_window,GTK_STATE_NORMAL,&color);
gtk_drag_dest_set(video_window, GTK_DEST_DEFAULT_ALL, targets, sizeof(targets)/sizeof(GtkTargetEntry), GDK_ACTION_COPY);
gtk_widget_show(video_window);
gdk_window_set_events(gtk_widget_get_window(video_window),
gdk_window_get_events(gtk_widget_get_window(video_window)) | GDK_POINTER_MOTION_MASK);
timeout=g_timeout_add(500,(GSourceFunc)resize_video_window,call);
g_signal_connect(video_window,"destroy",(GCallback)on_video_window_destroy,GINT_TO_POINTER(timeout));
g_signal_connect(video_window,"key-press-event",(GCallback)on_video_window_key_press,NULL);
g_signal_connect_swapped(video_window,"motion-notify-event",(GCallback)show_video_controls,video_window);
g_signal_connect(video_window,"configure-event",(GCallback)video_window_moved,NULL);
g_signal_connect(video_window, "drag-data-received",(GCallback)drag_data_received, NULL);
g_signal_connect(video_window, "drag-drop",(GCallback)drag_drop, NULL);
g_object_set_data(G_OBJECT(video_window),"call",call);
return video_window;
}
void linphone_gtk_in_call_show_video(LinphoneCall *call){
GtkWidget *callview=(GtkWidget*)linphone_call_get_user_pointer(call);
GtkWidget *video_window=(GtkWidget*)g_object_get_data(G_OBJECT(callview),"video_window");
const LinphoneCallParams *params=linphone_call_get_current_params(call);
LinphoneCore *lc=linphone_gtk_get_core();
if (linphone_call_get_state(call)!=LinphoneCallPaused && params && linphone_call_params_video_enabled(params)){
if (video_window==NULL){
video_window=create_video_window(call);
g_object_set_data(G_OBJECT(callview),"video_window",video_window);
}
linphone_core_set_native_video_window_id(lc,get_native_handle(gtk_widget_get_window(video_window)));
}else{
if (video_window){
gtk_widget_destroy(video_window);
g_object_set_data(G_OBJECT(callview),"video_window",NULL);
}
}
}

View file

@ -68,11 +68,15 @@ typedef enum {
SalTransportDTLS /*DTLS*/
}SalTransport;
#define SAL_MEDIA_DESCRIPTION_UNCHANGED 0x00
#define SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED 0x01
#define SAL_MEDIA_DESCRIPTION_CODEC_CHANGED 0x02
#define SAL_MEDIA_DESCRIPTION_CRYPTO_CHANGED 0x04
#define SAL_MEDIA_DESCRIPTION_CHANGED (SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED | SAL_MEDIA_DESCRIPTION_CODEC_CHANGED | SAL_MEDIA_DESCRIPTION_CRYPTO_CHANGED)
#define SAL_MEDIA_DESCRIPTION_UNCHANGED 0x00
#define SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED (1)
#define SAL_MEDIA_DESCRIPTION_CODEC_CHANGED (1<<1)
#define SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED (1<<2)
#define SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED (1<<3)
#define SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED (1<<4)
#define SAL_MEDIA_DESCRIPTION_CHANGED (SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED | SAL_MEDIA_DESCRIPTION_CODEC_CHANGED |\
SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED |SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED | SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED)
const char* sal_transport_to_string(SalTransport transport);
SalTransport sal_transport_parse(const char*);
@ -413,7 +417,7 @@ typedef void (*SalOnCallReceived)(SalOp *op);
typedef void (*SalOnCallRinging)(SalOp *op);
typedef void (*SalOnCallAccepted)(SalOp *op);
typedef void (*SalOnCallAck)(SalOp *op);
typedef void (*SalOnCallUpdating)(SalOp *op);/*< Called when a reINVITE/UPDATE is received*/
typedef void (*SalOnCallUpdating)(SalOp *op, bool_t is_update);/*< Called when a reINVITE/UPDATE is received*/
typedef void (*SalOnCallTerminated)(SalOp *op, const char *from);
typedef void (*SalOnCallFailure)(SalOp *op);
typedef void (*SalOnCallReleased)(SalOp *salop);
@ -517,6 +521,10 @@ int sal_get_listening_port(Sal *ctx, SalTransport tr);
int sal_unlisten_ports(Sal *ctx);
int sal_transport_available(Sal *ctx, SalTransport t);
void sal_set_dscp(Sal *ctx, int dscp);
void sal_set_supported_tags(Sal *ctx, const char* tags);
void sal_add_supported_tag(Sal *ctx, const char* tag);
void sal_remove_supported_tag(Sal *ctx, const char* tag);
const char *sal_get_supported_tags(Sal *ctx);
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);
@ -615,7 +623,7 @@ int sal_call_notify_ringing(SalOp *h, bool_t early_media);
/*accept an incoming call or, during a call accept a reINVITE*/
int sal_call_accept(SalOp*h);
int sal_call_decline(SalOp *h, SalReason reason, const char *redirection /*optional*/);
int sal_call_update(SalOp *h, const char *subject);
int sal_call_update(SalOp *h, const char *subject, bool_t no_user_consent);
SalMediaDescription * sal_call_get_remote_media_description(SalOp *h);
SalMediaDescription * sal_call_get_final_media_description(SalOp *h);
int sal_call_refer(SalOp *h, const char *refer_to);
@ -751,5 +759,5 @@ int sal_body_has_type(const SalBody *body, const char *type, const char *subtype
int sal_lines_get_value(const char *data, const char *key, char *value, size_t value_size);
belle_sip_stack_t *sal_get_belle_sip_stack(Sal *sal);
char* sal_op_get_public_uri(SalOp *sal);
#endif

View file

@ -14,21 +14,25 @@ public interface LinphoneChatMessage {
private final String mStringValue;
/**
* Idle
* Initial state
*/
public final static State Idle = new State(0,"Idle");
/**
* Incoming call received.
* Delivery in progress
*/
public final static State InProgress = new State(1,"InProgress");
/**
* Outgoing call initialiazed.
* Message succesffully delivered an acknoleged by remote end point
*/
public final static State Delivered = new State(2,"Delivered");
/**
* Outgoing call in progress.
* Message was not delivered
*/
public final static State NotDelivered = new State(3,"NotDelivered");
/**
* Message was received(and acknowledged) but cannot get file from server
*/
public final static State FileTransferError = new State(4,"FileTransferError");
private State(int value,String stringValue) {
mValue = value;
@ -153,5 +157,26 @@ public interface LinphoneChatMessage {
* @return an ErrorInfo.
*/
ErrorInfo getErrorInfo();
/**
* Start the download of the file bundled in the message
*/
void startFileDownload(LinphoneChatMessage.StateListener listener);
/**
* Get the file_transfer_information (used by call backs to recover informations during a rcs file transfer)
* @return a pointer to the LinphoneContent structure or NULL if not present.
*/
LinphoneContent getFileTransferInformation();
/**
* Sets data in the chat message
* @param data to store in the message
*/
void setAppData(String data);
/**
* @return the data stored in the chat message if any, else null
*/
String getAppData();
}

View file

@ -33,11 +33,13 @@ public interface LinphoneChatRoom {
* @return LinphoneAddress peer address
*/
LinphoneAddress getPeerAddress();
/**
* send a message to peer member of this chat room.
* @param message to be sent
*/
void sendMessage(String message);
/**
* Send a message to peer member of this chat room.
* @param chat message
@ -128,9 +130,23 @@ public interface LinphoneChatRoom {
* @return LinphoneChatMessage object
*/
LinphoneChatMessage createLinphoneChatMessage(String message, String url, State state, long timestamp, boolean isRead, boolean isIncoming);
/**
* Returns a back pointer to the core managing the chat room.
* @return the LinphoneCore
*/
LinphoneCore getCore();
/**
* Create a message attached to a dedicated chat room with a particular content.
* @param content LinphoneContent initial content.
* @return a new LinphoneChatMessage
*/
LinphoneChatMessage createFileTransferMessage(LinphoneContent content);
/**
* Cancel an ongoing file transfer attached to this message (upload or download)
* @param message
*/
void cancelFileTransfer(LinphoneChatMessage message);
}

View file

@ -31,10 +31,21 @@ public interface LinphoneContent {
**/
byte [] getData();
/**
* Get the data size.
* @return the data size.
* Get the expected data size.
* @return the expected data size
*/
int getSize();
int getExpectedSize();
/**
* Sets the expected data size
*/
void setExpectedSize(int size);
/**
* Return the size of the data field
* @return the size of the data field
*/
int getRealSize();
/**
* Set the content type, for example "application"
@ -59,4 +70,8 @@ public interface LinphoneContent {
* Set the data, as a byte buffer.
**/
void setData(byte data[]);
void setName(String name);
String getName();
}

File diff suppressed because it is too large Load diff

View file

@ -104,12 +104,10 @@ abstract public class LinphoneCoreFactory {
abstract public LinphoneAddress createLinphoneAddress(String address) throws LinphoneCoreException;
abstract public LpConfig createLpConfig(String file);
abstract public LinphoneProxyConfig createProxyConfig(String identity, String proxy,String route,boolean enableRegister) throws LinphoneCoreException;
/**
* Enable verbose traces
* @param enable
* @param tag
* @param enable true to enable debug mode, false to disable it
* @param tag Tag which prefixes each log message.
*/
abstract public void setDebugMode(boolean enable, String tag);

View file

@ -18,6 +18,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.linphone.core;
import java.nio.ByteBuffer;
import org.linphone.core.LinphoneCore.RemoteProvisioningState;
@ -188,6 +190,35 @@ public interface LinphoneCoreListener {
/** @Deprecated Callback to display a warning to the user
* @return */
void displayWarning(LinphoneCore lc,String message);
/**
* Callback to be notified about the transfer progress.
* @param lc the LinphoneCore
* @param message the LinphoneChatMessage
* @param content the LinphoneContent
* @param progress percentage of the transfer done
*/
void fileTransferProgressIndication(LinphoneCore lc, LinphoneChatMessage message, LinphoneContent content, int progress);
/**
* Callback to be notified when new data has been received
* @param lc the LinphoneCore
* @param message the LinphoneChatMessage
* @param content the LinphoneContent
* @param buffer
* @param size
*/
void fileTransferRecv(LinphoneCore lc, LinphoneChatMessage message, LinphoneContent content, byte[] buffer, int size);
/**
* Callback to be notified when new data needs to be sent
* @param lc the LinphoneCore
* @param message the LinphoneChatMessage
* @param content the LinphoneContent
* @param buffer
* @param size
* @return the number of bytes written into buffer
*/
int fileTransferSend(LinphoneCore lc, LinphoneChatMessage message, LinphoneContent content, ByteBuffer buffer, int size);
}

View file

@ -0,0 +1,95 @@
/**
* Interface to manipulate different media players of Linphone
*/
package org.linphone.core;
/**
* @author François Grisez
*
*/
public interface LinphonePlayer {
/**
* States that the player can be
* @author François Grisez
*
*/
public enum State {
closed, /**< No file is open */
paused, /**< A file is open and playback is not running */
playing; /**< A file is open and playback is running */
public static State fromValue(int value) {
if(value == 0) {
return closed;
} else if(value == 1) {
return paused;
} else if(value == 2) {
return playing;
} else {
return null;
}
}
};
/**
* Listener for Linphone players
* @author François Grisez
*
*/
public interface Listener {
/**
* Method called when a player reaches the end of a file
* @param player The player which called the method
*/
public void endOfFile(LinphonePlayer player);
}
/**
* Open a file
* @param filename Name of the file to open
* @return 0 on success, -1 on failure
*/
public int open(String filename, Listener listener);
/**
* Start playback
* @return 0 on success, -1 on failure
*/
public int start();
/**
* Get playback paused
* @return 0 on success, -1 on failure
*/
public int pause();
/**
* Go to a specific position in the timeline
* @param timeMs Time in milliseconds
* @return 0 on success, -1 on failure
*/
public int seek(int timeMs);
/**
* Get the state of the player
* @return See State enumeration
*/
public State getState();
/**
* Get the duration of the media
* @return The duration in milliseconds
*/
public int getDuration();
/**
* Get the position of the playback
* @return The position in milliseconds
*/
public int getCurrentPosition();
/**
* Close a file
*/
public void close();
}

View file

@ -103,4 +103,28 @@ public class LinphoneChatMessageImpl implements LinphoneChatMessage {
unref(nativePtr);
super.finalize();
}
private native void startFileDownload(long ptr, StateListener listener);
@Override
public void startFileDownload(StateListener listener) {
startFileDownload(nativePtr, listener);
}
private native Object getFileTransferInformation(long ptr);
@Override
public LinphoneContent getFileTransferInformation() {
return (LinphoneContent) getFileTransferInformation(nativePtr);
}
private native void setAppData(long ptr, String data);
@Override
public void setAppData(String data) {
setAppData(nativePtr, data);
}
private native String getAppData(long ptr);
@Override
public String getAppData() {
return getAppData(nativePtr);
}
}

View file

@ -168,4 +168,20 @@ class LinphoneChatRoomImpl implements LinphoneChatRoom {
return messages;
}
private native long createFileTransferMessage(long ptr, String name, String type, String subtype, int size);
@Override
public LinphoneChatMessage createFileTransferMessage(LinphoneContent content) {
synchronized(getCore()) {
return new LinphoneChatMessageImpl(createFileTransferMessage(nativePtr, content.getName(), content.getType(), content.getSubtype(), content.getRealSize()));
}
}
private native void cancelFileTransfer(long ptr, long messagePtr);
@Override
public void cancelFileTransfer(LinphoneChatMessage message) {
synchronized(getCore()) {
cancelFileTransfer(nativePtr, ((LinphoneChatMessageImpl)message).getNativePtr());
}
}
}

View file

@ -1,14 +1,26 @@
package org.linphone.core;
public class LinphoneContentImpl implements LinphoneContent {
private String mType, mSubtype, mEncoding;
private String mType, mSubtype, mEncoding, mName;
private byte[] mData;
private int mExpectedSize;
public LinphoneContentImpl(String type, String subtype, byte data[], String encoding ){
mType=type;
mSubtype=subtype;
mData=data;
mEncoding=encoding;
public LinphoneContentImpl(String type, String subtype, byte data[], String encoding){
mType = type;
mSubtype = subtype;
mData = data;
mEncoding = encoding;
mName = null;
mExpectedSize = 0;
}
public LinphoneContentImpl(String name, String type, String subtype, byte data[], String encoding, int expectedSize){
mType = type;
mSubtype = subtype;
mData = data;
mEncoding = encoding;
mName = name;
mExpectedSize = expectedSize;
}
@Override
@ -23,32 +35,49 @@ public class LinphoneContentImpl implements LinphoneContent {
@Override
public String getDataAsString() {
return new String(mData);
if (mData != null)
return new String(mData);
return null;
}
@Override
public void setExpectedSize(int size) {
mExpectedSize = size;
}
@Override
public int getSize() {
return mData.length;
public int getExpectedSize() {
return mExpectedSize;
}
@Override
public int getRealSize() {
if (mData != null)
return mData.length;
return 0;
}
@Override
public void setType(String type) {
mType=type;
mType = type;
}
@Override
public void setSubtype(String subtype) {
mSubtype=subtype;
mSubtype = subtype;
}
@Override
public void setStringData(String data) {
mData=data.getBytes();
if (data != null)
mData = data.getBytes();
else
mData = null;
}
@Override
public void setData(byte data[]){
mData=data;
mData = data;
}
@Override
@ -63,7 +92,16 @@ public class LinphoneContentImpl implements LinphoneContent {
@Override
public void setEncoding(String encoding) {
mEncoding=encoding;
mEncoding = encoding;
}
@Override
public void setName(String name) {
mName = name;
}
@Override
public String getName() {
return mName;
}
}

View file

@ -108,12 +108,6 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory {
}
}
@Override
public LinphoneProxyConfig createProxyConfig(String identity, String proxy,
String route, boolean enableRegister) throws LinphoneCoreException {
return new LinphoneProxyConfigImpl(identity,proxy,route,enableRegister);
}
@Override
public native void setDebugMode(boolean enable, String tag);

View file

@ -34,19 +34,19 @@ import android.media.AudioManager;
class LinphoneCoreImpl implements LinphoneCore {
private final LinphoneCoreListener mListener; //to make sure to keep a reference on this object
private long nativePtr = 0;
protected long nativePtr = 0;
private Context mContext = null;
private AudioManager mAudioManager = null;
private boolean mSpeakerEnabled = false;
private native long newLinphoneCore(LinphoneCoreListener listener,String userConfig,String factoryConfig,Object userdata);
private native void iterate(long nativePtr);
private native long getDefaultProxyConfig(long nativePtr);
private native LinphoneProxyConfig getDefaultProxyConfig(long nativePtr);
private native void setDefaultProxyConfig(long nativePtr,long proxyCfgNativePtr);
private native int addProxyConfig(LinphoneProxyConfig jprtoxyCfg,long nativePtr,long proxyCfgNativePtr);
private native void removeProxyConfig(long nativePtr, long proxyCfg);
private native void clearAuthInfos(long nativePtr);
private native void clearProxyConfigs(long nativePtr);
private native void addAuthInfo(long nativePtr,long authInfoNativePtr);
private native void removeAuthInfo(long nativePtr, long authInfoNativePtr);
@ -76,6 +76,8 @@ class LinphoneCoreImpl implements LinphoneCore {
private native boolean payloadTypeIsVbr(long nativePtr, long payloadType);
private native void enableAdaptiveRateControl(long nativePtr,boolean enable);
private native boolean isAdaptiveRateControlEnabled(long nativePtr);
private native String getAdaptiveRateAlgorithm(long nativePtr);
private native void setAdaptiveRateAlgorithm(long nativePtr, String alg);
private native void enableEchoCancellation(long nativePtr,boolean enable);
private native boolean isEchoCancellationEnabled(long nativePtr);
private native Object getCurrentCall(long nativePtr) ;
@ -148,12 +150,12 @@ class LinphoneCoreImpl implements LinphoneCore {
private native void setChatDatabasePath(long nativePtr, String path);
private native long[] getChatRooms(long nativePtr);
private native int migrateToMultiTransport(long nativePtr);
private native long createProxyConfig(long nativePtr);
private native void setCallErrorTone(long nativePtr, int reason, String path);
private native void enableSdp200Ack(long nativePtr,boolean enable);
private native boolean isSdp200AckEnabled(long nativePtr);
private native void stopRinging(long nativePtr);
private native static void setAndroidPowerManager(Object pm);
LinphoneCoreImpl(LinphoneCoreListener listener, File userConfig, File factoryConfig, Object userdata) throws IOException {
mListener = listener;
String user = userConfig == null ? null : userConfig.getCanonicalPath();
@ -164,9 +166,9 @@ class LinphoneCoreImpl implements LinphoneCore {
mListener = listener;
nativePtr = newLinphoneCore(listener,null,null,null);
}
protected void finalize() throws Throwable {
if (nativePtr!=0) destroy();
}
private boolean contextInitialized() {
@ -179,6 +181,7 @@ class LinphoneCoreImpl implements LinphoneCore {
public void setContext(Object context) {
mContext = (Context)context;
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
setAndroidPowerManager(mContext.getSystemService(Context.POWER_SERVICE));
}
public synchronized void addAuthInfo(LinphoneAuthInfo info) {
@ -193,12 +196,7 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized LinphoneProxyConfig getDefaultProxyConfig() {
isValid();
long lNativePtr = getDefaultProxyConfig(nativePtr);
if (lNativePtr!=0) {
return new LinphoneProxyConfigImpl(this,lNativePtr);
} else {
return null;
}
return getDefaultProxyConfig(nativePtr);
}
public synchronized LinphoneCall invite(String uri) {
@ -226,8 +224,6 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized void removeProxyConfig(LinphoneProxyConfig proxyCfg) {
isValid();
removeProxyConfig(nativePtr, ((LinphoneProxyConfigImpl)proxyCfg).nativePtr);
((LinphoneProxyConfigImpl)proxyCfg).mCore=null;
((LinphoneProxyConfigImpl)proxyCfg).deleteNativePtr();
}
public synchronized void clearAuthInfos() {
isValid();
@ -264,18 +260,17 @@ class LinphoneCoreImpl implements LinphoneCore {
}
public synchronized LinphoneCallLog[] getCallLogs() {
isValid();
LinphoneCallLog[] logs = new LinphoneCallLog[getNumberOfCallLogs(nativePtr)];
LinphoneCallLog[] logs = new LinphoneCallLog[getNumberOfCallLogs(nativePtr)];
for (int i=0;i < getNumberOfCallLogs(nativePtr);i++) {
logs[i] = new LinphoneCallLogImpl(getCallLog(nativePtr, i));
}
return logs;
}
public synchronized void destroy() {
isValid();
delete(nativePtr);
nativePtr = 0;
nativePtr=0;
}
private void isValid() {
if (nativePtr == 0) {
throw new RuntimeException("object already destroyed");
@ -286,7 +281,7 @@ class LinphoneCoreImpl implements LinphoneCore {
}
public synchronized void setPlaybackGain(float gain) {
setPlaybackGain(nativePtr,gain);
}
public synchronized float getPlaybackGain() {
return getPlaybackGain(nativePtr);
@ -303,7 +298,7 @@ class LinphoneCoreImpl implements LinphoneCore {
throw new LinphoneCoreException("Cannot interpret ["+destination+"]");
}
}
public synchronized LinphoneCall invite(LinphoneAddress to) throws LinphoneCoreException {
public synchronized LinphoneCall invite(LinphoneAddress to) throws LinphoneCoreException {
LinphoneCall call = (LinphoneCall)inviteAddress(nativePtr,((LinphoneAddressImpl)to).nativePtr);
if (call!=null) {
return call;
@ -336,18 +331,18 @@ class LinphoneCoreImpl implements LinphoneCore {
if (enablePayloadType(nativePtr,((PayloadTypeImpl)pt).nativePtr,enable) != 0) {
throw new LinphoneCoreException("cannot enable payload type ["+pt+"]");
}
}
public synchronized boolean isPayloadTypeEnabled(PayloadType pt) {
isValid();
return isPayloadTypeEnabled(nativePtr, ((PayloadTypeImpl)pt).nativePtr);
}
public synchronized boolean payloadTypeIsVbr(PayloadType pt) {
isValid();
return payloadTypeIsVbr(nativePtr, ((PayloadTypeImpl)pt).nativePtr);
}
public synchronized void enableEchoCancellation(boolean enable) {
isValid();
enableEchoCancellation(nativePtr, enable);
@ -355,21 +350,21 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized boolean isEchoCancellationEnabled() {
isValid();
return isEchoCancellationEnabled(nativePtr);
}
public synchronized LinphoneCall getCurrentCall() {
isValid();
return (LinphoneCall)getCurrentCall(nativePtr);
}
public int getPlayLevel() {
// TODO Auto-generated method stub
return 0;
}
public void setPlayLevel(int level) {
// TODO Auto-generated method stub
}
private void applyAudioHacks() {
@ -405,20 +400,20 @@ class LinphoneCoreImpl implements LinphoneCore {
}
public synchronized void playDtmf(char number, int duration) {
playDtmf(nativePtr,number, duration);
}
public synchronized void stopDtmf() {
stopDtmf(nativePtr);
}
public synchronized void addFriend(LinphoneFriend lf) throws LinphoneCoreException {
addFriend(nativePtr,((LinphoneFriendImpl)lf).nativePtr);
}
@SuppressWarnings("deprecation")
public synchronized void setPresenceInfo(int minutes_away, String alternative_contact, OnlineStatus status) {
setPresenceInfo(nativePtr,minutes_away,alternative_contact,status.mValue);
}
@SuppressWarnings("deprecation")
public synchronized OnlineStatus getPresenceInfo() {
@ -442,7 +437,7 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized void setDeviceRotation(int rotation) {
setDeviceRotation(nativePtr, rotation);
}
public synchronized void enableVideo(boolean vcap_enabled, boolean display_enabled) {
enableVideo(nativePtr,vcap_enabled, display_enabled);
}
@ -464,15 +459,15 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized void setStunServer(String stunServer) {
setStunServer(nativePtr,stunServer);
}
public synchronized LinphoneCallParams createDefaultCallParameters() {
return new LinphoneCallParamsImpl(createDefaultCallParams(nativePtr));
}
public synchronized LinphoneCall inviteAddressWithParams(LinphoneAddress to, LinphoneCallParams params) throws LinphoneCoreException {
long ptrDestination = ((LinphoneAddressImpl)to).nativePtr;
long ptrParams =((LinphoneCallParamsImpl)params).nativePtr;
LinphoneCall call = (LinphoneCall)inviteAddressWithParams(nativePtr, ptrDestination, ptrParams);
if (call!=null) {
return call;
@ -517,19 +512,19 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized String getRing() {
return getRing(nativePtr);
}
public synchronized void setRootCA(String path) {
setRootCA(nativePtr, path);
}
public synchronized LinphoneProxyConfig[] getProxyConfigList() {
public synchronized LinphoneProxyConfig[] getProxyConfigList() {
return getProxyConfigList(nativePtr);
}
public synchronized PayloadType[] getVideoCodecs() {
long[] typesPtr = listVideoPayloadTypes(nativePtr);
if (typesPtr == null) return null;
PayloadType[] codecs = new PayloadType[typesPtr.length];
for (int i=0; i < codecs.length; i++) {
@ -541,7 +536,7 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized PayloadType[] getAudioCodecs() {
long[] typesPtr = listAudioPayloadTypes(nativePtr);
if (typesPtr == null) return null;
PayloadType[] codecs = new PayloadType[typesPtr.length];
for (int i=0; i < codecs.length; i++) {
@ -553,10 +548,10 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized boolean isNetworkReachable() {
return isNetworkStateReachable(nativePtr);
}
public synchronized void enableKeepAlive(boolean enable) {
enableKeepAlive(nativePtr,enable);
}
public synchronized boolean isKeepAliveEnabled() {
return isKeepAliveEnabled(nativePtr);
@ -564,7 +559,7 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized void startEchoCalibration(Object data) throws LinphoneCoreException {
startEchoCalibration(nativePtr, data);
}
public synchronized Transports getSignalingTransportPorts() {
Transports transports = new Transports();
transports.udp = getSignalingTransportPort(nativePtr, 0);
@ -599,7 +594,7 @@ class LinphoneCoreImpl implements LinphoneCore {
}
public synchronized void setDownloadPtime(int ptime) {
setDownloadPtime(nativePtr,ptime);
}
public synchronized void setUploadPtime(int ptime) {
setUploadPtime(nativePtr,ptime);
@ -622,12 +617,12 @@ class LinphoneCoreImpl implements LinphoneCore {
}
private native void leaveConference(long nativePtr);
private native void leaveConference(long nativePtr);
public synchronized void leaveConference() {
leaveConference(nativePtr);
}
private native boolean enterConference(long nativePtr);
private native boolean enterConference(long nativePtr);
public synchronized boolean enterConference() {
return enterConference(nativePtr);
}
@ -665,12 +660,12 @@ class LinphoneCoreImpl implements LinphoneCore {
private native void addAllToConference(long nativePtr);
public synchronized void addAllToConference() {
addAllToConference(nativePtr);
}
private native void addToConference(long nativePtr, long nativePtrLcall);
public synchronized void addToConference(LinphoneCall call) {
addToConference(nativePtr, getCallPtr(call));
}
private native void removeFromConference(long nativePtr, long nativeCallPtr);
public synchronized void removeFromConference(LinphoneCall call) {
@ -680,7 +675,7 @@ class LinphoneCoreImpl implements LinphoneCore {
private long getCallPtr(LinphoneCall call) {
return ((LinphoneCallImpl)call).nativePtr;
}
private long getCallParamsPtr(LinphoneCallParams callParams) {
return ((LinphoneCallParamsImpl)callParams).nativePtr;
}
@ -708,7 +703,7 @@ class LinphoneCoreImpl implements LinphoneCore {
return isMediaEncryptionMandatory(nativePtr);
}
public synchronized void setMediaEncryption(MediaEncryption menc) {
setMediaEncryption(nativePtr, menc.mValue);
setMediaEncryption(nativePtr, menc.mValue);
}
public synchronized void setMediaEncryptionMandatory(boolean yesno) {
setMediaEncryptionMandatory(nativePtr, yesno);
@ -760,6 +755,18 @@ class LinphoneCoreImpl implements LinphoneCore {
tunnelAddServerAndMirror(nativePtr, host, port, mirror, ms);
}
private native void tunnelAddServer(long nativePtr, TunnelConfig config);
@Override
public synchronized void tunnelAddServer(TunnelConfig config) {
tunnelAddServer(nativePtr, config);
}
private native final TunnelConfig[] tunnelGetServers(long nativePtr);
@Override
public synchronized final TunnelConfig[] tunnelGetServers() {
return tunnelGetServers(nativePtr);
}
private native void tunnelAutoDetect(long nativePtr);
@Override
public synchronized void tunnelAutoDetect() {
@ -777,10 +784,34 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized void tunnelEnable(boolean enable) {
tunnelEnable(nativePtr, enable);
}
private native void tunnelSetMode(long nativePtr, int mode);
@Override
public synchronized void tunnelSetMode(LinphoneCore.TunnelMode mode) {
tunnelSetMode(nativePtr, TunnelMode.enumToInt(mode));
}
private native int tunnelGetMode(long nativePtr);
@Override
public synchronized LinphoneCore.TunnelMode tunnelGetMode() {
return LinphoneCore.TunnelMode.intToEnum(tunnelGetMode(nativePtr));
}
private native void tunnelEnableSip(long nativePtr, boolean enable);
@Override
public void tunnelEnableSip(boolean enable) {
tunnelEnableSip(nativePtr, enable);
}
private native boolean tunnelSipEnabled(long nativePtr);
@Override
public boolean tunnelSipEnabled() {
return tunnelSipEnabled(nativePtr);
}
@Override
public native boolean isTunnelAvailable();
private native void acceptCallWithParams(long nativePtr, long aCall,
long params);
@Override
@ -788,14 +819,14 @@ class LinphoneCoreImpl implements LinphoneCore {
LinphoneCallParams params) throws LinphoneCoreException {
acceptCallWithParams(nativePtr, getCallPtr(aCall), getCallParamsPtr(params));
}
private native void acceptCallUpdate(long nativePtr, long aCall, long params);
@Override
public synchronized void acceptCallUpdate(LinphoneCall aCall, LinphoneCallParams params)
throws LinphoneCoreException {
acceptCallUpdate(nativePtr, getCallPtr(aCall), getCallParamsPtr(params));
acceptCallUpdate(nativePtr, getCallPtr(aCall), getCallParamsPtr(params));
}
private native void deferCallUpdate(long nativePtr, long aCall);
@Override
public synchronized void deferCallUpdate(LinphoneCall aCall)
@ -803,7 +834,7 @@ class LinphoneCoreImpl implements LinphoneCore {
deferCallUpdate(nativePtr, getCallPtr(aCall));
}
private native void setVideoPolicy(long nativePtr, boolean autoInitiate, boolean autoAccept);
public synchronized void setVideoPolicy(boolean autoInitiate, boolean autoAccept) {
setVideoPolicy(nativePtr, autoInitiate, autoAccept);
@ -816,7 +847,7 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized boolean getVideoAutoAcceptPolicy() {
return getVideoAutoAcceptPolicy(nativePtr);
}
private native void setStaticPicture(long nativePtr, String path);
public synchronized void setStaticPicture(String path) {
setStaticPicture(nativePtr, path);
@ -832,11 +863,11 @@ class LinphoneCoreImpl implements LinphoneCore {
{
setCpuCountNative(count);
}
public synchronized int getMissedCallsCount() {
return getMissedCallsCount(nativePtr);
}
public synchronized void removeCallLog(LinphoneCallLog log) {
removeCallLog(nativePtr, ((LinphoneCallLogImpl) log).getNativePtr());
}
@ -844,7 +875,7 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized void resetMissedCallsCount() {
resetMissedCallsCount(nativePtr);
}
private native void tunnelSetHttpProxy(long nativePtr, String proxy_host, int port,
String username, String password);
@Override
@ -852,12 +883,12 @@ class LinphoneCoreImpl implements LinphoneCore {
String username, String password) {
tunnelSetHttpProxy(nativePtr, proxy_host, port, username, password);
}
private native void refreshRegisters(long nativePtr);
public synchronized void refreshRegisters() {
refreshRegisters(nativePtr);
}
@Override
public String getVersion() {
return getVersion(nativePtr);
@ -874,13 +905,13 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized PayloadType findPayloadType(String mime, int clockRate) {
return findPayloadType(mime, clockRate, FIND_PAYLOAD_IGNORE_CHANNELS);
}
private native void removeFriend(long ptr, long lf);
@Override
public synchronized void removeFriend(LinphoneFriend lf) {
removeFriend(nativePtr, lf.getNativePtr());
}
private native long getFriendByAddress(long ptr, String sipUri);
@Override
public synchronized LinphoneFriend findFriendByAddress(String sipUri) {
@ -890,64 +921,64 @@ class LinphoneCoreImpl implements LinphoneCore {
}
return new LinphoneFriendImpl(ptr);
}
public synchronized void setAudioPort(int port) {
setAudioPort(nativePtr, port);
}
public synchronized void setVideoPort(int port) {
setVideoPort(nativePtr, port);
}
public synchronized void setAudioPortRange(int minPort, int maxPort) {
setAudioPortRange(nativePtr, minPort, maxPort);
}
public synchronized void setVideoPortRange(int minPort, int maxPort) {
setVideoPortRange(nativePtr, minPort, maxPort);
}
public synchronized void setIncomingTimeout(int timeout) {
setIncomingTimeout(nativePtr, timeout);
}
public synchronized void setInCallTimeout(int timeout)
{
setInCallTimeout(nativePtr, timeout);
}
private native void setMicrophoneGain(long ptr, float gain);
public synchronized void setMicrophoneGain(float gain) {
setMicrophoneGain(nativePtr, gain);
}
public synchronized void setPrimaryContact(String displayName, String username) {
setPrimaryContact(nativePtr, displayName, username);
}
public synchronized String getPrimaryContactUsername() {
return getPrimaryContactUsername(nativePtr);
}
public synchronized String getPrimaryContactDisplayName() {
return getPrimaryContactDisplayName(nativePtr);
}
private native void setUseSipInfoForDtmfs(long ptr, boolean use);
public synchronized void setUseSipInfoForDtmfs(boolean use) {
setUseSipInfoForDtmfs(nativePtr, use);
}
private native boolean getUseSipInfoForDtmfs(long ptr);
public synchronized boolean getUseSipInfoForDtmfs() {
return getUseSipInfoForDtmfs(nativePtr);
}
private native void setUseRfc2833ForDtmfs(long ptr, boolean use);
public synchronized void setUseRfc2833ForDtmfs(boolean use) {
setUseRfc2833ForDtmfs(nativePtr, use);
}
private native boolean getUseRfc2833ForDtmfs(long ptr);
public synchronized boolean getUseRfc2833ForDtmfs() {
return getUseRfc2833ForDtmfs(nativePtr);
@ -968,17 +999,17 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized void declineCall(LinphoneCall aCall, Reason reason) {
declineCall(nativePtr,((LinphoneCallImpl)aCall).nativePtr,reason.mValue);
}
private native boolean upnpAvailable(long ptr);
public synchronized boolean upnpAvailable() {
return upnpAvailable(nativePtr);
}
}
private native int getUpnpState(long ptr);
public synchronized UpnpState getUpnpState() {
return UpnpState.fromInt(getUpnpState(nativePtr));
return UpnpState.fromInt(getUpnpState(nativePtr));
}
private native String getUpnpExternalIpaddress(long ptr);
public synchronized String getUpnpExternalIpaddress() {
return getUpnpExternalIpaddress(nativePtr);
@ -988,7 +1019,7 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized void startConferenceRecording(String path) {
startConferenceRecording(nativePtr,path);
}
private native int stopConferenceRecording(long nativePtr);
@Override
public synchronized void stopConferenceRecording() {
@ -998,13 +1029,13 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized PayloadType findPayloadType(String mime) {
return findPayloadType(mime, FIND_PAYLOAD_IGNORE_RATE);
}
private native void setSipDscp(long nativePtr, int dscp);
@Override
public synchronized void setSipDscp(int dscp) {
setSipDscp(nativePtr,dscp);
}
private native int getSipDscp(long nativePtr);
@Override
public synchronized int getSipDscp() {
@ -1015,36 +1046,36 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized void setAudioDscp(int dscp) {
setAudioDscp(nativePtr, dscp);
}
private native int getAudioDscp(long nativePtr);
@Override
public synchronized int getAudioDscp() {
return getAudioDscp(nativePtr);
}
private native void setVideoDscp(long nativePtr, int dscp);
@Override
public synchronized void setVideoDscp(int dscp) {
setVideoDscp(nativePtr,dscp);
}
private native int getVideoDscp(long nativePtr);
@Override
public synchronized int getVideoDscp() {
return getVideoDscp(nativePtr);
}
private native long createInfoMessage(long nativeptr);
@Override
public synchronized LinphoneInfoMessage createInfoMessage() {
return new LinphoneInfoMessageImpl(createInfoMessage(nativePtr));
}
private native Object subscribe(long coreptr, long addrptr, String eventname, int expires, String type, String subtype, byte data [], String encoding);
@Override
public synchronized LinphoneEvent subscribe(LinphoneAddress resource, String eventname,
int expires, LinphoneContent content) {
return (LinphoneEvent)subscribe(nativePtr, ((LinphoneAddressImpl)resource).nativePtr, eventname, expires,
return (LinphoneEvent)subscribe(nativePtr, ((LinphoneAddressImpl)resource).nativePtr, eventname, expires,
content!=null ? content.getType() : null, content!=null ? content.getSubtype() : null, content!=null ? content.getData() : null,
content!=null ? content.getEncoding() : null);
}
@ -1052,7 +1083,7 @@ class LinphoneCoreImpl implements LinphoneCore {
@Override
public synchronized LinphoneEvent publish(LinphoneAddress resource, String eventname,
int expires, LinphoneContent content) {
return (LinphoneEvent)publish(nativePtr, ((LinphoneAddressImpl)resource).nativePtr, eventname, expires,
return (LinphoneEvent)publish(nativePtr, ((LinphoneAddressImpl)resource).nativePtr, eventname, expires,
content!=null ? content.getType() : null, content!=null ? content.getSubtype() : null, content!=null ? content.getData() : null,
content!=null ? content.getEncoding() : null);
}
@ -1069,15 +1100,15 @@ class LinphoneCoreImpl implements LinphoneCore {
String event, int expires) {
return (LinphoneEvent)createPublish(nativePtr, ((LinphoneAddressImpl)resource).nativePtr, event, expires);
}
public synchronized void setChatDatabasePath(String path) {
setChatDatabasePath(nativePtr, path);
}
public synchronized LinphoneChatRoom[] getChatRooms() {
long[] typesPtr = getChatRooms(nativePtr);
if (typesPtr == null) return null;
LinphoneChatRoom[] proxies = new LinphoneChatRoom[typesPtr.length];
for (int i=0; i < proxies.length; i++) {
@ -1089,7 +1120,7 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized LinphoneAuthInfo[] getAuthInfosList() {
long[] typesPtr = getAuthInfosList(nativePtr);
if (typesPtr == null) return null;
LinphoneAuthInfo[] authInfos = new LinphoneAuthInfo[typesPtr.length];
for (int i=0; i < authInfos.length; i++) {
@ -1098,12 +1129,12 @@ class LinphoneCoreImpl implements LinphoneCore {
return authInfos;
}
public synchronized LinphoneAuthInfo findAuthInfo(String username, String realm, String domain) {
long ptr = findAuthInfos(nativePtr, username, realm, domain);
if (ptr == 0)
return null;
return new LinphoneAuthInfoImpl(ptr);
}
private native LinphoneCall startReferedCall(long corePtr, long callptr, long paramsPtr);
@ -1113,7 +1144,7 @@ class LinphoneCoreImpl implements LinphoneCore {
long ptrParams =((LinphoneCallParamsImpl)params).nativePtr;
return startReferedCall(nativePtr, getCallPtr(call), ptrParams);
}
private native String[] listSupportedVideoResolutions(long ptr);
@Override
public synchronized String[] getSupportedVideoSizes() {
@ -1124,13 +1155,13 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized int migrateToMultiTransport() {
return migrateToMultiTransport(nativePtr);
}
private native boolean acceptEarlyMedia(long lc, long call);
@Override
public synchronized boolean acceptEarlyMedia(LinphoneCall call) {
return acceptEarlyMedia(nativePtr, getCallPtr(call));
}
private native boolean acceptEarlyMediaWithParams(long lc, long call, long params);
@Override
public synchronized boolean acceptEarlyMediaWithParams(LinphoneCall call,
@ -1140,7 +1171,16 @@ class LinphoneCoreImpl implements LinphoneCore {
}
@Override
public synchronized LinphoneProxyConfig createProxyConfig() {
return new LinphoneProxyConfigImpl(this,createProxyConfig(nativePtr));
return new LinphoneProxyConfigImpl(this);
}
@Override
public synchronized LinphoneProxyConfig createProxyConfig(String identity,String proxy,String route, boolean enableRegister) throws LinphoneCoreException {
isValid();
try {
return new LinphoneProxyConfigImpl(this,identity,proxy,route,enableRegister);
} catch(LinphoneCoreException e){
return null;
}
}
@Override
public synchronized void setCallErrorTone(Reason reason, String path) {
@ -1184,7 +1224,7 @@ class LinphoneCoreImpl implements LinphoneCore {
public synchronized boolean chatEnabled() {
return chatEnabled(nativePtr);
}
@Override
public synchronized void stopRinging() {
stopRinging(nativePtr);
@ -1202,13 +1242,20 @@ class LinphoneCoreImpl implements LinphoneCore {
@Override
public synchronized void enableAdaptiveRateControl(boolean enable) {
enableAdaptiveRateControl(nativePtr,enable);
}
@Override
public synchronized boolean isAdaptiveRateControlEnabled() {
return isAdaptiveRateControlEnabled(nativePtr);
}
public synchronized AdaptiveRateAlgorithm getAdaptiveRateAlgorithm() {
return AdaptiveRateAlgorithm.fromString(getAdaptiveRateAlgorithm(nativePtr));
}
public synchronized void setAdaptiveRateAlgorithm(AdaptiveRateAlgorithm alg) {
setAdaptiveRateAlgorithm(nativePtr, alg.toString());
}
private native void setAudioJittcomp(long ptr, int value);
@Override
public synchronized void setAudioJittcomp(int value) {
@ -1220,4 +1267,32 @@ class LinphoneCoreImpl implements LinphoneCore {
setVideoJittcomp(nativePtr,value);
}
private native void setFileTransferServer(long ptr, String serverUrl);
@Override
public synchronized void setFileTransferServer(String serverUrl) {
setFileTransferServer(nativePtr, serverUrl);
}
private native String getFileTransferServer(long ptr);
@Override
public synchronized String getFileTransferServer() {
return getFileTransferServer(nativePtr);
}
private native long createPlayer(long nativePtr);
@Override
public synchronized LinphonePlayer createPlayer() {
long player = createPlayer(nativePtr);
if(player != 0) {
return new LinphonePlayerImpl(createPlayer(nativePtr));
} else {
return null;
}
}
private native void destroyPlayer(long playerPtr);
@Override
public synchronized void destroyPlayer(LinphonePlayer player) {
}
}

View file

@ -0,0 +1,64 @@
/**
*
*/
package org.linphone.core;
/**
* @author François Grisez
*
*/
public class LinphonePlayerImpl implements LinphonePlayer {
private long nativePtr = 0;
LinphonePlayerImpl(long nativePtr) {
this.nativePtr = nativePtr;
}
private native int open(long nativePtr, String filename, Listener listener);
@Override
public synchronized int open(String filename, Listener listener) {
return open(nativePtr, filename, listener);
}
private native int start(long nativePtr);
@Override
public synchronized int start() {
return start(nativePtr);
}
private native int pause(long nativePtr);
@Override
public synchronized int pause() {
return pause(nativePtr);
}
private native int seek(long nativePtr, int timeMs);
@Override
public synchronized int seek(int timeMs) {
return seek(nativePtr, timeMs);
}
private native int getState(long nativePtr);
@Override
public synchronized State getState() {
return LinphonePlayer.State.fromValue(getState(nativePtr));
}
private native int getDuration(long nativePtr);
@Override
public synchronized int getDuration() {
return getDuration(nativePtr);
}
private native int getCurrentPosition(long nativePtr);
@Override
public synchronized int getCurrentPosition() {
return getCurrentPosition(nativePtr);
}
private native void close(long nativePtr);
@Override
public synchronized void close() {
close(nativePtr);
}
}

View file

@ -22,32 +22,33 @@ import org.linphone.core.LinphoneCore.RegistrationState;
class LinphoneProxyConfigImpl implements LinphoneProxyConfig {
protected long nativePtr;
protected final long nativePtr;
protected LinphoneCoreImpl mCore;
Object userData;
private native void finalize(long ptr);
private native int getState(long nativePtr);
private native void setExpires(long nativePtr, int delay);
private native int getExpires(long nativePtr);
private native long createProxyConfig( long nativePtr);
boolean ownPtr = false;
protected LinphoneProxyConfigImpl(String identity,String proxy,String route, boolean enableRegister) throws LinphoneCoreException {
nativePtr = newLinphoneProxyConfig();
protected LinphoneProxyConfigImpl(LinphoneCoreImpl core,String identity,String proxy,String route, boolean enableRegister) throws LinphoneCoreException {
mCore=core;
nativePtr = createProxyConfig(core.nativePtr);
setIdentity(identity);
setProxy(proxy);
setRoute(route);
enableRegister(enableRegister);
ownPtr=true;
}
protected LinphoneProxyConfigImpl(LinphoneCoreImpl core,long aNativePtr) {
protected LinphoneProxyConfigImpl(LinphoneCoreImpl core) {
mCore=core;
nativePtr = createProxyConfig(core.nativePtr);
}
/*reserved for JNI */
protected LinphoneProxyConfigImpl(LinphoneCoreImpl core, long aNativePtr) {
mCore=core;
nativePtr = aNativePtr;
ownPtr=false;
}
protected LinphoneProxyConfigImpl(long aNativePtr) {
nativePtr = aNativePtr;
ownPtr=false;
}
private void isValid() {
@ -56,16 +57,13 @@ class LinphoneProxyConfigImpl implements LinphoneProxyConfig {
}
}
public void deleteNativePtr() {
nativePtr=0;
}
protected void finalize() throws Throwable {
//Log.e(LinphoneService.TAG,"fixme, should release underlying proxy config");
if (ownPtr) delete(nativePtr);
if (nativePtr != 0) {
finalize(nativePtr);
}
super.finalize();
}
private native long newLinphoneProxyConfig();
private native void delete(long ptr);
private native void edit(long ptr);
private native void done(long ptr);

View file

@ -0,0 +1,40 @@
package org.linphone.core;
public class TunnelConfig {
private String host = null;
private int port = 443;
private int remoteUdpMirrorPort = 12345;
private int delay = 1000;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public int getPort() {
return port;
}
public void setPort(int port) {
this.port = port;
}
public int getRemoteUdpMirrorPort() {
return remoteUdpMirrorPort;
}
public void setRemoteUdpMirrorPort(int remoteUdpMirrorPort) {
this.remoteUdpMirrorPort = remoteUdpMirrorPort;
}
public int getDelay() {
return delay;
}
public void setDelay(int delay) {
this.delay = delay;
}
}

Some files were not shown because too many files have changed in this diff Show more